Add "priority" filtering for the REFLECT layer.
This commit is contained in:
+52
-7
@@ -137,6 +137,7 @@ typedef enum
|
||||
TOKEN_REMOTE_PORT,
|
||||
TOKEN_PROTOCOL,
|
||||
TOKEN_LAYER,
|
||||
TOKEN_PRIORITY,
|
||||
TOKEN_FLOW,
|
||||
TOKEN_SOCKET,
|
||||
TOKEN_NETWORK,
|
||||
@@ -238,6 +239,7 @@ struct EXPR
|
||||
};
|
||||
UINT8 kind;
|
||||
UINT8 count;
|
||||
BOOL neg;
|
||||
UINT16 succ;
|
||||
UINT16 fail;
|
||||
};
|
||||
@@ -614,6 +616,7 @@ static ERROR WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer,
|
||||
{"packet", TOKEN_PACKET, LNM___},
|
||||
{"packet16", TOKEN_PACKET16, LNM___},
|
||||
{"packet32", TOKEN_PACKET32, LNM___},
|
||||
{"priority", TOKEN_PRIORITY, L____R},
|
||||
{"processId", TOKEN_PROCESS_ID, L__FSR},
|
||||
{"protocol", TOKEN_PROTOCOL, LN_FS_},
|
||||
{"random16", TOKEN_RANDOM16, LNM___},
|
||||
@@ -943,6 +946,7 @@ static PEXPR WinDivertMakeVar(KIND kind, PERROR error)
|
||||
{{{0}}, TOKEN_REMOTE_PORT},
|
||||
{{{0}}, TOKEN_PROTOCOL},
|
||||
{{{0}}, TOKEN_LAYER},
|
||||
{{{0}}, TOKEN_PRIORITY},
|
||||
};
|
||||
|
||||
// Binary search:
|
||||
@@ -997,10 +1001,6 @@ static PEXPR WinDivertMakeZero(void)
|
||||
*/
|
||||
static PEXPR WinDivertMakeNumber(HANDLE pool, UINT32 *val, PERROR error)
|
||||
{
|
||||
if (val[0] == 0 && val[1] == 0 && val[2] == 0 && val[3] == 0)
|
||||
{
|
||||
return WinDivertMakeZero();
|
||||
}
|
||||
PEXPR expr = (PEXPR)HeapAlloc(pool, HEAP_ZERO_MEMORY, sizeof(EXPR));
|
||||
if (expr == NULL)
|
||||
{
|
||||
@@ -1064,7 +1064,7 @@ static PEXPR WinDivertParseTest(HANDLE pool, TOKEN *toks, UINT *i, PERROR error)
|
||||
{
|
||||
PEXPR var, val;
|
||||
KIND kind;
|
||||
BOOL not = FALSE, neg;
|
||||
BOOL not = FALSE, neg, priority = FALSE;
|
||||
UINT idx, size;
|
||||
while (toks[*i].kind == TOKEN_NOT)
|
||||
{
|
||||
@@ -1073,6 +1073,9 @@ static PEXPR WinDivertParseTest(HANDLE pool, TOKEN *toks, UINT *i, PERROR error)
|
||||
}
|
||||
switch (toks[*i].kind)
|
||||
{
|
||||
case TOKEN_PRIORITY:
|
||||
priority = TRUE;
|
||||
/* fallthough */
|
||||
case TOKEN_ZERO:
|
||||
case TOKEN_EVENT:
|
||||
case TOKEN_RANDOM8:
|
||||
@@ -1261,12 +1264,19 @@ static PEXPR WinDivertParseTest(HANDLE pool, TOKEN *toks, UINT *i, PERROR error)
|
||||
}
|
||||
}
|
||||
*i = *i + 1;
|
||||
neg = FALSE;
|
||||
if (priority && toks[*i].kind == TOKEN_MINUS)
|
||||
{
|
||||
neg = TRUE;
|
||||
*i = *i + 1;
|
||||
}
|
||||
if (toks[*i].kind != TOKEN_NUMBER)
|
||||
{
|
||||
*error = MAKE_ERROR(WINDIVERT_ERROR_UNEXPECTED_TOKEN, toks[*i].pos);
|
||||
return NULL;
|
||||
}
|
||||
val = WinDivertMakeNumber(pool, toks[*i].val, error);
|
||||
val->neg = neg;
|
||||
*i = *i + 1;
|
||||
return WinDivertMakeBinOp(pool, kind, var, val, error);
|
||||
}
|
||||
@@ -1395,6 +1405,9 @@ static BOOL WinDivertEvalTest(PEXPR test, BOOL *res)
|
||||
case TOKEN_LAYER:
|
||||
lb = 0; ub = WINDIVERT_LAYER_MAX;
|
||||
break;
|
||||
case TOKEN_PRIORITY:
|
||||
lb = 0; ub = WINDIVERT_PRIORITY_MAX;
|
||||
break;
|
||||
case TOKEN_EVENT:
|
||||
lb = 0; ub = WINDIVERT_EVENT_MAX;
|
||||
break;
|
||||
@@ -1613,6 +1626,7 @@ static void WinDivertEmitTest(PEXPR test, UINT16 offset,
|
||||
{
|
||||
BOOL big;
|
||||
PEXPR var = test->arg[0], val = test->arg[1];
|
||||
UINT32 val0;
|
||||
switch (test->kind)
|
||||
{
|
||||
case TOKEN_EQ:
|
||||
@@ -1638,6 +1652,7 @@ static void WinDivertEmitTest(PEXPR test, UINT16 offset,
|
||||
}
|
||||
big = FALSE;
|
||||
object->arg[1] = object->arg[2] = object->arg[3] = 0;
|
||||
val0 = val->val[0];
|
||||
switch (var->kind)
|
||||
{
|
||||
case TOKEN_ZERO:
|
||||
@@ -1732,6 +1747,11 @@ static void WinDivertEmitTest(PEXPR test, UINT16 offset,
|
||||
case TOKEN_LAYER:
|
||||
object->field = WINDIVERT_FILTER_FIELD_LAYER;
|
||||
break;
|
||||
case TOKEN_PRIORITY:
|
||||
object->field = WINDIVERT_FILTER_FIELD_PRIORITY;
|
||||
val0 = (val->neg? WINDIVERT_PRIORITY_MAX - val0:
|
||||
WINDIVERT_PRIORITY_MAX + val0);
|
||||
break;
|
||||
case TOKEN_IP:
|
||||
object->field = WINDIVERT_FILTER_FIELD_IP;
|
||||
break;
|
||||
@@ -1898,7 +1918,7 @@ static void WinDivertEmitTest(PEXPR test, UINT16 offset,
|
||||
default:
|
||||
return;
|
||||
}
|
||||
object->arg[0] = val->val[0];
|
||||
object->arg[0] = val0;
|
||||
if (big)
|
||||
{
|
||||
object->arg[1] = val->val[1];
|
||||
@@ -2533,6 +2553,7 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
|
||||
addr->Layer == WINDIVERT_LAYER_REFLECT);
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_LAYER:
|
||||
case WINDIVERT_FILTER_FIELD_PRIORITY:
|
||||
pass = (addr->Layer == WINDIVERT_LAYER_REFLECT);
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_IP_HDRLENGTH:
|
||||
@@ -2629,6 +2650,13 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
|
||||
case WINDIVERT_FILTER_FIELD_EVENT:
|
||||
val[0] = addr->Event;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_LAYER:
|
||||
val[0] = addr->Reflect.Layer;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_PRIORITY:
|
||||
val[0] = (UINT32)((INT32)addr->Reflect.Layer +
|
||||
WINDIVERT_PRIORITY_MAX);
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_RANDOM8:
|
||||
val[0] = (UINT32)((random64 >> 48) & 0xFF);
|
||||
break;
|
||||
@@ -3514,6 +3542,8 @@ static PEXPR WinDivertDecompileTest(HANDLE pool, PWINDIVERT_FILTER test)
|
||||
kind = TOKEN_PROTOCOL; break;
|
||||
case WINDIVERT_FILTER_FIELD_LAYER:
|
||||
kind = TOKEN_LAYER; break;
|
||||
case WINDIVERT_FILTER_FIELD_PRIORITY:
|
||||
kind = TOKEN_PRIORITY; break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@@ -3965,7 +3995,7 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
{
|
||||
PEXPR field = expr->arg[0], val = expr->arg[1];
|
||||
BOOL is_ipv4_addr = FALSE, is_ipv6_addr = FALSE, is_layer = FALSE,
|
||||
is_event = FALSE, is_hex = FALSE;
|
||||
is_priority = FALSE, is_event = FALSE, is_hex = FALSE;
|
||||
|
||||
switch (field->kind)
|
||||
{
|
||||
@@ -4022,6 +4052,9 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
case TOKEN_LAYER:
|
||||
is_layer = TRUE;
|
||||
break;
|
||||
case TOKEN_PRIORITY:
|
||||
is_priority = TRUE;
|
||||
break;
|
||||
case TOKEN_EVENT:
|
||||
is_event = TRUE;
|
||||
break;
|
||||
@@ -4089,6 +4122,16 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
WinDivertFormatNumber(stream, val->val[0]); break;
|
||||
}
|
||||
}
|
||||
else if (is_priority)
|
||||
{
|
||||
INT32 val32 = (INT32)val->val[0];
|
||||
val32 -= WINDIVERT_PRIORITY_MAX;
|
||||
if (val32 < 0)
|
||||
{
|
||||
WinDivertPutChar(stream, '-');
|
||||
}
|
||||
WinDivertFormatNumber(stream, (val32 < 0? -val32: val32));
|
||||
}
|
||||
else if (is_event)
|
||||
{
|
||||
switch (layer)
|
||||
@@ -4387,6 +4430,8 @@ static void WinDivertFormatExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
WinDivertPutString(stream, "protocol"); return;
|
||||
case TOKEN_LAYER:
|
||||
WinDivertPutString(stream, "layer"); return;
|
||||
case TOKEN_PRIORITY:
|
||||
WinDivertPutString(stream, "priority"); return;
|
||||
case TOKEN_NUMBER:
|
||||
WinDivertFormatNumber(stream, expr->val[0]); return;
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ usage:
|
||||
return 0;
|
||||
}
|
||||
if (GetLastError() == ERROR_INVALID_PARAMETER &&
|
||||
!WinDivertHelperCompileFilter(filter, WINDIVERT_LAYER_FLOW,
|
||||
!WinDivertHelperCompileFilter(filter, WINDIVERT_LAYER_REFLECT,
|
||||
NULL, 0, &err_str, NULL))
|
||||
{
|
||||
fprintf(stderr, "error: invalid filter \"%s\"\n", err_str);
|
||||
|
||||
+14
-13
@@ -126,19 +126,20 @@
|
||||
#define WINDIVERT_FILTER_FIELD_REMOTEPORT 64
|
||||
#define WINDIVERT_FILTER_FIELD_PROTOCOL 65
|
||||
#define WINDIVERT_FILTER_FIELD_LAYER 66
|
||||
#define WINDIVERT_FILTER_FIELD_EVENT 67
|
||||
#define WINDIVERT_FILTER_FIELD_PACKET 68
|
||||
#define WINDIVERT_FILTER_FIELD_PACKET16 69
|
||||
#define WINDIVERT_FILTER_FIELD_PACKET32 70
|
||||
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD 71
|
||||
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD16 72
|
||||
#define WINDIVERT_FILTER_FIELD_TCP_PAYLOAD32 73
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD 74
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD16 75
|
||||
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOAD32 76
|
||||
#define WINDIVERT_FILTER_FIELD_RANDOM8 77
|
||||
#define WINDIVERT_FILTER_FIELD_RANDOM16 78
|
||||
#define WINDIVERT_FILTER_FIELD_RANDOM32 79
|
||||
#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_MAX \
|
||||
WINDIVERT_FILTER_FIELD_RANDOM32
|
||||
|
||||
|
||||
+7
-4
@@ -51,11 +51,11 @@ do
|
||||
BITS=64
|
||||
MANGLE=
|
||||
fi
|
||||
HAVE_SYS=yes
|
||||
if [ ! -d install/WDDK/$CPU ]
|
||||
then
|
||||
echo "WARNING: missing WDDK build; run wddk-build.bat first"
|
||||
echo "SKIP MINGW-$CPU"
|
||||
continue
|
||||
HAVE_SYS=no
|
||||
fi
|
||||
echo "BUILD MINGW-$CPU"
|
||||
CC="$ENV-gcc"
|
||||
@@ -109,8 +109,11 @@ do
|
||||
$CC -s -O2 -Iinclude/ examples/socketdump/socketdump.c \
|
||||
-o "install/MINGW/$CPU/socketdump.exe" -lWinDivert \
|
||||
-lpsapi -lshlwapi -L"install/MINGW/$CPU/"
|
||||
echo "\tcopy install/MINGW/$CPU/WinDivert$BITS.sys..."
|
||||
cp install/WDDK/$CPU/WinDivert$BITS.sys install/MINGW/$CPU
|
||||
if [ $HAVE_SYS = yes ]
|
||||
then
|
||||
echo "\tcopy install/MINGW/$CPU/WinDivert$BITS.sys..."
|
||||
cp install/WDDK/$CPU/WinDivert$BITS.sys install/MINGW/$CPU
|
||||
fi
|
||||
else
|
||||
echo "WARNING: $CC not found"
|
||||
fi
|
||||
|
||||
+12
-1
@@ -5063,6 +5063,7 @@ static BOOL windivert_filter(PNET_BUFFER buffer, WINDIVERT_LAYER layer,
|
||||
layer == WINDIVERT_LAYER_REFLECT);
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_LAYER:
|
||||
case WINDIVERT_FILTER_FIELD_PRIORITY:
|
||||
result = (layer == WINDIVERT_LAYER_REFLECT);
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_IP_HDRLENGTH:
|
||||
@@ -5659,7 +5660,11 @@ static BOOL windivert_filter(PNET_BUFFER buffer, WINDIVERT_LAYER layer,
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_LAYER:
|
||||
field[0] = reflect_data->Layer;
|
||||
field[0] = (UINT32)reflect_data->Layer;
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_PRIORITY:
|
||||
field[0] = (UINT32)((INT32)reflect_data->Priority +
|
||||
WINDIVERT_PRIORITY_MAX);
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
@@ -5845,6 +5850,12 @@ static const WINDIVERT_FILTER *windivert_filter_compile(
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_PRIORITY:
|
||||
if (ioctl_filter[i].arg[0] > 2 * WINDIVERT_PRIORITY_MAX)
|
||||
{
|
||||
goto windivert_filter_compile_error;
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_EVENT:
|
||||
event = (WINDIVERT_EVENT)ioctl_filter[i].arg[0];
|
||||
switch (layer)
|
||||
|
||||
Reference in New Issue
Block a user