Skip to content

ICMP 协议

2026 大纲 四(三)4 ARP 协议、DHCP 协议与 ICMP 协议 中的 ICMP。同条目的 DHCP 写在《FTP 与 DHCP》,ARP 写在《ARP 地址解析协议》,并列的 IGMP 写在《IP 多播与 IGMP》。

一、IP 出了事不通知任何人,这条通道就是补给它的

网络层的语义是"尽最大努力交付":数据报被丢弃时,不通知任何人。这在正常传输时没问题,可一旦出了故障,源点连"我发的东西为什么没到"都无从知晓。

ICMP 补的就是这条回程的通知通道——它让路由器或目的主机向源点报告差错情况与异常情况。

它属于网络层。判据不是"被谁封装"(ICMP 报文确实装在 IP 数据报的数据部分里,看着像高层协议),而是"为谁服务":ICMP 为 IP 自己服务、没有端口号、不为任何应用进程提供通道。IP 首部的协议字段取值 1

还有一个细节能反过来印证它的层次:ICMP 自带检验和,而且覆盖整个 ICMP 报文。原因是 IP 首部检验和只检验首部、不检验数据部分,保证不了作为"数据"被携带的 ICMP 报文——它得自己保自己

报文格式统一:前 4 字节固定为类型 1 B /代码 1 B /检验和 2 B,此后 4 字节与数据字段的内容都取决于类型。

二、四种差错报告 + 两种询问

差错报告报文只有四种:终点不可达 3、时间超过 11、参数问题 12、改变路由 5

其余的都已不再使用:源点抑制(4)、信息请求与回答、地址掩码请求与回答、路由器请求与通告。这一条要留意——它是随 RFC 修订变化的口径,早年的题目里源点抑制仍是正确答案(下面考点速记里就有一道)。

询问报文两种:回送请求 8 / 回送回答 0数值大的反而是请求,这一对很容易记反);时间戳请求 13 / 时间戳回答 14

时间超过有两个触发原因,只记 TTL 那一个是不完整的:① 路由器收到 TTL 已减为 0 的数据报;② 终点在规定时间内收不齐一个数据报的全部分片

改变路由报文在解决什么

它是四种差错报告报文里唯一不报告差错、而是报告"有更好选择"的一个,揭示的是主机与路由器的分工:

主机数量远大于路由器数量,出于效率考虑,主机不参加路由协议、不与路由器定期交换路由信息,刚开机时转发表里通常只配了一个默认路由器——不管发到哪,一律先交给它。而默认路由器未必是最优的下一跳:若本网络上另有一台路由器 R 通往某目的网络更近,默认路由器就用改变路由报文告诉主机"发往这个目的地址应该经过 R",主机于是加一条更具体的项目。

所以它是"路由器替不懂路由的主机做优化"的机制。

三、为什么抄"原首部 + 数据前 8 字节"

差错报告报文的数据字段结构是:ICMP 前 8 字节 + 原数据报的 IP 首部(20~60 B)+ 原数据部分的前 8 字节。这两段抄回来的东西各有明确用途。

抄原 IP 首部:源点手上可能有成百上千个正在传输的数据报,光说"有个数据报被丢了"毫无意义。原首部里的源 IP、目的 IP、标识、协议字段足以让它认出是哪一个

抄数据部分的前 8 字节:这 8 字节是精心挑的,恰好覆盖运输层报文的关键头部——对 UDP 是源端口 + 目的端口 + 长度 + 检验和(整个 UDP 首部),对 TCP 是源端口 + 目的端口 + 序号。于是源点能知道出问题的是哪个进程哪一段数据,IP 层才能把差错准确通知给对应的高层协议实体。

为什么不多抄一点:差错报文自己也要在网上传,而它服务的正是"已经出错的网络"——抄得越多,越可能自己也被丢。8 字节是"够用"与"够小"的平衡点。

