跳转至主要内容
在诊断与其他网络主机的连接问题时,Traceroute 工具堪称不可或缺。但要有效使用它,必须理解其工作原理以及输出结果的含义。

 

Traceroute通过操作IP头中的生存时间(TTL)值实现工作(图1)。 由于示例需Stratus 网络,我在数据包追踪记录中将IP地址的十六进制表示用X标记,并将所有点分十进制表示的八位字节转换为A至W的字母代码。字母数量代表字节位数:AAA表示三位数,J表示一位数。

 

Xmit IP Ver/HL 45, ToS 0, Len 5c, ID 5447, Flg/Frg 0, TTL 3c, Prtl 1
Cksum e90c, Src XXXXXXXX, Dst XXXXXXXX
ICMP from AAA.BBB.CC.DDD to EEE.FFF.GGG.HHH echo
图1 – 带TTL高亮显示的packet_monitor帧
每个处理数据包的路由器都会将TTL值减1,若TTL值大于0则将数据包转发至下一跳路由器或最终目的地。当TTL值为0时,路由器会丢弃该数据包,并*可能*向发送方回传ICMP超时消息。关键在于"可能"——部分路由器不会回传超时消息,或仅在非繁忙状态下执行此操作。 此外,某些防火墙会拦截ICMP消息,因此即使路由器发送了超时消息,运行traceroute的主机也可能永远无法接收该消息。
Traceroute首先向目标目的地发送一条TTL值为1的消息。它记录从发送消息到收到响应所需的时间。

 

17:07:07.797 Xmit IP Ver/HL 45, ToS 0, Len 28, ID 1, Flg/Frg 0, TTL 1, Prtl 11
Cksum 78CC, Src XXXXXXXX, Dst XXXXXXXX
UDP from AAA.BBB.CC.DDD.34611 to EEE.FFF.GGG.HHH.33435 Cksum 0000, 20 data bytes.
17:07:07.799 Rcvd IP Ver/HL 45, ToS c0, Len 38, ID 4a39, Flg/Frg 0, TTL 80, Prtl 1
Cksum 0d1a, Src aXXXXXXXX, Dst XXXXXXXX
ICMP from AAA.BBB.II.J to AAA.BBB.CC.DDD time excdd

 

图2 – packet_monitor 跟踪路由帧与响应
默认情况下,traceroute命令会发送三个TTL值为1的消息,并报告所有三次响应时间以及发送回复的路由器名称和/或IP地址。我始终使用-numeric参数,这样就不必等待域名解析(图3)。 随后 traceroute 会将 TTL 值递增 1 并重复操作。该过程将持续递增 TTL 值,直至收到目标地址的响应或达到默认上限 30 次。所有 traceroute 参数的详细说明可参阅《OpenVOS STREAMS TCP/IP 管理员指南》(R419) 手册

 

traceroute -numeric EEE.FFF.GGG.HHH
traceroute to EEE.FFF.GGG.HHH (EEE.FFF.GGG.HHH), 30 hops max, 40 byte packets
1 AAA.BBB.II.LLL 2 ms 1 ms 1 ms
2 AAA.BBB.II.J 1 ms 1 ms 1 ms
3 AAA.BBB.MM.NN 12 ms 5 ms 6 ms
4 BBB.OOO.PPP.QQQ 76 ms 76 ms 76 ms
5 BBB.RRR.SSS.TTT 80 ms 80 ms 80 ms
6 BBB.RRR.SSS.UUU 87 ms 82 ms 79 ms
7 EEE.FFF.V.J 89 ms 89 ms 86 ms
8 EEE.FFF.GGG.HHH 82 ms 87 ms 80 ms
ready 15:19:12

 

图3 – 追踪路由输出
您可能会认为随着TTL值增加,延迟时间也会随之增长,这种情况通常成立,但并非绝对。请比较图3中第6跳(79毫秒)与第5跳(80毫秒)的第三次报告时间。这种现象存在多个原因:首先,网络行为具有非确定性,有时延迟确实会自然延长。 其次,N-1跳路由器的负载可能高于N跳路由器,导致其发送ICMP消息的响应延迟。最后,从N跳路由器返回的路径可能比从N-1跳路由器返回的路径更快。例如,第四跳路由器并无必须通过第三、第二、第一跳路由器将响应传回源节点的限制,它可能直接将响应发往第一跳路由器,这种路径可能显著更快。 这意味着:虽然traceroute能精确报告数据包从发送主机到目标主机的路径,但无法保证目标主机发回的数据包会沿相同路径逆向传输。这种现象称为非对称路由。

 

