Add support for pseudo IP/TCP/UDP checksums.

Most NIC cards support checksum offloading,
meaning that it is not necessary to calculate the
full IP/TCP/UDP checksums for injected packets.
WINDIVERT_ADDRESS has been extended to include 3
extra flags that indicate if the packet has full
or pseudo checksums.  This is a WIP.
This commit is contained in:
basil00
2017-11-09 22:11:13 +08:00
parent bbf6a34aa6
commit aea3a3a858
8 changed files with 194 additions and 252 deletions
-4
View File
@@ -124,10 +124,6 @@ int __cdecl main(int argc, char **argv)
continue;
}
// Calculate checksums.
WinDivertHelperCalcChecksums(packet, packet_len,
WINDIVERT_HELPER_NO_REPLACE);
// Print info about the matching packet.
WinDivertHelperParsePacket(packet, packet_len, &ip_header,
&ipv6_header, &icmp_header, &icmpv6_header, &tcp_header,
+9 -11
View File
@@ -1,6 +1,6 @@
/*
* netfilter.c
* (C) 2016, all rights reserved,
* (C) 2017, all rights reserved,
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -270,11 +270,10 @@ int __cdecl main(int argc, char **argv)
htonl(ntohl(tcp_header->SeqNum) + 1):
htonl(ntohl(tcp_header->SeqNum) + payload_len));
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(TCPPACKET),
0);
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
send_addr.Direction = !recv_addr.Direction;
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(TCPPACKET),
&send_addr, 0);
if (!WinDivertSend(handle, (PVOID)reset, sizeof(TCPPACKET),
&send_addr, NULL))
{
@@ -298,11 +297,10 @@ int __cdecl main(int argc, char **argv)
htonl(ntohl(tcp_header->SeqNum) + 1):
htonl(ntohl(tcp_header->SeqNum) + payload_len));
WinDivertHelperCalcChecksums((PVOID)resetv6,
sizeof(TCPV6PACKET), 0);
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
send_addr.Direction = !recv_addr.Direction;
WinDivertHelperCalcChecksums((PVOID)resetv6,
sizeof(TCPV6PACKET), &send_addr, 0);
if (!WinDivertSend(handle, (PVOID)resetv6, sizeof(TCPV6PACKET),
&send_addr, NULL))
{
@@ -325,10 +323,10 @@ int __cdecl main(int argc, char **argv)
dnr->ip.SrcAddr = ip_header->DstAddr;
dnr->ip.DstAddr = ip_header->SrcAddr;
WinDivertHelperCalcChecksums((PVOID)dnr, icmp_length, 0);
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
send_addr.Direction = !recv_addr.Direction;
WinDivertHelperCalcChecksums((PVOID)dnr, icmp_length,
&send_addr, 0);
if (!WinDivertSend(handle, (PVOID)dnr, icmp_length, &send_addr,
NULL))
{
@@ -348,10 +346,10 @@ int __cdecl main(int argc, char **argv)
memcpy(dnrv6->ipv6.DstAddr, ipv6_header->SrcAddr,
sizeof(dnrv6->ipv6.DstAddr));
WinDivertHelperCalcChecksums((PVOID)dnrv6, icmpv6_length, 0);
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
send_addr.Direction = !recv_addr.Direction;
WinDivertHelperCalcChecksums((PVOID)dnrv6, icmpv6_length,
&send_addr, 0);
if (!WinDivertSend(handle, (PVOID)dnrv6, icmpv6_length,
&send_addr, NULL))
{
+1 -5
View File
@@ -1,6 +1,6 @@
/*
* passthru.c
* (C) 2016, all rights reserved,
* (C) 2017, all rights reserved,
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -108,10 +108,6 @@ static DWORD passthru(LPVOID arg)
}
// Re-inject the matching packet.
// NOTE: Only use the WINDIVERT_HELPER_NO_REPLACE flag if the packet
// was not modified.
WinDivertHelperCalcChecksums(packet, packet_len,
WINDIVERT_HELPER_NO_REPLACE);
if (!WinDivertSend(handle, packet, packet_len, &addr, NULL))
{
fprintf(stderr, "warning: failed to reinject packet (%d)\n",
+2 -2
View File
@@ -1,6 +1,6 @@
/*
* streamdump.c
* (C) 2016 basil, all rights reserved,
* (C) 2017 basil, all rights reserved,
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -278,7 +278,7 @@ read_failed:
break;
}
WinDivertHelperCalcChecksums(packet, packet_len, 0);
WinDivertHelperCalcChecksums(packet, packet_len, &addr, 0);
poverlapped = (OVERLAPPED *)malloc(sizeof(OVERLAPPED));
if (poverlapped == NULL)
{
+3 -5
View File
@@ -189,8 +189,6 @@ int __cdecl main(int argc, char **argv)
!BlackListPayloadMatch(blacklist, payload, (UINT16)payload_len))
{
// Packet does not match the blacklist; simply reinject it.
WinDivertHelperCalcChecksums(packet, packet_len,
WINDIVERT_HELPER_NO_REPLACE);
if (!WinDivertSend(handle, packet, packet_len, &addr, NULL))
{
fprintf(stderr, "warning: failed to reinject packet (%d)\n",
@@ -210,7 +208,7 @@ int __cdecl main(int argc, char **argv)
reset->tcp.DstPort = htons(80);
reset->tcp.SeqNum = tcp_header->SeqNum;
reset->tcp.AckNum = tcp_header->AckNum;
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(PACKET), 0);
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(PACKET), &addr, 0);
if (!WinDivertSend(handle, (PVOID)reset, sizeof(PACKET), &addr, NULL))
{
fprintf(stderr, "warning: failed to send reset packet (%d)\n",
@@ -224,8 +222,8 @@ int __cdecl main(int argc, char **argv)
blockpage->header.tcp.SeqNum = tcp_header->AckNum;
blockpage->header.tcp.AckNum =
htonl(ntohl(tcp_header->SeqNum) + payload_len);
WinDivertHelperCalcChecksums((PVOID)blockpage, blockpage_len, 0);
addr.Direction = !addr.Direction; // Reverse direction.
WinDivertHelperCalcChecksums((PVOID)blockpage, blockpage_len, &addr, 0);
if (!WinDivertSend(handle, (PVOID)blockpage, blockpage_len, &addr,
NULL))
{
@@ -243,7 +241,7 @@ int __cdecl main(int argc, char **argv)
htonl(ntohl(tcp_header->AckNum) + sizeof(block_data) - 1);
finish->tcp.AckNum =
htonl(ntohl(tcp_header->SeqNum) + payload_len);
WinDivertHelperCalcChecksums((PVOID)finish, sizeof(PACKET), 0);
WinDivertHelperCalcChecksums((PVOID)finish, sizeof(PACKET), &addr, 0);
if (!WinDivertSend(handle, (PVOID)finish, sizeof(PACKET), &addr, NULL))
{
fprintf(stderr, "warning: failed to send finish packet (%d)\n",