Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Nov 1999 21:56:27 -0800 (PST)
From:      Julian Elischer <julian@whistle.com>
To:        "Parthasarathy M. Aji" <partha@cs.duke.edu>
Cc:        freebsd-hackers@FreeBSD.ORG, Clinton Xavier Berni <xavier@cs.duke.edu>
Subject:   Re: ip checksum 
Message-ID:  <Pine.BSF.4.10.9911222144560.9392-100000@current1.whistle.com>
In-Reply-To: <Pine.GSO.4.20.9911230000550.1664-100000@astaire.cs.duke.edu>

next in thread | previous in thread | raw e-mail | index | archive | help
How many bytes have you changed?

is it possible that some of the values have already been ntohs()'d
or something similar?

rather than recalculate the whole packet, just update the exisitng
value.

there is an rfc for this but it took me a while to get 
the code right in C on a 386. The trick is getting the 1s complement
arithmetic right.



 #define FIXSUM16(c, op, np)                                           \
    do {                                                                \
      (c) -= (u_int16_t) ~*((u_int16_t *) (op));                        \
      if ((c) < 0) {                                                    \
        (c) += 0xffff;                                                  \
      }                                                                 \
      (c) -= (u_int16_t)  *((u_int16_t *) (np));                        \
      if ((c) < 0) {                                                    \
        (c) += 0xffff;                                                  \
      }                                                                 \
    } while (0)


/* 
 * IpsumReplaceShort()
 * 
 * Replace a 16 bit aligned (relative to the checksum) 16 bit value
 * in a packet and change the IP/TCP/UDP checksum at the same time.
 * 
 * Works with both big and little endian machines(!)
 *    
 * If for some wierd reason you want to replace a nonaligned value,
 * you need to byteswap it and the old value before doing the
 * subtractions.
 */
      
void
IpsumReplaceShort(u_int16_t *cksump, u_int16_t *oldvalp, u_int16_t newval)
{
  register int  cksum;
  
  cksum = *cksump;
  FIXSUM16(cksum, oldvalp, &newval);
  *cksump = cksum;
  *oldvalp = newval;
} 


On Tue, 23 Nov 1999, Parthasarathy M. Aji wrote:

> Hey,
> 
> I am trying to recompute the checksum of an IP packet. I use
> netinet/in_chksum.c to do this. The values returned are not correct. I've
> reset the ip_sum field to 0 before doing the sum. Is there something
> missing?   
> 
> thanks
> 
> 
> 
> To Unsubscribe: send mail to majordomo@FreeBSD.org
> with "unsubscribe freebsd-hackers" in the body of the message
> 



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.10.9911222144560.9392-100000>