ICMP是一种面向无连接的协议,负责传递可能需要注意的差错和控制报文,差错指示通信网络是否存在错误(如目的主机无法到达、IP路由器无法正常传输数据包等。注意,路由器缓冲区溢出导致的丢包不包括在ICMP响应范围内,在TCP负责范围)。
ICMPv4和ICMPv6分别指用于IPv4和IPv6的ICMP版本。在IPv4中,协议字段值为1表示该报文携带了ICMPv4;在IPv6中,ICMPv6报文位于扩展头部里,ICMPv6扩展头部上一个头部包含了值为58的"下一个头部"字段。
ICMP报文
所有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发现机制)。
传入的ICMPv6报文处理规则如下:
1. 未知的ICMPv6差错报文必须传递给上层产生差错报文的进程;
2. 未知的ICMPv6信息类报文被丢弃;
3. ICMPv6差错报文将会尽可能多地包含到差错的原始(违规)IPv6报文,最终的差错报文大小不能超过最小的IPv6 MTU(1280字节);
4. 在处理ICMPv6差错报文时,需要提取原始或违规数据包中的上层协议类型,用于选择适当的上层进程;
5. 存在处理差错的特殊规则;
6. IPv6节点必须限制它发生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(外地代理支持区域注册)。