我发现了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

相关推荐
熟人看不到5 小时前
解决Claude Code界面错位更新不及时-Windows
bug·vibecoding·claude code
深念Y7 小时前
踩坑实录:把 Windows 默认 PowerShell 换成 7.x 到底有多坑?一条龙解决指南
windows·乱码·bug·控制台·powershell·管道·流式
油炸自行车8 小时前
【Qt bug排查】Qt项目debug模式下,关闭可视化界面后,后台程序不退出,依然在打印log
bug
SoraShim15 小时前
2026实测:深入理解Gemini 3 Pro镜像站链式思考提示工程,三步解决复杂Bug定位
bug
AI 编程助手GPT2 天前
GPT-5.6意外曝光、Claude安全检查全面公测、Grok 4.3搅局价格战——多模型混战的五月,开发者如何避坑?
人工智能·gpt·ai·chatgpt·bug·ai编程
Zxxxxxy_3 天前
测试入门:从 0 到 1 搞懂开发与 Bug
bug
专注VB编程开发20年4 天前
Windows API 所有老式结构体4字节对齐,但是64位VBA,Twinbasic弄成了8字节对齐,大BUG
windows·bug
IT枫斗者5 天前
前端部署后如何判断“页面是不是最新”?一套可落地的版本检测方案(适配 Vite/Vue/React/任意 SPA)
前端·javascript·vue.js·react.js·架构·bug
半天法师6 天前
Bug 记录:UE 结构体转 JSON 时 Key 字段大小写异常 (Editor 与打包后表现不一致)
ai·ue5·json·bug
张小俊_6 天前
WPF 跨线程 UI 更新与硬编码赋值引发的 Bug 排查
c#·bug·wpf