Пример #1
0
PWSK_SOCKET
NTAPI
WSKCreateSocket(
	IN ADDRESS_FAMILY AddressFamily,
	IN USHORT SocketType,
	IN ULONG Protocol,
	IN ULONG Flags
	)
{
	KEVENT                  CompletionEvent = { 0 };
	PIRP                    Irp = NULL;
	PWSK_SOCKET             WskSocket = NULL;
	NTSTATUS                Status = STATUS_UNSUCCESSFUL;

	TRACE_ENTER();

	if (g_SocketsState != INITIALIZED)
	{
		TRACE_EXIT();
		return NULL;
	}

	Status = InitWskData(&Irp, &CompletionEvent);
	if (!NT_SUCCESS(Status))
	{
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "WSKCreateSocket()::InitWskData() failed with status 0x%08X\n", Status);
		TRACE_EXIT();
		return NULL;
	}

	Status = g_WskProvider.Dispatch->WskSocket(
		g_WskProvider.Client,
		AddressFamily,
		SocketType,
		Protocol,
		Flags,
		NULL,
		NULL,
		NULL,
		NULL,
		NULL,
		Irp);
	if (Status == STATUS_PENDING)
	{
		KeWaitForSingleObject(&CompletionEvent, Executive, KernelMode, FALSE, NULL);
		Status = Irp->IoStatus.Status;
	}

	if (!NT_SUCCESS(Status))
	{
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "WSKCreateSocket()::Dispatch::WskSocket() failed with status 0x%08X\n", Status);
	}

	WskSocket = NT_SUCCESS(Status) ? (PWSK_SOCKET)Irp->IoStatus.Information : NULL;

	IoFreeIrp(Irp);
	TRACE_EXIT();
	return (PWSK_SOCKET)WskSocket;
}
Пример #2
0
NTSTATUS
NTAPI
WSKSendPacketInternal_NBL(
	IN BOOLEAN bIPv4,
	IN PNET_BUFFER_LIST NetBufferList,
	IN ULONG Offset
	)
{
	NTSTATUS		status = STATUS_SUCCESS;
	ULONG			SentBytes;

	TRACE_ENTER();

	SentBytes = bIPv4 ?
		WSKSendTo_NBL(g_IPv4Socket, NetBufferList, Offset, (PSOCKADDR)& g_IPv4RemoteAddress) :
		WSKSendTo_NBL(g_IPv6Socket, NetBufferList, Offset, (PSOCKADDR)& g_IPv6RemoteAddress);

	if (SentBytes != NetBufferList->FirstNetBuffer->DataLength - Offset)
	{
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "WSKSendPacketInternal_NBL()::WSKSendTo_NBL() failed with SentBytes 0x%08X\n", SentBytes);
	}

	TRACE_EXIT();
	return status;
}
Пример #3
0
BOOLEAN
NPF_IsPacketSelfSent(
	_In_ PNET_BUFFER_LIST pNetBufferList,
	_In_ BOOLEAN bIPv4
	)
{
	NTSTATUS			status = STATUS_SUCCESS;
	NET_BUFFER*			pNetBuffer = 0;
	PVOID				pContiguousData = NULL;
	UCHAR				pPacketData[IPV6_HDR_LEN];
	UCHAR				iProtocol;

	TRACE_ENTER();

	pNetBuffer = NET_BUFFER_LIST_FIRST_NB(pNetBufferList);
	while (pNetBuffer)
	{
		pContiguousData = NdisGetDataBuffer(pNetBuffer,
			bIPv4 ? IP_HDR_LEN : IPV6_HDR_LEN,
			pPacketData,
			1,
			0);
		if (!pContiguousData)
		{
			status = STATUS_UNSUCCESSFUL;

			TRACE_MESSAGE1(PACKET_DEBUG_LOUD,
				"NPF_IsPacketSelfSent: NdisGetDataBuffer() [status: %#x]\n",
				status);

			TRACE_EXIT();
			return FALSE;
		}
		else
		{
			iProtocol = bIPv4 ? ((PIP_HEADER) pContiguousData)->ip_Protocol : ((PIP6_HEADER) pContiguousData)->ip6_CTL.ip6_HeaderCtl.ip6_NextHeader;
			if (iProtocol == IPPROTO_NPCAP_LOOPBACK)
			{
				TRACE_EXIT();
				return TRUE;
			}
			else
			{
				TRACE_EXIT();
				return FALSE;
			}
		}

		pNetBuffer = pNetBuffer->Next;
	}

	TRACE_EXIT();
	return FALSE;
}
Пример #4
0
NTSTATUS
NTAPI
WSKCloseSocket(
	IN PWSK_SOCKET WskSocket
	)
{
	KEVENT          CompletionEvent = { 0 };
	PIRP            Irp = NULL;
	NTSTATUS        Status = STATUS_UNSUCCESSFUL;

	TRACE_ENTER();

	if (g_SocketsState != INITIALIZED || !WskSocket)
	{
		TRACE_EXIT();
		return STATUS_INVALID_PARAMETER;
	}

	Status = InitWskData(&Irp, &CompletionEvent);
	if (!NT_SUCCESS(Status))
	{
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "WSKCloseSocket()::InitWskData() failed with status 0x%08X\n", Status);
		TRACE_EXIT();
		return Status;
	}

	Status = ((PWSK_PROVIDER_BASIC_DISPATCH)WskSocket->Dispatch)->WskCloseSocket(WskSocket, Irp);
	if (Status == STATUS_PENDING)
	{
		KeWaitForSingleObject(&CompletionEvent, Executive, KernelMode, FALSE, NULL);
		Status = Irp->IoStatus.Status;
	}
	else if (Status != STATUS_SUCCESS)
	{
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "WSKCloseSocket()::Dispatch::WskSocket() failed with status 0x%08X\n", Status);
	}

	IoFreeIrp(Irp);
	TRACE_EXIT();
	return Status;
}
Пример #5
0
NTSTATUS
NTAPI
NPF_WSKStartup(
	)
{
	WSK_CLIENT_NPI	WskClient = {0};
	NTSTATUS		Status = STATUS_UNSUCCESSFUL;

	TRACE_ENTER();

	if (InterlockedCompareExchange(&g_SocketsState, INITIALIZING, DEINITIALIZED) != DEINITIALIZED)
		return STATUS_ALREADY_REGISTERED;

	WskClient.ClientContext = NULL;
	WskClient.Dispatch = &g_WskDispatch;

	Status = WskRegister(&WskClient, &g_WskRegistration);
	if (!NT_SUCCESS(Status))
	{
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "NPF_WSKStartup()::WskRegister() failed with status 0x%08X\n", Status);
		InterlockedExchange(&g_SocketsState, DEINITIALIZED);
		TRACE_EXIT();
		return Status;
	}

	Status = WskCaptureProviderNPI(&g_WskRegistration, WSK_NO_WAIT, &g_WskProvider);
	if (!NT_SUCCESS(Status))
	{
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "NPF_WSKStartup()::WskCaptureProviderNPI() failed with status 0x%08X\n", Status);
		WskDeregister(&g_WskRegistration);
		InterlockedExchange(&g_SocketsState, DEINITIALIZED);
		TRACE_EXIT();
		return Status;
	}

	InterlockedExchange(&g_SocketsState, INITIALIZED);
	TRACE_EXIT();
	return STATUS_SUCCESS;
}
Пример #6
0
static
NTSTATUS
InitWskBuffer_NBL(
	IN PNET_BUFFER_LIST NetBufferList,
	IN ULONG BufferOffset,
	OUT PWSK_BUF WskBuffer
	)
{
	NTSTATUS Status = STATUS_SUCCESS;

	TRACE_ENTER();

	ASSERT(NetBufferList);
	ASSERT(WskBuffer);

	WskBuffer->Offset = BufferOffset;
	WskBuffer->Length = NetBufferList->FirstNetBuffer->DataLength - BufferOffset;

	WskBuffer->Mdl = NetBufferList->FirstNetBuffer->CurrentMdl;
	if (!WskBuffer->Mdl)
	{
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "InitWskBuffer_NBL()::NetBufferList->FirstNetBuffer->CurrentMdl failed with status 0x%08X\n", STATUS_INSUFFICIENT_RESOURCES);
		TRACE_EXIT();
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	__try
	{
		if ((WskBuffer->Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) != MDL_MAPPED_TO_SYSTEM_VA &&
			(WskBuffer->Mdl->MdlFlags & MDL_PAGES_LOCKED) != MDL_PAGES_LOCKED &&
			(WskBuffer->Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) != MDL_SOURCE_IS_NONPAGED_POOL)
		{
			MmProbeAndLockPages(WskBuffer->Mdl, KernelMode, IoWriteAccess);
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		TRACE_MESSAGE2(PACKET_DEBUG_LOUD, "InitWskBuffer_NBL()::MmProbeAndLockPages(%p) failed with status 0x%08X\n", WskBuffer->Mdl, STATUS_ACCESS_VIOLATION);
		Status = STATUS_ACCESS_VIOLATION;
	}

	TRACE_EXIT();
	return Status;
}
Пример #7
0
VOID
NPF_CloseAdapterComplete(IN NDIS_HANDLE  ProtocolBindingContext,IN NDIS_STATUS  Status)
{
    POPEN_INSTANCE    Open;
    PIRP              Irp;

	TRACE_ENTER();

	Open = (POPEN_INSTANCE)ProtocolBindingContext;

	ASSERT(Open != NULL);

	TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Open= %p", Open);

	NdisSetEvent(&Open->NdisOpenCloseCompleteEvent);

	TRACE_EXIT();
	return;

}
Пример #8
0
VOID
NPF_NetworkInjectionComplete(
	_In_ VOID* pContext,
	_Inout_ NET_BUFFER_LIST* pNetBufferList,
	_In_ BOOLEAN dispatchLevel
	)
{
	UNREFERENCED_PARAMETER(dispatchLevel);

	TRACE_ENTER();

	if (pNetBufferList->Status != STATUS_SUCCESS)
	{
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD,
			"NPF_NetworkInjectionComplete: pNetBufferList->Status [status: %#x]\n",
			pNetBufferList->Status);
	}

	FwpsFreeCloneNetBufferList(pNetBufferList, 0);

	TRACE_EXIT();
	return;
}
Пример #9
0
static
NTSTATUS
InitWskData(
	OUT PIRP* pIrp,
	OUT PKEVENT CompletionEvent
	)
{
	ASSERT(pIrp);
	ASSERT(CompletionEvent);

	TRACE_ENTER();

	*pIrp = IoAllocateIrp(1, FALSE);
	if (!*pIrp)
	{
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "InitWskData()::IoAllocateIrp() failed with status 0x%08X\n", STATUS_INSUFFICIENT_RESOURCES);
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	KeInitializeEvent(CompletionEvent, SynchronizationEvent, FALSE);
	IoSetCompletionRoutine(*pIrp, CompletionRoutine, CompletionEvent, TRUE, TRUE, TRUE);
	TRACE_EXIT();
	return STATUS_SUCCESS;
}
Пример #10
0
//-------------------------------------------------------------------
NTSTATUS
NPF_Cleanup(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{

	POPEN_INSTANCE    Open;
	NDIS_STATUS     Status;
	PIO_STACK_LOCATION  IrpSp;
	LARGE_INTEGER ThreadDelay;
	ULONG localNumOpenInstances;

	TRACE_ENTER();

	IrpSp = IoGetCurrentIrpStackLocation(Irp);
	Open = IrpSp->FileObject->FsContext;
	
	TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Open = %p\n", Open);

	ASSERT(Open != NULL);

	NPF_CloseOpenInstance(Open);

	if (Open->ReadEvent != NULL)
		KeSetEvent(Open->ReadEvent,0,FALSE);

	NPF_CloseBinding(Open);
	
	// NOTE:
	// code commented out because the kernel dump feature is disabled
	//
	//if (AdapterAlreadyClosing == FALSE)
	//{

	//	
	//	 Unfreeze the consumer
	//	
	//	if(Open->mode & MODE_DUMP)
	//		NdisSetEvent(&Open->DumpEvent);
	//	else
	//		KeSetEvent(Open->ReadEvent,0,FALSE);

	//	//
	//	// If this instance is in dump mode, complete the dump and close the file
	//	//
	//	if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL)
	//	{
	//		NTSTATUS wres;

	//		ThreadDelay.QuadPart = -50000000;

	//		//
	//		// Wait the completion of the thread
	//		//
	//		wres = KeWaitForSingleObject(Open->DumpThreadObject,
	//			UserRequest,
	//			KernelMode,
	//			TRUE,
	//			&ThreadDelay);

	//		ObDereferenceObject(Open->DumpThreadObject);

	//		//
	//		// Flush and close the dump file
	//		//
	//		NPF_CloseDumpFile(Open);
	//	}
	//}


	//
	// release all the resources
	//
	NPF_ReleaseOpenInstanceResources(Open);

//	IrpSp->FileObject->FsContext = NULL;
	
	//
	// Decrease the counter of open instances
	//
	localNumOpenInstances = InterlockedDecrement(&g_NumOpenedInstances);
	TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Opened Instances: %u", localNumOpenInstances);

	if(localNumOpenInstances == 0)
	{
		//
		// Force a synchronization at the next NPF_Open().
		// This hopefully avoids the synchronization issues caused by hibernation or standby.
		//
		TIME_DESYNCHRONIZE(&G_Start_Time);
	}


	//
	// and complete the IRP with status success
	//
	Irp->IoStatus.Information = 0;
	Irp->IoStatus.Status = STATUS_SUCCESS;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	TRACE_EXIT();

	return(STATUS_SUCCESS);
}
Пример #11
0
VOID
NPF_ReleaseOpenInstanceResources(POPEN_INSTANCE pOpen)
{
		PKEVENT pEvent;
		UINT i;

		TRACE_ENTER();

		ASSERT(pOpen != NULL);
		ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Open= %p", pOpen);

		NdisFreePacketPool(pOpen->PacketPool);

#ifdef HAVE_BUGGY_TME_SUPPORT
		//
		// free mem_ex
		//
		pOpen->mem_ex.size = 0;
		if(pOpen->mem_ex.buffer != NULL)
			ExFreePool(pOpen->mem_ex.buffer);
#endif //HAVE_BUGGY_TME_SUPPORT

		//
		// Free the filter if it's present
		//
		if(pOpen->bpfprogram != NULL)
			ExFreePool(pOpen->bpfprogram);

//
// Jitted filters are supported on x86 (32bit) only
// 
#ifdef _X86_
		// Free the jitted filter if it's present
		if(pOpen->Filter != NULL)
			BPF_Destroy_JIT_Filter(pOpen->Filter);
#endif //_X86_

		//
		// Dereference the read event.
		//

		if (pOpen->ReadEvent != NULL)
            ObDereferenceObject(pOpen->ReadEvent);

		//
		// free the buffer
		// NOTE: the buffer is fragmented among the various CPUs, but the base pointer of the
		// allocated chunk of memory is stored in the first slot (pOpen->CpuData[0])
		//
		if (pOpen->Size > 0)
			ExFreePool(pOpen->CpuData[0].Buffer);

		//
		// free the per CPU spinlocks
		//
		for (i = 0; i < g_NCpu; i++)
		{
			NdisFreeSpinLock(&Open->CpuData[i].BufferLock);
		}

		//
		// Free the string with the name of the dump file
		//
		if(pOpen->DumpFileName.Buffer!=NULL)
			ExFreePool(pOpen->DumpFileName.Buffer);

		TRACE_EXIT();
}
Пример #12
0
NTSTATUS NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{

	PDEVICE_EXTENSION	DeviceExtension;
	POPEN_INSTANCE		Open;
	PIO_STACK_LOCATION  IrpSp;
	NDIS_STATUS			Status;
	NDIS_STATUS			ErrorStatus;
	UINT				i;
	PUCHAR				tpointer;
	PLIST_ENTRY			PacketListEntry;
	NTSTATUS			returnStatus;

//  
//	Old registry based WinPcap names
//
//	WCHAR				EventPrefix[MAX_WINPCAP_KEY_CHARS];
//	UINT				RegStrLen;

	TRACE_ENTER();

	DeviceExtension = DeviceObject->DeviceExtension;

	IrpSp = IoGetCurrentIrpStackLocation(Irp);

	//  allocate some memory for the open structure
	Open=ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_INSTANCE), '0OWA');

	if (Open==NULL) {
		// no memory
		Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	RtlZeroMemory(
		Open,
		sizeof(OPEN_INSTANCE)
		);

//  
//	Old registry based WinPcap names
//
//	//
//	// Get the Event names base from the registry
//	//
//	RegStrLen = sizeof(EventPrefix)/sizeof(EventPrefix[0]);
//
//	NPF_QueryWinpcapRegistryString(NPF_EVENTS_NAMES_REG_KEY_WC,
//		EventPrefix,
//		RegStrLen,
//		NPF_EVENTS_NAMES_WIDECHAR);
//
		
	Open->DeviceExtension=DeviceExtension;

	//  Allocate a packet pool for our xmit and receive packets
	NdisAllocatePacketPool(
		&Status,
		&Open->PacketPool,
		TRANSMIT_PACKETS,
		sizeof(PACKET_RESERVED));

	if (Status != NDIS_STATUS_SUCCESS) {

		TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Failed to allocate packet pool");

		ExFreePool(Open);
		Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	NdisInitializeEvent(&Open->WriteEvent);
	NdisInitializeEvent(&Open->NdisRequestEvent);
	NdisInitializeEvent(&Open->NdisWriteCompleteEvent);
	NdisInitializeEvent(&Open->DumpEvent);
	NdisAllocateSpinLock(&Open->MachineLock);
	NdisAllocateSpinLock(&Open->WriteLock);
	Open->WriteInProgress = FALSE;

	for (i = 0; i < g_NCpu; i++)
	{
		NdisAllocateSpinLock(&Open->CpuData[i].BufferLock);
	}

	NdisInitializeEvent(&Open->NdisOpenCloseCompleteEvent);

	//  list to hold irp's want to reset the adapter
	InitializeListHead(&Open->ResetIrpList);

	//  Initialize the request list
	KeInitializeSpinLock(&Open->RequestSpinLock);
	InitializeListHead(&Open->RequestList);

#ifdef HAVE_BUGGY_TME_SUPPORT
	// Initializes the extended memory of the NPF machine
	Open->mem_ex.buffer = ExAllocatePoolWithTag(NonPagedPool, DEFAULT_MEM_EX_SIZE, '2OWA');
	if((Open->mem_ex.buffer) == NULL)
	{
		//
		// no memory
		//
		ExFreePool(Open);
		Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	Open->mem_ex.size = DEFAULT_MEM_EX_SIZE;
	RtlZeroMemory(Open->mem_ex.buffer, DEFAULT_MEM_EX_SIZE);
#endif //HAVE_BUGGY_TME_SUPPORT


	//
	// Initialize the open instance
	//
	Open->bpfprogram = NULL;	//reset the filter
	Open->mode = MODE_CAPT;
	Open->Nbytes.QuadPart = 0;
	Open->Npackets.QuadPart = 0;
	Open->Nwrites = 1;
	Open->Multiple_Write_Counter = 0;
	Open->MinToCopy = 0;
	Open->TimeOut.QuadPart = (LONGLONG)1;
	Open->DumpFileName.Buffer = NULL;
	Open->DumpFileHandle = NULL;
#ifdef HAVE_BUGGY_TME_SUPPORT
	Open->tme.active = TME_NONE_ACTIVE;
#endif // HAVE_BUGGY_TME_SUPPORT
	Open->DumpLimitReached = FALSE;
	Open->MaxFrameSize = 0;
	Open->WriterSN=0;
	Open->ReaderSN=0;
	Open->Size=0;
	Open->SkipSentPackets = FALSE;
	Open->ReadEvent = NULL;

	//
	// we need to keep a counter of the pending IRPs
	// so that when the IRP_MJ_CLEANUP dispatcher gets called,
	// we can wait for those IRPs to be completed
	//
	Open->NumPendingIrps = 0;
	Open->ClosePending = FALSE;
	NdisAllocateSpinLock(&Open->OpenInUseLock);

	//
	//allocate the spinlock for the statistic counters
	//
	NdisAllocateSpinLock(&Open->CountersLock);

	//
	//  link up the request stored in our open block
	//
	for (i = 0 ; i < MAX_REQUESTS ; i++ ) 
	{
		NdisInitializeEvent(&Open->Requests[i].InternalRequestCompletedEvent);

		ExInterlockedInsertTailList(
			&Open->RequestList,
			&Open->Requests[i].ListElement,
			&Open->RequestSpinLock);
	}

	NdisResetEvent(&Open->NdisOpenCloseCompleteEvent);

	// 
	// set the proper binding flags before trying to open the MAC
	//
	Open->AdapterBindingStatus = ADAPTER_BOUND;
	Open->AdapterHandleUsageCounter = 0;
	NdisAllocateSpinLock(&Open->AdapterHandleLock);

	//
	//  Try to open the MAC
	//
	TRACE_MESSAGE2(PACKET_DEBUG_LOUD,"Opening the device %ws, BindingContext=%p",DeviceExtension->AdapterName.Buffer, Open);

	returnStatus = STATUS_SUCCESS;

	NdisOpenAdapter(
		&Status,
		&ErrorStatus,
		&Open->AdapterHandle,
		&Open->Medium,
		MediumArray,
		NUM_NDIS_MEDIA,
		g_NdisProtocolHandle,
		Open,
		&DeviceExtension->AdapterName,
		0,
		NULL);

	TRACE_MESSAGE1(PACKET_DEBUG_LOUD,"Opened the device, Status=%x",Status);

	if (Status == NDIS_STATUS_PENDING)
	{
		NdisWaitEvent(&Open->NdisOpenCloseCompleteEvent, 0);

		if (!NT_SUCCESS(Open->OpenCloseStatus))
		{
			returnStatus = Open->OpenCloseStatus;
		}
		else
		{
			returnStatus = STATUS_SUCCESS;
		}
	}
	else
	{
		//
		// request not pending, we know the result, and OpenComplete has not been called.
		//
		if (Status == NDIS_STATUS_SUCCESS)
		{
			returnStatus = STATUS_SUCCESS;
		}
		else
		{
			//
			// this is not completely correct, as we are converting an NDIS_STATUS to a NTSTATUS
			//
			returnStatus = Status;

		}
	}

	if (returnStatus == STATUS_SUCCESS)
	{
		ULONG localNumOpenedInstances;	
		//
		// complete the open
		//
		localNumOpenedInstances = InterlockedIncrement(&g_NumOpenedInstances);

		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Opened Instances: %u", localNumOpenedInstances);

		// Get the absolute value of the system boot time.
		// This is used for timestamp conversion.
		TIME_SYNCHRONIZE(&G_Start_Time);

		returnStatus = NPF_GetDeviceMTU(Open, Irp, &Open->MaxFrameSize);

		if (!NT_SUCCESS(returnStatus))
		{
			//
			// Close the binding
			//
			NPF_CloseBinding(Open);
		}
	}

	if (!NT_SUCCESS(returnStatus))
	{
		NPF_ReleaseOpenInstanceResources(Open);
		//
		// Free the open instance itself
		//
		ExFreePool(Open);
		
	}
	else
	{
		//  Save or open here
		IrpSp->FileObject->FsContext=Open;
	}

	Irp->IoStatus.Status = returnStatus;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	TRACE_EXIT();
	return returnStatus;
}
Пример #13
0
LONG
NTAPI
WSKSendTo_NBL(
	IN PWSK_SOCKET WskSocket,
	IN PNET_BUFFER_LIST	NetBufferList,
	IN ULONG BufferOffset,
	__in_opt PSOCKADDR RemoteAddress
	)
{
	KEVENT          CompletionEvent = { 0 };
	PIRP            Irp = NULL;
	WSK_BUF         WskBuffer = { 0 };
	LONG            BytesSent = SOCKET_ERROR;
	NTSTATUS        Status = STATUS_UNSUCCESSFUL;

	TRACE_ENTER();

	if (g_SocketsState != INITIALIZED || !WskSocket || !NetBufferList)
	{
		TRACE_EXIT();
		return SOCKET_ERROR;
	}

	Status = InitWskBuffer_NBL(NetBufferList, BufferOffset, &WskBuffer);
	if (!NT_SUCCESS(Status))
	{
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "WSKSendTo_NBL()::InitWskBuffer_NBL() failed with status 0x%08X\n", Status);
		TRACE_EXIT();
		return SOCKET_ERROR;
	}

	Status = InitWskData(&Irp, &CompletionEvent);
	if (!NT_SUCCESS(Status))
	{
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "WSKSendTo_NBL()::InitWskData() failed with status 0x%08X\n", Status);
		FreeWskBuffer_NBL(&WskBuffer);
		TRACE_EXIT();
		return SOCKET_ERROR;
	}

	Status = ((PWSK_PROVIDER_DATAGRAM_DISPATCH)WskSocket->Dispatch)->WskSendTo(
		WskSocket,
		&WskBuffer,
		0,
		RemoteAddress,
		0,
		NULL,
		Irp);
	if (Status == STATUS_PENDING)
	{
		KeWaitForSingleObject(&CompletionEvent, Executive, KernelMode, FALSE, NULL);
		Status = Irp->IoStatus.Status;
	}

	BytesSent = NT_SUCCESS(Status) ? (LONG)Irp->IoStatus.Information : SOCKET_ERROR;

	IoFreeIrp(Irp);
	FreeWskBuffer_NBL(&WskBuffer);
	TRACE_EXIT();
	return BytesSent;
}
Пример #14
0
NTSTATUS
NTAPI
NPF_WSKSendPacket_NBL(
	IN PNET_BUFFER_LIST NetBufferList
	)
{
	PMDL				pMdl = NULL;
	ULONG				BuffSize;
	PETHER_HEADER		pEthernetHdr;
	PDLT_NULL_HEADER	pDltNullHdr;
	NTSTATUS			status = STATUS_UNSUCCESSFUL;

	TRACE_ENTER();

	pMdl = NetBufferList->FirstNetBuffer->CurrentMdl;
	if (pMdl)
	{
		NdisQueryMdl(
			pMdl,
			&pEthernetHdr,
			&BuffSize,
			NormalPagePriority);
		pDltNullHdr = (PDLT_NULL_HEADER) pEthernetHdr;
	}
	else
	{
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "NPF_WSKSendPacket_NBL()::NetBufferList->FirstNetBuffer->CurrentMdl failed with pMdl 0x%p\n", pMdl);

		TRACE_EXIT();
		return status;
	}

	if (pEthernetHdr == NULL)
	{
		//
		//  The system is low on resources. Set up to handle failure
		//  below.
		//
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "NPF_WSKSendPacket_NBL()::NdisQueryMdl() failed with pEthernetHdr 0x%p\n", pEthernetHdr);

		TRACE_EXIT();
		return status;
	}

	if (g_DltNullMode)
	{
		if (pDltNullHdr->null_type == DLTNULLTYPE_IP)
		{
			status = WSKSendPacketInternal_NBL(NPF_LOOPBACK_SEND_TYPE_IPV4, NetBufferList, DLT_NULL_HDR_LEN);
		}
		else if (pDltNullHdr->null_type == DLTNULLTYPE_IPV6)
		{
			status = WSKSendPacketInternal_NBL(NPF_LOOPBACK_SEND_TYPE_IPV6, NetBufferList, DLT_NULL_HDR_LEN);
		}
		else
		{
			TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "NPF_WSKSendPacket_NBL() failed with status 0x%08X, not valid loopback IPv4 or IPv6 packet (DLT_NULL)\n", status);
		}
	}
	else
	{
		if (pEthernetHdr->ether_type == RtlUshortByteSwap(ETHERTYPE_IP))
		{
			status = WSKSendPacketInternal_NBL(NPF_LOOPBACK_SEND_TYPE_IPV4, NetBufferList, ETHER_HDR_LEN);
		}
		else if (pEthernetHdr->ether_type == RtlUshortByteSwap(ETHERTYPE_IPV6))
		{
			status = WSKSendPacketInternal_NBL(NPF_LOOPBACK_SEND_TYPE_IPV6, NetBufferList, ETHER_HDR_LEN);
		}
		else
		{
			TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "NPF_WSKSendPacket_NBL() failed with status 0x%08X, not valid loopback IPv4 or IPv6 packet\n", status);
		}
	}

	TRACE_EXIT();
	return status;
}
Пример #15
0
NTSTATUS
NTAPI
NPF_WSKInitSockets(
	)
{
	NTSTATUS		status = STATUS_SUCCESS;

	TRACE_ENTER();

	// IPv4 Socket Initialization
	g_IPv4Socket = WSKCreateSocket(AF_INET, SOCK_RAW, IPPROTO_NPCAP_LOOPBACK, WSK_FLAG_DATAGRAM_SOCKET);
	if (g_IPv4Socket == NULL)
	{
		status = STATUS_UNSUCCESSFUL;
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "NPF_WSKInitSockets()::WSKCreateSocket() failed with status 0x%08X\n", status);
		TRACE_EXIT();
		return status;
	}

	g_IPv4LocalAddress.sin_family = AF_INET;
	g_IPv4LocalAddress.sin_addr.s_addr = INADDR_ANY;
	// g_IPv4LocalAddress.sin_port = INADDR_PORT;

	// Bind Required
	status = WSKBind(g_IPv4Socket, (PSOCKADDR) &g_IPv4LocalAddress);
	if (!NT_SUCCESS(status))
	{
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "NPF_WSKInitSockets()::WSKBind() failed with status 0x%08X\n", status);
		WSKCloseSocket(g_IPv4Socket);
		g_IPv4Socket = NULL;
		TRACE_EXIT();
		return status;
	}

	g_IPv4RemoteAddress.sin_family = AF_INET;
	g_IPv4RemoteAddress.sin_addr.s_addr = HTON_LONG(INADDR_LOOPBACK);
	// g_IPv4RemoteAddress.sin_port = HTON_SHORT(LOG_PORT);

	////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// IPv6 Socket Initialization
	g_IPv6Socket = WSKCreateSocket(AF_INET6, SOCK_RAW, IPPROTO_NPCAP_LOOPBACK, WSK_FLAG_DATAGRAM_SOCKET);
	if (g_IPv6Socket == NULL)
	{
		status = STATUS_UNSUCCESSFUL;
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "NPF_WSKInitSockets()::WSKCreateSocket() failed with status 0x%08X\n", status);
		TRACE_EXIT();
		return status;
	}

	g_IPv6LocalAddress.sin6_family = AF_INET6;
	struct in6_addr in6AnyAddr = IN6ADDR_ANY_INIT;
	g_IPv6LocalAddress.sin6_addr = in6AnyAddr;
	// g_IPv6LocalAddress.sin_port = INADDR_PORT;

	// Bind Required
	status = WSKBind(g_IPv6Socket, (PSOCKADDR) &g_IPv6LocalAddress);
	if (!NT_SUCCESS(status))
	{
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "NPF_WSKInitSockets()::WSKBind() failed with status 0x%08X\n", status);
		WSKCloseSocket(g_IPv6Socket);
		g_IPv6Socket = NULL;
		TRACE_EXIT();
		return status;
	}

	g_IPv6RemoteAddress.sin6_family = AF_INET6;
	struct in6_addr in6LoopbackAddr = IN6ADDR_LOOPBACK_INIT;
	g_IPv6RemoteAddress.sin6_addr = in6LoopbackAddr;
	// g_IPv6RemoteAddress.sin_port = HTON_SHORT(LOG_PORT);

	TRACE_EXIT();
	return status;
}
Пример #16
0
void
NPF_NetworkClassify(
	_In_ const FWPS_INCOMING_VALUES* inFixedValues,
	_In_ const FWPS_INCOMING_METADATA_VALUES* inMetaValues,
	_Inout_opt_ void* layerData,
	_In_ const FWPS_FILTER* filter,
	_In_ UINT64 flowContext,
	_Inout_ FWPS_CLASSIFY_OUT* classifyOut
	)

