ICMP 是 Internet Control Message Protocol 的缩写,即互联网控制消息协议。它是互联网协议族的核心协议之一。它用于 TCP/IP 网络中发送控制消息,为了更有效地转发 IP 数据报和提高交付成功的机会,在网际层使用了网际控制报文协议

ICMP 是网络层协议,但是它不像 IP 协议和 ARP 协议一样直接传递给数据链路层,而是先封装成 IP 数据包然后再传递给数据链路层。所以在 IP 数据包中如果协议类型字段的值是 1 的话,就表示 IP 数据是 ICMP 报文。IP 数据包就是靠这个协议类型字段来区分不同的数据包

1. ICMP 协议类型

ICMP 协议的类型分为两大类,查询报文差错报文

1.1. 差错报文

1.1.1. 终点不可达

当路由器或主机不能交付数据报时,就向源点发送终点不可达报文。具体可再根据 ICMP 的代码字段细分为目的网络不问达、
目的主机不可达、目的协议不可达、目的端口不可达、目的网络未知,目的主机未知等 13 种错误。

1.1.2. 源点抑制

当路由器或主机由于拥塞而丢弃数据报时,就向源点发送源点抑制报文,使源点知道应当把数据报的发送速率放缓。

1.1.3. 时间超过

当路由器收到一个目的 IP 地址不是自己的 IP 数据报,会将其生存时间下 TTL 字段的值减1。若结果不为0,则将该 IP 数据报转发出去;若结果为0,除丢弃该 IP 数据报外,还要向源点发送时间超过报文。

另外,当终点在预先规定的时间内不能收到一个数据报的全部数据报片时,就把已收到的数据报片都丢弃,也会向源点发
送时间超过报文。

1.1.4. 参数问题

当路由器或目的主机收到 IP 数据报后,根椐其首部中的检验和字段发现首部在传输过程中出现了误码,就丢弃该数据报,并
向源点发送参数问题报文。

1.1.5. 改变路由

路由器把改变路由报文发送给主机,让主机知道下次应将数据报发送给另外的路由器(可通过更好的路由)

注意:

不应发送 ICMP 差错报文的情况

  1. 对 ICMP 差错报告报文不再发送 ICMP 差错报告报文。
  2. 对第一个分片的数据报片的所有后续数据报片都不发送 ICMP 差错报告报文。(只对第一个分片发送)
  3. 对具有组播地址的数据报都不发送 ICMP 差错报告报文。
  4. 对具有特殊地址(如 127.0.0.0 环回地址或 0.0.0.0 本网内主机地址)的数据报不发送 ICMP 差错报告报文。

1.2. 询问报文

1.2.1. 回送请求和回答报文

ICMP 回送请求报文是由主机或路由器向一个特定的目的主机发出的询问。收到此报文的主机必须给源主机或路由器发送 ICMP

回送回答报文。

这种询问报文用来测试目的站是否可达及了解其有关状态

1.2.2. 时间戳请求和回答报文

ICMP 时间戳请求报文是请某个主机或路由器回答当前的日期和时间。在 ICMP 时间戳回答报文中有一个 32 位的字段,其中写入的整数代表从 1900 年 1 月 1 日起到当前时刻一共有多少秒。

这种询问报文用来进行时钟同步和测量时间

2. ICMP 报文格式

从 ICMP 的报文格式来说,ICMP 是 IP 的上层协议。但是 ICMP 是分担了 IP 的一部分功能。所以,也被认为是与 IP 同层的协议

2.1. ICMP 差错报文

对于出错的 IP 数据报丢弃并发送一个 ICMP 差错报文。

ICMP报文的前8字节(类型)+出错的IP数据报首部+数据字段前8字节。ICMP差错报文是IP数据报的数据部分

2.2. ICMP 询问报文

3. ICMP 协议应用

3.1. ping 命令

ping 命令用来在IP 层次上调查与指定机器是否连通,调查数据包往复需要多少时间。为了实现这个功能,ping 命令使用了两个ICMP 报文。

