永发信息网

TCP raw socket chksum 死活不对,求助

答案:2  悬赏:0  手机版
解决时间 2021-01-28 12:22
  • 提问者网友:战皆罪
  • 2021-01-28 06:58
TCP raw socket chksum 死活不对,求助
最佳答案
  • 五星知识达人网友:第四晚心情
  • 2021-01-28 07:05
一般情况下,我们使用raw socket都是用于发送icmp包或者自己定义的包。最近我想用raw socket
自己去创建TCP的包,并完成3次握手。
在这个过程中,发现了几个问题:
1. 发现收不到对端返回的ACK,但是通过tcpdump却可以看到。这个通过修改创建socket的API参数得以纠正。
原来创建socket使用如下参数s = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)。因为linux的raw socket不会把
不会把UDP和TCP的分组传递给任何原始套接口。——见《UNIX网络编程》28.3.
所以为了读到ACK包,我们创建的raw socket需要建立在数据链路层上。
s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP))
这样该socket就可以读取到所有的数据包。当然这样的数据包无疑是非常庞大的,那么我们可以
使用bind和connect来过滤数据包。bind可以指定本地的IP和端口,connect可以指定对端的IP和端口。
2. 在修改完创建socket的API,我发现还有一个问题,到现在依然没有找到合适的解决方法。
通过链路层的raw socket,我们可以收到对端的ACK。但是因为linux内核也会处理TCP的握手过程,
所以,当它收到ACK的时候,会认为这是一个非法包,会直接发送一个RST给对端。这样我们拿到了这个ACK,
也没有实际的用处了——因为这个连接已经被RST了。
我想,内核之所以会直接发送RST,也许是因为我们创建的是raw socket,但是发送的确是TCP包,
当对端返回ACK时,内核根本不认为我们已经打开了这个TCP端口,所以会直接RST掉这个连接。
那么问题就在于,我们如何告诉内核,我们打开了TCP的这个端口。
我想过一个方法,除了一个raw socket,再创建一个真正的TCP socket。但是细想起来,这条路应该行不通。
在网上搜了半天,总算找到一个比较详细的解释了。原因给我猜想的相差不远,当我们使用raw socket来发送sync包时,内核的TCP协议栈并不知道你发送了sync包,所以当对端返回SYNC/ACK时,内核首先要处理这个包,发现它是一 个SYNC/ACK,然而协议栈却不知道前面的sync,所以就认为这个包是非法的,于是就会发送RST来中止连接。
全部回答
  • 1楼网友:纵马山川剑自提
  • 2021-01-28 07:21
搜一下:TCP raw socket chksum 死活不对,求助
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