34 Commits

Author SHA1 Message Date
basil00 f7421f0671 Fix TEST simplification logic (again).
"ip.DstAddr >= 0.0.0.0" ---> "ip"
"ip.DstAddr <  0.0.0.0" ---> "false"

Previously, the latter simplified to "not ip".
2023-03-16 07:04:24 +08:00
basil00 a255d6776e Add support for the remaining ARP fields
- SrcHardAddr
- SrcProtAddr
- DstHardAddr
- DstProtAddr
2023-03-15 06:29:26 +08:00
basil00 c3182f8010 Sync doc with library 2023-02-22 09:44:03 +08:00
basil00 54153c425b Add WinDivert support for matching ARP packets. 2023-02-19 07:39:58 +08:00
basil00 4b7716edb0 Fix filter object serialization bug. 2023-02-06 07:21:33 +08:00
basil00 2c7727e179 Update hash function + bug fixes 2023-02-05 07:28:21 +08:00
basil00 87e792b528 Merge branch origin/release-v2.2.1 into eth_layer 2023-01-26 06:51:19 +08:00
basil00 9f835d9ffa Fix #294 for ethernet layer branch
Seems to solve the network-stop problem, see #326
2023-01-25 06:50:08 +08:00
basil00 1789526ecf Bump version to 2.2.2 & other fixups 2022-09-17 10:32:57 +08:00
basil00 3402f8b2f1 Fix #315 2022-09-12 08:08:42 +08:00
basil00 65bb889c79 Bump version and copyright years 2022-07-30 11:34:25 +08:00
basil00 c983d554c9 Fix previous commit 8bda0af
Fix #294

