简介
ICMP 是 Internet Control Message Protocol 的简写. 它主要用来调试网络通信环境中存在的问题.
比如,当 IP 数据包总是无法正常的发送到目的地址, 当网关没有足够的 buffer 来转发对应的数据包 等问题.
值得一提的是,它属于网络层,不属于传输层. 也就是说它和 IP 协议处于同一层次,而并不是与 TCP/UDP 处于同一层次.
消息格式
ICMP 协议使用 IP 协议头来传输数据. 具体的数据就是 ICMP 规定的一些数据包,我们接下来一一介绍…
因为 ICMP 格式与 IP 相同,这里我们简单介绍以下各个字段. 详细请参考 协议簇: IPv4 详解
几个需要特别注意的字段,及其值:
- Version: 4
- Type of Service: 0
- Protocol: ICMP = 1
接下来,我们来看看常见的 ICMP 报文实例
Destionation Unreachable Message
各字段的意义及其值:
- Type:3
- Code:
0 = net unreachable
1 = host unreachable
2 = protocol unreachable
3 = port unreachable
4 = fragmentation needed and DF set
5 = source route failed - Checksum: 检查和
- Internet Header + 64 bits of Data Datagram: 该字段存放原始的 ICMP 请求,以便将当前这个 ICMP 报文与请求报文对应起来.
描述
- 当根据网关的漏油表推断出该网络地址不可达,网关有可能会返回此ICMP消息。
- 目的端收到 IP 数据包,但是无法正常将该数据包传送到对应端口(该端口有可能没有启用), 目的端有可能会返回此 ICMP 消息
- 当数据包必须被分片才能正常的发送到目的端,当时当前数据包却设置了 Don’t Fragment 标记,此时网关有可能会返回此 ICMP 消息
实例
笔者在自己机器上使用 ping 192.168.1.44 命令得到了 Destination unreachable 消息的包,这里我们来分析以下
- 首先注意最上面的 IP 协议数据内容, Protocol 字段值是 1,表明当前数据包是一个 ICMP 消息。 目的地址和源地址相同,说明从我本地的路由表中解析不到 192.168.1.44 这个地址。
- 接下来是一个 ICMP 消息。 该消息作为 IP 协议的 Data 字段搭载在 IP 协议数据包上.
- ICMP 消息的 type 是 3, 正是 Destionation Unreachable Message
- Code 是 1, 表明主机不可达
- Internet Header + 64 bits of Data Datagram 字段中包含了我们发送的 ICMP 请求的 IP 数据包. 由这个 IP 包的源地址和目的地址得知,我本地是 192.168.1.35, 我 ping 了主机 192.168.1.44. 至于这个 ICMP 请求,我们先不分析,后边我们专门来分析.
Time Exceeded Message
它的包格式与 Destionation Unreachable Message 相同,这里不再赘述.
各字段的意义及其值:
- Type:11
- Code:
0 = time to live exceeded in transit
1 = fragment reassembly time exceeded
描述
- IP 协议规定当某个数据包在传输过程中 TimeToLive 字段的值减少到 0, 那个这个数据包应该被丢弃. 于此同时,丢弃数据包的网关有可能会给源主机发送此 ICMP 消息来通知该数据包被丢弃.
- 当目的端收到分片的数据包后,但是由于部分分片丢失而无法在指定时间内完成数据包重组,那么该数据包会被丢弃, 丢弃数据包的网关有可能会给源主机发送此 ICMP 消息来通知该数据包被丢弃.
实例
笔者使用 ping -i 2 baidu.com 命令抓取到了此类型的 ICMP 数据包,这里我们省略掉于前文重复的部分,直接贴出 ICMP 包相关的信息
- 这里注意,IP 头中 Time to live 字段的值是 1,而不是 0. 猜测是因为在处理该数据包的中间节点发现它并不是该数据包的目的地址,而此时 time to live 已经是 1,自己处理完之后再将该值减少 1 之后,该数据包的 time to live 就是 0,因此,该节点给我们发送了 time exceeded message.
Parameter Problem Message
各字段的意义及其值:
- Type:12
- Code:
0 = pointer indicates the error - Pointer: 当 code == 0, 这个字段指明出错的字节位置.
描述
当网关或者目标主机无法根据 IP 头正确的解析此数据包时,就会丢弃该数据包并发送此 ICMP 报文.
这个问题的可能原因是 错误的使用 Option.
Source Quench Message
它的包格式与 Destionation Unreachable Message 相同,这里不再赘述.
各字段的意义及其值:
- Type:4
- Code: 0
描述
当网管或者目标主机没有足够的 buffer 来处理对应的数据包时,就会丢弃数据包并发送此 ICMP 报文
Redirect Message
各字段的意义及其值:
- Type:5
- Code:
0 = Redirect datagrams for the Network
1 = Redirect datagrams for the Host
2 = Redirect datagrams for the Type of Service and Network
3 = Redirect datagrams for the Type of Service and Host - Gateway Internet Address: 该字段指明发送给当前目的主机的数据包都应该被发送给 Gateway Internet Address 所指定的网关
描述
这种 ICMP 消息在如下情况下会被发送:
假定网关 G1 从一个相连的主机或网关收到一个数据包,G1 检查自己的路由表找到该数据包应该被转发给网关 G2,再由 G2 继续转发,直到该数据包到达主机 X. 但是如果 G2 和 该数据包的源地址处于同一个网络,那么此时 G1 会发送此 ICMP 消息来建议源主机将发送给 X 的数据包都直接发送给 G2,这样路由长度最短,数据发送速度更快.
Echo or Echo Reply Message
各字段的意义及其值:
- Type:
8 = Echo Message
0 = Echo Reply Message - Code: 0
- Identifier 和 sequence number: 当 code = 0 时, 使用 Identifier 和 sequence number 来帮助将 Echo Message 和 Echo Reply Mesage 对应起来
描述
正如我们前面已经看到,我们在收到一个 ICMP 响应时,响应的 ICMP 数据包中都会包含对应 Echo Message.
实例
下面展示一个 Echo Message 的结构
下面时对应的 Echo Reply Message 的结构
值得注意的时: Echo Message 和 Echo Reply Message 中的 identifier 和 sequence number 字段时相同的. 这样我们就得知 这两个数据包时互相对应关系.
而我们收到了 Echo Reply Message,也就证明我们到对应的目的主机的链路是工作的.
Timestamp or Timestamp Reply Message
各字段的意义及其值:
- Type:
13 = Timestamp Message
14 = Timestamp Reply Message - Code: 0
- Identifier 和 sequence number: 同 Echo Message 和 Echo Reply Message.
- Originate Timestamp:发送方发送最后一次修改这个数据包的 timestamp
- Receive Timestamp: 接收方接收这个数据包的 timestamp
- Transmit Timestamp: 接收方最后一次修改这个数据包的 timestamp
Information Request or Information Reply Message
各字段的意义及其值:
- Type:
15 = Information Request Message
16 = Information Reply Message - Code: 0
- Identifier 和 sequence number: 同 Echo Message 和 Echo Reply Message.
描述
这个数据包发送时不填写目的地址字段,接收方在 reply message 中填写自己的地址信息.
使用这个数据包可以用来发现当前网络中所有的主机地址信息.
END!