Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Ping Monitor improvements #2573

Merged
merged 11 commits into from
Dec 9, 2023
Prev Previous commit
Next Next commit
Feature: DNS Lookup / Port Scanner improve group string
  • Loading branch information
BornToBeRoot committed Dec 3, 2023
commit a60869c80300baf4955041ba6d3ceaa53ca01e0b
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ private static void CreateCsv(IEnumerable<DNSLookupRecordInfo> collection, strin
var stringBuilder = new StringBuilder();

stringBuilder.AppendLine(
$"{nameof(DNSLookupRecordInfo.DomainName)},{nameof(DNSLookupRecordInfo.TTL)},{nameof(DNSLookupRecordInfo.RecordClass)},{nameof(DNSLookupRecordInfo.RecordType)},{nameof(DNSLookupRecordInfo.Result)},{nameof(DNSLookupRecordInfo.Server)},{nameof(DNSLookupRecordInfo.IPEndPoint)}");
$"{nameof(DNSLookupRecordInfo.DomainName)},{nameof(DNSLookupRecordInfo.TTL)},{nameof(DNSLookupRecordInfo.RecordClass)},{nameof(DNSLookupRecordInfo.RecordType)},{nameof(DNSLookupRecordInfo.Result)},{nameof(DNSLookupRecordInfo.NameServerIPAddress)},{nameof(DNSLookupRecordInfo.NameServerHostName)},{nameof(DNSLookupRecordInfo.NameServerPort)}");

foreach (var info in collection)
stringBuilder.AppendLine(
$"{info.DomainName},{info.TTL},{info.RecordClass},{info.RecordType},{info.Result},{info.Server},{info.IPEndPoint}");
$"{info.DomainName},{info.TTL},{info.RecordClass},{info.RecordType},{info.Result},{info.NameServerIPAddress},{info.NameServerHostName},{info.NameServerPort}");

System.IO.File.WriteAllText(filePath, stringBuilder.ToString());
}
Expand All @@ -73,8 +73,9 @@ private static void CreateXml(IEnumerable<DNSLookupRecordInfo> collection, strin
new XElement(nameof(DNSLookupRecordInfo.RecordClass), info.RecordClass),
new XElement(nameof(DNSLookupRecordInfo.RecordType), info.RecordType),
new XElement(nameof(DNSLookupRecordInfo.Result), info.Result),
new XElement(nameof(DNSLookupRecordInfo.Server), info.Server),
new XElement(nameof(DNSLookupRecordInfo.IPEndPoint), info.IPEndPoint)))));
new XElement(nameof(DNSLookupRecordInfo.NameServerIPAddress), info.NameServerIPAddress),
new XElement(nameof(DNSLookupRecordInfo.NameServerHostName), info.NameServerHostName),
new XElement(nameof(DNSLookupRecordInfo.NameServerPort), info.NameServerPort)))));

document.Save(filePath);
}
Expand All @@ -97,8 +98,9 @@ private static void CreateJson(IReadOnlyList<DNSLookupRecordInfo> collection, st
collection[i].RecordClass,
collection[i].RecordType,
collection[i].Result,
collection[i].Server,
collection[i].IPEndPoint
collection[i].NameServerIPAddress,
collection[i].NameServerHostName,
collection[i].NameServerPort
};
}

Expand Down
33 changes: 20 additions & 13 deletions Source/NETworkManager.Models/Network/DNSLookup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
using DnsClient.Protocol;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
using NETworkManager.Utilities;

namespace NETworkManager.Models.Network;

Expand Down Expand Up @@ -116,8 +116,15 @@ public void ResolveAsync(IEnumerable<string> hosts)
var queries = _addSuffix && _settings.QueryType != QueryType.PTR ? GetHostWithSuffix(hosts) : hosts;

