一.Winpcap简介
Winpcap是UNIX下的libpcap移植到windows下的产物,他是一个freeandopensource的项目。Winpcap工作于驱动(Driver)层,所以能以很高的效率进行网络操作。
Winpcap提供了以下强大的功能:
1.捕获原始的数据包
2.设置filter,只捕获自己敢兴趣的数据包
3.方便的把捕获的数据包输出到文件和从文件输入
4.发送原始的数据包
5.统计网络流量
6.…..(其它还有很多,我不知道了)
二.Winpcap的安装使用方法
1.到http://winpcap.polito.it下载winpcap的安装包,程序员开发包。
2.执行安装包,这样你的机子就能运行winpcap程序了
3.解压开发包,在VC的option的include和lib中加入winpcap的
include和lib
4.在你的程序中加入#include<pcap.h>,#include<remote-ext.h>.然后在工程的setting中加入预定义宏:WPCAP,HAVE_REMOTE.导入wpcap.lib库
5.就可以编写wpcap程序了
三.Winpcap的一些基本的功能的实现
一)捕获数据包
1. 枚举所有的可用的设备[pcap_findalldevs_ex](可选)
2. 通过名字打开一个设备[pcap_open()]
在这里可以打开一个文件,只是在打开这个文件之前需要通过pcap_createsrcstr创建相应的namestring
3. 设置Filter[pcap_compile,pcap_setfilter](可选)
4. 捕获数据
有几种捕获数据的方法(捕获数据的数据都是最原始的数据包,即包含数据链路层的数据头)
a. 是以回调的方式[pcap_loop,pcap_dispatch()].
这两种方法基本相同,底层收集数据包,当满足一定的条件(timeout或者缓冲区满),就会调用回调函数,把收集到的原始数据包s,交给用户。他们返回的数据缓冲区包含多个包
b. pcap_next_ex()的方式
每当一个包到到达以后,pcap_next_ex就会返回,返回的数据缓冲区里只包涵一个包。
二)发送包
Winpcap中有发送单个包和发送多个包的方法。这里只说说发送单个包
1.通过名字打开一个设备[pcap_open]
2.自己构造一个原始数据包(这个数据包会不经过任何处理就发送出去,所以必须把包中的各个字段设置好。另外这个数据包是包含数据链路层报头的)
3.使用pcap_sendpacket()发送数据包
三)统计网络流量
1.通过名字打开一个设备[pcap_open]
通过 read_timeout来设置统计的时间间隔
2.设置filter[pcap_compile,pcap_setfilter](可选)
3. 设置设备的为统计模式[pcap_setmode(MODE_STAT);]
4. 开始统计,pcap_loop/pcap_dispatch()
5.在回调函数中的参数中就包含了统计信息,如下图:
四.总结
这些东西都是我在学习winpcap的过程中的一些经验和总结。由于我学习winpcap的时间很匆忙,只是按照stepbystepguide来学习的,所以我对于winpcap的理解也就只能局限与此,希望能在以后有机会深入学习
/
//下面是一个应用winpcap写的一个网络流量统计的例子,
//nettraffic.cppefinestheentrypointfortheconsoleapplication.
//
#include"stdafx.h"
#include<pcap.h>
#include<remote-ext.h>
#include<iostream>
#include<winsock2.h>
usingnamespacestd;
//------------------------------------------------------------------------
//------------------------------------------------------------------------
voiddispatcher_handler(u_char*user_data,conststructpcap_pkthdr*pkthdr,constu_char*pktdata);
//------------------------------------------------------------------------
intmain(intargc,char*argv[])
{
int i;
pcap_if_t* alldevs;
pcap_if_t* dev;
char errorbuf[PCAP_ERRBUF_SIZE];
int choice;
pcap_t* stathandle;
WSADATA wsadata;
structtimeval timestamp;
if(WSAStartup(MAKEWORD(2,2),&wsadata)!=0)
{
cerr<<"WSAStartupfailed["<<WSAGetLastError()<<"]"<<endl;
return(-1);
}
//enumalldevice
if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&alldevs,errorbuf)==-1)
{
WSACleanup();
cerr<<"pcap_findalldevs_exfailed!("<<errorbuf<<""<<endl;
return(-1);
}
for(i=0,dev=alldevs;dev!=NULL;dev=dev->next)
{
cout<<++i<<'/t'<<dev->name<<endl;
}
if(i==0)
{
WSACleanup();
cerr<<"nodevicefound!"<<endl;
return(-2);
}
//letuserchoice
while(1)
{
cout<<"pleasechoiceadevice:";
cin>>choice;
if(choice>=1&& choice<=i)
break;
cerr<<"inputerror,youshallchoiceadevicefromuponlist"<<endl;
}
//movetothechoicedevice
for(i=0,dev=alldevs;i<choice-1;i++,dev=dev->next);
if((stathandle=pcap_open(dev->name,
100,
PCAP_OPENFLAG_PROMISCUOUS,
500,
NULL,errorbuf))==NULL)
{
cerr<<"opendevicefailed![device:"<<dev->name<<"]"
<<errorbuf<<endl;
pcap_freealldevs(alldevs);
WSACleanup();
return(-3);
}
cout<<"isStat"<<dev->name<<"..."<<endl;
pcap_freealldevs(alldevs);
pcap_setmode(stathandle,MODE_STAT);
timestamp.tv_sec=0;
timestamp.tv_usec=0;
pcap_loop(stathandle,0,dispatcher_handler,(unsignedchar*)×tamp);
pcap_close(stathandle);
return0;
}
//------------------------------------------------------------------------
voiddispatcher_handler(u_char*user_data,conststructpcap_pkthdr*pkthdr,constu_char*pktdata)
{
staticstructtimeval tstamp=*((structtimeval*)user_data);
LARGE_INTEGER Bps,Pps;
unsignedlong delay;
char strtime[32];
delay=(pkthdr->ts.tv_sec-tstamp.tv_sec)*1000000-tstamp.tv_usec+pkthdr->ts.tv_usec;
Pps.QuadPart=((*(LONGLONG*)(pktdata))*1000000)/delay;
Bps.QuadPart=((*(LONGLONG*)(pktdata+8))*1000000)/delay;
structtm*ltime=localtime(&(pkthdr->ts.tv_sec));
strftime(strtime,sizeof(strtime),"%H:%M:%S",ltime);
printf("%s:",strtime);
printf("/tPps=%I64u/tBps=%I64u/r/n",Pps.QuadPart,Bps.QuadPart);
tstamp=pkthdr->ts;
}
Winpcap是UNIX下的libpcap移植到windows下的产物,他是一个freeandopensource的项目。Winpcap工作于驱动(Driver)层,所以能以很高的效率进行网络操作。
Winpcap提供了以下强大的功能:
1.捕获原始的数据包
2.设置filter,只捕获自己敢兴趣的数据包
3.方便的把捕获的数据包输出到文件和从文件输入
4.发送原始的数据包
5.统计网络流量
6.…..(其它还有很多,我不知道了)
二.Winpcap的安装使用方法
1.到http://winpcap.polito.it下载winpcap的安装包,程序员开发包。
2.执行安装包,这样你的机子就能运行winpcap程序了
3.解压开发包,在VC的option的include和lib中加入winpcap的
include和lib
4.在你的程序中加入#include<pcap.h>,#include<remote-ext.h>.然后在工程的setting中加入预定义宏:WPCAP,HAVE_REMOTE.导入wpcap.lib库
5.就可以编写wpcap程序了
三.Winpcap的一些基本的功能的实现
一)捕获数据包
1. 枚举所有的可用的设备[pcap_findalldevs_ex](可选)
2. 通过名字打开一个设备[pcap_open()]
在这里可以打开一个文件,只是在打开这个文件之前需要通过pcap_createsrcstr创建相应的namestring
3. 设置Filter[pcap_compile,pcap_setfilter](可选)
4. 捕获数据
有几种捕获数据的方法(捕获数据的数据都是最原始的数据包,即包含数据链路层的数据头)
a. 是以回调的方式[pcap_loop,pcap_dispatch()].
这两种方法基本相同,底层收集数据包,当满足一定的条件(timeout或者缓冲区满),就会调用回调函数,把收集到的原始数据包s,交给用户。他们返回的数据缓冲区包含多个包
b. pcap_next_ex()的方式
每当一个包到到达以后,pcap_next_ex就会返回,返回的数据缓冲区里只包涵一个包。
二)发送包
Winpcap中有发送单个包和发送多个包的方法。这里只说说发送单个包
1.通过名字打开一个设备[pcap_open]
2.自己构造一个原始数据包(这个数据包会不经过任何处理就发送出去,所以必须把包中的各个字段设置好。另外这个数据包是包含数据链路层报头的)
3.使用pcap_sendpacket()发送数据包
三)统计网络流量
1.通过名字打开一个设备[pcap_open]
通过 read_timeout来设置统计的时间间隔
2.设置filter[pcap_compile,pcap_setfilter](可选)
3. 设置设备的为统计模式[pcap_setmode(MODE_STAT);]
4. 开始统计,pcap_loop/pcap_dispatch()
5.在回调函数中的参数中就包含了统计信息,如下图:
四.总结
这些东西都是我在学习winpcap的过程中的一些经验和总结。由于我学习winpcap的时间很匆忙,只是按照stepbystepguide来学习的,所以我对于winpcap的理解也就只能局限与此,希望能在以后有机会深入学习
/
//下面是一个应用winpcap写的一个网络流量统计的例子,
//nettraffic.cppefinestheentrypointfortheconsoleapplication.
//
#include"stdafx.h"
#include<pcap.h>
#include<remote-ext.h>
#include<iostream>
#include<winsock2.h>
usingnamespacestd;
//------------------------------------------------------------------------
//------------------------------------------------------------------------
voiddispatcher_handler(u_char*user_data,conststructpcap_pkthdr*pkthdr,constu_char*pktdata);
//------------------------------------------------------------------------
intmain(intargc,char*argv[])
{
int i;
pcap_if_t* alldevs;
pcap_if_t* dev;
char errorbuf[PCAP_ERRBUF_SIZE];
int choice;
pcap_t* stathandle;
WSADATA wsadata;
structtimeval timestamp;
if(WSAStartup(MAKEWORD(2,2),&wsadata)!=0)
{
cerr<<"WSAStartupfailed["<<WSAGetLastError()<<"]"<<endl;
return(-1);
}
//enumalldevice
if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&alldevs,errorbuf)==-1)
{
WSACleanup();
cerr<<"pcap_findalldevs_exfailed!("<<errorbuf<<""<<endl;
return(-1);
}
for(i=0,dev=alldevs;dev!=NULL;dev=dev->next)
{
cout<<++i<<'/t'<<dev->name<<endl;
}
if(i==0)
{
WSACleanup();
cerr<<"nodevicefound!"<<endl;
return(-2);
}
//letuserchoice
while(1)
{
cout<<"pleasechoiceadevice:";
cin>>choice;
if(choice>=1&& choice<=i)
break;
cerr<<"inputerror,youshallchoiceadevicefromuponlist"<<endl;
}
//movetothechoicedevice
for(i=0,dev=alldevs;i<choice-1;i++,dev=dev->next);
if((stathandle=pcap_open(dev->name,
100,
PCAP_OPENFLAG_PROMISCUOUS,
500,
NULL,errorbuf))==NULL)
{
cerr<<"opendevicefailed![device:"<<dev->name<<"]"
<<errorbuf<<endl;
pcap_freealldevs(alldevs);
WSACleanup();
return(-3);
}
cout<<"isStat"<<dev->name<<"..."<<endl;
pcap_freealldevs(alldevs);
pcap_setmode(stathandle,MODE_STAT);
timestamp.tv_sec=0;
timestamp.tv_usec=0;
pcap_loop(stathandle,0,dispatcher_handler,(unsignedchar*)×tamp);
pcap_close(stathandle);
return0;
}
//------------------------------------------------------------------------
voiddispatcher_handler(u_char*user_data,conststructpcap_pkthdr*pkthdr,constu_char*pktdata)
{
staticstructtimeval tstamp=*((structtimeval*)user_data);
LARGE_INTEGER Bps,Pps;
unsignedlong delay;
char strtime[32];
delay=(pkthdr->ts.tv_sec-tstamp.tv_sec)*1000000-tstamp.tv_usec+pkthdr->ts.tv_usec;
Pps.QuadPart=((*(LONGLONG*)(pktdata))*1000000)/delay;
Bps.QuadPart=((*(LONGLONG*)(pktdata+8))*1000000)/delay;
structtm*ltime=localtime(&(pkthdr->ts.tv_sec));
strftime(strtime,sizeof(strtime),"%H:%M:%S",ltime);
printf("%s:",strtime);
printf("/tPps=%I64u/tBps=%I64u/r/n",Pps.QuadPart,Bps.QuadPart);
tstamp=pkthdr->ts;
}