mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-28 03:45:01 +00:00
219 lines
7.9 KiB
C#
219 lines
7.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using PepperDash.Core;
|
|
using Crestron.SimplSharp;
|
|
using PepperDash.Essentials.Core;
|
|
using Serilog.Events;
|
|
|
|
namespace PepperDash.Essentials.Core.DeviceInfo
|
|
{
|
|
public static class NetworkDeviceHelpers
|
|
{
|
|
/// <summary>
|
|
/// Event raised when ArpTable changes
|
|
/// </summary>
|
|
public static event ArpTableEventHandler ArpTableUpdated;
|
|
|
|
/// <summary>
|
|
/// Delegate called by ArpTableUpdated
|
|
/// </summary>
|
|
/// <param name="args">contains the entire ARP table and a bool to note if there was an error in retrieving the data</param>
|
|
public delegate void ArpTableEventHandler(ArpTableEventArgs args);
|
|
|
|
private static readonly char NewLineSplitter = CrestronEnvironment.NewLine.ToCharArray().First();
|
|
private static readonly string NewLine = CrestronEnvironment.NewLine;
|
|
|
|
private static readonly CCriticalSection Lock = new CCriticalSection();
|
|
|
|
/// <summary>
|
|
/// Last resolved ARP table - it is recommended to refresh the arp before using this.
|
|
/// </summary>
|
|
public static List<ArpEntry> ArpTable { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Force recheck of ARP table
|
|
/// </summary>
|
|
public static void RefreshArp()
|
|
{
|
|
var error = false;
|
|
try
|
|
{
|
|
Lock.Enter();
|
|
var consoleResponse = string.Empty;
|
|
if (!CrestronConsole.SendControlSystemCommand("showarptable", ref consoleResponse)) return;
|
|
if (string.IsNullOrEmpty(consoleResponse))
|
|
{
|
|
error = true;
|
|
return;
|
|
}
|
|
ArpTable.Clear();
|
|
|
|
Debug.LogMessage(LogEventLevel.Verbose, "ConsoleResponse of 'showarptable' : {0}{1}", NewLine, consoleResponse);
|
|
|
|
var myLines =
|
|
consoleResponse.Split(NewLineSplitter)
|
|
.ToList()
|
|
.Where(o => (o.Contains(':') && !o.Contains("Type", StringComparison.OrdinalIgnoreCase)))
|
|
.ToList();
|
|
foreach (var line in myLines)
|
|
{
|
|
var item = line;
|
|
var seperator = item.Contains('\t') ? '\t' : ' ';
|
|
var dataPoints = item.Split(seperator);
|
|
if (dataPoints == null || dataPoints.Length < 2) continue;
|
|
var ipAddress = SanitizeIpAddress(dataPoints.First().TrimAll());
|
|
var macAddress = dataPoints.Last();
|
|
ArpTable.Add(new ArpEntry(ipAddress, macAddress));
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Information, "Exception in \"RefreshArp\" : {0}", ex.Message);
|
|
error = true;
|
|
}
|
|
finally
|
|
{
|
|
Lock.Leave();
|
|
OnArpTableUpdated(new ArpTableEventArgs(ArpTable, error));
|
|
}
|
|
}
|
|
|
|
|
|
private static void OnArpTableUpdated(ArpTableEventArgs args)
|
|
{
|
|
if (args == null) return;
|
|
var handler = ArpTableUpdated;
|
|
if (handler == null) return;
|
|
handler.Invoke(args);
|
|
}
|
|
|
|
static NetworkDeviceHelpers()
|
|
{
|
|
ArpTable = new List<ArpEntry>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes leading zeros, leading whitespace, and trailing whitespace from an IPAddress string
|
|
/// </summary>
|
|
/// <param name="ipAddressIn">Ip Address to Santitize</param>
|
|
/// <returns>Sanitized Ip Address</returns>
|
|
public static string SanitizeIpAddress(string ipAddressIn)
|
|
{
|
|
try
|
|
{
|
|
var ipAddress = IPAddress.Parse(ipAddressIn.TrimStart('0'));
|
|
return ipAddress.ToString();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Information, "Unable to Santize Ip : {0}", ex.Message);
|
|
return ipAddressIn;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resolves a hostname by IP Address using DNS
|
|
/// </summary>
|
|
/// <param name="ipAddress">IP Address to resolve from</param>
|
|
/// <returns>Resolved Hostname - on failure to determine hostname, will return IP Address</returns>
|
|
public static string ResolveHostnameFromIp(string ipAddress)
|
|
{
|
|
try
|
|
{
|
|
var santitizedIp = SanitizeIpAddress(ipAddress);
|
|
var hostEntry = Dns.GetHostEntry(santitizedIp);
|
|
return hostEntry == null ? ipAddress : hostEntry.HostName;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Information, "Exception Resolving Hostname from IP Address : {0}", ex.Message);
|
|
return ipAddress;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resolves an IP Address by hostname using DNS
|
|
/// </summary>
|
|
/// <param name="hostName">Hostname to resolve from</param>
|
|
/// <returns>Resolved IP Address - on a failure to determine IP Address, will return hostname</returns>
|
|
public static string ResolveIpFromHostname(string hostName)
|
|
{
|
|
try
|
|
{
|
|
var hostEntry = Dns.GetHostEntry(hostName);
|
|
return hostEntry == null ? hostName : hostEntry.AddressList.First().ToString();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Information, "Exception Resolving IP Address from Hostname : {0}", ex.Message);
|
|
return hostName;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Object to hold data about an arp entry
|
|
/// </summary>
|
|
public class ArpEntry
|
|
{
|
|
public readonly IPAddress IpAddress;
|
|
public readonly string MacAddress;
|
|
|
|
/// <summary>
|
|
/// Constructs new ArpEntry object
|
|
/// </summary>
|
|
/// <param name="ipAddress">string formatted as ipv4 address</param>
|
|
/// <param name="macAddress">mac address string - format is unimportant</param>
|
|
public ArpEntry(string ipAddress, string macAddress)
|
|
{
|
|
if (string.IsNullOrEmpty(ipAddress))
|
|
{
|
|
throw new ArgumentException("\"ipAddress\" cannot be null or empty");
|
|
}
|
|
if (string.IsNullOrEmpty(macAddress))
|
|
{
|
|
throw new ArgumentException("\"macAddress\" cannot be null or empty");
|
|
}
|
|
IpAddress = IPAddress.Parse(ipAddress.TrimStart().TrimStart('0').TrimEnd());
|
|
MacAddress = macAddress;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Arguments passed by the ArpTableUpdated event
|
|
/// </summary>
|
|
public class ArpTableEventArgs : EventArgs
|
|
{
|
|
/// <summary>
|
|
/// The retrieved ARP Table
|
|
/// </summary>
|
|
public readonly List<ArpEntry> ArpTable;
|
|
/// <summary>
|
|
/// True if there was a problem retrieving the ARP Table
|
|
/// </summary>
|
|
public readonly bool Error;
|
|
|
|
/// <summary>
|
|
/// Constructor for ArpTableEventArgs
|
|
/// </summary>
|
|
/// <param name="arpTable">The entirety of the retrieved ARP table</param>
|
|
/// <param name="error">True of an error was encountered updating the ARP table</param>
|
|
public ArpTableEventArgs(List<ArpEntry> arpTable, bool error)
|
|
{
|
|
ArpTable = arpTable;
|
|
Error = error;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Constructor for ArpTableEventArgs - assumes no error encountered in retrieving ARP Table
|
|
/// </summary>
|
|
/// <param name="arpTable">The entirety of the retrieved ARP table</param>
|
|
public ArpTableEventArgs(List<ArpEntry> arpTable)
|
|
{
|
|
ArpTable = arpTable;
|
|
Error = false;
|
|
}
|
|
}
|
|
} |