使用WFP做转发,将流量转发到localhost的某个端口上

FWPM_LAYER_ALE_CONNECT_REDIRECT 在这一层做转发。

VOID NTAPI
ALEConnectRedirectClassifyFn(
    IN const FWPS_INCOMING_VALUES  *inFixedValues,
    IN const FWPS_INCOMING_METADATA_VALUES  *inMetaValues,
    IN OUT VOID  *layerData,
    _In_opt_ const void* classifyContext,
    IN const FWPS_FILTER *filter,
    IN UINT64  flowContext,
    IN OUT FWPS_CLASSIFY_OUT *classifyOut
) {
    UINT64 classifyHandle = 0;
    NTSTATUS status;
    FWPS_CONNECT_REQUEST0* connectRequest;

    UNREFERENCED_PARAMETER(inFixedValues);
    UNREFERENCED_PARAMETER(flowContext);
    UNREFERENCED_PARAMETER(layerData);

    status = FwpsAcquireClassifyHandle((void*)classifyContext, (UINT32)0, &classifyHandle);
    if (!NT_SUCCESS(status)) {
        log("SMBRedirect: Failure to aquire classify handle.\n");
        goto Fail;
    }

#if(NTDDI_VERSION >= NTDDI_WIN8)
    FWPS_CONNECTION_REDIRECT_STATE redirectState = FwpsQueryConnectionRedirectState(
        inMetaValues->redirectRecords,
        redirectHandle,
        NULL
    );
    if (redirectState != FWPS_CONNECTION_NOT_REDIRECTED) {
        log("SMBRedirect: Connection was already redirected (presumably by us). Ignoring it.\n");
        goto Exit;
    }
#else
    UNREFERENCED_PARAMETER(inMetaValues);
#endif

    status = FwpsAcquireWritableLayerDataPointer(classifyHandle, filter->filterId, 0, &connectRequest, classifyOut);
    if (!NT_SUCCESS(status)) {
        log("SMBRedirect: Failure to aquire classify handle.\n");
        goto Fail;
    }

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

    UINT32 localAddrIp = localAddr->sin_addr.S_un.S_addr;
    UINT16 localAddrPort = localAddr->sin_port;
    UINT32 remoteAddrIp = remoteAddr->sin_addr.S_un.S_addr;
    UINT16 remoteAddrPort = remoteAddr->sin_port;
    log("SMBRedirect: In ALEConnectRedirectClassifyFn, intercepting connection from %08x:%d to %08x:%d.\n",
        ntohl(localAddrIp), ntohs(localAddrPort), ntohl(remoteAddrIp),ntohs(remoteAddrPort));

    int port = ntohs(remoteAddr->sin_port);
    if (port == PORT_1) {
        remoteAddr->sin_port = htons(PORT_2);
        log("SMBRedirect: Redirecting connection from port %d to %d.\n", PORT_1, PORT_2);
    }

#if(NTDDI_VERSION >= NTDDI_WIN8)
    connectRequest->localRedirectHandle = redirectHandle;
#endif

    connectRequest->localRedirectTargetPID = 0xFFFF;
    FwpsApplyModifiedLayerData(classifyHandle, connectRequest,0);
Exit:
    if (classifyHandle != 0) {
        FwpsReleaseClassifyHandle(classifyHandle);
    }
    return;
Fail:
    goto Exit;
}

参考:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/4e005df1-7e10-46e9-b1dc-29df842adf90/understanding-fwpmlayeraleconnectredirect?forum=wfp

https://docs.microsoft.com/en-us/windows-hardware/drivers/network/using-bind-or-connect-redirection?redirectedfrom=MSDN

你可能感兴趣的:(使用WFP做转发,将流量转发到localhost的某个端口上)