From owner-freebsd-net Wed Nov 8 10: 4:20 2000 Delivered-To: freebsd-net@freebsd.org Received: from whale.sunbay.crimea.ua (whale.sunbay.crimea.ua [212.110.138.65]) by hub.freebsd.org (Postfix) with ESMTP id D75EF37B479 for ; Wed, 8 Nov 2000 10:04:14 -0800 (PST) Received: (from ru@localhost) by whale.sunbay.crimea.ua (8.11.0/8.11.0) id eA8I40o39160; Wed, 8 Nov 2000 20:04:00 +0200 (EET) (envelope-from ru) Date: Wed, 8 Nov 2000 20:03:59 +0200 From: Ruslan Ermilov To: net@FreeBSD.org Cc: Charles Mott , Ari Suutari Subject: libalias: Incremental Update of Internet Checksum Message-ID: <20001108200359.A38693@sunbay.com> Mail-Followup-To: net@FreeBSD.org, Charles Mott , Ari Suutari Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="Dxnq1zWXvFF0Q93v" Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-net@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org --Dxnq1zWXvFF0Q93v Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi! The DifferentialChecksum() function in libalias(3) is used to efficiently recompute the checksum for altered packets. Unfortunately, the implementation suffers from the problem described in RFC 1624. I have implemented the replacement for it, using the final formula [4] from the RFC. The attached C program demonstrates the problem as well as the new implementation. Comments? -- Ruslan Ermilov Oracle Developer/DBA, ru@sunbay.com Sunbay Software AG, ru@FreeBSD.org FreeBSD committer, +380.652.512.251 Simferopol, Ukraine http://www.FreeBSD.org The Power To Serve http://www.oracle.com Enabling The Information Age --Dxnq1zWXvFF0Q93v Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=Makefile PROG= inc_cksum NOMAN= YES CFLAGS+=${BDECFLAGS} .include --Dxnq1zWXvFF0Q93v Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="inc_cksum.c" #include #include void DifferentialChecksum(u_short *, u_short *, u_short *, int); void DifferentialChecksum_RFC1624(u_short *, u_short *, u_short *, int); void DifferentialChecksum(u_short *cksum, u_short *new, u_short *old, int n) { int i; int accumulate; accumulate = *cksum; for (i=0; i> 16) + (accumulate & 0xffff); accumulate += accumulate >> 16; *cksum = (u_short) ~accumulate; } else { accumulate = (accumulate >> 16) + (accumulate & 0xffff); accumulate += accumulate >> 16; *cksum = (u_short) accumulate; } } /* * Incremental Update of Internet Checksum with [Eqn. 4] from RFC 1624. */ void DifferentialChecksum_RFC1624(u_short *cksum, u_short *new, u_short *old, int n) { int i; int accumulate; /* should be `signed' */ accumulate = *cksum; for (i = 0; i < n; i++) { accumulate -= *new++; accumulate -= (u_short)~*old++; } accumulate = (accumulate >> 16) + (accumulate & 0xffff); accumulate += accumulate >> 16; *cksum = (u_short) accumulate; } int main(void) { u_short old, new, oldcksum, newcksum1, newcksum2; old = 0x5555; for (new = 0x0;; new++) { for (oldcksum = 0x0;; oldcksum++) { newcksum1 = newcksum2 = oldcksum; DifferentialChecksum(&newcksum1, &new, &old, 1); DifferentialChecksum_RFC1624(&newcksum2, &new, &old, 1); if (newcksum1 != newcksum2) printf("old=%#hx new=%#hx oldcksum=%#hx " "newcksum1=%#hx newcksum2=%#hx\n", old, new, oldcksum, newcksum1, newcksum2); if (oldcksum == 0xffff) break; } if (new == 0xffff) break; } return (0); } --Dxnq1zWXvFF0Q93v-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-net" in the body of the message