winpcap发包问题,怎样发送一个带RST标志的TCP包

kingzai 2002-07-12 02:53:02
截获报文后,我想限制网上其他用户对因特网的访问权限。因此我构造了一份自己的报文。
发包的步骤我相信是一样的,主要如下代码
//构造一份报文
IP_HEADER ipHeader;
TCP_HEADER tcpHeader;
PSD_HEADER psdHeader;
char szSendBuf[100]={0};
//填充IP首部
ipHeader.h_lenver=(4<<4 | sizeof(ipHeader)/sizeof(unsigned long));
// ipHeader.tos=0;
ipHeader.tot_len=htons(sizeof(ipHeader)+sizeof(tcpHeader));
ipHeader.id=1;
ipHeader.frag_off=0;
ipHeader.ttl=128;
ipHeader.protocol=IPPROTO_TCP;
ipHeader.check=0;
ipHeader.saddr=pIpHdr->saddr;
ipHeader.daddr=pIpHdr->daddr;

//填充TCP首部
tcpHeader.dest=pTcpHdr->source;//源端口号,
tcpHeader.source=pTcpHdr->dest;//目的端口号 tcpHeader.seq=pTcpHdr->seq;//32位序列号
tcpHeader.ack_seq=0;//32位确认号
tcpHeader.th_lenres=(sizeof(tcpHeader)/4<<4|0);
tcpHeader.th_flag=4; //修改这里来实现不同的标志位探测,2是SYN,1是FIN,16是ACK,4是RST
tcpHeader.window=htons(512);
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, &ipHeader, sizeof(ipHeader));
memcpy(szSendBuf+sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
memset(szSendBuf+sizeof(ipHeader)+sizeof(tcpHeader), 0, 4);
ipHeader.check=checksum((USHORT *)szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader));
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));
pPacket->Buffer=szSendBuf;
PacketInitPacket(pPacket,pPacket->Buffer,strlen(szSendBuf));
// capture the packet
if(PacketSetNumWrites(lpAdapter,2)==FALSE)
{
AfxMessageBox("warning: Unable to send more than one packet in a single write!\n");
}
if(PacketSendPacket(lpAdapter,pPacket,TRUE)==FALSE)
{
AfxMessageBox("Error sending the packets!\n");
return ;
}
我的问题是:
1。是否发送带RST标志的TCP包后,系统会重起。(还是只是对当前IP包的限制?)
2。是否还有更好的限制访问的方法,(考虑时间和投入,不用驱动和防火墙等)
...全文
997 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
kingzai 2002-07-13
  • 打赏
  • 举报
回复
那客户端怎么判断哪个报文谁先到,如果晚到是否被丢弃,正如我在sniffer中根本看不到RST报文一样
kingzai 2002-07-13
  • 打赏
  • 举报
回复
先这么着吧,回去慢慢调
kingzai 2002-07-13
  • 打赏
  • 举报
回复
先这么着吧,回去慢慢调
xuying 2002-07-13
  • 打赏
  • 举报
回复
不用。
比如接收端发回的应答报文中 ack:1000,就表示下一个准备接收的序列号是1000。发送方发送序列号是1000的报文就可以了。
kingzai 2002-07-13
  • 打赏
  • 举报
回复
xuying,你说的没错,象这种问题真得慢慢调才行。一步一步查看内存的值。
另外,当得到一份从服务器到客户端的包拷贝序列号,是否要将它加1构造新报文。这样能保证客户端会接收到吗?
xuying 2002-07-13
  • 打赏
  • 举报
回复
给你贴一段发送syn数据包的程序,在2k server下编译运行没问题:
char packetbuff[5000];//包缓冲区
// define a pointer to a ADAPTER structure
LPADAPTER lpAdapter = 0;//设备指针
// define a pointer to a PACKET structure
LPPACKET lpPacket;//包指针

//分配空间
if((lpPacket = PacketAllocatePacket())==NULL)
{
printf("\nError:failed to allocate the LPPACKET structure.");
return (-1);
}

//将bufff中填入内容
//ETHERNET HEADER (14 BYTE)
//destination MAC address of 159.226.204.19
packetbuff[0]=0x00;
packetbuff[1]=0x50;
packetbuff[2]=0xBA;
packetbuff[3]=0xCC;
packetbuff[4]=0x13;
packetbuff[5]=0x4A;
//not exit source 159.226.204.20
packetbuff[6]=0x00;//0x00;
packetbuff[7]=0x80;//90;//0xD0;
packetbuff[8]=0x3E;//27;//0xB7;
packetbuff[9]=0x7C;//99;//0x70;
packetbuff[10]=0xA2;//02;//0xA7;
packetbuff[11]=0xE4;//0x14;
//ETHERNET TYPE (ip)
packetbuff[12]=0x08;
packetbuff[13]=0x00;

