好的,我意识到这种情况有点不寻常,但是我需要建立一个TCP连接(3路握手),只使用原始套接字(在C中,在linux中),也就是说,我需要自己构造IP报头和TCP报头。我正在编写一个服务器(所以我必须首先响应传入的SYN数据包),无论出于什么原因,我似乎无法正确地完成它。是的,我意识到SOCK_STREAM会为我处理这个问题,但出于不想进入的原因,这不是一种选择。
我在网上找到的关于使用原始套接字的教程都描述了如何构建SYN溢出程序,但这比实际建立TCP连接要容易一些,因为您不必根据原始数据包构建响应。我已经让SYN泛泛器示例工作起来了,我可以很好地从原始套接字读取传入的SYN数据包,但是我仍然很难为来自客户端的传入SYN创建一个有效的SYN/ACK响应。
那么,是否有人知道一个关于使用原始套接字的好教程,而不仅仅是创建SYN,或者有人有一些代码可以这样做(使用SOCK_RAW,而不是SOCK_STREAM)?我将非常感激。
MarkR是绝对正确的--问题是内核发送重置数据包来响应初始数据包,因为它认为端口关闭了。内核比我快到响应,连接就死了。我已经在使用tcpdump来监视连接了--我应该更仔细地观察并注意到有两条回复--其中一条是重置,把事情搞砸了,以及我的程序创建的响应。哦哦!
最有效的解决方案似乎是使用MarkR建议的iptables规则来阻止出站数据包。但是,有一种比使用mark选项更简单的方法,就像建议的那样。我只匹配是否设置了重置TCP标志。在正常连接的过程中,这是不太可能需要的,如果我阻止从所使用的端口中的所有出站重置数据包,对我的应用程序来说并不重要。这实际上阻止了内核不想要的响应,但不能阻止我自己的数据包。如果我的程序监听的端口是9999,那么iptables规则如下所示:
iptables -t filter -I OUTPUT -p tcp --sport 9999 --tcp-flags RST RST -j DROP发布于 2008-09-21 06:57:38
您希望在用户空间中实现TCP堆栈的一部分.这很好,其他的应用程序也会这么做。
您会遇到的一个问题是,内核将发送(通常是负面的、无帮助的)对传入数据包的答复。这会破坏你试图发起的任何沟通。
避免这种情况的一种方法是使用内核没有自己的IP堆栈的IP地址和接口--这很好,但是您需要自己处理链接层的内容(具体来说,arp)。这需要一个比IPPROTO_IP、SOCK_RAW更低的套接字--您需要一个包套接字(我认为)。
使用iptables规则也可能阻止内核的响应--但我更怀疑这些规则在某种程度上也适用于您自己的数据包,除非您能够设法使它们得到不同的处理(也许对您自己的数据包应用了一个netfilter“标记”?)
阅读手册页
套接字(7) ip(7)分组(7)
解释适用于套接字类型的各种选项和ioctl。
当然,您需要像Wireshark这样的工具来检查正在发生的事情。您将需要几台机器来测试这一点,我建议使用vmware (或类似的)来减少硬件所需的数量。
对不起,我不能推荐一个具体的教程。
祝好运。
发布于 2012-07-30 11:30:25
我意识到这是一个古老的线程,但这里有一个教程,它超越了常规的SYN洪水:http://www.enderunix.org/docs/en/rawipspoof/
希望能对某人有所帮助。
发布于 2008-09-21 06:44:13
我不能帮你上任何教程。
但是,我可以为您提供一些建议,说明您可以使用哪些工具来帮助调试。
首先,正如布达克所建议的,给自己一个威雷沙克的副本(或者tcpdump --但是wireshark更容易使用)。握住一个好的握手。一定要保存好这个。
抓住你的一次握手失败。Wireshark有相当好的数据包解析和错误检查,所以如果有一个直接的错误,它可能会告诉您。
接下来,给自己买一份tcpreplay的副本。这还应该包括一个名为"tcprewrite“的工具。tcprewrite将允许您将先前保存的捕获文件拆分为两个-一个用于握手的每一方。然后,您可以使用tcpreplay来回放握手的一边,这样您就可以使用一组一致的数据包来播放。
然后使用wireshark (再次)检查您的答复。
https://stackoverflow.com/questions/110341
复制相似问题