91 Commits

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

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

Previous commit was incomplete.
2022-07-30 11:27:57 +08:00
basil00 0b164b6ba3 Fix handling of FwpmTransaction*() errors.
Fixes #294
2022-07-30 11:24:46 +08:00
basil00 7f35b0c8f8 Merge pull request #296 from StalkR/patch-1
windivert.html: fix 6.11 title: format not parse
2022-07-30 11:24:46 +08:00
StalkR ea25bab7c5 windivert.html: fix 6.11 title: format not parse 2022-07-30 11:24:46 +08:00
basil00 c26ec39465 Fix filter compiler test simplification logic
Fix #285
2021-09-25 07:23:08 +08:00
basil00 227a6b1e78 Fix #283 2021-09-11 07:09:51 +08:00
basil00 134dd37bd0 Insert all WinDivert sublayers at the max weight. 2020-09-03 08:12:39 +08:00
basil00 97056af256 Cleanup the provider code. 2020-06-26 08:53:18 +08:00
basil00 db674a6696 Merge pull request #241 from ruilisi/add_provider
Install provider to pass HLK test
2020-06-24 08:35:31 +08:00
Zhou Yicheng 32af280add Install provider to pass HLK test 2020-06-22 11:08:51 +08:00
basil00 b83e7413be Add an ETHERNET layer to WinDivert.
Adds a new ETHERNET layer to WinDivert.  This
layer is similar to the NETWORK layers in that
packets can be blocked/modified/injected.  This
change requires Windows 8 or newer.
2019-12-20 09:09:57 +08:00
basil00 091ffb3d49 Reformatting 2019-10-06 08:19:23 +08:00
basil00 aff111e44d Merge pull request #211 from zzzjim/fix-mcafee
Inject on different handles for inbound/outbound
2019-10-06 08:12:36 +08:00
zzzjim 160d983960 Inject on different handles for inbound/outbound 2019-10-04 19:11:25 -07:00
basil00 69b4620277 Log a system event on driver (un)load.
This allows WinDivert to be detected without
using the REFLECT API.
2019-10-04 08:57:30 +08:00
basil00 bcba321048 Fix another packet batch parsing bug.
Extended/truncated logic was reversed.
2019-10-03 05:02:37 +08:00
basil00 0c773bc08f Fix batch parsing bug. 2019-09-29 07:27:04 +08:00
basil00 eba2e59e3b Ensure RC file included in MSVC build. 2019-09-29 07:15:41 +08:00
basil00 951560d403 Modify WINDIVERTEXPORT so it can be static.
For better static linking support.
2019-08-31 08:49:56 +08:00
basil00 7dc1c5d54a Fix some compiler warnings. 2019-08-27 09:45:45 +08:00
basil00 a1173fe08f Coalesce filter interpreter implementations.
Replace the dual kernel/user-mode filter
interpreters with a single shared implementation.
2019-08-17 09:31:46 +08:00
basil00 a240329323 Add "fragment" to filter language.
True if the packet is an IPv4/IPv6 fragment.
2019-08-15 09:08:46 +08:00
basil00 317e6f1099 Implement new packet parser(s) for WinDivert.
The new parser should better handle fragments
as well as be consistent with the kernel-mode
parser.  The new parser can also handle truncated
packets.
2019-08-12 07:50:49 +08:00
basil00 6501bec357 Make release script use MSVC build. 2019-08-05 07:47:53 +08:00
basil00 194d9afa1e Towards WinDivert version 2.1 release.
- inbounds/outbound now work for SOCKET layer.
- passthru.exe now uses MTU_MAX to prevent 122
  errors.
