A question about FWPS_FIELD_ALE_CONNECT_REDIRECT_V4_IP_PROTOCOL in WFP

Hello everyone!
I have a question about WFP that I’ve been looking for for a long time and can’t find an answer, I hope to get an answer here.
I want to get the protocol number of the transport layer in the callback function of the FWPM_LAYER_ALE_CONNECT_REDIRECT_V4 filter layer, such as: TCP=6 or UDP=17, but I can’t seem to get them.
I tried to get them with: inFixedValues->incomingValue[FWPS_FIELD_ALE_CONNECT_REDIRECT_V4_IP_PROTOCOL].value.uint16 in the callback function, but couldn’t get the correct answer.
The sample code is as follows:

VOID NTAPI AleConnectRedirectFn(
	IN const FWPS_INCOMING_VALUES* inFixedValues,
	IN const FWPS_INCOMING_METADATA_VALUES* inMetaValues,
	IN OUT VOID* layerData,
	IN const void* classifyContext,
	IN const FWPS_FILTER* filter,
	IN UINT64  flowContext,
	IN OUT FWPS_CLASSIFY_OUT* classifyOut
) {
	UINT64 classifyHandle = 0;
	NTSTATUS status;
	FWPS_CONNECT_REQUEST* connectRequest;
	ULONG  localIp, remoteIp;
	UINT16 localPort, remotePort;
	HANDLE redirectHandle = NULL;
	KIRQL currentIrql = KeGetCurrentIrql();
	UINT64 processId = 0;
	UNICODE_STRING ipV4;
	UINT16 protocol = 0;
	UCHAR* processName = NULL;

	SOCKADDR_IN* remoteAddr = NULL;
	SOCKADDR_IN* localAddr = NULL;

	UINT32 localAddrIp = 0;
	UINT16 localAddrPort = 0;
	UINT32 remoteAddrIp = 0;
	UINT16 remoteAddrPort = 0;

	if (!FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_PROCESS_ID)) {
		DbgPrint("AleConnectRedirectFn::persent FWPS_METADATA_FIELD_PROCESS_ID fail.\n");
		goto Exit;
	}

    //GetProcessName
	processId = inMetaValues->processId;
	processName = GetProcessNameByProcessId(processId);

	if (processName == NULL) {
		DbgPrint("AleConnectRedirectFn::GetProcessNameByProcessId is NULL.\n");
		goto Exit;
	}

	//MatchProcessName
	if (!MatchProcessName(processName, g_pWfpGlobal->config.redirectProcessName)) {
		classifyOut->actionType = FWP_ACTION_PERMIT;
		goto Exit;
	}

	DbgPrint("AleConnectRedirectFn::Filer processName=%s\n",processName);

#if(NTDDI_VERSION >= NTDDI_WIN8)
    //do something...
#endif

	status = FwpsAcquireClassifyHandle((void*)classifyContext, (UINT32)0, &classifyHandle);

	if (!NT_SUCCESS(status)) {
		DbgPrint("AleConnectRedirectFn::Failure to aquire classify handle.\n");
		goto Exit;
	}

	status = FwpsAcquireWritableLayerDataPointer(classifyHandle, filter->filterId, 0, &connectRequest, classifyOut);

	if (!NT_SUCCESS(status)) {
		DbgPrint("AleConnectRedirectFn::Failure to aquire classify handle.\n");
		goto Exit;
	}

	remoteAddr = (SOCKADDR_IN*)&connectRequest->remoteAddressAndPort;
	localAddr = (SOCKADDR_IN*)&connectRequest->localAddressAndPort;

	localAddrIp = localAddr->sin_addr.S_un.S_addr;
	localAddrPort = localAddr->sin_port;
	remoteAddrIp = remoteAddr->sin_addr.S_un.S_addr;//remote ip
	remoteAddrPort = remoteAddr->sin_port;//remote port

	//......
	
	protocol = inFixedValues->incomingValue[FWPS_FIELD_ALE_CONNECT_REDIRECT_V4_IP_PROTOCOL].value.uint16; //**The correct protocol number cannot be obtained here**
	
	//do something ......

thank you very much!

Hi,
did you try this?
if (inFixedValues->incomingValue[FWPS_FIELD_ALE_CONNECT_REDIRECT_V4_IP_PROTOCOL].value.uint8 == IPPROTO_UDP)
{
.
.
.

1 Like

@sennin said:
Hi,
did you try this?
if (inFixedValues->incomingValue[FWPS_FIELD_ALE_CONNECT_REDIRECT_V4_IP_PROTOCOL].value.uint8 == IPPROTO_UDP)
{
.
.
.

Wow, I’m so happy that using uint8 actually gets the correct result, which is pretty cool! Thank you very much for your reply.
In addition, I found that using protocol = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_PROTOCOL].value.uint16 in the callback function of the FWPM_LAYER_ALE_AUTH_CONNECT_V4 layer can get the correct data, which makes me a little confused, is this data type uint8 or uint16?

@liangdodo said:

@sennin said:
Hi,
did you try this?
if (inFixedValues->incomingValue[FWPS_FIELD_ALE_CONNECT_REDIRECT_V4_IP_PROTOCOL].value.uint8 == IPPROTO_UDP)
{
.
.
.

Wow, I’m so happy that using uint8 actually gets the correct result, which is pretty cool! Thank you very much for your reply.
In addition, I found that using protocol = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_PROTOCOL].value.uint16 in the callback function of the FWPM_LAYER_ALE_AUTH_CONNECT_V4 layer can get the correct data, which makes me a little confused, is this data type uint8 or uint16?

hxxps://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/shared/fwpstypes.idl#L367

1 Like

@sennin Thanks my friend, nice to meet you, I am a beginner, please advise :smiley: .

I don’t know why he shrouded the link. He’s trying to point you to the include file for that structure, which shows the data types:
https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/shared/fwpstypes.idl#L367
Always go to the source when you can.

@Tim_Roberts He may have made a typo, I saw this document, thank you very much for the correction.