Home › Forums › Discussions › Support › high performance filtering
- This topic has 2 replies, 2 voices, and was last updated 14 years, 10 months ago by Vadim Smirnov.
-
AuthorPosts
-
January 19, 2010 at 4:52 pm #5318
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.
January 19, 2010 at 6:36 pm #6910OK 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?January 20, 2010 at 12:28 pm #6911Yes, 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
-
AuthorPosts
- You must be logged in to reply to this topic.