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!

Était-ce utile?

La 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. [...]

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top