Computers do wacky things at times.  Because of their nature, they don't naturally have negative numbers.  There's a couple of choices, two's compliment and one's complimentto do signed numbers.  And I won't even get started on wacky ones (look down further at the one's complement link.  If you dare!)  Why this comp sci talk on a networking blog?

 

Checksums.

 

Data movement can be dangerous work.  It often goes over a lossy media.  Things get dropped, there are bit error rates and all this adds up for the potential of bad, missing or general mischief with the data.  In Ethernet land, we have a packet CRC to help make sure things are okay, but with UDP, TCP and other data movers it might go over Modems, Serial cables, ISDN, ATM, Wireless, avian carriersor signal flags.  So the stacks have their own checksums to make sure that no matter the media they travel over the data can be checked to be valid.  Valid enough I should say since the checksum isn't a guarantee.  But that's a whole 'nother post.

 

For a UDP packet, a checksum value of 0000h means that the packet does not include a checksum. Thus, if the packet is supposed to include a checksum, and the checksum calculation happens to result in a value of 0000h, then the actual value used for the checksum field is FFFFh.  Whoops!  Why?  In the one's complement math system that the stacks use, there is a concept of "negative zero".  FFFFh is negative zero and 0000h is positive zero.  Really.

 

The preferred method of verifying the IP, UDP or TCP checksum is to sum the covered data (in 16-bit quantities) using one's complement arithmetic and comparing the result to FFFFh. If it matches then the checksum is valid; otherwise it is invalid. This method is described in RFC 1071 (section 1, item 3) and in RFC 1624 (section 5).

 

This allows the UDP checksum to be verified without the end system worrying about converting a checksum of 0000h into FFFFh.

It also allows the IP and TCP checksum calculation to use this replacement. Because the values 0000h and FFFFh are equivalent in 1's complement arithmetic, the sum will still be FFFFh for a valid checksum.

 

In order to simplify the design, our hardware always converts a checksum value of 0000h into FFFFh. Because the RFC method accounts for this, there should be no conflict with well-written TCP/IP stacks.  Older DOS stacks and some embedded stripped down stacks are typically the ones that cause trouble.  If you can't correct the behavior of the stack, just turn off checksum offloads and let the stack do it.  Most stacks will use positive zero when its zero and not negative zero.

 

Time for the big review:

1)  In one's complement world of stack checksums, 0000h and FFFFh are both Zero.

2)  Older and stripped down stacks might get that wrong, so watch out.

3)  Thanks for using Intel networking products.