`Richard B. Johnson wrote:> On Tue, 16 Sep 2003, Vishwas Raman wrote:> > >>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...> > > The TCP/IP checksum is a WORD sum (unsigned short) in which> any overflow out of the word causes the word to be incremented.> The final sum is then inverted to become the checksum. Note that> many algorithms sum into a long then fold-back the bits. It's> the same thing, different method.> > Therefore:> 	Given an existing checksum of 0xffff, if the> 	next word to be summed is 0x0001, the result> 	will be 0x0001 because adding 1 to 0xffff makes> 	it 0, causing an overflow which propagates to> 	become 0x0001.> So:> 	Clearly, information is lost because one doesn't> 	know how the 0x0001 was obtained.> > If I were to modify a low byte somewhere by subtracting 1,> would I know that the new checksum, excluding the inversion,> was 0x0000? No. It could be 0xffff.> > This presents a problem when trying to modify existing checksums.> It's certainly easier to set the existing checksum to 0, then> re-checksum the whole packet. It's probably faster than some> looping algorithm that attempts to unwind a previous checksum.Are you then suggesting that instead of trying to do an incremental update of the tcp checksum, I set it to 0 and recalculate it from scratch? But I thought that doing that was a big performance hit. Isn't it?> > > Cheers,> Dick Johnson> Penguin : Linux version 2.4.22 on an i686 machine (794.73 BogoMips).>             Note 96.31% of all statistics are fiction.> > > -- --Vishwas RamanSoftware Engineer, Eternal Systems, Inc,5290 Overpass Rd, Bldg D, Santa Barbara. CA 93111Email: vishwas@eternal-systems.comTel:   (805) 696-9051 x246Fax:   (805) 696-9083URL:   http://www.eternal-systems.com/-To unsubscribe from this list: send the line "unsubscribe linux-kernel" inthe body of a message to majordomo@vger.kernel.orgMore majordomo info at  http://vger.kernel.org/majordomo-info.htmlPlease read the FAQ at  http://www.tux.org/lkml/`