//IP HEADER OF THE PACKET
packetbuff[14]=0x45;//VERSION & HEADER LEHGTH
packetbuff[15]=0x00;//PRECEDENCE=ROUTINE & TYPE OF SERVICE(TOS)= NORMAL SERVICE
packetbuff[16]=0x00;//TOTAL LENGTH
packetbuff[17]=0x30;// = 48
packetbuff[18]=0x09;//IDENTIFICATION
packetbuff[19]=0xD7;// =2320(0X910)
packetbuff[20]=0x40;//FLAGS SUMMARY = CANNOT FRGMENT DATAGRAM
packetbuff[21]=0x00;//FRAGMENT OFFEST =0 BYTE
packetbuff[22]=0x80;//TIME TO LIVE(TTL)=126
packetbuff[23]=0x06;//PROTOCOL ---TCP
packetbuff[24]=0x00;// CHECKSUM
packetbuff[25]=0x00;// 0X18FE
//SOURCE ADDRESS
packetbuff[26]=0x9F;//159
packetbuff[27]=0xE2;//226
packetbuff[28]=0xCC;//204
packetbuff[29]=0x49;//49;//14;//20
//DESTINATION ADDRESS
packetbuff[30]=0x9F;//0xD2;//159
packetbuff[31]=0xE2;//0x19;//226
packetbuff[32]=0xCC;//0x85;//204
packetbuff[33]=0x13;//0x15;//19
//TCP HEADER
packetbuff[34]=0x07;//SOURCE PORT
packetbuff[35]=0x2C;// 0X0438
//默认21端口
packetbuff[36]=0x00;//DESTINATION PORT
packetbuff[37]=0x15;//8B;// NETBIOS SESSION SERVICE 139
//设置目标端口
if(port!=0)
{
packetbuff[36]=(port/0x0100)&0xff;
packetbuff[37]=port&0x00ff;
}

packetbuff[38]=0x9C;//SEQUENCE NUMBER
packetbuff[39]=0x5A;// SEQUENCE NUMBER
packetbuff[40]=0xEC;// 194730145
packetbuff[41]=0x1A;// SEQUENCE NUMBER
packetbuff[42]=0x00;//ACK NUMBER
packetbuff[43]=0x00;//
packetbuff[44]=0x00;//
packetbuff[45]=0x00;//

packetbuff[46]=0x70;//DATA OFFSET 28(1C) & RESERVED & FLAGS =
packetbuff[47]=0x02;// 02 ----SYN----
packetbuff[48]=0x40;//WINDOW
packetbuff[49]=0x00;// = 16384;
packetbuff[50]=0x00;//DA;//CHECKSUM;
packetbuff[51]=0x00;//FF;// 0XDAFF
packetbuff[52]=0x00;//URGENT POINT
packetbuff[53]=0x00;// 0
//OPTION
packetbuff[54]=0x02;//OPTION TYPE = MAXIMUM SEGMENT SIZE
packetbuff[55]=0x04;//OPTION LENGTH
packetbuff[56]=0x05;//MAXIMUM SEGMENT SIZE
packetbuff[57]=0xB4;// 1460 (0X5B4)
packetbuff[58]=0x01;//OPTION NOP
//SACK PERMITTED OPTION
packetbuff[59]=0x01;// OPTION NOP
packetbuff[60]=0x04;//OPTION TYPE = SACK PERMITTED;
packetbuff[61]=0x02;//OPTION LENGTH 2

