Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Source/NETworkManager.Models/Network/IPScanner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

namespace NETworkManager.Models.Network;

/// <summary>
/// Class to scan for IP addresses in a network.
/// </summary>
/// <param name="options">The scan options.</param>
public sealed class IPScanner(IPScannerOptions options)
{
#region Variables
Expand All @@ -22,27 +26,39 @@ public sealed class IPScanner(IPScannerOptions options)

#region Events

/// <summary>
/// Occurs when a host has been scanned.
/// </summary>
public event EventHandler<IPScannerHostScannedArgs> HostScanned;

private void OnHostScanned(IPScannerHostScannedArgs e)
{
HostScanned?.Invoke(this, e);
}

/// <summary>
/// Occurs when the scan is complete.
/// </summary>
public event EventHandler ScanComplete;

private void OnScanComplete()
{
ScanComplete?.Invoke(this, EventArgs.Empty);
}

/// <summary>
/// Occurs when the scan progress has changed.
/// </summary>
public event EventHandler<ProgressChangedArgs> ProgressChanged;

private void OnProgressChanged()
{
ProgressChanged?.Invoke(this, new ProgressChangedArgs(_progressValue));
}

/// <summary>
/// Occurs when the user has canceled the scan.
/// </summary>
public event EventHandler UserHasCanceled;

private void OnUserHasCanceled()
Expand All @@ -54,6 +70,11 @@ private void OnUserHasCanceled()

#region Methods

/// <summary>
/// Starts the IP scan asynchronously.
/// </summary>
/// <param name="hosts">The list of hosts to scan.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
public void ScanAsync(IEnumerable<(IPAddress ipAddress, string hostname)> hosts,
CancellationToken cancellationToken)
{
Expand Down
43 changes: 43 additions & 0 deletions Source/NETworkManager.Models/Network/NetworkInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@

namespace NETworkManager.Models.Network;

/// <summary>
/// Provides functionality to manage network interfaces.
/// </summary>
public sealed class NetworkInterface
{
#region Events

/// <summary>
/// Occurs when the user has canceled an operation (e.g. UAC prompt).
/// </summary>
public event EventHandler UserHasCanceled;

private void OnUserHasCanceled()
Expand All @@ -26,11 +32,19 @@ private void OnUserHasCanceled()

#region Methods

/// <summary>
/// Gets a list of all available network interfaces asynchronously.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains a list of <see cref="NetworkInterfaceInfo"/>.</returns>
public static Task<List<NetworkInterfaceInfo>> GetNetworkInterfacesAsync()
{
return Task.Run(GetNetworkInterfaces);
}

/// <summary>
/// Gets a list of all available network interfaces.
/// </summary>
/// <returns>A list of <see cref="NetworkInterfaceInfo"/> describing the available network interfaces.</returns>
public static List<NetworkInterfaceInfo> GetNetworkInterfaces()
{
List<NetworkInterfaceInfo> listNetworkInterfaceInfo = new();
Expand Down Expand Up @@ -156,11 +170,21 @@ public static List<NetworkInterfaceInfo> GetNetworkInterfaces()
return listNetworkInterfaceInfo;
}

/// <summary>
/// Detects the local IP address based on routing to a remote IP address asynchronously.
/// </summary>
/// <param name="remoteIPAddress">The remote IP address to check routing against.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains the local <see cref="IPAddress"/> used to reach the remote address.</returns>
public static Task<IPAddress> DetectLocalIPAddressBasedOnRoutingAsync(IPAddress remoteIPAddress)
{
return Task.Run(() => DetectLocalIPAddressBasedOnRouting(remoteIPAddress));
}

/// <summary>
/// Detects the local IP address based on routing to a remote IP address.
/// </summary>
/// <param name="remoteIPAddress">The remote IP address to check routing against.</param>
/// <returns>The local <see cref="IPAddress"/> used to reach the remote address.</returns>
private static IPAddress DetectLocalIPAddressBasedOnRouting(IPAddress remoteIPAddress)
{
var isIPv4 = remoteIPAddress.AddressFamily == AddressFamily.InterNetwork;
Expand All @@ -184,11 +208,21 @@ private static IPAddress DetectLocalIPAddressBasedOnRouting(IPAddress remoteIPAd
return null;
}

/// <summary>
/// Detects the gateway IP address based on a local IP address asynchronously.
/// </summary>
/// <param name="localIPAddress">The local IP address to find the gateway for.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains the gateway <see cref="IPAddress"/>.</returns>
public static Task<IPAddress> DetectGatewayBasedOnLocalIPAddressAsync(IPAddress localIPAddress)
{
return Task.Run(() => DetectGatewayBasedOnLocalIPAddress(localIPAddress));
}

/// <summary>
/// Detects the gateway IP address based on a local IP address.
/// </summary>
/// <param name="localIPAddress">The local IP address to find the gateway for.</param>
/// <returns>The gateway <see cref="IPAddress"/>.</returns>
private static IPAddress DetectGatewayBasedOnLocalIPAddress(IPAddress localIPAddress)
{
foreach (var networkInterface in GetNetworkInterfaces())
Expand All @@ -210,11 +244,20 @@ private static IPAddress DetectGatewayBasedOnLocalIPAddress(IPAddress localIPAdd
return null;
}

/// <summary>
/// Configures a network interface with the specified configuration asynchronously.
/// </summary>
/// <param name="config">The configuration to apply.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
public Task ConfigureNetworkInterfaceAsync(NetworkInterfaceConfig config)
{
return Task.Run(() => ConfigureNetworkInterface(config));
}

/// <summary>
/// Configures a network interface with the specified configuration.
/// </summary>
/// <param name="config">The configuration to apply.</param>
private void ConfigureNetworkInterface(NetworkInterfaceConfig config)
{
// IP
Expand Down
49 changes: 49 additions & 0 deletions Source/NETworkManager.Models/Network/Ping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,36 @@

namespace NETworkManager.Models.Network;

/// <summary>
/// Provides functionality to ping a network host.
/// </summary>
public sealed class Ping
{
#region Variables

/// <summary>
/// The time in milliseconds to wait between ping requests. Default is 1000ms.
/// </summary>
public int WaitTime = 1000;

/// <summary>
/// The time in milliseconds to wait for a reply. Default is 4000ms.
/// </summary>
public int Timeout = 4000;

/// <summary>
/// The buffer to send with the ping request. Default is 32 bytes.
/// </summary>
public byte[] Buffer = new byte[32];

/// <summary>
/// The Time to Live (TTL) value for the ping request. Default is 64.
/// </summary>
public int TTL = 64;

/// <summary>
/// Indicates whether to prevent fragmentation of the data packets. Default is true.
/// </summary>
public bool DontFragment = true;

private const int ExceptionCancelCount = 3;
Expand All @@ -24,34 +46,49 @@ public sealed class Ping

#region Events

/// <summary>
/// Occurs when a ping reply is received.
/// </summary>
public event EventHandler<PingReceivedArgs> PingReceived;

private void OnPingReceived(PingReceivedArgs e)
{
PingReceived?.Invoke(this, e);
}

/// <summary>
/// Occurs when the ping operation is completed.
/// </summary>
public event EventHandler PingCompleted;

private void OnPingCompleted()
{
PingCompleted?.Invoke(this, EventArgs.Empty);
}

/// <summary>
/// Occurs when a ping exception is thrown.
/// </summary>
public event EventHandler<PingExceptionArgs> PingException;

private void OnPingException(PingExceptionArgs e)
{
PingException?.Invoke(this, e);
}

/// <summary>
/// Occurs when the hostname is resolved.
/// </summary>
public event EventHandler<HostnameArgs> HostnameResolved;

private void OnHostnameResolved(HostnameArgs e)
{
HostnameResolved?.Invoke(this, e);
}

/// <summary>
/// Occurs when the user has canceled the operation.
/// </summary>
public event EventHandler UserHasCanceled;

private void OnUserHasCanceled()
Expand All @@ -63,6 +100,11 @@ private void OnUserHasCanceled()

#region Methods

/// <summary>
/// Sends ping requests to the specified IP address asynchronously.
/// </summary>
/// <param name="ipAddress">The IP address to ping.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
public void SendAsync(IPAddress ipAddress, CancellationToken cancellationToken)
{
Task.Run(async () =>
Expand Down Expand Up @@ -153,6 +195,13 @@ public void SendAsync(IPAddress ipAddress, CancellationToken cancellationToken)
}

// Param: disableSpecialChar --> ExportManager --> "<" this char cannot be displayed in xml
/// <summary>
/// Converts the ping time to a string representation.
/// </summary>
/// <param name="status">The IP status of the ping reply.</param>
/// <param name="time">The round-trip time in milliseconds.</param>
/// <param name="disableSpecialChar">If true, disables special characters like '&lt;' in the output (e.g., for XML export).</param>
/// <returns>The formatted time string.</returns>
public static string TimeToString(IPStatus status, long time, bool disableSpecialChar = false)
{
if (status != IPStatus.Success && status != IPStatus.TtlExpired)
Expand Down
26 changes: 26 additions & 0 deletions Source/NETworkManager/ViewModels/ARPTableAddEntryViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,46 @@

namespace NETworkManager.ViewModels;

/// <summary>
/// View model for adding an ARP table entry.
/// </summary>
public class ArpTableAddEntryViewModel : ViewModelBase
{
/// <summary>
/// Backing field for <see cref="IPAddress"/>.
/// </summary>
private string _ipAddress;

/// <summary>
/// Backing field for <see cref="MACAddress"/>.
/// </summary>
private string _macAddress;

/// <summary>
/// Initializes a new instance of the <see cref="ArpTableAddEntryViewModel"/> class.
/// </summary>
/// <param name="addCommand">The action to execute when the add command is invoked.</param>
/// <param name="cancelHandler">The action to execute when the cancel command is invoked.</param>
public ArpTableAddEntryViewModel(Action<ArpTableAddEntryViewModel> addCommand,
Action<ArpTableAddEntryViewModel> cancelHandler)
{
AddCommand = new RelayCommand(_ => addCommand(this));
CancelCommand = new RelayCommand(_ => cancelHandler(this));
}

/// <summary>
/// Gets the command to add the entry.
/// </summary>
public ICommand AddCommand { get; }

/// <summary>
/// Gets the command to cancel the operation.
/// </summary>
public ICommand CancelCommand { get; }

/// <summary>
/// Gets or sets the IP address.
/// </summary>
public string IPAddress
{
get => _ipAddress;
Expand All @@ -34,6 +57,9 @@ public string IPAddress
}
}

/// <summary>
/// Gets or sets the MAC address.
/// </summary>
public string MACAddress
{
get => _macAddress;
Expand Down
Loading