Skip to content

Commit 225d3ea

Browse files
committed
1 parent dc12ddc commit 225d3ea

8 files changed

Lines changed: 126 additions & 86 deletions

File tree

Source/NETworkManager/Models/Network/PortInfo.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
using System.Net;
1+
using System;
2+
using System.Net;
23

34
namespace NETworkManager.Models.Network
45
{
56
public class PortInfo
67
{
7-
public IPAddress IPAddress { get; set; }
8+
public Tuple<IPAddress, string> Host { get; set; }
89
public int Port { get; set; }
910
public PortLookupInfo LookupInfo { get; set; }
1011
public PortStatus Status { get; set; }
@@ -14,17 +15,17 @@ public PortInfo()
1415

1516
}
1617

17-
public PortInfo(IPAddress ipAddress, int port, PortLookupInfo lookupInfo, PortStatus status)
18+
public PortInfo(Tuple<IPAddress, string> host, int port, PortLookupInfo lookupInfo, PortStatus status)
1819
{
19-
ipAddress = IPAddress;
20+
Host = host;
2021
Port = port;
2122
LookupInfo = lookupInfo;
2223
Status = status;
2324
}
2425

2526
public static PortInfo Parse(PortScannedArgs e)
2627
{
27-
return new PortInfo(e.IPAddress, e.Port, e.LookupInfo, e.Status);
28+
return new PortInfo(e.Host, e.Port, e.LookupInfo, e.Status);
2829
}
2930

3031
public enum PortStatus

Source/NETworkManager/Models/Network/PortScannedArgs.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
using System.Net;
1+
using System;
2+
using System.Net;
23

34
namespace NETworkManager.Models.Network
45
{
5-
public class PortScannedArgs : System.EventArgs
6+
public class PortScannedArgs : EventArgs
67
{
7-
public IPAddress IPAddress { get; set; }
8+
public Tuple <IPAddress, string> Host { get; set; }
89
public int Port { get; set; }
910
public PortLookupInfo LookupInfo { get; set; }
1011
public PortInfo.PortStatus Status { get; set; }
@@ -14,9 +15,9 @@ public PortScannedArgs()
1415

1516
}
1617

17-
public PortScannedArgs(IPAddress ipAddress, int port, PortLookupInfo lookupInfo, PortInfo.PortStatus status)
18+
public PortScannedArgs(Tuple<IPAddress, string> host, int port, PortLookupInfo lookupInfo, PortInfo.PortStatus status)
1819
{
19-
IPAddress = ipAddress;
20+
Host = host;
2021
Port = port;
2122
LookupInfo = lookupInfo;
2223
Status = status;

Source/NETworkManager/Models/Network/PortScanner.cs

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
24
using System.Linq;
35
using System.Net;
46
using System.Net.Sockets;
@@ -44,66 +46,69 @@ protected virtual void OnUserHasCanceled()
4446
#endregion
4547

4648
#region Methods
47-
public void ScanAsync(IPAddress ipAddress, int[] ports, PortScannerOptions portScannerOptions, CancellationToken cancellationToken)
49+
public void ScanAsync(List<Tuple<IPAddress, string>> hostData, int[] ports, PortScannerOptions portScannerOptions, CancellationToken cancellationToken)
4850
{
4951
progressValue = 0;
5052

5153
// Modify the ThreadPool for better performance
52-
5354
ThreadPool.GetMinThreads(out int workerThreads, out int completionPortThreads);
5455
ThreadPool.SetMinThreads(workerThreads + portScannerOptions.Threads, completionPortThreads + portScannerOptions.Threads);
5556

5657
Task.Run(() =>
5758
{
58-
try
59+
foreach (Tuple<IPAddress, string> host in hostData)
5960
{
60-
ParallelOptions parallelOptions = new ParallelOptions()
61-
{
62-
CancellationToken = cancellationToken,
63-
MaxDegreeOfParallelism = portScannerOptions.Threads
64-
};
65-
66-
// foreach ip, Parallel.ForEach port...
67-
Parallel.ForEach(ports, parallelOptions, port =>
61+
try
6862
{
69-
// Test if port is open
70-
using (TcpClient tcpClient = ipAddress.AddressFamily == AddressFamily.InterNetworkV6 ? new TcpClient(AddressFamily.InterNetworkV6) : new TcpClient(AddressFamily.InterNetwork))
63+
ParallelOptions parallelOptions = new ParallelOptions()
7164
{
72-
IAsyncResult tcpClientConnection = tcpClient.BeginConnect(ipAddress, port, null, null);
65+
CancellationToken = cancellationToken,
66+
MaxDegreeOfParallelism = portScannerOptions.Threads
67+
};
7368

74-
if (tcpClientConnection.AsyncWaitHandle.WaitOne(portScannerOptions.Timeout, false))
69+
// foreach ip, Parallel.ForEach port...
70+
Parallel.ForEach(ports, parallelOptions, port =>
71+
{
72+
// Test if port is open
73+
using (TcpClient tcpClient = host.Item1.AddressFamily == AddressFamily.InterNetworkV6 ? new TcpClient(AddressFamily.InterNetworkV6) : new TcpClient(AddressFamily.InterNetwork))
7574
{
76-
try
77-
{
78-
tcpClient.EndConnect(tcpClientConnection);
75+
IAsyncResult tcpClientConnection = tcpClient.BeginConnect(host.Item1, port, null, null);
7976

80-
OnPortScanned(new PortScannedArgs(ipAddress, port, PortLookup.Lookup(port).FirstOrDefault(x => x.Protocol == PortLookup.Protocol.tcp), PortInfo.PortStatus.Open));
77+
if (tcpClientConnection.AsyncWaitHandle.WaitOne(portScannerOptions.Timeout, false))
78+
{
79+
try
80+
{
81+
tcpClient.EndConnect(tcpClientConnection);
82+
83+
OnPortScanned(new PortScannedArgs(host, port, PortLookup.Lookup(port).FirstOrDefault(x => x.Protocol == PortLookup.Protocol.tcp), PortInfo.PortStatus.Open));
84+
}
85+
catch
86+
{
87+
if (portScannerOptions.ShowClosed)
88+
OnPortScanned(new PortScannedArgs(host, port, PortLookup.Lookup(port).FirstOrDefault(x => x.Protocol == PortLookup.Protocol.tcp), PortInfo.PortStatus.Closed));
89+
}
8190
}
82-
catch
91+
else
8392
{
8493
if (portScannerOptions.ShowClosed)
85-
OnPortScanned(new PortScannedArgs(ipAddress, port, PortLookup.Lookup(port).FirstOrDefault(x => x.Protocol == PortLookup.Protocol.tcp), PortInfo.PortStatus.Closed));
94+
OnPortScanned(new PortScannedArgs(host, port, PortLookup.Lookup(port).FirstOrDefault(x => x.Protocol == PortLookup.Protocol.tcp), PortInfo.PortStatus.Closed));
8695
}
8796
}
88-
else
89-
{
90-
if (portScannerOptions.ShowClosed)
91-
OnPortScanned(new PortScannedArgs(ipAddress, port, PortLookup.Lookup(port).FirstOrDefault(x => x.Protocol == PortLookup.Protocol.tcp), PortInfo.PortStatus.Closed));
92-
}
93-
}
94-
95-
// Increase the progress
96-
Interlocked.Increment(ref progressValue);
97-
OnProgressChanged();
98-
});
9997

100-
OnScanComplete();
101-
}
102-
catch (OperationCanceledException) // If user has canceled
103-
{
104-
OnUserHasCanceled();
98+
// Increase the progress
99+
Interlocked.Increment(ref progressValue);
100+
OnProgressChanged();
101+
});
102+
}
103+
catch (OperationCanceledException) // If user has canceled
104+
{
105+
OnUserHasCanceled();
106+
break;
107+
}
105108
}
106-
});
109+
110+
OnScanComplete();
111+
});
107112

108113
// Reset the ThreadPool to defaul
109114
ThreadPool.SetMinThreads(workerThreads, completionPortThreads);

Source/NETworkManager/Models/Settings/SettingsInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ public List<string> PortScanner_PortsHistory
649649
}
650650
}
651651

