Add WINDIVERT_FLAG_DEBUG for WinDivertOpen()

This commit is contained in:
basil00
2017-10-31 10:53:06 +08:00
parent d9fbc813f4
commit 4c4f586f4d
5 changed files with 59 additions and 15 deletions
+3
View File
@@ -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
View File
@@ -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>
+1
View File
@@ -79,6 +79,7 @@ typedef enum
*/
#define WINDIVERT_FLAG_SNIFF 1
#define WINDIVERT_FLAG_DROP 2
#define WINDIVERT_FLAG_DEBUG 4
/*
* Divert parameters.
+1 -1
View File
@@ -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
View File
@@ -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))