Traceroute是一个常用的网络诊断工具下面是traceroute的部分输出
[root@localhost ~]# traceroute 218.104.71.170
traceroute to 218.104.71.170 (218.104.71.170), 30 hops max, 60 byte packets
1 gateway (192.168.122.1) 0.205 ms 0.145 ms 0.199 ms
2 192.168.9.1 (192.168.9.1) 6.657 ms 6.949 ms 6.890 ms
3 192.168.11.1 (192.168.11.1) 6.822 ms 6.712 ms 6.632 ms
4 192.168.1.2 (192.168.1.2) 6.531 ms 6.449 ms 6.328 ms
...
12 218.104.71.170 (218.104.71.170) 36.418 ms 41.499 ms 41.555 ms
上面输出可以看见从主机到218.104.71.170的数据包需要经过的所有设备信息和耗时。
不过traceroute如何工作的呢,答案很简单TTL(Time to live)
TTL
Time to live,用于限制数据包的传输次数和传输时间,数据包每经过一次路由器,TTL字段就会减1,如果在数据包到达目标主机之前这个字段已经变成0了,那这个数据包会被丢弃,然后路由器会发送一个ICMP(Internet Control Message Protocol)错误的数据包给源主机。
默认traceroute的最大为30跳,工作过程如下,首先TTL设置成1,这样当数据包到达第一个路由(假设中间不只1跳)后路由器发现TTL为1,发现这个数据包不应该再继续传输了,所以在获取源IP后将该数据包丢弃后,向源IP发送一个ICMP TTL exceeded messages,这样源IP的主机就知道第一跳设备的信息了,再TTL设置成2,3,4逐次增加直至数据到达目标主机,当到达目标主机时目标主机,目标主机此时会发送一个ICMP Destination/PORT Unreachable的message,traceroute收到后就不再继续发送数据包了。
tcpdump抓包分析
[root@localhost ~]# tcpdump -i eth0 -n '(icmp or udp)' -vvv
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
19:46:45.248359 IP (tos 0x0, ttl 1, id 60517, offset 0, flags [none], proto UDP (17), length 60)
192.168.122.128.44012 > 218.104.71.170.traceroute: [bad udp cksum 0x5d75 -> 0x7ed6!] UDP, length 32
19:46:45.248514 IP (tos 0xc0, ttl 64, id 5995, offset 0, flags [none], proto ICMP (1), length 88)
192.168.122.1 > 192.168.122.128: ICMP time exceeded in-transit, length 68
IP (tos 0x0, ttl 1, id 60517, offset 0, flags [none], proto UDP (17), length 60)
192.168.122.128.44012 > 218.104.71.170.traceroute: [bad udp cksum 0x5d75 -> 0x7ed6!] UDP, length 32
19:46:45.248642 IP (tos 0x0, ttl 1, id 60518, offset 0, flags [none], proto UDP (17), length 60)
192.168.122.128.50754 > 218.104.71.170.33435: [bad udp cksum 0x5d75 -> 0x647f!] UDP, length 32
19:46:45.248761 IP (tos 0xc0, ttl 64, id 5996, offset 0, flags [none], proto ICMP (1), length 88)
192.168.122.1 > 192.168.122.128: ICMP time exceeded in-transit, length 68
IP (tos 0x0, ttl 1, id 60518, offset 0, flags [none], proto UDP (17), length 60)
192.168.122.128.50754 > 218.104.71.170.33435: [bad udp cksum 0x5d75 -> 0x647f!] UDP, length 32
19:46:45.248779 IP (tos 0x0, ttl 1, id 60519, offset 0, flags [none], proto UDP (17), length 60)
192.168.122.128.49140 > 218.104.71.170.33436: [bad udp cksum 0x5d75 -> 0x6acc!] UDP, length 32
19:46:45.248844 IP (tos 0x0, ttl 2, id 60520, offset 0, flags [none], proto UDP (17), length 60)
192.168.122.128.35278 > 218.104.71.170.33437: [bad udp cksum 0x5d75 -> 0xa0f1!] UDP, length 32
19:46:45.248924 IP (tos 0xc0, ttl 64, id 5997, offset 0, flags [none], proto ICMP (1), length 88)
192.168.122.1 > 192.168.122.128: ICMP time exceeded in-transit, length 68
IP (tos 0x0, ttl 1, id 60519, offset 0, flags [none], proto UDP (17), length 60)
192.168.122.128.49140 > 218.104.71.170.33436: [bad udp cksum 0x5d75 -> 0x6acc!] UDP, length 32
19:46:45.248976 IP (tos 0x0, ttl 2, id 60521, offset 0, flags [none], proto UDP (17), length 60)
192.168.122.128.60725 > 218.104.71.170.33438: [bad udp cksum 0x5d75 -> 0x3d89!] UDP, length 32
19:46:45.249061 IP (tos 0x0, ttl 2, id 60522, offset 0, flags [none], proto UDP (17), length 60)
192.168.122.128.34555 > 218.104.71.170.33439: [bad udp cksum 0x5d75 -> 0xa3c2!] UDP, length 32
...
19:47:30.527454 IP (tos 0x0, ttl 53, id 1126, offset 0, flags [none], proto ICMP (1), length 88)
218.104.71.170 > 192.168.122.128: ICMP 218.104.71.170 udp port 33472 unreachable, length 68
首先你会注意到发送的数据包是UDP包(也可发TCP或者ICMP包),以及不管是TTL为1还是2都有三个包,其实发三个包的原因是为了获取UDP数据包到没一跳的平均时间。在这可以看见前面的ICMP回包都是ICMP time exceeded in-transit,而最后一个是ICMP 218.104.71.170 udp port 33472 unreachable。
可以看见最后一个包的TTL是53,那个是DNS的缓存,如果DNS服务器缓存中存在,并且未过期则直接使用缓存数据。
注意traceroute使用TCP包时不会建立tcp连接,traceroute会直接发送RST包中断连接。