Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Nov 2000 15:56:50 -0500
From:      "Louis A. Mamakos" <louie@TransSys.COM>
To:        Luigi Rizzo <rizzo@aciri.org>
Cc:        ru@FreeBSD.ORG, cmott@scientech.com, archie@dellroad.org, net@FreeBSD.ORG, ari@suutari.iki.fi
Subject:   Re: libalias: Incremental Update of Internet Checksum 
Message-ID:  <200011152056.eAFKuoG68498@whizzo.transsys.com>
In-Reply-To: Your message of "Wed, 15 Nov 2000 12:46:43 PST." <200011152046.MAA00949@iguana.aciri.org> 
References:  <200011152046.MAA00949@iguana.aciri.org> 

next in thread | previous in thread | raw e-mail | index | archive | help
> > > If the above would be true that would mean that almost all implementations
> > > of computing the checksum are wrong, i.e. they produce the value of 0x0000
> > > as a checksum when it should actually be 0xffff.  That would also mean all
> > > three RFCs: 1071, 1141 and 1624 are wrong.  I can't believe that!
> > 
> > But the thing is, both 0xffff and 0x0000 are the same value == 0.  (One is
> 
> hmm... from memory: one of the two 'zero' values is used in UDP to
> indicate NO CHECKSUM. Not sure if the same applies to TCP and IP
> headers as well, but this would explain why the error (if there)
> goes unnoticed.

The +0 == 0x0000 value in the UDP checksum field indicates "no checksum",
while -0 == 0xffff value is the 1's complement of the computed packet
checksum value of zero.

This all makes sense if you consider that the first implementioon of 
these protocols were on 1's complement hardware.  Set the checksum field
to zero, compute the checksum of the packet header, take the 1's complement
(e.g., invert all the bigs) and store the computed value in the checksum
field.  

On actual hardware ALUs, the computed checksum will never be
0xFFFF because the ALU implementations typicaly produce a normalized 
(positive zero) value should the result of an addition be either -0 or
+0.  When you then complement the computed checksum, you'll get the
"correct" value of 0xffff to store in the checksum field of the packet,
and you don't have to do anything special to avoid the distinguished
"no checksum" value of 0xffff.

	From RFC 768:

	Checksum is the 16-bit one's complement of the one's complement sum of a
	pseudo header of information from the IP header, the UDP header, and the
	data,  padded  with zero octets  at the end (if  necessary)  to  make  a
	multiple of two octets.

	The pseudo  header  conceptually prefixed to the UDP header contains the
	source  address,  the destination  address,  the protocol,  and the  UDP
	length.   This information gives protection against misrouted datagrams.
	This checksum procedure is the same as is used in TCP.

	                  0      7 8     15 16    23 24    31 
	                 +--------+--------+--------+--------+
	                 |          source address           |
	                 +--------+--------+--------+--------+
	                 |        destination address        |
	                 +--------+--------+--------+--------+
	                 |  zero  |protocol|   UDP length    |
	                 +--------+--------+--------+--------+

	If the computed  checksum  is zero,  it is transmitted  as all ones (the
	equivalent  in one's complement  arithmetic).   An all zero  transmitted
	checksum  value means that the transmitter  generated  no checksum  (for
	debugging or for higher level protocols that don't care).


louie






To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200011152056.eAFKuoG68498>