652-
private int _portScanner_Threads = 50;
652+
private int _portScanner_Threads = 100;
653653
public int PortScanner_Threads
654654
{
655655
get { return _portScanner_Threads; }

Source/NETworkManager/Resources/Localization/Resources.de-DE.xaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,8 @@
216216
<system:String x:Key="String_UnkownError">Unbekannter Fehler!</system:String>
217217
<system:String x:Key="String_TimeoutWhenQueryingDNSServer">Timeout beim Abfragen des DNS-Servers mit der IP-Adresse "{0}"!</system:String>
218218
<system:String x:Key="String_ResolveCNAME">CNAME auflösen</system:String>
219-
219+
<system:String x:Key="String_Host">Host</system:String>
220+
220221
<!-- Buttons -->
221222
<system:String x:Key="String_Button_Change">Wechseln</system:String>
222223
<system:String x:Key="String_Button_Default">Standard</system:String>
@@ -270,7 +271,7 @@
270271
<system:String x:Key="String_Watermark_LocationOfTheImport">Speicherort der Importdatei...</system:String>
271272
<system:String x:Key="String_Watermark_ExampleMACAddressesOrVendor">01:23:45:67:89:AB; 01-23-45; AA11BB; 00F1A2C3D4E5; Intel Corp; Asus</system:String>
272273
<system:String x:Key="String_Watermark_EamplePortScanRange">22; 80; 443; 500 - 999; 8080</system:String>
273-
<system:String x:Key="String_Watermark_ExampleHostOrIPv4Address">192.168.178.1 oder fritz.box</system:String>
274+
<system:String x:Key="String_Watermark_ExampleHostnameAndOrIPAddress">192.168.178.1; fritz.box; localhost</system:String>
274275
<system:String x:Key="String_Watermark_ExampleSubnetmaskOrCIDR">255.255.255.0 or /24</system:String>
275276
<system:String x:Key="String_Watermark_ExampleIPv4Gateway">192.168.178.1</system:String>
276277
<system:String x:Key="String_Watermark_ExampleIPv4DNS">8.8.8.8</system:String>

Source/NETworkManager/Resources/Localization/Resources.en-US.xaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,8 @@
218218
<system:String x:Key="String_UnkownError">Unkown error!</system:String>
219219
<system:String x:Key="String_TimeoutWhenQueryingDNSServer">Timeout when querying the DNS server with the IP-Address "{0}"!</system:String>
220220
<system:String x:Key="String_ResolveCNAME">Resolve CNAME</system:String>
221-
221+
<system:String x:Key="String_Host">Host</system:String>
222+
222223
<!-- Buttons -->
223224
<system:String x:Key="String_Button_Change">Change</system:String>
224225
<system:String x:Key="String_Button_Default">Default</system:String>
@@ -272,7 +273,7 @@
272273
<system:String x:Key="String_Watermark_LocationOfTheImport">Location of the import file...</system:String>
273274
<system:String x:Key="String_Watermark_ExampleMACAddressesOrVendor">01:23:45:67:89:AB; 01-23-45; AA11BB; 00F1A2C3D4E5; Intel Corp; Asus</system:String>
274275
<system:String x:Key="String_Watermark_EamplePortScanRange">22; 80; 443; 500 - 999; 8080</system:String>
275-
<system:String x:Key="String_Watermark_ExampleHostOrIPv4Address">192.168.178.1 or fritz.box</system:String>
276+
<system:String x:Key="String_Watermark_ExampleHostnameAndOrIPAddress">192.168.178.1; fritz.box</system:String>
276277
<system:String x:Key="String_Watermark_ExampleSubnetmaskOrCIDR">255.255.255.0 or /24</system:String>
277278
<system:String x:Key="String_Watermark_ExampleIPv4Gateway">192.168.178.1</system:String>
278279
<system:String x:Key="String_Watermark_ExampleIPv4DNS">8.8.8.8</system:String>

Source/NETworkManager/ViewModels/Applications/PortScannerViewModel.cs

Lines changed: 59 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -221,45 +221,77 @@ private async void StartScan()
221221

222222
cancellationTokenSource = new CancellationTokenSource();
223223

224-
// Try to parse the string into an IP-Address
225-
IPAddress.TryParse(HostnameOrIPAddress, out IPAddress ipAddress);
224+
string[] HostnameOrIPAddresses = HostnameOrIPAddress.Split(';');
226225

227-
try
226+
List<Tuple<IPAddress, string>> hostData = new List<Tuple<IPAddress, string>>();
227+
228+
for (int i = 0; i < HostnameOrIPAddresses.Length; i++)
228229
{
229-
// Resolve DNS
230-
// Try to resolve the hostname
231-
if (ipAddress == null)
232-
{
233-
IPHostEntry ipHostEntrys = await Dns.GetHostEntryAsync(HostnameOrIPAddress);
230+
string hostname = HostnameOrIPAddresses[i];
231+
IPAddress.TryParse(hostname, out IPAddress ipAddress);
234232

235-
foreach (IPAddress ip in ipHostEntrys.AddressList)
233+
try
234+
{
235+
// Resolve DNS
236+
// Try to resolve the hostname
237+
if (ipAddress == null)
236238
{
237-
if (ip.AddressFamily == AddressFamily.InterNetwork && SettingsManager.Current.PortScanner_ResolveHostnamePreferIPv4)
239+
IPHostEntry ipHostEntry = await Dns.GetHostEntryAsync(HostnameOrIPAddress);
240+
241+
foreach (IPAddress ip in ipHostEntry.AddressList)
238242
{
239-
ipAddress = ip;
240-
continue;
243+
if (ip.AddressFamily == AddressFamily.InterNetwork && SettingsManager.Current.PortScanner_ResolveHostnamePreferIPv4)
244+
{
245+
ipAddress = ip;
246+
continue;
247+
}
248+
else if (ip.AddressFamily == AddressFamily.InterNetworkV6 && !SettingsManager.Current.PortScanner_ResolveHostnamePreferIPv4)
249+
{
250+
ipAddress = ip;
251+
continue;
252+
}
241253
}
242-
else if (ip.AddressFamily == AddressFamily.InterNetworkV6 && !SettingsManager.Current.PortScanner_ResolveHostnamePreferIPv4)
254+
255+
// Fallback --> If we could not resolve our prefered ip protocol
256+
if (ipAddress == null)
243257
{
244-
ipAddress = ip;
245-
continue;
258+
foreach (IPAddress ip in ipHostEntry.AddressList)
259+
{
260+
ipAddress = ip;
261+
continue;
262+
}
246263
}
247264
}
248-
249-
// Fallback --> If we could not resolve our prefered ip protocol
250-
if (ipAddress == null)
265+
else
251266
{
252-
foreach (IPAddress ip in ipHostEntrys.AddressList)
253-
{
254-
ipAddress = ip;
255-
continue;
256-
}
267+
IPHostEntry ipHostEntry = await Dns.GetHostEntryAsync(ipAddress);
268+
269+
if (ipHostEntry != null)
270+
hostname = ipHostEntry.HostName;
257271
}
258272
}
273+
catch (SocketException) // This will catch DNS resolve errors
274+
{
275+
await dialogCoordinator.ShowMessageAsync(this, Application.Current.Resources["String_Header_DnsError"] as string, Application.Current.Resources["String_CouldNotResolveHostnameMessage"] as string, MessageDialogStyle.Affirmative, dialogSettings);
276+
continue;
277+
}
259278

260-
int[] ports = await PortRangeHelper.ConvertPortRangeToIntArrayAsync(Ports);
279+
hostData.Add(Tuple.Create(ipAddress, hostname));
280+
}
281+
282+
if (hostData.Count == 0)
283+
{
284+
IsScanRunning = false;
285+
await dialogCoordinator.ShowMessageAsync(this, Application.Current.Resources["String_Header_DnsError"] as string, "Nothing to do", MessageDialogStyle.Affirmative, dialogSettings);
286+
287+
return;
288+
}
289+
290+
int[] ports = await PortRangeHelper.ConvertPortRangeToIntArrayAsync(Ports);
261291

262-
ProgressBarMaximum = ports.Length;
292+
try
293+
{
294+
ProgressBarMaximum = ports.Length * hostData.Count;
263295
ProgressBarValue = 0;
264296

265297
PreparingScan = false;
@@ -280,13 +312,9 @@ private async void StartScan()
280312
portScanner.ProgressChanged += PortScanner_ProgressChanged;
281313
portScanner.UserHasCanceled += PortScanner_UserHasCanceled;
282314

283-
portScanner.ScanAsync(ipAddress, ports, portScannerOptions, cancellationTokenSource.Token);
284-
}
285-
catch (SocketException) // This will catch DNS resolve errors
286-
{
287-
IsScanRunning = false;
288-
await dialogCoordinator.ShowMessageAsync(this, Application.Current.Resources["String_Header_DnsError"] as string, Application.Current.Resources["String_CouldNotResolveHostnameMessage"] as string, MessageDialogStyle.Affirmative, dialogSettings);
315+
portScanner.ScanAsync(hostData, ports, portScannerOptions, cancellationTokenSource.Token);
289316
}
317+
290318
catch (Exception ex) // This will catch any exception
291319
{
292320
IsScanRunning = false;

0 commit comments

Comments
 (0)