windows下使用winpcap修改数据包,重定向tcp连接
lzwml 2010-10-29 09:03:53 局域网里有3台计算机A、B、C其中A上运行抓包程序监控其余机台计算机通讯情况,A、B、C上运行我以前写的C/S程序,B、C运行的是Server,A运行的是Client。
我的工作是检测到当A向B发起3次握手连接请求的第一个数据包时,把这个数据包的目的地址修改成C的地址,然后发送出去,实现A与C的连接。判断是否是三次握手的第一个数据包我的依据是,tcp头里的ack为0。在C上运行wireshark的确看到我修改的数据包,但是没见到C上的Server有什么反映。
A:192.168.123.36
B:192.168.123.101
C:192.168.123.102
部分代码如下:
//winpcap回调函数
void protocol_packet_callback(
u_char *argument,
const struct pcap_pkthdr *packet_header,
const u_char *packet_content)
{
static long olddstip = inet_addr("192.168.123.101");//旧的目的地址,B的
static long dstip = inet_addr("192.168.123.102"); //新的目的地址,C的
static long srcip = inet_addr("192.168.123.36"); //原来的源地址,A的
static u_char dstmac[] = {0x00,0x88,0x99,0x80,0xbd,0xc3};//B的物理地址地址
if(ptcp->tcp_acknowledgement == 0 && //3次握手第一次连接
pip->ip_souce_address.S_un.S_addr == srcip && //且原来源地址是A
pip->ip_destination_address.S_un.S_addr == olddstip) {//且原目的地址是B
//定位各个协议头指针位置
u_char *ppacket;
ether_header *pether;
ip_header *pip;
tcp_header *ptcp;
ppacket = (u_char*)packet_content;
pether = (ether_header*)(ppacket);
pip = (ip_header*)(ppacket+sizeof(ether_header));
ptcp = (tcp_header*)(ppacket+sizeof(ether_header)+sizeof(ip_header));
memmove(pether->ether_dhost,dstmac,6);//B的物理地址写成C的物理地址
pip->ip_destination_address.S_un.S_addr = dstip;//B的IP地址写成C的IP地址
pip->ip_checksum = 0;//计算校验和,下面的函数我保证没有错误
pip->ip_checksum = ( checksum((unsigned short*)(packet_content+14),
sizeof(ip_header)/sizeof(unsigned short)) );
//发送出去
pcap_sendpacket(mydev,(u_char*)packet_content,packet_header->len);
}
//*******无关内容*****比如伪造A向B发送关闭连接操作数据包
}
实际上我怕原来的B在我之前应答了A,所以我在B上没有运行Server程序,B仅仅开机而已。
我不知道问题出在哪里,是我还有什么地方需要修改的,还是跟A上运行的Client有关,三次握手是由connect函数实现的,
int connect(
SOCKET s,
const struct sockaddr* name,
int namelen
);
莫非函数里对第二次握手的源地址(C的)与sockaddr里的地址(B的)是否一致做了判断?我成了非法连接?