0

我一直在自学如何使用原始套接字,因为我一直发现低级网络非常有趣。这里的目标不是使用原始套接字完全重新实现 TCP,而是学习如何为自己进行 3 次握手(绕过内核)。

对于我的示例,我编写了一个小程序,它将创建一个带有用户提供的源地址和目标地址的 IP 标头,为协议填写 TCP,组成任意 16 位标识,将版本设置为 4,长度设置为 5,并标记到 2(不要分段)。IP 标头对它制作的每个数据包都执行​​此操作(并且工作得很好,实际上除了地址和 ident 具有与已知良好 TCP SYN 数据包相同的所有位)。然后,它使用用户提供的端口、随机序列号、0 ACK、偏移量 5(除非选项)、标志设置为 2(SYN)和任意窗口大小(我一直在使用 32792)来制作 TCP 标头。我尝试了不同程度的 TCP 选项,希望其中一个选项阻碍了我的努力,所以有时这个标头会发生一些变化以使事情正常进行。

该程序是用 python 编写的,使用地址族 AF_INET 和协议 IPPROTO_RAW 的原始套接字(尽管我也尝试过 IPPROTO_TCP)。所以我启动了wireshark,并在一个等待TCP连接的用户应用程序上发射了一个SYN。Wireshark 显示 SYN,并且没有显示与数据包相关的错误,但这就是故事的结尾……没有 SYN/ACK,没有 RST,什么都没有。syslog 中没有错误,用户应用程序什么也没看到,并且检查 iptables 确保没有防火墙规则。值得注意的是,到目前为止我所有的测试都在同一个地址“127.0.0.1”上,对于这些初始响应,唯一被欺骗的是源端口。我一直在 slackware 14.0(在 VM 中运行)上对此进行测试。

奇怪的是,启动客户端用户应用程序(即我所针对的简单服务器的客户端)并通过 tcp 套接字连接显示了一个初始 SYN,它与我的数据包仅在几个字节上有所不同:tcp.s_port、tcp。校验和,ip.checksum,ip.identification。然而,服务器立即用 SYN/ACK 响应客户端的 SYN。我一生都无法弄清楚我的手工制作的数据包在哪里被丢弃了。为了调试,我关闭了 TCP 时间戳和窗口大小。任何人都可以阐明什么可能会抑制我

更新 代码在这里:http
://pastebin.com/2aHWYGxb# 对 TCP 校验和计算进行了更多阅读,我偶然发现了这一点: http
://www.tcpipguide.com/free/t_TCPChecksumCalculationandtheTCPPseudoHeader-2.htm 其中解释了一种与我以前见过的不同的方法,也许现在就是这样?不确定,但我现在正在努力。

按照上面的文章并重新实现要在伪标头、tcp 标头(校验和为 0)上计算的校验和函数,并且有效负载没有任何改进。更改后的代码可以在 pastebin 链接中找到:k6bwFvX6
我很确定,到目前为止,问题确实出在校验和计算上,但我一辈子都看不出它有什么问题。

经过进一步审查,结果发现我是在字节而不是半字节上运行校验和函数,我忘记了移位操作。现在一切正常,感谢那些提供帮助的人。

4

0 回答 0