From 48075e2e5ff42d75171b319a89bc56e93e449182 Mon Sep 17 00:00:00 2001 From: basil00 Date: Sat, 15 Nov 2014 15:06:16 +0800 Subject: [PATCH] - Fix broken implementation of WinDivertHelperParseIPv6Address(). - Fix IPv6 address word/byte ordering between DLL and SYS. --- CHANGELOG | 9 ++++++--- dll/windivert.c | 7 ++++--- sys/windivert.c | 24 ++++++++++++------------ 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 79765ac..d54f0f0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -52,6 +52,9 @@ WinDivert 1.1.6 - WinDivert now searches for the driver files in the application's directory (as opposed to the current directory). WinDivert 1.1.7 - - Fixed incorrect IPV6 TCP/UDP checksum calculation in - WinDivertHelperCalcChecksums(). - - Driver now calculates checksums for IPV6 packets. + - Improved IPv6 support: + * Fixed incorrect IPV6 TCP/UDP checksum calculation in + WinDivertHelperCalcChecksums(). + * WinDivert driver now calculates checksums for IPV6 packets. + * WinDivert can now handle IPV6 extension headers. + * Fixed WinDivertHelperParseIPv6Address(). diff --git a/dll/windivert.c b/dll/windivert.c index c647bdc..978566e 100644 --- a/dll/windivert.c +++ b/dll/windivert.c @@ -1891,11 +1891,11 @@ extern BOOL WinDivertHelperParseIPv6Address(const char *str, UINT32 *addr_ptr) WinDivertAToX(part_str, NULL, &part); if (!end) { - addr[i] = (UINT16)ntohs(part); + addr[i] = (UINT16)part; } else { - addr[j--] = (UINT16)ntohs(part); + addr[j--] = (UINT16)part; } if (*str == '\0') { @@ -1933,7 +1933,8 @@ extern BOOL WinDivertHelperParseIPv6Address(const char *str, UINT32 *addr_ptr) { for (i = 0; i < sizeof(addr) / sizeof(UINT32); i++) { - addr_ptr[i] = addr[i]; + addr_ptr[i] = (UINT32)addr[2 * i + 1] | + (UINT32)addr[2 * i]; } } diff --git a/sys/windivert.c b/sys/windivert.c index 1e3b46c..f5f488b 100644 --- a/sys/windivert.c +++ b/sys/windivert.c @@ -3049,23 +3049,23 @@ static BOOL windivert_filter(PNET_BUFFER buffer, UINT32 if_idx, break; case WINDIVERT_FILTER_FIELD_IPV6_SRCADDR: field[0] = - (UINT32)RtlUlongByteSwap(ipv6_header->SrcAddr[3]); - field[1] = - (UINT32)RtlUlongByteSwap(ipv6_header->SrcAddr[2]); - field[2] = - (UINT32)RtlUlongByteSwap(ipv6_header->SrcAddr[1]); - field[3] = (UINT32)RtlUlongByteSwap(ipv6_header->SrcAddr[0]); + field[1] = + (UINT32)RtlUlongByteSwap(ipv6_header->SrcAddr[1]); + field[2] = + (UINT32)RtlUlongByteSwap(ipv6_header->SrcAddr[2]); + field[3] = + (UINT32)RtlUlongByteSwap(ipv6_header->SrcAddr[3]); break; case WINDIVERT_FILTER_FIELD_IPV6_DSTADDR: field[0] = - (UINT32)RtlUlongByteSwap(ipv6_header->DstAddr[3]); - field[1] = - (UINT32)RtlUlongByteSwap(ipv6_header->DstAddr[2]); - field[2] = - (UINT32)RtlUlongByteSwap(ipv6_header->DstAddr[1]); - field[3] = (UINT32)RtlUlongByteSwap(ipv6_header->DstAddr[0]); + field[1] = + (UINT32)RtlUlongByteSwap(ipv6_header->DstAddr[1]); + field[2] = + (UINT32)RtlUlongByteSwap(ipv6_header->DstAddr[2]); + field[3] = + (UINT32)RtlUlongByteSwap(ipv6_header->DstAddr[3]); break; case WINDIVERT_FILTER_FIELD_ICMP_TYPE: field[0] = (UINT32)icmp_header->Type;