Question

I have two questions:

  1. RFC 793 states that the checksum should be computed over a 96-bit pseudo-header, the tcp header and the data. The pseudo-header includes the source and destination IP address. Doesn't this defeat the whole idea of keeping the layers seperate, because now when the network layer starts using addresses of a different size, the transport layer needs to change as well.

  2. In another SO post i found the following java code to calculate the checksum.

     private long computeChecksum( byte[] buf ){
         int length = buf.length;
         int i = 0;
         long sum = 0;
         long data;
    
         // loop through all 16-bit words unless there's 0 or 1 byte left.
         while( length > 1 ){
             data = ( ((buf[i] << 8) & 0xFF00) | ((buf[i + 1]) & 0xFF));
             sum += data;
             if( (sum & 0xFFFF0000) > 0 ){
                 sum = sum & 0xFFFF;
                 sum += 1;
             }
             i += 2;
             length -= 2;
         }
    
         if (length > 0 ){ // ie. there are 8 bits of data remaining.
             sum += (buf[i] << 8 & 0xFF00); // create a 16 bit word where the 8 lsb are 0's and add it to the sum.
             if( (sum & 0xFFFF0000) > 0) {
                 sum = sum & 0xFFFF;
                 sum += 1;
             }
         }
    
         sum = ~sum; 
         sum = sum & 0xFFFF;
         return sum;
     }
    

There are some things of which I dont understand why they are needed in that code. First in:

data = ( ((buf[i] << 8) & 0xFF00) | ((buf[i + 1]) & 0xFF));

what is the need for the binary AND's? I don't understand because buf[i] is a byte but is treated as an int and shifted by 8 bits to the left. Doesn't that already guarantee that the result looks like: 00000000 00000000 ???????? 00000000.

Also why are sum and data declared as long? As I see it, both variables will never use more then 17 bits, so why cant we just use an int? In the end they even do: sum = sum & 0xFFFF which discards anything but the 16 least significant bits.

Thanks!

Was it helpful?

Solution

Doesn't this defeat the whole idea of keeping the layers seperate, because now when the network layer starts using addresses of a different size, the transport layer needs to change as well.

Yes. And indeed, this is why RFC 2460 redefines the pseudo-header for IPv6:

Any transport or other upper-layer protocol that includes the addresses from the IP header in its checksum computation must be modified for use over IPv6, to include the 128-bit IPv6 addresses instead of 32-bit IPv4 addresses. [...]

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top