刘 琦 江西科技师范大学理工学院 330044
【文章摘要】
随着网络的迅速发展,信息量的增大,大量的无效数据降低了网络监控的效率,对网络数据包的捕获和过滤变得尤为必要了。BPF 网络数据包过滤器以其简洁的结构在Linux 操作系统内核中对网络数据包进行过滤,减轻了用户层工作的负担并且提高了捕获网络数据包的效率。
【关键字】
BPF ;过滤器;网络数据包
0 引言
网络数据包类型也不尽相同。在绝大多数情况下都只需要所有网络数据包的一部分。例如:对邮件系统进行监控的可能只需要端口号为25 或者110 的TCP 网络数据包,对DNS 系统进行监控可能就只需要端口号为53 的UDP 网络数据包。BPF 网络数据包过滤机制的引入就是为了解决这个问题的。用户程序只需简单地设置一系列过滤器,最终便能获得满足要求的网络数据包。
1 虚拟机指令的生成
BPF 中的虚拟机指令生成结构分为编译器和优化器两个独立的组成部分。首先编译器将高层语言表示的过滤器转化为无环控制流图CFG,再将此控制流图转化为符合SSA 中间表示形式的控制流图, 最后优化器负责对SSA 形式的控制流图进行优化,并生成最终的虚拟机指令,也就是虚拟机中间字节码(VM Byte Codes)
其中SSA 是BPF 引入的静态单赋值(static single assignment, SSA),它是一种优化的编译器数据结构,使用SSA 中间表示形式有利于使用更多的编译器优化算法或者提高这些算法的效率。
BPF 中虚拟机指令的生成的流程图如图1。
2 BPF 过滤器的主要代码实现过程
过滤过程是从一个用户所定义的过滤器( 比如:捕获起所有的TCP 数据包) 开始,首先应用程序调用Libpcap 源码中的gencode.c 文件中的pcap_compile() 函数来编译过滤器,通过该函数生成所需的虚拟机中间字节码。然后应用程序调用Libpcap 源码中的pcap.c 文件中的pcap_ setfilter() 函数将一个过滤器与一个捕获实例相关联,把过滤器的字节码传递给内核的BPF 驱动程序中,当进行数据捕获时, 驱动程序执行该过滤器对来自网络的所有数据包进行过滤,所有符合要求的数据包将会复制给应用程序,否则丢弃该数据包。
0.1pcap_setfilter() 函数代码实现
pcap_setfilter() 函数的顶层源代码如下:
int pcap_setfilter(pcap_t *p,struct bpf_ program *fp)/* 参数fp 是指向一个bpf_ program 结构体的指针,通常是调用pcap_ compile() 函数的返回结果*/
{
return p->setfilter_op(p,fp);
}
该函数用来把一个过滤器已经编译好的指令与内核捕获实例相关联,当pcap_setfilter() 函数被调用时,该过滤器将被应用到来自网络的所有数据包,并且所有符合要求的数据包将会被存储到内核缓存区中,以供应用程序使用。
3 结语
BPF 具有高效、简洁等独到的优点, 从而大大提高了网络数据包捕获的运行性能和效率。本文详细分析和研究了Libpcap 的BPF 过滤器,首先讲解了BPF 在Linux 内核中的位置和结构,然后详细分析了BPF 处理高层语言表示的过滤器, 最后通过设置了一个过滤器进行网络数据包的捕获,捕获到了满足要求的网络数据包。进一步说明了BPF 过滤器对捕获网络数据包的重要性和必要性。
【参考文献】
[1] 朱雁辉.Windows 防火墙与网络封包截获技术[M]. 北京:电子工业出版社,2002.
[2]Lawrence Berkeley National Labs. Libpcap,Network Research.Giroup[EB/ OL],
http:www.tcpdump.org,2009
[3] 王催. 基于BPF 模型的包捕获与过滤机制的研究及应用[J]. 计算机与数字,2008
图1121
财会研究
Finance Research
122
质量管理