Traceroute 可能会在时间戳后附加一个标志,表示其接收到的信息并非预期的超时消息。这些标志包括:
!H – 主机不可达
!N – 网络不可达
!P – 协议不可达
例如,图4显示第一个路由器不知道如何到达目标网络,因此它返回网络不可达消息,traceroute在该点终止。

 

traceroute EEE.FFF.GGG.HHH -numeric
traceroute to EEE.FFF.GGG.HHH (EEE.FFF.GGG.HHH), 30 hops max, 40 byte packets
1 AAA.BBB.CC.KKK 2 ms !N 0 ms !N 1 ms !N
ready 15:40:03

 

图4 网络不可达消息
星号(*)代替时间值表示traceroute未收到响应。如前所述,这可能是路由器未发送ICMP超时消息,也可能是防火墙在返回途中拦截了超时消息,或是防火墙阻断了外发消息。此外,网络也可能丢弃了外发或返回的消息。

 

单次甚至两次超时(如图5所示)通常表明:路由器因繁忙未发送消息,或网络丢包(或两者兼有)。请注意图5中的第8跳:IP地址前的星号表示该组消息的首条超时。

 

traceroute to EEE.FFF.GGG.HHH (EEE.FFF.GGG.HHH), 30 hops max, 40 byte packets
1 AAA.BBB.II.LLL 1 ms 0 ms *
2 AAA.BBB.II.J 1 ms 1 ms 1 ms
3 AAA.BBB.MM.NN 1 ms * 1 ms
4 BBB.OOO.PPP.QQQ 7 ms 8 ms 8 ms
5 BBB.RRR.SSS.TTT 76 ms 76 ms 75 ms
6 BBB.RRR.SSS.UUU 79 ms 77 ms 77 ms
7 EEE.FFF.V.J 79 ms * *
8 * EEE.FFF.W.253 79 ms 79 ms
9 EEE.FFF.GGG.HHH 80 ms 80 ms 80 ms
ready 14:43:16

 

图5 – 路由器繁忙或数据包丢失
如果三个消息都超时,但后续跳点报告了时间(图6),则很可能是该跳点的路由器根本不发送ICMP超时消息。

 

traceroute to EEE.FFF.GGG.HHH (EEE.FFF.GGG.HHH), 30 hops max, 40 byte packets
1 AAA.BBB.II.LLL 1 ms 0 ms 1 ms
2 AAA.BBB.II.J 1 ms 1 ms 1 ms
3 AAA.BBB.MM.NN 1 ms 1 ms 1 ms
4 BBB.OOO.PPP.QQQ 7 ms 8 ms 8 ms
5 BBB.RRR.SSS.TTT 76 ms 76 ms 75 ms
6 BBB.RRR.SSS.UUU 79 ms 77 ms 77 ms
7 * * *
8 * * *
9 EEE.FFF.GGG.HHH 80 ms 80 ms 80 ms
ready 14:47:01

 

图6 – 无响应路由器
如果所有经过某一点的跳数都超时(图7),则很可能存在防火墙阻塞了外发或返回的消息。

 

traceroute to EEE.FFF.GGG.HHH (EEE.FFF.GGG.HHH), 30 hops max, 40 byte packets
1 AAA.BBB.II.LLL 1 ms 0 ms 0 ms
2 AAA.BBB.II.J 1 ms 1 ms 1 ms
3 AAA.BBB.MM.NN 1 ms 1 ms 1 ms
4 BBB.OOO.PPP.QQQ 7 ms 6 ms 8 ms
5 * * *
6 * * *
7 * * *
8 * * *
. . . .
29 * * *
30 * * *
ready 14:51:05

 

图7 – 防火墙阻断
还有另一个原因会导致超过一定时间后所有操作超时,那就是目标未响应。并非所有目标都会响应,此时会出现类似图8的情况。图7与图8的区别在于:图8中最后发送响应的路由器是目标所在的本地路由器。如何判断这种情况? 有时地址结构能直接揭示:例如目标地址为192.168.1.12,而最后响应的路由器是192.168.1.1。但在图9中情况就复杂了——EEE.FFF.W.XXX可能是位于EEE.FFF.GGG.HHH之前的最后路由器,因为它们共享前16位地址。 但若不了解目标网络采用的子网划分方案,除非主动询问,否则无法确定。

 

