深入理解ICMP协议

发布时间 2023-09-13 19:06:10作者: tomato-haha

在日常工作中,我们经常需要判断网络是否连通,相信大家使用最多的命令就是 ping,traceroute 啦。大家都知道 ping/traceroute 命令是基于 ICMP 协议来实现的,那么什么是 ICMP 协议呢?ping/traceroute 命令又是如何基于 ICMP 实现的呢?

今天这篇文章,我们就来一起搞清楚其中的原理。下面首先我们先来了解一下ICMP 协议。

ICMP协议

ICMP是 Internet Control Message Protocol 的缩写,即互联网控制消息协议。它是互联网协议族的核心协议之一。它用于 TCP/IP 网络中发送控制消息,提供可能发生在通信环境中的各种问题反馈,通过这些信息,使网络管理者可以对所发生的问题作出诊断,然后采取适当的措施解决问题。

虽然 ICMP 是网络层协议,但是它不像 IP 协议和 ARP 协议一样直接传递给数据链路层,而是先封装成 IP 数据包然后再传递给数据链路层。所以在 IP 数据包中如果协议类型字段的值是 1 的话,就表示 IP 数据是 ICMP 报文。IP 数据包就是靠这个协议类型字段来区分不同的数据包的。如下图 WireShark 抓包所示:

在 IP 通信中如果某个包因为未知原因没有到达目的地址,那么这个具体的原因就是由 ICMP 负责告知。而 ICMP 协议的类型定义中就清楚的描述了各种报文的含义。

ICMP协议类型

ICMP协议的类型分为两大类,查询报文差错报文。如下表:

是不是看起来有点多啊?计算机网络真的是博大精深啊。而平时我们经常使用的少之又少。

ICMP报文格式

从 ICMP 的报文格式来说,ICMP 是 IP 的上层协议。但是 ICMP 是分担了 IP 的一部分功能。所以,他也被认为是与 IP 同层的协议。下面一起来看一下 ICMP 数据包格式和报文内容吧。具体参考下图:

可以看到,我们一层层剥开 ICMP 的外壳,查看其本质。方便我们更好的理解 ICMP 协议。

ICMP协议实现--Ping命令

通过上面的叙述,我们初步了解了 ICMP 协议的内容,那么下面我们来看一下ICMP 的具体实现与应用吧,首先我们来了解查询报文的应用--ping,下面我们通过 ping 同一个子网的主机,来看一下整个过程是怎么样的。

那么比较完整的流程是:

1. 向目的服务器发送回显请求
首先,向目的服务器上执行ping命令,主机会构建一个 ICMP 回显请求消息数据包(类型是8,代码是0),在这个回显请求数据包中,除了类型和代码字段,还被追加了标识符和序号字段。标识符和序号字段分别是 16 位的字段。ping 命令在发送回显请求数据包时,会将进程号填写在标识符里。对于序号,每送出一个数据包数值就增加1。而且,回显请求的选项数据部分用来装任意数据。这个任意数据用来调整 ping 的交互数据包的大小。如下图在 192.168.1.10上执行 ping 192.168.1.1的命令:

ping 命令执行的时候,他的进程号是 43991:

 

通过 WireShark 抓包可以看出,上图中的 192.168.1.10 主机会构建一个 ICMP 回显请求消息数据包。

上图中我们可以看到 ICMP 的 Type(协议类型)是 8,Code(代码)是 0,Identifier(ping进程号) 是 43991,同时还有 Sequence Number 发送序号11,以及发送时间 。

 

2. 目的服务器发送回显应答

当192.168.1.10送到 回显请求数据包后,192.168.1.1就会向发送方192.168.1.10发送回显应答(类型是0,代码是0),这个 ICMP 回显应答数据包在 IP 层来看,与被送来的回显请求数据包基本上一样。不同的只有源、目标 IP 地址字段被交换了,Type类型字段里填入了表示回显应答的0。通过 WireShark 抓包可以看出,如下图:

3. 源服务器显示相关数据

如果源服务器可以接收到回显应答数据包,那我们就认为192.168.1.1是正常工作着的。进一步,记住发送回显请求数据包的时间,与接收到回显应答数据包的时间差,就能计算出数据包一去一回所需要的时间。这个时候ping命令就会将目的服务器的 IP 地址,数据大小,往返花费的时间打印到屏幕上。如下图:

ICMP协议实现--traceroute命令

traceroute命令是一款充分利用 ICMP 差错报文类型的应用,其主要用作追踪路由信息,下面我们来逐个查看一下其工作原理。

我们通过执行 traceroute 192.168.1.1,来分析一下他的原理,它的原理就是利用 IP 包的 TTL 从 1 开始按照顺序递增的同时发送 UDP 包,强制接收 ICMP 超时消息的方法。

首先 traceroute 会将 IP 包的 TTL 设置 为 1,然后发送 UDP 包,他会填入一个端口号作为 UDP 目标端口号(默认是:33434-33534)。如下图:

当目的主机收到 UDP 包后,会返回 ICMP 差错报文消息(类型 3,代码 3)。参照上面的表,该错报文类型是端口不可达,说明发送方发出的 UDP 包到达了目的主机。如下图:

这样的过程,traceroute 就可以拿到了所有的路由器 IP,这样子就可以看到从源主机到目的主机过程中的所有路由信息。

当然实际情况有的路由器禁用 ICMP ,那么他就根本不会返回这个 ICMP 差错报文,所以是看不到中间经过的路由IP的。

Tips:traceroute 在类 Unix/Linux 系统中默认使用的是 UDP 协议,也可以通过参数修改为使用 ICMP 协议;Windows 操作系统中只使用 ICMP 协议。

说了这么多,我们还是直接来看一张图吧,基本可以描述清楚 traceroute 的整个过程。如下图:

总结

以上内容就是关于ICMP协议的全部内容啦,相信你看完本篇文章就可以深入理解每一次ping,traceroute背后的工作原理啦。好了,当我们深入学习完以上内容,当我们面对面试官的各种***钻问题时,是不是游刃有余了呢?那么面试官一般都问些什么问题呢?这就给推荐牛客网,各种面试经历,还有在线面试模拟。