Re: Incremental update of TCP Checksum

Vishwas Raman
2003-09-16T20:33:11Z

Valdis.Kletnieks@vt.edu wrote:
> On Tue, 16 Sep 2003 11:50:16 PDT, Vishwas Raman <vishwas@eternal-systems.com> said:
>
>
>>Can anyone out there tell me the algorithm to update the checksum
>>without having to recalculate it.
>
>
> The canonical source is the RFCs:
>
> 1071 Computing the Internet checksum. R.T. Braden, D.A. Borman, C.
> Partridge. Sep-01-1988. (Format: TXT=54941 bytes) (Updated by
> RFC1141) (Status: UNKNOWN)
>
> 1141 Incremental updating of the Internet checksum. T. Mallory, A.
> Kullberg. Jan-01-1990. (Format: TXT=3587 bytes) (Updates RFC1071)
> (Updated by RFC1624) (Status: INFORMATIONAL)
>
> 1624 Computation of the Internet Checksum via Incremental Update. A.
> Rijsinghani, Ed.. May 1994. (Format: TXT=9836 bytes) (Updates
> RFC1141) (Status: INFORMATIONAL)
>
> http://www.ietf.org/rfc/rfc1071.txt
> http://www.ietf.org/rfc/rfc1141.txt
> http://www.ietf.org/rfc/rfc1624.txt

As mentioned in RFC1624, I did the following.
void changePacket(struct sk_buff* skb)
{
struct tcphdr *tcpHdr = skb->h.th;

// Verifying the tcp checksum works here...

__u16 oldDoff = tcpHeader->doff;
tcpHeader->doff += 1;

// Formula from RFC1624 is HC' = ~(C + (-m) + m')
// where HC - old checksum in header
// C - one's complement sum of old header
// HC' - new checksum in header
// C' - one's complement sum of new header
// m - old value of a 16-bit field
// m' - new value of a 16-bit field

long cksum = (~(tcpHdr->check))&0xffff;
cksum += (__u16)~oldDoff;
cksum += tcpHeader->doff;
while (cksum >> 16)
{
cksum = (cksum & 0xffff) + (cksum >> 16);
}
tcpHeader->check = ~cksum;

// Verifying tcp checksum here fails with bad cksum
}

Is there any glaring mistake in the above code. If so, can someone
please let me know what it is. It will be of great help.

Thanks,

-Vishwas.