VOID NTAPI ClassifyBasicPacketExamination()

in network/trans/WFPSampler/sys/ClassifyFunctions_BasicPacketExaminationCallouts.cpp [5028:5374]


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