//seed the random number//
srand( (unsigned)time( NULL ) );
while (!kbhit())//(count<5)//
{
count++;
//计算ip包头
j=0;k=14;
for(j=0;j<20;j++)
{
ip_header[j]=packetbuff[k];
k++;
}
j=0;k=0;
j=checksum(ip_header,sizeof(ip_header));//计算ip校验和
packetbuff[24]=j;
packetbuff[25]=(j/0x0100)&0x00ff;
//计算伪tcp头
k=26;
for(j=0;j<8;j++)//source ip & destination ip
{
tcp_header[j]=packetbuff[k];
k++;
}
tcp_header[j]=0x00;// 填充0
j=j+1;
tcp_header[j]=0x06;// protocal type
j=j+1;
tcp_header[j]=0x00;//tcp lengh
j=j+1;
tcp_header[j]=0x1C;
j=j+1;
for(;j<40;j++)//tcp data fragment
{
tcp_header[j]=packetbuff[k];
k++;
}

//计算tcp校验和
k=0;
k=checksum(tcp_header,sizeof(tcp_header));
packetbuff[50]=k&0x00ff;
packetbuff[51]=(k/0x100)&0x00ff;

Snaplen=62;
//初始化包结构
PacketInitPacket(lpPacket,packetbuff,Snaplen);
//
//PrintPackets(lpPacket);
npacks=1;
//设置重发次数
PacketSetNumWrites(lpAdapter,npacks);
//发包
PacketSendPacket(lpAdapter,lpPacket,TRUE);
xuying 2002-07-13
  • 打赏
  • 举报
回复
PacketInitPacket()的实现很简单,就是赋值。
//---------------------------------------------------------------------------
VOID PacketInitPacket (LPPACKET lpPacket,
PVOID Buffer,
UINT Length)
{
lpPacket->Buffer = Buffer;
lpPacket->Length = Length;
}

kingzai 2002-07-13
  • 打赏
  • 举报
回复
xuying:我做的嗅探功能可以实现呀,证明网卡的选择应该是正确的。上面的代码有些不明晰,我改成如下。不会死机,但也没反应了。
void WINAPI SendRSTPackage(LPPACKET lpPacket,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;
///////////////////////////////////////////////////////
//构造一份报文
IP_HEADER ipHeader;
TCP_HEADER tcpHeader;
PSD_HEADER psdHeader;
char szSendBuf[100]={0};
//填充IP首部
ipHeader.h_lenver=pIpHdr->h_lenver;
ipHeader.tos=pIpHdr->tos;
ipHeader.tot_len=pIpHdr->tot_len;
ipHeader.id=pIpHdr->id;
ipHeader.frag_off=pIpHdr->frag_off;
ipHeader.ttl=pIpHdr->ttl;
ipHeader.protocol=pIpHdr->protocol;
ipHeader.check=pIpHdr->check;
ipHeader.saddr=pIpHdr->saddr;//服务器IP地址
ipHeader.daddr=pIpHdr->daddr; //客户端IP地址

//填充TCP首部
tcpHeader.dest=pTcpHdr->dest;//目的端口号,
tcpHeader.source=pTcpHdr->source;//源端口号 (pTcpHdr->dest)这是因为我们要假冒从服务器发出的包
tcpHeader.seq=pTcpHdr->seq;//32位序列号
tcpHeader.ack_seq=pTcpHdr->ack_seq;//32位确认号
tcpHeader.th_lenres=pTcpHdr->th_lenres;
tcpHeader.th_flag=4; //修改这里来实现不同的标志位探测,2是SYN,1是FIN,16是ACK,4是RST
tcpHeader.window=pTcpHdr->window;
tcpHeader.urg_ptr=pTcpHdr->urg_ptr;
tcpHeader.check=pTcpHdr->check;
//填充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, &ipHeader, sizeof(ipHeader));
memcpy(szSendBuf+sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
memset(szSendBuf+sizeof(ipHeader)+sizeof(tcpHeader), 0, 4);
ipHeader.check=checksum((USHORT *)szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader));
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,100);
//改成PacketInitPacket(pPacket,szSendBuf,strlen(szSendBuf));立马死机,屡试不爽。

// capture the packet
if(PacketSetNumWrites(lpAdapter,2)==FALSE)
{
AfxMessageBox("warning: Unable to send more than one packet in a single write!\n");
}
if(PacketSendPacket(lpAdapter,pPacket,TRUE)==FALSE)
{
AfxMessageBox("Error sending the packets!\n");
return ;
}
}
}

kingzai 2002-07-13
  • 打赏
  • 举报
