Beispiel #1
0
        public unsafe void SendPacket(Packet pkt)
        {
            bool worked = false;

            if (pkt.Outbound)
            {
                ETH_REQUEST          Request = new ETH_REQUEST();
                INTERMEDIATE_BUFFER *ib      = pkt.IB;
                Request.EthPacket.Buffer = (IntPtr)ib;
                Request.hAdapterHandle   = adapterHandle;
                if (!Ndisapi.SendPacketToAdapter(hNdisapi, ref Request))
                {
                    worked = false;
                }
                else
                {
                    worked = true;
                }
            }
            else
            {
                ETH_REQUEST          Request = new ETH_REQUEST();
                INTERMEDIATE_BUFFER *ib      = pkt.IB;
                Request.EthPacket.Buffer = (IntPtr)ib;
                Request.hAdapterHandle   = adapterHandle;
                worked = Ndisapi.SendPacketToMstcp(hNdisapi, ref Request);
            }
            if (pkt.CodeGenerated)
            {
                pkt.ClearGeneratedPacket();
            }
        }
Beispiel #2
0
 public static extern bool ReadPacket(SafeFilterDriverHandle hOpen, ref ETH_REQUEST packet);
Beispiel #3
0
 public static extern bool SendPacketToAdapter(SafeFilterDriverHandle hOpen, ref ETH_REQUEST packet);
