BaseNetworkManager.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Linq;
  5. using System.Net;
  6. using System.Net.NetworkInformation;
  7. using System.Net.Sockets;
  8. namespace MediaBrowser.Common.Implementations.Networking
  9. {
  10. public abstract class BaseNetworkManager
  11. {
  12. /// <summary>
  13. /// Gets the machine's local ip address
  14. /// </summary>
  15. /// <returns>IPAddress.</returns>
  16. public IEnumerable<string> GetLocalIpAddresses()
  17. {
  18. var list = GetIPsDefault().Where(i => !IPAddress.IsLoopback(i)).Select(i => i.ToString()).ToList();
  19. if (list.Count > 0)
  20. {
  21. return list;
  22. }
  23. return GetLocalIpAddressesFallback();
  24. }
  25. private IEnumerable<IPAddress> GetIPsDefault()
  26. {
  27. foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces())
  28. {
  29. var props = adapter.GetIPProperties();
  30. var gateways = from ga in props.GatewayAddresses
  31. where !ga.Address.Equals(IPAddress.Any)
  32. select true;
  33. if (!gateways.Any())
  34. {
  35. continue;
  36. }
  37. foreach (var uni in props.UnicastAddresses)
  38. {
  39. var address = uni.Address;
  40. if (address.AddressFamily != AddressFamily.InterNetwork)
  41. {
  42. continue;
  43. }
  44. yield return address;
  45. }
  46. }
  47. }
  48. private IEnumerable<string> GetLocalIpAddressesFallback()
  49. {
  50. var host = Dns.GetHostEntry(Dns.GetHostName());
  51. // Reverse them because the last one is usually the correct one
  52. // It's not fool-proof so ultimately the consumer will have to examine them and decide
  53. return host.AddressList
  54. .Where(i => i.AddressFamily == AddressFamily.InterNetwork)
  55. .Select(i => i.ToString())
  56. .Reverse();
  57. }
  58. /// <summary>
  59. /// Gets a random port number that is currently available
  60. /// </summary>
  61. /// <returns>System.Int32.</returns>
  62. public int GetRandomUnusedPort()
  63. {
  64. var listener = new TcpListener(IPAddress.Any, 0);
  65. listener.Start();
  66. var port = ((IPEndPoint)listener.LocalEndpoint).Port;
  67. listener.Stop();
  68. return port;
  69. }
  70. /// <summary>
  71. /// Returns MAC Address from first Network Card in Computer
  72. /// </summary>
  73. /// <returns>[string] MAC Address</returns>
  74. public string GetMacAddress()
  75. {
  76. return NetworkInterface.GetAllNetworkInterfaces()
  77. .Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback)
  78. .Select(i => BitConverter.ToString(i.GetPhysicalAddress().GetAddressBytes()))
  79. .FirstOrDefault();
  80. }
  81. /// <summary>
  82. /// Parses the specified endpointstring.
  83. /// </summary>
  84. /// <param name="endpointstring">The endpointstring.</param>
  85. /// <returns>IPEndPoint.</returns>
  86. public IPEndPoint Parse(string endpointstring)
  87. {
  88. return Parse(endpointstring, -1);
  89. }
  90. /// <summary>
  91. /// Parses the specified endpointstring.
  92. /// </summary>
  93. /// <param name="endpointstring">The endpointstring.</param>
  94. /// <param name="defaultport">The defaultport.</param>
  95. /// <returns>IPEndPoint.</returns>
  96. /// <exception cref="System.ArgumentException">Endpoint descriptor may not be empty.</exception>
  97. /// <exception cref="System.FormatException"></exception>
  98. private static IPEndPoint Parse(string endpointstring, int defaultport)
  99. {
  100. if (String.IsNullOrEmpty(endpointstring)
  101. || endpointstring.Trim().Length == 0)
  102. {
  103. throw new ArgumentException("Endpoint descriptor may not be empty.");
  104. }
  105. if (defaultport != -1 &&
  106. (defaultport < IPEndPoint.MinPort
  107. || defaultport > IPEndPoint.MaxPort))
  108. {
  109. throw new ArgumentException(String.Format("Invalid default port '{0}'", defaultport));
  110. }
  111. string[] values = endpointstring.Split(new char[] { ':' });
  112. IPAddress ipaddy;
  113. int port = -1;
  114. //check if we have an IPv6 or ports
  115. if (values.Length <= 2) // ipv4 or hostname
  116. {
  117. port = values.Length == 1 ? defaultport : GetPort(values[1]);
  118. //try to use the address as IPv4, otherwise get hostname
  119. if (!IPAddress.TryParse(values[0], out ipaddy))
  120. ipaddy = GetIPfromHost(values[0]);
  121. }
  122. else if (values.Length > 2) //ipv6
  123. {
  124. //could [a:b:c]:d
  125. if (values[0].StartsWith("[") && values[values.Length - 2].EndsWith("]"))
  126. {
  127. string ipaddressstring = String.Join(":", values.Take(values.Length - 1).ToArray());
  128. ipaddy = IPAddress.Parse(ipaddressstring);
  129. port = GetPort(values[values.Length - 1]);
  130. }
  131. else //[a:b:c] or a:b:c
  132. {
  133. ipaddy = IPAddress.Parse(endpointstring);
  134. port = defaultport;
  135. }
  136. }
  137. else
  138. {
  139. throw new FormatException(String.Format("Invalid endpoint ipaddress '{0}'", endpointstring));
  140. }
  141. if (port == -1)
  142. throw new ArgumentException(String.Format("No port specified: '{0}'", endpointstring));
  143. return new IPEndPoint(ipaddy, port);
  144. }
  145. protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
  146. /// <summary>
  147. /// Gets the port.
  148. /// </summary>
  149. /// <param name="p">The p.</param>
  150. /// <returns>System.Int32.</returns>
  151. /// <exception cref="System.FormatException"></exception>
  152. private static int GetPort(string p)
  153. {
  154. int port;
  155. if (!Int32.TryParse(p, out port)
  156. || port < IPEndPoint.MinPort
  157. || port > IPEndPoint.MaxPort)
  158. {
  159. throw new FormatException(String.Format("Invalid end point port '{0}'", p));
  160. }
  161. return port;
  162. }
  163. /// <summary>
  164. /// Gets the I pfrom host.
  165. /// </summary>
  166. /// <param name="p">The p.</param>
  167. /// <returns>IPAddress.</returns>
  168. /// <exception cref="System.ArgumentException"></exception>
  169. private static IPAddress GetIPfromHost(string p)
  170. {
  171. var hosts = Dns.GetHostAddresses(p);
  172. if (hosts == null || hosts.Length == 0)
  173. throw new ArgumentException(String.Format("Host not found: {0}", p));
  174. return hosts[0];
  175. }
  176. }
  177. }