diff options
| author | J M Rossy <[email protected]> | 2015-07-29 15:40:09 -0700 |
|---|---|---|
| committer | J M Rossy <[email protected]> | 2015-07-29 16:34:40 -0700 |
| commit | 5d61a4a79a1e96dc5d9af1e5e712c84507307544 (patch) | |
| tree | 49ed270893578cd18758b74ffcca16dc7ab948d6 /network/trans/WFPSampler/sys/ClassifyFunctions_BasicPacketExaminationCallouts.cpp | |
| parent | 5d41613e26e147d2300c786bb2b34cb4b4067a25 (diff) | |
Samples update for public Windows 10 release
Fix #2 Enabling WPP Recorder in Sensors Samples causes errors
Fix #4 Add back fixed KMDOD sample
Add new BarcodeScanner sample in pos folder
Add new MagneticStripeReader sample in pos folder
Add new SynpaticsTouch sample in input folder
Add new Power Engine Plugin sample in pofx folder
Add new DeviceMft sample in avstream folder
Add new AvsCamera sample in root
Add new SimBatt sample in root
Add other pre-existing samples not yet released for Win10
Diffstat (limited to 'network/trans/WFPSampler/sys/ClassifyFunctions_BasicPacketExaminationCallouts.cpp')
| -rw-r--r-- | network/trans/WFPSampler/sys/ClassifyFunctions_BasicPacketExaminationCallouts.cpp | 5640 |
1 files changed, 5640 insertions, 0 deletions
diff --git a/network/trans/WFPSampler/sys/ClassifyFunctions_BasicPacketExaminationCallouts.cpp b/network/trans/WFPSampler/sys/ClassifyFunctions_BasicPacketExaminationCallouts.cpp new file mode 100644 index 00000000..64c0b401 --- /dev/null +++ b/network/trans/WFPSampler/sys/ClassifyFunctions_BasicPacketExaminationCallouts.cpp @@ -0,0 +1,5640 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2014 Microsoft Corporation. All Rights Reserved. +// +// Module Name: +// ClassifyFunctions_BasicPacketExaminationCallouts.cpp +// +// Abstract: +// This module contains WFP Classify functions for examining indicated NET_BUFFER_LISTS. +// +// Naming Convention: +// +// <Module><Scenario> +// +// i.e. +// +// ClassifyBasicPacketExamination +// +// <Module> +// Classify - Function is an FWPS_CALLOUT_CLASSIFY_FN. +// <Scenario> +// BasicPacketExamination - Function demonstates examining classified packets. +// +// Private Functions: +// +// Public Functions: +// ClassifyBasicPacketExamination(), +// +// Author: +// Dusty Harper (DHarper) +// +// Revision History: +// +// [ Month ][Day] [Year] - [Revision]-[ Comments ] +// May 01, 2010 - 1.0 - Creation +// December 13, 2013 - 1.1 - Enhance function declaration for IntelliSense, enhance +// traces, add support for discard layers, and support +// tracing all of the classifyFn parameters. +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "Framework_WFPSamplerCalloutDriver.h" /// . +#include "ClassifyFunctions_BasicPacketExaminationCallouts.tmh" /// $(OBJ_PATH)\$(O)\ + +#define MAX_STRING_SIZE 2048 + +/** + @private_function="LogFlags" + + Purpose: Logs each of the flags from the FWPM_CONDITION_FLAGS value. <br> + <br> + Notes: Uses ETW Tracing for the logging. <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/AA364002.aspx <br> +*/ +VOID LogFlags(_In_ UINT32 flags) +{ + if(flags & FWP_CONDITION_FLAG_IS_LOOPBACK) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_LOOPBACK"); + + if(flags & FWP_CONDITION_FLAG_IS_IPSEC_SECURED) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_IPSEC_SECURED"); + + if(flags & FWP_CONDITION_FLAG_IS_REAUTHORIZE) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_REAUTHORIZE"); + + if(flags & FWP_CONDITION_FLAG_IS_WILDCARD_BIND) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_WILDCARD_BIND"); + + if(flags & FWP_CONDITION_FLAG_IS_RAW_ENDPOINT) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_RAW_ENDPOINT"); + + if(flags & FWP_CONDITION_FLAG_IS_FRAGMENT) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_FRAGMENT"); + + if(flags & FWP_CONDITION_FLAG_IS_FRAGMENT_GROUP) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_FRAGMENT_GROUP"); + + if(flags & FWP_CONDITION_FLAG_IS_IPSEC_NATT_RECLASSIFY) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_IPSEC_NATT_RECLASSIFY"); + + if(flags & FWP_CONDITION_FLAG_REQUIRES_ALE_CLASSIFY) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_REQUIRES_ALE_CLASSIFY"); + + if(flags & FWP_CONDITION_FLAG_IS_IMPLICIT_BIND) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_IMPLICIT_BIND"); + + +#if(NTDDI_VERSION >= NTDDI_VISTASP1) + + if(flags & FWP_CONDITION_FLAG_IS_REASSEMBLED) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_REASSEMBLED"); + + +#if(NTDDI_VERSION >= NTDDI_WIN7) + + if(flags & FWP_CONDITION_FLAG_IS_NAME_APP_SPECIFIED) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_NAME_APP_SPECIFIED"); + + if(flags & FWP_CONDITION_FLAG_IS_PROMISCUOUS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_PROMISCUOUS"); + + if(flags & FWP_CONDITION_FLAG_IS_AUTH_FW) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_AUTH_FW"); + + if(flags & FWP_CONDITION_FLAG_IS_RECLASSIFY) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_RECLASSIFY"); + + if(flags & FWP_CONDITION_FLAG_IS_OUTBOUND_PASS_THRU) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_OUTBOUND_PASS_THRU"); + + if(flags & FWP_CONDITION_FLAG_IS_INBOUND_PASS_THRU) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_INBOUND_PASS_THRU"); + + if(flags & FWP_CONDITION_FLAG_IS_CONNECTION_REDIRECTED) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_CONNECTION_REDIRECTED"); + + +#if(NTDDI_VERSION >= NTDDI_WIN8) + + if(flags & FWP_CONDITION_FLAG_IS_PROXY_CONNECTION) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_PROXY_CONNECTION"); + + if(flags & FWP_CONDITION_FLAG_IS_APPCONTAINER_LOOPBACK) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_APPCONTAINER_LOOPBACK"); + + if(flags & FWP_CONDITION_FLAG_IS_NON_APPCONTAINER_LOOPBACK) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_NON_APPCONTAINER_LOOPBACK"); + + if(flags & FWP_CONDITION_FLAG_IS_RESERVED) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_RESERVED"); + + if(flags & FWP_CONDITION_FLAG_IS_HONORING_POLICY_AUTHORIZE) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_FLAG_IS_HONORING_POLICY_AUTHORIZE"); + +#endif /// (NTDDI_VERSION >= NTDDI_WIN8) +#endif /// (NTDDI_VERSION >= NTDDI_WIN7) +#endif /// (NTDDI_VERSION >= NTDDI_VISTASP1) + + return; +} + +#if(NTDDI_VERSION >= NTDDI_WIN8) + +/** + @private_function="LogL2Flags" + + Purpose: Logs each of the flags from the FWPM_CONDITION_FLAGS value. <br> + <br> + Notes: Uses ETW Tracing for the logging. <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/AA364002.aspx <br> +*/ +VOID LogL2Flags(_In_ UINT32 flags) +{ + + if(flags & FWP_CONDITION_L2_IS_NATIVE_ETHERNET) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_L2_IS_NATIVE_ETHERNET"); + + if(flags & FWP_CONDITION_L2_IS_WIFI) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_L2_IS_WIFI"); + + if(flags & FWP_CONDITION_L2_IS_MOBILE_BROADBAND) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_L2_IS_MOBILE_BROADBAND"); + + if(flags & FWP_CONDITION_L2_IS_WIFI_DIRECT_DATA) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_L2_IS_WIFI_DIRECT_DATA"); + + if(flags & FWP_CONDITION_L2_IS_VM2VM) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_L2_IS_VM2VM"); + + if(flags & FWP_CONDITION_L2_IS_MALFORMED_PACKET) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_L2_IS_MALFORMED_PACKET"); + + if(flags & FWP_CONDITION_L2_IS_IP_FRAGMENT_GROUP) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_L2_IS_IP_FRAGMENT_GROUP"); + + if(flags & FWP_CONDITION_L2_IF_CONNECTOR_PRESENT) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\t\t\t\tFWP_CONDITION_L2_IF_CONNECTOR_PRESENT"); + return; +} + +#endif /// (NTDDI_VERSION >= NTDDI_WIN8) + +/** + @private_function="LogValue" + + Purpose: Logs each of the FWPS_INCOMING_VALUE from the FWPS_INCOMING_VALUES in classifyFn. <br> + <br> + Notes: Uses ETW Tracing for the logging. <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/FF552401.aspx <br> +*/ +VOID LogValue(_In_ const FWP_VALUE* pValue, + _In_ BOOLEAN shouldFormat = FALSE) +{ + if(pValue) + { + NTSTATUS status = STATUS_SUCCESS; + PSTR pString = 0; + + HLPR_NEW_ARRAY(pString, + CHAR, + MAX_STRING_SIZE, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + HLPR_BAIL_ON_ALLOC_FAILURE(pString, + status); + + switch(pValue->type) + { + case FWP_EMPTY: + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_EMPTY\n" + "\t\t\t\t\tuint64: %#p", + pValue->uint64); + + break; + } + case FWP_UINT8: + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_UINT8\n" + "\t\t\t\t\tuint8: %#x", + pValue->uint8); + + break; + } + case FWP_UINT16: + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_UINT16\n" + "\t\t\t\t\tuint16: %#x", + pValue->uint16); + + break; + } + case FWP_UINT32: + { + switch(shouldFormat) + { + case ADDRESS_VALUE: + { + BYTE pBytes[4] = {0}; + + RtlCopyMemory(pBytes, + &(pValue->uint32), + 4); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_UINT32\n" + "\t\t\t\t\tuint32: %d.%d.%d.%d", + pBytes[3], + pBytes[2], + pBytes[1], + pBytes[0]); + + break; + } + case FLAGS_VALUE: + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_UINT32\n" + "\t\t\t\t\tuint32: %#x", + pValue->uint32); + + LogFlags(pValue->uint32); + + break; + } + +#if(NTDDI_VERSION >= NTDDI_WIN8) + + case L2_FLAGS_VALUE: + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_UINT32\n" + "\t\t\t\t\tuint32: %#x", + pValue->uint32); + + LogL2Flags(pValue->uint32); + + break; + } + +#endif /// (NTDDI_VERSION >= NTDDI_WIN8) + + default: + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_UINT32\n" + "\t\t\t\t\tuint32: %#x", + pValue->uint32); + } + + break; + } + case FWP_UINT64: + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_UINT64\n" + "\t\t\t\t\tuint64: %#I64x", + *(pValue->uint64)); + + break; + } + case FWP_INT8: + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_INT8\n" + "\t\t\t\t\tint8: %#x", + pValue->int8); + + break; + } + case FWP_INT16: + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_INT16\n" + "\t\t\t\t\tint16: %#x", + pValue->int16); + + break; + } + case FWP_INT32: + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_INT32\n" + "\t\t\t\t\tint32: %#x", + pValue->int32); + + break; + } + case FWP_INT64: + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_INT64\n" + "\t\t\t\t\tint64: %#I64x", + *(pValue->int64)); + + break; + } + case FWP_FLOAT: + { + /// Using uint32 in place of float as floats are unsafe in kernel. + /// This is safe as its part of a union. + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_FLOAT\n" + "\t\t\t\t\tfloat32: %#x", + pValue->uint32); + + break; + } + case FWP_DOUBLE: + { + /// Using uint64 in place of double as doubles are unsafe in kernel. + /// This is safe as its part of a union. + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_DOUBLE\n" + "\t\t\t\t\tdouble64: %#I64x", + *(pValue->uint64)); + + break; + } + case FWP_BYTE_ARRAY16_TYPE: + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_BYTE_ARRAY16_TYPE\n" + "\t\t\t\t\tbyteArray16: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", + pValue->byteArray16->byteArray16[0], + pValue->byteArray16->byteArray16[1], + pValue->byteArray16->byteArray16[2], + pValue->byteArray16->byteArray16[3], + pValue->byteArray16->byteArray16[4], + pValue->byteArray16->byteArray16[5], + pValue->byteArray16->byteArray16[6], + pValue->byteArray16->byteArray16[7], + pValue->byteArray16->byteArray16[8], + pValue->byteArray16->byteArray16[9], + pValue->byteArray16->byteArray16[10], + pValue->byteArray16->byteArray16[11], + pValue->byteArray16->byteArray16[12], + pValue->byteArray16->byteArray16[13], + pValue->byteArray16->byteArray16[14], + pValue->byteArray16->byteArray16[15]); + + break; + } + case FWP_BYTE_BLOB_TYPE: + { + if(shouldFormat == UNICODE_STRING_VALUE && + KeGetCurrentIrql == PASSIVE_LEVEL) + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_BYTE_BLOB_TYPE\n" + "\t\t\t\t\tbyteBlob:\n" + "\t\t\t\t\t\tsize: %d\n" + "\t\t\t\t\t\tdata: %S", + pValue->byteBlob->size, + (PWSTR)(pValue->byteBlob->data)); + else + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_BYTE_BLOB_TYPE\n" + "\t\t\t\t\tbyteBlob:\n" + "\t\t\t\t\t\tsize: %d\n" + "\t\t\t\t\t\tdata: %#p", + pValue->byteBlob->size, + pValue->byteBlob->data); + + break; + } + case FWP_SID: + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_SID\n" + "\t\t\t\t\tsid: %#p", + pValue->sid); + + break; + } + case FWP_SECURITY_DESCRIPTOR_TYPE: + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_SECURITY_DESCRIPTOR_TYPE\n" + "\t\t\t\t\tsd:\n" + "\t\t\t\t\t\tsize: %d\n" + "\t\t\t\t\t\tdata: %#p", + pValue->sd->size, + pValue->sd->data); + break; + } + case FWP_TOKEN_INFORMATION_TYPE: + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_TOKEN_INFORMATION_TYPE\n" + "\t\t\t\t\ttokenInformation: %#p", + pValue->tokenInformation); + + break; + } + case FWP_TOKEN_ACCESS_INFORMATION_TYPE: + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_TOKEN_ACCESS_INFORMATION_TYPE\n" + "\t\t\t\t\ttokenAccessInformation:\n" + "\t\t\t\t\t\tsize: %d\n" + "\t\t\t\t\t\tdata: %#p", + pValue->tokenAccessInformation->size, + pValue->tokenAccessInformation->data); + break; + } + case FWP_UNICODE_STRING_TYPE: + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_UNICODE_STRING_TYPE\n" + "\t\t\t\t\tunicodeString: %S", + pValue->unicodeString); + + break; + } + case FWP_BYTE_ARRAY6_TYPE: + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\t\ttype: FWP_BYTE_ARRAY6_TYPE\n" + "\t\t\t\t\tbyteArray6: %02x:%02x:%02x:%02x:%02x:%02x", + pValue->byteArray6->byteArray6[0], + pValue->byteArray6->byteArray6[1], + pValue->byteArray6->byteArray6[2], + pValue->byteArray6->byteArray6[3], + pValue->byteArray6->byteArray6[4], + pValue->byteArray6->byteArray6[5]); + + break; + } + } + + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "%s", + pString); + + HLPR_BAIL_LABEL: + + HLPR_DELETE_ARRAY(pString, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + } + + return; +} + +/** + @private_function="LogValues" + + Purpose: Logs each of the FWPS_INCOMING_VALUE from the FWPS_INCOMING_VALUES in classifyFn. <br> + <br> + Notes: Uses ETW Tracing for the logging. <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/FF552401.aspx <br> +*/ +VOID LogValues(_In_reads_(numValues) const FWPS_INCOMING_VALUE* pValues, + _In_ UINT32 numValues, + _In_ UINT32 layerId) +{ + if(pValues) + { + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\tincomingValue:\n"); + + for(UINT32 index = 0; + index < numValues; + index++) + { + BOOLEAN shouldFormat = FALSE; + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tvalue: %d : %s\n", + index, + KrnlHlprFwpValueGetStringForFwpsIncomingValue(layerId, + index, + &shouldFormat)); + + LogValue(&(pValues[index].value), + shouldFormat); + } + } + + return; +} + +/** + @private_function="LogClassifyValues" + + Purpose: Logs the FWPS_INCOMING_VALUES from the classifyFn. <br> + <br> + Notes: Uses ETW Tracing for the logging. <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/FF552401.aspx <br> +*/ +VOID LogClassifyValues(_In_ const FWPS_INCOMING_VALUES* pClassifyValues) +{ + if(pClassifyValues) + { + NTSTATUS status = STATUS_SUCCESS; + PSTR pString = 0; + + HLPR_NEW_ARRAY(pString, + CHAR, + MAX_STRING_SIZE, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + HLPR_BAIL_ON_ALLOC_FAILURE(pString, + status); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\tClassifyValues:\n" + "\t\tlayerId: %d : %s\n" + "\t\tvalueCount: %d", + pClassifyValues->layerId, + KrnlHlprFwpsLayerIDToString(pClassifyValues->layerId), + pClassifyValues->valueCount); + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "%s", + pString); + + LogValues(pClassifyValues->incomingValue, + pClassifyValues->valueCount, + pClassifyValues->layerId); + + HLPR_BAIL_LABEL: + + HLPR_DELETE_ARRAY(pString, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + } + + return; +} + +/** + @private_function="LogMetadata" + + Purpose: Logs the FWPS_INCOMING_METADATA_VALUES from the classifyFn. <br> + <br> + Notes: Uses ETW Tracing for the logging. <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/FF552397.aspx <br> +*/ +VOID LogMetadata(_In_ const FWPS_INCOMING_METADATA_VALUES* pMetadata) +{ + if(pMetadata) + { + NTSTATUS status = STATUS_SUCCESS; + PSTR pString = 0; + + HLPR_NEW_ARRAY(pString, + CHAR, + MAX_STRING_SIZE, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + HLPR_BAIL_ON_ALLOC_FAILURE(pString, + status); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\tMetadata:\n" + "\t\tCurrentMetadataValues: %#x", + pMetadata->currentMetadataValues); + if(status == STATUS_SUCCESS) + { + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "%s", + pString); + + RtlZeroMemory(pString, + MAX_STRING_SIZE); + } + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_DISCARD_REASON)) + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\tdiscardMetadata:\n" + "\t\t\t\tdiscardModule: %d\n" + "\t\t\t\tdiscardReason: %d\n" + "\t\t\t\tfilterId: %I64d", + pMetadata->discardMetadata.discardModule, + pMetadata->discardMetadata.discardReason, + pMetadata->discardMetadata.filterId); + if(status == STATUS_SUCCESS) + { + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "%s", + pString); + + RtlZeroMemory(pString, + MAX_STRING_SIZE); + } + } + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_FLOW_HANDLE)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tflowHandle: %#I64x\n", + pMetadata->flowHandle); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_IP_HEADER_SIZE)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tipHeaderSize: %d\n", + pMetadata->ipHeaderSize); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_PROCESS_PATH)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tprocessPath: %s\n", + (PSTR)(pMetadata->processPath->data)); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_TOKEN)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\ttoken: %#I64x\n", + pMetadata->token); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_PROCESS_ID)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tprocessId: %#I64x\n", + pMetadata->processId); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_SYSTEM_FLAGS)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tflags: %#x\n", + pMetadata->flags); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_RESERVED)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\treserved: %#I64x\n", + pMetadata->reserved); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_SOURCE_INTERFACE_INDEX)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tsourceInterfaceIndex: %d\n", + pMetadata->sourceInterfaceIndex); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_DESTINATION_INTERFACE_INDEX)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tdestinationInterfaceIndex: %d\n", + pMetadata->destinationInterfaceIndex); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_TRANSPORT_HEADER_SIZE)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\ttransportHeaderSize: %d\n", + pMetadata->transportHeaderSize); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_COMPARTMENT_ID)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tcompartmentId: %d\n", + pMetadata->compartmentId); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_FRAGMENT_DATA)) + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\tfragmentMetadata:\n" + "\t\t\t\tfragmentIdentification: %#x\n" + "\t\t\t\tfragmentOffset: %d\n" + "\t\t\t\tfragmentLength: %d", + pMetadata->fragmentMetadata.fragmentIdentification, + pMetadata->fragmentMetadata.fragmentOffset, + pMetadata->fragmentMetadata.fragmentLength); + if(status == STATUS_SUCCESS) + { + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "%s", + pString); + + RtlZeroMemory(pString, + MAX_STRING_SIZE); + } + } + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_PATH_MTU)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tpathMtu: %d\n", + pMetadata->pathMtu); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_COMPLETION_HANDLE)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tcompletionHandle: %#I64x\n", + (UINT64)pMetadata->completionHandle); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_TRANSPORT_ENDPOINT_HANDLE)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\ttransportEndpointHandle: %#I64x\n", + pMetadata->transportEndpointHandle); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_TRANSPORT_CONTROL_DATA)) + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\t\t\tcontrolData:\n" + "\t\t\t\tcmsg_len: %I64d\n" + "\t\t\t\tcmsg_level: %d\n" + "\t\t\t\tcmsg_type: %d\n" + "\t\t\tcontrolDataLength: %d", + (UINT64)(pMetadata->controlData->cmsg_len), + pMetadata->controlData->cmsg_level, + pMetadata->controlData->cmsg_type, + pMetadata->controlDataLength); + if(status == STATUS_SUCCESS) + { + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "%s", + pString); + + RtlZeroMemory(pString, + MAX_STRING_SIZE); + } + } + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_REMOTE_SCOPE_ID)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tremoteScopeId: %#x\n", + pMetadata->remoteScopeId.Value); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_PACKET_DIRECTION)) + { + PSTR pDirection = "FWP_DIRECTION_MAX"; + + if(pMetadata->packetDirection == FWP_DIRECTION_OUTBOUND) + pDirection = "FWP_DIRECTION_OUTBOUND"; + else if(pMetadata->packetDirection == FWP_DIRECTION_INBOUND) + pDirection = "FWP_DIRECTION_INBOUND"; + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tpacketDirection: %s\n", + pDirection); + } + +#if(NTDDI_VERSION >= NTDDI_VISTASP1) + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_PACKET_SYSTEM_CRITICAL)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tpacketSystemCritical\n"); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_FORWARD_LAYER_OUTBOUND_PASS_THRU)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tforwardLayerOutboundPassThru\n"); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_FORWARD_LAYER_INBOUND_PASS_THRU)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tforwardLayerInboundPassThru\n"); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_ALE_CLASSIFY_REQUIRED)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\taleClassifyRequired\n"); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_TRANSPORT_HEADER_INCLUDE_HEADER)) + { + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\theaderIncludeHeader: %#p\n", + pMetadata->headerIncludeHeader); + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\theaderIncludeHeaderLength: %d\n", + pMetadata->headerIncludeHeaderLength); + } + +#if(NTDDI_VERSION >= NTDDI_WIN7) + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_DESTINATION_PREFIX)) + { + PSTR pAddrFamily = "AF_UNSPEC"; + + if(pMetadata->destinationPrefix.Prefix.si_family == AF_INET) + pAddrFamily = "AF_INET"; + else if(pMetadata->destinationPrefix.Prefix.si_family == AF_INET6) + pAddrFamily = "AF_INET6"; + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tdestinationPrefix:\n" + "\t\t\t\tPrefix:\n" + "\t\t\t\t\tIpv4:\n" + "\t\t\t\t\t\tsin_family: %d\n" + "\t\t\t\t\t\tsin_port: %d\n" + "\t\t\t\t\t\tsin_addr: %d.%d.%d.%d\n" + "\t\t\t\t\tIpv6:\n" + "\t\t\t\t\t\tsin6_family: %d\n" + "\t\t\t\t\t\tsin6_port: %d\n" + "\t\t\t\t\t\tsin6_flowinfo: %d\n" + "\t\t\t\t\t\tsin6_addr: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n" + "\t\t\t\t\tsi_family: %s\n" + "\t\t\t\tPrefixLength: %d\n", + pMetadata->destinationPrefix.Prefix.Ipv4.sin_family, + pMetadata->destinationPrefix.Prefix.Ipv4.sin_port, + pMetadata->destinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_un_b.s_b1, + pMetadata->destinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_un_b.s_b2, + pMetadata->destinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_un_b.s_b3, + pMetadata->destinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_un_b.s_b4, + pMetadata->destinationPrefix.Prefix.Ipv6.sin6_family, + pMetadata->destinationPrefix.Prefix.Ipv6.sin6_port, + pMetadata->destinationPrefix.Prefix.Ipv6.sin6_flowinfo, + pMetadata->destinationPrefix.Prefix.Ipv6.sin6_addr.u.Word[0], + pMetadata->destinationPrefix.Prefix.Ipv6.sin6_addr.u.Word[1], + pMetadata->destinationPrefix.Prefix.Ipv6.sin6_addr.u.Word[2], + pMetadata->destinationPrefix.Prefix.Ipv6.sin6_addr.u.Word[3], + pMetadata->destinationPrefix.Prefix.Ipv6.sin6_addr.u.Word[4], + pMetadata->destinationPrefix.Prefix.Ipv6.sin6_addr.u.Word[5], + pMetadata->destinationPrefix.Prefix.Ipv6.sin6_addr.u.Word[6], + pMetadata->destinationPrefix.Prefix.Ipv6.sin6_addr.u.Word[7], + pAddrFamily, + pMetadata->destinationPrefix.PrefixLength); + } + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_ETHER_FRAME_LENGTH)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tframeLength: %d\n", + pMetadata->frameLength); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_PARENT_ENDPOINT_HANDLE)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tparentEndpointHandle: %#I64x\n", + pMetadata->parentEndpointHandle); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_ICMP_ID_AND_SEQUENCE)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\ticmpIdAndSequence: %#x\n", + pMetadata->icmpIdAndSequence); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_LOCAL_REDIRECT_TARGET_PID)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tlocalRedirectTargetPID: %#x\n", + pMetadata->localRedirectTargetPID); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_ORIGINAL_DESTINATION)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\toriginalDestination: %#p\n", + pMetadata->originalDestination); + +#if(NTDDI_VERSION >= NTDDI_WIN8) + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_REDIRECT_RECORD_HANDLE)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tredirectRecords: %#p\n", + pMetadata->redirectRecords); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_SUB_PROCESS_TAG)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tsubProcessTag: %#p\n", + pMetadata->subProcessTag); + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\tCurrentL2MetadataValues: %#x\n", + pMetadata->currentL2MetadataValues); + + if(FWPS_IS_L2_METADATA_FIELD_PRESENT(pMetadata, + FWPS_L2_METADATA_FIELD_ETHERNET_MAC_HEADER_SIZE)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tethernetMacHeaderSize: %d\n", + pMetadata->ethernetMacHeaderSize); + + if(FWPS_IS_L2_METADATA_FIELD_PRESENT(pMetadata, + FWPS_L2_METADATA_FIELD_WIFI_OPERATION_MODE)) + { + PSTR WIFIMode = "UNKNOWN"; + + if(pMetadata->wiFiOperationMode == DOT11_OPERATION_MODE_EXTENSIBLE_AP) + WIFIMode = "DOT11_OPERATION_MODE_EXTENSIBLE_AP"; + else if(pMetadata->wiFiOperationMode == DOT11_OPERATION_MODE_EXTENSIBLE_STATION) + WIFIMode = "DOT11_OPERATION_MODE_EXTENSIBLE_STATION"; + else if(pMetadata->wiFiOperationMode == DOT11_OPERATION_MODE_NETWORK_MONITOR) + WIFIMode = "DOT11_OPERATION_MODE_NETWORK_MONITOR"; + else if(pMetadata->wiFiOperationMode == DOT11_OPERATION_MODE_WFD_DEVICE) + WIFIMode = "DOT11_OPERATION_MODE_WFD_DEVICE"; + else if(pMetadata->wiFiOperationMode == DOT11_OPERATION_MODE_WFD_GROUP_OWNER) + WIFIMode = "DOT11_OPERATION_MODE_WFD_GROUP_OWNER"; + else if(pMetadata->wiFiOperationMode == DOT11_OPERATION_MODE_WFD_CLIENT) + WIFIMode = "DOT11_OPERATION_MODE_WFD_CLIENT"; + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\twiFiOperationMode: %s\n", + WIFIMode); + } + + if(FWPS_IS_L2_METADATA_FIELD_PRESENT(pMetadata, + FWPS_L2_METADATA_FIELD_VSWITCH_SOURCE_PORT_ID)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tvSwitchSourcePortId: %#x\n", + pMetadata->vSwitchSourcePortId); + + if(FWPS_IS_L2_METADATA_FIELD_PRESENT(pMetadata, + FWPS_L2_METADATA_FIELD_VSWITCH_SOURCE_NIC_INDEX)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tvSwitchSourceNicIndex: %#x\n", + pMetadata->vSwitchSourceNicIndex); + + if(FWPS_IS_L2_METADATA_FIELD_PRESENT(pMetadata, + FWPS_L2_METADATA_FIELD_VSWITCH_PACKET_CONTEXT)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tvSwitchPacketContext: %#p\n", + pMetadata->vSwitchPacketContext); + + if(FWPS_IS_L2_METADATA_FIELD_PRESENT(pMetadata, + FWPS_L2_METADATA_FIELD_VSWITCH_DESTINATION_PORT_ID)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tvSwitchDestinationPortId: %#x\n", + pMetadata->vSwitchDestinationPortId); + +#if(NTDDI_VERSION >= NTDDI_WINBLUE) + + if(FWPS_IS_L2_METADATA_FIELD_PRESENT(pMetadata, + FWPS_L2_METADATA_FIELD_RESERVED)) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\treserved1: %#I64x\n", + pMetadata->reserved1); + +#endif /// (NTDDI_VERSION >= NTDDI_WINBLUE) +#endif /// (NTDDI_VERSION >= NTDDI_WIN8) +#endif /// (NTDDI_VERSION >= NTDDI_WIN7) +#endif /// (NTDDI_VERSION >= NTDDI_VISTASP1) + + HLPR_BAIL_LABEL: + + HLPR_DELETE_ARRAY(pString, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + } + + return; +} + +/** + @private_function="LogFilter" + + Purpose: Logs the FWPS_FILTER from the classifyFn. <br> + <br> + Notes: Uses ETW Tracing for the logging. <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/FF552387.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/FF552389.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/HH439768.aspx <br> +*/ +VOID LogFilter(_In_ const FWPS_FILTER* pFilter) +{ + if(pFilter) + { + NTSTATUS status = STATUS_SUCCESS; + PSTR pType = "FWP_EMPTY"; + UINT64 data = 0; + PSTR pAction = "FWP_ACTION_CALLOUT_UNKNOWN"; + PSTR pString = 0; + + if(pFilter->weight.type == FWP_UINT64) + { + pType = "FWP_UINT64"; + + if(pFilter->weight.uint64) + data = *(pFilter->weight.uint64); + } + + if(pFilter->action.type == FWP_ACTION_CALLOUT_TERMINATING) + pAction = "FWP_ACTION_CALLOUT_TERMINATING"; + else if(pFilter->action.type == FWP_ACTION_CALLOUT_INSPECTION) + pAction = "FWP_ACTION_CALLOUT_INSPECTION"; + + HLPR_NEW_ARRAY(pString, + CHAR, + MAX_STRING_SIZE, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + HLPR_BAIL_ON_ALLOC_FAILURE(pString, + status); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\tFilter:\n" + "\t\tfilterId: %#I64x\n" + "\t\tweight:\n" + "\t\t\ttype: %s\n" + "\t\t\tuint64: %#I64x\n" + "\t\tsubLayerWeight: %#x\n" + "\t\tflags: %#x\n" + "\t\tnumFilterConditions: %d:\n" + "\t\tfilterCondition: %#p\n" + "\t\taction:\n" + "\t\t\ttype: %s\n" + "\t\t\tcalloutId: %#x\n" + "\t\tcontext: %#I64d\n" + "\t\tproviderContext: %#p\n", + pFilter->filterId, + pType, + data, + pFilter->subLayerWeight, + pFilter->flags, + pFilter->numFilterConditions, + pFilter->filterCondition, + pAction, + pFilter->action.calloutId, + pFilter->context, + pFilter->providerContext); + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "%s", + pString); + + HLPR_BAIL_LABEL: + + HLPR_DELETE_ARRAY(pString, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + } + + return; +} + +/** + @private_function="LogClassifyOut" + + Purpose: Logs the FWPS_CLASSIFY_OUT from the classifyFn. <br> + <br> + Notes: Uses ETW Tracing for the logging. <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/FF551229.aspx <br> +*/ +VOID LogClassifyOut(_In_ const FWPS_CLASSIFY_OUT* pClassifyOut) +{ + if(pClassifyOut) + { + NTSTATUS status = STATUS_SUCCESS; + PSTR pAction = "FWP_ACTION_NONE"; + PSTR pString = 0; + + + if(pClassifyOut->actionType == FWP_ACTION_BLOCK) + pAction = "FWP_ACTION_BLOCK"; + else if(pClassifyOut->actionType == FWP_ACTION_CONTINUE) + pAction = "FWP_ACTION_CONTINUE"; + else if(pClassifyOut->actionType == FWP_ACTION_NONE_NO_MATCH) + pAction = "FWP_ACTION_NONE_NO_MATCH"; + else if(pClassifyOut->actionType == FWP_ACTION_PERMIT) + pAction = "FWP_ACTION_PERMIT"; + + HLPR_NEW_ARRAY(pString, + CHAR, + MAX_STRING_SIZE, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + HLPR_BAIL_ON_ALLOC_FAILURE(pString, + status); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\tClassifyOut:\n" + "\t\tactionType: %s\n" + "\t\toutContext: %#I64x\n" + "\t\tfilterId: %I64d\n" + "\t\trights: %#x", + pAction, + pClassifyOut->outContext, + pClassifyOut->filterId, + pClassifyOut->rights); + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "%s", + pString); + + if(pClassifyOut->rights & FWPS_RIGHT_ACTION_WRITE) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tFWPS_RIGHT_ACTION_WRITE"); + + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\tflags: %#x", + pClassifyOut->flags); + + if(pClassifyOut->flags & FWPS_CLASSIFY_OUT_FLAG_ABSORB) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tFWPS_CLASSIFY_OUT_FLAG_ABSORB"); + + if(pClassifyOut->flags & FWPS_CLASSIFY_OUT_FLAG_BUFFER_LIMIT_REACHED) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tFWPS_CLASSIFY_OUT_FLAG_BUFFER_LIMIT_REACHED"); + + if(pClassifyOut->flags & FWPS_CLASSIFY_OUT_FLAG_NO_MORE_DATA) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\t\tFWPS_CLASSIFY_OUT_FLAG_NO_MORE_DATA"); + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\treserved: %#x", + pClassifyOut->reserved); + + HLPR_BAIL_LABEL: + + HLPR_DELETE_ARRAY(pString, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + } + + return; +} + +/** + @private_function="LogEthernetIIHeader" + + Purpose: Logs the Ethernet II Header into a more easily readable format. <br> + <br> + Notes: Uses ETW Tracing for the logging, which is not ideal in a real world scenario. <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF562859.aspx <br> +*/ +VOID LogEthernetIIHeader(_In_ ETHERNET_II_HEADER* pEthernetIIHeader, + _In_ UINT32 vlanID = 0) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> LogEthernetIIHeader()\n"); + +#endif /// DBG + + NT_ASSERT(pEthernetIIHeader); + + NTSTATUS status = STATUS_SUCCESS; + PSTR pString = 0; + + HLPR_NEW_ARRAY(pString, + CHAR, + MAX_STRING_SIZE, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + HLPR_BAIL_ON_ALLOC_FAILURE(pString, + status); + + if(vlanID) + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n" + "\t\t 0 1 2\n" + "\t\t 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| |\n" + "\t\t+ Destination MAC Address +\n" + "\t\t| |\n" + "\t\t| %02x:%02x:%02x:%02x:%02x:%02x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| |\n" + "\t\t+ Source MAC Address +\n" + "\t\t| |\n" + "\t\t| %02x:%02x:%02x:%02x:%02x:%02x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| VLAN ID ... >\n" + "\t\t| >\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t|VLAN ID (cont.)| Type |\n" + "\t\t| | |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n", + pEthernetIIHeader->pDestinationAddress[0], + pEthernetIIHeader->pDestinationAddress[1], + pEthernetIIHeader->pDestinationAddress[2], + pEthernetIIHeader->pDestinationAddress[3], + pEthernetIIHeader->pDestinationAddress[4], + pEthernetIIHeader->pDestinationAddress[5], + pEthernetIIHeader->pSourceAddress[0], + pEthernetIIHeader->pSourceAddress[1], + pEthernetIIHeader->pSourceAddress[2], + pEthernetIIHeader->pSourceAddress[3], + pEthernetIIHeader->pSourceAddress[4], + pEthernetIIHeader->pSourceAddress[5]); + else + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n" + "\t\t 0 1 2\n" + "\t\t 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| |\n" + "\t\t+ Destination MAC Address +\n" + "\t\t| |\n" + "\t\t| %02x:%02x:%02x:%02x:%02x:%02x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| |\n" + "\t\t+ Source MAC Address +\n" + "\t\t| |\n" + "\t\t| %02x:%02x:%02x:%02x:%02x:%02x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Type | Data... |\n" + "\t\t| %04x | |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n", + pEthernetIIHeader->pDestinationAddress[0], + pEthernetIIHeader->pDestinationAddress[1], + pEthernetIIHeader->pDestinationAddress[2], + pEthernetIIHeader->pDestinationAddress[3], + pEthernetIIHeader->pDestinationAddress[4], + pEthernetIIHeader->pDestinationAddress[5], + pEthernetIIHeader->pSourceAddress[0], + pEthernetIIHeader->pSourceAddress[1], + pEthernetIIHeader->pSourceAddress[2], + pEthernetIIHeader->pSourceAddress[3], + pEthernetIIHeader->pSourceAddress[4], + pEthernetIIHeader->pSourceAddress[5], + ntohs(pEthernetIIHeader->type)); + + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\tEthernet II Header:%s", + pString); + + HLPR_BAIL_LABEL: + + HLPR_DELETE_ARRAY(pString, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- LogEthernetIIHeader [status: %#x]\n", + status); + +#else + + /// Used to get around preFast Warning 28931 + UNREFERENCED_PARAMETER(status); + +#endif /// DBG + + return; +} + +/** + @private_function="LogEthernetSNAPHeader" + + Purpose: Logs the MAC Ethernet SNAP Header into a more easily readable format. <br> + <br> + Notes: Uses ETW Tracing for the logging, which is not ideal in a real world scenario. <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF562859.aspx <br> +*/ +VOID LogEthernetSNAPHeader(_In_ ETHERNET_SNAP_HEADER* pEthernetSNAPHeader) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> LogEthernetSNAPHeader()\n"); + +#endif /// DBG + + NT_ASSERT(pEthernetSNAPHeader); + + NTSTATUS status = STATUS_SUCCESS; + PSTR pString = 0; + + HLPR_NEW_ARRAY(pString, + CHAR, + MAX_STRING_SIZE, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + HLPR_BAIL_ON_ALLOC_FAILURE(pString, + status); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n" + "\t\t 0 1 2\n" + "\t\t 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| |\n" + "\t\t+ Destination MAC Address +\n" + "\t\t| |\n" + "\t\t| %02x:%02x:%02x:%02x:%02x:%02x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| |\n" + "\t\t+ Source MAC Address +\n" + "\t\t| |\n" + "\t\t| %02x:%02x:%02x:%02x:%02x:%02x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Length | DSAP |\n" + "\t\t| %04x | %02x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| SSAP | Control Byte | OUI ... >\n" + "\t\t| %02x | %02x | %02x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t< OUI (cont.) | Type ... >\n" + "\t\t< %02x%02x | %04x >\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t< Type (cont.) | Data ... |\n" + "\t\t< | |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n", + pEthernetSNAPHeader->pDestinationAddress[0], + pEthernetSNAPHeader->pDestinationAddress[1], + pEthernetSNAPHeader->pDestinationAddress[2], + pEthernetSNAPHeader->pDestinationAddress[3], + pEthernetSNAPHeader->pDestinationAddress[4], + pEthernetSNAPHeader->pDestinationAddress[5], + pEthernetSNAPHeader->pSourceAddress[0], + pEthernetSNAPHeader->pSourceAddress[1], + pEthernetSNAPHeader->pSourceAddress[2], + pEthernetSNAPHeader->pSourceAddress[3], + pEthernetSNAPHeader->pSourceAddress[4], + pEthernetSNAPHeader->pSourceAddress[5], + pEthernetSNAPHeader->length, + pEthernetSNAPHeader->destinationSAP, + pEthernetSNAPHeader->sourceSAP, + pEthernetSNAPHeader->controlByte, + pEthernetSNAPHeader->pOUI[0], + pEthernetSNAPHeader->pOUI[1], + pEthernetSNAPHeader->pOUI[2], + ntohs(pEthernetSNAPHeader->type)); + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\tEthernet SNAP Header:%s", + pString); + + HLPR_BAIL_LABEL: + + HLPR_DELETE_ARRAY(pString, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- LogEthernetSNAPHeader() [status: %#x]\n", + status); + +#else + + /// Used to get around preFast Warning 28931 + UNREFERENCED_PARAMETER(status); + +#endif /// DBG + + return; +} + +/** + @private_function="LogIPv4Header" + + Purpose: Logs the IPv4 Header into a more easily readable format. <br> + <br> + Notes: Uses ETW Tracing for the logging, which is not ideal in a real world scenario. <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF562859.aspx <br> +*/ +VOID LogIPv4Header(_In_ IP_HEADER_V4* pIPv4Header) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> LogIPv4Header()\n"); + +#endif /// DBG + + NT_ASSERT(pIPv4Header); + + NTSTATUS status = STATUS_SUCCESS; + PSTR pString = 0; + + HLPR_NEW_ARRAY(pString, + CHAR, + MAX_STRING_SIZE, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + HLPR_BAIL_ON_ALLOC_FAILURE(pString, + status); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n" + "\t\t 0 1 2 3\n" + "\t\t 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t|Version| IHL |Type of Service| Total Length |\n" + "\t\t| %01x | %01x | %02x | %04x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Identification |Flags| Fragment Offset |\n" + "\t\t| %04x | %01x | %04x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Time to Live | Protocol | Header Checksum |\n" + "\t\t| %02x | %02x | %04x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Source Address |\n" + "\t\t| %08x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Destination Address |\n" + "\t\t| %08x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Options | Padding |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n", + pIPv4Header->version, + pIPv4Header->headerLength, + pIPv4Header->typeOfService, + pIPv4Header->totalLength, + ntohs(pIPv4Header->identification), + pIPv4Header->flags, + pIPv4Header->fragmentOffset, + pIPv4Header->timeToLive, + pIPv4Header->protocol, + ntohs(pIPv4Header->checksum), + ntohl((*((UINT32*)pIPv4Header->pSourceAddress))), + ntohl((*((UINT32*)pIPv4Header->pDestinationAddress)))); + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\tIPv4 Header:%s", + pString); + + HLPR_BAIL_LABEL: + + HLPR_DELETE_ARRAY(pString, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- LogIPv4Header() [status: %#x]\n", + status); + +#else + + /// Used to get around preFast Warning 28931 + UNREFERENCED_PARAMETER(status); + +#endif /// DBG + + return; +} + +/** + @private_function="LogIPv6Header" + + Purpose: Logs the IPv6 Header into a more easily readable format. <br> + <br> + Notes: Uses ETW Tracing for the logging, which is not ideal in a real world scenario. <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF562859.aspx <br> +*/ +VOID LogIPv6Header(_In_ IP_HEADER_V6* pIPv6Header) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> LogIPv6Header()\n"); + +#endif /// DBG + + NT_ASSERT(pIPv6Header); + + NTSTATUS status = STATUS_SUCCESS; + PSTR pString = 0; + UINT32 versionTrafficClassAndFlowLabel = 0; + + RtlCopyMemory(&versionTrafficClassAndFlowLabel, + pIPv6Header->pVersionTrafficClassAndFlowLabel, + 4); + + HLPR_NEW_ARRAY(pString, + CHAR, + MAX_STRING_SIZE, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + HLPR_BAIL_ON_ALLOC_FAILURE(pString, + status); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n" + "\t\t 0 1 2 3\n" + "\t\t 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t|Version| Traffic Class | Flow Label |\n" + "\t\t| %01x | %02x | %05x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Payload Length | Next Header | Hop Limit |\n" + "\t\t| %04x | %02x | %02x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| |\n" + "\t\t+ +\n" + "\t\t| |\n" + "\t\t+ Source Address +\n" + "\t\t| |\n" + "\t\t+ +\n" + "\t\t| %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| |\n" + "\t\t+ +\n" + "\t\t| |\n" + "\t\t+ Destination Address +\n" + "\t\t| |\n" + "\t\t+ +\n" + "\t\t| %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n", + pIPv6Header->version.value, + (ntohl(versionTrafficClassAndFlowLabel) & 0x0FF00000) >> 20, + ntohl(versionTrafficClassAndFlowLabel) & 0x000FFFFF, + ntohs(pIPv6Header->payloadLength), + pIPv6Header->nextHeader, + pIPv6Header->hopLimit, + pIPv6Header->pSourceAddress[0], + pIPv6Header->pSourceAddress[1], + pIPv6Header->pSourceAddress[2], + pIPv6Header->pSourceAddress[3], + pIPv6Header->pSourceAddress[4], + pIPv6Header->pSourceAddress[5], + pIPv6Header->pSourceAddress[6], + pIPv6Header->pSourceAddress[7], + pIPv6Header->pSourceAddress[8], + pIPv6Header->pSourceAddress[9], + pIPv6Header->pSourceAddress[10], + pIPv6Header->pSourceAddress[11], + pIPv6Header->pSourceAddress[12], + pIPv6Header->pSourceAddress[13], + pIPv6Header->pSourceAddress[14], + pIPv6Header->pSourceAddress[15], + pIPv6Header->pDestinationAddress[0], + pIPv6Header->pDestinationAddress[1], + pIPv6Header->pDestinationAddress[2], + pIPv6Header->pDestinationAddress[3], + pIPv6Header->pDestinationAddress[4], + pIPv6Header->pDestinationAddress[5], + pIPv6Header->pDestinationAddress[6], + pIPv6Header->pDestinationAddress[7], + pIPv6Header->pDestinationAddress[8], + pIPv6Header->pDestinationAddress[9], + pIPv6Header->pDestinationAddress[10], + pIPv6Header->pDestinationAddress[11], + pIPv6Header->pDestinationAddress[12], + pIPv6Header->pDestinationAddress[13], + pIPv6Header->pDestinationAddress[14], + pIPv6Header->pDestinationAddress[15]); + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\tIPv6 Header:%s", + pString); + + HLPR_BAIL_LABEL: + + HLPR_DELETE_ARRAY(pString, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- LogIPv6Header [status: %#x]\n", + status); +#else + + /// Used to get around preFast Warning 28931 + UNREFERENCED_PARAMETER(status); + +#endif /// DBG + + return; +} + +/** + @private_function="LogIPHeader" + + Purpose: Proxy IP Header logging to appropriate logging function base on IP version. <br> + <br> + Notes: <br> + <br> + MSDN_Ref: <br> +*/ +VOID LogIPHeader(_In_ VOID* pIPHeader, + _In_ UINT8 ipVersion) +{ + NT_ASSERT(pIPHeader); + + if(ipVersion == IPV4) + LogIPv4Header((IP_HEADER_V4*)pIPHeader); + else + LogIPv6Header((IP_HEADER_V6*)pIPHeader); + + return; +} + +/** + @private_function="LogICMPv4Header" + + Purpose: Logs the ICMPv4 Header into a more easily readable format. <br> + <br> + Notes: Uses ETW Tracing for the logging, which is not ideal in a real world scenario. <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF562859.aspx <br> +*/ +VOID LogICMPv4Header(_In_ ICMP_HEADER_V4* pICMPv4Header) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> LogICMPv4Header()\n"); + +#endif /// DBG + + NT_ASSERT(pICMPv4Header); + + NTSTATUS status = STATUS_SUCCESS; + PSTR pString = 0; + + HLPR_NEW_ARRAY(pString, + CHAR, + MAX_STRING_SIZE, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + HLPR_BAIL_ON_ALLOC_FAILURE(pString, + status); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n" + "\t\t 0 1 2 3\n" + "\t\t 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Type | Code | Checksum |\n" + "\t\t| %02x | %02x | %04x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Variable (Dependent on Type / Code) |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n", + pICMPv4Header->type, + pICMPv4Header->code, + ntohs(pICMPv4Header->checksum)); + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\tICMPv4 Header:%s", + pString); + + HLPR_BAIL_LABEL: + + HLPR_DELETE_ARRAY(pString, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- LogICMPv4Header [status: %#x]\n", + status); + +#else + + /// Used to get around preFast Warning 28931 + UNREFERENCED_PARAMETER(status); + +#endif /// DBG + + return; +} + +/** + @private_function="LogICMPv6Header" + + Purpose: Logs the ICMPv6 Header into a more easily readable format. <br> + <br> + Notes: Uses ETW Tracing for the logging, which is not ideal in a real world scenario. <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF562859.aspx <br> +*/ +VOID LogICMPv6Header(_In_ ICMP_HEADER_V6* pICMPv6Header) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> LogICMPv6Header()\n"); + +#endif /// DBG + + NT_ASSERT(pICMPv6Header); + + NTSTATUS status = STATUS_SUCCESS; + PSTR pString = 0; + + HLPR_NEW_ARRAY(pString, + CHAR, + MAX_STRING_SIZE, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + HLPR_BAIL_ON_ALLOC_FAILURE(pString, + status); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n" + "\t\t 0 1 2 3\n" + "\t\t 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Type | Code | Checksum |\n" + "\t\t| %02x | %02x | %04x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Variable (Dependent on Type / Code) |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n", + pICMPv6Header->type, + pICMPv6Header->code, + ntohs(pICMPv6Header->checksum)); + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\tICMPv6 Header:%s", + pString); + + HLPR_BAIL_LABEL: + + HLPR_DELETE_ARRAY(pString, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- LogICMPv6Header() [status: %#x]\n", + status); + +#else + + /// Used to get around preFast Warning 28931 + UNREFERENCED_PARAMETER(status); + +#endif /// DBG + + return; +} + +/** + @private_function="LogTCPHeader" + + Purpose: Logs the TCP Header into a more easily readable format. <br> + <br> + Notes: Uses ETW Tracing for the logging, which is not ideal in a real world scenario. <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF562859.aspx <br> +*/ +VOID LogTCPHeader(_In_ TCP_HEADER* pTCPHeader) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> LogTCPHeader()\n"); + +#endif /// DBG + + NT_ASSERT(pTCPHeader); + + NTSTATUS status = STATUS_SUCCESS; + PSTR pString = 0; + + HLPR_NEW_ARRAY(pString, + CHAR, + MAX_STRING_SIZE, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + HLPR_BAIL_ON_ALLOC_FAILURE(pString, + status); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n" + "\t\t 0 1 2 3\n" + "\t\t 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Source Port | Destination Port |\n" + "\t\t| %04x | %04x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Sequence Number |\n" + "\t\t| %08x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Acknowledgment Number |\n" + "\t\t| %08x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t|Offset |Rsvd |N|C|E|U|A|P|R|S|F| Window |\n" + "\t\t| %01x | %01x |%01x|%01x|%01x|%01x|%01x|%01x|%01x|%01x|%01x| %04x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Checksum | Urgent Pointer |\n" + "\t\t| %04x | %04x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Options | Padding |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n", + ntohs(pTCPHeader->sourcePort), + ntohs(pTCPHeader->destinationPort), + ntohl(pTCPHeader->sequenceNumber), + ntohl(pTCPHeader->acknowledgementNumber), + pTCPHeader->dORNS.dataOffset, + pTCPHeader->dORNS.reserved, + pTCPHeader->dORNS.nonceSum, + pTCPHeader->CWR, + pTCPHeader->ECE, + pTCPHeader->URG, + pTCPHeader->ACK, + pTCPHeader->PSH, + pTCPHeader->RST, + pTCPHeader->SYN, + pTCPHeader->FIN, + ntohs(pTCPHeader->window), + ntohs(pTCPHeader->checksum), + ntohs(pTCPHeader->urgentPointer)); + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\tTCP Header:%s", + pString); + + HLPR_BAIL_LABEL: + + HLPR_DELETE_ARRAY(pString, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- LogTCPHeader() [status: %#x]\n", + status); + +#else + + /// Used to get around preFast Warning 28931 + UNREFERENCED_PARAMETER(status); + +#endif /// DBG + + return; +} + +/** + @private_function="LogUDPHeader" + + Purpose: Logs the UDP Header into a more easily readable format. <br> + <br> + Notes: Uses ETW Tracing for the logging, which is not ideal in a real world scenario. <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF562859.aspx <br> +*/ +VOID LogUDPHeader(_In_ UDP_HEADER* pUDPHeader) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> LogUDPHeader()\n"); + +#endif /// DBG + + NT_ASSERT(pUDPHeader); + + NTSTATUS status = STATUS_SUCCESS; + PSTR pString = 0; + + HLPR_NEW_ARRAY(pString, + CHAR, + MAX_STRING_SIZE, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + HLPR_BAIL_ON_ALLOC_FAILURE(pString, + status); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n" + "\t\t 0 1 2 3\n" + "\t\t 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Source Port | Destination Port |\n" + "\t\t| %04x | %04x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n" + "\t\t| Length | Checksum |\n" + "\t\t| %04x | %04x |\n" + "\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n", + ntohs(pUDPHeader->sourcePort), + ntohs(pUDPHeader->destinationPort), + ntohs(pUDPHeader->length), + ntohs(pUDPHeader->checksum)); + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\tUDP Header:%s", + pString); + + HLPR_BAIL_LABEL: + + HLPR_DELETE_ARRAY(pString, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- LogUDPHeader() [status: %#x]\n", + status); + +#else + + /// Used to get around preFast Warning 28931 + UNREFERENCED_PARAMETER(status); + +#endif /// DBG + + return; +} + +/** + @private_function="LogTransportHeader" + + Purpose: Proxy Transport Header logging to appropriate logging function base on IP protocol.<br> + <br> + Notes: <br> + <br> + MSDN_Ref: <br> +*/ +VOID LogTransportHeader(_In_ VOID* pTransportHeader, + _In_ UINT8 ipProtocol) +{ + NT_ASSERT(pTransportHeader); + + switch(ipProtocol) + { + case ICMPV4: + { + LogICMPv4Header((ICMP_HEADER_V4*)pTransportHeader); + + break; + } + case TCP: + { + LogTCPHeader((TCP_HEADER*)pTransportHeader); + + break; + } + case UDP: + { + LogUDPHeader((UDP_HEADER*)pTransportHeader); + + break; + } + case ICMPV6: + { + LogICMPv6Header((ICMP_HEADER_V6*)pTransportHeader); + + break; + } + } + + return; +} + +#if(NTDDI_VERSION >= NTDDI_WIN8) + +/** + @private_function="PerformBasicPacketExaminationAtInboundMACFrame" + + Purpose: Examines and logs the contents of the MAC Header and Ip and Transport Headers if + available. <br> + <br> + Notes: Applies to the following framing layers: <br> + FWPM_LAYER_INBOUND_MAC_FRAME_ETHERNET <br> + FWPM_LAYER_INBOUND_MAC_FRAME_NATIVE <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF560703.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF564527.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF562631.aspx <br> +*/ +VOID PerformBasicPacketExaminationAtInboundMACFrame(_In_ CLASSIFY_DATA* pClassifyData) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> PerformBasicPacketExaminationAtInboundMACFrame()\n"); + +#endif /// DBG + + NT_ASSERT(pClassifyData); + + NTSTATUS status = STATUS_SUCCESS; + FWPS_INCOMING_VALUES* pClassifyValues = (FWPS_INCOMING_VALUES*)pClassifyData->pClassifyValues; + FWPS_INCOMING_METADATA_VALUES* pMetadata = (FWPS_INCOMING_METADATA_VALUES*)pClassifyData->pMetadataValues; + UINT32 bytesRetreated = 0; + UINT32 bytesAdvanced = 0; + UINT32 macHeaderSize = 0; + UINT32 ipHeaderSize = 0; + UINT16 etherType = 0; + UINT8 ipProtocol = 0; + VOID* pHeader = 0; + BOOLEAN needToFreeMemory = FALSE; + + if(FWPS_IS_L2_METADATA_FIELD_PRESENT(pMetadata, + FWPS_L2_METADATA_FIELD_ETHERNET_MAC_HEADER_SIZE)) + macHeaderSize = pMetadata->ethernetMacHeaderSize; + + if(pClassifyValues->layerId == FWPS_LAYER_INBOUND_MAC_FRAME_ETHERNET) + { + FWP_VALUE* pDestinationAddressValue = 0; + FWP_VALUE* pSourceAddressValue = 0; + FWP_VALUE* pEtherTypeValue = 0; + FWP_VALUE* pVLANIDValue = 0; + + pSourceAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_MAC_REMOTE_ADDRESS); + HLPR_BAIL_ON_NULL_POINTER(pSourceAddressValue); + + pDestinationAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_MAC_LOCAL_ADDRESS); + HLPR_BAIL_ON_NULL_POINTER(pDestinationAddressValue); + + pEtherTypeValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_ETHER_TYPE); + HLPR_BAIL_ON_NULL_POINTER(pEtherTypeValue); + + pVLANIDValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_VLAN_ID); + HLPR_BAIL_ON_NULL_POINTER(pVLANIDValue); + + /// Initial offset is at the IP Header, so retreat the size of the MAC Header ... + status = NdisRetreatNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + macHeaderSize, + 0, + 0); + if(status != STATUS_SUCCESS) + { + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_ERROR_LEVEL, + " !!!! PerformBasicPacketExaminationAtInboundMACFrame: NdisRetreatNetBufferDataStart() [status: %#x]\n", + status); + + HLPR_BAIL; + } + else + bytesRetreated = macHeaderSize; + + status = KrnlHlprMACHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory, + macHeaderSize); + HLPR_BAIL_ON_FAILURE(status); + + if(macHeaderSize == sizeof(ETHERNET_SNAP_HEADER)) + { + ETHERNET_SNAP_HEADER* pEthernetSNAPHeader = (ETHERNET_SNAP_HEADER*)pHeader; + + NT_ASSERT(ntohs(pEthernetSNAPHeader->type) == pEtherTypeValue->uint16); + + LogEthernetSNAPHeader(pEthernetSNAPHeader); + } + else + { + ETHERNET_II_HEADER* pEthernetIIHeader = (ETHERNET_II_HEADER*)pHeader; + + NT_ASSERT(RtlCompareMemory(pEthernetIIHeader->pDestinationAddress, + pDestinationAddressValue->byteArray6->byteArray6, + ETHERNET_ADDRESS_SIZE) == ETHERNET_ADDRESS_SIZE); + NT_ASSERT(RtlCompareMemory(pEthernetIIHeader->pSourceAddress, + pSourceAddressValue->byteArray6->byteArray6, + ETHERNET_ADDRESS_SIZE) == ETHERNET_ADDRESS_SIZE); + NT_ASSERT(ntohs(pEthernetIIHeader->type) == pEtherTypeValue->uint16); + + LogEthernetIIHeader(pEthernetIIHeader); + } + + etherType = pEtherTypeValue->uint16; + } + else + { + FWP_VALUE* pNDISMediaType = 0; + + pNDISMediaType = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_NDIS_MEDIA_TYPE); + HLPR_BAIL_ON_NULL_POINTER(pNDISMediaType); + + /// Initial offset is at the MAC Header ... + status = KrnlHlprMACHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory, + macHeaderSize); + HLPR_BAIL_ON_FAILURE(status); + + if(pNDISMediaType->uint32 == NdisMedium802_3) + { + ETHERNET_II_HEADER* pEthernetIIHeader = (ETHERNET_II_HEADER*)pHeader; + + etherType = ntohs(pEthernetIIHeader->type); + + if(etherType == NDIS_ETH_TYPE_IPV4 || + etherType == NDIS_ETH_TYPE_ARP || + etherType == NDIS_ETH_TYPE_IPV6 || + etherType == NDIS_ETH_TYPE_802_1X || + etherType == NDIS_ETH_TYPE_802_1Q || + etherType == NDIS_ETH_TYPE_SLOW_PROTOCOL) + { + LogEthernetIIHeader(pEthernetIIHeader); + + if(etherType == NDIS_ETH_TYPE_IPV4 || + etherType == NDIS_ETH_TYPE_IPV6) + macHeaderSize = sizeof(ETHERNET_II_HEADER); + } + else + { + ETHERNET_SNAP_HEADER* pEthernetSNAPHeader = (ETHERNET_SNAP_HEADER*)pHeader; + + LogEthernetSNAPHeader(pEthernetSNAPHeader); + + etherType = ntohs(pEthernetSNAPHeader->type); + + if(etherType == NDIS_ETH_TYPE_IPV4 || + etherType == NDIS_ETH_TYPE_IPV6) + macHeaderSize = sizeof(ETHERNET_SNAP_HEADER); + } + } + } + + if(macHeaderSize) + { + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + if(bytesRetreated) + { + /// ... advance the offset back to the original position. + NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + macHeaderSize, + FALSE, + 0); + + bytesRetreated -= macHeaderSize; + } + else + { + /// ... advance the offset to the IP Header. + NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + macHeaderSize, + FALSE, + 0); + + bytesAdvanced += macHeaderSize; + } + + status = KrnlHlprIPHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory); + HLPR_BAIL_ON_FAILURE(status); + + if(etherType == NDIS_ETH_TYPE_IPV4) + { + IP_HEADER_V4* pIPv4Header = (IP_HEADER_V4*)pHeader; + + ipProtocol = pIPv4Header->protocol; + + ipHeaderSize = pIPv4Header->headerLength * 4; + + LogIPv4Header(pIPv4Header); + } + else if(etherType == NDIS_ETH_TYPE_IPV6) + { + IP_HEADER_V6* pIPv6Header = (IP_HEADER_V6*)pHeader; + + ipProtocol = pIPv6Header->nextHeader; + + ipHeaderSize = sizeof(IP_HEADER_V6); + + LogIPv6Header(pIPv6Header); + } + else + HLPR_BAIL; + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + if(ipProtocol) + { + /// ... advance the offset to the Transport Header. + NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + ipHeaderSize, + FALSE, + 0); + + bytesAdvanced += ipHeaderSize; + + status = KrnlHlprTransportHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory); + HLPR_BAIL_ON_FAILURE(status); + + LogTransportHeader(pHeader, + ipProtocol); + } + } + + HLPR_BAIL_LABEL: + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + if(bytesRetreated) + { + /// ... advance the offset back to the original position. + NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + bytesRetreated, + FALSE, + 0); + } + + if(bytesAdvanced) + { + /// ... retreat the offset back to the original position. + status = NdisRetreatNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + bytesAdvanced, + 0, + 0); + if(status != STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_ERROR_LEVEL, + " !!!! PerformBasicPacketExaminationAtInboundMACFrame: NdisRetreatNetBufferDataStart() [status: %#x]\n", + status); + } + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- PerformBasicPacketExaminationAtInboundMACFrame()\n"); + +#endif /// DBG + + return; +} + +/** + @private_function="PerformBasicPacketExaminationAtOutboundMACFrame" + + Purpose: Examines and logs the contents of the MAC Header and Ip and Transport Headers if + available. <br> + <br> + Notes: Applies to the following framing layers: <br> + FWPM_LAYER_OUTBOUND_MAC_FRAME_ETHERNET <br> + FWPM_LAYER_OUTBOUND_MAC_FRAME_NATIVE <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF560703.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF564527.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF562631.aspx <br> +*/ +VOID PerformBasicPacketExaminationAtOutboundMACFrame(_In_ CLASSIFY_DATA* pClassifyData) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> PerformBasicPacketExaminationAtOutboundMACFrame()\n"); + +#endif /// DBG + + NT_ASSERT(pClassifyData); + + NTSTATUS status = STATUS_SUCCESS; + FWPS_INCOMING_VALUES* pClassifyValues = (FWPS_INCOMING_VALUES*)pClassifyData->pClassifyValues; + FWPS_INCOMING_METADATA_VALUES* pMetadata = (FWPS_INCOMING_METADATA_VALUES*)pClassifyData->pMetadataValues; + UINT32 bytesAdvanced = 0; + UINT32 macHeaderSize = 0; + UINT32 ipHeaderSize = 0; + UINT16 etherType = 0; + UINT8 ipProtocol = 0; + VOID* pHeader = 0; + BOOLEAN needToFreeMemory = FALSE; + + if(FWPS_IS_L2_METADATA_FIELD_PRESENT(pMetadata, + FWPS_L2_METADATA_FIELD_ETHERNET_MAC_HEADER_SIZE)) + macHeaderSize = pMetadata->ethernetMacHeaderSize; + + /// Initial offset is at the MAC Header ... + status = KrnlHlprMACHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory, + macHeaderSize); + HLPR_BAIL_ON_FAILURE(status); + + if(pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_MAC_FRAME_ETHERNET) + { + FWP_VALUE* pDestinationAddressValue = 0; + FWP_VALUE* pSourceAddressValue = 0; + FWP_VALUE* pEtherTypeValue = 0; + FWP_VALUE* pVLANIDValue = 0; + + pSourceAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_MAC_LOCAL_ADDRESS); + HLPR_BAIL_ON_NULL_POINTER(pSourceAddressValue); + + pDestinationAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_MAC_REMOTE_ADDRESS); + HLPR_BAIL_ON_NULL_POINTER(pDestinationAddressValue); + + pEtherTypeValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_ETHER_TYPE); + HLPR_BAIL_ON_NULL_POINTER(pEtherTypeValue); + + pVLANIDValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_VLAN_ID); + HLPR_BAIL_ON_NULL_POINTER(pVLANIDValue); + + if(macHeaderSize == sizeof(ETHERNET_SNAP_HEADER)) + { + ETHERNET_SNAP_HEADER* pEthernetSNAPHeader = (ETHERNET_SNAP_HEADER*)pHeader; + + NT_ASSERT(ntohs(pEthernetSNAPHeader->type) == pEtherTypeValue->uint16); + + LogEthernetSNAPHeader(pEthernetSNAPHeader); + } + else + { + ETHERNET_II_HEADER* pEthernetIIHeader = (ETHERNET_II_HEADER*)pHeader; + + NT_ASSERT(RtlCompareMemory(pEthernetIIHeader->pDestinationAddress, + pDestinationAddressValue->byteArray6->byteArray6, + ETHERNET_ADDRESS_SIZE) == ETHERNET_ADDRESS_SIZE); + NT_ASSERT(RtlCompareMemory(pEthernetIIHeader->pSourceAddress, + pSourceAddressValue->byteArray6->byteArray6, + ETHERNET_ADDRESS_SIZE) == ETHERNET_ADDRESS_SIZE); + NT_ASSERT(ntohs(pEthernetIIHeader->type) == pEtherTypeValue->uint16); + + LogEthernetIIHeader(pEthernetIIHeader, + pVLANIDValue->type == FWP_UINT32 ? pVLANIDValue->uint32: 0); + } + + etherType = pEtherTypeValue->uint16; + } + else + { + FWP_VALUE* pNDISMediaType = 0; + + pNDISMediaType = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_NDIS_MEDIA_TYPE); + HLPR_BAIL_ON_NULL_POINTER(pNDISMediaType); + + if(pNDISMediaType->uint32 == NdisMedium802_3) + { + ETHERNET_II_HEADER* pEthernetIIHeader = (ETHERNET_II_HEADER*)pHeader; + + etherType = ntohs(pEthernetIIHeader->type); + + if(etherType == NDIS_ETH_TYPE_IPV4 || + etherType == NDIS_ETH_TYPE_ARP || + etherType == NDIS_ETH_TYPE_IPV6 || + etherType == NDIS_ETH_TYPE_802_1X || + etherType == NDIS_ETH_TYPE_802_1Q || + etherType == NDIS_ETH_TYPE_SLOW_PROTOCOL) + { + LogEthernetIIHeader(pEthernetIIHeader); + + if(etherType == NDIS_ETH_TYPE_IPV4 || + etherType == NDIS_ETH_TYPE_IPV6) + macHeaderSize = sizeof(ETHERNET_II_HEADER); + } + else + { + ETHERNET_SNAP_HEADER* pEthernetSNAPHeader = (ETHERNET_SNAP_HEADER*)pHeader; + + LogEthernetSNAPHeader(pEthernetSNAPHeader); + + etherType = ntohs(pEthernetSNAPHeader->type); + + if(etherType == NDIS_ETH_TYPE_IPV4 || + etherType == NDIS_ETH_TYPE_IPV6) + macHeaderSize = sizeof(ETHERNET_SNAP_HEADER); + } + } + } + + if(macHeaderSize) + { + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + /// ... advance the offset to the IP Header. + NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + macHeaderSize, + FALSE, + 0); + + bytesAdvanced += macHeaderSize; + + status = KrnlHlprIPHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory); + HLPR_BAIL_ON_FAILURE(status); + + if(etherType == NDIS_ETH_TYPE_IPV4) + { + IP_HEADER_V4* pIPv4Header = (IP_HEADER_V4*)pHeader; + + ipProtocol = pIPv4Header->protocol; + + ipHeaderSize = pIPv4Header->headerLength * 4; + + LogIPv4Header(pIPv4Header); + } + else if(etherType == NDIS_ETH_TYPE_IPV6) + { + IP_HEADER_V6* pIPv6Header = (IP_HEADER_V6*)pHeader; + + ipProtocol = pIPv6Header->nextHeader; + + ipHeaderSize = sizeof(IP_HEADER_V6); + + LogIPv6Header(pIPv6Header); + } + else + HLPR_BAIL; + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + if(ipProtocol) + { + /// ... advance the offset to the Transport Header. + NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + ipHeaderSize, + FALSE, + 0); + + bytesAdvanced += ipHeaderSize; + + status = KrnlHlprTransportHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory); + HLPR_BAIL_ON_FAILURE(status); + + LogTransportHeader(pHeader, + ipProtocol); + } + } + + HLPR_BAIL_LABEL: + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + if(bytesAdvanced) + { + /// ... retreat the offset back to the original position. + status = NdisRetreatNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + bytesAdvanced, + 0, + 0); + if(status != STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_ERROR_LEVEL, + " !!!! PerformBasicPacketExaminationAtOutboundMACFrame: NdisRetreatNetBufferDataStart() [status: %#x]\n", + status); + } + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- PerformBasicPacketExaminationAtOutboundMACFrame()\n"); + +#endif /// DBG + + return; +} + +/** + @private_function="PerformBasicPacketExaminationAtVSwitchTransport" + + Purpose: Examines and logs the contents of the IP Header and Transport Headers if available.<br> + <br> + Notes: Applies to the following vSwitch layers: <br> + FWPM_LAYER_INGRESS_VSWITCH_ETHERNET <br> + FWPM_LAYER_EGRESS_VSWITCH_ETHERNET <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF560703.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF564527.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF562631.aspx <br> +*/ +VOID PerformBasicPacketExaminationAtVSwitchEthernet(_In_ CLASSIFY_DATA* pClassifyData) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> PerformBasicPacketExaminationAtVSwitchEthernet()\n"); + +#endif /// DBG + + NT_ASSERT(pClassifyData); + + NTSTATUS status = STATUS_SUCCESS; + FWPS_INCOMING_VALUES* pClassifyValues = (FWPS_INCOMING_VALUES*)pClassifyData->pClassifyValues; + FWPS_INCOMING_METADATA_VALUES* pMetadata = (FWPS_INCOMING_METADATA_VALUES*)pClassifyData->pMetadataValues; + UINT32 bytesAdvanced = 0; + UINT32 macHeaderSize = 0; + UINT32 ipHeaderSize = 0; + UINT16 etherType = 0; + UINT8 ipProtocol = 0; + FWP_VALUE* pDestinationAddressValue = 0; + FWP_VALUE* pSourceAddressValue = 0; + FWP_VALUE* pEtherTypeValue = 0; + FWP_VALUE* pVLANIDValue = 0; + VOID* pHeader = 0; + BOOLEAN needToFreeMemory = FALSE; + + if(FWPS_IS_L2_METADATA_FIELD_PRESENT(pMetadata, + FWPS_L2_METADATA_FIELD_ETHERNET_MAC_HEADER_SIZE)) + macHeaderSize = pMetadata->ethernetMacHeaderSize; + + pSourceAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_MAC_SOURCE_ADDRESS); + HLPR_BAIL_ON_NULL_POINTER(pSourceAddressValue); + + pDestinationAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_MAC_DESTINATION_ADDRESS); + HLPR_BAIL_ON_NULL_POINTER(pDestinationAddressValue); + + pEtherTypeValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_ETHER_TYPE); + HLPR_BAIL_ON_NULL_POINTER(pEtherTypeValue); + + pVLANIDValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_VLAN_ID); + HLPR_BAIL_ON_NULL_POINTER(pVLANIDValue); + + /// Initial offset is at the MAC Header ... + status = KrnlHlprMACHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory, + macHeaderSize); + HLPR_BAIL_ON_FAILURE(status); + + if(macHeaderSize == sizeof(ETHERNET_SNAP_HEADER)) + { + ETHERNET_SNAP_HEADER* pEthernetSNAPHeader = (ETHERNET_SNAP_HEADER*)pHeader; + + NT_ASSERT(ntohs(pEthernetSNAPHeader->type) == pEtherTypeValue->uint16); + + LogEthernetSNAPHeader(pEthernetSNAPHeader); + } + else + { + ETHERNET_II_HEADER* pEthernetIIHeader = (ETHERNET_II_HEADER*)pHeader; + + NT_ASSERT(RtlCompareMemory(pEthernetIIHeader->pDestinationAddress, + pDestinationAddressValue->byteArray6->byteArray6, + ETHERNET_ADDRESS_SIZE) == ETHERNET_ADDRESS_SIZE); + NT_ASSERT(RtlCompareMemory(pEthernetIIHeader->pSourceAddress, + pSourceAddressValue->byteArray6->byteArray6, + ETHERNET_ADDRESS_SIZE) == ETHERNET_ADDRESS_SIZE); + NT_ASSERT(ntohs(pEthernetIIHeader->type) == pEtherTypeValue->uint16); + + LogEthernetIIHeader(pEthernetIIHeader, + pVLANIDValue->type == FWP_UINT32 ? pVLANIDValue->uint32: 0); + } + + etherType = pEtherTypeValue->uint16; + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + /// ... advance the offset to the IP Header ... + NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + macHeaderSize, + FALSE, + 0); + + bytesAdvanced += macHeaderSize; + + status = KrnlHlprIPHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory); + HLPR_BAIL_ON_FAILURE(status); + + if(etherType == NDIS_ETH_TYPE_IPV4) + { + IP_HEADER_V4* pIPv4Header = (IP_HEADER_V4*)pHeader; + + ipProtocol = pIPv4Header->protocol; + + ipHeaderSize = pIPv4Header->headerLength * 4; + + LogIPv4Header(pIPv4Header); + } + else if(etherType == NDIS_ETH_TYPE_IPV6) + { + IP_HEADER_V6* pIPv6Header = (IP_HEADER_V6*)pHeader; + + ipProtocol = pIPv6Header->nextHeader; + + ipHeaderSize = sizeof(IP_HEADER_V6); + + LogIPv6Header(pIPv6Header); + } + else + HLPR_BAIL; + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + if(ipProtocol) + { + /// ... advance the offset to the Transport Header. + NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + ipHeaderSize, + FALSE, + 0); + + bytesAdvanced += ipHeaderSize; + + status = KrnlHlprTransportHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory); + HLPR_BAIL_ON_FAILURE(status); + + LogTransportHeader(pHeader, + ipProtocol); + } + + HLPR_BAIL_LABEL: + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + if(bytesAdvanced) + { + /// ... retreat the offset back to the original position. + status = NdisRetreatNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + bytesAdvanced, + 0, + 0); + if(status != STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_ERROR_LEVEL, + " !!!! PerformBasicPacketExaminationAtVSwitchEthernet: NdisRetreatNetBufferDataStart() [status: %#x]\n", + status); + } + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- PerformBasicPacketExaminationAtVSwitchEthernet()\n"); + +#endif /// DBG + + return; +} + +/** + @private_function="PerformBasicPacketExaminationAtVSwitchTransport" + + Purpose: Examines and logs the contents of the IP Header and Transport Headers if available.<br> + <br> + Notes: Applies to the following vSwitch layers: <br> + FWPM_LAYER_INGRESS_VSWITCH_TRANSPORT_V4 <br> + FWPM_LAYER_INGRESS_VSWITCH_TRANSPORT_V6 <br> + FWPM_LAYER_EGRESS_VSWITCH_TRANSPORT_V4 <br> + FWPM_LAYER_EGRESS_VSWITCH_TRANSPORT_V6 <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF560703.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF564527.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF562631.aspx <br> +*/ +VOID PerformBasicPacketExaminationAtVSwitchTransport(_In_ CLASSIFY_DATA* pClassifyData) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> PerformBasicPacketExaminationAtVSwitchTransport()\n"); + +#endif /// DBG + + NT_ASSERT(pClassifyData); + + NTSTATUS status = STATUS_SUCCESS; + FWPS_INCOMING_VALUES* pClassifyValues = (FWPS_INCOMING_VALUES*)pClassifyData->pClassifyValues; + FWPS_INCOMING_METADATA_VALUES* pMetadata = (FWPS_INCOMING_METADATA_VALUES*)pClassifyData->pMetadataValues; + UINT32 ipHeaderSize = 0; + UINT32 bytesAdvanced = 0; + FWP_VALUE* pProtocolValue = 0; + FWP_VALUE* pSourceAddressValue = 0; + FWP_VALUE* pDestinationAddressValue = 0; + FWP_VALUE* pSourcePortValue = 0; + FWP_VALUE* pDestinationPortValue = 0; + FWP_VALUE* pICMPTypeValue = 0; + FWP_VALUE* pICMPCodeValue = 0; + VOID* pHeader = 0; + BOOLEAN needToFreeMemory = FALSE; + + pProtocolValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_PROTOCOL); + HLPR_BAIL_ON_NULL_POINTER(pProtocolValue); + + pSourceAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_SOURCE_ADDRESS); + HLPR_BAIL_ON_NULL_POINTER(pSourceAddressValue); + + pDestinationAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_DESTINATION_ADDRESS); + HLPR_BAIL_ON_NULL_POINTER(pDestinationAddressValue); + + pSourcePortValue = pICMPTypeValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_SOURCE_PORT); + HLPR_BAIL_ON_NULL_POINTER(pSourcePortValue); + + pDestinationPortValue = pICMPCodeValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_DESTINATION_PORT); + HLPR_BAIL_ON_NULL_POINTER(pDestinationPortValue); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_IP_HEADER_SIZE)) + ipHeaderSize = pMetadata->ipHeaderSize; + + /// Initial offset is at the IP Header ... + status = KrnlHlprIPHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory, + ipHeaderSize); + HLPR_BAIL_ON_FAILURE(status); + + /// Validate that what is indicated in the classify is what is present in packet's IP Header + if(KrnlHlprFwpsLayerIsIPv4(pClassifyValues->layerId)) + { + IP_HEADER_V4* pIPv4Header = (IP_HEADER_V4*)pHeader; + + NT_ASSERT(pIPv4Header->version == IPV4); + NT_ASSERT(pIPv4Header->protocol == pProtocolValue->uint8); + NT_ASSERT(ntohl(*((UINT32*)pIPv4Header->pSourceAddress)) == pSourceAddressValue->uint32); + NT_ASSERT(ntohl(*((UINT32*)pIPv4Header->pDestinationAddress)) == pDestinationAddressValue->uint32); + + LogIPv4Header(pIPv4Header); + + if(ipHeaderSize == 0) + ipHeaderSize = IPV4_HEADER_MIN_SIZE; + } + else + { + IP_HEADER_V6* pIPv6Header = (IP_HEADER_V6*)pHeader; + + NT_ASSERT(pIPv6Header->version.value == IPV6); + NT_ASSERT(pIPv6Header->nextHeader == pProtocolValue->uint8); + NT_ASSERT(RtlCompareMemory(pIPv6Header->pSourceAddress, + pSourceAddressValue->byteArray16->byteArray16, + IPV6_ADDRESS_SIZE) == IPV6_ADDRESS_SIZE); + NT_ASSERT(RtlCompareMemory(pIPv6Header->pDestinationAddress, + pDestinationAddressValue->byteArray16->byteArray16, + IPV6_ADDRESS_SIZE) == IPV6_ADDRESS_SIZE); + + LogIPv6Header(pIPv6Header); + + if(ipHeaderSize == 0) + ipHeaderSize = IPV6_HEADER_MIN_SIZE; + } + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + /// ... advance the offset to the Transport Header. + NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + ipHeaderSize, + FALSE, + 0); + + bytesAdvanced += ipHeaderSize; + + status = KrnlHlprTransportHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory); + HLPR_BAIL_ON_FAILURE(status); + + switch(pProtocolValue->uint8) + { + case ICMPV4: + { + ICMP_HEADER_V4* pICMPv4Header = (ICMP_HEADER_V4*)pHeader; + + NT_ASSERT(pICMPv4Header->type == pICMPTypeValue->uint16); + NT_ASSERT(pICMPv4Header->code == pICMPCodeValue->uint16); + + LogICMPv4Header(pICMPv4Header); + + break; + } + case ICMPV6: + { + ICMP_HEADER_V6* pICMPv6Header = (ICMP_HEADER_V6*)pHeader; + + NT_ASSERT(pICMPv6Header->type == pICMPTypeValue->uint16); + NT_ASSERT(pICMPv6Header->code == pICMPCodeValue->uint16); + + LogICMPv6Header(pICMPv6Header); + + break; + } + case TCP: + { + TCP_HEADER* pTCPHeader = (TCP_HEADER*)pHeader; + + NT_ASSERT(ntohs(pTCPHeader->sourcePort) == pSourcePortValue->uint16 ); + NT_ASSERT(ntohs(pTCPHeader->destinationPort) == pDestinationPortValue->uint16); + + LogTCPHeader(pTCPHeader); + + break; + } + case UDP: + { + UDP_HEADER* pUDPHeader = (UDP_HEADER*)pHeader; + + NT_ASSERT(ntohs(pUDPHeader->sourcePort) == pSourcePortValue->uint16 ); + NT_ASSERT(ntohs(pUDPHeader->destinationPort) == pDestinationPortValue->uint16); + + LogUDPHeader(pUDPHeader); + + break; + } + } + + HLPR_BAIL_LABEL: + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + if(bytesAdvanced) + { + /// ... retreat the offset to the original position. + status = NdisRetreatNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + bytesAdvanced, + 0, + 0); + if(status != STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_ERROR_LEVEL, + " !!!! PerformBasicPacketExaminationAtInboundMACFrame: NdisRetreatNetBufferDataStart() [status: %#x]\n", + status); + } + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- PerformBasicPacketExaminationAtVSwitchTransport()\n"); + +#endif /// DBG + + return; +} + +#endif /// (NTDDI_VERSION >= NTDDI_WIN8) + +/** + @private_function="PerformBasicPacketExaminationAtInboundNetwork" + + Purpose: Examines and logs the contents of the IP Header and Transport Header if available. <br> + <br> + Notes: Applies to the following network layers: <br> + FWPM_LAYER_INBOUND_IPPACKET_V{4/6} <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF560703.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF564527.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF562631.aspx <br> +*/ +VOID PerformBasicPacketExaminationAtInboundNetwork(_In_ CLASSIFY_DATA* pClassifyData) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> PerformBasicPacketExaminationAtInboundNetwork()\n"); + +#endif /// DBG + + NT_ASSERT(pClassifyData); + + NTSTATUS status = STATUS_SUCCESS; + FWPS_INCOMING_VALUES* pClassifyValues = (FWPS_INCOMING_VALUES*)pClassifyData->pClassifyValues; + FWPS_INCOMING_METADATA_VALUES* pMetadata = (FWPS_INCOMING_METADATA_VALUES*)pClassifyData->pMetadataValues; + UINT32 ipHeaderSize = 0; + UINT32 bytesRetreated = 0; + FWP_VALUE* pSourceAddressValue = 0; + FWP_VALUE* pDestinationAddressValue = 0; + VOID* pHeader = 0; + BOOLEAN needToFreeMemory = FALSE; + UINT8 protocol = IPPROTO_RAW; + + pSourceAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_REMOTE_ADDRESS); + HLPR_BAIL_ON_NULL_POINTER(pSourceAddressValue); + + pDestinationAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_LOCAL_ADDRESS); + HLPR_BAIL_ON_NULL_POINTER(pDestinationAddressValue); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_IP_HEADER_SIZE)) + ipHeaderSize = pMetadata->ipHeaderSize; + + /// Initial offset is at the Transport Header, so retreat the size of the IP Header ... + status = NdisRetreatNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + ipHeaderSize, + 0, + 0); + if(status != STATUS_SUCCESS) + { + bytesRetreated = 0; + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_ERROR_LEVEL, + " !!!! PerformBasicPacketExaminationAtInboundNetwork: NdisRetreatNetBufferDataStart() [status: %#x]\n", + status); + + HLPR_BAIL; + } + else + bytesRetreated = ipHeaderSize; + + status = KrnlHlprIPHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory, + ipHeaderSize); + HLPR_BAIL_ON_FAILURE(status); + + /// Validate that what is indicated in the classify is what is present in packet's IP Header + if(KrnlHlprFwpsLayerIsIPv4(pClassifyValues->layerId)) + { + IP_HEADER_V4* pIPv4Header = (IP_HEADER_V4*)pHeader; + + NT_ASSERT(pIPv4Header->version == IPV4); + NT_ASSERT(((UINT32)(pIPv4Header->headerLength * 4)) == ipHeaderSize); + NT_ASSERT(ntohl(*((UINT32*)pIPv4Header->pSourceAddress)) == pSourceAddressValue->uint32); + NT_ASSERT(ntohl(*((UINT32*)pIPv4Header->pDestinationAddress)) == pDestinationAddressValue->uint32); + + LogIPv4Header(pIPv4Header); + + protocol = pIPv4Header->protocol; + } + else + { + IP_HEADER_V6* pIPv6Header = (IP_HEADER_V6*)pHeader; + + NT_ASSERT(sizeof(IP_HEADER_V6) == ipHeaderSize); + NT_ASSERT(pIPv6Header->version.value == IPV6); + NT_ASSERT(RtlCompareMemory(pIPv6Header->pSourceAddress, + pSourceAddressValue->byteArray16->byteArray16, + IPV6_ADDRESS_SIZE) == IPV6_ADDRESS_SIZE); + NT_ASSERT(RtlCompareMemory(pIPv6Header->pDestinationAddress, + pDestinationAddressValue->byteArray16->byteArray16, + IPV6_ADDRESS_SIZE) == IPV6_ADDRESS_SIZE); + + LogIPv6Header(pIPv6Header); + + protocol = pIPv6Header->nextHeader; + } + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + if(bytesRetreated) + { + /// ... and advance the offset back to the original position. + NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + bytesRetreated, + FALSE, + 0); + + bytesRetreated -= ipHeaderSize; + } + + status = KrnlHlprTransportHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory); + HLPR_BAIL_ON_FAILURE(status); + + LogTransportHeader(pHeader, + protocol); + + HLPR_BAIL_LABEL: + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + if(bytesRetreated) + { + /// ... and advance the offset back to the original position. + NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + bytesRetreated, + FALSE, + 0); + } + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- PerformBasicPacketExaminationAtInboundNetwork()\n"); + +#endif /// DBG + + return; +} + +/** + @private_function="PerformBasicPacketExaminationAtOutboundNetwork" + + Purpose: Examines and logs the contents of the IP Header and Transport Header if available. <br> + <br> + Notes: Applies to the following network layers: <br> + FWPM_LAYER_OUTBOUND_IPPACKET_V{4/6} <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF560703.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF564527.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF562631.aspx <br> +*/ +VOID PerformBasicPacketExaminationAtOutboundNetwork(_In_ CLASSIFY_DATA* pClassifyData) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> PerformBasicPacketExaminationAtOutboundNetwork()\n"); + +#endif /// DBG + + NT_ASSERT(pClassifyData); + + NTSTATUS status = STATUS_SUCCESS; + FWPS_INCOMING_VALUES* pClassifyValues = (FWPS_INCOMING_VALUES*)pClassifyData->pClassifyValues; + FWPS_INCOMING_METADATA_VALUES* pMetadata = (FWPS_INCOMING_METADATA_VALUES*)pClassifyData->pMetadataValues; + UINT32 ipHeaderSize = 0; + UINT32 bytesAdvanced = 0; + FWP_VALUE* pSourceAddressValue = 0; + FWP_VALUE* pDestinationAddressValue = 0; + VOID* pHeader = 0; + BOOLEAN needToFreeMemory = FALSE; + UINT8 protocol = IPPROTO_RAW; + + pSourceAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_LOCAL_ADDRESS); + HLPR_BAIL_ON_NULL_POINTER(pSourceAddressValue); + + pDestinationAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_REMOTE_ADDRESS); + HLPR_BAIL_ON_NULL_POINTER(pDestinationAddressValue); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_IP_HEADER_SIZE)) + ipHeaderSize = pMetadata->ipHeaderSize; + + /// Initial offset is at the IP Header ... + status = KrnlHlprIPHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory, + ipHeaderSize); + HLPR_BAIL_ON_FAILURE(status); + + /// Validate that what is indicated in the classify is what is present in packet's IP Header + if(KrnlHlprFwpsLayerIsIPv4(pClassifyValues->layerId)) + { + IP_HEADER_V4* pIPv4Header = (IP_HEADER_V4*)pHeader; + + NT_ASSERT(pIPv4Header->version == IPV4); + NT_ASSERT(((UINT32)(pIPv4Header->headerLength * 4)) == ipHeaderSize); + NT_ASSERT(ntohl(*((UINT32*)pIPv4Header->pSourceAddress)) == pSourceAddressValue->uint32); + NT_ASSERT(ntohl(*((UINT32*)pIPv4Header->pDestinationAddress)) == pDestinationAddressValue->uint32); + + LogIPv4Header(pIPv4Header); + + protocol = pIPv4Header->protocol; + } + else + { + IP_HEADER_V6* pIPv6Header = (IP_HEADER_V6*)pHeader; + + NT_ASSERT(sizeof(IP_HEADER_V6) == ipHeaderSize); + NT_ASSERT(pIPv6Header->version.value == IPV6); + NT_ASSERT(RtlCompareMemory(pIPv6Header->pSourceAddress, + pSourceAddressValue->byteArray16->byteArray16, + IPV6_ADDRESS_SIZE) == IPV6_ADDRESS_SIZE); + NT_ASSERT(RtlCompareMemory(pIPv6Header->pDestinationAddress, + pDestinationAddressValue->byteArray16->byteArray16, + IPV6_ADDRESS_SIZE) == IPV6_ADDRESS_SIZE); + + LogIPv6Header(pIPv6Header); + + protocol = pIPv6Header->nextHeader; + } + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + /// ... advance the offset to the Transport Header ... + NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + ipHeaderSize, + FALSE, + 0); + + bytesAdvanced = ipHeaderSize; + + status = KrnlHlprTransportHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory); + HLPR_BAIL_ON_FAILURE(status); + + LogTransportHeader(pHeader, + protocol); + + HLPR_BAIL_LABEL: + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + if(bytesAdvanced) + { + /// ... and retreat the offset back to the original position. + status = NdisRetreatNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + bytesAdvanced, + 0, + 0); + if(status != STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_ERROR_LEVEL, + " !!!! PerformBasicPacketExaminationAtOutboundNetwork : NdisRetreatNetBufferDataStart() [status: %#x]\n", + status); + } + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- PerformBasicPacketExaminationAtOutboundNetwork()\n"); + +#endif /// DBG + + return; +} + +/** + @private_function="PerformBasicPacketExaminationAtForward" + + Purpose: Examines and logs the contents of the IP Header and Transport Header if available. <br> + <br> + Notes: Applies to the following forwarding layers: <br> + FWPM_LAYER_IPFORWARD_V{4/6} <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF560703.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF564527.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF562631.aspx <br> +*/ +VOID PerformBasicPacketExaminationAtForward(_In_ CLASSIFY_DATA* pClassifyData) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> PerformBasicPacketExaminationAtForward()\n"); + +#endif /// DBG + + NT_ASSERT(pClassifyData); + + NTSTATUS status = STATUS_SUCCESS; + FWPS_INCOMING_VALUES* pClassifyValues = (FWPS_INCOMING_VALUES*)pClassifyData->pClassifyValues; + FWPS_INCOMING_METADATA_VALUES* pMetadata = (FWPS_INCOMING_METADATA_VALUES*)pClassifyData->pMetadataValues; + UINT32 ipHeaderSize = 0; + UINT32 bytesAdvanced = 0; + FWP_VALUE* pSourceAddressValue = 0; + FWP_VALUE* pDestinationAddressValue = 0; + VOID* pHeader = 0; + BOOLEAN needToFreeMemory = FALSE; + UINT8 protocol = IPPROTO_RAW; + + pSourceAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_SOURCE_ADDRESS); + HLPR_BAIL_ON_NULL_POINTER(pSourceAddressValue); + + pDestinationAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_DESTINATION_ADDRESS); + HLPR_BAIL_ON_NULL_POINTER(pDestinationAddressValue); + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_IP_HEADER_SIZE)) + ipHeaderSize = pMetadata->ipHeaderSize; + + /// Initial offset is at the IP Header ... + status = KrnlHlprIPHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory, + ipHeaderSize); + HLPR_BAIL_ON_FAILURE(status); + + /// Validate that what is indicated in the classify is what is present in packet's IP Header + if(KrnlHlprFwpsLayerIsIPv4(pClassifyValues->layerId)) + { + IP_HEADER_V4* pIPv4Header = (IP_HEADER_V4*)pHeader; + + NT_ASSERT(pIPv4Header->version == IPV4); + NT_ASSERT(ntohl(*((UINT32*)pIPv4Header->pSourceAddress)) == pSourceAddressValue->uint32); + NT_ASSERT(ntohl(*((UINT32*)pIPv4Header->pDestinationAddress)) == pDestinationAddressValue->uint32); + + LogIPv4Header(pIPv4Header); + + protocol = pIPv4Header->protocol; + } + else + { + IP_HEADER_V6* pIPv6Header = (IP_HEADER_V6*)pHeader; + + NT_ASSERT(pIPv6Header->version.value == IPV6); + NT_ASSERT(RtlCompareMemory(pIPv6Header->pSourceAddress, + pSourceAddressValue->byteArray16->byteArray16, + IPV6_ADDRESS_SIZE) == IPV6_ADDRESS_SIZE); + NT_ASSERT(RtlCompareMemory(pIPv6Header->pDestinationAddress, + pDestinationAddressValue->byteArray16->byteArray16, + IPV6_ADDRESS_SIZE) == IPV6_ADDRESS_SIZE); + + LogIPv6Header(pIPv6Header); + + protocol = pIPv6Header->nextHeader; + } + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + /// ... advance the offset to the Transport Header ... + NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + ipHeaderSize, + FALSE, + 0); + + bytesAdvanced = ipHeaderSize; + + status = KrnlHlprTransportHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory); + HLPR_BAIL_ON_FAILURE(status); + + LogTransportHeader(pHeader, + protocol); + + HLPR_BAIL_LABEL: + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + if(bytesAdvanced) + { + /// ... and retreat the offset back to the original position. + status = NdisRetreatNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + bytesAdvanced, + 0, + 0); + if(status != STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_ERROR_LEVEL, + " !!!! PerformBasicPacketExaminationAtForward : NdisRetreatNetBufferDataStart() [status: %#x]\n", + status); + } + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- PerformBasicPacketExaminationAtForward()\n"); + +#endif /// DBG + + return; +} + +/** + @private_function="PerformBasicPacketExaminationAtInboundTransport" + + Purpose: Examines and logs the contents of the IP Header and Transport Header if available. <br> + <br> + Notes: Applies to the following transport layers: <br> + FWPM_LAYER_INBOUND_TRANSPORT_V{4/6} <br> + FWPM_LAYER_INBOUND_ICMP_ERROR_V{4/6} <br> + FWPM_LAYER_DATAGRAM_DATA_V{4/6} (Inbound only) <br> + FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V{4/6} (Inbound only) <br> + FWPM_LAYER_ALE_AUTH_CONNECT_V{4/6} (Inbound, reauthorization only) <br> + FWPM_LAYER_ALE_FLOW_ESTABLISHED_V{4/6} (Inbound, non-TCP only) <br> + FWPM_LAYER_STREAM_PACKET_V{4/6} (Inbound only) <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF560703.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF564527.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF562631.aspx <br> +*/ +VOID PerformBasicPacketExaminationAtInboundTransport(_In_ CLASSIFY_DATA* pClassifyData) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> PerformBasicPacketExaminationAtInboundTransport()\n"); + +#endif /// DBG + + NT_ASSERT(pClassifyData); + + NTSTATUS status = STATUS_SUCCESS; + FWPS_INCOMING_VALUES* pClassifyValues = (FWPS_INCOMING_VALUES*)pClassifyData->pClassifyValues; + FWPS_INCOMING_METADATA_VALUES* pMetadata = (FWPS_INCOMING_METADATA_VALUES*)pClassifyData->pMetadataValues; + UINT32 ipHeaderSize = 0; + UINT32 transportHeaderSize = 0; + UINT32 bytesRetreated = 0; + UINT8 protocol = IPPROTO_RAW; + FWP_VALUE* pProtocolValue = 0; + FWP_VALUE* pSourceAddressValue = 0; + FWP_VALUE* pDestinationAddressValue = 0; + FWP_VALUE* pSourcePortValue = 0; + FWP_VALUE* pDestinationPortValue = 0; + FWP_VALUE* pICMPTypeValue = 0; + FWP_VALUE* pICMPCodeValue = 0; + VOID* pHeader = 0; + BOOLEAN needToFreeMemory = FALSE; + + if(pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V4) + protocol = ICMPV4; + else if(pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V6) + protocol = ICMPV6; + +#if(NTDDI_VERSION >= NTDDI_WIN7) + + else if(pClassifyValues->layerId == FWPS_LAYER_STREAM_PACKET_V4 || + pClassifyValues->layerId == FWPS_LAYER_STREAM_PACKET_V6) + protocol = TCP; + +#endif /// (NTDDI_VERSION >= NTDDI_WIN7) + + else + { + pProtocolValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_PROTOCOL); + HLPR_BAIL_ON_NULL_POINTER(pProtocolValue); + + protocol = pProtocolValue->uint8; + } + + pSourceAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_REMOTE_ADDRESS); + HLPR_BAIL_ON_NULL_POINTER(pSourceAddressValue); + + pDestinationAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_LOCAL_ADDRESS); + HLPR_BAIL_ON_NULL_POINTER(pDestinationAddressValue); + + pSourcePortValue = pICMPCodeValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_REMOTE_PORT); + HLPR_BAIL_ON_NULL_POINTER(pSourcePortValue); + + pDestinationPortValue = pICMPTypeValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_LOCAL_PORT); + HLPR_BAIL_ON_NULL_POINTER(pDestinationPortValue); + + if(pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V4) + { + ipHeaderSize = IPV4_HEADER_MIN_SIZE; + + if(protocol == ICMPV4) + transportHeaderSize = ICMP_HEADER_MIN_SIZE; + else if(protocol == TCP) + transportHeaderSize = TCP_HEADER_MIN_SIZE; + else if(protocol == UDP) + transportHeaderSize = UDP_HEADER_MIN_SIZE; + } + else if(pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V6) + { + ipHeaderSize = IPV6_HEADER_MIN_SIZE; + + if(protocol == ICMPV6) + transportHeaderSize = ICMP_HEADER_MIN_SIZE; + else if(protocol == TCP) + transportHeaderSize = TCP_HEADER_MIN_SIZE; + else if(protocol == UDP) + transportHeaderSize = UDP_HEADER_MIN_SIZE; + } + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_IP_HEADER_SIZE) && + pMetadata->ipHeaderSize) + ipHeaderSize = pMetadata->ipHeaderSize; + + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_TRANSPORT_HEADER_SIZE) && + pMetadata->transportHeaderSize) + transportHeaderSize = pMetadata->transportHeaderSize; + + if((protocol == ICMPV4 || + protocol == ICMPV6) && + (pClassifyValues->layerId != FWPS_LAYER_INBOUND_ICMP_ERROR_V4 && + pClassifyValues->layerId != FWPS_LAYER_INBOUND_ICMP_ERROR_V6 && + pClassifyValues->layerId != FWPS_LAYER_DATAGRAM_DATA_V4 && + pClassifyValues->layerId != FWPS_LAYER_DATAGRAM_DATA_V6)) + { + /// Initial offset is at the ICMP Header, so retreat the size of the IP Header ... + status = NdisRetreatNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + ipHeaderSize, + 0, + 0); + } + else + { + /// Initial offset is at the Data, so retreat the size of the IP and Transport Headers ... + status = NdisRetreatNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + ipHeaderSize + transportHeaderSize, + 0, + 0); + } + + if(status != STATUS_SUCCESS) + { + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_ERROR_LEVEL, + " !!!! PerformBasicPacketExaminationAtInboundTransport: NdisRetreatNetBufferDataStart() [status: %#x]\n", + status); + + HLPR_BAIL; + } + else + { + if((protocol == ICMPV4 || + protocol == ICMPV6) && + (pClassifyValues->layerId != FWPS_LAYER_INBOUND_ICMP_ERROR_V4 && + pClassifyValues->layerId != FWPS_LAYER_INBOUND_ICMP_ERROR_V6 && + pClassifyValues->layerId != FWPS_LAYER_DATAGRAM_DATA_V4 && + pClassifyValues->layerId != FWPS_LAYER_DATAGRAM_DATA_V6)) + bytesRetreated = ipHeaderSize; + else + bytesRetreated = ipHeaderSize + transportHeaderSize; + } + + status = KrnlHlprIPHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory, + ipHeaderSize); + HLPR_BAIL_ON_FAILURE(status); + + /// Validate that what is indicated in the classify is what is present in packet's IP Header + if(KrnlHlprFwpsLayerIsIPv4(pClassifyValues->layerId)) + { + IP_HEADER_V4* pIPv4Header = (IP_HEADER_V4*)pHeader; + + NT_ASSERT(pIPv4Header->version == IPV4); + NT_ASSERT(((UINT32)(pIPv4Header->headerLength * 4)) == ipHeaderSize); + NT_ASSERT(pIPv4Header->protocol == protocol); + NT_ASSERT(ntohl(*((UINT32*)pIPv4Header->pSourceAddress)) == pSourceAddressValue->uint32); + NT_ASSERT(ntohl(*((UINT32*)pIPv4Header->pDestinationAddress)) == pDestinationAddressValue->uint32); + + if(pIPv4Header->version == IPV4 && + ipHeaderSize >= IPV4_HEADER_MIN_SIZE) + LogIPv4Header(pIPv4Header); + } + else + { + IP_HEADER_V6* pIPv6Header = (IP_HEADER_V6*)pHeader; + + NT_ASSERT(sizeof(IP_HEADER_V6) == ipHeaderSize); + NT_ASSERT(pIPv6Header->version.value == IPV6); + NT_ASSERT(pIPv6Header->nextHeader == protocol); + NT_ASSERT(RtlCompareMemory(pIPv6Header->pSourceAddress, + pSourceAddressValue->byteArray16->byteArray16, + IPV6_ADDRESS_SIZE) == IPV6_ADDRESS_SIZE); + NT_ASSERT(RtlCompareMemory(pIPv6Header->pDestinationAddress, + pDestinationAddressValue->byteArray16->byteArray16, + IPV6_ADDRESS_SIZE) == IPV6_ADDRESS_SIZE); + + if(pIPv6Header->version.value == IPV6 && + ipHeaderSize >= IPV6_HEADER_MIN_SIZE) + LogIPv6Header(pIPv6Header); + } + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + if(bytesRetreated) + { + /// and advance the offset to the Transport Header. + NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + ipHeaderSize, + FALSE, + 0); + + bytesRetreated -= ipHeaderSize; + } + + status = KrnlHlprTransportHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory, + transportHeaderSize); + HLPR_BAIL_ON_FAILURE(status); + + switch(protocol) + { + case ICMPV4: + { + ICMP_HEADER_V4* pICMPv4Header = (ICMP_HEADER_V4*)pHeader; + + NT_ASSERT(pICMPv4Header->type == pICMPTypeValue->uint16); + NT_ASSERT(pICMPv4Header->code == pICMPCodeValue->uint16); + + if(transportHeaderSize >= ICMP_HEADER_MIN_SIZE) + LogICMPv4Header(pICMPv4Header); + + break; + } + case ICMPV6: + { + ICMP_HEADER_V6* pICMPv6Header = (ICMP_HEADER_V6*)pHeader; + + NT_ASSERT(pICMPv6Header->type == pICMPTypeValue->uint16); + NT_ASSERT(pICMPv6Header->code == pICMPCodeValue->uint16); + + if(transportHeaderSize >= ICMP_HEADER_MIN_SIZE) + LogICMPv6Header(pICMPv6Header); + + break; + } + case TCP: + { + TCP_HEADER* pTCPHeader = (TCP_HEADER*)pHeader; + + NT_ASSERT(ntohs(pTCPHeader->sourcePort) == pSourcePortValue->uint16 ); + NT_ASSERT(ntohs(pTCPHeader->destinationPort) == pDestinationPortValue->uint16); + + if(transportHeaderSize >= TCP_HEADER_MIN_SIZE) + LogTCPHeader(pTCPHeader); + + break; + } + case UDP: + { + UDP_HEADER* pUDPHeader = (UDP_HEADER*)pHeader; + + NT_ASSERT(ntohs(pUDPHeader->sourcePort) == pSourcePortValue->uint16 ); + NT_ASSERT(ntohs(pUDPHeader->destinationPort) == pDestinationPortValue->uint16); + + if(transportHeaderSize >= UDP_HEADER_MIN_SIZE) + LogUDPHeader(pUDPHeader); + + break; + } + } + + HLPR_BAIL_LABEL: + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + + if(bytesRetreated) + { + /// ... and advance the offset back to the original position. + NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket), + bytesRetreated, + FALSE, + 0); + } + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- PerformBasicPacketExaminationAtInboundTransport()\n"); + +#endif /// DBG + + return; +} + +/** + @private_function="PerformBasicPacketExaminationAtOutboundTransport" + + Purpose: Examines and logs the contents of the IP Header and Transport Header if available. <br> + <br> + Notes: Applies to the following transport layers: <br> + FWPM_LAYER_OUTBOUND_TRANSPORT_V{4/6} <br> + FWPM_LAYER_OUTBOUND_ICMP_ERROR_V{4/6} <br> + FWPM_LAYER_DATAGRAM_DATA_V{4/6} (Outbound only) <br> + FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V{4/6} (Outbound only) <br> + FWPM_LAYER_ALE_AUTH_CONNECT_V{4/6} (Outbound reauthorization only) <br> + FWPM_LAYER_ALE_FLOW_ESTABLISHED_V{4/6} (Outbound, non-TCP only) <br> + FWPM_LAYER_STREAM_PACKET_V{4/6} (Outbound only) <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF560703.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF564527.aspx <br> + HTTP://MSDN.Microsoft.com/En-US/Library/FF562631.aspx <br> +*/ +VOID PerformBasicPacketExaminationAtOutboundTransport(_In_ CLASSIFY_DATA* pClassifyData) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> PerformBasicPacketExaminationAtOutboundTransport()\n"); + +#endif /// DBG + + NT_ASSERT(pClassifyData); + + NTSTATUS status = STATUS_SUCCESS; + FWPS_INCOMING_VALUES* pClassifyValues = (FWPS_INCOMING_VALUES*)pClassifyData->pClassifyValues; + UINT8 protocol = IPPROTO_RAW; + FWP_VALUE* pProtocolValue = 0; + FWP_VALUE* pSourcePortValue = 0; + FWP_VALUE* pDestinationPortValue = 0; + FWP_VALUE* pICMPTypeValue = 0; + FWP_VALUE* pICMPCodeValue = 0; + VOID* pHeader = 0; + BOOLEAN needToFreeMemory = FALSE; + + if(pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V4) + protocol = ICMPV4; + else if(pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V6) + protocol = ICMPV6; + +#if(NTDDI_VERSION >= NTDDI_WIN7) + + else if(pClassifyValues->layerId == FWPS_LAYER_STREAM_PACKET_V4 || + pClassifyValues->layerId == FWPS_LAYER_STREAM_PACKET_V6) + protocol = TCP; + +#endif /// (NTDDI_VERSION >= NTDDI_WIN7) + + else + { + pProtocolValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_PROTOCOL); + HLPR_BAIL_ON_NULL_POINTER(pProtocolValue); + + protocol = pProtocolValue->uint8; + } + + pSourcePortValue = pICMPTypeValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_LOCAL_PORT); + HLPR_BAIL_ON_NULL_POINTER(pSourcePortValue); + + pDestinationPortValue = pICMPCodeValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_IP_REMOTE_PORT); + HLPR_BAIL_ON_NULL_POINTER(pDestinationPortValue); + + /// Initial offset is at the Transport Header ... + status = KrnlHlprTransportHeaderGet((NET_BUFFER_LIST*)pClassifyData->pPacket, + &pHeader, + &needToFreeMemory); + HLPR_BAIL_ON_FAILURE(status); + + switch(protocol) + { + case ICMPV4: + { + ICMP_HEADER_V4* pICMPv4Header = (ICMP_HEADER_V4*)pHeader; + + NT_ASSERT(pICMPv4Header->type == pICMPTypeValue->uint16); + NT_ASSERT(pICMPv4Header->code == pICMPCodeValue->uint16); + + LogICMPv4Header(pICMPv4Header); + + break; + } + case ICMPV6: + { + ICMP_HEADER_V6* pICMPv6Header = (ICMP_HEADER_V6*)pHeader; + + NT_ASSERT(pICMPv6Header->type == pICMPTypeValue->uint16); + NT_ASSERT(pICMPv6Header->code == pICMPCodeValue->uint16); + + LogICMPv6Header(pICMPv6Header); + + break; + } + case TCP: + { + TCP_HEADER* pTCPHeader = (TCP_HEADER*)pHeader; + + NT_ASSERT(ntohs(pTCPHeader->sourcePort) == pSourcePortValue->uint16); + NT_ASSERT(ntohs(pTCPHeader->destinationPort) == pDestinationPortValue->uint16); + + LogTCPHeader(pTCPHeader); + + break; + } + case UDP: + { + UDP_HEADER* pUDPHeader = (UDP_HEADER*)pHeader; + + NT_ASSERT(ntohs(pUDPHeader->sourcePort) == pSourcePortValue->uint16); + NT_ASSERT(ntohs(pUDPHeader->destinationPort) == pDestinationPortValue->uint16); + + LogUDPHeader(pUDPHeader); + + break; + } + } + + HLPR_BAIL_LABEL: + + if(needToFreeMemory) + { + HLPR_DELETE_ARRAY(pHeader, + WFPSAMPLER_SYSLIB_TAG); + + needToFreeMemory = FALSE; + } + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- PerformBasicPacketExaminationAtOutboundTransport()\n"); + +#endif /// DBG + + return; +} + +/** + @private_function="PerformBasicPacketExaminationAtOutboundTransport" + + Purpose: Logs the Discard reason. <br> + <br> + Notes: Applies to the following discard layers: <br> + FWPM_LAYER_INBOUND_IPPACKET_V{4/6}_DISCARD <br> + FWPM_LAYER_OUTBOUND_IPPACKET_V{4/6}_DISCARD <br> + FWPM_LAYER_IPFORWARD_V{4/6}_DISCARD <br> + FWPM_LAYER_INBOUND_TRANSPORT_V{4/6}_DISCARD <br> + FWPM_LAYER_OUTBOUND_TRANSPORT_V{4/6}_DISCARD <br> + FWPM_LAYER_STREAM_V{4/6}_DISCARD <br> + FWPM_LAYER_DATAGRAM_DATA_V{4/6} <br> + FWPM_LAYER_INBOUND_ICMP_ERROR_V{4/6}_DISCARD <br> + FWPM_LAYER_OUTBOUND_ICMP_ERROR_V{4/6}_DISCARD <br> + FWPM_LAYER_ALE_RESOURCE_ASSIGNMENT_V{4/6}_DISCARD <br> + FWPM_LAYER_ALE_AUTH_LISTEN_V{4/6}_DISCARD <br> + FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V{4/6}_DISCARD <br> + FWPM_LAYER_ALE_AUTH_CONNECT_V{4/6}_DISCARD <br> + FWPM_LAYER_ALE_FLOW_ESTABLISHED_V{4/6}_DISCARD <br> + <br> + MSDN_Ref: <br> +*/ +VOID PerformBasicPacketExaminationAtDiscard(_In_ CLASSIFY_DATA* pClassifyData) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> PerformBasicPacketExaminationAtDiscard()\n"); + +#endif /// DBG + + NT_ASSERT(pClassifyData); + NT_ASSERT(pClassifyData->pClassifyValues); + NT_ASSERT(pClassifyData->pMetadataValues); + NT_ASSERT(pClassifyData->pMetadataValues->currentMetadataValues & FWPS_METADATA_FIELD_DISCARD_REASON); + + NTSTATUS status = STATUS_SUCCESS; + UINT32 discardModule = FWPS_DISCARD_MODULE_MAX; + UINT32 discardReason = IpDiscardMax; + UINT64 filterID = 0; + PSTR pDiscardModule = "UNKNOWN"; + PSTR pDiscardReason = "UNKNOWN"; + PSTR pString = 0; + + if(FWPS_IS_METADATA_FIELD_PRESENT(pClassifyData->pMetadataValues, + FWPS_METADATA_FIELD_DISCARD_REASON)) + { + discardModule = pClassifyData->pMetadataValues->discardMetadata.discardModule; + + discardReason = pClassifyData->pMetadataValues->discardMetadata.discardReason; + + filterID = pClassifyData->pMetadataValues->discardMetadata.filterId; + } + + switch(discardModule) + { + case FWPS_DISCARD_MODULE_NETWORK: + { + pDiscardModule = "NETWORK"; + + switch(discardReason) + { + case IpDiscardBadSourceAddress: + { + pDiscardReason = "Bad Source Address"; + + break; + } + case IpDiscardNotLocallyDestined: + { + pDiscardReason = "Not Locally Destined"; + + break; + } + case IpDiscardProtocolUnreachable: + { + pDiscardReason = "Unreachable Protocol"; + + break; + } + case IpDiscardPortUnreachable: + { + pDiscardReason = "UnreachablePort"; + + break; + } + case IpDiscardBadLength: + { + pDiscardReason = "Bad Length"; + + break; + } + case IpDiscardMalformedHeader: + { + pDiscardReason = "Malformed Header"; + + break; + } + case IpDiscardNoRoute: + { + pDiscardReason = "No Route"; + + break; + } + case IpDiscardBeyondScope: + { + pDiscardReason = "Beyond Scope"; + + break; + } + case IpDiscardInspectionDrop: + { + pDiscardReason = "Inspection Drop"; + + break; + } + case IpDiscardTooManyDecapsulations: + { + pDiscardReason = "Too Many Decapsulations"; + + break; + } + case IpDiscardAdministrativelyProhibited: + { + pDiscardReason = "Administratively Prohibited"; + + break; + } + case IpDiscardHopLimitExceeded: + { + pDiscardReason = "Hop Limit Exceeded"; + + break; + } + case IpDiscardAddressUnreachable: + { + pDiscardReason = "Unreachable Address"; + + break; + } + case IpDiscardRscPacket: + { + pDiscardReason = "RSC Packet"; + + break; + } + case IpDiscardArbitrationUnhandled: + { + pDiscardReason = "Unhandled Arbitration"; + + break; + } + case IpDiscardInspectionAbsorb: + { + pDiscardReason = "Inspection Absorb"; + + break; + } + case IpDiscardDontFragmentMtuExceeded: + { + pDiscardReason = "Don't Fragment / MTU Exceeded"; + + break; + } + case IpDiscardBufferLengthExceeded: + { + pDiscardReason = "Buffer Length Exceeded"; + + break; + } + case IpDiscardAddressResolutionTimeout: + { + pDiscardReason = "Address Resolution Timeout"; + + break; + } + case IpDiscardAddressResolutionFailure: + { + pDiscardReason = "Address Resolution Failure"; + + break; + } + case IpDiscardIpsecFailure: + { + pDiscardReason = "IPsec Failure"; + + break; + } + case IpDiscardExtensionHeadersFailure: + { + pDiscardReason = "Extension Headers Failure"; + + break; + } + case IpDiscardIPSNPIDrop: + { + pDiscardReason = "IPSNPI Drop"; + + break; + } + } + + break; + } + case FWPS_DISCARD_MODULE_TRANSPORT: + { + pDiscardModule = "TRANSPORT"; + + switch(discardReason) + { + case InetDiscardSourceUnspecified: + { + pDiscardReason = "Unspecified Source"; + + break; + } + case InetDiscardDestinationMulticast: + { + pDiscardReason = "Multicast Destination"; + + break; + } + case InetDiscardHeaderInvalid: + { + pDiscardReason = "Invalid Header"; + + break; + } + case InetDiscardChecksumInvalid: + { + pDiscardReason = "Invalid Checksum"; + + break; + } + case InetDiscardEndpointNotFound: + { + pDiscardReason = "Endpoint Not Found"; + + break; + } + case InetDiscardConnectedPath: + { + pDiscardReason = "Connected Path"; + + break; + } + case InetDiscardSessionState: + { + pDiscardReason = "Session State"; + + break; + } + case InetDiscardReceiveInspection: + { + pDiscardReason = "Receive Inspection"; + + break; + } + } + + break; + } + case FWPS_DISCARD_MODULE_GENERAL: + { + pDiscardModule = "GENERAL"; + + switch(discardReason) + { + case FWPS_DISCARD_FIREWALL_POLICY: + { + pDiscardReason = "Firewall Policy"; + + break; + } + case FWPS_DISCARD_IPSEC: + { + pDiscardReason = "IPsec Policy"; + + break; + } + } + + break; + } + } + + HLPR_NEW_ARRAY(pString, + CHAR, + MAX_STRING_SIZE, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + HLPR_BAIL_ON_ALLOC_FAILURE(pString, + status); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n" + "\t\tLayer:\t%s" + "\t\tModule:\t%s\n" + "\t\tReason:\t%s\n" + "\t\tFilter:\t%I64d\n", + KrnlHlprFwpsLayerIDToString(pClassifyData->pClassifyValues->layerId - 1), + pDiscardModule, + pDiscardReason, + filterID); + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\tDiscard:%s", + pString); + + HLPR_BAIL_LABEL: + + HLPR_DELETE_ARRAY(pString, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- PerformBasicPacketExaminationAtDiscard()\n"); + +#endif /// DBG + + return; +} + +/** + @private_function="PerformBasicPacketExaminationAtOther" + + Purpose: Logs the classify. <br> + <br> + Notes: Applies to the following discard layers: <br> + FWPM_LAYER_STREAM_V{4/6} <br> + FWPM_LAYER_ALE_RESOURCE_ASSIGNMENT_V{4/6} <br> + FWPM_LAYER_ALE_AUTH_LISTEN_V{4/6} <br> + FWPM_LAYER_ALE_RESOURCE_RELEASE_V{4/6} <br> + FWPM_LAYER_ALE_ENDPOINT_CLOSURE_V{4/6} <br> + FWPM_LAYER_ALE_CONNECT_REDIRECT_V{4/6} <br> + FWPM_LAYER_ALE_BIND_REDIRECT_V{4/6} <br> + FWPM_LAYER_ALE_CONNECT_REDIRECT_V{4/6} <br> + <br> + MSDN_Ref: <br> +*/ +VOID PerformBasicPacketExaminationAtOther(_In_ CLASSIFY_DATA* pClassifyData) +{ +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> PerformBasicPacketExaminationAtOther()\n"); + +#endif /// DBG + + NT_ASSERT(pClassifyData); + NT_ASSERT(pClassifyData->pClassifyValues); + + NTSTATUS status = STATUS_SUCCESS; + UINT16 localPort = 0; + BYTE* pLocalAddress = 0; + PSTR pString = 0; + +#pragma warning(push) +#pragma warning(disable: 28193) /// value is checked before use + + FWP_VALUE* pLocalAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyData->pClassifyValues, + &FWPM_CONDITION_IP_LOCAL_ADDRESS); + FWP_VALUE* pProtocolValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyData->pClassifyValues, + &FWPM_CONDITION_IP_PROTOCOL); + FWP_VALUE* pLocalPortValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyData->pClassifyValues, + &FWPM_CONDITION_IP_LOCAL_PORT); + +#pragma warning(pop) + +#if(NTDDI_VERSION >= NTDDI_WIN7) + + UINT16 remotePort = 0; + BYTE* pRemoteAddress = 0; + +#pragma warning(push) +#pragma warning(disable: 28193) /// value is checked before use + + FWP_VALUE* pRemoteAddressValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyData->pClassifyValues, + &FWPM_CONDITION_IP_REMOTE_ADDRESS); + FWP_VALUE* pRemotePortValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyData->pClassifyValues, + &FWPM_CONDITION_IP_REMOTE_PORT); + +#pragma warning(pop) + +#endif /// (NTDDI_VERSION >= NTDDI_WIN7) + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\tLayer:%s\n", + KrnlHlprFwpsLayerIDToString(pClassifyData->pClassifyValues->layerId)); + + HLPR_NEW_ARRAY(pString, + CHAR, + MAX_STRING_SIZE, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + HLPR_BAIL_ON_ALLOC_FAILURE(pString, + status); + + switch(pClassifyData->pClassifyValues->layerId) + { + case FWPS_LAYER_STREAM_V4: + case FWPS_LAYER_STREAM_V6: + { + FWPS_STREAM_CALLOUT_IO_PACKET0* pIOPacket = (FWPS_STREAM_CALLOUT_IO_PACKET*)(pClassifyData->pPacket); + + if(pIOPacket) + { + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n" + "\t\t\tStreamData:\n" + "\t\t\t\tFlags: %#x\n" + "\t\t\t\tDataLength: %I64d\n" + "\t\t\tBytesMissed: %I64d\n" + "\t\t\tBytesRequired: %d\n" + "\t\t\tBytesEnforced: %I64d\n" + "\t\t\tStreamAction: %#x\n", + pIOPacket->streamData ? pIOPacket->streamData->flags : 0, + (UINT64)(pIOPacket->streamData ? pIOPacket->streamData->dataLength : 0), + (UINT64)(pIOPacket->missedBytes), + pIOPacket->countBytesRequired, + (UINT64)(pIOPacket->countBytesEnforced), + pIOPacket->streamAction); + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\tStreamCalloutIOPacket: %s", + pString); + } + + break; + } + case FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V4: + case FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V6: + { + PSTR pProtocolString = 0; + + if(pProtocolValue && + pProtocolValue->type == FWP_UINT8) + { + if(pProtocolValue->uint8 == ICMPV4 || + pProtocolValue->uint8 == ICMPV6) + pProtocolString = "ICMP"; + else if(pProtocolValue->uint8 == TCP) + pProtocolString = "TCP"; + else if(pProtocolValue->uint8 == UDP) + pProtocolString = "UDP"; + else if(pProtocolValue->uint8 == IPPROTO_RAW) + pProtocolString = "Raw IP"; + } + + if(pLocalPortValue) + { + if(pLocalPortValue->type == FWP_UINT16) + localPort = pLocalPortValue->uint16; + else if(pLocalPortValue->type == FWP_UINT8) + localPort = pLocalPortValue->uint8; + } + + if(pLocalAddressValue) + { + if(pLocalAddressValue->type == FWP_UINT32) + { + pLocalAddress = (BYTE*)&(pLocalAddressValue->uint32); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n\t\t\t" + "%s %d.%d.%d.%d : %d\n", + pProtocolString, + pLocalAddress[3], + pLocalAddress[2], + pLocalAddress[1], + pLocalAddress[0], + localPort); + } + else if(pLocalAddressValue->type == FWP_BYTE_ARRAY16_TYPE) + { + pLocalAddress = (BYTE*)pLocalAddressValue->byteArray16; + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n\t\t\t" + "%s %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x : %d", + pProtocolString, + pLocalAddress[0], + pLocalAddress[1], + pLocalAddress[2], + pLocalAddress[3], + pLocalAddress[4], + pLocalAddress[5], + pLocalAddress[6], + pLocalAddress[7], + pLocalAddress[8], + pLocalAddress[9], + pLocalAddress[10], + pLocalAddress[11], + pLocalAddress[12], + pLocalAddress[13], + pLocalAddress[14], + pLocalAddress[15], + localPort); + } + + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\tBinding: %s", + pString); + } + + break; + } + case FWPS_LAYER_ALE_AUTH_LISTEN_V4: + case FWPS_LAYER_ALE_AUTH_LISTEN_V6: + { + if(pLocalPortValue) + { + if(pLocalPortValue->type == FWP_UINT16) + localPort = pLocalPortValue->uint16; + else if(pLocalPortValue->type == FWP_UINT8) + localPort = pLocalPortValue->uint8; + } + + if(pLocalAddressValue) + { + if(pLocalAddressValue->type == FWP_UINT32) + { + pLocalAddress = (BYTE*)&(pLocalAddressValue->uint32); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n\t\t\t" + "%d.%d.%d.%d : %d\n", + pLocalAddress[3], + pLocalAddress[2], + pLocalAddress[1], + pLocalAddress[0], + localPort); + } + else if(pLocalAddressValue->type == FWP_BYTE_ARRAY16_TYPE) + { + pLocalAddress = (BYTE*)pLocalAddressValue->byteArray16; + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n\t\t\t" + "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x : %d", + pLocalAddress[0], + pLocalAddress[1], + pLocalAddress[2], + pLocalAddress[3], + pLocalAddress[4], + pLocalAddress[5], + pLocalAddress[6], + pLocalAddress[7], + pLocalAddress[8], + pLocalAddress[9], + pLocalAddress[10], + pLocalAddress[11], + pLocalAddress[12], + pLocalAddress[13], + pLocalAddress[14], + pLocalAddress[15], + localPort); + } + + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\tListening: TCP %s", + pString); + } + + break; + } + +#if(NTDDI_VERSION >= NTDDI_WIN7) + + case FWPS_LAYER_ALE_RESOURCE_RELEASE_V4: + case FWPS_LAYER_ALE_RESOURCE_RELEASE_V6: + { + PSTR pProtocolString = 0; + + if(pProtocolValue && + pProtocolValue->type == FWP_UINT8) + { + if(pProtocolValue->uint8 == ICMPV4 || + pProtocolValue->uint8 == ICMPV6) + pProtocolString = "ICMP"; + else if(pProtocolValue->uint8 == TCP) + pProtocolString = "TCP"; + else if(pProtocolValue->uint8 == UDP) + pProtocolString = "UDP"; + else if(pProtocolValue->uint8 == IPPROTO_RAW) + pProtocolString = "Raw IP"; + } + + if(pLocalPortValue) + { + if(pLocalPortValue->type == FWP_UINT16) + localPort = pLocalPortValue->uint16; + else if(pLocalPortValue->type == FWP_UINT8) + localPort = pLocalPortValue->uint8; + } + + if(pLocalAddressValue) + { + if(pLocalAddressValue->type == FWP_UINT32) + { + pLocalAddress = (BYTE*)&(pLocalAddressValue->uint32); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n\t\t\t" + "%s %d.%d.%d.%d : %d\n", + pProtocolString, + pLocalAddress[3], + pLocalAddress[2], + pLocalAddress[1], + pLocalAddress[0], + localPort); + } + else if(pLocalAddressValue->type == FWP_BYTE_ARRAY16_TYPE) + { + pLocalAddress = (BYTE*)pLocalAddressValue->byteArray16; + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n\t\t\t" + "%s %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x : %d", + pProtocolString, + pLocalAddress[0], + pLocalAddress[1], + pLocalAddress[2], + pLocalAddress[3], + pLocalAddress[4], + pLocalAddress[5], + pLocalAddress[6], + pLocalAddress[7], + pLocalAddress[8], + pLocalAddress[9], + pLocalAddress[10], + pLocalAddress[11], + pLocalAddress[12], + pLocalAddress[13], + pLocalAddress[14], + pLocalAddress[15], + localPort); + } + + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\tReleasing: %s", + pString); + } + + break; + } + case FWPS_LAYER_ALE_ENDPOINT_CLOSURE_V4: + case FWPS_LAYER_ALE_ENDPOINT_CLOSURE_V6: + { + PSTR pProtocolString = 0; + + if(pProtocolValue && + pProtocolValue->type == FWP_UINT8) + { + if(pProtocolValue->uint8 == ICMPV4 || + pProtocolValue->uint8 == ICMPV6) + pProtocolString = "ICMP"; + else if(pProtocolValue->uint8 == TCP) + pProtocolString = "TCP"; + else if(pProtocolValue->uint8 == UDP) + pProtocolString = "UDP"; + else if(pProtocolValue->uint8 == IPPROTO_RAW) + pProtocolString = "Raw IP"; + } + + if(pLocalPortValue) + { + if(pLocalPortValue->type == FWP_UINT16) + localPort = pLocalPortValue->uint16; + else if(pLocalPortValue->type == FWP_UINT8) + localPort = pLocalPortValue->uint8; + } + + if(pLocalAddressValue) + { + if(pLocalAddressValue->type == FWP_UINT32) + { + pLocalAddress = (BYTE*)&(pLocalAddressValue->uint32); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n\t\t\t" + "%s %d.%d.%d.%d : %d\n", + pProtocolString, + pLocalAddress[3], + pLocalAddress[2], + pLocalAddress[1], + pLocalAddress[0], + localPort); + } + else if(pLocalAddressValue->type == FWP_BYTE_ARRAY16_TYPE) + { + pLocalAddress = (BYTE*)pLocalAddressValue->byteArray16; + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n\t\t\t" + "%s %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x : %d", + pProtocolString, + pLocalAddress[0], + pLocalAddress[1], + pLocalAddress[2], + pLocalAddress[3], + pLocalAddress[4], + pLocalAddress[5], + pLocalAddress[6], + pLocalAddress[7], + pLocalAddress[8], + pLocalAddress[9], + pLocalAddress[10], + pLocalAddress[11], + pLocalAddress[12], + pLocalAddress[13], + pLocalAddress[14], + pLocalAddress[15], + localPort); + } + + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\tClosing: %s", + pString); + } + + break; + } + case FWPS_LAYER_ALE_CONNECT_REDIRECT_V4: + case FWPS_LAYER_ALE_CONNECT_REDIRECT_V6: + { + PSTR pProtocolString = 0; + + if(pProtocolValue && + pProtocolValue->type == FWP_UINT8) + { + if(pProtocolValue->uint8 == ICMPV4 || + pProtocolValue->uint8 == ICMPV6) + pProtocolString = "ICMP"; + else if(pProtocolValue->uint8 == TCP) + pProtocolString = "TCP"; + else if(pProtocolValue->uint8 == UDP) + pProtocolString = "UDP"; + else if(pProtocolValue->uint8 == IPPROTO_RAW) + pProtocolString = "Raw IP"; + } + + if(pLocalPortValue) + { + if(pLocalPortValue->type == FWP_UINT16) + localPort = pLocalPortValue->uint16; + else if(pLocalPortValue->type == FWP_UINT8) + localPort = pLocalPortValue->uint8; + } + + if(pRemotePortValue) + { + if(pRemotePortValue->type == FWP_UINT16) + remotePort = pRemotePortValue->uint16; + else if(pRemotePortValue->type == FWP_UINT8) + remotePort = pRemotePortValue->uint8; + } + + if(pLocalAddressValue && + pRemoteAddressValue) + { + if(pLocalAddressValue->type == FWP_UINT32 && + pRemoteAddressValue->type == FWP_UINT32) + { + pLocalAddress = (BYTE*)&(pLocalAddressValue->uint32); + + pRemoteAddress = (BYTE*)&(pRemoteAddressValue->uint32); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n\t\t\t" + "%s %d.%d.%d.%d : %d To %d.%d.%d.%d : %d\n", + pProtocolString, + pLocalAddress[3], + pLocalAddress[2], + pLocalAddress[1], + pLocalAddress[0], + localPort, + pRemoteAddress[3], + pRemoteAddress[2], + pRemoteAddress[1], + pRemoteAddress[0], + remotePort); + } + else if(pLocalAddressValue->type == FWP_BYTE_ARRAY16_TYPE && + pRemoteAddressValue->type == FWP_BYTE_ARRAY16_TYPE) + { + pLocalAddress = (BYTE*)pLocalAddressValue->byteArray16; + + pRemoteAddress = (BYTE*)pRemoteAddressValue->byteArray16; + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n\t\t\t" + "%s %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x : %d To %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x : %d\n", + pProtocolString, + pLocalAddress[0], + pLocalAddress[1], + pLocalAddress[2], + pLocalAddress[3], + pLocalAddress[4], + pLocalAddress[5], + pLocalAddress[6], + pLocalAddress[7], + pLocalAddress[8], + pLocalAddress[9], + pLocalAddress[10], + pLocalAddress[11], + pLocalAddress[12], + pLocalAddress[13], + pLocalAddress[14], + pLocalAddress[15], + localPort, + pRemoteAddress[0], + pRemoteAddress[1], + pRemoteAddress[2], + pRemoteAddress[3], + pRemoteAddress[4], + pRemoteAddress[5], + pRemoteAddress[6], + pRemoteAddress[7], + pRemoteAddress[8], + pRemoteAddress[9], + pRemoteAddress[10], + pRemoteAddress[11], + pRemoteAddress[12], + pRemoteAddress[13], + pRemoteAddress[14], + pRemoteAddress[15], + remotePort); + } + + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\tInspecting: %s", + pString); + } + + break; + } + case FWPS_LAYER_ALE_BIND_REDIRECT_V4: + case FWPS_LAYER_ALE_BIND_REDIRECT_V6: + { + PSTR pProtocolString = 0; + + if(pProtocolValue && + pProtocolValue->type == FWP_UINT8) + { + if(pProtocolValue->uint8 == ICMPV4 || + pProtocolValue->uint8 == ICMPV6) + pProtocolString = "ICMP"; + else if(pProtocolValue->uint8 == TCP) + pProtocolString = "TCP"; + else if(pProtocolValue->uint8 == UDP) + pProtocolString = "UDP"; + else if(pProtocolValue->uint8 == IPPROTO_RAW) + pProtocolString = "Raw IP"; + } + + if(pLocalPortValue) + { + if(pLocalPortValue->type == FWP_UINT16) + localPort = pLocalPortValue->uint16; + else if(pLocalPortValue->type == FWP_UINT8) + localPort = pLocalPortValue->uint8; + } + + if(pLocalAddressValue) + { + if(pLocalAddressValue->type == FWP_UINT32) + { + pLocalAddress = (BYTE*)&(pLocalAddressValue->uint32); + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n\t\t\t" + "%s %d.%d.%d.%d : %d\n", + pProtocolString, + pLocalAddress[3], + pLocalAddress[2], + pLocalAddress[1], + pLocalAddress[0], + localPort); + } + else if(pLocalAddressValue->type == FWP_BYTE_ARRAY16_TYPE) + { + pLocalAddress = (BYTE*)pLocalAddressValue->byteArray16; + + status = RtlStringCchPrintfA(pString, + MAX_STRING_SIZE, + "\n\t\t\t" + "%s %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x : %d", + pProtocolString, + pLocalAddress[0], + pLocalAddress[1], + pLocalAddress[2], + pLocalAddress[3], + pLocalAddress[4], + pLocalAddress[5], + pLocalAddress[6], + pLocalAddress[7], + pLocalAddress[8], + pLocalAddress[9], + pLocalAddress[10], + pLocalAddress[11], + pLocalAddress[12], + pLocalAddress[13], + pLocalAddress[14], + pLocalAddress[15], + localPort); + } + + if(status == STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\t\tInspecting: %s", + pString); + } + + break; + } + +#endif /// (NTDDI_VERSION >= NTDDI_WIN7) + + } + + HLPR_BAIL_LABEL: + + HLPR_DELETE_ARRAY(pString, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + +#if DBG + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- PerformBasicPacketExaminationAtOther()\n"); + +#endif /// DBG + + return; +} + +#if(NTDDI_VERSION >= NTDDI_WIN7) + +/** + @classify_function="ClassifyBasicPacketExamination" + + Purpose: Examines the packet and returns FWP_ACTION_CONTINUE. <br> + <br> + Notes: Applies to the following layers: <br> + FWPS_LAYER_INBOUND_IPPACKET_V{4/6} <br> + FWPS_LAYER_INBOUND_IPPACKET_V{4/6}_DISCARD <br> + FWPS_LAYER_OUTBOUND_IPPACKET_V{4/6} <br> + FWPS_LAYER_OUTBOUND_IPPACKET_V{4/6}_DISCARD <br> + FWPS_LAYER_IPFORWARD_V{4/6} <br> + FWPS_LAYER_IPFORWARD_V{4/6}_DISCARD <br> + FWPS_LAYER_INBOUND_TRANSPORT_V{4/6} <br> + FWPS_LAYER_INBOUND_TRANSPORT_V{4/6}_DISCARD <br> + FWPS_LAYER_OUTBOUND_TRANSPORT_V{4/6} <br> + FWPS_LAYER_OUTBOUND_TRANSPORT_V{4/6}_DISCARD <br> + FWPS_LAYER_STREAM_V{4/6} <br> + FWPS_LAYER_STREAM_V{4/6}_DISCARD <br> + FWPS_LAYER_DATAGRAM_DATA_V{4/6} <br> + FWPS_LAYER_DATAGRAM_DATA_V{4/6}_DISCARD <br> + FWPS_LAYER_INBOUND_ICMP_ERROR_V{4/6} <br> + FWPS_LAYER_INBOUND_ICMP_ERROR_V{4/6}_DISCARD <br> + FWPS_LAYER_OUTBOUND_ICMP_ERROR_V{4/6} <br> + FWPS_LAYER_OUTBOUND_ICMP_ERROR_V{4/6}_DISCARD <br> + FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V{4/6} <br> + FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V{4/6}_DISCARD <br> + FWPS_LAYER_ALE_AUTH_LISTEN_V{4/6} <br> + FWPS_LAYER_ALE_AUTH_LISTEN_V{4/6}_DISCARD <br> + FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V{4/6} <br> + FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V{4/6}_DISCARD <br> + FWPS_LAYER_ALE_AUTH_CONNECT_V{4/6} <br> + FWPS_LAYER_ALE_AUTH_CONNECT_V{4/6}_DISCARD <br> + FWPS_LAYER_ALE_FLOW_ESTABLISHED_V{4/6} <br> + FWPS_LAYER_ALE_FLOW_ESTABLISHED_V{4/6}_DISCARD <br> + FWPS_LAYER_ALE_RESOURCE_RELEASE_V{4/6} <br> + FWPS_LAYER_ALE_ENDPOINT_CLOSURE_V{4/6} <br> + FWPS_LAYER_ALE_CONNECT_REDIRECT_V{4/6} <br> + FWPS_LAYER_ALE_BIND_REDIRECT_V{4/6} <br> + FWPS_LAYER_STREAM_PACKET_V{4/6} <br> + FWPS_LAYER_INBOUND_MAC_FRAME_ETHERNET <br> + FWPS_LAYER_OUTBOUND_MAC_FRAME_ETHERNET <br> + FWPS_LAYER_INBOUND_MAC_FRAME_NATIVE <br> + FWPS_LAYER_OUTBOUND_MAC_FRAME_NATIVE <br> + FWPS_LAYER_INGRESS_VSWITCH_ETHERNET <br> + FWPS_LAYER_EGRESS_VSWITCH_ETHERNET <br> + FWPS_LAYER_INGRESS_VSWITCH_TRANSPORT_V{4/6} <br> + FWPS_LAYER_EGRESS_VSWITCH_TRANSPORT_V{4/6} <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF544893.aspx <br> +*/ +_IRQL_requires_min_(PASSIVE_LEVEL) +_IRQL_requires_max_(DISPATCH_LEVEL) +_IRQL_requires_same_ +VOID NTAPI ClassifyBasicPacketExamination(_In_ const FWPS_INCOMING_VALUES0* pClassifyValues, + _In_ const FWPS_INCOMING_METADATA_VALUES0* pMetadata, + _Inout_opt_ VOID* pLayerData, + _In_opt_ const VOID* pClassifyContext, + _In_ const FWPS_FILTER* pFilter, + _In_ UINT64 flowContext, + _Inout_ FWPS_CLASSIFY_OUT* pClassifyOut) +{ + NT_ASSERT(pClassifyValues); + NT_ASSERT(pMetadata); + NT_ASSERT(pFilter); + NT_ASSERT(pClassifyOut); + +#if(NTDDI_VERSION >= NTDDI_WIN8) + + NT_ASSERT(pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V4 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V6 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V4 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V6 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V4 || + pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V6 || + pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_TRANSPORT_V4 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_TRANSPORT_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_TRANSPORT_V6 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_TRANSPORT_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_TRANSPORT_V4 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_TRANSPORT_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_TRANSPORT_V6 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_TRANSPORT_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_STREAM_V4 || + pClassifyValues->layerId == FWPS_LAYER_STREAM_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_STREAM_V6 || + pClassifyValues->layerId == FWPS_LAYER_STREAM_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V4 || + pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V6 || + pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V4 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V6 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V4 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V6 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_RELEASE_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_RELEASE_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_ENDPOINT_CLOSURE_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_ENDPOINT_CLOSURE_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_CONNECT_REDIRECT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_CONNECT_REDIRECT_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_BIND_REDIRECT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_BIND_REDIRECT_V6 || + pClassifyValues->layerId == FWPS_LAYER_STREAM_PACKET_V4 || + pClassifyValues->layerId == FWPS_LAYER_STREAM_PACKET_V6 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_MAC_FRAME_ETHERNET || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_MAC_FRAME_ETHERNET || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_MAC_FRAME_NATIVE || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_MAC_FRAME_NATIVE || + pClassifyValues->layerId == FWPS_LAYER_INGRESS_VSWITCH_ETHERNET || + pClassifyValues->layerId == FWPS_LAYER_EGRESS_VSWITCH_ETHERNET || + pClassifyValues->layerId == FWPS_LAYER_INGRESS_VSWITCH_TRANSPORT_V4 || + pClassifyValues->layerId == FWPS_LAYER_INGRESS_VSWITCH_TRANSPORT_V6 || + pClassifyValues->layerId == FWPS_LAYER_EGRESS_VSWITCH_TRANSPORT_V4 || + pClassifyValues->layerId == FWPS_LAYER_EGRESS_VSWITCH_TRANSPORT_V6); + +#else + + NT_ASSERT(pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V4 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V6 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V4 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V6 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V4 || + pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V6 || + pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_TRANSPORT_V4 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_TRANSPORT_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_TRANSPORT_V6 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_TRANSPORT_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_TRANSPORT_V4 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_TRANSPORT_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_TRANSPORT_V6 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_TRANSPORT_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_STREAM_V4 || + pClassifyValues->layerId == FWPS_LAYER_STREAM_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_STREAM_V4 || + pClassifyValues->layerId == FWPS_LAYER_STREAM_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V4 || + pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V6 || + pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V4 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V6 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V4 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V6 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_RELEASE_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_RELEASE_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_ENDPOINT_CLOSURE_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_ENDPOINT_CLOSURE_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_CONNECT_REDIRECT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_CONNECT_REDIRECT_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_BIND_REDIRECT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_BIND_REDIRECT_V6 || + pClassifyValues->layerId == FWPS_LAYER_STREAM_PACKET_V4 || + pClassifyValues->layerId == FWPS_LAYER_STREAM_PACKET_V6); + +#endif /// (NTDDI_VERSION >= NTDDI_WIN8) + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> ClassifyBasicPacketExamination() [Layer: %s][FilterID: %#I64x][Rights: %#x]", + KrnlHlprFwpsLayerIDToString(pClassifyValues->layerId), + pFilter->filterId, + pClassifyOut->rights); + + NTSTATUS status = STATUS_SUCCESS; + CLASSIFY_DATA* pClassifyData = 0; + FWP_DIRECTION direction = FWP_DIRECTION_MAX; + FWP_VALUE* pDirectionValue = 0; + KIRQL originalIRQL = PASSIVE_LEVEL; + + HLPR_NEW(pClassifyData, + CLASSIFY_DATA, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + HLPR_BAIL_ON_ALLOC_FAILURE(pClassifyData, + status); + + if(pFilter->context & PCPEF_EXAMINE_UNDER_LOCK) + KeAcquireSpinLock(&g_bpeSpinLock, + &originalIRQL); + + if(pFilter->context & PCPEF_EXAMINE_INCOMING_VALUES) + LogClassifyValues(pClassifyValues); + + if(pFilter->context & PCPEF_EXAMINE_INCOMING_METADATA_VALUES) + LogMetadata(pMetadata); + + if(pFilter->context & PCPEF_EXAMINE_LAYER_DATA) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\tLayerData: %#p", + pLayerData); + + if(pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6) + direction = FWP_DIRECTION_INBOUND; + else if(pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6) + direction = FWP_DIRECTION_OUTBOUND; + + pDirectionValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_DIRECTION); + if(pDirectionValue) + direction = (FWP_DIRECTION)pDirectionValue->uint32; + else + { + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_PACKET_DIRECTION)) + direction = pMetadata->packetDirection; + } + + pClassifyData->pClassifyValues = pClassifyValues; + pClassifyData->pMetadataValues = pMetadata; + pClassifyData->pPacket = pLayerData; + pClassifyData->pClassifyContext = pClassifyContext; + pClassifyData->pFilter = pFilter; + pClassifyData->flowContext = flowContext; + pClassifyData->pClassifyOut = pClassifyOut; + + if(pClassifyData->pPacket) + { + if(pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V4 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V6) + PerformBasicPacketExaminationAtInboundNetwork(pClassifyData); + else if(pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V4 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V6) + PerformBasicPacketExaminationAtOutboundNetwork(pClassifyData); + else if(pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V4 || + pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V6) + PerformBasicPacketExaminationAtForward(pClassifyData); + else if(pClassifyValues->layerId == FWPS_LAYER_INBOUND_TRANSPORT_V4 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_TRANSPORT_V6 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V4 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V6 || + (direction == FWP_DIRECTION_INBOUND && + (pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V4 || + pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4 || /// Policy Change Reauthorization + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6 || /// Policy Change Reauthorization + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V6 || + pClassifyValues->layerId == FWPS_LAYER_STREAM_PACKET_V4 || + pClassifyValues->layerId == FWPS_LAYER_STREAM_PACKET_V6))) + PerformBasicPacketExaminationAtInboundTransport(pClassifyData); + else if(pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_TRANSPORT_V4 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_TRANSPORT_V6 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V4 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V6 || + (direction == FWP_DIRECTION_OUTBOUND && + (pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V4 || + pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4 || /// Policy Change Reauthorization + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6 || /// Policy Change Reauthorization + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V6 || + pClassifyValues->layerId == FWPS_LAYER_STREAM_PACKET_V4 || + pClassifyValues->layerId == FWPS_LAYER_STREAM_PACKET_V6))) + PerformBasicPacketExaminationAtOutboundTransport(pClassifyData); + +#if(NTDDI_VERSION >= NTDDI_WIN8) + + else if(pClassifyValues->layerId == FWPS_LAYER_INBOUND_MAC_FRAME_ETHERNET || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_MAC_FRAME_NATIVE) + PerformBasicPacketExaminationAtInboundMACFrame(pClassifyData); + else if(pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_MAC_FRAME_ETHERNET || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_MAC_FRAME_NATIVE) + PerformBasicPacketExaminationAtOutboundMACFrame(pClassifyData); + else if(pClassifyValues->layerId == FWPS_LAYER_INGRESS_VSWITCH_ETHERNET || + pClassifyValues->layerId == FWPS_LAYER_EGRESS_VSWITCH_ETHERNET) + PerformBasicPacketExaminationAtVSwitchEthernet(pClassifyData); + else if(pClassifyValues->layerId == FWPS_LAYER_INGRESS_VSWITCH_TRANSPORT_V4 || + pClassifyValues->layerId == FWPS_LAYER_INGRESS_VSWITCH_TRANSPORT_V6 || + pClassifyValues->layerId == FWPS_LAYER_EGRESS_VSWITCH_TRANSPORT_V4 || + pClassifyValues->layerId == FWPS_LAYER_EGRESS_VSWITCH_TRANSPORT_V6) + PerformBasicPacketExaminationAtVSwitchTransport(pClassifyData); + +#endif // (NTDDI_VERSION >= NTDDI_WIN8) + + else if(KrnlHlprFwpsLayerIsDiscard(pClassifyValues->layerId)) + PerformBasicPacketExaminationAtDiscard(pClassifyData); + else + PerformBasicPacketExaminationAtOther(pClassifyData); + } + else + { + if(KrnlHlprFwpsLayerIsDiscard(pClassifyValues->layerId)) + PerformBasicPacketExaminationAtDiscard(pClassifyData); + else + PerformBasicPacketExaminationAtOther(pClassifyData); + } + + if(pFilter->context & PCPEF_EXAMINE_CLASSIFY_CONTEXT) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\tClassifyContext: %#p", + pClassifyContext); + + if(pFilter->context & PCPEF_EXAMINE_FILTER) + LogFilter(pFilter); + + if(pFilter->context & PCPEF_EXAMINE_FLOW_CONTEXT) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\tflowContext: %#I64x", + flowContext); + + if(pFilter->context & PCPEF_EXAMINE_CLASSIFY_OUT) + LogClassifyOut(pClassifyOut); + + if(pFilter->context & PCPEF_EXAMINE_UNDER_LOCK) + KeReleaseSpinLock(&g_bpeSpinLock, + originalIRQL); + + HLPR_BAIL_LABEL: + + if(status != STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_ERROR_LEVEL, + " !!!! ClassifyBasicPacketExamination: [status: %#x]\n", + status); + + HLPR_DELETE(pClassifyData, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + + if(pClassifyOut->rights & FWPS_RIGHT_ACTION_WRITE) + pClassifyOut->actionType = FWP_ACTION_CONTINUE; + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- ClassifyBasicPacketExamination() [Layer: %s][FilterID: %#I64x][Action: %#x][Rights: %#x][Absorb: %s]\n", + KrnlHlprFwpsLayerIDToString(pClassifyValues->layerId), + pFilter->filterId, + pClassifyOut->actionType, + pClassifyOut->rights, + (pClassifyOut->flags & FWPS_CLASSIFY_OUT_FLAG_ABSORB) ? "TRUE" : "FALSE"); + + return; +} + +#else + +/** + @classify_function="ClassifyBasicPacketExamination" + + Purpose: Examines the packet and returns FWP_ACTION_CONTINUE. <br> + <br> + Notes: Applies to the following layers: <br> + FWPS_LAYER_INBOUND_IPPACKET_V{4/6} <br> + FWPS_LAYER_INBOUND_IPPACKET_V{4/6}_DISCARD <br> + FWPS_LAYER_OUTBOUND_IPPACKET_V{4/6} <br> + FWPS_LAYER_OUTBOUND_IPPACKET_V{4/6}_DISCARD <br> + FWPS_LAYER_IPFORWARD_V{4/6} <br> + FWPS_LAYER_IPFORWARD_V{4/6}_DISCARD <br> + FWPS_LAYER_INBOUND_TRANSPORT_V{4/6} <br> + FWPS_LAYER_INBOUND_TRANSPORT_V{4/6}_DISCARD <br> + FWPS_LAYER_OUTBOUND_TRANSPORT_V{4/6} <br> + FWPS_LAYER_OUTBOUND_TRANSPORT_V{4/6}_DISCARD <br> + FWPS_LAYER_STREAM_V{4/6} <br> + FWPS_LAYER_STREAM_V{4/6}_DISCARD <br> + FWPS_LAYER_DATAGRAM_DATA_V{4/6} <br> + FWPS_LAYER_DATAGRAM_DATA_V{4/6}_DISCARD <br> + FWPS_LAYER_INBOUND_ICMP_ERROR_V{4/6} <br> + FWPS_LAYER_INBOUND_ICMP_ERROR_V{4/6}_DISCARD <br> + FWPS_LAYER_OUTBOUND_ICMP_ERROR_V{4/6} <br> + FWPS_LAYER_OUTBOUND_ICMP_ERROR_V{4/6}_DISCARD <br> + FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V{4/6} <br> + FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V{4/6}_DISCARD <br> + FWPS_LAYER_ALE_AUTH_LISTEN_V{4/6} <br> + FWPS_LAYER_ALE_AUTH_LISTEN_V{4/6}_DISCARD <br> + FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V{4/6} <br> + FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V{4/6}_DISCARD <br> + FWPS_LAYER_ALE_AUTH_CONNECT_V{4/6} <br> + FWPS_LAYER_ALE_AUTH_CONNECT_V{4/6}_DISCARD <br> + FWPS_LAYER_ALE_FLOW_ESTABLISHED_V{4/6} <br> + FWPS_LAYER_ALE_FLOW_ESTABLISHED_V{4/6}_DISCARD <br> + <br> + MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF544890.aspx <br> +*/ +_IRQL_requires_min_(PASSIVE_LEVEL) +_IRQL_requires_max_(DISPATCH_LEVEL) +_IRQL_requires_same_ +VOID NTAPI ClassifyBasicPacketExamination(_In_ const FWPS_INCOMING_VALUES* pClassifyValues, + _In_ const FWPS_INCOMING_METADATA_VALUES* pMetadata, + _Inout_opt_ VOID* pLayerData, + _In_ const FWPS_FILTER* pFilter, + _In_ UINT64 flowContext, + _Inout_ FWPS_CLASSIFY_OUT* pClassifyOut) +{ + NT_ASSERT(pClassifyValues); + NT_ASSERT(pMetadata); + NT_ASSERT(pFilter); + NT_ASSERT(pClassifyOut); + NT_ASSERT(pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V4 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V6 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V4 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V6 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V4 || + pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V6 || + pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_TRANSPORT_V4 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_TRANSPORT_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_TRANSPORT_V6 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_TRANSPORT_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_TRANSPORT_V4 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_TRANSPORT_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_TRANSPORT_V6 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_TRANSPORT_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_STREAM_V4 || + pClassifyValues->layerId == FWPS_LAYER_STREAM_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_STREAM_V6 || + pClassifyValues->layerId == FWPS_LAYER_STREAM_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V4 || + pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V6 || + pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V4 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V6 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V4 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V6 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_LISTEN_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V4_DISCARD || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V6_DISCARD); + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " ---> ClassifyBasicPacketExamination() [Layer: %s][FilterID: %#I64x][Rights: %#x]", + KrnlHlprFwpsLayerIDToString(pClassifyValues->layerId), + pFilter->filterId, + pClassifyOut->rights); + + NTSTATUS status = STATUS_SUCCESS; + CLASSIFY_DATA* pClassifyData = 0; + FWP_DIRECTION direction = FWP_DIRECTION_MAX; + FWP_VALUE* pDirectionValue = 0; + KIRQL originalIRQL = PASSIVE_LEVEL; + + HLPR_NEW(pClassifyData, + CLASSIFY_DATA, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + HLPR_BAIL_ON_ALLOC_FAILURE(pClassifyData, + status); + + if(pFilter->context & PCPEF_EXAMINE_UNDER_LOCK) + KeAcquireSpinLock(&g_bpeSpinLock, + &originalIRQL); + + if(pFilter->context & PCPEF_EXAMINE_INCOMING_VALUES) + LogClassifyValues(pClassifyValues); + + if(pFilter->context & PCPEF_EXAMINE_INCOMING_METADATA_VALUES) + LogMetadata(pMetadata); + + if(pFilter->context & PCPEF_EXAMINE_LAYER_DATA) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\tLayerData: %#p", + pLayerData); + + if(pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6) + direction = FWP_DIRECTION_INBOUND; + else if(pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6) + direction = FWP_DIRECTION_OUTBOUND; + + pDirectionValue = KrnlHlprFwpValueGetFromFwpsIncomingValues(pClassifyValues, + &FWPM_CONDITION_DIRECTION); + if(pDirectionValue) + direction = (FWP_DIRECTION)pDirectionValue->uint32; + else + { + if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata, + FWPS_METADATA_FIELD_PACKET_DIRECTION)) + direction = pMetadata->packetDirection; + } + + pClassifyData->pClassifyValues = pClassifyValues; + pClassifyData->pMetadataValues = pMetadata; + pClassifyData->pPacket = pLayerData; + pClassifyData->pFilter = pFilter; + pClassifyData->flowContext = flowContext; + pClassifyData->pClassifyOut = pClassifyOut; + + if(pClassifyData->pPacket) + { + if(pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V4 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V6) + PerformBasicPacketExaminationAtInboundNetwork(pClassifyData); + else if(pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V4 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V6) + PerformBasicPacketExaminationAtOutboundNetwork(pClassifyData); + else if(pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V4 || + pClassifyValues->layerId == FWPS_LAYER_IPFORWARD_V6) + PerformBasicPacketExaminationAtForward(pClassifyData); + else if(pClassifyValues->layerId == FWPS_LAYER_INBOUND_TRANSPORT_V4 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_TRANSPORT_V6 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V4 || + pClassifyValues->layerId == FWPS_LAYER_INBOUND_ICMP_ERROR_V6 || + (direction == FWP_DIRECTION_INBOUND && + (pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V4 || + pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4 || /// Policy Change Reauthorization + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6 || /// Policy Change Reauthorization + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V6))) + PerformBasicPacketExaminationAtInboundTransport(pClassifyData); + else if(pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_TRANSPORT_V4 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_TRANSPORT_V6 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V4 || + pClassifyValues->layerId == FWPS_LAYER_OUTBOUND_ICMP_ERROR_V6 || + (direction == FWP_DIRECTION_OUTBOUND && + (pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V4 || + pClassifyValues->layerId == FWPS_LAYER_DATAGRAM_DATA_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4 || /// Policy Change Reauthorization + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6 || /// Policy Change Reauthorization + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_AUTH_CONNECT_V6 || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V4 || + pClassifyValues->layerId == FWPS_LAYER_ALE_FLOW_ESTABLISHED_V6))) + PerformBasicPacketExaminationAtOutboundTransport(pClassifyData); + else if(KrnlHlprFwpsLayerIsDiscard(pClassifyValues->layerId)) + PerformBasicPacketExaminationAtDiscard(pClassifyData); + else + PerformBasicPacketExaminationAtOther(pClassifyData); + } + else + { + if(KrnlHlprFwpsLayerIsDiscard(pClassifyValues->layerId)) + PerformBasicPacketExaminationAtDiscard(pClassifyData); + else + PerformBasicPacketExaminationAtOther(pClassifyData); + } + + if(pFilter->context & PCPEF_EXAMINE_FILTER) + LogFilter(pFilter); + + if(pFilter->context & PCPEF_EXAMINE_FLOW_CONTEXT) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + "\tflowContext: %#I64x", + flowContext); + + if(pFilter->context & PCPEF_EXAMINE_CLASSIFY_OUT) + LogClassifyOut(pClassifyOut); + + if(pFilter->context & PCPEF_EXAMINE_UNDER_LOCK) + KeReleaseSpinLock(&g_bpeSpinLock, + originalIRQL); + + HLPR_BAIL_LABEL: + + if(status != STATUS_SUCCESS) + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_ERROR_LEVEL, + " !!!! ClassifyBasicPacketExamination: [status: %#x]\n", + status); + + HLPR_DELETE(pClassifyData, + WFPSAMPLER_CALLOUT_DRIVER_TAG); + + if(pClassifyOut->rights & FWPS_RIGHT_ACTION_WRITE) + pClassifyOut->actionType = FWP_ACTION_CONTINUE; + + DbgPrintEx(DPFLTR_IHVNETWORK_ID, + DPFLTR_INFO_LEVEL, + " <--- ClassifyBasicPacketExamination() [Layer: %s][FilterID: %#I64x][Action: %#x][Rights: %#x][Absorb: %s]\n", + KrnlHlprFwpsLayerIDToString(pClassifyValues->layerId), + pFilter->filterId, + pClassifyOut->actionType, + pClassifyOut->rights, + (pClassifyOut->flags & FWPS_CLASSIFY_OUT_FLAG_ABSORB) ? "TRUE" : "FALSE"); + + return; +} + +#endif // (NTDDI_VERSION >= NTDDI_WIN7) |
