38 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
basil00 6501bec357 Make release script use MSVC build. 2019-08-05 07:47:53 +08:00
basil00 194d9afa1e Towards WinDivert version 2.1 release.
- inbounds/outbound now work for SOCKET layer.
- passthru.exe now uses MTU_MAX to prevent 122
  errors.
- Further header parsing code hardening.
- Fix bug where Reserved2 was not zeroed.
2019-08-04 08:11:43 +08:00
basil00 69e4edade7 Add new WINDIVERT_FLAG_FRAGMENTS flag (fix #191).
This flag only affects inbound packets at the
WINDIVERT_LAYER_NETWORK layer.

If set, the handle will capture IP fragments,
but not reassembled IP packets.

If unset (the default), the handle will capture
reassembled IP packets, but not IP fragments.
2019-08-02 08:32:50 +08:00
basil00 6eb82d08e0 Fix WinDivert 2.0 driver bugs.
- BSOD for incomplete transport headers (#202).
- Fix enforcement of wrong MTU.
- Fix missing endpoint handles for IPV6 flow
  layer.
2019-07-31 08:46:01 +08:00
26 changed files with 5195 additions and 3350 deletions
+21
View File
@@ -297,3 +297,24 @@ WinDivert 2.0.1-rc
- Rename the following functions for consistency:
* WinDivertHelperNtohIpv6Address -> WinDivertHelperNtohIPv6Address
* WinDivertHelperHtonIpv6Address -> WinDivertHelperHtonIPv6Address
WinDivert 2.1.0
- WinDivertOpen() now supports a new flag:
* WINDIVERT_FLAG_FRAGMENTS: If set, the handle will capture inbound IP
fragments, but not inbound reassembled IP packets. Otherwise, if not
set (the default), the handle will capture inbound reassembled IP
packets, but not inbound IP fragments. This flag only affects
inbound packets at the NETWORK layer.
- Filter fields inbound/outbound are now supported at the SOCKET layer.
- 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.0: 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.0.1-rc
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 -1406
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
+451 -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);
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))
{
+143 -57
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;
}
@@ -149,14 +241,9 @@ static DWORD passthru(LPVOID arg)
UINT8 *packet;
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 = (UINT8 *)malloc(batch * MTU);
packet = (UINT8 *)malloc(size);
addr = (WINDIVERT_ADDRESS *)malloc(batch * sizeof(WINDIVERT_ADDRESS));
if (packet == NULL || addr == NULL)
{
@@ -169,9 +256,8 @@ static DWORD passthru(LPVOID arg)
while (TRUE)
{
// Read a matching packet.
packet_len = batch * MTU;
addr_len = batch * sizeof(WINDIVERT_ADDRESS);
if (!WinDivertRecvEx(handle, packet, packet_len, &packet_len, 0,
addr_len = batch * sizeof(WINDIVERT_ADDRESS);
if (!WinDivertRecvEx(handle, packet, size, &packet_len, 0,
addr, &addr_len, NULL))
{
fprintf(stderr, "warning: failed to read 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);
+141 -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;
/*
@@ -195,6 +209,7 @@ typedef enum
#define WINDIVERT_FLAG_SEND_ONLY 0x0008
#define WINDIVERT_FLAG_WRITE_ONLY WINDIVERT_FLAG_SEND_ONLY
#define WINDIVERT_FLAG_NO_INSTALL 0x0010
#define WINDIVERT_FLAG_FRAGMENTS 0x0020
/*
* WinDivert parameters.
@@ -225,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,
@@ -234,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,
@@ -244,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,
@@ -257,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,
@@ -267,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,
@@ -280,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);
@@ -301,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);
@@ -335,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;
@@ -486,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
@@ -498,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,
@@ -509,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);
@@ -538,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);
@@ -546,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,
@@ -573,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,
@@ -591,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);
+20 -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,13 +38,13 @@
/*
* 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_MAJOR 3
#define WINDIVERT_VERSION_MINOR 0
#define WINDIVERT_MAGIC_DLL 0x4C4C447669645724ull
@@ -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
@@ -181,7 +195,8 @@
*/
#define WINDIVERT_FLAGS_ALL \
(WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_DROP | WINDIVERT_FLAG_RECV_ONLY |\
WINDIVERT_FLAG_SEND_ONLY | WINDIVERT_FLAG_NO_INSTALL)
WINDIVERT_FLAG_SEND_ONLY | WINDIVERT_FLAG_NO_INSTALL | \
WINDIVERT_FLAG_FRAGMENTS)
#define WINDIVERT_FLAGS_EXCLUDE(flags, flag1, flag2) \
(((flags) & ((flag1) | (flag2))) != ((flag1) | (flag2)))
#define WINDIVERT_FLAGS_VALID(flags) \
+1 -1
View File
@@ -4,7 +4,7 @@ Class = WFPCALLOUTS
ClassGuid = {57465043-616C-6C6F-7574-5F636C617373}
Provider = %Basil%
CatalogFile = WinDivert32.Cat
DriverVer = 01/01/2019,2.0.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 = 01/01/2019,2.0.0
DriverVer = 01/09/2022,2.2.2
[SourceDisksNames]
1 = %DiskName%
+6 -6
View File
@@ -33,7 +33,7 @@
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# Script for MinGW/Linux cross compilation.
# NOTE: run wddk-build.bat before this script.
# NOTE: run msvc-build.bat before this script.
set -e
@@ -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
@@ -57,16 +57,16 @@ do
MANGLE=
fi
HAVE_SYS=yes
if [ ! -d install/WDDK/$CPU ]
if [ ! -d install/MSVC/$CPU ]
then
echo "WARNING: missing WDDK build; run wddk-build.bat first"
echo "WARNING: missing MSVC build; run msvc-build.bat first"
HAVE_SYS=no
fi
echo "BUILD MINGW-$CPU"
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`" ]
@@ -121,7 +121,7 @@ do
if [ $HAVE_SYS = yes ]
then
echo "\tcopy install/MINGW/$CPU/WinDivert$BITS.sys..."
cp install/WDDK/$CPU/WinDivert$BITS.sys install/MINGW/$CPU
cp install/MSVC/$CPU/WinDivert$BITS.sys install/MINGW/$CPU
fi
else
echo "WARNING: $CC not found"
+1298 -1296
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.0
#define VER_PRODUCTVERSION_STR "2.0"
#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
};