aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs
diff options
context:
space:
mode:
authorLukePulverenti <luke.pulverenti@gmail.com>2013-02-26 16:05:52 -0500
committerLukePulverenti <luke.pulverenti@gmail.com>2013-02-26 16:05:52 -0500
commit51b3c32e2cc84778212531d72665d2c5f567f34a (patch)
tree68fe93852dd6b3dffac09b3d7917dd6370b2784b /MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs
parentfbac08feada72c198cd5151e25008bca2b435cda (diff)
a little more consolidation
Diffstat (limited to 'MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs')
-rw-r--r--MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs377
1 files changed, 377 insertions, 0 deletions
diff --git a/MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs b/MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs
new file mode 100644
index 000000000..51b37944c
--- /dev/null
+++ b/MediaBrowser.Common.Implementations/NetworkManagement/NetworkManager.cs
@@ -0,0 +1,377 @@
+using System.Management;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Model.Net;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Runtime.InteropServices;
+
+namespace MediaBrowser.Common.Implementations.NetworkManagement
+{
+ /// <summary>
+ /// Class NetUtils
+ /// </summary>
+ public class NetworkManager : INetworkManager
+ {
+ /// <summary>
+ /// Gets the machine's local ip address
+ /// </summary>
+ /// <returns>IPAddress.</returns>
+ public string GetLocalIpAddress()
+ {
+ var host = Dns.GetHostEntry(Dns.GetHostName());
+
+ var ip = host.AddressList.FirstOrDefault(i => i.AddressFamily == AddressFamily.InterNetwork);
+
+ if (ip == null)
+ {
+ return null;
+ }
+
+ return ip.ToString();
+ }
+
+ /// <summary>
+ /// Gets a random port number that is currently available
+ /// </summary>
+ /// <returns>System.Int32.</returns>
+ public int GetRandomUnusedPort()
+ {
+ var listener = new TcpListener(IPAddress.Any, 0);
+ listener.Start();
+ var port = ((IPEndPoint)listener.LocalEndpoint).Port;
+ listener.Stop();
+ return port;
+ }
+
+ /// <summary>
+ /// Creates the netsh URL registration.
+ /// </summary>
+ public void AuthorizeHttpListening(string url)
+ {
+ var startInfo = new ProcessStartInfo
+ {
+ FileName = "netsh",
+ Arguments = string.Format("http add urlacl url={0} user=\"NT AUTHORITY\\Authenticated Users\"", url),
+ CreateNoWindow = true,
+ WindowStyle = ProcessWindowStyle.Hidden,
+ Verb = "runas",
+ ErrorDialog = false
+ };
+
+ using (var process = Process.Start(startInfo))
+ {
+ process.WaitForExit();
+ }
+ }
+
+ /// <summary>
+ /// Adds the windows firewall rule.
+ /// </summary>
+ /// <param name="port">The port.</param>
+ /// <param name="protocol">The protocol.</param>
+ public void AddSystemFirewallRule(int port, NetworkProtocol protocol)
+ {
+ // First try to remove it so we don't end up creating duplicates
+ RemoveSystemFirewallRule(port, protocol);
+
+ var args = string.Format("advfirewall firewall add rule name=\"Port {0}\" dir=in action=allow protocol={1} localport={0}", port, protocol);
+
+ RunNetsh(args);
+ }
+
+ /// <summary>
+ /// Removes the windows firewall rule.
+ /// </summary>
+ /// <param name="port">The port.</param>
+ /// <param name="protocol">The protocol.</param>
+ public void RemoveSystemFirewallRule(int port, NetworkProtocol protocol)
+ {
+ var args = string.Format("advfirewall firewall delete rule name=\"Port {0}\" protocol={1} localport={0}", port, protocol);
+
+ RunNetsh(args);
+ }
+
+ /// <summary>
+ /// Runs the netsh.
+ /// </summary>
+ /// <param name="args">The args.</param>
+ private void RunNetsh(string args)
+ {
+ var startInfo = new ProcessStartInfo
+ {
+ FileName = "netsh",
+ Arguments = args,
+ CreateNoWindow = true,
+ WindowStyle = ProcessWindowStyle.Hidden,
+ Verb = "runas",
+ ErrorDialog = false
+ };
+
+ using (var process = new Process { StartInfo = startInfo })
+ {
+ process.Start();
+ process.WaitForExit();
+ }
+ }
+
+ /// <summary>
+ /// Returns MAC Address from first Network Card in Computer
+ /// </summary>
+ /// <returns>[string] MAC Address</returns>
+ public string GetMacAddress()
+ {
+ var mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
+ var moc = mc.GetInstances();
+ var macAddress = String.Empty;
+ foreach (ManagementObject mo in moc)
+ {
+ if (macAddress == String.Empty) // only return MAC Address from first card
+ {
+ try
+ {
+ if ((bool)mo["IPEnabled"]) macAddress = mo["MacAddress"].ToString();
+ }
+ catch
+ {
+ mo.Dispose();
+ return "";
+ }
+ }
+ mo.Dispose();
+ }
+
+ return macAddress.Replace(":", "");
+ }
+
+ /// <summary>
+ /// Uses the DllImport : NetServerEnum with all its required parameters
+ /// (see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netserverenum.asp
+ /// for full details or method signature) to retrieve a list of domain SV_TYPE_WORKSTATION
+ /// and SV_TYPE_SERVER PC's
+ /// </summary>
+ /// <returns>Arraylist that represents all the SV_TYPE_WORKSTATION and SV_TYPE_SERVER
+ /// PC's in the Domain</returns>
+ public IEnumerable<string> GetNetworkDevices()
+ {
+ //local fields
+ const int MAX_PREFERRED_LENGTH = -1;
+ var SV_TYPE_WORKSTATION = 1;
+ var SV_TYPE_SERVER = 2;
+ var buffer = IntPtr.Zero;
+ var tmpBuffer = IntPtr.Zero;
+ var entriesRead = 0;
+ var totalEntries = 0;
+ var resHandle = 0;
+ var sizeofINFO = Marshal.SizeOf(typeof(_SERVER_INFO_100));
+
+ try
+ {
+ //call the DllImport : NetServerEnum with all its required parameters
+ //see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netserverenum.asp
+ //for full details of method signature
+ var ret = NativeMethods.NetServerEnum(null, 100, ref buffer, MAX_PREFERRED_LENGTH, out entriesRead, out totalEntries, SV_TYPE_WORKSTATION | SV_TYPE_SERVER, null, out resHandle);
+
+ //if the returned with a NERR_Success (C++ term), =0 for C#
+ if (ret == 0)
+ {
+ //loop through all SV_TYPE_WORKSTATION and SV_TYPE_SERVER PC's
+ for (var i = 0; i < totalEntries; i++)
+ {
+ //get pointer to, Pointer to the buffer that received the data from
+ //the call to NetServerEnum. Must ensure to use correct size of
+ //STRUCTURE to ensure correct location in memory is pointed to
+ tmpBuffer = new IntPtr((int)buffer + (i * sizeofINFO));
+ //Have now got a pointer to the list of SV_TYPE_WORKSTATION and
+ //SV_TYPE_SERVER PC's, which is unmanaged memory
+ //Needs to Marshal data from an unmanaged block of memory to a
+ //managed object, again using STRUCTURE to ensure the correct data
+ //is marshalled
+ var svrInfo = (_SERVER_INFO_100)Marshal.PtrToStructure(tmpBuffer, typeof(_SERVER_INFO_100));
+
+ //add the PC names to the ArrayList
+ if (!string.IsNullOrEmpty(svrInfo.sv100_name))
+ {
+ yield return svrInfo.sv100_name;
+ }
+ }
+ }
+ }
+ finally
+ {
+ //The NetApiBufferFree function frees
+ //the memory that the NetApiBufferAllocate function allocates
+ NativeMethods.NetApiBufferFree(buffer);
+ }
+ }
+
+
+ /// <summary>
+ /// Gets the network shares.
+ /// </summary>
+ /// <param name="path">The path.</param>
+ /// <returns>IEnumerable{NetworkShare}.</returns>
+ public IEnumerable<NetworkShare> GetNetworkShares(string path)
+ {
+ return new ShareCollection(path).OfType<Share>().Select(ToNetworkShare);
+ }
+
+ /// <summary>
+ /// To the network share.
+ /// </summary>
+ /// <param name="share">The share.</param>
+ /// <returns>NetworkShare.</returns>
+ private NetworkShare ToNetworkShare(Share share)
+ {
+ return new NetworkShare
+ {
+ Name = share.NetName,
+ Path = share.Path,
+ Remark = share.Remark,
+ Server = share.Server,
+ ShareType = ToNetworkShareType(share.ShareType)
+ };
+ }
+
+ /// <summary>
+ /// To the type of the network share.
+ /// </summary>
+ /// <param name="shareType">Type of the share.</param>
+ /// <returns>NetworkShareType.</returns>
+ /// <exception cref="System.ArgumentException">Unknown share type</exception>
+ private NetworkShareType ToNetworkShareType(ShareType shareType)
+ {
+ switch (shareType)
+ {
+ case ShareType.Device:
+ return NetworkShareType.Device;
+ case ShareType.Disk :
+ return NetworkShareType.Disk;
+ case ShareType.IPC :
+ return NetworkShareType.Ipc;
+ case ShareType.Printer :
+ return NetworkShareType.Printer;
+ case ShareType.Special:
+ return NetworkShareType.Special;
+ default:
+ throw new ArgumentException("Unknown share type");
+ }
+ }
+
+ /// <summary>
+ /// Parses the specified endpointstring.
+ /// </summary>
+ /// <param name="endpointstring">The endpointstring.</param>
+ /// <returns>IPEndPoint.</returns>
+ public IPEndPoint Parse(string endpointstring)
+ {
+ return Parse(endpointstring, -1);
+ }
+
+ /// <summary>
+ /// Parses the specified endpointstring.
+ /// </summary>
+ /// <param name="endpointstring">The endpointstring.</param>
+ /// <param name="defaultport">The defaultport.</param>
+ /// <returns>IPEndPoint.</returns>
+ /// <exception cref="System.ArgumentException">Endpoint descriptor may not be empty.</exception>
+ /// <exception cref="System.FormatException"></exception>
+ private static IPEndPoint Parse(string endpointstring, int defaultport)
+ {
+ if (string.IsNullOrEmpty(endpointstring)
+ || endpointstring.Trim().Length == 0)
+ {
+ throw new ArgumentException("Endpoint descriptor may not be empty.");
+ }
+
+ if (defaultport != -1 &&
+ (defaultport < IPEndPoint.MinPort
+ || defaultport > IPEndPoint.MaxPort))
+ {
+ throw new ArgumentException(string.Format("Invalid default port '{0}'", defaultport));
+ }
+
+ string[] values = endpointstring.Split(new char[] { ':' });
+ IPAddress ipaddy;
+ int port = -1;
+
+ //check if we have an IPv6 or ports
+ if (values.Length <= 2) // ipv4 or hostname
+ {
+ if (values.Length == 1)
+ //no port is specified, default
+ port = defaultport;
+ else
+ port = GetPort(values[1]);
+
+ //try to use the address as IPv4, otherwise get hostname
+ if (!IPAddress.TryParse(values[0], out ipaddy))
+ ipaddy = GetIPfromHost(values[0]);
+ }
+ else if (values.Length > 2) //ipv6
+ {
+ //could [a:b:c]:d
+ if (values[0].StartsWith("[") && values[values.Length - 2].EndsWith("]"))
+ {
+ string ipaddressstring = string.Join(":", values.Take(values.Length - 1).ToArray());
+ ipaddy = IPAddress.Parse(ipaddressstring);
+ port = GetPort(values[values.Length - 1]);
+ }
+ else //[a:b:c] or a:b:c
+ {
+ ipaddy = IPAddress.Parse(endpointstring);
+ port = defaultport;
+ }
+ }
+ else
+ {
+ throw new FormatException(string.Format("Invalid endpoint ipaddress '{0}'", endpointstring));
+ }
+
+ if (port == -1)
+ throw new ArgumentException(string.Format("No port specified: '{0}'", endpointstring));
+
+ return new IPEndPoint(ipaddy, port);
+ }
+
+ /// <summary>
+ /// Gets the port.
+ /// </summary>
+ /// <param name="p">The p.</param>
+ /// <returns>System.Int32.</returns>
+ /// <exception cref="System.FormatException"></exception>
+ private static int GetPort(string p)
+ {
+ int port;
+
+ if (!int.TryParse(p, out port)
+ || port < IPEndPoint.MinPort
+ || port > IPEndPoint.MaxPort)
+ {
+ throw new FormatException(string.Format("Invalid end point port '{0}'", p));
+ }
+
+ return port;
+ }
+
+ /// <summary>
+ /// Gets the I pfrom host.
+ /// </summary>
+ /// <param name="p">The p.</param>
+ /// <returns>IPAddress.</returns>
+ /// <exception cref="System.ArgumentException"></exception>
+ private static IPAddress GetIPfromHost(string p)
+ {
+ var hosts = Dns.GetHostAddresses(p);
+
+ if (hosts == null || hosts.Length == 0)
+ throw new ArgumentException(string.Format("Host not found: {0}", p));
+
+ return hosts[0];
+ }
+ }
+
+}