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);
if(skb_is_nonlinear(skb))
skb_linearize(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,
iph->saddr,
iph->daddr,
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