Образец проверки трафика платформы фильтрации Windows не работает должным образом - PullRequest
0 голосов
/ 19 октября 2011

Привет Эксперты пытаются выяснить, что не так с моим кодом.Я взял образец из WindDK WDK 7600.16385.1, есть образец кода, который называется Inspect.когда я запускаю его, я получаю неожиданные результаты на win 7 x86: это пример icmp, когда я пингую 127.0.0.3, я получаю ответ от 127.0.0.1, а также, если я пингую 127.0.0.4, происходит то же самое - может любой показатьчто не так или как это исправить: это код:

       /*++

       Copyright (c) Microsoft Corporation. All rights reserved

    Abstract:

    This file implements the classifyFn callout functions for the ALE connect,
     recv-accept, and transport callouts. In addition the system worker thread 
      that performs the actual packet inspection is also implemented here along 
      with the eventing mechanisms shared between the classify function and the
      worker thread.

     connect/Packet inspection is done out-of-band by a system worker thread 
     using the reference-drop-clone-reinject as well as ALE pend/complete 
      mechanism. Therefore the sample can serve as a base in scenarios where 
       filtering decision cannot be made within the classifyFn() callout and 
        instead must be made, for example, by an user-mode application.

        Environment:

         Kernel mode

   --*/

   #include "ntddk.h"

   #pragma warning(push)
   #pragma warning(disable:4201)       // unnamed struct/union

   #include "fwpsk.h"

   #pragma warning(pop)

    #include "fwpmk.h"
    #include "inspect.h"
    #include "utils.h"
   #include "ndis.h"


   #define htonl(x)                                (((((ULONG)(x))&0xffL)<<24)           | \
((((ULONG)(x))&0xff00L)<<8)        | \
((((ULONG)(x))&0xff0000L)>>8)        | \
((((ULONG)(x))&0xff000000L)>>24))

    extern NDIS_HANDLE NdisNetBufferListPool;


   void
   TLInspectDatagramClassify(
   IN const FWPS_INCOMING_VALUES0* inFixedValues,
    IN const FWPS_INCOMING_METADATA_VALUES0* inMetaValues,
   IN OUT void* layerData,
    IN const FWPS_FILTER0* filter,
     IN UINT64 flowContext,
    OUT FWPS_CLASSIFY_OUT0* classifyOut
    )
     {
   BOOLEAN Direction;
   UCHAR IpProtocol;
    FWPS_PACKET_INJECTION_STATE InjectState;
    BOOLEAN IsInjected;

   BOOLEAN signalWorkerThread;
   KLOCK_QUEUE_HANDLE connListLockHandle;
   KLOCK_QUEUE_HANDLE packetQueueLockHandle;
   TL_INSPECT_PENDED_PACKET* pendedPacket = NULL;
   NTSTATUS Status;
ULONG netBufferOffset = 0;

   InjectState = FwpsQueryPacketInjectionState0 (gInjectionHandle,layerData,NULL );
   IsInjected = InjectState != FWPS_PACKET_NOT_INJECTED;

      Direction = inFixedValues->incomingValue                                 [FWPS_FIELD_DATAGRAM_DATA_V4_DIRECTION].value.uint32  ==  FWP_DIRECTION_OUTBOUND;         
            IpProtocol = inFixedValues->incomingValue                 [FWPS_FIELD_DATAGRAM_DATA_V4_IP_PROTOCOL].value.uint8;

if( IsInjected && IpProtocol == 1)
    DbgPrint("Data: Injected ICMP, Direction = %s\n",                                 ( Direction ? "FWP_DIRECTION_OUTBOUND" : "FWP_DIRECTION_INBOUND"));
else if(IpProtocol == 1)
    DbgPrint("Data: ICMP, Direction = %s\n",         (Direction ? "FWP_DIRECTION_OUTBOUND" : "FWP_DIRECTION_INBOUND"));


/* Skip injected, inbound or non ICMP packets */
if( IsInjected || ( IpProtocol != 1) || (Direction == 0))
    goto Permit;

/* request allocation */
pendedPacket = AllocateAndInitializePendedPacket();
if( pendedPacket == NULL )
    goto Permit;

pendedPacket->Direction = Direction;
   pendedPacket->InterfaceIndex = 
    inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_INTERFACE_INDEX].value.uint32;
   pendedPacket->SubInterfaceIndex = 
    inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_SUB_INTERFACE_INDEX].value.uint32;
