分类: 系统运维
2008-11-15 09:21:42
一、 libpcap工作原理
libpcap主要由两部份组成:网络分接头(Network Tap)和数据过滤器(Packet Filter)。网络分接头从网络设备驱动程序中收集数据拷贝,过滤器决定是否接收该数据包。Libpcap利用BSD Packet Filter(BPF)算法对网卡接收到的链路层数据包进行过滤。BPF算法的基本思想是在有BPF监听的网络中,网卡驱动将接收到的数据包复制一份交给BPF过滤器,过滤器根据用户定义的规则决定是否接收此数据包以及需要拷贝该数据包的那些内容,然后将过滤后的数据给与过滤器相关联的上层应用程序。
libpcap的包捕获机制就是在数据链路层加一个旁路处理。当一个数据包到达网络接口时,libpcap首先利用已经创建的Socket从链路层驱动程序中获得该数据包的拷贝,再通过Tap函数将数据包发给BPF过滤器。BPF过滤器根据用户已经定义好的过滤规则对数据包进行逐一匹配,匹配成功则放入内核缓冲区,并传递给用户缓冲区,匹配失败则直接丢弃。如果没有设置过滤规则,所有数据包都将放入内核缓冲区,并传递给用户层缓冲区。
二、 libpcap的抓包框架
pcap_lookupdev()函数用于查找网络设备,返回可被pcap_open_live()函数调用的网络设备名指针。
pcap_open_live()函数用于打开网络设备,并且返回用于捕获网络数据包的数据包捕获描述字。对于此网络设备的操作都要基于此网络设备描述字。
pcap_lookupnet()函数获得指定网络设备的网络号和掩码。
pcap_compile()函数用于将用户制定的过滤策略编译到过滤程序中。
pcap_setfilter()函数用于设置过滤器。
pcap_loop()函数pcap_dispatch()函数用于捕获数据包,捕获后还可以进行处理,此外pcap_next()和pcap_next_ex()两个函数也可以用来捕获数据包。
pcap_close()函数用于关闭网络设备,释放资源。
三、 libpcap-mmap
libpcap-mmap是libpcap的一个改进版本,它们捕获数据包的结构相同。不同的地方主要有以下两点:
1. libpcap使用固定大小的存储缓冲器和保持缓冲器来完成数据包从内核到用户层的传递,而libpcap-mmap设计了一个大小可以配置的循环缓冲器,允许用户程序和内核程序同时对该循环缓冲器的不同数据区域进行直接的读取。
2. 在libpcap中,当网卡接收到一个数据包之后,网卡驱动程序通过DMA方式调用系统函数netif_rx()将数据包从网卡拷贝到核心态内存,应用程序想访问位于核心态内存的数据时就必须将数据包从核心态内存中拷贝到用户态内存中,这样就占用了很多系统资源,降低数据包捕获的性能以及对数据包的处理能力。而libpcap-mmap采用MMAP技术,建立核心态内存和用户态内存的映射,将系统分配给网卡设备文件的核心态内存映射到一块用户态内存,这样应用程序可以通过调用系统函数recvfrom()函数把数据包从网卡上直接传送到用户态内存中,减少了一次数据拷贝,降低了系统资源的消耗,提高数据包捕获效率。