资源预览内容
第1页 / 共200页
第2页 / 共200页
第3页 / 共200页
第4页 / 共200页
第5页 / 共200页
第6页 / 共200页
第7页 / 共200页
第8页 / 共200页
第9页 / 共200页
第10页 / 共200页
亲,该文档总共200页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
密密密密WinPcap 中文技术文档4.0.1 作者: The WinPcap Team 作者主页: http:/www.winpcap.org 模块 WinPcap用户指南 o 定义 o 输出函数 o 过滤串表达式的语法 o 使用WinPcap编程 o WinPcap教程: 循序渐进教您使用WinPcap 获取设备列表 获取已安装设备的高级信息 打开适配器并捕获数据包 不用回调方法捕获数据包 过滤数据包 分析数据包 处理脱机堆文件 发送数据包 收集并统计网络流量 WinPcap核心资料 o NPF驱动核心指南 NPF结构与定义 NPF函数o Packet.dll - 数据包驱动API o 如何编译WinPcap 远程捕获 o 输出结构与定义 o 外部函数. 对于提供远程捕获的函数引用, 请参阅WinPcap 输出函数 章节的 Windows-specific Extensions . o 核心数据结构与定义 介绍本手册提供了WinPcap编程接口的描述及其源代码。它与详尽的WinPcap核心资料一起,为编程人员提供了详细的函数与结构的描述,同时也提供了若干教程和程序范例。 您可以点击页面顶部的导航链接,或者使用页面左边的树形控件,来跳转到您感兴趣的内容。 本文档使用 the Doxygen documentation system创建,您可以登录 http:/www.doxygen.org 阅览相关内容。 什么是WinPcapWinPcap是一个基于Win32平台的,用于捕获网络数据包并进行分析的开源库.大多数网络应用程序通过被广泛使用的操作系统元件来访问网络,比如sockets。 这是一种简单的实现方式,因为操作系统已经妥善处理了底层具体实现细节(比如协议处理,封装数据包等等),并且提供了一个与读写文件类似的,令人熟悉的接口。 然而,有些时候,这种“简单的方式”并不能满足任务的需求,因为有些应用程序需要直接访问网络中的数据包。也就是说,那些应用程序需要访问原始数据包,即没有被操作系统利用网络协议处理过的数据包。WinPcap产生的目的,就是为Win32应用程序提供这种访问方式; WinPcap提供了以下功能 捕获原始数据包,无论它是发往某台机器的,还是在其他设备(共享媒介)上进行交换的 在数据包发送给某应用程序前,根据用户指定的规则过滤数据包 将原始数据包通过网络发送出去 收集并统计网络流量信息 以上这些功能需要借助安装在Win32内核中的网络设备驱动程序才能实现,再加上几个动态链接库DLL。所有这些功能都能通过一个强大的编程接口来表现出来,易于开发,并能在不同的操作系统上使用。这本手册的主要目标是在一些程序范例的帮助下,叙述这些编程接口的使用。 如果您现在就想开始摸索这些功能,您可以直接进入 WinPcap用户手册.哪些程序在使用WinPcapWinPcap可以被用来制作许多类型的网络工具,比如具有分析,解决纷争,安全和监视功能的工具。特别地,一些基于WinPcap的典型应用有: 网络与协议分析器 (network and protocol analyzers) 网络监视器 (network monitors) 网络流量记录器 (traffic loggers) 网络流量发生器 (traffic generators) 用户级网桥及路由 (user-level bridges and routers) 网络入侵检测系统 (network intrusion detection systems (NIDS) 网络扫描器 (network scanners) 安全工具 (security tools) 什么是WinPcap做不到的WinPcap能 独立地 通过主机协议发送和接受数据,如同TCP-IP。这就意味着WinPcap不能阻止、过滤或操纵同一机器上的其他应用程序的通讯:它仅仅能简单地监视在网络上传输的数据包。所以,它不能提供类似网络流量控制、服务质量调度和个人防火墙之类的支持。 本手册的目标本手册的目的是提供一个全面而简单的方法来让您浏览WinPcap的设计文档。你会找到两个主要部分: WinPcap用户指南 和 WinPcap核心资料.第一部分内容主要适合那些需要利用WinPcap开发应用程序的编程人员: 它包含了WinPcap API的所有函数和数据结构的信息, 说明部分解释了如何编写一个数据包过滤器,而另一个页面则解释了如何将它包含到应用程序中。一个教程也提供了若干个程序范例,您可以使用它来循序渐进地学习WinPcap API的基本使用方法,不过有时候,它也会提供一些高级应用的代码片断。 第二部分内容主要为WinPcap的开发、维护人员,以及那些希望了解系统工作原理的人士而准备。它描述了WinPcap的主要设计方法,并解释了它是如何工作的。另外,它阐述了完整的设备驱动的数据结构及源代码,packet.dll的接口以及底层的WinPcap的API。如果您想了解WinPcap内部发生了什么,或者您想去扩展它,那么请您阅读此部分内容。 附加文档最新最及时的文档,请访问 http:/www.winpcap.org/docs/ 特别地,如果您对WinPcap的系统结构和核心内容感兴趣,我们建议您阅读下列内容 Fulvio Risso, Loris Degioanni, An Architecture for High Performance Network Analysis, Proceedings of the 6th IEEE Symposium on Computers and Communications (ISCC 2001), Hammamet, Tunisia, July 2001 Loris Degioanni, Mario Baldi, Fulvio Risso and Gianluca Varenni, Profiling and Optimization of Software-Based Network-Analysis Applications, Proceedings of the 15th IEEE Symposium on Computer Architecture and High Performance Computing (SBAC-PAD 2003), Sao Paulo, Brasil, November 2003 Loris Degioanni, Development of an Architecture for Packet Capture and Network Traffic Analysis, Graduation Thesis, Politecnico Di Torino (Turin, Italy, Mar. 2000) 术语 为了文献的一致性, 我们会使用术语 数据包(packet) ,尽管用术语 帧(frame) 会更加准确,因为捕获过程是在数据链路层完成的,并且数据链路首部也包含在被捕获的数据中。 本文档中使用的术语 Win9x 表示与Windows95同一体系的微软操作系统,如Windows 98和Windows ME。 术语 WinNTx 表示基于NT内核的操作系统,从Windows NT 4开始,包含了Windows 2000,Windows XP,Windows Server 2003等 附注我们主要会致力于开发基于Windows NT/2000/XP/2003版本的WinPcap及其相关文档。这一选择是基于这样一个事实,大多数WinPcap用户都工作在NTx系统上,而且9x技术已经被微软放弃。此外,我们假定,使用PC机来完成类似网络分析这样高级任务的用户,都会安装高级的操作系统。鉴于这个原因,本文档将参考WinNTx的驱动和API。Win9x版本在概念上很类似,不过有时在执行上有些不同。在有些场合,Win9x版本的API缺少一些高级功能。这本手册会给出一个完整的API描述,并会指出那些只有WinNTx才得到支持的函数。 Last Modified: Sunday, July 23, 2007 WinPcap 教程: 循序渐进教您使用WinPcap本节将向您展示如何使用WinPcap API的一些特性。 这部分教程细化成若干节课,以循序渐进的方式介绍给读者,让读者从最基本的部分(获得设备列表)到最复杂的部分(控制发送队列并收集和统计网络流量)来了解如何使用WinPcap进行程序开发。 有时,我们会给出一些简单使用的代码片断,但同时,我们提供完整程序的链接:所有的源代码包含一些指向手册其他地方的链接,这可以让您很方便地通过点击鼠标来跳转到您想查看的函数和数据结构的内容中去。 范例程序都是用纯C语言编写, 所以,掌握基本的C语言编程知识是必须的,而且,这是一部关于处理原始网络数据包的教程,因为,我们希望读者拥有良好的网络及网络协议的知识。获取设备列表通常,编写基于WinPcap应用程序的第一件事情,就是获得已连接的网络适配器列表。libpcap和WinPcap都提供了 pcap_findalldevs_ex() 函数来实现这个功能: 这个函数返回一个 pcap_if 结构的链表, 每个这样的结构都包含了一个适配器的详细信息。值得注意的是,数据域 name 和 description 表示一个适配器名称和一个可以让人们理解的描述。 下列代码能获取适配器列表,并在屏幕上显示出来,如果没有找到适配器,将打印错误信息。 #include pcap.hmain() pcap_if_t *alldevs; pcap_if_t *d; int i=0; char errbufPCAP_ERRBUF_SIZE; /* 获取本地机器设备列表 */ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL /* auth is not needed */, &alldevs, errbuf) = -1) fprintf(stderr,Error in pcap_findalldevs_ex: %sn, errbuf); exit(1); /* 打印列表 */ for(d= alldevs; d != NULL; 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; /* 不再需要设备列表了,释放它 */ pcap_freealldevs(alldevs);有关这段代码的一些说明 首先, pcap_findalldevs_ex() ,和其他libpcap函数一样,有一个 errbuf 参数。一旦发生错误,这个参数将会被libpcap写入字符串类型的错误信息。 第二要记住,不是所有的操作系统都支持libpcap提供的网络程序接口,因此,如果我们想编写一个可移植的应用程序,我们就必须考虑在什么情况下, description 是 null。本程序中,我们遇到这种情况时,会打印提示语句No description available。 最后要记住,当我们完成了设备列表的使用,我们要调用 pcap_freealldevs() 函数将其占用的内存资源释放。 让我们编译并运行我们的第一个示例程序吧! 为了能在Unix或Cygwin平台上编译这段程序,需要简单输入: gcc -o testprog testprog.c -lpcap在Windows平台上,您需要创建一个工程,并按照 使用WinPcap编程 里的步骤做。 然而,我们建议您使用WinPcap developers pack ( 详情请访问WinPcap网站, http:/www.winpcap.org ), 因为它提供了很多已经配置好的范例,包括本教程中的所有示例代码,以及在编译运行时需要的 包含文件(include) 和 库(libraries) jiash假设我们已经完成了对程序的编译,那让我们来运行它吧。在某台WinXP的电脑上,我们得到的结果是: 1. DeviceNPF_4E273621-5161-46C8-895A-48D0E52A0B83 (Realtek RTL8029(AS) Ethernet Adapter) 2. DeviceNPF_5D24AE04-C486-4A96-83FB-8B5EC6C7F430 (3Com EtherLink PCI) 正如您看到的,Windows平台下的网络适配器的名字读起来相当容易,可见,解释性的描述是多么有帮助阿!获取已安装设备的高级信息在第1讲中, (获取设备列表) 我们展示了如何获取适配器的基本信息 (如设备的名称和描述)。 事实上,WinPcap提供了其他更高级的信息。 特别需要指出的是, 由 pcap_findalldevs_ex() 返回的每一个 pcap_if 结构体,都包含一个 pcap_addr 结构体,这个结构体由如下元素组成: 一个地址列表 一个掩码列表 (each of which corresponds to an entry in the addresses list). 一个广播地址列表 (each of which corresponds to an entry in the addresses list). 一个目的地址列表 (each of which corresponds to an entry in the addresses list).另外,函数 pcap_findalldevs_ex() 还能返回远程适配器信息和一个位于所给的本地文件夹的pcap文件列表。 下面的范例使用了ifprint()函数来打印出 pcap_if 结构体中所有的内容。程序对每一个由 pcap_findalldevs_ex() 函数返回的pcap_if,都调用ifprint()函数来实现打印。 /* * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino, CACE Technologies * nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */#include pcap.h#ifndef WIN32 #include #include #else #include #endif/ 函数原型void ifprint(pcap_if_t *d);char *iptos(u_long in);char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen);int main() pcap_if_t *alldevs; pcap_if_t *d; char errbufPCAP_ERRBUF_SIZE+1; char sourcePCAP_ERRBUF_SIZE+1; printf(Enter the device you want to list:n rpcap:/ = lists interfaces in the local machinen rpcap:/hostname:port = lists interfaces in a remote machinen (rpcapd daemon must be up and runningn and it must accept null authentication)n file:/foldername = lists all pcap files in the give foldernn Enter your choice: ); fgets(source, PCAP_ERRBUF_SIZE, stdin); sourcePCAP_ERRBUF_SIZE = 0; /* 获得接口列表 */ if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) = -1) fprintf(stderr,Error in pcap_findalldevs: %sn,errbuf); exit(1); /* 扫描列表并打印每一项 */ for(d=alldevs;d;d=d-next) ifprint(d); pcap_freealldevs(alldevs); return 1;/* 打印所有可用信息 */void ifprint(pcap_if_t *d) pcap_addr_t *a; char ip6str128; /* 设备名(Name) */ printf(%sn,d-name); /* 设备描述(Description) */ if (d-description) printf(tDescription: %sn,d-description); /* Loopback Address*/ printf(tLoopback: %sn,(d-flags & PCAP_IF_LOOPBACK)?yes:no); /* IP addresses */ for(a=d-addresses;a;a=a-next) printf(tAddress Family: #%dn,a-addr-sa_family); switch(a-addr-sa_family) case AF_INET: printf(tAddress Family Name: AF_INETn); if (a-addr) printf(tAddress: %sn,iptos(struct sockaddr_in *)a-addr)-sin_addr.s_addr); if (a-netmask) printf(tNetmask: %sn,iptos(struct sockaddr_in *)a-netmask)-sin_addr.s_addr); if (a-broadaddr) printf(tBroadcast Address: %sn,iptos(struct sockaddr_in *)a-broadaddr)-sin_addr.s_addr); if (a-dstaddr) printf(tDestination Address: %sn,iptos(struct sockaddr_in *)a-dstaddr)-sin_addr.s_addr); break; case AF_INET6: printf(tAddress Family Name: AF_INET6n); if (a-addr) printf(tAddress: %sn, ip6tos(a-addr, ip6str, sizeof(ip6str); break; default: printf(tAddress Family Name: Unknownn); break; printf(n);/* 将数字类型的IP地址转换成字符串类型的 */#define IPTOSBUFFERS 12char *iptos(u_long in) static char outputIPTOSBUFFERS3*4+3+1; static short which; u_char *p; p = (u_char *)∈ which = (which + 1 = IPTOSBUFFERS ? 0 : which + 1); sprintf(outputwhich, %d.%d.%d.%d, p0, p1, p2, p3); return outputwhich;char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen) socklen_t sockaddrlen; #ifdef WIN32 sockaddrlen = sizeof(struct sockaddr_in6); #else sockaddrlen = sizeof(struct sockaddr_storage); #endif if(getnameinfo(sockaddr, sockaddrlen, address, addrlen, NULL, 0, NI_NUMERICHOST) != 0) address = NULL; return address;打开适配器并捕获数据包现在,我们已经知道如何获取适配器的信息了,那我们就开始一项更具意义的工作,打开适配器并捕获数据包。在这讲中,我们会编写一个程序,将每一个通过适配器的数据包打印出来。 打开设备的函数是 pcap_open()。下面是参数 snaplen, flags 和 to_ms 的解释说明 snaplen 制定要捕获数据包中的哪些部分。 在一些操作系统中 (比如 xBSD 和 Win32), 驱动可以被配置成只捕获数据包的初始化部分: 这样可以减少应用程序间复制数据的量,从而提高捕获效率。本例中,我们将值定为65535,它比我们能遇到的最大的MTU还要大。因此,我们确信我们总能收到完整的数据包。 flags: 最最重要的flag是用来指示适配器是否要被设置成混杂模式。 一般情况下,适配器只接收发给它自己的数据包, 而那些在其他机器之间通讯的数据包,将会被丢弃。 相反,如果适配器是混杂模式,那么不管这个数据包是不是发给我的,我都会去捕获。也就是说,我会去捕获所有的数据包。 这意味着在一个共享媒介(比如总线型以太网),WinPcap能捕获其他主机的所有的数据包。 大多数用于数据捕获的应用程序都会将适配器设置成混杂模式,所以,我们也会在下面的范例中,使用混杂模式。 to_ms 指定读取数据的超时时间,以毫秒计(1s=1000ms)。在适配器上进行读取操作(比如用 pcap_dispatch() 或 pcap_next_ex() 都会在 to_ms 毫秒时间内响应,即使在网络上没有可用的数据包。 在统计模式下,to_ms 还可以用来定义统计的时间间隔。 将 to_ms 设置为0意味着没有超时,那么如果没有数据包到达的话,读操作将永远不会返回。 如果设置成-1,则情况恰好相反,无论有没有数据包到达,读操作都会立即返回。 #include pcap.h/* packet handler 函数原型 */void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);main()pcap_if_t *alldevs;pcap_if_t *d;int inum;int i=0;pcap_t *adhandle;char errbufPCAP_ERRBUF_SIZE; /* 获取本机设备列表 */ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) = -1) fprintf(stderr,Error in pcap_findalldevs: %sn, errbuf); exit(1); /* 打印列表 */ 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 i) printf(nInterface number out of range.n); /* 释放设备列表 */ pcap_freealldevs(alldevs); return -1; /* 跳转到选中的适配器 */ for(d=alldevs, i=0; inext, i+); /* 打开设备 */if ( (adhandle= pcap_open( d-name, / 设备名 65536, / 65535保证能 /捕获到不同数据链路层上的 /每个数据包的全部内容 PCAP_OPENFLAG_PROMISCUOUS, / 混杂模式 1000, / 读取超时时间 NULL, / 远程机器验证 errbuf / 错误缓冲池 ) ) = NULL) fprintf(stderr,nUnable to open the adapter. %s is not supported by WinPcapn, d-name); /* 释放设备列表 */ pcap_freealldevs(alldevs); return -1; printf(nlistening on %s.n, d-description); /* 释放设备列表 */ pcap_freealldevs(alldevs); /* 开始捕获 */ pcap_loop(adhandle, 0, packet_handler, NULL); return 0;/* 每次捕获到数据包时,libpcap都会自动调用这个回调函数 */void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) struct tm *ltime; char timestr16; time_t local_tv_sec; /* 将时间戳转换成可识别的格式 */ local_tv_sec = header-ts.tv_sec; ltime=localtime(&local_tv_sec); strftime( timestr, sizeof timestr, %H:%M:%S, ltime); printf(%s,%.6d len:%dn, timestr, header-ts.tv_usec, header-len); 当适配器被打开,捕获工作就可以用 pcap_dispatch() 或 pcap_loop()进行。 这两个函数非常的相似,区别就是 pcap_ dispatch() 当超时时间到了(timeout expires)就返回 (尽管不能保证) ,而 pcap_loop() 不会因此而返回,只有当 cnt 数据包被捕获,所以,pcap_loop()会在一小段时间内,阻塞网络的利用。pcap_loop()对于我们这个简单的范例来说,可以满足需求,不过, pcap_dispatch() 函数一般用于比较复杂的程序中。 这两个函数都有一个 回调 参数, packet_handler指向一个可以接收数据包的函数。 这个函数会在收到每个新的数据包并收到一个通用状态时被libpcap所调用 ( 与函数 pcap_loop() 和 pcap_dispatch() 中的 user 参数相似),数据包的首部一般有一些诸如时间戳,数据包长度的信息,还有包含了协议首部的实际数据。 注意:冗余校验码CRC不再支持,因为帧到达适配器,并经过校验确认以后,适配器就会将CRC删除,与此同时,大部分适配器会直接丢弃CRC错误的数据包,所以,WinPcap没法捕获到它们。 上面的程序将每一个数据包的时间戳和长度从 pcap_pkthdr 的首部解析出来,并打印在屏幕上。 请注意,使用 pcap_loop() 函数可能会遇到障碍,主要因为它直接由数据包捕获驱动所调用。因此,用户程序是不能直接控制它的。另一个实现方法(也是提高可读性的方法),是使用 pcap_next_ex() 函数。有关这个函数的使用,我们将在下一讲为您展示。 (不用回调方法捕获数据包).不用回调方法捕获数据包本讲的范例程序所实现的功能和效果和上一讲的非常相似 (打开适配器并捕获数据包), 但本讲将用 pcap_next_ex() 函数代替上一讲的 pcap_loop()函数。 pcap_loop()函数是基于回调的原理来进行数据捕获,这是一种精妙的方法,并且在某些场合中,它是一种很好的选择。 然而,处理回调有时候并不实用 - 它会增加程序的复杂度,特别是在拥有多线程的C+程序中。 可以通过直接调用pcap_next_ex() 函数来获得一个数据包 - 只有当编程人员使用了 pcap_next_ex() 函数才能收到数据包。 这个函数的参数和捕获回调函数的参数是一样的 - 它包含一个网络适配器的描述符和两个可以初始化和返回给用户的指针 (一个指向 pcap_pkthdr 结构体,另一个指向数据报数据的缓冲)。 在下面的程序中,我们会再次用到上一讲中的有关回调方面的代码,只是我们将它放入了main()函数,之后调用 pcap_next_ex()函数。 #include pcap.hmain()pcap_if_t *alldevs;pcap_if_t *d;int inum;int i=0;pcap_t *adhandle;int res;char errbufPCAP_ERRBUF_SIZE;struct tm *ltime;char timestr16;struct pcap_pkthdr *header;const u_char *pkt_data;time_t local_tv_sec; /* 获取本机设备列表 */ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) = -1) fprintf(stderr,Error in pcap_findalldevs: %sn, errbuf); exit(1); /* 打印列表 */ 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 i) printf(nInterface number out of range.n); /* 释放设备列表 */ pcap_freealldevs(alldevs); return -1; /* 跳转到已选中的适配器 */ for(d=alldevs, i=0; inext, i+); /* 打开设备 */ if ( (adhandle= pcap_open(d-name, / 设备名 65536, / 要捕捉的数据包的部分 / 65535保证能捕获到不同数据链路层上的每个数据包的全部内容 PCAP_OPENFLAG_PROMISCUOUS, / 混杂模式 1000, / 读取超时时间 NULL, / 远程机器验证 errbuf / 错误缓冲池 ) ) = NULL) fprintf(stderr,nUnable to open the adapter. %s is not supported by WinPcapn, d-name); /* 释放设列表 */ pcap_freealldevs(alldevs); return -1; printf(nlistening on %s.n, d-description); /* 释放设备列表 */ pcap_freealldevs(alldevs); /* 获取数据包 */ while(res = pcap_next_ex( adhandle, &header, &pkt_data) = 0) if(res = 0) /* 超时时间到 */ continue; /* 将时间戳转换成可识别的格式 */ local_tv_sec = header-ts.tv_sec; ltime=localtime(&local_tv_sec); strftime( timestr, sizeof timestr, %H:%M:%S, ltime); printf(%s,%.6d len:%dn, timestr, header-ts.tv_usec, header-len); if(res = -1) printf(Error reading the packets: %sn, pcap_geterr(adhandle); return -1; return 0;为什么我们要用 pcap_next_ex() 代替以前的 pcap_next()? 因为 pcap_next() 有一些不好的地方。首先,它效率低下,尽管它隐藏了回调的方式,但它依然依赖于函数 pcap_dispatch()。第二,它不能检测到文件末尾这个状态(EOF),因此,如果数据包是从文件读取来的,那么它就不那么有用了。 值得注意的是, pcap_next_ex() 在成功,超时,出错或EOF的情况下,会返回不同的值。过滤数据包WinPcap和Libpcap的最强大的特性之一,是拥有过滤数据包的引擎。 它提供了有效的方法去获取网络中的某些数据包,这也是WinPcap捕获机制中的一个组成部分。 用来过滤数据包的函数是 pcap_compile() 和 pcap_setfilter() 。 pcap_compile() 它将一个高层的布尔过滤表达式编译成一个能够被过滤引擎所解释的低层的字节码。有关布尔过滤表达式的语法可以参见 Filtering expression syntax 这一节的内容。 pcap_setfilter() 将一个过滤器与内核捕获会话向关联。当 pcap_setfilter() 被调用时,这个过滤器将被应用到来自网络的所有数据包,并且,所有的符合要求的数据包 (即那些经过过滤器以后,布尔表达式为真的包) ,将会立即复制给应用程序。 以下代码展示了如何编译并设置过滤器。 请注意,我们必须从 pcap_if 结构体中获得掩码,因为一些使用 pcap_compile() 创建的过滤器需要它。 在这段代码片断中,传递给 pcap_compile() 的过滤器是ip and tcp,这说明我们只希望保留IPv4和TCP的数据包,并把他们发送给应用程序。 if (d-addresses != NULL) /* 获取接口第一个地址的掩码 */ netmask=(struct sockaddr_in *)(d-addresses-netmask)-sin_addr.S_un.S_addr; else /* 如果这个接口没有地址,那么我们假设这个接口在C类网络中 */ netmask=0xffffff; /* compile the filter */ if (pcap_compile(adhandle, &fcode, ip and tcp, 1, netmask) 0) fprintf(stderr,nUnable to compile the packet filter. Check the syntax.n); /* 释放设备列表 */ pcap_freealldevs(alldevs); return -1; set the filter if (pcap_setfilter(adhandle, &fcode) 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 i) printf(nInterface number out of range.n); /* 释放设备列表 */ pcap_freealldevs(alldevs); return -1; /* 跳转到已选设备 */ for(d=alldevs, i=0; inext, i+); /* 打开适配器 */ if ( (adhandle= pcap_open(d-name, / 设备名 65536, / 要捕捉的数据包的部分 / 65535保证能捕获到不同数据链路层上的每个数据包的全部内容 PCAP_OPENFLAG_PROMISCUOUS, / 混杂模式 1000, / 读取超时时间 NULL, / 远程机器验证 errbuf / 错误缓冲池 ) ) = NULL) fprintf(stderr,nUnable to open the adapter. %s is not supported by WinPcapn); /* 释放设备列表 */ pcap_freealldevs(alldevs); return -1; /* 检查数据链路层,为了简单,我们只考虑以太网 */ if(pcap_datalink(adhandle) != DLT_EN10MB) fprintf(stderr,nThis program works only on Ethernet networks.n); /* 释放设备列表 */ pcap_freealldevs(alldevs); return -1; if(d-addresses != NULL) /* 获得接口第一个地址的掩码 */ netmask=(struct sockaddr_in *)(d-addresses-netmask)-sin_addr.S_un.S_addr; else /* 如果接口没有地址,那么我们假设一个C类的掩码 */ netmask=0xffffff; /编译过滤器 if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) 0 ) fprintf(stderr,nUnable to compile the packet filter. Check the syntax.n); /* 释放设备列表 */ pcap_freealldevs(alldevs); return -1; /设置过滤器 if (pcap_setfilter(adhandle, &fcode)description); /* 释放设备列表 */ pcap_freealldevs(alldevs); /* 开始捕捉 */ pcap_loop(adhandle, 0, packet_handler, NULL); return 0;/* 回调函数,当收到每一个数据包时会被libpcap所调用 */void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) struct tm *ltime; char timestr16; ip_header *ih; udp_header *uh; u_int ip_len; u_short sport,dport; time_t local_tv_sec; /* 将时间戳转换成可识别的格式 */ local_tv_sec = header-ts.tv_sec; ltime=localtime(&local_tv_sec); strftime( timestr, sizeof timestr, %H:%M:%S, ltime); /* 打印数据包的时间戳和长度 */ printf(%s.%.6d len:%d , timestr, header-ts.tv_usec, header-len); /* 获得IP数据包头部的位置 */ ih = (ip_header *) (pkt_data + 14); /以太网头部长度 /* 获得UDP首部的位置 */ ip_len = (ih-ver_ihl & 0xf) * 4; uh = (udp_header *) (u_char*)ih + ip_len); /* 将网络字节序列转换成主机字节序列 */ sport = ntohs( uh-sport ); dport = ntohs( uh-dport ); /* 打印IP地址和UDP端口 */ printf(%d.%d.%d.%d.%d - %d.%d.%d.%d.%dn, ih-saddr.byte1, ih-saddr.byte2, ih-saddr.byte3, ih-saddr.byte4, sport, ih-daddr.byte1, ih-daddr.byte2, ih-daddr.byte3, ih-daddr.byte4, dport);首先,我们将过滤器设置成ip and udp。在这种方式下,我们确信packet_handler()只会收到基于IPv4的UDP数据包;这将简化解析过程,提高程序的效率。 我们还分别创建了用于描述IP首部和UDP首部的结构体。这些结构体中的各种数据会被packet_handler()合理地定位。 packet_handler(), 尽管只受限于单个协议的解析(比如基于IPv4的UDP),不过它展示了捕捉器(sniffers)是多么的复杂,就像TcpDump或WinDump对网络数据流进行解码那样。 因为我们对MAC首部不感兴趣,所以我们跳过它。 为了简洁,我们在开始捕捉前,使用了pcap_datalink() 对MAC层进行了检测,以确保我们是在处理一个以太网络。这样,我们就能确保MAC首部是14位的。 IP数据包的首部就位于MAC首部的后面。我们将从IP数据包的首部解析到源IP地址和目的IP地址。 处理UDP的首部有一些复杂,因为IP数据包的首部的长度并不是固定的。然而,我们可以通过IP数据包的length域来得到它的长度。一旦我们知道了UDP首部的位置,我们就能解析到源端口和目的端口。 被解析出来的值被打印在屏幕上,形式如下所示: 1. DevicePacket_A7FD048A-5D4B-478E-B3C1-34401AC3B72F (Xircom t 10/100 Adapter) Enter the interface number (1-2):1listening on Xircom CardBus Ethernet 10/100 Adapter. 16:13:15.312784 len:87 130.192.31.67.2682 - 130.192.3.21.53 16:13:15.314796 len:137 130.192.3.21.53 - 130.192.31.67.2682 16:13:15.322101 len:78 130.192.31.67.2683 - 130.192.3.21.53 最后3行中的每一行,分别代表了一个数据包。 处理脱机堆文件在本讲中,我们将学习如何处理捕获到文件中的数据包。 WinPcap提供了很多函数来将网络数据流保存到文件并读取它们 - 本讲将教你如何使用这些函数。我们还将看到如何使用WinPcap内核堆特性来获取一个高性能的堆。(请注意:此时,由于一些有关新内核缓冲的问题,这些特性将无法使用) 堆文件的格式是libpcap的一种。这种格式中,包含了被捕捉到的包的二进制数据,并且,这种格式是许多网络工具所使用的一种标准,这些工具包括WinDump,Etheral和Snort。 保存数据包到堆文件 首先,让我们看一下如何将一个数据包写成libpcap的格式。 接下来的例子讲从一个选定的接口捕获数据包,并且将它们保存到用户指定的文件中。 #include pcap.h/* 回调函数原型 */void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);main(int argc, char *argv)pcap_if_t *alldevs;pcap_if_t *d;int inum;int i=0;pcap_t *adhandle;char errbufPCAP_ERRBUF_SIZE;pcap_dumper_t *dumpfile; /* 检查程序输入参数 */ if(argc != 2) printf(usage: %s filename, argv0); return -1; /* 获取本机设备列表 */ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) = -1) fprintf(stderr,Error in pcap_findalldevs: %sn, errbuf); exit(1); /* 打印列表 */ 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 i) printf(nInterface number out of range.n); /* 释放列表 */ pcap_freealldevs(alldevs); return -1; /* 跳转到选中的适配器 */ for(d=alldevs, i=0; inext, i+); /* 打开适配器 */ if ( (adhandle= pcap_open(d-name, / 设备名 65536, / 要捕捉的数据包的部分 / 65535保证能捕获到不同数据链路层上的每个数据包的全部内容 PCAP_OPENFLAG_PROMISCUOUS, / 混杂模式 1000, / 读取超时时间 NULL, / 远程机器验证 errbuf / 错误缓冲池 ) ) = NULL) fprintf(stderr,nUnable to open the adapter. %s is not supported by WinPcapn, d-name); /* 释放设备列表 */ pcap_freealldevs(alldevs); return -1; /* 打开堆文件 */ dumpfile = pcap_dump_open(adhandle, argv1); if(dumpfile=NULL) fprintf(stderr,nError opening output filen); return -1; printf(nlistening on %s. Press Ctrl+C to stop.n, d-description); /* 释放设备列表 */ pcap_freealldevs(alldevs); /* 开始捕获 */ pcap_loop(adhandle, 0, packet_handler, (unsigned char *)dumpfile); return 0;/* 回调函数,用来处理数据包 */void packet_handler(u_char *dumpfile, const struct pcap_pkthdr *header, const u_char *pkt_data) /* 保存数据包到堆文件 */ pcap_dump(dumpfile, header, pkt_data);你可以看到,这个程序的结构和前面几讲的程序非常相似,它们的区别有: 只有当接口打开时,调用 pcap_dump_open() 才是有效的。 这个调用将打开一个堆文件,并将它关联到特定的接口上。 数据包将会通过 pcap_dump() 函数写入堆文件中,这个函数是packet_handler()的回调函数。 pcap_dump() 的参数和 pcap_handler() 函数中的参数是一一对应的。从堆文件中读取数据包 既然我们有了可用的堆文件,那我们就能读取它的内容了。 以下代码将打开一个WinPcap/libpcap的堆文件,并显示文件中每一个包的信息。文件通过 pcap_open_offline() 打开,然后,我们通常使用 pcap_loop() 来有序获取数据包。你可以看到,从脱机文件中读取数据包和从物理接口中接收它们是很相似的。 这个例子还会介绍另一个函数:pcap_createsrcsrc()。这个函数用于创建一个源字符串,这个源字符串以一个标志开头,这个标志会告诉WinPcap这个源的类型。比如,使用rpcap:/标志来打开一个适配器,使用file:/来打开一个文件。如果 pcap_findalldevs_ex() 已经被使用,那么这部是不需要的,因为其返回值已经包含了这些字符串。然而,在这个例子中,我们需要它。因为文件的名字来自于用户的输入。 #include #include #define LINE_LEN 16void dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *);main(int argc, char *argv)pcap_t *fp;char errbufPCAP_ERRBUF_SIZE;char sourcePCAP_BUF_SIZE; if(argc != 2) printf(usage: %s filename, argv0); return -1; /* 根据新WinPcap语法创建一个源字符串 */ if ( pcap_createsrcstr( source, / 源字符串 PCAP_SRC_FILE, / 我们要打开的文件 NULL, / 远程主机 NULL, / 远程主机端口 argv1, / 我们要打开的文件名 errbuf / 错误缓冲区 ) != 0) fprintf(stderr,nError creating a source stringn); return -1; /* 打开捕获文件 */ if ( (fp= pcap_open(source, / 设备名 65536, / 要捕捉的数据包的部分 / 65535保证能捕获到不同数据链路层上的每个数据包的全部内容 PCAP_OPENFLAG_PROMISCUOUS, / 混杂模式 1000, / 读取超时时间 NULL, / 远程机器验证 errbuf / 错误缓冲池 ) ) = NULL) fprintf(stderr,nUnable to open the file %s.n, source); return -1; / 读取并解析数据包,直到EOF为真 pcap_loop(fp, 0, dispatcher_handler, NULL); return 0;void dispatcher_handler(u_char *temp1, const struct pcap_pkthdr *header, const u_char *pkt_data) u_int i=0; /* 打印pkt时间戳和pkt长度 */ printf(%ld:%ld (%ld)n, header-ts.tv_sec, header-ts.tv_usec, header-len); /* 打印数据包 */ for (i=1; (i caplen + 1 ) ; i+) printf(%.2x , pkt_datai-1); if ( (i % LINE_LEN) = 0) printf(n); printf(nn); 下面的程序同样实现了如上功能,只是,我们使用了 pcap_next_ex() 函数来代替需要进行回调的 pcap_loop() 。 #include #include #define LINE_LEN 16main(int argc, char *argv)pcap_t *fp;char errbufPCAP_ERRBUF_SIZE;char sourcePCAP_BUF_SIZE;struct pcap_pkthdr *header;const u_char *pkt_data;u_int i=0;int res; if(argc != 2) printf(usage: %s filename, argv0); return -1; /* 根据新WinPcap语法创建一个源字符串 */ if ( pcap_createsrcstr( source, / 源字符串 PCAP_SRC_FILE, / 我们要打开的文件 NULL, / 远程主机 NULL, / 远程主机端口 argv1, / 我们要打开的文件名 errbuf / 错误缓冲区 ) != 0) fprintf(stderr,nError creating a source stringn); return -1; /* 打开捕获文件 */ if ( (fp= pcap_open(source, / 设备名 65536, / 要捕捉的数据包的部分 / 65535保证能捕获到不同数据链路层上的每个数据包的全部内容 PCAP_OPENFLAG_PROMISCUOUS, / 混杂模式 1000, / 读取超时时间 NULL, / 远程机器验证 errbuf / 错误缓冲池 ) ) = NULL) fprintf(stderr,nUnable to open the file %s.n, source); return -1; /* 从文件获取数据包 */ while(res = pcap_next_ex( fp, &header, &pkt_data) = 0) /* 打印pkt时间戳和pkt长度 */ printf(%ld:%ld (%ld)n, header-ts.tv_sec, header-ts.tv_usec, header-len); /* 打印数据包 */ for (i=1; (i caplen + 1 ) ; i+) printf(%.2x , pkt_datai-1); if ( (i % LINE_LEN) = 0) printf(n); printf(nn); if (res = -1) printf(Error reading the packets: %sn, pcap_geterr(fp); return 0;使用pcap_live_dump将包写入堆文件 注意: 此时,由于新内核缓冲的一些问题,这个特性可能不可用。 WinPcap的最近几个版本提供了一个更好的途径,来将数据流保存到磁盘,那就是 pcap_live_dump() 函数。 pcap_live_dump() 函数有3个参数:文件名,文件最大的大小(字节为单位),和文件可以允许存储的数据包的最大数量 。 0表示没有限制。 注意,在调用 pcap_live_dump() 将数据流保存下来之前,程序可以设置过滤器(使用 pcap_setfilter(),详情请参见教程的 过滤数据包这部分) ,这样,我们就可以定义要保存的那部分数据流了。 pcap_live_dump() 不会被阻塞, 因此,它开始堆处理后会立即返回。 堆处理以异步的方式进行,直到文件达到最大大小或者存储的数据包达到最大数量。 应用程序可以使用 pcap_live_dump_ended()来检查数据是否存储完毕。 特别注意: sync 参数必须是非零的, 如果它们是0,那么程序将永远被阻塞。 /* * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino, CACE Technologies * nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */#include #include #include #error At the moment the kernel dump feature is not supported in the drivermain(int argc, char *argv) pcap_if_t *alldevs, *d; pcap_t *fp; u_int inum, i=0; char errbufPCAP_ERRBUF_SIZE; printf(kdump: saves the network traffic to file using WinPcap kernel-level dump faeature.n); printf(t Usage: %s adapter | dump_file_name max_size max_packsn, argv0); printf(t Where: max_size is the maximum size that the dump file will reach (0 means no limit)n); printf(t Where: max_packs is the maximum number of packets that will be saved (0 means no limit)nn); if(argc 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 i) printf(nInterface number out of range.n); /* 释放列表 */ return -1; /* 跳转到所选的设备 */ for(d=alldevs, i=0; inext, i+); /* 打开设备 */ if ( (fp = pcap_open_live(d-name, 100, 1, 20, errbuf) ) = NULL) fprintf(stderr,nError opening adaptern); return -1; /* 释放设备列表 */ pcap_freealldevs(alldevs); /* 开始堆过程 */ if(pcap_live_dump(fp, argv1, atoi(argv2), atoi(argv3)=-1) printf(Unable to start the dump, %sn, pcap_geterr(fp); return -1; else /* 打开设备 */ if ( (fp= pcap_open_live(argv1, 100, 1, 20, errbuf) ) = NULL) fprintf(stderr,nError opening adaptern); return -1; /* 开始堆过程 */ if(pcap_live_dump(fp, argv0, atoi(argv1), atoi(argv2)=-1) printf(Unable to start the dump, %sn, pcap_geterr(fp); return -1; /* 等待,知道堆过程完成,也就是当数据到达max_size或max_packs的时候 */ pcap_live_dump_ended(fp, TRUE); /* 关闭适配器,这样,就可以将数据立刻输出到文件了 */ pcap_close(fp); return 0;pcap_live_dump() 和 pcap_dump()的区别,除了可以设置限制之外,就是运行结果。 pcap_live_dump() 利用了WinPcap NPF驱动自带的功能, (详情请参见 NPF驱动核心手册) ,在内核级来写堆文件,并将上下文交换的数量和内存拷贝的数量最小化。 显然,这个特性目前并不能应用于其它操作系统,因为 pcap_live_dump() 是WinPcap的特性之一,并且只运行于Win32平台下。发送数据包尽管从 WinPcap 的名字上看,这个库的目标应该是数据捕捉(Packet Capture),然而,它也提供了针对很多其它有用的特性。在其中,我们可以找到一组很完整的用于发送数据包的函数。 请注意:原始的libpcap库是不支持发送数据包的,因此,这里展示的函数都属于是WinPcap的扩展,并且它们不能运行于Unix平台下。 使用 pcap_sendpacket() 发送单个数据包 下面的代码展示了发送一个数据包的最简单的方式。打开适配器以后,调用 pcap_sendpacket() 来发送手工制作的数据包。 pcap_sendpacket() 的参数有一个要包涵发送数据的缓冲区,缓冲的长度,以及用来发送数据的适配器。注意,缓冲数据将直接发送到网络,而不会进行任何加工和处理。这就意味着应用程序需要创建一个正确的协议首部,来使这个数据包更有意义。 #include #include #include void main(int argc, char *argv)pcap_t *fp;char errbufPCAP_ERRBUF_SIZE;u_char packet100;int i; /* 检查命令行参数的合法性 */ if (argc != 2) printf(usage: %s interface (e.g. rpcap:/eth0), argv0); return; /* 打开输出设备 */ if ( (fp= pcap_open(argv1, / 设备名 100, / 要捕获的部分 (只捕获前100个字节) PCAP_OPENFLAG_PROMISCUOUS, / 混杂模式 1000, / 读超时时间 NULL, / 远程机器验证 errbuf / 错误缓冲 ) ) = NULL) fprintf(stderr,nUnable to open the adapter. %s is not supported by WinPcapn, argv1); return; /* 假设在以太网上,设置MAC的目的地址为 1:1:1:1:1:1 */ packet0=1; packet1=1; packet2=1; packet3=1; packet4=1; packet5=1; /* 设置MAC源地址为 2:2:2:2:2:2 */ packet6=2; packet7=2; packet8=2; packet9=2; packet10=2; packet11=2; /* 填充剩下的内容 */ for(i=12;i100;i+) packeti=i%256; /* 发送数据包 */ if (pcap_sendpacket(fp, packet, 100 /* size */) != 0) fprintf(stderr,nError sending the packet: n, pcap_geterr(fp); return; return;发送队列 pcap_sendpacket() 提供了一种简单而直接的方法来发送单个数据包,而 send queues 则提供了一种高级的,强大的,结构更优的方法来发送一组数据包。发送队列是一个容器,它能容纳不同数量的数据包,这些数据包将被发送到网络上。队列有大小,它代表了它能存储的数据包的最大数量。 发送队列通过调用 pcap_sendqueue_alloc() 函数创建,并且需要指定队列的大小。 一旦发送队列被创建, pcap_sendqueue_queue() 就可以将数据包添加到发送队列中。这个函数的参数包含一个 pcap_pkthdr 的结构体,它包含时间戳和长度,同时,参数还包含一个指向数据包数据的缓冲。这些参数和那些被 pcap_next_ex() 和 pcap_handler()接收到的数据相同,因此,为那些刚刚捕获到的,或是从文件读取出来的数据包排队,就相当于把三个参数传递给 pcap_sendqueue_queue() 。 WinPcap提供了 pcap_sendqueue_transmit() 函数来发送一个队列。请注意第三个参数:如果非零,那么发送过程将是同步进行,也就是说,只有时间戳相符的数据包才会被处理。这个操作需要消耗大量的CPU资源,因为同步操作由内核驱动中的忙等 (busy wait)循环来实现的。尽管这个操作对CPU的要求很高,但它对包传送的处理结果,通常是很精确的。(通常在数微秒左右,或更小) 请注意,使用 pcap_sendqueue_transmit() 要比 pcap_sendpacket() 来发送一系列数据更加有效率,因为发送队列保存在内核级的缓冲区,因此,减少了上下文交换的次数。 当队列不再需要时,我们可以使用 pcap_sendqueue_destroy() 来释放它所占用的内存。 下一个程序将演示如何使用发送队列。先用 pcap_open_offline() 打开一个捕获文件,然后,将文件中的数据包移到已分配的发送队列。这时,就可以发送队列了,如果用户指定了同步,那么它将同步发送队列。 注意,堆文件的链路层将会那些发送数据包接口中的一个进行比较,那些接口使用 pcap_datalink() 发送数据包。当比较的结果不相同,那么就会打印出警告信息。捕获文件的链路层和适配器的链路层相一致是非常重要的,不然,发送将变得毫无意义。 /* * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino, CACE Technologies * nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */#include #include #include #include void usage();void main(int argc, char *argv) pcap_t *indesc,*outdesc; char errbufPCAP_ERRBUF_SIZE; char sourcePCAP_BUF_SIZE; FILE *capfile; int caplen, sync; u_int res; pcap_send_queue *squeue; struct pcap_pkthdr *pktheader; u_char *pktdata; float cpu_time; u_int npacks = 0; /* 检查命令行参数的合法性 */ if (argc = 5) usage(); return; /* 获取捕获文件长度 */ capfile=fopen(argv1,rb); if(!capfile) printf(Capture file not found!n); return; fseek(capfile , 0, SEEK_END); caplen= ftell(capfile)- sizeof(struct pcap_file_header); fclose(capfile); /* 检查时间戳是否合法 */ if(argc = 4 & argv30 = s) sync = TRUE; else sync = FALSE; /* 开始捕获 */ /* 根据WinPcap的新语法创建一个源字符串 */ if ( pcap_createsrcstr( source, / 源字符串 PCAP_SRC_FILE, / 我们要打开的文件 NULL, / 远程主机 NULL, / 远程主机的端口 argv1, / 我们要打开的文件名 errbuf / 错误缓冲 ) != 0) fprintf(stderr,nError creating a source stringn); return; /* 打开捕获文件 */ if ( (indesc= pcap_open(source, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) = NULL) fprintf(stderr,nUnable to open the file %s.n, source); return; /* 打开要输出的适配器 */ if ( (outdesc= pcap_open(argv2, 100, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) = NULL) fprintf(stderr,nUnable to open adapter %s.n, source); return; /* 检查MAC的类型 */ if (pcap_datalink(indesc) != pcap_datalink(outdesc) printf(Warning: the datalink of the capture differs from the one of the selected interface.n); printf(Press a key to continue, or CTRL+C to stop.n); getchar(); /* 分配发送队列 */ squeue = pcap_sendqueue_alloc(caplen); /* 从文件中将数据包填充到发送队列 */ while (res = pcap_next_ex( indesc, &pktheader, &pktdata) = 1) if (pcap_sendqueue_queue(squeue, pktheader, pktdata) = -1) printf(Warning: packet buffer too small, not all the packets will be sent.n); break; npacks+; if (res = -1) printf(Corrupted input file.n); pcap_sendqueue_destroy(squeue); return; /* 发送队列 */ cpu_time = (float)clock (); if (res = pcap_sendqueue_transmit(outdesc, squeue, sync) len) printf(An error occurred sending the packets: %s. Only %d bytes were sentn, pcap_geterr(outdesc), res); cpu_time = (clock() - cpu_time)/CLK_TCK; printf (nnElapsed time: %5.3fn, cpu_time); printf (nTotal packets generated = %d, npacks); printf (nAverage packets per second = %d, (int)(double)npacks/cpu_time); printf (n); /* 释放发送队列 */ pcap_sendqueue_destroy(squeue); /* 关闭输入文件 */ pcap_close(indesc); /* * 释放输出适配器 * IMPORTANT: 记得一定要关闭适配器,不然就不能保证 * 所有的数据包都回被发送出去 */ pcap_close(outdesc); return;void usage() printf(nSendcap, sends a libpcap/tcpdump capture file to the net. Copyright (C) 2002 Loris Degioanni.n); printf(nUsage:n); printf(t sendcap file_name adapter sn); printf(nParameters:n); printf(nfile_name: the name of the dump file that will be sent to the networkn); printf(nadapter: the device to use. Use WinDump -D for a list of valid devicesn); printf(ns: if present, forces the packets to be sent synchronously, i.e. respecting the timestamps in the dump file. This option will work only under Windows NTx.nn); exit(0);收集并统计网络流量这一讲,我们将展示WinPcap的另一个高级特性:收集并统计网络流量。统计引擎利用了内核级的数据包过滤器,来有效地为收集到的数据包进行分类。如果你想阅读更多细节,请参阅 NPF驱动核心手册。 为了使用这个特性,编程人员必须打开一个适配器,并且,可以使用 pcap_setmode() 将它设置为统计模式(statistical mode)。特别注意,必须使用MODE_STAT来作为这个函数的mode参数。 在统计模式下,编写一个用于监听TCP网络流量的程序并不复杂,代码也不多。下面的范例程序将展示如何实现这个程序。 /* * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino, CACE Technologies * nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */#include #include #include void usage();void dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *);void main(int argc, char *argv)pcap_t *fp;char errbufPCAP_ERRBUF_SIZE;struct timeval st_ts;u_int netmask;struct bpf_program fcode; /* 检查命令行参数的合法性 */ if (argc != 2) usage(); return; /* 打开输出适配器 */ if ( (fp= pcap_open(argv1, 100, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) = NULL) fprintf(stderr,nUnable to open adapter %s.n, errbuf); return; /* 不用关心掩码,在这个过滤器中,它不会被使用 */ netmask=0xffffff; / 编译过滤器 if (pcap_compile(fp, &fcode, tcp, 1, netmask) 0 ) fprintf(stderr,nUnable to compile the packet filter. Check the syntax.n); /* 释放设备列表 */ return; /设置过滤器 if (pcap_setfilter(fp, &fcode)0) fprintf(stderr,nError setting the filter.n); pcap_close(fp); /* 释放设备列表 */ return; /* 将接口设置为统计模式 */ if (pcap_setmode(fp, MODE_STAT)ts.tv_sec - old_ts-tv_sec) * 1000000 - old_ts-tv_usec + header-ts.tv_usec; /* 获取每秒的比特数b/s */ Bps.QuadPart=(*(LONGLONG*)(pkt_data + 8) * 8 * 1000000) / (delay); /* | | | | | | 将字节转换成比特 - | | 延时是以毫秒表示的 - */ /* 得到每秒的数据包数量 */ Pps.QuadPart=(*(LONGLONG*)(pkt_data) * 1000000) / (delay); /* 将时间戳转化为可识别的格式 */ local_tv_sec = header-ts.tv_sec; ltime=localtime(&local_tv_sec); strftime( timestr, sizeof timestr, %H:%M:%S, ltime); /* 打印时间戳*/ printf(%s , timestr); /* 打印采样结果 */ printf(BPS=%I64u , Bps.QuadPart); printf(PPS=%I64un, Pps.QuadPart); /存储当前的时间戳 old_ts-tv_sec=header-ts.tv_sec; old_ts-tv_usec=header-ts.tv_usec;void usage() printf(nShows the TCP traffic load, in bits per second and packets per second.nCopyright (C) 2002 Loris Degioanni.n); printf(nUsage:n); printf(t tcptop adaptern); printf(t You can use WinDump -D if you dont know the name of your adapters.n); exit(0);在启动统计模式前,用户需要设置一个过滤器,以定义要监听的数据流。详细内容请参考 过滤表达式语法 。如果没有设置过滤器,那么,所有的数据流量都将会被监听 过程 设置过滤器 调用 pcap_setmode() 回调函数通过 pcap_loop()被启动接口描述符(the interface descriptor)开始工作在统计模式下。注意 pcap_open() 函数的第4个参数( to_ms ):它定义了统计采样的时间间隔。回调函数将在每一个to_ms时间,收到由驱动发来的计算好的采样数据。这些采样数据将通过回调函数的第2个和第3个参数传递,如下所示 它提供了两个64位的计数器,分别记录在最后一个时间间隔内,收到的数据包的数量和字节总数。 在这个范例中,适配器打开后的超时时间设置为1000毫秒。这就意味着dispatcher_handler()每隔1秒就会被调用一次。这里的过滤器被设置为只监视TCP包。然后, pcap_setmode() 和 pcap_loop() 被调用。注意,一个指向timeval结构的指针,作为user参数传递给函数 pcap_loop() 。这个结构体会被用来存储时间戳,以便计算两次采样的时间间隔。 dispatcher_handler() 会使用这个时间间隔来获得每秒的比特数(bps)以及每秒的数据包数量(pps),并将它们的值打印在屏幕上。 最后,我们想说,这个范例程序比传统的捕获和统计流量的程序都要高效,因为传统的程序都在用户层进行。静态模式需要最小的数据包拷贝和上下文交换,因此,CPU的性能会最优,而且,内存的需求量也会很少。WinPcap核心资料模块NPF驱动核心指南如何编译WinPcapPacket.dll - 数据包驱动API详细描述这部分指南从最底层的模块开始,描述了WinPcap的核心结构与接口。这部分内容的适合那些想要扩展或修改本软件的人,或者是那些对WinPcap的工作原理感兴趣的人。因此,那些只希望在他们的软件中,使用WinPcap的开发人员,不需要阅读此部分的内容。 WinPcap 结构饮用WinPcap主页上的一段内容:WinPcap是一个Win32平台的,用于捕获数据包和进行网络分析的体系结构。它包括了一个内核级的数据包过滤器,一个低层动态链接库(packet.dll),一个高层的,依赖于系统的库(wpcap.dll)。 为什么我们使用术语体系结构而不是库呢?因为数据捕获是一个低层的行为,它需要和网络适配器,及操作系统的信息交换,特别是网络的实现。所以,一个简单的库是实现不了的。 以下结构显示了WinPcap的不同的组件:WinPcap的主要结构 首先,捕获系统需要占用操作系统的协议栈,来访问通过网络的原始数据。这就需要有部分内容要运行在操作系统内核中,能直接访问网络接口驱动。这部分内容非常依赖于系统,在我们的解决方案中,它被认为是设备驱动,称为Netgroup Packet Filter(NPF);我们为Windows 95,Windows 98,Windows ME, Windows NT 4, Windows 2000 和 Windows XP提供了不同版本的驱动。这些驱动都提供了相同的基本功能,比如数据捕获和发送,也提供了一些高级功能,比如可编程的过滤系统和一个监听引擎,前者可以被用来获取过滤后的数据流(比如,可以从指定的端口,仅捕获ftp数据流),后者提供了一个强大的,但很简单的方式来获取数据流的统计信息。(比如获取网络流量或者两个主机间交换数据的总大小)。 其次,捕获系统必须输出一个端口,以便用户级应用程序利用内核驱动所提供的特性。WinPcap提供了两个不同的库:packet.dll 和 wpcap.dll第一个提供了低层的API,它可以直接访问驱动的函数,并且依赖于微软操作系统的可编程接口。第二个提供了更多强大的,高层次的,和libpcap(一个知名的Unix捕获库)兼容的捕获原语。这些函数捕可以在不考虑网络硬件和操作系统的情况下捕获数据。纵观本文档,我们会首先使用Packet Driver API 或 packet.dll的函数,然后才是wpcap, wpcap.dll 或 libpcap的。NPF驱动核心指南WinPcap核心资料 模块NPF 结构与定义NPF 函数数据结构struct binary_streamA stream of X86 binary code. More.struct JIT_BPF_FilterStructure describing a x86 filtering program created by the jitter. More.定义#defineEAX0#defineECX1#defineEDX2#defineEBX3#defineESP4#defineEBP5#defineESI6#defineEDI7#defineAX0#defineCX1#defineDX2#defineBX3#defineSP4#defineBP5#defineSI6#defineDI7#defineAL0#defineCL1#defineDL2#defineBL3#defineMOVid(r32, i32)emitm(&stream, 11 4 | 1 3 | r32 & 0x7, 1); emitm(&stream, i32, 4);mov r32,i32 #defineMOVrd(dr32, sr32)emitm(&stream, 8 4 | 3 | 1 3, 1); emitm(&stream, 3 6 | (dr32 & 0x7) 3 | sr32 & 0x7, 1);mov dr32,sr32 #defineMOVodd(dr32, sr32, off)mov dr32,sr32off #defineMOVobd(dr32, sr32, or32)mov dr32,sr32or32 #defineMOVobw(dr32, sr32, or32)mov dr16,sr32or32 #defineMOVobb(dr8, sr32, or32)mov dr8,sr32or32 #defineMOVomd(dr32, or32, sr32)mov dr32or32,sr32 #defineBSWAP(dr32)bswap dr32 #defineSWAP_AX()xchg al,ah #definePUSH(r32)emitm(&stream, 5 4 | 0 3 | r32 & 0x7, 1);push r32 #definePOP(r32)emitm(&stream, 5 4 | 1 3 | r32 & 0x7, 1);pop r32 #defineRET()emitm(&stream, 12 4 | 0 3 | 3, 1);ret #defineADDrd(dr32, sr32)add dr32,sr32 #defineADD_EAXi(i32)add eax,i32 #defineADDid(r32, i32)add r32,i32 #defineADDib(r32, i8)add r32,i8 #defineSUBrd(dr32, sr32)sub dr32,sr32 #defineSUB_EAXi(i32)sub eax,i32 #defineMULrd(r32)mul r32 #defineDIVrd(r32)div r32 #defineANDib(r8, i8)and r8,i8 #defineANDid(r32, i32)and r32,i32 #defineANDrd(dr32, sr32)and dr32,sr32 #defineORrd(dr32, sr32)or dr32,sr32 #defineORid(r32, i32)or r32,i32 #defineSHLib(r32, i8)shl r32,i8 #defineSHL_CLrb(dr32)shl dr32,cl #defineSHRib(r32, i8)shr r32,i8 #defineSHR_CLrb(dr32)shr dr32,cl #defineNEGd(r32)neg r32 #defineCMPodd(dr32, sr32, off)cmp dr32,sr32off #defineCMPrd(dr32, sr32)cmp dr32,sr32 #defineCMPid(dr32, i32)cmp dr32,i32 #defineJNEb(off8)jne off32 #defineJE(off32)je off32 #defineJLE(off32)jle off32 #defineJLEb(off8)jle off8 #defineJA(off32)ja off32 #defineJAE(off32)jae off32 #defineJG(off32)jg off32 #defineJGE(off32)jge off32 #defineJMP(off32)jmp off32 自定义类型typedef UINT(_cdecl *)BPF_filter_function (PVOID *, ULONG, UINT)Prototype of a filtering function created by the jitter. typedef void(*)emit_func (binary_stream *stream, ULONG value, UINT n)Prototype of the emit functions. 详细描述This section documents the internals of the Netgroup Packet Filter (NPF), the kernel portion of WinPcap. Normal users are probably interested in how to use WinPcap and not in its internal structure. Therefore the information present in this module is destined mainly to WinPcap developers and maintainers, or to the people interested in how the driver works. In particular, a good knowledge of OSes, networking and Win32 kernel programming and device drivers development is required to profitably read this section.NPF is the WinPcap component that does the hard work, processing the packets that transit on the network and exporting capture, injection and analysis capabilities to user-level.The following paragraphs will describe the interaction of NPF with the OS and its basic structure.NPF and NDISNDIS (Network Driver Interface Specification) is a standard that defines the communication between a network adapter (or, better, the driver that manages it) and the protocol drivers (that implement for example TCP/IP). Main NDIS purpose is to act as a wrapper that allows protocol drivers to send and receive packets onto a network (LAN or WAN) without caring either the particular adapter or the particular Win32 operating system.NDIS supports three types of network drivers:1. Network interface card or NIC drivers. NIC drivers directly manage network interface cards, referred to as NICs. The NIC drivers interface directly to the hardware at their lower edge and at their upper edge present an interface to allow upper layers to send packets on the network, to handle interrupts, to reset the NIC, to halt the NIC and to query and set the operational characteristics of the driver. NIC drivers can be either miniports or legacy full NIC drivers. o Miniport drivers implement only the hardware-specific operations necessary to manage a NIC, including sending and receiving data on the NIC. Operations common to all lowest level NIC drivers, such as synchronization, is provided by NDIS. Miniports do not call operating system routines directly; their interface to the operating system is NDIS.A miniport does not keep track of bindings. It merely passes packets up to NDIS and NDIS makes sure that these packets are passed to the correct protocols. o Full NIC drivers have been written to perform both hardware-specific operations and all the synchronization and queuing operations usually done by NDIS. Full NIC drivers, for instance, maintain their own binding information for indicating received data. 2. Intermediate drivers. Intermediate drivers interface between an upper-level driver such as a protocol driver and a miniport. To the upper-level driver, an intermediate driver looks like a miniport. To a miniport, the intermediate driver looks like a protocol driver. An intermediate protocol driver can layer on top of another intermediate driver although such layering could have a negative effect on system performance. A typical reason for developing an intermediate driver is to perform media translation between an existing legacy protocol driver and a miniport that manages a NIC for a new media type unknown to the protocol driver. For instance, an intermediate driver could translate from LAN protocol to ATM protocol. An intermediate driver cannot communicate with user-mode applications, but only with other NDIS drivers. 3. Transport drivers or protocol drivers. A protocol driver implements a network protocol stack such as IPX/SPX or TCP/IP, offering its services over one or more network interface cards. A protocol driver services application-layer clients at its upper edge and connects to one or more NIC driver(s) or intermediate NDIS driver(s) at its lower edge. NPF is implemented as a protocol driver. This is not the best possible choice from the performance point of view, but allows reasonable independence from the MAC layer and as well as complete access to the raw traffic.Notice that the various Win32 operating systems have different versions of NDIS: NPF is NDIS 5 compliant under Windows 2000 and its derivations (like Windows XP), NDIS 3 compliant on the other Win32 platforms.Next figure shows the position of NPF inside the NDIS stack:Figure 1: NPF inside NDIS.The interaction with the OS is normally asynchronous. This means that the driver provides a set of callback functions that are invoked by the system when some operation is required to NPF. NPF exports callback functions for all the I/O operations of the applications: open, close, read, write, ioctl, etc.The interaction with NDIS is asynchronous as well: events like the arrival of a new packet are notified to NPF through a callback function (Packet_tap() in this case). Furthermore, the interaction with NDIS and the NIC driver takes always place by means of non blocking functions: when NPF invokes a NDIS function, the call returns immediately; when the processing ends, NDIS invokes a specific NPF callback to inform that the function has finished. The driver exports a callback for any low-level operation, like sending packets, setting or requesting parameters on the NIC, etc.NPF structure basicsNext figure shows the structure of WinPcap, with particular reference to the NPF driver.Figure 2: NPF device driver. NPF is able to perform a number of different operations: capture, monitoring, dump to disk, packet injection. The following paragraphs will describe shortly each of these operations.Packet CaptureThe most important operation of NPF is packet capture. During a capture, the driver sniffs the packets using a network interface and delivers them intact to the user-level applications. The capture process relies on two main components: A packet filter that decides if an incoming packet has to be accepted and copied to the listening application. Most applications using NPF reject far more packets than those accepted, therefore a versatile and efficient packet filter is critical for good over-all performance. A packet filter is a function with boolean output that is applied to a packet. If the value of the function is true the capture driver copies the packet to the application; if it is false the packet is discarded. NPF packet filter is a bit more complex, because it determines not only if the packet should be kept, but also the amount of bytes to keep. The filtering system adopted by NPF derives from the BSD Packet Filter (BPF), a virtual processor able to execute filtering programs expressed in a pseudo-assembler and created at user level. The application takes a user-defined filter (e.g. “pick up all UDP packets”) and, using wpcap.dll, compiles them into a BPF program (e.g. “if the packet is IP and the protocol type field is equal to 17, then return true”). Then, the application uses the BIOCSETF IOCTL to inject the filter in the kernel. At this point, the program is executed for every incoming packet, and only the conformant packets are accepted. Unlike traditional solutions, NPF does not interpret the filters, but it executes them. For performance reasons, before using the filter NPF feeds it to a JIT compiler that translates it into a native 80x86 function. When a packet is captured, NPF calls this native function instead of invoking the filter interpreter, and this makes the process very fast. The concept behind this optimization is very similar to the one of Java jitters. A circular buffer to store the packets and avoid loss. A packet is stored in the buffer with a header that maintains information like the timestamp and the size of the packet. Moreover, an alignment padding is inserted between the packets in order to speed-up the access to their data by the applications. Groups of packets can be copied with a single operation from the NPF buffer to the applications. This improves performances because it minimizes the number of reads. If the buffer is full when a new packet arrives, the packet is discarded and hence its lost. Both kernel and user buffer can be changed at runtime for maximum versatility: packet.dll and wpcap.dll provide functions for this purpose. The size of the user buffer is very important because it determines the maximum amount of data that can be copied from kernel space to user space within a single system call. On the other hand, it can be noticed that also the minimum amount of data that can be copied in a single call is extremely important. In presence of a large value for this variable, the kernel waits for the arrival of several packets before copying the data to the user. This guarantees a low number of system calls, i.e. low processor usage, which is a good setting for applications like sniffers. On the other side, a small value means that the kernel will copy the packets as soon as the application is ready to receive them. This is excellent for real time applications (like, for example, ARP redirectors or bridges) that need the better responsiveness from the kernel. From this point of view, NPF has a configurable behavior, that allows users to choose between best efficiency or best responsiveness (or any intermediate situation).The wpcap library includes a couple of system calls that can be used both to set the timeout after which a read expires and the minimum amount of data that can be transferred to the application. By default, the read timeout is 1 second, and the minimum amount of data copied between the kernel and the application is 16K.Packet injectionNPF allows to write raw packets to the network. To send data, a user-level application performs a WriteFile() system call on the NPF device file. The data is sent to the network as is, without encapsulating it in any protocol, therefore the application will have to build the various headers for each packet. The application usually does not need to generate the FCS because it is calculated by the network adapter hardware and it is attached automatically at the end of a packet before sending it to the network.In normal situations, the sending rate of the packets to the network is not very high because of the need of a system call for each packet. For this reason, the possibility to send a single packet more than once with a single write system call has been added. The user-level application can set, with an IOCTL call (code pBIOCSWRITEREP), the number of times a single packet will be repeated: for example, if this value is set to 1000, every raw packet written by the application on the drivers device file will be sent 1000 times. This feature can be used to generate high speed traffic for testing purposes: the overload of context switches is no longer present, so performance is remarkably better.Network monitoringWinPcap offers a kernel-level programmable monitoring module, able to calculate simple statistics on the network traffic. The idea behind this module is shown in Figure 2: the statistics can be gathered without the need to copy the packets to the application, that simply receives and displays the results obtained from the monitoring engine. This allows to avoid great part of the capture overhead in terms of memory and CPU clocks.The monitoring engine is made of a classifier followed by a counter. The packets are classified using the filtering engine of NPF, that provides a configurable way to select a subset of the traffic. The data that pass the filter go to the counter, that keeps some variables like the number of packets and the amount of bytes accepted by the filter and updates them with the data of the incoming packets. These variables are passed to the user-level application at regular intervals whose period can be configured by the user. No buffers are allocated at kernel and user level.Dump to diskThe dump to disk capability can be used to save the network data to disk directly from kernel mode. Figure 3: packet capture versus kernel-level dump. In traditional systems, the path covered by the packets that are saved to disk is the one followed by the black arrows in Figure 3: every packet is copied several times, and normally 4 buffers are allocated: the one of the capture driver, the one in the application that keeps the captured data, the one of the stdio functions (or similar) that are used by the application to write on file, and finally the one of the file system. When the kernel-level traffic logging feature of NPF is enabled, the capture driver addresses the file system directly, hence the path covered by the packets is the one of the red dotted arrow: only two buffers and a single copy are necessary, the number of system call is drastically reduced, therefore the performance is considerably better. Current implementation dumps the to disk in the widely used libpcap format. It gives also the possibility to filter the traffic before the dump process in order to select the packet that will go to the disk. Further readingThe structure of NPF and its filtering engine derive directly from the one of the BSD Packet Filter (BPF), so if you are interested the subject you can read the following papers:- S. McCanne and V. Jacobson, The BSD Packet Filter: A New Architecture for User-level Packet Capture. Proceedings of the 1993 Winter USENIX Technical Conference (San Diego, CA, Jan. 1993), USENIX.- A. Begel, S. McCanne, S.L.Graham, BPF+: Exploiting Global Data-flow Optimization in a Generalized Packet Filter Architecture, Proceedings of ACM SIGCOMM 99, pages 123-134, Conference on Applications, technologies, architectures, and protocols for computer communications, August 30 - September 3, 1999, Cambridge, USANoteThe code documented in this manual is the one of the Windows NTx version of NPF.The Windows 9x code is very similar, but it is less efficient and lacks advanced features like kernel-mode dump.Define Documentation#define ADD_EAXi (i32)Value: emitm(&stream, 0x05, 1); emitm(&stream, i32, 4);add eax,i32 Definition at line 171 of file jitter.h. #define ADDib (r32, i8)Value: emitm(&stream, 0x83, 1); emitm(&stream, 24 3 | r32, 1); emitm(&stream, i8, 1);add r32,i8 Definition at line 182 of file jitter.h. #define ADDid (r32, i32)Value: emitm(&stream, 0x81, 1); emitm(&stream, 24 3 | r32, 1); emitm(&stream, i32, 4);add r32,i32 Definition at line 176 of file jitter.h. #define ADDrd (dr32, sr32)Value: emitm(&stream, 0x03, 1); emitm(&stream, 3 6 | (dr32 & 0x7) 3 | (sr32 & 0x7), 1);add dr32,sr32 Definition at line 166 of file jitter.h. #define AL0 Definition at line 59 of file jitter.h. #define ANDib (r8, i8)Value: emitm(&stream, 0x80, 1); emitm(&stream, 7 5 | r8, 1); emitm(&stream, i8, 1);and r8,i8 Definition at line 208 of file jitter.h. #define ANDid (r32, i32)Value: if (r32 = EAX) emitm(&stream, 0x25, 1); emitm(&stream, i32, 4); else emitm(&stream, 0x81, 1); emitm(&stream, 7 5 | r32, 1); emitm(&stream, i32, 4);and r32,i32 Definition at line 214 of file jitter.h. #define ANDrd (dr32, sr32)Value: emitm(&stream, 0x23, 1); emitm(&stream, 3 6 | (dr32 & 0x7) 3 | sr32 & 0x7, 1);and dr32,sr32 Definition at line 224 of file jitter.h. #define AX0 Definition at line 50 of file jitter.h. #define BL3 Definition at line 62 of file jitter.h. #define BP5 Definition at line 55 of file jitter.h. #define BSWAP (dr32)Value: emitm(&stream, 0xf, 1); emitm(&stream, 0x19 3 | dr32 , 1);bswap dr32 Definition at line 144 of file jitter.h. #define BX3 Definition at line 53 of file jitter.h. #define CL1 Definition at line 60 of file jitter.h. #define CMPid (dr32, i32)Value: if (dr32 = EAX) emitm(&stream, 0x3d, 1); emitm(&stream, i32, 4); else emitm(&stream, 0x81, 1); emitm(&stream, 0x1f 3 | (dr32 & 0x7), 1); emitm(&stream, i32, 4);cmp dr32,i32 Definition at line 282 of file jitter.h. #define CMPodd (dr32, sr32, off)Value: emitm(&stream, 3 4 | 3 | 1 3, 1); emitm(&stream, 1 6 | (dr32 & 0x7) 3 | sr32 & 0x7, 1); emitm(&stream, off, 1);cmp dr32,sr32off Definition at line 271 of file jitter.h. #define CMPrd (dr32, sr32)Value: emitm(&stream, 0x3b, 1); emitm(&stream, 3 6 | (dr32 & 0x7) 3 | sr32 & 0x7, 1);cmp dr32,sr32 Definition at line 277 of file jitter.h. #define CX1 Definition at line 51 of file jitter.h. #define DI7 Definition at line 57 of file jitter.h. #define DIVrd (r32)Value: emitm(&stream, 0xf7, 1); emitm(&stream, 15 4 | (r32 & 0x7), 1);div r32 Definition at line 203 of file jitter.h. #define DL2 Definition at line 61 of file jitter.h. #define DX2 Definition at line 52 of file jitter.h. #define EAX0 Definition at line 41 of file jitter.h. #define EBP5 Definition at line 46 of file jitter.h. #define EBX3 Definition at line 44 of file jitter.h. #define ECX1 Definition at line 42 of file jitter.h. #define EDI7 Definition at line 48 of file jitter.h. #define EDX2 Definition at line 43 of file jitter.h. #define ESI6 Definition at line 47 of file jitter.h. #define ESP4 Definition at line 45 of file jitter.h. #define JA (off32)Value: emitm(&stream, 0x0f, 1); emitm(&stream, 0x87, 1); emitm(&stream, off32, 4);ja off32 Definition at line 314 of file jitter.h. #define JAE (off32)Value: emitm(&stream, 0x0f, 1); emitm(&stream, 0x83, 1); emitm(&stream, off32, 4);jae off32 Definition at line 320 of file jitter.h. #define JE (off32)Value: emitm(&stream, 0x0f, 1); emitm(&stream, 0x84, 1); emitm(&stream, off32, 4);je off32 Definition at line 297 of file jitter.h. #define JG (off32)Value: emitm(&stream, 0x0f, 1); emitm(&stream, 0x8f, 1); emitm(&stream, off32, 4);jg off32 Definition at line 326 of file jitter.h. #define JGE (off32)Value: emitm(&stream, 0x0f, 1); emitm(&stream, 0x8d, 1); emitm(&stream, off32, 4);jge off32 Definition at line 332 of file jitter.h. #define JLE (off32)Value: emitm(&stream, 0x0f, 1); emitm(&stream, 0x8e, 1); emitm(&stream, off32, 4);jle off32 Definition at line 303 of file jitter.h. #define JLEb (off8)Value: emitm(&stream, 0x7e, 1); emitm(&stream, off8, 1);jle off8 Definition at line 309 of file jitter.h. #define JMP (off32)Value: emitm(&stream, 0xe9, 1); emitm(&stream, off32, 4);jmp off32 Definition at line 338 of file jitter.h. #define JNEb (off8)Value: emitm(&stream, 0x75, 1); emitm(&stream, off8, 1);jne off32 Definition at line 292 of file jitter.h. #define MOVid (r32, i32)emitm(&stream, 11 4 | 1 3 | r32 & 0x7, 1); emitm(&stream, i32, 4);mov r32,i32 Definition at line 105 of file jitter.h. #define MOVobb (dr8, sr32, or32)Value: emitm(&stream, 0x8a, 1); emitm(&stream, (dr8 & 0x7) 3 | 4 , 1); emitm(&stream, (or32 & 0x7) 3 | (sr32 & 0x7) , 1);mov dr8,sr32or32 Definition at line 132 of file jitter.h. #define MOVobd (dr32, sr32, or32)Value: emitm(&stream, 8 4 | 3 | 1 3, 1); emitm(&stream, (dr32 & 0x7) 3 | 4 , 1); emitm(&stream, (or32 & 0x7) 3 | (sr32 & 0x7) , 1);mov dr32,sr32or32 Definition at line 119 of file jitter.h. #define MOVobw (dr32, sr32, or32)Value: emitm(&stream, 0x66, 1); emitm(&stream, 8 4 | 3 | 1 3, 1); emitm(&stream, (dr32 & 0x7) 3 | 4 , 1); emitm(&stream, (or32 & 0x7) 3 | (sr32 & 0x7) , 1);mov dr16,sr32or32 Definition at line 125 of file jitter.h. #define MOVodd (dr32, sr32, off)Value: emitm(&stream, 8 4 | 3 | 1 3, 1); emitm(&stream, 1 6 | (dr32 & 0x7) 3 | sr32 & 0x7, 1); emitm(&stream, off, 1);mov dr32,sr32off Definition at line 113 of file jitter.h. #define MOVomd (dr32, or32, sr32)Value: emitm(&stream, 0x89, 1); emitm(&stream, (sr32 & 0x7) 3 | 4 , 1); emitm(&stream, (or32 & 0x7) 3 | (dr32 & 0x7) , 1);mov dr32or32,sr32 Definition at line 138 of file jitter.h. #define MOVrd (dr32, sr32)emitm(&stream, 8 4 | 3 | 1 3, 1); emitm(&stream, 3 6 | (dr32 & 0x7) 3 | sr32 & 0x7, 1);mov dr32,sr32 Definition at line 109 of file jitter.h. #define MULrd (r32)Value: emitm(&stream, 0xf7, 1); emitm(&stream, 7 5 | (r32 & 0x7), 1);mul r32 Definition at line 198 of file jitter.h. #define NEGd (r32)Value: emitm(&stream, 0xf7, 1); emitm(&stream, 27 3 | r32 & 0x7, 1);neg r32 Definition at line 266 of file jitter.h. #define ORid (r32, i32)Value: if (r32 = EAX) emitm(&stream, 0x0d, 1); emitm(&stream, i32, 4); else emitm(&stream, 0x81, 1); emitm(&stream, 25 3 | r32, 1); emitm(&stream, i32, 4);or r32,i32 Definition at line 234 of file jitter.h. #define ORrd (dr32, sr32)Value: emitm(&stream, 0x0b, 1); emitm(&stream, 3 6 | (dr32 & 0x7) 3 | sr32 & 0x7, 1);or dr32,sr32 Definition at line 229 of file jitter.h. #define POP (r32)emitm(&stream, 5 4 | 1 3 | r32 & 0x7, 1);pop r32 Definition at line 158 of file jitter.h. #define PUSH (r32)emitm(&stream, 5 4 | 0 3 | r32 & 0x7, 1);push r32 Definition at line 154 of file jitter.h. #define RET ( )emitm(&stream, 12 4 | 0 3 | 3, 1);ret Definition at line 162 of file jitter.h. #define SHL_CLrb (dr32)Value: emitm(&stream, 0xd3, 1); emitm(&stream, 7 5 | dr32 & 0x7, 1);shl dr32,cl Definition at line 250 of file jitter.h. #define SHLib (r32, i8)Value: emitm(&stream, 0xc1, 1); emitm(&stream, 7 5 | r32 & 0x7, 1); emitm(&stream, i8, 1);shl r32,i8 Definition at line 244 of file jitter.h. #define SHR_CLrb (dr32)Value: emitm(&stream, 0xd3, 1); emitm(&stream, 29 3 | dr32 & 0x7, 1);shr dr32,cl Definition at line 261 of file jitter.h. #define SHRib (r32, i8)Value: emitm(&stream, 0xc1, 1); emitm(&stream, 29 3 | r32 & 0x7, 1); emitm(&stream, i8, 1);shr r32,i8 Definition at line 255 of file jitter.h. #define SI6 Definition at line 56 of file jitter.h. #define SP4 Definition at line 54 of file jitter.h. #define SUB_EAXi (i32)Value: emitm(&stream, 0x2d, 1); emitm(&stream, i32, 4);sub eax,i32 Definition at line 193 of file jitter.h. #define SUBrd (dr32, sr32)Value: emitm(&stream, 0x2b, 1); emitm(&stream, 3 6 | (dr32 & 0x7) ProtocolReserved)Macro to obtain a NDIS_PACKET from a PACKET_RESERVED. #defineTRANSMIT_PACKETS256of packets that can be transmitted at the same time or with a single call to NdisSendPackets. #defineEXIT_SUCCESS(quantity)Macro used in the I/O routines to return the control to user-mode with a success status. #defineEXIT_FAILURE(quantity)Macro used in the I/O routines to return the control to user-mode with a failure status. 自定义类型typedef _INTERNAL_REQUESTINTERNAL_REQUESTStores an OID request. typedef _INTERNAL_REQUEST *PINTERNAL_REQUESTStores an OID request. typedef _PACKET_RESERVEDPACKET_RESERVEDContains a NDIS packet. typedef _PACKET_RESERVED *PPACKET_RESERVEDContains a NDIS packet. typedef _DEVICE_EXTENSIONDEVICE_EXTENSIONPort device extension. typedef _DEVICE_EXTENSION *PDEVICE_EXTENSIONPort device extension. typedef _CPU_Private_DataCpuPrivateDataKernel buffer of each CPU. typedef _OPEN_INSTANCEOPEN_INSTANCEContains the state of a running instance of the NPF driver. typedef _OPEN_INSTANCE *POPEN_INSTANCEContains the state of a running instance of the NPF driver. 枚举enum ADAPTER_BINDING_STATUS ADAPTER_UNBOUND, ADAPTER_BOUND, ADAPTER_UNBINDING 变量ULONGNCpu预处理定义文档#define BIOCGEVNAME7415 IOCTL code: get the name of the event that the driver signals when some data is present in the buffer. Command used by the application to retrieve the name of the global event associated with a NPF instance. The event is signaled by the driver when the kernel buffer contains enough data for a transfer. Definition at line 162 of file Packet.h. #define BIOCGSTATS9031 IOCTL code: get the capture stats. This command returns to the application the number of packets received and the number of packets dropped by an instance of the driver. Definition at line 100 of file Packet.h. #define BIOCISDUMPENDED7411 IOCTL code: Get the status of the kernel dump process. This command returns TRUE if the kernel dump is ended, i.e if one of the limits set with BIOCSETDUMPLIMITS (amount of bytes or number of packets) has been reached. Definition at line 197 of file Packet.h. #define BIOCISETLOBBEH7410 IOCTL code: set the loopback behavior. This IOCTL sets the loopback behavior of the driver with packets sent by itself: capture or drop. Definition at line 204 of file Packet.h. #define BIOCQUERYOID2147483652 IOCTL code: get an OID value. This IOCTL is used to perform an OID get operation on the NIC driver. Definition at line 145 of file Packet.h. #define BIOCSENDPACKETSNOSYNC9032 IOCTL code: Send a buffer containing multiple packets to the network, ignoring the timestamps. Command used to send a buffer of packets in a single system call. Every packet in the buffer is preceded by a sf_pkthdr structure. The timestamps of the packets are ignored, i.e. the packets are sent as fast as possible. The NPF_BufferedWrite() function is invoked to send the packets. Definition at line 171 of file Packet.h. #define BIOCSENDPACKETSSYNC9033 IOCTL code: Send a buffer containing multiple packets to the network, considering the timestamps. Command used to send a buffer of packets in a single system call. Every packet in the buffer is preceded by a sf_pkthdr structure. The timestamps of the packets are used to synchronize the write, i.e. the packets are sent to the network respecting the intervals specified in the sf_pkthdr structure assiciated with each packet. NPF_BufferedWrite() function is invoked to send the packets. Definition at line 181 of file Packet.h. #define BIOCSETBUFFERSIZE9592 IOCTL code: set kernel buffer size. This IOCTL is used to set a new size of the circular buffer associated with an instance of NPF. When a BIOCSETBUFFERSIZE command is received, the driver frees the old buffer, allocates the new one and resets all the parameters associated with the buffer in the OPEN_INSTANCE structure. The currently buffered packets are lost. Definition at line 80 of file Packet.h. #define BIOCSETDUMPFILENAME9029 IOCTL code: set the name of a the file used by kernel dump mode. This command opens a file whose name is contained in the IOCTL buffer and associates it with current NPf instance. The dump thread uses it to copy the content of the circular buffer to file. If a file was already opened, the driver closes it before opening the new one. Definition at line 154 of file Packet.h. #define BIOCSETDUMPLIMITS9034 IOCTL code: Set the dump file limits. This IOCTL sets the limits (maximum size and maximum number of packets) of the dump file created when the driver works in dump mode. Definition at line 189 of file Packet.h. #define BIOCSETEVENTHANDLE7920 This IOCTL passes the read event HANDLE allocated by the user (packet.dll) to kernel level. Parameter: HANDLE Parameter size: sizeof(HANDLE). If the caller is 32 bit, the parameter size is 4 bytes, even if sizeof(HANDLE) at kernel level is 8 bytes. Thats why in this IOCTL code handler we detect a 32bit calling process and do the necessary thunking. TODO GV:I will go to hell for this ugly IOCTL definition. We should use CTL_CODE! Definition at line 215 of file Packet.h. #define BIOCSETF9030 IOCTL code: set packet filtering program. This IOCTL sets a new packet filter in the driver. Before allocating any memory for the new filter, the bpf_validate() function is called to check the correctness of the filter. If this function returns TRUE, the filter is copied to the drivers memory, its address is stored in the bpfprogram field of the OPEN_INSTANCE structure associated with current instance of the driver, and the filter will be applied to every incoming packet. This command also empties the circular buffer used by current instance to store packets. This is done to avoid the presence in the buffer of packets that do not match the filter. Definition at line 92 of file Packet.h. #define BIOCSETOID2147483648 IOCTL code: set an OID value. This IOCTL is used to perform an OID set operation on the NIC driver. Definition at line 138 of file Packet.h. #define BIOCSMINTOCOPY7414 IOCTL code: set minimum amount of data in the kernel buffer that unlocks a read call. This command sets the OPEN_INSTANCE:MinToCopy member. Definition at line 131 of file Packet.h. #define BIOCSMODE7412 IOCTL code: set working mode. This IOCTL can be used to set the working mode of a NPF instance. The new mode, received by the driver in the buffer associated with the IOCTL command, can be MODE_CAPT for capture mode (the default), MODE_STAT for statistical mode or MODE_DUMP for dump mode. Definition at line 116 of file Packet.h. #define BIOCSRTIMEOUT7416 IOCTL code: set the read timeout. This command sets the maximum timeout after which a read is released, also if no data packets were received. Definition at line 107 of file Packet.h. #define BIOCSWRITEREP7413 IOCTL code: set number of physical repetions of every packet written by the app. Sets the number of times a single write call must be repeated. This command sets the OPEN_INSTANCE:Nwrites member, and is used to implement the multiple write feature of the driver. Definition at line 124 of file Packet.h. #define EXIT_FAILURE (quantity)Value: Irp-IoStatus.Information=quantity; Irp-IoStatus.Status = STATUS_UNSUCCESSFUL; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_UNSUCCESSFUL;Macro used in the I/O routines to return the control to user-mode with a failure status. Definition at line 464 of file Packet.h. #define EXIT_SUCCESS (quantity)Value: Irp-IoStatus.Information=quantity; Irp-IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS;Macro used in the I/O routines to return the control to user-mode with a success status. Definition at line 458 of file Packet.h. #define IMMEDIATE1 Immediate timeout. Forces a read call to return immediately. Definition at line 224 of file Packet.h. #define KERNEL_EVENT_NAMESPACELBaseNamedObjects Definition at line 66 of file Packet.h. #define MAX_REQUESTS32 Maximum number of simultaneous IOCTL requests. Definition at line 60 of file Packet.h. #define MODE_CAPT0x0 Capture working mode. Definition at line 218 of file Packet.h. #define MODE_DUMP0x10 Kernel dump working mode. Definition at line 221 of file Packet.h. #define MODE_MON0x2 Kernel monitoring mode. Definition at line 220 of file Packet.h. #define MODE_STAT0x1 Statistical working mode. Definition at line 219 of file Packet.h. #define NDIS_FLAGS_SKIP_LOOPBACK_W2K0x400 This is an undocumented flag for NdisSetPacketFlags() that allows to disable loopback reception. Definition at line 226 of file Packet.h. #define NPF_DISABLE_LOOPBACK1 Tells the driver to drop the packets sent by itself. This is usefult when building applications like bridges. Definition at line 235 of file Packet.h. #define NPF_ENABLE_LOOPBACK2 Tells the driver to capture the packets sent by itself. Definition at line 236 of file Packet.h. #define Packet_ALIGNMENTsizeof(int) Alignment macro. Defines the alignment size. Definition at line 62 of file Packet.h. #define Packet_WORDALIGN (x)(x)+(Packet_ALIGNMENT-1)&(Packet_ALIGNMENT-1)even multiple of Packet_ALIGNMENT. Alignment macro. Rounds up to the next Definition at line 63 of file Packet.h. #define PCAP_VERSION_MAJOR2 Major libpcap version of the dump file. Used by programs like tcpdump to recognize a drivers generated dump file. Definition at line 231 of file Packet.h. #define PCAP_VERSION_MINOR4 Minor libpcap version of the dump file. Used by programs like tcpdump to recognize a drivers generated dump file. Definition at line 232 of file Packet.h. #define RESERVED (_p)(PPACKET_RESERVED)(_p)-ProtocolReserved)Macro to obtain a NDIS_PACKET from a PACKET_RESERVED. Definition at line 301 of file Packet.h. #define TCPDUMP_MAGIC0xa1b2c3d4 Libpcap magic number. Used by programs like tcpdump to recognize a drivers generated dump file. Definition at line 230 of file Packet.h. #define TRANSMIT_PACKETS256 of packets that can be transmitted at the same time or with a single call to NdisSendPackets. Maximum number of packets in the transmit packet pool. This value is an upper bound to the number Definition at line 453 of file Packet.h. 自定义类型typedef struct _CPU_Private_Data CpuPrivateData Kernel buffer of each CPU. Structure containing the kernel buffer (and other CPU related fields) used to capture packets. typedef struct _DEVICE_EXTENSION DEVICE_EXTENSION Port device extension. Structure containing some data relative to every adapter on which NPF is bound. typedef struct _INTERNAL_REQUEST INTERNAL_REQUEST Stores an OID request. This structure is used by the driver to perform OID query or set operations on the underlying NIC driver. The OID operations be performed usually only by network drivers, but NPF exports this mechanism to user-level applications through an IOCTL interface. The driver uses this structure to wrap a NDIS_REQUEST structure. This allows to handle correctly the callback structure of NdisRequest(), handling multiple requests and maintaining information about the IRPs to complete. typedef struct _OPEN_INSTANCE OPEN_INSTANCE Contains the state of a running instance of the NPF driver. This is the most important structure of NPF: it is used by almost all the functions of the driver. An _OPEN_INSTANCE structure is associated with every user-level session, allowing concurrent access to the driver. typedef struct _PACKET_RESERVED PACKET_RESERVED Contains a NDIS packet. The driver uses this structure to wrap a NDIS_PACKET structure. This allows to handle correctly the callback structure of NdisTransferData(), handling multiple requests and maintaining information about the IRPs to complete. typedef struct _DEVICE_EXTENSION * PDEVICE_EXTENSION Port device extension. Structure containing some data relative to every adapter on which NPF is bound. typedef struct _INTERNAL_REQUEST * PINTERNAL_REQUEST Stores an OID request. This structure is used by the driver to perform OID query or set operations on the underlying NIC driver. The OID operations be performed usually only by network drivers, but NPF exports this mechanism to user-level applications through an IOCTL interface. The driver uses this structure to wrap a NDIS_REQUEST structure. This allows to handle correctly the callback structure of NdisRequest(), handling multiple requests and maintaining information about the IRPs to complete. typedef struct _OPEN_INSTANCE * POPEN_INSTANCE Contains the state of a running instance of the NPF driver. This is the most important structure of NPF: it is used by almost all the functions of the driver. An _OPEN_INSTANCE structure is associated with every user-level session, allowing concurrent access to the driver. typedef struct _PACKET_RESERVED * PPACKET_RESERVED Contains a NDIS packet. The driver uses this structure to wrap a NDIS_PACKET structure. This allows to handle correctly the callback structure of NdisTransferData(), handling multiple requests and maintaining information about the IRPs to complete. 枚举类型文档enum ADAPTER_BINDING_STATUS Enumerator: ADAPTER_UNBOUNDADAPTER_BOUNDADAPTER_UNBINDINGDefinition at line 430 of file Packet.h. 变量文档ULONG NCpu NPF 函数WinPcap核心资料 函数NTSTATUSDriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)The initialization routine of the driver. PWCHARgetAdaptersList (VOID)Returns the list of the MACs available on the system. PKEY_VALUE_PARTIAL_INFORMATIONgetTcpBindings (VOID)Returns the MACs that bind to TCP/IP. BOOLEANcreateDevice (IN OUT PDRIVER_OBJECT adriverObjectP, IN PUNICODE_STRING amacNameP, NDIS_HANDLE aProtoHandle)Creates a device for a given MAC. NTSTATUSNPF_Open (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)Opens a new instance of the driver. VOIDNPF_OpenAdapterComplete (IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status, IN NDIS_STATUS OpenErrorStatus)Ends the opening of an adapter. NTSTATUSNPF_Cleanup (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)Closes an instance of the driver. NTSTATUSNPF_Close (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)VOIDNPF_CloseAdapterComplete (IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status)Ends the closing of an adapter. NDIS_STATUSNPF_tap (IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MacReceiveContext, IN PVOID HeaderBuffer, IN UINT HeaderBufferSize, IN PVOID LookAheadBuffer, IN UINT LookaheadBufferSize, IN UINT PacketSize)Callback invoked by NDIS when a packet arrives from the network. VOIDNPF_TransferDataComplete (IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet, IN NDIS_STATUS Status, IN UINT BytesTransferred)Ends the transfer of a packet. VOIDNPF_ReceiveComplete (IN NDIS_HANDLE ProtocolBindingContext)Callback function that signals the end of a packet reception. NTSTATUSNPF_IoControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)Handles the IOCTL calls. VOIDNPF_RequestComplete (IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_REQUEST pRequest, IN NDIS_STATUS Status)Ends an OID request. NTSTATUSNPF_Write (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)Writes a raw packet to the network. INTNPF_BufferedWrite (IN PIRP Irp, IN PCHAR UserBuff, IN ULONG UserBuffSize, BOOLEAN sync)Writes a buffer of raw packets to the network. VOIDNPF_WaitEndOfBufferedWrite (POPEN_INSTANCE Open)Waits the completion of all the sends performed by NPF_BufferedWrite. VOIDNPF_SendComplete (IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pPacket, IN NDIS_STATUS Status)Ends a send operation. VOIDNPF_ResetComplete (IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status)Ends a reset of the adapter. VOIDNPF_Status (IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status, IN PVOID StatusBuffer, IN UINT StatusBufferSize)Callback for NDIS StatusHandler. Not used by NPF. VOIDNPF_StatusComplete (IN NDIS_HANDLE ProtocolBindingContext)Callback for NDIS StatusCompleteHandler. Not used by NPF. VOIDNPF_Unload (IN PDRIVER_OBJECT DriverObject)Function called by the OS when NPF is unloaded. NTSTATUSNPF_Read (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)Function that serves the users reads. NTSTATUSNPF_ReadRegistry (IN PWSTR *MacDriverName, IN PWSTR *PacketDriverName, IN PUNICODE_STRING RegistryPath)Reads the registry keys associated woth NPF if the driver is manually installed via the control panel. NTSTATUSNPF_QueryRegistryRoutine (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)Function used by NPF_ReadRegistry() to quesry the registry keys associated woth NPF if the driver is manually installed via the control panel. VOIDNPF_BindAdapter (OUT PNDIS_STATUS Status, IN NDIS_HANDLE BindContext, IN PNDIS_STRING DeviceName, IN PVOID SystemSpecific1, IN PVOID SystemSpecific2)Callback for NDIS BindAdapterHandler. Not used by NPF. VOIDNPF_UnbindAdapter (OUT PNDIS_STATUS Status, IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE UnbindContext)Callback for NDIS UnbindAdapterHandler. NTSTATUSNPF_OpenDumpFile (POPEN_INSTANCE Open, PUNICODE_STRING fileName, BOOLEAN append)Creates the file that will receive the packets when the driver is in dump mode. NTSTATUSNPF_StartDump (POPEN_INSTANCE Open)Starts dump to file. VOIDNPF_DumpThread (PVOID Open)The dump thread. NTSTATUSNPF_SaveCurrentBuffer (POPEN_INSTANCE Open)Saves the content of the packet buffer to the file associated with current instance. VOIDNPF_WriteDumpFile (PFILE_OBJECT FileObject, PLARGE_INTEGER Offset, ULONG Length, PMDL Mdl, PIO_STATUS_BLOCK IoStatusBlock)Writes a block of packets on the dump file. NTSTATUSNPF_CloseDumpFile (POPEN_INSTANCE Open)Closes the dump file associated with an instance of the driver. VOIDNPF_CloseOpenInstance (POPEN_INSTANCE pOpen)BOOLEANNPF_StartUsingBinding (IN POPEN_INSTANCE pOpen)VOIDNPF_StopUsingBinding (IN POPEN_INSTANCE pOpen)VOIDNPF_CloseBinding (IN POPEN_INSTANCE pOpen)NTSTATUSNPF_GetDeviceMTU (IN POPEN_INSTANCE pOpen, IN PIRP pIrp, OUT PUINT pMtu)UINTGetBuffOccupation (POPEN_INSTANCE Open)Returns the amount of bytes present in the packet buffer. JIT_BPF_Filter *BPF_jitter (struct bpf_insn *fp, INT nins)BPF jitter, builds an x86 function from a BPF program. BPF_filter_functionBPFtoX86 (struct bpf_insn *ins, UINT nins, INT *mem)Translates a set of BPF instructions in a set of x86 ones. voidBPF_Destroy_JIT_Filter (JIT_BPF_Filter *Filter)Deletes a filtering function that was previously created by BPF_jitter(). 函数文档void BPF_Destroy_JIT_Filter (JIT_BPF_Filter *Filter )Deletes a filtering function that was previously created by BPF_jitter(). Parameters: FilterThe filter to destroy.This function frees the variuos buffers (code, memory, etc.) associated with a filtering function. JIT_BPF_Filter* BPF_jitter (struct bpf_insn *fp, INTnins)BPF jitter, builds an x86 function from a BPF program. Parameters: fpThe BPF pseudo-assembly filter that will be translated into x86 code. ninsNumber of instructions of the input filter. Returns: The JIT_BPF_Filter structure containing the x86 filtering binary.BPF_jitter allocates the buffers for the new native filter and then translates the program pointed by fp calling BPFtoX86(). BPF_filter_function BPFtoX86 (struct bpf_insn *ins, UINTnins, INT *mem)Translates a set of BPF instructions in a set of x86 ones. Parameters: insPointer to the BPF instructions that will be translated into x86 code. ninsNumber of instructions to translate. memMemory used by the x86 function to emulate the RAM of the BPF pseudo processor. Returns: The x86 filtering function.This function does the hard work for the JIT compilation. It takes a group of BPF pseudo instructions and through the instruction macros defined in jitter.h it is able to create an function directly executable by NPF. BOOLEAN createDevice (IN OUT PDRIVER_OBJECTadriverObjectP, IN PUNICODE_STRINGamacNameP, NDIS_HANDLEaProtoHandle)Creates a device for a given MAC. Parameters: adriverObjectPThe driver object that will be associated with the device, i.e. the one of NPF. amacNamePThe name of the network interface that the device will point. aProtoHandleNDIS protocol handle of NPF. Returns: If the function succeeds, the return value is nonzero.NPF creates a device for every valid network adapter. The new device points to the NPF driver, but contains information about the original device. In this way, when the user opens the new device, NPF will be able to determine the correct adapter to use. NTSTATUS DriverEntry (IN PDRIVER_OBJECTDriverObject, IN PUNICODE_STRINGRegistryPath)The initialization routine of the driver. Parameters: DriverObjectThe driver object of NPF created by the system. RegistryPathThe registry path containing the keys related to the driver. Returns: A string containing a list of network adapters.DriverEntry is a mandatory function in a device driver. Like the main() of a user level program, it is called by the system when the driver is loaded in memory and started. Its purpose is to initialize the driver, performing all the allocations and the setup. In particular, DriverEntry registers all the drivers I/O callbacks, creates the devices, defines NPF as a protocol inside NDIS. PWCHAR getAdaptersList (VOID)Returns the list of the MACs available on the system. Returns: A string containing a list of network adapters.The list of adapters is retrieved from the SYSTEMCurrentControlSetControlClass4D36E972-E325-11CE-BFC1-08002BE10318 registry key. NPF tries to create its bindings from this list. In this way it is possible to be loaded and unloaded dynamically without passing from the control panel. UINT GetBuffOccupation (POPEN_INSTANCEOpen )Returns the amount of bytes present in the packet buffer. Parameters: OpenThe NPF instance that closes the file. PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings (VOID)Returns the MACs that bind to TCP/IP. Returns: Pointer to the registry key containing the list of adapters on which TCP/IP is bound.If getAdaptersList() fails, NPF tries to obtain the TCP/IP bindings through this function. VOID NPF_BindAdapter (OUT PNDIS_STATUSStatus, IN NDIS_HANDLEBindContext, IN PNDIS_STRINGDeviceName, IN PVOIDSystemSpecific1, IN PVOIDSystemSpecific2)Callback for NDIS BindAdapterHandler. Not used by NPF. Function called by NDIS when a new adapter is installed on the machine With Plug and Play. INT NPF_BufferedWrite (IN PIRPIrp, IN PCHARUserBuff, IN ULONGUserBuffSize, BOOLEANsync)Writes a buffer of raw packets to the network. Parameters: IrpPointer to the IRP containing the user request. UserBuffPointer to the buffer containing the packets to send. UserBuffSizeSize of the buffer with the packets. syncIf set to TRUE, the packets are transmitted respecting their timestamps. Returns: The amount of bytes actually sent. If the return value is smaller than the Size parameter, an error occurred during the send. The error can be caused by an adapter problem or by an inconsistent/bogus user buffer.This function is called by the OS in consequence of a BIOCSENDPACKETSNOSYNC or a BIOCSENDPACKETSSYNC IOCTL. The buffer received as input parameter contains an arbitrary number of packets, each of which preceded by a sf_pkthdr structure. NPF_BufferedWrite() scans the buffer and sends every packet via the NdisSend() function. When Sync is set to TRUE, the packets are synchronized with the KeQueryPerformanceCounter() function. This requires a remarkable amount of CPU, but allows to respect the timestamps associated with packets with a precision of some microseconds (depending on the precision of the performance counter of the machine). If Sync is false, the timestamps are ignored and the packets are sent as fat as possible. NTSTATUS NPF_Cleanup (IN PDEVICE_OBJECTDeviceObject, IN PIRPIrp)Closes an instance of the driver. Parameters: DeviceObjectPointer to the device object utilized by the user. IrpPointer to the IRP containing the user request. Returns: The status of the operation. See ntstatus.h in the DDK.This function is called when a running instance of the driver is closed by the user with a CloseHandle(). It stops the capture/monitoring/dump process, deallocates the memory and the objects associated with the instance and closing the files. The network adapter is then closed with a call to NdisCloseAdapter. NTSTATUS NPF_Close (IN PDEVICE_OBJECTDeviceObject, IN PIRPIrp)VOID NPF_CloseAdapterComplete (IN NDIS_HANDLEProtocolBindingContext, IN NDIS_STATUSStatus)Ends the closing of an adapter. Parameters: ProtocolBindingContextContext of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. StatusStatus of the close operation performed by NDIS.Callback function associated with the NdisCloseAdapter() NDIS function. It is invoked by NDIS when the NIC driver has finished a close operation that was previously started by NPF_Close(). VOID NPF_CloseBinding (IN POPEN_INSTANCEpOpen )NTSTATUS NPF_CloseDumpFile (POPEN_INSTANCEOpen )Closes the dump file associated with an instance of the driver. Parameters: OpenThe NPF instance that closes the file. Returns: The status of the operation. See ntstatus.h in the DDK. VOID NPF_CloseOpenInstance (POPEN_INSTANCEpOpen )VOID NPF_DumpThread (PVOIDOpen )The dump thread. Parameters: OpenThe NPF instance that creates the thread.This function moves the content of the NPF kernel buffer to file. It runs in the user context, so at lower priority than the TAP. NTSTATUS NPF_GetDeviceMTU (IN POPEN_INSTANCEpOpen, IN PIRPpIrp, OUT PUINTpMtu)NTSTATUS NPF_IoControl (IN PDEVICE_OBJECTDeviceObject, IN PIRPIrp)Handles the IOCTL calls. Parameters: DeviceObjectPointer to the device object utilized by the user. IrpPointer to the IRP containing the user request. Returns: The status of the operation. See ntstatus.h in the DDK.Once the packet capture driver is opened it can be configured from user-level applications with IOCTL commands using the DeviceIoControl() system call. NPF_IoControl receives and serves all the IOCTL calls directed to NPF. The following commands are recognized: BIOCSETBUFFERSIZE BIOCSETF BIOCGSTATS BIOCSRTIMEOUT BIOCSMODE BIOCSWRITEREP BIOCSMINTOCOPY BIOCSETOID BIOCQUERYOID BIOCSETDUMPFILENAME BIOCGEVNAME BIOCSENDPACKETSSYNC BIOCSENDPACKETSNOSYNC NTSTATUS NPF_Open (IN PDEVICE_OBJECTDeviceObject, IN PIRPIrp)Opens a new instance of the driver. Parameters: DeviceObjectPointer to the device object utilized by the user. IrpPointer to the IRP containing the user request. Returns: The status of the operation. See ntstatus.h in the DDK.This function is called by the OS when a new instance of the driver is opened, i.e. when a user application performs a CreateFile on a device created by NPF. NPF_Open allocates and initializes variables, objects and buffers needed by the new instance, fills the OPEN_INSTANCE structure associated with it and opens the adapter with a call to NdisOpenAdapter. VOID NPF_OpenAdapterComplete (IN NDIS_HANDLEProtocolBindingContext, IN NDIS_STATUSStatus, IN NDIS_STATUSOpenErrorStatus)Ends the opening of an adapter. Parameters: ProtocolBindingContextContext of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. StatusStatus of the opening operation performed by NDIS. OpenErrorStatusnot used by NPF.Callback function associated with the NdisOpenAdapter() NDIS function. It is invoked by NDIS when the NIC driver has finished an open operation that was previously started by NPF_Open(). NTSTATUS NPF_OpenDumpFile (POPEN_INSTANCEOpen, PUNICODE_STRINGfileName, BOOLEANappend)Creates the file that will receive the packets when the driver is in dump mode. Parameters: OpenThe NPF instance that opens the file. fileNamePointer to a UNICODE string containing the name of the file. appendBoolean value that specifies if the data must be appended to the file. Returns: The status of the operation. See ntstatus.h in the DDK. NTSTATUS NPF_QueryRegistryRoutine (IN PWSTRValueName, IN ULONGValueType, IN PVOIDValueData, IN ULONGValueLength, IN PVOIDContext, IN PVOIDEntryContext)Function used by NPF_ReadRegistry() to quesry the registry keys associated woth NPF if the driver is manually installed via the control panel. Normally not used in recent versions of NPF. NTSTATUS NPF_Read (IN PDEVICE_OBJECTDeviceObject, IN PIRPIrp)Function that serves the users reads. Parameters: DeviceObjectPointer to the device used by the user. IrpPointer to the IRP containing the user request. Returns: The status of the operation. See ntstatus.h in the DDK.This function is called by the OS in consequence of user ReadFile() call. It moves the data present in the kernel buffer to the user buffer associated with Irp. First of all, NPF_Read checks the amount of data in kernel buffer associated with current NPF instance. If the instance is in capture mode and the buffer contains more than OPEN_INSTANCE:MinToCopy bytes, NPF_Read moves the data in the user buffer and returns immediatly. In this way, the read performed by the user is not blocking. If the buffer contains less than MinToCopy bytes, the applications request isnt satisfied immediately, but its blocked until at least MinToCopy bytes arrive from the net or the timeout on this read expires. The timeout is kept in the OPEN_INSTANCE:TimeOut field. If the instance is in statistical mode or in dump mode, the applications request is blocked until the timeout kept in OPEN_INSTANCE:TimeOut expires. NTSTATUS NPF_ReadRegistry (IN PWSTR *MacDriverName, IN PWSTR *PacketDriverName, IN PUNICODE_STRINGRegistryPath)Reads the registry keys associated woth NPF if the driver is manually installed via the control panel. Normally not used in recent versions of NPF. VOID NPF_ReceiveComplete (IN NDIS_HANDLEProtocolBindingContext )Callback function that signals the end of a packet reception. Parameters: ProtocolBindingContextContext of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance.does nothing in NPF VOID NPF_RequestComplete (IN NDIS_HANDLEProtocolBindingContext, IN PNDIS_REQUESTpRequest, IN NDIS_STATUSStatus)Ends an OID request. Parameters: ProtocolBindingContextContext of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. pRequestPointer to the completed OID request. StatusStatus of the operation.Callback function associated with the NdisRequest() NDIS function. It is invoked by NDIS when the NIC driver has finished an OID request operation that was previously started by NPF_IoControl(). VOID NPF_ResetComplete (IN NDIS_HANDLEProtocolBindingContext, IN NDIS_STATUSStatus)Ends a reset of the adapter. Parameters: ProtocolBindingContextContext of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. StatusStatus of the operation.Callback function associated with the NdisReset() NDIS function. It is invoked by NDIS when the NIC driver has finished an OID request operation that was previously started by NPF_IoControl(), in an IOCTL_PROTOCOL_RESET command. NTSTATUS NPF_SaveCurrentBuffer (POPEN_INSTANCEOpen )Saves the content of the packet buffer to the file associated with current instance. Parameters: OpenThe NPF instance that creates the thread.Used by NPF_DumpThread() and NPF_CloseDumpFile(). VOID NPF_SendComplete (IN NDIS_HANDLEProtocolBindingContext, IN PNDIS_PACKETpPacket, IN NDIS_STATUSStatus)Ends a send operation. Parameters: ProtocolBindingContextContext of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. pPacketPointer to the NDIS PACKET structure used by NPF_Write() to send the packet. StatusStatus of the operation.Callback function associated with the NdisSend() NDIS function. It is invoked by NDIS when the NIC driver has finished an OID request operation that was previously started by NPF_Write(). NTSTATUS NPF_StartDump (POPEN_INSTANCEOpen )Starts dump to file. Parameters: OpenThe NPF instance that opens the file. Returns: The status of the operation. See ntstatus.h in the DDK.This function performs two operations. First, it writes the libpcap header at the beginning of the file. Second, it starts the thread that asynchronously dumps the network data to the file. BOOLEAN NPF_StartUsingBinding (IN POPEN_INSTANCEpOpen )VOID NPF_Status (IN NDIS_HANDLEProtocolBindingContext, IN NDIS_STATUSStatus, IN PVOIDStatusBuffer, IN UINTStatusBufferSize)Callback for NDIS StatusHandler. Not used by NPF. VOID NPF_StatusComplete (IN NDIS_HANDLEProtocolBindingContext )Callback for NDIS StatusCompleteHandler. Not used by NPF. VOID NPF_StopUsingBinding (IN POPEN_INSTANCEpOpen )NDIS_STATUS NPF_tap (IN NDIS_HANDLEProtocolBindingContext, IN NDIS_HANDLEMacReceiveContext, IN PVOIDHeaderBuffer, IN UINTHeaderBufferSize, IN PVOIDLookAheadBuffer, IN UINTLookaheadBufferSize, IN UINTPacketSize)Callback invoked by NDIS when a packet arrives from the network. Parameters: ProtocolBindingContextContext of the function. Points to a OPEN_INSTANCE structure that identifies the NPF instance to which the packets are destined. MacReceiveContextHandle that identifies the underlying NIC driver that generated the request. This value must be used when the packet is transferred from the NIC driver with NdisTransferData(). HeaderBufferPointer to the buffer in the NIC driver memory that contains the header of the packet. HeaderBufferSizeSize in bytes of the header. LookAheadBufferPointer to the buffer in the NIC drivers memory that contains the incoming packets data available to NPF. This value does not necessarily coincide with the actual size of the packet, since only a portion can be available at this time. The remaining portion can be obtained with the NdisTransferData() NDIS function. LookaheadBufferSizeSize in bytes of the lookahead buffer. PacketSizeTotal size of the incoming packet, excluded the header. Returns: The status of the operation. See ntstatus.h in the DDK.NPF_tap() is called by the underlying NIC for every incoming packet. It is the most important and one of the most complex functions of NPF: it executes the filter, runs the statistical engine (if the instance is in statistical mode), gathers the timestamp, moves the packet in the buffer. NPF_tap() is the only function, along with the filtering ones, that is executed for every incoming packet, therefore it is carefully optimized. VOID NPF_TransferDataComplete (IN NDIS_HANDLEProtocolBindingContext, IN PNDIS_PACKETPacket, IN NDIS_STATUSStatus, IN UINTBytesTransferred)Ends the transfer of a packet. Parameters: ProtocolBindingContextContext of the function. Contains a pointer to the OPEN_INSTANCE structure associated with the current instance. PacketPointer to the NDIS_PACKET structure that received the packet data. StatusStatus of the transfer operation. BytesTransferredAmount of bytes transferred.Callback function associated with the NdisTransferData() NDIS function. It is invoked by NDIS when the NIC driver has finished the transfer of a packet from the NIC driver memory to the NPF circular buffer. VOID NPF_UnbindAdapter (OUT PNDIS_STATUSStatus, IN NDIS_HANDLEProtocolBindingContext, IN NDIS_HANDLEUnbindContext)Callback for NDIS UnbindAdapterHandler. Parameters: Statusout variable filled by NPF_UnbindAdapter with the status of the unbind operation. ProtocolBindingContextContext of the function. Contains a pointer to the OPEN_INSTANCE structure associated with current instance. UnbindContextSpecifies a handle, supplied by NDIS, that NPF can use to complete the opration.Function called by NDIS when a new adapter is removed from the machine without shutting it down. NPF_UnbindAdapter closes the adapter calling NdisCloseAdapter() and frees the memory and the structures associated with it. It also releases the waiting user-level app and closes the dump thread if the instance is in dump mode. VOID NPF_Unload (IN PDRIVER_OBJECTDriverObject )Function called by the OS when NPF is unloaded. Parameters: DriverObjectThe driver object of NPF created by the system.This is the last function executed when the driver is unloaded from the system. It frees global resources, delete the devices and deregisters the protocol. The driver can be unloaded by the user stopping the NPF service (from control panel or with a console net stop npf). VOID NPF_WaitEndOfBufferedWrite (POPEN_INSTANCEOpen )Waits the completion of all the sends performed by NPF_BufferedWrite. Parameters: OpenPointer to open context structureUsed by NPF_BufferedWrite to wait the completion of all the sends before returning the control to the user. NTSTATUS NPF_Write (IN PDEVICE_OBJECTDeviceObject, IN PIRPIrp)Writes a raw packet to the network. Parameters: DeviceObjectPointer to the device object on which the user wrote the packet. IrpPointer to the IRP containing the user request. Returns: The status of the operation. See ntstatus.h in the DDK.This function is called by the OS in consequence of user WriteFile() call, with the data of the packet that must be sent on the net. The data is contained in the buffer associated with Irp, NPF_Write takes it and delivers it to the NIC driver via the NdisSend() function. The Nwrites field of the OPEN_INSTANCE structure associated with Irp indicates the number of copies of the packet that will be sent: more than one copy of the packet can be sent for performance reasons. VOID NPF_WriteDumpFile (PFILE_OBJECTFileObject, PLARGE_INTEGEROffset, ULONGLength, PMDLMdl, PIO_STATUS_BLOCKIoStatusBlock)Writes a block of packets on the dump file. Parameters: FileObjectThe file object that will receive the packets. OffsetThe offset in the file where the packets will be put. LengthThe amount of bytes to write. MdlMDL mapping the memory buffer that will be written to disk. IoStatusBlockUsed by the function to return the status of the operation. Returns: The status of the operation. See ntstatus.h in the DDK.NPF_WriteDumpFile addresses directly the file system, creating a custom IRP and using it to send a portion of the NPF circular buffer to disk. This function is used by NPF_DumpThread(). 如何编译WinPcapWinPcap核心资料 这部分内容将告诉你,在不同的win32平台上,如何编译WinPcap。源代码可以在WinPcap 网站上获得。编译驱动编译NPF时,有两个主要的路径:Windows NTx和Windows 9x。注意,因为NPF驱动是与平台相关的,所以,为了连接正确的DDK库,我们强烈建议编译的时候,要选择将来会被使用的那个操作系统。比如,如果你使用Windows NT 4 DDK库赖编译驱动,那么在Windows2000或其他操作系统上运行,将不会那么顺利了。在Windows NT4平台上编译驱动软件需求: Microsoft Driver Developer Kit (DDK) for Windows NT4 能在Visual Studio 6上编译的Microsoft Platform Software Development Kit (SDK)的较新的版本(最新的平台发布于2003年2月)。这个版本的PSDK在Microsoft的网站上提供,参见:http:/www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm。同时,它也可以在线订阅:http:/www.qmedia.ca/launch/psdk.htm,同时,在微软的用户下载网站里,也为微软MSDN用户提供了订阅。 Microsoft Visual C+ 6.0 with Service Pack 5 or 6 (这两个版本在微软的网站上都有提供).如果你的系统符合上面的三个要求,那么请按照下列步骤:1. 从Windows NT 开始 菜单,选择 程序 然后选择 Development Kits, 然后选择 Windows NT4 DDK. 在这里,如果你想建立一个调试版本,你可以选择Checked Build Environment ,如果你想建立一个发布版本,你可以选择 Free Build Environment 。 2. 一个命令提示框将被打开。用cd命令移到WinPcap文件夹下的PacketNTx文件夹,输入命令: CompileDriver这个脚本会产生一个驱动 (npf.sys),然后,二进制数据会被放入下列文件夹中的一个 o Free Build Environment: winpcapPacketNTxdriverbinNT4i386free o Checked Build Environment: winpcapPacketNTxdriverbinNT4i386checked 警告: 有时,在编译驱动的过程中,会产生很多last line incomplete错误提示。忽略这些错误,并且让编译过程继续进行。它们的产生是由于某些版本的DDK的bug所引起的。在Windows 2000/XP/2003/Vista(32位和64位AMD64)平台上编译驱动 软件需求: Microsoft Driver Developer Kit (DDK) for Windows Windows XP or Windows Server 2003. 对于 WinPcap 4.0, 最合适的 DDK environment 是 DDK for Windows Server 2003SP1, 也可以称作 DDK 3790.1830. 注意: 在Windows 2000下使用旧的DDK是可以的,但是,你需要手动地修改编译脚本来禁用PREfast。(PREfast是一个静态代码分析工具,捆绑在较新的DDK中)如果你的系统满足以上需求,那么请按下列步骤进行:1. 从Windows NT 开始 菜单,选择 程序 然后选择 Development Kits, 然后选择 Windows XXX DDK., XXX 就是你的目的系统,然后选择 Build Environments. o 32bit 驱动: 选择 Windows 2000 ,然后,如果你想建立一个发布版本的程序,请选择 Windows 2000 Free Build Environment,如果你想建立一个调试版本的程序,请选择 Windows 2000 Checked Build Environment 。 o 64bit AMD64 驱动: 选择 Windows Server 2003 然后,如果你想建立一个发布版本的程序,请选择 Windows Server 2003 Free x64 Build Environment 如果你想建立一个调试版本的程序,请选择 Windows Server 2003 Checked x64 Build Environment 。 2. 一个命令提示框将被打开。用cd命令移到WinPcap文件夹下的PacketNTx文件夹,输入命令: CompileDriver这个脚本会产生一个驱动 (npf.sys),然后,二进制数据会被放入下列文件夹中的一个 o 32bit driver (both Free and Checked Build): winpcapPacketNTxdriverbin2ki386 o 64bit AMD64 driver (both Free and Checked Build): winpcapPacketNTxdriverbinxpamd64 在Windows 9x平台上编译驱动注意: WinPcap已经不再支持这个Windows平台。然而,一些在代码包中,基于这些操作系统的源代码还是可用的。 要在Windows 9x上编译驱动,你需要: Driver Developer Kit (DDK) for Windows 95/98/ME 能在Visual Studio 6上编译的Microsoft Platform Software Development Kit (SDK)的较新的版本(最新的平台发布于2003年2月)。这个版本的PSDK在Microsoft的网站上提供,参见:http:/www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm。同时,它也可以在线订阅:http:/www.qmedia.ca/launch/psdk.htm,同时,在微软的用户下载网站里,也为微软MSDN用户提供了订阅。 Microsoft Visual C+ 6.0 with Service Pack 5 or 6 (这两个版本在微软的网站上都有提供).然后,按下列步骤进行:1. 打开DOS 2. 进入 VisualC+ BIN 目录 (比如 C:DEVSTUDIOVCBIN) 并执行命令 Vcvars323. 进入 SDK 目录 (比如 C:MSSDK) 并执行命令Setenv sdk_pathsdk_path 是 SDK 目录(比如 Setenv C:MSSDK) 4. 进入 DDK 目录 (比如 C:DDK) 并执行命令Ddkenv 32 net5. 进入驱动源代码所在目录,并执行命令nmake rtl来获得发布版本,或者执行nmake来获得调试版本发布版本的 packet.vxd 将会出现在 retail 目录下, 调试版本将会出现在 debug 目录下 警告: 在一些系统中, NMAKE 使用工具并不能启动 ADRC2VXD, 这一位着驱动二进制数据的产生是正确的,不过没有版本信息。我们还不知道引起这个问题的原因。编译 packet.dll这个DLL的源路径在 PacketNTxdll 注意: WinPcap已经不再支持这个Windows平台。然而,一些在代码包中,基于这些操作系统的源代码还是可用的。 软件需求: 能在Visual Studio 6上编译的Microsoft Platform Software Development Kit (SDK)的较新的版本(最新的平台发布于2003年2月)。这个版本的PSDK在Microsoft的网站上提供,参见:http:/www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm。同时,它也可以在线订阅:http:/www.qmedia.ca/launch/psdk.htm,同时,在微软的用户下载网站里,也为微软MSDN用户提供了订阅。 注意: 如果你使用 Microsoft Visual Studio .NET ,那么平台SDK是不需要编译packet.dll的。 Microsoft Visual C+ 6.0 with Service Pack 5 or 6 (这两个版本在微软的网站上都有提供). 如果你想用WinPcap建立一个支持CACE无线包捕获技术的程序,你需要从http:/www.cacetech.com/products/airpcap.htm下载AirPcap developers pack。The AirPcap developers pack需要被解压到和WinPcap同一个目录下。要编译 PACKET.DLL, 在Visual C+平台下,加载一个包含了目录 PacketNTxdllproject 的工程。 以下是一些工程的配置: PacketNT - Win32 Release: 标准发行版配置 PacketNT - Win32 Debug: 标准调试版配置 PacketNT - Win32 Release No AirPcap: 标准发行版配置,不支持AirPcap PacketNT - Win32 Debug No AirPcap: 标准调试版配置, 不支持AirPcap PacketNT - Win32 NT4 Release: 运行于NT4的发行版本配置,不包括对Wan和IP helper API的支持。 PacketNT - Win32 NT4 Debug: 运行于NT4的调试版本配置,不包括对Wan和IP helper API的支持。 PacketNT - Win32 Release Vista: 运行于Vista的发行版本配置,不包括对Wan的支持(以及NetMon API)。 PacketNT - Win32 Debug Vista: 运行于Vista的调试版本配置,不包括对Wan的支持(以及NetMon API)。 WanPacket - Win32 Release: 使用WanPacket 库的发行版本,用于同NetMon API进行广域网捕捉。 WanPacket - Win32 Debug: 使用WanPacket 库的调试版本,用于同NetMon API进行广域网捕捉。 选择一种需要的配置,并建立工程来获取二进制文件。编译 wpcap.dllwpcap.dll 可以在任何 Win32 平台下编译,产生的dll是平台相关的。系统需求: Microsoft Visual C+ 6.0 with Service Pack 5 or 6 (这两个版本在微软的网站上都有提供). 能在Visual Studio 6上编译的Microsoft Platform Software Development Kit (SDK)的较新的版本(最新的平台发布于2003年2月)。这个版本的PSDK在Microsoft的网站上提供,参见:http:/www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm。同时,它也可以在线订阅:http:/www.qmedia.ca/launch/psdk.htm,同时,在微软的用户下载网站里,也为微软MSDN用户提供了订阅。 注意: 如果你使用 Microsoft Visual Studio .NET ,那么平台SDK是不需要编译wpcap.dll的。 WinPcap源代码的工程文件位于 winpcapwpcapprj . 从 Visual C+ 开发平台上加载wpcap.dsw并构建程序。 如果你想用WinPcap建立一个支持CACE无线包捕获技术的程序,你需要从http:/www.cacetech.com/products/airpcap.htm下载AirPcap developers pack。The AirPcap developers pack需要被解压到和WinPcap同一个目录下。 以下是八种工程的配置:不支持远程捕获,支持AirPcap,不支持DAG, Wpcap debug: 目录输出: winpcapwpcapprjDebug Wpcap release: 目录输出: winpcapwpcapprjRelease支持远程捕获,不支持AirPcap,不支持DAG Wpcap debug REMOTE NO AIRPCAP: 目录输出: winpcapwpcapprjDebug_REMOTE_NO_AIRPCAP Wpcap release REMOTE NO AIRPCAP: 目录输出: winpcapwpcapprjRelease_REMOTE_NO_AIRPCAP 支持远程捕获,支持AirPcap,不支持DAG Wpcap debug REMOTE: 目录输出: winpcapwpcapprjDebug_REMOTE Wpcap release REMOTE: 目录输出: winpcapwpcapprjRelease_REMOTE支持远程捕获,支持AirPcap,支持DAG Wpcap debug REMOTE DAG: 目录输出: winpcapwpcapprjDebug_REMOTE_DAG Wpcap release REMOTE DAG: 目录输出: winpcapwpcapprjRelease_REMOTE_DAG 注意: wpcap.dll 包含了来自 www.tcpdump.org 的libpcap的源代码,对于远程捕获有一些修改。 你能包含和构建一个不同版本的libpcap,只需要简单地把它拷贝到winpcapwpcapprj下的WinPcap源代码中即可,但是,你必须使用Debug(调试)或Release(发行)进行配置。Packet.dll - 数据包驱动APIWinPcap核心资料 Packet.dll 是一个动态链接库,并提供了一些低层的函数,用来: 安装,启动和停止NPF设备驱动 从NPF驱动接收数据包 通过NPF驱动发送数据包 获取可用的网络适配器列表 获取适配器的不同信息,比如设备描述,地址列表和掩码 查询并设置一个低层的适配器参数 packet.dll有两个版本:第一个运行于 Windows 95/98/ME, 第二个运行于 Windows NT/2000/XP.提供了对WinPcap的低层函数的访问,这种访问依赖于系统。这个库维护了所有的依赖于系统的细节(比如管理设备,协助操作系统管理适配器,在注册表中查找信息等),并且输出一个可以在所有Windows操作系统中通用的API。这样,操作系统和库就可以在所有的 Windows操作系统下重新编译并运行了。然而,不是所有的packet.dll的API是完全可移植的:有些高级特性,比如内核模式下的堆处理,只能运行在WinNTx版本的WinPcap,Win9x的packet.dll不提供这样的功能。换种说法就是,NTx版本要比9x版本功能强大,也就是说,在Win9x版本中提供的所有函数,在WinNTx中都有。这个库的另一个重要特性,就是维护了NPF驱动。当程序试图访问适配器时,Packet.dll在后台安装和启动了驱动,这些对编程人员来说,是透明的。这就避免了用户通过控制面板,手动安装驱动程序。非常重要的注意事项,请仔细阅读!Packet.dll 的源代码是开放的,并且有完整的文档。 然而,packet.dll应该被认为是核心API,因为它建立在WinPcap内部的目的,就是为真正的公共API:wpcap.dll建立一层隔离墙。 由于应用程序使用WinPcap的常规(normal)方式和推荐(suggested)方式,是通过wpcap.dll,所以,我们不保证packet.dll的API不会在未来的WinPcap的发行版中被修改,并且,我们不提供这个API的支持。由于这个原因,在这个指南中,不会含有有关Packet.dll的文档。用户可以自行使用Doxygen来创建它们,或者阅读代码中的注释。 WinPcap用户指南模块定义输出函数过滤串表达式的语法使用WinPcap编程详细描述这节包含了有关wpcap.dll的用户指南。wpcap.dll是一个包含了公共WinPcap API的动态链接库,它输出了一组依赖于系统的函数,用来捕获和分析网络流量。这些函数的用途有: 获取网络适配器列表 获取网络适配器的不同信息,比如网卡描述和地址的列表 使用PC的一个网卡来捕获数据包 向网络上发送数据 有效保存数据包到磁盘,并通过一个接口捕获数据包,就如同从网卡捕获数据一样 使用高级语言创建一个数据包过滤器,并把它们应用到数据捕获中去 wpcap.dll 与 libpcap 兼容,后者是Unix平台下知名的数据包捕获库。这个兼容性意味着你可以开发可移植的网络工具,这些工具既可以运行在Win32系列的操作系统,也可以运行在与Unix兼容的机器上。这一章节的一些内容直接来自于tcpdump和libpcap的用户手册,它们由tcpdump.org的开发人员维护。因此,如果你想阅读最新的文档,你可以登录 www.tcpdump.org.注意有些函数被标注为 deprecated 或 discouraged。这些标签的意思是: discouraged: 这个函数的功能已经被另一个函数所代替,不过这个函数仍然可以使用。 deprecated: 这些函数只是为了可移植性和向下兼容而存在,它应该被禁止使用,并且强烈建议你使用另一个等价的函数来代替它定义WinPcap用户指南 结构体struct pcap_file_headerlibpcap堆文件首部 更多.struct pcap_pkthdr堆文件中包的首部 更多.struct pcap_stat保存一个接口统计值的结构体 更多.struct pcap_if接口列表中的一项,在 pcap_findalldevs()中被使用 更多.struct pcap_addr表示一个接口地址,在 pcap_findalldevs()中被使用 更多.宏定义#definePCAP_VERSION_MAJOR2主要libpcap堆文件版本 #definePCAP_VERSION_MINOR4次要libpcap堆文件版本 #definePCAP_ERRBUF_SIZE256libpcap错误信息缓存的大小 #definePCAP_IF_LOOPBACK0x00000001接口是回调的 (interface is loopback) #defineMODE_CAPT0捕捉模式,在调用 pcap_setmode() 时被使用。 #defineMODE_STAT1统计模式,在调用 pcap_setmode() 时被使用。 自定义类型typedef intbpf_int3232-bit integer typedef u_intbpf_u_int3232-bit unsigned integer typedef pcappcap_t一个已打开的捕捉实例的描述符。这个结构体对用户来说是不透明的,它通过wpcap.dll提供的函数,维护了它的内容。 typedef pcap_dumperpcap_dumper_tlibpcap存储文件的描述符 typedef pcap_ifpcap_if_t接口列表中的一项,参见 pcap_if。 typedef pcap_addrpcap_addr_t表示一个接口地址,参见 pcap_addr。 详细描述wpcap.dll的定义 定义文档#define MODE_CAPT0 捕获模式,在调用 pcap_setmode() 时被使用 第 172 行,文件 incs/pcap.h. #define MODE_STAT1 统计模式,在调用 pcap_setmode() 时被使用 第 173 行,文件 incs/pcap.h. #define PCAP_ERRBUF_SIZE256 libpcap错误信息缓存的大小 第 59 行,文件 incs/pcap.h. #define PCAP_IF_LOOPBACK0x00000001 接口是回调的 (interface is loopback) 第 156 行,文件 incs/pcap.h. #define PCAP_VERSION_MAJOR2 主要libpcap堆文件版本 第 56 行,文件 incs/pcap.h. #define PCAP_VERSION_MINOR4 次要libpcap堆文件版本 第 57 行,文件 incs/pcap.h. 自定义类型文档typedef int bpf_int32 32-bit integer 与拥有bpf.h的系统兼容,bpf的自定义类型已经提供了对64位的支持。 第 66 行,文件 incs/pcap.h. typedef u_int bpf_u_int32 32-bit unsigned integer 第 67 行,文件 incs/pcap.h. typedef struct pcap_addr pcap_addr_t 表示一个接口地址,参见 pcap_addr. 第 73 行,文件 incs/pcap.h. typedef struct pcap_dumper pcap_dumper_t libpcap存储文件的描述符 第 71 行,文件 incs/pcap.h. typedef struct pcap_if pcap_if_t 接口列表的一项,参见 pcap_if. 第 72 行,文件 incs/pcap.h. typedef struct pcap pcap_t 一个已打开的捕捉实例的描述符。这个结构体对用户来说是不透明的,它通过wpcap.dll提供的函数,维护了它的内容。 第 70 行,文件 incs/pcap.h. 输出函数WinPcap用户指南 与Unix兼容的函数这些函数是libpcap库的一部分,因此,既能运行在Windows平台,也能运行于Linux平台。 注意: 在函数 pcap_open_live(), pcap_open_dead(), pcap_open_offline(), pcap_setnonblock(), pcap_getnonblock(), pcap_findalldevs(), pcap_lookupdev(), 和 pcap_lookupnet() 中的errbuf假定至少有 PCAP_ERRBUF_SIZE 个字符。 typedef void(*)pcap_handler (u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)接受数据包的回调函数的原型 pcap_t *pcap_open_live (const char *device, int snaplen, int promisc, int to_ms, char *ebuf)在网络中打开一个活动的捕获 pcap_t *pcap_open_dead (int linktype, int snaplen)在还没开始捕获时,创建一个pcap_t的结构体 pcap_t *pcap_open_offline (const char *fname, char *errbuf)打开一个 tcpdump/libpcap 格式的存储文件,来读取数据包 pcap_dumper_t *pcap_dump_open (pcap_t *p, const char *fname)打开一个文件来写入数据包 intpcap_setnonblock (pcap_t *p, int nonblock, char *errbuf)在阻塞和非阻塞模式间切换 intpcap_getnonblock (pcap_t *p, char *errbuf)获得一个接口的非阻塞状态信息 intpcap_findalldevs (pcap_if_t *alldevsp, char *errbuf)构造一个可打开的网络设备的列表 pcap_open_live() voidpcap_freealldevs (pcap_if_t *alldevsp)释放一个接口列表,这个列表将被 pcap_findalldevs()返回 char *pcap_lookupdev (char *errbuf)返回系统中第一个合法的设备 intpcap_lookupnet (const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp, char *errbuf)返回接口的子网和掩码 intpcap_dispatch (pcap_t *p, int cnt, pcap_handler callback, u_char *user)收集一组数据包 intpcap_loop (pcap_t *p, int cnt, pcap_handler callback, u_char *user)收集一组数据包 u_char *pcap_next (pcap_t *p, struct pcap_pkthdr *h)返回下一个可用的数据包 intpcap_next_ex (pcap_t *p, struct pcap_pkthdr *pkt_header, const u_char *pkt_data)从一个设备接口,或从一个脱机文件中,读取一个数据包 voidpcap_breakloop (pcap_t *)设置一个标志位,这个标志位会强制 pcap_dispatch() 或 pcap_loop() 返回,而不是继续循环。 intpcap_sendpacket (pcap_t *p, u_char *buf, int size)发送一个原始数据包 voidpcap_dump (u_char *user, const struct pcap_pkthdr *h, const u_char *sp)将数据包保存到磁盘 longpcap_dump_ftell (pcap_dumper_t *)返回存储文件的文件位置 intpcap_compile (pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask)编译数据包过滤器,将程序中高级的过滤表达式,转换成能被内核级的过滤引擎所处理的东西。 (参见 过滤表达式语法) intpcap_compile_nopcap (int snaplen_arg, int linktype_arg, struct bpf_program *program, char *buf, int optimize, bpf_u_int32 mask)在不需要打开适配器的情况下,编译数据包过滤器。这个函数能将程序中高级的过滤表达式,转换成能被内核级的过滤引擎所处理的东西。 (参见 过滤表达式语法) intpcap_setfilter (pcap_t *p, struct bpf_program *fp)在捕获过程中绑定一个过滤器 voidpcap_freecode (struct bpf_program *fp)释放一个过滤器 intpcap_datalink (pcap_t *p)返回适配器的链路层 intpcap_list_datalinks (pcap_t *p, int *dlt_buf)列出数据链 intpcap_set_datalink (pcap_t *p, int dlt)将当前pcap描述符的数据链的类型,设置成dlt给出的类型。返回-1表示设置失败。 intpcap_datalink_name_to_val (const char *name)转换一个数据链类型的名字,即将具有DLT_remove的DLT_name,转换成符合数据链类型的值。转换是区分大小写的,返回-1表示错误。 const char *pcap_datalink_val_to_name (int dlt)将数据链类型值转换成合适的数据链类型的名字。返回NULL表示转换失败。 const char *pcap_datalink_val_to_description (int dlt)将数据链类型值转换成合适的数据链类型的简短的名字。返回NULL表示转换失败。 intpcap_snapshot (pcap_t *p)返回发送给应用程序的数据包部分的大小(字节) intpcap_is_swapped (pcap_t *p)当前存储文件使用与当前系统不同的字节序列时,返回true intpcap_major_version (pcap_t *p)返回正在用来写入存储文件的pcap库的主要版本号 intpcap_minor_version (pcap_t *p)返回正在用来写入存储文件的pcap库的次要版本号 FILE *pcap_file (pcap_t *p)返回一个脱机捕获文件的标准流 intpcap_stats (pcap_t *p, struct pcap_stat *ps)返回当前捕获的统计信息 voidpcap_perror (pcap_t *p, char *prefix)在标准错误输出台打印最后一次pcap库错误的文本信息,前缀是prefix。 char *pcap_geterr (pcap_t *p)返回最后一次pcap库错误的文本信息 char *pcap_strerror (int error)提供这个函数,以防 strerror() 不能使用。 const char *pcap_lib_version (void)返回一个字符串,这个字符串保存着libpcap库的版本信息。注意,它除了版本号,还包含了更多的信息。 voidpcap_close (pcap_t *p)关闭一个和p关联的文件,并释放资源 FILE *pcap_dump_file (pcap_dumper_t *p)返回一个由 pcap_dump_open()打开的存储文件的标准输入输出流 intpcap_dump_flush (pcap_dumper_t *p)将输出缓冲写入存储文件,这样,任何使用 pcap_dump() 存储,但还没有写入文件的数据包,会被立刻写入文件。 返回-1表示出错,返回0表示成功。 voidpcap_dump_close (pcap_dumper_t *p)关闭一个存储文件 Windows平台专用的扩展函数本节中的函数是从libpcap扩展而来,为了提供更强大的功能(比如远程数据捕获,数据包缓存尺寸变化或高精度的数据包注入)。然而,目前,这些函数只能用于Windows平台。PAirpcapHandlepcap_get_airpcap_handle (pcap_t *p)返回一个和适配器相关联的AirPcap句柄。这个句柄可以被用来改变和CACE无线技术有关的设置。boolpcap_offline_filter (struct bpf_program *prog, const struct pcap_pkthdr *header, const u_char *pkt_data)当给定的过滤器应用于一个脱机数据包时,返回true intpcap_live_dump (pcap_t *p, char *filename, int maxsize, int maxpacks)将捕获保存到文件 intpcap_live_dump_ended (pcap_t *p, int sync)返回内核堆处理的状态。例如,告诉我们由 pcap_live_dump() 定义的限制条件是否已经满足。 pcap_stat *pcap_stats_ex (pcap_t *p, int *pcap_stat_size)返回当前捕获的统计信息。 intpcap_setbuff (pcap_t *p, int dim)设置与当前适配器关联的内核缓存大小 intpcap_setmode (pcap_t *p, int mode)将接口p的工作模式设置为mode intpcap_setmintocopy (pcap_t *p, int size)设置内核一次调用所受到的最小数据总数 HANDLEpcap_getevent (pcap_t *p)返回与接口p关联的事件句柄 pcap_send_queue *pcap_sendqueue_alloc (u_int memsize)分配一个发送队列 voidpcap_sendqueue_destroy (pcap_send_queue *queue)销毁一个发送队列 intpcap_sendqueue_queue (pcap_send_queue *queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)将数据包加入到发送队列 u_intpcap_sendqueue_transmit (pcap_t *p, pcap_send_queue *queue, int sync)将一个发送队列发送至网络 intpcap_findalldevs_ex (char *source, struct pcap_rmtauth *auth, pcap_if_t *alldevs, char *errbuf)创建一个网络设备列表,它们可以由 pcap_open()打开。 intpcap_createsrcstr (char *source, int type, const char *host, const char *port, const char *name, char *errbuf)接收一组字符串(hot name,port,.),并根据新的格式,返回一个完整的源字符串(比如:rpcap:/1.2.3.4/eth0) intpcap_parsesrcstr (const char *source, int *type, char *host, char *port, char *name, char *errbuf)解析一个源字符串,并返回分离出来的内容。 pcap_t *pcap_open (const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf)打开一个用来捕获或发送流量(仅WinPcap)的通用源。 pcap_samp *pcap_setsampling (pcap_t *p)为数据包捕获定义一个采样方法 SOCKETpcap_remoteact_accept (const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf)阻塞,直到网络连接建立。(仅用于激活模式) intpcap_remoteact_close (const char *host, char *errbuf)释放一个活动连接 (仅用于激活模式). voidpcap_remoteact_cleanup ()清除一个正在用来等待活动连接的socket intpcap_remoteact_list (char *hostlist, char sep, int size, char *errbuf)返回一个主机名,这个主机和我们建立了活动连接。(仅用于激活模式) 详细描述wpcap.dll的输出函数 自定义类型文档typedef void(*) pcap_handler(u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data) Prototype of the callback function that receives the packets. When pcap_dispatch() or pcap_loop() are called by the user, the packets are passed to the application by means of this callback. user is a user-defined parameter that contains the state of the capture session, it corresponds to the user parameter of pcap_dispatch() and pcap_loop(). pkt_header is the header associated by the capture driver to the packet. It is NOT a protocol header. pkt_data points to the data of the packet, including the protocol headers. Definition at line 27 of file funcs/pcap.h. Function Documentationvoid pcap_breakloop (pcap_t *)set a flag that will force pcap_dispatch() or pcap_loop() to return rather than looping. They will return the number of packets that have been processed so far, or -2 if no packets have been processed so far. This routine is safe to use inside a signal handler on UNIX or a console control handler on Windows, as it merely sets a flag that is checked within the loop. The flag is checked in loops reading packets from the OS - a signal by itself will not necessarily terminate those loops - as well as in loops processing a set of packets returned by the OS. Note that if you are catching signals on UNIX systems that support restarting system calls after a signal, and calling pcap_breakloop() in the signal handler, you must specify, when catching those signals, that system calls should NOT be restarted by that signal. Otherwise, if the signal interrupted a call reading packets in a live capture, when your signal handler returns after calling pcap_breakloop(), the call will be restarted, and the loop will not terminate until more packets arrive and the call completes. Note: pcap_next() will, on some platforms, loop reading packets from the OS; that loop will not necessarily be terminated by a signal, so pcap_breakloop() should be used to terminate packet processing even if pcap_next() is being used. pcap_breakloop() does not guarantee that no further packets will be processed by pcap_dispatch() or pcap_loop() after it is called; at most one more packet might be processed. If -2 is returned from pcap_dispatch() or pcap_loop(), the flag is cleared, so a subsequent call will resume reading packets. If a positive number is returned, the flag is not cleared, so a subsequent call will return -2 and clear the flag. void pcap_close (pcap_t *p )close the files associated with p and deallocates resources. See also: pcap_open_live(), pcap_open_offline(), pcap_open_dead() int pcap_compile (pcap_t *p, struct bpf_program *fp, char *str, intoptimize, bpf_u_int32netmask)Compile a packet filter, converting an high level filtering expression (see Filtering expression syntax) in a program that can be interpreted by the kernel-level filtering engine. pcap_compile() is used to compile the string str into a filter program. program is a pointer to a bpf_program struct and is filled in by pcap_compile(). optimize controls whether optimization on the resulting code is performed. netmask specifies the IPv4 netmask of the network on which packets are being captured; it is used only when checking for IPv4 broadcast addresses in the filter program. If the netmask of the network on which packets are being captured isnt known to the program, or if packets are being captured on the Linux any pseudo-interface that can capture on more than one network, a value of 0 can be supplied; tests for IPv4 broadcast addreses wont be done correctly, but all other tests in the filter program will be OK. A return of -1 indicates an error in which case pcap_geterr() may be used to display the error text. See also: pcap_open_live(), pcap_setfilter(), pcap_freecode(), pcap_snapshot() int pcap_compile_nopcap (intsnaplen_arg, intlinktype_arg, struct bpf_program *program, char *buf, intoptimize, bpf_u_int32mask)Compile a packet filter without the need of opening an adapter. This function converts an high level filtering expression (see Filtering expression syntax) in a program that can be interpreted by the kernel-level filtering engine. pcap_compile_nopcap() is similar to pcap_compile() except that instead of passing a pcap structure, one passes the snaplen and linktype explicitly. It is intended to be used for compiling filters for direct BPF usage, without necessarily having called pcap_open(). A return of -1 indicates an error; the error text is unavailable. (pcap_compile_nopcap() is a wrapper around pcap_open_dead(), pcap_compile(), and pcap_close(); the latter three routines can be used directly in order to get the error text for a compilation error.) Look at the Filtering expression syntax section for details on the str parameter. See also: pcap_open_live(), pcap_setfilter(), pcap_freecode(), pcap_snapshot() int pcap_createsrcstr (char *source, inttype, const char *host, const char *port, const char *name, char *errbuf)Accept a set of strings (host name, port, .), and it returns the complete source string according to the new format (e.g. rpcap:/1.2.3.4/eth0). This function is provided in order to help the user creating the source string according to the new format. An unique source string is used in order to make easy for old applications to use the remote facilities. Think about tcpdump, for example, which has only one way to specify the interface on which the capture has to be started. However, GUI-based programs can find more useful to specify hostname, port and interface name separately. In that case, they can use this function to create the source string before passing it to the pcap_open() function. Parameters: source,:a user-allocated buffer that will contain the complete source string wen the function returns.The source will start with an identifier according to the new Source Specification Syntax .This function assumes that the allocated buffer is at least PCAP_BUF_SIZE bytes.type,:its value tells the type of the source we want to create. It can assume the values defined in the Source identification Codes .host,:an user-allocated buffer that keeps the host (e.g. foo.bar.com) we want to connect to. It can be NULL in case we want to open an interface on a local host.port,:an user-allocated buffer that keeps the network port (e.g. 2002) we want to use for the RPCAP protocol. It can be NULL in case we want to open an interface on a local host.name,:an user-allocated buffer that keeps the interface name we want to use (e.g. eth0). It can be NULL in case the return string (i.e. source) has to be used with the pcap_findalldevs_ex(), which does not require the interface name.errbuf,:a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) that will contain the error message (in case there is one).Returns: 0 if everything is fine, -1 if some errors occurred. The string containing the complete source is returned in the source variable.Warning: If the source is longer than PCAP_BUF_SIZE, the excess characters are truncated. int pcap_datalink (pcap_t *p )Return the link layer of an adapter. returns the link layer type; link layer types it can return include: DLT_NULL BSD loopback encapsulation; the link layer header is a 4-byte field, in host byte order, containing a PF_ value from socket.h for the network-layer protocol of the packet. Note that host byte order is the byte order of the machine on which the packets are captured, and the PF_ values are for the OS of the machine on which the packets are captured; if a live capture is being done, host byte order is the byte order of the machine capturing the packets, and the PF_ values are those of the OS of the machine capturing the packets, but if a savefile is being read, the byte order and PF_ values are not necessarily those of the machine reading the capture file. DLT_EN10MB Ethernet (10Mb, 100Mb, 1000Mb, and up) DLT_IEEE802: IEEE 802.5 Token Ring DLT_ARCNET: ARCNET DLT_SLIP: SLIP; the link layer header contains, in order: a. a 1-byte flag, which is 0 for packets received by the machine and 1 for packets sent by the machine; b. a 1-byte field, the upper 4 bits of which indicate the type of packet, as per RFC 1144: 0x40: an unmodified IP datagram (TYPE_IP); 0x70: an uncompressed-TCP IP datagram (UNCOMPRESSED_TCP), with that byte being the first byte of the raw IP header on the wire, containing the connection number in the protocol field; 0x80: a compressed-TCP IP datagram (COMPRESSED_TCP), with that byte being the first byte of the compressed TCP/IP datagram header;c. for UNCOMPRESSED_TCP, the rest of the modified IP header, and for COMPRESSED_TCP, the compressed TCP/IP datagram header; d. for a total of 16 bytes; the uncompressed IP datagram follows the header. DLT_PPP: PPP; if the first 2 bytes are 0xff and 0x03, its PPP in HDLC-like framing, with the PPP header following those two bytes, otherwise its PPP without framing, and the packet begins with the PPP header. DLT_FDDI: FDDI DLT_ATM_RFC1483: RFC 1483 LLC/SNAP-encapsulated ATM; the packet begins with an IEEE 802.2 LLC header. DLT_RAW: raw IP; the packet begins with an IP header. DLT_PPP_SERIAL: PPP in HDLC-like framing, as per RFC 1662, or Cisco PPP with HDLC framing, as per section 4.3.1 of RFC 1547; the first byte will be 0xFF for PPP in HDLC-like framing, and will be 0x0F or 0x8F for Cisco PPP with HDLC framing. DLT_PPP_ETHER: PPPoE; the packet begins with a PPPoE header, as per RFC 2516. DLT_C_HDLC: Cisco PPP with HDLC framing, as per section 4.3.1 of RFC 1547. DLT_IEEE802_11: IEEE 802.11 wireless LAN DLT_FRELAY: Frame Relay DLT_LOOP: OpenBSD loopback encapsulation; the link layer header is a 4-byte field, in network byte order, containing a PF_ value from OpenBSDs socket.h for the network-layer protocol of the packet. Note that, if a savefile is being read, those PF_ values are not necessarily those of the machine reading the capture file. DLT_LINUX_SLL: Linux cooked capture encapsulation; the link layer header contains, in order: o a 2-byte packet type, in network byte order, which is one of: i. packet was sent to us by somebody else ii. packet was broadcast by somebody else iii. packet was multicast, but not broadcast, by somebody else iv. packet was sent by somebody else to somebody else v. packet was sent by uso a 2-byte field, in network byte order, containing a Linux ARPHRD_ value for the link layer device type; o a 2-byte field, in network byte order, containing the length of the link layer address of the sender of the packet (which could be 0); o an 8-byte field containing that number of bytes of the link layer header (if there are more than 8 bytes, only the first 8 are present); o 2-byte field containing an Ethernet protocol type, in network byte order, or containing 1 for Novell 802.3 frames without an 802.2 LLC header or 4 for frames beginning with an 802.2 LLC header. DLT_LTALK: Apple LocalTalk; the packet begins with an AppleTalk LLAP header. DLT_PFLOG: OpenBSD pflog; the link layer header contains, in order: o a 4-byte PF_ value, in network byte order; o a 16-character interface name; o a 2-byte rule number, in network byte order; o a 2-byte reason code, in network byte order, which is one of: i. match ii. bad offset iii. fragment iv. short v. normalize vi. memory -a 2-byte action code, in network byte order, which is one of: vii. passed viii. dropped ix. scrubbedo a 2-byte direction, in network byte order, which is one of: i. incoming or outgoing ii. incoming iii. outgoing DLT_PRISM_HEADER: Prism monitor mode information followed by an 802.11 header. DLT_IP_OVER_FC: RFC 2625 IP-over-Fibre Channel, with the link-layer header being the Network_Header as described in that RFC. DLT_SUNATM: SunATM devices; the link layer header contains, in order: o a 1-byte flag field, containing a direction flag in the uppermost bit, which is set for packets transmitted by the machine and clear for packets received by the machine, and a 4-byte traffic type in the low-order 4 bits, which is one of: i. raw traffic ii. LANE traffic iii. LLC-encapsulated traffic iv. MARS traffic v. IFMP traffic vi. ILMI traffic vii. Q.2931 traffico a 1-byte VPI value; o a 2-byte VCI field, in network byte order. DLT_IEEE802_11_RADIO: link-layer information followed by an 802.11 header - see http:/www.shaftnet.org/pizza/software/capturefrm.txt for a description of the link-layer information. DLT_ARCNET_LINUX: ARCNET, with no exception frames, reassembled packets rather than raw frames, and an extra 16-bit offset field between the destination host and type bytes. DLT_LINUX_IRDA: Linux-IrDA packets, with a DLT_LINUX_SLL header followed by the IrLAP header.See also: pcap_list_datalinks(), pcap_set_datalink(), pcap_datalink_name_to_val() int pcap_datalink_name_to_val (const char *name )Translates a data link type name, which is a DLT_ name with the DLT_ removed, to the corresponding data link type value. The translation is case-insensitive. -1 is returned on failure. const char* pcap_datalink_val_to_description (intdlt )Translates a data link type value to a short description of that data link type. NULL is returned on failure. const char* pcap_datalink_val_to_name (intdlt )Translates a data link type value to the corresponding data link type name. NULL is returned on failure. int pcap_dispatch (pcap_t *p, intcnt, pcap_handlercallback, u_char *user)Collect a group of packets. pcap_dispatch() is used to collect and process packets. cnt specifies the maximum number of packets to process before returning. This is not a minimum number; when reading a live capture, only one bufferful of packets is read at a time, so fewer than cnt packets may be processed. A cnt of -1 processes all the packets received in one buffer when reading a live capture, or all the packets in the file when reading a savefile. callback specifies a routine to be called with three arguments: a u_char pointer which is passed in from pcap_dispatch(), a const struct pcap_pkthdr pointer, and a const u_char pointer to the first caplen (as given in the struct pcap_pkthdr a pointer to which is passed to the callback routine) bytes of data from the packet (which wont necessarily be the entire packet; to capture the entire packet, you will have to provide a value for snaplen in your call to pcap_open_live() that is sufficiently large to get all of the packets data - a value of 65535 should be sufficient on most if not all networks). The number of packets read is returned. 0 is returned if no packets were read from a live capture (if, for example, they were discarded because they didnt pass the packet filter, or if, on platforms that support a read timeout that starts before any packets arrive, the timeout expires before any packets arrive, or if the file descriptor for the capture device is in non-blocking mode and no packets were available to be read) or if no more packets are available in a savefile. A return of -1 indicates an error in which case pcap_perror() or pcap_geterr() may be used to display the error text. A return of -2 indicates that the loop terminated due to a call to pcap_breakloop() before any packets were processed. If your application uses pcap_breakloop(), make sure that you explicitly check for -1 and -2, rather than just checking for a return value name and the other ones in the linked list) are already ready to be used in the pcap_open() call. Vice versa, the output that comes from pcap_findalldevs() must be formatted with the new pcap_createsrcstr() before passing the source identifier to the pcap_open(). Parameters: source,:a char* buffer that keeps the source localtion, according to the new WinPcap syntax. This source will be examined looking for adapters (local or remote) (e.g. source can be rpcap:/ for local adapters or rpcap:/host:port for adapters on a remote host) or pcap files (e.g. source can be file:/c:/myfolder/).The strings that must be prepended to the source in order to define if we want local/remote adapters or files is defined in the new Source Specification Syntax .auth,:a pointer to a pcap_rmtauth structure. This pointer keeps the information required to authenticate the RPCAP connection to the remote host. This parameter is not meaningful in case of a query to the local host: in that case it can be NULL.alldevs,:a struct pcap_if_t pointer, which will be properly allocated inside this function. When the function returns, it is set to point to the first element of the interface list; each element of the list is of type struct pcap_if_t.errbuf,:a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) that will contain the error message (in case there is one).Returns: 0 if everything is fine, -1 if some errors occurred. The list of the devices is returned in the alldevs variable. When the function returns correctly, alldevs cannot be NULL. In other words, this function returns -1 also in case the system does not have any interface to list.The error message is returned in the errbuf variable. An error could be due to several reasons: libpcap/WinPcap was not installed on the local/remote host the user does not have enough privileges to list the devices / files a network problem the RPCAP version negotiation failed other errors (not enough memory and others).Warning: There may be network devices that cannot be opened with pcap_open() by the process calling pcap_findalldevs(), because, for example, that process might not have sufficient privileges to open them for capturing; if so, those devices will not appear on the list. The interface list must be deallocated manually by using the pcap_freealldevs(). void pcap_freealldevs (pcap_if_t *alldevsp )Free an interface list returned by pcap_findalldevs(). pcap_freealldevs() is used to free a list allocated by pcap_findalldevs(). See also: pcap_findalldevs() void pcap_freecode (struct bpf_program *fp )Free a filter. pcap_freecode() is used to free up allocated memory pointed to by a bpf_program struct generated by pcap_compile() when that BPF program is no longer needed, for example after it has been made the filter program for a pcap structure by a call to pcap_setfilter(). See also: pcap_compile(), pcap_compile_nopcap() PAirpcapHandle pcap_get_airpcap_handle (pcap_t *p )Returns the AirPcap handler associated with an adapter. This handler can be used to change the wireless-related settings of the CACE Technologies AirPcap wireless capture adapters. Note: THIS FUNCTION SHOULD BE CONSIDERED PROVISIONAL, AND MAY BE REPLACED IN THE FUTURE BY A MORE COMPLETE SET OF FUNCTIONS FOR WIRELESS SUPPORT.pcap_get_airpcap_handle() allows to obtain the airpcap handle of an open adapter. This handle can be used with the AirPcap API functions to perform wireless-releated operations, e.g. changing the channel or enabling WEP decryption. For more details about the AirPcap wireless capture adapters, see http:/www.cacetech.com/products/airpcap.htm Parameters: p,:handle to an open libpcap adapterReturns: a pointer to an open AirPcap handle, used internally by the libpcap open adapter. NULL if the libpcap adapter doesnt have wireless support through AirPcap. char* pcap_geterr (pcap_t *p )return the error text pertaining to the last pcap library error. Note: the pointer Return will no longer point to a valid error message string after the pcap_t passed to it is closed; you must use or copy the string before closing the pcap_t.See also: pcap_perror() HANDLE pcap_getevent (pcap_t *p )Return the handle of the event associated with the interface p. This event can be passed to functions like WaitForSingleObject() or WaitForMultipleObjects() to wait until the drivers buffer contains some data without performing a read. We disourage the use of this function because it is not portable. See also: pcap_open_live() int pcap_getnonblock (pcap_t *p, char *errbuf)Get the non-blocking state of an interface. pcap_getnonblock() returns the current non-blocking state of the capture descriptor; it always returns 0 on savefiles. If there is an error, -1 is returned and errbuf is filled in with an appropriate error message. See also: pcap_setnonblock() int pcap_is_swapped (pcap_t *p )returns true if the current savefile uses a different byte order than the current system. const char* pcap_lib_version (void)Returns a pointer to a string giving information about the version of the libpcap library being used; note that it contains more information than just a version number. int pcap_list_datalinks (pcap_t *p, int *dlt_buf)list datalinks pcap_list_datalinks() is used to get a list of the supported data link types of the interface associated with the pcap descriptor. pcap_list_datalinks() allocates an array to hold the list and sets *dlt_buf. The caller is responsible for freeing the array. -1 is returned on failure; otherwise, the number of data link types in the array is returned. See also: pcap_datalink(), pcap_set_datalink(), pcap_datalink_name_to_val() int pcap_live_dump (pcap_t *p, char *filename, intmaxsize, intmaxpacks)Save a capture to file. Note: : this function does not work in current version of WinPcap.pcap_live_dump() dumps the network traffic from an interface to a file. Using this function the dump is performed at kernel level, therefore it is more efficient than using pcap_dump(). The parameters of this function are an interface descriptor (obtained with pcap_open_live(), a string with the name of the dump file, the maximum size of the file (in bytes) and the maximum number of packets that the file will contain. Setting maxsize or maxpacks to 0 means no limit. When maxsize or maxpacks are reached, the dump ends. pcap_live_dump() is non-blocking, threfore Return immediately. pcap_live_dump_ended() can be used to check the status of the dump process or to wait until it is finished. pcap_close() can instead be used to end the dump process. Note that when one of the two limits is reached, the dump is stopped, but the file remains opened. In order to correctly flush the data and put the file in a consistent state, the adapter must be closed with pcap_close(). See also: pcap_live_dump_ended(), pcap_open_live(), pcap_close(), pcap_dump_open(), pcap_dump() int pcap_live_dump_ended (pcap_t *p, intsync)Return the status of the kernel dump process, i.e. tells if one of the limits defined with pcap_live_dump() has been reached. Note: : this function does not work in current version of WinPcap.pcap_live_dump_ended() informs the user about the limits that were set with a previous call to pcap_live_dump() on the interface pointed by p: if the return value is nonzero, one of the limits has been reched and the dump process is currently stopped. If sync is nonzero, the function blocks until the dump is finished, otherwise Return immediately. Warning: if the dump process has no limits (i.e. if the maxsize and maxpacks arguments of pcap_live_dump() were both 0), the dump process will never stop, therefore setting sync to TRUE will block the application on this call forever.See also: pcap_live_dump() char* pcap_lookupdev (char *errbuf )Return the first valid device in the system. Deprecated: Use pcap_findalldevs() or pcap_findalldevs_ex() instead.pcap_lookupdev() returns a pointer to a network device suitable for use with pcap_open_live() and pcap_lookupnet(). If there is an error, NULL is returned and errbuf is filled in with an appropriate error message. See also: pcap_findalldevs(), pcap_open_live() int pcap_lookupnet (const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp, char *errbuf)Return the subnet and netmask of an interface. Deprecated: Use pcap_findalldevs() or pcap_findalldevs_ex() instead.pcap_lookupnet() is used to determine the network number and mask associated with the network device device. Both netp and maskp are bpf_u_int32 pointers. A return of -1 indicates an error in which case errbuf is filled in with an appropriate error message. See also: pcap_findalldevs() int pcap_loop (pcap_t *p, intcnt, pcap_handlercallback, u_char *user)Collect a group of packets. pcap_loop() is similar to pcap_dispatch() except it keeps reading packets until cnt packets are processed or an error occurs. It does not return when live read timeouts occur. Rather, specifying a non-zero read timeout to pcap_open_live() and then calling pcap_dispatch() allows the reception and processing of any packets that arrive when the timeout occurs. A negative cnt causes pcap_loop() to loop forever (or at least until an error occurs). -1 is returned on an error; 0 is returned if cnt is exhausted; -2 is returned if the loop terminated due to a call to pcap_breakloop() before any packets were processed. If your application uses pcap_breakloop(), make sure that you explicitly check for -1 and -2, rather than just checking for a return value 0. See also: pcap_dispatch(), pcap_next(), pcap_open_live(), pcap_open_offline(), pcap_handler int pcap_major_version (pcap_t *p )return the major version number of the pcap library used to write the savefile. See also: pcap_minor_version() int pcap_minor_version (pcap_t *p )return the minor version number of the pcap library used to write the savefile. See also: pcap_major_version() u_char* pcap_next (pcap_t *p, struct pcap_pkthdr *h)Return the next available packet. pcap_next() reads the next packet (by calling pcap_dispatch() with a cnt of 1) and returns a u_char pointer to the data in that packet. (The pcap_pkthdr struct for that packet is not supplied.) NULL is returned if an error occured, or if no packets were read from a live capture (if, for example, they were discarded because they didnt pass the packet filter, or if, on platforms that support a read timeout that starts before any packets arrive, the timeout expires before any packets arrive, or if the file descriptor for the capture device is in non-blocking mode and no packets were available to be read), or if no more packets are available in a savefile. Unfortunately, there is no way to determine whether an error occured or not. See also: pcap_dispatch(), pcap_loop() int pcap_next_ex (pcap_t *p, struct pcap_pkthdr *pkt_header, const u_char *pkt_data)Read a packet from an interface or from an offline capture. This function is used to retrieve the next available packet, bypassing the callback method traditionally provided by libpcap. pcap_next_ex fills the pkt_header and pkt_data parameters (see pcap_handler() with the pointers to the header and to the data of the next captured packet. The return value can be: 1 if the packet has been read without problems 0 if the timeout set with pcap_open_live() has elapsed. In this case pkt_header and pkt_data dont point to a valid packet -1 if an error occurred -2 if EOF was reached reading from an offline captureSee also: pcap_open_live(), pcap_loop(), pcap_dispatch(), pcap_handler() bool pcap_offline_filter (struct bpf_program *prog, const struct pcap_pkthdr *header, const u_char *pkt_data)Returns if a given filter applies to an offline packet. This function is used to apply a filter to a packet that is currently in memory. This process does not need to open an adapter; we need just to create the proper filter (by settings parameters like the snapshot length, or the link-layer type) by means of the pcap_compile_nopcap(). The current API of libpcap does not allow to receive a packet and to filter the packet after it has been received. However, this can be useful in case you want to filter packets in the application, instead of into the receiving process. This function allows you to do the job. Parameters: prog,:bpf program (created with the pcap_compile_nopcap() ) header,:header of the packet that has to be filtered pkt_data,:buffer containing the packet, in network-byte order.Returns: the length of the bytes that are currently available into the packet if the packet satisfies the filter, 0 otherwise. pcap_t* pcap_open (const char *source, intsnaplen, intflags, intread_timeout, struct pcap_rmtauth *auth, char *errbuf)Open a generic source in order to capture / send (WinPcap only) traffic. The pcap_open() replaces all the pcap_open_xxx() functions with a single call. This function hides the differences between the different pcap_open_xxx() functions so that the programmer does not have to manage different opening function. In this way, the true open function is decided according to the source type, which is included into the source string (in the form of source prefix). This function can rely on the pcap_createsrcstr() to create the string that keeps the capture device according to the new syntax, and the pcap_parsesrcstr() for the other way round. Parameters: source,:zero-terminated string containing the source name to open. The source name has to include the format prefix according to the new Source Specification Syntax and it cannot be NULL.On on Linux systems with 2.2 or later kernels, a device argument of any (i.e. rpcap:/any) can be used to capture packets from all interfaces. In order to makes the source syntax easier, please remember that: the adapters returned by the pcap_findalldevs_ex() can be used immediately by the pcap_open() in case the user wants to pass its own source string to the pcap_open(), the pcap_createsrcstr() helps in creating the correct source identifier.snaplen,:length of the packet that has to be retained. For each packet received by the filter, only the first snaplen bytes are stored in the buffer and passed to the user application. For instance, snaplen equal to 100 means that only the first 100 bytes of each packet are stored.flags,:keeps several flags that can be needed for capturing packets. The allowed flags are defined in the pcap_open() flags .read_timeout,:read timeout in milliseconds. The read timeout is used to arrange that the read not necessarily return immediately when a packet is seen, but that it waits for some amount of time to allow more packets to arrive and to read multiple packets from the OS kernel in one operation. Not all platforms support a read timeout; on platforms that dont, the read timeout is ignored.auth,:a pointer to a struct pcap_rmtauth that keeps the information required to authenticate the user on a remote machine. In case this is not a remote capture, this pointer can be set to NULL.errbuf,:a pointer to a user-allocated buffer which will contain the error in case this function fails. The pcap_open() and findalldevs() are the only two functions which have this parameter, since they do not have (yet) a pointer to a pcap_t structure, which reserves space for the error string. Since these functions do not have (yet) a pcap_t pointer (the pcap_t pointer is NULL in case of errors), they need an explicit errbuf variable. errbuf may also be set to warning text when pcap_open_live() succeds; to detect this case the caller should store a zero-length string in errbuf before calling pcap_open_live() and display the warning to the user if errbuf is no longer a zero-length string.Returns: A pointer to a pcap_t which can be used as a parameter to the following calls (pcap_compile() and so on) and that specifies an opened WinPcap session. In case of problems, it returns NULL and the errbuf variable keeps the error message.Warning: The source cannot be larger than PCAP_BUF_SIZE. The following formats are not allowed as source strings: rpcap:/ to open the first local adapter rpcap:/hostname/ to open the first remote adapter pcap_t* pcap_open_dead (intlinktype, intsnaplen)Create a pcap_t structure without starting a capture. pcap_open_dead() is used for creating a pcap_t structure to use when calling the other functions in libpcap. It is typically used when just using libpcap for compiling BPF code. See also: pcap_open_offline(), pcap_open_live(), pcap_findalldevs(), pcap_compile(), pcap_setfilter(), pcap_close() pcap_t* pcap_open_live (const char *device, intsnaplen, intpromisc, intto_ms, char *ebuf)Open a live capture from the network. pcap_open_live() is used to obtain a packet capture descriptor to look at packets on the network. device is a string that specifies the network device to open; on Linux systems with 2.2 or later kernels, a device argument of any or NULL can be used to capture packets from all interfaces. snaplen specifies the maximum number of bytes to capture. If this value is less than the size of a packet that is captured, only the first snaplen bytes of that packet will be captured and provided as packet data. A value of 65535 should be sufficient, on most if not all networks, to capture all the data available from the packet. promisc specifies if the interface is to be put into promiscuous mode. (Note that even if this parameter is false, the interface could well be in promiscuous mode for some other reason.) For now, this doesnt work on the any device; if an argument of any or NULL is supplied, the promisc flag is ignored. to_ms specifies the read timeout in milliseconds. The read timeout is used to arrange that the read not necessarily return immediately when a packet is seen, but that it wait for some amount of time to allow more packets to arrive and to read multiple packets from the OS kernel in one operation. Not all platforms support a read timeout; on platforms that dont, the read timeout is ignored. A zero value for to_ms, on platforms that support a read timeout, will cause a read to wait forever to allow enough packets to arrive, with no timeout. errbuf is used to return error or warning text. It will be set to error text when pcap_open_live() fails and returns NULL. errbuf may also be set to warning text when pcap_open_live() succeds; to detect this case the caller should store a zero-length string in errbuf before calling pcap_open_live() and display the warning to the user if errbuf is no longer a zero-length string. See also: pcap_open_offline(), pcap_open_dead(), pcap_findalldevs(), pcap_close() pcap_t* pcap_open_offline (const char *fname, char *errbuf)Open a savefile in the tcpdump/libpcap format to read packets. pcap_open_offline() is called to open a savefile for reading. fname specifies the name of the file to open. The file has the same format as those used by tcpdump(1) and tcpslice(1). The name - in a synonym for stdin. Alternatively, you may call pcap_fopen_offline() to read dumped data from an existing open stream fp. Note that on Windows, that stream should be opened in binary mode. errbuf is used to return error text and is only set when pcap_open_offline() or pcap_fopen_offline() fails and returns NULL. See also: pcap_open_live(), pcap_dump_open(), pcap_findalldevs(), pcap_close() int pcap_parsesrcstr (const char *source, int *type, char *host, char *port, char *name, char *errbuf)Parse the source string and returns the pieces in which the source can be split. This call is the other way round of pcap_createsrcstr(). It accepts a null-terminated string and it returns the parameters related to the source. This includes: the type of the source (file, winpcap on a remote adapter, winpcap on local adapter), which is determined by the source prefix (PCAP_SRC_IF_STRING and so on) the host on which the capture has to be started (only for remote captures) the raw name of the source (file name, name of the remote adapter, name of the local adapter), without the source prefix. The string returned does not include the type of the source itself (i.e. the string returned does not include file:/ or rpcap:/ or such).The user can omit some parameters in case it is not interested in them. Parameters: source,:a null-terminated string containing the WinPcap source. This source starts with an identifier according to the new Source Specification Syntax .type,:pointer to an integer, which is used to return the code corrisponding to the selected source. The code will be one defined in the Source identification Codes .In case the source string does not exists (i.e. source = NULL) or it is empty (*source = NULL), it returns PCAP_SRC_IF_LOCAL (i.e. you are ready to call pcap_open_live() ). This behavior is kept only for compatibility with older applications (e.g. tcpdump); therefore we suggest to move to the new syntax for sources.This parameter can be NULL in case the user is not interested in that.host,:user-allocated buffer (of size PCAP_BUF_SIZE) that is used to return the host name on which the capture has to be started. This value is meaningful only in case of remote capture; otherwise, the returned string will be empty (). This parameter can be NULL in case the user is not interested in that.port,:user-allocated buffer (of size PCAP_BUF_SIZE) that is used to return the port that has to be used by the RPCAP protocol to contact the other host. This value is meaningful only in case of remote capture and if the user wants to use a non-standard port; otherwise, the returned string will be empty (). In case of remote capture, an emply string means use the standard RPCAP port. This parameter can be NULL in case the user is not interested in that.name,:user-allocated buffer (of size PCAP_BUF_SIZE) that is used to return the source name, without the source prefix. If the name does not exist (for example because source contains rpcap:/ that means default local adapter), it returns NULL. This parameter can be NULL in case the user is not interested in that.errbuf,:pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) that will contain the error message (in case there is one). This parameter can be NULL in case the user is not interested in that.Returns: 0 if everything is fine, -1 if some errors occurred. The requested values (host name, network port, type of the source) are returned into the proper variables passed by reference. void pcap_perror (pcap_t *p, char *prefix)print the text of the last pcap library error on stderr, prefixed by prefix. See also: pcap_geterr() SOCKET pcap_remoteact_accept (const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf)Block until a network connection is accepted (active mode only). This function has been defined to allow the client dealing with the active mode. In other words, in the active mode the server opens the connection toward the client, so that the client has to open a socket in order to wait for connections. When a new connection is accepted, the RPCAP protocol starts as usual; the only difference is that the connection is initiated by the server. This function accepts only ONE connection, then it closes the waiting socket. This means that if some error occurs, the application has to call it again in order to accept another connection. This function returns when a new connection (coming from a valid host connectinghost) is accepted; it returns error otherwise. Parameters: address,:a string that keeps the network address we have to bind to; usually it is NULL (it means bind on all local addresses).port,:a string that keeps the network port on which we have to bind to; usually it is NULL (it means bind on the predefined port, i.e. RPCAP_DEFAULT_NETPORT_ACTIVE).hostlist,:a string that keeps the host name of the host from whom we are expecting a connection; it can be NULL (it means accept connection from everyone). Host names are separated by a whatever character in the RPCAP_HOSTLIST_SEP list.connectinghost,:a user-allocated buffer that will contain the name of the host is trying to connect to us. This variable must be at least RPCAP_HOSTLIST_SIZE bytes.auth,:a pointer to a pcap_rmtauth structure. This pointer keeps the information required to authenticate the RPCAP connection to the remote host.errbuf,:a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) that will contain the error message (in case there is one).Returns: The SOCKET identifier of the new control connection if everything is fine, a negative number if some errors occurred. The error message is returned into the errbuf variable. In case it returns -1, this means everything is fine, but the host cannot be admitted. In case it returns -2, in means unrecoverable error (for example it is not able to bind the socket, or something like that). In case it returns -3, it means authentication failed. The authentication check is performed only if the connecting host is among the ones that are allowed to connect to this host.The host that is connecting to us is returned into the hostlist variable, which ust be allocated by the user. This variable contains the host name both in case the host is allowed, and in case the connection is refused. Warning: Although this function returns the socket established by the new control connection, this value should not be used. This value will be stored into some libpcap internal variables and it will be managed automatically by the library. In other words, all the following calls to findalldevs() and pcap_open() will check if the host is among one that already has a control connection in place; if so, that one will be used. This function has several problems if used inside a thread, which is stopped when this call is blocked into the accept(). In this case, the socket on which we accept connections is not freed (thread termination is a very dirty job), so that we are no longer able to accept other connections until the program (i.e. the process) stops. In order to solve the problem, call the pcap_remoteact_cleanup(). void pcap_remoteact_cleanup ()Clean the socket that is currently used in waiting active connections. This function does a very dirty job. The fact is that is the waiting socket is not freed if the pcap_remoteaccept() is killed inside a new thread. This function is able to clean the socket in order to allow the next calls to pcap_remoteact_accept() to work. This function is useful *only* if you launch pcap_remoteact_accept() inside a new thread, and you stops (not very gracefully) the thread (for example because the user changed idea, and it does no longer want to wait for an active connection). So, basically, the flow should be the following: launch a new thread call the pcap_remoteact_accept if this new thread is killed, call pcap_remoteact_cleanup().This function has no effects in other cases. Returns: None. int pcap_remoteact_close (const char *host, char *errbuf)Drop an active connection (active mode only). This function has been defined to allow the client dealing with the active mode. This function closes an active connection that is still in place and it purges the host name from the activeHost list. From this point on, the client will not have any connection with that host in place. Parameters: host,:a string that keeps the host name of the host for which we want to close the active connection.errbuf,:a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) that will contain the error message (in case there is one).Returns: 0 if everything is fine, -1 if some errors occurred. The error message is returned into the errbuf variable. int pcap_remoteact_list (char *hostlist, charsep, intsize, char *errbuf)Return the hostname of the host that have an active connection with us (active mode only). This function has been defined to allow the client dealing with the active mode. This function returns the list of hosts that are currently having an active connection with us. This function is useful in order to delete an active connection that is still in place. Parameters: hostlist,:a user-allocated string that will keep the list of host that are currently connected with us.sep,:the character that has to be sued as a separator between the hosts (, for example).size,:size of the hostlist buffer.errbuf,:a pointer to a user-allocated buffer (of size PCAP_ERRBUF_SIZE) that will contain the error message (in case there is one).Returns: 0 if everything is fine, -1 if some errors occurred. The error message is returned into the errbuf variable. int pcap_sendpacket (pcap_t *p, u_char *buf, intsize)Send a raw packet. This function allows to send a raw packet to the network. p is the interface that will be used to send the packet, buf contains the data of the packet to send (including the various protocol headers), size is the dimension of the buffer pointed by buf, i.e. the size of the packet to send. The MAC CRC doesnt need to be included, because it is transparently calculated and added by the network interface driver. The return value is 0 if the packet is succesfully sent, -1 otherwise. See also: pcap_open_live() pcap_send_queue* pcap_sendqueue_alloc (u_intmemsize )Allocate a send queue. This function allocates a send queue, i.e. a buffer containing a set of raw packets that will be transimtted on the network with pcap_sendqueue_transmit(). memsize is the size, in bytes, of the queue, therefore it determines the maximum amount of data that the queue will contain. Use pcap_sendqueue_queue() to insert packets in the queue. See also: pcap_sendqueue_queue(), pcap_sendqueue_transmit(), pcap_sendqueue_destroy() void pcap_sendqueue_destroy (pcap_send_queue *queue )Destroy a send queue. Deletes a send queue and frees all the memory associated with it. See also: pcap_sendqueue_alloc(), pcap_sendqueue_queue(), pcap_sendqueue_transmit() int pcap_sendqueue_queue (pcap_send_queue *queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)Add a packet to a send queue. pcap_sendqueue_queue() adds a packet at the end of the send queue pointed by the queue parameter. pkt_header points to a pcap_pkthdr structure with the timestamp and the length of the packet, pkt_data points to a buffer with the data of the packet. The pcap_pkthdr structure is the same used by WinPcap and libpcap to store the packets in a file, therefore sending a capture file is straightforward. Raw packet means that the sending application will have to include the protocol headers, since every packet is sent to the network as is. The CRC of the packets needs not to be calculated, because it will be transparently added by the network interface. See also: pcap_sendqueue_alloc(), pcap_sendqueue_transmit(), pcap_sendqueue_destroy() u_int pcap_sendqueue_transmit (pcap_t *p, pcap_send_queue *queue, intsync)Send a queue of raw packets to the network. This function transmits the content of a queue to the wire. p is a pointer to the adapter on which the packets will be sent, queue points to a pcap_send_queue structure containing the packets to send (see pcap_sendqueue_alloc() and pcap_sendqueue_queue(), sync determines if the send operation must be synchronized: if it is non-zero, the packets are sent respecting the timestamps, otherwise they are sent as fast as possible. The return value is the amount of bytes actually sent. If it is smaller than the size parameter, an error occurred during the send. The error can be caused by a driver/adapter problem or by an inconsistent/bogus send queue. Note: Using this function is more efficient than issuing a series of pcap_sendpacket(), because the packets are buffered in the kernel driver, so the number of context switches is reduced. Therefore, expect a better throughput when using pcap_sendqueue_transmit. When Sync is set to TRUE, the packets are synchronized in the kernel with a high precision timestamp. This requires a non-negligible amount of CPU, but allows normally to send the packets with a precision of some microseconds (depending on the accuracy of the performance counter of the machine). Such a precision cannot be reached sending the packets with pcap_sendpacket().See also: pcap_sendqueue_alloc(), pcap_sendqueue_queue(), pcap_sendqueue_destroy() int pcap_set_datalink (pcap_t *p, intdlt)Set the current data link type of the pcap descriptor to the type specified by dlt. -1 is returned on failure. int pcap_setbuff (pcap_t *p, intdim)Set the size of the kernel buffer associated with an adapter. dim specifies the size of the buffer in bytes. The return value is 0 when the call succeeds, -1 otherwise. If an old buffer was already created with a previous call to pcap_setbuff(), it is deleted and its content is discarded. pcap_open_live() creates a 1 MByte buffer by default. See also: pcap_open_live(), pcap_loop(), pcap_dispatch() int pcap_setfilter (pcap_t *p, struct bpf_program *fp)Associate a filter to a capture. pcap_setfilter() is used to specify a filter program. fp is a pointer to a bpf_program struct, usually the result of a call to pcap_compile(). -1 is returned on failure, in which case pcap_geterr() may be used to display the error text; 0 is returned on success. See also: pcap_compile(), pcap_compile_nopcap() int pcap_setmintocopy (pcap_t *p, intsize)Set the minumum amount of data received by the kernel in a single call. pcap_setmintocopy() changes the minimum amount of data in the kernel buffer that causes a read from the application to return (unless the timeout expires). If the value of size is large, the kernel is forced to wait the arrival of several packets before copying the data to the user. This guarantees a low number of system calls, i.e. low processor usage, and is a good setting for applications like packet-sniffers and protocol analyzers. Vice versa, in presence of a small value for this variable, the kernel will copy the packets as soon as the application is ready to receive them. This is useful for real time applications that need the best responsiveness from the kernel. See also: pcap_open_live(), pcap_loop(), pcap_dispatch() int pcap_setmode (pcap_t *p, intmode)Set the working mode of the interface p to mode. Valid values for mode are MODE_CAPT (default capture mode) and MODE_STAT (statistical mode). See the tutorial ref wpcap_tut9 for details about statistical mode. int pcap_setnonblock (pcap_t *p, intnonblock, char *errbuf)Switch between blocking and nonblocking mode. pcap_setnonblock() puts a capture descriptor, opened with pcap_open_live(), into non-blocking mode, or takes it out of non-blocking mode, depending on whether the nonblock argument is non-zero or zero. It has no effect on savefiles. If there is an error, -1 is returned and errbuf is filled in with an appropriate error message; otherwise, 0 is returned. In non-blocking mode, an attempt to read from the capture descriptor with pcap_dispatch() will, if no packets are currently available to be read, return 0 immediately rather than blocking waiting for packets to arrive. pcap_loop() and pcap_next() will not work in non-blocking mode. See also: pcap_getnonblock(), pcap_dispatch() struct pcap_samp* pcap_setsampling (pcap_t *p )Define a sampling method for packet capture. This function allows applying a sampling method to the packet capture process. The currently sampling methods (and the way to set them) are described into the struct pcap_samp. In other words, the user must set the appropriate parameters into it; these will be applied as soon as the capture starts. Warning: Sampling parameters cannot be changed when a capture is active. These parameters must be applied before starting the capture. If they are applied when the capture is in progress, the new settings are ignored. Sampling works only when capturing data on Win32 or reading from a file. It has not been implemented on other platforms. Sampling works on remote machines provided that the probe (i.e. the capturing device) is a Win32 workstation. int pcap_snapshot (pcap_t *p )Return the dimension of the packet portion (in bytes) that is delivered to the application. pcap_snapshot() returns the snapshot length specified when pcap_open_live was called. See also: pcap_open_live(), pcap_compile(), pcap_compile_nopcap() int pcap_stats (pcap_t *p, struct pcap_stat *ps)Return statistics on current capture. pcap_stats() returns 0 and fills in a pcap_stat struct. The values represent packet statistics from the start of the run to the time of the call. If there is an error or the underlying packet capture doesnt support packet statistics, -1 is returned and the error text can be obtained with pcap_perror() or pcap_geterr(). pcap_stats() is supported only on live captures, not on savefiles; no statistics are stored in savefiles, so no statistics are available when reading from a savefile. See also: pcap_stats_ex(), pcap_open_live() struct pcap_stat* pcap_stats_ex (pcap_t *p, int *pcap_stat_size)Return statistics on current capture. pcap_stats_ex() extends the pcap_stats() allowing to return more statistical parameters than the old call. One of the advantages of this new call is that the pcap_stat structure is not allocated by the user; instead, it is returned back by the system. This allow to extend the pcap_stat structure without affecting backward compatibility on older applications. These will simply check at the values of the members at the beginning of the structure, while only newest applications are able to read new statistical values, which are appended in tail. To be sure not to read a piece of mamory which has not been allocated by the system, the variable pcap_stat_size will return back the size of the structure pcap_stat allocated by the system. Parameters: p,:pointer to the pcap_t currently in use. pcap_stat_size,:pointer to an integer that will contain (when the function returns back) the size of the structure pcap_stat as it has been allocated by the system.Returns: : a pointer to a pcap_stat structure, that will contain the statistics related to the current device. The return value is NULL in case of errors, and the error text can be obtained with pcap_perror() or pcap_geterr().Warning: pcap_stats_ex() is supported only on live captures, not on savefiles; no statistics are stored in savefiles, so no statistics are available when reading from a savefile.See also: pcap_stats() char* pcap_strerror (interror )Provided in case strerror() isnt available. See also: pcap_perror(), pcap_geterr() 过滤串表达式的语法WinPcap用户指南 注意:这篇文档取自tcpdump的指南。原始的版本 www.tcpdump.org 找到。 wpcap的过滤器是以已声明的谓词语法为基础的。过滤器是一个ASCII字符串,它包含了一个过滤表达式。pcap_compile()把这个表达式编译成内核级的包过滤器。这个表达式会选择那些数据包将会被堆存。如果表达式没有给出,那么,网络上所有的包都会被内核过滤引擎所认可。不然,只有那些表达式为true的包才会被认可。这个表达式包含了一个或多个原语。原语通常包含了id(名字或序列),这些id优先于限定词。以下是三种不同的限定词: 输入(type) 指明了哪些东西是id所代表的。可能的输入是host,net和port。比如:host foo,net 128.3,port 20。如果没有输入限定词,就假定是host 方向(dir) 由id指明了一个特定的传输方向。可能的方向是src,dst,src or dst。比如,src foo,dst net 128.3,src or dst port ftp-data。如果没有指定,就假定是src or dst。如果没有链路层(比如,像slip这样的点对点协议),那么限定词可以使用inbound和outbound,来指明一个方向。 协议(proto) 限定词限制了所匹配的协议。可能的协议有:ether,fddi,tr,ip,ip6,arp,rarp,decnet,tcp和udp。比如:ether src foo,arp net 128.3,tcp port 21。如果没有指定协议限定词,那么就假定所有的协议都会被允许。例如:src foo等价于(ip or arp or rarp)src foo(当然,不能有不符合语法的字母出现),net bar等价于(ip or arp or rarp) net bar,port53等价于(tcp or udp) port 53。 fddi通常是ether的别名;解析器会认为它们是在特定网络接口上的数据链路层。FDDI的首部包含了和以太网很相似的源地址和目的地址,并且通常也包含了和以太网很相似的数据包类型。所以,在FDDI网域上使用过滤器和在以太网上使用过滤器基本一致。FDDI的首部还包括了其他的数据,不过你不能在过滤器表达式内表示他们。 同样的,tr也是ether的一个别名,它是较早被应用于FDDI的首部,也应用在令牌环网络首部。 除了以上内容,还有一些特殊的限定词和上面的形式不太一样,它们是:gateway,broadcast,less,greater和一些算术表达式。这些内容会在下面和大家介绍。 我们可以使用and,or和not将原语连接起来,来构造一个更复杂的过滤表达式。例如:host foo and not port ftp and not port ftp-data。如果要简化输入,我们可以把已列出的id限定词省略。比如:tcp dst port ftp or ftp-data or domain 和 tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain是完全等价的。 可使用的原语有: dst host host 当IPv4/v6数据包的目标域(destination field)为host时为true,host既可以是地址,也可以是名字。 src host host 当IPv4/v6数据包的源域(source field)为host时为true。 host host 当IPv4/v6数据包的源域(source field)或目标域(destination field)为host时为true。以上任何一个host表达式可以是ip,arp,rarp或ip6开头,如下所示: ip host host等价于: ether proto ip and host host如果host是一个多IP地址,那么每一个地址都会被匹配。 ether dst ehost 当以太网的目的地址为ehost时为true。ehost可以是一个来自/etc/ether的名字,也可以是一个数字代号(参见 ethers(3N)for numeric format)。 ether src ehost 当以太网的源地址为ehost时为true。 ether host ehost 当以太网的目的地址,或源地址为ehost时为true。 gateway host 当host为网关时为true。即,以太网源地址或目的地址是host,但源地址和目的地址不同时为host。host必须能被机器的主机-IP地址(host-name-to-IP-address)机制找到(如主机名文件,DNS,NIS等),也能被主机-以太网地址(host-name-to-Ethernet-address)机制找到(如/etc/ethers等)。例如: ether host ehost and not host hosthost / ehost均可使用名字或数字。这个语法目前在IPv6下不能工作。 dst net net 当IPv4/v6数据包的目的地址的网络号包含了net时为true。net可以是一个来自/etc/networks的名字,也可以是一个网络号(更多内容请参见 networks(4)。 src net net 当IPv4/v6数据包的源地址的网络号包含了net时为true。 net net 当IPv4/v6数据包的目的地址,或源地址的网络号包含了net时为true net net mask netmask 当IP地址是 net ,子网掩码匹配 netmask 时为true。可能需要 src 或 dst加以限制。注意,这个语法不能应用于IPv6。 net net/len 当IP地址是 net ,子网掩码连续1的个数为 len 时为true。可能需要 src 或 dst加以限制。 dst port port 当数据包是ip/tcp, ip/udp, ip6/tcp 或 ip6/udp,并且目的端口号是port时为true。port可以是数字,或是在/etc/services中被使用的名字。(参见 tcp(4P) and udp(4P)。如果使用名字,那么端口号和协议都将被检测。如果使用数字,或者一个不明确的名字,那么只有端口号会被检测。(比如:dst port 513将打印tcp/login数据流和udp/who数据流。port domain将打印tcp/domain的数据流和udp/domain的数据流)。 src port port 当源端口号是 port时为true。 port port 当源端口号或目的端口号为 port 时为true。以上任何一个port表达式可以以关键字tcp或udp开头,如下所示: tcp src port port只匹配源端口是 port 的tcp数据包。 less length 当数据包的长度小于等于length时为true。即: len = length.ip proto protocol 当数据包是IP数据包,并且它的协议类型为protocol时为true。protocol可以是一个数字,也可以是icmp, icmp6,igmp,igrp,pim,ah,esp,vrrp,udp 或 tcp中的一个。注意,tcp,udp, icmp是关键字,所以,它们要使用反斜杠()来转义,就好比C-shell中的。注意,这个原语不会去追踪协议首部链。 ip6 proto protocol 当数据包是IPv6数据包,并且它的协议类型为protocol时为true。注意,这个原语不会去追踪协议首部链。 ip6 protochain protocol 当数据包是IPv6数据包,并且,在它的协议首部链中,包含了protocol类型的协议首部时,为true。例如: ip6 protochain 6能匹配所有的,拥有TCP协议首部的IPv6的数据包。在IPv6首部和TCP首部之间,可能包含认证首部,路由首部和跳数选项首部。由这个原语所生成的BPF(BSD Packet Filter,包过滤机制)码是复杂的,而且不能被BPF优化器优化,所以,在某些程度上,它的速度比较慢。 ip protochain protocol 功能和 ip6 protochain protocol相同,只是这个应用于 IPv4。 ether broadcast 当数据包是以太网广播数据包时为true。关键字ether是可选的。 ip broadcast 当数据包是IP广播数据包时为true。它会检查所有的广播,包括地址全是0的和地址全是1的,然后,检查子网掩码。 ether multicast 当数据包是以太网多播数据包时为true。关键字ether是可选的。 下面是一个常用短语ether0 & 1 != 0 ip multicast 当数据包是IP多播数据包时为true。 ip6 multicast 当数据包是IPv6多播数据包时为true。 ether proto protocol 当数据包是以太类型的protocol时为true。protocol可以是一个数字,也可以是ip, ip6, arp, rarp, atalk, aarp,decnet, sca, lat, mopdl, moprc,iso, stp, ipx, netbeui中的一个。注意,这些符号也都是关键字,所以,他们都需要用反斜杠()转义。 在使用FDDI(比如fddi protocol arp)和令牌环(比如tr protocol arp)和其他大多数这种协议时,协议根据802.2逻辑链路控制(LLC)来识别,这些信息通常在FDDI或令牌环首部的开始。 当需要识别大多数协议的标识,比如FDDI或令牌环时, Tcpdump只检查LLC报头的ID数据域,它们以SNAP格式存储,并且,组织单位识别码(Organizational Unit Identifier(OUI)为0x000000,以封装以太网。它不会检查这个包是不是SNAP格式的,并在0x000000单元有OUI。 然而,iso是个特例,它会检查LLC首部的目的服务存取点DSAP(Destination Service Access Point)和源服务存取点SSAP(Source Service Access Point),stp和netbeui会检查LLC首部的DSAP,atalk会检查数据包是不是SNAP格式的,并且OUI是不是0x080007。Appletalk 同样如此。 在以太网的例子中,tcpdump检查大部分协议的以太网类型字段,iso,sap 和 netbeui除外,因为它们会检查802.3帧,然后检查LLC首部,就像它对FDDI和令牌环那样。atalk,它检查以太网帧的Appletalk etype和SNAP格式的以太网帧,arrp,它在以太网帧中检查Appletalk ARP etype,或是在OUI为0x000000的802.2 SNAP帧中查找,还有ipx,他会在以太网帧中检查IPX etype,在LLC首部检查IPX DSAP,没有用802.3封装的LLC首部的IPX,和SNAP帧中的IPX etype。 decnet src host 当DECNET的源地址为host时为true,它可能是一个格式为10.123的地址,也可能是一个DECNET主机名。DECNET主机名称只有在配置成可运行DECNET的Ultrix系统中才得到支持。 decnet dst host 当DECNET的目的地址为host时为true。 decnet host host 当DECNET的源地址或目的地址为host时为true。 ip, ip6, arp, rarp, atalk, aarp, decnet, iso, stp, ipx, netbeui 缩写是: ether proto pp 是以上协议中的一个。 lat, moprc, mopdl 缩写是: ether proto pp 是以上协议中的一个。注意: tcpdump 目前并不知道,如何解析出这些协议。 vlan vlan_id 当数据包是IEEE 802.1Q VLAN数据包时为true。若vlan_id被指定,则仅当数据包为指定的vlan_id,值才为true。注意,在假设数据包为VLAN数据包的前提下,表达式中的第一个关键字vlan会改变剩余表达式的解码偏移量。 tcp, udp, icmp 缩写是: ip proto p or ip6 proto pp 是以上协议中的一个。 iso proto protocol 当数据包的协议类型为protocol的OSI数据包时值为true。Protocol可以是一个数字或以下名称中的一个:clnp,esis或isis。 clnp, esis, isis 缩写是: iso proto pp 是以上协议中的一个。注意,tcpdump并不能完成这些协议的全部解析工作。 expr relop expr 若关系式如下:relop是 , =, =, =, != 中的一个,并且expr是一个由正整常数(用标准C语言的语法表示),标准二进制运算符 +, -, *, /, &, | ,运算符的长度,和指定数据包存取,则值为true。要存取数据包内的数据,可以使用以下的语法: proto expr : size Proto 是 ether, fddi, tr, ip, arp, rarp, tcp, udp, icmp or ip6中的一个,它为索引操作指明了协议层。注意,tcp,udp和其他较高层的协议类型只能应用于IPv4,而不能用于IPv6(这个问题可能在将来能得到解决)。被指定的协议层的字节偏移量由expr给出。Size是可选的,它指明了数据域中,我们所感兴趣的字节数。它可以是1,2,或4,默认为1。运算符的长度,由关键字len给出,指明了数据包的长度。 例如,ether0 & 1 != 0会捕捉所有的多播数据流。表达式ip0 & 0xf != 5能捕捉所有带可选域的IP数据包。表达式ip6:2 & 0x1fff = 0仅捕捉未分段的数据报和段偏移量是0的数据报。这个检查隐含在tcp和udp的下标操作中。例如,tcp0通常指第一个字节的TCP首部,而不是指第一个字节的分段。 有些偏移量和域值可以以名字来表示,而不是数值。以下协议首部域的偏移量是正确的:icmptype (ICMP 类型域), icmpcode (ICMP 代码域), and tcpflags (TCP 标志域)。 ICMP 类型域有以下这些: icmp-echoreply, icmp-unreach, icmp-sourcequench, icmp-redirect, icmp-echo, icmp-routeradvert, icmp-routersolicit, icmp-timxceed, icmp-paramprob, icmp-tstamp, icmp-tstampreply, icmp-ireq, icmp-ireqreply, icmp-maskreq, icmp-maskreply. TCP 标志域有以下这些: tcp-fin, tcp-syn, tcp-rst, tcp-push, tcp-push, tcp-ack, tcp-urg. 原语可以用以下内容组合: 用圆括号括起来的原语和操作符 (圆括号在Shell中是特殊符号,所以必须要转义)。 取反操作 (! 或 not). 连接操作 (& 或 and). 选择操作 (| 或 or). 取反操作的优先级最高。连接操作和选择操作有相同的优先级,并且它们的结合方向为从左向右。注意:做连接的时候是需要显示的 and 操作符的,而不是把要连接的东西写在一起。 如果给出一个标识符,却没有关键字,那么就会假定用最近使用的关键字。例如: not host vs and ace等价于 not host vs and host ace不能和下面的混淆 not ( host vs or ace )表达式参数即可以作为单个参数,也可以作为多个参数传递给tcpdump,后者更加方便一些。一般的,如果表达式包含一个Shell的元字符,那么用一个参数传递比较容易,最好把它括起来,多个参数在传递前,用空格连接起来。使用WinPcap编程WinPcap用户指南 创建一个使用 wpcap.dll 的应用程序用 Microsoft Visual C+ 创建一个使用 wpcap.dll 的应用程序,需要按一下步骤: 在每一个使用了库的源程序中,将 pcap.h 头文件包含(include)进来。 如果你在程序中使用了WinPcap中提供给Win32平台的特有的函数, 记得在预处理中加入WPCAP 的定义。 如果你的程序使用了WinPcap的远程捕获功能,那么在预处理定义中加入HAVE_REMOTE。不要直接把remote-ext.h直接加入到你的源文件中去。 设置VC+的链接器(Linker),把wpcap.lib库文件包含进来。wpcap.lib可以在WinPcap中找到。 设置VC+的链接器(Linker),把ws2_32.lib库文件包含进来。这个文件分布于C的编译器,并且包含了Windows的一些socket函数。本教程中的一些范例程序,会需要它。 记住以下几点: 要添加一个预处理定义,你需要打开Project菜单,选择Settings,然后选择C/C+选项卡,在General类下,你必须在Preprocessor Definitions下的文本框中添加定义。 要在一个VC+6.0工程中,添加一,个新的库,你必须打开Project菜单,选择Settings,然后选择Link选项卡,然后把新库的名字添加到Object/Library modules下的文本框中 要向VC+6.0中添加一个新的库所在的路径,你必须打开Tool菜单,选择Options,然后选择Directories选项卡,在Show directories下拉框中选择Library files,并且将新的路径添加到Directories中去 要向VC+6.0中添加一个新的包含文件所在的路径,你必须打开Tool菜单,选择Options,然后选择Directories选项卡,在Show directories下拉框中选择Include files,并且将新的路径添加到Directories中去 范例程序我们一共了一些范例程序来显示WinPcap API的用法。这些程序的源代码,以及编译运行这些代码所需的所有文件,都可以在 Developers Pack找到。作为教程,在这里,我们提供了浏览器式的代码:这样,在每个函数和变量之间的跳转会比较方便。更多完整的范例程序,请参阅 WinPcap 教程.Packet Dump这个程序会依据命令行参数,从网络适配器,或是从文件来读取数据包。如果没有提供源,那么程序会显示出所有可用的适配器,你可以选其中一个。当捕获过程开始,程序会打印数据包的时间戳,长度,原始内容。一旦被编译了,那么它将能运行于所有的Win32平台,当然,它也可以被编译成Unix平台的程序。/* * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino, CACE Technologies * nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */#include #include / NOTE: remember to include WPCAP and HAVE_REMOTE among your/ preprocessor definitions./#include #define LINE_LEN 16main(int argc, char *argv) pcap_if_t *alldevs, *d;pcap_t *fp;u_int inum, i=0;char errbufPCAP_ERRBUF_SIZE;int res;struct pcap_pkthdr *header;const u_char *pkt_data; printf(pktdump_ex: prints the packets of the network using WinPcap.n); printf( Usage: pktdump_ex -s sourcenn Examples:n pktdump_ex -s file:/c:/temp/file.acpn pktdump_ex -s rpcap:/DeviceNPF_C8736017-F3C3-4373-94AC-9A34B7DAD998nn); if(argc next) printf(%d. %sn , +i, d-name); if (d-description) printf( (%s)n, d-description); else printf( (No description available)n); if (i=0) fprintf(stderr,No interfaces found! Exiting.n); return -1; printf(Enter the interface number (1-%d):,i); scanf(%d, &inum); if (inum i) printf(nInterface number out of range.n); /* Free the device list */ pcap_freealldevs(alldevs); return -1; /* Jump to the selected adapter */ for (d=alldevs, i=0; inext, i+); /* Open the device */ if ( (fp= pcap_open(d-name, 100 /*snaplen*/, PCAP_OPENFLAG_PROMISCUOUS /*flags*/, 20 /*read timeout*/, NULL /* remote authentication */, errbuf) ) = NULL) fprintf(stderr,nError opening adaptern); return -1; else / Do not check for the switch type (-s) if ( (fp= pcap_open(argv2, 100 /*snaplen*/, PCAP_OPENFLAG_PROMISCUOUS /*flags*/, 20 /*read timeout*/, NULL /* remote authentication */, errbuf) ) = NULL) fprintf(stderr,nError opening source: %sn, errbuf); return -1; /* Read the packets */ while(res = pcap_next_ex( fp, &header, &pkt_data) = 0) if(res = 0) /* Timeout elapsed */ continue; /* print pkt timestamp and pkt len */ printf(%ld:%ld (%ld)n, header-ts.tv_sec, header-ts.tv_usec, header-len); /* Print the packet */ for (i=1; (i caplen + 1 ) ; i+) printf(%.2x , pkt_datai-1); if ( (i % LINE_LEN) = 0) printf(n); printf(nn); if(res = -1) fprintf(stderr, Error reading the packets: %sn, pcap_geterr(fp); return -1; return 0;数据包过滤器这是一个更加完整的使用libpcap的范例程序,它显示了如何创建和设置过滤器,如何把捕获保存到磁盘。这个程序在Win32和Unix平台下都能编译。Pcap_filter(pf.exe)是一个通用的数据包过滤程序:它的输入参数有数据包的源(可以是物理接口,或是一个文件),过滤器和一个输出文件。它会从源获取数据包,并对它们进行过滤,如果它们符合过滤器的要求,就把它们保存到输出文件,直到按下Ctrl+C,或者整个文件处理完毕。Pcap_filter不但可以根据一个特定的过滤器,来堆处理网络中的数据,而且可以从已经保存过的文件中提取数据包。输入和输出文件的格式都是libpcap兼容的格式,比如,WinDump,tcpdump和其他许多网络工具。/* * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino, CACE Technologies * nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */#include #include #include #define MAX_PRINT 80#define MAX_LINE 16void usage();void main(int argc, char *argv)pcap_t *fp;char errbufPCAP_ERRBUF_SIZE;char *source=NULL;char *ofilename=NULL;char *filter=NULL;int i;pcap_dumper_t *dumpfile;struct bpf_program fcode;bpf_u_int32 NetMask;int res;struct pcap_pkthdr *header;const u_char *pkt_data; if (argc = 1) usage(); return; for(i=1;i argc; i+= 2) switch (argvi 1) case s: source=argvi+1; ; break; case o: ofilename=argvi+1; ; break; case f: filter=argvi+1; ; break; / open a capture from the network if (source != NULL) if ( (fp= pcap_open(source, 1514 /*snaplen*/, PCAP_OPENFLAG_PROMISCUOUS /*flags*/, 20 /*read timeout*/, NULL /* remote authentication */, errbuf) ) = NULL) fprintf(stderr,nUnable to open the adapter.n); return; else usage(); if (filter != NULL) / We should loop through the adapters returned by the pcap_findalldevs_ex() / in order to locate the correct one. / / Lets do things simpler: we suppose to be in a C class network ;-) NetMask=0xffffff; /compile the filter if(pcap_compile(fp, &fcode, filter, 1, NetMask) 0) fprintf(stderr,nError compiling filter: wrong syntax.n); return; /set the filter if(pcap_setfilter(fp, &fcode)= 0) if(res = 0) /* Timeout elapsed */ continue; /save the packet on the dump file pcap_dump(unsigned char *) dumpfile, header, pkt_data); void usage() printf(npf - Generic Packet Filter.n); printf(nUsage:npf -s source -o output_file_name -f filter_stringnn); exit(0);远程捕获模块输出结构与定义输出函数内部函数内部结构与定义详细描述 远程捕获运行模式 配置远程程序(rpcapd) 在远程机器上启动捕获 在Unix机器上安装远程捕获程序 WinPcap拥有远程捕获的能力。这个高级特性能够捕获在远程网络上传输的数据包。它需要一个 远程后台程序(remote daemon) (被称为rpcapd) ,它进行捕获,并把捕获到的数据发回。一个 本地客户端 会发送合适的命令并接收捕获到的数据。WinPcap扩展了标准的WinPcap代码,这样,基于WinPcap的工具可以拥有远程捕获的能力。例如:远程后台程序被加入到客户软件中,我们并不需要另外修改,就能使程序拥有远程捕捉的能力。反之亦然,远程后台程序必须被安装(和配置)在远程机器上。远程捕获运行模式远程捕获协议 (RPCAP) 可以在两种模式下工作: 被动模式(Passive Mode) (默认): 客户机 (比如 a network sniffer) 连接到远程后台程序, 它发送一些合适的命令,并开始捕获。 主动模式(Active Mode): 远程后台程序试图连接到客户机 (比如 the network sniffer); 然后,客户机发送一些合适的命令,并开始捕获。 主动这个词的来历是因为远程后台程序 主动建立连接,而不是 等待 新的连接。 主动模式是有用的,除了当远程后台程序遇到了防火墙的阻止而不能访问外部网络时。在这种情况下,远程后台程序可以被配置成允许与已知的主机建立连接,而那个主机,只需要配置成等待连接即可。在连接建立完成之后,协议会继续自己的工作,这些工作在主动模式和被动模式下几乎是一样的。Analyzer (http:/analyzer.polito.it/30alpha/) 有一系列的命令 (在 Capture 菜单中) 。这些命令允许你接收一个远程连接,然后再远程设备上启动捕获。由于Analyzer需要一些代码上的修正,所以目前,它仅能工作在主动模式下。配置远程后台程序 (rpcapd)远程后台程序是一个标准的Win32可执行进程,它可以运行于受控模式或作为一个服务器。可执行进程可以在进入WinPcap文件夹后,使用下列语法找到它: rpcapd -b -p -6 -l -a -n -v -d -s -f 后台进程也可以在Linux平台上编译并运行以下是可用命令的简要描述SwitchDescription-b 设置所绑定的程序的地址 (数字或文字的都行)。默认情况下,它将绑定所有的本地IPv4和IPv6地址。-p 设置所绑定的程序的端口,默认为2002-4只绑定IPv4地址。默认:IPv4和IPv6被用于等待的sockets-l 它指明了一个包含允许程序连接的主机列表的文件(如果有多个,那么每行表示1个)。我们建议使用文字(而不是用数字)来描述,因为这样可以避免与IPv4或IPv6的地址发生误会。-n它允许 NULL 的认证 (通常和 -l 一起使用, 这样能保证只有被允许的主机才能连接到程序)。 默认情况下,用于身份认证的用户名/密码是必须的。-a 它强制程序运行在主动模式下,并在port端口,与主机host建立连接。这个并不标明,后台程序就不能运行在被动模式下了。-v它强制程序只能运行于主动模式下。(默认情况:程序总是接受主动连接,即使指定了-a)-d强制程序在后台运行,例如,作为一个后台程序(仅Unix)或作为一个服务程序(仅Win32)。警告(Win32):当WinPcap将这个程序安装进了Win32的服务中时,这个交换是自动提供的。(控制面板-管理工具-服务)-s 把当前配置保存到文件-f 从文件中加在配置信息。所有由命令行参数指明的交换都将会被忽略,代替它的,是文件内的设置-h在屏幕上打印帮助信息安装远程后台程序在安装WinPcap时,远程后台程序被自动安装。这个安装过程将rpcapd文件放入WinPcap文件夹中。这个文件可以用命令行方式执行,也可以作为一个服务。例如,安装过程更新了可用服务的列表,并创建了一个新的项目(远程数据包捕获协议 v.0 (试验中)。为了避免安全问题,服务是不激活的,它需要手工启动它。(控制面板-管理工具-服务-启动)这个服务有一组 标准 的参数, 例如:使用-d标志和-f rpcapd.ini标志启动(为了让它作为一个服务运行)。用户可以在与可执行进程相同的目录下,创建一个名为rpcapd.ini的文件,然后把配置命令放在里面。为了让服务执行这些命令,你需要重启服务。(初始化文件只会在开始运行的时候被揭西)。反之亦然,Unix版本的rpcapd在发送kill -HUP标志时,读取配置文件。在这种情况下,所有的已存在的连接都会保留原有配置,而新的连接则会根据新的配置参数创建。万一用户不想手工创建配置文件,它可以使用加上了-s filename的请求参数来启动rpcapd。远程后台程序会解析所有的参数,并把它们保存到指定的配置文件中。启动远程后台程序,作为一个标准执行进程rpcapd可以直接启动,比如,它可以运行在前台(不作为后台程序或服务)。不走很简单,你需要从命令行启动程序,并输入所有必要的参数,除了-d标志。这样,捕获服务会在前台启动。在远程主机上启动捕获如果你使用的工具已经知道如何进行远程捕获(比如Analyzer),那么一切都是简单的。捕获向导会帮助你在远程机器上建立合适的接口。如果你喜欢那些还没有远程捕获功能的工具,你仍然可以进行远程捕获。在这里,你需要阅读下一节的内容。特别小心: 捕获服务 (rpcapd) 必须启动并在远程机器上运行。用于选择接口的新字符串标识如果你喜欢的工具还没有远程捕获功能,你必须做的唯一一件事,就是插入一个你想要连接的远程主机。可以使用以下形式:适配器字符串描述file:/filename打开一个本地文件rpcap:/host.foo.bar/adaptername打开一个远程适配器,host用文字来指明,没有端口号(即使用默认RPCAP端口)rpcap:/host.foo.bar:1234/adaptername作用和上面的一样,只是指定了端口号rpcap:/10.11.12.13/adaptername打开一个远程适配器,只是,主机由一个IPv4地址给出,没有端口号(使用RPCAP默认端口)rpcap:/10.11.12.13:1234/adaptername作用和上面的一样,只是指定了端口号rpcap:/10.11.12.13:1234/adaptername作用和上面的一样,只是将地址写入了方括号中,这样,更像是IPv6地址的表示方式rpcap:/1:2:3:4/adaptername打开一个远程适配器,只是,主机由一个IPv6地址给出,没有端口号(使用RPCAP默认端口)。你必须使用方括号来表示一个IPv6地址。rpcap:/1:2:3:4:1234/adaptername作用和上面的一样,只是指定了端口号rpcap:/adaptername打开一个本地适配器,不使用RPCAP协议adaptername打开一个本地适配器,尽管它可行,但我们强烈不鼓励使用。(NULL)它将打开第一个本地适配器。尽管它是可行的,但我们强烈不鼓励使用。以下形式是不对的适配器字符串描述rpcap:/它不能打开第一个本地适配器rpcap:/hostname/它不能打开第一个本地适配器在UNIX上安装远程后台捕获程序WinPcap程序同样可以在UNIX上进行编译。目前,远程捕获已经在Linux和BSD上经过了测试。你需要做的,有以下这些事情: 下载WinPcap源文件 解压缩源文件 o 我们建议使用 unzip -a 命令来将DOS文件转换成UNIX的 转到 libpcap 文件夹 输入命令: o ./configure o 警告: 万一上一个步骤出现了错误,请使用automake(需要2.50以上版本)命令重新生成配置文件 o make 转到 rpcapd 文件夹 输入 make 在默认情况下,远程捕获功能在Linux和FreeBSD上是打开的。万一你不想使用远程捕获功能,你可以在配置的时候,输入: ./configure -disable-remote当你输入 ./configure -help,所有的可以使用的参数将列出来。你刚刚已经得到了: 一个库文件 (libpcap.a), 它可以连接到其他应用程序 (比如 tcpdump) 以便为他开启远程捕获。 一个远程的可执行程序 (rpcapd) 警告: 为了运行远程捕获程序( rpcapd daemon), 程序必须符合下列中的一条: 以root权限运行 (或) 以user身份运行,但它必须属于root,并且必须有SUID root (chmod u+s rpcapd) 已知的BUGFreeBSD: 你第一次调用 pcap_stat()时,函数会过段时间才返回。因此,像Analyzer这样的程序,在开始捕捉的时候,会停滞20-30秒。 (if this is done with BSD as a remote probe). 我们正在调查并试图解决这个问题。如有任何问题,请访问 WinPcap 的帮助页面。输出结构与定义远程捕获 模块Strings related to the new source syntaxIdentifiers related to the new source syntaxFlags defined in the pcap_open() functionSampling methods defined in the pcap_setsampling() functionAuthentication methods supported by the RPCAP protocol数据结构struct pcap_rmtauthThis structure keeps the information needed to autheticate the user on a remote machine. More.struct pcap_sampThis structure defines the information related to sampling. More.定义#definePCAP_BUF_SIZE1024Defines the maximum buffer size in which address, port, interface names are kept. #defineRPCAP_HOSTLIST_SIZE1024Maximum lenght of an host name (needed for the RPCAP active mode). 预处理定义文档#define PCAP_BUF_SIZE1024 Defines the maximum buffer size in which address, port, interface names are kept. In case the adapter name or such is larger than this value, it is truncated. This is not used by the user; however it must be aware that an hostname / interface name longer than this value will be truncated. Definition at line 76 of file remote-ext.h. #define RPCAP_HOSTLIST_SIZE1024 Maximum lenght of an host name (needed for the RPCAP active mode). Definition at line 396 of file remote-ext.h. Strings related to the new source syntaxExported Structures and Definitions Defines#definePCAP_SRC_FILE_STRINGfile:/String that will be used to determine the type of source in use (file, remote/local interface). #definePCAP_SRC_IF_STRINGrpcap:/String that will be used to determine the type of source in use (file, remote/local interface). Detailed DescriptionThe formats allowed by the pcap_open() are the following: file:/path_and_filename opens a local file rpcap:/devicename opens the selected device devices available on the local host, without using the RPCAP protocol rpcap:/host/devicename opens the selected device available on a remote host rpcap:/host:port/devicename opens the selected device available on a remote host, using a non-standard port for RPCAP adaptername to open a local adapter; kept for compability, but it is strongly discouraged (NULL) to open the first local adapter; kept for compability, but it is strongly discouragedThe formats allowed by the pcap_findalldevs_ex() are the following: file:/folder/ lists all the files in the given folder rpcap:/ lists all local adapters rpcap:/host:port/ lists the devices available on a remote hostReferring to the host and port paramters, they can be either numeric or literal. Since IPv6 is fully supported, these are the allowed formats: host (literal): e.g. host.foo.bar host (numeric IPv4): e.g. 10.11.12.13 host (numeric IPv4, IPv6 style): e.g. 10.11.12.13 host (numeric IPv6): e.g. 1:2:3:4 port: can be either numeric (e.g. 80) or literal (e.g. http)Here you find some allowed examples: rpcap:/host.foo.bar/devicename everything literal, no port number rpcap:/host.foo.bar:1234/devicename everything literal, with port number rpcap:/10.11.12.13/devicename IPv4 numeric, no port number rpcap:/10.11.12.13:1234/devicename IPv4 numeric, with port number rpcap:/10.11.12.13:1234/devicename IPv4 numeric with IPv6 format, with port number rpcap:/1:2:3:4/devicename IPv6 numeric, no port number rpcap:/1:2:3:4:1234/devicename IPv6 numeric, with port number rpcap:/1:2:3:4:http/devicename IPv6 numeric, with literal port number Define Documentation#define PCAP_SRC_FILE_STRINGfile:/ String that will be used to determine the type of source in use (file, remote/local interface). This string will be prepended to the interface name in order to create a string that contains all the information required to open the source. This string indicates that the user wants to open a capture from a local file. Definition at line 161 of file remote-ext.h. #define PCAP_SRC_IF_STRINGrpcap:/ String that will be used to determine the type of source in use (file, remote/local interface). This string will be prepended to the interface name in order to create a string that contains all the information required to open the source. This string indicates that the user wants to open a capture from a network interface. This string does not necessarily involve the use of the RPCAP protocol. If the interface required resides on the local host, the RPCAP protocol is not involved and the local functions are used. Definition at line 174 of file remote-ext.h. Identifiers related to the new source syntaxExported Structures and Definitions Defines#definePCAP_SRC_FILE2Internal representation of the type of source in use (file, remote/local interface). #definePCAP_SRC_IFLOCAL3Internal representation of the type of source in use (file, remote/local interface). #definePCAP_SRC_IFREMOTE4Internal representation of the type of source in use (file, remote/local interface). Define Documentation#define PCAP_SRC_FILE2 Internal representation of the type of source in use (file, remote/local interface). This indicates a file, i.e. the user want to open a capture from a local file. Definition at line 90 of file remote-ext.h. #define PCAP_SRC_IFLOCAL3 Internal representation of the type of source in use (file, remote/local interface). This indicates a local interface, i.e. the user want to open a capture from a local interface. This does not involve the RPCAP protocol. Definition at line 98 of file remote-ext.h. #define PCAP_SRC_IFREMOTE4 Internal representation of the type of source in use (file, remote/local interface). This indicates a remote interface, i.e. the user want to open a capture from an interface on a remote host. This does involve the RPCAP protocol. Definition at line 106 of file remote-ext.h. Flags defined in the pcap_open() functionExported Structures and Definitions Defines#definePCAP_OPENFLAG_PROMISCUOUS1Defines if the adapter has to go in promiscuous mode. #definePCAP_OPENFLAG_DATATX_UDP2Defines if the data trasfer (in case of a remote capture) has to be done with UDP protocol. #definePCAP_OPENFLAG_NOCAPTURE_RPCAP4Defines if the remote probe will capture its own generated traffic. #definePCAP_OPENFLAG_NOCAPTURE_LOCAL8Defines if the local adapter will capture its own generated traffic. #definePCAP_OPENFLAG_MAX_RESPONSIVENESS16This flag configures the adapter for maximum responsiveness. Define Documentation#define PCAP_OPENFLAG_DATATX_UDP2 Defines if the data trasfer (in case of a remote capture) has to be done with UDP protocol. If it is 1 if you want a UDP data connection, 0 if you want a TCP data connection; control connection is always TCP-based. A UDP connection is much lighter, but it does not guarantee that all the captured packets arrive to the client workstation. Moreover, it could be harmful in case of network congestion. This flag is meaningless if the source is not a remote interface. In that case, it is simply ignored. Definition at line 214 of file remote-ext.h. #define PCAP_OPENFLAG_MAX_RESPONSIVENESS16 This flag configures the adapter for maximum responsiveness. In presence of a large value for nbytes, WinPcap waits for the arrival of several packets before copying the data to the user. This guarantees a low number of system calls, i.e. lower processor usage, i.e. better performance, which is good for applications like sniffers. If the user sets the PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will copy the packets as soon as the application is ready to receive them. This is suggested for real time applications (like, for example, a bridge) that need the best responsiveness. Definition at line 245 of file remote-ext.h. #define PCAP_OPENFLAG_NOCAPTURE_LOCAL8 Defines if the local adapter will capture its own generated traffic. This flag tells the underlying capture driver to drop the packets that were sent by itself. This is usefult when building applications like bridges, that should ignore the traffic they just sent. Definition at line 234 of file remote-ext.h. #define PCAP_OPENFLAG_NOCAPTURE_RPCAP4 Defines if the remote probe will capture its own generated traffic. In case the remote probe uses the same interface to capture traffic and to send data back to the caller, the captured traffic includes the RPCAP traffic as well. If this flag is turned on, the RPCAP traffic is excluded from the capture, so that the trace returned back to the collector is does not include this traffic. Definition at line 225 of file remote-ext.h. #define PCAP_OPENFLAG_PROMISCUOUS1 Defines if the adapter has to go in promiscuous mode. It is 1 if you have to open the adapter in promiscuous mode, 0 otherwise. Note that even if this parameter is false, the interface could well be in promiscuous mode for some other reason (for example because another capture process with promiscuous mode enabled is currently using that interface). On on Linux systems with 2.2 or later kernels (that have the any device), this flag does not work on the any device; if an argument of any is supplied, the promisc flag is ignored. Definition at line 200 of file remote-ext.h. Sampling methods defined in the pcap_setsampling() functionExported Structures and Definitions Defines#definePCAP_SAMP_NOSAMP0No sampling has to be done on the current capture. #definePCAP_SAMP_1_EVERY_N1It defines that only 1 out of N packets must be returned to the user. #definePCAP_SAMP_FIRST_AFTER_N_MS2It defines that we have to return 1 packet every N milliseconds. Define Documentation#define PCAP_SAMP_1_EVERY_N1 It defines that only 1 out of N packets must be returned to the user. In this case, the value field of the pcap_samp structure indicates the number of packets (minus 1) that must be discarded before one packet got accepted. In other words, if value = 10, the first packet is returned to the caller, while the following 9 are discarded. Definition at line 272 of file remote-ext.h. #define PCAP_SAMP_FIRST_AFTER_N_MS2 It defines that we have to return 1 packet every N milliseconds. In this case, the value field of the pcap_samp structure indicates the waiting time in milliseconds before one packet got accepted. In other words, if value = 10, the first packet is returned to the caller; the next returned one will be the first packet that arrives when 10ms have elapsed. Definition at line 282 of file remote-ext.h. #define PCAP_SAMP_NOSAMP0 No sampling has to be done on the current capture. In this case, no sampling algorithms are applied to the current capture. Definition at line 262 of file remote-ext.h. Authentication methods supported by the RPCAP protocolExported Structures and Definitions Defines#defineRPCAP_RMTAUTH_NULL0It defines the NULL authentication. #defineRPCAP_RMTAUTH_PWD1It defines the username/password authentication. Define Documentation#define RPCAP_RMTAUTH_NULL0 It defines the NULL authentication. This value has to be used within the type member of the pcap_rmtauth structure. The NULL authentication has to be equal to zero, so that old applications can just put every field of struct pcap_rmtauth to zero, and it does work. Definition at line 301 of file remote-ext.h. #define RPCAP_RMTAUTH_PWD1 It defines the username/password authentication. With this type of authentication, the RPCAP protocol will use the username/ password provided to authenticate the user on the remote machine. If the authentication is successful (and the user has the right to open network devices) the RPCAP connection will continue; otherwise it will be dropped. This value has to be used within the type member of the pcap_rmtauth structure. Definition at line 312 of file remote-ext.h. 内部结构与定义远程捕获 数据结构struct activehostsKeeps a list of all the opened connections in the active mode. More.struct rpcap_headerCommon header for all the RPCAP messages. More.struct rpcap_findalldevs_ifFormat of the message for the interface description (findalldevs command). More.struct rpcap_findalldevs_ifaddrFormat of the message for the address listing (findalldevs command). More.struct rpcap_openreplyFormat of the message of the connection opening reply (open command). More.struct rpcap_startcapreqFormat of the message that starts a remote capture (startcap command). More.struct rpcap_startcapreplyFormat of the reply message that devoted to start a remote capture (startcap reply command). More.struct rpcap_pkthdrFormat of the header which encapsulates captured packets when transmitted on the network. More.struct rpcap_filterGeneral header used for the pcap_setfilter() command; keeps just the number of BPF instructions. More.struct rpcap_filterbpf_insnStructure that keeps a single BPF instuction; it is repeated ninsn times according to the rpcap_filterbpf header. More.struct rpcap_authStructure that keeps the data required for the authentication on the remote host. More.struct rpcap_statsStructure that keeps the statistics about the number of packets captured, dropped, etc. More.struct rpcap_samplingStructure that is needed to set sampling parameters. More.定义#defineRPCAP_DEFAULT_NETPORT2002#defineRPCAP_DEFAULT_NETPORT_ACTIVE2003#defineRPCAP_DEFAULT_NETADDR#defineRPCAP_VERSION0#defineRPCAP_TIMEOUT_INIT90#defineRPCAP_TIMEOUT_RUNTIME180#defineRPCAP_ACTIVE_WAIT30#defineRPCAP_SUSPEND_WRONGAUTH1#defineRPCAP_NETBUF_SIZE64000Buffer used by socket functions to send-receive packets. In case you plan to have messages larger than this value, you have to increase it. #defineRPCAP_HOSTLIST_SEP ,;nrSeparators used for the host list. #defineRPCAP_MSG_ERROR1#defineRPCAP_MSG_FINDALLIF_REQ2#defineRPCAP_MSG_OPEN_REQ3#defineRPCAP_MSG_STARTCAP_REQ4#defineRPCAP_MSG_UPDATEFILTER_REQ5#defineRPCAP_MSG_CLOSE6#defineRPCAP_MSG_PACKET7#defineRPCAP_MSG_AUTH_REQ8#defineRPCAP_MSG_STATS_REQ9#defineRPCAP_MSG_ENDCAP_REQ10#defineRPCAP_MSG_SETSAMPLING_REQ11#defineRPCAP_MSG_FINDALLIF_REPLY(128+RPCAP_MSG_FINDALLIF_REQ)#defineRPCAP_MSG_OPEN_REPLY(128+RPCAP_MSG_OPEN_REQ)#defineRPCAP_MSG_STARTCAP_REPLY(128+RPCAP_MSG_STARTCAP_REQ)#defineRPCAP_MSG_UPDATEFILTER_REPLY(128+RPCAP_MSG_UPDATEFILTER_REQ)#defineRPCAP_MSG_AUTH_REPLY(128+RPCAP_MSG_AUTH_REQ)#defineRPCAP_MSG_STATS_REPLY(128+RPCAP_MSG_STATS_REQ)#defineRPCAP_MSG_ENDCAP_REPLY(128+RPCAP_MSG_ENDCAP_REQ)#defineRPCAP_MSG_SETSAMPLING_REPLY(128+RPCAP_MSG_SETSAMPLING_REQ)#defineRPCAP_STARTCAPREQ_FLAG_PROMISC1#defineRPCAP_STARTCAPREQ_FLAG_DGRAM2#defineRPCAP_STARTCAPREQ_FLAG_SERVEROPEN4#defineRPCAP_STARTCAPREQ_FLAG_INBOUND8#defineRPCAP_STARTCAPREQ_FLAG_OUTBOUND16#defineRPCAP_UPDATEFILTER_BPF1#definePCAP_ERR_NETW1#definePCAP_ERR_INITTIMEOUT2#definePCAP_ERR_AUTH3#definePCAP_ERR_FINDALLIF4#definePCAP_ERR_NOREMOTEIF5#definePCAP_ERR_OPEN6#definePCAP_ERR_UPDATEFILTER7#definePCAP_ERR_GETSTATS8#definePCAP_ERR_READEX9#definePCAP_ERR_HOSTNOAUTH10#definePCAP_ERR_REMOTEACCEPT11#definePCAP_ERR_STARTCAPTURE12#definePCAP_ERR_ENDCAPTURE13#definePCAP_ERR_RUNTIMETIMEOUT14#definePCAP_ERR_SETSAMPLING15#definePCAP_ERR_WRONGMSG16#definePCAP_ERR_WRONGVER17自定义类型typedef unsigned charuint8Provides an 8-bits unsigned integer. typedef unsigned shortuint16Provides a 16-bits unsigned integer. typedef unsigned intuint32Provides a 32-bits unsigned integer. typedef intint32Provides a 32-bits integer. 预处理定义文档#define PCAP_ERR_AUTH3 Generic authentication error Definition at line 312 of file pcap-remote.h. #define PCAP_ERR_ENDCAPTURE13 Generic pcap_endcapture error Definition at line 322 of file pcap-remote.h. #define PCAP_ERR_FINDALLIF4 Generic findalldevs error Definition at line 313 of file pcap-remote.h. #define PCAP_ERR_GETSTATS8 Generic pcap_stats error Definition at line 317 of file pcap-remote.h. #define PCAP_ERR_HOSTNOAUTH10 The host is not authorized to connect to this server Definition at line 319 of file pcap-remote.h. #define PCAP_ERR_INITTIMEOUT2 The RPCAP initial timeout has expired Definition at line 311 of file pcap-remote.h. #define PCAP_ERR_NETW1 Network error Definition at line 310 of file pcap-remote.h. #define PCAP_ERR_NOREMOTEIF5 The findalldevs was ok, but the remote end had no interfaces to list Definition at line 314 of file pcap-remote.h. #define PCAP_ERR_OPEN6 Generic pcap_open error Definition at line 315 of file pcap-remote.h. #define PCAP_ERR_READEX9 Generic pcap_next_ex error Definition at line 318 of file pcap-remote.h. #define PCAP_ERR_REMOTEACCEPT11 Generic pcap_remoteaccept error Definition at line 320 of file pcap-remote.h. #define PCAP_ERR_RUNTIMETIMEOUT14 The RPCAP run-time timeout has expired Definition at line 323 of file pcap-remote.h. #define PCAP_ERR_SETSAMPLING15 Error diring the settings of sampling parameters Definition at line 324 of file pcap-remote.h. #define PCAP_ERR_STARTCAPTURE12 Generic pcap_startcapture error Definition at line 321 of file pcap-remote.h. #define PCAP_ERR_UPDATEFILTER7 Generic updatefilter error Definition at line 316 of file pcap-remote.h. #define PCAP_ERR_WRONGMSG16 The other end endpoint sent a message which has not been recognized Definition at line 325 of file pcap-remote.h. #define PCAP_ERR_WRONGVER17 The other end endpoint ahs a version number that is not compatible with our Definition at line 326 of file pcap-remote.h. #define RPCAP_ACTIVE_WAIT30 Waiting time betweek two attempts to open a connection, in active mode (default: 30 sec) Definition at line 91 of file pcap-remote.h. #define RPCAP_DEFAULT_NETADDR Default network address on which the RPCAP daemon binds to. Definition at line 87 of file pcap-remote.h. #define RPCAP_DEFAULT_NETPORT2002 Default port on which the RPCAP daemon is waiting for connections. Definition at line 84 of file pcap-remote.h. #define RPCAP_DEFAULT_NETPORT_ACTIVE2003 Default port on which the client workstation is waiting for connections in case of active mode. Definition at line 86 of file pcap-remote.h. #define RPCAP_HOSTLIST_SEP ,;nr Separators used for the host list. It is used: by the rpcapd daemon, when you types a list of allowed connecting hosts by the rpcap in active mode, when the client waits for incoming connections from other hosts Definition at line 108 of file pcap-remote.h. #define RPCAP_MSG_AUTH_REPLY(128+RPCAP_MSG_AUTH_REQ) Sends a message that says ok, authorization successful Definition at line 295 of file pcap-remote.h. #define RPCAP_MSG_AUTH_REQ8 Message that keeps the authentication parameters Definition at line 286 of file pcap-remote.h. #define RPCAP_MSG_CLOSE6 Close the connection with the remote peer Definition at line 284 of file pcap-remote.h. #define RPCAP_MSG_ENDCAP_REPLY(128+RPCAP_MSG_ENDCAP_REQ) Confirms that the capture stopped succesfully Definition at line 297 of file pcap-remote.h. #define RPCAP_MSG_ENDCAP_REQ10 Stops the current capture, keeping the device open Definition at line 288 of file pcap-remote.h. #define RPCAP_MSG_ERROR1 Message that keeps an error notification Definition at line 279 of file pcap-remote.h. #define RPCAP_MSG_FINDALLIF_REPLY(128+RPCAP_MSG_FINDALLIF_REQ) Keeps the list of all the remote interfaces Definition at line 291 of file pcap-remote.h. #define RPCAP_MSG_FINDALLIF_REQ2 Request to list all the remote interfaces Definition at line 280 of file pcap-remote.h. #define RPCAP_MSG_OPEN_REPLY(128+RPCAP_MSG_OPEN_REQ) The remote device has been opened correctly Definition at line 292 of file pcap-remote.h. #define RPCAP_MSG_OPEN_REQ3 Request to open a remote device Definition at line 281 of file pcap-remote.h. #define RPCAP_MSG_PACKET7 This is a data message, which carries a network packet Definition at line 285 of file pcap-remote.h. #define RPCAP_MSG_SETSAMPLING_REPLY(128+RPCAP_MSG_SETSAMPLING_REQ) Confirms that the capture stopped succesfully Definition at line 298 of file pcap-remote.h. #define RPCAP_MSG_SETSAMPLING_REQ11 Sset sampling parameters Definition at line 289 of file pcap-remote.h. #define RPCAP_MSG_STARTCAP_REPLY(128+RPCAP_MSG_STARTCAP_REQ) The capture is staarting correctly Definition at line 293 of file pcap-remote.h. #define RPCAP_MSG_STARTCAP_REQ4 Request to start a capture on a remote device Definition at line 282 of file pcap-remote.h. #define RPCAP_MSG_STATS_REPLY(128+RPCAP_MSG_STATS_REQ) Message that keeps the network statistics Definition at line 296 of file pcap-remote.h. #define RPCAP_MSG_STATS_REQ9 It requires to have network statistics Definition at line 287 of file pcap-remote.h. #define RPCAP_MSG_UPDATEFILTER_REPLY(128+RPCAP_MSG_UPDATEFILTER_REQ) The filter has been applied correctly on the remote device Definition at line 294 of file pcap-remote.h. #define RPCAP_MSG_UPDATEFILTER_REQ5 Send a compiled filter into the remote device Definition at line 283 of file pcap-remote.h. #define RPCAP_NETBUF_SIZE64000 Buffer used by socket functions to send-receive packets. In case you plan to have messages larger than this value, you have to increase it. Definition at line 98 of file pcap-remote.h. #define RPCAP_STARTCAPREQ_FLAG_DGRAM2 Use a datagram (i.e. UDP) connection for the data stream (default: use TCP) Definition at line 301 of file pcap-remote.h. #define RPCAP_STARTCAPREQ_FLAG_INBOUND8 Capture only inbound packets (take care: the flag has no effects with promiscuous enabled) Definition at line 303 of file pcap-remote.h. #define RPCAP_STARTCAPREQ_FLAG_OUTBOUND16 Capture only outbound packets (take care: the flag has no effects with promiscuous enabled) Definition at line 304 of file pcap-remote.h. #define RPCAP_STARTCAPREQ_FLAG_PROMISC1 Enables promiscuous mode (default: disabled) Definition at line 300 of file pcap-remote.h. #define RPCAP_STARTCAPREQ_FLAG_SERVEROPEN4 The server has to open the data connection toward the client Definition at line 302 of file pcap-remote.h. #define RPCAP_SUSPEND_WRONGAUTH1 If the authentication is wrong, stops 1 sec before accepting a new auth message Definition at line 92 of file pcap-remote.h. #define RPCAP_TIMEOUT_INIT90 Initial timeout for RPCAP connections (default: 90 sec) Definition at line 89 of file pcap-remote.h. #define RPCAP_TIMEOUT_RUNTIME180 Run-time timeout for RPCAP connections (default: 3 min) Definition at line 90 of file pcap-remote.h. #define RPCAP_UPDATEFILTER_BPF1 This code tells us that the filter is encoded with the BPF/NPF syntax Definition at line 306 of file pcap-remote.h. #define RPCAP_VERSION0 Present version of the RPCAP protocol (0 = Experimental). Definition at line 88 of file pcap-remote.h. 自定义类型文档typedef int int32 Provides a 32-bits integer. Definition at line 117 of file pcap-remote.h. typedef unsigned short uint16 Provides a 16-bits unsigned integer. Definition at line 115 of file pcap-remote.h. typedef unsigned int uint32 Provides a 32-bits unsigned integer. Definition at line 116 of file pcap-remote.h. typedef unsigned char uint8 Provides an 8-bits unsigned integer. Definition at line 114 of file pcap-remote.h. WinPcap 数据结构以下是数据结构及其简要的说明: _CPU_Private_Data每个CPU的核心缓存 _DEVICE_EXTENSION端口设备扩展 _INTERNAL_REQUEST保存一个对象标识(OID)请求 _OPEN_INSTANCE包含一个运行着的NPF驱动实例的 _PACKET_RESERVED包含一个NDIS数据包 active_parsactivehosts在激活模式下打开的所有连接的列表 binary_streamX86体系的二进制代码流 daemon_slpars保存 daemon_serviceloop() 函数所需要的参数 JIT_BPF_Filter描述X86过滤程序的结构 编写: jitter packet_file_headerlibpcap的当机转储文件(dump file)的首部 PacketHeader内核缓冲池中每个数据包的预定结构 pcap_addr接口地址描述, 用于函数 pcap_findalldevs() pcap_file_headerlibpcap的当机转储文件(dump file)的首部 pcap_if接口表中的一项, 用于函数 pcap_findalldevs() pcap_pkthdr当机转储文件(dump file)中数据包的首部 pcap_rmtauth用于记录在远程机器上需要被验证的用户信息 pcap_samp这个结构定义了与标本(sampling)相关的信息 pcap_send_queue将要使用函数 pcap_sendqueue_transmit() 发送到网络上的原始数据包队列pcap_stat描述接口的静态信息 rpcap_auth描述被用于远程主机验证的所需的数据 rpcap_filter被 pcap_setfilter() 命令所使用的通用首部; 仅保存BPF指令的编号 rpcap_filterbpf_insn保存单条BPF指令; 根据rpcap_filterbpf的首部重复 ninsn 次rpcap_findalldevs_if接口描述的消息格式 (findalldevs 命令) rpcap_findalldevs_ifaddr地址列表的消息格式 (findalldevs 命令) rpcap_header所有RPCAP消息的通用首部 rpcap_openreply连接打开响应的消息格式 (open 命令) rpcap_pkthdr封装捕获到的数据包的首部格式 rpcap_sampling设置标本(sampling)时需要的参数 rpcap_startcapreply远程捕获的回复消息格式 (startcap reply 命令) rpcap_startcapreq远程捕获的消息格式 (startcap command) rpcap_stats保存已捕获数据包的数量,丢弃数据包的数量等统计信息 sf_pkthdr在驱动缓冲中的数据包的首部,该驱动在dump模式下,与 bpf_hdr structure相似,但更简单 以下列出了所有的结构和联合,并给出了它们原型的链接 - a - Accepted : _CPU_Private_Data activeclose : daemon_slpars AdapterBindingStatus : _OPEN_INSTANCE AdapterHandle : _OPEN_INSTANCE AdapterHandleLock : _OPEN_INSTANCE AdapterHandleUsageCounter : _OPEN_INSTANCE AdapterName : _DEVICE_EXTENSION addr : pcap_addr , rpcap_findalldevs_ifaddr address : active_pars addresses : pcap_if ai_family : active_pars - b - bpf_pc : binary_stream bpfprogram : _OPEN_INSTANCE broadaddr : rpcap_findalldevs_ifaddr , pcap_addr bs_capt : pcap_stat buffer : pcap_send_queue Buffer : _CPU_Private_Data BufferLock : _CPU_Private_Data BufferMdl : _OPEN_INSTANCE bufsize : rpcap_startcapreply - c - C : _CPU_Private_Data caplen : rpcap_pkthdr , sf_pkthdr , pcap_pkthdr code : rpcap_filterbpf_insn CountersLock : _OPEN_INSTANCE Cpu : _PACKET_RESERVED CpuData : _OPEN_INSTANCE cur_ip : binary_stream - d - desclen : rpcap_findalldevs_if description : pcap_if DeviceExtension : _OPEN_INSTANCE Dropped : _CPU_Private_Data dstaddr : pcap_addr , rpcap_findalldevs_ifaddr dummy : rpcap_startcapreply , rpcap_filter , rpcap_auth , rpcap_findalldevs_if dummy1 : rpcap_sampling dummy2 : rpcap_sampling DumpEvent : _OPEN_INSTANCE DumpFileHandle : _OPEN_INSTANCE DumpFileName : _OPEN_INSTANCE DumpFileObject : _OPEN_INSTANCE DumpLimitReached : _OPEN_INSTANCE DumpOffset : _OPEN_INSTANCE DumpThreadHandle : _OPEN_INSTANCE DumpThreadObject : _OPEN_INSTANCE - e - ExportString : _DEVICE_EXTENSION - f - filtertype : rpcap_filter flags : rpcap_startcapreq , rpcap_findalldevs_if , pcap_if Free : _CPU_Private_Data FreeBufAfterWrite : _PACKET_RESERVED Function : JIT_BPF_Filter - h - header : PacketHeader host : activehosts - i - ibuf : binary_stream ifdrop : rpcap_stats ifrecv : rpcap_stats InternalRequestCompletedEvent : _INTERNAL_REQUEST IOStatus : _OPEN_INSTANCE Irp : _PACKET_RESERVED isactive : daemon_slpars - j - jf : rpcap_filterbpf_insn jt : rpcap_filterbpf_insn - k - k : rpcap_filterbpf_insn krnldrop : rpcap_stats - l - len : sf_pkthdr , rpcap_pkthdr , pcap_pkthdr , pcap_send_queue linktype : rpcap_openreply , pcap_file_header , packet_file_header ListElement : _PACKET_RESERVED , _INTERNAL_REQUEST - m - MachineLock : _OPEN_INSTANCE magic : packet_file_header , pcap_file_header MaxDumpBytes : _OPEN_INSTANCE MaxDumpPacks : _OPEN_INSTANCE MaxFrameSize : _OPEN_INSTANCE maxlen : pcap_send_queue Medium : _OPEN_INSTANCE mem : JIT_BPF_Filter mem_ex : _OPEN_INSTANCE method : pcap_samp , rpcap_sampling MinToCopy : _OPEN_INSTANCE mode : _OPEN_INSTANCE Multiple_Write_Counter : _OPEN_INSTANCE - n - naddr : rpcap_findalldevs_if name : pcap_if namelen : rpcap_findalldevs_if Nbytes : _OPEN_INSTANCE NdisOpenCloseCompleteEvent : _OPEN_INSTANCE NdisProtocolHandle : _DEVICE_EXTENSION NdisRequestEvent : _OPEN_INSTANCE NdisWriteCompleteEvent : _OPEN_INSTANCE netmask : rpcap_findalldevs_ifaddr , pcap_addr NewP : _CPU_Private_Data next : pcap_if , pcap_addr , activehosts nitems : rpcap_filter Npackets : _OPEN_INSTANCE npkt : rpcap_pkthdr nullAuthAllowed : daemon_slpars Nwrites : _OPEN_INSTANCE - o - OpenCloseStatus : _OPEN_INSTANCE - p - P : _CPU_Private_Data PacketPool : _OPEN_INSTANCE password : pcap_rmtauth plen : rpcap_header pMdl : _PACKET_RESERVED port : active_pars portdata : rpcap_startcapreq , rpcap_startcapreply ps_drop : pcap_stat ps_ifdrop : pcap_stat ps_recv : pcap_stat - r - read_timeout : rpcap_startcapreq ReaderSN : _OPEN_INSTANCE ReadEvent : _OPEN_INSTANCE Received : _CPU_Private_Data refs : binary_stream Request : _INTERNAL_REQUEST RequestList : _OPEN_INSTANCE Requests : _OPEN_INSTANCE RequestSpinLock : _OPEN_INSTANCE RequestStatus : _INTERNAL_REQUEST ResetIrpList : _OPEN_INSTANCE - s - sigfigs : packet_file_header , pcap_file_header Size : _OPEN_INSTANCE SkipSentPackets : _OPEN_INSTANCE slen1 : rpcap_auth slen2 : rpcap_auth SN : PacketHeader snaplen : packet_file_header , rpcap_startcapreq , pcap_file_header sockctrl : activehosts , daemon_slpars svrcapt : rpcap_stats - t - thiszone : packet_file_header , pcap_file_header TimeOut : _OPEN_INSTANCE timestamp_sec : rpcap_pkthdr timestamp_usec : rpcap_pkthdr tme : _OPEN_INSTANCE TransferMdl1 : _CPU_Private_Data TransferMdl2 : _CPU_Private_Data TransmitPendingPackets : _OPEN_INSTANCE ts : pcap_pkthdr , sf_pkthdr type : rpcap_auth , rpcap_header , pcap_rmtauth tzoff : rpcap_openreply - u - username : pcap_rmtauth - v - value : rpcap_header , pcap_samp , rpcap_sampling ver : rpcap_header version_major : packet_file_header , pcap_file_header version_minor : pcap_file_header , packet_file_header - w - WriteEvent : _OPEN_INSTANCE WriteInProgress : _OPEN_INSTANCE WriteLock : _OPEN_INSTANCE WriterSN : _OPEN_INSTANCE 以下是所有函数、变量、定义、枚举和自定义类型,并给出了它们的原型链接 - a - ADAPTER_BINDING_STATUS : Packet.h ADAPTER_BOUND : Packet.h ADAPTER_UNBINDING : Packet.h ADAPTER_UNBOUND : Packet.h ADD_EAXi : jitter.h ADDib : jitter.h ADDid : jitter.h ADDrd : jitter.h AIRPCAP_HANDLE_EAE405F5_0171_9592_B3C2_C19EC426AD34_DEFINED_ : Win32-Extensions.h AL : jitter.h ANDib : jitter.h ANDid : jitter.h ANDrd : jitter.h AX : jitter.h 废弃内容列表Global pcap_lookupdev 用 pcap_findalldevs() 或 pcap_findalldevs_ex() 代替 Global pcap_lookupnet 用 pcap_findalldevs() 或 pcap_findalldevs_ex() 代替 Global pcap_file 由于用来编译WinPcap的C运行环境(C Runtime,CRT)和被WinPcap应用程序所使用的那个环境是不相容的,这个函数可能会返回一个非法的FILE指针,也就是一个描述符导致了所有的标准输入输出流的函数的错误。这个函数仅在考虑后台二进制的兼容性时被使用。郑重声明,以上内容来源于以下网站,所有版权归原作者所有,仅供个人学习交流,请勿用于商业用途:http:/www.coffeecat.net.cn/winpcap/html/index.html
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号