admin管理员组

文章数量:1531667

2024年4月3日发(作者:)

Windows下截获网络数据

——winpcap源代码分析

王守彦

1 简介

在本刊的前期中,介绍用于截获网络数据的通用库libpcap的高层实现,及在linux/unix

下底层实现。Winpcap是libpcap的windows版本,它们虽然提供了同样的高层接口,但底

层实现却截然不同。对于linux/unix,网络数据的截获作为系统的一项基本功能,大多直接

实现于内核中,用户只要调用简单的接口函数,就能截获通过网络适配器的数据,windows

系统本身不提供截获网络数据的接口,但提供一套和网络适配器交互的网络驱动器接口规范

(NDIS),可以通过NDIS实现网络数据的截获。本文作为前文的补充,详细分析winpcap

的结构和如何通过NDIS实现网络数据的截获和过滤。本文分为三个部分:winpcap结构、

NDIS概述和winpcap包截获驱动器源代码分析。

2 Winpcap结构

图1 winpcap结构

图1描述了winpcap的结构,其中是一个使用winpcap的外部程序,winpcap

包括libpcap通用接口、动态链接库和NDIS包截获驱动器三个部分。NDIS包截获

驱动器用于从网络适配器(Network Adapter)截获数据,并提供一套标准的接口函数,如read,

write,ioctl等;提供对NDIS包截获驱动器接口函数的封装,对上层(libpcap)提

供更为方便的接口;libpcap调用中的函数,提供和linux/unix平台上libpcap相同

的接口,实现代码的通用性。

实际上在windows编程中使用提供的接口函数和使用libpcap函数一样方便,

它们都是对其它函数的封装,本文不做分析,而是着重分析NDIS包截获驱动器的实现。

3 NDIS概述

包截获驱动器通过NDIS(网络驱动器接口规范)与网络适配器交互,NDIS是win32网

络代码的一部分。NDIS管理各种网络适配器,并负责适配器与上层协议的通信。NDIS可

以实现这几种驱动器形式:小端口驱动器、中间驱动器和协议驱动器。Winpcap的包截获驱

动器实际上是一个协议驱动器。

NDIS协议驱动器可以分配,拷贝来自发送应用程序申请发送的数据包,也可以提供一

个协议接口来接受来自下级驱动程序的包,并转移接受到的数据给适当的客户端应用程序。

这正好是包截获驱动器要实现的功能。

4 包截获驱动器源代码分析

winpcap提供win98和winNT/2000的驱动,它们使用的都是统一的NDIS接口,只是提

供的接口函数不同,这里以winNT/2000代码为例。( .winpcappacketntxdriver )

4.1 入口函数DriverEntry()(packet.c)

DriverEntry()函数在这个驱动程序被加载启动时调用,是整个驱动程序的入口,其主要

功能是初始化并注册一个无连接协议驱动器,为每个网络适配器创建相应的设备用于截获通

过的数据。首先通过NdisRegisterProtocol()注册一个协议驱动器,这里最重要的参数就是

ProtocolChar,这个结构中存放这个协议驱动器的版本、名字等,更重要的是它存放了这个协

议驱动器的各种处理函数:

apterCompleteHandler = NPF_OpenAdapterComplete;

dapterCompleteHandler = NPF_CloseAdapterComplete;

mpleteHandler = NPF_SendComplete;

erDataCompleteHandler = NPF_TransferDataComplete;

ompleteHandler = NPF_ResetComplete;

tCompleteHandler = NPF_RequestComplete;

eHandler = NPF_tap;

eCompleteHandler = NPF_ReceiveComplete;

Handler = NPF_Status;

CompleteHandler = NPF_StatusComplete;

#ifdef NDIS50

apterHandler = NPF_BindAdapter;

AdapterHandler = NPF_UnbindAdapter;

ntHandler = NPF_PowerChange;

ePacketHandler = NULL;

这些处理函数只能被系统调用,即在网络设备或用户有某种动作后,这些函数会被自动调用,

以下是这些函数的用途:

BindAdapterHandler:这是一个必须的函数,NDIS调用这个函数来请求这个协议驱动 

程序绑定到一个由传过来的名字参数指向的下层NIC或虚拟NIC的句柄。 

UnbindAdapterHandler:这是一个必须的函数,ProtocolUnbindAdapter由NDIS关闭

一个由传过来的名字参数指向的下层NIC或虚拟NIC句柄的绑定时调用。ProtocolUnbind 

Adapter调用NdisCloseAdapter并在绑定安全关闭后释放分配的资源。 

本文标签: 驱动器截获数据