ICMP 运行机制

ICMP(Internet Control Message Protocol,因特网控制报文协议)被主机和路由器用来彼此沟通网络层的信息。ICMP 最典型的用途是差错报告。

ICMP 报文有一个类型字段和一个编码字段,并且包含引起该 ICMP 首次生成的 IP 数据报的首部和前 8 个字节(以便发送方能确定引发该差错的数据报)。下表是相关的 ICMP 报文类型:

ICMP 类型 编码 描述
0 0 回显回答(对 ping 的回答)
3 0 目的网络不可达
3 1 目的主机不可达
3 2 目的协议不可达
3 3 目的端口不可达
3 6 目的网络未知
3 7 目的主机未知
4 0 源抑制(拥塞控制)
8 0 回显请求
9 0 路由器通告
10 0 路由器发现
11 0 TTL 过期
12 0 IP 首部损坏

注意到 ICMP 报文并不仅是用于通知差错情况。

ping

ping 程序发送一个 ICMP 类型 8 编码 0 的报文到指定主机。看到回显(echo)请求,目的主机发回一个类型 0 编码 0 的 ICMP 回显回答。

ping 一个不存在的 IP 时,会收到目的主机不可达(类型 3 编码 1)的响应。

Traceroute

Traceroute 在 Linux 中一般为 tracepath,在 Windows 中一般为 tracert。该程序允许我们跟踪从一台主机到世界上任意一台主机之间的路由。其用 ICMP 报文来实现。

为了判断源和目的地之间所有路由器的名字和地址,源主机中的 Traceroute 向目的地主机发送一系列普通的 IP 数据报。这些数据报的每个携带了一个具有不可达 UDP 端口号的 UDP 报文段。第一个数据报的 TTL 为 1,第二个的 TTL 为 2,第三个的 TTL 为 3,依此类推。该源主机也为每个数据报启动定时器。当第 n 个数据报到达第 n 台路由器时,第 n 台路由器观察到这个数据报的 TTL 正好过期。根据 IP 协议规则,路由器丢弃该数据报并发送一个 ICMP 告警报文给源主机(类型 11 编码 0)。该告警报文包含了路由器的名字和它的 IP 地址。当该 ICMP 报文返回源主机时,源主机从定时器得到往返时延,从 ICMP 报文中得到第 n 台路由器的名字与 IP 地址。

这些数据报之一将最终沿着这条路到达目的主机。因为该数据报包含了一个具有不可达端口号的 UDP 报文段,该目的主机将向源发送一个端口不可达的 ICMP 报文(类型 3 编码 3)。当源主机收到这个特别的 ICMP 报文时,知道它不需要再发送另外的探测分组。

标准的 Traceroute 程序实际上用相同的 TTL 发送 3 个一组的分组,因此 Traceroute 输出对每个 TTL 提供了 3 个结果。

一个 Traceroute 运行示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
tracert 185.199.109.153

通过最多 30 个跃点跟踪
到 cdn-185-199-109-153.github.com [185.199.109.153] 的路由:

1 26 ms 5 ms 51 ms Hiwifi.lan [192.168.199.1]
2 * * * 请求超时。
3 9 ms 16 ms 6 ms 1.240.35.58.broad.xw.sh.dynamic.163data.com.cn [58.35.240.1]
4 11 ms 11 ms 10 ms 124.74.22.29
5 9 ms 6 ms 14 ms 61.152.24.42
6 27 ms 41 ms * 202.97.50.154
7 21 ms 23 ms 30 ms 202.97.74.1
8 93 ms 102 ms 102 ms 202.97.94.10
9 85 ms * * ae-3.r30.tokyjp05.jp.bb.gin.ntt.net [129.250.3.23]
10 * 83 ms 78 ms ae-2.r00.tokyjp08.jp.bb.gin.ntt.net [129.250.6.127]
11 85 ms * 81 ms ae-2.fastly.tokyjp08.jp.bb.gin.ntt.net [117.103.177.66]
12 72 ms 70 ms 80 ms cdn-185-199-109-153.github.com [185.199.109.153]

跟踪完成。

可以看到输出有 6 列:

  • 第一列:前面描述的 n 值,即路径上的路由器编号
  • 第二、三、四列:3 次实验的往返时延
  • 第五列:路由器的名字
  • 第六列:路由器地址

如果源从任何给定路由器接收到的报文少于 3 条(由于网络中的丢包),Traceroute 在该路由器号码后面放一个星号,并向那台路由器报告少于 3 次往返时间。

其他

ICMP 通常被认为是 IP 的一部分,但从体系结构上讲它位于 IP 之上,因为 ICMP 报文是承载在 IP 分组中的。这就是说,ICMP 报文是作为 IP 有效载荷承载的,就像 TCP 与 UDP 报文段作为 IP 有效载荷被承载那样。