Date: Wed, 8 Nov 2000 20:03:59 +0200 From: Ruslan Ermilov <ru@FreeBSD.org> To: net@FreeBSD.org Cc: Charles Mott <cmott@scientech.com>, Ari Suutari <ari@suutari.iki.fi> Subject: libalias: Incremental Update of Internet Checksum Message-ID: <20001108200359.A38693@sunbay.com>
next in thread | raw e-mail | index | archive | help
--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 <bsd.prog.mk> --Dxnq1zWXvFF0Q93v Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="inc_cksum.c" #include <sys/types.h> #include <stdio.h> 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<n; i++) { accumulate -= *new++; accumulate += *old++; } if (accumulate < 0) { accumulate = -accumulate; accumulate = (accumulate >> 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20001108200359.A38693>