Re: seq numbers and checksum in tcp

Rafael D'Halleweyn (rafael@village.uunet.be)
Wed, 20 Jan 1999 22:04:05 +0100 (MET)


In article <19990117235141.A365@ccwf.cc.utexas.edu> you wrote:
> basically, i want to just modify the th->seq and then recompute
> the tcp checksum and i suspect the skb checksum.

> Is there an easy way to check the tcp checksum and then make the
> mod and then recompute a new checksum. any help is much appreciated.

Hi Ayman,

I have been doing something similar.

Here is the code:

Somewhere I do the following:
__u32 newseq = ntohl(tcp->seq) + sequenceadd;
tcp->check = incr_check_l(tcp->check,
ntohl(tcp->seq), newseq);
tcp->seq = htonl(newseq);

And then use this function:

/* Incrementaly update a checksum, given old and new 32bit words */
static inline __u16 incr_check_l(__u16 old_check, __u32 old, __u32 new)
{ /* see RFC's 1624, 1141 and 1071 for incremental checksum
updates */
__u32 l;
old_check = ~ntohs(old_check);
old = ~old;
l = (__u32)old_check + (old>>16) + (old&0xffff)
+ (new>>16) + (new&0xffff);
return htons(~( (__u16)(l>>16) + (l&0xffff) ));
}

I have a similar function that can be used when you only change a 16bit
word:

/* Incrementaly update a checksum, given old and new 16bit words */
static inline __u16 incr_check_s(__u16 old_check, __u16 old, __u16 new)
{ /* see RFC's 1624, 1141 and 1071 for incremental checksum
updates */
__u32 l;
old_check = ~ntohs(old_check);
old = ~old;
l = (__u32)old_check + old + new;
return htons(~( (__u16)(l>>16) + (l&0xffff) ));
}

I guess these functions can be coded more optimally in assembler.

You should read the mentioned RFC, especially RFC 1624 which handles
incrementally changing checksums.

Maybe you would like to give some more information about your project?

I hope this helps you,

Rafael D'Halleweyn
rdhall@mail.dma.be

Where do you want to hide today?

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/