Richard B. Johnson wrote:
If I were to modify a low byte somewhere by subtracting 1,
would I know that the new checksum, excluding the inversion,
was 0x0000? No. It could be 0xffff.
You're right about information being thrown away, but wrong because IP
checksums are more rigidly defined than that.
RFC1624 was written because the earlier RFC actually got this wrong.
As long as at least one of the checksummed words is known to be
non-zero, 0x0000 is not a possible value. This is true of all IP checksums.
There is only one possible value of the non-complemented sum: 0xffff.
So when you subtract 1 from 0x0001, you get 0xffff.
To do this right, instead of subtracting a word, you add the
complement of the word. After carry-folding, this works out right.
Vishwas Raman wrote:
Are you then suggesting that instead of trying to do an incremental update of the tcp checksum, I set it to 0 and recalculate it from scratch? But I thought that doing that was a big performance hit. Isn't it?
You don't need to recalculate the sum. All routers modify the IP
header checksum when they decrement the TTL of a packet - it's a
widely used algorithm. Equation 3 from RFC1624 is correct :)
Your code looks fine to me. Are you sure you're verifying the
checksum correctly?
while (cksum >> 16)
{
cksum = (cksum & 0xffff) + (cksum >> 16);
}
In general you need to add back the carry bits at most twice, btw.
cksum = (cksum & 0xffff) + (cksum >> 16);
cksum += (cksum >> 16);