Hi Experts am trying to figure out what is wrong with my code. i took the sample from the winddk WDK 7600.16385.1 ,there is a sample code called inspect. when i run it i get unexpected results on win 7 x86: this is an icmp sample when i ping the 127.0.0.3 i get a reply from 127.0.0.1 and also if i ping 127.0.0.4 same thing happens -can any one show me wahts wrong or how to fix it: this is the code:
/*++
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);
}
thanks in advance for the help
127.0.0.1 is the standard IP address for a loopback network connection. This means that if someone tries to connect to 127.0.0.1, he/she is immediately looped back to his/her own machine. 127.0.0.1 is also referred to as “localhost,” meaning ‘this computer.
127.0.0.1 or localhost is used in place of a computer’s hostname to be connected. Although 127.0.0.1 is the most commonly utilized address for localhost, any IP address in the 127...* range should also work in the same manner.
Making a connection with a 127.0.0.1 loopback address is the same as making a connection with any remote computer on the network, but it bypasses the local network interface hardware. For IPv4 connections, the computer’s loopback address is usually allocated the address 127.0.0.1 with subnet mask 255.0.0.0.
In short, if you ping any 127.x.x.x address it will typically be answered by 127.0.0.1.