Previous commit was incomplete.
2022-07-30 11:27:57 +08:00
basil00 0b164b6ba3 Fix handling of FwpmTransaction*() errors.
Fixes #294
2022-07-30 11:24:46 +08:00
basil00 7f35b0c8f8 Merge pull request #296 from StalkR/patch-1
windivert.html: fix 6.11 title: format not parse
2022-07-30 11:24:46 +08:00
StalkR ea25bab7c5 windivert.html: fix 6.11 title: format not parse 2022-07-30 11:24:46 +08:00
basil00 c26ec39465 Fix filter compiler test simplification logic
Fix #285
2021-09-25 07:23:08 +08:00
basil00 227a6b1e78 Fix #283 2021-09-11 07:09:51 +08:00
basil00 134dd37bd0 Insert all WinDivert sublayers at the max weight. 2020-09-03 08:12:39 +08:00
basil00 97056af256 Cleanup the provider code. 2020-06-26 08:53:18 +08:00
basil00 db674a6696 Merge pull request #241 from ruilisi/add_provider
Install provider to pass HLK test
2020-06-24 08:35:31 +08:00
Zhou Yicheng 32af280add Install provider to pass HLK test 2020-06-22 11:08:51 +08:00
basil00 b83e7413be Add an ETHERNET layer to WinDivert.
Adds a new ETHERNET layer to WinDivert.  This
layer is similar to the NETWORK layers in that
packets can be blocked/modified/injected.  This
change requires Windows 8 or newer.
2019-12-20 09:09:57 +08:00
basil00 091ffb3d49 Reformatting 2019-10-06 08:19:23 +08:00
basil00 aff111e44d Merge pull request #211 from zzzjim/fix-mcafee
Inject on different handles for inbound/outbound
2019-10-06 08:12:36 +08:00
zzzjim 160d983960 Inject on different handles for inbound/outbound 2019-10-04 19:11:25 -07:00
basil00 69b4620277 Log a system event on driver (un)load.
This allows WinDivert to be detected without
using the REFLECT API.
2019-10-04 08:57:30 +08:00
basil00 bcba321048 Fix another packet batch parsing bug.
Extended/truncated logic was reversed.
2019-10-03 05:02:37 +08:00
basil00 0c773bc08f Fix batch parsing bug. 2019-09-29 07:27:04 +08:00
basil00 eba2e59e3b Ensure RC file included in MSVC build. 2019-09-29 07:15:41 +08:00
basil00 951560d403 Modify WINDIVERTEXPORT so it can be static.
For better static linking support.
2019-08-31 08:49:56 +08:00
basil00 7dc1c5d54a Fix some compiler warnings. 2019-08-27 09:45:45 +08:00
basil00 a1173fe08f Coalesce filter interpreter implementations.
Replace the dual kernel/user-mode filter
interpreters with a single shared implementation.
2019-08-17 09:31:46 +08:00
basil00 a240329323 Add "fragment" to filter language.
True if the packet is an IPv4/IPv6 fragment.
2019-08-15 09:08:46 +08:00
basil00 317e6f1099 Implement new packet parser(s) for WinDivert.
The new parser should better handle fragments
as well as be consistent with the kernel-mode
parser.  The new parser can also handle truncated
packets.
2019-08-12 07:50:49 +08:00
26 changed files with 5082 additions and 3325 deletions
+10
View File
@@ -308,3 +308,13 @@ WinDivert 2.1.0
- Fix BSOD caused by packets with missing or incomplete transport
headers (introduced in 2.0.0).
- Fix missing Flow.EndpointId and Flow.ParentEndpointId for IPv6 flows.
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.
+2 -2
View File
@@ -1,11 +1,11 @@
WinDivert 2.1: Windows Packet Divert
WinDivert 2.2: Windows Packet Divert
====================================
1. Introduction
---------------
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:
+1 -1
View File
@@ -1 +1 @@
2.1.0
2.2.2
+71 -24
View File
@@ -43,7 +43,9 @@
#include <stdio.h>
#include <stdlib.h>
#define WINDIVERTEXPORT
#ifndef WINDIVERTEXPORT
#define WINDIVERTEXPORT extern
#endif
#include "windivert.h"
#include "windivert_device.h"
@@ -85,6 +87,8 @@ static UINT32 WinDivertDivTen128(UINT32 *a);
#define UINT32_MAX 0xFFFFFFFF
#endif
#define IPPROTO_MH 135
#ifdef _MSC_VER
#pragma intrinsic(memcpy)
@@ -107,7 +111,22 @@ void *memset(void *dst, int c, size_t n)
return dst;
}
#endif
#define WINDIVERT_INLINE __forceinline
#else /* _MSC_VER */
#define WINDIVERT_INLINE __attribute__((__always_inline__)) inline
#endif /* _MSC_VER */
/*
* Filter interpreter config.
*/
static BOOL WinDivertGetData(const VOID *packet, UINT packet_len, INT min,
INT max, INT idx, PVOID data, UINT size);
#define WINDIVERT_GET_DATA(packet, packet_len, min, max, index, data, size) \
WinDivertGetData((packet), (packet_len), (min), (max), (index), (data), \
(size))
/*
* Prototypes.
@@ -135,8 +154,7 @@ static HMODULE module = NULL;
/*
* Dll Entry
*/
extern BOOL APIENTRY WinDivertDllEntry(HANDLE module0, DWORD reason,
LPVOID reserved)
BOOL APIENTRY WinDivertDllEntry(HANDLE module0, DWORD reason, LPVOID reserved)
{
HANDLE event;
switch (reason)
@@ -245,6 +263,33 @@ static BOOLEAN WinDivertGetDriverFileName(LPWSTR sys_str)
return TRUE;
}
/*
* Register event log. It is not an error if this function fails.
*/
static void WinDivertRegisterEventSource(const wchar_t *windivert_sys)
{
HKEY key;
size_t len;
DWORD types = 7;
if (!WinDivertStrLen(windivert_sys, MAX_PATH, &len))
{
return;
}
if (RegCreateKeyExA(HKEY_LOCAL_MACHINE,
"System\\CurrentControlSet\\Services\\EventLog\\System\\WinDivert",
0, NULL, REG_OPTION_VOLATILE, KEY_SET_VALUE, NULL, &key, NULL)
!= ERROR_SUCCESS)
{
return;
}
RegSetValueExW(key, L"EventMessageFile", 0, REG_SZ, (LPBYTE)windivert_sys,
(len + 1) * sizeof(wchar_t));
RegSetValueExA(key, "TypesSupported", 0, REG_DWORD, (LPBYTE)&types,
sizeof(types));
RegCloseKey(key);
}
/*
* Install the WinDivert driver.
*/
@@ -306,6 +351,9 @@ static BOOLEAN WinDivertDriverInstall(VOID)
goto WinDivertDriverInstallExit;
}
// Register event logging:
WinDivertRegisterEventSource(windivert_sys);
WinDivertDriverInstallExit:
success = (service != NULL);
@@ -338,7 +386,7 @@ WinDivertDriverInstallExit:
ReleaseMutex(mutex);
CloseHandle(mutex);
SetLastError(err);
return success;
}
@@ -403,8 +451,8 @@ static BOOL WinDivertIoControl(HANDLE handle, DWORD code,
/*
* Open a WinDivert handle.
*/
extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
INT16 priority, UINT64 flags)
HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer, INT16 priority,
UINT64 flags)
{
WINDIVERT_FILTER *object;
UINT obj_len;
@@ -431,6 +479,7 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
// Parameter checking:
switch (layer)
{
case WINDIVERT_LAYER_ETHERNET:
case WINDIVERT_LAYER_NETWORK:
case WINDIVERT_LAYER_NETWORK_FORWARD:
case WINDIVERT_LAYER_FLOW:
@@ -571,13 +620,13 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
/*
* Receive a WinDivert packet.
*/
extern BOOL WinDivertRecv(HANDLE handle, PVOID pPacket, UINT packetLen,
UINT *readLen, PWINDIVERT_ADDRESS addr)
BOOL WinDivertRecv(HANDLE handle, PVOID pPacket, UINT packetLen, UINT *readLen,
PWINDIVERT_ADDRESS addr)
{
WINDIVERT_IOCTL ioctl;
memset(&ioctl, 0, sizeof(ioctl));
ioctl.recv.addr = (UINT64)addr;
ioctl.recv.addr_len_ptr = (UINT64)NULL;
ioctl.recv.addr = (UINT64)(ULONG_PTR)addr;
ioctl.recv.addr_len_ptr = (UINT64)(ULONG_PTR)NULL;
return WinDivertIoControl(handle, IOCTL_WINDIVERT_RECV, &ioctl,
pPacket, packetLen, readLen);
}
@@ -585,14 +634,14 @@ extern BOOL WinDivertRecv(HANDLE handle, PVOID pPacket, UINT packetLen,
/*
* Receive a WinDivert packet.
*/
extern BOOL WinDivertRecvEx(HANDLE handle, PVOID pPacket, UINT packetLen,
BOOL WinDivertRecvEx(HANDLE handle, PVOID pPacket, UINT packetLen,
UINT *readLen, UINT64 flags, PWINDIVERT_ADDRESS addr, UINT *pAddrLen,
LPOVERLAPPED overlapped)
{
WINDIVERT_IOCTL ioctl;
memset(&ioctl, 0, sizeof(ioctl));
ioctl.recv.addr = (UINT64)addr;
ioctl.recv.addr_len_ptr = (UINT64)pAddrLen;
ioctl.recv.addr = (UINT64)(ULONG_PTR)addr;
ioctl.recv.addr_len_ptr = (UINT64)(ULONG_PTR)pAddrLen;
if (flags != 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
@@ -613,12 +662,12 @@ extern BOOL WinDivertRecvEx(HANDLE handle, PVOID pPacket, UINT packetLen,
/*
* Send a WinDivert packet.
*/
extern BOOL WinDivertSend(HANDLE handle, const VOID *pPacket, UINT packetLen,
BOOL WinDivertSend(HANDLE handle, const VOID *pPacket, UINT packetLen,
UINT *writeLen, const WINDIVERT_ADDRESS *addr)
{
WINDIVERT_IOCTL ioctl;
memset(&ioctl, 0, sizeof(ioctl));
ioctl.send.addr = (UINT64)addr;
ioctl.send.addr = (UINT64)(ULONG_PTR)addr;
ioctl.send.addr_len = sizeof(WINDIVERT_ADDRESS);
return WinDivertIoControl(handle, IOCTL_WINDIVERT_SEND, &ioctl,
(PVOID)pPacket, packetLen, writeLen);
@@ -627,13 +676,13 @@ extern BOOL WinDivertSend(HANDLE handle, const VOID *pPacket, UINT packetLen,
/*
* Send a WinDivert packet.
*/
extern BOOL WinDivertSendEx(HANDLE handle, const VOID *pPacket, UINT packetLen,
BOOL WinDivertSendEx(HANDLE handle, const VOID *pPacket, UINT packetLen,
UINT *writeLen, UINT64 flags, const WINDIVERT_ADDRESS *addr, UINT addrLen,
LPOVERLAPPED overlapped)
{
WINDIVERT_IOCTL ioctl;
memset(&ioctl, 0, sizeof(ioctl));
ioctl.send.addr = (UINT64)addr;
ioctl.send.addr = (UINT64)(ULONG_PTR)addr;
ioctl.send.addr_len = addrLen;
if (flags != 0)
{
@@ -655,7 +704,7 @@ extern BOOL WinDivertSendEx(HANDLE handle, const VOID *pPacket, UINT packetLen,
/*
* Shutdown a WinDivert handle.
*/
extern BOOL WinDivertShutdown(HANDLE handle, WINDIVERT_SHUTDOWN how)
BOOL WinDivertShutdown(HANDLE handle, WINDIVERT_SHUTDOWN how)
{
WINDIVERT_IOCTL ioctl;
memset(&ioctl, 0, sizeof(ioctl));
@@ -667,7 +716,7 @@ extern BOOL WinDivertShutdown(HANDLE handle, WINDIVERT_SHUTDOWN how)
/*
* Close a WinDivert handle.
*/
extern BOOL WinDivertClose(HANDLE handle)
BOOL WinDivertClose(HANDLE handle)
{
return CloseHandle(handle);
}
@@ -675,8 +724,7 @@ extern BOOL WinDivertClose(HANDLE handle)
/*
* Set a WinDivert parameter.
*/
extern BOOL WinDivertSetParam(HANDLE handle, WINDIVERT_PARAM param,
UINT64 value)
BOOL WinDivertSetParam(HANDLE handle, WINDIVERT_PARAM param, UINT64 value)
{
WINDIVERT_IOCTL ioctl;
memset(&ioctl, 0, sizeof(ioctl));
@@ -689,8 +737,7 @@ extern BOOL WinDivertSetParam(HANDLE handle, WINDIVERT_PARAM param,
/*
* Get a WinDivert parameter.
*/
extern BOOL WinDivertGetParam(HANDLE handle, WINDIVERT_PARAM param,
UINT64 *pValue)
BOOL WinDivertGetParam(HANDLE handle, WINDIVERT_PARAM param, UINT64 *pValue)
{
WINDIVERT_IOCTL ioctl;
memset(&ioctl, 0, sizeof(ioctl));
+4
View File
@@ -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
+51 -19
View File
@@ -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,35 +105,42 @@ static UINT64 WinDivertXXH64Avalanche(UINT64 h64)
/*
* WinDivert packet hash function.
*/
static UINT64 WinDivertHashPacket(UINT64 seed, PWINDIVERT_IPHDR ip_header,
PWINDIVERT_IPV6HDR ipv6_header, PWINDIVERT_ICMPHDR icmp_header,
PWINDIVERT_ICMPV6HDR icmpv6_header, PWINDIVERT_TCPHDR tcp_header,
PWINDIVERT_UDPHDR udp_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)
{
UINT64 h64, v1, v2, v3, v4, v[4], *data64;
UINT32 *data32;
UINT64 h64, v1, v2, v3, v4, v[4];
const UINT64 *data64;
const UINT32 *data32;
UINT i;
static const UINT64 padding64[] = // SHA2 IV
{
0x428A2F9871374491ull, 0xB5C0FBCFE9B5DBA5ull, 0x3956C25B59F111F1ull,
0x923F82A4AB1C5ED5ull, 0xD807AA9812835B01ull, 0x243185BE550C7DC3ull,
0x72BE5D7480DEB1FEull, 0x9BDC06A7C19BF174ull, 0xE49B69C1EFBE4786ull,
0x428A2F9871374491ull, 0xB5C0FBCFE9B5DBA5ull, 0x3956C25B59F111F1ull,
0x923F82A4AB1C5ED5ull, 0xD807AA9812835B01ull, 0x243185BE550C7DC3ull,
0x72BE5D7480DEB1FEull, 0x9BDC06A7C19BF174ull, 0xE49B69C1EFBE4786ull,
};
// Set-up seed & data
v1 = seed ^ padding64[0];
if (ip_header != NULL)
{
data64 = (UINT64 *)ip_header;
data64 = (const UINT64 *)ip_header;
v2 = data64[0] ^ padding64[1];
v3 = data64[1] ^ padding64[2];
data32 = (UINT32 *)ip_header;
data32 = (const UINT32 *)ip_header;
v4 = (UINT64)data32[4] ^ padding64[3];
i = 0;
}
else if (ipv6_header != NULL)
{
data64 = (UINT64 *)ipv6_header;
data64 = (const UINT64 *)ipv6_header;
v2 = data64[0] ^ padding64[1];
v3 = data64[1] ^ padding64[2];
v4 = data64[2] ^ padding64[3];
@@ -140,15 +148,24 @@ static UINT64 WinDivertHashPacket(UINT64 seed, PWINDIVERT_IPHDR ip_header,
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)
{
data64 = (UINT64 *)tcp_header;
data64 = (const UINT64 *)tcp_header;
v[i] = data64[0] ^ padding64[i+4]; i++;
v[i] = data64[1] ^ padding64[i+4]; i++;
data32 = (UINT32 *)tcp_header;
data32 = (const UINT32 *)tcp_header;
if (i <= 3)
{
v[i] = (UINT64)data32[4] ^ padding64[i+4]; i++;
@@ -162,17 +179,17 @@ static UINT64 WinDivertHashPacket(UINT64 seed, PWINDIVERT_IPHDR ip_header,
{
if (udp_header != NULL)
{
data64 = (UINT64 *)udp_header;
data64 = (const UINT64 *)udp_header;
v[i] = data64[0] ^ padding64[i+4]; i++;
}
else if (icmp_header != NULL)
{
data64 = (UINT64 *)icmp_header;
data64 = (const UINT64 *)icmp_header;
v[i] = data64[0] ^ padding64[i+4]; i++;
}
else if (icmpv6_header != NULL)
{
data64 = (UINT64 *)icmpv6_header;
data64 = (const UINT64 *)icmpv6_header;
v[i] = data64[0] ^ padding64[i+4]; i++;
}
}
@@ -187,6 +204,21 @@ static UINT64 WinDivertHashPacket(UINT64 seed, PWINDIVERT_IPHDR ip_header,
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);
@@ -194,7 +226,7 @@ static UINT64 WinDivertHashPacket(UINT64 seed, PWINDIVERT_IPHDR ip_header,
h64 = WinDivertXXH64MergeRound(h64, v3);
h64 = WinDivertXXH64MergeRound(h64, v4);
h64 += 32; // "length"
h64 = WinDivertXXH64Avalanche(h64);
h64 = WinDivertXXH64Avalanche(h64);
return h64;
}
+1063 -1404
View File
File diff suppressed because it is too large Load Diff
+1524 -231
View File
File diff suppressed because it is too large Load Diff
+438 -198
View File
File diff suppressed because it is too large Load Diff
+137 -27
View File
@@ -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,
&eth_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),
+9 -8
View File
@@ -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
View File
@@ -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",
+4 -4
View File
@@ -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());
+10 -7
View File
@@ -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",
+4 -1
View File
@@ -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);
+140 -38
View File
@@ -1,6 +1,6 @@
/*
* windivert.h
* (C) 2019, all rights reserved,
* (C) 2023, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -40,7 +40,7 @@
#endif /* WINDIVERT_KERNEL */
#ifndef WINDIVERTEXPORT
#define WINDIVERTEXPORT __declspec(dllimport)
#define WINDIVERTEXPORT extern __declspec(dllimport)
#endif /* WINDIVERTEXPORT */
#ifdef __MINGW32__
@@ -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;
/*
@@ -226,7 +240,7 @@ typedef enum
/*
* Open a WinDivert handle.
*/
extern WINDIVERTEXPORT HANDLE WinDivertOpen(
WINDIVERTEXPORT HANDLE WinDivertOpen(
__in const char *filter,
__in WINDIVERT_LAYER layer,
__in INT16 priority,
@@ -235,7 +249,7 @@ extern WINDIVERTEXPORT HANDLE WinDivertOpen(
/*
* Receive (read) a packet from a WinDivert handle.
*/
extern WINDIVERTEXPORT BOOL WinDivertRecv(
WINDIVERTEXPORT BOOL WinDivertRecv(
__in HANDLE handle,
__out_opt VOID *pPacket,
__in UINT packetLen,
@@ -245,7 +259,7 @@ extern WINDIVERTEXPORT BOOL WinDivertRecv(
/*
* Receive (read) a packet from a WinDivert handle.
*/
extern WINDIVERTEXPORT BOOL WinDivertRecvEx(
WINDIVERTEXPORT BOOL WinDivertRecvEx(
__in HANDLE handle,
__out_opt VOID *pPacket,
__in UINT packetLen,
@@ -258,7 +272,7 @@ extern WINDIVERTEXPORT BOOL WinDivertRecvEx(
/*
* Send (write/inject) a packet to a WinDivert handle.
*/
extern WINDIVERTEXPORT BOOL WinDivertSend(
WINDIVERTEXPORT BOOL WinDivertSend(
__in HANDLE handle,
__in const VOID *pPacket,
__in UINT packetLen,
@@ -268,7 +282,7 @@ extern WINDIVERTEXPORT BOOL WinDivertSend(
/*
* Send (write/inject) a packet to a WinDivert handle.
*/
extern WINDIVERTEXPORT BOOL WinDivertSendEx(
WINDIVERTEXPORT BOOL WinDivertSendEx(
__in HANDLE handle,
__in const VOID *pPacket,
__in UINT packetLen,
@@ -281,20 +295,20 @@ extern WINDIVERTEXPORT BOOL WinDivertSendEx(
/*
* Shutdown a WinDivert handle.
*/
extern WINDIVERTEXPORT BOOL WinDivertShutdown(
WINDIVERTEXPORT BOOL WinDivertShutdown(
__in HANDLE handle,
__in WINDIVERT_SHUTDOWN how);
/*
* Close a WinDivert handle.
*/
extern WINDIVERTEXPORT BOOL WinDivertClose(
WINDIVERTEXPORT BOOL WinDivertClose(
__in HANDLE handle);
/*
* Set a WinDivert handle parameter.
*/
extern WINDIVERTEXPORT BOOL WinDivertSetParam(
WINDIVERTEXPORT BOOL WinDivertSetParam(
__in HANDLE handle,
__in WINDIVERT_PARAM param,
__in UINT64 value);
@@ -302,7 +316,7 @@ extern WINDIVERTEXPORT BOOL WinDivertSetParam(
/*
* Get a WinDivert handle parameter.
*/
extern WINDIVERTEXPORT BOOL WinDivertGetParam(
WINDIVERTEXPORT BOOL WinDivertGetParam(
__in HANDLE handle,
__in WINDIVERT_PARAM param,
__out UINT64 *pValue);
@@ -336,9 +350,71 @@ extern 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;
@@ -487,9 +563,10 @@ typedef struct
/*
* Hash a packet.
*/
extern WINDIVERTEXPORT UINT64 WinDivertHelperHashPacket(
WINDIVERTEXPORT UINT64 WinDivertHelperHashPacket(
__in const VOID *pPacket,
__in UINT packetLen,
__in WINDIVERT_LAYER layer,
__in UINT64 seed
#ifdef __cplusplus
= 0
@@ -499,9 +576,12 @@ extern WINDIVERTEXPORT UINT64 WinDivertHelperHashPacket(
/*
* Parse IPv4/IPv6/ICMP/ICMPv6/TCP/UDP headers from a raw packet.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperParsePacket(
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,28 +590,41 @@ extern 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.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperParseIPv4Address(
WINDIVERTEXPORT BOOL WinDivertHelperParseIPv4Address(
__in const char *addrStr,
__out_opt UINT32 *pAddr);
/*
* Parse an IPv6 address.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperParseIPv6Address(
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.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv4Address(
WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv4Address(
__in UINT32 addr,
__out char *buffer,
__in UINT bufLen);
@@ -539,7 +632,7 @@ extern WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv4Address(
/*
* Format an IPv6 address.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv6Address(
WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv6Address(
__in const UINT32 *pAddr,
__out char *buffer,
__in UINT bufLen);
@@ -547,23 +640,25 @@ extern WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv6Address(
/*
* Calculate IPv4/IPv6/ICMP/ICMPv6/TCP/UDP checksums.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperCalcChecksums(
WINDIVERTEXPORT BOOL WinDivertHelperCalcChecksums(
__inout VOID *pPacket,
__in UINT packetLen,
__in WINDIVERT_LAYER layer,
__out_opt WINDIVERT_ADDRESS *pAddr,
__in UINT64 flags);
/*
* Decrement the TTL/HopLimit.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperDecrementTTL(
WINDIVERTEXPORT BOOL WinDivertHelperDecrementTTL(
__inout VOID *pPacket,
__in UINT packetLen);
__in UINT packetLen,
__in WINDIVERT_LAYER layer);
/*
* Compile the given filter string.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperCompileFilter(
WINDIVERTEXPORT BOOL WinDivertHelperCompileFilter(
__in const char *filter,
__in WINDIVERT_LAYER layer,
__out_opt char *object,
@@ -574,16 +669,17 @@ extern WINDIVERTEXPORT BOOL WinDivertHelperCompileFilter(
/*
* Evaluate the given filter string.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperEvalFilter(
WINDIVERTEXPORT BOOL WinDivertHelperEvalFilter(
__in const char *filter,
__in const VOID *pPacket,
__in UINT packetLen,
__in WINDIVERT_LAYER layer,
__in const WINDIVERT_ADDRESS *pAddr);
/*
* Format the given filter string.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperFormatFilter(
WINDIVERTEXPORT BOOL WinDivertHelperFormatFilter(
__in const char *filter,
__in WINDIVERT_LAYER layer,
__out char *buffer,
@@ -592,32 +688,38 @@ extern WINDIVERTEXPORT BOOL WinDivertHelperFormatFilter(
/*
* Byte ordering.
*/
extern WINDIVERTEXPORT UINT16 WinDivertHelperNtohs(
WINDIVERTEXPORT UINT16 WinDivertHelperNtohs(
__in UINT16 x);
extern WINDIVERTEXPORT UINT16 WinDivertHelperHtons(
WINDIVERTEXPORT UINT16 WinDivertHelperHtons(
__in UINT16 x);
extern WINDIVERTEXPORT UINT32 WinDivertHelperNtohl(
WINDIVERTEXPORT UINT32 WinDivertHelperNtohl(
__in UINT32 x);
extern WINDIVERTEXPORT UINT32 WinDivertHelperHtonl(
WINDIVERTEXPORT UINT32 WinDivertHelperHtonl(
__in UINT32 x);
extern WINDIVERTEXPORT UINT64 WinDivertHelperNtohll(
WINDIVERTEXPORT UINT64 WinDivertHelperNtohll(
__in UINT64 x);
extern WINDIVERTEXPORT UINT64 WinDivertHelperHtonll(
WINDIVERTEXPORT UINT64 WinDivertHelperHtonll(
__in UINT64 x);
extern WINDIVERTEXPORT void WinDivertHelperNtohIPv6Address(
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);
extern WINDIVERTEXPORT void WinDivertHelperHtonIPv6Address(
WINDIVERTEXPORT void WinDivertHelperHtonIPv6Address(
__in const UINT *inAddr,
__out UINT *outAddr);
/*
* Old names to be removed in the next version.
*/
extern WINDIVERTEXPORT void WinDivertHelperNtohIpv6Address(
WINDIVERTEXPORT void WinDivertHelperNtohIpv6Address(
__in const UINT *inAddr,
__out UINT *outAddr);
extern WINDIVERTEXPORT void WinDivertHelperHtonIpv6Address(
WINDIVERTEXPORT void WinDivertHelperHtonIpv6Address(
__in const UINT *inAddr,
__out UINT *outAddr);
+19 -5
View File
@@ -1,6 +1,6 @@
/*
* windivert_device.h
* (C) 2019, all rights reserved,
* (C) 2023, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -38,14 +38,14 @@
/*
* NOTE: This is the low-level interface to the WinDivert device driver.
* This interface should not be used directly, instead use the high-level
* interface provided by the divert API.
* interface provided by the WinDivert API.
*/
#define WINDIVERT_KERNEL
#include "windivert.h"
#define WINDIVERT_VERSION_MAJOR 2
#define WINDIVERT_VERSION_MINOR 1
#define WINDIVERT_VERSION_MAJOR 3
#define WINDIVERT_VERSION_MINOR 0
#define WINDIVERT_MAGIC_DLL 0x4C4C447669645724ull
#define WINDIVERT_MAGIC_SYS 0x5359537669645723ull
@@ -149,8 +149,22 @@
#define WINDIVERT_FILTER_FIELD_RANDOM8 82
#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_RANDOM32
WINDIVERT_FILTER_FIELD_ARP_DST_PROT_ADDR
#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 = 08/08/2019,2.1.0
DriverVer = 01/09/2022,2.2.2
[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 = 08/08/2019,2.1.0
DriverVer = 01/09/2022,2.2.2
[SourceDisksNames]
1 = %DiskName%
+2 -2
View File
@@ -41,7 +41,7 @@ ENVS="i686-w64-mingw32 x86_64-w64-mingw32"
if [ "$1" = "debug" ]
then
MSVCRT=-lmsvcrt
EXTRA_OPTS="-lmsvcrt -include stdio.h"
fi
for ENV in $ENVS
@@ -66,7 +66,7 @@ do
CC="$ENV-gcc"
COPTS="-fno-ident -shared -Wall -Wno-pointer-to-int-cast -Os -Iinclude/
-Wl,--enable-stdcall-fixup -Wl,--entry=${MANGLE}WinDivertDllEntry"
CLIBS="-lkernel32 -ladvapi32 $MSVCRT"
CLIBS="-lkernel32 -ladvapi32 $EXTRA_OPTS"
STRIP="$ENV-strip"
DLLTOOL="$ENV-dlltool"
if [ -x "`which $CC`" ]
+1214 -1274
View File
File diff suppressed because it is too large Load Diff
+8 -6
View File
@@ -1,6 +1,6 @@
/*
* windivert.rc
* (C) 2019, all rights reserved,
* (C) 2022, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -35,23 +35,25 @@
#include <windows.h>
#include <ntverp.h>
#include "windivert_log.rc"
#define VER_FILETYPE VFT_DRV
#define VER_FILESUBTYPE VFT2_DRV_NETWORK
#define VER_FILEDESCRIPTION_STR \
"The WinDivert 2.0 driver " \
"The WinDivert 2.2 driver " \
"[URL: https://reqrypt.org/windivert.html] " \
"[Bitcoin: 1C5vZVSbizPeZ8ydTYhUfm4LA2cNwBfcYh]"
#define VER_INTERNALNAME_STR "WinDivert.sys"
#define VER_ORIGINALFILENAME_STR "WinDivert.sys"
#define VER_PRODUCTVERSION 2.1
#define VER_PRODUCTVERSION_STR "2.1"
#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
#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR
#define VER_PRODUCTNAME_STR "WinDivert 2.0 driver"
#define VER_PRODUCTNAME_STR "WinDivert 2.2 driver"
#include "common.ver"
+11 -2
View File
@@ -45,11 +45,20 @@
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<MessageCompile Include="windivert_log.mc">
<RCFilePath>.</RCFilePath>
<HeaderFilePath>.</HeaderFilePath>
</MessageCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="windivert.rc" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="windivert.c">
<TreatWarningAsError>false</TreatWarningAsError>
<Optimization>MaxSpeed</Optimization>
<AdditionalIncludeDirectories>..\include;..\dll</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\include;..\dll;.</AdditionalIncludeDirectories>
</ClCompile>
</ItemGroup>
<PropertyGroup Label="Globals">
@@ -60,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>
+59
View File
@@ -0,0 +1,59 @@
;/*
; * windivert_log.mc
; * (C) 2019, all rights reserved,
; *
; * This file is part of WinDivert.
; *
; * WinDivert is free software: you can redistribute it and/or modify it under
; * the terms of the GNU Lesser General Public License as published by the
; * Free Software Foundation, either version 3 of the License, or (at your
; * option) any later version.
; *
; * This program is distributed in the hope that it will be useful, but
; * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
; * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
; * License for more details.
; *
; * You should have received a copy of the GNU Lesser General Public License
; * along with this program. If not, see <http://www.gnu.org/licenses/>.
; *
; * WinDivert is free software; you can redistribute it and/or modify it under
; * the terms of the GNU General Public License as published by the Free
; * Software Foundation; either version 2 of the License, or (at your option)
; * any later version.
; *
; * This program is distributed in the hope that it will be useful, but
; * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
; * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
; * for more details.
; *
; * You should have received a copy of the GNU General Public License along
; * with this program; if not, write to the Free Software Foundation, Inc., 51
; * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
; */
MessageIdTypedef=NTSTATUS
SeverityNames = (
Success = 0x0:STATUS_SEVERITY_SUCCESS
Informational = 0x1:STATUS_SEVERITY_INFORMATIONAL
Warning = 0x2:STATUS_SEVERITY_WARNING
Error = 0x3:STATUS_SEVERITY_ERROR
)
FacilityNames = (
System = 0x0:FACILITY_SYSTEM
Runtime = 0x2:FACILITY_RUNTIME
Stubs = 0x3:FACILITY_STUBS
Io = 0x4:FACILITY_IO_ERROR_CODE
WinDivert = 0x574:FACILITY_WINDIVERT
)
MessageId=0x312D
Facility=WinDivert
Severity=Informational
SymbolicName=WINDIVERT_INFO_EVENT
Language=English
%2 %3 (processId=%4)
.
+102 -10
View File
@@ -1,6 +1,6 @@
/*
* test.c
* (C) 2019, all rights reserved,
* (C) 2021, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -43,6 +43,7 @@
#include "windivert.h"
#define MAX_PACKET 2048
#define MIN(a, b) ((a) < (b)? (a): (b))
/*
* Packet data.
@@ -112,6 +113,30 @@ static const struct packet pkt_ipv6_exthdrs_udp =
sizeof(ipv6_exthdrs_udp),
"ipv6_exthdrs_udp"
};
static const struct packet pkt_ipv4_fragment_0 =
{
ipv4_fragment_0,
sizeof(ipv4_fragment_0),
"ipv4_fragemnt_0"
};
static const struct packet pkt_ipv4_fragment_1 =
{
ipv4_fragment_1,
sizeof(ipv4_fragment_1),
"ipv4_fragment_1"
};
static const struct packet pkt_ipv6_fragment_0 =
{
ipv6_fragment_0,
sizeof(ipv6_fragment_0),
"ipv6_fragment_0"
};
static const struct packet pkt_ipv6_fragment_1 =
{
ipv6_fragment_1,
sizeof(ipv6_fragment_1),
"ipv6_fragment_1"
};
static const struct test tests[] =
{
{"event = PACKET", &pkt_echo_request, TRUE},
@@ -167,6 +192,7 @@ static const struct test tests[] =
&pkt_echo_request, TRUE},
{"(tcp? tcp.DstPort == 80: true) and (udp? udp.DstPort == 80: true)",
&pkt_echo_request, TRUE},
{"fragment", &pkt_echo_request, FALSE},
{"ip and ip and ip and ip and ip and " // Max filter length:
"ip and ip and ip and ip and ip and "
"ip and ip and ip and ip and ip and "
@@ -309,6 +335,9 @@ static const struct test tests[] =
{"localAddr == 10.0.0.1 && remoteAddr == 8.8.8.8 && localPort == 8 && "
"remotePort == 0 && protocol == 1", &pkt_echo_request, TRUE},
{"packet[0] == 0x45", &pkt_echo_request, TRUE},
{"ip.MF or ip.FragOff != 0", &pkt_echo_request, FALSE},
{"icmp.Body != 123 || icmp.Body == 123", &pkt_echo_request, TRUE},
{"length == 84 && ip.Length == 84", &pkt_echo_request, TRUE},
{"tcp", &pkt_http_request, TRUE},
{"protocol == TCP", &pkt_http_request, TRUE},
{"outbound and tcp and tcp.DstPort == 80", &pkt_http_request, TRUE},
@@ -603,6 +632,7 @@ static const struct test tests[] =
{"localAddr == 10.0.0.1 && remoteAddr == 8.8.4.4 && "
"localPort == 57413 && remotePort == 53 && protocol == 17",
&pkt_dns_request, TRUE},
{"ipv6.DstAddr >= ::", &pkt_dns_request, FALSE},
{"ipv6", &pkt_ipv6_tcp_syn, TRUE},
{"ip", &pkt_ipv6_tcp_syn, FALSE},
{"tcp.Syn", &pkt_ipv6_tcp_syn, TRUE},
@@ -720,9 +750,11 @@ static const struct test tests[] =
{"icmpv6.Body == 0x10720003", &pkt_ipv6_echo_reply, TRUE},
{"ipv6.DstAddr >= 1000", &pkt_ipv6_echo_reply, FALSE},
{"ipv6.DstAddr <= 1", &pkt_ipv6_echo_reply, TRUE},
{"length == 104 && ipv6.Length == 64", &pkt_ipv6_echo_reply, TRUE},
{"ip and !loopback and (outbound? tcp.DstPort == 80 or"
" tcp.DstPort == 443 or udp.DstPort == 53 :"
" icmp.Type == 11 and icmp.Code == 0)", &pkt_ipv6_echo_reply, FALSE},
{"fragment", &pkt_ipv6_echo_reply, FALSE},
{"random8 < 128", &pkt_ipv6_echo_reply, TRUE},
{"(random8 < 128? random16 < 0x8000: random32 < 0x80000000)",
&pkt_ipv6_echo_reply, TRUE},
@@ -784,6 +816,7 @@ static const struct test tests[] =
{"ipv6.SrcAddr != abcd::1", &pkt_ipv6_exthdrs_udp, TRUE},
{"ipv6.SrcAddr >= abcd::1", &pkt_ipv6_exthdrs_udp, FALSE},
{"ipv6.SrcAddr > abcd::1", &pkt_ipv6_exthdrs_udp, FALSE},
{"ipv6.DstAddr >= ::", &pkt_ipv6_exthdrs_udp, TRUE},
{"timestamp > -1", &pkt_ipv6_exthdrs_udp, TRUE},
{"udp.SrcPort == 4660 and udp.DstPort == 43690",
&pkt_ipv6_exthdrs_udp, TRUE},
@@ -855,12 +888,51 @@ static const struct test tests[] =
&pkt_ipv6_exthdrs_udp, FALSE},
{"localAddr == ::1 and remoteAddr == 1 and localPort == 4660 and "
"remotePort == 43690 and protocol == 17", &pkt_ipv6_exthdrs_udp, TRUE},
{"fragment", &pkt_ipv4_fragment_0, TRUE},
{"ip.MF or ip.FragOff != 0", &pkt_ipv4_fragment_0, TRUE},
{"icmp", &pkt_ipv4_fragment_0, TRUE},
{"icmp.Body != 123 || icmp.Body == 123", &pkt_ipv4_fragment_0, TRUE},
{"length == 84 || ip.Length == 84", &pkt_ipv4_fragment_0, FALSE},
{"ip.HdrLength == 5 and ip.TOS == 0 and ip.Length == 28 and "
"ip.Id == 0x1234 and ip.FragOff == 0 and ip.MF == 1 and ip.DF == 0 and "
"ip.TTL == 64 and ip.Protocol == 1 and ip.SrcAddr == 0xFFFF0A000001 and "
"ip.DstAddr == 0xFFFF08080808 and icmp.Type == 8 and icmp.Code == 0 and "
"icmp.Body == 0x0D560001", &pkt_ipv4_fragment_0, TRUE},
{"fragment", &pkt_ipv4_fragment_1, TRUE},
{"ip.MF or ip.FragOff != 0", &pkt_ipv4_fragment_1, TRUE},
{"icmp", &pkt_ipv4_fragment_1, FALSE},
{"icmp.Body != 123 || icmp.Body == 123", &pkt_ipv4_fragment_1, FALSE},
{"length == 84 || ip.Length == 84", &pkt_ipv4_fragment_1, FALSE},
{"ip.HdrLength == 5 and ip.TOS == 0 and ip.Length == 76 and "
"ip.Id == 0x1234 and ip.FragOff == 1 and ip.MF == 0 and ip.DF == 0 and "
"ip.TTL == 64 and ip.Protocol == 1 and ip.SrcAddr == 0xFFFF0A000001 and "
"ip.DstAddr == 0xFFFF08080808", &pkt_ipv4_fragment_1, TRUE},
{"fragment", &pkt_ipv6_fragment_0, TRUE},
{"icmpv6", &pkt_ipv6_fragment_0, TRUE},
{"length == 104 || ipv6.Length == 64", &pkt_ipv6_fragment_0, FALSE},
{"ipv6.TrafficClass == 0x00000000 and ipv6.FlowLabel == 0x0000 and "
"ipv6.Length == 32 and ipv6.NextHdr == 44 and ipv6.HopLimit == 31 and "
"ipv6.SrcAddr == 0:0:0:0:0:0:0:1 and ipv6.DstAddr == 0:0:0:0:0:0:0:1 and "
"icmpv6.Type == 129 and icmpv6.Code == 0 and icmpv6.Body == 0x10720003",
&pkt_ipv6_fragment_0, TRUE},
{"fragment", &pkt_ipv6_fragment_1, TRUE},
{"icmpv6", &pkt_ipv6_fragment_1, FALSE},
{"length == 104 || ipv6.Length == 64", &pkt_ipv6_fragment_1, FALSE},
{"ipv6.TrafficClass == 0x00000000 and ipv6.FlowLabel == 0x0000 and "
"ipv6.Length == 48 and ipv6.NextHdr == 44 and ipv6.HopLimit == 31 and "
"ipv6.SrcAddr == 0:0:0:0:0:0:0:1 and ipv6.DstAddr == 0:0:0:0:0:0:0:1",
&pkt_ipv6_fragment_1, TRUE},
};
/*
* Test range.
*/
static size_t lo = 0, hi = UINT_MAX;
/*
* Main.
*/
int main(void)
int main(int argc, char **argv)
{
HANDLE upper_handle, lower_handle;
HANDLE console, monitor;
@@ -869,6 +941,25 @@ int main(void)
LARGE_INTEGER freq;
UINT64 diff;
size_t i;
size_t num_tests = sizeof(tests) / sizeof(struct test), passed_tests;
switch (argc)
{
case 1:
break;
case 3:
lo = atoi(argv[1]);
hi = atoi(argv[2]);
if (hi >= lo)
{
break;
}
// Fallthrough
default:
fprintf(stderr, "usage: %s [low high]\n", argv[0]);
exit(EXIT_FAILURE);
}
hi = MIN(num_tests, hi);
// Open handles to:
// (1) stop normal traffic from interacting with the tests; and
@@ -902,8 +993,8 @@ int main(void)
Sleep(150);
// Run tests:
size_t num_tests = sizeof(tests) / sizeof(struct test), passed_tests = 0;
for (i = 0; i < num_tests; i++)
passed_tests = 0;
for (i = lo; i < num_tests && i <= hi; i++)
{
const char *filter = tests[i].filter;
const char *packet = tests[i].packet->packet;
@@ -961,10 +1052,10 @@ int main(void)
}
printf("\npassed = %.2f%%\n",
((double)passed_tests / (double)num_tests) * 100.0);
((double)passed_tests / (double)(hi - lo)) * 100.0);
first = TRUE;
for (i = 0; i < num_tests; i++)
for (i = lo; i < num_tests && i <= hi; i++)
{
const char *filter = tests[i].filter;
char *name = tests[i].packet->name;
@@ -1185,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);
@@ -1274,7 +1365,7 @@ static DWORD monitor_worker(LPVOID arg)
}
size_t num_tests = sizeof(tests) / sizeof(struct test);
for (i = 0; i < num_tests; i++)
for (i = lo; i < num_tests && i <= hi; i++)
{
// (1) Read the reflected filter:
WinDivertHelperCompileFilter(tests[i].filter, WINDIVERT_LAYER_NETWORK,
@@ -1326,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\", "
+53
View File
@@ -181,3 +181,56 @@ static const unsigned char ipv6_exthdrs_udp[] =
0x72, 0x6c, 0x64, 0x21, 0x01
};
// IPV4 FRAGMENT #0
static const unsigned char ipv4_fragment_0[] =
{
0x45, 0x00, 0x00, 0x1C, 0x12, 0x34, 0x20, 0x00,
0x40, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x01,
0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x3c, 0xd2,
0x0d, 0x56, 0x00, 0x01
};
// IPV4 FRAGMENT #1
static const unsigned char ipv4_fragment_1[] =
{
0x45, 0x00, 0x00, 0x4C, 0x12, 0x34, 0x00, 0x01,
0x40, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x01,
0x08, 0x08, 0x08, 0x08, 0x8b, 0xa6, 0x60, 0x54,
0x00, 0x00, 0x00, 0x00, 0xf9, 0x08, 0x0a, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13,
0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33,
0x34, 0x35, 0x36, 0x37
};
// IPV6 FRAGMENT #0
static const unsigned char ipv6_fragment_0[] =
{
0x60, 0x00, 0x00, 0x00, 0x00, 0x20, 0x2c, 0x1f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x3a, 0x00, 0x00, 0x01, 0xc7, 0xf6, 0xce, 0x53,
0x81, 0x00, 0x6e, 0xd6, 0x10, 0x72, 0x00, 0x03,
0xa4, 0xd5, 0x69, 0x54, 0x00, 0x00, 0x00, 0x00,
0xab, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
// IPV6 FRAGMENT #1
static const unsigned char ipv6_fragment_1[] =
{
0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x2c, 0x1f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x3a, 0x00, 0x00, 0x18, 0xc7, 0xf6, 0xce, 0x53,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
};