在诊断与其他网络主机的连接问题时,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 |
图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 1117:07:07.799 Rcvd IP Ver/HL 45, ToS c0, Len 38, ID 4a39, Flg/Frg 0, TTL 80, Prtl 1 |
图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 |
图3 – 追踪路由输出
您可能会认为随着TTL值增加,延迟时间也会随之增长,这种情况通常成立,但并非绝对。请比较图3中第6跳(79毫秒)与第5跳(80毫秒)的第三次报告时间。这种现象存在多个原因:首先,网络行为具有非确定性,有时延迟确实会自然延长。 其次,N-1跳路由器的负载可能高于N跳路由器,导致其发送ICMP消息的响应延迟。最后,从N跳路由器返回的路径可能比从N-1跳路由器返回的路径更快。例如,第四跳路由器并无必须通过第三、第二、第一跳路由器将响应传回源节点的限制,它可能直接将响应发往第一跳路由器,这种路径可能显著更快。 这意味着:虽然traceroute能精确报告数据包从发送主机到目标主机的路径,但无法保证目标主机发回的数据包会沿相同路径逆向传输。这种现象称为非对称路由。
Traceroute 可能会在时间戳后附加一个标志,表示其接收到的信息并非预期的超时消息。这些标志包括:
!H – 主机不可达
!N – 网络不可达
!P – 协议不可达
!N – 网络不可达
!P – 协议不可达
例如,图4显示第一个路由器不知道如何到达目标网络,因此它返回网络不可达消息,traceroute在该点终止。
traceroute EEE.FFF.GGG.HHH -numeric |
图4 网络不可达消息
星号(*)代替时间值表示traceroute未收到响应。如前所述,这可能是路由器未发送ICMP超时消息,也可能是防火墙在返回途中拦截了超时消息,或是防火墙阻断了外发消息。此外,网络也可能丢弃了外发或返回的消息。
单次甚至两次超时(如图5所示)通常表明:路由器因繁忙未发送消息,或网络丢包(或两者兼有)。请注意图5中的第8跳:IP地址前的星号表示该组消息的首条超时。
traceroute to EEE.FFF.GGG.HHH (EEE.FFF.GGG.HHH), 30 hops max, 40 byte packetsready 14:43:16 |
图5 – 路由器繁忙或数据包丢失
如果三个消息都超时,但后续跳点报告了时间(图6),则很可能是该跳点的路由器根本不发送ICMP超时消息。
traceroute to EEE.FFF.GGG.HHH (EEE.FFF.GGG.HHH), 30 hops max, 40 byte packetsready 14:47:01 |
图6 – 无响应路由器
如果所有经过某一点的跳数都超时(图7),则很可能存在防火墙阻塞了外发或返回的消息。
traceroute to EEE.FFF.GGG.HHH (EEE.FFF.GGG.HHH), 30 hops max, 40 byte packets |
图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 |
图8 – 目标未响应
对于同一跃点,也可能收到来自两个或多个路由器的响应(图9)。这种情况可能发生在路由器进行负载均衡时,或网络不稳定导致路由变化时,又或者如图9所示:路由器AAA.BBB.CC.KKK并非最优路由器,在将数据包转发至AAA.BBB.II.J后,它向源节点发送了重定向消息以更改其路由表。
traceroute EEE.FFF.GGG.HHH -numeric |
图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 |
Figure 10 - (edited) packet traces showing port number changes最后,除非第一跳存在问题,否则你可能无力解决该问题。 一旦STCP(或任何主机的网络堆栈)将数据包发送到本地路由器,该数据包便脱离了其(以及您的)控制范围。不过,若您能确定最后响应的跳点的IP地址,或突然开始出现超时的跳点位置,就能大致定位问题所在,进而联系相应的网络管理团队进行处理。
