本章结合eve-ng来重点介绍ipv6的基础知识,主要包括ipv6格式、ipv6地址分类及应用场景、如何在主机/路由器上手动配置ipv6地址、ipv6中重要的网络控制信息协议版本6(internet control message protocol version 6,icmp6)、邻居发现协议(neighbor discovery protocol,ndp)、重复地址检查(duplicated address detection,dad)等内容。
ipv6地址表示方法
ipv6地址多达128位,十六进制。在ipv6的具体表示方法上,有3中表示方法较为流行,即首选格式、压缩格式和内嵌ipv4地址的ipv6地址格式
首选格式
ipv6地址的首选格式是最严谨的表示方法,它将ipv6的128位用:分成8段,每段16位,每连续的4位转换成十六进制。以首选格式来表示ipv6地址,需要特别注意两点:
- 1.与十进制表示的
ipv4地址一样,每段中4个十六进制前面的0可以省略,但后面的0不可以省略 - 2.如果一个段中4个十六进制数全是0,则必须要写一个0
压缩格式
在实际应用中,特别是服务器、网关等用到的ipv6地址,都会出现连续多位0,此时采用压缩格式来表示会更合理。假设一个首选格式的ipv6地址为2001:DA8:1004:0:0:0:0:1,这里连续的多个0就可以用::来代替,该地址就可以写出2001:DA8:1004::1。
以压缩格式来表示ipv6地址时,也需要注意两点:
- 前面提到连续的多个0是首选格式中每一段都为0,而不包括前面一段末尾的0和后面一段首位的0
- 压缩格式中的
::只能出现一次
验证ipv6地址的合法性
- 设置合法的首选格式和压缩格式的
ipv6地址 - 设置首选格式少于7段和压缩格式出现两个
::的非法格式地址,让系统判定是否合法 - 省去前面的0和省去后面的0,与真实地址进行比较
-
配置
ipv6地址,在win10手动输入首选格式的ipv6地址2001:0da8:1001:aabb:0001:0000:abcd:bbc0,子网前缀长度保持默认的64,其他保持空白,单击确定按钮。
在命令提示符输入ipconfig命令,查看设置的ipv6地址。第二段0da8前面的0可以省略,第三段1001中间的0不能省略,第五段0001前面的0可省略,变成了1,第六段的0000变成了0,保留了1位,不能全省略,第八段bbc0最后的0不能省略 -
设置
ipv6地址为2001:da8:1001:aabb:0:0:abcd:bbc0,再用ipconfig命令验证。第五段和第六段的连续两个0被转成了压缩格式::。再设置ipv6地址为2001:0:0:1:1:0:0:1,继续用ipconfig验证。ipv6地址第二段和第三段的0被压缩成::,第六段和第七段不再被压缩成::,也就是说压缩格式地址最多只允许出现一次::。需要说明的一点是,压缩格式优先考虑长度,在长度相同的情况下优先考虑高位。 -
继续设置错误地址
2001::1::1,windows系统会判定ipv6地址无效。
内嵌ipv4地址的ipv6地址格式
其书写格式一般是前面96位地址用首选格式或压缩格式的十六进制数表示,后面追加以十进制数表示的32位ipv4地址。比如:2001:da8:1004::192.168.1.1。其实这种格式只是便于书写,系统会自动将末尾的ipv4地址转换成十六进制。
子网前缀和接口ID
子网前缀
-
在
ipv4网络中,子网掩码用来指明网络号和主机号。如192.168.1.1/24,网络号就是192.168.1.0/24,主机号就是1.ipv6中,网络号改名为网络前缀,主机号改名为接口id了。通常情况下,地址前缀长度为64,即地址前缀和接口标识符各占64位。2001:1::1/64的前缀就是2001:1::/64,接口标识符就是剩余的::1。虽然RFC 4291规定,除了二进制000开头的ipv6地址,地址前缀和接口标识符必须各占64位,且接口标识符必须是修正的EUI-64(64-bit extended unique identifier,64位扩展唯一标识符,由网卡的mac地址转换而来)格式。但实际应用并不总是这样。这是因为限制地址前缀长度会使应用的灵活性降低,而规定EUI-64格式的接口标识符则存在隐私泄露的风险 -
网络设备选路的依据就是路由表。在
ipv4网络中,由子网掩码与目的ip做与运算来得出网络号,再查路由表中对应网络号的吓一跳,就可以选择出口转发数据了。在ipv6用地址前缀长度来替代了子网掩码的计算功能。 -
设置
ipv6地址为2001:250:5005:1::1/64,在命令提示符下执行route print -6命令,观察主机路由表

route print命令可同时显示ipv4和ipv6的路由表,-4和-6参数用来设定只显示ipv4或ipv6的路由表。
接口列表显示当前计算机有几个接口(也称网络适配器)。图中显示有3个接口,编号为4的接口是计算机的物理网卡,另外两个是虚拟网络适配器。
ipv6路由表显示当前计算机的路由表,4是接口编号;266是跃点数,跃点数越小,路由越优先;2001:250:5005:1111::/64是具体的路由条目;在链路上相当于是直连路由,若是非直连路由,这里显示的则是吓一跳的地址。
接口ID
-
一旦在主机或路由器等网络接口启用了
ipv6协议,就会在该接口下自动生成一个FE80::开头的链路本地地址,这也是ipv6的即插即用特性,即规定好固定前缀,再快速生成接口标识符以拥有一个完整的ipv6地址。这个接口标识符(也叫接口ID)是基于EUI-64格式的接口标识符。
以太网的mac地址是48位,而基于EUI-64格式的接口ID是64位,在mac地址中间插入特定的FFFE(16位),并将标识全球/本地范围的第7位设置为1.如果第7为本身是1,则转成0.这里假定以太网接口(如网卡)的mac地址是全球唯一的,因此自动生成的EUI-64格式的接口标识符也是唯一的。 -
配置计算机,在命令提示符中输入
ipconfig /all命令,查看接口mac地址和以FE80开头的地址的接口标识符部分这两种之间的对应关系,验证是否符合EUI-64格式

