阅读:1855回复:4
关于NdisGetNextBuffer一问
在调用完NdisSend之后打印包中的信息。源程序如下:
/*++ 将缓存中的数据拷贝到pPacketContent中进行分析。 --*/ begin of code VOID PrintPacket( IN PNDIS_PACKET packet ) { UINT PhysicalBufferCount; UINT BufferCount; PNDIS_BUFFER FirstBuffer; UINT TotalPacketLength; PUCHAR pPacketContent;//存放包的内容 NDIS_STATUS status; PUCHAR BuffVA; UINT BuffLen; //每个缓存的大小 UINT OffsetSize;//缓存总的大小 UINT count;//查询缓存的次数 count = 0; OffsetSize = 0; BuffLen = 0; // //调用NDIS函数得到封包信息 // NdisQueryPacket(packet , &PhysicalBufferCount , &BufferCount , &FirstBuffer , &TotalPacketLength ); // //输出封包信息 // DbgPrint(" PacketPointer: %u.\n", (VOID*)packet); DbgPrint(" PhysicalBufferCount: %u.\n", PhysicalBufferCount); DbgPrint(" BufferCount: %u.\n", BufferCount); DbgPrint(" FirstBufferPointer: %u.\n", FirstBuffer); DbgPrint(" TotalPacketLenth: %u.\n", TotalPacketLength); DbgPrint("8 Begin allocate memory for analyse..."); status = NdisAllocateMemoryWithTag(&pPacketContent, BUFFER_SIZE, TAG); if(status == NDIS_STATUS_FAILURE ) { DbgPrint("Error: there is no enough space for allocate\n"); } else { DbgPrint("Allocate Success!\n"); DbgPrint(" Pointer of pPacketContent: %u\n", pPacketContent); while( (FirstBuffer!=(PNDIS_BUFFER)NULL) && (count<4) ) {//为了避免出现无限循环而限制循环次数最多4次 count++; DbgPrint("The %d th of buffer...", count); NdisQueryBuffer(FirstBuffer, &BuffVA, &BuffLen); NdisMoveMemory(pPacketContent, BuffVA, BuffLen); DbgPrint(" BufferLen is: %d\n", BuffLen); OffsetSize += BuffLen; DbgPrint(" OffsetSize is: %d\n", OffsetSize); NdisGetNextBuffer(FirstBuffer, &FirstBuffer); if( FirstBuffer != (PNDIS_BUFFER)NULL ) { DbgPrint(" FirstBuffer != (PNDIS_BUFFER)NULL) "); DbgPrint(" Pointer of FirstBuffer: %u\n", FirstBuffer); } else { DbgPrint(" FirstBuffer == (PNDIS_BUFFER)NULL) "); DbgPrint(" Pointer of FirstBuffer: %u\n", FirstBuffer); } } NdisFreeMemory(pPacketContent, BUFFER_SIZE, 0); } DbgPrint(" End of allocate memory for analyse..."); DbgPrint("End of analyse the packet"); } //---end of code 先询问一下,上面的代码可以获得数据包的内容吧? 我不明白的地方是: 1、是否存在如下关系: BufferCount == PhysicalBufferCount TotalPacketLenth == OffsetSize count == BufferCount 2、在之前的调试中,我没有添加限制循环次数count,结果出现蓝屏:(。添加之后发现,上面三个等式有时候都成立,有时候只有第一个等式成立。请问这是怎么回事? 3、正确的情况应该如何? |
|
最新喜欢:![]() |
沙发#
发布于:2004-08-19 14:12
你可以查DDK中NdisQueryPacket函数的帮助和ndis.h中关于Packet(_NDISPACKET)的结构。说的比较清楚
|
|
板凳#
发布于:2004-08-19 21:51
还是自己回答。
根据http://www.driverdevelop.com/forum/html_67763.html?1092922483这篇帖子中给出的例子:2004-05-12_FireWall.rar。 1、将xpassthru源程序中miniport和protocol中注册的函数都换成FireWall中的函数。 2、将xpassthru中PtReceive和PtTransferDataComplete函数中Check_Packet((char*)pPacketContent)函数替换成DisplayPacketInfo((char*)pPacketContent);其源代码如下: //------------------------------------ // begin of code void DisplayPacketInfo( char *pPacketContent ) { P_IP_PACKET p_ip; p_ip = (P_IP_PACKET)pPacketContent; // 显示包的内容 if( p_ip == NULL ) { DbgPrint("Error: p_ip is NULL"); } else { DbgPrint("目的地址: %x-%x-%x-%x-%x-%x", p_ip->targ_hw_addr[0], p_ip->targ_hw_addr[1], p_ip->targ_hw_addr[2], p_ip->targ_hw_addr[3], p_ip->targ_hw_addr[4], p_ip->targ_hw_addr[5]); DbgPrint("源地址: %x-%x-%x-%x-%x-%x", p_ip->src_hw_addr[0], p_ip->src_hw_addr[1], p_ip->src_hw_addr[2], p_ip->src_hw_addr[3], p_ip->src_hw_addr[4], p_ip->src_hw_addr[5]); DbgPrint("H_frame_type: %x", p_ip->H_frame_type); DbgPrint("L_frame_type: %x", p_ip->L_frame_type); if( (p_ip->H_frame_type == 0x8) && (p_ip->L_frame_type == 0x0) ) { DbgPrint("This is an IP packet"); DbgPrint("4位首部长度,4位IP版本号: %x", p_ip->h_verlen); DbgPrint("8位服务类型TOS(优先级): %x", p_ip->tos); DbgPrint("16位总长度(字节): %d", p_ip->total_len); DbgPrint("16位标识: %d", p_ip->ident); DbgPrint("3位标志位和13位偏移: %x", p_ip->frag_and_flags); DbgPrint("8位生存时间 TTL: %d", p_ip->ttl); DbgPrint("8位协议 (1->ICMP, 2->IGMP, 6->TCP, 17->UDP): %d", p_ip->proto); DbgPrint("16位IP首部校验和: %d", p_ip->checksum); DbgPrint("32位源IP地址: %d:%d:%d:%d", p_ip->sourceIP[0], p_ip->sourceIP[1], p_ip->sourceIP[2], p_ip->sourceIP[3]); DbgPrint("32位目的IP地址: %d:%d:%d:%d", p_ip->destIP[0], p_ip->destIP[1], p_ip->destIP[2], p_ip->destIP[3]); } else if( (p_ip->H_frame_type == 0x8) && (p_ip->L_frame_type == 0x6) ) { DbgPrint("This is an ARP packet"); } } } //end of code 3、在使用FireWall例子的时候需要注意一点。在mydef.h文件中有一个错误:在定义IP_PACKET结构时,其源地址和目的地址采用int型,这会导致错误。采用这种定义方式,在32位机器上(可能在不同机器上就是正确的),IP_PACKET的大小为36字节,而正确的应该是34字节。 typedef struct _IP_PACKET { // Ethernet unsigned char targ_hw_addr[6]; // 目的地址,6字节。 unsigned char src_hw_addr[6]; // 源地址,6字节。 unsigned char H_frame_type; // 下一层协议的类型 unsigned char L_frame_type; // IP unsigned char h_verlen; //4位首部长度,4位IP版本号 unsigned char tos; //8位服务类型TOS unsigned short total_len; //16位总长度(字节) unsigned short ident; //16位标识 unsigned short frag_and_flags; //3位标志位和13位偏移 unsigned char ttl; //8位生存时间 TTL unsigned char proto;//8位协议(1->ICMP,2->IGMP,6->TCP,17->UDP) unsigned short checksum; //16位IP首部校验和 unsigned char sourceIP[4]; //32位源IP地址 unsigned char destIP[4]; //32位目的IP地址 /* 下面这种定义方法是错误的,如果这样定义,则IP_PACKET的大小为36字节。其原因我理解的是:当定义到checksum的时候,已经分配了26个字节,由于内存分片都是以四字节(32bit)来划分,所以当分配一个int型时必须是独立(或者说完整)的一个内存分片。因此,必须在26字节之后留出两字节用来填充。所以整体就多出两字节。通过查看sizeof(IP_PACKET)可以看到其大小为36字节。 改用我这种方法之后,就是正确的34字节。 */ //unsigned int sourceIP; //32位源IP地址 //unsigned int destIP; //32位目的IP地址 }IP_PACKET, *P_IP_PACKET; 4、不过目前对于如何解析发送时候的数据包还不甚了解,之前在sendpackets中对数据包进行解析,可惜得到的都是杂乱的消息。 继续努力!!! |
|
地板#
发布于:2004-08-19 23:23
结构大小的问题哪里用你那样作......
#pragma pack(push) #pragma pack(1) typedef struct xxx ///////xxxx #pragma pack(pop) .................... |
|
地下室#
发布于:2004-08-20 00:28
结构大小的问题哪里用你那样作...... 多谢指教 :) |
|