Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f7421f0671 | |||
| a255d6776e | |||
| c3182f8010 | |||
| 54153c425b | |||
| 4b7716edb0 | |||
| 2c7727e179 | |||
| 87e792b528 | |||
| 9f835d9ffa | |||
| 1789526ecf | |||
| 3402f8b2f1 | |||
| 65bb889c79 | |||
| c983d554c9 | |||
| 0b164b6ba3 | |||
| 7f35b0c8f8 | |||
| ea25bab7c5 | |||
| b83e7413be |
@@ -312,3 +312,9 @@ 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.
|
||||
|
||||
@@ -5,7 +5,7 @@ WinDivert 2.2: Windows Packet Divert
|
||||
---------------
|
||||
|
||||
Windows Packet Divert (WinDivert) is a user-mode packet interception library
|
||||
for Windows 7, Windows 8 and Windows 10.
|
||||
for Windows 10, Windows 11, and Windows Server.
|
||||
|
||||
WinDivert enables user-mode capturing/modifying/dropping of network packets
|
||||
sent to/from the Windows network stack. In summary, WinDivert can:
|
||||
|
||||
@@ -479,6 +479,7 @@ 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:
|
||||
|
||||
@@ -13,8 +13,10 @@ EXPORTS
|
||||
WinDivertHelperDecrementTTL
|
||||
WinDivertHelperHashPacket
|
||||
WinDivertHelperParsePacket
|
||||
WinDivertHelperParseMACAddress
|
||||
WinDivertHelperParseIPv4Address
|
||||
WinDivertHelperParseIPv6Address
|
||||
WinDivertHelperFormatMACAddress
|
||||
WinDivertHelperFormatIPv4Address
|
||||
WinDivertHelperFormatIPv6Address
|
||||
WinDivertHelperCompileFilter
|
||||
@@ -26,6 +28,8 @@ EXPORTS
|
||||
WinDivertHelperHtonl
|
||||
WinDivertHelperNtohll
|
||||
WinDivertHelperHtonll
|
||||
WinDivertHelperNtohMACAddress
|
||||
WinDivertHelperHtonMACAddress
|
||||
WinDivertHelperNtohIPv6Address
|
||||
WinDivertHelperHtonIPv6Address
|
||||
WinDivertHelperNtohIpv6Address
|
||||
|
||||
+34
-4
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* windivert_hash.c
|
||||
* (C) 2019, all rights reserved,
|
||||
* (C) 2023, all rights reserved,
|
||||
*
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
@@ -66,6 +66,7 @@
|
||||
* "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))))
|
||||
@@ -104,11 +105,16 @@ static UINT64 WinDivertXXH64Avalanche(UINT64 h64)
|
||||
/*
|
||||
* WinDivert packet hash function.
|
||||
*/
|
||||
static UINT64 WinDivertHashPacket(UINT64 seed,
|
||||
const WINDIVERT_IPHDR *ip_header, const WINDIVERT_IPV6HDR *ipv6_header,
|
||||
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,
|
||||
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;
|
||||
@@ -142,8 +148,17 @@ static UINT64 WinDivertHashPacket(UINT64 seed,
|
||||
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)
|
||||
{
|
||||
@@ -189,6 +204,21 @@ static UINT64 WinDivertHashPacket(UINT64 seed,
|
||||
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);
|
||||
|
||||
+564
-171
File diff suppressed because it is too large
Load Diff
+527
-217
File diff suppressed because it is too large
Load Diff
+438
-199
File diff suppressed because it is too large
Load Diff
+137
-27
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* netdump.c
|
||||
* (C) 2019, all rights reserved,
|
||||
* (C) 2023, 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]
|
||||
* usage: netdump.exe windivert-filter [priority] [layer]
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -60,18 +60,23 @@
|
||||
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;
|
||||
UINT packet_len, arp_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;
|
||||
UINT32 src_addr[4], dst_addr[4];
|
||||
UINT8 src_mac[6], dst_mac[6], *mac_ptr;
|
||||
UINT32 src_addr[4], dst_addr[4], *ip_ptr;
|
||||
UINT64 hash;
|
||||
char src_str[INET6_ADDRSTRLEN+1], dst_str[INET6_ADDRSTRLEN+1];
|
||||
const char *err_str;
|
||||
@@ -81,19 +86,44 @@ int __cdecl main(int argc, char **argv)
|
||||
// Check arguments.
|
||||
switch (argc)
|
||||
{
|
||||
case 2:
|
||||
break;
|
||||
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;
|
||||
default:
|
||||
fprintf(stderr, "usage: %s windivert-filter [priority]\n",
|
||||
usage:
|
||||
fprintf(stderr, "usage: %s windivert-filter [priority] [layer]\n\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\n",
|
||||
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",
|
||||
argv[0]);
|
||||
fprintf(stderr, "\t%s \"inbound and tcp.Syn\" -400\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -101,19 +131,19 @@ int __cdecl main(int argc, char **argv)
|
||||
console = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
// Divert traffic matching the filter:
|
||||
handle = WinDivertOpen(argv[1], WINDIVERT_LAYER_NETWORK, priority,
|
||||
WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_FRAGMENTS);
|
||||
handle = WinDivertOpen(argv[1], layer, priority, WINDIVERT_FLAG_SNIFF);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetLastError() == ERROR_INVALID_PARAMETER &&
|
||||
!WinDivertHelperCompileFilter(argv[1], WINDIVERT_LAYER_NETWORK,
|
||||
NULL, 0, &err_str, NULL))
|
||||
err = GetLastError();
|
||||
if (err == ERROR_INVALID_PARAMETER &&
|
||||
!WinDivertHelperCompileFilter(argv[1], layer, 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",
|
||||
GetLastError());
|
||||
err);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -156,24 +186,104 @@ int __cdecl main(int argc, char **argv)
|
||||
}
|
||||
|
||||
// Print info about the matching packet.
|
||||
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");
|
||||
}
|
||||
WinDivertHelperParsePacket(packet, packet_len, addr.Layer,
|
||||
ð_header, &arp_header, &ip_header, &ipv6_header, NULL,
|
||||
&icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL,
|
||||
NULL);
|
||||
|
||||
// Dump packet info:
|
||||
putchar('\n');
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED);
|
||||
time_passed = (double)(addr.Timestamp - base.QuadPart) /
|
||||
(double)freq.QuadPart;
|
||||
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);
|
||||
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);
|
||||
}
|
||||
if (ip_header != NULL)
|
||||
{
|
||||
WinDivertHelperFormatIPv4Address(ntohl(ip_header->SrcAddr),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* netfilter.c
|
||||
* (C) 2019, all rights reserved,
|
||||
* (C) 2023, 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, &ip_header, &ipv6_header,
|
||||
NULL, &icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL,
|
||||
&payload_len, NULL, NULL);
|
||||
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);
|
||||
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),
|
||||
&send_addr, 0);
|
||||
WINDIVERT_LAYER_NETWORK, &send_addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)reset, sizeof(TCPPACKET),
|
||||
NULL, &send_addr))
|
||||
{
|
||||
@@ -317,7 +317,8 @@ 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), &send_addr, 0);
|
||||
sizeof(TCPV6PACKET), WINDIVERT_LAYER_NETWORK, &send_addr,
|
||||
0);
|
||||
if (!WinDivertSend(handle, (PVOID)resetv6, sizeof(TCPV6PACKET),
|
||||
NULL, &send_addr))
|
||||
{
|
||||
@@ -343,7 +344,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,
|
||||
&send_addr, 0);
|
||||
WINDIVERT_LAYER_NETWORK, &send_addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)dnr, icmp_length, NULL,
|
||||
&send_addr))
|
||||
{
|
||||
@@ -366,7 +367,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,
|
||||
&send_addr, 0);
|
||||
WINDIVERT_LAYER_NETWORK, &send_addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)dnrv6, icmpv6_length,
|
||||
NULL, &send_addr))
|
||||
{
|
||||
|
||||
+144
-60
@@ -38,6 +38,7 @@
|
||||
* useful for performance testing.
|
||||
*
|
||||
* usage: passthru.exe [windivert-filter] [num-threads] [batch-size] [priority]
|
||||
* [layer]
|
||||
*/
|
||||
|
||||
#include <winsock2.h>
|
||||
@@ -47,69 +48,162 @@
|
||||
|
||||
#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 = "true";
|
||||
int threads = 1, batch = 1, priority = 0;
|
||||
const char *filter;
|
||||
int i;
|
||||
HANDLE handle, thread;
|
||||
CONFIG config;
|
||||
|
||||
if (argc > 5)
|
||||
filter = parse_options(argc, argv);
|
||||
|
||||
if (threads < 1 || threads > 64)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [filter] [num-threads] [batch-size] "
|
||||
"[priority]\n", argv[0]);
|
||||
fprintf(stderr, "error: number of threads must be within "
|
||||
"the range 1..64, found %d\n", threads);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (argc >= 2)
|
||||
if (batch < 1 || batch > WINDIVERT_BATCH_MAX)
|
||||
{
|
||||
filter = argv[1];
|
||||
fprintf(stderr, "error: batch size must be within the range 1..%u, "
|
||||
"found %d\n", WINDIVERT_BATCH_MAX, batch);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (argc >= 3)
|
||||
if (priority < WINDIVERT_PRIORITY_LOWEST ||
|
||||
priority > WINDIVERT_PRIORITY_HIGHEST)
|
||||
{
|
||||
threads = atoi(argv[2]);
|
||||
if (threads < 1 || threads > 64)
|
||||
{
|
||||
fprintf(stderr, "error: invalid number of threads\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(stderr, "error: priority must be within the range %d..%d, "
|
||||
"found %d\n", WINDIVERT_PRIORITY_LOWEST,
|
||||
WINDIVERT_PRIORITY_HIGHEST, priority);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (argc >= 4)
|
||||
if (size < 1 || size >= WINDIVERT_BATCH_MAX * WINDIVERT_MTU_MAX)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
// Divert traffic matching the filter:
|
||||
handle = WinDivertOpen(filter, WINDIVERT_LAYER_NETWORK, (INT16)priority,
|
||||
0);
|
||||
handle = WinDivertOpen(filter, layer, (INT16)priority, 0);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetLastError() == ERROR_INVALID_PARAMETER)
|
||||
@@ -123,12 +217,10 @@ 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)&config, 0, NULL);
|
||||
(LPVOID)handle, 0, NULL);
|
||||
if (thread == NULL)
|
||||
{
|
||||
fprintf(stderr, "error: failed to start passthru thread (%d)\n",
|
||||
@@ -138,8 +230,8 @@ int __cdecl main(int argc, char **argv)
|
||||
}
|
||||
|
||||
// Main thread:
|
||||
passthru((LPVOID)&config);
|
||||
|
||||
passthru((LPVOID)handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -147,19 +239,11 @@ int __cdecl main(int argc, char **argv)
|
||||
static DWORD passthru(LPVOID arg)
|
||||
{
|
||||
UINT8 *packet;
|
||||
UINT packet_len, recv_len, addr_len;
|
||||
UINT packet_len, addr_len;
|
||||
WINDIVERT_ADDRESS *addr;
|
||||
PCONFIG config = (PCONFIG)arg;
|
||||
HANDLE handle;
|
||||
int batch;
|
||||
HANDLE handle = (HANDLE)arg;
|
||||
|
||||
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);
|
||||
packet = (UINT8 *)malloc(size);
|
||||
addr = (WINDIVERT_ADDRESS *)malloc(batch * sizeof(WINDIVERT_ADDRESS));
|
||||
if (packet == NULL || addr == NULL)
|
||||
{
|
||||
@@ -173,7 +257,7 @@ static DWORD passthru(LPVOID arg)
|
||||
{
|
||||
// Read a matching packet.
|
||||
addr_len = batch * sizeof(WINDIVERT_ADDRESS);
|
||||
if (!WinDivertRecvEx(handle, packet, packet_len, &recv_len, 0,
|
||||
if (!WinDivertRecvEx(handle, packet, size, &packet_len, 0,
|
||||
addr, &addr_len, NULL))
|
||||
{
|
||||
fprintf(stderr, "warning: failed to read packet (%d)\n",
|
||||
@@ -182,7 +266,7 @@ static DWORD passthru(LPVOID arg)
|
||||
}
|
||||
|
||||
// Re-inject the matching packet.
|
||||
if (!WinDivertSendEx(handle, packet, recv_len, NULL, 0, addr,
|
||||
if (!WinDivertSendEx(handle, packet, packet_len, NULL, 0, addr,
|
||||
addr_len, NULL))
|
||||
{
|
||||
fprintf(stderr, "warning: failed to reinject packet (%d)\n",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* streamdump.c
|
||||
* (C) 2019, all rights reserved,
|
||||
* (C) 2023, 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, &ip_header, NULL, NULL,
|
||||
NULL, NULL, &tcp_header, NULL, NULL, NULL, NULL, NULL);
|
||||
WinDivertHelperParsePacket(packet, packet_len, addr.Layer, NULL, NULL,
|
||||
&ip_header, NULL, NULL, NULL, NULL, &tcp_header, 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, 0);
|
||||
WinDivertHelperCalcChecksums(packet, packet_len, addr.Layer, &addr, 0);
|
||||
if (!WinDivertSend(handle, packet, packet_len, NULL, &addr))
|
||||
{
|
||||
warning("failed to send packet (%d)", GetLastError());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* webfilter.c
|
||||
* (C) 2019, all rights reserved,
|
||||
* (C) 2023, 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, &ip_header, NULL,
|
||||
NULL, NULL, NULL, &tcp_header, NULL, &payload, &payload_len,
|
||||
NULL, NULL);
|
||||
WinDivertHelperParsePacket(packet, packet_len, addr.Layer, NULL, NULL,
|
||||
&ip_header, NULL, NULL, NULL, NULL, &tcp_header, NULL, &payload,
|
||||
&payload_len);
|
||||
if (ip_header == NULL || tcp_header == NULL || payload == NULL ||
|
||||
!BlackListPayloadMatch(blacklist, payload, (UINT16)payload_len))
|
||||
{
|
||||
@@ -230,7 +230,8 @@ 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, 0);
|
||||
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(PACKET),
|
||||
addr.Layer, &addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)reset, sizeof(PACKET), NULL, &addr))
|
||||
{
|
||||
fprintf(stderr, "warning: failed to send reset packet (%d)\n",
|
||||
@@ -245,7 +246,8 @@ 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, 0);
|
||||
WinDivertHelperCalcChecksums((PVOID)blockpage, blockpage_len,
|
||||
addr.Layer, &addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)blockpage, blockpage_len, NULL,
|
||||
&addr))
|
||||
{
|
||||
@@ -263,7 +265,8 @@ 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, 0);
|
||||
WinDivertHelperCalcChecksums((PVOID)finish, sizeof(PACKET),
|
||||
addr.Layer, &addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)finish, sizeof(PACKET), NULL, &addr))
|
||||
{
|
||||
fprintf(stderr, "warning: failed to send finish packet (%d)\n",
|
||||
|
||||
@@ -244,11 +244,14 @@ 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("NETWORK_FORWARD", stdout);
|
||||
fputs("FORWARD", stdout);
|
||||
break;
|
||||
case WINDIVERT_LAYER_FLOW:
|
||||
fputs("FLOW", stdout);
|
||||
|
||||
+109
-7
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* windivert.h
|
||||
* (C) 2019, all rights reserved,
|
||||
* (C) 2023, all rights reserved,
|
||||
*
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
@@ -79,8 +79,18 @@ 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.
|
||||
*/
|
||||
@@ -153,9 +163,12 @@ typedef struct
|
||||
UINT32 TCPChecksum:1; /* Packet has valid TCP checksum? */
|
||||
UINT32 UDPChecksum:1; /* Packet has valid UDP checksum? */
|
||||
UINT32 Reserved1:8;
|
||||
UINT32 Reserved2;
|
||||
UINT32 Reserved2:12;
|
||||
UINT32 Length:20; /* Packet length. */
|
||||
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. */
|
||||
@@ -183,6 +196,7 @@ 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;
|
||||
|
||||
/*
|
||||
@@ -336,9 +350,71 @@ WINDIVERTEXPORT BOOL WinDivertGetParam(
|
||||
#endif
|
||||
|
||||
/*
|
||||
* IPv4/IPv6/ICMP/ICMPv6/TCP/UDP header definitions.
|
||||
* Ethernet/ARP/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;
|
||||
@@ -490,6 +566,7 @@ typedef struct
|
||||
WINDIVERTEXPORT UINT64 WinDivertHelperHashPacket(
|
||||
__in const VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__in UINT64 seed
|
||||
#ifdef __cplusplus
|
||||
= 0
|
||||
@@ -502,6 +579,9 @@ 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,
|
||||
@@ -510,9 +590,14 @@ WINDIVERTEXPORT BOOL WinDivertHelperParsePacket(
|
||||
__out_opt PWINDIVERT_TCPHDR *ppTcpHdr,
|
||||
__out_opt PWINDIVERT_UDPHDR *ppUdpHdr,
|
||||
__out_opt PVOID *ppData,
|
||||
__out_opt UINT *pDataLen,
|
||||
__out_opt PVOID *ppNext,
|
||||
__out_opt UINT *pNextLen);
|
||||
__out_opt UINT *pDataLen);
|
||||
|
||||
/*
|
||||
* Parse a MAC address.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperParseMACAddress(
|
||||
__in const char *addrStr,
|
||||
__out_opt UINT8 *pAddr);
|
||||
|
||||
/*
|
||||
* Parse an IPv4 address.
|
||||
@@ -528,6 +613,14 @@ 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.
|
||||
*/
|
||||
@@ -550,6 +643,7 @@ WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv6Address(
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperCalcChecksums(
|
||||
__inout VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__out_opt WINDIVERT_ADDRESS *pAddr,
|
||||
__in UINT64 flags);
|
||||
|
||||
@@ -558,7 +652,8 @@ WINDIVERTEXPORT BOOL WinDivertHelperCalcChecksums(
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperDecrementTTL(
|
||||
__inout VOID *pPacket,
|
||||
__in UINT packetLen);
|
||||
__in UINT packetLen,
|
||||
__in WINDIVERT_LAYER layer);
|
||||
|
||||
/*
|
||||
* Compile the given filter string.
|
||||
@@ -578,6 +673,7 @@ WINDIVERTEXPORT BOOL WinDivertHelperEvalFilter(
|
||||
__in const char *filter,
|
||||
__in const VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__in const WINDIVERT_ADDRESS *pAddr);
|
||||
|
||||
/*
|
||||
@@ -604,6 +700,12 @@ 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);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* windivert_device.h
|
||||
* (C) 2019, all rights reserved,
|
||||
* (C) 2023, all rights reserved,
|
||||
*
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
@@ -44,8 +44,8 @@
|
||||
#define WINDIVERT_KERNEL
|
||||
#include "windivert.h"
|
||||
|
||||
#define WINDIVERT_VERSION_MAJOR 2
|
||||
#define WINDIVERT_VERSION_MINOR 2
|
||||
#define WINDIVERT_VERSION_MAJOR 3
|
||||
#define WINDIVERT_VERSION_MINOR 0
|
||||
|
||||
#define WINDIVERT_MAGIC_DLL 0x4C4C447669645724ull
|
||||
#define WINDIVERT_MAGIC_SYS 0x5359537669645723ull
|
||||
@@ -150,8 +150,21 @@
|
||||
#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_FRAGMENT
|
||||
WINDIVERT_FILTER_FIELD_ARP_DST_PROT_ADDR
|
||||
|
||||
#define WINDIVERT_FILTER_TEST_EQ 0
|
||||
#define WINDIVERT_FILTER_TEST_NEQ 1
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ Class = WFPCALLOUTS
|
||||
ClassGuid = {57465043-616C-6C6F-7574-5F636C617373}
|
||||
Provider = %Basil%
|
||||
CatalogFile = WinDivert32.Cat
|
||||
DriverVer = 08/08/2019,2.2.0
|
||||
DriverVer = 01/09/2022,2.2.2
|
||||
|
||||
[SourceDisksNames]
|
||||
1 = %DiskName%
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ Class = WFPCALLOUTS
|
||||
ClassGuid = {57465043-616C-6C6F-7574-5F636C617373}
|
||||
Provider = %Basil%
|
||||
CatalogFile = WinDivert64.Cat
|
||||
DriverVer = 08/08/2019,2.2.0
|
||||
DriverVer = 01/09/2022,2.2.2
|
||||
|
||||
[SourceDisksNames]
|
||||
1 = %DiskName%
|
||||
|
||||
+894
-358
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* windivert.rc
|
||||
* (C) 2019, all rights reserved,
|
||||
* (C) 2022, 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-2019"
|
||||
#define VER_LEGALCOPYRIGHT_YEARS "2011-2022"
|
||||
#define VER_LEGALCOPYRIGHT_STR \
|
||||
"Copyright \251 " VER_COMPANYNAME_STR " " VER_LEGALCOPYRIGHT_YEARS
|
||||
#define VER_FILEVERSION VER_PRODUCTVERSION
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<TargetVersion>Windows7</TargetVersion>
|
||||
<TargetVersion>Windows8</TargetVersion>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
|
||||
+4
-3
@@ -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],
|
||||
&addr[idx]) != result) ||
|
||||
WINDIVERT_LAYER_NETWORK, &addr[idx]) != result) ||
|
||||
(random && result &&
|
||||
!WinDivertHelperEvalFilter(filter, buf[idx], buf_len[idx],
|
||||
&addr[idx])))
|
||||
WINDIVERT_LAYER_NETWORK, &addr[idx])))
|
||||
{
|
||||
fprintf(stderr, "error: filter \"%s\" does not match the given "
|
||||
"packet\n", filter);
|
||||
@@ -1417,7 +1417,8 @@ 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, &addr) != tests[i].match)
|
||||
tests[i].packet->packet_len, WINDIVERT_LAYER_NETWORK, &addr)
|
||||
!= tests[i].match)
|
||||
{
|
||||
fprintf(stderr, "error: failed to match recompiled filter "
|
||||
"(test = %.3u, filter = \"%s\" formatted = \"%s\", "
|
||||
|
||||
Reference in New Issue
Block a user