darkme
驱动牛犊
驱动牛犊
  • 注册日期2004-07-17
  • 最后登录2006-03-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1854回复:4

关于NdisGetNextBuffer一问

楼主#
更多 发布于:2004-08-18 10:40
在调用完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、正确的情况应该如何?

最新喜欢:

qiyidiqiyidi
kenychen1981
驱动牛犊
驱动牛犊
  • 注册日期2004-06-12
  • 最后登录2005-01-17
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-08-19 14:12
你可以查DDK中NdisQueryPacket函数的帮助和ndis.h中关于Packet(_NDISPACKET)的结构。说的比较清楚
darkme
驱动牛犊
驱动牛犊
  • 注册日期2004-07-17
  • 最后登录2006-03-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于: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中对数据包进行解析,可惜得到的都是杂乱的消息。

继续努力!!!
tiamo
VIP专家组
VIP专家组
  • 注册日期2002-02-26
  • 最后登录2018-01-09
  • 粉丝17
  • 关注4
  • 积分50分
  • 威望142点
  • 贡献值1点
  • 好评度40点
  • 原创分2分
  • 专家分15分
  • 原创先锋奖
  • 社区居民
地板#
发布于:2004-08-19 23:23
结构大小的问题哪里用你那样作......

#pragma pack(push)
#pragma pack(1)

typedef struct xxx
///////xxxx

#pragma pack(pop)

....................
darkme
驱动牛犊
驱动牛犊
  • 注册日期2004-07-17
  • 最后登录2006-03-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-08-20 00:28
结构大小的问题哪里用你那样作......

#pragma pack(push)
#pragma pack(1)

typedef struct xxx
///////xxxx

#pragma pack(pop)

....................


多谢指教 :)
游客

返回顶部