《电子技术应用》
您所在的位置:首页 > 通信与网络 > 业界动态 > 一种高速数据包捕获系统的设计与实现

一种高速数据包捕获系统的设计与实现

2008-03-20
作者:饶 超,黄 建,顿新平

  摘 要: 提出一种针对高速光网络环境的数据包捕获平台的设计方案。采用软硬件结合" title="软硬件结合">软硬件结合的设计思想,由系统硬件完成数据包的解析和过滤,软件根据硬件解析结果将数据直接向应用进程分发。驱动部分借鉴了零拷贝和循环缓冲区技术,并进行了中断优化以降低数据采集的CPU占用率。
  关键词: 软硬件结合 规则  包捕获  64位PCI  OC48接口

 

  随着网络的普及,安全问题正威胁着每个网络用户。因此对计算机的网络监控十分必要,而其中对网络数据包的捕获和分析尤为重要。随着网络带宽不断增加,监控高速网络数据流的需求越来越明显,各种数据包捕获技术在大规模宽带网络的入侵检测系统[1]、大流量网络数据情况下的网络协议分析、宽带网络防火墙和高性能路由器等领域中,都具有广泛的应用前景。
1 传统方案
  传统的数据包捕获方案一般是基于普通的网卡,通过应用程序和支持库把网卡设置成混杂模式[2],从而绕开网卡通常的工作程序,使之能够接受目标地址而不是自己MAC地址的数据包,再经过过滤、解析实现监控。
  目前实现包捕获功能的软件有很多。支持Linux操作系统的Libpcap[3]库就是基于BPF模型一个典型数据包捕获平台。Libpcap 实质上是一个系统独立的 API 函数接口,用于用户层次的数据包截获工作。它为底层网络监控编程提供了易于移植的应用框架。利用Libpcap库开发的网络监控的工具如Tcpdump[3]等,大多有效地利用了库中的接口实现了按需捕获功能。但是总体上来看,这些工具由于设计上的限制,即使工作在非常强大的硬件平台上,在面对现代高速网络时也越来越难以应付,特别是在快于千兆的光网络环境中,常常因为来不及处理导致丢包相当严重。
2 改进方案概述
  这是一种采用软硬件结合的高速数据包捕获实现方案。为了能适用于高速光网络环境,硬件部分完成了对实时性要求高的数据包的预处理工作,软件部分在后期能够对数据包进行再次的深度处理。整个系统硬件的关键在包解析处理模块" title="处理模块">处理模块和规则管理模块。包解析处理模块实现了数据包的预处理;规则管理模块则用于规则存储和查找,包解析处理模块对数据包的过滤有赖于查找的结果。基于硬件配置的灵活性,可以在前期就将未匹配成功、校验出错、太短或太长等不符合要求的数据包丢弃,后期处理阶段可以专注于对有处理需求的数据包进行解析,极大地提高了整个系统的性能。另外,由于目前大部分宽带IP网的地市级出口基本上都是由2.5Gbps POS(Packet Over SONET)链路组成,每个设备采用了两路2.5Gbps OC48 POS接口作为数据输入;而输出端采用了64 bit 66MHz的PCI总线设计,从而在主机一侧保证带宽。为了适应更高的采样需求,驱动在设计上支持多设备协同工作。
  系统软件部分基于Linux操作系统平台,由驱动程序和自定义的库函数组成。驱动程序实现了系统各芯片的初始化,响应上层对规则和硬件配置的要求和维护数据缓冲区等功能。库函数介于应用程序与驱动程序之间,起到一个桥梁中介作用,主要向上层提供类似Libpcap的API,从而把复杂的处理函数封装起来,给用户一个简洁通用的接口。
  考虑到传统方案主要在网卡中断、内存操作、用户态和内核态间的拷贝等方面存在瓶颈,软件中做了几项改进:(1)改进了中断方式,以数据块" title="数据块">数据块而不是以单个数据包触发中断,减少了中断的频率;(2)借鉴零拷贝的思想,避免了不必要的内存拷贝;(3)利用循环缓冲区(ring buffer)存储用户数据, 提高了内存利用率。
