ICMP协议

2025年03月17日 | 阅读 9 分钟

ICMP 的全称是 Internet Control Message Protocol(互联网控制报文协议)。它是一个网络层协议。它用于处理网络层的错误,并且主要在路由器等网络设备上使用。由于网络层可能存在各种类型的错误,因此 ICMP 可以用来报告和调试这些错误。

例如,某个发送方想向某个目的地发送消息,但路由器无法将消息发送到目的地。在这种情况下,路由器会向发送方发送消息,告知无法将消息发送到该目的地。

IP 协议没有任何错误报告或错误纠正机制,因此它使用消息来传递信息。例如,如果有人发送消息到目的地,但消息在发送方和目的地之间丢失了。如果没有人报告错误,发送方可能会认为消息已到达目的地。如果有人在中间报告了错误,发送方将很快重新发送消息。

ICMP 在网络层的位置

ICMP 位于 IP 层,如下图所示。

ICMP Protocol

消息

ICMP 消息通常分为两类

ICMP Protocol
  • 错误报告消息

错误报告消息是指路由器在处理 IP 数据包时遇到问题,然后报告消息。

  • 查询消息

查询消息是帮助主机获取另一台主机特定信息的消息。例如,假设有一个客户端和一个服务器,客户端想知道服务器是否在线,那么它会向服务器发送 ICMP 消息。

ICMP 消息格式

消息格式包含两部分:一是类别,用于指明消息的类型。如果消息是错误类型,错误消息包含类型和代码。类型定义了消息的类型,而代码定义了消息的子类型。

ICMP 消息包含以下字段

ICMP Protocol
  • 类型 (Type): 这是一个 8 位字段。它定义了 ICMP 消息的类型。值从 0 到 127 定义了 ICMPv6,而值从 128 到 255 是信息性消息。
  • 代码 (Code): 这是一个 8 位字段,用于定义 ICMP 消息的子类型。
  • 校验和 (Checksum): 这是一个 16 位字段,用于检测消息中是否存在错误。

注意:ICMP 协议总是将错误消息报告给原始源。例如,当发送方发送消息时,如果消息中出现任何错误,则路由器会报告给发送方而不是接收方,因为发送方正在发送消息。

错误报告消息类型

错误报告消息大致分为以下几类

ICMP Protocol
  • 目标不可达

当数据包无法到达目的地时,会发生目标不可达错误。假设发送方发送消息,但消息未到达目的地,则中间路由器会向发送方报告目标不可达。

ICMP Protocol

上面的图显示了目标不可达消息的消息格式。在消息格式中

类型 (Type): 定义了消息类型。数字 3 表示目标不可达。

代码 (Code, 0 到 15): 这是一个 4 位数字,用于识别消息是来自中间路由器还是目的地本身。

注意:如果目的地创建了目标不可达消息,则代码可能是 2 或 3。

有时,目的地不想处理请求,因此它会向源发送目标不可达消息。路由器并非能检测到所有阻止数据包传递的问题。

  • 源抑制

网络层或 IP 协议没有流量控制或拥塞控制机制。发送方只关心发送数据包,而不考虑接收方是否准备好接收这些数据包,或者网络层是否发生拥塞,因此发送方可以发送较少数量的数据包。在这种情况下,ICMP 提供反馈,即源抑制。假设发送方以更高的速率重发数据包,而路由器无法处理高数据速率。为了克服这种情况,路由器会发送源抑制消息,告知发送方以较低的速率发送数据包。

ICMP Protocol

上面的图显示了源抑制消息的消息格式。它是一个类型 4 消息,代码为零。

注意:源抑制消息通知发送方,由于网络层发生拥塞而丢弃了该数据报。

因此,发送方必须停止或减慢数据报的发送速度,直到拥塞减轻。路由器会为因网络层拥塞而被丢弃的每个数据报发送一个源抑制消息。

  • 超时

有时,发送方和接收方之间存在许多路由器的情况。当发送方发送数据包时,它会陷入路由循环。超时是基于生存时间(TTL)值。当数据包遍历路由器时,每个路由器都会将 TTL 值减一。当路由器将生存时间值为零的数据报丢弃时,路由器会丢弃该数据报并向原始源发送超时消息。

每个 MAC 层都有不同的数据单元。例如,某些层最多可以处理 1500 个数据单元,而某些层最多可以处理 300 个数据单元。当数据包从一个有 1500 个数据单元的层发送到只有 300 个数据单元的层时,数据包会被分割成片段;这个过程称为分片。这 1500 个数据单元被分成 5 个片段,即 f1、f2、f3、f4、f5,这些片段按顺序到达目的地。如果在设定的时间内未收到所有片段,则会丢弃所有收到的片段,并向原始源发送超时消息。

在分片的情况下,代码将与 TTL 不同。让我们观察一下超时消息格式。

ICMP Protocol

上面的消息格式显示,超时消息的类型是 11,代码可以是 0 或 1。代码 0 表示 TTL,而代码 1 表示分片。在超时消息中,代码 0 由路由器使用,表示生存时间值已达到零。

