linux · 2025-07-26 0

探究 ICMP 协议

一、ICMP

工具如 ping 和 traceroute 都是基于 ICMP 实现的。

IP 是尽力传输的网络协议,提供的数据传输服务是不可靠的、无连接的,不能保证数据包能成功到达目的地。

这需要一个网络层协议,提供错误检测功能和报告机制功能,于是出现了 ICMP(Internet Control Message Protocol 互联网控制消息协议)。ICMP 的主要功能是,确认 IP 包是否成功送达目的地址,通知发送过程中 IP 包被丢弃的原因。

ICMP包 (84字节) = IP头 (20字节) + ICMP头 (8字节) + ICMP 数据 (56字节)

二、抓取包

ping ip,并发送数据 6162 (ab)

ping -c 3 -p 6162 172.17.0.2

tcpdump 在服务器上抓包

root@fdc276a87cec:/# tcpdump -n -v -X
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
08:25:50.469444 IP (tos 0x0, ttl 64, id 39378, offset 0, flags [DF], proto ICMP (1), length 84)
    172.17.0.1 > 172.17.0.2: ICMP echo request, id 19, seq 1, length 64
    0x0000:  4500 0054 99d2 4000 4001 48b1 ac11 0001  E..T..@.@.H.....
    0x0010:  ac11 0002 0800 4119 0013 0001 0e91 8468  ......A........h
    0x0020:  0000 0000 8129 0700 0000 0000 6162 6162  .....)......abab
    0x0030:  6162 6162 6162 6162 6162 6162 6162 6162  abababababababab
    0x0040:  6162 6162 6162 6162 6162 6162 6162 6162  abababababababab
    0x0050:  6162 6162                                abab
08:25:50.469472 IP (tos 0x0, ttl 64, id 5228, offset 0, flags [none], proto ICMP (1), length 84)
    172.17.0.2 > 172.17.0.1: ICMP echo reply, id 19, seq 1, length 64
    0x0000:  4500 0054 146c 0000 4001 0e18 ac11 0002  E..T.l..@.......
    0x0010:  ac11 0001 0000 4919 0013 0001 0e91 8468  ......I........h
    0x0020:  0000 0000 8129 0700 0000 0000 6162 6162  .....)......abab
    0x0030:  6162 6162 6162 6162 6162 6162 6162 6162  abababababababab
    0x0040:  6162 6162 6162 6162 6162 6162 6162 6162  abababababababab
    0x0050:  6162 6162                                abab

三、解析包

数据是一个完整的 ICMP Echo Request(ping 请求)

1.IP 头部解析(从 0x0000 开始,共 20 字节)

0x0000:  4500 0054 99d2 4000 4001 48b1 ac11 0001  
0x0010:  ac11 0002

第一个字段是 4500,4500 (hex) = 0100 0101 0000 0000 (binary)

字段 说明
版本 + 头部长度 45 4 表示 IPv4
- 5 表示 IP 头长度为 5×4 = 20 字节
服务类型 TOS 00 通常为 0,表示默认服务类型
总长度 Total Length 0054 十进制:84 字节(整个 IP 数据包)
标识符 Identification 99d2 十进制:39378,用于分片重组
标志位 + 片偏移 4000 DF(Don't Fragment)标志置位,不分片
协议 Protocol 01 上层协议为 ICMP(协议号 1)
TTL(Time To Live) 40 十进制:64,每经过一个路由器减 1
校验和 Checksum 48b1 用于 IP 头部完整性校验
源 IP地址 ac11 0001 十进制 IP:172.17.0.1
目标 IP 地址 ac11 0002 十进制 IP:172.17.0.2

2.ICMP 头部解析(从 0x0014 开始,共 8 字节)

0x0010:  ... ... 0800 4119 0013 0001 ... ...
字段 说明
类型 Type 08 表示 ICMP Echo Request(ping 请求)
代码 Code 00 对 Echo Request 来说,通常为 0
校验和 Checksum 4119 校验 ICMP 报文完整性
标识符 Identifier 0013 十进制:19,用于匹配请求和响应
序列号 Sequence Number 0001 十进制:1,表示这是第 1 个 ping 请求

请求与响应差异:
类型 Type :请求值是 08(Echo Request),相应值是 00(Echo Reply)
标识符 Identifier :0013(19),用于匹配请求和响应
序列号 Sequence Number :0001,表示这是第 1 个 ping 请求

3.ICMP 数据部分解析(从 0x001C 开始,共 56 字节)

0x0010:  .... .... .... .... .... .... 0e91 8468
0x0020:  0000 0000 8129 0700 0000 0000 6162 6162
0x0030:  6162 6162 6162 6162 6162 6162 6162 6162
0x0040:  6162 6162 6162 6162 6162 6162 6162 6162
0x0050:  6162 6162

1) 时间戳(前 8 字节)0e91 8468 0000 0000,0e918468 是一个时间戳值,用于计算往返时间(RTT),具体含义取决于系统实现(如 Linux 内核如何填充)
2) 其余为填充数据
8129 0700 0000 0000 可能是 ping 工具内部使用的标识或填充字段
6162 每个对应 ASCII 字符 'a' 和 'b'

请求与响应差异:
说明响应方将请求中的数据原样返回,这是 ICMP Echo 协议的标准行为。
时间戳 0e918468 在响应中也保留,表示请求发送的时间,用于计算 RTT(往返时间)