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>