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:
basil00
2019-03-13 08:33:12 +08:00
parent 4289e7ec2b
commit d29688ea83
10 changed files with 601 additions and 341 deletions
+8 -7
View File
@@ -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
View File
@@ -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
View File
@@ -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]");
}
+4
View File
@@ -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
View File
@@ -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>&#10004;</td><td>&#10004;</td><td></td><td></td><td></td><td>Sub-interface index</td></tr>
<tr><td><code>loopback</code></td><td>&#10004;</td><td></td><td>&#10004;</td><td>&#10004;</td><td></td><td>Is loopback packet?</td></tr>
<tr><td><code>impostor</code></td><td>&#10004;</td><td>&#10004;</td><td></td><td></td><td></td><td>Is impostor packet?</td></tr>
<tr><td><code>endpointId</code></td><td></td><td></td><td>&#10004;</td><td>&#10004;</td><td></td><td>Endpoint ID</td></tr>
<tr><td><code>parentEndpointId</code></td><td></td><td></td><td>&#10004;</td><td>&#10004;</td><td></td><td>Parent endpoint ID</td></tr>
<tr><td><code>processId</code></td><td></td><td></td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>Process ID</td></tr>
<tr><td><code>random8</code></td><td>&#10004;</td><td>&#10004;</td><td></td><td></td><td></td><td>8-bit random number</td></tr>
<tr><td><code>random16</code></td><td>&#10004;</td><td>&#10004;</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&nbsp;&nbsp;&nbsp;</code></th><th><code>SOCKET&nbsp;</code></th><th><code>REFLECT</code></th><th></th></tr>
<tr><td><code>PACKET</code></td><td>&#10004;</td><td>&#10004;</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>&#10004;</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>&#10004;</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>&#10004;</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>&#10004;</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>&#10004;</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>&#10004;</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>&#10004;</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>&#10004;</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>&#10004;</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>&#10004;</td><td><code>WINDIVERT_EVENT_REFLECT_CLOSE</code></td></tr>
<tr><td><code>CLOSE</code></td><td></td><td></td><td></td><td>&#10004;</td><td>&#10004;</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>&#10004;</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>&#10004;</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>&#10004;</td><td><code>WINDIVERT_LAYER_FLOW_FLOW</code></td></tr>
+36 -10
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
}