【计算机网络】ping 和 traceroute 到底有什么区别?深入浅出 ICMP 协议!

 个人原创笔记,含有自己的理解并且整理了很久。若出现错误,请大佬们理解与及时指正!课程来源:极客时间。


 在复习 ICMP 协议前,我们先来看看 ping 和 traceroute LINUX Windows 操作系统中的输出,了解一下他们是干什么用的。

ping(LINUX):

ping(Windows):

traceroute(LINUX):

tracert(Windows):

  • ping:我们通常使用 ping 命令来测试到某一个 IP 之间的网络是否通畅。 如果 ping 某个网址(IP)通畅,说明该主机可以访问到对应网址(IP)上。
  • traceroute:来定位到目标主机之间的所有路由器。比如上图,我分别在Windows 下和 Linux 下对 www.baidu.com 进行了路由追踪,可以看到 IP 数据报从我们主机到百度服务器的转发过程。

 为什么 traceroute 和 tracert 显示不同呢?默认情况下,tracert是向目的地址发出ICMP请求回显数据包而traceroute是向目的地址的某个端口(大于30000)发送UDP数据报。两者用于探测的数据类型不同。但他们也有一个共同点:都是通过设置发送包的TTL的值从1开始、逐次增1的方法来探测。

我们必须知道的是,以上的命令都是基于 ICMP 协议实现的,因此我们先来认识一下 ICMP 协议


ICMP协议

ICMP 协议,全称是 Internet Control Message Protrol,翻译过来就是 互联网控制报文协议。这里的重点在于 怎么起到控制的作用呢? 这就是 ICMP 协议的精髓所在了,它使用了多种 类型码 对网络包在网络上传输出现的错误进行了分类,从而我们能通过返回的错误类型知道这个网络包是怎么“死”的,进而方便我们对后面网络包的传输进行控制。

关于ICMP协议到底是那一层,我觉得这是最好的回答:

ICMP 协议介于传输层和网络层之间。不能说它是网络层协议,是因为它依赖于所有的 IP 协议实现,ICMP 报文在传输过程中,又很可能被传输层解析处理。

尽管如此,我们通常仍然认为 ICMP 协议是网络层协议。维基百科对此有如下解释:

ICMP 协议使用了 IP 协议的基本支持,以至于它好像是更高层的协议。然而, ICMP 协议实际上是 IP 协议的一个组成部分。尽管 ICMP 报文被封装在标准 IP 协议包中,但与一般的 IP 包处理不同,ICMP 报文通常作为特殊情况处理。(维基百科)

ICMP 报文是被封装在 IP 包里面的,因为在传输的时候,肯定需要源IP地址和目标IP地址,具体见下图:(图中”相应“改成”响应“)

ICMP报文有很多的类型,不同类型对应不同的代码。最常用的为主动请求(8)主动请求的应答(0)

从上图最右边一列可以看出,ICMP报文分类了两种 ,一种是 查询报文类型,另外一种是 差错报文类型而我们前面看的 ping 命令就是查询报文的一种应用;traceroute 是差错报文的一种应用。我们接下来分别来看看。

查询报文类型

查询报文类型比较简单,就是主动去探查网络情况。对 ping 的 主动请求,进行网络抓包,称为 ICMP ECHO REQUEST。同理。对于 主动请求的回复,称为 ICMP ECHO REPLY。这里多了两个字段,标识符 和 序列号 用于匹配 回显应答 和 回显请求。在 选项数据 中可能包括一个表示传输时间的 时间戳 和一个 序列号 ,这允许 PING 以无状态的方式计算 往返时间(Round Trip Time, RTT),而不需要记录每个包的传输时间。

PING

机器A:192.168.1.1,机器B:192.168.1.2。

第一步。机器A 首先在构建一个 ICMP 请求数据包,里面封装了 主动请求类型字段(8)序列号(ping的时候会发出多个,这个给他们编编号,用于区分),同时为了能计算 RTT(往返时间),会在报文的数据部分插入发送时间。这里再次把运行图片丢出来,看看为什么 ICMP请求数据包要包含这些。

 第二步。ICMP 协议将这个包和目标IP一起给网络层,让网络层封装好。网络层就把 ICMP 数据包和 源IP、目标IP封装成一个 IP 数据包。

第三步。IP 数据包继续往下走,到了数据链路层,需要加上 源MAC地址目标MAC地址。这里要么就是直接从 ARP 缓存中找到对应 目标MAC地址,要么就是发送 ARP 协议来找目标 MAC 地址,这不是本文重点,不赘述。总之,结合两者的物理地址,封装成一个数据帧,继续向下传到物理层,按照相应的以太网介质访问规则发送出去。

第四步。机器B收到数据帧后,先检查 MAC地址,发现是自己的数据帧,就向上层递交。

第五步。上层继续拆开,发现 IP 也是自己的,就 将有用的信息提取后交给 ICMP 协议

第六步。机器B就会构建一个 ICMP 数据包,类型字段为 0(主动请求的应答)序列号为收到请求数据包中的序列号,然后再发送给主机A。

分析结果:在规定时间内,若 机器A 没有收到 ICMP 的应答包,说明目标主机不可达。反之,则说明目标主机可达。同时用当前时刻减去数据包最初的发送时刻,就是 ICMP 数据包的时间延时。

差错报文类型

差错报文类型就是来汇报差错情况的。我们看看上图的 类型3(终点不可达)类型4(源抑制) 和 类型11(超时) 中列举的都是错误情况。

Traceroute

Traceroute 可以认为是一个“大骗子”,它利用了 ICMP 的规则,故意制造一些能够产生错误的场景。

第一个作用:故意设置特殊的TTL(Time To Live,可以理解为网络包的生命,每经过一个路由器 - 1),来追踪去往目的地时沿途经过的路由器。Traceroute 的参数指向一个目的IP地址,它会发送一个 UDP 的数据包。将TTL设置为1,也就是一旦遇到一个路由器,数据包就会“死亡”。如果中间的路由器不止一个,那么碰到第一个路由器就“死亡”,于是返回一个 ICMP 网络差错包,类型是时间超时。接下来再发送TTL为2的UDP数据包,,看看通过两个路由器能到哪里。于是如此反复,一直到走到终点。

怎么知道 UDP 有没有到达目的主机呢?

Traceroute 程序会发送一份 UDP 数据报给目的主机,但它会选择一个不可能的值作为 UDP 端口号(大于 30000)。当该数据报到达时,将使目的主机的 UDP 模块产生一份“端口不可达”错误 ICMP 报文。如果数据报没有到达,则可能是 超时

第二个作用:故意设置不分片,从而确定路径的MTU。要做的工作首先是发送分组,并设置“不分片”标志。发送的第一个分组的长度正好与出口 MTU 相等。如果中间遇到窄的关口会被卡住,会发送 ICMP 网络差错包,类型为“需要进行分片但设置了不分片位”。其实,这是人家故意的好吧,每次收到 ICMP“不能分片”差错时就减小分组的长度,直到到达目标主机。

最后总结

  • ICMP 协议工作于传输层和网络层之间,但由于需要网络层的封装,因此认为是 网络层的协议
  • ping 是查询报文的应用,主动查询类型为8,主动查询类型的应答为0
  • tracerout 是差错报文的应用,细分为两个功能,一个是追踪路由(到终点:端口不可达;未到终点:超时),另一个是确定路径MTU(通过设置不分片完成)
发布了104 篇原创文章 · 获赞 27 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_41960890/article/details/105020897