Beispiel #4
0
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Console.WriteLine(@"Command line syntax:
    PassThru.exe index num
    index - network interface index.
    num - number or packets to filter
    You can use ListAdapters to determine correct index.\n");
                return;
            }

            var adapterIndex = uint.Parse(args[0]) - 1;
            var packetsCount = int.Parse(args[1]);

            try
            {
                var driverPtr = Ndisapi.OpenFilterDriver();
                if (!Ndisapi.IsDriverLoaded(driverPtr))
                {
                    throw new ApplicationException("Cannot load driver");
                }

                // Retrieve adapter list
                var adapters = new TCP_AdapterList();
                Ndisapi.GetTcpipBoundAdaptersInfo(driverPtr, ref adapters);

                // Set tunnel mode for the selected network interface
                var mode = new ADAPTER_MODE
                {
                    dwFlags        = Ndisapi.MSTCP_FLAG_SENT_TUNNEL | Ndisapi.MSTCP_FLAG_RECV_TUNNEL,
                    hAdapterHandle = adapters.m_nAdapterHandle[adapterIndex]
                };
                Ndisapi.SetAdapterMode(driverPtr, ref mode);

                // Create and set event for the adapter
                var manualResetEvent = new ManualResetEvent(false);
                Ndisapi.SetPacketEvent(driverPtr, adapters.m_nAdapterHandle[adapterIndex], manualResetEvent.SafeWaitHandle);

                // Allocate and initialize packet structures
                var request   = new ETH_REQUEST();
                var buffer    = new INTERMEDIATE_BUFFER();
                var bufferPtr = Marshal.AllocHGlobal(Marshal.SizeOf(buffer));

                Win32Api.ZeroMemory(bufferPtr, Marshal.SizeOf(buffer));

                request.hAdapterHandle   = adapters.m_nAdapterHandle[adapterIndex];
                request.EthPacket.Buffer = bufferPtr;

                while (packetsCount > 0)
                {
                    manualResetEvent.WaitOne();

                    while (Ndisapi.ReadPacket(driverPtr, ref request))
                    {
                        --packetsCount;

                        buffer = (INTERMEDIATE_BUFFER)Marshal.PtrToStructure(bufferPtr, typeof(INTERMEDIATE_BUFFER));

                        WriteToConsole(buffer, bufferPtr);

                        if (buffer.m_dwDeviceFlags == Ndisapi.PACKET_FLAG_ON_SEND)
                        {
                            Ndisapi.SendPacketToAdapter(driverPtr, ref request);
                        }
                        else
                        {
                            Ndisapi.SendPacketToMstcp(driverPtr, ref request);
                        }
                    }

                    manualResetEvent.Reset();
                }
                Marshal.FreeHGlobal(bufferPtr);

                Ndisapi.CloseFilterDriver(driverPtr);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
Beispiel #5
0
        unsafe void ProcessLoop()
        {
            // Allocate and initialize packet structures
            ETH_REQUEST         Request      = new ETH_REQUEST();
            INTERMEDIATE_BUFFER PacketBuffer = new INTERMEDIATE_BUFFER();

            IntPtr PacketBufferIntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(PacketBuffer));

            try
            {
                win32api.ZeroMemory(PacketBufferIntPtr, Marshal.SizeOf(PacketBuffer));

                Request.hAdapterHandle   = adapterHandle;
                Request.EthPacket.Buffer = PacketBufferIntPtr;

                modules = new ModuleList(this);

                modules.LoadExternalModules();

                modules.UpdateModuleOrder();

                string folder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
                folder = folder + System.IO.Path.DirectorySeparatorChar + "firebwall";
                if (!System.IO.Directory.Exists(folder))
                {
                    System.IO.Directory.CreateDirectory(folder);
                }
                folder = folder + System.IO.Path.DirectorySeparatorChar + "pcapLogs";
                if (!System.IO.Directory.Exists(folder))
                {
                    System.IO.Directory.CreateDirectory(folder);
                }
                string f = folder + System.IO.Path.DirectorySeparatorChar + "blocked-" + this.InterfaceInformation.Name + "-" + PcapCreator.Instance.GetNewDate() + ".pcap";
                pcaplog = new PcapFileWriter(f);

                INTERMEDIATE_BUFFER *PacketPointer;

                while (true)
                {
                    hEvent.WaitOne();
                    while (Ndisapi.ReadPacket(hNdisapi, ref Request))
                    {
                        PacketPointer = (INTERMEDIATE_BUFFER *)PacketBufferIntPtr;
                        //PacketBuffer = (INTERMEDIATE_BUFFER)Marshal.PtrToStructure(PacketBufferIntPtr, typeof(INTERMEDIATE_BUFFER));

                        Packet pkt = new EthPacket(PacketPointer).MakeNextLayerPacket();

                        if (pkt.Outbound)
                        {
                            OutBandwidth.AddBits(pkt.Length());
                        }
                        else
                        {
                            InBandwidth.AddBits(pkt.Length());
                        }

                        bool drop = false;
                        bool edit = false;

                        if (enabled)
                        {
                            for (int x = 0; x < modules.Count; x++)
                            {
                                FirewallModule   fm  = modules.GetModule(x);
                                PacketMainReturn pmr = fm.PacketMain(ref pkt);
                                if (pmr == null)
                                {
                                    continue;
                                }
                                if ((pmr.returnType & PacketMainReturnType.Log) == PacketMainReturnType.Log && pmr.logMessage != null)
                                {
                                    LogCenter.Instance.Push(pmr);
                                }
                                if ((pmr.returnType & PacketMainReturnType.Drop) == PacketMainReturnType.Drop)
                                {
                                    drop = true;
                                    break;
                                }
                                if ((pmr.returnType & PacketMainReturnType.Edited) == PacketMainReturnType.Edited)
                                {
                                    edit = true;
                                }
                            }
                        }

                        if (!drop)
                        {
                            if (pkt.Outbound)
                            {
                                Ndisapi.SendPacketToAdapter(hNdisapi, ref Request);
                            }
                            else
                            {
                                Ndisapi.SendPacketToMstcp(hNdisapi, ref Request);
                            }
                        }
                        else
                        {
                            pcaplog.AddPacket(pkt.Data(), (int)pkt.Length());
                        }
                    }

                    //OM NOM NOM PASTA!
                    while (processQueue.Count != 0)
                    {
                        Packet pkt = processQueue.Dequeue().MakeNextLayerPacket();

                        if (pkt.Outbound)
                        {
                            OutBandwidth.AddBits(pkt.Length());
                        }
                        else
                        {
                            InBandwidth.AddBits(pkt.Length());
                        }

                        bool drop = false;
                        bool edit = false;

                        if (enabled)
                        {
                            for (int x = 0; x < modules.Count; x++)
                            {
                                FirewallModule   fm  = modules.GetModule(x);
                                PacketMainReturn pmr = fm.PacketMain(ref pkt);
                                if (pmr == null)
                                {
                                    continue;
                                }
                                if ((pmr.returnType & PacketMainReturnType.Log) == PacketMainReturnType.Log && pmr.logMessage != null)
                                {
                                    LogCenter.Instance.Push(pmr.Module, pmr.logMessage);
                                }
                                if ((pmr.returnType & PacketMainReturnType.Drop) == PacketMainReturnType.Drop)
                                {
                                    drop = true;
                                    break;
                                }
                                if ((pmr.returnType & PacketMainReturnType.Edited) == PacketMainReturnType.Edited)
                                {
                                    edit = true;
                                }
                            }
                        }

                        if (!drop)
                        {
                            if (pkt.Outbound)
                            {
                                Ndisapi.SendPacketToAdapter(hNdisapi, ref Request);
                            }
                            else
                            {
                                Ndisapi.SendPacketToMstcp(hNdisapi, ref Request);
                            }
                        }
                        else
                        {
                            pcaplog.AddPacket(pkt.Data(), (int)pkt.Length());
                        }
                    }
                    hEvent.Reset();
                }
            }
            catch (Exception tae)
            {
                Marshal.FreeHGlobal(PacketBufferIntPtr);
            }
        }