traceroute to EEE.FFF.GGG.HHH (EEE.FFF.GGG.HHH), 30 hops max, 40 byte packets
1 AAA.BBB.II.LLL 1 ms * 0 ms
2 AAA.BBB.II.J 1 ms 1 ms 1 ms
3 AAA.BBB.MM.NN 1 ms 1 ms 0 ms
4 BBB.OOO.PPP.QQQ 10 ms 7 ms 6 ms
5 BBB.RRR.SSS.TTT 77 ms 76 ms 75 ms
6 BBB.RRR.SSS.UUU 79 ms 80 ms 81 ms
7 EEE.FFF.V.J 82 ms 78 ms 79 ms
8 EEE.FFF.W.XXX 78 ms 95 ms 77 ms
9 * * *
. . . .
29 * * *
30 * * *
ready 15:00:20

 

图8 – 目标未响应
对于同一跃点,也可能收到来自两个或多个路由器的响应(图9)。这种情况可能发生在路由器进行负载均衡时,或网络不稳定导致路由变化时,又或者如图9所示:路由器AAA.BBB.CC.KKK并非最优路由器,在将数据包转发至AAA.BBB.II.J后,它向源节点发送了重定向消息以更改其路由表。

 

traceroute EEE.FFF.GGG.HHH -numeric
traceroute to EEE.FFF.GGG.HHH (EEE.FFF.GGG.HHH), 30 hops max, 40 byte packets
1 AAA.BBB.CC.KKK 7 ms 1 ms 0 ms
2 AAA.BBB.II.J 1 ms AAA.BBB.MM.NN 1 ms 1 ms
3 BBB.OOO.PPP.QQQ 9 ms 8 ms 8 ms
4 BBB.RRR.SSS.TTT 81 ms 81 ms 77 ms
5 BBB.RRR.SSS.UUU 80 ms 79 ms 78 ms
6 EEE.FFF.V.J 81 ms 77 ms 77 ms
7 EEE.FFF.W.253 78 ms 80 ms 80 ms
8 EEE.FFF.GGG.HHH 84 ms 83 ms 80 ms
ready 15:47:51

 

图9 – 同一跳的两个响应
根据发送消息的类型,路由追踪命令可分为两类。某些路由追踪工具(如微软Windows系统中的工具)发送ICMP回显请求(ping)消息;而另一些工具(如在STCP环境下运行的工具)则发送UDP消息。若需配置防火墙放行数据包或编写协议分析器过滤器,明确所用路由追踪工具的类型至关重要。此外,目标设备的响应方式也会有所不同。 若目标接收的是ping请求,则会返回ping应答;若接收的是UDP消息,则响应取决于端口号。若端口正在使用中,监听应用程序很可能会丢弃该数据包,因为其不符合应用程序的消息结构要求。若端口未被占用,主机*可能*会返回ICMP目标端口不可达消息。因此traceroute通常选择未被占用的端口进行测试。

 

目标主机所见端口号取决于到达目标所需的中间跳数。Traceroute默认从33435端口开始,每发送一条消息递增端口号(图10)。因此目标主机会看到3个不同端口,但这三个端口未必都处于使用状态。源端口则基于发送进程的进程ID。 特定进程始终使用相同的源端口。

 

dir len proto source destination src port dst port
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33435
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33436
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33437
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33438
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33439
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33440
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33441
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33442
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33443
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33444
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33445
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33446
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33447
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33448
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33449
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33450
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33451
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33452
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33453
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33454
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33455
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33456
R 28 ICMP EEE.FFF.GGG.HHH AAA.BBB.CC.DDD unreach
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33457
R 28 ICMP EEE.FFF.GGG.HHH AAA.BBB.CC.DDD unreach
T 40 UDP AAA.BBB.CC.DDD EEE.FFF.GGG.HHH 34737 33458
R 28 ICMP EEE.FFF.GGG.HHH AAA.BBB.CC.DDD unreach

 

Figure 10 - (edited) packet traces showing port number changes
最后,除非第一跳存在问题,否则你可能无力解决该问题。 一旦STCP(或任何主机的网络堆栈)将数据包发送到本地路由器,该数据包便脱离了其(以及您的)控制范围。不过,若您能确定最后响应的跳点的IP地址,或突然开始出现超时的跳点位置,就能大致定位问题所在,进而联系相应的网络管理团队进行处理。