Move pseduo checksum calculation inside driver.

This means WinDivertSend() no longer needs to
modify the packet and address buffers.  See #134.
This commit is contained in:
basil00
2018-10-26 10:38:35 +08:00
parent 34e8f96910
commit 86db54b400
4 changed files with 37 additions and 482 deletions
-50
View File
@@ -51,19 +51,6 @@
#define WINDIVERT_DRIVER32_SYS L"\\" WINDIVERT_DRIVER_NAME L"32.sys"
#define WINDIVERT_DRIVER64_SYS L"\\" WINDIVERT_DRIVER_NAME L"64.sys"
/*
* 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)
static BOOLEAN WinDivertIsXDigit(char c);
static BOOLEAN WinDivertIsSpace(char c);
static BOOLEAN WinDivertIsAlNum(char c);
@@ -532,41 +519,6 @@ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer,
return handle;
}
/*
* Workaround for #134
*/
static void WinDivertFixChecksums(PVOID pPacket, UINT packetLen,
PWINDIVERT_ADDRESS addr)
{
UINT64 flags =
WINDIVERT_HELPER_NO_IP_CHECKSUM |
WINDIVERT_HELPER_NO_TCP_CHECKSUM |
WINDIVERT_HELPER_NO_UDP_CHECKSUM;
BOOL calc = FALSE;
if (addr->PseudoIPChecksum != 0)
{
addr->PseudoIPChecksum = 0;
flags &= ~WINDIVERT_HELPER_NO_IP_CHECKSUM;
calc = TRUE;
}
if (addr->PseudoTCPChecksum != 0)
{
addr->PseudoTCPChecksum = 0;
flags &= ~WINDIVERT_HELPER_NO_TCP_CHECKSUM;
calc = TRUE;
}
if (addr->PseudoUDPChecksum != 0)
{
addr->PseudoUDPChecksum = 0;
flags &= ~WINDIVERT_HELPER_NO_UDP_CHECKSUM;
calc = TRUE;
}
if (calc)
{
WinDivertHelperCalcChecksums(pPacket, packetLen, addr, flags);
}
}
/*
* Receive a WinDivert packet.
*/
@@ -612,7 +564,6 @@ extern BOOL WinDivertSend(HANDLE handle, PVOID pPacket, UINT packetLen,
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
WinDivertFixChecksums(pPacket, packetLen, addr);
return WinDivertIoControl(handle, IOCTL_WINDIVERT_SEND, 0, (UINT64)addr,
pPacket, packetLen, writelen);
}
@@ -629,7 +580,6 @@ extern BOOL WinDivertSendEx(HANDLE handle, PVOID pPacket, UINT packetLen,
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
WinDivertFixChecksums(pPacket, packetLen, addr);
if (overlapped == NULL)
{
return WinDivertIoControl(handle, IOCTL_WINDIVERT_SEND, 0,
+3 -415
View File
@@ -252,8 +252,6 @@ typedef UINT64 ERROR, *PERROR;
#define IS_ERROR(err) \
(GET_CODE(err) != WINDIVERT_ERROR_NONE)
#define MAX(a, b) ((a) > (b)? (a): (b))
/*
* Prototypes.
*/
@@ -261,233 +259,11 @@ static PEXPR WinDivertParseFilter(HANDLE pool, TOKEN *toks, UINT *i,
INT depth, BOOL and, PERROR error);
static BOOL WinDivertCondExecFilter(PWINDIVERT_FILTER filter, UINT length,
UINT8 field, UINT32 arg);
static UINT16 WinDivertInitPseudoHeader(PWINDIVERT_IPHDR ip_header,
PWINDIVERT_IPV6HDR ipv6_header, UINT8 protocol, UINT len,
void *pseudo_header);
static UINT16 WinDivertHelperCalcChecksum(PVOID pseudo_header,
UINT16 pseudo_header_len, PVOID data, UINT len);
static BOOL WinDivertDeserializeFilter(PWINDIVERT_STREAM stream,
PWINDIVERT_FILTER filter, UINT *length);
static void WinDivertFormatExpr(PWINDIVERT_STREAM stream, PEXPR expr,
BOOL top_level, BOOL and);
/*
* 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 WinDivertHelperParsePacket_2(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;
}
/*
* Parse IPv4/IPv6/ICMP/ICMPv6/TCP/UDP headers from a raw packet.
*/
@@ -497,196 +273,8 @@ extern BOOL WinDivertHelperParsePacket(PVOID pPacket, UINT packetLen,
PWINDIVERT_TCPHDR *ppTcpHdr, PWINDIVERT_UDPHDR *ppUdpHdr, PVOID *ppData,
UINT *pDataLen)
{
return WinDivertHelperParsePacket_2(pPacket, packetLen, ppIpHdr,
ppIpv6Hdr, ppIcmpHdr, ppIcmpv6Hdr, ppTcpHdr, ppUdpHdr, NULL,
ppData, pDataLen);
}
/*
* 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;
WinDivertHelperParsePacket_2(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 = WinDivertHelperCalcChecksum(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 = WinDivertHelperCalcChecksum(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 = WinDivertHelperCalcChecksum(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 = WinDivertHelperCalcChecksum(
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 = WinDivertHelperCalcChecksum(
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 WinDivertHelperCalcChecksum(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;
return WinDivertParsePacket(pPacket, packetLen, ppIpHdr, ppIpv6Hdr,
ppIcmpHdr, ppIcmpv6Hdr, ppTcpHdr, ppUdpHdr, NULL, ppData, pDataLen);
}
/*
@@ -2563,7 +2151,7 @@ extern BOOL WinDivertHelperEvalFilter(const char *filter, PVOID packet,
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
WinDivertHelperParsePacket_2(packet, packet_len, &iphdr, &ipv6hdr,
WinDivertParsePacket(packet, packet_len, &iphdr, &ipv6hdr,
&icmphdr, &icmpv6hdr, &tcphdr, &udphdr, &protocol, NULL,
&payload_len);
if ((addr->IPv6 && ipv6hdr == NULL) ||
+2 -2
View File
@@ -413,8 +413,6 @@ typedef struct
UINT16 Checksum;
} WINDIVERT_UDPHDR, *PWINDIVERT_UDPHDR;
#ifndef WINDIVERT_KERNEL
/*
* Flags for WinDivertHelperCalcChecksums()
*/
@@ -424,6 +422,8 @@ typedef struct
#define WINDIVERT_HELPER_NO_TCP_CHECKSUM 8
#define WINDIVERT_HELPER_NO_UDP_CHECKSUM 16
#ifndef WINDIVERT_KERNEL
/*
* Parse IPv4/IPv6/ICMP/ICMPv6/TCP/UDP headers from a raw packet.
*/
+32 -15
View File
@@ -663,7 +663,7 @@ static struct layer_s layer_resource_assignment_ipv4_0 =
0
};
static layer_t layer_resource_assignment_ipv4 =
&layer_resource_assignment_ipv4_0;
&layer_resource_assignment_ipv4_0;
static struct layer_s layer_resource_assignment_ipv6_0 =
{
@@ -680,7 +680,7 @@ static struct layer_s layer_resource_assignment_ipv6_0 =
0
};
static layer_t layer_resource_assignment_ipv6 =
&layer_resource_assignment_ipv6_0;
&layer_resource_assignment_ipv6_0;
static struct layer_s layer_auth_connect_ipv4_0 =
{
@@ -810,6 +810,11 @@ static struct layer_s layer_flow_established_ipv6_0 =
};
static layer_t layer_flow_established_ipv6 = &layer_flow_established_ipv6_0;
/*
* Shared functions.
*/
#include "windivert_shared.c"
/*
* WinDivert malloc/free.
*/
@@ -887,18 +892,18 @@ extern NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver_obj,
FWPM_LAYER_ALE_FLOW_ESTABLISHED_V4;
layer_flow_established_ipv6->layer_guid =
FWPM_LAYER_ALE_FLOW_ESTABLISHED_V6;
layer_resource_assignment_ipv4->layer_guid =
layer_resource_assignment_ipv4->layer_guid =
FWPM_LAYER_ALE_RESOURCE_ASSIGNMENT_V4;
layer_resource_assignment_ipv6->layer_guid =
layer_resource_assignment_ipv6->layer_guid =
FWPM_LAYER_ALE_RESOURCE_ASSIGNMENT_V6;
layer_auth_connect_ipv4->layer_guid = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
layer_auth_connect_ipv6->layer_guid = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
layer_auth_listen_ipv4->layer_guid = FWPM_LAYER_ALE_AUTH_LISTEN_V4;
layer_auth_listen_ipv6->layer_guid = FWPM_LAYER_ALE_AUTH_LISTEN_V6;
layer_auth_recv_accept_ipv4->layer_guid =
FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4;
FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4;
layer_auth_recv_accept_ipv6->layer_guid =
FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6;
FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6;
layer_inbound_network_ipv4->sublayer_guid =
WINDIVERT_SUBLAYER_INBOUND_IPV4_GUID;
layer_outbound_network_ipv4->sublayer_guid =
@@ -2119,7 +2124,7 @@ static NTSTATUS windivert_write(context_t context, WDFREQUEST request,
BOOL ipv4;
UINT8 layer;
UINT32 priority;
UINT64 flags;
UINT64 flags, checksums;
HANDLE handle, compl_handle;
PNET_BUFFER_LIST buffers = NULL;
NTSTATUS status = STATUS_SUCCESS;
@@ -2183,6 +2188,7 @@ windivert_write_bad_packet:
goto windivert_write_exit;
}
// Copy packet data:
data_copy = windivert_malloc(data_len, FALSE);
if (data_copy == NULL)
{
@@ -2191,7 +2197,6 @@ windivert_write_bad_packet:
status);
goto windivert_write_exit;
}
RtlCopyMemory(data_copy, data, sizeof(WINDIVERT_IPHDR));
ip_header = (PWINDIVERT_IPHDR)data_copy;
switch (ip_header->Version)
@@ -2225,6 +2230,19 @@ windivert_write_bad_packet:
(char *)data + sizeof(WINDIVERT_IPHDR),
data_len - sizeof(WINDIVERT_IPHDR));
}
// Fix checksums:
if (addr->PseudoIPChecksum != 0 || addr->PseudoTCPChecksum != 0 ||
addr->PseudoUDPChecksum != 0)
{
checksums =
(addr->PseudoIPChecksum? 0: WINDIVERT_HELPER_NO_IP_CHECKSUM) |
(addr->PseudoTCPChecksum? 0: WINDIVERT_HELPER_NO_TCP_CHECKSUM) |
(addr->PseudoUDPChecksum? 0: WINDIVERT_HELPER_NO_UDP_CHECKSUM);
WinDivertHelperCalcChecksums(data_copy, data_len, NULL, checksums);
}
// Decrement TTL for impostor packets:
if (addr->Impostor && !windivert_decrement_ttl(data_copy, ipv4,
(addr->PseudoIPChecksum == 0)))
{
@@ -2232,6 +2250,7 @@ windivert_write_bad_packet:
goto windivert_write_exit;
}
// Allocate packet:
mdl_copy = IoAllocateMdl(data_copy, data_len, FALSE, FALSE, NULL);
if (mdl_copy == NULL)
{
@@ -2239,7 +2258,6 @@ windivert_write_bad_packet:
DEBUG_ERROR("failed to allocate MDL for injected packet", status);
goto windivert_write_exit;
}
MmBuildMdlForNonPagedPool(mdl_copy);
status = FwpsAllocateNetBufferAndNetBufferList0(nbl_pool_handle, 0, 0,
mdl_copy, 0, data_len, &buffers);
@@ -2250,6 +2268,7 @@ windivert_write_bad_packet:
goto windivert_write_exit;
}
// Inject packet:
handle = (ipv4? inject_handle: injectv6_handle);
compl_handle = ((flags & WINDIVERT_FLAG_DEBUG) != 0? (HANDLE)request: NULL);
if (layer == WINDIVERT_LAYER_NETWORK_FORWARD)
@@ -3521,7 +3540,7 @@ static void windivert_resource_assignment_v4_classify(
socket_data.RemoteAddr[2] = 0;
socket_data.RemoteAddr[3] = 0;
value = fixed_vals->incomingValue[
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_IP_LOCAL_PORT].value;
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_IP_LOCAL_PORT].value;
socket_data.LocalPort = (value.type == FWP_UINT16? value.uint16: 0);
socket_data.RemotePort = 0;
socket_data.Protocol = fixed_vals->incomingValue[
@@ -3575,7 +3594,7 @@ static void windivert_resource_assignment_v6_classify(
socket_data.RemoteAddr[2] = 0;
socket_data.RemoteAddr[3] = 0;
value = fixed_vals->incomingValue[
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_IP_LOCAL_PORT].value;
FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_IP_LOCAL_PORT].value;
socket_data.LocalPort = (value.type == FWP_UINT16? value.uint16: 0);
socket_data.RemotePort = 0;
socket_data.Protocol = fixed_vals->incomingValue[
@@ -3697,7 +3716,7 @@ static void windivert_auth_listen_v4_classify(
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;
FWPS_FIELD_ALE_AUTH_LISTEN_V4_IP_LOCAL_PORT].value.uint16;
socket_data.RemotePort = 0;
socket_data.Protocol = IPPROTO_TCP;
@@ -3737,7 +3756,7 @@ static void windivert_auth_listen_v6_classify(
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;
FWPS_FIELD_ALE_AUTH_LISTEN_V6_IP_LOCAL_PORT].value.uint16;
socket_data.RemotePort = 0;
socket_data.Protocol = IPPROTO_TCP;
@@ -5456,8 +5475,6 @@ windivert_filter_compile_error:
/* WINDIVERT REFLECT MANAGER IMPLEMENTATION */
/****************************************************************************/
#include "windivert_shared.c"
/*
* WinDivert reflect state.
*/