title: UDP checksum error c++
body: <p>I am calculating UDP checksum using the following function (found it somewhere):</p>
  
  <pre><code>   uint16_t udp_checksum(const void *buff, size_t len, in_addr_t src_addr, in_addr_t dest_addr)
       {
               const uint16_t *buf=(const uint16_t *)buff;
               uint16_t *ip_src=(uint16_t *)&amp;src_addr,
                        *ip_dst=(uint16_t *)&amp;dest_addr;
               uint32_t sum;
               size_t length=len;
  
  
           // Calculate the sum                                      
           sum = 0;
           while (len &gt; 1)
           {
                   sum += *buf++;
                   if (sum &amp; 0x80000000)
                           sum = (sum &amp; 0xFFFF) + (sum &gt;&gt; 16);
                   len -= 2;
           }
  
           if ( len &amp; 1 )
                   // Add the padding if the packet length is odd         
                   sum += *((uint8_t *)buf);
  
           // Add the pseudo-header                                       
           sum += *(ip_src++);
           sum += *ip_src;
  
           sum += *(ip_dst++);
           sum += *ip_dst;
  
           sum += htons(IPROTO_UDP);
           sum += htons(length);
  
       // Add the carries                                              
           while (sum &gt;&gt; 16)
                   sum = (sum &amp; 0xFFFF) + (sum &gt;&gt; 16);
  
           // Return the one's complement of sum                           
           return ( (uint16_t)(~sum)  );
   }
  
  
  
      int form_checksums(char * buff)
      {
        // Get IP and UDP headers
        IP_Header* ipHdr  = (IP_Header*)(buff);
        struct UDP_Header* udpHdr = (struct UDP_Header*) (buff + 4*ipHdr-&gt;ihl);
  
        //---- Form and fill IP checksum now--------------------------------------
        ipHdr-&gt;check = 0;
        ipHdr-&gt;check = in_cksum((unsigned short *)ipHdr, sizeof(*ipHdr));
  
  
        //---- calculate and fill udp checksum now ---
        udpHdr-&gt;checksum = 0;
  
        udpHdr-&gt;checksum = udp_checksum(buff + 4*ipHdr-&gt;ihl, udpHdr-&gt;length, ipHdr-&gt;saddr, ipHdr-&gt;daddr); 
  
        return 0;
      }
  </code></pre>
  
  <p>Wireshark shows that the wrong UDP checksum is calculated. I don't see any problem in the function. What can be going wrong?</p>