Add an ETHERNET layer to WinDivert.
Adds a new ETHERNET layer to WinDivert. This layer is similar to the NETWORK layers in that packets can be blocked/modified/injected. This change requires Windows 8 or newer.
This commit is contained in:
@@ -479,6 +479,7 @@ HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer, INT16 priority,
|
||||
// Parameter checking:
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
case WINDIVERT_LAYER_NETWORK_FORWARD:
|
||||
case WINDIVERT_LAYER_FLOW:
|
||||
|
||||
@@ -13,8 +13,10 @@ EXPORTS
|
||||
WinDivertHelperDecrementTTL
|
||||
WinDivertHelperHashPacket
|
||||
WinDivertHelperParsePacket
|
||||
WinDivertHelperParseMACAddress
|
||||
WinDivertHelperParseIPv4Address
|
||||
WinDivertHelperParseIPv6Address
|
||||
WinDivertHelperFormatMACAddress
|
||||
WinDivertHelperFormatIPv4Address
|
||||
WinDivertHelperFormatIPv6Address
|
||||
WinDivertHelperCompileFilter
|
||||
@@ -26,6 +28,8 @@ EXPORTS
|
||||
WinDivertHelperHtonl
|
||||
WinDivertHelperNtohll
|
||||
WinDivertHelperHtonll
|
||||
WinDivertHelperNtohMACAddress
|
||||
WinDivertHelperHtonMACAddress
|
||||
WinDivertHelperNtohIPv6Address
|
||||
WinDivertHelperHtonIPv6Address
|
||||
WinDivertHelperNtohIpv6Address
|
||||
|
||||
@@ -105,8 +105,8 @@ static UINT64 WinDivertXXH64Avalanche(UINT64 h64)
|
||||
* WinDivert packet hash function.
|
||||
*/
|
||||
static UINT64 WinDivertHashPacket(UINT64 seed,
|
||||
const WINDIVERT_IPHDR *ip_header, const WINDIVERT_IPV6HDR *ipv6_header,
|
||||
const WINDIVERT_ICMPHDR *icmp_header,
|
||||
const WINDIVERT_ETHHDR *eth_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)
|
||||
{
|
||||
|
||||
+386
-164
@@ -143,11 +143,16 @@ typedef enum
|
||||
TOKEN_PARENT_ENDPOINT_ID,
|
||||
TOKEN_LAYER,
|
||||
TOKEN_PRIORITY,
|
||||
TOKEN_FLOW,
|
||||
TOKEN_SOCKET,
|
||||
TOKEN_NETWORK,
|
||||
TOKEN_NETWORK_FORWARD,
|
||||
TOKEN_REFLECT,
|
||||
TOKEN_ETH_DST_ADDR,
|
||||
TOKEN_ETH_SRC_ADDR,
|
||||
TOKEN_ETH_TYPE,
|
||||
TOKEN_LAYER_FLOW,
|
||||
TOKEN_LAYER_SOCKET,
|
||||
TOKEN_LAYER_NETWORK,
|
||||
TOKEN_LAYER_NETWORK_FORWARD,
|
||||
TOKEN_LAYER_REFLECT,
|
||||
TOKEN_LAYER_ETHERNET,
|
||||
TOKEN_EVENT_FRAME,
|
||||
TOKEN_EVENT_PACKET,
|
||||
TOKEN_EVENT_ESTABLISHED,
|
||||
TOKEN_EVENT_DELETED,
|
||||
@@ -260,10 +265,58 @@ static BOOL WinDivertCondExecFilter(PWINDIVERT_FILTER filter, UINT length,
|
||||
static int WinDivertCompare128(BOOL neg_a, const UINT32 *a, BOOL neg_b,
|
||||
const UINT32 *b, BOOL big);
|
||||
static BOOL WinDivertDeserializeFilter(PWINDIVERT_STREAM stream,
|
||||
PWINDIVERT_FILTER filter, UINT *length);
|
||||
WINDIVERT_LAYER layer, PWINDIVERT_FILTER filter, UINT *length);
|
||||
static void WinDivertFormatExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
WINDIVERT_LAYER layer, BOOL top_level, BOOL and);
|
||||
|
||||
/*
|
||||
* Parse a MAC address.
|
||||
*/
|
||||
extern BOOL WinDivertHelperParseMACAddress(const char *str, UINT8 *addr_ptr)
|
||||
{
|
||||
UINT i, j;
|
||||
UINT8 part;
|
||||
char c;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
part = 0;
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
c = *str++;
|
||||
part <<= 4;
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
part += (UINT8)(c - '0');
|
||||
}
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
{
|
||||
part += (UINT8)(c - 'a') + 10;
|
||||
}
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
{
|
||||
part += (UINT8)(c - 'A') + 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ((i != 5? *str != ':': *str != '\0'))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
str++;
|
||||
if (addr_ptr != NULL)
|
||||
{
|
||||
addr_ptr[5-i] = part;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse an IPv4 address.
|
||||
*/
|
||||
@@ -463,14 +516,14 @@ 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,
|
||||
PVOID *ppNext, UINT *pNextLen)
|
||||
PWINDIVERT_UDPHDR *ppUDPHeader, PVOID *ppData, UINT *pDataLen)
|
||||
{
|
||||
WINDIVERT_PACKET info;
|
||||
if (!WinDivertHelperParsePacketEx(pPacket, packetLen, &info))
|
||||
if (!WinDivertHelperParsePacketEx(pPacket, packetLen, layer, &info))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -483,6 +536,10 @@ BOOL WinDivertHelperParsePacket(const VOID *pPacket, UINT packetLen,
|
||||
{
|
||||
*pProtocol = info.Protocol;
|
||||
}
|
||||
if (ppEthHeader != NULL)
|
||||
{
|
||||
*ppEthHeader = info.EthHeader;
|
||||
}
|
||||
if (ppIPHeader != NULL)
|
||||
{
|
||||
*ppIPHeader = info.IPHeader;
|
||||
@@ -515,16 +572,6 @@ BOOL WinDivertHelperParsePacket(const VOID *pPacket, UINT packetLen,
|
||||
{
|
||||
*pDataLen = info.PayloadLength;
|
||||
}
|
||||
if (ppNext != NULL)
|
||||
{
|
||||
*ppNext = (info.Extended? (PVOID)((UINT8 *)pPacket +
|
||||
(info.HeaderLength + info.PayloadLength)): NULL);
|
||||
}
|
||||
if (pNextLen != NULL)
|
||||
{
|
||||
*pNextLen = (info.Extended?
|
||||
packetLen - (info.HeaderLength + info.PayloadLength): 0);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -536,21 +583,27 @@ static BOOL WinDivertExpandMacro(KIND kind, WINDIVERT_LAYER layer, UINT32 *val)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case TOKEN_NETWORK:
|
||||
case TOKEN_LAYER_ETHERNET:
|
||||
*val = WINDIVERT_LAYER_ETHERNET;
|
||||
return TRUE;
|
||||
case TOKEN_LAYER_NETWORK:
|
||||
*val = WINDIVERT_LAYER_NETWORK;
|
||||
return TRUE;
|
||||
case TOKEN_NETWORK_FORWARD:
|
||||
case TOKEN_LAYER_NETWORK_FORWARD:
|
||||
*val = WINDIVERT_LAYER_NETWORK_FORWARD;
|
||||
return TRUE;
|
||||
case TOKEN_FLOW:
|
||||
case TOKEN_LAYER_FLOW:
|
||||
*val = WINDIVERT_LAYER_FLOW;
|
||||
return TRUE;
|
||||
case TOKEN_SOCKET:
|
||||
case TOKEN_LAYER_SOCKET:
|
||||
*val = WINDIVERT_LAYER_SOCKET;
|
||||
return TRUE;
|
||||
case TOKEN_REFLECT:
|
||||
case TOKEN_LAYER_REFLECT:
|
||||
*val = WINDIVERT_LAYER_REFLECT;
|
||||
return TRUE;
|
||||
case TOKEN_EVENT_FRAME:
|
||||
*val = WINDIVERT_EVENT_ETHERNET_FRAME;
|
||||
return (layer == WINDIVERT_LAYER_ETHERNET);
|
||||
case TOKEN_EVENT_PACKET:
|
||||
*val = WINDIVERT_EVENT_NETWORK_PACKET;
|
||||
return (layer == WINDIVERT_LAYER_NETWORK ||
|
||||
@@ -619,121 +672,128 @@ static ERROR WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer,
|
||||
{
|
||||
static const TOKEN_INFO token_info[] =
|
||||
{
|
||||
{"ACCEPT", TOKEN_EVENT_ACCEPT },
|
||||
{"BIND", TOKEN_EVENT_BIND },
|
||||
{"CLOSE", TOKEN_EVENT_CLOSE },
|
||||
{"CONNECT", TOKEN_EVENT_CONNECT },
|
||||
{"DELETED", TOKEN_EVENT_DELETED },
|
||||
{"ESTABLISHED", TOKEN_EVENT_ESTABLISHED },
|
||||
{"FALSE", TOKEN_MACRO_FALSE },
|
||||
{"FLOW", TOKEN_FLOW },
|
||||
{"ICMP", TOKEN_MACRO_ICMP },
|
||||
{"ICMPV6", TOKEN_MACRO_ICMPV6 },
|
||||
{"LISTEN", TOKEN_EVENT_LISTEN },
|
||||
{"NETWORK", TOKEN_NETWORK },
|
||||
{"NETWORK_FORWARD", TOKEN_NETWORK_FORWARD },
|
||||
{"OPEN", TOKEN_EVENT_OPEN },
|
||||
{"PACKET", TOKEN_EVENT_PACKET },
|
||||
{"REFLECT", TOKEN_REFLECT },
|
||||
{"SOCKET", TOKEN_SOCKET },
|
||||
{"TCP", TOKEN_MACRO_TCP },
|
||||
{"TRUE", TOKEN_MACRO_TRUE },
|
||||
{"UDP", TOKEN_MACRO_UDP },
|
||||
{"and", TOKEN_AND },
|
||||
{"endpointId", TOKEN_ENDPOINT_ID },
|
||||
{"event", TOKEN_EVENT },
|
||||
{"false", TOKEN_FALSE },
|
||||
{"fragment", TOKEN_FRAGMENT },
|
||||
{"icmp", TOKEN_ICMP },
|
||||
{"icmp.Body", TOKEN_ICMP_BODY },
|
||||
{"icmp.Checksum", TOKEN_ICMP_CHECKSUM },
|
||||
{"icmp.Code", TOKEN_ICMP_CODE },
|
||||
{"icmp.Type", TOKEN_ICMP_TYPE },
|
||||
{"icmpv6", TOKEN_ICMPV6 },
|
||||
{"icmpv6.Body", TOKEN_ICMPV6_BODY },
|
||||
{"icmpv6.Checksum", TOKEN_ICMPV6_CHECKSUM },
|
||||
{"icmpv6.Code", TOKEN_ICMPV6_CODE },
|
||||
{"icmpv6.Type", TOKEN_ICMPV6_TYPE },
|
||||
{"ifIdx", TOKEN_IF_IDX },
|
||||
{"impostor", TOKEN_IMPOSTOR },
|
||||
{"inbound", TOKEN_INBOUND },
|
||||
{"ip", TOKEN_IP },
|
||||
{"ip.Checksum", TOKEN_IP_CHECKSUM },
|
||||
{"ip.DF", TOKEN_IP_DF },
|
||||
{"ip.DstAddr", TOKEN_IP_DST_ADDR },
|
||||
{"ip.FragOff", TOKEN_IP_FRAG_OFF },
|
||||
{"ip.HdrLength", TOKEN_IP_HDR_LENGTH },
|
||||
{"ip.Id", TOKEN_IP_ID },
|
||||
{"ip.Length", TOKEN_IP_LENGTH },
|
||||
{"ip.MF", TOKEN_IP_MF },
|
||||
{"ip.Protocol", TOKEN_IP_PROTOCOL },
|
||||
{"ip.SrcAddr", TOKEN_IP_SRC_ADDR },
|
||||
{"ip.TOS", TOKEN_IP_TOS },
|
||||
{"ip.TTL", TOKEN_IP_TTL },
|
||||
{"ipv6", TOKEN_IPV6 },
|
||||
{"ipv6.DstAddr", TOKEN_IPV6_DST_ADDR },
|
||||
{"ipv6.FlowLabel", TOKEN_IPV6_FLOW_LABEL },
|
||||
{"ipv6.HopLimit", TOKEN_IPV6_HOP_LIMIT },
|
||||
{"ipv6.Length", TOKEN_IPV6_LENGTH },
|
||||
{"ipv6.NextHdr", TOKEN_IPV6_NEXT_HDR },
|
||||
{"ipv6.SrcAddr", TOKEN_IPV6_SRC_ADDR },
|
||||
{"ipv6.TrafficClass", TOKEN_IPV6_TRAFFIC_CLASS},
|
||||
{"layer", TOKEN_LAYER },
|
||||
{"length", TOKEN_LENGTH },
|
||||
{"localAddr", TOKEN_LOCAL_ADDR },
|
||||
{"localPort", TOKEN_LOCAL_PORT },
|
||||
{"loopback", TOKEN_LOOPBACK },
|
||||
{"not", TOKEN_NOT },
|
||||
{"or", TOKEN_OR },
|
||||
{"outbound", TOKEN_OUTBOUND },
|
||||
{"packet", TOKEN_PACKET },
|
||||
{"packet16", TOKEN_PACKET16 },
|
||||
{"packet32", TOKEN_PACKET32 },
|
||||
{"parentEndpointId", TOKEN_PARENT_ENDPOINT_ID},
|
||||
{"priority", TOKEN_PRIORITY },
|
||||
{"processId", TOKEN_PROCESS_ID },
|
||||
{"protocol", TOKEN_PROTOCOL },
|
||||
{"random16", TOKEN_RANDOM16 },
|
||||
{"random32", TOKEN_RANDOM32 },
|
||||
{"random8", TOKEN_RANDOM8 },
|
||||
{"remoteAddr", TOKEN_REMOTE_ADDR },
|
||||
{"remotePort", TOKEN_REMOTE_PORT },
|
||||
{"subIfIdx", TOKEN_SUB_IF_IDX },
|
||||
{"tcp", TOKEN_TCP },
|
||||
{"tcp.Ack", TOKEN_TCP_ACK },
|
||||
{"tcp.AckNum", TOKEN_TCP_ACK_NUM },
|
||||
{"tcp.Checksum", TOKEN_TCP_CHECKSUM },
|
||||
{"tcp.DstPort", TOKEN_TCP_DST_PORT },
|
||||
{"tcp.Fin", TOKEN_TCP_FIN },
|
||||
{"tcp.HdrLength", TOKEN_TCP_HDR_LENGTH },
|
||||
{"tcp.Payload", TOKEN_TCP_PAYLOAD },
|
||||
{"tcp.Payload16", TOKEN_TCP_PAYLOAD16 },
|
||||
{"tcp.Payload32", TOKEN_TCP_PAYLOAD32 },
|
||||
{"tcp.PayloadLength", TOKEN_TCP_PAYLOAD_LENGTH},
|
||||
{"tcp.Psh", TOKEN_TCP_PSH },
|
||||
{"tcp.Rst", TOKEN_TCP_RST },
|
||||
{"tcp.SeqNum", TOKEN_TCP_SEQ_NUM },
|
||||
{"tcp.SrcPort", TOKEN_TCP_SRC_PORT },
|
||||
{"tcp.Syn", TOKEN_TCP_SYN },
|
||||
{"tcp.Urg", TOKEN_TCP_URG },
|
||||
{"tcp.UrgPtr", TOKEN_TCP_URG_PTR },
|
||||
{"tcp.Window", TOKEN_TCP_WINDOW },
|
||||
{"timestamp", TOKEN_TIMESTAMP },
|
||||
{"true", TOKEN_TRUE },
|
||||
{"udp", TOKEN_UDP },
|
||||
{"udp.Checksum", TOKEN_UDP_CHECKSUM },
|
||||
{"udp.DstPort", TOKEN_UDP_DST_PORT },
|
||||
{"udp.Length", TOKEN_UDP_LENGTH },
|
||||
{"udp.Payload", TOKEN_UDP_PAYLOAD },
|
||||
{"udp.Payload16", TOKEN_UDP_PAYLOAD16 },
|
||||
{"udp.Payload32", TOKEN_UDP_PAYLOAD32 },
|
||||
{"udp.PayloadLength", TOKEN_UDP_PAYLOAD_LENGTH},
|
||||
{"udp.SrcPort", TOKEN_UDP_SRC_PORT },
|
||||
{"zero", TOKEN_ZERO },
|
||||
{"ACCEPT", TOKEN_EVENT_ACCEPT },
|
||||
{"BIND", TOKEN_EVENT_BIND },
|
||||
{"CLOSE", TOKEN_EVENT_CLOSE },
|
||||
{"CONNECT", TOKEN_EVENT_CONNECT },
|
||||
{"DELETED", TOKEN_EVENT_DELETED },
|
||||
{"ESTABLISHED", TOKEN_EVENT_ESTABLISHED },
|
||||
{"ETHERNET", TOKEN_LAYER_ETHERNET },
|
||||
{"FALSE", TOKEN_MACRO_FALSE },
|
||||
{"FRAME", TOKEN_EVENT_FRAME },
|
||||
{"FLOW", TOKEN_LAYER_FLOW },
|
||||
{"ICMP", TOKEN_MACRO_ICMP },
|
||||
{"ICMPV6", TOKEN_MACRO_ICMPV6 },
|
||||
{"LISTEN", TOKEN_EVENT_LISTEN },
|
||||
{"NETWORK", TOKEN_LAYER_NETWORK },
|
||||
{"NETWORK_FORWARD", TOKEN_LAYER_NETWORK_FORWARD},
|
||||
{"OPEN", TOKEN_EVENT_OPEN },
|
||||
{"PACKET", TOKEN_EVENT_PACKET },
|
||||
{"REFLECT", TOKEN_LAYER_REFLECT },
|
||||
{"SOCKET", TOKEN_LAYER_SOCKET },
|
||||
{"TCP", TOKEN_MACRO_TCP },
|
||||
{"TRUE", TOKEN_MACRO_TRUE },
|
||||
{"UDP", TOKEN_MACRO_UDP },
|
||||
{"and", TOKEN_AND },
|
||||
{"b", TOKEN_BYTES },
|
||||
{"endpointId", TOKEN_ENDPOINT_ID },
|
||||
{"eth.DstAddr", TOKEN_ETH_DST_ADDR },
|
||||
{"eth.SrcAddr", TOKEN_ETH_SRC_ADDR },
|
||||
{"eth.Type", TOKEN_ETH_TYPE },
|
||||
{"event", TOKEN_EVENT },
|
||||
{"false", TOKEN_FALSE },
|
||||
{"fragment", TOKEN_FRAGMENT },
|
||||
{"icmp", TOKEN_ICMP },
|
||||
{"icmp.Body", TOKEN_ICMP_BODY },
|
||||
{"icmp.Checksum", TOKEN_ICMP_CHECKSUM },
|
||||
{"icmp.Code", TOKEN_ICMP_CODE },
|
||||
{"icmp.Type", TOKEN_ICMP_TYPE },
|
||||
{"icmpv6", TOKEN_ICMPV6 },
|
||||
{"icmpv6.Body", TOKEN_ICMPV6_BODY },
|
||||
{"icmpv6.Checksum", TOKEN_ICMPV6_CHECKSUM },
|
||||
{"icmpv6.Code", TOKEN_ICMPV6_CODE },
|
||||
{"icmpv6.Type", TOKEN_ICMPV6_TYPE },
|
||||
{"ifIdx", TOKEN_IF_IDX },
|
||||
{"impostor", TOKEN_IMPOSTOR },
|
||||
{"inbound", TOKEN_INBOUND },
|
||||
{"ip", TOKEN_IP },
|
||||
{"ip.Checksum", TOKEN_IP_CHECKSUM },
|
||||
{"ip.DF", TOKEN_IP_DF },
|
||||
{"ip.DstAddr", TOKEN_IP_DST_ADDR },
|
||||
{"ip.FragOff", TOKEN_IP_FRAG_OFF },
|
||||
{"ip.HdrLength", TOKEN_IP_HDR_LENGTH },
|
||||
{"ip.Id", TOKEN_IP_ID },
|
||||
{"ip.Length", TOKEN_IP_LENGTH },
|
||||
{"ip.MF", TOKEN_IP_MF },
|
||||
{"ip.Protocol", TOKEN_IP_PROTOCOL },
|
||||
{"ip.SrcAddr", TOKEN_IP_SRC_ADDR },
|
||||
{"ip.TOS", TOKEN_IP_TOS },
|
||||
{"ip.TTL", TOKEN_IP_TTL },
|
||||
{"ipv6", TOKEN_IPV6 },
|
||||
{"ipv6.DstAddr", TOKEN_IPV6_DST_ADDR },
|
||||
{"ipv6.FlowLabel", TOKEN_IPV6_FLOW_LABEL },
|
||||
{"ipv6.HopLimit", TOKEN_IPV6_HOP_LIMIT },
|
||||
{"ipv6.Length", TOKEN_IPV6_LENGTH },
|
||||
{"ipv6.NextHdr", TOKEN_IPV6_NEXT_HDR },
|
||||
{"ipv6.SrcAddr", TOKEN_IPV6_SRC_ADDR },
|
||||
{"ipv6.TrafficClass", TOKEN_IPV6_TRAFFIC_CLASS },
|
||||
{"layer", TOKEN_LAYER },
|
||||
{"length", TOKEN_LENGTH },
|
||||
{"localAddr", TOKEN_LOCAL_ADDR },
|
||||
{"localPort", TOKEN_LOCAL_PORT },
|
||||
{"loopback", TOKEN_LOOPBACK },
|
||||
{"not", TOKEN_NOT },
|
||||
{"or", TOKEN_OR },
|
||||
{"outbound", TOKEN_OUTBOUND },
|
||||
{"packet", TOKEN_PACKET },
|
||||
{"packet16", TOKEN_PACKET16 },
|
||||
{"packet32", TOKEN_PACKET32 },
|
||||
{"parentEndpointId", TOKEN_PARENT_ENDPOINT_ID },
|
||||
{"priority", TOKEN_PRIORITY },
|
||||
{"processId", TOKEN_PROCESS_ID },
|
||||
{"protocol", TOKEN_PROTOCOL },
|
||||
{"random16", TOKEN_RANDOM16 },
|
||||
{"random32", TOKEN_RANDOM32 },
|
||||
{"random8", TOKEN_RANDOM8 },
|
||||
{"remoteAddr", TOKEN_REMOTE_ADDR },
|
||||
{"remotePort", TOKEN_REMOTE_PORT },
|
||||
{"subIfIdx", TOKEN_SUB_IF_IDX },
|
||||
{"tcp", TOKEN_TCP },
|
||||
{"tcp.Ack", TOKEN_TCP_ACK },
|
||||
{"tcp.AckNum", TOKEN_TCP_ACK_NUM },
|
||||
{"tcp.Checksum", TOKEN_TCP_CHECKSUM },
|
||||
{"tcp.DstPort", TOKEN_TCP_DST_PORT },
|
||||
{"tcp.Fin", TOKEN_TCP_FIN },
|
||||
{"tcp.HdrLength", TOKEN_TCP_HDR_LENGTH },
|
||||
{"tcp.Payload", TOKEN_TCP_PAYLOAD },
|
||||
{"tcp.Payload16", TOKEN_TCP_PAYLOAD16 },
|
||||
{"tcp.Payload32", TOKEN_TCP_PAYLOAD32 },
|
||||
{"tcp.PayloadLength", TOKEN_TCP_PAYLOAD_LENGTH },
|
||||
{"tcp.Psh", TOKEN_TCP_PSH },
|
||||
{"tcp.Rst", TOKEN_TCP_RST },
|
||||
{"tcp.SeqNum", TOKEN_TCP_SEQ_NUM },
|
||||
{"tcp.SrcPort", TOKEN_TCP_SRC_PORT },
|
||||
{"tcp.Syn", TOKEN_TCP_SYN },
|
||||
{"tcp.Urg", TOKEN_TCP_URG },
|
||||
{"tcp.UrgPtr", TOKEN_TCP_URG_PTR },
|
||||
{"tcp.Window", TOKEN_TCP_WINDOW },
|
||||
{"timestamp", TOKEN_TIMESTAMP },
|
||||
{"true", TOKEN_TRUE },
|
||||
{"udp", TOKEN_UDP },
|
||||
{"udp.Checksum", TOKEN_UDP_CHECKSUM },
|
||||
{"udp.DstPort", TOKEN_UDP_DST_PORT },
|
||||
{"udp.Length", TOKEN_UDP_LENGTH },
|
||||
{"udp.Payload", TOKEN_UDP_PAYLOAD },
|
||||
{"udp.Payload16", TOKEN_UDP_PAYLOAD16 },
|
||||
{"udp.Payload32", TOKEN_UDP_PAYLOAD32 },
|
||||
{"udp.PayloadLength", TOKEN_UDP_PAYLOAD_LENGTH },
|
||||
{"udp.SrcPort", TOKEN_UDP_SRC_PORT },
|
||||
{"zero", TOKEN_ZERO },
|
||||
};
|
||||
TOKEN_INFO *result;
|
||||
char c;
|
||||
char token[TOKEN_MAXLEN];
|
||||
UINT8 eth_addr[6];
|
||||
UINT32 field;
|
||||
UINT i = 0, j;
|
||||
UINT tp = 0;
|
||||
@@ -890,13 +950,6 @@ static ERROR WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer,
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for 'b':
|
||||
if (token[0] == 'b' && token[1] == '\0')
|
||||
{
|
||||
tokens[tp].kind = TOKEN_BYTES;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for base 10 number:
|
||||
if (WinDivertAToI(token, &end, num, sizeof(num)/sizeof(num[0])))
|
||||
{
|
||||
@@ -928,6 +981,22 @@ static ERROR WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer,
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for MAC address:
|
||||
if (WinDivertHelperParseMACAddress(token, eth_addr))
|
||||
{
|
||||
tokens[tp].val[0] =
|
||||
(UINT32)eth_addr[0] |
|
||||
((UINT32)eth_addr[1] << 8) |
|
||||
((UINT32)eth_addr[2] << 16) |
|
||||
((UINT32)eth_addr[3] << 24);
|
||||
tokens[tp].val[1] =
|
||||
(UINT32)eth_addr[4] |
|
||||
((UINT32)eth_addr[5] << 8);
|
||||
tokens[tp].kind = TOKEN_NUMBER;
|
||||
tp++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for IPv4 address:
|
||||
if (WinDivertHelperParseIPv4Address(token, tokens[tp].val))
|
||||
{
|
||||
@@ -1042,6 +1111,9 @@ static PEXPR WinDivertMakeVar(KIND kind, PERROR error)
|
||||
{{{0}}, TOKEN_PARENT_ENDPOINT_ID},
|
||||
{{{0}}, TOKEN_LAYER},
|
||||
{{{0}}, TOKEN_PRIORITY},
|
||||
{{{0}}, TOKEN_ETH_DST_ADDR},
|
||||
{{{0}}, TOKEN_ETH_SRC_ADDR},
|
||||
{{{0}}, TOKEN_ETH_TYPE},
|
||||
};
|
||||
|
||||
// Binary search:
|
||||
@@ -1200,6 +1272,9 @@ static PEXPR WinDivertParseTest(HANDLE pool, TOKEN *toks, UINT *i, PERROR error)
|
||||
case TOKEN_PARENT_ENDPOINT_ID:
|
||||
case TOKEN_LENGTH:
|
||||
case TOKEN_LAYER:
|
||||
case TOKEN_ETH_DST_ADDR:
|
||||
case TOKEN_ETH_SRC_ADDR:
|
||||
case TOKEN_ETH_TYPE:
|
||||
case TOKEN_IP_HDR_LENGTH:
|
||||
case TOKEN_IP_TOS:
|
||||
case TOKEN_IP_LENGTH:
|
||||
@@ -1554,6 +1629,7 @@ static BOOL WinDivertEvalTest(PEXPR test, BOOL *res)
|
||||
case TOKEN_IP_FRAG_OFF:
|
||||
lb[0] = 0; ub[0] = 0x1FFF;
|
||||
break;
|
||||
case TOKEN_ETH_TYPE:
|
||||
case TOKEN_IP_TOS:
|
||||
case TOKEN_IP_LENGTH:
|
||||
case TOKEN_IP_ID:
|
||||
@@ -1607,6 +1683,12 @@ static BOOL WinDivertEvalTest(PEXPR test, BOOL *res)
|
||||
ub[1] = 0x7FFFFFFF;
|
||||
neg_lb = TRUE;
|
||||
break;
|
||||
case TOKEN_ETH_DST_ADDR:
|
||||
case TOKEN_ETH_SRC_ADDR:
|
||||
lb[0] = lb[1] = 0;
|
||||
ub[0] = 0xFFFFFFFF;
|
||||
ub[1] = 0xFFFF;
|
||||
break;
|
||||
case TOKEN_ENDPOINT_ID:
|
||||
case TOKEN_PARENT_ENDPOINT_ID:
|
||||
lb[0] = lb[1] = 0;
|
||||
@@ -1831,6 +1913,12 @@ static UINT32 WinDivertKindToField(KIND kind)
|
||||
return WINDIVERT_FILTER_FIELD_TCP;
|
||||
case TOKEN_UDP:
|
||||
return WINDIVERT_FILTER_FIELD_UDP;
|
||||
case TOKEN_ETH_DST_ADDR:
|
||||
return WINDIVERT_FILTER_FIELD_ETH_DST_ADDR;
|
||||
case TOKEN_ETH_SRC_ADDR:
|
||||
return WINDIVERT_FILTER_FIELD_ETH_SRC_ADDR;
|
||||
case TOKEN_ETH_TYPE:
|
||||
return WINDIVERT_FILTER_FIELD_ETH_TYPE;
|
||||
case TOKEN_IP_HDR_LENGTH:
|
||||
return WINDIVERT_FILTER_FIELD_IP_HDRLENGTH;
|
||||
case TOKEN_IP_TOS:
|
||||
@@ -2054,7 +2142,8 @@ static UINT64 WinDivertAnalyzeFilter(WINDIVERT_LAYER layer,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (layer == WINDIVERT_LAYER_NETWORK ||
|
||||
if (layer == WINDIVERT_LAYER_ETHERNET ||
|
||||
layer == WINDIVERT_LAYER_NETWORK ||
|
||||
layer == WINDIVERT_LAYER_NETWORK_FORWARD)
|
||||
{
|
||||
// Inbound?
|
||||
@@ -2078,7 +2167,8 @@ static UINT64 WinDivertAnalyzeFilter(WINDIVERT_LAYER layer,
|
||||
flags |= (result? WINDIVERT_FILTER_FLAG_OUTBOUND: 0);
|
||||
}
|
||||
|
||||
if (layer != WINDIVERT_LAYER_REFLECT)
|
||||
if (layer != WINDIVERT_LAYER_ETHERNET &&
|
||||
layer != WINDIVERT_LAYER_REFLECT)
|
||||
{
|
||||
// IPv4?
|
||||
result = WinDivertCondExecFilter(filter, length,
|
||||
@@ -2258,7 +2348,7 @@ static ERROR WinDivertCompileFilter(const char *filter, HANDLE pool,
|
||||
stream.max = UINT_MAX;
|
||||
stream.overflow = FALSE;
|
||||
|
||||
if (!WinDivertDeserializeFilter(&stream, object, obj_len))
|
||||
if (!WinDivertDeserializeFilter(&stream, layer, object, obj_len))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return MAKE_ERROR(WINDIVERT_ERROR_BAD_OBJECT, 0);
|
||||
@@ -2434,17 +2524,19 @@ static BOOL WinDivertGetData(const VOID *packet, UINT packet_len, INT min,
|
||||
* Evaluate the given filter with the given packet as input.
|
||||
*/
|
||||
BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
|
||||
UINT packet_len, const WINDIVERT_ADDRESS *addr)
|
||||
UINT packet_len, WINDIVERT_LAYER layer, const WINDIVERT_ADDRESS *addr)
|
||||
{
|
||||
ERROR err;
|
||||
DWORD error;
|
||||
WINDIVERT_PACKET info;
|
||||
PWINDIVERT_ETHHDR eth_header = NULL;
|
||||
PWINDIVERT_IPHDR ip_header = NULL;
|
||||
PWINDIVERT_IPV6HDR ipv6_header = NULL;
|
||||
PWINDIVERT_ICMPHDR icmp_header = NULL;
|
||||
PWINDIVERT_ICMPV6HDR icmpv6_header = NULL;
|
||||
PWINDIVERT_TCPHDR tcp_header = NULL;
|
||||
PWINDIVERT_UDPHDR udp_header = NULL;
|
||||
const WINDIVERT_DATA_ETHERNET *ethernet_data = NULL;
|
||||
const WINDIVERT_DATA_NETWORK *network_data = NULL;
|
||||
const WINDIVERT_DATA_FLOW *flow_data = NULL;
|
||||
const WINDIVERT_DATA_SOCKET *socket_data = NULL;
|
||||
@@ -2462,8 +2554,9 @@ BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
switch (addr->Layer)
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
case WINDIVERT_LAYER_NETWORK_FORWARD:
|
||||
if (packet == NULL)
|
||||
@@ -2471,12 +2564,14 @@ BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
if (!WinDivertHelperParsePacketEx((PVOID)packet, packet_len, &info))
|
||||
if (!WinDivertHelperParsePacketEx((PVOID)packet, packet_len,
|
||||
layer, &info))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
protocol = info.Protocol;
|
||||
eth_header = info.EthHeader;
|
||||
ip_header = info.IPHeader;
|
||||
ipv6_header = info.IPv6Header;
|
||||
icmp_header = info.ICMPHeader;
|
||||
@@ -2507,8 +2602,11 @@ BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
switch (addr->Layer)
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
ethernet_data = &addr->Ethernet;
|
||||
break;
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
case WINDIVERT_LAYER_NETWORK_FORWARD:
|
||||
network_data = &addr->Network;
|
||||
@@ -2539,7 +2637,7 @@ BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
|
||||
{
|
||||
goto WinDivertHelperEvalFilterError;
|
||||
}
|
||||
err = WinDivertCompileFilter(filter, pool, addr->Layer, object, &obj_len);
|
||||
err = WinDivertCompileFilter(filter, pool, layer, object, &obj_len);
|
||||
if (IS_ERROR(err))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
@@ -2548,7 +2646,7 @@ BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
|
||||
|
||||
result = WinDivertExecuteFilter(
|
||||
object,
|
||||
addr->Layer,
|
||||
layer,
|
||||
addr->Timestamp,
|
||||
addr->Event,
|
||||
(addr->IPv6 != 0? FALSE: TRUE),
|
||||
@@ -2556,10 +2654,12 @@ BOOL WinDivertHelperEvalFilter(const char *filter, const VOID *packet,
|
||||
(addr->Loopback != 0? TRUE: FALSE),
|
||||
(addr->Impostor != 0? TRUE: FALSE),
|
||||
fragment,
|
||||
ethernet_data,
|
||||
network_data,
|
||||
flow_data,
|
||||
socket_data,
|
||||
reflect_data,
|
||||
eth_header,
|
||||
ip_header,
|
||||
ipv6_header,
|
||||
icmp_header,
|
||||
@@ -2720,7 +2820,7 @@ static BOOL WinDivertDeserializeLabel(PWINDIVERT_STREAM stream, UINT16 *label)
|
||||
* Deserialize a test.
|
||||
*/
|
||||
static BOOL WinDivertDeserializeTest(PWINDIVERT_STREAM stream,
|
||||
PWINDIVERT_FILTER filter)
|
||||
WINDIVERT_LAYER layer, PWINDIVERT_FILTER filter)
|
||||
{
|
||||
UINT32 val;
|
||||
UINT16 success, failure;
|
||||
@@ -2732,7 +2832,7 @@ static BOOL WinDivertDeserializeTest(PWINDIVERT_STREAM stream,
|
||||
}
|
||||
|
||||
if (!WinDivertDeserializeNumber(stream, 2, &val) ||
|
||||
val > WINDIVERT_FILTER_FIELD_MAX)
|
||||
!WinDivertValidateField(layer, val))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2773,6 +2873,8 @@ static BOOL WinDivertDeserializeTest(PWINDIVERT_STREAM stream,
|
||||
case WINDIVERT_FILTER_FIELD_ENDPOINTID:
|
||||
case WINDIVERT_FILTER_FIELD_PARENTENDPOINTID:
|
||||
case WINDIVERT_FILTER_FIELD_TIMESTAMP:
|
||||
case WINDIVERT_FILTER_FIELD_ETH_DST_ADDR:
|
||||
case WINDIVERT_FILTER_FIELD_ETH_SRC_ADDR:
|
||||
if (!WinDivertDeserializeNumber(stream, 7, &filter->arg[1]))
|
||||
{
|
||||
return FALSE;
|
||||
@@ -2854,7 +2956,7 @@ static BOOL WinDivertDeserializeFilterHeader(PWINDIVERT_STREAM stream,
|
||||
* Deserialize a filter.
|
||||
*/
|
||||
static BOOL WinDivertDeserializeFilter(PWINDIVERT_STREAM stream,
|
||||
PWINDIVERT_FILTER filter, UINT *length)
|
||||
WINDIVERT_LAYER layer, PWINDIVERT_FILTER filter, UINT *length)
|
||||
{
|
||||
UINT i;
|
||||
|
||||
@@ -2865,7 +2967,7 @@ static BOOL WinDivertDeserializeFilter(PWINDIVERT_STREAM stream,
|
||||
|
||||
for (i = 0; i < *length; i++)
|
||||
{
|
||||
if (!WinDivertDeserializeTest(stream, filter + i))
|
||||
if (!WinDivertDeserializeTest(stream, layer, filter + i))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2967,6 +3069,12 @@ static PEXPR WinDivertDecompileTest(HANDLE pool, PWINDIVERT_FILTER test)
|
||||
kind = TOKEN_UDP; break;
|
||||
case WINDIVERT_FILTER_FIELD_ICMPV6:
|
||||
kind = TOKEN_ICMPV6; break;
|
||||
case WINDIVERT_FILTER_FIELD_ETH_DST_ADDR:
|
||||
kind = TOKEN_ETH_DST_ADDR; break;
|
||||
case WINDIVERT_FILTER_FIELD_ETH_SRC_ADDR:
|
||||
kind = TOKEN_ETH_SRC_ADDR; break;
|
||||
case WINDIVERT_FILTER_FIELD_ETH_TYPE:
|
||||
kind = TOKEN_ETH_TYPE; break;
|
||||
case WINDIVERT_FILTER_FIELD_IP_HDRLENGTH:
|
||||
kind = TOKEN_IP_HDR_LENGTH; break;
|
||||
case WINDIVERT_FILTER_FIELD_IP_TOS:
|
||||
@@ -3482,6 +3590,36 @@ static void WinDivertFormatHexNumber(PWINDIVERT_STREAM stream,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Format a MAC address.
|
||||
*/
|
||||
static void WinDivertFormatMacAddr(PWINDIVERT_STREAM stream, const UINT8 *addr)
|
||||
{
|
||||
UINT8 part, dig;
|
||||
INT i, j;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
part = addr[5-i];
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
dig = (j == 0? part >> 4: part & 0xF);
|
||||
if (dig <= 9)
|
||||
{
|
||||
WinDivertPutChar(stream, '0' + dig);
|
||||
}
|
||||
else
|
||||
{
|
||||
WinDivertPutChar(stream, 'a' + (dig - 10));
|
||||
}
|
||||
}
|
||||
if (i != 5)
|
||||
{
|
||||
WinDivertPutChar(stream, ':');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Format an IPv4 address.
|
||||
*/
|
||||
@@ -3548,6 +3686,27 @@ static void WinDivertFormatIPv6Addr(PWINDIVERT_STREAM stream,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Format a MAC address.
|
||||
*/
|
||||
extern BOOL WinDivertHelperFormatMACAddress(const UINT8 *addr, char *buffer,
|
||||
UINT bufLen)
|
||||
{
|
||||
WINDIVERT_STREAM stream;
|
||||
stream.data = buffer;
|
||||
stream.pos = 0;
|
||||
stream.max = bufLen;
|
||||
stream.overflow = FALSE;
|
||||
WinDivertFormatMacAddr(&stream, addr);
|
||||
WinDivertPutNul(&stream);
|
||||
if (stream.overflow)
|
||||
{
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Format an IPv4 address.
|
||||
*/
|
||||
@@ -3596,8 +3755,8 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
WINDIVERT_LAYER layer)
|
||||
{
|
||||
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;
|
||||
BOOL is_eth_addr = FALSE, is_ipv4_addr = FALSE, is_ipv6_addr = FALSE,
|
||||
is_layer = FALSE, is_event = FALSE, is_hex = FALSE;
|
||||
|
||||
switch (field->kind)
|
||||
{
|
||||
@@ -3642,8 +3801,20 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TOKEN_ETH_SRC_ADDR:
|
||||
case TOKEN_ETH_DST_ADDR:
|
||||
if (val->val[2] != 0 || val->val[3] != 0 || val->val[1] > 0xFFFF)
|
||||
{
|
||||
break;
|
||||
}
|
||||
is_eth_addr = TRUE;
|
||||
break;
|
||||
case TOKEN_IP_SRC_ADDR:
|
||||
case TOKEN_IP_DST_ADDR:
|
||||
if (val->val[2] != 0 || val->val[3] != 0 || val->val[1] != 0xFFFF)
|
||||
{
|
||||
break;
|
||||
}
|
||||
is_ipv4_addr = TRUE;
|
||||
break;
|
||||
case TOKEN_IPV6_SRC_ADDR:
|
||||
@@ -3673,6 +3844,7 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
case TOKEN_UDP_PAYLOAD32:
|
||||
case TOKEN_ICMP_CHECKSUM:
|
||||
case TOKEN_ICMPV6_CHECKSUM:
|
||||
case TOKEN_ETH_TYPE:
|
||||
is_hex = TRUE;
|
||||
break;
|
||||
default:
|
||||
@@ -3700,7 +3872,18 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
{
|
||||
WinDivertPutChar(stream, '-');
|
||||
}
|
||||
if (is_ipv4_addr)
|
||||
if (is_eth_addr)
|
||||
{
|
||||
UINT8 eth_addr[6];
|
||||
eth_addr[0] = (UINT8)val->val[0];
|
||||
eth_addr[1] = (UINT8)(val->val[0] >> 8);
|
||||
eth_addr[2] = (UINT8)(val->val[0] >> 16);
|
||||
eth_addr[3] = (UINT8)(val->val[0] >> 24);
|
||||
eth_addr[4] = (UINT8)val->val[1];
|
||||
eth_addr[5] = (UINT8)(val->val[1] >> 8);
|
||||
WinDivertFormatMacAddr(stream, eth_addr);
|
||||
}
|
||||
else if (is_ipv4_addr)
|
||||
{
|
||||
WinDivertFormatIPv4Addr(stream, val->val[0]);
|
||||
}
|
||||
@@ -3712,6 +3895,8 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
{
|
||||
switch (val->val[0])
|
||||
{
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
WinDivertPutString(stream, "ETHERNET"); break;
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
WinDivertPutString(stream, "NETWORK"); break;
|
||||
case WINDIVERT_LAYER_NETWORK_FORWARD:
|
||||
@@ -3730,6 +3915,16 @@ static void WinDivertFormatTestExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
{
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
if (val->val[0] == WINDIVERT_EVENT_ETHERNET_FRAME)
|
||||
{
|
||||
WinDivertPutString(stream, "FRAME");
|
||||
}
|
||||
else
|
||||
{
|
||||
WinDivertFormatDecNumber32(stream, val->val[0]);
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
case WINDIVERT_LAYER_NETWORK_FORWARD:
|
||||
if (val->val[0] == WINDIVERT_EVENT_NETWORK_PACKET)
|
||||
@@ -3920,6 +4115,12 @@ static void WinDivertFormatExpr(PWINDIVERT_STREAM stream, PEXPR expr,
|
||||
WinDivertPutString(stream, "udp"); return;
|
||||
case TOKEN_ICMPV6:
|
||||
WinDivertPutString(stream, "icmpv6"); return;
|
||||
case TOKEN_ETH_DST_ADDR:
|
||||
WinDivertPutString(stream, "eth.DstAddr"); return;
|
||||
case TOKEN_ETH_SRC_ADDR:
|
||||
WinDivertPutString(stream, "eth.SrcAddr"); return;
|
||||
case TOKEN_ETH_TYPE:
|
||||
WinDivertPutString(stream, "eth.Type"); return;
|
||||
case TOKEN_IP_HDR_LENGTH:
|
||||
WinDivertPutString(stream, "ip.HdrLength"); return;
|
||||
case TOKEN_IP_TOS:
|
||||
@@ -4171,8 +4372,9 @@ WinDivertHelperFormatFilterError:
|
||||
* WinDivert packet hash function.
|
||||
*/
|
||||
UINT64 WinDivertHelperHashPacket(const VOID *pPacket, UINT packetLen,
|
||||
UINT64 seed)
|
||||
WINDIVERT_LAYER layer, UINT64 seed)
|
||||
{
|
||||
PWINDIVERT_ETHHDR eth_header = NULL;
|
||||
PWINDIVERT_IPHDR ip_header = NULL;
|
||||
PWINDIVERT_IPV6HDR ipv6_header = NULL;
|
||||
PWINDIVERT_ICMPHDR icmp_header = NULL;
|
||||
@@ -4180,14 +4382,14 @@ UINT64 WinDivertHelperHashPacket(const VOID *pPacket, UINT packetLen,
|
||||
PWINDIVERT_TCPHDR tcp_header = NULL;
|
||||
PWINDIVERT_UDPHDR udp_header = NULL;
|
||||
|
||||
if (!WinDivertHelperParsePacket((PVOID)pPacket, packetLen, &ip_header,
|
||||
&ipv6_header, NULL, &icmp_header, &icmpv6_header, &tcp_header,
|
||||
&udp_header, NULL, NULL, NULL, NULL))
|
||||
if (!WinDivertHelperParsePacket((PVOID)pPacket, packetLen, layer,
|
||||
ð_header, &ip_header, &ipv6_header, NULL, &icmp_header,
|
||||
&icmpv6_header, &tcp_header, &udp_header, NULL, NULL))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return WinDivertHashPacket(seed, ip_header, ipv6_header, icmp_header,
|
||||
icmpv6_header, tcp_header, udp_header);
|
||||
return WinDivertHashPacket(seed, eth_header, ip_header, ipv6_header,
|
||||
icmp_header, icmpv6_header, tcp_header, udp_header);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4217,6 +4419,26 @@ UINT64 WinDivertHelperHtonll(UINT64 x)
|
||||
{
|
||||
return BYTESWAP64(x);
|
||||
}
|
||||
static void WinDivertByteSwap48(const UINT8 *inAddr, UINT8 *outAddr)
|
||||
{
|
||||
UINT8 tmp[6], i; // tmp[] allows overlapping inAddr/outAddr
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
tmp[5-i] = inAddr[i];
|
||||
}
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
outAddr[i] = tmp[i];
|
||||
}
|
||||
}
|
||||
extern void WinDivertHelperNtohMACAddress(const UINT8 *inAddr, UINT8 *outAddr)
|
||||
{
|
||||
WinDivertByteSwap48(inAddr, outAddr);
|
||||
}
|
||||
extern void WinDivertHelperHtonMACAddress(const UINT8 *inAddr, UINT8 *outAddr)
|
||||
{
|
||||
WinDivertByteSwap48(inAddr, outAddr);
|
||||
}
|
||||
static void WinDivertByteSwap128(const UINT *inAddr, UINT *outAddr)
|
||||
{
|
||||
UINT32 tmp[4], i; // tmp[] allows overlapping inAddr/outAddr
|
||||
|
||||
+407
-216
@@ -45,6 +45,13 @@
|
||||
#define BYTESWAP32(x) \
|
||||
((((x) >> 24) & 0x000000FFu) | (((x) >> 8) & 0x0000FF00u) | \
|
||||
(((x) << 8) & 0x00FF0000u) | (((x) << 24) & 0xFF000000u))
|
||||
#define BYTESWAP48(x) \
|
||||
((((x) >> 40) & 0x0000000000FF0000ull) | \
|
||||
(((x) >> 24) & 0x00000000FF000000ull) | \
|
||||
(((x) >> 8) & 0x000000FF00000000ull) | \
|
||||
(((x) << 8) & 0x0000FF0000000000ull) | \
|
||||
(((x) << 24) & 0x00FF000000000000ull) | \
|
||||
(((x) << 40) & 0xFF00000000000000ull))
|
||||
#define BYTESWAP64(x) \
|
||||
((((x) >> 56) & 0x00000000000000FFull) | \
|
||||
(((x) >> 40) & 0x000000000000FF00ull) | \
|
||||
@@ -58,6 +65,11 @@
|
||||
#define htons(x) BYTESWAP16(x)
|
||||
#define ntohl(x) BYTESWAP32(x)
|
||||
#define htonl(x) BYTESWAP32(x)
|
||||
#define ntohl48(x) BYTESWAP48(x)
|
||||
#define htonl48(x) BYTESWAP48(x)
|
||||
|
||||
#define ETHERTYPE_IP 0x0800
|
||||
#define ETHERTYPE_IPV6 0x86DD
|
||||
|
||||
/*
|
||||
* Layer flags shorthand.
|
||||
@@ -68,32 +80,46 @@
|
||||
#define WINDIVERT_LAYER_FLAG_FLOW (1 << WINDIVERT_LAYER_FLOW)
|
||||
#define WINDIVERT_LAYER_FLAG_SOCKET (1 << WINDIVERT_LAYER_SOCKET)
|
||||
#define WINDIVERT_LAYER_FLAG_REFLECT (1 << WINDIVERT_LAYER_REFLECT)
|
||||
#define LNMFSR (WINDIVERT_LAYER_FLAG_NETWORK | \
|
||||
#define WINDIVERT_LAYER_FLAG_ETHERNET (1 << WINDIVERT_LAYER_ETHERNET)
|
||||
#define LENMFSR (WINDIVERT_LAYER_FLAG_ETHERNET | \
|
||||
WINDIVERT_LAYER_FLAG_NETWORK | \
|
||||
WINDIVERT_LAYER_FLAG_NETWORK_FORWARD | \
|
||||
WINDIVERT_LAYER_FLAG_FLOW | \
|
||||
WINDIVERT_LAYER_FLAG_SOCKET | \
|
||||
WINDIVERT_LAYER_FLAG_REFLECT)
|
||||
#define LNMFS_ (WINDIVERT_LAYER_FLAG_NETWORK | \
|
||||
#define LENMFS_ (WINDIVERT_LAYER_FLAG_ETHERNET | \
|
||||
WINDIVERT_LAYER_FLAG_NETWORK | \
|
||||
WINDIVERT_LAYER_FLAG_NETWORK_FORWARD | \
|
||||
WINDIVERT_LAYER_FLAG_FLOW | \
|
||||
WINDIVERT_LAYER_FLAG_SOCKET)
|
||||
#define L__F_R (WINDIVERT_LAYER_FLAG_FLOW | \
|
||||
#define LEN_F__ (WINDIVERT_LAYER_FLAG_ETHERNET | \
|
||||
WINDIVERT_LAYER_FLAG_NETWORK | \
|
||||
WINDIVERT_LAYER_FLAG_FLOW)
|
||||
#define L___F_R (WINDIVERT_LAYER_FLAG_FLOW | \
|
||||
WINDIVERT_LAYER_FLAG_REFLECT)
|
||||
#define LN_FS_ (WINDIVERT_LAYER_FLAG_NETWORK | \
|
||||
#define LEN_FS_ (WINDIVERT_LAYER_FLAG_ETHERNET | \
|
||||
WINDIVERT_LAYER_FLAG_NETWORK | \
|
||||
WINDIVERT_LAYER_FLAG_FLOW | \
|
||||
WINDIVERT_LAYER_FLAG_SOCKET)
|
||||
#define L__FS_ (WINDIVERT_LAYER_FLAG_FLOW | \
|
||||
#define L_N_FS_ (WINDIVERT_LAYER_FLAG_NETWORK | \
|
||||
WINDIVERT_LAYER_FLAG_FLOW | \
|
||||
WINDIVERT_LAYER_FLAG_SOCKET)
|
||||
#define L___SR (WINDIVERT_LAYER_FLAG_SOCKET | \
|
||||
#define L___FS_ (WINDIVERT_LAYER_FLAG_FLOW | \
|
||||
WINDIVERT_LAYER_FLAG_SOCKET)
|
||||
#define L____SR (WINDIVERT_LAYER_FLAG_SOCKET | \
|
||||
WINDIVERT_LAYER_FLAG_REFLECT)
|
||||
#define L__FSR (WINDIVERT_LAYER_FLAG_FLOW | \
|
||||
#define L___FSR (WINDIVERT_LAYER_FLAG_FLOW | \
|
||||
WINDIVERT_LAYER_FLAG_SOCKET | \
|
||||
WINDIVERT_LAYER_FLAG_REFLECT)
|
||||
#define LNM___ (WINDIVERT_LAYER_FLAG_NETWORK | \
|
||||
#define LENM___ (WINDIVERT_LAYER_FLAG_ETHERNET | \
|
||||
WINDIVERT_LAYER_FLAG_NETWORK | \
|
||||
WINDIVERT_LAYER_FLAG_NETWORK_FORWARD)
|
||||
#define L__F__ WINDIVERT_LAYER_FLAG_FLOW
|
||||
#define L___S_ WINDIVERT_LAYER_FLAG_SOCKET
|
||||
#define L____R WINDIVERT_LAYER_FLAG_REFLECT
|
||||
#define L_NM___ (WINDIVERT_LAYER_FLAG_NETWORK | \
|
||||
WINDIVERT_LAYER_FLAG_NETWORK_FORWARD)
|
||||
#define LE_____ WINDIVERT_LAYER_FLAG_ETHERNET
|
||||
#define L___F__ WINDIVERT_LAYER_FLAG_FLOW
|
||||
#define L____S_ WINDIVERT_LAYER_FLAG_SOCKET
|
||||
#define L_____R WINDIVERT_LAYER_FLAG_REFLECT
|
||||
|
||||
#if defined(WIN32) && defined(_MSC_VER)
|
||||
#pragma intrinsic(__emulu)
|
||||
@@ -161,6 +187,7 @@ typedef struct
|
||||
UINT32 Truncated:1;
|
||||
UINT32 Extended:1;
|
||||
UINT32 Reserved1:6;
|
||||
PWINDIVERT_ETHHDR EthHeader;
|
||||
PWINDIVERT_IPHDR IPHeader;
|
||||
PWINDIVERT_IPV6HDR IPv6Header;
|
||||
PWINDIVERT_ICMPHDR ICMPHeader;
|
||||
@@ -360,9 +387,10 @@ static void WinDivertSerializeFilter(PWINDIVERT_STREAM stream,
|
||||
/*
|
||||
* Parse IPv4/IPv6/ICMP/ICMPv6/TCP/UDP headers from a raw packet.
|
||||
*/
|
||||
static BOOL WinDivertHelperParsePacketEx(const VOID *pPacket, UINT packetLen,
|
||||
PWINDIVERT_PACKET pInfo)
|
||||
static BOOL WinDivertHelperParsePacketEx(const VOID *pPacket,
|
||||
UINT packetLen, WINDIVERT_LAYER layer, PWINDIVERT_PACKET pInfo)
|
||||
{
|
||||
PWINDIVERT_ETHHDR eth_header = NULL;
|
||||
PWINDIVERT_IPHDR ip_header = NULL;
|
||||
PWINDIVERT_IPV6HDR ipv6_header = NULL;
|
||||
PWINDIVERT_ICMPHDR icmp_header = NULL;
|
||||
@@ -370,109 +398,168 @@ static BOOL WinDivertHelperParsePacketEx(const VOID *pPacket, UINT packetLen,
|
||||
PWINDIVERT_TCPHDR tcp_header = NULL;
|
||||
PWINDIVERT_UDPHDR udp_header = NULL;
|
||||
PWINDIVERT_IPV6FRAGHDR frag_header;
|
||||
UINT8 protocol = 0;
|
||||
UINT8 ip_protocol = 0;
|
||||
UINT8 *data = NULL;
|
||||
UINT packet_len, total_len, header_len, data_len = 0, frag_off = 0;
|
||||
BOOL MF = FALSE, fragment = FALSE, is_ext_header;
|
||||
UINT ip_packet_len = 0, ip_total_len = 0, ip_header_len = 0,
|
||||
trans_header_len, header_len = 0, data_len, frag_off = 0;
|
||||
BOOL ipv4 = FALSE, MF = FALSE, fragment = FALSE, is_ext_header;
|
||||
|
||||
if (pPacket == NULL || packetLen < sizeof(WINDIVERT_IPHDR))
|
||||
if (pPacket == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
data = (UINT8 *)pPacket;
|
||||
data_len = packetLen;
|
||||
|
||||
ip_header = (PWINDIVERT_IPHDR)data;
|
||||
switch (ip_header->Version)
|
||||
switch (layer)
|
||||
{
|
||||
case 4:
|
||||
if (packetLen < sizeof(WINDIVERT_IPHDR) ||
|
||||
ip_header->HdrLength < 5)
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
if (data_len < sizeof(WINDIVERT_ETHHDR))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
total_len = (UINT)ntohs(ip_header->Length);
|
||||
protocol = ip_header->Protocol;
|
||||
header_len = ip_header->HdrLength * sizeof(UINT32);
|
||||
if (total_len < header_len || packetLen < header_len)
|
||||
eth_header = (PWINDIVERT_ETHHDR)data;
|
||||
data = (PVOID)(eth_header + 1);
|
||||
data_len -= sizeof(WINDIVERT_ETHHDR);
|
||||
header_len = sizeof(WINDIVERT_ETHHDR);
|
||||
switch (ntohs(eth_header->Type))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
frag_off = ntohs(WINDIVERT_IPHDR_GET_FRAGOFF(ip_header));
|
||||
MF = (WINDIVERT_IPHDR_GET_MF(ip_header) != 0);
|
||||
fragment = (MF || frag_off != 0);
|
||||
packet_len = (total_len < packetLen? total_len: packetLen);
|
||||
data += header_len;
|
||||
data_len = packet_len - header_len;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
ip_header = NULL;
|
||||
ipv6_header = (PWINDIVERT_IPV6HDR)data;
|
||||
if (packetLen < sizeof(WINDIVERT_IPV6HDR))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
protocol = ipv6_header->NextHdr;
|
||||
total_len = (UINT)ntohs(ipv6_header->Length) +
|
||||
sizeof(WINDIVERT_IPV6HDR);
|
||||
packet_len = (total_len < packetLen? total_len: packetLen);
|
||||
data += sizeof(WINDIVERT_IPV6HDR);
|
||||
data_len = packet_len - sizeof(WINDIVERT_IPV6HDR);
|
||||
|
||||
while (frag_off == 0 && data_len >= 2)
|
||||
{
|
||||
header_len = (UINT)data[1];
|
||||
is_ext_header = TRUE;
|
||||
switch (protocol)
|
||||
{
|
||||
case IPPROTO_FRAGMENT:
|
||||
header_len = 8;
|
||||
if (fragment || data_len < header_len)
|
||||
{
|
||||
is_ext_header = FALSE;
|
||||
break;
|
||||
}
|
||||
frag_header = (PWINDIVERT_IPV6FRAGHDR)data;
|
||||
frag_off = ntohs(
|
||||
WINDIVERT_IPV6FRAGHDR_GET_FRAGOFF(frag_header));
|
||||
MF = WINDIVERT_IPV6FRAGHDR_GET_MF(frag_header);
|
||||
fragment = TRUE;
|
||||
break;
|
||||
case IPPROTO_AH:
|
||||
header_len += 2;
|
||||
header_len *= 4;
|
||||
break;
|
||||
case IPPROTO_HOPOPTS:
|
||||
case IPPROTO_DSTOPTS:
|
||||
case IPPROTO_ROUTING:
|
||||
case IPPROTO_MH:
|
||||
header_len++;
|
||||
header_len *= 8;
|
||||
break;
|
||||
default:
|
||||
is_ext_header = FALSE;
|
||||
break;
|
||||
}
|
||||
if (!is_ext_header || data_len < header_len)
|
||||
{
|
||||
case ETHERTYPE_IP:
|
||||
if (data_len < sizeof(WINDIVERT_IPHDR))
|
||||
{
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
ipv4 = TRUE;
|
||||
break;
|
||||
}
|
||||
protocol = data[0];
|
||||
data += header_len;
|
||||
data_len -= header_len;
|
||||
case ETHERTYPE_IPV6:
|
||||
if (data_len < sizeof(WINDIVERT_IPV6HDR))
|
||||
{
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
ip_packet_len = data_len;
|
||||
break;
|
||||
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
case WINDIVERT_LAYER_NETWORK_FORWARD:
|
||||
if (data_len < sizeof(WINDIVERT_IPHDR))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
switch (((PWINDIVERT_IPHDR)data)->Version)
|
||||
{
|
||||
case 4:
|
||||
ipv4 = TRUE;
|
||||
break;
|
||||
case 6:
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
ip_packet_len = packetLen;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (ipv4)
|
||||
{
|
||||
ip_header = (PWINDIVERT_IPHDR)data;
|
||||
if (ip_header->HdrLength < 5)
|
||||
{
|
||||
WinDivertHelperParsePacketIPError:
|
||||
if (eth_header == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
ip_total_len = (UINT)ntohs(ip_header->Length);
|
||||
ip_protocol = ip_header->Protocol;
|
||||
ip_header_len = ip_header->HdrLength * sizeof(UINT32);
|
||||
if (ip_total_len < ip_header_len || ip_packet_len < ip_header_len)
|
||||
{
|
||||
goto WinDivertHelperParsePacketIPError;
|
||||
}
|
||||
frag_off = ntohs(WINDIVERT_IPHDR_GET_FRAGOFF(ip_header));
|
||||
MF = (WINDIVERT_IPHDR_GET_MF(ip_header) != 0);
|
||||
fragment = (MF || frag_off != 0);
|
||||
ip_packet_len =
|
||||
(ip_total_len < ip_packet_len? ip_total_len: ip_packet_len);
|
||||
data += ip_header_len;
|
||||
data_len = ip_packet_len - ip_header_len;
|
||||
header_len += ip_header_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data_len < sizeof(WINDIVERT_IPV6HDR))
|
||||
{
|
||||
goto WinDivertHelperParsePacketIPError;
|
||||
}
|
||||
ipv6_header = (PWINDIVERT_IPV6HDR)data;
|
||||
ip_protocol = ipv6_header->NextHdr;
|
||||
ip_total_len = (UINT)ntohs(ipv6_header->Length) +
|
||||
sizeof(WINDIVERT_IPV6HDR);
|
||||
ip_packet_len =
|
||||
(ip_total_len < ip_packet_len? ip_total_len: ip_packet_len);
|
||||
data += sizeof(WINDIVERT_IPV6HDR);
|
||||
data_len = ip_packet_len - sizeof(WINDIVERT_IPV6HDR);
|
||||
header_len += ip_header_len;
|
||||
|
||||
while (frag_off == 0 && data_len >= 2)
|
||||
{
|
||||
ip_header_len = (UINT)data[1];
|
||||
is_ext_header = TRUE;
|
||||
switch (ip_protocol)
|
||||
{
|
||||
case IPPROTO_FRAGMENT:
|
||||
ip_header_len = 8;
|
||||
if (fragment || data_len < ip_header_len)
|
||||
{
|
||||
is_ext_header = FALSE;
|
||||
break;
|
||||
}
|
||||
frag_header = (PWINDIVERT_IPV6FRAGHDR)data;
|
||||
frag_off = ntohs(
|
||||
WINDIVERT_IPV6FRAGHDR_GET_FRAGOFF(frag_header));
|
||||
MF = WINDIVERT_IPV6FRAGHDR_GET_MF(frag_header);
|
||||
fragment = TRUE;
|
||||
break;
|
||||
case IPPROTO_AH:
|
||||
ip_header_len += 2;
|
||||
ip_header_len *= 4;
|
||||
break;
|
||||
case IPPROTO_HOPOPTS:
|
||||
case IPPROTO_DSTOPTS:
|
||||
case IPPROTO_ROUTING:
|
||||
case IPPROTO_MH:
|
||||
ip_header_len++;
|
||||
ip_header_len *= 8;
|
||||
break;
|
||||
default:
|
||||
is_ext_header = FALSE;
|
||||
break;
|
||||
}
|
||||
if (!is_ext_header || data_len < ip_header_len)
|
||||
{
|
||||
break;
|
||||
}
|
||||
ip_protocol = data[0];
|
||||
data += ip_header_len;
|
||||
data_len -= ip_header_len;
|
||||
header_len += ip_header_len;
|
||||
}
|
||||
}
|
||||
|
||||
if (frag_off != 0)
|
||||
{
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
switch (protocol)
|
||||
switch (ip_protocol)
|
||||
{
|
||||
case IPPROTO_TCP:
|
||||
tcp_header = (PWINDIVERT_TCPHDR)data;
|
||||
@@ -482,8 +569,9 @@ static BOOL WinDivertHelperParsePacketEx(const VOID *pPacket, UINT packetLen,
|
||||
tcp_header = NULL;
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
header_len = tcp_header->HdrLength * sizeof(UINT32);
|
||||
header_len = (header_len > data_len? data_len: header_len);
|
||||
trans_header_len = tcp_header->HdrLength * sizeof(UINT32);
|
||||
trans_header_len =
|
||||
(trans_header_len > data_len? data_len: trans_header_len);
|
||||
break;
|
||||
|
||||
case IPPROTO_UDP:
|
||||
@@ -492,7 +580,7 @@ static BOOL WinDivertHelperParsePacketEx(const VOID *pPacket, UINT packetLen,
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
udp_header = (PWINDIVERT_UDPHDR)data;
|
||||
header_len = sizeof(WINDIVERT_UDPHDR);
|
||||
trans_header_len = sizeof(WINDIVERT_UDPHDR);
|
||||
break;
|
||||
|
||||
case IPPROTO_ICMP:
|
||||
@@ -502,7 +590,7 @@ static BOOL WinDivertHelperParsePacketEx(const VOID *pPacket, UINT packetLen,
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
icmp_header = (PWINDIVERT_ICMPHDR)data;
|
||||
header_len = sizeof(WINDIVERT_ICMPHDR);
|
||||
trans_header_len = sizeof(WINDIVERT_ICMPHDR);
|
||||
break;
|
||||
|
||||
case IPPROTO_ICMPV6:
|
||||
@@ -512,14 +600,15 @@ static BOOL WinDivertHelperParsePacketEx(const VOID *pPacket, UINT packetLen,
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
icmpv6_header = (PWINDIVERT_ICMPV6HDR)data;
|
||||
header_len = sizeof(WINDIVERT_ICMPV6HDR);
|
||||
trans_header_len = sizeof(WINDIVERT_ICMPV6HDR);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
data += header_len;
|
||||
data_len -= header_len;
|
||||
data += trans_header_len;
|
||||
data_len -= trans_header_len;
|
||||
header_len += trans_header_len;
|
||||
|
||||
WinDivertHelperParsePacketExit:
|
||||
if (pInfo == NULL)
|
||||
@@ -527,13 +616,14 @@ WinDivertHelperParsePacketExit:
|
||||
return TRUE;
|
||||
}
|
||||
data = (data_len == 0? NULL: data);
|
||||
pInfo->Protocol = (UINT32)protocol;
|
||||
pInfo->Protocol = (UINT32)ip_protocol;
|
||||
pInfo->Fragment = (fragment? 1: 0);
|
||||
pInfo->MF = (MF? 1: 0);
|
||||
pInfo->FragOff = (UINT32)frag_off;
|
||||
pInfo->Truncated = (total_len > packetLen? 1: 0);
|
||||
pInfo->Extended = (total_len < packetLen? 1: 0);
|
||||
pInfo->Truncated = (ip_total_len > ip_packet_len? 1: 0);
|
||||
pInfo->Extended = (ip_total_len < ip_packet_len? 1: 0);
|
||||
pInfo->Reserved1 = 0;
|
||||
pInfo->EthHeader = eth_header;
|
||||
pInfo->IPHeader = ip_header;
|
||||
pInfo->IPv6Header = ipv6_header;
|
||||
pInfo->ICMPHeader = icmp_header;
|
||||
@@ -541,7 +631,7 @@ WinDivertHelperParsePacketExit:
|
||||
pInfo->TCPHeader = tcp_header;
|
||||
pInfo->UDPHeader = udp_header;
|
||||
pInfo->Payload = data;
|
||||
pInfo->HeaderLength = (UINT32)(packet_len - data_len);
|
||||
pInfo->HeaderLength = (UINT32)header_len;
|
||||
pInfo->PayloadLength = (UINT32)data_len;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -550,7 +640,7 @@ WinDivertHelperParsePacketExit:
|
||||
* Calculate IPv4/IPv6/ICMP/ICMPv6/TCP/UDP checksums.
|
||||
*/
|
||||
BOOL WinDivertHelperCalcChecksums(PVOID pPacket, UINT packetLen,
|
||||
WINDIVERT_ADDRESS *pAddr, UINT64 flags)
|
||||
WINDIVERT_LAYER layer, WINDIVERT_ADDRESS *pAddr, UINT64 flags)
|
||||
{
|
||||
UINT8 pseudo_header[
|
||||
MAX(sizeof(WINDIVERT_PSEUDOHDR), sizeof(WINDIVERT_PSEUDOV6HDR))];
|
||||
@@ -565,7 +655,7 @@ BOOL WinDivertHelperCalcChecksums(PVOID pPacket, UINT packetLen,
|
||||
UINT payload_len, checksum_len;
|
||||
BOOL truncated;
|
||||
|
||||
if (!WinDivertHelperParsePacketEx(pPacket, packetLen, &info))
|
||||
if (!WinDivertHelperParsePacketEx(pPacket, packetLen, layer, &info))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -754,53 +844,104 @@ static UINT16 WinDivertCalcChecksum(PVOID pseudo_header,
|
||||
/*
|
||||
* Decrement the TTL.
|
||||
*/
|
||||
BOOL WinDivertHelperDecrementTTL(VOID *packet, UINT packetLen)
|
||||
BOOL WinDivertHelperDecrementTTL(VOID *packet, UINT packetLen,
|
||||
WINDIVERT_LAYER layer)
|
||||
{
|
||||
PWINDIVERT_ETHHDR eth_header;
|
||||
PWINDIVERT_IPHDR ip_header;
|
||||
PWINDIVERT_IPV6HDR ipv6_header;
|
||||
BOOL is_ipv6 = FALSE;
|
||||
|
||||
if (packet == NULL || packetLen < sizeof(WINDIVERT_IPHDR))
|
||||
if (packet == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ip_header = (PWINDIVERT_IPHDR)packet;
|
||||
switch (ip_header->Version)
|
||||
switch (layer)
|
||||
{
|
||||
case 4:
|
||||
if (ip_header->TTL <= 1)
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
if (packetLen < sizeof(WINDIVERT_ETHHDR))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
ip_header->TTL--;
|
||||
|
||||
// Incremental checksum update:
|
||||
if (ip_header->Checksum >= 0xFFFE)
|
||||
eth_header = (PWINDIVERT_ETHHDR)packet;
|
||||
switch (ntohs(eth_header->Type))
|
||||
{
|
||||
ip_header->Checksum -= 0xFFFE;
|
||||
case ETHERTYPE_IP:
|
||||
if (packetLen < sizeof(WINDIVERT_IPHDR))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case ETHERTYPE_IPV6:
|
||||
if (packetLen < sizeof(WINDIVERT_IPV6HDR))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
is_ipv6 = TRUE;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ip_header->Checksum += 1;
|
||||
}
|
||||
return TRUE;
|
||||
packet = (VOID *)(eth_header + 1);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (packetLen < sizeof(WINDIVERT_IPV6HDR))
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
case WINDIVERT_LAYER_NETWORK_FORWARD:
|
||||
if (packetLen < sizeof(WINDIVERT_IPHDR))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
ipv6_header = (PWINDIVERT_IPV6HDR)packet;
|
||||
if (ipv6_header->HopLimit <= 1)
|
||||
ip_header = (PWINDIVERT_IPHDR)packet;
|
||||
switch (ip_header->Version)
|
||||
{
|
||||
return FALSE;
|
||||
case 4:
|
||||
break;
|
||||
case 6:
|
||||
if (packetLen < sizeof(WINDIVERT_IPV6HDR))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
is_ipv6 = TRUE;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
ipv6_header->HopLimit--;
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!is_ipv6)
|
||||
{
|
||||
ip_header = (PWINDIVERT_IPHDR)packet;
|
||||
if (ip_header->TTL <= 1)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
ip_header->TTL--;
|
||||
|
||||
// Incremental checksum update:
|
||||
if (ip_header->Checksum >= 0xFFFE)
|
||||
{
|
||||
ip_header->Checksum -= 0xFFFE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ip_header->Checksum += 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ipv6_header = (PWINDIVERT_IPV6HDR)packet;
|
||||
if (ipv6_header->HopLimit <= 1)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
ipv6_header->HopLimit--;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -810,92 +951,95 @@ static BOOL WinDivertValidateField(WINDIVERT_LAYER layer, UINT32 field)
|
||||
{
|
||||
static const UINT8 flags[] =
|
||||
{
|
||||
LNMFSR, /* WINDIVERT_FILTER_FIELD_ZERO */
|
||||
LN_FS_, /* WINDIVERT_FILTER_FIELD_INBOUND */
|
||||
LN_FS_, /* WINDIVERT_FILTER_FIELD_OUTBOUND */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IFIDX */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_SUBIFIDX */
|
||||
LNMFS_, /* WINDIVERT_FILTER_FIELD_IP */
|
||||
LNMFS_, /* WINDIVERT_FILTER_FIELD_IPV6 */
|
||||
LNMFS_, /* WINDIVERT_FILTER_FIELD_ICMP */
|
||||
LNMFS_, /* WINDIVERT_FILTER_FIELD_TCP */
|
||||
LNMFS_, /* WINDIVERT_FILTER_FIELD_UDP */
|
||||
LNMFS_, /* WINDIVERT_FILTER_FIELD_ICMPV6 */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IP_HDRLENGTH */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IP_TOS */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IP_LENGTH */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IP_ID */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IP_DF */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IP_MF */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IP_FRAGOFF */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IP_TTL */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IP_PROTOCOL */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IP_CHECKSUM */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IP_SRCADDR */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IP_DSTADDR */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IPV6_TRAFFICCLASS */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IPV6_FLOWLABEL */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IPV6_LENGTH */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IPV6_NEXTHDR */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IPV6_HOPLIMIT */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IPV6_SRCADDR */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IPV6_DSTADDR */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_ICMP_TYPE */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_ICMP_CODE */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_ICMP_CHECKSUM */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_ICMP_BODY */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_ICMPV6_TYPE */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_ICMPV6_CODE */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_ICMPV6_CHECKSUM */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_ICMPV6_BODY */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_SRCPORT */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_DSTPORT */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_SEQNUM */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_ACKNUM */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_HDRLENGTH */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_URG */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_ACK */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_PSH */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_RST */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_SYN */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_FIN */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_WINDOW */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_CHECKSUM */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_URGPTR */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_PAYLOADLENGTH */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_UDP_SRCPORT */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_UDP_DSTPORT */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_UDP_LENGTH */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_UDP_CHECKSUM */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH */
|
||||
LN_FS_, /* WINDIVERT_FILTER_FIELD_LOOPBACK */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_IMPOSTOR */
|
||||
L__FSR, /* WINDIVERT_FILTER_FIELD_PROCESSID */
|
||||
LN_FS_, /* WINDIVERT_FILTER_FIELD_LOCALADDR */
|
||||
LN_FS_, /* WINDIVERT_FILTER_FIELD_REMOTEADDR */
|
||||
LN_FS_, /* WINDIVERT_FILTER_FIELD_LOCALPORT */
|
||||
LN_FS_, /* WINDIVERT_FILTER_FIELD_REMOTEPORT */
|
||||
LN_FS_, /* WINDIVERT_FILTER_FIELD_PROTOCOL */
|
||||
L__FS_, /* WINDIVERT_FILTER_FIELD_ENDPOINTID */
|
||||
L__FS_, /* WINDIVERT_FILTER_FIELD_PARENTENDPOINTID */
|
||||
L____R, /* WINDIVERT_FILTER_FIELD_LAYER */
|
||||
L____R, /* WINDIVERT_FILTER_FIELD_PRIORITY */
|
||||
LNMFSR, /* WINDIVERT_FILTER_FIELD_EVENT */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_PACKET */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_PACKET16 */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_PACKET32 */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_PAYLOAD */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_PAYLOAD16 */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_TCP_PAYLOAD32 */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_UDP_PAYLOAD */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_UDP_PAYLOAD16 */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_UDP_PAYLOAD32 */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_LENGTH */
|
||||
LNMFSR, /* WINDIVERT_FILTER_FIELD_TIMESTAMP */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_RANDOM8 */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_RANDOM16 */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_RANDOM32 */
|
||||
LNM___, /* WINDIVERT_FILTER_FIELD_FRAGMENT */
|
||||
LENMFSR, /* WINDIVERT_FILTER_FIELD_ZERO */
|
||||
LEN_FS_, /* WINDIVERT_FILTER_FIELD_INBOUND */
|
||||
LEN_FS_, /* WINDIVERT_FILTER_FIELD_OUTBOUND */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IFIDX */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_SUBIFIDX */
|
||||
LENMFS_, /* WINDIVERT_FILTER_FIELD_IP */
|
||||
LENMFS_, /* WINDIVERT_FILTER_FIELD_IPV6 */
|
||||
LENMFS_, /* WINDIVERT_FILTER_FIELD_ICMP */
|
||||
LENMFS_, /* WINDIVERT_FILTER_FIELD_TCP */
|
||||
LENMFS_, /* WINDIVERT_FILTER_FIELD_UDP */
|
||||
LENMFS_, /* WINDIVERT_FILTER_FIELD_ICMPV6 */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IP_HDRLENGTH */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IP_TOS */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IP_LENGTH */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IP_ID */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IP_DF */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IP_MF */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IP_FRAGOFF */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IP_TTL */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IP_PROTOCOL */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IP_CHECKSUM */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IP_SRCADDR */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IP_DSTADDR */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IPV6_TRAFFICCLASS */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IPV6_FLOWLABEL */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IPV6_LENGTH */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IPV6_NEXTHDR */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IPV6_HOPLIMIT */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IPV6_SRCADDR */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IPV6_DSTADDR */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_ICMP_TYPE */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_ICMP_CODE */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_ICMP_CHECKSUM */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_ICMP_BODY */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_ICMPV6_TYPE */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_ICMPV6_CODE */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_ICMPV6_CHECKSUM */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_ICMPV6_BODY */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_SRCPORT */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_DSTPORT */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_SEQNUM */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_ACKNUM */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_HDRLENGTH */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_URG */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_ACK */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_PSH */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_RST */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_SYN */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_FIN */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_WINDOW */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_CHECKSUM */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_URGPTR */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_PAYLOADLENGTH */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_UDP_SRCPORT */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_UDP_DSTPORT */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_UDP_LENGTH */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_UDP_CHECKSUM */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH */
|
||||
L_N_FS_, /* WINDIVERT_FILTER_FIELD_LOOPBACK */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_IMPOSTOR */
|
||||
L___FSR, /* WINDIVERT_FILTER_FIELD_PROCESSID */
|
||||
LEN_FS_, /* WINDIVERT_FILTER_FIELD_LOCALADDR */
|
||||
LEN_FS_, /* WINDIVERT_FILTER_FIELD_REMOTEADDR */
|
||||
LEN_FS_, /* WINDIVERT_FILTER_FIELD_LOCALPORT */
|
||||
LEN_FS_, /* WINDIVERT_FILTER_FIELD_REMOTEPORT */
|
||||
LEN_FS_, /* WINDIVERT_FILTER_FIELD_PROTOCOL */
|
||||
L___FS_, /* WINDIVERT_FILTER_FIELD_ENDPOINTID */
|
||||
L___FS_, /* WINDIVERT_FILTER_FIELD_PARENTENDPOINTID */
|
||||
L_____R, /* WINDIVERT_FILTER_FIELD_LAYER */
|
||||
L_____R, /* WINDIVERT_FILTER_FIELD_PRIORITY */
|
||||
LENMFSR, /* WINDIVERT_FILTER_FIELD_EVENT */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_PACKET */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_PACKET16 */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_PACKET32 */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_PAYLOAD */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_PAYLOAD16 */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_TCP_PAYLOAD32 */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_UDP_PAYLOAD */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_UDP_PAYLOAD16 */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_UDP_PAYLOAD32 */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_LENGTH */
|
||||
LENMFSR, /* WINDIVERT_FILTER_FIELD_TIMESTAMP */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_RANDOM8 */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_RANDOM16 */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_RANDOM32 */
|
||||
LENM___, /* WINDIVERT_FILTER_FIELD_FRAGMENT */
|
||||
LE_____, /* WINDIVERT_FILTER_FIELD_ETH_DST_ADDR */
|
||||
LE_____, /* WINDIVERT_FILTER_FIELD_ETH_SRC_ADDR */
|
||||
LE_____, /* WINDIVERT_FILTER_FIELD_ETH_TYPE */
|
||||
};
|
||||
|
||||
if (field > WINDIVERT_FILTER_FIELD_MAX)
|
||||
@@ -972,10 +1116,12 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
|
||||
BOOL loopback,
|
||||
BOOL impostor,
|
||||
BOOL fragment,
|
||||
const WINDIVERT_DATA_ETHERNET *ethernet_data,
|
||||
const WINDIVERT_DATA_NETWORK *network_data,
|
||||
const WINDIVERT_DATA_FLOW *flow_data,
|
||||
const WINDIVERT_DATA_SOCKET *socket_data,
|
||||
const WINDIVERT_DATA_REFLECT *reflect_data,
|
||||
const WINDIVERT_ETHHDR *eth_header,
|
||||
const WINDIVERT_IPHDR *ip_header,
|
||||
const WINDIVERT_IPV6HDR *ipv6_header,
|
||||
const WINDIVERT_ICMPHDR *icmp_header,
|
||||
@@ -994,6 +1140,7 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
|
||||
UINT16 data16;
|
||||
UINT32 data32;
|
||||
ULARGE_INTEGER val64;
|
||||
const UINT8 *eth_addr;
|
||||
|
||||
ip = 0;
|
||||
ttl = WINDIVERT_FILTER_MAXLEN+1;
|
||||
@@ -1017,11 +1164,16 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
|
||||
if (random64 == 0)
|
||||
{
|
||||
random64 = WinDivertHashPacket((UINT64)timestamp,
|
||||
ip_header, ipv6_header, icmp_header, icmpv6_header,
|
||||
tcp_header, udp_header);
|
||||
eth_header, ip_header, ipv6_header, icmp_header,
|
||||
icmpv6_header, tcp_header, udp_header);
|
||||
random64 |= 0xFF00000000000000ull; // Make non-zero.
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_ETH_DST_ADDR:
|
||||
case WINDIVERT_FILTER_FIELD_ETH_SRC_ADDR:
|
||||
case WINDIVERT_FILTER_FIELD_ETH_TYPE:
|
||||
result = (eth_header != NULL);
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_IP_HDRLENGTH:
|
||||
case WINDIVERT_FILTER_FIELD_IP_TOS:
|
||||
case WINDIVERT_FILTER_FIELD_IP_LENGTH:
|
||||
@@ -1174,6 +1326,9 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
|
||||
case WINDIVERT_FILTER_FIELD_IFIDX:
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
val[0] = ethernet_data->IfIdx;
|
||||
break;
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
case WINDIVERT_LAYER_NETWORK_FORWARD:
|
||||
val[0] = network_data->IfIdx;
|
||||
@@ -1183,7 +1338,17 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_SUBIFIDX:
|
||||
val[0] = network_data->SubIfIdx;
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
val[0] = ethernet_data->SubIfIdx;
|
||||
break;
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
val[0] = network_data->SubIfIdx;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_LOOPBACK:
|
||||
val[0] = (UINT32)loopback;
|
||||
@@ -1200,6 +1365,7 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
|
||||
case WINDIVERT_FILTER_FIELD_ICMP:
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
case WINDIVERT_LAYER_NETWORK_FORWARD:
|
||||
val[0] = (UINT32)(icmp_header != NULL);
|
||||
@@ -1219,6 +1385,7 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
|
||||
case WINDIVERT_FILTER_FIELD_ICMPV6:
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
case WINDIVERT_LAYER_NETWORK_FORWARD:
|
||||
val[0] = (UINT32)(icmpv6_header != NULL);
|
||||
@@ -1238,6 +1405,7 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
|
||||
case WINDIVERT_FILTER_FIELD_TCP:
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
case WINDIVERT_LAYER_NETWORK_FORWARD:
|
||||
val[0] = (UINT32)(tcp_header != NULL);
|
||||
@@ -1257,6 +1425,7 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
|
||||
case WINDIVERT_FILTER_FIELD_UDP:
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
case WINDIVERT_LAYER_NETWORK_FORWARD:
|
||||
val[0] = (UINT32)(udp_header != NULL);
|
||||
@@ -1273,6 +1442,23 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
|
||||
return -1;
|
||||
}
|
||||
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;
|
||||
case WINDIVERT_FILTER_FIELD_ETH_TYPE:
|
||||
val[0] = (UINT32)ntohs(eth_header->Type);
|
||||
break;
|
||||
case WINDIVERT_FILTER_FIELD_IP_HDRLENGTH:
|
||||
val[0] = (UINT32)ip_header->HdrLength;
|
||||
break;
|
||||
@@ -1435,6 +1621,7 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
|
||||
big = TRUE;
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
if (ip_header != NULL)
|
||||
{
|
||||
@@ -1483,6 +1670,7 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
|
||||
big = TRUE;
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
if (ip_header != NULL)
|
||||
{
|
||||
@@ -1530,6 +1718,7 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
|
||||
case WINDIVERT_FILTER_FIELD_LOCALPORT:
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
if (tcp_header != NULL)
|
||||
{
|
||||
@@ -1571,6 +1760,7 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
|
||||
case WINDIVERT_FILTER_FIELD_REMOTEPORT:
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
if (tcp_header != NULL)
|
||||
{
|
||||
@@ -1612,6 +1802,7 @@ static WINDIVERT_INLINE int WinDivertExecuteFilter(
|
||||
case WINDIVERT_FILTER_FIELD_PROTOCOL:
|
||||
switch (layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
val[0] = (UINT32)protocol;
|
||||
break;
|
||||
|
||||
+381
-196
@@ -1,11 +1,11 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>WinDivert 2.2 Documentation</title>
|
||||
<title>WinDivert 3.0 Documentation</title>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<h1>WinDivert 2.2: Windows Packet Divert</h1>
|
||||
<h1>WinDivert 3.0: Windows Packet Divert</h1>
|
||||
<h2>Table of Contents</h2>
|
||||
<ul>
|
||||
<li><a href="#introduction">1. Introduction</a></li>
|
||||
@@ -34,25 +34,28 @@
|
||||
</li>
|
||||
<li><a href="#helper_programming_api">6. Helper Programming API</a>
|
||||
<ul>
|
||||
<li><a href="#divert_iphdr">6.1 WINDIVERT_IPHDR</a></li>
|
||||
<li><a href="#divert_ipv6hdr">6.2 WINDIVERT_IPV6HDR</a></li>
|
||||
<li><a href="#divert_icmphdr">6.3 WINDIVERT_ICMPHDR</a></li>
|
||||
<li><a href="#divert_icmpv6hdr">6.4 WINDIVERT_ICMPV6HDR</a></li>
|
||||
<li><a href="#divert_tcphdr">6.5 WINDIVERT_TCPHDR</a></li>
|
||||
<li><a href="#divert_udphdr">6.6 WINDIVERT_UDPHDR</a></li>
|
||||
<li><a href="#divert_helper_parse_packet">6.7 WinDivertHelperParsePacket</a></li>
|
||||
<li><a href="#divert_helper_hash_packet">6.8 WinDivertHelperHashPacket</a></li>
|
||||
<li><a href="#divert_helper_parse_ipv4_address">6.9 WinDivertHelperParseIPv4Address</a></li>
|
||||
<li><a href="#divert_helper_parse_ipv6_address">6.10 WinDivertHelperParseIPv6Address</a></li>
|
||||
<li><a href="#divert_helper_format_ipv4_address">6.11 WinDivertHelperFormatIPv4Address</a></li>
|
||||
<li><a href="#divert_helper_format_ipv6_address">6.12 WinDivertHelperFormatIPv6Address</a></li>
|
||||
<li><a href="#divert_helper_calc_checksums">6.13 WinDivertHelperCalcChecksums</a></li>
|
||||
<li><a href="#divert_helper_dec_ttl">6.14 WinDivertHelperDecrementTTL</a></li>
|
||||
<li><a href="#divert_helper_compile_filter">6.15 WinDivertHelperCompileFilter</a></li>
|
||||
<li><a href="#divert_helper_eval_filter">6.16 WinDivertHelperEvalFilter</a></li>
|
||||
<li><a href="#divert_helper_format_filter">6.17 WinDivertHelperFormatFilter</a></li>
|
||||
<li><a href="#divert_helper_ntoh">6.18 WinDivertHelperNtoh*</a></li>
|
||||
<li><a href="#divert_helper_hton">6.19 WinDivertHelperHton*</a></li>
|
||||
<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>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#filter_language">7. Filter Language</a>
|
||||
@@ -72,7 +75,7 @@
|
||||
<p>
|
||||
WinDivert is a powerful user-mode
|
||||
capture/sniffing/modification/blocking/re-injection package for
|
||||
Windows 7, Windows 8 and Windows 10.
|
||||
Windows 8 and Windows 10, as well as Windows Server 2012/2016/2019.
|
||||
WinDivert can be used to implement user-mode packet filters, packet sniffers,
|
||||
firewalls, NAT, VPNs, tunneling applications, etc., without the need to
|
||||
write kernel-mode code.
|
||||
@@ -116,25 +119,26 @@ The source code for WinDivert is available for download at:
|
||||
To build the WinDivert drivers from source:
|
||||
</p>
|
||||
<ol>
|
||||
<li> Download and install <a href="http://www.microsoft.com/whdc/devtools/wdk/default.mspx">
|
||||
Windows Driver Kit 7.1.0</a>.</li>
|
||||
<li> Open a <i>x86 Free Build Environment</i> console.</li>
|
||||
<li> Download and install Visual Studio 2015 and Windows Driver Kit (WDK).</li>
|
||||
<li> Open a Visual Studio 2015 <i>Developer Command Prompt</i>.</li>
|
||||
<li> In the WinDivert package root directory, run the command:
|
||||
<pre>
|
||||
wddk-build.bat
|
||||
msvc-build.bat
|
||||
</pre>
|
||||
This will build the <code>install\WDDK\i386\WinDivert32.sys</code> driver.</li>
|
||||
<li> Next, open a <i>x64 Free Build Environment</i> console.</li>
|
||||
<li> Re-run the <code>wddk-build.bat</code> command to build the
|
||||
<code>install\WDDK\amd64\WinDivert64.sys</code> driver.</li>
|
||||
This will build the <code>install\MSVC\i386\WinDivert32.sys</code> and
|
||||
<code>install\WDDK\amd64\WinDivert64.sys</code> drivers.</li>
|
||||
</ol>
|
||||
<p>
|
||||
To build the WinDivert user-mode library (<code>WinDivert.dll</code>) and sample
|
||||
programs:
|
||||
Note that the <code>msvc-build.bat</code> script will also build the
|
||||
<code>WinDivert.dll</code> and sample programs.
|
||||
However, these versions are not used in the official distribution
|
||||
because of the dependency on the Visual Studio 2015 C runtime.
|
||||
</p><p>
|
||||
To build the (dependency free) WinDivert user-mode library
|
||||
(<code>WinDivert.dll</code>) and sample programs:
|
||||
</p>
|
||||
<ol>
|
||||
<li> First, build the WinDivert drivers by running the
|
||||
<code>wddk-build.bat</code> command described above.</li>
|
||||
<li> First, build the WinDivert drivers as described above.</li>
|
||||
<li> In Linux (with the MinGW cross-compilers installed) and in the
|
||||
WinDivert package root directory, run the command:
|
||||
<pre>
|
||||
@@ -272,6 +276,7 @@ typedef enum
|
||||
WINDIVERT_LAYER_FLOW,
|
||||
WINDIVERT_LAYER_SOCKET,
|
||||
WINDIVERT_LAYER_REFLECT,
|
||||
WINDIVERT_LAYER_ETHERNET,
|
||||
} <b>WINDIVERT_LAYER</b>, *<b>PWINDIVERT_LAYER</b>;
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
@@ -311,6 +316,15 @@ PID?
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>WINDIVERT_LAYER_ETHERNET</code>
|
||||
</td>
|
||||
<td>✔</td><td>✔</td><td>✔</td><td></td>
|
||||
<td>
|
||||
Ethernet frames to/from the local machine.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>WINDIVERT_LAYER_NETWORK</code>
|
||||
</td>
|
||||
<td>✔</td><td>✔</td><td>✔</td><td></td>
|
||||
@@ -367,12 +381,21 @@ Here, the layer capabilities are:
|
||||
an event/packet is available at this layer, or not.
|
||||
</ul>
|
||||
<p>
|
||||
The <code>WINDIVERT_LAYER_NETWORK</code> and
|
||||
<code>WINDIVERT_LAYER_NETWORK_FORWARD</code>
|
||||
layers allow the user application to capture/block/inject network packets
|
||||
The <code>WINDIVERT_LAYER_ETHERNET</code>
|
||||
layer allows the user application to capture/block/inject ethernet
|
||||
frames passing to/from the local machine.
|
||||
An ethernet frame will start with <i>ethernet header</i>,
|
||||
followed by a packet from an upper layer protocol, such as
|
||||
IPv4, IPv6, ARP, etc.
|
||||
</p>
|
||||
<p>
|
||||
The <code>WINDIVERT_LAYER_NETWORK</code> (and
|
||||
<code>WINDIVERT_LAYER_NETWORK_FORWARD</code>)
|
||||
layers allow the user application to
|
||||
capture/block/inject network packets
|
||||
passing to/from (and through) the local machine.
|
||||
Due to technical limitations, process ID information is not available
|
||||
at these layers.
|
||||
Network layer packets start with either an IPv4 or IPv6 header,
|
||||
typically followed by a transport layer payload (e.g., TCP or UDP).
|
||||
</p>
|
||||
<p>
|
||||
The <code>WINDIVERT_LAYER_FLOW</code> layer captures information about
|
||||
@@ -393,8 +416,10 @@ The <code>WINDIVERT_LAYER_SOCKET</code> layer can capture or block events
|
||||
corresponding to socket operations, such as <code>bind()</code>,
|
||||
<code>connect()</code>, <code>listen()</code>, etc., or the termination
|
||||
of socket operations, such as a TCP socket disconnection.
|
||||
Unlike the flow layer, most socket-related events can be blocked.
|
||||
However, it is not possible to inject new or modified socket events.
|
||||
Unlike the flow layer, most socket-related events can be blocked,
|
||||
but it is not possible to inject new or modified socket events.
|
||||
Some events at this layer may be <i>implicit</i>, meaning that the event
|
||||
does not correspond to an explicit call to a WinSock2 function.
|
||||
Process ID information (of the process responsible for the socket operation)
|
||||
is available at this layer.
|
||||
Due to technical limitations, this layer cannot capture events that
|
||||
@@ -434,6 +459,7 @@ typedef enum
|
||||
WINDIVERT_EVENT_SOCKET_CLOSE,
|
||||
WINDIVERT_EVENT_REFLECT_OPEN,
|
||||
WINDIVERT_EVENT_REFLECT_CLOSE,
|
||||
WINDIVERT_EVENT_ETHERNET_FRAME,
|
||||
} <b>WINDIVERT_EVENT</b>, *<b>PWINDIVERT_EVENT</b>;
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
@@ -445,6 +471,27 @@ Each layer supports one or more <i>events</i> summarized below:
|
||||
<ul>
|
||||
<li>
|
||||
<p>
|
||||
<b><code>WINDIVERT_LAYER_ETHERNET</code></b>:
|
||||
Only a single event is supported:
|
||||
</p>
|
||||
<center>
|
||||
<table border="1" cellpadding="5" width="50%">
|
||||
<tr>
|
||||
<th>Event</th>
|
||||
<th>Description</th>
|
||||
<tr>
|
||||
<td>
|
||||
<code>WINDIVERT_EVENT_ETHERNET_FRAME</code>
|
||||
</td>
|
||||
<td>
|
||||
A new ethernet frame.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
<b><code>WINDIVERT_LAYER_NETWORK</code></b> and
|
||||
<b><code>WINDIVERT_LAYER_NETWORK_FORWARD</code></b>:
|
||||
Only a single event is supported:
|
||||
@@ -464,8 +511,6 @@ A new network packet.
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
<ul>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
@@ -585,6 +630,12 @@ An old WinDivert handle was closed.
|
||||
<a name="divert_address"><h3>5.3 WINDIVERT_ADDRESS</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
typedef struct
|
||||
{
|
||||
UINT32 IfIdx;
|
||||
UINT32 SubIfIdx;
|
||||
} <b>WINDIVERT_DATA_ETHERNET</b>, *<b>PWINDIVERT_DATA_ETHERNET</b>;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT32 IfIdx;
|
||||
@@ -627,22 +678,24 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
INT64 Timestamp;
|
||||
UINT64 Layer:8;
|
||||
UINT64 Event:8;
|
||||
UINT64 Sniffed:1;
|
||||
UINT64 Outbound:1;
|
||||
UINT64 Loopback:1;
|
||||
UINT64 Impostor:1;
|
||||
UINT64 IPv6:1;
|
||||
UINT64 IPChecksum:1;
|
||||
UINT64 TCPChecksum:1;
|
||||
UINT64 UDPChecksum:1;
|
||||
UINT32 Layer:8;
|
||||
UINT32 Event:8;
|
||||
UINT32 Sniffed:1;
|
||||
UINT32 Outbound:1;
|
||||
UINT32 Loopback:1;
|
||||
UINT32 Impostor:1;
|
||||
UINT32 IPv6:1;
|
||||
UINT32 IPChecksum:1;
|
||||
UINT32 TCPChecksum:1;
|
||||
UINT32 UDPChecksum:1;
|
||||
UINT32 Length:20;
|
||||
union
|
||||
{
|
||||
WINDIVERT_DATA_NETWORK Network;
|
||||
WINDIVERT_DATA_FLOW Flow;
|
||||
WINDIVERT_DATA_SOCKET Socket;
|
||||
WINDIVERT_DATA_REFLECT Reflect;
|
||||
WINDIVERT_DATA_ETHERNET Ethernet;
|
||||
WINDIVERT_DATA_NETWORK Network;
|
||||
WINDIVERT_DATA_FLOW Flow;
|
||||
WINDIVERT_DATA_SOCKET Socket;
|
||||
WINDIVERT_DATA_REFLECT Reflect;
|
||||
};
|
||||
} <b>WINDIVERT_ADDRESS</b>, *<b>PWINDIVERT_ADDRESS</b>;
|
||||
</pre>
|
||||
@@ -669,6 +722,11 @@ valid, <code>0</code> otherwise.</li>
|
||||
valid, <code>0</code> otherwise.</li>
|
||||
<li> <code>UDPChecksum</code>: Set to <code>1</code> if the UDP checksum is
|
||||
valid, <code>0</code> otherwise.</li>
|
||||
<li> <code>Length</code>: Set to the length of the packet.</li>
|
||||
<li> <code>Ethernet.IfIdx</code>: The interface index on which the frame
|
||||
arrived (for inbound frames), or is to be sent (for outbound frames).</li>
|
||||
<li> <code>Ethernet.SubIfIdx</code>: The sub-interface index for
|
||||
<code>IfIdx</code>.</li>
|
||||
<li> <code>Network.IfIdx</code>: The interface index on which the packet arrived
|
||||
(for inbound packets), or is to be sent (for outbound packets).</li>
|
||||
<li> <code>Network.SubIfIdx</code>: The sub-interface index for <code>IfIdx</code>.</li>
|
||||
@@ -754,11 +812,20 @@ When <i>IP/TCP/UDP checksum offloading</i> is enabled, it is possible that
|
||||
captured packets do not have valid checksums.
|
||||
Invalid checksums may be arbitrary values.
|
||||
</p><p>
|
||||
The <code>Length</code> field corresponds to the length of the packet.
|
||||
This is mostly used for <i>batch mode</i>, where multiple packets are
|
||||
stored in the same buffer.
|
||||
</p><p>
|
||||
The <code>Ethernet.*</code> fields are only valid at the
|
||||
<code>WINDIVERT_LAYER_ETHERNET</code> layer.
|
||||
The <code>Ethernet.IfIdx</code>/<code>Ethernet.SubIfIdx</code> indicate the
|
||||
frame's network adapter (a.k.a. interface) index.
|
||||
</p><p>
|
||||
The <code>Network.*</code> fields are only valid at the
|
||||
<code>WINDIVERT_LAYER_NETWORK</code> and
|
||||
<code>WINDIVERT_LAYER_NETWORK_FORWARD</code> layers.
|
||||
The <code>Network.IfIdx</code>/<code>Network.SubIfIdx</code> indicate the packet's
|
||||
network adapter (a.k.a. interface) index.
|
||||
The <code>Network.IfIdx</code>/<code>Network.SubIfIdx</code> indicate the
|
||||
packet's network adapter (a.k.a. interface) index.
|
||||
These values are ignored for <i>outbound</i> packets.
|
||||
</p><p>
|
||||
The <code>Flow.*</code> fields are only valid at the
|
||||
@@ -807,10 +874,18 @@ the opened handle.
|
||||
Most address fields are ignored by
|
||||
<a href="#divert_send"><code>WinDivertSend()</code></a>.
|
||||
The exceptions are
|
||||
<code>Outbound</code> (for <code>WINDIVERT_LAYER_NETWORK</code> only),
|
||||
<code>Outbound</code> (for
|
||||
<code>WINDIVERT_LAYER_ETHERNET</code>/<code>WINDIVERT_LAYER_NETWORK</code>
|
||||
only),
|
||||
<code>Impostor</code>, <code>IPChecksum</code>, <code>TCPChecksum</code>,
|
||||
<code>UDPChecksum</code>, <code>Network.IfIdx</code> and
|
||||
<code>UDPChecksum</code>, <code>Ethernet.IfIdx</code>,
|
||||
<code>Ethernet.SubIfIdx</code>, <code>Network.IfIdx</code> and
|
||||
<code>Network.SubIfIdx</code>.
|
||||
The <code>Length</code> field is used for <i>batch mode</i> where
|
||||
multiple packets are injected at once.
|
||||
That said, the <code>Length</code> field is ignored for the last packet of the
|
||||
batch, in which case the remaining buffer length determines the
|
||||
injected packet size.
|
||||
</p>
|
||||
</dd></dl>
|
||||
|
||||
@@ -991,11 +1066,18 @@ Description
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>WINDIVERT_LAYER_NETWORK = 0</code>
|
||||
<code>WINDIVERT_LAYER_ETHERNET</code>
|
||||
</td>
|
||||
<td>
|
||||
Ethernet frames to/from the local machine.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>WINDIVERT_LAYER_NETWORK</code>
|
||||
</td>
|
||||
<td>
|
||||
Network packets to/from the local machine.
|
||||
This is the default layer.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -1292,6 +1374,17 @@ Description
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>WINDIVERT_LAYER_ETHERNET</code>
|
||||
</td>
|
||||
<td>
|
||||
✔
|
||||
</td>
|
||||
<td>
|
||||
Ethernet frame.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>WINDIVERT_LAYER_NETWORK</code>
|
||||
</td>
|
||||
<td>
|
||||
@@ -1543,8 +1636,10 @@ modified version, or a completely new packet.
|
||||
Injected packets can be captured and diverted again by other WinDivert
|
||||
handles with lower priorities.
|
||||
</p><p>
|
||||
Only the <code>WINDIVERT_LAYER_NETWORK</code> and
|
||||
<code>WINDIVERT_LAYER_NETWORK_FORWARD</code> <a href="#divert_layers">layers</a>
|
||||
Only the <code>WINDIVERT_LAYER_ETHERMET</code>,
|
||||
<code>WINDIVERT_LAYER_NETWORK</code> and
|
||||
<code>WINDIVERT_LAYER_NETWORK_FORWARD</code>
|
||||
<a href="#divert_layers">layers</a>
|
||||
support packet injection, as summarized below:
|
||||
</p>
|
||||
<center>
|
||||
@@ -1559,6 +1654,14 @@ Inject?
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>WINDIVERT_LAYER_ETHERNET</code>
|
||||
</td>
|
||||
<td>
|
||||
✔
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>WINDIVERT_LAYER_NETWORK</code>
|
||||
</td>
|
||||
<td>
|
||||
@@ -1597,7 +1700,8 @@ Inject?
|
||||
</table>
|
||||
</center>
|
||||
<p>
|
||||
For the <code>WINDIVERT_LAYER_NETWORK</code> layer the
|
||||
For the <code>WINDIVERT_LAYER_ETHERNET</code> and
|
||||
<code>WINDIVERT_LAYER_NETWORK</code> layers, the
|
||||
<code>pAddr->Outbound</code> value determines which direction the packet
|
||||
is injected.
|
||||
If the <code>pAddr->Outbound</code> field is <code>1</code>,
|
||||
@@ -1958,7 +2062,29 @@ The WinDivert helper programming API is a collection of definitions
|
||||
and functions designed to make writing WinDivert applications easier.
|
||||
The use of the helper API is optional.
|
||||
|
||||
<a name="divert_iphdr"><h3>6.1 WINDIVERT_IPHDR</h3></a>
|
||||
<a name="divert_ethhdr"><h3>6.1 WINDIVERT_ETHHDR</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
typedef struct
|
||||
{
|
||||
UINT8 DstAddr[6];
|
||||
UINT8 SrcAddr[6];
|
||||
UINT16 Type;
|
||||
} <b>WINDIVERT_ETHHDR</b>, *<b>PWINDIVERT_ETHHDR</b>;
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
<dl><dd>
|
||||
<p>
|
||||
<b>Fields</b><br>
|
||||
See <a href="https://en.wikipedia.org/wiki/Ethernet_frame#Header">here</a>
|
||||
for more information.
|
||||
</p><p>
|
||||
<b>Remarks</b><br>
|
||||
Ethernet frame header definition.
|
||||
</p>
|
||||
</dl></dd>
|
||||
|
||||
<a name="divert_iphdr"><h3>6.2 WINDIVERT_IPHDR</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
typedef struct
|
||||
@@ -2001,7 +2127,7 @@ definitions:
|
||||
</ul>
|
||||
</dl></dd>
|
||||
|
||||
<a name="divert_ipv6hdr"><h3>6.2 WINDIVERT_IPV6HDR</h3></a>
|
||||
<a name="divert_ipv6hdr"><h3>6.3 WINDIVERT_IPV6HDR</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
typedef struct
|
||||
@@ -2037,7 +2163,7 @@ definitions:
|
||||
</ul>
|
||||
</dl></dd>
|
||||
|
||||
<a name="divert_icmphdr"><h3>6.3 WINDIVERT_ICMPHDR</h3></a>
|
||||
<a name="divert_icmphdr"><h3>6.4 WINDIVERT_ICMPHDR</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
typedef struct
|
||||
@@ -2060,7 +2186,7 @@ ICMP header definition.
|
||||
</p>
|
||||
</dl></dd>
|
||||
|
||||
<a name="divert_icmpv6hdr"><h3>6.4 WINDIVERT_ICMPV6HDR</h3></a>
|
||||
<a name="divert_icmpv6hdr"><h3>6.5 WINDIVERT_ICMPV6HDR</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
typedef struct
|
||||
@@ -2083,7 +2209,7 @@ ICMPv6 header definition.
|
||||
</p>
|
||||
</dl></dd>
|
||||
|
||||
<a name="divert_tcphdr"><h3>6.5 WINDIVERT_TCPHDR</h3></a>
|
||||
<a name="divert_tcphdr"><h3>6.6 WINDIVERT_TCPHDR</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
typedef struct
|
||||
@@ -2118,7 +2244,7 @@ TCP header definition.
|
||||
</p>
|
||||
</dl></dd>
|
||||
|
||||
<a name="divert_udphdr"><h3>6.6 WINDIVERT_UDPHDR</h3></a>
|
||||
<a name="divert_udphdr"><h3>6.7 WINDIVERT_UDPHDR</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
typedef struct
|
||||
@@ -2141,12 +2267,14 @@ UDP header definition.
|
||||
</p>
|
||||
</dl></dd>
|
||||
|
||||
<a name="divert_helper_parse_packet"><h3>6.7 WinDivertHelperParsePacket</h3></a>
|
||||
<a name="divert_helper_parse_packet"><h3>6.8 WinDivertHelperParsePacket</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
BOOL <b>WinDivertHelperParsePacket</b>(
|
||||
__in PVOID pPacket,
|
||||
__in UINT packetLen,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__out_opt PWINDIVERT_ETHHDR *ppEthHdr,
|
||||
__out_opt PWINDIVERT_IPHDR *ppIpHdr,
|
||||
__out_opt PWINDIVERT_IPV6HDR *ppIpv6Hdr,
|
||||
__out_opt UINT8 *pProtocol,
|
||||
@@ -2155,9 +2283,7 @@ BOOL <b>WinDivertHelperParsePacket</b>(
|
||||
__out_opt PWINDIVERT_TCPHDR *ppTcpHdr,
|
||||
__out_opt PWINDIVERT_UDPHDR *ppUdpHdr,
|
||||
__out_opt PVOID *ppData,
|
||||
__out_opt UINT *pDataLen,
|
||||
__out_opt PVOID *ppNext,
|
||||
__out_opt UINT *pNextLen
|
||||
__out_opt UINT *pDataLen
|
||||
);
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
@@ -2166,6 +2292,8 @@ BOOL <b>WinDivertHelperParsePacket</b>(
|
||||
<ul>
|
||||
<li> <code>pPacket</code>: The packet(s) to be parsed.</li>
|
||||
<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>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>
|
||||
@@ -2175,17 +2303,17 @@ BOOL <b>WinDivertHelperParsePacket</b>(
|
||||
<li> <code>ppUdpHdr</code>: Output pointer to a <code>WINDIVERT_UDPHDR</code>.</li>
|
||||
<li> <code>ppData</code>: Output pointer to the packet's data/payload.</li>
|
||||
<li> <code>pDataLen</code>: Output data/payload length.</li>
|
||||
<li> <code>ppNext</code>: Output pointer to the next packet (if present).</li>
|
||||
<li> <code>pNextLen</code>: Output next packet length.</li>
|
||||
</ul>
|
||||
<p>
|
||||
<b>Return Value</b><br>
|
||||
<code>TRUE</code> if successful, <code>FALSE</code> if an error occurred.
|
||||
</p><p>
|
||||
<b>Remarks</b><br>
|
||||
Parses a raw packet or batch of packets (e.g. from <a
|
||||
href="#divert_recv"><code>WinDivertRecv()</code></a>) into the
|
||||
various packet headers and/or payloads that may or may not be present.
|
||||
Parses a raw packet (e.g. from <a
|
||||
href="#divert_recv"><code>WinDivertRecv()</code></a>)
|
||||
from the <code>WINDIVERT_LAYER_ETHERNET</code> or
|
||||
<code>WINDIVERT_LAYER_NETWORK*</code> layers
|
||||
into the various packet headers and/or payloads that may or may not be present.
|
||||
</p><p>
|
||||
Each output parameter may be <code>NULL</code> or non-<code>NULL</code>.
|
||||
For non-<code>NULL</code> parameters, this function will write the pointer to
|
||||
@@ -2194,41 +2322,24 @@ otherwise.
|
||||
Any non-<code>NULL</code> pointer that is returned:
|
||||
</p>
|
||||
<ol>
|
||||
<li> Is a pointer into the original <code>pPacket</code> packet buffer; and</li>
|
||||
<li> Is a pointer into the original <code>pPacket</code> packet buffer
|
||||
(this function does not allocate any memory); and</li>
|
||||
<li> There is enough space in <code>pPacket</code> to fit the header.</li>
|
||||
</ol>
|
||||
<p>
|
||||
This function does not do any verification of the header/payload contents
|
||||
beyond checking the header length and any other minimal information required
|
||||
for parsing.
|
||||
This function will always succeed provided the <code>pPacket</code> buffer
|
||||
contains at least one IPv4 or IPv6 header and the <code>packetLen</code> is
|
||||
correct.
|
||||
</p><p>
|
||||
By default this function will parse a single packet.
|
||||
However, if either <code>ppNext</code> or <code>pNextLen</code> are
|
||||
non-<code>NULL</code>, then the <code>pPacket</code> parameter can point
|
||||
to a batch (>1) of packets
|
||||
(and <code>packetLen</code> can be the total length of the batch).
|
||||
In this case, the function will parse the first packet, and a pointer to the
|
||||
remaining packet(s) will be written to <code>ppNext</code>,
|
||||
and the remaining length will be written to <code>pNextLen</code>.
|
||||
This makes it convenient to loop over every packet in the batch as follows:
|
||||
This function will succeed if at least one header can be parsed.
|
||||
</p>
|
||||
<pre>
|
||||
while (WinDivertHelperParsePacket(pPacket, packetLen, ..., &pPacket, &packetLen))
|
||||
{
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</dd></dl>
|
||||
|
||||
<a name="divert_helper_hash_packet"><h3>6.8 WinDivertHelperHashPacket</h3></a>
|
||||
<a name="divert_helper_hash_packet"><h3>6.9 WinDivertHelperHashPacket</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
UINT64 <b>WinDivertHelperHashPacket</b>(
|
||||
__in const VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__in UINT64 seed = 0
|
||||
);
|
||||
</pre>
|
||||
@@ -2238,6 +2349,7 @@ UINT64 <b>WinDivertHelperHashPacket</b>(
|
||||
<ul>
|
||||
<li> <code>pPacket</code>: The packet to be hashed.</li>
|
||||
<li> <code>packetLen</code>: The total length of the packet <code>pPacket</code>.</li>
|
||||
<li> <code>layer</code>: The layer.</li>
|
||||
<li> <code>seed</code>: An optional seed value.</li>
|
||||
</ul>
|
||||
<p>
|
||||
@@ -2258,7 +2370,37 @@ The optional <code>seed</code> value is also incorporated into the hash.
|
||||
<p>
|
||||
</dd></dl>
|
||||
|
||||
<a name="divert_helper_parse_ipv4_address"><h3>6.9 WinDivertHelperParseIPv4Address</h3></a>
|
||||
<a name="divert_helper_parse_mac_address"><h3>6.10 WinDivertHelperParseMACAddress</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
BOOL <b>WinDivertHelperParseMACAddress</b>(
|
||||
__in const char *addrStr,
|
||||
__out_opt UINT8 *pAddr
|
||||
);
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
<dl><dd>
|
||||
<p><b>Parameters</b></p>
|
||||
<ul>
|
||||
<li> <code>addrStr</code>: The address string.</li>
|
||||
<li> <code>pAddr</code>: Output address.</li>
|
||||
</ul>
|
||||
<p>
|
||||
<b>Return Value</b><br>
|
||||
<code>TRUE</code> if successful, <code>FALSE</code> if an error occurred.
|
||||
Use <code>GetLastError()</code> to get the reason for the error.
|
||||
</p><p>
|
||||
<b>Remarks</b><br>
|
||||
Parses a MAC address stored in <code>addrStr</code>.
|
||||
If <code>pAddr</code> is non-<code>NULL</code>, the result is be stored in
|
||||
host-byte-order.
|
||||
Use
|
||||
<a href="#divert_helper_hton"><code>WinDivertHelperHtonMACAddress()</code></a>
|
||||
to convert the result into network-byte-order.
|
||||
</p>
|
||||
</dd></dl>
|
||||
|
||||
<a name="divert_helper_parse_ipv4_address"><h3>6.11 WinDivertHelperParseIPv4Address</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
BOOL <b>WinDivertHelperParseIPv4Address</b>(
|
||||
@@ -2287,7 +2429,7 @@ to convert the result into network-byte-order.
|
||||
</p>
|
||||
</dd></dl>
|
||||
|
||||
<a name="divert_helper_parse_ipv6_address"><h3>6.10 WinDivertHelperParseIPv6Address</h3></a>
|
||||
<a name="divert_helper_parse_ipv6_address"><h3>6.12 WinDivertHelperParseIPv6Address</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
BOOL <b>WinDivertHelperParseIPv6Address</b>(
|
||||
@@ -2317,7 +2459,34 @@ to convert the result into network-byte-order.
|
||||
</p>
|
||||
</dd></dl>
|
||||
|
||||
<a name="divert_helper_format_ipv4_address"><h3>6.11 WinDivertHelperParseIPv4Address</h3></a>
|
||||
<a name="divert_helper_format_mac_address"><h3>6.13 WinDivertHelperParseMacAddress</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
BOOL <b>WinDivertHelperFormatMacAddress</b>(
|
||||
__in const UINT8 *addr,
|
||||
__out char *buffer,
|
||||
__in UINT bufLen
|
||||
);
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
<dl><dd>
|
||||
<p><b>Parameters</b></p>
|
||||
<ul>
|
||||
<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>
|
||||
<p>
|
||||
<b>Return Value</b><br>
|
||||
<code>TRUE</code> if successful, <code>FALSE</code> if an error occurred.
|
||||
Use <code>GetLastError()</code> to get the reason for the error.
|
||||
</p><p>
|
||||
<b>Remarks</b><br>
|
||||
Convert a Mac address into a string.
|
||||
</p>
|
||||
</dd></dl>
|
||||
|
||||
<a name="divert_helper_format_ipv4_address"><h3>6.14 WinDivertHelperParseIPv4Address</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
BOOL <b>WinDivertHelperFormatIPv4Address</b>(
|
||||
@@ -2344,7 +2513,7 @@ Convert an IPv4 address into a string.
|
||||
</p>
|
||||
</dd></dl>
|
||||
|
||||
<a name="divert_helper_format_ipv6_address"><h3>6.12 WinDivertHelperParseIPv6Address</h3></a>
|
||||
<a name="divert_helper_format_ipv6_address"><h3>6.15 WinDivertHelperParseIPv6Address</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
BOOL <b>WinDivertHelperFormatIPv6Address</b>(
|
||||
@@ -2371,12 +2540,13 @@ Convert an IPv6 address into a string.
|
||||
</p>
|
||||
</dd></dl>
|
||||
|
||||
<a name="divert_helper_calc_checksums"><h3>6.13 WinDivertHelperCalcChecksums</h3></a>
|
||||
<a name="divert_helper_calc_checksums"><h3>6.16 WinDivertHelperCalcChecksums</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
BOOL <b>WinDivertHelperCalcChecksums</b>(
|
||||
__inout VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__out_opt WINDIVERT_ADDRESS *pAddr,
|
||||
__in UINT64 flags
|
||||
);
|
||||
@@ -2387,6 +2557,7 @@ BOOL <b>WinDivertHelperCalcChecksums</b>(
|
||||
<ul>
|
||||
<li> <code>pPacket</code>: The packet to be modified.</li>
|
||||
<li> <code>packetLen</code>: The total length of the packet <code>pPacket</code>.</li>
|
||||
<li> <code>layer</code>: The layer.</li>
|
||||
<li> <code>pAddr</code>: Optional pointer to a
|
||||
<a href="#divert_address"><code>WINDIVERT_ADDRESS</code></a> structure.</li>
|
||||
<li> <code>flags</code>: One or more of the following flags:
|
||||
@@ -2429,12 +2600,13 @@ packet injection.
|
||||
</p>
|
||||
</dd></dl>
|
||||
|
||||
<a name="divert_helper_dec_ttl"><h3>6.14 WinDivertHelperDecrementTTL</h3></a>
|
||||
<a name="divert_helper_dec_ttl"><h3>6.17 WinDivertHelperDecrementTTL</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
BOOL <b>WinDivertHelperDecrementTTL</b>(
|
||||
__inout VOID *packet,
|
||||
__in packetLen
|
||||
__in packetLen,
|
||||
__in WINDIVERT_LAYER layer
|
||||
);
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
@@ -2443,6 +2615,7 @@ BOOL <b>WinDivertHelperDecrementTTL</b>(
|
||||
<ul>
|
||||
<li> <code>pPacket</code>: The packet to be modified.</li>
|
||||
<li> <code>packetLen</code>: The total length of the packet <code>pPacket</code>.</li>
|
||||
<li> <code>layer</code>: The layer.</li>
|
||||
</ul>
|
||||
<p>
|
||||
<b>Return Value</b><br>
|
||||
@@ -2463,7 +2636,7 @@ This function updates the checksum field incrementally.
|
||||
</p>
|
||||
</dd></dl>
|
||||
|
||||
<a name="divert_helper_compile_filter"><h3>6.15 WinDivertHelperCompileFilter</h3></a>
|
||||
<a name="divert_helper_compile_filter"><h3>6.18 WinDivertHelperCompileFilter</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
BOOL <b>WinDivertHelperCompileFilter</b>(
|
||||
@@ -2514,13 +2687,14 @@ objects, and therefore do not need to be deallocated.
|
||||
<p>
|
||||
</dd></dl>
|
||||
|
||||
<a name="divert_helper_eval_filter"><h3>6.16 WinDivertHelperEvalFilter</h3></a>
|
||||
<a name="divert_helper_eval_filter"><h3>6.19 WinDivertHelperEvalFilter</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
BOOL <b>WinDivertHelperEvalFilter</b>(
|
||||
__in const char *filter,
|
||||
__in const VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__in const WINDIVERT_ADDRESS *pAddr
|
||||
);
|
||||
</pre>
|
||||
@@ -2531,6 +2705,7 @@ BOOL <b>WinDivertHelperEvalFilter</b>(
|
||||
<li> <code>filter</code>: The packet filter string to be evaluated.</li>
|
||||
<li> <code>pPacket</code>: The packet.</li>
|
||||
<li> <code>packetLen</code>: The total length of the packet <code>pPacket</code>.</li>
|
||||
<li> <code>layer</code>: The layer.</li>
|
||||
<li> <code>pAddr</code>: The <code>WINDIVERT_ADDRESS</code> of the packet
|
||||
<code>pPacket</code>.</li>
|
||||
</ul>
|
||||
@@ -2558,10 +2733,10 @@ function.
|
||||
<p>
|
||||
</dd></dl>
|
||||
|
||||
<a name="divert_helper_format_filter"><h3>6.17 WinDivertHelperFormatFilter</h3></a>
|
||||
<a name="divert_helper_format_filter"><h3>6.20 WinDivertHelperFormatFilter</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
BOOL <b>WinDivertHelperEvalFilter</b>(
|
||||
BOOL <b>WinDivertHelperFormatFilter</b>(
|
||||
__in const char *filter,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__out char *buffer,
|
||||
@@ -2592,7 +2767,7 @@ returned by <a href="#divert_recv"><code>WinDivertRecv()</code></a>.
|
||||
</p>
|
||||
</dd></dl>
|
||||
|
||||
<a name="divert_helper_ntoh"><h3>6.18 WinDivertHelperNtoh*</h3></a>
|
||||
<a name="divert_helper_ntoh"><h3>6.21 WinDivertHelperNtoh*</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
UINT16 <b>WinDivertHelperNtohs</b>(
|
||||
@@ -2604,6 +2779,9 @@ UINT32 <b>WinDivertHelperNtohl</b>(
|
||||
UINT64 <b>WinDivertHelperNtohll</b>(
|
||||
__in UINT64 x
|
||||
);
|
||||
void <b>WinDivertHelperNtohMACAddress</b>(
|
||||
__in const UINT8 *inAddr,
|
||||
__out UINT8 *outAddr);
|
||||
void <b>WinDivertHelperNtohIPv6Address</b>(
|
||||
__in const UINT *inAddr,
|
||||
__out UINT *outAddr
|
||||
@@ -2614,8 +2792,8 @@ void <b>WinDivertHelperNtohIPv6Address</b>(
|
||||
<p><b>Parameters</b></p>
|
||||
<ul>
|
||||
<li> <code>x</code>: The input value in network byte-order.</li>
|
||||
<li> <code>inAddr</code>: The input IPv6 address in network byte-order.</li>
|
||||
<li> <code>outAddr</code>: A buffer for the output IPv6 address in host
|
||||
<li> <code>inAddr</code>: The input MAC/IPv6 address in network byte-order.</li>
|
||||
<li> <code>outAddr</code>: A buffer for the output MAC/IPv6 address in host
|
||||
byte-order.</li>
|
||||
</ul>
|
||||
<p>
|
||||
@@ -2627,7 +2805,7 @@ Converts a value/IPv6-address from network to host byte-order.
|
||||
</p>
|
||||
</dd></dl>
|
||||
|
||||
<a name="divert_helper_hton"><h3>6.19 WinDivertHelperHton*</h3></a>
|
||||
<a name="divert_helper_hton"><h3>6.22 WinDivertHelperHton*</h3></a>
|
||||
<table border="1" cellpadding="5"><tr><td>
|
||||
<pre>
|
||||
UINT16 <b>WinDivertHelperHtons</b>(
|
||||
@@ -2639,6 +2817,9 @@ UINT32 <b>WinDivertHelperHtonl</b>(
|
||||
UINT64 <b>WinDivertHelperHtonll</b>(
|
||||
__in UINT64 x
|
||||
);
|
||||
void <b>WinDivertHelperHtonMACAddress</b>(
|
||||
__in const UINT8 *inAddr,
|
||||
__out UINT8 *outAddr);
|
||||
void <b>WinDivertHelperHtonIPv6Address</b>(
|
||||
__in const UINT *inAddr,
|
||||
__out UINT *outAddr
|
||||
@@ -2649,8 +2830,8 @@ void <b>WinDivertHelperHtonIPv6Address</b>(
|
||||
<p><b>Parameters</b></p>
|
||||
<ul>
|
||||
<li> <code>x</code>: The input value in host byte-order.</li>
|
||||
<li> <code>inAddr</code>: The input IPv6 address in host byte-order.</li>
|
||||
<li> <code>outAddr</code>: A buffer for the output IPv6 address in network
|
||||
<li> <code>inAddr</code>: The input MAC/IPv6 address in host byte-order.</li>
|
||||
<li> <code>outAddr</code>: A buffer for the output MAC/IPv6 address in network
|
||||
byte-order.</li>
|
||||
</ul>
|
||||
<p>
|
||||
@@ -2681,7 +2862,7 @@ This could be achieved using the following filter.
|
||||
HANDLE handle = WinDivertOpen(
|
||||
"outbound and "
|
||||
"tcp.PayloadLength > 0 and "
|
||||
"tcp.DstPort == 80", 0, 0, 0);
|
||||
"tcp.DstPort == 80", WINDIVERT_LAYER_NETWORK, 0, 0);
|
||||
</pre>
|
||||
<p>
|
||||
This filter selects only the subset of all traffic that is:
|
||||
@@ -2740,55 +2921,56 @@ The possible fields are:
|
||||
</p>
|
||||
<center>
|
||||
<table border="1" cellpadding="5">
|
||||
<tr><th>Field</th><th colspan="5">Layer</th><th>Description</th></tr>
|
||||
<tr><th></th><th><code>NETWORK</code></th><th><code>FORWARD</code></th><th><code>FLOW </code></th><th><code>SOCKET </code></th><th><code>REFLECT</code></th><th></th></tr>
|
||||
<tr><td><code>zero</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>The value zero</td></tr>
|
||||
<tr><td><code>timestamp</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>The packet/event timestamp</td></tr>
|
||||
<tr><td><code>event</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>The event</td></tr>
|
||||
<tr><td><code>outbound</code></td><td>✔</td><td></td><td>✔</td><td></td><td></td><td>Is outbound?</td></tr>
|
||||
<tr><td><code>inbound</code></td><td>✔</td><td></td><td>✔</td><td></td><td></td><td>Is inbound?</td></tr>
|
||||
<tr><td><code>ifIdx</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>Interface index</td></tr>
|
||||
<tr><td><code>subIfIdx</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>Sub-interface index</td></tr>
|
||||
<tr><td><code>loopback</code></td><td>✔</td><td></td><td>✔</td><td>✔</td><td></td><td>Is loopback packet?</td></tr>
|
||||
<tr><td><code>impostor</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>Is impostor packet?</td></tr>
|
||||
<tr><td><code>fragment</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>Is IP fragment packet?</td></tr>
|
||||
<tr><td><code>endpointId</code></td><td></td><td></td><td>✔</td><td>✔</td><td></td><td>Endpoint ID</td></tr>
|
||||
<tr><td><code>parentEndpointId</code></td><td></td><td></td><td>✔</td><td>✔</td><td></td><td>Parent endpoint ID</td></tr>
|
||||
<tr><td><code>processId</code></td><td></td><td></td><td>✔</td><td>✔</td><td>✔</td><td>Process ID</td></tr>
|
||||
<tr><td><code>random8</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>8-bit random number</td></tr>
|
||||
<tr><td><code>random16</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>16-bit random number</td></tr>
|
||||
<tr><td><code>random32</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>32-bit random number</td></tr>
|
||||
<tr><td><code>layer</code></td><td></td><td></td><td></td><td></td><td>✔</td><td>The handle's layer</td></tr>
|
||||
<tr><td><code>priority</code></td><td></td><td></td><td></td><td></td><td>✔</td><td>The handle's priority</td></tr>
|
||||
<tr><td><code>packet[i]</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The <code>i</code><sup>th</sup> 8-bit word of the packet</td></tr>
|
||||
<tr><td><code>packet16[i]</code></td><td>✔</td><td>✔</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>✔</td><td>✔</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>✔</td><td>✔</td><td></td><td></td><td></td><td>The packet length</td></tr>
|
||||
<tr><td><code>ip</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td></td><td>Is IPv4?</td></tr>
|
||||
<tr><td><code>ipv6</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td></td><td>Is IPv6?</td></tr>
|
||||
<tr><td><code>icmp</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td></td><td>Is ICMP?</td></tr>
|
||||
<tr><td><code>icmpv6</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td></td><td>Is ICMPv6?</td></tr>
|
||||
<tr><td><code>tcp</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td></td><td>Is TCP?</td></tr>
|
||||
<tr><td><code>udp</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td></td><td>Is UDP?</td></tr>
|
||||
<tr><td><code>protocol</code></td><td>✔</td><td></td><td>✔</td><td>✔</td><td></td><td>The protocol</td></tr>
|
||||
<tr><td><code>localAddr</code></td><td>✔</td><td></td><td>✔</td><td>✔</td><td></td><td>The local address</td></tr>
|
||||
<tr><td><code>localPort</code></td><td>✔</td><td></td><td>✔</td><td>✔</td><td></td><td>The local port</td></tr>
|
||||
<tr><td><code>remoteAddr</code></td><td>✔</td><td></td><td>✔</td><td>✔</td><td></td><td>The remote address</td></tr>
|
||||
<tr><td><code>remotePort</code></td><td>✔</td><td></td><td>✔</td><td>✔</td><td></td><td>The remote port</td></tr>
|
||||
<tr><td><code>ip.*</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>IPv4 fields (see <code>WINDIVERT_IPHDR</code>)</td></tr>
|
||||
<tr><td><code>ipv6.*</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>IPv6 fields (see <code>WINDIVERT_IPV6HDR</code>)</td></tr>
|
||||
<tr><td><code>icmp.*</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>ICMP fields (see <code>WINDIVERT_ICMPHDR</code>)</td></tr>
|
||||
<tr><td><code>icmpv6.*</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>ICMPV6 fields (see <code>WINDIVERT_ICMPV6HDR</code>)</td></tr>
|
||||
<tr><td><code>tcp.*</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>TCP fields (see <code>WINDIVERT_TCPHDR</code>)</td></tr>
|
||||
<tr><td><code>tcp.PayloadLength</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The TCP payload length</td></tr>
|
||||
<tr><td><code>tcp.Payload[i]</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The <code>i</code><sup>th</sup> 8-bit word of the TCP payload</td></tr>
|
||||
<tr><td><code>tcp.Payload16[i]</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The <code>i</code><sup>th</sup> 16-bit word of the TCP payload</td></tr>
|
||||
<tr><td><code>tcp.Payload32[i]</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The <code>i</code><sup>th</sup> 32-bit word of the TCP payload</td></tr>
|
||||
<tr><td><code>udp.*</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>UDP fields (see <code>WINDIVERT_UDPHDR</code>)</td></tr>
|
||||
<tr><td><code>udp.PayloadLength</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The UDP payload length</td></tr>
|
||||
<tr><td><code>udp.Payload[i]</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The <code>i</code><sup>th</sup> 8-bit word of the UDP payload</td></tr>
|
||||
<tr><td><code>udp.Payload16[i]</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The <code>i</code><sup>th</sup> 16-bit word of the UDP payload</td></tr>
|
||||
<tr><td><code>udp.Payload32[i]</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The <code>i</code><sup>th</sup> 32-bit word of the UDP payload</td></tr>
|
||||
<tr><th>Field</th><th colspan="6">Layer</th><th>Description</th></tr>
|
||||
<tr><th></th><th><code>ETHERNET</code></th><th><code>NETWORK</code></th><th><code>FORWARD</code></th><th><code>FLOW </code></th><th><code>SOCKET </code></th><th><code>REFLECT</code></th><th></th></tr>
|
||||
<tr><td><code>zero</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>The value zero</td></tr>
|
||||
<tr><td><code>timestamp</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>The packet/event timestamp</td></tr>
|
||||
<tr><td><code>event</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>The event</td></tr>
|
||||
<tr><td><code>outbound</code></td><td>✔</td><td>✔</td><td></td><td>✔</td><td></td><td></td><td>Is outbound?</td></tr>
|
||||
<tr><td><code>inbound</code></td><td>✔</td><td>✔</td><td></td><td>✔</td><td></td><td></td><td>Is inbound?</td></tr>
|
||||
<tr><td><code>ifIdx</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>Interface index</td></tr>
|
||||
<tr><td><code>subIfIdx</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>Sub-interface index</td></tr>
|
||||
<tr><td><code>loopback</code></td><td></td><td>✔</td><td></td><td>✔</td><td>✔</td><td></td><td>Is loopback packet?</td></tr>
|
||||
<tr><td><code>impostor</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>Is impostor packet?</td></tr>
|
||||
<tr><td><code>fragment</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>Is IP fragment packet?</td></tr>
|
||||
<tr><td><code>endpointId</code></td><td></td><td></td><td></td><td>✔</td><td>✔</td><td></td><td>Endpoint ID</td></tr>
|
||||
<tr><td><code>parentEndpointId</code></td><td></td><td></td><td></td><td>✔</td><td>✔</td><td></td><td>Parent endpoint ID</td></tr>
|
||||
<tr><td><code>processId</code></td><td></td><td></td><td></td><td>✔</td><td>✔</td><td>✔</td><td>Process ID</td></tr>
|
||||
<tr><td><code>random8</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>8-bit random number</td></tr>
|
||||
<tr><td><code>random16</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>16-bit random number</td></tr>
|
||||
<tr><td><code>random32</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>32-bit random number</td></tr>
|
||||
<tr><td><code>layer</code></td><td></td><td></td><td></td><td></td><td></td><td>✔</td><td>The handle's layer</td></tr>
|
||||
<tr><td><code>priority</code></td><td></td><td></td><td></td><td></td><td></td><td>✔</td><td>The handle's priority</td></tr>
|
||||
<tr><td><code>packet[i]</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The <code>i</code><sup>th</sup> 8-bit word of the packet</td></tr>
|
||||
<tr><td><code>packet16[i]</code></td><td>✔</td><td>✔</td><td>✔</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>✔</td><td>✔</td><td>✔</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>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The packet length</td></tr>
|
||||
<tr><td><code>ip</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td></td><td>Is IPv4?</td></tr>
|
||||
<tr><td><code>ipv6</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td></td><td>Is IPv6?</td></tr>
|
||||
<tr><td><code>icmp</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td></td><td>Is ICMP?</td></tr>
|
||||
<tr><td><code>icmpv6</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td></td><td>Is ICMPv6?</td></tr>
|
||||
<tr><td><code>tcp</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td></td><td>Is TCP?</td></tr>
|
||||
<tr><td><code>udp</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td></td><td>Is UDP?</td></tr>
|
||||
<tr><td><code>protocol</code></td><td>✔</td><td>✔</td><td></td><td>✔</td><td>✔</td><td></td><td>The protocol</td></tr>
|
||||
<tr><td><code>localAddr</code></td><td>✔</td><td>✔</td><td></td><td>✔</td><td>✔</td><td></td><td>The local address</td></tr>
|
||||
<tr><td><code>localPort</code></td><td>✔</td><td>✔</td><td></td><td>✔</td><td>✔</td><td></td><td>The local port</td></tr>
|
||||
<tr><td><code>remoteAddr</code></td><td>✔</td><td>✔</td><td></td><td>✔</td><td>✔</td><td></td><td>The remote address</td></tr>
|
||||
<tr><td><code>remotePort</code></td><td>✔</td><td>✔</td><td></td><td>✔</td><td>✔</td><td></td><td>The remote port</td></tr>
|
||||
<tr><td><code>eth.*</code></td><td>✔</td><td></td><td></td><td></td><td></td><td></td><td>Ethernet fields (see <code>WINDIVERT_ETHHDR</code>)</td></tr>
|
||||
<tr><td><code>ip.*</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>IPv4 fields (see <code>WINDIVERT_IPHDR</code>)</td></tr>
|
||||
<tr><td><code>ipv6.*</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>IPv6 fields (see <code>WINDIVERT_IPV6HDR</code>)</td></tr>
|
||||
<tr><td><code>icmp.*</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>ICMP fields (see <code>WINDIVERT_ICMPHDR</code>)</td></tr>
|
||||
<tr><td><code>icmpv6.*</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>ICMPV6 fields (see <code>WINDIVERT_ICMPV6HDR</code>)</td></tr>
|
||||
<tr><td><code>tcp.*</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>TCP fields (see <code>WINDIVERT_TCPHDR</code>)</td></tr>
|
||||
<tr><td><code>tcp.PayloadLength</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The TCP payload length</td></tr>
|
||||
<tr><td><code>tcp.Payload[i]</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The <code>i</code><sup>th</sup> 8-bit word of the TCP payload</td></tr>
|
||||
<tr><td><code>tcp.Payload16[i]</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The <code>i</code><sup>th</sup> 16-bit word of the TCP payload</td></tr>
|
||||
<tr><td><code>tcp.Payload32[i]</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The <code>i</code><sup>th</sup> 32-bit word of the TCP payload</td></tr>
|
||||
<tr><td><code>udp.*</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>UDP fields (see <code>WINDIVERT_UDPHDR</code>)</td></tr>
|
||||
<tr><td><code>udp.PayloadLength</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The UDP payload length</td></tr>
|
||||
<tr><td><code>udp.Payload[i]</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The <code>i</code><sup>th</sup> 8-bit word of the UDP payload</td></tr>
|
||||
<tr><td><code>udp.Payload16[i]</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The <code>i</code><sup>th</sup> 16-bit word of the UDP payload</td></tr>
|
||||
<tr><td><code>udp.Payload32[i]</code></td><td>✔</td><td>✔</td><td>✔</td><td></td><td></td><td></td><td>The <code>i</code><sup>th</sup> 32-bit word of the UDP payload</td></tr>
|
||||
</table>
|
||||
</center>
|
||||
<p>
|
||||
@@ -2799,6 +2981,7 @@ packet does not contain a TCP header.
|
||||
The <code>processId</code> field matches the ID of the process associated
|
||||
to an event.
|
||||
Due to technical limitations, this field is not supported by the
|
||||
<code>WINDIVERT_LAYER_ETHERNET</code> and
|
||||
<code>WINDIVERT_LAYER_NETWORK*</code> layers.
|
||||
That said, it is usually possible to associate process IDs to network packets
|
||||
matching the same network 5-tuple.
|
||||
@@ -2843,31 +3026,33 @@ The possible macros are:
|
||||
</p>
|
||||
<center>
|
||||
<table border="1" cellpadding="5" width="75%">
|
||||
<tr><th>Macro</th><th colspan="5">Layer</th><th>Value</th></tr>
|
||||
<tr><th></th><th><code>NETWORK</code></th><th><code>FORWARD</code></th><th><code>FLOW </code></th><th><code>SOCKET </code></th><th><code>REFLECT</code></th><th></th></tr>
|
||||
<tr><td><code>TRUE</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td><code>1</code></td></tr>
|
||||
<tr><td><code>FALSE</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td><code>0</code></td></tr>
|
||||
<tr><td><code>TCP</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td><code>IPPROTO_TCP</code> (<code>6</code>)</td></tr>
|
||||
<tr><td><code>UDP</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td><code>IPPROTO_UDP</code> (<code>17</code>)</td></tr>
|
||||
<tr><td><code>ICMP</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td><code>IPPROTO_ICMP</code> (<code>1</code>)</td></tr>
|
||||
<tr><td><code>ICMPV6</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td><code>IPPROTO_ICMPV6</code> (<code>58</code>)</td></tr>
|
||||
<tr><td><code>PACKET</code></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td><code>WINDIVERT_EVENT_NETWORK_PACKET</code></td></tr>
|
||||
<tr><td><code>ESTABLISHED</code></td><td></td><td></td><td>✔</td><td></td><td></td><td><code>WINDIVERT_EVENT_FLOW_ESTABLISHED</code></td></tr>
|
||||
<tr><td><code>DELETED</code></td><td></td><td></td><td>✔</td><td></td><td></td><td><code>WINDIVERT_EVENT_FLOW_DELETED</code></td></tr>
|
||||
<tr><td><code>BIND</code></td><td></td><td></td><td></td><td>✔</td><td></td><td><code>WINDIVERT_EVENT_SOCKET_BIND</code></td></tr>
|
||||
<tr><td><code>CONNECT</code></td><td></td><td></td><td></td><td>✔</td><td></td><td><code>WINDIVERT_EVENT_SOCKET_CONNECT</code></td></tr>
|
||||
<tr><td><code>ACCEPT</code></td><td></td><td></td><td></td><td>✔</td><td></td><td><code>WINDIVERT_EVENT_SOCKET_ACCEPT</code></td></tr>
|
||||
<tr><td><code>LISTEN</code></td><td></td><td></td><td></td><td>✔</td><td></td><td><code>WINDIVERT_EVENT_SOCKET_LISTEN</code></td></tr>
|
||||
<tr><td><code>OPEN</code></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_EVENT_REFLECT_OPEN</code></td></tr>
|
||||
<tr><td><code>CLOSE</code></td><td></td><td></td><td></td><td>✔</td><td>✔</td><td><code>WINDIVERT_EVENT_SOCKET_CLOSE</code>
|
||||
<tr><th>Macro</th><th colspan="6">Layer</th><th>Value</th></tr>
|
||||
<tr><th></th><th><code>ETHERNET</code></th><th><code>NETWORK</code></th><th><code>FORWARD</code></th><th><code>FLOW </code></th><th><code>SOCKET </code></th><th><code>REFLECT</code></th><th></th></tr>
|
||||
<tr><td><code>TRUE</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td><code>1</code></td></tr>
|
||||
<tr><td><code>FALSE</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td><code>0</code></td></tr>
|
||||
<tr><td><code>TCP</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td><code>IPPROTO_TCP</code> (<code>6</code>)</td></tr>
|
||||
<tr><td><code>UDP</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td><code>IPPROTO_UDP</code> (<code>17</code>)</td></tr>
|
||||
<tr><td><code>ICMP</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td><code>IPPROTO_ICMP</code> (<code>1</code>)</td></tr>
|
||||
<tr><td><code>ICMPV6</code></td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td>✔</td><td><code>IPPROTO_ICMPV6</code> (<code>58</code>)</td></tr>
|
||||
<tr><td><code>FRAME</code></td><td>✔</td><td></td><td></td><td></td><td></td><td></td><td><code>WINDIVERT_EVENT_ETHERNET_FRAME</code></td></tr>
|
||||
<tr><td><code>PACKET</code></td><td></td><td>✔</td><td>✔</td><td></td><td></td><td></td><td><code>WINDIVERT_EVENT_NETWORK_PACKET</code></td></tr>
|
||||
<tr><td><code>ESTABLISHED</code></td><td></td><td></td><td></td><td>✔</td><td></td><td></td><td><code>WINDIVERT_EVENT_FLOW_ESTABLISHED</code></td></tr>
|
||||
<tr><td><code>DELETED</code></td><td></td><td></td><td></td><td>✔</td><td></td><td></td><td><code>WINDIVERT_EVENT_FLOW_DELETED</code></td></tr>
|
||||
<tr><td><code>BIND</code></td><td></td><td></td><td></td><td></td><td>✔</td><td></td><td><code>WINDIVERT_EVENT_SOCKET_BIND</code></td></tr>
|
||||
<tr><td><code>CONNECT</code></td><td></td><td></td><td></td><td></td><td>✔</td><td></td><td><code>WINDIVERT_EVENT_SOCKET_CONNECT</code></td></tr>
|
||||
<tr><td><code>ACCEPT</code></td><td></td><td></td><td></td><td></td><td>✔</td><td></td><td><code>WINDIVERT_EVENT_SOCKET_ACCEPT</code></td></tr>
|
||||
<tr><td><code>LISTEN</code></td><td></td><td></td><td></td><td></td><td>✔</td><td></td><td><code>WINDIVERT_EVENT_SOCKET_LISTEN</code></td></tr>
|
||||
<tr><td><code>OPEN</code></td><td></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_EVENT_REFLECT_OPEN</code></td></tr>
|
||||
<tr><td><code>CLOSE</code></td><td></td><td></td><td></td><td></td><td>✔</td><td>✔</td><td><code>WINDIVERT_EVENT_SOCKET_CLOSE</code>
|
||||
for the <code>SOCKET</code> layer, or
|
||||
<code>WINDIVERT_EVENT_REFLECT_CLOSE</code> for the <code>REFLECT</code>
|
||||
layer.</td></tr>
|
||||
<tr><td><code>NETWORK</code></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_LAYER_NETWORK</code></td></tr>
|
||||
<tr><td><code>NETWORK_FORWARD</code></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_LAYER_NETWORK_FORWARD</code></td></tr>
|
||||
<tr><td><code>FLOW</code></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_LAYER_FLOW</code></td></tr>
|
||||
<tr><td><code>SOCKET</code></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_LAYER_SOCKET</code></td></tr>
|
||||
<tr><td><code>REFLECT</code></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_LAYER_REFLECT</code></td></tr>
|
||||
<tr><td><code>ETHERNET</code></td><td></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_LAYER_ETHERNET</code></td></tr>
|
||||
<tr><td><code>NETWORK</code></td><td></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_LAYER_NETWORK</code></td></tr>
|
||||
<tr><td><code>NETWORK_FORWARD</code></td><td></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_LAYER_NETWORK_FORWARD</code></td></tr>
|
||||
<tr><td><code>FLOW</code></td><td></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_LAYER_FLOW</code></td></tr>
|
||||
<tr><td><code>SOCKET</code></td><td></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_LAYER_SOCKET</code></td></tr>
|
||||
<tr><td><code>REFLECT</code></td><td></td><td></td><td></td><td></td><td></td><td>✔</td><td><code>WINDIVERT_LAYER_REFLECT</code></td></tr>
|
||||
</table>
|
||||
</center>
|
||||
|
||||
@@ -2880,7 +3065,7 @@ Divert all outbound (non-local) web traffic:
|
||||
HANDLE handle = WinDivertOpen(
|
||||
"outbound and !loopback and "
|
||||
"(tcp.DstPort == 80 or udp.DstPort == 53)",
|
||||
0, 0, 0
|
||||
WINDIVERT_LAYER_NETWORK, 0, 0
|
||||
);
|
||||
</pre>
|
||||
</li>
|
||||
@@ -2890,20 +3075,20 @@ Divert all inbound TCP SYNs:
|
||||
HANDLE handle = WinDivertOpen(
|
||||
"inbound and "
|
||||
"tcp.Syn",
|
||||
0, 0, 0
|
||||
WINDIVERT_LAYER_NETWORK, 0, 0
|
||||
);
|
||||
</pre>
|
||||
</li>
|
||||
<li>
|
||||
Divert all traffic:
|
||||
<pre>
|
||||
HANDLE handle = WinDivertOpen("true", 0, 0, 0);
|
||||
HANDLE handle = WinDivertOpen("true", WINDIVERT_LAYER_NETWORK, 0, 0);
|
||||
</pre>
|
||||
</li>
|
||||
<li>
|
||||
Divert no traffic:
|
||||
<pre>
|
||||
HANDLE handle = WinDivertOpen("false", 0, 0, 0);
|
||||
HANDLE handle = WinDivertOpen("false", WINDIVERT_LAYER_NETWORK, 0, 0);
|
||||
</pre>
|
||||
This is useful for packet injection.
|
||||
</ol>
|
||||
|
||||
+66
-22
@@ -37,7 +37,7 @@
|
||||
* This is a simple traffic monitor. It uses a WinDivert handle in SNIFF mode.
|
||||
* The SNIFF mode copies packets and does not block the original.
|
||||
*
|
||||
* usage: netdump.exe windivert-filter [priority]
|
||||
* usage: netdump.exe windivert-filter [priority] [layer]
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -60,17 +60,21 @@
|
||||
int __cdecl main(int argc, char **argv)
|
||||
{
|
||||
HANDLE handle, console;
|
||||
DWORD err;
|
||||
UINT i;
|
||||
WINDIVERT_LAYER layer = WINDIVERT_LAYER_NETWORK;
|
||||
INT16 priority = 0;
|
||||
unsigned char packet[MAXBUF];
|
||||
UINT packet_len;
|
||||
WINDIVERT_ADDRESS addr;
|
||||
PWINDIVERT_ETHHDR eth_header;
|
||||
PWINDIVERT_IPHDR ip_header;
|
||||
PWINDIVERT_IPV6HDR ipv6_header;
|
||||
PWINDIVERT_ICMPHDR icmp_header;
|
||||
PWINDIVERT_ICMPV6HDR icmpv6_header;
|
||||
PWINDIVERT_TCPHDR tcp_header;
|
||||
PWINDIVERT_UDPHDR udp_header;
|
||||
UINT8 src_mac[6], dst_mac[6];
|
||||
UINT32 src_addr[4], dst_addr[4];
|
||||
UINT64 hash;
|
||||
char src_str[INET6_ADDRSTRLEN+1], dst_str[INET6_ADDRSTRLEN+1];
|
||||
@@ -81,19 +85,44 @@ int __cdecl main(int argc, char **argv)
|
||||
// Check arguments.
|
||||
switch (argc)
|
||||
{
|
||||
case 2:
|
||||
break;
|
||||
case 4:
|
||||
if (strcmp(argv[3], "network") == 0)
|
||||
{
|
||||
layer = WINDIVERT_LAYER_NETWORK;
|
||||
}
|
||||
else if (strcmp(argv[3], "forward") == 0)
|
||||
{
|
||||
layer = WINDIVERT_LAYER_NETWORK_FORWARD;
|
||||
}
|
||||
else if (strcmp(argv[3], "ethernet") == 0)
|
||||
{
|
||||
layer = WINDIVERT_LAYER_ETHERNET;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto usage;
|
||||
}
|
||||
// Fallthrough
|
||||
case 3:
|
||||
priority = (INT16)atoi(argv[2]);
|
||||
// Fallthrough
|
||||
case 2:
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "usage: %s windivert-filter [priority]\n",
|
||||
usage:
|
||||
fprintf(stderr, "usage: %s windivert-filter [priority] [layer]\n\n",
|
||||
argv[0]);
|
||||
fprintf(stderr, "where:\n");
|
||||
fprintf(stderr, "\t- priority is an integer between "
|
||||
"-30000..30000 (default = %d)\n", (int)priority);
|
||||
fprintf(stderr, "\t- layer is one of ethernet/network/forward "
|
||||
"(default = network)\n\n");
|
||||
fprintf(stderr, "examples:\n");
|
||||
fprintf(stderr, "\t%s true\n", argv[0]);
|
||||
fprintf(stderr, "\t%s \"outbound and tcp.DstPort == 80\" 1000\n",
|
||||
fprintf(stderr, "\t%s \"outbound and tcp.DstPort == 80\" 1000 "
|
||||
"network\n", argv[0]);
|
||||
fprintf(stderr, "\t%s \"inbound and tcp.Syn\" -400 ethernet\n",
|
||||
argv[0]);
|
||||
fprintf(stderr, "\t%s \"inbound and tcp.Syn\" -400\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -101,11 +130,11 @@ int __cdecl main(int argc, char **argv)
|
||||
console = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
// Divert traffic matching the filter:
|
||||
handle = WinDivertOpen(argv[1], WINDIVERT_LAYER_NETWORK, priority,
|
||||
WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_FRAGMENTS);
|
||||
handle = WinDivertOpen(argv[1], layer, priority, WINDIVERT_FLAG_SNIFF);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetLastError() == ERROR_INVALID_PARAMETER &&
|
||||
err = GetLastError();
|
||||
if (err == ERROR_INVALID_PARAMETER &&
|
||||
!WinDivertHelperCompileFilter(argv[1], WINDIVERT_LAYER_NETWORK,
|
||||
NULL, 0, &err_str, NULL))
|
||||
{
|
||||
@@ -113,7 +142,7 @@ int __cdecl main(int argc, char **argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(stderr, "error: failed to open the WinDivert device (%d)\n",
|
||||
GetLastError());
|
||||
err);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -156,24 +185,39 @@ int __cdecl main(int argc, char **argv)
|
||||
}
|
||||
|
||||
// Print info about the matching packet.
|
||||
WinDivertHelperParsePacket(packet, packet_len, &ip_header, &ipv6_header,
|
||||
NULL, &icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL,
|
||||
NULL, NULL, NULL);
|
||||
if (ip_header == NULL && ipv6_header == NULL)
|
||||
{
|
||||
fprintf(stderr, "warning: junk packet\n");
|
||||
}
|
||||
WinDivertHelperParsePacket(packet, packet_len, addr.Layer,
|
||||
ð_header, &ip_header, &ipv6_header, NULL, &icmp_header,
|
||||
&icmpv6_header, &tcp_header, &udp_header, NULL, NULL);
|
||||
|
||||
// Dump packet info:
|
||||
putchar('\n');
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED);
|
||||
time_passed = (double)(addr.Timestamp - base.QuadPart) /
|
||||
(double)freq.QuadPart;
|
||||
hash = WinDivertHelperHashPacket(packet, packet_len, 0);
|
||||
printf("Packet [Timestamp=%.8g, Direction=%s IfIdx=%u SubIfIdx=%u "
|
||||
"Loopback=%u Hash=0x%.16llX]\n",
|
||||
time_passed, (addr.Outbound? "outbound": "inbound"),
|
||||
addr.Network.IfIdx, addr.Network.SubIfIdx, addr.Loopback, hash);
|
||||
hash = WinDivertHelperHashPacket(packet, packet_len, addr.Layer, 0);
|
||||
if (eth_header != NULL)
|
||||
{
|
||||
printf("Packet [Timestamp=%.8g Length=%u Direction=%s IfIdx=%u "
|
||||
"SubIfIdx=%u Hash=0x%.16llX]\n",
|
||||
time_passed, packet_len, (addr.Outbound? "outbound": "inbound"),
|
||||
addr.Ethernet.IfIdx, addr.Ethernet.SubIfIdx, hash);
|
||||
WinDivertHelperNtohMACAddress(eth_header->SrcAddr, src_mac);
|
||||
WinDivertHelperNtohMACAddress(eth_header->DstAddr, dst_mac);
|
||||
WinDivertHelperFormatMACAddress(src_mac, src_str, sizeof(src_str));
|
||||
WinDivertHelperFormatMACAddress(dst_mac, dst_str, sizeof(dst_str));
|
||||
SetConsoleTextAttribute(console,
|
||||
FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
printf("Ethernet [SrcAddr=%s DstAddr=%s Type=0x%.4X]\n",
|
||||
src_str, dst_str, ntohs(eth_header->Type));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Packet [Timestamp=%.8g Length=%u Direction=%s IfIdx=%u "
|
||||
"SubIfIdx=%u Loopback=%u Hash=0x%.16llX]\n",
|
||||
time_passed, packet_len, (addr.Outbound? "outbound": "inbound"),
|
||||
addr.Network.IfIdx, addr.Network.SubIfIdx, addr.Loopback,
|
||||
hash);
|
||||
}
|
||||
if (ip_header != NULL)
|
||||
{
|
||||
WinDivertHelperFormatIPv4Address(ntohl(ip_header->SrcAddr),
|
||||
|
||||
@@ -201,9 +201,9 @@ int __cdecl main(int argc, char **argv)
|
||||
}
|
||||
|
||||
// Print info about the matching packet.
|
||||
WinDivertHelperParsePacket(packet, packet_len, &ip_header, &ipv6_header,
|
||||
NULL, &icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL,
|
||||
&payload_len, NULL, NULL);
|
||||
WinDivertHelperParsePacket(packet, packet_len, recv_addr.Layer, NULL,
|
||||
&ip_header, &ipv6_header, NULL, &icmp_header, &icmpv6_header,
|
||||
&tcp_header, &udp_header, NULL, &payload_len);
|
||||
if (ip_header == NULL && ipv6_header == NULL)
|
||||
{
|
||||
continue;
|
||||
@@ -290,7 +290,7 @@ int __cdecl main(int argc, char **argv)
|
||||
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
|
||||
send_addr.Outbound = !recv_addr.Outbound;
|
||||
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(TCPPACKET),
|
||||
&send_addr, 0);
|
||||
WINDIVERT_LAYER_NETWORK, &send_addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)reset, sizeof(TCPPACKET),
|
||||
NULL, &send_addr))
|
||||
{
|
||||
@@ -317,7 +317,8 @@ int __cdecl main(int argc, char **argv)
|
||||
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
|
||||
send_addr.Outbound = !recv_addr.Outbound;
|
||||
WinDivertHelperCalcChecksums((PVOID)resetv6,
|
||||
sizeof(TCPV6PACKET), &send_addr, 0);
|
||||
sizeof(TCPV6PACKET), WINDIVERT_LAYER_NETWORK, &send_addr,
|
||||
0);
|
||||
if (!WinDivertSend(handle, (PVOID)resetv6, sizeof(TCPV6PACKET),
|
||||
NULL, &send_addr))
|
||||
{
|
||||
@@ -343,7 +344,7 @@ int __cdecl main(int argc, char **argv)
|
||||
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
|
||||
send_addr.Outbound = !recv_addr.Outbound;
|
||||
WinDivertHelperCalcChecksums((PVOID)dnr, icmp_length,
|
||||
&send_addr, 0);
|
||||
WINDIVERT_LAYER_NETWORK, &send_addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)dnr, icmp_length, NULL,
|
||||
&send_addr))
|
||||
{
|
||||
@@ -366,7 +367,7 @@ int __cdecl main(int argc, char **argv)
|
||||
memcpy(&send_addr, &recv_addr, sizeof(send_addr));
|
||||
send_addr.Outbound = !recv_addr.Outbound;
|
||||
WinDivertHelperCalcChecksums((PVOID)dnrv6, icmpv6_length,
|
||||
&send_addr, 0);
|
||||
WINDIVERT_LAYER_NETWORK, &send_addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)dnrv6, icmpv6_length,
|
||||
NULL, &send_addr))
|
||||
{
|
||||
|
||||
+144
-60
@@ -38,6 +38,7 @@
|
||||
* useful for performance testing.
|
||||
*
|
||||
* usage: passthru.exe [windivert-filter] [num-threads] [batch-size] [priority]
|
||||
* [layer]
|
||||
*/
|
||||
|
||||
#include <winsock2.h>
|
||||
@@ -47,69 +48,162 @@
|
||||
|
||||
#include "windivert.h"
|
||||
|
||||
#define MTU 1500
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HANDLE handle;
|
||||
int batch;
|
||||
} CONFIG, *PCONFIG;
|
||||
|
||||
static DWORD passthru(LPVOID arg);
|
||||
|
||||
/*
|
||||
* Options.
|
||||
*/
|
||||
static int threads = 1;
|
||||
static int batch = WINDIVERT_BATCH_MAX;
|
||||
static int priority = 0;
|
||||
static WINDIVERT_LAYER layer = WINDIVERT_LAYER_NETWORK;
|
||||
static int size = (0x10000 + 4096);
|
||||
|
||||
/*
|
||||
* Print usage and exit.
|
||||
*/
|
||||
static void usage(const char *prog)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [OPTIONS] filter-string\n\n", prog);
|
||||
fprintf(stderr, "OPTIONS:\n");
|
||||
fprintf(stderr, "\t--batch N\n");
|
||||
fprintf(stderr, "\t\tSet the batch size to N (default=%u)\n",
|
||||
WINDIVERT_BATCH_MAX);
|
||||
fprintf(stderr, "\t--layer LAYER\n");
|
||||
fprintf(stderr, "\t\tSet the filter layer to LAYER (default=network).\n");
|
||||
fprintf(stderr, "\t\tValid values are {ethernet,network,forward}.\n");
|
||||
fprintf(stderr, "\t--priority N\n");
|
||||
fprintf(stderr, "\t\tSet the filter priority to N (default=0)\n");
|
||||
fprintf(stderr, "\t--size N\n");
|
||||
fprintf(stderr, "\t\tSet the buffer size to N (default=%u)\n",
|
||||
(0x10000 + 4096));
|
||||
fprintf(stderr, "\t--threads N\n");
|
||||
fprintf(stderr, "\t\tSet the number of threads to be N (default=1)\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse options.
|
||||
*/
|
||||
static const char *parse_options(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
size_t n;
|
||||
const char *filter = NULL, *opt, *arg;
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
opt = argv[i];
|
||||
if (opt[0] != '-' || opt[1] != '-')
|
||||
{
|
||||
if (filter != NULL)
|
||||
{
|
||||
usage(argv[0]);
|
||||
}
|
||||
filter = opt;
|
||||
continue;
|
||||
}
|
||||
opt += 2;
|
||||
arg = strchr(opt, '=');
|
||||
if (arg == NULL)
|
||||
{
|
||||
i++;
|
||||
if (i >= argc)
|
||||
{
|
||||
usage(argv[0]);
|
||||
}
|
||||
arg = argv[i];
|
||||
n = strlen(opt);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = arg - opt;
|
||||
arg++;
|
||||
}
|
||||
if (strncmp(opt, "threads", n) == 0)
|
||||
{
|
||||
threads = atoi(arg);
|
||||
}
|
||||
else if (strncmp(opt, "batch", n) == 0)
|
||||
{
|
||||
batch = atoi(arg);
|
||||
}
|
||||
else if (strncmp(opt, "priority", n) == 0)
|
||||
{
|
||||
priority = atoi(arg);
|
||||
}
|
||||
else if (strncmp(opt, "size", n) == 0)
|
||||
{
|
||||
size = atoi(arg);
|
||||
}
|
||||
else if (strncmp(opt, "layer", n) == 0)
|
||||
{
|
||||
if (strcmp(arg, "ethernet") == 0)
|
||||
{
|
||||
layer = WINDIVERT_LAYER_ETHERNET;
|
||||
}
|
||||
else if (strcmp(arg, "network") == 0)
|
||||
{
|
||||
layer = WINDIVERT_LAYER_NETWORK;
|
||||
}
|
||||
else if (strcmp(arg, "forward") == 0)
|
||||
{
|
||||
layer = WINDIVERT_LAYER_NETWORK_FORWARD;
|
||||
}
|
||||
else
|
||||
{
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
return (filter == NULL? "true": filter);
|
||||
}
|
||||
|
||||
/*
|
||||
* Entry.
|
||||
*/
|
||||
int __cdecl main(int argc, char **argv)
|
||||
{
|
||||
const char *filter = "true";
|
||||
int threads = 1, batch = 1, priority = 0;
|
||||
const char *filter;
|
||||
int i;
|
||||
HANDLE handle, thread;
|
||||
CONFIG config;
|
||||
|
||||
if (argc > 5)
|
||||
filter = parse_options(argc, argv);
|
||||
|
||||
if (threads < 1 || threads > 64)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [filter] [num-threads] [batch-size] "
|
||||
"[priority]\n", argv[0]);
|
||||
fprintf(stderr, "error: number of threads must be within "
|
||||
"the range 1..64, found %d\n", threads);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (argc >= 2)
|
||||
if (batch < 1 || batch > WINDIVERT_BATCH_MAX)
|
||||
{
|
||||
filter = argv[1];
|
||||
fprintf(stderr, "error: batch size must be within the range 1..%u, "
|
||||
"found %d\n", WINDIVERT_BATCH_MAX, batch);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (argc >= 3)
|
||||
if (priority < WINDIVERT_PRIORITY_LOWEST ||
|
||||
priority > WINDIVERT_PRIORITY_HIGHEST)
|
||||
{
|
||||
threads = atoi(argv[2]);
|
||||
if (threads < 1 || threads > 64)
|
||||
{
|
||||
fprintf(stderr, "error: invalid number of threads\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(stderr, "error: priority must be within the range %d..%d, "
|
||||
"found %d\n", WINDIVERT_PRIORITY_LOWEST,
|
||||
WINDIVERT_PRIORITY_HIGHEST, priority);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (argc >= 4)
|
||||
if (size < 1 || size >= WINDIVERT_BATCH_MAX * WINDIVERT_MTU_MAX)
|
||||
{
|
||||
batch = atoi(argv[3]);
|
||||
if (batch <= 0 || batch > WINDIVERT_BATCH_MAX)
|
||||
{
|
||||
fprintf(stderr, "error: invalid batch size\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
if (argc >= 5)
|
||||
{
|
||||
priority = atoi(argv[4]);
|
||||
if (priority < WINDIVERT_PRIORITY_LOWEST ||
|
||||
priority > WINDIVERT_PRIORITY_HIGHEST)
|
||||
{
|
||||
fprintf(stderr, "error: invalid priority value\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(stderr, "error: buffer size must be within the range 1..%d, "
|
||||
"found %d\n", WINDIVERT_BATCH_MAX * WINDIVERT_MTU_MAX,
|
||||
size);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Divert traffic matching the filter:
|
||||
handle = WinDivertOpen(filter, WINDIVERT_LAYER_NETWORK, (INT16)priority,
|
||||
0);
|
||||
handle = WinDivertOpen(filter, layer, (INT16)priority, 0);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetLastError() == ERROR_INVALID_PARAMETER)
|
||||
@@ -123,12 +217,10 @@ int __cdecl main(int argc, char **argv)
|
||||
}
|
||||
|
||||
// Start the threads
|
||||
config.handle = handle;
|
||||
config.batch = batch;
|
||||
for (i = 1; i < threads; i++)
|
||||
{
|
||||
thread = CreateThread(NULL, 1, (LPTHREAD_START_ROUTINE)passthru,
|
||||
(LPVOID)&config, 0, NULL);
|
||||
(LPVOID)handle, 0, NULL);
|
||||
if (thread == NULL)
|
||||
{
|
||||
fprintf(stderr, "error: failed to start passthru thread (%d)\n",
|
||||
@@ -138,8 +230,8 @@ int __cdecl main(int argc, char **argv)
|
||||
}
|
||||
|
||||
// Main thread:
|
||||
passthru((LPVOID)&config);
|
||||
|
||||
passthru((LPVOID)handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -147,19 +239,11 @@ int __cdecl main(int argc, char **argv)
|
||||
static DWORD passthru(LPVOID arg)
|
||||
{
|
||||
UINT8 *packet;
|
||||
UINT packet_len, recv_len, addr_len;
|
||||
UINT packet_len, addr_len;
|
||||
WINDIVERT_ADDRESS *addr;
|
||||
PCONFIG config = (PCONFIG)arg;
|
||||
HANDLE handle;
|
||||
int batch;
|
||||
HANDLE handle = (HANDLE)arg;
|
||||
|
||||
handle = config->handle;
|
||||
batch = config->batch;
|
||||
|
||||
packet_len = batch * MTU;
|
||||
packet_len =
|
||||
(packet_len < WINDIVERT_MTU_MAX? WINDIVERT_MTU_MAX: packet_len);
|
||||
packet = (UINT8 *)malloc(packet_len);
|
||||
packet = (UINT8 *)malloc(size);
|
||||
addr = (WINDIVERT_ADDRESS *)malloc(batch * sizeof(WINDIVERT_ADDRESS));
|
||||
if (packet == NULL || addr == NULL)
|
||||
{
|
||||
@@ -173,7 +257,7 @@ static DWORD passthru(LPVOID arg)
|
||||
{
|
||||
// Read a matching packet.
|
||||
addr_len = batch * sizeof(WINDIVERT_ADDRESS);
|
||||
if (!WinDivertRecvEx(handle, packet, packet_len, &recv_len, 0,
|
||||
if (!WinDivertRecvEx(handle, packet, size, &packet_len, 0,
|
||||
addr, &addr_len, NULL))
|
||||
{
|
||||
fprintf(stderr, "warning: failed to read packet (%d)\n",
|
||||
@@ -182,7 +266,7 @@ static DWORD passthru(LPVOID arg)
|
||||
}
|
||||
|
||||
// Re-inject the matching packet.
|
||||
if (!WinDivertSendEx(handle, packet, recv_len, NULL, 0, addr,
|
||||
if (!WinDivertSendEx(handle, packet, packet_len, NULL, 0, addr,
|
||||
addr_len, NULL))
|
||||
{
|
||||
fprintf(stderr, "warning: failed to reinject packet (%d)\n",
|
||||
|
||||
@@ -193,8 +193,8 @@ int __cdecl main(int argc, char **argv)
|
||||
continue;
|
||||
}
|
||||
|
||||
WinDivertHelperParsePacket(packet, packet_len, &ip_header, NULL, NULL,
|
||||
NULL, NULL, &tcp_header, NULL, NULL, NULL, NULL, NULL);
|
||||
WinDivertHelperParsePacket(packet, packet_len, addr.Layer, NULL,
|
||||
&ip_header, NULL, NULL, NULL, NULL, &tcp_header, NULL, NULL, NULL);
|
||||
if (ip_header == NULL || tcp_header == NULL)
|
||||
{
|
||||
warning("failed to parse packet (%d)", GetLastError());
|
||||
@@ -236,7 +236,7 @@ int __cdecl main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
WinDivertHelperCalcChecksums(packet, packet_len, &addr, 0);
|
||||
WinDivertHelperCalcChecksums(packet, packet_len, addr.Layer, &addr, 0);
|
||||
if (!WinDivertSend(handle, packet, packet_len, NULL, &addr))
|
||||
{
|
||||
warning("failed to send packet (%d)", GetLastError());
|
||||
|
||||
@@ -204,9 +204,9 @@ int __cdecl main(int argc, char **argv)
|
||||
continue;
|
||||
}
|
||||
|
||||
WinDivertHelperParsePacket(packet, packet_len, &ip_header, NULL,
|
||||
NULL, NULL, NULL, &tcp_header, NULL, &payload, &payload_len,
|
||||
NULL, NULL);
|
||||
WinDivertHelperParsePacket(packet, packet_len, addr.Layer, NULL,
|
||||
&ip_header, NULL, NULL, NULL, NULL, &tcp_header, NULL, &payload,
|
||||
&payload_len);
|
||||
if (ip_header == NULL || tcp_header == NULL || payload == NULL ||
|
||||
!BlackListPayloadMatch(blacklist, payload, (UINT16)payload_len))
|
||||
{
|
||||
@@ -230,7 +230,8 @@ int __cdecl main(int argc, char **argv)
|
||||
reset->tcp.DstPort = htons(80);
|
||||
reset->tcp.SeqNum = tcp_header->SeqNum;
|
||||
reset->tcp.AckNum = tcp_header->AckNum;
|
||||
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(PACKET), &addr, 0);
|
||||
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(PACKET),
|
||||
addr.Layer, &addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)reset, sizeof(PACKET), NULL, &addr))
|
||||
{
|
||||
fprintf(stderr, "warning: failed to send reset packet (%d)\n",
|
||||
@@ -245,7 +246,8 @@ int __cdecl main(int argc, char **argv)
|
||||
blockpage->header.tcp.AckNum =
|
||||
htonl(ntohl(tcp_header->SeqNum) + payload_len);
|
||||
addr.Outbound = !addr.Outbound; // Reverse direction.
|
||||
WinDivertHelperCalcChecksums((PVOID)blockpage, blockpage_len, &addr, 0);
|
||||
WinDivertHelperCalcChecksums((PVOID)blockpage, blockpage_len,
|
||||
addr.Layer, &addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)blockpage, blockpage_len, NULL,
|
||||
&addr))
|
||||
{
|
||||
@@ -263,7 +265,8 @@ int __cdecl main(int argc, char **argv)
|
||||
htonl(ntohl(tcp_header->AckNum) + sizeof(block_data) - 1);
|
||||
finish->tcp.AckNum =
|
||||
htonl(ntohl(tcp_header->SeqNum) + payload_len);
|
||||
WinDivertHelperCalcChecksums((PVOID)finish, sizeof(PACKET), &addr, 0);
|
||||
WinDivertHelperCalcChecksums((PVOID)finish, sizeof(PACKET),
|
||||
addr.Layer, &addr, 0);
|
||||
if (!WinDivertSend(handle, (PVOID)finish, sizeof(PACKET), NULL, &addr))
|
||||
{
|
||||
fprintf(stderr, "warning: failed to send finish packet (%d)\n",
|
||||
|
||||
@@ -244,11 +244,14 @@ usage:
|
||||
SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
switch (addr.Reflect.Layer)
|
||||
{
|
||||
case WINDIVERT_LAYER_ETHERNET:
|
||||
fputs("ETHERNET", stdout);
|
||||
break;
|
||||
case WINDIVERT_LAYER_NETWORK:
|
||||
fputs("NETWORK", stdout);
|
||||
break;
|
||||
case WINDIVERT_LAYER_NETWORK_FORWARD:
|
||||
fputs("NETWORK_FORWARD", stdout);
|
||||
fputs("FORWARD", stdout);
|
||||
break;
|
||||
case WINDIVERT_LAYER_FLOW:
|
||||
fputs("FLOW", stdout);
|
||||
|
||||
+52
-6
@@ -79,8 +79,18 @@ typedef enum
|
||||
WINDIVERT_LAYER_FLOW = 2, /* Flow layer. */
|
||||
WINDIVERT_LAYER_SOCKET = 3, /* Socket layer. */
|
||||
WINDIVERT_LAYER_REFLECT = 4, /* Reflect layer. */
|
||||
WINDIVERT_LAYER_ETHERNET = 5, /* Ethernet layer. */
|
||||
} WINDIVERT_LAYER, *PWINDIVERT_LAYER;
|
||||
|
||||
/*
|
||||
* WinDivert ETHERNET layer data.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT32 IfIdx; /* Packet's interface index. */
|
||||
UINT32 SubIfIdx; /* Packet's sub-interface index. */
|
||||
} WINDIVERT_DATA_ETHERNET, *PWINDIVERT_DATA_ETHERNET;
|
||||
|
||||
/*
|
||||
* WinDivert NETWORK and NETWORK_FORWARD layer data.
|
||||
*/
|
||||
@@ -153,9 +163,12 @@ typedef struct
|
||||
UINT32 TCPChecksum:1; /* Packet has valid TCP checksum? */
|
||||
UINT32 UDPChecksum:1; /* Packet has valid UDP checksum? */
|
||||
UINT32 Reserved1:8;
|
||||
UINT32 Reserved2;
|
||||
UINT32 Reserved2:12;
|
||||
UINT32 Length:20; /* Packet length. */
|
||||
union
|
||||
{
|
||||
WINDIVERT_DATA_ETHERNET Ethernet;
|
||||
/* Ethernet layer data. */
|
||||
WINDIVERT_DATA_NETWORK Network; /* Network layer data. */
|
||||
WINDIVERT_DATA_FLOW Flow; /* Flow layer data. */
|
||||
WINDIVERT_DATA_SOCKET Socket; /* Socket layer data. */
|
||||
@@ -183,6 +196,7 @@ typedef enum
|
||||
WINDIVERT_EVENT_SOCKET_CLOSE = 7, /* Socket close. */
|
||||
WINDIVERT_EVENT_REFLECT_OPEN = 8, /* WinDivert handle opened. */
|
||||
WINDIVERT_EVENT_REFLECT_CLOSE = 9, /* WinDivert handle closed. */
|
||||
WINDIVERT_EVENT_ETHERNET_FRAME = 10,/* Ethernet frame. */
|
||||
} WINDIVERT_EVENT, *PWINDIVERT_EVENT;
|
||||
|
||||
/*
|
||||
@@ -336,8 +350,15 @@ WINDIVERTEXPORT BOOL WinDivertGetParam(
|
||||
#endif
|
||||
|
||||
/*
|
||||
* IPv4/IPv6/ICMP/ICMPv6/TCP/UDP header definitions.
|
||||
* Ethernet/IPv4/IPv6/ICMP/ICMPv6/TCP/UDP header definitions.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT8 DstAddr[6];
|
||||
UINT8 SrcAddr[6];
|
||||
UINT16 Type;
|
||||
} WINDIVERT_ETHHDR, *PWINDIVERT_ETHHDR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 HdrLength:4;
|
||||
@@ -490,6 +511,7 @@ typedef struct
|
||||
WINDIVERTEXPORT UINT64 WinDivertHelperHashPacket(
|
||||
__in const VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__in UINT64 seed
|
||||
#ifdef __cplusplus
|
||||
= 0
|
||||
@@ -502,6 +524,8 @@ WINDIVERTEXPORT UINT64 WinDivertHelperHashPacket(
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperParsePacket(
|
||||
__in const VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__out_opt PWINDIVERT_ETHHDR *ppEthHdr,
|
||||
__out_opt PWINDIVERT_IPHDR *ppIpHdr,
|
||||
__out_opt PWINDIVERT_IPV6HDR *ppIpv6Hdr,
|
||||
__out_opt UINT8 *pProtocol,
|
||||
@@ -510,9 +534,14 @@ WINDIVERTEXPORT BOOL WinDivertHelperParsePacket(
|
||||
__out_opt PWINDIVERT_TCPHDR *ppTcpHdr,
|
||||
__out_opt PWINDIVERT_UDPHDR *ppUdpHdr,
|
||||
__out_opt PVOID *ppData,
|
||||
__out_opt UINT *pDataLen,
|
||||
__out_opt PVOID *ppNext,
|
||||
__out_opt UINT *pNextLen);
|
||||
__out_opt UINT *pDataLen);
|
||||
|
||||
/*
|
||||
* Parse a MAC address.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperParseMACAddress(
|
||||
__in const char *addrStr,
|
||||
__out_opt UINT8 *pAddr);
|
||||
|
||||
/*
|
||||
* Parse an IPv4 address.
|
||||
@@ -528,6 +557,14 @@ WINDIVERTEXPORT BOOL WinDivertHelperParseIPv6Address(
|
||||
__in const char *addrStr,
|
||||
__out_opt UINT32 *pAddr);
|
||||
|
||||
/*
|
||||
* Format a MAC address.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperFormatMACAddress(
|
||||
__in const UINT8 *pAddr,
|
||||
__out char *buffer,
|
||||
__in UINT bufLen);
|
||||
|
||||
/*
|
||||
* Format an IPv4 address.
|
||||
*/
|
||||
@@ -550,6 +587,7 @@ WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv6Address(
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperCalcChecksums(
|
||||
__inout VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__out_opt WINDIVERT_ADDRESS *pAddr,
|
||||
__in UINT64 flags);
|
||||
|
||||
@@ -558,7 +596,8 @@ WINDIVERTEXPORT BOOL WinDivertHelperCalcChecksums(
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperDecrementTTL(
|
||||
__inout VOID *pPacket,
|
||||
__in UINT packetLen);
|
||||
__in UINT packetLen,
|
||||
__in WINDIVERT_LAYER layer);
|
||||
|
||||
/*
|
||||
* Compile the given filter string.
|
||||
@@ -578,6 +617,7 @@ WINDIVERTEXPORT BOOL WinDivertHelperEvalFilter(
|
||||
__in const char *filter,
|
||||
__in const VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__in const WINDIVERT_ADDRESS *pAddr);
|
||||
|
||||
/*
|
||||
@@ -604,6 +644,12 @@ WINDIVERTEXPORT UINT64 WinDivertHelperNtohll(
|
||||
__in UINT64 x);
|
||||
WINDIVERTEXPORT UINT64 WinDivertHelperHtonll(
|
||||
__in UINT64 x);
|
||||
WINDIVERTEXPORT void WinDivertHelperNtohMACAddress(
|
||||
__in const UINT8 *inAddr,
|
||||
__out UINT8 *outAddr);
|
||||
WINDIVERTEXPORT void WinDivertHelperHtonMACAddress(
|
||||
__in const UINT8 *inAddr,
|
||||
__out UINT8 *outAddr);
|
||||
WINDIVERTEXPORT void WinDivertHelperNtohIPv6Address(
|
||||
__in const UINT *inAddr,
|
||||
__out UINT *outAddr);
|
||||
|
||||
@@ -44,8 +44,8 @@
|
||||
#define WINDIVERT_KERNEL
|
||||
#include "windivert.h"
|
||||
|
||||
#define WINDIVERT_VERSION_MAJOR 2
|
||||
#define WINDIVERT_VERSION_MINOR 2
|
||||
#define WINDIVERT_VERSION_MAJOR 3
|
||||
#define WINDIVERT_VERSION_MINOR 0
|
||||
|
||||
#define WINDIVERT_MAGIC_DLL 0x4C4C447669645724ull
|
||||
#define WINDIVERT_MAGIC_SYS 0x5359537669645723ull
|
||||
@@ -150,8 +150,11 @@
|
||||
#define WINDIVERT_FILTER_FIELD_RANDOM16 83
|
||||
#define WINDIVERT_FILTER_FIELD_RANDOM32 84
|
||||
#define WINDIVERT_FILTER_FIELD_FRAGMENT 85
|
||||
#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_MAX \
|
||||
WINDIVERT_FILTER_FIELD_FRAGMENT
|
||||
WINDIVERT_FILTER_FIELD_ETH_TYPE
|
||||
|
||||
#define WINDIVERT_FILTER_TEST_EQ 0
|
||||
#define WINDIVERT_FILTER_TEST_NEQ 1
|
||||
|
||||
+898
-397
File diff suppressed because it is too large
Load Diff
@@ -69,7 +69,7 @@
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<TargetVersion>Windows7</TargetVersion>
|
||||
<TargetVersion>Windows8</TargetVersion>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
|
||||
+4
-3
@@ -1274,10 +1274,10 @@ static BOOL run_test(HANDLE inject_handle, const char *filter,
|
||||
// non-matching random values have been lost:
|
||||
if ((!random &&
|
||||
WinDivertHelperEvalFilter(filter, buf[idx], buf_len[idx],
|
||||
&addr[idx]) != result) ||
|
||||
WINDIVERT_LAYER_NETWORK, &addr[idx]) != result) ||
|
||||
(random && result &&
|
||||
!WinDivertHelperEvalFilter(filter, buf[idx], buf_len[idx],
|
||||
&addr[idx])))
|
||||
WINDIVERT_LAYER_NETWORK, &addr[idx])))
|
||||
{
|
||||
fprintf(stderr, "error: filter \"%s\" does not match the given "
|
||||
"packet\n", filter);
|
||||
@@ -1415,7 +1415,8 @@ static DWORD monitor_worker(LPVOID arg)
|
||||
addr.Outbound = TRUE;
|
||||
addr.IPv6 = (iphdr->Version == 4? FALSE: TRUE);
|
||||
if (WinDivertHelperEvalFilter(object_1, tests[i].packet->packet,
|
||||
tests[i].packet->packet_len, &addr) != tests[i].match)
|
||||
tests[i].packet->packet_len, WINDIVERT_LAYER_NETWORK, &addr)
|
||||
!= tests[i].match)
|
||||
{
|
||||
fprintf(stderr, "error: failed to match recompiled filter "
|
||||
"(test = %.3u, filter = \"%s\" formatted = \"%s\", "
|
||||
|
||||
Reference in New Issue
Block a user