Ethereal-users: Re: [Ethereal-users] Bug in IP/TCP checksum ...

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: "Joshua Nekl" <jnekl@xxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 3 Mar 2001 23:16:15 -0600
Guy,

Thanks for the enlightenment.

I've known how to compute the 2's complement and 1's complement of numbers,
however, the only addition I've ever done has always been in the 2's
complement fashion. I've never done 1's complement addition before and this
was the first I've ever heard of it. Seemed strange at first, adding the
carry back into the LSB. Then, I read on and see why. The resulting 16 bit
addition is independent on both big/little endian architectures. The guys
that came up with the protocol never cease to amaze me on how much they
thought ahead.

Thanks again. I feel ashamed for thinking it was a bug. I should know
better.

Josh




----- Original Message -----
From: "Guy Harris" <gharris@xxxxxxxxxxxx>
To: "Joshua Nekl" <jnekl@xxxxxxxxxxxxxxxxxxxxx>
Cc: <ethereal-users@xxxxxxxxxxxx>
Sent: Saturday, March 03, 2001 6:59 PM
Subject: Re: [Ethereal-users] Bug in IP/TCP checksum ...


On Sat, Mar 03, 2001 at 06:47:19PM -0600, Joshua Nekl wrote:
>       "The checksum field is the 16 bit one's complement of the one's
>       complement sum of all 16 bit words in the header.  For purposes of
>       computing the checksum, the value of the checksum field is zero."
>       ~RFC0791
>
> Not being sure if they meant (take the 1's complement first, then add
them,
> then take the 1's complement again, or add them, then take the 1's
> complement...)

What they meant is

Take the 16 bit one's complement of the result of adding up all
the 16 bit words in the header; the addition in question is done
in one's-complement arithmetic.

See, for example, RFC 1071, "Computing the Internet Checksum":

   (1)  Adjacent octets to be checksummed are paired to form 16-bit
        integers, and the 1's complement sum of these 16-bit integers is
        formed.

   (2)  To generate a checksum, the checksum field itself is cleared,
        the 16-bit 1's complement sum is computed over the octets
        concerned, and the 1's complement of this sum is placed in the
        checksum field.

One way of adding two numbers in one's complement arithmetic is to add
them in two's complement arithmetic and, if the result produced a carry,
one's-complement add 1 to the two's-complement sum.  As the addition is
of 16-bit numbers, the carry would be a carry out of the 16th bit.

See, again, RFC 1071:

        On a 2's complement machine, the 1's complement sum must be
        computed by means of an "end around carry", i.e., any overflows
        from the most significant bits are added into the least
        significant bits. See the examples below.