PageRenderTime 50ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/System/System.Net.NetworkInformation/IPInterfaceProperties.cs

https://github.com/skolima/mono
C# | 376 lines | 289 code | 44 blank | 43 comment | 39 complexity | f7438fa879c8e8743ff7a61ac7047c08 MD5 | raw file
  1. //
  2. // System.Net.NetworkInformation.IPInterfaceProperties
  3. //
  4. // Authors:
  5. // Gonzalo Paniagua Javier (gonzalo@novell.com)
  6. // Atsushi Enomoto (atsushi@ximian.com)
  7. //
  8. // Copyright (c) 2006-2007 Novell, Inc. (http://www.novell.com)
  9. //
  10. // Permission is hereby granted, free of charge, to any person obtaining
  11. // a copy of this software and associated documentation files (the
  12. // "Software"), to deal in the Software without restriction, including
  13. // without limitation the rights to use, copy, modify, merge, publish,
  14. // distribute, sublicense, and/or sell copies of the Software, and to
  15. // permit persons to whom the Software is furnished to do so, subject to
  16. // the following conditions:
  17. //
  18. // The above copyright notice and this permission notice shall be
  19. // included in all copies or substantial portions of the Software.
  20. //
  21. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  25. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  26. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  27. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  28. //
  29. using System.Collections.Generic;
  30. using System.Globalization;
  31. using System.IO;
  32. using System.Net.Sockets;
  33. using System.Text.RegularExpressions;
  34. namespace System.Net.NetworkInformation {
  35. public abstract class IPInterfaceProperties {
  36. protected IPInterfaceProperties ()
  37. {
  38. }
  39. public abstract IPv4InterfaceProperties GetIPv4Properties ();
  40. public abstract IPv6InterfaceProperties GetIPv6Properties ();
  41. public abstract IPAddressInformationCollection AnycastAddresses { get; }
  42. public abstract IPAddressCollection DhcpServerAddresses { get; }
  43. public abstract IPAddressCollection DnsAddresses { get; }
  44. public abstract string DnsSuffix { get; }
  45. public abstract GatewayIPAddressInformationCollection GatewayAddresses { get; }
  46. public abstract bool IsDnsEnabled { get; }
  47. public abstract bool IsDynamicDnsEnabled { get; }
  48. public abstract MulticastIPAddressInformationCollection MulticastAddresses { get; }
  49. public abstract UnicastIPAddressInformationCollection UnicastAddresses { get; }
  50. public abstract IPAddressCollection WinsServersAddresses { get; }
  51. }
  52. abstract class UnixIPInterfaceProperties : IPInterfaceProperties
  53. {
  54. protected IPv4InterfaceProperties ipv4iface_properties;
  55. protected UnixNetworkInterface iface;
  56. List <IPAddress> addresses;
  57. IPAddressCollection dns_servers;
  58. IPAddressCollection gateways;
  59. string dns_suffix;
  60. DateTime last_parse;
  61. public UnixIPInterfaceProperties (UnixNetworkInterface iface, List <IPAddress> addresses)
  62. {
  63. this.iface = iface;
  64. this.addresses = addresses;
  65. }
  66. public override IPv6InterfaceProperties GetIPv6Properties ()
  67. {
  68. throw new NotImplementedException ();
  69. }
  70. void ParseRouteInfo (string iface)
  71. {
  72. try {
  73. gateways = new IPAddressCollection ();
  74. using (StreamReader reader = new StreamReader ("/proc/net/route")) {
  75. string line;
  76. reader.ReadLine (); // Ignore first line
  77. while ((line = reader.ReadLine ()) != null) {
  78. line = line.Trim ();
  79. if (line.Length == 0)
  80. continue;
  81. string [] parts = line.Split ('\t');
  82. if (parts.Length < 3)
  83. continue;
  84. string gw_address = parts [2].Trim ();
  85. byte [] ipbytes = new byte [4];
  86. if (gw_address.Length == 8 && iface.Equals (parts [0], StringComparison.OrdinalIgnoreCase)) {
  87. for (int i = 0; i < 4; i++) {
  88. if (!Byte.TryParse (gw_address.Substring (i * 2, 2), NumberStyles.HexNumber, null, out ipbytes [3 - i]))
  89. continue;
  90. }
  91. IPAddress ip = new IPAddress (ipbytes);
  92. if (!ip.Equals (IPAddress.Any))
  93. gateways.Add (ip);
  94. }
  95. }
  96. }
  97. } catch {
  98. }
  99. }
  100. static Regex ns = new Regex (@"\s*nameserver\s+(?<address>.*)");
  101. static Regex search = new Regex (@"\s*search\s+(?<domain>.*)");
  102. void ParseResolvConf ()
  103. {
  104. try {
  105. DateTime wt = File.GetLastWriteTime ("/etc/resolv.conf");
  106. if (wt <= last_parse)
  107. return;
  108. last_parse = wt;
  109. dns_suffix = "";
  110. dns_servers = new IPAddressCollection ();
  111. using (StreamReader reader = new StreamReader ("/etc/resolv.conf")) {
  112. string str;
  113. string line;
  114. while ((line = reader.ReadLine ()) != null) {
  115. line = line.Trim ();
  116. if (line.Length == 0 || line [0] == '#')
  117. continue;
  118. Match match = ns.Match (line);
  119. if (match.Success) {
  120. try {
  121. str = match.Groups ["address"].Value;
  122. str = str.Trim ();
  123. dns_servers.Add (IPAddress.Parse (str));
  124. } catch {
  125. }
  126. } else {
  127. match = search.Match (line);
  128. if (match.Success) {
  129. str = match.Groups ["domain"].Value;
  130. string [] parts = str.Split (',');
  131. dns_suffix = parts [0].Trim ();
  132. }
  133. }
  134. }
  135. }
  136. } catch {
  137. } finally {
  138. dns_servers.SetReadOnly ();
  139. }
  140. }
  141. public override IPAddressInformationCollection AnycastAddresses {
  142. get {
  143. List<IPAddress> anycastAddresses = new List<IPAddress> ();
  144. /* XXX:
  145. foreach (IPAddress address in addresses) {
  146. if (is_anycast_address (address)) {
  147. anycastAddresses.Add (address);
  148. }
  149. }
  150. */
  151. return IPAddressInformationImplCollection.LinuxFromAnycast (anycastAddresses);
  152. }
  153. }
  154. [MonoTODO ("Always returns an empty collection.")]
  155. public override IPAddressCollection DhcpServerAddresses {
  156. get {
  157. // There are lots of different DHCP clients
  158. // that all store their configuration differently.
  159. // I'm not sure what to do here.
  160. IPAddressCollection coll = new IPAddressCollection ();
  161. coll.SetReadOnly ();
  162. return coll;
  163. }
  164. }
  165. public override IPAddressCollection DnsAddresses {
  166. get {
  167. ParseResolvConf ();
  168. return dns_servers;
  169. }
  170. }
  171. public override string DnsSuffix {
  172. get {
  173. ParseResolvConf ();
  174. return dns_suffix;
  175. }
  176. }
  177. public override GatewayIPAddressInformationCollection GatewayAddresses {
  178. get {
  179. ParseRouteInfo (this.iface.Name.ToString());
  180. if (gateways.Count > 0)
  181. return new LinuxGatewayIPAddressInformationCollection (gateways);
  182. else
  183. return LinuxGatewayIPAddressInformationCollection.Empty;
  184. }
  185. }
  186. [MonoTODO ("Always returns true")]
  187. public override bool IsDnsEnabled {
  188. get {
  189. return true;
  190. }
  191. }
  192. [MonoTODO ("Always returns false")]
  193. public override bool IsDynamicDnsEnabled {
  194. get {
  195. return false;
  196. }
  197. }
  198. public override MulticastIPAddressInformationCollection MulticastAddresses {
  199. get {
  200. List<IPAddress> multicastAddresses = new List<IPAddress> ();
  201. foreach (IPAddress address in addresses) {
  202. byte[] addressBytes = address.GetAddressBytes ();
  203. if (addressBytes[0] >= 224 && addressBytes[0] <= 239) {
  204. multicastAddresses.Add (address);
  205. }
  206. }
  207. return MulticastIPAddressInformationImplCollection.LinuxFromList (multicastAddresses);
  208. }
  209. }
  210. public override UnicastIPAddressInformationCollection UnicastAddresses {
  211. get {
  212. List<IPAddress> unicastAddresses = new List<IPAddress> ();
  213. foreach (IPAddress address in addresses) {
  214. switch (address.AddressFamily) {
  215. case AddressFamily.InterNetwork:
  216. byte top = address.GetAddressBytes () [0];
  217. if (top >= 224 && top <= 239)
  218. continue;
  219. unicastAddresses.Add (address);
  220. break;
  221. case AddressFamily.InterNetworkV6:
  222. if (address.IsIPv6Multicast)
  223. continue;
  224. unicastAddresses.Add (address);
  225. break;
  226. }
  227. }
  228. return UnicastIPAddressInformationImplCollection.LinuxFromList (unicastAddresses);
  229. }
  230. }
  231. [MonoTODO ("Always returns an empty collection.")]
  232. public override IPAddressCollection WinsServersAddresses {
  233. get {
  234. // I do SUPPOSE we could scrape /etc/samba/smb.conf, but.. yeesh.
  235. return new IPAddressCollection ();
  236. }
  237. }
  238. }
  239. class LinuxIPInterfaceProperties : UnixIPInterfaceProperties
  240. {
  241. public LinuxIPInterfaceProperties (LinuxNetworkInterface iface, List <IPAddress> addresses)
  242. : base (iface, addresses)
  243. {
  244. }
  245. public override IPv4InterfaceProperties GetIPv4Properties ()
  246. {
  247. if (ipv4iface_properties == null)
  248. ipv4iface_properties = new LinuxIPv4InterfaceProperties (iface as LinuxNetworkInterface);
  249. return ipv4iface_properties;
  250. }
  251. }
  252. class MacOsIPInterfaceProperties : UnixIPInterfaceProperties
  253. {
  254. public MacOsIPInterfaceProperties (MacOsNetworkInterface iface, List <IPAddress> addresses)
  255. : base (iface, addresses)
  256. {
  257. }
  258. public override IPv4InterfaceProperties GetIPv4Properties ()
  259. {
  260. if (ipv4iface_properties == null)
  261. ipv4iface_properties = new MacOsIPv4InterfaceProperties (iface as MacOsNetworkInterface);
  262. return ipv4iface_properties;
  263. }
  264. }
  265. class Win32IPInterfaceProperties2 : IPInterfaceProperties
  266. {
  267. readonly Win32_IP_ADAPTER_ADDRESSES addr;
  268. readonly Win32_MIB_IFROW mib4, mib6;
  269. public Win32IPInterfaceProperties2 (Win32_IP_ADAPTER_ADDRESSES addr, Win32_MIB_IFROW mib4, Win32_MIB_IFROW mib6)
  270. {
  271. this.addr = addr;
  272. this.mib4 = mib4;
  273. this.mib6 = mib6;
  274. }
  275. public override IPv4InterfaceProperties GetIPv4Properties ()
  276. {
  277. Win32_IP_ADAPTER_INFO v4info = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
  278. return v4info != null ? new Win32IPv4InterfaceProperties (v4info, mib4) : null;
  279. }
  280. public override IPv6InterfaceProperties GetIPv6Properties ()
  281. {
  282. Win32_IP_ADAPTER_INFO v6info = Win32NetworkInterface2.GetAdapterInfoByIndex (mib6.Index);
  283. return v6info != null ? new Win32IPv6InterfaceProperties (mib6) : null;
  284. }
  285. public override IPAddressInformationCollection AnycastAddresses {
  286. get { return IPAddressInformationImplCollection.Win32FromAnycast (addr.FirstAnycastAddress); }
  287. }
  288. public override IPAddressCollection DhcpServerAddresses {
  289. get {
  290. Win32_IP_ADAPTER_INFO v4info = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
  291. // FIXME: should ipv6 DhcpServer be considered?
  292. return v4info != null ? new Win32IPAddressCollection (v4info.DhcpServer) : Win32IPAddressCollection.Empty;
  293. }
  294. }
  295. public override IPAddressCollection DnsAddresses {
  296. get { return Win32IPAddressCollection.FromDnsServer (addr.FirstDnsServerAddress); }
  297. }
  298. public override string DnsSuffix {
  299. get { return addr.DnsSuffix; }
  300. }
  301. public override GatewayIPAddressInformationCollection GatewayAddresses {
  302. get {
  303. Win32_IP_ADAPTER_INFO v4info = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
  304. // FIXME: should ipv6 DhcpServer be considered?
  305. return v4info != null ? new Win32GatewayIPAddressInformationCollection (v4info.GatewayList) : Win32GatewayIPAddressInformationCollection.Empty;
  306. }
  307. }
  308. public override bool IsDnsEnabled {
  309. get { return Win32_FIXED_INFO.Instance.EnableDns != 0; }
  310. }
  311. public override bool IsDynamicDnsEnabled {
  312. get { return addr.DdnsEnabled; }
  313. }
  314. public override MulticastIPAddressInformationCollection MulticastAddresses {
  315. get { return MulticastIPAddressInformationImplCollection.Win32FromMulticast (addr.FirstMulticastAddress); }
  316. }
  317. public override UnicastIPAddressInformationCollection UnicastAddresses {
  318. get {
  319. Win32_IP_ADAPTER_INFO ai = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
  320. // FIXME: should ipv6 DhcpServer be considered?
  321. return ai != null ? UnicastIPAddressInformationImplCollection.Win32FromUnicast ((int) ai.Index, addr.FirstUnicastAddress) : UnicastIPAddressInformationImplCollection.Empty;
  322. }
  323. }
  324. public override IPAddressCollection WinsServersAddresses {
  325. get {
  326. Win32_IP_ADAPTER_INFO v4info = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
  327. // FIXME: should ipv6 DhcpServer be considered?
  328. return v4info != null ? new Win32IPAddressCollection (v4info.PrimaryWinsServer, v4info.SecondaryWinsServer) : Win32IPAddressCollection.Empty;
  329. }
  330. }
  331. }
  332. }