01概览
对于ping
命令,我想大家都不会陌生。 当我们检查网络的时候,最先使用的肯定是ping命令。
一般我们使用ping
查看网络情况,主要是检查两个指标:
- 第一个看看是否超时
- 第二个看看是不是延迟过高
如果超时那么肯定是网络有问题(禁ping情况除外);如果延迟太高,网络情况肯定也是很糟糕的。
那么这篇博客就跟着ping
命令走一圈,看看ping是如何工作的。
02环境准备和抓包
- 环境准备
抓包工具: Wireshark 两台电脑进行互ping操作:
- A电脑(IP地址:
192.168.3.8
/ MAC地址:b0:fc:36:2b:45:c9
) - B电脑(IP地址:
192.168.3.47
/ MAC地址:bc;a8:a6:f3:7d:70
)
- 抓包操作
进行ping
操作,在A电脑上 ping B电脑的IP。
打开Wireshark,选取指定网卡进行抓包。
抓包情况如下:
这里先简单介绍一下Wireshark
的控制面板以方便对应图片。
这个面板包含7个字段:
NO
:编号Time
:包的时间戳Source
:源地址Destination
:目标地址Protocol
:协议Length
:包长度Info
:数据包附加信息
03深入理解
上图抓包编号 44745-44766
显示的就是整个ping
命令的过程(从who has 192.168.47? Tell 192.168.3.8 开始)。
我们知道ping
命令不是依托于TCP或者UDP这种传输层协议的,而是依托于ICMP协议实现的,那么什么是ICMP
协议呢?
- ICMP协议的产生背景
[RFC792]中说明了ICMP
的产生原因:由于互联网之间通讯会涉及很多网关和主机,为了能够报告数据错误,所以产生了ICMP协议 。也就是说ICMP协议是为了更高效的转发IP数据报和提高交付成功的机会。 - ICMP协议的数据格式
根据上图我们知道了ICMP协议头
包含了4个字节,头部主要用来类型和校验ICMP报文
。下图是对应的类型和代码释义列表,我们后面分析抓包时候会用到。
简单介绍完了ICMP
,那么在抓包中出现的ARP协议是什么呢?
我们再来简单介绍下ARP协议
:
-
ARP协议
我们知道,在一个局域网中,计算机通信实际上是依赖于MAC地址进行通信的,那么ARP的作用就是根据IP地址查找出对应的MAC地址。 -
ping过程解析
了解了上面的基础概念后,我们再来分析下抓包的数据,其流程如下:
- A电脑(192.168.3.8)发起 ping 请求,
ping 192.168.3.47
- A电脑广播发起
ARP
请求,查询192.168.3.47的MAC地址。 - B电脑应答
ARP
请求,向A电脑发起单向应答,告诉A电脑自己的MAC
地址为 b0:fc:36:2b:45:c9 - 知道了
MAC
地址后,开始进行真正的ping
请求,由于B电脑可以根据A电脑发送的请求知道 源 MAC 地址 ,所以就可以根据源MAC地址进行响应了。
我们发现,在 ping 4次请求和相应结束后,还有一次B电脑对A电脑的ARP请求,这是为什么呢?
我猜测应该有以下两个原因:
- 由于ARP有缓存机制,为了防止ARP过期,结束后重新更新下ARP缓存,保证下次请求能去正确的路径,如果ARP过期就会出现一次错误,从而影响测试准确性。
- 由于ping命令的响应时间是根据请求包和响应包的时间戳计算出来的,所以一次
ARP
的过程也是会消耗时间的。这里提前缓存最新的ARP结果就是节省了下次ping的ARP时间。
我们在第一次ping 192.168.3.47前先arp -a
看一下缓存的arp列表:
为了验证我们的猜测,我们再进行一次ping
的操作,抓包看看是否和我们猜测的一样。
此时,计算机里面已经有了ARP的缓存,我们此时执行arp -a
再看看缓存列表进行对比:
再来看看第二次 ping
的抓包:
我们在上图中在真正 ping 之前并没有进行一次ARP请求,这也就是说,直接拿了缓存中的ARP来执行了。
另外当 B计算机进行响应之前还是进行了一次 ARP请求,它还是要确认下之前的 ARP缓存是否为正确的。然后结束ping操作之后,同样再发一次 ARP请求,更新下自己的 ARP缓存。这里和我们的猜想基本一致。
弄懂了ping的流程之后我们再来解释下之前解释的ICMP数据结果是否和抓包的一致。
我们来点击一个ping request
看看ICMP协议详情
这里的Type=8,code=0
,校验是正确,且这是一个请求报文。
然后再根据 Response frame: 20397
,知道相应报文在序号 20397
根据上图的响应报文,Type=0,Code=0
,这里就知道是响应报文了
最后根据请求和和响应时间戳计算出来的相应延迟
849.62664ms - 849.59568ms = 0.03096ms
以上我们分析的是目标 IP 和本机使用的 IP 在同一子网
那么如果目标IP和本机 IP 不在同一个子网呢?
目标IP和本机 IP 不在同一个子网
先进行DNS解析将域名解析到IP然后再进行以下操作。
arp只是同一子网广播查询,如果目标IP不是同一子网的话,就要经过本IP网关进行转发。
- 如果本机没有缓存网关MAC,那么先发送一次arp查询网关的MAC,然后流程和上面一样,只不过是把ICMP包发到了网关。(MAC地址填写的是 网关的MAC)。
查看路由选择表route -n
:
运行一次ping www.okokme.cn
后的ARP缓存列表arp -a
:
- 可以得知,
网关
为 192.168.3.1 MAC地址为:90:94:97:10:fa:bd, (ping包头的MAC)。 - 真正目标 IP 的MAC地址当然不是这个,ICMP包先根据MAC地址路由到网关上。
- 网关接收到这个包后(因为MAC地址是它的),打开一看IP地址是148.70.124.59,不是自己的,于是继续查自己的
route
和ARP缓存
,发现下一个网关,于是把包的目的MAC地址改成下一个网关的MAC继续发出去。 - 下一个网关收到包后,如果查看目的IP是自己同一子网的
IP
,就ARP广播
找MAC
,找到就将包发送给该MAC
地址; 如果依然不是自己同一子网IP,继续重复上一步操作直到找到或TTL用尽结束。
整个过程中目标MAC地址每一跳都在改变,IP地址不变
每经过一次MAC变化可以理解为一跳,实际上可能要经过多个网关,多次跳跃才能真正到达目标机器。
目标机器收到这个ICMP包后的回复一样,具体参考上面,略过。