使用C#在一个LAN中获取所有ip和mac地址列表太慢

时间:2016-10-15 15:38:40

标签: c# macos list lan arp

我想使用C#获取一个局域网中所有ip和mac地址的列表。目前我正在向局域网中的每个IP发送ARP数据包,例如192.168.0.1~192.168.0.254,以获取其mac地址,但是发送所有arp数据包并获得所有回复需要4分钟。 有没有其他方法可以做到这一点?非常感谢!

    public void ScanLAN(IP startIP, IP endIP)
    {   
        var targetIPList = new List<IPAddress>();
        while (!startIP.Equals(endIP))
        {
            targetIPList.Add(startIP.IPAddress);
            startIP.AddOne();
        }

        var arpPackets = new Packet[targetIPList.Count];
        for (int i = 0; i < arpPackets.Length; ++i)
        {
            arpPackets[i] = BuildRequest(targetIPList[i], LocalMAC, LocalIP);
        }

        //create a "tcpdump" filter for allowing only arp replies to be read
        String arpFilter = "arp and ether dst " + LocalMAC.ToString();

        //open the device with 20ms timeout
        _device.Open(DeviceMode.Promiscuous, 20);

        //set the filter
        _device.Filter = arpFilter;

        scanThread = new System.Threading.Thread(() =>
        {
            for (int i = 0; i < arpPackets.Length; ++i)
            {

                var lastRequestTime = DateTime.FromBinary(0);
                var requestInterval = new TimeSpan(0, 0, 1);
                var timeoutDateTime = DateTime.Now + timeout;
                while (DateTime.Now < timeoutDateTime)
                {
                    if (requestInterval < (DateTime.Now - lastRequestTime))
                    {
                        // inject the packet to the wire
                        _device.SendPacket(arpPackets[i]);
                        lastRequestTime = DateTime.Now;
                    }

                    //read the next packet from the network
                    var reply = _device.GetNextPacket();
                    if (reply == null)
                    {
                        continue;
                    }

                    // parse the packet
                    var packet = PacketDotNet.Packet.ParsePacket(reply.LinkLayerType, reply.Data);

                    // is this an arp packet?
                    var arpPacket = PacketDotNet.ARPPacket.GetEncapsulated(packet);
                    if (arpPacket == null)
                    {
                        continue;
                    }

                    //if this is the reply we're looking for, stop
                    if (arpPacket.SenderProtocolAddress.Equals(targetIPList[i]))
                    {
                        if (ResolvedEvent != null)
                        {
                            ResolvedEvent(this, new ResolvedEventArgs()
                            {
                                IPAddress = arpPacket.SenderProtocolAddress,
                                PhysicalAddress = arpPacket.SenderHardwareAddress
                            });
                        }
                        break;
                    }
                }
            }
            _device.Close();
            Console.WriteLine("exit scan");
            if (ScanStopedEvent != null)
            {
                ScanStopedEvent(this, new EventArgs());
            }
        });
        scanThread.Start();
    }

0 个答案:

没有答案