if ( FWPS_IS_METADATA_FIELD_PRESENT( inMetaValues, FWPS_METADATA_FIELD_COMPARTMENT_ID ) )
    pendedPacket->CompartmentId = inMetaValues->compartmentId;

pendedPacket->IsLoopback = 0;
if(inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_FLAGS].value.uint32 &      FWP_CONDITION_FLAG_IS_LOOPBACK)
{
    pendedPacket->IsLoopback = 1;
}
pendedPacket->transportEndpointHandle = inMetaValues->transportEndpointHandle;



if ( ! Direction ) { // FWP_DIRECTION_INBOUND
    netBufferOffset = inMetaValues->ipHeaderSize + inMetaValues-      >transportHeaderSize;

    Status = NdisRetreatNetBufferDataStart (
        NET_BUFFER_LIST_FIRST_NB(((NET_BUFFER_LIST*)layerData)),
        netBufferOffset,
        0,
        NULL );

    if( !NT_SUCCESS(Status) )
        goto Advance_Permit;
}

Status = FwpsAllocateCloneNetBufferList0 (
    ((NET_BUFFER_LIST*)layerData),
    NULL,
    NULL,
    0,
    &pendedPacket->NetBufferListAllocated );

if ( ! Direction ) { // FWP_DIRECTION_INBOUND
    NdisAdvanceNetBufferDataStart (
        NET_BUFFER_LIST_FIRST_NB(((NET_BUFFER_LIST*)layerData)),
        netBufferOffset,
        FALSE,
        NULL );
}

if( !NT_SUCCESS(Status) )
    goto Advance_Permit;


pendedPacket->RemoteIpAddress = htonl(inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_IP_REMOTE_ADDRESS].value.uint32);
pendedPacket->LocalIpAddress = inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_IP_LOCAL_ADDRESS].value.uint32;
pendedPacket->remoteScopeId = inMetaValues->remoteScopeId;

if ( ( inMetaValues->controlData ) && ( inMetaValues->controlDataLength ) ) {
    if ( ( pendedPacket->controlData = ExAllocatePoolWithTag ( NonPagedPool, inMetaValues->controlDataLength, 'dcLZ' ) ) != NULL ) {
        RtlCopyMemory ( pendedPacket->controlData, inMetaValues->controlData, inMetaValues->controlDataLength );
        pendedPacket->controlDataLength = inMetaValues->controlDataLength;
    }
}

classifyOut->actionType = FWP_ACTION_BLOCK;
classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB;
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;

    /* indicate the worker thread */
    DbgPrintEx(DPFLTR_IHVDRIVER_ID , DPFLTR_ERROR_LEVEL, "ICMP, inbound, echo reply\n");

   KeAcquireInStackQueuedSpinLock(
  &gPacketQueueLock,
  &packetQueueLockHandle
  );

   if (!gDriverUnloading)
  {
  signalWorkerThread = IsListEmpty(&gPacketQueue);

  InsertTailList(&gPacketQueue, &pendedPacket->listEntry);
  pendedPacket = NULL; // ownership transferred
   }
   else
   {
  //
  // Driver is being unloaded, permit any connect classify.
  //
  signalWorkerThread = FALSE;

  classifyOut->actionType = FWP_ACTION_PERMIT;
   }

   KeReleaseInStackQueuedSpinLock(&packetQueueLockHandle);

   if (signalWorkerThread)
   {
      KeSetEvent(
     &gWorkerEvent, 
     0, 
     FALSE
     );
   }


    if( gDriverUnloading )
        goto Permit;

    return;


Advance_Permit:
    NdisAdvanceNetBufferDataStart(
    NET_BUFFER_LIST_FIRST_NB((PNET_BUFFER_LIST)layerData),
    inMetaValues->ipHeaderSize + inMetaValues->transportHeaderSize,
    FALSE,
    NULL);

 Permit:
classifyOut->actionType = FWP_ACTION_PERMIT;

    if( pendedPacket )
    {

    //new code
    if( pendedPacket->NetBufferListAllocated )
        FwpsFreeCloneNetBufferList0 ( pendedPacket->NetBufferListAllocated,     0 );

    FreePendedPacket(pendedPacket);
    }
 }

    NTSTATUS
    TLInspectDatagramNotify(
   IN FWPS_CALLOUT_NOTIFY_TYPE notifyType,
   IN const GUID* filterKey,
   IN const FWPS_FILTER0* filter
      )
    {
    UNREFERENCED_PARAMETER(notifyType);
    UNREFERENCED_PARAMETER(filterKey);
    UNREFERENCED_PARAMETER(filter);

   return STATUS_SUCCESS;
   }

     VOID NTAPI
   CommonClassifyInjectComplete (
   IN VOID  *context,
   IN OUT NET_BUFFER_LIST  *netBufferList,
    IN BOOLEAN  dispatchLevel )
     {
      TL_INSPECT_PENDED_PACKET* packet = (TL_INSPECT_PENDED_PACKET*)context;

FwpsFreeCloneNetBufferList0 ( packet->NetBufferListAllocated, 0 );

      FreePendedPacket(packet);
     }

     void DumpNBL(NET_BUFFER_LIST* l)
      {
NET_BUFFER* nb = l->FirstNetBuffer;
MDL* currentMdl = nb->CurrentMdl;
ULONG dataLength = nb->DataLength;
ULONG currentByteIndex = nb->CurrentMdlOffset;
ULONG currentMdlSize = 0;
CHAR* dataPtr = 0;
ULONG lineIndex = 0;
ULONG numOfElemntsinLine = 0;
CHAR line[128];
DbgPrint("Dump NBL: 0x%x. Data length: 0x%x(%d) bytes\n",l,dataLength,dataLength);
lineIndex = 0;
line[0] = '\0';


while(currentMdl != NULL){
    currentMdlSize = currentMdl->ByteCount;
    dataPtr = currentMdl->MappedSystemVa;
    for (;currentByteIndex < currentMdlSize; currentByteIndex++)
    {
        if (dataLength == 0)
        {
            line[lineIndex] = '\0';
            lineIndex = 0;
            numOfElemntsinLine = 0;
            DbgPrint("%s.\n", line);
            line[0] = '\0';
            return;
        }

        if(numOfElemntsinLine < 16 && lineIndex < sizeof(line) - 4)
        {   
            CHAR currentChar = dataPtr[currentByteIndex];
            CHAR highChar = (currentChar & 0xF0) >> 4;
            CHAR lowChar = currentChar & 0x0F;

            if(highChar >= 0xA && highChar <= 0xF)
            {
                line[lineIndex] = 'A' + highChar - 0xA;
            }
            else if(highChar >= 0 && highChar <= 9)
            {
                line[lineIndex] = '0' + highChar - 0;
            }
            lineIndex++;

            if(lowChar >= 0xA && lowChar <= 0xF)
            {
                line[lineIndex] = 'A' + lowChar - 0xA;
            }
            else if(lowChar >= 0 && lowChar <= 9)
            {
                line[lineIndex] = '0' + lowChar - 0;
            }
            lineIndex++;
            line[lineIndex] = ' ';
            lineIndex++;

            if((numOfElemntsinLine + 1) % 4 == 0)
            {
                line[lineIndex] = '.';
                lineIndex++;
                line[lineIndex] = ' ';
                lineIndex++;
            }

        }

        numOfElemntsinLine++;

        if(!(numOfElemntsinLine < 16 && lineIndex < sizeof(line) - 4))
        {
            line[lineIndex] = '\0';
            lineIndex = 0;
            numOfElemntsinLine = 0;
            DbgPrint("%s\n", line);
            line[0] = '\0';
        }

        dataLength--;
    }

    currentByteIndex = 0;
    currentMdl = currentMdl->Next;
}
line[lineIndex] = '\0';
lineIndex = 0;
numOfElemntsinLine = 0;
DbgPrint("%s\n", line);
line[0] = '\0';
DbgPrint("\n");
return;
     }

   BOOLEAN
    DatagramDataClassifyPostProc (
     TL_INSPECT_PENDED_PACKET* packet )
      {
      FWPS_TRANSPORT_SEND_PARAMS0 TransportSendParams;

//DumpNBL(packet->NetBufferListAllocated);

if (packet->Direction) //send
{
    DbgPrintEx(DPFLTR_IHVDRIVER_ID , DPFLTR_ERROR_LEVEL, "Inject send\n");

    RtlZeroMemory ( &TransportSendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS0) );

    TransportSendParams.remoteAddress = (PUCHAR)(&(packet->RemoteIpAddress));
    TransportSendParams.remoteScopeId = packet->remoteScopeId;
    if ( packet->controlData ) {
        TransportSendParams.controlData = packet->controlData;
        TransportSendParams.controlDataLength = packet->controlDataLength;
    }

    //DbgPrint("TransportSendParams: remoteAddress = 0x%x\n",*((UINT32*)       TransportSendParams.remoteAddress));

    FwpsInjectTransportSendAsync0(
        gInjectionHandle,
        NULL,
        packet->transportEndpointHandle, // endpointHandle,
        0,
        &TransportSendParams, 
        AF_INET,
        packet->CompartmentId,
        packet->NetBufferListAllocated,
        CommonClassifyInjectComplete,
        packet );
} 