mac地址是50:00:00:01:00:00,链路本地地址的接口id是d57c:b6c:cf69:cec6,说明接口标识符与基于mac地址转换生成的EUI-64格式的标识符之间没有关系 -
配置路由器。双击路由器,打开路由器的配置界面,执行下面的配置
enable configure terminal interface ethernet 0/0 ipv6 enable no shutdown end配置完成后,使用
show ipv6 interface ethernet 0/0命令查看以FE80开头的链路本地地址的接口id,使用show interface ethernet 0/0命令查看接口的mac地址。可以得出网络设备是根据EUI-64自动配置链路本地地址。 -
修改
windows的默认配置。打开命令提示符,执行netsh interface ipv6 show global命令

从图中可以看出,系统默认已经对接口id随机化了。如果要使用EUI-64格式的接口id,关闭随机标识符选项即可。netsh interface ipv6 set global randomizeidentifiers=disable store=persistent -
网络设备配置
EUI-64格式的ip地址。执行如下命令
ipv6 address 2001:1::/64 eui-64 //设置接口的ipv6地址,接口id采用eui-64格式自动生成
ipv6 address 2001:2::1/64 //一个接口可以配置多个ipv6地址,此地址的接口ID指定为::1
Router#show ipv6 interface ethernet 0/0
Ethernet0/0 is up, line protocol is up
IPv6 is enabled, link-local address is FE80::A8BB:CCFF:FE00:300
No Virtual link-local address(es):
Global unicast address(es):
2001:1::A8BB:CCFF:FE00:300, subnet is 2001:1::/64 [EUI]
2001:2::1, subnet is 2001:2::/64
Joined group address(es):
FF02::1
FF02::1:FF00:1
FF02::1:FF00:300
Ipv6地址分类
相较于ipv4地址的分类情况,ipv6地址有以下3个重要变化
ipv6地址不再有网络地址和广播地址,广播被组播替代,减少了广播风暴对网络性能的影响- 不再有
A、B、C、D、E类地址,而是固定特定的地址用于特殊的网络或环境 - 一个接口一般会有多个
ipv6地址,每个地址有不同的用途
ipv6地址分为3类:单播、任博和多播。ipv6中还有特俗的为指定地址和环回地址。
单播地址
单播地址用于标识一定范围内唯一的网络接口,发送给单薄地址的数据包将最终发送到由该地址标识的网络接口。单播地址具有两个特定:在一定范围内唯一存在;一个地址只能配置在一个接口上。一个单播地址包括N位网络前缀和128-N位接口标识符,且通常情况下前缀长度和接口标识符都是64位。
单播地址又可继续分为4类:可聚合全球单播地址、链路本地单播地址、站点本地单播地址、站点本地单播地址、内嵌ipv4地址的兼容地址
-
可聚合全球单播地址
可聚合全球单播地址即在全球ipv6互联网中可聚合、可路由的地址,类似于ipv4的公网地址,在ipv6网络中可相互直接通信。
虽然ipv6地址很多,但目前可聚合的全球单播地址仅限于前3位是001的地址,即2000::/3。 -
链路本地单播地址
链路本地单播地址是以FE80::/64打头的地址,它在ipv6通信中是受限制的,其作用范围仅限于连接到同一本地链路的节点之间。也可以简单地认为链路本地地址只用来在不跨网段的局域网通信。
链路本地单播地址在局域网通信中有着重要的作用,自动配置机制、邻居发现机制等都会用到链路本地单播地址。
通常情况下,链路本地单播地址都是自动配置的,即只要接口启用了ipv6协议,就会自动生成FE80::/64+64位接口id(可为EUI-64格式,也可遵循私密性扩展,对接口id进行随机化处理)形式的ipv6地址。该地址也可以手动修改。
可以对路由器上的链路本地单播地址进行修改,也可以在计算机上增加链路本地单播地址。
- 配置路由器的链路本地地址
Router(config-if)#ipv6 address fe80::abcd link-local
show ipv6 interface ethernet 0/0
Ethernet0/0 is up, line protocol is up
IPv6 is enabled, link-local address is FE80::ABCD
- 配置
win10。在命令提示符下执行ipconfig命令,

链路本地单播地址为fe80::5200:ff:fe01:0,后面的%4表示接口编号。
主机可以有很多接口,每个接口都有一个编号,可用命令netsh interface ipv6 show interface来查看每个接口对应的编号。
执行命令netsh interface ipv6 set address "4" fe80::abc,给该接口增加一个链路本地单播地址。

要想删除某个地址,将命令中的set改为delete即可
- 数据包捕获演示
配置路由器Router(config)#ipv6 unicast-routing //开启ipv6单播路由功能,这里的思科路由器默认不支持ipv6路由,通过此命令开启ipv6路由支持 Router(config-if)#no ipv6 nd ra suppress //guan'b关闭ipv6邻居发现协议中的路由通过抑制功能,使win10客户机能自动获取到ipv6网关
在win10配置ipv6为自动获取地址。用ipconfig命令查看本机的链路本地单播地址和网关的链路本地单播地址,并ping网关的链路本地单播地址。

右键单击路由器,在快捷菜单中选择capture-->e/0/0,捕获数据包对话框将弹出。

