Add "priority" filtering for the REFLECT layer.

This commit is contained in:
basil00
2018-11-24 08:00:17 +08:00
parent 1c4075ed51
commit ebe1af330b
5 changed files with 86 additions and 26 deletions
+52 -7
View File
@@ -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;
}
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)