diff --git a/dll/windivert_hash.c b/dll/windivert_hash.c index df85523..2f6b999 100644 --- a/dll/windivert_hash.c +++ b/dll/windivert_hash.c @@ -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) + diff --git a/dll/windivert_helper.c b/dll/windivert_helper.c index 9261fd8..e6b3449 100644 --- a/dll/windivert_helper.c +++ b/dll/windivert_helper.c @@ -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, - ð_header, &ip_header, &ipv6_header, NULL, &icmp_header, - &icmpv6_header, &tcp_header, &udp_header, NULL, NULL)) + ð_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); } /* diff --git a/dll/windivert_shared.c b/dll/windivert_shared.c index f708d6a..577cfc9 100644 --- a/dll/windivert_shared.c +++ b/dll/windivert_shared.c @@ -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; diff --git a/doc/windivert.html b/doc/windivert.html index 06ca083..a6abc55 100644 --- a/doc/windivert.html +++ b/doc/windivert.html @@ -35,27 +35,28 @@
+
+typedef struct
+{
+ UINT16 Hardware;
+ UINT16 Protocol;
+ UINT8 HardLength;
+ UINT8 ProtLength;
+ UINT16 Opcode;
+} WINDIVERT_ARPHDR, *PWINDIVERT_ARPHDR;
+
+ |
+Fields
+See here
+for more information.
+
+Remarks
+ARP header definition.
+
typedef struct @@ -2127,7 +2152,7 @@ definitions: -
|