Redesign the WinDivert SOCKET layer.
- Socket (& flow) events are now associated with a endpointId/parentEndpointId pair that allows the tracking of socket operations. - A single socket CLOSE event replaces the UNBIND and DISCONNECT events. - A new flag addr.Sniffed indicates if the event was sniffed or not. Some events (CLOSE) are always sniffed, regardless of the flags. - All filter language numbers are now 128bit. - socketdump.exe can now optionally block events.
This commit is contained in:
@@ -136,16 +136,21 @@ WinDivert 2.0.0-rc
|
||||
* addr.Layer: The WINDIVERT_LAYER_* value for the handle.
|
||||
* addr.Event: A WINDIVERT_EVENT_* value representing the event (see
|
||||
below).
|
||||
* addr.Sniffed: Indicates that the event was sniffed.
|
||||
* addr.Outbound: Replaces addr.Direction.
|
||||
* addr.IPv6: Indicates an IPv6 packet.
|
||||
* addr.Network.IfIdx: Replaces addr.IfIdx.
|
||||
* addr.Network.SubIfIdx: Replaces addr.SubIfIdx.
|
||||
* addr.Flow.EndpointId: The endpoint ID of the flow.
|
||||
* addr.Flow.ParentEndpointId: The parent endpoint ID of the flow.
|
||||
* addr.Flow.ProcessId: The ID of process that created the flow.
|
||||
* addr.Flow.LocalAddr: The flow's local address.
|
||||
* addr.Flow.RemoteAddr: The flow's remote address.
|
||||
* addr.Flow.LocalPort: The flow's local port.
|
||||
* addr.Flow.RemotePort: The flow's remote port.
|
||||
* addr.Flow.Protocol: The flow's protocol.
|
||||
* addr.Socket.EndpointId: The endpoint ID of the operation.
|
||||
* addr.Socket.ParentEndpointId: The parent endpoint ID of the operation.
|
||||
* addr.Socket.ProcessId: The ID of process that created the socket.
|
||||
* addr.Socket.LocalAddr: The socket's local address.
|
||||
* addr.Socket.RemoteAddr: The socket's remote address.
|
||||
@@ -167,17 +172,14 @@ WinDivert 2.0.0-rc
|
||||
deleted.
|
||||
* WINDIVERT_EVENT_SOCKET_BIND: (SOCKET layer) a socket bind()
|
||||
operation occurred.
|
||||
* WINDIVERT_EVENT_SOCKET_UNBIND: (SOCKET layer) a previous binding
|
||||
is removed.
|
||||
operation occurred.
|
||||
* WINDIVERT_EVENT_SOCKET_CONNECT: (SOCKET layer) a socket connect()
|
||||
operation occurred.
|
||||
* WINDIVERT_EVENT_SOCKET_DISCONNECT: (SOCKET layer) a previous
|
||||
connection is terminated.
|
||||
* WINDIVERT_EVENT_SOCKET_LISTEN: (SOCKET layer) a socket listen()
|
||||
operation occurred.
|
||||
* WINDIVERT_EVENT_SOCKET_ACCEPT: (SOCKET layer) a socket accept()
|
||||
operation occurred.
|
||||
* WINDIVERT_EVENT_SOCKET_CLOSE: (SOCKET layer) a socket endpoint is
|
||||
closed.
|
||||
* WINDIVERT_EVENT_REFLECT_OPEN: (REFLECT layer) a WinDivertOpen()
|
||||
operation occurred.
|
||||
* WINDIVERT_EVENT_REFLECT_CLOSE: (REFLECT layer) a WinDivertClose()
|
||||
@@ -227,12 +229,11 @@ WinDivert 2.0.0-rc
|
||||
* ESTABLISHED: (FLOW layer) equal to WINDIVERT_EVENT_FLOW_ESTABLISHED.
|
||||
* DELETED: (FLOW LAYER) equal to WINDIVERT_EVENT_FLOW_DELETED.
|
||||
* BIND: (SOCKET layer) equal to WINDIVERT_EVENT_SOCKET_BIND.
|
||||
* UNBIND: (SOCKET layer) equal to WINDIVERT_EVENT_SOCKET_UNBIND.
|
||||
* CONNECT: (SOCKET layer) equal to WINDIVERT_EVENT_SOCKET_CONNECT.
|
||||
* DISCONNECT: (SOCKET layer) equal to WINDIVERT_EVENT_SOCKET_DISCONNECT.
|
||||
* LISTEN: (SOCKET layer) equal to WINDIVERT_EVENT_SOCKET_LISTEN.
|
||||
* ACCEPT: (SOCKET layer) equal to WINDIVERT_EVENT_SOCKET_ACCEPT.
|
||||
WINDIVERT_LAYER_NETWORK_FORWARD.
|
||||
* CLOSE: (SOCKET layer) equal to WINDIVERT_EVENT_SOCKET_CLOSE.
|
||||
* OPEN: (REFLECT layer) equal to WINDIVERT_EVENT_REFLECT_OPEN.
|
||||
* CLOSE: (REFLECT layer) equal to WINDIVERT_EVENT_REFLECT_CLOSE.
|
||||
* NETWORK: (REFLECT layer) equal to WINDIVERT_LAYER_NETWORK.
|
||||
|
||||
+83
-37
@@ -65,8 +65,10 @@ static BOOLEAN WinDivertStrLen(const wchar_t *s, size_t maxlen,
|
||||
static BOOLEAN WinDivertStrCpy(wchar_t *dst, size_t dstlen,
|
||||
const wchar_t *src);
|
||||
static int WinDivertStrCmp(const char *s, const char *t);
|
||||
static BOOLEAN WinDivertAToI(const char *str, char **endptr, UINT32 *intptr);
|
||||
static BOOLEAN WinDivertAToX(const char *str, char **endptr, UINT32 *intptr);
|
||||
static BOOLEAN WinDivertAToI(const char *str, char **endptr, UINT32 *intptr,
|
||||
UINT size);
|
||||
static BOOLEAN WinDivertAToX(const char *str, char **endptr, UINT32 *intptr,
|
||||
UINT size, BOOL prefix);
|
||||
|
||||
/*
|
||||
* Misc.
|
||||
@@ -379,12 +381,11 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
|
||||
UINT obj_len;
|
||||
ERROR comp_err;
|
||||
DWORD err;
|
||||
BOOL sniff;
|
||||
HANDLE handle;
|
||||
UINT64 filter_flags;
|
||||
WINDIVERT_IOCTL ioctl;
|
||||
WINDIVERT_VERSION version;
|
||||
|
||||
|
||||
// Parameter checking.
|
||||
switch (layer)
|
||||
{
|
||||
@@ -418,8 +419,7 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
sniff = ((flags & WINDIVERT_FLAG_SNIFF) != 0);
|
||||
filter_flags = WinDivertAnalyzeFilter(layer, sniff, object, obj_len);
|
||||
filter_flags = WinDivertAnalyzeFilter(layer, object, obj_len);
|
||||
|
||||
// Attempt to open the WinDivert device:
|
||||
handle = CreateFile(L"\\\\.\\" WINDIVERT_DEVICE_NAME,
|
||||
@@ -711,66 +711,112 @@ static int WinDivertStrCmp(const char *s, const char *t)
|
||||
}
|
||||
}
|
||||
|
||||
static BOOLEAN WinDivertAToI(const char *str, char **endptr, UINT32 *intptr)
|
||||
static BOOLEAN WinDivertMul128(UINT32 *n, UINT32 m)
|
||||
{
|
||||
UINT64 n64 = (UINT64)n[0] * (UINT64)m;
|
||||
n[0] = (UINT32)n64;
|
||||
n64 = (UINT64)n[1] * (UINT64)m + (n64 >> 32);
|
||||
n[1] = (UINT32)n64;
|
||||
n64 = (UINT64)n[2] * (UINT64)m + (n64 >> 32);
|
||||
n[2] = (UINT32)n64;
|
||||
n64 = (UINT64)n[3] * (UINT64)m + (n64 >> 32);
|
||||
n[3] = (UINT32)n64;
|
||||
return ((n64 >> 32) == 0);
|
||||
}
|
||||
|
||||
static BOOLEAN WinDivertAdd128(UINT32 *n, UINT32 a)
|
||||
{
|
||||
UINT64 n64 = (UINT64)n[0] + (UINT64)a;
|
||||
n[0] = (UINT32)n64;
|
||||
n64 = (UINT64)n[1] + (n64 >> 32);
|
||||
n[1] = (UINT32)n64;
|
||||
n64 = (UINT64)n[2] + (n64 >> 32);
|
||||
n[2] = (UINT32)n64;
|
||||
n64 = (UINT64)n[3] + (n64 >> 32);
|
||||
n[3] = (UINT32)n64;
|
||||
return ((n64 >> 32) == 0);
|
||||
}
|
||||
|
||||
static BOOLEAN WinDivertAToI(const char *str, char **endptr, UINT32 *intptr,
|
||||
UINT size)
|
||||
{
|
||||
size_t i = 0;
|
||||
UINT32 num = 0, num0;
|
||||
if (str[i] == '\0')
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
UINT32 n[4] = {0};
|
||||
BOOLEAN result = TRUE;
|
||||
for (; str[i] && isdigit(str[i]); i++)
|
||||
{
|
||||
num0 = num;
|
||||
num *= 10;
|
||||
num += (UINT32)(str[i] - '0');
|
||||
if (num0 > num)
|
||||
if (!WinDivertMul128(n, 10) || !WinDivertAdd128(n, str[i] - '0'))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (i == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (endptr != NULL)
|
||||
{
|
||||
*endptr = (char *)str + i;
|
||||
}
|
||||
*intptr = num;
|
||||
return TRUE;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
intptr[i] = n[i];
|
||||
}
|
||||
for (; result && i < size && i < 4; i++)
|
||||
{
|
||||
result = result && (n[i] == 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static BOOLEAN WinDivertAToX(const char *str, char **endptr, UINT32 *intptr)
|
||||
static BOOLEAN WinDivertAToX(const char *str, char **endptr, UINT32 *intptr,
|
||||
UINT size, BOOL prefix)
|
||||
{
|
||||
size_t i = 0;
|
||||
UINT32 num = 0, num0;
|
||||
if (str[i] == '\0')
|
||||
UINT32 n[4] = {0}, dig;
|
||||
BOOLEAN result = TRUE;
|
||||
if (prefix)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (str[i] == '0' && str[i+1] == 'x')
|
||||
{
|
||||
i += 2;
|
||||
}
|
||||
for (; str[i] && WinDivertIsXDigit(str[i]); i++)
|
||||
{
|
||||
num0 = num;
|
||||
num *= 16;
|
||||
if (isdigit(str[i]))
|
||||
if (str[i] == '0' && str[i+1] == 'x')
|
||||
{
|
||||
num += (UINT32)(str[i] - '0');
|
||||
i += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
num += (UINT32)(WinDivertToLower(str[i]) - 'a') + 0x0A;
|
||||
return FALSE;
|
||||
}
|
||||
if (num0 > num)
|
||||
}
|
||||
for (; str[i] && WinDivertIsXDigit(str[i]); i++)
|
||||
{
|
||||
if (isdigit(str[i]))
|
||||
{
|
||||
dig = (UINT32)(str[i] - '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
dig = (UINT32)(WinDivertToLower(str[i]) - 'a') + 0x0A;
|
||||
}
|
||||
if (!WinDivertMul128(n, 16) || !WinDivertAdd128(n, dig))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (i == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (endptr != NULL)
|
||||
{
|
||||
*endptr = (char *)str + i;
|
||||
}
|
||||
*intptr = num;
|
||||
return TRUE;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
intptr[i] = n[i];
|
||||
}
|
||||
for (; result && i < size && i < 4; i++)
|
||||
{
|
||||
result = result && (n[i] == 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+222
-105
@@ -136,6 +136,8 @@ typedef enum
|
||||
TOKEN_LOCAL_PORT,
|
||||
TOKEN_REMOTE_PORT,
|
||||
TOKEN_PROTOCOL,
|
||||
TOKEN_ENDPOINT_ID,
|
||||
TOKEN_PARENT_ENDPOINT_ID,
|
||||
TOKEN_LAYER,
|
||||
TOKEN_PRIORITY,
|
||||
TOKEN_FLOW,
|
||||
@@ -147,9 +149,7 @@ typedef enum
|
||||
TOKEN_EVENT_ESTABLISHED,
|
||||
TOKEN_EVENT_DELETED,
|
||||
TOKEN_EVENT_BIND,
|
||||
TOKEN_EVENT_UNBIND,
|
||||
TOKEN_EVENT_CONNECT,
|
||||
TOKEN_EVENT_DISCONNECT,
|
||||
TOKEN_EVENT_LISTEN,
|
||||
TOKEN_EVENT_ACCEPT,
|
||||
TOKEN_EVENT_OPEN,
|
||||
@@ -181,7 +181,7 @@ typedef struct
|
||||
UINT pos;
|
||||
UINT32 val[4];
|
||||
} TOKEN;
|
||||
#define TOKEN_MAXLEN 32
|
||||
#define TOKEN_MAXLEN 40
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -216,6 +216,10 @@ typedef struct
|
||||
#define LN_FS_ (WINDIVERT_LAYER_FLAG_NETWORK | \
|
||||
WINDIVERT_LAYER_FLAG_FLOW | \
|
||||
WINDIVERT_LAYER_FLAG_SOCKET)
|
||||
#define L__FS_ (WINDIVERT_LAYER_FLAG_FLOW | \
|
||||
WINDIVERT_LAYER_FLAG_SOCKET)
|
||||
#define L___SR (WINDIVERT_LAYER_FLAG_SOCKET | \
|
||||
WINDIVERT_LAYER_FLAG_REFLECT)
|
||||
#define L__FSR (WINDIVERT_LAYER_FLAG_FLOW | \
|
||||
WINDIVERT_LAYER_FLAG_SOCKET | \
|
||||
WINDIVERT_LAYER_FLAG_REFLECT)
|
||||
@@ -241,7 +245,7 @@ struct EXPR
|
||||
};
|
||||
UINT8 kind;
|
||||
UINT8 count;
|
||||
BOOL neg;
|
||||
BOOLEAN neg;
|
||||
UINT16 succ;
|
||||
UINT16 fail;
|
||||
};
|
||||
@@ -281,6 +285,7 @@ static PEXPR WinDivertParseFilter(HANDLE pool, TOKEN *toks, UINT *i,
|
||||
INT depth, BOOL and, PERROR error);
|
||||
static BOOL WinDivertCondExecFilter(PWINDIVERT_FILTER filter, UINT length,
|
||||
UINT8 field, UINT32 arg);
|
||||
static int WinDivertBigNumCompare(const UINT32 *a, const UINT32 *b, BOOL big);
|
||||
static BOOL WinDivertDeserializeFilter(PWINDIVERT_STREAM stream,
|
||||
PWINDIVERT_FILTER filter, UINT *length);
|
||||
static void WinDivertFormatExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
@@ -302,7 +307,7 @@ extern BOOL WinDivertHelperParseIPv4Address(const char *str, UINT32 *addr_ptr)
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (!WinDivertAToI(str, (char **)&str, &part) || part > UINT8_MAX)
|
||||
if (!WinDivertAToI(str, (char **)&str, &part, 1) || part > UINT8_MAX)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
@@ -396,7 +401,7 @@ extern BOOL WinDivertHelperParseIPv6Address(const char *str, UINT32 *addr_ptr)
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
WinDivertAToX(part_str, NULL, &part);
|
||||
WinDivertAToX(part_str, NULL, &part, /*size=*/1, /*prefix=*/FALSE);
|
||||
if (left)
|
||||
{
|
||||
laddr[i++] = (UINT16)part;
|
||||
@@ -516,15 +521,9 @@ static BOOL WinDivertExpandMacro(KIND kind, WINDIVERT_LAYER layer,
|
||||
case TOKEN_EVENT_BIND:
|
||||
*val = WINDIVERT_EVENT_SOCKET_BIND;
|
||||
return (layer == WINDIVERT_LAYER_SOCKET);
|
||||
case TOKEN_EVENT_UNBIND:
|
||||
*val = WINDIVERT_EVENT_SOCKET_UNBIND;
|
||||
return (layer == WINDIVERT_LAYER_SOCKET);
|
||||
case TOKEN_EVENT_CONNECT:
|
||||
*val = WINDIVERT_EVENT_SOCKET_CONNECT;
|
||||
return (layer == WINDIVERT_LAYER_SOCKET);
|
||||
case TOKEN_EVENT_DISCONNECT:
|
||||
*val = WINDIVERT_EVENT_SOCKET_DISCONNECT;
|
||||
return (layer == WINDIVERT_LAYER_SOCKET);
|
||||
case TOKEN_EVENT_LISTEN:
|
||||
*val = WINDIVERT_EVENT_SOCKET_LISTEN;
|
||||
return (layer == WINDIVERT_LAYER_SOCKET);
|
||||
@@ -535,8 +534,17 @@ static BOOL WinDivertExpandMacro(KIND kind, WINDIVERT_LAYER layer,
|
||||
*val = WINDIVERT_EVENT_REFLECT_OPEN;
|
||||
return (layer == WINDIVERT_LAYER_REFLECT);
|
||||
case TOKEN_EVENT_CLOSE:
|
||||
*val = WINDIVERT_EVENT_REFLECT_CLOSE;
|
||||
return (layer == WINDIVERT_LAYER_REFLECT);
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_SOCKET:
|
||||
*val = WINDIVERT_EVENT_SOCKET_CLOSE;
|
||||
return TRUE;
|
||||
case WINDIVERT_LAYER_REFLECT:
|
||||
*val = WINDIVERT_EVENT_REFLECT_CLOSE;
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
@@ -552,10 +560,9 @@ static ERROR WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer,
|
||||
{
|
||||
{"ACCEPT", TOKEN_EVENT_ACCEPT, L___S_},
|
||||
{"BIND", TOKEN_EVENT_BIND, L___S_},
|
||||
{"CLOSE", TOKEN_EVENT_CLOSE, L____R},
|
||||
{"CLOSE", TOKEN_EVENT_CLOSE, L___SR},
|
||||
{"CONNECT", TOKEN_EVENT_CONNECT, L___S_},
|
||||
{"DELETED", TOKEN_EVENT_DELETED, L__F__},
|
||||
{"DISCONNECT", TOKEN_EVENT_DISCONNECT, L___S_},
|
||||
{"ESTABLISHED", TOKEN_EVENT_ESTABLISHED, L__F__},
|
||||
{"FLOW", TOKEN_FLOW, L____R},
|
||||
{"LISTEN", TOKEN_EVENT_LISTEN, L___S_},
|
||||
@@ -565,8 +572,8 @@ static ERROR WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer,
|
||||
{"PACKET", TOKEN_EVENT_PACKET, LNM___},
|
||||
{"REFLECT", TOKEN_REFLECT, L____R},
|
||||
{"SOCKET", TOKEN_SOCKET, L____R},
|
||||
{"UNBIND", TOKEN_EVENT_UNBIND, L___S_},
|
||||
{"and", TOKEN_AND, LNMFSR},
|
||||
{"endpointId", TOKEN_ENDPOINT_ID, L__FS_},
|
||||
{"event", TOKEN_EVENT, LNMFSR},
|
||||
{"false", TOKEN_FALSE, LNMFSR},
|
||||
{"icmp", TOKEN_ICMP, LNMFS_},
|
||||
@@ -613,6 +620,7 @@ static ERROR WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer,
|
||||
{"packet", TOKEN_PACKET, LNM___},
|
||||
{"packet16", TOKEN_PACKET16, LNM___},
|
||||
{"packet32", TOKEN_PACKET32, LNM___},
|
||||
{"parentEndpointId", TOKEN_PARENT_ENDPOINT_ID, L__FS_},
|
||||
{"priority", TOKEN_PRIORITY, L____R},
|
||||
{"processId", TOKEN_PROCESS_ID, L__FSR},
|
||||
{"protocol", TOKEN_PROTOCOL, LN_FS_},
|
||||
@@ -762,7 +770,7 @@ static ERROR WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer,
|
||||
token[0] = c;
|
||||
if (WinDivertIsAlNum(c) || c == '.' || c == ':' || c == '_')
|
||||
{
|
||||
UINT32 num;
|
||||
UINT32 num[4];
|
||||
char *end;
|
||||
for (j = 1; j < TOKEN_MAXLEN && (WinDivertIsAlNum(filter[i]) ||
|
||||
filter[i] == '.' || filter[i] == ':' || filter[i] == '_');
|
||||
@@ -808,17 +816,25 @@ static ERROR WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer,
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for 'b':
|
||||
if (token[0] == 'b' && token[1] == '\0')
|
||||
{
|
||||
tokens[tp].kind = TOKEN_BYTES;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for base 10 number:
|
||||
if (WinDivertAToI(token, &end, &num))
|
||||
if (WinDivertAToI(token, &end, num, sizeof(num)/sizeof(num[0])))
|
||||
{
|
||||
BOOL b = (*end == 'b' && *(end+1) == '\0');
|
||||
if (*end == '\0' || b)
|
||||
{
|
||||
tokens[tp].kind = TOKEN_NUMBER;
|
||||
tokens[tp].val[0] = num;
|
||||
tokens[tp].kind = TOKEN_NUMBER;
|
||||
memcpy(tokens[tp].val, num, sizeof(tokens[tp].val));
|
||||
tp++;
|
||||
if (b)
|
||||
{
|
||||
memset(tokens[tp].val, 0, sizeof(tokens[tp].val));
|
||||
tokens[tp].kind = TOKEN_BYTES;
|
||||
tp++;
|
||||
}
|
||||
@@ -828,13 +844,16 @@ static ERROR WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer,
|
||||
|
||||
// Check for base 16 number:
|
||||
if (token[0] == '0' && token[1] == 'x' &&
|
||||
WinDivertAToX(token, &end, &num) && *end == '\0')
|
||||
WinDivertAToX(token, &end, num, sizeof(num)/sizeof(num[0]),
|
||||
/*prefix=*/TRUE) &&
|
||||
*end == '\0')
|
||||
{
|
||||
tokens[tp].kind = TOKEN_NUMBER;
|
||||
tokens[tp].val[0] = num;
|
||||
tokens[tp].kind = TOKEN_NUMBER;
|
||||
memcpy(tokens[tp].val, num, sizeof(tokens[tp].val));
|
||||
tp++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for IPv4 address:
|
||||
if (WinDivertHelperParseIPv4Address(token, tokens[tp].val))
|
||||
{
|
||||
@@ -942,6 +961,8 @@ static PEXPR WinDivertMakeVar(KIND kind, PERROR error)
|
||||
{{{0}}, TOKEN_LOCAL_PORT},
|
||||
{{{0}}, TOKEN_REMOTE_PORT},
|
||||
{{{0}}, TOKEN_PROTOCOL},
|
||||
{{{0}}, TOKEN_ENDPOINT_ID},
|
||||
{{{0}}, TOKEN_PARENT_ENDPOINT_ID},
|
||||
{{{0}}, TOKEN_LAYER},
|
||||
{{{0}}, TOKEN_PRIORITY},
|
||||
};
|
||||
@@ -1098,6 +1119,8 @@ static PEXPR WinDivertParseTest(HANDLE pool, TOKEN *toks, UINT *i, PERROR error)
|
||||
case TOKEN_LOCAL_PORT:
|
||||
case TOKEN_REMOTE_PORT:
|
||||
case TOKEN_PROTOCOL:
|
||||
case TOKEN_ENDPOINT_ID:
|
||||
case TOKEN_PARENT_ENDPOINT_ID:
|
||||
case TOKEN_LAYER:
|
||||
case TOKEN_IP_HDR_LENGTH:
|
||||
case TOKEN_IP_TOS:
|
||||
@@ -1182,7 +1205,7 @@ static PEXPR WinDivertParseTest(HANDLE pool, TOKEN *toks, UINT *i, PERROR error)
|
||||
goto unexpected_token;
|
||||
}
|
||||
if (toks[*i].val[3] != 0 || toks[*i].val[2] != 0 ||
|
||||
toks[*i].val[1] != 0 || toks[*i].val[0] > UINT16_MAX)
|
||||
toks[*i].val[1] != 0 || toks[*i].val[0] > WINDIVERT_MTU_MAX)
|
||||
{
|
||||
*error = MAKE_ERROR(WINDIVERT_ERROR_INDEX_OOB, toks[*i].pos);
|
||||
return NULL;
|
||||
@@ -1385,28 +1408,29 @@ static BOOL WinDivertEvalTest(PEXPR test, BOOL *res)
|
||||
{
|
||||
PEXPR var = test->arg[0];
|
||||
PEXPR val = test->arg[1];
|
||||
UINT32 val32 = val->val[0];
|
||||
BOOL big = (val->val[1] != 0 || val->val[2] != 0 || val->val[3] != 0);
|
||||
UINT32 lb, ub;
|
||||
UINT32 lb[4] = {0}, ub[4] = {0};
|
||||
int result_lb, result_ub;
|
||||
BOOL eq = FALSE;
|
||||
|
||||
switch (var->kind)
|
||||
{
|
||||
case TOKEN_ZERO:
|
||||
lb = ub = 0;
|
||||
case TOKEN_FALSE:
|
||||
eq = TRUE;
|
||||
lb[0] = ub[0] = 0;
|
||||
break;
|
||||
case TOKEN_TRUE:
|
||||
lb = ub = 1;
|
||||
break;
|
||||
case TOKEN_FALSE:
|
||||
lb = ub = 0;
|
||||
eq = TRUE;
|
||||
lb[0] = ub[0] = 1;
|
||||
break;
|
||||
case TOKEN_LAYER:
|
||||
lb = 0; ub = WINDIVERT_LAYER_MAX;
|
||||
lb[0] = 0; ub[0] = WINDIVERT_LAYER_MAX;
|
||||
break;
|
||||
case TOKEN_PRIORITY:
|
||||
lb = 0; ub = WINDIVERT_PRIORITY_MAX;
|
||||
lb[0] = 0; ub[0] = WINDIVERT_PRIORITY_MAX;
|
||||
break;
|
||||
case TOKEN_EVENT:
|
||||
lb = 0; ub = WINDIVERT_EVENT_MAX;
|
||||
lb[0] = 0; ub[0] = WINDIVERT_EVENT_MAX;
|
||||
break;
|
||||
case TOKEN_INBOUND:
|
||||
case TOKEN_OUTBOUND:
|
||||
@@ -1424,11 +1448,11 @@ static BOOL WinDivertEvalTest(PEXPR test, BOOL *res)
|
||||
case TOKEN_TCP_RST:
|
||||
case TOKEN_TCP_SYN:
|
||||
case TOKEN_TCP_FIN:
|
||||
lb = 0; ub = 1;
|
||||
lb[0] = 0; ub[0] = 1;
|
||||
break;
|
||||
case TOKEN_IP_HDR_LENGTH:
|
||||
case TOKEN_TCP_HDR_LENGTH:
|
||||
lb = 0; ub = 0x0F;
|
||||
lb[0] = 0; ub[0] = 0x0F;
|
||||
break;
|
||||
case TOKEN_IP_TTL:
|
||||
case TOKEN_IP_PROTOCOL:
|
||||
@@ -1444,10 +1468,10 @@ static BOOL WinDivertEvalTest(PEXPR test, BOOL *res)
|
||||
case TOKEN_TCP_PAYLOAD:
|
||||
case TOKEN_UDP_PAYLOAD:
|
||||
case TOKEN_RANDOM8:
|
||||
lb = 0; ub = 0xFF;
|
||||
lb[0] = 0; ub[0] = 0xFF;
|
||||
break;
|
||||
case TOKEN_IP_FRAG_OFF:
|
||||
lb = 0; ub = 0x1FFF;
|
||||
lb[0] = 0; ub[0] = 0x1FFF;
|
||||
break;
|
||||
case TOKEN_IP_TOS:
|
||||
case TOKEN_IP_LENGTH:
|
||||
@@ -1473,90 +1497,105 @@ static BOOL WinDivertEvalTest(PEXPR test, BOOL *res)
|
||||
case TOKEN_TCP_PAYLOAD16:
|
||||
case TOKEN_UDP_PAYLOAD16:
|
||||
case TOKEN_RANDOM16:
|
||||
lb = 0; ub = 0xFFFF;
|
||||
lb[0] = 0; ub[0] = 0xFFFF;
|
||||
break;
|
||||
case TOKEN_IPV6_FLOW_LABEL:
|
||||
lb = 0; ub = 0x000FFFFF;
|
||||
lb[0] = 0; ub[0] = 0x000FFFFF;
|
||||
break;
|
||||
case TOKEN_IP_SRC_ADDR:
|
||||
case TOKEN_IP_DST_ADDR:
|
||||
lb[0] = 0;
|
||||
lb[1] = 0xFFFF;
|
||||
ub[0] = 0xFFFFFFFF;
|
||||
ub[1] = 0xFFFF;
|
||||
break;
|
||||
case TOKEN_IPV6_SRC_ADDR:
|
||||
case TOKEN_IPV6_DST_ADDR:
|
||||
case TOKEN_LOCAL_ADDR:
|
||||
case TOKEN_REMOTE_ADDR:
|
||||
return FALSE;
|
||||
lb[0] = lb[1] = lb[2] = lb[3] = 0;
|
||||
ub[0] = ub[1] = ub[2] = ub[3] = 0xFFFFFFFF;
|
||||
break;
|
||||
case TOKEN_ENDPOINT_ID:
|
||||
case TOKEN_PARENT_ENDPOINT_ID:
|
||||
lb[0] = lb[1] = 0;
|
||||
ub[0] = ub[1] = 0xFFFFFFFF;
|
||||
break;
|
||||
default:
|
||||
lb = 0; ub = 0xFFFFFFFF;
|
||||
lb[0] = 0; ub[0] = 0xFFFFFFFF;
|
||||
break;
|
||||
}
|
||||
result_lb = WinDivertBigNumCompare(val->val, lb, /*big=*/TRUE);
|
||||
result_ub = WinDivertBigNumCompare(val->val, ub, /*big=*/TRUE);
|
||||
switch (test->kind)
|
||||
{
|
||||
case TOKEN_EQ:
|
||||
if (big || val32 < lb || val32 > ub)
|
||||
if (result_lb < 0 || result_ub > 0)
|
||||
{
|
||||
*res = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
if (lb == ub && val32 == lb)
|
||||
if (eq && result_lb == 0)
|
||||
{
|
||||
*res = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
case TOKEN_NEQ:
|
||||
if (big || val32 < lb || val32 > ub)
|
||||
if (result_lb < 0 || result_ub > 0)
|
||||
{
|
||||
*res = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
if (lb == ub && val32 == lb)
|
||||
if (eq && result_lb == 0)
|
||||
{
|
||||
*res = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
case TOKEN_LT:
|
||||
if (big || val32 > ub)
|
||||
if (result_ub > 0)
|
||||
{
|
||||
*res = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
if (val32 <= lb)
|
||||
if (result_lb <= 0)
|
||||
{
|
||||
*res = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
case TOKEN_LEQ:
|
||||
if (big || val32 >= ub)
|
||||
if (result_ub >= 0)
|
||||
{
|
||||
*res = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
if (val32 < lb)
|
||||
if (result_lb < 0)
|
||||
{
|
||||
*res = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
case TOKEN_GT:
|
||||
if (big || val32 >= ub)
|
||||
if (result_ub >= 0)
|
||||
{
|
||||
*res = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
if (val32 < lb)
|
||||
if (result_lb < 0)
|
||||
{
|
||||
*res = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
case TOKEN_GEQ:
|
||||
if (big || val32 > ub)
|
||||
if (result_ub > 0)
|
||||
{
|
||||
*res = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
if (val32 <= lb)
|
||||
if (result_lb <= 0)
|
||||
{
|
||||
*res = TRUE;
|
||||
return TRUE;
|
||||
@@ -1741,6 +1780,14 @@ static void WinDivertEmitTest(PEXPR test, UINT16 offset,
|
||||
case TOKEN_PROTOCOL:
|
||||
object->field = WINDIVERT_FILTER_FIELD_PROTOCOL;
|
||||
break;
|
||||
case TOKEN_ENDPOINT_ID:
|
||||
object->field = WINDIVERT_FILTER_FIELD_ENDPOINTID;
|
||||
big = TRUE;
|
||||
break;
|
||||
case TOKEN_PARENT_ENDPOINT_ID:
|
||||
object->field = WINDIVERT_FILTER_FIELD_PARENTENDPOINTID;
|
||||
big = TRUE;
|
||||
break;
|
||||
case TOKEN_LAYER:
|
||||
object->field = WINDIVERT_FILTER_FIELD_LAYER;
|
||||
break;
|
||||
@@ -1978,7 +2025,7 @@ static void WinDivertEmitFilter(PEXPR *stack, UINT len, UINT16 label,
|
||||
* Analyze a filter object.
|
||||
*/
|
||||
static UINT64 WinDivertAnalyzeFilter(WINDIVERT_LAYER layer,
|
||||
BOOL sniff, PWINDIVERT_FILTER filter, UINT length)
|
||||
PWINDIVERT_FILTER filter, UINT length)
|
||||
{
|
||||
BOOL result;
|
||||
UINT64 flags = 0;
|
||||
@@ -2051,25 +2098,12 @@ static UINT64 WinDivertAnalyzeFilter(WINDIVERT_LAYER layer,
|
||||
result = WinDivertCondExecFilter(filter, length,
|
||||
WINDIVERT_FILTER_FIELD_EVENT, WINDIVERT_EVENT_SOCKET_BIND);
|
||||
flags |= (result? WINDIVERT_FILTER_FLAG_EVENT_SOCKET_BIND: 0);
|
||||
if (sniff)
|
||||
{
|
||||
result = WinDivertCondExecFilter(filter, length,
|
||||
WINDIVERT_FILTER_FIELD_EVENT,
|
||||
WINDIVERT_EVENT_SOCKET_UNBIND);
|
||||
flags |=
|
||||
(result? WINDIVERT_FILTER_FLAG_EVENT_SOCKET_UNBIND: 0);
|
||||
}
|
||||
result = WinDivertCondExecFilter(filter, length,
|
||||
WINDIVERT_FILTER_FIELD_EVENT, WINDIVERT_EVENT_SOCKET_CONNECT);
|
||||
flags |= (result? WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CONNECT: 0);
|
||||
if (sniff)
|
||||
{
|
||||
result = WinDivertCondExecFilter(filter, length,
|
||||
WINDIVERT_FILTER_FIELD_EVENT,
|
||||
WINDIVERT_EVENT_SOCKET_DISCONNECT);
|
||||
flags |=
|
||||
(result? WINDIVERT_FILTER_FLAG_EVENT_SOCKET_DISCONNECT: 0);
|
||||
}
|
||||
result = WinDivertCondExecFilter(filter, length,
|
||||
WINDIVERT_FILTER_FIELD_EVENT, WINDIVERT_EVENT_SOCKET_CLOSE);
|
||||
flags |= (result? WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CLOSE: 0);
|
||||
result = WinDivertCondExecFilter(filter, length,
|
||||
WINDIVERT_FILTER_FIELD_EVENT, WINDIVERT_EVENT_SOCKET_LISTEN);
|
||||
flags |= (result? WINDIVERT_FILTER_FLAG_EVENT_SOCKET_LISTEN: 0);
|
||||
@@ -2565,6 +2599,11 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
|
||||
addr->Layer == WINDIVERT_LAYER_FLOW ||
|
||||
addr->Layer == WINDIVERT_LAYER_SOCKET);
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_ENDPOINTID:
|
||||
case WINDIVERT_FILTER_FIELD_PARENTENDPOINTID:
|
||||
pass = (addr->Layer == WINDIVERT_LAYER_FLOW ||
|
||||
addr->Layer == WINDIVERT_LAYER_SOCKET);
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_PROCESSID:
|
||||
pass = (addr->Layer == WINDIVERT_LAYER_FLOW ||
|
||||
addr->Layer == WINDIVERT_LAYER_SOCKET ||
|
||||
@@ -3149,6 +3188,42 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_ENDPOINTID:
|
||||
big = TRUE;
|
||||
val[3] = val[2] = 0;
|
||||
switch (addr->Layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_FLOW:
|
||||
val[0] = (UINT32)addr->Flow.EndpointId;
|
||||
val[1] = (UINT32)(addr->Flow.EndpointId >> 32);
|
||||
break;
|
||||
case WINDIVERT_LAYER_SOCKET:
|
||||
val[0] = (UINT32)addr->Socket.EndpointId;
|
||||
val[1] = (UINT32)(addr->Socket.EndpointId >> 32);
|
||||
break;
|
||||
default:
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_PARENTENDPOINTID:
|
||||
big = TRUE;
|
||||
val[3] = val[2] = 0;
|
||||
switch (addr->Layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_FLOW:
|
||||
val[0] = (UINT32)addr->Flow.ParentEndpointId;
|
||||
val[1] = (UINT32)(addr->Flow.ParentEndpointId >> 32);
|
||||
break;
|
||||
case WINDIVERT_LAYER_SOCKET:
|
||||
val[0] = (UINT32)addr->Socket.ParentEndpointId;
|
||||
val[1] = (UINT32)(addr->Socket.ParentEndpointId >> 32);
|
||||
break;
|
||||
default:
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_PROCESSID:
|
||||
switch (addr->Layer)
|
||||
{
|
||||
@@ -3344,6 +3419,14 @@ static BOOL WinDivertDeserializeTest(PWINDIVERT_STREAM stream,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_ENDPOINTID:
|
||||
case WINDIVERT_FILTER_FIELD_PARENTENDPOINTID:
|
||||
if (!WinDivertDeserializeNumber(stream, 7, &filter->arg[1]))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
filter->arg[2] = filter->arg[3] = 0;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_IP_SRCADDR:
|
||||
case WINDIVERT_FILTER_FIELD_IP_DSTADDR:
|
||||
filter->arg[1] = 0x0000FFFF;
|
||||
@@ -3641,6 +3724,10 @@ static PEXPR WinDivertDecompileTest(HANDLE pool, PWINDIVERT_FILTER test)
|
||||
kind = TOKEN_REMOTE_PORT; break;
|
||||
case WINDIVERT_FILTER_FIELD_PROTOCOL:
|
||||
kind = TOKEN_PROTOCOL; break;
|
||||
case WINDIVERT_FILTER_FIELD_ENDPOINTID:
|
||||
kind = TOKEN_ENDPOINT_ID; break;
|
||||
case WINDIVERT_FILTER_FIELD_PARENTENDPOINTID:
|
||||
kind = TOKEN_PARENT_ENDPOINT_ID; break;
|
||||
case WINDIVERT_FILTER_FIELD_LAYER:
|
||||
kind = TOKEN_LAYER; break;
|
||||
case WINDIVERT_FILTER_FIELD_PRIORITY:
|
||||
@@ -3686,7 +3773,7 @@ static PEXPR WinDivertDecompileTest(HANDLE pool, PWINDIVERT_FILTER test)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
switch (test->test)
|
||||
{
|
||||
case WINDIVERT_FILTER_TEST_EQ:
|
||||
@@ -3956,9 +4043,9 @@ static PEXPR WinDivertCoalesceExpr(HANDLE pool, PEXPR *exprs, UINT8 i)
|
||||
/*
|
||||
* Format a decimal number.
|
||||
*/
|
||||
static void WinDivertFormatNumber(PWINDIVERT_STREAM stream, UINT32 val)
|
||||
static void WinDivertFormatDecNumber(PWINDIVERT_STREAM stream, UINT64 val)
|
||||
{
|
||||
UINT64 r = 1000000000, dig;
|
||||
UINT64 r = 10000000000000000000ull, dig;
|
||||
BOOL zeroes = FALSE;
|
||||
|
||||
while (r != 0)
|
||||
@@ -3978,22 +4065,48 @@ static void WinDivertFormatNumber(PWINDIVERT_STREAM stream, UINT32 val)
|
||||
/*
|
||||
* Format a hexidecimal number.
|
||||
*/
|
||||
static void WinDivertFormatHexNumber(PWINDIVERT_STREAM stream, UINT32 val)
|
||||
static void WinDivertFormatHexNumber(PWINDIVERT_STREAM stream, UINT32 *val)
|
||||
{
|
||||
INT s = 28;
|
||||
INT i, s;
|
||||
UINT32 dig;
|
||||
BOOL zeroes = FALSE;
|
||||
|
||||
while (s >= 0)
|
||||
for (i = 3; val[i] == 0 && i >= 1; i--)
|
||||
;
|
||||
for (; i >= 0; i--)
|
||||
{
|
||||
dig = (val & ((UINT32)0xF << s)) >> s;
|
||||
s -= 4;
|
||||
if (dig == 0 && !zeroes && s >= 0)
|
||||
s = 28;
|
||||
while (s >= 0)
|
||||
{
|
||||
continue;
|
||||
dig = (val[i] & ((UINT32)0xF << s)) >> s;
|
||||
s -= 4;
|
||||
if (dig == 0 && !zeroes)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
WinDivertPutChar(stream, (dig <= 9? '0' + dig: 'a' + (dig - 10)));
|
||||
zeroes = TRUE;
|
||||
}
|
||||
WinDivertPutChar(stream, (dig <= 9? '0' + dig: 'a' + (dig - 10)));
|
||||
zeroes = TRUE;
|
||||
}
|
||||
if (!zeroes)
|
||||
{
|
||||
WinDivertPutChar(stream, '0');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Format a big number.
|
||||
*/
|
||||
static void WinDivertFormatNumber(PWINDIVERT_STREAM stream, UINT32 *val)
|
||||
{
|
||||
if (val[2] == 0 && val[3] == 0)
|
||||
{
|
||||
UINT64 val64 = ((UINT64)val[1] << 32) | (UINT64)val[0];
|
||||
WinDivertFormatDecNumber(stream, val64);
|
||||
}
|
||||
else
|
||||
{
|
||||
WinDivertFormatHexNumber(stream, val);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4002,13 +4115,13 @@ static void WinDivertFormatHexNumber(PWINDIVERT_STREAM stream, UINT32 val)
|
||||
*/
|
||||
static void WinDivertFormatIPv4Addr(PWINDIVERT_STREAM stream, UINT32 addr)
|
||||
{
|
||||
WinDivertFormatNumber(stream, (addr & 0xFF000000) >> 24);
|
||||
WinDivertFormatDecNumber(stream, (addr & 0xFF000000) >> 24);
|
||||
WinDivertPutChar(stream, '.');
|
||||
WinDivertFormatNumber(stream, (addr & 0x00FF0000) >> 16);
|
||||
WinDivertFormatDecNumber(stream, (addr & 0x00FF0000) >> 16);
|
||||
WinDivertPutChar(stream, '.');
|
||||
WinDivertFormatNumber(stream, (addr & 0x0000FF00) >> 8);
|
||||
WinDivertFormatDecNumber(stream, (addr & 0x0000FF00) >> 8);
|
||||
WinDivertPutChar(stream, '.');
|
||||
WinDivertFormatNumber(stream, (addr & 0x000000FF) >> 0);
|
||||
WinDivertFormatDecNumber(stream, (addr & 0x000000FF) >> 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4019,6 +4132,7 @@ static void WinDivertFormatIPv6Addr(PWINDIVERT_STREAM stream,
|
||||
{
|
||||
INT i, z_curr, z_count, z_start, z_max;
|
||||
UINT16 addr[8];
|
||||
UINT32 part[4] = {0};
|
||||
|
||||
// IPv4 special case:
|
||||
if (addr32[3] == 0 && addr32[2] == 0 && addr32[1] == 0x0000FFFF)
|
||||
@@ -4056,7 +4170,8 @@ static void WinDivertFormatIPv6Addr(PWINDIVERT_STREAM stream,
|
||||
i -= (z_max-1);
|
||||
continue;
|
||||
}
|
||||
WinDivertFormatHexNumber(stream, addr[i]);
|
||||
part[0] = (UINT32)addr[i];
|
||||
WinDivertFormatHexNumber(stream, part);
|
||||
WinDivertPutString(stream, (i != 0? ":": ""));
|
||||
}
|
||||
}
|
||||
@@ -4235,7 +4350,7 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
case WINDIVERT_LAYER_REFLECT:
|
||||
WinDivertPutString(stream, "REFLECT"); break;
|
||||
default:
|
||||
WinDivertFormatNumber(stream, val->val[0]); break;
|
||||
WinDivertFormatDecNumber(stream, val->val[0]); break;
|
||||
}
|
||||
}
|
||||
else if (is_priority)
|
||||
@@ -4246,7 +4361,7 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
{
|
||||
WinDivertPutChar(stream, '-');
|
||||
}
|
||||
WinDivertFormatNumber(stream, (val32 < 0? -val32: val32));
|
||||
WinDivertFormatDecNumber(stream, (val32 < 0? -val32: val32));
|
||||
}
|
||||
else if (is_event)
|
||||
{
|
||||
@@ -4260,7 +4375,7 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
}
|
||||
else
|
||||
{
|
||||
WinDivertFormatNumber(stream, val->val[0]);
|
||||
WinDivertFormatDecNumber(stream, val->val[0]);
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_LAYER_FLOW:
|
||||
@@ -4271,7 +4386,7 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
case WINDIVERT_EVENT_FLOW_DELETED:
|
||||
WinDivertPutString(stream, "DELETED"); break;
|
||||
default:
|
||||
WinDivertFormatNumber(stream, val->val[0]); break;
|
||||
WinDivertFormatDecNumber(stream, val->val[0]); break;
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_LAYER_SOCKET:
|
||||
@@ -4279,18 +4394,16 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
{
|
||||
case WINDIVERT_EVENT_SOCKET_BIND:
|
||||
WinDivertPutString(stream, "BIND"); break;
|
||||
case WINDIVERT_EVENT_SOCKET_UNBIND:
|
||||
WinDivertPutString(stream, "UNBIND"); break;
|
||||
case WINDIVERT_EVENT_SOCKET_CONNECT:
|
||||
WinDivertPutString(stream, "CONNECT"); break;
|
||||
case WINDIVERT_EVENT_SOCKET_DISCONNECT:
|
||||
WinDivertPutString(stream, "DISCONNECT"); break;
|
||||
case WINDIVERT_EVENT_SOCKET_LISTEN:
|
||||
WinDivertPutString(stream, "LISTEN"); break;
|
||||
case WINDIVERT_EVENT_SOCKET_ACCEPT:
|
||||
WinDivertPutString(stream, "ACCEPT"); break;
|
||||
case WINDIVERT_EVENT_SOCKET_CLOSE:
|
||||
WinDivertPutString(stream, "CLOSE"); break;
|
||||
default:
|
||||
WinDivertFormatNumber(stream, val->val[0]); break;
|
||||
WinDivertFormatDecNumber(stream, val->val[0]); break;
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_LAYER_REFLECT:
|
||||
@@ -4301,21 +4414,21 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
case WINDIVERT_EVENT_REFLECT_CLOSE:
|
||||
WinDivertPutString(stream, "CLOSE"); break;
|
||||
default:
|
||||
WinDivertFormatNumber(stream, val->val[0]); break;
|
||||
WinDivertFormatDecNumber(stream, val->val[0]); break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WinDivertFormatNumber(stream, val->val[0]); break;
|
||||
WinDivertFormatDecNumber(stream, val->val[0]); break;
|
||||
}
|
||||
}
|
||||
else if (is_hex)
|
||||
{
|
||||
WinDivertPutString(stream, "0x");
|
||||
WinDivertFormatHexNumber(stream, val->val[0]);
|
||||
WinDivertFormatHexNumber(stream, val->val);
|
||||
}
|
||||
else
|
||||
{
|
||||
WinDivertFormatNumber(stream, val->val[0]);
|
||||
WinDivertFormatNumber(stream, val->val);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4548,12 +4661,16 @@ static void WinDivertFormatExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
WinDivertPutString(stream, "remotePort"); return;
|
||||
case TOKEN_PROTOCOL:
|
||||
WinDivertPutString(stream, "protocol"); return;
|
||||
case TOKEN_ENDPOINT_ID:
|
||||
WinDivertPutString(stream, "endpointId"); return;
|
||||
case TOKEN_PARENT_ENDPOINT_ID:
|
||||
WinDivertPutString(stream, "parentEndpointId"); return;
|
||||
case TOKEN_LAYER:
|
||||
WinDivertPutString(stream, "layer"); return;
|
||||
case TOKEN_PRIORITY:
|
||||
WinDivertPutString(stream, "priority"); return;
|
||||
case TOKEN_NUMBER:
|
||||
WinDivertFormatNumber(stream, expr->val[0]); return;
|
||||
WinDivertFormatNumber(stream, expr->val); return;
|
||||
}
|
||||
|
||||
WinDivertPutChar(stream, '[');
|
||||
@@ -4563,7 +4680,7 @@ static void WinDivertFormatExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
WinDivertPutChar(stream, '-');
|
||||
idx = -idx;
|
||||
}
|
||||
WinDivertFormatNumber(stream, (UINT32)idx);
|
||||
WinDivertFormatDecNumber(stream, (UINT64)idx);
|
||||
WinDivertPutString(stream, "b]");
|
||||
}
|
||||
|
||||
|
||||
@@ -207,6 +207,10 @@ static void WinDivertSerializeTest(PWINDIVERT_STREAM stream,
|
||||
WinDivertSerializeNumber(stream, filter->arg[i]);
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_ENDPOINTID:
|
||||
case WINDIVERT_FILTER_FIELD_PARENTENDPOINTID:
|
||||
WinDivertSerializeNumber(stream, filter->arg[1]);
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_PACKET:
|
||||
case WINDIVERT_FILTER_FIELD_PACKET16:
|
||||
case WINDIVERT_FILTER_FIELD_PACKET32:
|
||||
|
||||
+32
-24
@@ -428,11 +428,10 @@ typedef enum
|
||||
WINDIVERT_EVENT_FLOW_ESTABLISHED,
|
||||
WINDIVERT_EVENT_FLOW_DELETED,
|
||||
WINDIVERT_EVENT_SOCKET_BIND,
|
||||
WINDIVERT_EVENT_SOCKET_UNBIND,
|
||||
WINDIVERT_EVENT_SOCKET_CONNECT,
|
||||
WINDIVERT_EVENT_SOCKET_DISCONNECT,
|
||||
WINDIVERT_EVENT_SOCKET_LISTEN,
|
||||
WINDIVERT_EVENT_SOCKET_ACCEPT,
|
||||
WINDIVERT_EVENT_SOCKET_CLOSE,
|
||||
WINDIVERT_EVENT_REFLECT_OPEN,
|
||||
WINDIVERT_EVENT_REFLECT_CLOSE,
|
||||
} <b>WINDIVERT_EVENT</b>, *<b>PWINDIVERT_EVENT</b>;
|
||||
@@ -517,14 +516,6 @@ A <code>bind()</code> operation.
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>WINDIVERT_EVENT_SOCKET_UNBIND</code>
|
||||
</td>
|
||||
<td>
|
||||
A previous binding is removed.
|
||||
This event cannot be blocked.
|
||||
</td>
|
||||
<tr>
|
||||
<td>
|
||||
<code>WINDIVERT_EVENT_SOCKET_CONNECT</code>
|
||||
</td>
|
||||
<td>
|
||||
@@ -533,15 +524,6 @@ A <code>connect()</code> operation.
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>WINDIVERT_EVENT_SOCKET_DISCONNECT</code>
|
||||
</td>
|
||||
<td>
|
||||
A previous connection is terminated.
|
||||
This event cannot be blocked.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>WINDIVERT_EVENT_SOCKET_LISTEN</code>
|
||||
</td>
|
||||
<td>
|
||||
@@ -556,6 +538,15 @@ A <code>listen()</code> operation.
|
||||
An <code>accept()</code> operation.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>WINDIVERT_EVENT_SOCKET_CLOSE</code>
|
||||
</td>
|
||||
<td>
|
||||
A socket endpoint is closed.
|
||||
This corresponds to a previous binding being released, or an established
|
||||
connection being terminated.
|
||||
The event cannot be blocked.
|
||||
</table>
|
||||
</center>
|
||||
</li>
|
||||
@@ -602,6 +593,8 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT64 Endpoint;
|
||||
UINT64 ParentEndpoint;
|
||||
UINT32 ProcessId;
|
||||
UINT32 LocalAddr[4];
|
||||
UINT32 RemoteAddr[4];
|
||||
@@ -612,6 +605,8 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT64 Endpoint;
|
||||
UINT64 ParentEndpoint;
|
||||
UINT32 ProcessId;
|
||||
UINT32 LocalAddr[4];
|
||||
UINT32 RemoteAddr[4];
|
||||
@@ -634,6 +629,7 @@ typedef struct
|
||||
INT64 Timestamp;
|
||||
UINT64 Layer:8;
|
||||
UINT64 Event:8;
|
||||
UINT64 Sniffed:1;
|
||||
UINT64 Outbound:1;
|
||||
UINT64 Loopback:1;
|
||||
UINT64 Impostor:1;
|
||||
@@ -657,6 +653,8 @@ typedef struct
|
||||
<li> <code>Timestamp</code>: A timestamp indicating when event occurred.</li>
|
||||
<li> <code>Layer</code>: The handle's layer (<code>WINDIVERT_LAYER_*</code>).</li>
|
||||
<li> <code>Event</code>: The captured event (<code>WINDIVERT_EVENT_*</code>).</li>
|
||||
<li> <code>Sniffed</code>: Set to <code>1</code> if the event was
|
||||
<q>sniffed</q> (i.e., not blocked), <code>0</code> otherwise..</li>
|
||||
<li> <code>Outbound</code>: Set to <code>1</code> for <i>outbound</i>
|
||||
packets/event, <code>0</code> for <i>inbound</i> or otherwise.</li>
|
||||
<li> <code>Loopback</code>: Set to <code>1</code> for loopback packets, <code>0</code>
|
||||
@@ -674,12 +672,19 @@ valid, <code>0</code> otherwise.</li>
|
||||
<li> <code>Network.IfIdx</code>: The interface index on which the packet arrived
|
||||
(for inbound packets), or is to be sent (for outbound packets).</li>
|
||||
<li> <code>Network.SubIfIdx</code>: The sub-interface index for <code>IfIdx</code>.</li>
|
||||
<li> <code>Flow.EndpointId</code>: The endpoint ID of the flow.</li>
|
||||
<li> <code>Flow.ParentEndpointId</code>: The parent endpoint ID of the
|
||||
flow.</li>
|
||||
<li> <code>Flow.ProcessId</code>: The ID of the process associated with the
|
||||
flow.</li>
|
||||
flow.</li>
|
||||
<li> <code>Flow.LocalAddr</code>, <code>Flow.RemoteAddr</code>,
|
||||
<code>Flow.LocalPort</code>, <code>Flow.RemotePort</code>, and
|
||||
<code>Flow.Protocol</code>: The network 5-tuple associated with the
|
||||
flow.</li>
|
||||
<li> <code>Socket.EndpointId</code>: The endpoint ID of the socket
|
||||
operation.</li>
|
||||
<li> <code>Socket.ParentEndpointId</code>: The parent endpoint ID of the
|
||||
socket operation.</li>
|
||||
<li> <code>Socket.ProcessId</code>: The ID of the process associated with the
|
||||
socket operation.</li>
|
||||
<li> <code>Socket.LocalAddr</code>, <code>Socket.RemoteAddr</code>,
|
||||
@@ -2732,6 +2737,8 @@ The possible fields are:
|
||||
<tr><td><code>subIfIdx</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>Sub-interface index</td></tr>
|
||||
<tr><td><code>loopback</code></td><td>✔</td><td></td><td>✔</td><td>✔</td><td></td><td>Is loopback packet?</td></tr>
|
||||
<tr><td><code>impostor</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>Is impostor packet?</td></tr>
|
||||
<tr><td><code>endpointId</code></td><td></td><td></td><td>✔</td><td>✔</td><td></td><td>Endpoint ID</td></tr>
|
||||
<tr><td><code>parentEndpointId</code></td><td></td><td></td><td>✔</td><td>✔</td><td></td><td>Parent endpoint ID</td></tr>
|
||||
<tr><td><code>processId</code></td><td></td><td></td><td>✔</td><td>✔</td><td>✔</td><td>Process ID</td></tr>
|
||||
<tr><td><code>random8</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>8-bit random number</td></tr>
|
||||
<tr><td><code>random16</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>16-bit random number</td></tr>
|
||||
@@ -2819,20 +2826,21 @@ and layers symbolically, e.g., <q><code>event == CONNECT</code></q> or
|
||||
The possible macros are:
|
||||
</p>
|
||||
<center>
|
||||
<table border="1" cellpadding="5">
|
||||
<table border="1" cellpadding="5" width="75%">
|
||||
<tr><th>Macro</th><th colspan="5">Layer</th><th>Value</th></tr>
|
||||
<tr><th></th><th><code>NETWORK</code></th><th><code>FORWARD</code></th><th><code>FLOW </code></th><th><code>SOCKET </code></th><th><code>REFLECT</code></th><th></th></tr>
|
||||
<tr><td><code>PACKET</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td><code>WINDIVERT_EVENT_NETWORK_PACKET</code></td></tr>
|
||||
<tr><td><code>ESTABLISHED</code></td><td></td><td></td><td>✔</td><td></td><td></td><td><code>WINDIVERT_EVENT_FLOW_ESTABLISHED</code></td></tr>
|
||||
<tr><td><code>DELETED</code></td><td></td><td></td><td>✔</td><td></td><td></td><td><code>WINDIVERT_EVENT_FLOW_DELETED</code></td></tr>
|
||||
<tr><td><code>BIND</code></td><td></td><td></td><td></td><td>✔</td><td></td><td><code>WINDIVERT_EVENT_SOCKET_BIND</code></td></tr>
|
||||
<tr><td><code>UNBIND</code></td><td></td><td></td><td></td><td>✔</td><td></td><td><code>WINDIVERT_EVENT_SOCKET_UNBIND</code></td></tr>
|
||||
<tr><td><code>CONNECT</code></td><td></td><td></td><td></td><td>✔</td><td></td><td><code>WINDIVERT_EVENT_SOCKET_CONNECT</code></td></tr>
|
||||
<tr><td><code>DISCONNECT</code></td><td></td><td></td><td></td><td>✔</td><td></td><td><code>WINDIVERT_EVENT_SOCKET_DISCONNECT</code></td></tr>
|
||||
<tr><td><code>ACCEPT</code></td><td></td><td></td><td></td><td>✔</td><td></td><td><code>WINDIVERT_EVENT_SOCKET_ACCEPT</code></td></tr>
|
||||
<tr><td><code>LISTEN</code></td><td></td><td></td><td></td><td>✔</td><td></td><td><code>WINDIVERT_EVENT_SOCKET_LISTEN</code></td></tr>
|
||||
<tr><td><code>OPEN</code></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_EVENT_REFLECT_OPEN</code></td></tr>
|
||||
<tr><td><code>CLOSE</code></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_EVENT_REFLECT_CLOSE</code></td></tr>
|
||||
<tr><td><code>CLOSE</code></td><td></td><td></td><td></td><td>✔</td><td>✔</td><td><code>WINDIVERT_EVENT_SOCKET_CLOSE</code>
|
||||
for the <code>SOCKET</code> layer, or
|
||||
<code>WINDIVERT_EVENT_REFLECT_CLOSE</code> for the <code>REFLECT</code>
|
||||
layer.</td></tr>
|
||||
<tr><td><code>NETWORK</code></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_LAYER_FLOW_NETWORK</code></td></tr>
|
||||
<tr><td><code>NETWORK_FORWARD</code></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_LAYER_FLOW_NETWORK_FORWARD</code></td></tr>
|
||||
<tr><td><code>FLOW</code></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_LAYER_FLOW_FLOW</code></td></tr>
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* usage: socketdump.exe [filter]
|
||||
* socketdump.exe --block [filter]
|
||||
*/
|
||||
|
||||
#include <winsock2.h>
|
||||
@@ -62,22 +63,39 @@ int __cdecl main(int argc, char **argv)
|
||||
char *filename;
|
||||
DWORD path_len;
|
||||
WINDIVERT_ADDRESS addr;
|
||||
BOOL block = FALSE;
|
||||
|
||||
switch (argc)
|
||||
{
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
filter = argv[1];
|
||||
if (strcmp(argv[1], "--block") == 0)
|
||||
{
|
||||
block = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
filter = argv[1];
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (strcmp(argv[1], "--block") == 0)
|
||||
{
|
||||
block = TRUE;
|
||||
filter = argv[2];
|
||||
break;
|
||||
}
|
||||
// Fallthrough:
|
||||
default:
|
||||
fprintf(stderr, "usage: %s [filter]\n");
|
||||
fprintf(stderr, " %s --block [filter]\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Open WinDivert SOCKET handle:
|
||||
handle = WinDivertOpen(filter, WINDIVERT_LAYER_SOCKET, priority,
|
||||
WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_RECV_ONLY);
|
||||
(block? 0: WINDIVERT_FLAG_SNIFF) | WINDIVERT_FLAG_RECV_ONLY);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetLastError() == ERROR_INVALID_PARAMETER &&
|
||||
@@ -108,10 +126,6 @@ int __cdecl main(int argc, char **argv)
|
||||
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
|
||||
printf("BIND");
|
||||
break;
|
||||
case WINDIVERT_EVENT_SOCKET_UNBIND:
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED);
|
||||
printf("UNBIND");
|
||||
break;
|
||||
case WINDIVERT_EVENT_SOCKET_LISTEN:
|
||||
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
|
||||
printf("LISTEN");
|
||||
@@ -120,14 +134,14 @@ int __cdecl main(int argc, char **argv)
|
||||
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
|
||||
printf("CONNECT");
|
||||
break;
|
||||
case WINDIVERT_EVENT_SOCKET_DISCONNECT:
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED);
|
||||
printf("DISCONNECT");
|
||||
break;
|
||||
case WINDIVERT_EVENT_SOCKET_ACCEPT:
|
||||
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
|
||||
printf("ACCEPT");
|
||||
break;
|
||||
case WINDIVERT_EVENT_SOCKET_CLOSE:
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED);
|
||||
printf("CLOSE");
|
||||
break;
|
||||
default:
|
||||
SetConsoleTextAttribute(console, FOREGROUND_BLUE);
|
||||
printf("???");
|
||||
@@ -168,6 +182,18 @@ int __cdecl main(int argc, char **argv)
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
|
||||
printf(" endpoint=");
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
printf("%lu", addr.Socket.Endpoint);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
|
||||
printf(" parent=");
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
printf("%lu", addr.Socket.ParentEndpoint);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
|
||||
printf(" protocol=");
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
switch (addr.Socket.Protocol)
|
||||
|
||||
+14
-10
@@ -95,6 +95,8 @@ typedef struct
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT64 EndpointId; /* Endpoint ID. */
|
||||
UINT64 ParentEndpointId; /* Parent endpoint ID. */
|
||||
UINT32 ProcessId; /* Process ID. */
|
||||
UINT32 LocalAddr[4]; /* Local address. */
|
||||
UINT32 RemoteAddr[4]; /* Remote address. */
|
||||
@@ -108,6 +110,8 @@ typedef struct
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT64 EndpointId; /* Endpoint ID. */
|
||||
UINT64 ParentEndpointId; /* Parent Endpoint ID. */
|
||||
UINT32 ProcessId; /* Process ID. */
|
||||
UINT32 LocalAddr[4]; /* Local address. */
|
||||
UINT32 RemoteAddr[4]; /* Remote address. */
|
||||
@@ -136,6 +140,7 @@ typedef struct
|
||||
INT64 Timestamp; /* Packet's timestamp. */
|
||||
UINT64 Layer:8; /* Packet's layer. */
|
||||
UINT64 Event:8; /* Packet event. */
|
||||
UINT64 Sniffed:1; /* Packet was sniffed? */
|
||||
UINT64 Outbound:1; /* Packet is outound? */
|
||||
UINT64 Loopback:1; /* Packet is loopback? */
|
||||
UINT64 Impostor:1; /* Packet is impostor? */
|
||||
@@ -143,14 +148,14 @@ typedef struct
|
||||
UINT64 IPChecksum:1; /* Packet has valid IPv4 checksum? */
|
||||
UINT64 TCPChecksum:1; /* Packet has valid TCP checksum? */
|
||||
UINT64 UDPChecksum:1; /* Packet has valid UDP checksum? */
|
||||
UINT64 Reserved1:41;
|
||||
UINT64 Reserved1:40;
|
||||
union
|
||||
{
|
||||
WINDIVERT_DATA_NETWORK Network; /* Network layer data. */
|
||||
WINDIVERT_DATA_FLOW Flow; /* Flow layer data. */
|
||||
WINDIVERT_DATA_SOCKET Socket; /* Socket layer data. */
|
||||
WINDIVERT_DATA_REFLECT Reflect; /* Reflect layer data. */
|
||||
UINT8 Reserved2[48];
|
||||
UINT8 Reserved2[64];
|
||||
};
|
||||
} WINDIVERT_ADDRESS, *PWINDIVERT_ADDRESS;
|
||||
|
||||
@@ -164,14 +169,12 @@ typedef enum
|
||||
/* Flow established. */
|
||||
WINDIVERT_EVENT_FLOW_DELETED = 2, /* Flow deleted. */
|
||||
WINDIVERT_EVENT_SOCKET_BIND = 3, /* Socket bind. */
|
||||
WINDIVERT_EVENT_SOCKET_UNBIND = 4, /* Socket unbind. */
|
||||
WINDIVERT_EVENT_SOCKET_CONNECT = 5, /* Socket connect. */
|
||||
WINDIVERT_EVENT_SOCKET_DISCONNECT = 6,
|
||||
/* Socket disconnect. */
|
||||
WINDIVERT_EVENT_SOCKET_LISTEN = 7, /* Socket listen. */
|
||||
WINDIVERT_EVENT_SOCKET_ACCEPT = 8, /* Socket accept. */
|
||||
WINDIVERT_EVENT_REFLECT_OPEN = 9, /* WinDivert handle opened. */
|
||||
WINDIVERT_EVENT_REFLECT_CLOSE = 10, /* WinDivert handle closed. */
|
||||
WINDIVERT_EVENT_SOCKET_CONNECT = 4, /* Socket connect. */
|
||||
WINDIVERT_EVENT_SOCKET_LISTEN = 5, /* Socket listen. */
|
||||
WINDIVERT_EVENT_SOCKET_ACCEPT = 6, /* Socket accept. */
|
||||
WINDIVERT_EVENT_SOCKET_CLOSE = 7, /* Socket close. */
|
||||
WINDIVERT_EVENT_REFLECT_OPEN = 8, /* WinDivert handle opened. */
|
||||
WINDIVERT_EVENT_REFLECT_CLOSE = 9, /* WinDivert handle closed. */
|
||||
} WINDIVERT_EVENT, *PWINDIVERT_EVENT;
|
||||
|
||||
/*
|
||||
@@ -312,6 +315,7 @@ extern WINDIVERTEXPORT BOOL WinDivertGetParam(
|
||||
#define WINDIVERT_PARAM_QUEUE_SIZE_MIN 65535 /* 64KB */
|
||||
#define WINDIVERT_PARAM_QUEUE_SIZE_MAX 33554432 /* 32MB */
|
||||
#define WINDIVERT_BATCH_MAX 0xFF /* 255 */
|
||||
#define WINDIVERT_MTU_MAX (40 + 0xFFFF)
|
||||
|
||||
/****************************************************************************/
|
||||
/* WINDIVERT HELPER API */
|
||||
|
||||
+23
-24
@@ -130,21 +130,23 @@
|
||||
#define WINDIVERT_FILTER_FIELD_LOCALPORT 63
|
||||
#define WINDIVERT_FILTER_FIELD_REMOTEPORT 64
|
||||
#define WINDIVERT_FILTER_FIELD_PROTOCOL 65
|
||||
#define WINDIVERT_FILTER_FIELD_LAYER 66
|
||||
#define WINDIVERT_FILTER_FIELD_PRIORITY 67
|
||||
#define WINDIVERT_FILTER_FIELD_EVENT 68
|
||||
#define WINDIVERT_FILTER_FIELD_PACKET 69
|
||||
#define WINDIVERT_FILTER_FIELD_PACKET16 70
|
||||
#define WINDIVERT_FILTER_FIELD_PACKET32 71
|
||||
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD 72
|
||||
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD16 73
|
||||
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD32 74
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD 75
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD16 76
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD32 77
|
||||
#define WINDIVERT_FILTER_FIELD_RANDOM8 78
|
||||
#define WINDIVERT_FILTER_FIELD_RANDOM16 79
|
||||
#define WINDIVERT_FILTER_FIELD_RANDOM32 80
|
||||
#define WINDIVERT_FILTER_FIELD_ENDPOINTID 66
|
||||
#define WINDIVERT_FILTER_FIELD_PARENTENDPOINTID 67
|
||||
#define WINDIVERT_FILTER_FIELD_LAYER 68
|
||||
#define WINDIVERT_FILTER_FIELD_PRIORITY 69
|
||||
#define WINDIVERT_FILTER_FIELD_EVENT 70
|
||||
#define WINDIVERT_FILTER_FIELD_PACKET 71
|
||||
#define WINDIVERT_FILTER_FIELD_PACKET16 72
|
||||
#define WINDIVERT_FILTER_FIELD_PACKET32 73
|
||||
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD 74
|
||||
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD16 75
|
||||
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD32 76
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD 77
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD16 78
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD32 79
|
||||
#define WINDIVERT_FILTER_FIELD_RANDOM8 80
|
||||
#define WINDIVERT_FILTER_FIELD_RANDOM16 81
|
||||
#define WINDIVERT_FILTER_FIELD_RANDOM32 82
|
||||
#define WINDIVERT_FILTER_FIELD_MAX \
|
||||
WINDIVERT_FILTER_FIELD_RANDOM32
|
||||
|
||||
@@ -196,12 +198,10 @@
|
||||
#define WINDIVERT_FILTER_FLAG_IPV6 0x0000000000000080ull
|
||||
#define WINDIVERT_FILTER_FLAG_EVENT_FLOW_DELETED 0x0000000000000100ull
|
||||
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_BIND 0x0000000000000200ull
|
||||
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_UNBIND 0x0000000000000400ull
|
||||
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CONNECT 0x0000000000000800ull
|
||||
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_DISCONNECT \
|
||||
0x0000000000001000ull
|
||||
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_LISTEN 0x0000000000002000ull
|
||||
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_ACCEPT 0x0000000000004000ull
|
||||
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CONNECT 0x0000000000000400ull
|
||||
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_LISTEN 0x0000000000000800ull
|
||||
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_ACCEPT 0x0000000000001000ull
|
||||
#define WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CLOSE 0x0000000000002000ull
|
||||
|
||||
#define WINDIVERT_FILTER_FLAGS_ALL \
|
||||
(WINDIVERT_FILTER_FLAG_INBOUND | \
|
||||
@@ -210,11 +210,10 @@
|
||||
WINDIVERT_FILTER_FLAG_IPV6 | \
|
||||
WINDIVERT_FILTER_FLAG_EVENT_FLOW_DELETED | \
|
||||
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_BIND | \
|
||||
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_UNBIND | \
|
||||
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CONNECT | \
|
||||
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_DISCONNECT | \
|
||||
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_LISTEN | \
|
||||
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_ACCEPT)
|
||||
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_ACCEPT | \
|
||||
WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CLOSE)
|
||||
|
||||
/*
|
||||
* WinDivert priorities.
|
||||
|
||||
+159
-105
@@ -258,6 +258,7 @@ struct packet_s
|
||||
LONGLONG timestamp; // Packet timestamp.
|
||||
UINT64 layer:8; // Layer.
|
||||
UINT64 event:8; // Event.
|
||||
UINT64 sniffed:1; // Packet was sniffed?
|
||||
UINT64 outbound:1; // Packet is outound?
|
||||
UINT64 loopback:1; // Packet is loopback?
|
||||
UINT64 impostor:1; // Packet is impostor?
|
||||
@@ -266,7 +267,7 @@ struct packet_s
|
||||
UINT64 tcp_checksum:1; // Packet has TCP checksum?
|
||||
UINT64 udp_checksum:1; // Packet has UDP checksum?
|
||||
UINT64 match:1; // Packet matches filter?
|
||||
UINT64 padding:8; // Padding for alignment.
|
||||
UINT64 padding:7; // Padding for alignment.
|
||||
UINT64 packet_size:32; // Packet total size.
|
||||
PVOID object; // Object associated with packet.
|
||||
UINT32 priority; // Packet priority.
|
||||
@@ -1513,8 +1514,8 @@ static NTSTATUS windivert_install_callouts(context_t context, UINT8 layer,
|
||||
UINT8 i, j;
|
||||
layer_t layers[WINDIVERT_CONTEXT_MAXLAYERS];
|
||||
UINT32 *callout_ids[WINDIVERT_CONTEXT_MAXLAYERS] = {NULL};
|
||||
BOOL inbound, outbound, ipv4, ipv6, bind, unbind, connect, disconnect,
|
||||
listen, accept;
|
||||
BOOL inbound, outbound, ipv4, ipv6, bind, connect, listen,
|
||||
accept, close;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
|
||||
inbound = ((flags & WINDIVERT_FILTER_FLAG_INBOUND) != 0);
|
||||
@@ -1522,11 +1523,10 @@ static NTSTATUS windivert_install_callouts(context_t context, UINT8 layer,
|
||||
ipv4 = ((flags & WINDIVERT_FILTER_FLAG_IP) != 0);
|
||||
ipv6 = ((flags & WINDIVERT_FILTER_FLAG_IPV6) != 0);
|
||||
bind = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_BIND) != 0);
|
||||
unbind = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_UNBIND) != 0);
|
||||
connect = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CONNECT) != 0);
|
||||
disconnect = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_DISCONNECT) != 0);
|
||||
listen = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_LISTEN) != 0);
|
||||
accept = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_ACCEPT) != 0);
|
||||
close = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CLOSE) != 0);
|
||||
|
||||
i = 0;
|
||||
switch (layer)
|
||||
@@ -1579,18 +1579,10 @@ static NTSTATUS windivert_install_callouts(context_t context, UINT8 layer,
|
||||
{
|
||||
layers[i++] = WINDIVERT_LAYER_RESOURCE_ASSIGNMENT_IPV4;
|
||||
}
|
||||
if (ipv4 && unbind)
|
||||
{
|
||||
layers[i++] = WINDIVERT_LAYER_RESOURCE_RELEASE_IPV4;
|
||||
}
|
||||
if (ipv4 && connect)
|
||||
{
|
||||
layers[i++] = WINDIVERT_LAYER_AUTH_CONNECT_IPV4;
|
||||
}
|
||||
if (ipv4 && disconnect)
|
||||
{
|
||||
layers[i++] = WINDIVERT_LAYER_ENDPOINT_CLOSURE_IPV4;
|
||||
}
|
||||
if (ipv4 && listen)
|
||||
{
|
||||
layers[i++] = WINDIVERT_LAYER_AUTH_LISTEN_IPV4;
|
||||
@@ -1599,22 +1591,19 @@ static NTSTATUS windivert_install_callouts(context_t context, UINT8 layer,
|
||||
{
|
||||
layers[i++] = WINDIVERT_LAYER_AUTH_RECV_ACCEPT_IPV4;
|
||||
}
|
||||
if (ipv4 && close)
|
||||
{
|
||||
layers[i++] = WINDIVERT_LAYER_RESOURCE_RELEASE_IPV4;
|
||||
layers[i++] = WINDIVERT_LAYER_ENDPOINT_CLOSURE_IPV4;
|
||||
}
|
||||
if (ipv6 && bind)
|
||||
{
|
||||
layers[i++] = WINDIVERT_LAYER_RESOURCE_ASSIGNMENT_IPV6;
|
||||
}
|
||||
if (ipv6 && unbind)
|
||||
{
|
||||
layers[i++] = WINDIVERT_LAYER_RESOURCE_RELEASE_IPV6;
|
||||
}
|
||||
if (ipv6 && connect)
|
||||
{
|
||||
layers[i++] = WINDIVERT_LAYER_AUTH_CONNECT_IPV6;
|
||||
}
|
||||
if (ipv6 && disconnect)
|
||||
{
|
||||
layers[i++] = WINDIVERT_LAYER_ENDPOINT_CLOSURE_IPV6;
|
||||
}
|
||||
if (ipv6 && listen)
|
||||
{
|
||||
layers[i++] = WINDIVERT_LAYER_AUTH_LISTEN_IPV6;
|
||||
@@ -1623,6 +1612,11 @@ static NTSTATUS windivert_install_callouts(context_t context, UINT8 layer,
|
||||
{
|
||||
layers[i++] = WINDIVERT_LAYER_AUTH_RECV_ACCEPT_IPV6;
|
||||
}
|
||||
if (ipv6 && close)
|
||||
{
|
||||
layers[i++] = WINDIVERT_LAYER_RESOURCE_RELEASE_IPV6;
|
||||
layers[i++] = WINDIVERT_LAYER_ENDPOINT_CLOSURE_IPV6;
|
||||
}
|
||||
break;
|
||||
|
||||
case WINDIVERT_LAYER_REFLECT:
|
||||
@@ -2188,6 +2182,7 @@ static void windivert_read_service_request(context_t context, packet_t packet,
|
||||
addr[i].Timestamp = (INT64)packet->timestamp;
|
||||
addr[i].Layer = packet->layer;
|
||||
addr[i].Event = packet->event;
|
||||
addr[i].Sniffed = packet->sniffed;
|
||||
addr[i].Outbound = packet->outbound;
|
||||
addr[i].Loopback = packet->loopback;
|
||||
addr[i].Impostor = packet->impostor;
|
||||
@@ -2294,7 +2289,7 @@ static void windivert_fast_read_service_request(PVOID packet, ULONG packet_len,
|
||||
PWINDIVERT_ADDRESS addr;
|
||||
UINT *addr_len_ptr;
|
||||
NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO checksums;
|
||||
BOOL ip_checksum, tcp_checksum, udp_checksum;
|
||||
BOOL sniffed, ip_checksum, tcp_checksum, udp_checksum;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
|
||||
// This function bypasses the normal work_queue -> packet_queue flow, but
|
||||
@@ -2384,9 +2379,13 @@ static void windivert_fast_read_service_request(PVOID packet, ULONG packet_len,
|
||||
|
||||
if (addr != NULL)
|
||||
{
|
||||
sniffed = ((flags & WINDIVERT_FLAG_SNIFF) != 0 ||
|
||||
event == WINDIVERT_EVENT_SOCKET_CLOSE);
|
||||
|
||||
addr->Timestamp = timestamp;
|
||||
addr->Layer = layer;
|
||||
addr->Event = event;
|
||||
addr->Sniffed = (sniffed? 1: 0);
|
||||
addr->Outbound = (outbound? 1: 0);
|
||||
addr->Loopback = (loopback? 1: 0);
|
||||
addr->Impostor = (impostor? 1: 0);
|
||||
@@ -3823,6 +3822,8 @@ static void windivert_flow_established_v4_classify(
|
||||
BOOL outbound, loopback;
|
||||
UINT64 flow_id;
|
||||
|
||||
flow_data.EndpointId = meta_vals->transportEndpointHandle;
|
||||
flow_data.ParentEndpointId = meta_vals->parentEndpointHandle;
|
||||
flow_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
windivert_get_ipv4_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_LOCAL_ADDRESS,
|
||||
@@ -4097,6 +4098,8 @@ static void windivert_resource_assignment_v4_classify(
|
||||
return;
|
||||
}
|
||||
|
||||
socket_data.EndpointId = meta_vals->transportEndpointHandle;
|
||||
socket_data.ParentEndpointId = 0;
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
windivert_get_ipv4_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_IP_LOCAL_ADDRESS,
|
||||
@@ -4134,6 +4137,8 @@ static void windivert_resource_assignment_v6_classify(
|
||||
return;
|
||||
}
|
||||
|
||||
socket_data.EndpointId = meta_vals->transportEndpointHandle;
|
||||
socket_data.ParentEndpointId = 0;
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
windivert_get_ipv6_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_IP_LOCAL_ADDRESS,
|
||||
@@ -4166,6 +4171,8 @@ static void windivert_resource_release_v4_classify(
|
||||
WINDIVERT_DATA_SOCKET socket_data;
|
||||
BOOL loopback;
|
||||
|
||||
socket_data.EndpointId = meta_vals->transportEndpointHandle;
|
||||
socket_data.ParentEndpointId = 0;
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
windivert_get_ipv4_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_RESOURCE_RELEASE_V4_IP_LOCAL_ADDRESS,
|
||||
@@ -4182,7 +4189,7 @@ static void windivert_resource_release_v4_classify(
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
|
||||
windivert_socket_classify((context_t)filter->context,
|
||||
&socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_UNBIND, /*ipv4=*/TRUE,
|
||||
&socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_CLOSE, /*ipv4=*/TRUE,
|
||||
/*outbound=*/FALSE, loopback, result);
|
||||
}
|
||||
|
||||
@@ -4198,6 +4205,8 @@ static void windivert_resource_release_v6_classify(
|
||||
WINDIVERT_DATA_SOCKET socket_data;
|
||||
BOOL loopback;
|
||||
|
||||
socket_data.EndpointId = meta_vals->transportEndpointHandle;
|
||||
socket_data.ParentEndpointId = 0;
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
windivert_get_ipv6_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_RESOURCE_RELEASE_V6_IP_LOCAL_ADDRESS,
|
||||
@@ -4214,7 +4223,7 @@ static void windivert_resource_release_v6_classify(
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
|
||||
windivert_socket_classify((context_t)filter->context,
|
||||
&socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_UNBIND, /*ipv4=*/FALSE,
|
||||
&socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_CLOSE, /*ipv4=*/FALSE,
|
||||
/*outbound=*/FALSE, loopback, result);
|
||||
}
|
||||
|
||||
@@ -4243,6 +4252,8 @@ static void windivert_auth_connect_v4_classify(
|
||||
return;
|
||||
}
|
||||
|
||||
socket_data.EndpointId = meta_vals->transportEndpointHandle;
|
||||
socket_data.ParentEndpointId = meta_vals->parentEndpointHandle;
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
windivert_get_ipv4_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_LOCAL_ADDRESS,
|
||||
@@ -4289,6 +4300,8 @@ static void windivert_auth_connect_v6_classify(
|
||||
return;
|
||||
}
|
||||
|
||||
socket_data.EndpointId = meta_vals->transportEndpointHandle;
|
||||
socket_data.ParentEndpointId = meta_vals->parentEndpointHandle;
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
windivert_get_ipv6_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V6_IP_LOCAL_ADDRESS,
|
||||
@@ -4322,6 +4335,8 @@ static void windivert_endpoint_closure_v4_classify(
|
||||
WINDIVERT_DATA_SOCKET socket_data;
|
||||
BOOL loopback;
|
||||
|
||||
socket_data.EndpointId = meta_vals->transportEndpointHandle;
|
||||
socket_data.ParentEndpointId = meta_vals->parentEndpointHandle;
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
windivert_get_ipv4_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_ENDPOINT_CLOSURE_V4_IP_LOCAL_ADDRESS,
|
||||
@@ -4341,7 +4356,7 @@ static void windivert_endpoint_closure_v4_classify(
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
|
||||
windivert_socket_classify((context_t)filter->context,
|
||||
&socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_DISCONNECT,
|
||||
&socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_CLOSE,
|
||||
/*ipv4=*/TRUE, /*outbound=*/TRUE, loopback, result);
|
||||
}
|
||||
|
||||
@@ -4357,6 +4372,8 @@ static void windivert_endpoint_closure_v6_classify(
|
||||
WINDIVERT_DATA_SOCKET socket_data;
|
||||
BOOL loopback;
|
||||
|
||||
socket_data.EndpointId = meta_vals->transportEndpointHandle;
|
||||
socket_data.ParentEndpointId = meta_vals->parentEndpointHandle;
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
windivert_get_ipv6_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_ENDPOINT_CLOSURE_V6_IP_LOCAL_ADDRESS,
|
||||
@@ -4376,11 +4393,10 @@ static void windivert_endpoint_closure_v6_classify(
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
|
||||
windivert_socket_classify((context_t)filter->context,
|
||||
&socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_DISCONNECT,
|
||||
&socket_data, /*event=*/WINDIVERT_EVENT_SOCKET_CLOSE,
|
||||
/*ipv4=*/FALSE, /*outbound=*/TRUE, loopback, result);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* WinDivert classify auth listen IPv4 function.
|
||||
*/
|
||||
@@ -4398,6 +4414,8 @@ static void windivert_auth_listen_v4_classify(
|
||||
return;
|
||||
}
|
||||
|
||||
socket_data.EndpointId = meta_vals->transportEndpointHandle;
|
||||
socket_data.ParentEndpointId = 0;
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
windivert_get_ipv4_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_LISTEN_V4_IP_LOCAL_ADDRESS,
|
||||
@@ -4434,6 +4452,8 @@ static void windivert_auth_listen_v6_classify(
|
||||
return;
|
||||
}
|
||||
|
||||
socket_data.EndpointId = meta_vals->transportEndpointHandle;
|
||||
socket_data.ParentEndpointId = 0;
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
windivert_get_ipv6_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_LISTEN_V6_IP_LOCAL_ADDRESS,
|
||||
@@ -4478,6 +4498,8 @@ static void windivert_auth_recv_accept_v4_classify(
|
||||
return;
|
||||
}
|
||||
|
||||
socket_data.EndpointId = meta_vals->transportEndpointHandle;
|
||||
socket_data.ParentEndpointId = meta_vals->parentEndpointHandle;
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
windivert_get_ipv4_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_LOCAL_ADDRESS,
|
||||
@@ -4524,6 +4546,8 @@ static void windivert_auth_recv_accept_v6_classify(
|
||||
return;
|
||||
}
|
||||
|
||||
socket_data.EndpointId = meta_vals->transportEndpointHandle;
|
||||
socket_data.ParentEndpointId = meta_vals->parentEndpointHandle;
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
windivert_get_ipv6_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_IP_LOCAL_ADDRESS,
|
||||
@@ -4598,9 +4622,8 @@ static void windivert_socket_classify(context_t context,
|
||||
}
|
||||
|
||||
WdfObjectDereference(object);
|
||||
if ((result->rights & FWPS_RIGHT_ACTION_WRITE) != 0 &&
|
||||
event != WINDIVERT_EVENT_SOCKET_UNBIND &&
|
||||
event != WINDIVERT_EVENT_SOCKET_DISCONNECT &&
|
||||
if (match && (result->rights & FWPS_RIGHT_ACTION_WRITE) != 0 &&
|
||||
event != WINDIVERT_EVENT_SOCKET_CLOSE &&
|
||||
(flags & WINDIVERT_FLAG_SNIFF) == 0)
|
||||
{
|
||||
result->actionType = FWP_ACTION_BLOCK;
|
||||
@@ -4665,11 +4688,14 @@ static BOOL windivert_queue_work(context_t context, PVOID packet,
|
||||
PWINDIVERT_DATA_FLOW flow_data;
|
||||
PWINDIVERT_DATA_SOCKET socket_data;
|
||||
PWINDIVERT_DATA_REFLECT reflect_data;
|
||||
BOOL ip_checksum, tcp_checksum, udp_checksum;
|
||||
BOOL sniffed, ip_checksum, tcp_checksum, udp_checksum;
|
||||
WDFREQUEST request = NULL;
|
||||
NTSTATUS status;
|
||||
|
||||
if (!match && (flags & WINDIVERT_FLAG_SNIFF) != 0)
|
||||
sniffed = ((flags & WINDIVERT_FLAG_SNIFF) != 0 ||
|
||||
event == WINDIVERT_EVENT_SOCKET_CLOSE);
|
||||
|
||||
if (!match && sniffed)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -4795,6 +4821,7 @@ static BOOL windivert_queue_work(context_t context, PVOID packet,
|
||||
|
||||
work->layer = layer;
|
||||
work->event = event;
|
||||
work->sniffed = (sniffed? 1: 0);
|
||||
work->outbound = (outbound? 1: 0);
|
||||
work->loopback = (loopback? 1: 0);
|
||||
work->impostor = (impostor? 1: 0);
|
||||
@@ -5438,6 +5465,11 @@ static BOOL windivert_filter(PNET_BUFFER buffer, WINDIVERT_LAYER layer,
|
||||
layer == WINDIVERT_LAYER_SOCKET ||
|
||||
layer == WINDIVERT_LAYER_REFLECT);
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_ENDPOINTID:
|
||||
case WINDIVERT_FILTER_FIELD_PARENTENDPOINTID:
|
||||
result = (layer == WINDIVERT_LAYER_FLOW ||
|
||||
layer == WINDIVERT_LAYER_SOCKET);
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_LAYER:
|
||||
case WINDIVERT_FILTER_FIELD_PRIORITY:
|
||||
result = (layer == WINDIVERT_LAYER_REFLECT);
|
||||
@@ -6057,6 +6089,42 @@ static BOOL windivert_filter(PNET_BUFFER buffer, WINDIVERT_LAYER layer,
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_ENDPOINTID:
|
||||
big = TRUE;
|
||||
field[2] = field[3] = 0;
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_FLOW:
|
||||
field[0] = (UINT32)flow_data->EndpointId;
|
||||
field[1] = (UINT32)(flow_data->EndpointId >> 32);
|
||||
break;
|
||||
case WINDIVERT_LAYER_SOCKET:
|
||||
field[0] = (UINT32)socket_data->EndpointId;
|
||||
field[1] = (UINT32)(socket_data->EndpointId >> 32);
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_PARENTENDPOINTID:
|
||||
big = TRUE;
|
||||
field[2] = field[3] = 0;
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_FLOW:
|
||||
field[0] = (UINT32)flow_data->ParentEndpointId;
|
||||
field[1] =
|
||||
(UINT32)(flow_data->ParentEndpointId >> 32);
|
||||
break;
|
||||
case WINDIVERT_LAYER_SOCKET:
|
||||
field[0] = (UINT32)socket_data->ParentEndpointId;
|
||||
field[1] =
|
||||
(UINT32)(socket_data->ParentEndpointId >> 32);
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_LAYER:
|
||||
field[0] = (UINT32)reflect_data->Layer;
|
||||
break;
|
||||
@@ -6119,6 +6187,8 @@ static const WINDIVERT_FILTER *windivert_filter_compile(
|
||||
{
|
||||
PWINDIVERT_FILTER filter = NULL;
|
||||
WINDIVERT_EVENT event;
|
||||
UINT32 lb[4], ub[4];
|
||||
int result;
|
||||
UINT16 i;
|
||||
size_t length;
|
||||
|
||||
@@ -6174,49 +6244,30 @@ static const WINDIVERT_FILTER *windivert_filter_compile(
|
||||
}
|
||||
|
||||
// Enforce ranges:
|
||||
if (ioctl_filter[i].field != WINDIVERT_FILTER_FIELD_IPV6_SRCADDR &&
|
||||
ioctl_filter[i].field != WINDIVERT_FILTER_FIELD_IPV6_DSTADDR &&
|
||||
ioctl_filter[i].field != WINDIVERT_FILTER_FIELD_LOCALADDR &&
|
||||
ioctl_filter[i].field != WINDIVERT_FILTER_FIELD_REMOTEADDR)
|
||||
lb[0] = lb[1] = lb[2] = lb[3] = 0;
|
||||
ub[0] = ub[1] = ub[2] = ub[3] = 0;
|
||||
switch (ioctl_filter[i].field)
|
||||
{
|
||||
if (ioctl_filter[i].arg[2] != 0 ||
|
||||
ioctl_filter[i].arg[3] != 0)
|
||||
case WINDIVERT_FILTER_FIELD_PACKET:
|
||||
case WINDIVERT_FILTER_FIELD_PACKET16:
|
||||
case WINDIVERT_FILTER_FIELD_PACKET32:
|
||||
case WINDIVERT_FILTER_FIELD_TCP_PAYLOAD:
|
||||
case WINDIVERT_FILTER_FIELD_TCP_PAYLOAD16:
|
||||
case WINDIVERT_FILTER_FIELD_TCP_PAYLOAD32:
|
||||
case WINDIVERT_FILTER_FIELD_UDP_PAYLOAD:
|
||||
case WINDIVERT_FILTER_FIELD_UDP_PAYLOAD16:
|
||||
case WINDIVERT_FILTER_FIELD_UDP_PAYLOAD32:
|
||||
{
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
switch (ioctl_filter[i].field)
|
||||
{
|
||||
case WINDIVERT_FILTER_FIELD_IP_SRCADDR:
|
||||
case WINDIVERT_FILTER_FIELD_IP_DSTADDR:
|
||||
if (ioctl_filter[i].arg[1] != 0x0000FFFF)
|
||||
{
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_PACKET:
|
||||
case WINDIVERT_FILTER_FIELD_PACKET16:
|
||||
case WINDIVERT_FILTER_FIELD_PACKET32:
|
||||
case WINDIVERT_FILTER_FIELD_TCP_PAYLOAD:
|
||||
case WINDIVERT_FILTER_FIELD_TCP_PAYLOAD16:
|
||||
case WINDIVERT_FILTER_FIELD_TCP_PAYLOAD32:
|
||||
case WINDIVERT_FILTER_FIELD_UDP_PAYLOAD:
|
||||
case WINDIVERT_FILTER_FIELD_UDP_PAYLOAD16:
|
||||
case WINDIVERT_FILTER_FIELD_UDP_PAYLOAD32:
|
||||
INT idx = (INT)ioctl_filter[i].arg[1];
|
||||
if (idx > WINDIVERT_MTU_MAX || idx < -WINDIVERT_MTU_MAX)
|
||||
{
|
||||
INT idx = (INT)ioctl_filter[i].arg[1];
|
||||
if (idx > UINT16_MAX || idx < -UINT16_MAX)
|
||||
{
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
break;
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
default:
|
||||
if (ioctl_filter[i].arg[1] != 0)
|
||||
{
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
break;
|
||||
lb[1] = ub[1] = ioctl_filter[i].arg[1];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (ioctl_filter[i].field)
|
||||
{
|
||||
@@ -6237,22 +6288,13 @@ static const WINDIVERT_FILTER *windivert_filter_compile(
|
||||
case WINDIVERT_FILTER_FIELD_TCP_RST:
|
||||
case WINDIVERT_FILTER_FIELD_TCP_SYN:
|
||||
case WINDIVERT_FILTER_FIELD_TCP_FIN:
|
||||
if (ioctl_filter[i].arg[0] > 1)
|
||||
{
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
ub[0] = 1;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_LAYER:
|
||||
if (ioctl_filter[i].arg[0] > WINDIVERT_LAYER_MAX)
|
||||
{
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
ub[0] = WINDIVERT_LAYER_MAX;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_PRIORITY:
|
||||
if (ioctl_filter[i].arg[0] > 2 * WINDIVERT_PRIORITY_MAX)
|
||||
{
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
ub[0] = 2 * WINDIVERT_PRIORITY_MAX;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_EVENT:
|
||||
event = (WINDIVERT_EVENT)ioctl_filter[i].arg[0];
|
||||
@@ -6274,11 +6316,10 @@ static const WINDIVERT_FILTER *windivert_filter_compile(
|
||||
break;
|
||||
case WINDIVERT_LAYER_SOCKET:
|
||||
if (event != WINDIVERT_EVENT_SOCKET_BIND &&
|
||||
event != WINDIVERT_EVENT_SOCKET_UNBIND &&
|
||||
event != WINDIVERT_EVENT_SOCKET_CONNECT &&
|
||||
event != WINDIVERT_EVENT_SOCKET_DISCONNECT &&
|
||||
event != WINDIVERT_EVENT_SOCKET_LISTEN &&
|
||||
event != WINDIVERT_EVENT_SOCKET_ACCEPT)
|
||||
event != WINDIVERT_EVENT_SOCKET_ACCEPT &&
|
||||
event != WINDIVERT_EVENT_SOCKET_CLOSE)
|
||||
{
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
@@ -6293,13 +6334,11 @@ static const WINDIVERT_FILTER *windivert_filter_compile(
|
||||
default:
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
ub[0] = WINDIVERT_EVENT_MAX;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_IP_HDRLENGTH:
|
||||
case WINDIVERT_FILTER_FIELD_TCP_HDRLENGTH:
|
||||
if (ioctl_filter[i].arg[0] > 0x0F)
|
||||
{
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
ub[0] = 0x0F;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_IP_TOS:
|
||||
case WINDIVERT_FILTER_FIELD_IP_TTL:
|
||||
@@ -6316,16 +6355,10 @@ static const WINDIVERT_FILTER *windivert_filter_compile(
|
||||
case WINDIVERT_FILTER_FIELD_TCP_PAYLOAD:
|
||||
case WINDIVERT_FILTER_FIELD_UDP_PAYLOAD:
|
||||
case WINDIVERT_FILTER_FIELD_RANDOM8:
|
||||
if (ioctl_filter[i].arg[0] > UINT8_MAX)
|
||||
{
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
ub[0] = 0xFF;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_IP_FRAGOFF:
|
||||
if (ioctl_filter[i].arg[0] > 0x1FFF)
|
||||
{
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
ub[0] = 0x1FFF;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_IP_LENGTH:
|
||||
case WINDIVERT_FILTER_FIELD_IP_ID:
|
||||
@@ -6350,20 +6383,41 @@ static const WINDIVERT_FILTER *windivert_filter_compile(
|
||||
case WINDIVERT_FILTER_FIELD_TCP_PAYLOAD16:
|
||||
case WINDIVERT_FILTER_FIELD_UDP_PAYLOAD16:
|
||||
case WINDIVERT_FILTER_FIELD_RANDOM16:
|
||||
if (ioctl_filter[i].arg[0] > UINT16_MAX)
|
||||
{
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
ub[0] = 0xFFFF;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_IPV6_FLOWLABEL:
|
||||
if (ioctl_filter[i].arg[0] > 0x000FFFFF)
|
||||
{
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
ub[0] = 0x000FFFFF;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_IP_SRCADDR:
|
||||
case WINDIVERT_FILTER_FIELD_IP_DSTADDR:
|
||||
ub[0] = 0xFFFFFFFF;
|
||||
ub[1] = lb[1] = 0x0000FFFF;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_ENDPOINTID:
|
||||
case WINDIVERT_FILTER_FIELD_PARENTENDPOINTID:
|
||||
ub[0] = ub[1] = 0xFFFFFFFF;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_IPV6_SRCADDR:
|
||||
case WINDIVERT_FILTER_FIELD_IPV6_DSTADDR:
|
||||
case WINDIVERT_FILTER_FIELD_LOCALADDR:
|
||||
case WINDIVERT_FILTER_FIELD_REMOTEADDR:
|
||||
ub[0] = ub[1] = ub[2] = ub[3] = 0xFFFFFFFF;
|
||||
break;
|
||||
default:
|
||||
ub[0] = 0xFFFFFFFF;
|
||||
break;
|
||||
}
|
||||
result = windivert_big_num_compare(ioctl_filter[i].arg, lb, TRUE);
|
||||
if (result < 0)
|
||||
{
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
result = windivert_big_num_compare(ioctl_filter[i].arg, ub, TRUE);
|
||||
if (result > 0)
|
||||
{
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
|
||||
filter[i].field = ioctl_filter[i].field;
|
||||
filter[i].test = ioctl_filter[i].test;
|
||||
filter[i].success = ioctl_filter[i].success;
|
||||
|
||||
+20
-19
@@ -296,13 +296,13 @@ static const struct test tests[] =
|
||||
"not packet[69] <= 0x29)))))", &pkt_echo_request, FALSE},
|
||||
{"ip.HdrLength == 5 and ip.TOS == 0 and ip.Length == 84 and "
|
||||
"ip.Id == 0x1234 and ip.FragOff == 0 and ip.MF == 0 and ip.DF == 1 and "
|
||||
"ip.TTL == 64 and ip.Protocol == 1 and ip.SrcAddr == 0x0A000001 and "
|
||||
"ip.DstAddr == 0x08080808 and icmp.Type == 8 and icmp.Code == 0 and "
|
||||
"ip.TTL == 64 and ip.Protocol == 1 and ip.SrcAddr == 0xFFFF0A000001 and "
|
||||
"ip.DstAddr == 0xFFFF08080808 and icmp.Type == 8 and icmp.Code == 0 and "
|
||||
"icmp.Body == 0x0D560001", &pkt_echo_request, TRUE},
|
||||
{"ip.HdrLength > 5 or ip.TOS > 0 or ip.Length != 84 or ip.Id < 0x1234 or "
|
||||
"ip.FragOff != 0 or ip.MF < 0 or ip.DF != 1 or ip.TTL > 64 or "
|
||||
"ip.Protocol != 1 or ip.SrcAddr < 0x0A000001 or "
|
||||
"ip.DstAddr < 0x08080808 or icmp.Type != 8 or icmp.Code != 0 or "
|
||||
"ip.Protocol != 1 or ip.SrcAddr < 0xFFFF0A000001 or "
|
||||
"ip.DstAddr < 0xFFFF08080808 or icmp.Type != 8 or icmp.Code != 0 or "
|
||||
"icmp.Body != 0x0D560001", &pkt_echo_request, FALSE},
|
||||
{"localAddr == 10.0.0.1 && remoteAddr == 8.8.8.8 && localPort == 8 && "
|
||||
"remotePort == 0 && protocol == 1", &pkt_echo_request, TRUE},
|
||||
@@ -481,8 +481,8 @@ static const struct test tests[] =
|
||||
"not packet[477] == 0x69)))", &pkt_http_request, FALSE},
|
||||
{"ip.HdrLength == 5 and ip.TOS == 0 and ip.Length == 521 and "
|
||||
"ip.Id == 0x482D and ip.FragOff == 0 and ip.MF == 0 and ip.DF == 1 and "
|
||||
"ip.TTL == 64 and ip.Protocol == 6 and ip.SrcAddr == 0x0A0A0A0A and "
|
||||
"ip.DstAddr == 0x5DB8D877 and tcp.SrcPort == 41754 and "
|
||||
"ip.TTL == 64 and ip.Protocol == 6 and ip.SrcAddr == 0xFFFF0A0A0A0A and "
|
||||
"ip.DstAddr == 0xFFFF5DB8D877 and tcp.SrcPort == 41754 and "
|
||||
"tcp.DstPort == 80 and tcp.SeqNum == 1396231362 and "
|
||||
"tcp.AckNum == 1446490965 and tcp.HdrLength == 8 and tcp.Fin == 0 and "
|
||||
"tcp.Syn == 0 and tcp.Rst == 0 and tcp.Psh == 1 and tcp.Ack == 1 and "
|
||||
@@ -490,12 +490,13 @@ static const struct test tests[] =
|
||||
&pkt_http_request, TRUE},
|
||||
{"ip.HdrLength > 5 or ip.TOS < 0 or ip.Length < 521 or ip.Id != 0x482D or "
|
||||
"ip.FragOff != 0 or ip.MF != 0 or ip.DF < 1 or ip.TTL < 64 or "
|
||||
"ip.Protocol > 6 or ip.SrcAddr != 0x0A0A0A0A or "
|
||||
"ip.DstAddr < 0x5DB8D877 or tcp.SrcPort < 41754 or tcp.DstPort < 80 or "
|
||||
"tcp.SeqNum != 1396231362 or tcp.AckNum < 1446490965 or "
|
||||
"tcp.HdrLength < 8 or tcp.Fin != 0 or tcp.Syn != 0 or tcp.Rst != 0 or "
|
||||
"tcp.Psh != 1 or tcp.Ack > 1 or tcp.Urg != 0 or tcp.Window < 115 or "
|
||||
"tcp.UrgPtr < 0", &pkt_http_request, FALSE},
|
||||
"ip.Protocol > 6 or ip.SrcAddr != 0xFFFF0A0A0A0A or "
|
||||
"ip.DstAddr < 0xFFFF5DB8D877 or tcp.SrcPort < 41754 or "
|
||||
"tcp.DstPort < 80 or tcp.SeqNum != 1396231362 or "
|
||||
"tcp.AckNum < 1446490965 or tcp.HdrLength < 8 or tcp.Fin != 0 or "
|
||||
"tcp.Syn != 0 or tcp.Rst != 0 or tcp.Psh != 1 or tcp.Ack > 1 or "
|
||||
"tcp.Urg != 0 or tcp.Window < 115 or tcp.UrgPtr < 0",
|
||||
&pkt_http_request, FALSE},
|
||||
{"localAddr == 10.10.10.10 && remoteAddr == 93.184.216.119 && "
|
||||
"localPort == 41754 && remotePort == 80 && protocol == 6",
|
||||
&pkt_http_request, TRUE},
|
||||
@@ -585,14 +586,14 @@ static const struct test tests[] =
|
||||
{"packet32[54b] <= 0xFFFFFFE", &pkt_dns_request, FALSE},
|
||||
{"ip.HdrLength == 5 and ip.TOS == 0 and ip.Length == 57 and "
|
||||
"ip.Id == 0x2090 and ip.FragOff == 0 and ip.MF == 0 and ip.DF == 0 and "
|
||||
"ip.TTL == 73 and ip.Protocol == 17 and ip.SrcAddr == 0x0A000001 and "
|
||||
"ip.DstAddr == 0x08080404 and udp.SrcPort == 57413 and "
|
||||
"ip.TTL == 73 and ip.Protocol == 17 and ip.SrcAddr == 0xFFFF0A000001 and "
|
||||
"ip.DstAddr == 0xFFFF08080404 and udp.SrcPort == 57413 and "
|
||||
"udp.DstPort == 53 and udp.Length == 37", &pkt_dns_request, TRUE},
|
||||
{"ip.HdrLength > 5 or ip.TOS > 0 or ip.Length < 57 or ip.Id > 0x2090 or "
|
||||
"ip.FragOff != 0 or ip.MF < 0 or ip.DF < 0 or ip.TTL > 73 or "
|
||||
"ip.Protocol < 17 or ip.SrcAddr < 0x0A000001 or "
|
||||
"ip.DstAddr > 0x08080404 or udp.SrcPort > 57413 or udp.DstPort != 53 or "
|
||||
"udp.Length < 37", &pkt_dns_request, FALSE},
|
||||
"ip.Protocol < 17 or ip.SrcAddr < 0xFFFF0A000001 or "
|
||||
"ip.DstAddr > 0xFFFF08080404 or udp.SrcPort > 57413 or "
|
||||
"udp.DstPort != 53 or udp.Length < 37", &pkt_dns_request, FALSE},
|
||||
{"localAddr == 10.0.0.1 && remoteAddr == 8.8.4.4 && "
|
||||
"localPort == 57413 && remotePort == 53 && protocol == 17",
|
||||
&pkt_dns_request, TRUE},
|
||||
@@ -1316,8 +1317,8 @@ static DWORD monitor_worker(LPVOID arg)
|
||||
tests[i].packet->packet_len, &addr) != tests[i].match)
|
||||
{
|
||||
fprintf(stderr, "error: failed to match recompiled filter "
|
||||
"(test = %.3u, filter = \"%s\", err = %d)\n", i, filter_2,
|
||||
GetLastError());
|
||||
"(test = %.3u, filter = \"%s\", err = %d)\n", i,
|
||||
tests[i].filter, GetLastError());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user