winpcap使用方法(winpcap有用吗)
winpcap使用方法(winpcap有用吗),本文通过数据整理汇集了winpcap使用方法(winpcap有用吗)相关信息,下面一起看看。
我们先来百科什么是Winpcap。Winpcap(windows packet capture)是windows平台下一个免费的公共网络访问系统。
它具有以下功能:
1.捕获原始数据包,包括共享网络上每个主机发送/接收的以及相互交换的数据;
2.在数据包发送到应用程序之前,根据自定义规则过滤掉一些特殊的数据包;
3.在网络上发送原始数据包;
4.收集网络交流过程中的统计信息。
从上面的函数来看,这个库文件提供了很多API函数,可以让我们抓取网络上的数据包,统计网络通信的信息。为了更直观的反映这个库文件的作用,我们来看看用这个库文件编写的一个应用软件wireshark。如下图所示,这个界面只是一个抓取数据的小界面。里面有很多设定。有兴趣可以下载一个试试。他可以统计一个局域网内的所有网络信息。
这里重要的一点是,winpcap的主要功能是独立于主机协议(如TCP-IP)发送和接收原始数据包。也就是说,winpcap无法阻止、过滤或控制其他应用程序数据包的发送和接收,它只是监控共享网络上传输的数据包。也就是说WinpCap的主要功能是不能拦截网络中的数据,只能监控里面的数据。
至于WinpCap的结构和原理,我们自然可以忽略。我们只需要知道它的目的!
首先,安装WinpCap 1。首先,让我们看看如何安装WinpCap库。首先,下载WinpCap安装文件。这里有很多版本,可以在官网下载。这里提醒一下,特别注意版本。如果您的版本是4.02,那么您的安装包也必须下载相应的版本。这里请特别注意,可以下载目前稳定的版本。下载安装后就ok了!我这里用的是WinpCap4.02。
2.下载WinpCap开发者包。这里我也提供相同版本的WpdPack4.02。
3.解压后会得到一个目录WpdPack,有四个子目录:Docs Examples-PCAP Examples-Remote Include Lib然后配置VC工具-选项-项目和解决方案-VC目录:
包含文件:WpdPackPathinclude
库文件:WpdPackPathlib
4.完成上述步骤后,您的WinpCap应该安装成功。然后,运行其中提供的例程。有问题就上网查问题。一般来说有以下几个问题:第一个是你需要把wpcap.lib链接库添加到项目的链接库中;第二是你的SDK太老了。你需要添加和更新你的SDK,相应的从官网下载适合你电脑的SDK。这里查错的能力是每个人都能找到相关的网站。只要把错误的英文输入谷歌和百度,大部分都能找到原因。这里是别人的博客,详细介绍了WinPcap常见的安装和操作错误。
第二,各种功能的实现。这里有很多例子,但大部分都是建立在一定基础上的。首先,让我们来看看几个基本功能。这里有一个很好的网站,上面有这个库的所有解释。
1.pcap_if与pcap _ if _ T相同。
/**接口列表中的项目。*/
结构pcap_if {
struct pcap _ if * next
char * name/*要传递给' pcap_open_live()' */的名称
char *描述;/*接口的文本描述,或NULL */struct pcap _ addr *地址。
bpf_u_int32标志;/* PCAP_IF_接口标志*/};
从上面的结构定义可以看出,有五个元素。第一个是pcap_if的链表指向下一个设备接口;第二个是设备的实际名称,是机器可以识别的名称,由pcap_open_live()调用;三是设备的文本描述符,是人能识别的文本符号;第四个是地址指针,指向一系列接口的第一个指针;第五个是标志位。目前这个标志位主要是环回设备。
用户定义的两种类型。
typedef struct pcap pcap _ t;对用户不透明的开放捕获实例描述符提供了wpcap.dll函数来维护其内容。typedef struct pcap _ addr pcap _ addr _ t;接口地址。
堆文件中三个数据包的头,包括时间戳、当前部分的长度和数据包的长度。
struct pcap _ PKT HDR { struct time val ts;/*时间戳*/bpf _ u _ int 32 cap len;/*当前部分的长度*/bpf _ u _ int 32 len;/*此数据包的长度(离线)*/};
1.去拿设备清单。
通常,基于WinPcap编写应用程序的第一件事是获取连接的网络适配器列表。libap和WinPcap都提供了pcap_findalldevs_ex()函数来实现这个功能:这个函数返回一个pcap_if结构的链表,每个链表包含一个适配器的详细信息。值得注意的是,数据字段name和description表示人们能够理解的适配器名称和描述。
看一下下面的简单代码:
这段代码非常简单。首先使用一个API函数获取机器所有网络设备的列表,然后逐个打印出来。
# include ' pcap . h ' main(){ pcap _ if _ t * all devs;pcap _ if _ t * d;inti=0;charerrbuf[PCAP _ ERRBUF _ SIZE];/*获取本地机器设备列表*/if(PCAP _ findalldevs _ ex(PCAP _ src _ if _ string,null/*不需要authis */,alldevs,errbuf)=-1){ fprintf(stderr,' PCAP _ findalldevs _ ex中出错:)exit(1);}/*打印列表*/for(d=all devs;d!=NULLd=d- next){printf('%d. %s ',I,d-name);if(d-description)printf('(% s) n ',d-description);elseprintf('(没有可用的描述) n ');} if(I==0){ printf(' n找不到接口!请确保安装了WinPcap。 n’);返回;}/*不再需要设备列表,释放*/pcap _ freeall devs(all devs);} 2.获取已安装设备的高级信息。在第1课中,(获取设备列表)我们展示了如何获取适配器的基本信息(比如设备的名称和描述)。事实上,WinPcap提供了其他更高级的信息。特别是,pcap_findalldevs_ex()返回的每个pcap_if结构都包含一个pcap_addr结构,它由以下元素组成:
地址列表、掩码列表(每一个都对应于地址列表中的条目)和广播地址列表(每一个都对应于地址列表中的条目)。目的地地址列表(每一个都对应于地址列表中的一个条目)。
# include ' pcap。h ' # ifndef WIN32 # include sys/socket。h #包含网络/输入。h # else #包含Winsock。h # endif//函数原型void if print(pcap _ if _ t * d);char * iptos(u _ long in);char * IP 6 tos(structsockaddr * sockaddr,char*address,intaddrlen);int main(){ pcap _ if _ t * all dev;pcap _ if _ t * d;charerrbuf[PCAP _ ERRBUF _ SIZE 1];char source[PCAP _错误缓冲区_大小1];printf('输入要列出的设备:n''rpcap://==列出本地计算机中的接口n''rpcap://hostname:port==列出远程计算机中的接口n'' (rpcapd守护程序必须已启动并正在运行n ' '并且必须接受'空'身份验证)n''file://foldername==列出给定文件夹中的所有pcap文件nn ' '输入您的选择:');fgets(来源,PCAP_ERRBUF_SIZE,stdin);来源【PCAP _错误缓冲区_大小]=' 0 ';/* 获得接口列表*/if(pcap_findalldevs _ ex(source,NULL,alldevs,err buf){ fprintf(stderr,' pcap _ findalldevs中的错误:%sn ',errbuf);出口(1);}/* 扫描列表并打印每一项*/for(d=所有开发人员;d;d=d-next){ if print(d);} pcap _ freeall devs(所有devs);return1}/*打印所有可用信息*/void if print(pcap _ if _ t * d){ pcap _ addr _ t * a;charip 6 str[128];/* 设备名(Name) */printf('%sn ',d-Name);/* 设备描述(描述)*/if(d-描述)printf(' t描述:%sn ',d-描述);/*环回地址*/printf(' t环回:%sn ',(d标志PCAP _ IF _环回)?是':'否');/* IP地址*/for(a=d-地址;a;a=a-next){ printf(' t地址族:# % d n ',a-addr-sa _ Family);switch(a-addr-sa _ Family){ caseAF _ INET:printf(' t地址族名称:AF _ INET n’);if(a-addr)printf(' t address:% s n ',iptos((structsockaddr _ in *)a-addr)-sin _ addr。s _ addr));if(a-net mask)printf(' tnet mask:% s n ',iptos((structsockaddr _ in *)a-net mask)-sin _ addr。s _ addr));if(a-broad addr)printf(' t广播地址:% s n ',iptos((structsockaddr _ in *)a-broad addr)-sin _ addr。s _ addr));if(a-dstaddr)printf(' t目标地址:%sn ',iptos((structsockaddr _ in *)a-dstaddr)-sin _ addr。s _ addr));打破;caseAF _ inet 6:printf(' t地址家族名称:AF _ inet 6 n’);if(a-addr)printf(' t地址:% s n ',ip6tos(a- addr,ip6str,sizeof(IP 6 str)));打破;默认值:printf(' t地址系列名称:未知 n’);打破;} } printf(' n ');}/* 将数字类型的互联网协议(互联网协议)地址转换成字符串类型的*/#定义iptos缓冲区12 char * iptos(u _ long in){静态char输出[iptos缓冲区][3 * 4 3 1];staticshortwhichu _ char * p;p=(u _ char *)which=(which 1==IPTOSBUFFERS?0:哪个1);sprintf(output[which],' %d.%d.%d.%d ',p[0],p[1],p[2],p[3]);返回输出[which];} char * IP 6 tos(structsockaddr * sockaddr,char*address,intaddrlen){ socklen _ t sockaddrlen;# ifdef win32 sockaddrlen=sizeof(structsockaddr _ in6);# elsesockaddrlen=sizeof(structsockaddr _ storage);#endifif(getnameinfo(sockaddr,sockaddrlen,address,addrlen,NULL,0,NI_NUMERICHOST)!=0)地址=空;返回地址;} 代码里面都有解释,很好理解,而这些应用程序界面函数如果不明白,都可以MSDN就行啦!
3、打开适配器并捕获数据包(利用回调函数实现数据包捕获) 现在,我们已经知道如何获取适配器的信息了,那我们就开始一项更具意义的工作,打开适配器并捕获数据包。在这讲中,我们会编写一个程序,将每一个通过适配器的数据包打印出来。 打开设备的函数是pcap_open()。下面是参数快照,标志和至毫秒的解释说明。
snaplen制定要捕获数据包中的哪些部分。 在一些操作系统中(比如xBSD和Win32),驱动可以被配置成只捕获数据包的初始化部分: 这样可以减少应用程序间复制数据的量,从而
提高捕获效率。本例中,我们将值定为65535,它比我们能遇到的最大的移动式测试装置(移动测试装置)还要大。因此,我们确信我们总能收到完整的数据包。
标志:最最重要的旗是用来指示适配器是否要被设置成混杂模式。 一般情况下,适配器只接收发给它自己的数据包, 而那些在其他机器之间通讯的数据包,将会被丢弃。 相反,如果适
适配器是混杂模式,所以不管这个数据包是否发送给我,我都会捕获它。换句话说,我会捕获所有的数据包。这意味着在共享介质(如总线以太网)中,WinPcap可以捕获其他
主机的所有数据包。大多数用于数据捕获的应用程序会将适配器设置为混杂模式,因此在下面的示例中,我们也将使用混杂模式。
To_ms指定读取数据的超时时间,单位为毫秒(1s=1000ms)。适配器上的读操作(如pcap_dispatch()或pcap_next_ex())将在毫秒内响应,即使它不在网络上。
有可用的数据包。在统计模式下,to_ms也可以用来定义统计时间间隔。将to_ms设置为0意味着没有超时,因此如果没有数据包到达,读取操作将永远不会返回。如果你假设
设置为-1,那么情况正好相反。无论数据包是否到达,读取操作都将立即返回。
# include' pcap.h'/*包处理函数的原型*/void packet _ handler(u _ char * param,conststructpcap _ pkthdr * header,constu _ char * PKT _ data);main(){ pcap _ if _ t * all devs;pcap _ if _ t * d;intinuminti=0;pcap _ t * adhandlecharerrbuf[PCAP _ ERRBUF _ SIZE];/*获取本地设备列表*/if(pcap _ findalldevs _ ex(pcap _ src _ if _ string,null,alldevs,errbuf)=-1){ fprintf(stderr,' pcap _ findalldevs中的错误:% s n ',errbuf);出口(1);}/*打印列表*/for(d=all devs;d;d=d- next){printf('%d. %s ',I,d-name);if(d-description)printf('(% s) n ',d-description);elseprintf('(没有可用的描述) n ');} if(I==0){ printf(' n找不到接口!请确保安装了WinPcap。 n’);return-1;}printf('输入接口号(1-%d):',I);scanf('%d ',inum);if(inum 1 | | inum I){ printf(' n接口号超出范围。 n’);/*释放设备列表*/pcap _ freeall devs(all devs);return-1;}/*跳转到选定的适配器*/for(d=alldevs,I=0;I inum-1;d=d-下一个,I);/*打开设备*/if((ad handle=pcap _ open(d-name,//设备名65536,//65535)保证可以捕获不同数据链路层上每个数据包的所有内容PCAP_OPENFLAG_PROMISCUOUS,//promiscuous mode 1000,//读取超时为NULL,//远程机器认证errbuf //错误缓冲池))==null) {fprintf (stderr,' n无法打开适配器。winpcap不支持% s is ',d-name);/*释放设备列表*/pcap _ freeall devs(all devs);return-1;} printf(' n在%s上侦听.n ',d-描述);/*释放设备列表*/pcap _ freeall devs(all devs);/*开始捕获*/pcap _ loop (adhandle,0,packet _ handler,null);return0}/*每次捕获一个包,libpcap都会自动调用这个回调函数*/void packet _ handler(u _ char * param,conststructpcap _ pkthdr * header,constu _ char * PKT _ data){ struct TM * ltime;chartimestr[16];时间_本地_电视_秒;/*将时间戳转换成可识别的格式*/local _ TV _ sec=header-ts . TV _ sec;ltime=local time(local _ TV _ sec);strftime( timestr,sizeoftimestr,' %H:%M:%S ',ltime);printf('%s,%.6d len:%dn ',timestr,header- ts.tv_usec,header-len);}本网站是一个提供个人知识管理的网络存储空间。所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请一键举报。
更多winpcap使用方法(winpcap有用吗)相关信息请关注本站,本文仅仅做为展示!