回复
xuying:我做的嗅探功能可以实现呀,证明网卡的选择应该是正确的。上面的代码有些不明晰,我改成如下。不会死机,但也没反应了。
void WINAPI SendRSTPackage(LPPACKET lpPacket,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;
///////////////////////////////////////////////////////
//构造一份报文
IP_HEADER ipHeader;
TCP_HEADER tcpHeader;
PSD_HEADER psdHeader;
char szSendBuf[100]={0};
//填充IP首部
ipHeader.h_lenver=pIpHdr->h_lenver;
ipHeader.tos=pIpHdr->tos;
ipHeader.tot_len=pIpHdr->tot_len;
ipHeader.id=pIpHdr->id;
ipHeader.frag_off=pIpHdr->frag_off;
ipHeader.ttl=pIpHdr->ttl;
ipHeader.protocol=pIpHdr->protocol;
ipHeader.check=pIpHdr->check;
ipHeader.saddr=pIpHdr->saddr;//服务器IP地址
ipHeader.daddr=pIpHdr->daddr; //客户端IP地址

//填充TCP首部
tcpHeader.dest=pTcpHdr->dest;//目的端口号,
tcpHeader.source=pTcpHdr->source;//源端口号 (pTcpHdr->dest)这是因为我们要假冒从服务器发出的包
tcpHeader.seq=pTcpHdr->seq;//32位序列号
tcpHeader.ack_seq=pTcpHdr->ack_seq;//32位确认号
tcpHeader.th_lenres=pTcpHdr->th_lenres;
tcpHeader.th_flag=4; //修改这里来实现不同的标志位探测,2是SYN,1是FIN,16是ACK,4是RST
tcpHeader.window=pTcpHdr->window;
tcpHeader.urg_ptr=pTcpHdr->urg_ptr;
tcpHeader.check=pTcpHdr->check;
//填充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, &ipHeader, sizeof(ipHeader));
memcpy(szSendBuf+sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
memset(szSendBuf+sizeof(ipHeader)+sizeof(tcpHeader), 0, 4);
ipHeader.check=checksum((USHORT *)szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader));
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,100);
//改成PacketInitPacket(pPacket,szSendBuf,strlen(szSendBuf));立马死机,屡试不爽。

// capture the packet
if(PacketSetNumWrites(lpAdapter,2)==FALSE)
{
AfxMessageBox("warning: Unable to send more than one packet in a single write!\n");
}
if(PacketSendPacket(lpAdapter,pPacket,TRUE)==FALSE)
{
AfxMessageBox("Error sending the packets!\n");
return ;
}
}
}

kingzai 2002-07-13
  • 打赏
  • 举报
回复
xuying,我嗅探得来的数据是正确的呀,证明网卡选择是正确的,上面的代码我又改了一些。
代码如下:
//当符合过滤条件时,发送一条带RST标志的报文
void WINAPI SendRSTPackage(LPPACKET lpPacket,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;
///////////////////////////////////////////////////////
//构造一份报文
IP_HEADER ipHeader;
TCP_HEADER tcpHeader;
PSD_HEADER psdHeader;
char szSendBuf[100]={0};
//填充IP首部
ipHeader.h_lenver=pIpHdr->h_lenver;
ipHeader.tos=pIpHdr->tos;
ipHeader.tot_len=pIpHdr->tot_len;
ipHeader.id=pIpHdr->id;
ipHeader.frag_off=pIpHdr->frag_off;
ipHeader.ttl=pIpHdr->ttl;
ipHeader.protocol=pIpHdr->protocol;
ipHeader.check=pIpHdr->check;
ipHeader.saddr=pIpHdr->saddr;//服务器IP地址
ipHeader.daddr=pIpHdr->daddr; //客户端IP地址

//填充TCP首部
tcpHeader.dest=pTcpHdr->dest;//目的端口号,
tcpHeader.source=pTcpHdr->source;//源端口号 (pTcpHdr->dest)这是因为我们要假冒从服务器发出的包
tcpHeader.seq=pTcpHdr->seq;//32位序列号
tcpHeader.ack_seq=pTcpHdr->ack_seq;//32位确认号
tcpHeader.th_lenres=pTcpHdr->th_lenres;
tcpHeader.th_flag=4; //修改这里来实现不同的标志位探测,2是SYN,1是FIN,16是ACK,4是RST
tcpHeader.window=pTcpHdr->window;
tcpHeader.urg_ptr=pTcpHdr->urg_ptr;
tcpHeader.check=pTcpHdr->check;
//填充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, &ipHeader, sizeof(ipHeader));
memcpy(szSendBuf+sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
memset(szSendBuf+sizeof(ipHeader)+sizeof(tcpHeader), 0, 4);
ipHeader.check=checksum((USHORT *)szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader));
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,100);
// capture the packet
if(PacketSetNumWrites(lpAdapter,2)==FALSE)
{
AfxMessageBox("warning: Unable to send more than one packet in a single write!\n");
}
if(PacketSendPacket(lpAdapter,pPacket,TRUE)==FALSE)
{
AfxMessageBox("Error sending the packets!\n");
return ;
}
}
}
xuying 2002-07-13
  • 打赏
  • 举报
回复
怀疑是你的lpAdapter有问题,检查一下指向了一个有效的网卡?
kingzai 2002-07-13
  • 打赏
  • 举报
回复
if(PacketSendPacket(lpAdapter,pPacket,TRUE)==FALSE)
{
AfxMessageBox("Error sending the packets!\n");
return ;
}
到SendPacket的时候就死机了,因为死机,报文都捕获不到。估计肯定是构造包出了问题,只是我现在还查不到参数错在哪里
xuying 2002-07-12
  • 打赏
  • 举报
