static int Fill (ushort [] addr, string ipString)\r
{\r
int p = 0;\r
+ int pdigits = 0;\r
int slot = 0;\r
\r
if (ipString.Length == 0)\r
return 0;\r
\r
// Catch double uses of ::\r
- if (ipString.IndexOf ("::") != -1)\r
+ if (ipString.IndexOf ("::", StringComparison.Ordinal) != -1)\r
return -1;\r
\r
for (int i = 0; i < ipString.Length; i++){\r
int n;\r
\r
if (c == ':'){\r
+ // Leading : is not allowed.\r
+ if (i == 0)\r
+ return -1;\r
+ \r
// Trailing : is not allowed.\r
if (i == ipString.Length-1)\r
return -1;\r
\r
addr [slot++] = (ushort) p;\r
p = 0;\r
+ pdigits = 0;\r
continue;\r
- } if ('0' <= c && c <= '9')\r
+ }\r
+ pdigits++;\r
+ if (pdigits > 4)\r
+ return -1;\r
+ if ('0' <= c && c <= '9')\r
n = (int) (c - '0');\r
else if ('a' <= c && c <= 'f')\r
n = (int) (c - 'a' + 10);\r
return slot;\r
}\r
\r
- static bool TryParse (string s, out int res)\r
+ static bool TryParse (string prefix, out int res)\r
{\r
-#if NET_2_0\r
- return Int32.TryParse (s, NumberStyles.Integer, CultureInfo.InvariantCulture, out res);\r
-#else\r
- try {\r
- res = Int32.Parse (prefix, NumberStyles.Integer, CultureInfo.InvariantCulture);\r
- } catch (Exception) {\r
- res = -1;\r
- return false;\r
- }\r
-#endif\r
+ return Int32.TryParse (prefix, NumberStyles.Integer, CultureInfo.InvariantCulture, out res);\r
}\r
\r
public static bool TryParse (string ipString, out IPv6Address result)\r
//\r
// Is there an ipv4 address at the end?\r
//\r
- bool ipv4 = false;\r
- int pos2 = ipString.LastIndexOf (":");\r
+ int pos2 = ipString.LastIndexOf (':');\r
if (pos2 == -1)\r
return false;\r
\r
ipString = ipString.Substring (0, pos2 + 1);\r
else\r
ipString = ipString.Substring (0, pos2);\r
- ipv4 = true;\r
slots = 2;\r
}\r
} \r
// Only an ipv6 block remains, either:\r
// "hexnumbers::hexnumbers", "hexnumbers::" or "hexnumbers"\r
//\r
- int c = ipString.IndexOf ("::");\r
+ int c = ipString.IndexOf ("::", StringComparison.Ordinal);\r
if (c != -1){\r
int right_slots = Fill (addr, ipString.Substring (c+2));\r
if (right_slots == -1){\r
return false;\r
}\r
\r
- // Now check the results in the ipv6-address range only\r
- bool ipv6 = false;\r
- for (int i = 0; i < slots; i++){\r
- if (addr [i] != 0 || i == 5 && addr [i] != 0xffff)\r
- ipv6 = true;\r
- }\r
- \r
- // check IPv4 validity\r
- if (ipv4 && !ipv6) {\r
- for (int i = 0; i < 5; i++) {\r
- if (addr [i] != 0)\r
- return false;\r
- }\r
-\r
- if (addr [5] != 0 && addr [5] != 0xffff)\r
- return false;\r
- }\r
-\r
result = new IPv6Address (addr, prefixLen, scopeId);\r
return true;\r
}\r
}\r
\r
// Convert the address into a format expected by the IPAddress (long) ctor\r
- private int AsIPv4Int ()\r
+ // This needs to be unsigned to satisfy the '> 1' test in IsIPv4Compatible()\r
+ private uint AsIPv4Int ()\r
{\r
- return (SwapUShort (address [7]) << 16) + SwapUShort (address [6]);\r
+ return (uint)(SwapUShort (address [7]) << 16) + SwapUShort (address [6]);\r
} \r
\r
public bool IsIPv4Compatible ()\r
for (int i = 0; i < 6; i++) \r
if (address [i] != 0)\r
return false;\r
+ /* MS .net only seems to format the last 4\r
+ * bytes as an IPv4 address if address[6] is\r
+ * non-zero\r
+ */\r
+ if (address[6] == 0)\r
+ return false;\r
return (AsIPv4Int () > 1);\r
}\r
\r
for (int i = 0; i < 5; i++) \r
if (address [i] != 0)\r
return false;\r
+ /* MS .net only seems to format the last 4\r
+ * bytes as an IPv4 address if address[6] is\r
+ * non-zero\r
+ */\r
+ if (address[6] == 0)\r
+ return false;\r
+ \r
return address [5] == 0xffff;\r
}\r
\r