Checksum ip packet

0

Galera would like to understand the last 4 lines, why do all these bitswise? Code complete .

Follow the code:

static int in_cksum(u_short *addr, int len)
{
    register int nleft = len;
    register u_short *w = addr;
    register int sum = 0;
    u_short answer = 0;

    /*
     * 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 > 1)  {
        sum += *w++;
        nleft -= 2;
    }

    /* mop up an odd byte, if necessary */
    if (nleft == 1) {
        *(u_char *)(&answer) = *(u_char *)w ;
        sum += answer;
    }


    sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
    sum += (sum >> 16);         /* add carry */
    answer = ~sum;              /* truncate to 16 bits */
    return(answer);
}
    
asked by anonymous 01.02.2016 / 22:48

1 answer

0

After the initial calculations are completed, the variable sum (32 bits) will have any value.

The first expression ( sum = (sum >> 16) + (sum & 0xffff); ) isolates the two 16-bit halves of this value and sums them by putting the result into the original variable

bits    31 30 ... 17 16 // sum >> 16
bits  + 15 14 ... 01 00 // sum & 0xffff
      -----------------
bits xx 15 14 ... 01 00 // xx é o carry

Note that the sum of these two halves will have a maximum of 17 significant bits.

The second expression ( sum += (sum >> 16); ) does (more or less) the same as the first one. The difference is that this expression does not care about what stays in the high bits.

bits    31 30 ... 17 16 15 14 ... 01 00 // sum
bits  +                 31 30 ... 17 16 // sum >> 16
      ---------------------------------
bits xx xx ... xx xx xx 15 14 ... 01 00 // xx é o carry nos high bits

Finally, the third expression ( answer = ~sum; ) exchanges the calculated bits and isolates the 16 low bits because it gets the value into a variable of type u_short .

answer = ~sum;
// bits de ~sum:   31 30 ... 17 16 15 14 ... 01 00
// bits de answer:                 15 14 ... 01 00
    
19.02.2016 / 12:42