pcap使用手册
WinPcap 教程

WinPcap 教程: 循序渐进教您使用WinPcap本节将向您展示如何使用WinPcap API的一些特性。
这部分教程细化成若干节课,以循序渐进的方式介绍给读者,让读者从最基本的部分(获得设备列表)到最复杂的部分(控制发送队列并收集和统计网络流量)来了解如何使用WinPcap进行程序开发。
有时,我们会给出一些简单使用的代码片断,但同时,我们提供完整程序的链接:所有的源代码包含一些指向手册其他地方的链接,这可以让您很方便地通过点击鼠标来跳转到您想查看的函数和数据结构的内容中去。
范例程序都是用纯C语言编写, 所以,掌握基本的C语言编程知识是必须的,而且,这是一部关于处理原始网络数据包的教程,因为,我们希望读者拥有良好的网络及网络协议的知识。
用Microsoft Visual C++ 创建一个使用wpcap.dll 的应用程序,需要按一下步骤:∙在每一个使用了库的源程序中,将pcap.h 头文件包含(include)进来。
∙如果你在程序中使用了WinPcap中提供给Win32平台的特有的函数,记得在预处理中加入WPCAP 的定义。
(工程->设置->c/c++->预处理程序定义中添加WPCAP)∙如果你的程序使用了WinPcap的远程捕获功能,那么在预处理定义中加入HAVE_REMOTE。
不要直接把remote-ext.h直接加入到你的源文件中去。
(工程->设置->c/c++->预处理程序定义中添加HAVE_REMOTE)∙设置VC++的链接器(Linker),把wpcap.lib库文件包含进来。
wpcap.lib可以在WinPcap 中找到。
∙设置VC++的链接器(Linker),把ws2_32.lib库文件包含进来。
这个文件分布于C的编译器,并且包含了Windows的一些socket函数。
本教程中的一些范例程序,会需要它。
获取设备列表通常,编写基于WinPcap应用程序的第一件事情,就是获得已连接的网络适配器列表。
pcap使用手册

pcap使用手册让我们从看看这篇文章写给谁开始。
显而易见的,需要一些C语言基础知识,除非你只想了解基本的理论。
你不必是一个编码专家,因为这个领域只有经验丰富的程序员涉足,而我将尽可能详细的描述这些概念。
另外,考虑到这是有关一个包嗅探器的,所以对网络基础知识的理解是有帮助的。
所有在此出现的代码示例都已在FreeBSD 4.3平台上测试通过。
开始:pcap应用程序的格式我们所要理解的第一件事情是一个基于pcap的嗅探器程序的总体布局。
流程如下:1.我们从决定用哪一个接口进行嗅探开始。
在Linux中,这可能是eth0,而在BSD系统中则可能是xl1等等。
我们也可以用一个字符串来定义这个设备,或者采用pcap提供的接口名来工作。
2.初始化pcap。
在这里我们要告诉pcap对什么设备进行嗅探。
假如愿意的话,我们还可以嗅探多个设备。
怎样区分它们呢?使用文件句柄。
就像打开一个文件进行读写一样,必须命名我们的嗅探“会话”,以此使它们各自区别开来。
3.如果我们只想嗅探特定的传输(如TCP/IP包,发往端口23的包等等),我们必须创建一个规则集合,编译并且使用它。
这个过程分为三个相互紧密关联的阶段。
规则集合被置于一个字符串内,并且被转换成能被pcap读的格式(因此编译它)。
编译实际上就是在我们的程序里调用一个不被外部程序使用的函数。
接下来我们要告诉pcap使用它来过滤出我们想要的那一个会话。
4.最后,我们告诉pcap进入它的主体执行循环。
在这个阶段内pcap一直工作到它接收了所有我们想要的包为止。
每当它收到一个包就调用另一个已经定义好的函数,这个函数可以做我们想要的任何工作,它可以剖析所部获的包并给用户打印出结果,它可以将结果保存为一个文件,或者什么也不作。
5.在嗅探到所需的数据后,我们要关闭会话并结束。
这是实际上一个很简单的过程。
一共五个步骤,其中一个(第3个)是可选的。
我们为什么不看一看是怎样实现每一个步骤呢?设置设备这是很简单的。
Libpcap详细教程