Beispiel #6
0
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Console.WriteLine(@"Command line syntax:
    PacketSniffer.exe index num [-promisc]
    index - network interface index.
    num - number or packets to capture
    -promisc - optional parameter. 
    When specified network interface is switched to the promiscuous mode.\n\tYou can use ListAdapters to determine correct index.\n");
                return;
            }

            var promisciousMode = args.Length == 3 && args[2].Equals("-promisc");

            var adapterIndex = uint.Parse(args[0]) - 1;
            var packetsCount = int.Parse(args[1]);

            try
            {
                var driverPtr = Ndisapi.OpenFilterDriver();
                if (!Ndisapi.IsDriverLoaded(driverPtr))
                {
                    throw new ApplicationException("Cannot load driver");
                }

                // Retrieve adapter list
                var adList = new TCP_AdapterList();
                Ndisapi.GetTcpipBoundAdaptersInfo(driverPtr, ref adList);
                uint dwOldHwFilter = 0;

                if (promisciousMode)
                {
                    if (!Ndisapi.GetHwPacketFilter(driverPtr, adList.m_nAdapterHandle[adapterIndex], ref dwOldHwFilter))
                    {
                        Console.WriteLine("Failed to get current packet filter from the network interface.");
                    }
                    else
                    {
                        Console.WriteLine("Succeded to get current packet filter from the network interface. dwOldHwFilter = {0}", dwOldHwFilter);
                    }

                    if (!Ndisapi.SetHwPacketFilter(driverPtr, adList.m_nAdapterHandle[adapterIndex], 0x00000020 /*NDIS_PACKET_TYPE_PROMISCUOUS*/))
                    {
                        Console.WriteLine("Failed to set promiscuous mode for the network interface.");
                    }
                    else
                    {
                        Console.WriteLine("Succeded to set promiscuous mode for the network interface.");
                    }
                }

                // Set listen mode for the selected network interface
                var mode = new ADAPTER_MODE
                {
                    dwFlags        = Ndisapi.MSTCP_FLAG_SENT_LISTEN | Ndisapi.MSTCP_FLAG_RECV_LISTEN,
                    hAdapterHandle = adList.m_nAdapterHandle[adapterIndex]
                };
                if (promisciousMode)
                {
                    mode.dwFlags = mode.dwFlags | Ndisapi.MSTCP_FLAG_FILTER_DIRECT | Ndisapi.MSTCP_FLAG_LOOPBACK_BLOCK;
                }

                Ndisapi.SetAdapterMode(driverPtr, ref mode);

                // Allocate and initialize packet structures
                var buffer    = new INTERMEDIATE_BUFFER();
                var bufferPtr = Marshal.AllocHGlobal(Marshal.SizeOf(buffer));
                Win32Api.ZeroMemory(bufferPtr, Marshal.SizeOf(buffer));

                var request = new ETH_REQUEST
                {
                    hAdapterHandle = adList.m_nAdapterHandle[adapterIndex],
                    EthPacket      = { Buffer = bufferPtr }
                };


                while (packetsCount > 0)
                {
                    if (Ndisapi.ReadPacket(driverPtr, ref request))
                    {
                        --packetsCount;

                        buffer = (INTERMEDIATE_BUFFER)Marshal.PtrToStructure(bufferPtr, typeof(INTERMEDIATE_BUFFER));
                        WriteToConsole(buffer, bufferPtr);
                    }
                    else
                    {
                        Console.Write(".");
                        System.Threading.Thread.Sleep(100);
                    }
                }
                Marshal.FreeHGlobal(bufferPtr);
                if (promisciousMode)
                {
                    Ndisapi.SetHwPacketFilter(driverPtr, adList.m_nAdapterHandle[adapterIndex], dwOldHwFilter);
                }

                Ndisapi.CloseFilterDriver(driverPtr);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
Beispiel #7
0
        public void start(int num)
        {
            if (ready)
            {
                ADAPTER_MODE mode = new ADAPTER_MODE
                {
                    dwFlags        = Ndisapi.MSTCP_FLAG_SENT_LISTEN | Ndisapi.MSTCP_FLAG_RECV_LISTEN,
                    hAdapterHandle = adapters.m_nAdapterHandle[num]
                };
                Ndisapi.SetAdapterMode(driverPtr, ref mode);
                IP_ADDRESS_V4[] serversIp = new IP_ADDRESS_V4[serverIps.Length];
                for (int i = 0; i < serverIps.Length; i++)
                {
                    serversIp[i] = new IP_ADDRESS_V4()
                    {
                        m_AddressType = Ndisapi.IP_SUBNET_V4_TYPE,
                        m_IpSubnet    = new IP_SUBNET_V4
                        {
                            m_Ip     = BitConverter.ToUInt32(IPAddress.Parse(serverIps[i]).GetAddressBytes(), 0),
                            m_IpMask = 0xFFFFFFFF
                        }
                    }
                }
                ;
                //Filters
                STATIC_FILTER_TABLE filtersTable = new STATIC_FILTER_TABLE();
                filtersTable.m_StaticFilters = new STATIC_FILTER[256];
                filtersTable.m_TableSize     = (uint)(2 * serverIps.Length + 1);
                for (int i = 0; i < 2 * serverIps.Length; i += 2)
                {
                    filtersTable.m_StaticFilters[i].m_Adapter      = 0; // applied to all adapters
                    filtersTable.m_StaticFilters[i].m_ValidFields  = Ndisapi.NETWORK_LAYER_VALID;
                    filtersTable.m_StaticFilters[i].m_FilterAction = Ndisapi.FILTER_PACKET_REDIRECT;

                    filtersTable.m_StaticFilters[i].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_SEND;
                    filtersTable.m_StaticFilters[i].m_NetworkFilter.m_dwUnionSelector    = Ndisapi.IPV4;
                    filtersTable.m_StaticFilters[i].m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V4_FILTER_DEST_ADDRESS;

                    filtersTable.m_StaticFilters[i].m_NetworkFilter.m_IPv4.m_DestAddress = serversIp[i / 2];

                    filtersTable.m_StaticFilters[i + 1].m_Adapter      = 0; // applied to all adapters
                    filtersTable.m_StaticFilters[i + 1].m_ValidFields  = Ndisapi.NETWORK_LAYER_VALID;
                    filtersTable.m_StaticFilters[i + 1].m_FilterAction = Ndisapi.FILTER_PACKET_REDIRECT;

                    filtersTable.m_StaticFilters[i + 1].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_RECEIVE;
                    filtersTable.m_StaticFilters[i + 1].m_NetworkFilter.m_dwUnionSelector    = Ndisapi.IPV4;
                    filtersTable.m_StaticFilters[i + 1].m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V4_FILTER_SRC_ADDRESS;

                    filtersTable.m_StaticFilters[i + 1].m_NetworkFilter.m_IPv4.m_SrcAddress = serversIp[i / 2];
                }
                filtersTable.m_StaticFilters[2 * serverIps.Length].m_Adapter          = 0; // applied to all adapters
                filtersTable.m_StaticFilters[2 * serverIps.Length].m_ValidFields      = 0;
                filtersTable.m_StaticFilters[2 * serverIps.Length].m_FilterAction     = Ndisapi.FILTER_PACKET_PASS;
                filtersTable.m_StaticFilters[2 * serverIps.Length].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_RECEIVE | Ndisapi.PACKET_FLAG_ON_SEND;
                Ndisapi.SetPacketFilterTable(driverPtr, ref filtersTable);



                buffer    = new INTERMEDIATE_BUFFER();
                bufferPtr = Marshal.AllocHGlobal(Marshal.SizeOf(buffer));
                Win32Api.ZeroMemory(bufferPtr, Marshal.SizeOf(buffer));
                request = new ETH_REQUEST
                {
                    hAdapterHandle = adapters.m_nAdapterHandle[num],
                    EthPacket      = { Buffer = bufferPtr }
                };
                threadLookingForPacket.Start();
                threadParsePacket.Start();
                ready = false;

                if (onStartedSniffer != null)
                {
                    onStartedSniffer(this, EventArgs.Empty);
                }
            }
        }
Beispiel #8
0
        static void Main(string[] args)
        {
            try
            {
                if (args.Length < 2)
                {
                    Console.WriteLine(
                        "Command line syntax:\n\tfilter.exe index scenario \n\tindex - network interface index.\n\tscenario - sample set of filters to load.\n\tYou can use ListAdapters to determine correct index.");
                    Console.WriteLine("Available Scenarios:");
                    Console.WriteLine("1 - Redirect only IPv4 DNS packets for processing in user mode.");
                    Console.WriteLine("2 - Redirect only HTTP(TCP port 80) packets for processing in user mode. Both IPv4 and IPv6 protocols.");
                    Console.WriteLine("3 - Drop all IPv4 ICMP packets. Redirect all other packets to user mode (default behaviour).");
                    Console.WriteLine("4 - Block IPv4 access to http://www.ntkernel.com. Pass all other packets without processing in user mode.");
                    Console.WriteLine("5 - Redirect only ARP/RARP packets to user mode. Pass all others.");
                    return;
                }

                var adapterIndex = uint.Parse(args[0]) - 1;
                var scena        = uint.Parse(args[1]);

                var driverPtr = Ndisapi.OpenFilterDriver();
                if (!Ndisapi.IsDriverLoaded(driverPtr))
                {
                    Console.WriteLine("Driver not installed on this system of failed to load.");
                    return;
                }

                // Retrieve adapter list
                var adapters = new TCP_AdapterList();
                Ndisapi.GetTcpipBoundAdaptersInfo(driverPtr, ref adapters);

                // Set tunnel mode for the selected network interface
                var mode = new ADAPTER_MODE
                {
                    dwFlags        = Ndisapi.MSTCP_FLAG_SENT_TUNNEL | Ndisapi.MSTCP_FLAG_RECV_TUNNEL,
                    hAdapterHandle = adapters.m_nAdapterHandle[adapterIndex]
                };

                Ndisapi.SetAdapterMode(driverPtr, ref mode);

                // Create and set event for the adapter
                var manualResetEvent = new ManualResetEvent(false);
                Ndisapi.SetPacketEvent(driverPtr, adapters.m_nAdapterHandle[adapterIndex], manualResetEvent.SafeWaitHandle);

                var filtersTable = new STATIC_FILTER_TABLE();
                filtersTable.m_StaticFilters = new STATIC_FILTER[256];

                switch (scena)
                {
                case 1:
                    filtersTable.m_TableSize = 3;

                    //**************************************************************************************
                    // 1. Outgoing DNS requests filter: REDIRECT OUT UDP packets with destination PORT 53
                    // Common values
                    filtersTable.m_StaticFilters[0].m_Adapter          = 0; // applied to all adapters
                    filtersTable.m_StaticFilters[0].m_ValidFields      = Ndisapi.NETWORK_LAYER_VALID | Ndisapi.TRANSPORT_LAYER_VALID;
                    filtersTable.m_StaticFilters[0].m_FilterAction     = Ndisapi.FILTER_PACKET_REDIRECT;
                    filtersTable.m_StaticFilters[0].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_SEND;

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

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

                    //****************************************************************************************
                    // 2. Incoming DNS responses filter: REDIRECT IN UDP packets with source PORT 53
                    // Common values
                    filtersTable.m_StaticFilters[1].m_Adapter          = 0; // applied to all adapters
                    filtersTable.m_StaticFilters[1].m_ValidFields      = Ndisapi.NETWORK_LAYER_VALID | Ndisapi.TRANSPORT_LAYER_VALID;
                    filtersTable.m_StaticFilters[1].m_FilterAction     = Ndisapi.FILTER_PACKET_REDIRECT;
                    filtersTable.m_StaticFilters[1].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_RECEIVE;

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

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

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

                    break;

                case 2:
                    filtersTable.m_TableSize = 5;

                    //**************************************************************************************
                    // 1. Outgoing HTTP requests filter: REDIRECT OUT TCP packets with destination PORT 80 IPv4
                    // Common values
                    filtersTable.m_StaticFilters[0].m_Adapter          = 0; // applied to all adapters
                    filtersTable.m_StaticFilters[0].m_ValidFields      = Ndisapi.NETWORK_LAYER_VALID | Ndisapi.TRANSPORT_LAYER_VALID;
                    filtersTable.m_StaticFilters[0].m_FilterAction     = Ndisapi.FILTER_PACKET_REDIRECT;
                    filtersTable.m_StaticFilters[0].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_SEND;

                    // Network layer filter
                    filtersTable.m_StaticFilters[0].m_NetworkFilter.m_dwUnionSelector    = Ndisapi.IPV4;
                    filtersTable.m_StaticFilters[0].m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V4_FILTER_PROTOCOL;
                    filtersTable.m_StaticFilters[0].m_NetworkFilter.m_IPv4.m_Protocol    = 6; //IPPROTO_TCP

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

                    //****************************************************************************************
                    // 2. Incoming HTTP responses filter: REDIRECT IN TCP packets with source PORT 80 IPv4
                    // Common values
                    filtersTable.m_StaticFilters[1].m_Adapter          = 0; // applied to all adapters
                    filtersTable.m_StaticFilters[1].m_ValidFields      = Ndisapi.NETWORK_LAYER_VALID | Ndisapi.TRANSPORT_LAYER_VALID;
                    filtersTable.m_StaticFilters[1].m_FilterAction     = Ndisapi.FILTER_PACKET_REDIRECT;
                    filtersTable.m_StaticFilters[1].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_RECEIVE;

                    // Network layer filter
                    filtersTable.m_StaticFilters[1].m_NetworkFilter.m_dwUnionSelector    = Ndisapi.IPV4;
                    filtersTable.m_StaticFilters[1].m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V4_FILTER_PROTOCOL;
                    filtersTable.m_StaticFilters[1].m_NetworkFilter.m_IPv4.m_Protocol    = 6;  //IPPROTO_TCP

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

                    //****************************************************************************************
                    // 3. Outgoing HTTP requests filter: REDIRECT OUT TCP packets with destination PORT 80 IPv6
                    // Common values
                    filtersTable.m_StaticFilters[2].m_Adapter          = 0; // applied to all adapters
                    filtersTable.m_StaticFilters[2].m_ValidFields      = Ndisapi.NETWORK_LAYER_VALID | Ndisapi.TRANSPORT_LAYER_VALID;
                    filtersTable.m_StaticFilters[2].m_FilterAction     = Ndisapi.FILTER_PACKET_REDIRECT;
                    filtersTable.m_StaticFilters[2].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_SEND;

                    // Network layer filter
                    filtersTable.m_StaticFilters[2].m_NetworkFilter.m_dwUnionSelector    = Ndisapi.IPV6;
                    filtersTable.m_StaticFilters[2].m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V6_FILTER_PROTOCOL;
                    filtersTable.m_StaticFilters[2].m_NetworkFilter.m_IPv4.m_Protocol    = 6;  //IPPROTO_TCP

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

                    //****************************************************************************************
                    // 4. Incoming HTTP responses filter: REDIRECT IN TCP packets with source PORT 80 IPv6
                    // Common values
                    filtersTable.m_StaticFilters[3].m_Adapter          = 0; // applied to all adapters
                    filtersTable.m_StaticFilters[3].m_ValidFields      = Ndisapi.NETWORK_LAYER_VALID | Ndisapi.TRANSPORT_LAYER_VALID;
                    filtersTable.m_StaticFilters[3].m_FilterAction     = Ndisapi.FILTER_PACKET_REDIRECT;
                    filtersTable.m_StaticFilters[3].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_RECEIVE;

                    // Network layer filter
                    filtersTable.m_StaticFilters[3].m_NetworkFilter.m_dwUnionSelector    = Ndisapi.IPV6;
                    filtersTable.m_StaticFilters[3].m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V6_FILTER_PROTOCOL;
                    filtersTable.m_StaticFilters[3].m_NetworkFilter.m_IPv4.m_Protocol    = 6; // IPPROTO_TCP

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

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

                    break;

                case 3:
                    filtersTable.m_TableSize = 5;

                    //**************************************************************************************
                    // 1. Block all ICMP packets
                    // Common values
                    filtersTable.m_StaticFilters[0].m_Adapter          = 0; // applied to all adapters
                    filtersTable.m_StaticFilters[0].m_ValidFields      = Ndisapi.NETWORK_LAYER_VALID;
                    filtersTable.m_StaticFilters[0].m_FilterAction     = Ndisapi.FILTER_PACKET_DROP;
                    filtersTable.m_StaticFilters[0].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_SEND | Ndisapi.PACKET_FLAG_ON_RECEIVE;

                    // Network layer filter
                    filtersTable.m_StaticFilters[0].m_NetworkFilter.m_dwUnionSelector    = Ndisapi.IPV4;
                    filtersTable.m_StaticFilters[0].m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V4_FILTER_PROTOCOL;
                    filtersTable.m_StaticFilters[0].m_NetworkFilter.m_IPv4.m_Protocol    = 1; //IPPROTO_ICMP

                    break;

                case 4:

                    filtersTable.m_TableSize = 2;

                    //**************************************************************************************
                    // 1. Outgoing HTTP requests filter: DROP OUT TCP packets with destination IP 104.196.49.47 PORT 80 - 443 (http://www.ntkernel.com)
                    // Common values
                    filtersTable.m_StaticFilters[0].m_Adapter          = 0; // applied to all adapters
                    filtersTable.m_StaticFilters[0].m_ValidFields      = Ndisapi.NETWORK_LAYER_VALID | Ndisapi.TRANSPORT_LAYER_VALID;
                    filtersTable.m_StaticFilters[0].m_FilterAction     = Ndisapi.FILTER_PACKET_DROP;
                    filtersTable.m_StaticFilters[0].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_SEND;

                    // Network layer filter
                    var address = new in_addr();
                    var mask    = new in_addr();

                    // IP address 104.196.49.47
                    address.s_b1 = 104;
                    address.s_b2 = 196;
                    address.s_b3 = 49;
                    address.s_b4 = 47;

                    // Network mask 255.255.255.255
                    mask.s_b1 = 255;
                    mask.s_b2 = 255;
                    mask.s_b3 = 255;
                    mask.s_b4 = 255;

                    filtersTable.m_StaticFilters[0].m_NetworkFilter.m_dwUnionSelector    = Ndisapi.IPV4;
                    filtersTable.m_StaticFilters[0].m_NetworkFilter.m_IPv4.m_ValidFields = Ndisapi.IP_V4_FILTER_PROTOCOL | Ndisapi.IP_V4_FILTER_DEST_ADDRESS;
                    filtersTable.m_StaticFilters[0].m_NetworkFilter.m_IPv4.m_DestAddress.m_AddressType       = Ndisapi.IP_SUBNET_V4_TYPE;
                    filtersTable.m_StaticFilters[0].m_NetworkFilter.m_IPv4.m_DestAddress.m_IpSubnet.m_Ip     = address.s_addr; // IP address
                    filtersTable.m_StaticFilters[0].m_NetworkFilter.m_IPv4.m_DestAddress.m_IpSubnet.m_IpMask = mask.s_addr;    // network mask
                    filtersTable.m_StaticFilters[0].m_NetworkFilter.m_IPv4.m_Protocol = 6;                                     //IPPROTO_TCP

                    // Transport layer filter
                    filtersTable.m_StaticFilters[0].m_TransportFilter.m_dwUnionSelector                = Ndisapi.TCPUDP;
                    filtersTable.m_StaticFilters[0].m_TransportFilter.m_TcpUdp.m_ValidFields           = Ndisapi.TCPUDP_DEST_PORT;
                    filtersTable.m_StaticFilters[0].m_TransportFilter.m_TcpUdp.m_DestPort.m_StartRange = 80;    // HTTP
                    filtersTable.m_StaticFilters[0].m_TransportFilter.m_TcpUdp.m_DestPort.m_EndRange   = 443;   //HTTPS

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

                    break;

                case 5:

                    filtersTable.m_TableSize = 3;

                    //**************************************************************************************
                    // 1. Redirects all ARP packets to be processes by user mode application
                    // Common values
                    filtersTable.m_StaticFilters[0].m_Adapter          = 0; // applied to all adapters
                    filtersTable.m_StaticFilters[0].m_ValidFields      = Ndisapi.DATA_LINK_LAYER_VALID;
                    filtersTable.m_StaticFilters[0].m_FilterAction     = Ndisapi.FILTER_PACKET_REDIRECT;
                    filtersTable.m_StaticFilters[0].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_SEND | Ndisapi.PACKET_FLAG_ON_RECEIVE;
                    filtersTable.m_StaticFilters[0].m_DataLinkFilter.m_dwUnionSelector             = Ndisapi.ETH_802_3;
                    filtersTable.m_StaticFilters[0].m_DataLinkFilter.m_Eth8023Filter.m_ValidFields = Ndisapi.ETH_802_3_PROTOCOL;
                    filtersTable.m_StaticFilters[0].m_DataLinkFilter.m_Eth8023Filter.m_Protocol    = 0x0806;  // ETH_P_ARP;


                    //**************************************************************************************
                    // 1. Redirects all RARP packets to be processes by user mode application
                    // Common values
                    filtersTable.m_StaticFilters[1].m_Adapter          = 0; // applied to all adapters
                    filtersTable.m_StaticFilters[1].m_ValidFields      = Ndisapi.DATA_LINK_LAYER_VALID;
                    filtersTable.m_StaticFilters[1].m_FilterAction     = Ndisapi.FILTER_PACKET_REDIRECT;
                    filtersTable.m_StaticFilters[1].m_dwDirectionFlags = Ndisapi.PACKET_FLAG_ON_SEND | Ndisapi.PACKET_FLAG_ON_RECEIVE;
                    filtersTable.m_StaticFilters[1].m_DataLinkFilter.m_dwUnionSelector             = Ndisapi.ETH_802_3;
                    filtersTable.m_StaticFilters[1].m_DataLinkFilter.m_Eth8023Filter.m_ValidFields = Ndisapi.ETH_802_3_PROTOCOL;
                    filtersTable.m_StaticFilters[1].m_DataLinkFilter.m_Eth8023Filter.m_Protocol    = 0x0806;  // ETH_P_ARP;


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

                    break;

                default:
                    Console.WriteLine("Unknown test scenario specified. Exiting.");
                    return;
                }

                // Load filters into driver
                Ndisapi.SetPacketFilterTable(driverPtr, ref filtersTable);

                // Allocate and initialize packet structures
                var request   = new ETH_REQUEST();
                var buffer    = new INTERMEDIATE_BUFFER();
                var bufferPtr = Marshal.AllocHGlobal(Marshal.SizeOf(buffer));

                Win32Api.ZeroMemory(bufferPtr, Marshal.SizeOf(buffer));

                request.hAdapterHandle   = adapters.m_nAdapterHandle[adapterIndex];
                request.EthPacket.Buffer = bufferPtr;

                while (true)
                {
                    manualResetEvent.WaitOne();

                    while (Ndisapi.ReadPacket(driverPtr, ref request))
                    {
                        buffer = (INTERMEDIATE_BUFFER)Marshal.PtrToStructure(bufferPtr, typeof(INTERMEDIATE_BUFFER));

                        WriteToConsole(buffer, bufferPtr);

                        if (buffer.m_dwDeviceFlags == Ndisapi.PACKET_FLAG_ON_SEND)
                        {
                            Ndisapi.SendPacketToAdapter(driverPtr, ref request);
                        }
                        else
                        {
                            Ndisapi.SendPacketToMstcp(driverPtr, ref request);
                        }
                    }

                    manualResetEvent.Reset();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }