New test.
[mono.git] / mcs / class / System / System.Net.NetworkInformation / IPInterfaceProperties.cs
index 9c011a450c43c548a12695f9a30bd4604ff9651d..d017319290834e409f659b9303c2c75df04e9d03 100644 (file)
 //
 #if NET_2_0
 using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
 using System.Net.Sockets;
+using System.Text.RegularExpressions;
 
 namespace System.Net.NetworkInformation {
        public abstract class IPInterfaceProperties {
@@ -51,29 +54,100 @@ namespace System.Net.NetworkInformation {
                public abstract IPAddressCollection WinsServersAddresses { get; }
        }
 
-       class LinuxIPInterfaceProperties : IPInterfaceProperties
+       abstract class UnixIPInterfaceProperties : IPInterfaceProperties
        {
-               IPv4InterfaceProperties ipv4iface_properties;
-               LinuxNetworkInterface iface;
+               protected IPv4InterfaceProperties ipv4iface_properties;
+               protected UnixNetworkInterface iface;
                List <IPAddress> addresses;
+               IPAddressCollection dns_servers;
+               IPAddressCollection gateways;
+               string dns_suffix;
+               DateTime last_parse;
                
-               public LinuxIPInterfaceProperties (LinuxNetworkInterface iface, List <IPAddress> addresses)
+               public UnixIPInterfaceProperties (UnixNetworkInterface iface, List <IPAddress> addresses)
                {
                        this.iface = iface;
                        this.addresses = addresses;
                }
 
-               public override IPv4InterfaceProperties GetIPv4Properties ()
+               public override IPv6InterfaceProperties GetIPv6Properties ()
                {
-                       if (ipv4iface_properties == null)
-                               ipv4iface_properties = new LinuxIPv4InterfaceProperties (iface);
-                       
-                       return ipv4iface_properties;
+                       throw new NotImplementedException ();
                }
 
-               public override IPv6InterfaceProperties GetIPv6Properties ()
+               void ParseRouteInfo (string iface)
                {
-                       throw new NotImplementedException ();
+                       try {
+                               gateways = new IPAddressCollection ();
+                               using (StreamReader reader = new StreamReader ("/proc/net/route")) {
+                                       string line;
+                                       reader.ReadLine (); // Ignore first line
+                                       while ((line = reader.ReadLine ()) != null) {
+                                               line = line.Trim ();
+                                               if (line.Length == 0)
+                                                       continue;
+
+                                               string [] parts = line.Split ('\t');
+                                               if (parts.Length < 3)
+                                                       continue;
+                                               string gw_address = parts [2].Trim ();
+                                               byte [] ipbytes = new byte [4];  
+                                               if (gw_address.Length == 8 && iface.Equals (parts [0], StringComparison.OrdinalIgnoreCase)) {
+                                                       for (int i = 0; i < 4; i++) {
+                                                               if (!Byte.TryParse (gw_address.Substring (i * 2, 2), NumberStyles.HexNumber, null, out ipbytes [3 - i]))
+                                                                       continue;
+                                                       }
+                                                       IPAddress ip = new IPAddress (ipbytes);
+                                                       if (!ip.Equals (IPAddress.Any))
+                                                               gateways.Add (ip);
+                                               }
+                                       }
+                               }
+                       } catch {
+                       }
+               }
+
+               static Regex ns = new Regex (@"\s*nameserver\s+(?<address>.*)");
+               static Regex search = new Regex (@"\s*search\s+(?<domain>.*)");
+               void ParseResolvConf ()
+               {
+                       try {
+                               DateTime wt = File.GetLastWriteTime ("/etc/resolv.conf");
+                               if (wt <= last_parse)
+                                       return;
+
+                               last_parse = wt;
+                               dns_suffix = "";
+                               dns_servers = new IPAddressCollection ();
+                               using (StreamReader reader = new StreamReader ("/etc/resolv.conf")) {
+                                       string str;
+                                       string line;
+                                       while ((line = reader.ReadLine ()) != null) {
+                                               line = line.Trim ();
+                                               if (line.Length == 0 || line [0] == '#')
+                                                       continue;
+                                               Match match = ns.Match (line);
+                                               if (match.Success) {
+                                                       try {
+                                                               str = match.Groups ["address"].Value;
+                                                               str = str.Trim ();
+                                                               dns_servers.Add (IPAddress.Parse (str));
+                                                       } catch {
+                                                       }
+                                               } else {
+                                                       match = search.Match (line);
+                                                       if (match.Success) {
+                                                               str = match.Groups ["domain"].Value;
+                                                               string [] parts = str.Split (',');
+                                                               dns_suffix = parts [0].Trim ();
+                                                       }
+                                               }
+                                       }
+                               }
+                       } catch {
+                       } finally {
+                               dns_servers.SetReadOnly ();
+                       }
                }
 
                public override IPAddressInformationCollection AnycastAddresses {
@@ -96,31 +170,33 @@ namespace System.Net.NetworkInformation {
                                // There are lots of different DHCP clients
                                // that all store their configuration differently.
                                // I'm not sure what to do here.
-                               return new IPAddressCollection ();
+                               IPAddressCollection coll = new IPAddressCollection ();
+                               coll.SetReadOnly ();
+                               return coll;
                        }
                }
 
-               [MonoTODO ("Always returns an empty collection.")]
                public override IPAddressCollection DnsAddresses {
                        get {
-                               // XXX: Parse /etc/resolv.conf, I suppose.
-                               return new IPAddressCollection ();
+                               ParseResolvConf ();
+                               return dns_servers;
                        }
                }
 
-               [MonoTODO ("Does not return anything.")]
                public override string DnsSuffix {
                        get {
-                               // XXX: Also parse resolv.conf?
-                               return String.Empty;
+                               ParseResolvConf ();
+                               return dns_suffix;
                        }
                }
-
-               [MonoTODO ("Always returns an empty collection.")]
+     
                public override GatewayIPAddressInformationCollection GatewayAddresses {
                        get {
-                               // XXX: Pull information from route table.
-                               return LinuxGatewayIPAddressInformationCollection.Empty;
+                               ParseRouteInfo (this.iface.Name.ToString());
+                               if (gateways.Count > 0)
+                                       return new LinuxGatewayIPAddressInformationCollection (gateways);
+                               else
+                                       return LinuxGatewayIPAddressInformationCollection.Empty;
                        }
                }
 
@@ -183,6 +259,38 @@ namespace System.Net.NetworkInformation {
                }
        }
 
+       class LinuxIPInterfaceProperties : UnixIPInterfaceProperties
+       {
+               public LinuxIPInterfaceProperties (LinuxNetworkInterface iface, List <IPAddress> addresses)
+                       : base (iface, addresses)
+               {
+               }
+
+               public override IPv4InterfaceProperties GetIPv4Properties ()
+               {
+                       if (ipv4iface_properties == null)
+                               ipv4iface_properties = new LinuxIPv4InterfaceProperties (iface as LinuxNetworkInterface);
+                       
+                       return ipv4iface_properties;
+               }
+       }
+
+       class MacOsIPInterfaceProperties : UnixIPInterfaceProperties
+       {
+               public MacOsIPInterfaceProperties (MacOsNetworkInterface iface, List <IPAddress> addresses)
+                       : base (iface, addresses)
+               {
+               }
+
+               public override IPv4InterfaceProperties GetIPv4Properties ()
+               {
+                       if (ipv4iface_properties == null)
+                               ipv4iface_properties = new MacOsIPv4InterfaceProperties (iface as MacOsNetworkInterface);
+                       
+                       return ipv4iface_properties;
+               }
+       }
+
        class Win32IPInterfaceProperties2 : IPInterfaceProperties
        {
                readonly Win32_IP_ADAPTER_ADDRESSES addr;
@@ -248,7 +356,11 @@ namespace System.Net.NetworkInformation {
                }
 
                public override UnicastIPAddressInformationCollection UnicastAddresses {
-                       get { return UnicastIPAddressInformationImplCollection.Win32FromUnicast (addr.FirstUnicastAddress); }
+                       get {
+                               Win32_IP_ADAPTER_INFO ai = Win32NetworkInterface2.GetAdapterInfoByIndex (mib4.Index);
+                               // FIXME: should ipv6 DhcpServer be considered?
+                               return ai != null ? UnicastIPAddressInformationImplCollection.Win32FromUnicast ((int) ai.Index, addr.FirstUnicastAddress) : UnicastIPAddressInformationImplCollection.Empty;
+                       }
                }
 
                public override IPAddressCollection WinsServersAddresses {