Libpcap 是 Packet Capture library 的英文缩写,即数据包捕获函数库,该库提供的 C 函数接口用于捕获经过指定网络接口 (通过将网卡设置为混杂模式,可以捕获所有经过该网络接口的数据包 )的数据包。
著名的 TCPDUMP 就是在 Libpcap 的基础上开发而成的, Libpcap 提供的接口函数主要实现和封装了与数据包的采集、构造、发送等有关的功能。
Libpcap 面向上层应用,提供了用户级别的网络数据包捕获接口,在系统部署时充分考虑到应用程序的可以移植性。
Libpcap 主要有如下功能:(1)数据包捕获捕获流经本网卡的所有原始数据包,甚至对交换设备中的数据包也能够进行捕获,本功能是嗅探器的基础。
(2)自定义数据包发送构造任意格式的原始数据包,并发送到目标网络,本功能是新协议验证、甚至攻击验证的基础。
(3)流量采集与统计对所采集到的网络中的流量信息进行按照新规则分类,按指标进行统计,并输出到指定终端。
利用这项功能可以分析目标网络的流量特性。
(4)规则过滤Libpcap 自带规则过滤功能,并提供脚本编程接口,能够按照用户编程的方式对已经采集到的数据包进行过滤,以便提高分析的性能。
Libpcap 的应用范围:由于拥有强大的功能,当前基于 Libpcap 的应用比较广泛,有很多 Unix 上的流量相关的网络系统都是基于 Libpcap 的,它的一些典型应用如下:(1)网络协议分析器Libpcap 应用最多的就是网络协议分析器,也可以称之为网络嗅探。
(2)网络流量发生器网络流量发生器也是 Libpcap 的一大应用,它是基于 Libpcap 的数据构造与发送功能,可以有针对性的构造各种形式的数据包,并执行发送工作,这样的组合便构成了网络流量的产生工具。
(3)网络入侵检测系统网络入侵检测系统(IDS)是发现网络入侵行为的关键,利用 Libpcap 所提供的数据包捕获功能,可以进一步开发出 IDS。
pcap tls协议解析规则

pcap tls协议解析规则
摘要:
1.PCAP 简介
2.TLS 协议概述
3.PCAP 解析TLS 协议的方法
4.PCAP tls 协议解析规则的实际应用
5.总结
正文:
1.PCAP 简介
PCAP(Packet Capture) 是一种网络数据包捕获技术,可以用于监视和分析网络流量。
PCAP 可以捕获网络中的所有数据包,包括TLS 加密协议的数据包。
2.TLS 协议概述
TLS(Transport Layer Security) 是一种安全协议,用于保护网络通信。
TLS 协议通常用于保护Web 浏览器和Web 服务器之间的通信,以及其他需要保护数据传输的应用程序。
3.PCAP 解析TLS 协议的方法
PCAP 可以捕获TLS 协议的数据包,并通过解析这些数据包来获取TLS 协议的详细信息。
PCAP 可以使用各种工具来解析TLS 协议,例如Wireshark 和tcpdump。
4.PCAP tls 协议解析规则的实际应用
PCAP tls 协议解析规则可以用于监视和分析网络流量,以确保网络安全。
例如,可以使用PCAP tls 协议解析规则来检测TLS 协议的漏洞,并采取相应的措施来修复这些漏洞。
5.总结
PCAP 是一种强大的网络数据包捕获技术,可以用于监视和分析网络流量。
JNetPcap安装及使用

