53 Commits

Author SHA1 Message Date
basil00 02541ce1da WinDivert 2.0.1-rc bugfix release. 2019-07-06 08:23:06 +08:00
basil00 db7f80d26d PACKET macro is also valid for the FORWARD layer. 2019-06-18 09:11:16 +08:00
basil00 cedb929873 Bug fixes.
- Fix broken WinDivertCondExecFilter().  This
  caused some callouts to be needlessly installed.
- Fix broken WinDivertByteSwap128().
- Rename "Ipv6" -> "IPv6" to keep API consistent.
- Samples now use correct MTU.
2019-06-15 07:31:56 +08:00
basil00 5d62e2a938 Add a Visual Studio build system (fix #118).
Currently the VS build system targets VS2015, but
may also work for later versions (not tested).
To use:
- Download & install VS2015.
- Install WDK.
- Open a Developer Command Prompt.
- Run the msvc-build.bat script.
2019-04-19 09:52:36 +08:00
basil00 8c4bbf31c6 Fix #175 2019-04-10 07:37:45 +08:00
basil00 cb6d09f094 Update WinDivert release build script. 2019-03-26 22:05:54 +08:00
basil00 40a22f0cf5 Fix #168 2019-03-21 19:25:46 +08:00
basil00 e306d0058b WinDivert filter language improvements.
- Add "length" for total packet length.
- Add "timestamp" for timestamp filtering.
- All filter language numbers are now signed.
- Add new macros: TRUE, FALSE, TCP, UDP, ICMP &
  ICMPV6.
- Future-proof the WINDIVERT_FILTER struct.
2019-03-15 08:01:10 +08:00
basil00 d29688ea83 Redesign the WinDivert SOCKET layer.
- Socket (& flow) events are now associated with
  a endpointId/parentEndpointId pair that allows
  the tracking of socket operations.
- A single socket CLOSE event replaces the UNBIND
  and DISCONNECT events.
- A new flag addr.Sniffed indicates if the event
  was sniffed or not.  Some events (CLOSE) are
  always sniffed, regardless of the flags.
- All filter language numbers are now 128bit.
- socketdump.exe can now optionally block events.
2019-03-13 08:33:12 +08:00
basil00 4289e7ec2b Fix 64/32 driver & DLL compatibility. 2019-03-11 07:27:00 +08:00
basil00 36b118b2b0 Fix WinDivert service management.
DeleteService() must be called else the WinDivert
service will survive reboot.
2019-03-09 07:04:34 +08:00
basil00 2307347070 Use C-string-friendly chars for filter objects. 2019-03-08 09:24:31 +08:00
basil00 3d4f52e2c0 Cleanup the passthru sample program. 2019-03-08 09:23:41 +08:00
basil00 1cc17786e8 Add boundary tests 2019-03-08 09:22:34 +08:00
basil00 a5e525d436 WinDivert driver refactoring + bug fixes. 2019-03-08 09:17:52 +08:00
basil00 8baeda9ec7 WinDivert documentation tweaks. 2019-03-06 09:34:07 +08:00
basil00 20382a9a75 Reverse order of WinDivert handle priorities.
Higher values now correspond to higher
priorities.
2019-03-06 09:08:48 +08:00
basil00 81ce9b7f87 Build script fixes. 2019-03-05 08:46:14 +08:00
basil00 ec83681601 Fix filter flags & test suite. 2019-03-05 08:21:39 +08:00
basil00 8fcb4313b6 WinDivert 2.0 API, service & documentation fixes.
- Make WinDivertRecv() and WinDivertSend() arg
  ordering match the Ex versions.
- Put the WinDivertHelperParsePacket() protocol
  arg after the IP headers.
- WinDivert service handling is now protected by
  a mutex.
- Debug the "uninstall" command for windivertctl.
  It can now uninstall the WinDivert driver &
  not leave the WinDivert service in a "pending"
  state.
- Document WinDivert performance tips.
2019-03-04 08:42:34 +08:00
basil00 0028aa6fff Add an "uninstall" option to windivertctl.
This will kill all processes and uninstall the
WinDivert driver.
2019-03-03 07:58:46 +08:00
basil00 85141a231c Fix passthru performance bugs.
Using large fixed-size buffers adds significant
overheads.  Instead, scale the buffer to the
batch size.
2019-03-03 07:56:44 +08:00
basil00 34652660f5 Fix WinDivert release build script. 2019-03-03 07:56:01 +08:00
basil00 45e0ea4e12 Fix 32bit build. 2019-03-02 08:31:51 +08:00
basil00 d0e8106158 Update copyright year. 2019-03-02 08:20:19 +08:00
basil00 bb67daf2da Update WinDivert documentation. 2019-03-02 08:12:51 +08:00
basil00 eb75e63431 Add WINDIVERT_PARAM_VERSION_* parameters.
This makes it possible for the user application
to determine the exact driver version.

Also update documentation and tests.
2019-02-28 09:23:08 +08:00
basil00 c084c8239b WinDivert security improvements.
(1) WinDivert will now reference the PROCESS that
opened the handle, and will not deref until the
handle is closed & all corresponding REFLECT
events have been completed.  This means the OPEN
REFLECT event will always return a valid PID.

(2) The packet queue size now also accounts for
internal overheads.
2019-02-27 08:57:10 +08:00
basil00 7fa04945c0 Various WinDivert improvements.
- Add UNBIND/DISCONNECT events to the SOCKET
  layer.  These events can only be sniffed.
- Remove the RECV_PARTIAL flag.  The user
  application can just ignore the error code
  instead.
- WINDIVERT_ADDRESS is now 64bytes.  Some extra
  padding added for future-proofing.
- Ignore SOCKET-layer REAUTHORIZE.
- The REFLECT layer returns the filter object
  directly (no IPv4 "pseudo" packet).
2019-02-25 09:15:33 +08:00
basil00 32c5aa90f4 Redesign the WinDivert IOCTL interface.
The idea is to make future versions of the
WinDivert DLL compatible with older SYS and vice
versa.

The interface has also been streamlined so less
system calls are required when the handle is first
opened.
2019-02-23 09:38:18 +08:00
basil00 e33cc74527 Remove overlapped I/O from streamdump.
This just complicated the sample.  Furthermore,
it was unclear if the implementation was correct
anyway.
2019-02-21 09:13:31 +08:00
basil00 18dfc50557 Fix broken INF files 2019-02-21 09:09:05 +08:00
basil00 b7860e3ff5 Add a new WinDivertHelperDecrementTTL() function.
This function decrements the ip.TTL or
ipv6.HopLimit field.  For ipv4, it also updates
the checksum.

Also:
- Make WinDivertHelperParsePacket() work on a
  single packet unless the pNext parameters are
  provided.
- Update documentation.
2019-02-20 07:57:40 +08:00
basil00 d38563a31f More minor API improvements.
- Revert batching for
  WinDivertHelperCalcChecksums().
  All non-ParsePacket helper functions support a
  single packet only.  This is much simpler.
- WinDivertHelperCalcChecksums() now returns a
  simple BOOL.
- More WinDivertHelper*() functions set the error
  code.
2019-02-18 08:44:16 +08:00
basil00 ab50ffebd5 Minor API improvements.
- addr.Pseudo*Checksum flags replaced by simpler
  addr.*Checksum flags.
- WinDivertHelperParsePacket() can now handle
  batched packets.
- WinDivertHelperParsePacket() can now return the
  transport protocol.
- WinDivertHelperCalcChecksums() can now handle
  batched packets.
- WinDivertHelperCalcChecksums() now sets address
  checksum flags that were calculated.
- A bunch of WINDIVERT_* macros have been moved
  to windivert.h for windivert_device.h.
2019-02-17 11:08:10 +08:00
basil00 42bf883096 Update WinDivert documentation.
- Also partly modernize the html.
2019-02-17 09:22:08 +08:00
basil00 ed90600d1d Update WinDivert documentation. 2019-02-16 09:47:04 +08:00
basil00 805661d6f3 Update WinDivert documentation. 2019-02-15 08:48:14 +08:00
basil00 8601f07ce1 Update WinDivert documentation. 2019-02-14 09:16:41 +08:00
basil00 ea366e80c2 Update WinDivert documentation. 2019-02-13 09:06:07 +08:00
basil00 6a0dd00e39 Update WinDivert documentation. 2019-02-12 08:14:00 +08:00
basil00 1496a0fe06 Document WinDivert layers 2019-02-11 10:13:52 +08:00
basil00 5c9b473873 Document WinDivert filter language fields. 2019-01-29 08:36:45 +08:00
basil00 fa9229820c Document WinDivertHelperCompileFilter(). 2019-01-27 08:50:41 +08:00
basil00 74b806d042 Document WinDivertShutdown() 2019-01-25 10:06:10 +08:00
basil00 f941045b0f Update WinDivert CHANGELOG for v2.0 2019-01-18 09:27:44 +08:00
basil00 3b31737673 Start updating the CHANGELOG for version 2.0 2019-01-17 10:08:18 +08:00
basil00 22a5ad0996 Expand test suite & fix bugs. 2018-11-28 08:28:38 +08:00
basil00 2e334c9133 Fix bignum bug & add more tests. 2018-11-25 09:47:27 +08:00
basil00 1c76a7c522 Improve WinDivert test suite.
- More tests
- Monitor tests using REFLECT layer.
2018-11-24 08:23:01 +08:00
basil00 ebe1af330b Add "priority" filtering for the REFLECT layer. 2018-11-24 08:00:17 +08:00
basil00 1c4075ed51 Add a recv "fast-path" to help reduce overheads.
WinDivert will now process some packets in-band
if the queue is empty and there is a read
request.  When activated, this saves 1xcopy,
1x(de)allocation, and 1xcontext-switch, and
reduces latency from ~60usec to ~20usec on my
test system.
2018-11-21 07:57:49 +08:00
basil00 af91071a79 Merge pull request #162 from basil00/flow_layer
WinDivert 2.0
2018-11-19 07:30:41 +08:00
40 changed files with 7465 additions and 2622 deletions
+170 -2
View File
@@ -127,5 +127,173 @@ WinDivert 1.4.2
- Add workaround for pseudo checksum issue (see #134).
WinDivert 1.4.3
- WinDivert.dll no longer depends on MSVCRT*.dll.
WinDivert 1.4.4
- Optimize pseudo checksum calculation.
WinDivert 2.0.0-rc
- Add 3 new layers:
* WINDIVERT_LAYER_FLOW for tracking network "flow" events.
* WINDIVERT_LAYER_SOCKET for tracking "socket" events.
* WINDIVERT_LAYER_REFLECT for tracking WinDivert events.
- WINDIVERT_ADDRESS has been re-factored as follows:
* addr.Layer: The WINDIVERT_LAYER_* value for the handle.
* addr.Event: A WINDIVERT_EVENT_* value representing the event (see
below).
* addr.Sniffed: Indicates that the event was sniffed.
* addr.Outbound: Replaces addr.Direction.
* addr.IPv6: Indicates an IPv6 packet.
* addr.Network.IfIdx: Replaces addr.IfIdx.
* addr.Network.SubIfIdx: Replaces addr.SubIfIdx.
* addr.Flow.EndpointId: The endpoint ID of the flow.
* addr.Flow.ParentEndpointId: The parent endpoint ID of the flow.
* addr.Flow.ProcessId: The ID of process that created the flow.
* addr.Flow.LocalAddr: The flow's local address.
* addr.Flow.RemoteAddr: The flow's remote address.
* addr.Flow.LocalPort: The flow's local port.
* addr.Flow.RemotePort: The flow's remote port.
* addr.Flow.Protocol: The flow's protocol.
* addr.Socket.EndpointId: The endpoint ID of the operation.
* addr.Socket.ParentEndpointId: The parent endpoint ID of the operation.
* addr.Socket.ProcessId: The ID of process that created the socket.
* addr.Socket.LocalAddr: The socket's local address.
* addr.Socket.RemoteAddr: The socket's remote address.
* addr.Socket.LocalPort: The socket's local port.
* addr.Socket.RemotePort: The socket's remote port.
* addr.Socket.Protocol: The socket's protocol.
* addr.Reflect.ProcessId: The ID of process that created opened the
handle.
* addr.Reflect.Timestamp: The timestamp of the handle.
* addr.Reflect.Layer: The layer of the handle.
* addr.Reflect.Flags: The flags of the handle.
* addr.Reflect.Priority: The priority of the handle.
- The addr.Event field can take the following values:
* WINDIVERT_EVENT_NETWORK_PACKET: (NETWORK/NETWORK_FORWARD layers) a new
packet was diverted.
* WINDIVERT_EVENT_FLOW_ESTABLISHED: (FLOW layer) a new flow is
established.
* WINDIVERT_EVENT_FLOW_DELETED: (FLOW layer) an existing flow is
deleted.
* WINDIVERT_EVENT_SOCKET_BIND: (SOCKET layer) a socket bind()
operation occurred.
* WINDIVERT_EVENT_SOCKET_CONNECT: (SOCKET layer) a socket connect()
operation occurred.
* WINDIVERT_EVENT_SOCKET_LISTEN: (SOCKET layer) a socket listen()
operation occurred.
* WINDIVERT_EVENT_SOCKET_ACCEPT: (SOCKET layer) a socket accept()
operation occurred.
* WINDIVERT_EVENT_SOCKET_CLOSE: (SOCKET layer) a socket endpoint is
closed.
* WINDIVERT_EVENT_REFLECT_OPEN: (REFLECT layer) a WinDivertOpen()
operation occurred.
* WINDIVERT_EVENT_REFLECT_CLOSE: (REFLECT layer) a WinDivertClose()
operation occurred.
- The WinDivert filter language has been expanded with new fields:
* event: The event value.
* timestamp: The event timestamp.
* endpointId: (FLOW/SOCKET layers) the endpoint ID.
* parentEndpointId: (FLOW/SOCKET layers) the parent endpoint ID.
* processId: (FLOW/SOCKET/REFLECT layers) the process ID.
* localAddr: (NETWORK/NETWORK_FORWARD/FLOW/SOCKET layers) the local
address.
* localPort: (NETWORK/NETWORK_FORWARD/FLOW/SOCKET layers) the local
port.
* remoteAddr: (NETWORK/NETWORK_FORWARD/FLOW/SOCKET layers) the remote
address.
* remotePort: (NETWORK/NETWORK_FORWARD/FLOW/SOCKET layers) the remote
port.
* protocol: (NETWORK/NETWORK_FORWARD/FLOW/SOCKET layers) the protocol.
* priority: (REFLECT layer) the handle's priority.
* layer: (REFLECT layer) the handle's layer.
* random8: (NETWORK/NETWORK_FORWARD layers) an 8-bit pseudo random
number.
* random16: (NETWORK/NETWORK_FORWARD layers) a 16-bit pseudo random
number.
* random32: (NETWORK/NETWORK_FORWARD layers) a 32-bit pseudo random
number.
* length: (NETWORK/NETWORK_FORWARD layers) the packet length.
* zero: The value "0".
- The WinDivert filter language can now address packet/payload data for
the NETWORK/NETWORK_FORWARD layers:
* packet[i]: the ith packet byte.
* packet16[i]: the ith packet 16bit word.
* packet32[i]: the ith packet 32bit word.
* tcp.payload[i]: the ith TCP payload byte.
* tcp.payload16[i]: the ith TCP 16bit word.
* tcp.payload32[i]: the ith TCP 32bit word.
* udp.payload[i]: the ith UDP payload byte.
* udp.payload16[i]: the ith UDP 16bit word.
* udp.payload32[i]: the ith UDP 32bit word.
The index (i) can be:
* An ordinary integer representing word addressing.
* A 'b' decorated integer representing byte-level addressing.
Furthermore, the index can be:
* Positive, representing addressing from the start of the
packet/payload.
* Negative, representing addressing from the end of the packet/payload.
- The WinDivert filter language now supports several symbolic values:
* PACKET: (NETWORK/NETWORK_FORWARD layers) equal to
WINDIVERT_EVENT_NETWORK_PACKET
* ESTABLISHED: (FLOW layer) equal to WINDIVERT_EVENT_FLOW_ESTABLISHED.
* DELETED: (FLOW LAYER) equal to WINDIVERT_EVENT_FLOW_DELETED.
* BIND: (SOCKET layer) equal to WINDIVERT_EVENT_SOCKET_BIND.
* CONNECT: (SOCKET layer) equal to WINDIVERT_EVENT_SOCKET_CONNECT.
* LISTEN: (SOCKET layer) equal to WINDIVERT_EVENT_SOCKET_LISTEN.
* ACCEPT: (SOCKET layer) equal to WINDIVERT_EVENT_SOCKET_ACCEPT.
WINDIVERT_LAYER_NETWORK_FORWARD.
* CLOSE: (SOCKET layer) equal to WINDIVERT_EVENT_SOCKET_CLOSE.
* OPEN: (REFLECT layer) equal to WINDIVERT_EVENT_REFLECT_OPEN.
* CLOSE: (REFLECT layer) equal to WINDIVERT_EVENT_REFLECT_CLOSE.
* NETWORK: (REFLECT layer) equal to WINDIVERT_LAYER_NETWORK.
* NETWORK_FORWARD: (REFLECT layer) equal to
* FLOW: (REFLECT layer) equal to WINDIVERT_LAYER_FLOW.
* SOCKET: (REFLECT layer) equal to WINDIVERT_LAYER_SOCKET.
* REFLECT: (REFLECT layer) equal to WINDIVERT_LAYER_REFLECT.
* TRUE: equal to 1.
* FALSE: equal to 0.
* TCP: equal to IPPROTO_TCP (6).
* UDP: equal to IPPROTO_UDP (17).
* ICMP: equal to IPPROTO_ICMP (1).
* ICMPV6: equal to IPPROTO_ICMPV6 (58).
- WinDivertOpen() now supports several new flags:
* WINDIVERT_FLAG_RECV_ONLY/WINDIVERT_FLAG_READ_ONLY: The handle cannot
be used for send operations.
* WINDIVERT_FLAG_SEND_ONLY/WINDIVERT_FLAG_WRITE_ONLY: The handle cannot
be used for receive operations.
* WINDIVERT_FLAG_NO_INSTALL: If the WinDivert driver is not already
installed/loaded, then WinDivertOpen() will fail with an error.
- WinDivertRecvEx()/WinDivertSendEx() now support a "batch" mode that
allows more than one packet to be received/sent at once. The number
of packets is determined by a new pAddrLen/addrLen parameter.
- Add a new WinDivertShutdown() function that supports the following
modes:
* WINDIVERT_SHUTDOWN_RECV: Disable the queuing new packets.
* WINDIVERT_SHUTDOWN_SEND: Disable the sending of new packets.
* WINDIVERT_SHUTDOWN_BOTH: Equivalent to
(WINDIVERT_SHUTDOWN_RECV | WINDIVERT_SHUTDOWN_SEND).
- Add new "read-only" WinDivert parameters:
* WINDIVERT_PARAM_VERSION_MAJOR: Driver version (major).
* WINDIVERT_PARAM_VERSION_MINOR: Driver version (minor).
- Add a new WinDivertHelperHashPacket() helper function that calculates
a 64bit hash value of a packet.
- Add new WinDivertHelperFormatIPv4Address() and
WinDivertHelperFormatIPv6Address() helper functions that format
IPv4 and IPv6 addresses respectively.
- Replace WinDivertHelperCheckFilter() with a new
WinDivertHelperCompileFilter() helper function. The latter can also be
used to compile a human-readable filter string into a more compact
"object" format. The object format can be used in place of the
human readable format for all WinDivert operations.
- Add a new WinDivertHelperFormatFilter() helper function that formats a
filter string into a normalized form. It also can be used to
"de-compile" the object format into a human readable form.
- Add a new WinDivertHelperDecrementTTL() function that decrements the
ip.TTL/ipv6.HopLimit field of a packet.
- Add new WinDivertHelperNto*()/WinDivertHelperHton*() helper functions
for swapping from network to host byte ordering, and vice versa.
- WinDivertOpen() priorities now are ascending, meaning that higher
values correspond to higher priorities.
- The last two arguments for WinDivertRecv() and WinDivertSend() have been
swapped.
WinDivert 2.0.1-rc
- Fix WFP callout install optimization bug.
- Fix WinDivertHelperNtohIpv6Address/WinDivertHelperHtonIpv6Address bug.
- Rename the following functions for consistency:
* WinDivertHelperNtohIpv6Address -> WinDivertHelperNtohIPv6Address
* WinDivertHelperHtonIpv6Address -> WinDivertHelperHtonIPv6Address
+1 -1
View File
@@ -1 +1 @@
2.0.0
2.0.1-rc
+353 -201
View File
@@ -1,6 +1,6 @@
/*
* windivert.c
* (C) 2018, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -50,7 +50,13 @@
#define WINDIVERT_DRIVER_NAME L"WinDivert"
#define WINDIVERT_DRIVER32_SYS L"\\" WINDIVERT_DRIVER_NAME L"32.sys"
#define WINDIVERT_DRIVER64_SYS L"\\" WINDIVERT_DRIVER_NAME L"64.sys"
#define WINDIVERT_VERSION_MAJOR_MIN 2
#ifndef ERROR_DRIVER_FAILED_PRIOR_UNLOAD
#define ERROR_DRIVER_FAILED_PRIOR_UNLOAD ((DWORD)654)
#endif
static BOOLEAN WinDivertIsDigit(char c);
static BOOLEAN WinDivertIsXDigit(char c);
static BOOLEAN WinDivertIsSpace(char c);
static BOOLEAN WinDivertIsAlNum(char c);
@@ -60,8 +66,11 @@ static BOOLEAN WinDivertStrLen(const wchar_t *s, size_t maxlen,
static BOOLEAN WinDivertStrCpy(wchar_t *dst, size_t dstlen,
const wchar_t *src);
static int WinDivertStrCmp(const char *s, const char *t);
static BOOLEAN WinDivertAToI(const char *str, char **endptr, UINT32 *intptr);
static BOOLEAN WinDivertAToX(const char *str, char **endptr, UINT32 *intptr);
static BOOLEAN WinDivertAToI(const char *str, char **endptr, UINT32 *intptr,
UINT size);
static BOOLEAN WinDivertAToX(const char *str, char **endptr, UINT32 *intptr,
UINT size, BOOL prefix);
static UINT32 WinDivertDivTen128(UINT32 *a);
/*
* Misc.
@@ -69,21 +78,43 @@ static BOOLEAN WinDivertAToX(const char *str, char **endptr, UINT32 *intptr);
#ifndef UINT8_MAX
#define UINT8_MAX 0xFF
#endif
#ifndef UINT16_MAX
#define UINT16_MAX 0xFFFF
#endif
#ifndef UINT32_MAX
#define UINT32_MAX 0xFFFFFFFF
#endif
#ifdef _MSC_VER
#pragma intrinsic(memcpy)
#pragma function(memcpy)
void *memcpy(void *dst, const void *src, size_t n)
{
size_t i;
for (i = 0; i < n; i++)
((UINT8 *)dst)[i] = ((const UINT8 *)src)[i];
return dst;
}
#pragma intrinsic(memset)
#pragma function(memset)
void *memset(void *dst, int c, size_t n)
{
size_t i;
for (i = 0; i < n; i++)
((UINT8 *)dst)[i] = (UINT8)c;
return dst;
}
#endif
/*
* Prototypes.
*/
static BOOLEAN WinDivertUse32Bit(void);
static BOOLEAN WinDivertGetDriverFileName(LPWSTR sys_str);
static SC_HANDLE WinDivertDriverInstall(VOID);
static BOOL WinDivertIoControl(HANDLE handle, DWORD code, UINT64 arg1,
UINT64 arg2, PVOID buf, UINT len, UINT *iolen);
static BOOL WinDivertIoControlEx(HANDLE handle, DWORD code, UINT64 arg1,
UINT64 arg2, PVOID buf, UINT len, UINT *iolen, LPOVERLAPPED overlapped);
static UINT8 WinDivertSkipExtHeaders(UINT8 proto, UINT8 **header, UINT *len);
static BOOLEAN WinDivertDriverInstall(VOID);
/*
* Include the helper API implementation.
@@ -217,12 +248,28 @@ static BOOLEAN WinDivertGetDriverFileName(LPWSTR sys_str)
/*
* Install the WinDivert driver.
*/
static SC_HANDLE WinDivertDriverInstall(VOID)
static BOOLEAN WinDivertDriverInstall(VOID)
{
DWORD err, retries = 2;
DWORD err;
SC_HANDLE manager = NULL, service = NULL;
wchar_t windivert_sys[MAX_PATH+1];
SERVICE_STATUS status;
HANDLE mutex = NULL;
BOOL success = TRUE;
// Create & lock a named mutex. This is to stop two processes trying
// to start the driver at the same time.
mutex = CreateMutex(NULL, FALSE, L"WinDivertDriverInstallMutex");
if (mutex == NULL)
{
return FALSE;
}
switch (WaitForSingleObject(mutex, INFINITE))
{
case WAIT_OBJECT_0: case WAIT_ABANDONED:
break;
default:
return FALSE;
}
// Open the service manager:
manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
@@ -232,7 +279,6 @@ static SC_HANDLE WinDivertDriverInstall(VOID)
}
// Check if the WinDivert service already exists; if so, start it.
WinDivertDriverInstallReTry:
service = OpenService(manager, WINDIVERT_DEVICE_NAME, SERVICE_ALL_ACCESS);
if (service != NULL)
{
@@ -254,36 +300,29 @@ WinDivertDriverInstallReTry:
{
if (GetLastError() == ERROR_SERVICE_EXISTS)
{
if (retries != 0)
{
retries--;
goto WinDivertDriverInstallReTry;
}
service = OpenService(manager, WINDIVERT_DEVICE_NAME,
SERVICE_ALL_ACCESS);
}
goto WinDivertDriverInstallExit;
}
WinDivertDriverInstallExit:
success = (service != NULL);
if (service != NULL)
{
// Start the service:
if (!StartService(service, 0, NULL))
success = StartService(service, 0, NULL);
if (!success)
{
err = GetLastError();
if (err == ERROR_SERVICE_ALREADY_RUNNING)
{
SetLastError(0);
}
else
{
// Failed to start service; clean-up:
ControlService(service, SERVICE_CONTROL_STOP, &status);
DeleteService(service);
CloseServiceHandle(service);
service = NULL;
SetLastError(err);
}
success = (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING);
}
else
{
// Mark the service for deletion. This will cause the driver to
// unload if (1) there are no more open handles, and (2) the
// service is STOPPED or on system reboot.
(VOID)DeleteService(service);
}
}
@@ -292,16 +331,41 @@ WinDivertDriverInstallExit:
{
CloseServiceHandle(manager);
}
if (service != NULL)
{
CloseServiceHandle(service);
}
ReleaseMutex(mutex);
CloseHandle(mutex);
SetLastError(err);
return service;
return success;
}
/*
* Perform an (overlapped) DeviceIoControl.
*/
static BOOL WinDivertIoControlEx(HANDLE handle, DWORD code,
PWINDIVERT_IOCTL ioctl, PVOID buf, UINT len, UINT *iolen,
LPOVERLAPPED overlapped)
{
BOOL result;
DWORD iolen0;
result = DeviceIoControl(handle, code, ioctl, sizeof(WINDIVERT_IOCTL), buf,
(DWORD)len, &iolen0, overlapped);
if (result && iolen != NULL)
{
*iolen = (UINT)iolen0;
}
return result;
}
/*
* Perform a DeviceIoControl.
*/
static BOOL WinDivertIoControl(HANDLE handle, DWORD code, UINT64 arg1,
UINT64 arg2, PVOID buf, UINT len, UINT *iolen)
static BOOL WinDivertIoControl(HANDLE handle, DWORD code,
PWINDIVERT_IOCTL ioctl, PVOID buf, UINT len, UINT *iolen)
{
OVERLAPPED overlapped;
DWORD iolen0;
@@ -320,7 +384,7 @@ static BOOL WinDivertIoControl(HANDLE handle, DWORD code, UINT64 arg1,
memset(&overlapped, 0, sizeof(overlapped));
overlapped.hEvent = event;
if (!WinDivertIoControlEx(handle, code, arg1, arg2, buf, len, iolen,
if (!WinDivertIoControlEx(handle, code, ioctl, buf, len, iolen,
&overlapped))
{
if (GetLastError() != ERROR_IO_PENDING ||
@@ -336,42 +400,35 @@ static BOOL WinDivertIoControl(HANDLE handle, DWORD code, UINT64 arg1,
return TRUE;
}
/*
* Perform an (overlapped) DeviceIoControl.
*/
static BOOL WinDivertIoControlEx(HANDLE handle, DWORD code, UINT64 arg1,
UINT64 arg2, PVOID buf, UINT len, UINT *iolen, LPOVERLAPPED overlapped)
{
WINDIVERT_IOCTL ioctl;
BOOL result;
DWORD iolen0;
ioctl.arg1 = arg1;
ioctl.arg2 = arg2;
result = DeviceIoControl(handle, code, &ioctl, sizeof(ioctl), buf,
(DWORD)len, &iolen0, overlapped);
if (result && iolen != NULL)
{
*iolen = (UINT)iolen0;
}
return result;
}
/*
* Open a WinDivert handle.
*/
extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
INT16 priority, UINT64 flags)
{
WINDIVERT_FILTER object[WINDIVERT_FILTER_MAXLEN];
WINDIVERT_FILTER *object;
UINT obj_len;
ERROR comp_err;
DWORD err;
HANDLE handle;
SC_HANDLE service;
UINT64 priority64, filter_flags;
// Parameter checking.
HANDLE handle, pool;
UINT64 filter_flags;
WINDIVERT_IOCTL ioctl;
WINDIVERT_VERSION version;
// Static checks (should be compiled away if TRUE):
if (sizeof(WINDIVERT_ADDRESS) != 80 ||
sizeof(WINDIVERT_DATA_NETWORK) != 8 ||
offsetof(WINDIVERT_DATA_FLOW, Protocol) != 56 ||
offsetof(WINDIVERT_DATA_SOCKET, Protocol) != 56 ||
offsetof(WINDIVERT_DATA_REFLECT, Priority) != 24 ||
sizeof(WINDIVERT_FILTER) != 24 ||
offsetof(WINDIVERT_ADDRESS, Reserved3) != 16)
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
// Parameter checking:
switch (layer)
{
case WINDIVERT_LAYER_NETWORK:
@@ -398,9 +455,25 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
}
// Compile & analyze the filter:
comp_err = WinDivertCompileFilter(filter, layer, object, &obj_len);
pool = HeapCreate(HEAP_NO_SERIALIZE, WINDIVERT_MIN_POOL_SIZE,
WINDIVERT_MAX_POOL_SIZE);
if (pool == NULL)
{
return FALSE;
}
object = HeapAlloc(pool, 0,
WINDIVERT_FILTER_MAXLEN * sizeof(WINDIVERT_FILTER));
if (object == NULL)
{
err = GetLastError();
HeapDestroy(pool);
SetLastError(err);
return FALSE;
}
comp_err = WinDivertCompileFilter(filter, pool, layer, object, &obj_len);
if (IS_ERROR(comp_err))
{
HeapDestroy(pool);
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
@@ -415,82 +488,81 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
err = GetLastError();
if (err != ERROR_FILE_NOT_FOUND && err != ERROR_PATH_NOT_FOUND)
{
HeapDestroy(pool);
SetLastError(err);
return INVALID_HANDLE_VALUE;
}
// Open failed because the device isn't installed; install it now.
if ((flags & WINDIVERT_FLAG_NO_INSTALL) != 0)
{
HeapDestroy(pool);
SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
return INVALID_HANDLE_VALUE;
}
SetLastError(0);
service = WinDivertDriverInstall();
if (service == NULL)
if (!WinDivertDriverInstall())
{
if (GetLastError() == 0)
{
SetLastError(ERROR_OPEN_FAILED);
}
err = GetLastError();
err = (err == 0? ERROR_OPEN_FAILED: err);
HeapDestroy(pool);
SetLastError(err);
return INVALID_HANDLE_VALUE;
}
handle = CreateFile(L"\\\\.\\" WINDIVERT_DEVICE_NAME,
GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
INVALID_HANDLE_VALUE);
// Schedule the service to be deleted (once all handles are closed).
DeleteService(service);
CloseServiceHandle(service);
if (handle == INVALID_HANDLE_VALUE)
{
err = GetLastError();
HeapDestroy(pool);
SetLastError(err);
return INVALID_HANDLE_VALUE;
}
}
// Set the layer:
if (layer != WINDIVERT_LAYER_DEFAULT)
// Initialize the handle:
memset(&ioctl, 0, sizeof(ioctl));
ioctl.initialize.layer = layer;
ioctl.initialize.priority = (INT32)priority + WINDIVERT_PRIORITY_MAX;
ioctl.initialize.flags = flags;
memset(&version, 0, sizeof(version));
version.magic = WINDIVERT_MAGIC_DLL;
version.major = WINDIVERT_VERSION_MAJOR;
version.minor = WINDIVERT_VERSION_MINOR;
version.bits = 8 * sizeof(void *);
if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_INITIALIZE, &ioctl,
&version, sizeof(version), NULL))
{
if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_SET_LAYER,
(UINT64)layer, 0, NULL, 0, NULL))
{
CloseHandle(handle);
return INVALID_HANDLE_VALUE;
}
err = GetLastError();
CloseHandle(handle);
HeapDestroy(pool);
SetLastError(err);
return INVALID_HANDLE_VALUE;
}
// Set the flags:
if (flags != 0)
if (version.magic != WINDIVERT_MAGIC_SYS ||
version.major < WINDIVERT_VERSION_MAJOR_MIN)
{
if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_SET_FLAGS, flags, 0,
NULL, 0, NULL))
{
CloseHandle(handle);
return INVALID_HANDLE_VALUE;
}
}
// Set the priority:
if (priority != WINDIVERT_PRIORITY_DEFAULT)
{
// Make positive:
priority64 = (UINT64)((INT64)priority + WINDIVERT_PRIORITY_MAX);
if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_SET_PRIORITY,
priority64, 0, NULL, 0, NULL))
{
CloseHandle(handle);
return INVALID_HANDLE_VALUE;
}
CloseHandle(handle);
HeapDestroy(pool);
SetLastError(ERROR_DRIVER_FAILED_PRIOR_UNLOAD);
return INVALID_HANDLE_VALUE;
}
// Start the filter:
if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_START_FILTER,
filter_flags, 0, object, obj_len * sizeof(WINDIVERT_FILTER), NULL))
memset(&ioctl, 0, sizeof(ioctl));
ioctl.startup.flags = filter_flags;
if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_STARTUP, &ioctl,
object, obj_len * sizeof(WINDIVERT_FILTER), NULL))
{
err = GetLastError();
CloseHandle(handle);
HeapDestroy(pool);
SetLastError(err);
return INVALID_HANDLE_VALUE;
}
HeapDestroy(pool);
// Success!
return handle;
@@ -500,10 +572,14 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
* Receive a WinDivert packet.
*/
extern BOOL WinDivertRecv(HANDLE handle, PVOID pPacket, UINT packetLen,
PWINDIVERT_ADDRESS addr, UINT *readlen)
UINT *readLen, PWINDIVERT_ADDRESS addr)
{
return WinDivertIoControl(handle, IOCTL_WINDIVERT_RECV, (UINT64)addr,
(UINT64)NULL, pPacket, packetLen, readlen);
WINDIVERT_IOCTL ioctl;
memset(&ioctl, 0, sizeof(ioctl));
ioctl.recv.addr = (UINT64)addr;
ioctl.recv.addr_len_ptr = (UINT64)NULL;
return WinDivertIoControl(handle, IOCTL_WINDIVERT_RECV, &ioctl,
pPacket, packetLen, readLen);
}
/*
@@ -513,6 +589,10 @@ extern 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;
if (flags != 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
@@ -520,14 +600,13 @@ extern BOOL WinDivertRecvEx(HANDLE handle, PVOID pPacket, UINT packetLen,
}
if (overlapped == NULL)
{
return WinDivertIoControl(handle, IOCTL_WINDIVERT_RECV,
(UINT64)addr, (UINT64)pAddrLen, pPacket, packetLen, readLen);
return WinDivertIoControl(handle, IOCTL_WINDIVERT_RECV, &ioctl,
pPacket, packetLen, readLen);
}
else
{
return WinDivertIoControlEx(handle, IOCTL_WINDIVERT_RECV,
(UINT64)addr, (UINT64)pAddrLen, pPacket, packetLen, readLen,
overlapped);
return WinDivertIoControlEx(handle, IOCTL_WINDIVERT_RECV, &ioctl,
pPacket, packetLen, readLen, overlapped);
}
}
@@ -535,10 +614,14 @@ extern BOOL WinDivertRecvEx(HANDLE handle, PVOID pPacket, UINT packetLen,
* Send a WinDivert packet.
*/
extern BOOL WinDivertSend(HANDLE handle, const VOID *pPacket, UINT packetLen,
const WINDIVERT_ADDRESS *addr, UINT *writelen)
UINT *writeLen, const WINDIVERT_ADDRESS *addr)
{
return WinDivertIoControl(handle, IOCTL_WINDIVERT_SEND, (UINT64)addr,
sizeof(WINDIVERT_ADDRESS), (PVOID)pPacket, packetLen, writelen);
WINDIVERT_IOCTL ioctl;
memset(&ioctl, 0, sizeof(ioctl));
ioctl.send.addr = (UINT64)addr;
ioctl.send.addr_len = sizeof(WINDIVERT_ADDRESS);
return WinDivertIoControl(handle, IOCTL_WINDIVERT_SEND, &ioctl,
(PVOID)pPacket, packetLen, writeLen);
}
/*
@@ -548,6 +631,10 @@ extern 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_len = addrLen;
if (flags != 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
@@ -555,15 +642,13 @@ extern BOOL WinDivertSendEx(HANDLE handle, const VOID *pPacket, UINT packetLen,
}
if (overlapped == NULL)
{
return WinDivertIoControl(handle, IOCTL_WINDIVERT_SEND,
(UINT64)addr, (UINT64)addrLen, (PVOID)pPacket, packetLen,
writeLen);
return WinDivertIoControl(handle, IOCTL_WINDIVERT_SEND, &ioctl,
(PVOID)pPacket, packetLen, writeLen);
}
else
{
return WinDivertIoControlEx(handle, IOCTL_WINDIVERT_SEND,
(UINT64)addr, (UINT64)addrLen, (PVOID)pPacket, packetLen, writeLen,
overlapped);
return WinDivertIoControlEx(handle, IOCTL_WINDIVERT_SEND, &ioctl,
(PVOID)pPacket, packetLen, writeLen, overlapped);
}
}
@@ -572,8 +657,11 @@ extern BOOL WinDivertSendEx(HANDLE handle, const VOID *pPacket, UINT packetLen,
*/
extern BOOL WinDivertShutdown(HANDLE handle, WINDIVERT_SHUTDOWN how)
{
return WinDivertIoControl(handle, IOCTL_WINDIVERT_SHUTDOWN,
(UINT64)how, 0, NULL, 0, NULL);
WINDIVERT_IOCTL ioctl;
memset(&ioctl, 0, sizeof(ioctl));
ioctl.shutdown.how = (UINT32)how;
return WinDivertIoControl(handle, IOCTL_WINDIVERT_SHUTDOWN, &ioctl, NULL,
0, NULL);
}
/*
@@ -590,38 +678,12 @@ extern BOOL WinDivertClose(HANDLE handle)
extern BOOL WinDivertSetParam(HANDLE handle, WINDIVERT_PARAM param,
UINT64 value)
{
switch ((int)param)
{
case WINDIVERT_PARAM_QUEUE_LEN:
if (value < WINDIVERT_PARAM_QUEUE_LEN_MIN ||
value > WINDIVERT_PARAM_QUEUE_LEN_MAX)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case WINDIVERT_PARAM_QUEUE_TIME:
if (value < WINDIVERT_PARAM_QUEUE_TIME_MIN ||
value > WINDIVERT_PARAM_QUEUE_TIME_MAX)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case WINDIVERT_PARAM_QUEUE_SIZE:
if (value < WINDIVERT_PARAM_QUEUE_SIZE_MIN ||
value > WINDIVERT_PARAM_QUEUE_SIZE_MAX)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
return WinDivertIoControl(handle, IOCTL_WINDIVERT_SET_PARAM, (UINT8)param,
value, NULL, 0, NULL);
WINDIVERT_IOCTL ioctl;
memset(&ioctl, 0, sizeof(ioctl));
ioctl.set_param.param = (UINT32)param;
ioctl.set_param.val = value;
return WinDivertIoControl(handle, IOCTL_WINDIVERT_SET_PARAM, &ioctl, NULL,
0, NULL);
}
/*
@@ -630,22 +692,22 @@ extern BOOL WinDivertSetParam(HANDLE handle, WINDIVERT_PARAM param,
extern BOOL WinDivertGetParam(HANDLE handle, WINDIVERT_PARAM param,
UINT64 *pValue)
{
switch ((int)param)
{
case WINDIVERT_PARAM_QUEUE_LEN: case WINDIVERT_PARAM_QUEUE_TIME:
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
return WinDivertIoControl(handle, IOCTL_WINDIVERT_GET_PARAM, (UINT8)param,
0, pValue, sizeof(UINT64), NULL);
WINDIVERT_IOCTL ioctl;
memset(&ioctl, 0, sizeof(ioctl));
ioctl.get_param.param = (UINT32)param;
return WinDivertIoControl(handle, IOCTL_WINDIVERT_GET_PARAM, &ioctl,
pValue, sizeof(UINT64), NULL);
}
/*****************************************************************************/
/* REPLACEMENTS */
/*****************************************************************************/
static BOOLEAN WinDivertIsDigit(char c)
{
return (c >= '0' && c <= '9');
}
static BOOLEAN WinDivertIsXDigit(char c)
{
return (c >= '0' && c <= '9') ||
@@ -725,66 +787,156 @@ static int WinDivertStrCmp(const char *s, const char *t)
}
}
static BOOLEAN WinDivertAToI(const char *str, char **endptr, UINT32 *intptr)
static BOOLEAN WinDivertMul128(UINT32 *n, UINT32 m)
{
UINT64 n64 = (UINT64)n[0] * (UINT64)m;
n[0] = (UINT32)n64;
n64 = (UINT64)n[1] * (UINT64)m + (n64 >> 32);
n[1] = (UINT32)n64;
n64 = (UINT64)n[2] * (UINT64)m + (n64 >> 32);
n[2] = (UINT32)n64;
n64 = (UINT64)n[3] * (UINT64)m + (n64 >> 32);
n[3] = (UINT32)n64;
return ((n64 >> 32) == 0);
}
static BOOLEAN WinDivertAdd128(UINT32 *n, UINT32 a)
{
UINT64 n64 = (UINT64)n[0] + (UINT64)a;
n[0] = (UINT32)n64;
n64 = (UINT64)n[1] + (n64 >> 32);
n[1] = (UINT32)n64;
n64 = (UINT64)n[2] + (n64 >> 32);
n[2] = (UINT32)n64;
n64 = (UINT64)n[3] + (n64 >> 32);
n[3] = (UINT32)n64;
return ((n64 >> 32) == 0);
}
static BOOLEAN WinDivertAToI(const char *str, char **endptr, UINT32 *intptr,
UINT size)
{
size_t i = 0;
UINT32 num = 0, num0;
if (str[i] == '\0')
UINT32 n[4] = {0};
BOOLEAN result = TRUE;
for (; str[i] && WinDivertIsDigit(str[i]); i++)
{
return FALSE;
}
for (; str[i] && isdigit(str[i]); i++)
{
num0 = num;
num *= 10;
num += (UINT32)(str[i] - '0');
if (num0 > num)
if (!WinDivertMul128(n, 10) || !WinDivertAdd128(n, str[i] - '0'))
{
return FALSE;
}
}
if (i == 0)
{
return FALSE;
}
if (endptr != NULL)
{
*endptr = (char *)str + i;
}
*intptr = num;
return TRUE;
for (i = 0; i < size; i++)
{
intptr[i] = n[i];
}
for (; result && i < size && i < 4; i++)
{
result = result && (n[i] == 0);
}
return result;
}
static BOOLEAN WinDivertAToX(const char *str, char **endptr, UINT32 *intptr)
static BOOLEAN WinDivertAToX(const char *str, char **endptr, UINT32 *intptr,
UINT size, BOOL prefix)
{
size_t i = 0;
UINT32 num = 0, num0;
if (str[i] == '\0')
UINT32 n[4] = {0}, dig;
BOOLEAN result = TRUE;
if (prefix)
{
return FALSE;
}
if (str[i] == '0' && str[i+1] == 'x')
{
i += 2;
}
for (; str[i] && WinDivertIsXDigit(str[i]); i++)
{
num0 = num;
num *= 16;
if (isdigit(str[i]))
if (str[i] == '0' && str[i+1] == 'x')
{
num += (UINT32)(str[i] - '0');
i += 2;
}
else
{
num += (UINT32)(WinDivertToLower(str[i]) - 'a') + 0x0A;
return FALSE;
}
if (num0 > num)
}
for (; str[i] && WinDivertIsXDigit(str[i]); i++)
{
if (WinDivertIsDigit(str[i]))
{
dig = (UINT32)(str[i] - '0');
}
else
{
dig = (UINT32)(WinDivertToLower(str[i]) - 'a') + 0x0A;
}
if (!WinDivertMul128(n, 16) || !WinDivertAdd128(n, dig))
{
return FALSE;
}
}
if (i == 0)
{
return FALSE;
}
if (endptr != NULL)
{
*endptr = (char *)str + i;
}
*intptr = num;
return TRUE;
for (i = 0; i < size; i++)
{
intptr[i] = n[i];
}
for (; result && i < size && i < 4; i++)
{
result = result && (n[i] == 0);
}
return result;
}
/*
* Divide by 10 and return the remainder.
*/
#define WINDIVERT_BIG_MUL_ROUND(a, c, r, i) \
do { \
UINT64 t = WINDIVERT_MUL64((UINT64)(a), (UINT64)(c)); \
UINT k; \
for (k = (i); k < 9 && t != 0; k++) \
{ \
UINT64 s = (UINT64)(r)[k] + (t & 0xFFFFFFFF); \
(r)[k] = (UINT32)s; \
t = (t >> 32) + (s >> 32); \
} \
} while (FALSE)
static UINT32 WinDivertDivTen128(UINT32 *a)
{
const UINT32 c[5] =
{
0x9999999A, 0x99999999, 0x99999999, 0x99999999, 0x19999999
};
UINT32 r[9] = {0}, m[6] = {0};
UINT i, j;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 5; j++)
{
WINDIVERT_BIG_MUL_ROUND(a[i], c[j], r, i+j);
}
}
a[0] = r[5];
a[1] = r[6];
a[2] = r[7];
a[3] = r[8];
for (i = 0; i < 5; i++)
{
WINDIVERT_BIG_MUL_ROUND(r[i], 10, m, i);
}
return m[5];
}
+3 -1
View File
@@ -1,6 +1,5 @@
LIBRARY WinDivert
EXPORTS
WinDivertDllEntry
WinDivertOpen
WinDivertRecv
WinDivertRecvEx
@@ -11,6 +10,7 @@ EXPORTS
WinDivertSetParam
WinDivertGetParam
WinDivertHelperCalcChecksums
WinDivertHelperDecrementTTL
WinDivertHelperHashPacket
WinDivertHelperParsePacket
WinDivertHelperParseIPv4Address
@@ -26,5 +26,7 @@ EXPORTS
WinDivertHelperHtonl
WinDivertHelperNtohll
WinDivertHelperHtonll
WinDivertHelperNtohIPv6Address
WinDivertHelperHtonIPv6Address
WinDivertHelperNtohIpv6Address
WinDivertHelperHtonIpv6Address
+84
View File
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
windivert.vcxproj
(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.
-->
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="windivert.c">
<TreatWarningAsError>false</TreatWarningAsError>
<Optimization>MinSpace</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<BufferSecurityCheck>false</BufferSecurityCheck>
<AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
</ClCompile>
</ItemGroup>
<PropertyGroup Label="Globals">
<RootNamespace>WinDivert</RootNamespace>
<ProjectName>WinDivert</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
<UseDebugLibraries>true</UseDebugLibraries>
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ItemDefinitionGroup>
<ClCompile>
<WppEnabled>false</WppEnabled>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<EntryPointSymbol>WinDivertDllEntry</EntryPointSymbol>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>windivert.def</ModuleDefinitionFile>
<ImportLibrary>WinDivert.lib</ImportLibrary>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
+33 -33
View File
@@ -1,6 +1,6 @@
/*
* windivert_hash.c
* (C) 2018, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -31,33 +31,33 @@
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* xxHash - Fast Hash algorithm
* Copyright (C) 2012-2016, Yann Collet
* xxHash - Fast Hash algorithm
* Copyright (C) 2012-2016, Yann Collet
*
* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
@@ -68,7 +68,7 @@
* only ever a single round. As such, the algorithm has been specialized.
*/
#define WINDIVERT_ROTL(x, r) (((x) << (r)) | ((x) >> (64 - (r))))
#define WINDIVERT_ROTL64(x, r) (((x) << (r)) | ((x) >> (64 - (r))))
static const UINT64 WINDIVERT_PRIME64_1 = 11400714785074694791ull;
static const UINT64 WINDIVERT_PRIME64_2 = 14029467366897019727ull;
@@ -77,9 +77,9 @@ static const UINT64 WINDIVERT_PRIME64_4 = 9650029242287828579ull;
static UINT64 WinDivertXXH64Round(UINT64 acc, UINT64 input)
{
acc += input * WINDIVERT_PRIME64_2;
acc = WINDIVERT_ROTL(acc, 31);
acc *= WINDIVERT_PRIME64_1;
acc += WINDIVERT_MUL64(input, WINDIVERT_PRIME64_2);
acc = WINDIVERT_ROTL64(acc, 31);
acc = WINDIVERT_MUL64(acc, WINDIVERT_PRIME64_1);
return acc;
}
@@ -87,16 +87,16 @@ static UINT64 WinDivertXXH64MergeRound(UINT64 acc, UINT64 val)
{
val = WinDivertXXH64Round(0, val);
acc ^= val;
acc = acc * WINDIVERT_PRIME64_1 + WINDIVERT_PRIME64_4;
acc = WINDIVERT_MUL64(acc, WINDIVERT_PRIME64_1) + WINDIVERT_PRIME64_4;
return acc;
}
static UINT64 WinDivertXXH64Avalanche(UINT64 h64)
{
h64 ^= h64 >> 33;
h64 *= WINDIVERT_PRIME64_2;
h64 = WINDIVERT_MUL64(h64, WINDIVERT_PRIME64_2);
h64 ^= h64 >> 29;
h64 *= WINDIVERT_PRIME64_3;
h64 = WINDIVERT_MUL64(h64, WINDIVERT_PRIME64_3);
h64 ^= h64 >> 32;
return h64;
}
@@ -187,8 +187,8 @@ static UINT64 WinDivertHashPacket(UINT64 seed, PWINDIVERT_IPHDR ip_header,
v2 = WinDivertXXH64Round(v[1], v2);
v3 = WinDivertXXH64Round(v[2], v3);
v4 = WinDivertXXH64Round(v[3], v4);
h64 = WINDIVERT_ROTL(v1, 1) + WINDIVERT_ROTL(v2, 7) +
WINDIVERT_ROTL(v3, 12) + WINDIVERT_ROTL(v4, 18);
h64 = WINDIVERT_ROTL64(v1, 1) + WINDIVERT_ROTL64(v2, 7) +
WINDIVERT_ROTL64(v3, 12) + WINDIVERT_ROTL64(v4, 18);
h64 = WinDivertXXH64MergeRound(h64, v1);
h64 = WinDivertXXH64MergeRound(h64, v2);
h64 = WinDivertXXH64MergeRound(h64, v3);
+753 -264
View File
File diff suppressed because it is too large Load Diff
+217 -101
View File
@@ -1,6 +1,6 @@
/*
* windivert_shared.c
* (C) 2018, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -33,7 +33,7 @@
*/
#define WINDIVERT_OBJECT_MAXLEN \
(8 + 4 + 2 + WINDIVERT_FILTER_MAXLEN * (1 + 2 + 2 + 4*7 + 2 + 2) + 1)
(8 + 4 + 2 + WINDIVERT_FILTER_MAXLEN * (1 + 1 + 2 + 2 + 4*7 + 3 + 3) + 1)
#define MAX(a, b) ((a) > (b)? (a): (b))
@@ -41,10 +41,10 @@
* Definitions to remove (some) external dependencies:
*/
#define BYTESWAP16(x) \
((((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00))
((((x) >> 8) & 0x00FFu) | (((x) << 8) & 0xFF00u))
#define BYTESWAP32(x) \
((((x) >> 24) & 0x000000FF) | (((x) >> 8) & 0x0000FF00) | \
(((x) << 8) & 0x00FF0000) | (((x) << 24) & 0xFF000000))
((((x) >> 24) & 0x000000FFu) | (((x) >> 8) & 0x0000FF00u) | \
(((x) << 8) & 0x00FF0000u) | (((x) << 24) & 0xFF000000u))
#define BYTESWAP64(x) \
((((x) >> 56) & 0x00000000000000FFull) | \
(((x) >> 40) & 0x000000000000FF00ull) | \
@@ -59,6 +59,20 @@
#define ntohl(x) BYTESWAP32(x)
#define htonl(x) BYTESWAP32(x)
#if defined(WIN32) && defined(_MSC_VER)
#pragma intrinsic(__emulu)
static UINT64 WinDivertMul64(UINT64 a, UINT64 b)
{
UINT64 r = __emulu((UINT32)a, (UINT32)b);
r += __emulu((UINT32)(a >> 32), (UINT32)b) << 32;
r += __emulu((UINT32)a, (UINT32)(b >> 32)) << 32;
return r;
}
#define WINDIVERT_MUL64(a, b) WinDivertMul64(a, b)
#else /* WIN32 */
#define WINDIVERT_MUL64(a, b) ((a) * (b))
#endif /* WIN32 */
#include "windivert_hash.c"
/*
@@ -143,35 +157,65 @@ static void WinDivertPutNul(PWINDIVERT_STREAM stream)
}
}
/*
* Encode a digit.
*/
static char WinDivertEncodeDigit(UINT8 dig, BOOL final)
{
static const char windivert_digits[64+1] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+=";
return windivert_digits[(dig & 0x1F) + (final? 32: 0)];
}
/*
* Serialize a number.
*/
static void WinDivertSerializeNumber(PWINDIVERT_STREAM stream, UINT32 val)
{
UINT64 mask = 0x00000007C0000000ull;
UINT32 mask = 0xC0000000;
UINT dig = 6;
UINT64 val64 = (UINT64)val;
UINT8 digit;
BOOL final;
while ((mask & val64) == 0 && dig != 0)
while ((mask & val) == 0 && dig != 0)
{
mask >>= 5;
mask = (dig == 6? 0x3E000000: mask >> 5);
dig--;
}
while (TRUE)
{
final = (dig == 0);
WinDivertPutChar(stream, '!' + (char)((mask & val64) >> (5 * dig)) +
(final? 32: 0));
digit = (UINT8)((mask & val) >> (5 * dig));
WinDivertPutChar(stream, WinDivertEncodeDigit(digit, final));
if (final)
{
break;
}
mask >>= 5;
mask = (dig == 6? 0x3E000000: mask >> 5);
dig--;
}
}
/*
* Serialize a label.
*/
static void WinDivertSerializeLabel(PWINDIVERT_STREAM stream, UINT16 label)
{
switch (label)
{
case WINDIVERT_FILTER_RESULT_ACCEPT:
WinDivertPutChar(stream, 'A');
break;
case WINDIVERT_FILTER_RESULT_REJECT:
WinDivertPutChar(stream, 'X');
break;
default:
WinDivertPutChar(stream, 'L');
WinDivertSerializeNumber(stream, label);
break;
}
}
/*
* Serialize a test.
*/
@@ -184,6 +228,7 @@ static void WinDivertSerializeTest(PWINDIVERT_STREAM stream,
WinDivertPutChar(stream, '_');
WinDivertSerializeNumber(stream, filter->field);
WinDivertSerializeNumber(stream, filter->test);
WinDivertSerializeNumber(stream, filter->neg);
WinDivertSerializeNumber(stream, filter->arg[0]);
switch (filter->field)
{
@@ -196,6 +241,11 @@ static void WinDivertSerializeTest(PWINDIVERT_STREAM stream,
WinDivertSerializeNumber(stream, filter->arg[i]);
}
break;
case WINDIVERT_FILTER_FIELD_ENDPOINTID:
case WINDIVERT_FILTER_FIELD_PARENTENDPOINTID:
case WINDIVERT_FILTER_FIELD_TIMESTAMP:
WinDivertSerializeNumber(stream, filter->arg[1]);
break;
case WINDIVERT_FILTER_FIELD_PACKET:
case WINDIVERT_FILTER_FIELD_PACKET16:
case WINDIVERT_FILTER_FIELD_PACKET32:
@@ -212,8 +262,8 @@ static void WinDivertSerializeTest(PWINDIVERT_STREAM stream,
default:
break;
}
WinDivertSerializeNumber(stream, (UINT8)(filter->success + 2));
WinDivertSerializeNumber(stream, (UINT8)(filter->failure + 2));
WinDivertSerializeLabel(stream, (UINT16)filter->success);
WinDivertSerializeLabel(stream, (UINT16)filter->failure);
}
/*
@@ -283,11 +333,11 @@ static UINT8 WinDivertSkipExtHeaders(UINT8 proto, UINT8 **header, UINT *len)
/*
* Parse IPv4/IPv6/ICMP/ICMPv6/TCP/UDP headers from a raw packet.
*/
static BOOL WinDivertParsePacket(PVOID pPacket, UINT packetLen,
PWINDIVERT_IPHDR *ppIpHdr, PWINDIVERT_IPV6HDR *ppIpv6Hdr,
extern BOOL WinDivertHelperParsePacket(const VOID *pPacket, UINT packetLen,
PWINDIVERT_IPHDR *ppIpHdr, PWINDIVERT_IPV6HDR *ppIpv6Hdr, UINT8 *pProtocol,
PWINDIVERT_ICMPHDR *ppIcmpHdr, PWINDIVERT_ICMPV6HDR *ppIcmpv6Hdr,
PWINDIVERT_TCPHDR *ppTcpHdr, PWINDIVERT_UDPHDR *ppUdpHdr, UINT8 *pProto,
PVOID *ppData, UINT *pDataLen)
PWINDIVERT_TCPHDR *ppTcpHdr, PWINDIVERT_UDPHDR *ppUdpHdr, PVOID *ppData,
UINT *pDataLen, PVOID *ppNext, UINT *pNextLen)
{
PWINDIVERT_IPHDR ip_header = NULL;
PWINDIVERT_IPV6HDR ipv6_header = NULL;
@@ -296,16 +346,16 @@ static BOOL WinDivertParsePacket(PVOID pPacket, UINT packetLen,
PWINDIVERT_TCPHDR tcp_header = NULL;
PWINDIVERT_UDPHDR udp_header = NULL;
UINT16 header_len;
UINT8 trans_proto = 0;
PVOID data = NULL;
UINT data_len = 0;
BOOL success;
UINT8 protocol = 0;
PVOID data = NULL, next = NULL;
UINT data_len = 0, next_len = 0, packet_len;
BOOL success = FALSE;
if (pPacket == NULL || packetLen < sizeof(UINT8))
if (pPacket == NULL || packetLen < sizeof(WINDIVERT_IPHDR))
{
goto WinDivertHelperParsePacketExit;
}
data = pPacket;
data = (PVOID)pPacket;
data_len = packetLen;
ip_header = (PWINDIVERT_IPHDR)data;
@@ -313,39 +363,57 @@ static BOOL WinDivertParsePacket(PVOID pPacket, UINT packetLen,
{
case 4:
if (data_len < sizeof(WINDIVERT_IPHDR) ||
ip_header->HdrLength < 5 ||
data_len < ip_header->HdrLength*sizeof(UINT32) ||
ntohs(ip_header->Length) != data_len)
ip_header->HdrLength < 5)
{
ip_header = NULL;
goto WinDivertHelperParsePacketExit;
}
trans_proto = ip_header->Protocol;
packet_len = (UINT)ntohs(ip_header->Length);
header_len = ip_header->HdrLength*sizeof(UINT32);
protocol = ip_header->Protocol;
if (data_len < header_len || data_len < packet_len ||
packet_len < header_len)
{
ip_header = NULL;
goto WinDivertHelperParsePacketExit;
}
else if (packet_len < data_len)
{
next = (PVOID)((UINT8 *)data + packet_len);
next_len = data_len - packet_len;
}
data = (PVOID)((UINT8 *)data + header_len);
data_len -= header_len;
data_len = packet_len - header_len;
break;
case 6:
ip_header = NULL;
ipv6_header = (PWINDIVERT_IPV6HDR)data;
if (data_len < sizeof(WINDIVERT_IPV6HDR) ||
ntohs(ipv6_header->Length) !=
data_len - sizeof(WINDIVERT_IPV6HDR))
data_len < ntohs(ipv6_header->Length) +
sizeof(WINDIVERT_IPV6HDR))
{
ipv6_header = NULL;
goto WinDivertHelperParsePacketExit;
}
trans_proto = ipv6_header->NextHdr;
protocol = ipv6_header->NextHdr;
packet_len = ntohs(ipv6_header->Length) + sizeof(WINDIVERT_IPV6HDR);
if (packet_len < data_len)
{
next = (PVOID)((UINT8 *)data + packet_len);
next_len = data_len - packet_len;
}
data = (PVOID)((UINT8 *)data + sizeof(WINDIVERT_IPV6HDR));
data_len -= sizeof(WINDIVERT_IPV6HDR);
trans_proto = WinDivertSkipExtHeaders(trans_proto, (UINT8 **)&data,
data_len = packet_len - sizeof(WINDIVERT_IPV6HDR);
protocol = WinDivertSkipExtHeaders(protocol, (UINT8 **)&data,
&data_len);
break;
default:
ip_header = NULL;
goto WinDivertHelperParsePacketExit;
}
switch (trans_proto)
data = (data_len == 0? NULL: data);
success = TRUE;
switch (protocol)
{
case IPPROTO_TCP:
tcp_header = (PWINDIVERT_TCPHDR)data;
@@ -403,58 +471,64 @@ static BOOL WinDivertParsePacket(PVOID pPacket, UINT packetLen,
}
WinDivertHelperParsePacketExit:
success = TRUE;
if (pProtocol != NULL)
{
*pProtocol = protocol;
}
if (ppIpHdr != NULL)
{
*ppIpHdr = ip_header;
success = success && (ip_header != NULL);
}
if (ppIpv6Hdr != NULL)
{
*ppIpv6Hdr = ipv6_header;
success = success && (ipv6_header != NULL);
}
if (ppIcmpHdr != NULL)
{
*ppIcmpHdr = icmp_header;
success = success && (icmp_header != NULL);
}
if (ppIcmpv6Hdr != NULL)
{
*ppIcmpv6Hdr = icmpv6_header;
success = success && (icmpv6_header != NULL);
}
if (ppTcpHdr != NULL)
{
*ppTcpHdr = tcp_header;
success = success && (tcp_header != NULL);
}
if (ppUdpHdr != NULL)
{
*ppUdpHdr = udp_header;
success = success && (udp_header != NULL);
}
if (pProto != NULL)
{
*pProto = trans_proto;
}
if (ppData != NULL)
{
*ppData = data;
success = success && (data != NULL);
}
if (pDataLen != NULL)
{
*pDataLen = data_len;
}
if (ppNext != NULL)
{
*ppNext = next;
}
if (pNextLen != NULL)
{
*pNextLen = next_len;
}
if (ppNext == NULL && pNextLen == NULL && next != NULL)
{
success = FALSE;
}
return success;
}
/*
* Calculate IPv4/IPv6/ICMP/ICMPv6/TCP/UDP checksums.
*/
extern UINT WinDivertHelperCalcChecksums(PVOID pPacket, UINT packetLen,
const WINDIVERT_ADDRESS *pAddr, UINT64 flags)
extern BOOL WinDivertHelperCalcChecksums(PVOID pPacket, UINT packetLen,
WINDIVERT_ADDRESS *pAddr, UINT64 flags)
{
UINT8 pseudo_header[
MAX(sizeof(WINDIVERT_PSEUDOHDR), sizeof(WINDIVERT_PSEUDOV6HDR))];
@@ -466,41 +540,42 @@ extern UINT WinDivertHelperCalcChecksums(PVOID pPacket, UINT packetLen,
PWINDIVERT_TCPHDR tcp_header;
PWINDIVERT_UDPHDR udp_header;
UINT payload_len, checksum_len;
UINT count = 0;
WinDivertParsePacket(pPacket, packetLen, &ip_header, &ipv6_header,
&icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL, NULL,
&payload_len);
if (!WinDivertHelperParsePacket(pPacket, packetLen, &ip_header,
&ipv6_header, NULL, &icmp_header, &icmpv6_header, &tcp_header,
&udp_header, NULL, &payload_len, NULL, NULL))
{
return FALSE;
}
if (ip_header != NULL && !(flags & WINDIVERT_HELPER_NO_IP_CHECKSUM))
{
ip_header->Checksum = 0;
if (pAddr == NULL || pAddr->PseudoIPChecksum == 0)
ip_header->Checksum = WinDivertCalcChecksum(NULL, 0, ip_header,
ip_header->HdrLength*sizeof(UINT32));
if (pAddr != NULL)
{
ip_header->Checksum = WinDivertCalcChecksum(NULL, 0,
ip_header, ip_header->HdrLength*sizeof(UINT32));
pAddr->IPChecksum = 1;
}
count++;
}
if (icmp_header != NULL)
{
if ((flags & WINDIVERT_HELPER_NO_ICMP_CHECKSUM) != 0)
{
return count;
return TRUE;
}
icmp_header->Checksum = 0;
icmp_header->Checksum = WinDivertCalcChecksum(NULL, 0,
icmp_header, payload_len + sizeof(WINDIVERT_ICMPHDR));
count++;
return count;
return TRUE;
}
if (icmpv6_header != NULL)
{
if ((flags & WINDIVERT_HELPER_NO_ICMPV6_CHECKSUM) != 0)
{
return count;
return TRUE;
}
checksum_len = payload_len + sizeof(WINDIVERT_ICMPV6HDR);
pseudo_header_len = WinDivertInitPseudoHeader(NULL, ipv6_header,
@@ -508,63 +583,52 @@ extern UINT WinDivertHelperCalcChecksums(PVOID pPacket, UINT packetLen,
icmpv6_header->Checksum = 0;
icmpv6_header->Checksum = WinDivertCalcChecksum(pseudo_header,
pseudo_header_len, icmpv6_header, checksum_len);
count++;
return count;
return TRUE;
}
if (tcp_header != NULL)
{
if ((flags & WINDIVERT_HELPER_NO_TCP_CHECKSUM) != 0)
{
return count;
return TRUE;
}
if (pAddr == NULL || pAddr->PseudoTCPChecksum == 0)
checksum_len = payload_len + tcp_header->HdrLength*sizeof(UINT32);
pseudo_header_len = WinDivertInitPseudoHeader(ip_header,
ipv6_header, IPPROTO_TCP, checksum_len, pseudo_header);
tcp_header->Checksum = 0;
tcp_header->Checksum = WinDivertCalcChecksum(
pseudo_header, pseudo_header_len, tcp_header, checksum_len);
if (pAddr != NULL)
{
// Full TCP checksum
checksum_len = payload_len + tcp_header->HdrLength*sizeof(UINT32);
pseudo_header_len = WinDivertInitPseudoHeader(ip_header,
ipv6_header, IPPROTO_TCP, checksum_len, pseudo_header);
tcp_header->Checksum = 0;
tcp_header->Checksum = WinDivertCalcChecksum(
pseudo_header, pseudo_header_len, tcp_header, checksum_len);
pAddr->TCPChecksum = 1;
}
else if (pAddr->Outbound)
{
// Pseudo TCP checksum
tcp_header->Checksum = 0;
}
count++;
return count;
return TRUE;
}
if (udp_header != NULL)
{
if ((flags & WINDIVERT_HELPER_NO_UDP_CHECKSUM) != 0)
{
return count;
return TRUE;
}
if (pAddr == NULL || pAddr->PseudoUDPChecksum == 0)
// Full UDP checksum
checksum_len = payload_len + sizeof(WINDIVERT_UDPHDR);
pseudo_header_len = WinDivertInitPseudoHeader(ip_header,
ipv6_header, IPPROTO_UDP, checksum_len, pseudo_header);
udp_header->Checksum = 0;
udp_header->Checksum = WinDivertCalcChecksum(
pseudo_header, pseudo_header_len, udp_header, checksum_len);
if (udp_header->Checksum == 0)
{
// Full UDP checksum
checksum_len = payload_len + sizeof(WINDIVERT_UDPHDR);
pseudo_header_len = WinDivertInitPseudoHeader(ip_header,
ipv6_header, IPPROTO_UDP, checksum_len, pseudo_header);
udp_header->Checksum = 0;
udp_header->Checksum = WinDivertCalcChecksum(
pseudo_header, pseudo_header_len, udp_header, checksum_len);
if (udp_header->Checksum == 0)
{
udp_header->Checksum = 0xFFFF;
}
udp_header->Checksum = 0xFFFF;
}
else if (pAddr->Outbound)
if (pAddr != NULL)
{
// Pseudo UDP checksum
udp_header->Checksum = 0;
pAddr->UDPChecksum = 1;
}
count++;
}
return count;
return TRUE;
}
/*
@@ -637,3 +701,55 @@ static UINT16 WinDivertCalcChecksum(PVOID pseudo_header,
return (UINT16)sum;
}
/*
* Decrement the TTL.
*/
extern BOOL WinDivertHelperDecrementTTL(VOID *packet, UINT packetLen)
{
PWINDIVERT_IPHDR ip_header;
PWINDIVERT_IPV6HDR ipv6_header;
if (packet == NULL || packetLen < sizeof(WINDIVERT_IPHDR))
{
return FALSE;
}
ip_header = (PWINDIVERT_IPHDR)packet;
switch (ip_header->Version)
{
case 4:
if (ip_header->TTL <= 1)
{
return FALSE;
}
ip_header->TTL--;
// Incremental checksum update:
if (ip_header->Checksum >= 0xFFFE)
{
ip_header->Checksum -= 0xFFFE;
}
else
{
ip_header->Checksum += 1;
}
return TRUE;
case 6:
if (packetLen < sizeof(WINDIVERT_IPV6HDR))
{
return FALSE;
}
ipv6_header = (PWINDIVERT_IPV6HDR)packet;
if (ipv6_header->HopLimit <= 1)
{
return FALSE;
}
ipv6_header->HopLimit--;
return TRUE;
default:
return FALSE;
}
}
+2083 -675
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -1,6 +1,6 @@
/*
* flowtrack.c
* (C) 2018, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -227,7 +227,7 @@ int __cdecl main(int argc, char **argv)
filter = argv[1];
break;
default:
fprintf(stderr, "usage: %s [filter]\n");
fprintf(stderr, "usage: %s [filter]\n", argv[0]);
exit(EXIT_FAILURE);
}
@@ -263,7 +263,7 @@ int __cdecl main(int argc, char **argv)
// Main loop:
while (TRUE)
{
if (!WinDivertRecv(handle, NULL, 0, &addr, &packet_len))
if (!WinDivertRecv(handle, NULL, 0, NULL, &addr))
{
fprintf(stderr, "failed to read packet (%d)\n", GetLastError());
continue;
+73
View File
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
flowtrack.vcxproj
(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.
-->
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="flowtrack.c">
<TreatWarningAsError>false</TreatWarningAsError>
<Optimization>MinSpace</Optimization>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
</ClCompile>
</ItemGroup>
<PropertyGroup Label="Globals">
<RootNamespace>flowtrack</RootNamespace>
<ProjectName>flowtrack</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\install\MSVC\i386\WinDivert.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\install\MSVC\amd64\WinDivert.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
+19 -10
View File
@@ -1,6 +1,6 @@
/*
* netdump.c
* (C) 2018, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -51,7 +51,7 @@
#define ntohs(x) WinDivertHelperNtohs(x)
#define ntohl(x) WinDivertHelperNtohl(x)
#define MAXBUF 0xFFFF
#define MAXBUF WINDIVERT_MTU_MAX
#define INET6_ADDRSTRLEN 45
/*
@@ -118,18 +118,27 @@ int __cdecl main(int argc, char **argv)
}
// Max-out the packet queue:
if (!WinDivertSetParam(handle, WINDIVERT_PARAM_QUEUE_LEN, 8192))
if (!WinDivertSetParam(handle, WINDIVERT_PARAM_QUEUE_LENGTH,
WINDIVERT_PARAM_QUEUE_LENGTH_MAX))
{
fprintf(stderr, "error: failed to set packet queue length (%d)\n",
GetLastError());
exit(EXIT_FAILURE);
}
if (!WinDivertSetParam(handle, WINDIVERT_PARAM_QUEUE_TIME, 2048))
if (!WinDivertSetParam(handle, WINDIVERT_PARAM_QUEUE_TIME,
WINDIVERT_PARAM_QUEUE_TIME_MAX))
{
fprintf(stderr, "error: failed to set packet queue time (%d)\n",
GetLastError());
exit(EXIT_FAILURE);
}
if (!WinDivertSetParam(handle, WINDIVERT_PARAM_QUEUE_SIZE,
WINDIVERT_PARAM_QUEUE_SIZE_MAX))
{
fprintf(stderr, "error: failed to set packet queue size (%d)\n",
GetLastError());
exit(EXIT_FAILURE);
}
// Set up timing:
QueryPerformanceFrequency(&freq);
@@ -139,7 +148,7 @@ int __cdecl main(int argc, char **argv)
while (TRUE)
{
// Read a matching packet.
if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len))
if (!WinDivertRecv(handle, packet, sizeof(packet), &packet_len, &addr))
{
fprintf(stderr, "warning: failed to read packet (%d)\n",
GetLastError());
@@ -147,9 +156,9 @@ int __cdecl main(int argc, char **argv)
}
// Print info about the matching packet.
WinDivertHelperParsePacket(packet, packet_len, &ip_header,
&ipv6_header, &icmp_header, &icmpv6_header, &tcp_header,
&udp_header, NULL, NULL);
WinDivertHelperParsePacket(packet, packet_len, &ip_header, &ipv6_header,
NULL, &icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL,
NULL, NULL, NULL);
if (ip_header == NULL && ipv6_header == NULL)
{
fprintf(stderr, "warning: junk packet\n");
@@ -188,8 +197,8 @@ int __cdecl main(int argc, char **argv)
}
if (ipv6_header != NULL)
{
WinDivertHelperNtohIpv6Address(ipv6_header->SrcAddr, src_addr);
WinDivertHelperNtohIpv6Address(ipv6_header->DstAddr, dst_addr);
WinDivertHelperNtohIPv6Address(ipv6_header->SrcAddr, src_addr);
WinDivertHelperNtohIPv6Address(ipv6_header->DstAddr, dst_addr);
WinDivertHelperFormatIPv6Address(src_addr, src_str,
sizeof(src_str));
WinDivertHelperFormatIPv6Address(dst_addr, dst_str,
+73
View File
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
netdump.vcxproj
(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.
-->
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="netdump.c">
<TreatWarningAsError>false</TreatWarningAsError>
<Optimization>MinSpace</Optimization>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
</ClCompile>
</ItemGroup>
<PropertyGroup Label="Globals">
<RootNamespace>netdump</RootNamespace>
<ProjectName>netdump</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\install\MSVC\i386\WinDivert.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\install\MSVC\amd64\WinDivert.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
+14 -14
View File
@@ -1,6 +1,6 @@
/*
* netfilter.c
* (C) 2018, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -59,7 +59,7 @@
#define htons(x) WinDivertHelperHtons(x)
#define htonl(x) WinDivertHelperHtonl(x)
#define MAXBUF 0xFFFF
#define MAXBUF WINDIVERT_MTU_MAX
#define INET6_ADDRSTRLEN 45
#define IPPROTO_ICMPV6 58
@@ -193,17 +193,17 @@ int __cdecl main(int argc, char **argv)
while (TRUE)
{
// Read a matching packet.
if (!WinDivertRecv(handle, packet, sizeof(packet), &recv_addr,
&packet_len))
if (!WinDivertRecv(handle, packet, sizeof(packet), &packet_len,
&recv_addr))
{
fprintf(stderr, "warning: failed to read packet\n");
continue;
}
// Print info about the matching packet.
WinDivertHelperParsePacket(packet, packet_len, &ip_header,
&ipv6_header, &icmp_header, &icmpv6_header, &tcp_header,
&udp_header, NULL, &payload_len);
WinDivertHelperParsePacket(packet, packet_len, &ip_header, &ipv6_header,
NULL, &icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL,
&payload_len, NULL, NULL);
if (ip_header == NULL && ipv6_header == NULL)
{
continue;
@@ -223,8 +223,8 @@ int __cdecl main(int argc, char **argv)
}
if (ipv6_header != NULL)
{
WinDivertHelperNtohIpv6Address(ipv6_header->SrcAddr, src_addr);
WinDivertHelperNtohIpv6Address(ipv6_header->DstAddr, dst_addr);
WinDivertHelperNtohIPv6Address(ipv6_header->SrcAddr, src_addr);
WinDivertHelperNtohIPv6Address(ipv6_header->DstAddr, dst_addr);
WinDivertHelperFormatIPv6Address(src_addr, src_str,
sizeof(src_str));
WinDivertHelperFormatIPv6Address(dst_addr, dst_str,
@@ -292,7 +292,7 @@ int __cdecl main(int argc, char **argv)
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(TCPPACKET),
&send_addr, 0);
if (!WinDivertSend(handle, (PVOID)reset, sizeof(TCPPACKET),
&send_addr, NULL))
NULL, &send_addr))
{
fprintf(stderr, "warning: failed to send TCP reset (%d)\n",
GetLastError());
@@ -319,7 +319,7 @@ int __cdecl main(int argc, char **argv)
WinDivertHelperCalcChecksums((PVOID)resetv6,
sizeof(TCPV6PACKET), &send_addr, 0);
if (!WinDivertSend(handle, (PVOID)resetv6, sizeof(TCPV6PACKET),
&send_addr, NULL))
NULL, &send_addr))
{
fprintf(stderr, "warning: failed to send TCP (IPV6) "
"reset (%d)\n", GetLastError());
@@ -344,8 +344,8 @@ int __cdecl main(int argc, char **argv)
send_addr.Outbound = !recv_addr.Outbound;
WinDivertHelperCalcChecksums((PVOID)dnr, icmp_length,
&send_addr, 0);
if (!WinDivertSend(handle, (PVOID)dnr, icmp_length, &send_addr,
NULL))
if (!WinDivertSend(handle, (PVOID)dnr, icmp_length, NULL,
&send_addr))
{
fprintf(stderr, "warning: failed to send ICMP message "
"(%d)\n", GetLastError());
@@ -368,7 +368,7 @@ int __cdecl main(int argc, char **argv)
WinDivertHelperCalcChecksums((PVOID)dnrv6, icmpv6_length,
&send_addr, 0);
if (!WinDivertSend(handle, (PVOID)dnrv6, icmpv6_length,
&send_addr, NULL))
NULL, &send_addr))
{
fprintf(stderr, "warning: failed to send ICMPv6 message "
"(%d)\n", GetLastError());
+73
View File
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
netfilter.vcxproj
(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.
-->
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="netfilter.c">
<TreatWarningAsError>false</TreatWarningAsError>
<Optimization>MinSpace</Optimization>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
</ClCompile>
</ItemGroup>
<PropertyGroup Label="Globals">
<RootNamespace>netfilter</RootNamespace>
<ProjectName>netfilter</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\install\MSVC\i386\WinDivert.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\install\MSVC\amd64\WinDivert.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
+64 -28
View File
@@ -1,6 +1,6 @@
/*
* passthru.c
* (C) 2018, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -37,7 +37,7 @@
* This program does nothing except divert packets and re-inject them. This is
* useful for performance testing.
*
* usage: netdump.exe windivert-filter num-threads
* usage: passthru.exe [windivert-filter] [num-threads] [batch-size] [priority]
*/
#include <winsock2.h>
@@ -47,10 +47,13 @@
#include "windivert.h"
#define MAXBUF 400000
#define MAXBATCH 0xFF
#define MTU 1500
static int batch = 1;
typedef struct
{
HANDLE handle;
int batch;
} CONFIG, *PCONFIG;
static DWORD passthru(LPVOID arg);
@@ -59,37 +62,53 @@ static DWORD passthru(LPVOID arg);
*/
int __cdecl main(int argc, char **argv)
{
int num_threads, priority = 0, i;
const char *filter = "true";
int threads = 1, batch = 1, priority = 0;
int i;
HANDLE handle, thread;
CONFIG config;
if (argc < 3 || argc > 5)
if (argc > 5)
{
fprintf(stderr, "usage: %s filter num-threads [batch] [priority]\n",
argv[0]);
fprintf(stderr, "usage: %s [filter] [num-threads] [batch-size] "
"[priority]\n", argv[0]);
exit(EXIT_FAILURE);
}
num_threads = atoi(argv[2]);
if (num_threads < 1 || num_threads > 64)
if (argc >= 2)
{
fprintf(stderr, "error: invalid number of threads\n");
exit(EXIT_FAILURE);
filter = argv[1];
}
if (argc >= 3)
{
threads = atoi(argv[2]);
if (threads < 1 || threads > 64)
{
fprintf(stderr, "error: invalid number of threads\n");
exit(EXIT_FAILURE);
}
}
if (argc >= 4)
{
batch = atoi(argv[3]);
}
if (batch <= 0 || batch > MAXBATCH)
{
fprintf(stderr, "error: invalid batch size\n");
exit(EXIT_FAILURE);
if (batch <= 0 || batch > WINDIVERT_BATCH_MAX)
{
fprintf(stderr, "error: invalid batch size\n");
exit(EXIT_FAILURE);
}
}
if (argc >= 5)
{
priority = atoi(argv[4]);
if (priority < WINDIVERT_PRIORITY_LOWEST ||
priority > WINDIVERT_PRIORITY_HIGHEST)
{
fprintf(stderr, "error: invalid priority value\n");
exit(EXIT_FAILURE);
}
}
// Divert traffic matching the filter:
handle = WinDivertOpen(argv[1], WINDIVERT_LAYER_NETWORK, (INT16)priority,
handle = WinDivertOpen(filter, WINDIVERT_LAYER_NETWORK, (INT16)priority,
0);
if (handle == INVALID_HANDLE_VALUE)
{
@@ -104,20 +123,22 @@ int __cdecl main(int argc, char **argv)
}
// Start the threads
for (i = 1; i < num_threads; i++)
config.handle = handle;
config.batch = batch;
for (i = 1; i < threads; i++)
{
thread = CreateThread(NULL, 1, (LPTHREAD_START_ROUTINE)passthru,
(LPVOID)handle, 0, NULL);
(LPVOID)&config, 0, NULL);
if (thread == NULL)
{
fprintf(stderr, "error: failed to start passthru thread (%u)\n",
fprintf(stderr, "error: failed to start passthru thread (%d)\n",
GetLastError());
exit(EXIT_FAILURE);
}
}
// Main thread:
passthru((LPVOID)handle);
passthru((LPVOID)&config);
return 0;
}
@@ -125,17 +146,32 @@ int __cdecl main(int argc, char **argv)
// Passthru thread.
static DWORD passthru(LPVOID arg)
{
UINT8 packet[MAXBUF];
UINT8 *packet;
UINT packet_len, addr_len;
WINDIVERT_ADDRESS addr[MAXBATCH];
HANDLE handle = (HANDLE)arg;
WINDIVERT_ADDRESS *addr;
PCONFIG config = (PCONFIG)arg;
HANDLE handle;
int batch;
handle = config->handle;
batch = config->batch;
packet = (UINT8 *)malloc(batch * MTU);
addr = (WINDIVERT_ADDRESS *)malloc(batch * sizeof(WINDIVERT_ADDRESS));
if (packet == NULL || addr == NULL)
{
fprintf(stderr, "error: failed to allocate buffer (%d)\n",
GetLastError());
exit(EXIT_FAILURE);
}
// Main loop:
while (TRUE)
{
// Read a matching packet.
addr_len = batch * sizeof(WINDIVERT_ADDRESS);
if (!WinDivertRecvEx(handle, packet, sizeof(packet), &packet_len, 0,
packet_len = batch * MTU;
addr_len = batch * sizeof(WINDIVERT_ADDRESS);
if (!WinDivertRecvEx(handle, packet, packet_len, &packet_len, 0,
addr, &addr_len, NULL))
{
fprintf(stderr, "warning: failed to read packet (%d)\n",
+73
View File
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
passthru.vcxproj
(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.
-->
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="passthru.c">
<TreatWarningAsError>false</TreatWarningAsError>
<Optimization>MinSpace</Optimization>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
</ClCompile>
</ItemGroup>
<PropertyGroup Label="Globals">
<RootNamespace>passthru</RootNamespace>
<ProjectName>passthru</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\install\MSVC\i386\WinDivert.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\install\MSVC\amd64\WinDivert.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
+44 -7
View File
@@ -1,6 +1,6 @@
/*
* socketdump.c
* (C) 2018, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -36,6 +36,7 @@
* DESCRIPTION:
*
* usage: socketdump.exe [filter]
* socketdump.exe --block [filter]
*/
#include <winsock2.h>
@@ -61,24 +62,40 @@ int __cdecl main(int argc, char **argv)
char local_str[INET6_ADDRSTRLEN+1], remote_str[INET6_ADDRSTRLEN+1];
char *filename;
DWORD path_len;
UINT packet_len;
WINDIVERT_ADDRESS addr;
BOOL block = FALSE;
switch (argc)
{
case 1:
break;
case 2:
filter = argv[1];
if (strcmp(argv[1], "--block") == 0)
{
block = TRUE;
}
else
{
filter = argv[1];
}
break;
case 3:
if (strcmp(argv[1], "--block") == 0)
{
block = TRUE;
filter = argv[2];
break;
}
// Fallthrough:
default:
fprintf(stderr, "usage: %s [filter]\n");
fprintf(stderr, "usage: %s [filter]\n", argv[0]);
fprintf(stderr, " %s --block [filter]\n", argv[0]);
exit(EXIT_FAILURE);
}
// Open WinDivert SOCKET handle:
handle = WinDivertOpen(filter, WINDIVERT_LAYER_SOCKET, priority,
WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_RECV_ONLY);
(block? 0: WINDIVERT_FLAG_SNIFF) | WINDIVERT_FLAG_RECV_ONLY);
if (handle == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_INVALID_PARAMETER &&
@@ -97,28 +114,36 @@ int __cdecl main(int argc, char **argv)
console = GetStdHandle(STD_OUTPUT_HANDLE);
while (TRUE)
{
if (!WinDivertRecv(handle, NULL, 0, &addr, &packet_len))
if (!WinDivertRecv(handle, NULL, 0, NULL, &addr))
{
fprintf(stderr, "failed to read packet (%d)\n", GetLastError());
continue;
}
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
switch (addr.Event)
{
case WINDIVERT_EVENT_SOCKET_BIND:
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
printf("BIND");
break;
case WINDIVERT_EVENT_SOCKET_LISTEN:
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
printf("LISTEN");
break;
case WINDIVERT_EVENT_SOCKET_CONNECT:
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
printf("CONNECT");
break;
case WINDIVERT_EVENT_SOCKET_ACCEPT:
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
printf("ACCEPT");
break;
case WINDIVERT_EVENT_SOCKET_CLOSE:
SetConsoleTextAttribute(console, FOREGROUND_RED);
printf("CLOSE");
break;
default:
SetConsoleTextAttribute(console, FOREGROUND_BLUE);
printf("???");
break;
}
@@ -157,6 +182,18 @@ int __cdecl main(int argc, char **argv)
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
FOREGROUND_BLUE);
printf(" endpoint=");
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
printf("%lu", addr.Socket.EndpointId);
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
FOREGROUND_BLUE);
printf(" parent=");
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
printf("%lu", addr.Socket.ParentEndpointId);
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
FOREGROUND_BLUE);
printf(" protocol=");
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
switch (addr.Socket.Protocol)
+73
View File
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
socketdump.vcxproj
(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.
-->
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="socketdump.c">
<TreatWarningAsError>false</TreatWarningAsError>
<Optimization>MinSpace</Optimization>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
</ClCompile>
</ItemGroup>
<PropertyGroup Label="Globals">
<RootNamespace>socketdump</RootNamespace>
<ProjectName>socketdump</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\install\MSVC\i386\WinDivert.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\install\MSVC\amd64\WinDivert.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
+9 -76
View File
@@ -1,6 +1,6 @@
/*
* streamdump.c
* (C) 2018, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -40,8 +40,6 @@
* The program works by "reflecting" outbound TCP connections into inbound
* TCP connections that are handled by a simple proxy server.
*
* This program also demonstrates WinDivert asynchronous I/O.
*
* usage: streamdump.exe port
*/
@@ -53,7 +51,7 @@
#include "windivert.h"
#define MAXBUF 0xFFFF
#define MAXBUF WINDIVERT_MTU_MAX
#define PROXY_PORT 34010
#define ALT_PORT 43010
#define MAX_LINE 65
@@ -114,24 +112,6 @@ static void message(const char *msg, ...)
#define warning(msg, ...) \
message("warning: " msg, ## __VA_ARGS__)
/*
* Cleanup completed I/O requests.
*/
static void cleanup(HANDLE ioport, OVERLAPPED *ignore)
{
OVERLAPPED *overlapped;
DWORD iolen;
ULONG_PTR iokey = 0;
while (GetQueuedCompletionStatus(ioport, &iolen, &iokey, &overlapped, 0))
{
if (overlapped != ignore)
{
free(overlapped);
}
}
}
/*
* Entry.
*/
@@ -148,9 +128,6 @@ int __cdecl main(int argc, char **argv)
WINDIVERT_ADDRESS addr;
PWINDIVERT_IPHDR ip_header;
PWINDIVERT_TCPHDR tcp_header;
OVERLAPPED *poverlapped;
OVERLAPPED overlapped;
HANDLE ioport, event;
DWORD len;
// Init.
@@ -174,16 +151,6 @@ int __cdecl main(int argc, char **argv)
GetLastError());
exit(EXIT_FAILURE);
}
ioport = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
if (ioport == NULL)
{
error("failed to create I/O completion port (%d)", GetLastError());
}
event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (event == NULL)
{
error("failed to create event (%d)", GetLastError());
}
// Divert all traffic to/from `port', `proxy_port' and `alt_port'.
r = snprintf(filter, sizeof(filter),
@@ -200,10 +167,6 @@ int __cdecl main(int argc, char **argv)
{
error("failed to open the WinDivert device (%d)", GetLastError());
}
if (CreateIoCompletionPort(handle, ioport, 0, 0) == NULL)
{
error("failed to associate I/O completion port (%d)", GetLastError());
}
// Spawn proxy thread,
config = (PPROXY_CONFIG)malloc(sizeof(PROXY_CONFIG));
@@ -224,34 +187,15 @@ int __cdecl main(int argc, char **argv)
// Main loop:
while (TRUE)
{
memset(&overlapped, 0, sizeof(overlapped));
ResetEvent(event);
overlapped.hEvent = event;
if (!WinDivertRecvEx(handle, packet, sizeof(packet), &packet_len, 0,
&addr, NULL, &overlapped))
if (!WinDivertRecv(handle, packet, sizeof(packet), &packet_len, &addr))
{
if (GetLastError() != ERROR_IO_PENDING)
{
read_failed:
warning("failed to read packet (%d)", GetLastError());
continue;
}
// Timeout = 1s
while (WaitForSingleObject(event, 1000) == WAIT_TIMEOUT)
{
cleanup(ioport, &overlapped);
}
if (!GetOverlappedResult(handle, &overlapped, &len, FALSE))
{
goto read_failed;
}
packet_len = len;
warning("failed to read packet (%d)", GetLastError());
continue;
}
cleanup(ioport, &overlapped);
if (!WinDivertHelperParsePacket(packet, packet_len, &ip_header, NULL,
NULL, NULL, &tcp_header, NULL, NULL, NULL))
WinDivertHelperParsePacket(packet, packet_len, &ip_header, NULL, NULL,
NULL, NULL, &tcp_header, NULL, NULL, NULL, NULL, NULL);
if (ip_header == NULL || tcp_header == NULL)
{
warning("failed to parse packet (%d)", GetLastError());
continue;
@@ -293,18 +237,7 @@ read_failed:
}
WinDivertHelperCalcChecksums(packet, packet_len, &addr, 0);
poverlapped = (OVERLAPPED *)malloc(sizeof(OVERLAPPED));
if (poverlapped == NULL)
{
error("failed to allocate memory");
}
memset(poverlapped, 0, sizeof(OVERLAPPED));
if (WinDivertSendEx(handle, packet, packet_len, NULL, 0, &addr,
sizeof(WINDIVERT_ADDRESS), poverlapped))
{
continue;
}
if (GetLastError() != ERROR_IO_PENDING)
if (!WinDivertSend(handle, packet, packet_len, NULL, &addr))
{
warning("failed to send packet (%d)", GetLastError());
continue;
+73
View File
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
streamdump.vcxproj
(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.
-->
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="streamdump.c">
<TreatWarningAsError>false</TreatWarningAsError>
<Optimization>MinSpace</Optimization>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
</ClCompile>
</ItemGroup>
<PropertyGroup Label="Globals">
<RootNamespace>streamdump</RootNamespace>
<ProjectName>streamdump</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\install\MSVC\i386\WinDivert.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\install\MSVC\amd64\WinDivert.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
+13 -11
View File
@@ -1,6 +1,6 @@
/*
* webfilter.c
* (C) 2018, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -53,8 +53,8 @@
#define htons(x) WinDivertHelperHtons(x)
#define htonl(x) WinDivertHelperHtonl(x)
#define MAXBUF 0xFFFF
#define MAXURL 4096
#define MAXBUF WINDIVERT_MTU_MAX
#define MAXURL 4096
/*
* URL and blacklist representation.
@@ -197,19 +197,21 @@ int __cdecl main(int argc, char **argv)
// Main loop:
while (TRUE)
{
if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len))
if (!WinDivertRecv(handle, packet, sizeof(packet), &packet_len, &addr))
{
fprintf(stderr, "warning: failed to read packet (%d)\n",
GetLastError());
continue;
}
if (!WinDivertHelperParsePacket(packet, packet_len, &ip_header, NULL,
NULL, NULL, &tcp_header, NULL, &payload, &payload_len) ||
WinDivertHelperParsePacket(packet, packet_len, &ip_header, NULL,
NULL, NULL, NULL, &tcp_header, NULL, &payload, &payload_len,
NULL, NULL);
if (ip_header == NULL || tcp_header == NULL || payload == NULL ||
!BlackListPayloadMatch(blacklist, payload, (UINT16)payload_len))
{
// Packet does not match the blacklist; simply reinject it.
if (!WinDivertSend(handle, packet, packet_len, &addr, NULL))
if (!WinDivertSend(handle, packet, packet_len, NULL, &addr))
{
fprintf(stderr, "warning: failed to reinject packet (%d)\n",
GetLastError());
@@ -229,7 +231,7 @@ int __cdecl main(int argc, char **argv)
reset->tcp.SeqNum = tcp_header->SeqNum;
reset->tcp.AckNum = tcp_header->AckNum;
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(PACKET), &addr, 0);
if (!WinDivertSend(handle, (PVOID)reset, sizeof(PACKET), &addr, NULL))
if (!WinDivertSend(handle, (PVOID)reset, sizeof(PACKET), NULL, &addr))
{
fprintf(stderr, "warning: failed to send reset packet (%d)\n",
GetLastError());
@@ -244,8 +246,8 @@ int __cdecl main(int argc, char **argv)
htonl(ntohl(tcp_header->SeqNum) + payload_len);
addr.Outbound = !addr.Outbound; // Reverse direction.
WinDivertHelperCalcChecksums((PVOID)blockpage, blockpage_len, &addr, 0);
if (!WinDivertSend(handle, (PVOID)blockpage, blockpage_len, &addr,
NULL))
if (!WinDivertSend(handle, (PVOID)blockpage, blockpage_len, NULL,
&addr))
{
fprintf(stderr, "warning: failed to send block page packet (%d)\n",
GetLastError());
@@ -262,7 +264,7 @@ int __cdecl main(int argc, char **argv)
finish->tcp.AckNum =
htonl(ntohl(tcp_header->SeqNum) + payload_len);
WinDivertHelperCalcChecksums((PVOID)finish, sizeof(PACKET), &addr, 0);
if (!WinDivertSend(handle, (PVOID)finish, sizeof(PACKET), &addr, NULL))
if (!WinDivertSend(handle, (PVOID)finish, sizeof(PACKET), NULL, &addr))
{
fprintf(stderr, "warning: failed to send finish packet (%d)\n",
GetLastError());
+73
View File
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
webfilter.vcxproj
(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.
-->
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="webfilter.c">
<TreatWarningAsError>false</TreatWarningAsError>
<Optimization>MinSpace</Optimization>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
</ClCompile>
</ItemGroup>
<PropertyGroup Label="Globals">
<RootNamespace>webfilter</RootNamespace>
<ProjectName>webfilter</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\install\MSVC\i386\WinDivert.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\install\MSVC\amd64\WinDivert.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
+103 -129
View File
@@ -1,6 +1,6 @@
/*
* windivertctl.c
* (C) 2018, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -50,19 +50,6 @@
#define MAX_PACKET 0xFFFF
#define MAX_FILTER_LEN 30000
/*
* Process info.
*/
typedef struct INFO
{
UINT32 process_id;
UINT32 ref_count;
HANDLE process;
struct INFO *next;
} INFO, *PINFO;
static INFO *open = NULL; // All open handles
/*
* Modes.
*/
@@ -70,123 +57,37 @@ typedef enum
{
LIST,
WATCH,
KILLALL
KILL,
UNINSTALL
} MODE;
/*
* Add a new process.
*/
static HANDLE add_process(UINT32 process_id)
{
PINFO info = open;
HANDLE process;
while (info != NULL)
{
if (info->process_id == process_id)
{
info->ref_count++;
return info->process;
}
info = info->next;
}
process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE,
FALSE, process_id);
info = (INFO *)malloc(sizeof(INFO));
if (info == NULL)
{
fprintf(stderr, "error: failed to allocate memory (%d)\n",
GetLastError());
exit(EXIT_FAILURE);
}
info->process_id = process_id;
info->process = process;
info->ref_count = 1;
info->next = open;
open = info;
return process;
}
/*
* Lookup a process.
*/
static HANDLE lookup_process(UINT32 process_id)
{
PINFO info = open;
while (info != NULL)
{
if (info->process_id == process_id)
{
return info->process;
}
info = info->next;
}
}
/*
* Remove an old process.
*/
static void remove_process(UINT32 process_id)
{
PINFO info = open, prev = NULL;
while (info != NULL)
{
if (info->process_id == process_id)
{
info->ref_count--;
if (info->ref_count > 0)
{
return;
}
break;
}
prev = info;
info = info->next;
}
if (info->process != NULL)
{
CloseHandle(info->process);
}
if (prev != NULL)
{
prev->next = info->next;
}
else
{
open = info->next;
}
free(info);
}
/*
* Entry.
*/
int __cdecl main(int argc, char **argv)
{
HANDLE handle, process, console;
HANDLE handle, process, console, mutex;
INT16 priority = -333; // Arbitrary.
UINT packet_len;
static UINT8 packet[MAX_PACKET];
static char path[MAX_PATH+1];
static char filter_str[MAX_FILTER_LEN];
PVOID object;
DWORD path_len;
BOOL or;
WINDIVERT_ADDRESS addr;
ULONGLONG freq, start_count;
LARGE_INTEGER li;
MODE mode;
SC_HANDLE manager = NULL, service = NULL;
SERVICE_STATUS status;
const char *filter = "true";
const char *err_str = NULL;
if (argc != 2 && argc != 3)
{
usage:
fprintf(stderr, "usage: %s (list|watch|killall) [filter]\n", argv[0]);
fprintf(stderr, "usage: %s (list|watch|kill) [filter]\n", argv[0]);
fprintf(stderr, " %s uninstall\n", argv[0]);
exit(EXIT_FAILURE);
}
if (strcmp(argv[1], "list") == 0)
@@ -197,9 +98,17 @@ usage:
{
mode = WATCH;
}
else if (strcmp(argv[1], "killall") == 0)
else if (strcmp(argv[1], "kill") == 0)
{
mode = KILLALL;
mode = KILL;
}
else if (strcmp(argv[1], "uninstall") == 0)
{
if (argc != 2)
{
goto usage;
}
mode = UNINSTALL;
}
else
{
@@ -228,7 +137,7 @@ usage:
return 0;
}
if (GetLastError() == ERROR_INVALID_PARAMETER &&
!WinDivertHelperCompileFilter(filter, WINDIVERT_LAYER_FLOW,
!WinDivertHelperCompileFilter(filter, WINDIVERT_LAYER_REFLECT,
NULL, 0, &err_str, NULL))
{
fprintf(stderr, "error: invalid filter \"%s\"\n", err_str);
@@ -244,18 +153,29 @@ usage:
GetLastError());
return EXIT_FAILURE;
}
if (!WinDivertSetParam(handle, WINDIVERT_PARAM_QUEUE_LENGTH,
WINDIVERT_PARAM_QUEUE_LENGTH_MAX) ||
!WinDivertSetParam(handle, WINDIVERT_PARAM_QUEUE_SIZE,
WINDIVERT_PARAM_QUEUE_SIZE_MAX) ||
!WinDivertSetParam(handle, WINDIVERT_PARAM_QUEUE_TIME,
WINDIVERT_PARAM_QUEUE_TIME_MAX))
{
fprintf(stderr, "error: failed to set WinDivert handle params (%d)\n",
GetLastError());
return EXIT_FAILURE;
}
// Main loop:
console = GetStdHandle(STD_OUTPUT_HANDLE);
while (TRUE)
{
if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len))
if (!WinDivertRecv(handle, packet, sizeof(packet), &packet_len, &addr))
{
if (mode != WATCH && GetLastError() == ERROR_NO_DATA)
{
break;
}
fprintf(stderr, "failed to event (%d)\n", GetLastError());
fprintf(stderr, "failed to receive event (%d)\n", GetLastError());
continue;
}
@@ -263,12 +183,10 @@ usage:
{
case WINDIVERT_EVENT_REFLECT_OPEN:
// Open handle:
process = add_process(addr.Reflect.ProcessId);
if (mode == KILLALL)
if (mode == KILL || mode == UNINSTALL)
{
SetConsoleTextAttribute(console, FOREGROUND_RED);
fputs("KILL", stdout);
TerminateProcess(process, 0);
}
else
{
@@ -283,7 +201,6 @@ usage:
{
continue;
}
process = lookup_process(addr.Reflect.ProcessId);
SetConsoleTextAttribute(console, FOREGROUND_RED);
fputs("CLOSE", stdout);
break;
@@ -292,6 +209,9 @@ usage:
fputs("???", stdout);
break;
}
process = OpenProcess(
PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE,
FALSE, addr.Reflect.ProcessId);
SetConsoleTextAttribute(console,
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
fputs(" time=", stdout);
@@ -310,6 +230,11 @@ usage:
if (process != NULL)
{
path_len = GetProcessImageFileName(process, path, sizeof(path));
if (mode == KILL || mode == UNINSTALL)
{
TerminateProcess(process, 0);
}
CloseHandle(process);
}
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
printf("%s", (path_len != 0? path: "???"));
@@ -369,11 +294,6 @@ usage:
printf("%sSEND_ONLY", (or? "|": ""));
or = TRUE;
}
if ((addr.Reflect.Flags & WINDIVERT_FLAG_RECV_PARTIAL) != 0)
{
printf("%sRECV_PARTIAL", (or? "|": ""));
or = TRUE;
}
if ((addr.Reflect.Flags & WINDIVERT_FLAG_NO_INSTALL) != 0)
{
printf("%sNO_INSTALL", (or? "|": ""));
@@ -389,21 +309,18 @@ usage:
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
fputs(" filter=", stdout);
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
WinDivertHelperParsePacket(packet, packet_len, NULL, NULL, NULL, NULL,
NULL, NULL, &object, NULL);
if (WinDivertHelperFormatFilter((char *)object, addr.Reflect.Layer,
if (WinDivertHelperFormatFilter((char *)packet, addr.Reflect.Layer,
filter_str, sizeof(filter_str)))
{
printf("\"%s\"", filter_str);
}
else
{
printf("\"%s\"", (char *)packet);
}
SetConsoleTextAttribute(console,
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
putchar('\n');
if (addr.Event == WINDIVERT_EVENT_REFLECT_CLOSE)
{
remove_process(addr.Reflect.ProcessId);
}
}
if (!WinDivertClose(handle))
@@ -413,6 +330,63 @@ usage:
return EXIT_FAILURE;
}
if (mode == UNINSTALL)
{
// Stop & delete the WinDivert service:
mutex = CreateMutex(NULL, FALSE, "WinDivertDriverInstallMutex");
if (mutex == NULL)
{
fprintf(stderr, "error: failed to create WinDivert driver "
"install mutex (%d)\n", GetLastError());
return EXIT_FAILURE;
}
switch (WaitForSingleObject(mutex, INFINITE))
{
case WAIT_OBJECT_0: case WAIT_ABANDONED:
break;
default:
fprintf(stderr, "error: failed to acquire WinDivert driver "
"install mutex (%d)\n", GetLastError());
return EXIT_FAILURE;
}
manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (manager == NULL)
{
fprintf(stderr, "error: failed to open service manager (%d)\n",
GetLastError());
return EXIT_FAILURE;
}
service = OpenService(manager, "WinDivert", SERVICE_ALL_ACCESS);
if (service == NULL)
{
fprintf(stderr, "error: failed to open WinDivert service (%d)\n",
GetLastError());
return EXIT_FAILURE;
}
if (!ControlService(service, SERVICE_CONTROL_STOP, &status))
{
fprintf(stderr, "error: failed to stop WinDivert service (%d)\n",
GetLastError());
return EXIT_FAILURE;
}
if (status.dwCurrentState != SERVICE_STOPPED)
{
fprintf(stderr, "error: failed to stop WinDivert service");
return EXIT_FAILURE;
}
CloseServiceHandle(service);
CloseServiceHandle(manager);
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
fputs("UNINSTALL", stdout);
SetConsoleTextAttribute(console,
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
puts(" WinDivert");
ReleaseMutex(mutex);
CloseHandle(mutex);
}
return 0;
}
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
windivertctl.vcxproj
(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.
-->
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="windivertctl.c">
<TreatWarningAsError>false</TreatWarningAsError>
<Optimization>MinSpace</Optimization>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
</ClCompile>
</ItemGroup>
<PropertyGroup Label="Globals">
<RootNamespace>windivertctl</RootNamespace>
<ProjectName>windivertctl</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\install\MSVC\i386\WinDivert.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\install\MSVC\amd64\WinDivert.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
+92 -30
View File
@@ -1,6 +1,6 @@
/*
* windivert.h
* (C) 2018, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -95,6 +95,8 @@ typedef struct
*/
typedef struct
{
UINT64 EndpointId; /* Endpoint ID. */
UINT64 ParentEndpointId; /* Parent endpoint ID. */
UINT32 ProcessId; /* Process ID. */
UINT32 LocalAddr[4]; /* Local address. */
UINT32 RemoteAddr[4]; /* Remote address. */
@@ -108,6 +110,8 @@ typedef struct
*/
typedef struct
{
UINT64 EndpointId; /* Endpoint ID. */
UINT64 ParentEndpointId; /* Parent Endpoint ID. */
UINT32 ProcessId; /* Process ID. */
UINT32 LocalAddr[4]; /* Local address. */
UINT32 RemoteAddr[4]; /* Remote address. */
@@ -131,27 +135,37 @@ typedef struct
/*
* WinDivert address.
*/
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4201)
#endif
typedef struct
{
INT64 Timestamp; /* Packet's timestamp. */
UINT64 Layer:8; /* Packet's layer. */
UINT64 Event:8; /* Packet event. */
UINT64 Outbound:1; /* Packet is outound? */
UINT64 Loopback:1; /* Packet is loopback? */
UINT64 Impostor:1; /* Packet is impostor? */
UINT64 IPv6:1; /* Packet is IPv6? */
UINT64 PseudoIPChecksum:1; /* Packet has pseudo IPv4 checksum? */
UINT64 PseudoTCPChecksum:1; /* Packet has pseudo TCP checksum? */
UINT64 PseudoUDPChecksum:1; /* Packet has pseudo UDP checksum? */
UINT64 Reserved:41;
UINT32 Layer:8; /* Packet's layer. */
UINT32 Event:8; /* Packet event. */
UINT32 Sniffed:1; /* Packet was sniffed? */
UINT32 Outbound:1; /* Packet is outound? */
UINT32 Loopback:1; /* Packet is loopback? */
UINT32 Impostor:1; /* Packet is impostor? */
UINT32 IPv6:1; /* Packet is IPv6? */
UINT32 IPChecksum:1; /* Packet has valid IPv4 checksum? */
UINT32 TCPChecksum:1; /* Packet has valid TCP checksum? */
UINT32 UDPChecksum:1; /* Packet has valid UDP checksum? */
UINT32 Reserved1:8;
UINT32 Reserved2;
union
{
WINDIVERT_DATA_NETWORK Network; /* Network layer data. */
WINDIVERT_DATA_FLOW Flow; /* Flow layer data. */
WINDIVERT_DATA_SOCKET Socket; /* Socket layer data. */
WINDIVERT_DATA_REFLECT Reflect; /* Reflect layer data. */
UINT8 Reserved3[64];
};
} WINDIVERT_ADDRESS, *PWINDIVERT_ADDRESS;
#ifdef _MSC_VER
#pragma warning(pop)
#endif
/*
* WinDivert events.
@@ -163,11 +177,12 @@ typedef enum
/* Flow established. */
WINDIVERT_EVENT_FLOW_DELETED = 2, /* Flow deleted. */
WINDIVERT_EVENT_SOCKET_BIND = 3, /* Socket bind. */
WINDIVERT_EVENT_SOCKET_LISTEN = 4, /* Socket listen. */
WINDIVERT_EVENT_SOCKET_CONNECT = 5, /* Socket connect. */
WINDIVERT_EVENT_SOCKET_CONNECT = 4, /* Socket connect. */
WINDIVERT_EVENT_SOCKET_LISTEN = 5, /* Socket listen. */
WINDIVERT_EVENT_SOCKET_ACCEPT = 6, /* Socket accept. */
WINDIVERT_EVENT_REFLECT_OPEN = 7, /* WinDivert handle opened. */
WINDIVERT_EVENT_REFLECT_CLOSE = 8, /* WinDivert handle closed. */
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, *PWINDIVERT_EVENT;
/*
@@ -179,19 +194,20 @@ typedef enum
#define WINDIVERT_FLAG_READ_ONLY WINDIVERT_FLAG_RECV_ONLY
#define WINDIVERT_FLAG_SEND_ONLY 0x0008
#define WINDIVERT_FLAG_WRITE_ONLY WINDIVERT_FLAG_SEND_ONLY
#define WINDIVERT_FLAG_RECV_PARTIAL 0x0010
#define WINDIVERT_FLAG_NO_INSTALL 0x0020
#define WINDIVERT_FLAG_NO_INSTALL 0x0010
/*
* WinDivert parameters.
*/
typedef enum
{
WINDIVERT_PARAM_QUEUE_LEN = 0, /* Packet queue length. */
WINDIVERT_PARAM_QUEUE_LENGTH = 0, /* Packet queue length. */
WINDIVERT_PARAM_QUEUE_TIME = 1, /* Packet queue time. */
WINDIVERT_PARAM_QUEUE_SIZE = 2, /* Packet queue size. */
WINDIVERT_PARAM_VERSION_MAJOR = 3, /* Driver version (major). */
WINDIVERT_PARAM_VERSION_MINOR = 4, /* Driver version (minor). */
} WINDIVERT_PARAM, *PWINDIVERT_PARAM;
#define WINDIVERT_PARAM_MAX WINDIVERT_PARAM_QUEUE_SIZE
#define WINDIVERT_PARAM_MAX WINDIVERT_PARAM_VERSION_MINOR
/*
* WinDivert shutdown parameter.
@@ -220,19 +236,19 @@ extern WINDIVERTEXPORT HANDLE WinDivertOpen(
*/
extern WINDIVERTEXPORT BOOL WinDivertRecv(
__in HANDLE handle,
__out VOID *pPacket,
__out_opt VOID *pPacket,
__in UINT packetLen,
__out_opt WINDIVERT_ADDRESS *pAddr,
__out_opt UINT *pReadLen);
__out_opt UINT *pRecvLen,
__out_opt WINDIVERT_ADDRESS *pAddr);
/*
* Receive (read) a packet from a WinDivert handle.
*/
extern WINDIVERTEXPORT BOOL WinDivertRecvEx(
__in HANDLE handle,
__out PVOID pPacket,
__out_opt VOID *pPacket,
__in UINT packetLen,
__out_opt UINT *pReadLen,
__out_opt UINT *pRecvLen,
__in UINT64 flags,
__out WINDIVERT_ADDRESS *pAddr,
__inout_opt UINT *pAddrLen,
@@ -245,8 +261,8 @@ extern WINDIVERTEXPORT BOOL WinDivertSend(
__in HANDLE handle,
__in const VOID *pPacket,
__in UINT packetLen,
__in const WINDIVERT_ADDRESS *pAddr,
__out_opt UINT *pWriteLen);
__out_opt UINT *pSendLen,
__in const WINDIVERT_ADDRESS *pAddr);
/*
* Send (write/inject) a packet to a WinDivert handle.
@@ -255,7 +271,7 @@ extern WINDIVERTEXPORT BOOL WinDivertSendEx(
__in HANDLE handle,
__in const VOID *pPacket,
__in UINT packetLen,
__out_opt UINT *pWriteLen,
__out_opt UINT *pSendLen,
__in UINT64 flags,
__in const WINDIVERT_ADDRESS *pAddr,
__in UINT addrLen,
@@ -292,10 +308,32 @@ extern WINDIVERTEXPORT BOOL WinDivertGetParam(
#endif /* WINDIVERT_KERNEL */
/*
* WinDivert constants.
*/
#define WINDIVERT_PRIORITY_HIGHEST 30000
#define WINDIVERT_PRIORITY_LOWEST (-WINDIVERT_PRIORITY_HIGHEST)
#define WINDIVERT_PARAM_QUEUE_LENGTH_DEFAULT 4096
#define WINDIVERT_PARAM_QUEUE_LENGTH_MIN 32
#define WINDIVERT_PARAM_QUEUE_LENGTH_MAX 16384
#define WINDIVERT_PARAM_QUEUE_TIME_DEFAULT 2000 /* 2s */
#define WINDIVERT_PARAM_QUEUE_TIME_MIN 100 /* 100ms */
#define WINDIVERT_PARAM_QUEUE_TIME_MAX 16000 /* 16s */
#define WINDIVERT_PARAM_QUEUE_SIZE_DEFAULT 4194304 /* 4MB */
#define WINDIVERT_PARAM_QUEUE_SIZE_MIN 65535 /* 64KB */
#define WINDIVERT_PARAM_QUEUE_SIZE_MAX 33554432 /* 32MB */
#define WINDIVERT_BATCH_MAX 0xFF /* 255 */
#define WINDIVERT_MTU_MAX (40 + 0xFFFF)
/****************************************************************************/
/* WINDIVERT HELPER API */
/****************************************************************************/
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4214)
#endif
/*
* IPv4/IPv6/ICMP/ICMPv6/TCP/UDP header definitions.
*/
@@ -430,6 +468,10 @@ typedef struct
UINT16 Checksum;
} WINDIVERT_UDPHDR, *PWINDIVERT_UDPHDR;
#ifdef _MSC_VER
#pragma warning(pop)
#endif
/*
* Flags for WinDivertHelperCalcChecksums()
*/
@@ -461,12 +503,15 @@ extern WINDIVERTEXPORT BOOL WinDivertHelperParsePacket(
__in UINT packetLen,
__out_opt PWINDIVERT_IPHDR *ppIpHdr,
__out_opt PWINDIVERT_IPV6HDR *ppIpv6Hdr,
__out_opt UINT8 *pProtocol,
__out_opt PWINDIVERT_ICMPHDR *ppIcmpHdr,
__out_opt PWINDIVERT_ICMPV6HDR *ppIcmpv6Hdr,
__out_opt PWINDIVERT_TCPHDR *ppTcpHdr,
__out_opt PWINDIVERT_UDPHDR *ppUdpHdr,
__out_opt PVOID *ppData,
__out_opt UINT *pDataLen);
__out_opt UINT *pDataLen,
__out_opt PVOID *ppNext,
__out_opt UINT *pNextLen);
/*
* Parse an IPv4 address.
@@ -501,12 +546,19 @@ extern WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv6Address(
/*
* Calculate IPv4/IPv6/ICMP/ICMPv6/TCP/UDP checksums.
*/
extern WINDIVERTEXPORT UINT WinDivertHelperCalcChecksums(
extern WINDIVERTEXPORT BOOL WinDivertHelperCalcChecksums(
__inout VOID *pPacket,
__in UINT packetLen,
__in_opt const WINDIVERT_ADDRESS *pAddr,
__out_opt WINDIVERT_ADDRESS *pAddr,
__in UINT64 flags);
/*
* Decrement the TTL/HopLimit.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperDecrementTTL(
__inout VOID *pPacket,
__in UINT packetLen);
/*
* Compile the given filter string.
*/
@@ -551,6 +603,16 @@ extern WINDIVERTEXPORT UINT64 WinDivertHelperNtohll(
__in UINT64 x);
extern WINDIVERTEXPORT UINT64 WinDivertHelperHtonll(
__in UINT64 x);
extern WINDIVERTEXPORT void WinDivertHelperNtohIPv6Address(
__in const UINT *inAddr,
__out UINT *outAddr);
extern WINDIVERTEXPORT void WinDivertHelperHtonIPv6Address(
__in const UINT *inAddr,
__out UINT *outAddr);
/*
* Old names to be removed in the next version.
*/
extern WINDIVERTEXPORT void WinDivertHelperNtohIpv6Address(
__in const UINT *inAddr,
__out UINT *outAddr);
+118 -82
View File
@@ -1,6 +1,6 @@
/*
* windivert_device.h
* (C) 2018, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -44,20 +44,25 @@
#define WINDIVERT_KERNEL
#include "windivert.h"
#define WINDIVERT_VERSION 2
#define WINDIVERT_VERSION_MAJOR 2
#define WINDIVERT_VERSION_MINOR 0
#define WINDIVERT_MAGIC_DLL 0x4C4C447669645724ull
#define WINDIVERT_MAGIC_SYS 0x5359537669645723ull
#define WINDIVERT_STR2(s) #s
#define WINDIVERT_STR(s) WINDIVERT_STR2(s)
#define WINDIVERT_LSTR2(s) L ## #s
#define WINDIVERT_LSTR(s) WINDIVERT_LSTR2(s)
#define WINDIVERT_VERSION_LSTR \
WINDIVERT_LSTR(WINDIVERT_VERSION) L"." \
WINDIVERT_LSTR(WINDIVERT_VERSION_MAJOR) L"." \
WINDIVERT_LSTR(WINDIVERT_VERSION_MINOR)
#define WINDIVERT_DEVICE_NAME \
L"WinDivert" WINDIVERT_VERSION_LSTR
L"WinDivert"
#define WINDIVERT_LAYER_NAME \
WINDIVERT_DEVICE_NAME WINDIVERT_VERSION_LSTR
#define WINDIVERT_FILTER_FIELD_ZERO 0
#define WINDIVERT_FILTER_FIELD_INBOUND 1
@@ -125,20 +130,25 @@
#define WINDIVERT_FILTER_FIELD_LOCALPORT 63
#define WINDIVERT_FILTER_FIELD_REMOTEPORT 64
#define WINDIVERT_FILTER_FIELD_PROTOCOL 65
#define WINDIVERT_FILTER_FIELD_LAYER 66
#define WINDIVERT_FILTER_FIELD_EVENT 67
#define WINDIVERT_FILTER_FIELD_PACKET 68
#define WINDIVERT_FILTER_FIELD_PACKET16 69
#define WINDIVERT_FILTER_FIELD_PACKET32 70
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD 71
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD16 72
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD32 73
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD 74
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD16 75
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD32 76
#define WINDIVERT_FILTER_FIELD_RANDOM8 77
#define WINDIVERT_FILTER_FIELD_RANDOM16 78
#define WINDIVERT_FILTER_FIELD_RANDOM32 79
#define WINDIVERT_FILTER_FIELD_ENDPOINTID 66
#define WINDIVERT_FILTER_FIELD_PARENTENDPOINTID 67
#define WINDIVERT_FILTER_FIELD_LAYER 68
#define WINDIVERT_FILTER_FIELD_PRIORITY 69
#define WINDIVERT_FILTER_FIELD_EVENT 70
#define WINDIVERT_FILTER_FIELD_PACKET 71
#define WINDIVERT_FILTER_FIELD_PACKET16 72
#define WINDIVERT_FILTER_FIELD_PACKET32 73
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD 74
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD16 75
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD32 76
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD 77
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD16 78
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD32 79
#define WINDIVERT_FILTER_FIELD_LENGTH 80
#define WINDIVERT_FILTER_FIELD_TIMESTAMP 81
#define WINDIVERT_FILTER_FIELD_RANDOM8 82
#define WINDIVERT_FILTER_FIELD_RANDOM16 83
#define WINDIVERT_FILTER_FIELD_RANDOM32 84
#define WINDIVERT_FILTER_FIELD_MAX \
WINDIVERT_FILTER_FIELD_RANDOM32
@@ -150,15 +160,14 @@
#define WINDIVERT_FILTER_TEST_GEQ 5
#define WINDIVERT_FILTER_TEST_MAX WINDIVERT_FILTER_TEST_GEQ
#define WINDIVERT_FILTER_MAXLEN (0xFF-2)
#define WINDIVERT_FILTER_MAXLEN 256
#define WINDIVERT_FILTER_RESULT_ACCEPT (WINDIVERT_FILTER_MAXLEN+1)
#define WINDIVERT_FILTER_RESULT_REJECT (WINDIVERT_FILTER_MAXLEN+2)
#define WINDIVERT_FILTER_RESULT_ACCEPT 0x7FFE
#define WINDIVERT_FILTER_RESULT_REJECT 0x7FFF
/*
* WinDivert layers.
*/
#define WINDIVERT_LAYER_DEFAULT WINDIVERT_LAYER_NETWORK
#define WINDIVERT_LAYER_MAX WINDIVERT_LAYER_REFLECT
/*
@@ -172,8 +181,7 @@
*/
#define WINDIVERT_FLAGS_ALL \
(WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_DROP | WINDIVERT_FLAG_RECV_ONLY |\
WINDIVERT_FLAG_SEND_ONLY | WINDIVERT_FLAG_RECV_PARTIAL | \
WINDIVERT_FLAG_NO_INSTALL)
WINDIVERT_FLAG_SEND_ONLY | WINDIVERT_FLAG_NO_INSTALL)
#define WINDIVERT_FLAGS_EXCLUDE(flags, flag1, flag2) \
(((flags) & ((flag1) | (flag2))) != ((flag1) | (flag2)))
#define WINDIVERT_FLAGS_VALID(flags) \
@@ -181,76 +189,110 @@
WINDIVERT_FLAGS_EXCLUDE(flags, WINDIVERT_FLAG_SNIFF, \
WINDIVERT_FLAG_DROP) && \
WINDIVERT_FLAGS_EXCLUDE(flags, WINDIVERT_FLAG_RECV_ONLY, \
WINDIVERT_FLAG_SEND_ONLY) && \
WINDIVERT_FLAGS_EXCLUDE(flags, WINDIVERT_FLAG_RECV_PARTIAL, \
WINDIVERT_FLAG_SEND_ONLY))
/*
* WinDivert filter flags.
*/
#define WINDIVERT_FILTER_FLAG_INBOUND 0x0000000000000001ull
#define WINDIVERT_FILTER_FLAG_OUTBOUND 0x0000000000000002ull
#define WINDIVERT_FILTER_FLAG_IP 0x0000000000000004ull
#define WINDIVERT_FILTER_FLAG_IPV6 0x0000000000000008ull
#define WINDIVERT_FILTER_FLAG_EVENT_FLOW_DELETED 0x0000000000000010ull
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_BIND 0x0000000000000020ull
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CONNECT 0x0000000000000040ull
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_LISTEN 0x0000000000000080ull
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_ACCEPT 0x0000000000000100ull
#define WINDIVERT_FILTER_FLAG_INBOUND 0x0000000000000010ull
#define WINDIVERT_FILTER_FLAG_OUTBOUND 0x0000000000000020ull
#define WINDIVERT_FILTER_FLAG_IP 0x0000000000000040ull
#define WINDIVERT_FILTER_FLAG_IPV6 0x0000000000000080ull
#define WINDIVERT_FILTER_FLAG_EVENT_FLOW_DELETED 0x0000000000000100ull
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_BIND 0x0000000000000200ull
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CONNECT 0x0000000000000400ull
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_LISTEN 0x0000000000000800ull
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_ACCEPT 0x0000000000001000ull
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CLOSE 0x0000000000002000ull
#define WINDIVERT_FILTER_FLAGS_ALL \
(WINDIVERT_FILTER_FLAG_INBOUND | WINDIVERT_FILTER_FLAG_OUTBOUND | \
WINDIVERT_FILTER_FLAG_IP | WINDIVERT_FILTER_FLAG_IPV6 | \
(WINDIVERT_FILTER_FLAG_INBOUND | \
WINDIVERT_FILTER_FLAG_OUTBOUND | \
WINDIVERT_FILTER_FLAG_IP | \
WINDIVERT_FILTER_FLAG_IPV6 | \
WINDIVERT_FILTER_FLAG_EVENT_FLOW_DELETED | \
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_BIND | \
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CONNECT | \
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_LISTEN | \
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_ACCEPT)
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_ACCEPT | \
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CLOSE)
/*
* WinDivert priorities.
*/
#define WINDIVERT_PRIORITY_DEFAULT 0
#define WINDIVERT_PRIORITY_MAX 30000
#define WINDIVERT_PRIORITY_MIN -WINDIVERT_PRIORITY_MAX
#define WINDIVERT_PRIORITY_MAX WINDIVERT_PRIORITY_HIGHEST
#define WINDIVERT_PRIORITY_MIN WINDIVERT_PRIORITY_LOWEST
/*
* WinDivert parameters.
* WinDivert timestamps.
*/
#define WINDIVERT_PARAM_QUEUE_LEN_DEFAULT 2048
#define WINDIVERT_PARAM_QUEUE_LEN_MIN 16
#define WINDIVERT_PARAM_QUEUE_LEN_MAX 16384
#define WINDIVERT_PARAM_QUEUE_TIME_DEFAULT 1000 // 1s
#define WINDIVERT_PARAM_QUEUE_TIME_MIN 20 // 20ms
#define WINDIVERT_PARAM_QUEUE_TIME_MAX 8000 // 8s
#define WINDIVERT_PARAM_QUEUE_SIZE_MIN 65535 // 64KB
#define WINDIVERT_PARAM_QUEUE_SIZE_MAX 33554432 // 32MB
#define WINDIVERT_PARAM_QUEUE_SIZE_DEFAULT 4194304 // 4MB
/*
* WinDivert batch limits.
*/
#define WINDIVERT_BATCH_MAX 0xFF
#define WINDIVERT_TIMESTAMP_MAX 0x7FFFFFFFFFFFFFFFull
/*
* WinDivert message definitions.
*/
#pragma pack(push, 1)
typedef struct
typedef union
{
UINT64 arg1; // argument #1
UINT64 arg2; // argument #2
struct
{
UINT64 addr; // WINDIVERT_ADDRESS pointer.
UINT64 addr_len_ptr; // sizeof(addr) pointer.
} recv;
struct
{
UINT64 addr; // WINDIVERT_ADDRESS pointer.
UINT64 addr_len; // sizeof(addr).
} send;
struct
{
UINT32 layer; // Handle layer.
UINT32 priority; // Handle priority.
UINT64 flags; // Handle flags.
} initialize;
struct
{
UINT64 flags; // Filter flags.
} startup;
struct
{
UINT32 how; // WINDIVERT_SHUTDOWN_*
} shutdown;
struct
{
UINT32 param; // WINDIVERT_PARAM_*
} get_param;
struct
{
UINT64 val; // Value pointer.
UINT32 param; // WINDIVERT_PARAM_*
} set_param;
} WINDIVERT_IOCTL, *PWINDIVERT_IOCTL;
/*
* WinDivert IOCTL structures.
* WinDivert initialization structure.
*/
typedef struct
{
UINT8 field; // WINDIVERT_FILTER_FIELD_*
UINT8 test; // WINDIVERT_FILTER_TEST_*
UINT8 success; // Success continuation.
UINT8 failure; // Fail continuation.
UINT64 magic; // Magic number (in/out).
UINT32 major; // Driver major version (in/out).
UINT32 minor; // Driver minor version (in/out).
UINT32 bits; // 32 or 64 (in/out).
UINT32 reserved32[3];
UINT64 reserved64[4];
} WINDIVERT_VERSION, *PWINDIVERT_VERSION;
/*
* WinDivert filter structure.
*/
typedef struct
{
UINT32 field:11; // WINDIVERT_FILTER_FIELD_*
UINT32 test:5; // WINDIVERT_FILTER_TEST_*
UINT32 success:16; // Success continuation.
UINT32 failure:16; // Fail continuation.
UINT32 neg:1; // Argument negative?
UINT32 reserved:15;
UINT32 arg[4]; // Argument.
} WINDIVERT_FILTER, *PWINDIVERT_FILTER;
#pragma pack(pop)
@@ -258,30 +300,24 @@ typedef struct
/*
* IOCTL codes.
*/
#define IOCTL_WINDIVERT_SHUTDOWN \
CTL_CODE(FILE_DEVICE_NETWORK, 0x917, METHOD_IN_DIRECT, FILE_READ_DATA | \
#define IOCTL_WINDIVERT_INITIALIZE \
CTL_CODE(FILE_DEVICE_NETWORK, 0x921, METHOD_OUT_DIRECT, FILE_READ_DATA |\
FILE_WRITE_DATA)
#define IOCTL_WINDIVERT_STARTUP \
CTL_CODE(FILE_DEVICE_NETWORK, 0x922, METHOD_IN_DIRECT, FILE_READ_DATA | \
FILE_WRITE_DATA)
#define IOCTL_WINDIVERT_RECV \
CTL_CODE(FILE_DEVICE_NETWORK, 0x918, METHOD_OUT_DIRECT, FILE_READ_DATA)
CTL_CODE(FILE_DEVICE_NETWORK, 0x923, METHOD_OUT_DIRECT, FILE_READ_DATA)
#define IOCTL_WINDIVERT_SEND \
CTL_CODE(FILE_DEVICE_NETWORK, 0x919, METHOD_IN_DIRECT, FILE_READ_DATA | \
FILE_WRITE_DATA)
#define IOCTL_WINDIVERT_START_FILTER \
CTL_CODE(FILE_DEVICE_NETWORK, 0x91A, METHOD_IN_DIRECT, FILE_READ_DATA | \
FILE_WRITE_DATA)
#define IOCTL_WINDIVERT_SET_LAYER \
CTL_CODE(FILE_DEVICE_NETWORK, 0x91B, METHOD_IN_DIRECT, FILE_READ_DATA | \
FILE_WRITE_DATA)
#define IOCTL_WINDIVERT_SET_PRIORITY \
CTL_CODE(FILE_DEVICE_NETWORK, 0x91C, METHOD_IN_DIRECT, FILE_READ_DATA | \
FILE_WRITE_DATA)
#define IOCTL_WINDIVERT_SET_FLAGS \
CTL_CODE(FILE_DEVICE_NETWORK, 0x91D, METHOD_IN_DIRECT, FILE_READ_DATA | \
CTL_CODE(FILE_DEVICE_NETWORK, 0x924, METHOD_IN_DIRECT, FILE_READ_DATA | \
FILE_WRITE_DATA)
#define IOCTL_WINDIVERT_SET_PARAM \
CTL_CODE(FILE_DEVICE_NETWORK, 0x91E, METHOD_IN_DIRECT, FILE_READ_DATA | \
CTL_CODE(FILE_DEVICE_NETWORK, 0x925, METHOD_IN_DIRECT, FILE_READ_DATA | \
FILE_WRITE_DATA)
#define IOCTL_WINDIVERT_GET_PARAM \
CTL_CODE(FILE_DEVICE_NETWORK, 0x91F, METHOD_OUT_DIRECT, FILE_READ_DATA)
CTL_CODE(FILE_DEVICE_NETWORK, 0x926, METHOD_OUT_DIRECT, FILE_READ_DATA)
#define IOCTL_WINDIVERT_SHUTDOWN \
CTL_CODE(FILE_DEVICE_NETWORK, 0x927, METHOD_IN_DIRECT, FILE_READ_DATA | \
FILE_WRITE_DATA)
#endif /* __WINDIVERT_DEVICE_H */
+5 -11
View File
@@ -23,12 +23,6 @@ CopyFiles = WinDivertCalloutDriver.DriverFiles
[DefaultInstall.Services]
AddService = %ServiceName%,,WinDivertCalloutDriver.Service
[DefaultUninstall]
DelFiles = WinDivertCalloutDriver.DriverFiles
[DefaultUninstall.Services]
DelService = WinDivertCalloutDriver,0x200 ; SPSVCINST_STOPSERVICE
[WinDivertCalloutDriver.DriverFiles]
WinDivert32.sys,,,0x00000040 ; COPYFLG_OVERWRITE_OLDER_ONLY
@@ -41,8 +35,8 @@ ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %12%\WinDivert32.sys
[Strings]
%Basil% = "Basil"
%DiskName% = "WinDivert Installation Disk"
%Description% = "WinDivert Driver"
%ServiceName% = "WinDivert"
%ServiceDesc% = "WinDivert Driver"
Basil = "Basil"
DiskName = "WinDivert Installation Disk"
Description = "WinDivert Driver"
ServiceName = "WinDivert"
ServiceDesc = "WinDivert Driver"
+5 -11
View File
@@ -23,12 +23,6 @@ CopyFiles = WinDivertCalloutDriver.DriverFiles
[DefaultInstall.Services]
AddService = %ServiceName%,,WinDivertCalloutDriver.Service
[DefaultUninstall]
DelFiles = WinDivertCalloutDriver.DriverFiles
[DefaultUninstall.Services]
DelService = WinDivertCalloutDriver,0x200 ; SPSVCINST_STOPSERVICE
[WinDivertCalloutDriver.DriverFiles]
WinDivert64.sys,,,0x00000040 ; COPYFLG_OVERWRITE_OLDER_ONLY
@@ -41,8 +35,8 @@ ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %12%\WinDivert64.sys
[Strings]
%Basil% = "Basil"
%DiskName% = "WinDivert Installation Disk"
%Description% = "WinDivert Driver"
%ServiceName% = "WinDivert"
%ServiceDesc% = "WinDivert Driver"
Basil = "Basil"
DiskName = "WinDivert Installation Disk"
Description = "WinDivert Driver"
ServiceName = "WinDivert"
ServiceDesc = "WinDivert Driver"
+21 -9
View File
@@ -1,7 +1,7 @@
#!/bin/bash
#
# mingw-build.sh
# (C) 2018, all rights reserved,
# (C) 2019, all rights reserved,
#
# This file is part of WinDivert.
#
@@ -39,6 +39,11 @@ set -e
ENVS="i686-w64-mingw32 x86_64-w64-mingw32"
if [ "$1" = "debug" ]
then
MSVCRT=-lmsvcrt
fi
for ENV in $ENVS
do
if [ $ENV = "i686-w64-mingw32" ]
@@ -51,17 +56,17 @@ do
BITS=64
MANGLE=
fi
HAVE_SYS=yes
if [ ! -d install/WDDK/$CPU ]
then
echo "WARNING: missing WDDK build; run wddk-build.bat first"
echo "SKIP MINGW-$CPU"
continue
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="-lgcc -lkernel32 -ladvapi32"
CLIBS="-lkernel32 -ladvapi32 $MSVCRT"
STRIP="$ENV-strip"
DLLTOOL="$ENV-dlltool"
if [ -x "`which $CC`" ]
@@ -97,20 +102,27 @@ do
$CC -s -O2 -Iinclude/ examples/streamdump/streamdump.c \
-o "install/MINGW/$CPU/streamdump.exe" -lWinDivert -lws2_32 \
-L"install/MINGW/$CPU/"
echo "\tcopy install/MINGW/$CPU/flowtrack.exe..."
echo "\tbuild install/MINGW/$CPU/flowtrack.exe..."
$CC -s -O2 -Iinclude/ examples/flowtrack/flowtrack.c \
-o "install/MINGW/$CPU/flowtrack.exe" -lWinDivert -lpsapi \
-lshlwapi -L"install/MINGW/$CPU/"
echo "\tcopy install/MINGW/$CPU/windivertctl.exe..."
echo "\tbuild install/MINGW/$CPU/windivertctl.exe..."
$CC -s -O2 -Iinclude/ examples/windivertctl/windivertctl.c \
-o "install/MINGW/$CPU/windivertctl.exe" -lWinDivert \
-lpsapi -lshlwapi -L"install/MINGW/$CPU/"
echo "\tcopy install/MINGW/$CPU/socketdump.exe..."
echo "\tbuild install/MINGW/$CPU/socketdump.exe..."
$CC -s -O2 -Iinclude/ examples/socketdump/socketdump.c \
-o "install/MINGW/$CPU/socketdump.exe" -lWinDivert \
-lpsapi -lshlwapi -L"install/MINGW/$CPU/"
echo "\tcopy install/MINGW/$CPU/WinDivert$BITS.sys..."
cp install/WDDK/$CPU/WinDivert$BITS.sys install/MINGW/$CPU
echo "\tbuild install/MINGW/$CPU/test.exe..."
$CC -s -O2 -Iinclude/ test/test.c \
-o "install/MINGW/$CPU/test.exe" -lWinDivert \
-L"install/MINGW/$CPU/"
if [ $HAVE_SYS = yes ]
then
echo "\tcopy install/MINGW/$CPU/WinDivert$BITS.sys..."
cp install/WDDK/$CPU/WinDivert$BITS.sys install/MINGW/$CPU
fi
else
echo "WARNING: $CC not found"
fi
+150
View File
@@ -0,0 +1,150 @@
:: msvc-build.bat
:: (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.
@echo off
msbuild sys\windivert.vcxproj ^
/p:Configuration=Release ^
/p:platform=Win32 ^
/p:SignMode=Off ^
/p:OutDir=..\install\MSVC\i386\ ^
/p:AssemblyName=WinDivert32
msbuild sys\windivert.vcxproj ^
/p:Configuration=Release ^
/p:platform=x64 ^
/p:SignMode=Off ^
/p:OutDir=..\install\MSVC\amd64\ ^
/p:AssemblyName=WinDivert64
msbuild dll\windivert.vcxproj ^
/p:Configuration=Release ^
/p:platform=Win32 ^
/p:OutDir=..\install\MSVC\i386\
move dll\WinDivert.lib install\MSVC\i386\.
msbuild dll\windivert.vcxproj ^
/p:Configuration=Release ^
/p:platform=x64 ^
/p:OutDir=..\install\MSVC\amd64\
move dll\WinDivert.lib install\MSVC\amd64\.
msbuild examples\flowtrack\flowtrack.vcxproj ^
/p:Configuration=Release ^
/p:Platform=Win32 ^
/p:OutDir=..\..\install\MSVC\i386\
msbuild examples\flowtrack\flowtrack.vcxproj ^
/p:Configuration=Release ^
/p:Platform=x64 ^
/p:OutDir=..\..\install\MSVC\amd64\
msbuild examples\netdump\netdump.vcxproj ^
/p:Configuration=Release ^
/p:Platform=Win32 ^
/p:OutDir=..\..\install\MSVC\i386\
msbuild examples\netdump\netdump.vcxproj ^
/p:Configuration=Release ^
/p:Platform=x64 ^
/p:OutDir=..\..\install\MSVC\amd64\
msbuild examples\netfilter\netfilter.vcxproj ^
/p:Configuration=Release ^
/p:Platform=Win32 ^
/p:OutDir=..\..\install\MSVC\i386\
msbuild examples\netfilter\netfilter.vcxproj ^
/p:Configuration=Release ^
/p:Platform=x64 ^
/p:OutDir=..\..\install\MSVC\amd64\
msbuild examples\passthru\passthru.vcxproj ^
/p:Configuration=Release ^
/p:Platform=Win32 ^
/p:OutDir=..\..\install\MSVC\i386\
msbuild examples\passthru\passthru.vcxproj ^
/p:Configuration=Release ^
/p:Platform=x64 ^
/p:OutDir=..\..\install\MSVC\amd64\
msbuild examples\socketdump\socketdump.vcxproj ^
/p:Configuration=Release ^
/p:Platform=Win32 ^
/p:OutDir=..\..\install\MSVC\i386\
msbuild examples\socketdump\socketdump.vcxproj ^
/p:Configuration=Release ^
/p:Platform=x64 ^
/p:OutDir=..\..\install\MSVC\amd64\
msbuild examples\streamdump\streamdump.vcxproj ^
/p:Configuration=Release ^
/p:Platform=Win32 ^
/p:OutDir=..\..\install\MSVC\i386\
msbuild examples\streamdump\streamdump.vcxproj ^
/p:Configuration=Release ^
/p:Platform=x64 ^
/p:OutDir=..\..\install\MSVC\amd64\
msbuild examples\webfilter\webfilter.vcxproj ^
/p:Configuration=Release ^
/p:Platform=Win32 ^
/p:OutDir=..\..\install\MSVC\i386\
msbuild examples\webfilter\webfilter.vcxproj ^
/p:Configuration=Release ^
/p:Platform=x64 ^
/p:OutDir=..\..\install\MSVC\amd64\
msbuild examples\windivertctl\windivertctl.vcxproj ^
/p:Configuration=Release ^
/p:Platform=Win32 ^
/p:OutDir=..\..\install\MSVC\i386\
msbuild examples\windivertctl\windivertctl.vcxproj ^
/p:Configuration=Release ^
/p:Platform=x64 ^
/p:OutDir=..\..\install\MSVC\amd64\
msbuild test\test.vcxproj ^
/p:Configuration=Release ^
/p:Platform=Win32 ^
/p:OutDir=..\install\MSVC\i386\
msbuild test\test.vcxproj ^
/p:Configuration=Release ^
/p:Platform=x64 ^
/p:OutDir=..\install\MSVC\amd64\
+121 -91
View File
@@ -1,7 +1,7 @@
#!/bin/bash
#
# release-build.sh
# (C) 2018, all rights reserved,
# (C) 2019, all rights reserved,
#
# This file is part of WinDivert.
#
@@ -37,99 +37,129 @@
set -e
LABEL=
if [ $# -ge 1 ]
then
LABEL="-$1"
fi
TARGET=MINGW
WINDIVERT32_SYS=install/$TARGET/i386/WinDivert32.sys
if [ $# -ge 2 ]
then
WINDIVERT32_SYS=$2
fi
WINDIVERT64_SYS=install/$TARGET/amd64/WinDivert64.sys
if [ $# -ge 3 ]
then
WINDIVERT64_SYS=$3
fi
VERSION=`cat ./VERSION`
NAME=WinDivert-$VERSION
for TARGET in MINGW
do
if [ ! -d "install/$TARGET" ]
echo "BUILD $NAME$LABEL"
INSTALL=install/$NAME$LABEL
echo "\tmake $INSTALL..."
rm -rf $INSTALL
mkdir -p $INSTALL
echo "\tcopy $INSTALL/README..."
cp README $INSTALL
echo "\tcopy $INSTALL/CHANGELOG..."
cp CHANGELOG $INSTALL
echo "\tcopy $INSTALL/LICENSE..."
cp LICENSE $INSTALL
echo "\tcopy $INSTALL/VERSION..."
cp VERSION $INSTALL
echo "\tmake $INSTALL/include..."
mkdir -p $INSTALL/include
echo "\tcopy $INSTALL/include/windivert.h..."
cp include/windivert.h $INSTALL/include
echo "\tmake $INSTALL/doc..."
mkdir -p $INSTALL/doc
echo "\tcopy $INSTALL/doc/WinDivert.html..."
cp doc/windivert.html $INSTALL/doc/WinDivert.html
echo "\tmake $INSTALL/x86..."
mkdir -p $INSTALL/x86
echo "\tcopy $INSTALL/x86/WinDivert32.sys..."
cp "$WINDIVERT32_SYS" $INSTALL/x86
if ! grep "DigiCert High Assurance EV Root" $INSTALL/x86/WinDivert32.sys \
2>&1 >/dev/null
then
echo "\t\033[33mWARNING\033[0m: unsigned WinDivert32.sys..."
fi
if [ -e "$WINDIVERT64_SYS" ]
then
echo "\tcopy $INSTALL/x64/WinDivert64.sys..."
cp "$WINDIVERT64_SYS" $INSTALL/x86
fi
echo "\tcopy $INSTALL/x86/WinDivert.lib..."
cp install/$TARGET/i386/WinDivert.lib $INSTALL/x86
echo "\tcopy $INSTALL/x86/WinDivert.dll..."
cp install/$TARGET/i386/WinDivert.dll $INSTALL/x86
echo "\tcopy $INSTALL/x86/netdump.exe..."
cp install/$TARGET/i386/netdump.exe $INSTALL/x86
echo "\tcopy $INSTALL/x86/netfilter.exe..."
cp install/$TARGET/i386/netfilter.exe $INSTALL/x86
echo "\tcopy $INSTALL/x86/passtru.exe..."
cp install/$TARGET/i386/passthru.exe $INSTALL/x86
echo "\tcopy $INSTALL/x86/webfilter.exe..."
cp install/$TARGET/i386/webfilter.exe $INSTALL/x86
echo "\tcopy $INSTALL/x86/streamdump.exe..."
cp install/$TARGET/i386/streamdump.exe $INSTALL/x86
echo "\tcopy $INSTALL/x86/flowtrack.exe..."
cp install/$TARGET/i386/flowtrack.exe $INSTALL/x86
echo "\tcopy $INSTALL/x86/socketdump.exe..."
cp install/$TARGET/i386/socketdump.exe $INSTALL/x86
echo "\tcopy $INSTALL/x86/windivertctl.exe..."
cp install/$TARGET/i386/windivertctl.exe $INSTALL/x86
echo "\tcopy $INSTALL/x86/test.exe..."
cp install/$TARGET/i386/test.exe $INSTALL/x86
if [ -d "install/$TARGET/amd64" ]
then
echo "\tmake $INSTALL/amd64..."
mkdir -p $INSTALL/x64
echo "\tcopy $INSTALL/amd64/WinDivert64.sys..."
cp "$WINDIVERT64_SYS" $INSTALL/x64
if ! grep "DigiCert High Assurance EV Root" \
$INSTALL/x64/WinDivert64.sys 2>&1 >/dev/null
then
echo "SKIP $NAME-$TARGET"
continue
echo "\t\033[33mWARNING\033[0m: unsigned WinDivert64.sys..."
fi
echo "BUILD $NAME"
INSTALL=install/$NAME
echo "\tmake $INSTALL..."
mkdir -p $INSTALL
echo "\tcopy $INSTALL/README..."
cp README $INSTALL
echo "\tcopy $INSTALL/CHANGELOG..."
cp CHANGELOG $INSTALL
echo "\tcopy $INSTALL/LICENSE..."
cp LICENSE $INSTALL
echo "\tcopy $INSTALL/VERSION..."
cp VERSION $INSTALL
echo "\tmake $INSTALL/include..."
mkdir -p $INSTALL/include
echo "\tcopy $INSTALL/include/windivert.h..."
cp include/windivert.h $INSTALL/include
echo "\tmake $INSTALL/doc..."
mkdir -p $INSTALL/doc
echo "\tcopy $INSTALL/doc/WinDivert.html..."
cp doc/windivert.html $INSTALL/doc/WinDivert.html
echo "\tmake $INSTALL/x86..."
mkdir -p $INSTALL/x86
echo "\tcopy $INSTALL/x86/WinDivert32.sys..."
cp install/$TARGET/i386/WinDivert32.sys $INSTALL/x86
if ! grep "DigiCert High Assurance EV Root" $INSTALL/x86/WinDivert32.sys \
2>&1 >/dev/null
then
echo "\t\033[33mWARNING\033[0m: unsigned WinDivert32.sys..."
fi
echo "\tcopy $INSTALL/x86/WinDivert.lib..."
cp install/$TARGET/i386/WinDivert.lib $INSTALL/x86
echo "\tcopy $INSTALL/x86/WinDivert.dll..."
cp install/$TARGET/i386/WinDivert.dll $INSTALL/x86
echo "\tcopy $INSTALL/x86/netdump.exe..."
cp install/$TARGET/i386/netdump.exe $INSTALL/x86
echo "\tcopy $INSTALL/x86/netfilter.exe..."
cp install/$TARGET/i386/netfilter.exe $INSTALL/x86
echo "\tcopy $INSTALL/x86/passtru.exe..."
cp install/$TARGET/i386/passthru.exe $INSTALL/x86
echo "\tcopy $INSTALL/x86/webfilter.exe..."
cp install/$TARGET/i386/webfilter.exe $INSTALL/x86
echo "\tcopy $INSTALL/x86/streamdump.exe..."
cp install/$TARGET/i386/streamdump.exe $INSTALL/x86
echo "\tcopy $INSTALL/i386/flowtrack.exe..."
cp install/$TARGET/i386/flowtrack.exe $INSTALL/amd64
if [ -d "install/$TARGET/amd64" ]
then
echo "\tmake $INSTALL/amd64..."
mkdir -p $INSTALL/amd64
echo "\tcopy $INSTALL/amd64/WinDivert64.sys..."
cp install/$TARGET/amd64/WinDivert64.sys $INSTALL/amd64
if ! grep "DigiCert High Assurance EV Root" \
$INSTALL/amd64/WinDivert64.sys 2>&1 >/dev/null
then
echo -e "\t\033[33mWARNING\033[0m: unsigned WinDivert64.sys..."
fi
echo "\tcopy $INSTALL/amd64/WinDivert.lib..."
cp install/$TARGET/amd64/WinDivert.lib $INSTALL/amd64
echo "\tcopy $INSTALL/amd64/WinDivert.dll..."
cp install/$TARGET/amd64/WinDivert.dll $INSTALL/amd64
echo "\tcopy $INSTALL/amd64/netdump.exe..."
cp install/$TARGET/amd64/netdump.exe $INSTALL/amd64
echo "\tcopy $INSTALL/amd64/netfilter.exe..."
cp install/$TARGET/amd64/netfilter.exe $INSTALL/amd64
echo "\tcopy $INSTALL/amd64/passtru.exe..."
cp install/$TARGET/amd64/passthru.exe $INSTALL/amd64
echo "\tcopy $INSTALL/amd64/webfilter.exe..."
cp install/$TARGET/amd64/webfilter.exe $INSTALL/amd64
echo "\tcopy $INSTALL/amd64/streamdump.exe..."
cp install/$TARGET/amd64/streamdump.exe $INSTALL/amd64
echo "\tcopy $INSTALL/amd64/flowtrack.exe..."
cp install/$TARGET/amd64/flowtrack.exe $INSTALL/amd64
else
echo "\tWARNING: skipping missing AMD64 build..."
fi
PACKAGE=$NAME.zip
echo "\tbuilding $PACKAGE..."
(
cd install;
zip -r $PACKAGE $NAME > /dev/null
)
echo -n "\tclean $INSTALL..."
rm -rf $INSTALL
echo "DONE"
done
echo "\tcopy $INSTALL/x64/WinDivert.lib..."
cp install/$TARGET/amd64/WinDivert.lib $INSTALL/x64
echo "\tcopy $INSTALL/x64/WinDivert.dll..."
cp install/$TARGET/amd64/WinDivert.dll $INSTALL/x64
echo "\tcopy $INSTALL/x64/netdump.exe..."
cp install/$TARGET/amd64/netdump.exe $INSTALL/x64
echo "\tcopy $INSTALL/x64/netfilter.exe..."
cp install/$TARGET/amd64/netfilter.exe $INSTALL/x64
echo "\tcopy $INSTALL/x64/passtru.exe..."
cp install/$TARGET/amd64/passthru.exe $INSTALL/x64
echo "\tcopy $INSTALL/x64/webfilter.exe..."
cp install/$TARGET/amd64/webfilter.exe $INSTALL/x64
echo "\tcopy $INSTALL/x64/streamdump.exe..."
cp install/$TARGET/amd64/streamdump.exe $INSTALL/x64
echo "\tcopy $INSTALL/x64/flowtrack.exe..."
cp install/$TARGET/amd64/flowtrack.exe $INSTALL/x64
echo "\tcopy $INSTALL/x64/socketdump.exe..."
cp install/$TARGET/amd64/socketdump.exe $INSTALL/x64
echo "\tcopy $INSTALL/x64/windivertctl.exe..."
cp install/$TARGET/amd64/windivertctl.exe $INSTALL/x64
echo "\tcopy $INSTALL/x64/test.exe..."
cp install/$TARGET/amd64/test.exe $INSTALL/x64
else
echo "\tWARNING: skipping missing AMD64 build..."
fi
PACKAGE=$NAME$LABEL.zip
echo "\tbuilding $PACKAGE..."
(
cd install;
zip -r $PACKAGE $NAME$LABEL > /dev/null
)
echo -n "\tclean $INSTALL..."
rm -rf $INSTALL
echo "DONE"
+1594 -807
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1,6 +1,6 @@
/*
* windivert.rc
* (C) 2018, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -38,7 +38,7 @@
#define VER_FILETYPE VFT_DRV
#define VER_FILESUBTYPE VFT2_DRV_NETWORK
#define VER_FILEDESCRIPTION_STR \
"The WinDivert driver " \
"The WinDivert 2.0 driver " \
"[URL: https://reqrypt.org/windivert.html] " \
"[Bitcoin: 1C5vZVSbizPeZ8ydTYhUfm4LA2cNwBfcYh]"
#define VER_INTERNALNAME_STR "WinDivert.sys"
+84
View File
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
windivert.vcxproj
(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.
-->
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="windivert.c">
<TreatWarningAsError>false</TreatWarningAsError>
<Optimization>MaxSpeed</Optimization>
<AdditionalIncludeDirectories>..\include;..\dll</AdditionalIncludeDirectories>
</ClCompile>
</ItemGroup>
<PropertyGroup Label="Globals">
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<RootNamespace>WinDivert</RootNamespace>
<ProjectName>WinDivert</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Label="Configuration">
<TargetVersion>Windows7</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<EnableInf2cat>false</EnableInf2cat>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ItemDefinitionGroup>
<ClCompile>
<WppEnabled>false</WppEnabled>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions);NDIS60;UNICODE;_UNICODE;NDIS_SUPPORT_NDIS60;NT;BINARY_COMPATIBLE=0</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions);NDIS60;UNICODE;_UNICODE;NDIS_SUPPORT_NDIS60;NT;BINARY_COMPATIBLE=0</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfLdr.lib;$(KMDF_LIB_PATH)$(KMDF_VER_PATH)\WdfDriverEntry.lib;$(DDK_LIB_PATH)\wdmsec.lib;$(DDK_LIB_PATH)\ndis.lib;$(DDK_LIB_PATH)\fwpkclnt.lib;$(SDK_LIB_PATH)\uuid.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
+7 -4
View File
@@ -1,7 +1,7 @@
#!/bin/bash
#
# build.sh
# (C) 2018, all rights reserved,
# (C) 2019, all rights reserved,
#
# This file is part of WinDivert.
#
@@ -35,8 +35,11 @@
# Script for MinGW/Linux cross compilation.
# NOTE: run wddk-build.bat before this script.
CC=i686-w64-mingw32-gcc
$CC -fno-ident -s -O2 -I../include/ test.c \
-o ../install/MINGW/i386/test.exe -lWinDivert -L"../install/MINGW/i386/"
CC=x86_64-w64-mingw32-gcc
$CC -fno-ident -s -O2 -I../include/ test.c -o test.exe -lWinDivert \
-L"../install/MINGW/amd64/"
$CC -fno-ident -s -O2 -I../include/ test.c -o ../install/MINGW/amd64/test.exe \
-lWinDivert -L"../install/MINGW/amd64/"
+641 -17
View File
@@ -1,6 +1,6 @@
/*
* test.c
* (C) 2018, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -71,6 +71,7 @@ struct test
*/
static BOOL run_test(HANDLE inject_handle, const char *filter,
const char *packet, const size_t packet_len, BOOL match, INT64 *diff);
static DWORD monitor_worker(LPVOID arg);
/*
* Test data.
@@ -152,6 +153,8 @@ static const struct test tests[] =
{"ip or ipv6", &pkt_echo_request, TRUE},
{"inbound", &pkt_echo_request, FALSE},
{"tcp", &pkt_echo_request, FALSE},
{"tcp == TRUE", &pkt_echo_request, FALSE},
{"tcp == FALSE", &pkt_echo_request, TRUE},
{"icmp.Type == 8", &pkt_echo_request, TRUE},
{"icmp.Type == 9", &pkt_echo_request, FALSE},
{"(tcp? ip.Checksum == 0: icmp)", &pkt_echo_request, TRUE},
@@ -255,7 +258,59 @@ static const struct test tests[] =
{"(((icmp)? (true): (false)) and "
"(((tcp)? (false): (true)) and "
"((ipv6)? (false): (true))))", &pkt_echo_request, TRUE},
{"((((packet[31] > 0x54 or (packet[46] == 0x12 and "
"not packet[78] >= 0x32)) and (not packet[79] <= 0x33 and "
"not packet[81] > 0x35)) and (((not packet[62] <= 0x22 and "
"not packet[54] <= 0x1A) and (not packet[69] <= 0x29 or "
"packet[55] > 0x1B)) or ((not packet[78] != 0x32 and "
"packet[22] != 0x3C)? (not packet[11] <= 0x00? packet[7] >= 0x00: "
"packet[67] >= 0x27): (packet[1] < 0x00? not packet[49] == 0x15: "
"not packet[44] != 0x10))))? ((((not packet[11] > 0x00 and "
"not packet[62] <= 0x22) or (packet[7] < 0x00? packet[23] < 0xD2: "
"not packet[10] != 0x00)) and not packet[74] != 0x2E) or "
"packet[43] >= 0x00): ((((packet[3] == 0x54? packet[19] == 0x08: "
"packet[8] > 0x40) or not packet[80] > 0x34)? ((packet[9] >= 0x01? "
"packet[5] != 0x34: packet[61] > 0x21) or (packet[44] > 0x10 and "
"packet[63] < 0x23)): ((packet[80] <= 0x34 or not packet[78] < 0x32)? "
"(packet[19] != 0x08? packet[40] == 0x00: not packet[71] == 0x2B): "
"(not packet[39] < 0x00 or packet[38] != 0x0A))) or "
"(((not packet[81] > 0x35 and packet[22] <= 0x3C)? "
"(not packet[60] != 0x20? packet[28] < 0x8B: not packet[74] != 0x2E): "
"packet[8] <= 0x40) or ((packet[60] == 0x20? packet[57] <= 0x1D: "
"packet[24] >= 0x0D)? (packet[34] > 0x00 or not packet[53] < 0x19): "
"(packet[11] < 0x00 and packet[35] != 0x00)))))",
&pkt_echo_request, TRUE},
{"(((((packet[23] <= 0xD2 and not packet[1] >= 0x00)? "
"(packet[3] != 0x54 or packet[45] >= 0x11): (packet[4] > 0x12 and "
"packet[2] != 0x00)) or packet[24] > 0x0D) or (((not packet[57] > 0x1D? "
"packet[62] == 0x22: not packet[12] < 0x0A) or (packet[28] > 0x8B? "
"not packet[48] > 0x14: not packet[64] > 0x24)) or ((packet[80] >= 0x34? "
"not packet[3] != 0x54: not packet[26] <= 0x00) and "
"(packet[68] != 0x28 and packet[32] == 0x00))))? not packet[1] == 0x00: "
"((((not packet[36] > 0xF9 and not packet[70] == 0x2A) or "
"(not packet[3] <= 0x54? packet[1] > 0x00: not packet[14] != 0x00)) and "
"packet[57] <= 0x1D)? packet[38] == 0x0A: (((not packet[59] != 0x1F? "
"packet[46] < 0x12: not packet[81] < 0x35) and (packet[27] >= 0x01? "
"not packet[50] > 0x16: not packet[7] <= 0x00))? ((packet[76] >= 0x30 or "
"not packet[54] >= 0x1A) and packet[64] < 0x24): "
"((packet[58] <= 0x1E and packet[81] < 0x35)? (packet[20] < 0x08 or "
"packet[22] <= 0x3C): (not packet[70] >= 0x2A? packet[31] < 0x54: "
"not packet[69] <= 0x29)))))", &pkt_echo_request, FALSE},
{"ip.HdrLength == 5 and ip.TOS == 0 and ip.Length == 84 and "
"ip.Id == 0x1234 and ip.FragOff == 0 and ip.MF == 0 and ip.DF == 1 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_echo_request, TRUE},
{"ip.HdrLength > 5 or ip.TOS > 0 or ip.Length != 84 or ip.Id < 0x1234 or "
"ip.FragOff != 0 or ip.MF < 0 or ip.DF != 1 or ip.TTL > 64 or "
"ip.Protocol != 1 or ip.SrcAddr < 0xFFFF0A000001 or "
"ip.DstAddr < 0xFFFF08080808 or icmp.Type != 8 or icmp.Code != 0 or "
"icmp.Body != 0x0D560001", &pkt_echo_request, FALSE},
{"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},
{"tcp", &pkt_http_request, TRUE},
{"protocol == TCP", &pkt_http_request, TRUE},
{"outbound and tcp and tcp.DstPort == 80", &pkt_http_request, TRUE},
{"outbound and tcp and tcp.DstPort == 81", &pkt_http_request, FALSE},
{"outbound and tcp and tcp.DstPort != 80", &pkt_http_request, FALSE},
@@ -341,15 +396,119 @@ static const struct test tests[] =
"packet[-1] = 0x0a", &pkt_http_request, TRUE},
{"tcp.Payload16[-1] == 0x0d0a", &pkt_http_request, TRUE},
{"tcp.Payload32[-2] == 0x20474d54", &pkt_http_request, TRUE},
{"(ipv6? true: false) or (udp? udp.DstPort != 53: false) or "
"(not tcp and not udp? true: false)", &pkt_http_request, FALSE},
{"ip and !loopback and (outbound? tcp.DstPort == 80 or"
" tcp.DstPort == 443 or udp.DstPort == 53 :"
" icmp.Type == 11 and icmp.Code == 0)", &pkt_http_request, TRUE},
{"random8 < 128", &pkt_http_request, TRUE},
{"(random8 < 128? random16 < 0x8000: random32 < 0x80000000)",
&pkt_http_request, TRUE},
{"(random32 < 0x22223333? packet32[72] == 0x58585858: udp)",
&pkt_http_request, TRUE},
{"(((((not packet[340] != 0x58? not packet[173] < 0x74: "
"not packet[376] > 0x70) or not packet[87] != 0x6F) or "
"not packet[226] > 0x73) and (((not packet[289] <= 0x58 and "
"not packet[76] > 0x77) and (packet[231] < 0x67 and "
"not packet[24] < 0x53))? ((packet[365] > 0x58? not packet[91] <= 0x43: "
"not packet[310] <= 0x58) or (not packet[515] < 0x4D or "
"packet[518] >= 0x0A)): ((not packet[209] < 0x77? "
"not packet[237] > 0x58: not packet[286] == 0x58)? "
"(packet[354] == 0x58 or packet[502] > 0x31): not packet[2] > 0x02)))? "
"(((packet[520] <= 0x0A? (packet[484] == 0x63 and packet[83] >= 0x6C): "
"(packet[384] >= 0x69 or packet[245] >= 0x58)) and "
"(packet[106] > 0x70 or packet[45] != 0x2C))? (((packet[153] == 0x2F or "
"packet[139] >= 0x0D) and (packet[136] != 0x65? packet[100] == 0x6E: "
"not packet[128] == 0x3A))? ((not packet[288] != 0x58 or "
"not packet[309] == 0x58) and packet[350] <= 0x58): "
"not packet[129] >= 0x20): (not packet[493] != 0x30 and "
"((packet[465] != 0x33 or not packet[386] >= 0x67)? "
"(packet[470] >= 0x66 or not packet[259] >= 0x58): "
"packet[408] != 0x41))): ((((not packet[500] > 0x32 or "
"not packet[163] < 0x69) and not packet[122] == 0x6F) and "
"((packet[324] <= 0x58 and packet[481] > 0x53)? "
"(not packet[17] > 0xB8 and packet[102] != 0x20): (packet[303] > 0x58 or "
"packet[345] >= 0x58)))? (packet[191] < 0x6E and ((packet[429] <= 0x53? "
"not packet[239] >= 0x58: packet[258] < 0x58)? packet[382] >= 0x6F: "
"(packet[443] == 0x2D? not packet[67] < 0x0A: packet[168] <= 0x6F))): "
"(((packet[34] == 0x00 and not packet[77] != 0x2E)? "
"(packet[27] != 0xC2? not packet[477] <= 0x69: not packet[472] != 0x4D): "
"(not packet[157] >= 0x6C or not packet[308] <= 0x58)) or "
"((not packet[293] == 0x58? not packet[83] != 0x6C: packet[70] > 0x73)? "
"(not packet[260] < 0x58? packet[98] != 0x69: not packet[226] <= 0x73): "
"(packet[139] < 0x0D and not packet[171] == 0x78)))))",
&pkt_http_request, FALSE},
{"(((((packet[307] > 0x58 or packet[437] == 0x2E)? (packet[331] <= 0x58? "
"packet[39] != 0x00: not packet[503] > 0x34): not packet[248] >= 0x58)? "
"((not packet[266] >= 0x58? packet[510] != 0x3A: "
"not packet[343] == 0x58)? (not packet[183] == 0x70 and "
"not packet[333] <= 0x58): (packet[456] >= 0x22? packet[400] <= 0x65: "
"not packet[218] <= 0x71)): (packet[482] <= 0x69? "
"(packet[288] > 0x58 and packet[142] == 0x63): (packet[8] >= 0x40 or "
"not packet[211] == 0x62))) or ((packet[267] <= 0x58 and "
"(packet[35] != 0x73? packet[36] == 0x02: not packet[100] > 0x6E)) and "
"(not packet[170] > 0x2F and (not packet[289] != 0x58 and "
"not packet[344] < 0x58)))) or ((((not packet[468] > 0x0A and "
"not packet[372] >= 0x41) and (packet[513] < 0x20 or "
"packet[306] == 0x58)) or ((not packet[431] <= 0x65 and "
"not packet[144] < 0x65)? (packet[478] != 0x65? packet[37] <= 0xA4: "
"not packet[26] < 0xCC): (not packet[269] != 0x58 and "
"packet[149] != 0x74)))? (((packet[422] <= 0x65 and "
"not packet[176] > 0x2B) and (not packet[417] > 0x6E? "
"not packet[451] <= 0x74: packet[348] >= 0x58)) and "
"packet[284] != 0x58): (((packet[200] < 0x2E and packet[89] < 0x0D) or "
"(packet[469] == 0x49 and not packet[384] == 0x69))? "
"((not packet[105] >= 0x65 or packet[128] == 0x3A) or "
"packet[389] <= 0x67): not packet[271] >= 0x58)))",
&pkt_http_request, TRUE},
{"(packet[248] != 0x58? ((packet[470] > 0x66 and ((packet[96] < 0x63? "
"not packet[216] >= 0x2A: packet[261] == 0x58)? "
"(not packet[166] > 0x74? packet[502] >= 0x31: not packet[387] > 0x3A): "
"(not packet[387] > 0x3A? not packet[265] < 0x58: "
"packet[237] < 0x58))) and ((not packet[264] < 0x58 or "
"(not packet[113] >= 0x0D? not packet[423] == 0x3A: "
"packet[329] == 0x58)) and (not packet[515] < 0x4D? "
"(packet[172] >= 0x68? packet[286] != 0x58: not packet[121] != 0x43): "
"(not packet[160] < 0x70? not packet[322] != 0x58: "
"not packet[398] < 0x61)))): ((((packet[298] < 0x58 and "
"packet[268] > 0x58) and (not packet[447] <= 0x65 or "
"packet[149] >= 0x74)) or ((not packet[517] != 0x0D or "
"packet[179] < 0x6C)? (not packet[343] > 0x58 or "
"not packet[186] < 0x63): (not packet[255] > 0x58 or "
"not packet[487] == 0x20))) and (((not packet[149] < 0x74? "
"not packet[125] == 0x72: packet[496] < 0x41) and "
"(not packet[344] == 0x58? not packet[261] != 0x58: "
"not packet[317] >= 0x58))? (packet[100] == 0x6E? "
"(not packet[233] == 0x6E? packet[120] >= 0x2D: not packet[186] > 0x63): "
"(not packet[360] == 0x58 or packet[133] > 0x2D)): "
"not packet[477] == 0x69)))", &pkt_http_request, FALSE},
{"ip.HdrLength == 5 and ip.TOS == 0 and ip.Length == 521 and "
"ip.Id == 0x482D and ip.FragOff == 0 and ip.MF == 0 and ip.DF == 1 and "
"ip.TTL == 64 and ip.Protocol == 6 and ip.SrcAddr == 0xFFFF0A0A0A0A and "
"ip.DstAddr == 0xFFFF5DB8D877 and tcp.SrcPort == 41754 and "
"tcp.DstPort == 80 and tcp.SeqNum == 1396231362 and "
"tcp.AckNum == 1446490965 and tcp.HdrLength == 8 and tcp.Fin == 0 and "
"tcp.Syn == 0 and tcp.Rst == 0 and tcp.Psh == 1 and tcp.Ack == 1 and "
"tcp.Urg == 0 and tcp.Window == 115 and tcp.UrgPtr == 0",
&pkt_http_request, TRUE},
{"ip.HdrLength > 5 or ip.TOS < 0 or ip.Length < 521 or ip.Id != 0x482D or "
"ip.FragOff != 0 or ip.MF != 0 or ip.DF < 1 or ip.TTL < 64 or "
"ip.Protocol > 6 or ip.SrcAddr != 0xFFFF0A0A0A0A or "
"ip.DstAddr < 0xFFFF5DB8D877 or tcp.SrcPort < 41754 or "
"tcp.DstPort < 80 or tcp.SeqNum != 1396231362 or "
"tcp.AckNum < 1446490965 or tcp.HdrLength < 8 or tcp.Fin != 0 or "
"tcp.Syn != 0 or tcp.Rst != 0 or tcp.Psh != 1 or tcp.Ack > 1 or "
"tcp.Urg != 0 or tcp.Window < 115 or tcp.UrgPtr < 0",
&pkt_http_request, FALSE},
{"localAddr == 10.10.10.10 && remoteAddr == 93.184.216.119 && "
"localPort == 41754 && remotePort == 80 && protocol == 6",
&pkt_http_request, TRUE},
{"udp", &pkt_dns_request, TRUE},
{"udp && udp.SrcPort > 1 && ipv6", &pkt_dns_request, FALSE},
{"udp.DstPort == 53", &pkt_dns_request, TRUE},
{"udp.DstPort > 100", &pkt_dns_request, FALSE},
{"zero = 0", &pkt_dns_request, TRUE},
{"zero = 1", &pkt_dns_request, FALSE},
{"ip.DstAddr = 8.8.4.4", &pkt_dns_request, TRUE},
{"ip.DstAddr = 8.8.8.8", &pkt_dns_request, FALSE},
{"ip.DstAddr >= 8.8.0.0 &&"
@@ -360,6 +519,13 @@ static const struct test tests[] =
&pkt_dns_request, FALSE},
{"ip.DstAddr == ::ffff:8.8.4.4", &pkt_dns_request, TRUE},
{"ip.DstAddr == ::0:ffff:8.8.4.4", &pkt_dns_request, TRUE},
{"remoteAddr == 8.8.4.4", &pkt_dns_request, TRUE},
{"remoteAddr == ::ffff:8.8.4.4", &pkt_dns_request, TRUE},
{"protocol == 17", &pkt_dns_request, TRUE},
{"remotePort == 53", &pkt_dns_request, TRUE},
{"(ipv6? true: false) or (udp? udp.DstPort != 53: false) or "
"(not tcp and not udp? true: false)", &pkt_dns_request, FALSE},
{"ipv6 or (not tcp and udp.DstPort != 53)",&pkt_dns_request, FALSE},
{"udp.PayloadLength == 29", &pkt_dns_request, TRUE},
{"udp.Payload16[-1] == 0x0001 && udp.Payload16[-2] == 0x0001",
&pkt_dns_request, TRUE},
@@ -367,18 +533,96 @@ static const struct test tests[] =
&pkt_dns_request, TRUE},
{"tcp.Payload32[0] > 0", &pkt_dns_request, FALSE},
{"udp.Payload32[1] > 0", &pkt_dns_request, TRUE},
{"length == 57", &pkt_dns_request, TRUE},
{"(length > 57? udp: tcp)", &pkt_dns_request, FALSE},
{"protocol == UDP", &pkt_dns_request, TRUE},
{"random8 < 128", &pkt_dns_request, TRUE},
{"(random8 < 128? random16 < 0x8000: random32 < 0x80000000)",
&pkt_dns_request, TRUE},
{"((((not packet[22] < 0x00 or (packet[14] > 0x00 and "
"packet[8] <= 0x49))? (not packet[3] > 0x39 and packet[22] <= 0x00): "
"not packet[1] <= 0x00) and (((packet[27] != 0xA7 or "
"packet[16] != 0x08) or (packet[3] > 0x39? packet[18] > 0x04: "
"not packet[32] != 0x00))? ((packet[32] == 0x00? not packet[51] > 0x6D: "
"packet[54] == 0x01)? (not packet[3] >= 0x39 and packet[7] != 0x00): "
"not packet[45] >= 0x70): ((not packet[5] != 0x90? packet[52] > 0x00: "
"packet[49] == 0x63) and (not packet[46] >= 0x6C? packet[15] <= 0x01: "
"not packet[27] >= 0xA7))))? ((((packet[22] > 0x00? "
"not packet[36] >= 0x00: packet[0] > 0x45)? (packet[31] != 0x00? "
"not packet[40] == 0x07: packet[31] >= 0x00): not packet[43] > 0x61) and "
"((not packet[16] == 0x08 and not packet[13] >= 0x00)? "
"(packet[24] <= 0x00 or packet[15] != 0x01): "
"(packet[56] < 0x01? packet[50] > 0x6F: not packet[56] == 0x01)))? "
"(packet[15] >= 0x01 or ((not packet[14] < 0x00? not packet[39] >= 0x00: "
"not packet[4] == 0x20)? (packet[12] >= 0x0A and "
"not packet[25] <= 0x25): packet[2] < 0x00)): "
"(((not packet[19] <= 0x04 or not packet[25] < 0x25)? "
"(packet[10] != 0x00 or packet[25] < 0x25): (not packet[46] > 0x6C? "
"not packet[23] <= 0x35: packet[56] < 0x01))? "
"((not packet[48] >= 0x03 or not packet[1] == 0x00)? "
"(packet[47] >= 0x65 and not packet[13] == 0x00): (packet[34] <= 0x00? "
"packet[22] <= 0x00: packet[43] >= 0x61)): (not packet[6] < 0x00 and "
"not packet[41] < 0x65))): (((not packet[21] != 0x45 and "
"(packet[26] < 0x22 or not packet[46] <= 0x6C)) and "
"((not packet[56] > 0x01? packet[3] == 0x39: not packet[42] >= 0x78)? "
"(not packet[4] > 0x20 or not packet[8] >= 0x49): "
"packet[34] > 0x00)) and ((packet[50] >= 0x6F and "
"(packet[1] != 0x00 and not packet[37] != 0x00)) and "
"((packet[28] == 0x17 or not packet[11] < 0x00) or (packet[40] == 0x07? "
"not packet[54] > 0x01: packet[18] < 0x04)))))",
&pkt_dns_request, FALSE},
{"((((packet[26] > 0x22 or packet[19] != 0x04)? ((not packet[17] > 0x08? "
"packet[20] != 0xE0: packet[52] < 0x00) and not packet[31] == 0x00): "
"((not packet[23] == 0x35 and packet[13] < 0x00) and "
"(not packet[44] > 0x6D and packet[22] <= 0x00)))? "
"(((not packet[27] >= 0xA7? packet[34] >= 0x00: "
"not packet[38] < 0x00) and (not packet[37] < 0x00? packet[40] > 0x07: "
"not packet[50] >= 0x6F)) and packet[36] != 0x00): "
"(((packet[16] == 0x08? not packet[50] > 0x6F: packet[51] != 0x6D)? "
"not packet[29] != 0x08: packet[16] <= 0x08)? "
"((not packet[32] != 0x00 or not packet[26] != 0x22) or "
"(not packet[27] != 0xA7 and not packet[21] == 0x45)): "
"((packet[30] >= 0x01 or packet[40] > 0x07) or "
"(not packet[46] < 0x6C and packet[56] <= 0x01))))? packet[31] <= 0x00: "
"(not packet[50] >= 0x6F and not packet[9] <= 0x11))",
&pkt_dns_request, TRUE},
{"packet32[13] <= 0xFFFFFFE", &pkt_dns_request, TRUE},
{"packet32[53b] <= 0xFFFFFFE", &pkt_dns_request, TRUE},
{"packet32[14] <= 0xFFFFFFE", &pkt_dns_request, FALSE},
{"packet32[54b] <= 0xFFFFFFE", &pkt_dns_request, FALSE},
{"ip.HdrLength == 5 and ip.TOS == 0 and ip.Length == 57 and "
"ip.Id == 0x2090 and ip.FragOff == 0 and ip.MF == 0 and ip.DF == 0 and "
"ip.TTL == 73 and ip.Protocol == 17 and ip.SrcAddr == 0xFFFF0A000001 and "
"ip.DstAddr == 0xFFFF08080404 and udp.SrcPort == 57413 and "
"udp.DstPort == 53 and udp.Length == 37", &pkt_dns_request, TRUE},
{"ip.HdrLength > 5 or ip.TOS > 0 or ip.Length < 57 or ip.Id > 0x2090 or "
"ip.FragOff != 0 or ip.MF < 0 or ip.DF < 0 or ip.TTL > 73 or "
"ip.Protocol < 17 or ip.SrcAddr < 0xFFFF0A000001 or "
"ip.DstAddr > 0xFFFF08080404 or udp.SrcPort > 57413 or "
"udp.DstPort != 53 or udp.Length < 37", &pkt_dns_request, FALSE},
{"localAddr == 10.0.0.1 && remoteAddr == 8.8.4.4 && "
"localPort == 57413 && remotePort == 53 && protocol == 17",
&pkt_dns_request, TRUE},
{"ipv6", &pkt_ipv6_tcp_syn, TRUE},
{"ip", &pkt_ipv6_tcp_syn, FALSE},
{"tcp.Syn", &pkt_ipv6_tcp_syn, TRUE},
{"tcp.Syn == ::1 && tcp.Syn < ::ffff:aaaa:bbbb:cccc:dddd",
&pkt_ipv6_tcp_syn, TRUE},
{"tcp.DstPort >= 23 && tcp.DstPort <= 23", &pkt_ipv6_tcp_syn, TRUE},
{"tcp.Syn and not tcp.Ack", &pkt_ipv6_tcp_syn, TRUE},
{"tcp.Syn == 1 && tcp.Ack == 0", &pkt_ipv6_tcp_syn, TRUE},
{"tcp.Rst or tcp.Fin", &pkt_ipv6_tcp_syn, FALSE},
{"(tcp.Syn? !tcp.Rst && !tcp.Fin: true)", &pkt_ipv6_tcp_syn, TRUE},
{"(tcp.Rst? !tcp.Syn: (tcp.Fin? !tcp.Syn: tcp.Syn))",
&pkt_ipv6_tcp_syn, TRUE},
{"(tcp.Rst or tcp.Urg or tcp.Psh or tcp.Fin? false: tcp.Syn)",
&pkt_ipv6_tcp_syn, TRUE},
{"(tcp.Rst and tcp.Urg and tcp.Psh and tcp.Fin? false: tcp.Syn)",
&pkt_ipv6_tcp_syn, TRUE},
{"tcp.PayloadLength == 0", &pkt_ipv6_tcp_syn, 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_tcp_syn, FALSE},
{"ipv6.SrcAddr == 1234:5678:1::aabb:ccdd", &pkt_ipv6_tcp_syn, TRUE},
{"ipv6.SrcAddr == aabb:5678:1::1234:ccdd", &pkt_ipv6_tcp_syn, FALSE},
{"tcp.SrcPort == 50046", &pkt_ipv6_tcp_syn, TRUE},
@@ -392,8 +636,83 @@ static const struct test tests[] =
{"random8 < 128", &pkt_ipv6_tcp_syn, TRUE},
{"(random8 < 128? random16 < 0x8000: random32 < 0x80000000)",
&pkt_ipv6_tcp_syn, TRUE},
{"((((packet[56] != 0xC3? not packet[26] > 0x00: (packet[50] <= 0x00? "
"packet[62] < 0xFF: not packet[43] < 0x17))? not packet[2] > 0x00: "
"(packet[69] != 0xFF or (not packet[28] >= 0x00 and "
"not packet[79] > 0x07)))? (((packet[46] < 0xC8 or "
"packet[47] == 0xAA) or (packet[51] == 0x00 and packet[0] >= 0x60))? "
"packet[55] == 0xAA: not packet[79] >= 0x07): not packet[53] < 0x02)? "
"((not packet[65] > 0x02 and ((packet[36] >= 0x00 or "
"packet[24] < 0x00) and packet[3] != 0x00)) and (not packet[56] < 0xC3? "
"(not packet[0] <= 0x60 and (not packet[38] == 0x00 and "
"packet[78] > 0x03)): ((not packet[56] == 0xC3 and "
"not packet[9] < 0x34) and (packet[21] > 0xBB? not packet[67] < 0x0A: "
"not packet[75] >= 0x00)))): not packet[5] > 0x28)",
&pkt_ipv6_tcp_syn, FALSE},
{"(((packet[8] >= 0x12 and ((not packet[36] >= 0x00? "
"not packet[57] > 0x5E: packet[66] > 0x08) and "
"(not packet[53] > 0x02? not packet[2] == 0x00: packet[76] < 0x01))) or "
"(((not packet[26] <= 0x00? not packet[57] <= 0x5E: packet[7] >= 0x40)? "
"packet[60] > 0x02: not packet[11] <= 0x78) or ((packet[71] != 0x86? "
"packet[65] > 0x02: not packet[4] > 0x00)? (not packet[2] != 0x00? "
"not packet[57] < 0x5E: not packet[14] == 0x00): "
"(not packet[25] != 0x00 or packet[29] >= 0x00)))) or "
"(not packet[59] <= 0x00 or ((packet[76] < 0x01? not packet[7] < 0x40: "
"(packet[66] != 0x08 and not packet[30] > 0x00)) or "
"not packet[20] <= 0xAA)))", &pkt_ipv6_tcp_syn, TRUE},
{"((packet[50] >= 0x00? packet[8] != 0x12: (((packet[33] > 0x00? "
"packet[15] >= 0x00: not packet[21] == 0xBB) or (packet[67] > 0x0A? "
"packet[9] == 0x34: packet[36] > 0x00)) and (packet[74] < 0x00? "
"(packet[60] != 0x02 and not packet[26] >= 0x00): "
"(not packet[29] == 0x00 and not packet[25] < 0x00)))) or "
"((((not packet[69] != 0xFF or packet[10] >= 0x56)? packet[8] >= 0x12: "
"(packet[78] < 0x03 and packet[9] >= 0x34))? ((packet[40] <= 0xC3? "
"not packet[15] > 0x00: not packet[71] != 0x86) and "
"not packet[45] != 0xD7): ((not packet[50] >= 0x00 or "
"not packet[1] == 0x00) or not packet[55] >= 0xAA))? "
"(not packet[32] == 0x00? (not packet[58] <= 0x00 and "
"not packet[8] > 0x12): (not packet[7] < 0x40 or "
"not packet[4] >= 0x00)): (((not packet[23] < 0xDD or "
"packet[68] >= 0xFF) and (packet[50] == 0x00 and "
"not packet[12] >= 0x00))? packet[48] >= 0x00: ((packet[10] != 0x56 and "
"not packet[4] == 0x00) and (packet[11] >= 0x78? not packet[18] > 0x00: "
"not packet[55] == 0xAA)))))", &pkt_ipv6_tcp_syn, TRUE},
{"((packet[79] <= 0x07 and not packet[62] == 0xFF) and "
"((((not packet[20] > 0xAA? packet[20] <= 0xAA: packet[27] <= 0x00) and "
"(packet[62] > 0xFF? packet[12] == 0x00: not packet[19] == 0x00)) and "
"((not packet[68] == 0xFF and packet[75] > 0x00)? (packet[6] <= 0x06 or "
"packet[76] <= 0x01): not packet[50] == 0x00)) and (packet[57] >= 0x5E? "
"((not packet[75] >= 0x00? packet[75] != 0x00: not packet[63] != 0xC4)? "
"not packet[1] < 0x00: (packet[30] > 0x00? packet[16] == 0x00: "
"packet[36] == 0x00)): ((packet[66] < 0x08? not packet[0] < 0x60: "
"packet[72] != 0x00)? (packet[25] > 0x00 or not packet[13] < 0x01): "
"(packet[47] <= 0xAA and not packet[15] != 0x00)))))",
&pkt_ipv6_tcp_syn, FALSE},
{"packet32[-4b] < 0xFFFFFFFE", &pkt_ipv6_tcp_syn, TRUE},
{"ipv6.TrafficClass == 0x00000000 and ipv6.FlowLabel == 0x0000 and "
"ipv6.Length == 40 and ipv6.NextHdr == 6 and ipv6.HopLimit == 64 and "
"ipv6.SrcAddr == 1234:5678:1:0:0:0:aabb:ccdd and "
"ipv6.DstAddr == 0:0:0:0:0:0:0:1 and tcp.SrcPort == 50046 and "
"tcp.DstPort == 23 and tcp.SeqNum == 3789015210 and tcp.AckNum == 0 and "
"tcp.HdrLength == 10 and tcp.Fin == 0 and tcp.Syn == 1 and "
"tcp.Rst == 0 and tcp.Psh == 0 and tcp.Ack == 0 and tcp.Urg == 0 and "
"tcp.Window == 43690 and tcp.UrgPtr == 0",&pkt_ipv6_tcp_syn, TRUE},
{"ipv6.TrafficClass > 0x00000000 or ipv6.FlowLabel < 0x0000 or "
"ipv6.Length < 40 or ipv6.NextHdr != 6 or ipv6.HopLimit > 64 or "
"ipv6.SrcAddr != 1234:5678:1:0:0:0:aabb:ccdd or "
"ipv6.DstAddr < 0:0:0:0:0:0:0:1 or tcp.SrcPort < 50046 or "
"tcp.DstPort > 23 or tcp.SeqNum < 3789015210 or tcp.AckNum < 0 or "
"tcp.HdrLength != 10 or tcp.Fin > 0 or tcp.Syn > 1 or tcp.Rst > 0 or "
"tcp.Psh > 0 or tcp.Ack != 0 or tcp.Urg != 0 or tcp.Window != 43690 or "
"tcp.UrgPtr != 0", &pkt_ipv6_tcp_syn, FALSE},
{"localAddr == 1234:5678:1::aabb:ccdd && remoteAddr == ::1 && "
"localPort == 50046 && remotePort == 23 && protocol == 6",
&pkt_ipv6_tcp_syn, TRUE},
{"packet[0] == 0x60", &pkt_ipv6_tcp_syn, TRUE},
{"icmpv6", &pkt_ipv6_echo_reply, TRUE},
{"icmp", &pkt_ipv6_echo_reply, FALSE},
{"protocol == ICMPV6", &pkt_ipv6_echo_reply, TRUE},
{"protocol == ICMP", &pkt_ipv6_echo_reply, FALSE},
{"icmp or icmpv6", &pkt_ipv6_echo_reply, TRUE},
{"not icmp", &pkt_ipv6_echo_reply, TRUE},
{"icmpv6.Type == 129", &pkt_ipv6_echo_reply, TRUE},
@@ -401,11 +720,59 @@ 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},
{"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},
{"random8 < 128", &pkt_ipv6_echo_reply, TRUE},
{"(random8 < 128? random16 < 0x8000: random32 < 0x80000000)",
&pkt_ipv6_echo_reply, TRUE},
{"(((((not packet[68] != 0x44? packet[58] >= 0x00: "
"not packet[39] >= 0x01) and not packet[101] != 0x55) and "
"((not packet[70] >= 0x66? not packet[68] > 0x44: "
"not packet[77] > 0xDD) and (not packet[72] <= 0x88 or "
"packet[5] >= 0x40)))? (((not packet[88] <= 0x88 and "
"packet[13] > 0x00) and (packet[52] >= 0x00 and "
"not packet[96] == 0x00)) or packet[32] < 0x00): "
"(((packet[57] <= 0x75? not packet[27] == 0x00: packet[0] >= 0x60) or "
"(packet[90] == 0xAA or packet[62] > 0x00))? "
"((not packet[39] <= 0x01 and packet[48] != 0xA4) or "
"packet[86] <= 0x66): not packet[61] >= 0x00)) and "
"((packet[64] >= 0x00? (not packet[50] != 0x69 or "
"(not packet[92] != 0xCC? not packet[9] < 0x00: packet[93] >= 0xDD)): "
"((packet[58] <= 0x00 and not packet[103] != 0x77) or "
"(not packet[22] < 0x00? not packet[93] <= 0xDD: "
"not packet[55] < 0x00))) or (packet[87] <= 0x77 and "
"((packet[70] <= 0x66 and not packet[59] <= 0x00) and "
"(not packet[8] != 0x00 or packet[82] == 0x22)))))",
&pkt_ipv6_echo_reply, FALSE},
{"((((packet[14] == 0x00? (packet[102] > 0x66 or packet[16] != 0x00): "
"(packet[81] >= 0x11 or not packet[35] <= 0x00))? "
"((packet[88] < 0x88? packet[8] <= 0x00: packet[18] > 0x00) or "
"(not packet[82] <= 0x22? not packet[13] == 0x00: "
"not packet[37] == 0x00)): (packet[38] < 0x00 and "
"not packet[83] < 0x33))? packet[95] >= 0xFF: "
"(((not packet[96] <= 0x00? packet[84] != 0x44: "
"not packet[34] <= 0x00) or not packet[47] <= 0x03) or "
"((packet[78] == 0xEE? packet[101] >= 0x55: not packet[25] >= 0x00) or "
"packet[9] <= 0x00))) or (packet[59] == 0x00 and ((packet[72] < 0x88 and "
"(packet[52] == 0x00 or not packet[54] >= 0x00)) or "
"(packet[13] >= 0x00 or (not packet[93] == 0xDD and "
"not packet[99] < 0x33)))))", &pkt_ipv6_echo_reply, TRUE},
{"ipv6.TrafficClass == 0x00000000 and ipv6.FlowLabel == 0x0000 and "
"ipv6.Length == 64 and ipv6.NextHdr == 58 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_echo_reply, TRUE},
{"ipv6.TrafficClass != 0x00000000 or ipv6.FlowLabel != 0x0000 or "
"ipv6.Length < 64 or ipv6.NextHdr > 58 or ipv6.HopLimit != 31 or "
"ipv6.SrcAddr != 0:0:0:0:0:0:0:1 or ipv6.DstAddr > 0:0:0:0:0:0:0:1 or "
"icmpv6.Type > 129 or icmpv6.Code > 0 or icmpv6.Body != 0x10720003",
&pkt_ipv6_echo_reply, FALSE},
{"localAddr == ::1 && remoteAddr == ::1 && localPort == 129 && "
"remotePort == 0 && protocol == 58", &pkt_ipv6_echo_reply, TRUE},
{"true", &pkt_ipv6_exthdrs_udp, TRUE},
{"false", &pkt_ipv6_exthdrs_udp, FALSE},
{"protocol == 0", &pkt_ipv6_exthdrs_udp, FALSE},
{"udp", &pkt_ipv6_exthdrs_udp, TRUE},
{"tcp", &pkt_ipv6_exthdrs_udp, FALSE},
{"ipv6.SrcAddr == ::", &pkt_ipv6_exthdrs_udp, FALSE},
@@ -417,23 +784,77 @@ 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},
{"timestamp > -1", &pkt_ipv6_exthdrs_udp, TRUE},
{"udp.SrcPort == 4660 and udp.DstPort == 43690",
&pkt_ipv6_exthdrs_udp, TRUE},
{"udp.SrcPort == 4660 and udp.DstPort == 12345",
&pkt_ipv6_exthdrs_udp, FALSE},
{"localAddr == ::1", &pkt_ipv6_exthdrs_udp, TRUE},
{"localPort == 4660 and remotePort == 43690",
&pkt_ipv6_exthdrs_udp, TRUE},
{"(outbound and tcp? tcp.DstPort == 0xABAB: false) or "
"(outbound and udp? udp.DstPort == 0xAAAA: false) or "
"(inbound and tcp? tcp.SrcPort == 0xABAB: false) or "
"(inbound and udp? udp.SrcPort == 0xAAAA: false)",
&pkt_ipv6_exthdrs_udp, TRUE},
{"(ipv6? true: false) or (udp? udp.DstPort != 53: false) or "
"(not tcp and not udp? true: false)", &pkt_ipv6_exthdrs_udp, TRUE},
{"(tcp or udp) and (ip or ipv6) and (icmp or !icmpv6) and "
"(tcp.Payload16[-1] == 0x1234 or udp.Payload16[-1] == 0x2101)",
&pkt_ipv6_exthdrs_udp, TRUE},
{"udp.PayloadLength == 13", &pkt_ipv6_exthdrs_udp, TRUE},
{"(udp.Length == 13? false: udp.Length == 21)",
&pkt_ipv6_exthdrs_udp, TRUE},
{"(tcp or icmp or icmpv6 or ip or !udp or ipv6? udp.PayloadLength > 0: "
"udp.DstPort == 39482)", &pkt_ipv6_exthdrs_udp, TRUE},
{"random8 < 128", &pkt_ipv6_exthdrs_udp, TRUE},
{"(random8 < 128? random16 < 0x8000: random32 < 0x80000000)",
&pkt_ipv6_exthdrs_udp, TRUE},
{"timestamp != -0x8000000000000000", &pkt_ipv6_exthdrs_udp, TRUE},
{"timestamp != 0x7fffffffffffffff", &pkt_ipv6_exthdrs_udp, TRUE},
{"timestamp == -0x1deadbeef1234567", &pkt_ipv6_exthdrs_udp, FALSE},
{"((packet[2] <= 0x00 or (((packet[29] < 0x00 or "
"not packet[35] != 0x00) and packet[32] != 0x00) and "
"((not packet[31] != 0x00 and packet[52] > 0x00) and "
"(packet[28] < 0x00? not packet[28] <= 0x00: packet[73] == 0x65))))? "
"((((packet[9] <= 0x00? not packet[28] == 0x00: "
"not packet[22] >= 0x00) and (not packet[20] != 0x00 and "
"not packet[22] >= 0x00)) and ((packet[42] > 0x00 and "
"not packet[12] < 0x00) or packet[66] == 0xAA)) or "
"(not packet[23] >= 0x01 and (packet[79] > 0x6F and "
"(not packet[18] > 0x00 or not packet[82] <= 0x64)))): "
"packet[62] <= 0x00)",
&pkt_ipv6_exthdrs_udp, FALSE},
{"((packet[56] > 0x11? (((not packet[0] > 0x60? not packet[22] < 0x00: "
"not packet[15] > 0x00)? (not packet[5] >= 0x2D and packet[18] != 0x00): "
"packet[45] == 0x00) or ((packet[47] >= 0x00 or not packet[32] >= 0x00)? "
"(packet[29] >= 0x00 or not packet[20] == 0x00): (packet[32] > 0x00 and "
"packet[46] > 0x00))): not packet[76] != 0x6F) or "
"((not packet[32] > 0x00 or (packet[13] == 0x00 or (packet[4] > 0x00 or "
"packet[21] < 0x00))) or (((packet[55] != 0x00? packet[67] != 0xAA: "
"not packet[66] >= 0xAA)? (packet[8] > 0x00? not packet[28] > 0x00: "
"packet[28] <= 0x00): not packet[78] != 0x57)? ((packet[79] == 0x6F or "
"packet[25] == 0x00) or (packet[68] == 0x00? not packet[50] < 0x00: "
"not packet[68] < 0x00)): ((not packet[78] > 0x57 and "
"not packet[8] == 0x00) or packet[32] <= 0x00))))",
&pkt_ipv6_exthdrs_udp, TRUE},
{"ipv6.TrafficClass == 0x00000000 and ipv6.FlowLabel == 0x0000 and "
"ipv6.Length == 45 and ipv6.NextHdr == 0 and ipv6.HopLimit == 100 and "
"ipv6.SrcAddr == 0:0:0:0:0:0:0:1 and ipv6.DstAddr == 0:0:0:0:0:0:0:1 and "
"udp.SrcPort == 4660 and udp.DstPort == 43690 and udp.Length == 21",
&pkt_ipv6_exthdrs_udp, TRUE},
{"(ipv6.TrafficClass == 0x00000000 and ipv6.FlowLabel == 0x0000 and "
"ipv6.Length == 45 and ipv6.NextHdr == 0 and ipv6.HopLimit == 101? false: "
"(ipv6.SrcAddr == 0:0:0:0:0:0:0:1 and ipv6.DstAddr == 0:0:0:0:0:0:0:1 and "
"udp.SrcPort == 4660 and udp.DstPort == 43691? false: udp.Length == 22))",
&pkt_ipv6_exthdrs_udp, FALSE},
{"ipv6.TrafficClass != 0x00000000 or ipv6.FlowLabel > 0x0000 or "
"ipv6.Length < 45 or ipv6.NextHdr != 0 or ipv6.HopLimit < 100 or "
"ipv6.SrcAddr > 0:0:0:0:0:0:0:1 or ipv6.DstAddr < 0:0:0:0:0:0:0:1 or "
"udp.SrcPort > 4660 or udp.DstPort < 43690 or udp.Length > 21",
&pkt_ipv6_exthdrs_udp, FALSE},
{"localAddr == ::1 and remoteAddr == 1 and localPort == 4660 and "
"remotePort == 43690 and protocol == 17", &pkt_ipv6_exthdrs_udp, TRUE},
};
/*
@@ -442,7 +863,9 @@ static const struct test tests[] =
int main(void)
{
HANDLE upper_handle, lower_handle;
HANDLE console;
HANDLE console, monitor;
BOOL passed[sizeof(tests) / sizeof(struct test)], first;
DWORD result;
LARGE_INTEGER freq;
UINT64 diff;
size_t i;
@@ -450,14 +873,14 @@ int main(void)
// Open handles to:
// (1) stop normal traffic from interacting with the tests; and
// (2) stop test packets escaping to the Internet or TCP/IP stack.
upper_handle = WinDivertOpen("true", WINDIVERT_LAYER_NETWORK, -999,
upper_handle = WinDivertOpen("true", WINDIVERT_LAYER_NETWORK, 9999,
WINDIVERT_FLAG_DROP);
lower_handle = WinDivertOpen("true", WINDIVERT_LAYER_NETWORK, 999,
lower_handle = WinDivertOpen("true", WINDIVERT_LAYER_NETWORK, -9999,
WINDIVERT_FLAG_DROP);
if (upper_handle == INVALID_HANDLE_VALUE ||
lower_handle == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "error: failed to open WinDivert handle (err = %d)",
fprintf(stderr, "error: failed to open WinDivert handle (err = %d)\n",
GetLastError());
exit(EXIT_FAILURE);
}
@@ -465,6 +888,16 @@ int main(void)
console = GetStdHandle(STD_OUTPUT_HANDLE);
QueryPerformanceFrequency(&freq);
// Spawn monitor thread:
monitor = CreateThread(NULL, 1, (LPTHREAD_START_ROUTINE)monitor_worker,
NULL, 0, NULL);
if (monitor == NULL)
{
fprintf(stderr, "error: failed to spawn monitor thread (err = %d)\n",
GetLastError());
exit(EXIT_FAILURE);
}
// Wait for existing packets to flush:
Sleep(150);
@@ -479,11 +912,11 @@ int main(void)
BOOL match = tests[i].match;
// Run the test:
BOOL res = run_test(upper_handle, filter, packet, packet_len, match,
passed[i] = run_test(upper_handle, filter, packet, packet_len, match,
&diff);
diff = 1000000 * diff / freq.QuadPart;
printf("%.3u ", i);
if (res)
printf("%.3u ", (unsigned)i);
if (passed[i])
{
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
printf("PASSED");
@@ -512,9 +945,61 @@ int main(void)
WinDivertClose(upper_handle);
WinDivertClose(lower_handle);
result = WaitForSingleObject(monitor, 1000);
switch (result)
{
case WAIT_OBJECT_0:
break;
case WAIT_TIMEOUT:
fprintf(stderr, "error: failed to wait for monitor thread "
"(timeout)\n");
exit(EXIT_FAILURE);
default:
fprintf(stderr, "error: failed to wait for monitor thread "
"(err = %d)\n", result);
exit(EXIT_FAILURE);
}
printf("\npassed = %.2f%%\n",
((double)passed_tests / (double)num_tests) * 100.0);
first = TRUE;
for (i = 0; i < num_tests; i++)
{
const char *filter = tests[i].filter;
char *name = tests[i].packet->name;
if (passed[i])
{
continue;
}
if (first)
{
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_BLUE);
printf("\nFAILED TESTS");
SetConsoleTextAttribute(console, FOREGROUND_RED |
FOREGROUND_GREEN | FOREGROUND_BLUE);
printf("\n------------\n\n");
first = FALSE;
}
printf("%.3u ", (unsigned)i);
SetConsoleTextAttribute(console, FOREGROUND_RED);
printf("FAILED");
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
FOREGROUND_BLUE);
printf(" p=[");
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
printf("%s", name);
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
FOREGROUND_BLUE);
printf("] f=[");
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
printf("%s", filter);
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
FOREGROUND_BLUE);
printf("]\n");
}
return 0;
}
@@ -537,6 +1022,7 @@ static BOOL run_test(HANDLE inject_handle, const char *filter,
HANDLE event[2] = {NULL, NULL};
BOOL random, result, ipv4;
LARGE_INTEGER end;
UINT64 val;
*diff = 0;
@@ -550,20 +1036,47 @@ static BOOL run_test(HANDLE inject_handle, const char *filter,
}
// (1) Open WinDivert handles:
handle[0] = WinDivertOpen(object, WINDIVERT_LAYER_NETWORK, 777, 0);
handle[0] = WinDivertOpen(object, WINDIVERT_LAYER_NETWORK, 8888, 0);
if (handle[0] == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "error: failed to open WinDivert handle for filter "
"\"%s\" (err = %d)\n", filter, GetLastError());
goto failed;
}
handle[1] = WinDivertOpen("true", WINDIVERT_LAYER_NETWORK, 888, 0);
handle[1] = WinDivertOpen("true", WINDIVERT_LAYER_NETWORK, 7777, 0);
if (handle[1] == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "error: failed to open WinDivert handle "
"(err = %d)\n", GetLastError());
goto failed;
}
if (!WinDivertSetParam(handle[0], WINDIVERT_PARAM_QUEUE_LENGTH,
WINDIVERT_PARAM_QUEUE_LENGTH_MAX) ||
!WinDivertGetParam(handle[0], WINDIVERT_PARAM_QUEUE_LENGTH, &val) ||
val != WINDIVERT_PARAM_QUEUE_LENGTH_MAX)
{
fprintf(stderr, "error: failed to set WINDIVERT_PARAM_QUEUE_LENGTH "
"parameter (err = %d)\n", GetLastError());
goto failed;
}
if (!WinDivertSetParam(handle[0], WINDIVERT_PARAM_QUEUE_SIZE,
WINDIVERT_PARAM_QUEUE_SIZE_MAX) ||
!WinDivertGetParam(handle[0], WINDIVERT_PARAM_QUEUE_SIZE, &val) ||
val != WINDIVERT_PARAM_QUEUE_SIZE_MAX)
{
fprintf(stderr, "error: failed to set WINDIVERT_PARAM_QUEUE_SIZE "
"parameter (err = %d)\n", GetLastError());
goto failed;
}
if (!WinDivertSetParam(handle[0], WINDIVERT_PARAM_QUEUE_TIME,
WINDIVERT_PARAM_QUEUE_TIME_MAX) ||
!WinDivertGetParam(handle[0], WINDIVERT_PARAM_QUEUE_TIME, &val) ||
val != WINDIVERT_PARAM_QUEUE_TIME_MAX)
{
fprintf(stderr, "error: failed to set WINDIVERT_PARAM_QUEUE_TIME "
"parameter (err = %d)\n", GetLastError());
goto failed;
}
// (2) Create pended recv requests:
event[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
@@ -592,12 +1105,12 @@ static BOOL run_test(HANDLE inject_handle, const char *filter,
// (2) Inject the packet:
memset(&addr_send, 0, sizeof(addr_send));
addr_send.Outbound = TRUE;
addr_send.PseudoIPChecksum = TRUE;
addr_send.PseudoTCPChecksum = TRUE;
addr_send.PseudoUDPChecksum = TRUE;
if (!WinDivertSend(inject_handle, (PVOID)packet, packet_len, &addr_send,
NULL))
addr_send.Outbound = TRUE;
addr_send.IPChecksum = FALSE;
addr_send.TCPChecksum = FALSE;
addr_send.UDPChecksum = FALSE;
if (!WinDivertSend(inject_handle, (PVOID)packet, packet_len, NULL,
&addr_send))
{
fprintf(stderr, "error: failed to inject test packet (err = %d)\n",
GetLastError());
@@ -640,7 +1153,7 @@ static BOOL run_test(HANDLE inject_handle, const char *filter,
if (buf_len[idx] != packet_len)
{
fprintf(stderr, "error: packet length mis-match, expected (%u), got "
"(%u)\n", packet_len, buf_len[idx]);
"(%u)\n", (unsigned)packet_len, buf_len[idx]);
goto failed;
}
iphdr = (PWINDIVERT_IPHDR)buf[idx];
@@ -689,6 +1202,29 @@ static BOOL run_test(HANDLE inject_handle, const char *filter,
}
// (5) Clean-up:
if (!WinDivertShutdown(handle[0], WINDIVERT_SHUTDOWN_BOTH) ||
!WinDivertShutdown(handle[1], WINDIVERT_SHUTDOWN_BOTH))
{
fprintf(stderr, "error: failed to shutdown WinDivert handle (err = "
"%d)\n", GetLastError());
goto failed;
}
for (i = 0; i < 1000 && WinDivertRecv(handle[0], NULL, 0, NULL, NULL); i++)
;
if (GetLastError() != ERROR_NO_DATA)
{
fprintf(stderr, "error: failed to recv NO_DATA from shutdown "
"WinDivert handle (err = %d)\n", GetLastError());
goto failed;
}
for (i = 0; i < 1000 && WinDivertRecv(handle[1], NULL, 0, NULL, NULL); i++)
;
if (GetLastError() != ERROR_NO_DATA)
{
fprintf(stderr, "error: failed to recv NO_DATA from shutdown "
"WinDivert handle (err = %d)\n", GetLastError());
goto failed;
}
if (!WinDivertClose(handle[0]) || !WinDivertClose(handle[1]))
{
fprintf(stderr, "error: failed to close WinDivert handle (err = %d)\n",
@@ -715,3 +1251,91 @@ failed:
return FALSE;
}
/*
* Monitor thread.
*/
static DWORD monitor_worker(LPVOID arg)
{
char filter[100], packet[4096], object_1[4096], *object_2, filter_2[8192];
UINT packet_len;
WINDIVERT_ADDRESS addr;
PWINDIVERT_IPHDR iphdr;
UINT i;
snprintf(filter, sizeof(filter), "processId=%d and priority=8888 and "
"event=OPEN", GetCurrentProcessId());
HANDLE handle = WinDivertOpen(filter, WINDIVERT_LAYER_REFLECT, 0,
WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_RECV_ONLY);
if (handle == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "error: failed to open reflect handle (err = %d)\n",
GetLastError());
exit(EXIT_FAILURE);
}
size_t num_tests = sizeof(tests) / sizeof(struct test);
for (i = 0; i < num_tests; i++)
{
// (1) Read the reflected filter:
WinDivertHelperCompileFilter(tests[i].filter, WINDIVERT_LAYER_NETWORK,
object_1, sizeof(object_1), NULL, NULL);
if (!WinDivertRecv(handle, packet, sizeof(packet), &packet_len, &addr))
{
fprintf(stderr, "error: failed to read OPEN event (err = %d)\n",
GetLastError());
exit(EXIT_FAILURE);
}
object_2 = packet;
if (strcmp(object_1, object_2) != 0)
{
// Filter is not the same.
fprintf(stderr, "error: filter object mismatch (%s vs %s)\n",
object_1, object_2);
exit(EXIT_FAILURE);
}
// (2) Test if formatted filter is equivalent:
if (!WinDivertHelperFormatFilter(object_1, WINDIVERT_LAYER_NETWORK,
filter_2, sizeof(filter_2)))
{
fprintf(stderr, "error: failed to format filter (err = %d)\n",
GetLastError());
exit(EXIT_FAILURE);
}
if (!WinDivertHelperCompileFilter(filter_2, WINDIVERT_LAYER_NETWORK,
object_1, sizeof(object_1), NULL, NULL))
{
fprintf(stderr, "error: failed to recompile filter (err = %d)\n",
GetLastError());
exit(EXIT_FAILURE);
}
if (strcmp(object_1, object_2) == 0)
{
// Recompiled filter is exactly the same; test has passed.
continue;
}
if (strstr(filter_2, "random") != NULL)
{
// Cannot verify random filters.
continue;
}
iphdr = (PWINDIVERT_IPHDR)tests[i].packet->packet;
memset(&addr, 0, sizeof(addr));
addr.Event = WINDIVERT_EVENT_NETWORK_PACKET;
addr.Layer = WINDIVERT_LAYER_NETWORK;
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)
{
fprintf(stderr, "error: failed to match recompiled filter "
"(test = %.3u, filter = \"%s\" formatted = \"%s\", "
"err = %d)\n", i, tests[i].filter, filter_2, GetLastError());
exit(EXIT_FAILURE);
}
}
WinDivertClose(handle);
return 0;
}
+73
View File
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
test.vcxproj
(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.
-->
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="test.c">
<TreatWarningAsError>false</TreatWarningAsError>
<Optimization>MinSpace</Optimization>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
</ClCompile>
</ItemGroup>
<PropertyGroup Label="Globals">
<RootNamespace>test</RootNamespace>
<ProjectName>test</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\install\MSVC\i386\WinDivert.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\install\MSVC\amd64\WinDivert.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* test_data.c
* (C) 2018, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
+1 -1
View File
@@ -1,5 +1,5 @@
:: wddk-build.bat
:: (C) 2018, all rights reserved,
:: (C) 2019, all rights reserved,
::
:: This file is part of WinDivert.
::