- Further header parsing code hardening.
- Fix bug where Reserved2 was not zeroed.
2019-08-04 08:11:43 +08:00
basil00 69e4edade7 Add new WINDIVERT_FLAG_FRAGMENTS flag (fix #191).
This flag only affects inbound packets at the
WINDIVERT_LAYER_NETWORK layer.

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

If unset (the default), the handle will capture
reassembled IP packets, but not IP fragments.
2019-08-02 08:32:50 +08:00
basil00 6eb82d08e0 Fix WinDivert 2.0 driver bugs.
- BSOD for incomplete transport headers (#202).
- Fix enforcement of wrong MTU.
- Fix missing endpoint handles for IPV6 flow
  layer.
2019-07-31 08:46:01 +08:00
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
42 changed files with 11845 additions and 5157 deletions
+191 -2
View File
@@ -127,5 +127,194 @@ 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
WinDivert 2.1.0
- WinDivertOpen() now supports a new flag:
* WINDIVERT_FLAG_FRAGMENTS: If set, the handle will capture inbound IP
fragments, but not inbound reassembled IP packets. Otherwise, if not
set (the default), the handle will capture inbound reassembled IP
packets, but not inbound IP fragments. This flag only affects
inbound packets at the NETWORK layer.
- Filter fields inbound/outbound are now supported at the SOCKET layer.
- Fix BSOD caused by packets with missing or incomplete transport
headers (introduced in 2.0.0).
- Fix missing Flow.EndpointId and Flow.ParentEndpointId for IPv6 flows.
WinDivert 2.2.0
- Implement new packet parser that correctly handles IP fragments.
- Add a new "fragment" filter field that matches IP fragments.
- (Un)Loading the WinDivert driver will cause a system event to be logged.
WinDivert 2.2.1
- Fix potential driver deadlock on user-mode program crash.
- Fix filter language simplification bug.
- Fix Flow.EndpointId containing junk data.
WinDivert 2.2.2
- Fix potential WinDivertClose() BSOD for WINDIVERT_LAYER_FLOW handles.
+2 -2
View File
@@ -1,11 +1,11 @@
WinDivert 2.0: Windows Packet Divert
WinDivert 2.2: Windows Packet Divert
====================================
1. Introduction
---------------
Windows Packet Divert (WinDivert) is a user-mode packet interception library
for Windows 7, Windows 8 and Windows 10.
for Windows 10, Windows 11, and Windows Server.
WinDivert enables user-mode capturing/modifying/dropping of network packets
sent to/from the Windows network stack. In summary, WinDivert can:
+1 -1
View File
@@ -1 +1 @@
2.0.0
2.2.2
+416 -217
View File
@@ -1,6 +1,6 @@
/*
* windivert.c
* (C) 2018, all rights reserved,
* (C) 2019, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -43,14 +43,22 @@
#include <stdio.h>
#include <stdlib.h>
#define WINDIVERTEXPORT
#ifndef WINDIVERTEXPORT
#define WINDIVERTEXPORT extern
#endif
#include "windivert.h"
#include "windivert_device.h"
#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 +68,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 +80,60 @@ 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
#define IPPROTO_MH 135
#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;
}
#define WINDIVERT_INLINE __forceinline
#else /* _MSC_VER */
#define WINDIVERT_INLINE __attribute__((__always_inline__)) inline
#endif /* _MSC_VER */
/*
* Filter interpreter config.
*/
static BOOL WinDivertGetData(const VOID *packet, UINT packet_len, INT min,
INT max, INT idx, PVOID data, UINT size);
#define WINDIVERT_GET_DATA(packet, packet_len, min, max, index, data, size) \
WinDivertGetData((packet), (packet_len), (min), (max), (index), (data), \
(size))
/*
* Prototypes.
*/
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.
@@ -104,8 +154,7 @@ static HMODULE module = NULL;
/*
* Dll Entry
*/
extern BOOL APIENTRY WinDivertDllEntry(HANDLE module0, DWORD reason,
LPVOID reserved)
BOOL APIENTRY WinDivertDllEntry(HANDLE module0, DWORD reason, LPVOID reserved)
{
HANDLE event;
switch (reason)
@@ -214,15 +263,58 @@ static BOOLEAN WinDivertGetDriverFileName(LPWSTR sys_str)
return TRUE;
}
/*
* Register event log. It is not an error if this function fails.
*/
static void WinDivertRegisterEventSource(const wchar_t *windivert_sys)
{
HKEY key;
size_t len;
DWORD types = 7;
if (!WinDivertStrLen(windivert_sys, MAX_PATH, &len))
{
return;
}
if (RegCreateKeyExA(HKEY_LOCAL_MACHINE,
"System\\CurrentControlSet\\Services\\EventLog\\System\\WinDivert",
0, NULL, REG_OPTION_VOLATILE, KEY_SET_VALUE, NULL, &key, NULL)
!= ERROR_SUCCESS)
{
return;
}
RegSetValueExW(key, L"EventMessageFile", 0, REG_SZ, (LPBYTE)windivert_sys,
(len + 1) * sizeof(wchar_t));
RegSetValueExA(key, "TypesSupported", 0, REG_DWORD, (LPBYTE)&types,
sizeof(types));
RegCloseKey(key);
}
/*
* Install the WinDivert driver.
*/
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 +324,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 +345,32 @@ WinDivertDriverInstallReTry:
{
if (GetLastError() == ERROR_SERVICE_EXISTS)
{
if (retries != 0)
{
retries--;
goto WinDivertDriverInstallReTry;
}
service = OpenService(manager, WINDIVERT_DEVICE_NAME,
SERVICE_ALL_ACCESS);
}
goto WinDivertDriverInstallExit;
}
// Register event logging:
WinDivertRegisterEventSource(windivert_sys);
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 +379,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 +432,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,44 +448,38 @@ 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)
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_ETHERNET:
case WINDIVERT_LAYER_NETWORK:
case WINDIVERT_LAYER_NETWORK_FORWARD:
case WINDIVERT_LAYER_FLOW:
@@ -398,9 +504,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 +537,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;
@@ -499,20 +620,28 @@ 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)
BOOL WinDivertRecv(HANDLE handle, PVOID pPacket, UINT packetLen, 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)(ULONG_PTR)addr;
ioctl.recv.addr_len_ptr = (UINT64)(ULONG_PTR)NULL;
return WinDivertIoControl(handle, IOCTL_WINDIVERT_RECV, &ioctl,
pPacket, packetLen, readLen);
}
/*
* Receive a WinDivert packet.
*/
extern BOOL WinDivertRecvEx(HANDLE handle, PVOID pPacket, UINT packetLen,
BOOL WinDivertRecvEx(HANDLE handle, PVOID pPacket, UINT packetLen,
UINT *readLen, UINT64 flags, PWINDIVERT_ADDRESS addr, UINT *pAddrLen,
LPOVERLAPPED overlapped)
{
WINDIVERT_IOCTL ioctl;
memset(&ioctl, 0, sizeof(ioctl));
ioctl.recv.addr = (UINT64)(ULONG_PTR)addr;
ioctl.recv.addr_len_ptr = (UINT64)(ULONG_PTR)pAddrLen;
if (flags != 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
@@ -520,34 +649,41 @@ 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);
}
}
/*
* Send a WinDivert packet.
*/
extern BOOL WinDivertSend(HANDLE handle, const VOID *pPacket, UINT packetLen,
const WINDIVERT_ADDRESS *addr, UINT *writelen)
BOOL WinDivertSend(HANDLE handle, const VOID *pPacket, UINT packetLen,
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)(ULONG_PTR)addr;
ioctl.send.addr_len = sizeof(WINDIVERT_ADDRESS);
return WinDivertIoControl(handle, IOCTL_WINDIVERT_SEND, &ioctl,
(PVOID)pPacket, packetLen, writeLen);
}
/*
* Send a WinDivert packet.
*/
extern BOOL WinDivertSendEx(HANDLE handle, const VOID *pPacket, UINT packetLen,
BOOL WinDivertSendEx(HANDLE handle, const VOID *pPacket, UINT packetLen,
UINT *writeLen, UINT64 flags, const WINDIVERT_ADDRESS *addr, UINT addrLen,
LPOVERLAPPED overlapped)
{
WINDIVERT_IOCTL ioctl;
memset(&ioctl, 0, sizeof(ioctl));
ioctl.send.addr = (UINT64)(ULONG_PTR)addr;
ioctl.send.addr_len = addrLen;
if (flags != 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
@@ -555,31 +691,32 @@ 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);
}
}
/*
* Shutdown a WinDivert handle.
*/
extern BOOL WinDivertShutdown(HANDLE handle, WINDIVERT_SHUTDOWN how)
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);
}
/*
* Close a WinDivert handle.
*/
extern BOOL WinDivertClose(HANDLE handle)
BOOL WinDivertClose(HANDLE handle)
{
return CloseHandle(handle);
}
@@ -587,65 +724,37 @@ extern BOOL WinDivertClose(HANDLE handle)
/*
* Set a WinDivert parameter.
*/
extern BOOL WinDivertSetParam(HANDLE handle, WINDIVERT_PARAM param,
UINT64 value)
BOOL WinDivertSetParam(HANDLE handle, WINDIVERT_PARAM param, UINT64 value)
{
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);
}
/*
* Get a WinDivert parameter.
*/
extern BOOL WinDivertGetParam(HANDLE handle, WINDIVERT_PARAM param,
UINT64 *pValue)
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 +834,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];
}
+7 -1
View File
@@ -1,6 +1,5 @@
LIBRARY WinDivert
EXPORTS
WinDivertDllEntry
WinDivertOpen
WinDivertRecv
WinDivertRecvEx
@@ -11,10 +10,13 @@ EXPORTS
WinDivertSetParam
WinDivertGetParam
WinDivertHelperCalcChecksums
WinDivertHelperDecrementTTL
WinDivertHelperHashPacket
WinDivertHelperParsePacket
WinDivertHelperParseMACAddress
WinDivertHelperParseIPv4Address
WinDivertHelperParseIPv6Address
WinDivertHelperFormatMACAddress
WinDivertHelperFormatIPv4Address
WinDivertHelperFormatIPv6Address
WinDivertHelperCompileFilter
@@ -26,5 +28,9 @@ EXPORTS
WinDivertHelperHtonl
WinDivertHelperNtohll
WinDivertHelperHtonll
WinDivertHelperNtohMACAddress
WinDivertHelperHtonMACAddress
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>
+83 -51
View File
@@ -1,6 +1,6 @@
/*
* windivert_hash.c
* (C) 2018, all rights reserved,
* (C) 2023, 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.
*/
/*
@@ -66,9 +66,10 @@
* "seed" value.
* - The input sized is fixed to 32bytes (excluding the seed), so there is
* only ever a single round. As such, the algorithm has been specialized.
* - [ETHERNET] uses an additional "pseudo-round" for the ethernet header.
*/
#define WINDIVERT_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 +78,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 +88,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;
}
@@ -104,35 +105,42 @@ static UINT64 WinDivertXXH64Avalanche(UINT64 h64)
/*
* WinDivert packet hash function.
*/
static UINT64 WinDivertHashPacket(UINT64 seed, PWINDIVERT_IPHDR ip_header,
PWINDIVERT_IPV6HDR ipv6_header, PWINDIVERT_ICMPHDR icmp_header,
PWINDIVERT_ICMPV6HDR icmpv6_header, PWINDIVERT_TCPHDR tcp_header,
PWINDIVERT_UDPHDR udp_header)
static UINT64 WinDivertHashPacket(
UINT64 seed,
const WINDIVERT_ETHHDR *eth_header,
const WINDIVERT_ARPHDR *arp_header,
const WINDIVERT_IPHDR *ip_header,
const WINDIVERT_IPV6HDR *ipv6_header,
const WINDIVERT_ICMPHDR *icmp_header,
const WINDIVERT_ICMPV6HDR *icmpv6_header,
const WINDIVERT_TCPHDR *tcp_header,
const WINDIVERT_UDPHDR *udp_header)
{
UINT64 h64, v1, v2, v3, v4, v[4], *data64;
UINT32 *data32;
UINT64 h64, v1, v2, v3, v4, v[4];
const UINT64 *data64;
const UINT32 *data32;
UINT i;
static const UINT64 padding64[] = // SHA2 IV
{
0x428A2F9871374491ull, 0xB5C0FBCFE9B5DBA5ull, 0x3956C25B59F111F1ull,
0x923F82A4AB1C5ED5ull, 0xD807AA9812835B01ull, 0x243185BE550C7DC3ull,
0x72BE5D7480DEB1FEull, 0x9BDC06A7C19BF174ull, 0xE49B69C1EFBE4786ull,
0x428A2F9871374491ull, 0xB5C0FBCFE9B5DBA5ull, 0x3956C25B59F111F1ull,
0x923F82A4AB1C5ED5ull, 0xD807AA9812835B01ull, 0x243185BE550C7DC3ull,
0x72BE5D7480DEB1FEull, 0x9BDC06A7C19BF174ull, 0xE49B69C1EFBE4786ull,
};
// Set-up seed & data
v1 = seed ^ padding64[0];
if (ip_header != NULL)
{
data64 = (UINT64 *)ip_header;
data64 = (const UINT64 *)ip_header;
v2 = data64[0] ^ padding64[1];
v3 = data64[1] ^ padding64[2];
data32 = (UINT32 *)ip_header;
data32 = (const UINT32 *)ip_header;
v4 = (UINT64)data32[4] ^ padding64[3];
i = 0;
}
else if (ipv6_header != NULL)
{
data64 = (UINT64 *)ipv6_header;
data64 = (const UINT64 *)ipv6_header;
v2 = data64[0] ^ padding64[1];
v3 = data64[1] ^ padding64[2];
v4 = data64[2] ^ padding64[3];
@@ -140,15 +148,24 @@ static UINT64 WinDivertHashPacket(UINT64 seed, PWINDIVERT_IPHDR ip_header,
v[1] = data64[4] ^ padding64[5];
i = 2;
}
else if (eth_header != NULL)
{
v2 = padding64[1];
v3 = padding64[2];
v4 = padding64[3];
i = 0;
}
else
{
return 0;
}
if (tcp_header != NULL)
{
data64 = (UINT64 *)tcp_header;
data64 = (const UINT64 *)tcp_header;
v[i] = data64[0] ^ padding64[i+4]; i++;
v[i] = data64[1] ^ padding64[i+4]; i++;
data32 = (UINT32 *)tcp_header;
data32 = (const UINT32 *)tcp_header;
if (i <= 3)
{
v[i] = (UINT64)data32[4] ^ padding64[i+4]; i++;
@@ -162,17 +179,17 @@ static UINT64 WinDivertHashPacket(UINT64 seed, PWINDIVERT_IPHDR ip_header,
{
if (udp_header != NULL)
{
data64 = (UINT64 *)udp_header;
data64 = (const UINT64 *)udp_header;
v[i] = data64[0] ^ padding64[i+4]; i++;
}
else if (icmp_header != NULL)
{
data64 = (UINT64 *)icmp_header;
data64 = (const UINT64 *)icmp_header;
v[i] = data64[0] ^ padding64[i+4]; i++;
}
else if (icmpv6_header != NULL)
{
data64 = (UINT64 *)icmpv6_header;
data64 = (const UINT64 *)icmpv6_header;
v[i] = data64[0] ^ padding64[i+4]; i++;
}
}
@@ -187,14 +204,29 @@ 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);
// Ethernet-layer pseudo-round:
if (eth_header != NULL)
{
data64 = (const UINT64 *)eth_header->DstAddr;
v1 = WinDivertXXH64Round(v1, data64[0] & 0xFFFFFFFFFFFFull);
data64 = (const UINT64 *)eth_header->SrcAddr;
v2 = WinDivertXXH64Round(v2, data64[0]);
if (arp_header != NULL)
{
data64 = (const UINT64 *)arp_header;
v3 = WinDivertXXH64Round(v3, data64[0]);
}
}
h64 = WINDIVERT_ROTL64(v1, 1) + WINDIVERT_ROTL64(v2, 7) +
WINDIVERT_ROTL64(v3, 12) + WINDIVERT_ROTL64(v4, 18);
h64 = WinDivertXXH64MergeRound(h64, v1);
h64 = WinDivertXXH64MergeRound(h64, v2);
h64 = WinDivertXXH64MergeRound(h64, v3);
h64 = WinDivertXXH64MergeRound(h64, v4);
h64 += 32; // "length"
h64 = WinDivertXXH64Avalanche(h64);
h64 = WinDivertXXH64Avalanche(h64);
return h64;
}
+1614 -1468
View File
File diff suppressed because it is too large Load Diff
+1638 -229
View File
File diff suppressed because it is too large Load Diff
+2358 -697
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>
+152 -33
View File
@@ -1,6 +1,6 @@
/*
* netdump.c
* (C) 2018, all rights reserved,
* (C) 2023, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -37,7 +37,7 @@
* This is a simple traffic monitor. It uses a WinDivert handle in SNIFF mode.
* The SNIFF mode copies packets and does not block the original.
*
* usage: netdump.exe windivert-filter [priority]
* usage: netdump.exe windivert-filter [priority] [layer]
*
*/
@@ -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
/*
@@ -60,18 +60,23 @@
int __cdecl main(int argc, char **argv)
{
HANDLE handle, console;
DWORD err;
UINT i;
WINDIVERT_LAYER layer = WINDIVERT_LAYER_NETWORK;
INT16 priority = 0;
unsigned char packet[MAXBUF];
UINT packet_len;
UINT packet_len, arp_len;
WINDIVERT_ADDRESS addr;
PWINDIVERT_ETHHDR eth_header;
PWINDIVERT_ARPHDR arp_header;
PWINDIVERT_IPHDR ip_header;
PWINDIVERT_IPV6HDR ipv6_header;
PWINDIVERT_ICMPHDR icmp_header;
PWINDIVERT_ICMPV6HDR icmpv6_header;
PWINDIVERT_TCPHDR tcp_header;
PWINDIVERT_UDPHDR udp_header;
UINT32 src_addr[4], dst_addr[4];
UINT8 src_mac[6], dst_mac[6], *mac_ptr;
UINT32 src_addr[4], dst_addr[4], *ip_ptr;
UINT64 hash;
char src_str[INET6_ADDRSTRLEN+1], dst_str[INET6_ADDRSTRLEN+1];
const char *err_str;
@@ -81,19 +86,44 @@ int __cdecl main(int argc, char **argv)
// Check arguments.
switch (argc)
{
case 2:
break;
case 4:
if (strcmp(argv[3], "network") == 0)
{
layer = WINDIVERT_LAYER_NETWORK;
}
else if (strcmp(argv[3], "forward") == 0)
{
layer = WINDIVERT_LAYER_NETWORK_FORWARD;
}
else if (strcmp(argv[3], "ethernet") == 0)
{
layer = WINDIVERT_LAYER_ETHERNET;
}
else
{
goto usage;
}
// Fallthrough
case 3:
priority = (INT16)atoi(argv[2]);
// Fallthrough
case 2:
break;
default:
fprintf(stderr, "usage: %s windivert-filter [priority]\n",
usage:
fprintf(stderr, "usage: %s windivert-filter [priority] [layer]\n\n",
argv[0]);
fprintf(stderr, "where:\n");
fprintf(stderr, "\t- priority is an integer between "
"-30000..30000 (default = %d)\n", (int)priority);
fprintf(stderr, "\t- layer is one of ethernet/network/forward "
"(default = network)\n\n");
fprintf(stderr, "examples:\n");
fprintf(stderr, "\t%s true\n", argv[0]);
fprintf(stderr, "\t%s \"outbound and tcp.DstPort == 80\" 1000\n",
fprintf(stderr, "\t%s \"outbound and tcp.DstPort == 80\" 1000 "
"network\n", argv[0]);
fprintf(stderr, "\t%s \"inbound and tcp.Syn\" -400 ethernet\n",
argv[0]);
fprintf(stderr, "\t%s \"inbound and tcp.Syn\" -400\n", argv[0]);
exit(EXIT_FAILURE);
}
@@ -101,35 +131,44 @@ int __cdecl main(int argc, char **argv)
console = GetStdHandle(STD_OUTPUT_HANDLE);
// Divert traffic matching the filter:
handle = WinDivertOpen(argv[1], WINDIVERT_LAYER_NETWORK, priority,
WINDIVERT_FLAG_SNIFF);
handle = WinDivertOpen(argv[1], layer, priority, WINDIVERT_FLAG_SNIFF);
if (handle == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_INVALID_PARAMETER &&
!WinDivertHelperCompileFilter(argv[1], WINDIVERT_LAYER_NETWORK,
NULL, 0, &err_str, NULL))
err = GetLastError();
if (err == ERROR_INVALID_PARAMETER &&
!WinDivertHelperCompileFilter(argv[1], layer, NULL, 0, &err_str,
NULL))
{
fprintf(stderr, "error: invalid filter \"%s\"\n", err_str);
exit(EXIT_FAILURE);
}
fprintf(stderr, "error: failed to open the WinDivert device (%d)\n",
GetLastError());
err);
exit(EXIT_FAILURE);
}
// 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 +178,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,24 +186,104 @@ 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);
if (ip_header == NULL && ipv6_header == NULL)
{
fprintf(stderr, "warning: junk packet\n");
}
WinDivertHelperParsePacket(packet, packet_len, addr.Layer,
&eth_header, &arp_header, &ip_header, &ipv6_header, NULL,
&icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL,
NULL);
// Dump packet info:
putchar('\n');
SetConsoleTextAttribute(console, FOREGROUND_RED);
time_passed = (double)(addr.Timestamp - base.QuadPart) /
(double)freq.QuadPart;
hash = WinDivertHelperHashPacket(packet, packet_len, 0);
printf("Packet [Timestamp=%.8g, Direction=%s IfIdx=%u SubIfIdx=%u "
"Loopback=%u Hash=0x%.16llX]\n",
time_passed, (addr.Outbound? "outbound": "inbound"),
addr.Network.IfIdx, addr.Network.SubIfIdx, addr.Loopback, hash);
hash = WinDivertHelperHashPacket(packet, packet_len, addr.Layer, 0);
if (eth_header != NULL)
{
printf("Packet [Timestamp=%.8g Length=%u Direction=%s IfIdx=%u "
"SubIfIdx=%u Hash=0x%.16llX]\n",
time_passed, packet_len, (addr.Outbound? "outbound": "inbound"),
addr.Ethernet.IfIdx, addr.Ethernet.SubIfIdx, hash);
WinDivertHelperNtohMACAddress(eth_header->SrcAddr, src_mac);
WinDivertHelperNtohMACAddress(eth_header->DstAddr, dst_mac);
WinDivertHelperFormatMACAddress(src_mac, src_str, sizeof(src_str));
WinDivertHelperFormatMACAddress(dst_mac, dst_str, sizeof(dst_str));
SetConsoleTextAttribute(console,
FOREGROUND_GREEN | FOREGROUND_BLUE);
printf("Ethernet [SrcAddr=%s DstAddr=%s Type=0x%.4X]\n",
src_str, dst_str, ntohs(eth_header->Type));
if (arp_header != NULL)
{
arp_len = packet_len - sizeof(WINDIVERT_ETHHDR);
SetConsoleTextAttribute(console,
FOREGROUND_GREEN);
printf("ARP [Hardware=%u Protocol=%u HardLength=%u "
"ProtLength=%u Opcode=%u",
ntohs(arp_header->Hardware), ntohs(arp_header->Protocol),
arp_header->HardLength, arp_header->ProtLength,
ntohs(arp_header->Opcode));
mac_ptr = WINDIVERT_ARPHDR_GET_SRCMACADDR_PTR(arp_header,
arp_len);
if (mac_ptr != NULL)
{
WinDivertHelperNtohMACAddress(mac_ptr, src_mac);
WinDivertHelperFormatMACAddress(src_mac, src_str,
sizeof(src_str));
printf(" SrcHardAddr=%s", src_str);
}
ip_ptr = WINDIVERT_ARPHDR_GET_SRCIPV4ADDR_PTR(arp_header,
arp_len);
if (ip_ptr != NULL)
{
WinDivertHelperFormatIPv4Address(ntohl(ip_ptr[0]),
src_str, sizeof(src_str));
printf(" SrcProtAddr=%s", src_str);
}
ip_ptr = WINDIVERT_ARPHDR_GET_SRCIPV6ADDR_PTR(arp_header,
arp_len);
if (ip_ptr != NULL)
{
WinDivertHelperNtohIPv6Address(ip_ptr, src_addr);
WinDivertHelperFormatIPv6Address(src_addr, src_str,
sizeof(src_str));
printf(" SrcProtAddr=%s", src_str);
}
mac_ptr = WINDIVERT_ARPHDR_GET_DSTMACADDR_PTR(arp_header,
arp_len);
if (mac_ptr != NULL)
{
WinDivertHelperNtohMACAddress(mac_ptr, dst_mac);
WinDivertHelperFormatMACAddress(dst_mac, dst_str,
sizeof(dst_str));
printf(" DstHardAddr=%s", dst_str);
}
ip_ptr = WINDIVERT_ARPHDR_GET_DSTIPV4ADDR_PTR(arp_header,
arp_len);
if (ip_ptr != NULL)
{
WinDivertHelperFormatIPv4Address(ntohl(ip_ptr[0]),
dst_str, sizeof(dst_str));
printf(" DstProtAddr=%s", dst_str);
}
ip_ptr = WINDIVERT_ARPHDR_GET_DSTIPV6ADDR_PTR(arp_header,
arp_len);
if (ip_ptr != NULL)
{
WinDivertHelperNtohIPv6Address(ip_ptr, dst_addr);
WinDivertHelperFormatIPv6Address(dst_addr, dst_str,
sizeof(dst_str));
printf(" DstProtAddr=%s", dst_str);
}
printf("]\n");
}
}
else
{
printf("Packet [Timestamp=%.8g Length=%u Direction=%s IfIdx=%u "
"SubIfIdx=%u Loopback=%u Hash=0x%.16llX]\n",
time_passed, packet_len, (addr.Outbound? "outbound": "inbound"),
addr.Network.IfIdx, addr.Network.SubIfIdx, addr.Loopback,
hash);
}
if (ip_header != NULL)
{
WinDivertHelperFormatIPv4Address(ntohl(ip_header->SrcAddr),
@@ -188,8 +307,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>
+19 -18
View File
@@ -1,6 +1,6 @@
/*
* netfilter.c
* (C) 2018, all rights reserved,
* (C) 2023, 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, recv_addr.Layer, NULL,
NULL, &ip_header, &ipv6_header, NULL, &icmp_header, &icmpv6_header,
&tcp_header, &udp_header, NULL, &payload_len);
if (ip_header == NULL && ipv6_header == NULL)
{
continue;
@@ -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,
@@ -290,9 +290,9 @@ int __cdecl main(int argc, char **argv)
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
send_addr.Outbound = !recv_addr.Outbound;
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(TCPPACKET),
&send_addr, 0);
WINDIVERT_LAYER_NETWORK, &send_addr, 0);
if (!WinDivertSend(handle, (PVOID)reset, sizeof(TCPPACKET),
&send_addr, NULL))
NULL, &send_addr))
{
fprintf(stderr, "warning: failed to send TCP reset (%d)\n",
GetLastError());
@@ -317,9 +317,10 @@ int __cdecl main(int argc, char **argv)
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
send_addr.Outbound = !recv_addr.Outbound;
WinDivertHelperCalcChecksums((PVOID)resetv6,
sizeof(TCPV6PACKET), &send_addr, 0);
sizeof(TCPV6PACKET), WINDIVERT_LAYER_NETWORK, &send_addr,
0);
if (!WinDivertSend(handle, (PVOID)resetv6, sizeof(TCPV6PACKET),
&send_addr, NULL))
NULL, &send_addr))
{
fprintf(stderr, "warning: failed to send TCP (IPV6) "
"reset (%d)\n", GetLastError());
@@ -343,9 +344,9 @@ int __cdecl main(int argc, char **argv)
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
send_addr.Outbound = !recv_addr.Outbound;
WinDivertHelperCalcChecksums((PVOID)dnr, icmp_length,
&send_addr, 0);
if (!WinDivertSend(handle, (PVOID)dnr, icmp_length, &send_addr,
NULL))
WINDIVERT_LAYER_NETWORK, &send_addr, 0);
if (!WinDivertSend(handle, (PVOID)dnr, icmp_length, NULL,
&send_addr))
{
fprintf(stderr, "warning: failed to send ICMP message "
"(%d)\n", GetLastError());
@@ -366,9 +367,9 @@ int __cdecl main(int argc, char **argv)
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
send_addr.Outbound = !recv_addr.Outbound;
WinDivertHelperCalcChecksums((PVOID)dnrv6, icmpv6_length,
&send_addr, 0);
WINDIVERT_LAYER_NETWORK, &send_addr, 0);
if (!WinDivertSend(handle, (PVOID)dnrv6, icmpv6_length,
&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>
+152 -30
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,8 @@
* 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]
* [layer]
*/
#include <winsock2.h>
@@ -47,50 +48,162 @@
#include "windivert.h"
#define MAXBUF 400000
#define MAXBATCH 0xFF
static int batch = 1;
static DWORD passthru(LPVOID arg);
/*
* Options.
*/
static int threads = 1;
static int batch = WINDIVERT_BATCH_MAX;
static int priority = 0;
static WINDIVERT_LAYER layer = WINDIVERT_LAYER_NETWORK;
static int size = (0x10000 + 4096);
/*
* Print usage and exit.
*/
static void usage(const char *prog)
{
fprintf(stderr, "usage: %s [OPTIONS] filter-string\n\n", prog);
fprintf(stderr, "OPTIONS:\n");
fprintf(stderr, "\t--batch N\n");
fprintf(stderr, "\t\tSet the batch size to N (default=%u)\n",
WINDIVERT_BATCH_MAX);
fprintf(stderr, "\t--layer LAYER\n");
fprintf(stderr, "\t\tSet the filter layer to LAYER (default=network).\n");
fprintf(stderr, "\t\tValid values are {ethernet,network,forward}.\n");
fprintf(stderr, "\t--priority N\n");
fprintf(stderr, "\t\tSet the filter priority to N (default=0)\n");
fprintf(stderr, "\t--size N\n");
fprintf(stderr, "\t\tSet the buffer size to N (default=%u)\n",
(0x10000 + 4096));
fprintf(stderr, "\t--threads N\n");
fprintf(stderr, "\t\tSet the number of threads to be N (default=1)\n");
exit(EXIT_FAILURE);
}
/*
* Parse options.
*/
static const char *parse_options(int argc, char **argv)
{
int i;
size_t n;
const char *filter = NULL, *opt, *arg;
for (i = 1; i < argc; i++)
{
opt = argv[i];
if (opt[0] != '-' || opt[1] != '-')
{
if (filter != NULL)
{
usage(argv[0]);
}
filter = opt;
continue;
}
opt += 2;
arg = strchr(opt, '=');
if (arg == NULL)
{
i++;
if (i >= argc)
{
usage(argv[0]);
}
arg = argv[i];
n = strlen(opt);
}
else
{
n = arg - opt;
arg++;
}
if (strncmp(opt, "threads", n) == 0)
{
threads = atoi(arg);
}
else if (strncmp(opt, "batch", n) == 0)
{
batch = atoi(arg);
}
else if (strncmp(opt, "priority", n) == 0)
{
priority = atoi(arg);
}
else if (strncmp(opt, "size", n) == 0)
{
size = atoi(arg);
}
else if (strncmp(opt, "layer", n) == 0)
{
if (strcmp(arg, "ethernet") == 0)
{
layer = WINDIVERT_LAYER_ETHERNET;
}
else if (strcmp(arg, "network") == 0)
{
layer = WINDIVERT_LAYER_NETWORK;
}
else if (strcmp(arg, "forward") == 0)
{
layer = WINDIVERT_LAYER_NETWORK_FORWARD;
}
else
{
usage(argv[0]);
}
}
else
{
usage(argv[0]);
}
}
return (filter == NULL? "true": filter);
}
/*
* Entry.
*/
int __cdecl main(int argc, char **argv)
{
int num_threads, priority = 0, i;
const char *filter;
int i;
HANDLE handle, thread;
if (argc < 3 || argc > 5)
filter = parse_options(argc, argv);
if (threads < 1 || threads > 64)
{
fprintf(stderr, "usage: %s filter num-threads [batch] [priority]\n",
argv[0]);
fprintf(stderr, "error: number of threads must be within "
"the range 1..64, found %d\n", threads);
exit(EXIT_FAILURE);
}
num_threads = atoi(argv[2]);
if (num_threads < 1 || num_threads > 64)
if (batch < 1 || batch > WINDIVERT_BATCH_MAX)
{
fprintf(stderr, "error: invalid number of threads\n");
fprintf(stderr, "error: batch size must be within the range 1..%u, "
"found %d\n", WINDIVERT_BATCH_MAX, batch);
exit(EXIT_FAILURE);
}
if (argc >= 4)
if (priority < WINDIVERT_PRIORITY_LOWEST ||
priority > WINDIVERT_PRIORITY_HIGHEST)
{
batch = atoi(argv[3]);
}
if (batch <= 0 || batch > MAXBATCH)
{
fprintf(stderr, "error: invalid batch size\n");
fprintf(stderr, "error: priority must be within the range %d..%d, "
"found %d\n", WINDIVERT_PRIORITY_LOWEST,
WINDIVERT_PRIORITY_HIGHEST, priority);
exit(EXIT_FAILURE);
}
if (argc >= 5)
if (size < 1 || size >= WINDIVERT_BATCH_MAX * WINDIVERT_MTU_MAX)
{
priority = atoi(argv[4]);
fprintf(stderr, "error: buffer size must be within the range 1..%d, "
"found %d\n", WINDIVERT_BATCH_MAX * WINDIVERT_MTU_MAX,
size);
exit(EXIT_FAILURE);
}
// Divert traffic matching the filter:
handle = WinDivertOpen(argv[1], WINDIVERT_LAYER_NETWORK, (INT16)priority,
0);
handle = WinDivertOpen(filter, layer, (INT16)priority, 0);
if (handle == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_INVALID_PARAMETER)
@@ -104,13 +217,13 @@ int __cdecl main(int argc, char **argv)
}
// Start the threads
for (i = 1; i < num_threads; i++)
for (i = 1; i < threads; i++)
{
thread = CreateThread(NULL, 1, (LPTHREAD_START_ROUTINE)passthru,
(LPVOID)handle, 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);
}
@@ -118,24 +231,33 @@ int __cdecl main(int argc, char **argv)
// Main thread:
passthru((LPVOID)handle);
return 0;
}
// Passthru thread.
static DWORD passthru(LPVOID arg)
{
UINT8 packet[MAXBUF];
UINT8 *packet;
UINT packet_len, addr_len;
WINDIVERT_ADDRESS addr[MAXBATCH];
WINDIVERT_ADDRESS *addr;
HANDLE handle = (HANDLE)arg;
packet = (UINT8 *)malloc(size);
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,
if (!WinDivertRecvEx(handle, packet, size, &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>
+10 -77
View File
@@ -1,6 +1,6 @@
/*
* streamdump.c
* (C) 2018, all rights reserved,
* (C) 2023, 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, addr.Layer, NULL, NULL,
&ip_header, NULL, NULL, NULL, NULL, &tcp_header, NULL, NULL, NULL);
if (ip_header == NULL || tcp_header == NULL)
{
warning("failed to parse packet (%d)", GetLastError());
continue;
@@ -292,19 +236,8 @@ 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)
WinDivertHelperCalcChecksums(packet, packet_len, addr.Layer, &addr, 0);
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>
+19 -14
View File
@@ -1,6 +1,6 @@
/*
* webfilter.c
* (C) 2018, all rights reserved,
* (C) 2023, 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, addr.Layer, NULL, NULL,
&ip_header, NULL, NULL, NULL, NULL, &tcp_header, NULL, &payload,
&payload_len);
if (ip_header == NULL || tcp_header == NULL || payload == NULL ||
!BlackListPayloadMatch(blacklist, payload, (UINT16)payload_len))
{
// 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());
@@ -228,8 +230,9 @@ int __cdecl main(int argc, char **argv)
reset->tcp.DstPort = htons(80);
reset->tcp.SeqNum = tcp_header->SeqNum;
reset->tcp.AckNum = tcp_header->AckNum;
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(PACKET), &addr, 0);
if (!WinDivertSend(handle, (PVOID)reset, sizeof(PACKET), &addr, NULL))
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(PACKET),
addr.Layer, &addr, 0);
if (!WinDivertSend(handle, (PVOID)reset, sizeof(PACKET), NULL, &addr))
{
fprintf(stderr, "warning: failed to send reset packet (%d)\n",
GetLastError());
@@ -243,9 +246,10 @@ int __cdecl main(int argc, char **argv)
blockpage->header.tcp.AckNum =
htonl(ntohl(tcp_header->SeqNum) + payload_len);
addr.Outbound = !addr.Outbound; // Reverse direction.
WinDivertHelperCalcChecksums((PVOID)blockpage, blockpage_len, &addr, 0);
if (!WinDivertSend(handle, (PVOID)blockpage, blockpage_len, &addr,
NULL))
WinDivertHelperCalcChecksums((PVOID)blockpage, blockpage_len,
addr.Layer, &addr, 0);
if (!WinDivertSend(handle, (PVOID)blockpage, blockpage_len, NULL,
&addr))
{
fprintf(stderr, "warning: failed to send block page packet (%d)\n",
GetLastError());
@@ -261,8 +265,9 @@ int __cdecl main(int argc, char **argv)
htonl(ntohl(tcp_header->AckNum) + sizeof(block_data) - 1);
finish->tcp.AckNum =
htonl(ntohl(tcp_header->SeqNum) + payload_len);
WinDivertHelperCalcChecksums((PVOID)finish, sizeof(PACKET), &addr, 0);
if (!WinDivertSend(handle, (PVOID)finish, sizeof(PACKET), &addr, NULL))
WinDivertHelperCalcChecksums((PVOID)finish, sizeof(PACKET),
addr.Layer, &addr, 0);
if (!WinDivertSend(handle, (PVOID)finish, sizeof(PACKET), NULL, &addr))
{
fprintf(stderr, "warning: failed to send finish packet (%d)\n",
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>
+107 -130
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: "???"));
@@ -319,11 +244,14 @@ usage:
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
switch (addr.Reflect.Layer)
{
case WINDIVERT_LAYER_ETHERNET:
fputs("ETHERNET", stdout);
break;
case WINDIVERT_LAYER_NETWORK:
fputs("NETWORK", stdout);
break;
case WINDIVERT_LAYER_NETWORK_FORWARD:
fputs("NETWORK_FORWARD", stdout);
fputs("FORWARD", stdout);
break;
case WINDIVERT_LAYER_FLOW:
fputs("FLOW", stdout);
@@ -369,11 +297,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 +312,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 +333,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>
+222 -57
View File
@@ -1,6 +1,6 @@
/*
* windivert.h
* (C) 2018, all rights reserved,
* (C) 2023, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -40,7 +40,7 @@
#endif /* WINDIVERT_KERNEL */
#ifndef WINDIVERTEXPORT
#define WINDIVERTEXPORT __declspec(dllimport)
#define WINDIVERTEXPORT extern __declspec(dllimport)
#endif /* WINDIVERTEXPORT */
#ifdef __MINGW32__
@@ -79,8 +79,18 @@ typedef enum
WINDIVERT_LAYER_FLOW = 2, /* Flow layer. */
WINDIVERT_LAYER_SOCKET = 3, /* Socket layer. */
WINDIVERT_LAYER_REFLECT = 4, /* Reflect layer. */
WINDIVERT_LAYER_ETHERNET = 5, /* Ethernet layer. */
} WINDIVERT_LAYER, *PWINDIVERT_LAYER;
/*
* WinDivert ETHERNET layer data.
*/
typedef struct
{
UINT32 IfIdx; /* Packet's interface index. */
UINT32 SubIfIdx; /* Packet's sub-interface index. */
} WINDIVERT_DATA_ETHERNET, *PWINDIVERT_DATA_ETHERNET;
/*
* WinDivert NETWORK and NETWORK_FORWARD layer data.
*/
@@ -95,6 +105,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 +120,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 +145,40 @@ 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:12;
UINT32 Length:20; /* Packet length. */
union
{
WINDIVERT_DATA_ETHERNET Ethernet;
/* Ethernet layer data. */
WINDIVERT_DATA_NETWORK Network; /* Network layer data. */
WINDIVERT_DATA_FLOW Flow; /* Flow layer data. */
WINDIVERT_DATA_SOCKET Socket; /* Socket layer data. */
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 +190,13 @@ 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_ETHERNET_FRAME = 10,/* Ethernet frame. */
} WINDIVERT_EVENT, *PWINDIVERT_EVENT;
/*
@@ -179,19 +208,21 @@ 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
#define WINDIVERT_FLAG_FRAGMENTS 0x0020
/*
* 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.
@@ -209,7 +240,7 @@ typedef enum
/*
* Open a WinDivert handle.
*/
extern WINDIVERTEXPORT HANDLE WinDivertOpen(
WINDIVERTEXPORT HANDLE WinDivertOpen(
__in const char *filter,
__in WINDIVERT_LAYER layer,
__in INT16 priority,
@@ -218,21 +249,21 @@ extern WINDIVERTEXPORT HANDLE WinDivertOpen(
/*
* Receive (read) a packet from a WinDivert handle.
*/
extern WINDIVERTEXPORT BOOL WinDivertRecv(
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(
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,
@@ -241,21 +272,21 @@ extern WINDIVERTEXPORT BOOL WinDivertRecvEx(
/*
* Send (write/inject) a packet to a WinDivert handle.
*/
extern WINDIVERTEXPORT BOOL WinDivertSend(
WINDIVERTEXPORT BOOL WinDivertSend(
__in HANDLE handle,
__in const VOID *pPacket,
__in UINT packetLen,
__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.
*/
extern WINDIVERTEXPORT BOOL WinDivertSendEx(
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,
@@ -264,20 +295,20 @@ extern WINDIVERTEXPORT BOOL WinDivertSendEx(
/*
* Shutdown a WinDivert handle.
*/
extern WINDIVERTEXPORT BOOL WinDivertShutdown(
WINDIVERTEXPORT BOOL WinDivertShutdown(
__in HANDLE handle,
__in WINDIVERT_SHUTDOWN how);
/*
* Close a WinDivert handle.
*/
extern WINDIVERTEXPORT BOOL WinDivertClose(
WINDIVERTEXPORT BOOL WinDivertClose(
__in HANDLE handle);
/*
* Set a WinDivert handle parameter.
*/
extern WINDIVERTEXPORT BOOL WinDivertSetParam(
WINDIVERTEXPORT BOOL WinDivertSetParam(
__in HANDLE handle,
__in WINDIVERT_PARAM param,
__in UINT64 value);
@@ -285,21 +316,105 @@ extern WINDIVERTEXPORT BOOL WinDivertSetParam(
/*
* Get a WinDivert handle parameter.
*/
extern WINDIVERTEXPORT BOOL WinDivertGetParam(
WINDIVERTEXPORT BOOL WinDivertGetParam(
__in HANDLE handle,
__in WINDIVERT_PARAM param,
__out UINT64 *pValue);
#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.
* Ethernet/ARP/IPv4/IPv6/ICMP/ICMPv6/TCP/UDP header definitions.
*/
typedef struct
{
UINT8 DstAddr[6];
UINT8 SrcAddr[6];
UINT16 Type;
} WINDIVERT_ETHHDR, *PWINDIVERT_ETHHDR;
typedef struct
{
UINT16 Hardware;
UINT16 Protocol;
UINT8 HardLength;
UINT8 ProtLength;
UINT16 Opcode;
} WINDIVERT_ARPHDR, *PWINDIVERT_ARPHDR;
#define WINDIVERT_ARPHDR_VALIDATE(hdr, len) \
((hdr) != NULL && \
(len) >= sizeof(WINDIVERT_ARPHDR) && \
(len) >= sizeof(WINDIVERT_ARPHDR) + \
2 * (hdr)->HardLength + 2 * (hdr)->ProtLength && \
(hdr)->Hardware == 0x0100 && \
(hdr)->HardLength == 6 && \
(((hdr)->Protocol == 0x0008 && \
(hdr)->ProtLength == 4) || \
((hdr)->Protocol == 0xDD86 && \
(hdr)->ProtLength == 16)))
#define WINDIVERT_ARPHDR_GET_SRCHARDADDR_OFFSET(hdr) \
(sizeof(WINDIVERT_ARPHDR))
#define WINDIVERT_ARPHDR_GET_SRCPROTADDR_OFFSET(hdr) \
(sizeof(WINDIVERT_ARPHDR)+(hdr)->HardLength)
#define WINDIVERT_ARPHDR_GET_DSTHARDADDR_OFFSET(hdr) \
(sizeof(WINDIVERT_ARPHDR)+(hdr)->HardLength+(hdr)->ProtLength)
#define WINDIVERT_ARPHDR_GET_DSTPROTADDR_OFFSET(hdr) \
(sizeof(WINDIVERT_ARPHDR)+2*(hdr)->HardLength+(hdr)->ProtLength)
#define WINDIVERT_ARPHDR_GET_SRCMACADDR_PTR(hdr, len) \
(!WINDIVERT_ARPHDR_VALIDATE(hdr, len) || \
(hdr)->Hardware != 0x0100? NULL: \
(((UINT8 *)(hdr))+WINDIVERT_ARPHDR_GET_SRCHARDADDR_OFFSET(hdr)))
#define WINDIVERT_ARPHDR_GET_SRCIPV4ADDR_PTR(hdr, len) \
(!WINDIVERT_ARPHDR_VALIDATE(hdr, len) || \
(hdr)->Protocol != 0x0008? NULL: \
((UINT32 *)(((UINT8 *)(hdr))+WINDIVERT_ARPHDR_GET_SRCPROTADDR_OFFSET(hdr))))
#define WINDIVERT_ARPHDR_GET_SRCIPV6ADDR_PTR(hdr, len) \
(!WINDIVERT_ARPHDR_VALIDATE(hdr, len) || \
(hdr)->Protocol != 0xDD86? NULL: \
((UINT32 *)(((UINT8 *)(hdr))+WINDIVERT_ARPHDR_GET_SRCPROTADDR_OFFSET(hdr))))
#define WINDIVERT_ARPHDR_GET_DSTMACADDR_PTR(hdr, len) \
(!WINDIVERT_ARPHDR_VALIDATE(hdr, len) || \
(hdr)->Hardware != 0x0100? NULL: \
(((UINT8 *)(hdr))+WINDIVERT_ARPHDR_GET_DSTHARDADDR_OFFSET(hdr)))
#define WINDIVERT_ARPHDR_GET_DSTIPV4ADDR_PTR(hdr, len) \
(!WINDIVERT_ARPHDR_VALIDATE(hdr, len) || \
(hdr)->Protocol != 0x0008? NULL: \
((UINT32 *)(((UINT8 *)(hdr))+WINDIVERT_ARPHDR_GET_DSTPROTADDR_OFFSET(hdr))))
#define WINDIVERT_ARPHDR_GET_DSTIPV6ADDR_PTR(hdr, len) \
(!WINDIVERT_ARPHDR_VALIDATE(hdr, len) || \
(hdr)->Protocol != 0xDD86? NULL: \
((UINT32 *)(((UINT8 *)(hdr))+WINDIVERT_ARPHDR_GET_DSTPROTADDR_OFFSET(hdr))))
typedef struct
{
UINT8 HdrLength:4;
UINT8 Version:4;
@@ -430,6 +545,10 @@ typedef struct
UINT16 Checksum;
} WINDIVERT_UDPHDR, *PWINDIVERT_UDPHDR;
#ifdef _MSC_VER
#pragma warning(pop)
#endif
/*
* Flags for WinDivertHelperCalcChecksums()
*/
@@ -444,9 +563,10 @@ typedef struct
/*
* Hash a packet.
*/
extern WINDIVERTEXPORT UINT64 WinDivertHelperHashPacket(
WINDIVERTEXPORT UINT64 WinDivertHelperHashPacket(
__in const VOID *pPacket,
__in UINT packetLen,
__in WINDIVERT_LAYER layer,
__in UINT64 seed
#ifdef __cplusplus
= 0
@@ -456,11 +576,15 @@ extern WINDIVERTEXPORT UINT64 WinDivertHelperHashPacket(
/*
* Parse IPv4/IPv6/ICMP/ICMPv6/TCP/UDP headers from a raw packet.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperParsePacket(
WINDIVERTEXPORT BOOL WinDivertHelperParsePacket(
__in const VOID *pPacket,
__in UINT packetLen,
__in WINDIVERT_LAYER layer,
__out_opt PWINDIVERT_ETHHDR *ppEthHdr,
__out_opt PWINDIVERT_ARPHDR *ppArpHdr,
__out_opt PWINDIVERT_IPHDR *ppIpHdr,
__out_opt PWINDIVERT_IPV6HDR *ppIpv6Hdr,
__out_opt UINT8 *pProtocol,
__out_opt PWINDIVERT_ICMPHDR *ppIcmpHdr,
__out_opt PWINDIVERT_ICMPV6HDR *ppIcmpv6Hdr,
__out_opt PWINDIVERT_TCPHDR *ppTcpHdr,
@@ -468,24 +592,39 @@ extern WINDIVERTEXPORT BOOL WinDivertHelperParsePacket(
__out_opt PVOID *ppData,
__out_opt UINT *pDataLen);
/*
* Parse a MAC address.
*/
WINDIVERTEXPORT BOOL WinDivertHelperParseMACAddress(
__in const char *addrStr,
__out_opt UINT8 *pAddr);
/*
* Parse an IPv4 address.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperParseIPv4Address(
WINDIVERTEXPORT BOOL WinDivertHelperParseIPv4Address(
__in const char *addrStr,
__out_opt UINT32 *pAddr);
/*
* Parse an IPv6 address.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperParseIPv6Address(
WINDIVERTEXPORT BOOL WinDivertHelperParseIPv6Address(
__in const char *addrStr,
__out_opt UINT32 *pAddr);
/*
* Format a MAC address.
*/
WINDIVERTEXPORT BOOL WinDivertHelperFormatMACAddress(
__in const UINT8 *pAddr,
__out char *buffer,
__in UINT bufLen);
/*
* Format an IPv4 address.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv4Address(
WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv4Address(
__in UINT32 addr,
__out char *buffer,
__in UINT bufLen);
@@ -493,7 +632,7 @@ extern WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv4Address(
/*
* Format an IPv6 address.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv6Address(
WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv6Address(
__in const UINT32 *pAddr,
__out char *buffer,
__in UINT bufLen);
@@ -501,16 +640,25 @@ extern WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv6Address(
/*
* Calculate IPv4/IPv6/ICMP/ICMPv6/TCP/UDP checksums.
*/
extern WINDIVERTEXPORT UINT WinDivertHelperCalcChecksums(
WINDIVERTEXPORT BOOL WinDivertHelperCalcChecksums(
__inout VOID *pPacket,
__in UINT packetLen,
__in_opt const WINDIVERT_ADDRESS *pAddr,
__in WINDIVERT_LAYER layer,
__out_opt WINDIVERT_ADDRESS *pAddr,
__in UINT64 flags);
/*
* Decrement the TTL/HopLimit.
*/
WINDIVERTEXPORT BOOL WinDivertHelperDecrementTTL(
__inout VOID *pPacket,
__in UINT packetLen,
__in WINDIVERT_LAYER layer);
/*
* Compile the given filter string.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperCompileFilter(
WINDIVERTEXPORT BOOL WinDivertHelperCompileFilter(
__in const char *filter,
__in WINDIVERT_LAYER layer,
__out_opt char *object,
@@ -521,16 +669,17 @@ extern WINDIVERTEXPORT BOOL WinDivertHelperCompileFilter(
/*
* Evaluate the given filter string.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperEvalFilter(
WINDIVERTEXPORT BOOL WinDivertHelperEvalFilter(
__in const char *filter,
__in const VOID *pPacket,
__in UINT packetLen,
__in WINDIVERT_LAYER layer,
__in const WINDIVERT_ADDRESS *pAddr);
/*
* Format the given filter string.
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperFormatFilter(
WINDIVERTEXPORT BOOL WinDivertHelperFormatFilter(
__in const char *filter,
__in WINDIVERT_LAYER layer,
__out char *buffer,
@@ -539,22 +688,38 @@ extern WINDIVERTEXPORT BOOL WinDivertHelperFormatFilter(
/*
* Byte ordering.
*/
extern WINDIVERTEXPORT UINT16 WinDivertHelperNtohs(
WINDIVERTEXPORT UINT16 WinDivertHelperNtohs(
__in UINT16 x);
extern WINDIVERTEXPORT UINT16 WinDivertHelperHtons(
WINDIVERTEXPORT UINT16 WinDivertHelperHtons(
__in UINT16 x);
extern WINDIVERTEXPORT UINT32 WinDivertHelperNtohl(
WINDIVERTEXPORT UINT32 WinDivertHelperNtohl(
__in UINT32 x);
extern WINDIVERTEXPORT UINT32 WinDivertHelperHtonl(
WINDIVERTEXPORT UINT32 WinDivertHelperHtonl(
__in UINT32 x);
extern WINDIVERTEXPORT UINT64 WinDivertHelperNtohll(
WINDIVERTEXPORT UINT64 WinDivertHelperNtohll(
__in UINT64 x);
extern WINDIVERTEXPORT UINT64 WinDivertHelperHtonll(
WINDIVERTEXPORT UINT64 WinDivertHelperHtonll(
__in UINT64 x);
extern WINDIVERTEXPORT void WinDivertHelperNtohIpv6Address(
WINDIVERTEXPORT void WinDivertHelperNtohMACAddress(
__in const UINT8 *inAddr,
__out UINT8 *outAddr);
WINDIVERTEXPORT void WinDivertHelperHtonMACAddress(
__in const UINT8 *inAddr,
__out UINT8 *outAddr);
WINDIVERTEXPORT void WinDivertHelperNtohIPv6Address(
__in const UINT *inAddr,
__out UINT *outAddr);
extern WINDIVERTEXPORT void WinDivertHelperHtonIpv6Address(
WINDIVERTEXPORT void WinDivertHelperHtonIPv6Address(
__in const UINT *inAddr,
__out UINT *outAddr);
/*
* Old names to be removed in the next version.
*/
WINDIVERTEXPORT void WinDivertHelperNtohIpv6Address(
__in const UINT *inAddr,
__out UINT *outAddr);
WINDIVERTEXPORT void WinDivertHelperHtonIpv6Address(
__in const UINT *inAddr,
__out UINT *outAddr);
+135 -84
View File
@@ -1,6 +1,6 @@
/*
* windivert_device.h
* (C) 2018, all rights reserved,
* (C) 2023, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -38,26 +38,31 @@
/*
* NOTE: This is the low-level interface to the WinDivert device driver.
* This interface should not be used directly, instead use the high-level
* interface provided by the divert API.
* interface provided by the WinDivert API.
*/
#define WINDIVERT_KERNEL
#include "windivert.h"
#define WINDIVERT_VERSION 2
#define WINDIVERT_VERSION_MAJOR 3
#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,22 +130,41 @@
#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_FRAGMENT 85
#define WINDIVERT_FILTER_FIELD_ETH_DST_ADDR 86
#define WINDIVERT_FILTER_FIELD_ETH_SRC_ADDR 87
#define WINDIVERT_FILTER_FIELD_ETH_TYPE 88
#define WINDIVERT_FILTER_FIELD_ARP 89
#define WINDIVERT_FILTER_FIELD_ARP_HARDWARE 90
#define WINDIVERT_FILTER_FIELD_ARP_PROTOCOL 91
#define WINDIVERT_FILTER_FIELD_ARP_HARD_LENGTH 92
#define WINDIVERT_FILTER_FIELD_ARP_PROT_LENGTH 93
#define WINDIVERT_FILTER_FIELD_ARP_OPCODE 94
#define WINDIVERT_FILTER_FIELD_ARP_SRC_HARD_ADDR 95
#define WINDIVERT_FILTER_FIELD_ARP_SRC_PROT_ADDR 96
#define WINDIVERT_FILTER_FIELD_ARP_DST_HARD_ADDR 97
#define WINDIVERT_FILTER_FIELD_ARP_DST_PROT_ADDR 98
#define WINDIVERT_FILTER_FIELD_MAX \
WINDIVERT_FILTER_FIELD_RANDOM32
WINDIVERT_FILTER_FIELD_ARP_DST_PROT_ADDR
#define WINDIVERT_FILTER_TEST_EQ 0
#define WINDIVERT_FILTER_TEST_NEQ 1
@@ -150,15 +174,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 +195,8 @@
*/
#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 | \
WINDIVERT_FLAG_FRAGMENTS)
#define WINDIVERT_FLAGS_EXCLUDE(flags, flag1, flag2) \
(((flags) & ((flag1) | (flag2))) != ((flag1) | (flag2)))
#define WINDIVERT_FLAGS_VALID(flags) \
@@ -181,76 +204,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 +315,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 */
+6 -12
View File
@@ -4,7 +4,7 @@ Class = WFPCALLOUTS
ClassGuid = {57465043-616C-6C6F-7574-5F636C617373}
Provider = %Basil%
CatalogFile = WinDivert32.Cat
DriverVer = 01/01/2019,2.0.0
DriverVer = 01/09/2022,2.2.2
[SourceDisksNames]
1 = %DiskName%
@@ -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"
+6 -12
View File
@@ -4,7 +4,7 @@ Class = WFPCALLOUTS
ClassGuid = {57465043-616C-6C6F-7574-5F636C617373}
Provider = %Basil%
CatalogFile = WinDivert64.Cat
DriverVer = 01/01/2019,2.0.0
DriverVer = 01/09/2022,2.2.2
[SourceDisksNames]
1 = %DiskName%
@@ -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"
+24 -12
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.
#
@@ -33,12 +33,17 @@
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# Script for MinGW/Linux cross compilation.
# NOTE: run wddk-build.bat before this script.
# NOTE: run msvc-build.bat before this script.
set -e
ENVS="i686-w64-mingw32 x86_64-w64-mingw32"
if [ "$1" = "debug" ]
then
EXTRA_OPTS="-lmsvcrt -include stdio.h"
fi
for ENV in $ENVS
do
if [ $ENV = "i686-w64-mingw32" ]
@@ -51,17 +56,17 @@ do
BITS=64
MANGLE=
fi
if [ ! -d install/WDDK/$CPU ]
HAVE_SYS=yes
if [ ! -d install/MSVC/$CPU ]
then
echo "WARNING: missing WDDK build; run wddk-build.bat first"
echo "SKIP MINGW-$CPU"
continue
echo "WARNING: missing MSVC build; run msvc-build.bat first"
HAVE_SYS=no
fi
echo "BUILD MINGW-$CPU"
CC="$ENV-gcc"
COPTS="-fno-ident -shared -Wall -Wno-pointer-to-int-cast -Os -Iinclude/
-Wl,--enable-stdcall-fixup -Wl,--entry=${MANGLE}WinDivertDllEntry"
CLIBS="-lgcc -lkernel32 -ladvapi32"
CLIBS="-lkernel32 -ladvapi32 $EXTRA_OPTS"
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/MSVC/$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"
+2663 -1874
View File
File diff suppressed because it is too large Load Diff
+8 -6
View File
@@ -1,6 +1,6 @@
/*
* windivert.rc
* (C) 2018, all rights reserved,
* (C) 2022, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -35,23 +35,25 @@
#include <windows.h>
#include <ntverp.h>
#include "windivert_log.rc"
#define VER_FILETYPE VFT_DRV
#define VER_FILESUBTYPE VFT2_DRV_NETWORK
#define VER_FILEDESCRIPTION_STR \
"The WinDivert driver " \
"The WinDivert 2.2 driver " \
"[URL: https://reqrypt.org/windivert.html] " \
"[Bitcoin: 1C5vZVSbizPeZ8ydTYhUfm4LA2cNwBfcYh]"
#define VER_INTERNALNAME_STR "WinDivert.sys"
#define VER_ORIGINALFILENAME_STR "WinDivert.sys"
#define VER_PRODUCTVERSION 2.0
#define VER_PRODUCTVERSION_STR "2.0"
#define VER_PRODUCTVERSION 2.2
#define VER_PRODUCTVERSION_STR "2.2"
#define VER_COMPANYNAME_STR "Basil"
#define VER_LEGALCOPYRIGHT_YEARS "2011-2019"
#define VER_LEGALCOPYRIGHT_YEARS "2011-2022"
#define VER_LEGALCOPYRIGHT_STR \
"Copyright \251 " VER_COMPANYNAME_STR " " VER_LEGALCOPYRIGHT_YEARS
#define VER_FILEVERSION VER_PRODUCTVERSION
#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR
#define VER_PRODUCTNAME_STR "WinDivert 2.0 driver"
#define VER_PRODUCTNAME_STR "WinDivert 2.2 driver"
#include "common.ver"
+93
View File
@@ -0,0 +1,93 @@
<?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>
<MessageCompile Include="windivert_log.mc">
<RCFilePath>.</RCFilePath>
<HeaderFilePath>.</HeaderFilePath>
</MessageCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="windivert.rc" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="windivert.c">
<TreatWarningAsError>false</TreatWarningAsError>
<Optimization>MaxSpeed</Optimization>
<AdditionalIncludeDirectories>..\include;..\dll;.</AdditionalIncludeDirectories>
</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>Windows8</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>
+59
View File
@@ -0,0 +1,59 @@
;/*
; * windivert_log.mc
; * (C) 2019, all rights reserved,
; *
; * This file is part of WinDivert.
; *
; * WinDivert is free software: you can redistribute it and/or modify it under
; * the terms of the GNU Lesser General Public License as published by the
; * Free Software Foundation, either version 3 of the License, or (at your
; * option) any later version.
; *
; * This program is distributed in the hope that it will be useful, but
; * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
; * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
; * License for more details.
; *
; * You should have received a copy of the GNU Lesser General Public License
; * along with this program. If not, see <http://www.gnu.org/licenses/>.
; *
; * WinDivert is free software; you can redistribute it and/or modify it under
; * the terms of the GNU General Public License as published by the Free
; * Software Foundation; either version 2 of the License, or (at your option)
; * any later version.
; *
; * This program is distributed in the hope that it will be useful, but
; * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
; * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
; * for more details.
; *
; * You should have received a copy of the GNU General Public License along
; * with this program; if not, write to the Free Software Foundation, Inc., 51
; * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
; */
MessageIdTypedef=NTSTATUS
SeverityNames = (
Success = 0x0:STATUS_SEVERITY_SUCCESS
Informational = 0x1:STATUS_SEVERITY_INFORMATIONAL
Warning = 0x2:STATUS_SEVERITY_WARNING
Error = 0x3:STATUS_SEVERITY_ERROR
)
FacilityNames = (
System = 0x0:FACILITY_SYSTEM
Runtime = 0x2:FACILITY_RUNTIME
Stubs = 0x3:FACILITY_STUBS
Io = 0x4:FACILITY_IO_ERROR_CODE
WinDivert = 0x574:FACILITY_WINDIVERT
)
MessageId=0x312D
Facility=WinDivert
Severity=Informational
SymbolicName=WINDIVERT_INFO_EVENT
Language=English
%2 %3 (processId=%4)
.
+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/"
+739 -23
View File
@@ -1,6 +1,6 @@
/*
* test.c
* (C) 2018, all rights reserved,
* (C) 2021, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -43,6 +43,7 @@
#include "windivert.h"
#define MAX_PACKET 2048
#define MIN(a, b) ((a) < (b)? (a): (b))
/*
* Packet data.
@@ -71,6 +72,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.
@@ -111,6 +113,30 @@ static const struct packet pkt_ipv6_exthdrs_udp =
sizeof(ipv6_exthdrs_udp),
"ipv6_exthdrs_udp"
};
static const struct packet pkt_ipv4_fragment_0 =
{
ipv4_fragment_0,
sizeof(ipv4_fragment_0),
"ipv4_fragemnt_0"
};
static const struct packet pkt_ipv4_fragment_1 =
{
ipv4_fragment_1,
sizeof(ipv4_fragment_1),
"ipv4_fragment_1"
};
static const struct packet pkt_ipv6_fragment_0 =
{
ipv6_fragment_0,
sizeof(ipv6_fragment_0),
"ipv6_fragment_0"
};
static const struct packet pkt_ipv6_fragment_1 =
{
ipv6_fragment_1,
sizeof(ipv6_fragment_1),
"ipv6_fragment_1"
};
static const struct test tests[] =
{
{"event = PACKET", &pkt_echo_request, TRUE},
@@ -152,6 +178,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},
@@ -164,6 +192,7 @@ static const struct test tests[] =
&pkt_echo_request, TRUE},
{"(tcp? tcp.DstPort == 80: true) and (udp? udp.DstPort == 80: true)",
&pkt_echo_request, TRUE},
{"fragment", &pkt_echo_request, FALSE},
{"ip and ip and ip and ip and ip and " // Max filter length:
"ip and ip and ip and ip and ip and "
"ip and ip and ip and ip and ip and "
@@ -255,7 +284,62 @@ 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},
{"ip.MF or ip.FragOff != 0", &pkt_echo_request, FALSE},
{"icmp.Body != 123 || icmp.Body == 123", &pkt_echo_request, TRUE},
{"length == 84 && ip.Length == 84", &pkt_echo_request, TRUE},
{"tcp", &pkt_http_request, TRUE},
{"protocol == TCP", &pkt_http_request, TRUE},
{"outbound and tcp and tcp.DstPort == 80", &pkt_http_request, TRUE},
{"outbound and tcp and tcp.DstPort == 81", &pkt_http_request, FALSE},
{"outbound and tcp and tcp.DstPort != 80", &pkt_http_request, FALSE},
@@ -341,15 +425,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 +548,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 +562,97 @@ 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.DstAddr >= ::", &pkt_dns_request, FALSE},
{"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 +666,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 +750,61 @@ static const struct test tests[] =
{"icmpv6.Body == 0x10720003", &pkt_ipv6_echo_reply, TRUE},
{"ipv6.DstAddr >= 1000", &pkt_ipv6_echo_reply, FALSE},
{"ipv6.DstAddr <= 1", &pkt_ipv6_echo_reply, TRUE},
{"length == 104 && ipv6.Length == 64", &pkt_ipv6_echo_reply, TRUE},
{"ip and !loopback and (outbound? tcp.DstPort == 80 or"
" tcp.DstPort == 443 or udp.DstPort == 53 :"
" icmp.Type == 11 and icmp.Code == 0)", &pkt_ipv6_echo_reply, FALSE},
{"fragment", &pkt_ipv6_echo_reply, FALSE},
{"random8 < 128", &pkt_ipv6_echo_reply, TRUE},
{"(random8 < 128? random16 < 0x8000: random32 < 0x80000000)",
&pkt_ipv6_echo_reply, TRUE},
{"(((((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,47 +816,162 @@ static const struct test tests[] =
{"ipv6.SrcAddr != abcd::1", &pkt_ipv6_exthdrs_udp, TRUE},
{"ipv6.SrcAddr >= abcd::1", &pkt_ipv6_exthdrs_udp, FALSE},
{"ipv6.SrcAddr > abcd::1", &pkt_ipv6_exthdrs_udp, FALSE},
{"ipv6.DstAddr >= ::", &pkt_ipv6_exthdrs_udp, TRUE},
{"timestamp > -1", &pkt_ipv6_exthdrs_udp, TRUE},
{"udp.SrcPort == 4660 and udp.DstPort == 43690",
&pkt_ipv6_exthdrs_udp, TRUE},
{"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},
{"fragment", &pkt_ipv4_fragment_0, TRUE},
{"ip.MF or ip.FragOff != 0", &pkt_ipv4_fragment_0, TRUE},
{"icmp", &pkt_ipv4_fragment_0, TRUE},
{"icmp.Body != 123 || icmp.Body == 123", &pkt_ipv4_fragment_0, TRUE},
{"length == 84 || ip.Length == 84", &pkt_ipv4_fragment_0, FALSE},
{"ip.HdrLength == 5 and ip.TOS == 0 and ip.Length == 28 and "
"ip.Id == 0x1234 and ip.FragOff == 0 and ip.MF == 1 and ip.DF == 0 and "
"ip.TTL == 64 and ip.Protocol == 1 and ip.SrcAddr == 0xFFFF0A000001 and "
"ip.DstAddr == 0xFFFF08080808 and icmp.Type == 8 and icmp.Code == 0 and "
"icmp.Body == 0x0D560001", &pkt_ipv4_fragment_0, TRUE},
{"fragment", &pkt_ipv4_fragment_1, TRUE},
{"ip.MF or ip.FragOff != 0", &pkt_ipv4_fragment_1, TRUE},
{"icmp", &pkt_ipv4_fragment_1, FALSE},
{"icmp.Body != 123 || icmp.Body == 123", &pkt_ipv4_fragment_1, FALSE},
{"length == 84 || ip.Length == 84", &pkt_ipv4_fragment_1, FALSE},
{"ip.HdrLength == 5 and ip.TOS == 0 and ip.Length == 76 and "
"ip.Id == 0x1234 and ip.FragOff == 1 and ip.MF == 0 and ip.DF == 0 and "
"ip.TTL == 64 and ip.Protocol == 1 and ip.SrcAddr == 0xFFFF0A000001 and "
"ip.DstAddr == 0xFFFF08080808", &pkt_ipv4_fragment_1, TRUE},
{"fragment", &pkt_ipv6_fragment_0, TRUE},
{"icmpv6", &pkt_ipv6_fragment_0, TRUE},
{"length == 104 || ipv6.Length == 64", &pkt_ipv6_fragment_0, FALSE},
{"ipv6.TrafficClass == 0x00000000 and ipv6.FlowLabel == 0x0000 and "
"ipv6.Length == 32 and ipv6.NextHdr == 44 and ipv6.HopLimit == 31 and "
"ipv6.SrcAddr == 0:0:0:0:0:0:0:1 and ipv6.DstAddr == 0:0:0:0:0:0:0:1 and "
"icmpv6.Type == 129 and icmpv6.Code == 0 and icmpv6.Body == 0x10720003",
&pkt_ipv6_fragment_0, TRUE},
{"fragment", &pkt_ipv6_fragment_1, TRUE},
{"icmpv6", &pkt_ipv6_fragment_1, FALSE},
{"length == 104 || ipv6.Length == 64", &pkt_ipv6_fragment_1, FALSE},
{"ipv6.TrafficClass == 0x00000000 and ipv6.FlowLabel == 0x0000 and "
"ipv6.Length == 48 and ipv6.NextHdr == 44 and ipv6.HopLimit == 31 and "
"ipv6.SrcAddr == 0:0:0:0:0:0:0:1 and ipv6.DstAddr == 0:0:0:0:0:0:0:1",
&pkt_ipv6_fragment_1, TRUE},
};
/*
* Test range.
*/
static size_t lo = 0, hi = UINT_MAX;
/*
* Main.
*/
int main(void)
int main(int argc, char **argv)
{
HANDLE upper_handle, lower_handle;
HANDLE console;
HANDLE console, monitor;
BOOL passed[sizeof(tests) / sizeof(struct test)], first;
DWORD result;
LARGE_INTEGER freq;
UINT64 diff;
size_t i;
size_t num_tests = sizeof(tests) / sizeof(struct test), passed_tests;
switch (argc)
{
case 1:
break;
case 3:
lo = atoi(argv[1]);
hi = atoi(argv[2]);
if (hi >= lo)
{
break;
}
// Fallthrough
default:
fprintf(stderr, "usage: %s [low high]\n", argv[0]);
exit(EXIT_FAILURE);
}
hi = MIN(num_tests, hi);
// Open handles to:
// (1) stop normal traffic from interacting with the tests; and
// (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,12 +979,22 @@ 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);
// Run tests:
size_t num_tests = sizeof(tests) / sizeof(struct test), passed_tests = 0;
for (i = 0; i < num_tests; i++)
passed_tests = 0;
for (i = lo; i < num_tests && i <= hi; i++)
{
const char *filter = tests[i].filter;
const char *packet = tests[i].packet->packet;
@@ -479,11 +1003,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,8 +1036,60 @@ 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);
((double)passed_tests / (double)(hi - lo)) * 100.0);
first = TRUE;
for (i = lo; i < num_tests && i <= hi; 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 +1113,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 +1127,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 +1196,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 +1244,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];
@@ -672,10 +1276,10 @@ static BOOL run_test(HANDLE inject_handle, const char *filter,
// non-matching random values have been lost:
if ((!random &&
WinDivertHelperEvalFilter(filter, buf[idx], buf_len[idx],
&addr[idx]) != result) ||
WINDIVERT_LAYER_NETWORK, &addr[idx]) != result) ||
(random && result &&
!WinDivertHelperEvalFilter(filter, buf[idx], buf_len[idx],
&addr[idx])))
WINDIVERT_LAYER_NETWORK, &addr[idx])))
{
fprintf(stderr, "error: filter \"%s\" does not match the given "
"packet\n", filter);
@@ -689,6 +1293,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 +1342,92 @@ 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 = lo; i < num_tests && i <= hi; 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, WINDIVERT_LAYER_NETWORK, &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>
+54 -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.
*
@@ -181,3 +181,56 @@ static const unsigned char ipv6_exthdrs_udp[] =
0x72, 0x6c, 0x64, 0x21, 0x01
};
// IPV4 FRAGMENT #0
static const unsigned char ipv4_fragment_0[] =
{
0x45, 0x00, 0x00, 0x1C, 0x12, 0x34, 0x20, 0x00,
0x40, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x01,
0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x3c, 0xd2,
0x0d, 0x56, 0x00, 0x01
};
// IPV4 FRAGMENT #1
static const unsigned char ipv4_fragment_1[] =
{
0x45, 0x00, 0x00, 0x4C, 0x12, 0x34, 0x00, 0x01,
0x40, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x01,
0x08, 0x08, 0x08, 0x08, 0x8b, 0xa6, 0x60, 0x54,
0x00, 0x00, 0x00, 0x00, 0xf9, 0x08, 0x0a, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13,
0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33,
0x34, 0x35, 0x36, 0x37
};
// IPV6 FRAGMENT #0
static const unsigned char ipv6_fragment_0[] =
{
0x60, 0x00, 0x00, 0x00, 0x00, 0x20, 0x2c, 0x1f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x3a, 0x00, 0x00, 0x01, 0xc7, 0xf6, 0xce, 0x53,
0x81, 0x00, 0x6e, 0xd6, 0x10, 0x72, 0x00, 0x03,
0xa4, 0xd5, 0x69, 0x54, 0x00, 0x00, 0x00, 0x00,
0xab, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
// IPV6 FRAGMENT #1
static const unsigned char ipv6_fragment_1[] =
{
0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x2c, 0x1f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x3a, 0x00, 0x00, 0x18, 0xc7, 0xf6, 0xce, 0x53,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
};
+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.
::