ICMP:ping 和 traceroute 背后的协议
本文是《计算机网络学习笔记》系列的第十一篇。每次网络出问题,第一反应都是 ping 一下;路由追踪用 traceroute;连接超时浏览器弹出"目标网络不可达"——这些背后都是同一个协议:ICMP。它是 IP 层的"神经系统",专门负责在主机和路由器之间传递网络状态信息。
一、ICMP 是什么?
ICMP(Internet Control Message Protocol,因特网控制报文协议),是 IP 协议的配套协议,两者都工作在网络层(第三层)。
IP 协议是"尽力而为"的,它不保证送达,也不汇报失败原因。当数据包在传输途中出现问题时——比如 TTL 耗尽、目标不可达、包太大无法转发——路由器或目标主机需要一种方式把这个消息告诉发送方。这就是 ICMP 的核心职责:
ICMP 是 IP 的错误报告机制和诊断工具。
在 IP 头部的协议字段(Protocol)中,ICMP 的编号是 1:
IP 头部中的协议字段:
1 → ICMP
6 → TCP
17 → UDPICMP 报文被封装在 IP 数据报的数据部分发送,所以从技术上说它"属于"网络层,而不是传输层。
二、协议格式
所有 ICMP 报文共享一个 8 字节的固定头部,后面跟着可变长度的数据:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Rest of Header | (含义因 Type 而异)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| 字段 | 大小 | 说明 |
|---|---|---|
| Type | 8 位 | 报文大类,决定这条 ICMP 消息是什么类型的事件 |
| Code | 8 位 | 对 Type 的进一步细分,描述具体原因 |
| Checksum | 16 位 | 覆盖整个 ICMP 报文的检验和 |
| Rest of Header | 32 位 | 内容因 Type 不同而异,有的是标识符+序号,有的是全零 |
| Data | 可变 | 附带的原始信息,通常包含触发该 ICMP 消息的原始 IP 头部 + 前 8 字节数据 |
三、常见报文类型
ICMP 的功能完全由 Type + Code 组合决定,下面是最常见的几种:
| Type | Code | 含义 | 触发场景 |
|---|---|---|---|
| 0 | 0 | Echo Reply(回显回复) | 对 ping 请求的应答 |
| 3 | 0 | Destination Network Unreachable | 目标网络不可达 |
| 3 | 1 | Destination Host Unreachable | 目标主机不可达 |
| 3 | 3 | Destination Port Unreachable | 目标端口不可达(UDP 常见) |
| 3 | 4 | Fragmentation Needed | 包太大需要分片,但 DF 位已置 1 |
| 8 | 0 | Echo Request(回显请求) | ping 命令发出的探测包 |
| 11 | 0 | Time Exceeded(超时) | TTL 减为 0,路由器丢弃并通知 |
| 12 | 0 | Parameter Problem | IP 头部字段有错误 |
四、ping:最简单的网络诊断
ping 是最常用的网络诊断工具,原理极简:
发送方 ──► [ICMP Echo Request, Type=8, Code=0] ──► 目标主机
发送方 ◄── [ICMP Echo Reply, Type=0, Code=0] ◄── 目标主机Echo Request 的 Rest of Header 字段包含两个值:
- Identifier(标识符):标识本次 ping 会话,区分不同进程的 ping;
- Sequence Number(序号):从 0 开始递增,每发一个包加 1,用于对应请求和响应、检测丢包。
ping 能测出什么?
- 连通性:能收到 Reply,说明目标可达;
- 往返延迟(RTT):记录发送时间戳,收到 Reply 时计算差值;
- 丢包率:发了 N 个 Request,收到 M 个 Reply,丢包率 = (N-M)/N。
ping 收不到回复意味着什么?
不一定是目标宕机——防火墙可能直接丢弃了 ICMP 包,很多服务器出于安全考虑会屏蔽 ping。
# 基本用法
ping www.baidu.com
# 指定发包次数(Windows)
ping -n 10 www.baidu.com
# 指定发包次数(Linux/macOS)
ping -c 10 www.baidu.com五、traceroute:逐跳追踪路径
traceroute(Windows 上叫 tracert)能显示数据包从本机到目标经过的每一台路由器,是定位网络故障位置的利器。
原理:利用 TTL 和 ICMP Time Exceeded
IP 头部有一个 TTL(Time To Live) 字段,每经过一台路由器就减 1。当 TTL 减为 0 时,路由器丢弃该包,并向发送方回复一条 ICMP Type 11(Time Exceeded) 消息——这条消息的源地址,正是这台路由器的 IP。
traceroute 就是利用这个机制,主动把 TTL 从 1 开始递增,依次"引爆"沿途每一台路由器:
第1轮:TTL=1 ──► 路由器A(TTL减为0,返回 ICMP Time Exceeded)
→ 得到路由器A的IP和延迟
第2轮:TTL=2 ──► 路由器A(TTL=1,继续转发)
──► 路由器B(TTL减为0,返回 ICMP Time Exceeded)
→ 得到路由器B的IP和延迟
第3轮:TTL=3 ──► ...
直到收到目标主机的回复(或达到最大跳数)每轮通常发 3 个包,所以每一跳显示 3 个延迟值,用于评估该段链路的稳定性。
示例输出解读
tracert www.baidu.com
1 1 ms 1 ms 1 ms 192.168.1.1 ← 家用路由器
2 8 ms 7 ms 8 ms 10.xx.xx.1 ← 运营商接入层
3 12 ms 11 ms 12 ms 221.xx.xx.1 ← 运营商骨干
4 * * * Request timed out. ← 该路由器屏蔽了 ICMP
5 28 ms 27 ms 28 ms 180.xx.xx.xx ← 百度边缘节点*表示该跳的路由器屏蔽了 ICMP,不代表网络中断;- 延迟突然增大的那一跳,通常是瓶颈所在;
- 出现连续
*之后又恢复正常,说明中间路由器只是不回复 ICMP,数据实际上是通过的。
# Windows
tracert www.baidu.com
# Linux / macOS
traceroute www.baidu.com
# Linux 也可以用 mtr,实时刷新,更直观
mtr www.baidu.com六、"目标不可达":Type 3 的各种情况
当数据包无法送达时,路由器或目标主机会回复 ICMP Type 3(Destination Unreachable),Code 字段指明具体原因:
| Code | 含义 | 通常由谁发 |
|---|---|---|
| 0 | 网络不可达 | 路由器(没有到目标网络的路由) |
| 1 | 主机不可达 | 路由器(能找到网络,但找不到主机) |
| 3 | 端口不可达 | 目标主机(主机在线,但该端口没有程序在监听) |
| 4 | 需要分片但 DF=1 | 路由器(包太大,且 IP 头禁止分片) |
Code 3(端口不可达)是 UDP 端口扫描的基础:
向目标的某个 UDP 端口发一个包,如果收到 ICMP Type 3 Code 3,说明端口关闭;如果没有回复,说明端口可能开放(有程序在监听),也可能被防火墙拦截了。这也是 UDP 扫描比 TCP 扫描慢且不准确的原因——TCP 有明确的 SYN/RST 握手响应,UDP 只能靠 ICMP 的"否定回复"来判断。
七、ICMPv6:IPv6 时代的升级版
IPv6 中对应的协议是 ICMPv6,协议号为 58。除了继承 ICMPv4 的错误报告功能,ICMPv6 还承担了更多职责:
- 邻居发现协议(NDP):替代了 IPv4 中的 ARP,用于解析 IPv6 地址对应的 MAC 地址;
- 路由器发现:主机通过 ICMPv6 自动发现网关;
- 地址自动配置(SLAAC):主机无需 DHCP,自动生成全球唯一的 IPv6 地址。
ICMPv6 在 IPv6 网络中是强制实现的,不能被过滤掉,否则 IPv6 的基础功能会崩溃。
小结
| 概念 | 一句话总结 |
|---|---|
| ICMP | IP 的配套协议,负责传递网络错误信息和诊断消息,协议号 1 |
| Type + Code | ICMP 的核心:Type 定大类,Code 细分原因 |
| ping | 发 Echo Request(Type 8),收 Echo Reply(Type 0),测连通性和 RTT |
| traceroute | 利用 TTL 从 1 递增,逐跳触发 Time Exceeded(Type 11),绘出完整路径 |
| 端口不可达(Type 3 Code 3) | UDP 端口扫描的判断依据 |
| ICMPv6 | IPv6 的升级版,额外承担 ARP 替代、路由发现、地址自动配置等职责 |
本系列前十篇:
· 第1篇:《TCP 协议格式详解》
· 第2篇:《TCP 三次握手与四次挥手》
· 第3篇:《TCP 可靠数据传输》
· 第4篇:《TCP 流量控制与拥塞控制》
· 第5篇:《TLS:HTTPS 背后的加密握手》
· 第6篇:《HTTP 协议进化史》
· 第7篇:《DNS:互联网的电话簿》
· 第8篇:《IPv4 与 IPv6:网络层的寻址与路由》
· 第9篇:《NAT:家里的路由器如何帮你"上网"》
· 第10篇:《UDP 协议详解》
参考资料:《计算机网络:自顶向下方法》