예제 #1
0
        // LISTENS TO VPN ADAPTER AND SENDS THE SPECIFIC PACKETS OUT THE NORMAL ADAPTER
        private static void TreatOUTPacketsVPNtoNormal(NdisApiDotNet outNdisapi, NetworkAdapter vpnAdapter, NetworkAdapter normalAdapter)
        {
            // Lists for re-injecting packets
            List <RawPacket> toAdapter = new List <RawPacket>();
            List <RawPacket> toMstcp   = new List <RawPacket>();

            // Unmanaged memory resource for sending receiving bulk of packets
            // Maximum number of packets to send/receive = 64
            NdisBufferResource buffer = new NdisBufferResource(64);

            outNdisapi.SetAdapterMode(vpnAdapter.Handle, MSTCP_FLAGS.MSTCP_FLAG_TUNNEL);
            outNdisapi.SetPacketEvent(vpnAdapter.Handle, outPacketEvent);

            do
            {
                outPacketEvent.WaitOne();
                var packetList = outNdisapi.ReadPackets(vpnAdapter.Handle, buffer);

                while (packetList.Item1)
                {
                    foreach (var packet in packetList.Item2)
                    {
                        Packet         p = null;
                        EthernetPacket ethernetPacket = null;
                        TcpPacket      tcpPacket      = null;
                        IPv4Packet     ipv4Packet     = null;
                        ushort         sport          = 0;
                        ushort         dport          = 0;
                        try {
                            p = Packet.ParsePacket(LinkLayers.Ethernet, packet.Data);
                            ethernetPacket = (EthernetPacket)p;
                            tcpPacket      = (TcpPacket)((IPPacket)((EthernetPacket)p).PayloadPacket).PayloadPacket;
                            ipv4Packet     = (IPv4Packet)((EthernetPacket)p).PayloadPacket;
                            sport          = tcpPacket.SourcePort;
                            dport          = tcpPacket.DestinationPort;
                        } catch (Exception ex) {
                            if (packet.DeviceFlags == PACKET_FLAG.PACKET_FLAG_ON_RECEIVE)
                            {
                                toMstcp.Add(packet);
                            }
                            else
                            {
                                toAdapter.Add(packet);
                            }
                            Console.WriteLine($"An exeption {ex.Message} occured while trying to parse network packet. Packet will be let thru without any changes");
                            continue;
                        }

                        DumpSourceChangingFilteredPacket(packet.DeviceFlags,
                                                         ipv4Packet.SourceAddress.ToString(),
                                                         sport.ToString(),
                                                         ipv4Packet.DestinationAddress.ToString(),
                                                         dport.ToString(),
                                                         p.Bytes.Length,
                                                         packet.DeviceFlags == PACKET_FLAG.PACKET_FLAG_ON_RECEIVE);

                        if (packet.DeviceFlags == PACKET_FLAG.PACKET_FLAG_ON_RECEIVE)
                        {
                            // Packet was received on VPN adapter, leave it as it is
                            toMstcp.Add(packet);
                        }
                        else
                        {
                            if (ipv4Packet.SourceAddress.Equals(vpnIP))
                            {
                                // Change the Source for outgoing packets that will later be sent thru normal adapter
                                ipv4Packet.SourceAddress             = localIp;
                                ethernetPacket.SourceHardwareAddress = localMacAddress;
                                ipv4Packet.UpdateIPChecksum();
                                tcpPacket.UpdateTcpChecksum();
                                ethernetPacket.UpdateCalculatedValues();
                                var newPackage = new RawPacket()
                                {
                                    Data        = p.Bytes,
                                    FilterId    = packet.FilterId,
                                    Dot1q       = packet.Dot1q,
                                    NdisFlags   = packet.NdisFlags,
                                    DeviceFlags = packet.DeviceFlags
                                };
                                toAdapter.Add(newPackage);
                            }
                            else
                            {
                                toAdapter.Add(packet);
                            }
                        }
                    }

                    if (toMstcp.Count > 0)
                    {
                        // If we have packets to forward upwards the network stack then do it here
                        // RECEIVED SHOULD BE TREATED BY VPN ADAPTER
                        outNdisapi.SendPacketsToMstcp(vpnAdapter.Handle, buffer, toMstcp);
                        toMstcp.Clear();
                    }

                    if (toAdapter.Count > 0)
                    {
                        // If we have packets to forward downwards the network stack then do it here
                        // SENT SHOULD BE TREATED BY NORMAL ADAPTER
                        outNdisapi.SendPacketsToAdapter(normalAdapter.Handle, buffer, toAdapter);
                        toAdapter.Clear();
                    }

                    packetList = outNdisapi.ReadPackets(vpnAdapter.Handle, buffer);
                }
                ;
                outPacketEvent.Reset();
            } while (!stopCapturing);

            //
            // Release driver and associated resources
            //
            buffer.Dispose();

            outNdisapi.SetPacketEvent(vpnAdapter.Handle, null);

            outNdisapi.SetAdapterMode(vpnAdapter.Handle, 0);
        }
