目录
最近尝试通过node 调用wintun.dll,写了几个demo 尝试发送和响应ICMP和UDP,但总发现包发送了,能被抓包,但收不到。
包发送了,能被抓包,但收不到
大概的情况是:
cmd tun node_tun.js 以太网
ping ===> read ===> replace srcip ===> send
timeout <=== write <=== replace detip <=== rec
tun网卡 ip地址为 192.167.0.126
以太网网卡 ip 地址为 192.168.2.121
以上数据包均可以被抓到。
- 指定tun网卡ip ping 8.8.8.8, cmd 输入
ping -S 192.167.0.126 8.8.8.8
- 通过WintunReceivePacket 接口从tun中读取到整个IP数据包
- 将IP包的源地址 192.167.0.126 替换成 192.168.2.121,计算checksum 后,通过 raw-socket send,数据从[以太网网卡]发出
- raw-socket on message 收到 8.8.8.8 发给 192.168.2.121回包
- 将目标地址 192.168.2.121 替换成 192.167.0.126,计算checksum 后,通过 WintunAllocateSendPacket 接口从tun写入
- cmd 显示 timeout
正常的话应该能ping 通,但是没有。
检查:
- icmp.id 和 icmp.seq 正确
- winshark 有显示 replay in ? 和 request in ?
- ……
最后发现 ip header checksum 没算对,数据包被被丢弃了。
好吧,有点丢人,同个坑我连续踩2次。
一次是ChatGPT给的checksum算法不对坑了自己3天。
这次是修改数据后,计算checksum时,没把原来checksum重置为0再计算。
奇怪的地方
这里简单说下我当时觉得奇怪的地方:
- 错误的checksum被使用了2次,一次 replace srcip ,一次 replace detip,为啥第一次没发送失败?
- winshark replay in ? 和 request in ? 不能代表包的正确性?
- winshark 都能抓到包,为什么我收不到包?
尝试回答
-
同一个checksum 函数被使用了2次,一次 replace srcip ,一次 replace detip,为啥第一次没发送失败?
- 路由器没有做IP包头的checksum检查,错误被忽略
- IP包过路由器时,由于是NAT,IP包头的checksum会被重新计算,错误被修正
-
winshark replay in ? 和 request in ? 不能代表包的正确性?
- 这里应该只是按照ICMP的 id 和 seq 字段做对应
- winshark 默认不开启 checksum 验证,而且开启时需要按协议设置
-
winshark 都能抓到包,为什么我收不到包?
- winshark只能确认数据包经过了网卡
- checksum 检查不在应用程序中,ping 命令和 raw-socket 均收不到
- win10 在数据进入用户空间是有检查 checksum,校验失败即丢弃
复盘
- 构造IP包和复写checksum不熟练
- winshark 不熟练,如果有开启checksum 验证,飘红的警告会第一时间发现
- 对TUN和系统工作原理不懂,当能抓到TUN写入的包,而应用程序收不到的时候,应该第一时间检查IP包的有效性
winshark 开启checksum
如图,
- 在对应的协议的checksum字段 [右键],点击 [协议首选]
- 勾选 [Validate the lPv4 checksum if possible],如果没算对,这里会飘红
另外按照winshark的官网说明,开启checksum的验证对winshark 的性能影响不大,几乎可以忽略