问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

ping的工作原理

创作时间:
作者:
@小白创作中心

ping的工作原理

引用
CSDN
1.
https://blog.csdn.net/qq_37896194/article/details/138481787

本文将深入探讨ping命令的工作原理,从ICMP协议的基础知识到ping命令的具体实现机制,通过生动的比喻和详细的步骤说明,帮助读者理解这一常用的网络诊断工具。

IP协议的助手 —— ICMP 协议

ping是基于ICMP协议工作的,所以要明白ping的工作,首先我们先来熟悉ICMP协议。

ICMP是什么?
ICMP全称是Internet Control Message Protocol,也就是互联网控制报文协议。

里面有个关键词——控制,如何控制的呢?
网络包在复杂的网络传输环境里,常常会遇到各种问题。当遇到问题的时候,总不能死的不明不白,没头没脑的作风不是计算机网络的风格。所以需要传出消息,报告遇到了什么问题,这样才可以调整传输策略,以此来控制整个局面。

ICMP功能都有啥?
ICMP主要的功能包括:确认IP包是否成功送达目标地址、报告发送过程中IP包被废弃的原因和改善网络设置等。

在IP通信中如果某个IP包因为某种原因未能达到目标地址,那么这个具体的原因将由ICMP负责通知。
如上图例子,主机A向主机B发送了数据包,由于某种原因,途中的路由器2未能发现主机B的存在,这时,路由器2就会向主机A发送一个ICMP目标不可达数据包,说明发往主机B的包未能成功。

ICMP的这种通知消息会使用IP进行发送。
因此,从路由器2返回的ICMP包会按照往常的路由控制先经过路由器1再转发给主机A。收到该ICMP包的主机A则分解ICMP的首部和数据域以后得知具体发生问题的原因。

ICMP包头格式
ICMP报文是封装在IP包里面,它工作在网络层,是IP协议的助手。
ICMP包头的类型字段,大致可以分为两大类:

  • 一类是用于诊断的查询消息,也就是「查询报文类型」
  • 另一类是通知出错原因的错误消息,也就是「差错报文类型」

查询报文类型

回送消息——类型0和8
回送消息用于进行通信的主机或路由器之间,判断所发送的数据包是否已经成功到达对端的一种消息,ping命令就是利用这个消息实现的。
可以向对端主机发送回送请求的消息(ICMP Echo Request Message,类型8),也可以接收对端主机发回来的回送应答消息(ICMP Echo Reply Message,类型0)。

相比原生的ICMP,这里多了两个字段:

  • 标识符:用以区分是哪个应用程序发ICMP包,比如用进程PID作为标识符;
  • 序号:序列号从0开始,每发送一次新的回送请求就会加1,可以用来确认网络包是否有丢失。

在选项数据中,ping还会存放发送请求的时间值,来计算往返时间,说明路程的长短。

差错报文类型

接下来,说明几个常用的ICMP差错报文的例子:

  • 目标不可达消息——类型为3
  • 原点抑制消息——类型4
  • 重定向消息——类型5
  • 超时消息——类型11

目标不可达消息(Destination Unreachable Message)——类型为3
IP路由器无法将IP数据包发送给目标地址时,会给发送端主机返回一个目标不可达的ICMP消息,并在这个消息中显示不可达的具体原因,原因记录在ICMP包头的代码字段。
由此,根据ICMP不可达的具体消息,发送端主机也就可以了解此次发送不可达的具体原因。

举例6种常见的目标不可达类型的代码:

  • 网络不可达代码为0
  • 主机不可达代码为1
  • 协议不可达代码为2
  • 端口不可达代码为3
  • 需要进行分片但设置了不分片位代码为4

为了给大家说清楚上面的目标不可达的原因,牺牲自己给大家送5次外卖。

