From 60ec88353f7f35ebc1874bbdd2577e5665c03f0f Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Wed, 9 Nov 2011 16:08:09 +0100 Subject: simplify the chksum code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bjørn Mork --- ldra.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'ldra.c') diff --git a/ldra.c b/ldra.c index bdf4fbc..a6074d9 100644 --- a/ldra.c +++ b/ldra.c @@ -118,28 +118,40 @@ int print_hex(const char *buf, size_t len) { fprintf(stderr, "\n\n"); } -u_int32_t complement(u_int32_t sum) { - /* carry adjustment */ + +/* creating an UDP checksum isn't all that magic. you can checksum + parts individually and add up the result and carry later, provided + that all parts except possibly the last one has an even number of + bytes. +*/ + +/* fixup carry and complement the sum, returning it in network byte order */ +u_int16_t complement(u_int32_t sum) { + /* carry adjustment */ while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16); - sum = ~sum & 0xffff; - return (htons(sum)); + /* return the complement sum in network byte order */ + return htons(~sum); } -/* calulate a possibly partial checksum */ +/* calulate a possibly partial checksum + We consider buf a stream of 16bit numbers in network byte order. + Just sum them up, and leave the carry adjustment for later +*/ u_int32_t chksum(u_int8_t *buf, size_t n) { u_int32_t sum = 0; int i; - for (i = 0; i <(n & ~1U); i += 2) - sum += (u_int16_t)ntohs(*((u_int16_t *)(buf + i))); + /* this will limit the max buf length, but we cannot handle that large packets anyway */ + for (i = 0; i < (n & 0xfffe); i += 2) + sum += ntohs(*(u_int16_t *)(buf + i)); /* odd number of bytes? */ if (i < n) sum += buf[i] << 8; - return (sum); + return sum; } -- cgit v1.2.3