ICMP协议详解与实践指南

ICMP协议详解与实践指南

1. 引言

1.1 为什么学习ICMP

在日常的网络编程与维护工作中,了解ICMP(Internet Control Message Protocol,互联网控制报文协议)是非常重要的。它不仅帮助我们理解网络故障诊断的基本原理,如通过ping命令检查主机连通性,还能让我们更好地设计和调试网络应用。此外,深入学习ICMP可以提高我们对网络层协议的理解,对于优化网络性能、增强网络安全等方面也有很大帮助。

1.2 ICMP的历史背景和发展

ICMP最初是在1981年由Jon Postel在RFC 792中定义的。它是为了补充IP协议的功能,提供一种机制来报告错误和传递控制信息。随着时间的发展,ICMP已经成为网络管理和故障排除的重要工具。

1.3 ICMP在现代网络中的重要性

ICMP在现代网络中扮演着多重角色:

  • 错误报告:报告网络通信中的错误,如目标不可达、数据包超时等。
  • 诊断工具:提供pingtraceroute等工具,帮助网络管理员诊断和解决网络问题。
  • 流量控制:虽然不是主要目的,但ICMP可以通过源抑制报文减少网络拥塞。

2. ICMP基础概念

2.1 什么是ICMP

ICMP是一种网络层协议,用于在IP网络中发送错误消息和操作消息。它主要负责在主机与路由器之间传递关于网络通达性的信息。

2.2 ICMP的工作原理

ICMP报文通常由网络设备(如路由器)发送给源主机,用来报告错误情况。这些报文可以帮助网络管理员诊断和解决网络问题。

2.3 ICMP与其他网络协议的关系

ICMP与IP协议紧密相关,它是IP协议的一部分。ICMP报文作为IP数据报的数据部分来传输。此外,ICMP还与TCPUDP等传输层协议协同工作,提供更全面的网络服务。

2.4 ICMP的基本用途

  • 错误报告:报告网络通信中的错误。
  • 诊断工具:提供网络诊断工具,如pingtraceroute
  • 流量控制:通过源抑制报文减少网络拥塞。

3. ICMP协议结构

3.1 ICMP报文格式详解

