关于winpcap截获数据包以及构造伪包!~~急!~急~急!~~
#include <winsock2.h>
#include <ws2tcpip.h>
#define SOURCE_PORT 7234
#define MAX_RECEIVEBYTE 255
#include "protocol.h"
#include "mstcpip.h"
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <iphlpapi.h>
#pragma comment(lib,"iphlpapi.lib")
#pragma comment(lib,"WS2_32")
#pragma comment(lib, "Advapi32.lib")
#include "pcap.h"
int HCchecksum(unsigned short *addr, int len) {
register int sum = 0;
unsigned short answer = 0;
register unsigned short *w = addr;
register int nleft = len;
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
if (nleft == 1) {
sum += htons(*(unsigned char *)w<<8);
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return(answer);
}
int sendTCP_SYNACK(char * szSrcIP, char * szDestIP,unsigned short srcPort,
unsigned short destPort,unsigned int iseq)
{
WSADATA WSAData;
SOCKET sock;
SOCKADDR_IN addr_in;
HCIPHEADER ipHeader;
HCTCPHEADER tcpHeader;
HCPSDHEADER psdHeader;
char szSendBuf[60]={0};
BOOL flag;
int rect,nTimeOver;
if (WSAStartup(MAKEWORD(2,2), &WSAData)!=0)
{
printf("WSAStartup Error!\n");
return false;
}
if ((sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET)
{
printf("Socket Setup Error!\n");
return false;
}
flag=true;
if (setsockopt(sock,IPPROTO_IP, IP_HDRINCL,(char *)&flag,sizeof(flag))==SOCKET_ERROR)
{
printf("setsockopt IP_HDRINCL error!\n");
return false;
}
nTimeOver=1000;
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOver, sizeof(nTimeOver))==SOCKET_ERROR)
{
printf("setsockopt SO_SNDTIMEO error!\n");
return false;
}
addr_in.sin_family=AF_INET;
addr_in.sin_port=htons(destPort);
addr_in.sin_addr.S_un.S_addr=inet_addr(szDestIP);
//
//
//填充IP首部
ipHeader.h_verlen=(4<<4 | sizeof(ipHeader)/sizeof(unsigned long));
ipHeader.tos=0;
ipHeader.total_len=htons(sizeof(ipHeader)+ sizeof(tcpHeader));
ipHeader.ident=1;
ipHeader.frag_and_flags=0;
ipHeader.ttl=128;
ipHeader.proto=IPPROTO_TCP;
ipHeader.checksum=0;
ipHeader.sourceIP=inet_addr(szSrcIP);
ipHeader.destIP=inet_addr(szDestIP);
//填充TCP首部
tcpHeader.th_dport=htons(destPort);
tcpHeader.th_sport=htons(srcPort); //源端口号
tcpHeader.th_seq=htonl(0x12345678);
tcpHeader.th_ack=htonl(iseq+0x01);
printf("ack:%d\n",iseq+0x01);
tcpHeader.th_lenres=(sizeof(tcpHeader)/4<<4|0);
tcpHeader.th_flag=0x13; //修改这里来实现不同的标志位探测,2是SYN,1是FIN,16是ACK探测 等等
tcpHeader.th_win=htons(512);
tcpHeader.th_urp=0;
tcpHeader.th_sum=0;
psdHeader.saddr=ipHeader.sourceIP;
psdHeader.daddr=ipHeader.destIP;
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.th_sum=HCchecksum((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.checksum=HCchecksum((USHORT *)szSendBuf, sizeof(ipHeader) +sizeof(tcpHeader));
memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
rect=sendto(sock, szSendBuf, sizeof(ipHeader)+ sizeof(tcpHeader),
0, (struct sockaddr*)&addr_in, sizeof(addr_in));
if (rect==SOCKET_ERROR)
{
printf("send error!:%d\n",WSAGetLastError());
return false;
}
else
printf("send ok!\n");
closesocket(sock);
WSACleanup();
return 0;
}
void ip_protocol_packet_callback(u_char *argument,const struct pcap_pkthdr*
packet_header,const u_char *packet_content) //解析侦听到的IP数据包
{
HCIPHEADER *pIPhdr = (HCIPHEADER *)(packet_content+14);
in_addr source, dest;
HCTCPHEADER * pTCPhdr;
char szSourceIp[32], szDestIp[32];
// 从IP头中取出源IP地址和目的IP地址
source.S_un.S_addr = pIPhdr->sourceIP;
dest.S_un.S_addr = pIPhdr->destIP;
strcpy(szSourceIp, ::inet_ntoa(source));
strcpy(szDestIp, ::inet_ntoa(dest));
//获得TCP header的起始位置
int iIphLen = sizeof(unsigned long) * (pIPhdr->h_verlen & 0xf);
//printf("iplength:%d\n",iIphLen);
pTCPhdr = (HCTCPHEADER* )(packet_content+14+20);
//判断是否为第一次握手IP数据包,pIPhdr->th_flag=2 即("-s----")
if( (pTCPhdr->th_flag==0x02)&&(pIPhdr->proto==IPPROTO_TCP))
{
printf("发送伪包");
sendTCP_SYNACK(szDestIp,szSourceIp,ntohs(pTCPhdr->th_dport),ntohs(pTCPhdr->th_sport),ntohl(pTCPhdr->th_seq));
}
}
int main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
u_int netmask;
char packet_filter[] = "ip and tcp ";
struct bpf_program fcode;
/* Retrieve the device list */
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
/* Print the list */
for(d=alldevs; d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
if(i==0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return -1;
}
printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);
if(inum < 1 || inum > i)
{
printf("\nInterface number out of range.\n");
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
/* Jump to the selected adapter */
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
/* Open the adapter */
if ( (adhandle= pcap_open_live(d->name, // name of the device
65536, // portion of the packet to capture.
// 65536 grants that the whole packet will be captured on all the MACs.
1, // promiscuous mode
1000, // read timeout
errbuf // error buffer
) ) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n");
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
/* Check the link layer. We support only Ethernet for simplicity. */
if(pcap_datalink(adhandle) != DLT_EN10MB)
{
fprintf(stderr,"\nThis program works only on Ethernet networks.\n");
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
if(d->addresses != NULL)
/* Retrieve the mask of the first address of the interface */
netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
else
/* If the interface is without addresses we suppose to be in a C class network */
netmask=0xffffff;
//compile the filter
if(pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 ){
fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");
//Free the device list
pcap_freealldevs(alldevs);
return -1;
}
//set the filter
if(pcap_setfilter(adhandle, &fcode)<0){
fprintf(stderr,"\nError setting the filter.\n");
// Free the device list
pcap_freealldevs(alldevs);
return -1;
}
printf("\nlistening on %s...\n", d->description);
/* At this point, we don't need any more the device list. Free it */
pcap_freealldevs(alldevs);
/* start the capture */
pcap_loop(adhandle, 0,ip_protocol_packet_callback, NULL);
return 0;
}
以上是 我的程序的源代码,我是用的winpcap截获的包,然后用raw socket 构造的伪包,都可以正常运行,传给发包函数的参数也没问题, 但是就是不可以打断上网,怎么回事呀, 可能是什么问题??请各位朋友们帮帮小弟的忙,!~~大恩不言谢!~~~~~~- -!~

