public void ScanAsync(IPAddress[] ipAddresses, CancellationToken cancellationToken) { // Start the scan in a separat task Task.Run(() => { _progressValue = 0; // Create dns client and set options if (ResolveHostname) { DnsLookupClient = UseCustomDNSServer ? new LookupClient(new IPEndPoint(CustomDNSServer, CustomDNSPort)) : new LookupClient(); DnsLookupClient.UseCache = DNSUseCache; DnsLookupClient.Recursion = DNSRecursion; DnsLookupClient.Timeout = DNSTimeout; DnsLookupClient.Retries = DNSRetries; DnsLookupClient.UseTcpOnly = DNSUseTCPOnly; } // Modify the ThreadPool for better performance ThreadPool.GetMinThreads(out var workerThreads, out var completionPortThreads); ThreadPool.SetMinThreads(workerThreads + Threads, completionPortThreads + Threads); try { var parallelOptions = new ParallelOptions { CancellationToken = cancellationToken, MaxDegreeOfParallelism = Threads }; Parallel.ForEach(ipAddresses, parallelOptions, ipAddress => { var pingInfo = new PingInfo(); var pingable = false; // PING using (var ping = new System.Net.NetworkInformation.Ping()) { for (var i = 0; i < ICMPAttempts; i++) { try { var pingReply = ping.Send(ipAddress, ICMPTimeout, ICMPBuffer); if (pingReply != null && IPStatus.Success == pingReply.Status) { pingInfo = new PingInfo(pingReply.Address, pingReply.Buffer.Length, pingReply.RoundtripTime, pingReply.Options.Ttl, pingReply.Status); pingable = true; break; // Continue with the next checks... } if (pingReply != null) { pingInfo = new PingInfo(ipAddress, pingReply.Status); } } catch (PingException) { } // Don't scan again, if the user has canceled (when more than 1 attempt) if (cancellationToken.IsCancellationRequested) { break; } } } if (pingable || ShowScanResultForAllIPAddresses) { // DNS var hostname = string.Empty; if (ResolveHostname) { try { var dnsQueryResponse = DnsLookupClient.QueryReverse(ipAddress); if (dnsQueryResponse != null && !dnsQueryResponse.HasError) { hostname = dnsQueryResponse.Answers.PtrRecords().FirstOrDefault()?.PtrDomainName; } else { hostname = DNSShowErrorMessage ? dnsQueryResponse.ErrorMessage : ""; } } catch (Exception ex) { hostname = DNSShowErrorMessage ? ex.Message : ""; } } // ARP PhysicalAddress macAddress = null; var vendor = string.Empty; if (ResolveMACAddress) { // Get info from arp table var arpTableInfo = ARP.GetTable().FirstOrDefault(p => p.IPAddress.ToString() == ipAddress.ToString()); if (arpTableInfo != null) { macAddress = arpTableInfo.MACAddress; } // Check if it is the local mac if (macAddress == null) { var networkInferfaceInfo = NetworkInterface.GetNetworkInterfaces().FirstOrDefault(p => p.IPv4Address.Contains(ipAddress)); if (networkInferfaceInfo != null) { macAddress = networkInferfaceInfo.PhysicalAddress; } } // Vendor lookup if (macAddress != null) { var info = OUILookup.Lookup(macAddress.ToString()).FirstOrDefault(); if (info != null) { vendor = info.Vendor; } } } OnHostFound(new HostFoundArgs(pingInfo, hostname, macAddress, vendor)); } IncreaseProcess(); }); OnScanComplete(); } catch (OperationCanceledException) // If user has canceled { // Check if the scan is already complete... if (ipAddresses.Length == _progressValue) { OnScanComplete(); } else { OnUserHasCanceled(); } } finally { // Reset the ThreadPool to default ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads); ThreadPool.SetMinThreads(workerThreads - Threads, completionPortThreads - Threads); } }, cancellationToken); }
public void ScanAsync(IPAddress[] ipAddresses, IPScannerOptions ipScannerOptions, CancellationToken cancellationToken) { // Start the scan in a separat task Task.Run(() => { _progressValue = 0; // Modify the ThreadPool for better performance ThreadPool.GetMinThreads(out int workerThreads, out int completionPortThreads); ThreadPool.SetMinThreads(workerThreads + ipScannerOptions.Threads, completionPortThreads + ipScannerOptions.Threads); try { var parallelOptions = new ParallelOptions { CancellationToken = cancellationToken, MaxDegreeOfParallelism = ipScannerOptions.Threads }; Parallel.ForEach(ipAddresses, parallelOptions, ipAddress => { var pingInfo = new PingInfo(); var pingable = false; // PING using (var ping = new System.Net.NetworkInformation.Ping()) { for (int i = 0; i < ipScannerOptions.ICMPAttempts; i++) { try { var pingReply = ping.Send(ipAddress, ipScannerOptions.ICMPTimeout, ipScannerOptions.ICMPBuffer); if (pingReply != null && IPStatus.Success == pingReply.Status) { pingInfo = new PingInfo(pingReply.Address, pingReply.Buffer.Count(), pingReply.RoundtripTime, pingReply.Options.Ttl, pingReply.Status); pingable = true; break; // Continue with the next checks... } if (pingReply != null) { pingInfo = new PingInfo(ipAddress, pingReply.Status); } } catch (PingException) { } // Don't scan again, if the user has canceled (when more than 1 attempt) if (cancellationToken.IsCancellationRequested) { break; } } } if (pingable || ipScannerOptions.ShowScanResultForAllIPAddresses) { // DNS var hostname = string.Empty; if (ipScannerOptions.ResolveHostname) { var options = new DNSLookupOptions() { UseCustomDNSServer = ipScannerOptions.UseCustomDNSServer, CustomDNSServers = ipScannerOptions.CustomDNSServer, Port = ipScannerOptions.DNSPort, Attempts = ipScannerOptions.DNSAttempts, Timeout = ipScannerOptions.DNSTimeout, TransportType = ipScannerOptions.DNSTransportType, UseResolverCache = ipScannerOptions.DNSUseResolverCache, Recursion = ipScannerOptions.DNSRecursion, }; hostname = DNSLookup.ResolvePTR(ipAddress, options).Item2.FirstOrDefault(); } // ARP PhysicalAddress macAddress = null; var vendor = string.Empty; if (ipScannerOptions.ResolveMACAddress) { // Get info from arp table var arpTableInfo = ARP.GetTable().FirstOrDefault(p => p.IPAddress.ToString() == ipAddress.ToString()); if (arpTableInfo != null) { macAddress = arpTableInfo.MACAddress; } // Check if it is the local mac if (macAddress == null) { var networkInferfaceInfo = NetworkInterface.GetNetworkInterfaces().FirstOrDefault(p => p.IPv4Address.Contains(ipAddress)); if (networkInferfaceInfo != null) { macAddress = networkInferfaceInfo.PhysicalAddress; } } // Vendor lookup if (macAddress != null) { var info = OUILookup.Lookup(macAddress.ToString()).FirstOrDefault(); if (info != null) { vendor = info.Vendor; } } } OnHostFound(new HostFoundArgs(pingInfo, hostname, macAddress, vendor)); } IncreaseProcess(); }); OnScanComplete(); } catch (OperationCanceledException) // If user has canceled { // Check if the scan is already complete... if (ipAddresses.Length == _progressValue) { OnScanComplete(); } else { OnUserHasCanceled(); } } finally { // Reset the ThreadPool to default ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads); ThreadPool.SetMinThreads(workerThreads - ipScannerOptions.Threads, completionPortThreads - ipScannerOptions.Threads); } }, cancellationToken); }