个人总结NDIS中NDIS_PACKET,NDIS_BUFFER的关系

个人总结NDIS中NDIS_PACKET,NDIS_BUFFER的关系

 1  //    
 2  //  NDIS_PACKET结构的定义  
 3  //    
 4  typedef  struct  _NDIS_PACKET  
 5  {  
 6  NDIS_PACKET_PRIVATE Private;  
 7  // 这个其实是一个链表结构,Private.Head指向第一个链表,Private.Tail指向最后一个  
 8  // 以下有关于这个结构的解释  
 9 
10  union  
11  {  
12  struct   //  For Connection-less miniports   
13  {  
14  UCHAR MiniportReserved[ 2 * sizeof (PVOID)];  
15  UCHAR WrapperReserved[ 2 * sizeof (PVOID)];  
16  };  
17 
18  struct   
19  {  
20  //    
21  //  For de-serialized miniports. And by implication conn-oriented miniports.   
22  //  This is for the send-path only. Packets indicated will use WrapperReserved   
23  //  instead of WrapperReservedEx   
24  //    
25  UCHAR MiniportReservedEx[ 3 * sizeof (PVOID)];  
26  UCHAR WrapperReservedEx[ sizeof (PVOID)];  
27  };  
28 
29  struct   
30  {  
31  UCHAR MacReserved[ 4 * sizeof (PVOID)];  
32  };  
33  };  
34 
35  ULONG_PTR Reserved[ 2 ];  //  For compatibility with Win95   
36  UCHAR ProtocolReserved[ 1 ];  
37 
38  } NDIS_PACKET,  * PNDIS_PACKET,  ** PPNDIS_PACKET;  
39 
40  //  NDIS_PACKET_PRIVATE 的定义  
41  typedef  struct  _NDIS_PACKET_PRIVATE  
42  {  
43  UINT PhysicalCount;  //  number of physical pages in packet.   
44  UINT TotalLength;  //  Total amount of data in the packet.   
45  PNDIS_BUFFER Head;  //  链表指针,指向第一个 
46  PNDIS_BUFFER Tail;  //  链表指针, 指向最后一个  
47 
48  //  if Head is NULL the chain is empty; Tail doesn\'t have to be NULL also   
49 
50  PNDIS_PACKET_POOL Pool;  //  so we know where to free it back to   
51  UINT Count;  
52  ULONG Flags;  
53  BOOLEAN ValidCounts;  
54  UCHAR NdisPacketFlags;  //  See fPACKET_xxx bits below   
55  USHORT NdisPacketOobOffset;  
56  } NDIS_PACKET_PRIVATE,  *  PNDIS_PACKET_PRIVATE;  
57 
58  // NDIS_BUFFER定义 其实就是一个内存描述符
59 
60  typedef  struct  _NDIS_BUFFER {  
61  struct  _NDIS_BUFFER  * Next;  // 指向下一个节点的指针
62  PVOID VirtualAddress;       // 指向报文首地址
63  PNDIS_BUFFER_POOL Pool;  
64  UINT Length;                // 报文数据长度
65  UINT Signature;  
66  } NDIS_BUFFER,  *  PNDIS_BUFFER;  

注释写的很清楚了  那么他们的关系还是不清楚的话看看附图



  好了  这样一来我们的思路大概清楚了  NDIS_PACKET只不过是一个关于NDIS_BUFFER链表的结构  在NDIS_PACKET中的成 员Private中有指向第一个NDIS_BUFFER的指针和指向最后一个NDIS_BUFFER的指针  分别是Private.Head 和Private.Tail     而NDIS_BUFFER中就记录了我们数据包的地址和下一个NDIS_BUFFER的地址   操作有很多种方法   由于这些结构体本来对我们是不透明的    所以最安全的方法是用MS提供的一系列函数来操作NDIS_PACKET和NDIS_BUFFER  

    还是拿个例子好说话吧

 1  NDIS_STATUS status ;
 2      PNDIS_BUFFER NdisBuffer ;
 3      UINT TotalPacketLength  =   0  , copysize  =   0  , DataOffset  =   0  , PhysicalBufferCount  ,  BufferCount   ;
 4      PUCHAR mybuffer  =  NULL ,tembuffer  =  NULL ;  
 5 
 6  // 假设这个是在PtReceive等函数中得到的PACKET
 7  NdisQueryPacket(packet                      // 我们先得到第一个NDISBUFFER 的指针   
 8          ,  & PhysicalBufferCount              
 9          ,  & BufferCount                           
10          , & NdisBuffer                                // NdisBuffer就是指向链表头
11          ,  & TotalPacketLength
12          );
13  /*
14  其实也可以不用那么麻烦 直接  NdisBuffer = packet->Private.Head ;就可以取得第一个BUFFER了
15  */
16 
17      status  =  NdisAllocateMemory(  & mybuffer,  2048 0 , HighestAcceptableMax );   // 分配我们自己的内存块
18 
19       if ( status  !=  NDIS_STATUS_SUCCESS )
20           return  NDIS_STATUS_FAILURE ;
21 
22      NdisZeroMemory( mybuffer,  2048  ) ;
23 
24      NdisQueryBufferSafe(   // 取得NDIS_BUFFER描述符中数据的首地址和大小
25                                  NdisBuffer,
26                                   & tembuffer,
27                                   & copysize,
28                                  NormalPagePriority
29      );  
30       
31           // 将数据复制到我们的内存中
32      NdisMoveMemory(mybuffer, tembuffer, copysize) ;
33 
34      DataOffset  =  copysize ;
35 
36       while ( 1 )
37      {
38           /*
39                  也可以这样操作而不用NdisGetNextBuffer
40          if(NdisBuffer->Next == packet->Private.Tail )
41              break ;
42 
43          NdisBuffer = NdisBuffer->Next ;
44 
45          if(pmdl == NULL )
46             break ;
47              */
48           // 获得下一个NDIS_BUFFER的的指针
49      NdisGetNextBuffer(NdisBuffer ,  & NdisBuffer ) ;
50          如果指针是NULL  那么表示到链表尾了
51       if ( NdisBuffer  ==  NULL )
52           break  ;
53 
54      NdisQueryBufferSafe(
55                                  NdisBuffer,
56                                   & tembuffer,
57                                   & copysize,
58                                  NormalPagePriority
59                                  ) ;
60 
61      NdisMoveMemory( mybuffer  +  DataOffset , tembuffer, copysize) ;
62 
63      DataOffset  +=  copysize  ;
64 
65      }
66 
67  // OK  我们要的数据就全部都在我们申请的内存mybuffer 数据大小为DataOffset

   
 

你可能感兴趣的:(个人总结NDIS中NDIS_PACKET,NDIS_BUFFER的关系)