当然,也可以从路由器上ping计算机的链路本地单播地址
Router>ping fe80::5200:ff:fe01:0
Output Interface: ethernet0/0 //由于ping的是链路本地单播地址,因此需要在路由器上明确指出从哪个接口发出ping数据包。在计算机上执行ping操作时不用指出哪块网卡,计算机默认是从每块网卡发出ping数据包,没有路由器严谨
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to FE80::5200:FF:FE01:0, timeout is 2 seconds:
Packet sent with a source address of FE80::ABCD%Ethernet0/0
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/1 ms
-
站点本地单播地址
站点本地单播地址是ipv6中的私网地址。FC00::/7为本地单播地址。按照子网划分的原则,可以划分为FC00::/8和FD00::/8,其中FC00::/8为保留地址段,FD00::/8为站点范围内的单播地址。 -
内嵌
ipv4的兼容地址
任播地址
任播地址在地址格式上与单播地址别无二致,但用途不同。单播地址用于一个源地址到一个目的地址之间的通信,即一个单播地址只能用于一个接口,而任播地址是同一个地址用在网络中多个节点、多个接口之上。任播地址用于表示一组不同节点的接口。若某个数据包的目的地址是任播地址,该数据包将被发送到路由意义上最近的一个网络接口。
为了与单播地址区分,任播地址一般约定64位接口ID全是0。这有点类似于ipv4的主机位为0的网络地址,只不过ipv4主机位全是0的网络地址和主机位全是1的广播地址是不能分配给设备使用的,而ipv6中主机位全是0的任播地址和主机位全是1的地址都能供设备使用。
任播地址一般只能用作目的地址,不能用作源地址。
这个实验是模拟任播地址的使用,其中R1和R4模拟客户机。

R2和R3上的loopback0来模拟具有相同任播地址240c::6666的服务器。R1和R4都访问240c::6666
R1配置如下:
enable
config terminal
host R1
ipv6 unicast-routing
interface eth0/0
ipv6 enable
ipv6 address 2001:12::1/64
no shutdown
ipv6 route ::/0 2001:12::2 //设置默认路由
R2配置如下:
enable
config terminal
host R2
ipv6 unicast-routing
interface eth0/0
ipv6 enable
ipv6 address 2001:12::2/64
no shutdown
interface eth0/1
ipv6 enable
ipv6 address 2001:23::2/64
no shutdown
interface loopback0 //配置环回接口来模拟服务器。
ipv6 enable
ipv6 address 240c::6666/128 anycast //配置任播ipv6地址
exit
ipv6 route ::/0 2001:23::3 //配置默认路由,R2把所有不明确的路由都发往R3
line vty 0 4
password cisco //配置路由器的远程登录密码
login //远程访问要求登录,如果配置成no login则无需登录
transport input all //允许多种协议远程连接服务器,比如telnet、ssh
R3配置如下:
enable
config terminal
host R3
ipv6 unicast-routing
interface eth0/0
ipv6 enable
ipv6 address 2001:23::3/64
no shutdown
interface eth0/1
ipv6 enable
ipv6 address 2001:34::3/64
no shutdown
exit
ipv6 route ::/0 2001:23::2
interface loopback0
ipv6 enable
ipv6 address 240c::6666/128 anycast
line vty 0 4
password cisco
login
transport input all
R4配置如下:
enable
config terminal
host R4
ipv6 unicast-routing
interface eth0/0
ipv6 enable
ipv6 address 2001:34::4/64
no shutdown
ipv6 route ::/0 2001:34::3
测试:在R1上telnet任播地址240c::6666
R1#telnet 240c::6666
Trying 240C::6666 ... Open
User Access Verification
Password: //输入密码cisco
R2> //注意到登录的是R2
测试:在R4上telnet任播地址240c::6666
R4#telnet 240c::6666
Trying 240C::6666 ... Open
User Access Verification
Password:
R3> //注意到登录的是R3
任播地址一般只能用作目的地址,不能用作源地址。使用待用源地址240c::6666的ping命令时,系统将提示源地址非法
R2#ping 2001:34::4 source 240c::6666
% No valid source address for destination
组播地址
ipv6中的组播地址用来标识多个接口,它对应于一组接口的地址,且这些接口通常分属于不同的节点
由源节点发送到组播地址的数据包会由该地址标识的每个接口所接收。组播地址只能用作目的地址

标志位目前只定义了十六进制的0和1,其中0经常使用,表示永久;1较少使用,表示临时。
ipv6不像ipv4那用使用TTL来限制范围,而是使用组播地址中的范围字段来定义和限制。
目前,范围字段定义的十六进制数包括:1表示本地接口范围;2表示本地链路范围;3表示本地子网范围;4表示本地管理范围;5表示本地站点范围;8表示组织机构范围;E表示全球范围。
其中2表示的本地链路范围较为常用。
在ipv6中,由于组播替代了广播,所以即便网络中没有组播应用,也常常见到一些组播地址
| 组播地址 | 描述 |
|---|---|
| FF01::1 | 本地接口范围的所有节点 |
| FF01::2 | 本地接口范围的所有路由器 |
| FF02::1 | 本地链路范围的所有节点 |
| FF02::2 | 本地链路范围的所有路由器 |
| FF05::2 | 本地站点范围的所有路由器 |
-
被请求节点组播地址
除了上面的常用组播地址,还有一种被请求节点组播地址,它的前104位是固定的,即FF02::1:ff00:0000/104,后面的24位是单播或任播地址的低24位。被请求节点组播地址主要用于替代ipv4的地址解析协议(address resolution protocol,arp)来获取邻居的mac地址以生成邻居表,并用在局域网进行地址冲突检测。 -
组播地址到
mac地址的映射
组播地址毕竟实在网络层使用,在以太网这样的局域网中,还需要底层链路层来封装传输数据帧,因此就需要将组播地址映射成mac地址。在ipv6中,映射关系是前16位位固定的十六进制3333,然后再加上组播地址的低32位,这就构成了48位mac地址。
例如,组播地址是FF02::1111:AAAA:BBBB,则对应的mac地址就是33-33-AA-AA-BB-BB
- 路由器上常用的
ipv6地址
本实验主要是为了让我们熟悉路由器至少应具有哪些ipv6地址,并能知道每个ipv6地址的类型和用途。
路由器配置。开启路由器R1,并进行如下配置:
Router>enable
Router#configure terminal
Router(config)#ipv6 unicast-routing
Router(config)#interface ethernet 0/0
Router(config-if)#ipv6 enable
Router(config-if)#ipv6 address 2001::1/64
Router(config-if)#no shutdown
查看路由器接口的ipv6地址
Router#show ipv6 interface ethernet 0/0
Ethernet0/0 is up, line protocol is up
IPv6 is enabled, link-local address is FE80::A8BB:CCFF:FE00:300
No Virtual link-local address(es):
Global unicast address(es):
2001::1, subnet is 2001::/64
Joined group address(es):
FF02::1
FF02::2
FF02::1:FF00:1
FF02::1:FF00:300
可以看到,路由器接口具有多个ipv6地址,其地址和含义如下
| ipv6地址 | 含义 |
|---|---|
| FE80::A8BB:CCFF:FE00:300 | 接口只要启用了ipv6,就会有一个链路本地单播地址 |
| 2001::1 | 为接口手动配置的全球单播地址 |
| FF02::1 | 加入的本地链路所有节点组播地址 |
| FF02::2 | 加入的本地链路所有路由器组播地址 |
| FF02::1:FF00:1 | 全球单播地址对应的被请求节点组播地址 |
| FF02::1:FF00:300 | 链路本地单播地址对应的被请求节点组播地址 |
通过实验可以发现,即使路由器没有运行组播路由协议,其接口也默认会加入一些组播组中,接收目的地址是这些组播地址的数据包
在R1上ping本地链路所有的路由器组播地址ff02::2,结果如下:
R1>ping ff02::2
Output Interface: ethernet0/0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to FF02::2, timeout is 2 seconds:
Packet sent with a source address of FE80::A8BB:CCFF:FE00:100%Ethernet0/0
Reply to request 0 received from FE80::A8BB:CCFF:FE00:200, 1 ms
Reply to request 1 received from FE80::A8BB:CCFF:FE00:200, 1 ms
Reply to request 2 received from FE80::A8BB:CCFF:FE00:200, 1 ms
Reply to request 3 received from FE80::A8BB:CCFF:FE00:200, 1 ms
Reply to request 4 received from FE80::A8BB:CCFF:FE00:200, 1 ms
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/1 ms
5 multicast replies and 0 errors.
可见,R2的链路本地地址FE80::A8BB:CCFF:FE00:200对ff02::2进行了回应
抓包分析。右键单击R2,从快捷菜单中选择capture-->e0/0,

