Add a new FLOW layer into WinDivert.

Adds a new WINDIVERT_LAYER_FLOW layer that can:
- Track when flows are established
- Track when existing flows are deleted
This commit is contained in:
basil00
2018-09-30 09:07:16 +08:00
parent e82552153b
commit 6250568974
14 changed files with 1964 additions and 671 deletions
+66 -20
View File
@@ -70,43 +70,90 @@ extern "C" {
/****************************************************************************/
/*
* Divert address.
* WinDivert NETWORK and NETWORK_FORWARD layer data.
*/
typedef struct
{
UINT32 IfIdx; /* Packet's interface index. */
UINT32 SubIfIdx; /* Packet's sub-interface index. */
} WINDIVERT_NETWORK_DATA, *PWINDIVERT_NETWORK_DATA;
/*
* WinDivert FLOW 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_FLOW_DATA, *PWINDIVERT_FLOW_DATA;
/*
* WinDivert address.
*/
typedef struct
{
INT64 Timestamp; /* Packet's timestamp. */
UINT32 IfIdx; /* Packet's interface index. */
UINT32 SubIfIdx; /* Packet's sub-interface index. */
UINT8 Direction:1; /* Packet's direction. */
UINT8 Loopback:1; /* Packet is loopback? */
UINT8 Impostor:1; /* Packet is impostor? */
UINT8 PseudoIPChecksum:1; /* Packet has pseudo IPv4 checksum? */
UINT8 PseudoTCPChecksum:1; /* Packet has pseudo TCP checksum? */
UINT8 PseudoUDPChecksum:1; /* Packet has pseudo UDP checksum? */
UINT8 Reserved:2;
UINT32 Layer:8; /* Packet's layer. */
UINT32 Event:8; /* Packet event. */
UINT32 Outbound:1; /* Packet is outound? */
UINT32 Loopback:1; /* Packet is loopback? */
UINT32 Impostor:1; /* Packet is impostor? */
UINT32 IPv6:1; /* Packet is IPv6? */
UINT32 PseudoIPChecksum:1; /* Packet has pseudo IPv4 checksum? */
UINT32 PseudoTCPChecksum:1; /* Packet has pseudo TCP checksum? */
UINT32 PseudoUDPChecksum:1; /* Packet has pseudo UDP checksum? */
UINT32 Reserved:9;
union
{
WINDIVERT_NETWORK_DATA Network; /* Network layer data. */
WINDIVERT_FLOW_DATA Flow; /* Flow layer data. */
};
} WINDIVERT_ADDRESS, *PWINDIVERT_ADDRESS;
#define WINDIVERT_DIRECTION_OUTBOUND 0
#define WINDIVERT_DIRECTION_INBOUND 1
/*
* Divert layers.
* WinDivert layers.
*/
typedef enum
{
WINDIVERT_LAYER_NETWORK = 0, /* Network layer. */
WINDIVERT_LAYER_NETWORK_FORWARD = 1 /* Network layer (forwarded packets) */
WINDIVERT_LAYER_NETWORK = 1, /* Network layer. */
WINDIVERT_LAYER_NETWORK_FORWARD = 2,/* Network layer (forwarded packets) */
WINDIVERT_LAYER_FLOW = 3 /* Flow layer. */
} WINDIVERT_LAYER, *PWINDIVERT_LAYER;
/*
* Divert flags.
* WinDivert events.
*/
typedef enum
{
WINDIVERT_EVENT_NETWORK_PACKET = 0, /* Network packet. */
WINDIVERT_EVENT_FLOW_ESTABLISHED = 1,
/* Flow established. */
WINDIVERT_EVENT_FLOW_DELETED = 2, /* Flow deleted. */
} WINDIVERT_EVENT, *PWINDIVERT_EVENT;
/*
* WinDivert flags.
*/
#define WINDIVERT_FLAG_SNIFF 1
#define WINDIVERT_FLAG_DROP 2
#define WINDIVERT_FLAG_DEBUG 4
#define WINDIVERT_FLAG_RECV_ONLY 4
#define WINDIVERT_FLAG_READ_ONLY WINDIVERT_FLAG_RECV_ONLY
#define WINDIVERT_FLAG_SEND_ONLY 8
#define WINDIVERT_FLAG_WRITE_ONLY WINDIVERT_FLAG_SEND_ONLY
#define WINDIVERT_FLAG_DEBUG 16
#define WINDIVERT_FLAGS_LAYER_NETWORK 0
#define WINDIVERT_FLAGS_LAYER_NETWORK_FORWARD \
0
#define WINDIVERT_FLAGS_LAYER_FLOW \
(WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_RECV_ONLY)
/*
* Divert parameters.
* WinDivert parameters.
*/
typedef enum
{
@@ -396,7 +443,6 @@ extern WINDIVERTEXPORT BOOL WinDivertHelperCheckFilter(
*/
extern WINDIVERTEXPORT BOOL WinDivertHelperEvalFilter(
__in const char *filter,
__in WINDIVERT_LAYER layer,
__in PVOID pPacket,
__in UINT packetLen,
__in PWINDIVERT_ADDRESS pAddr);
+25 -18
View File
@@ -44,8 +44,8 @@
#define WINDIVERT_KERNEL
#include "windivert.h"
#define WINDIVERT_VERSION 1
#define WINDIVERT_VERSION_MINOR 4
#define WINDIVERT_VERSION 2
#define WINDIVERT_VERSION_MINOR 0
#define WINDIVERT_STR2(s) #s
#define WINDIVERT_STR(s) WINDIVERT_STR2(s)
@@ -59,8 +59,8 @@
#define WINDIVERT_DEVICE_NAME \
L"WinDivert" WINDIVERT_VERSION_LSTR
#define WINDIVERT_IOCTL_VERSION 6
#define WINDIVERT_IOCTL_MAGIC 0xA2BF
#define WINDIVERT_IOCTL_VERSION 7
#define WINDIVERT_IOCTL_MAGIC 0xC7C9
#define WINDIVERT_FILTER_FIELD_ZERO 0
#define WINDIVERT_FILTER_FIELD_INBOUND 1
@@ -122,8 +122,14 @@
#define WINDIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH 57
#define WINDIVERT_FILTER_FIELD_LOOPBACK 58
#define WINDIVERT_FILTER_FIELD_IMPOSTOR 59
#define WINDIVERT_FILTER_FIELD_PROCESSID 60
#define WINDIVERT_FILTER_FIELD_LOCALADDR 61
#define WINDIVERT_FILTER_FIELD_REMOTEADDR 62
#define WINDIVERT_FILTER_FIELD_LOCALPORT 63
#define WINDIVERT_FILTER_FIELD_REMOTEPORT 64
#define WINDIVERT_FILTER_FIELD_PROTOCOL 65
#define WINDIVERT_FILTER_FIELD_MAX \
WINDIVERT_FILTER_FIELD_IMPOSTOR
WINDIVERT_FILTER_FIELD_PROTOCOL
#define WINDIVERT_FILTER_TEST_EQ 0
#define WINDIVERT_FILTER_TEST_NEQ 1
@@ -142,20 +148,21 @@
* WinDivert layers.
*/
#define WINDIVERT_LAYER_DEFAULT WINDIVERT_LAYER_NETWORK
#define WINDIVERT_LAYER_MAX \
WINDIVERT_LAYER_NETWORK_FORWARD
/*
* WinDivert flags.
*/
#define WINDIVERT_FLAGS_ALL \
(WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_DROP | WINDIVERT_FLAG_DEBUG)
(WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_DROP | WINDIVERT_FLAG_RECV_ONLY |\
WINDIVERT_FLAG_SEND_ONLY | WINDIVERT_FLAG_DEBUG)
#define WINDIVERT_FLAGS_EXCLUDE(flags, flag1, flag2) \
(((flags) & ((flag1) | (flag2))) != ((flag1) | (flag2)))
#define WINDIVERT_FLAGS_VALID(flags) \
((((flags) & ~WINDIVERT_FLAGS_ALL) == 0) && \
WINDIVERT_FLAGS_EXCLUDE(flags, WINDIVERT_FLAG_SNIFF, \
WINDIVERT_FLAG_DROP))
WINDIVERT_FLAG_DROP) && \
WINDIVERT_FLAGS_EXCLUDE(flags, WINDIVERT_FLAG_RECV_ONLY, \
WINDIVERT_FLAG_SEND_ONLY))
/*
* WinDivert priorities.
@@ -197,7 +204,7 @@ typedef struct windivert_ioctl_s *windivert_ioctl_t;
*/
struct windivert_ioctl_filter_s
{
UINT8 field; // WINDIVERT_FILTER_FIELD_IP_*
UINT8 field; // WINDIVERT_FILTER_FIELD_*
UINT8 test; // WINDIVERT_FILTER_TEST_*
UINT16 success; // Success continuation.
UINT16 failure; // Fail continuation.
@@ -210,20 +217,20 @@ typedef struct windivert_ioctl_filter_s *windivert_ioctl_filter_t;
* IOCTL codes.
*/
#define IOCTL_WINDIVERT_RECV \
CTL_CODE(FILE_DEVICE_NETWORK, 0x908, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
CTL_CODE(FILE_DEVICE_NETWORK, 0x918, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_WINDIVERT_SEND \
CTL_CODE(FILE_DEVICE_NETWORK, 0x909, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
CTL_CODE(FILE_DEVICE_NETWORK, 0x919, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_WINDIVERT_START_FILTER \
CTL_CODE(FILE_DEVICE_NETWORK, 0x90A, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
CTL_CODE(FILE_DEVICE_NETWORK, 0x91A, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_WINDIVERT_SET_LAYER \
CTL_CODE(FILE_DEVICE_NETWORK, 0x90B, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
CTL_CODE(FILE_DEVICE_NETWORK, 0x91B, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_WINDIVERT_SET_PRIORITY \
CTL_CODE(FILE_DEVICE_NETWORK, 0x90C, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
CTL_CODE(FILE_DEVICE_NETWORK, 0x91C, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_WINDIVERT_SET_FLAGS \
CTL_CODE(FILE_DEVICE_NETWORK, 0x90D, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
CTL_CODE(FILE_DEVICE_NETWORK, 0x91D, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_WINDIVERT_SET_PARAM \
CTL_CODE(FILE_DEVICE_NETWORK, 0x90E, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
CTL_CODE(FILE_DEVICE_NETWORK, 0x91E, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_WINDIVERT_GET_PARAM \
CTL_CODE(FILE_DEVICE_NETWORK, 0x90F, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
CTL_CODE(FILE_DEVICE_NETWORK, 0x91F, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#endif /* __WINDIVERT_DEVICE_H */