3 系统设计及实现
3.1 系统硬件实现
  系统利用硬件代替Linux内核实现了数据包的差错校验和协议栈的初步解析。一定格式的过滤规则按照优先级存储于规则管理模块中,规则管理模块将包解析模块从数据包的一些控制字段中抽取出关键字同预设的所有规则进行比较,选出优先级最高的匹配规则,匹配的结果反馈给包处理模块,而没有匹配到任何规则的数据包会被丢弃。符合要求的数据包被加上一个叫做internal head的自定义头部。这个自定义头部包含了这个数据包的长度、协议类型、时间戳和cookie等信息,这里cookie字段是数据包分发的依据。此后驱动程序惟一需要解析的包头只有自定义头部,从而降低了软件处理部分的复杂度。
  经过过滤后,符合要求的数据包会被暂存在硬件外部高速存储器中,同时包处理模块以中断的方式通知驱动新数据的到来。为避免频繁中断带来的额外的系统开销,在设计上采用了以数据块而不是以数据包的方式来触发中断:暂存在硬件外部高速存储器中的数据达到规定大小时触发中断, 数据借助这次中断通过DMA方式送往主机侧。当然,为防止收取不到规定大小的数据块而造成的死锁,也就是如果收取的数据在一定时间仍没有办法达到这个大小,则采用超时机制强行发出中断请求,送出剩余的数据。
系统硬件数据处理的整个过程如图1所示。


3.2 系统软件实现
  本系统在Linux操作系统中被注册为一个字符设备并共用一个设备号。为了提供对多设备的支持,这里设计了一个全局的私有结构来区分它们,每个结构被用一个单向链表管理起来:每当驱动程序找到一个新设备,就给它分配一个新的结构并挂在链表上。另外这个结构的另一个用途是作为中断处理" title="中断处理">中断处理函数的dev_id参数,在中断来时中断处理函数能够以此区分不同的设备。
  从驱动程序代理用户进程设置过滤规则到硬件触发中断通知驱动程序收取数据包,驱动程序代表整个系统进行一些必要的工作。
  整个系统的软件结构如图2所示。


3.2.1 用户规则设置
  每个用户进程在创建初期会在内核中获取一块或多块连续内存块用来存储自己所需的数据。考虑到用户进程可能在数量上会很多,系统初始化时就已经申请好一定数量固定大小的内存块,并打上id标记等待进程来申请。为了提高内存的利用率,这里利用了循环缓冲区结构来管理每个内存块。循环缓冲区可以让驱动程序专心进行数据接收而不用考虑读进程,同时内存也不会被浪费。为避免频繁的数据拷贝,借鉴了零拷贝[4](zero-copy)的思想。零拷贝基本思想是:数据包从网络设备到用户程序空间传递的过程中,减少数据拷贝次数,减少系统调用,在一定程度上实现CPU的零参与。实现零拷贝采用的最主要技术是DMA数据传输技术和内存区域映射技术。传统的网络数据包过滤处理,需要进行多次数据拷贝,整个过程需要用户进程向系统发出的系统调用,其中涉及到操作系统大量的上下文切换和CPU的始终参与。零拷贝技术首先利用DMA技术将网络数据包通过DMA通道直接推入系统内核中一个公共缓冲区,其过程可与主机并行操作,然后由公共缓冲区分发给相应用户缓冲区。由于位于内核空间的用户缓冲区是受保护的,应用进程在用户态无法直接访问。排除低效率的系统调用方法,这里采用了Linux的一种高效的内存映射机制mmap将内核空间映射到虚地址空间,用户通过这个空间内的虚地址就能访问到相应的用户缓冲区了。
  创建用户进程的同时,过滤规则也按一定语法被设置。规则通过库函数和系统调用被按一定优先级(这里称规则索引)存储于规则管理模块中,此时该规则开始生效。为了方便驱动管理规则,同样的规则以链表的方式保存于系统内存中。软件中的规则是硬件中的规则的抽象,两者每时每刻都保持着同步。
  用户的缓冲区和用户设置的规则被前文所述的内存块id标记联系起来。这个标记的值会赋予以规则索引为下标的数组从而完成关联。


  一个进程添加新规则的过程如图3所示。虚线箭头表示控制流。用户进程发出系统调用在内存中创建新规则及其规则索引,驱动程序代替它查询用户缓冲区得到一个空闲内存块的id标记号,然后这个id号关联到新规则,也从而使用户缓冲区的内存块、规则和用户进程三者对应起来,最后规则被添加进入硬件。值得注意的是,如果驱动程序发现内存中已存在同样的规则,它仅会把这个进程申请到的id号放在旧规则索引的数组最后。
  在做好其他相应的设置以后,应用进程会到自己的用户缓冲区中查看是否有新的数据到来。这里没有采用常用的轮询方法来检查缓冲区。虽然轮询不需要硬件特别的支持,但随之带来的问题也是明显的。频率过高的轮询会大量地消耗CPU的时钟周期;时间间隔过大则会带来数据包时间戳不准确,错过收取数据的时机导致丢包等问题。取而代之采用了一种中断驱动的方法:用户进程察看自己的缓冲区内有没有新数据的到来,如没有则把自己挂到等待队列开始睡眠;中断来时,中断处理函数收取数据包并发信号唤醒睡眠进程做读操作。


