Ping
ping 程序的主要目的是测试主机是否可达,它发送 ICMP 回显请求报文给目的主机,返回 ICMP 回显应答。
工作机制
ping 程序一般会周期性持续地发送 ICMP 请求报文,除非用户手动终止,或指定了发包个数,回显请求和回显应答通过序列号(icmp_seq)进行匹配,下图中序列号依次为 1、2、..
ping 程序通过数据报中记录的发送请求时间值和接收到回显应答报文的当前时间值,计算往返耗时(time)
为什么 ping 第一次一般会产生更多耗时:
因为 ping 第一次的时候,需要首先进行 ARP 解析,获取 IP 地址对应的 MAC 地址(同时将映射关系缓存),
而下次 ping 的时候会直接从 ARP 高速缓存读取,少了一个步骤,自然时间就缩短了。
ping报文
Request的报文类型为8。
Reply的类型为0。
通过具体的ping报文可以看到ping报文的大小为84字节。其中ICMP报文56个字节,再加上20个字节的IP首部和8个字节的ICMP首部。因此IP报文的总长度为84字节。
可以改变ICMP的报文大小,通过-s命令, 将ICMP报文大小设置为32字节。加上20字节的IP首部以及8字节的ICMP首部,总共60个字节。
Ping程序中还可以通过设置ping的次数,通过-c。在ping了3次以后,ping程序自动停止。
IP记录路由选项
ping程序还可以记录所经过路径的IP地址。这个通过-R的方法来实现。Ping程序在发送出去的IP数据报中设置IP RR选项。这样每个处理该数据报的路由器都把它的IP地址放入选项字段中。当数据包达到目的端时,IP地址清单就复制到ICMP回显应答中。当ping程序收到回显应答时,它就打印出这份IP地址清单。
弊端:
由于IP首部中的首部长度字段只有4bit,因此IP首部最长只能包含15个32bit的字=60字节。IP首部为20个字节。RR选项用去3个字节。这样只剩下37个字节来存放IP地址清单,一个IP地址为4个字节,因此最大也就只能存放9个IP地址。在当前的互联网场景下,9个IP地址太少了。一般情况下都满足不了要求。
Traceroute
前面讲到IP可以记录路由选项。但是IP首部中留给选项空间有限,不可能存放太多的路径,最多只能存放9个地址,对于现在的网络来说远远不够,那么如果我们想探究网络路径可以用traceroute命令。
工作机制
通过封装一份 UDP 数据报(指定一个不可能使用的端口,30000以上),依次将数据报的 TTL 值置为 1、2、3…,并发送给目的主机。
- 当路径上第一个路由器收到 TTL 值为 1 的数据报时,首先将该数据报的 TTL 值减 1,发现 TTL 值为 0,而自己并非该数据报的目的主机,就会向源主机发送一个 ICMP 超时报文,traceroute 收到该超时报文,就得到了路径上第一台路由器的地址;
- 然后照此原理,traceroute 发送 TTL 为 2 的数据报时,会收到路径上第二台路由器返回的 ICMP 超时报文,记录第二台路由器的地址;
- 直到报文到达目的主机,目的主机不会返回 ICMP 超时,但由于端口无法使用,就会返回一份端口不可达报文给源主机,源主机收到端口不可达报文,证明数据报已经到达了目的地,停止后续的 UDP 数据报发送,将记录的路径依次打印出来,使命完成,结束任务。
实现方式
Windows下使用的是ICMP报文,而linux下使用的是UDP报文。
首先来看windows的报文。从报文中可以看出ttl不断的在增长。
而且主机发出的报文全都是ICMP报文。
Linux下的报文可以看到主机发出的报文都是UDP报文,而且每个报文都带有一个目的端口,端口每次都在增长。
带的是一个UDP报文,而非ICMP报文
但是从对端反馈回的报文都是ICMP报文。且最终目的地址反馈一个port unreachable的报文。这个端口不可达的报文在windows系统中并没有找到。
从上面的报文对比可以看到windows下和linux下的traceroute报文是不一样的。Windows下是纯粹使用ICMP报文。直到找到目的地址,并记录经过的路径。
而linux下是发出一个UDP报文。且同样也设置TTL时长,但选择一个不可能的值作为UDP端口(大于30000),使目的主机的任何一个应用程序都不可能使用这个端口。最终目的主机会产生一份端口不可达的错误。此时就判断结束。具体流程参考下图
命令输出解析
记录按序列号从1开始,每个纪录就是一跳 ,每跳表示一个网关,我们看到每行有三个时间,单位是 ms,其实就是-q的默认参数。探测数据包向每个网关发送三个数据包后,网关响应后返回的时间;如果您用 traceroute -q 4 www.123.com ,表示向每个网关发送4个数据包。
traceroute约束与缺陷
约束:
- 不能保证现在的路由也是将来所要采用的路由,甚至两份连续的 IP 数据报都可能采用不同的路由;
- 不能保证 ICMP 报文的路由与 traceoute 程序发送的 UDP 数据报采用同一路由,时间测量可能不准;
- 返回的 ICMP 报文中的信源 IP 地址是 UDP 数据报到达的路由器接口的 IP 地址;
当从网络1某主机执行 traceroute 程序到网络3某主机,返回的路径将是 if1 和 if3 的地址;而反方向,将打印出 if4 和 if2 的地址。
缺陷:
- 中间路由器有可能做了限制,不返回 ICMP 超时报文,traceroute 就无法获得其地址了,只能打印出 * 或 no reply
- 目的主机可能由于安全原因不会向源主机返回端口不可达的 ICMP 报文,尽管探测数据报已经到达了目的主机,但 traceroute 程序收不到端口不可达报文,就仍会持续发送请求 …
适用场景
如果在局域网中的不同网段之间,我们可以通过traceroute 来排查问题所在,是主机的问题还是网关的问题。