3.1.1. 向目的服务器发送回显请求

首先向目的服务器上执行 ping 命令,主机会构建一个 ICMP 回显请求消息数据包(类型是8,代码是0)

在这个回显请求数据包中,除了类型和代码字段,还被追加了标识符和序号字段。标识符和序号字段分别是 16 位的字段。ping 命令在发送回显请求数据包时,会将进程号填写在标识符里。对于序号,每送出一个数据包数值就增加1。而且,回显请求的选项数据部分用来装任意数据。这个任意数据用来调整 ping 的交互数据包的大小。

3.1.2. 目的服务器发送回显应答

当192.168.1.10送到 回显请求数据包后,192.168.1.1就会向发送方192.168.1.10发送回显应答(类型是0,代码是0),这个 ICMP 回显应答数据包在 IP 层来看,与被送来的回显请求数据包基本上一样。不同的只有源、目标 IP 地址字段被交换了,Type类型字段里填入了表示回显应答的0

3.1.3. 源服务器显示相关数据

如果源服务器可以接收到回显应答数据包,那我们就认为192.168.1.1是正常工作着的。进一步,记住发送回显请求数据包的时间,与接收到回显应答数据包的时间差,就能计算出数据包一去一回所需要的时间。这个时候ping命令就会将目的服务器的 IP 地址,数据大小,往返花费的时间打印到屏幕上

ping 命令执行的时候,源主机首先会构建一个 ICMP 请求数据包,ICMP 数据包内包含多个字段。最重要的是两个,第一个是类型字段,对于请求数据包而言该字段为 8;另外一个是顺序号,主要用于区分连续 ping 的时候发出的多个数据包。每发出一个请求数据包,顺序号会自动加 1。为了能够计算往返时间 RTT,它会在报文的数据部分插入发送时间。

然后,由 ICMP 协议将这个数据包连同地址 192.168.1.2 一起交给 IP 层。IP 层将以 192.168.1.2 作为目的地址,本机 IP 地址作为源地址,加上一些其他控制信息,构建一个 IP 数据包。

接下来,需要加入 MAC 头。如果在 ARP 映射表中查找出 IP 地址 192.168.1.2 所对应的 MAC 地址,则可以直接使用;如果没有,则需要发送 ARP 协议查询 MAC 地址,获得 MAC 地址后,由数据链路层构建一个数据帧,目的地址是 IP 层传过来的 MAC 地址,源地址则是本机的 MAC 地址;还要附加上一些控制信息,依据以太网的介质访问规则,将它们传送出去。主机 B 收到这个数据帧后,先检查它的目的 MAC 地址,并和本机的 MAC 地址对比,如符合,则接收,否则就丢弃。接收后检查该数据帧,将 IP 数据包从帧中提取出来,交给本机的 IP 层。同样,IP 层检查后,将有用的信息提取后交给 ICMP 协议。主机 B 会构建一个 ICMP 应答包,应答数据包的类型字段为 0,顺序号为接收到的请求数据包中的顺序号,然后再发送出去给主机 A。在规定的时候间内,源主机如果没有接到 ICMP 的应答包,则说明目标主机不可达;如果接收到了 ICMP 应答包,则说明目标主机可达。此时,源主机会检查,用当前时刻减去该数据包最初从源主机上发出的时刻,就是 ICMP 数据包的时间延迟。

3.2. traceroute 命令

traceroute 命令是一款充分利用 ICMP 差错报文类型的应用,其主要用作追踪路由信息

首先 traceroute 会将 IP 包的 TTL 设置 为 1,然后发送 UDP 包,会填入一个端口号作为 UDP 目标端口号(默认是:33434-33534)。

当目的主机收到 UDP 包后,会返回 ICMP 差错报文消息, 该错报文类型是端口不可达,说明发送方发出的 UDP 包到达了目的主机。

4. 总结