Skip to content

ICMP 协议:ping 与 traceroute 原理

当你怀疑网络有问题时,第一反应是什么?多半是 ping 一下。

ping 是网络工程师最常用的排障工具——简单、快捷、一目了然。但你知道 ping 是怎么工作的吗?

ping 背后是 ICMP(Internet Control Message Protocol)协议,它是 IP 的「小秘书」,负责传递控制消息和错误报告。

ICMP 是什么?

ICMP 协议工作在网络层(IP 层),是 IP 协议的一部分。它的设计目的是:

让 IP 更可靠。 当数据包在传输过程中出现问题时,ICMP 负责通知发送方。

你可以把 ICMP 想象成快递的「签收短信」或「退件通知」——当快递(IP 数据报)出问题(找不到收件人、超时等),就会通过 ICMP 通知发件人。

ICMP 报文格式

┌────────────────────────────────────────────────────────────┐
│  类型(1字节) │  代码(1字节)  │        校验和(2字节)       │
├────────────────────────────────────────────────────────────┤
│                     头部其余部分(4字节)                    │
│              (取决于类型,部分类型可选项)                    │
├────────────────────────────────────────────────────────────┤
│                        数据部分                             │
│            (原始 IP 数据包的部分内容 + 时间戳等)             │
└────────────────────────────────────────────────────────────┘

常见 ICMP 类型

类型名称用途
0Echo Replyping 响应
3Destination Unreachable目的不可达
8Echo Requestping 请求
11Time ExceededTTL 超时(traceroute)
5Redirect路由重定向

ping 的工作原理

ICMP Echo 请求与响应

ping 发送的是 ICMP Echo Request(类型 8),目标主机收到后回复 ICMP Echo Reply(类型 0)。

主机 A(192.168.1.100)                          主机 B(192.168.1.1)
        │                                                  ▲
        │─── ICMP Echo Request ──────────────────────────>│
        │      类型=8, 代码=0, 标识符=1234, 序号=1          │
        │                                                  │
        │<── ICMP Echo Reply ───────────────────────────│
        │      类型=0, 代码=0, 标识符=1234, 序号=1         │

ping 通过测量发送和接收的时间差来计算往返时延(RTT)。

ping 的实际输出

bash
$ ping -c 4 114.114.114.114

PING 114.114.114.114 (114.114.114.114): 56 data bytes
64 bytes from 114.114.114.114: icmp_seq=0 ttl=117 time=12.345 ms
64 bytes from 114.114.114.114: icmp_seq=1 ttl=117 time=13.456 ms
64 bytes from 114.114.114.114: icmp_seq=2 ttl=117 time=11.234 ms
64 bytes from 114.114.114.114: icmp_seq=3 ttl=117 time=12.678 ms

--- 114.114.114.114 ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 11.234/12.428/13.456/0.823 ms

关键字段解读

  • 64 bytes:ICMP 响应数据部分的长度(默认 56 字节,加上 8 字节 ICMP 头部 = 64)
  • icmp_seq:ICMP 序列号,标识第几个包
  • ttl=117:生存时间,每经过一个路由器减 1,117 说明中间经过了 128-117=11 个路由器
  • time=12.345 ms:往返时延

TTL 的作用

TTL(Time To Live)最初是设计用来防止路由环路的。数据包每经过一个路由器,TTL 就减 1,当 TTL 变成 0 时,路由器会丢弃该数据包并发送 ICMP 超时报文。

为什么从 117 开始?

TTL 是从初始值开始递减的,Linux 默认初始值是 64,Windows 默认是 128。当 ttl=117 时,说明经过了 64-117+1=48128-117+1=12 个路由器(取决于系统默认值)。

ping 的 Java 实现

