监听以太网
(
一
) Packet32
包说明
Article last modified on 2002-9-17
|
The information in this article applies to:
--Microsoft Windwos NTx
---
Microsoft Windwos 9x
--WinPcap: the Free Packet Capture Architecture for Windows
|
简述
:
监听网络上
的所有数据,是一个比较有趣的题目。流传比较广的一些监听程序,它们都使用了一个更加著名的开发包
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
包的内容
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
本文档所包含的信息代表了在发布之日,
ZhengYun
对所讨论问题的当前看法,
Zhengyun
不保证所给信息在发布之日以后的准确性。
本文档仅供参考。对本文档中的信息,
Zhengyun
不做任何明示或默示的保证。
参考文献:
1. 如何编写网络监视器 作者:邹建平
2. 《 Windows NT 下开发网络监控程序 》 作者: 北京锐信科学技术培训中心
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=12690