⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filter.c

📁 James Antognini和Tom Divine提供的PASSTHRU的编成实例。
💻 C
📖 第 1 页 / 共 3 页
字号:
//    the ADAPT structure.
//
// Parameters
//    pAdapt - pointer to ADAPT structure to be freed.
//
// Return Value
//    Nothing.
//
// Remarks
//    Called from protocol.c and miniport.c immediately after adapter is
//    closed and just prior to freeing the ADAPT structure.
//

VOID
FltOnDeinitAdapter(
    IN PADAPT  pAdapt
    )
{
   PADAPT_FILTER_RSVD   pFilterContext;

   //
   // Deinitialize FilterReserved Area In ADAPT Structure
   //
   pFilterContext = (PADAPT_FILTER_RSVD )&pAdapt->FilterReserved;

   if( pFilterContext->pIPv4BlockAddrArray )
   {
      NdisFreeMemory( pFilterContext->pIPv4BlockAddrArray, 0, 0);
   }

   pFilterContext->pIPv4BlockAddrArray = NULL;
}

////////////////////////////////////////////////////////////////////////////
//                        Send Packet Filter Functions                    //
////////////////////////////////////////////////////////////////////////////

int IPv4AddrCompare( const void *pKey, const void *pElement )
{
   ULONG a1 = *(PULONG )pKey;
   ULONG a2 = *(PULONG )pElement;

   if( a1 == a2 )
   {
      return( 0 );
   }

   if( a1 < a2 )
   {
      return( -1 );
   }

   return( 1 );
}

/////////////////////////////////////////////////////////////////////////////
//// FltFilterSendPacket
//
// Purpose
//   Called to filter each packet packet being sent.
//
// Parameters
//    pAdapt - pointer to ADAPT structure that the send is on.
//    pSendPacket - pointer to send packet to be filtered.
//    DispatchLevel - TRUE if caller is running at IRQL DISPATCH_LEVEL.
//                    FALSE of caller is running at IRQL <= DISPATCH_LEVEL.
//
// Return Value
//    A ULONG containing the send filter bitmap defined in filter.h
//
// Remarks
//   Called from MPSendPackets for each individual packet in the send
//   packet array and from MPSend.
//
//   Runs at IRQL <= DISPATCH_LEVEL if called from MPSendPackets or
//   at IRQL == DISPATCH_LEVEL if called from MPSend.
//

