WinpCap安裝與網絡截包

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




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章