InternetGateway on Win10: DNS reply has invalid UDP cksum

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

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
      Keymaster

        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.