2011-10-19 27 views
0

嗨,專家正在嘗試弄清楚我的代碼出了什麼問題。 我從winddk WDK 7600.16385.1取樣,有一個稱爲inspect的示例代碼。 當我運行它我得到意想不到的結果贏得7 x86: 這是一個icmp示例 當我ping 127.0.0.3我從127.0.0.1得到的答覆,如果我ping 127.0.0.4同樣的事情發生 - 可以任何一個告訴我wahts錯誤或如何解決它: 這是代碼:Windows篩選平臺流量檢查示例不能按預期方式工作

 /*++ 

     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); 

    } 

在此先感謝您的幫助

回答

3

127.0.0.1是迴環網絡連接標準的IP地址。這意味着如果有人試圖連接到127.0.0.1,他/她立即回到他/她自己的機器。 127.0.0.1也被稱爲「localhost」,意思是「這臺電腦。

127.0.0.1或localhost用於替代要連接的計算機的主機名。雖然127.0.0.1是本地主機最常用的地址,但127. 中的任何IP地址。。*範圍也應該以相同的方式工作。

與127.0.0.1環回地址建立連接與網絡上的任何遠程計算機建立連接是相同的,但它會繞過本地網絡接口硬件。對於IPv4連接,計算機的環回地址通常分配地址127.0.0.1和子網掩碼255.0.0.0。

總之,如果你ping任何127.x.x.x地址,它通常會被127.0.0.1回答。

相關問題