From 69e4edade7634d22931c00c14eb65caf605b17b4 Mon Sep 17 00:00:00 2001 From: basil00 Date: Fri, 2 Aug 2019 08:32:50 +0800 Subject: [PATCH] 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. --- CHANGELOG | 9 +- doc/windivert.html | 13 +++ examples/netdump/netdump.c | 2 +- include/windivert.h | 1 + include/windivert_device.h | 5 +- sys/windivert.c | 173 +++++++++++++++++++++++-------------- sys/windivert.rc | 4 +- 7 files changed, 133 insertions(+), 74 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 8a03b23..e69ab72 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -297,8 +297,13 @@ WinDivert 2.0.1-rc - Rename the following functions for consistency: * WinDivertHelperNtohIpv6Address -> WinDivertHelperNtohIPv6Address * WinDivertHelperHtonIpv6Address -> WinDivertHelperHtonIPv6Address -WinDivert 2.0.2-rc +WinDivert 2.1.0-rc + - 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 WINDIVERT_LAYER_NETWORK layer. - Fix BSOD caused by packets with missing or incomplete transport headers. This bug does not affect WinDivert 1.4.*. - - Fix driver max MTU enforcement. - Fix missing Flow.EndpointId and Flow.ParentEndpointId for IPv6 flows. diff --git a/doc/windivert.html b/doc/windivert.html index d5a8ce0..3954d00 100644 --- a/doc/windivert.html +++ b/doc/windivert.html @@ -1135,6 +1135,19 @@ This flag is useful for querying the WinDivert state using a WINDIVERT_LAYER_REFLECT handle. + + +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 +WINDIVERT_LAYER_NETWORK layer, else the flag is ignored. + +