return TRUE;
}


void
TLInspectWorker( 
  IN PVOID StartContext
)
     /* ++

     This worker thread waits for the connect and packet queue event when the 
    queues are empty; and it will be woken up when there are connects/packets 
     queued needing to be inspected. Once awaking, It will run in a loop to 
    complete the pended ALE classifies and/or clone-reinject packets back 
     until both queues are exhausted (and it will go to sleep waiting for more 
       work).

     The worker thread will end once it detected the driver is unloading.

      -- */
    {
    NTSTATUS status;

    TL_INSPECT_PENDED_PACKET* packet = NULL;
     LIST_ENTRY* listEntry;

       KLOCK_QUEUE_HANDLE packetQueueLockHandle;
       KLOCK_QUEUE_HANDLE connListLockHandle;

      UNREFERENCED_PARAMETER(StartContext);

      for(;;)
       {
        KeWaitForSingleObject(
          &gWorkerEvent,
        Executive, 
         KernelMode, 
          FALSE, 
     NULL
     );

  if (gDriverUnloading)
  {
     break;
  }


    ASSERT(!IsListEmpty(&gPacketQueue));

     KeAcquireInStackQueuedSpinLock(
        &gPacketQueueLock,
        &packetQueueLockHandle
        );

     listEntry = RemoveHeadList(&gPacketQueue);

     packet = CONTAINING_RECORD(
                       listEntry,
                       TL_INSPECT_PENDED_PACKET,
                       listEntry
                       );

     KeReleaseInStackQueuedSpinLock(&packetQueueLockHandle);



  if ((packet != NULL) )
  {
     /* inject the packet here */
        DatagramDataClassifyPostProc(packet);
        packet = NULL; // ownership transferred.


  }

  if (packet != NULL)
  {
     FreePendedPacket(packet);
  }

  KeAcquireInStackQueuedSpinLock(
     &gPacketQueueLock,
     &packetQueueLockHandle
     );

  if (IsListEmpty(&gPacketQueue) &&
      !gDriverUnloading)
  {
     KeClearEvent(&gWorkerEvent);
  }

  KeReleaseInStackQueuedSpinLock(&packetQueueLockHandle);
 }

   ASSERT(gDriverUnloading);


   //
  // Discard all the pended packets if driver is being unloaded.
  //

  while (!IsListEmpty(&gPacketQueue))
  {
  packet = NULL;

  KeAcquireInStackQueuedSpinLock(
     &gPacketQueueLock,
     &packetQueueLockHandle
     );

  if (!IsListEmpty(&gPacketQueue))
  {
     listEntry = RemoveHeadList(&gPacketQueue);

     packet = CONTAINING_RECORD(
                       listEntry,
                       TL_INSPECT_PENDED_PACKET,
                       listEntry
                       );
  }

  KeReleaseInStackQueuedSpinLock(&packetQueueLockHandle);

  if (packet != NULL)
  {
     FreePendedPacket(packet);
  }
  }

  PsTerminateSystemThread(STATUS_SUCCESS);

  }

Заранее спасибо за помощь

1 Ответ

3 голосов
/ 07 декабря 2011

127.0.0.1 - это стандартный IP-адрес для петлевого сетевого подключения. Это означает, что если кто-то пытается подключиться к 127.0.0.1, он / она немедленно возвращается к своей собственной машине. 127.0.0.1 также называется «localhost», что означает ‘этот компьютер.

127.0.0.1 или localhost используется вместо имени хоста компьютера для подключения. Хотя 127.0.0.1 является наиболее часто используемым адресом для localhost, любой IP-адрес в диапазоне 127. . . * Также должен работать аналогичным образом.

Установление соединения с обратным адресом 127.0.0.1 аналогично установлению соединения с любым удаленным компьютером в сети, но оно обходит аппаратное обеспечение локального сетевого интерфейса. Для соединений IPv4 петлевому адресу компьютера обычно присваивается адрес 127.0.0.1 с маской подсети 255.0.0.0.

Короче говоря, если вы пингуете какой-либо адрес 127.x.x.x, на него, как правило, будет отвечать 127.0.0.1.

...