从结果来看,R2在收到目的地址是ff02::2(本地链路所有路由器的组播地址)的包围请求后,由于它也是此组播组成员,因此使用本地链路单播地址进行回应。同时可以发现,收到的组播报文的目的mac地址是33:33:00:00:00:02,即ff02::2对应的mac地址
为指定地址和本地环回地址
未指定地址就是128位全是0的地址,可以表示为::/128,其用途与ipv4的全0地址一样,可在接口还未自动获取到ipv6地址时,用作源地址。
环回地址是除了最后一位是1外,其余位全是0,可以表示为::1/128。
本地环回地址跟ipv4的本地环回地址一样,用于测试网络协议是否正常。
发送给本地环回地址的数据包并不会从本机网络接口发送出去,而是由本机自己响应。
windows等主机默认设有本地环回地址,可以在命令提示符下执行netsh interface ipv6 show interface查看环回地址,也可以在主机上自行ping本地环回地址。
ICMPv6
与ipv4地址一样,ipv6报文在网络传输中也需要一种协议来报告它在网络中的状态,这就是icmpv6,它是ipv6协议的一个重要组成部分。
ipv6网络中的每一个节点都必须实现icmpv6,当任何一个节点无法正确处理所接收到的ipv6报文时,系统就会通过icmpv6向源节点发送消息报文或差错报文,让源节点知道报文的传输情况。
比如,ping,就是通过发送icmpv6请求报文和回应报文来确定目的节点的可达性。
再比如,假如一个ipv6报文太大,路由器不能将其转发到下一跳,那么路由器就会发送icmpv6报文向源节点报告报文太大,源节点就可以适当调整报文大小,重新发送。
相较于icmpv4,icmpv6报文实现的功能更多,ipv4网络中使用的icmp、arp、igmp、rarp等功能,在ipv6网络中均有icmpv6替代实现。
除此之外,icmpv6报文还用于ipv6的无状态地址配置、重复地址检测、前缀重新编制、路径最大传输单元(maximum transmission unit,mtu)发现等。
总体来说,icmpv6实现了5种网络功能:错误报告、网络诊断、邻居发现、多播实现和路由重定向。
这些功能主要是依靠icmpv6的差错报文和消息报文实现的。
差错报文主要包括目的不可达、报文分组过大、超时、参数错误等。
消息报文主要包括请求报文、回应报文、邻居请求、邻居通告、路由器请求、路由器通告等。
icmpv6差错报文

icmpv6报文的格式如上,类型占8位,其最高位是0时,即类型值范围为0~127时,为差错报文;最高位为1时,即类型值范围为128~255时,为消息报文。
代码字段占8位,表示类型的详细信息。比如类型为1时表示目的不可达,但目的不可达的原有有多种,代码为3时表示地址不可达,代码为4时表示端口不可达。
校验和字段占16位,用于为报文的正确传输提供校验。整个icmpv6报文封装在ipv6报头中,其ipv6报头中一下报头值是58.
icmpv6常见的差错报文类型和代码如下:

icmpv6差错报文主要是用于网络中的错误诊断,代码字段是对类型字段更详细的说明。需要明确的是,icmpv6本身不能解决网络中的故障,只是为网络排障提供线索
icmpv6消息报文
比较常见的报文是类型为128的回声请求报文和类型为129的回声应答报文。
我们在执行ping操作时,就是发送128类型的回声请求报文,并期待收到129类型的回声应答报文,从而检查网络的可达性。
常见的icmpv6消息报文如下: |
报文类型 | 报文名称 | 使用场景 |
|---|---|---|---|
| 128 | 回声请求 | ping请求 | |
| 129 | 回声应答 | ping应答 | |
| 133 | 路由器请求 | 用于网关发现和ipv6地址自动配置 | |
| 134 | 路由器通告 | 用于网关发现和ipv6地址自动配置 | |
| 135 | 邻居请求 | 用于邻居发现及重复地址检测 | |
| 136 | 邻居应答 | 用于邻居发现及重复地址检测 | |
| 137 | 重定向报文 | 与ipv4的重定向类似 |
- 实验,常用的
ipv6诊断工具
ping和traceroute。这两个命令主要用于测试网络的联通性。