// Foreach dns server
Parallel.ForEach(_servers, dnsServer =>
Parallel.ForEach(_servers, async dnsServer =>
{
// Get the dns server hostname for some additional information
var dnsServerHostName = string.Empty;

var dnsResult = await DNSClient.GetInstance().ResolvePtrAsync(dnsServer.Address);
if (!dnsResult.HasError)
dnsServerHostName = dnsResult.Value;

// Init each dns server once
LookupClientOptions lookupClientOptions = new(dnsServer)
{
Expand All @@ -129,7 +136,7 @@ public void ResolveAsync(IEnumerable<string> hosts)
};

LookupClient lookupClient = new(lookupClientOptions);

// Foreach host
Parallel.ForEach(queries, query =>
{
Expand All @@ -153,7 +160,7 @@ public void ResolveAsync(IEnumerable<string> hosts)
}

// Process the results...
ProcessDnsAnswers(dnsResponse.Answers, dnsResponse.NameServer);
ProcessDnsAnswers(dnsResponse.Answers, dnsResponse.NameServer, dnsServerHostName);
}
catch (Exception ex)
{
Expand All @@ -171,7 +178,7 @@ public void ResolveAsync(IEnumerable<string> hosts)
/// </summary>
/// <param name="answers">List of DNS resource records.</param>
/// <param name="nameServer">DNS name server that answered the query.</param>
private void ProcessDnsAnswers(IEnumerable<DnsResourceRecord> answers, NameServer nameServer)
private void ProcessDnsAnswers(IEnumerable<DnsResourceRecord> answers, NameServer nameServer, string nameServerHostname = null)
{
if(answers is not DnsResourceRecord[] dnsResourceRecords)
return;
Expand All @@ -180,49 +187,49 @@ private void ProcessDnsAnswers(IEnumerable<DnsResourceRecord> answers, NameServe
foreach (var record in dnsResourceRecords.ARecords())
OnRecordReceived(new DNSLookupRecordReceivedArgs(
new DNSLookupRecordInfo(
record.DomainName, record.TimeToLive, $"{record.RecordClass}",$"{record.RecordType}" , $"{record.Address}", $"{nameServer.Address}", $"{nameServer.Address}:{nameServer.Port}")));
record.DomainName, record.TimeToLive, $"{record.RecordClass}",$"{record.RecordType}" , $"{record.Address}", $"{nameServer.Address}", nameServerHostname, nameServer.Port)));

// AAAA
foreach (var record in dnsResourceRecords.AaaaRecords())
OnRecordReceived(new DNSLookupRecordReceivedArgs(
new DNSLookupRecordInfo(
record.DomainName, record.TimeToLive, $"{record.RecordClass}",$"{record.RecordType}", $"{record.Address}", $"{nameServer.Address}", $"{nameServer.Address}:{nameServer.Port}")));
record.DomainName, record.TimeToLive, $"{record.RecordClass}",$"{record.RecordType}", $"{record.Address}", $"{nameServer.Address}", nameServerHostname, nameServer.Port)));

// CNAME
foreach (var record in dnsResourceRecords.CnameRecords())
OnRecordReceived(new DNSLookupRecordReceivedArgs(
new DNSLookupRecordInfo(
record.DomainName, record.TimeToLive, $"{record.RecordClass}",$"{record.RecordType}", record.CanonicalName, $"{nameServer.Address}", $"{nameServer.Address}:{nameServer.Port}")));
record.DomainName, record.TimeToLive, $"{record.RecordClass}",$"{record.RecordType}", record.CanonicalName, $"{nameServer.Address}", nameServerHostname, nameServer.Port)));

// MX
foreach (var record in dnsResourceRecords.MxRecords())
OnRecordReceived(new DNSLookupRecordReceivedArgs(
new DNSLookupRecordInfo(
record.DomainName, record.TimeToLive, $"{record.RecordClass}",$"{record.RecordType}", record.Exchange, $"{nameServer.Address}", $"{nameServer.Address}:{nameServer.Port}")));
record.DomainName, record.TimeToLive, $"{record.RecordClass}",$"{record.RecordType}", record.Exchange, $"{nameServer.Address}", nameServerHostname, nameServer.Port)));

