84 Commits
Author SHA1 Message Date
basil00 1543e958e6 Dual-license WinDivert under the LGPLv3 and GPLv2.
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.
2018-04-04 18:41:45 +08:00
basil00 bef2240d9e Do not thread the impostor flag.
Only packets directly injected by other drivers
are considered impostor.  This is still sufficient
to prevent infinite loops.
2018-01-13 16:27:20 +08:00
basil00 53845fa8a9 Fix #107
This issue was caused by an uninitialized variable
inside the driver.  It sometimes resulted in a
junk error code returned for the "false" filter.
2018-01-13 08:08:37 +08:00
basil00 21f1e1a71e Revert WinDivert back to inline packet processing.
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.
2018-01-08 08:11:10 +08:00
basil00 fb68612176 Cleanup protocol header definitions.
Now use a single version.
Also prepare for 1.4.0-rc release.
2017-11-21 09:16:06 +08:00
basil00 dbb6b0fe60 Invert the checksum flags.
Zeroing the addr will default to full checksums.
2017-11-14 20:20:18 +08:00
basil00 80b31815b2 Implement "impostor" packets.
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.
2017-11-13 09:38:06 +08:00
basil00 aea3a3a858 Add support for pseudo IP/TCP/UDP checksums.
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.
2017-11-09 22:11:13 +08:00
basil00 bbf6a34aa6 Add Loopback and Timestamp fields to addresses.
- Loopback=1 for loopback packets, 0 otherwise.
- Timestamp is the time when packet captured.
2017-11-05 12:12:19 +08:00
basil00 9ae77eb7a5 Loopback packets are now considered outbound only
Workaround for #17
2017-11-01 20:47:45 +08:00
basil00 4c4f586f4d Add WINDIVERT_FLAG_DEBUG for WinDivertOpen() 2017-10-31 10:53:06 +08:00
basil00 d9fbc813f4 Refactor timeout logic. 2017-10-24 20:22:47 +08:00
basil00 b2fd7eb891 Bump version to 1.4 2017-10-22 21:07:06 +08:00
basil00 4ae5101d56 Reinject queued packets on WinDivertClose() 2017-10-22 09:40:50 +08:00
basil00 65f366820a Fix context access without lock. 2017-10-21 17:53:15 +08:00
basil00 4d68983d25 Ensure that the work queue length is bounded. 2017-10-20 08:17:27 +08:00
basil00 c4575b7059 Prevent block-clone-inject infinite loops.
- 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.
2017-10-18 15:47:50 +08:00
basil00 f5f3559ae9 Various improvements
- Support NonPagedPoolNx for Windows 8, 10.
- More aggressive context locking
- Set MAXWORKERS=1 (seems to perform best).
2017-10-16 22:56:38 +08:00
basil00 d778639cbe Optimizations & bug fixes.
- 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).
2017-10-13 06:47:15 +08:00
basil00 11b9a74341 Queued packets now use the PagedPool.
This is possible since IRQL=PASSIVE_LEVEL.
2017-10-11 20:44:01 +08:00
basil00 2e1bfa8ca5 WinDivert driver overhaul.
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.
2017-10-10 23:14:37 +08:00
basil00 910a2e3050 Add new WINDIVERT_PARAM_QUEUE_SIZE parameter.
Controls the number of bytes used by the packet queue.
2017-10-01 15:33:58 +08:00
basil00 e69cc09cce Update WinDivert sublayer GUIDs for version 1.3. 2017-09-24 16:24:37 +08:00
basil00 7b7d92cd26 Bump version to WinDivert 1.3.0
This prevents the old 1.2 driver from being used by new 1.3 software.

Also, clean up the driver code.
2017-09-24 15:48:38 +08:00
basil00 200da2fba1 Complete WinDivertSend() IO requests immediately.
Currently, WinDivert waits until injection completes before completing the
corresponding IO request.  However, packet injection may take an arbitrarily
long time, such as waiting for a user-mode application.

The new version completes the IO request immediately, provided the call to the
corresponding WFP packet injection function did not return an error, thus
eliminating the problem.  The disadvantage is that some packet injection
errors may no longer be detected.
2017-09-23 20:09:04 +08:00
basil00 c13a27bb4f Update CHANGELOG and VERSION 2017-09-23 16:54:58 +08:00
basil00 ea95889a30 Possible fix for issue #90. 2017-09-12 20:18:41 +08:00
Mike Neuman 504132080a Bugfix: If the user's app exits (or crashes) before calling CloseHandle()
on the WinDivert handle, the driver's cleanup function cannot make FWPM
calls. The cleanup function detects this FWPM error and returns
without ever calling the Fwps cleanup functions (which are independent
of fwpm).

