Subject: Re: A question about the IP header checksum
To: None <tech-net@NetBSD.org>
From: Alan Barrett <apb@cequrux.com>
List: tech-net
Date: 12/06/2007 11:14:26
On Wed, 05 Dec 2007, John Nemeth wrote:
> On Apr 27,  6:42pm, Alan Barrett wrote:
> } RFC 791 simply refers to one's complement arithmetic without defining
> } it.  In one's complement arithmetic, both 0x0000 and 0xffff represent
> } zero, so I'd say that they are interchangeable, in the absence of extra
> } text in RFC 791 saying that they are not interchangeable.
> 
>      Are you suggesting that if you perform the math and the result is
> either 0x0000 of 0xffff that you need to check the header for both,
> instead of doing a simple comparison?

A simple way of verifying a checksum is to compute the one's complement
sum over the entire packet, including the checksum field, and check that
the result is zero (or 0xffff).  This is often easier than computing
what value the checksum field should have had, and then verifying that
the checksum field actually had that value.

For example,

    sum = 0
    for word in (all 16-bit words in packet):
        sum += word # using two's complement arithmetic
        if above addition generated a carry:
            sum = sum & 0xffff + 1 
    if sum == 0xffff:
        checksum was correct
    else:
        checksum was incorrect

If the checksum is correct, this will always produce a result of 0xffff,
even in the case under discussion where the sender might have had a
choice between storing 0x0000 and 0xffff in the checksum field.  (The
only way the above code can generate a result of 0x0000 is if the input
consists entirely of zeros, which never happens in an IP packet.)

--apb (Alan Barrett)