WinPCAP封包協議分析

NO IMAGE

對WINPCAP簡單封裝,直接看程式碼吧。

標頭檔案:

#pragma once
#include <pcap.h>
#include <string>

class CNetCap
{
public:
CNetCap(void);
virtual ~CNetCap(void);
pcap_if_t * m_dDevice;
pcap_if_t * m_dAllDevice;
pcap_t * m_fCap ;
u_int m_nDriverNum;
char m_bErrorBuf[PCAP_ERRBUF_SIZE];
int m_nRes;
struct pcap_pkthdr * m_sHeader;
u_char * m_cPktData ;
public:
pcap_if_t * GetAllDevice();
pcap_if_t * SelectOneDevice(int num, pcap_if_t * allDevice);
void StartCap(int num, pcap_handler handler, std::string filter);
/* prototype of the packet handler */
// virtual void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) = 0;
};

實現 :

#include “NetCap.h”
#include <iostream>

CNetCap::CNetCap(void)
{
}

CNetCap::~CNetCap(void)
{
}

pcap_if_t * CNetCap::GetAllDevice()
{
pcap_if_t * allDevice ;
if (pcap_findalldevs(&allDevice, m_bErrorBuf) == -1)
{
fprintf(stderr,”Error in pcap_findalldevs_ex: %s\n”, m_bErrorBuf);
return NULL;
}
return allDevice;
}

pcap_if_t * CNetCap::SelectOneDevice(int num, pcap_if_t * allDevice)

int i = 0;
pcap_if_t * selectDevice;
/* Print the list */
for(selectDevice=allDevice; selectDevice; selectDevice=selectDevice->next)
{
printf(“%d. %s\n    “, i, selectDevice->name);
if (selectDevice->description)
printf(” (%s)\n”, selectDevice->description);
else
printf(” (No description available)\n”);
}
if(i == 0)
{
std::cout<<“No interfaces found! Make sure WinPcap is installed.\n”;
return NULL;
}

if (num < 1 || num > i)
{
std::cout<<“Interface number out of range.\n”;
/* Free the device list */
pcap_freealldevs(allDevice);
return NULL;
}

for (selectDevice=allDevice, i=0; i< num-1 ;selectDevice=selectDevice->next, i );
return selectDevice;
}

void CNetCap::StartCap(int sNum, pcap_handler handler, std::string filter)
{
bpf_u_int32 NetMask;
struct bpf_program fcode;

if((m_dAllDevice = GetAllDevice()) == NULL)
{
std::cout<<“查詢裝置錯誤!!”<<std::endl;
return;
}
m_dDevice = SelectOneDevice(sNum, m_dAllDevice);
m_fCap = pcap_open_live(m_dDevice->name, 
65536,
1, 
1000,
m_bErrorBuf);
if(m_fCap == NULL)
{
std::cout<<“開啟裝置錯誤!!”<<std::endl;
return;
}
pcap_freealldevs(m_dAllDevice);
NetMask=0xffffff;
if(pcap_compile(m_fCap, &fcode, filter.c_str(), 1, NetMask) < 0)
{
fprintf(stderr,”\nError compiling filter: wrong syntax.\n”);

pcap_close(m_fCap);
return;
}
//set the filter
if(pcap_setfilter(m_fCap, &fcode)<0)
{
fprintf(stderr,”\nError setting the filter\n”);
pcap_close(m_fCap);
return;
}
pcap_loop(m_fCap, 0, handler, NULL);

pcap_close(m_fCap);  
}

呼叫 :

#include “NetCap.h”
#include <iostream>
#include <winsock.h> 
using namespace std;

/* 4 bytes IP address */
typedef struct ip_address
{
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
}ip_address;

/* IPv4 header */
typedef struct ip_header
{
u_char
ver_ihl; // Version (4 bits) Internet header length (4 bits)
u_char
tos; // Type of service 
u_short tlen;
// Total length 
u_short identification; // Identification
u_short flags_fo;
// Flags (3 bits) Fragment offset (13 bits)
u_char
ttl; // Time to live
u_char
proto; // Protocol
u_short crc;
// Header checksum
ip_address
saddr; // Source address
ip_address
daddr; // Destination address
u_int op_pad;
// Option Padding
}ip_header;
typedef struct tcp_header
{
u_short  sport;//16位源埠
u_short dport;//目的埠
u_int seq;//32位序列號
u_int ack;//32位確認號
u_char lenres;//4位首部長度/6位保留字
u_char flag;//6位標誌位
u_short win;//16位視窗大小
u_short sum;//16位檢驗和
u_short urp;//16位緊急資料偏移量
} tcp_hearder;

實現 PACKET_HANDLER即可

void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)