TCP/IP 协议——第八章:ICMPv4和ICMPv6:Internet控制报文协议
ICMP是一种面向无连接的协议,负责传递可能需要注意的差错和控制报文,差错指示通信网络是否存在错误(如目的主机无法到达、IP路由器无法正常传输数据包等)。
注意,ICMP并不为IP网络提供可靠性,相反,它表明了某些类别的故障和配置信息。路由器缓冲区溢出导致的丢包不包括在ICMP响应范围内,在TCP负责范围。
ICMP报文
ICMP报文是在IP数据报内被封装传输的,所有ICMP报文都以8位的类型(Type)和代码(Code)字段开始,其后跟随的16位校验和(Checksum)字段涵盖整个报文。
类型字段用于确定特定的报文,ICMPv4和ICMPv6的该字段值并不相同;代码字段进一步肯定报文的含义,ICMPv4和ICMPv6的该字段值并不相同;校验和字段用于确定报文信息的正确性。
ICMP报文可分为两类:有关IP数据报传递的ICMP报文(差错报文)和信息采集和配置的ICMP报文(查询或者信息类报文)。
由类型字段决定的ICMPv4报文类型
(*)标记的类型是最常见的,(+)标记的可能包含[RFC4884]扩展对象,E表示差错报文,I表示查询/信息类报文。
ICMPv4报文类型使用的代码
由类型字段决定的ICMPv6报文类型:差错报文的类型从0-127,信息类报文类型为128-255
ICMPv6报文类型使用的代码
一般来说,对于传入的ICMP信息,查询或信息类将被操作系统自动处理,差错类报文传递给用户进程或传输层协议(除去重定向报文和目的地不可达,前者导致主机路由表的自动更新,后者用于路径MTU发现机制)。
ICMP差错报文
ICMP差错报文不会对以下报文进行响应:
1. 另一个ICMP差错报文;
2. 头部损坏的数据报;
3. IP层的广播/组播数据报;
4. 封装在链路层广播或者组播帧中的数据报;
5. 无效或者网络为零的源地址数据报;
6. 或除第一个之外的其他分片。
限制生成ICMP差错报文的原因是限制生成广播风暴。在[RFC4443]中,推荐采用令牌桶(token bucket)方法来限制ICMP报文速率。过程如下(一令牌大小为一字节):
1. 假设"桶"里保存了最大数量"B"的"令牌",如果"令牌"到达时"桶"满了,则"令牌"被丢弃;
2. 当一个N字节的数据包达到,如果"桶"中多于N个"令牌",则删除N个"令牌",且数据包被发送到网络;如果"桶"中少于N个"令牌",则不删除"令牌",且认为这个数据包在流量限制之外。
目的地不可达:表示数据报无法送达目的地,可能是因为传输过程中出了问题或接收者缺乏兴趣接受它。
(1)ICMPv4主机不可达和ICMPv6地址不可达
由路由器或者主机产生,出现在它被要求使用直接交付方法发送一个IP数据报到一个主机,但由于某些原因(例如最后一跳路由器试图发送一个ARP请求到已经不在或者关闭的主机)无法到达目的地时。
(2) ICMPv6目的无路由
当到达的数据报不必采用直接交付的方式转发,但却没有路由条目来指定下一跳该用哪个路由器。
(3) ICMPv4管理禁止通信和ICMPv6目的管理禁止通信
表明一个管理禁令(防火墙)正阻止目的地的成功通信。
(4)ICMPv4端口不可达和ICMPv6端口不可达
当传入的数据报的目的应用程序还没有准备好接收它时,就会生成一个端口不可达报文(最常出现在和UDP一起使用,端口号未被任何服务器进程使用)。
(5)ICMPv4 PTB
如果一个IPv4路由器收到一个打算转发的数据报,如果数据报大于选定的传出网络接口的MTU,则数据报需要分片。如果到达的数据报在IP头部中设置了不分片位字段,那么它会被丢弃,此时将产生ICMPv4目的不可达(PTB)报文。由于发送此报文的路由器知道下一跳的MTU,为此能够将MTU值包含在它生成的报文中(可用于路径MTU发现)。
而在ICMPv6中,因为IPv6只有数据包的发送者才能执行数据包分片,所以只产生ICMPv6目的不可达(PTB)报文,该报文能将下一跳的MTU包含在其中。
重定向:
假如一个路由器收到一个来自主机的数据报,并确定自身并不是主机将数据报投递到目的地的对应下一跳,则该路由器发送一个重定向报文到主机并将该报文发送到正确的路由器(或主机)。
也就是说,如果它能够确定给定的数据报存在一个比自己更好的下一跳路由,它就向主机发送重定向报文使其更新转发表,这样以后目的地一样的流量就会被定向到新的节点中。
ICMP超时:
当由于TTL或跳数限制字段值太小(即到达值0或1,且必须转发)致使路由器丢弃报文时,会产生ICMP超时报文。
traceroute工具:用于确定从发送者到目的地路径上的路由器。该方法首先发送IPv4 TTL字段设置为1的数据报,到期的数据报促使沿途路由器发送ICMPv4超时报文。每一轮,发送的TTL值增加1,导致数据报在更远一跳的路由器超时,并产生一个ICMP报文。
ICMP查询/信息类报文
由于某些ICMP的功能已经被其他特殊目的的协议代替,保存下来的广泛使用的ICMP查询/信息类报文是回显请求/应答报文(常用的"ping"),以及路由器发现报文。
回显请求/应答相对简单,收到回显请求之后,ICMP的实现要求将任何收到的数据返回给发送者。其报文结构如下:
发送主机利用标识符来分离返回的应答(如多个ping同时允许的时候,用于区分返回的应答)。
当一个ping实例运行时,序列号从0开始,每发送一个回显请求报文则加1。ping打印出每个返回的数据包的序列号,方便用户查看数据包是否丢失、重排或者重复。
ping程序在传出的回显请求中的可选数据区域中包含了一份本地时间拷贝,这个时间数据域中剩余的内容均包含在返回的回显应答报文中。当应答收到时,用当前时间减去应答中的时间,便得到了一个到达被ping主机的RTT估计值。