http://www.paper.edu.cn
基于 WinPcap 的数据包捕获和分析系统的
设计与实现
郑玲
北京邮电大学信息与通信工程学院,北京 (100876)
Email: zhengling1123@gmail.com
摘 要:WinPcap 是 Windows 平台上高性能的包捕获开发工具。本文对 WinPcap 的结构和功
能进行了详细的介绍和分析,阐述了基于 WinPcap 捕获和分析网络数据包的方法和主要步
骤,并且给出了一个在 Windows 平台上,Microsoft VC++6.0 环境下,基于 WinPcap 捕获和
分析网络数据包的实例。该实例能过滤用户指定的 IP 地址、端口号和网络协议的数据包,
并在界面实时显示数据包的具体信息。
关键词:WinPcap,数据包,包捕获
中图分类号:TP39
1.引言
随着互联网的飞速发展,网络已成为信息交换的主要手段。一些网络新业务在不断地兴
起,如电子商务、移动支付等,这些都对网络安全提出了较高的要求。与此同时,黑客对网
络的攻击从未停止,很多网络攻击都是从捕获局域网中的数据包开始。因此研究网络底层数
据包捕获和分析技术对于保障网络安全有着重要的意义。
WinPcap 是一个基于 Win32 平台的, 用于捕获网络数据包并进行分析的开源库。 WinPcap
提供的驱动接口,可以在数据链路层实现对网络数据流的捕获和分析。同时,WinPcap 以其
开源的魅力和强大的功能,已经赢得越来越多的网络程序开发人员的青睐。
2.WinPcap 介绍
WinPcap 是由意大利人 Fulvio Risso 和 Loris Degioanni 等人提出并实现的 [1] , 在 Windows
平台上实现对底层数据包的捕获和过滤。WinPcap 能访问网络中的原始数据包,即没有被操
作系统利用网络协议处理过的数据包。它的主要思想来自于 UNIX 系统中著名的 BSD 包捕
获结构,具有良好的结构和性能。
总的来说,WinPcap 提供了以下 4 个功能:①捕获原始数据包,无论它是发往某台机器
的,还是在其他设备(共享媒介)上进行交换的;②在数据包发送给某应用程序前,根据用
户指定的规则过滤数据包; ③将原始数据包通过网络发送出去; ④收集并统计网络流量信息。
这些功能需要借助安装在 Win32 内核中的网络设备驱动程序和若干个动态链接库才能实现。
然而,WinPcap 有其应用的局限性:它不能阻止、过滤或操纵同一机器上的其他应用程序的
通讯,它仅仅能简单地“监视”在网络上传输的数据包。所以,它不能提供类似网络流量控
制、服务质量调度和个人防火墙之类的支持。
1
WinPcap 的整体结构分为三个相对独立的部分: 网络组包过滤器 (Netgroup Packet Filter,
NPF)、低级动态链接库(Packet.dll)和高级动态链接库(Wpcap.dll),如图 1 所示。
http://www.paper.edu.cn
Application
Wpcap.dll
Packet.dll
User Level
NPF Device Driver
Kernel Level
Packets
Network
图 1 WinPcap 系统结构
NPF(Netgroup Packet Filter)是一个虚拟设备驱动程序,是 WinPcap 的核心部分,它
从网卡驱动程序收集到网络数据包,转发给过滤器进行过滤,也可以发送给统计器进行网络
统计分析,还可以发送到转储器,直接将网络数据包存储到磁盘。
Packet.dll 是内核级、低层次的包过滤动态链接库,通过它直接映射到 Windows 系统内
核的调用,使应用程序可以运行在不同的 Windows 系统中,通过调用可直接访问 NPF 驱动
程序的 API,接收或发送网络数据包。
Wpcap.dll 是高级的、与系统无关的动态链接库,它与应用程序链接在一起,使用
packet.dll 提供的服务,向应用程序提供更完善的监听接口和更多功能的函数调用。
3.系统架构
本系统基于 WinPcap 用于捕获和分析网络数据包。用户可以根据需要,选择捕获指定
的 IP 地址、端口号和协议类型的数据包(默认捕获局域网内的所有数据包) 。捕获后系统在
用户界面以十六进制的形式实时地显示这些数据包的完整信息,并解析其帧长、源 MAC 地
址、目的 MAC 地址、以太网类型、源 IP 地址、目的 IP 地址、IP 协议、源端口号、目的端
口号等内容并显示在界面上。如果是 HTTP 协议的数据包,则显示其明文。同时,系统能够
把每次捕获的数据包保存在本地文件中,记录日志信息。
对于数据包的捕获,如果在一个繁忙的网络上进行,而不设置任何过滤,则得到的数据
2
http://www.paper.edu.cn
包是非常多的。如果应用程序不进行必要的性能优化,那么将会丢失大量的数据包。因此对
捕包性能的优化必不可少,本系统采用多线程来解决此问题:一个线程负责捕获数据包,一
个线程负者数据处理,一个线程负责用户界面显示。
3.1 主要步骤及相关函数
利用 WinPcap 对数据包进行捕获的主要步骤分为:开启指定网卡,设置过滤规则,循
环捕获网络数据包,以及分析处理网络数据包。
3.1.1 开启指定网卡
pcap_findalldevs()函数用来获取当前机器上所配置网络接口的内容,接口的全部信息都
保存在 pcap_if 结构链表中,链表的每项内容含有全面的网卡信息。pcap_open_live()函数专
门用于打开指定网卡设备。
以太网(Ethernet)具有共享介质的特征,信息是以明文的形式在以太网络上传输的。
网络适配器(网卡)具有 4 种工作模式:广播模式,多播模式,直接模式和混杂模式。缺省
工作模式包含广播模式和直接模式,即它只接收广播帧和发给自己的帧。当网络适配器设置
为混杂模式时,可以捕获同一个网络内所有的数据包。因此用 Winpcap 抓包时,需要将网
络适配器的工作模式设置为混杂模式。
3.1.2 设置过滤规则
WinPcap 过滤数据包的方法是结合使用 pcap_compile()和 pcap_setfilter()这两个函数。前
者将一个高层的布尔过滤表达式编译成一个能够被过滤引擎所解释的低层的字节码; 后者将
一个过滤器与内核捕获会话相关联。当 pcap_setfilter()被调用时,这个过滤器将被应用到来
自网络的所有数据包,并且所有符合要求的数据包(即那些经过过滤器以后,布尔表达式为
真的包)将会立即复制给应用程序。利用这两个函数可以方便地实现过滤数据包的功能。例
如, 要捕捉特定源/目的 IP 地址和特定源/目的端口的数据包, 只需将过滤器设置成诸如 “host
59.64.133.16 and tcp port 80”的高层表达式即可。
3.1.3 捕获网络数据包
WinPcap 提供 2 种抓包方法:pcap_loop()方法和 pcap_next_ex()方法。前者是基于回调
的原理来捕获数据包,用户在 pacp_loop()函数中写希望执行的代码,系统会记录下这个函
数的地址作为系统的一个接口。 当有数据包流过网卡时,系统会自动调用这个接口函数执行
相应的功能。 后者不同, 它是被程序员显示调用的, 即只有当编程人员使用了 pcap_next_ex()
函数才能收到数据包。该函数每次捕获一个数据包。
3.1.4 分析处理网络数据包
WinPcap 能访问网络中的原始数据包,即没有被操作系统利用网络协议处理过的数据
3
http://www.paper.edu.cn
包。捕获到的每一个数据包就是数据链路层中的每一帧。常用的以太网 MAC 帧格式有两种
标准:DIX Ethernet V2 标准(即以太网 V2 标准)和 IEEE 的 802.3 标准。现在使用最多的
是以太网 V2 的 MAC 帧格式。 该标准由 5 个字段组成: 6 字节的目的地址、 6 字节的源地址、
2 字节的类型(用来标识上一层的协议类型,例如:0x0800 表示上层使用是 IP 数据报)、46
字节至 1500 字节长度不等的 IP 数据报,以及 4 字节的帧检验序列(FCS)。分析每一帧可
以得到此数据包的源 MAC 地址和目的 MAC 地址,并且可以得到 IP 数据报的完整内容。
IP 数据报的第 4 至 7 位是 IP 首部长度,该字段可以用来准确定位上层协议的起始位置
(例如:TCP 的首部) 。第 10 字节是协议字段,指出该 IP 数据报携带的数据使用何种协议,
常用的协议字段如图 2 所示 [2] 。第 13 至 16 字节是源 IP 地址,第 17 至 20 字节是目的 IP 地
址。因此可以据此解析出该数据包的源 IP 地址和目的 IP 地址。
表 1 常用的 IP 协议和相应的字段值
协议名
ICMP
协议字段值
1
IGMP TCP
6
3
EGP
8
IGP
9
UDP
17
IPv6 OSPF
41
89
TCP 报文段的第 1 至 2 字节是源端口号,第 3 至 4 字节是目的端口号。第 13 字节的前
4 位是数据偏移,该字段实际上指出了 TCP 报文段的首部长度。如果 TCP 承载的是 HTTP
协议,则可以据此定位 HTTP 协议的起始位置。
系统处理时,如果分析是 HTTP 协议,则提取出 HTTP 的内容,以明文显示。而可以直
接显示 HTTP 报文信息的原因是:HTTP 是应用层协议,使用面向连接的 TCP 作为传输层
协议,在向下层传递时是以明文的方式直接传递,即 TCP 在 HTTP 报文前加 TCP 头封装
HTTP 报文。因此,只要把捕获到的数据包依次剥去 MAC 头、IP 头、TCP 头,就可以显示
HTTP 报文的内容了。
HTTP 报文分为两种:请求报文和响应报文。对于判断是否为 HTTP 报文,目前还没有
快速有效的方法。传统的方法依据:①传送 HTTP 报文前是否有 TCP 的三次握手;②判断
数据包中是否含有诸如“GET” 、 “HTTP/1.1”等关键字。对于这两种方法,第①点需要一定
的空间开销,要判断 TCP 承载的是否为 HTTP 报文,需要分配一定的空间存储前 3 个数据
包的相关信息(实际并不需要存储 3 个数据包的全部内容,但是即便是若干比特的信息,也
会增加 NPF 的负担),这给 NPF(Netgroup Packet Filter)的运行速率和存储器带来挑战;对
于第②点,由于 HTTP 是面向文本的,因此在报文中的每一个字段都是一些 ASCII 码串,
因而各个字段的长度都是不确定的。请求报文中除了 “GET”方法外,还有 7 种常用的方法,
如果要一一模式匹配来确定是否是 HTTP 报文,显然会造成很大的时间开销。此外,响应报
文含“HTTP/1.1” (或 HTTP/1.0)的版本号,这个字段在请求报文中也有,具体的版本是
1.1 还是 1.0 则是不确定的。
因此,综合考虑时间和空间的开销,本文采取模式匹配“HTTP”的方法来判断是否为
HTTP 报文。具体方法是:捕获到的数据包从 TCP 的尾部(HTTP 的第一个字节)开始匹配
“HTTP” ,如果匹配成功,则认为是 HTTP 报文,否则就不是。这种方法存在的问题是:①
4
http://www.paper.edu.cn
如果 TCP 承载的是 FTP 或 SMTP 等其他应用层协议,恰好在某个部分也含有“HTTP”字
样, 则会误判为 HTTP 报文。 但是由于基于 HTTP 协议的 Web 服务已经成为 Internet 的主流,
非 HTTP 协议只占到小部分, 因此误判的几率很小。 系统测试期间, 还未发现此类误判问题,
用户界面显示的明文信息表明: 确为 HTTP 协议的请求报文或响应报文。②该方法本身不存
在 “漏判” , 因为所有的 HTTP 报文都含有 “HTTP” 字样, 而抓到的数据包只要含有 “HTTP”
字样,就被过滤认为 HTTP 报文。但是,由于该方法需要一定的时间开销,可能来不及匹配
后续的数据包而造成广义上的“漏判” 。这个问题通过编写高效的模式匹配算法可以得到一
定的改进,但是不能解决根本问题。根本问题在于匹配速度和内核的存储器容量的限制。
对于过滤用户指定的 IP 地址和端口号,用户输入的 IP 地址为 char []字符数组型,而且
是用标准的 Internet 的“.”间隔格式来表示一个 Internet 地址,而捕获得到的数据包拆包后
的 IP 地址是网络字节的,因此不可直接比较。本文的方法是:首先用 inet_addr()将用户输
入的 IP 地址转换成一个无符号长整型数(实际上是 in_addr 类型),然后与抓到的数据包的
4 字节 IP 地址一一比较,即可过滤出用户指定的 IP 地址。对于端口号亦可类似处理。
3.2 系统流程图
根据上文阐述的基于 WinPcap 捕获和分析网络数据包的思想和方法,系统的流程图如
图所示。
5
http://www.paper.edu.cn
用户配置适配器
Adapter
用户设置过滤器
Filter
菜单项控制
Menu
开始抓包
停止接收?
N
从用户缓冲区
读取数据包处理
Y
N
满 足 用 户 设定
的过滤条件?
Y
不显示
数 据 包 信 息 显 示 在
界面的相应位置
图 2 系统流程图
释放适配器和
应用程序缓冲区
3.3 系统实例
根据上文阐述的基于 WinPcap 捕获和分析网络数据包的思想和方法,作者在 Windows
平台上,Microsoft VC++6.0 环境下,成功开发出一套软件,用来捕获并分析网络数据包。
该软件可以过滤出用户指定的 IP 地址、端口号及网络协议的数据包;同时分析每个数据包
的帧长、源 MAC 地址、目的 MAC 地址、以太网类型、源 IP 地址、目的 IP 地址、IP 协议、
源端口号、目的端口号等内容并显示在界面上。如果是 HTTP 协议,则在界面显示其明文;
否则以十六进制的形式显示其完整信息。 此外,软件还能把每次捕获的数据包保存在本地文
件中,记录日志信息。
设置网络适配器的界面如图 3 所示。
6
http://www.paper.edu.cn
用户设定 IP 地址、端口号和网络协议的界面如图 4 所示。
图 3 设置网络适配器
抓包结果显示图如图 5 所示。
图 4 设置过滤器
7
http://www.paper.edu.cn
(a)非 HTTP 报文,以十六进制显示
(b)HTTP 报文,显示明文
8