Hello all,
I am writing a WFP driver which updates the source IP address and destination IP address and port.
I have written a filter on layer FWPM_LAYER_ALE_BIND_REDIRECT_V4 and FWPM_LAYER_ALE_CONNECT_REDIRECT_V4 to update source IP and destination IP address.
When I used FWPM_LAYER_ALE_BIND_REDIRECT_V4 the source IP is getting successfully updated.
Also at FWPM_LAYER_ALE_CONNECT_REDIRECT_V4 layer destination, IP and port are getting updated.
But when I tried to use both layers to update the source IP and destination IP and port then only the source IP is getting updated.
Following is the implementation I am doing for redirection.
Update the source IP
UINT64 classifyHandle = 0;
NTSTATUS status = FwpsAcquireClassifyHandle0(
(void*)classifyContext,
(UINT32)0,
&classifyHandle
);
if (!NT_SUCCESS(status))
{
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_NDE_ERROR_LEVEL, "Could not get the classify handle %x\r\n", status);
return;
}
FWPS_BIND_REQUEST0* writableLayerData = NULL;
status = FwpsAcquireWritableLayerDataPointer(
classifyHandle,
filter->filterId,
0,
(PVOID*)&writableLayerData,
classifyOut
);
if (!NT_SUCCESS(status))
{
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_NDE_ERROR_LEVEL, "FwpsAcquireWritableLayerDataPointer Failed %x\r\n", status);
return;
}
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_NDE_DEBUG_LEVEL, "Updating the source ip address for PID : %llu\r\n", inMetaValues->processId);
SOCKADDR_IN* sourceAddr = (SOCKADDR_IN*)(&(writableLayerData->localAddressAndPort));
if (sourceAddr == NULL)
{
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_NDE_ERROR_LEVEL, "socket address is NULL\r\n");
goto Exit;
}
sourceAddr->sin_addr.S_un.S_addr = RtlUlongByteSwap(*(unsigned long*)&newIP);
classifyOut->actionType = FWP_ACTION_PERMIT;
FwpsApplyModifiedLayerData(
classifyHandle,
writableLayerData,
0);
Exit:
FwpsReleaseClassifyHandle(classifyHandle);
Update the destination IP and port
NTSTATUS status = FwpsAcquireClassifyHandle0(
(void*)classifyContext,
(UINT32)0,
&classifyHandle
);
if (!NT_SUCCESS(status))
{
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_NDE_ERROR_LEVEL, "FwpsAcquireClassifyHandle0 Failed %x\r\n", status);
return;
}
FWPS_CONNECT_REQUEST* writableLayerData = NULL;
status = FwpsAcquireWritableLayerDataPointer(
classifyHandle,
filter->filterId,
0,
(PVOID*)&writableLayerData,
classifyOut
);
if (!NT_SUCCESS(status))
{
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_NDE_ERROR_LEVEL, "FwpsAcquireWritableLayerDataPointer Failed %x\r\n", status);
return;
}
SOCKADDR_IN* remoteAddr = (SOCKADDR_IN*)(&(writableLayerData->remoteAddressAndPort));
if (remoteAddr == NULL)
{
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_NDE_ERROR_LEVEL, "socket address is NULL\r\n");
goto Exit;
}
remoteAddr->sin_port = ConvertPortNumber(newPort);
writableLayerData->localRedirectTargetPID = (DWORD)procesID;
remoteAddr->sin_addr.S_un.S_addr = RtlUlongByteSwap(*(unsigned long*)&new_destination_ip);
//PROVPN_FOR_WIN8
#if (NTDDI_VERSION >= NTDDI_WIN8)
if (inFixedValues->layerId == FWPS_LAYER_ALE_CONNECT_REDIRECT_V4)
writableLayerData->localRedirectHandle = gRedirectConnectHandlev4;
else if (inFixedValues->layerId == FWPS_LAYER_ALE_CONNECT_REDIRECT_V6)
writableLayerData->localRedirectHandle = gRedirectConnectHandlev6;
writableLayerData->localRedirectContext = NULL;
writableLayerData->localRedirectContextSize = 0;
#endif
classifyOut->actionType = FWP_ACTION_PERMIT;
FwpsApplyModifiedLayerData(
classifyHandle,
writableLayerData,
0
);
Exit:
FwpsReleaseClassifyHandle(classifyHandle);
Please let me know what changes I need to do to make the source and destination update work on the same packet.
Thanks,
Chetan