代码 1 由目的地使用,表示在设定的时间内未收到所有片段。

参数问题

路由器和目标主机都可以发送参数问题消息。此消息表示某些参数未正确设置。

ICMP Protocol

上面的图显示了参数问题消息的格式。消息类型是 12,代码可以是 0 或 1。

重定向

ICMP Protocol

当发送数据包时,路由表会逐渐扩充和更新。用于实现此目的的工具是重定向消息。例如,A 想发送数据包到 B,并且 A 和 B 之间存在两个路由器。首先,A 将数据发送到路由器 1。路由器 1 将 IP 数据包发送到路由器 2,并向 A 发送重定向消息,以便 A 可以更新其路由表。

注意:重定向消息从路由器发送到同一网络上的主机。

ICMP 查询消息

ICMP 查询消息用于处理互联网错误或进行调试。此消息通常用于 ping 消息。

回显请求和回显应答消息

路由器或主机可以发送回显请求消息。它用于向另一台主机 ping 消息,询问“你是否在线”。如果另一台主机在线,它会发送回显应答消息。回显应答消息由接收到回显请求消息的路由器或主机发送。

查询消息的关键点

  1. 网络管理员可以使用回显请求和回显应答消息来检查 IP 协议的运行情况。假设存在两个主机 A 和 B,A 想与主机 B 通信。如果 A 和 B 之间的链路未断开,并且 B 仍然在线,则 A 主机可以与主机 B 通信。
  2. 回显请求和回显应答消息可以检查主机的可达性,这可以通过调用 ping 命令来实现。

回显请求和回显应答消息的消息格式

ICMP Protocol

上面的图显示了回显请求和回显应答消息的消息格式。回显请求的类型是 8,回显应答的请求是 0。此消息的代码是 0。

时间戳请求和时间戳应答消息

时间戳请求和时间戳应答消息也是一种查询消息。假设计算机 A 想知道计算机 B 的时间,因此它向计算机 B 发送时间戳请求消息。计算机 B 以时间戳应答消息进行响应。

时间戳请求和时间戳应答的消息格式

ICMP Protocol

时间戳请求的类型是 13,时间戳应答的类型是 14。此类型消息的代码是 0。

与时间戳请求和时间戳应答消息相关的关键点

  • 即使时钟不同步,也可以用它来计算源和目的地之间的往返时间。
  • 如果知道确切的传输时间,也可以用它来同步两台不同机器上的时钟。

如果发送方知道确切的传输时间,那么它可以同步时钟。发送方询问接收方时钟上的时间,然后加上时间和传播延迟。假设时间是 1:00 时钟,传播延迟是 100 毫秒,那么时间将是 1:00 时钟加上 100 毫秒。

调试工具

有几种工具用于调试。在本主题中,我们将学习两种使用 ICMP 进行调试的工具。这两种工具是 **ping** 和 **traceroute**。我们在回显请求和回显应答消息中已经了解了 ping,它用于检查主机或路由器是否在线或正在运行。

现在我们来看看 traceroute。

Traceroute 是一种跟踪数据包在 IP 网络上从源到目的地的路径的工具。它记录了数据包在其从源到目的地的路径上的每个跳跃所花费的时间。Traceroute 使用 ICMP 消息和 TTL 值。TTL 值会被计算;如果 TTL 值达到零,数据包将被丢弃。Traceroute 使用较小的 TTL 值,因为它们会很快过期。如果 TTL 值为 1,则消息由路由器 1 生成;如果 TTL 值为 2,则消息由路由器 2 生成,依此类推。

让我们通过一个例子来理解 traceroute。

假设 A 和 B 是两个不同的主机,A 想将数据包发送到主机 B。A 和 B 之间存在 3 个路由器。为了确定路由器的位置,我们使用 traceroute 工具。

TTL 值 = 1: 首先,主机 A 以 TTL 值 1 发送数据包到路由器 1,当数据包到达路由器 1 时,路由器将其 TTL 值减一,TTL 值变为 0。在这种情况下,路由器 1 生成超时消息,主机 A 得知路由器 1 是路径中的第一个路由器。

TTL 值 = 2: 当主机 A 以 TTL 值 2 发送数据包到路由器 1 时,当数据包到达路由器 1 时,TTL 值会减一,TTL 值变为 1。然后路由器 1 将数据包发送到路由器 2,TTL 值变为 0,因此路由器会生成超时消息。主机 A 得知路由器 2 是路径中的第二个路由器。

TTL 值 = 3: 当主机 A 以 TTL 值 3 发送数据包到路由器 1 时,路由器会将其值减一,TTL 值变为 2。然后,路由器 1 将数据包发送到路由器 2,TTL 值变为 1。然后,路由器 2 将数据包发送到路由器 3,TTL 值变为 0。由于 TTL 值变为 0,路由器 3 生成超时消息。这样,主机 A 得知路由器 3 是路径中的第三个路由器。


下一个主题MQTT 协议