forked from Mirror/frr
isisd: add new tlv parser
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
This commit is contained in:
parent
9879e291a4
commit
7ef5fefc3c
|
@ -8,7 +8,7 @@ LIBS = @LIBS@
|
|||
AM_CFLAGS = $(WERROR)
|
||||
|
||||
noinst_LIBRARIES = libisis.a
|
||||
sbin_PROGRAMS = isisd
|
||||
sbin_PROGRAMS = isisd
|
||||
|
||||
libisis_a_SOURCES = \
|
||||
isis_memory.c \
|
||||
|
@ -16,7 +16,8 @@ libisis_a_SOURCES = \
|
|||
isis_tlv.c isisd.c isis_misc.c isis_zebra.c isis_dr.c \
|
||||
isis_flags.c isis_dynhn.c iso_checksum.c isis_csm.c isis_events.c \
|
||||
isis_spf.c isis_redist.c isis_route.c isis_routemap.c isis_te.c \
|
||||
isis_vty.c isis_mt.c
|
||||
isis_vty.c isis_mt.c \
|
||||
isis_tlvs2.c
|
||||
|
||||
|
||||
noinst_HEADERS = \
|
||||
|
@ -25,7 +26,8 @@ noinst_HEADERS = \
|
|||
isis_lsp.h dict.h isis_circuit.h isis_misc.h isis_network.h \
|
||||
isis_zebra.h isis_dr.h isis_flags.h isis_dynhn.h isis_common.h \
|
||||
iso_checksum.h isis_csm.h isis_events.h isis_spf.h isis_redist.h \
|
||||
isis_route.h isis_routemap.h isis_te.h isis_mt.h
|
||||
isis_route.h isis_routemap.h isis_te.h isis_mt.h \
|
||||
isis_tlvs2.h
|
||||
|
||||
isisd_SOURCES = \
|
||||
isis_main.c $(libisis_a_SOURCES) \
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#define ISIS_MT_MASK 0x0fff
|
||||
#define ISIS_MT_OL_MASK 0x8000
|
||||
#define ISIS_MT_AT_MASK 0x4000
|
||||
|
||||
#define ISIS_MT_IPV4_UNICAST 0
|
||||
#define ISIS_MT_IPV4_MGMT 1
|
||||
|
|
3085
isisd/isis_tlvs2.c
Normal file
3085
isisd/isis_tlvs2.c
Normal file
File diff suppressed because it is too large
Load diff
308
isisd/isis_tlvs2.h
Normal file
308
isisd/isis_tlvs2.h
Normal file
|
@ -0,0 +1,308 @@
|
|||
/*
|
||||
* IS-IS TLV Serializer/Deserializer
|
||||
*
|
||||
* Copyright (C) 2015,2017 Christian Franke
|
||||
*
|
||||
* This file is part of FRR.
|
||||
*
|
||||
* FRR is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* FRR is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with FRR; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
#ifndef ISIS_TLVS2_H
|
||||
#define ISIS_TLVS2_H
|
||||
|
||||
#include "openbsd-tree.h"
|
||||
#include "prefix.h"
|
||||
#include "isisd/dict.h"
|
||||
|
||||
struct isis_subtlvs;
|
||||
|
||||
struct isis_area_address;
|
||||
struct isis_area_address {
|
||||
struct isis_area_address *next;
|
||||
|
||||
uint8_t addr[20];
|
||||
uint8_t len;
|
||||
};
|
||||
|
||||
struct isis_oldstyle_reach;
|
||||
struct isis_oldstyle_reach {
|
||||
struct isis_oldstyle_reach *next;
|
||||
|
||||
uint8_t id[7];
|
||||
uint8_t metric;
|
||||
};
|
||||
|
||||
struct isis_oldstyle_ip_reach;
|
||||
struct isis_oldstyle_ip_reach {
|
||||
struct isis_oldstyle_ip_reach *next;
|
||||
|
||||
uint8_t metric;
|
||||
struct prefix_ipv4 prefix;
|
||||
};
|
||||
|
||||
struct isis_lsp_entry;
|
||||
struct isis_lsp_entry {
|
||||
struct isis_lsp_entry *next;
|
||||
|
||||
uint16_t rem_lifetime;
|
||||
uint8_t id[8];
|
||||
uint16_t checksum;
|
||||
uint32_t seqno;
|
||||
|
||||
struct isis_lsp *lsp;
|
||||
};
|
||||
|
||||
struct isis_extended_reach;
|
||||
struct isis_extended_reach {
|
||||
struct isis_extended_reach *next;
|
||||
|
||||
uint8_t id[7];
|
||||
uint32_t metric;
|
||||
|
||||
uint8_t *subtlvs;
|
||||
uint8_t subtlv_len;
|
||||
};
|
||||
|
||||
struct isis_extended_ip_reach;
|
||||
struct isis_extended_ip_reach {
|
||||
struct isis_extended_ip_reach *next;
|
||||
|
||||
uint32_t metric;
|
||||
bool down;
|
||||
struct prefix_ipv4 prefix;
|
||||
};
|
||||
|
||||
struct isis_ipv6_reach;
|
||||
struct isis_ipv6_reach {
|
||||
struct isis_ipv6_reach *next;
|
||||
|
||||
uint32_t metric;
|
||||
bool down;
|
||||
bool external;
|
||||
|
||||
struct prefix_ipv6 prefix;
|
||||
|
||||
struct isis_subtlvs *subtlvs;
|
||||
};
|
||||
|
||||
struct isis_protocols_supported {
|
||||
uint8_t count;
|
||||
uint8_t *protocols;
|
||||
};
|
||||
|
||||
struct isis_item;
|
||||
struct isis_item {
|
||||
struct isis_item *next;
|
||||
};
|
||||
|
||||
struct isis_lan_neighbor;
|
||||
struct isis_lan_neighbor {
|
||||
struct isis_lan_neighbor *next;
|
||||
|
||||
uint8_t mac[6];
|
||||
};
|
||||
|
||||
struct isis_ipv4_address;
|
||||
struct isis_ipv4_address {
|
||||
struct isis_ipv4_address *next;
|
||||
|
||||
struct in_addr addr;
|
||||
};
|
||||
|
||||
struct isis_ipv6_address;
|
||||
struct isis_ipv6_address {
|
||||
struct isis_ipv6_address *next;
|
||||
|
||||
struct in6_addr addr;
|
||||
};
|
||||
|
||||
struct isis_mt_router_info;
|
||||
struct isis_mt_router_info {
|
||||
struct isis_mt_router_info *next;
|
||||
|
||||
bool overload;
|
||||
bool attached;
|
||||
uint16_t mtid;
|
||||
};
|
||||
|
||||
struct isis_auth;
|
||||
struct isis_auth {
|
||||
struct isis_auth *next;
|
||||
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t value[256];
|
||||
|
||||
uint8_t plength;
|
||||
uint8_t passwd[256];
|
||||
|
||||
size_t offset; /* Only valid after packing */
|
||||
};
|
||||
|
||||
struct isis_item_list;
|
||||
struct isis_item_list {
|
||||
struct isis_item *head;
|
||||
struct isis_item **tail;
|
||||
|
||||
RB_ENTRY(isis_item_list) mt_tree;
|
||||
uint16_t mtid;
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
RB_HEAD(isis_mt_item_list, isis_item_list);
|
||||
|
||||
struct isis_item_list *isis_get_mt_items(struct isis_mt_item_list *m,
|
||||
uint16_t mtid);
|
||||
struct isis_item_list *isis_lookup_mt_items(struct isis_mt_item_list *m,
|
||||
uint16_t mtid);
|
||||
|
||||
struct isis_tlvs {
|
||||
struct isis_item_list isis_auth;
|
||||
struct isis_item_list area_addresses;
|
||||
struct isis_item_list oldstyle_reach;
|
||||
struct isis_item_list lan_neighbor;
|
||||
struct isis_item_list lsp_entries;
|
||||
struct isis_item_list extended_reach;
|
||||
struct isis_mt_item_list mt_reach;
|
||||
struct isis_item_list oldstyle_ip_reach;
|
||||
struct isis_protocols_supported protocols_supported;
|
||||
struct isis_item_list oldstyle_ip_reach_ext;
|
||||
struct isis_item_list ipv4_address;
|
||||
struct isis_item_list ipv6_address;
|
||||
struct isis_item_list mt_router_info;
|
||||
bool mt_router_info_empty;
|
||||
struct in_addr *te_router_id;
|
||||
struct isis_item_list extended_ip_reach;
|
||||
struct isis_mt_item_list mt_ip_reach;
|
||||
char *hostname;
|
||||
struct isis_item_list ipv6_reach;
|
||||
struct isis_mt_item_list mt_ipv6_reach;
|
||||
};
|
||||
|
||||
struct isis_subtlvs {
|
||||
/* draft-baker-ipv6-isis-dst-src-routing-06 */
|
||||
struct prefix_ipv6 *source_prefix;
|
||||
};
|
||||
|
||||
enum isis_tlv_context {
|
||||
ISIS_CONTEXT_LSP,
|
||||
ISIS_CONTEXT_SUBTLV_NE_REACH,
|
||||
ISIS_CONTEXT_SUBTLV_IP_REACH,
|
||||
ISIS_CONTEXT_SUBTLV_IPV6_REACH,
|
||||
ISIS_CONTEXT_MAX
|
||||
};
|
||||
|
||||
enum isis_tlv_type {
|
||||
ISIS_TLV_AREA_ADDRESSES = 1,
|
||||
ISIS_TLV_OLDSTYLE_REACH = 2,
|
||||
ISIS_TLV_LAN_NEIGHBORS = 6,
|
||||
ISIS_TLV_PADDING = 8,
|
||||
ISIS_TLV_LSP_ENTRY = 9,
|
||||
ISIS_TLV_AUTH = 10,
|
||||
ISIS_TLV_EXTENDED_REACH = 22,
|
||||
|
||||
ISIS_TLV_OLDSTYLE_IP_REACH = 128,
|
||||
ISIS_TLV_PROTOCOLS_SUPPORTED = 129,
|
||||
ISIS_TLV_OLDSTYLE_IP_REACH_EXT = 130,
|
||||
ISIS_TLV_IPV4_ADDRESS = 132,
|
||||
ISIS_TLV_TE_ROUTER_ID = 134,
|
||||
ISIS_TLV_EXTENDED_IP_REACH = 135,
|
||||
ISIS_TLV_DYNAMIC_HOSTNAME = 137,
|
||||
ISIS_TLV_MT_REACH = 222,
|
||||
ISIS_TLV_MT_ROUTER_INFO = 229,
|
||||
ISIS_TLV_IPV6_ADDRESS = 232,
|
||||
ISIS_TLV_MT_IP_REACH = 235,
|
||||
ISIS_TLV_IPV6_REACH = 236,
|
||||
ISIS_TLV_MT_IPV6_REACH = 237,
|
||||
ISIS_TLV_MAX = 256,
|
||||
|
||||
ISIS_SUBTLV_IPV6_SOURCE_PREFIX = 22
|
||||
};
|
||||
|
||||
#define IS_COMPAT_MT_TLV(tlv_type) \
|
||||
((tlv_type == ISIS_TLV_MT_REACH) || (tlv_type == ISIS_TLV_MT_IP_REACH) \
|
||||
|| (tlv_type == ISIS_TLV_MT_IPV6_REACH))
|
||||
|
||||
struct stream;
|
||||
int isis_pack_tlvs(struct isis_tlvs *tlvs, struct stream *stream,
|
||||
size_t len_pointer, bool pad, bool is_lsp);
|
||||
void isis_free_tlvs(struct isis_tlvs *tlvs);
|
||||
struct isis_tlvs *isis_alloc_tlvs(void);
|
||||
int isis_unpack_tlvs(size_t avail_len, struct stream *stream,
|
||||
struct isis_tlvs **dest, const char **error_log);
|
||||
const char *isis_format_tlvs(struct isis_tlvs *tlvs);
|
||||
struct isis_tlvs *isis_copy_tlvs(struct isis_tlvs *tlvs);
|
||||
struct list *isis_fragment_tlvs(struct isis_tlvs *tlvs, size_t size);
|
||||
|
||||
#define ISIS_EXTENDED_IP_REACH_DOWN 0x80
|
||||
#define ISIS_EXTENDED_IP_REACH_SUBTLV 0x40
|
||||
|
||||
#define ISIS_IPV6_REACH_DOWN 0x80
|
||||
#define ISIS_IPV6_REACH_EXTERNAL 0x40
|
||||
#define ISIS_IPV6_REACH_SUBTLV 0x20
|
||||
|
||||
#ifndef ISIS_MT_MASK
|
||||
#define ISIS_MT_MASK 0x0fff
|
||||
#define ISIS_MT_OL_MASK 0x8000
|
||||
#define ISIS_MT_AT_MASK 0x4000
|
||||
#endif
|
||||
|
||||
|
||||
void isis_tlvs_add_auth(struct isis_tlvs *tlvs, struct isis_passwd *passwd);
|
||||
void isis_tlvs_add_area_addresses(struct isis_tlvs *tlvs,
|
||||
struct list *addresses);
|
||||
void isis_tlvs_add_lan_neighbors(struct isis_tlvs *tlvs,
|
||||
struct list *neighbors);
|
||||
void isis_tlvs_set_protocols_supported(struct isis_tlvs *tlvs,
|
||||
struct nlpids *nlpids);
|
||||
void isis_tlvs_add_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid,
|
||||
bool overload, bool attached);
|
||||
void isis_tlvs_add_ipv4_address(struct isis_tlvs *tlvs, struct in_addr *addr);
|
||||
void isis_tlvs_add_ipv4_addresses(struct isis_tlvs *tlvs,
|
||||
struct list *addresses);
|
||||
void isis_tlvs_add_ipv6_addresses(struct isis_tlvs *tlvs,
|
||||
struct list *addresses);
|
||||
bool isis_tlvs_auth_is_valid(struct isis_tlvs *tlvs, struct isis_passwd *passwd,
|
||||
struct stream *stream, bool is_lsp);
|
||||
bool isis_tlvs_area_addresses_match(struct isis_tlvs *tlvs,
|
||||
struct list *addresses);
|
||||
struct isis_adjacency;
|
||||
void isis_tlvs_to_adj(struct isis_tlvs *tlvs, struct isis_adjacency *adj,
|
||||
bool *changed);
|
||||
bool isis_tlvs_own_snpa_found(struct isis_tlvs *tlvs, uint8_t *snpa);
|
||||
void isis_tlvs_add_lsp_entry(struct isis_tlvs *tlvs, struct isis_lsp *lsp);
|
||||
void isis_tlvs_add_csnp_entries(struct isis_tlvs *tlvs, uint8_t *start_id,
|
||||
uint8_t *stop_id, uint16_t num_lsps,
|
||||
dict_t *lspdb, struct isis_lsp **last_lsp);
|
||||
void isis_tlvs_set_dynamic_hostname(struct isis_tlvs *tlvs,
|
||||
const char *hostname);
|
||||
void isis_tlvs_set_te_router_id(struct isis_tlvs *tlvs,
|
||||
const struct in_addr *id);
|
||||
void isis_tlvs_add_oldstyle_ip_reach(struct isis_tlvs *tlvs,
|
||||
struct prefix_ipv4 *dest, uint8_t metric);
|
||||
void isis_tlvs_add_extended_ip_reach(struct isis_tlvs *tlvs,
|
||||
struct prefix_ipv4 *dest, uint32_t metric);
|
||||
void isis_tlvs_add_ipv6_reach(struct isis_tlvs *tlvs, uint16_t mtid,
|
||||
struct prefix_ipv6 *dest, uint32_t metric);
|
||||
void isis_tlvs_add_oldstyle_reach(struct isis_tlvs *tlvs, uint8_t *id,
|
||||
uint8_t metric);
|
||||
void isis_tlvs_add_extended_reach(struct isis_tlvs *tlvs, uint16_t mtid,
|
||||
uint8_t *id, uint32_t metric,
|
||||
uint8_t *subtlvs, uint8_t subtlv_len);
|
||||
|
||||
struct isis_mt_router_info *
|
||||
isis_tlvs_lookup_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid);
|
||||
#endif
|
2
tests/.gitignore
vendored
2
tests/.gitignore
vendored
|
@ -25,6 +25,8 @@ __pycache__
|
|||
/bgpd/test_ecommunity
|
||||
/bgpd/test_mp_attr
|
||||
/bgpd/test_mpath
|
||||
/isisd/test_fuzz_isis_tlv
|
||||
/isisd/test_fuzz_isis_tlv_tests.h
|
||||
/lib/cli/test_cli
|
||||
/lib/cli/test_commands
|
||||
/lib/cli/test_commands_defun.c
|
||||
|
|
|
@ -24,6 +24,13 @@ else
|
|||
TESTS_BGPD =
|
||||
endif
|
||||
|
||||
if ISISD
|
||||
TESTS_ISISD = \
|
||||
isisd/test_fuzz_isis_tlv
|
||||
else
|
||||
TESTS_ISISD =
|
||||
endif
|
||||
|
||||
if OSPF6D
|
||||
TESTS_OSPF6D = \
|
||||
ospf6d/test_lsdb \
|
||||
|
@ -61,6 +68,7 @@ check_PROGRAMS = \
|
|||
lib/cli/test_cli \
|
||||
lib/cli/test_commands \
|
||||
$(TESTS_BGPD) \
|
||||
$(TESTS_ISISD) \
|
||||
$(TESTS_OSPF6D) \
|
||||
# end
|
||||
|
||||
|
@ -75,7 +83,12 @@ lib/cli/test_commands_defun.c: ../vtysh/vtysh_cmd.c
|
|||
< ../vtysh/vtysh_cmd.c \
|
||||
> "$@"
|
||||
|
||||
BUILT_SOURCES = lib/cli/test_commands_defun.c
|
||||
isisd/test_fuzz_isis_tlv_tests.h: $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz
|
||||
gzip -d < $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz > "$@"
|
||||
|
||||
BUILT_SOURCES = \
|
||||
lib/cli/test_commands_defun.c \
|
||||
isisd/test_fuzz_isis_tlv_tests.h
|
||||
|
||||
noinst_HEADERS = \
|
||||
./helpers/c/prng.h \
|
||||
|
@ -110,11 +123,14 @@ bgpd_test_capability_SOURCES = bgpd/test_capability.c
|
|||
bgpd_test_ecommunity_SOURCES = bgpd/test_ecommunity.c
|
||||
bgpd_test_mp_attr_SOURCES = bgpd/test_mp_attr.c
|
||||
bgpd_test_mpath_SOURCES = bgpd/test_mpath.c
|
||||
isisd_test_fuzz_isis_tlv_SOURCES = isisd/test_fuzz_isis_tlv.c
|
||||
isisd_test_fuzz_isis_tlv_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/tests/isisd
|
||||
|
||||
ospf6d_test_lsdb_SOURCES = ospf6d/test_lsdb.c lib/cli/common_cli.c
|
||||
|
||||
ALL_TESTS_LDADD = ../lib/libfrr.la @LIBCAP@
|
||||
BGP_TEST_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) $(ALL_TESTS_LDADD) -lm
|
||||
ISISD_TEST_LDADD = ../isisd/libisis.a $(ALL_TESTS_LDADD)
|
||||
OSPF6_TEST_LDADD = ../ospf6d/libospf6.a $(ALL_TESTS_LDADD)
|
||||
|
||||
lib_test_buffer_LDADD = $(ALL_TESTS_LDADD)
|
||||
|
@ -140,6 +156,7 @@ bgpd_test_capability_LDADD = $(BGP_TEST_LDADD)
|
|||
bgpd_test_ecommunity_LDADD = $(BGP_TEST_LDADD)
|
||||
bgpd_test_mp_attr_LDADD = $(BGP_TEST_LDADD)
|
||||
bgpd_test_mpath_LDADD = $(BGP_TEST_LDADD)
|
||||
isisd_test_fuzz_isis_tlv_LDADD = $(ISISD_TEST_LDADD)
|
||||
ospf6d_test_lsdb_LDADD = $(OSPF6_TEST_LDADD)
|
||||
|
||||
EXTRA_DIST = \
|
||||
|
@ -151,6 +168,8 @@ EXTRA_DIST = \
|
|||
bgpd/test_mpath.py \
|
||||
helpers/python/frrsix.py \
|
||||
helpers/python/frrtest.py \
|
||||
isisd/test_fuzz_isis_tlv.py \
|
||||
isisd/test_fuzz_isis_tlv_tests.h.gz \
|
||||
lib/cli/test_commands.in \
|
||||
lib/cli/test_commands.py \
|
||||
lib/cli/test_commands.refout \
|
||||
|
|
1
tests/isisd/.gitignore
vendored
Normal file
1
tests/isisd/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/*_afl/*
|
188
tests/isisd/test_fuzz_isis_tlv.c
Normal file
188
tests/isisd/test_fuzz_isis_tlv.c
Normal file
|
@ -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;
|
||||
}
|
6
tests/isisd/test_fuzz_isis_tlv.py
Normal file
6
tests/isisd/test_fuzz_isis_tlv.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
import frrtest
|
||||
|
||||
class TestFuzzIsisTLV(frrtest.TestMultiOut):
|
||||
program = './test_fuzz_isis_tlv'
|
||||
|
||||
TestFuzzIsisTLV.exit_cleanly()
|
BIN
tests/isisd/test_fuzz_isis_tlv_tests.h.gz
Normal file
BIN
tests/isisd/test_fuzz_isis_tlv_tests.h.gz
Normal file
Binary file not shown.
Loading…
Reference in a new issue