现在的位置: 首页 > 综合 > 正文

监听以太网(一) Packet32包说明

2013年10月05日 ⁄ 综合 ⁄ 共 2540字 ⁄ 字号 评论关闭
简述

  监听网络上的所有数据,是一个比较有趣的题目。流传比较广的一些监听程序,它们都使用了一个更加著名的开发包Packet32。比如,ntsniff、EthernetSpy、ntpacket等,还有赫赫有名的WinPcap。应用程序通过它可以设置网卡的工作模式,直接在网卡上读写数据,等等。

一般使用的Packet32的实现版本,是微软的Packet32.c和Packet32.h。这个版本写得比较简单。

  WinPcap开发包中自带的Packet32,是Politecnico di Torino重写的,增加了许多错误处理,而且注释翔实,值得一读。

  在 http://winpcap.polito.it/default.htm 中,WinPcap开发包被描述为:

WinPcap is an architecture for packet capture and network analysis for the Win32 platforms. It includes a kernel-level packet filter, a low-level dynamic link library (packet.dll), and a high-level and system-independent library (wpcap.dll, based on libpcap version 0.6.2).

下面就给出Packet32这个实现版本的说明,仿照Microsft SDK的风格。内容依次为:

Packet32包的内容
Packet32包中的函数
PacketGetAdapterNames
PacketOpenAdapter等
Packet32包中的数据结构

例子1:用Packet32设置网卡为混杂模式,监听所有的数据包。
Packet32包的内容

  Packet驱动:Oemsetup.inf安装信息文件、Packet.sys系统文件,在利用Packet32包开发网络监控程序前,需要用这两个文件安装Packet驱动。Packet32程序开发库:Packet32.lib静态链接库、 Packet32.dll动态链接库,用户可以通过调用库中的函数直接对网卡进行操作。

Packet32包中的函数说明:

No.1. PacketGetAdapterNames(从注册表中读取网卡名)

得到现有的网络适配器的列表和它们的描述。

BOOLEAN PacketGetAdapterNames(
PTSTR pStr,
PULONG BufferSize
);

Parameters:
pStr:
[in , out] 一块用户负责分配的缓冲区,将把适配器的名字填充进去。

BufferSize:
[in] pStr这块缓冲区的大小。

Return Values: 如果查询成功,返回一个非零值。

Usage:
[C/C++]
C/C++ Usage Sample
char AdapterNamea[8192];
ULONG AdapterLength;
PacketGetAdapterNames(AdapterName,&AdapterLength);

Remarks:
  通常,这都是与网卡通信时要调用的第一个函数。它返回系统上安装了的网卡的名字。在每个网卡的名字后面,pStr中还有一个与之相应的描述。
  由于结果都是通过查询注册表得到的,所以WindowsNTx和Windows9X/Me下得到的字符串编码是不同的。Windows9X下用ASCII编码存储,而WindowsNTx则是Unicode。

  如果是在Windows9X下,调用完PacketGetAdapterNames后,得到的pStr将是这样的:

一串用"/0"分隔的ASCII字符串,每一个都是一个网卡的名字;
两个"/0";
一串用"/0"分隔的ASCII字符串,每一个都是一个网卡的描述;顺序是和网卡名字一样的;
两个"/0";
  如果是在WindowsNTx下,调用完PacketGetAdapterNames后,得到的pStr将是这样的:

一串用一个Unicode的"/0"分隔的Unicode字符串,每一个都是一个网卡的名字;
两个Unicode的"/0";
一串用ASCII的"/0"分隔的ASCII字符串,每一个都是一个网卡的描述;顺序是和网卡名字一样的;
两个ASCII的"/0";
这个函数的操作大致为:

网卡的注册表项是:

HKEY_LOCAL_MACHINE/
  SYSTEM/
   CurrentControlSet/
    Control/
     Class/
      {4D36E972-E325-11CE-BFC1-08002BE10318}

先打开这个键值;
再枚举下面的每一项,依次读取参数:
对子项/Linkage/UpperBind参数,核对是否等于” NdisWan”,如果不是,就跳过去;
如果是” NdisWan”,则读取子项/Linkage/Export,这就是网卡的名字。

如果前面的查询有网卡记录,那么执行下面这个循环:
将调用PacketOpenAdapter打开每个网卡;
其中将调用PacketRequest(adapter,FALSE,OidData)来得到网卡的描述;
具体方法是这样,OidData是一个PACKET_OID_DATA结构,我们事先设置它的Oid成员为OID_GEN_VENDOR_DESCRIPTION,然后调用PacketRequest把这个OID发送给网卡driver,就可以从OidData->Data中拿到网卡的描述了。
最后调用PacketCloseAdapter关闭适配器。

如果前面没有查询到网卡记录,那么执行我们将根据TCP/IP Binding来查找网卡:
先打开这个键值; HKEY_LOCAL_MACHINE/
  SYSTEM/
   CurrentControlSet/
    Services/
     Tcpip/
      Linkage

  它的Bind参数设置的就是现在系统上绑定的网卡的名字。得到名字之后,同上调用PacketOpenAdapter和PacketRequest方法向网卡查询它的描述。 (To be continued)
Writen by zhengyun@tomosoft.com 

 

抱歉!评论已关闭.