diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/.gitignore | 19 | ||||
-rw-r--r-- | tests/ChangeLog | 160 | ||||
-rw-r--r-- | tests/Makefile.am | 7 | ||||
-rw-r--r-- | tests/heavy-wq.c | 2 | ||||
-rw-r--r-- | tests/test-checksum.c | 499 |
5 files changed, 525 insertions, 162 deletions
diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 00000000..ca085943 --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1,19 @@ +Makefile +Makefile.in +*.o +tags +TAGS +.deps +.nfs* +*.lo +*.la +*.libs +testsig +.arch-inventory +.arch-ids +testbuffer +testmemory +testsig +*~ +*.loT + diff --git a/tests/ChangeLog b/tests/ChangeLog deleted file mode 100644 index 18696519..00000000 --- a/tests/ChangeLog +++ /dev/null @@ -1,160 +0,0 @@ -2008-06-07 Paul Jakma <paul@jakma.org - - * bgp_mp_attr_test.c: MP_(UN)REACH_NLRI unit tests - -2008-02-23 Paul Jakma <paul.jakma@sun.com> - - * aspath_test.c: Test for 0-ASN sequences that still have data. - -2007-12-22 Paul Jakma <paul.jakma@sun.com> - - * bgp_capability_test.c: Test for empty capabilities. - -2007-09-27 Paul Jakma <paul.jakma@sun.com> - - * aspath_test.c: Test dupe-weeding from sets. - Test that reconciliation merges AS_PATH and AS4_PATH where - former is shorter than latter. - -2007-09-26 Paul Jakma <paul.jakma@sun.com> - - * aspath_test.c: Test AS4_PATH reconcilation where length - of AS_PATH and AS4_PATH is same. - -2007-09-25 Paul Jakma <paul.jakma@sun.com> - - * bgp_capability_test.c: (general) Extend tests to validate - peek_for_as4_capability. - Add test of full OPEN Option block, with multiple capabilities, - both as a series of Option, and a single option. - Add some crap to beginning of stream, to prevent code depending - on getp == 0. - -2007-09-18 Paul Jakma <paul.jakma@sun.com> - - * bgp_capability_test.c: (parse_test) update for changes to - peek_for_as4_capability - -2007-09-17 Paul Jakma <paul.jakma@sun.com> - - * bgp_capability_test.c: Test that peer's adv_recv and adv_nego get - set correctly for MP capability and given AFI/SAFI. - Colour OK/failed result so it's easier to find them. - -2007-07-27 Paul Jakma <paul.jakma@sun.com> - - * bgp_capability_test.c: new, capability parser unit tests. - * Makefile.am: add previous. - -2007-07-25 Paul Jakma <paul.jakma@sun.com> - - * aspath_test.c: Exercise 32bit parsing. Test reconcile - function. - * ecommunity_test.c: New, test AS4 ecommunity changes, positive - test only at this time, error cases not tested yet. - -2006-12-01 Juergen Kammer <j.kammer@eurodata.de> - - * aspath_test.c: Support asn32 changes, call aspath_parse with 16 bit. - -2006-08-26 Paul Jakma <paul.jakma@sun.com> - - * heavy-wq.c: (slow_func_del,slow_func) update to match workqueue - changes - -2006-08-06 Paul Jakma <paul.jakma@sun.com> - - * aspath_test.c: (validate) Fix the sense of the aspath_loop_check, - which was the wrong way around and had actually been testing for - aspath_loop_check to be buggy. - -2006-05-28 Paul Jakma <paul.jakma@sun.com> - - * test-sig.c: (main) configure logging, there's no terminal - to write to for one thing, but we do want stdout, and we - don't want a test to spam syslog. - -2006-03-16 Paul Jakma <paul.jakma@sun.com> - - * heavy-wq.c: (heavy_wq_init) delay is gone from workqueue - spec. - * aspath_test.c: (test_segments) Add an AS_SET with redundant - ASNs. - ({empty_prepend,prepend,parse}_test) add static qualifiers - -2006-01-16 Paul Jakma <paul.jakma@sun.com> - - * aspath_test.c: (validate) free the temporary aspaths. - (empty_get_test) ditto. - -2006-01-10 Paul Jakma <paul.jakma@sun.com> - - * test-stream.c: new file, small unit test for new - resize and {put,get}-quad stream functions. - * Makefile.am: build teststream unit test. - -2005-11-23 Paul Jakma <paul.jakma@sun.com> - - * aspath_test.c: Add an empty aspath to test segments, and to - compare tests. - Add a segment identical to seq1, but with one extra asn. - Fix bogus free of stream in make_aspath for case where - no stream was allocated (empty path data). - -2005-10-11 Paul Jakma <paul.jakma@sun.com> - - * test-privs.c: Privileges unit test. - * Makefile.am: build testprivs - * aspath_test.c: fix a few sign warnings - -2005-09-06 Paul Jakma <paul@dishone.st> - - * aspath_test.c: Test bgp_aspath functionality. - * Makefile.am: build aspathtest - * ChangeLog: Fix date of previous commit - -2005-09-06 Paul Jakma <paul@dishone.st> - - * test-buffer.c: include memory.h - (main) call memory_init(). - -2004-09-05 Paul Jakma <paul@dishone.st> - - * heavy-wq.c: (slow_func_del,slow_func_err) make them take - void * argument to shut up silly gcc warning. - -2004-05-25 Paul Jakma <paul@dishone.st> - - * main.c: new file, common 'main' portion which then calls - test_init. - * heavy.c: remove common portions now in 'main. - * heavy-wq.c: ditto - * heavy-thread.c: ditto - * heavy*.c: Set the slow_function iteration number lower, to 300, it - was several orders of magnitude too 'slow' to be useful. :) - * Makefile.am: main is a source of the tests. heavy should link - to the math library. - -2004-05-22 Paul Jakma <paul@dishone.st> - - * heavy-thread.c: Andrew Schorr's adaptation of heavy.c to use a - background thread to avoid responsiveness problems. - * Makefile.am: Build heavythread - -2004-05-21 Paul Jakma <paul@dishone.st> - - * heavy.c: Add a timer thread to demonstrate thread interactivity, - Add a daemon_exit command to assist with debugging (eg for memory - tracers, etc..) - -2004-05-19 Paul Jakma <paul@dishone.st> - - * heavy.c: test programme to show how long-running functions - kill responsiveness. Demonstrating the most niggly problem - left in bgpd. - -2004-05-13 Paul Jakma <paul@dishone.st> - - * test-buffer.c: Andrew's buffer tester - * test-memory.c: basic memory tester - * Makefile.am: Add new tests diff --git a/tests/Makefile.am b/tests/Makefile.am index d00485f1..4ab507bb 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,9 +1,12 @@ INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\" +AM_CFLAGS = $(PICFLAGS) +AM_LDFLAGS = $(PILDFLAGS) + noinst_PROGRAMS = testsig testbuffer testmemory heavy heavywq heavythread \ aspathtest testprivs teststream testbgpcap ecommtest \ - testbgpmpattr + testbgpmpattr testchecksum testsig_SOURCES = test-sig.c testbuffer_SOURCES = test-buffer.c @@ -17,6 +20,7 @@ aspathtest_SOURCES = aspath_test.c testbgpcap_SOURCES = bgp_capability_test.c ecommtest_SOURCES = ecommunity_test.c testbgpmpattr_SOURCES = bgp_mp_attr_test.c +testchecksum_SOURCES = test-checksum.c testsig_LDADD = ../lib/libzebra.la @LIBCAP@ testbuffer_LDADD = ../lib/libzebra.la @LIBCAP@ @@ -30,3 +34,4 @@ aspathtest_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a testbgpcap_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a ecommtest_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a testbgpmpattr_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a +testchecksum_LDADD = ../lib/libzebra.la @LIBCAP@ diff --git a/tests/heavy-wq.c b/tests/heavy-wq.c index 543b9dbb..a2c609d4 100644 --- a/tests/heavy-wq.c +++ b/tests/heavy-wq.c @@ -1,5 +1,5 @@ /* - * $Id: heavy-wq.c,v 1.4 2006/08/27 06:53:24 paul Exp $ + * $Id$ * * This file is part of Quagga. * diff --git a/tests/test-checksum.c b/tests/test-checksum.c new file mode 100644 index 00000000..d218840d --- /dev/null +++ b/tests/test-checksum.c @@ -0,0 +1,499 @@ +#include <zebra.h> +#include <stdlib.h> +#include <time.h> + +#include "checksum.h" + +struct thread_master *master; + +struct acc_vals { + int c0; + int c1; +}; + +struct csum_vals { + struct acc_vals a; + int x; + int y; +}; + +static struct csum_vals ospfd_vals, isisd_vals; + +typedef size_t testsz_t; +typedef uint16_t testoff_t; + +/* Fletcher Checksum -- Refer to RFC1008. */ +#define MODX 4102 + +/* Accumulator phase of checksum */ +static +struct acc_vals +accumulate (u_char *buffer, testsz_t len, testoff_t off) +{ + u_int8_t *p; + u_int16_t *csum; + int i, init_len, partial_len; + struct acc_vals ret; + + csum = (u_int16_t *) (buffer + off); + *(csum) = 0; + + p = buffer; + ret.c0 = 0; + ret.c1 = 0; + init_len = len; + + while (len != 0) + { + partial_len = MIN(len, MODX); + + for (i = 0; i < partial_len; i++) + { + ret.c0 = ret.c0 + *(p++); + ret.c1 += ret.c0; + } + + ret.c0 = ret.c0 % 255; + ret.c1 = ret.c1 % 255; + + len -= partial_len; + } + return ret; +} + +/* The final reduction phase. + * This one should be the original ospfd version + */ +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; + + /* take care endian issue. */ + return htons ((x << 8) + y); +#undef x +#undef y +#undef c0 +#undef c1 +} + +/* slightly different concatenation */ +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; + + /* take care endian issue. */ + return htons ((x << 8) | (y & 0xff)); +#undef x +#undef y +#undef c0 +#undef c1 +} + +/* original isisd version */ +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; + + if (y > 0) + y++; + if (x < 0) + x--; + + x %= 255; + y %= 255; + + if (x == 0) + x = 255; + if (y == 0) + y = 1; + + return htons ((x << 8) | (y & 0xff)); + +#undef x +#undef y +#undef c0 +#undef c1 +} + +/* Is the -1 in y wrong perhaps? */ +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; + + if (y > 0) + y++; + if (x < 0) + x--; + + x %= 255; + y %= 255; + + if (x == 0) + x = 255; + if (y == 0) + y = 1; + + return htons ((x << 8) | (y & 0xff)); + +#undef x +#undef y +#undef c0 +#undef c1 +} + +/* Move the mods yp */ +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; + + x %= 255; + y %= 255; + + if (y > 0) + y++; + if (x < 0) + x--; + + if (x == 0) + x = 255; + if (y == 0) + y = 1; + + return htons ((x << 8) | (y & 0xff)); + +#undef x +#undef y +#undef c0 +#undef c1 +} + +/* Move the mods up + fix y */ +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; + + x %= 255; + y %= 255; + + if (y > 0) + y++; + if (x < 0) + x--; + + if (x == 0) + x = 255; + if (y == 0) + y = 1; + + return htons ((x << 8) | (y & 0xff)); + +#undef x +#undef y +#undef c0 +#undef c1 +} + +struct reductions_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 }, +}; + +/* The original ospfd checksum */ +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); +} + +/* the original, broken isisd checksum */ +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; + } + + 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; +} + +static int +verify (u_char * buffer, testsz_t len) +{ + u_int8_t *p; + u_int32_t c0; + u_int32_t c1; + u_int16_t checksum; + int i, partial_len; + + p = buffer; + checksum = 0; + + c0 = 0; + c1 = 0; + + while (len) + { + partial_len = MIN(len, 5803); + + 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; +} + +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; +#define EXERCISESTEP 257 + + srandom (time (NULL)); + + while (1) { + u_int16_t ospfd, isisd, lib; + + exercise += EXERCISESTEP; + exercise %= MAXDATALEN; + + for (int i = 0; i < exercise; i += sizeof (long int)) { + long int rand = random (); + + for (int j = sizeof (long int); j > 0; j--) + buffer[i + (sizeof (long int) - j)] = (rand >> (j * 8)) & 0xff; + } + + 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 (int 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 (int i = 0; i < exercise; i++) { + printf ("0x%02x,%s", + buffer[i], + (i + 1) % 8 ? " " : "\n "); + } + printf ("\n}\n"); + exit (1); + } + } +} |