3.2.2 中断处理过程
  中断的处理流程如图4所示。中断来时,中断处理函数首先根据内核传入的私有结构dev_id[5]判断到底是哪个设备产生中断,然后检查相应设备的中断状态寄存器,根据寄存器判断中断发生的不同原因决定是否进行DMA操作。DMA操作会在无需操作系统干预的情况下把数据块从硬件外部高速存储器搬到内核公共缓冲区。公共缓冲区数据包自定义包头经过解析后得到cookie值,它对应着前文所述的规则索引。驱动程序会根据规则索引把数据从公共缓冲区分发到相应进程的用户缓冲区并唤醒等待队列上的进程做读取包和深度解析的工作。
  在中断处理过程中对于非抢占的Linux内核涉及系统同步的问题。为保护共享数据可能被非同步操作,整个中断处理过程通过关中断的方式来保护。但对于拥有对称多处理器(SMP)或加入抢占机制的系统,需要做一些额外的处理:为了不影响其他处理器上的中断处理,避免使用全局关中断函数,只禁用当前处理器的中断,并利用不会睡眠的锁如自旋锁对所有可能引发同步问题的临界区进行保护。在多设备的环境下,系统中的每个设备DMA操作前都必须拥有自己的锁;为了避免数据混乱,每个设备都拥有各自的公共缓冲区,而且从各自的公共缓冲区向用户缓冲区写数据前必须获得一个全局锁,从而实现写操作的串行化。


4 性能测试
  实验使用SmartBits测试仪模拟真实的网络环境对本系统进行了测试。测试硬件平台为Intel P4 2.4GHz的处理器,1GB内存,64位PCI总线;软件平台为Fedra core3。测试结果" title="测试结果">测试结果显示传统的Libpcap在400Mbps左右就已经出现严重的丢包现象,而且受包长影响很大。而本系统在单设备双输入的情况下,当包速率超过1 800Mbps才出现丢包现象,并基本不受包长变化影响。另外测试结果表明本系统在Linux操作系统平台下有较低的系统占用,如图5所示本系统在不同包长的情况下处理器占用率均比Intel 光网卡 PRO/1000F要低得多。
  本文在参考传统网络数据包捕获方法的同时,针对传统方法的一些弱点,提出一种软硬件结合的包捕获方案。该方案由硬件完成数据包过滤的任务,并对软件部分作了优化,测试结果表明,该方案能满足大多数高速网络数据包捕获任务的需要,具有广泛的应用前景。

参考文献
1 White G B,Pooch U W.Cooperating security managers:Distributed intrusion detection systems.Computers & Security,1996;15(5):441~450
2 唐正军,刘代志.网络嗅探器Sniffer软件源代码浅3:采用Labpcap库的通用设计.计算机工程,2002;28(2)
3 Jacobson V,Leres C,McCanne S.The tcpdump manual page. Lawrence Berkeley Laboratory,Berkeley,CA,1997
4 Kurmann C,Rauch F,Stricker T.Speculative defragmentation-leading gigabit ethernet to true Zero-Copy communication. Cluster Computing,2001;4(1):7~18
5 Rubini A,Corbet J著,魏永明,骆 刚,姜 君译.Linux设备驱动程序(第二版).北京:中国电力出版社,2004:275~276

本站内容除特别声明的原创文章之外,转载内容只为传递更多信息,并不代表本网站赞同其观点。转载的所有的文章、图片、音/视频文件等资料的版权归版权所有权人所有。本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如涉及作品内容、版权和其它问题,请及时通过电子邮件或电话通知我们,以便迅速采取适当措施,避免给双方造成不必要的经济损失。联系电话:010-82306118;邮箱:aet@chinaaet.com。