// NS
foreach (var record in dnsResourceRecords.NsRecords())
OnRecordReceived(new DNSLookupRecordReceivedArgs(
new DNSLookupRecordInfo(
record.DomainName, record.TimeToLive, $"{record.RecordClass}",$"{record.RecordType}", record.NSDName, $"{nameServer.Address}", $"{nameServer.Address}:{nameServer.Port}")));
record.DomainName, record.TimeToLive, $"{record.RecordClass}",$"{record.RecordType}", record.NSDName, $"{nameServer.Address}", nameServerHostname, nameServer.Port)));

// PTR
foreach (var record in dnsResourceRecords.PtrRecords())
OnRecordReceived(new DNSLookupRecordReceivedArgs(
new DNSLookupRecordInfo(
record.DomainName, record.TimeToLive, $"{record.RecordClass}",$"{record.RecordType}", record.PtrDomainName, $"{nameServer.Address}", $"{nameServer.Address}:{nameServer.Port}")));
record.DomainName, record.TimeToLive, $"{record.RecordClass}",$"{record.RecordType}", record.PtrDomainName, $"{nameServer.Address}", nameServerHostname, nameServer.Port)));

// SOA
foreach (var record in dnsResourceRecords.SoaRecords())
OnRecordReceived(new DNSLookupRecordReceivedArgs(
new DNSLookupRecordInfo(
record.DomainName, record.TimeToLive, $"{record.RecordClass}",$"{record.RecordType}", record.MName + ", " + record.RName, $"{nameServer.Address}", $"{nameServer.Address}:{nameServer.Port}")));
record.DomainName, record.TimeToLive, $"{record.RecordClass}",$"{record.RecordType}", record.MName + ", " + record.RName, $"{nameServer.Address}", nameServerHostname, nameServer.Port)));

// TXT
foreach (var record in dnsResourceRecords.TxtRecords())
OnRecordReceived(new DNSLookupRecordReceivedArgs(
new DNSLookupRecordInfo(
record.DomainName, record.TimeToLive, $"{record.RecordClass}",$"{record.RecordType}", string.Join(", ", record.Text), $"{nameServer.Address}", $"{nameServer.Address}:{nameServer.Port}")));
record.DomainName, record.TimeToLive, $"{record.RecordClass}",$"{record.RecordType}", string.Join(", ", record.Text), $"{nameServer.Address}", nameServerHostname, nameServer.Port)));

// ToDo: implement more
}
Expand Down
39 changes: 27 additions & 12 deletions Source/NETworkManager.Models/Network/DNSLookupRecordInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ public class DNSLookupRecordInfo
/// Domain name of the record.
/// </summary>
public string DomainName { get; set; }

/// <summary>
/// Time to live (TTL) of the record.
/// </summary>
public int TTL { get; set; }

/// <summary>
/// Class of the record.
/// </summary>
Expand All @@ -31,14 +31,26 @@ public class DNSLookupRecordInfo
public string Result { get; set; }

/// <summary>
/// Name server that provided the result.
/// IP address of the name server that provided the result.
/// </summary>
public string NameServerIPAddress { get; set; }

/// <summary>
/// Port of the name server that provided the result.
/// </summary>
public int NameServerPort { get; set; }

/// <summary>
/// Hostname of the name server that provided the result.
/// </summary>
public string Server { get; set; }
public string NameServerHostName { get; set; }

/// <summary>
/// IP endpoint (IP address:port) of the name server that provided the result.
/// Hostname (if available) or/and IP address with port of the name server that provided the result.
/// </summary>
public string IPEndPoint { get; set; }
public string NameServerAsString => string.IsNullOrWhiteSpace(NameServerHostName)
? $"{NameServerIPAddress}:{NameServerPort}"
: $"{NameServerHostName} ({NameServerIPAddress}:{NameServerPort})";