基本配置
R1配置如下:
enable
config terminal
host R1
ipv6 unicast-routing
interface eth0/0
ipv6 enable
ipv6 address 2001:12::1/64
no shutdown
ipv6 route ::/0 2001:12::2
R2配置如下:
enable
config terminal
host R2
ipv6 unicast-routing
interface eth0/0
ipv6 enable
ipv6 address 2001:12::2/64
no shutdown
interface eth0/1
ipv6 enable
ipv6 address 2001:23::2/64
no shutdown
R3配置如下:
enable
config terminal
host R3
ipv6 unicast-routing
interface eth0/0
ipv6 enable
ipv6 address 2001:23::3/64
no shutdown
ipv6 route ::/0 2001:23::2
ping命令测试。在路由器R1上执行命令ping 2001:12::2,抓包后internet control message protocol v6层,可以看到type类型是echo (ping) request (128),说明这是一个回声请求报文,报文类型是128


可以看到type(类型)是echo (ping) reply (129),说明这是一个回声应答报文,报文类型是129
-
traceroute命令测试。traceroute是另一个必不可少的网络诊断工具,可以显示ip数据报文从一个节点传到另一个节点所经过的路径。R1#traceroute 2001:23::3 Type escape sequence to abort. Tracing the route to 2001:23::3 1 2001:12::2 1 msec 0 msec 0 msec //traceroute的同样报文会发3次,所以这里有3个时间 2 2001:23::3 33 msec 0 msec 0 msec由上可知,
R1可以到达2001:23::3,且中间经过了一台路由器2001:12::2。

编号为3的报文是第一个报文,在中间栏可以看到hop limit:1,表示这个报文的跳数限制是1.
当路由器R2收到这个报文后,hop limit=0表示这个报文将倍丢弃,同时R2向报文的源发送方反馈一个报文,告诉它报文被丢弃了,这个反馈报文也就是编号为4的报文。
从这个捕获的报文中,也可以看出traceroute使用的是UDP