As a result, the driver will not unregister the callouts, which leaves
the Windows kernel confused. You can reproduce the problem by having
a user app close uncleanly, then "sc stop windivert1.2", then try to
re-run the app. You'll get "file not found" when StartService() is called.
2017-08-15 09:32:44 -07:00
basil00 cd1bfff998 Bump copyright year. 2016-01-19 11:15:48 +08:00
basil00 657285bef6 CHANGELOG tweaks & remove old .inf file. 2015-07-26 11:06:32 +08:00
basil00 f0be301f1d Expand tests & bug fixes.
Extend the number of tests to cover some of the new features.
Fix IPv6 address comparison which did not work correctly in some cases.
2015-07-25 23:16:48 +08:00
basil00 3fcb692478 Ensure offloaded checksums are zero.
WinDivert now treats all offloaded checksum fields as zero:
- WinDivertRecv() will zero all offloaded checksum fields.
- Filter matching will treat offloaded fields as zero.
2015-07-25 12:05:23 +08:00
basil00 54f8640b89 Build & bug fixes.
- Make WinDivert compile again under WDK/MSVC.
- Fix undiscovered bug where ip.TOS (8-bit field) was passed to ntohs.
2015-07-18 16:46:21 +08:00
basil00 130e25c05b Bump copyright year. 2015-07-17 19:13:55 +08:00
basil00 fdd5825f5d Bump version to WinDivert 1.2
Bump version and change magic numbers to make the driver incompatible with
older versions.  Also cleanup some driver checksum code missed by previous
commit.
2015-07-17 18:24:30 +08:00
basil00 e247f01c43 Remove automatic checksum calculation & legacy API
- 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.
2015-07-02 21:19:27 +08:00
basil00 b452e1ce29 - Fix failing test case caused by bad word ordering. 2014-11-17 23:57:49 +08:00
basil00 bf19fdf2f9 - Add an ICMPv6 test packet.
- Fix missing byte-swaps for ICMPv6 fields.
- Todo: 1 test-case fails.
2014-11-17 19:25:17 +08:00
basil00 ecd9ae59d3 - Re-implement WinDivertHelperParseIPv6Address(). Previous version was just
too bug-prone, so re-try from scratch.  New version works for several tests.
- Fix broken WinDivertAToX().
- New test case: IPv6 TCP SYN.
2014-11-16 13:31:07 +08:00
basil00 48075e2e5f - Fix broken implementation of WinDivertHelperParseIPv6Address().
- Fix IPv6 address word/byte ordering between DLL and SYS.
2014-11-15 15:06:16 +08:00
basil00 72d83fcb07 - Fix incorrect IPv6 pseudo header definition in the driver. 2014-11-15 13:51:16 +08:00
basil00 8d98da751c - WinDivert driver now skips IPv6 extension headers when filtering packets.
- windivert_filter() now uses Ndis(Advance/Retreat)NetBufferDataStart() to
  find packet headers.
- NOTE: This new code is not yet very well tested.
2014-11-15 00:57:17 +08:00
basil00 0a70d4120d - Remove duplicate code from last commit. 2014-11-13 18:52:16 +08:00
basil00 4edd82f55f - Ignore the checksum info for loopback packets. This info seems to be
unreliable for whatever reason, so better to ignore until a better solution
  is found.
2014-11-13 18:47:46 +08:00
basil00 7235b687b3 - WinDivertHelperParsePacket() now skips IPv6 extension headers. 2014-11-10 19:16:33 +08:00
basil00 7952724127 - Driver now calculates checksums for IPv6 packets (fix issue #28).
- Bump version to 1.1.7
2014-11-09 12:44:21 +08:00
basil00 bbf06c9503 - Fix missing '\'. 2014-09-16 00:04:07 +08:00
basil00 d43aa57014 - Reduce number of work items to 2; 4 was overkill. 2014-09-15 23:48:32 +08:00
basil00 50aecbda75 - Towards version 1.1.6 2014-09-05 12:36:55 +08:00
basil00 9a13606030 - Insert WinDivert as the highest weighted sublayer. 2014-05-19 19:18:10 +08:00