算这个长度时有两处容易失手:IP 首部长度字段的单位是 4 字节(字段值 5 → 20 B,不是 5 B);而 ICMP 报文长 = 8 + 原首部 + 8,承载它的那个 IP 数据报的总长度还要再加 20 字节的新首部。

四、不发送 ICMP 差错报文的四种情况

这四条不是硬记的清单,每一条都在防一件具体的事:

情况防的是什么
对 ICMP 差错报告报文,不再发差错报告报文无限循环。A 的差错报文在路上又出错,B 回一个差错报文,它又可能出错……两台机器能互相打到网络瘫痪
对第一个分片之后的所有后续分片,不发报文风暴,也因为没用。一个数据报分成 10 片全丢,源点会收到 10 个说同一件事的报文;而且只有第一个分片里才有运输层首部,后续分片抄回来的"前 8 字节"是纯数据,源点认不出是哪个进程
对具有多播地址的数据报,不发响应爆炸。多播数据报可能被成千上万台主机收到,每台都回一个就把源点淹没了。这也是"ping 多播地址永远收不到响应"的原因(见 IP 多播
对具有特殊地址(127.0.0.0 或 0.0.0.0)的数据报,不发这两类地址没有确定的回信对象:127.x.x.x 是环回、根本不出主机;0.0.0.0 表示"本网络本主机",是尚未配置地址的主机才用的源地址

一条统一原则:差错报文只在"能确定唯一收信人"且"不会引发级联"时才发。

五、ping

ping 不使用 TCP,也不使用 UDP。 它是"应用层程序直接使用网络层 ICMP"的典型例子,整个运输层被跳过了——而 traceroute 恰恰用到了 UDP,两者在这一点上正好相反。

还有一条要按住:ping 不通不等于网络不通。有的主机为防恶意攻击故意不理睬回送请求。而且 ping 只统计发送数、收到数、丢失数与 RTT 的最小/最大/平均值,不给丢失原因

六、traceroute

核心思路:故意让数据报在第 k 跳上"死掉",那么发回时间超过报文的那台路由器就是第 k 跳。 设路径为 源主机 → R1 → R2 → R3 → 目的主机

第几轮TTL 初值谁把 TTL 减到 0源主机收到什么因此得知
11R1时间超过(11),源地址 = R1第 1 跳是 R1
22R2时间超过(11),源地址 = R2第 2 跳是 R2
33R3时间超过(11),源地址 = R3第 3 跳是 R3
44没人——数据报到达目的主机终点不可达(3),源地址 = 目的主机已到终点,探测结束

每一轮源主机通常发三次同样的数据报,所以输出里每行有三个时间。

终点为什么回的不是"时间超过":数据报到达目的主机时 TTL 还是 1,而主机不转发数据报,也不把 TTL 减 1,永远触发不了时间超过。traceroute 的做法是在 IP 数据报里封装一个无法交付的 UDP 用户数据报(目的端口取一个几乎不可能有进程监听的值),目的主机的运输层发现没有进程在这个端口上,就回终点不可达(代码为"端口不可达")。

一句话记法:中间收 11,终点收 3。

Windows 的 tracert 实现上常用 ICMP 回送请求代替 UDP,但教材口径是"封装无法交付的 UDP 用户数据报、终点回终点不可达",以此为准。

一个反直觉的观察:实测输出里经常出现"跳数更多反而更快"。原因是互联网的拥塞程度随时在变,某一跳恰好赶上拥塞就会比更远的那一跳还慢。逐跳时间不是单调递增的,这不是测量错误。

本节小结

  1. IP 出了事不通知任何人,ICMP 就是那条回程的通知通道。它属网络层的判据是"为 IP 自己服务、没有端口号",而不是"被 IP 封装";也因为 IP 首部检验和不管数据部分,ICMP 必须自带覆盖整个报文的检验和。
  2. 差错报告报文只有四种(3 / 11 / 12 / 5),改变路由是唯一不报差错的一个;差错报文抄回"原首部 + 原数据前 8 字节",前者认出是哪个数据报,后者恰好覆盖 UDP 完整首部或 TCP 的端口与序号。四种不发差错报文的情况统一于"只在能确定唯一收信人且不会引发级联时才发"。
  3. ping = 回送请求(8)/ 回送回答(0),应用层直接使用网络层,不经运输层;traceroute = TTL 递增 + 时间超过,终点因主机不减 TTL 而改用"无法交付的 UDP 端口"触发终点不可达——中间收 11、终点收 3

考点速记

ICMP 在真题里被考过的形式有两种,都是选择题,都只考一句话

① 直接为 ICMP 提供服务的协议是哪个(cn-2012-33)。四个候选 PPP、IP、UDP、TCP,答 B:IP。ICMP 报文封装在 IP 数据报的数据部分里,IP 首部的协议字段填 1。

这道题的干扰项设计得很实在:选 UDP 或 TCP 的人,是被"ICMP 看起来像高层协议"骗了;选 PPP 的人是记混了封装层次。判据是那句——ICMP 为 IP 服务、没有端口号,它在 IP 之上被承载,但不属于运输层。 对照记:ARP 直接封装在链路层帧里(类型 0x0806),ICMP 与 IGMP 封装在 IP 数据报里。

② 路由器因拥塞丢弃分组时发哪种 ICMP 报文(cn-2010-36)。四个候选是路由重定向、目的不可达、源点抑制、超时,标准答案是 C:源点抑制

这道题要连着一条口径变化一起记。 源点抑制(类型 4)的设计意图正是"路由器把拥塞信号显式告诉源主机,请它慢一点",这与本题题干完全吻合;另外三项各对应别的场景——路由重定向是"有更好的下一跳",目的不可达是"送不到",超时是"TTL 归零或分片收不齐"。

但要注意:源点抑制现在已经不再使用了。 它效果不佳(拥塞时再多发一个报文只会加重拥塞),后来被正式弃用,拥塞控制的责任完全交给了端系统的 TCP——这正是网络层功能里讲的"路由器丢包本身就是隐式的拥塞信号"。2010 年这道题按当时的教材口径答 C 是对的;遇到新题问"下列 ICMP 报文中已不再使用的是",源点抑制就成了要选出来的那一个。两种问法都要能应付。

其余内容——差错报文的数据字段结构、四种不发差错报文的情况、ping 与 traceroute 的原理——在真题里不单独成题。它们的作用是让你在读到"TTL 减到 0""收不齐分片""端口没进程"这些描述时,能立刻对上是哪一类 ICMP 报文。

本篇练习区里还会出现另外五道题:cn-2012-38 与 cn-2015-47 考 ARP,讲在 ARP 地址解析协议;cn-2011-47 与 cn-2017-36 讲在 IPv4 数据报格式;cn-2025-36 考 DHCP,讲在 FTP 与 DHCP

易错ICMP 封装在 IP 数据报里,但它是网络层协议。 判据是"为 IP 自己服务、没有端口号"。

易错ARP 直接封装在链路层帧里,ICMP 与 IGMP 封装在 IP 数据报里。 三者别混。

易错回送请求是 8、回送回答是 0,数值大的反而是请求。

易错时间超过有两个触发原因:TTL 减到 0,以及终点收不齐分片。

易错源点抑制已不再使用,但 2010 年的真题按当时口径答它。新题问"哪个已不再使用"时它就是答案。

易错ping 不经运输层,traceroute 用到 UDP。 两者在这一点上相反。

易错traceroute 中间收时间超过(11)、终点收终点不可达(3),因为主机不转发也不减 TTL。

易错ping 不通不等于网络不通,有的主机故意不理睬回送请求。

教材出处
  • 谢希仁《计算机网络》(第 8 版):ICMP 的定位与报文格式,见印刷版 p146(4.4 网际控制报文协议 ICMP)——"ICMP 允许主机或路由器报告差错情况和提供有关异常情况的报告。ICMP 是互联网的标准协议。但 ICMP 不是高层协议(看起来好像是高层协议,因为 ICMP 报文装在 IP 数据报中,作为其中的数据部分),而是 IP 层的协议";"ICMP 报文的前 4 字节是统一的格式,共有三个字段:类型、代码和检验和",且"检验和字段用来检验整个 ICMP 报文。我们应当还记得,IP 数据报首部的检验和并不检验 IP 数据报的内容,因此不能保证经过传输的 ICMP 报文不产生差错"。同页表 4-6 给出四种差错报告报文(3 终点不可达、11 时间超过、12 参数问题、5 改变路由)与两种询问报文(8 或 0 回送、13 或 14 时间戳),并明确"已不再使用的 ICMP 报文有:'信息请求与回答报文''地址掩码请求与回答报文''路由器请求与通告报文'以及'源点抑制报文'"。
  • 同书 p147:时间超过的两个触发原因——"当路由器收到生存时间为零的数据报时,除丢弃该数据报外,还要向源点发送时间超过报文。当终点在预先规定的时间内不能收到一个数据报的全部数据报片时,就把已收到的数据报片都丢弃,并向源点发送时间超过报文";改变路由的机制:"在互联网中主机的数量远大于路由器的数量,出于效率的考虑,这些主机不和连接在网络上的路由器定期交换路由信息。在主机刚开始工作时,一般都在转发表中设置一个默认路由器的 IP 地址……如果默认路由器发现主机发往某个目的地址的数据报的最佳路由应当经过网络上的另一个路由器 R,就用改变路由报文把这情况告诉主机"。
  • 同书 p147:差错报告报文的数据字段——"把收到的需要进行差错报告的 IP 数据报的首部和数据字段的前 8 个字节提取出来,作为 ICMP 报文的数据字段。再加上相应的 ICMP 差错报告报文的前 8 个字节,就构成了 ICMP 差错报告报文。提取收到的数据报的数据字段前 8 个字节是为了得到运输层的端口号(对于 TCP 和 UDP)以及运输层报文的发送序号(对于 TCP)"。同页给出四条不发送差错报告报文的情况(对 ICMP 差错报告报文、对第一个分片的所有后续分片、对具有多播地址的数据报、对具有特殊地址如 127.0.0.0 或 0.0.0.0 的数据报)。
  • 同书 p148(4.4.2 ICMP 的应用举例):ping 的定位——"ICMP 的一个重要应用就是分组网间探测 PING……PING 使用了 ICMP 回送请求与回送回答报文。PING 是应用层直接使用网络层 ICMP 的一个例子。它没有通过运输层的 TCP 或 UDP";并说明"有的主机为了防止恶意攻击就不理睬外界发送过来的这种报文",统计结果"给出分组丢失的数目(但不给出分组丢失的原因),以及往返时间的最小值、最大值和平均值"。
  • 同书 p148–p149:traceroute 的原理——"traceroute 从源主机向目的主机发送一连串的 IP 数据报,数据报中封装的是无法交付的 UDP 用户数据报",逐轮 TTL 递增触发时间超过;到终点时"当最后一个数据报刚刚到达目的主机时,数据报的 TTL 是 1。主机不转发数据报,也不把 TTL 值减 1。但因 IP 数据报中封装的是无法交付的运输层的 UDP 用户数据报,因此目的主机要向源主机发送 ICMP 终点不可达差错报告报文";"对应于每一个 TTL 值,源主机要发送三次同样的 IP 数据报";以及那个反直觉的观察——"从原则上讲,IP 数据报经过的路由器越多,所花费的时间也会越长。但……有时正好相反。这是因为互联网的拥塞程度随时都在变化"。
  • ⚠️ 源点抑制的口径变化:谢希仁第 8 版 p146 已把源点抑制列入"已不再使用的 ICMP 报文"。而 cn-2010-36 出题时它仍是标准答案。本篇按"标准答案永远赢"处理:那道真题答 C 成立,同时把弃用这一事实写清楚,两种问法都能应付。

相关知识

IPv4 数据报格式ARP 地址解析协议IP 分片与重装IP 多播与 IGMPIPv6 基础

真题练习