JNetPcap安装及使⽤啥是JNetPcap?JNetPcap是由开发的开源DPI(Deep Packet Inspection)SDK。
Java平台底层不⽀持底层⽹络操作,需要通过JNI封装不同系统提供的C库提供Java访问⽅法。
JnetPcap主要有下⾯四个特点:1. 提供⼏乎所有libpcap类的封装2. 实时解码抓取到的数据包3. 提供多种类的⽹络协议解析库4. 通过使⽤SDK⽤户可以轻松的扩展⽹络协议5. 通过native和Java实现,来优化解码过程JnetPcap安装JnetPcap的安装其实也⽐较简单,也就是3步⾛的政策。
关键有时候会搞不清楚,容易拉掉某些步骤。
因此,我将这些步骤整理如下:1. 安装依赖在第⼀部分对JNetPcap的介绍中已经提过了,JNetPcap⼏乎提供libpcap的所有封装,所以他肯定要依赖于libpcap的啦,通过⼀下命令在你的机器上安装libpcap。
yum install -y libpcap libpcap-devel2. 引⼊jar包引⼊jar包就是直接将jar包引⼊到你的项⽬中就可以了。
3. 设定library个⼈感觉这⼀步还是⽐较坑爹的,因为当你运⾏⼀个普通的java程序和运⾏⼀个hadoop MapReduce程序时,library的⽂件⽬录可能会有所不同。
你可以通过以下⽅法,查看当前java程序的library⽬录地址。
public class Main {public static void main() {// 输出当前程序的library⽬的地址System.out.println(System.getProperty("java.library.path"));}}然后将jnetpcap.so复制到上⾯输出的library⽬录中即可。
JNetPcap的相关demo参见。
参考⽂档1.。
实验3:WinPcap技术的使用

实验3:WinPcap技术的使用1实验目的和要求学习使用WinPcap开发包实现网络数据包的捕获、过滤和分析的功能,具体要求如下:1)WinPcap开发包的下载和安装;2)使用WinPcap获取与网络适配器绑定的设备列表;3)使用WinPcap获取网络适配器的高级属性信息;4)使用WinPcap打开网络适配器并实现抓包功能5)使用WinPcap过滤数据包、分析数据包。
2实验设备及材料1)Windows主机2)Visual Studio 2005或Visual Studio 20083实验内容本实验学习WinPcap开发包的使用,利用WinPcap实现网络数据包捕获、过滤和分析的功能,实验内容如下。
3.1 WinPcap开发包的下载和安装下载并安装WinPcap开发包,下载地址:/archive/。
1)4.1.1-WinPcap.exe的安装;2)4.1.1-WpdPack.zip的下载和使用。
3.2获取与网络适配器绑定的设备列表信息pcap_findalldevs_ex()函数的使用。
调用pcap_findalldevs_ex()函数,获取的网络设备信息将存储在结构体pcap_if_t中,然后打印网卡设备列表信息,包括网络适配器名称和描述。
3.3获取网络适配器的高级属性信息在3.2的基础上,除打印本地主机所有网络适配器的名称、描述外,还打印是否回环地址、协议簇类型、协议簇名称、IP地址、子网掩码、广播地址和目标地址等信息。
3.4打开网络适配器并通过事件处理器来捕获数据包pcap_open()函数和pcap_loop()函数的使用。
程序的运行过程如下:1)调用pcap_findalldevs_ex()函数获取并打印本机的网络设备列表。
2)要求用户选择用于捕获数据包的网络设备。
3)使用for语句跳转到选中的网络设备,以便在后面的程序中打开该设备,并在该设备上捕获数据。
4)调用pcap_open()函数打开选择的网络设备。
Winpcap使用介绍

Winpcap使用介绍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提供的功能包括四个方面:捕获原始数据包,包括在共享网络上各主机发送/接收的以及相互之间交换的数据包;在数据包发往应用程序之前,按照自定义的规则将某些特殊的数据包过滤掉;在网络上发送原始的数据包;收集网络通信过程中的流量信息。
pcap手册

