请教大家winpcap发包的问题

kingzai 2002-07-16 10:37:03
我现在想实现的是,接受网络里面所有的请求,并给于每个请求返回三个unreach,两个rst。目的是中断请求。raw socket的实现见http://www.csdn.net/expert/topic/866/866712.xml?temp=.2748529
我现在基本上是把它改成相应winpcap发包的代码。具体如下:
void WINAPI SendICMPPackage(unsigned int icmpcode,LPPACKET lpPacket,void* lpAdapter)
{
LPADAPTER pAdapter = (LPADAPTER) lpAdapter;
//得到一份请求的报文,我们从源报文得到源端口,目的端口,源IP地址,目的IP地址,TCP序列号(重要!)
if (lpPacket->ulBytesReceived> (sizeof(ETH_HEADER) + sizeof(IP_HEADER) + sizeof(TCP_HEADER)))
{
char *pChar;
struct bpf_hdr *hdr;
char *buf=(char*)lpPacket->Buffer;
UINT off=0;
hdr=(struct bpf_hdr *)(buf+off);
off+=hdr->bh_hdrlen;
pChar =(char*)(buf+off); // pChar中指向的才是报文数据。
//////////////////////////////////////////////////////
// ETHER_PACKET *pEthPkt = (ETHER_PACKET *) lpPacket->Buffer;
ETH_HEADER *pEthHdr = (ETH_HEADER *) pChar;
IP_HEADER *pIpHdr = (IP_HEADER *) (pChar+sizeof(ETH_HEADER));
int i_IPH_Size = 20;//pIpHdr->ihl * 4;
TCP_HEADER *pTcpHdr = (TCP_HEADER *) ((char *) pIpHdr + i_IPH_Size);
int i_TCPH_Size = 20;//pTcpHdr->doff * 4;
///////////////////////////////构造一条回应报文//////////
char szSendBuf[100]={0};
struct PPACK
{
ETH_HEADER eth;
IP_HEADER ip;
ICMP_HEADER icmp;
}ppack;
memset(&ppack,0,sizeof(PPACK));
memcpy(ppack.eth.h_dest,pEthHdr->h_source,sizeof(pEthHdr->h_source));
memcpy(ppack.eth.h_source,pEthHdr->h_dest,sizeof(pEthHdr->h_dest));
ppack.eth.h_proto=pEthHdr->h_proto;
ppack.ip.check=0;
ppack.ip.daddr=pIpHdr->saddr;
ppack.ip.frag_off=0;
ppack.ip.h_lenver=pIpHdr->h_lenver;
ppack.ip.id=0;
ppack.ip.protocol=IPPROTO_ICMP;
ppack.ip.saddr=pIpHdr->daddr;
ppack.ip.tos=0;
ppack.ip.tot_len=htons(sizeof(IP_HEADER)+sizeof(ICMP_HEADER));
ppack.ip.ttl=64;

ppack.icmp.i_type=3;
ppack.icmp.i_code=icmpcode;
ppack.icmp.i_cksum=0;
memcpy(szSendBuf, &ppack, sizeof(ppack));

//使用winpcap库函数发送包
LPPACKET pPacket;
if((pPacket = PacketAllocatePacket())==NULL)
{
AfxMessageBox("\nError:failed to allocate the LPPACKET structure.");
return ;
}
memset(pPacket,0,sizeof(LPPACKET));
PacketInitPacket(pPacket,szSendBuf,sizeof(IP_HEADER)+sizeof(ICMP_HEADER)+sizeof(ETH_HEADER));
// capture the packet
if(PacketSetNumWrites(pAdapter,5)==FALSE)
{
AfxMessageBox("warning: Unable to send more than one packet in a single write!\n");
}

if(PacketSendPacket(pAdapter,pPacket,TRUE)==FALSE)
{
AfxMessageBox("Error sending the packets!\n");
return ;
}
}

}
发送RST的代码见下面的回复。我的问题是:
我用sniffer抓包发现包已经发出,但连接并没有被中断。是否校验和或者某个参数出现了问题。
...全文
401 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
ksyou 2002-07-17
  • 打赏
  • 举报
回复
kingzai: 非常感谢你,也非常感谢xuying

我的email是

yong_jsu@hotmail.com
explorer007 2002-07-16
  • 打赏
  • 举报
回复
MARK
wg2000happy 2002-07-16
  • 打赏
  • 举报
