Calculating IP Checksums:

According to the RFC on IP (RFC 791), the "official" explanation for how to
calculate the IP checksum is as follows:

"The checksum field is the 16 bit one's complement of the one's complement
sum of all 16 bit words in the header."

Unfortunately, this explanation is too simple and is not difficult enough to
understand for normal humans. Thus, the following more complex explanation is
offered as an aid. (It is worth noting, in passing, that the Internet
checksum is such a big deal that an entire RFC is devoted to the topic: RFC
1071, "Computing the Internet Checksum".)

First of all, keep in mind that the checksum is only done on the IP packet's
header; It is NOT applied to the actual data in the IP packet. Also note that
the checksum field is actually part of the header, but while calculating the
checksum, it is considered to be zero. (Otherwise it would create a bizarre
situation in which the correct value for the checksum would become dependant
on itself. Sort of trying to paint a painting of the painting you're making;
You don't know what it's going to look like until you're finished.) Be aware
that calculating IP checksums is probably easiest to do in hexadecimal
notation.

Basically, to calculate an IP header's checksum:

1. Split the header into a series of 16-bit pieces. Add up all of these
16-bit pieces together. (For this example, let's imagine your result of this
operation is 24327 hex.)

2. The result will probably exceed FFFF hex, so remove everything to the left
of the last 4 digits, and add it to them. For example, if the result were
24327, you would strip off the 2 (because it's to the left of the last 4
digits), and then you would add it to them. Lo, the result of this is 4329.

3. Subtract the result from FFFF hex (or 1111111111111111 binary, or 65,535
decimal, or 177777 octal; whichever is easiest for you, they're all the same
number). For example, in the previous example, you ended up with 4329; FFFF
minus 4329 is BCD6.

You now have your IP header checksum. In this case, the checksum field should
be set to BCD6.

This works because the checksum is actually "checked" by simply seeing if all
the 16-bit words of the header add up to FFFF hex. If they do, the packet is
considered "good". If not, the packet is "bad" and gets discarded
immediately. So the whole point is to adjust the checksum value so that it
makes the packet's sum (or more specifically, the sum of the 16-bit words)
equal exactly FFFF.

    Source: geocities.com/siliconvalley/2072

               ( geocities.com/siliconvalley)