ICMP报文作为IP数据报的数据部分来传输,其头部包含以下字段:

  • 类型字段(Type:定义了ICMP报文的具体类型。例如:

    • 0:回声应答(Echo Reply)
    • 3:目标不可达(Destination Unreachable)
    • 8:回声请求(Echo Request)
    • 11:超时(Time Exceeded)
    • 12:参数问题(Parameter Problem)
    • 5:重定向(Redirect)
    • 4:源抑制(Source Quench)
    • 13:时间戳请求(Timestamp Request)
    • 14:时间戳应答(Timestamp Reply)
    • 15:信息请求(Information Request)
    • 16:信息应答(Information Reply)
  • 代码字段(Code:进一步细化类型字段的信息。例如,类型3(目标不可达)有多个代码值,每个值代表不同的不可达原因:

    • 0:网络不可达
    • 1:主机不可达
    • 2:协议不可达
    • 3:端口不可达
    • 4:需要进行分片但设置了DF标志
    • 5:源路由失败
  • 校验和字段(Checksum:用于确保ICMP报文的完整性和正确性。校验和是16位的反码和,计算时校验和字段应为0。

3.2 常见ICMP报文类型解析

3.2.1 回声请求与回声应答
  • 类型:8(回声请求),0(回声应答)
  • 用途:用于测试两台主机之间的连通性。ping命令就是基于这两种报文实现的。

报文格式

  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             |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |           Identifier          |        Sequence Number        |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |     Data ...
 +-+-+-+-+-
  • Type:8(回声请求),0(回声应答)
  • Code:0
  • Checksum:校验和
  • Identifier:标识符,用于匹配请求和应答
  • Sequence Number:序列号,用于匹配请求和应答
  • Data:可选数据,用于携带额外信息
3.2.2 目标不可达
  • 类型:3
  • 代码
    • 0:网络不可达
    • 1:主机不可达
    • 2:协议不可达
    • 3:端口不可达
    • 4:需要进行分片但设置了DF标志
    • 5:源路由失败
  • 用途:报告目标网络或主机不可达的情况。

报文格式

  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             |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                             unused                            |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |      Internet Header + 64 bits of Original Data Datagram      |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • Type:3
  • Code:具体不可达原因的代码
  • Checksum:校验和
  • unused:保留字段,必须为0
  • Internet Header + 64 bits of Original Data Datagram:原始IP头和前64位数据,用于匹配错误的报文
3.2.3 超时
  • 类型:11
  • 代码
    • 0:生存时间(TTL)超时
    • 1:重组超时
  • 用途:报告数据包在传输过程中生存时间超时或重组超时的情况。

报文格式

  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             |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                             unused                            |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |      Internet Header + 64 bits of Original Data Datagram      |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • Type:11
  • Code:具体超时原因的代码
  • Checksum:校验和
  • unused:保留字段,必须为0
  • Internet Header + 64 bits of Original Data Datagram:原始IP头和前64位数据,用于匹配错误的报文
3.2.4 参数问题
  • 类型:12
  • 代码:0
  • 用途:报告IP头中存在参数错误的情况。

报文格式

  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             |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |    Pointer    |                   unused                      |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |      Internet Header + 64 bits of Original Data Datagram      |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • Type:12
  • Code:0
  • Checksum:校验和
  • Pointer:指向错误字段的位置
  • unused:保留字段,必须为0
  • Internet Header + 64 bits of Original Data Datagram:原始IP头和前64位数据,用于匹配错误的报文
3.2.5 重定向
  • 类型:5
  • 代码
    • 0:网络重定向
    • 1:主机重定向
    • 2:服务类型和网络重定向
    • 3:服务类型和主机重定向
  • 用途:通知主机使用更短的路径发送数据包。

报文格式

  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             |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                 Gateway Internet Address                      |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |      Internet Header + 64 bits of Original Data Datagram      |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • Type:5
  • Code:具体重定向原因的代码
  • Checksum:校验和
  • Gateway Internet Address:新的网关地址
  • Internet Header + 64 bits of Original Data Datagram:原始IP头和前64位数据,用于匹配错误的报文
3.2.6 源抑制
  • 类型:4
  • 代码:0
  • 用途:请求源主机减少数据包的发送速率,以减轻网络拥塞。

报文格式

  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             |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                             unused                            |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |      Internet Header + 64 bits of Original Data Datagram      |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • Type:4
  • Code:0
  • Checksum:校验和
  • unused:保留字段,必须为0
  • Internet Header + 64 bits of Original Data Datagram:原始IP头和前64位数据,用于匹配错误的报文
3.2.7 时间戳请求与应答
  • 类型:13(请求),14(应答)
  • 用途:用于获取网络延迟和时间同步信息。

报文格式

  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             |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |           Identifier          |        Sequence Number        |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |     Originate Timestamp                                       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |     Receive Timestamp                                         |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |     Transmit Timestamp                                        |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • Type:13(请求),14(应答)
  • Code:0
  • Checksum:校验和
  • Identifier:标识符,用于匹配请求和应答
  • Sequence Number:序列号,用于匹配请求和应答
  • Originate Timestamp:发送方发送报文的时间戳
  • Receive Timestamp:接收方接收到报文的时间戳
  • Transmit Timestamp:接收方发送应答报文的时间戳
3.2.8 信息请求与应答
  • 类型:15(请求),16(应答)
  • 用途:用于获取网络信息,如网络地址。

报文格式

  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             |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |           Identifier          |        Sequence Number        |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • Type:15(请求),16(应答)
  • Code:0
  • Checksum:校验和
  • Identifier:标识符,用于匹配请求和应答
  • Sequence Number:序列号,用于匹配请求和应答

4. ICMP的实际应用

4.1 ping命令的工作原理及使用案例

4.1.1 工作原理

ping命令是网络中最常用的工具之一,用于测试主机之间的连通性和测量网络延迟。其工作原理如下:

  1. 发送ICMP回声请求报文ping命令从源主机发送ICMP回声请求(Type 8)报文到目标主机。
  2. 接收ICMP回声应答报文:目标主机收到回声请求后,返回ICMP回声应答(Type 0)报文。
  3. 测量往返时间(RTT)ping命令通过测量从发送请求到接收应答的时间,计算出往返时间(Round-Trip Time, RTT)。
  4. 统计结果ping命令通常会发送多个请求,并统计平均延迟、最小延迟、最大延迟和丢包率等信息。
4.1.2 使用案例
  • 基本用法:发送4个ICMP回声请求报文到目标主机。

    ping -c 4 example.com
    
  • 持续ping:持续发送ICMP回声请求报文,直到手动停止。

    ping example.com
    
  • 指定超时时间:设置每个请求的超时时间为2秒。

    ping -W 2 example.com
    
  • 指定数据包大小:发送100字节的数据包。

    ping -s 100 example.com
    
  • 记录路径:记录每次请求的路径。

    ping -R example.com
    

4.2 traceroute命令的工作原理及使用案例

4.2.1 工作原理

traceroute命令用于确定到达目标主机的路径,并显示每个跳点的响应时间。其工作原理如下:

  1. 发送带有不同TTL值的报文traceroute命令从源主机发送带有不同TTL(Time To Live)值的ICMP或UDP报文。初始TTL值通常为1。
  2. 记录每个跳点的响应:当报文到达某个中间路由器时,由于TTL值减为0,路由器会返回一个ICMP超时(Type 11)报文。traceroute命令记录下该路由器的IP地址和响应时间。
  3. 逐步增加TTL值traceroute命令逐步增加TTL值,直到报文到达目标主机。目标主机返回ICMP回声应答报文。
  4. 显示路径traceroute命令汇总所有记录的信息,显示从源主机到目标主机的路径和每个跳点的响应时间。
4.2.2 使用案例
  • 基本用法:显示到达目标主机的路径。

    traceroute example.com
    
  • 使用ICMP报文:使用ICMP报文而不是默认的UDP报文。

    traceroute -I example.com
    
  • 指定最大跳数:设置最大跳数为30。

    traceroute -m 30 example.com
    
  • 指定数据包大小:发送100字节的数据包。

    traceroute -s 100 example.com
    
  • 显示详细信息:显示详细的跟踪信息。

    traceroute -v example.com
    

4.3 其他基于ICMP的网络工具简介

4.3.1 mtr

mtr(My Trace Route)是一个结合了pingtraceroute功能的网络诊断工具。它可以实时显示网络路径和丢包率,非常适合监控网络连接的稳定性和性能。

  • 基本用法:显示到达目标主机的路径和丢包率。

    mtr example.com
    
  • 持续监控:持续显示网络路径和丢包率,直到手动停止。

    mtr -r example.com
    
  • 显示详细信息:显示详细的跟踪信息。

    mtr -v example.com
    
4.3.2 fping

fping是一个批量ping工具,可以同时ping多个主机,适用于大规模网络监控。它比传统的ping命令更高效,适合自动化脚本和网络管理工具使用。

  • 基本用法:ping多个主机。

    fping -f hosts.txt
    
  • 显示简要结果:只显示ping成功的主机。

    fping -a -f hosts.txt
    
  • 指定超时时间:设置每个请求的超时时间为2秒。

    fping -t 2000 -f hosts.txt
    
  • 持续ping:持续ping多个主机,直到手动停止。

    fping -c 4 -f hosts.txt
    

4.4 实际案例分析:网络故障排查

4.4.1 使用ping命令排查网络连通性

假设您怀疑某个网络连接有问题,可以使用ping命令来快速检查连通性和延迟。

ping -c 4 example.com

输出示例:

PING example.com (93.184.216.34) 56(84) bytes of data.
64 bytes from 93.184.216.34: icmp_seq=1 ttl=54 time=12.3 ms
64 bytes from 93.184.216.34: icmp_seq=2 ttl=54 time=12.4 ms
64 bytes from 93.184.216.34: icmp_seq=3 ttl=54 time=12.5 ms
64 bytes from 93.184.216.34: icmp_seq=4 ttl=54 time=12.6 ms

--- example.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 12.300/12.450/12.600/0.120 ms

从输出中可以看到,4个请求全部成功,平均延迟为12.45毫秒,没有丢包,说明网络连接正常。

4.4.2 使用traceroute命令确定路径

如果您怀疑某个网络路径存在问题,可以使用traceroute命令来确定路径和每个跳点的响应时间。

traceroute example.com

输出示例:

traceroute to example.com (93.184.216.34), 30 hops max, 60 byte packets
 1  192.168.1.1 (192.168.1.1)  1.234 ms  1.234 ms  1.234 ms
 2  10.0.0.1 (10.0.0.1)  2.345 ms  2.345 ms  2.345 ms
 3  10.0.0.2 (10.0.0.2)  3.456 ms  3.456 ms  3.456 ms
 4  10.0.0.3 (10.0.0.3)  4.567 ms  4.567 ms  4.567 ms
 5  93.184.216.34 (93.184.216.34)  12.345 ms  12.345 ms  12.345 ms

从输出中可以看到,从源主机到目标主机的路径经过了5个跳点,每个跳点的响应时间都比较正常,说明网络路径没有明显的问题。

4.4.3 使用mtr命令实时监控网络路径

如果您需要实时监控网络路径和丢包率,可以使用mtr命令。

mtr example.com

输出示例:

Start: 2023-10-01T12:00:00+0800
HOST: your-hostname         Loss%   Snt   Last   Avg  Best  Wrst  StDev
 1. 192.168.1.1               0.0%    10    1.2   1.2   1.2   1.3   0.0
 2. 10.0.0.1                  0.0%    10    2.3   2.3   2.3   2.4   0.0
 3. 10.0.0.2                  0.0%    10    3.4   3.4   3.4   3.5   0.0
 4. 10.0.0.3                  0.0%    10    4.5   4.5   4.5   4.6   0.0
 5. 93.184.216.34             0.0%    10   12.3  12.3  12.3  12.4   0.0

从输出中可以看到,每个跳点的丢包率为0%,响应时间也比较稳定,说明网络连接质量良好。

4.4.4 使用fping命令批量监控网络

如果您需要批量监控多个主机的连通性,可以使用fping命令。

创建一个包含多个主机的文件hosts.txt

example.com
google.com
facebook.com

使用fping命令批量ping这些主机:

fping -f hosts.txt

输出示例:

example.com is alive
google.com is alive
facebook.com is alive

从输出中可以看到,所有主机都在线,说明网络连接正常。

5. ICMP与网络安全

5.1 ICMP的安全风险

  • ICMP洪水攻击:攻击者通过大量发送ICMP报文,使目标主机或网络过载,导致服务中断。
  • ICMP隧道:攻击者利用ICMP报文携带恶意数据,绕过防火墙的检测。

5.2 如何防止ICMP滥用

  • 配置防火墙规则:限制不必要的ICMP流量,只允许必要的ICMP报文通过。
  • 启用ICMP过滤:在路由器和防火墙上启用ICMP过滤功能,防止恶意ICMP报文进入网络。

5.3 防火墙配置中的ICMP策略

  • 允许基本的ICMP报文:如回声请求和应答、目标不可达等。
  • 限制ICMP流量:设置每秒允许的最大ICMP报文数量,防止洪水攻击。
  • 禁用不必要的ICMP报文:如时间戳请求、信息请求等。

5.4 最佳实践

  • 定期审计:定期检查防火墙和路由器的ICMP配置,确保安全性。
  • 监控网络流量:使用网络监控工具,及时发现异常的ICMP流量。

6 ICMP编程实践 – 实现自己的ping工具

  • 步骤:
    • 创建原始套接字。
    • 构建ICMP回声请求报文。
    • 发送报文并接收应答。
    • 计算往返时间(RTT)。
    • 显示结果。
  • 示例代码(Python):
import socket
import struct
import time
import select

def create_icmp_packet(id, seq):
    ICMP_ECHO_REQUEST = 8  # 类型: 回显请求
    CODE = 0
    CHECKSUM = 0
    ID = id
    SEQ = seq
    DATA = b'Hello, ICMP!'  # 测试数据

    # 创建ICMP包
    packet = struct.pack('!BBHHH', ICMP_ECHO_REQUEST, CODE, CHECKSUM, ID, SEQ) + DATA
    checksum = calculate_checksum(packet)
    # 重新插入校验和
    packet = struct.pack('!BBHHH', ICMP_ECHO_REQUEST, CODE, checksum, ID, SEQ) + DATA
    return packet

def calculate_checksum(data):
    if len(data) % 2 == 1:
        data += b'\0'
    s = sum(struct.unpack('!%dH' % (len(data) // 2), data))
    s = (s >> 16) + (s & 0xffff)
    s += s >> 16
    return ~s & 0xffff

def send_icmp_packet(sock, dest_addr, id, seq):
    packet = create_icmp_packet(id, seq)
    sock.sendto(packet, (dest_addr, 0))

def receive_icmp_packet(sock, id, seq, timeout=1):
    start_time = time.time()
    while True:
        remaining_time = timeout - (time.time() - start_time)
        if remaining_time <= 0:
            return None, None

        ready = select.select([sock], [], [], remaining_time)
        if ready[0]:
            packet, addr = sock.recvfrom(1024)
            ip_header = packet[:20]
            iph = struct.unpack('!BBHHHBBH4s4s', ip_header)
            version_ihl = iph[0]
            ihl = version_ihl & 0xF
            iph_length = ihl * 4
            icmp_header = packet[iph_length:iph_length + 8]
            icmph = struct.unpack('!BBHHH', icmp_header)
            icmp_type, code, checksum, packet_id, seq_number = icmph
            if icmp_type == 0 and packet_id == id and seq_number == seq:
                return addr[0], time.time() - start_time
    return None, None

def ping(dest_addr, count=4):
    try:
        dest_ip = socket.gethostbyname(dest_addr)
        print(f'Pinging {dest_addr} [{dest_ip}] with ICMP packets:')
        id = int((time.time() * 1000) % 65535)
        for i in range(count):
            seq = i + 1
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
                sock.settimeout(1)
                send_icmp_packet(sock, dest_ip, id, seq)
                addr, rtt = receive_icmp_packet(sock, id, seq)
                if addr:
                    print(f'Reply from {addr}: seq={seq} time={rtt * 1000:.2f} ms')
                else:
                    print('Request timed out.')
            finally:
                sock.close()
            time.sleep(1)
    except PermissionError:
        print('Error: You need administrative privileges to run this program.')
    except socket.gaierror:
        print(f'Error: Could not resolve hostname {dest_addr}.')

if __name__ == '__main__':
    ping('192.168.100.1')

7. 附录

7.1 参考文献

  • Postel, J. (ed.), “Internet Protocol - DARPA Internet Program Protocol Specification,” RFC 791, USC/Information Sciences Institute, September 1981.
  • Postel, J., “Internet Control Message Protocol,” RFC 792, USC/Information Sciences Institute, September 1981.

7.2 常用命令速查表

命令用途
ping测试主机连通性
traceroute查看到达目标主机的路径
mtr结合pingtraceroute的功能,实时显示网络路径和丢包率
fping批量ping多个主机

7.3 相关资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值