网际控制报文协议 ICMP

为了有效地转发 IP 数据报和提高交付成功的机会,在网络层使用了网际控制报文协议(Internet Control Message Protocol,ICMP),让主机或路由器报告差错和异常情况。ICMP 报文被封装在 IP 数据报中发送,但 ICMP 不是高层协议,而是网络层的协议(直接为 ICMP 提供服务的协议 2012 年考过,答案是 IP)。

真题考 ICMP 差错报文的类型及含义(2022)。本页的错题是”TTL 为 1 的数据报到了路由器”:要同时答出丢不丢和发哪一种报文。

机制

两种 ICMP 报文

ICMP 报文有两种,即 ICMP 差错报告报文和 ICMP 询问报文。

ICMP 差错报告报文用于目标主机或到目标主机路径上的路由器,向源主机报告差错和异常情况,共有以下 5 种常用的类型(ICMP 差错报文的类型及含义 2022 年考过):

类型何时发送
终点不可达路由器或主机不能交付数据报时,向源点发送
源点抑制路由器或主机因为拥塞而丢弃数据报时,向源点发送,使源点知道应当把数据报的发送速率放慢
时间超过路由器收到数据报,将 TTL 减 1 后结果为 0,丢弃该数据报并向源点发送;或者终点在预先规定的时间内不能收到一个数据报的全部数据报片时,把已收到的数据报片都丢弃,并向源点发送
参数问题路由器或目的主机收到的数据报的首部中有的字段(注意不是任意字段)的值不正确时,丢弃该数据报并向源点发送
改变路由(重定向)路由器把改变路由报文发送给主机,让主机知道下次应将数据报发送给另外的路由器(可通过更好的路由)

对于以下几种情况,不应发送 ICMP 差错报告报文:

  1. 对 ICMP 差错报告报文,不再发送 ICMP 差错报告报文。
  2. 对第一个分片的数据报片的所有后续数据报片,都不发送 ICMP 差错报告报文。
  3. 对具有多播地址的数据报,都不发送 ICMP 差错报告报文(4.5)。
  4. 对具有特殊地址(如 127.0.0.0 或 0.0.0.0)的数据报,不发送 ICMP 差错报告报文。

这四条的共同目的是防止差错报告本身引起报文风暴:差错报告若出错还要报告,就会无穷无尽;一个数据报的每个片、一个多播数据报的每个接收者都报告一次,报告的数量就会远超原数据报。

常用的 ICMP 询问报文有两种类型:

  1. 回送请求和回答报文:用来测试目的主机是否可达以及了解其有关状态。
  2. 时间戳请求和回答报文:利用报文中记录的时间戳,发送方可计算出当前的往返时延。

PING 与 Traceroute

ICMP 的两个常见应用是分组网间探测 PING(用来测试两台主机之间的连通性)和 Traceroute(UNIX 中的名字,在 Windows 中是 Tracert,可以用来跟踪分组经过的路由)。其中 PING 使用了 ICMP 回送请求和回答报文,Traceroute(Tracert)使用了 ICMP 时间超过报文。王道的注意框指出:PING 工作在应用层,它直接使用网络层的 ICMP(不经过 TCP 或 UDP);Traceroute/Tracert 工作在网络层。

Traceroute 利用的正是 TTL 与”时间超过”报文:

sequenceDiagram
  participant S as 源主机
  participant R1 as 路由器 R1
  participant R2 as 路由器 R2
  participant D as 目的主机
  S->>R1: TTL=1
  R1-->>S: ICMP 时间超过(暴露 R1 的地址)
  S->>R1: TTL=2
  R1->>R2: TTL=1
  R2-->>S: ICMP 时间超过(暴露 R2 的地址)
  S->>R1: TTL=3
  R1->>R2: TTL=2
  R2->>D: TTL=1
  D-->>S: 到达终点的回答

源主机依次发送 TTL 为 1、2、3……的数据报,第 个路由器正好把 TTL 减为 0,于是丢弃数据报并发回时间超过报文,源主机从报文的源地址得知第 跳是谁。TTL 只在转发时检查:数据报到了目的主机,即使 TTL 是 1 也照常交付。

边界

路由器先把 TTL 减 1,再判断是否为 0。 收到 TTL=1 的数据报,减 1 后为 0,必须丢弃并发送时间超过报文;收到 TTL=0 的数据报的情况不会正常出现,因为上一跳在减到 0 时已经丢弃了它。

错题复盘:路由器收到 TTL=1 的数据报,丢弃并发送"时间超过",不是"终点不可达"

王道 4.2.8 第 48 题:若某路由器收到一个 TTL 值为 1 的 IP 数据报,则路由器的操作是(A. 转发该 IP 数据报 B. 仅仅丢弃该 IP 数据报 C. 丢弃该 IP 数据报并向源主机发送类型为终点不可达的 ICMP 差错报告报文 D. 丢弃该 IP 数据报并向源主机发送类型为时间超过的 ICMP 差错报告报文)。答案 D。

路由器先将 TTL 值减 1,然后判断是否为 0;若为 0,则丢弃该 IP 数据报并向源主机发送类型为时间超过的 ICMP 差错报告报文。A 没有先减 1;B 漏了报告;C 报错了类型——终点不可达对应”不能交付”,TTL 耗尽对应”时间超过”。

“不能交付”与”时间超过”是两类不同的报文。 找不到路由(4.2.4)、目的主机不存在、DF=1 却需要分片(4.2.1),都发终点不可达;TTL 减到 0 或重组超时,才发时间超过。

ICMP 是网络层协议,但报文放在 IP 数据报里。 协议字段值为 1 表示数据部分是 ICMP 报文。“封装在 IP 里”不能推出”比 IP 高一层”。

口径差异:源点抑制报文已被废弃

教材口径:ICMP 差错报告报文有 5 种,其中包括源点抑制。

标准口径:王道脚注已说明,最新的 ICMP 标准(RFC 6633)已不再使用源点抑制报文——路由器因拥塞丢包时发一个报文给源点,只会在拥塞时再往网络里加流量,实际效果不好。今天互联网的拥塞信号靠 TCP 自己推断(第 5 章),或者由路由器在分组上做显式拥塞通知(ECN)标记。

考试按教材的 5 种作答。

对照速查

说法对错
ICMP 报文封装在 IP 数据报中,所以是传输层协议❌(网络层)
路由器收到 TTL=1 的数据报,丢弃并发送时间超过报文✅
路由器收到 TTL=1 的数据报,丢弃并发送终点不可达报文❌
目的主机重组超时,丢弃所有片并发送时间超过报文✅
对 ICMP 差错报告报文出错,还要发送 ICMP 差错报告报文❌
对多播数据报出错,不发送 ICMP 差错报告报文✅
PING 使用 ICMP 回送请求和回答报文✅
Traceroute 使用 ICMP 时间超过报文✅
PING 通过 UDP 发送 ICMP 报文❌(直接使用 ICMP)

考点

  • ICMP 是网络层协议,报文封装在 IP 数据报中(2012)
  • 差错报告 5 种:终点不可达、源点抑制、时间超过、参数问题、改变路由(2022)
  • 不发送差错报告的 4 种情况
  • 询问报文:回送请求和回答(PING)、时间戳请求和回答
  • TTL 减为 0 → 丢弃 + 时间超过;Traceroute 用时间超过报文

链接