Add type-safe get-fixed-val routines.
This prevents possible bsods when values are missing. Also add missing windivert_shared.c file.
This commit is contained in:
@@ -63,27 +63,6 @@ static int WinDivertStrCmp(const char *s, const char *t);
|
||||
static BOOLEAN WinDivertAToI(const char *str, char **endptr, UINT32 *intptr);
|
||||
static BOOLEAN WinDivertAToX(const char *str, char **endptr, UINT32 *intptr);
|
||||
|
||||
/*
|
||||
* IPv4/IPv6 pseudo headers.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT32 SrcAddr;
|
||||
UINT32 DstAddr;
|
||||
UINT8 Zero;
|
||||
UINT8 Protocol;
|
||||
UINT16 Length;
|
||||
} WINDIVERT_PSEUDOHDR, *PWINDIVERT_PSEUDOHDR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT32 SrcAddr[4];
|
||||
UINT32 DstAddr[4];
|
||||
UINT32 Length;
|
||||
UINT32 Zero:24;
|
||||
UINT32 NextHdr:8;
|
||||
} WINDIVERT_PSEUDOV6HDR, *PWINDIVERT_PSEUDOV6HDR;
|
||||
|
||||
/*
|
||||
* Misc.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,614 @@
|
||||
/*
|
||||
* windivert_shared.c
|
||||
* (C) 2018, all rights reserved,
|
||||
*
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define WINDIVERT_OBJECT_MAXLEN \
|
||||
(8 + 4 + 2 + WINDIVERT_FILTER_MAXLEN * (1 + 2 + 2 + 4*7 + 2 + 2) + 1)
|
||||
|
||||
#define MAX(a, b) ((a) > (b)? (a): (b))
|
||||
|
||||
/*
|
||||
* Definitions to remove (some) external dependencies:
|
||||
*/
|
||||
#define BYTESWAP16(x) \
|
||||
((((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00))
|
||||
#define BYTESWAP32(x) \
|
||||
((((x) >> 24) & 0x000000FF) | (((x) >> 8) & 0x0000FF00) | \
|
||||
(((x) << 8) & 0x00FF0000) | (((x) << 24) & 0xFF000000))
|
||||
#define ntohs(x) BYTESWAP16(x)
|
||||
#define htons(x) BYTESWAP16(x)
|
||||
#define ntohl(x) BYTESWAP32(x)
|
||||
#define htonl(x) BYTESWAP32(x)
|
||||
|
||||
/*
|
||||
* IPv4/IPv6 pseudo headers.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT32 SrcAddr;
|
||||
UINT32 DstAddr;
|
||||
UINT8 Zero;
|
||||
UINT8 Protocol;
|
||||
UINT16 Length;
|
||||
} WINDIVERT_PSEUDOHDR, *PWINDIVERT_PSEUDOHDR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT32 SrcAddr[4];
|
||||
UINT32 DstAddr[4];
|
||||
UINT32 Length;
|
||||
UINT32 Zero:24;
|
||||
UINT32 NextHdr:8;
|
||||
} WINDIVERT_PSEUDOV6HDR, *PWINDIVERT_PSEUDOV6HDR;
|
||||
|
||||
/*
|
||||
* Streams.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *data;
|
||||
UINT pos;
|
||||
UINT max;
|
||||
BOOL overflow;
|
||||
} WINDIVERT_STREAM, *PWINDIVERT_STREAM;
|
||||
|
||||
/*
|
||||
* Prototypes.
|
||||
*/
|
||||
static UINT16 WinDivertInitPseudoHeader(PWINDIVERT_IPHDR ip_header,
|
||||
PWINDIVERT_IPV6HDR ipv6_header, UINT8 protocol, UINT len,
|
||||
void *pseudo_header);
|
||||
static UINT16 WinDivertCalcChecksum(PVOID pseudo_header,
|
||||
UINT16 pseudo_header_len, PVOID data, UINT len);
|
||||
|
||||
/*
|
||||
* Put a char into a stream.
|
||||
*/
|
||||
static void WinDivertPutChar(PWINDIVERT_STREAM stream, char c)
|
||||
{
|
||||
if (stream->pos >= stream->max)
|
||||
{
|
||||
stream->overflow = TRUE;
|
||||
return;
|
||||
}
|
||||
stream->data[stream->pos] = c;
|
||||
stream->pos++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put a string into a stream.
|
||||
*/
|
||||
static void WinDivertPutString(PWINDIVERT_STREAM stream, const char *str)
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
WinDivertPutChar(stream, *str);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Put a NUL character into a stream.
|
||||
*/
|
||||
static void WinDivertPutNul(PWINDIVERT_STREAM stream)
|
||||
{
|
||||
if (stream->pos >= stream->max && stream->max > 0)
|
||||
{
|
||||
stream->data[stream->max-1] = '\0'; // Truncate
|
||||
}
|
||||
else
|
||||
{
|
||||
WinDivertPutChar(stream, '\0');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialize a number.
|
||||
*/
|
||||
static void WinDivertSerializeNumber(PWINDIVERT_STREAM stream, UINT32 val)
|
||||
{
|
||||
UINT64 mask = 0x00000007C0000000ull;
|
||||
UINT dig = 6;
|
||||
UINT64 val64 = (UINT64)val;
|
||||
BOOL final;
|
||||
|
||||
while ((mask & val64) == 0 && dig != 0)
|
||||
{
|
||||
mask >>= 5;
|
||||
dig--;
|
||||
}
|
||||
while (TRUE)
|
||||
{
|
||||
final = (dig == 0);
|
||||
WinDivertPutChar(stream, '!' + (char)((mask & val64) >> (5 * dig)) +
|
||||
(final? 32: 0));
|
||||
if (final)
|
||||
{
|
||||
break;
|
||||
}
|
||||
mask >>= 5;
|
||||
dig--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialize a test.
|
||||
*/
|
||||
static void WinDivertSerializeTest(PWINDIVERT_STREAM stream,
|
||||
PWINDIVERT_FILTER filter)
|
||||
{
|
||||
UINT i;
|
||||
|
||||
WinDivertPutChar(stream, '_');
|
||||
WinDivertSerializeNumber(stream, filter->field);
|
||||
WinDivertSerializeNumber(stream, filter->test);
|
||||
WinDivertSerializeNumber(stream, filter->arg[0]);
|
||||
switch (filter->field)
|
||||
{
|
||||
case WINDIVERT_FILTER_FIELD_IPV6_SRCADDR:
|
||||
case WINDIVERT_FILTER_FIELD_IPV6_DSTADDR:
|
||||
case WINDIVERT_FILTER_FIELD_LOCALADDR:
|
||||
case WINDIVERT_FILTER_FIELD_REMOTEADDR:
|
||||
for (i = 1; i < 4; i++)
|
||||
{
|
||||
WinDivertSerializeNumber(stream, filter->arg[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
WinDivertSerializeNumber(stream, (UINT8)(filter->success + 2));
|
||||
WinDivertSerializeNumber(stream, (UINT8)(filter->failure + 2));
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialize a test.
|
||||
*/
|
||||
static void WinDivertSerializeFilter(PWINDIVERT_STREAM stream,
|
||||
PWINDIVERT_FILTER filter, UINT8 length)
|
||||
{
|
||||
UINT8 i;
|
||||
WinDivertPutString(stream, "@WinDiv_"); // Magic
|
||||
WinDivertSerializeNumber(stream, 0); // Version
|
||||
WinDivertSerializeNumber(stream, length); // Length
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
WinDivertSerializeTest(stream, filter + i);
|
||||
}
|
||||
WinDivertPutNul(stream);
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip well-known IPv6 extension headers.
|
||||
*/
|
||||
static UINT8 WinDivertSkipExtHeaders(UINT8 proto, UINT8 **header, UINT *len)
|
||||
{
|
||||
UINT hdrlen;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (*len <= 2)
|
||||
{
|
||||
return IPPROTO_NONE;
|
||||
}
|
||||
|
||||
hdrlen = (UINT)*(*header + 1);
|
||||
switch (proto)
|
||||
{
|
||||
case IPPROTO_FRAGMENT:
|
||||
hdrlen = 8;
|
||||
break;
|
||||
case IPPROTO_AH:
|
||||
hdrlen += 2;
|
||||
hdrlen *= 4;
|
||||
break;
|
||||
case IPPROTO_HOPOPTS:
|
||||
case IPPROTO_DSTOPTS:
|
||||
case IPPROTO_ROUTING:
|
||||
hdrlen++;
|
||||
hdrlen *= 8;
|
||||
break;
|
||||
case IPPROTO_NONE:
|
||||
return proto;
|
||||
default:
|
||||
return proto;
|
||||
}
|
||||
|
||||
if (hdrlen >= *len)
|
||||
{
|
||||
return IPPROTO_NONE;
|
||||
}
|
||||
|
||||
proto = **header;
|
||||
*header += hdrlen;
|
||||
*len -= hdrlen;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse IPv4/IPv6/ICMP/ICMPv6/TCP/UDP headers from a raw packet.
|
||||
*/
|
||||
static BOOL WinDivertParsePacket(PVOID pPacket, UINT packetLen,
|
||||
PWINDIVERT_IPHDR *ppIpHdr, PWINDIVERT_IPV6HDR *ppIpv6Hdr,
|
||||
PWINDIVERT_ICMPHDR *ppIcmpHdr, PWINDIVERT_ICMPV6HDR *ppIcmpv6Hdr,
|
||||
PWINDIVERT_TCPHDR *ppTcpHdr, PWINDIVERT_UDPHDR *ppUdpHdr, UINT8 *pProto,
|
||||
PVOID *ppData, UINT *pDataLen)
|
||||
{
|
||||
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;
|
||||
UINT16 header_len;
|
||||
UINT8 trans_proto = 0;
|
||||
PVOID data = NULL;
|
||||
UINT data_len = 0;
|
||||
BOOL success;
|
||||
|
||||
if (pPacket == NULL || packetLen < sizeof(UINT8))
|
||||
{
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
data = pPacket;
|
||||
data_len = packetLen;
|
||||
|
||||
ip_header = (PWINDIVERT_IPHDR)data;
|
||||
switch (ip_header->Version)
|
||||
{
|
||||
case 4:
|
||||
if (data_len < sizeof(WINDIVERT_IPHDR) ||
|
||||
ip_header->HdrLength < 5 ||
|
||||
data_len < ip_header->HdrLength*sizeof(UINT32) ||
|
||||
ntohs(ip_header->Length) != data_len)
|
||||
{
|
||||
ip_header = NULL;
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
trans_proto = ip_header->Protocol;
|
||||
header_len = ip_header->HdrLength*sizeof(UINT32);
|
||||
data = (PVOID)((UINT8 *)data + header_len);
|
||||
data_len -= header_len;
|
||||
break;
|
||||
case 6:
|
||||
ip_header = NULL;
|
||||
ipv6_header = (PWINDIVERT_IPV6HDR)data;
|
||||
if (data_len < sizeof(WINDIVERT_IPV6HDR) ||
|
||||
ntohs(ipv6_header->Length) !=
|
||||
data_len - sizeof(WINDIVERT_IPV6HDR))
|
||||
{
|
||||
ipv6_header = NULL;
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
trans_proto = ipv6_header->NextHdr;
|
||||
data = (PVOID)((UINT8 *)data + sizeof(WINDIVERT_IPV6HDR));
|
||||
data_len -= sizeof(WINDIVERT_IPV6HDR);
|
||||
trans_proto = WinDivertSkipExtHeaders(trans_proto, (UINT8 **)&data,
|
||||
&data_len);
|
||||
break;
|
||||
default:
|
||||
ip_header = NULL;
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
switch (trans_proto)
|
||||
{
|
||||
case IPPROTO_TCP:
|
||||
tcp_header = (PWINDIVERT_TCPHDR)data;
|
||||
if (data_len < sizeof(WINDIVERT_TCPHDR) ||
|
||||
tcp_header->HdrLength < 5 ||
|
||||
data_len < tcp_header->HdrLength*sizeof(UINT32))
|
||||
{
|
||||
tcp_header = NULL;
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
header_len = tcp_header->HdrLength*sizeof(UINT32);
|
||||
data = ((UINT8 *)data + header_len);
|
||||
data_len -= header_len;
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
udp_header = (PWINDIVERT_UDPHDR)data;
|
||||
if (data_len < sizeof(WINDIVERT_UDPHDR) ||
|
||||
ntohs(udp_header->Length) != data_len)
|
||||
{
|
||||
udp_header = NULL;
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
data = ((UINT8 *)data + sizeof(WINDIVERT_UDPHDR));
|
||||
data_len -= sizeof(WINDIVERT_UDPHDR);
|
||||
break;
|
||||
case IPPROTO_ICMP:
|
||||
icmp_header = (PWINDIVERT_ICMPHDR)data;
|
||||
if (ip_header == NULL ||
|
||||
data_len < sizeof(WINDIVERT_ICMPHDR))
|
||||
{
|
||||
icmp_header = NULL;
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
data = ((UINT8 *)data + sizeof(WINDIVERT_ICMPHDR));
|
||||
data_len -= sizeof(WINDIVERT_ICMPHDR);
|
||||
break;
|
||||
case IPPROTO_ICMPV6:
|
||||
icmpv6_header = (PWINDIVERT_ICMPV6HDR)data;
|
||||
if (ipv6_header == NULL ||
|
||||
data_len < sizeof(WINDIVERT_ICMPV6HDR))
|
||||
{
|
||||
icmpv6_header = NULL;
|
||||
goto WinDivertHelperParsePacketExit;
|
||||
}
|
||||
data = ((UINT8 *)data + sizeof(WINDIVERT_ICMPV6HDR));
|
||||
data_len -= sizeof(WINDIVERT_ICMPV6HDR);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (data_len == 0)
|
||||
{
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
WinDivertHelperParsePacketExit:
|
||||
success = TRUE;
|
||||
if (ppIpHdr != NULL)
|
||||
{
|
||||
*ppIpHdr = ip_header;
|
||||
success = success && (ip_header != NULL);
|
||||
}
|
||||
if (ppIpv6Hdr != NULL)
|
||||
{
|
||||
*ppIpv6Hdr = ipv6_header;
|
||||
success = success && (ipv6_header != NULL);
|
||||
}
|
||||
if (ppIcmpHdr != NULL)
|
||||
{
|
||||
*ppIcmpHdr = icmp_header;
|
||||
success = success && (icmp_header != NULL);
|
||||
}
|
||||
if (ppIcmpv6Hdr != NULL)
|
||||
{
|
||||
*ppIcmpv6Hdr = icmpv6_header;
|
||||
success = success && (icmpv6_header != NULL);
|
||||
}
|
||||
if (ppTcpHdr != NULL)
|
||||
{
|
||||
*ppTcpHdr = tcp_header;
|
||||
success = success && (tcp_header != NULL);
|
||||
}
|
||||
if (ppUdpHdr != NULL)
|
||||
{
|
||||
*ppUdpHdr = udp_header;
|
||||
success = success && (udp_header != NULL);
|
||||
}
|
||||
if (pProto != NULL)
|
||||
{
|
||||
*pProto = trans_proto;
|
||||
}
|
||||
if (ppData != NULL)
|
||||
{
|
||||
*ppData = data;
|
||||
success = success && (data != NULL);
|
||||
}
|
||||
if (pDataLen != NULL)
|
||||
{
|
||||
*pDataLen = data_len;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate IPv4/IPv6/ICMP/ICMPv6/TCP/UDP checksums.
|
||||
*/
|
||||
extern UINT WinDivertHelperCalcChecksums(PVOID pPacket, UINT packetLen,
|
||||
PWINDIVERT_ADDRESS pAddr, UINT64 flags)
|
||||
{
|
||||
UINT8 pseudo_header[
|
||||
MAX(sizeof(WINDIVERT_PSEUDOHDR), sizeof(WINDIVERT_PSEUDOV6HDR))];
|
||||
UINT16 pseudo_header_len;
|
||||
PWINDIVERT_IPHDR ip_header;
|
||||
PWINDIVERT_IPV6HDR ipv6_header;
|
||||
PWINDIVERT_ICMPHDR icmp_header;
|
||||
PWINDIVERT_ICMPV6HDR icmpv6_header;
|
||||
PWINDIVERT_TCPHDR tcp_header;
|
||||
PWINDIVERT_UDPHDR udp_header;
|
||||
UINT payload_len, checksum_len;
|
||||
UINT count = 0;
|
||||
|
||||
WinDivertParsePacket(pPacket, packetLen, &ip_header, &ipv6_header,
|
||||
&icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL, NULL,
|
||||
&payload_len);
|
||||
|
||||
if (ip_header != NULL && !(flags & WINDIVERT_HELPER_NO_IP_CHECKSUM))
|
||||
{
|
||||
ip_header->Checksum = 0;
|
||||
if (pAddr == NULL || pAddr->PseudoIPChecksum == 0)
|
||||
{
|
||||
ip_header->Checksum = WinDivertCalcChecksum(NULL, 0,
|
||||
ip_header, ip_header->HdrLength*sizeof(UINT32));
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
if (icmp_header != NULL)
|
||||
{
|
||||
if ((flags & WINDIVERT_HELPER_NO_ICMP_CHECKSUM) != 0)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
icmp_header->Checksum = 0;
|
||||
icmp_header->Checksum = WinDivertCalcChecksum(NULL, 0,
|
||||
icmp_header, payload_len + sizeof(WINDIVERT_ICMPHDR));
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
if (icmpv6_header != NULL)
|
||||
{
|
||||
if ((flags & WINDIVERT_HELPER_NO_ICMPV6_CHECKSUM) != 0)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
checksum_len = payload_len + sizeof(WINDIVERT_ICMPV6HDR);
|
||||
pseudo_header_len = WinDivertInitPseudoHeader(NULL, ipv6_header,
|
||||
IPPROTO_ICMPV6, checksum_len, pseudo_header);
|
||||
icmpv6_header->Checksum = 0;
|
||||
icmpv6_header->Checksum = WinDivertCalcChecksum(pseudo_header,
|
||||
pseudo_header_len, icmpv6_header, checksum_len);
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
if (tcp_header != NULL)
|
||||
{
|
||||
if ((flags & WINDIVERT_HELPER_NO_TCP_CHECKSUM) != 0)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
if (pAddr == NULL || pAddr->PseudoTCPChecksum == 0)
|
||||
{
|
||||
// Full TCP checksum
|
||||
checksum_len = payload_len + tcp_header->HdrLength*sizeof(UINT32);
|
||||
pseudo_header_len = WinDivertInitPseudoHeader(ip_header,
|
||||
ipv6_header, IPPROTO_TCP, checksum_len, pseudo_header);
|
||||
tcp_header->Checksum = 0;
|
||||
tcp_header->Checksum = WinDivertCalcChecksum(
|
||||
pseudo_header, pseudo_header_len, tcp_header, checksum_len);
|
||||
}
|
||||
else if (pAddr->Outbound)
|
||||
{
|
||||
// Pseudo TCP checksum
|
||||
tcp_header->Checksum = 0;
|
||||
}
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
if (udp_header != NULL)
|
||||
{
|
||||
if ((flags & WINDIVERT_HELPER_NO_UDP_CHECKSUM) != 0)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
if (pAddr == NULL || pAddr->PseudoUDPChecksum == 0)
|
||||
{
|
||||
// Full UDP checksum
|
||||
checksum_len = payload_len + sizeof(WINDIVERT_UDPHDR);
|
||||
pseudo_header_len = WinDivertInitPseudoHeader(ip_header,
|
||||
ipv6_header, IPPROTO_UDP, checksum_len, pseudo_header);
|
||||
udp_header->Checksum = 0;
|
||||
udp_header->Checksum = WinDivertCalcChecksum(
|
||||
pseudo_header, pseudo_header_len, udp_header, checksum_len);
|
||||
if (udp_header->Checksum == 0)
|
||||
{
|
||||
udp_header->Checksum = 0xFFFF;
|
||||
}
|
||||
}
|
||||
else if (pAddr->Outbound)
|
||||
{
|
||||
// Pseudo UDP checksum
|
||||
udp_header->Checksum = 0;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the IP/IPv6 pseudo header.
|
||||
*/
|
||||
static UINT16 WinDivertInitPseudoHeader(PWINDIVERT_IPHDR ip_header,
|
||||
PWINDIVERT_IPV6HDR ipv6_header, UINT8 protocol, UINT len,
|
||||
void *pseudo_header)
|
||||
{
|
||||
if (ip_header != NULL)
|
||||
{
|
||||
PWINDIVERT_PSEUDOHDR pseudo_header_v4 =
|
||||
(PWINDIVERT_PSEUDOHDR)pseudo_header;
|
||||
pseudo_header_v4->SrcAddr = ip_header->SrcAddr;
|
||||
pseudo_header_v4->DstAddr = ip_header->DstAddr;
|
||||
pseudo_header_v4->Zero = 0;
|
||||
pseudo_header_v4->Protocol = protocol;
|
||||
pseudo_header_v4->Length = htons((UINT16)len);
|
||||
return sizeof(WINDIVERT_PSEUDOHDR);
|
||||
}
|
||||
else
|
||||
{
|
||||
PWINDIVERT_PSEUDOV6HDR pseudo_header_v6 =
|
||||
(PWINDIVERT_PSEUDOV6HDR)pseudo_header;
|
||||
memcpy(pseudo_header_v6->SrcAddr, ipv6_header->SrcAddr,
|
||||
sizeof(pseudo_header_v6->SrcAddr));
|
||||
memcpy(pseudo_header_v6->DstAddr, ipv6_header->DstAddr,
|
||||
sizeof(pseudo_header_v6->DstAddr));
|
||||
pseudo_header_v6->Length = htonl((UINT32)len);
|
||||
pseudo_header_v6->NextHdr = protocol;
|
||||
pseudo_header_v6->Zero = 0;
|
||||
return sizeof(WINDIVERT_PSEUDOV6HDR);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic checksum computation.
|
||||
*/
|
||||
static UINT16 WinDivertCalcChecksum(PVOID pseudo_header,
|
||||
UINT16 pseudo_header_len, PVOID data, UINT len)
|
||||
{
|
||||
register const UINT16 *data16 = (const UINT16 *)pseudo_header;
|
||||
register size_t len16 = pseudo_header_len >> 1;
|
||||
register UINT32 sum = 0;
|
||||
size_t i;
|
||||
|
||||
// Pseudo header:
|
||||
for (i = 0; i < len16; i++)
|
||||
{
|
||||
sum += (UINT32)data16[i];
|
||||
}
|
||||
|
||||
// Main data:
|
||||
data16 = (const UINT16 *)data;
|
||||
len16 = len >> 1;
|
||||
for (i = 0; i < len16; i++)
|
||||
{
|
||||
sum += (UINT32)data16[i];
|
||||
}
|
||||
|
||||
if (len & 0x1)
|
||||
{
|
||||
const UINT8 *data8 = (const UINT8 *)data;
|
||||
sum += (UINT16)data8[len-1];
|
||||
}
|
||||
|
||||
sum = (sum & 0xFFFF) + (sum >> 16);
|
||||
sum += (sum >> 16);
|
||||
sum = ~sum;
|
||||
return (UINT16)sum;
|
||||
}
|
||||
|
||||
+205
-268
@@ -288,27 +288,6 @@ struct flow_s
|
||||
};
|
||||
typedef struct flow_s *flow_t;
|
||||
|
||||
/*
|
||||
* IPv4/IPv6 pseudo headers.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT32 SrcAddr;
|
||||
UINT32 DstAddr;
|
||||
UINT8 Zero;
|
||||
UINT8 Protocol;
|
||||
UINT16 Length;
|
||||
} WINDIVERT_PSEUDOHDR, *PWINDIVERT_PSEUDOHDR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT32 SrcAddr[4];
|
||||
UINT32 DstAddr[4];
|
||||
UINT32 Length;
|
||||
UINT32 Zero:24;
|
||||
UINT32 NextHdr:8;
|
||||
} WINDIVERT_PSEUDOV6HDR, *PWINDIVERT_PSEUDOV6HDR;
|
||||
|
||||
/*
|
||||
* Misc.
|
||||
*/
|
||||
@@ -2853,6 +2832,59 @@ static NTSTATUS windivert_notify(IN FWPS_CALLOUT_NOTIFY_TYPE type,
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* WinDivert get fixed values.
|
||||
*/
|
||||
static UINT8 windivert_get_val8(const FWPS_INCOMING_VALUES0 *fixed_vals,
|
||||
int idx)
|
||||
{
|
||||
FWP_VALUE0 value = fixed_vals->incomingValue[idx].value;
|
||||
return (value.type != FWP_UINT8? 0: value.uint8);
|
||||
}
|
||||
static UINT16 windivert_get_val16(const FWPS_INCOMING_VALUES0 *fixed_vals,
|
||||
int idx)
|
||||
{
|
||||
FWP_VALUE0 value = fixed_vals->incomingValue[idx].value;
|
||||
return (value.type != FWP_UINT16? 0: value.uint16);
|
||||
}
|
||||
static UINT32 windivert_get_val32(const FWPS_INCOMING_VALUES0 *fixed_vals,
|
||||
int idx)
|
||||
{
|
||||
FWP_VALUE0 value = fixed_vals->incomingValue[idx].value;
|
||||
return (value.type != FWP_UINT32? 0: value.uint32);
|
||||
}
|
||||
static void windivert_get_ipv4_addr(const FWPS_INCOMING_VALUES0 *fixed_vals,
|
||||
int idx, UINT32 *addr)
|
||||
{
|
||||
FWP_VALUE0 value = fixed_vals->incomingValue[idx].value;
|
||||
addr[2] = addr[3] = 0;
|
||||
if (value.type != FWP_UINT32)
|
||||
{
|
||||
addr[0] = addr[1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr[0] = value.uint32;
|
||||
addr[1] = 0x0000FFFF;
|
||||
}
|
||||
}
|
||||
static void windivert_get_ipv6_addr(const FWPS_INCOMING_VALUES0 *fixed_vals,
|
||||
int idx, UINT32 *addr)
|
||||
{
|
||||
UINT8 *addr8 = (UINT8 *)addr;
|
||||
INT i;
|
||||
FWP_VALUE0 value = fixed_vals->incomingValue[idx].value;
|
||||
if (value.type != FWP_BYTE_ARRAY16_TYPE)
|
||||
{
|
||||
RtlZeroMemory(&addr, 16);
|
||||
return;
|
||||
}
|
||||
for (i = 16-1; i >= 0; i--)
|
||||
{
|
||||
addr8[16-i-1] = value.byteArray16->byteArray16[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* WinDivert classify outbound IPv4 function.
|
||||
*/
|
||||
@@ -2870,12 +2902,12 @@ static void windivert_outbound_network_v4_classify(
|
||||
return;
|
||||
}
|
||||
|
||||
network_data.IfIdx = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_OUTBOUND_IPPACKET_V4_INTERFACE_INDEX].value.uint32,
|
||||
network_data.SubIfIdx = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_OUTBOUND_IPPACKET_V4_SUB_INTERFACE_INDEX].value.uint32,
|
||||
loopback = ((fixed_vals->incomingValue[
|
||||
FWPS_FIELD_OUTBOUND_IPPACKET_V4_FLAGS].value.uint32 &
|
||||
network_data.IfIdx = windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_OUTBOUND_IPPACKET_V4_INTERFACE_INDEX);
|
||||
network_data.SubIfIdx = windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_OUTBOUND_IPPACKET_V4_SUB_INTERFACE_INDEX);
|
||||
loopback = ((windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_OUTBOUND_IPPACKET_V4_FLAGS) &
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
|
||||
windivert_network_classify((context_t)filter->context, &network_data,
|
||||
@@ -2900,12 +2932,12 @@ static void windivert_outbound_network_v6_classify(
|
||||
return;
|
||||
}
|
||||
|
||||
network_data.IfIdx = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_OUTBOUND_IPPACKET_V6_INTERFACE_INDEX].value.uint32,
|
||||
network_data.SubIfIdx = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_OUTBOUND_IPPACKET_V6_SUB_INTERFACE_INDEX].value.uint32,
|
||||
loopback = ((fixed_vals->incomingValue[
|
||||
FWPS_FIELD_OUTBOUND_IPPACKET_V6_FLAGS].value.uint32 &
|
||||
network_data.IfIdx = windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_OUTBOUND_IPPACKET_V6_INTERFACE_INDEX);
|
||||
network_data.SubIfIdx = windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_OUTBOUND_IPPACKET_V6_SUB_INTERFACE_INDEX);
|
||||
loopback = ((windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_OUTBOUND_IPPACKET_V6_FLAGS) &
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
|
||||
windivert_network_classify((context_t)filter->context, &network_data,
|
||||
@@ -2931,8 +2963,8 @@ static void windivert_inbound_network_v4_classify(
|
||||
return;
|
||||
}
|
||||
|
||||
loopback = ((fixed_vals->incomingValue[
|
||||
FWPS_FIELD_INBOUND_IPPACKET_V4_FLAGS].value.uint32 &
|
||||
loopback = ((windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_INBOUND_IPPACKET_V4_FLAGS) &
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
if (loopback)
|
||||
{
|
||||
@@ -2940,10 +2972,10 @@ static void windivert_inbound_network_v4_classify(
|
||||
return;
|
||||
}
|
||||
|
||||
network_data.IfIdx = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_INBOUND_IPPACKET_V4_INTERFACE_INDEX].value.uint32;
|
||||
network_data.SubIfIdx = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_INBOUND_IPPACKET_V4_SUB_INTERFACE_INDEX].value.uint32;
|
||||
network_data.IfIdx = windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_INBOUND_IPPACKET_V4_INTERFACE_INDEX);
|
||||
network_data.SubIfIdx = windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_INBOUND_IPPACKET_V4_SUB_INTERFACE_INDEX);
|
||||
advance = meta_vals->ipHeaderSize;
|
||||
|
||||
windivert_network_classify((context_t)filter->context, &network_data,
|
||||
@@ -2968,8 +3000,8 @@ static void windivert_inbound_network_v6_classify(
|
||||
return;
|
||||
}
|
||||
|
||||
loopback = ((fixed_vals->incomingValue[
|
||||
FWPS_FIELD_INBOUND_IPPACKET_V6_FLAGS].value.uint32 &
|
||||
loopback = ((windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_INBOUND_IPPACKET_V6_FLAGS) &
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
if (loopback)
|
||||
{
|
||||
@@ -2977,10 +3009,10 @@ static void windivert_inbound_network_v6_classify(
|
||||
return;
|
||||
}
|
||||
|
||||
network_data.IfIdx = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_INBOUND_IPPACKET_V6_INTERFACE_INDEX].value.uint32;
|
||||
network_data.SubIfIdx = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_INBOUND_IPPACKET_V6_SUB_INTERFACE_INDEX].value.uint32;
|
||||
network_data.IfIdx = windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_INBOUND_IPPACKET_V6_INTERFACE_INDEX);
|
||||
network_data.SubIfIdx = windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_INBOUND_IPPACKET_V6_SUB_INTERFACE_INDEX);
|
||||
advance = meta_vals->ipHeaderSize;
|
||||
|
||||
windivert_network_classify((context_t)filter->context, &network_data,
|
||||
@@ -3003,8 +3035,8 @@ static void windivert_forward_network_v4_classify(
|
||||
return;
|
||||
}
|
||||
|
||||
network_data.IfIdx = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_IPFORWARD_V4_DESTINATION_INTERFACE_INDEX].value.uint32;
|
||||
network_data.IfIdx = windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_IPFORWARD_V4_DESTINATION_INTERFACE_INDEX);
|
||||
network_data.SubIfIdx = 0;
|
||||
|
||||
windivert_network_classify((context_t)filter->context, &network_data,
|
||||
@@ -3028,8 +3060,8 @@ static void windivert_forward_network_v6_classify(
|
||||
return;
|
||||
}
|
||||
|
||||
network_data.IfIdx = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_IPFORWARD_V6_DESTINATION_INTERFACE_INDEX].value.uint32;
|
||||
network_data.IfIdx = windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_IPFORWARD_V6_DESTINATION_INTERFACE_INDEX);
|
||||
network_data.SubIfIdx = 0;
|
||||
|
||||
windivert_network_classify((context_t)filter->context, &network_data,
|
||||
@@ -3248,28 +3280,24 @@ static void windivert_flow_established_v4_classify(
|
||||
UINT64 flow_id;
|
||||
|
||||
flow_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
flow_data.LocalAddr[0] = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_LOCAL_ADDRESS].value.uint32;
|
||||
flow_data.LocalAddr[1] = 0x0000FFFF;
|
||||
flow_data.LocalAddr[2] = 0;
|
||||
flow_data.LocalAddr[3] = 0;
|
||||
flow_data.RemoteAddr[0] = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_REMOTE_ADDRESS].value.uint32;
|
||||
flow_data.RemoteAddr[1] = 0x0000FFFF;
|
||||
flow_data.RemoteAddr[2] = 0;
|
||||
flow_data.RemoteAddr[3] = 0;
|
||||
flow_data.LocalPort = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_LOCAL_PORT].value.uint16;
|
||||
flow_data.RemotePort = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_REMOTE_PORT].value.uint16;
|
||||
flow_data.Protocol = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_PROTOCOL].value.uint8;
|
||||
windivert_get_ipv4_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_LOCAL_ADDRESS,
|
||||
flow_data.LocalAddr);
|
||||
windivert_get_ipv4_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_REMOTE_ADDRESS,
|
||||
flow_data.RemoteAddr);
|
||||
flow_data.LocalPort = windivert_get_val16(fixed_vals,
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_LOCAL_PORT);
|
||||
flow_data.RemotePort = windivert_get_val16(fixed_vals,
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_REMOTE_PORT);
|
||||
flow_data.Protocol = windivert_get_val8(fixed_vals,
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_PROTOCOL);
|
||||
|
||||
outbound = (fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_DIRECTION].value.uint32 ==
|
||||
outbound = (windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_DIRECTION) ==
|
||||
FWP_DIRECTION_OUTBOUND);
|
||||
loopback = ((fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_FLAGS].value.uint32 &
|
||||
loopback = ((windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_FLAGS) &
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
flow_id = meta_vals->flowHandle;
|
||||
|
||||
@@ -3289,37 +3317,26 @@ static void windivert_flow_established_v6_classify(
|
||||
WINDIVERT_DATA_FLOW flow_data;
|
||||
BOOL outbound, loopback;
|
||||
UINT64 flow_id;
|
||||
UINT8 *addr;
|
||||
INT i;
|
||||
|
||||
// IPv6 assumes host byte order, so convert:
|
||||
flow_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
addr = (UINT8 *)&flow_data.LocalAddr;
|
||||
for (i = sizeof(flow_data.LocalAddr)-1; i >= 0; i--)
|
||||
{
|
||||
addr[sizeof(flow_data.LocalAddr)-i-1] = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_IP_LOCAL_ADDRESS]
|
||||
.value.byteArray16->byteArray16[i];
|
||||
}
|
||||
addr = (UINT8 *)&flow_data.RemoteAddr;
|
||||
for (i = sizeof(flow_data.RemoteAddr)-1; i >= 0; i--)
|
||||
{
|
||||
addr[sizeof(flow_data.RemoteAddr)-i-1] = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_IP_REMOTE_ADDRESS]
|
||||
.value.byteArray16->byteArray16[i];
|
||||
}
|
||||
flow_data.LocalPort = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_IP_LOCAL_PORT].value.uint16;
|
||||
flow_data.RemotePort = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_IP_REMOTE_PORT].value.uint16;
|
||||
flow_data.Protocol = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_IP_PROTOCOL].value.uint8;
|
||||
windivert_get_ipv6_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_IP_LOCAL_ADDRESS,
|
||||
flow_data.LocalAddr);
|
||||
windivert_get_ipv6_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_IP_REMOTE_ADDRESS,
|
||||
flow_data.RemoteAddr);
|
||||
flow_data.LocalPort = windivert_get_val16(fixed_vals,
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_IP_LOCAL_PORT);
|
||||
flow_data.RemotePort = windivert_get_val16(fixed_vals,
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_IP_REMOTE_PORT);
|
||||
flow_data.Protocol = windivert_get_val8(fixed_vals,
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_IP_PROTOCOL);
|
||||
|
||||
outbound = (fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_DIRECTION].value.uint32 ==
|
||||
outbound = (windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_DIRECTION) ==
|
||||
FWP_DIRECTION_OUTBOUND);
|
||||
loopback = ((fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_FLAGS].value.uint32 &
|
||||
loopback = ((windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_FLAGS) &
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
flow_id = meta_vals->flowHandle;
|
||||
|
||||
@@ -3518,37 +3535,21 @@ static void windivert_resource_assignment_v4_classify(
|
||||
OUT FWPS_CLASSIFY_OUT0 *result)
|
||||
{
|
||||
WINDIVERT_DATA_SOCKET socket_data;
|
||||
FWP_VALUE0 value;
|
||||
BOOL loopback;
|
||||
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
value = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_IP_LOCAL_ADDRESS].value;
|
||||
if (value.type == FWP_UINT32)
|
||||
{
|
||||
socket_data.LocalAddr[0] = value.uint32;
|
||||
socket_data.LocalAddr[1] = 0x0000FFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
socket_data.LocalAddr[0] = 0;
|
||||
socket_data.LocalAddr[1] = 0;
|
||||
}
|
||||
socket_data.LocalAddr[2] = 0;
|
||||
socket_data.LocalAddr[3] = 0;
|
||||
socket_data.RemoteAddr[0] = 0;
|
||||
socket_data.RemoteAddr[1] = 0;
|
||||
socket_data.RemoteAddr[2] = 0;
|
||||
socket_data.RemoteAddr[3] = 0;
|
||||
value = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_IP_LOCAL_PORT].value;
|
||||
socket_data.LocalPort = (value.type == FWP_UINT16? value.uint16: 0);
|
||||
windivert_get_ipv4_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_IP_LOCAL_ADDRESS,
|
||||
socket_data.LocalAddr);
|
||||
RtlZeroMemory(&socket_data.RemoteAddr, sizeof(socket_data.RemoteAddr));
|
||||
socket_data.LocalPort = windivert_get_val16(fixed_vals,
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_IP_LOCAL_PORT);
|
||||
socket_data.RemotePort = 0;
|
||||
socket_data.Protocol = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_IP_PROTOCOL].value.uint8;
|
||||
socket_data.Protocol = windivert_get_val8(fixed_vals,
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_IP_PROTOCOL);
|
||||
|
||||
loopback = ((fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_FLAGS].value.uint32 &
|
||||
loopback = ((windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_FLAGS) &
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
|
||||
windivert_socket_classify((context_t)filter->context,
|
||||
@@ -3566,43 +3567,21 @@ static void windivert_resource_assignment_v6_classify(
|
||||
OUT FWPS_CLASSIFY_OUT0 *result)
|
||||
{
|
||||
WINDIVERT_DATA_SOCKET socket_data;
|
||||
FWP_VALUE0 value;
|
||||
BOOL loopback;
|
||||
UINT8 *addr;
|
||||
INT i;
|
||||
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
addr = (UINT8 *)&socket_data.LocalAddr;
|
||||
value = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_IP_LOCAL_ADDRESS].value;
|
||||
if (value.type == FWP_BYTE_ARRAY16_TYPE)
|
||||
{
|
||||
for (i = sizeof(socket_data.LocalAddr)-1; i >= 0; i--)
|
||||
{
|
||||
addr[sizeof(socket_data.LocalAddr)-i-1] =
|
||||
value.byteArray16->byteArray16[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
socket_data.LocalAddr[0] = 0;
|
||||
socket_data.LocalAddr[1] = 0;
|
||||
socket_data.LocalAddr[2] = 0;
|
||||
socket_data.LocalAddr[3] = 0;
|
||||
}
|
||||
socket_data.RemoteAddr[0] = 0;
|
||||
socket_data.RemoteAddr[1] = 0;
|
||||
socket_data.RemoteAddr[2] = 0;
|
||||
socket_data.RemoteAddr[3] = 0;
|
||||
value = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_IP_LOCAL_PORT].value;
|
||||
socket_data.LocalPort = (value.type == FWP_UINT16? value.uint16: 0);
|
||||
windivert_get_ipv6_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_IP_LOCAL_ADDRESS,
|
||||
socket_data.LocalAddr);
|
||||
RtlZeroMemory(&socket_data.RemoteAddr, sizeof(socket_data.RemoteAddr));
|
||||
socket_data.LocalPort = windivert_get_val16(fixed_vals,
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_IP_LOCAL_PORT);
|
||||
socket_data.RemotePort = 0;
|
||||
socket_data.Protocol = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_IP_PROTOCOL].value.uint8;
|
||||
socket_data.Protocol = windivert_get_val8(fixed_vals,
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_IP_PROTOCOL);
|
||||
|
||||
loopback = ((fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_FLAGS].value.uint32 &
|
||||
loopback = ((windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_FLAGS) &
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
|
||||
windivert_socket_classify((context_t)filter->context,
|
||||
@@ -3623,25 +3602,21 @@ static void windivert_auth_connect_v4_classify(
|
||||
BOOL loopback;
|
||||
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
socket_data.LocalAddr[0] = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_LOCAL_ADDRESS].value.uint32;
|
||||
socket_data.LocalAddr[1] = 0x0000FFFF;
|
||||
socket_data.LocalAddr[2] = 0;
|
||||
socket_data.LocalAddr[3] = 0;
|
||||
socket_data.RemoteAddr[0] = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_ADDRESS].value.uint32;
|
||||
socket_data.RemoteAddr[1] = 0x0000FFFF;
|
||||
socket_data.RemoteAddr[2] = 0;
|
||||
socket_data.RemoteAddr[3] = 0;
|
||||
socket_data.LocalPort = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_LOCAL_PORT].value.uint16;
|
||||
socket_data.RemotePort = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_PORT].value.uint16;
|
||||
socket_data.Protocol = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_PROTOCOL].value.uint8;
|
||||
windivert_get_ipv4_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_LOCAL_ADDRESS,
|
||||
socket_data.LocalAddr);
|
||||
windivert_get_ipv4_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_ADDRESS,
|
||||
socket_data.RemoteAddr);
|
||||
socket_data.LocalPort = windivert_get_val16(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_LOCAL_PORT);
|
||||
socket_data.RemotePort = windivert_get_val16(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_PORT);
|
||||
socket_data.Protocol = windivert_get_val8(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_PROTOCOL);
|
||||
|
||||
loopback = ((fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V4_FLAGS].value.uint32 &
|
||||
loopback = ((windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V4_FLAGS) &
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
|
||||
windivert_socket_classify((context_t)filter->context,
|
||||
@@ -3660,33 +3635,23 @@ static void windivert_auth_connect_v6_classify(
|
||||
{
|
||||
WINDIVERT_DATA_SOCKET socket_data;
|
||||
BOOL loopback;
|
||||
UINT8 *addr;
|
||||
INT i;
|
||||
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
addr = (UINT8 *)&socket_data.LocalAddr;
|
||||
for (i = sizeof(socket_data.LocalAddr)-1; i >= 0; i--)
|
||||
{
|
||||
addr[sizeof(socket_data.LocalAddr)-i-1] = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V6_IP_LOCAL_ADDRESS]
|
||||
.value.byteArray16->byteArray16[i];
|
||||
}
|
||||
addr = (UINT8 *)&socket_data.RemoteAddr;
|
||||
for (i = sizeof(socket_data.RemoteAddr)-1; i >= 0; i--)
|
||||
{
|
||||
addr[sizeof(socket_data.RemoteAddr)-i-1] = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V6_IP_REMOTE_ADDRESS]
|
||||
.value.byteArray16->byteArray16[i];
|
||||
}
|
||||
socket_data.LocalPort = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_LOCAL_PORT].value.uint16;
|
||||
socket_data.RemotePort = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_PORT].value.uint16;
|
||||
socket_data.Protocol = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_PROTOCOL].value.uint8;
|
||||
windivert_get_ipv6_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V6_IP_LOCAL_ADDRESS,
|
||||
socket_data.LocalAddr);
|
||||
windivert_get_ipv6_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V6_IP_REMOTE_ADDRESS,
|
||||
socket_data.RemoteAddr);
|
||||
socket_data.LocalPort = windivert_get_val16(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V6_IP_LOCAL_PORT);
|
||||
socket_data.RemotePort = windivert_get_val16(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V6_IP_REMOTE_PORT);
|
||||
socket_data.Protocol = windivert_get_val8(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V6_IP_PROTOCOL);
|
||||
|
||||
loopback = ((fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V4_FLAGS].value.uint32 &
|
||||
loopback = ((windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_CONNECT_V6_FLAGS) &
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
|
||||
windivert_socket_classify((context_t)filter->context,
|
||||
@@ -3707,22 +3672,17 @@ static void windivert_auth_listen_v4_classify(
|
||||
BOOL loopback;
|
||||
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
socket_data.LocalAddr[0] = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_LISTEN_V4_IP_LOCAL_ADDRESS].value.uint32;
|
||||
socket_data.LocalAddr[1] = 0x0000FFFF;
|
||||
socket_data.LocalAddr[2] = 0;
|
||||
socket_data.LocalAddr[3] = 0;
|
||||
socket_data.RemoteAddr[0] = 0;
|
||||
socket_data.RemoteAddr[1] = 0;
|
||||
socket_data.RemoteAddr[2] = 0;
|
||||
socket_data.RemoteAddr[3] = 0;
|
||||
socket_data.LocalPort = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_LISTEN_V4_IP_LOCAL_PORT].value.uint16;
|
||||
windivert_get_ipv4_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_LISTEN_V4_IP_LOCAL_ADDRESS,
|
||||
socket_data.LocalAddr);
|
||||
RtlZeroMemory(&socket_data.RemoteAddr, sizeof(socket_data.RemoteAddr));
|
||||
socket_data.LocalPort = windivert_get_val16(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_LISTEN_V4_IP_LOCAL_PORT);
|
||||
socket_data.RemotePort = 0;
|
||||
socket_data.Protocol = IPPROTO_TCP;
|
||||
|
||||
loopback = ((fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_LISTEN_V4_FLAGS].value.uint32 &
|
||||
loopback = ((windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_LISTEN_V4_FLAGS) &
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
|
||||
windivert_socket_classify((context_t)filter->context,
|
||||
@@ -3741,28 +3701,19 @@ static void windivert_auth_listen_v6_classify(
|
||||
{
|
||||
WINDIVERT_DATA_SOCKET socket_data;
|
||||
BOOL loopback;
|
||||
UINT8 *addr;
|
||||
INT i;
|
||||
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
addr = (UINT8 *)&socket_data.LocalAddr;
|
||||
for (i = sizeof(socket_data.LocalAddr)-1; i >= 0; i--)
|
||||
{
|
||||
addr[sizeof(socket_data.LocalAddr)-i-1] = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_LISTEN_V6_IP_LOCAL_ADDRESS]
|
||||
.value.byteArray16->byteArray16[i];
|
||||
}
|
||||
socket_data.RemoteAddr[0] = 0;
|
||||
socket_data.RemoteAddr[1] = 0;
|
||||
socket_data.RemoteAddr[2] = 0;
|
||||
socket_data.RemoteAddr[3] = 0;
|
||||
socket_data.LocalPort = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_LISTEN_V6_IP_LOCAL_PORT].value.uint16;
|
||||
windivert_get_ipv6_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_LISTEN_V6_IP_LOCAL_ADDRESS,
|
||||
socket_data.LocalAddr);
|
||||
RtlZeroMemory(&socket_data.RemoteAddr, sizeof(socket_data.RemoteAddr));
|
||||
socket_data.LocalPort = windivert_get_val16(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_LISTEN_V6_IP_LOCAL_PORT);
|
||||
socket_data.RemotePort = 0;
|
||||
socket_data.Protocol = IPPROTO_TCP;
|
||||
|
||||
loopback = ((fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_LISTEN_V6_FLAGS].value.uint32 &
|
||||
loopback = ((windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_LISTEN_V6_FLAGS) &
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
|
||||
windivert_socket_classify((context_t)filter->context,
|
||||
@@ -3783,25 +3734,21 @@ static void windivert_auth_recv_accept_v4_classify(
|
||||
BOOL loopback;
|
||||
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
socket_data.LocalAddr[0] = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_LOCAL_ADDRESS].value.uint32;
|
||||
socket_data.LocalAddr[1] = 0x0000FFFF;
|
||||
socket_data.LocalAddr[2] = 0;
|
||||
socket_data.LocalAddr[3] = 0;
|
||||
socket_data.RemoteAddr[0] = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_REMOTE_ADDRESS].value.uint32;
|
||||
socket_data.RemoteAddr[1] = 0x0000FFFF;
|
||||
socket_data.RemoteAddr[2] = 0;
|
||||
socket_data.RemoteAddr[3] = 0;
|
||||
socket_data.LocalPort = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_LOCAL_PORT].value.uint16;
|
||||
socket_data.RemotePort = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_REMOTE_PORT].value.uint16;
|
||||
socket_data.Protocol = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_PROTOCOL].value.uint8;
|
||||
windivert_get_ipv4_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_LOCAL_ADDRESS,
|
||||
socket_data.LocalAddr);
|
||||
windivert_get_ipv4_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_REMOTE_ADDRESS,
|
||||
socket_data.RemoteAddr);
|
||||
socket_data.LocalPort = windivert_get_val16(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_LOCAL_PORT);
|
||||
socket_data.RemotePort = windivert_get_val16(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_REMOTE_PORT);
|
||||
socket_data.Protocol = windivert_get_val8(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_PROTOCOL);
|
||||
|
||||
loopback = ((fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_FLAGS].value.uint32 &
|
||||
loopback = ((windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_FLAGS) &
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
|
||||
windivert_socket_classify((context_t)filter->context,
|
||||
@@ -3820,33 +3767,23 @@ static void windivert_auth_recv_accept_v6_classify(
|
||||
{
|
||||
WINDIVERT_DATA_SOCKET socket_data;
|
||||
BOOL loopback;
|
||||
UINT8 *addr;
|
||||
INT i;
|
||||
|
||||
socket_data.ProcessId = (UINT32)meta_vals->processId;
|
||||
addr = (UINT8 *)&socket_data.LocalAddr;
|
||||
for (i = sizeof(socket_data.LocalAddr)-1; i >= 0; i--)
|
||||
{
|
||||
addr[sizeof(socket_data.LocalAddr)-i-1] = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_IP_LOCAL_ADDRESS]
|
||||
.value.byteArray16->byteArray16[i];
|
||||
}
|
||||
addr = (UINT8 *)&socket_data.RemoteAddr;
|
||||
for (i = sizeof(socket_data.RemoteAddr)-1; i >= 0; i--)
|
||||
{
|
||||
addr[sizeof(socket_data.RemoteAddr)-i-1] = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_IP_REMOTE_ADDRESS]
|
||||
.value.byteArray16->byteArray16[i];
|
||||
}
|
||||
socket_data.LocalPort = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_LOCAL_PORT].value.uint16;
|
||||
socket_data.RemotePort = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_REMOTE_PORT].value.uint16;
|
||||
socket_data.Protocol = fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_PROTOCOL].value.uint8;
|
||||
windivert_get_ipv6_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_IP_LOCAL_ADDRESS,
|
||||
socket_data.LocalAddr);
|
||||
windivert_get_ipv6_addr(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_IP_REMOTE_ADDRESS,
|
||||
socket_data.RemoteAddr);
|
||||
socket_data.LocalPort = windivert_get_val16(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_IP_LOCAL_PORT);
|
||||
socket_data.RemotePort = windivert_get_val16(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_IP_REMOTE_PORT);
|
||||
socket_data.Protocol = windivert_get_val8(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_IP_PROTOCOL);
|
||||
|
||||
loopback = ((fixed_vals->incomingValue[
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_FLAGS].value.uint32 &
|
||||
loopback = ((windivert_get_val32(fixed_vals,
|
||||
FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V6_FLAGS) &
|
||||
FWP_CONDITION_FLAG_IS_LOOPBACK) != 0);
|
||||
|
||||
windivert_socket_classify((context_t)filter->context,
|
||||
|
||||
Reference in New Issue
Block a user