前两天遇到个事情,就是我刚刚做完了服务器的域名指向,但是同事访问不了该域名,我就喊他ping以下这个域名,ping不通,但是我在服务器上ping是通的,过一会儿他就可以访问并且ping通了。这时候就产生了一个问题,ping的工作原理是什么样的呀?它是怎么工作的?
一.ICMP协议
讲到ping,首先要讲下它的爸爸,也就是ICMP协议(ping是基于它工作的),ICMP是(Internet Control Message Protocol)Internet控制报文协议。 它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。
说起ICMP可能大家都比较陌生,接下来说明下它的主要功能:众所周知,咱们的网络环境是非常复杂的,那么当网络包在网络环境中传输的时候,总会遇到各式各样的问题。当遇到问题的时候,我们需要知道所遇到的问题具体是什么,这样才能够去针对问题去更换不同的策略。那么ICMP就是应用于采集传输过程中问题的。
需要注意的是,ICMP报文是封装在IP包中的,它是属于网络层的。
二.报文分类
ICMP报文有很多类型,不同类型的话有着不同的代码,常用的就是0和8,其中8是主动请求,0是主动应答。ICMP报文具体分为查询报文类型和差错报文类型,下面进行一下简单介绍。
1.查询报文类型
查询报文类型,顾名思义,就是主动发起的一种查询,例如ping 就是查询报文,是一种主动请求,并且获得主动应答是的ICMP协议。「注意,ping的话还在ICMP协议格式中加入了自己的格式,并不是与ICMP协议格式完全相同」。
对ping 的主动请求进行网络抓包,成为ICMP ECHO REQUEST,主动请求的应答被成为ICMP ECHO REPLY。相比于ICMP协议格式,它增加了两个自己的字段“标识符”和“序号”。标识符 是用来 标示去向区分的,判断包去干啥去哪,序号 是 发送包的识别编号,判断是哪个包。
2.差错报文类型
差错报文类型是在异常情况发生时,来报告发生错误的。ICMP差错报告报文只能报告差错,不能纠正差错,差错的纠正留给高层协议去做,它根据源IP地址将差错报告报文发送给IP数据报的源发送站点。它的结构较为复杂,将收到的需要进行差错报告IP数据报的首部和数据字段的前8个字节提取出来,作为ICMP报文的数据字段,再加上响应的ICMP差错报告报文的前8个字节。举几个例子:「代码3」终点不可达,「代码4」源抑制,「代码11」超时,「代码5」重定向。简单讲解下几个错误:
终点不可达,包含很多种情况,总体来说就是没办法和目标主机对接上。网络不可达:没找到地方;主机不可达:没找到对应主机;协议不可达;端口不可达;需要进行分片但是被禁用等。
源抑制,目标主机无法消化掉所有的数据,需要给更细的粒度或更大的时间区间进行传输。
超时,在规定的时间内,没有及时到达目标主机。
重定向,到达了,下次去走别的路由器线路。
三.该如何使用
说的再多原理,最终还是要归到使用上。
1.查询报文类型的使用:ping
下面就来讨论下ping在执行的过程中发生了什么,已内网间ping为例更简单的说明下过程。
ping在执行的时候,主机会去构建一个ICMP请求数据包,其中包含的多个字段中最重要的两个是“类型字段”和“顺序号”。类型字段 对于请求数据包而言为8;顺序号 主要区分连续 ping 的多个数据包,可以把它理解成自增id。为了计算往返时间RTT,它会在报文的数据部分插入发送时间。
然后ICMP协议将数据包连同本机的IP地址一起交给IP层进行处理,加入目标IP地址等信息构建IP数据包。
接下来需要加上MAC头,在局域网中通过ARP协议,找出目标地址对应的MAC地址,到达数据链路层构建数据帧,发送出去。
目标主机收到了数据帧之后,依次提取MAC,IP等信息,对比MAC信息,到IP层对比IP信息,提取数据交给ICMP协议,构建应答包,其中类型字段为 0 标示为应答包,顺序号为来时的顺序号,进行回包。
在规定时间内没有主机没有收到应答包就为主机不可到达;然后会算一下延迟,就是我们在打了ping命令后看到的时间time。

当然这是最简单的情况,出外网以后遇到的问题会更加的复杂。除了ping目标地址外,还应该知道一个包都经过了哪些路由设备,ttl跃点数为55,如果这些都是在控制范围内的话,可以通过tcpdump -i [网卡] icmp 查看有没有到达某个点,进一步进行排查。如果不在控制范围内的话,就要使用telnet通过其他协议进行测试网络是否通畅了。
2.差错报文类型的使用:traceroute
traceroute的主要作用是设置特说的ttl,进行追踪去往目的所经过的路由器。下面描述下工作过程:
当其指向某个地址的时候,他会发送一个UDP数据包,将ttl设置为1,一旦度过一个路由,他就结束了。
如果中间路由不止一个,就会返回ICMP网络差错包,类型是时间超时,那么就使 ttl 加 1进行尝试,循环往复直到达到目标主机。
这样就拿到了中间所度过的所有路由器的IP地址,当然有的路由器不会回这个ICMP,这也是traceroute的一个公网的地址,看不到中间路由的原因。不会产生ICMP的原因有很多情况,例如 ICMP的差错报文出错;目的地址为广播地址活着源地址不唯一的时候等都会产生不回包的情况。
注意这里判断UDP是否到达目标主机的方式,它发送一个指定端口号大于30000的一个包,使目的主机回产生一个“端口不可到达”的错误。
总结下:
1.ICMP分为 查询报文和差错报文。
2.查询报文主要应用:ping
3.差错报文主要应用:traceroute
网友评论