Discussion:
A question about the IP header checksum
(too old to reply)
p***@klos.com
2007-12-05 20:52:28 UTC
Permalink
Hello IP Gurus,

I have a question about the IP header checksum that I'm looking for a
definitive answer for. I'm pretty sure I have the answer, but if anyone
can help me substantiate my answer, it would really help.

The IP header checksum is pretty straightforward: add up all the (2 byte)
words in the IP header using one's complement addition, then take the one's
complement of the sum and insert that as the checksum. Here's the question:

Is it proper to substitute a resulting value of 0x0000 with 0xffff as
is done in UDP?

UDP explicitly defines 0x0000 as "checksum disabled", and so specifies that
a computed result of 0x0000 should be replaced with 0xffff. TCP and IP do
not state anything more than "take the one's complement of the one's
complement sum of the words...".

What do you think?

Thanks,

Patrick Klos
========= For LAN/WAN Protocol Analysis, check out PacketView Pro! =========
Patrick Klos Email: ***@klos.com
Network/Embedded Software Engineer Web: http://www.klos.com/
Klos Technologies, Inc. Phone: 603-714-0195
============================================================================

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
der Mouse
2007-12-05 21:07:57 UTC
Permalink
The IP header checksum is pretty straightforward: [...] Here's the
question: Is it proper to substitute a resulting value of 0x0000 with
0xffff as is done in UDP?
I can't see anything wrong with it.

I doubt it's necessary, but I have trouble seeing it causing trouble.

But I'm not an IP guru, so....

/~\ The ASCII der Mouse
\ / Ribbon Campaign
X Against HTML ***@rodents.montreal.qc.ca
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
John Nemeth
2007-12-05 21:26:13 UTC
Permalink
On Mar 23, 12:59am, ***@klos.com wrote:
}
} I have a question about the IP header checksum that I'm looking for a
} definitive answer for. I'm pretty sure I have the answer, but if anyone
} can help me substantiate my answer, it would really help.
}
} The IP header checksum is pretty straightforward: add up all the (2 byte)
} words in the IP header using one's complement addition, then take the one's
} complement of the sum and insert that as the checksum. Here's the question:
}
} Is it proper to substitute a resulting value of 0x0000 with 0xffff as
} is done in UDP?

No. This question could easily be answered by checking the RFC
for IP (it is fairly easy to read). See
ftp://ftp.rfc-editor.org/in-notes/rfc791.txt .

} ========= For LAN/WAN Protocol Analysis, check out PacketView Pro! =========

Interesting that you are advertising something like this when you
have to ask trivial questions about the most commonly used protocol!

}-- End of excerpt from ***@klos.com

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
der Mouse
2007-12-05 21:46:04 UTC
Permalink
Post by p***@klos.com
Is it proper to substitute a resulting value of 0x0000 with 0xffff
[in the IP header checksum] as is done in UDP?
No. This question could easily be answered by checking the RFC for
IP (it is fairly easy to read). See
ftp://ftp.rfc-editor.org/in-notes/rfc791.txt .
Citation? I just had a look, and I don't find anything that would
forbid using ffff when the computed checksum is 0000. But I don't have
time to reread the whole thing now, so I depended on searching for
"checksum". What did I miss?

/~\ The ASCII der Mouse
\ / Ribbon Campaign
X Against HTML ***@rodents.montreal.qc.ca
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Alan Barrett
2007-12-05 22:07:12 UTC
Permalink
Post by John Nemeth
} Is it proper to substitute a resulting value of 0x0000 with 0xffff as
} is done in UDP?
No. This question could easily be answered by checking the RFC
for IP (it is fairly easy to read). See
ftp://ftp.rfc-editor.org/in-notes/rfc791.txt .
RFC 791 simply refers to one's complement arithmetic without defining
it. In one's complement arithmetic, both 0x0000 and 0xffff represent
zero, so I'd say that they are interchangeable, in the absence of extra
text in RFC 791 saying that they are not interchangeable.