回复
1. 跟踪一下,定位到死机的那一条语句。
2. 用sniffer或者windump检查一下捕获和发送的报文有无问题。
kingzai 2002-07-12
  • 打赏
  • 举报
回复
是从截获的包中得到的,是服务器回应客户请求的应答包,确认号没什么关系吧,请求包和应答包中的确认号是相同的。
ExitWindows 2002-07-12
  • 打赏
  • 举报
回复
你的ack_seq是怎么算出来的啊。
kingzai 2002-07-12
  • 打赏
  • 举报
回复
//当符合过滤条件时,发送一条带RST标志的报文
void WINAPI SendRSTPackage(LPPACKET lpPacket,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;

///////////////////////////////////////////////////////
//构造一份报文
IP_HEADER ipHeader;
TCP_HEADER tcpHeader;
PSD_HEADER psdHeader;
char szSendBuf[100]={0};
//填充IP首部
ipHeader.h_lenver=(4<<4 | sizeof(ipHeader)/sizeof(unsigned long));
// ipHeader.tos=0;
ipHeader.tot_len=htons(sizeof(ipHeader)+sizeof(tcpHeader));
ipHeader.id=1;
ipHeader.frag_off=0;
ipHeader.ttl=128;
ipHeader.protocol=IPPROTO_TCP;
ipHeader.check=0;
ipHeader.saddr=pIpHdr->saddr;//服务器IP地址
ipHeader.daddr=pIpHdr->daddr; //客户端IP地址

//填充TCP首部
tcpHeader.dest=pTcpHdr->dest;//目的端口号,
tcpHeader.source=pTcpHdr->source;//源端口号
tcpHeader.seq=pTcpHdr->seq;//32位序列号
tcpHeader.ack_seq=pTcpHdr->ack_seq;//32位确认号
tcpHeader.th_lenres=(sizeof(tcpHeader)/4<<4|0);
tcpHeader.th_flag=4; //修改这里来实现不同的标志位探测,2是SYN,1是FIN,16是ACK,4是RST
tcpHeader.window=htons(512);
tcpHeader.urg_ptr=0;
tcpHeader.check=0;
//填充TCP伪首部
psdHeader.saddr=ipHeader.daddr;
psdHeader.daddr=ipHeader.saddr;
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, &ipHeader, sizeof(ipHeader));
memcpy(szSendBuf+sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
memset(szSendBuf+sizeof(ipHeader)+sizeof(tcpHeader), 0, 4);
ipHeader.check=checksum((USHORT *)szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader));
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));
pPacket->Buffer=szSendBuf;
PacketInitPacket(pPacket,pPacket->Buffer,strlen(szSendBuf));
// capture the packet
if(PacketSetNumWrites(lpAdapter,1)==FALSE)
{
AfxMessageBox("warning: Unable to send more than one packet in a single write!\n");
}
if(PacketSendPacket(lpAdapter,pPacket,TRUE)==FALSE)
{
AfxMessageBox("Error sending the packets!\n");
return ;
}
}
}
//这是现在的代码,某些参数我猜想有问题。
wordsgolden 2002-07-12
  • 打赏
  • 举报
回复
おもしろいですね

 私の違いことと同じです

楽しみ!
kingzai 2002-07-12
  • 打赏
  • 举报
回复
ksyou:
我正在找我程序的BUG,你去找找网上其它的源代码把,很多的。
xuying:
我差点就以为这种方法会导致客户端死机呢,这样可能会遭致被人狂扁,看来是我程序上的问题。上面的程序有点问题,改了一些,但还是有BUG。
我把我的思路和流程说一下把,
1。截获报文,这里没有问题,只是抓包而已。
2。当我截获到从服务器发到客户端的回应报文后,得到源端口,目的端口,序列号等等,相信这些也是没问题的。
3。根据序列号构造报文,这段代码和网上通用的代码很相似,但问题可能就出在这里。(是否报文不正确??)
4。发送,就几行代码
5。死机。。。
6。晕倒


xuying 2002-07-12
  • 打赏
  • 举报
回复
1. 不会重起的,RST报文只是中止TCP连接。
2. 这应该是最好的方法了。
ksyou 2002-07-12
  • 打赏
  • 举报
回复
kingzai:能否给我一个完整的程序?我现在在学习着方面的东西,谢谢!
我的MAIL:

YY0_YY1@163.NET
加载更多回复(5)

4,356

社区成员

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

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