Add a new SOCKET layer to WinDivert (see #156).
Adds a new SOCKET layer for monitoring socket events, such as BIND, LISTEN, CONNECT, and ACCEPT. These events occur before the flow is established (and unlike the FLOW layer) it is possible to block/drop SOCKET events. Otherwise, this layer is very similar to the FLOW layer, so the PID is available and injection is not possible. This commit should be considered to be a WIP. Other changes: - New socketdump.exe sample. Prints socket events. - Improve IPv6 address parsing. - New helper functions: * WinDivertHelperFormatIPv4Address * WinDivertHelperFormatIPv6Address - Fix REFLECT bugs. - The network 5-tuple can now be accessed at the NETWORK layer. - Various cleanups.
This commit is contained in:
@@ -413,6 +413,7 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
case WINDIVERT_LAYER_NETWORK_FORWARD:
|
||||
case WINDIVERT_LAYER_FLOW:
|
||||
case WINDIVERT_LAYER_SOCKET:
|
||||
case WINDIVERT_LAYER_REFLECT:
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -13,6 +13,8 @@ EXPORTS
|
||||
WinDivertHelperParsePacket
|
||||
WinDivertHelperParseIPv4Address
|
||||
WinDivertHelperParseIPv6Address
|
||||
WinDivertHelperFormatIPv4Address
|
||||
WinDivertHelperFormatIPv6Address
|
||||
WinDivertHelperCompileFilter
|
||||
WinDivertHelperEvalFilter
|
||||
WinDivertHelperFormatFilter
|
||||
|
||||
+577
-349
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* streamdump.c
|
||||
* flowtrack.c
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This file is part of WinDivert.
|
||||
@@ -47,7 +47,8 @@
|
||||
|
||||
#include "windivert.h"
|
||||
|
||||
#define MAX_FLOWS 256
|
||||
#define MAX_FLOWS 256
|
||||
#define INET6_ADDRSTRLEN 45
|
||||
|
||||
/*
|
||||
* Flow tracking.
|
||||
@@ -61,39 +62,6 @@ typedef struct FLOW
|
||||
static HANDLE lock;
|
||||
static PFLOW flows = NULL;
|
||||
|
||||
/*
|
||||
* Print an IP address.
|
||||
*/
|
||||
static void print_address(const UINT32 *addr)
|
||||
{
|
||||
if (addr[3] == 0 && addr[2] == 0 && addr[1] == 0x0000FFFF)
|
||||
{
|
||||
// IPv4 address:
|
||||
UINT32 a, b, c, d;
|
||||
a = (addr[0] >> 24) & 0xFF;
|
||||
b = (addr[0] >> 16) & 0xFF;
|
||||
c = (addr[0] >> 8) & 0xFF;
|
||||
d = (addr[0] >> 0) & 0xFF;
|
||||
printf("%u.%u.%u.%u", a, b, c, d);
|
||||
}
|
||||
else
|
||||
{
|
||||
// IPv6 address:
|
||||
int i;
|
||||
for (i = 3; i >= 0; i--)
|
||||
{
|
||||
UINT32 a, b;
|
||||
a = (addr[i] >> 16) & 0xFFFF;
|
||||
b = (addr[i] >> 0) & 0xFFFF;
|
||||
printf("%x:%x", a, b);
|
||||
if (i != 0)
|
||||
{
|
||||
putchar(':');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw flows to console in a delayed loop.
|
||||
*
|
||||
@@ -105,6 +73,7 @@ static DWORD draw(LPVOID arg)
|
||||
HANDLE process, console = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
CONSOLE_SCREEN_BUFFER_INFO screen;
|
||||
char path[MAX_PATH+1];
|
||||
char addr_str[INET6_ADDRSTRLEN+1];
|
||||
char *filename;
|
||||
const char header[] = "PID PROGRAM PROT FLOW";
|
||||
DWORD rows, columns, written, fill_len, path_len, i;
|
||||
@@ -216,11 +185,13 @@ static DWORD draw(LPVOID arg)
|
||||
}
|
||||
SetConsoleTextAttribute(console,
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
print_address(addr->Flow.LocalAddr);
|
||||
printf(":%u %s ", addr->Flow.LocalPort,
|
||||
WinDivertHelperFormatIPv6Address(addr->Flow.LocalAddr, addr_str,
|
||||
sizeof(addr_str));
|
||||
printf("%s:%u %s ", addr_str, addr->Flow.LocalPort,
|
||||
(addr->Outbound? "---->": "<----"));
|
||||
print_address(addr->Flow.RemoteAddr);
|
||||
printf(":%u", addr->Flow.RemotePort);
|
||||
WinDivertHelperFormatIPv6Address(addr->Flow.RemoteAddr, addr_str,
|
||||
sizeof(addr_str));
|
||||
printf("%s:%u", addr_str, addr->Flow.RemotePort);
|
||||
fflush(stdout);
|
||||
}
|
||||
for (; i < rows-1; i++)
|
||||
|
||||
@@ -49,7 +49,8 @@
|
||||
|
||||
#include "windivert.h"
|
||||
|
||||
#define MAXBUF 0xFFFF
|
||||
#define MAXBUF 0xFFFF
|
||||
#define INET6_ADDRSTRLEN 45
|
||||
|
||||
/*
|
||||
* Entry.
|
||||
@@ -68,6 +69,7 @@ int __cdecl main(int argc, char **argv)
|
||||
PWINDIVERT_ICMPV6HDR icmpv6_header;
|
||||
PWINDIVERT_TCPHDR tcp_header;
|
||||
PWINDIVERT_UDPHDR udp_header;
|
||||
char src_str[INET6_ADDRSTRLEN+1], dst_str[INET6_ADDRSTRLEN+1];
|
||||
const char *err_str;
|
||||
LARGE_INTEGER base, freq;
|
||||
double time_passed;
|
||||
@@ -166,16 +168,19 @@ int __cdecl main(int argc, char **argv)
|
||||
FOREGROUND_GREEN | FOREGROUND_RED);
|
||||
printf("IPv4 [Version=%u HdrLength=%u TOS=%u Length=%u Id=0x%.4X "
|
||||
"Reserved=%u DF=%u MF=%u FragOff=%u TTL=%u Protocol=%u "
|
||||
"Checksum=0x%.4X SrcAddr=%u.%u.%u.%u DstAddr=%u.%u.%u.%u]\n",
|
||||
"Checksum=0x%.4X SrcAddr=%s DstAddr=%s]\n",
|
||||
ip_header->Version, ip_header->HdrLength,
|
||||
ntohs(ip_header->TOS), ntohs(ip_header->Length),
|
||||
ntohs(ip_header->Id), WINDIVERT_IPHDR_GET_RESERVED(ip_header),
|
||||
WINDIVERT_IPHDR_GET_DF(ip_header),
|
||||
WINDIVERT_IPHDR_GET_MF(ip_header),
|
||||
ntohs(WINDIVERT_IPHDR_GET_FRAGOFF(ip_header)), ip_header->TTL,
|
||||
ip_header->Protocol, ntohs(ip_header->Checksum),
|
||||
src_addr[0], src_addr[1], src_addr[2], src_addr[3],
|
||||
dst_addr[0], dst_addr[1], dst_addr[2], dst_addr[3]);
|
||||
ip_header->Protocol, ntohs(ip_header->Checksum));
|
||||
WinDivertHelperFormatIPv4Address(ntohl(ip_header->SrcAddr),
|
||||
src_str, sizeof(src_str));
|
||||
WinDivertHelperFormatIPv4Address(ntohl(ip_header->DstAddr),
|
||||
dst_str, sizeof(dst_str));
|
||||
|
||||
}
|
||||
if (ipv6_header != NULL)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* socketdump.c
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* usage: socketdump.exe [filter]
|
||||
*/
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
#include <shlwapi.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "windivert.h"
|
||||
|
||||
#define INET6_ADDRSTRLEN 45
|
||||
|
||||
/*
|
||||
* Entry.
|
||||
*/
|
||||
int __cdecl main(int argc, char **argv)
|
||||
{
|
||||
HANDLE handle, process, console;
|
||||
INT16 priority = 1121; // Arbitrary.
|
||||
const char *filter = "true", *err_str;
|
||||
char path[MAX_PATH+1];
|
||||
char local_str[INET6_ADDRSTRLEN+1], remote_str[INET6_ADDRSTRLEN+1];
|
||||
char *filename;
|
||||
DWORD path_len;
|
||||
UINT packet_len;
|
||||
WINDIVERT_ADDRESS addr;
|
||||
|
||||
switch (argc)
|
||||
{
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
filter = argv[1];
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "usage: %s [filter]\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Open WinDivert SOCKET handle:
|
||||
handle = WinDivertOpen(filter, WINDIVERT_LAYER_SOCKET, priority,
|
||||
WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_RECV_ONLY);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetLastError() == ERROR_INVALID_PARAMETER &&
|
||||
!WinDivertHelperCompileFilter(filter, WINDIVERT_LAYER_SOCKET,
|
||||
NULL, 0, &err_str, NULL))
|
||||
{
|
||||
fprintf(stderr, "error: invalid filter \"%s\"\n", err_str);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(stderr, "error: failed to open the WinDivert device (%d)\n",
|
||||
GetLastError());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Main loop:
|
||||
console = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
while (TRUE)
|
||||
{
|
||||
if (!WinDivertRecv(handle, NULL, 0, &addr, &packet_len))
|
||||
{
|
||||
fprintf(stderr, "failed to read packet (%d)\n", GetLastError());
|
||||
continue;
|
||||
}
|
||||
|
||||
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
|
||||
switch (addr.Event)
|
||||
{
|
||||
case WINDIVERT_EVENT_SOCKET_BIND:
|
||||
printf("BIND");
|
||||
break;
|
||||
case WINDIVERT_EVENT_SOCKET_LISTEN:
|
||||
printf("LISTEN");
|
||||
break;
|
||||
case WINDIVERT_EVENT_SOCKET_CONNECT:
|
||||
printf("CONNECT");
|
||||
break;
|
||||
case WINDIVERT_EVENT_SOCKET_ACCEPT:
|
||||
printf("ACCEPT");
|
||||
break;
|
||||
default:
|
||||
printf("???");
|
||||
break;
|
||||
}
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
|
||||
printf(" pid=");
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
printf("%u", addr.Socket.ProcessId);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
|
||||
printf(" program=");
|
||||
process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE,
|
||||
addr.Socket.ProcessId);
|
||||
path_len = 0;
|
||||
if (process != NULL)
|
||||
{
|
||||
path_len = GetProcessImageFileName(process, path, sizeof(path));
|
||||
CloseHandle(process);
|
||||
}
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
if (path_len != 0)
|
||||
{
|
||||
filename = PathFindFileName(path);
|
||||
printf("%s", filename);
|
||||
}
|
||||
else if (addr.Socket.ProcessId == 4)
|
||||
{
|
||||
printf("Windows");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("???");
|
||||
}
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
|
||||
printf(" protocol=");
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
switch (addr.Socket.Protocol)
|
||||
{
|
||||
case IPPROTO_TCP:
|
||||
printf("TCP");
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
printf("UDP");
|
||||
break;
|
||||
case IPPROTO_ICMP:
|
||||
printf("ICMP");
|
||||
break;
|
||||
case IPPROTO_ICMPV6:
|
||||
printf("ICMPV6");
|
||||
break;
|
||||
default:
|
||||
printf("%u", addr.Socket.Protocol);
|
||||
break;
|
||||
}
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
|
||||
WinDivertHelperFormatIPv6Address(addr.Socket.LocalAddr, local_str,
|
||||
sizeof(local_str));
|
||||
if (addr.Socket.LocalPort != 0 || strcmp(local_str, "::") != 0)
|
||||
{
|
||||
printf(" local=");
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
printf("[%s]:%u", local_str, addr.Socket.LocalPort);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
}
|
||||
|
||||
WinDivertHelperFormatIPv6Address(addr.Socket.RemoteAddr, remote_str,
|
||||
sizeof(remote_str));
|
||||
if (addr.Socket.RemotePort != 0 || strcmp(remote_str, "::") != 0)
|
||||
{
|
||||
printf(" remote=");
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
printf("[%s]:%u", remote_str, addr.Socket.RemotePort);
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN |
|
||||
FOREGROUND_BLUE);
|
||||
}
|
||||
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -315,6 +315,9 @@ usage:
|
||||
case WINDIVERT_LAYER_FLOW:
|
||||
fputs("FLOW", stdout);
|
||||
break;
|
||||
case WINDIVERT_LAYER_SOCKET:
|
||||
fputs("SOCKET", stdout);
|
||||
break;
|
||||
case WINDIVERT_LAYER_REFLECT:
|
||||
fputs("REFLECT", stdout);
|
||||
break;
|
||||
|
||||
+39
-4
@@ -77,7 +77,8 @@ typedef enum
|
||||
WINDIVERT_LAYER_NETWORK = 0, /* Network layer. */
|
||||
WINDIVERT_LAYER_NETWORK_FORWARD = 1,/* Network layer (forwarded packets) */
|
||||
WINDIVERT_LAYER_FLOW = 2, /* Flow layer. */
|
||||
WINDIVERT_LAYER_REFLECT = 3, /* Reflect layer. */
|
||||
WINDIVERT_LAYER_SOCKET = 3, /* Socket layer. */
|
||||
WINDIVERT_LAYER_REFLECT = 4, /* Reflect layer. */
|
||||
} WINDIVERT_LAYER, *PWINDIVERT_LAYER;
|
||||
|
||||
/*
|
||||
@@ -102,6 +103,19 @@ typedef struct
|
||||
UINT8 Protocol; /* Protocol. */
|
||||
} WINDIVERT_FLOW_DATA, *PWINDIVERT_FLOW_DATA;
|
||||
|
||||
/*
|
||||
* WinDivert SOCKET layer data.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT32 ProcessId; /* Process ID. */
|
||||
UINT32 LocalAddr[4]; /* Local address. */
|
||||
UINT32 RemoteAddr[4]; /* Remote address. */
|
||||
UINT16 LocalPort; /* Local port. */
|
||||
UINT16 RemotePort; /* Remote port. */
|
||||
UINT8 Protocol; /* Protocol. */
|
||||
} WINDIVERT_SOCKET_DATA, *PWINDIVERT_SOCKET_DATA;
|
||||
|
||||
/*
|
||||
* WinDivert REFLECTION layer data.
|
||||
*/
|
||||
@@ -135,6 +149,7 @@ typedef struct
|
||||
{
|
||||
WINDIVERT_NETWORK_DATA Network; /* Network layer data. */
|
||||
WINDIVERT_FLOW_DATA Flow; /* Flow layer data. */
|
||||
WINDIVERT_SOCKET_DATA Socket; /* Socket layer data. */
|
||||
WINDIVERT_REFLECT_DATA Reflect; /* Reflect layer data. */
|
||||
};
|
||||
} WINDIVERT_ADDRESS, *PWINDIVERT_ADDRESS;
|
||||
@@ -148,10 +163,14 @@ typedef enum
|
||||
WINDIVERT_EVENT_FLOW_ESTABLISHED = 1,
|
||||
/* Flow established. */
|
||||
WINDIVERT_EVENT_FLOW_DELETED = 2, /* Flow deleted. */
|
||||
WINDIVERT_EVENT_REFLECT_ESTABLISHED = 3,
|
||||
WINDIVERT_EVENT_SOCKET_BIND = 3, /* Socket bind. */
|
||||
WINDIVERT_EVENT_SOCKET_CONNECT = 4, /* Socket connect. */
|
||||
WINDIVERT_EVENT_SOCKET_LISTEN = 5, /* Socket listen. */
|
||||
WINDIVERT_EVENT_SOCKET_ACCEPT = 6, /* Socket accept. */
|
||||
WINDIVERT_EVENT_REFLECT_ESTABLISHED = 7,
|
||||
/* Previously open WinDivert handle. */
|
||||
WINDIVERT_EVENT_REFLECT_OPEN = 4, /* Open new WinDivert handle. */
|
||||
WINDIVERT_EVENT_REFLECT_CLOSE = 5, /* Close existing WinDivert handle. */
|
||||
WINDIVERT_EVENT_REFLECT_OPEN = 8, /* Open new WinDivert handle. */
|
||||
WINDIVERT_EVENT_REFLECT_CLOSE = 9, /* Close existing WinDivert handle. */
|
||||
} WINDIVERT_EVENT, *PWINDIVERT_EVENT;
|
||||
|
||||
/*
|
||||
@@ -434,6 +453,22 @@ extern WINDIVERTEXPORT BOOL WinDivertHelperParseIPv6Address(
|
||||
__in const char *addrStr,
|
||||
__out_opt UINT32 *pAddr);
|
||||
|
||||
/*
|
||||
* Format an IPv4 address.
|
||||
*/
|
||||
extern WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv4Address(
|
||||
__in UINT32 addr,
|
||||
__out char *buffer,
|
||||
__in UINT bufLen);
|
||||
|
||||
/*
|
||||
* Format an IPv6 address.
|
||||
*/
|
||||
extern WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv6Address(
|
||||
__in const UINT32 *pAddr,
|
||||
__out char *buffer,
|
||||
__in UINT bufLen);
|
||||
|
||||
/*
|
||||
* Calculate IPv4/IPv6/ICMP/ICMPv6/TCP/UDP checksums.
|
||||
*/
|
||||
|
||||
@@ -105,6 +105,10 @@ do
|
||||
$CC -s -O2 -Iinclude/ examples/windivertctl/windivertctl.c \
|
||||
-o "install/MINGW/$CPU/windivertctl.exe" -lWinDivert -lws2_32 \
|
||||
-lpsapi -lshlwapi -L"install/MINGW/$CPU/"
|
||||
echo "\tcopy install/MINGW/$CPU/socketdump.exe..."
|
||||
$CC -s -O2 -Iinclude/ examples/socketdump/socketdump.c \
|
||||
-o "install/MINGW/$CPU/socketdump.exe" -lWinDivert -lws2_32 \
|
||||
-lpsapi -lshlwapi -L"install/MINGW/$CPU/"
|
||||
echo "\tcopy install/MINGW/$CPU/WinDivert$BITS.sys..."
|
||||
cp install/WDDK/$CPU/WinDivert$BITS.sys install/MINGW/$CPU
|
||||
else
|
||||
|
||||
+1062
-58
File diff suppressed because it is too large
Load Diff
+9
-1
@@ -257,6 +257,8 @@ static struct test tests[] =
|
||||
&pkt_dns_request, TRUE},
|
||||
{"ip.SrcAddr < 10.0.0.0 or ip.SrcAddr > 10.255.255.255",
|
||||
&pkt_dns_request, FALSE},
|
||||
{"ip.DstAddr == ::ffff:8.8.4.4", &pkt_dns_request, TRUE},
|
||||
{"ip.DstAddr == ::0:ffff:8.8.4.4", &pkt_dns_request, TRUE},
|
||||
{"udp.PayloadLength == 29", &pkt_dns_request, TRUE},
|
||||
{"ipv6", &pkt_ipv6_tcp_syn, TRUE},
|
||||
{"ip", &pkt_ipv6_tcp_syn, FALSE},
|
||||
@@ -284,8 +286,10 @@ static struct test tests[] =
|
||||
{"false", &pkt_ipv6_exthdrs_udp, FALSE},
|
||||
{"udp", &pkt_ipv6_exthdrs_udp, TRUE},
|
||||
{"tcp", &pkt_ipv6_exthdrs_udp, FALSE},
|
||||
{"ipv6.SrcAddr == ::", &pkt_ipv6_exthdrs_udp, FALSE},
|
||||
{"ipv6.SrcAddr == ::1", &pkt_ipv6_exthdrs_udp, TRUE},
|
||||
{"ipv6.SrcAddr == ::2", &pkt_ipv6_exthdrs_udp, FALSE},
|
||||
{"ipv6.SrcAddr == ::8.8.4.4", &pkt_ipv6_exthdrs_udp, FALSE},
|
||||
{"ipv6.SrcAddr < abcd::1", &pkt_ipv6_exthdrs_udp, TRUE},
|
||||
{"ipv6.SrcAddr <= abcd::1", &pkt_ipv6_exthdrs_udp, TRUE},
|
||||
{"ipv6.SrcAddr != abcd::1", &pkt_ipv6_exthdrs_udp, TRUE},
|
||||
@@ -332,7 +336,7 @@ int main(void)
|
||||
Sleep(100);
|
||||
|
||||
// Run tests:
|
||||
size_t num_tests = sizeof(tests) / sizeof(struct test);
|
||||
size_t num_tests = sizeof(tests) / sizeof(struct test), passed_tests = 0;
|
||||
for (i = 0; i < num_tests; i++)
|
||||
{
|
||||
char *filter = tests[i].filter;
|
||||
@@ -352,6 +356,7 @@ int main(void)
|
||||
{
|
||||
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
|
||||
printf("PASSED");
|
||||
passed_tests++;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -376,6 +381,9 @@ int main(void)
|
||||
WinDivertClose(upper_handle);
|
||||
WinDivertClose(lower_handle);
|
||||
|
||||
printf("\npassed = %.2f%%\n",
|
||||
((double)passed_tests / (double)num_tests) * 100.0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user