--apb (Alan Barrett)

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
p***@klos.com
2007-12-06 00:44:45 UTC
Permalink
Post by John Nemeth
}
} I have a question about the IP header checksum that I'm looking for a
} definitive answer for. I'm pretty sure I have the answer, but if anyone
} can help me substantiate my answer, it would really help.
}
} The IP header checksum is pretty straightforward: add up all the (2 byte)
} words in the IP header using one's complement addition, then take the one's
}
} Is it proper to substitute a resulting value of 0x0000 with 0xffff as
} is done in UDP?
No. This question could easily be answered by checking the RFC
for IP (it is fairly easy to read). See
ftp://ftp.rfc-editor.org/in-notes/rfc791.txt .
Thanks, I've read RFC 791 plenty of times. It doesn't explicitly address
the idea that one's complement systems have 2 representations for 0 (all
zeros and all ones). That's why I asked the people who have implemented
and used IP stacks at this level.

Someone suggested I look at RFC 1122 which states "zero and 65535 are
equivalent in 1's complement arithmetic" under the UDP checksum section,
reinforcing the idea that they should be considered equivalent. I also
looked at RFC 1071 which states in section (3) of paragraph 1 that the
checksum result should be all ones for a good result.

I'm finding the concensus to be that implementations should consider 0x0000
and 0xffff to be equivalent when computing the checksum. This is based on
the idea that in one's complement, there are 2 forms of 0 (0x0000 and 0xffff)
and they are considered equivalent.

This all came about because a customer of ours ran across a packet with the
following IP header:

45 00 05 DC 7B 0D 00 00 FE 2F FF FF C0 A8 DD 0A
C0 A8 DD 89

The one's complement sum of the IP header (not including the checksum field)
is 0xffff. Most implementations will take the one's complement of that
with a simple XOR of 0xffff resulting in a checksum field of 0x0000. Since
0x0000 is mathematically equivalent to 0xffff in one's complement math,
setting the checksum field to 0xffff, while unexpected, is not mathematically
incorrect.
Post by John Nemeth
} ========= For LAN/WAN Protocol Analysis, check out PacketView Pro! =========
Interesting that you are advertising something like this when you
have to ask trivial questions about the most commonly used protocol!
I think it's interesting that I found the mailing list's "Mr. Smarty-pants"
on my first posting to this mailing list. Nice to meet you. ;^)

Patrick
========= For LAN/WAN Protocol Analysis, check out PacketView Pro! =========
Patrick Klos Email: ***@klos.com
Network/Embedded Software Engineer Web: http://www.klos.com/
Klos Technologies, Inc. Phone: 603-714-0195
============================================================================

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Alan Barrett
2007-12-05 22:00:54 UTC
Permalink
Post by p***@klos.com
The IP header checksum is pretty straightforward: add up all the (2 byte)
words in the IP header using one's complement addition, then take the one's
Is it proper to substitute a resulting value of 0x0000 with 0xffff as
is done in UDP?
Yes, 0x0000 and 0xffff are interchangeable in IP and TCP checksums,
though 0x0000 is special in UDP checksums.

--apb (Alan Barrett)

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Erik Fair
2007-12-05 22:46:42 UTC
Permalink
See sec 4.1.3.4 of RFC 1122 ("Requirements for Internet Hosts --
Communication Layers"). RFC 1122 and 1123 cleaned up and clarified a
wide range of ambiguities the original specifications.

Erik <***@netbsd.org>


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
der Mouse
2007-12-05 23:56:12 UTC
Permalink
See sec 4.1.3.4 of RFC 1122 ...
... is about UDP checksums. I believe this question is about IP
checksums.

(That cite *does* make it clear that 0000 and ffff are interchangable
in one's-complement arithmetic, though.)

/~\ The ASCII der Mouse
\ / Ribbon Campaign
X Against HTML ***@rodents.montreal.qc.ca
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
John Nemeth
2007-12-05 22:26:05 UTC
Permalink
On Apr 27, 6:36pm, Alan Barrett wrote:
} On Wed, 05 Dec 2007, ***@klos.com wrote:
} > The IP header checksum is pretty straightforward: add up all the (2 byte)
} > words in the IP header using one's complement addition, then take the one's
} > complement of the sum and insert that as the checksum. Here's the question:
} >
} > Is it proper to substitute a resulting value of 0x0000 with 0xffff as
} > is done in UDP?
}
} Yes, 0x0000 and 0xffff are interchangeable in IP and TCP checksums,
} though 0x0000 is special in UDP checksums.

