Add a new FLOW layer into WinDivert.

Adds a new WINDIVERT_LAYER_FLOW layer that can:
- Track when flows are established
- Track when existing flows are deleted
This commit is contained in:
basil00
2018-09-30 09:07:16 +08:00
parent e82552153b
commit 6250568974
14 changed files with 1964 additions and 671 deletions
+1 -1
View File
@@ -1 +1 @@
1.4.4
2.0.0
+16 -1
View File
@@ -411,11 +411,26 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
UINT32 priority32;
// Parameter checking.
if (!WINDIVERT_FLAGS_VALID(flags) || layer > WINDIVERT_LAYER_MAX)
if (layer == 0)
{
layer = WINDIVERT_LAYER_NETWORK;
}
switch (layer)
{
case WINDIVERT_LAYER_NETWORK:
case WINDIVERT_LAYER_NETWORK_FORWARD:
case WINDIVERT_LAYER_FLOW:
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
if (!WINDIVERT_FLAGS_VALID(flags))
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
priority32 = WINDIVERT_PRIORITY(priority);
if (priority32 < WINDIVERT_PRIORITY_MIN ||
priority32 > WINDIVERT_PRIORITY_MAX)
+234 -49
View File
@@ -116,6 +116,12 @@ typedef enum
TOKEN_SUB_IF_IDX,
TOKEN_LOOPBACK,
TOKEN_IMPOSTOR,
TOKEN_PROCESS_ID,
TOKEN_LOCAL_ADDR,
TOKEN_REMOTE_ADDR,
TOKEN_LOCAL_PORT,
TOKEN_REMOTE_PORT,
TOKEN_PROTOCOL,
TOKEN_OPEN,
TOKEN_CLOSE,
TOKEN_EQ,
@@ -504,7 +510,7 @@ extern UINT WinDivertHelperCalcChecksums(PVOID pPacket, UINT packetLen,
tcp_header->Checksum = WinDivertHelperCalcChecksum(
pseudo_header, pseudo_header_len, tcp_header, checksum_len);
}
else if (pAddr->Direction == WINDIVERT_DIRECTION_OUTBOUND)
else if (pAddr->Outbound)
{
// Pseudo TCP checksum
tcp_header->Checksum = 0;
@@ -533,7 +539,7 @@ extern UINT WinDivertHelperCalcChecksums(PVOID pPacket, UINT packetLen,
udp_header->Checksum = 0xFFFF;
}
}
else if (pAddr->Direction == WINDIVERT_DIRECTION_OUTBOUND)
else if (pAddr->Outbound)
{
// Pseudo UDP checksum
udp_header->Checksum = 0;
@@ -748,7 +754,7 @@ extern BOOL WinDivertHelperParseIPv6Address(const char *str, UINT32 *addr_ptr)
l = k + 1;
k = (k >= 8? k - 8: k);
l = (l >= 8? l - 8: l);
addr_ptr[i] =
addr_ptr[3 - i] =
(UINT32)laddr[2 * i + 1] |
(UINT32)laddr[2 * i] << 16 |
(UINT32)raddr[l] |
@@ -785,6 +791,91 @@ static PTOKEN_NAME WinDivertTokenLookup(PTOKEN_NAME token_names,
return NULL;
}
/*
* Validate token for layer.
*/
static BOOL WinDivertCheckTokenKindForLayer(WINDIVERT_LAYER layer, KIND kind)
{
switch (layer)
{
case WINDIVERT_LAYER_NETWORK:
case WINDIVERT_LAYER_NETWORK_FORWARD:
switch (kind)
{
case TOKEN_INBOUND:
case TOKEN_OUTBOUND:
return (layer != WINDIVERT_LAYER_NETWORK_FORWARD);
case TOKEN_PROCESS_ID:
case TOKEN_LOCAL_ADDR:
case TOKEN_REMOTE_ADDR:
case TOKEN_LOCAL_PORT:
case TOKEN_REMOTE_PORT:
return FALSE;
default:
return TRUE;
}
case WINDIVERT_LAYER_FLOW:
switch (kind)
{
case TOKEN_ICMP_BODY:
case TOKEN_ICMP_CHECKSUM:
case TOKEN_ICMP_CODE:
case TOKEN_ICMP_TYPE:
case TOKEN_ICMPV6_BODY:
case TOKEN_ICMPV6_CHECKSUM:
case TOKEN_ICMPV6_CODE:
case TOKEN_ICMPV6_TYPE:
case TOKEN_IP_CHECKSUM:
case TOKEN_IP_DF:
case TOKEN_IP_DST_ADDR:
case TOKEN_IP_FRAG_OFF:
case TOKEN_IP_HDR_LENGTH:
case TOKEN_IP_ID:
case TOKEN_IP_LENGTH:
case TOKEN_IP_MF:
case TOKEN_IP_PROTOCOL:
case TOKEN_IP_SRC_ADDR:
case TOKEN_IP_TOS:
case TOKEN_IP_TTL:
case TOKEN_IPV6_DST_ADDR:
case TOKEN_IPV6_FLOW_LABEL:
case TOKEN_IPV6_HOP_LIMIT:
case TOKEN_IPV6_LENGTH:
case TOKEN_IPV6_NEXT_HDR:
case TOKEN_IPV6_SRC_ADDR:
case TOKEN_IPV6_TRAFFIC_CLASS:
case TOKEN_TCP_ACK:
case TOKEN_TCP_ACK_NUM:
case TOKEN_TCP_CHECKSUM:
case TOKEN_TCP_DST_PORT:
case TOKEN_TCP_FIN:
case TOKEN_TCP_HDR_LENGTH:
case TOKEN_TCP_PAYLOAD_LENGTH:
case TOKEN_TCP_PSH:
case TOKEN_TCP_RST:
case TOKEN_TCP_SEQ_NUM:
case TOKEN_TCP_SRC_PORT:
case TOKEN_TCP_SYN:
case TOKEN_TCP_URG:
case TOKEN_TCP_URG_PTR:
case TOKEN_TCP_WINDOW:
case TOKEN_UDP_CHECKSUM:
case TOKEN_UDP_DST_PORT:
case TOKEN_UDP_LENGTH:
case TOKEN_UDP_PAYLOAD_LENGTH:
case TOKEN_UDP_SRC_PORT:
case TOKEN_IF_IDX:
case TOKEN_SUB_IF_IDX:
case TOKEN_IMPOSTOR:
return FALSE;
default:
return TRUE;
}
default:
return FALSE;
}
}
/*
* Tokenize the given filter string.
*/
@@ -829,10 +920,16 @@ 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},
{"localAddr", TOKEN_LOCAL_ADDR},
{"localPort", TOKEN_LOCAL_PORT},
{"loopback", TOKEN_LOOPBACK},
{"not", TOKEN_NOT},
{"or", TOKEN_OR},
{"outbound", TOKEN_OUTBOUND},
{"processId", TOKEN_PROCESS_ID},
{"protocol", TOKEN_PROTOCOL},
{"remoteAddr", TOKEN_REMOTE_ADDR},
{"remotePort", TOKEN_REMOTE_PORT},
{"subIfIdx", TOKEN_SUB_IF_IDX},
{"tcp", TOKEN_TCP},
{"tcp.Ack", TOKEN_TCP_ACK},
@@ -986,18 +1083,9 @@ static ERROR WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer,
sizeof(token_names) / sizeof(TOKEN_NAME), token);
if (result != NULL)
{
switch (layer)
if (!WinDivertCheckTokenKindForLayer(layer, result->kind))
{
case WINDIVERT_LAYER_NETWORK_FORWARD:
if (result->kind == TOKEN_INBOUND ||
result->kind == TOKEN_OUTBOUND)
{
return MAKE_ERROR(
WINDIVERT_ERROR_BAD_TOKEN_FOR_LAYER, i-j);
}
break;
default:
break;
return MAKE_ERROR(WINDIVERT_ERROR_BAD_TOKEN_FOR_LAYER, i-j);
}
tokens[tp++].kind = result->kind;
continue;
@@ -1023,6 +1111,7 @@ static ERROR WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer,
// Check for IPv4 address:
if (WinDivertHelperParseIPv4Address(token, tokens[tp].val))
{
tokens[tp].val[1] = 0x0000FFFF;
tokens[tp].kind = TOKEN_NUMBER;
tp++;
continue;
@@ -1032,16 +1121,6 @@ static ERROR WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer,
SetLastError(0);
if (WinDivertHelperParseIPv6Address(token, tokens[tp].val))
{
// Work-around the different word orderings between the
// DLL vs SYS.
UINT32 tmp;
tmp = tokens[tp].val[0];
tokens[tp].val[0] = tokens[tp].val[3];
tokens[tp].val[3] = tmp;
tmp = tokens[tp].val[1];
tokens[tp].val[1] = tokens[tp].val[2];
tokens[tp].val[2] = tmp;
tokens[tp].kind = TOKEN_NUMBER;
tp++;
continue;
@@ -1140,7 +1219,13 @@ static PEXPR WinDivertMakeVar(PPOOL pool, KIND kind)
{{{0}}, TOKEN_IF_IDX},
{{{0}}, TOKEN_SUB_IF_IDX},
{{{0}}, TOKEN_LOOPBACK},
{{{0}}, TOKEN_IMPOSTOR}
{{{0}}, TOKEN_IMPOSTOR},
{{{0}}, TOKEN_PROCESS_ID},
{{{0}}, TOKEN_LOCAL_ADDR},
{{{0}}, TOKEN_REMOTE_ADDR},
{{{0}}, TOKEN_LOCAL_PORT},
{{{0}}, TOKEN_REMOTE_PORT},
{{{0}}, TOKEN_PROTOCOL},
};
// Binary search:
@@ -1268,6 +1353,12 @@ static PEXPR WinDivertParseTest(PPOOL pool, TOKEN *toks, UINT *i)
case TOKEN_ICMPV6:
case TOKEN_TCP:
case TOKEN_UDP:
case TOKEN_PROCESS_ID:
case TOKEN_LOCAL_ADDR:
case TOKEN_REMOTE_ADDR:
case TOKEN_LOCAL_PORT:
case TOKEN_REMOTE_PORT:
case TOKEN_PROTOCOL:
case TOKEN_IP_HDR_LENGTH:
case TOKEN_IP_TOS:
case TOKEN_IP_LENGTH:
@@ -1524,6 +1615,7 @@ static BOOL WinDivertEvalTest(PEXPR test, BOOL *res)
case TOKEN_ICMP_CODE:
case TOKEN_ICMPV6_TYPE:
case TOKEN_ICMPV6_CODE:
case TOKEN_PROCESS_ID:
lb = 0; ub = 0xFF;
break;
case TOKEN_IP_FRAG_OFF:
@@ -1547,13 +1639,19 @@ static BOOL WinDivertEvalTest(PEXPR test, BOOL *res)
case TOKEN_UDP_LENGTH:
case TOKEN_UDP_CHECKSUM:
case TOKEN_UDP_PAYLOAD_LENGTH:
case TOKEN_LOCAL_PORT:
case TOKEN_REMOTE_PORT:
lb = 0; ub = 0xFFFF;
break;
case TOKEN_IPV6_FLOW_LABEL:
lb = 0; ub = 0x000FFFFF;
break;
case TOKEN_IP_SRC_ADDR:
case TOKEN_IP_DST_ADDR:
case TOKEN_IPV6_SRC_ADDR:
case TOKEN_IPV6_DST_ADDR:
case TOKEN_LOCAL_ADDR:
case TOKEN_REMOTE_ADDR:
return FALSE;
default:
lb = 0; ub = 0xFFFFFFFF;
@@ -1735,6 +1833,21 @@ static void WinDivertEmitTest(PEXPR test, UINT16 offset,
case TOKEN_IMPOSTOR:
object->field = WINDIVERT_FILTER_FIELD_IMPOSTOR;
break;
case TOKEN_PROCESS_ID:
object->field = WINDIVERT_FILTER_FIELD_PROCESSID;
break;
case TOKEN_LOCAL_ADDR:
object->field = WINDIVERT_FILTER_FIELD_LOCALADDR;
break;
case TOKEN_REMOTE_ADDR:
object->field = WINDIVERT_FILTER_FIELD_REMOTEADDR;
break;
case TOKEN_LOCAL_PORT:
object->field = WINDIVERT_FILTER_FIELD_LOCALPORT;
break;
case TOKEN_REMOTE_PORT:
object->field = WINDIVERT_FILTER_FIELD_REMOTEPORT;
break;
case TOKEN_IP:
object->field = WINDIVERT_FILTER_FIELD_IP;
break;
@@ -2118,18 +2231,17 @@ static int WinDivertBigNumCompare(const UINT32 *a, const UINT32 *b)
/*
* Evaluate the given filter with the given packet as input.
*/
extern BOOL WinDivertHelperEvalFilter(const char *filter,
WINDIVERT_LAYER layer, PVOID packet, UINT packet_len,
PWINDIVERT_ADDRESS addr)
extern BOOL WinDivertHelperEvalFilter(const char *filter, PVOID packet,
UINT packet_len, PWINDIVERT_ADDRESS addr)
{
UINT16 pc;
ERROR err;
PWINDIVERT_IPHDR iphdr;
PWINDIVERT_IPV6HDR ipv6hdr;
PWINDIVERT_ICMPHDR icmphdr;
PWINDIVERT_ICMPV6HDR icmpv6hdr;
PWINDIVERT_TCPHDR tcphdr;
PWINDIVERT_UDPHDR udphdr;
PWINDIVERT_IPHDR iphdr = NULL;
PWINDIVERT_IPV6HDR ipv6hdr = NULL;
PWINDIVERT_ICMPHDR icmphdr = NULL;
PWINDIVERT_ICMPV6HDR icmpv6hdr = NULL;
PWINDIVERT_TCPHDR tcphdr = NULL;
PWINDIVERT_UDPHDR udphdr = NULL;
UINT payload_len;
UINT32 val[4];
BOOL pass;
@@ -2137,22 +2249,48 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter,
struct windivert_ioctl_filter_s object[WINDIVERT_FILTER_MAXLEN];
UINT obj_len;
if (filter == NULL || packet == NULL || addr == NULL)
if (filter == NULL || addr == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
switch (addr->Layer)
{
case WINDIVERT_LAYER_NETWORK:
case WINDIVERT_LAYER_NETWORK_FORWARD:
if (packet == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
WinDivertHelperParsePacket(packet, packet_len, &iphdr, &ipv6hdr,
&icmphdr, &icmpv6hdr, &tcphdr, &udphdr, NULL, &payload_len);
if ((addr->IPv6 && ipv6hdr == NULL) ||
(!addr->IPv6 && iphdr == NULL))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case WINDIVERT_LAYER_FLOW:
if (packet != NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
err = WinDivertCompileFilter(filter, layer, object, &obj_len);
err = WinDivertCompileFilter(filter, addr->Layer, object, &obj_len);
if (IS_ERROR(err))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
WinDivertHelperParsePacket(packet, packet_len, &iphdr, &ipv6hdr, &icmphdr,
&icmpv6hdr, &tcphdr, &udphdr, NULL, &payload_len);
pc = 0;
while (TRUE)
{
@@ -2232,6 +2370,23 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter,
case WINDIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH:
pass = (udphdr != NULL);
break;
case WINDIVERT_FILTER_FIELD_INBOUND:
case WINDIVERT_FILTER_FIELD_OUTBOUND:
pass = (addr->Layer != WINDIVERT_LAYER_NETWORK_FORWARD);
break;
case WINDIVERT_FILTER_FIELD_IFIDX:
case WINDIVERT_FILTER_FIELD_SUBIFIDX:
pass = (addr->Layer == WINDIVERT_LAYER_NETWORK ||
addr->Layer == WINDIVERT_LAYER_NETWORK_FORWARD);
break;
case WINDIVERT_FILTER_FIELD_PROCESSID:
case WINDIVERT_FILTER_FIELD_LOCALADDR:
case WINDIVERT_FILTER_FIELD_REMOTEADDR:
case WINDIVERT_FILTER_FIELD_LOCALPORT:
case WINDIVERT_FILTER_FIELD_REMOTEPORT:
case WINDIVERT_FILTER_FIELD_PROTOCOL:
pass = (addr->Layer == WINDIVERT_LAYER_FLOW);
break;
default:
pass = TRUE;
break;
@@ -2248,16 +2403,16 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter,
val[0] = 0;
break;
case WINDIVERT_FILTER_FIELD_INBOUND:
val[0] = (addr->Direction == WINDIVERT_DIRECTION_INBOUND);
val[0] = !addr->Outbound;
break;
case WINDIVERT_FILTER_FIELD_OUTBOUND:
val[0] = (addr->Direction == WINDIVERT_DIRECTION_OUTBOUND);
val[0] = addr->Outbound;
break;
case WINDIVERT_FILTER_FIELD_IFIDX:
val[0] = addr->IfIdx;
val[0] = addr->Network.IfIdx;
break;
case WINDIVERT_FILTER_FIELD_SUBIFIDX:
val[0] = addr->SubIfIdx;
val[0] = addr->Network.SubIfIdx;
break;
case WINDIVERT_FILTER_FIELD_LOOPBACK:
val[0] = addr->Loopback;
@@ -2266,22 +2421,26 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter,
val[0] = addr->Impostor;
break;
case WINDIVERT_FILTER_FIELD_IP:
val[0] = (iphdr != NULL);
val[0] = !addr->IPv6;
break;
case WINDIVERT_FILTER_FIELD_IPV6:
val[0] = (ipv6hdr != NULL);
val[0] = addr->IPv6;
break;
case WINDIVERT_FILTER_FIELD_ICMP:
val[0] = (icmphdr != NULL);
val[0] = (addr->Layer == WINDIVERT_LAYER_FLOW?
addr->Flow.Protocol == IPPROTO_ICMP: icmphdr != NULL);
break;
case WINDIVERT_FILTER_FIELD_ICMPV6:
val[0] = (icmpv6hdr != NULL);
val[0] = (addr->Layer == WINDIVERT_LAYER_FLOW?
addr->Flow.Protocol == IPPROTO_ICMPV6: icmpv6hdr != NULL);
break;
case WINDIVERT_FILTER_FIELD_TCP:
val[0] = (tcphdr != NULL);
val[0] = (addr->Layer == WINDIVERT_LAYER_FLOW?
addr->Flow.Protocol == IPPROTO_TCP: tcphdr != NULL);
break;
case WINDIVERT_FILTER_FIELD_UDP:
val[0] = (udphdr != NULL);
val[0] = (addr->Layer == WINDIVERT_LAYER_FLOW?
addr->Flow.Protocol == IPPROTO_UDP: udphdr != NULL);
break;
case WINDIVERT_FILTER_FIELD_IP_HDRLENGTH:
val[0] = iphdr->HdrLength;
@@ -2314,9 +2473,11 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter,
val[0] = ntohs(iphdr->Checksum);
break;
case WINDIVERT_FILTER_FIELD_IP_SRCADDR:
val[1] = 0x0000FFFF;
val[0] = ntohl(iphdr->SrcAddr);
break;
case WINDIVERT_FILTER_FIELD_IP_DSTADDR:
val[1] = 0x0000FFFF;
val[0] = ntohl(iphdr->DstAddr);
break;
case WINDIVERT_FILTER_FIELD_IPV6_TRAFFICCLASS:
@@ -2430,6 +2591,30 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter,
case WINDIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH:
val[0] = payload_len;
break;
case WINDIVERT_FILTER_FIELD_PROCESSID:
val[0] = addr->Flow.ProcessId;
break;
case WINDIVERT_FILTER_FIELD_LOCALADDR:
val[0] = addr->Flow.LocalAddr[0];
val[1] = addr->Flow.LocalAddr[1];
val[2] = addr->Flow.LocalAddr[2];
val[3] = addr->Flow.LocalAddr[3];
break;
case WINDIVERT_FILTER_FIELD_REMOTEADDR:
val[0] = addr->Flow.RemoteAddr[0];
val[1] = addr->Flow.RemoteAddr[1];
val[2] = addr->Flow.RemoteAddr[2];
val[3] = addr->Flow.RemoteAddr[3];
break;
case WINDIVERT_FILTER_FIELD_LOCALPORT:
val[0] = addr->Flow.LocalPort;
break;
case WINDIVERT_FILTER_FIELD_REMOTEPORT:
val[0] = addr->Flow.RemotePort;
break;
case WINDIVERT_FILTER_FIELD_PROTOCOL:
val[0] = addr->Flow.Protocol;
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
+12 -11
View File
@@ -1260,8 +1260,8 @@ Use <tt>GetLastError()</tt> to get the reason for the error.
</p><p>
<b>Remarks</b><br>
Parses an IPv4 address stored in <tt>addrStr</tt>.
If non-<tt>NULL</tt>, the result is stored in <tt>pAddr</tt>
in host-byte-order.
If <tt>pAddr</tt> is non-<tt>NULL</tt>, the is be stored in
host-byte-order.
Use <tt>htonl()</tt> to convert the result into network-byte-order.
</p>
<dd></dl>
@@ -1289,21 +1289,22 @@ Use <tt>GetLastError()</tt> to get the reason for the error.
</p><p>
<b>Remarks</b><br>
Parses an IPv6 address stored in <tt>addrStr</tt>.
If non-<tt>NULL</tt>, the result is stored in <tt>pAddr</tt>.
The <tt>pAddr</tt> parameter is assumed to point to a buffer large enough
to hold a 16-byte IPv6 address.
Given an IPv6 address of the form
If <tt>pAddr</tt> is non-<tt>NULL</tt>, the buffer assumed
to be large enough to hold a 16-byte IPv6 address.
The result is stored in host-byte-order.
For example, given an IPv6 address of the form
<tt>0011:2233:4455:6677:8899:aabb:ccdd:eeff</tt>, then
the result is ordered as follows:
<pre>
pAddr[0] = 0x00112233
pAddr[1] = 0x44556677
pAddr[2] = 0x8899aabb
pAddr[3] = 0xccddeeff
pAddr[0] = 0xccddeeff
pAddr[1] = 0x8899aabb
pAddr[2] = 0x44556677
pAddr[3] = 0x00112233
</pre>
where each <tt>pAddr[i]</tt> is in host-byte-order.
The result can be converted into network-byte-order by setting
<tt>pAddr[i] = htonl(pAddr[i])</tt> for each <tt>i</tt>.
<tt>pAddr[i] = htonl(pAddr[i])</tt> for each <tt>i</tt> and
swapping the array indexes.
</p>
<dd></dl>
+350
View File
@@ -0,0 +1,350 @@
/*
* streamdump.c
* (C) 2018, all rights reserved,
*
* This file is part of WinDivert.
*
* WinDivert is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* WinDivert is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*
* DESCRIPTION:
*
* usage: flowtrack.exe [filter]
*/
#include <winsock2.h>
#include <windows.h>
#include <psapi.h>
#include <shlwapi.h>
#include <stdio.h>
#include <stdlib.h>
#include "windivert.h"
#define MAX_FLOWS 256
/*
* Flow tracking.
*/
typedef struct FLOW
{
WINDIVERT_ADDRESS addr;
struct FLOW *next;
} FLOW, *PFLOW;
static HANDLE lock;
static PFLOW flows = NULL;
/*
* Print an IP address.
*/
static void print_address(const UINT32 *addr)
{
if (addr[3] == 0 && addr[2] == 0 && addr[1] == 0x0000FFFF)
{
// IPv4 address:
UINT32 a, b, c, d;
a = (addr[0] >> 24) & 0xFF;
b = (addr[0] >> 16) & 0xFF;
c = (addr[0] >> 8) & 0xFF;
d = (addr[0] >> 0) & 0xFF;
printf("%u.%u.%u.%u", a, b, c, d);
}
else
{
// IPv6 address:
int i;
for (i = 3; i >= 0; i--)
{
UINT32 a, b;
a = (addr[i] >> 16) & 0xFFFF;
b = (addr[i] >> 0) & 0xFFFF;
printf("%x:%x", a, b);
if (i != 0)
{
putchar(':');
}
}
}
}
/*
* Draw flows to console in a delayed loop.
*
* This function does minimal error checking.
*/
static DWORD draw(LPVOID arg)
{
const COORD top_left = {0, 0};
HANDLE process, console = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO screen;
char path[MAX_PATH+1];
char *filename;
const char header[] = "PID PROGRAM PROT FLOW";
DWORD rows, columns, written, fill_len, path_len, i;
PFLOW flow;
WINDIVERT_ADDRESS addrs[MAX_FLOWS], *addr;
UINT num_addrs;
while (TRUE)
{
GetConsoleScreenBufferInfo(console, &screen);
SetConsoleCursorPosition(console, top_left);
rows = screen.srWindow.Bottom - screen.srWindow.Top + 1;
columns = screen.srWindow.Right - screen.srWindow.Left + 1;
// Copy a snapshot of the current flows:
WaitForSingleObject(lock, INFINITE);
flow = flows;
num_addrs = 0;
for (i = 0; flow != NULL && i < rows && i < MAX_FLOWS; i++)
{
memcpy(&addrs[i], &flow->addr, sizeof(addrs[i]));
num_addrs++;
flow = flow->next;
}
ReleaseMutex(lock);
// Print the flows:
SetConsoleTextAttribute(console, BACKGROUND_RED | BACKGROUND_GREEN |
BACKGROUND_BLUE);
WriteConsole(console, header, sizeof(header)-1, &written, NULL);
fill_len = columns - (sizeof(header)-1);
if (fill_len > 0)
{
COORD pos = {sizeof(header)-1, 0};
FillConsoleOutputCharacterA(console, ' ', fill_len, pos,
&written);
FillConsoleOutputAttribute(console,
BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE,
fill_len, pos, &written);
}
putchar('\n');
SetConsoleTextAttribute(console,
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
for (i = 0; i < num_addrs && i < rows-1; i++)
{
COORD pos = {0, i+1};
addr = &addrs[i];
FillConsoleOutputCharacterA(console, ' ', columns, pos, &written);
FillConsoleOutputAttribute(console,
FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE,
columns, pos, &written);
SetConsoleCursorPosition(console, pos);
if (i == rows-2 && (i+1) < num_addrs)
{
fputs("...", stdout);
fflush(stdout);
continue;
}
printf("%-10d ", addr->Flow.ProcessId);
process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE,
addr->Flow.ProcessId);
path_len = 0;
if (process != NULL)
{
path_len = GetProcessImageFileName(process, path, sizeof(path));
CloseHandle(process);
}
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
if (path_len != 0)
{
filename = PathFindFileName(path);
printf("%-20.20s ", filename);
}
else if (addr->Flow.ProcessId == 4)
{
fputs("Windows ", stdout);
}
else
{
fputs("??? ", stdout);
}
SetConsoleTextAttribute(console,
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
switch (addr->Flow.Protocol)
{
case IPPROTO_TCP:
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
printf("TCP ");
break;
case IPPROTO_UDP:
SetConsoleTextAttribute(console,
FOREGROUND_RED | FOREGROUND_GREEN);
printf("UDP ");
break;
case IPPROTO_ICMP:
SetConsoleTextAttribute(console, FOREGROUND_RED);
printf("ICMP ");
break;
case IPPROTO_ICMPV6:
SetConsoleTextAttribute(console, FOREGROUND_RED);
printf("ICMPV6 ");
break;
default:
printf("%-6u ", addr->Flow.Protocol);
break;
}
SetConsoleTextAttribute(console,
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
print_address(addr->Flow.LocalAddr);
printf(":%u %s ", addr->Flow.LocalPort,
(addr->Outbound? "---->": "<----"));
print_address(addr->Flow.RemoteAddr);
printf(":%u", addr->Flow.RemotePort);
fflush(stdout);
}
for (; i < rows-1; i++)
{
COORD pos = {0, i+1};
FillConsoleOutputCharacterA(console, ' ', columns, pos, &written);
FillConsoleOutputAttribute(console,
FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE,
columns, pos, &written);
}
Sleep(1000);
}
}
/*
* Entry.
*/
int __cdecl main(int argc, char **argv)
{
HANDLE handle, thread;
INT16 priority = 776; // Arbitrary.
const char *filter = "true", *err_str;
UINT packet_len;
WINDIVERT_ADDRESS addr;
PFLOW flow, prev;
switch (argc)
{
case 1:
break;
case 2:
filter = argv[1];
break;
default:
fprintf(stderr, "usage: %s [filter]\n");
exit(EXIT_FAILURE);
}
// Spawn the draw() thread.
lock = CreateMutex(NULL, FALSE, NULL);
thread = CreateThread(NULL, 1, (LPTHREAD_START_ROUTINE)draw, NULL, 0,
NULL);
if (thread == NULL)
{
fprintf(stderr, "error: failed to create thread (%d)\n",
GetLastError());
return EXIT_FAILURE;
}
CloseHandle(thread);
// Open WinDivert FLOW handle:
handle = WinDivertOpen(filter, WINDIVERT_LAYER_FLOW, priority,
WINDIVERT_FLAGS_LAYER_FLOW);
if (handle == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_INVALID_PARAMETER &&
!WinDivertHelperCheckFilter(filter, WINDIVERT_LAYER_FLOW,
&err_str, NULL))
{
fprintf(stderr, "error: invalid filter \"%s\"\n", err_str);
exit(EXIT_FAILURE);
}
fprintf(stderr, "error: failed to open the WinDivert device (%d)\n",
GetLastError());
return EXIT_FAILURE;
}
// Main loop:
while (TRUE)
{
if (!WinDivertRecv(handle, NULL, 0, &addr, &packet_len))
{
fprintf(stderr, "failed to read packet (%d)\n", GetLastError());
continue;
}
switch (addr.Event)
{
case WINDIVERT_EVENT_FLOW_ESTABLISHED:
// Flow established:
flow = (PFLOW)malloc(sizeof(FLOW));
if (flow == NULL)
{
fprintf(stderr, "error: failed to allocate memory\n");
exit(EXIT_FAILURE);
}
memcpy(&flow->addr, &addr, sizeof(flow->addr));
WaitForSingleObject(lock, INFINITE);
flow->next = flows;
flows = flow;
ReleaseMutex(lock);
break;
case WINDIVERT_EVENT_FLOW_DELETED:
// Flow deleted:
prev = NULL;
WaitForSingleObject(lock, INFINITE);
flow = flows;
while (flow != NULL)
{
if (memcmp(&addr.Flow, &flow->addr.Flow,
sizeof(addr.Flow)) == 0)
{
if (prev != NULL)
{
prev->next = flow->next;
}
else
{
flows = flow->next;
}
break;
}
prev = flow;
flow = flow->next;
}
ReleaseMutex(lock);
free(flow);
}
}
return 0;
}
+2 -3
View File
@@ -156,9 +156,8 @@ int __cdecl main(int argc, char **argv)
(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);
time_passed, (addr.Outbound? "outbound": "inbound"),
addr.Network.IfIdx, addr.Network.SubIfIdx, addr.Loopback);
if (ip_header != NULL)
{
UINT8 *src_addr = (UINT8 *)&ip_header->SrcAddr;
+4 -4
View File
@@ -287,7 +287,7 @@ int __cdecl main(int argc, char **argv)
htonl(ntohl(tcp_header->SeqNum) + payload_len));
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
send_addr.Direction = !recv_addr.Direction;
send_addr.Outbound = !recv_addr.Outbound;
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(TCPPACKET),
&send_addr, 0);
if (!WinDivertSend(handle, (PVOID)reset, sizeof(TCPPACKET),
@@ -314,7 +314,7 @@ int __cdecl main(int argc, char **argv)
htonl(ntohl(tcp_header->SeqNum) + payload_len));
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
send_addr.Direction = !recv_addr.Direction;
send_addr.Outbound = !recv_addr.Outbound;
WinDivertHelperCalcChecksums((PVOID)resetv6,
sizeof(TCPV6PACKET), &send_addr, 0);
if (!WinDivertSend(handle, (PVOID)resetv6, sizeof(TCPV6PACKET),
@@ -340,7 +340,7 @@ int __cdecl main(int argc, char **argv)
dnr->ip.DstAddr = ip_header->SrcAddr;
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
send_addr.Direction = !recv_addr.Direction;
send_addr.Outbound = !recv_addr.Outbound;
WinDivertHelperCalcChecksums((PVOID)dnr, icmp_length,
&send_addr, 0);
if (!WinDivertSend(handle, (PVOID)dnr, icmp_length, &send_addr,
@@ -363,7 +363,7 @@ int __cdecl main(int argc, char **argv)
sizeof(dnrv6->ipv6.DstAddr));
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
send_addr.Direction = !recv_addr.Direction;
send_addr.Outbound = !recv_addr.Outbound;
WinDivertHelperCalcChecksums((PVOID)dnrv6, icmpv6_length,
&send_addr, 0);
if (!WinDivertSend(handle, (PVOID)dnrv6, icmpv6_length,
+32 -34
View File
@@ -257,41 +257,39 @@ read_failed:
continue;
}
switch (addr.Direction)
if (addr.Outbound)
{
case WINDIVERT_DIRECTION_OUTBOUND:
if (tcp_header->DstPort == htons(port))
{
// Reflect: PORT ---> PROXY
UINT32 dst_addr = ip_header->DstAddr;
tcp_header->DstPort = htons(proxy_port);
ip_header->DstAddr = ip_header->SrcAddr;
ip_header->SrcAddr = dst_addr;
addr.Direction = WINDIVERT_DIRECTION_INBOUND;
}
else if (tcp_header->SrcPort == htons(proxy_port))
{
// Reflect: PROXY ---> PORT
UINT32 dst_addr = ip_header->DstAddr;
tcp_header->SrcPort = htons(port);
ip_header->DstAddr = ip_header->SrcAddr;
ip_header->SrcAddr = dst_addr;
addr.Direction = WINDIVERT_DIRECTION_INBOUND;
}
else if (tcp_header->DstPort == htons(alt_port))
{
// Redirect: ALT ---> PORT
tcp_header->DstPort = htons(port);
}
break;
case WINDIVERT_DIRECTION_INBOUND:
if (tcp_header->SrcPort == htons(port))
{
// Redirect: PORT ---> ALT
tcp_header->SrcPort = htons(alt_port);
}
break;
if (tcp_header->DstPort == htons(port))
{
// Reflect: PORT ---> PROXY
UINT32 dst_addr = ip_header->DstAddr;
tcp_header->DstPort = htons(proxy_port);
ip_header->DstAddr = ip_header->SrcAddr;
ip_header->SrcAddr = dst_addr;
addr.Outbound = FALSE;
}
else if (tcp_header->SrcPort == htons(proxy_port))
{
// Reflect: PROXY ---> PORT
UINT32 dst_addr = ip_header->DstAddr;
tcp_header->SrcPort = htons(port);
ip_header->DstAddr = ip_header->SrcAddr;
ip_header->SrcAddr = dst_addr;
addr.Outbound = FALSE;
}
else if (tcp_header->DstPort == htons(alt_port))
{
// Redirect: ALT ---> PORT
tcp_header->DstPort = htons(port);
}
}
else
{
if (tcp_header->SrcPort == htons(port))
{
// Redirect: PORT ---> ALT
tcp_header->SrcPort = htons(alt_port);
}
}
WinDivertHelperCalcChecksums(packet, packet_len, &addr, 0);
+1 -1
View File
@@ -238,7 +238,7 @@ int __cdecl main(int argc, char **argv)
blockpage->header.tcp.SeqNum = tcp_header->AckNum;
blockpage->header.tcp.AckNum =
htonl(ntohl(tcp_header->SeqNum) + payload_len);
addr.Direction = !addr.Direction; // Reverse direction.
addr.Outbound = !addr.Outbound; // Reverse direction.
WinDivertHelperCalcChecksums((PVOID)blockpage, blockpage_len, &addr, 0);
if (!WinDivertSend(handle, (PVOID)blockpage, blockpage_len, &addr,
NULL))
+66 -20
View File
@@ -70,43 +70,90 @@ extern "C" {
/****************************************************************************/
/*
* Divert address.
* WinDivert NETWORK and NETWORK_FORWARD layer data.
*/
typedef struct
{
UINT32 IfIdx; /* Packet's interface index. */
UINT32 SubIfIdx; /* Packet's sub-interface index. */
} WINDIVERT_NETWORK_DATA, *PWINDIVERT_NETWORK_DATA;
/*
* WinDivert FLOW layer data.
*/
typedef struct
{
UINT32 ProcessId; /* Process ID. */
UINT32 LocalAddr[4]; /* Local address. */
UINT32 RemoteAddr[4]; /* Remote address. */
UINT16 LocalPort; /* Local port. */
UINT16 RemotePort; /* Remote port. */
UINT8 Protocol; /* Protocol. */
} WINDIVERT_FLOW_DATA, *PWINDIVERT_FLOW_DATA;
/*
* WinDivert address.
*/
typedef struct
{
INT64 Timestamp; /* Packet's timestamp. */
UINT32 IfIdx; /* Packet's interface index. */
UINT32 SubIfIdx; /* Packet's sub-interface index. */
UINT8 Direction:1; /* Packet's direction. */
UINT8 Loopback:1; /* Packet is loopback? */
UINT8 Impostor:1; /* Packet is impostor? */
UINT8 PseudoIPChecksum:1; /* Packet has pseudo IPv4 checksum? */
UINT8 PseudoTCPChecksum:1; /* Packet has pseudo TCP checksum? */
UINT8 PseudoUDPChecksum:1; /* Packet has pseudo UDP checksum? */
UINT8 Reserved:2;
UINT32 Layer:8; /* Packet's layer. */
UINT32 Event:8; /* Packet event. */
UINT32 Outbound:1; /* Packet is outound? */
UINT32 Loopback:1; /* Packet is loopback? */
UINT32 Impostor:1; /* Packet is impostor? */
UINT32 IPv6:1; /* Packet is IPv6? */
UINT32 PseudoIPChecksum:1; /* Packet has pseudo IPv4 checksum? */
UINT32 PseudoTCPChecksum:1; /* Packet has pseudo TCP checksum? */
UINT32 PseudoUDPChecksum:1; /* Packet has pseudo UDP checksum? */
UINT32 Reserved:9;
union
{
WINDIVERT_NETWORK_DATA Network; /* Network layer data. */
WINDIVERT_FLOW_DATA Flow; /* Flow layer data. */
};
} WINDIVERT_ADDRESS, *PWINDIVERT_ADDRESS;
#define WINDIVERT_DIRECTION_OUTBOUND 0
#define WINDIVERT_DIRECTION_INBOUND 1
/*
* Divert layers.
* WinDivert layers.
*/
typedef enum
{
WINDIVERT_LAYER_NETWORK = 0, /* Network layer. */
WINDIVERT_LAYER_NETWORK_FORWARD = 1 /* Network layer (forwarded packets) */
WINDIVERT_LAYER_NETWORK = 1, /* Network layer. */
WINDIVERT_LAYER_NETWORK_FORWARD = 2,/* Network layer (forwarded packets) */
WINDIVERT_LAYER_FLOW = 3 /* Flow layer. */
} WINDIVERT_LAYER, *PWINDIVERT_LAYER;
/*
* Divert flags.
* WinDivert events.
*/
typedef enum
{
WINDIVERT_EVENT_NETWORK_PACKET = 0, /* Network packet. */
WINDIVERT_EVENT_FLOW_ESTABLISHED = 1,
/* Flow established. */
WINDIVERT_EVENT_FLOW_DELETED = 2, /* Flow deleted. */
} WINDIVERT_EVENT, *PWINDIVERT_EVENT;
/*
* WinDivert flags.
*/
#define WINDIVERT_FLAG_SNIFF 1
#define WINDIVERT_FLAG_DROP 2
#define WINDIVERT_FLAG_DEBUG 4
#define WINDIVERT_FLAG_RECV_ONLY 4
#define WINDIVERT_FLAG_READ_ONLY WINDIVERT_FLAG_RECV_ONLY
#define WINDIVERT_FLAG_SEND_ONLY 8
#define WINDIVERT_FLAG_WRITE_ONLY WINDIVERT_FLAG_SEND_ONLY
#define WINDIVERT_FLAG_DEBUG 16
#define WINDIVERT_FLAGS_LAYER_NETWORK 0
#define WINDIVERT_FLAGS_LAYER_NETWORK_FORWARD \
0
#define WINDIVERT_FLAGS_LAYER_FLOW \
(WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_RECV_ONLY)
/*
* Divert parameters.
* WinDivert parameters.
*/
typedef enum
{
@@ -396,7 +443,6 @@ extern WINDIVERTEXPORT BOOL WinDivertHelperCheckFilter(
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperEvalFilter(
__in const char *filter,
__in WINDIVERT_LAYER layer,
__in PVOID pPacket,
__in UINT packetLen,
__in PWINDIVERT_ADDRESS pAddr);
+25 -18
View File
@@ -44,8 +44,8 @@
#define WINDIVERT_KERNEL
#include "windivert.h"
#define WINDIVERT_VERSION 1
#define WINDIVERT_VERSION_MINOR 4
#define WINDIVERT_VERSION 2
#define WINDIVERT_VERSION_MINOR 0
#define WINDIVERT_STR2(s) #s
#define WINDIVERT_STR(s) WINDIVERT_STR2(s)
@@ -59,8 +59,8 @@
#define WINDIVERT_DEVICE_NAME \
L"WinDivert" WINDIVERT_VERSION_LSTR
#define WINDIVERT_IOCTL_VERSION 6
#define WINDIVERT_IOCTL_MAGIC 0xA2BF
#define WINDIVERT_IOCTL_VERSION 7
#define WINDIVERT_IOCTL_MAGIC 0xC7C9
#define WINDIVERT_FILTER_FIELD_ZERO 0
#define WINDIVERT_FILTER_FIELD_INBOUND 1
@@ -122,8 +122,14 @@
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH 57
#define WINDIVERT_FILTER_FIELD_LOOPBACK 58
#define WINDIVERT_FILTER_FIELD_IMPOSTOR 59
#define WINDIVERT_FILTER_FIELD_PROCESSID 60
#define WINDIVERT_FILTER_FIELD_LOCALADDR 61
#define WINDIVERT_FILTER_FIELD_REMOTEADDR 62
#define WINDIVERT_FILTER_FIELD_LOCALPORT 63
#define WINDIVERT_FILTER_FIELD_REMOTEPORT 64
#define WINDIVERT_FILTER_FIELD_PROTOCOL 65
#define WINDIVERT_FILTER_FIELD_MAX \
WINDIVERT_FILTER_FIELD_IMPOSTOR
WINDIVERT_FILTER_FIELD_PROTOCOL
#define WINDIVERT_FILTER_TEST_EQ 0
#define WINDIVERT_FILTER_TEST_NEQ 1
@@ -142,20 +148,21 @@
* WinDivert layers.
*/
#define WINDIVERT_LAYER_DEFAULT WINDIVERT_LAYER_NETWORK
#define WINDIVERT_LAYER_MAX \
WINDIVERT_LAYER_NETWORK_FORWARD
/*
* WinDivert flags.
*/
#define WINDIVERT_FLAGS_ALL \
(WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_DROP | WINDIVERT_FLAG_DEBUG)
(WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_DROP | WINDIVERT_FLAG_RECV_ONLY |\
WINDIVERT_FLAG_SEND_ONLY | WINDIVERT_FLAG_DEBUG)
#define WINDIVERT_FLAGS_EXCLUDE(flags, flag1, flag2) \
(((flags) & ((flag1) | (flag2))) != ((flag1) | (flag2)))
#define WINDIVERT_FLAGS_VALID(flags) \
((((flags) & ~WINDIVERT_FLAGS_ALL) == 0) && \
WINDIVERT_FLAGS_EXCLUDE(flags, WINDIVERT_FLAG_SNIFF, \
WINDIVERT_FLAG_DROP))
WINDIVERT_FLAG_DROP) && \
WINDIVERT_FLAGS_EXCLUDE(flags, WINDIVERT_FLAG_RECV_ONLY, \
WINDIVERT_FLAG_SEND_ONLY))
/*
* WinDivert priorities.
@@ -197,7 +204,7 @@ typedef struct windivert_ioctl_s *windivert_ioctl_t;
*/
struct windivert_ioctl_filter_s
{
UINT8 field; // WINDIVERT_FILTER_FIELD_IP_*
UINT8 field; // WINDIVERT_FILTER_FIELD_*
UINT8 test; // WINDIVERT_FILTER_TEST_*
UINT16 success; // Success continuation.
UINT16 failure; // Fail continuation.
@@ -210,20 +217,20 @@ typedef struct windivert_ioctl_filter_s *windivert_ioctl_filter_t;
* IOCTL codes.
*/
#define IOCTL_WINDIVERT_RECV \
CTL_CODE(FILE_DEVICE_NETWORK, 0x908, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
CTL_CODE(FILE_DEVICE_NETWORK, 0x918, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_WINDIVERT_SEND \
CTL_CODE(FILE_DEVICE_NETWORK, 0x909, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
CTL_CODE(FILE_DEVICE_NETWORK, 0x919, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_WINDIVERT_START_FILTER \
CTL_CODE(FILE_DEVICE_NETWORK, 0x90A, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
CTL_CODE(FILE_DEVICE_NETWORK, 0x91A, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_WINDIVERT_SET_LAYER \
CTL_CODE(FILE_DEVICE_NETWORK, 0x90B, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
CTL_CODE(FILE_DEVICE_NETWORK, 0x91B, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_WINDIVERT_SET_PRIORITY \
CTL_CODE(FILE_DEVICE_NETWORK, 0x90C, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
CTL_CODE(FILE_DEVICE_NETWORK, 0x91C, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_WINDIVERT_SET_FLAGS \
CTL_CODE(FILE_DEVICE_NETWORK, 0x90D, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
CTL_CODE(FILE_DEVICE_NETWORK, 0x91D, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_WINDIVERT_SET_PARAM \
CTL_CODE(FILE_DEVICE_NETWORK, 0x90E, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
CTL_CODE(FILE_DEVICE_NETWORK, 0x91E, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_WINDIVERT_GET_PARAM \
CTL_CODE(FILE_DEVICE_NETWORK, 0x90F, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
CTL_CODE(FILE_DEVICE_NETWORK, 0x91F, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#endif /* __WINDIVERT_DEVICE_H */
+4
View File
@@ -97,6 +97,10 @@ do
$CC -s -O2 -Iinclude/ examples/streamdump/streamdump.c \
-o "install/MINGW/$CPU/streamdump.exe" -lWinDivert -lws2_32 \
-L"install/MINGW/$CPU/"
echo "\tcopy install/MINGW/$CPU/flowtrack.exe..."
$CC -s -O2 -Iinclude/ examples/flowtrack/flowtrack.c \
-o "install/MINGW/$CPU/flowtrack.exe" -lWinDivert -lws2_32 -lpsapi \
-lshlwapi -L"install/MINGW/$CPU/"
echo "\tcopy install/MINGW/$CPU/WinDivert$BITS.sys..."
cp install/WDDK/$CPU/WinDivert$BITS.sys install/MINGW/$CPU
else
+4
View File
@@ -90,6 +90,8 @@ do
cp install/$TARGET/i386/webfilter.exe $INSTALL/x86
echo "\tcopy $INSTALL/x86/streamdump.exe..."
cp install/$TARGET/i386/streamdump.exe $INSTALL/x86
echo "\tcopy $INSTALL/i386/flowtrack.exe..."
cp install/$TARGET/i386/flowtrack.exe $INSTALL/amd64
if [ -d "install/$TARGET/amd64" ]
then
echo "\tmake $INSTALL/amd64..."
@@ -115,6 +117,8 @@ do
cp install/$TARGET/amd64/webfilter.exe $INSTALL/amd64
echo "\tcopy $INSTALL/amd64/streamdump.exe..."
cp install/$TARGET/amd64/streamdump.exe $INSTALL/amd64
echo "\tcopy $INSTALL/amd64/flowtrack.exe..."
cp install/$TARGET/amd64/flowtrack.exe $INSTALL/amd64
else
echo "\tWARNING: skipping missing AMD64 build..."
fi
+1213 -529
View File
File diff suppressed because it is too large Load Diff