2007-02-16 Geoff Norton <gnorton@customerdna.com>
[mono.git] / mcs / class / System / System.Net / IPAddress.cs
index 07ddd0d3e14d55b0cc8a036afc17bf31e40b44eb..8d34ba74847b909a0293535bfeecf5836775a546 100644 (file)
@@ -47,18 +47,14 @@ namespace System.Net {
                private AddressFamily m_Family = AddressFamily.InterNetwork;
                private ushort[] m_Numbers = new ushort[8];     /// ip6 Stored in network order (as ip4)
                private long m_ScopeId = 0;
-               private int m_HashCode; // Added for serialization compatibility with MS.NET
 
                public static readonly IPAddress Any = new IPAddress(0);
                public static readonly IPAddress Broadcast = IPAddress.Parse ("255.255.255.255");
                public static readonly IPAddress Loopback = IPAddress.Parse ("127.0.0.1");
                public static readonly IPAddress None = IPAddress.Parse ("255.255.255.255");
-
-#if NET_1_1
                public static readonly IPAddress IPv6Any = IPAddress.ParseIPV6 ("::");
                public static readonly IPAddress IPv6Loopback = IPAddress.ParseIPV6 ("::1");
                public static readonly IPAddress IPv6None = IPAddress.ParseIPV6 ("::");
-#endif
 
                private static short SwapShort (short number)
                {
@@ -138,17 +134,22 @@ namespace System.Net {
                        m_Address = addr;
                }
 
-#if NET_1_1
                public IPAddress (byte[] address)
                {
+                       if (address == null)
+                               throw new ArgumentNullException ("address");
+
                        int len = address.Length;
+
 #if NET_2_0
                        if (len != 16 && len != 4)
-                               throw new ArgumentException ("address");
+                               throw new ArgumentException ("An invalid IP address was specified.",
+                                       "address");
 #else
                        if (len != 16)
                                throw new ArgumentException ("address");
 #endif
+
                        if (len == 16) {
                                Buffer.BlockCopy(address, 0, m_Numbers, 0, 16);
                                m_Family = AddressFamily.InterNetworkV6;
@@ -161,8 +162,16 @@ namespace System.Net {
 
                public IPAddress(byte[] address, long scopeId)
                {
+                       if (address == null)
+                               throw new ArgumentNullException ("address");
+
                        if (address.Length != 16)
+#if NET_2_0
+                               throw new ArgumentException ("An invalid IP address was specified.",
+                                       "address");
+#else
                                throw new ArgumentException("address");
+#endif
 
                        Buffer.BlockCopy(address, 0, m_Numbers, 0, 16);
                        m_Family = AddressFamily.InterNetworkV6;
@@ -179,24 +188,27 @@ namespace System.Net {
                        m_Family = AddressFamily.InterNetworkV6;
                        m_ScopeId = scopeId;
                }
-#endif
 
                public static IPAddress Parse (string ip)
                {
                        IPAddress ret;
+                       if (TryParse (ip, out ret))
+                               return ret;
+                       throw new FormatException("An invalid IP address was specified.");
+               }
 
+#if NET_2_0
+               public
+#endif
+               static bool TryParse (string ip, out IPAddress address)
+               {
                        if (ip == null)
                                throw new ArgumentNullException ("Value cannot be null.");
                                
-#if NET_1_1
-                       if( (ret = ParseIPV4(ip)) == null)
-                               if( (ret = ParseIPV6(ip)) == null)
-                                       throw new FormatException("An invalid IP address was specified.");
-#else
-                       if( (ret = ParseIPV4(ip)) == null)
-                                       throw new FormatException("An invalid IP address was specified.");
-#endif
-                       return ret;
+                       if( (address = ParseIPV4(ip)) == null)
+                               if( (address = ParseIPV6(ip)) == null)
+                                       return false;
+                       return true;
                }
 
                private static IPAddress ParseIPV4 (string ip)
@@ -206,7 +218,7 @@ namespace System.Net {
                                
                        int pos = ip.IndexOf (' ');
                        if (pos != -1)
-                               ip = ip.Substring (0, pos);                             
+                               ip = ip.Substring (0, pos);
 
                        if (ip.Length == 0 || ip [ip.Length - 1] == '.')
                                return null;
@@ -246,7 +258,6 @@ namespace System.Net {
                        }
                }
                
-#if NET_1_1
                private static IPAddress ParseIPV6 (string ip)
                {
                        try 
@@ -260,7 +271,6 @@ namespace System.Net {
                }
 
                [Obsolete("This property is obsolete. Use GetAddressBytes.")]
-#endif
                public long Address 
                {
                        get {
@@ -286,8 +296,34 @@ namespace System.Net {
                internal long InternalIPv4Address {
                        get { return m_Address; }
                }
-               
-#if NET_1_1
+
+#if NET_2_0
+               public bool IsIPv6LinkLocal {
+                       get {
+                               if (m_Family == AddressFamily.InterNetwork)
+                                       return false;
+                               int v = NetworkToHostOrder ((short) m_Numbers [0]) & 0xFFF0;
+                               return 0xFE80 <= v && v < 0xFEC0;
+                       }
+               }
+
+               public bool IsIPv6SiteLocal {
+                       get {
+                               if (m_Family == AddressFamily.InterNetwork)
+                                       return false;
+                               int v = NetworkToHostOrder ((short) m_Numbers [0]) & 0xFFF0;
+                               return 0xFEC0 <= v && v < 0xFF00;
+                       }
+               }
+
+               public bool IsIPv6Multicast {
+                       get {
+                               return m_Family != AddressFamily.InterNetwork &&
+                                       ((ushort) NetworkToHostOrder ((short) m_Numbers [0]) & 0xFF00) == 0xFF00;
+                       }
+               }
+#endif
+
                public long ScopeId {
                        get {
                                if(m_Family != AddressFamily.InterNetworkV6)
@@ -316,7 +352,7 @@ namespace System.Net {
                                                     (byte)(m_Address >> 24) }; 
                        }
                }
-#endif
+
                public AddressFamily AddressFamily 
                {
                        get {
@@ -418,5 +454,11 @@ namespace System.Net {
                {
                        return i ^ (j << 13 | j >> 19) ^ (k << 26 | k >> 6) ^ (l << 7 | l >> 25);
                }
+
+#pragma warning disable 169
+               // Added for serialization compatibility with MS.NET
+               private int m_HashCode; 
+#pragma warning restore
+               
        }
 }