ULONG
FltFilterSendPacket(
	IN PADAPT         pAdapt,
	IN	PNDIS_PACKET   pSendPacket,
   IN BOOLEAN        DispatchLevel  // TRUE -> IRQL == DISPATCH_LEVEL
	)
{
   PADAPT_FILTER_RSVD   pFilterContext;
   ULONG                SndFltAction = SND_FLT_SIMPLE_PASSTHRU;
   USHORT               EtherType;
   ULONG                NumberOfBytesRead;
   struct ip            IPHeader;

   //
   // Hold Adapter Spin Lock When Using Filter Data
   // ---------------------------------------------
   // See note at ADAPT_FILTER_RSVD structure declaration.
   //
   if( DispatchLevel )
      NdisDprAcquireSpinLock(&pAdapt->Lock);
   else
      NdisAcquireSpinLock(&pAdapt->Lock);

   //
   // Find FilterReserved Area In ADAPT Structure
   //
   pFilterContext = (PADAPT_FILTER_RSVD )&pAdapt->FilterReserved;

   ++pFilterContext->IPv4Stats.MPSendPktsCt; // SpinLock Already Held

   //
   // Pass All Packets If No Filter Is Set
   //
   if( !pFilterContext->pIPv4BlockAddrArray )
   {
      goto ExitTheFilter;
   }

   //
   // Filter On EtherType
   // -------------------
   // We only filter IP at this point. The switch below is provided simply
   // to illustrate how other EtherTypes could be identified and handled
   // differently.
   //
   FltReadOnPacket(
      pSendPacket,
      &EtherType,
      sizeof( EtherType ),
      FIELD_OFFSET( struct ether_header, ether_type ),
      &NumberOfBytesRead
      );

   if( NumberOfBytesRead != sizeof( EtherType ) )
   {
      goto ExitTheFilter;
   }

   switch( ntohs( EtherType ) )
   {
      // See ..\B2Winet/ethernet.h for ETHERTYPE Definitions
      case ETHERTYPE_IP:
         break;

      case ETHERTYPE_ARP:
      case ETHERTYPE_REVARP:
      case ETHERTYPE_NETBEUI:
      default:
         goto ExitTheFilter;
   }

   //
   // Fetch The IP Header
   // -------------------
   // The logic of the send packet filter and the recceive packet filter
   // is identical - except for whether the IP destination address of the
   // IP source address should be checked.
   //
   // However. for illustrative purposes there is a difference in the
   // filter implementation.
   //
   // The send packet filter uses FltReadOnPacket to fetch the entire
   // IP header and then accesses information using fields in struct ip.
   //
   // The receive packet filter uses a different technique. It uses
   // FltReadOnPacket to fetch only specific fields of interest.
   //
   FltReadOnPacket(
      pSendPacket,
      &IPHeader,
      sizeof( IPHeader ),
      sizeof( struct ether_header ),
      &NumberOfBytesRead
      );

   if( NumberOfBytesRead != sizeof( IPHeader ) )
   {
      goto ExitTheFilter;
   }

   //
   // Only Filter IPv4 For Now...
   //
   switch( IPHeader.ip_v )
   {
      case 4:        // IPv4
         break;

      case 6:        // IPv6
      default:
         goto ExitTheFilter;
   }

   //
   // Do Binary Search On Sorted List Of IP Addresses To Block
   //
   if( bsearch(
         &IPHeader.ip_dst.s_addr,                              // Key To Search For
         (pFilterContext->pIPv4BlockAddrArray)->IPAddrArray,   // Array Base
         (pFilterContext->pIPv4BlockAddrArray)->NumberElements,// Number Of Elements In Array
         sizeof( ULONG ),                                      // Bytes Per Element
         IPv4AddrCompare                                       // Comparison Function
         )
      )
   {
      //
      // Reject Packets That Have Matching IP Source Address
      //
      ++pFilterContext->IPv4Stats.MPSendPktsDropped;  // SpinLock Already Held
      SndFltAction = SND_FLT_BLOCK_PACKET;
   }

ExitTheFilter:
   //
   // Release Adapter Spin Lock After Filtering
   //
   if( DispatchLevel )
      NdisDprReleaseSpinLock(&pAdapt->Lock);
   else
      NdisReleaseSpinLock(&pAdapt->Lock);

   return( SndFltAction );
}

////////////////////////////////////////////////////////////////////////////
//                      Receive Packet Filter Functions                   //
////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
//// FltFilterReceivePacket
//
// Purpose
//   Called to filter each received packet.
//
// Parameters
//    pAdapt - pointer to ADAPT structure that the send is on.
//    pReceivedPacket - pointer to receive packet to be filtered.
//
// Return Value
//    A ULONG containing the receive filter action bitmap defined
//    in filter.h
//
// Remarks
//   Called from PtReceivePacket for each received packet.
//
//   Runs at IRQL DISPATCH_LEVEL.
//

