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.