-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'development' into hotfix/pdu-bridge-issues
- Loading branch information
Showing
5 changed files
with
315 additions
and
2 deletions.
There are no files selected for viewing
218 changes: 218 additions & 0 deletions
218
...ls-framework/Essentials Core/PepperDashEssentialsBase/Device Info/NetworkDeviceHelpers.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using PepperDash.Core; | ||
using Crestron.SimplSharp; | ||
using PepperDash.Essentials.Core; | ||
|
||
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.Console(2, "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.Console(0, "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.Console(0, "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.Console(0, "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.Console(0, "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; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters