diff --git a/dll/windivert.c b/dll/windivert.c index 32a4da4..eb4fd28 100644 --- a/dll/windivert.c +++ b/dll/windivert.c @@ -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, diff --git a/dll/windivert_helper.c b/dll/windivert_helper.c index 06976a6..0ffc158 100644 --- a/dll/windivert_helper.c +++ b/dll/windivert_helper.c @@ -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) || diff --git a/include/windivert.h b/include/windivert.h index dfe341d..2c8249f 100644 --- a/include/windivert.h +++ b/include/windivert.h @@ -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. */ diff --git a/sys/windivert.c b/sys/windivert.c index 47dacac..2706043 100644 --- a/sys/windivert.c +++ b/sys/windivert.c @@ -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. */