WinpCap安装:
(一) 首先安装winpcap驱动,可以到winpcap官方网站上下载:http://www.winpcap.org/install/default.htm
安装winpcap驱动后:1. C:\WINDOWS\system32目录下自动生成: wpcap.dll,packet.dll
2. C:\WINDOWS\system32\drivers下自动生成:npf.sys
(二)winpcap-4.0.3配置环境:
在项目->XX属性,选择配置属性:1. c/c++->常规\附加包含目录:D:\WpdPack-4.0.3\Include
->预处理器\预处理器定义:WPCAP
2. 链接器->常规\附加库目录:D:\WpdPack-4.0.3\Lib
->输入\附加依赖项: Packet.lib wpcap.lib ws2_32.lib
网络截包:
获取截获数据包数据段长度
#include <stdlib.h>
#include <stdio.h>
#define WIN32 1
#include "pcap.h"
#include <windows.h>
#pragma comment (lib,"wpcap.lib")
#pragma comment(lib, "ws2_32.lib")
CRITICAL_SECTION cs;
typedef struct mac_hdr
{
unsigned char a;
unsigned char b;
unsigned char c;
unsigned char d;
unsigned char e;
unsigned char f;
unsigned char a1;
unsigned char b2;
unsigned char c3;
unsigned char d4;
unsigned char e5;
unsigned char f6;
short type;
}MAC_HEADER;
typedef struct tcp_hdr //定义TCP首部
{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端口
ULONG th_seq; //32位序列号
ULONG th_ack; //32位确认号
UCHAR th_lenres; //4位首部长度/6位保留字
UCHAR th_flag; //6位标志位
USHORT th_win; //16位窗口大小
USHORT th_sum; //16位校验和
USHORT th_urp; //16位紧急数据偏移量
}TCP_HEADER;
typedef struct ip_hdr //定义IP首部
{
UCHAR h_verlen; //4位首部长度,4位IP版本号
UCHAR tos; //8位服务类型TOS
USHORT total_len; //16位总长度(字节)
USHORT ident; //16位标识
USHORT frag_and_flags; //3位标志位
UCHAR ttl; //8位生存时间 TTL
UCHAR proto; //8位协议 (TCP, UDP 或其他)
USHORT checksum; //16位IP首部校验和
ULONG sourceIP; //32位源IP地址
ULONG destIP; //32位目的IP地址
}IP_HEADER;
void dispatcher_handler_send(u_char *, const struct pcap_pkthdr *, const u_char *);
//void dispatcher_handler_recv(u_char *, const struct pcap_pkthdr *, const u_char *);
DWORD Setoption(pcap_t *adhandle,char *express);
DWORD WINAPI SendThread(LPVOID lparam);
//DWORD WINAPI RecvThread(LPVOID lparam);
//bool recvNotify = false;
bool sendNotify = false;
DWORD g_dwCount = 0;
LARGE_INTEGER recvPacket,sendPacket;
int main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
char errbuf[PCAP_ERRBUF_SIZE];
DWORD dwThreadId;
int error = 0;
/* Retrieve the device list */
if(pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
return -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");
pcap_freealldevs(alldevs);
return -1;
}
/* Jump to the selected adapter */
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
InitializeCriticalSection(&cs);
CreateThread(NULL,0,SendThread,d,0,&dwThreadId);
// CreateThread(NULL,0,RecvThread,d -> name,0,&dwThreadId);
printf("\nlistening on %s...\n", "world");
/* At this point, we don't need any more the device list. Free it */
while(1)
{
if(sendNotify)
{
if(g_dwCount == 30)
{
printf("the server has die!\n");
TerminateProcess(SendThread,0);//关闭进程即关闭响应的端口
break;
}
sendNotify = false;
}
Sleep(10);
}
pcap_freealldevs(alldevs);
return 0;
}
DWORD WINAPI SendThread (LPVOID lparam)
{
pcap_t *adhandle;
struct bpf_program fcode;
u_int netmask;
pcap_if_t* pcap = (pcap_if_t*)lparam;
printf("hello,world,%s\n",pcap->name);
EnterCriticalSection(&cs);
if ((adhandle= pcap_open_live(pcap->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 (nonzero means promiscuous)
1000, // read timeout
NULL // error buffer
)) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", pcap->name);
LeaveCriticalSection(&cs);
return -1;
}
LeaveCriticalSection(&cs);
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(pcap->addresses != NULL)
/* Retrieve the mask of the first address of the interface */
netmask=((struct sockaddr_in *)(pcap->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;
if (pcap_compile(adhandle, &fcode, "tcp", 1, netmask) <0 )
{
fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");
return 0;
}
if (pcap_setfilter(adhandle, &fcode)<0)
{
fprintf(stderr,"\nError setting the filter.\n");
return 0;
}
pcap_loop(adhandle, 0, dispatcher_handler_send, NULL);
return 0;
/*
pcap_t *adhandle;
u_int netmask;
struct bpf_program fcode;
char errbuf[PCAP_ERRBUF_SIZE];
char *device = (char *)lparam;
EnterCriticalSection(&cs);
if ((adhandle= pcap_open_live(device, // 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 (nonzero means promiscuous)
1000, // read timeout
errbuf // error buffer
)) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", device);
LeaveCriticalSection(&cs);
return -1;
}
LeaveCriticalSection(&cs);
netmask=0xffffff;
//compile the filter
// if (pcap_compile(adhandle, &fcode, "port 80 and tcp and ether src 44:37:E6:00:34:CD", 1, netmask) <0 )
if (pcap_compile(adhandle, &fcode, "tcp", 1, netmask) <0 )
{
fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");
return 0;
}
//set the filter
if (pcap_setfilter(adhandle, &fcode)<0)
{
fprintf(stderr,"\nError setting the filter.\n");
return 0;
}
pcap_setmode(adhandle, MODE_STAT);
printf("TCP traffic summary:\n");
struct timeval st_ts;
pcap_loop(adhandle, 0, dispatcher_handler_send, (PUCHAR)&st_ts);
pcap_close(adhandle);
*/
}
void dispatcher_handler_send(u_char *state, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
IP_HEADER *iph;
TCP_HEADER *tcph;
//MAC_HEADER *mach;
u_int ip_len;
int nIpLen,nTcpLen ;
int nTotalLen;
int nDataLen = 0;
if ( NULL == pkt_data)
{
printf("can't get pkt_data");
return;
}
//(VOID)(state);
iph=(IP_HEADER *)(pkt_data+14);
nTotalLen=nIpLen= ntohs(iph->total_len)+14;
if(nIpLen>0)
printf("ip_total_len = %d\n",nIpLen );
/* 获得IP数据包头部的位置 */
ip_len= (iph->h_verlen & 0xf) * 4;
printf("ip_len is %d\n",ip_len);
/* 获得tcp首部的位置 */
tcph = (TCP_HEADER *) ((u_char*)iph + ip_len);
nTcpLen = (tcph ->th_lenres>>4)*4 ;
printf("tcplen = %d\n",nTcpLen);
// printf("totalLen = %d\n",nTotalLen);
nDataLen = nTotalLen - ip_len - nTcpLen;
printf("datalen = %d\n",nDataLen);
sendNotify = true;
if(nDataLen == 0)
g_dwCount++;
else
g_dwCount = 0;
}