2 // System.Net.IPAddress.cs
5 // Miguel de Icaza (miguel@ximian.com)
6 // Lawrence Pit (loz@cable.a2000.nl)
8 // (C) Ximian, Inc. http://www.ximian.com
11 // Note: the address is stored in host order
14 using System.Globalization;
15 using System.Net.Sockets;
16 using System.Runtime.InteropServices;
18 namespace System.Net {
21 /// Encapsulates an IP Address.
24 public class IPAddress {
25 // Don't change the name of this field without also
26 // changing socket-io.c in the runtime
29 public static readonly IPAddress Any = new IPAddress(0);
30 public static readonly IPAddress Broadcast = IPAddress.Parse ("255.255.255.255");
31 public static readonly IPAddress Loopback = IPAddress.Parse ("127.0.0.1");
32 public static readonly IPAddress None = IPAddress.Parse ("255.255.255.255");
34 private static short SwapShort (short number)
36 return (short) ( ((number >> 8) & 0xFF) + ((number << 8) & 0xFF00) );
39 private static int SwapInt (int number)
41 byte b0 = (byte) ((number >> 24) & 0xFF);
42 byte b1 = (byte) ((number >> 16) & 0xFF);
43 byte b2 = (byte) ((number >> 8) & 0xFF);
44 byte b3 = (byte) (number & 0xFF);
45 return b0 + (b1 << 8) + (b2 << 16) + (b3 << 24);
48 private static long SwapLong (long number)
50 byte b0 = (byte) ((number >> 56) & 0xFF);
51 byte b1 = (byte) ((number >> 48) & 0xFF);
52 byte b2 = (byte) ((number >> 40) & 0xFF);
53 byte b3 = (byte) ((number >> 32) & 0xFF);
54 byte b4 = (byte) ((number >> 24) & 0xFF);
55 byte b5 = (byte) ((number >> 16) & 0xFF);
56 byte b6 = (byte) ((number >> 8) & 0xFF);
57 byte b7 = (byte) (number & 0xFF);
58 return (long) b0 + ((long) b1 << 8) + ((long) b2 << 16) + ((long) b3 << 24) + ((long) b4 << 32) + ((long) b5 << 40) + ((long) b6 << 48) + ((long) b7 << 56);
61 public static short HostToNetworkOrder(short host) {
62 if (!BitConverter.IsLittleEndian)
65 return SwapShort (host);
68 public static int HostToNetworkOrder(int host) {
69 if (!BitConverter.IsLittleEndian)
72 return SwapInt (host);
75 public static long HostToNetworkOrder(long host) {
76 if (!BitConverter.IsLittleEndian)
79 return SwapLong (host);
82 public static short NetworkToHostOrder(short network) {
83 if (!BitConverter.IsLittleEndian)
86 return SwapShort (network);
89 public static int NetworkToHostOrder(int network) {
90 if (!BitConverter.IsLittleEndian)
93 return SwapInt (network);
96 public static long NetworkToHostOrder(long network) {
97 if (!BitConverter.IsLittleEndian)
100 return SwapLong (network);
104 /// Constructor from a 32-bit constant with its bytes
105 /// in network order.
107 public IPAddress (long addr)
112 public static IPAddress Parse (string ip)
115 throw new ArgumentNullException ("null ip string");
117 if (ip.Length == 0 || ip [0] == ' ')
118 return new IPAddress (0);
120 int pos = ip.IndexOf (' ');
122 ip = ip.Substring (0, pos);
123 else if (ip [ip.Length - 1] == '.')
124 throw new FormatException ("An invalid IP address was specified");
126 string [] ips = ip.Split (new char [] {'.'});
128 throw new FormatException ("An invalid IP address was specified");
130 // Make the number in network order
134 for (int i = 0; i < ips.Length; i++) {
135 string subnet = ips [i];
136 if ((3 <= subnet.Length && subnet.Length <= 4) &&
137 (subnet [0] == '0') &&
138 (subnet [1] == 'x' || subnet [2] == 'X')) {
139 if (subnet.Length == 3)
140 val = (byte) Uri.FromHex (subnet [2]);
142 val = (byte) ((Uri.FromHex (subnet [2]) << 4) | Uri.FromHex (subnet [3]));
143 } else if (subnet.Length == 0)
146 val = Byte.Parse (subnet, NumberStyles.None);
148 if (ips.Length < 4 && i == (ips.Length - 1))
151 a |= (long) val << (i << 3);
154 return (new IPAddress (a));
155 } catch (Exception) {
156 throw new FormatException ("An invalid IP address was specified");
160 public long Address {
165 /* no need to do this test, ms.net accepts any value.
166 if (value < 0 || value > 0x00000000FFFFFFFF)
167 throw new ArgumentOutOfRangeException (
168 "the address must be between 0 and 0xFFFFFFFF");
175 public AddressFamily AddressFamily {
177 return(AddressFamily.InterNetwork);
183 /// Used to tell whether an address is a loopback.
184 /// All IP addresses of the form 127.X.Y.Z, where X, Y, and Z are in
185 /// the range 0-255, are loopback addresses.
187 /// <param name="addr">Address to compare</param>
188 /// <returns></returns>
189 public static bool IsLoopback (IPAddress addr)
191 return (addr.address & 0xFF) == 127;
195 /// Overrides System.Object.ToString to return
196 /// this object rendered in a quad-dotted notation
198 public override string ToString ()
200 return ToString (address);
204 /// Returns this object rendered in a quad-dotted notation
206 static string ToString (long addr)
208 // addr is in network order
209 return (addr & 0xff).ToString () + "." +
210 ((addr >> 8) & 0xff).ToString () + "." +
211 ((addr >> 16) & 0xff).ToString () + "." +
212 ((addr >> 24) & 0xff).ToString ();
216 /// Whether both objects are equal.
218 public override bool Equals (object other)
220 if (other is System.Net.IPAddress){
221 return Address == ((System.Net.IPAddress) other).Address;
226 public override int GetHashCode ()