实验 19:网际控制报文协议 ICMP 的应用
# 190.实验 19:网际控制报文协议 ICMP 的应用
下面我们来进行一个仿真实验,本仿真实验的目的在于验证 PING 命令和 tracert 命令的工作原理,这两个命令都是基于网际控制报文协议 ICMP 而实现的。
ping 命令在我们之前的仿真实验中经常会用到,我们使用它来测试主机之间的连通性,或者是主机和路由器之间的连通性,又或者是路由器和路由器之间的连通性。tracert 命令用来探测源主机到达目的主机之间要经过哪些路由器,PING 命令和 tracert 命令都是基于 ICMP 协议来实现的。
我已经在软件中构建好了这样一个网络拓扑,并且按图所示给各主机和路由器的各接口都配置了相应的 IP 地址和子网掩码。另外对于路由器 R1 我还给它添加了一条静态路由,也就是到达网络 192.168.1.0 的这样一个网络的话,我们下一跳,应该让 R1 跳给 R2 的接口,那 IP 地址为 10.0.2,同理还给 R2 路由器添加了一条到达网络,也就是 192.168.0.0 这样的一个网络的一条静态路由,下一跳应该跳给 R1 的接口,那也就是下一跳的 IP 地址为 10.0.0.1。
下面我们在主机 H1 的命令行使用,PING 命令来检测一下我们拓扑是否建立了成功了,以及各项配置是否是配置的正确的。那么我们点击主机 H1,然后到它的桌面选项卡,然后到它的命令行提示符,然后我把这里置顶。
下面的话我们就来 ping 一下,用我们主机 H1, 去 ping 主机 H2 的 IP 地址 192.168.1.1
那就开始进行 ping 的过程了,这个我们之前已经非常熟悉了,如果是刚建立好拓扑首次 ping 的话,那么中间有几个路由器就会产生几次超时,这是因为有 ARP 协议,也就是路由器,它还需要问下一条路由器的地址对应的 MAC 地址,对于 R2 这个路由器它还要问目的主机它的 IP 地址对应的 MAC 地址,当然这些 ARP 的动作都是在 R1 要帮主机 H1 转发数据包,或者是 R2 要转发来自 R1 的数据包的时候才会进行。这样的话我们前两次都会是超时的 PING,然后他第三次向他发送的请求数据包,主机 H2 就回来了一个响应,那么主机 H1 收到以后,那就会做出这样的一个显示来告诉我们。
同理主机 H1 第三次发了一个请求,然后到达主机 H2 以后,他收到了这个请求,会发一个响应回来给主机 H1。这样的话我们首先用 PING 命令来检测了一下连通性,那么这个是通的。至于 PING 命命的背后是如何利用 ICMP 协议来做的原理,我们等一会来进行单步仿真:
C:\>ping 192.168.1.1
Pinging 192.168.1.1 with 32 bytes of data:
Request timed out.
Request timed out.
Reply from 192.168.1.1: bytes=32 time<1ms TTL=126
Reply from 192.168.1.1: bytes=32 time<1ms TTL=126
Ping statistics for 192.168.1.1:
Packets: Sent = 4, Received = 2, Lost = 2 (50% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
2
3
4
5
6
7
8
9
10
11
12
13
下面我们再干一件事情,就是我们来跟踪一下从主机 H1 到达主机 H2,它中间经过哪些路由器,当然对于我们人来说一眼就看出来了,一看逻辑拓扑就看出来要过 R1 还要过 R2,但是作为主机 H1 来说的话,他是如何知道其实可以通过 tracert 192.168.1.1,也就是我们要跟踪一下到达主机 H2。输完这条命令以后,他会首先给我们一个提示,就是说你要到追踪到达 IP 地址的话,他最终最多帮你追踪中间的 30 跳。如果这里面从源主机到达目的主机有多于 30 个路由器有多于 30 跳的话,它只显示前 30 个。
那么对于每一跳,这就是它整个路径上的第一跳,那么 192.168.0.254,也就是路由器 R1 的接口,主机 H1 到达主机 H2 路径上的第一个路由器,总之 tracert 就帮我们探测出来了,而这个地方写的是时间 MS 是毫秒,我们可以看到实际上它进行了三次,对于这路径上的第一个路由器,它就进行了三次测试,那么每一次的时间的延时就是耗费的时间,他统计出来是 0 毫秒,当然这个并不代表说主机 H1 到达这个路由器 R1 中间就没花时间瞬间就过来了,根本就没有任何时间,只是他在以毫秒为单位前面这个数值会非常小,也就是 H1 到 R1 会非常快,一般情况下,那么所以它统计出来的近似认为是 0 秒 0 毫秒。
同理第二条就代表发现了路径上的第二个路由器,具体它的地址是 10.0.2,我们看到 R2 的接口是 10.0.0.2,那同理是第三个。到第三个的话,其实它就已经叫做跟踪结束了,我们可以看到这个我们要让他跟踪的目的 IP 地址 192.168.1.1,也就是我们主机 H2 它已经跟踪到了:
C:\>tracert 192.168.1.1
Tracing route to 192.168.1.1 over a maximum of 30 hops:
1 0 ms 0 ms 0 ms 192.168.0.254
2 0 ms 0 ms 0 ms 10.0.0.2
3 0 ms 0 ms 0 ms 192.168.1.1
Trace complete.
2
3
4
5
6
7
8
9
当然由于我们网络拓扑比较简单,中间的路由器比较少,所以我们看到的每次对于每一个路由器,它的往返的时间的话并不是很长,近似都是 0。如果在实践当中你去跟踪到达某一个网站的话,那么一般这个地方是不会出现 0 毫秒的,当然一般来说第一跳有可能会出来,随着往后走,不同的跳数的路由器就离你不同的,我们指的是中间隔的不同的路由器,那么它测量出来的时间就要有所不同,一般是呈增长的趋势,但是也有可能第二跳的耗时反而比第三跳或者说是第十二跳的比第十五跳的耗时反而大,这都是有可能的。因为还要考虑到网络的拥塞程度等等。
这样的话我们首先介绍了一下 ping 命令和 tracert 命令,它的大致的功能以及它的命令用法里面的使用完了以后所表达的含义,我们应该能够把它看懂。
接下来我们就来看一下 ping 命令是如何利用 ICMP 协议来实现的。那么我们先把从实时模式切换到仿真模式,监听 ICMP。因为 ping 命令实际上就是利用了 ICMP 协议,封装数据包然后来实现的。那么我们这次用主机 H2 来 ping 一下主机 H1:ping 192.168.0.1
这个时候我们可以看到主机 H2 准备发送数据包了,这个数据包我们可以点开看一下它的细节。
然后我们可以看到 ping 实际上我们说的是命令,实际上它是一个应用程序,把它运行起来就叫做 ping 进程,他要发送一个 ping 的请求,这个 ping 的请求实际上它是利用了 ICMP 的一种报文类型,这个我们在理论课中已经讲过了,叫做回送请求这样的一个请求报文,是用来询问目的主机的,然后他会把 ICMP 的回送请求报文又封装在 IP 数据报里面,我们这是以太网的话,最终还要封成以太网的帧,然后最后通过物理层把它发送走。
我们发送也可以看一下它具体的封装细节,这个地方以下的这一部分就是 ICMP 的请求报文,它具体的里面的内容我们就要不详细解释了,然后把这一部分封装在 HIP 数据报的数据载荷里面。然后再把 IP 数据报整个又放在以太网的帧里面。
我们可以看到在我们的命令行上显示的它也是在等待,因为我们现在是单步仿真,所以我们让它前进。那么到达了路由器 R2,路由器 R2 查自己的路由表去转发,他知道要转发给 R1,那么到 R1 以后再进行查表转发,就转发到了主机 H1。
我们看一下主机 H1 在收到这个数据包以后会做什么样的处理,我们把它点开。这样的话啊我们可以看到主机 H1 从物理层把它变接入信号变换成比特,然后往上送到了以太网,识别出来就是一个帧,然后从这个帧里面来提出出来的,这是一个 IP 数据报,而 IP 数据报的话在解出来的发现这是一个 ICMP 的这样一个报文,一看是 ICMP 的询问报文,所以主机 H1 它会重新封装一个数据包,拿 ICMP 封装一个数据包,封装成回送请求报文的一个应答报文。这样的话也就是说他收到的他解释出来说报文是一个回送请求报文,那么紧接着我们自己 H1 就会重新构建一个数据包,那么这就是它构建数据包的结构的处理。
我们看一下这个时候它的 ICMP 进程就要发送一个叫做回送回答的这样的一个响应报文来响应 H2。然后它是封装在 IP 数据报里面的,然后再分装到一台网站,最后通过物理层把客流转变成电信号号,那么如果有兴趣,你可以仔细看一下出站的它又是如何封装的数据包的这样的一个显示情况,我们这里就不看了。
那么我们再继续前进,那么回送的响应报文,到了每个路由器都是查表转发,最终就到达了 H2。那相应的我们可以看到我们在 H2 上面命令行使用的,PING 命令他的第一次 PING 的过程就结束了,他收到了响应,然后这是响应的多大 32 个字节,然后耗时了 6 个毫秒。
然后 TTL 值我们在讲 IP 数据报首部的时候是讲过的是生存时间,那么通过这个东西以及我们网络拓扑我们可以看出来,我们可以马上就知道,其实主机 H1 在发回 ICMPT 的回送响应的时候,其实是经过了两跳,从图上看是两跳,那么我们可以推断出来什么东西,就是它发送这个包的话,封装的 IP 数据报的时候,当初他封装的 PDF 什么应该是 128,那么到了路由器 R1 先减 1 就变 127,那么到了路由器 R6,-1 就变成 126,最终到达 H2 的时候,看到的 TTL 只能就是 126。这样第一个就这件事发送了一个 ICMP 的回送请求,然后总结 H1 收到以后解析完了,知道我应该发回一个回送应答这样子,H2 收到了第一次测试就做完成了
这个命令的话,如果我们就这么打,那么他是会做这么 4 次的,那么我们接下来快速的把第二次的也给它发出来。那么第二次响应就要回来了,我们点的快一点,那么这个时候 H2 的 PING 的应用进程告诉我们,我收到了第二次的响应。同理他还会再进行两次,总共有 4 次请求,4 次响应,我这里就不再演示了。
我们再来看一下吹 tracert 命令是如何利用 ICMP 协议来实现的。这次我们用主机 H1 在它的命令行上输入 tracert 命令,来跟踪一下它到达主机 H2 要过哪些路由器:tracert 192.168.1.1
这样的话就可以看到在我们主机 H1 这它形成了一个数据包,tracert 命令实际上它叫做 tracert 这样的一个进程,我们说了它虽然有时候我们叫命令,其实它是一个应用程序,你执行它的话,它就变成一个进程,是一个动态的东西,那么它就会构建一个叫做 ICMP 的回送请求报文,这跟 PING 一样的,刚开始是一样的,也是要利用回送请求报文,那么他就把它发送出去,那么发送出去的话关键在这个地方,我们来看一下回送请求,ICMP 的回送请求报文它是封装在 IP 数据报里面的,那么这个点很关键,我们来看一下它的细节,在出站 PDU 里面我们会发现那么这是他构建的回送请求,这跟 PING 命令构建的回送请求是一样的,只不过当它把它装在了 IP 协议的也就是 IP 数据报的数据载荷部分以后,在 IP 首部的 TTL 字段也就生存时间字段它把它给为 1。
而我们之前 PING 命的我们知道是给 128 的,而我们这里的话跟踪路由的命令它直接把它给成 1,那目的是什么?目的的话就是希望这个数据包到达这条路径上的第一个路由器的时候,这个时候路由器把这个数据包的生命值给它减一,那么这时候就变成 0 了,所以数据包就不会转发数据包,同时路由器还会把这个事情通过一个 ICMP 的差错报告,你刚才发给我,让我帮你转发的数据包,我把它丢弃了,因为它生命时间到了,我把这个事告诉你,通过 ICMP 的差错报告。差错报告有很多种类型,比如说主机不可达,还有的话时间超过,那么我们这里面很明显,通告的差错是时间超过,也就是待转发数据包的生命周期到了,那么我们继续来前进,看一下是不是这样子的。
我们点击捕获按钮,这个数据包就到达了路由器 R1,那么我们看一下路由器 R1 给它一把叉,那意思是这个数据包过期了,我们可以点来看一下物理层,信号变比特流,然后送上去是处理帧,从帧里面提出 IP 数据报,从 IP 数据报里面本身是可以解出来,它里面封装的是 ICMP 的回送请求报文,但是实际上把 IP 数据报的首部一看它里面 TTL 字段的值是一,我如果要把这个数据包转出去的话,我要先把它减一,这时候它已经是 0 了,所以它是过期的,所以我就不能再转这个数据包了。所以我这时候一方面把它丢弃掉,另外一方面我还要给数据包的源主机去发送一个 ICMP 的差错报告报文,具体的差错叫做时间超过。
那么我们再来打开看一下,那么这个就是差错报告报文,那么它具体是时间超过这个类型,它虽然是差错报告报文,那么差错报告报文有很多种类型,时间超过是其中一种,然后他就被封装在 IP 数据报之中,然后就会把它封装成以太网的帧,然后再通过物理层转发出去。
当我们再次点击捕获以后,差错报告就回到了主机 H1,这样的话主机 H1 把 IP 数据报解出来,那么最终就知道这是一个 ICMP 的这样的差错报告。那么我们可以看到在这主机 H1 的命令行上,这出现了一个往返时间的测试值,也就是第一跳我已经知道是谁了,他是怎么知道的,其实这个数据包里面就带有路由器接口的 IP 地址,所以他就知道了他第一跳路由器的 IP 地址是什么。那么这种过程要往返三次,那么他进行第二次发送了,第二次发送的时候里面的 TTL 值封装成 IP 数据报的时候,TTL 值仍然是一。那么当然就到达第一个路由器的话就会被丢弃掉,然后第一个路由器给他一个差错报告,叫做时间超过。那么再测出来第二次的也是两毫秒,
那么再走第三次,第三次 IP 数据报封装的 ICMP 的回送请求里面仍然是 TTL 值唯一的,所以路由器 R1 把它丢弃掉了,又发回这个差错报告。这样的话对于第一个第一条路由器的话,那么最终给出的结果三次测试往返时间都是两毫秒,然后路由器的 IP192.168.0.254,那也就是找到了 H1 要到达 H2 整个路径上的第一个路由器它就找到了。
那么我们再往下走,他就准备找第二个路由器了,那么他要发第二个包了,那么我们打开看一下,这个包仍然是用 ICMP 先做一个回送请求的这样报文,然后把报文封装在 IP 数据报里面,那么我们看一下细节,这个时候 IP 数据报首部里面的生存时间它就可以成 2 了。这样的话我们应该能够想象到数据包到达 R1 以后, TTL 值被减一,那么得出来的结果是 1 剩余时间还是 1 剩余距离或者说跳数还有一跳可以跳,所以 R1 就把它转发出来到 R2,R2 再把它 1-1 就变成 0 了,就不能转发。此时 R2 的就会把数据包丢掉,并且给 H1 发回一个 ICMP 的时间超过这样的一个差错报告。我们来看一下,单部点击到了路由器 R1,这时候我们看一下进站的时候, IP 数据报 TTL 是2,然后出站的时候他就把它减 1,变为 1 还是可以发的,所以这时候就把它转发出来了。
那么到达 R2,R2 把它又一减一发现是 0 了,所以就要丢弃掉,那么此时还要给我们的源主机,也就是被丢弃这个数据包的源主机给他一个差错报告,就是说数据包的生存时间到了,我们看一下,这样的话当主机 H1 收到这个的差错报告的时候啊,他就发现了第二个路由器的存在,并且这一次往返测试的时间是 4 毫秒。同理了,针对第二个路由器,它也会进行总共三次这样的测试,每一次它的 TTL 值都是 2,发送出来的时候都是 2,那么经过第一个减 1,到了第二个路由器就是减 0,所以产生差错报告。
那么再接下来我们都可以想象到了,马上要进行第三次测试,主机 H1 就是测第三跳到底是在哪里?那么它构建一个数据包,这个数据包里面仍然封装的最开始用 ICMP 这个协议构建一个回送请求,然后把它装在 IP 数据包里面,那么这个时候 IP 数据包的生存时间它给它弄成 3,那么这样到达 R1 的话减一为二可以转发,到达 R2 的话减一为一还可以转发,那么就到达了目的主机。那么我们来快速的看一下。同样的对于最终的目的主机它也要进行三次测试。第三次的测试完成,那么整个的 tracert 的过程就结束了。
那么在解释一下这儿的 trace 就是跟踪 RT 是路由的这样的一个缩写词。这样的话我们今天就验证了这个啊,PING 命令以及 tracert 命令他们是如何利用 ICMP 的协议的。
那么我们总结一下 PING 命令它其实利用的是 ICMP 的询问报文,只利用了询问报文,当然目标方收到以后会针对询问报文回送一个应答报文。 而 tracert 的话,它一方面利用了询问报文和针对询问报文的应答报文,另外一部分它还利用了一个 ICMP 的差错报告,报文这里面具体的差错报告是报告的是生存时间超过,也就是时间超过。
相信经过这样的一个仿真实验,您对 ICMP 的作用有了更深入的理解。