#endif

{
	POPEN_INSTANCE		GroupOpen;
	POPEN_INSTANCE		TempOpen;
	NTSTATUS			status = STATUS_SUCCESS;
	UINT32				ipHeaderSize = 0;
	UINT32				bytesRetreated = 0;
	UINT32				bytesRetreatedEthernet = 0;
	INT32				iIPv4 = -1;
	INT32				iDrection = -1;
	BOOLEAN				bSelfSent = FALSE;
	PVOID				pContiguousData = NULL;
	NET_BUFFER*			pNetBuffer = 0;
	UCHAR				pPacketData[ETHER_HDR_LEN];
	PNET_BUFFER_LIST	pNetBufferList = (NET_BUFFER_LIST*) layerData;
	COMPARTMENT_ID		compartmentID = UNSPECIFIED_COMPARTMENT_ID;
	FWPS_PACKET_INJECTION_STATE injectionState = FWPS_PACKET_INJECTION_STATE_MAX;

#if(NTDDI_VERSION >= NTDDI_WIN7)
	UNREFERENCED_PARAMETER(classifyContext);
#endif
	UNREFERENCED_PARAMETER(filter);
	UNREFERENCED_PARAMETER(flowContext);

	// Make the default action.
	if (classifyOut->rights & FWPS_RIGHT_ACTION_WRITE)
		classifyOut->actionType = FWP_ACTION_CONTINUE;

#if(NTDDI_VERSION >= NTDDI_WIN7)
	// Filter out fragment packets and reassembled packets.
	if (inMetaValues->currentMetadataValues & FWPS_METADATA_FIELD_FRAGMENT_DATA)
	{
		return;
	}
	if (inMetaValues->currentMetadataValues & FWP_CONDITION_FLAG_IS_REASSEMBLED)
	{
		return;
	}
#endif

	TRACE_ENTER();

	// Get the packet protocol (IPv4 or IPv6) and the direction (Inbound or Outbound).
	if (inFixedValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V4 || inFixedValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V4)
	{
		iIPv4 = 1;
	}
	else // if (inFixedValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V6 || inFixedValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V6)
	{
		iIPv4 = 0;
	}
	if (inFixedValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V4 || inFixedValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V6)
	{
		iDrection = 0;
	}
	else // if (inFixedValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V4 || inFixedValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V6)
	{
		iDrection = 1;
	}

	if (inMetaValues->currentMetadataValues & FWPS_METADATA_FIELD_IP_HEADER_SIZE)
	{
		ipHeaderSize = inMetaValues->ipHeaderSize;
	}

	injectionState = FwpsQueryPacketInjectionState(iIPv4 ? g_InjectionHandle_IPv4 : g_InjectionHandle_IPv6,
		pNetBufferList,
		NULL);
	if (injectionState == FWPS_PACKET_INJECTED_BY_SELF ||
		injectionState == FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF)
	{
		TRACE_MESSAGE(PACKET_DEBUG_LOUD,
			"NPF_NetworkClassify: this packet is injected by ourself, let it go\n");

		TRACE_EXIT();
		return;
	}

	// Inbound: Initial offset is at the Transport Header, so retreat the size of the Ethernet Header and IP Header.
	// Outbound: Initial offset is at the IP Header, so just retreat the size of the Ethernet Header.
	// We retreated the packet in two phases: 1) retreat the IP Header (if has), 2) clone the packet and retreat the Ethernet Header.
	// We must NOT retreat the Ethernet Header on the original packet, or this will lead to BAD_POOL_CALLER Bluescreen.
	bytesRetreated = iDrection ? ipHeaderSize : 0;

	status = NdisRetreatNetBufferListDataStart(pNetBufferList,
		bytesRetreated,
		0,
		NULL,
		NULL);

	if (status != STATUS_SUCCESS)
	{
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD,
			"NPF_NetworkClassify: NdisRetreatNetBufferListDataStart(bytesRetreated) [status: %#x]\n",
			status);

		TRACE_EXIT();
		return;
	}

	//bSelfSent = NPF_IsPacketSelfSent(pNetBufferList, (BOOLEAN)iIPv4);
	bSelfSent = (iDrection == 0) ? FALSE : NPF_IsPacketSelfSent(pNetBufferList, (BOOLEAN) iIPv4);
	TRACE_MESSAGE1(PACKET_DEBUG_LOUD,
		"NPF_NetworkClassify: NPF_IsPacketSelfSent() [bSelfSent: %#x]\n",
		bSelfSent);

	if (bSelfSent)
	{
		NdisAdvanceNetBufferListDataStart(pNetBufferList,
			iIPv4 ? IP_HDR_LEN : IPV6_HDR_LEN,
			FALSE,
			0);
	}

	// Here if this NBL is sent by ourself, we will clone it starting from IP header and inject it into Network Layer send path.
	if (bSelfSent)
	{
		PNET_BUFFER_LIST pClonedNetBufferList_Injection;
		status = FwpsAllocateCloneNetBufferList(pNetBufferList, NULL, NULL, 0, &pClonedNetBufferList_Injection);
		if (status != STATUS_SUCCESS)
		{
			TRACE_MESSAGE1(PACKET_DEBUG_LOUD,
				"NPF_NetworkClassify: FwpsAllocateCloneNetBufferList(pClonedNetBufferList_Injection) [status: %#x]\n",
				status);

			goto Exit_WSK_IP_Retreated;
		}

		if (FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues,
			FWPS_METADATA_FIELD_COMPARTMENT_ID))
			compartmentID = (COMPARTMENT_ID)inMetaValues->compartmentId;

		// This cloned NBL will be freed in NPF_NetworkInjectionComplete function.
		status = FwpsInjectNetworkSendAsync(iIPv4 ? g_InjectionHandle_IPv4 : g_InjectionHandle_IPv6,
			NULL,
			0,
			compartmentID,
			pClonedNetBufferList_Injection,
			NPF_NetworkInjectionComplete,
			NULL);
		if (status != STATUS_SUCCESS)
		{
			TRACE_MESSAGE1(PACKET_DEBUG_LOUD,
				"NPF_NetworkClassify: FwpsInjectNetworkSendAsync() [status: %#x]\n",
				status);

			FwpsFreeCloneNetBufferList(pClonedNetBufferList_Injection, 0);
			goto Exit_WSK_IP_Retreated;
		}

		// We have successfully re-inject the cloned NBL, so remove this one.
		classifyOut->actionType = FWP_ACTION_BLOCK;
		classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB;
		classifyOut->rights ^= FWPS_RIGHT_ACTION_WRITE;
	}

	// We clone this NBL again, for packet reading operation.
	PNET_BUFFER_LIST pClonedNetBufferList;
	status = FwpsAllocateCloneNetBufferList(pNetBufferList, NULL, NULL, 0, &pClonedNetBufferList);
	if (status != STATUS_SUCCESS)
	{
		TRACE_MESSAGE1(PACKET_DEBUG_LOUD,
			"NPF_NetworkClassify: FwpsAllocateCloneNetBufferList() [status: %#x]\n",
			status);

		goto Exit_WSK_IP_Retreated;
	}

	bytesRetreatedEthernet = g_DltNullMode ? DLT_NULL_HDR_LEN : ETHER_HDR_LEN;
	status = NdisRetreatNetBufferListDataStart(pClonedNetBufferList,
		bytesRetreatedEthernet,
		0,
		0,
		0);
	if (status != STATUS_SUCCESS)
	{
		bytesRetreatedEthernet = 0;

		TRACE_MESSAGE1(PACKET_DEBUG_LOUD,
			"NPF_NetworkClassify: NdisRetreatNetBufferListDataStart(bytesRetreatedEthernet) [status: %#x]\n",
			status);

		goto Exit_Packet_Cloned;
	}

	pNetBuffer = NET_BUFFER_LIST_FIRST_NB(pClonedNetBufferList);
	while (pNetBuffer)
	{
		pContiguousData = NdisGetDataBuffer(pNetBuffer,
			bytesRetreatedEthernet,
			pPacketData,
			1,
			0);
		if (!pContiguousData)
		{
			status = STATUS_UNSUCCESSFUL;

			TRACE_MESSAGE1(PACKET_DEBUG_LOUD,
				"NPF_NetworkClassify: NdisGetDataBuffer() [status: %#x]\n",
				status);

			goto Exit_Ethernet_Retreated;
		}
		else
		{
			if (g_DltNullMode)
			{
				((PDLT_NULL_HEADER) pContiguousData)->null_type = iIPv4 ? DLTNULLTYPE_IP : DLTNULLTYPE_IPV6;
			}
			else
			{
				RtlZeroMemory(pContiguousData, ETHER_ADDR_LEN * 2);
				((PETHER_HEADER) pContiguousData)->ether_type = iIPv4 ? RtlUshortByteSwap(ETHERTYPE_IP) : RtlUshortByteSwap(ETHERTYPE_IPV6);
			}
		}

		pNetBuffer = pNetBuffer->Next;
	}

	// Send the loopback packets data to the user-mode code.
	if (g_LoopbackOpenGroupHead)
	{
		//get the 1st group adapter child
		GroupOpen = g_LoopbackOpenGroupHead->GroupNext;
	}
	else
	{
		// Should not come here
		GroupOpen = NULL;
	}

	while (GroupOpen != NULL)
	{
		TempOpen = GroupOpen;
		if (TempOpen->AdapterBindingStatus == ADAPTER_BOUND)
		{
			//let every group adapter receive the packets
			NPF_TapExForEachOpen(TempOpen, pClonedNetBufferList);
		}

		GroupOpen = TempOpen->GroupNext;
	}

