针对第一个问题先说结论
windows的tracert是使用icmp来探路,linux的traceroute是使用udp探测,如果想达到和windows下一个效果,建议使用-I参数或mtr
下面是原理分析
tracert工具是我们常用的故障排查工具,它可以探测终端到目的主机间所经过的节点,但他的使用具有一定的局限性,单纯的通过tracert路径图并不足以完全判断出问题节点
首先来介绍下tracert的原理
假设源端节点为A 目的节点为E,AE之间的路径为A-B-C-D-E
当我们在终端输入tracert E时,我们的操作系统会发送一个目的地址为E的icmp request且TTL为1的数据包,数据包到达节点B,节点B回应TTL超时的ICMP差错消息,操作系统根据发出数据包与接收到数据包的时间来计算出该节点的时延,接着会继续发送一个TTL为2的数据包,节点A把TTL -1后转发给节点B,节点B会向源端回应ICMP差错消息(TTL超时),以此类推,直到收到目的节点E回复的ICMP replay消息
linux中的tracepath原理与tracert类型,只不过是把发送的ICMP request数据包更换成了UDP数据包,探测一个比较大的端口,直到目的主机回应端口不可达为止
示例
源IP 10.0.64.20 目的IP 8.8.8.8 抓包看tracert过程
可以看到源IP10.0.64.20 到目的IP8.8.8.8 的icmp request数据包的TTL值是累加的,一直加到9才到达8.8.8.8,我们展开两个数据包来看一下
可以看到第一个ICMP request数据包的TTL封装为1
网关回应的time to live exceeded的icmp差错消息
以上我们已经掌握了tracert的原理,但是有时候我们会遇到一些非常规的tracert图,例如
也许有朋友会问,第3条有两个*号,是不是我到这个目的ip地址一直在丢包?还有朋友会问,为什么第5,6跳不显示节点ip啊,是网络异常吗?
其实我们通过上面学习到的原理可知tracert显示的每一个节点ip是给我们回复icmp ttl超时的节点,但是如果我们在网络设备上设置了针对ttl为1的报文进行直接丢弃不回复来节约设备资源呢?又或者数据包经过的这台设备上没有任何可以和互联网进行通信的公网ip地址呢,这时我们是得不到这些节点ip的,我们的操作系统在进行三次发包后无论有没有收到icmp差错消息都会把数据包的ttl加1再次发送
至于中间节点有两个*号,一个正常的时延这种情况大概率是因为网络设备对以icmp报文的速率进行了一定的限制,会丢弃一部分报文不做回应导致,通过我们对tracert原理的了解,中间节点的丢包并不代表我们到目的节点的网络存在问题
综上,tracert是一款很好用的故障排查工具,但他最大的用武之地在于探测源目节点间路由走向是否异常,是否发生as路径错误等故障,而不在于探测目的节点网络连通性
以驱魔为理想,为生计而奔波