1 在winpcap官网上,下载WpdPack的二次开发包
2 配置include和lib的路径,引用wpcap.lib和packet.lib,定义WPCAP和HAVE_REMOTE的宏
3 以抓TCP包,并打印源IP和目的IP为例子,做简单分析。
#include <iostream>
#include "pcap.h"
using namespace std;
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
int srcport=pkt_data[34]<<8|pkt_data[35];
int dstport=pkt_data[36]<<8|pkt_data[37];
printf("source ip:%d.%d.%d.%d:%d| ",pkt_data[26],pkt_data[27],pkt_data[28],pkt_data[29],srcport);
printf("dst ip:%d.%d.%d.%d:%d\n",pkt_data[30],pkt_data[31],pkt_data[32],pkt_data[33],dstport);
}
int main(int argc, char* argv[])
{
char errbuf[PCAP_ERRBUF_SIZE], *devStr;
char *szName = "tcp";//tpkt
pcap_if_t *alldevs;
/* 获得设备列表 */
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
{
fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
/* 跳转到已选设备 */
for (pcap_if_t *d = alldevs; d; d = d->next)
{
/* 打开适配器 */
pcap_t *fp = pcap_open(d->name, // 监听的适配器名称
65536, // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
PCAP_OPENFLAG_PROMISCUOUS, // 混杂模式
1000, // 读取超时时间
NULL, // 远程机器验证
errbuf); // 错误缓冲池
/* 检查数据链路层,为了简单,我们只考虑以太网 */
if (pcap_datalink(fp) != DLT_EN10MB)
{
fprintf(stderr, "\nThis program works only on Ethernet networks.\n");
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return -1;
}
u_int netmask;
if (d->addresses != NULL)
/* 获得接口第一个地址的掩码 */
netmask = ((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
else
/* 如果接口没有地址,那么我们假设一个C类的掩码 */
netmask = 0xffffff;
struct bpf_program fcode;
//编译过滤器
if (pcap_compile(fp, &fcode, szName, 1, netmask) <0)
{
fprintf(stderr, "\nUnable to compile the packet filter. Check the syntax.\n");
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return -1;
}
//设置过滤器
if (pcap_setfilter(fp, &fcode)<0)
{
fprintf(stderr, "\nError setting the filter.\n");
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return -1;
}
//myLoger.saveLog("2");
//设置缓冲区
pcap_setbuff(fp, 1024 * 1024 * 10);
pcap_setuserbuffer(fp, 1024 * 1024 * 10);
pcap_loop(fp, 0, packet_handler, NULL);
}
getchar();
}
需要说明:
1.szName是wireshark上的包过滤条件,用来初步筛选需要处理的包;
2.packet_handler函数,是自定义处理方法,用来仔细的处理包。
3.对应IPv4,在数据链路层是14个字节,网络层是20个字节,TCP层是20个字节,由于14+20是固定长度,所以直接取地址偏移,就可以取源ip地址和目的ip地址了。