Umm, RFC 791 says this:

-----

Header Checksum: 16 bits

A checksum on the header only. Since some header fields change
(e.g., time to live), this is recomputed and verified at each point
that the internet header is processed.

The checksum algorithm is:

The checksum field is the 16 bit one's complement of the one's
complement sum of all 16 bit words in the header. For purposes of
computing the checksum, the value of the checksum field is zero.

This is a simple to compute checksum and experimental evidence
indicates it is adequate, but it is provisional and may be replaced
by a CRC procedure, depending on further experience.

-----
From that, how do you get that 0x0000 and 0xffff are equivalent?
}-- End of excerpt from Alan Barrett

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
der Mouse
2007-12-05 23:57:43 UTC
Permalink
Umm, RFC 791 says this: [...]
From that, how do you get that 0x0000 and 0xffff are equivalent?
"one's complement".

/~\ The ASCII der Mouse
\ / Ribbon Campaign
X Against HTML ***@rodents.montreal.qc.ca
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
John Nemeth
2007-12-06 00:19:06 UTC
Permalink
On Apr 27, 6:42pm, Alan Barrett wrote:
} On Wed, 05 Dec 2007, John Nemeth wrote:
} > } Is it proper to substitute a resulting value of 0x0000 with 0xffff as
} > } is done in UDP?
} >
} > No. This question could easily be answered by checking the RFC
} > for IP (it is fairly easy to read). See
} > ftp://ftp.rfc-editor.org/in-notes/rfc791.txt .
}
} RFC 791 simply refers to one's complement arithmetic without defining
} it. In one's complement arithmetic, both 0x0000 and 0xffff represent
} zero, so I'd say that they are interchangeable, in the absence of extra
} text in RFC 791 saying that they are not interchangeable.

Are you suggesting that if you perform the math and the result is
either 0x0000 of 0xffff that you need to check the header for both,
instead of doing a simple comparison?

}-- End of excerpt from Alan Barrett

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
der Mouse
2007-12-06 00:46:24 UTC
Permalink
Post by John Nemeth
[...one's complement arithmetic...0x0000...0xffff...]
Are you suggesting that if you perform the math and the result is
either 0x0000 of 0xffff that you need to check the header for both,
instead of doing a simple comparison?
Well, note that the checksum is defined as the _complement of_ the sum
of the headers words. This suggests to me that the intended design is
to just sum up the words in a received packet and check that the sum is
zero.

Depending on how you compute the sum, it's even possible to arrange
that you get only one of the two zero values. This means that checking
sums can be done by summing and then doing a simple compare against
whichever zero value is the one your algorithm generates.

/~\ The ASCII der Mouse
\ / Ribbon Campaign
X Against HTML ***@rodents.montreal.qc.ca
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Alan Barrett
2007-12-06 09:14:26 UTC
Permalink
Post by John Nemeth
} RFC 791 simply refers to one's complement arithmetic without defining
} it. In one's complement arithmetic, both 0x0000 and 0xffff represent
} zero, so I'd say that they are interchangeable, in the absence of extra
} text in RFC 791 saying that they are not interchangeable.
Are you suggesting that if you perform the math and the result is
either 0x0000 of 0xffff that you need to check the header for both,
instead of doing a simple comparison?
A simple way of verifying a checksum is to compute the one's complement
sum over the entire packet, including the checksum field, and check that
the result is zero (or 0xffff). This is often easier than computing
what value the checksum field should have had, and then verifying that
the checksum field actually had that value.