ULONG
FltFilterReceivePacket(
	IN PADAPT         pAdapt,
	IN	PNDIS_PACKET   pReceivedPacket
	)
{
   PADAPT_FILTER_RSVD   pFilterContext;
   ULONG                RcvFltAction = RCV_FLT_SIMPLE_PASSTHRU;
   USHORT               EtherType;
   ULONG                NumberOfBytesRead;
   ULONG                PktSrcAddr;
   UCHAR                IPVersion;

   //
   // Hold Adapter Spin Lock When Using Filter Data
   // ---------------------------------------------
   // See note at ADAPT_FILTER_RSVD structure declaration.
   //
   NdisDprAcquireSpinLock(&pAdapt->Lock);

   //
   // Find FilterReserved Area In ADAPT Structure
   //
   pFilterContext = (PADAPT_FILTER_RSVD )&pAdapt->FilterReserved;

   ++pFilterContext->IPv4Stats.PTRcvPktCt;   // SpinLock Already Held

   //
   // Pass All Packets If No Filter Is Set
   //
   if( !pFilterContext->pIPv4BlockAddrArray )
   {
      goto ExitTheFilter;
   }

   //
   // Filter On EtherType
   // -------------------
   // We only filter IP at this point. The switch below is provided simply
   // to illustrate how other EtherTypes could be identified and handled
   // differently.
   //
   FltReadOnPacket(
      pReceivedPacket,
      &EtherType,
      sizeof( EtherType ),
      FIELD_OFFSET( struct ether_header, ether_type ),
      &NumberOfBytesRead
      );

   if( NumberOfBytesRead != sizeof( EtherType ) )
   {
      goto ExitTheFilter;
   }

   switch( ntohs( EtherType ) )
   {
      // See ..\B2Winet/ethernet.h for ETHERTYPE Definitions
      case ETHERTYPE_IP:
         break;

      case ETHERTYPE_ARP:
      case ETHERTYPE_REVARP:
      case ETHERTYPE_NETBEUI:
      default:
         goto ExitTheFilter;
   }

   //
   // The logic of the send packet filter and the recceive packet filter
   // is identical - except for whether the IP destination address of the
   // IP source address should be checked.
   //
   // However. for illustrative purposes there is a difference in the
   // filter implementation.
   //
   // The receive packet filter uses FltReadOnPacket to fetch only specific
   // fields of interest.
   //
   // The send packet filter uses FltReadOnPacket to fetch the entire
   // IP header and then accesses information using fields in struct ip.
   //

   //
   // Only Filter IPv4 For Now...
   //
   FltReadOnPacket(
      pReceivedPacket,
      &IPVersion,
      sizeof( IPVersion ),
      sizeof( struct ether_header ),
      &NumberOfBytesRead
      );

   if( NumberOfBytesRead != sizeof( IPVersion ) )
   {
      goto ExitTheFilter;
   }

   if( NumberOfBytesRead != sizeof( IPVersion ) )
   {
      goto ExitTheFilter;
   }

   switch( IPVersion >> 4 )
   {
      case 4:        // IPv4
         break;

      case 6:        // IPv6
      default:
         goto ExitTheFilter;
   }

   //
   // Fetch IPv4 Source Address
   //
   FltReadOnPacket(
      pReceivedPacket,
      &PktSrcAddr,
      sizeof( PktSrcAddr ),
      sizeof( struct ether_header ) + FIELD_OFFSET( struct ip, ip_src.s_addr ),
      &NumberOfBytesRead
      );

   if( NumberOfBytesRead != sizeof( PktSrcAddr ) )
   {
      goto ExitTheFilter;
   }

   //
   // Do Binary Search On Sorted List Of IP Addresses To Block
   //
   if( bsearch(
         &PktSrcAddr,                                          // Key To Search For
         (pFilterContext->pIPv4BlockAddrArray)->IPAddrArray,     // Array Base
         (pFilterContext->pIPv4BlockAddrArray)->NumberElements,  // Number Of Elements In Array
         sizeof( ULONG ),                                      // Bytes Per Element
         IPv4AddrCompare                                      // Comparison Function
         )
      )
   {
      //
      // Reject Packets That Have Matching IP Source Address
      //
      ++pFilterContext->IPv4Stats.PTRcvPktDropped; // SpinLock Already Held
      RcvFltAction = RCV_FLT_BLOCK_PACKET;
   }

ExitTheFilter:
   //
   // Release Adapter Spin Lock After Filtering
   //
   NdisDprReleaseSpinLock(&pAdapt->Lock);

   return( RcvFltAction );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -