From 4ba359c86fd25c3ffba44db8d931ffe7ead7549a Mon Sep 17 00:00:00 2001 From: basil00 Date: Wed, 13 Jun 2018 17:35:59 +0800 Subject: [PATCH] Add workaround for #134 For some reason pseudo checksums do not work on some systems. The workaround is to modify WinDivertSend() so that it calculates the full checksums before forwarding the packet to the driver. --- CHANGELOG | 2 ++ VERSION | 2 +- dll/windivert.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index e16ac37..de407cf 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -123,3 +123,5 @@ WinDivert 1.4.0-rc for unmodified packets. WinDivert 1.4.1 - Dual license WinDivert under LGPLv3 and GPLv2. +WinDivert 1.4.2 + - Add workaround for pseudo checksum issue (see #134). diff --git a/VERSION b/VERSION index 347f583..9df886c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.4.1 +1.4.2 diff --git a/dll/windivert.c b/dll/windivert.c index 88c275e..cfcd346 100644 --- a/dll/windivert.c +++ b/dll/windivert.c @@ -514,6 +514,41 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer, return handle; } +/* + * Workaround for #134 + */ +static void WinDivertFixChecksums(PVOID pPacket, UINT packetLen, + PWINDIVERT_ADDRESS addr) +{ + UINT64 flags = + WINDIVERT_HELPER_NO_IP_CHECKSUM | + WINDIVERT_HELPER_NO_TCP_CHECKSUM | + WINDIVERT_HELPER_NO_UDP_CHECKSUM; + BOOL calc = FALSE; + if (addr->PseudoIPChecksum != 0) + { + addr->PseudoIPChecksum = 0; + flags &= ~WINDIVERT_HELPER_NO_IP_CHECKSUM; + calc = TRUE; + } + if (addr->PseudoTCPChecksum != 0) + { + addr->PseudoTCPChecksum = 0; + flags &= ~WINDIVERT_HELPER_NO_TCP_CHECKSUM; + calc = TRUE; + } + if (addr->PseudoUDPChecksum != 0) + { + addr->PseudoUDPChecksum = 0; + flags &= ~WINDIVERT_HELPER_NO_UDP_CHECKSUM; + calc = TRUE; + } + if (calc) + { + WinDivertHelperCalcChecksums(pPacket, packetLen, addr, flags); + } +} + /* * Receive a WinDivert packet. */ @@ -554,6 +589,12 @@ extern BOOL WinDivertRecvEx(HANDLE handle, PVOID pPacket, UINT packetLen, extern BOOL WinDivertSend(HANDLE handle, PVOID pPacket, UINT packetLen, PWINDIVERT_ADDRESS addr, UINT *writelen) { + if (addr == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + WinDivertFixChecksums(pPacket, packetLen, addr); return WinDivertIoControl(handle, IOCTL_WINDIVERT_SEND, 0, (UINT64)addr, pPacket, packetLen, writelen); } @@ -565,11 +606,12 @@ extern BOOL WinDivertSendEx(HANDLE handle, PVOID pPacket, UINT packetLen, UINT64 flags, PWINDIVERT_ADDRESS addr, UINT *writelen, LPOVERLAPPED overlapped) { - if (flags != 0) + if (flags != 0 || addr == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } + WinDivertFixChecksums(pPacket, packetLen, addr); if (overlapped == NULL) { return WinDivertIoControl(handle, IOCTL_WINDIVERT_SEND, 0,