wincap_stdio 2008
WinPcap学习笔记
2008年05月09日 星期五 下午 05:33
这是上学期上的《网络编程实践》课上,老师提供的学习文档。基本上算比较基础的内容了。第三部分有一些源代码,发过来的时候我删掉了,都是WinPcap官方提供的文档里面的例子,官方文档的内容其实已经非常完整了,如果英文看不懂的话,网上搜索一下也有中文的版本。把官方文档的教程看完了也就能掌握基本的了。
—————————————————————————————————————————————————————— 一、什么是WINPCAP winpcap(windows packet capture)是windows平台下一个免费、开源、公共的网络访问系统。开发winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力。它的主要功能是进行数据包捕获和网络分析。它允许应用程序通过协议栈捕获和传输网络数据包,也包括内核级别的数据包过滤、网络静态引擎和支持远程数据包捕获等有用的功能。它提供了以下的各项功能: 1> 捕获原始数据报,包括在共享网络上各主机发送/接收的以及相互之间交换的数据报; 2> 在数据报发往应用程序之前,按照自定义的规则将某些特殊的数据报过滤掉; 3> 在网络上发送原始的数据报; 4> 收集网络通信过程中的统计信息。 winpcap的主要功能在于独立于主机协议(如TCP-IP)而发送和接收原始数据报。也就是说,winpcap不能阻塞,过滤或控制其他应用程序数据报的发收,它仅仅只是监听共享网络上传送的数据报。因此,它不能用于QoS调度程序或个人防火墙。 目前,winpcap开发的主要对象是windows NT/2000/XP,这主要是因为在使用winpcap的用户中只有一小部分是仅使用windows 95/98/Me,并且M$也已经放弃了对win9x的开发。因此本文相关的程序T-ARP也是面向NT/2000/XP用户的。其实winpcap中的面向9x系统的概念和NT系统的非常相似,只是在某些实现上有点差异,比如说9x只支持ANSI编码,而NT系统则提倡使用Unicode编码。 WinPcap由两部分组成: 驱动程序: 扩展操作系统功能提供低层次的网络访问 动态链接库:运行在Win32平台上的应用程序可以非常方便地访问网络低层次的数据。 Ethereal是大名鼎鼎的捕获数据包专业软件,它的运行是在WinPcap的支持之下的,如果没有安装WinPcap,Ethereal也无法正常捕获数据包。 二、WINPCAP编程环境设置 在正式WinPcap编程之前,要配置运行环境。 1、运行环境设置 Win32 平台下WinPcap应用程序需要以下四个动态链接库才能正常运行:wpcap.dll Packet.dll WanPacket.dll pthreadVC.dll 这四个动态链接库在WinPcap驱动程序里。 如果没有这个驱动程序,需要到WinPcap官方网站上下载,下载地址为:www.WinPcap.org 如果应用程序出现一下提示,那就是没有安装驱动程序的原因了。 也可以不安装WinPcap驱动程序。但是需要把上面提到的四个动态链接库文件拷贝到系统分区/WINDOWS/system32目录下。(似乎有些问题) 2、配置编程环境。 1> 从WWW.WINPCAP.ORG上下载WINPCAP SDK -WpdPack,WinPcap SDk里面包含库文件,头文件,文档文件和一些例子。解压到一个指定的目录。解压缩后把Include目录添加到IDE的包含文件中(VC6.0 Tools->Option->Directory; VS 2003/2005 工具->选项->项目和解决方案/项目->VC++目录); lib目录添加为新的库文件目录(VC6.0 Tools->Option->Directory; VS 2003/2005 工具->选项->项目和解决方案/项目->VC++目录)如下图所示。 2> 如果一个源文件使用了WinPcap提供的库函数,那么就需要在该文件开始的位置添加pcap.h包含文件(或者在引用的文件中),即#include “pcap.h” 也许会出现下面的错误: fatal error C1083: 无法打开包括文件:“pcap.h”: No such file or directory 这个错误表明找不到pcap.h文件,这个头文件在驱动程序安装完成后也是没有的,它是开发包里面的一个头文件,所以,如果要运行程序还需要到官方网站上去下载WinPcap SDK,并按步骤1添加到项目中。 3> 在程序中添加wpcap.lib。如果出现下面错误 error LNK2019: 无法解析的外部符号_pcap_findalldevs_ex,该符号在函数XXX 中被引用,如果发生上面的错误就表明缺少库文件,需要添加wpcap.lib到工程中(VC6.0 Project->Settings->Link->Object/library modules; VS 2003/2005 项目->添加现有项->所有文件)如下图所示: 4> 新的版本里WinPcap支持远程数据包获取,所以还应当添加一个头文件remote-ext.h ,即#include "remote-ext.h"(记住这条语句要放在#include “pcap.h”之后,否则会出错!) 否则会发生下面的错误 error C2065: “PCAP_SRC_IF_STRING”: 未声明的标识符 error C3861: “pcap_findalldevs_ex”: 找不到标识符 error C2065: “PCAP_OPENFLAG_PROMISCUOUS”: 未声明的标识符 error C3861: “pcap_open”: 找不到标识符 5> 或者不用添加#include "remote-ext.h".在VC.NET提供的IDE环境中,可以通过执行“项目”菜单中的的“属性”进入该项目的属性配置页,通过选择“配置属性”树中的“C/C++预处理哭”选项就增加’WPCAP’和’HAVE_REMOTE’两个标号。如下图所示: 6> 如果还有问题,可以到WinPcaP官方网站上找FAQ。 三、WINPCAP编程入门 利用WINPCAP捕获数据包一般要经过以下几个步骤 1、获取网络接口列表 通常, 一个基于WinPcap的应用程序所要做的第一件事, 就是获得适合的网络接口的列表.pcap_findalldevs()(或者pcap_findalldevs_ex())函数就是干这活的: 这个函数返回一个pcap_if结构的列表, 每个元素都记录了一个接口的信息. 其中, name和description以人类可以阅读的形式, 记录了设备的信息. 2、获取设备的高级信息 WinPcap 也可以为我们提供关于接口的更多信息. 由 pcap_findalldevs() 函数返回的 pcap_if 结构也包含了一个 pcap_addr 结构的列表, 它记录了以下信息: 1. 接口的地址列表 2. 接口的掩码列表 (与地址列表一一对应) 3. 接口的广播地址列表 (与地址列表一一对应) 4. 目标地址列表 (与地址列表一一对应) 3、打开一个接口并捕捉流量 现在我们已经知道如何获取一个接口的有关信息了, 我们可以来点真家伙了 -- 打开一个接口并捕捉流量. 接下来我们会编译一个程序, 它将捕捉网络中所有的数据包并输出他们的一些相关信息。我们使用函数 pcap_open_live() 来打开一个捕捉设备. 这里, 我们需要解释一下 snaplen, promisc 和 to_ms 参数. 函数原型: pcap_t * pcap_open_live (char *device, int snaplen, int promisc, int to_ms, char *ebuf) "snaplen" 参数指定了要捕捉的数据包的部分. 在某些操作系统中 (如 xBSD 和 Win32), 驱动程序提供了只捕捉每个数据包其中一部分的可能性: 这样就降低了要处理的数据的量, 从而提高了捕捉程序的效率. 在例子中, 我们使用一个高出 MTU 最大值的值 (65536) 以确保可以捕捉到成个数据包. "promisc" =1表明接口将会被设置为混杂模式. 一般情况下, 接口只处理目标地址为自己的数据; 到其他主机的数据包将会被忽略. 然而当一个接口处于混杂模式时, 它将会处理全部的流量: 也就是说, 在共享媒介, 例如非交换型以太网 (比如基于集线器的网络 )中, WinPcap 可以捕捉到所有主机的数据包. 混在模式是多数捕捉程序的默认模式, 所以我们在例子中也采用这种模式. "to_ms" 用以设置超时, 单位是毫秒. 一个从接口读取 ( Y- 捕捉) 的操作, (例如 pcap_dispatch() 或者 pcap_next_ex()), 如果没有捕捉到数据包, 那么在超过指定的时间以后就会返回. 进一步说, 如果接口处在静态模式中, to_ms 也定义了静态报告的间隔时间 (参阅 "Gathering Statistics on the network traffic " 以获取更多信息). 设置 to_ms 为 0, 则说明永远不会超时, 如果没有数据包到达, 那么捕捉操作将会永远不会返回, 而将其值设置为 -1 则会立刻返回. |