/// <summary>
/// Creates a new instance of <see cref="DNSLookupRecordInfo"/> with the specified parameters.
Expand All @@ -48,16 +60,19 @@ public class DNSLookupRecordInfo
/// <param name="recordClass">Class of the record.</param>
/// <param name="recordType">Type of the record.</param>
/// <param name="result">Result of the record. (IP address, hostname, text, etc.)</param>
/// <param name="server">Name server that provided the result.</param>
/// <param name="ipEndPoint">IP endpoint (IP address:port) of the name server that provided the result.</param>
public DNSLookupRecordInfo(string domainName, int ttl, string recordClass, string recordType, string result, string server, string ipEndPoint)
/// <param name="nameServerIPAddress">IP address of the name server that provided the result.</param>
/// <param name="nameServerHostName">Hostname of the name server that provided the result.</param>
/// <param name="nameServerPort">Port of the name server that provided the result.</param>
public DNSLookupRecordInfo(string domainName, int ttl, string recordClass, string recordType, string result,
string nameServerIPAddress, string nameServerHostName, int nameServerPort)
{
DomainName = domainName;
TTL = ttl;
RecordClass = recordClass;
RecordType = recordType;
Result = result;
Server = server;
IPEndPoint = ipEndPoint;
NameServerIPAddress = nameServerIPAddress;
NameServerPort = nameServerPort;
NameServerHostName = nameServerHostName;
}
}
}
5 changes: 3 additions & 2 deletions Source/NETworkManager.Models/Network/PortScanner.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using NETworkManager.Models.Lookup;
using NETworkManager.Utilities;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
Expand Down Expand Up @@ -54,7 +55,7 @@ public PortScanner(PortScannerOptions options)
#endregion

#region Methods
public void ScanAsync(IPAddress[] ipAddresses, int[] ports, CancellationToken cancellationToken)
public void ScanAsync(IPAddress[] ipAddresses, IEnumerable<int> ports, CancellationToken cancellationToken)
{
_progressValue = 0;

Expand All @@ -81,7 +82,7 @@ public void ScanAsync(IPAddress[] ipAddresses, int[] ports, CancellationToken ca

if (_options.ResolveHostname)
{
// Don't use await in Paralle.ForEach, this will break
// Don't use await in Parallel.ForEach, this will break
var dnsResolverTask = DNSClient.GetInstance().ResolvePtrAsync(ipAddress);

// Wait for task inside a Parallel.Foreach
Expand Down
5 changes: 5 additions & 0 deletions Source/NETworkManager.Models/Network/PortScannerPortInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ public class PortScannerPortInfo : PortInfo
/// </summary>
public int IPAddressInt32 => IPAddress is { AddressFamily: System.Net.Sockets.AddressFamily.InterNetwork } ? IPv4Address.ToInt32(IPAddress) : 0;

/// <summary>
/// Hostname (if available) or IP address of the host.
/// </summary>
public string HostAsString => string.IsNullOrWhiteSpace(Hostname) ? IPAddress.ToString() : Hostname;

/// <summary>
/// Creates a new instance of <see cref="PortScannerPortInfo"/> with the specified parameters.
/// </summary>
Expand Down
12 changes: 6 additions & 6 deletions Source/NETworkManager.Models/Network/Traceroute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace NETworkManager.Models.Network;

public class Traceroute
public sealed class Traceroute
{
#region Variables

Expand All @@ -23,35 +23,35 @@ public class Traceroute

public event EventHandler<TracerouteHopReceivedArgs> HopReceived;

protected virtual void OnHopReceived(TracerouteHopReceivedArgs e)
private void OnHopReceived(TracerouteHopReceivedArgs e)
{
HopReceived?.Invoke(this, e);
}

public event EventHandler TraceComplete;

protected virtual void OnTraceComplete()
private void OnTraceComplete()
{
TraceComplete?.Invoke(this, EventArgs.Empty);
}

public event EventHandler<MaximumHopsReachedArgs> MaximumHopsReached;

protected virtual void OnMaximumHopsReached(MaximumHopsReachedArgs e)
private void OnMaximumHopsReached(MaximumHopsReachedArgs e)
{
MaximumHopsReached?.Invoke(this, e);
}

public event EventHandler<TracerouteErrorArgs> TraceError;

protected virtual void OnTraceError(TracerouteErrorArgs e)
private void OnTraceError(TracerouteErrorArgs e)
{
TraceError?.Invoke(this, e);
}

public event EventHandler UserHasCanceled;

protected virtual void OnUserHasCanceled()
private void OnUserHasCanceled()
{
UserHasCanceled?.Invoke(this, EventArgs.Empty);
}
Expand Down
Loading