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;
}