From dbb6b0fe60e7ba224d17d11de351a0b0e3df149a Mon Sep 17 00:00:00 2001 From: basil00 Date: Tue, 14 Nov 2017 20:20:18 +0800 Subject: [PATCH] Invert the checksum flags. Zeroing the addr will default to full checksums. --- dll/windivert_helper.c | 6 +++--- include/windivert.h | 6 +++--- sys/windivert.c | 30 +++++++++++++++++++++--------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/dll/windivert_helper.c b/dll/windivert_helper.c index 0cff931..a8c6703 100644 --- a/dll/windivert_helper.c +++ b/dll/windivert_helper.c @@ -435,7 +435,7 @@ extern UINT WinDivertHelperCalcChecksums(PVOID pPacket, UINT packetLen, if (ip_header != NULL && !(flags & WINDIVERT_HELPER_NO_IP_CHECKSUM)) { ip_header->Checksum = 0; - if (pAddr == NULL || pAddr->IPv4Checksum != 0) + if (pAddr == NULL || pAddr->PseudoIPChecksum == 0) { ip_header->Checksum = WinDivertHelperCalcChecksum(NULL, 0, ip_header, ip_header->HdrLength*sizeof(UINT32)); @@ -478,7 +478,7 @@ extern UINT WinDivertHelperCalcChecksums(PVOID pPacket, UINT packetLen, { return count; } - if (pAddr == NULL || pAddr->TCPChecksum != 0) + if (pAddr == NULL || pAddr->PseudoTCPChecksum == 0) { // Full TCP checksum checksum_len = payload_len + tcp_header->HdrLength*sizeof(UINT32); @@ -512,7 +512,7 @@ extern UINT WinDivertHelperCalcChecksums(PVOID pPacket, UINT packetLen, { return count; } - if (pAddr == NULL || pAddr->UDPChecksum != 0) + if (pAddr == NULL || pAddr->PseudoUDPChecksum == 0) { // Full UDP checksum checksum_len = payload_len + sizeof(WINDIVERT_UDPHDR); diff --git a/include/windivert.h b/include/windivert.h index 8bd80cd..4b4ed5e 100644 --- a/include/windivert.h +++ b/include/windivert.h @@ -63,9 +63,9 @@ typedef struct UINT8 Direction:1; /* Packet's direction. */ UINT8 Loopback:1; /* Packet is loopback? */ UINT8 Impostor:1; /* Packet is impostor? */ - UINT8 IPv4Checksum:1; /* Packet has full IPv4 checksum? */ - UINT8 TCPChecksum:1; /* Packet has full TCP checksum? */ - UINT8 UDPChecksum:1; /* Packet has full UDP checksum? */ + UINT8 PseudoIPChecksum:1; /* Packet has pseudo IPv4 checksum? */ + UINT8 PseudoTCPChecksum:1; /* Packet has pseudo TCP checksum? */ + UINT8 PseudoUDPChecksum:1; /* Packet has pseudo UDP checksum? */ UINT8 Reserved:2; } WINDIVERT_ADDRESS, *PWINDIVERT_ADDRESS; diff --git a/sys/windivert.c b/sys/windivert.c index 553df73..8e8e007 100644 --- a/sys/windivert.c +++ b/sys/windivert.c @@ -1554,9 +1554,12 @@ static void windivert_read_service_request(packet_t packet, addr->Direction = direction; addr->Loopback = (loopback? 1: 0); addr->Impostor = (impostor? 1: 0); - addr->IPv4Checksum = ((checksums & WINDIVERT_IP_CHECKSUM) != 0? 1: 0); - addr->TCPChecksum = ((checksums & WINDIVERT_TCP_CHECKSUM) != 0? 1: 0); - addr->UDPChecksum = ((checksums & WINDIVERT_UDP_CHECKSUM) != 0? 1: 0); + addr->PseudoIPChecksum = + ((checksums & WINDIVERT_IP_CHECKSUM) == 0? 1: 0); + addr->PseudoTCPChecksum = + ((checksums & WINDIVERT_TCP_CHECKSUM) == 0? 1: 0); + addr->PseudoUDPChecksum = + ((checksums & WINDIVERT_UDP_CHECKSUM) == 0? 1: 0); addr->Reserved = 0; } @@ -1763,24 +1766,33 @@ windivert_write_bad_packet: if (addr->Direction == WINDIVERT_DIRECTION_OUTBOUND) { checksums_info.Transmit.TcpChecksum = - (addr->TCPChecksum != 0? 0: 1); + (addr->PseudoTCPChecksum == 0? 0: 1); checksums_info.Transmit.UdpChecksum = - (addr->UDPChecksum != 0? 0: 1); + (addr->PseudoUDPChecksum == 0? 0: 1); checksums_info.Transmit.IpHeaderChecksum = - (addr->IPv4Checksum != 0? 0: 1); + (addr->PseudoIPChecksum == 0? 0: 1); } else { checksums_info.Receive.TcpChecksumSucceeded = - (addr->TCPChecksum != 0? 0: 1); + (addr->PseudoTCPChecksum == 0? 0: 1); checksums_info.Receive.UdpChecksumSucceeded = - (addr->UDPChecksum != 0? 0: 1); + (addr->PseudoUDPChecksum == 0? 0: 1); checksums_info.Receive.IpChecksumSucceeded = - (addr->IPv4Checksum != 0? 0: 1); + (addr->PseudoIPChecksum == 0? 0: 1); } NET_BUFFER_LIST_INFO(buffers, TcpIpChecksumNetBufferListInfo) = checksums_info.Value; } + else + { + if (addr->PseudoTCPChecksum != 0 || addr->PseudoUDPChecksum != 0 || + addr->PseudoIPChecksum != 0) + { + status = STATUS_INVALID_PARAMETER; + goto windivert_write_exit; + } + } if (addr->Impostor) {