public void Scan(ICollection <IpV4Address> addresses) { if (IsScanning) { return; } IsScanning = true; _totalScans = addresses.Count; _finishedScans = 0; var sourceAddress = ((IpV4SocketAddress)_networkInfo.InterfaceAddress.Address).Address; var sourcePhysicalAddress = _networkInfo.Interface.GetNetworkInterface().GetPhysicalAddress(); _tokenSource = new CancellationTokenSource(); var cancellationToken = _tokenSource.Token; var discoveredHosts = new List <Host>(); Task.Run(() => { while (true) { if (cancellationToken.IsCancellationRequested) { break; } _networkInfo.Communicator.ReceivePacket(out Packet p); if (!cancellationToken.IsCancellationRequested && p != null && p.IsValid && p.Ethernet.IsValid && p.Ethernet.EtherType == EthernetType.Arp && p.Ethernet.Arp.IsValid && p.Ethernet.Arp.Operation == ArpOperation.Reply && addresses.Contains(p.Ethernet.Arp.SenderProtocolIpV4Address) && p.Ethernet.Arp.TargetProtocolIpV4Address == sourceAddress) { var host = new Host( p.Ethernet.Arp.SenderProtocolIpV4Address, new MacAddress(BitConverter.ToString(p.Ethernet.Arp.SenderHardwareAddress.ToArray()).Replace('-', ':')) ); if (!discoveredHosts.Contains(host)) { discoveredHosts.Add(host); } } } }, cancellationToken); Task.Run(() => { foreach (var addr in addresses) { var packet = PacketBuilder.Build( DateTime.Now, new EthernetLayer() { EtherType = EthernetType.None, Source = NetworkUtilities.PhysicalAddressToMacAddress(sourcePhysicalAddress), Destination = NetworkUtilities.BroadcastMac, }, new ArpLayer() { ProtocolType = EthernetType.IpV4, Operation = ArpOperation.Request, SenderProtocolAddress = sourceAddress.ToBytes(), SenderHardwareAddress = sourcePhysicalAddress.GetAddressBytes().AsReadOnly(), TargetProtocolAddress = addr.ToBytes(), TargetHardwareAddress = MacAddress.Zero.ToBytes(), } ); _networkInfo.Communicator.SendPacket(packet); if (cancellationToken.IsCancellationRequested) { break; } Interlocked.Increment(ref _finishedScans); OnHostScanned(new HostScannedEventArgs(_totalScans, _finishedScans)); Thread.Sleep(Config.ScanSendInterval); } if (!cancellationToken.IsCancellationRequested) { Thread.Sleep(Config.ScanReplyTimeout); _tokenSource.Cancel(); foreach (var host in discoveredHosts) { host.HostName = NetworkUtilities.GetHostNameByIp(host.IpAddress); } OnScanFinished(new ScanFinishedEventArgs(discoveredHosts)); } IsScanning = false; }, cancellationToken); }