Incremental update of TCP Checksum

Vishwas Raman
2003-09-16T18:51:08Z

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).

Can anyone out there tell me the algorithm to update the checksum
without having to recalculate it.

I tried the following algorithm but it didnt work. The packet got
rejected as a packet with bad cksum.

void changePacket(struct sk_buff* skb)
{
struct tcphdr *tcpHdr = skb->h.th;
// Verifying the tcp checksum works here...
tcpHeader->doff += 1;
long cksum = (~(tcpHdr->check))&0xffff;
cksum += 1;
while (cksum >> 16)
{
cksum = (cksum & 0xffff) + (cksum >> 16);
}
tcpHeader->check = ~cksum;
// Verifying tcp checksum here fails with bad cksum
}

Any pointers/help in this regard will be highly appreciated...

Thanks,

-Vishwas.