Packet32学习笔记

来源:互联网 发布:淘宝400客服电话是多少 编辑:程序博客网 时间:2024/04/30 14:08

一个网络抓包程序,在使用时需要包括packet32.h。利用Packet API函数直接操作网卡进行抓包、发包。非常实用。

首先了解几个基本的数据结构:

数据结构:_ADAPTER(关于Network Adapter的)

typedef struct _ADAPTER

{

HANDLE hFile;                      // 一个打开的NPF driver实例的句柄

CHARSymbolicLink[MAX_LINK_NAME_LENGTH];   // 当前打开的网卡的名字

int NumWrites;                 // 在这块Adapter上,一个数据包被写的次数:

HANDLE ReadEvent;           /* 这块Adapter上的read操作的通知事件。它可以被传递给标准Win32函数(如WaitForSingleObject或者WaitForMultipleObjects) ,这 样可以等待到                                                    driver的缓冲区内有数据到来。在同时等待几个事件的GUI程序中,它特别有用。在Windows2000/XP中, 函数PacketSetMinToCopy()可以用来                                                       设置内核缓冲区中激发本事件的最小数据大小:*/

UINT ReadTimeOut; // 设置一个时间,到时候,即使没有捕获任何包,read操作也会被释放,ReadEvent也会被触发:

} ADAPTER, *LPADAPTER;


数据结构:_PACKET(关于Packet的)

 typedef struct _PACKET

{

 HANDLE hEvent;   // 向后兼容用的:

 OVERLAPPED OverLapped;// 向后兼容用的:

 PVOIDBuffer;          // 存放Packets的缓冲区

 UINT Length;           //缓冲区的大小

 DWORD ulBytesReceived; // 当前缓冲区中有效的字节数,如,上一次调用PacketReceivePacket()函数接收到的字节数

 BOOLEAN bIoComplete;    //向后兼容用的

} PACKET, *LPPACKET;


数据结构:_PACKET_OID_DATA (关于OID请求的) ------------------OID:即对象标识符,是为了找到区分整体中的对象而添加的标记

typedef struct_PACKET_OID_DATA

ULONGOid;         // OID的code,有效的OIDcode的定义参见ntddndis.h;比如:OID_GEN_SUPPORTED_LIST,OID_GEN_VENDOR_DESCRIPTION等

ULONGLength;      // 成员Data的长度

UCHARData[1];    // 存放发送给网卡或者从网卡接收的数据的缓冲区

} ;

typedef struct_PACKET_OID_DATA PACKET_OID_DATA,*PPACKET_OID_DATA;

 

其他数据结构:

npf_if_addr(网卡的地址):

typedef structnpf_if_addr

{

struct sockaddrIPAddress; // IP address.

struct sockaddrSubnetMask; // Netmask forthat address

struct sockaddrBroadcast; // Broadcastaddress.

}npf_if_addr

 

bpf_hdr(PacketHeader):

struct bpf_hdr 

{

struct timevalbh_tstamp; // 捕获到的packet的timestamp

UINTbh_caplen;         // 捕获到的packet的长度

UINTbh_datalen;        // 原始packet的长度

 USHORTbh_hdrlen;        // bpf header的长度(this struct plus alignment padding)

};


bpf_insn(一个简单的BPF伪指令):

 bpf_insn中包含了一个BPF注册机的简单指令,它被用来发送一个filter程序给driver。

struct bpf_insn 

{

USHORTcode;   // 指令的类型和寻址模式

 UCHARjt;      // Jump if true

UCHARjf;      // Jump if false

intk;         // 通用的一个字段,有多种目的

};


bpf_program(一个BPF伪汇编程序):

这段程序将被PacketSetBPF()注射入内核,并被应用到每一个进来的Packet。

struct bpf_program 

{

UINTbf_len;              //程序指令数目,如,后面的bpf_insn结构的数目

struct bpf_insn*bf_insns;    // 指向第一个bpf_insn结构的指针

};

 

bpf_stat(本次捕获的统计数据):

这个结构将被Packet.dll用来返回捕获过程中的统计数据。 

struct bpf_stat 

{

UINTbs_recv;   // 从开始捕获起,这个driver从网卡上接收的Packet的数量(包括driver丢失的Packet)

UINTbs_drop;    //从开始捕获起,这个driver丢失的Packet的数量,一般地,包丢失,是因为driver的缓冲区满了,这时driver将扔掉这个包

UINTps_ifdrop;  // 通过filter的包的数量

UINT bs_capt;

}; 


dump_bpf_hdr(DumpPacketHeader转储文件包的头):

 struct dump_bpf_hdr

{

struct timevalts; // Packet的timestamp

UINTcaplen;       // 捕获到的packet的长度

UINTlen;          // 原始Packet的长度

};

 

NetType(网络类型):

 NetType用于PacketGetNetType(),返回当前网卡的类型和速度。

struct NetType

{

UINTLinkType;    //当前网卡的MAC

UINTLinkSpeed;   // 网络的速度(bits/s)

};

通过调用Packet32中的库函数,可直接对网卡进行操作,基本的步骤如图一示:


                                                                                                  图一   网卡操作基本步骤

除了上述函数外,Packet32中还有些其他辅助函数,只列出了部分,例如:

1.PCHAR PacketGetVersion(); //返回关于dll的版本信息

2.BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes);//<设置内核缓冲区中激发本事件的最小数据大小

3.BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s);//得到本次捕获的统计数据,包括从开始捕获起,从该网卡上接收到的包数,丢失的包数

4.BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type);//(网络类型)返回当前网卡的类型和速度

5.BOOLEAN PacketGetNetInfoEx(PCHARAdapterName, npf_if_addr* buffer, PLONG NEntries);//返回某个网络适配器的全面地址信息

6.BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEANSet,PPACKET_OID_DATA  OidData);//调用PacketRequest向网卡发送OID请求

0 0
原创粉丝点击