为什么要送外卖?别问,问就是为28岁的我做准备……

  1. 网络不可达代码为0
    外卖版本:
    第一次送外卖时,小区里只有A和B区两栋楼,但送餐地址写的是C区楼,表示头上很多问号,压根就没这个地方。
    正常版本:
    IP地址是分为网络号和主机号的,所以当路由器中的路由器表匹配不到接收方IP的网络号,就通过ICMP协议以网络不可达(Network Unreachable)的原因告知主机。
    自从不再有网络分类以后,网络不可达也渐渐不再使用了。

  2. 主机不可达代码为1
    外卖版本:
    第二次送外卖时,这次小区有5层楼高的C区楼了,找到地方了,但送餐地址写的是C区楼601号房,说明找不到这个房间。
    正常版本:
    当路由表中没有该主机的信息,或者该主机没有连接到网络,那么会通过ICMP协议以主机不可达(Host Unreachable)的原因告知主机。

  3. 协议不可达代码为2
    外卖版本:
    第三次送外卖时,这次小区有C区楼,也有601号房,找到地方了,也找到房间了,但是一开门人家是外国人说的是英语,我说的是中文!语言不通,外卖送达失败~
    正常版本:
    当主机使用TCP协议访问对端主机时,能找到对端的主机了,可是对端主机的防火墙已经禁止TCP协议访问,那么会通过ICMP协议以协议不可达的原因告知主机。

  4. 端口不可达代码为3
    外卖版本:
    第四次送外卖时,这次小区有C区楼,也有601号房,找到地方了,也找到房间了,房间里的人也是说中文的人了,但是人家说他要的不是外卖,而是快递……
    正常版本:
    当主机访问对端主机8080端口时,这次能找到对端主机了,防火墙也没有限制,可是发现对端主机没有进程监听8080端口,那么会通过ICMP协议以端口不可达的原因告知主机。

  5. 需要进行分片但设置了不分片位代码为4
    外卖版本:
    第五次送外卖时,这次是个吃播博主点了100份外卖,但是吃播博主要求一次性要把全部外卖送达,装不下呀,这样就没办法送达了。
    正常版本:
    发送端主机发送IP数据报时,将IP首部的分片禁止标志位设置为1。根据这个标志位,途中的路由器遇到超过MTU大小的数据包时,不会进行分片,而是直接抛弃。
    随后,通过一个ICMP的不可达消息类型,代码为4的报文,告知发送端主机。

原点抑制消息(ICMP Source Quench Message)——类型4
在使用低速广域线路的情况下,连接WAN的路由器可能会遇到网络拥堵的问题。
ICMP原点抑制消息的目的就是为了缓和这种拥堵情况。
当路由器向低速线路发送数据时,其发送队列的缓存变为零而无法发送出去时,可以向IP包的源地址发送一个ICMP原点抑制消息。
收到这个消息的主机借此了解在整个线路的某一处发生了拥堵的情况,从而增大IP包的传输间隔,减少网络拥堵的情况。
然而,由于这种ICMP可能引起不公平的网络通信,一般不被使用。

重定向消息(ICMP Redirect Message)——类型5
如果路由器发现发送端主机使用了「不是最优」的路径发送数据,那么它会返回一个ICMP重定向消息给这个主机。
在这个消息中包含了最合适的路由信息和源数据。这主要发生在路由器持有更好的路由信息的情况下。路由器会通过这样的ICMP消息告知发送端,让它下次发给另外一个路由器。
好比,本可以过条马路就能到的地方,但不知道,所以绕了一圈才到,后面知道后,下次就不会那么傻再绕一圈了。

超时消息(ICMP Time Exceeded Message)——类型11
IP包中有一个字段叫做TTL(Time To Live,生存周期),它的值随着每经过一次路由器就会减1,直到减到0时该IP包会被丢弃。
此时,路由器将会发送一个ICMP超时消息给发送端主机,并通知该包已被丢弃。
设置IP包生存周期的主要目的,是为了在路由控制遇到问题发生循环状况时,避免IP包无休止地在网络上被转发。

此外,有时可以用TTL控制包的到达范围,例如设置一个较小的TTL值。

ping——查询报文类型的使用

接下来,我们重点来看ping的发送和接收过程。
同个子网下的主机A和主机B,主机A执行ping主机B后,我们来看看其间发送了什么?
ping命令执行的时候,源主机首先会构建一个ICMP回送请求消息数据包。
ICMP数据包内包含多个字段,最重要的是两个:

  • 第一个是类型,对于回送请求消息而言该字段为8;
  • 另外一个是序号,主要用于区分连续ping的时候发出的多个数据包。
    每发出一个请求数据包,序号会自动加1。为了能够计算往返时间RTT,它会在报文的数据部分插入发送时间。

然后,由ICMP协议将这个数据包连同地址192.168.1.2一起交给IP层。IP层将以192.168.1.2作为目的地址,本机IP地址作为源地址,协议字段设置为1表示是ICMP协议,再加上一些其他控制信息,构建一个IP数据包。

