in network/trans/WFPSampler/sys/ClassifyFunctions_FastPacketInjectionCallouts.cpp [1137:1873]
VOID NTAPI ClassifyFastPacketInjection(_In_ const FWPS_INCOMING_VALUES* pClassifyValues,
_In_ const FWPS_INCOMING_METADATA_VALUES0* pMetadata,
_Inout_opt_ VOID* pNetBufferList,
_In_ const FWPS_FILTER* pFilter,
_In_ UINT64 flowContext,
_Inout_ FWPS_CLASSIFY_OUT* pClassifyOut)
{
UNREFERENCED_PARAMETER(pFilter);
UNREFERENCED_PARAMETER(flowContext);
if(pClassifyOut->rights & FWPS_RIGHT_ACTION_WRITE)
{
NTSTATUS status = STATUS_SUCCESS;
UINT32 ipHeaderSize = 0;
UINT32 transportHeaderSize = 0;
COMPARTMENT_ID compartmentID = DEFAULT_COMPARTMENT_ID;
UINT64 endpointHandle = 0;
ADDRESS_FAMILY addressFamily = AF_UNSPEC;
UINT8 protocol = 0;
FWP_DIRECTION direction = FWP_DIRECTION_MAX;
UINT32 flags = 0;
BOOLEAN isALEClassifyRequired = FALSE;
VOID* pRemoteAddress = 0;
IF_INDEX interfaceIndex = 0;
IF_INDEX subInterfaceIndex = 0;
HANDLE injectionHandle = 0;
FWPS_PACKET_INJECTION_STATE injectionState = FWPS_PACKET_INJECTION_STATE_MAX;
HANDLE injectionContext = 0;
UINT32 bytesRetreated = 0;
NET_BUFFER_LIST* pClonedNetBufferList = 0;
UINT32 index = WFPSAMPLER_INDEX;
if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata,
FWPS_METADATA_FIELD_IP_HEADER_SIZE))
ipHeaderSize = pMetadata->ipHeaderSize;
if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata,
FWPS_METADATA_FIELD_TRANSPORT_HEADER_SIZE))
transportHeaderSize = pMetadata->transportHeaderSize;
if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata,
FWPS_METADATA_FIELD_COMPARTMENT_ID))
compartmentID = (COMPARTMENT_ID)pMetadata->compartmentId;
if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata,
FWPS_METADATA_FIELD_TRANSPORT_ENDPOINT_HANDLE))
endpointHandle = pMetadata->transportEndpointHandle;
if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata,
FWPS_METADATA_FIELD_PACKET_DIRECTION))
direction = pMetadata->packetDirection;
if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata,
FWPS_METADATA_FIELD_ALE_CLASSIFY_REQUIRED))
isALEClassifyRequired = TRUE;
if(pFilter->subLayerWeight == FWPM_SUBLAYER_UNIVERSAL_WEIGHT)
index = UNIVERSAL_INDEX;
switch(pClassifyValues->layerId)
{
case FWPS_LAYER_INBOUND_IPPACKET_V4:
{
addressFamily = AF_INET;
interfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_IPPACKET_V4_INTERFACE_INDEX].value.uint32;
subInterfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_IPPACKET_V4_SUB_INTERFACE_INDEX].value.uint32;
flags = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_IPPACKET_V4_FLAGS].value.uint32;
injectionHandle = g_pIPv4InboundNetworkInjectionHandles[index];
bytesRetreated = ipHeaderSize;
break;
}
case FWPS_LAYER_INBOUND_IPPACKET_V6:
{
addressFamily = AF_INET6;
interfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_IPPACKET_V6_INTERFACE_INDEX].value.uint32;
subInterfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_IPPACKET_V6_SUB_INTERFACE_INDEX].value.uint32;
flags = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_IPPACKET_V6_FLAGS].value.uint32;
injectionHandle = g_pIPv6InboundNetworkInjectionHandles[index];
bytesRetreated = ipHeaderSize;
break;
}
case FWPS_LAYER_OUTBOUND_IPPACKET_V4:
{
addressFamily = AF_INET;
flags = pClassifyValues->incomingValue[FWPS_FIELD_OUTBOUND_IPPACKET_V4_FLAGS].value.uint32;
injectionHandle = g_pIPv4OutboundNetworkInjectionHandles[index];
break;
}
case FWPS_LAYER_OUTBOUND_IPPACKET_V6:
{
addressFamily = AF_INET6;
flags = pClassifyValues->incomingValue[FWPS_FIELD_OUTBOUND_IPPACKET_V6_FLAGS].value.uint32;
injectionHandle = g_pIPv6OutboundNetworkInjectionHandles[index];
break;
}
case FWPS_LAYER_IPFORWARD_V4:
{
addressFamily = AF_INET;
interfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_IPFORWARD_V4_DESTINATION_INTERFACE_INDEX].value.uint32;
flags = pClassifyValues->incomingValue[FWPS_FIELD_IPFORWARD_V4_FLAGS].value.uint32;
if(direction == FWP_DIRECTION_OUTBOUND)
injectionHandle = g_pIPv4OutboundForwardInjectionHandles[index];
else
injectionHandle = g_pIPv4InboundForwardInjectionHandles[index];
break;
}
case FWPS_LAYER_IPFORWARD_V6:
{
addressFamily = AF_INET6;
interfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_IPFORWARD_V6_DESTINATION_INTERFACE_INDEX].value.uint32;
flags = pClassifyValues->incomingValue[FWPS_FIELD_IPFORWARD_V6_FLAGS].value.uint32;
if(direction == FWP_DIRECTION_OUTBOUND)
injectionHandle = g_pIPv6OutboundForwardInjectionHandles[index];
else
injectionHandle = g_pIPv6InboundForwardInjectionHandles[index];
break;
}
case FWPS_LAYER_INBOUND_TRANSPORT_V4:
{
addressFamily = AF_INET;
protocol = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V4_IP_PROTOCOL].value.uint8;
interfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V4_INTERFACE_INDEX].value.uint32;
subInterfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V4_SUB_INTERFACE_INDEX].value.uint32;
flags = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V4_FLAGS].value.uint32;
injectionHandle = g_pIPv4InboundTransportInjectionHandles[index];
if(protocol == ICMPV4)
bytesRetreated = ipHeaderSize;
else
bytesRetreated = ipHeaderSize + transportHeaderSize;
break;
}
case FWPS_LAYER_INBOUND_TRANSPORT_V6:
{
addressFamily = AF_INET6;
protocol = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V6_IP_PROTOCOL].value.uint8;
interfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V6_INTERFACE_INDEX].value.uint32;
subInterfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V6_SUB_INTERFACE_INDEX].value.uint32;
flags = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_TRANSPORT_V6_FLAGS].value.uint32;
injectionHandle = g_pIPv6InboundTransportInjectionHandles[index];
if(protocol == ICMPV6)
bytesRetreated = ipHeaderSize;
else
bytesRetreated = ipHeaderSize + transportHeaderSize;
break;
}
case FWPS_LAYER_OUTBOUND_TRANSPORT_V4:
{
addressFamily = AF_INET;
protocol = pClassifyValues->incomingValue[FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_PROTOCOL].value.uint8;
pRemoteAddress = &(pClassifyValues->incomingValue[FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_REMOTE_ADDRESS].value.uint32);
flags = pClassifyValues->incomingValue[FWPS_FIELD_OUTBOUND_TRANSPORT_V4_FLAGS].value.uint32;
injectionHandle = g_pIPv4OutboundTransportInjectionHandles[index];
break;
}
case FWPS_LAYER_OUTBOUND_TRANSPORT_V6:
{
addressFamily = AF_INET6;
protocol = pClassifyValues->incomingValue[FWPS_FIELD_OUTBOUND_TRANSPORT_V6_IP_PROTOCOL].value.uint8;
pRemoteAddress = pClassifyValues->incomingValue[FWPS_FIELD_OUTBOUND_TRANSPORT_V6_IP_REMOTE_ADDRESS].value.byteArray16->byteArray16;
flags = pClassifyValues->incomingValue[FWPS_FIELD_OUTBOUND_TRANSPORT_V6_FLAGS].value.uint32;
injectionHandle = g_pIPv6OutboundTransportInjectionHandles[index];
break;
}
case FWPS_LAYER_DATAGRAM_DATA_V4:
{
addressFamily = AF_INET;
protocol = pClassifyValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_IP_PROTOCOL].value.uint8;
direction = (FWP_DIRECTION)pClassifyValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_DIRECTION].value.uint32;
flags = pClassifyValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_FLAGS].value.uint32;
if(direction == FWP_DIRECTION_INBOUND)
{
interfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_INTERFACE_INDEX].value.uint32;
subInterfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_SUB_INTERFACE_INDEX].value.uint32;
injectionHandle = g_pIPv4InboundTransportInjectionHandles[index];
bytesRetreated = ipHeaderSize + transportHeaderSize;
}
else
{
pRemoteAddress = &(pClassifyValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_IP_REMOTE_ADDRESS].value.uint32);
injectionHandle = g_pIPv4OutboundTransportInjectionHandles[index];
}
break;
}
case FWPS_LAYER_DATAGRAM_DATA_V6:
{
addressFamily = AF_INET6;
protocol = pClassifyValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V6_IP_PROTOCOL].value.uint8;
direction = (FWP_DIRECTION)pClassifyValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V6_DIRECTION].value.uint32;
flags = pClassifyValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V6_FLAGS].value.uint32;
if(direction == FWP_DIRECTION_INBOUND)
{
interfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V6_INTERFACE_INDEX].value.uint32;
subInterfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V6_SUB_INTERFACE_INDEX].value.uint32;
injectionHandle = g_pIPv6InboundTransportInjectionHandles[index];
bytesRetreated = ipHeaderSize + transportHeaderSize;
}
else
{
pRemoteAddress = pClassifyValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V6_IP_REMOTE_ADDRESS].value.byteArray16->byteArray16;
injectionHandle = g_pIPv6OutboundTransportInjectionHandles[index];
}
break;
}
case FWPS_LAYER_INBOUND_ICMP_ERROR_V4:
{
addressFamily = AF_INET;
protocol = ICMPV4;
interfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_ICMP_ERROR_V4_INTERFACE_INDEX].value.uint32;
subInterfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_ICMP_ERROR_V4_SUB_INTERFACE_INDEX].value.uint32;
flags = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_ICMP_ERROR_V4_FLAGS].value.uint32;
injectionHandle = g_pIPv4InboundTransportInjectionHandles[index];
bytesRetreated = ipHeaderSize + transportHeaderSize;
break;
}
case FWPS_LAYER_INBOUND_ICMP_ERROR_V6:
{
addressFamily = AF_INET6;
protocol = ICMPV6;
interfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_ICMP_ERROR_V6_INTERFACE_INDEX].value.uint32;
subInterfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_ICMP_ERROR_V6_SUB_INTERFACE_INDEX].value.uint32;
flags = pClassifyValues->incomingValue[FWPS_FIELD_INBOUND_ICMP_ERROR_V6_FLAGS].value.uint32;
injectionHandle = g_pIPv6InboundTransportInjectionHandles[index];
bytesRetreated = ipHeaderSize + transportHeaderSize;
break;
}
case FWPS_LAYER_OUTBOUND_ICMP_ERROR_V4:
{
addressFamily = AF_INET;
protocol = ICMPV4;
pRemoteAddress = &(pClassifyValues->incomingValue[FWPS_FIELD_OUTBOUND_ICMP_ERROR_V4_IP_REMOTE_ADDRESS].value.uint32);
flags = pClassifyValues->incomingValue[FWPS_FIELD_OUTBOUND_ICMP_ERROR_V4_FLAGS].value.uint32;
injectionHandle = g_pIPv4OutboundTransportInjectionHandles[index];
bytesRetreated = ipHeaderSize;
break;
}
case FWPS_LAYER_OUTBOUND_ICMP_ERROR_V6:
{
addressFamily = AF_INET6;
protocol = ICMPV6;
pRemoteAddress = pClassifyValues->incomingValue[FWPS_FIELD_OUTBOUND_ICMP_ERROR_V6_IP_REMOTE_ADDRESS].value.byteArray16->byteArray16;
flags = pClassifyValues->incomingValue[FWPS_FIELD_OUTBOUND_ICMP_ERROR_V6_FLAGS].value.uint32;
injectionHandle = g_pIPv6OutboundTransportInjectionHandles[index];
bytesRetreated = ipHeaderSize;
break;
}
case FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V4:
{
addressFamily = AF_INET;
protocol = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_PROTOCOL].value.uint8;
flags = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_FLAGS].value.uint32;
if(direction == FWP_DIRECTION_OUTBOUND)
{
pRemoteAddress = &(pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_REMOTE_ADDRESS].value.uint32);
injectionHandle = g_pIPv4OutboundTransportInjectionHandles[index];
}
else
{
interfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_INTERFACE_INDEX].value.uint32;
subInterfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_SUB_INTERFACE_INDEX].value.uint32;
injectionHandle = g_pIPv4InboundTransportInjectionHandles[index];
if(protocol == ICMPV4)
bytesRetreated = ipHeaderSize;
else
bytesRetreated = ipHeaderSize + transportHeaderSize;
}
break;
}
case FWPS_LAYER_ALE_AUTH_RECV_ACCEPT_V6:
{
addressFamily = AF_INET6;
protocol = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_IP_PROTOCOL].value.uint8;
flags = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_FLAGS].value.uint32;
if(direction == FWP_DIRECTION_OUTBOUND)
{
pRemoteAddress = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_IP_REMOTE_ADDRESS].value.byteArray16->byteArray16;
injectionHandle = g_pIPv6OutboundTransportInjectionHandles[index];
}
else
{
interfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_INTERFACE_INDEX].value.uint32;
subInterfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_SUB_INTERFACE_INDEX].value.uint32;
injectionHandle = g_pIPv6InboundTransportInjectionHandles[index];
if(protocol == ICMPV6)
bytesRetreated = ipHeaderSize;
else
bytesRetreated = ipHeaderSize + transportHeaderSize;
}
break;
}
case FWPS_LAYER_ALE_AUTH_CONNECT_V4:
{
addressFamily = AF_INET;
protocol = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_PROTOCOL].value.uint8;
flags = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_FLAGS].value.uint32;
bytesRetreated = ipHeaderSize + transportHeaderSize;
if(direction == FWP_DIRECTION_INBOUND)
{
interfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_INTERFACE_INDEX].value.uint32;
subInterfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_SUB_INTERFACE_INDEX].value.uint32;
injectionHandle = g_pIPv4InboundTransportInjectionHandles[index];
}
else
{
pRemoteAddress = &(pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_ADDRESS].value.uint32);
injectionHandle = g_pIPv4OutboundTransportInjectionHandles[index];
}
break;
}
case FWPS_LAYER_ALE_AUTH_CONNECT_V6:
{
addressFamily = AF_INET6;
protocol = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V6_IP_PROTOCOL].value.uint8;
flags = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V6_FLAGS].value.uint32;
bytesRetreated = ipHeaderSize + transportHeaderSize;
if(direction == FWP_DIRECTION_INBOUND)
{
interfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V6_INTERFACE_INDEX].value.uint32;
subInterfaceIndex = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V6_SUB_INTERFACE_INDEX].value.uint32;
injectionHandle = g_pIPv6InboundTransportInjectionHandles[index];
}
else
{
pRemoteAddress = pClassifyValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V6_IP_REMOTE_ADDRESS].value.byteArray16->byteArray16;
injectionHandle = g_pIPv6OutboundTransportInjectionHandles[index];
}
break;
}
case FWPS_LAYER_ALE_FLOW_ESTABLISHED_V4:
{
addressFamily = AF_INET;
protocol = pClassifyValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_PROTOCOL].value.uint8;
direction = (FWP_DIRECTION)pClassifyValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_DIRECTION].value.uint8;
flags = pClassifyValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_FLAGS].value.uint32;
if(direction == FWP_DIRECTION_INBOUND)
{
injectionHandle = g_pIPv4InboundTransportInjectionHandles[index];
if(ipHeaderSize == 0)
ipHeaderSize = IPV4_HEADER_MIN_SIZE;
if(transportHeaderSize == 0)
{
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;
}
if(protocol == ICMPV4)
bytesRetreated = ipHeaderSize;
else
bytesRetreated = ipHeaderSize + transportHeaderSize;
}
else
{
pRemoteAddress = &(pClassifyValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_IP_REMOTE_ADDRESS].value.uint32);
injectionHandle = g_pIPv4OutboundTransportInjectionHandles[index];
bytesRetreated = ipHeaderSize;
}
break;
}
case FWPS_LAYER_ALE_FLOW_ESTABLISHED_V6:
{
addressFamily = AF_INET6;
protocol = pClassifyValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_IP_PROTOCOL].value.uint8;
direction = (FWP_DIRECTION)pClassifyValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_DIRECTION].value.uint8;
flags = pClassifyValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_FLAGS].value.uint32;
if(direction == FWP_DIRECTION_INBOUND)
{
injectionHandle = g_pIPv6InboundTransportInjectionHandles[index];
if(ipHeaderSize == 0)
ipHeaderSize = IPV6_HEADER_MIN_SIZE;
if(transportHeaderSize == 0)
{
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(protocol == ICMPV6)
bytesRetreated = ipHeaderSize;
else
bytesRetreated = ipHeaderSize + transportHeaderSize;
}
else
{
pRemoteAddress = pClassifyValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_IP_REMOTE_ADDRESS].value.byteArray16->byteArray16;
injectionHandle = g_pIPv6OutboundTransportInjectionHandles[index];
bytesRetreated = ipHeaderSize;
}
break;
}
}
pClassifyOut->actionType = FWP_ACTION_PERMIT;
if(!((flags & FWP_CONDITION_FLAG_IS_LOOPBACK ||
(flags & FWP_CONDITION_FLAG_IS_IPSEC_SECURED &&
(flags & FWP_CONDITION_FLAG_REQUIRES_ALE_CLASSIFY ||
isALEClassifyRequired)))))
{
injectionState = FwpsQueryPacketInjectionState(injectionHandle,
(NET_BUFFER_LIST*)pNetBufferList,
&injectionContext);
if(injectionState != FWPS_PACKET_INJECTED_BY_SELF &&
injectionState != FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF)
{
/// Due to TCP's locking semantics, TCP can only be injected Out of Band at any
/// transport layer or equivalent.
if(protocol == TCP &&
(injectionHandle == g_pIPv4InboundTransportInjectionHandles[index] ||
injectionHandle == g_pIPv6InboundTransportInjectionHandles[index] ||
injectionHandle == g_pIPv4OutboundTransportInjectionHandles[index] ||
injectionHandle == g_pIPv6OutboundTransportInjectionHandles[index]))
HLPR_BAIL;
pClassifyOut->actionType = FWP_ACTION_BLOCK;
pClassifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB;
pClassifyOut->rights ^= FWPS_RIGHT_ACTION_WRITE;
if(bytesRetreated)
{
status = NdisRetreatNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pNetBufferList),
bytesRetreated,
0,
0);
HLPR_BAIL_ON_FAILURE(status);
}
status = FwpsAllocateCloneNetBufferList((NET_BUFFER_LIST*)pNetBufferList,
g_pNDISPoolData->nblPoolHandle,
g_pNDISPoolData->nbPoolHandle,
0,
&pClonedNetBufferList);
if(bytesRetreated)
NdisAdvanceNetBufferDataStart(NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pNetBufferList),
bytesRetreated,
FALSE,
0);
HLPR_BAIL_ON_FAILURE(status);
if(injectionHandle == g_pIPv4InboundNetworkInjectionHandles[index] ||
injectionHandle == g_pIPv6InboundNetworkInjectionHandles[index])
status = FwpsInjectNetworkReceiveAsync(injectionHandle,
injectionContext,
0,
compartmentID,
interfaceIndex,
subInterfaceIndex,
pClonedNetBufferList,
CompleteFastPacketInjection,
0);
else if(injectionHandle == g_pIPv4OutboundNetworkInjectionHandles[index] ||
injectionHandle == g_pIPv6OutboundNetworkInjectionHandles[index])
status = FwpsInjectNetworkSendAsync(injectionHandle,
injectionContext,
0,
compartmentID,
pClonedNetBufferList,
CompleteFastPacketInjection,
0);
else if(injectionHandle == g_pIPv4InboundForwardInjectionHandles[index] ||
injectionHandle == g_pIPv6InboundForwardInjectionHandles[index] ||
injectionHandle == g_pIPv4OutboundForwardInjectionHandles[index] ||
injectionHandle == g_pIPv6OutboundForwardInjectionHandles[index])
status = FwpsInjectForwardAsync(injectionHandle,
injectionContext,
0,
addressFamily,
compartmentID,
interfaceIndex,
pClonedNetBufferList,
CompleteFastPacketInjection,
0);
else if(injectionHandle == g_pIPv4InboundTransportInjectionHandles[index] ||
injectionHandle == g_pIPv6InboundTransportInjectionHandles[index])
status = FwpsInjectTransportReceiveAsync(injectionHandle,
injectionContext,
0,
0,
addressFamily,
compartmentID,
interfaceIndex,
subInterfaceIndex,
pClonedNetBufferList,
CompleteFastPacketInjection,
0);
else if(injectionHandle == g_pIPv4OutboundTransportInjectionHandles[index] ||
injectionHandle == g_pIPv6OutboundTransportInjectionHandles[index])
{
FWPS_TRANSPORT_SEND_PARAMS* pSendParams = 0;
UINT32 addressSize = addressFamily == AF_INET ? IPV4_ADDRESS_SIZE : IPV6_ADDRESS_SIZE;
#pragma warning(push)
#pragma warning(disable: 6014) /// pSendParams will be freed in completionFn using FastPacketInjectionCompletionDataDestroy
HLPR_NEW(pSendParams,
FWPS_TRANSPORT_SEND_PARAMS,
WFPSAMPLER_CALLOUT_DRIVER_TAG);
HLPR_BAIL_ON_ALLOC_FAILURE_2(pSendParams,
status);
HLPR_NEW_ARRAY(pSendParams->remoteAddress,
BYTE,
addressSize,
WFPSAMPLER_CALLOUT_DRIVER_TAG);
HLPR_BAIL_ON_ALLOC_FAILURE_2(pSendParams->remoteAddress,
status);
#pragma warning(pop)
if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata,
FWPS_METADATA_FIELD_TRANSPORT_CONTROL_DATA))
{
pSendParams->controlData = pMetadata->controlData;
pSendParams->controlDataLength = pMetadata->controlDataLength;
}
if(addressFamily == AF_INET)
{
UINT32 remoteAddress = *((UINT32*)pRemoteAddress);
remoteAddress = ntohl(remoteAddress);
RtlCopyMemory(pSendParams->remoteAddress,
&remoteAddress,
addressSize);
}
else
{
RtlCopyMemory(pSendParams->remoteAddress,
pRemoteAddress,
addressSize);
if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata,
FWPS_METADATA_FIELD_REMOTE_SCOPE_ID))
pSendParams->remoteScopeId = pMetadata->remoteScopeId;
}
status = FwpsInjectTransportSendAsync(injectionHandle,
injectionContext,
endpointHandle,
0,
pSendParams,
addressFamily,
compartmentID,
pClonedNetBufferList,
CompleteFastPacketInjection,
pSendParams);
HLPR_BAIL_LABEL_2:
if(status != STATUS_SUCCESS)
{
#pragma warning(push)
#pragma warning(disable: 28924) /// pSendParams could be NULL if the ALLOC fails
if(pSendParams)
{
HLPR_DELETE_ARRAY(pSendParams->remoteAddress,
WFPSAMPLER_CALLOUT_DRIVER_TAG);
}
HLPR_DELETE(pSendParams,
WFPSAMPLER_CALLOUT_DRIVER_TAG);
#pragma warning(pop)
}
}
HLPR_BAIL_LABEL:
if(status != STATUS_SUCCESS)
{
if(pClonedNetBufferList)
FwpsFreeCloneNetBufferList(pClonedNetBufferList,
0);
DbgPrintEx(DPFLTR_IHVNETWORK_ID,
DPFLTR_ERROR_LEVEL,
" !!!! ClassifyFastPacketInjection : FwpsInjectAsync() [status: %#x]\n",
status);
}
}
}
}
return;}