Add WINDIVERT_FLAG_DEBUG for WinDivertOpen()
This commit is contained in:
@@ -87,4 +87,7 @@ WinDivert 1.3.0
|
||||
WinDivert 1.4.0-rc
|
||||
- Add a new WINDIVERT_PARAM_QUEUE_SIZE parameter that can be used to
|
||||
control the maximum number of bytes used by the packet queue.
|
||||
- Add a new WINDIVERT_FLAG_DEBUG flag that causes WinDivertSend() to
|
||||
block until the packet exits the Windows TCP/IP stack. This is slower
|
||||
but provides better error messages, so is useful for debugging.
|
||||
- Internally queued packets are now reinjected on WinDivertClose().
|
||||
|
||||
+22
-1
@@ -548,6 +548,20 @@ This is useful for implementing simple packet filters using the
|
||||
WinDivert <a href="#filter_language">filter language</a>.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<tt>WINDIVERT_FLAG_DEBUG</tt>
|
||||
</td>
|
||||
<td>
|
||||
This flag causes <a href="#divert_recv"><tt>WinDivertRecv()</tt></a> to block
|
||||
until the injected packet <i>exits</i> the Windows TCP/IP stack.
|
||||
By default, <a href="#divert_recv"><tt>WinDivertRecv()</tt></a> does not
|
||||
block and returns immediately after the packet <i>enters</i> the
|
||||
TCP/IP stack.
|
||||
The default mode is faster, but will not return an error code if the
|
||||
packet is lost or rejected for any reason; making debugging difficult.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
Note that only one of <tt>WINDIVERT_FLAG_SNIFF</tt> or
|
||||
@@ -584,6 +598,7 @@ BOOL <b>WinDivertRecv</b>(
|
||||
<tt>TRUE</tt> if a packet was successfully received, or <tt>FALSE</tt> if
|
||||
an error occurred.
|
||||
Use <tt>GetLastError()</tt> to get the reason for the error.
|
||||
</table>
|
||||
</p><p>
|
||||
<b>Remarks</b><br>
|
||||
Receives a diverted packet that matched the filter passed to
|
||||
@@ -701,6 +716,12 @@ BOOL <b>WinDivertSend</b>(
|
||||
an error occurred.
|
||||
Use <tt>GetLastError()</tt> to get the reason for the error.
|
||||
</p><p>
|
||||
Note that a return value of <tt>TRUE</tt> does not necessarily mean the
|
||||
packet was accepted by the Windows TCP/IP stack.
|
||||
For better error messages (at the cost of performance), pass the
|
||||
<tt>WINDIVERT_FLAG_DEBUG</tt> flag to <a
|
||||
href="#divert_open"><tt>WinDivertOpen()</tt></a>.
|
||||
</p><p>
|
||||
<b>Remarks</b><br>
|
||||
Injects a packet into the network stack.
|
||||
The injected packet may be one received from
|
||||
@@ -1577,7 +1598,7 @@ The sample programs are:
|
||||
The basic idea is to divert outbound TCP connections to a local proxy
|
||||
server which can capture or manipulate the stream.
|
||||
The <tt>streamdump</tt> sample program also demonstrates usage of the
|
||||
<a href="#divert_recv_ex"><tt>WinDivertRecvEx()<tt></a> and
|
||||
<a href="#divert_recv_ex"><tt>WinDivertRecvEx()</tt></a> and
|
||||
<a href="#divert_send_ex"><tt>WinDivertSendEx()</tt></a> functions.</li>
|
||||
</ul>
|
||||
</p><p>
|
||||
|
||||
@@ -79,6 +79,7 @@ typedef enum
|
||||
*/
|
||||
#define WINDIVERT_FLAG_SNIFF 1
|
||||
#define WINDIVERT_FLAG_DROP 2
|
||||
#define WINDIVERT_FLAG_DEBUG 4
|
||||
|
||||
/*
|
||||
* Divert parameters.
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
* WinDivert flags.
|
||||
*/
|
||||
#define WINDIVERT_FLAGS_ALL \
|
||||
(WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_DROP)
|
||||
(WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_DROP | WINDIVERT_FLAG_DEBUG)
|
||||
#define WINDIVERT_FLAGS_EXCLUDE(flags, flag1, flag2) \
|
||||
(((flags) & ((flag1) | (flag2))) != ((flag1) | (flag2)))
|
||||
#define WINDIVERT_FLAGS_VALID(flags) \
|
||||
|
||||
+32
-13
@@ -1623,7 +1623,8 @@ static NTSTATUS windivert_write(context_t context, WDFREQUEST request,
|
||||
BOOL isipv4;
|
||||
UINT8 layer;
|
||||
UINT32 priority;
|
||||
HANDLE handle;
|
||||
UINT64 flags;
|
||||
HANDLE handle, compl_handle;
|
||||
PNET_BUFFER_LIST buffers = NULL;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
|
||||
@@ -1726,33 +1727,38 @@ windivert_write_bad_packet:
|
||||
}
|
||||
layer = context->layer;
|
||||
priority = context->priority;
|
||||
flags = context->flags;
|
||||
KeReleaseInStackQueuedSpinLock(&lock_handle);
|
||||
|
||||
handle = (isipv4? inject_handle: injectv6_handle);
|
||||
compl_handle = ((flags & WINDIVERT_FLAG_DEBUG) != 0? (HANDLE)request: NULL);
|
||||
if (layer == WINDIVERT_LAYER_NETWORK_FORWARD)
|
||||
{
|
||||
status = FwpsInjectForwardAsync0(handle, (HANDLE)priority, 0,
|
||||
(isipv4? AF_INET: AF_INET6), UNSPECIFIED_COMPARTMENT_ID,
|
||||
addr->IfIdx, buffers, windivert_inject_complete, NULL);
|
||||
addr->IfIdx, buffers, windivert_inject_complete, compl_handle);
|
||||
}
|
||||
else if (addr->Direction == WINDIVERT_DIRECTION_OUTBOUND)
|
||||
{
|
||||
status = FwpsInjectNetworkSendAsync0(handle, (HANDLE)priority, 0,
|
||||
UNSPECIFIED_COMPARTMENT_ID, buffers, windivert_inject_complete,
|
||||
NULL);
|
||||
compl_handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = FwpsInjectNetworkReceiveAsync0(handle, (HANDLE)priority, 0,
|
||||
UNSPECIFIED_COMPARTMENT_ID, addr->IfIdx, addr->SubIfIdx, buffers,
|
||||
windivert_inject_complete, NULL);
|
||||
windivert_inject_complete, compl_handle);
|
||||
}
|
||||
|
||||
windivert_write_exit:
|
||||
|
||||
if (NT_SUCCESS(status))
|
||||
{
|
||||
WdfRequestCompleteWithInformation(request, status, data_len);
|
||||
if ((flags & WINDIVERT_FLAG_DEBUG) == 0)
|
||||
{
|
||||
WdfRequestCompleteWithInformation(request, status, data_len);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1780,10 +1786,23 @@ static void NTAPI windivert_inject_complete(VOID *context,
|
||||
PMDL mdl;
|
||||
PVOID data;
|
||||
PNET_BUFFER buffer;
|
||||
UNREFERENCED_PARAMETER(context);
|
||||
size_t length;
|
||||
WDFREQUEST request;
|
||||
NTSTATUS status;
|
||||
UNREFERENCED_PARAMETER(dispatch_level);
|
||||
|
||||
buffer = NET_BUFFER_LIST_FIRST_NB(buffers);
|
||||
request = (WDFREQUEST)context;
|
||||
if (request != NULL)
|
||||
{
|
||||
status = NET_BUFFER_LIST_STATUS(buffers);
|
||||
length = 0;
|
||||
if (NT_SUCCESS(status))
|
||||
{
|
||||
length = NET_BUFFER_DATA_LENGTH(buffer);
|
||||
}
|
||||
WdfRequestCompleteWithInformation(request, status, length);
|
||||
}
|
||||
mdl = NET_BUFFER_FIRST_MDL(buffer);
|
||||
data = MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority);
|
||||
windivert_free(data);
|
||||
@@ -2834,7 +2853,7 @@ static BOOL windivert_reinject_packet(BOOL sniff_mode, BOOL forward,
|
||||
PMDL mdl = NULL;
|
||||
PVOID data = NULL;
|
||||
FWPS_INJECT_COMPLETE0 completion;
|
||||
HANDLE comp_handle, handle;
|
||||
HANDLE compl_handle, handle;
|
||||
NTSTATUS status;
|
||||
|
||||
if (buffer != NULL)
|
||||
@@ -2863,7 +2882,7 @@ static BOOL windivert_reinject_packet(BOOL sniff_mode, BOOL forward,
|
||||
}
|
||||
clone = FALSE;
|
||||
completion = windivert_reinject_complete;
|
||||
comp_handle = (HANDLE)buffers;
|
||||
compl_handle = (HANDLE)buffers;
|
||||
FwpsReferenceNetBufferList(buffers, TRUE);
|
||||
}
|
||||
else if (buffers != NULL)
|
||||
@@ -2879,7 +2898,7 @@ static BOOL windivert_reinject_packet(BOOL sniff_mode, BOOL forward,
|
||||
}
|
||||
clone = TRUE;
|
||||
completion = windivert_reinject_clone_complete;
|
||||
comp_handle = (HANDLE)buffers;
|
||||
compl_handle = (HANDLE)buffers;
|
||||
FwpsReferenceNetBufferList(buffers, TRUE);
|
||||
}
|
||||
else if (packet != NULL)
|
||||
@@ -2919,7 +2938,7 @@ static BOOL windivert_reinject_packet(BOOL sniff_mode, BOOL forward,
|
||||
}
|
||||
clone = FALSE;
|
||||
completion = windivert_inject_complete;
|
||||
comp_handle = (HANDLE)NULL;
|
||||
compl_handle = (HANDLE)NULL;
|
||||
}
|
||||
else
|
||||
return TRUE;
|
||||
@@ -2929,19 +2948,19 @@ static BOOL windivert_reinject_packet(BOOL sniff_mode, BOOL forward,
|
||||
{
|
||||
status = FwpsInjectForwardAsync0(handle, (HANDLE)priority, 0,
|
||||
(isipv4? AF_INET: AF_INET6), UNSPECIFIED_COMPARTMENT_ID,
|
||||
if_idx, buffers_cpy, completion, comp_handle);
|
||||
if_idx, buffers_cpy, completion, compl_handle);
|
||||
}
|
||||
else if (direction == WINDIVERT_DIRECTION_OUTBOUND)
|
||||
{
|
||||
status = FwpsInjectNetworkSendAsync0(handle,
|
||||
(HANDLE)priority, 0, UNSPECIFIED_COMPARTMENT_ID, buffers_cpy,
|
||||
completion, comp_handle);
|
||||
completion, compl_handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = FwpsInjectNetworkReceiveAsync0(handle,
|
||||
(HANDLE)priority, 0, UNSPECIFIED_COMPARTMENT_ID, if_idx,
|
||||
sub_if_idx, buffers_cpy, completion, comp_handle);
|
||||
sub_if_idx, buffers_cpy, completion, compl_handle);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
|
||||
Reference in New Issue
Block a user