Exit_Ethernet_Retreated:
	// Advance the offset back to the original position.
	NdisAdvanceNetBufferListDataStart(pClonedNetBufferList,
		bytesRetreatedEthernet,
		FALSE,
		0);

Exit_Packet_Cloned:
	FwpsFreeCloneNetBufferList(pClonedNetBufferList, 0);

Exit_WSK_IP_Retreated:
	if (bSelfSent)
	{
		status = NdisRetreatNetBufferListDataStart(pNetBufferList,
			iIPv4 ? IP_HDR_LEN : IPV6_HDR_LEN,
			0,
			NULL,
			NULL);

// 		if (status != STATUS_SUCCESS)
// 		{
// 			TRACE_MESSAGE1(PACKET_DEBUG_LOUD,
// 				"NPF_NetworkClassify: NdisRetreatNetBufferListDataStart(IP_HDR_LEN) [status: %#x]\n",
// 				status);
//
// 			goto Exit_IP_Retreated;
// 		}
	}

/*Exit_IP_Retreated:*/
	NdisAdvanceNetBufferListDataStart(pNetBufferList,
		bytesRetreated,
		FALSE,
		0);

// 	// print "protocol, direction, fragment, reassembled" info for the current packet.
// 
// 	int iFragment = -1;
// 	if (inMetaValues->currentMetadataValues & FWPS_METADATA_FIELD_FRAGMENT_DATA)
// 	{
// 		iFragment = 1;
// 	}
// 	else
// 	{
// 		iFragment = 0;
// 	}
// 
// 	int iReassembled = -1;
// 	if (inMetaValues->currentMetadataValues & FWP_CONDITION_FLAG_IS_REASSEMBLED)
// 	{
// 		iReassembled = 1;
// 	}
// 	else
// 	{
// 		iReassembled = 0;
// 	}
// 	IF_LOUD(DbgPrint("\n\nNPF_NetworkClassify: Loopback packet found !!! protocol=[%d] (ipv4=0, ipv6=1), direction=[%d] (out=0, in=1), fragment=[%d], reassembled=[%d]\n", iProtocol, iDrection, iFragment, iReassembled);)


	TRACE_EXIT();
	return;
}