我正在使用python RAW套接字实现TCP握手。 然而,Linux内核很烦人,因为它试图处理这个协议的某些方面。
例如,当我发送一个SYN数据包时,服务器响应一个SYN,ACK数据包; 内核自动响应RST包重置连接。 我克服了这一点,我使用下面的iptable规则丢弃所有这样的重置数据包:
-A OUTPUT -p tcp -m tcp --sport 999 --tcp-flags RST RST -j DROP
现在我想接收服务器发送的SYN,ACK包并将其打印出来。 但是当我做以下事情时我什么也收不到:
a = self.s.recvfrom(4096)
我怀疑内核正在丢弃的SYN,ACK之前,我可以用我的套接字recv它。 有谁知道一个合理的解决方法?
你可以使用libpcap,在Python中看来这个模块: http : //pylibpcap.sourceforge.net/或者这个: https : //pypi.python.org/pypi/pypcap
用pcap你可以注册接收来自内核的消息。 通过从应用程序提供正确的过滤器,您可以从内核接收TCP段。 我已经在C中使用了libpcap,我想你可以用相同的方式使用指定的模块。 对我来说,这是最好的解决方案,因为你可以用一种非常标准的方式从应用程序中处理它。
为了避免内核响应RST,你的iptables解决方案看起来是最适合我的。
虽然我希望有人提出一个更方便的解决方案,但一种方法是使用iptables将传入的TCP Syn数据包传递给nfqueue 。 Nfqueue有现有的Python 绑定 ,所以使用它不应该是一个问题。
这个想法是在到达内核的TCP实现之前捕获所有传入的TCP Syns。 然后将这些数据包传递给您的用户空间应用程序可以监视的nfqueue。 对于你的应用程序将从nfqueue得到的每个数据包,它将不得不决定是否处理数据包本身(即将数据包丢弃到操作系统)或者将它传递给常规的TCP实现。
我知道这个方法可行,但是很麻烦。
既然你用原始数据包完成了这一切,为什么不创建自己的MAC地址和IP地址呢? 您需要将适配器设置为混杂模式来接收数据包,但是如果这样做,内核不应该将任何响应发送到您的传入数据包,因为它们看起来会被发送到“某些其他系统”。 这使得过滤你关心别人的数据包变得微不足道。
您还需要适当地回应ARP,以便其他系统找到您的MAC地址。 如果你需要DHCP获得IP地址,你也需要处理这些交互。