ICMP协议

ICMP是Internet Control Message Protocol的缩写,用于发送控制消息,如网络通断、主机可达性、路由信息等。主要类型包括超时消息、目标不可达、回送消息、重定向消息。ICMPv6增加了邻居探索协议,用于IPv6环境下的地址对应查询。Traceroute通过递增TTL值来探测数据包到目标主机的完整路径,常见的实现方式有UDP、ICMP和TCP。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • ICMP 的全称是 Internet Control Message Protocol(互联网控制协议)
  • 用于在IP主机、路由器之间发送控制消息
    • 不用于传输用户数据
    • 控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息
  • ICMP 报文承载在 IP 包中
    • 就和 TCP 与 UDP 报文段作为 IP 有效载荷被承载那样
    • 但ICMP和IP协议是一层的,而不是和TCP、UDP协议一层
      • 所以首部没有端口号字段

组成

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

分类

在这里插入图片描述
在这里插入图片描述

ICMP 超时消息(Type: 11)

  • 在 IP 数据包中有一个叫做 TTL(Time To Live, 生存周期) ,指定IP包被路由器丢弃之前允许通过的最大路由节点数量
    • 它的值在每经过路由器一跳之后都会减 1,减为 0 时IP 数据包会被丢弃,并返回错误
      • 主要目的就是为了防止路由器控制遇到问题发生循环状况时,避免 IP 包无休止的在网络上转发
    • IPv4报头的一个8 bit字段
      • TTL的最大值是255,TTL的一个推荐值是64
  • 此时路由器会发送一个 ICMP 超时消息(Code=0)发送给主机,通知该包已经被丢弃
    在这里插入图片描述

ICMP 目标不可达(Type: 3)

  • 路由器无法将 IP 数据报发送给目标地址时,会给发送端主机返回目标不可达的 ICMP 消息,并且用Code字段表示不可达的具体原因
    在这里插入图片描述

ICMP 回送消息(Type: 0 和 Type: 8)

  • 用于判断相互通信的主机之间是否连通,也就是判断所发送的数据包是否能够到达目标主机
  • Type=8: 回送请求ICMP Echo Request Message
  • Type=0: 回送应答ICMP Echo Reply Message
    在这里插入图片描述

ICMP 重定向消息(Type: 5)

  • 路由器发现发送端主机使用了次优的路径发送数据,那么它会返回一个 ICMP 重定向的消息给这个主机
    • 这个 ICMP 重定向消息包含了更合适的路由信息
  • 好处:
    • 优化数据在网络中的转发路径,使得流量更快到达目的地
    • 降低网络资源利用率,例如带宽和路由器 CPU 负载
      在这里插入图片描述

ICMP 原点抑制消息(Type: 4)

  • 在使用低速率网络的情况下,在网络通信遇到网络拥堵的情况下,需要抑制 IP 数据报的发送
    • 路由器的发送队列的残存数据报变为 0 从而无法发送时,向源地址发送该ICMP消息
  • 不过这个 ICMP 消息可能会引起不公平的网络通信,一般不被使用
    在这里插入图片描述

ICMPv6

在这里插入图片描述

  • ICMPv6邻居探索协议
    • 用于查询 IPv6 地址于 MAC 地址的对应关系
    • 利用IPv6 的多播地址实现传输

在这里插入图片描述

  • ipv6支持在没有 DHCP 服务器的环境下也能实现 IP 地址的自动获取
    • 如果是一个没有路由器的网络,就使用 MAC 地址作为链路本地单播地址
    • 在一个有路由器的网络环境中,可以从路由器获得 IPv6 地址的前面部分,后面部分使用 MAC 地址进行设置
      在这里插入图片描述

