/////////////////////////////////////////////////////////////////////////////
//// UTILReadOnPacket
//
// Purpose
// Logical read on the packet data in a NDIS_PACKET.
//
// Parameters
//
// Return Value
//
// Remarks
// The purpose of this function is to provide a convenient mechanism to
// read packet data from an NDIS_PACKET that may have multiple chained
// NDIS_BUFFERs.
//
VOID
UTILReadOnPacket(
   PNDIS_PACKET Packet,
   PUCHAR lpBuffer,
   ULONG nNumberOfBytesToRead,
   ULONG nOffset,                // Byte Offset, Starting With MAC Header
   PULONG lpNumberOfBytesRead
   )
{
   PNDIS_BUFFER    CurrentBuffer;
   UINT            nBufferCount, TotalPacketLength;
   PUCHAR          VirtualAddress;
   UINT            CurrentLength, CurrentOffset;
   UINT            AmountToMove;
   *lpNumberOfBytesRead = 0;
   if (!nNumberOfBytesToRead)
      return;
   //
   // Query Packet
   //
   NdisQueryPacket(
      (PNDIS_PACKET )Packet,
      (PUINT )NULL,           // Physical Buffer Count
      (PUINT )&nBufferCount,  // Buffer Count
      &CurrentBuffer,         // First Buffer
      &TotalPacketLength      // TotalPacketLength
      );
   //
   // Query The First Buffer
   //
   NdisQueryBuffer(
      CurrentBuffer,
      &VirtualAddress,
      &CurrentLength
      );
   CurrentOffset = 0;
   while( nOffset || nNumberOfBytesToRead )
   {
      while( !CurrentLength )
      {
         NdisGetNextBuffer(
            CurrentBuffer,
            &CurrentBuffer
            );
         // If we've reached the end of the packet.  We return with what
         // we've done so far (which must be shorter than requested).
         if (!CurrentBuffer)
            return;
         NdisQueryBuffer(
            CurrentBuffer,
            &VirtualAddress,
            &CurrentLength
            );
         CurrentOffset = 0;
      }
      if( nOffset )
      {
         // Compute how much data to move from this fragment
         if( CurrentLength > nOffset )
            CurrentOffset = nOffset;
         else
            CurrentOffset = CurrentLength;
         nOffset -= CurrentOffset;
         CurrentLength -= CurrentOffset;
      }
      if( nOffset )
      {
         CurrentLength = 0;
         continue;
      }
      if( !CurrentLength )
      {
         continue;
      }
      // Compute how much data to move from this fragment
      if (CurrentLength > nNumberOfBytesToRead)
         AmountToMove = nNumberOfBytesToRead;
      else
         AmountToMove = CurrentLength;
      // Copy the data.
      NdisMoveMemory(
         lpBuffer,
         &VirtualAddress[ CurrentOffset ],
         AmountToMove
         );
      // Update destination pointer
      lpBuffer += AmountToMove;
      // Update counters
      *lpNumberOfBytesRead +=AmountToMove;
      nNumberOfBytesToRead -=AmountToMove;
      CurrentLength = 0;
   }
}
PCASIM_SEND_FILTER_ACTION
IPBlock_FilterSendPacket(
   IN PADAPTER       Adapter,
   IN PNDIS_PACKET   pOriginalPacket
   )
{
   USHORT                  nEtherType;
   ULONG                   nNumberOfBytesRead = 0;
   <snip...>
   //
   // Ignore Non-IP Packets
   // ---------------------
   // Packets that are presented to IPBlock_FilterRcvIndication include
   // non-IP packets. These should, of course, be ignored for TCP.
   //
   // The switch could be extended to to ARP, REVARP, etc.
   //
   UTILReadOnPacket(
      pOriginalPacket,
      (PUCHAR )&nEtherType,
      sizeof( USHORT ),
      MEtherType, // Offset From MAC Header To Length/Type. Value is 12.
      &nNumberOfBytesRead
      );
   //
   // Check For IEEE 802.2/802.3 (RFC 1042) Encapsulation
   //
   if( htons( nEtherType ) <= MAX_802_3_LENGTH )
   {
      return( SEND_FILTER_ACTION_PASS_PACKET );  // Allow The Packet To Pass Through
   }
   else
   {
      //
      // Check For Ethernet Encapsulation (RFC 894)
      //
      switch( htons( nEtherType ) )
      {
         case ETHERTYPE_IP:
            break;
         case ETHERTYPE_ARP:
         case ETHERTYPE_REVARP:
         default:
            ImDbgOut( DBG_TRACE, DBG_FILTERS, ( "IPBlock_FilterSendPacket: Ignoring 0x%4.4X EtherType\n",
               htons( nEtherType ) ) );
            return( SEND_FILTER_ACTION_PASS_PACKET );  // Allow The Packet To Pass Through
      }
   }
   <Snip...>
   return( SEND_FILTER_ACTION_PASS_PACKET );
}

Topic Status

December 29, 2002 Reviewed and moved to NDIS.com.

 

 
 

PCAUSA Home · Privacy Statement · Products · Ordering · Support · Utilities · Resources
Mailing Lists  · PCAUSA Newsletter · PCAUSA Discussion List
Rawether for Windows, Rawether .NET, WinDis 32 and NDIS Press are trademarks of Printing Communications Assoc., Inc. (PCAUSA)
Microsoft, MS, Windows, Windows Vista, Windows 95, Windows 98, Windows Millennium, Windows 2000, and Win32 are registered trademarks and Visual C++ and Windows NT are trademarks of the Microsoft Corporation.
Copyright © 1996-2007 Printing Communications Assoc., Inc. (PCAUSA)
Last modified: January 20, 2007