diff options
Diffstat (limited to 'tests/lib/test_checksum.c')
| -rw-r--r-- | tests/lib/test_checksum.c | 694 |
1 files changed, 344 insertions, 350 deletions
diff --git a/tests/lib/test_checksum.c b/tests/lib/test_checksum.c index 53ab260e26..6abf5c1f9b 100644 --- a/tests/lib/test_checksum.c +++ b/tests/lib/test_checksum.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2008 Sun Microsystems, Inc. * * This file is part of Quagga. @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with Quagga; see the file COPYING. If not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. + * 02111-1307, USA. */ #include <zebra.h> @@ -28,14 +28,14 @@ struct thread_master *master; struct acc_vals { - int c0; - int c1; + int c0; + int c1; }; struct csum_vals { - struct acc_vals a; - int x; - int y; + struct acc_vals a; + int x; + int y; }; static struct csum_vals ospfd_vals, isisd_vals; @@ -47,26 +47,26 @@ typedef uint16_t testoff_t; #define MODX 4102U /* The final reduction phase. - * This one should be the original ospfd version + * This one should be the original ospfd version */ -static u_int16_t -reduce_ospfd (struct csum_vals *vals, testsz_t len, testoff_t off) +static u_int16_t reduce_ospfd(struct csum_vals *vals, testsz_t len, + testoff_t off) { #define x vals->x #define y vals->y #define c0 vals->a.c0 #define c1 vals->a.c1 - x = ((len - off - 1) * c0 - c1) % 255; - - if (x <= 0) - x += 255; - y = 510 - c0 - x; - if (y > 255) - y -= 255; + x = ((len - off - 1) * c0 - c1) % 255; - /* take care endian issue. */ - return htons ((x << 8) + y); + if (x <= 0) + x += 255; + y = 510 - c0 - x; + if (y > 255) + y -= 255; + + /* take care endian issue. */ + return htons((x << 8) + y); #undef x #undef y #undef c0 @@ -74,23 +74,23 @@ reduce_ospfd (struct csum_vals *vals, testsz_t len, testoff_t off) } /* slightly different concatenation */ -static u_int16_t -reduce_ospfd1 (struct csum_vals *vals, testsz_t len, testoff_t off) +static u_int16_t reduce_ospfd1(struct csum_vals *vals, testsz_t len, + testoff_t off) { #define x vals->x #define y vals->y #define c0 vals->a.c0 #define c1 vals->a.c1 - x = ((len - off - 1) * c0 - c1) % 255; - if (x <= 0) - x += 255; - y = 510 - c0 - x; - if (y > 255) - y -= 255; + x = ((len - off - 1) * c0 - c1) % 255; + if (x <= 0) + x += 255; + y = 510 - c0 - x; + if (y > 255) + y -= 255; - /* take care endian issue. */ - return htons ((x << 8) | (y & 0xff)); + /* take care endian issue. */ + return htons((x << 8) | (y & 0xff)); #undef x #undef y #undef c0 @@ -98,33 +98,33 @@ reduce_ospfd1 (struct csum_vals *vals, testsz_t len, testoff_t off) } /* original isisd version */ -static u_int16_t -reduce_isisd (struct csum_vals *vals, testsz_t len, testoff_t off) +static u_int16_t reduce_isisd(struct csum_vals *vals, testsz_t len, + testoff_t off) { #define x vals->x #define y vals->y #define c0 vals->a.c0 #define c1 vals->a.c1 - u_int32_t mul; - - mul = (len - off)*(c0); - x = mul - c0 - c1; - y = c1 - mul - 1; + u_int32_t mul; + + mul = (len - off) * (c0); + x = mul - c0 - c1; + y = c1 - mul - 1; - if (y > 0) - y++; - if (x < 0) - x--; + if (y > 0) + y++; + if (x < 0) + x--; - x %= 255; - y %= 255; + x %= 255; + y %= 255; - if (x == 0) - x = 255; - if (y == 0) - y = 1; + if (x == 0) + x = 255; + if (y == 0) + y = 1; - return htons ((x << 8) | (y & 0xff)); + return htons((x << 8) | (y & 0xff)); #undef x #undef y @@ -133,33 +133,33 @@ reduce_isisd (struct csum_vals *vals, testsz_t len, testoff_t off) } /* Is the -1 in y wrong perhaps? */ -static u_int16_t -reduce_isisd_yfix (struct csum_vals *vals, testsz_t len, testoff_t off) +static u_int16_t reduce_isisd_yfix(struct csum_vals *vals, testsz_t len, + testoff_t off) { #define x vals->x #define y vals->y #define c0 vals->a.c0 #define c1 vals->a.c1 - u_int32_t mul; - - mul = (len - off)*(c0); - x = mul - c0 - c1; - y = c1 - mul; + u_int32_t mul; + + mul = (len - off) * (c0); + x = mul - c0 - c1; + y = c1 - mul; - if (y > 0) - y++; - if (x < 0) - x--; + if (y > 0) + y++; + if (x < 0) + x--; - x %= 255; - y %= 255; + x %= 255; + y %= 255; - if (x == 0) - x = 255; - if (y == 0) - y = 1; + if (x == 0) + x = 255; + if (y == 0) + y = 1; - return htons ((x << 8) | (y & 0xff)); + return htons((x << 8) | (y & 0xff)); #undef x #undef y @@ -168,33 +168,33 @@ reduce_isisd_yfix (struct csum_vals *vals, testsz_t len, testoff_t off) } /* Move the mods yp */ -static u_int16_t -reduce_isisd_mod (struct csum_vals *vals, testsz_t len, testoff_t off) +static u_int16_t reduce_isisd_mod(struct csum_vals *vals, testsz_t len, + testoff_t off) { #define x vals->x #define y vals->y #define c0 vals->a.c0 #define c1 vals->a.c1 - u_int32_t mul; - - mul = (len - off)*(c0); - x = mul - c1 - c0; - y = c1 - mul - 1; + u_int32_t mul; - x %= 255; - y %= 255; + mul = (len - off) * (c0); + x = mul - c1 - c0; + y = c1 - mul - 1; - if (y > 0) - y++; - if (x < 0) - x--; + x %= 255; + y %= 255; - if (x == 0) - x = 255; - if (y == 0) - y = 1; + if (y > 0) + y++; + if (x < 0) + x--; - return htons ((x << 8) | (y & 0xff)); + if (x == 0) + x = 255; + if (y == 0) + y = 1; + + return htons((x << 8) | (y & 0xff)); #undef x #undef y @@ -203,33 +203,33 @@ reduce_isisd_mod (struct csum_vals *vals, testsz_t len, testoff_t off) } /* Move the mods up + fix y */ -static u_int16_t -reduce_isisd_mody (struct csum_vals *vals, testsz_t len, testoff_t off) +static u_int16_t reduce_isisd_mody(struct csum_vals *vals, testsz_t len, + testoff_t off) { #define x vals->x #define y vals->y #define c0 vals->a.c0 #define c1 vals->a.c1 - u_int32_t mul; - - mul = (len - off)*(c0); - x = mul - c0 - c1; - y = c1 - mul; + u_int32_t mul; + + mul = (len - off) * (c0); + x = mul - c0 - c1; + y = c1 - mul; - x %= 255; - y %= 255; + x %= 255; + y %= 255; - if (y > 0) - y++; - if (x < 0) - x--; + if (y > 0) + y++; + if (x < 0) + x--; - if (x == 0) - x = 255; - if (y == 0) - y = 1; + if (x == 0) + x = 255; + if (y == 0) + y = 1; - return htons ((x << 8) | (y & 0xff)); + return htons((x << 8) | (y & 0xff)); #undef x #undef y @@ -238,184 +238,175 @@ reduce_isisd_mody (struct csum_vals *vals, testsz_t len, testoff_t off) } struct reductions_t { - const char *name; - u_int16_t (*f) (struct csum_vals *, testsz_t, testoff_t); + const char *name; + u_int16_t (*f)(struct csum_vals *, testsz_t, testoff_t); } reducts[] = { - { .name = "ospfd", .f = reduce_ospfd }, - { .name = "ospfd-1", .f = reduce_ospfd1 }, - { .name = "isisd", .f = reduce_isisd }, - { .name = "isisd-yfix", .f = reduce_isisd_yfix }, - { .name = "isisd-mod", .f = reduce_isisd_mod }, - { .name = "isisd-mody", .f = reduce_isisd_mody }, - { NULL, NULL }, + {.name = "ospfd", .f = reduce_ospfd}, + {.name = "ospfd-1", .f = reduce_ospfd1}, + {.name = "isisd", .f = reduce_isisd}, + {.name = "isisd-yfix", .f = reduce_isisd_yfix}, + {.name = "isisd-mod", .f = reduce_isisd_mod}, + {.name = "isisd-mody", .f = reduce_isisd_mody}, + {NULL, NULL}, }; /* The original ospfd checksum */ -static u_int16_t -ospfd_checksum (u_char *buffer, testsz_t len, testoff_t off) +static u_int16_t ospfd_checksum(u_char *buffer, testsz_t len, testoff_t off) { - u_char *sp, *ep, *p, *q; - int c0 = 0, c1 = 0; - int x, y; - u_int16_t checksum, *csum; - - csum = (u_int16_t *) (buffer + off); - *(csum) = 0; - - sp = buffer; - - for (ep = sp + len; sp < ep; sp = q) - { - q = sp + MODX; - if (q > ep) - q = ep; - for (p = sp; p < q; p++) - { - c0 += *p; - c1 += c0; - } - c0 %= 255; - c1 %= 255; - } - - ospfd_vals.a.c0 = c0; - ospfd_vals.a.c1 = c1; - - //printf ("%s: len %u, off %u, c0 %d, c1 %d\n", - // __func__, len, off, c0, c1); - - x = ((int)(len - off - 1) * (int)c0 - (int)c1) % 255; - - if (x <= 0) - x += 255; - y = 510 - c0 - x; - if (y > 255) - y -= 255; - - ospfd_vals.x = x; - ospfd_vals.y = y; - - buffer[off] = x; - buffer[off + 1] = y; - - /* take care endian issue. */ - checksum = htons ((x << 8) | (y & 0xff)); - - return (checksum); + u_char *sp, *ep, *p, *q; + int c0 = 0, c1 = 0; + int x, y; + u_int16_t checksum, *csum; + + csum = (u_int16_t *)(buffer + off); + *(csum) = 0; + + sp = buffer; + + for (ep = sp + len; sp < ep; sp = q) { + q = sp + MODX; + if (q > ep) + q = ep; + for (p = sp; p < q; p++) { + c0 += *p; + c1 += c0; + } + c0 %= 255; + c1 %= 255; + } + + ospfd_vals.a.c0 = c0; + ospfd_vals.a.c1 = c1; + + // printf ("%s: len %u, off %u, c0 %d, c1 %d\n", + // __func__, len, off, c0, c1); + + x = ((int)(len - off - 1) * (int)c0 - (int)c1) % 255; + + if (x <= 0) + x += 255; + y = 510 - c0 - x; + if (y > 255) + y -= 255; + + ospfd_vals.x = x; + ospfd_vals.y = y; + + buffer[off] = x; + buffer[off + 1] = y; + + /* take care endian issue. */ + checksum = htons((x << 8) | (y & 0xff)); + + return (checksum); } /* the original, broken isisd checksum */ -static u_int16_t -iso_csum_create (u_char * buffer, testsz_t len, testoff_t off) +static u_int16_t iso_csum_create(u_char *buffer, testsz_t len, testoff_t off) { - u_int8_t *p; - int x; - int y; - u_int32_t mul; - u_int32_t c0; - u_int32_t c1; - u_int16_t checksum, *csum; - int i, init_len, partial_len; - - checksum = 0; - - csum = (u_int16_t *) (buffer + off); - *(csum) = checksum; - - p = buffer; - c0 = 0; - c1 = 0; - init_len = len; - - while (len != 0) - { - partial_len = MIN(len, MODX); - - for (i = 0; i < partial_len; i++) - { - c0 = c0 + *(p++); - c1 += c0; + u_int8_t *p; + int x; + int y; + u_int32_t mul; + u_int32_t c0; + u_int32_t c1; + u_int16_t checksum, *csum; + int i, init_len, partial_len; + + checksum = 0; + + csum = (u_int16_t *)(buffer + off); + *(csum) = checksum; + + p = buffer; + c0 = 0; + c1 = 0; + init_len = len; + + while (len != 0) { + partial_len = MIN(len, MODX); + + for (i = 0; i < partial_len; i++) { + c0 = c0 + *(p++); + c1 += c0; + } + + c0 = c0 % 255; + c1 = c1 % 255; + + len -= partial_len; } - c0 = c0 % 255; - c1 = c1 % 255; - - len -= partial_len; - } - - isisd_vals.a.c0 = c0; - isisd_vals.a.c1 = c1; - - mul = (init_len - off) * c0; - - x = mul - c1 - c0; - y = c1 - mul - 1; - - if (y > 0) - y++; - if (x < 0) - x--; - - x %= 255; - y %= 255; - - if (x == 0) - x = 255; - if (y == 0) - y = 1; - - isisd_vals.x = x; - isisd_vals.y = y; - - checksum = htons((x << 8) | (y & 0xFF)); - - *(csum) = checksum; - - /* return the checksum for user usage */ - return checksum; + isisd_vals.a.c0 = c0; + isisd_vals.a.c1 = c1; + + mul = (init_len - off) * c0; + + x = mul - c1 - c0; + y = c1 - mul - 1; + + if (y > 0) + y++; + if (x < 0) + x--; + + x %= 255; + y %= 255; + + if (x == 0) + x = 255; + if (y == 0) + y = 1; + + isisd_vals.x = x; + isisd_vals.y = y; + + checksum = htons((x << 8) | (y & 0xFF)); + + *(csum) = checksum; + + /* return the checksum for user usage */ + return checksum; } -static int -verify (u_char * buffer, testsz_t len) +static int verify(u_char *buffer, testsz_t len) { - u_int8_t *p; - u_int32_t c0; - u_int32_t c1; - int i, partial_len; - - p = buffer; - - c0 = 0; - c1 = 0; - - while (len) - { - partial_len = MIN(len, 5803U); - - for (i = 0; i < partial_len; i++) - { - c0 = c0 + *(p++); - c1 += c0; - } - c0 = c0 % 255; - c1 = c1 % 255; - - len -= partial_len; - } - - if (c0 == 0 && c1 == 0) - return 0; - - return 1; + u_int8_t *p; + u_int32_t c0; + u_int32_t c1; + int i, partial_len; + + p = buffer; + + c0 = 0; + c1 = 0; + + while (len) { + partial_len = MIN(len, 5803U); + + for (i = 0; i < partial_len; i++) { + c0 = c0 + *(p++); + c1 += c0; + } + c0 = c0 % 255; + c1 = c1 % 255; + + len -= partial_len; + } + + if (c0 == 0 && c1 == 0) + return 0; + + return 1; } -static int /* return checksum in low-order 16 bits */ -in_cksum_optimized(void *parg, int nbytes) +static int /* return checksum in low-order 16 bits */ + in_cksum_optimized(void *parg, int nbytes) { u_short *ptr = parg; - register long sum; /* assumes long == 32 bits */ - register u_short answer; /* assumes u_short == 16 bits */ + register long sum; /* assumes long == 32 bits */ + register u_short answer; /* assumes u_short == 16 bits */ register int count; /* * Our algorithm is simple, using a 32-bit accumulator (sum), @@ -425,126 +416,129 @@ in_cksum_optimized(void *parg, int nbytes) sum = 0; count = nbytes >> 1; /* div by 2 */ - for(ptr--; count; --count) - sum += *++ptr; + for (ptr--; count; --count) + sum += *++ptr; - if (nbytes & 1) /* Odd */ - sum += *(u_char *)(++ptr); /* one byte only */ + if (nbytes & 1) /* Odd */ + sum += *(u_char *)(++ptr); /* one byte only */ /* * Add back carry outs from top 16 bits to low 16 bits. */ - sum = (sum >> 16) + (sum & 0xffff); /* add high-16 to low-16 */ - sum += (sum >> 16); /* add carry */ - answer = ~sum; /* ones-complement, then truncate to 16 bits */ - return(answer); + sum = (sum >> 16) + (sum & 0xffff); /* add high-16 to low-16 */ + sum += (sum >> 16); /* add carry */ + answer = ~sum; /* ones-complement, then truncate to 16 bits */ + return (answer); } static int /* return checksum in low-order 16 bits */ -in_cksum_rfc(void *parg, int count) + in_cksum_rfc(void *parg, int count) /* from RFC 1071 */ { u_short *addr = parg; /* Compute Internet Checksum for "count" bytes * beginning at location "addr". */ - register long sum = 0; + register long sum = 0; - while (count > 1) { - /* This is the inner loop */ - sum += *addr++; - count -= 2; + while (count > 1) { + /* This is the inner loop */ + sum += *addr++; + count -= 2; } /* Add left-over byte, if any */ if (count > 0) { - sum += *(u_char *)addr; + sum += *(u_char *)addr; } /* Fold 32-bit sum to 16 bits */ - while (sum>>16) - sum = (sum & 0xffff) + (sum >> 16); + while (sum >> 16) + sum = (sum & 0xffff) + (sum >> 16); return ~sum; } -int -main(int argc, char **argv) +int main(int argc, char **argv) { /* 60017 65629 702179 */ #define MAXDATALEN 60017 #define BUFSIZE MAXDATALEN + sizeof(u_int16_t) - u_char buffer[BUFSIZE]; - int exercise = 0; + u_char buffer[BUFSIZE]; + int exercise = 0; #define EXERCISESTEP 257 - - srandom (time (NULL)); - - while (1) { - u_int16_t ospfd, isisd, lib, in_csum, in_csum_res, in_csum_rfc; - int i,j; - - exercise += EXERCISESTEP; - exercise %= MAXDATALEN; - - for (i = 0; i < exercise; i += sizeof (long int)) { - long int rand = random (); - - for (j = sizeof (long int); j > 0; j--) - buffer[i + (sizeof (long int) - j)] = (rand >> (j * 8)) & 0xff; - } - - in_csum = in_cksum(buffer, exercise); - in_csum_res = in_cksum_optimized(buffer, exercise); - in_csum_rfc = in_cksum_rfc(buffer, exercise); - if (in_csum_res != in_csum || in_csum != in_csum_rfc) - printf ("verify: in_chksum failed in_csum:%x, in_csum_res:%x," - "in_csum_rfc %x, len:%d\n", - in_csum, in_csum_res, in_csum_rfc, exercise); - - ospfd = ospfd_checksum (buffer, exercise + sizeof(u_int16_t), exercise); - if (verify (buffer, exercise + sizeof(u_int16_t))) - printf ("verify: ospfd failed\n"); - isisd = iso_csum_create (buffer, exercise + sizeof(u_int16_t), exercise); - if (verify (buffer, exercise + sizeof(u_int16_t))) - printf ("verify: isisd failed\n"); - lib = fletcher_checksum (buffer, exercise + sizeof(u_int16_t), exercise); - if (verify (buffer, exercise + sizeof(u_int16_t))) - printf ("verify: lib failed\n"); - - if (ospfd != lib) { - printf ("Mismatch in values at size %u\n" - "ospfd: 0x%04x\tc0: %d\tc1: %d\tx: %d\ty: %d\n" - "isisd: 0x%04x\tc0: %d\tc1: %d\tx: %d\ty: %d\n" - "lib: 0x%04x\n", - exercise, - ospfd, ospfd_vals.a.c0, ospfd_vals.a.c1, ospfd_vals.x, ospfd_vals.y, - isisd, isisd_vals.a.c0, isisd_vals.a.c1, isisd_vals.x, isisd_vals.y, - lib - ); - - /* Investigate reduction phase discrepencies */ - if (ospfd_vals.a.c0 == isisd_vals.a.c0 - && ospfd_vals.a.c1 == isisd_vals.a.c1) { - printf ("\n"); - for (i = 0; reducts[i].name != NULL; i++) { - ospfd = reducts[i].f (&ospfd_vals, - exercise + sizeof (u_int16_t), - exercise); - printf ("%20s: x: %02x, y %02x, checksum 0x%04x\n", - reducts[i].name, ospfd_vals.x & 0xff, ospfd_vals.y & 0xff, ospfd); - } - } - - printf ("\n u_char testdata [] = {\n "); - for (i = 0; i < exercise; i++) { - printf ("0x%02x,%s", - buffer[i], - (i + 1) % 8 ? " " : "\n "); - } - printf ("\n}\n"); - exit (1); - } - } + srandom(time(NULL)); + + while (1) { + u_int16_t ospfd, isisd, lib, in_csum, in_csum_res, in_csum_rfc; + int i, j; + + exercise += EXERCISESTEP; + exercise %= MAXDATALEN; + + for (i = 0; i < exercise; i += sizeof(long int)) { + long int rand = random(); + + for (j = sizeof(long int); j > 0; j--) + buffer[i + (sizeof(long int) - j)] = + (rand >> (j * 8)) & 0xff; + } + + in_csum = in_cksum(buffer, exercise); + in_csum_res = in_cksum_optimized(buffer, exercise); + in_csum_rfc = in_cksum_rfc(buffer, exercise); + if (in_csum_res != in_csum || in_csum != in_csum_rfc) + printf("verify: in_chksum failed in_csum:%x, in_csum_res:%x," + "in_csum_rfc %x, len:%d\n", + in_csum, in_csum_res, in_csum_rfc, exercise); + + ospfd = ospfd_checksum(buffer, exercise + sizeof(u_int16_t), + exercise); + if (verify(buffer, exercise + sizeof(u_int16_t))) + printf("verify: ospfd failed\n"); + isisd = iso_csum_create(buffer, exercise + sizeof(u_int16_t), + exercise); + if (verify(buffer, exercise + sizeof(u_int16_t))) + printf("verify: isisd failed\n"); + lib = fletcher_checksum(buffer, exercise + sizeof(u_int16_t), + exercise); + if (verify(buffer, exercise + sizeof(u_int16_t))) + printf("verify: lib failed\n"); + + if (ospfd != lib) { + printf("Mismatch in values at size %u\n" + "ospfd: 0x%04x\tc0: %d\tc1: %d\tx: %d\ty: %d\n" + "isisd: 0x%04x\tc0: %d\tc1: %d\tx: %d\ty: %d\n" + "lib: 0x%04x\n", + exercise, ospfd, ospfd_vals.a.c0, + ospfd_vals.a.c1, ospfd_vals.x, ospfd_vals.y, + isisd, isisd_vals.a.c0, isisd_vals.a.c1, + isisd_vals.x, isisd_vals.y, lib); + + /* Investigate reduction phase discrepencies */ + if (ospfd_vals.a.c0 == isisd_vals.a.c0 + && ospfd_vals.a.c1 == isisd_vals.a.c1) { + printf("\n"); + for (i = 0; reducts[i].name != NULL; i++) { + ospfd = reducts[i].f( + &ospfd_vals, + exercise + sizeof(u_int16_t), + exercise); + printf("%20s: x: %02x, y %02x, checksum 0x%04x\n", + reducts[i].name, + ospfd_vals.x & 0xff, + ospfd_vals.y & 0xff, ospfd); + } + } + + printf("\n u_char testdata [] = {\n "); + for (i = 0; i < exercise; i++) { + printf("0x%02x,%s", buffer[i], + (i + 1) % 8 ? " " : "\n "); + } + printf("\n}\n"); + exit(1); + } + } } |