예제 #2
0
        static void Main(string[] args)
        {
            if (!ndisapi.IsDriverLoaded())
            {
                Console.WriteLine("WinpkFilter driver is not loaded. Exiting.");
                return;
            }

            UInt32 driverVersion = ndisapi.GetVersion();
            UInt32 majorVersion  = (driverVersion & (0xF000)) >> 12;
            UInt32 minorVersion1 = (driverVersion & (0xFF000000)) >> 24;
            UInt32 minorVersion2 = (driverVersion & (0xFF0000)) >> 16;

            if (ndisapi != null)
            {
                Console.WriteLine($"Detected Windows Packet Filter version {majorVersion}.{minorVersion1}.{minorVersion2}");
            }

            Console.WriteLine();

            var adapterList = ndisapi.GetTcpipBoundAdaptersInfo();

            if (!adapterList.Item1)
            {
                Console.WriteLine("WinpkFilter failed to query active interfaces. Exiting.");
                return;
            }

            if (adapterList.Item2.Count > 0)
            {
                Console.WriteLine("Available network interfaces: ");
            }

            Console.WriteLine();

            int counter = 0;

            foreach (var adapter in adapterList.Item2)
            {
                Console.WriteLine($"{++counter}) {adapter.FriendlyName}");
                Console.WriteLine($"\t Internal name: {adapter.Name}");
                Console.WriteLine($"\t Handle: {adapter.Handle.ToString("x")}");
                Console.WriteLine($"\t MAC: {adapter.CurrentAddress}");
                Console.WriteLine($"\t Medium: {adapter.Medium}");
                Console.WriteLine($"\t MTU: {adapter.Mtu}");

                if (adapter.Medium == NDIS_MEDIUM.NdisMediumWan)
                {
                    var rasLinkInfoList = ndisapi.GetRasLinks(adapter.Handle);

                    if (rasLinkInfoList.Item1 && (rasLinkInfoList.Item2.Count > 0))
                    {
                        foreach (var e in rasLinkInfoList.Item2)
                        {
                            Console.WriteLine($"----------------------------------------------------------------");
                            Console.WriteLine($"\t\tLinkSpeed = {e.LinkSpeed}");
                            Console.WriteLine($"\t\tMTU: {e.MaximumTotalSize}");
                            Console.WriteLine($"\t\tLocalAddress: {e.LocalAddress}");
                            Console.WriteLine($"\t\tRemoteAddress: {e.RemoteAddress}");

                            Byte[] ipAddress = new Byte[4];
                            Array.Copy(e.ProtocolBuffer, 584, ipAddress, 0, 4);
                            IPAddress ipV4 = new IPAddress(ipAddress);
                            Array.Copy(e.ProtocolBuffer, 588, ipAddress, 0, 4);
                            IPAddress ipMaskV4 = new IPAddress(ipAddress);

                            Console.WriteLine($"\t\tIPv4: {ipV4} Mask: {ipMaskV4}");
                            Console.WriteLine($"----------------------------------------------------------------");
                        }
                    }
                }

                Console.WriteLine();
            }

            Console.Write("Select network interface: ");
            int index = Convert.ToInt32(Console.ReadLine());

            if (index > adapterList.Item2.Count)
            {
                Console.WriteLine($"Wrong interface index {index}");
                return;
            }

            #region Testing NdisrdRequest API call
            Console.WriteLine();
            Console.WriteLine($"Probing NDIS requests on: {adapterList.Item2[index - 1].FriendlyName}:");
            Console.WriteLine();

            PacketOidData oidRequest = new PacketOidData();
            oidRequest.Adapter = adapterList.Item2[index - 1].Handle;
            oidRequest.Oid     = OID_802_3_CURRENT_ADDRESS;
            oidRequest.Data    = new byte[6];

            if (ndisapi.NdisrdRequest(oidRequest, false))
            {
                Console.WriteLine($@"OID_802_3_CURRENT_ADDRESS:     Status = OK     Value: {new PhysicalAddress(oidRequest.Data)}");
            }
            else
            {
                Console.WriteLine($@"OID_802_3_CURRENT_ADDRESS:     Status = FAILED");
            }

            oidRequest.Oid  = OID_GEN_MAXIMUM_TOTAL_SIZE;
            oidRequest.Data = new byte[4];

            if (ndisapi.NdisrdRequest(oidRequest, false))
            {
                Console.WriteLine($@"OID_GEN_MAXIMUM_TOTAL_SIZE:    Status = OK     Value: {BitConverter.ToUInt32(oidRequest.Data, 0)}");
            }
            else
            {
                Console.WriteLine($@"OID_GEN_MAXIMUM_TOTAL_SIZE:    Status = FAILED");
            }

            oidRequest.Oid = OID_GEN_PHYSICAL_MEDIUM;

            if (ndisapi.NdisrdRequest(oidRequest, false))
            {
                Console.WriteLine($@"OID_GEN_PHYSICAL_MEDIUM:       Status = OK     Value: {(NdisPhysicalMedium)BitConverter.ToUInt32(oidRequest.Data, 0)}");
            }
            else
            {
                Console.WriteLine($@"OID_GEN_PHYSICAL_MEDIUM:       Status = FAILED");
            }
            #endregion

            #region Testing static filters
            Console.WriteLine();
            Console.WriteLine("Please select the static filters set to use:");
            Console.WriteLine();
            Console.WriteLine(@"1 - IPv4 DNS filter:    Redirect and dump only IPv4 DNS packets for processing in user mode.");
            Console.WriteLine(@"2 - HTTP filter:        Redirect and dump only HTTP(TCP port 80) packets for processing in user mode.");
            Console.WriteLine(@"3 - FQDN filter:        Redirect and dump only packets destined to/from selected domain name.");
            Console.WriteLine(@"4 - Default filter:     Redirect and dump all network packets.");
            Console.WriteLine(@"5 - Silent default:     Redirect all network packets. Zero output (performance test option).");
            Console.WriteLine();
            Console.Write("Select filter option: ");

            int option = Convert.ToInt32(Console.ReadLine());

            if (option > 5)
            {
                Console.WriteLine($"Wrong filter option {option}");
                return;
            }

            bool dumpPackets = true;

            switch (option)
            {
            case 1:
                LoadIpv4DnsFilter(adapterList.Item2[index - 1].Handle);
                break;

            case 2:
                LoadHttpFilter(adapterList.Item2[index - 1].Handle);
                break;

            case 3:
                Console.Write("Enter FQDN: ");
                LoadFqdnFilter(adapterList.Item2[index - 1].Handle, Console.ReadLine());
                break;

            case 4:
                // Do nothing, this is a default behaviour
                break;

            case 5:
                dumpPackets = false;
                break;

            default:
                Console.WriteLine("Wrong filter option. Exiting...");
                return;
            }
            #endregion

            // Register a cancel handler that lets us break out of our capture loop
            Console.CancelKeyPress += HandleCancelKeyPress;

            ndisapi.SetAdapterMode(
                adapterList.Item2[index - 1].Handle,
                MSTCP_FLAGS.MSTCP_FLAG_TUNNEL
                );

            ndisapi.SetPacketEvent(adapterList.Item2[index - 1].Handle, packetEvent);

            Console.WriteLine($"-- Filtering on {adapterList.Item2[index - 1].FriendlyName}, hit 'ctrl-c' to stop...");

            // Lists for re-injecting packets
            List <RawPacket> toAdapter = new List <RawPacket>();
            List <RawPacket> toMstcp   = new List <RawPacket>();

            // Unmanaged memory resource for sending receiving bulk of packets
            // Maximum number of packets to send/receive = 64
            NdisBufferResource buffer = new NdisBufferResource(64);

            do
            {
                packetEvent.WaitOne();
                #region Single packet read/write
                //RawPacket packet = ndisapi.ReadPacket(adapterList[index - 1].Handle);

                //while (packet != null)
                //{
                //    // use PacketDotNet to parse this packet and print out
                //    // its high level information
                //    Packet p = Packet.ParsePacket(LinkLayers.Ethernet, packet.Data);

                //    try
                //    {
                //        Console.WriteLine(p.ToString());
                //    }
                //    catch (Exception)
                //    { }

                //    if (packet.DeviceFlags == PACKET_FLAG.PACKET_FLAG_ON_RECEIVE)
                //    {
                //        ndisapi.SendPacketToMstcp(adapterList[index - 1].Handle, packet);
                //    }
                //    else
                //    {
                //        ndisapi.SendPacketToAdapter(adapterList[index - 1].Handle, packet);
                //    }

                //    packet = ndisapi.ReadPacket(adapterList[index - 1].Handle);
                //};
                #endregion
                #region Bulk of packets read/write

                var packetList = ndisapi.ReadPackets(adapterList.Item2[index - 1].Handle, buffer);

                while (packetList.Item1)
                {
                    foreach (var packet in packetList.Item2)
                    {
                        if (dumpPackets)
                        {
                            Console.WriteLine($"Succesfully read {packetList.Item2.Count} packets from {adapterList.Item2[index - 1].FriendlyName}");
                            try
                            {
                                // Use PacketDotNet to parse this packet and print out
                                // its high level information
                                Packet p = Packet.ParsePacket(LinkLayers.Ethernet, packet.Data);

                                Console.WriteLine(p.ToString());
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine($"An exeption {ex.Message} occured while trying to parse network packet.");
                            }
                        }

                        // Depending on the packet direction insert it to the appropriate list
                        if (packet.DeviceFlags == PACKET_FLAG.PACKET_FLAG_ON_RECEIVE)
                        {
                            toMstcp.Add(packet);
                        }
                        else
                        {
                            toAdapter.Add(packet);
                        }
                    }

                    if (toMstcp.Count > 0)
                    {
                        // If we have packets to forward upwards the network stack then do it here
                        ndisapi.SendPacketsToMstcp(adapterList.Item2[index - 1].Handle, buffer, toMstcp);
                        toMstcp.Clear();
                    }

                    if (toAdapter.Count > 0)
                    {
                        // If we have packets to forward downwards the network stack then do it here
                        ndisapi.SendPacketsToAdapter(adapterList.Item2[index - 1].Handle, buffer, toAdapter);
                        toAdapter.Clear();
                    }

                    packetList = ndisapi.ReadPackets(adapterList.Item2[index - 1].Handle, buffer);
                }
                ;

                #endregion
                packetEvent.Reset();
            } while (!stopCapturing);

            Console.WriteLine("-- Filtering stopped");

            //
            // Release driver and associated resources
            //
            buffer.Dispose();

            ndisapi.SetPacketEvent(adapterList.Item2[index - 1].Handle, null);

            ndisapi.SetAdapterMode(
                adapterList.Item2[index - 1].Handle,
                0
                );

            //
            // Display loaded static filters
            //
            DumpStaticFilters();
        }