回复
gz
kingzai 2002-07-16
  • 打赏
  • 举报
回复
在TCP段发送RST报文的各种情况我昨天都试过了,感觉序列号被正常回应的报文占用了,因为winpcap只是截获拷贝报文呀。
所以我现在采用发送ICMP包来实现
kingzai 2002-07-16
  • 打赏
  • 举报
回复
在TCP段发送RST报文的各种情况我昨天都试过了,感觉序列号被正常回应的报文占用了,因为winpcap只是截获拷贝报文呀。
所以我现在采用发送ICMP包来实现
kingzai 2002-07-16
  • 打赏
  • 举报
回复
我是要发送从服务器到客户端的伪报文。
改成这样也不行啊:
tcpHeader.seq=pTcpHdr->ack_seq;//32位序列号
xuying 2002-07-16
  • 打赏
  • 举报
回复
序列号不对啊。
tcpHeader.seq=0;//32位序列号
tcpHeader.seq+=1;//序列号+2

你发送给服务器的报文序列号应该是你上次截获到的服务器发出的tcp报文中的ack的序列号。这样服务器才不会丢弃你的报文而进行处理。
kingzai 2002-07-16
  • 打赏
  • 举报
回复
发送RST的代码如下:
void WINAPI SendRSTPackage(LPPACKET lpPacket,void* lpAdapter)
{
LPADAPTER pAdapter = (LPADAPTER) lpAdapter;
//得到一份请求的报文,我们从源报文得到源端口,目的端口,源IP地址,目的IP地址,TCP序列号(重要!)
if (lpPacket->ulBytesReceived> (sizeof(ETH_HEADER) + sizeof(IP_HEADER) + sizeof(TCP_HEADER)))
{
char *pChar;
struct bpf_hdr *hdr;
char *buf=(char*)lpPacket->Buffer;
UINT off=0;
hdr=(struct bpf_hdr *)(buf+off);
off+=hdr->bh_hdrlen;
pChar =(char*)(buf+off); // pChar中指向的才是报文数据。
//////////////////////////////////////////////////////
// ETHER_PACKET *pEthPkt = (ETHER_PACKET *) lpPacket->Buffer;
ETH_HEADER *pEthHdr = (ETH_HEADER *) pChar;
IP_HEADER *pIpHdr = (IP_HEADER *) (pChar+sizeof(ETH_HEADER));
int i_IPH_Size = 20;//pIpHdr->ihl * 4;
TCP_HEADER *pTcpHdr = (TCP_HEADER *) ((char *) pIpHdr + i_IPH_Size);
int i_TCPH_Size = 20;//pTcpHdr->doff * 4;
//filter when port do not equate 80//这里我们只对80端口进行监视,即服务器的回应包
// int iSourcePort=(int) ntohs(pTcpHdr->source); //source port no
// int iDestPort=(int)ntohs(pTcpHdr->dest);//dest port no
// if(iSourcePort !=80 || iSourcePort!=8080)
// return;
///////////////////////////////////////////////////////
//构造一份回应报文,和请求报文不太一样
ETH_HEADER ethHeader;
IP_HEADER ipHeader;
TCP_HEADER tcpHeader;
PSD_HEADER psdHeader;
char szSendBuf[100]={0};
//填充MAC地址
memcpy(ethHeader.h_dest, pEthHdr->h_source, sizeof(pEthHdr->h_source));
memcpy(ethHeader.h_source, pEthHdr->h_dest, sizeof(pEthHdr->h_dest));
ethHeader.h_proto=pEthHdr->h_proto;
//填充IP首部
ipHeader.h_lenver=pIpHdr->h_lenver;
ipHeader.tos=pIpHdr->tos;
ipHeader.tot_len=htons(40);
ipHeader.id=0;
ipHeader.frag_off=0;
ipHeader.ttl=64;
ipHeader.protocol=IPPROTO_TCP;
ipHeader.check=0;
ipHeader.saddr=pIpHdr->daddr;//客户端IP地址
ipHeader.daddr=pIpHdr->saddr; //服务器端IP地址

//填充TCP首部
tcpHeader.dest=pTcpHdr->source;//源端口号,
tcpHeader.source=pTcpHdr->dest;//目的端口号 (pTcpHdr->dest)这是因为我们要假冒从服务器发出的包
tcpHeader.seq=0;//32位序列号 tcpHeader.seq+=1;//序列号+2
tcpHeader.ack_seq=htonl(ntohl(pTcpHdr->seq)+1);//32位确认号
tcpHeader.th_lenres=0;
tcpHeader.th_flag=4; //修改这里来实现不同的标志位探测,2是SYN,1是FIN,16是ACK,4是RST
tcpHeader.window=0;
tcpHeader.urg_ptr=0;
tcpHeader.check=0;
//填充TCP伪首部
psdHeader.saddr=ipHeader.saddr;
psdHeader.daddr=ipHeader.daddr;
psdHeader.mbz=0;
psdHeader.ptcl=IPPROTO_TCP;
psdHeader.tcpl=htons(sizeof(tcpHeader));

//计算校验和
memcpy(szSendBuf, &psdHeader, sizeof(psdHeader));
memcpy(szSendBuf+sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader));
tcpHeader.check=checksum((USHORT *)szSendBuf,sizeof(psdHeader)+sizeof(tcpHeader));
memcpy(szSendBuf,ðHeader,sizeof(ethHeader));
memcpy(szSendBuf+sizeof(ipHeader)+sizeof(ethHeader), &tcpHeader, sizeof(tcpHeader));
memset(szSendBuf+sizeof(ipHeader)+sizeof(tcpHeader)+sizeof(ethHeader), 0, 4);
ipHeader.check=checksum((USHORT *)szSendBuf+sizeof(ethHeader), sizeof(ipHeader)+sizeof(tcpHeader));
memcpy(szSendBuf+sizeof(ethHeader), &ipHeader, sizeof(ipHeader));

// memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
//使用winpcap库函数发送包
LPPACKET pPacket;
if((pPacket = PacketAllocatePacket())==NULL)
{
AfxMessageBox("\nError:failed to allocate the LPPACKET structure.");
return ;
}
memset(pPacket,0,sizeof(LPPACKET));
PacketInitPacket(pPacket,szSendBuf,54);
// capture the packet
if(PacketSetNumWrites(pAdapter,5)==FALSE)
{
AfxMessageBox("warning: Unable to send more than one packet in a single write!\n");
}

if(PacketSendPacket(pAdapter,pPacket,TRUE)==FALSE)
{
AfxMessageBox("Error sending the packets!\n");
return ;
}
}



}
我感觉这种方法应该是可以的,继续调试中...
kingzai 2002-07-16
  • 打赏
  • 举报
