Merge pull request #2720 from mono/fix-39325
[mono.git] / mcs / class / System / Test / System.Net / IPAddressTest.cs
1 //
2 // IPAddressTest.cs - NUnit Test Cases for System.Net.IPAddress
3 //
4 // Authors:
5 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //   Martin Willemoes Hansen (mwh@sysrq.dk)
7 //
8 // (C) Ximian, Inc. http://www.ximian.com
9 // (C) 2003 Martin Willemoes Hansen
10 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
11 //
12
13 using NUnit.Framework;
14 using System;
15 using System.Net;
16 using System.Net.Sockets;
17 using System.Runtime.InteropServices;
18
19 namespace MonoTests.System.Net
20 {
21
22 [TestFixture]
23 public class IPAddressTest
24 {
25         static string[] ipv6AddressList = new string[] {
26                    "::", "0:0:0:0:0:0:0:0", 
27                    "1::", "1:0:0:0:0:0:0:0",
28                    "2:2::", "2:2:0:0:0:0:0:0",
29                    "7:7:7:7:7:7:7:0", "7:7:7:7:7:7:7:0",
30                    "::1", "0:0:0:0:0:0:0:1",
31                    "::2", "0:0:0:0:0:0:0:2",
32                    "::F", "0:0:0:0:0:0:0:F",
33                    "::10", "0:0:0:0:0:0:0:10",
34                    "::A0", "0:0:0:0:0:0:0:A0",
35                    "::F0", "0:0:0:0:0:0:0:F0",
36                    "::FF", "0:0:0:0:0:0:0:FF",
37                    "::0.1.0.0", "0:0:0:0:0:0:1:0",
38                    "::0.2.0.0", "0:0:0:0:0:0:2:0",
39                    "::0.15.0.0", "0:0:0:0:0:0:F:0",
40                    "::0.16.0.0", "0:0:0:0:0:0:10:0",
41                    "::0.160.0.0", "0:0:0:0:0:0:A0:0",
42                    "::0.240.0.0", "0:0:0:0:0:0:F0:0",
43                    "::0.255.0.0", "0:0:0:0:0:0:FF:0",
44                    "::1001", "0:0:0:0:0:0:0:1001",
45                    "::1002", "0:0:0:0:0:0:0:1002",
46                    "::100F", "0:0:0:0:0:0:0:100F",
47                    "::1010", "0:0:0:0:0:0:0:1010",
48                    "::10A0", "0:0:0:0:0:0:0:10A0",
49                    "::10F0", "0:0:0:0:0:0:0:10F0",
50                    "::10FF", "0:0:0:0:0:0:0:10FF",
51                    "::0.1.0.1", "0:0:0:0:0:0:1:1",
52                    "::0.2.0.2", "0:0:0:0:0:0:2:2",
53                    "::0.15.0.15", "0:0:0:0:0:0:F:F",
54                    "::0.16.0.16", "0:0:0:0:0:0:10:10",
55                    "::0.160.0.160", "0:0:0:0:0:0:A0:A0",
56                    "::0.240.0.240", "0:0:0:0:0:0:F0:F0",
57                    "::0.255.0.255", "0:0:0:0:0:0:FF:FF",
58                    "::FFFF:0:1", "0:0:0:0:0:FFFF:0:1",
59                    "::FFFF:0:2", "0:0:0:0:0:FFFF:0:2",
60                    "::FFFF:0:F", "0:0:0:0:0:FFFF:0:F",
61                    "::FFFF:0:10", "0:0:0:0:0:FFFF:0:10",
62                    "::FFFF:0:A0", "0:0:0:0:0:FFFF:0:A0",
63                    "::FFFF:0:F0", "0:0:0:0:0:FFFF:0:F0",
64                    "::FFFF:0:FF", "0:0:0:0:0:FFFF:0:FF",
65                    "::FFFF:0.1.0.0", "0:0:0:0:0:FFFF:1:0",
66                    "::FFFF:0.2.0.0", "0:0:0:0:0:FFFF:2:0",
67                    "::FFFF:0.15.0.0", "0:0:0:0:0:FFFF:F:0",
68                    "::FFFF:0.16.0.0", "0:0:0:0:0:FFFF:10:0",
69                    "::FFFF:0.160.0.0", "0:0:0:0:0:FFFF:A0:0",
70                    "::FFFF:0.240.0.0", "0:0:0:0:0:FFFF:F0:0",
71                    "::FFFF:0.255.0.0", "0:0:0:0:0:FFFF:FF:0",
72                    "::FFFF:0:1001", "0:0:0:0:0:FFFF:0:1001",
73                    "::FFFF:0:1002", "0:0:0:0:0:FFFF:0:1002",
74                    "::FFFF:0:100F", "0:0:0:0:0:FFFF:0:100F",
75                    "::FFFF:0:1010", "0:0:0:0:0:FFFF:0:1010",
76                    "::FFFF:0:10A0", "0:0:0:0:0:FFFF:0:10A0",
77                    "::FFFF:0:10F0", "0:0:0:0:0:FFFF:0:10F0",
78                    "::FFFF:0:10FF", "0:0:0:0:0:FFFF:0:10FF",
79                    "::FFFF:0.1.0.1", "0:0:0:0:0:FFFF:1:1",
80                    "::FFFF:0.2.0.2", "0:0:0:0:0:FFFF:2:2",
81                    "::FFFF:0.15.0.15", "0:0:0:0:0:FFFF:F:F",
82                    "::FFFF:0.16.0.16", "0:0:0:0:0:FFFF:10:10",
83                    "::FFFF:0.160.0.160", "0:0:0:0:0:FFFF:A0:A0",
84                    "::FFFF:0.240.0.240", "0:0:0:0:0:FFFF:F0:F0",
85                    "::FFFF:0.255.0.255", "0:0:0:0:0:FFFF:FF:FF",
86                    "0:7:7:7:7:7:7:7", "0:7:7:7:7:7:7:7",
87                    "E::1", "E:0:0:0:0:0:0:1",
88                    "E::2:2", "E:0:0:0:0:0:2:2",
89                    "E:0:6:6:6:6:6:6", "E:0:6:6:6:6:6:6",
90                    "E:E::1", "E:E:0:0:0:0:0:1",
91                    "E:E::2:2", "E:E:0:0:0:0:2:2",
92                    "E:E:0:5:5:5:5:5", "E:E:0:5:5:5:5:5",
93                    "E:E:E::1", "E:E:E:0:0:0:0:1",
94                    "E:E:E::2:2", "E:E:E:0:0:0:2:2",
95                    "E:E:E:0:4:4:4:4", "E:E:E:0:4:4:4:4",
96                    "E:E:E:E::1", "E:E:E:E:0:0:0:1",
97                    "E:E:E:E::2:2", "E:E:E:E:0:0:2:2",
98                    "E:E:E:E:0:3:3:3", "E:E:E:E:0:3:3:3",
99                    "E:E:E:E:E::1", "E:E:E:E:E:0:0:1",
100                    "E:E:E:E:E:0:2:2", "E:E:E:E:E:0:2:2",
101                    "E:E:E:E:E:E:0:1", "E:E:E:E:E:E:0:1",
102                    "::0.2.0.2", "0:0:0:0:0:0:2:2",
103                    "::FFFF:192.168.0.1", "::FFFF:192.168.0.1",
104                    "::FFFF:0.168.0.1", "::FFFF:0.168.0.1",
105                    "::FFFF", "::0.0.255.255",
106                    "::EEEE:A00:1", "::EEEE:10.0.0.1",
107                    "::10.0.0.1", "::10.0.0.1",
108                    "1234::1234:0:0", "1234:0:0:0:0:1234:0:0",
109                    "1:0:1:0:1:0:1:0", "1:0:1:0:1:0:1:0",
110                    "1:1:1::1:1:0", "1:1:1:0:0:1:1:0",
111                    "::1234:0:0", "0:0:0:0:0:1234:0:0",
112                    "3ffe:38e1::100:1:1", "3ffe:38e1::0100:1:0001",
113                    "0:0:1:2::", "0:0:1:2:00:00:000:0000",
114                    "100:0:1:2::abcd", "100:0:1:2:0:0:000:abcd",
115                    "ffff::abcd", "ffff:0:0:0:0:0:00:abcd",
116                    "ffff:0:0:2::abcd", "ffff:0:0:2:0:0:00:abcd",
117                    "0:0:1:2::", "0:0:1:2:0:00:0000:0000",
118                    "::1:0:0", "0000:0000::1:0000:0000",
119                    "::111:234:5:6:789a:0", "0:0:111:234:5:6:789A:0",
120                    "11:22:33:44:55:66:77:8", "11:22:33:44:55:66:77:8",
121                    "0:0:7711:ab42:1230::", "::7711:ab42:1230:0:0:0",
122                    "fec0:0:0:ffff::1%1",
123         };
124
125         static string[] ipv6ParseWrong = new string[] {
126                    ":::4df",
127                    "4df:::",
128                    "0:::4df",
129                    "4df:::0",
130                    "::4df:::",
131                    "0::4df:::",
132                    " ::1",
133                    ":: 1",
134                    ":",
135                    "0:0:0:0:0:0:0:0:0",
136                    "0:0:0:0:0:0:0",
137                    "0FFFF::",
138                    "FFFF0::",
139                    "[::1",
140         };
141
142         static string[] ipv4ParseOk = new string[] {
143                 "192.168.1.1", "192.168.1.1",
144                 "0xff.0x7f.0x20.0x01", "255.127.32.1",
145                 "0xff.0x7f.0x20.0xf", "255.127.32.15",
146                 "0.0.0.0", IPAddress.Any.ToString(),
147                 "255.255.255.255", IPAddress.Broadcast.ToString(),
148                 "12.1.1.3 abc", "12.1.1.3",
149                 "12.1 .1.2", "12.0.0.1",
150                 "12.1 .zzzz.2", "12.0.0.1",
151                 "12.1.7", "12.1.0.7",
152                 "12", "0.0.0.12",
153                 "12.5.3 foo.67.test.test.7FFFFFFFFFfaFFF789FFFFFFFFFFFFFFF", "12.5.0.3",
154                 "12.1 foo.bar.test.test.baf", "12.0.0.1",
155                 "12.1.4.6 foo.bar.test.test.baf", "12.1.4.6",
156                 "12.3 foo.bar.test.test.4", "12.0.0.3",
157                 "12 foo.bar.test.test.baf", "0.0.0.12",
158                 "65536", "0.1.0.0",
159                 "65535", "0.0.255.255",
160                 "20.65535", "20.0.255.255",
161                 "0313.027035210", "203.92.58.136", // bug #411920
162                 "0313.0134.035210", "203.92.58.136", // too
163                 "1434328179", "85.126.28.115", // too
164                 "3397943208", "202.136.127.168", // too
165         };
166
167         static string [] ipv4ParseWrong = new string [] {
168                 " foo",
169                 "12.. .",
170                 "12.1.2. ",
171                 "12.1.8. ",
172                 ".1.1.6",
173                 " 12.1.1.1",
174                 "12.+1.1.4",
175                 "12.1.-1.5",
176                 "257.1.1.9",
177                 "255.1.1.256",
178                 "12.1.1.3 ",
179                 "12.1 foo.1.2.3.4.5.bar",
180                 "12.1 foo.1.2.3.4.5.",
181                 "12.1.1.3 g",
182                 " ",
183                 "",
184                 "12.1.foo.1.2.3.4.5.bar",
185                 "12.",
186                 "12.1.2.",
187                 "12...",
188                 "  ",
189                 "7848198702",
190         };
191
192         static byte [] ipv4MappedIPv6Prefix = new byte [] { 0,0, 0,0, 0,0, 0,0, 0,0, 0xFF,0xFF };
193
194         [Test]
195         public void PublicFields ()
196         {
197                 Assert.AreEqual ((long) 0, IPAddress.Any.Address, "#1");
198                 Assert.AreEqual ((long) 0xFFFFFFFF, IPAddress.Broadcast.Address, "#2");
199                 long loopback = IPAddress.HostToNetworkOrder (BitConverter.IsLittleEndian ? 
200                                                               0x7f000001 : 
201                                                               0x0100007f);
202                 Assert.AreEqual (loopback, IPAddress.Loopback.Address, "#3");
203                 Assert.AreEqual ((long) 0xFFFFFFFF, IPAddress.None.Address, "#4");
204         }
205
206         [Test]
207         public void ToStringV4 ()
208         {
209                 IPAddress ip = IPAddress.Parse ("192.168.1.1");
210                 Assert.AreEqual ("192.168.1.1", ip.ToString (), "#1");
211                 Assert.AreEqual ("0.0.0.0", IPAddress.Any.ToString (), "#2");
212                 Assert.AreEqual ("255.255.255.255", IPAddress.Broadcast.ToString (), "#3");
213                 Assert.AreEqual ("127.0.0.1", IPAddress.Loopback.ToString (), "#4");
214                 Assert.AreEqual ("255.255.255.255", IPAddress.None.ToString (), "#5");
215         }
216
217         [Test]
218         public void ToStringV6 ()
219         {
220                 for(int i=0; i<ipv6AddressList.Length/2; i++) {
221                         string addr = IPAddress.Parse (ipv6AddressList[i*2+1]).ToString().ToLower();
222                         Assert.AreEqual (ipv6AddressList[i*2].ToLower(), addr, "ToStringIPv6 #" + i);
223                 }
224         }
225
226         [Test]
227         public void IsLoopbackV4 ()
228         {
229                 IPAddress ip;
230
231                 ip = IPAddress.Parse ("127.0.0.1");
232                 Assert.IsTrue (IPAddress.IsLoopback (ip), "#1");
233                 ip = IPAddress.Any;
234                 Assert.IsFalse (IPAddress.IsLoopback (ip), "#2");
235                 ip = IPAddress.Loopback;
236                 Assert.IsTrue (IPAddress.IsLoopback (ip), "#3");
237                 ip = IPAddress.Parse ("::101");
238                 Assert.IsFalse (IPAddress.IsLoopback (ip), "#4");
239         }
240
241         [Test]
242         public void IsLoopbackV6 ()
243         {
244                 if (!Socket.SupportsIPv6)
245                         Assert.Ignore ("IPv6 must be enabled in machine.config");
246
247                 IPAddress ip = IPAddress.IPv6Loopback;
248                 Assert.IsTrue (IPAddress.IsLoopback (ip), "#1");
249
250                 ip = IPAddress.IPv6None;
251                 Assert.IsFalse (IPAddress.IsLoopback (ip), "#2");
252         }
253
254         [Test]
255         public void GetAddressBytesV4 ()
256         {
257                 byte[] dataIn   = { 10, 11, 12, 13 };
258                 byte[] dataOut  = IPAddress.Parse ("10.11.12.13").GetAddressBytes ();
259                 for (int i = 0; i < dataIn.Length; i++)
260                         Assert.AreEqual (dataOut [i], dataIn [i], "GetAddressBytesV4");
261         }
262
263         [Test]
264         public void GetAddressBytesV6 ()
265         {
266                 byte[] dataIn   = new byte[]{ 0x01, 0x23, 0x45, 0x67, 0x89, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0x98 };
267                 byte[] dataOut  = IPAddress.Parse ("123:4567:8998:7654:3210:0123:4567:8998").GetAddressBytes ();
268                 for (int i = 0; i < dataIn.Length; i++)
269                         Assert.AreEqual (dataOut [i], dataIn [i], "GetAddressBytesV6 #1");
270
271                 dataIn  = new byte[]{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x01 };
272                 dataOut = IPAddress.Parse ("::FFFF:127.0.0.1").GetAddressBytes ();
273                 for (int i = 0; i < dataIn.Length; i++)
274                         Assert.AreEqual (dataOut [i], dataIn [i], "GetAddressBytesV6 #2");
275         }
276
277         [Test]
278         public void Address ()
279         {
280                 // hm, lame, anything is accepted by ms.net
281                 /*
282                 try {
283                         IPAddress ip1 = new IPAddress (0x0000000100000000);
284                         Assertion.Fail ("#1");
285                 } catch (ArgumentOutOfRangeException) {}
286                 IPAddress ip = IPAddress.Parse ("127.0.0.1");
287                 ip.Address = 0;
288                 ip.Address = 0xffffffff;
289                 try {
290                         ip.Address = -1;
291                         Assertion.Fail ("#2");
292                 } catch (ArgumentOutOfRangeException) {}
293                 try {
294                         ip.Address = 0x0000000100000000;
295                         Assertion.Fail ("#3");
296                 } catch (ArgumentOutOfRangeException) {}
297                 */
298         }
299
300         [Test]
301         public void ParseOkV4 ()
302         {
303                 for (int i = 0; i < ipv4ParseOk.Length / 2; i++) {
304                         IPAddress ip;
305                         try {
306                                 ip = IPAddress.Parse (ipv4ParseOk [i*2]);
307                                 Assert.AreEqual (ipv4ParseOk [i * 2 + 1], ip.ToString (), "ParseOkV4:" + i);
308                         } catch (FormatException) {
309                                 Assert.Fail ("Cannot parse test i=" + i + ": '" + ipv4ParseOk [i*2] + "'");
310                         }
311                 }
312         }
313
314         [Test]
315         public void ParseOkV6 ()
316         {
317                 for (int i = 0; i < ipv6AddressList.Length / 2; i++) {
318                         string source = ipv6AddressList [i*2].ToLower();
319
320                         IPAddress ip = IPAddress.Parse (source);
321                         Assert.AreEqual (ip.ToString ().ToLower (), source,
322                                 string.Format("ParseIPv6 #{0}-1: {1} != {2}", i,
323                                         ip.ToString ().ToLower (), source));
324
325                         ip = IPAddress.Parse (ipv6AddressList [i*2+1].ToLower ());
326                         Assert.AreEqual (ip.ToString ().ToLower (), source,
327                                 string.Format("ParseIPv6 #{0}-2: {1} != {2}", i,
328                                         ip.ToString ().ToLower (), source));
329                 }
330         }
331
332         [Test]
333         public void ParseWrongV4 ()
334         {
335                 for (int i = 0; i < ipv4ParseWrong.Length; i++) {
336                         string ipAddress = ipv4ParseWrong [i];
337
338                         try {
339                                 IPAddress ip = IPAddress.Parse (ipAddress);
340                                 Assert.Fail ("#1:" + i + " (" + ipAddress + ")");
341                         } catch (FormatException ex) {
342                                 Assert.AreEqual (typeof (FormatException), ex.GetType (), "#2:" + i);
343                                 Assert.IsNull (ex.InnerException, "#3:" + i);
344                                 Assert.IsNotNull (ex.Message, "#4:" + i);
345                         }
346                 }
347         }
348
349         [Test]
350         public void Parse_IpString_Null ()
351         {
352                 try {
353                         IPAddress.Parse ((string) null);
354                         Assert.Fail ("#1");
355                 } catch (ArgumentNullException ex) {
356                         Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
357                         Assert.IsNull (ex.InnerException, "#3");
358                         Assert.IsNotNull (ex.Message, "#4");
359                         Assert.AreEqual ("ipString", ex.ParamName, "#5");
360                 }
361         }
362
363         [Test]
364         public void NetworkHost ()
365         {
366                 long [] tested = new long [] { 0, 1, 1, 1};
367                 long [] expectedLE = new long [] {0, 256, 16777216, 72057594037927936 };
368                 long [] expected;
369                 
370                 expected = BitConverter.IsLittleEndian ? expectedLE : tested;
371
372                 short short0 = IPAddress.NetworkToHostOrder ((short) tested [0]);
373                 Assert.AreEqual ((short) expected [0], short0, "#A1");
374                 short0 = IPAddress.HostToNetworkOrder (short0);
375                 Assert.AreEqual ((short) tested [0], short0, "#A2");
376
377                 int int0 = IPAddress.NetworkToHostOrder ((int) tested [0]);
378                 Assert.AreEqual ((int) expected [0], int0, "#B1");
379                 int0 = IPAddress.HostToNetworkOrder (int0);
380                 Assert.AreEqual ((int) tested [0], int0, "#B2");
381                 
382                 long long0 = IPAddress.NetworkToHostOrder (tested [0]);
383                 Assert.AreEqual (expected [0], long0, "#C1");
384                 long0 = IPAddress.HostToNetworkOrder (long0);
385                 Assert.AreEqual (tested [0], long0, "#C2");
386
387                 short0 = IPAddress.NetworkToHostOrder ((short) tested [1]);
388                 Assert.AreEqual ((short) expected [1], short0, "#D1");
389                 short0 = IPAddress.HostToNetworkOrder (short0);
390                 Assert.AreEqual ((short) tested [1], short0, "#D2");
391                 
392                 int0 = IPAddress.NetworkToHostOrder ((int) tested [2]);
393                 Assert.AreEqual ((int) expected [2], int0, "#E1");
394                 int0 = IPAddress.HostToNetworkOrder (int0);
395                 Assert.AreEqual ((int) tested [2], int0, "#E2");
396                 
397                 long0 = IPAddress.NetworkToHostOrder (tested [3]);
398                 Assert.AreEqual (expected [3], long0, "#F1");
399                 long0 = IPAddress.HostToNetworkOrder (long0);
400                 Assert.AreEqual (tested [3], long0, "#F2");
401         }
402
403         [Test]
404         public void LoopbackIPv6 ()
405         {
406                 Assert.IsTrue (new Uri("http://[0:0:0:0::127.0.0.1]/").IsLoopback, "#1");
407                 Assert.IsFalse (new Uri ("http://[0:0:0:0::127.1.2.3]/").IsLoopback, "#2");
408                 Assert.IsTrue (new Uri ("http://[0:0:0:0::0.0.0.1]/").IsLoopback, "#3");
409         }
410
411         [Test] // bug #76792
412         public void Constructor0_Address_4Byte ()
413         {
414                 byte[] bytes = new byte[4] { 192, 202, 112, 37 };
415                 IPAddress i = new IPAddress (bytes);
416                 Assert.AreEqual (bytes, i.GetAddressBytes (), "#1");
417                 Assert.AreEqual ("192.202.112.37", i.ToString (), "#2");
418         }
419
420         [Test]
421         public void Constructor0_Address_Invalid ()
422         {
423                 try {
424                         new IPAddress (new byte [0]);
425                         Assert.Fail ("#A1");
426                 } catch (ArgumentException ex) {
427                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
428                         Assert.IsNull (ex.InnerException, "#A3");
429                         Assert.IsNotNull (ex.Message, "#A4");
430                         Assert.IsFalse (ex.Message == "address", ex.Message, "#A5");
431                         Assert.IsNotNull (ex.ParamName, "#A6");
432                         Assert.AreEqual ("address", ex.ParamName, "#A7");
433                 }
434
435                 try {
436                         new IPAddress (new byte [3] { 192, 202, 112 });
437                         Assert.Fail ("#B1");
438                 } catch (ArgumentException ex) {
439                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
440                         Assert.IsNull (ex.InnerException, "#B3");
441                         Assert.IsNotNull (ex.Message, "#B4");
442                         Assert.IsFalse (ex.Message == "address", ex.Message, "#B5");
443                         Assert.IsNotNull (ex.ParamName, "#B6");
444                         Assert.AreEqual ("address", ex.ParamName, "#B7");
445                 }
446
447                 try {
448                         new IPAddress (new byte [5] { 192, 202, 112, 142, 25 });
449                         Assert.Fail ("#C1");
450                 } catch (ArgumentException ex) {
451                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
452                         Assert.IsNull (ex.InnerException, "#C3");
453                         Assert.IsNotNull (ex.Message, "#C4");
454                         Assert.IsFalse (ex.Message == "address", "#C5");
455                         Assert.IsNotNull (ex.ParamName, "#C6");
456                         Assert.AreEqual ("address", ex.ParamName, "#C7");
457                 }
458         }
459
460         [Test]
461         public void Constructor0_Address_Null ()
462         {
463                 try {
464                         new IPAddress ((byte []) null);
465                         Assert.Fail ("#1");
466                 } catch (ArgumentNullException ex) {
467                         Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
468                         Assert.IsNull (ex.InnerException, "#3");
469                         Assert.IsNotNull (ex.Message, "#4");
470                         Assert.AreEqual ("address", ex.ParamName, "#5");
471                 }
472         }
473
474         [Test]
475         public void Constructor1_Address_4Byte ()
476         {
477                 byte [] bytes = new byte [4] { 192, 202, 112, 37 };
478                 try {
479                         new IPAddress (bytes, 0);
480                         Assert.Fail ("#1");
481                 } catch (ArgumentException ex) {
482                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
483                         Assert.IsNull (ex.InnerException, "#3");
484                         Assert.IsNotNull (ex.Message, "#4");
485                         Assert.IsFalse (ex.Message == "address", "#5");
486                         Assert.IsNotNull (ex.ParamName, "#6");
487                         Assert.AreEqual ("address", ex.ParamName, "#7");
488                 }
489         }
490
491         [Test]
492         public void Constructor1_Address_Null ()
493         {
494                 try {
495                         new IPAddress ((byte []) null, 5);
496                         Assert.Fail ("#1");
497                 } catch (ArgumentNullException ex) {
498                         Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
499                         Assert.IsNull (ex.InnerException, "#3");
500                         Assert.IsNotNull (ex.Message, "#4");
501                         Assert.AreEqual ("address", ex.ParamName, "#5");
502                 }
503         }
504
505         [Test]
506         public void FromBytes1 ()
507         {
508                 byte[] val1 = new byte[4];
509                 val1[0] = 82;
510                 val1[1] = 165;
511                 val1[2] = 240;
512                 val1[3] = 134;
513                 CompareIPs (val1, "82.165.240.134");
514
515                 byte[] val2 = new byte[4];
516                 val2[0] = 123;
517                 val2[1] = 124;
518                 val2[2] = 125;
519                 val2[3] = 126;
520                 CompareIPs (val2, "123.124.125.126");
521         }
522
523         void CompareIPs (byte [] bytes, string address)
524         {
525                 IPAddress ip = new IPAddress (bytes);
526                 IPAddress ip2 = IPAddress.Parse (address);
527                 Assert.IsTrue (ip2.Equals (ip), "#A-" + address);
528                 Assert.IsTrue (ip.Equals (ip2), "#B-" + address);
529         }
530
531         [Test]
532         public void TryParse_IpString_Null ()
533         {
534                 IPAddress i;
535                 
536                 bool val1 = IPAddress.TryParse ((string) null, out i);
537                 
538                 Assert.IsFalse (val1, "#1");
539                 Assert.IsNull (i, "#2");
540         }
541
542         [Test]
543         public void TryParse ()
544         {
545                 IPAddress i;
546                 Assert.IsTrue (IPAddress.TryParse ("0.0.0.0", out i), "#1");
547                 Assert.IsTrue (IPAddress.TryParse ("127.0.0.1", out i), "#2");
548                 Assert.IsFalse (IPAddress.TryParse ("www.mono-project.com", out i), "#3");
549                 Assert.IsTrue (IPAddress.TryParse ("0001:0002:0003:0004:0005:0006:0007:0008", out i), "#4");
550                 Assert.IsTrue (IPAddress.TryParse ("1:2:3:4:5:6:7:8", out i), "#5");
551                 Assert.IsTrue (IPAddress.TryParse ("1::8", out i), "#6");
552                 Assert.IsTrue (IPAddress.TryParse ("1::3:4:5:6:7:8", out i), "#7");
553                 Assert.IsFalse (IPAddress.TryParse ("1::2:3:4:5::6:7:8", out i), "#8"); // :: ::
554                 Assert.IsFalse (IPAddress.TryParse ("1::2:3:4:5:6:7:8", out i), "#9");
555                 Assert.IsFalse (IPAddress.TryParse ("1;2:3:4:5:6:7:8", out i), "#10"); // ;
556                 // FIXME:
557                 // Assert.IsFalse (IPAddress.TryParse ("1:2:3:4:5:6:7:8/10", out i), "#11"); // subnet
558         }
559
560         [Test]
561         public void TryParseOkV4 ()
562         {
563                 for (int i = 0; i < ipv4ParseOk.Length / 2; i++) {
564                         IPAddress ip;
565                         Assert.IsTrue (IPAddress.TryParse (ipv4ParseOk [i * 2], out ip), "#1:" + i);
566                         Assert.AreEqual (ipv4ParseOk [i * 2 + 1], ip.ToString (), "#2:" + i);
567                 }
568         }
569
570         [Test]
571         public void TryParseWrongV4 ()
572         {
573                 for (int i = 0; i < ipv4ParseWrong.Length; i++) {
574                         IPAddress ip;
575                         string ipAddress = ipv4ParseWrong [i];
576
577                         Assert.IsFalse (IPAddress.TryParse (ipAddress, out ip), "#1:" + i);
578                         Assert.IsNull (ip, "#2:" + i);
579                 }
580         }
581
582         [Test]
583         public void IsIPv6LinkLocal ()
584         {
585                 Assert.IsTrue (IPAddress.Parse ("FE80::1").IsIPv6LinkLocal, "#1");
586                 Assert.IsTrue (IPAddress.Parse ("FE81::1").IsIPv6LinkLocal, "#2");
587                 Assert.IsFalse (IPAddress.Parse ("FD81::1").IsIPv6LinkLocal, "#3");
588                 Assert.IsFalse (IPAddress.Parse ("FF80::1").IsIPv6LinkLocal, "#4");
589                 Assert.IsTrue (IPAddress.Parse ("FE91::1").IsIPv6LinkLocal, "#5");
590                 Assert.IsTrue (IPAddress.Parse ("FEA0::1").IsIPv6LinkLocal, "#6");
591                 Assert.IsFalse (IPAddress.Parse ("FEC0::1").IsIPv6LinkLocal, "#7");
592         }
593
594         [Test]
595         public void IsIPv6SiteLocal ()
596         {
597                 Assert.IsTrue (IPAddress.Parse ("FEC0::1").IsIPv6SiteLocal, "#1");
598                 Assert.IsTrue (IPAddress.Parse ("FEC1::1").IsIPv6SiteLocal, "#2");
599                 Assert.IsFalse (IPAddress.Parse ("FE81::1").IsIPv6SiteLocal, "#3");
600                 Assert.IsFalse (IPAddress.Parse ("FFC0::1").IsIPv6SiteLocal, "#4");
601                 Assert.IsTrue (IPAddress.Parse ("FED1::1").IsIPv6SiteLocal, "#5");
602                 Assert.IsTrue (IPAddress.Parse ("FEE1::1").IsIPv6SiteLocal, "#6");
603         }
604
605         [Test]
606         public void IsIPv6Multicast ()
607         {
608                 Assert.IsTrue (IPAddress.Parse ("FF00::1").IsIPv6Multicast, "#1");
609                 Assert.IsTrue (IPAddress.Parse ("FF01::1").IsIPv6Multicast, "#2");
610                 Assert.IsFalse (IPAddress.Parse ("FE00::1").IsIPv6Multicast, "#3");
611         }
612
613         [Test]
614         public void IsIPv6Teredo ()
615         {
616                 Assert.IsTrue (IPAddress.Parse ("2001::1").IsIPv6Teredo, "#1");
617                 Assert.IsFalse (IPAddress.Parse ("2002::1").IsIPv6Teredo, "#2");
618         }
619
620         [Test]
621         public void ParseWrongV6 ()
622         {
623                 if (!Socket.SupportsIPv6)
624                         Assert.Ignore ("IPv6 must be enabled in machine.config");
625
626                 for (int i = 0; i < ipv6ParseWrong.Length; i++) {
627                         string ipAddress = ipv6ParseWrong [i];
628
629                         try {
630                                 IPAddress ip = IPAddress.Parse (ipAddress);
631                                 Assert.Fail ("#1:" + i + " (" + ipAddress + ")");
632                         } catch (FormatException ex) {
633                                 Assert.AreEqual (typeof (FormatException), ex.GetType (), "#2:" + i);
634                                 Assert.IsNull (ex.InnerException, "#3:" + i);
635                                 Assert.IsNotNull (ex.Message, "#4:" + i);
636                         }
637                 }
638         }
639
640 #if NET_4_5
641
642         [Test]
643         public void MapToIPv6 ()
644         {
645                 for (int i = 0; i < ipv4ParseOk.Length / 2; i++) {
646                         IPAddress v4 = IPAddress.Parse (ipv4ParseOk [i * 2]);
647                         byte [] v4bytes = v4.GetAddressBytes ();
648                         IPAddress v6 = v4.MapToIPv6 ();
649                         byte [] v6bytes = v6.GetAddressBytes ();
650                         IPAddress v4back = v6.MapToIPv4 ();
651
652                         Assert.IsTrue (StartsWith (v6bytes, ipv4MappedIPv6Prefix), "MapToIPv6 #" + i + ".1");
653                         Assert.IsTrue (v6bytes [12] == v4bytes [0], "MapToIPv6 #" + i + ".2");
654                         Assert.IsTrue (v6bytes [13] == v4bytes [1], "MapToIPv6 #" + i + ".3");
655                         Assert.IsTrue (v6bytes [14] == v4bytes [2], "MapToIPv6 #" + i + ".4");
656                         Assert.IsTrue (v6bytes [15] == v4bytes [3], "MapToIPv6 #" + i + ".5");
657                         Assert.IsTrue (v4.Equals (v4back), "MapToIPv4 #" + i);
658                 }
659
660                 //TODO: Test using MapToIPv4/6 with anything other than IPv4/6 addresses.
661                 //Currently it is not possible to do with the IPAddress implementation.
662         }
663
664         static bool StartsWith (byte [] a, byte [] b)
665         {
666                 if (a.Length < b.Length)
667                         return false;
668                 for (int i = 0; i < b.Length; i++)
669                 {
670                         if (a [i] != b [i])
671                                 return false;
672                 }
673                 return true;
674         }
675
676 #endif
677
678         [Test]
679         public void EqualsFromBytes ()
680         {
681                 for (int i = 0; i < ipv4ParseOk.Length / 2; i++) {
682                         IPAddress ip = IPAddress.Parse (ipv4ParseOk [i * 2]);
683                         IPAddress ipFromBytes = new IPAddress (ip.GetAddressBytes ());
684                         Assert.IsTrue (ip.Equals (ipFromBytes), "EqualsFromBytes #" + i);
685                 }
686
687         }
688
689 }
690 }
691