Re: Incremental update of TCP Checksum

Jesper Juhl
2003-09-16T20:36:47Z

On Tue, 16 Sep 2003, Vishwas Raman wrote:

>
> Richard B. Johnson wrote:
> > On Tue, 16 Sep 2003, Vishwas Raman wrote:
> >
> >
> >>Hi all,
> >>
> >>I have a very simple question, which a lot of you would have solved. I
> >>am intercepting a TCP packet, which I would like to change slightly.
> >>
> >>Let's say, I change the doff field of the tcp-header (for eg: increase
> >>it by 1). I know it is wrong just to change the doff field without
> >>increasing the packet length, but lets say I do it just as a test. Since
> >>I changed a portion of the tcp header, I have to update the tcp checksum
> >>too right!!! If so, what is the best way to do so, without having to
> >>recalculate the entire tcp checksum (I know how to recalculate the
> >>checksum from scratch).
> >>
> >
> > The TCP/IP checksum is a WORD sum (unsigned short) in which
> > any overflow out of the word causes the word to be incremented.
> > The final sum is then inverted to become the checksum. Note that
> > many algorithms sum into a long then fold-back the bits. It's
> > the same thing, different method.
> >
> > Therefore:
> > Given an existing checksum of 0xffff, if the
> > next word to be summed is 0x0001, the result
> > will be 0x0001 because adding 1 to 0xffff makes
> > it 0, causing an overflow which propagates to
> > become 0x0001.
> > So:
> > Clearly, information is lost because one doesn't
> > know how the 0x0001 was obtained.
> >
> > 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.
> >
> > This presents a problem when trying to modify existing checksums.
> > It's certainly easier to set the existing checksum to 0, then
> > re-checksum the whole packet. It's probably faster than some
> > looping algorithm that attempts to unwind a previous checksum.
>
> 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?
>
Personally I can't see that you have any other option. The way the
checksum is calculated information is lost, so it's impossible to
determine exactely what input generated the current output (the checksum).
Just as it is impossible to tell if the number 6 was generated from 2+2+2,
from 3*2 or from 3+3 or some other... So I don't see what else you can do
except just recalculate the checksum from scratch. To try and determine
how your modification would affect the checksum would probably take far
longer than just re-calculating it.

- Jesper Juhl <jju@dif.dk>