Home › Forums › Discussions › Support › Implementing filter functionality in C# › Re: Re: Implementing filter functionality in C#
So I came up with somewhat of a solution to the post above, after heavy experimentation:
Here is the C# version of the 2nd case in filter.cpp – process port 80, pass everything else:
var filter1 = new STATIC_FILTER();
filter1.m_Adapter = 0;
filter1.m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_SEND;
filter1.m_FilterAction = Ndisapi.FILTER_PACKET_REDIRECT;
filter1.m_ValidFields = Ndisapi.NETWORK_LAYER_VALID | Ndisapi.TRANSPORT_LAYER_VALID;
// Network layer filter
filter1.m_NetworkFilter.m_dwUnionSelector = Ndisapi.IPV4;
filter1.m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V4_FILTER_PROTOCOL;
filter1.m_NetworkFilter.m_IPv4.m_Protocol = 6;
// Transport layer filter
filter1.m_TransportFilter.m_dwUnionSelector = Ndisapi.TCPUDP;
filter1.m_TransportFilter.m_TcpUdp.m_ValidFields = Ndisapi.TCPUDP_DEST_PORT;
filter1.m_TransportFilter.m_TcpUdp.m_DestPort.m_StartRange = 80; // HTTP
filter1.m_TransportFilter.m_TcpUdp.m_DestPort.m_EndRange = 80t;
var filter2 = new STATIC_FILTER();
filter2.m_Adapter = 0;
filter2.m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_RECEIVE;
filter2.m_FilterAction = Ndisapi.FILTER_PACKET_REDIRECT;
filter2.m_ValidFields = Ndisapi.NETWORK_LAYER_VALID | Ndisapi.TRANSPORT_LAYER_VALID;
// Network layer filter
filter2.m_NetworkFilter.m_dwUnionSelector = Ndisapi.IPV4;
filter2.m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V4_FILTER_PROTOCOL;
filter2.m_NetworkFilter.m_IPv4.m_Protocol = 6;
// Transport layer filter
filter2.m_TransportFilter.m_dwUnionSelector = Ndisapi.TCPUDP;
filter2.m_TransportFilter.m_TcpUdp.m_ValidFields = Ndisapi.TCPUDP_SRC_PORT;
filter2.m_TransportFilter.m_TcpUdp.m_DestPort.m_StartRange = 80; // HTTP
filter2.m_TransportFilter.m_TcpUdp.m_DestPort.m_EndRange = 80;
/// IPV6
///
var filter3 = new STATIC_FILTER();
filter3.m_Adapter = 0;
filter3.m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_SEND;
filter3.m_FilterAction = Ndisapi.FILTER_PACKET_REDIRECT;
filter3.m_ValidFields = Ndisapi.NETWORK_LAYER_VALID | Ndisapi.TRANSPORT_LAYER_VALID;
// Network layer filter
filter3.m_NetworkFilter.m_dwUnionSelector = Ndisapi.IPV6;
filter3.m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V6_FILTER_PROTOCOL;
filter3.m_NetworkFilter.m_IPv4.m_Protocol = 6;
// Transport layer filter
filter3.m_TransportFilter.m_dwUnionSelector = Ndisapi.TCPUDP;
filter3.m_TransportFilter.m_TcpUdp.m_ValidFields = Ndisapi.TCPUDP_DEST_PORT;
filter3.m_TransportFilter.m_TcpUdp.m_DestPort.m_StartRange = 80; // HTTP
filter3.m_TransportFilter.m_TcpUdp.m_DestPort.m_EndRange = 80;
var filter4 = new STATIC_FILTER();
filter4.m_Adapter = 0;
filter4.m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_RECEIVE;
filter4.m_FilterAction = Ndisapi.FILTER_PACKET_REDIRECT;
filter4.m_ValidFields = Ndisapi.NETWORK_LAYER_VALID | Ndisapi.TRANSPORT_LAYER_VALID;
// Network layer filter
filter4.m_NetworkFilter.m_dwUnionSelector = Ndisapi.IPV6;
filter4.m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V6_FILTER_PROTOCOL;
filter4.m_NetworkFilter.m_IPv4.m_Protocol = 6;
// Transport layer filter
filter4.m_TransportFilter.m_dwUnionSelector = Ndisapi.TCPUDP;
filter4.m_TransportFilter.m_TcpUdp.m_ValidFields = Ndisapi.TCPUDP_SRC_PORT;
filter4.m_TransportFilter.m_TcpUdp.m_DestPort.m_StartRange = 80; // HTTP
filter4.m_TransportFilter.m_TcpUdp.m_DestPort.m_EndRange = 80;
var filter5 = new STATIC_FILTER();
//filter5.m_Adapter.QuadPart = 0; // applied to all adapters
filter5.m_Adapter = 0;
filter5.m_ValidFields = 0;
filter5.m_FilterAction = Ndisapi.FILTER_PACKET_PASS;
filter5.m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_RECEIVE | Ndisapi.PACKET_FLAG_ON_SEND;
//STATIC_FILTER[] filterarray = new STATIC_FILTER[5];
//filterarray[0] = filter1;
//filterarray[1] = filter2;
//filterarray[2] = filter3;
//filterarray[3] = filter4;
//filterarray[4] = filter5;
var filtertable = new STATIC_FILTER_TABLE();
filtertable.m_TableSize = 5;
filtertable.m_StaticFilters = new STATIC_FILTER[256];
filtertable.m_StaticFilters[0] = filter1;
filtertable.m_StaticFilters[1] = filter2;
filtertable.m_StaticFilters[2] = filter3;
filtertable.m_StaticFilters[3] = filter4;
filtertable.m_StaticFilters[4] = filter5;
Ndisapi.SetPacketFilterTable(driverPtr, ref filtertable);
However – after figuring this out, I discovered a new issue that I can not solve:
If my goal was to process every packed EXCEPT port 80, I would assume I would change Ndisapi.FILTER_PACKET_REDIRECT to Ndisapi.FILTER_PACKET_PASS; in the filters above and vice versa.
However, when I do this, the packets to port 80 still end up being processed. I have tried re-arranging the order that I put them into the filter, and that did not yield any results
I was wondering – how would it be possible to achieve this scenario – to process all packets EXCEPT a particular port?