Add WinDivert support for matching ARP packets.

This commit is contained in:
basil00
2023-02-19 07:39:58 +08:00
parent 4b7716edb0
commit 54153c425b
11 changed files with 355 additions and 105 deletions
+14 -4
View File
@@ -105,11 +105,16 @@ static UINT64 WinDivertXXH64Avalanche(UINT64 h64)
/*
* WinDivert packet hash function.
*/
static UINT64 WinDivertHashPacket(UINT64 seed,
const WINDIVERT_ETHHDR *eth_header, const WINDIVERT_IPHDR *ip_header,
const WINDIVERT_IPV6HDR *ipv6_header, const WINDIVERT_ICMPHDR *icmp_header,
static UINT64 WinDivertHashPacket(
UINT64 seed,
const WINDIVERT_ETHHDR *eth_header,
const WINDIVERT_ARPHDR *arp_header,
const WINDIVERT_IPHDR *ip_header,
const WINDIVERT_IPV6HDR *ipv6_header,
const WINDIVERT_ICMPHDR *icmp_header,
const WINDIVERT_ICMPV6HDR *icmpv6_header,
const WINDIVERT_TCPHDR *tcp_header, const WINDIVERT_UDPHDR *udp_header)
const WINDIVERT_TCPHDR *tcp_header,
const WINDIVERT_UDPHDR *udp_header)
{
UINT64 h64, v1, v2, v3, v4, v[4];
const UINT64 *data64;
@@ -207,6 +212,11 @@ static UINT64 WinDivertHashPacket(UINT64 seed,
v1 = WinDivertXXH64Round(v1, data64[0] & 0xFFFFFFFFFFFFull);
data64 = (const UINT64 *)eth_header->SrcAddr;
v2 = WinDivertXXH64Round(v2, data64[0]);
if (arp_header != NULL)
{
data64 = (const UINT64 *)arp_header;
v3 = WinDivertXXH64Round(v3, data64[0]);
}
}
h64 = WINDIVERT_ROTL64(v1, 1) + WINDIVERT_ROTL64(v2, 7) +
+121 -10
View File
@@ -49,6 +49,9 @@
#define IPPROTO_ICMPV6 58
#define IPPROTO_NONE 59
#define IPPROTO_DSTOPTS 60
#define ETHERTYPE_ARP 0x0806
#define ETHERTYPE_IP 0x0800
#define ETHERTYPE_IPV6 0x86dd
/*
* Filter tokens.
@@ -146,6 +149,12 @@ typedef enum
TOKEN_ETH_DST_ADDR,
TOKEN_ETH_SRC_ADDR,
TOKEN_ETH_TYPE,
TOKEN_ARP,
TOKEN_ARP_HARDWARE,
TOKEN_ARP_PROTOCOL,
TOKEN_ARP_HARD_LENGTH,
TOKEN_ARP_PROT_LENGTH,
TOKEN_ARP_OPCODE,
TOKEN_LAYER_FLOW,
TOKEN_LAYER_SOCKET,
TOKEN_LAYER_NETWORK,
@@ -168,6 +177,9 @@ typedef enum
TOKEN_MACRO_UDP,
TOKEN_MACRO_ICMP,
TOKEN_MACRO_ICMPV6,
TOKEN_MACRO_ARP,
TOKEN_MACRO_IP,
TOKEN_MACRO_IPV6,
TOKEN_OPEN,
TOKEN_CLOSE,
TOKEN_SQUARE_OPEN,
@@ -515,12 +527,20 @@ static PTOKEN_INFO WinDivertTokenLookup(PTOKEN_INFO token_info,
/*
* Parse IPv4/IPv6/ICMP/ICMPv6/TCP/UDP headers from a raw packet.
*/
BOOL WinDivertHelperParsePacket(const VOID *pPacket, UINT packetLen,
WINDIVERT_LAYER layer, PWINDIVERT_ETHHDR *ppEthHeader,
PWINDIVERT_IPHDR *ppIPHeader, PWINDIVERT_IPV6HDR *ppIPv6Header,
UINT8 *pProtocol, PWINDIVERT_ICMPHDR *ppICMPHeader,
PWINDIVERT_ICMPV6HDR *ppICMPv6Header, PWINDIVERT_TCPHDR *ppTCPHeader,
PWINDIVERT_UDPHDR *ppUDPHeader, PVOID *ppData, UINT *pDataLen)
BOOL WinDivertHelperParsePacket(
const VOID *pPacket,
UINT packetLen,
WINDIVERT_LAYER layer,
PWINDIVERT_ETHHDR *ppEthHeader,
PWINDIVERT_ARPHDR *ppArpHeader,
PWINDIVERT_IPHDR *ppIPHeader,
PWINDIVERT_IPV6HDR *ppIPv6Header,
UINT8 *pProtocol,
PWINDIVERT_ICMPHDR *ppICMPHeader,
PWINDIVERT_ICMPV6HDR *ppICMPv6Header,
PWINDIVERT_TCPHDR *ppTCPHeader,
PWINDIVERT_UDPHDR *ppUDPHeader,
PVOID *ppData, UINT *pDataLen)
{
WINDIVERT_PACKET info;
if (!WinDivertHelperParsePacketEx(pPacket, packetLen, layer, &info))
@@ -540,6 +560,10 @@ BOOL WinDivertHelperParsePacket(const VOID *pPacket, UINT packetLen,
{
*ppEthHeader = info.EthHeader;
}
if (ppArpHeader != NULL)
{
*ppArpHeader = info.ArpHeader;
}
if (ppIPHeader != NULL)
{
*ppIPHeader = info.IPHeader;
@@ -659,6 +683,15 @@ static BOOL WinDivertExpandMacro(KIND kind, WINDIVERT_LAYER layer, UINT32 *val)
case TOKEN_MACRO_ICMPV6:
*val = IPPROTO_ICMPV6;
return TRUE;
case TOKEN_MACRO_ARP:
*val = ETHERTYPE_ARP;
return (layer == WINDIVERT_LAYER_ETHERNET);
case TOKEN_MACRO_IP:
*val = ETHERTYPE_IP;
return (layer == WINDIVERT_LAYER_ETHERNET);
case TOKEN_MACRO_IPV6:
*val = ETHERTYPE_IPV6;
return (layer == WINDIVERT_LAYER_ETHERNET);
default:
return FALSE;
}
@@ -673,6 +706,7 @@ static ERROR WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer,
static const TOKEN_INFO token_info[] =
{
{"ACCEPT", TOKEN_EVENT_ACCEPT },
{"ARP", TOKEN_MACRO_ARP },
{"BIND", TOKEN_EVENT_BIND },
{"CLOSE", TOKEN_EVENT_CLOSE },
{"CONNECT", TOKEN_EVENT_CONNECT },
@@ -684,6 +718,8 @@ static ERROR WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer,
{"FLOW", TOKEN_LAYER_FLOW },
{"ICMP", TOKEN_MACRO_ICMP },
{"ICMPV6", TOKEN_MACRO_ICMPV6 },
{"IP", TOKEN_MACRO_IP },
{"IPV6", TOKEN_MACRO_IPV6 },
{"LISTEN", TOKEN_EVENT_LISTEN },
{"NETWORK", TOKEN_LAYER_NETWORK },
{"NETWORK_FORWARD", TOKEN_LAYER_NETWORK_FORWARD},
@@ -695,6 +731,12 @@ static ERROR WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer,
{"TRUE", TOKEN_MACRO_TRUE },
{"UDP", TOKEN_MACRO_UDP },
{"and", TOKEN_AND },
{"arp", TOKEN_ARP },
{"arp.HardLength", TOKEN_ARP_HARD_LENGTH },
{"arp.Hardware", TOKEN_ARP_HARDWARE },
{"arp.ProtLength", TOKEN_ARP_PROT_LENGTH },
{"arp.Protocol", TOKEN_ARP_PROTOCOL },
{"arp.Opcode", TOKEN_ARP_OPCODE },
{"b", TOKEN_BYTES },
{"endpointId", TOKEN_ENDPOINT_ID },
{"eth.DstAddr", TOKEN_ETH_DST_ADDR },
@@ -1114,6 +1156,12 @@ static PEXPR WinDivertMakeVar(KIND kind, PERROR error)
{{{0}}, TOKEN_ETH_DST_ADDR},
{{{0}}, TOKEN_ETH_SRC_ADDR},
{{{0}}, TOKEN_ETH_TYPE},
{{{0}}, TOKEN_ARP},
{{{0}}, TOKEN_ARP_HARDWARE},
{{{0}}, TOKEN_ARP_PROTOCOL},
{{{0}}, TOKEN_ARP_HARD_LENGTH},
{{{0}}, TOKEN_ARP_PROT_LENGTH},
{{{0}}, TOKEN_ARP_OPCODE},
};
// Binary search:
@@ -1268,6 +1316,7 @@ static PEXPR WinDivertParseTest(HANDLE pool, TOKEN *toks, UINT *i, PERROR error)
case TOKEN_SUB_IF_IDX:
case TOKEN_LOOPBACK:
case TOKEN_IMPOSTOR:
case TOKEN_ARP:
case TOKEN_IP:
case TOKEN_IPV6:
case TOKEN_ICMP:
@@ -1287,6 +1336,11 @@ static PEXPR WinDivertParseTest(HANDLE pool, TOKEN *toks, UINT *i, PERROR error)
case TOKEN_ETH_DST_ADDR:
case TOKEN_ETH_SRC_ADDR:
case TOKEN_ETH_TYPE:
case TOKEN_ARP_HARDWARE:
case TOKEN_ARP_PROTOCOL:
case TOKEN_ARP_HARD_LENGTH:
case TOKEN_ARP_PROT_LENGTH:
case TOKEN_ARP_OPCODE:
case TOKEN_IP_HDR_LENGTH:
case TOKEN_IP_TOS:
case TOKEN_IP_LENGTH:
@@ -1617,6 +1671,7 @@ static void WinDivertSimplifyTest(PEXPR test)
case TOKEN_INBOUND:
case TOKEN_OUTBOUND:
case TOKEN_FRAGMENT:
case TOKEN_ARP:
case TOKEN_IP:
case TOKEN_IPV6:
case TOKEN_ICMP:
@@ -1633,6 +1688,11 @@ static void WinDivertSimplifyTest(PEXPR test)
type = TOKEN_TCP;
lb[0] = 0; ub[0] = 0x0F;
break;
case TOKEN_ARP_HARD_LENGTH:
case TOKEN_ARP_PROT_LENGTH:
type = TOKEN_ARP;
lb[0] = 0; ub[0] = 0xFF;
break;
case TOKEN_IP_TTL:
case TOKEN_IP_PROTOCOL:
type = TOKEN_IP;
@@ -1674,6 +1734,12 @@ static void WinDivertSimplifyTest(PEXPR test)
case TOKEN_ETH_TYPE:
lb[0] = 0; ub[0] = 0xFFFF;
break;
case TOKEN_ARP_HARDWARE:
case TOKEN_ARP_PROTOCOL:
case TOKEN_ARP_OPCODE:
type = TOKEN_ARP;
lb[0] = 0; ub[0] = 0xFFFF;
break;
case TOKEN_IP_TOS:
case TOKEN_IP_LENGTH:
case TOKEN_IP_ID:
@@ -1984,6 +2050,8 @@ static UINT32 WinDivertKindToField(KIND kind)
return WINDIVERT_FILTER_FIELD_LAYER;
case TOKEN_PRIORITY:
return WINDIVERT_FILTER_FIELD_PRIORITY;
case TOKEN_ARP:
return WINDIVERT_FILTER_FIELD_ARP;
case TOKEN_IP:
return WINDIVERT_FILTER_FIELD_IP;
case TOKEN_IPV6:
@@ -2002,6 +2070,16 @@ static UINT32 WinDivertKindToField(KIND kind)
return WINDIVERT_FILTER_FIELD_ETH_SRC_ADDR;
case TOKEN_ETH_TYPE:
return WINDIVERT_FILTER_FIELD_ETH_TYPE;
case TOKEN_ARP_HARDWARE:
return WINDIVERT_FILTER_FIELD_ARP_HARDWARE;
case TOKEN_ARP_PROTOCOL:
return WINDIVERT_FILTER_FIELD_ARP_PROTOCOL;
case TOKEN_ARP_HARD_LENGTH:
return WINDIVERT_FILTER_FIELD_ARP_HARD_LENGTH;
case TOKEN_ARP_PROT_LENGTH:
return WINDIVERT_FILTER_FIELD_ARP_PROT_LENGTH;
case TOKEN_ARP_OPCODE:
return WINDIVERT_FILTER_FIELD_ARP_OPCODE;
case TOKEN_IP_HDR_LENGTH:
return WINDIVERT_FILTER_FIELD_IP_HDRLENGTH;
case TOKEN_IP_TOS:
@@ -2613,6 +2691,7 @@ BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
DWORD error;
WINDIVERT_PACKET info;
PWINDIVERT_ETHHDR eth_header = NULL;
PWINDIVERT_ARPHDR arp_header = NULL;
PWINDIVERT_IPHDR ip_header = NULL;
PWINDIVERT_IPV6HDR ipv6_header = NULL;
PWINDIVERT_ICMPHDR icmp_header = NULL;
@@ -2655,6 +2734,7 @@ BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
}
protocol = info.Protocol;
eth_header = info.EthHeader;
arp_header = info.ArpHeader;
ip_header = info.IPHeader;
ipv6_header = info.IPv6Header;
icmp_header = info.ICMPHeader;
@@ -2743,6 +2823,7 @@ BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
socket_data,
reflect_data,
eth_header,
arp_header,
ip_header,
ipv6_header,
icmp_header,
@@ -3140,6 +3221,8 @@ static PEXPR WinDivertDecompileTest(HANDLE pool, PWINDIVERT_FILTER test)
kind = TOKEN_IF_IDX; break;
case WINDIVERT_FILTER_FIELD_SUBIFIDX:
kind = TOKEN_SUB_IF_IDX; break;
case WINDIVERT_FILTER_FIELD_ARP:
kind = TOKEN_ARP; break;
case WINDIVERT_FILTER_FIELD_IP:
kind = TOKEN_IP; break;
case WINDIVERT_FILTER_FIELD_IPV6:
@@ -3158,6 +3241,16 @@ static PEXPR WinDivertDecompileTest(HANDLE pool, PWINDIVERT_FILTER test)
kind = TOKEN_ETH_SRC_ADDR; break;
case WINDIVERT_FILTER_FIELD_ETH_TYPE:
kind = TOKEN_ETH_TYPE; break;
case WINDIVERT_FILTER_FIELD_ARP_HARDWARE:
kind = TOKEN_ARP_HARDWARE; break;
case WINDIVERT_FILTER_FIELD_ARP_PROTOCOL:
kind = TOKEN_ARP_PROTOCOL; break;
case WINDIVERT_FILTER_FIELD_ARP_HARD_LENGTH:
kind = TOKEN_ARP_HARD_LENGTH; break;
case WINDIVERT_FILTER_FIELD_ARP_PROT_LENGTH:
kind = TOKEN_ARP_PROT_LENGTH; break;
case WINDIVERT_FILTER_FIELD_ARP_OPCODE:
kind = TOKEN_ARP_OPCODE; break;
case WINDIVERT_FILTER_FIELD_IP_HDRLENGTH:
kind = TOKEN_IP_HDR_LENGTH; break;
case WINDIVERT_FILTER_FIELD_IP_TOS:
@@ -3847,6 +3940,7 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
case TOKEN_INBOUND:
case TOKEN_OUTBOUND:
case TOKEN_FRAGMENT:
case TOKEN_ARP:
case TOKEN_IP:
case TOKEN_IPV6:
case TOKEN_ICMP:
@@ -3928,6 +4022,9 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
case TOKEN_ICMP_CHECKSUM:
case TOKEN_ICMPV6_CHECKSUM:
case TOKEN_ETH_TYPE:
case TOKEN_ARP_HARDWARE:
case TOKEN_ARP_PROTOCOL:
case TOKEN_ARP_OPCODE:
is_hex = TRUE;
break;
default:
@@ -4186,6 +4283,8 @@ static void WinDivertFormatExpr(PWINDIVERT_STREAM stream, PEXPR expr,
WinDivertPutString(stream, "ifIdx"); return;
case TOKEN_SUB_IF_IDX:
WinDivertPutString(stream, "subIfIdx"); return;
case TOKEN_ARP:
WinDivertPutString(stream, "arp"); return;
case TOKEN_IP:
WinDivertPutString(stream, "ip"); return;
case TOKEN_IPV6:
@@ -4204,6 +4303,16 @@ static void WinDivertFormatExpr(PWINDIVERT_STREAM stream, PEXPR expr,
WinDivertPutString(stream, "eth.SrcAddr"); return;
case TOKEN_ETH_TYPE:
WinDivertPutString(stream, "eth.Type"); return;
case TOKEN_ARP_HARDWARE:
WinDivertPutString(stream, "arp.Hardware"); return;
case TOKEN_ARP_PROTOCOL:
WinDivertPutString(stream, "arp.Protocol"); return;
case TOKEN_ARP_HARD_LENGTH:
WinDivertPutString(stream, "arp.HardLength"); return;
case TOKEN_ARP_PROT_LENGTH:
WinDivertPutString(stream, "arp.ProtLength"); return;
case TOKEN_ARP_OPCODE:
WinDivertPutString(stream, "arp.Opcode"); return;
case TOKEN_IP_HDR_LENGTH:
WinDivertPutString(stream, "ip.HdrLength"); return;
case TOKEN_IP_TOS:
@@ -4458,6 +4567,7 @@ UINT64 WinDivertHelperHashPacket(const VOID *pPacket, UINT packetLen,
WINDIVERT_LAYER layer, UINT64 seed)
{
PWINDIVERT_ETHHDR eth_header = NULL;
PWINDIVERT_ARPHDR arp_header = NULL;
PWINDIVERT_IPHDR ip_header = NULL;
PWINDIVERT_IPV6HDR ipv6_header = NULL;
PWINDIVERT_ICMPHDR icmp_header = NULL;
@@ -4466,13 +4576,14 @@ UINT64 WinDivertHelperHashPacket(const VOID *pPacket, UINT packetLen,
PWINDIVERT_UDPHDR udp_header = NULL;
if (!WinDivertHelperParsePacket((PVOID)pPacket, packetLen, layer,
&eth_header, &ip_header, &ipv6_header, NULL, &icmp_header,
&icmpv6_header, &tcp_header, &udp_header, NULL, NULL))
&eth_header, &arp_header, &ip_header, &ipv6_header, NULL,
&icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL,
NULL))
{
return 0;
}
return WinDivertHashPacket(seed, eth_header, ip_header, ipv6_header,
icmp_header, icmpv6_header, tcp_header, udp_header);
return WinDivertHashPacket(seed, eth_header, arp_header, ip_header,
ipv6_header, icmp_header, icmpv6_header, tcp_header, udp_header);
}
/*
+63 -17
View File
@@ -1,6 +1,6 @@
/*
* windivert_shared.c
* (C) 2019, all rights reserved,
* (C) 2023, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -68,6 +68,7 @@
#define ntohl48(x) BYTESWAP48(x)
#define htonl48(x) BYTESWAP48(x)
#define ETHERTYPE_ARP 0x0806
#define ETHERTYPE_IP 0x0800
#define ETHERTYPE_IPV6 0x86DD
@@ -188,6 +189,7 @@ typedef struct
UINT32 Extended:1;
UINT32 Reserved1:6;
PWINDIVERT_ETHHDR EthHeader;
PWINDIVERT_ARPHDR ArpHeader;
PWINDIVERT_IPHDR IPHeader;
PWINDIVERT_IPV6HDR IPv6Header;
PWINDIVERT_ICMPHDR ICMPHeader;
@@ -393,6 +395,7 @@ static BOOL WinDivertHelperParsePacketEx(const VOID *pPacket,
UINT packetLen, WINDIVERT_LAYER layer, PWINDIVERT_PACKET pInfo)
{
PWINDIVERT_ETHHDR eth_header = NULL;
PWINDIVERT_ARPHDR arp_header = NULL;
PWINDIVERT_IPHDR ip_header = NULL;
PWINDIVERT_IPV6HDR ipv6_header = NULL;
PWINDIVERT_ICMPHDR icmp_header = NULL;
@@ -439,6 +442,16 @@ static BOOL WinDivertHelperParsePacketEx(const VOID *pPacket,
goto WinDivertHelperParsePacketExit;
}
break;
case ETHERTYPE_ARP:
if (data_len < sizeof(WINDIVERT_ARPHDR))
{
goto WinDivertHelperParsePacketExit;
}
arp_header = (PWINDIVERT_ARPHDR)data;
data = (PVOID)(arp_header + 1);
data_len -= sizeof(WINDIVERT_ARPHDR);
header_len += sizeof(WINDIVERT_ARPHDR);
goto WinDivertHelperParsePacketExit;
default:
goto WinDivertHelperParsePacketExit;
}
@@ -626,6 +639,7 @@ WinDivertHelperParsePacketExit:
pInfo->Extended = (ip_total_len < ip_packet_len? 1: 0);
pInfo->Reserved1 = 0;
pInfo->EthHeader = eth_header;
pInfo->ArpHeader = arp_header;
pInfo->IPHeader = ip_header;
pInfo->IPv6Header = ipv6_header;
pInfo->ICMPHeader = icmp_header;
@@ -1042,6 +1056,12 @@ static BOOL WinDivertValidateField(WINDIVERT_LAYER layer, UINT32 field)
LE_____, /* WINDIVERT_FILTER_FIELD_ETH_DST_ADDR */
LE_____, /* WINDIVERT_FILTER_FIELD_ETH_SRC_ADDR */
LE_____, /* WINDIVERT_FILTER_FIELD_ETH_TYPE */
LE_____, /* WINDIVERT_FILTER_FIELD_ARP */
LE_____, /* WINDIVERT_FILTER_FIELD_ARP_HARDWARE */
LE_____, /* WINDIVERT_FILTER_FIELD_ARP_PROTOCOL */
LE_____, /* WINDIVERT_FILTER_FIELD_ARP_HARD_LENGTH */
LE_____, /* WINDIVERT_FILTER_FIELD_ARP_PROT_LENGTH */
LE_____, /* WINDIVERT_FILTER_FIELD_ARP_OPCODE */
};
if (field > WINDIVERT_FILTER_FIELD_MAX)
@@ -1124,6 +1144,7 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
const WINDIVERT_DATA_SOCKET *socket_data,
const WINDIVERT_DATA_REFLECT *reflect_data,
const WINDIVERT_ETHHDR *eth_header,
const WINDIVERT_ARPHDR *arp_header,
const WINDIVERT_IPHDR *ip_header,
const WINDIVERT_IPV6HDR *ipv6_header,
const WINDIVERT_ICMPHDR *icmp_header,
@@ -1166,8 +1187,8 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
if (random64 == 0)
{
random64 = WinDivertHashPacket((UINT64)timestamp,
eth_header, ip_header, ipv6_header, icmp_header,
icmpv6_header, tcp_header, udp_header);
eth_header, arp_header, ip_header, ipv6_header,
icmp_header, icmpv6_header, tcp_header, udp_header);
random64 |= 0xFF00000000000000ull; // Make non-zero.
}
break;
@@ -1176,6 +1197,13 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
case WINDIVERT_FILTER_FIELD_ETH_TYPE:
result = (eth_header != NULL);
break;
case WINDIVERT_FILTER_FIELD_ARP_HARDWARE:
case WINDIVERT_FILTER_FIELD_ARP_PROTOCOL:
case WINDIVERT_FILTER_FIELD_ARP_HARD_LENGTH:
case WINDIVERT_FILTER_FIELD_ARP_PROT_LENGTH:
case WINDIVERT_FILTER_FIELD_ARP_OPCODE:
result = (arp_header != NULL);
break;
case WINDIVERT_FILTER_FIELD_IP_HDRLENGTH:
case WINDIVERT_FILTER_FIELD_IP_TOS:
case WINDIVERT_FILTER_FIELD_IP_LENGTH:
@@ -1358,6 +1386,9 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
case WINDIVERT_FILTER_FIELD_IMPOSTOR:
val[0] = (UINT32)impostor;
break;
case WINDIVERT_FILTER_FIELD_ARP:
val[0] = (UINT32)(arp_header != NULL);
break;
case WINDIVERT_FILTER_FIELD_IP:
val[0] = (UINT32)(ip_header != NULL);
break;
@@ -1446,21 +1477,36 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
break;
case WINDIVERT_FILTER_FIELD_ETH_DST_ADDR:
case WINDIVERT_FILTER_FIELD_ETH_SRC_ADDR:
big = TRUE;
eth_addr =
(filter[ip].field == WINDIVERT_FILTER_FIELD_ETH_DST_ADDR?
eth_header->DstAddr: eth_header->SrcAddr);
val[0] = ((UINT32)eth_addr[2] << 24) |
((UINT32)eth_addr[3] << 16) |
((UINT32)eth_addr[4] << 8) |
((UINT32)eth_addr[5]);
val[1] = ((UINT32)eth_addr[0] << 8) |
((UINT32)eth_addr[1]);
val[2] = val[3] = 0;
break;
big = TRUE;
eth_addr =
(filter[ip].field == WINDIVERT_FILTER_FIELD_ETH_DST_ADDR?
eth_header->DstAddr: eth_header->SrcAddr);
val[0] = ((UINT32)eth_addr[2] << 24) |
((UINT32)eth_addr[3] << 16) |
((UINT32)eth_addr[4] << 8) |
((UINT32)eth_addr[5]);
val[1] = ((UINT32)eth_addr[0] << 8) |
((UINT32)eth_addr[1]);
val[2] = val[3] = 0;
break;
case WINDIVERT_FILTER_FIELD_ETH_TYPE:
val[0] = (UINT32)ntohs(eth_header->Type);
break;
val[0] = (UINT32)ntohs(eth_header->Type);
break;
case WINDIVERT_FILTER_FIELD_ARP_HARDWARE:
val[0] = (UINT32)ntohs(arp_header->Hardware);
break;
case WINDIVERT_FILTER_FIELD_ARP_PROTOCOL:
val[0] = (UINT32)ntohs(arp_header->Protocol);
break;
case WINDIVERT_FILTER_FIELD_ARP_HARD_LENGTH:
val[0] = (UINT32)arp_header->HardLength;
break;
case WINDIVERT_FILTER_FIELD_ARP_PROT_LENGTH:
val[0] = (UINT32)arp_header->ProtLength;
break;
case WINDIVERT_FILTER_FIELD_ARP_OPCODE:
val[0] = (UINT32)ntohs(arp_header->Opcode);
break;
case WINDIVERT_FILTER_FIELD_IP_HDRLENGTH:
val[0] = (UINT32)ip_header->HdrLength;
break;
+79 -47
View File
@@ -35,27 +35,28 @@
<li><a href="#helper_programming_api">6. Helper Programming API</a>
<ul>
<li><a href="#divert_ethhdr">6.1 WINDIVERT_ETHHDR</a></li>
<li><a href="#divert_iphdr">6.2 WINDIVERT_IPHDR</a></li>
<li><a href="#divert_ipv6hdr">6.3 WINDIVERT_IPV6HDR</a></li>
<li><a href="#divert_icmphdr">6.4 WINDIVERT_ICMPHDR</a></li>
<li><a href="#divert_icmpv6hdr">6.5 WINDIVERT_ICMPV6HDR</a></li>
<li><a href="#divert_tcphdr">6.6 WINDIVERT_TCPHDR</a></li>
<li><a href="#divert_udphdr">6.7 WINDIVERT_UDPHDR</a></li>
<li><a href="#divert_helper_parse_packet">6.8 WinDivertHelperParsePacket</a></li>
<li><a href="#divert_helper_hash_packet">6.9 WinDivertHelperHashPacket</a></li>
<li><a href="#divert_helper_parse_mac_address">6.10 WinDivertHelperParseMACAddress</a></li>
<li><a href="#divert_helper_parse_ipv4_address">6.11 WinDivertHelperParseIPv4Address</a></li>
<li><a href="#divert_helper_parse_ipv6_address">6.12 WinDivertHelperParseIPv6Address</a></li>
<li><a href="#divert_helper_format_mac_address">6.13 WinDivertHelperFormatMacAddress</a></li>
<li><a href="#divert_helper_format_ipv4_address">6.14 WinDivertHelperFormatIPv4Address</a></li>
<li><a href="#divert_helper_format_ipv6_address">6.15 WinDivertHelperFormatIPv6Address</a></li>
<li><a href="#divert_helper_calc_checksums">6.16 WinDivertHelperCalcChecksums</a></li>
<li><a href="#divert_helper_dec_ttl">6.17 WinDivertHelperDecrementTTL</a></li>
<li><a href="#divert_helper_compile_filter">6.18 WinDivertHelperCompileFilter</a></li>
<li><a href="#divert_helper_eval_filter">6.19 WinDivertHelperEvalFilter</a></li>
<li><a href="#divert_helper_format_filter">6.20 WinDivertHelperFormatFilter</a></li>
<li><a href="#divert_helper_ntoh">6.21 WinDivertHelperNtoh*</a></li>
<li><a href="#divert_helper_hton">6.22 WinDivertHelperHton*</a></li>
<li><a href="#divert_arphdr">6.2 WINDIVERT_ARPHDR</a></li>
<li><a href="#divert_iphdr">6.3 WINDIVERT_IPHDR</a></li>
<li><a href="#divert_ipv6hdr">6.4 WINDIVERT_IPV6HDR</a></li>
<li><a href="#divert_icmphdr">6.5 WINDIVERT_ICMPHDR</a></li>
<li><a href="#divert_icmpv6hdr">6.6 WINDIVERT_ICMPV6HDR</a></li>
<li><a href="#divert_tcphdr">6.7 WINDIVERT_TCPHDR</a></li>
<li><a href="#divert_udphdr">6.8 WINDIVERT_UDPHDR</a></li>
<li><a href="#divert_helper_parse_packet">6.9 WinDivertHelperParsePacket</a></li>
<li><a href="#divert_helper_hash_packet">6.10 WinDivertHelperHashPacket</a></li>
<li><a href="#divert_helper_parse_mac_address">6.11 WinDivertHelperParseMACAddress</a></li>
<li><a href="#divert_helper_parse_ipv4_address">6.12 WinDivertHelperParseIPv4Address</a></li>
<li><a href="#divert_helper_parse_ipv6_address">6.13 WinDivertHelperParseIPv6Address</a></li>
<li><a href="#divert_helper_format_mac_address">6.14 WinDivertHelperFormatMACAddress</a></li>
<li><a href="#divert_helper_format_ipv4_address">6.15 WinDivertHelperFormatIPv4Address</a></li>
<li><a href="#divert_helper_format_ipv6_address">6.16 WinDivertHelperFormatIPv6Address</a></li>
<li><a href="#divert_helper_calc_checksums">6.17 WinDivertHelperCalcChecksums</a></li>
<li><a href="#divert_helper_dec_ttl">6.18 WinDivertHelperDecrementTTL</a></li>
<li><a href="#divert_helper_compile_filter">6.19 WinDivertHelperCompileFilter</a></li>
<li><a href="#divert_helper_eval_filter">6.20 WinDivertHelperEvalFilter</a></li>
<li><a href="#divert_helper_format_filter">6.21 WinDivertHelperFormatFilter</a></li>
<li><a href="#divert_helper_ntoh">6.22 WinDivertHelperNtoh*</a></li>
<li><a href="#divert_helper_hton">6.23 WinDivertHelperHton*</a></li>
</ul>
</li>
<li><a href="#filter_language">7. Filter Language</a>
@@ -2084,7 +2085,31 @@ Ethernet frame header definition.
</p>
</dl></dd>
<a name="divert_iphdr"><h3>6.2 WINDIVERT_IPHDR</h3></a>
<a name="divert_arphdr"><h3>6.2 WINDIVERT_ARPHDR</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
typedef struct
{
UINT16 Hardware;
UINT16 Protocol;
UINT8 HardLength;
UINT8 ProtLength;
UINT16 Opcode;
} <b>WINDIVERT_ARPHDR</b>, *<b>PWINDIVERT_ARPHDR</b>;
</pre>
</td></tr></table>
<dl><dd>
<p>
<b>Fields</b><br>
See <a href="https://en.wikipedia.org/wiki/Address_Resolution_Protocol#Packet_structure">here</a>
for more information.
</p><p>
<b>Remarks</b><br>
ARP header definition.
</p>
</dl></dd>
<a name="divert_iphdr"><h3>6.3 WINDIVERT_IPHDR</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
typedef struct
@@ -2127,7 +2152,7 @@ definitions:
</ul>
</dl></dd>
<a name="divert_ipv6hdr"><h3>6.3 WINDIVERT_IPV6HDR</h3></a>
<a name="divert_ipv6hdr"><h3>6.4 WINDIVERT_IPV6HDR</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
typedef struct
@@ -2163,7 +2188,7 @@ definitions:
</ul>
</dl></dd>
<a name="divert_icmphdr"><h3>6.4 WINDIVERT_ICMPHDR</h3></a>
<a name="divert_icmphdr"><h3>6.5 WINDIVERT_ICMPHDR</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
typedef struct
@@ -2186,7 +2211,7 @@ ICMP header definition.
</p>
</dl></dd>
<a name="divert_icmpv6hdr"><h3>6.5 WINDIVERT_ICMPV6HDR</h3></a>
<a name="divert_icmpv6hdr"><h3>6.6 WINDIVERT_ICMPV6HDR</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
typedef struct
@@ -2209,7 +2234,7 @@ ICMPv6 header definition.
</p>
</dl></dd>
<a name="divert_tcphdr"><h3>6.6 WINDIVERT_TCPHDR</h3></a>
<a name="divert_tcphdr"><h3>6.7 WINDIVERT_TCPHDR</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
typedef struct
@@ -2244,7 +2269,7 @@ TCP header definition.
</p>
</dl></dd>
<a name="divert_udphdr"><h3>6.7 WINDIVERT_UDPHDR</h3></a>
<a name="divert_udphdr"><h3>6.8 WINDIVERT_UDPHDR</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
typedef struct
@@ -2267,7 +2292,7 @@ UDP header definition.
</p>
</dl></dd>
<a name="divert_helper_parse_packet"><h3>6.8 WinDivertHelperParsePacket</h3></a>
<a name="divert_helper_parse_packet"><h3>6.9 WinDivertHelperParsePacket</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
BOOL <b>WinDivertHelperParsePacket</b>(
@@ -2275,6 +2300,7 @@ BOOL <b>WinDivertHelperParsePacket</b>(
__in UINT packetLen,
__in WINDIVERT_LAYER layer,
__out_opt PWINDIVERT_ETHHDR *ppEthHdr,
__out_opt PWINDIVERT_ARPHDR *ppArpHdr,
__out_opt PWINDIVERT_IPHDR *ppIpHdr,
__out_opt PWINDIVERT_IPV6HDR *ppIpv6Hdr,
__out_opt UINT8 *pProtocol,
@@ -2294,6 +2320,7 @@ BOOL <b>WinDivertHelperParsePacket</b>(
<li> <code>packetLen</code>: The total length of the packet(s) <code>pPacket</code>.</li>
<li> <code>layer</code>: The layer.</li>
<li> <code>ppEthHdr</code>: Output pointer to a <code>WINDIVERT_ETHHDR</code>.</li>
<li> <code>ppArpHdr</code>: Output pointer to an <code>WINDIVERT_ARPHDR</code>.</li>
<li> <code>ppIpHdr</code>: Output pointer to a <code>WINDIVERT_IPHDR</code>.</li>
<li> <code>ppIpv6Hdr</code>: Output pointer to a <code>WINDIVERT_IPV6HDR</code>.</li>
<li> <code>pProtocol</code>: Output transport protocol.</li>
@@ -2333,7 +2360,7 @@ for parsing.
This function will succeed if at least one header can be parsed.
</p>
<a name="divert_helper_hash_packet"><h3>6.9 WinDivertHelperHashPacket</h3></a>
<a name="divert_helper_hash_packet"><h3>6.10 WinDivertHelperHashPacket</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
UINT64 <b>WinDivertHelperHashPacket</b>(
@@ -2370,7 +2397,7 @@ The optional <code>seed</code> value is also incorporated into the hash.
<p>
</dd></dl>
<a name="divert_helper_parse_mac_address"><h3>6.10 WinDivertHelperParseMACAddress</h3></a>
<a name="divert_helper_parse_mac_address"><h3>6.11 WinDivertHelperParseMACAddress</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
BOOL <b>WinDivertHelperParseMACAddress</b>(
@@ -2400,7 +2427,7 @@ to convert the result into network-byte-order.
</p>
</dd></dl>
<a name="divert_helper_parse_ipv4_address"><h3>6.11 WinDivertHelperParseIPv4Address</h3></a>
<a name="divert_helper_parse_ipv4_address"><h3>6.12 WinDivertHelperParseIPv4Address</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
BOOL <b>WinDivertHelperParseIPv4Address</b>(
@@ -2429,7 +2456,7 @@ to convert the result into network-byte-order.
</p>
</dd></dl>
<a name="divert_helper_parse_ipv6_address"><h3>6.12 WinDivertHelperParseIPv6Address</h3></a>
<a name="divert_helper_parse_ipv6_address"><h3>6.13 WinDivertHelperParseIPv6Address</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
BOOL <b>WinDivertHelperParseIPv6Address</b>(
@@ -2459,10 +2486,10 @@ to convert the result into network-byte-order.
</p>
</dd></dl>
<a name="divert_helper_format_mac_address"><h3>6.13 WinDivertHelperParseMacAddress</h3></a>
<a name="divert_helper_format_mac_address"><h3>6.14 WinDivertHelperParseMACAddress</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
BOOL <b>WinDivertHelperFormatMacAddress</b>(
BOOL <b>WinDivertHelperFormatMACAddress</b>(
__in const UINT8 *addr,
__out char *buffer,
__in UINT bufLen
@@ -2472,7 +2499,7 @@ BOOL <b>WinDivertHelperFormatMacAddress</b>(
<dl><dd>
<p><b>Parameters</b></p>
<ul>
<li> <code>addr</code>: The Mac address in host-byte order.</li>
<li> <code>addr</code>: The MAC address in host-byte order.</li>
<li> <code>buffer</code>: The buffer to store the formatted string.</li>
<li> <code>bufLen</code>: The length of <code>buffer</code>.
</ul>
@@ -2482,11 +2509,11 @@ BOOL <b>WinDivertHelperFormatMacAddress</b>(
Use <code>GetLastError()</code> to get the reason for the error.
</p><p>
<b>Remarks</b><br>
Convert a Mac address into a string.
Convert a MAC address into a string.
</p>
</dd></dl>
<a name="divert_helper_format_ipv4_address"><h3>6.14 WinDivertHelperParseIPv4Address</h3></a>
<a name="divert_helper_format_ipv4_address"><h3>6.15 WinDivertHelperParseIPv4Address</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
BOOL <b>WinDivertHelperFormatIPv4Address</b>(
@@ -2513,7 +2540,7 @@ Convert an IPv4 address into a string.
</p>
</dd></dl>
<a name="divert_helper_format_ipv6_address"><h3>6.15 WinDivertHelperParseIPv6Address</h3></a>
<a name="divert_helper_format_ipv6_address"><h3>6.16 WinDivertHelperParseIPv6Address</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
BOOL <b>WinDivertHelperFormatIPv6Address</b>(
@@ -2540,7 +2567,7 @@ Convert an IPv6 address into a string.
</p>
</dd></dl>
<a name="divert_helper_calc_checksums"><h3>6.16 WinDivertHelperCalcChecksums</h3></a>
<a name="divert_helper_calc_checksums"><h3>6.17 WinDivertHelperCalcChecksums</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
BOOL <b>WinDivertHelperCalcChecksums</b>(
@@ -2600,7 +2627,7 @@ packet injection.
</p>
</dd></dl>
<a name="divert_helper_dec_ttl"><h3>6.17 WinDivertHelperDecrementTTL</h3></a>
<a name="divert_helper_dec_ttl"><h3>6.18 WinDivertHelperDecrementTTL</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
BOOL <b>WinDivertHelperDecrementTTL</b>(
@@ -2636,7 +2663,7 @@ This function updates the checksum field incrementally.
</p>
</dd></dl>
<a name="divert_helper_compile_filter"><h3>6.18 WinDivertHelperCompileFilter</h3></a>
<a name="divert_helper_compile_filter"><h3>6.19 WinDivertHelperCompileFilter</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
BOOL <b>WinDivertHelperCompileFilter</b>(
@@ -2687,7 +2714,7 @@ objects, and therefore do not need to be deallocated.
<p>
</dd></dl>
<a name="divert_helper_eval_filter"><h3>6.19 WinDivertHelperEvalFilter</h3></a>
<a name="divert_helper_eval_filter"><h3>6.20 WinDivertHelperEvalFilter</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
BOOL <b>WinDivertHelperEvalFilter</b>(
@@ -2733,7 +2760,7 @@ function.
<p>
</dd></dl>
<a name="divert_helper_format_filter"><h3>6.20 WinDivertHelperFormatFilter</h3></a>
<a name="divert_helper_format_filter"><h3>6.21 WinDivertHelperFormatFilter</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
BOOL <b>WinDivertHelperFormatFilter</b>(
@@ -2767,7 +2794,7 @@ returned by <a href="#divert_recv"><code>WinDivertRecv()</code></a>.
</p>
</dd></dl>
<a name="divert_helper_ntoh"><h3>6.21 WinDivertHelperNtoh*</h3></a>
<a name="divert_helper_ntoh"><h3>6.22 WinDivertHelperNtoh*</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
UINT16 <b>WinDivertHelperNtohs</b>(
@@ -2801,11 +2828,11 @@ void <b>WinDivertHelperNtohIPv6Address</b>(
The output value in host byte order.
</p><p>
<b>Remarks</b><br>
Converts a value/IPv6-address from network to host byte-order.
Converts a value/MAC-address/IPv6-address from network to host byte-order.
</p>
</dd></dl>
<a name="divert_helper_hton"><h3>6.22 WinDivertHelperHton*</h3></a>
<a name="divert_helper_hton"><h3>6.23 WinDivertHelperHton*</h3></a>
<table border="1" cellpadding="5"><tr><td>
<pre>
UINT16 <b>WinDivertHelperHtons</b>(
@@ -2839,7 +2866,7 @@ void <b>WinDivertHelperHtonIPv6Address</b>(
The output value in network byte order.
</p><p>
<b>Remarks</b><br>
Converts a value/IPv6-address from host to network byte-order.
Converts a value/MAC-address/IPv6-address from host to network byte-order.
</p>
</dd></dl>
@@ -2945,6 +2972,7 @@ The possible fields are:
<tr><td><code>packet16[i]</code></td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td></td><td></td><td></td><td>The <code>i</code><sup>th</sup> 16-bit word of the packet</td></tr>
<tr><td><code>packet32[i]</code></td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td></td><td></td><td></td><td>The <code>i</code><sup>th</sup> 32-bit word of the packet</td></tr>
<tr><td><code>length</code></td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td></td><td></td><td></td><td>The packet length</td></tr>
<tr><td><code>arp</code></td><td>&#10004;</td><td></td><td></td><td></td><td></td><td></td><td>Is ARP?</td></tr>
<tr><td><code>ip</code></td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td></td><td>Is IPv4?</td></tr>
<tr><td><code>ipv6</code></td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td></td><td>Is IPv6?</td></tr>
<tr><td><code>icmp</code></td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td></td><td>Is ICMP?</td></tr>
@@ -2957,6 +2985,7 @@ The possible fields are:
<tr><td><code>remoteAddr</code></td><td>&#10004;</td><td>&#10004;</td><td></td><td>&#10004;</td><td>&#10004;</td><td></td><td>The remote address</td></tr>
<tr><td><code>remotePort</code></td><td>&#10004;</td><td>&#10004;</td><td></td><td>&#10004;</td><td>&#10004;</td><td></td><td>The remote port</td></tr>
<tr><td><code>eth.*</code></td><td>&#10004;</td><td></td><td></td><td></td><td></td><td></td><td>Ethernet fields (see <code>WINDIVERT_ETHHDR</code>)</td></tr>
<tr><td><code>arp.*</code></td><td>&#10004;</td><td></td><td></td><td></td><td></td><td></td><td>ARP fields (see <code>WINDIVERT_ARPHDR</code>)</td></tr>
<tr><td><code>ip.*</code></td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td></td><td></td><td></td><td>IPv4 fields (see <code>WINDIVERT_IPHDR</code>)</td></tr>
<tr><td><code>ipv6.*</code></td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td></td><td></td><td></td><td>IPv6 fields (see <code>WINDIVERT_IPV6HDR</code>)</td></tr>
<tr><td><code>icmp.*</code></td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td></td><td></td><td></td><td>ICMP fields (see <code>WINDIVERT_ICMPHDR</code>)</td></tr>
@@ -3030,6 +3059,9 @@ The possible macros are:
<tr><th></th><th><code>ETHERNET</code></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>TRUE</code></td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td><code>1</code></td></tr>
<tr><td><code>FALSE</code></td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td><code>0</code></td></tr>
<tr><td><code>IP</code></td><td>&#10004;</td><td></td><td></td><td></td><td></td><td></td><td><code>ETHERTYPE_IP</code> (<code>0x0800</code>)</td></tr>
<tr><td><code>IPV6</code></td><td>&#10004;</td><td></td><td></td><td></td><td></td><td></td><td><code>ETHERTYPE_IPV6</code> (<code>0x86dd</code>)</td></tr>
<tr><td><code>ARP</code></td><td>&#10004;</td><td></td><td></td><td></td><td></td><td></td><td><code>ETHERTYPE_ARP</code> (<code>0x0806</code>)</td></tr>
<tr><td><code>TCP</code></td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td><code>IPPROTO_TCP</code> (<code>6</code>)</td></tr>
<tr><td><code>UDP</code></td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td><code>IPPROTO_UDP</code> (<code>17</code>)</td></tr>
<tr><td><code>ICMP</code></td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td>&#10004;</td><td><code>IPPROTO_ICMP</code> (<code>1</code>)</td></tr>
+15 -3
View File
@@ -1,6 +1,6 @@
/*
* netdump.c
* (C) 2019, all rights reserved,
* (C) 2023, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -68,6 +68,7 @@ int __cdecl main(int argc, char **argv)
UINT packet_len;
WINDIVERT_ADDRESS addr;
PWINDIVERT_ETHHDR eth_header;
PWINDIVERT_ARPHDR arp_header;
PWINDIVERT_IPHDR ip_header;
PWINDIVERT_IPV6HDR ipv6_header;
PWINDIVERT_ICMPHDR icmp_header;
@@ -186,8 +187,9 @@ int __cdecl main(int argc, char **argv)
// Print info about the matching packet.
WinDivertHelperParsePacket(packet, packet_len, addr.Layer,
&eth_header, &ip_header, &ipv6_header, NULL, &icmp_header,
&icmpv6_header, &tcp_header, &udp_header, NULL, NULL);
&eth_header, &arp_header, &ip_header, &ipv6_header, NULL,
&icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL,
NULL);
// Dump packet info:
putchar('\n');
@@ -209,6 +211,16 @@ int __cdecl main(int argc, char **argv)
FOREGROUND_GREEN | FOREGROUND_BLUE);
printf("Ethernet [SrcAddr=%s DstAddr=%s Type=0x%.4X]\n",
src_str, dst_str, ntohs(eth_header->Type));
if (arp_header != NULL)
{
SetConsoleTextAttribute(console,
FOREGROUND_GREEN);
printf("ARP [Hardware=%u Protocol=%u HardLength=%u "
"ProtLength=%u Opcode=%u]\n",
ntohs(arp_header->Hardware), ntohs(arp_header->Protocol),
arp_header->HardLength, arp_header->ProtLength,
ntohs(arp_header->Opcode));
}
}
else
{
+2 -2
View File
@@ -1,6 +1,6 @@
/*
* netfilter.c
* (C) 2019, all rights reserved,
* (C) 2023, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -202,7 +202,7 @@ int __cdecl main(int argc, char **argv)
// Print info about the matching packet.
WinDivertHelperParsePacket(packet, packet_len, recv_addr.Layer, NULL,
&ip_header, &ipv6_header, NULL, &icmp_header, &icmpv6_header,
NULL, &ip_header, &ipv6_header, NULL, &icmp_header, &icmpv6_header,
&tcp_header, &udp_header, NULL, &payload_len);
if (ip_header == NULL && ipv6_header == NULL)
{
+2 -2
View File
@@ -1,6 +1,6 @@
/*
* streamdump.c
* (C) 2019, all rights reserved,
* (C) 2023, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -193,7 +193,7 @@ int __cdecl main(int argc, char **argv)
continue;
}
WinDivertHelperParsePacket(packet, packet_len, addr.Layer, NULL,
WinDivertHelperParsePacket(packet, packet_len, addr.Layer, NULL, NULL,
&ip_header, NULL, NULL, NULL, NULL, &tcp_header, NULL, NULL, NULL);
if (ip_header == NULL || tcp_header == NULL)
{
+2 -2
View File
@@ -1,6 +1,6 @@
/*
* webfilter.c
* (C) 2019, all rights reserved,
* (C) 2023, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -204,7 +204,7 @@ int __cdecl main(int argc, char **argv)
continue;
}
WinDivertHelperParsePacket(packet, packet_len, addr.Layer, NULL,
WinDivertHelperParsePacket(packet, packet_len, addr.Layer, NULL, NULL,
&ip_header, NULL, NULL, NULL, NULL, &tcp_header, NULL, &payload,
&payload_len);
if (ip_header == NULL || tcp_header == NULL || payload == NULL ||
+12 -2
View File
@@ -1,6 +1,6 @@
/*
* windivert.h
* (C) 2019, all rights reserved,
* (C) 2023, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -350,7 +350,7 @@ WINDIVERTEXPORT BOOL WinDivertGetParam(
#endif
/*
* Ethernet/IPv4/IPv6/ICMP/ICMPv6/TCP/UDP header definitions.
* Ethernet/ARP/IPv4/IPv6/ICMP/ICMPv6/TCP/UDP header definitions.
*/
typedef struct
{
@@ -359,6 +359,15 @@ typedef struct
UINT16 Type;
} WINDIVERT_ETHHDR, *PWINDIVERT_ETHHDR;
typedef struct
{
UINT16 Hardware;
UINT16 Protocol;
UINT8 HardLength;
UINT8 ProtLength;
UINT16 Opcode;
} WINDIVERT_ARPHDR, *PWINDIVERT_ARPHDR;
typedef struct
{
UINT8 HdrLength:4;
@@ -526,6 +535,7 @@ WINDIVERTEXPORT BOOL WinDivertHelperParsePacket(
__in UINT packetLen,
__in WINDIVERT_LAYER layer,
__out_opt PWINDIVERT_ETHHDR *ppEthHdr,
__out_opt PWINDIVERT_ARPHDR *ppArpHdr,
__out_opt PWINDIVERT_IPHDR *ppIpHdr,
__out_opt PWINDIVERT_IPV6HDR *ppIpv6Hdr,
__out_opt UINT8 *pProtocol,
+8 -2
View File
@@ -1,6 +1,6 @@
/*
* windivert_device.h
* (C) 2019, all rights reserved,
* (C) 2023, all rights reserved,
*
* This file is part of WinDivert.
*
@@ -153,8 +153,14 @@
#define WINDIVERT_FILTER_FIELD_ETH_DST_ADDR 86
#define WINDIVERT_FILTER_FIELD_ETH_SRC_ADDR 87
#define WINDIVERT_FILTER_FIELD_ETH_TYPE 88
#define WINDIVERT_FILTER_FIELD_ARP 89
#define WINDIVERT_FILTER_FIELD_ARP_HARDWARE 90
#define WINDIVERT_FILTER_FIELD_ARP_PROTOCOL 91
#define WINDIVERT_FILTER_FIELD_ARP_HARD_LENGTH 92
#define WINDIVERT_FILTER_FIELD_ARP_PROT_LENGTH 93
#define WINDIVERT_FILTER_FIELD_ARP_OPCODE 94
#define WINDIVERT_FILTER_FIELD_MAX \
WINDIVERT_FILTER_FIELD_ETH_TYPE
WINDIVERT_FILTER_FIELD_ARP_OPCODE
#define WINDIVERT_FILTER_TEST_EQ 0
#define WINDIVERT_FILTER_TEST_NEQ 1
+37 -14
View File
@@ -489,8 +489,8 @@ static BOOL windivert_get_data(PNET_BUFFER buffer, UINT length, INT min,
INT max, INT idx, PVOID data, UINT size);
static BOOL windivert_parse_headers(PNET_BUFFER buffer, WINDIVERT_LAYER layer,
BOOL ipv4, BOOL *fragment_ptr, PWINDIVERT_ETHHDR *eth_header_ptr,
PWINDIVERT_IPHDR *ip_header_ptr, PWINDIVERT_IPV6HDR *ipv6_header_ptr,
PWINDIVERT_ICMPHDR *icmp_header_ptr,
PWINDIVERT_ARPHDR *arp_header, PWINDIVERT_IPHDR *ip_header_ptr,
PWINDIVERT_IPV6HDR *ipv6_header_ptr, PWINDIVERT_ICMPHDR *icmp_header_ptr,
PWINDIVERT_ICMPV6HDR *icmpv6_header_ptr, PWINDIVERT_TCPHDR *tcp_header_ptr,
PWINDIVERT_UDPHDR *udp_header_ptr, UINT8 *proto_ptr, UINT *header_len_ptr,
UINT *payload_len_ptr);
@@ -1517,7 +1517,6 @@ static void windivert_driver_unload(void)
static NTSTATUS windivert_install_provider()
{
FWPM_PROVIDER0 provider;
NTSTATUS status;
RtlZeroMemory(&provider, sizeof(provider));
provider.providerKey = WINDIVERT_PROVIDER_GUID;
@@ -5811,15 +5810,20 @@ static BOOL windivert_get_data(PNET_BUFFER buffer, UINT length, INT min,
*/
static WINDIVERT_INLINE BOOL windivert_parse_headers(PNET_BUFFER buffer,
WINDIVERT_LAYER layer, BOOL ipv4, BOOL *fragment_ptr,
PWINDIVERT_ETHHDR *eth_header_ptr, PWINDIVERT_IPHDR *ip_header_ptr,
PWINDIVERT_IPV6HDR *ipv6_header_ptr, PWINDIVERT_ICMPHDR *icmp_header_ptr,
PWINDIVERT_ICMPV6HDR *icmpv6_header_ptr, PWINDIVERT_TCPHDR *tcp_header_ptr,
PWINDIVERT_UDPHDR *udp_header_ptr, UINT8 *proto_ptr, UINT *header_len_ptr,
UINT *payload_len_ptr)
PWINDIVERT_ETHHDR *eth_header_ptr,
PWINDIVERT_ARPHDR *arp_header_ptr,
PWINDIVERT_IPHDR *ip_header_ptr,
PWINDIVERT_IPV6HDR *ipv6_header_ptr,
PWINDIVERT_ICMPHDR *icmp_header_ptr,
PWINDIVERT_ICMPV6HDR *icmpv6_header_ptr,
PWINDIVERT_TCPHDR *tcp_header_ptr,
PWINDIVERT_UDPHDR *udp_header_ptr,
UINT8 *proto_ptr, UINT *header_len_ptr, UINT *payload_len_ptr)
{
UINT min_len, total_len, ip_header_len, header_len, packet_len,
payload_len, advance_len;
PWINDIVERT_ETHHDR eth_header = NULL;
PWINDIVERT_ARPHDR arp_header = NULL;
PWINDIVERT_IPHDR ip_header = NULL;
PWINDIVERT_IPV6HDR ipv6_header = NULL;
PWINDIVERT_ICMPHDR icmp_header = NULL;
@@ -5856,6 +5860,9 @@ static WINDIVERT_INLINE BOOL windivert_parse_headers(PNET_BUFFER buffer,
min_len = 64 - sizeof(UINT32);
min_len = (total_len < min_len? total_len: min_len);
min_len -= sizeof(WINDIVERT_ETHHDR);
NdisAdvanceNetBufferDataStart(buffer, sizeof(WINDIVERT_ETHHDR),
FALSE, NULL);
advance_len += sizeof(WINDIVERT_ETHHDR);
switch (RtlUshortByteSwap(eth_header->Type))
{
case ETHERTYPE_IP:
@@ -5864,12 +5871,20 @@ static WINDIVERT_INLINE BOOL windivert_parse_headers(PNET_BUFFER buffer,
case ETHERTYPE_IPV6:
ipv4 = FALSE;
break;
case ETHERTYPE_ARP:
arp_header = (PWINDIVERT_ARPHDR)NdisGetDataBuffer(buffer,
sizeof(WINDIVERT_ARPHDR), NULL, 1, 0);
if (arp_header == NULL)
{
DEBUG("FILTER: REJECT (failed to get ARP header)");
return FALSE;
}
header_len += sizeof(WINDIVERT_ARPHDR);
payload_len -= sizeof(WINDIVERT_ARPHDR);
goto windivert_parse_headers_exit;
default:
goto windivert_parse_headers_exit;
}
NdisAdvanceNetBufferDataStart(buffer, sizeof(WINDIVERT_ETHHDR),
FALSE, NULL);
advance_len += sizeof(WINDIVERT_ETHHDR);
}
// Get the IP header.
@@ -6073,6 +6088,7 @@ windivert_parse_headers_exit:
*fragment_ptr = fragment;
*eth_header_ptr = eth_header;
*arp_header_ptr = arp_header;
*ip_header_ptr = ip_header;
*ipv6_header_ptr = ipv6_header;
*icmp_header_ptr = icmp_header;
@@ -6103,6 +6119,7 @@ static BOOL windivert_filter(PNET_BUFFER buffer, WINDIVERT_LAYER layer,
const WINDIVERT_FILTER *filter)
{
PWINDIVERT_ETHHDR eth_header = NULL;
PWINDIVERT_ARPHDR arp_header = NULL;
PWINDIVERT_IPHDR ip_header = NULL;
PWINDIVERT_IPV6HDR ipv6_header = NULL;
PWINDIVERT_ICMPHDR icmp_header = NULL;
@@ -6125,9 +6142,9 @@ static BOOL windivert_filter(PNET_BUFFER buffer, WINDIVERT_LAYER layer,
case WINDIVERT_LAYER_NETWORK:
case WINDIVERT_LAYER_NETWORK_FORWARD:
if (!windivert_parse_headers(buffer, layer, ipv4, &fragment,
&eth_header, &ip_header, &ipv6_header, &icmp_header,
&icmpv6_header, &tcp_header, &udp_header, &protocol,
&header_len, &payload_len))
&eth_header, &arp_header, &ip_header, &ipv6_header,
&icmp_header, &icmpv6_header, &tcp_header, &udp_header,
&protocol, &header_len, &payload_len))
{
return FALSE;
}
@@ -6174,6 +6191,7 @@ static BOOL windivert_filter(PNET_BUFFER buffer, WINDIVERT_LAYER layer,
socket_data,
reflect_data,
eth_header,
arp_header,
ip_header,
ipv6_header,
icmp_header,
@@ -6365,6 +6383,8 @@ static const WINDIVERT_FILTER *windivert_filter_compile(
case WINDIVERT_FILTER_FIELD_TCP_HDRLENGTH:
ub[0] = 0x0F;
break;
case WINDIVERT_FILTER_FIELD_ARP_HARD_LENGTH:
case WINDIVERT_FILTER_FIELD_ARP_PROT_LENGTH:
case WINDIVERT_FILTER_FIELD_IP_TOS:
case WINDIVERT_FILTER_FIELD_IP_TTL:
case WINDIVERT_FILTER_FIELD_IP_PROTOCOL:
@@ -6386,6 +6406,9 @@ static const WINDIVERT_FILTER *windivert_filter_compile(
ub[0] = 0x1FFF;
break;
case WINDIVERT_FILTER_FIELD_ETH_TYPE:
case WINDIVERT_FILTER_FIELD_ARP_HARDWARE:
case WINDIVERT_FILTER_FIELD_ARP_PROTOCOL:
case WINDIVERT_FILTER_FIELD_ARP_OPCODE:
case WINDIVERT_FILTER_FIELD_IP_LENGTH:
case WINDIVERT_FILTER_FIELD_IP_ID:
case WINDIVERT_FILTER_FIELD_IP_CHECKSUM: