Fwd: How to calculate the TCP checksum

Adel Qodmani mpcadel at gmail.com
Mon Jun 24 23:27:56 EDT 2013

On Tue, Jun 25, 2013 at 6:19 AM, Peter Teoh <htmldeveloper at gmail.com> wrote:

> c.   if your hardware is not capable to do TCP offloading, then the LONG
> way is to start from beginning of packet to end of packet, and calculate
> checksum.
I've tested that, my hardware apparently doesn't support TCP offloading.

>  d.   if u keep the previous checksum, ie (th->checksum=0 is not needed
> at all), and u know exactly which byte u modify, then just do a xor of the
> modified byte with the previous checksum, and u get the new
> checksum.....this is the preferred and fastest way.
> so in summary:
> th->check = 0;
> th->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
> datalen, iph->protocol,
> csum_partial((char *)th, datalen, 0));
> skb->ip_summed = CHECKSUM_UNNECESSARY;
> your setting of "0" above is correct, is because u want to calculate the
> checksum OVERALL....ie, packet start to packet end......demarcate correctly
> and u should get the answer....NOT csum_partial().....partial checksumming
> does not apply here.
> --
> Regards,
> Peter Teoh

Well, the problem is now solved, it seems that the error was with the fact
that some skbs are not linear and I was ignoring this fact.
Fixed it by the following:

                tcph = tcp_hdr(skb);

                tcplen = (skb->len - (iph->ihl << 2));/* tcplen is the
length of the skb - the ip-header length */
                tcph->check = 0;
                tcph->check = tcp_v4_check(tcplen,
                                csum_partial((char*) tcph, tcplen, 0));
                skb->ip_summed = CHECKSUM_NONE;/* in case another hardware
has TCP offloading */

Thanks a lot, anyhow :D
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20130625/28b7e437/attachment.html 

More information about the Kernelnewbies mailing list