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.
Since pseudo checksums can now be arbitrary
values, the WinDivertHelperCalcChecksums function
no longer attempts to calculate the pseudo-
header checksum.
The MSVCRT*.dll dependency has been removed by:
(1) using Win32 API equivalents where possible,
and (2) re-implementing some basic C runtime
functions. This prevents multiple MSVCRTs from
being loaded at runtime (if the application uses
a different version than the DLL). The new
WinDivert.dll only depends on KERNEL32.dll and
ADVAPI32.dll.
Furthermore, the MINGW build has been extended
to generate a WinDivert.lib import library file.
This means that the MINGW DLL can now be used
directly by Visual Studio (any version).
For some reason pseudo checksums do not work on
some systems. The workaround is to modify
WinDivertSend() so that it calculates the full
checksums before forwarding the packet to the
driver.
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.
This hardens WinDivert against other drivers that
attempt to modify packets after they were blocked
& absorbed by WinDivert, leading to BSODs. This
is also a fix for issue #110.
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.
- A partial fix for #41
- Decrements the TTL for reinjected packets.
- If (TTL==0), WinDivertRecv() will fail with:
ERROR_HOST_UNREACHABLE = 1232
which is better than looping.
- Immediately reinject in SNIFF mode.
- Use a NET_BUFFER pool for cloned packets.
- Fix bug caused by pool mix up for cloned packets.
- Copy NET_BUFFER_LIST info for non-matching packets.
- Keep reference to original NET_BUFFER_LIST after cloning.
(might not be necessary, but some sample drivers do).
This is a major update designed to modernize the WinDivert driver, including
optimizations, design improvements and bug fixes. The new version has not
been fully tested and should be considered **UNSTABLE**.
- Most of the packet processing is now (almost) fully out-of-band. This is a
good since the classify function runs at DISPATCH_LEVEL. The driver will
still try to match at least one packet before moving the work out-of-band.
- Re-injected non-matching packets are now clones rather than copies.
- Queued packets are still copied. This is because the driver should avoid
keeping a reference to the original packet for very long. Since we do not
trust the user application to handle the packet in a timely fashion, it is
better to copy rather than keep a reference. That said, the driver now
implements an optimization where it will service a read request immediately
if possible (saving 1 packet copy).
- SNIFF mode also now works differently. Previously, SNIFF mode would not
block the original packet. However, this is problematic under the new
design since WinDivert cannot permit the packet and retain a reference to it
at the same time. The new version will block & absorb the original packet
and re-inject a clone out-of-band.
- Packet time management has been replaced. Previously, a timer was used to
periodically wake up a function that would sweep away expired packets. The
new version explicitly timestamps every packet, and expired packets are
cleaned up by the read service routine.
- The context->filter is now deallocated in the destroy callback to avoid
possible a race condition with the callout function. It is unclear if this
is really necessary, however.