if (i == (ips.Length - 1)) {
if (i != 0 && val >= (256 << ((3 - i) * 8)))
return null;
- else if (val > 0x3fffffffe) // this is the last number that parses correctly with MS
+ else if (val > 0xffffffff)
return null;
i = 3;
} else if (val >= 0x100)
return m_Family;
}
}
-
-
+
+#if NET_4_5
+
+ public IPAddress MapToIPv4 ()
+ {
+ if (AddressFamily == AddressFamily.InterNetwork)
+ return this;
+ if (AddressFamily != AddressFamily.InterNetworkV6)
+ throw new Exception ("Only AddressFamily.InterNetworkV6 can be converted to IPv4");
+
+ //Test for 0000 0000 0000 0000 0000 FFFF xxxx xxxx
+ for (int i = 0; i < 5; i++) {
+ if (m_Numbers [i] != 0x0000)
+ throw new Exception ("Address does not have the ::FFFF prefix");
+ }
+ if (m_Numbers [5] != 0xFFFF)
+ throw new Exception ("Address does not have the ::FFFF prefix");
+
+ //We've got an IPv4 address
+ byte [] ipv4Bytes = new byte [4];
+ Buffer.BlockCopy (m_Numbers, 12, ipv4Bytes, 0, 4);
+ return new IPAddress (ipv4Bytes);
+ }
+
+ public IPAddress MapToIPv6 ()
+ {
+ if (AddressFamily == AddressFamily.InterNetworkV6)
+ return this;
+ if (AddressFamily != AddressFamily.InterNetwork)
+ throw new Exception ("Only AddressFamily.InterNetworkV4 can be converted to IPv6");
+
+ byte [] ipv4Bytes = GetAddressBytes ();
+ byte [] ipv6Bytes = new byte [16] {
+ 0,0, 0,0, 0,0, 0,0, 0,0, 0xFF,0xFF,
+ ipv4Bytes [0], ipv4Bytes [1], ipv4Bytes [2], ipv4Bytes [3]
+ };
+ return new IPAddress (ipv6Bytes);
+ }
+
+#endif
+
/// <summary>
/// Used to tell whether an address is a loopback.
/// All IP addresses of the form 127.X.Y.Z, where X, Y, and Z are in
"20.65535", "20.0.255.255",
"0313.027035210", "203.92.58.136", // bug #411920
"0313.0134.035210", "203.92.58.136", // too
- "7848198702", "211.202.2.46", // too
"1434328179", "85.126.28.115", // too
"3397943208", "202.136.127.168", // too
};
"12.",
"12.1.2.",
"12...",
- " "
+ " ",
+ "7848198702",
};
+ static byte [] ipv4MappedIPv6Prefix = new byte [] { 0,0, 0,0, 0,0, 0,0, 0,0, 0xFF,0xFF };
+
[Test]
public void PublicFields ()
{
}
}
}
+
+#if NET_4_5
+
+ [Test]
+ public void MapToIPv6 ()
+ {
+ for (int i = 0; i < ipv4ParseOk.Length / 2; i++) {
+ IPAddress v4 = IPAddress.Parse (ipv4ParseOk [i * 2]);
+ byte [] v4bytes = v4.GetAddressBytes ();
+ IPAddress v6 = v4.MapToIPv6 ();
+ byte [] v6bytes = v6.GetAddressBytes ();
+ IPAddress v4back = v6.MapToIPv4 ();
+
+ Assert.IsTrue (StartsWith (v6bytes, ipv4MappedIPv6Prefix), "MapToIPv6 #" + i + ".1");
+ Assert.IsTrue (v6bytes [12] == v4bytes [0], "MapToIPv6 #" + i + ".2");
+ Assert.IsTrue (v6bytes [13] == v4bytes [1], "MapToIPv6 #" + i + ".3");
+ Assert.IsTrue (v6bytes [14] == v4bytes [2], "MapToIPv6 #" + i + ".4");
+ Assert.IsTrue (v6bytes [15] == v4bytes [3], "MapToIPv6 #" + i + ".5");
+ Assert.IsTrue (v4.Equals (v4back), "MapToIPv4 #" + i);
+ }
+
+ //TODO: Test using MapToIPv4/6 with anything other than IPv4/6 addresses.
+ //Currently it is not possible to do with the IPAddress implementation.
+ }
+
+ static bool StartsWith (byte [] a, byte [] b)
+ {
+ if (a.Length < b.Length)
+ return false;
+ for (int i = 0; i < b.Length; i++)
+ {
+ if (a [i] != b [i])
+ return false;
+ }
+ return true;
+ }
+
+#endif
+
+ [Test]
+ public void EqualsFromBytes ()
+ {
+ for (int i = 0; i < ipv4ParseOk.Length / 2; i++) {
+ IPAddress ip = IPAddress.Parse (ipv4ParseOk [i * 2]);
+ IPAddress ipFromBytes = new IPAddress (ip.GetAddressBytes ());
+ Assert.IsTrue (ip.Equals (ipFromBytes), "EqualsFromBytes #" + i);
+ }
+
+ }
+
}
}