Add Loopback and Timestamp fields to addresses.
- Loopback=1 for loopback packets, 0 otherwise. - Timestamp is the time when packet captured.
This commit is contained in:
@@ -93,3 +93,10 @@ WinDivert 1.4.0-rc
|
||||
- Internally queued packets are now reinjected on WinDivertClose().
|
||||
- WinDivertRecv() will eventually fail with ERROR_HOST_UNREACHABLE
|
||||
if a packet loops indefinitely between WinDivert and another driver.
|
||||
- WINDIVERT_ADDRESS now includes a Timestamp field that indicates when
|
||||
the packet was first captured by WinDivert. The timestamp uses the
|
||||
same clock as QueryPerformanceCounter().
|
||||
- WINDIVERT_ADDRESS now includes a Loopback field that indicates whether
|
||||
the packet is a loopback packet or not.
|
||||
- The filter language has been extended to include a loopback field that
|
||||
matches loopback packets.
|
||||
|
||||
+11
-1
@@ -98,6 +98,7 @@ typedef enum
|
||||
TOKEN_OUTBOUND,
|
||||
TOKEN_IF_IDX,
|
||||
TOKEN_SUB_IF_IDX,
|
||||
TOKEN_LOOPBACK,
|
||||
TOKEN_OPEN,
|
||||
TOKEN_CLOSE,
|
||||
TOKEN_EQ,
|
||||
@@ -824,6 +825,7 @@ static ERROR WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer,
|
||||
{"ipv6.NextHdr", TOKEN_IPV6_NEXT_HDR},
|
||||
{"ipv6.SrcAddr", TOKEN_IPV6_SRC_ADDR},
|
||||
{"ipv6.TrafficClass", TOKEN_IPV6_TRAFFIC_CLASS},
|
||||
{"loopback", TOKEN_LOOPBACK},
|
||||
{"not", TOKEN_NOT},
|
||||
{"or", TOKEN_OR},
|
||||
{"outbound", TOKEN_OUTBOUND},
|
||||
@@ -1132,7 +1134,8 @@ static PEXPR WinDivertMakeVar(PPOOL pool, KIND kind)
|
||||
{{{0}}, TOKEN_INBOUND},
|
||||
{{{0}}, TOKEN_OUTBOUND},
|
||||
{{{0}}, TOKEN_IF_IDX},
|
||||
{{{0}}, TOKEN_SUB_IF_IDX}
|
||||
{{{0}}, TOKEN_SUB_IF_IDX},
|
||||
{{{0}}, TOKEN_LOOPBACK}
|
||||
};
|
||||
|
||||
// Binary search:
|
||||
@@ -1252,6 +1255,7 @@ static PEXPR WinDivertParseTest(PPOOL pool, TOKEN *toks, UINT *i)
|
||||
case TOKEN_INBOUND:
|
||||
case TOKEN_IF_IDX:
|
||||
case TOKEN_SUB_IF_IDX:
|
||||
case TOKEN_LOOPBACK:
|
||||
case TOKEN_IP:
|
||||
case TOKEN_IPV6:
|
||||
case TOKEN_ICMP:
|
||||
@@ -1719,6 +1723,9 @@ static void WinDivertEmitTest(PEXPR test, UINT16 offset,
|
||||
case TOKEN_SUB_IF_IDX:
|
||||
object->field = WINDIVERT_FILTER_FIELD_SUBIFIDX;
|
||||
break;
|
||||
case TOKEN_LOOPBACK:
|
||||
object->field = WINDIVERT_FILTER_FIELD_LOOPBACK;
|
||||
break;
|
||||
case TOKEN_IP:
|
||||
object->field = WINDIVERT_FILTER_FIELD_IP;
|
||||
break;
|
||||
@@ -2243,6 +2250,9 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter,
|
||||
case WINDIVERT_FILTER_FIELD_SUBIFIDX:
|
||||
val[0] = addr->SubIfIdx;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_LOOPBACK:
|
||||
val[0] = addr->Loopback;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_IP:
|
||||
val[0] = (iphdr != NULL);
|
||||
break;
|
||||
|
||||
+13
-14
@@ -311,9 +311,11 @@ library.</li>
|
||||
<pre>
|
||||
typedef struct
|
||||
{
|
||||
INT64 Timestamp;
|
||||
UINT32 IfIdx;
|
||||
UINT32 SubIfIdx;
|
||||
UINT8 Direction;
|
||||
UINT8 Direction:1;
|
||||
UINT8 Loopback:1;
|
||||
} <b>WINDIVERT_ADDRESS</b>, *<b>PWINDIVERT_ADDRESS</b>;
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
@@ -321,6 +323,11 @@ typedef struct
|
||||
<p>
|
||||
<b>Fields</b>
|
||||
<ul>
|
||||
<li> <tt>Timestamp</tt>: A timestamp indicating when WinDivert first captured
|
||||
the packet.
|
||||
Uses the same clock as <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx"><tt>QueryPerformanceCounter()</tt></a>.
|
||||
This value is ignored by <a href="#divert_send"><tt>WinDivertSend()</tt></a>.
|
||||
</li>
|
||||
<li> <tt>IfIdx</tt>: The interface index on which the packet arrived
|
||||
(for inbound packets), or is to be sent (for outbound packets).</li>
|
||||
<li> <tt>SubIfIdx</tt>: The sub-interface index for <tt>IfIdx</tt>.</li>
|
||||
@@ -332,6 +339,8 @@ packets.</li>
|
||||
<li> <tt>WINDIVERT_DIRECTION_INBOUND</tt> with value 1 for <i>inbound</i>
|
||||
packets.</li>
|
||||
</ul></li>
|
||||
<li> <tt>Loopback</tt>: Set to <tt>1</tt> for loopback packets, <tt>0</tt>
|
||||
otherwise</li>
|
||||
</ul>
|
||||
</p><p>
|
||||
<b>Remarks</b><br>
|
||||
@@ -1508,6 +1517,7 @@ The possible fields are:
|
||||
<tr><td><tt>inbound</tt></td><td>Is inbound? (only valid for <tt>WINDIVERT_LAYER_NETWORK</tt>)</td></tr>
|
||||
<tr><td><tt>ifIdx</tt></td><td>Interface index</td></tr>
|
||||
<tr><td><tt>subIfIdx</tt></td><td>Sub-interface index</td></tr>
|
||||
<tr><td><tt>loopback</tt></td><td>Is loopback packet?</td></tr>
|
||||
<tr><td><tt>ip</tt></td><td>Is IPv4?</td></tr>
|
||||
<tr><td><tt>ipv6</tt></td><td>Is IPv6?</td></tr>
|
||||
<tr><td><tt>icmp</tt></td><td>Is ICMP?</td></tr>
|
||||
@@ -1535,10 +1545,10 @@ contain a TCP header.
|
||||
<p>
|
||||
<ol>
|
||||
<li>
|
||||
Divert all outbound web traffic:
|
||||
Divert all outbound (non-local) web traffic:
|
||||
<pre>
|
||||
HANDLE handle = WinDivertOpen(
|
||||
"outbound and "
|
||||
"outbound and !loopback and "
|
||||
"(tcp.DstPort == 80 or udp.DstPort == 53)",
|
||||
0, 0, 0
|
||||
);
|
||||
@@ -1555,17 +1565,6 @@ HANDLE handle = WinDivertOpen(
|
||||
</pre>
|
||||
</li>
|
||||
<li>
|
||||
Divert only (inbound) local traffic:
|
||||
<pre>
|
||||
HANDLE handle = WinDivertOpen(
|
||||
"inbound and ("
|
||||
"(ip.DstAddr >= 127.0.0.1 and ip.DstAddr <= 127.255.255.255) or"
|
||||
"ipv6.DstAddr == ::1)",
|
||||
0, 0, 0
|
||||
);
|
||||
</pre>
|
||||
</li>
|
||||
<li>
|
||||
Divert all traffic:
|
||||
<pre>
|
||||
HANDLE handle = WinDivertOpen("true", 0, 0, 0);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* netdump.c
|
||||
* (C) 2016, all rights reserved,
|
||||
* (C) 2017, all rights reserved,
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@@ -53,6 +53,8 @@ int __cdecl main(int argc, char **argv)
|
||||
PWINDIVERT_TCPHDR tcp_header;
|
||||
PWINDIVERT_UDPHDR udp_header;
|
||||
const char *err_str;
|
||||
LARGE_INTEGER base, freq;
|
||||
double time_passed;
|
||||
|
||||
// Check arguments.
|
||||
switch (argc)
|
||||
@@ -107,6 +109,10 @@ int __cdecl main(int argc, char **argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Set up timing:
|
||||
QueryPerformanceFrequency(&freq);
|
||||
QueryPerformanceCounter(&base);
|
||||
|
||||
// Main loop:
|
||||
while (TRUE)
|
||||
{
|
||||
@@ -134,8 +140,13 @@ int __cdecl main(int argc, char **argv)
|
||||
// Dump packet info:
|
||||
putchar('\n');
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED);
|
||||
printf("Packet [Direction=%u IfIdx=%u SubIfIdx=%u]\n",
|
||||
addr.Direction, addr.IfIdx, addr.SubIfIdx);
|
||||
time_passed = (double)(addr.Timestamp - base.QuadPart) /
|
||||
(double)freq.QuadPart;
|
||||
printf("Packet [Timestamp=%.8g, Direction=%s IfIdx=%u SubIfIdx=%u "
|
||||
"Loopback=%u]\n",
|
||||
time_passed, (addr.Direction == WINDIVERT_DIRECTION_OUTBOUND?
|
||||
"outbound": "inbound"), addr.IfIdx, addr.SubIfIdx,
|
||||
addr.Loopback);
|
||||
if (ip_header != NULL)
|
||||
{
|
||||
UINT8 *src_addr = (UINT8 *)&ip_header->SrcAddr;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* webfilter.c
|
||||
* (C) 2016, all rights reserved,
|
||||
* (C) 2017, all rights reserved,
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@@ -160,6 +160,7 @@ int __cdecl main(int argc, char **argv)
|
||||
// Open the Divert device:
|
||||
handle = WinDivertOpen(
|
||||
"outbound && " // Outbound traffic only
|
||||
"!loopback && " // No loopback traffic
|
||||
"ip && " // Only IPv4 supported
|
||||
"tcp.DstPort == 80 && " // HTTP (port 80) only
|
||||
"tcp.PayloadLength > 0", // TCP data packets only
|
||||
|
||||
+5
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* windivert.h
|
||||
* (C) 2016, all rights reserved,
|
||||
* (C) 2017, all rights reserved,
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@@ -57,9 +57,12 @@ extern "C" {
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
INT64 Timestamp; /* Packet's timestamp. */
|
||||
UINT32 IfIdx; /* Packet's interface index. */
|
||||
UINT32 SubIfIdx; /* Packet's sub-interface index. */
|
||||
UINT8 Direction; /* Packet's direction. */
|
||||
UINT8 Direction:1; /* Packet's direction. */
|
||||
UINT8 Loopback:1; /* Packet is loopback? */
|
||||
UINT8 Reserved:6;
|
||||
} WINDIVERT_ADDRESS, *PWINDIVERT_ADDRESS;
|
||||
|
||||
#define WINDIVERT_DIRECTION_OUTBOUND 0
|
||||
|
||||
@@ -104,8 +104,9 @@
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_LENGTH 55
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_CHECKSUM 56
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH 57
|
||||
#define WINDIVERT_FILTER_FIELD_LOOPBACK 58
|
||||
#define WINDIVERT_FILTER_FIELD_MAX \
|
||||
WINDIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH
|
||||
WINDIVERT_FILTER_FIELD_LOOPBACK
|
||||
|
||||
#define WINDIVERT_FILTER_TEST_EQ 0
|
||||
#define WINDIVERT_FILTER_TEST_NEQ 1
|
||||
|
||||
+46
-30
@@ -186,7 +186,7 @@ typedef struct layer_s *layer_t;
|
||||
*/
|
||||
struct req_context_s
|
||||
{
|
||||
struct windivert_addr_s *addr; // Pointer to address structure.
|
||||
PWINDIVERT_ADDRESS addr; // Pointer to address structure.
|
||||
};
|
||||
typedef struct req_context_s req_context_s;
|
||||
typedef struct req_context_s *req_context_t;
|
||||
@@ -202,8 +202,9 @@ struct work_s
|
||||
PNET_BUFFER_LIST buffers; // Packet list.
|
||||
PNET_BUFFER buffer; // First matching packet.
|
||||
UINT advance; // Bytes to retreat/advance.
|
||||
BOOL is_ipv4; // Is IPv4?
|
||||
BOOL hop; // Decrement TTL?
|
||||
BOOL is_ipv4:1; // Is IPv4?
|
||||
BOOL hop:1; // Decrement TTL?
|
||||
BOOL loopback:1; // Is loopback?
|
||||
UINT8 checksums; // Which checksums are valid.
|
||||
UINT8 direction; // Packet direction.
|
||||
UINT32 if_idx; // Interface index.
|
||||
@@ -226,8 +227,9 @@ struct packet_s
|
||||
LIST_ENTRY entry; // Entry for queue.
|
||||
UINT8 checksums; // Which checksums are valid.
|
||||
UINT8 direction; // Packet direction.
|
||||
BOOL is_ipv4; // Is IPv4?
|
||||
BOOL hop; // Decrement TTL?
|
||||
BOOL is_ipv4:1; // Is IPv4?
|
||||
BOOL hop:1; // Decrement TTL?
|
||||
BOOL loopback:1; // Is loopback?
|
||||
UINT32 if_idx; // Interface index.
|
||||
UINT32 sub_if_idx; // Sub-interface index.
|
||||
LONGLONG timestamp; // Packet timestamp.
|
||||
@@ -236,6 +238,7 @@ struct packet_s
|
||||
};
|
||||
typedef struct packet_s *packet_t;
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* WinDivert address definition.
|
||||
*/
|
||||
@@ -246,6 +249,7 @@ struct windivert_addr_s
|
||||
UINT8 Direction;
|
||||
};
|
||||
typedef struct windivert_addr_s *windivert_addr_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Header definitions.
|
||||
@@ -382,7 +386,7 @@ extern VOID windivert_cleanup(IN WDFFILEOBJECT object);
|
||||
extern VOID windivert_close(IN WDFFILEOBJECT object);
|
||||
extern VOID windivert_destroy(IN WDFOBJECT object);
|
||||
extern NTSTATUS windivert_write(context_t context, WDFREQUEST request,
|
||||
windivert_addr_t addr);
|
||||
PWINDIVERT_ADDRESS addr);
|
||||
extern void NTAPI windivert_inject_complete(VOID *context,
|
||||
NET_BUFFER_LIST *packets, BOOLEAN dispatch_level);
|
||||
static NTSTATUS windivert_notify_callout(IN FWPS_CALLOUT_NOTIFY_TYPE type,
|
||||
@@ -423,7 +427,7 @@ static void windivert_classify_callout(context_t context, IN UINT8 direction,
|
||||
IN UINT64 flow_context, OUT FWPS_CLASSIFY_OUT0 *result);
|
||||
static BOOL windivert_queue_packet(context_t context, PNET_BUFFER buffer,
|
||||
UINT8 direction, UINT32 if_idx, UINT32 sub_if_idx, BOOL is_ipv4, BOOL hop,
|
||||
UINT8 checksums, LONGLONG timestamp);
|
||||
BOOL loopback, UINT8 checksums, LONGLONG timestamp);
|
||||
static BOOL windivert_reinject_packet(BOOL sniff_mode, BOOL foward,
|
||||
UINT8 direction, BOOL isipv4, UINT32 if_idx, UINT32 sub_if_idx,
|
||||
UINT32 priority, PNET_BUFFER_LIST buffers, PNET_BUFFER buffer,
|
||||
@@ -436,8 +440,8 @@ static void windivert_free_packet(packet_t packet);
|
||||
static UINT8 windivert_skip_headers(UINT8 proto, UINT8 **header, size_t *len);
|
||||
static int windivert_big_num_compare(const UINT32 *a, const UINT32 *b);
|
||||
static BOOL windivert_filter(PNET_BUFFER buffer, UINT32 if_idx,
|
||||
UINT32 sub_if_idx, BOOL outbound, BOOL isipv4, BOOL hop, UINT8 checksums,
|
||||
filter_t filter);
|
||||
UINT32 sub_if_idx, BOOL outbound, BOOL isipv4, BOOL hop, BOOL loopback,
|
||||
UINT8 checksums, filter_t filter);
|
||||
static NTSTATUS windivert_finalize_packet(void *header, size_t len,
|
||||
BOOL hop, UINT8 checksums);
|
||||
static filter_t windivert_filter_compile(windivert_ioctl_filter_t ioctl_filter,
|
||||
@@ -1481,14 +1485,15 @@ static NTSTATUS windivert_read(context_t context, WDFREQUEST request)
|
||||
*/
|
||||
static void windivert_read_service_request(packet_t packet,
|
||||
PNET_BUFFER buffer, UINT8 direction, UINT32 if_idx, UINT32 sub_if_idx,
|
||||
BOOL hop, UINT8 checksums, WDFREQUEST request)
|
||||
BOOL hop, BOOL loopback, LONGLONG timestamp, UINT8 checksums,
|
||||
WDFREQUEST request)
|
||||
{
|
||||
PMDL dst_mdl;
|
||||
PVOID dst, src;
|
||||
ULONG dst_len, src_len;
|
||||
NTSTATUS status;
|
||||
req_context_t req_context;
|
||||
windivert_addr_t addr;
|
||||
PWINDIVERT_ADDRESS addr;
|
||||
|
||||
DEBUG("SERVICE: servicing read request (request=%p)", request);
|
||||
|
||||
@@ -1534,9 +1539,12 @@ static void windivert_read_service_request(packet_t packet,
|
||||
addr = req_context->addr;
|
||||
if (addr != NULL)
|
||||
{
|
||||
addr->Timestamp = (INT64)timestamp;
|
||||
addr->IfIdx = if_idx;
|
||||
addr->SubIfIdx = sub_if_idx;
|
||||
addr->Direction = direction;
|
||||
addr->Loopback = (loopback? 1: 0);
|
||||
addr->Reserved = 0;
|
||||
}
|
||||
|
||||
// Zero the IP/TCP/UDP checksums and/or decrement the TTL (if required).
|
||||
@@ -1569,7 +1577,7 @@ static void windivert_read_service(context_t context)
|
||||
NTSTATUS status;
|
||||
packet_t packet;
|
||||
req_context_t req_context;
|
||||
windivert_addr_t addr;
|
||||
PWINDIVERT_ADDRESS addr;
|
||||
|
||||
timestamp = KeQueryPerformanceCounter(NULL).QuadPart;
|
||||
KeAcquireInStackQueuedSpinLock(&context->lock, &lock_handle);
|
||||
@@ -1596,9 +1604,10 @@ static void windivert_read_service(context_t context)
|
||||
|
||||
if (!timeout)
|
||||
{
|
||||
windivert_read_service_request(packet, NULL,
|
||||
packet->direction, packet->if_idx, packet->sub_if_idx,
|
||||
packet->hop, packet->checksums, request);
|
||||
windivert_read_service_request(packet, NULL, packet->direction,
|
||||
packet->if_idx, packet->sub_if_idx, packet->hop,
|
||||
packet->loopback, packet->timestamp, packet->checksums,
|
||||
request);
|
||||
}
|
||||
|
||||
windivert_free_packet(packet);
|
||||
@@ -1612,7 +1621,7 @@ static void windivert_read_service(context_t context)
|
||||
* WinDivert write routine.
|
||||
*/
|
||||
static NTSTATUS windivert_write(context_t context, WDFREQUEST request,
|
||||
windivert_addr_t addr)
|
||||
PWINDIVERT_ADDRESS addr)
|
||||
{
|
||||
KLOCK_QUEUE_HANDLE lock_handle;
|
||||
PMDL mdl = NULL, mdl_copy = NULL;
|
||||
@@ -1626,6 +1635,7 @@ static NTSTATUS windivert_write(context_t context, WDFREQUEST request,
|
||||
UINT64 flags;
|
||||
HANDLE handle, compl_handle;
|
||||
PNET_BUFFER_LIST buffers = NULL;
|
||||
NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO checksums_info;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
|
||||
DEBUG("WRITE: writing/injecting a packet (context=%p, request=%p)",
|
||||
@@ -1819,7 +1829,7 @@ VOID windivert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request)
|
||||
size_t inbuflen;
|
||||
WDF_REQUEST_PARAMETERS params;
|
||||
WDFMEMORY memobj;
|
||||
windivert_addr_t addr = NULL;
|
||||
PWINDIVERT_ADDRESS addr = NULL;
|
||||
windivert_ioctl_t ioctl;
|
||||
WDF_OBJECT_ATTRIBUTES attributes;
|
||||
req_context_t req_context = NULL;
|
||||
@@ -1876,13 +1886,13 @@ VOID windivert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request)
|
||||
goto windivert_caller_context_error;
|
||||
}
|
||||
status = WdfRequestProbeAndLockUserBufferForWrite(request,
|
||||
(PVOID)ioctl->arg, sizeof(struct windivert_addr_s), &memobj);
|
||||
(PVOID)ioctl->arg, sizeof(WINDIVERT_ADDRESS), &memobj);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
DEBUG_ERROR("invalid arg pointer for RECV ioctl", status);
|
||||
goto windivert_caller_context_error;
|
||||
}
|
||||
addr = (windivert_addr_t)WdfMemoryGetBuffer(memobj, NULL);
|
||||
addr = (PWINDIVERT_ADDRESS)WdfMemoryGetBuffer(memobj, NULL);
|
||||
break;
|
||||
|
||||
case IOCTL_WINDIVERT_SEND:
|
||||
@@ -1893,13 +1903,13 @@ VOID windivert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request)
|
||||
goto windivert_caller_context_error;
|
||||
}
|
||||
status = WdfRequestProbeAndLockUserBufferForRead(request,
|
||||
(PVOID)ioctl->arg, sizeof(struct windivert_addr_s), &memobj);
|
||||
(PVOID)ioctl->arg, sizeof(WINDIVERT_ADDRESS), &memobj);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
DEBUG_ERROR("invalid arg pointer for SEND ioctl", status);
|
||||
goto windivert_caller_context_error;
|
||||
}
|
||||
addr = (windivert_addr_t)WdfMemoryGetBuffer(memobj, NULL);
|
||||
addr = (PWINDIVERT_ADDRESS)WdfMemoryGetBuffer(memobj, NULL);
|
||||
break;
|
||||
|
||||
case IOCTL_WINDIVERT_START_FILTER:
|
||||
@@ -1947,7 +1957,7 @@ extern VOID windivert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request,
|
||||
UINT8 layer;
|
||||
UINT32 priority;
|
||||
UINT64 flags;
|
||||
windivert_addr_t addr;
|
||||
PWINDIVERT_ADDRESS addr;
|
||||
req_context_t req_context;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
context_t context =
|
||||
@@ -2495,7 +2505,7 @@ static void windivert_classify_callout(context_t context, IN UINT8 direction,
|
||||
do
|
||||
{
|
||||
BOOL match = windivert_filter(buffer_fst, if_idx, sub_if_idx, outbound,
|
||||
isipv4, hop, checksums, filter);
|
||||
isipv4, hop, loopback, checksums, filter);
|
||||
if (match)
|
||||
{
|
||||
break;
|
||||
@@ -2530,6 +2540,7 @@ static void windivert_classify_callout(context_t context, IN UINT8 direction,
|
||||
work->advance = advance;
|
||||
work->is_ipv4 = isipv4;
|
||||
work->hop = hop;
|
||||
work->loopback = loopback;
|
||||
work->checksums = checksums;
|
||||
work->direction = direction;
|
||||
work->if_idx = if_idx;
|
||||
@@ -2653,7 +2664,7 @@ VOID windivert_worker(IN WDFWORKITEM item)
|
||||
// Queue the first matching packet.
|
||||
ok = windivert_queue_packet(context, buffer_itr, work->direction,
|
||||
work->if_idx, work->sub_if_idx, work->is_ipv4, work->hop,
|
||||
work->checksums, work->timestamp);
|
||||
work->loopback, work->checksums, work->timestamp);
|
||||
if (!ok)
|
||||
{
|
||||
goto windivert_worker_complete;
|
||||
@@ -2666,12 +2677,12 @@ VOID windivert_worker(IN WDFWORKITEM item)
|
||||
{
|
||||
match = windivert_filter(buffer_itr, work->if_idx,
|
||||
work->sub_if_idx, outbound, work->is_ipv4, work->hop,
|
||||
work->checksums, filter);
|
||||
work->loopback, work->checksums, filter);
|
||||
if (match)
|
||||
{
|
||||
ok = windivert_queue_packet(context, buffer_itr,
|
||||
work->direction, work->if_idx, work->sub_if_idx,
|
||||
work->is_ipv4, work->hop, work->checksums,
|
||||
work->is_ipv4, work->hop, work->loopback, work->checksums,
|
||||
work->timestamp);
|
||||
}
|
||||
else
|
||||
@@ -2705,7 +2716,7 @@ windivert_worker_complete:
|
||||
*/
|
||||
static BOOL windivert_queue_packet(context_t context, PNET_BUFFER buffer,
|
||||
UINT8 direction, UINT32 if_idx, UINT32 sub_if_idx, BOOL is_ipv4, BOOL hop,
|
||||
UINT8 checksums, LONGLONG timestamp0)
|
||||
BOOL loopback, UINT8 checksums, LONGLONG timestamp0)
|
||||
{
|
||||
KLOCK_QUEUE_HANDLE lock_handle;
|
||||
PVOID data;
|
||||
@@ -2751,7 +2762,7 @@ static BOOL windivert_queue_packet(context_t context, PNET_BUFFER buffer,
|
||||
{
|
||||
// FAST PATH: Service an I/O request without queueing the packet.
|
||||
windivert_read_service_request(NULL, buffer, direction, if_idx,
|
||||
sub_if_idx, hop, checksums, request);
|
||||
sub_if_idx, hop, loopback, timestamp0, checksums, request);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -2780,6 +2791,7 @@ static BOOL windivert_queue_packet(context_t context, PNET_BUFFER buffer,
|
||||
}
|
||||
packet->is_ipv4 = is_ipv4;
|
||||
packet->hop = hop;
|
||||
packet->loopback = loopback;
|
||||
packet->checksums = checksums;
|
||||
packet->direction = direction;
|
||||
packet->if_idx = if_idx;
|
||||
@@ -3237,8 +3249,8 @@ static int windivert_big_num_compare(const UINT32 *a, const UINT32 *b)
|
||||
* Checks if the given packet is of interest.
|
||||
*/
|
||||
static BOOL windivert_filter(PNET_BUFFER buffer, UINT32 if_idx,
|
||||
UINT32 sub_if_idx, BOOL outbound, BOOL isipv4, BOOL hop, UINT8 checksums,
|
||||
filter_t filter)
|
||||
UINT32 sub_if_idx, BOOL outbound, BOOL isipv4, BOOL hop, BOOL loopback,
|
||||
UINT8 checksums, filter_t filter)
|
||||
{
|
||||
size_t tot_len, ip_header_len;
|
||||
struct iphdr *ip_header = NULL;
|
||||
@@ -3447,6 +3459,9 @@ static BOOL windivert_filter(PNET_BUFFER buffer, UINT32 if_idx,
|
||||
case WINDIVERT_FILTER_FIELD_SUBIFIDX:
|
||||
field[0] = (UINT32)sub_if_idx;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_LOOPBACK:
|
||||
field[0] = (UINT32)loopback;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_IP:
|
||||
field[0] = (UINT32)(ip_header != NULL);
|
||||
break;
|
||||
@@ -4008,6 +4023,7 @@ static filter_t windivert_filter_compile(windivert_ioctl_filter_t ioctl_filter,
|
||||
case WINDIVERT_FILTER_FIELD_OUTBOUND:
|
||||
case WINDIVERT_FILTER_FIELD_IFIDX:
|
||||
case WINDIVERT_FILTER_FIELD_SUBIFIDX:
|
||||
case WINDIVERT_FILTER_FIELD_LOOPBACK:
|
||||
case WINDIVERT_FILTER_FIELD_IP:
|
||||
case WINDIVERT_FILTER_FIELD_IPV6:
|
||||
case WINDIVERT_FILTER_FIELD_ICMP:
|
||||
|
||||
Reference in New Issue
Block a user