今天终于建立起一条TCP连接了。
前两天的问题通过写了一些试验程序得出了结论。
单单用Raw Socket做不到这个目的。
下面先讲讲我的解决方法:
现在是用的方法,原理是基于ARP欺骗的手段。
先简单描述一下环境吧。假设有两台机器A和B,并且连接在同一个局域网上。现在要做到的就是主机A不使用OS提供的TCP/IP协议栈中的TCP,通过模拟TCP3次握手的过程,与主机B建立起一条TCP连接(也就是A发起主动连接)。先假设主机A的IP为IP1,网卡MAC地址为eth1;主机B的IP为IP2,网卡MAC地址为eth2。
如果是用Socket或者Raw Socket,那么当主机B发回报文的时候,会经过OS的协议栈,因此,在应用程序截获到该报文前,OS中的协议栈已经对该报文做出响应了(这个响应是错误的,因为内核根本没有这条连接的任何状态信息,所以就会发送RST报文回去,这就导致了无法建立起连接)。
现在设想的方法就是伪造一个不存在的IP,这样OS中的协议栈看到这个IP不是本机的,就会丢弃。也就不会达到TCP层了。不过这样一来,用Raw Socket就不行了,因为Raw Socket也是在IP上面的,IP已经丢掉了该报文,所以我的程序也无法收到该报文了。
所以,现在只有一条路了,就是用WinPcap在链路层就截获该报文,通过我的程序来对该报文进行识别和处理。好在WinPcap还提供了过滤报文的API,这样我的程序不需要识别每个收到的报文了。
所以现在的基本方法如下:
1.发送ARP Reply报文,使得对方主机的ARP Cache中有主机A的伪造IP——IP3的信息,其对应的MAC地址其实还是eth1。
2.发送SYN报文。
3.等待接收SYN、ACK报文。
4.构造相应的ACK报文,发送。
至此,一条TCP连接已经建立,对于主机A来说,没有任何信息,而对于主机B来说,可以认为一条连接已建立。