我想知道一个数据包从出发地到目的地所遵循的路由,即所有转发实体(中间的路由器)的 IP 地址。虽然不能保证所有数据包都走相同的路线,但通常都是一样的。路由信息非常有助于调试网络相关的问题。
此时使用 traceroute 工具能够输出数据包到特定目的地的完整路径。
traceroute 工具使用 IP 包头中的 TTL 字段来实现。而 TTL 字段表示数据包在网络中经过多少跳(中转)到达目的地。所以这就有效地描述了数据包在网络上的生命周期。这个字段通常设置为32或64。数据包每经过一个中间路由器,TTL 会减1。当某个路由器在接收到数据包后发现 TTL 值为1,这个数据包不会被转发而是被丢弃。
在丢包后,路由器丢包的同时也会对数据包来源发送一个 ICMP TTL Exceeded 的信息。这个被发回的 ICMP 包携带了此路由器的 IP 地址。
所以通过每次发送 TTL 值从1开始递增的数据包来实现路由追踪。每当一个路由器收到了数据包,例行检查 TTL 字段,如果 TTL 值为1就丢包并向源 IP 地址发送 ICMP 错误信息。traceroute 就这样逐步获取到起始地和目的地之间所有路由器的 IP。
traceroute [-dFlnrvx][-f<存活数值>][-g<网关>...][-i<网络界面>][-m<存活数值>][-p<通信端口>][-s<来源地址>][-t<服务类型>][-w<超时秒数>][主机名称或IP地址][数据包大小]
参数说明:
-d 使用Socket层级的排错功能。
-f<存活数值> 设置第一个检测数据包的存活数值TTL的大小。
-F 设置勿离断位。
-g<网关> 设置来源路由网关,最多可设置8个。
-i<网络界面> 使用指定的网络界面送出数据包。
-I 使用ICMP回应取代UDP资料信息。
-m<存活数值> 设置检测数据包的最大存活数值TTL的大小。
-n 直接使用IP地址而非主机名称。
-p<通信端口> 设置UDP传输协议的通信端口。
-r 忽略普通的Routing Table,直接将数据包送到远端主机上。
-s<来源地址> 设置本地主机送出数据包的IP地址。
-t<服务类型> 设置检测数据包的TOS数值。
-v 详细显示指令的执行过程。
-w<超时秒数> 设置等待远端主机回报的时间。
-x 开启或关闭数据包的正确性检验。
server-name 是目标名称或者 IP 地址。举个例子,使用 traceroute 来找出我的机器到 blog.crazytaxii.com 的网络路径:
$ traceroute SZH-C-005ME
traceroute to SZH-C-005ME (10.161.229.120), 30 hops max, 60 byte packets1 _gateway (10.0.2.2) 0.307 ms 0.304 ms 0.432 ms2 _gateway (10.0.2.2) 3.579 ms 3.402 ms 3.256 ms
每行提供了与中间路由器交互的详细信息,不仅有路由器的 IP 地址,还有此路由器的三个往返时间,因为 traceroute 命令每次发了三包数据。
有时候输出 *,表示无法获取所需的字段。可能是从反向 DNS 查询失败、没有命中目标路由器甚至在回程中丢包。虽然可能有多种失败原因,但是 traceroute 统统输出 *。
traceroute 提供选项 -n 来禁用 IP 地址与主机名映射。
$ traceroute -n SZH-C-005ME
traceroute to SZH-C-005ME (10.161.229.120), 30 hops max, 60 byte packets1 10.0.2.2 0.427 ms 1.134 ms 0.849 ms2 10.0.2.2 3.505 ms 3.358 ms 3.214 ms
然后我们在输出中就看不到主机名了。
还可以配置 traceroute 工具在发包后的等待时间,-w 选项带上值。下面例子中,等待时间设置为1秒。
$ traceroute -w 1 SZH-C-005ME
traceroute to SZH-C-005ME (10.161.229.120), 30 hops max, 60 byte packets1 _gateway (10.0.2.2) 0.374 ms 0.175 ms 0.312 ms2 _gateway (10.0.2.2) 3.355 ms 3.203 ms 3.050 ms
traceroute 工具默认每跳发送3包数据来得到3次来回时间。选项 -q 需要带上整数。
$ traceroute -q 5 SZH-C-005ME
traceroute to SZH-C-005ME (10.161.229.120), 30 hops max, 60 byte packets1 _gateway (10.0.2.2) 0.421 ms 0.290 ms 0.299 ms 0.293 ms 0.287 ms2 _gateway (10.0.2.2) 3.432 ms 3.279 ms 3.130 ms 2.880 ms 2.731 ms
traceroute 可以根据用户的需求灵活改变初始 TTL 值。默认为1意味着从第一个路由器就开始,使用 -f 选项来设置一个自定义的值。
$ traceroute -f 2 szh-c-005me
traceroute to szh-c-005me (10.161.229.120), 30 hops max, 60 byte packets2 _gateway (10.0.2.2) 3.404 ms 3.108 ms 2.956 ms
看到相比于之前的输出少了第一跳 10.0.2.2,也就是从第二跳开始抓取。