libpcap是unix/linux平台下的网络数据包捕获函数库。它是一个独立于系统的用户级数据包捕获的API接口,为底层网络监测提供一个可移植的框架。
1、 工作原理
一个包捕获机制包含三个主要部分,分别是:面向底层的包捕获引擎、面向中间层的数据包过滤器、面向应用层的用户接口。
linux操作系统对于数据包的处理流程是采用从底向上的方式,依次经历网络接口卡、网卡驱动层、数据链路层、IP层、传输层,最后到达应用程序。
而包捕获机制是在数据链路层增加一个旁路处理,对发送和接收到的数据包通过linux内核做过滤/缓冲等处理,最后直接传递给上层应用程序进行交互。
libpcap也是基于这种原理,libpcap的包捕获机制并不影响linux操作系统中网络协议栈对数据包的处理。
对应用程序而言,libpcap的包捕获机制只是提供了一个统一的API接口,用户只需要按照相关的编程流程,简单的调用若干函数就能捕获到感兴趣的数据包。
具体来说,libpcap库主要由三部分组成,分别为:网络分接头、数据包过滤器和用户API。
(1) 网络分接头
网络分接头(network tap)是一种链路层旁路机制,负责采集网卡数据包。
(2) 数据包过滤器
数据包过滤器(Packet Filter)是针对数据包的一种过滤机制,在libpcap中采用BPF(BSD Packet Filter)算法对数据包执行过滤操作,这种算法的基本思想是基于规则匹配,对于符合条件的数据包进行放行。
(3) 用户API
用户API是libpcap面向上层应用程序提供的编程接口,用户通过调用相关的函数实现数据包的捕获或发送。
具体说来,libpcap的工作流程可描述为:
当一个数据包到达网卡时,libpcap利用创建的套接字从链路层驱动程序中获得该数据包的复制,即旁路机制,同时通过tap函数将数据包发给BPF过滤器。
BPF过滤器 是根据用户已经定义好的过滤规则对数据包进行逐一匹配,若匹配成功则放入内核缓冲区,并传递给用户缓冲区;若匹配失败则直接丢弃。
如果没有设置过滤规则,则所有数据包都将被放入内核缓冲区,并传递给用户层缓冲区。
如图所示:
2、 抓包流程
1) 查找网络设备
查找网络设备的目的是发现可用的网卡,它的实现函数是pcap_lookupdev(),如果当前有多个网卡,函数会返回一个网络设备名指针列表。
2)打开网络设备
利用步骤1)的返回值,用户可以决定libpcap使用哪个网卡。
打开这个网络设备的函数是pcap_open_live(),函数调用成功后返回用于捕获数据网络包的描述字。
对于此网络设备的任何操作都要基于这个描述字。
3)获得网络参数
利用pcap_lookupnet()函数,可以获得指定网络设备的IP地址和子网掩码。
这个步骤并不是必须的,但为了显示的完整性,有时还是需要标记这些参数。
4)编译过滤策略
libpcap