#include "precomp.h" #include "driver.h" #include "dnsfirewall.tmh" BOOLEAN IsListEntryInList( PLIST_ENTRY pListEntry, PLIST_ENTRY pListHead ) { PLIST_ENTRY pCurrentLE, pLastLE; if (IsListEmpty(pListHead)) { return FALSE; } pCurrentLE = pListHead->Flink; pLastLE = pListHead->Blink; for (;;) { if (pCurrentLE == pListEntry) { return TRUE; } pCurrentLE = pCurrentLE->Flink; if (pCurrentLE == pLastLE) { break; } } return FALSE; } NTSTATUS dnsfirewallCoInitialize(PDEVICE_OBJECT deviceObject) { NTSTATUS status = STATUS_SUCCESS; TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Enter" ); InitializeListHead(&g_stFreeFileList); InitializeListHead(&g_stWaitForDoneFileList); InitializeListHead(&g_stWaitForQuery2FileList); InitializeListHead(&g_stWaitForSetFilterFileList); InitializeListHead(&g_stAcceptableList); InitializeListHead(&g_stUdpInboundList); InitializeListHead(&g_stUdpAcceptNotifyList); InitializeListHead(&g_stUdpALEAcceptRecvList); InitializeListHead(&g_stUdpALEAcceptPendedList); InitializeListHead(&g_stUdpALEFlowEstablishList); InitializeListHead(&g_stFlowedFileList); InitializeListHead(&g_stPendedPacketsQueue); KeInitializeEvent( &g_oWorkerEvent, NotificationEvent, FALSE ); KeInitializeEvent( &g_oWorkerDoneEvent, NotificationEvent, FALSE ); status = FwpsInjectionHandleCreate( AF_INET, FWPS_INJECTION_TYPE_STREAM | FWPS_INJECTION_TYPE_TRANSPORT | FWPS_INJECTION_TYPE_NETWORK, &g_hInjectionHandleV4 ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! FwpsInjectionHandleCreate for AF_INET failed with status %!STATUS!", status ); return status; } status = FwpsInjectionHandleCreate( AF_INET6, FWPS_INJECTION_TYPE_STREAM | FWPS_INJECTION_TYPE_TRANSPORT | FWPS_INJECTION_TYPE_NETWORK, &g_hInjectionHandleV6 ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! FwpsInjectionHandleCreate for AF_INET6 failed with status %!STATUS!", status ); return status; } status = dnsfirewallCoRegisterCallouts(deviceObject); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! dnsfirewallCoRegisterCallouts failed with status %!STATUS!", status ); return status; } TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit" ); return status; } NTSTATUS dnsfirewallCoRegisterCallouts( PDEVICE_OBJECT deviceObject ) { NTSTATUS status = STATUS_SUCCESS; FWPS_CALLOUT stCallout; TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Enter" ); RtlZeroMemory( &stCallout, sizeof(stCallout) ); stCallout.calloutKey = DNS_FIREWALL_INBOUND_TRANSPORT_CALLOUT_V4; //stCallout.flags = FWP_CALLOUT_FLAG_ENABLE_COMMIT_ADD_NOTIFY; stCallout.classifyFn = onInboundTransportV4Classify; stCallout.notifyFn = onFiltersChangeNotify; stCallout.flowDeleteFn = (FWPS_CALLOUT_FLOW_DELETE_NOTIFY_FN) NULL; status = FwpsCalloutRegister( deviceObject, &stCallout, &g_nInboundTransportV4Id ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! FwpsCalloutRegister failed with status %!STATUS!", status ); return status; } RtlZeroMemory( &stCallout, sizeof(stCallout) ); stCallout.calloutKey = DNS_FIREWALL_INBOUND_TRANSPORT_CALLOUT_V6; //stCallout.flags = FWP_CALLOUT_FLAG_ENABLE_COMMIT_ADD_NOTIFY; stCallout.classifyFn = onInboundTransportV6Classify; stCallout.notifyFn = onFiltersChangeNotify; stCallout.flowDeleteFn = (FWPS_CALLOUT_FLOW_DELETE_NOTIFY_FN) NULL; status = FwpsCalloutRegister( deviceObject, &stCallout, &g_nInboundTransportV6Id ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! FwpsCalloutRegister failed with status %!STATUS!", status ); return status; } stCallout.calloutKey = DNS_FIREWALL_ALE_ACCEPT_RECV_CALLOUT_V4; //stCallout.flags = FWP_CALLOUT_FLAG_ENABLE_COMMIT_ADD_NOTIFY; stCallout.classifyFn = onAleAcceptRecvV4Classify; stCallout.notifyFn = onFiltersChangeNotify; stCallout.flowDeleteFn = (FWPS_CALLOUT_FLOW_DELETE_NOTIFY_FN) NULL; status = FwpsCalloutRegister( deviceObject, &stCallout, &g_nAleAcceptRecvV4Id ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! FwpsCalloutRegister failed with status %!STATUS!", status ); return status; } RtlZeroMemory( &stCallout, sizeof(stCallout) ); stCallout.calloutKey = DNS_FIREWALL_ALE_ACCEPT_RECV_CALLOUT_V6; //stCallout.flags = FWP_CALLOUT_FLAG_ENABLE_COMMIT_ADD_NOTIFY; stCallout.classifyFn = onAleAcceptRecvV6Classify; stCallout.notifyFn = onFiltersChangeNotify; stCallout.flowDeleteFn = (FWPS_CALLOUT_FLOW_DELETE_NOTIFY_FN) NULL; status = FwpsCalloutRegister( deviceObject, &stCallout, &g_nAleAcceptRecvV6Id ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! FwpsCalloutRegister failed with status %!STATUS!", status ); return status; } // // We won't be called for flow deletion for the flow established layer // since we only establish a flow for the stream layer, so we don't // specify a flow deletion function. // RtlZeroMemory( &stCallout, sizeof(stCallout) ); stCallout.calloutKey = DNS_FIREWALL_ALE_FLOW_ESTABLISHED_CALLOUT_V4; //stCallout.flags = FWP_CALLOUT_FLAG_ENABLE_COMMIT_ADD_NOTIFY; stCallout.classifyFn = onAleFlowEstablishedV4Classify; stCallout.notifyFn = onFiltersChangeNotify; stCallout.flowDeleteFn = (FWPS_CALLOUT_FLOW_DELETE_NOTIFY_FN) NULL; status = FwpsCalloutRegister( deviceObject, &stCallout, &g_nAleFlowEstablishedV4Id ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! FwpsCalloutRegister failed with status %!STATUS!", status ); return status; } RtlZeroMemory( &stCallout, sizeof(stCallout) ); stCallout.calloutKey = DNS_FIREWALL_ALE_FLOW_ESTABLISHED_CALLOUT_V6; //stCallout.flags = FWP_CALLOUT_FLAG_ENABLE_COMMIT_ADD_NOTIFY; stCallout.classifyFn = onAleFlowEstablishedV6Classify; stCallout.notifyFn = onFiltersChangeNotify; stCallout.flowDeleteFn = (FWPS_CALLOUT_FLOW_DELETE_NOTIFY_FN) NULL; // We don't need a flow delete function at this layer. status = FwpsCalloutRegister( deviceObject, &stCallout, &g_nAleFlowEstablishedV6Id ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! FwpsCalloutRegister failed with status %!STATUS!", status ); return status; } RtlZeroMemory( &stCallout, sizeof(stCallout) ); stCallout.calloutKey = DSN_FIREWALL_STREAM_CALLOUT_V4; stCallout.flags = FWP_CALLOUT_FLAG_CONDITIONAL_ON_FLOW; // FWP_CALLOUT_FLAG_ENABLE_COMMIT_ADD_NOTIFY | stCallout.classifyFn = onStreamClassify; stCallout.notifyFn = onFiltersChangeNotify; stCallout.flowDeleteFn = onDnsFlowDeletion; status = FwpsCalloutRegister( deviceObject, &stCallout, &g_nStreamIdV4 ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! FwpsCalloutRegister failed with status %!STATUS!", status ); return status; } RtlZeroMemory( &stCallout, sizeof(stCallout) ); stCallout.calloutKey = DSN_FIREWALL_STREAM_CALLOUT_V6; stCallout.flags = FWP_CALLOUT_FLAG_CONDITIONAL_ON_FLOW; // FWP_CALLOUT_FLAG_ENABLE_COMMIT_ADD_NOTIFY | stCallout.classifyFn = onStreamClassify; stCallout.notifyFn = onFiltersChangeNotify; stCallout.flowDeleteFn = onDnsFlowDeletion; status = FwpsCalloutRegister( deviceObject, &stCallout, &g_nStreamIdV6 ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! FwpsCalloutRegister failed with status %!STATUS!", status ); return status; } RtlZeroMemory( &stCallout, sizeof(stCallout) ); stCallout.calloutKey = DSN_FIREWALL_DATAGRAM_DATA_CALLOUT_V4; stCallout.flags = FWP_CALLOUT_FLAG_CONDITIONAL_ON_FLOW; // FWP_CALLOUT_FLAG_ENABLE_COMMIT_ADD_NOTIFY | stCallout.classifyFn = onDatagramDataClassify; stCallout.notifyFn = onFiltersChangeNotify; stCallout.flowDeleteFn = onDnsFlowDeletion; status = FwpsCalloutRegister( deviceObject, &stCallout, &g_nDatagramIdV4 ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! FwpsCalloutRegister failed with status %!STATUS!", status ); return status; } RtlZeroMemory( &stCallout, sizeof(stCallout) ); stCallout.calloutKey = DSN_FIREWALL_DATAGRAM_DATA_CALLOUT_V6; stCallout.flags = FWP_CALLOUT_FLAG_CONDITIONAL_ON_FLOW; // FWP_CALLOUT_FLAG_ENABLE_COMMIT_ADD_NOTIFY | stCallout.classifyFn = onDatagramDataClassify; stCallout.notifyFn = onFiltersChangeNotify; stCallout.flowDeleteFn = onDnsFlowDeletion; status = FwpsCalloutRegister( deviceObject, &stCallout, &g_nDatagramIdV6 ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! FwpsCalloutRegister failed with status %!STATUS!", status ); return status; } TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit" ); return status; } void NTAPI onAleFlowEstablishedV4Classify( __in const FWPS_INCOMING_VALUES* inFixedValues, __in const FWPS_INCOMING_METADATA_VALUES* inMetaValues, __inout_opt void* layerData, _In_opt_ const void* classifyContext, __in const FWPS_FILTER* filter, __in UINT64 flowContext, __inout FWPS_CLASSIFY_OUT* classifyOut ) { PADDRESSES_DESCRIPTOR pAddressesDescriptor = NULL; UINT32 ulRemoteAddress, ulI, ulRemoteAddressN; int i; BOOLEAN bLocalNetwork = FALSE; PLIST_ENTRY pListEntry, pFirstLE; PFLOW_DATA pFlowContext = NULL, pFirstEstablishingFlowContext = NULL; WDFFILEOBJECT wdfFlowFileObject = NULL; IPPROTO enIpProto; UINT64 flowHandle = 0, uiOldFlowHandle; NTSTATUS status = STATUS_SUCCESS; BOOLEAN bEmpty; UINT32 ulInboundCount = 0; UINT16 usRemotePort; IN_ADDR stIpAddress; WCHAR szIpAddress[128]; LPWSTR pAddressEnd; BOOLEAN bTestIpV4; WDFREQUEST wdfPendedRequest; WDFMEMORY wdfOutputMemory; UNREFERENCED_PARAMETER(layerData); UNREFERENCED_PARAMETER(filter); UNREFERENCED_PARAMETER(classifyContext); UNREFERENCED_PARAMETER(flowContext); ASSERT(FWPS_LAYER_ALE_FLOW_ESTABLISHED_V4 == inFixedValues->layerId); if (!(classifyOut->rights & FWPS_RIGHT_ACTION_WRITE)) { return; } WdfObjectAcquireLock(g_wdfControlDevice); ulRemoteAddress = inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_REMOTE_ADDRESS].value.uint32; enIpProto = (IPPROTO) inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_PROTOCOL].value.uint8; usRemotePort = inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_REMOTE_PORT].value.uint16; ASSERT(FWPS_IS_METADATA_FIELD_PRESENT( inMetaValues, FWPS_METADATA_FIELD_FLOW_HANDLE) ); flowHandle = inMetaValues->flowHandle; ASSERT(0 != flowHandle); ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); bTestIpV4 = ((IPPROTO_UDP == enIpProto) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pAddressesDescriptor = WdfObjectGetTypedContext( g_wdfControlDevice, ADDRESSES_DESCRIPTOR ); if (NULL == pAddressesDescriptor) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (NULL == pAddressesDescriptor)" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL == pAddressesDescriptor->m_pDataArray) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (NULL == pAddressesDescriptor->m_pDataArray)" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (c_ulLocalHost == ulRemoteAddress) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPublicIpArray) { for (i = 0; im_nPublicIpCount; i++) { if (ulRemoteAddress == pAddressesDescriptor->m_pPublicIpArray[i]) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPrivateIpArray) { for (i = 0; im_nPrivateIpCount; i++) { if (ulRemoteAddress == pAddressesDescriptor->m_pPrivateIpArray[i]) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPublicRangeArray) { for (i = 0; im_nPublicRangeCount; i++) { if ((ulRemoteAddress >= pAddressesDescriptor->m_pPublicRangeArray[i]._ulLowValue) && (ulRemoteAddress <= pAddressesDescriptor->m_pPublicRangeArray[i]._ulHighValue) ) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPrivateRangeArray) { for (i = 0; im_nPrivateRangeCount; i++) { if ((ulRemoteAddress >= pAddressesDescriptor->m_pPrivateRangeArray[i]._ulLowValue) && (ulRemoteAddress <= pAddressesDescriptor->m_pPrivateRangeArray[i]._ulHighValue) ) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPublicSubnetArray) { for (i = 0; im_nPublicSubnetCount; i++) { UINT32 ulAddrPart = (ulRemoteAddress & pAddressesDescriptor->m_pPublicSubnetArray[i]._ulIpMask); if (ulAddrPart == pAddressesDescriptor->m_pPublicSubnetArray[i]._ulIpAddr) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPrivateSubnetArray) { for (i = 0; im_nPrivateSubnetCount; i++) { UINT32 ulAddrPart = (ulRemoteAddress & pAddressesDescriptor->m_pPrivateSubnetArray[i]._ulIpMask); if (ulAddrPart == pAddressesDescriptor->m_pPrivateSubnetArray[i]._ulIpAddr) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (IPPROTO_UDP == enIpProto) { if (!IsListEmpty(&g_stFlowedFileList)) { pListEntry = g_stFlowedFileList.Blink; pFirstLE = g_stFlowedFileList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if ((IPPROTO_UDP == pFlowContext->enIpProto) && (!pFlowContext->bIPv6)) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (usRemotePort == pFlowContext->usRemotePort) && pFlowContext->bUdpQueryClassifyPended) { switch (pFlowContext->enContextState) { case csUdpWaitPermitQuery2: case csUdpPermitQuery2Done: pFirstEstablishingFlowContext = pFlowContext; ulInboundCount++; break; } } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } if (ulInboundCount > 0) { ASSERT(1 == ulInboundCount); pFlowContext = pFirstEstablishingFlowContext; pFlowContext->bUdpQueryClassifyPended = FALSE; uiOldFlowHandle = pFlowContext->flowHandle; classifyOut->actionType = FWP_ACTION_PERMIT; if (uiOldFlowHandle != flowHandle) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Old Context for IpV4 Host %ws will Removed; clent.port = %hu;", szIpAddress, usRemotePort ); pFlowContext->flowHandle = flowHandle; status = FwpsFlowAssociateContext( flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4, (UINT64) pFlowContext ); ASSERT(NT_SUCCESS(status)); pFlowContext->bUdpQuery2Reestablish = TRUE; //if (bTestIpV4) //{ // TraceEvents( // TRACE_LEVEL_INFORMATION, // TRACE_DNSFIREWALL, // "%!FUNC! line:%!LINE! %!LEVEL! DNS Query from Tested IpV4 Host was Reestablished." // ); //} WdfObjectReleaseLock(g_wdfControlDevice); status = FwpsFlowRemoveContext( uiOldFlowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } return; } WdfObjectReleaseLock(g_wdfControlDevice); return; } } if (IsListEmpty(&g_stUdpALEFlowEstablishList)) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"g_stUdpALEFlowEstablishList\" is Empty!! Host IP = %ws; clent.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } pListEntry = g_stUdpALEFlowEstablishList.Blink; pFirstLE = g_stUdpALEFlowEstablishList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (usRemotePort == pFlowContext->usRemotePort)) { pFirstEstablishingFlowContext = pFlowContext; ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } if (0 == ulInboundCount) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Matched element in \"g_stUdpALEFlowEstablishList\" not Found!!" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } pFlowContext = pFirstEstablishingFlowContext; switch (pFlowContext->enContextState) { case csUdpAcceptedRecv: break; case csUdpWaitPermitQuery: case csUdpPermitQueryDone: if (!pFlowContext->bUdpQueryClassifyPended) { ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (g_bFiltersChangeInProgress | g_stFirewallConfig.bExternalClientBlocked) { pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } for (ulI = 0; ulI < g_stFirewallConfig.nBlackSubnetListLength; ulI++) { UINT32 ulAddrPart = (ulRemoteAddress & g_stFirewallConfig.aBlackSubnetList[ulI]._ulIpMask); if (ulAddrPart == g_stFirewallConfig.aBlackSubnetList[ulI]._ulIpAddr) { pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } } for (ulI = 0; ulI < g_stFirewallConfig.nBlackListLength; ulI++) { if (ulRemoteAddress == g_stFirewallConfig.aBlackListArray[ulI]) { pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } } if (pFlowContext->bUdpNotifyQuery) { if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! NOTIFY Query will remove from UDP-flow." ); } pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } pFlowContext->flowHandle = flowHandle; status = FwpsFlowAssociateContext( flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4, (UINT64) pFlowContext ); ASSERT(NT_SUCCESS(status)); if (!pFlowContext->bUdpQueryClassifyPended) { pFlowContext->enContextState = csUdpFlowEstablished; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); } else { stIpAddress.S_un.S_addr = pFlowContext->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Classify Packet was Injected for Host Ip = %ws; clent.port = %hu;", szIpAddress, pFlowContext->usRemotePort ); //ASSERT(FALSE); } if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host Insert to \"g_stFlowedFileList\"." ); } pFlowContext->enFlowDataOwner = foFlowedFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFlowedFileList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (IsListEmpty(&g_stAcceptableList)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"g_stAcceptableList\" is Empty!!" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; if (NULL != g_wdfWaitRestartQueue) { status = WdfIoQueueRetrieveNextRequest( g_wdfWaitRestartQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, &g_uiRestartStatus, sizeof(g_uiRestartStatus) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(g_uiRestartStatus) ); WdfObjectDelete(g_wdfWaitRestartQueue); g_wdfWaitRestartQueue = NULL; } WdfObjectReleaseLock(g_wdfControlDevice); return; } pListEntry = RemoveHeadList(&g_stAcceptableList); pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; pFlowContext->enIpProto = enIpProto; pFlowContext->nRemoteAddressV4 = ulRemoteAddress; pFlowContext->nRemoteAddressV4N = RtlUlongByteSwap(ulRemoteAddress); pFlowContext->usRemotePort = usRemotePort; pFlowContext->flowHandle = flowHandle; ASSERT(csWaitQueryStarted == pFlowContext->enContextState); status = FwpsFlowAssociateContext( flowHandle, FWPS_LAYER_STREAM_V4, g_nStreamIdV4, (UINT64) pFlowContext ); pFlowContext->enContextState = csTcpFlowEstablished; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); ASSERT(NT_SUCCESS(status)); if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host Insert to \"g_stFlowedFileList\"." ); } pFlowContext->enFlowDataOwner = foFlowedFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFlowedFileList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); } void NTAPI onAleFlowEstablishedV6Classify( __in const FWPS_INCOMING_VALUES* inFixedValues, __in const FWPS_INCOMING_METADATA_VALUES* inMetaValues, __inout_opt void* layerData, _In_opt_ const void* classifyContext, __in const FWPS_FILTER* filter, __in UINT64 flowContext, __inout FWPS_CLASSIFY_OUT* classifyOut ) { int i; PADDRESSES_DESCRIPTOR pAddressesDescriptor = NULL; FWP_BYTE_ARRAY16 *pRemoteAddress; BOOLEAN bLocalNetwork = FALSE; PLIST_ENTRY pListEntry, pFirstLE; PFLOW_DATA pFlowContext = NULL, pFirstEstablishingFlowContext = NULL; WDFFILEOBJECT wdfFlowFileObject = NULL; NTSTATUS status = STATUS_SUCCESS; IPPROTO enIpProto; UINT64 flowHandle = 0, uiOldFlowHandle; UINT32 ulI, ulInboundCount = 0; UINT16 usRemotePort; BOOLEAN bEmpty; IN6_ADDR stIp6Address; WCHAR szIpAddress[128]; LPWSTR pAddressEnd; WDFREQUEST wdfPendedRequest; WDFMEMORY wdfOutputMemory; UNREFERENCED_PARAMETER(layerData); UNREFERENCED_PARAMETER(filter); UNREFERENCED_PARAMETER(classifyContext); UNREFERENCED_PARAMETER(flowContext); ASSERT(FWPS_LAYER_ALE_FLOW_ESTABLISHED_V6 == inFixedValues->layerId); if (!(classifyOut->rights & FWPS_RIGHT_ACTION_WRITE)) { return; } WdfObjectAcquireLock(g_wdfControlDevice); pRemoteAddress = inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_IP_REMOTE_ADDRESS].value.byteArray16; enIpProto = (IPPROTO) inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_IP_PROTOCOL].value.uint8; usRemotePort = inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_IP_REMOTE_PORT].value.uint16; ASSERT(FWPS_IS_METADATA_FIELD_PRESENT( inMetaValues, FWPS_METADATA_FIELD_FLOW_HANDLE) ); flowHandle = inMetaValues->flowHandle; ASSERT(0 != flowHandle); pAddressesDescriptor = WdfObjectGetTypedContext( g_wdfControlDevice, ADDRESSES_DESCRIPTOR ); if (NULL == pAddressesDescriptor) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (NULL == pAddressesDescriptor)" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL == pAddressesDescriptor->m_pDataArray) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (NULL == pAddressesDescriptor->m_pDataArray)" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (!bfIPv6AddressInIPv6Subnet(pRemoteAddress, c_pGlobalIPv6Subnet)) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPublicIPV6AddrArray) { for (i = 0; im_nPublicIPV6AddrCount; i++) { if (bfIPv6AddressInIPv6Subnet(pRemoteAddress, &pAddressesDescriptor->m_pPublicIPV6AddrArray[i])) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPrivateIPV6AddrArray) { for (i = 0; im_nPrivateIPV6AddrCount; i++) { if (bfIPv6AddressInIPv6Subnet(pRemoteAddress, &pAddressesDescriptor->m_pPrivateIPV6AddrArray[i])) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (IPPROTO_UDP == enIpProto) { if (!IsListEmpty(&g_stFlowedFileList)) { pListEntry = g_stFlowedFileList.Blink; pFirstLE = g_stFlowedFileList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if ((IPPROTO_UDP == pFlowContext->enIpProto) && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6) && (usRemotePort == pFlowContext->usRemotePort) && pFlowContext->bUdpQueryClassifyPended) { switch (pFlowContext->enContextState) { case csUdpWaitPermitQuery2: case csUdpPermitQuery2Done: pFirstEstablishingFlowContext = pFlowContext; ulInboundCount++; break; } } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } if (ulInboundCount > 0) { ASSERT(1 == ulInboundCount); pFlowContext = pFirstEstablishingFlowContext; pFlowContext->bUdpQueryClassifyPended = FALSE; uiOldFlowHandle = pFlowContext->flowHandle; classifyOut->actionType = FWP_ACTION_PERMIT; if (uiOldFlowHandle != flowHandle) { RtlCopyMemory( &stIp6Address, pRemoteAddress, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Old Context for Host IP = %ws will Removed; clent.port = %hu;", szIpAddress, usRemotePort ); pFlowContext->flowHandle = flowHandle; status = FwpsFlowAssociateContext( flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6, (UINT64) pFlowContext ); ASSERT(NT_SUCCESS(status)); pFlowContext->bUdpQuery2Reestablish = TRUE; WdfObjectReleaseLock(g_wdfControlDevice); status = FwpsFlowRemoveContext( uiOldFlowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } return; } WdfObjectReleaseLock(g_wdfControlDevice); return; } } if (IsListEmpty(&g_stUdpALEFlowEstablishList)) { RtlCopyMemory( &stIp6Address, pRemoteAddress, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"g_stUdpALEFlowEstablishList\" is Empty!! Host IP = %ws; clent.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } pListEntry = g_stUdpALEFlowEstablishList.Blink; pFirstLE = g_stUdpALEFlowEstablishList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6) && (usRemotePort == pFlowContext->usRemotePort)) { pFirstEstablishingFlowContext = pFlowContext; ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } if (0 == ulInboundCount) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Matched element in \"g_stUdpALEFlowEstablishList\" not Found!!" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } pFlowContext = pFirstEstablishingFlowContext; switch (pFlowContext->enContextState) { case csUdpAcceptedRecv: break; case csUdpWaitPermitQuery: case csUdpPermitQueryDone: if (!pFlowContext->bUdpQueryClassifyPended) { ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (g_bFiltersChangeInProgress | g_stFirewallConfig.bExternalClientBlocked) { pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } for (ulI = 0; ulI < g_stFirewallConfig.nBlackListV6Length; ulI++) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &g_stFirewallConfig.aBlackListV6Array[ulI])) { pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } } if (pFlowContext->bUdpNotifyQuery) { pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } pFlowContext->flowHandle = flowHandle; status = FwpsFlowAssociateContext( flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6, (UINT64) pFlowContext ); ASSERT(NT_SUCCESS(status)); if (pFlowContext->bUdpQueryClassifyPended) { RtlCopyMemory( &stIp6Address, &pFlowContext->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Classify Packet was Injected for Host Ip = %ws; clent.port = %hu;", szIpAddress, pFlowContext->usRemotePort ); } else { pFlowContext->enContextState = csUdpFlowEstablished; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); } pFlowContext->enFlowDataOwner = foFlowedFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFlowedFileList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (IsListEmpty(&g_stAcceptableList)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"g_stAcceptableList\" is Empty!!" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; if (NULL != g_wdfWaitRestartQueue) { status = WdfIoQueueRetrieveNextRequest( g_wdfWaitRestartQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, &g_uiRestartStatus, sizeof(g_uiRestartStatus) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(g_uiRestartStatus) ); WdfObjectDelete(g_wdfWaitRestartQueue); g_wdfWaitRestartQueue = NULL; } WdfObjectReleaseLock(g_wdfControlDevice); return; } pListEntry = RemoveHeadList(&g_stAcceptableList); pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; pFlowContext->bIPv6 = TRUE; pFlowContext->enIpProto = enIpProto; IPv6CopyAddress(&pFlowContext->stRemoteAddressV6, pRemoteAddress); pFlowContext->usRemotePort = usRemotePort; pFlowContext->flowHandle = flowHandle; ASSERT(csWaitQueryStarted == pFlowContext->enContextState); status = FwpsFlowAssociateContext( flowHandle, FWPS_LAYER_STREAM_V6, g_nStreamIdV6, (UINT64) pFlowContext ); pFlowContext->enContextState = csTcpFlowEstablished; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); ASSERT(NT_SUCCESS(status)); pFlowContext->enFlowDataOwner = foFlowedFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFlowedFileList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); } NTSTATUS onFiltersChangeNotify( _In_ FWPS_CALLOUT_NOTIFY_TYPE notifyType, _In_ const GUID* filterKey, _Inout_ const FWPS_FILTER* filter ) { NTSTATUS status = STATUS_SUCCESS; if (FWPS_CALLOUT_NOTIFY_ADD_FILTER == notifyType) { if (NULL != filterKey) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Add WFP Filter with filterKey = %!GUID!", filterKey ); } else { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Add WFP Filter with filterKey = NULL" ); } } else if (FWPS_CALLOUT_NOTIFY_DELETE_FILTER == notifyType) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Delete WFP Filter" ); } else if (FWPS_CALLOUT_NOTIFY_ADD_FILTER_POST_COMMIT == notifyType) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Add WFP Filter Post Commit" ); } else { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal notifyType = %d", notifyType ); } TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! filterId = 0x%016I64X; subLayerWeight = 0x%04hX; flags = 0x%04hX; numFilterConditions = %u;", filter->filterId, filter->subLayerWeight, filter->flags, filter->numFilterConditions ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! action.type = 0x%08X; action.calloutId = 0x%08X; context = %016I64X; providerContext = %p;", filter->action.type, filter->action.calloutId, filter->context, filter->providerContext ); return status; } void NTAPI onStreamClassify( __in const FWPS_INCOMING_VALUES* inFixedValues, __in const FWPS_INCOMING_METADATA_VALUES* inMetaValues, __inout_opt void* layerData, _In_opt_ const void* classifyContext, __in const FWPS_FILTER* filter, __in UINT64 flowContext, __inout FWPS_CLASSIFY_OUT* classifyOut ) { FWP_DIRECTION enPacketDirection; WDFFILEOBJECT wdfFlowFileObject = NULL; PFLOW_DATA pFlowData; BOOLEAN bInbound; BOOLEAN bIPv6; FWPS_STREAM_CALLOUT_IO_PACKET* pStreamPacket; FWPS_STREAM_DATA0* pStreamBuffer; SIZE_T nStreamLength; UINT64 hFlowHandle; NTSTATUS status; WDFREQUEST wdfPendedRequest; WDFMEMORY wdfOutputMemory; UINT16 wMessageLength; SIZE_T nBytesCopied; WDFDEVICE wdfDeviceObject; WDFQUEUE wdfRequestQueue; PNET_BUFFER_LIST pNetBufferList = NULL; PMDL _pMdl; UINT16 usRemotePort; UINT32 ulRemoteAddress = 0, ulRemoteAddressN = 0; BOOLEAN bTestIpV4; UINT32 ulInboundCount = 0; PLIST_ENTRY pListEntry, pLastLE; PFLOW_DATA pFlowContext = NULL; IN6_ADDR stRemoteAddress; IN_ADDR stIpAddress; WCHAR szIpAddress[128]; LPWSTR pAddressEnd; BOOLEAN bEmpty; UNREFERENCED_PARAMETER(classifyContext); UNREFERENCED_PARAMETER(filter); UNREFERENCED_PARAMETER(inFixedValues); // // We don't have the necessary right to alter the classify, exit. // if ((classifyOut->rights & FWPS_RIGHT_ACTION_WRITE) == 0) { // // Cannot alter the action. // return; } wdfDeviceObject = g_wdfControlDevice; WdfObjectAcquireLock(wdfDeviceObject); pStreamPacket = (FWPS_STREAM_CALLOUT_IO_PACKET*) layerData; ASSERT(NULL != pStreamPacket); pStreamBuffer = pStreamPacket->streamData; nStreamLength = pStreamBuffer->dataLength; pFlowData = (PFLOW_DATA) flowContext; ASSERT(NULL != pFlowData); ASSERT(pFlowData == pFlowData->pThis); wdfFlowFileObject = pFlowData->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); bIPv6 = pFlowData->bIPv6; bInbound = (BOOLEAN) ((pStreamBuffer->flags & FWPS_STREAM_FLAG_RECEIVE) == FWPS_STREAM_FLAG_RECEIVE); enPacketDirection = (bInbound) ? FWP_DIRECTION_INBOUND : FWP_DIRECTION_OUTBOUND; pFlowData->enPacketDirection = enPacketDirection; ASSERT(FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_FLOW_HANDLE)); if (0 == nStreamLength) { _tcp_break_stream: ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if (bInbound) { pFlowData->enContextState = csTcpClientDisconnect; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); } else { pFlowData->enContextState = csTcpServerDisconnect; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); } classifyOut->actionType = FWP_ACTION_PERMIT; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; if ((NULL == pFlowData->pTcpResponceInjectBufferList) && (NULL == pFlowData->pTcpResponceBufferList) && (NULL == pFlowData->pTcpQueryInjectBufferList) && (NULL == pFlowData->pTcpQueryBufferList)) { WdfObjectReleaseLock(wdfDeviceObject); if (bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_STREAM_V6, g_nStreamIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_STREAM_V4, g_nStreamIdV4 ); } WdfObjectAcquireLock(wdfDeviceObject); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } } WdfObjectReleaseLock(wdfDeviceObject); return; } hFlowHandle = inMetaValues->flowHandle; ASSERT(hFlowHandle == pFlowData->flowHandle); switch (pFlowData->enContextState) { case csTcpFlowEstablished: goto _tcp_query_elaborate; case csTcpQueryMoreData01: goto _tcp_query_elaborate; case csTcpQueryMoreData02: _tcp_query_elaborate : ; ASSERT(bInbound); pFlowData->hTcpQueryFlowID = hFlowHandle; ASSERT(nStreamLength >= sizeof(UINT16)); FwpsCopyStreamDataToBuffer( pStreamBuffer, &wMessageLength, sizeof(wMessageLength), &nBytesCopied ); ASSERT(nBytesCopied == sizeof(wMessageLength)); wMessageLength = RtlUshortByteSwap(wMessageLength); if (nStreamLength < (SIZE_T) wMessageLength + sizeof(wMessageLength)) { classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; pStreamPacket->streamAction = FWPS_STREAM_ACTION_NEED_MORE_DATA; pStreamPacket->countBytesRequired = (UINT32) wMessageLength + sizeof(wMessageLength); switch (pFlowData->enContextState) { case csTcpWaitPermitResponce: pFlowData->enContextState = csTcpQueryMoreData02; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpWaitReplaceResponceDone: pFlowData->enContextState = csTcpQueryMoreData02; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpQueryMoreData02: pFlowData->enContextState = csTcpQueryMoreData02; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpPermitResponceDone: pFlowData->enContextState = csTcpQueryMoreData02; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpReplaceResponceDone: pFlowData->enContextState = csTcpQueryMoreData02; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpFlowEstablished: pFlowData->enContextState = csTcpQueryMoreData01; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpQueryMoreData01: pFlowData->enContextState = csTcpQueryMoreData01; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (switch (pFlowData->enContextState) default:) enContextState = %u", pFlowData->enContextState ); pFlowData->enContextState = csTcpQueryMoreData01; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; } break; } if ((SIZE_T) wMessageLength + 2 != nStreamLength) { bIPv6 = pFlowData->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowData->stRemoteAddressV6, sizeof(stRemoteAddress) ); pAddressEnd = RtlIpv6AddressToStringW( &stRemoteAddress, szIpAddress ); } else { ulRemoteAddress = pFlowData->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } usRemotePort = pFlowData->usRemotePort; TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Not valid DNS message format! Host %ws; clent.port = %hu; enContextState = %u;", szIpAddress, usRemotePort, pFlowData->enContextState ); goto _tcp_break_stream; } switch (pFlowData->enContextState) { case csTcpPermitResponceDone: case csTcpReplaceResponceDone: case csTcpWaitPermitResponce: case csTcpWaitReplaceResponceDone: case csTcpQueryMoreData02: wdfRequestQueue = pFlowData->wdfWaitTcpNewMessageQueue; break; case csTcpFlowEstablished: case csTcpQueryMoreData01: wdfRequestQueue = pFlowData->wdfWaitDnsQueryQueue; break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (switch (pFlowData->enContextState) default:) enContextState = %u", pFlowData->enContextState ); wdfRequestQueue = pFlowData->wdfWaitDnsQueryQueue; break; } ASSERT(NULL != wdfRequestQueue); status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); switch (pFlowData->enContextState) { case csTcpPermitResponceDone: case csTcpReplaceResponceDone: case csTcpWaitPermitResponce: case csTcpWaitReplaceResponceDone: case csTcpQueryMoreData02: pFlowData->wdfWaitTcpNewMessageQueue = NULL; break; default: pFlowData->wdfWaitDnsQueryQueue = NULL; break; } pFlowData->nTcpQueryLength = nStreamLength; status = FwpsCloneStreamData( pStreamBuffer, g_hNetBufferListPool, NULL, 0, &pNetBufferList ); ASSERT(NT_SUCCESS(status)); pFlowData->pTcpQueryBufferList = pNetBufferList; switch (pFlowData->enContextState) { case csTcpWaitPermitResponce: case csTcpWaitReplaceResponceDone: case csTcpQueryMoreData02: pFlowData->enContextState = csTcpWaitResponceInjectDone; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpFlowEstablished: case csTcpQueryMoreData01: case csTcpPermitResponceDone: case csTcpReplaceResponceDone: pFlowData->enContextState = csTcpWaitReadQuery; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; default: TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (switch (pFlowData->enContextState) default:) enContextState = %u", pFlowData->enContextState ); pFlowData->enContextState = csTcpWaitReadQuery; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; } status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowData, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectDelete(wdfRequestQueue); break; case csTcpPermitQueryDone: goto _tcp_responce_elaborate; case csTcpReplaceQueryDone: goto _tcp_responce_elaborate; case csTcpResponceMoreData01: goto _tcp_responce_elaborate; case csTcpWaitPermitQuery: goto _tcp_responce_elaborate; case csTcpWaitReplaceQueryDone: goto _tcp_responce_elaborate; case csTcpResponceMoreData02: goto _tcp_responce_elaborate; case csTcpResponceMoreData03: _tcp_responce_elaborate : ; switch (pFlowData->enContextState) { case csTcpPermitResponceDone: case csTcpReplaceResponceDone: case csTcpWaitPermitResponce: case csTcpWaitReplaceResponceDone: case csTcpResponceMoreData03: wdfRequestQueue = pFlowData->wdfWaitTcpNewMessageQueue; break; default: wdfRequestQueue = pFlowData->wdfWaitTcpResponceQueue; break; } ASSERT(NULL != wdfRequestQueue); status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); if (pStreamBuffer->flags&FWPS_STREAM_FLAG_SEND) { bInbound = FALSE; enPacketDirection = FWP_DIRECTION_OUTBOUND; pFlowData->enPacketDirection = enPacketDirection; } else { // ! (pStreamBuffer->flags&FWPS_STREAM_FLAG_SEND) NTSTATUS status1; TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid flow direction %!STATUS!", status ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; switch (pFlowData->enContextState) { case csTcpPermitQueryDone: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpPermitQueryDone\"" ); break; case csTcpReplaceQueryDone: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpReplaceQueryDone\"" ); break; case csTcpResponceMoreData01: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpResponceMoreData01\"" ); break; case csTcpWaitPermitQuery: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpWaitPermitQuery\"" ); pNetBufferList = pFlowData->pTcpQueryBufferList; if (NULL != pNetBufferList) { FwpsDiscardClonedStreamData( pNetBufferList, 0, FALSE ); pFlowData->pTcpQueryBufferList = NULL; } break; case csTcpWaitReplaceQueryDone: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpWaitReplaceQueryDone\"" ); pNetBufferList = pFlowData->pTcpQueryInjectBufferList; if (NULL != pNetBufferList) { FwpsFreeNetBufferList( pNetBufferList ); pFlowData->pTcpQueryInjectBufferList = NULL; _pMdl = pFlowData->pTcpQueryMdl; ASSERT(NULL != _pMdl); IoFreeMdl(_pMdl); ExFreePoolWithTag( _pMdl->MappedSystemVa, POOL_TAG ); pFlowData->pTcpQueryMdl = NULL; } break; case csTcpResponceMoreData02: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpResponceMoreData02\"" ); break; case csTcpResponceMoreData03: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpResponceMoreData03\"" ); break; case csTcpPermitResponceDone: break; case csTcpReplaceResponceDone: break; case csTcpWaitPermitResponce: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpWaitPermitResponce\"" ); pNetBufferList = pFlowData->pTcpResponceBufferList; if (NULL != pNetBufferList) { FwpsDiscardClonedStreamData( pNetBufferList, 0, FALSE ); pFlowData->pTcpResponceBufferList = NULL; } break; case csTcpWaitReplaceResponceDone: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpWaitReplaceResponceDone\"" ); pNetBufferList = pFlowData->pTcpResponceInjectBufferList; if (NULL != pNetBufferList) { FwpsFreeNetBufferList( pNetBufferList ); pFlowData->pTcpResponceInjectBufferList = NULL; _pMdl = pFlowData->pTcpResponceMdl; ASSERT(NULL != _pMdl); IoFreeMdl(_pMdl); ExFreePoolWithTag( _pMdl->MappedSystemVa, POOL_TAG ); pFlowData->pTcpResponceMdl = NULL; } break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid State Superintendent of State machine. enContextState = %u", pFlowData->enContextState ); break; } ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } pFlowData->enContextState = csTcpIllegalInbound; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); WdfObjectReleaseLock(wdfDeviceObject); if (bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_STREAM_V6, g_nStreamIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_STREAM_V4, g_nStreamIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } WdfObjectAcquireLock(wdfDeviceObject); if ((STATUS_SUCCESS == status) || (STATUS_PENDING == status)) { WdfObjectReleaseLock(wdfDeviceObject); return; } pFlowData->enContextState = csDnsError; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); status1 = status; wdfRequestQueue = pFlowData->wdfWaitFlowDoneQueue; pFlowData->wdfWaitFlowDoneQueue = NULL; if (NULL != wdfRequestQueue) { status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowData, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status1, sizeof(FLOW_DATA) ); } WdfObjectDelete(wdfRequestQueue); } WdfObjectReleaseLock(wdfDeviceObject); return; } // !bInbound pFlowData->hTcpResponceFlowID = hFlowHandle; ASSERT(nStreamLength >= sizeof(UINT16)); FwpsCopyStreamDataToBuffer( pStreamBuffer, &wMessageLength, sizeof(wMessageLength), &nBytesCopied ); ASSERT(nBytesCopied == sizeof(wMessageLength)); wMessageLength = RtlUshortByteSwap(wMessageLength); if (nStreamLength < (SIZE_T) wMessageLength + 2) { classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; pStreamPacket->streamAction = FWPS_STREAM_ACTION_NEED_MORE_DATA; pStreamPacket->countBytesRequired = (UINT32) wMessageLength + 2; switch (pFlowData->enContextState) { case csTcpPermitQueryDone: pFlowData->enContextState = csTcpResponceMoreData01; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpReplaceQueryDone: pFlowData->enContextState = csTcpResponceMoreData01; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpPermitResponceDone: pFlowData->enContextState = csTcpResponceMoreData01; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpReplaceResponceDone: pFlowData->enContextState = csTcpResponceMoreData01; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpResponceMoreData01: pFlowData->enContextState = csTcpResponceMoreData01; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpWaitPermitQuery: pFlowData->enContextState = csTcpResponceMoreData02; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpWaitReplaceQueryDone: pFlowData->enContextState = csTcpResponceMoreData02; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpResponceMoreData02: pFlowData->enContextState = csTcpResponceMoreData02; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpWaitPermitResponce: pFlowData->enContextState = csTcpResponceMoreData03; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpWaitReplaceResponceDone: pFlowData->enContextState = csTcpResponceMoreData03; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpResponceMoreData03: pFlowData->enContextState = csTcpResponceMoreData03; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid State Superintendent of State machine. enContextState = %u", pFlowData->enContextState ); break; } WdfObjectDelete(wdfRequestQueue); break; } // !(nStreamLength < (SIZE_T) wMessageLength + 2) ASSERT((SIZE_T) wMessageLength + sizeof(wMessageLength) == nStreamLength); switch (pFlowData->enContextState) { case csTcpPermitResponceDone: case csTcpReplaceResponceDone: case csTcpWaitPermitResponce: case csTcpWaitReplaceResponceDone: case csTcpResponceMoreData03: pFlowData->wdfWaitTcpNewMessageQueue = NULL; break; default: pFlowData->wdfWaitTcpResponceQueue = NULL; break; } pFlowData->nTcpResponceLength = nStreamLength; status = FwpsCloneStreamData( pStreamBuffer, g_hNetBufferListPool, NULL, 0, &pFlowData->pTcpResponceBufferList ); ASSERT(NT_SUCCESS(status)); switch (pFlowData->enContextState) { case csTcpPermitQueryDone: pFlowData->enContextState = csTcpWaitReadResponce; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpReplaceQueryDone: pFlowData->enContextState = csTcpWaitReadResponce; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpResponceMoreData01: pFlowData->enContextState = csTcpWaitReadResponce; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpPermitResponceDone: pFlowData->enContextState = csTcpWaitReadResponce; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpReplaceResponceDone: pFlowData->enContextState = csTcpWaitReadResponce; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpWaitPermitQuery: pFlowData->enContextState = csTcpWaitQueryInjectDone; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpWaitReplaceQueryDone: pFlowData->enContextState = csTcpWaitQueryInjectDone; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpResponceMoreData02: pFlowData->enContextState = csTcpWaitQueryInjectDone; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpWaitPermitResponce: pFlowData->enContextState = csTcpWaitResponceInjectDone; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpWaitReplaceResponceDone: pFlowData->enContextState = csTcpWaitResponceInjectDone; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpResponceMoreData03: pFlowData->enContextState = csTcpWaitResponceInjectDone; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid State Superintendent of State machine. enContextState = %u", pFlowData->enContextState ); break; } status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowData, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectDelete(wdfRequestQueue); break; } TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; switch (pFlowData->enContextState) { case csTcpPermitQueryDone: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpPermitQueryDone\"" ); break; case csTcpReplaceQueryDone: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpReplaceQueryDone\"" ); break; case csTcpResponceMoreData01: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpResponceMoreData01\"" ); break; case csTcpWaitPermitQuery: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpWaitPermitQuery\"" ); pNetBufferList = pFlowData->pTcpQueryBufferList; if (NULL != pNetBufferList) { FwpsDiscardClonedStreamData( pNetBufferList, 0, FALSE ); pFlowData->pTcpQueryBufferList = NULL; } break; case csTcpWaitReplaceQueryDone: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpWaitReplaceQueryDone\"" ); pNetBufferList = pFlowData->pTcpQueryInjectBufferList; if (NULL != pNetBufferList) { FwpsFreeNetBufferList( pNetBufferList ); pFlowData->pTcpQueryInjectBufferList = NULL; _pMdl = pFlowData->pTcpQueryMdl; ASSERT(NULL != _pMdl); IoFreeMdl(_pMdl); ExFreePoolWithTag( _pMdl->MappedSystemVa, POOL_TAG ); pFlowData->pTcpQueryMdl = NULL; } break; case csTcpResponceMoreData02: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpResponceMoreData02\"" ); break; case csTcpResponceMoreData03: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpResponceMoreData03\"" ); break; case csTcpPermitResponceDone: break; case csTcpReplaceResponceDone: break; case csTcpWaitPermitResponce: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpWaitPermitResponce\"" ); pNetBufferList = pFlowData->pTcpResponceBufferList; if (NULL != pNetBufferList) { FwpsDiscardClonedStreamData( pNetBufferList, 0, FALSE ); pFlowData->pTcpResponceBufferList = NULL; } break; case csTcpWaitReplaceResponceDone: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csTcpWaitReplaceResponceDone\"" ); pNetBufferList = pFlowData->pTcpResponceInjectBufferList; if (NULL != pNetBufferList) { FwpsFreeNetBufferList( pNetBufferList ); pFlowData->pTcpResponceInjectBufferList = NULL; _pMdl = pFlowData->pTcpResponceMdl; ASSERT(NULL != _pMdl); IoFreeMdl(_pMdl); ExFreePoolWithTag( _pMdl->MappedSystemVa, POOL_TAG ); pFlowData->pTcpResponceMdl = NULL; } break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid State Superintendent of State machine. enContextState = %u", pFlowData->enContextState ); break; } WdfObjectDelete(wdfRequestQueue); switch (pFlowData->enContextState) { case csTcpPermitResponceDone: case csTcpReplaceResponceDone: case csTcpWaitPermitResponce: case csTcpWaitReplaceResponceDone: case csTcpResponceMoreData03: pFlowData->wdfWaitTcpNewMessageQueue = NULL; break; default: pFlowData->wdfWaitTcpResponceQueue = NULL; break; } ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } pFlowData->enContextState = csDnsError; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); WdfObjectReleaseLock(wdfDeviceObject); if (bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_STREAM_V6, g_nStreamIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_STREAM_V4, g_nStreamIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } return; case csTcpPermitResponceDone: goto _cont15; case csTcpReplaceResponceDone: goto _cont15; case csTcpWaitPermitResponce: goto _cont15; case csTcpWaitReplaceResponceDone: _cont15 : if (bInbound) goto _tcp_query_elaborate; goto _tcp_responce_elaborate; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid State Superintendent of State machine. enContextState = %u", pFlowData->enContextState ); break; } WdfObjectReleaseLock(wdfDeviceObject); } void NTAPI onDnsFlowDeletion( __in UINT16 layerId, __in UINT32 calloutId, __in UINT64 flowContext ) { WDFFILEOBJECT wdfFlowFileObject; PFLOW_DATA pFlowData; WDFREQUEST wdfPendedRequest = NULL; NTSTATUS status = STATUS_SUCCESS, status1 = STATUS_SUCCESS; WDFMEMORY wdfOutputMemory; BOOLEAN bListEmpty; int j, nFileIndex, nThreadIndex; WDFDEVICE wdfDeviceObject; WDFQUEUE wdfRequestQueue = NULL; PNET_BUFFER_LIST pNetBufferList; PMDL _pMdl; WDFQUEUE wdfFlowQueue; ULONG_PTR Information; WSACMSGHDR* _pControlData = NULL; BOOLEAN bTestIpV4 = FALSE; BOOLEAN bIPv6; UINT32 ulRemoteAddress = 0, ulRemoteAddressN = 0; IN_ADDR stIpAddress; WCHAR szIpAddress[128]; LPWSTR pAddressEnd; UINT16 usRemotePort; IN6_ADDR stIp6Address; IPPROTO enIpProto; UINT32 ulInboundCount; PLIST_ENTRY pListEntry, pLastLE; PFLOW_DATA pFlowContext = NULL; IN6_ADDR stRemoteAddress; BOOLEAN bEmpty; UNREFERENCED_PARAMETER(layerId); UNREFERENCED_PARAMETER(calloutId); pFlowData = (PFLOW_DATA) flowContext; if (NULL == pFlowData) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (NULL == pFlowData)" ); return; } if (NULL == pFlowData->pThis) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (NULL == pFlowData->pThis)" ); return; } if (pFlowData != pFlowData->pThis) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (pFlowData != pFlowData->pThis)" ); return; } if (0 == pFlowData->flowHandle) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (0 == pFlowData->flowHandle)" ); return; } wdfFlowFileObject = pFlowData->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfDeviceObject = g_wdfControlDevice; WdfObjectAcquireLock(wdfDeviceObject); bIPv6 = pFlowData->bIPv6; usRemotePort = pFlowData->usRemotePort; enIpProto = pFlowData->enIpProto; if (!bIPv6) { ulRemoteAddress = pFlowData->nRemoteAddressV4; ulRemoteAddressN = pFlowData->nRemoteAddressV4N; bTestIpV4 = ((IPPROTO_UDP == enIpProto) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } } if (pFlowData->bUdpQuery2Reestablish) { pFlowData->bUdpQuery2Reestablish = FALSE; switch (pFlowData->enContextState) { case csUdpWaitPermitQuery2: case csUdpPermitQuery2Done: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on (pFlowData->bUdpQuery2Reestablish)." ); } WdfObjectReleaseLock(wdfDeviceObject); return; } } j = 1; pFlowData->enContextState = csFlowDeleted; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); switch (pFlowData->arContextStateStack[j]) { case csTcpQueryDiscarded: ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } j++; switch (pFlowData->arContextStateStack[j]) { case csTcpWaitApprovalQuery: status1 = STATUS_END_OF_FILE; break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Driver State = %u", (UINT32) pFlowData->arContextStateStack[j] ); //ASSERT(FALSE); status1 = STATUS_UNEXPECTED_IO_ERROR; } break; case csUdpFlowCancel: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpFlowCancel\"." ); } j++; status1 = STATUS_END_OF_FILE; switch (pFlowData->arContextStateStack[j]) { case csUdpFlowEstablished: wdfRequestQueue = pFlowData->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpWaitReadQuery: case csUdpWaitApprovalQuery: pNetBufferList = pFlowData->pUdpQueryBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQueryBufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpPermitQueryPended: if (IsListEntryInList(&pFlowData->threadListEntry, &g_stPendedPacketsQueue)) { bListEmpty = RemoveEntryList(&pFlowData->threadListEntry); } case csUdpWaitPermitQuery: pNetBufferList = pFlowData->pUdpQueryCloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQueryCloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } wdfRequestQueue = pFlowData->wdfUdpQueryPermitQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfUdpQueryPermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpPermitQueryDone: wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpWaitResponce1Pended: if (IsListEntryInList(&pFlowData->threadListEntry, &g_stPendedPacketsQueue)) { bListEmpty = RemoveEntryList(&pFlowData->threadListEntry); } pNetBufferList = pFlowData->pUdpResponceBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponceBufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } _pControlData = pFlowData->stUdpResponceSendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponceSendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpWaitResponce1: pNetBufferList = pFlowData->pUdpResponceCloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponceCloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } _pControlData = pFlowData->stUdpResponceSendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponceSendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpWaitReadQuery2: case csUdpWaitApprovalQuery2: pNetBufferList = pFlowData->pUdpQuery2BufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQuery2BufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpPermitQuery2Pended: if (IsListEntryInList(&pFlowData->threadListEntry, &g_stPendedPacketsQueue)) { bListEmpty = RemoveEntryList(&pFlowData->threadListEntry); } case csUdpWaitPermitQuery2: pNetBufferList = pFlowData->pUdpQuery2CloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQuery2CloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } wdfRequestQueue = pFlowData->wdfUdpQuery2PermitQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfUdpQuery2PermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpPermitQuery2Done: wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpWaitResponce2Pended: if (IsListEntryInList(&pFlowData->threadListEntry, &g_stPendedPacketsQueue)) { bListEmpty = RemoveEntryList(&pFlowData->threadListEntry); } pNetBufferList = pFlowData->pUdpResponce2BufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponce2BufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } _pControlData = pFlowData->stUdpResponce2SendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponce2SendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpWaitResponce2: pNetBufferList = pFlowData->pUdpResponce2CloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponce2CloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } _pControlData = pFlowData->stUdpResponce2SendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponce2SendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Driver State = %u", (UINT32) pFlowData->arContextStateStack[j] ); //ASSERT(FALSE); status1 = STATUS_UNEXPECTED_IO_ERROR; } break; case csUdpFlowSetFirewallEvent: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpFlowSetFirewallEvent\"." ); } j++; status1 = STATUS_NO_MORE_ENTRIES; pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; switch (pFlowData->arContextStateStack[j]) { case csUdpFlowEstablished: wdfRequestQueue = pFlowData->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpWaitReadQuery: case csUdpWaitApprovalQuery: pNetBufferList = pFlowData->pUdpQueryBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQueryBufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpPermitQueryPended: if (IsListEntryInList(&pFlowData->threadListEntry, &g_stPendedPacketsQueue)) { bListEmpty = RemoveEntryList(&pFlowData->threadListEntry); } case csUdpWaitPermitQuery: pNetBufferList = pFlowData->pUdpQueryCloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQueryCloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } wdfRequestQueue = pFlowData->wdfUdpQueryPermitQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfUdpQueryPermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpPermitQueryDone: wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpWaitResponce1Pended: if (IsListEntryInList(&pFlowData->threadListEntry, &g_stPendedPacketsQueue)) { bListEmpty = RemoveEntryList(&pFlowData->threadListEntry); } pNetBufferList = pFlowData->pUdpResponceBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponceBufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } _pControlData = pFlowData->stUdpResponceSendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponceSendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpWaitResponce1: pNetBufferList = pFlowData->pUdpResponceCloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponceCloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } _pControlData = pFlowData->stUdpResponceSendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponceSendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpWaitReadQuery2: case csUdpWaitApprovalQuery2: pNetBufferList = pFlowData->pUdpQuery2BufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQuery2BufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } break; case csUdpPermitQuery2Pended: if (IsListEntryInList(&pFlowData->threadListEntry, &g_stPendedPacketsQueue)) { bListEmpty = RemoveEntryList(&pFlowData->threadListEntry); } case csUdpWaitPermitQuery2: pNetBufferList = pFlowData->pUdpQuery2CloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQuery2CloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } wdfRequestQueue = pFlowData->wdfUdpQuery2PermitQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfUdpQuery2PermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpPermitQuery2Done: break; case csUdpWaitResponce2Pended: if (IsListEntryInList(&pFlowData->threadListEntry, &g_stPendedPacketsQueue)) { bListEmpty = RemoveEntryList(&pFlowData->threadListEntry); } pNetBufferList = pFlowData->pUdpResponce2BufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponce2BufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } _pControlData = pFlowData->stUdpResponce2SendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponce2SendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); break; case csUdpWaitResponce2: pNetBufferList = pFlowData->pUdpResponce2CloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponce2CloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } _pControlData = pFlowData->stUdpResponce2SendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponce2SendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); break; case csUdpFlow1Done: wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Driver State = %u", (UINT32) pFlowData->arContextStateStack[j] ); //ASSERT(FALSE); status1 = STATUS_UNEXPECTED_IO_ERROR; } break; case csUdpWaitReplaceQuery2: case csUdpWaitReplaceQuery: ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } j++; TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! UDP Query Replace operation not Implemented on previos Driver State = %u", (UINT32) pFlowData->arContextStateStack[j] ); status1 = STATUS_NOT_IMPLEMENTED; break; case csUdpQuery2Discarded: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpQuery2Discarded\"." ); } ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } j++; switch (pFlowData->arContextStateStack[j]) { case csUdpWaitApprovalQuery2: status1 = STATUS_END_OF_FILE; break; case csUdpQuery2Discarded: status1 = STATUS_END_OF_FILE; break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Driver State = %u", (UINT32) pFlowData->arContextStateStack[j] ); //ASSERT(FALSE); status1 = STATUS_UNEXPECTED_IO_ERROR; } break; case csUdpQueryDiscarded: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpQueryDiscarded\"." ); } ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } j++; switch (pFlowData->arContextStateStack[j]) { case csUdpWaitApprovalQuery: status1 = STATUS_END_OF_FILE; break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Driver State = %u", (UINT32) pFlowData->arContextStateStack[j] ); //ASSERT(FALSE); status1 = STATUS_UNEXPECTED_IO_ERROR; } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csFlowDeleted: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csFlowDeleted\"." ); } pNetBufferList = pFlowData->pUdpQueryBufferList; if (NULL != pNetBufferList) { FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); pFlowData->pUdpQueryBufferList = NULL; } pNetBufferList = pFlowData->pUdpQueryCloneBufferList; if (NULL != pNetBufferList) { FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); pFlowData->pUdpQueryCloneBufferList = NULL; } pNetBufferList = pFlowData->pUdpQuery2BufferList; if (NULL != pNetBufferList) { FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); pFlowData->pUdpQuery2BufferList = NULL; } pNetBufferList = pFlowData->pUdpQuery2CloneBufferList; if (NULL != pNetBufferList) { FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); pFlowData->pUdpQuery2CloneBufferList = NULL; } pNetBufferList = pFlowData->pTcpQueryBufferList; if (NULL != pNetBufferList) { FwpsDiscardClonedStreamData( pNetBufferList, 0, FALSE ); pFlowData->pTcpQueryBufferList = NULL; } pNetBufferList = pFlowData->pTcpQueryInjectBufferList; if (NULL != pNetBufferList) { FwpsFreeNetBufferList0(pNetBufferList); pFlowData->pTcpQueryInjectBufferList = NULL; _pMdl = pFlowData->pTcpQueryMdl; if (NULL != _pMdl) { IoFreeMdl(_pMdl); ExFreePoolWithTag( _pMdl->MappedSystemVa, POOL_TAG ); pFlowData->pTcpQueryMdl = NULL; } } pNetBufferList = pFlowData->pTcpResponceBufferList; if (NULL != pNetBufferList) { FwpsDiscardClonedStreamData( pNetBufferList, 0, FALSE ); pFlowData->pTcpResponceBufferList = NULL; } pNetBufferList = pFlowData->pTcpResponceInjectBufferList; if (NULL != pNetBufferList) { FwpsFreeNetBufferList0(pNetBufferList); pFlowData->pTcpResponceInjectBufferList = NULL; _pMdl = pFlowData->pTcpResponceMdl; if (NULL != _pMdl) { IoFreeMdl(_pMdl); ExFreePoolWithTag( _pMdl->MappedSystemVa, POOL_TAG ); pFlowData->pTcpResponceMdl = NULL; } } pNetBufferList = pFlowData->pUdpResponceBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponceBufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } pNetBufferList = pFlowData->pUdpResponceCloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponceCloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } pNetBufferList = pFlowData->pUdpResponce2BufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponce2BufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } pNetBufferList = pFlowData->pUdpResponce2CloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponce2CloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } _pControlData = pFlowData->stUdpResponceSendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponceSendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); _pControlData = pFlowData->stUdpResponce2SendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } status1 = STATUS_END_OF_FILE; wdfRequestQueue = pFlowData->wdfTcpResponceInjectQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfTcpResponceInjectQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfTcpResponcePermitQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfTcpResponcePermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfTcpQueryInjectQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfTcpQueryInjectQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfTcpQueryPermitQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfTcpQueryPermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitTcpResponceQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitTcpResponceQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitTcpNewMessageQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitTcpNewMessageQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfUdpQuery2PermitQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfUdpQuery2PermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfUdpQueryPermitQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfUdpQueryPermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowData, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status1, sizeof(FLOW_DATA) ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } bListEmpty = RemoveEntryList(&pFlowData->listEntry); if (IsListEntryInList(&pFlowData->threadListEntry, &g_stPendedPacketsQueue)) { bListEmpty = RemoveEntryList(&pFlowData->threadListEntry); } pFlowData->enContextState = csNotRun; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); WdfObjectReleaseLock(wdfDeviceObject); return; case csUdpIllegalOutbound: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpIllegalOutbound\"." ); } j++; switch (pFlowData->arContextStateStack[j]) { case csUdpWaitResponce1: case csUdpWaitResponce2: case csUdpWaitResponce2Pended: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Outbound on elaborate DNS UDP Responce." ); status1 = STATUS_UNEXPECTED_NETWORK_ERROR; break; case csUdpWaitReadQuery: case csUdpWaitApprovalQuery: case csUdpPermitQueryPended: case csUdpWaitPermitQuery: case csUdpWaitPermitQuery2: case csUdpPermitQuery2Pended: case csUdpWaitReplaceQuery2: case csUdpQuery2Discarded: case csUdpWaitApprovalQuery2: case csUdpWaitReadQuery2: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Outbound on elaborate DNS UDP Query." ); status1 = STATUS_UNEXPECTED_NETWORK_ERROR; break; case csUdpFlowEstablished: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Outbound on First UDP Packet." ); status1 = STATUS_UNEXPECTED_NETWORK_ERROR; break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Driver State = %u", (UINT32) pFlowData->arContextStateStack[j] ); //ASSERT(FALSE); status1 = STATUS_UNEXPECTED_IO_ERROR; } wdfRequestQueue = pFlowData->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpFlowDone: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpFlowDone\"." ); } j++; switch (pFlowData->arContextStateStack[j]) { case csUdpWaitResponce2: status1 = STATUS_END_OF_FILE; break; case csUdpWaitResponce1: status1 = STATUS_END_OF_FILE; break; case csUdpFlow1Done: status1 = STATUS_END_OF_FILE; break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Driver State = %u", (UINT32) pFlowData->arContextStateStack[j] ); //ASSERT(FALSE); status1 = STATUS_UNEXPECTED_IO_ERROR; } pNetBufferList = pFlowData->pUdpQuery2BufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQuery2BufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csTcpClientDisconnect: case csTcpServerDisconnect: status1 = STATUS_END_OF_FILE; pNetBufferList = pFlowData->pTcpResponceInjectBufferList; if (NULL != pNetBufferList) { FwpsFreeNetBufferList0(pNetBufferList); pFlowData->pTcpResponceInjectBufferList = NULL; _pMdl = pFlowData->pTcpResponceMdl; if (NULL != _pMdl) { IoFreeMdl(_pMdl); ExFreePoolWithTag( _pMdl->MappedSystemVa, POOL_TAG ); pFlowData->pTcpResponceMdl = NULL; } } pNetBufferList = pFlowData->pTcpResponceBufferList; if (NULL != pNetBufferList) { FwpsDiscardClonedStreamData( pNetBufferList, 0, FALSE ); pFlowData->pTcpResponceBufferList = NULL; } pNetBufferList = pFlowData->pTcpQueryInjectBufferList; if (NULL != pNetBufferList) { FwpsFreeNetBufferList0(pNetBufferList); pFlowData->pTcpQueryInjectBufferList = NULL; _pMdl = pFlowData->pTcpQueryMdl; if (NULL != _pMdl) { IoFreeMdl(_pMdl); ExFreePoolWithTag( _pMdl->MappedSystemVa, POOL_TAG ); pFlowData->pTcpQueryMdl = NULL; } } pNetBufferList = pFlowData->pTcpQueryBufferList; if (NULL != pNetBufferList) { FwpsDiscardClonedStreamData( pNetBufferList, 0, FALSE ); pFlowData->pTcpQueryBufferList = NULL; } wdfRequestQueue = pFlowData->wdfWaitTcpNewMessageQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitTcpNewMessageQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitTcpResponceQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitTcpResponceQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfTcpQueryPermitQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfTcpQueryPermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfTcpQueryInjectQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfTcpQueryInjectQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfTcpResponcePermitQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfTcpResponcePermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfTcpResponceInjectQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfTcpResponceInjectQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpSetFilterEvent: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpSetFilterEvent\"." ); } j++; switch (pFlowData->arContextStateStack[j]) { case csUdpWaitReadQuery2: case csUdpWaitApprovalQuery2: case csUdpQuery2Discarded: case csUdpWaitReplaceQuery2: case csUdpPermitQuery2Pended: status1 = STATUS_END_OF_FILE; break; case csUdpPermitQuery2Done: status1 = STATUS_END_OF_FILE; break; case csUdpWaitResponce2Pended: status1 = STATUS_END_OF_FILE; break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Driver State = %u", (UINT32) pFlowData->arContextStateStack[j] ); //ASSERT(FALSE); status1 = STATUS_UNEXPECTED_IO_ERROR; } wdfRequestQueue = pFlowData->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_NO_MORE_ENTRIES, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; ASSERT(NULL != wdfRequestQueue); pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowData, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); break; case csTcpIllegalInbound: j++; switch (pFlowData->arContextStateStack[j]) { case csTcpPermitQueryDone: case csTcpReplaceQueryDone: case csTcpResponceMoreData01: case csTcpWaitPermitQuery: case csTcpWaitReplaceQueryDone: case csTcpResponceMoreData02: case csTcpResponceMoreData03: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Inbound on elaborate DNS TCP Responce." ); status1 = STATUS_UNEXPECTED_NETWORK_ERROR; break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Driver State = %u", (UINT32) pFlowData->arContextStateStack[j] ); //ASSERT(FALSE); status1 = STATUS_UNEXPECTED_IO_ERROR; } break; case csTcpReplaceResponceDone: status1 = STATUS_END_OF_FILE; wdfRequestQueue = pFlowData->wdfWaitTcpNewMessageQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitTcpNewMessageQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csTcpReplaceResponcePended: status1 = STATUS_END_OF_FILE; if (IsListEntryInList(&pFlowData->threadListEntry, &g_stPendedPacketsQueue)) { bListEmpty = RemoveEntryList(&pFlowData->threadListEntry); } pNetBufferList = pFlowData->pTcpResponceInjectBufferList; if (NULL != pNetBufferList) { pFlowData->pTcpResponceInjectBufferList = NULL; FwpsFreeNetBufferList0(pNetBufferList); _pMdl = pFlowData->pTcpResponceMdl; if (NULL != _pMdl) { IoFreeMdl(_pMdl); ExFreePoolWithTag( _pMdl->MappedSystemVa, POOL_TAG ); pFlowData->pTcpResponceMdl = NULL; } } wdfRequestQueue = pFlowData->wdfTcpResponceInjectQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfTcpResponceInjectQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { Information = pFlowData->nTcpResponceInjectDataSize; pFlowData->nTcpResponceInjectDataSize = 0; ASSERT(0 != Information); WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, Information ); WdfObjectDelete(wdfRequestQueue); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitTcpNewMessageQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitTcpNewMessageQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csTcpPermitQueryDone: j++; switch (pFlowData->arContextStateStack[j]) { case csTcpWaitPermitQuery: case csTcpPermitQueryDone: status1 = STATUS_END_OF_FILE; break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Driver State = %u", (UINT32) pFlowData->arContextStateStack[j] ); //ASSERT(FALSE); status1 = STATUS_UNEXPECTED_IO_ERROR; } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpPermitQueryDone: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpPermitQueryDone\"." ); } j++; switch (pFlowData->arContextStateStack[j]) { case csUdpWaitPermitQuery: status1 = STATUS_END_OF_FILE; ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Driver State = %u", (UINT32) pFlowData->arContextStateStack[j] ); //ASSERT(FALSE); status1 = STATUS_UNEXPECTED_IO_ERROR; } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpPermitQuery2Done: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpPermitQuery2Done\"." ); } j++; switch (pFlowData->arContextStateStack[j]) { case csUdpWaitPermitQuery2: status1 = STATUS_END_OF_FILE; ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Driver State = %u", (UINT32) pFlowData->arContextStateStack[j] ); //ASSERT(FALSE); status1 = STATUS_UNEXPECTED_IO_ERROR; } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpWaitResponce1Pended: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpWaitResponce1Pended\"." ); } if (IsListEntryInList(&pFlowData->threadListEntry, &g_stPendedPacketsQueue)) { bListEmpty = RemoveEntryList(&pFlowData->threadListEntry); } pNetBufferList = pFlowData->pUdpResponceBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponceBufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } _pControlData = pFlowData->stUdpResponceSendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponceSendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } status1 = STATUS_END_OF_FILE; break; case csUdpWaitResponce1: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpWaitResponce1\"." ); } pNetBufferList = pFlowData->pUdpResponceCloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponceCloneBufferList = NULL; //if (pFlowData->arContextStateStack[2] != csUdpWaitResponce1Pended) //{ // FwpsFreeCloneNetBufferList( // pNetBufferList, // 0 // ); //} } _pControlData = pFlowData->stUdpResponceSendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponceSendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } status1 = STATUS_END_OF_FILE; break; case csUdpWaitPermitQuery2: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpWaitPermitQuery2\"." ); } j++; switch (pFlowData->arContextStateStack[j]) { case csUdpWaitPermitQuery: status1 = STATUS_END_OF_FILE; break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Driver State = %u", (UINT32) pFlowData->arContextStateStack[j] ); //ASSERT(FALSE); status1 = STATUS_UNEXPECTED_IO_ERROR; } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpWaitResponce2Pended: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpWaitResponce2Pended\"." ); } if (IsListEntryInList(&pFlowData->threadListEntry, &g_stPendedPacketsQueue)) { bListEmpty = RemoveEntryList(&pFlowData->threadListEntry); } pNetBufferList = pFlowData->pUdpResponce2BufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponce2BufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } _pControlData = pFlowData->stUdpResponce2SendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponce2SendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } status1 = STATUS_END_OF_FILE; break; case csUdpWaitResponce2: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpWaitResponce2\"." ); } pNetBufferList = pFlowData->pUdpResponce2CloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponce2CloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } _pControlData = pFlowData->stUdpResponce2SendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponce2SendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpFiltersChangeInProgress: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpFiltersChangeInProgress\"." ); } j++; switch (pFlowData->arContextStateStack[j]) { case csUdpFlowEstablished: wdfRequestQueue = pFlowData->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } status1 = STATUS_END_OF_FILE; break; case csUdpWaitReadQuery: case csUdpWaitApprovalQuery: pNetBufferList = pFlowData->pUdpQueryBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQueryBufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } status1 = STATUS_END_OF_FILE; break; case csUdpPermitQueryPended: if (IsListEntryInList(&pFlowData->threadListEntry, &g_stPendedPacketsQueue)) { bListEmpty = RemoveEntryList(&pFlowData->threadListEntry); } case csUdpWaitPermitQuery: pNetBufferList = pFlowData->pUdpQueryCloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQueryCloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } wdfRequestQueue = pFlowData->wdfUdpQueryPermitQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfUdpQueryPermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } status1 = STATUS_END_OF_FILE; break; case csUdpPermitQueryDone: wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } status1 = STATUS_END_OF_FILE; break; case csUdpWaitReadQuery2: case csUdpWaitApprovalQuery2: pNetBufferList = pFlowData->pUdpQuery2BufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQuery2BufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } status1 = STATUS_END_OF_FILE; break; case csUdpPermitQuery2Pended: if (IsListEntryInList(&pFlowData->threadListEntry, &g_stPendedPacketsQueue)) { bListEmpty = RemoveEntryList(&pFlowData->threadListEntry); } case csUdpWaitPermitQuery2: pNetBufferList = pFlowData->pUdpQuery2CloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQuery2CloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } wdfRequestQueue = pFlowData->wdfUdpQuery2PermitQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfUdpQuery2PermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } status1 = STATUS_END_OF_FILE; break; case csUdpPermitQuery2Done: wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } status1 = STATUS_END_OF_FILE; break; case csUdpWaitResponce2: pNetBufferList = pFlowData->pUdpResponce2CloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponce2CloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } _pControlData = pFlowData->stUdpResponce2SendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponce2SendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } status1 = STATUS_END_OF_FILE; break; case csUdpWaitResponce1: pNetBufferList = pFlowData->pUdpResponceCloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponceCloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } _pControlData = pFlowData->stUdpResponceSendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponceSendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } status1 = STATUS_END_OF_FILE; break; case csUdpWaitResponce2Pended: if (IsListEntryInList(&pFlowData->threadListEntry, &g_stPendedPacketsQueue)) { bListEmpty = RemoveEntryList(&pFlowData->threadListEntry); } pNetBufferList = pFlowData->pUdpResponce2BufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponce2BufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } _pControlData = pFlowData->stUdpResponce2SendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponce2SendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } status1 = STATUS_END_OF_FILE; break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Driver State = %u", (UINT32) pFlowData->arContextStateStack[j] ); //ASSERT(FALSE); status1 = STATUS_UNEXPECTED_IO_ERROR; } break; case csTcpReplaceQueryDone: j++; switch (pFlowData->arContextStateStack[j]) { case csTcpWaitReplaceQueryDone: status1 = STATUS_END_OF_FILE; break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Driver State = %u", (UINT32) pFlowData->arContextStateStack[j] ); ////ASSERT(FALSE); status1 = STATUS_UNEXPECTED_IO_ERROR; } wdfRequestQueue = pFlowData->wdfWaitTcpResponceQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitTcpResponceQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csTcpWaitReplaceResponceDone: case csTcpQueryMoreData01: case csTcpQueryMoreData02: case csTcpWaitReadQuery: case csTcpWaitApprovalQuery: case csTcpWaitResponceStarted: case csTcpWaitReplaceQuery: case csTcpPermitQueryPended: case csTcpWaitPermitQuery: case csTcpWaitQueryInjectDone: case csTcpReplaceQueryPended: case csTcpWaitReplaceQueryDone: case csTcpWaitReadResponce: case csTcpResponceMoreData01: case csTcpResponceMoreData02: case csTcpResponceMoreData03: case csTcpWaitApprovalResponce: case csTcpPermitResponcePended: case csTcpWaitPermitResponce: case csTcpPermitResponceDone: case csTcpWaitResponceInjectDone: case csTcpWaitReplaceResponce: case csTcpResponceDiscarded: case csTcpWaitNewMessageStarted: status1 = STATUS_END_OF_FILE; wdfRequestQueue = pFlowData->wdfWaitTcpNewMessageQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitTcpNewMessageQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csTcpFlowEstablished: status1 = STATUS_END_OF_FILE; TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! DNS Packets Flow terminated on state \"csTcpFlowEstablished\"" ); wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpFlowEstablished: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpFlowEstablished\"." ); } status1 = STATUS_END_OF_FILE; TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! DNS Packets Flow terminated on state \"csUdpFlowEstablished\"" ); wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpWaitReadQuery: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpWaitReadQuery\"." ); } TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! UDP Flow Terminated on state \"csUdpWaitReadQuery\"!" ); pNetBufferList = pFlowData->pUdpQueryBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQueryBufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } status1 = STATUS_END_OF_FILE; break; case csUdpFlowBreak: j++; if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpFlowBreak\"." ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host has previos state = %u.", pFlowData->arContextStateStack[j] ); } status1 = STATUS_END_OF_FILE; if (IsListEntryInList(&pFlowData->threadListEntry, &g_stPendedPacketsQueue)) { bListEmpty = RemoveEntryList(&pFlowData->threadListEntry); } pNetBufferList = pFlowData->pUdpResponce2CloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponce2CloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } _pControlData = pFlowData->stUdpResponce2SendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponce2SendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); pNetBufferList = pFlowData->pUdpResponce2BufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponce2BufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } pNetBufferList = pFlowData->pUdpQuery2CloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQuery2CloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } pNetBufferList = pFlowData->pUdpQuery2BufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQuery2BufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } pNetBufferList = pFlowData->pUdpResponceCloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponceCloneBufferList = NULL; if (!(pFlowData->arContextStateStack[1] == csUdpFlowBreak && pFlowData->arContextStateStack[2] == csUdpWaitResponce1)) { FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } } _pControlData = pFlowData->stUdpResponceSendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponceSendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); pNetBufferList = pFlowData->pUdpQueryCloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQueryCloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } pNetBufferList = pFlowData->pUdpQueryBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQueryBufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfUdpQueryPermitQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfUdpQueryPermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfUdpQuery2PermitQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfUdpQuery2PermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; case csUdpWaitPermitQuery: status1 = STATUS_END_OF_FILE; pNetBufferList = pFlowData->pUdpQueryCloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQueryCloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } break; default: if (bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Illegal Driver State = %u!! Host %ws; clent.port = %hu;", (UINT32) pFlowData->arContextStateStack[j], szIpAddress, usRemotePort ); //ASSERT(FALSE); status1 = STATUS_UNEXPECTED_IO_ERROR; } bListEmpty = RemoveEntryList(&pFlowData->listEntry); nFileIndex = pFlowData->nFileIndex; nThreadIndex = pFlowData->nThreadIndex; if (IsListEntryInList(&pFlowData->threadListEntry, &g_stPendedPacketsQueue)) { bListEmpty = RemoveEntryList(&pFlowData->threadListEntry); } wdfFlowQueue = pFlowData->wdfFlowQueue; pNetBufferList = pFlowData->pTcpResponceInjectBufferList; if (NULL != pNetBufferList) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"pTcpResponceInjectBufferList\" not free; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); FwpsFreeNetBufferList0(pNetBufferList); pFlowData->pTcpResponceInjectBufferList = NULL; _pMdl = pFlowData->pTcpResponceMdl; if (NULL != _pMdl) { IoFreeMdl(_pMdl); ExFreePoolWithTag( _pMdl->MappedSystemVa, POOL_TAG ); pFlowData->pTcpResponceMdl = NULL; } } pNetBufferList = pFlowData->pTcpResponceBufferList; if (NULL != pNetBufferList) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"pTcpResponceBufferList\" not free; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); FwpsDiscardClonedStreamData( pNetBufferList, 0, FALSE ); pFlowData->pTcpResponceBufferList = NULL; } pNetBufferList = pFlowData->pTcpQueryInjectBufferList; if (NULL != pNetBufferList) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"pTcpQueryInjectBufferList\" not free; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); FwpsFreeNetBufferList0(pNetBufferList); pFlowData->pTcpQueryInjectBufferList = NULL; _pMdl = pFlowData->pTcpQueryMdl; if (NULL != _pMdl) { IoFreeMdl(_pMdl); ExFreePoolWithTag( _pMdl->MappedSystemVa, POOL_TAG ); pFlowData->pTcpQueryMdl = NULL; } } pNetBufferList = pFlowData->pTcpQueryBufferList; if (NULL != pNetBufferList) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"pTcpQueryBufferList\" not free; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); FwpsDiscardClonedStreamData( pNetBufferList, 0, FALSE ); pFlowData->pTcpQueryBufferList = NULL; } pNetBufferList = pFlowData->pUdpResponce2CloneBufferList; if (NULL != pNetBufferList) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"pUdpResponce2CloneBufferList\" not free; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); pFlowData->pUdpResponce2CloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } _pControlData = pFlowData->stUdpResponce2SendParams.controlData; if (NULL != _pControlData) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"stUdpResponce2SendParams.controlData\" not free; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponce2SendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); pNetBufferList = pFlowData->pUdpResponce2BufferList; if (NULL != pNetBufferList) { pFlowData->pUdpResponce2BufferList = NULL; TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"pUdpResponce2BufferList\" not free; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } pNetBufferList = pFlowData->pUdpQuery2CloneBufferList; if (NULL != pNetBufferList) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"pUdpQuery2CloneBufferList\" not free; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); pFlowData->pUdpQuery2CloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } pNetBufferList = pFlowData->pUdpQuery2BufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQuery2BufferList = NULL; TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"pUdpQuery2BufferList\" not free; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } pNetBufferList = pFlowData->pUdpResponceCloneBufferList; if (NULL != pNetBufferList) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"pUdpResponceCloneBufferList\" not free; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); pFlowData->pUdpResponceCloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } _pControlData = pFlowData->stUdpResponceSendParams.controlData; if (NULL != _pControlData) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"stUdpResponceSendParams.controlData\" not free; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponceSendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); pNetBufferList = pFlowData->pUdpQueryCloneBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQueryCloneBufferList = NULL; TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"pUdpQueryCloneBufferList\" not free; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } pNetBufferList = pFlowData->pUdpQueryBufferList; if (NULL != pNetBufferList) { pFlowData->pUdpQueryBufferList = NULL; TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"pUdpQueryBufferList\" not free; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpQuery2Queue = NULL; TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"wdfWaitUdpQuery2Queue\" not empty; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"wdfWaitUdpSetFirewallFilterQueue\" not empty; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitDnsQueryQueue = NULL; TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"wdfWaitDnsQueryQueue\" not empty; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfUdpQueryPermitQueue; if (NULL != wdfRequestQueue) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"wdfUdpQueryPermitQueue\" not empty; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); pFlowData->wdfUdpQueryPermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfUdpQuery2PermitQueue; if (NULL != wdfRequestQueue) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"wdfUdpQuery2PermitQueue\" not empty; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); pFlowData->wdfUdpQuery2PermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitTcpNewMessageQueue; if (NULL != wdfRequestQueue) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"wdfWaitTcpNewMessageQueue\" not empty; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); pFlowData->wdfWaitTcpNewMessageQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitTcpResponceQueue; if (NULL != wdfRequestQueue) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"wdfWaitTcpResponceQueue\" not empty; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); pFlowData->wdfWaitTcpResponceQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfTcpQueryPermitQueue; if (NULL != wdfRequestQueue) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"wdfTcpQueryPermitQueue\" not empty; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); pFlowData->wdfTcpQueryPermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfTcpQueryInjectQueue; if (NULL != wdfRequestQueue) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"wdfTcpQueryInjectQueue\" not empty; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); pFlowData->wdfTcpQueryInjectQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfTcpResponcePermitQueue; if (NULL != wdfRequestQueue) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"wdfTcpResponcePermitQueue\" not empty; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); pFlowData->wdfTcpResponcePermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfTcpResponceInjectQueue; if (NULL != wdfRequestQueue) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"wdfTcpResponceInjectQueue\" not empty; Driver State = %u", (UINT32) pFlowData->arContextStateStack[1] ); pFlowData->wdfTcpResponceInjectQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowData->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowData, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status1, sizeof(FLOW_DATA) ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } RtlZeroMemory( pFlowData, sizeof(FLOW_DATA) ); pFlowData->pThis = pFlowData; pFlowData->nFileIndex = nFileIndex; pFlowData->nThreadIndex = nThreadIndex; pFlowData->wdfFlowFileObject = wdfFlowFileObject; pFlowData->wdfFlowQueue = wdfFlowQueue; if (IsListHeadBad(&g_stFreeFileList)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid \"g_stFreeFileList\"!!" ); InitializeListHead(&g_stFreeFileList); } pFlowData->enFlowDataOwner = foFreeFileList; push_fos(pFlowData->arFlowDataOwnerStack, pFlowData->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowData->listEntry ); WdfObjectReleaseLock(wdfDeviceObject); } void NTAPI onDatagramDataClassify( __in const FWPS_INCOMING_VALUES* inFixedValues, __in const FWPS_INCOMING_METADATA_VALUES* inMetaValues, __inout_opt void* layerData, _In_opt_ const void* classifyContext, __in const FWPS_FILTER* filter, __in UINT64 flowContext, __inout FWPS_CLASSIFY_OUT* classifyOut ) { FWP_DIRECTION enPacketDirection; WDFFILEOBJECT wdfFlowFileObject = NULL; WDFFILEOBJECT wdfInjectDataObject = NULL; NTSTATUS status = STATUS_SUCCESS; BOOLEAN bInbound; BOOLEAN bIPv6; PNET_BUFFER_LIST pNetBufferList; FWPS_PACKET_INJECTION_STATE packetState; PFLOW_DATA pFlowData; PNET_BUFFER pNetBuffer; UINT32 nDataSize; UINT32 ulUdpDataOffset; UINT32 ulUdpDataLength; UINT32 ulIpHeaderSize; UINT32 ulTransportHeaderSize; WDFREQUEST wdfPendedRequest; WDFMEMORY wdfOutputMemory = NULL; COMPARTMENT_ID enUdpCompartmentID; WDFDEVICE wdfDeviceObject; WDFQUEUE wdfRequestQueue; UINT64 hFlowHandle; HANDLE hInjectionHandle; IN6_ADDR stIp6Address; IN_ADDR stIpAddress; WCHAR szIpAddress[128]; LPWSTR pAddressEnd; BOOLEAN bSignalWorkerThread; UINT16 usRemotePort; UINT32 ulRemoteAddress = 0, ulRemoteAddressN = 0; BOOLEAN bTestIpV4; UINT32 ulInboundCount = 0; PLIST_ENTRY pListEntry, pLastLE, pNextLE; PFLOW_DATA pFlowContext = NULL; IN6_ADDR stRemoteAddress; BOOLEAN bEmpty; FWP_BYTE_ARRAY16 *pRemoteAddress = NULL; UNREFERENCED_PARAMETER(classifyContext); UNREFERENCED_PARAMETER(filter); // // We don't have the necessary right to alter the classify, exit. // if ((classifyOut->rights & FWPS_RIGHT_ACTION_WRITE) == 0) { // // Cannot alter the action. // return; } pNetBufferList = (PNET_BUFFER_LIST) layerData; ASSERT(pNetBufferList != NULL); pFlowData = (PFLOW_DATA) flowContext; ASSERT(NULL != pFlowData); ASSERT(pFlowData == pFlowData->pThis); wdfFlowFileObject = pFlowData->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfDeviceObject = g_wdfControlDevice; bIPv6 = pFlowData->bIPv6; if (bIPv6) { hInjectionHandle = g_hInjectionHandleV6; enPacketDirection = (FWP_DIRECTION) inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V6_DIRECTION].value.uint8; } else { ulRemoteAddress = pFlowData->nRemoteAddressV4; hInjectionHandle = g_hInjectionHandleV4; enPacketDirection = (FWP_DIRECTION) inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_DIRECTION].value.uint8; } bInbound = (BOOLEAN) (FWP_DIRECTION_INBOUND == enPacketDirection); WdfObjectAcquireLock(wdfDeviceObject); ASSERT(FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_FLOW_HANDLE)); hFlowHandle = inMetaValues->flowHandle; if (hFlowHandle != pFlowData->flowHandle) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! Exit (hFlowHandle != pFlowData->flowHandle)" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(wdfDeviceObject); return; } pFlowData->enPacketDirection = enPacketDirection; if (bInbound && (g_bFiltersChangeInProgress | g_stFirewallConfig.bExternalClientBlocked)) { if (bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Host %ws Blocked because (g_bFiltersChangeInProgress | g_stFirewallConfig.bExternalClientBlocked)!", szIpAddress ); if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { ulInboundCount = 0; pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } pFlowData->enContextState = csUdpFiltersChangeInProgress; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(wdfDeviceObject); if (bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } return; } if (bIPv6) { pRemoteAddress = inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V6_IP_REMOTE_ADDRESS].value.byteArray16; pFlowData->interfaceIndex = inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V6_INTERFACE_INDEX].value.uint32; pFlowData->subInterfaceIndex = inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V6_SUB_INTERFACE_INDEX].value.uint32; usRemotePort = inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V6_IP_REMOTE_PORT].value.uint16; } else { pFlowData->interfaceIndex = inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_INTERFACE_INDEX].value.uint32; pFlowData->subInterfaceIndex = inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_SUB_INTERFACE_INDEX].value.uint32; ulRemoteAddress = inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_IP_REMOTE_ADDRESS].value.uint32; usRemotePort = inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_IP_REMOTE_PORT].value.uint16; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } pNetBuffer = NET_BUFFER_LIST_FIRST_NB(pNetBufferList); nDataSize = NET_BUFFER_DATA_LENGTH(pNetBuffer); ulUdpDataOffset = NET_BUFFER_DATA_OFFSET(pNetBuffer); enUdpCompartmentID = (COMPARTMENT_ID) inMetaValues->compartmentId; if (FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_IP_HEADER_SIZE)) { ulIpHeaderSize = inMetaValues->ipHeaderSize; } else { ulIpHeaderSize = pFlowData->ulUdpQueryIpHeaderSize; } ulTransportHeaderSize = inMetaValues->transportHeaderSize; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } packetState = FwpsQueryPacketInjectionState( hInjectionHandle, pNetBufferList, (HANDLE*) &wdfInjectDataObject ); if ((packetState == FWPS_PACKET_INJECTED_BY_SELF) || (packetState == FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF)) { if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Reinjected." ); } classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(wdfDeviceObject); return; } usRemotePort = pFlowData->usRemotePort; switch (pFlowData->enContextState) { case csUdpFlowEstablished: if (!bInbound) { if (pFlowData->bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! if (!bInbound)! Host IP = %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(wdfDeviceObject); break; } // inbound if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpFlowEstablished\"." ); } pFlowData->ulUdpQueryCount++; pFlowData->pUdpQueryBufferList = pNetBufferList; pFlowData->ulUdpQueryBufferSize = nDataSize + ulIpHeaderSize + ulTransportHeaderSize; pFlowData->ulUdpQueryDataOffset = ulUdpDataOffset; pFlowData->ulUdpQueryPacketOffset = ulUdpDataOffset - ulIpHeaderSize - ulTransportHeaderSize; ulUdpDataLength = nDataSize; pFlowData->ulUdpQueryDataLength = ulUdpDataLength; ASSERT(pFlowData->ulUdpQueryDataLength > 0); pFlowData->enUdpQueryCompartmentID = enUdpCompartmentID; pFlowData->ulUdpQueryIpHeaderSize = ulIpHeaderSize; pFlowData->ulUdpQueryTransportHeaderSize = ulTransportHeaderSize; FwpsReferenceNetBufferList(pNetBufferList, TRUE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; pFlowData->enContextState = csUdpWaitReadQuery; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); wdfRequestQueue = pFlowData->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowData->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowData, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); WdfObjectReleaseLock(wdfDeviceObject); break; case csUdpWaitResponce1Pended: if (pFlowData->bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } if (bInbound) { if (pFlowData->bUdpQueryClassifyPended) { pFlowData->bUdpQueryClassifyPended = FALSE; TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Receive Pended UDP-Query from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); //ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(wdfDeviceObject); break; } if ((usRemotePort != pFlowData->usRemotePort) && (!IsListEmpty(&g_stUdpAcceptNotifyList))) { ulInboundCount = 0; pListEntry = g_stUdpAcceptNotifyList.Flink; pLastLE = g_stUdpAcceptNotifyList.Blink; for (;;) { pNextLE = pListEntry->Flink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (bIPv6 && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6) && (usRemotePort == pFlowContext->usRemotePort)) { ulInboundCount++; break; } } else if ((!bIPv6) && (!pFlowContext->bIPv6)) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (usRemotePort == pFlowContext->usRemotePort)) { ulInboundCount++; break; } } if (pListEntry == pLastLE) { break; } pListEntry = pNextLE; } if (ulInboundCount > 0) { bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } break; } } TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Unexpect Repeated UDP-Query from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } pFlowData->enContextState = csUdpIllegalInbound; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } break; } // outbound KeClearEvent(&g_oWorkerEvent); if (IsListHeadBad(&g_stPendedPacketsQueue)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid \"g_stPendedPacketsQueue\"!!" ); InitializeListHead(&g_stPendedPacketsQueue); } TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Double send responce #1 to host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); pFlowData->enContextState = csUdpFlowBreak; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } break; case csUdpWaitResponce1: if (pFlowData->bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } if (bInbound) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid INBOUND Datagram on state \"csUdpWaitResponce1\" from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); pFlowData->enContextState = csUdpIllegalInbound; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } break; } // outbound TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid OUTBOUND Datagram on state \"csUdpWaitResponce1\" to host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); pFlowData->enContextState = csUdpFlowBreak; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } break; case csUdpPermitQueryDone: if (bInbound) { if (pFlowData->bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } if (pFlowData->bUdpQueryClassifyPended) { pFlowData->bUdpQueryClassifyPended = FALSE; TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Receive Pended UDP-Query from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); //ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(wdfDeviceObject); break; } if ((usRemotePort != pFlowData->usRemotePort) && (!IsListEmpty(&g_stUdpAcceptNotifyList))) { ulInboundCount = 0; pListEntry = g_stUdpAcceptNotifyList.Flink; pLastLE = g_stUdpAcceptNotifyList.Blink; for (;;) { pNextLE = pListEntry->Flink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (bIPv6 && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6) && (usRemotePort == pFlowContext->usRemotePort)) { ulInboundCount++; break; } } else if ((!bIPv6) && (!pFlowContext->bIPv6)) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (usRemotePort == pFlowContext->usRemotePort)) { ulInboundCount++; break; } } if (pListEntry == pLastLE) { break; } pListEntry = pNextLE; } if (ulInboundCount > 0) { bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } break; } } TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Unexpect Repeated UDP-Query from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } pFlowData->enContextState = csUdpIllegalInbound; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } break; } // outbound if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpPermitQueryDone\"." ); } if (FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_REMOTE_SCOPE_ID)) { RtlCopyMemory( &pFlowData->stUdpResponceSendParams.remoteScopeId, &inMetaValues->remoteScopeId, sizeof(SCOPE_ID) ); } else { RtlZeroMemory( &pFlowData->stUdpResponceSendParams.remoteScopeId, sizeof(SCOPE_ID) ); } if (FWPS_IS_METADATA_FIELD_PRESENT( inMetaValues, FWPS_METADATA_FIELD_TRANSPORT_CONTROL_DATA)) { ASSERT(inMetaValues->controlDataLength > 0); pFlowData->stUdpResponceSendParams.controlData = (WSACMSGHDR*) ExAllocatePoolWithTag( NonPagedPool, inMetaValues->controlDataLength, POOL_TAG ); ASSERT(NULL != pFlowData->stUdpResponceSendParams.controlData); RtlCopyMemory( pFlowData->stUdpResponceSendParams.controlData, inMetaValues->controlData, inMetaValues->controlDataLength ); pFlowData->stUdpResponceSendParams.controlDataLength = inMetaValues->controlDataLength; } else { if (NULL != pFlowData->stUdpResponceSendParams.controlData) { ExFreePoolWithTag( pFlowData->stUdpResponceSendParams.controlData, POOL_TAG ); } pFlowData->stUdpResponceSendParams.controlData = NULL; pFlowData->stUdpResponceSendParams.controlDataLength = 0; } if (bIPv6) { pFlowData->stUdpResponceSendParams.remoteAddress = (UCHAR*) &pFlowData->stRemoteAddressV6; } else { pFlowData->stUdpResponceSendParams.remoteAddress = (UCHAR*) &pFlowData->nRemoteAddressV4N; } FwpsReferenceNetBufferList(pNetBufferList, TRUE); pFlowData->pUdpResponceBufferList = pNetBufferList; pFlowData->ulUdpResponceBufferSize = nDataSize; ulUdpDataOffset = ulTransportHeaderSize; pFlowData->ulUdpResponceDataOffset = ulUdpDataOffset; ulUdpDataLength = nDataSize - ulTransportHeaderSize; pFlowData->nUdpResponceDataLength = ulUdpDataLength; pFlowData->enUdpResponceCompartmentID = enUdpCompartmentID; pFlowData->ulUdpResponceIpHeaderSize = ulIpHeaderSize; pFlowData->ulUdpResponceTransportHeaderSize = ulTransportHeaderSize; ASSERT(FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_TRANSPORT_ENDPOINT_HANDLE)); pFlowData->hUdpResponceEndpointHandle = inMetaValues->transportEndpointHandle; pFlowData->hUdpInjectEndpointHandle = inMetaValues->transportEndpointHandle; classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; pFlowData->enContextState = csUdpWaitResponce1Pended; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); bSignalWorkerThread = IsListEmpty(&g_stPendedPacketsQueue); InsertTailList(&g_stPendedPacketsQueue, &pFlowData->threadListEntry); WdfObjectReleaseLock(wdfDeviceObject); if (bSignalWorkerThread) { KeSetEvent( &g_oWorkerEvent, 0, FALSE ); } break; case csUdpWaitResponce2Pended: if (pFlowData->bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } if (!bInbound) { KeClearEvent(&g_oWorkerEvent); if (IsListHeadBad(&g_stPendedPacketsQueue)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid \"g_stPendedPacketsQueue\"!!" ); InitializeListHead(&g_stPendedPacketsQueue); } TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Double send responce #2 to host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); pFlowData->enContextState = csUdpFlowBreak; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } break; } // inbound if (pFlowData->bUdpQueryClassifyPended) { pFlowData->bUdpQueryClassifyPended = FALSE; TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Receive Pended UDP-Query #2 from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(wdfDeviceObject); break; } if ((usRemotePort != pFlowData->usRemotePort) && (!IsListEmpty(&g_stUdpAcceptNotifyList))) { ulInboundCount = 0; pListEntry = g_stUdpAcceptNotifyList.Flink; pLastLE = g_stUdpAcceptNotifyList.Blink; for (;;) { pNextLE = pListEntry->Flink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (bIPv6 && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6) && (usRemotePort == pFlowContext->usRemotePort)) { ulInboundCount++; break; } } else if ((!bIPv6) && (!pFlowContext->bIPv6)) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (usRemotePort == pFlowContext->usRemotePort)) { ulInboundCount++; break; } } if (pListEntry == pLastLE) { break; } pListEntry = pNextLE; } if (ulInboundCount > 0) { bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } break; } } TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Unexpect Repeated UDP-Query from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); ASSERT(FALSE); ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } pFlowData->enContextState = csUdpIllegalInbound; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } break; case csUdpPermitQuery2Done: if (!bInbound) { if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpPermitQuery2Done\"." ); } if (FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_REMOTE_SCOPE_ID)) { RtlCopyMemory( &pFlowData->stUdpResponce2SendParams.remoteScopeId, &inMetaValues->remoteScopeId, sizeof(SCOPE_ID) ); } else { RtlZeroMemory( &pFlowData->stUdpResponce2SendParams.remoteScopeId, sizeof(SCOPE_ID) ); } if (FWPS_IS_METADATA_FIELD_PRESENT( inMetaValues, FWPS_METADATA_FIELD_TRANSPORT_CONTROL_DATA)) { ASSERT(inMetaValues->controlDataLength > 0); pFlowData->stUdpResponce2SendParams.controlData = (WSACMSGHDR*) ExAllocatePoolWithTag( NonPagedPool, inMetaValues->controlDataLength, POOL_TAG ); ASSERT(NULL != pFlowData->stUdpResponce2SendParams.controlData); RtlCopyMemory( pFlowData->stUdpResponce2SendParams.controlData, inMetaValues->controlData, inMetaValues->controlDataLength ); pFlowData->stUdpResponce2SendParams.controlDataLength = inMetaValues->controlDataLength; } else { if (NULL != pFlowData->stUdpResponce2SendParams.controlData) { ExFreePoolWithTag( pFlowData->stUdpResponce2SendParams.controlData, POOL_TAG ); } pFlowData->stUdpResponce2SendParams.controlData = NULL; pFlowData->stUdpResponce2SendParams.controlDataLength = 0; } if (bIPv6) { pFlowData->stUdpResponce2SendParams.remoteAddress = (UCHAR*) &pFlowData->stRemoteAddressV6; } else { pFlowData->stUdpResponce2SendParams.remoteAddress = (UCHAR*) &pFlowData->nRemoteAddressV4N; } FwpsReferenceNetBufferList( pNetBufferList, TRUE ); pFlowData->pUdpResponce2BufferList = pNetBufferList; pFlowData->ulUdpResponce2BufferSize = nDataSize; ulUdpDataOffset = ulTransportHeaderSize; pFlowData->ulUdpResponce2DataOffset = ulUdpDataOffset; ulUdpDataLength = nDataSize - ulTransportHeaderSize; pFlowData->nUdpResponce2DataLength = ulUdpDataLength; pFlowData->enUdpResponce2CompartmentID = enUdpCompartmentID; pFlowData->ulUdpResponce2IpHeaderSize = ulIpHeaderSize; pFlowData->ulUdpResponce2TransportHeaderSize = ulTransportHeaderSize; ASSERT(FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_TRANSPORT_ENDPOINT_HANDLE)); pFlowData->hUdpResponce2EndpointHandle = inMetaValues->transportEndpointHandle; pFlowData->hUdpInject2EndpointHandle = inMetaValues->transportEndpointHandle; classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; pFlowData->enContextState = csUdpWaitResponce2Pended; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); bSignalWorkerThread = IsListEmpty(&g_stPendedPacketsQueue); InsertTailList(&g_stPendedPacketsQueue, &pFlowData->threadListEntry); WdfObjectReleaseLock(wdfDeviceObject); if (bSignalWorkerThread) { KeSetEvent( &g_oWorkerEvent, 0, FALSE ); } break; } // inbound if (pFlowData->bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } if (pFlowData->bUdpQueryClassifyPended) { pFlowData->bUdpQueryClassifyPended = FALSE; TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Receive Pended UDP-Query #2 from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(wdfDeviceObject); break; } if ((usRemotePort != pFlowData->usRemotePort) && (!IsListEmpty(&g_stUdpAcceptNotifyList))) { ulInboundCount = 0; pListEntry = g_stUdpAcceptNotifyList.Flink; pLastLE = g_stUdpAcceptNotifyList.Blink; for (;;) { pNextLE = pListEntry->Flink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (bIPv6 && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6) && (usRemotePort == pFlowContext->usRemotePort)) { ulInboundCount++; break; } } else if ((!bIPv6) && (!pFlowContext->bIPv6)) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (usRemotePort == pFlowContext->usRemotePort)) { ulInboundCount++; break; } } if (pListEntry == pLastLE) { break; } pListEntry = pNextLE; } if (ulInboundCount > 0) { bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } break; } } TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Unexpect Repeated UDP-Query from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); ASSERT(FALSE); ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } pFlowData->enContextState = csUdpIllegalInbound; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } break; case csUdpFlowDone: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpFlowDone\"." ); } TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! UDP flow is Done" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(wdfDeviceObject); break; case csUdpWaitResponce2: if (bInbound) { if (pFlowData->bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Unexpect Repeated UDP-Query from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } pFlowData->enContextState = csUdpIllegalInbound; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } break; } // outbound; if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpWaitResponce2\"." ); } push_css(pFlowData->arContextStateStack, pFlowData->enContextState); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(wdfDeviceObject); break; case csUdpWaitPermitQuery: if (bInbound) { if (pFlowData->bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } if (pFlowContext->bUdpQueryClassifyPended) { pFlowContext->bUdpQueryClassifyPended = FALSE; TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Receive Pended UDP-Query from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(wdfDeviceObject); break; } TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Unexpect Repeated UDP-Query from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } pFlowData->enContextState = csUdpIllegalInbound; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } break; } // outbound if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpWaitPermitQuery\"." ); } if (FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_REMOTE_SCOPE_ID)) { RtlCopyMemory( &pFlowData->stUdpResponceSendParams.remoteScopeId, &inMetaValues->remoteScopeId, sizeof(SCOPE_ID) ); } else { RtlZeroMemory( &pFlowData->stUdpResponceSendParams.remoteScopeId, sizeof(SCOPE_ID) ); } if (FWPS_IS_METADATA_FIELD_PRESENT( inMetaValues, FWPS_METADATA_FIELD_TRANSPORT_CONTROL_DATA)) { ASSERT(inMetaValues->controlDataLength > 0); pFlowData->stUdpResponceSendParams.controlData = (WSACMSGHDR*) ExAllocatePoolWithTag( NonPagedPool, inMetaValues->controlDataLength, POOL_TAG ); ASSERT(NULL != pFlowData->stUdpResponceSendParams.controlData); RtlCopyMemory( pFlowData->stUdpResponceSendParams.controlData, inMetaValues->controlData, inMetaValues->controlDataLength ); pFlowData->stUdpResponceSendParams.controlDataLength = inMetaValues->controlDataLength; } else { if (NULL != pFlowData->stUdpResponceSendParams.controlData) { ExFreePoolWithTag( pFlowData->stUdpResponceSendParams.controlData, POOL_TAG ); } pFlowData->stUdpResponceSendParams.controlData = NULL; pFlowData->stUdpResponceSendParams.controlDataLength = 0; } if (bIPv6) { pFlowData->stUdpResponceSendParams.remoteAddress = (UCHAR*) &pFlowData->stRemoteAddressV6; } else { pFlowData->stUdpResponceSendParams.remoteAddress = (UCHAR*) &pFlowData->nRemoteAddressV4N; } FwpsReferenceNetBufferList(pNetBufferList, TRUE); pFlowData->pUdpResponceBufferList = pNetBufferList; pFlowData->ulUdpResponceBufferSize = nDataSize; ulUdpDataOffset = ulTransportHeaderSize; pFlowData->ulUdpResponceDataOffset = ulUdpDataOffset; ulUdpDataLength = nDataSize - ulTransportHeaderSize; pFlowData->nUdpResponceDataLength = ulUdpDataLength; pFlowData->enUdpResponceCompartmentID = enUdpCompartmentID; pFlowData->ulUdpResponceIpHeaderSize = ulIpHeaderSize; pFlowData->ulUdpResponceTransportHeaderSize = ulTransportHeaderSize; ASSERT(FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_TRANSPORT_ENDPOINT_HANDLE)); pFlowData->hUdpResponceEndpointHandle = inMetaValues->transportEndpointHandle; pFlowData->hUdpInjectEndpointHandle = inMetaValues->transportEndpointHandle; classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; pFlowData->enContextState = csUdpWaitResponce1Pended; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); bSignalWorkerThread = IsListEmpty(&g_stPendedPacketsQueue); InsertTailList(&g_stPendedPacketsQueue, &pFlowData->threadListEntry); WdfObjectReleaseLock(wdfDeviceObject); if (bSignalWorkerThread) { KeSetEvent( &g_oWorkerEvent, 0, FALSE ); } break; case csUdpWaitPermitQuery2: if (bInbound) { if (pFlowData->bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } if (pFlowContext->bUdpQueryClassifyPended) { pFlowContext->bUdpQueryClassifyPended = FALSE; TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Receive Pended UDP-Query from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(wdfDeviceObject); break; } TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Unexpect Repeated UDP-Query from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } pFlowData->enContextState = csUdpIllegalInbound; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } break; } // outbound if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpWaitPermitQuery2\"." ); } if (FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_REMOTE_SCOPE_ID)) { RtlCopyMemory( &pFlowData->stUdpResponce2SendParams.remoteScopeId, &inMetaValues->remoteScopeId, sizeof(SCOPE_ID) ); } else { RtlZeroMemory( &pFlowData->stUdpResponce2SendParams.remoteScopeId, sizeof(SCOPE_ID) ); } if (FWPS_IS_METADATA_FIELD_PRESENT( inMetaValues, FWPS_METADATA_FIELD_TRANSPORT_CONTROL_DATA)) { ASSERT(inMetaValues->controlDataLength > 0); pFlowData->stUdpResponce2SendParams.controlData = (WSACMSGHDR*) ExAllocatePoolWithTag( NonPagedPool, inMetaValues->controlDataLength, POOL_TAG ); ASSERT(NULL != pFlowData->stUdpResponce2SendParams.controlData); RtlCopyMemory( pFlowData->stUdpResponce2SendParams.controlData, inMetaValues->controlData, inMetaValues->controlDataLength ); pFlowData->stUdpResponce2SendParams.controlDataLength = inMetaValues->controlDataLength; } else { if (NULL != pFlowData->stUdpResponce2SendParams.controlData) { ExFreePoolWithTag( pFlowData->stUdpResponce2SendParams.controlData, POOL_TAG ); } pFlowData->stUdpResponce2SendParams.controlData = NULL; pFlowData->stUdpResponce2SendParams.controlDataLength = 0; } if (bIPv6) { pFlowData->stUdpResponce2SendParams.remoteAddress = (UCHAR*) &pFlowData->stRemoteAddressV6; } else { pFlowData->stUdpResponce2SendParams.remoteAddress = (UCHAR*) &pFlowData->nRemoteAddressV4N; } FwpsReferenceNetBufferList( pNetBufferList, TRUE ); pFlowData->pUdpResponce2BufferList = pNetBufferList; pFlowData->ulUdpResponce2BufferSize = nDataSize; ulUdpDataOffset = ulTransportHeaderSize; pFlowData->ulUdpResponce2DataOffset = ulUdpDataOffset; ulUdpDataLength = nDataSize - ulTransportHeaderSize; pFlowData->nUdpResponce2DataLength = ulUdpDataLength; pFlowData->enUdpResponce2CompartmentID = enUdpCompartmentID; pFlowData->ulUdpResponce2IpHeaderSize = ulIpHeaderSize; pFlowData->ulUdpResponce2TransportHeaderSize = ulTransportHeaderSize; ASSERT(FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_TRANSPORT_ENDPOINT_HANDLE)); pFlowData->hUdpResponce2EndpointHandle = inMetaValues->transportEndpointHandle; pFlowData->hUdpInject2EndpointHandle = inMetaValues->transportEndpointHandle; classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; pFlowData->enContextState = csUdpWaitResponce2Pended; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); bSignalWorkerThread = IsListEmpty(&g_stPendedPacketsQueue); InsertTailList(&g_stPendedPacketsQueue, &pFlowData->threadListEntry); WdfObjectReleaseLock(wdfDeviceObject); if (bSignalWorkerThread) { KeSetEvent( &g_oWorkerEvent, 0, FALSE ); } break; case csUdpWaitReadQuery: if (pFlowData->bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Unexpect UDP-Message in state =\"csUdpWaitReadQuery\" from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); push_css(pFlowData->arContextStateStack, pFlowData->enContextState); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(wdfDeviceObject); break; case csUdpWaitReadQuery2: if (pFlowData->bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Unexpect UDP-Message in state =\"csUdpWaitReadQuery2\" from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); push_css(pFlowData->arContextStateStack, pFlowData->enContextState); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(wdfDeviceObject); break; case csUdpFlowBreak: if (pFlowData->bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Unexpect UDP-Message in state =\"csUdpFlowBreak\" from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(wdfDeviceObject); break; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid State Superintendent of State machine = %u", pFlowData->enContextState ); push_css(pFlowData->arContextStateStack, pFlowData->enContextState); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; ASSERT(FALSE); WdfObjectReleaseLock(wdfDeviceObject); break; } } void dnsfirewallWorker( __in PVOID StartContext ) { PFLOW_DATA pFlowContext; PLIST_ENTRY pListEntry; NTSTATUS status = STATUS_SUCCESS; WDFFILEOBJECT wdfFlowFileObject; PNET_BUFFER_LIST pNetBufferList; COMPARTMENT_ID enCompartmentID; PNET_BUFFER_LIST pCloneBufferList; BOOLEAN bEmpty; BOOLEAN bTestIpV4 = FALSE; BOOLEAN bIPv6; UINT32 ulRemoteAddress = 0, ulRemoteAddressN = 0; IN_ADDR stIpAddress; WCHAR szIpAddress[128]; LPWSTR pAddressEnd; UINT16 usRemotePort; IN6_ADDR stIp6Address; IPPROTO enIpProto; StartContext; for (;;) { KeWaitForSingleObject( &g_oWorkerEvent, Executive, KernelMode, FALSE, NULL ); if (g_bDriverUnload) { break; } WdfObjectAcquireLock(g_wdfControlDevice); if (IsListEmpty(&g_stPendedPacketsQueue)) { KeClearEvent(&g_oWorkerEvent); WdfObjectReleaseLock(g_wdfControlDevice); continue; } if (IsListHeadBad(&g_stPendedPacketsQueue)) { KeClearEvent(&g_oWorkerEvent); TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid \"g_stPendedPacketsQueue\"!!" ); InitializeListHead(&g_stPendedPacketsQueue); WdfObjectReleaseLock(g_wdfControlDevice); continue; } pListEntry = RemoveHeadList(&g_stPendedPacketsQueue); pFlowContext = CONTAINING_RECORD( pListEntry, FLOW_DATA, threadListEntry ); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; bIPv6 = pFlowContext->bIPv6; usRemotePort = pFlowContext->usRemotePort; enIpProto = pFlowContext->enIpProto; if (!bIPv6) { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = pFlowContext->nRemoteAddressV4N; bTestIpV4 = ((IPPROTO_UDP == enIpProto) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } } switch (pFlowContext->enContextState) { case csUdpPermitQueryPended: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpPermitQueryPended\"." ); } pFlowContext->enContextState = csUdpWaitPermitQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pNetBufferList = pFlowContext->pUdpQueryCloneBufferList; enCompartmentID = pFlowContext->enUdpQueryCompartmentID; if (pFlowContext->bUdpQueryClassifyPended) { if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on (pFlowContext->bUdpQueryClassifyPended)." ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (NULL != pFlowContext->hAleAuthRecvAcceptContext) { FwpsCompleteOperation( pFlowContext->hAleAuthRecvAcceptContext, pNetBufferList ); } pFlowContext->enFlowDataOwner = foUdpALEFlowEstablishList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stUdpALEFlowEstablishList, &pFlowContext->listEntry ); } WdfObjectReleaseLock(g_wdfControlDevice); if (bIPv6) { status = FwpsInjectTransportReceiveAsync( g_hInjectionHandleV6, (HANDLE) pFlowContext, NULL, 0, AF_INET6, enCompartmentID, pFlowContext->interfaceIndex, pFlowContext->subInterfaceIndex, pNetBufferList, clonedDatagramDnsQueryCompletionFn, (HANDLE) pFlowContext ); } else { status = FwpsInjectTransportReceiveAsync( g_hInjectionHandleV4, (HANDLE) pFlowContext, NULL, 0, AF_INET, enCompartmentID, pFlowContext->interfaceIndex, pFlowContext->subInterfaceIndex, pNetBufferList, clonedDatagramDnsQueryCompletionFn, (HANDLE) pFlowContext ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Call \"FwpsInjectTransportReceiveAsync\" failed with status = %!STATUS!;", status ); } break; case csUdpPermitQuery2Pended: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpPermitQuery2Pended\"." ); } pFlowContext->enContextState = csUdpWaitPermitQuery2; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pNetBufferList = pFlowContext->pUdpQuery2CloneBufferList; enCompartmentID = pFlowContext->enUdpQuery2CompartmentID; WdfObjectReleaseLock(g_wdfControlDevice); if (bIPv6) { status = FwpsInjectTransportReceiveAsync( g_hInjectionHandleV6, (HANDLE) pFlowContext, NULL, 0, AF_INET6, enCompartmentID, pFlowContext->interfaceIndex, pFlowContext->subInterfaceIndex, pNetBufferList, clonedDatagramDnsQueryCompletionFn, (HANDLE) pFlowContext ); } else { status = FwpsInjectTransportReceiveAsync( g_hInjectionHandleV4, (HANDLE) pFlowContext, NULL, 0, AF_INET, enCompartmentID, pFlowContext->interfaceIndex, pFlowContext->subInterfaceIndex, pNetBufferList, clonedDatagramDnsQueryCompletionFn, (HANDLE) pFlowContext ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Call \"FwpsInjectTransportReceiveAsync\" failed with status = %!STATUS!;", status ); } break; case csTcpPermitQueryPended: pFlowContext->enContextState = csTcpWaitPermitQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pNetBufferList = pFlowContext->pTcpQueryBufferList; WdfObjectReleaseLock(g_wdfControlDevice); if (bIPv6) { status = FwpsStreamInjectAsync( g_hInjectionHandleV6, (HANDLE) pFlowContext, 0, pFlowContext->hTcpQueryFlowID, g_nStreamIdV6, FWPS_LAYER_STREAM_V6, FWPS_STREAM_FLAG_RECEIVE, pNetBufferList, pFlowContext->nTcpQueryLength, clonedStreamDnsQueryCompletionFn, (HANDLE) pFlowContext ); } else { status = FwpsStreamInjectAsync( g_hInjectionHandleV4, (HANDLE) pFlowContext, 0, pFlowContext->hTcpQueryFlowID, g_nStreamIdV4, FWPS_LAYER_STREAM_V4, FWPS_STREAM_FLAG_RECEIVE, pNetBufferList, pFlowContext->nTcpQueryLength, clonedStreamDnsQueryCompletionFn, (HANDLE) pFlowContext ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Call \"FwpsStreamInjectAsync\" failed with status = %!STATUS!;", status ); } break; case csTcpReplaceQueryPended: pFlowContext->enContextState = csTcpWaitReplaceQueryDone; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pNetBufferList = pFlowContext->pTcpQueryInjectBufferList; WdfObjectReleaseLock(g_wdfControlDevice); if (bIPv6) { status = FwpsStreamInjectAsync( g_hInjectionHandleV6, (HANDLE) pFlowContext, 0, pFlowContext->hTcpQueryFlowID, g_nStreamIdV6, FWPS_LAYER_STREAM_V6, FWPS_STREAM_FLAG_RECEIVE, pNetBufferList, pFlowContext->nTcpQueryInjectDataSize, allocatedStreamDnsQueryCompletionFn, (HANDLE) pFlowContext ); } else { status = FwpsStreamInjectAsync( g_hInjectionHandleV4, (HANDLE) pFlowContext, 0, pFlowContext->hTcpQueryFlowID, g_nStreamIdV4, FWPS_LAYER_STREAM_V4, FWPS_STREAM_FLAG_RECEIVE, pNetBufferList, pFlowContext->nTcpQueryInjectDataSize, allocatedStreamDnsQueryCompletionFn, (HANDLE) pFlowContext ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Call \"FwpsStreamInjectAsync\" failed with status = %!STATUS!;", status ); } break; case csTcpPermitResponcePended: pFlowContext->enContextState = csTcpWaitPermitResponce; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pNetBufferList = pFlowContext->pTcpResponceBufferList; WdfObjectReleaseLock(g_wdfControlDevice); if (bIPv6) { status = FwpsStreamInjectAsync( g_hInjectionHandleV6, (HANDLE) pFlowContext, 0, pFlowContext->hTcpResponceFlowID, g_nStreamIdV6, FWPS_LAYER_STREAM_V6, FWPS_STREAM_FLAG_SEND, pNetBufferList, pFlowContext->nTcpResponceLength, clonedStreamDnsResponceCompletionFn, (HANDLE) pFlowContext ); } else { status = FwpsStreamInjectAsync( g_hInjectionHandleV4, (HANDLE) pFlowContext, 0, pFlowContext->hTcpResponceFlowID, g_nStreamIdV4, FWPS_LAYER_STREAM_V4, FWPS_STREAM_FLAG_SEND, pNetBufferList, pFlowContext->nTcpResponceLength, clonedStreamDnsResponceCompletionFn, (HANDLE) pFlowContext ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Call \"FwpsStreamInjectAsync\" failed with status = %!STATUS!;", status ); } break; case csTcpReplaceResponcePended: pFlowContext->enContextState = csTcpWaitReplaceResponceDone; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pNetBufferList = pFlowContext->pTcpResponceInjectBufferList; WdfObjectReleaseLock(g_wdfControlDevice); if (bIPv6) { status = FwpsStreamInjectAsync( g_hInjectionHandleV6, (HANDLE) pFlowContext, 0, pFlowContext->hTcpResponceFlowID, g_nStreamIdV6, FWPS_LAYER_STREAM_V6, FWPS_STREAM_FLAG_SEND, pNetBufferList, pFlowContext->nTcpResponceInjectDataSize, allocatedStreamDnsResponceCompletionFn, (HANDLE) pFlowContext ); } else { status = FwpsStreamInjectAsync( g_hInjectionHandleV4, (HANDLE) pFlowContext, 0, pFlowContext->hTcpResponceFlowID, g_nStreamIdV4, FWPS_LAYER_STREAM_V4, FWPS_STREAM_FLAG_SEND, pNetBufferList, pFlowContext->nTcpResponceInjectDataSize, allocatedStreamDnsResponceCompletionFn, (HANDLE) pFlowContext ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Call \"FwpsStreamInjectAsync\" failed with status = %!STATUS!;", status ); } break; case csUdpWaitResponce1Pended: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpWaitResponce1Pended\"." ); } pNetBufferList = pFlowContext->pUdpResponceBufferList; // // Note that the clone will inherit the original net buffer list's offset. // status = FwpsAllocateCloneNetBufferList( pNetBufferList, g_hNetBufferListPool, NULL, 0, &pCloneBufferList ); ASSERT(NT_SUCCESS(status)); pFlowContext->pUdpResponceCloneBufferList = pCloneBufferList; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); pFlowContext->pUdpResponceBufferList = NULL; pFlowContext->enContextState = csUdpWaitResponce1; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pNetBufferList = pFlowContext->pUdpResponceCloneBufferList; WdfObjectReleaseLock(g_wdfControlDevice); if (bIPv6) { status = FwpsInjectTransportSendAsync( g_hInjectionHandleV6, (HANDLE) pFlowContext, // pFlowContext->hUdpResponceEndpointHandle, 0, &pFlowContext->stUdpResponceSendParams, AF_INET6, pFlowContext->enUdpResponceCompartmentID, pNetBufferList, clonedDatagramDnsResponceCompletionFn, (HANDLE) pFlowContext ); } else { status = FwpsInjectTransportSendAsync( g_hInjectionHandleV4, (HANDLE) pFlowContext, // pFlowContext->hUdpResponceEndpointHandle, 0, &pFlowContext->stUdpResponceSendParams, AF_INET, pFlowContext->enUdpResponceCompartmentID, pNetBufferList, clonedDatagramDnsResponceCompletionFn, (HANDLE) pFlowContext ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Call \"FwpsInjectTransportSendAsync\" failed with status = %!STATUS!;", status ); } break; case csUdpWaitResponce2Pended: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpWaitResponce2Pended\"." ); } pNetBufferList = pFlowContext->pUdpResponce2BufferList; // // Note that the clone will inherit the original net buffer list's offset. // status = FwpsAllocateCloneNetBufferList( pNetBufferList, g_hNetBufferListPool, NULL, 0, &pCloneBufferList ); ASSERT(NT_SUCCESS(status)); pFlowContext->pUdpResponce2CloneBufferList = pCloneBufferList; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); pFlowContext->pUdpResponce2BufferList = NULL; pFlowContext->enContextState = csUdpWaitResponce2; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pNetBufferList = pFlowContext->pUdpResponce2CloneBufferList; WdfObjectReleaseLock(g_wdfControlDevice); if (bIPv6) { status = FwpsInjectTransportSendAsync( g_hInjectionHandleV6, (HANDLE) pFlowContext, // pFlowContext->hUdpResponce2EndpointHandle, 0, &pFlowContext->stUdpResponce2SendParams, AF_INET6, pFlowContext->enUdpResponce2CompartmentID, pNetBufferList, clonedDatagramDnsResponceCompletionFn, (HANDLE) pFlowContext ); } else { status = FwpsInjectTransportSendAsync( g_hInjectionHandleV4, (HANDLE) pFlowContext, // pFlowContext->hUdpResponce2EndpointHandle, 0, &pFlowContext->stUdpResponce2SendParams, AF_INET, pFlowContext->enUdpResponce2CompartmentID, pNetBufferList, clonedDatagramDnsResponceCompletionFn, (HANDLE) pFlowContext ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Call \"FwpsInjectTransportSendAsync\" failed with status = %!STATUS!;", status ); } break; default: if (bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowContext->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowContext->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid State Superintendent of State machine = %u!! Host %ws; clent.port = %hu;", pFlowContext->enContextState, szIpAddress, usRemotePort ); WdfObjectReleaseLock(g_wdfControlDevice); break; } } ASSERT(g_bDriverUnload); WdfObjectAcquireLock(g_wdfControlDevice); while (!IsListEmpty(&g_stPendedPacketsQueue)) { if (!IsListEmpty(&g_stPendedPacketsQueue)) { pListEntry = RemoveTailList(&g_stPendedPacketsQueue); } } KeSetEvent( &g_oWorkerDoneEvent, 0, FALSE ); WdfObjectReleaseLock(g_wdfControlDevice); PsTerminateSystemThread(STATUS_SUCCESS); ObDereferenceObject(g_pWorkerThreadObj); g_pWorkerThreadObj = NULL; } void FilterDataCleanup( PADDRESSES_DESCRIPTOR pDeviceAddressesDescriptor ) { NTSTATUS status = STATUS_SUCCESS; PFLOW_DATA pFlowContext = NULL; PLIST_ENTRY pFlowContextEntry; WDFQUEUE wdfRequestQueue = NULL; WDFREQUEST wdfPendedRequest = NULL; PNET_BUFFER_LIST pNetBufferList; while (!IsListEmpty(&g_stFlowedFileList)) { pFlowContextEntry = g_stFlowedFileList.Blink; pFlowContext = CONTAINING_RECORD(pFlowContextEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); ASSERT(0 != pFlowContext->flowHandle); pFlowContext->enContextState = csFlowDeleted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); #pragma warning(suppress: 26110) WdfObjectReleaseLock(g_wdfControlDevice); if (IPPROTO_UDP == pFlowContext->enIpProto) { if (pFlowContext->bIPv6) { status = FwpsFlowRemoveContext( pFlowContext->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowContext->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } } else { if (pFlowContext->bIPv6) { status = FwpsFlowRemoveContext( pFlowContext->flowHandle, FWPS_LAYER_STREAM_V6, g_nStreamIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowContext->flowHandle, FWPS_LAYER_STREAM_V4, g_nStreamIdV4 ); } } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } WdfObjectAcquireLock(g_wdfControlDevice); } while (!IsListEmpty(&g_stUdpALEFlowEstablishList)) { pFlowContextEntry = RemoveTailList(&g_stUdpALEFlowEstablishList); pFlowContext = CONTAINING_RECORD(pFlowContextEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pNetBufferList = pFlowContext->pUdpQueryCloneBufferList; if (NULL != pNetBufferList) { pFlowContext->pUdpQueryCloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } if (csUdpPermitQueryPended == pFlowContext->enContextState) { if (IsListEntryInList(&pFlowContext->threadListEntry, &g_stPendedPacketsQueue)) { RtlZeroMemory(&pFlowContext->threadListEntry, sizeof(pFlowContext->threadListEntry)); InitializeListHead(&g_stPendedPacketsQueue); } } wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } pFlowContext->enContextState = csNotRun; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); } while (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pFlowContextEntry = RemoveTailList(&g_stUdpALEAcceptPendedList); pFlowContext = CONTAINING_RECORD(pFlowContextEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pNetBufferList = pFlowContext->pUdpQueryCloneBufferList; if (NULL != pNetBufferList) { pFlowContext->pUdpQueryCloneBufferList = NULL; FwpsFreeCloneNetBufferList( pNetBufferList, 0 ); } pNetBufferList = pFlowContext->pUdpQueryBufferList; if (NULL != pNetBufferList) { pFlowContext->pUdpQueryBufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } if (csUdpPermitQueryPended == pFlowContext->enContextState) { if (IsListEntryInList(&pFlowContext->threadListEntry, &g_stPendedPacketsQueue)) { RtlZeroMemory(&pFlowContext->threadListEntry, sizeof(pFlowContext->threadListEntry)); InitializeListHead(&g_stPendedPacketsQueue); } } wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } pFlowContext->enContextState = csNotRun; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); } while (!IsListEmpty(&g_stUdpAcceptNotifyList)) { pFlowContextEntry = RemoveTailList(&g_stUdpAcceptNotifyList); pFlowContext = CONTAINING_RECORD(pFlowContextEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } pFlowContext->enContextState = csNotRun; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); } while (!IsListEmpty(&g_stUdpALEAcceptRecvList)) { pFlowContextEntry = RemoveTailList(&g_stUdpALEAcceptRecvList); pFlowContext = CONTAINING_RECORD(pFlowContextEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } pFlowContext->enContextState = csNotRun; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); } while (!IsListEmpty(&g_stUdpInboundList)) { pFlowContextEntry = RemoveTailList(&g_stUdpInboundList); pFlowContext = CONTAINING_RECORD(pFlowContextEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pNetBufferList = pFlowContext->pUdpQuery2BufferList; if (NULL != pNetBufferList) { pFlowContext->pUdpQuery2BufferList = NULL; FwpsDereferenceNetBufferList( pNetBufferList, FALSE ); } wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } pFlowContext->enContextState = csNotRun; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); } while (!IsListEmpty(&g_stAcceptableList)) { pFlowContextEntry = RemoveTailList(&g_stAcceptableList); pFlowContext = CONTAINING_RECORD(pFlowContextEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } pFlowContext->enContextState = csNotRun; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); } while (!IsListEmpty(&g_stWaitForSetFilterFileList)) { pFlowContextEntry = RemoveTailList(&g_stWaitForSetFilterFileList); pFlowContext = CONTAINING_RECORD(pFlowContextEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } pFlowContext->enContextState = csNotRun; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); } while (!IsListEmpty(&g_stWaitForQuery2FileList)) { pFlowContextEntry = RemoveTailList(&g_stWaitForQuery2FileList); pFlowContext = CONTAINING_RECORD(pFlowContextEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } pFlowContext->enContextState = csNotRun; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); } while (!IsListEmpty(&g_stWaitForDoneFileList)) { pFlowContextEntry = RemoveTailList(&g_stWaitForDoneFileList); pFlowContext = CONTAINING_RECORD(pFlowContextEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } pFlowContext->enContextState = csNotRun; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); } g_bFiltersChangeInProgress = FALSE; RtlZeroMemory( &g_stFirewallConfig, sizeof(g_stFirewallConfig) ); InitializeListHead(&g_stFreeFileList); InitializeListHead(&g_stWaitForDoneFileList); InitializeListHead(&g_stWaitForQuery2FileList); InitializeListHead(&g_stWaitForSetFilterFileList); InitializeListHead(&g_stAcceptableList); InitializeListHead(&g_stUdpInboundList); InitializeListHead(&g_stUdpALEAcceptRecvList); InitializeListHead(&g_stUdpAcceptNotifyList); InitializeListHead(&g_stUdpALEAcceptPendedList); InitializeListHead(&g_stUdpALEFlowEstablishList); InitializeListHead(&g_stFlowedFileList); InitializeListHead(&g_stPendedPacketsQueue); if (NULL != g_wdfWaitRestartQueue) { WdfObjectDelete(g_wdfWaitRestartQueue); g_wdfWaitRestartQueue = NULL; } if (NULL != pDeviceAddressesDescriptor->m_pDataArray) { ExFreePoolWithTag( pDeviceAddressesDescriptor->m_pDataArray, POOL_TAG ); } RtlZeroMemory( pDeviceAddressesDescriptor, sizeof(ADDRESSES_DESCRIPTOR) ); } void NTAPI clonedDatagramDnsQueryCompletionFn( __in VOID *context, __inout NET_BUFFER_LIST *netBufferList, __in BOOLEAN dispatchLevel ) { WDFFILEOBJECT wdfFlowFileObject = NULL; PFLOW_DATA pFlowData; WDFREQUEST wdfPendedRequest; NTSTATUS status = STATUS_SUCCESS; WDFDEVICE wdfDeviceObject; WDFQUEUE wdfRequestQueue = NULL; BOOLEAN bTestIpV4 = FALSE; BOOLEAN bIPv6; UINT32 ulRemoteAddress = 0, ulRemoteAddressN = 0; IN_ADDR stIpAddress; WCHAR szIpAddress[128]; LPWSTR pAddressEnd; UINT16 usRemotePort; IN6_ADDR stIp6Address; UNREFERENCED_PARAMETER(dispatchLevel); pFlowData = (PFLOW_DATA) context; ASSERT(NULL != pFlowData); wdfFlowFileObject = pFlowData->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfDeviceObject = g_wdfControlDevice; WdfObjectAcquireLock(wdfDeviceObject); if ((csNotRun == pFlowData->enContextState) || (csFlowDeleted == pFlowData->enContextState)) { WdfObjectReleaseLock(wdfDeviceObject); return; } ASSERT(pFlowData == pFlowData->pThis); FwpsFreeCloneNetBufferList( netBufferList, 0 ); bIPv6 = pFlowData->bIPv6; usRemotePort = pFlowData->usRemotePort; if (!bIPv6) { ulRemoteAddress = pFlowData->nRemoteAddressV4; ulRemoteAddressN = pFlowData->nRemoteAddressV4N; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } } switch (pFlowData->enContextState) { case csUdpWaitResponce1: ASSERT(pFlowData->pUdpQueryCloneBufferList == netBufferList); pFlowData->pUdpQueryCloneBufferList = NULL; wdfRequestQueue = pFlowData->wdfUdpQueryPermitQueue; ASSERT(NULL != wdfRequestQueue); pFlowData->wdfUdpQueryPermitQueue = NULL; if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpWaitResponce1\"." ); } break; case csUdpWaitResponce1Pended: ASSERT(pFlowData->pUdpQueryCloneBufferList == netBufferList); pFlowData->pUdpQueryCloneBufferList = NULL; wdfRequestQueue = pFlowData->wdfUdpQueryPermitQueue; ASSERT(NULL != wdfRequestQueue); pFlowData->wdfUdpQueryPermitQueue = NULL; if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpWaitResponce1Pended\"." ); } break; case csUdpWaitPermitQuery: ASSERT(pFlowData->pUdpQueryCloneBufferList == netBufferList); pFlowData->pUdpQueryCloneBufferList = NULL; wdfRequestQueue = pFlowData->wdfUdpQueryPermitQueue; ASSERT(NULL != wdfRequestQueue); pFlowData->wdfUdpQueryPermitQueue = NULL; pFlowData->enContextState = csUdpPermitQueryDone; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpWaitPermitQuery\"." ); } break; case csUdpWaitResponce2: ASSERT(pFlowData->pUdpQuery2CloneBufferList == netBufferList); pFlowData->pUdpQuery2CloneBufferList = NULL; wdfRequestQueue = pFlowData->wdfUdpQuery2PermitQueue; ASSERT(NULL != wdfRequestQueue); pFlowData->wdfUdpQuery2PermitQueue = NULL; if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpWaitResponce2\"." ); } break; case csUdpWaitResponce2Pended: ASSERT(pFlowData->pUdpQuery2CloneBufferList == netBufferList); pFlowData->pUdpQuery2CloneBufferList = NULL; wdfRequestQueue = pFlowData->wdfUdpQuery2PermitQueue; ASSERT(NULL != wdfRequestQueue); pFlowData->wdfUdpQuery2PermitQueue = NULL; if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpWaitResponce2Pended\"." ); } break; case csUdpWaitPermitQuery2: ASSERT(pFlowData->pUdpQuery2CloneBufferList == netBufferList); pFlowData->pUdpQuery2CloneBufferList = NULL; wdfRequestQueue = pFlowData->wdfUdpQuery2PermitQueue; ASSERT(NULL != wdfRequestQueue); pFlowData->wdfUdpQuery2PermitQueue = NULL; pFlowData->enContextState = csUdpPermitQuery2Done; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Elaborated on state \"csUdpWaitPermitQuery2\"." ); } break; default: if (bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid State Superintendent of State machine = %u!! Host %ws; clent.port = %hu;", pFlowData->enContextState, szIpAddress, usRemotePort ); break; } if (NULL != wdfRequestQueue) { status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(UDP_QUERY_APPROVAL) ); WdfObjectDelete(wdfRequestQueue); } WdfObjectReleaseLock(wdfDeviceObject); } void GetStreamData( NET_BUFFER_LIST* pNetBufferList, BYTE* pDataBuffer, UINT32 nDataBufferLength, UINT32* pByteCopied ) { NET_BUFFER_LIST* pCurrentNetBufferList = pNetBufferList; NET_BUFFER_LIST* pNextNetBufferList; NET_BUFFER* pCurrentNetBuffer; NET_BUFFER* pNextNetBuffer; BYTE* pCurrentDataPointer = pDataBuffer; BYTE* pNbDataPointer; UINT32 nCurrentBufferLength, nCurrentDataLength = 0; BOOLEAN bBufferDone = FALSE; while (NULL != pCurrentNetBufferList) { pNextNetBufferList = NET_BUFFER_LIST_NEXT_NBL(pCurrentNetBufferList); pCurrentNetBuffer = NET_BUFFER_LIST_FIRST_NB(pCurrentNetBufferList); while (NULL != pCurrentNetBuffer) { pNextNetBuffer = NET_BUFFER_NEXT_NB(pCurrentNetBuffer); nCurrentBufferLength = NET_BUFFER_DATA_LENGTH(pCurrentNetBuffer); nCurrentDataLength += nCurrentBufferLength; if (nCurrentDataLength > nDataBufferLength) { bBufferDone = TRUE; nCurrentBufferLength -= nCurrentDataLength - nDataBufferLength; } if (nCurrentBufferLength > 0) { pNbDataPointer = (BYTE*) NdisGetDataBuffer( pCurrentNetBuffer, nCurrentBufferLength, pCurrentDataPointer, 1, 0 ); ASSERT(NULL != pNbDataPointer); if (pNbDataPointer != pCurrentDataPointer) { #pragma warning(suppress: 6387) RtlCopyMemory( pCurrentDataPointer, pNbDataPointer, nCurrentBufferLength ); } pCurrentDataPointer += nCurrentBufferLength; } if (bBufferDone) { *pByteCopied = nDataBufferLength; return; } pCurrentNetBuffer = pNextNetBuffer; } pCurrentNetBufferList = pNextNetBufferList; } *pByteCopied = nCurrentDataLength; } void NTAPI clonedStreamDnsQueryCompletionFn( __in VOID *context, __inout NET_BUFFER_LIST *netBufferList, __in BOOLEAN dispatchLevel ) { WDFFILEOBJECT wdfFlowFileObject; PFLOW_DATA pFlowData; WDFREQUEST wdfPendedRequest; NTSTATUS status = STATUS_SUCCESS; WDFDEVICE wdfDeviceObject; WDFQUEUE wdfRequestQueue; int i = 0; UINT32 ulInboundCount = 0; PLIST_ENTRY pListEntry, pLastLE; PFLOW_DATA pFlowContext = NULL; BOOLEAN bIPv6; IN6_ADDR stRemoteAddress; UINT32 ulRemoteAddress = 0, ulRemoteAddressN = 0; UINT16 usRemotePort; BOOLEAN bTestIpV4; IN_ADDR stIpAddress; WCHAR szIpAddress[128]; LPWSTR pAddressEnd; WDFMEMORY wdfOutputMemory = NULL; BOOLEAN bEmpty; UNREFERENCED_PARAMETER(dispatchLevel); pFlowData = (PFLOW_DATA) context; ASSERT(NULL != pFlowData); wdfFlowFileObject = pFlowData->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfDeviceObject = g_wdfControlDevice; WdfObjectAcquireLock(wdfDeviceObject); if (csFlowDeleted == pFlowData->enContextState) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (csFlowDeleted == pFlowData->enContextState)" ); WdfObjectReleaseLock(wdfDeviceObject); return; } ASSERT(pFlowData == pFlowData->pThis); if (NULL != NET_BUFFER_LIST_NEXT_NBL(netBufferList)) { FwpsFreeCloneNetBufferList( netBufferList, 0 ); //push_css(pFlowData->arContextStateStack, pFlowData->enContextState); WdfObjectReleaseLock(wdfDeviceObject); return; } else { FwpsFreeCloneNetBufferList( netBufferList, 0 ); } pFlowData->pTcpQueryBufferList = NULL; pFlowData->hTcpQueryFlowID = 0; wdfRequestQueue = pFlowData->wdfTcpQueryPermitQueue; if (NULL != wdfRequestQueue) { pFlowData->wdfTcpQueryPermitQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(TCP_QUERY_APPROVAL) ); WdfObjectDelete(wdfRequestQueue); } switch (pFlowData->arContextStateStack[i]) { case csTcpWaitPermitQuery: case csTcpPermitQueryDone: pFlowData->enContextState = csTcpPermitQueryDone; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpWaitQueryInjectDone: pFlowData->enContextState = csTcpWaitReadResponce; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csDnsError: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csDnsError\"" ); push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpResponceMoreData02: pFlowData->enContextState = csTcpResponceMoreData01; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpClientDisconnect: case csTcpServerDisconnect: ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } push_css(pFlowData->arContextStateStack, pFlowData->enContextState); WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_STREAM_V6, g_nStreamIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_STREAM_V4, g_nStreamIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } return; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid State Superintendent of State machine" ); break; } WdfObjectReleaseLock(wdfDeviceObject); } void NTAPI allocatedStreamDnsQueryCompletionFn( __in VOID *context, __inout NET_BUFFER_LIST *netBufferList, __in BOOLEAN dispatchLevel ) { WDFFILEOBJECT wdfFlowFileObject; PFLOW_DATA pFlowData; WDFREQUEST wdfPendedRequest; NTSTATUS status = STATUS_SUCCESS; PMDL _pMdl; ULONG_PTR Information; WDFDEVICE wdfDeviceObject; WDFQUEUE wdfRequestQueue; int i = 0; UINT32 ulInboundCount = 0; PLIST_ENTRY pListEntry, pLastLE; PFLOW_DATA pFlowContext = NULL; BOOLEAN bIPv6; IN6_ADDR stRemoteAddress; UINT32 ulRemoteAddress = 0, ulRemoteAddressN = 0; UINT16 usRemotePort; BOOLEAN bTestIpV4; IN_ADDR stIpAddress; WCHAR szIpAddress[128]; LPWSTR pAddressEnd; WDFMEMORY wdfOutputMemory = NULL; BOOLEAN bEmpty; UNREFERENCED_PARAMETER(dispatchLevel); pFlowData = (PFLOW_DATA) context; ASSERT(NULL != pFlowData); wdfFlowFileObject = pFlowData->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfDeviceObject = g_wdfControlDevice; WdfObjectAcquireLock(wdfDeviceObject); if (csFlowDeleted == pFlowData->enContextState) { WdfObjectReleaseLock(wdfDeviceObject); return; } ASSERT(pFlowData == pFlowData->pThis); ASSERT(pFlowData->pTcpQueryInjectBufferList == netBufferList); FwpsFreeNetBufferList( netBufferList ); pFlowData->pTcpQueryInjectBufferList = NULL; _pMdl = pFlowData->pTcpQueryMdl; ASSERT(NULL != _pMdl); IoFreeMdl(_pMdl); ExFreePoolWithTag( _pMdl->MappedSystemVa, POOL_TAG ); pFlowData->pTcpQueryMdl = NULL; wdfRequestQueue = pFlowData->wdfTcpQueryInjectQueue; pFlowData->wdfTcpQueryInjectQueue = NULL; if (NULL != wdfRequestQueue) { status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); Information = pFlowData->nTcpQueryInjectDataSize; pFlowData->nTcpQueryInjectDataSize = 0; ASSERT(0 != Information); WdfRequestCompleteWithInformation( wdfPendedRequest, status, Information ); WdfObjectDelete(wdfRequestQueue); } switch (pFlowData->arContextStateStack[i]) { case csTcpWaitReplaceQueryDone: pFlowData->enContextState = csTcpReplaceQueryDone; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpWaitQueryInjectDone: pFlowData->enContextState = csTcpWaitReadResponce; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csDnsError: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! State of the State machine is \"csDnsError\"" ); push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpResponceMoreData02: pFlowData->enContextState = csTcpResponceMoreData01; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpClientDisconnect: case csTcpServerDisconnect: ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } push_css(pFlowData->arContextStateStack, pFlowData->enContextState); WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_STREAM_V6, g_nStreamIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_STREAM_V4, g_nStreamIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } return; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid State Superintendent of State machine" ); break; } WdfObjectReleaseLock(wdfDeviceObject); } void NTAPI clonedStreamDnsResponceCompletionFn( __in VOID *context, __inout NET_BUFFER_LIST *netBufferList, __in BOOLEAN dispatchLevel ) { WDFFILEOBJECT wdfFlowFileObject; PFLOW_DATA pFlowData; WDFREQUEST wdfPendedRequest; NTSTATUS status = STATUS_SUCCESS; BOOLEAN bInbound; WDFDEVICE wdfDeviceObject; WDFQUEUE wdfRequestQueue; int i = 0; UINT32 ulInboundCount = 0; PLIST_ENTRY pListEntry, pLastLE; PFLOW_DATA pFlowContext = NULL; BOOLEAN bIPv6; IN6_ADDR stRemoteAddress; UINT32 ulRemoteAddress = 0, ulRemoteAddressN = 0; UINT16 usRemotePort; BOOLEAN bTestIpV4; IN_ADDR stIpAddress; WCHAR szIpAddress[128]; LPWSTR pAddressEnd; WDFMEMORY wdfOutputMemory = NULL; BOOLEAN bEmpty; UNREFERENCED_PARAMETER(dispatchLevel); pFlowData = (PFLOW_DATA) context; ASSERT(NULL != pFlowData); wdfFlowFileObject = pFlowData->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfDeviceObject = g_wdfControlDevice; WdfObjectAcquireLock(wdfDeviceObject); if (csFlowDeleted == pFlowData->enContextState) { WdfObjectReleaseLock(wdfDeviceObject); return; } ASSERT(pFlowData == pFlowData->pThis); bInbound = (BOOLEAN) (FWP_DIRECTION_INBOUND == pFlowData->enPacketDirection); if (NULL != NET_BUFFER_LIST_NEXT_NBL(netBufferList)) { FwpsFreeCloneNetBufferList( netBufferList, 0 ); //push_css(pFlowData->arContextStateStack, pFlowData->enContextState); WdfObjectReleaseLock(wdfDeviceObject); return; } else { FwpsFreeCloneNetBufferList( netBufferList, 0 ); } pFlowData->pTcpResponceBufferList = NULL; wdfRequestQueue = pFlowData->wdfTcpResponcePermitQueue; pFlowData->wdfTcpResponcePermitQueue = NULL; if (NULL != wdfRequestQueue) { status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(TCP_RESPONCE_APPROVAL) ); WdfObjectDelete(wdfRequestQueue); } switch (pFlowData->arContextStateStack[i]) { case csTcpPermitResponceDone: goto _cont14; case csTcpWaitPermitResponce: _cont14 : pFlowData->enContextState = csTcpPermitResponceDone; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpWaitResponceInjectDone: if (bInbound) { pFlowData->enContextState = csTcpWaitReadQuery; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); } else { pFlowData->enContextState = csTcpWaitReadResponce; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); } break; case csTcpQueryMoreData02: push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpClientDisconnect: case csTcpServerDisconnect: ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } push_css(pFlowData->arContextStateStack, pFlowData->enContextState); WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_STREAM_V6, g_nStreamIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_STREAM_V4, g_nStreamIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } return; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_QUEUE, "%!FUNC! line:%!LINE! %!LEVEL! Invalid State Superintendent of State machine" ); break; } WdfObjectReleaseLock(wdfDeviceObject); } void NTAPI allocatedStreamDnsResponceCompletionFn( __in VOID *context, __inout NET_BUFFER_LIST *netBufferList, __in BOOLEAN dispatchLevel ) { WDFFILEOBJECT wdfFlowFileObject; PFLOW_DATA pFlowData; WDFREQUEST wdfPendedRequest; NTSTATUS status = STATUS_SUCCESS; PMDL _pMdl; ULONG_PTR Information; BOOLEAN bInbound; WDFDEVICE wdfDeviceObject; WDFQUEUE wdfRequestQueue; int i = 0; UINT32 ulInboundCount = 0; PLIST_ENTRY pListEntry, pLastLE; PFLOW_DATA pFlowContext = NULL; BOOLEAN bIPv6; IN6_ADDR stRemoteAddress; UINT32 ulRemoteAddress = 0, ulRemoteAddressN = 0; UINT16 usRemotePort; BOOLEAN bTestIpV4; IN_ADDR stIpAddress; WCHAR szIpAddress[128]; LPWSTR pAddressEnd; WDFMEMORY wdfOutputMemory = NULL; BOOLEAN bEmpty; UNREFERENCED_PARAMETER(dispatchLevel); pFlowData = (PFLOW_DATA) context; ASSERT(NULL != pFlowData); wdfFlowFileObject = pFlowData->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfDeviceObject = g_wdfControlDevice; WdfObjectAcquireLock(wdfDeviceObject); ASSERT(pFlowData == pFlowData->pThis); if (pFlowData->pTcpResponceInjectBufferList != netBufferList) { WdfObjectReleaseLock(wdfDeviceObject); return; } bInbound = (BOOLEAN) (FWP_DIRECTION_INBOUND == pFlowData->enPacketDirection); _pMdl = pFlowData->pTcpResponceMdl; ASSERT(NULL != _pMdl); IoFreeMdl(_pMdl); ExFreePoolWithTag( _pMdl->MappedSystemVa, POOL_TAG ); FwpsFreeNetBufferList( netBufferList ); pFlowData->pTcpResponceMdl = NULL; pFlowData->pTcpResponceInjectBufferList = NULL; wdfRequestQueue = pFlowData->wdfTcpResponceInjectQueue; pFlowData->wdfTcpResponceInjectQueue = NULL; if (NULL != wdfRequestQueue) { status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); Information = pFlowData->nTcpResponceInjectDataSize; pFlowData->nTcpResponceInjectDataSize = 0; ASSERT(0 != Information); WdfRequestCompleteWithInformation( wdfPendedRequest, status, Information ); WdfObjectDelete(wdfRequestQueue); } switch (pFlowData->arContextStateStack[i]) { case csTcpWaitReplaceResponceDone: pFlowData->enContextState = csTcpReplaceResponceDone; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpWaitResponceInjectDone: if (bInbound) { pFlowData->enContextState = csTcpWaitReadQuery; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); } else { pFlowData->enContextState = csTcpWaitReadResponce; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); } break; case csTcpQueryMoreData02: push_css(pFlowData->arContextStateStack, pFlowData->enContextState); break; case csTcpClientDisconnect: case csTcpServerDisconnect: ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } push_css(pFlowData->arContextStateStack, pFlowData->enContextState); WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_STREAM_V6, g_nStreamIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_STREAM_V4, g_nStreamIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } return; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_QUEUE, "%!FUNC! line:%!LINE! %!LEVEL! Invalid State Superintendent of State machine" ); break; } WdfObjectReleaseLock(wdfDeviceObject); } void NTAPI clonedDatagramDnsResponceCompletionFn( __in VOID *context, __inout NET_BUFFER_LIST *netBufferList, __in BOOLEAN dispatchLevel ) { WDFFILEOBJECT wdfFlowFileObject = NULL; WDFQUEUE wdfFlowQueue; int nFileIndex, nThreadIndex; PFLOW_DATA pFlowData; WDFREQUEST wdfPendedRequest; NTSTATUS status = STATUS_SUCCESS; WSACMSGHDR* _pControlData = NULL; WDFDEVICE wdfDeviceObject; WDFQUEUE wdfRequestQueue; WDFMEMORY wdfOutputMemory = NULL; PLIST_ENTRY pListEntry, pFirstLE, pLastLE, pPrevLE; PFLOW_DATA pFlowContext = NULL, pFirstFlowContext = NULL; UINT32 ulInboundCount = 0; BOOLEAN bEmpty, bIPv6; UINT32 ulRemoteAddress = 0, ulRemoteAddressN = 0; FWP_BYTE_ARRAY16 stRemoteAddress = { 0 }; IN_ADDR stIpAddress; IN6_ADDR stIp6Address; WCHAR szIpAddress[128]; LPWSTR pAddressEnd; UINT16 usRemotePort; BOOLEAN bTestIpV4; UNREFERENCED_PARAMETER(dispatchLevel); pFlowData = (PFLOW_DATA) context; ASSERT(NULL != pFlowData); wdfFlowFileObject = pFlowData->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfDeviceObject = g_wdfControlDevice; WdfObjectAcquireLock(wdfDeviceObject); if ((csNotRun == pFlowData->enContextState) || (csFlowDeleted == pFlowData->enContextState)) { WdfObjectReleaseLock(wdfDeviceObject); return; } ASSERT(pFlowData == pFlowData->pThis); FwpsFreeCloneNetBufferList( netBufferList, 0 ); bIPv6 = pFlowData->bIPv6; if (bIPv6) { IPv6CopyAddress( &stRemoteAddress, &pFlowData->stRemoteAddressV6 ); } else { ulRemoteAddress = pFlowData->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowData->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } switch (pFlowData->enContextState) { case csUdpWaitResponce1: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host will Elaborated on state \"csUdpWaitResponce1\"." ); } ASSERT(pFlowData->pUdpResponceCloneBufferList == netBufferList); pFlowData->pUdpResponceCloneBufferList = NULL; _pControlData = pFlowData->stUdpResponceSendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponceSendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); pFlowData->bUdpFlow1Done = TRUE; if (!IsListEmpty(&g_stUdpInboundList)) { pListEntry = g_stUdpInboundList.Blink; pFirstLE = g_stUdpInboundList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (bIPv6 && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(&stRemoteAddress, &pFlowContext->stRemoteAddressV6)) { pFirstFlowContext = pFlowContext; ulInboundCount++; } } else if ((!bIPv6) && (!pFlowContext->bIPv6)) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { pFirstFlowContext = pFlowContext; ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } pFlowData->enContextState = csUdpFlow1Done; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); if (ulInboundCount > 1) { pListEntry = g_stUdpInboundList.Blink; pFirstLE = g_stUdpInboundList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (bIPv6 && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(&stRemoteAddress, &pFlowContext->stRemoteAddressV6)) { switch (pFlowContext->enContextState) { case csUdpInboundPended: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (NULL != pFlowContext->pUdpQuery2BufferList) { FwpsDereferenceNetBufferList( pFlowContext->pUdpQuery2BufferList, FALSE ); pFlowContext->pUdpQuery2BufferList = NULL; } pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); if (bEmpty) { break; } } } else if ((!bIPv6) && (!pFlowContext->bIPv6)) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { switch (pFlowContext->enContextState) { case csUdpInboundPended: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (NULL != pFlowContext->pUdpQuery2CloneBufferList) { FwpsFreeCloneNetBufferList( pFlowContext->pUdpQuery2CloneBufferList, 0 ); pFlowContext->pUdpQuery2CloneBufferList = NULL; } if (NULL != pFlowContext->pUdpQuery2BufferList) { FwpsDereferenceNetBufferList( pFlowContext->pUdpQuery2BufferList, FALSE ); pFlowContext->pUdpQuery2BufferList = NULL; } pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); if (bEmpty) { break; } } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } if (!IsListEmpty(&g_stUdpAcceptNotifyList)) { pListEntry = g_stUdpAcceptNotifyList.Blink; pFirstLE = g_stUdpAcceptNotifyList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (bIPv6 && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(&stRemoteAddress, &pFlowContext->stRemoteAddressV6)) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); if (bEmpty) { break; } } } else if ((!bIPv6) && (!pFlowContext->bIPv6)) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); if (bEmpty) { break; } } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } if (!IsListEmpty(&g_stUdpALEAcceptRecvList)) { pListEntry = g_stUdpALEAcceptRecvList.Blink; pFirstLE = g_stUdpALEAcceptRecvList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (bIPv6 && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(&stRemoteAddress, &pFlowContext->stRemoteAddressV6)) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); if (bEmpty) { break; } } } else if ((!bIPv6) && (!pFlowContext->bIPv6)) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); if (bEmpty) { break; } } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Blink; pFirstLE = g_stUdpALEAcceptPendedList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (bIPv6 && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(&stRemoteAddress, &pFlowContext->stRemoteAddressV6)) { switch (pFlowContext->enContextState) { case csUdpFlowEstablishPended: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (NULL != pFlowContext->pUdpQueryCloneBufferList) { FwpsFreeCloneNetBufferList( pFlowContext->pUdpQueryCloneBufferList, 0 ); pFlowContext->pUdpQueryCloneBufferList = NULL; } if (NULL != pFlowContext->pUdpQueryBufferList) { FwpsDereferenceNetBufferList( pFlowContext->pUdpQueryBufferList, FALSE ); pFlowContext->pUdpQueryBufferList = NULL; } if (NULL == pFlowContext->wdfWaitDnsQueryQueue) { wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, sizeof(FLOW_DATA) ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else { pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } if (bEmpty) { break; } } } else if ((!bIPv6) && (!pFlowContext->bIPv6)) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { switch (pFlowContext->enContextState) { case csUdpFlowEstablishPended: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (NULL != pFlowContext->pUdpQueryBufferList) { FwpsDereferenceNetBufferList( pFlowContext->pUdpQueryBufferList, FALSE ); pFlowContext->pUdpQueryBufferList = NULL; } if (NULL == pFlowContext->wdfWaitDnsQueryQueue) { wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, sizeof(FLOW_DATA) ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else { pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } if (bEmpty) { break; } } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } if (!IsListEmpty(&g_stUdpALEFlowEstablishList)) { pListEntry = g_stUdpALEFlowEstablishList.Blink; pFirstLE = g_stUdpALEFlowEstablishList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (bIPv6 && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(&stRemoteAddress, &pFlowContext->stRemoteAddressV6)) { switch (pFlowContext->enContextState) { case csUdpAcceptedRecv: break; case csUdpWaitPermitQuery: if (!pFlowContext->bUdpQueryClassifyPended) { ASSERT(FALSE); } break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (NULL == pFlowContext->wdfWaitDnsQueryQueue) { wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, sizeof(FLOW_DATA) ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else { pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } if (bEmpty) { break; } } } else if ((!bIPv6) && (!pFlowContext->bIPv6)) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { switch (pFlowContext->enContextState) { case csUdpAcceptedRecv: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (NULL == pFlowContext->wdfWaitDnsQueryQueue) { wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, sizeof(FLOW_DATA) ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else { pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } if (bEmpty) { break; } } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { ulInboundCount = 0; pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { IPv6CopyAddress( &stRemoteAddress, &pFlowContext->stRemoteAddressV6 ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } bIPv6 = pFlowData->bIPv6; if (bIPv6) { IPv6CopyAddress( &stRemoteAddress, &pFlowData->stRemoteAddressV6 ); } else { ulRemoteAddress = pFlowData->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowData->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } if (bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Posible UDP-Attack to DNS port from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); g_bFiltersChangeInProgress = TRUE; wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; ASSERT(NULL != wdfRequestQueue); pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowData, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); WdfObjectReleaseLock(g_wdfControlDevice); pFlowData->enContextState = csUdpFlowSetFirewallEvent; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); WdfObjectReleaseLock(g_wdfControlDevice); if (bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } return; } if (1 == ulInboundCount) { pFlowContext = pFirstFlowContext; switch (pFlowContext->enContextState) { case csUdpInboundPended: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowData->usRemotePort = pFlowContext->usRemotePort; pFlowData->interfaceIndex = pFlowContext->interfaceIndex; pFlowData->subInterfaceIndex = pFlowContext->subInterfaceIndex; pFlowData->pUdpQuery2BufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowData->ulUdpQuery2BufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowData->ulUdpQuery2DataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowData->ulUdpQuery2PacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowData->ulUdpQuery2DataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowData->enUdpQuery2CompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowData->ulUdpQuery2IpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowData->ulUdpQuery2TransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowData->bUdpNotInboundTransport = pFlowContext->bUdpNotInboundTransport; pFlowContext->bUdpNotInboundTransport = FALSE; pFlowData->bUdpQueryClassifyPended = TRUE; pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); pFlowData->ulUdpQueryCount++; if (pFlowData->bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Repeated UDP-Query from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); wdfRequestQueue = pFlowData->wdfWaitUdpQuery2Queue; ASSERT(NULL != wdfRequestQueue); pFlowData->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowData, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); pFlowData->enContextState = csUdpWaitReadQuery2; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); WdfObjectReleaseLock(g_wdfControlDevice); return; } ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } bIPv6 = pFlowData->bIPv6; if (bIPv6) { IPv6CopyAddress( &stRemoteAddress, &pFlowData->stRemoteAddressV6 ); } else { ulRemoteAddress = pFlowData->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowData->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Done." ); } pFlowData->enContextState = csUdpFlowDone; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } return; case csUdpWaitResponce2: if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host will Elaborated on state \"csUdpWaitResponce2\"." ); } ASSERT(pFlowData->pUdpResponce2CloneBufferList == netBufferList); pFlowData->pUdpResponce2CloneBufferList = NULL; _pControlData = pFlowData->stUdpResponce2SendParams.controlData; if (NULL != _pControlData) { ExFreePoolWithTag( _pControlData, POOL_TAG ); } RtlZeroMemory( &pFlowData->stUdpResponce2SendParams, sizeof(FWPS_TRANSPORT_SEND_PARAMS) ); if (!IsListEmpty(&g_stUdpInboundList)) { pListEntry = g_stUdpInboundList.Blink; pFirstLE = g_stUdpInboundList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (bIPv6 && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(&stRemoteAddress, &pFlowContext->stRemoteAddressV6)) { pFirstFlowContext = pFlowContext; ulInboundCount++; } } else if ((!bIPv6) && (!pFlowContext->bIPv6)) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { pFirstFlowContext = pFlowContext; ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } if (ulInboundCount > 0) { pListEntry = g_stUdpInboundList.Blink; pFirstLE = g_stUdpInboundList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (bIPv6 && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(&stRemoteAddress, &pFlowContext->stRemoteAddressV6)) { switch (pFlowContext->enContextState) { case csUdpInboundPended: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (NULL != pFlowContext->pUdpQuery2BufferList) { FwpsDereferenceNetBufferList( pFlowContext->pUdpQuery2BufferList, FALSE ); pFlowContext->pUdpQuery2BufferList = NULL; } pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } else if ((!bIPv6) && (!pFlowContext->bIPv6)) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { switch (pFlowContext->enContextState) { case csUdpInboundPended: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (NULL != pFlowContext->pUdpQuery2CloneBufferList) { FwpsFreeCloneNetBufferList( pFlowContext->pUdpQuery2CloneBufferList, 0 ); pFlowContext->pUdpQuery2CloneBufferList = NULL; } if (NULL != pFlowContext->pUdpQuery2BufferList) { FwpsDereferenceNetBufferList( pFlowContext->pUdpQuery2BufferList, FALSE ); pFlowContext->pUdpQuery2BufferList = NULL; } pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } if (!IsListEmpty(&g_stUdpAcceptNotifyList)) { pListEntry = g_stUdpAcceptNotifyList.Blink; pFirstLE = g_stUdpAcceptNotifyList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (bIPv6 && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(&stRemoteAddress, &pFlowContext->stRemoteAddressV6)) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } else if ((!bIPv6) && (!pFlowContext->bIPv6)) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } if (!IsListEmpty(&g_stUdpALEAcceptRecvList)) { pListEntry = g_stUdpALEAcceptRecvList.Blink; pFirstLE = g_stUdpALEAcceptRecvList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (bIPv6 && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(&stRemoteAddress, &pFlowContext->stRemoteAddressV6)) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } else if ((!bIPv6) && (!pFlowContext->bIPv6)) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Blink; pFirstLE = g_stUdpALEAcceptPendedList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (csUdpWaitReadQuery != pFlowContext->enContextState) { if (bIPv6 && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(&stRemoteAddress, &pFlowContext->stRemoteAddressV6)) { switch (pFlowContext->enContextState) { case csUdpFlowEstablishPended: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (NULL != pFlowContext->pUdpQueryCloneBufferList) { FwpsFreeCloneNetBufferList( pFlowContext->pUdpQueryCloneBufferList, 0 ); pFlowContext->pUdpQueryCloneBufferList = NULL; } if (NULL != pFlowContext->pUdpQueryBufferList) { FwpsDereferenceNetBufferList( pFlowContext->pUdpQueryBufferList, FALSE ); pFlowContext->pUdpQueryBufferList = NULL; } if (NULL == pFlowContext->wdfWaitDnsQueryQueue) { wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, sizeof(FLOW_DATA) ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else { pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bIPv6 = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } } else if ((!bIPv6) && (!pFlowContext->bIPv6)) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { switch (pFlowContext->enContextState) { case csUdpFlowEstablishPended: break; default: ASSERT(FALSE); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (NULL != pFlowContext->pUdpQueryBufferList) { FwpsDereferenceNetBufferList( pFlowContext->pUdpQueryBufferList, FALSE ); pFlowContext->pUdpQueryBufferList = NULL; } if (NULL == pFlowContext->wdfWaitDnsQueryQueue) { wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, sizeof(FLOW_DATA) ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else { pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bIPv6 = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } if (!IsListEmpty(&g_stUdpALEFlowEstablishList)) { pListEntry = g_stUdpALEFlowEstablishList.Blink; pFirstLE = g_stUdpALEFlowEstablishList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (bIPv6 && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(&stRemoteAddress, &pFlowContext->stRemoteAddressV6)) { switch (pFlowContext->enContextState) { case csUdpAcceptedRecv: bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (NULL == pFlowContext->wdfWaitDnsQueryQueue) { wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, sizeof(FLOW_DATA) ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else { pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } break; case csUdpWaitPermitQuery: case csUdpPermitQueryDone: if (!pFlowContext->bUdpQueryClassifyPended) { ASSERT(FALSE); } break; default: ASSERT(FALSE); } } } else if ((!bIPv6) && (!pFlowContext->bIPv6)) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { switch (pFlowContext->enContextState) { case csUdpAcceptedRecv: bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (NULL == pFlowContext->wdfWaitDnsQueryQueue) { wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, sizeof(FLOW_DATA) ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else { pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } break; case csUdpWaitPermitQuery: case csUdpPermitQueryDone: if (!pFlowContext->bUdpQueryClassifyPended) { ASSERT(FALSE); } break; default: ASSERT(FALSE); } } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { ulInboundCount = 0; pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { IPv6CopyAddress( &stRemoteAddress, &pFlowContext->stRemoteAddressV6 ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } bIPv6 = pFlowData->bIPv6; if (bIPv6) { IPv6CopyAddress( &stRemoteAddress, &pFlowData->stRemoteAddressV6 ); } else { ulRemoteAddress = pFlowData->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowData->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } if (bIPv6) { RtlCopyMemory( &stIp6Address, &pFlowData->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); } else { stIpAddress.S_un.S_addr = pFlowData->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); } TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Posible UDP-Attack to DNS port from host %ws; clent.port = %hu;", szIpAddress, pFlowData->usRemotePort ); g_bFiltersChangeInProgress = TRUE; wdfRequestQueue = pFlowData->wdfWaitUdpSetFirewallFilterQueue; ASSERT(NULL != wdfRequestQueue); pFlowData->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowData, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); pFlowData->enContextState = csUdpFlowSetFirewallEvent; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); WdfObjectReleaseLock(g_wdfControlDevice); if (bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } return; } ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } bIPv6 = pFlowData->bIPv6; if (bIPv6) { IPv6CopyAddress( &stRemoteAddress, &pFlowData->stRemoteAddressV6 ); } else { ulRemoteAddress = pFlowData->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowData->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Flow Context from Test IpV4 Host %ws will removed; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowData->enContextState = csUdpFlowDone; push_css(pFlowData->arContextStateStack, pFlowData->enContextState); WdfObjectReleaseLock(wdfDeviceObject); if (pFlowData->bIPv6) { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); } else { status = FwpsFlowRemoveContext( pFlowData->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); } if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } return; default: TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Invalid State Superintendent of State machine = %u", pFlowData->enContextState ); break; } WdfObjectReleaseLock(wdfDeviceObject); } void NTAPI onInboundTransportV4Classify( __in const FWPS_INCOMING_VALUES* inFixedValues, __in const FWPS_INCOMING_METADATA_VALUES* inMetaValues, __inout_opt void* layerData, _In_opt_ const void* classifyContext, __in const FWPS_FILTER* filter, __in UINT64 flowContext, __inout FWPS_CLASSIFY_OUT* classifyOut ) { static BOOLEAN bWaitRestartQueueInit = FALSE; static WDFQUEUE wdfWaitRestartQueue = NULL; static FLOW_DATA stFlowDataCopy; static WCHAR szIpAddress[128]; static BYTE baDataArray[512]; PADDRESSES_DESCRIPTOR pAddressesDescriptor = NULL; UINT32 ulRemoteAddress, ulI; int i; BOOLEAN bLocalNetwork = FALSE; PLIST_ENTRY pListEntry, pFirstLE, pPrevLE, pLastLE, pNextLE; PFLOW_DATA pFlowContext = NULL, pInboundContext = NULL; UINT32 ulInboundCount = 0; BOOLEAN bEmpty; FWPS_PACKET_INJECTION_STATE packetState; HANDLE hInjectionHandle; PNET_BUFFER_LIST pNetBufferList; WDFFILEOBJECT wdfInjectDataObject = NULL; WDFQUEUE wdfRequestQueue; WDFREQUEST wdfPendedRequest; NTSTATUS status = STATUS_SUCCESS; WDFMEMORY wdfOutputMemory; WDFFILEOBJECT wdfFlowFileObject = NULL; WDFQUEUE wdfFlowQueue; int nFileIndex, nThreadIndex; IPPROTO enIpProto; BOOLEAN bFlowDataCopy = FALSE; PNET_BUFFER pNetBuffer; UINT32 nDataSize; UINT32 ulUdpDataOffset; UINT32 ulIpHeaderSize; UINT32 ulTransportHeaderSize; COMPARTMENT_ID enUdpCompartmentID; UINT32 ulUdpDataLength; UINT16 usRemotePort; UINT32 ulRemoteAddressN; IN_ADDR stIpAddress; LPWSTR pAddressEnd; BOOLEAN bTestIpV4; PBYTE pInboundData; PDNS_HEADER pDnsHeader; BOOLEAN bDnsNotify = FALSE; BOOLEAN bInboundExist = FALSE; UNREFERENCED_PARAMETER(filter); UNREFERENCED_PARAMETER(classifyContext); UNREFERENCED_PARAMETER(flowContext); if (!(classifyOut->rights & FWPS_RIGHT_ACTION_WRITE)) { return; } if (NULL != g_wdfWaitRestartQueue && !bWaitRestartQueueInit) { bWaitRestartQueueInit = TRUE; wdfWaitRestartQueue = g_wdfWaitRestartQueue; } else if (NULL == g_wdfWaitRestartQueue && bWaitRestartQueueInit) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! (NULL == g_wdfWaitRestartQueue && bWaitRestartQueueInit);" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; return; } WdfObjectAcquireLock(g_wdfControlDevice); pNetBufferList = (PNET_BUFFER_LIST) layerData; ASSERT(pNetBufferList != NULL); enIpProto = (IPPROTO) inFixedValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V4_IP_PROTOCOL].value.uint8; ASSERT(IPPROTO_UDP == enIpProto); hInjectionHandle = g_hInjectionHandleV4; ulRemoteAddress = inFixedValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V4_IP_REMOTE_ADDRESS].value.uint32; enUdpCompartmentID = (COMPARTMENT_ID) inMetaValues->compartmentId; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); ASSERT(FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_IP_HEADER_SIZE)); ulIpHeaderSize = inMetaValues->ipHeaderSize; ulTransportHeaderSize = inMetaValues->transportHeaderSize; usRemotePort = inFixedValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V4_IP_REMOTE_PORT].value.uint16; pNetBuffer = NET_BUFFER_LIST_FIRST_NB(pNetBufferList); nDataSize = NET_BUFFER_DATA_LENGTH(pNetBuffer); ulUdpDataOffset = NET_BUFFER_DATA_OFFSET(pNetBuffer); if (0 == nDataSize) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! (0 == nDataSize)!! Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pAddressesDescriptor = WdfObjectGetTypedContext( g_wdfControlDevice, ADDRESSES_DESCRIPTOR ); if (NULL == pAddressesDescriptor) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! pAddressesDescriptor == NULL" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL == pAddressesDescriptor->m_pDataArray) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! pAddressesDescriptor->m_pDataArray == NULL" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (c_ulLocalHost == ulRemoteAddress) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPublicIpArray) { for (i = 0; im_nPublicIpCount; i++) { if (ulRemoteAddress == pAddressesDescriptor->m_pPublicIpArray[i]) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPrivateIpArray) { for (i = 0; im_nPrivateIpCount; i++) { if (ulRemoteAddress == pAddressesDescriptor->m_pPrivateIpArray[i]) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPublicRangeArray) { for (i = 0; im_nPublicRangeCount; i++) { if ((ulRemoteAddress >= pAddressesDescriptor->m_pPublicRangeArray[i]._ulLowValue) && (ulRemoteAddress <= pAddressesDescriptor->m_pPublicRangeArray[i]._ulHighValue) ) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPrivateRangeArray) { for (i = 0; im_nPrivateRangeCount; i++) { if ((ulRemoteAddress >= pAddressesDescriptor->m_pPrivateRangeArray[i]._ulLowValue) && (ulRemoteAddress <= pAddressesDescriptor->m_pPrivateRangeArray[i]._ulHighValue) ) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPublicSubnetArray) { for (i = 0; im_nPublicSubnetCount; i++) { UINT32 ulAddrPart = (ulRemoteAddress & pAddressesDescriptor->m_pPublicSubnetArray[i]._ulIpMask); if (ulAddrPart == pAddressesDescriptor->m_pPublicSubnetArray[i]._ulIpAddr) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPrivateSubnetArray) { for (i = 0; im_nPrivateSubnetCount; i++) { UINT32 ulAddrPart = (ulRemoteAddress & pAddressesDescriptor->m_pPrivateSubnetArray[i]._ulIpMask); if (ulAddrPart == pAddressesDescriptor->m_pPrivateSubnetArray[i]._ulIpAddr) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (g_bFiltersChangeInProgress | g_stFirewallConfig.bExternalClientBlocked) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Host %ws Blocked because (g_bFiltersChangeInProgress | g_stFirewallConfig.bExternalClientBlocked)!", szIpAddress ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } for (ulI = 0; ulI < g_stFirewallConfig.nBlackSubnetListLength; ulI++) { UINT32 ulAddrPart = (ulRemoteAddress & g_stFirewallConfig.aBlackSubnetList[ulI]._ulIpMask); if (ulAddrPart == g_stFirewallConfig.aBlackSubnetList[ulI]._ulIpAddr) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Host %ws Blocked because is in Black List Subnet!", szIpAddress ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } } for (ulI = 0; ulI < g_stFirewallConfig.nBlackListLength; ulI++) { if (ulRemoteAddress == g_stFirewallConfig.aBlackListArray[ulI]) { if (bTestIpV4) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host Blocked because is in Black List!" ); } classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } } packetState = FwpsQueryPacketInjectionState( hInjectionHandle, pNetBufferList, (HANDLE*) &wdfInjectDataObject ); if ((packetState == FWPS_PACKET_INJECTED_BY_SELF) || (packetState == FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF)) { if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Reinjected." ); } classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (!IsListEmpty(&g_stUdpAcceptNotifyList)) { pListEntry = g_stUdpAcceptNotifyList.Flink; pLastLE = g_stUdpAcceptNotifyList.Blink; for (;;) { pNextLE = pListEntry->Flink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { bDnsNotify = TRUE; bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } if (pListEntry == pLastLE) { break; } pListEntry = pNextLE; } } pInboundData = (PBYTE) NdisGetDataBuffer( pNetBuffer, nDataSize, baDataArray, 1, 0 ); ASSERT(NULL != pInboundData); pDnsHeader = (PDNS_HEADER) pInboundData; if (DNS_OPCODE_NOTIFY == pDnsHeader->Opcode) { if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! NOTIFY Query from Tested IpV4 Host was Received." ); } if (IsListEmpty(&g_stAcceptableList)) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"g_stAcceptableList\" is Empty!! Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; if (NULL != g_wdfWaitRestartQueue) { status = WdfIoQueueRetrieveNextRequest( g_wdfWaitRestartQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, &g_uiRestartStatus, sizeof(g_uiRestartStatus) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(g_uiRestartStatus) ); WdfObjectDelete(g_wdfWaitRestartQueue); g_wdfWaitRestartQueue = NULL; } WdfObjectReleaseLock(g_wdfControlDevice); return; } pListEntry = RemoveHeadList(&g_stAcceptableList); pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; pFlowContext->enIpProto = IPPROTO_UDP; pFlowContext->nRemoteAddressV4 = ulRemoteAddress; pFlowContext->nRemoteAddressV4N = ulRemoteAddressN; pFlowContext->usRemotePort = usRemotePort; pFlowContext->bUdpNotInboundTransport = FALSE; pFlowContext->bUdpNotifyQuery = TRUE; pFlowContext->enContextState = csUdpWaitAcceptRecv; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host Insert to \"g_stUdpAcceptNotifyList\"." ); } pFlowContext->enFlowDataOwner = foUdpAcceptNotifyList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stUdpAcceptNotifyList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_PERMIT; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (FWPS_IS_METADATA_FIELD_PRESENT( inMetaValues, FWPS_METADATA_FIELD_ALE_CLASSIFY_REQUIRED) ) { if (IsListEmpty(&g_stAcceptableList)) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"g_stAcceptableList\" is Empty!! Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; if (NULL != g_wdfWaitRestartQueue) { status = WdfIoQueueRetrieveNextRequest( g_wdfWaitRestartQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, &g_uiRestartStatus, sizeof(g_uiRestartStatus) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(g_uiRestartStatus) ); WdfObjectDelete(g_wdfWaitRestartQueue); g_wdfWaitRestartQueue = NULL; } WdfObjectReleaseLock(g_wdfControlDevice); return; } pListEntry = RemoveHeadList(&g_stAcceptableList); pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; pFlowContext->enIpProto = IPPROTO_UDP; pFlowContext->nRemoteAddressV4 = ulRemoteAddress; pFlowContext->nRemoteAddressV4N = ulRemoteAddressN; pFlowContext->usRemotePort = usRemotePort; pFlowContext->bUdpNotInboundTransport = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->enContextState = csUdpWaitAcceptRecv; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host Insert to \"g_stUdpALEAcceptRecvList\"." ); } pFlowContext->enFlowDataOwner = foUdpALEAcceptRecvList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stUdpALEAcceptRecvList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_PERMIT; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } ulInboundCount = 0; if (!IsListEmpty(&g_stFlowedFileList)) { pListEntry = g_stFlowedFileList.Blink; pFirstLE = g_stFlowedFileList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (IPPROTO_UDP == pFlowContext->enIpProto)) { ulInboundCount += pFlowContext->ulUdpQueryCount; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } } if (ulInboundCount > 2) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Host %ws Blocked because exist greater then two UDP-flow for this host; client.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (!IsListEmpty(&g_stUdpALEAcceptRecvList)) { pListEntry = g_stUdpALEAcceptRecvList.Blink; pFirstLE = g_stUdpALEAcceptRecvList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } } if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Blink; pFirstLE = g_stUdpALEAcceptPendedList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } } if (!IsListEmpty(&g_stUdpALEFlowEstablishList)) { pListEntry = g_stUdpALEFlowEstablishList.Blink; pFirstLE = g_stUdpALEFlowEstablishList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } } if (!IsListEmpty(&g_stUdpInboundList)) { pListEntry = g_stUdpInboundList.Blink; pFirstLE = g_stUdpInboundList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { bInboundExist = TRUE; ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } } if (ulInboundCount > 4) { if (!IsListEmpty(&g_stFlowedFileList)) { pListEntry = g_stFlowedFileList.Blink; pFirstLE = g_stFlowedFileList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (IPPROTO_UDP == pFlowContext->enIpProto)) { switch (pFlowContext->enContextState) { case csUdpWaitApprovalQuery: case csUdpWaitReplaceQuery: case csUdpWaitApprovalQuery2: case csUdpWaitReplaceQuery2: break; default: stIpAddress.S_un.S_addr = pFlowContext->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Host %ws client.port = %hu on state = %u exist in \"g_stFlowedFileList\".", szIpAddress, pFlowContext->usRemotePort, (UINT32) pFlowContext->enContextState ); pFlowContext->enContextState = csUdpFlowBreak; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); WdfObjectReleaseLock(g_wdfControlDevice); status = FwpsFlowRemoveContext( pFlowContext->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } WdfObjectAcquireLock(g_wdfControlDevice); } } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } if (!IsListEmpty(&g_stUdpInboundList)) { pListEntry = g_stUdpInboundList.Blink; pFirstLE = g_stUdpInboundList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { switch (pFlowContext->enContextState) { case csUdpInboundPended: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (NULL != pFlowContext->pUdpQuery2BufferList) { FwpsDereferenceNetBufferList( pFlowContext->pUdpQuery2BufferList, FALSE ); pFlowContext->pUdpQuery2BufferList = NULL; } pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; if (!bFlowDataCopy) { bFlowDataCopy = TRUE; wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_NO_MORE_ENTRIES, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } pFlowContext->enContextState = csUdpSetFilterEvent; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); RtlCopyMemory( &stFlowDataCopy, pFlowContext, sizeof(stFlowDataCopy) ); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else { pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } if (!IsListEmpty(&g_stUdpALEAcceptRecvList)) { pListEntry = g_stUdpALEAcceptRecvList.Blink; pFirstLE = g_stUdpALEAcceptRecvList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotifyQuery = FALSE; if (!bFlowDataCopy) { bFlowDataCopy = TRUE; wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_NO_MORE_ENTRIES, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } pFlowContext->enContextState = csUdpSetFilterEvent; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); RtlCopyMemory( &stFlowDataCopy, pFlowContext, sizeof(stFlowDataCopy) ); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else { pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Blink; pFirstLE = g_stUdpALEAcceptPendedList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { switch (pFlowContext->enContextState) { case csUdpFlowEstablishPended: bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (NULL != pFlowContext->pUdpQueryCloneBufferList) { FwpsFreeCloneNetBufferList( pFlowContext->pUdpQueryCloneBufferList, 0 ); pFlowContext->pUdpQueryCloneBufferList = NULL; } if (NULL != pFlowContext->pUdpQueryBufferList) { FwpsDereferenceNetBufferList( pFlowContext->pUdpQueryBufferList, FALSE ); pFlowContext->pUdpQueryBufferList = NULL; } pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bUdpNotInboundTransport = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; if (!bFlowDataCopy) { bFlowDataCopy = TRUE; wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_NO_MORE_ENTRIES, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } pFlowContext->enContextState = csUdpSetFilterEvent; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); RtlCopyMemory( &stFlowDataCopy, pFlowContext, sizeof(stFlowDataCopy) ); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else if (NULL == pFlowContext->wdfWaitDnsQueryQueue) { wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, sizeof(FLOW_DATA) ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else { pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } break; case csUdpWaitReadQuery: break; case csUdpWaitApprovalQuery: break; case csUdpPermitQueryPended: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } if (!IsListEmpty(&g_stUdpALEFlowEstablishList)) { pListEntry = g_stUdpALEFlowEstablishList.Blink; pFirstLE = g_stUdpALEFlowEstablishList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { switch (pFlowContext->enContextState) { case csUdpAcceptedRecv: break; case csUdpWaitPermitQuery: case csUdpPermitQueryDone: if (!pFlowContext->bUdpQueryClassifyPended) { ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotInboundTransport = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; if (!bFlowDataCopy) { bFlowDataCopy = TRUE; wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_NO_MORE_ENTRIES, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } pFlowContext->enContextState = csUdpSetFilterEvent; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); RtlCopyMemory( &stFlowDataCopy, pFlowContext, sizeof(stFlowDataCopy) ); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else if (NULL == pFlowContext->wdfWaitDnsQueryQueue) { wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, sizeof(FLOW_DATA) ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else { pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } ASSERT(bFlowDataCopy); pFlowContext = &stFlowDataCopy; stIpAddress.S_un.S_addr = pFlowContext->nRemoteAddressV4N; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Posible UDP-Attack to DNS port from host %ws; clent.port = %hu;", szIpAddress, pFlowContext->usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; pFlowContext->bFilterGhangePended = TRUE; g_bFiltersChangeInProgress = TRUE; wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); WdfObjectReleaseLock(g_wdfControlDevice); return; } if (0 == ulInboundCount) { // Авторизованный поток закончился, и потому требуется повторная Авторизация if (IsListEmpty(&g_stAcceptableList)) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"g_stAcceptableList\" is Empty!! Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; if (NULL != g_wdfWaitRestartQueue) { status = WdfIoQueueRetrieveNextRequest( g_wdfWaitRestartQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, &g_uiRestartStatus, sizeof(g_uiRestartStatus) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(g_uiRestartStatus) ); WdfObjectDelete(g_wdfWaitRestartQueue); g_wdfWaitRestartQueue = NULL; } WdfObjectReleaseLock(g_wdfControlDevice); return; } pListEntry = RemoveHeadList(&g_stAcceptableList); pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; pFlowContext->enIpProto = IPPROTO_UDP; pFlowContext->nRemoteAddressV4 = ulRemoteAddress; pFlowContext->nRemoteAddressV4N = ulRemoteAddressN; pFlowContext->usRemotePort = usRemotePort; pFlowContext->bUdpNotInboundTransport = TRUE; pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->enContextState = csUdpWaitAcceptRecv; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host Insert to \"g_stUdpALEAcceptRecvList\"." ); } pFlowContext->enFlowDataOwner = foUdpALEAcceptRecvList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stUdpALEAcceptRecvList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (IsListEmpty(&g_stAcceptableList)) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"g_stAcceptableList\" is Empty!! Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; if (NULL != g_wdfWaitRestartQueue) { status = WdfIoQueueRetrieveNextRequest( g_wdfWaitRestartQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, &g_uiRestartStatus, sizeof(g_uiRestartStatus) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(g_uiRestartStatus) ); WdfObjectDelete(g_wdfWaitRestartQueue); g_wdfWaitRestartQueue = NULL; } WdfObjectReleaseLock(g_wdfControlDevice); return; } pListEntry = RemoveHeadList(&g_stAcceptableList); pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); pInboundContext = pFlowContext; wdfFlowFileObject = pFlowContext->wdfFlowFileObject; pFlowContext->enIpProto = IPPROTO_UDP; pFlowContext->nRemoteAddressV4 = ulRemoteAddress; pFlowContext->nRemoteAddressV4N = ulRemoteAddressN; pFlowContext->usRemotePort = usRemotePort; pFlowContext->interfaceIndex = inFixedValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V4_INTERFACE_INDEX].value.uint32; pFlowContext->subInterfaceIndex = inFixedValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V4_SUB_INTERFACE_INDEX].value.uint32; pFlowContext->pUdpQuery2BufferList = pNetBufferList; pFlowContext->ulUdpQuery2BufferSize = nDataSize + ulIpHeaderSize + ulTransportHeaderSize; pFlowContext->ulUdpQuery2DataOffset = ulUdpDataOffset; pFlowContext->ulUdpQuery2PacketOffset = ulUdpDataOffset - ulIpHeaderSize - ulTransportHeaderSize; ulUdpDataLength = nDataSize; pFlowContext->ulUdpQuery2DataLength = ulUdpDataLength; ASSERT(pFlowContext->ulUdpQuery2DataLength > 0); pFlowContext->enUdpQuery2CompartmentID = enUdpCompartmentID; pFlowContext->ulUdpQuery2IpHeaderSize = ulIpHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = ulTransportHeaderSize; FwpsReferenceNetBufferList( pNetBufferList, TRUE ); pFlowContext->bUdpNotInboundTransport = FALSE; pFlowContext->enContextState = csUdpInboundPended; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host Insert to \"g_stUdpInboundList\"." ); } pFlowContext->enFlowDataOwner = foUdpInboundList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stUdpInboundList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; if (bInboundExist) // && bDnsNotify { ulInboundCount = 0; pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (pInboundContext != pFlowContext) ) { ulInboundCount++; break; } } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host Insert to \"g_stUdpALEAcceptPendedList\"." ); } pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } WdfObjectReleaseLock(g_wdfControlDevice); } void NTAPI onInboundTransportV6Classify( __in const FWPS_INCOMING_VALUES* inFixedValues, __in const FWPS_INCOMING_METADATA_VALUES* inMetaValues, __inout_opt void* layerData, _In_opt_ const void* classifyContext, __in const FWPS_FILTER* filter, __in UINT64 flowContext, __inout FWPS_CLASSIFY_OUT* classifyOut ) { static BOOLEAN bWaitRestartQueueInit = FALSE; static WDFQUEUE wdfWaitRestartQueue = NULL; static FLOW_DATA stFlowDataCopy; static WCHAR szIpAddress[128]; static BYTE baDataArray[512]; PADDRESSES_DESCRIPTOR pAddressesDescriptor = NULL; FWP_BYTE_ARRAY16 *pRemoteAddress; BOOLEAN bLocalNetwork = FALSE; PLIST_ENTRY pListEntry, pFirstLE, pPrevLE, pLastLE, pNextLE; PFLOW_DATA pFlowContext = NULL, pInboundContext = NULL; UINT32 ulI; BOOLEAN bEmpty; FWPS_PACKET_INJECTION_STATE packetState; HANDLE hInjectionHandle; PNET_BUFFER_LIST pNetBufferList; WDFFILEOBJECT wdfInjectDataObject = NULL; IN6_ADDR stIp6Address; LPWSTR pAddressEnd; WDFQUEUE wdfRequestQueue; WDFREQUEST wdfPendedRequest; NTSTATUS status = STATUS_SUCCESS; WDFMEMORY wdfOutputMemory; WDFFILEOBJECT wdfFlowFileObject = NULL; WDFQUEUE wdfFlowQueue; int nFileIndex, nThreadIndex; IPPROTO enIpProto; BOOLEAN bFlowDataCopy = FALSE; PNET_BUFFER pNetBuffer; UINT32 nDataSize; UINT32 ulUdpDataOffset; UINT32 ulIpHeaderSize; UINT32 ulTransportHeaderSize; COMPARTMENT_ID enUdpCompartmentID; UINT32 ulUdpDataLength = 0; UINT32 ulInboundCount = 0; int i; UINT16 usRemotePort; PBYTE pInboundData; PDNS_HEADER pDnsHeader; BOOLEAN bDnsNotify = FALSE; BOOLEAN bInboundExist = FALSE; UNREFERENCED_PARAMETER(filter); UNREFERENCED_PARAMETER(classifyContext); UNREFERENCED_PARAMETER(flowContext); if (!(classifyOut->rights & FWPS_RIGHT_ACTION_WRITE)) { return; } if (NULL != g_wdfWaitRestartQueue && !bWaitRestartQueueInit) { bWaitRestartQueueInit = TRUE; wdfWaitRestartQueue = g_wdfWaitRestartQueue; } else if (NULL == g_wdfWaitRestartQueue && bWaitRestartQueueInit) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! (NULL == g_wdfWaitRestartQueue && bWaitRestartQueueInit);" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; return; } WdfObjectAcquireLock(g_wdfControlDevice); pNetBufferList = (PNET_BUFFER_LIST) layerData; ASSERT(pNetBufferList != NULL); enIpProto = (IPPROTO) inFixedValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V6_IP_PROTOCOL].value.uint8; ASSERT(IPPROTO_UDP == enIpProto); hInjectionHandle = g_hInjectionHandleV6; pRemoteAddress = inFixedValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V6_IP_REMOTE_ADDRESS].value.byteArray16; enUdpCompartmentID = (COMPARTMENT_ID) inMetaValues->compartmentId; ASSERT(FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_IP_HEADER_SIZE)); ulIpHeaderSize = inMetaValues->ipHeaderSize; ulTransportHeaderSize = inMetaValues->transportHeaderSize; usRemotePort = inFixedValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V6_IP_REMOTE_PORT].value.uint16; pNetBuffer = NET_BUFFER_LIST_FIRST_NB(pNetBufferList); nDataSize = NET_BUFFER_DATA_LENGTH(pNetBuffer); ulUdpDataOffset = NET_BUFFER_DATA_OFFSET(pNetBuffer); if (0 == nDataSize) { RtlCopyMemory( &stIp6Address, pRemoteAddress, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! (0 == nDataSize)!! Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } pAddressesDescriptor = WdfObjectGetTypedContext( g_wdfControlDevice, ADDRESSES_DESCRIPTOR ); if (NULL == pAddressesDescriptor) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (NULL == pAddressesDescriptor)" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL == pAddressesDescriptor->m_pDataArray) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (NULL == pAddressesDescriptor->m_pDataArray)" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (!bfIPv6AddressInIPv6Subnet(pRemoteAddress, c_pGlobalIPv6Subnet)) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPublicIPV6AddrArray) { for (i = 0; im_nPublicIPV6AddrCount; i++) { if (bfIPv6AddressInIPv6Subnet(pRemoteAddress, &pAddressesDescriptor->m_pPublicIPV6AddrArray[i])) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPrivateIPV6AddrArray) { for (i = 0; im_nPrivateIPV6AddrCount; i++) { if (bfIPv6AddressInIPv6Subnet(pRemoteAddress, &pAddressesDescriptor->m_pPrivateIPV6AddrArray[i])) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (g_bFiltersChangeInProgress | g_stFirewallConfig.bExternalClientBlocked) { classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } for (ulI = 0; ulI < g_stFirewallConfig.nBlackListV6Length; ulI++) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &g_stFirewallConfig.aBlackListV6Array[ulI])) { classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } } packetState = FwpsQueryPacketInjectionState( hInjectionHandle, pNetBufferList, (HANDLE*) &wdfInjectDataObject ); if ((packetState == FWPS_PACKET_INJECTED_BY_SELF) || (packetState == FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF)) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (!IsListEmpty(&g_stUdpAcceptNotifyList)) { pListEntry = g_stUdpAcceptNotifyList.Flink; pLastLE = g_stUdpAcceptNotifyList.Blink; for (;;) { pNextLE = pListEntry->Flink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6)) { bDnsNotify = TRUE; bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } if (pListEntry == pLastLE) { break; } pListEntry = pNextLE; } } pInboundData = (PBYTE) NdisGetDataBuffer( pNetBuffer, nDataSize, baDataArray, 1, 0 ); ASSERT(NULL != pInboundData); pDnsHeader = (PDNS_HEADER) pInboundData; if (DNS_OPCODE_NOTIFY == pDnsHeader->Opcode) { if (IsListEmpty(&g_stAcceptableList)) { RtlCopyMemory( &stIp6Address, pRemoteAddress, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"g_stAcceptableList\" is Empty!! Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; if (NULL != g_wdfWaitRestartQueue) { status = WdfIoQueueRetrieveNextRequest( g_wdfWaitRestartQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, &g_uiRestartStatus, sizeof(g_uiRestartStatus) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(g_uiRestartStatus) ); WdfObjectDelete(g_wdfWaitRestartQueue); g_wdfWaitRestartQueue = NULL; } WdfObjectReleaseLock(g_wdfControlDevice); return; } pListEntry = RemoveHeadList(&g_stAcceptableList); pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; pFlowContext->enIpProto = IPPROTO_UDP; pFlowContext->bIPv6 = TRUE; IPv6CopyAddress(&pFlowContext->stRemoteAddressV6, pRemoteAddress); pFlowContext->usRemotePort = usRemotePort; pFlowContext->bUdpNotInboundTransport = FALSE; pFlowContext->bUdpNotifyQuery = TRUE; pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->enContextState = csUdpWaitAcceptRecv; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpAcceptNotifyList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stUdpAcceptNotifyList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_PERMIT; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (FWPS_IS_METADATA_FIELD_PRESENT( inMetaValues, FWPS_METADATA_FIELD_ALE_CLASSIFY_REQUIRED) ) { if (IsListEmpty(&g_stAcceptableList)) { RtlCopyMemory( &stIp6Address, pRemoteAddress, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"g_stAcceptableList\" is Empty!! Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; if (NULL != g_wdfWaitRestartQueue) { status = WdfIoQueueRetrieveNextRequest( g_wdfWaitRestartQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, &g_uiRestartStatus, sizeof(g_uiRestartStatus) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(g_uiRestartStatus) ); WdfObjectDelete(g_wdfWaitRestartQueue); g_wdfWaitRestartQueue = NULL; } WdfObjectReleaseLock(g_wdfControlDevice); return; } pListEntry = RemoveHeadList(&g_stAcceptableList); pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; pFlowContext->enIpProto = IPPROTO_UDP; pFlowContext->bIPv6 = TRUE; IPv6CopyAddress(&pFlowContext->stRemoteAddressV6, pRemoteAddress); pFlowContext->usRemotePort = usRemotePort; pFlowContext->bUdpNotInboundTransport = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->enContextState = csUdpWaitAcceptRecv; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptRecvList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stUdpALEAcceptRecvList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } ulInboundCount = 0; if (!IsListEmpty(&g_stFlowedFileList)) { pListEntry = g_stFlowedFileList.Blink; pFirstLE = g_stFlowedFileList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (pFlowContext->bIPv6) { if ((bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6)) && (IPPROTO_UDP == pFlowContext->enIpProto)) { ulInboundCount += pFlowContext->ulUdpQueryCount; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } } if (ulInboundCount > 2) { RtlCopyMemory( &stIp6Address, pRemoteAddress, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Host %ws Blocked because exist greater then two UDP-flow for this host; client.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (!IsListEmpty(&g_stUdpALEAcceptRecvList)) { pListEntry = g_stUdpALEAcceptRecvList.Blink; pFirstLE = g_stUdpALEAcceptRecvList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6)) { ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } } if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Blink; pFirstLE = g_stUdpALEAcceptPendedList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6)) { ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } } if (!IsListEmpty(&g_stUdpALEFlowEstablishList)) { pListEntry = g_stUdpALEFlowEstablishList.Blink; pFirstLE = g_stUdpALEFlowEstablishList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6)) { ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } } if (!IsListEmpty(&g_stUdpInboundList)) { pListEntry = g_stUdpInboundList.Blink; pFirstLE = g_stUdpInboundList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6)) { bInboundExist = TRUE; ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } } if (ulInboundCount > 4) { if (!IsListEmpty(&g_stFlowedFileList)) { pListEntry = g_stFlowedFileList.Blink; pFirstLE = g_stFlowedFileList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6) && (IPPROTO_UDP == pFlowContext->enIpProto)) { switch (pFlowContext->enContextState) { case csUdpWaitApprovalQuery: case csUdpWaitReplaceQuery: case csUdpWaitApprovalQuery2: case csUdpWaitReplaceQuery2: break; default: RtlCopyMemory( &stIp6Address, &pFlowContext->stRemoteAddressV6, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Host %ws client.port = %hu on state = %u exist in \"g_stFlowedFileList\".", szIpAddress, pFlowContext->usRemotePort, (UINT32) pFlowContext->enContextState ); pFlowContext->enContextState = csUdpFlowBreak; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); WdfObjectReleaseLock(g_wdfControlDevice); status = FwpsFlowRemoveContext( pFlowContext->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } WdfObjectAcquireLock(g_wdfControlDevice); } } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } if (!IsListEmpty(&g_stUdpInboundList)) { pListEntry = g_stUdpInboundList.Blink; pFirstLE = g_stUdpInboundList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6)) { switch (pFlowContext->enContextState) { case csUdpInboundPended: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotInboundTransport = FALSE; if (NULL != pFlowContext->pUdpQuery2BufferList) { FwpsDereferenceNetBufferList( pFlowContext->pUdpQuery2BufferList, FALSE ); pFlowContext->pUdpQuery2BufferList = NULL; } pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; if (!bFlowDataCopy) { bFlowDataCopy = TRUE; wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_NO_MORE_ENTRIES, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } pFlowContext->enContextState = csUdpSetFilterEvent; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); RtlCopyMemory( &stFlowDataCopy, pFlowContext, sizeof(stFlowDataCopy) ); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else { pFlowContext->bIPv6 = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } if (!IsListEmpty(&g_stUdpALEAcceptRecvList)) { pListEntry = g_stUdpALEAcceptRecvList.Blink; pFirstLE = g_stUdpALEAcceptRecvList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6)) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotInboundTransport = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; if (!bFlowDataCopy) { bFlowDataCopy = TRUE; wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_NO_MORE_ENTRIES, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } pFlowContext->enContextState = csUdpSetFilterEvent; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); RtlCopyMemory( &stFlowDataCopy, pFlowContext, sizeof(stFlowDataCopy) ); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else { pFlowContext->bIPv6 = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Blink; pFirstLE = g_stUdpALEAcceptPendedList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6)) { switch (pFlowContext->enContextState) { case csUdpFlowEstablishPended: bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotInboundTransport = FALSE; if (NULL != pFlowContext->pUdpQueryCloneBufferList) { FwpsFreeCloneNetBufferList( pFlowContext->pUdpQueryCloneBufferList, 0 ); pFlowContext->pUdpQueryCloneBufferList = NULL; } if (NULL != pFlowContext->pUdpQueryBufferList) { FwpsDereferenceNetBufferList( pFlowContext->pUdpQueryBufferList, FALSE ); pFlowContext->pUdpQueryBufferList = NULL; } pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; if (!bFlowDataCopy) { bFlowDataCopy = TRUE; wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_NO_MORE_ENTRIES, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } pFlowContext->enContextState = csUdpSetFilterEvent; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); RtlCopyMemory( &stFlowDataCopy, pFlowContext, sizeof(stFlowDataCopy) ); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else if (NULL == pFlowContext->wdfWaitDnsQueryQueue) { wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, sizeof(FLOW_DATA) ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else { pFlowContext->bIPv6 = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } break; case csUdpWaitReadQuery: break; case csUdpWaitApprovalQuery: break; case csUdpPermitQueryPended: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } if (!IsListEmpty(&g_stUdpALEFlowEstablishList)) { pListEntry = g_stUdpALEFlowEstablishList.Blink; pFirstLE = g_stUdpALEFlowEstablishList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6)) { switch (pFlowContext->enContextState) { case csUdpAcceptedRecv: break; case csUdpWaitPermitQuery: case csUdpPermitQueryDone: if (!pFlowContext->bUdpQueryClassifyPended) { ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotInboundTransport = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; if (!bFlowDataCopy) { bFlowDataCopy = TRUE; wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_NO_MORE_ENTRIES, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } pFlowContext->enContextState = csUdpSetFilterEvent; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); RtlCopyMemory( &stFlowDataCopy, pFlowContext, sizeof(stFlowDataCopy) ); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else if (NULL == pFlowContext->wdfWaitDnsQueryQueue) { wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitUdpQuery2Queue; if (NULL != wdfRequestQueue) { pFlowContext->wdfWaitUdpQuery2Queue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, 0 ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); } wdfRequestQueue = pFlowContext->wdfWaitFlowDoneQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitFlowDoneQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); if (NT_SUCCESS(status)) { status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, STATUS_END_OF_FILE, sizeof(FLOW_DATA) ); } else if (STATUS_NO_MORE_ENTRIES != status) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"WdfIoQueueRetrieveNextRequest\" return %!STATUS!", status ); } WdfObjectDelete(wdfRequestQueue); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; ASSERT(NULL != wdfFlowFileObject); wdfFlowQueue = pFlowContext->wdfFlowQueue; nFileIndex = pFlowContext->nFileIndex; nThreadIndex = pFlowContext->nThreadIndex; RtlZeroMemory( pFlowContext, sizeof(FLOW_DATA) ); pFlowContext->pThis = pFlowContext; pFlowContext->wdfFlowFileObject = wdfFlowFileObject; pFlowContext->wdfFlowQueue = wdfFlowQueue; pFlowContext->nFileIndex = nFileIndex; pFlowContext->nThreadIndex = nThreadIndex; pFlowContext->enFlowDataOwner = foFreeFileList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stFreeFileList, &pFlowContext->listEntry ); } else { pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } } ASSERT(bFlowDataCopy); pFlowContext = &stFlowDataCopy; RtlCopyMemory( &stIp6Address, pRemoteAddress, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Posible UDP-Attack to DNS port from host %ws; clent.port = %hu;", szIpAddress, pFlowContext->usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; g_bFiltersChangeInProgress = TRUE; wdfRequestQueue = pFlowContext->wdfWaitUdpSetFirewallFilterQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitUdpSetFirewallFilterQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); WdfObjectReleaseLock(g_wdfControlDevice); return; } if (0 == ulInboundCount) { // Авторизованный поток закончился, и потому требуется повторная Авторизация if (IsListEmpty(&g_stAcceptableList)) { RtlCopyMemory( &stIp6Address, pRemoteAddress, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"g_stAcceptableList\" is Empty!! Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; if (NULL != g_wdfWaitRestartQueue) { status = WdfIoQueueRetrieveNextRequest( g_wdfWaitRestartQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, &g_uiRestartStatus, sizeof(g_uiRestartStatus) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(g_uiRestartStatus) ); WdfObjectDelete(g_wdfWaitRestartQueue); g_wdfWaitRestartQueue = NULL; } WdfObjectReleaseLock(g_wdfControlDevice); return; } pListEntry = RemoveHeadList(&g_stAcceptableList); pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); wdfFlowFileObject = pFlowContext->wdfFlowFileObject; pFlowContext->enIpProto = IPPROTO_UDP; pFlowContext->bIPv6 = TRUE; IPv6CopyAddress(&pFlowContext->stRemoteAddressV6, pRemoteAddress); pFlowContext->usRemotePort = usRemotePort; pFlowContext->bUdpNotInboundTransport = TRUE; pFlowContext->enContextState = csUdpWaitAcceptRecv; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptRecvList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stUdpALEAcceptRecvList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (IsListEmpty(&g_stAcceptableList)) { RtlCopyMemory( &stIp6Address, pRemoteAddress, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"g_stAcceptableList\" is Empty!! Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; if (NULL != g_wdfWaitRestartQueue) { status = WdfIoQueueRetrieveNextRequest( g_wdfWaitRestartQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, &g_uiRestartStatus, sizeof(g_uiRestartStatus) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(g_uiRestartStatus) ); WdfObjectDelete(g_wdfWaitRestartQueue); g_wdfWaitRestartQueue = NULL; } WdfObjectReleaseLock(g_wdfControlDevice); return; } pListEntry = RemoveHeadList(&g_stAcceptableList); pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); pInboundContext = pFlowContext; wdfFlowFileObject = pFlowContext->wdfFlowFileObject; pFlowContext->enIpProto = IPPROTO_UDP; pFlowContext->bIPv6 = TRUE; IPv6CopyAddress(&pFlowContext->stRemoteAddressV6, pRemoteAddress); pFlowContext->usRemotePort = usRemotePort; pFlowContext->interfaceIndex = inFixedValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V6_INTERFACE_INDEX].value.uint32; pFlowContext->subInterfaceIndex = inFixedValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V6_SUB_INTERFACE_INDEX].value.uint32; pFlowContext->pUdpQuery2BufferList = pNetBufferList; pFlowContext->ulUdpQuery2BufferSize = nDataSize + ulIpHeaderSize + ulTransportHeaderSize; pFlowContext->ulUdpQuery2DataOffset = ulUdpDataOffset; pFlowContext->ulUdpQuery2PacketOffset = ulUdpDataOffset - ulIpHeaderSize - ulTransportHeaderSize; ulUdpDataLength = nDataSize; pFlowContext->ulUdpQuery2DataLength = ulUdpDataLength; ASSERT(pFlowContext->ulUdpQuery2DataLength > 0); pFlowContext->enUdpQuery2CompartmentID = enUdpCompartmentID; pFlowContext->ulUdpQuery2IpHeaderSize = ulIpHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = ulTransportHeaderSize; FwpsReferenceNetBufferList( pNetBufferList, TRUE ); pFlowContext->bUdpNotInboundTransport = FALSE; pFlowContext->enContextState = csUdpInboundPended; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpInboundList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stUdpInboundList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; if (bInboundExist) // && bDnsNotify { ulInboundCount = 0; pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6) && (pInboundContext != pFlowContext) ) { ulInboundCount++; break; } } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bEmpty = RemoveEntryList(&pFlowContext->listEntry); usRemotePort = pFlowContext->usRemotePort; pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } WdfObjectReleaseLock(g_wdfControlDevice); } void NTAPI onAleAcceptRecvV4Classify( __in const FWPS_INCOMING_VALUES* inFixedValues, __in const FWPS_INCOMING_METADATA_VALUES* inMetaValues, __inout_opt void* layerData, _In_opt_ const void* classifyContext, __in const FWPS_FILTER* filter, __in UINT64 flowContext, __inout FWPS_CLASSIFY_OUT* classifyOut ) { PADDRESSES_DESCRIPTOR pAddressesDescriptor = NULL; UINT32 ulRemoteAddress, ulI, ulRemoteAddressN; int i; BOOLEAN bLocalNetwork = FALSE; PLIST_ENTRY pListEntry, pFirstLE, pPrevLE, pLastLE; PFLOW_DATA pFlowContext = NULL, pFirstAcceptingFlowContext = NULL; UINT32 ulInboundCount = 0; BOOLEAN bEmpty; PNET_BUFFER_LIST pNetBufferList; NTSTATUS status = STATUS_SUCCESS; IPPROTO enIpProto; PNET_BUFFER pNetBuffer; UINT32 nDataSize; UINT32 ulUdpDataOffset; UINT32 ulIpHeaderSize; UINT32 ulTransportHeaderSize; COMPARTMENT_ID enUdpCompartmentID; UINT32 ulUdpDataLength; UINT16 usRemotePort; HANDLE hCompletionHandle = NULL; IN_ADDR stIpAddress; WCHAR szIpAddress[128]; LPWSTR pAddressEnd; FWPS_PACKET_INJECTION_STATE packetState; HANDLE hInjectionHandle; WDFFILEOBJECT wdfInjectDataObject = NULL; BOOLEAN bTestIpV4; BOOLEAN bIPv6; WDFQUEUE wdfRequestQueue; WDFREQUEST wdfPendedRequest; WDFMEMORY wdfOutputMemory = NULL; IN6_ADDR stRemoteAddress; UNREFERENCED_PARAMETER(filter); UNREFERENCED_PARAMETER(classifyContext); UNREFERENCED_PARAMETER(flowContext); if (!(classifyOut->rights & FWPS_RIGHT_ACTION_WRITE)) { return; } WdfObjectAcquireLock(g_wdfControlDevice); pNetBufferList = (PNET_BUFFER_LIST) layerData; ASSERT(pNetBufferList != NULL); enIpProto = (IPPROTO) inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_PROTOCOL].value.uint8; ASSERT(IPPROTO_UDP == enIpProto); ulRemoteAddress = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_REMOTE_ADDRESS].value.uint32; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); pNetBuffer = NET_BUFFER_LIST_FIRST_NB(pNetBufferList); nDataSize = NET_BUFFER_DATA_LENGTH(pNetBuffer); ulUdpDataOffset = NET_BUFFER_DATA_OFFSET(pNetBuffer); enUdpCompartmentID = (COMPARTMENT_ID) inMetaValues->compartmentId; ASSERT(FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_IP_HEADER_SIZE)); ulIpHeaderSize = inMetaValues->ipHeaderSize; ulTransportHeaderSize = inMetaValues->transportHeaderSize; usRemotePort = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_REMOTE_PORT].value.uint16; hInjectionHandle = g_hInjectionHandleV4; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pAddressesDescriptor = WdfObjectGetTypedContext( g_wdfControlDevice, ADDRESSES_DESCRIPTOR ); if (NULL == pAddressesDescriptor) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (NULL == pAddressesDescriptor)" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL == pAddressesDescriptor->m_pDataArray) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (NULL == pAddressesDescriptor->m_pDataArray)" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (c_ulLocalHost == ulRemoteAddress) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPublicIpArray) { for (i = 0; im_nPublicIpCount; i++) { if (ulRemoteAddress == pAddressesDescriptor->m_pPublicIpArray[i]) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPrivateIpArray) { for (i = 0; im_nPrivateIpCount; i++) { if (ulRemoteAddress == pAddressesDescriptor->m_pPrivateIpArray[i]) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPublicRangeArray) { for (i = 0; im_nPublicRangeCount; i++) { if ((ulRemoteAddress >= pAddressesDescriptor->m_pPublicRangeArray[i]._ulLowValue) && (ulRemoteAddress <= pAddressesDescriptor->m_pPublicRangeArray[i]._ulHighValue) ) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPrivateRangeArray) { for (i = 0; im_nPrivateRangeCount; i++) { if ((ulRemoteAddress >= pAddressesDescriptor->m_pPrivateRangeArray[i]._ulLowValue) && (ulRemoteAddress <= pAddressesDescriptor->m_pPrivateRangeArray[i]._ulHighValue) ) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPublicSubnetArray) { for (i = 0; im_nPublicSubnetCount; i++) { UINT32 ulAddrPart = (ulRemoteAddress & pAddressesDescriptor->m_pPublicSubnetArray[i]._ulIpMask); if (ulAddrPart == pAddressesDescriptor->m_pPublicSubnetArray[i]._ulIpAddr) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPrivateSubnetArray) { for (i = 0; im_nPrivateSubnetCount; i++) { UINT32 ulAddrPart = (ulRemoteAddress & pAddressesDescriptor->m_pPrivateSubnetArray[i]._ulIpMask); if (ulAddrPart == pAddressesDescriptor->m_pPrivateSubnetArray[i]._ulIpAddr) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } packetState = FwpsQueryPacketInjectionState( hInjectionHandle, pNetBufferList, (HANDLE*) &wdfInjectDataObject ); if ((packetState == FWPS_PACKET_INJECTED_BY_SELF) || (packetState == FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF)) { if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host was Reinjected." ); } classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (!IsListEmpty(&g_stFlowedFileList)) { pListEntry = g_stFlowedFileList.Blink; pFirstLE = g_stFlowedFileList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if ((IPPROTO_UDP == pFlowContext->enIpProto) && (!pFlowContext->bIPv6)) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (usRemotePort == pFlowContext->usRemotePort)) { switch (pFlowContext->enContextState) { case csUdpWaitPermitQuery2: case csUdpPermitQuery2Done: pFirstAcceptingFlowContext = pFlowContext; ulInboundCount++; break; } } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } if (ulInboundCount > 0) { ASSERT(1 == ulInboundCount); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } } if (!FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_COMPLETION_HANDLE)) { // Ответное сообщение пошло по маршруту отличному от маршрута DNS-запроса. // UDP-поток неоходимо закрыть. //stIpAddress.S_un.S_addr = ulRemoteAddressN; //pAddressEnd = RtlIpv4AddressToStringW( // &stIpAddress, // szIpAddress // ); //TraceEvents( // TRACE_LEVEL_INFORMATION, // TRACE_DNSFIREWALL, // "%!FUNC! line:%!LINE! %!LEVEL! FWPS_METADATA_FIELD_COMPLETION_HANDLE Not Present! Host IP = %ws; clent.port = %hu;", // szIpAddress, // usRemotePort // ); ulInboundCount = 0; if (!IsListEmpty(&g_stFlowedFileList)) { pListEntry = g_stFlowedFileList.Blink; pFirstLE = g_stFlowedFileList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if ((IPPROTO_UDP == pFlowContext->enIpProto) && (!pFlowContext->bIPv6)) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (usRemotePort == pFlowContext->usRemotePort) && (csUdpPermitQueryDone == pFlowContext->enContextState)) { pFirstAcceptingFlowContext = pFlowContext; ulInboundCount++; break; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } } if (0 == ulInboundCount) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Matched packet not found in \"g_stFlowedFileList\"!! Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } pFlowContext = pFirstAcceptingFlowContext; ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Flow Context from Test IpV4 Host %ws will Removed; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->enContextState = csUdpFlowBreak; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); status = FwpsFlowRemoveContext( pFlowContext->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V4, g_nDatagramIdV4 ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } return; } hCompletionHandle = inMetaValues->completionHandle; if (!IsListEmpty(&g_stUdpAcceptNotifyList)) { ulInboundCount = 0; pListEntry = g_stUdpAcceptNotifyList.Blink; pFirstLE = g_stUdpAcceptNotifyList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (usRemotePort == pFlowContext->usRemotePort)) { pFirstAcceptingFlowContext = pFlowContext; ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } if (ulInboundCount > 0) { if (g_bFiltersChangeInProgress | g_stFirewallConfig.bExternalClientBlocked) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Host %ws Blocked because (g_bFiltersChangeInProgress | g_stFirewallConfig.bExternalClientBlocked)!", szIpAddress ); pListEntry = g_stUdpAcceptNotifyList.Blink; pFirstLE = g_stUdpAcceptNotifyList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (usRemotePort == pFlowContext->usRemotePort)) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } for (ulI = 0; ulI < g_stFirewallConfig.nBlackSubnetListLength; ulI++) { UINT32 ulAddrPart = (ulRemoteAddress & g_stFirewallConfig.aBlackSubnetList[ulI]._ulIpMask); if (ulAddrPart == g_stFirewallConfig.aBlackSubnetList[ulI]._ulIpAddr) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Host %ws Blocked because is in Black List Subnet!", szIpAddress ); pListEntry = g_stUdpAcceptNotifyList.Blink; pFirstLE = g_stUdpAcceptNotifyList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (usRemotePort == pFlowContext->usRemotePort)) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } } for (ulI = 0; ulI < g_stFirewallConfig.nBlackListLength; ulI++) { if (ulRemoteAddress == g_stFirewallConfig.aBlackListArray[ulI]) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Host %ws Blocked because exist in Black List!", szIpAddress ); pListEntry = g_stUdpAcceptNotifyList.Blink; pFirstLE = g_stUdpAcceptNotifyList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (usRemotePort == pFlowContext->usRemotePort)) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } } pFlowContext = pFirstAcceptingFlowContext; switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->enContextState = csUdpAcceptedRecv; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host Insert to \"g_stUdpALEFlowEstablishList\"." ); } pFlowContext->enFlowDataOwner = foUdpALEFlowEstablishList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stUdpALEFlowEstablishList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } } if (IsListEmpty(&g_stUdpALEAcceptRecvList)) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"g_stUdpALEAcceptRecvList\" is Empty! Host IP = %ws; clent.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } ulInboundCount = 0; pListEntry = g_stUdpALEAcceptRecvList.Blink; pFirstLE = g_stUdpALEAcceptRecvList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (usRemotePort == pFlowContext->usRemotePort)) { pFirstAcceptingFlowContext = pFlowContext; ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } if (0 == ulInboundCount) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Matched element in \"g_stUdpALEAcceptRecvList\" not Found!!" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (g_bFiltersChangeInProgress | g_stFirewallConfig.bExternalClientBlocked) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Host %ws Blocked because (g_bFiltersChangeInProgress | g_stFirewallConfig.bExternalClientBlocked)!", szIpAddress ); pListEntry = g_stUdpALEAcceptRecvList.Blink; pFirstLE = g_stUdpALEAcceptRecvList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (usRemotePort == pFlowContext->usRemotePort)) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } for (ulI = 0; ulI < g_stFirewallConfig.nBlackSubnetListLength; ulI++) { UINT32 ulAddrPart = (ulRemoteAddress & g_stFirewallConfig.aBlackSubnetList[ulI]._ulIpMask); if (ulAddrPart == g_stFirewallConfig.aBlackSubnetList[ulI]._ulIpAddr) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Host %ws Blocked because is in Black List Subnet!", szIpAddress ); pListEntry = g_stUdpALEAcceptRecvList.Blink; pFirstLE = g_stUdpALEAcceptRecvList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (usRemotePort == pFlowContext->usRemotePort)) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } } for (ulI = 0; ulI < g_stFirewallConfig.nBlackListLength; ulI++) { if (ulRemoteAddress == g_stFirewallConfig.aBlackListArray[ulI]) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_WARNING, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Host %ws Blocked because exist in Black List!", szIpAddress ); pListEntry = g_stUdpALEAcceptRecvList.Blink; pFirstLE = g_stUdpALEAcceptRecvList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bIPv6) { if ((ulRemoteAddress == pFlowContext->nRemoteAddressV4) && (usRemotePort == pFlowContext->usRemotePort)) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } } ulInboundCount = 0; if (!IsListEmpty(&g_stFlowedFileList)) { pListEntry = g_stFlowedFileList.Blink; pFirstLE = g_stFlowedFileList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if ((IPPROTO_UDP == pFlowContext->enIpProto) && (!pFlowContext->bIPv6)) { if (ulRemoteAddress == pFlowContext->nRemoteAddressV4) { ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } } pFlowContext = pFirstAcceptingFlowContext; switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (0 == ulInboundCount) { pFlowContext->enContextState = csUdpAcceptedRecv; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host Insert to \"g_stUdpALEFlowEstablishList\"." ); } pFlowContext->enFlowDataOwner = foUdpALEFlowEstablishList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stUdpALEFlowEstablishList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } pFlowContext->pUdpQueryBufferList = pNetBufferList; pFlowContext->ulUdpQueryBufferSize = nDataSize + ulIpHeaderSize + ulTransportHeaderSize; pFlowContext->ulUdpQueryDataOffset = ulUdpDataOffset; pFlowContext->ulUdpQueryPacketOffset = ulUdpDataOffset - ulIpHeaderSize - ulTransportHeaderSize; ulUdpDataLength = nDataSize; pFlowContext->ulUdpQueryDataLength = ulUdpDataLength; ASSERT(pFlowContext->ulUdpQueryDataLength > 0); pFlowContext->enUdpQueryCompartmentID = enUdpCompartmentID; pFlowContext->ulUdpQueryIpHeaderSize = ulIpHeaderSize; pFlowContext->ulUdpQueryTransportHeaderSize = ulTransportHeaderSize; FwpsReferenceNetBufferList( pNetBufferList, TRUE ); pFlowContext->interfaceIndex = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_INTERFACE_INDEX].value.uint32; pFlowContext->subInterfaceIndex = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_SUB_INTERFACE_INDEX].value.uint32; pFlowContext->hAleAuthRecvAcceptCompletionHandle = hCompletionHandle; status = FwpsPendOperation( hCompletionHandle, &pFlowContext->hAleAuthRecvAcceptContext ); ASSERT(NT_SUCCESS(status)); pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->enContextState = csUdpFlowEstablishPended; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); if (bTestIpV4) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Packet from Tested IpV4 Host Insert to \"g_stUdpALEAcceptPendedList\"." ); } pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; WdfObjectReleaseLock(g_wdfControlDevice); } void NTAPI onAleAcceptRecvV6Classify( __in const FWPS_INCOMING_VALUES* inFixedValues, __in const FWPS_INCOMING_METADATA_VALUES* inMetaValues, __inout_opt void* layerData, _In_opt_ const void* classifyContext, __in const FWPS_FILTER* filter, __in UINT64 flowContext, __inout FWPS_CLASSIFY_OUT* classifyOut ) { PADDRESSES_DESCRIPTOR pAddressesDescriptor = NULL; UINT32 ulI; int i; BOOLEAN bLocalNetwork = FALSE; PLIST_ENTRY pListEntry, pFirstLE, pLastLE, pPrevLE; PFLOW_DATA pFlowContext = NULL, pFirstAcceptingFlowContext = NULL; UINT32 ulInboundCount = 0; BOOLEAN bEmpty; PNET_BUFFER_LIST pNetBufferList; NTSTATUS status = STATUS_SUCCESS; IPPROTO enIpProto; PNET_BUFFER pNetBuffer; UINT32 nDataSize; UINT32 ulUdpDataOffset; UINT32 ulIpHeaderSize; UINT32 ulTransportHeaderSize; COMPARTMENT_ID enUdpCompartmentID; UINT32 ulUdpDataLength; UINT16 usRemotePort; FWP_BYTE_ARRAY16 *pRemoteAddress; HANDLE hCompletionHandle = NULL; IN6_ADDR stIp6Address; WCHAR szIpAddress[128]; LPWSTR pAddressEnd; FWPS_PACKET_INJECTION_STATE packetState; HANDLE hInjectionHandle; WDFFILEOBJECT wdfInjectDataObject = NULL; BOOLEAN bTestIpV4; BOOLEAN bIPv6; WDFQUEUE wdfRequestQueue; WDFREQUEST wdfPendedRequest; WDFMEMORY wdfOutputMemory = NULL; IN_ADDR stIpAddress; IN6_ADDR stRemoteAddress; UINT32 ulRemoteAddress = 0, ulRemoteAddressN = 0; UNREFERENCED_PARAMETER(filter); UNREFERENCED_PARAMETER(classifyContext); UNREFERENCED_PARAMETER(flowContext); if (!(classifyOut->rights & FWPS_RIGHT_ACTION_WRITE)) { return; } WdfObjectAcquireLock(g_wdfControlDevice); pNetBufferList = (PNET_BUFFER_LIST) layerData; ASSERT(pNetBufferList != NULL); enIpProto = (IPPROTO) inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_PROTOCOL].value.uint8; ASSERT(IPPROTO_UDP == enIpProto); pRemoteAddress = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_IP_REMOTE_ADDRESS].value.byteArray16; pNetBuffer = NET_BUFFER_LIST_FIRST_NB(pNetBufferList); nDataSize = NET_BUFFER_DATA_LENGTH(pNetBuffer); ulUdpDataOffset = NET_BUFFER_DATA_OFFSET(pNetBuffer); enUdpCompartmentID = (COMPARTMENT_ID) inMetaValues->compartmentId; ASSERT(FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_IP_HEADER_SIZE)); ulIpHeaderSize = inMetaValues->ipHeaderSize; ulTransportHeaderSize = inMetaValues->transportHeaderSize; usRemotePort = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_IP_REMOTE_PORT].value.uint16; hInjectionHandle = g_hInjectionHandleV6; pAddressesDescriptor = WdfObjectGetTypedContext( g_wdfControlDevice, ADDRESSES_DESCRIPTOR ); if (NULL == pAddressesDescriptor) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (NULL == pAddressesDescriptor)" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL == pAddressesDescriptor->m_pDataArray) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Exit (NULL == pAddressesDescriptor->m_pDataArray)" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (!bfIPv6AddressInIPv6Subnet(pRemoteAddress, c_pGlobalIPv6Subnet)) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPublicIPV6AddrArray) { for (i = 0; im_nPublicIPV6AddrCount; i++) { if (bfIPv6AddressInIPv6Subnet(pRemoteAddress, &pAddressesDescriptor->m_pPublicIPV6AddrArray[i])) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (NULL != pAddressesDescriptor->m_pPrivateIPV6AddrArray) { for (i = 0; im_nPrivateIPV6AddrCount; i++) { if (bfIPv6AddressInIPv6Subnet(pRemoteAddress, &pAddressesDescriptor->m_pPrivateIPV6AddrArray[i])) { bLocalNetwork = TRUE; break; } } } if (bLocalNetwork) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } packetState = FwpsQueryPacketInjectionState( hInjectionHandle, pNetBufferList, (HANDLE*) &wdfInjectDataObject ); if ((packetState == FWPS_PACKET_INJECTED_BY_SELF) || (packetState == FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF)) { classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (!IsListEmpty(&g_stFlowedFileList)) { pListEntry = g_stFlowedFileList.Blink; pFirstLE = g_stFlowedFileList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if ((IPPROTO_UDP == pFlowContext->enIpProto) && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6) && (usRemotePort == pFlowContext->usRemotePort)) { switch (pFlowContext->enContextState) { case csUdpWaitPermitQuery2: case csUdpPermitQuery2Done: pFirstAcceptingFlowContext = pFlowContext; ulInboundCount++; break; } } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } if (ulInboundCount > 0) { ASSERT(1 == ulInboundCount); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } } if (!FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_COMPLETION_HANDLE)) { // Ответное сообщение пошло по маршруту отличному от маршрута DNS-запроса. // UDP-поток неоходимо закрыть. //RtlCopyMemory( // &stIp6Address, // pRemoteAddress, // sizeof(stIp6Address) // ); //pAddressEnd = RtlIpv6AddressToStringW( // &stIp6Address, // szIpAddress // ); //TraceEvents( // TRACE_LEVEL_WARNING, // TRACE_DNSFIREWALL, // "%!FUNC! line:%!LINE! %!LEVEL! FWPS_METADATA_FIELD_COMPLETION_HANDLE Not Present! Host IP = %ws; clent.port = %hu;", // szIpAddress, // usRemotePort // ); ulInboundCount = 0; if (!IsListEmpty(&g_stFlowedFileList)) { pListEntry = g_stFlowedFileList.Blink; pFirstLE = g_stFlowedFileList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if ((IPPROTO_UDP == pFlowContext->enIpProto) && (pFlowContext->bIPv6)) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6) && (usRemotePort == pFlowContext->usRemotePort) && (csUdpPermitQueryDone == pFlowContext->enContextState)) { pFirstAcceptingFlowContext = pFlowContext; ulInboundCount++; break; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } } if (0 == ulInboundCount) { RtlCopyMemory( &stIp6Address, pRemoteAddress, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Matched packet not found in \"g_stFlowedFileList\"!! Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } ulInboundCount = 0; if (!IsListEmpty(&g_stUdpALEAcceptPendedList)) { pListEntry = g_stUdpALEAcceptPendedList.Flink; pLastLE = g_stUdpALEAcceptPendedList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (ulInboundCount > 0) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Read Pended Accepted Packet fom Test IpV4 Host %ws; clent.port = %hu;", szIpAddress, usRemotePort ); } pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->ulUdpQueryCount++; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); //ASSERT(FALSE); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } if ((0 == ulInboundCount) && (!IsListEmpty(&g_stUdpInboundList))) { pListEntry = g_stUdpInboundList.Flink; pLastLE = g_stUdpInboundList.Blink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (!pFlowContext->bUdpQueryClassifyPended) { ulInboundCount++; break; } if (pListEntry == pLastLE) { break; } pListEntry = pListEntry->Flink; } if (1 == ulInboundCount) { bIPv6 = pFlowContext->bIPv6; if (bIPv6) { RtlCopyMemory( &stRemoteAddress, &pFlowContext->stRemoteAddressV6, sizeof(stRemoteAddress) ); } else { ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); } usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = ((!bIPv6) && (c_ulTestIpV4 == ulRemoteAddress)); if (bTestIpV4) { stIpAddress.S_un.S_addr = ulRemoteAddressN; pAddressEnd = RtlIpv4AddressToStringW( &stIpAddress, szIpAddress ); TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Pended Inbound Packet from Test IpV4 Host %ws Insert to \"g_stUdpALEAcceptPendedList\"; clent.port = %hu;", szIpAddress, usRemotePort ); } bEmpty = RemoveEntryList(&pFlowContext->listEntry); ulRemoteAddress = pFlowContext->nRemoteAddressV4; ulRemoteAddressN = RtlUlongByteSwap(ulRemoteAddress); usRemotePort = pFlowContext->usRemotePort; bTestIpV4 = (c_ulTestIpV4 == ulRemoteAddress); pFlowContext->bUdpQueryClassifyPended = TRUE; pFlowContext->hAleAuthRecvAcceptCompletionHandle = NULL; pFlowContext->ulUdpQueryCount++; pFlowContext->pUdpQueryBufferList = pFlowContext->pUdpQuery2BufferList; pFlowContext->pUdpQuery2BufferList = NULL; pFlowContext->ulUdpQueryBufferSize = pFlowContext->ulUdpQuery2BufferSize; pFlowContext->ulUdpQuery2BufferSize = 0; pFlowContext->ulUdpQueryDataOffset = pFlowContext->ulUdpQuery2DataOffset; pFlowContext->ulUdpQuery2DataOffset = 0; pFlowContext->ulUdpQueryPacketOffset = pFlowContext->ulUdpQuery2PacketOffset; pFlowContext->ulUdpQuery2PacketOffset = 0; pFlowContext->ulUdpQueryDataLength = pFlowContext->ulUdpQuery2DataLength; pFlowContext->ulUdpQuery2DataLength = 0; pFlowContext->enUdpQueryCompartmentID = pFlowContext->enUdpQuery2CompartmentID; pFlowContext->enUdpQuery2CompartmentID = (COMPARTMENT_ID) 0; pFlowContext->ulUdpQueryIpHeaderSize = pFlowContext->ulUdpQuery2IpHeaderSize; pFlowContext->ulUdpQuery2IpHeaderSize = 0; pFlowContext->ulUdpQueryTransportHeaderSize = pFlowContext->ulUdpQuery2TransportHeaderSize; pFlowContext->ulUdpQuery2TransportHeaderSize = 0; pFlowContext->enContextState = csUdpWaitReadQuery; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); //ASSERT(FALSE); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); wdfRequestQueue = pFlowContext->wdfWaitDnsQueryQueue; ASSERT(NULL != wdfRequestQueue); pFlowContext->wdfWaitDnsQueryQueue = NULL; status = WdfIoQueueRetrieveNextRequest( wdfRequestQueue, &wdfPendedRequest ); ASSERT(NT_SUCCESS(status)); status = WdfRequestRetrieveOutputMemory( wdfPendedRequest, &wdfOutputMemory ); ASSERT(NT_SUCCESS(status)); status = WdfMemoryCopyFromBuffer( wdfOutputMemory, 0, pFlowContext, sizeof(FLOW_DATA) ); ASSERT(NT_SUCCESS(status)); WdfRequestCompleteWithInformation( wdfPendedRequest, status, sizeof(FLOW_DATA) ); WdfObjectDelete(wdfRequestQueue); } } pFlowContext = pFirstAcceptingFlowContext; pFlowContext->enContextState = csUdpFlowBreak; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); status = FwpsFlowRemoveContext( pFlowContext->flowHandle, FWPS_LAYER_DATAGRAM_DATA_V6, g_nDatagramIdV6 ); if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"FwpsFlowRemoveContext\" return %!STATUS!", status ); } return; } hCompletionHandle = inMetaValues->completionHandle; if (!IsListEmpty(&g_stUdpAcceptNotifyList)) { ulInboundCount = 0; pListEntry = g_stUdpAcceptNotifyList.Blink; pFirstLE = g_stUdpAcceptNotifyList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6) && (usRemotePort == pFlowContext->usRemotePort)) { pFirstAcceptingFlowContext = pFlowContext; ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } if (ulInboundCount > 0) { if (g_bFiltersChangeInProgress | g_stFirewallConfig.bExternalClientBlocked) { pListEntry = g_stUdpAcceptNotifyList.Blink; pFirstLE = g_stUdpAcceptNotifyList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6) && (usRemotePort == pFlowContext->usRemotePort)) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } for (ulI = 0; ulI < g_stFirewallConfig.nBlackListV6Length; ulI++) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &g_stFirewallConfig.aBlackListV6Array[ulI])) { pListEntry = g_stUdpAcceptNotifyList.Blink; pFirstLE = g_stUdpAcceptNotifyList.Flink; for (;;) { pPrevLE = pListEntry->Blink; pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6) && (usRemotePort == pFlowContext->usRemotePort)) { switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); } } if (pListEntry == pFirstLE) { break; } pListEntry = pPrevLE; } classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } } pFlowContext = pFirstAcceptingFlowContext; switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->enContextState = csUdpAcceptedRecv; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEFlowEstablishList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stUdpALEFlowEstablishList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } } if (IsListEmpty(&g_stUdpALEAcceptRecvList)) { RtlCopyMemory( &stIp6Address, pRemoteAddress, sizeof(stIp6Address) ); pAddressEnd = RtlIpv6AddressToStringW( &stIp6Address, szIpAddress ); TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! \"g_stUdpALEAcceptRecvList\" is Empty! Host IP = %ws; clent.port = %hu;", szIpAddress, usRemotePort ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } ulInboundCount = 0; pListEntry = g_stUdpALEAcceptRecvList.Blink; pFirstLE = g_stUdpALEAcceptRecvList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if (pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6) && (usRemotePort == pFlowContext->usRemotePort)) { pFirstAcceptingFlowContext = pFlowContext; ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } if (0 == ulInboundCount) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DNSFIREWALL, "%!FUNC! line:%!LINE! %!LEVEL! Matched element in \"g_stUdpALEAcceptRecvList\" not Found!!" ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } if (g_bFiltersChangeInProgress | g_stFirewallConfig.bExternalClientBlocked) { pFlowContext = pFirstAcceptingFlowContext; switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->bIPv6 = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } for (ulI = 0; ulI < g_stFirewallConfig.nBlackListV6Length; ulI++) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &g_stFirewallConfig.aBlackListV6Array[ulI])) { pFlowContext = pFirstAcceptingFlowContext; switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); pFlowContext->bIPv6 = FALSE; pFlowContext->bUdpNotifyQuery = FALSE; pFlowContext->enContextState = csWaitQueryStarted; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foAcceptableList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stAcceptableList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } } ulInboundCount = 0; if (!IsListEmpty(&g_stFlowedFileList)) { pListEntry = g_stFlowedFileList.Blink; pFirstLE = g_stFlowedFileList.Flink; for (;;) { pFlowContext = CONTAINING_RECORD(pListEntry, FLOW_DATA, listEntry); ASSERT(pFlowContext == pFlowContext->pThis); if ((IPPROTO_UDP == pFlowContext->enIpProto) && pFlowContext->bIPv6) { if (bfIsIPv6AddressesEqual(pRemoteAddress, &pFlowContext->stRemoteAddressV6)) { ulInboundCount++; } } if (pListEntry == pFirstLE) { break; } pListEntry = pListEntry->Blink; } } pFlowContext = pFirstAcceptingFlowContext; switch (pFlowContext->enContextState) { case csUdpWaitAcceptRecv: break; default: ASSERT(FALSE); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; WdfObjectReleaseLock(g_wdfControlDevice); return; } bEmpty = RemoveEntryList(&pFlowContext->listEntry); if (0 == ulInboundCount) { pFlowContext->enContextState = csUdpAcceptedRecv; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEFlowEstablishList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stUdpALEFlowEstablishList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_PERMIT; WdfObjectReleaseLock(g_wdfControlDevice); return; } pFlowContext->pUdpQueryBufferList = pNetBufferList; pFlowContext->ulUdpQueryBufferSize = nDataSize + ulIpHeaderSize + ulTransportHeaderSize; pFlowContext->ulUdpQueryDataOffset = ulUdpDataOffset; pFlowContext->ulUdpQueryPacketOffset = ulUdpDataOffset - ulIpHeaderSize - ulTransportHeaderSize; ulUdpDataLength = nDataSize; pFlowContext->ulUdpQueryDataLength = ulUdpDataLength; ASSERT(pFlowContext->ulUdpQueryDataLength > 0); pFlowContext->enUdpQueryCompartmentID = enUdpCompartmentID; pFlowContext->ulUdpQueryIpHeaderSize = ulIpHeaderSize; pFlowContext->ulUdpQueryTransportHeaderSize = ulTransportHeaderSize; FwpsReferenceNetBufferList( pNetBufferList, TRUE ); pFlowContext->interfaceIndex = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_INTERFACE_INDEX].value.uint32; pFlowContext->subInterfaceIndex = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_SUB_INTERFACE_INDEX].value.uint32; pFlowContext->hAleAuthRecvAcceptCompletionHandle = hCompletionHandle; status = FwpsPendOperation( hCompletionHandle, &pFlowContext->hAleAuthRecvAcceptContext ); ASSERT(NT_SUCCESS(status)); pFlowContext->bUdpQueryClassifyPended = FALSE; pFlowContext->enContextState = csUdpFlowEstablishPended; push_css(pFlowContext->arContextStateStack, pFlowContext->enContextState); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); pFlowContext->enFlowDataOwner = foUdpALEAcceptPendedList; push_fos(pFlowContext->arFlowDataOwnerStack, pFlowContext->enFlowDataOwner); InsertTailList( &g_stUdpALEAcceptPendedList, &pFlowContext->listEntry ); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; WdfObjectReleaseLock(g_wdfControlDevice); }