2.4.2 数据包捕获的基本过程

网络上的数据包通过物理网络接口卡(Network Interface Card,NIC)与对应设备驱动程序传递到操作系统的内核空间,对应的协议驱动程序(对WinPcap而言就是NPF内核驱动)将会处理所接收的数据包,然后相应的应用程序获得该数据包,做进一步的应用处理,比如解析数据包内容并显示出来等。

数据包从NIC到应用程序的传输路径如图2-2所示。

2.4.2 数据包捕获的基本过程 - 图1

图 2-2 数据包从NIC到应用程序的传输路径

下面详细描述从网络上捕获一个数据包,然后传递给应用程序的过程。

1.网卡与NIC设备驱动

现代网络接口卡板载内存的大小通常限制为几千字节。在不依赖主机工作能力的情况下,这些内存在全连接速度(full link speed)下需要满足数据包的接收与发送需求。此外,当数据包被存储于板载内存中时,NIC就会执行一些初步的检查,诸如检查CRC错误、过短的以太网数据包,因此,无效的数据包可以立即被丢弃。

一个有效的数据包被NIC接收后,将对总线控制器产生一个总线数据传输请求。此时,NIC控制了总线,传输数据包到主机主内存的NIC缓冲区中(见图2-2),接着释放总线,产生一个硬件中断给高级可编程中断控制器(Advanced Programmable Interrupt Controller,APIC)芯片。该芯片会唤醒操作系统的中断处理例程(OS interrupt handling routine),触发NIC设备驱动程序的中断服务程序(ISR)。

在一个写得很好的设备驱动程序中,其ISR只做很少的工作。ISR所做工作中,最基本的是检查该中断是否是它自己要处理的(在x86机器中一个中断可被多个设备共享),并做出应答。接着,ISR调度一个较低优先级的函数,这一过程称为延迟过程调用(Deferred Procedure Call,DPC),该函数稍后处理硬件请求并告知上层驱动程序(如协议层的驱动程序、数据包捕获驱动程序),一个数据包已被接收。当没有中断被挂起时,CPU将处理DPC例程,而当NIC设备驱动程序正在执行处理时,来自NIC的中断会被禁用,因为在处理下一个服务前,上一个数据包的处理必须完成。此外,因为中断的产生是一个耗费很大的操作,现在的NIC会允许多个数据包被送入一个中断的上下文中,因此上层驱动程序每次激活时要能够处理多个数据包。

2.数据包捕获驱动

数据包捕获组件主要完成数据包的过滤操作,并把合适的数据包存储在内核缓冲区中,以便用户层的应用程序获取所需的数据包,同时还提供内核空间与用户空间进行交互的系统接口的具体实现。通常,数据包捕获组件对其他的软件模块(如协议栈)是透明的,并不会给标准的系统行为带来影响。数据包捕获组件仅是在系统中插入一个“钩子”——通常使用一个回调函数实现——只要有新的数据包从网络上到来,其就会被告知。

在WinPcap中,数据包捕获组件作为一个网络协议驱动程序被实现,即NPF。对应的回调函数为NPF_tap,该函数执行的第一步就是对所接收的数据包执行过滤操作,接着把符合过滤条件的数据包放置到一个内核环形缓冲区中,等待应用程序读取。

3.应用程序读取数据包

用户空间的应用程序使用wpcap.dll库(wpcap.dll库的功能由Packet.dll库支持)提供的接口函数可方便地从内核驱动处读取数据包,从而完成所需的功能。