summaryrefslogtreecommitdiffstats
path: root/tests/isisd
diff options
context:
space:
mode:
authorChristian Franke <chris@opensourcerouting.org>2017-05-08 13:02:55 +0200
committerChristian Franke <chris@opensourcerouting.org>2017-08-03 11:34:04 +0200
commit7ef5fefc3c10f8dc6034344b9a0eed9b365332de (patch)
treed37cf16344f7982f08e321de0c5fd30747e1c59e /tests/isisd
parentisisd: add formatter code (diff)
downloadfrr-7ef5fefc3c10f8dc6034344b9a0eed9b365332de.tar.xz
frr-7ef5fefc3c10f8dc6034344b9a0eed9b365332de.zip
isisd: add new tlv parser
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
Diffstat (limited to 'tests/isisd')
-rw-r--r--tests/isisd/.gitignore1
-rw-r--r--tests/isisd/test_fuzz_isis_tlv.c188
-rw-r--r--tests/isisd/test_fuzz_isis_tlv.py6
-rw-r--r--tests/isisd/test_fuzz_isis_tlv_tests.h.gzbin0 -> 232370 bytes
4 files changed, 195 insertions, 0 deletions
diff --git a/tests/isisd/.gitignore b/tests/isisd/.gitignore
new file mode 100644
index 000000000..e12422129
--- /dev/null
+++ b/tests/isisd/.gitignore
@@ -0,0 +1 @@
+/*_afl/*
diff --git a/tests/isisd/test_fuzz_isis_tlv.c b/tests/isisd/test_fuzz_isis_tlv.c
new file mode 100644
index 000000000..33eb4b523
--- /dev/null
+++ b/tests/isisd/test_fuzz_isis_tlv.c
@@ -0,0 +1,188 @@
+#include "test_fuzz_isis_tlv_tests.h"
+
+#include <zebra.h>
+
+#include "memory.h"
+#include "sbuf.h"
+#include "stream.h"
+#include "thread.h"
+
+#include "isisd/isis_circuit.h"
+#include "isisd/isis_tlvs2.h"
+
+#define TEST_STREAM_SIZE 1500
+
+struct thread_master *master;
+int isis_sock_init(struct isis_circuit *circuit);
+int isis_sock_init(struct isis_circuit *circuit)
+{
+ return 0;
+}
+
+static bool atexit_registered;
+
+static void show_meminfo_at_exit(void)
+{
+ log_memstats_stderr("isis fuzztest");
+}
+
+static int comp_line(const void *p1, const void *p2)
+{
+ return strcmp(*(char * const *)p1, *(char * const *)p2);
+}
+
+static char *sortlines(char *in)
+{
+ size_t line_count = 1;
+ size_t rv_len = strlen(in) + 1;
+ size_t rv_pos = 0;
+ char *rv = XMALLOC(MTYPE_TMP, rv_len);
+
+ for (char *c = in; *c; c++) {
+ if (*c == '\n')
+ line_count++;
+ }
+
+ if (line_count == 1) {
+ strncpy(rv, in, rv_len);
+ return rv;
+ }
+
+ char **lines = XCALLOC(MTYPE_TMP, sizeof(char *)*line_count);
+ char *saveptr = NULL;
+ size_t i = 0;
+
+ for (char *line = strtok_r(in, "\n", &saveptr); line;
+ line = strtok_r(NULL, "\n", &saveptr)) {
+ lines[i++] = line;
+ assert(i <= line_count);
+ }
+
+ line_count = i;
+
+ qsort(lines, line_count, sizeof(char *), comp_line);
+
+ for (i = 0; i < line_count; i++) {
+ int printf_rv = snprintf(rv + rv_pos, rv_len - rv_pos, "%s\n", lines[i]);
+ assert(printf_rv >= 0);
+ rv_pos += printf_rv;
+ }
+
+ XFREE(MTYPE_TMP, lines);
+ return rv;
+}
+
+static int test(FILE *input, FILE *output)
+{
+ struct stream *s = stream_new(TEST_STREAM_SIZE);
+ char buf[TEST_STREAM_SIZE];
+ size_t bytes_read = 0;
+
+ if (!atexit_registered) {
+ atexit(show_meminfo_at_exit);
+ atexit_registered = true;
+ }
+
+ while (STREAM_WRITEABLE(s) && !feof(input)) {
+ bytes_read = fread(buf, 1, STREAM_WRITEABLE(s), input);
+ if (bytes_read == 0)
+ break;
+ stream_put(s, buf, bytes_read);
+ }
+
+ if (bytes_read && !feof(input)) {
+ fprintf(output, "Too much input data.\n");
+ stream_free(s);
+ return 1;
+ }
+
+ stream_set_getp(s, 0);
+ struct isis_tlvs *tlvs;
+ const char *log;
+ int rv = isis_unpack_tlvs(STREAM_READABLE(s), s, &tlvs, &log);
+
+ if (rv) {
+ fprintf(output, "Could not unpack TLVs:\n%s\n", log);
+ isis_free_tlvs(tlvs);
+ stream_free(s);
+ return 2;
+ }
+
+ fprintf(output, "Unpack log:\n%s", log);
+ const char *s_tlvs = isis_format_tlvs(tlvs);
+ fprintf(output, "Unpacked TLVs:\n%s", s_tlvs);
+
+ struct isis_tlvs *tlv_copy = isis_copy_tlvs(tlvs);
+ isis_free_tlvs(tlvs);
+
+ struct stream *s2 = stream_new(TEST_STREAM_SIZE);
+
+ if (isis_pack_tlvs(tlv_copy, s2, (size_t)-1, false, false)) {
+ fprintf(output, "Could not pack TLVs.\n");
+ assert(0);
+ }
+
+ stream_set_getp(s2, 0);
+ rv = isis_unpack_tlvs(STREAM_READABLE(s2), s2, &tlvs, &log);
+ if (rv) {
+ fprintf(output, "Could not unpack own TLVs:\n%s\n", log);
+ assert(0);
+ }
+
+ char *orig_tlvs = XSTRDUP(MTYPE_TMP, s_tlvs);
+ s_tlvs = isis_format_tlvs(tlvs);
+
+ if (strcmp(orig_tlvs, s_tlvs)) {
+ fprintf(output,
+ "Deserialized and Serialized LSP seem to differ.\n");
+ fprintf(output, "Re-Unpacked TLVs:\n%s", s_tlvs);
+ assert(0);
+ }
+
+ isis_free_tlvs(tlv_copy);
+ stream_free(s);
+ stream_free(s2);
+
+ struct list *fragments = isis_fragment_tlvs(tlvs, 550);
+ isis_free_tlvs(tlvs);
+ if (!fragments) {
+ XFREE(MTYPE_TMP, orig_tlvs);
+ return 0;
+ }
+
+ s = stream_new(550);
+
+ struct sbuf fragment_format;
+ sbuf_init(&fragment_format, NULL, 0);
+
+ struct listnode *node;
+ for (ALL_LIST_ELEMENTS_RO(fragments, node, tlvs)) {
+ stream_reset(s);
+ int rv = isis_pack_tlvs(tlvs, s, (size_t)-1, false, false);
+ if (rv) {
+ fprintf(output, "Could not pack fragment, too large.\n");
+ assert(0);
+ }
+ sbuf_push(&fragment_format, 0, "%s", isis_format_tlvs(tlvs));
+ isis_free_tlvs(tlvs);
+ }
+ list_delete(fragments);
+ stream_free(s);
+
+ char *fragment_content = sortlines((char *)sbuf_buf(&fragment_format));
+ sbuf_free(&fragment_format);
+ char *orig_tlv_content = sortlines(orig_tlvs);
+ XFREE(MTYPE_TMP, orig_tlvs);
+
+ if (strcmp(fragment_content, orig_tlv_content)) {
+ fprintf(output, "Fragmented and unfragmented LSP seem to differ.\n");
+ fprintf(output, "Original:\n%s\nFragmented:\n%s\n",
+ orig_tlv_content, fragment_content);
+ assert(0);
+ }
+
+ XFREE(MTYPE_TMP, fragment_content);
+ XFREE(MTYPE_TMP, orig_tlv_content);
+
+ return 0;
+}
diff --git a/tests/isisd/test_fuzz_isis_tlv.py b/tests/isisd/test_fuzz_isis_tlv.py
new file mode 100644
index 000000000..60938472b
--- /dev/null
+++ b/tests/isisd/test_fuzz_isis_tlv.py
@@ -0,0 +1,6 @@
+import frrtest
+
+class TestFuzzIsisTLV(frrtest.TestMultiOut):
+ program = './test_fuzz_isis_tlv'
+
+TestFuzzIsisTLV.exit_cleanly()
diff --git a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz
new file mode 100644
index 000000000..3eb0205a5
--- /dev/null
+++ b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz
Binary files differ