Windows NT下开发网络监控程序
信息工程大学信息安全学院 许士博 颜学雄 王清贤
本文简单地介绍了Windows系统中的NDIS及应用程序与它的交互,重点介绍怎样利用一个辅助的开发包(Packet32)直接对网卡进行操作及对接收到的数据进行分析。
维护网络安全的一项重要技术就是网络的实时监控,它要对网络上的所有数据进行检查,而现在的大部分操作系统是不允许用户这样做的,但是我们可以自己开发或者利用现有的底层网络驱动程序来实现。目前Unix环境下网络监控程序的开发包有很多,而Windows环境下的开发包很少,因为Windows的封装性特别强,开发困难大。
一、Windows系统中的网络通信结构
1.Windows系统中的网络通信结构
图1的上层应用程序包括IE、Outlook等各种基于网络的软件,网络驱动协议包括TCP/IP、NETBEUI等各种Windows支持的网络层、传输层协议,NDIS是Windows操作系统网络功能驱动的关键部分,下面对NDIS进行介绍。
2.NDIS及其特点
NDIS(Network Driver Interface Specification)是Microsoft和 3Com公司联合制定的网络驱动规范,并提供了大量的操作函数。它为上层的协议驱动提供服务,屏蔽了下层各种网卡的差别。
NDIS向上支持多种网络协议,比如TCP/IP、NWLink IPX/SPX、NETBEUI等,向下支持不同厂家生产的多种网卡。NDIS还支持多种工作模式,支持多处理器,提供一个完备的NDIS库(Library)。 但库中所提供的各个函数都是工作在核心模式下的,用户不宜直接操作,这就需要寻找另外的接口。
二、一个非常有用的开发包
澳大利亚的Canberra大学信息科学与工程系1997年在 Windows NT环境下研制了一个网络开发包Packet32,应用程序通过它可以设置网卡的工作模式,直接在网卡上读写数据。
1.Packet32的原理
如图2所示,Packet32为用户提供了一个面向低层的网络编程接口。
2.网卡的工作模式
广播模式:目的物理地址是0xFFFFFF的帧为广播帧,工作在广播模式的网卡接收广播帧。
多播传送(组内广播):D类IP地址是用于组内广播的,也就是一个人发出的包可以同时被其他多个有资格的人接收,这个人和那些有资格的人就形成了一个组,他们在组内的通信是广播式的。与此相对应,在物理层也存在着组内广播(或多播传送),以多播传送地址作为目的物理地址的帧可以被组内的其他主机同时接收,而组外主机却接收不到。但是,如果将网卡设置为多播传送模式,它可以接收所有的多播传送帧,而不论它是不是组内成员。
直接模式:工作在直接模式下的网卡只接收目的地址是自己的地址的帧。
混杂模式:工作在混杂模式下的网卡接受所有的流过网卡的帧,监控程序就是在这种模式下运行的。
网卡的缺省工作模式包含广播模式和直接模式,即它只接收广播帧和发给自己的帧。利用Packet32包可以将网卡设置为以上的任意模式。
3.Packet32包的内容
Packet驱动:Oemsetup.inf安装信息文件、Packet.sys系统文件,在利用Packet32包开发网络监控程序前,需要用这两个文件安装Packet驱动。
Packet32程序开发库:Packet32.lib静态链接库、 Packet32.dll动态链接库,用户可以通过调用库中的函数直接对网卡进行操作。
4.Packet32包的使用
两个数据结构:
网卡结构: typedef struct _ADAPTER {
HANDLE hFile;
TCHAR SymbolicLink[MAX_LINK_NAME_LENGTH];
} ADAPTER, *LPADAPTER;
数据包结构: typedef struct _PACKET {
HANDLE hEvent;
OVERLAPPED OverLapped;
PVOID Buffer;
UINT Length;
} PACKET, *LPPACKET;
主要的函数:
PVOID PacketOpenAdapter(LPTSTR AdapterName),网卡的打开函数,AdapterName是要打开的网卡的名字,返回该网卡的结构指针。
BOOLEAN PacketSendPacket(LPADAPTER lpAdapter,LPPACKET lpPacket,
BOOLEAN Sync),数据包发送函数,lpAdapter是已经打开的网卡的结构指针,lpPacket是要发送的数据包的结构指针,Sync是同步、异步标志,TRUE为同步,FALSE为异步。
PVOID PacketAllocatePacket(VOID),数据包申请函数。
VOID PacketInitPacket(LPPACKET lpPacket,
PVOID Buffer,
UINT Length),数据包初始化函数,lpPacket是数据包结构指针,Buffer是存放数据的缓冲区,Length是缓冲区的大小。
VOID PacketFreePacket(LPPACKET lpPacket),数据包释放函数。
ULONG PacketGetAddress(LPADAPTER lpAdapter,PUCHAR AddressBuffer),获取网卡的物理地址,该函数将网卡lpAdapter的物理地址放入缓冲区 AddressBuffer,返回值是地址的长度。
BOOLEAN PacketReceivePacket
(LPADAPTER lpAdapter,
LPPACKET lpPacket,
BOOLEAN Sync,
PULONG BytesReceived),数据包接收函数,该函数从网卡lpAdapter接收数据包,并将数据包放入lpPacket,Sync是同步、异步标志, BytesReceived是实际接收到的字节数,若接收成功返回TRUE,否则返回FALSE。
VOID PacketCloseAdapter(LPADAPTER lpAdapter),关闭网卡lpAdapter。
BOOLEAN PacketSetFilter(LPADAPTER lpAdapter,
ULONG Filter),设置网卡的工作模式,该函数将网卡设置成为指定的Filter模式,成功返回TRUE,失败返回FALSE。
ULONG PacketGetAdapterNames(PTSTR pStr,
PULONG BufferSize),获得网卡的名字,该函数从注册表获取网卡的名字,并将它放入pStr,BufferSize为名字的长度。
三、 一个简单实例
下面这段程序在VC++环境下编译、运行通过,它将网卡设为混杂模式并接收一个帧。
#define NDIS_PACKET_TYPE_DIRECTED
0x0001 //直接模式。
#define NDIS_PACKET_TYPE_MULTICAST
0x0002 //多播传送模式。
#define NDIS_PACKET_TYPE_BROADCAST
0x0008 //广播模式。
#define NDIS_PACKET_TYPE_PROMISCUOUS
0x0020 //混杂模式。
LPADAPTER lpAdapter;
LPPACKET lpPacket;
ULONG Filter = 0;
TCHAR NameBuf[256];
UCHAR buf[1514];
ULONG Length;
ULONG NameLength = 256;
UCHAR Address[6];
PacketGetAdapterNames(NameBuf, &NameLength);
lpAdapter = PacketOpenAdapter(NameBuf);
Filter = NDIS_PACKET_TYPE_PROMISCUOUS;
//混杂模式。
PacketSetFilter(lpAdapter, Filter);
PacketGetAddress(lpAdapter, Address);
lpPacket = PacketAllocatePacket();
PacketInitPacket(lpPacket, buf, 1514);
PacketReceivePacket(lpAdapter, lpPacket,
TRUE, &Length);
PacketFreePacket(lpPacket);
PacketCloseAdapter(lpAdapter);
四、 数据分析
Internet的一个主要应用方式是通过浏览器获取信息,它所用的Http协议是基于TCP/IP协议的,现在我们以监控Http的连接请求为例,介绍一下数据的分析过程。
首先要提取出IP包,利用Packet32包接收到的是物理帧的内容,格式如下:
帧格式字段的值标明帧数据的类型,若是08 00(16进制),说明是IP数据包;若是08 06(16进制),说明是ARP数据包;若是80 35(16 进制),说明是RARP数据包,等等。通过判断帧格式字段的值可以提取出IP数据包,此时帧数据区的内容格式为:
其中,协议字段的值标明了IP数据区的内容类型,若为 6说明为TCP包,若为17 说明为UDP包,若为1说明为ICMP包,若为2 说明为IGMP 包,等等。Http数据是通过TCP进行传输的,通过判断IP报头中协议字段的值可以提取出TCP包,它的格式为:
因为Http服务的端口号是80,所以通过检查TCP报头中的端口号就可以知道是不是Http数据,若目的端口号为80,则说明是Http连接请求包,我们就可以采取一些相应的措施。
五、 结束语
因为Internet上流动的是海量数据,而且数据的流量是随机的,所以肯定存在丢包的情况,这是无法避免的。但我们可以采取一些改善措施,使丢包率尽可能小。有两种方法:一是选用合适的缓冲区管理方法,并且接收过程和处理过程并行进行;二是在多个机器上同时进行监控。