c++ - Understanding the TCP checksum function -


i believe tcp checksum function following:

  1. break pseudoheader , tcp segment header , data 2 byte blocks.
  2. add 1 byte padding of 0s end of last block if it's not 2 bytes long, make 2 bytes.
  3. take one's complement of sum tcp checksum.

sounds simple enough. hence wrote own generic checksum function:

#include <inttypes.h> #include <arpa/inet.h>  uint16_t checksum(uint16_t * data, int size) {     uint16_t sum = 0;      int = 0, length = size / 2;      while (i < length) sum += data[i++];      if (size % 2) sum += data[i] & 0xff00;      return htons(~sum); } 

however other people have written checksum functions seem more complicated. example:

uint16_t checksum(uint16_t * addr, int len) {     int nleft = len;     int sum = 0;      uint16_t * w = addr;     uint16_t answer = 0;      while (nleft > 1) {         sum += *w++;         nleft -= sizeof(uint16_t);     }      if (nleft == 1) {         *(uint8_t *) (&answer) = *(uint8_t *) w;         sum += answer;     }      sum = (sum >> 16) + (sum & 0xffff);     sum += (sum >> 16);     answer = ~sum;     return (answer); } 

i have few questions regarding code:

  1. what statement *(uint8_t *) (&answer) = *(uint8_t *) w; do?
  2. why take sum as:

    sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); 
  3. did way calculate tcp checksum change?

i don't see why sum = (sum >> 16) + (sum & 0xffff). consider sum 0xabcd:

0xabcd >> 16    == 0x0000  0xabcd & 0xffff == 0xabcd  0x0000 + 0xabcd == 0xabcd 

it seems redundant step. same goes next statement sum += (sum >> 16).

the checksum function appears big-endian processors only.

the first while loop optimized speed.

the &answer trick loads last byte (if there odd number of bytes) high byte of answer, leaving low byte zero, similar code data[i] & 0xff00. way works this

1) take address of answer      (&answer) 2) convert byte pointer  (uint8_t *)   2a) on big endian processor first byte of 16-bit quantity high byte 3) overwrite high byte last byte of data 

the checksum supposed computed carries added in. it's assumed here code running on machine int 32-bits. therefore, (sum & 0xffff) 16-bit checksum, , (sum >> 16) carry bits (if any) need added in. hence, line

sum = (sum >> 16) + (sum & 0xffff); 

adjusts sum include carries. however, line of code generate carry bit. next line sum += (sum >> 16) adds carry (if any) checksum.

finally, take ones-complement of answer. note htons not used since whole function implicitly assumes running on big endian processor.


Comments

Popular posts from this blog

get url and add instance to a model with prefilled foreign key :django admin -

android - Keyboard hides my half of edit-text and button below it even in scroll view -

css - Make div keyboard-scrollable in jQuery Mobile? -