java
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class PingDemo {
    public static void main(String[] args) {
        String host = "114.114.114.114";
        try {
            // 执行 ping 命令(-c 4 表示发送 4 个包)
            Process process = Runtime.getRuntime().exec("ping -c 4 " + host);

            // 读取输出
            BufferedReader reader = new BufferedReader(
                new InputStreamReader(process.getInputStream())
            );
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

            int exitCode = process.waitFor();
            System.out.println("\nExit Code: " + exitCode);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

traceroute:追踪数据包的路

traceroute(Windows 下是 tracert)用于追踪数据包从源到目的经过的每一跳路由器。

核心原理:TTL 探测

traceroute 故意利用 TTL 机制来「探测」路径:

第一步:发送 TTL=1 的包
        → 第一个路由器收到后 TTL 变成 0,丢弃并返回 ICMP Time Exceeded
        → 我们获得了第一跳的 IP

第二步:发送 TTL=2 的包
        → 前两个路由器递减 TTL,第二个路由器返回 ICMP Time Exceeded
        → 我们获得了第二跳的 IP

第三步:发送 TTL=3 的包
        → ...

重复,直到到达目标或超时

traceroute 的实际输出

bash
$ traceroute -m 15 114.114.114.114

traceroute to 114.114.114.114 (114.114.114.114), 15 hops max, 60 byte packets
 1  192.168.1.1       1.234 ms   1.123 ms   1.456 ms   (网关)
 2  10.100.1.1        3.456 ms   3.234 ms   3.567 ms   (ISP 路由器)
 3  61.128.123.1      6.789 ms   6.567 ms   6.890 ms   (骨干网)
 4  *  *  *                                          (可能防火墙屏蔽了 ICMP)
 5  114.114.114.114   12.345 ms  12.123 ms  12.456 ms   (目标)

为什么有些跳显示 *

有些路由器或防火墙会屏蔽 ICMP 包,导致 traceroute 无法收到响应。这不代表那一跳有问题,只是「拒绝回复」。

traceroute 使用 UDP 探针

类 Unix 系统的 traceroute 默认使用 UDP 探针(而不是 ICMP):

TTL=1 → 路由器返回 ICMP Time Exceeded
TTL=2 → 下一路由器返回 ICMP Time Exceeded
...
TTL=n → 到达目标,目标返回 ICMP Port Unreachable(因为端口不可达)

为什么用 UDP?因为可以自定义目标端口(通常是大于 33434 的高端口),当到达目的地时,目标主机会回复「端口不可达」。

Windows 的 tracert 使用 ICMP Echo Request,和 ping 类似。

ICMP 的安全风险

ICMP 洪水攻击

攻击者向目标发送大量 ICMP 包,耗尽带宽或 CPU 资源。

防御:在防火墙上过滤或限制 ICMP 流量。

ICMP 隧道

理论上可以通过 ICMP 数据包建立隐蔽通道——把数据藏在 ICMP 的数据部分,绕过防火墙。

防御:检测 ICMP 包的大小和内容,限制非标准使用。

ICMP 重定向攻击

攻击者发送 ICMP 重定向报文,让受害者修改路由表,把流量导向攻击者。

防御:现代系统默认忽略 ICMP 重定向报文。

实际应用:网络诊断

常见诊断流程

bash
# 1. 先 ping 本地网关,确认本地网络正常
ping 192.168.1.1

# 2. ping 外网地址,确认出口网络正常
ping 114.114.114.114

# 3. ping 域名,确认 DNS 解析正常
ping www.baidu.com

# 4. traceroute 追踪路由
traceroute www.baidu.com

# 5. 查看路由表
route -n      # Linux/Mac
route print   # Windows

批量 ping 脚本

python
#!/usr/bin/env python3
import subprocess
import concurrent.futures

def ping_host(host):
    """Ping 一个主机,返回结果"""
    try:
        # Windows 用 ping -n 1,Linux/Mac 用 ping -c 1
        result = subprocess.run(
            ['ping', '-c', '1', '-W', '2', host],
            capture_output=True,
            text=True,
            timeout=3
        )
        if result.returncode == 0:
            return f"✓ {host} 可达"
        else:
            return f"✗ {host} 不可达"
    except Exception as e:
        return f"✗ {host} 错误: {e}"

def main():
    # 常见 DNS 和网关
    hosts = [
        "192.168.1.1",     # 默认网关
        "8.8.8.8",         # Google DNS
        "114.114.114.114", # 腾讯 DNS
        "www.baidu.com",
        "www.taobao.com",
    ]

    with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
        results = executor.map(ping_host, hosts)
        for result in results:
            print(result)

if __name__ == "__main__":
    main()

面试追问方向

  • ICMP 协议的作用是什么?为什么需要它?
  • ping 的原理是什么?如何计算往返时延?
  • TTL 的作用是什么?为什么 traceroute 能追踪路由?
  • 为什么 traceroute 有些跳显示 *
  • ICMP 有什么安全风险?如何防御?
  • ICMP 和 IP 的关系是什么?ICMP 是传输层协议吗?

基于 VitePress 构建