3、什么是ICMPv6
要知道什么是ICMPv6协议、我们首先要知道什么是ICMP?ICMP是一种面向无连接的协议,负责传递可能需要注意的差错和控制报文,差错指示通信网络是否存在错误(如目的主机无法到达、IP路由器无法正常传输数据包等。注意,路由器缓冲区溢出导致的丢包不包括在ICMP响应范围内,在TCP负责范围)。
ICMPv4和ICMPv6分别指用于IPv4和IPv6的ICMP版本。在IPv4网络中,ICMP协议用于在路由器、主机之间传递控制消息,主要有控制报文与信息报文。比如主机不可达、路由是否可用或者网络通不通等消息。这些信息也是我们日常去排查网络所用到的基本手段。当然,控制消息本身不会传输数据,但对于整个网络而言,对于传输数据而言,都是不可或缺的一部分。
与IPv4一样,IPv6也需要使用到ICMP报文;在IPv6中,ICMP开发了新的版本,称之为ICMPv6。ICMPv6 全称 Internet Control Message Protocol for the IPv6,它是IPv6的基础协议之一。那么它和ICMPV4有什么区别呢?相较于ICMPv4,ICMPv6实现的功能更多,IPv4网络中使用的ICMP、ARP、IGMP、RARP等功能,在IPv6网络中均由ICMPv6替代实现。除此之外,ICMPv6报文还用于IPv6的无状态自动配置、重复地址检测、前缀重新编址、路径MTU(Maximum Transmission Unit,最大传输单元)发现等。在IPv4中,协议字段值为1表示该报文携带了ICMPv4;在IPv6中,ICMPv6报文位于扩展头部里,ICMPv6扩展头部上一个头部包含了值为58的”下一个头部”字段。
当然、 ICMPv6协议还用以汇报IPv6节点在数据文件处理方式中发生的不正确信息,并完成简易的网络诊断作用。ICMPv6新增多的邻居发现作用替代了ARP协议的作用,因此 ,在IPv6网络体系结构中早已沒有ARP协议了。除了支持IPv6详细地址文件格式以外,ICMPv6还给支持IPv6中的路由器优化、IP组播、移动IP等增多了一些新的报文格式种类。
下面我们一起来看看IMCPv6的三个重要知识点:ICMPv6差错报文、ICMPv6消息报文和PMTU(路径MTU)。
3.1、ICMPv6差错报文
ICMP报文可分为两类:有关IP数据报传递的ICMP报文(差错报文)和信息采集和配置的ICMP报文(查询或者信息类报文)。ICMP差错报文不会对以下报文进行响应:
- 另一个ICMP差错报文;
-
头部损坏的数据报;
-
IP层的广播/组播数据报;
-
封装在链路层广播或者组播帧中的数据报;
-
无效或者网络为零的源地址数据报;
-
或除第一个之外的其他分片。
限制生成ICMP差错报文的原因是限制生成广播风暴。在[RFC4443]中,推荐采用令牌桶(token bucket)方法来限制ICMP报文速率。过程如下(一令牌大小为一字节):
- 假设”桶”里保存了最大数量”B”的”令牌”,如果”令牌”到达时”桶”满了,则”令牌”被丢弃;
-
当一个N字节的数据包达到,如果”桶”中多于N个”令牌”,则删除N个”令牌”,且数据包被发送到网络;如果”桶”中少于N个”令牌”,则不删除”令牌”,且认为这个数据包在流量限制之外。
ICMPv4到ICMPv6的转换只有回显请求和回显应答报文被转换,为了执行这个转换,类型值(8和0)分别被转换到值128和129。在转换之后,计算并应用ICMPv6的伪头部校验和。当转换ICMPv4差错报文时,只有下面的差错报文被转换了:目的不可达(类型3),超时(类型11),参数问题(类型12)。ICMPv6到ICMPv4的转换回显请求(类型128)和回显应答(类型129)报文被分别转换到ICMPv4回显请求(类型8)和回显应答(类型0),更新校验和以体现类型值变化和缺少为头部计算,其他信息类报文将被丢弃。
好了、说了这么多;我们在试验环境中抓一个ICMPv6的数据包看看。试验拓扑和配置信息如下:
# R1配置
Router>en
Router#conf t
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)#host R1
R1(config)#ipv6 unicast-routing
R1(config)#inter ethernet 0/0
R1(config-if)#ipv6 enable
R1(config-if)#ipv6 add 2001:12::1/64
R1(config-if)#no shutdown
R1(config)#ipv6 route ::/0 2001:12::2
R1(config)#end
R1#wr
Building configuration...
[OK]
R1#
# R2配置
Router>en
Router#conf t
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)#host R2
R2(config)#ipv6 unicast-routing
R2(config)#inter ethernet 0/0
R2(config-if)#ipv6 add 2001:12::2/64
R2(config-if)#no shutdown
*Jan 7 19:50:06.281: %LINK-3-UPDOWN: Interface Ethernet0/0, changed state to up
*Jan 7 19:50:07.285: %LINEPROTO-5-UPDOWN: Line protocol on Interface Ethernet0/0, changed state to up
R2(config-if)#exit
R2(config)#int ethernet 0/1
R2(config-if)#ipv6 enable
R2(config-if)#ipv6 add 2001:23::2/64
R2(config-if)#no shutdown
R2(config-if)#end
R2#wr
Building configuration...
[OK]
R2#
# R3配置
Router>en
Router#conf t
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)#host R3
R3(config)#ipv6 unicast-routing
R3(config)#interface ethernet 0/0
R3(config-if)#ipv6 enable
R3(config-if)#ipv6 address 2001:23::3/64
R3(config-if)#no shutdown
R3(config)#ipv6 route ::/0 2001:23::2
R3(config)#end
R3#wr
Building configuration...
[OK]
R3#
配置完成以后我们在R1路由器上ping 2001:23::3这个地址,然后在R2上抓ETH0/1的接口数据包:
抓包内容如下:
注:从上图我们可以看到、ping 2001:23::3命令执行后发送的数据包和返回的数据包;其中发送数据类型request是128,而返回数据类型reply是129;ping命令Data长度是52个字节,而Data的数据内容为:0001–33的ASIIC码(换成十进制就是从00-51)。
3.2、ICMPv6消息报文
由于某些ICMP的功能已经被其他特殊目的的协议代替,保存下来的广泛使用的ICMP查询/信息类报文是回显请求/应答报文(常用的”ping”),以及路由器发现报文。回显请求/应答相对简单,收到回显请求之后,ICMP的实现要求将任何收到的数据返回给发送者。其报文结构如下:
发送主机利用标识符来分离返回的应答(如多个ping同时允许的时候,用于区分返回的应答)。当一个ping实例运行时,序列号从0开始,每发送一个回显请求则加1.路由器发现则较为复杂,也就是与移动IP一起使用的那个。其主要目的是让一台主机学习到它所在的本地子网中所有路由器,从而选择一台作为默认路由器,也用于发现那些愿意充当移动IP代理的路由器。
地址数给出报文中路由地址块的个数,每个块包含一个IPv4地址及相应的优先水平(优先水平是一个32位的有符号二进制补码整数,其值越大代表优先级越高。默认的优先水平是0,特殊值0x80000000表示这个地址不应该用作有效的默认路由);地址条目大小给出每个块的32位字数;生命周期给出地址列表被认为有效的秒数;序列号字段给出了自从初始化之后代理产生的这种扩展的个数;注册字段给出了发送 代理愿意接受MIPv4注册的最大秒数(0xFFFF表示无穷大);那些字母的含义:R(为MIP服务所需的注册)、B(代理太忙无法接受注册)、H(代理愿意充当本地代理)、F(代理愿意充当外地代理)、M(支持最小封装格式)、G(代理支持封装数据报的GRE隧道)、r(保留零)、T(支持反向隧道)、U(支持UDP的隧道)、X(支持撤销注册)、I(外地代理支持区域注册)。
注:由类型字段决定的ICMPv6报文类型:差错报文的类型从0-127,信息类报文类型为128-255
ICMPv6报文类型使用的代码:
一般来说,对于传入的ICMP信息,查询或信息类将被操作系统自动处理,差错类报文传递给用户进程或传输层协议(除去重定向报文和目的地不可达,前者导致主机路由表的自动更新,后者用于路径MTU发现机制)。传入的ICMPv6报文处理规则如下:
1. 未知的ICMPv6差错报文必须传递给上层产生差错报文的进程;
2. 未知的ICMPv6信息类报文被丢弃;
3. ICMPv6差错报文将会尽可能多地包含到差错的原始(违规)IPv6报文,最终的差错报文大小不能超过最小的IPv6 MTU(1280字节);
4. 在处理ICMPv6差错报文时,需要提取原始或违规数据包中的上层协议类型,用于选择适当的上层进程;
5. 存在处理差错的特殊规则;
6. IPv6节点必须限制它发生ICMPv6差错报文的速率。
3.3、PMTU(路径MTU)
在 IPv4 中,报文如果过大,必须要分片进行发送,所以在每个节点发送报文之前,设备都会根据发送接口的最大传输单元 MTU(Maximum Transmission Unit)来对报文进行分片。
但是在 IPv6 中,为了减少中间转发设备的处理压力,中间转发设备不对 IPv6 报文进行分片,报文的分片将在源节点进行。当中间转发设备的接口收到一个报文后,如果发现报文长度比转发接口的 MTU 值大,则会将其丢弃;同时将转发接口的 MTU 值通过 ICMPv6 报文的“Packet Too Big”消息发给源端主机,源端主机以该值重新发送 IPv6 报文,这样带来了额外流量开销。 PMTU 发现协议可以动态发现整条传输路径上各链路的 MTU 值,减少由于重传带来的额外流量开销。PMTU 协议是通过 ICMPv6 的 Packet Too Big 报文来完成的。首先源节点假设 PMTU 就是其出接口的 MTU,发出一个试探性的报文,当转发路径上存在一个小于当前假设的 PMTU 时,转发设备就会向源节点发送 Packet Too Big 报文,并且携带自己的 MTU 值,此后源节点将 PMTU 的假设值更改为新收到的 MTU 值继续发送报文。如此反复,直到报文到达目的地之后,源节点就能知道到达目的地的 PMTU 了。
注:在VLANIF接口下,交换机支持MTU值设置,协议栈发出的报文会按设置的MTU值分片。但是硬件芯片中不支持MTU值设置,默认最大值12K。
如上图:整条传输路径需要通过 4 条链路,每条链路的 MTU 分别是 1500、 1500、 1400、 1300,当源节点发送一个分片报文的时候,首先按照 PMTU 为 1500 进行分片并发送分片报文,当到达 MTU 为 1400的出接口时,路由器返回 Packet Too Big 错误,同时携带 MTU 值为 1400 的信息。源节点接收到之后会将报文重新按照 PMTU 为 1400 进行分片并再次发送一个分片报文,当分片报文到达 MTU 值为 1300 的出接口时,同样返回 Packet Too Big 错误,携带 MTU 值为 1300 的信息。之后源节点重新按照 PMTU 为 1300 进行分片并发送分片报文,最终到达目的地,这样就找到了该路径的 PMTU。
注:由于IPv6要求链路层所支持的最小MTU为1280,所以PMTU的值必须大于1280。我们建议您用1500作为链路的PMTU值。