接下来,需要加入MAC头。如果在本地ARP映射表中查找出IP地址192.168.1.2所对应的MAC地址,则可以直接使用;如果没有,则需要发送ARP协议查询MAC地址,获得MAC地址后,由数据链路层构建一个数据帧,目的地址是IP层传过来的MAC地址,源地址则是本机的MAC地址;还要附加上一些控制信息,依据以太网的介质访问规则,将它们传送出去。

主机B收到这个数据帧后,先检查它的目的MAC地址,并和本机的MAC地址对比,如符合,则接收,否则就丢弃。
接收后检查该数据帧,将IP数据包从帧中提取出来,交给本机的IP层。同样,IP层检查后,将有用的信息提取后交给ICMP协议。

主机B会构建一个ICMP回送响应消息数据包,回送响应数据包的类型字段为0,序号为接收到的请求数据包中的序号,然后再发送出去给主机A。

在规定的时候间内,源主机如果没有接到ICMP的应答包,则说明目标主机不可达;如果接收到了ICMP回送响应消息,则说明目标主机可达。
此时,源主机会检查,用当前时刻减去该数据包最初从源主机上发出的时刻,就是ICMP数据包的时间延迟。

针对上面发送的事情,总结成了如下图:

当然这只是最简单的,同一个局域网里面的情况。如果跨网段的话,还会涉及网关的转发、路由器的转发等等。
但是对于ICMP的头来讲,是没什么影响的。会影响的是根据目标IP地址,选择路由的下一跳,还有每经过一个路由器到达一个新的局域网,需要换MAC头里面的MAC地址。

说了这么多,可以看出ping这个程序是使用了ICMP里面的ECHO REQUEST(类型为8)和ECHO REPLY(类型为0)。

traceroute——差错报文类型的使用

有一款充分利用ICMP差错报文类型的应用叫做traceroute(在UNIX、MacOS中是这个命令,而在Windows中对等的命令叫做tracert)。

  1. traceroute作用一
    traceroute的第一个作用就是故意设置特殊的TTL,来追踪去往目的地时沿途经过的路由器。
    traceroute的参数指向某个目的IP地址:
traceroute 192.168.1.100

这个作用是如何工作的呢?
它的原理就是利用IP包的生存期限从1开始按照顺序递增的同时发送UDP包,强制接收ICMP超时消息的一种方法。
比如,将TTL设置为1,则遇到第一个路由器,就牺牲了,接着返回ICMP差错报文网络包,类型是时间超时。
接下来将TTL设置为2,第一个路由器过了,遇到第二个路由器也牺牲了,也同时返回了ICMP差错报文数据包,如此往复,直到到达目的主机。
这样的过程,traceroute就可以拿到了所有的路由器IP。
当然有的路由器根本就不会返回这个ICMP,所以对于有的公网地址,是看不到中间经过的路由的。

发送方如何知道发出的UDP包是否到达了目的主机呢?
traceroute在发送UDP包时,会填入一个不可能的端口号值作为UDP目标端口号:33434。然后对于每个下一个探针,它都会增加一个,这些端口都是通常认为不会被使用,不过,没有人知道当某些应用程序监听此类端口时会发生什么。
当目的主机,收到UDP包后,会返回ICMP差错报文消息,但这个差错报文消息的类型是「端口不可达」。
所以,当差错报文类型是端口不可达时,说明发送方发出的UDP包到达了目的主机。

  1. traceroute作用二
    traceroute还有一个作用是故意设置不分片,从而确定路径的MTU。
    这么做是为了什么?
    这样做的目的是为了路径MTU发现。
    因为有的时候我们并不知道路由器的MTU大小,以太网的数据链路上的MTU通常是1500字节,但是非以太网的MTU值就不一样了,所以我们要知道MTU的大小,从而控制发送的包大小。

它的工作原理如下:
首先在发送端主机发送IP数据报时,将IP包首部的分片禁止标志位设置为1。根据这个标志位,途中的路由器不会对大数据包进行分片,而是将包丢弃。
随后,通过一个ICMP的不可达消息将数据链路上MTU的值一起给发送主机,不可达消息的类型为「需要进行分片但设置了不分片位」。
发送主机端每次收到ICMP差错报文时就减少包的大小,以此来定位一个合适的MTU值,以便能到达目标主机。

参考资料:
[1]竹下隆史.图解TCP/IP.人民邮电出版社.
[2]刘超.趣谈网络协议.极客时间.

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号