golang使用raw socket发送syn包

17090阅读 0评论2018-08-09 oxwangfeng
分类:LINUX

模拟client只发送syn包
1. client发送给server syn包,然后就主动断开了连接;
2. server收到client发过来的server返回给client syn+ack;
3. 由于client已经断开了连接,收到server发送的syn+ack以后,内核就给server发送了rst;(意思是我已经断开了连接,你不要再发送了)
发送完syn包以后,通过wireshark发现收到了syn + ack包,但是内核会主动发送一个rst包?why?具体答案在下面
程序采用原始套接字来发送socket;具体可以参考
使用raw socket来发送syn包后者icmp包;
使用raw socket必须自己组装ip header和tcp header,然后将组装好的内容发送给server;
模拟发送syn包的程序
也可以使用工具hping3工具来模拟发送syn包,具体用法如: hping3 -S bucket.wht.wgz.qbox.net
使用raw socket必须知道的两个问题:
了解了原始套接字的接收过程以后我们来回答上文中提到的两个问题: 
?Q:通过raw socket发送了一个SYN数据包以后,为什么kernel在接收到SYN+ACK的回包以后会发送RST给对端? 
?A:从第5节我们知道raw socket在发送数据报的时候没有经过L3的IP层和L4的TCP/UDP层,所以kernel也就完全不知道你自己”偷偷”的发送了一个SYN数据包。等待对端给我们发回来SYN+ACK的数据包的时候我们从第6节内容得知无论是否有对应的原始套接字处理,该报文都会走后续的协议栈处理流程,此时协议栈发现你发过来的这个数据包我根本不认识,我自己没有发过对应的SYN报文,毫无疑问协议栈肯定就会认为这是一个异常的报文,直接给回送了RST。 
?Q:protocol等于IPPROTO_RAW的套接字能否接收到数据包? 
?A:从上面的原始套接字的接收流程得知,对数据包进行的第一次筛选就是根据数据包的protocol生成的hash从raw_v4_htable中查找对应的raw socket,我们从网卡接收回来的数据包的L4层protocol肯定是TCP、UDP、ICMP等有效的值,我们没有听过说哪个数据包的protocol是IPPROTO_RAW吧,那么我们用protocol等于IPPROTO_RAW来新建原始套接字最后生成的hash值也就不会匹配到任何的数据包了。也就是说用IPPROTO_RAW新建的套接字只适合发送,不能接收数据包
:也就是raw socket没有经过ip层,也没有经过tcp层(如果经过tcp层和ip层,系统就会添加tcp header和ip header),也就说内核不知道client发送一个syn包,也更没有办法接受数据了;
后来发现一个syn包的文章:使用syn报来探测服务器的端口
上一篇:合并回源
下一篇:golang访问源站报x509: certificate signed by unknown authority