InternetGateway on Win10: DNS reply has invalid UDP cksum

Home Forums Discussions Support Portal InternetGateway on Win10: DNS reply has invalid UDP cksum

This topic contains 2 replies, has 2 voices, and was last updated by  demoddie 4 days, 1 hour ago.

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #11036

    demoddie
    Participant

    I ran InternetGateway sample on a machine with Win10 1709. Provider NIC (Intel Pro I219 PCIE) is connected to company’s WIN-Domain. Client NIC is a USB-NIC (Realtek USB GbE Family Controller) connected to another Win10 machine with Intel Pro NIC.
    DNS resolution (e.g. via nslookup) did not work at the other machine (timeout)
    Analysis with wireshark on the different NICs (not via TAP but on Windows via npcap-driver) showed an invalid UDP checksum of the DNS response at the remote Win10 machine. The wireshark at the igateway running machine showed the identical checksum but as valid.
    Maybe this is a problem of the USB-NIC?

    The following code change in snatDlg.cpp. L. 1089 ff. with recalculating the UDP checksum fixed the problem for me. But I do not understand the problem:

    // DNS reply came, substitute source IP back to the original DNS address
    if ((hAdapters[dwIndex]->m_NATState == CLIENT)&&
       (PacketBuffer.m_dwDeviceFlags == PACKET_FLAG_ON_SEND))
    {
    	if (ntohs(pUdpHeader->th_sport) == 53/*DNS port*/)
    	{
    		pIpHeader->ip_src.S_un.S_addr = htonl(hAdapters[dwIndex]->m_LocalDNS.S_un.S_addr);
    		RecalculateUDPChecksum(&PacketBuffer);
    		RecalculateIPChecksum (&PacketBuffer);
    	}
    }
    
    #11037

    Vadim Smirnov
    Moderator

    Yes, you are right, it is bug. You should add UDP checksum recalculation in two places:

    //DNS hook
    //If we receive DNS packet on the NAT client adapter then we redirect it 
    //to this system configured DNS server
    if((pDlg->m_DNSIp.S_un.S_addr != INADDR_ANY) && (pDlg->m_DNSIp.S_un.S_addr != INADDR_NONE))
    {
        if ((hAdapters[dwIndex]->m_NATState == CLIENT)&&
        (PacketBuffer.m_dwDeviceFlags == PACKET_FLAG_ON_RECEIVE))
        {
            if (ntohs(pUdpHeader->th_dport) == 53/*DNS port*/)
            {
                // Save the DNS IP used by the NAT client system
                hAdapters[dwIndex]->m_LocalDNS.S_un.S_addr = ntohl(pIpHeader->ip_dst.S_un.S_addr);
                
                pIpHeader->ip_dst.S_un.S_addr = pDlg->m_DNSIp.S_un.S_addr;
            
                if(bForceRouting) 
                {
                    bNeedToBeRouted = pDlg->IsNeedToForceRouting(pEthHeader->h_dest, pIpHeader->ip_dst.S_un.S_addr, pProviderCard->m_Index);
                }
    
                RecalculateUDPChecksum(&PacketBuffer);
                RecalculateIPChecksum (&PacketBuffer);
            }
        }
    
        // DNS reply came, substitute source IP back to the original DNS address
        if ((hAdapters[dwIndex]->m_NATState == CLIENT)&&
            (PacketBuffer.m_dwDeviceFlags == PACKET_FLAG_ON_SEND))
        {
            if (ntohs(pUdpHeader->th_sport) == 53/*DNS port*/)
            {
                pIpHeader->ip_src.S_un.S_addr = htonl(hAdapters[dwIndex]->m_LocalDNS.S_un.S_addr);
                RecalculateUDPChecksum(&PacketBuffer);
                RecalculateIPChecksum (&PacketBuffer);
            }
        }
    }

    Internet Gateway is a very old sample and I have a newer NAT library implementation (not available for public though) where surprisingly this bug was already fixed.

    #11040

    demoddie
    Participant

    Thank you for your commit.

Viewing 3 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.