5 Commits

Author SHA1 Message Date
basil00 97101072db Fix previous commit 8bda0af
Fix #294

Previous commit was incomplete.
2022-04-10 06:51:38 +08:00
basil00 8bda0aff7b Fix handling of FwpmTransaction*() errors.
Fixes #294
2022-04-09 09:49:45 +08:00
basil00 34b565de65 Merge pull request #296 from StalkR/patch-1
windivert.html: fix 6.11 title: format not parse
2022-02-23 11:24:31 +08:00
StalkR 90396ffa2b windivert.html: fix 6.11 title: format not parse 2022-02-15 19:35:18 +01:00
basil00 8cdddce6ac Send an ICMP(V6) message if the packet is too big
Fix #278

The Miniport driver will reject any outbound
packet that is larger than the MTU.  However the
error flows back to the sending application as
an error code/condition, which is disrupted by
WinDivert, meaning the error is lost.

This change translates the error code into an
ICMP(V6) "packet too big" message, allowing for
the error to flow back to the origin in some
form.

This change required some refactoring.
2021-10-22 07:34:23 +08:00
23 changed files with 1269 additions and 3005 deletions
-6
View File
@@ -312,9 +312,3 @@ WinDivert 2.2.0
- Implement new packet parser that correctly handles IP fragments.
- Add a new "fragment" filter field that matches IP fragments.
- (Un)Loading the WinDivert driver will cause a system event to be logged.
WinDivert 2.2.1
- Fix potential driver deadlock on user-mode program crash.
- Fix filter language simplification bug.
- Fix Flow.EndpointId containing junk data.
WinDivert 2.2.2
- Fix potential WinDivertClose() BSOD for WINDIVERT_LAYER_FLOW handles.
+1 -1
View File
@@ -5,7 +5,7 @@ WinDivert 2.2: Windows Packet Divert
---------------
Windows Packet Divert (WinDivert) is a user-mode packet interception library
for Windows 10, Windows 11, and Windows Server.
for Windows 7, Windows 8 and Windows 10.
WinDivert enables user-mode capturing/modifying/dropping of network packets
sent to/from the Windows network stack. In summary, WinDivert can:
+1 -1
View File
@@ -1 +1 @@
2.2.2
2.2.0
-1
View File
@@ -479,7 +479,6 @@ HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer, INT16 priority,
// Parameter checking:
switch (layer)
{
case WINDIVERT_LAYER_ETHERNET:
case WINDIVERT_LAYER_NETWORK:
case WINDIVERT_LAYER_NETWORK_FORWARD:
case WINDIVERT_LAYER_FLOW:
-4
View File
@@ -13,10 +13,8 @@ EXPORTS
WinDivertHelperDecrementTTL
WinDivertHelperHashPacket
WinDivertHelperParsePacket
WinDivertHelperParseMACAddress
WinDivertHelperParseIPv4Address
WinDivertHelperParseIPv6Address
WinDivertHelperFormatMACAddress
WinDivertHelperFormatIPv4Address
WinDivertHelperFormatIPv6Address
WinDivertHelperCompileFilter
@@ -28,8 +26,6 @@ EXPORTS
WinDivertHelperHtonl
WinDivertHelperNtohll
WinDivertHelperHtonll
WinDivertHelperNtohMACAddress
WinDivertHelperHtonMACAddress
WinDivertHelperNtohIPv6Address
WinDivertHelperHtonIPv6Address
WinDivertHelperNtohIpv6Address
+4 -34
View File
@@ -1,6 +1,6 @@
/*
* windivert_hash.c
* (C) 2023, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -66,7 +66,6 @@
* "seed" value.
* - The input sized is fixed to 32bytes (excluding the seed), so there is
* only ever a single round. As such, the algorithm has been specialized.
* - [ETHERNET] uses an additional "pseudo-round" for the ethernet header.
*/
#define WINDIVERT_ROTL64(x, r) (((x) << (r)) | ((x) >> (64 - (r))))
@@ -105,16 +104,11 @@ static UINT64 WinDivertXXH64Avalanche(UINT64 h64)
/*
* WinDivert packet hash function.
*/
static UINT64 WinDivertHashPacket(
UINT64 seed,
const WINDIVERT_ETHHDR *eth_header,
const WINDIVERT_ARPHDR *arp_header,
const WINDIVERT_IPHDR *ip_header,
const WINDIVERT_IPV6HDR *ipv6_header,
static UINT64 WinDivertHashPacket(UINT64 seed,
const WINDIVERT_IPHDR *ip_header, const WINDIVERT_IPV6HDR *ipv6_header,
const WINDIVERT_ICMPHDR *icmp_header,
const WINDIVERT_ICMPV6HDR *icmpv6_header,
const WINDIVERT_TCPHDR *tcp_header,
const WINDIVERT_UDPHDR *udp_header)
const WINDIVERT_TCPHDR *tcp_header, const WINDIVERT_UDPHDR *udp_header)
{
UINT64 h64, v1, v2, v3, v4, v[4];
const UINT64 *data64;
@@ -148,17 +142,8 @@ static UINT64 WinDivertHashPacket(
v[1] = data64[4] ^ padding64[5];
i = 2;
}
else if (eth_header != NULL)
{
v2 = padding64[1];
v3 = padding64[2];
v4 = padding64[3];
i = 0;
}
else
{
return 0;
}
if (tcp_header != NULL)
{
@@ -204,21 +189,6 @@ static UINT64 WinDivertHashPacket(
v2 = WinDivertXXH64Round(v[1], v2);
v3 = WinDivertXXH64Round(v[2], v3);
v4 = WinDivertXXH64Round(v[3], v4);
// Ethernet-layer pseudo-round:
if (eth_header != NULL)
{
data64 = (const UINT64 *)eth_header->DstAddr;
v1 = WinDivertXXH64Round(v1, data64[0] & 0xFFFFFFFFFFFFull);
data64 = (const UINT64 *)eth_header->SrcAddr;
v2 = WinDivertXXH64Round(v2, data64[0]);
if (arp_header != NULL)
{
data64 = (const UINT64 *)arp_header;
v3 = WinDivertXXH64Round(v3, data64[0]);
}
}
h64 = WINDIVERT_ROTL64(v1, 1) + WINDIVERT_ROTL64(v2, 7) +
WINDIVERT_ROTL64(v3, 12) + WINDIVERT_ROTL64(v4, 18);
h64 = WinDivertXXH64MergeRound(h64, v1);
+171 -564
View File
File diff suppressed because it is too large Load Diff
+211 -521
View File
File diff suppressed because it is too large Load Diff
+199 -438
View File
File diff suppressed because it is too large Load Diff
+28 -138
View File
@@ -1,6 +1,6 @@
/*
* netdump.c
* (C) 2023, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -37,7 +37,7 @@
* This is a simple traffic monitor. It uses a WinDivert handle in SNIFF mode.
* The SNIFF mode copies packets and does not block the original.
*
* usage: netdump.exe windivert-filter [priority] [layer]
* usage: netdump.exe windivert-filter [priority]
*
*/
@@ -60,23 +60,18 @@
int __cdecl main(int argc, char **argv)
{
HANDLE handle, console;
DWORD err;
UINT i;
WINDIVERT_LAYER layer = WINDIVERT_LAYER_NETWORK;
INT16 priority = 0;
unsigned char packet[MAXBUF];
UINT packet_len, arp_len;
UINT packet_len;
WINDIVERT_ADDRESS addr;
PWINDIVERT_ETHHDR eth_header;
PWINDIVERT_ARPHDR arp_header;
PWINDIVERT_IPHDR ip_header;
PWINDIVERT_IPV6HDR ipv6_header;
PWINDIVERT_ICMPHDR icmp_header;
PWINDIVERT_ICMPV6HDR icmpv6_header;
PWINDIVERT_TCPHDR tcp_header;
PWINDIVERT_UDPHDR udp_header;
UINT8 src_mac[6], dst_mac[6], *mac_ptr;
UINT32 src_addr[4], dst_addr[4], *ip_ptr;
UINT32 src_addr[4], dst_addr[4];
UINT64 hash;
char src_str[INET6_ADDRSTRLEN+1], dst_str[INET6_ADDRSTRLEN+1];
const char *err_str;
@@ -86,44 +81,19 @@ int __cdecl main(int argc, char **argv)
// Check arguments.
switch (argc)
{
case 4:
if (strcmp(argv[3], "network") == 0)
{
layer = WINDIVERT_LAYER_NETWORK;
}
else if (strcmp(argv[3], "forward") == 0)
{
layer = WINDIVERT_LAYER_NETWORK_FORWARD;
}
else if (strcmp(argv[3], "ethernet") == 0)
{
layer = WINDIVERT_LAYER_ETHERNET;
}
else
{
goto usage;
}
// Fallthrough
case 3:
priority = (INT16)atoi(argv[2]);
// Fallthrough
case 2:
break;
case 3:
priority = (INT16)atoi(argv[2]);
break;
default:
usage:
fprintf(stderr, "usage: %s windivert-filter [priority] [layer]\n\n",
fprintf(stderr, "usage: %s windivert-filter [priority]\n",
argv[0]);
fprintf(stderr, "where:\n");
fprintf(stderr, "\t- priority is an integer between "
"-30000..30000 (default = %d)\n", (int)priority);
fprintf(stderr, "\t- layer is one of ethernet/network/forward "
"(default = network)\n\n");
fprintf(stderr, "examples:\n");
fprintf(stderr, "\t%s true\n", argv[0]);
fprintf(stderr, "\t%s \"outbound and tcp.DstPort == 80\" 1000 "
"network\n", argv[0]);
fprintf(stderr, "\t%s \"inbound and tcp.Syn\" -400 ethernet\n",
fprintf(stderr, "\t%s \"outbound and tcp.DstPort == 80\" 1000\n",
argv[0]);
fprintf(stderr, "\t%s \"inbound and tcp.Syn\" -400\n", argv[0]);
exit(EXIT_FAILURE);
}
@@ -131,19 +101,19 @@ int __cdecl main(int argc, char **argv)
console = GetStdHandle(STD_OUTPUT_HANDLE);
// Divert traffic matching the filter:
handle = WinDivertOpen(argv[1], layer, priority, WINDIVERT_FLAG_SNIFF);
handle = WinDivertOpen(argv[1], WINDIVERT_LAYER_NETWORK, priority,
WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_FRAGMENTS);
if (handle == INVALID_HANDLE_VALUE)
{
err = GetLastError();
if (err == ERROR_INVALID_PARAMETER &&
!WinDivertHelperCompileFilter(argv[1], layer, NULL, 0, &err_str,
NULL))
if (GetLastError() == ERROR_INVALID_PARAMETER &&
!WinDivertHelperCompileFilter(argv[1], WINDIVERT_LAYER_NETWORK,
NULL, 0, &err_str, NULL))
{
fprintf(stderr, "error: invalid filter \"%s\"\n", err_str);
exit(EXIT_FAILURE);
}
fprintf(stderr, "error: failed to open the WinDivert device (%d)\n",
err);
GetLastError());
exit(EXIT_FAILURE);
}
@@ -186,104 +156,24 @@ int __cdecl main(int argc, char **argv)
}
// Print info about the matching packet.
WinDivertHelperParsePacket(packet, packet_len, addr.Layer,
&eth_header, &arp_header, &ip_header, &ipv6_header, NULL,
&icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL,
NULL);
WinDivertHelperParsePacket(packet, packet_len, &ip_header, &ipv6_header,
NULL, &icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL,
NULL, NULL, NULL);
if (ip_header == NULL && ipv6_header == NULL)
{
fprintf(stderr, "warning: junk packet\n");
}
// Dump packet info:
putchar('\n');
SetConsoleTextAttribute(console, FOREGROUND_RED);
time_passed = (double)(addr.Timestamp - base.QuadPart) /
(double)freq.QuadPart;
hash = WinDivertHelperHashPacket(packet, packet_len, addr.Layer, 0);
if (eth_header != NULL)
{
printf("Packet [Timestamp=%.8g Length=%u Direction=%s IfIdx=%u "
"SubIfIdx=%u Hash=0x%.16llX]\n",
time_passed, packet_len, (addr.Outbound? "outbound": "inbound"),
addr.Ethernet.IfIdx, addr.Ethernet.SubIfIdx, hash);
WinDivertHelperNtohMACAddress(eth_header->SrcAddr, src_mac);
WinDivertHelperNtohMACAddress(eth_header->DstAddr, dst_mac);
WinDivertHelperFormatMACAddress(src_mac, src_str, sizeof(src_str));
WinDivertHelperFormatMACAddress(dst_mac, dst_str, sizeof(dst_str));
SetConsoleTextAttribute(console,
FOREGROUND_GREEN | FOREGROUND_BLUE);
printf("Ethernet [SrcAddr=%s DstAddr=%s Type=0x%.4X]\n",
src_str, dst_str, ntohs(eth_header->Type));
if (arp_header != NULL)
{
arp_len = packet_len - sizeof(WINDIVERT_ETHHDR);
SetConsoleTextAttribute(console,
FOREGROUND_GREEN);
printf("ARP [Hardware=%u Protocol=%u HardLength=%u "
"ProtLength=%u Opcode=%u",
ntohs(arp_header->Hardware), ntohs(arp_header->Protocol),
arp_header->HardLength, arp_header->ProtLength,
ntohs(arp_header->Opcode));
mac_ptr = WINDIVERT_ARPHDR_GET_SRCMACADDR_PTR(arp_header,
arp_len);
if (mac_ptr != NULL)
{
WinDivertHelperNtohMACAddress(mac_ptr, src_mac);
WinDivertHelperFormatMACAddress(src_mac, src_str,
sizeof(src_str));
printf(" SrcHardAddr=%s", src_str);
}
ip_ptr = WINDIVERT_ARPHDR_GET_SRCIPV4ADDR_PTR(arp_header,
arp_len);
if (ip_ptr != NULL)
{
WinDivertHelperFormatIPv4Address(ntohl(ip_ptr[0]),
src_str, sizeof(src_str));
printf(" SrcProtAddr=%s", src_str);
}
ip_ptr = WINDIVERT_ARPHDR_GET_SRCIPV6ADDR_PTR(arp_header,
arp_len);
if (ip_ptr != NULL)
{
WinDivertHelperNtohIPv6Address(ip_ptr, src_addr);
WinDivertHelperFormatIPv6Address(src_addr, src_str,
sizeof(src_str));
printf(" SrcProtAddr=%s", src_str);
}
mac_ptr = WINDIVERT_ARPHDR_GET_DSTMACADDR_PTR(arp_header,
arp_len);
if (mac_ptr != NULL)
{
WinDivertHelperNtohMACAddress(mac_ptr, dst_mac);
WinDivertHelperFormatMACAddress(dst_mac, dst_str,
sizeof(dst_str));
printf(" DstHardAddr=%s", dst_str);
}
ip_ptr = WINDIVERT_ARPHDR_GET_DSTIPV4ADDR_PTR(arp_header,
arp_len);
if (ip_ptr != NULL)
{
WinDivertHelperFormatIPv4Address(ntohl(ip_ptr[0]),
dst_str, sizeof(dst_str));
printf(" DstProtAddr=%s", dst_str);
}
ip_ptr = WINDIVERT_ARPHDR_GET_DSTIPV6ADDR_PTR(arp_header,
arp_len);
if (ip_ptr != NULL)
{
WinDivertHelperNtohIPv6Address(ip_ptr, dst_addr);
WinDivertHelperFormatIPv6Address(dst_addr, dst_str,
sizeof(dst_str));
printf(" DstProtAddr=%s", dst_str);
}
printf("]\n");
}
}
else
{
printf("Packet [Timestamp=%.8g Length=%u Direction=%s IfIdx=%u "
"SubIfIdx=%u Loopback=%u Hash=0x%.16llX]\n",
time_passed, packet_len, (addr.Outbound? "outbound": "inbound"),
addr.Network.IfIdx, addr.Network.SubIfIdx, addr.Loopback,
hash);
}
hash = WinDivertHelperHashPacket(packet, packet_len, 0);
printf("Packet [Timestamp=%.8g, Direction=%s IfIdx=%u SubIfIdx=%u "
"Loopback=%u Hash=0x%.16llX]\n",
time_passed, (addr.Outbound? "outbound": "inbound"),
addr.Network.IfIdx, addr.Network.SubIfIdx, addr.Loopback, hash);
if (ip_header != NULL)
{
WinDivertHelperFormatIPv4Address(ntohl(ip_header->SrcAddr),
+8 -9
View File
@@ -1,6 +1,6 @@
/*
* netfilter.c
* (C) 2023, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -201,9 +201,9 @@ int __cdecl main(int argc, char **argv)
}
// Print info about the matching packet.
WinDivertHelperParsePacket(packet, packet_len, recv_addr.Layer, NULL,
NULL, &ip_header, &ipv6_header, NULL, &icmp_header, &icmpv6_header,
&tcp_header, &udp_header, NULL, &payload_len);
WinDivertHelperParsePacket(packet, packet_len, &ip_header, &ipv6_header,
NULL, &icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL,
&payload_len, NULL, NULL);
if (ip_header == NULL && ipv6_header == NULL)
{
continue;
@@ -290,7 +290,7 @@ int __cdecl main(int argc, char **argv)
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
send_addr.Outbound = !recv_addr.Outbound;
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(TCPPACKET),
WINDIVERT_LAYER_NETWORK, &send_addr, 0);
&send_addr, 0);
if (!WinDivertSend(handle, (PVOID)reset, sizeof(TCPPACKET),
NULL, &send_addr))
{
@@ -317,8 +317,7 @@ int __cdecl main(int argc, char **argv)
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
send_addr.Outbound = !recv_addr.Outbound;
WinDivertHelperCalcChecksums((PVOID)resetv6,
sizeof(TCPV6PACKET), WINDIVERT_LAYER_NETWORK, &send_addr,
0);
sizeof(TCPV6PACKET), &send_addr, 0);
if (!WinDivertSend(handle, (PVOID)resetv6, sizeof(TCPV6PACKET),
NULL, &send_addr))
{
@@ -344,7 +343,7 @@ int __cdecl main(int argc, char **argv)
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
send_addr.Outbound = !recv_addr.Outbound;
WinDivertHelperCalcChecksums((PVOID)dnr, icmp_length,
WINDIVERT_LAYER_NETWORK, &send_addr, 0);
&send_addr, 0);
if (!WinDivertSend(handle, (PVOID)dnr, icmp_length, NULL,
&send_addr))
{
@@ -367,7 +366,7 @@ int __cdecl main(int argc, char **argv)
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
send_addr.Outbound = !recv_addr.Outbound;
WinDivertHelperCalcChecksums((PVOID)dnrv6, icmpv6_length,
WINDIVERT_LAYER_NETWORK, &send_addr, 0);
&send_addr, 0);
if (!WinDivertSend(handle, (PVOID)dnrv6, icmpv6_length,
NULL, &send_addr))
{
+60 -144
View File
@@ -38,7 +38,6 @@
* useful for performance testing.
*
* usage: passthru.exe [windivert-filter] [num-threads] [batch-size] [priority]
* [layer]
*/
#include <winsock2.h>
@@ -48,162 +47,69 @@
#include "windivert.h"
#define MTU 1500
typedef struct
{
HANDLE handle;
int batch;
} CONFIG, *PCONFIG;
static DWORD passthru(LPVOID arg);
/*
* Options.
*/
static int threads = 1;
static int batch = WINDIVERT_BATCH_MAX;
static int priority = 0;
static WINDIVERT_LAYER layer = WINDIVERT_LAYER_NETWORK;
static int size = (0x10000 + 4096);
/*
* Print usage and exit.
*/
static void usage(const char *prog)
{
fprintf(stderr, "usage: %s [OPTIONS] filter-string\n\n", prog);
fprintf(stderr, "OPTIONS:\n");
fprintf(stderr, "\t--batch N\n");
fprintf(stderr, "\t\tSet the batch size to N (default=%u)\n",
WINDIVERT_BATCH_MAX);
fprintf(stderr, "\t--layer LAYER\n");
fprintf(stderr, "\t\tSet the filter layer to LAYER (default=network).\n");
fprintf(stderr, "\t\tValid values are {ethernet,network,forward}.\n");
fprintf(stderr, "\t--priority N\n");
fprintf(stderr, "\t\tSet the filter priority to N (default=0)\n");
fprintf(stderr, "\t--size N\n");
fprintf(stderr, "\t\tSet the buffer size to N (default=%u)\n",
(0x10000 + 4096));
fprintf(stderr, "\t--threads N\n");
fprintf(stderr, "\t\tSet the number of threads to be N (default=1)\n");
exit(EXIT_FAILURE);
}
/*
* Parse options.
*/
static const char *parse_options(int argc, char **argv)
{
int i;
size_t n;
const char *filter = NULL, *opt, *arg;
for (i = 1; i < argc; i++)
{
opt = argv[i];
if (opt[0] != '-' || opt[1] != '-')
{
if (filter != NULL)
{
usage(argv[0]);
}
filter = opt;
continue;
}
opt += 2;
arg = strchr(opt, '=');
if (arg == NULL)
{
i++;
if (i >= argc)
{
usage(argv[0]);
}
arg = argv[i];
n = strlen(opt);
}
else
{
n = arg - opt;
arg++;
}
if (strncmp(opt, "threads", n) == 0)
{
threads = atoi(arg);
}
else if (strncmp(opt, "batch", n) == 0)
{
batch = atoi(arg);
}
else if (strncmp(opt, "priority", n) == 0)
{
priority = atoi(arg);
}
else if (strncmp(opt, "size", n) == 0)
{
size = atoi(arg);
}
else if (strncmp(opt, "layer", n) == 0)
{
if (strcmp(arg, "ethernet") == 0)
{
layer = WINDIVERT_LAYER_ETHERNET;
}
else if (strcmp(arg, "network") == 0)
{
layer = WINDIVERT_LAYER_NETWORK;
}
else if (strcmp(arg, "forward") == 0)
{
layer = WINDIVERT_LAYER_NETWORK_FORWARD;
}
else
{
usage(argv[0]);
}
}
else
{
usage(argv[0]);
}
}
return (filter == NULL? "true": filter);
}
/*
* Entry.
*/
int __cdecl main(int argc, char **argv)
{
const char *filter;
const char *filter = "true";
int threads = 1, batch = 1, priority = 0;
int i;
HANDLE handle, thread;
CONFIG config;
filter = parse_options(argc, argv);
if (threads < 1 || threads > 64)
if (argc > 5)
{
fprintf(stderr, "error: number of threads must be within "
"the range 1..64, found %d\n", threads);
fprintf(stderr, "usage: %s [filter] [num-threads] [batch-size] "
"[priority]\n", argv[0]);
exit(EXIT_FAILURE);
}
if (batch < 1 || batch > WINDIVERT_BATCH_MAX)
if (argc >= 2)
{
fprintf(stderr, "error: batch size must be within the range 1..%u, "
"found %d\n", WINDIVERT_BATCH_MAX, batch);
exit(EXIT_FAILURE);
filter = argv[1];
}
if (priority < WINDIVERT_PRIORITY_LOWEST ||
priority > WINDIVERT_PRIORITY_HIGHEST)
if (argc >= 3)
{
fprintf(stderr, "error: priority must be within the range %d..%d, "
"found %d\n", WINDIVERT_PRIORITY_LOWEST,
WINDIVERT_PRIORITY_HIGHEST, priority);
exit(EXIT_FAILURE);
threads = atoi(argv[2]);
if (threads < 1 || threads > 64)
{
fprintf(stderr, "error: invalid number of threads\n");
exit(EXIT_FAILURE);
}
}
if (size < 1 || size >= WINDIVERT_BATCH_MAX * WINDIVERT_MTU_MAX)
if (argc >= 4)
{
fprintf(stderr, "error: buffer size must be within the range 1..%d, "
"found %d\n", WINDIVERT_BATCH_MAX * WINDIVERT_MTU_MAX,
size);
exit(EXIT_FAILURE);
batch = atoi(argv[3]);
if (batch <= 0 || batch > WINDIVERT_BATCH_MAX)
{
fprintf(stderr, "error: invalid batch size\n");
exit(EXIT_FAILURE);
}
}
if (argc >= 5)
{
priority = atoi(argv[4]);
if (priority < WINDIVERT_PRIORITY_LOWEST ||
priority > WINDIVERT_PRIORITY_HIGHEST)
{
fprintf(stderr, "error: invalid priority value\n");
exit(EXIT_FAILURE);
}
}
// Divert traffic matching the filter:
handle = WinDivertOpen(filter, layer, (INT16)priority, 0);
handle = WinDivertOpen(filter, WINDIVERT_LAYER_NETWORK, (INT16)priority,
0);
if (handle == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_INVALID_PARAMETER)
@@ -217,10 +123,12 @@ int __cdecl main(int argc, char **argv)
}
// Start the threads
config.handle = handle;
config.batch = batch;
for (i = 1; i < threads; i++)
{
thread = CreateThread(NULL, 1, (LPTHREAD_START_ROUTINE)passthru,
(LPVOID)handle, 0, NULL);
(LPVOID)&config, 0, NULL);
if (thread == NULL)
{
fprintf(stderr, "error: failed to start passthru thread (%d)\n",
@@ -230,8 +138,8 @@ int __cdecl main(int argc, char **argv)
}
// Main thread:
passthru((LPVOID)handle);
passthru((LPVOID)&config);
return 0;
}
@@ -239,11 +147,19 @@ int __cdecl main(int argc, char **argv)
static DWORD passthru(LPVOID arg)
{
UINT8 *packet;
UINT packet_len, addr_len;
UINT packet_len, recv_len, addr_len;
WINDIVERT_ADDRESS *addr;
HANDLE handle = (HANDLE)arg;
PCONFIG config = (PCONFIG)arg;
HANDLE handle;
int batch;
packet = (UINT8 *)malloc(size);
handle = config->handle;
batch = config->batch;
packet_len = batch * MTU;
packet_len =
(packet_len < WINDIVERT_MTU_MAX? WINDIVERT_MTU_MAX: packet_len);
packet = (UINT8 *)malloc(packet_len);
addr = (WINDIVERT_ADDRESS *)malloc(batch * sizeof(WINDIVERT_ADDRESS));
if (packet == NULL || addr == NULL)
{
@@ -257,7 +173,7 @@ static DWORD passthru(LPVOID arg)
{
// Read a matching packet.
addr_len = batch * sizeof(WINDIVERT_ADDRESS);
if (!WinDivertRecvEx(handle, packet, size, &packet_len, 0,
if (!WinDivertRecvEx(handle, packet, packet_len, &recv_len, 0,
addr, &addr_len, NULL))
{
fprintf(stderr, "warning: failed to read packet (%d)\n",
@@ -266,7 +182,7 @@ static DWORD passthru(LPVOID arg)
}
// Re-inject the matching packet.
if (!WinDivertSendEx(handle, packet, packet_len, NULL, 0, addr,
if (!WinDivertSendEx(handle, packet, recv_len, NULL, 0, addr,
addr_len, NULL))
{
fprintf(stderr, "warning: failed to reinject packet (%d)\n",
+4 -4
View File
@@ -1,6 +1,6 @@
/*
* streamdump.c
* (C) 2023, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -193,8 +193,8 @@ int __cdecl main(int argc, char **argv)
continue;
}
WinDivertHelperParsePacket(packet, packet_len, addr.Layer, NULL, NULL,
&ip_header, NULL, NULL, NULL, NULL, &tcp_header, NULL, NULL, NULL);
WinDivertHelperParsePacket(packet, packet_len, &ip_header, NULL, NULL,
NULL, NULL, &tcp_header, NULL, NULL, NULL, NULL, NULL);
if (ip_header == NULL || tcp_header == NULL)
{
warning("failed to parse packet (%d)", GetLastError());
@@ -236,7 +236,7 @@ int __cdecl main(int argc, char **argv)
}
}
WinDivertHelperCalcChecksums(packet, packet_len, addr.Layer, &addr, 0);
WinDivertHelperCalcChecksums(packet, packet_len, &addr, 0);
if (!WinDivertSend(handle, packet, packet_len, NULL, &addr))
{
warning("failed to send packet (%d)", GetLastError());
+7 -10
View File
@@ -1,6 +1,6 @@
/*
* webfilter.c
* (C) 2023, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -204,9 +204,9 @@ int __cdecl main(int argc, char **argv)
continue;
}
WinDivertHelperParsePacket(packet, packet_len, addr.Layer, NULL, NULL,
&ip_header, NULL, NULL, NULL, NULL, &tcp_header, NULL, &payload,
&payload_len);
WinDivertHelperParsePacket(packet, packet_len, &ip_header, NULL,
NULL, NULL, NULL, &tcp_header, NULL, &payload, &payload_len,
NULL, NULL);
if (ip_header == NULL || tcp_header == NULL || payload == NULL ||
!BlackListPayloadMatch(blacklist, payload, (UINT16)payload_len))
{
@@ -230,8 +230,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),
addr.Layer, &addr, 0);
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(PACKET), &addr, 0);
if (!WinDivertSend(handle, (PVOID)reset, sizeof(PACKET), NULL, &addr))
{
fprintf(stderr, "warning: failed to send reset packet (%d)\n",
@@ -246,8 +245,7 @@ int __cdecl main(int argc, char **argv)
blockpage->header.tcp.AckNum =
htonl(ntohl(tcp_header->SeqNum) + payload_len);
addr.Outbound = !addr.Outbound; // Reverse direction.
WinDivertHelperCalcChecksums((PVOID)blockpage, blockpage_len,
addr.Layer, &addr, 0);
WinDivertHelperCalcChecksums((PVOID)blockpage, blockpage_len, &addr, 0);
if (!WinDivertSend(handle, (PVOID)blockpage, blockpage_len, NULL,
&addr))
{
@@ -265,8 +263,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),
addr.Layer, &addr, 0);
WinDivertHelperCalcChecksums((PVOID)finish, sizeof(PACKET), &addr, 0);
if (!WinDivertSend(handle, (PVOID)finish, sizeof(PACKET), NULL, &addr))
{
fprintf(stderr, "warning: failed to send finish packet (%d)\n",
+1 -4
View File
@@ -244,14 +244,11 @@ usage:
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
switch (addr.Reflect.Layer)
{
case WINDIVERT_LAYER_ETHERNET:
fputs("ETHERNET", stdout);
break;
case WINDIVERT_LAYER_NETWORK:
fputs("NETWORK", stdout);
break;
case WINDIVERT_LAYER_NETWORK_FORWARD:
fputs("FORWARD", stdout);
fputs("NETWORK_FORWARD", stdout);
break;
case WINDIVERT_LAYER_FLOW:
fputs("FLOW", stdout);
+7 -109
View File
@@ -1,6 +1,6 @@
/*
* windivert.h
* (C) 2023, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -79,18 +79,8 @@ typedef enum
WINDIVERT_LAYER_FLOW = 2, /* Flow layer. */
WINDIVERT_LAYER_SOCKET = 3, /* Socket layer. */
WINDIVERT_LAYER_REFLECT = 4, /* Reflect layer. */
WINDIVERT_LAYER_ETHERNET = 5, /* Ethernet layer. */
} WINDIVERT_LAYER, *PWINDIVERT_LAYER;
/*
* WinDivert ETHERNET layer data.
*/
typedef struct
{
UINT32 IfIdx; /* Packet's interface index. */
UINT32 SubIfIdx; /* Packet's sub-interface index. */
} WINDIVERT_DATA_ETHERNET, *PWINDIVERT_DATA_ETHERNET;
/*
* WinDivert NETWORK and NETWORK_FORWARD layer data.
*/
@@ -163,12 +153,9 @@ typedef struct
UINT32 TCPChecksum:1; /* Packet has valid TCP checksum? */
UINT32 UDPChecksum:1; /* Packet has valid UDP checksum? */
UINT32 Reserved1:8;
UINT32 Reserved2:12;
UINT32 Length:20; /* Packet length. */
UINT32 Reserved2;
union
{
WINDIVERT_DATA_ETHERNET Ethernet;
/* Ethernet layer data. */
WINDIVERT_DATA_NETWORK Network; /* Network layer data. */
WINDIVERT_DATA_FLOW Flow; /* Flow layer data. */
WINDIVERT_DATA_SOCKET Socket; /* Socket layer data. */
@@ -196,7 +183,6 @@ typedef enum
WINDIVERT_EVENT_SOCKET_CLOSE = 7, /* Socket close. */
WINDIVERT_EVENT_REFLECT_OPEN = 8, /* WinDivert handle opened. */
WINDIVERT_EVENT_REFLECT_CLOSE = 9, /* WinDivert handle closed. */
WINDIVERT_EVENT_ETHERNET_FRAME = 10,/* Ethernet frame. */
} WINDIVERT_EVENT, *PWINDIVERT_EVENT;
/*
@@ -350,71 +336,9 @@ WINDIVERTEXPORT BOOL WinDivertGetParam(
#endif
/*
* Ethernet/ARP/IPv4/IPv6/ICMP/ICMPv6/TCP/UDP header definitions.
* IPv4/IPv6/ICMP/ICMPv6/TCP/UDP header definitions.
*/
typedef struct
{
UINT8 DstAddr[6];
UINT8 SrcAddr[6];
UINT16 Type;
} WINDIVERT_ETHHDR, *PWINDIVERT_ETHHDR;
typedef struct
{
UINT16 Hardware;
UINT16 Protocol;
UINT8 HardLength;
UINT8 ProtLength;
UINT16 Opcode;
} WINDIVERT_ARPHDR, *PWINDIVERT_ARPHDR;
#define WINDIVERT_ARPHDR_VALIDATE(hdr, len) \
((hdr) != NULL && \
(len) >= sizeof(WINDIVERT_ARPHDR) && \
(len) >= sizeof(WINDIVERT_ARPHDR) + \
2 * (hdr)->HardLength + 2 * (hdr)->ProtLength && \
(hdr)->Hardware == 0x0100 && \
(hdr)->HardLength == 6 && \
(((hdr)->Protocol == 0x0008 && \
(hdr)->ProtLength == 4) || \
((hdr)->Protocol == 0xDD86 && \
(hdr)->ProtLength == 16)))
#define WINDIVERT_ARPHDR_GET_SRCHARDADDR_OFFSET(hdr) \
(sizeof(WINDIVERT_ARPHDR))
#define WINDIVERT_ARPHDR_GET_SRCPROTADDR_OFFSET(hdr) \
(sizeof(WINDIVERT_ARPHDR)+(hdr)->HardLength)
#define WINDIVERT_ARPHDR_GET_DSTHARDADDR_OFFSET(hdr) \
(sizeof(WINDIVERT_ARPHDR)+(hdr)->HardLength+(hdr)->ProtLength)
#define WINDIVERT_ARPHDR_GET_DSTPROTADDR_OFFSET(hdr) \
(sizeof(WINDIVERT_ARPHDR)+2*(hdr)->HardLength+(hdr)->ProtLength)
#define WINDIVERT_ARPHDR_GET_SRCMACADDR_PTR(hdr, len) \
(!WINDIVERT_ARPHDR_VALIDATE(hdr, len) || \
(hdr)->Hardware != 0x0100? NULL: \
(((UINT8 *)(hdr))+WINDIVERT_ARPHDR_GET_SRCHARDADDR_OFFSET(hdr)))
#define WINDIVERT_ARPHDR_GET_SRCIPV4ADDR_PTR(hdr, len) \
(!WINDIVERT_ARPHDR_VALIDATE(hdr, len) || \
(hdr)->Protocol != 0x0008? NULL: \
((UINT32 *)(((UINT8 *)(hdr))+WINDIVERT_ARPHDR_GET_SRCPROTADDR_OFFSET(hdr))))
#define WINDIVERT_ARPHDR_GET_SRCIPV6ADDR_PTR(hdr, len) \
(!WINDIVERT_ARPHDR_VALIDATE(hdr, len) || \
(hdr)->Protocol != 0xDD86? NULL: \
((UINT32 *)(((UINT8 *)(hdr))+WINDIVERT_ARPHDR_GET_SRCPROTADDR_OFFSET(hdr))))
#define WINDIVERT_ARPHDR_GET_DSTMACADDR_PTR(hdr, len) \
(!WINDIVERT_ARPHDR_VALIDATE(hdr, len) || \
(hdr)->Hardware != 0x0100? NULL: \
(((UINT8 *)(hdr))+WINDIVERT_ARPHDR_GET_DSTHARDADDR_OFFSET(hdr)))
#define WINDIVERT_ARPHDR_GET_DSTIPV4ADDR_PTR(hdr, len) \
(!WINDIVERT_ARPHDR_VALIDATE(hdr, len) || \
(hdr)->Protocol != 0x0008? NULL: \
((UINT32 *)(((UINT8 *)(hdr))+WINDIVERT_ARPHDR_GET_DSTPROTADDR_OFFSET(hdr))))
#define WINDIVERT_ARPHDR_GET_DSTIPV6ADDR_PTR(hdr, len) \
(!WINDIVERT_ARPHDR_VALIDATE(hdr, len) || \
(hdr)->Protocol != 0xDD86? NULL: \
((UINT32 *)(((UINT8 *)(hdr))+WINDIVERT_ARPHDR_GET_DSTPROTADDR_OFFSET(hdr))))
typedef struct
{
UINT8 HdrLength:4;
UINT8 Version:4;
@@ -566,7 +490,6 @@ typedef struct
WINDIVERTEXPORT UINT64 WinDivertHelperHashPacket(
__in const VOID *pPacket,
__in UINT packetLen,
__in WINDIVERT_LAYER layer,
__in UINT64 seed
#ifdef __cplusplus
= 0
@@ -579,9 +502,6 @@ WINDIVERTEXPORT UINT64 WinDivertHelperHashPacket(
WINDIVERTEXPORT BOOL WinDivertHelperParsePacket(
__in const VOID *pPacket,
__in UINT packetLen,
__in WINDIVERT_LAYER layer,
__out_opt PWINDIVERT_ETHHDR *ppEthHdr,
__out_opt PWINDIVERT_ARPHDR *ppArpHdr,
__out_opt PWINDIVERT_IPHDR *ppIpHdr,
__out_opt PWINDIVERT_IPV6HDR *ppIpv6Hdr,
__out_opt UINT8 *pProtocol,
@@ -590,14 +510,9 @@ WINDIVERTEXPORT BOOL WinDivertHelperParsePacket(
__out_opt PWINDIVERT_TCPHDR *ppTcpHdr,
__out_opt PWINDIVERT_UDPHDR *ppUdpHdr,
__out_opt PVOID *ppData,
__out_opt UINT *pDataLen);
/*
* Parse a MAC address.
*/
WINDIVERTEXPORT BOOL WinDivertHelperParseMACAddress(
__in const char *addrStr,
__out_opt UINT8 *pAddr);
__out_opt UINT *pDataLen,
__out_opt PVOID *ppNext,
__out_opt UINT *pNextLen);
/*
* Parse an IPv4 address.
@@ -613,14 +528,6 @@ WINDIVERTEXPORT BOOL WinDivertHelperParseIPv6Address(
__in const char *addrStr,
__out_opt UINT32 *pAddr);
/*
* Format a MAC address.
*/
WINDIVERTEXPORT BOOL WinDivertHelperFormatMACAddress(
__in const UINT8 *pAddr,
__out char *buffer,
__in UINT bufLen);
/*
* Format an IPv4 address.
*/
@@ -643,7 +550,6 @@ WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv6Address(
WINDIVERTEXPORT BOOL WinDivertHelperCalcChecksums(
__inout VOID *pPacket,
__in UINT packetLen,
__in WINDIVERT_LAYER layer,
__out_opt WINDIVERT_ADDRESS *pAddr,
__in UINT64 flags);
@@ -652,8 +558,7 @@ WINDIVERTEXPORT BOOL WinDivertHelperCalcChecksums(
*/
WINDIVERTEXPORT BOOL WinDivertHelperDecrementTTL(
__inout VOID *pPacket,
__in UINT packetLen,
__in WINDIVERT_LAYER layer);
__in UINT packetLen);
/*
* Compile the given filter string.
@@ -673,7 +578,6 @@ WINDIVERTEXPORT BOOL WinDivertHelperEvalFilter(
__in const char *filter,
__in const VOID *pPacket,
__in UINT packetLen,
__in WINDIVERT_LAYER layer,
__in const WINDIVERT_ADDRESS *pAddr);
/*
@@ -700,12 +604,6 @@ WINDIVERTEXPORT UINT64 WinDivertHelperNtohll(
__in UINT64 x);
WINDIVERTEXPORT UINT64 WinDivertHelperHtonll(
__in UINT64 x);
WINDIVERTEXPORT void WinDivertHelperNtohMACAddress(
__in const UINT8 *inAddr,
__out UINT8 *outAddr);
WINDIVERTEXPORT void WinDivertHelperHtonMACAddress(
__in const UINT8 *inAddr,
__out UINT8 *outAddr);
WINDIVERTEXPORT void WinDivertHelperNtohIPv6Address(
__in const UINT *inAddr,
__out UINT *outAddr);
+4 -17
View File
@@ -1,6 +1,6 @@
/*
* windivert_device.h
* (C) 2023, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -44,8 +44,8 @@
#define WINDIVERT_KERNEL
#include "windivert.h"
#define WINDIVERT_VERSION_MAJOR 3
#define WINDIVERT_VERSION_MINOR 0
#define WINDIVERT_VERSION_MAJOR 2
#define WINDIVERT_VERSION_MINOR 2
#define WINDIVERT_MAGIC_DLL 0x4C4C447669645724ull
#define WINDIVERT_MAGIC_SYS 0x5359537669645723ull
@@ -150,21 +150,8 @@
#define WINDIVERT_FILTER_FIELD_RANDOM16 83
#define WINDIVERT_FILTER_FIELD_RANDOM32 84
#define WINDIVERT_FILTER_FIELD_FRAGMENT 85
#define WINDIVERT_FILTER_FIELD_ETH_DST_ADDR 86
#define WINDIVERT_FILTER_FIELD_ETH_SRC_ADDR 87
#define WINDIVERT_FILTER_FIELD_ETH_TYPE 88
#define WINDIVERT_FILTER_FIELD_ARP 89
#define WINDIVERT_FILTER_FIELD_ARP_HARDWARE 90
#define WINDIVERT_FILTER_FIELD_ARP_PROTOCOL 91
#define WINDIVERT_FILTER_FIELD_ARP_HARD_LENGTH 92
#define WINDIVERT_FILTER_FIELD_ARP_PROT_LENGTH 93
#define WINDIVERT_FILTER_FIELD_ARP_OPCODE 94
#define WINDIVERT_FILTER_FIELD_ARP_SRC_HARD_ADDR 95
#define WINDIVERT_FILTER_FIELD_ARP_SRC_PROT_ADDR 96
#define WINDIVERT_FILTER_FIELD_ARP_DST_HARD_ADDR 97
#define WINDIVERT_FILTER_FIELD_ARP_DST_PROT_ADDR 98
#define WINDIVERT_FILTER_FIELD_MAX \
WINDIVERT_FILTER_FIELD_ARP_DST_PROT_ADDR
WINDIVERT_FILTER_FIELD_FRAGMENT
#define WINDIVERT_FILTER_TEST_EQ 0
#define WINDIVERT_FILTER_TEST_NEQ 1
+1 -1
View File
@@ -4,7 +4,7 @@ Class = WFPCALLOUTS
ClassGuid = {57465043-616C-6C6F-7574-5F636C617373}
Provider = %Basil%
CatalogFile = WinDivert32.Cat
DriverVer = 01/09/2022,2.2.2
DriverVer = 08/08/2019,2.2.0
[SourceDisksNames]
1 = %DiskName%
+1 -1
View File
@@ -4,7 +4,7 @@ Class = WFPCALLOUTS
ClassGuid = {57465043-616C-6C6F-7574-5F636C617373}
Provider = %Basil%
CatalogFile = WinDivert64.Cat
DriverVer = 01/09/2022,2.2.2
DriverVer = 08/08/2019,2.2.0
[SourceDisksNames]
1 = %DiskName%
+555 -991
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1,6 +1,6 @@
/*
* windivert.rc
* (C) 2022, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -48,7 +48,7 @@
#define VER_PRODUCTVERSION 2.2
#define VER_PRODUCTVERSION_STR "2.2"
#define VER_COMPANYNAME_STR "Basil"
#define VER_LEGALCOPYRIGHT_YEARS "2011-2022"
#define VER_LEGALCOPYRIGHT_YEARS "2011-2019"
#define VER_LEGALCOPYRIGHT_STR \
"Copyright \251 " VER_COMPANYNAME_STR " " VER_LEGALCOPYRIGHT_YEARS
#define VER_FILEVERSION VER_PRODUCTVERSION
+1 -1
View File
@@ -69,7 +69,7 @@
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Label="Configuration">
<TargetVersion>Windows8</TargetVersion>
<TargetVersion>Windows7</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
+3 -4
View File
@@ -1276,10 +1276,10 @@ static BOOL run_test(HANDLE inject_handle, const char *filter,
// non-matching random values have been lost:
if ((!random &&
WinDivertHelperEvalFilter(filter, buf[idx], buf_len[idx],
WINDIVERT_LAYER_NETWORK, &addr[idx]) != result) ||
&addr[idx]) != result) ||
(random && result &&
!WinDivertHelperEvalFilter(filter, buf[idx], buf_len[idx],
WINDIVERT_LAYER_NETWORK, &addr[idx])))
&addr[idx])))
{
fprintf(stderr, "error: filter \"%s\" does not match the given "
"packet\n", filter);
@@ -1417,8 +1417,7 @@ static DWORD monitor_worker(LPVOID arg)
addr.Outbound = TRUE;
addr.IPv6 = (iphdr->Version == 4? FALSE: TRUE);
if (WinDivertHelperEvalFilter(object_1, tests[i].packet->packet,
tests[i].packet->packet_len, WINDIVERT_LAYER_NETWORK, &addr)
!= tests[i].match)
tests[i].packet->packet_len, &addr) != tests[i].match)
{
fprintf(stderr, "error: failed to match recompiled filter "
"(test = %.3u, filter = \"%s\" formatted = \"%s\", "