pcap - Packet Capture librarySYNOPSIS大纲#include <pcap.h>char errbuf[PCAP_ERRBUF_SIZE];pcap_t *pcap_open_live(const char *device, int snaplen,int promisc, int to_ms,char *errbuf)pcap_t *pcap_open_dead(int linktype, int snaplen)pcap_t *pcap_open_offline(const char *fname, char *errbuf)pcap_dumper_t *pcap_dump_open(pcap_t *p, const char *fname)int pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf);int pcap_getnonblock(pcap_t *p, char *errbuf);int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)void pcap_freealldevs(pcap_if_t *alldevs)char *pcap_lookupdev(char *errbuf)int pcap_lookupnet(const char *device, bpf_u_int32 *netp,bpf_u_int32 *maskp, char *errbuf)int pcap_dispatch(pcap_t *p, int cnt,pcap_handler callback, u_char *user)int pcap_loop(pcap_t *p, int cnt,pcap_handler callback, u_char *user)void pcap_dump(u_char *user, struct pcap_pkthdr *h,u_char *sp)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)void pcap_freecode(struct bpf_program *);const u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,const u_char**pkt_data)void pcap_breakloop(pcap_t *)int pcap_datalink(pcap_t *p)int pcap_list_datalinks(pcap_t *p, int **dlt_buf);int pcap_set_datalink(pcap_t *p, int dlt);int pcap_datalink_name_to_val(const char *name);const char *pcap_datalink_val_to_name(int dlt);const char *pcap_datalink_val_to_description(int dlt);int pcap_snapshot(pcap_t *p)int pcap_is_swapped(pcap_t *p)int pcap_major_version(pcap_t *p)int pcap_minor_version(pcap_t *p)int pcap_stats(pcap_t *p, struct pcap_stat *ps)FILE *pcap_file(pcap_t *p)int pcap_fileno(pcap_t *p)void pcap_perror(pcap_t *p, char *prefix)char *pcap_geterr(pcap_t *p)char *pcap_strerror(int error)const char *pcap_lib_version(void)void pcap_close(pcap_t *p)int pcap_dump_flush(pcap_dumper_t *p)FILE *pcap_dump_file(pcap_dumper_t *p)void pcap_dump_close(pcap_dumper_t *p)DESCRIPTIONThe Packet Capture library provides a high level interface to packet capture systems. All packets on the network, even those destined去往,注定for other hosts, are accessible可进入的,可及的through this mechanism.机械装置,原理ROUTINES函数NOTE: errbuf in pcap_open_live(), pcap_open_dead(), pcap_open_offline(), pcap_setnonblock(), pcap_getnonblock(), pcap_findalldevs(), pcap_lookupdev(), and pcap_lookupnet() is assumed假定的to be able to hold at leastPCAP_ERRBUF_SIZE chars.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 doesn't 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 don't, 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.pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char*ebuf)功能打开网卡参数char *device 指定的嗅探设备;snaplen pcap捕获的最大字节数;promisc 是否将指定接口设为为混杂模式;to_ms 读取时的超时值,单位是毫秒,如果为0则一直嗅探直到错误发生,为-1则不确定;。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
让我们从看看这篇文章写给谁开始。
显而易见的,需要一些C语言基础知识,除非你只想了解基本的理论。
你不必是一个编码专家,因为这个领域只有经验丰富的程序员涉足,而我将尽可能详细的描述这些概念。
另外,考虑到这是有关一个包嗅探器的,所以对网络基础知识的理解是有帮助的。
所有在此出现的代码示例都已在FreeBSD 4.3平台上测试通过。
开始:pcap应用程序的格式我们所要理解的第一件事情是一个基于pcap的嗅探器程序的总体布局。
流程如下:1.我们从决定用哪一个接口进行嗅探开始。
在Linux中,这可能是eth0,而在BSD系统中则可能是xl1等等。
我们也可以用一个字符串来定义这个设备,或者采用pcap提供的接口名来工作。
2.初始化pcap。
在这里我们要告诉pcap对什么设备进行嗅探。
假如愿意的话,我们还可以嗅探多个设备。
怎样区分它们呢?使用文件句柄。
就像打开一个文件进行读写一样,必须命名我们的嗅探“会话”,以此使它们各自区别开来。
3.如果我们只想嗅探特定的传输(如TCP/IP包,发往端口23的包等等),我们必须创建一个规则集合,编译并且使用它。
这个过程分为三个相互紧密关联的阶段。
规则集合被置于一个字符串内,并且被转换成能被pcap读的格式(因此编译它)。
编译实际上就是在我们的程序里调用一个不被外部程序使用的函数。
接下来我们要告诉pcap使用它来过滤出我们想要的那一个会话。
4.最后,我们告诉pcap进入它的主体执行循环。
在这个阶段内pcap一直工作到它接收了所有我们想要的包为止。
每当它收到一个包就调用另一个已经定义好的函数,这个函数可以做我们想要的任何工作,它可以剖析所部获的包并给用户打印出结果,它可以将结果保存为一个文件,或者什么也不作。
5.在嗅探到所需的数据后,我们要关闭会话并结束。
这是实际上一个很简单的过程。
一共五个步骤,其中一个(第3个)是可选的。
我们为什么不看一看是怎样实现每一个步骤呢?设置设备这是很简单的。
有两种方法设置想要嗅探的设备。
第一种,我们可以简单的让用户告诉我们。
考察下面的程序:#include <stdio.h>#include <pcap.h>int main(int argc, char *argv[]){char *dev = argv[1];printf("Device: %s", dev);return(0);}用户通过传递给程序的第一个参数来指定设备。
字符串“dev”以pcap能“理解”的格式保存了我们要嗅探的接口的名字(当然,用户必须给了我们一个真正存在的接口)。
另一种也是同样的简单。
来看这段程序:#include <stdio.h>#include <pcap.h>int main(){char *dev, errbuf[PCAP_ERRBUF_SIZE];dev = pcap_lookupdev(errbuf);printf("Device: %s", dev);return(0);}在这个例子里,pcap就自己设置设备。
“但是,等一下,Tim”,你会说,“字符串errbuf 是做什么的?”大多数的pcap命令允许我们向它们传递字符串作为参数。
这个字符串的目的是什么呢?如果命令失败,它将传给这个字符串关于错误的描述。
这样,如果pcap_lookupdev()失败,它将在errbuf存储错误信息。
很好,是不是?这就是我们怎样去设置设备。
打开设备进行嗅探创建一个嗅探会话的任务真的非常简单。
为此,我们使用pcap_open_live()函数。
此函数的原型(根据pcap的手册页)如下:pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)其第一个参数是我们在上一节中指定的设备,snaplen是整型的,它定义了将被pcap捕获的最大字节数。
当promisc设为true时将置指定接口为混杂模式(然而,当它置为false 时接口仍处于混杂模式的特殊情况也是有可能的)。
to_ms是读取时的超时值,单位是毫秒(如果为0则一直嗅探直到错误发生,为-1则不确定)。
最后,ebuf是一个我们可以存入任何错误信息的字符串(就像上面的errbuf)。
此函数返回其会话句柄。
举个例子,考察以下代码片断:#include <pcap.h>...pcap_t *handle;handle = pcap_open_live(somedev, BUFSIZ, 1, 0, errbuf);这个代码片断打开字符串somedev的设备,告诉它读取被BUFSIZ指定的字节数(BUFSIZ在pcap.h里定义)。
我们告诉它将设备置为混杂模式,一直嗅探到错误发生,如果有了错误,把它存放在字符串errbuf中。
混杂模式与非混杂模式的区别:这两种方式区别很大。
一般来说,非混杂模式的嗅探器中,主机仅嗅探那些跟它直接有关的通信,如发向它的,从它发出的,或经它路由的等都会被嗅探器捕获。
而在混杂模式中则嗅探传输线路上的所有通信。
在非交换式网络中,这将是整个网络的通信。
这样做最明显的优点就是使更多的包被嗅探到,它们因你嗅探网络的原因或者对你有帮助,或者没有。
但是,混杂模式是可被探测到的。
一个主机可以通过高强度的测试判定另一台主机是否正在进行混杂模式的嗅探。
其次,它仅在非交换式的网络环境中有效工作(如集线器,或者交换中的ARP层面)。
再次,在高负荷的网络中,主机的系统资源将消耗的非常严重。
过滤通信通常,我们的嗅探器仅对某特定的通信感兴趣。
例如,有时我们想嗅探到端口23(telnet)的包以获得密码;或者我们想截获一个正通过端口21 (FTP)传送的文件;可能我们仅想要得到DNS的通信(端口53,UDP)。
无论哪种情况,我们都很少盲目的嗅探整个网络的通信。
下面讨论pcap_compile()与pcap_setfilter()。
这个过程非常简单。
当我们已经调用了pcap_open_live()从而建立了一个嗅探会话之后就可以应用我们自己的过滤器了。
为什么要用我们自己的过滤器呢?有两个原因。
第一,pcap 的过滤器太强大了,因为它直接使用BPF过滤器,我们通过使用BPF驱动直接过滤跳过了很多的关节。
第二,这样做要容易的多。
在使用我们自己的过滤器前必须编译它。
过滤表达式被保存在一个字符串中(字符数组)。
其句法在tcpdump的手册页中被证明非常好。
我建议你亲自阅读它。
但是我们将使用简单的测试表达式,这样你可能很容易理解我的例子。
我们调用pcap_compile()来编译它,其原型是这样定义的:int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask)第一个参数是会话句柄(pcap_t *handle在前一节的示例中)。
接下来的是我们存储被编译的过滤器版本的地址的引用。
再接下来的则是表达式本身,存储在规定的字符串格式里。
再下边是一个定义表达式是否被优化的整形量(0为false,1为true,标准规定)。
最后,我们必须指定应用此过滤器的网络掩码。
函数返回-1为失败,其他的任何值都表明是成功的。
表达式被编译之后就可以使用了。
现在进入pcap_setfilter()。
仿照我们介绍pcap的格式,先来看一看pcap_setfilter()的原型:int pcap_setfilter(pcap_t *p, struct bpf_program *fp)这非常直观,第一个参数是会话句柄,第二个参数是被编译表达式版本的引用(可推测出它与pcap_compile()的第二个参数相同)。
下面的代码示例可能能使你更好的理解:#include <pcap.h>pcap_t *handle; /* 会话的句柄*/char dev[] = "rl0"; /* 执行嗅探的设备*/char errbuf[PCAP_ERRBUF_SIZE]; /* 存储错误信息的字符串*/struct bpf_program filter; /*已经编译好的过滤表达式*/char filter_app[] = "port 23"; /* 过滤表达式*/bpf_u_int32 mask; /* 执行嗅探的设备的网络掩码*/bpf_u_int32 net; /* 执行嗅探的设备的IP地址*/pcap_lookupnet(dev, &net, &mask, errbuf);handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);pcap_compile(handle, &filter, filter_app, 0, net);pcap_setfilter(handle, &filter);这个程序使嗅探器嗅探经由端口23的所有通信,使用混杂模式,设备是rl0。
你可能注意到前面的示例包含一个我们还没提到的函数:pcap_lookupnet(),向这个函数提供设备接口名,它将返回其IP和网络掩码,这是很基本的,因为我们需要知道网络掩码以便应用过滤器。
此函数在此文最后的miscellaneous一节里还有描述。
据我的经验,这个过滤器在所有的操作系统下都不会工作。
在我的测试环境里,我发现OpenBSD 2.9默认内核支持这种过滤器,但FreeBSD 4.3默认内核则不支持。
你的情况可能会有变化。
实际的嗅探到此为止,我们已经学习了如何定义一个设备,让它准备嗅探,还有应用过滤器使我们嗅谈到什么或者不嗅探到什么。
现在到了真正去捕获一些数据包的时候了。
有两种手段捕获包。
我们可以一次只捕获一个包,也可以进入一个循环,等捕获到多个包再进行处理。
我们将先看看怎样去捕获单个包。
pcap_next()的原型及其简单:u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)第一个参数是会话句柄,第二个参数是指向一个包括了当前数据包总体信息(被捕获时的时间,包的长度,其被指定的部分长度)的结构体的指针(在这里只有一个片断,只作为一个示例)。
Pcap_next()返回一个u_char指针给被这个结构体描述的包。
我们将稍后讨论这种实际读取包本身的手段。
这里有一个演示怎样使用pcap_next()来嗅探一个包的例子:#include <pcap.h>#include <stdio.h>int main(){pcap_t *handle; /* 会话句柄*/char *dev; /* 执行嗅探的设备*/char errbuf[PCAP_ERRBUF_SIZE]; /* 存储错误信息的字符串*/struct bpf_program filter; /* 已经编译好的过滤器*/char filter_app[] = "port 23"; /* 过滤表达式*/bpf_u_int32 mask; /* 所在网络的掩码*/bpf_u_int32 net; /* 主机的IP地址*/struct pcap_pkthdr header; /* 由pcap.h定义*/const u_char *packet; /* 实际的包*//* Define the device */dev = pcap_lookupdev(errbuf);/* 探查设备属性*/pcap_lookupnet(dev, &net, &mask, errbuf);/* 以混杂模式打开会话*/handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);/* 编译并应用过滤器*/pcap_compile(handle, &filter, filter_app, 0, net);pcap_setfilter(handle, &filter);/* 截获一个包*/packet = pcap_next(handle, &header);/* 打印它的长度*/printf("Jacked a packet with length of [%d]", header.len);/* 关闭会话*/pcap_close(handle);return(0);}这个程序嗅探被pcap_lookupdev()返回的设备并将它置为混杂模式。