title: how to verify tcp checksum
body: <p>For some odd reason, i'm unable to properly verify the TCP checksum. I have code to check IP and UDP checksum, and it works perfectly fine, but for TCP something in my logic is amiss. </p>
  
  <p>My struct definitions for these headers are fine as i can read the data perfectly fine (verified from wireshark). The only problem i'm having is that for TCP checksum, i'm unable to verify whether the checksum is actually correct. Any thoughts as to where i'm doing this wrong? </p>
  
  <p>Very much appreciated.</p>
  
  <p><strong>checksum function</strong></p>
  
  <pre><code>unsigned short in_cksum(unsigned short *addr,int len)
  {
      register int sum = 0;
      u_short answer = 0;
      register u_short *w = addr;
      register int nleft = len;
  
      /*
       * Our algorithm is simple, using a 32 bit accumulator (sum), we add
       * sequential 16 bit words to it, and at the end, fold back all the
       * carry bits from the top 16 bits into the lower 16 bits.
       */
      while (nleft &gt; 1)  {
              sum += *w++;
              nleft -= 2;
      }
  
      if (nleft == 1) {
              *(u_char *)(&amp;answer) = *(u_char *)w ;
              sum += answer;
      }
  
      sum = (sum &gt;&gt; 16) + (sum &amp; 0xffff);
      sum += (sum &gt;&gt; 16);                
      answer = ~sum;                     
      return(answer);
  }
  </code></pre>
  
  <p><strong>read TCP function (old, check edited version)</strong></p>
  
  <pre><code>/* packets are read using the pcap libraries */
  void readTCP(const u_char *packets) {
     struct TCP_Header *tcp = (struct TCP_Header*) (packets + sizeof(struct Ethernet_Header) + sizeof(struct IP_Header));
     struct IP_Header *ip = (struct IP_Header*) (packets + sizeof(struct Ethernet_Header));
     struct TCP_Pseudo tcpPseudo;
     char tcpcsumblock[sizeof(struct TCP_Pseudo) + sizeof(struct TCP_Header)];
  
     /* tcp pseudo header */
     memset(&amp;tcpPseudo, 0, sizeof(struct TCP_Pseudo));
     tcpPseudo.source_ip = ip-&gt;source_ip.s_addr;
     tcpPseudo.destination_ip = ip-&gt;destination_ip.s_addr;
     tcpPseudo.zero = 0;
     tcpPseudo.protocol = 6;
     tcpPseudo.length = htons(sizeof(struct TCP_Header));
  
     /* grab tcp checksum and reset it */
     int tcpCheckSum = htons(tcp-&gt;tcp_checksum);
     tcp-&gt;tcp_checksum = 0;
  
     /* place the data from the tcp pseudo infront of the tcp header */
     memcpy(tcpcsumblock, &amp;tcpPseudo, sizeof(TCPPseudoHeader));   
     memcpy(tcpcsumblock+sizeof(TCPPseudoHeader),tcp, sizeof(TCPHeader));
  
     /* here is the issue, the checksum that i'm calculating isn't the correct checksum (i checked this by examing the packets from wireshark */
     u_short checksum = in_cksum((unsigned short *)tcpcsumblock, sizeof(tcpcsumblock));
  }
  </code></pre>
  
  <p>==EDIT== </p>
  
  <p><strong>new tcp function</strong></p>
  
  <pre><code>/* packets are read using the pcap libraries */
  void readTCP(const u_char *packets) {
     struct TCP_Header *tcp = (struct TCP_Header*) (packets + sizeof(struct Ethernet_Header) + sizeof(struct IP_Header));
     struct IP_Header *ip = (struct IP_Header*) (packets + sizeof(struct Ethernet_Header));
     struct TCP_Pseudo tcpPseudo;
  
     /* tcp pseudo header */
     memset(&amp;tcpPseudo, 0, sizeof(struct TCP_Pseudo));
     tcpPseudo.source_ip = ip-&gt;source_ip;
     tcpPseudo.destination_ip = ip-&gt;destination_ip;
     tcpPseudo.zero = 0;
     tcpPseudo.protocol = 6;
     tcpPseudo.len = htons(ip-&gt;ip_len - (ip-&gt;ip_hdr_len * 4));
  
     int len = sizeof(struct TCP_Pseudo) + tcpPseudo.len;
     u_char tcpcsumblock[len];
  
     memcpy(tcpcsumblock, &amp;tcpPseudo, sizeof(struct TCP_Pseudo));
     memcpy(tcpcsumblock + sizeof(struct TCP_Pseudo), (packets + sizeof(struct Ethernet_Header) + sizeof(struct IP_Header)), tcpPseudo.len);
  
     /* here is the issue, the checksum that i'm calculating isn't the correct checksum (i checked this by examing the packets from wireshark */
     u_short checksum = in_cksum((unsigned short *)ps_tcp, len);
     char *cs = checksum ? "Invalid Checksum!" : "Valid!";
  }
  </code></pre>
  
  <p><strong>ip header</strong></p>
  
  <pre><code>typedef struct IP_Header {
  #if __BYTE_ORDER__ == __LITTLE_ENDIAN__
     uint8_t ip_hdr_len:4;   /* header length */
     uint8_t ip_version:4;   /* ip version */
  #else
     uint8_t ip_version:4;   /* ip version */
     uint8_t ip_hdr_len:4;   /* The IP header length */
  #endif
  
     uint8_t ip_tos;      /* type of service */
     uint16_t ip_len;     /* total length */
     uint16_t ip_id;      /* identification */
     uint16_t ip_off;     /* fragment offset field */
  #define IP_DF 0x4000            /* dont fragment flag */
  #define IP_MF 0x2000            /* more fragments flag */
  #define IP_OFFMASK 0x1fff       /* mask for fragmenting bits */
     uint8_t  ip_ttl;     /* time to live */
     uint8_t  ip_p;       /* protocol */
     uint16_t ip_sum;     /* checksum */
     struct in_addr ip_src, ip_dst;   /* source and dest address */
  } __attribute__ ((packed));
  </code></pre>
  
  <p><strong>tcp header</strong></p>
  
  <pre><code>typedef struct TCP_Header {
    uint16_t tcp_source_port; /* source port */
    uint16_t tcp_dest_port; /* destination port */
    uint32_t tcp_seq; /* sequence */   
    uint32_t tcp_ack; /* acknowledgement number */
    uint8_t tcp_offest; /* data offset */
  #define TH_OFF(th)      (((th)-&gt;th_offx2 &amp; 0xf0) &gt;&gt; 4)
    uint8_t tcp_flags; /* flags */
  #define TH_FIN      0x01
  #define TH_SYN      0x02
  #define TH_RST      0x04
  #define TH_PUSH     0x08
  #define TH_ACK      0x10
  #define TH_URG      0x20
  #define TH_ECE      0x40
  #define TH_CWR      0x80
  
  #define TH_NS       0x100
  #define TH_RS       0xE00
  
     uint16_t tcp_window; /* window */
     uint16_t tcp_sum; /* checksum */
     uint16_t tcp_urp; /* urgent pointer */
  } __attribute__ ((packed));
  </code></pre>
  
  <p><strong>tcp pseudo header</strong></p>
  
  <pre><code>typedef struct TCP_Pseudo {
     struct in_addr src_ip; /* source ip */
     struct in_addr dest_ip; /* destination ip */
     uint8_t zeroes; /* = 0 */
     uint8_t protocol; /* = 6 */
     uint16_t len; /* length of TCPHeader */
  } __attribute__ ((packed));
  </code></pre>