high performance filtering

Home Forums Discussions Support Portal high performance filtering

This topic contains 2 replies, has 2 voices, and was last updated by  Vadim Smirnov 7 years, 3 months ago.

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #5318

    asmercer2004
    Participant

    Greetings,

    I am using the winpkfilter libraries to develop an application that will do the following:

    Look for udp communications on certain udp ports (only do stuff when something is on these ports).
    Append a 16 byte header (2 doubles for gps data) to outgoing data packets on those udp ports.
    Strip the header off of incoming data packets on those udp ports.

    I tried modifying the passthru application to do this. I first pulled off the ethernet header and if it wasn’t an IP packet I just forwarded it along. Then I looked for udp packets and if not then forwarded. Then I looked for my port range and did the same. I was then able to add/strip the gps header from the packet. This program worked fine for small to moderate amounts of network traffic. Once you got more traffic however (in our case we’re looking at 400k to 500k incoming packets per second), communications such as PING packets, UltraVNC remote desktoping, plink remote commands, etc tend to not work. Is there a more efficient way of doing what I need? Are filters faster (I didnt’ really understand the filter example). I’m also using C# to do this.

    #6910

    asmercer2004
    Participant

    OK here is the code I came up with for setting up the filters.

    void SetUpFilters()
    {
    pFilters.m_TableSize = 7;

    pFilters.m_StaticFilters = new STATIC_FILTER[7];

    //****************************************************************************************
    // 1. REDIRECT OUT UDP packets with source PORT 34401
    // Common values
    pFilters.m_StaticFilters[0].m_Adapter = 0; // applied to all adapters
    pFilters.m_StaticFilters[0].m_ValidFields = Ndisapi.NETWORK_LAYER_VALID | Ndisapi.TRANSPORT_LAYER_VALID;
    pFilters.m_StaticFilters[0].m_FilterAction = Ndisapi.FILTER_PACKET_REDIRECT;
    pFilters.m_StaticFilters[0].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_SEND;

    // Network layer filter
    pFilters.m_StaticFilters[0].m_NetworkFilter.m_dwUnionSelector = Ndisapi.IPV4;
    pFilters.m_StaticFilters[0].m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V4_FILTER_PROTOCOL;
    pFilters.m_StaticFilters[0].m_NetworkFilter.m_IPv4.m_Protocol = IPHeader.IPPROTO_UDP;

    // Transport layer filter
    pFilters.m_StaticFilters[0].m_TransportFilter.m_dwUnionSelector = Ndisapi.TCPUDP;
    pFilters.m_StaticFilters[0].m_TransportFilter.m_TcpUdp.m_ValidFields = Ndisapi.TCPUDP_DEST_PORT;
    pFilters.m_StaticFilters[0].m_TransportFilter.m_TcpUdp.m_DestPort.m_StartRange = 34401;
    pFilters.m_StaticFilters[0].m_TransportFilter.m_TcpUdp.m_DestPort.m_EndRange = 34401;

    //****************************************************************************************
    // 2. REDIRECT IN UDP packets with source PORT 34401
    // Common values
    pFilters.m_StaticFilters[1].m_Adapter = 0; // applied to all adapters
    pFilters.m_StaticFilters[1].m_ValidFields = Ndisapi.NETWORK_LAYER_VALID | Ndisapi.TRANSPORT_LAYER_VALID;
    pFilters.m_StaticFilters[1].m_FilterAction = Ndisapi.FILTER_PACKET_REDIRECT;
    pFilters.m_StaticFilters[1].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_RECEIVE;

    // Network layer filter
    pFilters.m_StaticFilters[1].m_NetworkFilter.m_dwUnionSelector = Ndisapi.IPV4;
    pFilters.m_StaticFilters[1].m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V4_FILTER_PROTOCOL;
    pFilters.m_StaticFilters[1].m_NetworkFilter.m_IPv4.m_Protocol = IPHeader.IPPROTO_UDP;

    // Transport layer filter
    pFilters.m_StaticFilters[1].m_TransportFilter.m_dwUnionSelector = Ndisapi.TCPUDP;
    pFilters.m_StaticFilters[1].m_TransportFilter.m_TcpUdp.m_ValidFields = Ndisapi.TCPUDP_SRC_PORT;
    pFilters.m_StaticFilters[1].m_TransportFilter.m_TcpUdp.m_SourcePort.m_StartRange = 34401;
    pFilters.m_StaticFilters[1].m_TransportFilter.m_TcpUdp.m_SourcePort.m_EndRange = 34401;

    //****************************************************************************************
    // 3. REDIRECT OUT UDP packets with source PORT 34402
    // Common values
    pFilters.m_StaticFilters[2].m_Adapter = 0; // applied to all adapters
    pFilters.m_StaticFilters[2].m_ValidFields = Ndisapi.NETWORK_LAYER_VALID | Ndisapi.TRANSPORT_LAYER_VALID;
    pFilters.m_StaticFilters[2].m_FilterAction = Ndisapi.FILTER_PACKET_REDIRECT;
    pFilters.m_StaticFilters[2].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_SEND;

    // Network layer filter
    pFilters.m_StaticFilters[2].m_NetworkFilter.m_dwUnionSelector = Ndisapi.IPV4;
    pFilters.m_StaticFilters[2].m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V4_FILTER_PROTOCOL;
    pFilters.m_StaticFilters[2].m_NetworkFilter.m_IPv4.m_Protocol = IPHeader.IPPROTO_UDP;

    // Transport layer filter
    pFilters.m_StaticFilters[2].m_TransportFilter.m_dwUnionSelector = Ndisapi.TCPUDP;
    pFilters.m_StaticFilters[2].m_TransportFilter.m_TcpUdp.m_ValidFields = Ndisapi.TCPUDP_DEST_PORT;
    pFilters.m_StaticFilters[2].m_TransportFilter.m_TcpUdp.m_DestPort.m_StartRange = 34402;
    pFilters.m_StaticFilters[2].m_TransportFilter.m_TcpUdp.m_DestPort.m_EndRange = 34402;

    //****************************************************************************************
    // 4. REDIRECT IN UDP packets with source PORT 34402
    // Common values
    pFilters.m_StaticFilters[3].m_Adapter = 0; // applied to all adapters
    pFilters.m_StaticFilters[3].m_ValidFields = Ndisapi.NETWORK_LAYER_VALID | Ndisapi.TRANSPORT_LAYER_VALID;
    pFilters.m_StaticFilters[3].m_FilterAction = Ndisapi.FILTER_PACKET_REDIRECT;
    pFilters.m_StaticFilters[3].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_RECEIVE;

    // Network layer filter
    pFilters.m_StaticFilters[3].m_NetworkFilter.m_dwUnionSelector = Ndisapi.IPV4;
    pFilters.m_StaticFilters[3].m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V4_FILTER_PROTOCOL;
    pFilters.m_StaticFilters[3].m_NetworkFilter.m_IPv4.m_Protocol = IPHeader.IPPROTO_UDP;

    // Transport layer filter
    pFilters.m_StaticFilters[3].m_TransportFilter.m_dwUnionSelector = Ndisapi.TCPUDP;
    pFilters.m_StaticFilters[3].m_TransportFilter.m_TcpUdp.m_ValidFields = Ndisapi.TCPUDP_SRC_PORT;
    pFilters.m_StaticFilters[3].m_TransportFilter.m_TcpUdp.m_SourcePort.m_StartRange = 34402;
    pFilters.m_StaticFilters[3].m_TransportFilter.m_TcpUdp.m_SourcePort.m_EndRange = 34402;

    //****************************************************************************************
    // 5. REDIRECT OUT UDP packets with source PORT 34403
    // Common values
    pFilters.m_StaticFilters[4].m_Adapter = 0; // applied to all adapters
    pFilters.m_StaticFilters[4].m_ValidFields = Ndisapi.NETWORK_LAYER_VALID | Ndisapi.TRANSPORT_LAYER_VALID;
    pFilters.m_StaticFilters[4].m_FilterAction = Ndisapi.FILTER_PACKET_REDIRECT;
    pFilters.m_StaticFilters[4].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_SEND;

    // Network layer filter
    pFilters.m_StaticFilters[4].m_NetworkFilter.m_dwUnionSelector = Ndisapi.IPV4;
    pFilters.m_StaticFilters[4].m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V4_FILTER_PROTOCOL;
    pFilters.m_StaticFilters[4].m_NetworkFilter.m_IPv4.m_Protocol = IPHeader.IPPROTO_UDP;

    // Transport layer filter
    pFilters.m_StaticFilters[4].m_TransportFilter.m_dwUnionSelector = Ndisapi.TCPUDP;
    pFilters.m_StaticFilters[4].m_TransportFilter.m_TcpUdp.m_ValidFields = Ndisapi.TCPUDP_DEST_PORT;
    pFilters.m_StaticFilters[4].m_TransportFilter.m_TcpUdp.m_DestPort.m_StartRange = 34403;
    pFilters.m_StaticFilters[4].m_TransportFilter.m_TcpUdp.m_DestPort.m_EndRange = 34403;

    //****************************************************************************************
    // 6. REDIRECT IN UDP packets with source PORT 34403
    // Common values
    pFilters.m_StaticFilters[5].m_Adapter = 0; // applied to all adapters
    pFilters.m_StaticFilters[5].m_ValidFields = Ndisapi.NETWORK_LAYER_VALID | Ndisapi.TRANSPORT_LAYER_VALID;
    pFilters.m_StaticFilters[5].m_FilterAction = Ndisapi.FILTER_PACKET_REDIRECT;
    pFilters.m_StaticFilters[5].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_RECEIVE;

    // Network layer filter
    pFilters.m_StaticFilters[5].m_NetworkFilter.m_dwUnionSelector = Ndisapi.IPV4;
    pFilters.m_StaticFilters[5].m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V4_FILTER_PROTOCOL;
    pFilters.m_StaticFilters[5].m_NetworkFilter.m_IPv4.m_Protocol = IPHeader.IPPROTO_UDP;

    // Transport layer filter
    pFilters.m_StaticFilters[5].m_TransportFilter.m_dwUnionSelector = Ndisapi.TCPUDP;
    pFilters.m_StaticFilters[5].m_TransportFilter.m_TcpUdp.m_ValidFields = Ndisapi.TCPUDP_SRC_PORT;
    pFilters.m_StaticFilters[5].m_TransportFilter.m_TcpUdp.m_SourcePort.m_StartRange = 34403;
    pFilters.m_StaticFilters[5].m_TransportFilter.m_TcpUdp.m_SourcePort.m_EndRange = 34403;

    //***************************************************************************************
    // 7. Pass all packets (skipped by previous filters) without processing in user mode
    // Common values
    pFilters.m_StaticFilters[6].m_Adapter = 0; // applied to all adapters
    pFilters.m_StaticFilters[6].m_ValidFields = 0;
    pFilters.m_StaticFilters[6].m_FilterAction = Ndisapi.FILTER_PACKET_PASS;
    pFilters.m_StaticFilters[6].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_RECEIVE | Ndisapi.PACKET_FLAG_ON_SEND;
    }

    and then in my Run function I call the following:

    // set up packet filters
    SetUpFilters();
    Ndisapi.SetPacketFilterTable(hNdisapi, ref pFilters);

    When i do this i get the following error:
    Type could not be marshaled because the length of an embedded array instance does not match the declared length in the layout. Any idea what could be causing this?

    #6911

    Vadim Smirnov
    Moderator

    Yes, filters allow you to reduce the number of packets indicated to user mode for processing thus improving overall performance.

    Note, that only unmanaged block of memory can be passed to WinpkFilter driver. To simplify marshalling STATIC_FILTER_TABLE for C# is declared to contain fixed size array of filters (256).


    //
    // Static filters table to be passed to WinpkFilter driver
    //
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct STATIC_FILTER_TABLE
    {
    public uint m_TableSize; // number of STATIC_FILTER entries
    [MarshalAs(UnmanagedType.ByValArray,SizeConst=256)] // For convinience (easier marshalling to unmanaged memory) the size of the array is fixed to 256 entries
    public STATIC_FILTER[] m_StaticFilters; // Feel free to change this value if you need more filter entries
    }

    So in order to fix the marshalling error you have to change your code like this:


    pFilters.m_TableSize = 7;

    pFilters.m_StaticFilters = new STATIC_FILTER[256];

    You pass 256 filters to drivers but only 7 are valid as indicated by pFilters.m_TableSize

Viewing 3 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.