Index: lib/rtl/network.c =================================================================== --- lib/rtl/network.c (revision 67125) +++ lib/rtl/network.c (working copy) @@ -28,6 +28,18 @@ /* network to host order conversion for little endian machines */ #define WN2H(w) (((w & 0xFF00) >> 8) | ((w & 0x00FF) << 8)) +/* in the case of the address ::0:a:b:c:d:e:f windows incorrectly cuts off the f. + define FOLLOW_INCORRECT_FIRSTZERO to 1 to follow this behavior, to 0 to disable this. */ +#if !defined(IPV6_FOLLOW_INCORRECT_FIRSTZERO) +#define IPV6_FOLLOW_INCORRECT_FIRSTZERO 1 +#endif + +/* windows does accept a group of the form 0xffff as the last group in an ipv6 address.. + the terminator points to the x in this case. */ +#if !defined(IPV6_ACCEPT_HEXNOTATION_LAST_DIGIT) +#define IPV6_ACCEPT_HEXNOTATION_LAST_DIGIT 1 +#endif + /* PRIVATE FUNCTIONS **********************************************************/ /* decode a string with given Base (8, 10 or 16) */ @@ -813,7 +825,9 @@ ULONG Base, Len; NTSTATUS Status = STATUS_SUCCESS; enum { None, Number, Colon, DoubleColon } Last = None; +#if IPV6_ACCEPT_HEXNOTATION_LAST_DIGIT BOOLEAN SkipoutLastHex = FALSE; +#endif if (!String || !Terminator || !Addr) return STATUS_INVALID_PARAMETER; @@ -830,12 +844,14 @@ /* double colon, 1 or more fields set to 0. mark the position, and move on. */ if (StartSkip == -1 && String[1] == ':') { +#if IPV6_FOLLOW_INCORRECT_FIRSTZERO /* this case was observed in windows, but it does not seem correct. */ if (!n) { Addr->s6_words[n++] = 0; Addr->s6_words[n++] = 0; } +#endif /* IPV6_FOLLOW_INCORRECT_FIRSTZERO */ StartSkip = n; String += 2; Last = DoubleColon; @@ -907,6 +923,7 @@ break; } +#if IPV6_ACCEPT_HEXNOTATION_LAST_DIGIT if (Len == 1 && towlower(String[Len]) == 'x' && String[0] == '0') { Len = RtlpClassifyChars(String + 2, &Base); @@ -917,6 +934,7 @@ SkipoutLastHex = TRUE; } } +#endif Status = RtlpStringToUlongBase(String, 16, &String, &Value); if (!NT_SUCCESS(Status)) @@ -926,8 +944,10 @@ Parts++; Addr->s6_words[n++] = WN2H(Value); Last = Number; +#if IPV6_ACCEPT_HEXNOTATION_LAST_DIGIT if (SkipoutLastHex) break; +#endif } } @@ -939,9 +959,11 @@ n = 8; } +#if IPV6_ACCEPT_HEXNOTATION_LAST_DIGIT /* we have already set the terminator */ if (SkipoutLastHex) return n < 8 ? STATUS_INVALID_PARAMETER : Status; +#endif *Terminator = String; return n < 8 ? STATUS_INVALID_PARAMETER : Status; }