- 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.
- 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.
- 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.
(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.
- 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).
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.
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.
- 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.
- 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.
- Adds 3 new "pseudo-random" filter expressions:
* random8 (8bit)
* random16 (16bit)
* random32 (32bit)
Not really "random", but these values are based
on a hash of the packet headers & timestamp.
These are useful for traffic sampling, e.g.:
"random8 < 100" matches ~39% of all packets.
- Add new WinDivertHelperHashPacket() helper
function. The algorithm is an xxHash variant.
This function allows the user application to
"shutdown" a handle in anticipation of a
call to WinDivertClose(). When a handle has
been shutdown, new packets will no longer be
queued. However, existing queued packets can
still be read by WinDivertRecv(). When the
queue is emptied, WinDivertRecv() will fail
with ERROR_NO_DATA.
The WinDivertShutdown() function is analogous
to the shutdown() socket function.
This change also simplifies events.
Adds the follow terms to the filter language:
- packet[idx]: 8bit packet value at idx.
- packet16[idx]: 16bit packet value at idx.
- packet32[idx]: 32bit packet value at idx.
- PROTO.Payload[idx]: 8bit payload value at idx.
- PROTO.Payload16[idx]: 16bit payload value at
idx.
- PROTO.Payload32[idx]: 32bit payload value at
idx.
where PROTO is {tcp,udp}.
16 and 32bit values assume network byte ordering.
The index may be:
- An undecorated integer, in which case the
packet or payload is treated as a 8/16/32bit
value array, similar to C arrays.
- A 'b' decorated integer, (e.g, packet32[17b]),
in which case the integer is interpreted as a
byte offset.
- A negative (un)decorated integer, in which
case indexing begins at the *end* of the
packet or payload. E.g., packet32[-1] is the
last 32bits of the packet.
If the index is out-of-bounds, then the test
is deemed to be equivalent to "false".
This change allows multiple packets to be
received/sent at once, reducing overheads. To
exploit this feature, applications need to use
the WinDivertRecvEx()/WinDivertSendEx()
functions with the new addrLen parameter. The
passthru example has been modified to use
batching.
The DEBUG flag has been retired since it
conflicts with batching, and was not very
useful anyway.
Adds a new SOCKET layer for monitoring socket
events, such as BIND, LISTEN, CONNECT,
and ACCEPT. These events occur before the
flow is established (and unlike the FLOW layer)
it is possible to block/drop SOCKET events.
Otherwise, this layer is very similar to the
FLOW layer, so the PID is available and injection
is not possible. This commit should be
considered to be a WIP.
Other changes:
- New socketdump.exe sample. Prints socket
events.
- Improve IPv6 address parsing.
- New helper functions:
* WinDivertHelperFormatIPv4Address
* WinDivertHelperFormatIPv6Address
- Fix REFLECT bugs.
- The network 5-tuple can now be accessed at
the NETWORK layer.
- Various cleanups.
Adds a new REFLECT layer for monitoring WinDivert
handles. This includes:
- three new REFLECT events: ESTABLISHED, OPEN and
CLOSE;
- modifying the ADDRESS for REFLECT data:
open time, process-id, layer, flags, and
priority of the opened handle; and
- allowing WinDivertRecv() to read a
representation of the opened filter.
This change also includes a new "object"
representation for WinDivert filter strings.
The API has been updated as follows:
- WinDivertHelperCompileFilter (replaces
CheckFilter) compiles filter strings into the
object form; and
- WinDivertHelperFormatFilter can "decompile" an
object back into a human-readable filter
string.
Other:
- New NO_INSTALL flag.
- New windivertctl.exe sample program.
This allows projects that are strictly "GPLv2
only" to use WinDivert without licensing issues.
See the FSF's compatibility matrix here:
https://www.gnu.org/licenses/gpl-faq.en.html
This change does not affect existing projects
that can continue to use the LGPLv3 as before.
Also, bump the WinDivert version to 1.4.1.
WinDivert will now mark any packet injected by
another driver as an "impostor", meaning that it
did not originate from the network. Changes are:
- User programs may filter impostor packets.
- WinDivertSend() automatically decrements the TTL
for imposter packets, see #41.
Most NIC cards support checksum offloading,
meaning that it is not necessary to calculate the
full IP/TCP/UDP checksums for injected packets.
WINDIVERT_ADDRESS has been extended to include 3
extra flags that indicate if the packet has full
or pseudo checksums. This is a WIP.
The WINDIVERT_HELPER_NO_REPLACE flag tells WinDivertHelperCalcChecksums not to
recalculate and replace non-zero checksum fields. This is useful for
reconstructing the checksums for packets returned by WinDivertRecv(), where
all non-zero checksum fields are already valid. This allows WinDivert1.2
to achieve similar efficiency as WinDivert1.1, where checksums were calculated
by the driver.
Note that for modified packets, the WINDIVERT_HELPER_NO_REPLACE flag should
not be used, as all checksums need to be recalculated from scratch anyway.
Bump version and change magic numbers to make the driver incompatible with
older versions. Also cleanup some driver checksum code missed by previous
commit.
- As discussed in #37, the WINDIVERT_FLAG_NO_CHECKSUM behavior has become the
default. This means that outbound packets returned by WinDivertRecv() are
no longer guaranteed to have valid checksums, thanks to TCP checksum
offloading by the Windows TCP/IP stack. The checksums can still be
recovered by calling WinDivertHelperCalcChecksums() manually.
- Remove the old WinDivert1.0 legacy API, as nobody should still be using it.
Replaces the old filter compiler with a new version that:
- Is a cleaner, more extensible, implementation.
- Can report specific error messages (e.g. bad token vs parse error).
- Supports the new C-style if-then-else expression "(A? B: C)" syntax.
Two new WinDivert helper API functions have been implemented:
- WinDivertHelperCheckFilter() can be used to check a filter string for
errors.
- WinDivertHelperEvalFilter() evaluates a filter on a given packet. Will be
useful for testing.