title: Calculating IP checksum in C
body: <p>I looked at <a href="https://www.rfc-editor.org/rfc/rfc1071#section-4" rel="nofollow noreferrer">RFC 1071</a> for some information on calculating the IP checksum. For the application I'm making, I need to calculate the IP checksum of a 20 byte IP header (no options). My code is as follows:</p>
  <pre><code>uint16_t calculate_ip_chksum(IP *ip)
  {
      uint16_t *buf = (uint16_t *) ip;
      uint32_t sum = 0;
      uint16_t checksum = 0;
  
      int counter = (ip-&gt;version &amp; 0xF) * 4;
      while (counter &gt; 1)
       {
              sum += *buf++;
              counter -= 2;
       }
  
      if (counter == 1)
              sum += * (uint8_t *) buf;
  
      while (sum &gt;&gt; 16)
              sum = (sum &amp; 0xFFFF) + (sum &gt;&gt; 16);
      checksum = ~sum;
      return checksum;
  }
  </code></pre>
  <p>I defined an IP header as follows:</p>
  <pre><code>typedef struct ip_h
  {
      uint8_t version;
      uint8_t tos;
      uint16_t tot_len;
      uint16_t id;
      uint16_t frag_off;
      uint8_t ttl;
      uint8_t proto;
      uint16_t chksum;
      uint32_t src;
      uint32_t dst;
  
  } IP;
  </code></pre>
  <p>I understand the mathematics of how to calculate the checksum, but I do not understand why my code (which is almost exactly the same as the RFC) does not work.</p>