diff --git a/examples/netdump/netdump.c b/examples/netdump/netdump.c index 52fbd9e..47db9ba 100644 --- a/examples/netdump/netdump.c +++ b/examples/netdump/netdump.c @@ -102,7 +102,7 @@ int __cdecl main(int argc, char **argv) // Divert traffic matching the filter: handle = WinDivertOpen(argv[1], WINDIVERT_LAYER_NETWORK, priority, - WINDIVERT_FLAG_SNIFF); + WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_FRAGMENTS); if (handle == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_INVALID_PARAMETER && diff --git a/include/windivert.h b/include/windivert.h index 6407d76..49d6e66 100644 --- a/include/windivert.h +++ b/include/windivert.h @@ -195,6 +195,7 @@ typedef enum #define WINDIVERT_FLAG_SEND_ONLY 0x0008 #define WINDIVERT_FLAG_WRITE_ONLY WINDIVERT_FLAG_SEND_ONLY #define WINDIVERT_FLAG_NO_INSTALL 0x0010 +#define WINDIVERT_FLAG_FRAGMENTS 0x0020 /* * WinDivert parameters. diff --git a/include/windivert_device.h b/include/windivert_device.h index 70cea0f..7eec0f0 100644 --- a/include/windivert_device.h +++ b/include/windivert_device.h @@ -45,7 +45,7 @@ #include "windivert.h" #define WINDIVERT_VERSION_MAJOR 2 -#define WINDIVERT_VERSION_MINOR 0 +#define WINDIVERT_VERSION_MINOR 1 #define WINDIVERT_MAGIC_DLL 0x4C4C447669645724ull #define WINDIVERT_MAGIC_SYS 0x5359537669645723ull @@ -181,7 +181,8 @@ */ #define WINDIVERT_FLAGS_ALL \ (WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_DROP | WINDIVERT_FLAG_RECV_ONLY |\ - WINDIVERT_FLAG_SEND_ONLY | 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) \ diff --git a/sys/windivert.c b/sys/windivert.c index ed0578d..5b66bf7 100644 --- a/sys/windivert.c +++ b/sys/windivert.c @@ -63,35 +63,12 @@ EVT_WDF_WORKITEM windivert_reflect_worker; * Debugging macros. */ // #define DEBUG_ON -#define DEBUG_BUFSIZE 256 - #ifdef DEBUG_ON -static void DEBUG(PCCH format, ...) -{ - va_list args; - char buf[DEBUG_BUFSIZE+1]; - if (KeGetCurrentIrql() != PASSIVE_LEVEL) - { - return; - } - va_start(args, format); - RtlStringCbVPrintfA(buf, DEBUG_BUFSIZE, format, args); - DbgPrint("WINDIVERT: %s\n", buf); - va_end(args); -} -static void DEBUG_ERROR(PCCH format, NTSTATUS status, ...) -{ - va_list args; - char buf[DEBUG_BUFSIZE+1]; - if (KeGetCurrentIrql() != PASSIVE_LEVEL) - { - return; - } - va_start(args, status); - RtlStringCbVPrintfA(buf, DEBUG_BUFSIZE, format, args); - DbgPrint("WINDIVERT: *** ERROR ***: (status = %x): %s\n", status, buf); - va_end(args); -} +#define DEBUG(format, ...) \ + DbgPrint("WINDIVERT: " format "\n", ##__VA_ARGS__) +#define DEBUG_ERROR(format, status, ...) \ + DbgPrint("WINDIVERT: *** ERROR ***: (status = 0x%x): " format "\n", \ + (status), ##__VA_ARGS__) static void DEBUG_BOUNDS_CHECK(PVOID start, PVOID end, PVOID access_start, PVOID access_end) { @@ -478,7 +455,7 @@ static void windivert_socket_classify(context_t context, BOOL outbound, BOOL loopback, FWPS_CLASSIFY_OUT0 *result); static void windivert_network_classify(context_t context, IN PWINDIVERT_DATA_NETWORK network_data, IN BOOL ipv4, IN BOOL outbound, - IN BOOL loopback, IN UINT advance, IN OUT void *data, + IN BOOL loopback, IN BOOL reassembled, IN UINT advance, IN OUT void *data, OUT FWPS_CLASSIFY_OUT0 *result); static BOOL windivert_queue_work(context_t context, PVOID packet, ULONG packet_len, PNET_BUFFER_LIST buffers, PVOID object, @@ -494,14 +471,14 @@ static BOOL windivert_copy_data(PNET_BUFFER buffer, PVOID data, UINT size); static BOOL windivert_lookup_data(PNET_BUFFER buffer, UINT offset, INT idx, PVOID data, UINT size); static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4, - PWINDIVERT_IPHDR *ip_header_ptr, PWINDIVERT_IPV6HDR *ipv6_header_ptr, - PWINDIVERT_ICMPHDR *icmp_header_ptr, - PWINDIVERT_ICMPV6HDR *icmpv6_header_ptr, - PWINDIVERT_TCPHDR *tcp_header_ptr, PWINDIVERT_UDPHDR *udp_header_ptr, - UINT8 *proto_ptr, UINT *header_len_ptr, UINT *payload_len_ptr); + BOOL frag_mode, PWINDIVERT_IPHDR *ip_header_ptr, + PWINDIVERT_IPV6HDR *ipv6_header_ptr, PWINDIVERT_ICMPHDR *icmp_header_ptr, + PWINDIVERT_ICMPV6HDR *icmpv6_header_ptr, PWINDIVERT_TCPHDR *tcp_header_ptr, + PWINDIVERT_UDPHDR *udp_header_ptr, UINT8 *proto_ptr, UINT *header_len_ptr, + UINT *payload_len_ptr); static BOOL windivert_filter(PNET_BUFFER buffer, WINDIVERT_LAYER layer, const VOID *layer_data, LONGLONG timestamp, WINDIVERT_EVENT event, - BOOL ipv4, BOOL outbound, BOOL loopback, BOOL impostor, + BOOL ipv4, BOOL outbound, BOOL loopback, BOOL impostor, BOOL frag_mode, const WINDIVERT_FILTER *filter); static const WINDIVERT_FILTER *windivert_filter_compile( const WINDIVERT_FILTER *ioctl_filter, size_t ioctl_filter_len, @@ -3456,7 +3433,8 @@ static void windivert_outbound_network_v4_classify( FWP_CONDITION_FLAG_IS_LOOPBACK) != 0); windivert_network_classify(context, &network_data, /*ipv4=*/TRUE, - /*outbound=*/TRUE, loopback, /*advance=*/0, data, result); + /*outbound=*/TRUE, loopback, /*reassembled=*/FALSE, /*advance=*/0, + data, result); } /* @@ -3490,7 +3468,8 @@ static void windivert_outbound_network_v6_classify( FWP_CONDITION_FLAG_IS_LOOPBACK) != 0); windivert_network_classify(context, &network_data, /*ipv4=*/FALSE, - /*outbound=*/TRUE, loopback, /*advance=*/0, data, result); + /*outbound=*/TRUE, loopback, /*reassembled=*/FALSE, /*advance=*/0, + data, result); } /* @@ -3504,7 +3483,8 @@ static void windivert_inbound_network_v4_classify( { WINDIVERT_DATA_NETWORK network_data; UINT advance; - BOOL loopback; + UINT32 flags; + BOOL fragment, loopback, reassembled; context_t context = (context_t)(ULONG_PTR)filter->context; UNREFERENCED_PARAMETER(data); @@ -3515,14 +3495,21 @@ static void windivert_inbound_network_v4_classify( return; } - loopback = ((windivert_get_val32(fixed_vals, - FWPS_FIELD_INBOUND_IPPACKET_V4_FLAGS) & - FWP_CONDITION_FLAG_IS_LOOPBACK) != 0); + flags = windivert_get_val32(fixed_vals, + FWPS_FIELD_INBOUND_IPPACKET_V4_FLAGS); + fragment = ((flags & FWP_CONDITION_FLAG_IS_FRAGMENT) != 0); + if (fragment) + { + result->actionType = FWP_ACTION_CONTINUE; + return; + } + loopback = ((flags & FWP_CONDITION_FLAG_IS_LOOPBACK) != 0); if (loopback) { result->actionType = FWP_ACTION_CONTINUE; return; } + reassembled = ((flags & FWP_CONDITION_FLAG_IS_REASSEMBLED) != 0); network_data.IfIdx = windivert_get_val32(fixed_vals, FWPS_FIELD_INBOUND_IPPACKET_V4_INTERFACE_INDEX); @@ -3531,7 +3518,7 @@ static void windivert_inbound_network_v4_classify( advance = meta_vals->ipHeaderSize; windivert_network_classify(context, &network_data, /*ipv4=*/TRUE, - /*outbound=*/FALSE, loopback, advance, data, result); + /*outbound=*/FALSE, loopback, reassembled, advance, data, result); } /* @@ -3545,7 +3532,8 @@ static void windivert_inbound_network_v6_classify( { WINDIVERT_DATA_NETWORK network_data; UINT advance; - BOOL loopback; + UINT32 flags; + BOOL fragment, loopback, reassembled; context_t context = (context_t)(ULONG_PTR)filter->context; UNREFERENCED_PARAMETER(data); @@ -3556,14 +3544,21 @@ static void windivert_inbound_network_v6_classify( return; } - loopback = ((windivert_get_val32(fixed_vals, - FWPS_FIELD_INBOUND_IPPACKET_V6_FLAGS) & - FWP_CONDITION_FLAG_IS_LOOPBACK) != 0); + flags = windivert_get_val32(fixed_vals, + FWPS_FIELD_INBOUND_IPPACKET_V6_FLAGS); + fragment = ((flags & FWP_CONDITION_FLAG_IS_FRAGMENT) != 0); + if (fragment) + { + result->actionType = FWP_ACTION_CONTINUE; + return; + } + loopback = ((flags & FWP_CONDITION_FLAG_IS_LOOPBACK) != 0); if (loopback) { result->actionType = FWP_ACTION_CONTINUE; return; } + reassembled = ((flags & FWP_CONDITION_FLAG_IS_REASSEMBLED) != 0); network_data.IfIdx = windivert_get_val32(fixed_vals, FWPS_FIELD_INBOUND_IPPACKET_V6_INTERFACE_INDEX); @@ -3572,7 +3567,7 @@ static void windivert_inbound_network_v6_classify( advance = meta_vals->ipHeaderSize; windivert_network_classify(context, &network_data, /*ipv4=*/FALSE, - /*outbound=*/FALSE, loopback, advance, data, result); + /*outbound=*/FALSE, loopback, reassembled, advance, data, result); } /* @@ -3585,6 +3580,8 @@ static void windivert_forward_network_v4_classify( OUT FWPS_CLASSIFY_OUT0 *result) { WINDIVERT_DATA_NETWORK network_data; + UINT32 flags; + BOOL group; context_t context = (context_t)(ULONG_PTR)filter->context; UNREFERENCED_PARAMETER(meta_vals); @@ -3595,13 +3592,21 @@ static void windivert_forward_network_v4_classify( { return; } + flags = windivert_get_val32(fixed_vals, FWPS_FIELD_IPFORWARD_V4_FLAGS); + group = ((flags & FWP_CONDITION_FLAG_IS_FRAGMENT_GROUP) != 0); + if (group) + { + result->actionType = FWP_ACTION_CONTINUE; + return; + } network_data.IfIdx = windivert_get_val32(fixed_vals, FWPS_FIELD_IPFORWARD_V4_DESTINATION_INTERFACE_INDEX); network_data.SubIfIdx = 0; windivert_network_classify(context, &network_data, /*ipv4=*/TRUE, - /*outbound=*/TRUE, /*loopback=*/FALSE, /*advance=*/0, data, result); + /*outbound=*/TRUE, /*loopback=*/FALSE, /*reassembled=*/FALSE, + /*advance=*/0, data, result); } /* @@ -3614,6 +3619,8 @@ static void windivert_forward_network_v6_classify( OUT FWPS_CLASSIFY_OUT0 *result) { WINDIVERT_DATA_NETWORK network_data; + UINT32 flags; + BOOL group; context_t context = (context_t)(ULONG_PTR)filter->context; UNREFERENCED_PARAMETER(meta_vals); @@ -3624,13 +3631,21 @@ static void windivert_forward_network_v6_classify( { return; } + flags = windivert_get_val32(fixed_vals, FWPS_FIELD_IPFORWARD_V6_FLAGS); + group = ((flags & FWP_CONDITION_FLAG_IS_FRAGMENT_GROUP) != 0); + if (group) + { + result->actionType = FWP_ACTION_CONTINUE; + return; + } network_data.IfIdx = windivert_get_val32(fixed_vals, FWPS_FIELD_IPFORWARD_V6_DESTINATION_INTERFACE_INDEX); network_data.SubIfIdx = 0; windivert_network_classify(context, &network_data, /*ipv4=*/FALSE, - /*outbound=*/TRUE, /*loopback=*/FALSE, /*advance=*/0, data, result); + /*outbound=*/TRUE, /*loopback=*/FALSE, /*reassembled=*/FALSE, + /*advance=*/0, data, result); } /* @@ -3638,7 +3653,7 @@ static void windivert_forward_network_v6_classify( */ static void windivert_network_classify(context_t context, IN PWINDIVERT_DATA_NETWORK network_data, IN BOOL ipv4, IN BOOL outbound, - IN BOOL loopback, IN UINT advance, IN OUT void *data, + IN BOOL loopback, IN BOOL reassembled, IN UINT advance, IN OUT void *data, OUT FWPS_CLASSIFY_OUT0 *result) { KLOCK_QUEUE_HANDLE lock_handle; @@ -3649,7 +3664,7 @@ static void windivert_network_classify(context_t context, WINDIVERT_LAYER layer; PNET_BUFFER_LIST buffers; PNET_BUFFER buffer, buffer_fst, buffer_itr; - BOOL impostor, sniff_mode, ok; + BOOL impostor, sniff_mode, frag_mode, ok; WDFOBJECT object; const WINDIVERT_FILTER *filter; LONGLONG timestamp; @@ -3712,6 +3727,16 @@ static void windivert_network_classify(context_t context, // Get the timestamp. timestamp = KeQueryPerformanceCounter(NULL).QuadPart; + // Filter fragments or reassembled packets. + frag_mode = + (outbound || layer == WINDIVERT_LAYER_NETWORK_FORWARD? TRUE: + (flags & WINDIVERT_FLAG_FRAGMENTS) != 0); + if (frag_mode && reassembled) + { + WdfObjectDereference(object); + return; + } + // Retreat the NET_BUFFER to the IP header, if necessary. // If (advance != 0) then this must be in the inbound path, and the // NET_BUFFER_LIST must contain exactly one NET_BUFFER. @@ -3741,7 +3766,7 @@ static void windivert_network_classify(context_t context, { BOOL match = windivert_filter(buffer_fst, layer, (PVOID)network_data, timestamp, /*event=*/WINDIVERT_EVENT_NETWORK_PACKET, ipv4, - outbound, loopback, impostor, filter); + outbound, loopback, impostor, frag_mode, filter); if (match) { break; @@ -3806,7 +3831,7 @@ static void windivert_network_classify(context_t context, { BOOL match = windivert_filter(buffer_itr, layer, (PVOID)network_data, timestamp, /*event=*/WINDIVERT_EVENT_NETWORK_PACKET, ipv4, - outbound, loopback, impostor, filter); + outbound, loopback, impostor, frag_mode, filter); ok = windivert_queue_work(context, (PVOID)buffer_itr, NET_BUFFER_DATA_LENGTH(buffer_itr), buffers, /*object=*/NULL, layer, (PVOID)network_data, /*event=*/WINDIVERT_EVENT_NETWORK_PACKET, @@ -3972,7 +3997,7 @@ static void windivert_flow_established_classify(context_t context, match = windivert_filter(/*buffer=*/NULL, /*layer=*/WINDIVERT_LAYER_FLOW, (PVOID)flow_data, timestamp, /*event=*/WINDIVERT_EVENT_FLOW_ESTABLISHED, ipv4, outbound, loopback, - /*impostor=*/FALSE, filter); + /*impostor=*/FALSE, /*frag_mode=*/FALSE, filter); if (match) { ok = windivert_queue_work(context, /*packet=*/NULL, /*packet_len=*/0, @@ -4096,7 +4121,7 @@ static void windivert_flow_delete_notify(UINT16 layer_id, UINT32 callout_id, match = windivert_filter(/*buffer=*/NULL, /*layer=*/WINDIVERT_LAYER_FLOW, (PVOID)&flow->data, timestamp, /*event=*/WINDIVERT_EVENT_FLOW_DELETED, !flow->ipv6, flow->outbound, flow->loopback, /*impostor=*/FALSE, - filter); + /*frag_mode=*/FALSE, filter); if (match) { (VOID)windivert_queue_work(context, /*packet=*/NULL, /*packet_len=*/0, @@ -4688,7 +4713,7 @@ static void windivert_socket_classify(context_t context, match = windivert_filter(/*buffer=*/NULL, /*layer=*/WINDIVERT_LAYER_SOCKET, (PVOID)socket_data, timestamp, event, ipv4, outbound, loopback, - /*impostor=*/FALSE, filter); + /*impostor=*/FALSE, /*frag_mode=*/FALSE, filter); if (match) { ok = windivert_queue_work(context, /*packet=*/NULL, /*packet_len=*/0, @@ -5258,11 +5283,11 @@ static BOOL windivert_lookup_data(PNET_BUFFER buffer, UINT offset, INT idx, * Parse packet headers. */ static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4, - PWINDIVERT_IPHDR *ip_header_ptr, PWINDIVERT_IPV6HDR *ipv6_header_ptr, - PWINDIVERT_ICMPHDR *icmp_header_ptr, - PWINDIVERT_ICMPV6HDR *icmpv6_header_ptr, - PWINDIVERT_TCPHDR *tcp_header_ptr, PWINDIVERT_UDPHDR *udp_header_ptr, - UINT8 *proto_ptr, UINT *header_len_ptr, UINT *payload_len_ptr) + BOOL frag_mode, PWINDIVERT_IPHDR *ip_header_ptr, + PWINDIVERT_IPV6HDR *ipv6_header_ptr, PWINDIVERT_ICMPHDR *icmp_header_ptr, + PWINDIVERT_ICMPV6HDR *icmpv6_header_ptr, PWINDIVERT_TCPHDR *tcp_header_ptr, + PWINDIVERT_UDPHDR *udp_header_ptr, UINT8 *proto_ptr, UINT *header_len_ptr, + UINT *payload_len_ptr) { UINT tot_len, ip_header_len; PWINDIVERT_IPHDR ip_header = NULL; @@ -5313,6 +5338,13 @@ static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4, DEBUG("FILTER: REJECT (bad IPv4 packet)"); return FALSE; } + if (!frag_mode && + (WINDIVERT_IPHDR_GET_MF(ip_header) != 0 || + WINDIVERT_IPHDR_GET_FRAGOFF(ip_header) != 0)) + { + DEBUG("FILTER: REJECT (fragment)"); + return FALSE; + } proto = ip_header->Protocol; NdisAdvanceNetBufferDataStart(buffer, ip_header_len, FALSE, NULL); } @@ -5360,6 +5392,11 @@ static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4, switch (proto) { case IPPROTO_FRAGMENT: + if (!frag_mode) + { + DEBUG("FILTER: REJECT (fragment)"); + return FALSE; + } ext_header_len = 8; break; case IPPROTO_AH: @@ -5444,7 +5481,7 @@ static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4, */ static BOOL windivert_filter(PNET_BUFFER buffer, WINDIVERT_LAYER layer, const VOID *layer_data, LONGLONG timestamp, WINDIVERT_EVENT event, - BOOL ipv4, BOOL outbound, BOOL loopback, BOOL impostor, + BOOL ipv4, BOOL outbound, BOOL loopback, BOOL impostor, BOOL frag_mode, const WINDIVERT_FILTER *filter) { PWINDIVERT_IPHDR ip_header = NULL; @@ -5469,9 +5506,9 @@ static BOOL windivert_filter(PNET_BUFFER buffer, WINDIVERT_LAYER layer, { case WINDIVERT_LAYER_NETWORK: case WINDIVERT_LAYER_NETWORK_FORWARD: - if (!windivert_parse_headers(buffer, ipv4, &ip_header, &ipv6_header, - &icmp_header, &icmpv6_header, &tcp_header, &udp_header, - &protocol, &header_len, &payload_len)) + if (!windivert_parse_headers(buffer, ipv4, frag_mode, &ip_header, + &ipv6_header, &icmp_header, &icmpv6_header, &tcp_header, + &udp_header, &protocol, &header_len, &payload_len)) { return FALSE; } @@ -6763,7 +6800,8 @@ static void windivert_reflect_event_notify(context_t context, match = windivert_filter(/*buffer=*/NULL, /*layer=*/WINDIVERT_LAYER_REFLECT, (PVOID)&context->reflect.data, timestamp, event, /*ipv4=*/TRUE, /*outbound=*/FALSE, - /*loopback=*/FALSE, /*impostor=*/FALSE, filter); + /*loopback=*/FALSE, /*impostor=*/FALSE, /*frag_mode=*/FALSE, + filter); if (!match) { continue; @@ -6813,7 +6851,8 @@ static void windivert_reflect_established_notify(context_t context, match = windivert_filter(/*buffer=*/NULL, /*layer=*/WINDIVERT_LAYER_REFLECT, (PVOID)&waiter->reflect.data, timestamp, /*event=*/WINDIVERT_EVENT_REFLECT_OPEN, /*ipv4=*/TRUE, - /*outbound=*/FALSE, /*loopback=*/FALSE, /*impostor=*/FALSE, filter); + /*outbound=*/FALSE, /*loopback=*/FALSE, /*impostor=*/FALSE, + /*frag_mode=*/FALSE, filter); if (!match) { continue; diff --git a/sys/windivert.rc b/sys/windivert.rc index 57fa09f..ea1820e 100644 --- a/sys/windivert.rc +++ b/sys/windivert.rc @@ -43,8 +43,8 @@ "[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.1 +#define VER_PRODUCTVERSION_STR "2.1" #define VER_COMPANYNAME_STR "Basil" #define VER_LEGALCOPYRIGHT_YEARS "2011-2019" #define VER_LEGALCOPYRIGHT_STR \