Ejemplo n.º 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);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 実行する
        /// </summary>
        public List <ScanResponse> Execute()
        {
            var ret = new List <ScanResponse>();
            // デバイス変換
            var device = _captureDevice as NpcapDevice;

            if (device == null)
            {
                throw new InvalidCastException(string.Format("デバイス {0} を NpcapDevice に変換できません", device.Description));
            }

            // 送信元IPアドレス
            var srcIPAddress = GetIPv4(device);

            // SYNスキャン
            foreach (var request in _scanRequests)
            {
                // 送信先MACアドレス
                var arp = new ARP(device);
                var targetMacAddress = arp.Resolve(request.IPAddress);

                if (targetMacAddress == null)
                {
                    ret.Add(new ScanResponse()
                    {
                        IPAddress = request.IPAddress,
                        Port      = request.Port,
                        Status    = PortStatus.UnResolved
                    });
                    continue;
                    //throw new InvalidOperationException(string.Format("アドレス {0} を ARP 解決できません", request.IPAddress.ToString()));
                }

                // TCPヘッダ生成
                var tcpPacket = new TcpPacket(1024, request.Port);
                tcpPacket.Synchronize = !tcpPacket.Synchronize;
                tcpPacket.WindowSize  = 4096;

                // IPヘッダ生成
                var ipPacket = new IPv4Packet(srcIPAddress, request.IPAddress);

                // Ehternetヘッダ生成
                var ethernetPacket = new EthernetPacket(device.Interface.MacAddress, targetMacAddress, EthernetType.None);

                // TCPパケット生成
                ipPacket.PayloadPacket = tcpPacket;
                tcpPacket.UpdateTcpChecksum();
                ethernetPacket.PayloadPacket = ipPacket;
                ipPacket.UpdateIPChecksum();

                for (int retryCount = 0; retryCount < _maxRetryCount; retryCount++)
                {
                    // オープン
                    device.Open(DeviceMode.Normal, 1000);
                    // フィルタセット
                    device.Filter = "src host " + request.IPAddress + " and src port " + request.Port + " and (tcp[13] & 18 != 0) or (tcp[13] & 4 != 0)";

                    try
                    {
                        // TCPパケット送信
                        device.SendPacket(ethernetPacket);

                        // 受信パケット取得
                        var rawpacket = device.GetNextPacket();

                        if (rawpacket == null)
                        {
                            if ((retryCount + 1) >= _maxRetryCount)
                            {
                                ret.Add(new ScanResponse()
                                {
                                    IPAddress = request.IPAddress,
                                    Port      = request.Port,
                                    Status    = PortStatus.Timeout
                                });
                                break;
                            }
                            continue;
                        }
                        else
                        {
                            // SYN/ACKフラグが立っていたら、open判定
                            // RSTフラグが立っていたらclosed判定
                            var response = Packet.ParsePacket(rawpacket.LinkLayerType, rawpacket.Data);
                            if (response is EthernetPacket eth)
                            {
                                var ip = response.Extract <IPPacket>();
                                if (ip != null)
                                {
                                    var tcp = response.Extract <TcpPacket>();
                                    if (tcp != null)
                                    {
                                        if (tcp.Acknowledgment && tcp.Synchronize)
                                        {
                                            ret.Add(new ScanResponse()
                                            {
                                                IPAddress = request.IPAddress,
                                                Port      = request.Port,
                                                Status    = PortStatus.Open
                                            });
                                        }
                                        else if (tcp.Reset)
                                        {
                                            ret.Add(new ScanResponse()
                                            {
                                                IPAddress = request.IPAddress,
                                                Port      = request.Port,
                                                Status    = PortStatus.Closed
                                            });
                                        }
                                        else
                                        {
                                            ret.Add(new ScanResponse()
                                            {
                                                IPAddress = request.IPAddress,
                                                Port      = request.Port,
                                                Status    = PortStatus.UnKnown
                                            });
                                        }
                                    }
                                }
                            }
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(ex.Message);
                    }
                    finally
                    {
                        if (device.Opened)
                        {
                            device.Close();
                        }
                    }
                }
            }
            return(ret);
        }