Winpcap使用介绍
Winpcap简介
Winpcap(windowspacketcapture)是在Win32平台上的强大的、有较好扩展性的底层网络分析体系结构,是Unix下的lipbcap移植到windows下的产物,是Win32环境下数据包捕获的开放代码函数库。Winpcap是第一个Win32开放式的捕获包的体系结构,能够支持大多数应用程序的需要。
如图A-1所示,Winpcap包含了一个内核级的数据包过滤器——NPF(NetgroupPacketFilter)、一个底层动态链接库(Packet.dll)和一个高层的独立于系统的库(Wpcap.dll)。这三个模块中,NPF属于内核级,其他两模块属于用户级。
图A-1Winpcap的结构图
NPF模块过滤数据包,将数据包不做任何改动的传递给用户,它还包含了一些操作系统专用代码(如:时间戳管理)。
Packet.dll模块提供了Win32平台下的捕获包的驱动接口。实际上,不同版本的Windows都提供了不同的内核模块和应用程序之间的接口函数,Packet.dll有一套独立于系统的API来处理这些差异。基于Packet.dll编写的程序可以不经过重新编译就在各种Win32平台下实现捕获数据包。Packet.dll还包含了其他一些函数。它可以进行一些底层的操作,Packet.dll和NPF都依赖于操作系统,并且由于Windows95/98和WindowsNT/2000之间操作系统结构的不同而在不同版本的操作系统上有所不同。
Wpcap.dll库不依赖于操作系统,并且它包含了一些其它高层的函数,比如:过滤器生成器、用户定义的缓冲区和高层特性(数据统计和构造数据包)。
Winpcap提供的功能包括四个方面:
捕获原始数据包,包括在共享网络上各主机发送/接收的以及相互之间交换的数据包;
在数据包发往应用程序之前,按照自定义的规则将某些特殊的数据包过滤掉;
在网络上发送原始的数据包;
收集网络通信过程中的流量信息。
Winpcap的主要功能在于独立于主机协议(如TCP-IP而发送和接收原始数据。也就是说,Winpcap不能阻塞过滤或控制其他应用程序数据的收发,它只是监听共享网络上传送的数据。因此,它不能用于QoS调度程序或个人防火墙。
下载Winpcap驱动程序和相应版本的WpdPack包(Developer''sPack)。WpdPack包中含有Winpcap编程所需的头文件和lib库文件以及一些示例程序和帮助文档。下载地址:http://www.winpcap.org/install/default.htm。当前Winpcap的最新版本是WinPcap4.0。
根据屏幕提示安装Winpcap驱动程序,安装后重启机器。
将WpdPack包解压到某个自定义的目录,在该目录中会看到docs、Include、lib、Examples等文件夹。
在VC中设定Include目录及Library目录。具体做法是:打开VC后,点击“Tools->Option->Directories”,在includefiles中添加……\wpdpack\Include目录(“……”为步骤3中自定义的目录);在Libraryfiles中添加……\wpdpack\Lib目录。
点击“Project->settings->Link”,在Object/librarymodules中添加wpcap.lib。
基于Winpcap的应用程序一般按照下面几个步骤:
获取网络设备列表;
选择网卡并打开;
当捕获数据包时,可能需要设置过滤器;
捕获数据包或者发送数据包。
Winpcap动态库
前面已经介绍过,Winpcap提供了两个动态链接库:Packet.dll和Wpcap.dll。因此,程序员可以使用两类API:一套是直接映射到内核调用的原始函数,包含在Packet.dll中;另一套是Wpcap.dll提供的高层函数,这些函数更强大,用户更容易掌握。
Packet.dll相关的主要数据结构及函数
Packet.dll提供了一些实现如下功能的底层函数:
安装、启动和停止NPF设备驱动
从NPF驱动模块接收数据包
向NPF驱动模块发送数据包
获取可用网络适配器列表
获得适配器各种各样信息,比如适配器描述、IP地址列表和子网掩码
查询和设置适配器的底层参数
主要数据结构
typedefstruct_ADAPTER??ADAPTER? //描述一个网络适配器typedefstruct_PACKETPACKET???? //描述一组网络数据的结构
structbpf_hdr??//数据头部
structbpf_stat??//当前捕获数据的统计信息typedefstructNetTypeNetType???? //描述网络类型的数据结构typedefstructnpf_if_addrnpf_if_addr?? //描述一个网络适配器的地址?PCHARPacketGetVersion()
返回关于dll的版本信息。BOOLEANPacketSetNumWrites(LPADAPTERAdapterObject,intnwrites)
设置调用PacketSendPacket()函数发送一个数据副本所重复的次数。
BOOLEANPacketSetReadTimeout(LPADAPTERAdapterObject,inttimeout)设置在接收到一个数据后休息的时间。
BOOLEANPacketSetBpf(LPADAPTERAdapterObject,structbpf_programfp)
?BOOLEANPacketGetStats(LPADAPTERAdapterObject,structbpf_stats)
返回关于当前捕获报告的统计信息。其中bpf_stat结构包含bs_recvbs_drop,ps_ifdrop和bs_capt4个参数。
bs_recv表示从网络适配器捕获数据包开始所接收到的所有数据包的数目,包括丢失的数据包;bs_drop丢失的数据包数目。在驱动缓冲区已经满时,就会发生数据包丢失的情况。BOOLEANPacketSetBuff(LPADAPTERAdapterObject,intdim)
设置与数据包捕获相关的内核级缓冲区大小。
?BOOLEANPacketGetNetType(LPADAPTERAdapterObject,NetTypetype)
返回某个网络适配器的MAC类型。NetType结构里包含了LinkSpeed速度和LinkType类型。其中LinkType包含以下几种情况:NdisMedium802_3:Ethernet(802.3)
NdisMediumWan:WAN
NdisMedium802_5:TokenRing(802.5)
NdisMediumFddi:FDDI
NdisMediumAtm:ATM
NdisMediumArcnet878_2:ARCNET(878.2)
LPADAPTERPacketOpenAdapter(LPTSTRAdapterName)
打开一个网络适配器。
?BOOLEANPacketSendPacket(LPADAPTERAdapterObject,
LPPACKETlpPacket,BOOLEANSync)
发送一个或多个数据包的副本。INTPacketSendPackets(LPADAPTERAdapterObject,PVOIDPacketBuff,ULONGSize,BOOLEANSync)
发送PacketBuff所指缓冲区中的数据包。
LPPACKETPacketAllocatePacket(void)
如果运行成功,返回一个_PACKET结构的指针,否则返回NULL。成功返回的结果将会传送到PacketReceivePacket()函数,PacketReceivePacket()函数接收来自驱动的网络数据包。?VOIDPacketInitPacket(LPPACKETlpPacket,PVOIDBuffer,UINTLength)
初始化一个_PACKET结构。VOIDPacketFreePacket(LPPACKETlpPacket)
释放参数提供的_PACKET结构。?BOOLEANPacketReceivePacket(LPADAPTERAdapterObject,
LPPACKETlpPacket,BOOLEANSync)
从NPF驱动程序读取网络数据包及统计信息。数据包编码结构:|bpf_hdr|data|Padding|bpf_hdr|data|Padding|BOOLEANPacketSetHwFilter(LPADAPTERAdapterObject,ULONGFilter)
为接收到的数据包设置硬件过滤规则。?以下为一些典型的过滤规则:NDIS_PACKET_TYPE_PROMISCUOUS:设置为混杂模式,接收所有过的数据包NDIS_PACKET_TYPE_DIRECTED:只有目的地为本地主机网络适配器的数据包才会被接收NDIS_PACKET_TYPE_BROADCAST:只有广播数据包才会被接收NDIS_PACKET_TYPE_MULTICAST:只有与本地主机网络适配器相对应的多播数据包才会被接收NDIS_PACKET_TYPE_ALL_MULTICAST:所有多播数据包均被接收NDIS_PACKET_TYPE_ALL_LOCAL:所有本地数据包均被接收BOOLEANPacketGetAdapterNames(LPSTRpStr,PULONGBufferSize)
返回可以得到的网络适配器列表及描述。BOOLEANPacketGetNetInfo(LPTSTRAdapterName,PULONGnetp,PULONGmaskp)
返回某个网络适配器的BOOLEANPacketGetNetInfoEx(LPTSTRAdapterNames,npf_if_addrbuff,PLONGNEntries)
返回某个网络适配器的全面地址信息。其中npf_if_addr结构包含PAddressSubnetMask和Broadcast3个参数。IPAddress表示IP地址SubnetMask表示子网掩码Broadcast表示广播地址VOIDPacketCloseAdapter(LPADAPTERlpAdapter)
关闭参数中提供的网络适配器,释放相关的ADAPTER结构。BOOLEANPacketRequest(LPADAPTERAdapterObject,BOOLEANSet,PPACKET_OID_DATAOidData)
指定适配器上运行的询问/设置函数的类型BOOLEANPacketSetDumpName(LPADAPTERAdapterObject,voidname,intlen)
设置适配器dump模式时接收数据包的文件。
BOOLPacketStopDriver()
停止并卸载Winpcap设备驱动器。
Wpcap.dll相关的主要数据结构及函数
主要数据结构
typedefstructpcappcap_t //捕获数据包的网络接口的描述符
typedefstructpcap_dumperpcap_dumper_t //数据包存储文件的描述符
typedefstructpcap_ifpcap_if_t //接口链表中某个接口的信息
typedefstructpcap_addrpcap_addr_t //描述接口地址信息
structpcap_file_header //数据包存储文件的头部
structpcap_pkthdr //捕获数据包的头部结构
structpcap_stat //捕获数据包的统计信息
intpcap_findalldevs_ex(charhost,charport,SOCKETsockctrl,structpcap_rmtauthauth,pcap_if_talldevs,charerrbuf)
枚举系统所有网络设备的信息。取代旧的函数pcap_findalldevs()。
pcap_tpcap_open(constcharsource,intsnaplen,intflags,intread_timeout,structpcap_rmtauthauth,charerrbuf)
为捕获/发送数据包打开一个网络接口。pcap_open()能够替代所有的pcap_open_xxx()函数,它隐藏了不同pcap_open_xxx()之间的差异,所以程序员不必使用不同的open函数。
intpcap_compile(pcap_tp,structbpf_programfp,charstr,intoptimize,bpf_u_int32netmask)
编译数据包过滤器,把高层的过滤规则解释成能被过滤引擎集成到数据包驱动中的低级字节码。
intpcap_setfilter(pcap_tp,structbpf_programfp)
设置数据包过滤器,把一个过滤器与核心驱动的抓包会话关联起来。在编译了过滤器之后必须调用pcap_setfilter函数设置内核过滤器方能生效。
intpcap_next_ex(pcap_tp,structpcap_pkthdrpkt_header,u_charpkt_data)
从网卡或者数据包文件中读取一个数据包。
intpcap_sendpacket(pcap_tp,u_charbuf,intsize)
发送一个原始数据包。
voidpcap_close(pcap_tp)
关闭与网络接口p相关联的文件,并释放资源。
前面介绍了Winpcap编程所涉及的主要数据结构与函数,与之相关的更加详细的信息请参考http://www.winpcap.org/docs/docs_412/html/main.html。中文参考文档:http://www.ferrisxu.com/WinPcap/html/index.html
1
|
|