Files
cs-note/hhs/NETWORK/03-网络层/05-ICMP与Ping-Traceroute.md
T
2026-05-24 11:42:38 +08:00

190 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
tags: [计算机网络, ICMP, Ping, Traceroute]
create time: 2026-05-18 00:50
---
# ICMP 与 Ping / Traceroute
## 概述
ICMP(Internet Control Message Protocol,互联网控制消息协议)是 IP 的"副手"——它不承载用户数据,而是用来报告错误、传递诊断信息。ping 和 traceroute 这两个最常用的网络工具,底层全靠 ICMP。
## ICMP 报文格式
```
┌──────────┬───────────┬──────────┬───────────────┐
│ Type(8b) │ Code(8b) │ Checksum │ Rest of Header │
├──────────┼───────────┴──────────┴───────────────┤
│ Data (variable) │
└───────────────────────────────────────────┘
```
### 常用 Type 对照表
| Type | Code | Name | 用途 |
|------|------|------|------|
| 0 | 0 | Echo Reply | ping 回复 |
| 3 | 0–3 | Destination Unreachable | 目的不可达 |
| 3/0 | Network Unreachable | 路由表中无目标网段 |
| 3/1 | Host Unreachable | 同一网段但主机不存在 |
| 3/2 | Protocol Unreachable | TCP/UDP 端口无监听 |
| 3/3 | Port Unreachable | UDP 端口不可达(最常见) |
| 8 | 0 | Echo Request | ping 请求 |
| 11 | 0 | Time Exceeded | TTL 归零(traceroute 利用此) |
| 12 | 0 | Parameter Problem | IP 首部字段错误 |
| 13 | 0 | Timestamp Request | 时间戳查询 |
| 14 | 0 | Timestamp Reply | — |
| 17 | 0 | Address Mask Request | 子网掩码查询(老旧) |
| 18 | 0 | Address Mask Reply | — |
## Ping — 最基础的连通性测试
### Ping 工作原理
```mermaid
sequenceDiagram
participant Client as 客户端
participant Server as 服务器
Client->>Server: ICMP Echo Request<br/>Type=8, ID=0x1234, Seq=0
Note over Server: 内核自动回复,无需应用层处理
Server-->>Client: ICMP Echo Reply<br/>Type=0, ID=0x1234, Seq=0
loop 继续发第 2, 3... 个包
Client->>Server: Echo Request Seq=1
Server-->>Client: Echo Reply Seq=1
end
```
### Linux ping 详解
```bash
$ ping -c 4 -s 1024 example.com
PING example.com (93.184.216.34): 1024 data bytes
1032 bytes from 93.184.216.34: icmp_seq=0 ttl=55 time=23.4 ms
1032 bytes from 93.184.216.34: icmp_seq=1 ttl=55 time=22.8 ms
1032 bytes from 93.184.216.34: icmp_seq=2 ttl=55 time=23.1 ms
1032 bytes from 93.184.216.34: icmp_seq=3 ttl=55 time=23.5 ms
--- example.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss
rtt min/avg/max/stddev = 22.8/23.2/23.5/0.30 ms
```
参数速查:
| 参数 | 含义 |
|------|------|
| `-c N` | 发送 N 个包后停止 |
| `-i SEC` | 间隔秒数(默认 1s,root 可用 < 0.1s) |
| `-s SIZE` | 载荷大小(默认 56 bytes,即 64 byte ICMP 包) |
| `-t TTL` | 指定初始 TTL |
| `-W MSEC` | 等待超时毫秒数 |
| `-q` | 静默模式,仅显示统计摘要 |
### macOS / Windows 的差异
| 特性 | Linux | macOS | Windows |
|------|-------|-------|---------|
| 默认行为 | 不停发送直到 Ctrl+C | 不停发送 | 发 4 次后停止 |
| 默认 TTL | 64 | 64 | 128 |
| 默认载荷 | 56 bytes | 56 bytes | 32 bytes |
| `-c` | ✅ 限制次数 | ❌ | ❌ |
> [!tip] 判断丢包率的阈值
>
> | 丢包率 | 评价 |
> |--------|------|
> | 0% | 正常 |
> | < 0.1% | 可接受(偶尔重传) |
> | 0.1%~1% | 注意观察 |
> | 1%~5% | 可能存在瓶颈或线路老化 |
> | > 5% | 严重问题,需排查物理链路或设备 |
## Traceroute — 路由路径探测
### 原理:利用 ICMP Time Exceeded
```mermaid
sequenceDiagram
participant T as 客户端
participant R1 as Router 1
participant R2 as Router 2
participant D as Destination
T->>R1: ICMP(TTL=1) → R1 TTL归零,返回 Time Exceeded
Note over T: 收到 R1 的 reply → 第一跳延迟记录完毕
T->>R1: ICMP(TTL=2) → R1转发 → R2 TTL归零→ Time Exceeded
Note over T: 收到 R2 的 reply → 第二跳记录完毕
T->>R1: ICMP(TTL=3) → ... → D 收到 → 返回 Echo Reply
Note over T: ✅ 到达目的地
```
### Linux traceroute vs tracepath
```bash
# traceroute 使用 UDP(默认高位端口)或 ICMP(-I 参数)
$ traceroute -I example.com # 使用 ICMP
1 192.168.1.1 1ms 1ms 1ms
2 10.0.0.1 10ms 10ms 10ms
3 202.97.xx.xx 20ms 19ms 20ms
...
12 93.184.216.34 45ms 44ms 44ms
# tracepath 不需要 root 权限,默认 MTU 发现
$ tracepath example.com
1: 192.168.1.1 0.4ms
2: 10.0.0.1 8.2ms
...
12: 93.184.216.34 43.5ms
No route to above host (mtu discovered: 1492)
```
### Windows 等价命令
```cmd
tracert example.com
```
> [!warning] 为什么有些 traceroute "星号 * * *"?
> 路由器可以配置为**不回复 ICMP Time Exceeded**(出于安全考虑)。此时你看不到中间节点,只能看到最后的目的地。
## ICMP Rate Limiting(限速)
Linux 内核默认对 ICMP 进行限速,防止 ICMP flood 攻击:
```bash
$ sysctl net.ipv4.icmp_ratelimit # 每秒最多发出多少个 ICMP
net.ipv4.icmp_ratelimit = 1000 # 默认 1000 msg/s
$ sysctl net.ipv4.icmp_ratemask # 哪些 type 受限速
net.ipv4.icmp_ratemask = 6168 # mask bits
```
> [!note] iptables 中也可以限速
> ```bash
> iptables -A INPUT -p icmp --icmp-type echo-request -m limit \
> --limit 1/s --limit-burst 4 -j ACCEPT
> ```
## IPv6 等价:ICMPv6
IPv6 中 ICMP 被增强为 NDP(Neighbor Discovery Protocol),功能更丰富:
| IPv4 ICMP | IPv6 ICMPv6 对应 |
|-----------|-----------------|
| Echo Request/Reply | 类型 8/0(不变) |
| Destination Unreachable | 类型 1(相同语义) |
| Time Exceeded | 类型 3(traceroute 用) |
| Router Discovery | Router Solicitation / Advertisement(类型 133/134)|
| ARP | Neighbor Solicitation / Advertisement(类型 135/136)|
| PMTUD | Path MTU Discovery 成为强制要求 |
## 关联笔记
- [[hhs/NETWORK/IPv4首部与分段重组]] — ICMP 作为 IP 上层协议(Protocol=1)
- [[hhs/NETWORK/CIDR与子网划分]] — 理解子网后才能正确使用 ping
- [[hhs/NETWORK/NAT原理与应用]] — NAT 会影响 ICMP 的回程路径