Traceroute

  • Traceroute 的基本原理:向外发送带有逐次递增 TTL 的数据包从而获取的路径中每一跳的信息
    在这里插入图片描述

  • Traceroute 的实现一共有三种方法:

    • UDP: 向外发送的是一个 UDP 数据包,最终返回的是 ICMP Destination Unreachable
    • ICMP:向外发送的是一个 ICMP Echo Request,最终返回的是 ICMP Echo Reply
    • TCP: 向外发送的是一个 TCP SYN 数据包,最终返回的是 TCP RST
  • UDP实现

    • 客户端使用一个大于30000的目标端口号发送UDP报文
      • 这么大的端口号目的端一般未使用,所以会收到一个端口不可达信息
  • ICMP实现

    • 相比UDP,更容易穿透防火墙
      • 很多应用服务器都不提供UDP服务(或者被防火墙挡掉),所以拿不到服务器的任何返回,实际用起来并不能达到想要的效果
      • 而为了有利于troubeshooting,一般ICMP Echo request/reply是不会被封禁的
        • 所以一般能ping通
    • 运营商可能会封了大目的端口号的UDP包
      • 因为UDP没有连接,常被用作网络攻击
      • 运营商为了安全考虑,只允许白名单端口的UDP包通过
        • 比如DNS、DHCP的
  • TCP实现

    • 穿透防火墙的几率更大,因为 TCP SYN 看起来是试图建立一个正常的 TCP 连接
  • 为什么会出现中间节点为*,但是最终节点可以到达?

    • 有些路由器会隐藏的自己的IP,不让ICMP TTL-Expired的返回消息通过,结果就是在那一跳上始终会显示星号
  • 为什么会一个节点后所有的节点都没有数据?

    • UDP或者ICMP请求被封禁了
  • Traceroute能保证每个分组都是走一样路由路径吗?

    • 不能,只有在对称路由时才能给出准确的测量
    • 一般多路径路由是在运营商或者目标主机前出现负载均衡
  • 参考:

### ICMP协议的介绍与使用方法 ICMP(Internet Control Message Protocol,互联网控制消息协议)是TCP/IP协议族中的一个重要成员,主要用于在IP网络中传递控制消息和错误信息。ICMP报文作为IP数据报的数据部分进行传输[^1]。它不仅与IP协议紧密相关,还与TCP和UDP等传输层协议协同工作,提供更全面的网络服务。 #### ICMP的基本用途 ICMP的主要功能包括以下几个方面: - **错误报告**:当网络通信中发生错误时,ICMP会生成相应的错误消息并发送给源主机。例如,目标不可达(Type=3)、超时(Type=11)等。 - **诊断工具**:ICMP为网络诊断提供了重要支持。常见的网络诊断工具有ping和traceroute,它们依赖ICMP实现其功能。 - **流量控制**:通过源抑制报文(Source Quench),ICMP可以通知发送方减少数据包的发送速率,以缓解网络拥塞问题[^1]。 #### ICMP协议结构 ICMP报文的格式较为简单,主要包括类型字段(Type)、代码字段(Code)、校验和字段(Checksum)以及根据具体类型定义的额外数据。以下是ICMP报文的基本结构: - **Type**:标识ICMP消息的类型。 - **Code**:进一步细化Type字段的具体含义。 - **Checksum**:用于检测ICMP报文的完整性。 - **剩余数据**:根据不同的ICMP消息类型,这部分内容可能包含IP头部或数据部分的信息。 #### 使用场景 1. **MTU探测**:通过接收“需要分片”差错报文(Type=3, Code=4),动态调整数据包大小,避免分片带来的性能损失[^2]。 2. **网络连通性测试**:使用ping命令向目标主机发送ICMP回显请求(Echo Request)报文,并等待回显应答(Echo Reply)报文。 3. **路径跟踪**:使用traceroute命令结合ICMP时间超过(Time Exceeded)报文来确定数据包到达目标主机的路径。 #### 示例代码 以下是一个简单的Python脚本,演示如何使用`socket`库发送ICMP回显请求报文: ```python import socket import struct import os import time def create_packet(id): # Header is type (8), code (8), checksum (16), id (16), sequence (16) header = struct.pack("bbHHh", 8, 0, 0, id, 1) data = struct.pack("d", time.time()) my_checksum = checksum(header + data) header = struct.pack("bbHHh", 8, 0, my_checksum, id, 1) return header + data def checksum(source_string): count_to = (int(len(source_string) / 2)) * 2 sum_ = 0 count = 0 while count < count_to: this_val = source_string[count + 1] * 256 + source_string[count] sum_ += this_val sum_ &= 0xffffffff count += 2 if count_to < len(source_string): sum_ += source_string[-1] sum_ &= 0xffffffff sum_ = (sum_ >> 16) + (sum_ & 0xffff) sum_ += (sum_ >> 16) answer = ~sum_ & 0xffff answer = socket.htons(answer) return answer def send_ping(dest_addr): try: with socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) as sock: packet_id = os.getpid() & 0xFFFF packet = create_packet(packet_id) sock.sendto(packet, (dest_addr, 1)) received, _ = sock.recvfrom(1024) print(f"Received: {received}") except PermissionError: print("Raw sockets require administrative privileges.") if __name__ == "__main__": send_ping("8.8.8.8") ``` #### 安全须知 在实际应用中,需要注意ICMP的安全性问题。例如,合理配置防火墙规则以防止ICMP被用于网络侦察;警惕ICMP Flood攻击,限制请求频率;在某些云环境中,ICMP可能被禁用,此时可考虑使用TCP Ping等替代方案[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值