For example,

sum = 0
for word in (all 16-bit words in packet):
sum += word # using two's complement arithmetic
if above addition generated a carry:
sum = sum & 0xffff + 1
if sum == 0xffff:
checksum was correct
else:
checksum was incorrect

If the checksum is correct, this will always produce a result of 0xffff,
even in the case under discussion where the sender might have had a
choice between storing 0x0000 and 0xffff in the checksum field. (The
only way the above code can generate a result of 0x0000 is if the input
consists entirely of zeros, which never happens in an IP packet.)

--apb (Alan Barrett)

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
j***@dsg.stanford.edu
2007-12-06 00:22:02 UTC
Permalink
Post by p***@klos.com
Hello IP Gurus,
I have a question about the IP header checksum that I'm looking for a
definitive answer for. I'm pretty sure I have the answer, but if anyone
can help me substantiate my answer, it would really help.
The IP header checksum is pretty straightforward: add up all the (2 byte)
words in the IP header using one's complement addition, then take the one's
Is it proper to substitute a resulting value of 0x0000 with 0xffff as
is done in UDP?
Long verbose answer:

It's not *im*proper to do that, since 1's complement arithmetic, zero
is a signed value. There are two zero values. 0xFFFF is -0, and 0x0000
is +0. But I don't see any good or compelling reason to do so.
The, er, "very controversial" [rfc-1122, sec 4.1.3.4] mechanism
whereby a UDP sender indicates "sender did not compute a UDP checksum"
are applicable only to UDP.

Indeed, rfc-1122 notes that UDP receiver who has received a UDP packet
with a nonzero UDP checksum doesn't need to take any special action
(with regard to verifying the received checksum) with regard to -0 and
+0; they are equivalent.


May I ask: why would you want to make this 0x0000 -> 0xffff
substituion for an IP header checksum?

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
p***@klos.com
2007-12-06 00:53:29 UTC
Permalink
Post by j***@dsg.stanford.edu
Post by p***@klos.com
Hello IP Gurus,
I have a question about the IP header checksum that I'm looking for a
definitive answer for. I'm pretty sure I have the answer, but if anyone
can help me substantiate my answer, it would really help.
The IP header checksum is pretty straightforward: add up all the (2 byte)
words in the IP header using one's complement addition, then take the one's
Is it proper to substitute a resulting value of 0x0000 with 0xffff as
is done in UDP?
It's not *im*proper to do that, since 1's complement arithmetic, zero
is a signed value. There are two zero values. 0xFFFF is -0, and 0x0000
is +0. But I don't see any good or compelling reason to do so.
The, er, "very controversial" [rfc-1122, sec 4.1.3.4] mechanism
whereby a UDP sender indicates "sender did not compute a UDP checksum"
are applicable only to UDP.
Indeed, rfc-1122 notes that UDP receiver who has received a UDP packet
with a nonzero UDP checksum doesn't need to take any special action
(with regard to verifying the received checksum) with regard to -0 and
+0; they are equivalent.
Thanks for responding. That is consistant with the other responses and
what I'm finding by poking around some other relevant RFCs.
Post by j***@dsg.stanford.edu
May I ask: why would you want to make this 0x0000 -> 0xffff
substituion for an IP header checksum?
Sure, you can ask. It's not that *I* want to make such a substitution.
It came up because a customer ran across a packet that implemented the IP
checksum this way, and my customer was concerned that our product flagged
that packet as having an incorrect checksum. Now that we've investigated the
topic, I have to accept that either form of the value should be accepted in
the IP header checksum field.

Patrick
========= For LAN/WAN Protocol Analysis, check out PacketView Pro! =========
Patrick Klos Email: ***@klos.com
Network/Embedded Software Engineer Web: http://www.klos.com/
Klos Technologies, Inc. Phone: 603-714-0195
============================================================================

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Loading...