1
votes

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!

1

1 Answers

2
votes

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