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.
This commit is contained in:
basil00
2018-06-13 17:35:59 +08:00
parent ae25f27469
commit 4ba359c86f
3 changed files with 46 additions and 2 deletions
+2
View File
@@ -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).
+1 -1
View File
@@ -1 +1 @@
1.4.1
1.4.2
+43 -1
View File
@@ -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,