winpcap
-
2023年4月19日发(作者:sql数据库下载)Winpcap使用介绍 1. Winpcap简介 Winpcap(windows packet capture)是在Win32平台上的强大的、有较好扩展性的底层网络分析体系结构,是Unix下的lipbcap移植到windows下的产物,是Win32环境下数据包捕获的开放代码函数库。Winpcap是第一个Win32开放式的捕获包的体系结构,能够支持大多数应用程序的需要。 如图A-1所示,Winpcap包含了一个内核级的数据包过滤器——NPF (Netgroup Packet Filter)、一个底层动态链接库()和一个高层的独立于系统的库()。这三个模块中,NPF属于内核级,其他两模块属于用户级。 图A-1 Winpcap的结构图 NPF模块过滤数据包,将数据包不做任何改动的传递给用户,它还包含了一些操作系统专用代码(如:时间戳管理)。 模块提供了Win32平台下的捕获包的驱动接口。实际上,不同版本的Windows都提供了不同的内核模块和应用程序之间的接口函数,有一套独立于系统的API来处理这些差异。基于编写的程序可以不经过重新编译就在各种Win32平台下实现捕获数据包。还包含了其他一些函数。它可以进行一些底层的操作,和NPF都依赖于操作系统,并且由于Windows95/98和WindowsNT/2000之间操作系统结构的不同而在不同版本的操作系统上有所不同。 库不依赖于操作系统,并且它包含了一些其它高层的函数,比如:过滤器生成器、用户定义的缓冲区和高层特性(数据统计和构造数据包)。 Winpcap提供的功能包括四个方面: 1) 捕获原始数据包,包括在共享网络上各主机发送/接收的以及相互之间交换的数据包; 1 2) 在数据包发往应用程序之前,按照自定义的规则将某些特殊的数据包过滤掉; 3) 在网络上发送原始的数据包; 4) 收集网络通信过程中的流量信息。 Winpcap的主要功能在于独立于主机协议(如TCP-IP)而发送和接收原始数据包。也就是说,Winpcap不能阻塞、过滤或控制其他应用程序数据包的收发,它只是监听共享网络上传送的数据包。因此,它不能用于QoS调度程序或个人防火墙。 2. 使用Winpcap编程的一般步骤 使用Winpcap编程的准备工作如下: 1) 下载Winpcap驱动程序和相应版本的WpdPack包(Developer's Pack)。WpdPack包中含有Winpcap编程所需的头文件和lib库文件以及一些示例程序和帮助文档。下载地址:/install/。当前Winpcap的最新版本是WinPcap 4.0。 2) 根据屏幕提示安装Winpcap驱动程序,安装后重启机器。 3) 将WpdPack包解压到某个自定义的目录,在该目录中会看到docs、Include、lib、Examples等文件夹。 4) 在VC中设定Include目录及Library目录。具体做法是:打开VC后,点击“Tools->Option->Directories”,在include files中添加„„wpdpackInclude目录(“„„”为步骤3中自定义的目录);在Library files中添加„„wpdpackLib目录。 5) 点击“Project->settings->Link”,在Object/library modules中添加。 基于Winpcap的应用程序一般按照下面几个步骤: 1) 获取网络设备列表; 2) 选择网卡并打开; 3) 当捕获数据包时,可能需要设置过滤器; 4) 捕获数据包或者发送数据包。 3. Winpcap动态库 前面已经介绍过,Winpcap提供了两个动态链接库:和。因此,程序员可以使用两类API:一套是直接映射到内核调用的原始函数,包含在中;另一套是提供的高层函数,这些函数更强大,用户更容易掌握。 1) 相关的主要数据结构及函数 提供了一些实现如下功能的底层函数: 安装、启动和停止NPF设备驱动 从NPF驱动模块接收数据包 向NPF驱动模块发送数据包 获取可用网络适配器列表 获得适配器各种各样信息,比如适配器描述、IP地址列表和子网掩码 查询和设置适配器的底层参数 // 描述一个网络适配器 typedef struct _ADAPTER ADAPTER // 描述一组网络数据包的结构 typedef struct _PACKET PACKET // 数据包头部 struct bpf_hdr // 当前捕获数据包的统计信息struct bpf_stat // 描述网络类型的数据结构 typedef struct NetType NetType // 描述一个网络适配器的IP地址 typedef struct npf_if_addr npf_if_addr 2 主要数据结构 主要函数 PCHAR PacketGetVersion() BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites) BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout) BOOLEAN PacketSetBpf(LPADAPTER AdapterObject, struct bpf_program *fp) BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s) 返回关于dll的版本信息。 设置调用PacketSendPacket()函数发送一个数据包副本所重复的次数。 设置在接收到一个数据包后“休息”的时间。 设置内核级的数据包过滤器。 返回几个关于当前捕获报告的统计信息。 其中bpf_stat结构包含bs_recv,bs_drop,ps_ifdrop和bs_capt 4个参数。 bs_recv表示从网络适配器捕获数据包开始所接收到的所有数据包的数目,包括丢失的数据包;bs_drop表示丢失的数据包数目。在驱动缓冲区已经满时,就会发生数据包丢失的情况。 BOOLEAN PacketSetBuff(LPADAPTER AdapterObject, int dim) BOOLEAN PacketGetNetType(LPADAPTER AdapterObject, NetType *type) 设置与数据包捕获相关的内核级缓冲区大小。 返回某个网络适配器的MAC类型。 NetType结构里包含了LinkSpeed(速度)和LinkType(类型)。其中LinkType包含以下几种情况: NdisMedium802_3:Ethernet(802.3) NdisMediumWan:WAN NdisMedium802_5:Token Ring(802.5) NdisMediumFddi:FDDI NdisMediumAtm:ATM NdisMediumArcnet878_2:ARCNET(878.2) LPADAPTER PacketOpenAdapter(LPTSTR AdapterName) BOOLEAN PacketSendPacket(LPADAPTER AdapterObject, 打开一个网络适配器。 LPPACKET lpPacket, BOOLEAN Sync) 发送一个或多个数据包的副本。 INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync) 发送PacketBuff所指缓冲区中的数据包。 LPPACKET PacketAllocatePacket(void) 如果运行成功,返回一个_PACKET结构的指针,否则返回NULL。成功返回的结果将会传送到PacketReceivePacket()函数,PacketReceivePacket()函数将接收来自驱动的网络数据包。 VOID PacketInitPacket(LPPACKET lpPacket, PVOID Buffer, UINT Length) VOID PacketFreePacket(LPPACKET lpPacket) BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject, 3 初始化一个_PACKET结构。 释放参数提供的_PACKET结构。 LPPACKET lpPacket,BOOLEAN Sync) 从NPF驱动程序读取网络数据包及统计信息。 数据包编码结构: |bpf_hdr|data|Padding|bpf_hdr|data|Padding| BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter) 为接收到的数据包设置硬件过滤规则。 以下为一些典型的过滤规则: 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:所有本地数据包均被接收 BOOLEAN PacketGetAdapterNames(LPSTR pStr, PULONG BufferSize) 返回可以得到的网络适配器列表及描述。 BOOLEAN PacketGetNetInfo(LPTSTR AdapterName, PULONG netp, PULONG maskp) 返回某个网络适配器的IP地址和子网掩码。 BOOLEAN PacketGetNetInfoEx(LPTSTR AdapterNames, npf_if_addr *buff, PLONG NEntries) 返回某个网络适配器的全面地址信息。 其中npf_if_addr结构包含PAddress、SubnetMask和Broadcast 3个参数。IPAddress表示IP地址;SubnetMask表示子网掩码;Broadcast表示广播地址。 VOID PacketCloseAdapter(LPADAPTER lpAdapter) , , BOOLEAN PacketRequest( 关闭参数中提供的网络适配器,释放相关的ADAPTER结构。 AdapterObjectBOOLEANSetLPADAPTERPPACKET_OID_DATA OidData) 指定适配器上运行的询问/设置函数的类型。 BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len) BOOL PacketStopDriver () 设置适配器处于dump模式时接收数据包的文件。 停止并卸载Winpcap设备驱动器。 2) 相关的主要数据结构及函数 主要数据结构 typedef struct pcap pcap_t // 捕获数据包的网络接口的描述符 // 数据包存储文件的描述符 typedef struct pcap_dumper pcap_dumper_t // 接口链表中某个接口的信息 typedef struct pcap_if pcap_if_t // 描述接口地址信息 typedef struct pcap_addr pcap_addr_t // 数据包存储文件的头部 struct pcap_file_header // 捕获数据包的头部结构 struct pcap_pkthdr // 捕获数据包的统计信息 struct pcap_stat 主要函数 4 int pcap_findalldevs_ex(char *host, char *port, SOCKET sockctrl, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf) 枚举系统所有网络设备的信息。取代旧的函数pcap_findalldevs()。 pcap_t* pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf) 为捕获/发送数据包打开一个网络接口。pcap_open()能够替代所有的pcap_open_xxx()函数,它隐藏了不同pcap_open_xxx()之间的差异,所以程序员不必使用不同的open函数。 int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask) 编译数据包过滤器,把高层的过滤规则解释成能被过滤引擎集成到数据包驱动中的低级字节码。 int pcap_setfilter (pcap_t *p, struct bpf_program *fp) 设置数据包过滤器,把一个过滤器与核心驱动的抓包会话关联起来。在编译了过滤器之后必须调用pcap_setfilter 函数设置内核过滤器方能生效。 int pcap_next_ex (pcap_t *p, struct pcap_pkthdr **pkt_header, u_char **pkt_data) int pcap_sendpacket (pcap_t *p, u_char *buf, int size) void pcap_close (pcap_t *p) 从网卡或者数据包文件中读取一个数据包。 发送一个原始数据包。 关闭与网络接口p相关联的文件,并释放资源。 前面介绍了Winpcap编程所涉及的主要数据结构与函数,与之相关的更加详细的信息请参考/docs/docs_412/html/。中文参考文档:/WinPcap/html/ 5-
winpcap