编号为4的报文是R2返回给R1的ICMPv6报文,用来告诉R1目的不可达,并且反馈了具体的原因是type:time exceeded(3),更具体的原因则是下一行code:0(hop limit exceeded in transit,即传输过程中跳数超限。
当R1收到R2返回的报文时,R1就知道了去往目的ipv6地址所经过的第一跳路由器的ipv6地址。
当R1收到R3返回的报文时(下图编号为10的报文,type=1 code=4),R1就知道了去往目的ipv6地址所经过的第二跳路由器的ipv6地址。
接下来源会发送hop limit=3、4、4...的报文,直至最终到达目的地,这样源就会直到中间经过的每一台路由器的ipv6地址

有时会探测不到中间某台路由器的ipv6地址,这通常是中间路由器做了数据包过滤或网络安全防护,以阻止接收traceroute的udp报文或者在接收报文后拒绝反馈报文,这样潜在的攻击者就探测不到中间路由器的ipv6地址,也就无从对其发动攻击。
pmtu(路径mtu)
在网络通信中,每一条通信链路都有一个允许传输的最大传输单元mtu,当一个数据报文长度超过mtu值时,就必须在链路的源节点处进行分片后传输,在到达链路的目的节点后再按一定的规则将分片的数据报文重新组装。
ipv6网络不再允许中间路由器对数据报文进行分片和重组,这些操作只能在源节点和目的节点上进行。
那么为了避免中间路由器进行分片和重组,那么从源节点发送出来的数据报文的大小,就不能超过在到达目的节点之前所经过的每一条链路的mtu值。即数据报文在从源到目的的路径上所经过的每一条链路中,谁的mtu最小,谁就是源到目的路径上的路径mtu(pmtu)。
pmtu的值是这样找到的:向路径中的每一个节点发送长icmpv6报文,直到收到类型为2(分组过大)的icmpv6差错报文,然后再逐渐调小icmpv6报文,最终找到pmtu值。
本实验用来演示在发送较大报文时,网络设备如何进行分片处理。同时,通过本实验也能看到ipv6使用类型为44的扩展报头来分片。
- 正常
ping测试,在R1上ping 2001:23::3,思科路由器默认的ping包大小是52字节,字符是从00开始的十六进制编码字符。

- 扩展
ping测试。改变默认的ping包大小。R1#ping 2001:23::3 size ? <48-18024> Datagram size //因为ipv6数据包的封装默认占用了48字节,size为80,则真正发送的字符只有80-48=32字节
在R1上执行ping 2001:23::3 size 10000命令,ping包的大小是10000字节。

发送的icmpv6回声报文被分成了7段,前6段的长度为固定的1510字节,最后一段是1334字节。路由器回应的报文一样被分成7段
分片报文使用了ipv6扩展报头,即下一报头为44的分片扩展报头。再在分段报头中指明下一包头为58,即icmpv6
- 修改路由器
R2的e0/1接口的ipv6 mtu值R2(config-if)#ipv6 mtu ? <1280-1500> MTU (bytes) R2(config-if)#ipv6 mtu 1400 //将mtu改为1400字节
继续在R1上执行ping 2001:23::3 size 10000命令,捕获的数据报文如下图:

编号3~9可以看出,从R1发出来的数据报文分片大小没有变化,仍然是1510字节(最后一段是1314字节)。
但当分片报文从路由器R2 e0/1接口发出时,因大于mtu值而被丢弃,R2向R1返回了packet too big的报错信息(编号10~15),并告诉R1它能接受的mut值是1400字节。
R1再次发出ping报文(编号16~23),每个ping报文的大小是1400-48=1352字节,10000字节大小的数据包被分成了8段。
R3返回R1的报文(编号24~30)大小仍然是1510字节,这也说明mtu的修改只影响从本地接口发送出去的数据报文的分片大小,接收的报文不受影响。
使用如下命令还原R2 e0/1接口的默认mtu大小:
R2(config-if)#no ipv6 mtu
因为存在mtu缓存。路由器R1执行命令R1#clear ipv6 mtu,此时捕获的数据报文被还原到1510字节。
NDP
NDP简介
邻居发现协议(neighbor discovery protocol,ndp)是ipv6协议体系中最重要的基础协议之一,很多ipv6功能都依赖ndp来实现。
ndp可以实现的功能包括:替代ipv4的arp来形成邻居表;默认网关的自动获取;无状态地址自动配置;路由重定向等。
以太网如何获知目的节点的mac地址?在ipv4网络中,该地址是通过广播arp报文来获取的,一旦获知目的节点的mac地址,就将ip和mac的对应关系写入自身的arp表中。
而在ipv6中,邻居表中记录着同一局域网内邻居的ipv6地址与mac地址的对应关系。如果邻居表中没有目的地址的mac地址,则使用ndp来发现并形成邻居表。
在局域网中,自动配置地址的主机会主动寻找网关,而路由器默认也会通告自己是默认网关。路由器在通过自己是默认网关的同时,会携带自身的链路层地址,因此主机无须再次运行ndp来解析默认网关的链路层地址。
路由器在通告自己是默认网关的同时,可以携带前缀信息,使主机可以根据获得的前缀信息自动生成ipv6地址。
路由重定向也属于ndp的作用范围。ipv6的路由重定向,即首选的默认网关发现到达目的地有更好的路由器网关时,会向其转发数据报文,并同时向源节点发送路由重定向报文,告知源节点有更好的下一跳到达目的节点,同时会在重定向报文中携带新的网关的链路层地址。
NDP常用报文格式
ndp定义了5类icmpv6报文,即路由请求(router solicitor,rs)报文、路由器通告(router advertisement,ra)报文、邻居请求(neighbor solicitor,ns)报文、邻居通告(neighbor advertisement,na)报文和路由重定向吧。这5种类型的icmpv6报文都是消息类型的报文,用来实现邻居链路层地址解析、网关发现、地址自动配置和路由重定向等功能。
RS报文,RS报文供ipv6主机用以查找本地链路上存在的路由器,主机发送RS报文会触发同网段的路由器立即回复RA报文,以获取前缀信息、mtu信息等,而不用等待路由器周期性地发送ra报文。

ipv6主机发送rs报文时,目的地址为预定义的本地链路所有路由器的组播地址ff02::2,源地址是自身接口fe80打头的链路本地地址。数据链路层源地址是rs报文主机的mac地址,目的地址是ff02::2对应的组播mac地址3333-0000-0002
RA报文,路由器会周期性(思科路由器默认是200s)地发送ra报文,向邻居节点通告自己的存在。ra报文可以携带一些路由前缀、自身链路层等参数信息。

通过抓包发现:无论是路由器主动的周期性通告,还是收到rs报文后的被动应答,ra报文的目的地址都是组播地址ff02::1
跳数限制字段用来告知ipv6主机后面发送的单播报文将使用的默认跳数值。
M位和O位是dhcpv6相关的选项。当M位是1时,告知ipv6主机使用dhcpv6来获取ipv6地址;当O位是1时,则是告知ipv6主机使用dhcpv6获取其他参数信息,如dns地址信息等。
路由器生存期字段占16位,用来告知ipv6主机本路由器作为默认网关时的有效期,单位是秒。当该字段为0时,表示本路由器不能作为默认路由器。
可达时间选项用来告知ipv6主机邻居表中关于自己的可达信息。
重传时间字段为周期性发送ra报文的时间间隔。
选项字段可以包括路由器接口的链路层地址、mtu、单薄前缀信息等。
NS报文,用于查询邻居节点的链路层地址。ns报文中的目的地址字段存放的是想要解析成链路层地址的ipv6单播地址。选项字段可以携带自身的链路层地址

当ns报文用于邻居可达性检测时,目的地址是单播地址;当用于邻居解析时,目的地址是被请求节点的组播地址ff02::1:ff00:0/104加目的单播地址的最后24位。
ipv6节点在检测ipv6地址冲突时,也会发送邻居请求报文,此时目的ipv6地址是被请求节点的组播地址ff02::1:ff00:0/104加自己ipv6地址的最后24位,若收不到回复则表示ipv6地址没有冲突,ipv6配置生效。
在实际配置中发现,windows计算机配置ipv6地址时若存在地址冲突,不会弹出信息,只能在命令行模式执行ipconfig查看ipv6地址是否有效。
在路由器上配置ipv6地址时,若存在地址冲突,会提示:duplicate address
NA报文,ipv6节点通过使用na报文来通告自己的存在,或者告诉邻居需要更新自己的链路层地址信息。
当节点发送na报文来回应ns报文时,目的地址使用单播地址,如果目的是告诉邻居需要更新自己的链路层地址信息,则使用组播地址ff02::1作为目的地址。
na报文有3个标志位:当R位为1时表示此报文是由路由器发送的;当S位为1时表示是ns报文的回复;当O位为1时则表示需要更改原先的邻居表条目。
在S位为1的情况下,na报文的源地址是对应ns报文中的目的地址字段
如果S位为0,则na报文的源地址就是自身需要更新链路层地址信息的接口ipv6地址。
选项字段是发送na报文设备的链路层地址。
默认路由自动发现
ipv6主机维护的表项
在ndp中,每一个ipv6节点都需要跟踪和维护至少包括邻居表在内的多张表
-
邻居表:记录着同一局域网中相邻
ipv6节点的mac地址等信息,而且会标明邻居是路由器网关还是普通主机。在计算机上查看邻居表的命令是netsh interface ipv6 show neighbors -
目的地缓存表:记录的是最近发送的目的地址,可实现快速转发功能。可以将目的地缓存表理解为缓存下来的路由表。在计算机上查看缓存表的命令是
netsh interface ipv6 show destinationcache -
路由表:主机在发送报文前,为了决定该如何到达目的地址而查询的表。路由表中至少包括自身接口所在的前缀列表,可以将前缀列表理解为主机的直连路由,如
fe80::/64和自身ipv6单播地址的前缀。对于不在本网段的地址,路由表中可以有明确的下一跳或者能匹配的默认路由。在计算机上查看路由表的命令是route print
ipv6主机发送报文过程
一台主机如果要向目的地发送报文,需要经历以下过程
-
1.查找目的缓存表,看目的地址是否与表中的表项有匹配,如果有匹配,直接跳到第三步查找邻居表,否则到第二步查找路由表
-
2.查找路由表,看目的地址是否有匹配项。如果有匹配,则转下一步;如果没匹配,则会向数据包中的源
ipv6地址发送icmpv6差错报文 -
3.检查下一跳地址在邻居表中是否有匹配,如果有,则提取其对应的链路层地址进行封装转发;如果没有,则通过
ndp来获取下一跳节点的链路层地址,再进行封装转发
默认路由自动发现过程
在ipv6中,如果要自动获取默认路由,即默认网关,那么都是/只能通过rs和ra报文来完成的。
这与ipv4通过dhcp来下发默认路由的机制不一样,即便是dhcpv6也不能下发默认路由。
首先,路由器会周期性地向组播地址ff02::1发送ra报文,向网段中的主机通告自己是默认路由;
其次,主机自动获取网络配置时,也会发送rs报文,以查找网段中的默认路由
在这个过程中,可能会出现多个路由器同时发送ra报文的情况,从而导致主机有多个默认路由。此时就可以在交换机的非信任端口上禁止接收路由器的ra报文,以避免用户获取到错误的网关。
还有一种办法是在主机上手动设置默认路由的优先级。
- 实验网关欺骗防范
本实验将用路由器向主机通告自己是默认路由,同时也会将自己的链路层地址发送给主机,以便主机更新自己的邻居表。
通过本实验,可以了解当同网段有多台路由器通告自己是默认路由时,主机如何选中正确的默认路由;路由器如何发送ra报文,以及如何修改路由器ra报文中的属性;在主机上如何查看邻居表和路由表,如何手动设置路由表以及如何手动选择正确的默认路由等。

-
基本配置。
R1配置如下:Router>enable R1#configure terminal R1(config)#ipv6 unicast-routing R1(config)#interface ethernet 0/0 R1(config-if)#ipv6 enable R1(config-if)#ipv6 address 2001:2019::1/64 R1(config-if)#no shutdown R1(config)#interface loopback 0 R1(config-if)#ipv6 address 2001:2019:1::1/64 -
查看地址分配。在
win10的命令提示符窗口使用ipconfig命令查看获得的地址以及默认网关

默认网关是路由器R1的ethernet0/0接口的链路本地地址。win10自动获得一个ipv6地址和一个临时ipv6地址,两者的前缀都是2001:2019::/64。前缀信息也是通过ra报文来通告的。
- 查看邻居表。在
win10上使用命令netsh interface ipv6 show neighbors "4"查看邻居表。

默认网关的物理地址已经解析,类型如果为停滞,是因为还没进行可达性检测。
2001:2019::1是路由器R1 e0/0接口配置的ipv6地址,fe80::a8bb:ccff: fe00:400是路由器R1 e0/0接口的链路本地地址,这两者的mac地址是一样的。
-
更新邻居表。在
win10上ping路由器的链路本地地址,强制对邻居表中默认网关的物理地址进行可达性检测。停滞会变成可以访问类型 -
查看路由表。在
win10上使用route print -6命令查看ipv6的路由表

- 修改
RA属性,在r1上将ra报文的lifetime属性改为0
R1(config-if)#ipv6 nd ra lifetime ?
<0-9000> RA Lifetime (seconds)
R1(config-if)#ipv6 nd ra lifetime 0
在win10上使用ipconfig命令查看网络配置,发现默认网关没有了,这是因为ra报文的lifetime一旦为0,就表明路由器不再是默认网关,但ipv6地址仍在,即ra报文还是可以携带前缀信息给客户。
- 加入非法路由器。将
lifetime属性修改成默认值no ipv6 nd ra lifetime
再打开路由器R2进行配置Router>enable R2#configure terminal R2(config)#ipv6 unicast-routing R2(config)#interface ethernet 0/0 R2(config-if)#ipv6 enable R2(config-if)#ipv6 address 2001:2018::1/64 R2(config-if)#no shutdown R2(config)#interface loopback 0 R2(config-if)#ipv6 address 2001:2018:1::1/64
此时网络中的两台路由器同时发送ra报文。在win10上使用命令route print -6查看路由表

自动获取到了两条跃点数都是266的等价默认路由,分别是R1和R2对应接口的链路本地地址。
在主机上使用ipconfig命令也会卡卡难道同时存在两个默认网关。有了两条等价的默认路由,通信中就会产生负载均衡效果,但具体到哪一个数据包走哪一条默认路由却不可控。
- 修改跃点数。两条默认路由的跃点数(
metric)都为266。主机在选择默认路由时,纵使优先选择跃点数较小的路由。可以通过命令route change将优选默认路由的metric值设置为小于256(进入路由表时,这个metric会被自动加10)。-p参数,表示永久的意思。

再次查看路由表,发现只有一条默认路由了,其跃点数是110(100+10=110)。
- 添加明细路由。永久路由是需要管理员使用命令
route add手动添加的。在win10执行route add 2001:2018:1::/64 fe80::a8bb:ccff:fe00:500 –p命令,添加明细路由。此时查看路由表,会发现路由表最后多出一条永久路由。

地址解析过程及邻居表
-
地址解析过程:主机或路由器将邻居节点的
ipv6地址解析成链路层mac地址,然后再保存再邻居表中的过程。这个解析过程是通过ns和na报文来完成的,主要步骤如下-
1.节点发送一个目的地址是被请求节点组播地址的
ns报文,此请求报文选项中携带了节点自身的链路层mac地址,以便邻居能快速解析自身的链路层mac地址。被请求节点的组播地址是ff02::1:ff00:0/104外加单播地址的末24位。比如想要解析fe80::abcd:1234的链路层mac地址,发送的ns报文的目的地址就是ff02::1:ffcd:1234 -
2.目的节点收到
ns报文后,首先提取源地址和报文选项中的源链路层mac地址,形成映射关系,再添加或更新本地邻居表。然后再向请求者发送目的地址为单播地址的na报文,并在报文中携带自己的链路层mac地址。 -
3.最初的节点收到
na报文后,根据其内容更新自己的本地邻居表
-
-
邻居表及邻居状态信息,每个
ipv6节点都会跟踪和维护邻居表。邻居表记录邻居状态信息的目的也是为了尽快发现和解决网络中断问题,邻居表中记录着每个邻居的状态。 -
实验查看邻居表:通过本实验可以掌握如何在
windows主机和路由器上查看邻居表,以及查看邻居表的状态-
1.
windows主机邻居表,类型是停滞(路由器),可以通过ping命令强制进行可达性检测,使地址的类型为可以访问。另外邻居表中还有一些组播地址对应的链路层地址,其类型都是永久。这些对应的链路层mac地址都是固定的33-33加上组播地址的低32位地址。
在ipv6中,攻击者可以发送ra或na报文,让主机将默认路由或主机的错误链路层地址更新到邻居表。对于windows主机,手动绑定的命令是netsh interface ipv6 set neighbor "接口id" 邻居ipv6地址 邻居链路层mac地址。 -
2.路由器邻居表。在路由器
R1上通过命令show ipv6 neighbors查看邻居表R1#show ipv6 neighbors IPv6 Address Age Link-layer Addr State Interface 2001:2019::75C2:A389:5FF1:5BCD 0 5000.0001.0000 REACH Et0/0 2001:2019::E894:896E:8686:3BC4 0 5000.0002.0000 STALE Et0/0 FE80::5D03:AE85:29E0:6B2B 0 5000.0002.0000 REACH Et0/0 FE80::FD70:2E95:9D73:6B85 1 5000.0001.0000 STALE Et0/0同样在路由器上也可以手动绑定邻居的链路层`mac`地址,可在路由器上执行如下命令
R1(config)#ipv6 neighbor 2001:2019::E894:896E:8686:3BC4 ethernet 0/0 5000.0002.0000 R1(config)#do show ipv6 neighbors //可以在特权模式执行show命令,前面加do IPv6 Address Age Link-layer Addr State Interface 2001:2019::75C2:A389:5FF1:5BCD 0 5000.0001.0000 REACH Et0/0 2001:2019::E894:896E:8686:3BC4 - 5000.0002.0000 REACH Et0/0 FE80::5D03:AE85:29E0:6B2B 0 5000.0002.0000 REACH Et0/0 FE80::FD70:2E95:9D73:6B85 0 5000.0001.0000 REACH Et0/0注意到在手动绑定后,该条目的
age栏中显示为-,这表示永不过期的意思。保存路由器的配置文件时,这条配置命令也被保存,路由器在重启后绑定仍然有效。
-
路由重定向
当路由器收到一个报文时,若发现同网段有更好的下一跳,则向发送方发送重定向报文。具体过程如下
- 发送方在向一个目的地址发送
ipv6单播报文时,根据路由表中的最佳匹配原则,将报文发送给下一跳路由器 - 路由器收到报文后查找路由表,发现去往目的的下一跳地址与报文中的源地址处于同一网段。
- 路由器继续转发报文给下一跳路由器,同时向发送方发送路由重定向报文,告知源节点去往此目的地有更好的下一跳。这个更好的下一跳地址在重定向报文中的目的地址字段中指定,且该地址与源节点处于同一网段。源节点收到路由重定向报文后,是否采用新的下一跳地址转发后续报文,由源节点的配置决定。
ipv6层次化地址规划
ipv6地址在分配上采用层次化的路由分配原则,尽可能减少主干路由条目数,从而提高网络转发效率。什么是层次化规划呢?就是在进行网络规划时,按网络区域从大到小的顺序,对应着ipv6前缀长度有短到长的规律来划分地址。

从上表可以看出,一个省级单位申请到/48位的地址,而到市级单位,就可以使用/52位,也就是到市级单位时,可以划分16个子网。每个市级单位再往下到县级单位,就可以使用/56位地址,同样,每个市下面可以支持16个子网分别用于各个县级单位。每个县还可以进一步把/56的地址分到下面的各个乡镇。
当这样做好规划后,网络就可以按区域来汇聚路由。对于省级单位的路由器来说,一条2001:1:1:0000::/52路由条目就包括了整个A市,不用再单独针对某个县来写具体的/56位路由。
虽然最新的标志规定主机节点使用的ipv6地址前缀长度必须是64位,但其实很多网络设备和终端主机都支持更长的前缀长度,也就是说用户主机完全可以使用/80位这样的前缀长度,从而使层次化规划的层级数可以更深入、更细致。
假定某高校申请到一个2001:1:1::/48地址段,该高校有3个校区。每个校区又包括两个教学区域和两个宿舍区域。每个区域又由若干栋楼宇组成。ipv6地址可进行如下规划
- A校区:
2001:1:1:0000::/50 - B校区:
2001:1:1:4000::/50 - C校区:
2001:1:1:8000::/50 - D校区:
2001:1:1:c000::/50
以C校区为例,继续划分4个区域,采用/52来划分
- 教学区1地址:
2001:1:1:8000::/52 - 教学区2地址:
2001:1:1:9000::/52 - 宿舍区1地址:
2001:1:1:a000::/52 - 宿舍区2地址:
2001:1:1:b000::/52
再以教学区1为例,可以再按/56给楼宇分配地址,总共支持16栋楼宇,地址段分别为2001:1:1:8000::/56、2001:1:1:8100::/56...2001:1:1:8f00::/56
最后可以再为每栋楼宇划分/64地址,每栋楼可以分配256个子网
这样的ipv6地址就有层次化概念。只要确定ipv6地址所在的网段,就能快速定位再哪栋楼哪个网段;同时,由于路由条目层次分明,在主干上也便于进行路由聚合,这样一来条目数也大大减少,转发效率也会提高。
留言