我发现了windows的tracert命令的一个bug---ICMP重定向包详尽分析

hi朋友,如果你的好奇心没有因繁杂的生活而被消磨,如果你喜欢对计算机进行追根究底的研究,那么欢迎与我一起,进行一趟说走就走的ICMP协议底层之旅。

先把ICMP包结构贴在这里:

我们研究的是差错报告报文的类型5,也就是ICMP"重定向"报文,它有2个作用:对网络重定向,对主机重定向。

要理解这个报文的作用,先画出一张拓扑图:

实验是PC1 ping PC3,由于PC1的默认网关是路由器R1的f0/0口,所以数据包的流向是:PC1→R1→R6→PC3。

但很明显,R1的转发多此一举,PC1把数据包直接发给路由器R6的f0/0口即可。

所以R1会给PC1发出一个ICMP错误报文,本例是type=5,code=0,意为网络重定向,即告诉PC1:去往192.168.7.0/24这个网络(路由器有路由表),网关应该是192.168.0.4,wireshark抓包如下:

PC1收到后会更新路由表,下一跳指向192.168.0.4的MAC地址,数据包转由R6转发。

那么接下来就做实验。先运行wf.msc关闭防火墙,因为防火墙会禁用ICMP重定向包以防止中间人攻击风险。

用tracert命令跟踪数据包的路径,这是2次运行tracert命令的结果:

tracert命令的原理是,发出ICMP的ping包(type=8,code=0),但初始ttl=1,之后每次累加1,直到目的地。这样一来,途径的每个路由器将TTL-1,如果为0,就会向PC1发回"TTL过期"错误包(type=5,code=0),这样tracert命令就探测出了途径的所有路由器和主机。

分析上图。用wiershark抓包可以发现,第一次运行tracert命令,R1会向PC1返回ICMP重定向包(type=5,code=0),但随后仍然会继续转发此包,也就是说第一次ping能够到达目的地,但并非最优路径。

第二次运行tracert命令,由于之前收到了ICMP重定向包,所以修改了路由表,ping包的第一跳就是R6,随后到达目的地。

但我们只关注第一次运行tracert命令的结果。你发现了没有,路径是不对的,正确的应该是R2(192.168.0.1)→R6(192.168.0.4)→PC3(192.168.7.2)才对,可显示的结果缺失了中间的R6(192.168.0.4)。

一开始我也是百思不得其解,但仔细观察wireshark的抓包结果之后,终于知道了问题根源所在。

原来,tracert命令发出的第一个ping包的TTL=1,那么第二个ping包就应该是TTL=2,第三个ping包应该是TTL=3。。。

可这种累加策略却忽略了ICMP重定向包造成的"干扰",所以当第二个ping包的下一跳转向R6时,携带的TTL=2。

当数据包到达R6,会将TTL-1=1,由于并非为0,所以R6不会向PC1返回TTL过期的ICMP错误包,tracert命令也就探测不到R6的存在了。

这。。。算是tracert命令的一个bug吧。正确的方法是当路由表被ICMP重定向包修改,发出的第一个ping包的TTL应该被置为1。

对此,GNS3的VPCS虚拟设备就做得很好,清楚地显示了路径的修改过程:

另外,被ICMP重定向包修改的路由表是看不到的,因为Windows 在处理 ICMP Redirect 时,不会在永久或显示的路由表中增加一条可见路由项。被重定向的路由是**内核临时缓存(transient route)**中的一部分,只在内存中生效,不会显示在 route print 或 netstat -r 里。这个缓存属于 TCP/IP 协议栈内部(Route Cache 或 Neighbor Cache),更新仅在该目标主机或子网通信时生效,不会写入持久路由表。

但也有显示的方法------显示缓存表:

netsh interface ipv4 show destinationcache

还有资料提到另一种写法,记录于此:

netsh interface ipv4 show global

相关推荐
^Rocky2 天前
IT 疑难杂症诊疗室:复杂技术问题解决实录
运维·bug
Keven_114 天前
Bug:UVA816
bug
Keven_114 天前
Bug:UVA1103
bug
钱栈up5 天前
坯料管理导入功能bug修复:只改前端一个文件就解决问题
前端·bug
项目管理实用笔记5 天前
Bug跟踪管理系统有哪些?2026 推荐清单与选型指南
bug·研发管理·研发管理工具·项目管理软件选型
iNeuOS工业互联网8 天前
iNeuOS工业互联网操作系统,重要更新:性能优化、安全漏洞与BUG修复,远程控制响应效率大幅提升
性能优化·bug
嵌入式学习菌9 天前
Modbus‑RTU 数据类型分析
开发语言·单片机·bug
缘友一世10 天前
dsh(0.1.5-rc.1)接入官方模型deepseek-flash图像输入不支持修复
bug·图片输入·deepseek-flash·dsh 0.1.5-rc.1
lovingsoft10 天前
AI测试中的对抗测试:从“找Bug”到“预演战争”
人工智能·bug
golang学习记11 天前
VS Code 新UI被曝重大bug:菜单栏消失了
vscode·bug