回复
xuying:
我对你的崇拜已到滔滔江水级别了。。。
ksyou:
留下你的mail,我发给你,代码有注释,很详细,不过就不要太公开了。
kingzai 2002-07-16
  • 打赏
  • 举报
回复
xuying:
我对你的崇拜已到滔滔江水级别了。。。
ksyou:
留下你的mail,我发给你,代码有注释,很详细,不过就不要太公开了。
xuying 2002-07-16
  • 打赏
  • 举报
回复
to ksyou:
我改好了,发给kingzai了,你问他要吧。
ksyou 2002-07-16
  • 打赏
  • 举报
回复
kingzai:上次你说的修改注册表的做法在当时确实是可行的,但今天我调试的时候却又出现了同样的错误,而且,修改注册表也没有用处,我在2台机器是做过了,都不行,
kingzai 2002-07-16
  • 打赏
  • 举报
回复
收包是绝对没问题的,发包也没有问题。断开连接我正在调
kingzai 2002-07-16
  • 打赏
  • 举报
回复
收包是绝对没问题的,发包也没有问题。断开连接我正在调
ksyou 2002-07-16
  • 打赏
  • 举报
回复
kingzai:那份代码实现不了,现在头让我看了2天的winpcap,又让我用winpcap去做啊,我只看了2天啊!天啊
kingzai 2002-07-16
  • 打赏
  • 举报
回复
ksyou,你不是用的raw socket吗,你在应用层发包不必考虑MAC地址等东西,而且我看那份代码可以实现的呀。
ksyou 2002-07-16
  • 打赏
  • 举报
回复
2位大哥啊,kingzai and xuying,快点把这个问题做出来吧,我做了一个星期都没做出来啊,为了小弟的前途,2位大哥努力一点啊

我拜2位大哥为师啊,我的qq是5833238

4,358

社区成员

发帖
与我相关
我的任务
社区描述
通信技术相关讨论
社区管理员
  • 网络通信
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