diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile.am | 85 | ||||
-rw-r--r-- | tests/Makefile.in | 1419 | ||||
-rw-r--r-- | tests/check-compat.h | 16 | ||||
-rw-r--r-- | tests/check_bitmap.c | 77 | ||||
-rw-r--r-- | tests/check_cdp.c | 536 | ||||
-rw-r--r-- | tests/check_edp.c | 578 | ||||
-rw-r--r-- | tests/check_fixedpoint.c | 353 | ||||
-rw-r--r-- | tests/check_lldp.c | 835 | ||||
-rw-r--r-- | tests/check_marshal.c | 925 | ||||
-rw-r--r-- | tests/check_pattern.c | 148 | ||||
-rw-r--r-- | tests/check_snmp.c | 1190 | ||||
-rw-r--r-- | tests/check_sonmp.c | 221 | ||||
-rw-r--r-- | tests/common.c | 153 | ||||
-rw-r--r-- | tests/common.h | 45 | ||||
-rw-r--r-- | tests/decode.c | 265 | ||||
-rw-r--r-- | tests/fuzz_cdp.c | 54 | ||||
-rw-r--r-- | tests/fuzz_edp.c | 54 | ||||
-rw-r--r-- | tests/fuzz_lldp.c | 50 | ||||
-rw-r--r-- | tests/fuzz_sonmp.c | 50 | ||||
-rw-r--r-- | tests/pcap-hdr.h | 25 |
20 files changed, 7079 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..c41f673 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,85 @@ +AM_CFLAGS = -I $(top_srcdir)/include $(LLDP_CFLAGS) +AM_CPPFLAGS = $(LLDP_CPPFLAGS) +AM_LDFLAGS = $(LLDP_LDFLAGS) $(LLDP_BIN_LDFLAGS) + +check_PROGRAMS = decode +decode_SOURCES = decode.c \ + $(top_srcdir)/src/daemon/lldpd.h \ + pcap-hdr.h + +LDADD = $(top_builddir)/src/daemon/liblldpd.la @libevent_LDFLAGS@ +if ENABLE_SYSTEMTAP +LDADD += $(top_builddir)/src/daemon/probes.o +endif +if USE_SNMP +LDADD += @NETSNMP_LIBS@ +endif + +if HAVE_CHECK + +TESTS = check_marshal check_pattern check_bitmap check_fixedpoint \ + check_lldp check_cdp check_sonmp check_edp +AM_CFLAGS += @check_CFLAGS@ -Wno-format-extra-args +LDADD += @check_LIBS@ + +check_marshal_SOURCES = check_marshal.c \ + $(top_srcdir)/src/marshal.h \ + check-compat.h + +check_pattern_SOURCES = check_pattern.c \ + $(top_srcdir)/src/daemon/lldpd.h + +check_bitmap_SOURCES = check_bitmap.c \ + $(top_srcdir)/src/daemon/lldpd.h + +check_lldp_SOURCES = check_lldp.c \ + $(top_srcdir)/src/daemon/lldpd.h \ + common.h common.c check-compat.h pcap-hdr.h + +check_cdp_SOURCES = check_cdp.c \ + $(top_srcdir)/src/daemon/lldpd.h \ + common.h common.c check-compat.h pcap-hdr.h + +check_sonmp_SOURCES = check_sonmp.c \ + $(top_srcdir)/src/daemon/lldpd.h \ + common.h common.c check-compat.h pcap-hdr.h + +check_edp_SOURCES = check_edp.c \ + $(top_srcdir)/src/daemon/lldpd.h \ + common.h common.c check-compat.h pcap-hdr.h + +check_fixedpoint_SOURCES = check_fixedpoint.c +check_fixedpoint_LDADD = $(top_builddir)/src/lib/libfixedpoint.la $(LDADD) + +if USE_SNMP +TESTS += check_snmp +check_snmp_SOURCES = check_snmp.c \ + $(top_srcdir)/src/daemon/lldpd.h \ + $(top_srcdir)/src/daemon/agent.h +endif + +check_PROGRAMS += $(TESTS) + +endif + +if ENABLE_FUZZ_DECODE +noinst_PROGRAMS = fuzz_lldp fuzz_cdp fuzz_sonmp fuzz_edp + +fuzz_lldp_SOURCES = fuzz_lldp.c \ + $(top_srcdir)/src/daemon/lldpd.h +fuzz_lldp_LDADD = $(top_builddir)/src/daemon/liblldpd.la $(LDADD) $(FUZZ_DECODE_ENGINE) + +fuzz_cdp_SOURCES = fuzz_cdp.c \ + $(top_srcdir)/src/daemon/lldpd.h +fuzz_cdp_LDADD = $(top_builddir)/src/daemon/liblldpd.la $(LDADD) $(FUZZ_DECODE_ENGINE) + +fuzz_sonmp_SOURCES = fuzz_sonmp.c \ + $(top_srcdir)/src/daemon/lldpd.h +fuzz_sonmp_LDADD = $(top_builddir)/src/daemon/liblldpd.la $(LDADD) $(FUZZ_DECODE_ENGINE) + +fuzz_edp_SOURCES = fuzz_edp.c \ + $(top_srcdir)/src/daemon/lldpd.h +fuzz_edp_LDADD = $(top_builddir)/src/daemon/liblldpd.la $(LDADD) $(FUZZ_DECODE_ENGINE) +endif + +MOSTLYCLEANFILES = *.pcap diff --git a/tests/Makefile.in b/tests/Makefile.in new file mode 100644 index 0000000..842c794 --- /dev/null +++ b/tests/Makefile.in @@ -0,0 +1,1419 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = decode$(EXEEXT) $(am__EXEEXT_3) +@ENABLE_SYSTEMTAP_TRUE@am__append_1 = $(top_builddir)/src/daemon/probes.o +@USE_SNMP_TRUE@am__append_2 = @NETSNMP_LIBS@ +@HAVE_CHECK_TRUE@TESTS = check_marshal$(EXEEXT) check_pattern$(EXEEXT) \ +@HAVE_CHECK_TRUE@ check_bitmap$(EXEEXT) \ +@HAVE_CHECK_TRUE@ check_fixedpoint$(EXEEXT) check_lldp$(EXEEXT) \ +@HAVE_CHECK_TRUE@ check_cdp$(EXEEXT) check_sonmp$(EXEEXT) \ +@HAVE_CHECK_TRUE@ check_edp$(EXEEXT) $(am__EXEEXT_1) +@HAVE_CHECK_TRUE@am__append_3 = @check_CFLAGS@ -Wno-format-extra-args +@HAVE_CHECK_TRUE@am__append_4 = @check_LIBS@ +@HAVE_CHECK_TRUE@@USE_SNMP_TRUE@am__append_5 = check_snmp +@HAVE_CHECK_TRUE@am__append_6 = $(TESTS) +@ENABLE_FUZZ_DECODE_TRUE@noinst_PROGRAMS = fuzz_lldp$(EXEEXT) \ +@ENABLE_FUZZ_DECODE_TRUE@ fuzz_cdp$(EXEEXT) fuzz_sonmp$(EXEEXT) \ +@ENABLE_FUZZ_DECODE_TRUE@ fuzz_edp$(EXEEXT) +subdir = tests +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/alignof.m4 \ + $(top_srcdir)/m4/args.m4 \ + $(top_srcdir)/m4/ax_build_date_epoch.m4 \ + $(top_srcdir)/m4/ax_cflags_gcc_option.m4 \ + $(top_srcdir)/m4/ax_ld_check_flag.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/ax_prog_doxygen.m4 \ + $(top_srcdir)/m4/config_subdirs.m4 \ + $(top_srcdir)/m4/ld-version-script.m4 \ + $(top_srcdir)/m4/libcap.m4 $(top_srcdir)/m4/libevent.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/os.m4 \ + $(top_srcdir)/m4/progname.m4 $(top_srcdir)/m4/seccomp.m4 \ + $(top_srcdir)/m4/snmp.m4 $(top_srcdir)/m4/stdint.m4 \ + $(top_srcdir)/m4/systemtap.m4 $(top_srcdir)/m4/xml2.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +@HAVE_CHECK_TRUE@@USE_SNMP_TRUE@am__EXEEXT_1 = check_snmp$(EXEEXT) +@HAVE_CHECK_TRUE@am__EXEEXT_2 = check_marshal$(EXEEXT) \ +@HAVE_CHECK_TRUE@ check_pattern$(EXEEXT) check_bitmap$(EXEEXT) \ +@HAVE_CHECK_TRUE@ check_fixedpoint$(EXEEXT) check_lldp$(EXEEXT) \ +@HAVE_CHECK_TRUE@ check_cdp$(EXEEXT) check_sonmp$(EXEEXT) \ +@HAVE_CHECK_TRUE@ check_edp$(EXEEXT) $(am__EXEEXT_1) +@HAVE_CHECK_TRUE@am__EXEEXT_3 = $(am__EXEEXT_2) +PROGRAMS = $(noinst_PROGRAMS) +am__check_bitmap_SOURCES_DIST = check_bitmap.c \ + $(top_srcdir)/src/daemon/lldpd.h +@HAVE_CHECK_TRUE@am_check_bitmap_OBJECTS = check_bitmap.$(OBJEXT) +check_bitmap_OBJECTS = $(am_check_bitmap_OBJECTS) +check_bitmap_LDADD = $(LDADD) +am__DEPENDENCIES_1 = +check_bitmap_DEPENDENCIES = $(top_builddir)/src/daemon/liblldpd.la \ + $(am__append_1) $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +am__check_cdp_SOURCES_DIST = check_cdp.c \ + $(top_srcdir)/src/daemon/lldpd.h common.h common.c \ + check-compat.h pcap-hdr.h +@HAVE_CHECK_TRUE@am_check_cdp_OBJECTS = check_cdp.$(OBJEXT) \ +@HAVE_CHECK_TRUE@ common.$(OBJEXT) +check_cdp_OBJECTS = $(am_check_cdp_OBJECTS) +check_cdp_LDADD = $(LDADD) +check_cdp_DEPENDENCIES = $(top_builddir)/src/daemon/liblldpd.la \ + $(am__append_1) $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am__check_edp_SOURCES_DIST = check_edp.c \ + $(top_srcdir)/src/daemon/lldpd.h common.h common.c \ + check-compat.h pcap-hdr.h +@HAVE_CHECK_TRUE@am_check_edp_OBJECTS = check_edp.$(OBJEXT) \ +@HAVE_CHECK_TRUE@ common.$(OBJEXT) +check_edp_OBJECTS = $(am_check_edp_OBJECTS) +check_edp_LDADD = $(LDADD) +check_edp_DEPENDENCIES = $(top_builddir)/src/daemon/liblldpd.la \ + $(am__append_1) $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am__check_fixedpoint_SOURCES_DIST = check_fixedpoint.c +@HAVE_CHECK_TRUE@am_check_fixedpoint_OBJECTS = \ +@HAVE_CHECK_TRUE@ check_fixedpoint.$(OBJEXT) +check_fixedpoint_OBJECTS = $(am_check_fixedpoint_OBJECTS) +am__DEPENDENCIES_2 = $(top_builddir)/src/daemon/liblldpd.la \ + $(am__append_1) $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +@HAVE_CHECK_TRUE@check_fixedpoint_DEPENDENCIES = \ +@HAVE_CHECK_TRUE@ $(top_builddir)/src/lib/libfixedpoint.la \ +@HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_2) +am__check_lldp_SOURCES_DIST = check_lldp.c \ + $(top_srcdir)/src/daemon/lldpd.h common.h common.c \ + check-compat.h pcap-hdr.h +@HAVE_CHECK_TRUE@am_check_lldp_OBJECTS = check_lldp.$(OBJEXT) \ +@HAVE_CHECK_TRUE@ common.$(OBJEXT) +check_lldp_OBJECTS = $(am_check_lldp_OBJECTS) +check_lldp_LDADD = $(LDADD) +check_lldp_DEPENDENCIES = $(top_builddir)/src/daemon/liblldpd.la \ + $(am__append_1) $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am__check_marshal_SOURCES_DIST = check_marshal.c \ + $(top_srcdir)/src/marshal.h check-compat.h +@HAVE_CHECK_TRUE@am_check_marshal_OBJECTS = check_marshal.$(OBJEXT) +check_marshal_OBJECTS = $(am_check_marshal_OBJECTS) +check_marshal_LDADD = $(LDADD) +check_marshal_DEPENDENCIES = $(top_builddir)/src/daemon/liblldpd.la \ + $(am__append_1) $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am__check_pattern_SOURCES_DIST = check_pattern.c \ + $(top_srcdir)/src/daemon/lldpd.h +@HAVE_CHECK_TRUE@am_check_pattern_OBJECTS = check_pattern.$(OBJEXT) +check_pattern_OBJECTS = $(am_check_pattern_OBJECTS) +check_pattern_LDADD = $(LDADD) +check_pattern_DEPENDENCIES = $(top_builddir)/src/daemon/liblldpd.la \ + $(am__append_1) $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am__check_snmp_SOURCES_DIST = check_snmp.c \ + $(top_srcdir)/src/daemon/lldpd.h \ + $(top_srcdir)/src/daemon/agent.h +@HAVE_CHECK_TRUE@@USE_SNMP_TRUE@am_check_snmp_OBJECTS = \ +@HAVE_CHECK_TRUE@@USE_SNMP_TRUE@ check_snmp.$(OBJEXT) +check_snmp_OBJECTS = $(am_check_snmp_OBJECTS) +check_snmp_LDADD = $(LDADD) +check_snmp_DEPENDENCIES = $(top_builddir)/src/daemon/liblldpd.la \ + $(am__append_1) $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am__check_sonmp_SOURCES_DIST = check_sonmp.c \ + $(top_srcdir)/src/daemon/lldpd.h common.h common.c \ + check-compat.h pcap-hdr.h +@HAVE_CHECK_TRUE@am_check_sonmp_OBJECTS = check_sonmp.$(OBJEXT) \ +@HAVE_CHECK_TRUE@ common.$(OBJEXT) +check_sonmp_OBJECTS = $(am_check_sonmp_OBJECTS) +check_sonmp_LDADD = $(LDADD) +check_sonmp_DEPENDENCIES = $(top_builddir)/src/daemon/liblldpd.la \ + $(am__append_1) $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_decode_OBJECTS = decode.$(OBJEXT) +decode_OBJECTS = $(am_decode_OBJECTS) +decode_LDADD = $(LDADD) +decode_DEPENDENCIES = $(top_builddir)/src/daemon/liblldpd.la \ + $(am__append_1) $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am__fuzz_cdp_SOURCES_DIST = fuzz_cdp.c \ + $(top_srcdir)/src/daemon/lldpd.h +@ENABLE_FUZZ_DECODE_TRUE@am_fuzz_cdp_OBJECTS = fuzz_cdp.$(OBJEXT) +fuzz_cdp_OBJECTS = $(am_fuzz_cdp_OBJECTS) +@ENABLE_FUZZ_DECODE_TRUE@fuzz_cdp_DEPENDENCIES = $(top_builddir)/src/daemon/liblldpd.la \ +@ENABLE_FUZZ_DECODE_TRUE@ $(am__DEPENDENCIES_2) \ +@ENABLE_FUZZ_DECODE_TRUE@ $(am__DEPENDENCIES_1) +am__fuzz_edp_SOURCES_DIST = fuzz_edp.c \ + $(top_srcdir)/src/daemon/lldpd.h +@ENABLE_FUZZ_DECODE_TRUE@am_fuzz_edp_OBJECTS = fuzz_edp.$(OBJEXT) +fuzz_edp_OBJECTS = $(am_fuzz_edp_OBJECTS) +@ENABLE_FUZZ_DECODE_TRUE@fuzz_edp_DEPENDENCIES = $(top_builddir)/src/daemon/liblldpd.la \ +@ENABLE_FUZZ_DECODE_TRUE@ $(am__DEPENDENCIES_2) \ +@ENABLE_FUZZ_DECODE_TRUE@ $(am__DEPENDENCIES_1) +am__fuzz_lldp_SOURCES_DIST = fuzz_lldp.c \ + $(top_srcdir)/src/daemon/lldpd.h +@ENABLE_FUZZ_DECODE_TRUE@am_fuzz_lldp_OBJECTS = fuzz_lldp.$(OBJEXT) +fuzz_lldp_OBJECTS = $(am_fuzz_lldp_OBJECTS) +@ENABLE_FUZZ_DECODE_TRUE@fuzz_lldp_DEPENDENCIES = $(top_builddir)/src/daemon/liblldpd.la \ +@ENABLE_FUZZ_DECODE_TRUE@ $(am__DEPENDENCIES_2) \ +@ENABLE_FUZZ_DECODE_TRUE@ $(am__DEPENDENCIES_1) +am__fuzz_sonmp_SOURCES_DIST = fuzz_sonmp.c \ + $(top_srcdir)/src/daemon/lldpd.h +@ENABLE_FUZZ_DECODE_TRUE@am_fuzz_sonmp_OBJECTS = fuzz_sonmp.$(OBJEXT) +fuzz_sonmp_OBJECTS = $(am_fuzz_sonmp_OBJECTS) +@ENABLE_FUZZ_DECODE_TRUE@fuzz_sonmp_DEPENDENCIES = $(top_builddir)/src/daemon/liblldpd.la \ +@ENABLE_FUZZ_DECODE_TRUE@ $(am__DEPENDENCIES_2) \ +@ENABLE_FUZZ_DECODE_TRUE@ $(am__DEPENDENCIES_1) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/check_bitmap.Po \ + ./$(DEPDIR)/check_cdp.Po ./$(DEPDIR)/check_edp.Po \ + ./$(DEPDIR)/check_fixedpoint.Po ./$(DEPDIR)/check_lldp.Po \ + ./$(DEPDIR)/check_marshal.Po ./$(DEPDIR)/check_pattern.Po \ + ./$(DEPDIR)/check_snmp.Po ./$(DEPDIR)/check_sonmp.Po \ + ./$(DEPDIR)/common.Po ./$(DEPDIR)/decode.Po \ + ./$(DEPDIR)/fuzz_cdp.Po ./$(DEPDIR)/fuzz_edp.Po \ + ./$(DEPDIR)/fuzz_lldp.Po ./$(DEPDIR)/fuzz_sonmp.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(check_bitmap_SOURCES) $(check_cdp_SOURCES) \ + $(check_edp_SOURCES) $(check_fixedpoint_SOURCES) \ + $(check_lldp_SOURCES) $(check_marshal_SOURCES) \ + $(check_pattern_SOURCES) $(check_snmp_SOURCES) \ + $(check_sonmp_SOURCES) $(decode_SOURCES) $(fuzz_cdp_SOURCES) \ + $(fuzz_edp_SOURCES) $(fuzz_lldp_SOURCES) $(fuzz_sonmp_SOURCES) +DIST_SOURCES = $(am__check_bitmap_SOURCES_DIST) \ + $(am__check_cdp_SOURCES_DIST) $(am__check_edp_SOURCES_DIST) \ + $(am__check_fixedpoint_SOURCES_DIST) \ + $(am__check_lldp_SOURCES_DIST) \ + $(am__check_marshal_SOURCES_DIST) \ + $(am__check_pattern_SOURCES_DIST) \ + $(am__check_snmp_SOURCES_DIST) $(am__check_sonmp_SOURCES_DIST) \ + $(decode_SOURCES) $(am__fuzz_cdp_SOURCES_DIST) \ + $(am__fuzz_edp_SOURCES_DIST) $(am__fuzz_lldp_SOURCES_DIST) \ + $(am__fuzz_sonmp_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ + $(top_srcdir)/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPARMORDIR = @APPARMORDIR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFIGURE_ARGS = @CONFIGURE_ARGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN_PAPER_SIZE = @DOXYGEN_PAPER_SIZE@ +DSYMUTIL = @DSYMUTIL@ +DTRACE = @DTRACE@ +DUMPBIN = @DUMPBIN@ +DX_CONFIG = @DX_CONFIG@ +DX_DOCDIR = @DX_DOCDIR@ +DX_DOT = @DX_DOT@ +DX_DOXYGEN = @DX_DOXYGEN@ +DX_DVIPS = @DX_DVIPS@ +DX_EGREP = @DX_EGREP@ +DX_ENV = @DX_ENV@ +DX_FLAG_chi = @DX_FLAG_chi@ +DX_FLAG_chm = @DX_FLAG_chm@ +DX_FLAG_doc = @DX_FLAG_doc@ +DX_FLAG_dot = @DX_FLAG_dot@ +DX_FLAG_html = @DX_FLAG_html@ +DX_FLAG_man = @DX_FLAG_man@ +DX_FLAG_pdf = @DX_FLAG_pdf@ +DX_FLAG_ps = @DX_FLAG_ps@ +DX_FLAG_rtf = @DX_FLAG_rtf@ +DX_FLAG_xml = @DX_FLAG_xml@ +DX_HHC = @DX_HHC@ +DX_LATEX = @DX_LATEX@ +DX_MAKEINDEX = @DX_MAKEINDEX@ +DX_PDFLATEX = @DX_PDFLATEX@ +DX_PERL = @DX_PERL@ +DX_PROJECT = @DX_PROJECT@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILECMD = @FILECMD@ +FUZZ_DECODE_ENGINE = @FUZZ_DECODE_ENGINE@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LAUNCHDDAEMONSDIR = @LAUNCHDDAEMONSDIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LLDPD_CTL_SOCKET = @LLDPD_CTL_SOCKET@ +LLDPD_PID_FILE = @LLDPD_PID_FILE@ +LLDP_BIN_LDFLAGS = @LLDP_BIN_LDFLAGS@ +LLDP_CFLAGS = @LLDP_CFLAGS@ +LLDP_CPPFLAGS = @LLDP_CPPFLAGS@ +LLDP_LDFLAGS = @LLDP_LDFLAGS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NETLINK_MAX_RECEIVE_BUFSIZE = @NETLINK_MAX_RECEIVE_BUFSIZE@ +NETLINK_RECEIVE_BUFSIZE = @NETLINK_RECEIVE_BUFSIZE@ +NETLINK_SEND_BUFSIZE = @NETLINK_SEND_BUFSIZE@ +NETSNMP_CFLAGS = @NETSNMP_CFLAGS@ +NETSNMP_CONFIG = @NETSNMP_CONFIG@ +NETSNMP_LIBS = @NETSNMP_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PRIVSEP_CHROOT = @PRIVSEP_CHROOT@ +PRIVSEP_GROUP = @PRIVSEP_GROUP@ +PRIVSEP_USER = @PRIVSEP_USER@ +RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEMDSYSTEMUNITDIR = @SYSTEMDSYSTEMUNITDIR@ +SYSUSERSDIR = @SYSUSERSDIR@ +VERSION = @VERSION@ +XML2_CONFIG = @XML2_CONFIG@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +apparmordir = @apparmordir@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +check_CFLAGS = @check_CFLAGS@ +check_LIBS = @check_LIBS@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +launchddaemonsdir = @launchddaemonsdir@ +libbsd_CFLAGS = @libbsd_CFLAGS@ +libbsd_LIBS = @libbsd_LIBS@ +libcap_CFLAGS = @libcap_CFLAGS@ +libcap_LIBS = @libcap_LIBS@ +libdir = @libdir@ +libevent_CFLAGS = @libevent_CFLAGS@ +libevent_LDFLAGS = @libevent_LDFLAGS@ +libevent_LIBS = @libevent_LIBS@ +libexecdir = @libexecdir@ +libseccomp_CFLAGS = @libseccomp_CFLAGS@ +libseccomp_LIBS = @libseccomp_LIBS@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgconfigdir = @pkgconfigdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +sysusersdir = @sysusersdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CFLAGS = -I $(top_srcdir)/include $(LLDP_CFLAGS) $(am__append_3) +AM_CPPFLAGS = $(LLDP_CPPFLAGS) +AM_LDFLAGS = $(LLDP_LDFLAGS) $(LLDP_BIN_LDFLAGS) +decode_SOURCES = decode.c \ + $(top_srcdir)/src/daemon/lldpd.h \ + pcap-hdr.h + +LDADD = $(top_builddir)/src/daemon/liblldpd.la @libevent_LDFLAGS@ \ + $(am__append_1) $(am__append_2) $(am__append_4) +@HAVE_CHECK_TRUE@check_marshal_SOURCES = check_marshal.c \ +@HAVE_CHECK_TRUE@ $(top_srcdir)/src/marshal.h \ +@HAVE_CHECK_TRUE@ check-compat.h + +@HAVE_CHECK_TRUE@check_pattern_SOURCES = check_pattern.c \ +@HAVE_CHECK_TRUE@ $(top_srcdir)/src/daemon/lldpd.h + +@HAVE_CHECK_TRUE@check_bitmap_SOURCES = check_bitmap.c \ +@HAVE_CHECK_TRUE@ $(top_srcdir)/src/daemon/lldpd.h + +@HAVE_CHECK_TRUE@check_lldp_SOURCES = check_lldp.c \ +@HAVE_CHECK_TRUE@ $(top_srcdir)/src/daemon/lldpd.h \ +@HAVE_CHECK_TRUE@ common.h common.c check-compat.h pcap-hdr.h + +@HAVE_CHECK_TRUE@check_cdp_SOURCES = check_cdp.c \ +@HAVE_CHECK_TRUE@ $(top_srcdir)/src/daemon/lldpd.h \ +@HAVE_CHECK_TRUE@ common.h common.c check-compat.h pcap-hdr.h + +@HAVE_CHECK_TRUE@check_sonmp_SOURCES = check_sonmp.c \ +@HAVE_CHECK_TRUE@ $(top_srcdir)/src/daemon/lldpd.h \ +@HAVE_CHECK_TRUE@ common.h common.c check-compat.h pcap-hdr.h + +@HAVE_CHECK_TRUE@check_edp_SOURCES = check_edp.c \ +@HAVE_CHECK_TRUE@ $(top_srcdir)/src/daemon/lldpd.h \ +@HAVE_CHECK_TRUE@ common.h common.c check-compat.h pcap-hdr.h + +@HAVE_CHECK_TRUE@check_fixedpoint_SOURCES = check_fixedpoint.c +@HAVE_CHECK_TRUE@check_fixedpoint_LDADD = $(top_builddir)/src/lib/libfixedpoint.la $(LDADD) +@HAVE_CHECK_TRUE@@USE_SNMP_TRUE@check_snmp_SOURCES = check_snmp.c \ +@HAVE_CHECK_TRUE@@USE_SNMP_TRUE@ $(top_srcdir)/src/daemon/lldpd.h \ +@HAVE_CHECK_TRUE@@USE_SNMP_TRUE@ $(top_srcdir)/src/daemon/agent.h + +@ENABLE_FUZZ_DECODE_TRUE@fuzz_lldp_SOURCES = fuzz_lldp.c \ +@ENABLE_FUZZ_DECODE_TRUE@ $(top_srcdir)/src/daemon/lldpd.h + +@ENABLE_FUZZ_DECODE_TRUE@fuzz_lldp_LDADD = $(top_builddir)/src/daemon/liblldpd.la $(LDADD) $(FUZZ_DECODE_ENGINE) +@ENABLE_FUZZ_DECODE_TRUE@fuzz_cdp_SOURCES = fuzz_cdp.c \ +@ENABLE_FUZZ_DECODE_TRUE@ $(top_srcdir)/src/daemon/lldpd.h + +@ENABLE_FUZZ_DECODE_TRUE@fuzz_cdp_LDADD = $(top_builddir)/src/daemon/liblldpd.la $(LDADD) $(FUZZ_DECODE_ENGINE) +@ENABLE_FUZZ_DECODE_TRUE@fuzz_sonmp_SOURCES = fuzz_sonmp.c \ +@ENABLE_FUZZ_DECODE_TRUE@ $(top_srcdir)/src/daemon/lldpd.h + +@ENABLE_FUZZ_DECODE_TRUE@fuzz_sonmp_LDADD = $(top_builddir)/src/daemon/liblldpd.la $(LDADD) $(FUZZ_DECODE_ENGINE) +@ENABLE_FUZZ_DECODE_TRUE@fuzz_edp_SOURCES = fuzz_edp.c \ +@ENABLE_FUZZ_DECODE_TRUE@ $(top_srcdir)/src/daemon/lldpd.h + +@ENABLE_FUZZ_DECODE_TRUE@fuzz_edp_LDADD = $(top_builddir)/src/daemon/liblldpd.la $(LDADD) $(FUZZ_DECODE_ENGINE) +MOSTLYCLEANFILES = *.pcap +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +check_bitmap$(EXEEXT): $(check_bitmap_OBJECTS) $(check_bitmap_DEPENDENCIES) $(EXTRA_check_bitmap_DEPENDENCIES) + @rm -f check_bitmap$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(check_bitmap_OBJECTS) $(check_bitmap_LDADD) $(LIBS) + +check_cdp$(EXEEXT): $(check_cdp_OBJECTS) $(check_cdp_DEPENDENCIES) $(EXTRA_check_cdp_DEPENDENCIES) + @rm -f check_cdp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(check_cdp_OBJECTS) $(check_cdp_LDADD) $(LIBS) + +check_edp$(EXEEXT): $(check_edp_OBJECTS) $(check_edp_DEPENDENCIES) $(EXTRA_check_edp_DEPENDENCIES) + @rm -f check_edp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(check_edp_OBJECTS) $(check_edp_LDADD) $(LIBS) + +check_fixedpoint$(EXEEXT): $(check_fixedpoint_OBJECTS) $(check_fixedpoint_DEPENDENCIES) $(EXTRA_check_fixedpoint_DEPENDENCIES) + @rm -f check_fixedpoint$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(check_fixedpoint_OBJECTS) $(check_fixedpoint_LDADD) $(LIBS) + +check_lldp$(EXEEXT): $(check_lldp_OBJECTS) $(check_lldp_DEPENDENCIES) $(EXTRA_check_lldp_DEPENDENCIES) + @rm -f check_lldp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(check_lldp_OBJECTS) $(check_lldp_LDADD) $(LIBS) + +check_marshal$(EXEEXT): $(check_marshal_OBJECTS) $(check_marshal_DEPENDENCIES) $(EXTRA_check_marshal_DEPENDENCIES) + @rm -f check_marshal$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(check_marshal_OBJECTS) $(check_marshal_LDADD) $(LIBS) + +check_pattern$(EXEEXT): $(check_pattern_OBJECTS) $(check_pattern_DEPENDENCIES) $(EXTRA_check_pattern_DEPENDENCIES) + @rm -f check_pattern$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(check_pattern_OBJECTS) $(check_pattern_LDADD) $(LIBS) + +check_snmp$(EXEEXT): $(check_snmp_OBJECTS) $(check_snmp_DEPENDENCIES) $(EXTRA_check_snmp_DEPENDENCIES) + @rm -f check_snmp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(check_snmp_OBJECTS) $(check_snmp_LDADD) $(LIBS) + +check_sonmp$(EXEEXT): $(check_sonmp_OBJECTS) $(check_sonmp_DEPENDENCIES) $(EXTRA_check_sonmp_DEPENDENCIES) + @rm -f check_sonmp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(check_sonmp_OBJECTS) $(check_sonmp_LDADD) $(LIBS) + +decode$(EXEEXT): $(decode_OBJECTS) $(decode_DEPENDENCIES) $(EXTRA_decode_DEPENDENCIES) + @rm -f decode$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(decode_OBJECTS) $(decode_LDADD) $(LIBS) + +fuzz_cdp$(EXEEXT): $(fuzz_cdp_OBJECTS) $(fuzz_cdp_DEPENDENCIES) $(EXTRA_fuzz_cdp_DEPENDENCIES) + @rm -f fuzz_cdp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(fuzz_cdp_OBJECTS) $(fuzz_cdp_LDADD) $(LIBS) + +fuzz_edp$(EXEEXT): $(fuzz_edp_OBJECTS) $(fuzz_edp_DEPENDENCIES) $(EXTRA_fuzz_edp_DEPENDENCIES) + @rm -f fuzz_edp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(fuzz_edp_OBJECTS) $(fuzz_edp_LDADD) $(LIBS) + +fuzz_lldp$(EXEEXT): $(fuzz_lldp_OBJECTS) $(fuzz_lldp_DEPENDENCIES) $(EXTRA_fuzz_lldp_DEPENDENCIES) + @rm -f fuzz_lldp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(fuzz_lldp_OBJECTS) $(fuzz_lldp_LDADD) $(LIBS) + +fuzz_sonmp$(EXEEXT): $(fuzz_sonmp_OBJECTS) $(fuzz_sonmp_DEPENDENCIES) $(EXTRA_fuzz_sonmp_DEPENDENCIES) + @rm -f fuzz_sonmp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(fuzz_sonmp_OBJECTS) $(fuzz_sonmp_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_bitmap.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_cdp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_edp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_fixedpoint.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_lldp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_marshal.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_pattern.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_snmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_sonmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decode.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fuzz_cdp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fuzz_edp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fuzz_lldp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fuzz_sonmp.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: $(check_PROGRAMS) + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_PROGRAMS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +check_marshal.log: check_marshal$(EXEEXT) + @p='check_marshal$(EXEEXT)'; \ + b='check_marshal'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +check_pattern.log: check_pattern$(EXEEXT) + @p='check_pattern$(EXEEXT)'; \ + b='check_pattern'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +check_bitmap.log: check_bitmap$(EXEEXT) + @p='check_bitmap$(EXEEXT)'; \ + b='check_bitmap'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +check_fixedpoint.log: check_fixedpoint$(EXEEXT) + @p='check_fixedpoint$(EXEEXT)'; \ + b='check_fixedpoint'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +check_lldp.log: check_lldp$(EXEEXT) + @p='check_lldp$(EXEEXT)'; \ + b='check_lldp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +check_cdp.log: check_cdp$(EXEEXT) + @p='check_cdp$(EXEEXT)'; \ + b='check_cdp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +check_sonmp.log: check_sonmp$(EXEEXT) + @p='check_sonmp$(EXEEXT)'; \ + b='check_sonmp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +check_edp.log: check_edp$(EXEEXT) + @p='check_edp$(EXEEXT)'; \ + b='check_edp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +check_snmp.log: check_snmp$(EXEEXT) + @p='check_snmp$(EXEEXT)'; \ + b='check_snmp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/check_bitmap.Po + -rm -f ./$(DEPDIR)/check_cdp.Po + -rm -f ./$(DEPDIR)/check_edp.Po + -rm -f ./$(DEPDIR)/check_fixedpoint.Po + -rm -f ./$(DEPDIR)/check_lldp.Po + -rm -f ./$(DEPDIR)/check_marshal.Po + -rm -f ./$(DEPDIR)/check_pattern.Po + -rm -f ./$(DEPDIR)/check_snmp.Po + -rm -f ./$(DEPDIR)/check_sonmp.Po + -rm -f ./$(DEPDIR)/common.Po + -rm -f ./$(DEPDIR)/decode.Po + -rm -f ./$(DEPDIR)/fuzz_cdp.Po + -rm -f ./$(DEPDIR)/fuzz_edp.Po + -rm -f ./$(DEPDIR)/fuzz_lldp.Po + -rm -f ./$(DEPDIR)/fuzz_sonmp.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/check_bitmap.Po + -rm -f ./$(DEPDIR)/check_cdp.Po + -rm -f ./$(DEPDIR)/check_edp.Po + -rm -f ./$(DEPDIR)/check_fixedpoint.Po + -rm -f ./$(DEPDIR)/check_lldp.Po + -rm -f ./$(DEPDIR)/check_marshal.Po + -rm -f ./$(DEPDIR)/check_pattern.Po + -rm -f ./$(DEPDIR)/check_snmp.Po + -rm -f ./$(DEPDIR)/check_sonmp.Po + -rm -f ./$(DEPDIR)/common.Po + -rm -f ./$(DEPDIR)/decode.Po + -rm -f ./$(DEPDIR)/fuzz_cdp.Po + -rm -f ./$(DEPDIR)/fuzz_edp.Po + -rm -f ./$(DEPDIR)/fuzz_lldp.Po + -rm -f ./$(DEPDIR)/fuzz_sonmp.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ + check-am clean clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am recheck tags tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tests/check-compat.h b/tests/check-compat.h new file mode 100644 index 0000000..3236d78 --- /dev/null +++ b/tests/check-compat.h @@ -0,0 +1,16 @@ +#ifndef _CHECK_COMPAT_H +#define _CHECK_COMPAT_H + +#if (CHECK_MAJOR_VERSION == 0 && \ + (CHECK_MINOR_VERSION < 9 || \ + (CHECK_MINOR_VERSION == 9 && CHECK_MICRO_VERSION < 10))) +# define ck_assert_ptr_eq(X, Y) \ + do { \ + void *_ck_x = (X); \ + void *_ck_y = (Y); \ + ck_assert_msg(_ck_x == _ck_y, \ + "Assertion '" #X "==" #Y "' failed: " #X "==%p, " #Y "==%p", _ck_x, _ck_y); \ + } while (0) +#endif + +#endif diff --git a/tests/check_bitmap.c b/tests/check_bitmap.c new file mode 100644 index 0000000..467bb28 --- /dev/null +++ b/tests/check_bitmap.c @@ -0,0 +1,77 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2020 Vincent Bernat <bernat@luffy.cx> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <check.h> + +#include "../src/daemon/lldpd.h" + +START_TEST(test_empty) +{ + uint32_t vlan_bmap[VLAN_BITMAP_LEN] = {}; + ck_assert(bitmap_isempty(vlan_bmap)); + ck_assert_int_eq(bitmap_numbits(vlan_bmap), 0); +} +END_TEST + +START_TEST(test_first_bit) +{ + uint32_t vlan_bmap[VLAN_BITMAP_LEN] = {}; + bitmap_set(vlan_bmap, 1); + ck_assert_int_eq(vlan_bmap[0], 2); + ck_assert_int_eq(bitmap_numbits(vlan_bmap), 1); +} +END_TEST + +START_TEST(test_some_bits) +{ + uint32_t vlan_bmap[VLAN_BITMAP_LEN] = {}; + bitmap_set(vlan_bmap, 1); + bitmap_set(vlan_bmap, 6); + bitmap_set(vlan_bmap, 31); + bitmap_set(vlan_bmap, 50); + ck_assert_int_eq(vlan_bmap[0], (1UL << 1) | (1UL << 6) | (1UL << 31)); + ck_assert_int_eq(vlan_bmap[1], (1UL << (50 - 32))); + ck_assert_int_eq(vlan_bmap[2], 0); + ck_assert_int_eq(bitmap_numbits(vlan_bmap), 4); +} +END_TEST + +static Suite * +bitmap_suite(void) +{ + Suite *s = suite_create("Bitmap handling"); + + TCase *tc_bitmap = tcase_create("Bitmap handling"); + tcase_add_test(tc_bitmap, test_empty); + tcase_add_test(tc_bitmap, test_first_bit); + tcase_add_test(tc_bitmap, test_some_bits); + suite_add_tcase(s, tc_bitmap); + + return s; +} + +int +main() +{ + int number_failed; + Suite *s = bitmap_suite(); + SRunner *sr = srunner_create(s); + srunner_run_all(sr, CK_ENV); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/tests/check_cdp.c b/tests/check_cdp.c new file mode 100644 index 0000000..7512a23 --- /dev/null +++ b/tests/check_cdp.c @@ -0,0 +1,536 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2015 Vincent Bernat <bernat@luffy.cx> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdlib.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <check.h> +#include "common.h" + +char filenameprefix[] = "cdp_send"; + +#ifdef ENABLE_CDP + +START_TEST(test_send_cdpv1) +{ + int n; + /* Packet we should build: +IEEE 802.3 Ethernet + Destination: CDP/VTP/DTP/PAgP/UDLD (01:00:0c:cc:cc:cc) + Source: 5e:10:8e:e7:84:ad (5e:10:8e:e7:84:ad) + Length: 106 +Logical-Link Control + DSAP: SNAP (0xaa) + IG Bit: Individual + SSAP: SNAP (0xaa) + CR Bit: Command + Control field: U, func=UI (0x03) + 000. 00.. = Command: Unnumbered Information (0x00) + .... ..11 = Frame type: Unnumbered frame (0x03) + Organization Code: Cisco (0x00000c) + PID: CDP (0x2000) +Cisco Discovery Protocol + Version: 1 + TTL: 180 seconds + Checksum: 0x3af7 [correct] + [Good: True] + [Bad : False] + Device ID: First chassis + Type: Device ID (0x0001) + Length: 17 + Device ID: First chassis + Addresses + Type: Addresses (0x0002) + Length: 17 + Number of addresses: 1 + IP address: 172.17.142.37 + Protocol type: NLPID + Protocol length: 1 + Protocol: IP + Address length: 4 + IP address: 172.17.142.37 + Port ID: FastEthernet 1/5 + Type: Port ID (0x0003) + Length: 20 + Sent through Interface: FastEthernet 1/5 + Capabilities + Type: Capabilities (0x0004) + Length: 8 + Capabilities: 0x00000011 + .... .... .... .... .... .... .... ...1 = Is a Router + .... .... .... .... .... .... .... ..0. = Not a Transparent Bridge + .... .... .... .... .... .... .... .0.. = Not a Source Route Bridge + .... .... .... .... .... .... .... 0... = Not a Switch + .... .... .... .... .... .... ...1 .... = Is a Host + .... .... .... .... .... .... ..0. .... = Not IGMP capable + .... .... .... .... .... .... .0.. .... = Not a Repeater + Software Version + Type: Software version (0x0005) + Length: 23 + Software Version: Chassis description + Platform: Linux + Type: Platform (0x0006) + Length: 9 + Platform: Linux + */ + char pkt1[] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc, 0x5e, 0x10, 0x8e, 0xe7, + 0x84, 0xad, 0x00, 0x6a, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x0c, 0x20, 0x00, + 0x01, 0xb4, 0x3a, 0xf7, 0x00, 0x01, 0x00, 0x11, 0x46, 0x69, 0x72, 0x73, + 0x74, 0x20, 0x63, 0x68, 0x61, 0x73, 0x73, 0x69, 0x73, 0x00, 0x02, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0xcc, 0x00, 0x04, 0xac, 0x11, + 0x8e, 0x25, 0x00, 0x03, 0x00, 0x14, 0x46, 0x61, 0x73, 0x74, 0x45, 0x74, + 0x68, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x31, 0x2f, 0x35, 0x00, 0x04, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x11, 0x00, 0x05, 0x00, 0x17, 0x43, 0x68, + 0x61, 0x73, 0x73, 0x69, 0x73, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x06, 0x00, 0x09, 0x4c, 0x69, 0x6e, + 0x75, 0x78 }; + struct packet *pkt; + in_addr_t addr; + struct lldpd_mgmt *mgmt; + struct lldpd cfg = { .g_config = { .c_ttl = 180, .c_platform = "Linux" } }; + + /* Populate port and chassis */ + hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_IFNAME; + hardware.h_lport.p_id = "Not used"; + hardware.h_lport.p_id_len = strlen(hardware.h_lport.p_id); + hardware.h_lport.p_descr = "FastEthernet 1/5"; + chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR; + chassis.c_id = macaddress; + chassis.c_id_len = ETHER_ADDR_LEN; + chassis.c_name = "First chassis"; + chassis.c_descr = "Chassis description"; + chassis.c_cap_available = chassis.c_cap_enabled = LLDP_CAP_ROUTER; + TAILQ_INIT(&chassis.c_mgmt); + addr = inet_addr("172.17.142.37"); + mgmt = lldpd_alloc_mgmt(LLDPD_AF_IPV4, &addr, sizeof(in_addr_t), 0); + if (mgmt == NULL) ck_abort(); + TAILQ_INSERT_TAIL(&chassis.c_mgmt, mgmt, m_entries); + + /* Build packet */ + n = cdpv1_send(&cfg, &hardware); + if (n != 0) { + fail("unable to build packet"); + return; + } + if (TAILQ_EMPTY(&pkts)) { + fail("no packets sent"); + return; + } + pkt = TAILQ_FIRST(&pkts); + ck_assert_int_eq(pkt->size, sizeof(pkt1)); + fail_unless(memcmp(pkt->data, pkt1, sizeof(pkt1)) == 0); + fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent"); +} +END_TEST + +START_TEST(test_send_cdpv2) +{ + int n; + /* Packet we should build: +IEEE 802.3 Ethernet + Destination: CDP/VTP/DTP/PAgP/UDLD (01:00:0c:cc:cc:cc) + Source: 5e:10:8e:e7:84:ad (5e:10:8e:e7:84:ad) + the factory default) + Length: 111 +Logical-Link Control + DSAP: SNAP (0xaa) + IG Bit: Individual + SSAP: SNAP (0xaa) + CR Bit: Command + Control field: U, func=UI (0x03) + 000. 00.. = Command: Unnumbered Information (0x00) + .... ..11 = Frame type: Unnumbered frame (0x03) + Organization Code: Cisco (0x00000c) + PID: CDP (0x2000) +Cisco Discovery Protocol + Version: 2 + TTL: 180 seconds + Checksum: 0x5926 [correct] + [Good: True] + [Bad : False] + Device ID: Second chassis + Type: Device ID (0x0001) + Length: 18 + Device ID: Second chassis + Addresses + Type: Addresses (0x0002) + Length: 26 + Number of addresses: 2 + IP address: 172.17.142.36 + Protocol type: NLPID + Protocol length: 1 + Protocol: IP + Address length: 4 + IP address: 172.17.142.36 + IP address: 172.17.142.38 + Protocol type: NLPID + Protocol length: 1 + Protocol: IP + Address length: 4 + IP address: 172.17.142.38 + Port ID: Gigabit Ethernet 5/8 + Type: Port ID (0x0003) + Length: 24 + Sent through Interface: Gigabit Ethernet 5/8 + Capabilities + Type: Capabilities (0x0004) + Length: 8 + Capabilities: 0x00000019 + .... .... .... .... .... .... .... ...1 = Is a Router + .... .... .... .... .... .... .... ..0. = Not a Transparent Bridge + .... .... .... .... .... .... .... .0.. = Not a Source Route Bridge + .... .... .... .... .... .... .... 1... = Is a Switch + .... .... .... .... .... .... ...1 .... = Is a Host + .... .... .... .... .... .... ..0. .... = Not IGMP capable + .... .... .... .... .... .... .0.. .... = Not a Repeater + Software Version + Type: Software version (0x0005) + Length: 23 + Software Version: Chassis description + Platform: Linux + Type: Platform (0x0006) + Length: 9 + Platform: Linux + */ + char pkt1[] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc, 0x5e, 0x10, 0x8e, 0xe7, + 0x84, 0xad, 0x00, 0x78, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x0c, 0x20, 0x00, + 0x02, 0xb4, 0xc8, 0x67, 0x00, 0x01, 0x00, 0x12, 0x53, 0x65, 0x63, 0x6f, + 0x6e, 0x64, 0x20, 0x63, 0x68, 0x61, 0x73, 0x73, 0x69, 0x73, 0x00, 0x02, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0xcc, 0x00, 0x04, 0xac, + 0x11, 0x8e, 0x24, 0x01, 0x01, 0xcc, 0x00, 0x04, 0xac, 0x11, 0x8e, 0x26, + 0x00, 0x03, 0x00, 0x18, 0x47, 0x69, 0x67, 0x61, 0x62, 0x69, 0x74, 0x20, + 0x45, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x35, 0x2f, 0x38, + 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x05, 0x00, 0x17, + 0x43, 0x68, 0x61, 0x73, 0x73, 0x69, 0x73, 0x20, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x06, 0x00, 0x09, 0x4c, + 0x69, 0x6e, 0x75, 0x78 }; + struct packet *pkt; + in_addr_t addr1; + in_addr_t addr2; + struct lldpd_mgmt *mgmt1; + struct lldpd_mgmt *mgmt2; + struct lldpd cfg = { .g_config = { .c_ttl = 180, .c_platform = "Linux" } }; + + /* Populate port and chassis */ + hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_LLADDR; + hardware.h_lport.p_id = macaddress; + hardware.h_lport.p_id_len = ETHER_ADDR_LEN; + hardware.h_lport.p_descr = "Gigabit Ethernet 5/8"; + chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR; + chassis.c_id = macaddress; + chassis.c_id_len = ETHER_ADDR_LEN; + chassis.c_name = "Second chassis"; + chassis.c_descr = "Chassis description"; + chassis.c_cap_available = chassis.c_cap_enabled = + LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE; + TAILQ_INIT(&chassis.c_mgmt); + addr1 = inet_addr("172.17.142.36"); + addr2 = inet_addr("172.17.142.38"); + mgmt1 = lldpd_alloc_mgmt(LLDPD_AF_IPV4, &addr1, sizeof(in_addr_t), 0); + mgmt2 = lldpd_alloc_mgmt(LLDPD_AF_IPV4, &addr2, sizeof(in_addr_t), 0); + if (mgmt1 == NULL || mgmt2 == NULL) ck_abort(); + TAILQ_INSERT_TAIL(&chassis.c_mgmt, mgmt1, m_entries); + TAILQ_INSERT_TAIL(&chassis.c_mgmt, mgmt2, m_entries); + + /* Build packet */ + n = cdpv2_send(&cfg, &hardware); + if (n != 0) { + fail("unable to build packet"); + return; + } + if (TAILQ_EMPTY(&pkts)) { + fail("no packets sent"); + return; + } + pkt = TAILQ_FIRST(&pkts); + ck_assert_int_eq(pkt->size, sizeof(pkt1)); + fail_unless(memcmp(pkt->data, pkt1, sizeof(pkt1)) == 0); + fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent"); +} +END_TEST + +START_TEST(test_recv_cdpv1) +{ + char pkt1[] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc, 0x00, 0xe0, 0x1e, 0xd5, + 0xd5, 0x15, 0x01, 0x1e, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x0c, 0x20, 0x00, + 0x01, 0xb4, 0xdf, 0xf0, 0x00, 0x01, 0x00, 0x06, 0x52, 0x31, 0x00, 0x02, + 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0xcc, 0x00, 0x04, 0xc0, + 0xa8, 0x0a, 0x01, 0x00, 0x03, 0x00, 0x0d, 0x45, 0x74, 0x68, 0x65, 0x72, + 0x6e, 0x65, 0x74, 0x30, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x05, 0x00, 0xd8, 0x43, 0x69, 0x73, 0x63, 0x6f, 0x20, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x4f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x53, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, + 0x20, 0x0a, 0x49, 0x4f, 0x53, 0x20, 0x28, 0x74, 0x6d, 0x29, 0x20, 0x31, + 0x36, 0x30, 0x30, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, + 0x20, 0x28, 0x43, 0x31, 0x36, 0x30, 0x30, 0x2d, 0x4e, 0x59, 0x2d, 0x4c, + 0x29, 0x2c, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, + 0x31, 0x2e, 0x32, 0x28, 0x31, 0x32, 0x29, 0x50, 0x2c, 0x20, 0x52, 0x45, + 0x4c, 0x45, 0x41, 0x53, 0x45, 0x20, 0x53, 0x4f, 0x46, 0x54, 0x57, 0x41, + 0x52, 0x45, 0x20, 0x28, 0x66, 0x63, 0x31, 0x29, 0x0a, 0x43, 0x6f, 0x70, + 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x31, + 0x39, 0x38, 0x36, 0x2d, 0x31, 0x39, 0x39, 0x38, 0x20, 0x62, 0x79, 0x20, + 0x63, 0x69, 0x73, 0x63, 0x6f, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x43, 0x6f, 0x6d, 0x70, + 0x69, 0x6c, 0x65, 0x64, 0x20, 0x54, 0x75, 0x65, 0x20, 0x30, 0x33, 0x2d, + 0x4d, 0x61, 0x72, 0x2d, 0x39, 0x38, 0x20, 0x30, 0x36, 0x3a, 0x33, 0x33, + 0x20, 0x62, 0x79, 0x20, 0x64, 0x73, 0x63, 0x68, 0x77, 0x61, 0x72, 0x74, + 0x00, 0x06, 0x00, 0x0e, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x20, 0x31, 0x36, + 0x30, 0x31 }; + /* This is: +IEEE 802.3 Ethernet + Destination: CDP/VTP/DTP/PAgP/UDLD (01:00:0c:cc:cc:cc) + Source: Cisco_d5:d5:15 (00:e0:1e:d5:d5:15) + Length: 286 +Logical-Link Control + DSAP: SNAP (0xaa) + IG Bit: Individual + SSAP: SNAP (0xaa) + CR Bit: Command + Control field: U, func=UI (0x03) + 000. 00.. = Command: Unnumbered Information (0x00) + .... ..11 = Frame type: Unnumbered frame (0x03) + Organization Code: Cisco (0x00000c) + PID: CDP (0x2000) +Cisco Discovery Protocol + Version: 1 + TTL: 180 seconds + Checksum: 0xdff0 [correct] + [Good: True] + [Bad : False] + Device ID: R1 + Type: Device ID (0x0001) + Length: 6 + Device ID: R1 + Addresses + Type: Addresses (0x0002) + Length: 17 + Number of addresses: 1 + IP address: 192.168.10.1 + Protocol type: NLPID + Protocol length: 1 + Protocol: IP + Address length: 4 + IP address: 192.168.10.1 + Port ID: Ethernet0 + Type: Port ID (0x0003) + Length: 13 + Sent through Interface: Ethernet0 + Capabilities + Type: Capabilities (0x0004) + Length: 8 + Capabilities: 0x00000011 + .... .... .... .... .... .... .... ...1 = Is a Router + .... .... .... .... .... .... .... ..0. = Not a Transparent Bridge + .... .... .... .... .... .... .... .0.. = Not a Source Route Bridge + .... .... .... .... .... .... .... 0... = Not a Switch + .... .... .... .... .... .... ...1 .... = Is a Host + .... .... .... .... .... .... ..0. .... = Not IGMP capable + .... .... .... .... .... .... .0.. .... = Not a Repeater + Software Version + Type: Software version (0x0005) + Length: 216 + Software Version: Cisco Internetwork Operating System Software + IOS (tm) 1600 Software (C1600-NY-L), Version 11.2(12)P, +RELEASE SOFTWARE (fc1) Copyright (c) 1986-1998 by cisco Systems, Inc. Compiled Tue +03-Mar-98 06:33 by dschwart Platform: cisco 1601 Type: Platform (0x0006) Length: 14 + Platform: cisco 1601 + */ + struct lldpd_chassis *nchassis = NULL; + struct lldpd_port *nport = NULL; + + fail_unless(cdpv1_guess(pkt1, sizeof(pkt1))); + fail_unless( + cdp_decode(NULL, pkt1, sizeof(pkt1), &hardware, &nchassis, &nport) != -1); + if (!nchassis || !nport) { + fail("unable to decode packet"); + return; + } + ck_assert_int_eq(nchassis->c_id_subtype, LLDP_CHASSISID_SUBTYPE_LOCAL); + ck_assert_int_eq(nchassis->c_id_len, 2); + fail_unless(memcmp(nchassis->c_id, "R1", 2) == 0); + ck_assert_str_eq(nchassis->c_name, "R1"); + ck_assert_int_eq(TAILQ_FIRST(&nchassis->c_mgmt)->m_addr.inet.s_addr, + (u_int32_t)inet_addr("192.168.10.1")); + ck_assert_int_eq(TAILQ_FIRST(&nchassis->c_mgmt)->m_iface, 0); + ck_assert_int_eq(nport->p_id_subtype, LLDP_PORTID_SUBTYPE_IFNAME); + ck_assert_int_eq(nport->p_id_len, strlen("Ethernet0")); + fail_unless(memcmp(nport->p_id, "Ethernet0", strlen("Ethernet0")) == 0); + ck_assert_str_eq(nport->p_descr, "Ethernet0"); + ck_assert_int_eq(nchassis->c_cap_enabled, LLDP_CAP_ROUTER); + ck_assert_str_eq(nchassis->c_descr, + "cisco 1601 running on\n" + "Cisco Internetwork Operating System Software \n" + "IOS (tm) 1600 Software (C1600-NY-L), Version 11.2(12)P, RELEASE SOFTWARE (fc1)\n" + "Copyright (c) 1986-1998 by cisco Systems, Inc.\n" + "Compiled Tue 03-Mar-98 06:33 by dschwart"); +} +END_TEST + +START_TEST(test_recv_cdpv2) +{ + char pkt1[] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc, 0xca, 0x00, 0x68, 0x46, + 0x00, 0x00, 0x01, 0x30, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x0c, 0x20, 0x00, + 0x02, 0xb4, 0x54, 0x27, 0x00, 0x01, 0x00, 0x0f, 0x72, 0x74, 0x62, 0x67, + 0x36, 0x74, 0x65, 0x73, 0x74, 0x30, 0x31, 0x00, 0x05, 0x00, 0xd3, 0x43, + 0x69, 0x73, 0x63, 0x6f, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x69, 0x6e, 0x67, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x53, + 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x0a, 0x49, 0x4f, 0x53, + 0x20, 0x28, 0x74, 0x6d, 0x29, 0x20, 0x37, 0x32, 0x30, 0x30, 0x20, 0x53, + 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x28, 0x43, 0x37, 0x32, + 0x30, 0x30, 0x2d, 0x50, 0x2d, 0x4d, 0x29, 0x2c, 0x20, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x32, 0x2e, 0x32, 0x28, 0x34, 0x36, + 0x29, 0x2c, 0x20, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x20, 0x53, + 0x4f, 0x46, 0x54, 0x57, 0x41, 0x52, 0x45, 0x20, 0x28, 0x66, 0x63, 0x31, + 0x29, 0x0a, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, + 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, 0x38, 0x36, 0x2d, 0x32, 0x30, 0x30, + 0x37, 0x20, 0x62, 0x79, 0x20, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x20, 0x53, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x54, 0x68, + 0x75, 0x20, 0x32, 0x36, 0x2d, 0x41, 0x70, 0x72, 0x2d, 0x30, 0x37, 0x20, + 0x32, 0x31, 0x3a, 0x35, 0x36, 0x20, 0x62, 0x79, 0x20, 0x70, 0x77, 0x61, + 0x64, 0x65, 0x00, 0x06, 0x00, 0x11, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x20, + 0x37, 0x32, 0x30, 0x36, 0x56, 0x58, 0x52, 0x00, 0x02, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x01, 0xcc, 0x00, 0x04, 0xac, 0x42, 0x37, 0x03, + 0x00, 0x03, 0x00, 0x13, 0x46, 0x61, 0x73, 0x74, 0x45, 0x74, 0x68, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x30, 0x2f, 0x30, 0x00, 0x04, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x05, 0x00 }; + /* This is: +IEEE 802.3 Ethernet + Destination: CDP/VTP/DTP/PAgP/UDLD (01:00:0c:cc:cc:cc) + Source: ca:00:68:46:00:00 (ca:00:68:46:00:00) + Length: 304 +Logical-Link Control + DSAP: SNAP (0xaa) + IG Bit: Individual + SSAP: SNAP (0xaa) + CR Bit: Command + Control field: U, func=UI (0x03) + 000. 00.. = Command: Unnumbered Information (0x00) + .... ..11 = Frame type: Unnumbered frame (0x03) + Organization Code: Cisco (0x00000c) + PID: CDP (0x2000) +Cisco Discovery Protocol + Version: 2 + TTL: 180 seconds + Checksum: 0x5427 [correct] + [Good: True] + [Bad : False] + Device ID: rtbg6test01 + Type: Device ID (0x0001) + Length: 15 + Device ID: rtbg6test01 + Software Version + Type: Software version (0x0005) + Length: 211 + Software Version: Cisco Internetwork Operating System Software + IOS (tm) 7200 Software (C7200-P-M), Version 12.2(46), RELEASE +SOFTWARE (fc1) Copyright (c) 1986-2007 by cisco Systems, Inc. Compiled Thu 26-Apr-07 +21:56 by pwade Platform: cisco 7206VXR Type: Platform (0x0006) Length: 17 Platform: +cisco 7206VXR Addresses Type: Addresses (0x0002) Length: 17 Number of addresses: 1 IP +address: 172.66.55.3 Protocol type: NLPID Protocol length: 1 Protocol: IP Address +length: 4 IP address: 172.66.55.3 Port ID: FastEthernet0/0 Type: Port ID (0x0003) + Length: 19 + Sent through Interface: FastEthernet0/0 + Capabilities + Type: Capabilities (0x0004) + Length: 8 + Capabilities: 0x00000000 + .... .... .... .... .... .... .... ...0 = Not a Router + .... .... .... .... .... .... .... ..0. = Not a Transparent Bridge + .... .... .... .... .... .... .... .0.. = Not a Source Route Bridge + .... .... .... .... .... .... .... 0... = Not a Switch + .... .... .... .... .... .... ...0 .... = Not a Host + .... .... .... .... .... .... ..0. .... = Not IGMP capable + .... .... .... .... .... .... .0.. .... = Not a Repeater + Duplex: Half + Type: Duplex (0x000b) + Length: 5 + Duplex: Half + */ + struct lldpd_chassis *nchassis = NULL; + struct lldpd_port *nport = NULL; + + fail_unless(cdpv2_guess(pkt1, sizeof(pkt1))); + fail_unless( + cdp_decode(NULL, pkt1, sizeof(pkt1), &hardware, &nchassis, &nport) != -1); + if (!nchassis || !nport) { + fail("unable to decode packet"); + return; + } + ck_assert_int_eq(nchassis->c_id_subtype, LLDP_CHASSISID_SUBTYPE_LOCAL); + ck_assert_int_eq(nchassis->c_id_len, strlen("rtbg6test01")); + fail_unless(memcmp(nchassis->c_id, "rtbg6test01", strlen("rtbg6test01")) == 0); + ck_assert_str_eq(nchassis->c_name, "rtbg6test01"); + ck_assert_int_eq(TAILQ_FIRST(&nchassis->c_mgmt)->m_addr.inet.s_addr, + (u_int32_t)inet_addr("172.66.55.3")); + ck_assert_int_eq(TAILQ_FIRST(&nchassis->c_mgmt)->m_iface, 0); + ck_assert_int_eq(nport->p_id_subtype, LLDP_PORTID_SUBTYPE_IFNAME); + ck_assert_int_eq(nport->p_id_len, strlen("FastEthernet0/0")); + fail_unless( + memcmp(nport->p_id, "FastEthernet0/0", strlen("FastEthernet0/0")) == 0); + ck_assert_str_eq(nport->p_descr, "FastEthernet0/0"); + ck_assert_int_eq(nchassis->c_cap_enabled, LLDP_CAP_STATION); + ck_assert_str_eq(nchassis->c_descr, + "cisco 7206VXR running on\n" + "Cisco Internetwork Operating System Software \n" + "IOS (tm) 7200 Software (C7200-P-M), Version 12.2(46), RELEASE SOFTWARE (fc1)\n" + "Copyright (c) 1986-2007 by cisco Systems, Inc.\n" + "Compiled Thu 26-Apr-07 21:56 by pwade"); +} +END_TEST + +#endif + +static Suite * +cdp_suite(void) +{ + Suite *s = suite_create("CDP"); + +#ifdef ENABLE_CDP + TCase *tc_send = tcase_create("Send CDP packets"); + TCase *tc_receive = tcase_create("Receive CDP packets"); + + tcase_add_checked_fixture(tc_send, pcap_setup, pcap_teardown); + tcase_add_test(tc_send, test_send_cdpv1); + tcase_add_test(tc_send, test_send_cdpv2); + suite_add_tcase(s, tc_send); + + tcase_add_test(tc_receive, test_recv_cdpv1); + tcase_add_test(tc_receive, test_recv_cdpv2); + suite_add_tcase(s, tc_receive); +#endif + + return s; +} + +int +main() +{ + int number_failed; + Suite *s = cdp_suite(); + SRunner *sr = srunner_create(s); + srunner_set_fork_status(sr, CK_NOFORK); /* Can't fork because + we need to write + files */ + srunner_run_all(sr, CK_ENV); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/tests/check_edp.c b/tests/check_edp.c new file mode 100644 index 0000000..726e2dd --- /dev/null +++ b/tests/check_edp.c @@ -0,0 +1,578 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2015 Vincent Bernat <bernat@luffy.cx> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdlib.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <check.h> +#include "common.h" + +char filenameprefix[] = "edp_send"; + +#ifdef ENABLE_EDP + +START_TEST(test_send_basic) +{ + int n; + /* Packet we should build: +Extreme Discovery Protocol + Version: 1 + Reserved: 0 + Data length: 74 + Checksum: 0xde22 [correct] + [Good: True] + [Bad : False] + Sequence number: 0 + Machine ID type: MAC (0) + Machine MAC: 5e:10:8e:e7:84:ad (5e:10:8e:e7:84:ad) + Display: "First chassis" + Marker 0x99, length 18, type 1 = Display + TLV Marker: 0x99 + TLV type: Display (1) + TLV length: 18 + Name: First chassis + Info: Slot/Port: 1/4, Version: 7.6.4.99 + Marker 0x99, length 36, type 2 = Info + TLV Marker: 0x99 + TLV type: Info (2) + TLV length: 36 + Slot: 1 + Port: 4 + Virt chassis: 0 + Reserved: 000000000000 + Version: 7.6.4 Internal: 99 + Version: 0x07060463 + Version (major1): 7 + Version (major2): 6 + Version (sustaining): 4 + Version (internal): 99 + Connections: FFFFFFFF000000000000000000000000 + Null + Marker 0x99, length 4, type 0 = Null + TLV Marker: 0x99 + TLV type: Null (0) + TLV length: 4 + */ + char pkt1[] = { 0x00, 0xe0, 0x2b, 0x00, 0x00, 0x00, 0x5e, 0x10, 0x8e, 0xe7, + 0x84, 0xad, 0x00, 0x52, 0xaa, 0xaa, 0x03, 0x00, 0xe0, 0x2b, 0x00, 0xbb, + 0x01, 0x00, 0x00, 0x4a, 0xde, 0x22, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x10, + 0x8e, 0xe7, 0x84, 0xad, 0x99, 0x01, 0x00, 0x12, 0x46, 0x69, 0x72, 0x73, + 0x74, 0x20, 0x63, 0x68, 0x61, 0x73, 0x73, 0x69, 0x73, 0x00, 0x99, 0x02, + 0x00, 0x24, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x06, 0x04, 0x63, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, + 0x00, 0x04 }; + struct packet *pkt; + + /* Populate port and chassis */ + hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_IFNAME; + hardware.h_lport.p_id = "Not used"; + hardware.h_lport.p_id_len = strlen(hardware.h_lport.p_id); + hardware.h_lport.p_descr = "Not used"; + strlcpy(hardware.h_ifname, "eth3", sizeof(hardware.h_ifname)); + hardware.h_ifindex = 4; + chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR; + chassis.c_id = macaddress; + chassis.c_id_len = ETHER_ADDR_LEN; + chassis.c_name = "First chassis"; + /* Build packet */ + n = edp_send(NULL, &hardware); + if (n != 0) { + fail("unable to build packet"); + return; + } + if (TAILQ_EMPTY(&pkts)) { + fail("no packets sent"); + return; + } + pkt = TAILQ_FIRST(&pkts); + ck_assert_int_eq(pkt->size, sizeof(pkt1)); + fail_unless(memcmp(pkt->data, pkt1, sizeof(pkt1)) == 0); + fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent"); +} +END_TEST + +# ifdef ENABLE_DOT1 +START_TEST(test_send_vlans) +{ + int n; + /* Packets we should build: +Extreme Discovery Protocol + Version: 1 + Reserved: 0 + Data length: 74 + Checksum: 0xde20 [correct] + [Good: True] + [Bad : False] + Sequence number: 2 + Machine ID type: MAC (0) + Machine MAC: 5e:10:8e:e7:84:ad (5e:10:8e:e7:84:ad) + Display: "First chassis" + Marker 0x99, length 18, type 1 = Display + TLV Marker: 0x99 + TLV type: Display (1) + TLV length: 18 + Name: First chassis + Info: Slot/Port: 1/4, Version: 7.6.4.99 + Marker 0x99, length 36, type 2 = Info + TLV Marker: 0x99 + TLV type: Info (2) + TLV length: 36 + Slot: 1 + Port: 4 + Virt chassis: 0 + Reserved: 000000000000 + Version: 7.6.4 Internal: 99 + Version: 0x07060463 + Version (major1): 7 + Version (major2): 6 + Version (sustaining): 4 + Version (internal): 99 + Connections: FFFFFFFF000000000000000000000000 + Null + Marker 0x99, length 4, type 0 = Null + TLV Marker: 0x99 + TLV type: Null (0) + TLV length: 4 + +Extreme Discovery Protocol + Version: 1 + Reserved: 0 + Data length: 102 + Checksum: 0x28c4 [correct] + [Good: True] + [Bad : False] + Sequence number: 3 + Machine ID type: MAC (0) + Machine MAC: 5e:10:8e:e7:84:ad (5e:10:8e:e7:84:ad) + Vlan: ID 157, Name "First VLAN" + Marker 0x99, length 27, type 5 = VL + TLV Marker: 0x99 + TLV type: VL (5) + TLV length: 27 + Flags: 0x00 + 0... .... = Flags-IP: Not set + .000 000. = Flags-reserved: 0x00 + .... ...0 = Flags-Unknown: Not set + Reserved1: 00 + Vlan ID: 157 + Reserved2: 00000000 + IP addr: 0.0.0.0 (0.0.0.0) + Name: First VLAN + Vlan: ID 1247, Name "Second VLAN" + Marker 0x99, length 28, type 5 = VL + TLV Marker: 0x99 + TLV type: VL (5) + TLV length: 28 + Flags: 0x00 + 0... .... = Flags-IP: Not set + .000 000. = Flags-reserved: 0x00 + .... ...0 = Flags-Unknown: Not set + Reserved1: 00 + Vlan ID: 1247 + Reserved2: 00000000 + IP addr: 0.0.0.0 (0.0.0.0) + Name: Second VLAN + Vlan: ID 741, Name "Third VLAN" + Marker 0x99, length 27, type 5 = VL + TLV Marker: 0x99 + TLV type: VL (5) + TLV length: 27 + Flags: 0x00 + 0... .... = Flags-IP: Not set + .000 000. = Flags-reserved: 0x00 + .... ...0 = Flags-Unknown: Not set + Reserved1: 00 + Vlan ID: 741 + Reserved2: 00000000 + IP addr: 0.0.0.0 (0.0.0.0) + Name: Third VLAN + Null + Marker 0x99, length 4, type 0 = Null + TLV Marker: 0x99 + TLV type: Null (0) + TLV length: 4 + */ + char pkt1[] = { 0x00, 0xe0, 0x2b, 0x00, 0x00, 0x00, 0x5e, 0x10, 0x8e, 0xe7, + 0x84, 0xad, 0x00, 0x52, 0xaa, 0xaa, 0x03, 0x00, 0xe0, 0x2b, 0x00, 0xbb, + 0x01, 0x00, 0x00, 0x4a, 0xde, 0x20, 0x00, 0x02, 0x00, 0x00, 0x5e, 0x10, + 0x8e, 0xe7, 0x84, 0xad, 0x99, 0x01, 0x00, 0x12, 0x46, 0x69, 0x72, 0x73, + 0x74, 0x20, 0x63, 0x68, 0x61, 0x73, 0x73, 0x69, 0x73, 0x00, 0x99, 0x02, + 0x00, 0x24, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x06, 0x04, 0x63, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, + 0x00, 0x04 }; + + char pkt2[] = { 0x00, 0xe0, 0x2b, 0x00, 0x00, 0x00, 0x5e, 0x10, 0x8e, 0xe7, + 0x84, 0xad, 0x00, 0x6e, 0xaa, 0xaa, 0x03, 0x00, 0xe0, 0x2b, 0x00, 0xbb, + 0x01, 0x00, 0x00, 0x66, 0x28, 0xc4, 0x00, 0x03, 0x00, 0x00, 0x5e, 0x10, + 0x8e, 0xe7, 0x84, 0xad, 0x99, 0x05, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x9d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x69, 0x72, 0x73, + 0x74, 0x20, 0x56, 0x4c, 0x41, 0x4e, 0x00, 0x99, 0x05, 0x00, 0x1c, 0x00, + 0x00, 0x04, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, + 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x56, 0x4c, 0x41, 0x4e, 0x00, 0x99, + 0x05, 0x00, 0x1b, 0x00, 0x00, 0x02, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x54, 0x68, 0x69, 0x72, 0x64, 0x20, 0x56, 0x4c, 0x41, + 0x4e, 0x00, 0x99, 0x00, 0x00, 0x04 }; + + struct packet *pkt; + struct lldpd_vlan vlan1, vlan2, vlan3; + + /* Populate port and chassis */ + hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_IFNAME; + hardware.h_lport.p_id = "Not used"; + hardware.h_lport.p_id_len = strlen(hardware.h_lport.p_id); + hardware.h_lport.p_descr = "Not used"; + strlcpy(hardware.h_ifname, "eth3", sizeof(hardware.h_ifname)); + hardware.h_ifindex = 4; + chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR; + chassis.c_id = macaddress; + chassis.c_id_len = ETHER_ADDR_LEN; + chassis.c_name = "First chassis"; + vlan1.v_name = "First VLAN"; + vlan1.v_vid = 157; + vlan2.v_name = "Second VLAN"; + vlan2.v_vid = 1247; + vlan3.v_name = "Third VLAN"; + vlan3.v_vid = 741; + TAILQ_INSERT_TAIL(&hardware.h_lport.p_vlans, &vlan1, v_entries); + TAILQ_INSERT_TAIL(&hardware.h_lport.p_vlans, &vlan2, v_entries); + TAILQ_INSERT_TAIL(&hardware.h_lport.p_vlans, &vlan3, v_entries); + + /* Build packet */ + n = edp_send(NULL, &hardware); + if (n != 0) { + fail("unable to build packet"); + return; + } + if (TAILQ_EMPTY(&pkts)) { + fail("no packets sent"); + return; + } + pkt = TAILQ_FIRST(&pkts); + ck_assert_int_eq(pkt->size, sizeof(pkt1)); + fail_unless(memcmp(pkt->data, pkt1, sizeof(pkt1)) == 0); + pkt = TAILQ_NEXT(pkt, next); + if (!pkt) { + fail("need one more packet"); + return; + } + ck_assert_int_eq(pkt->size, sizeof(pkt2)); + fail_unless(memcmp(pkt->data, pkt2, sizeof(pkt2)) == 0); + fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than two packets sent"); +} +END_TEST +# endif + +START_TEST(test_recv_edp) +{ + char pkt1[] = { 0x00, 0xe0, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x04, 0x96, 0x05, + 0x44, 0x6f, 0x01, 0x44, 0xaa, 0xaa, 0x03, 0x00, 0xe0, 0x2b, 0x00, 0xbb, + 0x01, 0x00, 0x01, 0x3c, 0x05, 0xdf, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x04, + 0x96, 0x05, 0x44, 0x6f, 0x99, 0x02, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x06, 0x04, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x99, 0x01, 0x01, 0x04, 0x6e, 0x65, 0x30, 0x35, + 0x30, 0x31, 0x73, 0x77, 0x2e, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x79, 0x0d, 0xec, + 0xff, 0xff, 0xff, 0xff, 0x80, 0xa7, 0x8b, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x17, 0x08, 0x7e, 0xe5, 0xe2, 0x00, 0x00, 0xee, 0xee, 0xee, 0xee, + 0x00, 0x00, 0x00, 0x02, 0x81, 0xb2, 0x19, 0xf0, 0x00, 0x00, 0x00, 0x02, + 0x80, 0xa5, 0x67, 0x20, 0xee, 0xee, 0xee, 0xee, 0x80, 0xea, 0x8c, 0xac, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x2b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xa4, 0x86, 0x2c, + 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, + 0xee, 0xee, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0xee, 0xee, + 0x00, 0xe0, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, + 0x99, 0x00, 0x00, 0x04 }; + /* This is: +IEEE 802.3 Ethernet + Destination: Extreme-EDP (00:e0:2b:00:00:00) + Source: ExtremeN_05:44:6f (00:04:96:05:44:6f) + Length: 324 +Logical-Link Control + DSAP: SNAP (0xaa) + IG Bit: Individual + SSAP: SNAP (0xaa) + CR Bit: Command + Control field: U, func=UI (0x03) + 000. 00.. = Command: Unnumbered Information (0x00) + .... ..11 = Frame type: Unnumbered frame (0x03) + Organization Code: Extreme Networks (0x00e02b) + PID: EDP (0x00bb) +Extreme Discovery Protocol + Version: 1 + Reserved: 0 + Data length: 316 + Checksum: 0xdf05 [correct] + [Good: True] + [Bad : False] + Sequence number: 783 + Machine ID type: MAC (0) + Machine MAC: ExtremeN_05:44:6f (00:04:96:05:44:6f) + Info: Slot/Port: 1/1, Version: 7.6.4.0 + Marker 0x99, length 36, type 2 = Info + TLV Marker: 0x99 + TLV type: Info (2) + TLV length: 36 + Slot: 1 + Port: 1 + Virt chassis: 0 + Reserved: 000000000000 + Version: 7.6.4 Internal: 0 + Version: 0x07060400 + Version (major1): 7 + Version (major2): 6 + Version (sustaining): 4 + Version (internal): 0 + Connections: FFFF0000000000000000000000000000 + Display: "ne0501sw.XXXXXX" + Marker 0x99, length 260, type 1 = Display + TLV Marker: 0x99 + TLV type: Display (1) + TLV length: 260 + Name: ne0501sw.XXXXXX + Null + Marker 0x99, length 4, type 0 = Null + TLV Marker: 0x99 + TLV type: Null (0) + TLV length: 4 + */ + +# ifdef ENABLE_DOT1 + char pkt2[] = { 0x00, 0xe0, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x04, 0x96, 0x05, + 0x44, 0x6f, 0x01, 0x48, 0xaa, 0xaa, 0x03, 0x00, 0xe0, 0x2b, 0x00, 0xbb, + 0x01, 0x00, 0x01, 0x40, 0x73, 0x04, 0x03, 0x10, 0x00, 0x00, 0x00, 0x04, + 0x96, 0x05, 0x44, 0x6f, 0x99, 0x05, 0x00, 0x64, 0x80, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x00, 0x43, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x73, + 0x61, 0x76, 0x65, 0x20, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x20, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x6e, 0x76, + 0x20, 0x28, 0x25, 0x64, 0x29, 0x0a, 0x00, 0x00, 0x4e, 0x6f, 0x20, 0x62, + 0x72, 0x69, 0x64, 0x67, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x75, + 0x70, 0x65, 0x72, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x49, 0x6e, 0x73, + 0x74, 0x20, 0x25, 0x64, 0x00, 0x00, 0x00, 0x00, 0x99, 0x05, 0x00, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4d, 0x61, 0x63, 0x56, 0x6c, 0x61, 0x6e, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x99, 0x05, 0x00, 0x64, 0x80, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x0a, 0x32, 0x00, 0x3f, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x42, 0x32, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x04 }; + /* This is: +IEEE 802.3 Ethernet + Destination: Extreme-EDP (00:e0:2b:00:00:00) + Source: ExtremeN_05:44:6f (00:04:96:05:44:6f) + Length: 328 +Logical-Link Control + DSAP: SNAP (0xaa) + IG Bit: Individual + SSAP: SNAP (0xaa) + CR Bit: Command + Control field: U, func=UI (0x03) + 000. 00.. = Command: Unnumbered Information (0x00) + .... ..11 = Frame type: Unnumbered frame (0x03) + Organization Code: Extreme Networks (0x00e02b) + PID: EDP (0x00bb) +Extreme Discovery Protocol + Version: 1 + Reserved: 0 + Data length: 320 + Checksum: 0x7304 [correct] + [Good: True] + [Bad : False] + Sequence number: 784 + Machine ID type: MAC (0) + Machine MAC: ExtremeN_05:44:6f (00:04:96:05:44:6f) + Vlan: ID 1, Name "Default" + Marker 0x99, length 100, type 5 = VL + TLV Marker: 0x99 + TLV type: VL (5) + TLV length: 100 + Flags: 0x80 + 1... .... = Flags-IP: Set + .000 000. = Flags-reserved: 0x00 + .... ...0 = Flags-Unknown: Not set + Reserved1: 00 + Vlan ID: 1 + Reserved2: 00000000 + IP addr: 0.0.0.0 (0.0.0.0) + Name: Default + Vlan: ID 0, Name "MacVlanDiscover" + Marker 0x99, length 100, type 5 = VL + TLV Marker: 0x99 + TLV type: VL (5) + TLV length: 100 + Flags: 0x00 + 0... .... = Flags-IP: Not set + .000 000. = Flags-reserved: 0x00 + .... ...0 = Flags-Unknown: Not set + Reserved1: 00 + Vlan ID: 0 + Reserved2: 00000000 + IP addr: 0.0.0.0 (0.0.0.0) + Name: MacVlanDiscover + Vlan: ID 50, Name "AdminB2" + Marker 0x99, length 100, type 5 = VL + TLV Marker: 0x99 + TLV type: VL (5) + TLV length: 100 + Flags: 0x80 + 1... .... = Flags-IP: Set + .000 000. = Flags-reserved: 0x00 + .... ...0 = Flags-Unknown: Not set + Reserved1: 00 + Vlan ID: 50 + Reserved2: 00000000 + IP addr: 10.50.0.63 (10.50.0.63) + Name: AdminB2 + Null + Marker 0x99, length 4, type 0 = Null + TLV Marker: 0x99 + TLV type: Null (0) + TLV length: 4 + */ + struct lldpd_vlan *vlan; +# endif + struct lldpd_chassis *nchassis = NULL; + struct lldpd_port *nport = NULL; + struct lldpd cfg; + char mac1[] = { 0x00, 0x04, 0x96, 0x05, 0x44, 0x6f }; + + cfg.g_config.c_mgmt_pattern = NULL; + fail_unless( + edp_decode(&cfg, pkt1, sizeof(pkt1), &hardware, &nchassis, &nport) != -1); + if (!nchassis || !nport) { + fail("unable to decode packet"); + return; + } + ck_assert_int_eq(nchassis->c_id_subtype, LLDP_CHASSISID_SUBTYPE_LLADDR); + ck_assert_int_eq(nchassis->c_id_len, ETHER_ADDR_LEN); + fail_unless(memcmp(nchassis->c_id, mac1, ETHER_ADDR_LEN) == 0); + ck_assert_int_eq(nport->p_id_subtype, LLDP_PORTID_SUBTYPE_IFNAME); + ck_assert_int_eq(nport->p_id_len, strlen("1/1")); + fail_unless(memcmp(nport->p_id, "1/1", strlen("1/1")) == 0); + ck_assert_str_eq(nport->p_descr, "Slot 1 / Port 1"); + ck_assert_str_eq(nchassis->c_name, "ne0501sw.XXXXXX"); + ck_assert_str_eq(nchassis->c_descr, "EDP enabled device, version 7.6.4.0"); + ck_assert_int_eq(nchassis->c_cap_enabled, 0); + +# ifdef ENABLE_DOT1 + /* Add this port to list of remote port for hardware port */ + TAILQ_INSERT_TAIL(&hardware.h_rports, nport, p_entries); + nport->p_chassis = nchassis; + nport->p_protocol = LLDPD_MODE_EDP; + + /* Recept second packet */ + nchassis = NULL; + nport = NULL; + fail_unless( + edp_decode(&cfg, pkt2, sizeof(pkt2), &hardware, &nchassis, &nport) == -1); + nport = TAILQ_FIRST(&hardware.h_rports); + if (!nport) { + fail("unable to find our previous port?"); + return; + } + ck_assert_int_eq(TAILQ_FIRST(&nport->p_chassis->c_mgmt)->m_addr.inet.s_addr, + (u_int32_t)inet_addr("10.50.0.63")); + if (TAILQ_EMPTY(&nport->p_vlans)) { + fail("no VLAN"); + return; + } + vlan = TAILQ_FIRST(&nport->p_vlans); + ck_assert_int_eq(vlan->v_vid, 1); + ck_assert_str_eq(vlan->v_name, "Default"); + vlan = TAILQ_NEXT(vlan, v_entries); + if (!vlan) { + fail("no more VLAN"); + return; + } + ck_assert_int_eq(vlan->v_vid, 0); + ck_assert_str_eq(vlan->v_name, "MacVlanDiscover"); + vlan = TAILQ_NEXT(vlan, v_entries); + if (!vlan) { + fail("no more VLAN"); + return; + } + ck_assert_int_eq(vlan->v_vid, 50); + ck_assert_str_eq(vlan->v_name, "AdminB2"); + vlan = TAILQ_NEXT(vlan, v_entries); + fail_unless(vlan == NULL); +# endif +} +END_TEST + +#endif + +static Suite * +edp_suite(void) +{ + Suite *s = suite_create("EDP"); + +#ifdef ENABLE_EDP + TCase *tc_send = tcase_create("Send EDP packets"); + TCase *tc_receive = tcase_create("Receive EDP packets"); + + tcase_add_checked_fixture(tc_send, pcap_setup, pcap_teardown); + tcase_add_test(tc_send, test_send_basic); +# ifdef ENABLE_DOT1 + tcase_add_test(tc_send, test_send_vlans); +# endif + suite_add_tcase(s, tc_send); + + tcase_add_test(tc_receive, test_recv_edp); + suite_add_tcase(s, tc_receive); +#endif + + return s; +} + +int +main() +{ + int number_failed; + Suite *s = edp_suite(); + SRunner *sr = srunner_create(s); + srunner_set_fork_status(sr, CK_NOFORK); /* Can't fork because + we need to write + files */ + srunner_run_all(sr, CK_ENV); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/tests/check_fixedpoint.c b/tests/check_fixedpoint.c new file mode 100644 index 0000000..a37d370 --- /dev/null +++ b/tests/check_fixedpoint.c @@ -0,0 +1,353 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2012 Vincent Bernat <bernat@luffy.cx> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <check.h> +#include <stdlib.h> + +#include "../src/lib/fixedpoint.h" + +#ifdef ENABLE_LLDPMED + +START_TEST(test_string_parsing_suffix) +{ + char *end; + fp_strtofp("4541T", &end, 14, 8); + ck_assert_int_eq(*end, 'T'); + fp_strtofp("4541.U", &end, 14, 8); + ck_assert_int_eq(*end, 'U'); + fp_strtofp("4541.676V", &end, 14, 8); + ck_assert_int_eq(*end, 'V'); +} +END_TEST + +START_TEST(test_string_parsing_positive_int) +{ + struct fp_number fp = fp_strtofp("4541T", NULL, 14, 8); + ck_assert_int_eq(fp.integer.bits, 14); + ck_assert_int_eq(fp.integer.value, 4541); + ck_assert_int_eq(fp.fraction.bits, 8); + ck_assert_int_eq(fp.fraction.value, 0); + ck_assert_int_eq(fp.fraction.precision, 0); +} +END_TEST + +START_TEST(test_string_parsing_negative_int) +{ + struct fp_number fp = fp_strtofp("-4214N", NULL, 14, 8); + ck_assert_int_eq(fp.integer.bits, 14); + ck_assert_int_eq(fp.integer.value, -4214); + ck_assert_int_eq(fp.fraction.bits, 8); + ck_assert_int_eq(fp.fraction.value, 0); + ck_assert_int_eq(fp.fraction.precision, 0); +} +END_TEST + +START_TEST(test_string_parsing_positive_int_overflow) +{ + struct fp_number fp1 = fp_strtofp("4098", NULL, 13, 8); + struct fp_number fp2 = fp_strtofp("4096", NULL, 13, 8); + struct fp_number fp3 = fp_strtofp("4095", NULL, 13, 8); + struct fp_number fp4 = fp_strtofp("4094", NULL, 13, 8); + ck_assert_int_eq(fp1.integer.value, 4095); + ck_assert_int_eq(fp2.integer.value, 4095); + ck_assert_int_eq(fp3.integer.value, 4095); + ck_assert_int_eq(fp4.integer.value, 4094); +} +END_TEST + +START_TEST(test_string_parsing_negative_int_overflow) +{ + struct fp_number fp1 = fp_strtofp("-4097", NULL, 13, 8); + struct fp_number fp2 = fp_strtofp("-4096", NULL, 13, 8); + struct fp_number fp3 = fp_strtofp("-4095", NULL, 13, 8); + struct fp_number fp4 = fp_strtofp("-4094", NULL, 13, 8); + ck_assert_int_eq(fp1.integer.value, -4096); + ck_assert_int_eq(fp2.integer.value, -4096); + ck_assert_int_eq(fp3.integer.value, -4095); + ck_assert_int_eq(fp4.integer.value, -4094); +} +END_TEST + +START_TEST(test_string_parsing_positive_float) +{ + struct fp_number fp1 = fp_strtofp("1542.6250E", NULL, 13, 20); + ck_assert_int_eq(fp1.integer.value, 1542); + ck_assert_int_eq(fp1.fraction.precision, 14); + ck_assert_int_eq((fp1.fraction.value * 10000) >> fp1.fraction.bits, 6250); + + struct fp_number fp2 = fp_strtofp("1542.06250E", NULL, 13, 4); + ck_assert_int_eq(fp2.integer.value, 1542); + ck_assert_int_eq(fp2.fraction.precision, 4); + ck_assert_int_eq((fp2.fraction.value * 10000) >> fp2.fraction.bits, 625); +} +END_TEST + +START_TEST(test_string_parsing_negative_float) +{ + struct fp_number fp = fp_strtofp("-11542.6250N", NULL, 15, 4); + ck_assert_int_eq(fp.integer.value, -11542); + ck_assert_int_eq(fp.fraction.precision, 4); + ck_assert_int_eq((fp.fraction.value * 10000) >> fp.fraction.bits, 6250); +} +END_TEST + +START_TEST(test_string_parsing_no_fract_part) +{ + struct fp_number fp = fp_strtofp("11542.", NULL, 15, 4); + ck_assert_int_eq(fp.integer.value, 11542); + ck_assert_int_eq(fp.fraction.value, 0); + ck_assert_int_eq(fp.fraction.precision, 1); +} +END_TEST + +START_TEST(test_string_parsing_no_int_part) +{ + struct fp_number fp = fp_strtofp(".6250E", NULL, 13, 4); + ck_assert_int_eq(fp.integer.value, 0); + ck_assert_int_eq(fp.fraction.precision, 4); + ck_assert_int_eq((fp.fraction.value * 10000) >> fp.fraction.bits, 6250); +} +END_TEST + +START_TEST(test_string_representation_positive_int) +{ + struct fp_number fp1 = fp_strtofp("214", NULL, 9, 9); + struct fp_number fp2 = fp_strtofp("11178.0000", NULL, 15, 9); + ck_assert_str_eq(fp_fptostr(fp1, NULL), "214"); + ck_assert_str_eq(fp_fptostr(fp2, NULL), "11178"); + ck_assert_str_eq(fp_fptostr(fp2, "ES"), "11178E"); +} +END_TEST + +START_TEST(test_string_representation_negative_int) +{ + struct fp_number fp1 = fp_strtofp("-214", NULL, 9, 9); + struct fp_number fp2 = fp_strtofp("-11178.0000", NULL, 15, 9); + ck_assert_str_eq(fp_fptostr(fp1, NULL), "-214"); + ck_assert_str_eq(fp_fptostr(fp2, NULL), "-11178"); + ck_assert_str_eq(fp_fptostr(fp2, "ES"), "11178S"); +} +END_TEST + +START_TEST(test_string_representation_positive_float) +{ + struct fp_number fp = fp_strtofp("214.6250", NULL, 9, 20); + ck_assert_str_eq(fp_fptostr(fp, NULL), "214.6250"); + ck_assert_str_eq(fp_fptostr(fp, "ES"), "214.6250E"); +} +END_TEST + +START_TEST(test_string_representation_positive_float_with_leading_zero) +{ + struct fp_number fp = fp_strtofp("214.06250", NULL, 9, 24); + ck_assert_str_eq(fp_fptostr(fp, NULL), "214.06250"); + ck_assert_str_eq(fp_fptostr(fp, "ES"), "214.06250E"); +} +END_TEST + +START_TEST(test_string_representation_negative_float) +{ + struct fp_number fp1 = fp_strtofp("-214.625", NULL, 22, 10); + struct fp_number fp2 = fp_strtofp("-415.5", NULL, 22, 4); + ck_assert_str_eq(fp_fptostr(fp1, NULL), "-214.625"); + ck_assert_str_eq(fp_fptostr(fp2, NULL), "-415.5"); + ck_assert_str_eq(fp_fptostr(fp2, "ES"), "415.5S"); +} +END_TEST + +START_TEST(test_buffer_representation_positive_float) +{ + unsigned char buffer[5] = {}; + unsigned char expected[] = { 0x21 << 2, 47 << 1, 0x68, 0x00, 0x00 }; + /* 47.2031250 = 47 + 2**-3 + 2**-4 + 2**-6, precision = 9+24 */ + struct fp_number fp = fp_strtofp("47.2031250", NULL, 9, 25); + fp_fptobuf(fp, buffer, 0); + fail_unless(memcmp(buffer, expected, sizeof(expected)) == 0); +} +END_TEST + +START_TEST(test_buffer_representation_negative_float) +{ + unsigned char buffer[5] = {}; + unsigned char expected[] = { (0x21 << 2) | 3, 0xa1, 0x98, 0x00, 0x00 }; + /* 47.2031250 = 000101111.0011010000000000000000000 */ + /* -47.2031250 = 111010000.1100101111111111111111111 + 1 */ + /* -47.2031250 = 111010000.1100110000000000000000000 */ + struct fp_number fp = fp_strtofp("-47.2031250", NULL, 9, 25); + fp_fptobuf(fp, buffer, 0); + fail_unless(memcmp(buffer, expected, sizeof(expected)) == 0); +} +END_TEST + +START_TEST(test_buffer_representation_with_shift) +{ + unsigned char buffer[] = { 0x77, 0xc6, 0x0, 0x0, 0x0, 0x0, 0xc7 }; + unsigned char expected[] = { 0x77, 0xc8, 0x45, 0xe6, 0x80, 0x00, 0x07 }; + struct fp_number fp = fp_strtofp("47.2031250", NULL, 9, 25); + fp_fptobuf(fp, buffer, 12); + fail_unless(memcmp(buffer, expected, sizeof(buffer)) == 0); +} +END_TEST + +START_TEST(test_buffer_representation_altitude) +{ + unsigned char buffer[5] = {}; + unsigned char expected[] = { (22 + 4) << 2, 0, 0, 14 << 4 | 1 << 3, 0 }; + struct fp_number fp = fp_strtofp("14.5", NULL, 22, 8); + fp_fptobuf(fp, buffer, 0); + fail_unless(memcmp(buffer, expected, sizeof(buffer)) == 0); +} +END_TEST + +START_TEST(test_buffer_parsing_positive_float) +{ + unsigned char buffer[] = { 0x21 << 2, 47 << 1, 0x68, 0x00, 0x00 }; + struct fp_number fp = fp_buftofp(buffer, 9, 25, 0); + ck_assert_int_eq(fp.integer.value, 47); + ck_assert_int_eq(fp.integer.bits, 9); + ck_assert_int_eq((fp.fraction.value * 10000000) >> fp.fraction.bits, 2031250); + ck_assert_int_eq(fp.fraction.bits, 25); + ck_assert_int_eq(fp.fraction.precision, 24); +} +END_TEST + +START_TEST(test_buffer_parsing_negative_float) +{ + unsigned char buffer[] = { (0x21 << 2) | 3, 0xa1, 0x98, 0x00, 0x00 }; + struct fp_number fp = fp_buftofp(buffer, 9, 25, 0); + ck_assert_int_eq(fp.integer.value, -47); + ck_assert_int_eq(fp.integer.bits, 9); + ck_assert_int_eq((fp.fraction.value * 10000000) >> fp.fraction.bits, 2031250); + ck_assert_int_eq(fp.fraction.bits, 25); + ck_assert_int_eq(fp.fraction.precision, 24); +} +END_TEST + +/* This is some corner case */ +START_TEST(test_buffer_parsing_positive_float_2) +{ + unsigned char buffer[] = { 0x40, 0x9c, 0x80, 0x00, 0x00 }; + struct fp_number fp = fp_buftofp(buffer, 9, 25, 0); + ck_assert_int_eq(fp.integer.value, 78); +} +END_TEST + +START_TEST(test_buffer_parsing_positive_float_with_shift) +{ + unsigned char buffer[] = { 0x77, 0xc8, 0x45, 0xe6, 0x80, 0x00, 0x07 }; + struct fp_number fp = fp_buftofp(buffer, 9, 25, 12); + ck_assert_int_eq(fp.integer.value, 47); + ck_assert_int_eq(fp.integer.bits, 9); + ck_assert_int_eq((fp.fraction.value * 10000000) >> fp.fraction.bits, 2031250); + ck_assert_int_eq(fp.fraction.bits, 25); + ck_assert_int_eq(fp.fraction.precision, 24); +} +END_TEST + +START_TEST(test_buffer_parsing_negative_float_with_shift) +{ + unsigned char buffer[] = { 0x00, 0xff, (0x21 << 2) | 3, 0xa1, 0x98, 0x00, + 0x00 }; + struct fp_number fp = fp_buftofp(buffer, 9, 25, 16); + ck_assert_int_eq(fp.integer.value, -47); + ck_assert_int_eq(fp.integer.bits, 9); + ck_assert_int_eq((fp.fraction.value * 10000000) >> fp.fraction.bits, 2031250); + ck_assert_int_eq(fp.fraction.bits, 25); + ck_assert_int_eq(fp.fraction.precision, 24); +} +END_TEST + +START_TEST(test_negate_positive) +{ + struct fp_number fp = fp_strtofp("14.5", NULL, 9, 25); + struct fp_number nfp = fp_negate(fp); + ck_assert_int_eq(nfp.integer.value, -14); + ck_assert_int_eq(fp.fraction.value, nfp.fraction.value); + ck_assert_str_eq(fp_fptostr(nfp, NULL), "-14.5"); +} +END_TEST + +START_TEST(test_negate_negative) +{ + struct fp_number fp = fp_strtofp("-14.5", NULL, 9, 25); + struct fp_number nfp = fp_negate(fp); + ck_assert_int_eq(nfp.integer.value, 14); + ck_assert_int_eq(fp.fraction.value, nfp.fraction.value); + ck_assert_str_eq(fp_fptostr(nfp, NULL), "14.5"); +} +END_TEST + +#endif + +static Suite * +fixedpoint_suite(void) +{ + Suite *s = suite_create("Fixed point representation"); + +#ifdef ENABLE_LLDPMED + TCase *tc_fp = tcase_create("Fixed point representation"); + tcase_add_test(tc_fp, test_string_parsing_suffix); + tcase_add_test(tc_fp, test_string_parsing_positive_int); + tcase_add_test(tc_fp, test_string_parsing_negative_int); + tcase_add_test(tc_fp, test_string_parsing_no_fract_part); + tcase_add_test(tc_fp, test_string_parsing_no_int_part); + tcase_add_test(tc_fp, test_string_parsing_positive_int_overflow); + tcase_add_test(tc_fp, test_string_parsing_negative_int_overflow); + tcase_add_test(tc_fp, test_string_parsing_positive_float); + tcase_add_test(tc_fp, test_string_parsing_negative_float); + tcase_add_test(tc_fp, test_string_representation_positive_int); + tcase_add_test(tc_fp, test_string_representation_negative_int); + tcase_add_test(tc_fp, test_string_representation_positive_float); + tcase_add_test(tc_fp, + test_string_representation_positive_float_with_leading_zero); + tcase_add_test(tc_fp, test_string_representation_negative_float); + tcase_add_test(tc_fp, test_buffer_representation_positive_float); + tcase_add_test(tc_fp, test_buffer_representation_negative_float); + tcase_add_test(tc_fp, test_buffer_representation_with_shift); + tcase_add_test(tc_fp, test_buffer_representation_altitude); + tcase_add_test(tc_fp, test_buffer_parsing_positive_float); + tcase_add_test(tc_fp, test_buffer_parsing_positive_float_2); + tcase_add_test(tc_fp, test_buffer_parsing_negative_float); + tcase_add_test(tc_fp, test_buffer_parsing_positive_float_with_shift); + tcase_add_test(tc_fp, test_buffer_parsing_negative_float_with_shift); + tcase_add_test(tc_fp, test_negate_positive); + tcase_add_test(tc_fp, test_negate_negative); + suite_add_tcase(s, tc_fp); +#endif + + return s; +} + +/* Disable leak detection sanitizer */ +int __lsan_is_turned_off(void); +int +__lsan_is_turned_off(void) +{ + return 1; +} + +int +main() +{ + int number_failed; + Suite *s = fixedpoint_suite(); + SRunner *sr = srunner_create(s); + srunner_run_all(sr, CK_ENV); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/tests/check_lldp.c b/tests/check_lldp.c new file mode 100644 index 0000000..bd6637e --- /dev/null +++ b/tests/check_lldp.c @@ -0,0 +1,835 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2015 Vincent Bernat <bernat@luffy.cx> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdlib.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <check.h> +#include "common.h" + +char filenameprefix[] = "lldp_send"; + +static struct lldpd test_lldpd = { .g_config = { + .c_cap_advertise = + 1, /* Chassis capabilities advertisement */ + .c_mgmt_advertise = + 1, /* Management addresses advertisement */ + } }; + +#define ck_assert_str_eq_n(X, Y, N) \ + ck_assert_msg(!strncmp(X, Y, N), \ + "Assertion '" #X "==" #Y "' failed: " #X "==\"%s\", " #Y "==\"%s\"", X, Y) + +static void +check_received_port(struct lldpd_port *sport, struct lldpd_port *rport) +{ + ck_assert_int_eq(rport->p_id_subtype, sport->p_id_subtype); + ck_assert_int_eq(rport->p_id_len, sport->p_id_len); + ck_assert_str_eq_n(rport->p_id, sport->p_id, sport->p_id_len); + ck_assert_str_eq(rport->p_descr, sport->p_descr); +#ifdef ENABLE_DOT3 + ck_assert_int_eq(rport->p_mfs, sport->p_mfs); +#endif +} + +static void +check_received_chassis(struct lldpd_chassis *schassis, struct lldpd_chassis *rchassis) +{ + ck_assert_int_eq(rchassis->c_id_subtype, schassis->c_id_subtype); + ck_assert_int_eq(rchassis->c_id_len, schassis->c_id_len); + ck_assert_str_eq_n(rchassis->c_id, schassis->c_id, schassis->c_id_len); + ck_assert_str_eq(rchassis->c_name, schassis->c_name); + ck_assert_str_eq(rchassis->c_descr, schassis->c_descr); + ck_assert_int_eq(rchassis->c_cap_available, schassis->c_cap_available); + ck_assert_int_eq(rchassis->c_cap_enabled, schassis->c_cap_enabled); +} + +#ifdef ENABLE_LLDPMED +static void +check_received_port_med(struct lldpd_port *sport, struct lldpd_port *rport) +{ + ck_assert_int_eq(rport->p_med_cap_enabled, sport->p_med_cap_enabled); + ck_assert_int_eq(rport->p_med_cap_enabled, sport->p_med_cap_enabled); + ck_assert_int_eq(rport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC - 1].format, + sport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC - 1].format); + ck_assert_int_eq(rport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC - 1].data_len, + sport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC - 1].data_len); + ck_assert_str_eq_n(rport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC - 1].data, + sport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC - 1].data, + sport->p_med_location[LLDP_MED_LOCFORMAT_CIVIC - 1].data_len); + ck_assert_int_eq(rport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE - 1].type, + sport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE - 1].type); + ck_assert_int_eq( + rport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE - 1].tagged, + sport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE - 1].tagged); + ck_assert_int_eq(rport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE - 1].vid, + sport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE - 1].vid); + ck_assert_int_eq( + rport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE - 1].priority, + sport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE - 1].priority); + ck_assert_int_eq(rport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE - 1].dscp, + sport->p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE - 1].dscp); + ck_assert_int_eq(rport->p_med_power.devicetype, sport->p_med_power.devicetype); + ck_assert_int_eq(rport->p_med_power.source, sport->p_med_power.source); + ck_assert_int_eq(rport->p_med_power.priority, sport->p_med_power.priority); + ck_assert_int_eq(rport->p_med_power.val, sport->p_med_power.val); +} + +static void +check_received_chassis_med(struct lldpd_chassis *schassis, + struct lldpd_chassis *rchassis) +{ + ck_assert_int_eq(rchassis->c_med_cap_available, schassis->c_med_cap_available); + ck_assert_int_eq(rchassis->c_med_type, schassis->c_med_type); + ck_assert_str_eq(rchassis->c_med_hw, schassis->c_med_hw); + ck_assert_str_eq(rchassis->c_med_fw, schassis->c_med_fw); + ck_assert_str_eq(rchassis->c_med_sw, schassis->c_med_sw); + ck_assert_str_eq(rchassis->c_med_sn, schassis->c_med_sn); +} +#endif + +#ifdef ENABLE_DOT3 +static void +check_received_port_dot3(struct lldpd_port *sport, struct lldpd_port *rport) +{ + ck_assert_int_eq(rport->p_aggregid, sport->p_aggregid); + ck_assert_int_eq(rport->p_macphy.autoneg_support, + sport->p_macphy.autoneg_support); + ck_assert_int_eq(rport->p_macphy.autoneg_enabled, + sport->p_macphy.autoneg_enabled); + ck_assert_int_eq(rport->p_macphy.autoneg_advertised, + sport->p_macphy.autoneg_advertised); + ck_assert_int_eq(rport->p_macphy.mau_type, sport->p_macphy.mau_type); +} +#endif + +START_TEST(test_send_rcv_basic) +{ + int n; + struct packet *pkt; + struct lldpd_chassis *nchassis = NULL; + struct lldpd_port *nport = NULL; + + /* Populate port and chassis */ + hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_IFNAME; + hardware.h_lport.p_id = "FastEthernet 1/5"; + hardware.h_lport.p_id_len = strlen(hardware.h_lport.p_id); + hardware.h_lport.p_descr = "Fake port description"; + hardware.h_lport.p_mfs = 1516; + chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR; + chassis.c_id = macaddress; + chassis.c_id_len = ETHER_ADDR_LEN; + chassis.c_name = "First chassis"; + chassis.c_descr = "Chassis description"; + chassis.c_cap_available = chassis.c_cap_enabled = LLDP_CAP_ROUTER; + + /* Build packet */ + n = lldp_send(&test_lldpd, &hardware); + if (n != 0) { + fail("unable to build packet"); + return; + } + if (TAILQ_EMPTY(&pkts)) { + fail("no packets sent"); + return; + } + pkt = TAILQ_FIRST(&pkts); + fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent"); + + /* decode the retrieved packet calling lldp_decode() */ + fail_unless(lldp_decode(NULL, pkt->data, pkt->size, &hardware, &nchassis, + &nport) != -1); + if (!nchassis || !nport) { + fail("unable to decode packet"); + return; + } + /* verify port values */ + check_received_port(&hardware.h_lport, nport); + /* verify chassis values */ + check_received_chassis(&chassis, nchassis); +} +END_TEST + +#define ETHERTYPE_OFFSET 2 * ETHER_ADDR_LEN +#define VLAN_TAG_SIZE 2 +START_TEST(test_send_rcv_vlan_tx) +{ + int n; + struct packet *pkt; + struct lldpd_chassis *nchassis = NULL; + struct lldpd_port *nport = NULL; + int vlan_id = 100; + int vlan_prio = 5; + int vlan_dei = 1; + unsigned int vlan_tag = 0; + unsigned int tmp; + + /* Populate port and chassis */ + hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_IFNAME; + hardware.h_lport.p_id = "FastEthernet 1/5"; + hardware.h_lport.p_id_len = strlen(hardware.h_lport.p_id); + hardware.h_lport.p_descr = "Fake port description"; + hardware.h_lport.p_mfs = 1516; + + /* Assembly VLAN tag: Priority(3bits) | DEI(1bit) | VID(12bits) */ + vlan_tag = + ((vlan_prio & 0x7) << 13) | ((vlan_dei & 0x1) << 12) | (vlan_id & 0xfff); + hardware.h_lport.p_vlan_tx_tag = vlan_tag; + hardware.h_lport.p_vlan_tx_enabled = 1; + chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR; + chassis.c_id = macaddress; + chassis.c_id_len = ETHER_ADDR_LEN; + chassis.c_name = "First chassis"; + chassis.c_descr = "Chassis description"; + chassis.c_cap_available = chassis.c_cap_enabled = LLDP_CAP_ROUTER; + + /* Build packet */ + n = lldp_send(&test_lldpd, &hardware); + if (n != 0) { + fail("unable to build packet"); + return; + } + if (TAILQ_EMPTY(&pkts)) { + fail("no packets sent"); + return; + } + pkt = TAILQ_FIRST(&pkts); + fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent"); + + /* Check ETHER_TYPE, should be VLAN */ + memcpy(&tmp, (unsigned char *)pkt->data + ETHERTYPE_OFFSET, ETHER_TYPE_LEN); + ck_assert_uint_eq(ntohl(tmp) >> 16, ETHERTYPE_VLAN); + + /* Check VLAN tag */ + memcpy(&tmp, (unsigned char *)pkt->data + ETHERTYPE_OFFSET + ETHER_TYPE_LEN, + VLAN_TAG_SIZE); + ck_assert_uint_eq(ntohl(tmp) >> 16, vlan_tag); + + /* Remove VLAN ethertype and VLAN tag */ + memmove((unsigned char *)pkt->data + ETHERTYPE_OFFSET, + /* move all after VLAN tag */ + (unsigned char *)pkt->data + ETHERTYPE_OFFSET + ETHER_TYPE_LEN + + VLAN_TAG_SIZE, + /* size without src and dst MAC, VLAN tag */ + pkt->size - (ETHERTYPE_OFFSET + ETHER_TYPE_LEN + VLAN_TAG_SIZE)); + + /* Decode the packet without VLAN tag, calling lldp_decode() */ + fail_unless(lldp_decode(NULL, pkt->data, pkt->size, &hardware, &nchassis, + &nport) != -1); + if (!nchassis || !nport) { + fail("unable to decode packet"); + return; + } + + /* Verify port values (VLAN information is not checked here) */ + check_received_port(&hardware.h_lport, nport); + /* Verify chassis values */ + check_received_chassis(&chassis, nchassis); +} +END_TEST + +#ifdef ENABLE_DOT1 +/* This test case tests send and receive of all DOT1 TLVs(2005 and 2009): + Port Valn ID, VLAN, Port Protocol VLAN ID, Protocol Identity, + VID Usage Digest, Management VID, and 802.1ax Link Aggregation TLVs */ +START_TEST(test_send_rcv_dot1_tlvs) +{ + int n; + struct lldpd_vlan *rvlan, vlan1, vlan2, vlan3; + struct lldpd_ppvid ppvid, *rppvid; + struct lldpd_pi pi1, pi2, *rpi; + struct lldpd_chassis *nchassis = NULL; + struct lldpd_port *nport = NULL; + struct packet *pkt; + + /* Populate port and chassis */ + hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_LLADDR; + hardware.h_lport.p_id = macaddress; + hardware.h_lport.p_id_len = ETHER_ADDR_LEN; + hardware.h_lport.p_descr = "Fake port description"; + hardware.h_lport.p_mfs = 1516; + hardware.h_lport.p_pvid = 1500; + chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LOCAL; + chassis.c_id = "Chassis name"; + chassis.c_id_len = strlen(chassis.c_id); + chassis.c_name = "Second chassis"; + chassis.c_descr = "Chassis description"; + chassis.c_cap_available = LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE; + chassis.c_cap_enabled = LLDP_CAP_ROUTER; + vlan1.v_name = "Voice"; + vlan1.v_vid = 157; + vlan2.v_name = "Data"; + vlan2.v_vid = 1247; + vlan3.v_name = "Control"; + vlan3.v_vid = 741; + TAILQ_INSERT_TAIL(&hardware.h_lport.p_vlans, &vlan1, v_entries); + TAILQ_INSERT_TAIL(&hardware.h_lport.p_vlans, &vlan2, v_entries); + TAILQ_INSERT_TAIL(&hardware.h_lport.p_vlans, &vlan3, v_entries); + ppvid.p_cap_status = 3; + ppvid.p_ppvid = 1500; + TAILQ_INSERT_TAIL(&hardware.h_lport.p_ppvids, &ppvid, p_entries); + pi1.p_pi = "IEEE Link Aggregration Control Protocol 802.3ad"; + pi1.p_pi_len = strlen(pi1.p_pi); + pi2.p_pi = "IEEE Link Layer Discovery Protocol 802.1ab-2005"; + pi2.p_pi_len = strlen(pi2.p_pi); + TAILQ_INSERT_TAIL(&hardware.h_lport.p_pids, &pi1, p_entries); + TAILQ_INSERT_TAIL(&hardware.h_lport.p_pids, &pi2, p_entries); + + /* Build packet */ + n = lldp_send(&test_lldpd, &hardware); + if (n != 0) { + fail("unable to build packet"); + return; + } + if (TAILQ_EMPTY(&pkts)) { + fail("no packets sent"); + return; + } + pkt = TAILQ_FIRST(&pkts); + fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent"); + + /* decode the retrieved packet calling lldp_decode() */ + fail_unless(lldp_decode(NULL, pkt->data, pkt->size, &hardware, &nchassis, + &nport) != -1); + if (!nchassis || !nport) { + fail("unable to decode packet"); + return; + } + + /* verify port values */ + check_received_port(&hardware.h_lport, nport); + /* verify chassis values */ + check_received_chassis(&chassis, nchassis); + + if (TAILQ_EMPTY(&nport->p_vlans)) { + fail("no VLAN"); + return; + } + + rvlan = TAILQ_FIRST(&nport->p_vlans); + ck_assert_int_eq(rvlan->v_vid, vlan1.v_vid); + ck_assert_str_eq(rvlan->v_name, vlan1.v_name); + + rvlan = TAILQ_NEXT(rvlan, v_entries); + if (!rvlan) { + fail("no more VLAN"); + return; + } + ck_assert_int_eq(rvlan->v_vid, vlan2.v_vid); + ck_assert_str_eq(rvlan->v_name, vlan2.v_name); + + rvlan = TAILQ_NEXT(rvlan, v_entries); + if (!rvlan) { + fail("no more VLAN"); + return; + } + ck_assert_int_eq(rvlan->v_vid, vlan3.v_vid); + ck_assert_str_eq(rvlan->v_name, vlan3.v_name); + + rvlan = TAILQ_NEXT(rvlan, v_entries); + fail_unless(rvlan == NULL); + + ck_assert_int_eq(nport->p_pvid, hardware.h_lport.p_pvid); + + if (TAILQ_EMPTY(&nport->p_ppvids)) { + fail("no Port Protocal VLAN ID"); + return; + } + rppvid = TAILQ_FIRST(&nport->p_ppvids); + ck_assert_int_eq(rppvid->p_cap_status, ppvid.p_cap_status); + ck_assert_int_eq(rppvid->p_ppvid, ppvid.p_ppvid); + + if (TAILQ_EMPTY(&nport->p_pids)) { + fail("no Protocal Identity TLV"); + return; + } + rpi = TAILQ_FIRST(&nport->p_pids); + ck_assert_int_eq(rpi->p_pi_len, pi1.p_pi_len); + ck_assert_str_eq_n(rpi->p_pi, pi1.p_pi, pi1.p_pi_len); + + rpi = TAILQ_NEXT(rpi, p_entries); + if (!rpi) { + fail("no more Protocol Identity TLVs"); + return; + } + ck_assert_int_eq(rpi->p_pi_len, pi2.p_pi_len); + ck_assert_str_eq_n(rpi->p_pi, pi2.p_pi, pi2.p_pi_len); + + rpi = TAILQ_NEXT(rpi, p_entries); + fail_unless(rpi == NULL); +} +END_TEST +#endif + +#ifdef ENABLE_LLDPMED +START_TEST(test_send_rcv_med) +{ + int n; + struct packet *pkt; + struct lldpd_chassis *nchassis = NULL; + struct lldpd_port *nport = NULL; + + /* Populate port and chassis */ + hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_LLADDR; + hardware.h_lport.p_id = macaddress; + hardware.h_lport.p_id_len = ETHER_ADDR_LEN; + hardware.h_lport.p_descr = "Fake port description"; + hardware.h_lport.p_mfs = 1516; + chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LOCAL; + chassis.c_id = "Chassis name"; + chassis.c_id_len = strlen(chassis.c_id); + chassis.c_name = "Third chassis"; + chassis.c_descr = "Chassis description"; + chassis.c_cap_available = LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE; + chassis.c_cap_enabled = LLDP_CAP_ROUTER; + chassis.c_med_cap_available = LLDP_MED_CAP_CAP | LLDP_MED_CAP_POLICY | + LLDP_MED_CAP_LOCATION | LLDP_MED_CAP_MDI_PSE | LLDP_MED_CAP_IV; + chassis.c_med_type = LLDP_MED_CLASS_III; + chassis.c_med_hw = "hardware rev 5"; + chassis.c_med_fw = "47b5"; + chassis.c_med_sw = "2.6.22b5"; + chassis.c_med_sn = "SN 47842"; + hardware.h_lport.p_med_cap_enabled = chassis.c_med_cap_available; + hardware.h_lport.p_med_location[LLDP_MED_LOCFORMAT_CIVIC - 1].format = + LLDP_MED_LOCFORMAT_CIVIC; + hardware.h_lport.p_med_location[LLDP_MED_LOCFORMAT_CIVIC - 1].data = + "Your favorite city"; + hardware.h_lport.p_med_location[LLDP_MED_LOCFORMAT_CIVIC - 1].data_len = + sizeof("Your favorite city"); + hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE - 1].type = + LLDP_MED_APPTYPE_SOFTPHONEVOICE; + hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE - 1].tagged = 1; + hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE - 1].vid = 51; + hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE - 1].priority = 6; + hardware.h_lport.p_med_policy[LLDP_MED_APPTYPE_SOFTPHONEVOICE - 1].dscp = 46; + hardware.h_lport.p_med_power.devicetype = LLDP_MED_POW_TYPE_PSE; + hardware.h_lport.p_med_power.source = LLDP_MED_POW_SOURCE_PRIMARY; + hardware.h_lport.p_med_power.priority = LLDP_MED_POW_PRIO_HIGH; + hardware.h_lport.p_med_power.val = 65; + + /* Build packet */ + n = lldp_send(&test_lldpd, &hardware); + if (n != 0) { + fail("unable to build packet"); + return; + } + if (TAILQ_EMPTY(&pkts)) { + fail("no packets sent"); + return; + } + pkt = TAILQ_FIRST(&pkts); + fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent"); + + /* decode the retrieved packet calling lldp_decode() */ + fail_unless(lldp_decode(NULL, pkt->data, pkt->size, &hardware, &nchassis, + &nport) != -1); + if (!nchassis || !nport) { + fail("unable to decode packet"); + return; + } + /* verify port values */ + check_received_port(&hardware.h_lport, nport); + /* verify chassis values */ + check_received_chassis(&chassis, nchassis); + + /* veridfy med content */ + check_received_port_med(&hardware.h_lport, nport); + check_received_chassis_med(&chassis, nchassis); +} +END_TEST +#endif + +#ifdef ENABLE_DOT3 +START_TEST(test_send_rcv_dot3) +{ + int n; + struct lldpd_chassis *nchassis = NULL; + struct lldpd_port *nport = NULL; + struct packet *pkt; + + /* Populate port and chassis */ + hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_IFNAME; + hardware.h_lport.p_id = "FastEthernet 1/5"; + hardware.h_lport.p_id_len = strlen(hardware.h_lport.p_id); + hardware.h_lport.p_descr = "Fake port description"; + hardware.h_lport.p_mfs = 1516; + hardware.h_lport.p_aggregid = 5; + hardware.h_lport.p_macphy.autoneg_support = 1; + hardware.h_lport.p_macphy.autoneg_enabled = 1; + hardware.h_lport.p_macphy.autoneg_advertised = LLDP_DOT3_LINK_AUTONEG_10BASE_T | + LLDP_DOT3_LINK_AUTONEG_10BASET_FD | LLDP_DOT3_LINK_AUTONEG_100BASE_TX | + LLDP_DOT3_LINK_AUTONEG_100BASE_TXFD; + hardware.h_lport.p_macphy.mau_type = LLDP_DOT3_MAU_100BASETXFD; + chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR; + chassis.c_id = macaddress; + chassis.c_id_len = ETHER_ADDR_LEN; + chassis.c_name = "Fourth chassis"; + chassis.c_descr = "Long chassis description"; + chassis.c_cap_available = chassis.c_cap_enabled = + LLDP_CAP_ROUTER | LLDP_CAP_WLAN; + + /* Build packet */ + n = lldp_send(&test_lldpd, &hardware); + if (n != 0) { + fail("unable to build packet"); + return; + } + if (TAILQ_EMPTY(&pkts)) { + fail("no packets sent"); + return; + } + pkt = TAILQ_FIRST(&pkts); + fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent"); + + /* decode the retrieved packet calling lldp_decode() */ + fail_unless(lldp_decode(NULL, pkt->data, pkt->size, &hardware, &nchassis, + &nport) != -1); + if (!nchassis || !nport) { + fail("unable to decode packet"); + return; + } + /* verify port values */ + check_received_port(&hardware.h_lport, nport); + /* verify chassis values */ + check_received_chassis(&chassis, nchassis); + /* verify dot3 values */ + check_received_port_dot3(&hardware.h_lport, nport); +} +END_TEST +#endif + +START_TEST(test_recv_min) +{ + char pkt1[] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, 0x00, 0x17, 0xd1, 0xa8, + 0x35, 0xbe, 0x88, 0xcc, 0x02, 0x07, 0x04, 0x00, 0x17, 0xd1, 0xa8, 0x35, + 0xbf, 0x04, 0x07, 0x03, 0x00, 0x17, 0xd1, 0xa8, 0x36, 0x02, 0x06, 0x02, + 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 }; + /* This is: +Ethernet II, Src: Nortel_a8:35:be (00:17:d1:a8:35:be), Dst: LLDP_Multicast +(01:80:c2:00:00:0e) Destination: LLDP_Multicast (01:80:c2:00:00:0e) Source: +Nortel_a8:35:be (00:17:d1:a8:35:be) Type: 802.1 Link Layer Discovery Protocol (LLDP) +(0x88cc) Link Layer Discovery Protocol Chassis Subtype = MAC address 0000 001. .... .... += TLV Type: Chassis Id (1) + .... ...0 0000 0111 = TLV Length: 7 + Chassis Id Subtype: MAC address (4) + Chassis Id: Nortel_a8:35:bf (00:17:d1:a8:35:bf) + Port Subtype = MAC address + 0000 010. .... .... = TLV Type: Port Id (2) + .... ...0 0000 0111 = TLV Length: 7 + Port Id Subtype: MAC address (3) + Port Id: Nortel_a8:36:02 (00:17:d1:a8:36:02) + Time To Live = 120 sec + 0000 011. .... .... = TLV Type: Time to Live (3) + .... ...0 0000 0010 = TLV Length: 2 + Seconds: 120 + End of LLDPDU + 0000 000. .... .... = TLV Type: End of LLDPDU (0) + .... ...0 0000 0000 = TLV Length: 0 + */ + struct lldpd_chassis *nchassis = NULL; + struct lldpd_port *nport = NULL; + char mac1[] = { 0x0, 0x17, 0xd1, 0xa8, 0x35, 0xbf }; + char mac2[] = { 0x0, 0x17, 0xd1, 0xa8, 0x36, 0x02 }; + + fail_unless( + lldp_decode(NULL, pkt1, sizeof(pkt1), &hardware, &nchassis, &nport) != -1); + if (!nchassis || !nport) { + fail("unable to decode packet"); + return; + } + ck_assert_int_eq(nchassis->c_id_subtype, LLDP_CHASSISID_SUBTYPE_LLADDR); + ck_assert_int_eq(nchassis->c_id_len, ETHER_ADDR_LEN); + fail_unless(memcmp(mac1, nchassis->c_id, ETHER_ADDR_LEN) == 0); + ck_assert_int_eq(nport->p_id_subtype, LLDP_PORTID_SUBTYPE_LLADDR); + ck_assert_int_eq(nport->p_id_len, ETHER_ADDR_LEN); + fail_unless(memcmp(mac2, nport->p_id, ETHER_ADDR_LEN) == 0); + ck_assert_ptr_eq(nchassis->c_name, NULL); + ck_assert_ptr_eq(nchassis->c_descr, NULL); + ck_assert_ptr_eq(nport->p_descr, NULL); + ck_assert_int_eq(nport->p_ttl, 120); +} +END_TEST + +START_TEST(test_recv_lldpd) +{ + /* This is a frame generated by lldpd */ + char pkt1[] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, 0x00, 0x16, 0x17, 0x2f, + 0xa1, 0xb6, 0x88, 0xcc, 0x02, 0x07, 0x04, 0x00, 0x16, 0x17, 0x2f, 0xa1, + 0xb6, 0x04, 0x07, 0x03, 0x00, 0x16, 0x17, 0x2f, 0xa1, 0xb6, 0x06, 0x02, + 0x00, 0x78, 0x0a, 0x1a, 0x6e, 0x61, 0x72, 0x75, 0x74, 0x6f, 0x2e, 0x58, + 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, + 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x0c, 0x3f, 0x4c, 0x69, 0x6e, 0x75, + 0x78, 0x20, 0x32, 0x2e, 0x36, 0x2e, 0x32, 0x39, 0x2d, 0x32, 0x2d, 0x61, + 0x6d, 0x64, 0x36, 0x34, 0x20, 0x23, 0x31, 0x20, 0x53, 0x4d, 0x50, 0x20, + 0x53, 0x75, 0x6e, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x31, 0x37, 0x20, 0x31, + 0x37, 0x3a, 0x31, 0x35, 0x3a, 0x34, 0x37, 0x20, 0x55, 0x54, 0x43, 0x20, + 0x32, 0x30, 0x30, 0x39, 0x20, 0x78, 0x38, 0x36, 0x5f, 0x36, 0x34, 0x0e, + 0x04, 0x00, 0x1c, 0x00, 0x14, 0x10, 0x0c, 0x05, 0x01, 0x0a, 0xee, 0x50, + 0x4b, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x04, 0x65, 0x74, 0x68, + 0x30, 0xfe, 0x09, 0x00, 0x12, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0x09, 0x00, 0x12, 0x0f, 0x01, 0x03, 0x6c, 0x03, 0x00, 0x10, 0xfe, + 0x06, 0x00, 0x12, 0x0f, 0x04, 0x05, 0xdc, 0xfe, 0x07, 0x00, 0x12, 0xbb, + 0x01, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x12, 0xbb, 0x05, 0x4e, 0x44, + 0x39, 0x39, 0x31, 0x37, 0x38, 0x39, 0x37, 0x30, 0x32, 0xfe, 0x0b, 0x00, + 0x12, 0xbb, 0x06, 0x30, 0x38, 0x30, 0x30, 0x31, 0x32, 0x20, 0xfe, 0x12, + 0x00, 0x12, 0xbb, 0x07, 0x32, 0x2e, 0x36, 0x2e, 0x32, 0x39, 0x2d, 0x32, + 0x2d, 0x61, 0x6d, 0x64, 0x36, 0x34, 0xfe, 0x10, 0x00, 0x12, 0xbb, 0x08, + 0x31, 0x30, 0x35, 0x38, 0x32, 0x30, 0x38, 0x35, 0x30, 0x30, 0x30, 0x39, + 0xfe, 0x15, 0x00, 0x12, 0xbb, 0x09, 0x4e, 0x45, 0x43, 0x20, 0x43, 0x6f, + 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x73, 0x20, 0x53, 0x41, 0x53, 0xfe, + 0x13, 0x00, 0x12, 0xbb, 0x0a, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x4d, 0x41, + 0x54, 0x45, 0x20, 0x56, 0x4c, 0x33, 0x35, 0x30, 0xfe, 0x0d, 0x00, 0x12, + 0xbb, 0x0b, 0x31, 0x30, 0x30, 0x32, 0x30, 0x37, 0x31, 0x32, 0x30, 0x00, + 0x00 }; + /* This is: +Ethernet II, Src: Msi_2f:a1:b6 (00:16:17:2f:a1:b6), Dst: LLDP_Multicast +(01:80:c2:00:00:0e) Destination: LLDP_Multicast (01:80:c2:00:00:0e) Source: Msi_2f:a1:b6 +(00:16:17:2f:a1:b6) Type: 802.1 Link Layer Discovery Protocol (LLDP) (0x88cc) Link Layer +Discovery Protocol Chassis Subtype = MAC address 0000 001. .... .... = TLV Type: Chassis +Id (1) + .... ...0 0000 0111 = TLV Length: 7 + Chassis Id Subtype: MAC address (4) + Chassis Id: Msi_2f:a1:b6 (00:16:17:2f:a1:b6) + Port Subtype = MAC address + 0000 010. .... .... = TLV Type: Port Id (2) + .... ...0 0000 0111 = TLV Length: 7 + Port Id Subtype: MAC address (3) + Port Id: Msi_2f:a1:b6 (00:16:17:2f:a1:b6) + Time To Live = 120 sec + 0000 011. .... .... = TLV Type: Time to Live (3) + .... ...0 0000 0010 = TLV Length: 2 + Seconds: 120 + System Name = naruto.XXXXXXXXXXXXXXXXXXX + 0000 101. .... .... = TLV Type: System Name (5) + .... ...0 0001 1010 = TLV Length: 26 + System Name = naruto.bureau.b1.p.fti.net + System Description = Linux 2.6.29-2-amd64 #1 SMP Sun May 17 17:15:47 UTC 2009 x86_64 + 0000 110. .... .... = TLV Type: System Description (6) + .... ...0 0011 1111 = TLV Length: 63 + System Description = Linux 2.6.29-2-amd64 #1 SMP Sun May 17 17:15:47 UTC 2009 +x86_64 Capabilities 0000 111. .... .... = TLV Type: System Capabilities (7) + .... ...0 0000 0100 = TLV Length: 4 + Capabilities: 0x001c + .... .... .... .1.. = Bridge + .... .... .... 1... = WLAN access point + .... .... ...1 .... = Router + Enabled Capabilities: 0x0014 + .... .... .... .1.. = Bridge + .... .... ...1 .... = Router + Management Address + 0001 000. .... .... = TLV Type: Management Address (8) + .... ...0 0000 1100 = TLV Length: 12 + Address String Length: 5 + Address Subtype: IPv4 (1) + Management Address: 10.238.80.75 + Interface Subtype: ifIndex (2) + Interface Number: 3 + OID String Length: 0 + Port Description = eth0 + 0000 100. .... .... = TLV Type: Port Description (4) + .... ...0 0000 0100 = TLV Length: 4 + Port Description: eth0 + IEEE 802.3 - Link Aggregation + 1111 111. .... .... = TLV Type: Organization Specific (127) + .... ...0 0000 1001 = TLV Length: 9 + Organization Unique Code: IEEE 802.3 (0x00120f) + IEEE 802.3 Subtype: Link Aggregation (0x03) + Aggregation Status: 0x01 + .... ...1 = Aggregation Capability: Yes + .... ..0. = Aggregation Status: Not Enabled + Aggregated Port Id: 0 + IEEE 802.3 - MAC/PHY Configuration/Status + 1111 111. .... .... = TLV Type: Organization Specific (127) + .... ...0 0000 1001 = TLV Length: 9 + Organization Unique Code: IEEE 802.3 (0x00120f) + IEEE 802.3 Subtype: MAC/PHY Configuration/Status (0x01) + Auto-Negotiation Support/Status: 0x03 + .... ...1 = Auto-Negotiation: Supported + .... ..1. = Auto-Negotiation: Enabled + PMD Auto-Negotiation Advertised Capability: 0x6C03 + .... .... .... ...1 = 1000BASE-T (full duplex mode) + .... .... .... ..1. = 1000BASE-T (half duplex mode) + .... .1.. .... .... = 100BASE-TX (full duplex mode) + .... 1... .... .... = 100BASE-TX (half duplex mode) + ..1. .... .... .... = 10BASE-T (full duplex mode) + .1.. .... .... .... = 10BASE-T (half duplex mode) + Operational MAU Type: 100BaseTXFD - 2 pair category 5 UTP, full duplex mode +(0x0010) IEEE 802.3 - Maximum Frame Size 1111 111. .... .... = TLV Type: Organization +Specific (127) + .... ...0 0000 0110 = TLV Length: 6 + Organization Unique Code: IEEE 802.3 (0x00120f) + IEEE 802.3 Subtype: Maximum Frame Size (0x04) + Maximum Frame Size: 1500 + TIA - Media Capabilities + 1111 111. .... .... = TLV Type: Organization Specific (127) + .... ...0 0000 0111 = TLV Length: 7 + Organization Unique Code: TIA (0x0012bb) + Media Subtype: Media Capabilities (0x01) + Capabilities: 0x0000 + Class Type: Type Not Defined + TIA - Inventory - Hardware Revision + 1111 111. .... .... = TLV Type: Organization Specific (127) + .... ...0 0000 1111 = TLV Length: 15 + Organization Unique Code: TIA (0x0012bb) + Media Subtype: Inventory - Hardware Revision (0x05) + Hardware Revision: ND991789702 + TIA - Inventory - Firmware Revision + 1111 111. .... .... = TLV Type: Organization Specific (127) + .... ...0 0000 1011 = TLV Length: 10 + Organization Unique Code: TIA (0x0012bb) + Media Subtype: Inventory - Firmware Revision (0x06) + Firmware Revision: 080012 + TIA - Inventory - Software Revision + 1111 111. .... .... = TLV Type: Organization Specific (127) + .... ...0 0001 0010 = TLV Length: 18 + Organization Unique Code: TIA (0x0012bb) + Media Subtype: Inventory - Software Revision (0x07) + Software Revision: 2.6.29-2-amd64 + TIA - Inventory - Serial Number + 1111 111. .... .... = TLV Type: Organization Specific (127) + .... ...0 0001 0000 = TLV Length: 16 + Organization Unique Code: TIA (0x0012bb) + Media Subtype: Inventory - Serial Number (0x08) + Serial Number: 105820850009 + TIA - Inventory - Manufacturer Name + 1111 111. .... .... = TLV Type: Organization Specific (127) + .... ...0 0001 0101 = TLV Length: 21 + Organization Unique Code: TIA (0x0012bb) + Media Subtype: Inventory - Manufacturer Name (0x09) + Manufacturer Name: NEC Computers SAS + TIA - Inventory - Model Name + 1111 111. .... .... = TLV Type: Organization Specific (127) + .... ...0 0001 0011 = TLV Length: 19 + Organization Unique Code: TIA (0x0012bb) + Media Subtype: Inventory - Model Name (0x0a) + Model Name: POWERMATE VL350 + TIA - Inventory - Asset ID + 1111 111. .... .... = TLV Type: Organization Specific (127) + .... ...0 0000 1101 = TLV Length: 13 + Organization Unique Code: TIA (0x0012bb) + Media Subtype: Inventory - Asset ID (0x0b) + Asset ID: 100207120 + End of LLDPDU + 0000 000. .... .... = TLV Type: End of LLDPDU (0) + .... ...0 0000 0000 = TLV Length: 0 + */ + struct lldpd_chassis *nchassis = NULL; + struct lldpd_port *nport = NULL; + char mac1[] = { 0x00, 0x16, 0x17, 0x2f, 0xa1, 0xb6 }; + + fail_unless( + lldp_decode(NULL, pkt1, sizeof(pkt1), &hardware, &nchassis, &nport) != -1); + if (!nchassis || !nport) { + fail("unable to decode packet"); + return; + } + ck_assert_int_eq(nchassis->c_id_subtype, LLDP_CHASSISID_SUBTYPE_LLADDR); + ck_assert_int_eq(nchassis->c_id_len, ETHER_ADDR_LEN); + fail_unless(memcmp(mac1, nchassis->c_id, ETHER_ADDR_LEN) == 0); + ck_assert_int_eq(nport->p_id_subtype, LLDP_PORTID_SUBTYPE_LLADDR); + ck_assert_int_eq(nport->p_id_len, ETHER_ADDR_LEN); + fail_unless(memcmp(mac1, nport->p_id, ETHER_ADDR_LEN) == 0); + ck_assert_int_eq(nport->p_ttl, 120); + ck_assert_str_eq(nchassis->c_name, "naruto.XXXXXXXXXXXXXXXXXXX"); + ck_assert_str_eq(nchassis->c_descr, + "Linux 2.6.29-2-amd64 #1 SMP Sun May 17 17:15:47 UTC 2009 x86_64"); + ck_assert_str_eq(nport->p_descr, "eth0"); + ck_assert_int_eq(nchassis->c_cap_available, + LLDP_CAP_WLAN | LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE); + ck_assert_int_eq(nchassis->c_cap_enabled, LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE); + ck_assert_int_eq(nchassis->c_mgmt.tqh_first->m_addr.inet.s_addr, + (u_int32_t)inet_addr("10.238.80.75")); + ck_assert_int_eq(nchassis->c_mgmt.tqh_first->m_iface, 3); +#ifdef ENABLE_DOT3 + ck_assert_int_eq(nport->p_aggregid, 0); + ck_assert_int_eq(nport->p_macphy.autoneg_enabled, 1); + ck_assert_int_eq(nport->p_macphy.autoneg_support, 1); + ck_assert_int_eq(nport->p_macphy.autoneg_advertised, + LLDP_DOT3_LINK_AUTONEG_1000BASE_TFD | LLDP_DOT3_LINK_AUTONEG_1000BASE_T | + LLDP_DOT3_LINK_AUTONEG_100BASE_TXFD | + LLDP_DOT3_LINK_AUTONEG_100BASE_TX | LLDP_DOT3_LINK_AUTONEG_10BASET_FD | + LLDP_DOT3_LINK_AUTONEG_10BASE_T); + ck_assert_int_eq(nport->p_macphy.mau_type, LLDP_DOT3_MAU_100BASETXFD); + ck_assert_int_eq(nport->p_mfs, 1500); +#endif +#ifdef ENABLE_LLDPMED + ck_assert_int_eq(nchassis->c_med_type, 0); + ck_assert_str_eq(nchassis->c_med_hw, "ND991789702"); + ck_assert_str_eq(nchassis->c_med_fw, "080012 "); /* Extra space */ + ck_assert_str_eq(nchassis->c_med_sw, "2.6.29-2-amd64"); + ck_assert_str_eq(nchassis->c_med_sn, "105820850009"); + ck_assert_str_eq(nchassis->c_med_manuf, "NEC Computers SAS"); + ck_assert_str_eq(nchassis->c_med_model, "POWERMATE VL350"); + ck_assert_str_eq(nchassis->c_med_asset, "100207120"); +#endif +} +END_TEST + +static Suite * +lldp_suite(void) +{ + Suite *s = suite_create("LLDP"); + TCase *tc_send = tcase_create("Send LLDP packets"); + TCase *tc_receive = tcase_create("Receive LLDP packets"); + + /* Send tests are first run without knowing the result. The + result is then checked with: + tshark -V -T text -r tests/lldp_send_0000.pcap + + If the result is correct, then, we get the packet as C + bytes using wireshark export to C arrays (tshark seems not + be able to do this). + */ + + tcase_add_checked_fixture(tc_send, pcap_setup, pcap_teardown); + tcase_add_test(tc_send, test_send_rcv_basic); + tcase_add_test(tc_send, test_send_rcv_vlan_tx); +#ifdef ENABLE_DOT1 + tcase_add_test(tc_send, test_send_rcv_dot1_tlvs); +#endif +#ifdef ENABLE_LLDPMED + tcase_add_test(tc_send, test_send_rcv_med); +#endif +#ifdef ENABLE_DOT3 + tcase_add_test(tc_send, test_send_rcv_dot3); +#endif + suite_add_tcase(s, tc_send); + + tcase_add_test(tc_receive, test_recv_min); + tcase_add_test(tc_receive, test_recv_lldpd); + suite_add_tcase(s, tc_receive); + + return s; +} + +int +main() +{ + int number_failed; + Suite *s = lldp_suite(); + SRunner *sr = srunner_create(s); + srunner_set_fork_status(sr, CK_NOFORK); /* Can't fork because + we need to write + files */ + srunner_run_all(sr, CK_ENV); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/tests/check_marshal.c b/tests/check_marshal.c new file mode 100644 index 0000000..ddb170e --- /dev/null +++ b/tests/check_marshal.c @@ -0,0 +1,925 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2015 Vincent Bernat <bernat@luffy.cx> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdlib.h> +#include <unistd.h> +#include <check.h> +#include <sys/queue.h> + +#define MARSHAL_EXPORT +#include "check-compat.h" +#include "../src/marshal.h" +#include "../src/log.h" + +/* This suite can be run in valgrind for memory leaks: + CK_FORK=no valgrind -v --leak-check=yes ./tests/check_marshal +*/ + +/* Use this callback to avoid some logs */ +static void donothing(int pri, const char *msg) {}; + +struct struct_simple { + int a1; + long a2; + char a3; + time_t a4; + char a5[7]; +}; +MARSHAL(struct_simple); + +START_TEST(test_simple_structure) +{ + struct struct_simple source = { + .a1 = 78452, + .a2 = 48751424, + .a3 = 'h', + .a4 = 784254, + .a5 = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' }, + }; + struct struct_simple *destination; + void *buffer; + size_t len, len2; + + len = struct_simple_serialize(&source, &buffer); + fail_unless(len > 0, "Unable to serialize"); + memset(&source, 0, sizeof(struct struct_simple)); + len2 = struct_simple_unserialize(buffer, len, &destination); + fail_unless(len2 > 0, "Unable to deserialize"); + free(buffer); + ck_assert_int_eq(len, len2); + ck_assert_int_eq(destination->a1, 78452); + ck_assert_int_eq(destination->a2, 48751424); + ck_assert_int_eq(destination->a3, 'h'); + ck_assert_int_eq(destination->a4, 784254); + ck_assert_int_eq(destination->a5[0], 'A'); + ck_assert_int_eq(destination->a5[1], 'B'); + ck_assert_int_eq(destination->a5[2], 'C'); + ck_assert_int_eq(destination->a5[3], 'D'); + ck_assert_int_eq(destination->a5[4], 'E'); + ck_assert_int_eq(destination->a5[5], 'F'); + ck_assert_int_eq(destination->a5[6], 'G'); + free(destination); +} +END_TEST + +struct struct_sub { + int e1; + struct struct_simple e2; + char e3; +}; +MARSHAL_BEGIN(struct_sub) +MARSHAL_SUBSTRUCT(struct_sub, struct_simple, e2) +MARSHAL_END(struct_sub); + +START_TEST(test_substruct_structure) +{ + struct struct_sub source = { + .e1 = -5122, + .e2 = { + .a1 = 78452, + .a2 = 48751424, + .a3 = 'h', + .a4 = 784254, + .a5 = { 'A', 'B', 'C', 'D', 'E', 'F', 'G'}, + }, + .e3 = 'a', + }; + + struct struct_sub *destination; + void *buffer; + size_t len, len2; + + len = struct_sub_serialize(&source, &buffer); + fail_unless(len > 0, "Unable to serialize"); + memset(&source, 0, sizeof(struct struct_sub)); + len2 = struct_sub_unserialize(buffer, len, &destination); + fail_unless(len2 > 0, "Unable to deserialize"); + free(buffer); + ck_assert_int_eq(len, len2); + ck_assert_int_eq(destination->e1, -5122); + ck_assert_int_eq(destination->e2.a1, 78452); + ck_assert_int_eq(destination->e2.a2, 48751424); + ck_assert_int_eq(destination->e2.a3, 'h'); + ck_assert_int_eq(destination->e2.a4, 784254); + ck_assert_int_eq(destination->e2.a5[0], 'A'); + ck_assert_int_eq(destination->e2.a5[1], 'B'); + ck_assert_int_eq(destination->e2.a5[2], 'C'); + ck_assert_int_eq(destination->e2.a5[3], 'D'); + ck_assert_int_eq(destination->e2.a5[4], 'E'); + ck_assert_int_eq(destination->e2.a5[5], 'F'); + ck_assert_int_eq(destination->e2.a5[6], 'G'); + ck_assert_int_eq(destination->e3, 'a'); + free(destination); +} +END_TEST + +struct struct_onepointer { + int b1; + long b2; + char b3; + struct struct_simple *b4; + int b5; +}; +MARSHAL_BEGIN(struct_onepointer) +MARSHAL_POINTER(struct_onepointer, struct_simple, b4) +MARSHAL_END(struct_onepointer); + +START_TEST(test_pointer_structure) +{ + struct struct_simple source_simple = { + .a1 = 78452, + .a2 = 48751424, + .a3 = 'h', + .a4 = 784254, + .a5 = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' }, + }; + struct struct_onepointer source = { + .b1 = 18, + .b2 = 15454, + .b3 = 'o', + .b4 = &source_simple, + .b5 = 333333, + }; + + struct struct_onepointer *destination; + void *buffer; + size_t len, len2; + + len = struct_onepointer_serialize(&source, &buffer); + fail_unless(len > 0, "Unable to serialize"); + memset(&source_simple, 0, sizeof(struct struct_simple)); + memset(&source, 0, sizeof(struct struct_onepointer)); + len2 = struct_onepointer_unserialize(buffer, len, &destination); + fail_unless(len2 > 0, "Unable to deserialize"); + free(buffer); + ck_assert_int_eq(len, len2); + ck_assert_int_eq(destination->b1, 18); + ck_assert_int_eq(destination->b2, 15454); + ck_assert_int_eq(destination->b3, 'o'); + ck_assert_int_eq(destination->b4->a1, 78452); + ck_assert_int_eq(destination->b4->a2, 48751424); + ck_assert_int_eq(destination->b4->a3, 'h'); + ck_assert_int_eq(destination->b4->a4, 784254); + ck_assert_int_eq(destination->b4->a5[0], 'A'); + ck_assert_int_eq(destination->b4->a5[1], 'B'); + ck_assert_int_eq(destination->b4->a5[2], 'C'); + ck_assert_int_eq(destination->b4->a5[3], 'D'); + ck_assert_int_eq(destination->b4->a5[4], 'E'); + ck_assert_int_eq(destination->b4->a5[5], 'F'); + ck_assert_int_eq(destination->b4->a5[6], 'G'); + ck_assert_int_eq(destination->b5, 333333); + free(destination->b4); + free(destination); +} +END_TEST + +struct struct_nestedpointers { + int c1; + long c2; + struct struct_simple *c3; + struct struct_onepointer *c4; + int c5; +}; +MARSHAL_BEGIN(struct_nestedpointers) +MARSHAL_POINTER(struct_nestedpointers, struct_simple, c3) +MARSHAL_POINTER(struct_nestedpointers, struct_onepointer, c4) +MARSHAL_END(struct_nestedpointers); + +START_TEST(test_several_pointers_structure) +{ + struct struct_simple source_simple1 = { + .a1 = 78452, + .a2 = 48751424, + .a3 = 'h', + .a4 = 784254, + .a5 = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' }, + }; + struct struct_simple source_simple2 = { + .a1 = 451, + .a2 = 451424, + .a3 = 'o', + .a4 = 74, + .a5 = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }, + }; + struct struct_onepointer source_onepointer = { + .b1 = 18, + .b2 = 15454, + .b3 = 'o', + .b4 = &source_simple1, + .b5 = 333333, + }; + struct struct_nestedpointers source = { + .c1 = 4542, + .c2 = 5665454, + .c3 = &source_simple2, + .c4 = &source_onepointer, + .c5 = -545424, + }; + + struct struct_nestedpointers *destination; + void *buffer; + size_t len, len2; + + len = struct_nestedpointers_serialize(&source, &buffer); + fail_unless(len > 0, "Unable to serialize"); + memset(&source_simple1, 0, sizeof(struct struct_simple)); + memset(&source_simple2, 0, sizeof(struct struct_simple)); + memset(&source_onepointer, 0, sizeof(struct struct_onepointer)); + memset(&source, 0, sizeof(struct struct_nestedpointers)); + len2 = struct_nestedpointers_unserialize(buffer, len, &destination); + fail_unless(len2 > 0, "Unable to deserialize"); + free(buffer); + ck_assert_int_eq(len, len2); + ck_assert_int_eq(destination->c1, 4542); + ck_assert_int_eq(destination->c2, 5665454); + ck_assert_int_eq(destination->c3->a1, 451); + ck_assert_int_eq(destination->c3->a2, 451424); + ck_assert_int_eq(destination->c3->a3, 'o'); + ck_assert_int_eq(destination->c3->a4, 74); + ck_assert_int_eq(destination->c3->a5[3], 'd'); + ck_assert_int_eq(destination->c3->a5[4], 'e'); + ck_assert_int_eq(destination->c3->a5[6], 'g'); + ck_assert_int_eq(destination->c4->b1, 18); + ck_assert_int_eq(destination->c4->b2, 15454); + ck_assert_int_eq(destination->c4->b3, 'o'); + ck_assert_int_eq(destination->c4->b4->a1, 78452); + ck_assert_int_eq(destination->c4->b4->a2, 48751424); + ck_assert_int_eq(destination->c4->b4->a3, 'h'); + ck_assert_int_eq(destination->c4->b4->a4, 784254); + ck_assert_int_eq(destination->c4->b4->a5[0], 'A'); + ck_assert_int_eq(destination->c4->b4->a5[1], 'B'); + ck_assert_int_eq(destination->c4->b4->a5[2], 'C'); + ck_assert_int_eq(destination->c4->b4->a5[3], 'D'); + ck_assert_int_eq(destination->c4->b4->a5[4], 'E'); + ck_assert_int_eq(destination->c4->b4->a5[5], 'F'); + ck_assert_int_eq(destination->c4->b4->a5[6], 'G'); + ck_assert_int_eq(destination->c4->b5, 333333); + free(destination->c3); + free(destination->c4->b4); + free(destination->c4); + free(destination); +} +END_TEST + +START_TEST(test_null_pointers) +{ + struct struct_simple source_simple2 = { + .a1 = 451, + .a2 = 451424, + .a3 = 'o', + .a4 = 74, + .a5 = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }, + }; + struct struct_nestedpointers source = { + .c1 = 4542, + .c2 = 5665454, + .c3 = &source_simple2, + .c4 = NULL, + .c5 = -545424, + }; + + struct struct_nestedpointers *destination; + void *buffer; + size_t len, len2; + + len = struct_nestedpointers_serialize(&source, &buffer); + fail_unless(len > 0, "Unable to serialize"); + memset(&source_simple2, 0, sizeof(struct struct_simple)); + memset(&source, 0, sizeof(struct struct_nestedpointers)); + len2 = struct_nestedpointers_unserialize(buffer, len, &destination); + fail_unless(len2 > 0, "Unable to deserialize"); + free(buffer); + ck_assert_int_eq(len, len2); + ck_assert_int_eq(destination->c1, 4542); + ck_assert_int_eq(destination->c2, 5665454); + ck_assert_int_eq(destination->c3->a1, 451); + ck_assert_int_eq(destination->c3->a2, 451424); + ck_assert_int_eq(destination->c3->a3, 'o'); + ck_assert_int_eq(destination->c3->a4, 74); + ck_assert_int_eq(destination->c3->a5[3], 'd'); + ck_assert_int_eq(destination->c3->a5[4], 'e'); + ck_assert_int_eq(destination->c3->a5[6], 'g'); + ck_assert_ptr_eq(destination->c4, NULL); + free(destination->c3); + free(destination); +} +END_TEST + +struct struct_multipleref { + int f1; + struct struct_simple *f2; + struct struct_simple *f3; + struct struct_nestedpointers *f4; +}; +MARSHAL_BEGIN(struct_multipleref) +MARSHAL_POINTER(struct_multipleref, struct_simple, f2) +MARSHAL_POINTER(struct_multipleref, struct_simple, f3) +MARSHAL_POINTER(struct_multipleref, struct_nestedpointers, f4) +MARSHAL_END(struct_multipleref); + +START_TEST(test_multiple_references) +{ + struct struct_simple source_simple = { + .a1 = 451, + .a2 = 451424, + .a3 = 'o', + .a4 = 74, + .a5 = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }, + }; + struct struct_nestedpointers source_nested = { + .c3 = &source_simple, + .c4 = NULL, + }; + struct struct_multipleref source = { + .f1 = 15, + .f2 = &source_simple, + .f3 = &source_simple, + .f4 = &source_nested, + }; + + struct struct_multipleref *destination; + void *buffer = NULL; + size_t len, len2; + + len = struct_multipleref_serialize(&source, &buffer); + fail_unless(buffer != NULL, "Buffer is empty"); + fail_unless(len > 0, "Unable to serialize"); + memset(&source_simple, 0, sizeof(struct struct_simple)); + memset(&source_nested, 0, sizeof(struct struct_nestedpointers)); + memset(&source, 0, sizeof(struct struct_multipleref)); + len2 = struct_multipleref_unserialize(buffer, len, &destination); + fail_unless(len2 > 0, "Unable to deserialize"); + free(buffer); + ck_assert_int_eq(len, len2); + ck_assert_int_eq(destination->f1, 15); + ck_assert_ptr_eq(destination->f2, destination->f3); + ck_assert_ptr_eq(destination->f2, destination->f4->c3); + ck_assert_int_eq(destination->f2->a1, 451); + ck_assert_int_eq(destination->f2->a2, 451424); + ck_assert_int_eq(destination->f2->a3, 'o'); + ck_assert_int_eq(destination->f2->a4, 74); + ck_assert_ptr_eq(destination->f4->c4, NULL); + free(destination->f2); + free(destination->f4); + free(destination); +} +END_TEST + +struct struct_circularref { + int g1; + struct struct_circularref *g2; +}; +MARSHAL_BEGIN(struct_circularref) +MARSHAL_POINTER(struct_circularref, struct_circularref, g2) +MARSHAL_END(struct_circularref); + +START_TEST(test_circular_references) +{ + struct struct_circularref source = { + .g1 = 42, + .g2 = &source, + }; + + struct struct_circularref *destination; + void *buffer = NULL; + size_t len, len2; + + len = struct_circularref_serialize(&source, &buffer); + fail_unless(len > 0, "Unable to serialize"); + memset(&source, 0, sizeof(struct struct_circularref)); + len2 = struct_circularref_unserialize(buffer, len, &destination); + fail_unless(len2 > 0, "Unable to deserialize"); + free(buffer); + ck_assert_int_eq(len, len2); + ck_assert_int_eq(destination->g1, 42); + ck_assert_int_eq(destination->g2->g1, 42); + ck_assert_ptr_eq(destination->g2, destination->g2->g2); + free(destination); +} +END_TEST + +START_TEST(test_too_small_unmarshal) +{ + struct struct_simple source_simple1; + struct struct_onepointer source_onepointer = { + .b4 = &source_simple1, + }; + struct struct_nestedpointers source = { + .c3 = &source_simple1, + .c4 = &source_onepointer, + }; + + struct struct_nestedpointers *destination; + void *buffer; + size_t len, len2; + size_t i, j; + + log_register(donothing); + + len = struct_nestedpointers_serialize(&source, &buffer); + fail_unless(len > 0, "Unable to serialize"); + memset(&source_simple1, 0, sizeof(struct struct_simple)); + memset(&source_onepointer, 0, sizeof(struct struct_onepointer)); + memset(&source, 0, sizeof(struct struct_nestedpointers)); + /* Loop 30 times to ease debugging leaks with valgrind */ + for (j = 0; j < 30; j++) { + for (i = 0; i < len; i++) { + len2 = + struct_nestedpointers_unserialize(buffer, 1, &destination); + fail_unless(len2 == 0, + "Should not be able to deserialize, too small (%zu<%zu)", i, + len); + } + } + len2 = struct_nestedpointers_unserialize(buffer, len + 5, &destination); + fail_unless(len2 == len, "Deserialized too much"); + free(destination->c3); + free(destination->c4); + free(destination); + free(buffer); + + log_register(NULL); +} +END_TEST + +struct struct_simpleentry { + TAILQ_ENTRY(struct_simpleentry) s_entries; + int g1; + struct struct_simple *g2; +}; +MARSHAL_BEGIN(struct_simpleentry) +MARSHAL_TQE(struct_simpleentry, s_entries) +MARSHAL_POINTER(struct_simpleentry, struct_simple, g2) +MARSHAL_END(struct_simpleentry); + +TAILQ_HEAD(list_simple, struct_simpleentry); +MARSHAL_TQ(list_simple, struct_simpleentry); + +START_TEST(test_simple_list) +{ + struct struct_simple source_simple = { + .a1 = 451, + .a2 = 451424, + .a3 = 'o', + .a4 = 74, + .a5 = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }, + }; + struct list_simple source; + struct struct_simpleentry entry1 = { + .g1 = 47, + .g2 = &source_simple, + }; + struct struct_simpleentry entry2 = { + .g1 = 49, + .g2 = &source_simple, + }; + struct struct_simpleentry entry3 = { + .g1 = 4700, + .g2 = NULL, + }; + struct struct_simpleentry entry4 = { + .g1 = -47, + .g2 = &source_simple, + }; + struct list_simple *destination; + void *buffer; + size_t len, len2; + struct struct_simpleentry *e1, *e2; + struct struct_simple *s; + + TAILQ_INIT(&source); + TAILQ_INSERT_TAIL(&source, &entry1, s_entries); + TAILQ_INSERT_TAIL(&source, &entry2, s_entries); + TAILQ_INSERT_TAIL(&source, &entry3, s_entries); + TAILQ_INSERT_TAIL(&source, &entry4, s_entries); + + len = list_simple_serialize(&source, &buffer); + fail_unless(len > 0, "Unable to serialize"); + memset(&source, 0, sizeof(struct list_simple)); + memset(&entry1, 0, sizeof(struct struct_simpleentry)); + memset(&entry2, 0, sizeof(struct struct_simpleentry)); + memset(&entry3, 0, sizeof(struct struct_simpleentry)); + memset(&entry4, 0, sizeof(struct struct_simpleentry)); + len2 = list_simple_unserialize(buffer, len, &destination); + fail_unless(len2 > 0, "Unable to deserialize"); + free(buffer); + + e1 = TAILQ_FIRST(destination); + ck_assert_int_eq(e1->g1, 47); + s = e1->g2; + e2 = TAILQ_NEXT(e1, s_entries); + free(e1); + ck_assert_int_eq(e2->g1, 49); + ck_assert_ptr_eq(e2->g2, s); + e1 = TAILQ_NEXT(e2, s_entries); + free(e2); + ck_assert_int_eq(e1->g1, 4700); + ck_assert_ptr_eq(e1->g2, NULL); + e2 = TAILQ_NEXT(e1, s_entries); + free(e1); + ck_assert_int_eq(e2->g1, -47); + ck_assert_ptr_eq(e2->g2, s); + e1 = TAILQ_NEXT(e2, s_entries); + free(e2); + ck_assert_ptr_eq(e1, NULL); + free(s); + free(destination); +} +END_TEST + +START_TEST(test_simple_repaired_list) +{ + struct struct_simple source_simple = { + .a1 = 451, + .a2 = 451424, + .a3 = 'o', + .a4 = 74, + .a5 = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }, + }; + struct list_simple source; + struct struct_simpleentry entry1 = { + .g1 = 47, + .g2 = &source_simple, + }; + struct struct_simpleentry entry2 = { + .g1 = 49, + .g2 = &source_simple, + }; + struct struct_simpleentry entry3 = { + .g1 = 4700, + .g2 = NULL, + }; + struct struct_simpleentry entry4 = { + .g1 = -47, + .g2 = &source_simple, + }; + struct struct_simpleentry entry5 = { + .g1 = -1000, + .g2 = NULL, + }; + struct list_simple *destination; + void *buffer; + size_t len, len2; + struct struct_simpleentry *e1, *e2, *e3, *e4; + + TAILQ_INIT(&source); + TAILQ_INSERT_TAIL(&source, &entry1, s_entries); + TAILQ_INSERT_TAIL(&source, &entry2, s_entries); + TAILQ_INSERT_TAIL(&source, &entry3, s_entries); + TAILQ_INSERT_TAIL(&source, &entry4, s_entries); + + len = list_simple_serialize(&source, &buffer); + fail_unless(len > 0, "Unable to serialize"); + memset(&source, 0, sizeof(struct list_simple)); + memset(&entry1, 0, sizeof(struct struct_simpleentry)); + memset(&entry2, 0, sizeof(struct struct_simpleentry)); + memset(&entry3, 0, sizeof(struct struct_simpleentry)); + memset(&entry4, 0, sizeof(struct struct_simpleentry)); + len2 = list_simple_unserialize(buffer, len, &destination); + fail_unless(len2 > 0, "Unable to deserialize"); + free(buffer); + + marshal_repair_tailq(struct_simpleentry, destination, s_entries); + + e1 = TAILQ_FIRST(destination); + ck_assert_int_eq(e1->g1, 47); + e4 = TAILQ_LAST(destination, list_simple); + ck_assert_int_eq(e4->g1, -47); + e3 = TAILQ_PREV(e4, list_simple, s_entries); + ck_assert_int_eq(e3->g1, 4700); + e2 = TAILQ_PREV(e3, list_simple, s_entries); + ck_assert_int_eq(e2->g1, 49); + + TAILQ_INSERT_TAIL(destination, &entry5, s_entries); + free(e1->g2); + free(e1); + free(e2); + free(e3); + free(e4); + free(destination); +} +END_TEST + +START_TEST(test_empty_repaired_list) +{ + struct list_simple source; + size_t len, len2; + struct list_simple *destination; + void *buffer; + struct struct_simpleentry *e1; + struct struct_simpleentry entry5 = { + .g1 = -1000, + .g2 = NULL, + }; + TAILQ_INIT(&source); + + len = list_simple_serialize(&source, &buffer); + fail_unless(len > 0, "Unable to serialize"); + memset(&source, 0, sizeof(struct list_simple)); + len2 = list_simple_unserialize(buffer, len, &destination); + fail_unless(len2 > 0, "Unable to deserialize"); + free(buffer); + + marshal_repair_tailq(struct_simpleentry, destination, s_entries); + + e1 = TAILQ_FIRST(destination); + ck_assert_ptr_eq(e1, NULL); + e1 = TAILQ_LAST(destination, list_simple); + ck_assert_ptr_eq(e1, NULL); + + TAILQ_INSERT_TAIL(destination, &entry5, s_entries); + + free(destination); +} +END_TEST + +struct struct_withlist { + int i1; + TAILQ_HEAD(, struct_simpleentry) i2; + int i3; +}; +MARSHAL_BEGIN(struct_withlist) +MARSHAL_SUBTQ(struct_withlist, struct_simpleentry, i2) +MARSHAL_END(struct_withlist); + +START_TEST(test_embedded_list) +{ + struct struct_withlist source = { + .i1 = 45424, + .i3 = 4542, + }; + struct struct_simple source_simple = { + .a1 = 451, + .a2 = 451424, + .a3 = 'o', + .a4 = 74, + .a5 = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }, + }; + struct struct_simpleentry entry1 = { + .g1 = 47, + .g2 = &source_simple, + }; + struct struct_simpleentry entry2 = { + .g1 = 49, + .g2 = &source_simple, + }; + struct struct_simpleentry entry3 = { + .g1 = 4700, + .g2 = NULL, + }; + struct struct_simpleentry entry4 = { + .g1 = -47, + .g2 = &source_simple, + }; + struct struct_withlist *destination; + void *buffer; + size_t len, len2; + struct struct_simpleentry *e1, *e2; + struct struct_simple *s; + + TAILQ_INIT(&source.i2); + TAILQ_INSERT_TAIL(&source.i2, &entry1, s_entries); + TAILQ_INSERT_TAIL(&source.i2, &entry2, s_entries); + TAILQ_INSERT_TAIL(&source.i2, &entry3, s_entries); + TAILQ_INSERT_TAIL(&source.i2, &entry4, s_entries); + + len = struct_withlist_serialize(&source, &buffer); + fail_unless(len > 0, "Unable to serialize"); + memset(&source, 0, sizeof(struct list_simple)); + memset(&entry1, 0, sizeof(struct struct_simpleentry)); + memset(&entry2, 0, sizeof(struct struct_simpleentry)); + memset(&entry3, 0, sizeof(struct struct_simpleentry)); + memset(&entry4, 0, sizeof(struct struct_simpleentry)); + len2 = struct_withlist_unserialize(buffer, len, &destination); + fail_unless(len2 > 0, "Unable to deserialize"); + free(buffer); + + ck_assert_int_eq(destination->i1, 45424); + ck_assert_int_eq(destination->i3, 4542); + e1 = TAILQ_FIRST(&destination->i2); + ck_assert_int_eq(e1->g1, 47); + ck_assert_int_eq(e1->g2->a4, 74); + s = e1->g2; + e2 = TAILQ_NEXT(e1, s_entries); + free(e1); + ck_assert_int_eq(e2->g1, 49); + ck_assert_ptr_eq(e2->g2, s); + e1 = TAILQ_NEXT(e2, s_entries); + free(e2); + ck_assert_int_eq(e1->g1, 4700); + ck_assert_ptr_eq(e1->g2, NULL); + e2 = TAILQ_NEXT(e1, s_entries); + free(e1); + ck_assert_int_eq(e2->g1, -47); + ck_assert_ptr_eq(e2->g2, s); + e1 = TAILQ_NEXT(e2, s_entries); + free(e2); + ck_assert_ptr_eq(e1, NULL); + free(s); + free(destination); +} +END_TEST + +struct struct_string { + int s1; + char *s2; + char *s3; +}; +MARSHAL_BEGIN(struct_string) +MARSHAL_STR(struct_string, s2) +MARSHAL_STR(struct_string, s3) +MARSHAL_END(struct_string); + +START_TEST(test_string) +{ + struct struct_string source = { + .s1 = 44444, + .s2 = "String 2", + .s3 = "String 3", + }; + struct struct_string *destination; + void *buffer; + size_t len, len2; + + len = struct_string_serialize(&source, &buffer); + fail_unless(len > 0, "Unable to serialize"); + memset(&source, 0, sizeof(struct struct_string)); + len2 = struct_string_unserialize(buffer, len, &destination); + fail_unless(len2 > 0, "Unable to deserialize"); + free(buffer); + ck_assert_int_eq(len, len2); + ck_assert_int_eq(destination->s1, 44444); + ck_assert_str_eq(destination->s2, "String 2"); + ck_assert_str_eq(destination->s3, "String 3"); + free(destination->s2); + free(destination->s3); + free(destination); +} +END_TEST + +struct struct_fixedstring { + int s1; + char *s2; + int s2_len; + char *s3; +}; +MARSHAL_BEGIN(struct_fixedstring) +MARSHAL_FSTR(struct_fixedstring, s2, s2_len) +MARSHAL_STR(struct_fixedstring, s3) +MARSHAL_END(struct_fixedstring); + +START_TEST(test_fixed_string) +{ + struct struct_fixedstring source = { + .s1 = 44444, + .s2 = "String 2 Bla", + .s2_len = 8, /* Not 12! */ + .s3 = "String 3", + }; + struct struct_fixedstring *destination; + void *buffer; + size_t len, len2; + + len = struct_fixedstring_serialize(&source, &buffer); + fail_unless(len > 0, "Unable to serialize"); + memset(&source, 0, sizeof(struct struct_fixedstring)); + len2 = struct_fixedstring_unserialize(buffer, len, &destination); + fail_unless(len2 > 0, "Unable to deserialize"); + free(buffer); + ck_assert_int_eq(len, len2); + ck_assert_int_eq(destination->s1, 44444); + ck_assert_int_eq(destination->s2_len, 8); + ck_assert_int_eq(destination->s2[0], 'S'); + ck_assert_int_eq(destination->s2[2], 'r'); + ck_assert_int_eq(destination->s2[4], 'n'); + ck_assert_int_eq(destination->s2[5], 'g'); + ck_assert_int_eq(destination->s2[6], ' '); + ck_assert_int_eq(destination->s2[7], '2'); + ck_assert_int_eq(destination->s2[8], + '\0'); /* fixed string are null-terminated too */ + ck_assert_str_eq(destination->s3, "String 3"); + free(destination->s2); + free(destination->s3); + free(destination); +} +END_TEST + +struct struct_ignore { + int t1; + void *t2; + int t3; +}; +MARSHAL_BEGIN(struct_ignore) +MARSHAL_IGNORE(struct_ignore, t2) +MARSHAL_END(struct_ignore); + +START_TEST(test_ignore) +{ + struct struct_ignore source = { + .t1 = 4544, + .t2 = (void *)"String 2 Bla", + .t3 = 11111, + }; + struct struct_ignore *destination; + void *buffer; + size_t len, len2; + + len = struct_ignore_serialize(&source, &buffer); + fail_unless(len > 0, "Unable to serialize"); + memset(&source, 0, sizeof(struct struct_ignore)); + len2 = struct_ignore_unserialize(buffer, len, &destination); + fail_unless(len2 > 0, "Unable to deserialize"); + free(buffer); + ck_assert_int_eq(len, len2); + ck_assert_int_eq(destination->t1, 4544); + ck_assert_ptr_eq(destination->t2, NULL); + ck_assert_int_eq(destination->t3, 11111); + free(destination); +} +END_TEST + +START_TEST(test_equality) +{ + struct struct_simple source_simple1 = { + .a1 = 451, + .a2 = 451424, + .a3 = 'o', + .a4 = 74, + .a5 = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }, + }; + struct struct_simpleentry entry1 = { + .g1 = 47, + .g2 = &source_simple1, + }; + + struct struct_simple source_simple2; + struct struct_simpleentry entry2; + + void *buffer1, *buffer2; + memcpy(&source_simple2, &source_simple1, sizeof(source_simple1)); + memcpy(&entry2, &entry1, sizeof(entry1)); + entry2.g2 = &source_simple2; + ssize_t len1 = struct_simpleentry_serialize(&entry1, &buffer1); + ssize_t len2 = struct_simpleentry_serialize(&entry2, &buffer2); + fail_unless(len1 > 0, "Unable to serialize"); + fail_unless(len2 > 0, "Unable to serialize"); + ck_assert_int_eq(len1, len2); + fail_unless(!memcmp(buffer1, buffer2, len1), + "Same content should give the same serialization"); + free(buffer1); + free(buffer2); +} +END_TEST + +static Suite * +marshal_suite(void) +{ + Suite *s = suite_create("Marshalling"); + + TCase *tc_marshal = tcase_create("Marshalling"); + tcase_add_test(tc_marshal, test_simple_structure); + tcase_add_test(tc_marshal, test_substruct_structure); + tcase_add_test(tc_marshal, test_pointer_structure); + tcase_add_test(tc_marshal, test_several_pointers_structure); + tcase_add_test(tc_marshal, test_null_pointers); + tcase_add_test(tc_marshal, test_multiple_references); + tcase_add_test(tc_marshal, test_circular_references); + tcase_add_test(tc_marshal, test_too_small_unmarshal); + tcase_add_test(tc_marshal, test_simple_list); + tcase_add_test(tc_marshal, test_simple_repaired_list); + tcase_add_test(tc_marshal, test_empty_repaired_list); + tcase_add_test(tc_marshal, test_embedded_list); + tcase_add_test(tc_marshal, test_string); + tcase_add_test(tc_marshal, test_fixed_string); + tcase_add_test(tc_marshal, test_ignore); + tcase_add_test(tc_marshal, test_equality); + suite_add_tcase(s, tc_marshal); + + return s; +} + +int +main() +{ + int number_failed; + Suite *s = marshal_suite(); + SRunner *sr = srunner_create(s); + srunner_run_all(sr, CK_ENV); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/tests/check_pattern.c b/tests/check_pattern.c new file mode 100644 index 0000000..b2504be --- /dev/null +++ b/tests/check_pattern.c @@ -0,0 +1,148 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2014 Vincent Bernat <bernat@luffy.cx> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <check.h> + +#include "../src/daemon/lldpd.h" + +START_TEST(test_empty) +{ + ck_assert_int_eq(pattern_match("eth0", "", 0), 0); + ck_assert_int_eq(pattern_match("eth0", "", 1), 1); +} +END_TEST + +START_TEST(test_simple_match) +{ + ck_assert_int_eq(pattern_match("eth0", "eth0", 0), 2); + ck_assert_int_eq(pattern_match("eth0", "eth0", 1), 2); + ck_assert_int_eq(pattern_match("eth0", "eth1", 0), 0); + ck_assert_int_eq(pattern_match("eth0", "eth1", 1), 1); +} +END_TEST + +START_TEST(test_wildcard) +{ + ck_assert_int_eq(pattern_match("eth0", "eth*", 0), 1); + ck_assert_int_eq(pattern_match("eth0", "eth*", 1), 1); + ck_assert_int_eq(pattern_match("vlan0", "eth*", 0), 0); + ck_assert_int_eq(pattern_match("vlan0", "eth*", 1), 1); +} +END_TEST + +START_TEST(test_match_list) +{ + ck_assert_int_eq(pattern_match("eth0", "eth0,eth1,eth2", 0), 2); + ck_assert_int_eq(pattern_match("eth1", "eth0,eth1,eth2", 0), 2); + ck_assert_int_eq(pattern_match("eth3", "eth0,eth1,eth2", 0), 0); + ck_assert_int_eq(pattern_match("eth3", "eth0,eth1,eth2", 1), 1); +} +END_TEST + +START_TEST(test_match_list_with_wildcards) +{ + ck_assert_int_eq(pattern_match("eth0", "eth0,eth*,eth2", 0), 2); + ck_assert_int_eq(pattern_match("eth1", "eth0,eth*,eth2", 0), 1); + ck_assert_int_eq(pattern_match("eth2", "eth0,eth*,eth2", 0), 2); + ck_assert_int_eq(pattern_match("eth3", "eth0,eth*,eth2", 0), 1); + ck_assert_int_eq(pattern_match("vlan3", "eth0,eth*,eth2", 0), 0); + ck_assert_int_eq(pattern_match("vlan3", "eth0,eth*,eth2", 1), 1); +} +END_TEST + +START_TEST(test_simple_denylist) +{ + ck_assert_int_eq(pattern_match("eth0", "!eth0", 0), 0); + ck_assert_int_eq(pattern_match("eth0", "!eth0", 1), 0); + ck_assert_int_eq(pattern_match("eth1", "!eth0", 0), 0); + ck_assert_int_eq(pattern_match("eth1", "!eth0", 1), 1); +} +END_TEST + +START_TEST(test_match_and_denylist) +{ + ck_assert_int_eq(pattern_match("eth0", "eth0,!eth0", 0), 0); + ck_assert_int_eq(pattern_match("eth0", "eth0,!eth0", 1), 0); + ck_assert_int_eq(pattern_match("eth1", "eth0,!eth0", 0), 0); + ck_assert_int_eq(pattern_match("eth1", "eth0,!eth0", 1), 1); +} +END_TEST + +START_TEST(test_denylist_wildcard) +{ + ck_assert_int_eq(pattern_match("eth0", "!eth*", 0), 0); + ck_assert_int_eq(pattern_match("eth0", "!eth*", 1), 0); + ck_assert_int_eq(pattern_match("eth1", "!eth*", 0), 0); + ck_assert_int_eq(pattern_match("eth1", "!eth*", 1), 0); + ck_assert_int_eq(pattern_match("eth1", "eth*,!eth1", 0), 0); + ck_assert_int_eq(pattern_match("eth1", "eth*,!eth1", 1), 0); + ck_assert_int_eq(pattern_match("eth0", "eth*,!eth1", 0), 1); + ck_assert_int_eq(pattern_match("eth0", "eth*,!eth1", 1), 1); +} +END_TEST + +START_TEST(test_allowlist) +{ + ck_assert_int_eq(pattern_match("eth0", "!!eth0", 0), 2); + ck_assert_int_eq(pattern_match("eth0", "!!eth0", 1), 2); + ck_assert_int_eq(pattern_match("eth1", "!!eth0", 1), 1); + ck_assert_int_eq(pattern_match("eth0", "!eth*,!!eth0", 0), 2); + ck_assert_int_eq(pattern_match("eth0", "!eth*,!!eth0", 1), 2); + ck_assert_int_eq(pattern_match("eth1", "!eth*,!!eth0", 0), 0); + ck_assert_int_eq(pattern_match("eth1", "!eth*,!!eth0", 1), 0); + ck_assert_int_eq(pattern_match("vlan0", "*,!eth*,!!eth0", 0), 1); + ck_assert_int_eq(pattern_match("vlan0", "*,!eth*,!!eth0", 1), 1); + ck_assert_int_eq(pattern_match("eth0", "*,!eth*,!!eth0", 0), 2); + ck_assert_int_eq(pattern_match("eth0", "*,!eth*,!!eth0", 1), 2); + ck_assert_int_eq(pattern_match("eth1", "*,!eth*,!!eth0", 0), 0); + ck_assert_int_eq(pattern_match("eth1", "*,!!eth0,!eth*", 1), 0); + ck_assert_int_eq(pattern_match("eth0", "*,!!eth0,!eth*", 0), 2); + ck_assert_int_eq(pattern_match("eth0", "*,!!eth0,!eth*", 1), 2); +} +END_TEST + +static Suite * +pattern_suite(void) +{ + Suite *s = suite_create("Pattern matching"); + + TCase *tc_pattern = tcase_create("Pattern matching"); + tcase_add_test(tc_pattern, test_empty); + tcase_add_test(tc_pattern, test_simple_match); + tcase_add_test(tc_pattern, test_wildcard); + tcase_add_test(tc_pattern, test_match_list); + tcase_add_test(tc_pattern, test_match_list_with_wildcards); + tcase_add_test(tc_pattern, test_simple_denylist); + tcase_add_test(tc_pattern, test_match_and_denylist); + tcase_add_test(tc_pattern, test_denylist_wildcard); + tcase_add_test(tc_pattern, test_allowlist); + suite_add_tcase(s, tc_pattern); + + return s; +} + +int +main() +{ + int number_failed; + Suite *s = pattern_suite(); + SRunner *sr = srunner_create(s); + srunner_run_all(sr, CK_ENV); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/tests/check_snmp.c b/tests/check_snmp.c new file mode 100644 index 0000000..6817e9e --- /dev/null +++ b/tests/check_snmp.c @@ -0,0 +1,1190 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2015 Vincent Bernat <bernat@luffy.cx> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <check.h> + +#include "../src/daemon/lldpd.h" +#include "../src/daemon/agent.h" + +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> +#include <net-snmp/agent/net-snmp-agent-includes.h> +#include <net-snmp/agent/snmp_vars.h> + +extern struct lldpd *agent_scfg; +extern struct timeval starttime; +extern struct variable8 agent_lldp_vars[]; + +/* Our test config */ +struct lldpd test_cfg = { .g_config = { .c_tx_interval = 30000, + .c_tx_hold = 2, + .c_ttl = 60, + .c_smart = 0 } }; +struct timeval test_starttime = { .tv_sec = 100, .tv_usec = 0 }; + +/* First chassis */ +struct lldpd_mgmt mgmt1 = { .m_family = LLDPD_AF_IPV4, + .m_addr = { .octets = { 0xc0, 0, 0x2, 0xf } }, /* 192.0.2.15 */ + .m_addrsize = sizeof(struct in_addr), + .m_iface = 3 }; +struct lldpd_chassis chassis1 = { + .c_index = 1, + .c_protocol = LLDPD_MODE_LLDP, + .c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR, + .c_id = "AAA012", + .c_id_len = 6, + .c_name = "chassis1.example.com", + .c_descr = "First chassis", + .c_cap_available = LLDP_CAP_BRIDGE | LLDP_CAP_WLAN | LLDP_CAP_ROUTER, + .c_cap_enabled = LLDP_CAP_ROUTER, +#ifdef ENABLE_LLDPMED + .c_med_cap_available = LLDP_MED_CAP_CAP | LLDP_MED_CAP_IV | + LLDP_MED_CAP_LOCATION | LLDP_MED_CAP_POLICY | LLDP_MED_CAP_MDI_PSE | + LLDP_MED_CAP_MDI_PD, + .c_med_type = LLDP_MED_CLASS_II, + .c_med_hw = "Hardware 1", + /* We skip c_med_fw */ + .c_med_sw = "Software 1", + .c_med_sn = "00-00-0000-AAAA", + .c_med_manuf = "Manufacturer 1", + .c_med_model = "Model 1", + .c_med_asset = "Asset 1", +#endif +}; +/* Second chassis */ +struct lldpd_mgmt mgmt2 = { .m_family = LLDPD_AF_IPV4, + .m_addr = { .octets = { 0xc0, 0, 0x2, 0x11 } }, /* 192.0.2.17 */ + .m_addrsize = sizeof(struct in_addr), + .m_iface = 5 }; +struct lldpd_mgmt mgmt3 = { .m_family = LLDPD_AF_IPV6, + .m_addr = { .octets = { 0x20, 0x01, 0x0d, 0xb8, 0xca, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x17 } }, /* 2001:db8:cafe::17 */ + .m_addrsize = sizeof(struct in6_addr), + .m_iface = 5 }; +struct lldpd_chassis chassis2 = { + .c_index = 4, + .c_protocol = LLDPD_MODE_LLDP, + .c_id_subtype = LLDP_CHASSISID_SUBTYPE_LOCAL, + .c_id = "chassis2", + .c_id_len = 6, + .c_name = "chassis2.example.com", + .c_descr = "Second chassis", + .c_cap_available = LLDP_CAP_ROUTER, + .c_cap_enabled = LLDP_CAP_ROUTER, +#ifdef ENABLE_LLDPMED + .c_med_hw = "Hardware 2", + /* We skip c_med_fw */ + .c_med_sw = "Software 2", + .c_med_sn = "00-00-0000-AAAC", + .c_med_manuf = "Manufacturer 2", + .c_med_model = "Model 2", + .c_med_asset = "Asset 2", +#endif +}; + +/* First port of first chassis */ +struct lldpd_hardware hardware1 = { + .h_ifindex = 3, + .h_tx_cnt = 1352, + .h_rx_cnt = 1458, + .h_rx_discarded_cnt = 5, + .h_rx_unrecognized_cnt = 4, + .h_insert_cnt = 100, + .h_delete_cnt = 5, + .h_ageout_cnt = 20, + .h_drop_cnt = 1, + .h_lport = { + .p_chassis = &chassis1, + .p_lastchange = 200, + .p_protocol = LLDPD_MODE_LLDP, + .p_id_subtype = LLDP_PORTID_SUBTYPE_LLADDR, + .p_id = "AAA012", + .p_id_len = 6, + .p_descr = "eth2", + .p_mfs = 1600, +#ifdef ENABLE_DOT3 + .p_aggregid = 0, + .p_macphy = { + .autoneg_support = 1, + .autoneg_enabled = 1, + .autoneg_advertised = LLDP_DOT3_LINK_AUTONEG_100BASE_TX | LLDP_DOT3_LINK_AUTONEG_100BASE_TXFD, + .mau_type = LLDP_DOT3_MAU_100BASETXFD, + }, + .p_power = { + .devicetype = LLDP_DOT3_POWER_PD, + .supported = 1, + .enabled = 1, + .paircontrol = 1, + .pairs = 2, + .class = 3, + .powertype = LLDP_DOT3_POWER_8023AT_TYPE2, + .source = LLDP_DOT3_POWER_SOURCE_BOTH, + .priority = LLDP_DOT3_POWER_PRIO_LOW, + .requested = 2000, + .allocated = 2500, + }, +#endif +#ifdef ENABLE_LLDPMED + .p_med_cap_enabled = LLDP_MED_CAP_CAP | LLDP_MED_CAP_IV | LLDP_MED_CAP_MDI_PD | + LLDP_MED_CAP_POLICY | LLDP_MED_CAP_LOCATION, + .p_med_policy = { + { .type = 0 }, { .type = 0 }, { + .type = LLDP_MED_APPTYPE_GUESTVOICE, + .unknown = 1, + .tagged = 1, + .vid = 475, + .priority = 3, + .dscp = 62 + }, { .type = 0 }, { .type = 0 }, { .type = 0 }, { + .type = LLDP_MED_APPTYPE_VIDEOSTREAM, + .unknown = 0, + .tagged = 1, + .vid = 472, + .priority = 1, + .dscp = 60 + }, { .type = 0 } + }, + .p_med_location = { + { .format = 0 }, { + .format = LLDP_MED_LOCFORMAT_CIVIC, + /* 2:FR:6:Commercial Rd:19:4 */ + .data = "\x15" "\x02" "FR" "\x06" "\x0d" "Commercial Rd" "\x13" "\x01" "4", + .data_len = 22, + }, { .format = 0 } + }, + .p_med_power = { + .devicetype = LLDP_MED_POW_TYPE_PD, + .source = LLDP_MED_POW_SOURCE_LOCAL, + .priority = LLDP_MED_POW_PRIO_HIGH, + .val = 100 + }, +#endif +#ifdef ENABLE_DOT1 + .p_pvid = 47, +/* Remaining is done is snmp_config */ +#endif + } +}; +/* Second port of first chassis */ +struct lldpd_hardware hardware2 = { + .h_ifindex = 4, + .h_tx_cnt = 11352, + .h_rx_cnt = 11458, + .h_rx_discarded_cnt = 55, + .h_rx_unrecognized_cnt = 14, + .h_insert_cnt = 1000, + .h_delete_cnt = 51, + .h_ageout_cnt = 210, + .h_drop_cnt = 1, + .h_lport = { + .p_chassis = &chassis1, + .p_lastchange = 50, + .p_protocol = LLDPD_MODE_LLDP, + .p_id_subtype = LLDP_PORTID_SUBTYPE_IFNAME, + .p_id = "eth4", + .p_id_len = 4, + .p_descr = "Intel 1000 GE", + .p_mfs = 9000, +#ifdef ENABLE_DOT3 + .p_aggregid = 3, + .p_macphy = { + .autoneg_support = 1, + .autoneg_enabled = 1, + .autoneg_advertised = LLDP_DOT3_LINK_AUTONEG_100BASE_TXFD | LLDP_DOT3_LINK_AUTONEG_1000BASE_TFD, + .mau_type = LLDP_DOT3_MAU_1000BASETFD, + }, +#endif +#ifdef ENABLE_LLDPMED + .p_med_cap_enabled = LLDP_MED_CAP_CAP | LLDP_MED_CAP_IV | LLDP_MED_CAP_MDI_PD | + LLDP_MED_CAP_MDI_PSE | LLDP_MED_CAP_POLICY | LLDP_MED_CAP_LOCATION, + .p_med_policy = { + { .type = 0 }, { .type = 0 }, { + .type = LLDP_MED_APPTYPE_GUESTVOICE, + .unknown = 1, + .tagged = 1, + .vid = 475, + .priority = 3, + .dscp = 62 + }, { .type = 0 }, { .type = 0 }, { + .type = LLDP_MED_APPTYPE_VIDEOCONFERENCE, + .unknown = 0, + .tagged = 0, + .vid = 1007, + .priority = 1, + .dscp = 49 + }, { .type = 0 }, { .type = 0 } + }, + .p_med_location = { + { + .format = LLDP_MED_LOCFORMAT_COORD, + .data = "Not interpreted", + .data_len = 15, + }, { .format = 0 }, { .format = 0 }, + }, +#endif + } +}; + +#ifdef ENABLE_CUSTOM +struct lldpd_custom custom1 = { + .oui = { 33, 44, 55 }, + .subtype = 44, + .oui_info = (u_int8_t *)"OUI content", +}; +struct lldpd_custom custom2 = { + .oui = { 33, 44, 55 }, + .subtype = 44, + .oui_info = (u_int8_t *)"More content", +}; +struct lldpd_custom custom3 = { + .oui = { 33, 44, 55 }, + .subtype = 45, + .oui_info = (u_int8_t *)"More more content", +}; +struct lldpd_custom custom4 = { + .oui = { 33, 44, 56 }, + .subtype = 44, + .oui_info = (u_int8_t *)"Even more content", +}; +struct lldpd_custom custom5 = { + .oui = { 33, 44, 55 }, + .subtype = 44, + .oui_info = (u_int8_t *)"Still more content", +}; +#endif + +#ifdef ENABLE_DOT1 +struct lldpd_vlan vlan47 = { + .v_name = "VLAN #47", + .v_vid = 47, +}; +struct lldpd_vlan vlan49 = { + .v_name = "VLAN #49", + .v_vid = 49, +}; +struct lldpd_vlan vlan1449 = { + .v_name = "VLAN #1449", + .v_vid = 1449, +}; +struct lldpd_ppvid ppvid47 = { + .p_cap_status = LLDP_PPVID_CAP_SUPPORTED | LLDP_PPVID_CAP_ENABLED, + .p_ppvid = 47, +}; +struct lldpd_ppvid ppvid118 = { + .p_cap_status = LLDP_PPVID_CAP_SUPPORTED | LLDP_PPVID_CAP_ENABLED, + .p_ppvid = 118, +}; +struct lldpd_pi pi88cc = { + .p_pi = "\x88\xcc", + .p_pi_len = 2, +}; +struct lldpd_pi pi888e01 = { + .p_pi = "\x88\x8e\x01", + .p_pi_len = 3, +}; +#endif + +/* First port of second chassis */ +struct lldpd_port port2 = { + .p_chassis = &chassis2, + .p_lastchange = 180, + .p_protocol = LLDPD_MODE_LLDP, + .p_id_subtype = LLDP_PORTID_SUBTYPE_IFALIAS, + .p_id = "Giga1/7", + .p_id_len = 7, + .p_descr = "Gigabit Ethernet 1/7", +}; + +static void +snmp_config() +{ + starttime = test_starttime; + agent_scfg = &test_cfg; + TAILQ_INIT(&test_cfg.g_chassis); + TAILQ_INIT(&chassis1.c_mgmt); + TAILQ_INSERT_TAIL(&chassis1.c_mgmt, &mgmt1, m_entries); + TAILQ_INSERT_TAIL(&test_cfg.g_chassis, &chassis1, c_entries); + TAILQ_INIT(&chassis2.c_mgmt); + TAILQ_INSERT_TAIL(&chassis2.c_mgmt, &mgmt2, m_entries); + TAILQ_INSERT_TAIL(&chassis2.c_mgmt, &mgmt3, m_entries); + TAILQ_INSERT_TAIL(&test_cfg.g_chassis, &chassis2, c_entries); + TAILQ_INIT(&test_cfg.g_hardware); + TAILQ_INSERT_TAIL(&test_cfg.g_hardware, &hardware1, h_entries); + TAILQ_INSERT_TAIL(&test_cfg.g_hardware, &hardware2, h_entries); +#ifdef ENABLE_CUSTOM + custom1.oui_info_len = strlen((char *)custom1.oui_info); + custom2.oui_info_len = strlen((char *)custom2.oui_info); + custom3.oui_info_len = strlen((char *)custom3.oui_info); + custom4.oui_info_len = strlen((char *)custom4.oui_info); + custom5.oui_info_len = strlen((char *)custom5.oui_info); + TAILQ_INIT(&hardware1.h_lport.p_custom_list); + TAILQ_INIT(&hardware2.h_lport.p_custom_list); + TAILQ_INIT(&port2.p_custom_list); + TAILQ_INSERT_TAIL(&hardware2.h_lport.p_custom_list, &custom1, next); + TAILQ_INSERT_TAIL(&hardware2.h_lport.p_custom_list, &custom2, next); + TAILQ_INSERT_TAIL(&hardware2.h_lport.p_custom_list, &custom3, next); + TAILQ_INSERT_TAIL(&hardware2.h_lport.p_custom_list, &custom4, next); + TAILQ_INSERT_TAIL(&hardware1.h_lport.p_custom_list, &custom5, next); +#endif +#ifdef ENABLE_DOT1 + TAILQ_INIT(&hardware1.h_lport.p_vlans); + TAILQ_INSERT_TAIL(&hardware1.h_lport.p_vlans, &vlan47, v_entries); + TAILQ_INSERT_TAIL(&hardware1.h_lport.p_vlans, &vlan49, v_entries); + TAILQ_INSERT_TAIL(&hardware1.h_lport.p_vlans, &vlan1449, v_entries); + TAILQ_INIT(&hardware1.h_lport.p_ppvids); + TAILQ_INSERT_TAIL(&hardware1.h_lport.p_ppvids, &ppvid47, p_entries); + TAILQ_INSERT_TAIL(&hardware1.h_lport.p_ppvids, &ppvid118, p_entries); + TAILQ_INIT(&hardware1.h_lport.p_pids); + TAILQ_INSERT_TAIL(&hardware1.h_lport.p_pids, &pi88cc, p_entries); + TAILQ_INSERT_TAIL(&hardware1.h_lport.p_pids, &pi888e01, p_entries); + TAILQ_INIT(&hardware2.h_lport.p_vlans); + TAILQ_INIT(&hardware2.h_lport.p_ppvids); + TAILQ_INIT(&hardware2.h_lport.p_pids); + TAILQ_INIT(&port2.p_vlans); + TAILQ_INIT(&port2.p_ppvids); + TAILQ_INIT(&port2.p_pids); +#endif + TAILQ_INIT(&hardware1.h_rports); + TAILQ_INSERT_TAIL(&hardware1.h_rports, &port2, p_entries); + TAILQ_INSERT_TAIL(&hardware1.h_rports, &hardware2.h_lport, p_entries); + TAILQ_INIT(&hardware2.h_rports); + TAILQ_INSERT_TAIL(&hardware2.h_rports, &hardware1.h_lport, p_entries); +} + +/* Convert OID to a string. Static buffer. */ +static char * +snmp_oidrepr(oid *name, size_t namelen) +{ + static char *buffer[4] = { NULL, NULL, NULL, NULL }; + static int current = 0; + size_t i; + + current = (current + 1) % 4; + free(buffer[current]); + buffer[current] = NULL; + + for (i = 0; i < namelen; i++) { + /* Not very efficient... */ + char *newbuffer = NULL; + if (asprintf(&newbuffer, "%s.%lu", + buffer[current] ? buffer[current] : "", + (unsigned long)name[i]) == -1) { + free(buffer[current]); + buffer[current] = NULL; + return NULL; + } + free(buffer[current]); + buffer[current] = newbuffer; + } + return buffer[current++]; +} + +struct tree_node { + oid name[MAX_OID_LEN]; + size_t namelen; + int type; /* ASN_* */ + union { + unsigned long int integer; + struct { + char *octet; + size_t len; + } string; + } value; +}; + +static oid zeroDotZero[2] = { 0, 0 }; +struct tree_node snmp_tree[] = { { { 1, 1, 1, 0 }, 4, ASN_INTEGER, + { .integer = 30 } }, /* lldpMessageTxInterval */ + { { 1, 1, 2, 0 }, 4, ASN_INTEGER, + { .integer = 2 } }, /* lldpMessageTxHoldMultiplier */ + { { 1, 1, 3, 0 }, 4, ASN_INTEGER, { .integer = 1 } }, /* lldpReinitDelay */ + { { 1, 1, 4, 0 }, 4, ASN_INTEGER, { .integer = 1 } }, /* lldpTxDelay */ + { { 1, 1, 5, 0 }, 4, ASN_INTEGER, + { .integer = 5 } }, /* lldpNotificationInterval */ + { { 1, 2, 1, 0 }, 4, ASN_TIMETICKS, + { .integer = 10000 } }, /* lldpStatsRemTablesLastChangeTime */ + { { 1, 2, 2, 0 }, 4, ASN_GAUGE, + { .integer = 1100 } }, /* lldpStatsRemTablesInserts */ + { { 1, 2, 3, 0 }, 4, ASN_GAUGE, + { .integer = 56 } }, /* lldpStatsRemTablesDeletes */ + { { 1, 2, 4, 0 }, 4, ASN_GAUGE, + { .integer = 2 } }, /* lldpStatsRemTablesDrops */ + { { 1, 2, 5, 0 }, 4, ASN_GAUGE, + { .integer = 230 } }, /* lldpStatsRemTablesAgeouts */ + + { { 1, 2, 6, 1, 2, 3 }, 6, ASN_COUNTER, + { .integer = 1352 } }, /* lldpStatsTxPortFramesTotal.3 */ + { { 1, 2, 6, 1, 2, 4 }, 6, ASN_COUNTER, + { .integer = 11352 } }, /* lldpStatsTxPortFramesTotal.4 */ + { { 1, 2, 7, 1, 2, 3 }, 6, ASN_COUNTER, + { .integer = 5 } }, /* lldpStatsRxPortFramesDiscardedTotal.3 */ + { { 1, 2, 7, 1, 2, 4 }, 6, ASN_COUNTER, + { .integer = 55 } }, /* lldpStatsRxPortFramesDiscardedTotal.4 */ + { { 1, 2, 7, 1, 3, 3 }, 6, ASN_COUNTER, + { .integer = 5 } }, /* lldpStatsRxPortFramesError.3 */ + { { 1, 2, 7, 1, 3, 4 }, 6, ASN_COUNTER, + { .integer = 55 } }, /* lldpStatsRxPortFramesError.4 */ + { { 1, 2, 7, 1, 4, 3 }, 6, ASN_COUNTER, + { .integer = 1458 } }, /* lldpStatsRxPortFramesTotal.3 */ + { { 1, 2, 7, 1, 4, 4 }, 6, ASN_COUNTER, + { .integer = 11458 } }, /* lldpStatsRxPortFramesTotal.4 */ + { { 1, 2, 7, 1, 5, 3 }, 6, ASN_COUNTER, + { .integer = 4 } }, /* lldpStatsRxPortTLVsDiscardedTotal.3 */ + { { 1, 2, 7, 1, 5, 4 }, 6, ASN_COUNTER, + { .integer = 14 } }, /* lldpStatsRxPortTLVsDiscardedTotal.4 */ + { { 1, 2, 7, 1, 6, 3 }, 6, ASN_COUNTER, + { .integer = 4 } }, /* lldpStatsRxPortTLVsUnrecognizedTotal.3 */ + { { 1, 2, 7, 1, 6, 4 }, 6, ASN_COUNTER, + { .integer = 14 } }, /* lldpStatsRxPortTLVsUnrecognizedTotal.4 */ + { { 1, 2, 7, 1, 7, 3 }, 6, ASN_GAUGE, + { .integer = 20 } }, /* lldpStatsRxPortAgeoutsTotal.3 */ + { { 1, 2, 7, 1, 7, 4 }, 6, ASN_GAUGE, + { .integer = 210 } }, /* lldpStatsRxPortAgeoutsTotal.4 */ + + { { 1, 3, 1, 0 }, 4, ASN_INTEGER, + { .integer = 4 } }, /* lldpLocChassisIdSubtype */ + /* lldpLocChassisId */ + { { 1, 3, 2, 0 }, 4, ASN_OCTET_STR, + { .string = { .octet = "AAA012", .len = 6 } } }, + /* lldpLocSysName */ + { { 1, 3, 3, 0 }, 4, ASN_OCTET_STR, + { .string = { .octet = "chassis1.example.com", .len = 20 } } }, + /* lldpLocSysDesc */ + { { 1, 3, 4, 0 }, 4, ASN_OCTET_STR, + { .string = { .octet = "First chassis", .len = 13 } } }, + /* lldpLocSysCapSupported */ + { { 1, 3, 5, 0 }, 4, ASN_OCTET_STR, + { .string = { .octet = "\x38", .len = 1 } } }, + /* lldpLocSysCapEnabled */ + { { 1, 3, 6, 0 }, 4, ASN_OCTET_STR, + { .string = { .octet = "\x8", .len = 1 } } }, + + { { 1, 3, 7, 1, 2, 3 }, 6, ASN_INTEGER, + { .integer = 3 } }, /* lldpLocPortIdSubtype.3 */ + { { 1, 3, 7, 1, 2, 4 }, 6, ASN_INTEGER, + { .integer = 5 } }, /* lldpLocPortIdSubtype.5 */ + /* lldpLocPortId.3 */ + { { 1, 3, 7, 1, 3, 3 }, 6, ASN_OCTET_STR, + { .string = { .octet = "AAA012", .len = 6 } } }, + /* lldpLocPortId.4 */ + { { 1, 3, 7, 1, 3, 4 }, 6, ASN_OCTET_STR, + { .string = { .octet = "eth4", .len = 4 } } }, + /* lldpLocPortDesc.3 */ + { { 1, 3, 7, 1, 4, 3 }, 6, ASN_OCTET_STR, + { .string = { .octet = "eth2", .len = 4 } } }, + /* lldpLocPortDesc.4 */ + { { 1, 3, 7, 1, 4, 4 }, 6, ASN_OCTET_STR, + { .string = { .octet = "Intel 1000 GE", .len = 13 } } }, + + { { 1, 3, 8, 1, 3, 1, 4, 192, 0, 2, 15 }, 11, ASN_INTEGER, + { .integer = 5 } }, /* lldpLocManAddrLen */ + { { 1, 3, 8, 1, 4, 1, 4, 192, 0, 2, 15 }, 11, ASN_INTEGER, + { .integer = 2 } }, /* lldpLocManAddrIfSubtype */ + { { 1, 3, 8, 1, 5, 1, 4, 192, 0, 2, 15 }, 11, ASN_INTEGER, + { .integer = 3 } }, /* lldpLocManAddrIfId */ + /* lldpLocManAddrOID */ + { { 1, 3, 8, 1, 6, 1, 4, 192, 0, 2, 15 }, 11, ASN_OBJECT_ID, + { .string = { .octet = (char *)zeroDotZero, + .len = sizeof(zeroDotZero) } } }, + + /* lldpRemChassisIdSubtype */ + { { 1, 4, 1, 1, 4, 0, 3, 1 }, 8, ASN_INTEGER, { .integer = 4 } }, + { { 1, 4, 1, 1, 4, 8000, 3, 4 }, 8, ASN_INTEGER, { .integer = 7 } }, + { { 1, 4, 1, 1, 4, 10000, 4, 1 }, 8, ASN_INTEGER, { .integer = 4 } }, + /* lldpRemChassisId */ + { { 1, 4, 1, 1, 5, 0, 3, 1 }, 8, ASN_OCTET_STR, + { .string = { .octet = "AAA012", .len = 6 } } }, + { { 1, 4, 1, 1, 5, 8000, 3, 4 }, 8, ASN_OCTET_STR, + { .string = { .octet = "chassis2", .len = 6 } } }, + { { 1, 4, 1, 1, 5, 10000, 4, 1 }, 8, ASN_OCTET_STR, + { .string = { .octet = "AAA012", .len = 6 } } }, + /* lldpRemPortIdSubtype */ + { { 1, 4, 1, 1, 6, 0, 3, 1 }, 8, ASN_INTEGER, { .integer = 5 } }, + { { 1, 4, 1, 1, 6, 8000, 3, 4 }, 8, ASN_INTEGER, { .integer = 1 } }, + { { 1, 4, 1, 1, 6, 10000, 4, 1 }, 8, ASN_INTEGER, { .integer = 3 } }, + /* lldpRemPortId */ + { { 1, 4, 1, 1, 7, 0, 3, 1 }, 8, ASN_OCTET_STR, + { .string = { .octet = "eth4", .len = 4 } } }, + { { 1, 4, 1, 1, 7, 8000, 3, 4 }, 8, ASN_OCTET_STR, + { .string = { .octet = "Giga1/7", .len = 7 } } }, + { { 1, 4, 1, 1, 7, 10000, 4, 1 }, 8, ASN_OCTET_STR, + { .string = { .octet = "AAA012", .len = 6 } } }, + /* lldpRemPortDesc */ + { { 1, 4, 1, 1, 8, 0, 3, 1 }, 8, ASN_OCTET_STR, + { .string = { .octet = "Intel 1000 GE", .len = 13 } } }, + { { 1, 4, 1, 1, 8, 8000, 3, 4 }, 8, ASN_OCTET_STR, + { .string = { .octet = "Gigabit Ethernet 1/7", .len = 20 } } }, + { { 1, 4, 1, 1, 8, 10000, 4, 1 }, 8, ASN_OCTET_STR, + { .string = { .octet = "eth2", .len = 4 } } }, + /* lldpRemSysName */ + { { 1, 4, 1, 1, 9, 0, 3, 1 }, 8, ASN_OCTET_STR, + { .string = { .octet = "chassis1.example.com", .len = 20 } } }, + { { 1, 4, 1, 1, 9, 8000, 3, 4 }, 8, ASN_OCTET_STR, + { .string = { .octet = "chassis2.example.com", .len = 20 } } }, + { { 1, 4, 1, 1, 9, 10000, 4, 1 }, 8, ASN_OCTET_STR, + { .string = { .octet = "chassis1.example.com", .len = 20 } } }, + /* lldpRemSysDesc */ + { { 1, 4, 1, 1, 10, 0, 3, 1 }, 8, ASN_OCTET_STR, + { .string = { .octet = "First chassis", .len = 13 } } }, + { { 1, 4, 1, 1, 10, 8000, 3, 4 }, 8, ASN_OCTET_STR, + { .string = { .octet = "Second chassis", .len = 14 } } }, + { { 1, 4, 1, 1, 10, 10000, 4, 1 }, 8, ASN_OCTET_STR, + { .string = { .octet = "First chassis", .len = 13 } } }, + /* lldpRemSysCapSupported */ + { { 1, 4, 1, 1, 11, 0, 3, 1 }, 8, ASN_OCTET_STR, + { .string = { .octet = "\x38", .len = 1 } } }, + { { 1, 4, 1, 1, 11, 8000, 3, 4 }, 8, ASN_OCTET_STR, + { .string = { .octet = "\x8", .len = 1 } } }, + { { 1, 4, 1, 1, 11, 10000, 4, 1 }, 8, ASN_OCTET_STR, + { .string = { .octet = "\x38", .len = 1 } } }, + /* lldpRemSysCapEnabled */ + { { 1, 4, 1, 1, 12, 0, 3, 1 }, 8, ASN_OCTET_STR, + { .string = { .octet = "\x8", .len = 1 } } }, + { { 1, 4, 1, 1, 12, 8000, 3, 4 }, 8, ASN_OCTET_STR, + { .string = { .octet = "\x8", .len = 1 } } }, + { { 1, 4, 1, 1, 12, 10000, 4, 1 }, 8, ASN_OCTET_STR, + { .string = { .octet = "\x8", .len = 1 } } }, + + /* lldpRemManAddrIfSubtype */ + { { 1, 4, 2, 1, 3, 0, 3, 1, 1, 4, 192, 0, 2, 15 }, 14, ASN_INTEGER, + { .integer = 2 } }, + { { 1, 4, 2, 1, 3, 8000, 3, 4, 1, 4, 192, 0, 2, 17 }, 14, ASN_INTEGER, + { .integer = 2 } }, + { { 1, 4, 2, 1, 3, 8000, 3, 4, 2, 16, 0x20, 0x01, 0x0d, 0xb8, 0xca, 0xfe, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17 }, + 26, ASN_INTEGER, { .integer = 2 } }, + { { 1, 4, 2, 1, 3, 10000, 4, 1, 1, 4, 192, 0, 2, 15 }, 14, ASN_INTEGER, + { .integer = 2 } }, + /* lldpRemManAddrIfId */ + { { 1, 4, 2, 1, 4, 0, 3, 1, 1, 4, 192, 0, 2, 15 }, 14, ASN_INTEGER, + { .integer = 3 } }, + { { 1, 4, 2, 1, 4, 8000, 3, 4, 1, 4, 192, 0, 2, 17 }, 14, ASN_INTEGER, + { .integer = 5 } }, + { { 1, 4, 2, 1, 4, 8000, 3, 4, 2, 16, 0x20, 0x01, 0x0d, 0xb8, 0xca, 0xfe, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17 }, + 26, ASN_INTEGER, { .integer = 5 } }, + { { 1, 4, 2, 1, 4, 10000, 4, 1, 1, 4, 192, 0, 2, 15 }, 14, ASN_INTEGER, + { .integer = 3 } }, + /* lldpRemManAddrOID */ + { { 1, 4, 2, 1, 5, 0, 3, 1, 1, 4, 192, 0, 2, 15 }, 14, ASN_OBJECT_ID, + { .string = { .octet = (char *)zeroDotZero, + .len = sizeof(zeroDotZero) } } }, + { { 1, 4, 2, 1, 5, 8000, 3, 4, 1, 4, 192, 0, 2, 17 }, 14, ASN_OBJECT_ID, + { .string = { .octet = (char *)zeroDotZero, + .len = sizeof(zeroDotZero) } } }, + { { 1, 4, 2, 1, 5, 8000, 3, 4, 2, 16, 0x20, 0x01, 0x0d, 0xb8, 0xca, 0xfe, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17 }, + 26, ASN_OBJECT_ID, + { .string = { .octet = (char *)zeroDotZero, + .len = sizeof(zeroDotZero) } } }, + { { 1, 4, 2, 1, 5, 10000, 4, 1, 1, 4, 192, 0, 2, 15 }, 14, ASN_OBJECT_ID, + { .string = { .octet = (char *)zeroDotZero, + .len = sizeof(zeroDotZero) } } }, + +#ifdef ENABLE_CUSTOM + /* lldpRemOrgDefInfo */ + { { 1, 4, 4, 1, 4, 0, 3, 1, 33, 44, 55, 44, 1 }, 13, ASN_OCTET_STR, + { .string = { .octet = "OUI content", .len = 11 } } }, + { { 1, 4, 4, 1, 4, 0, 3, 1, 33, 44, 55, 44, 2 }, 13, ASN_OCTET_STR, + { .string = { .octet = "More content", .len = 12 } } }, + { { 1, 4, 4, 1, 4, 0, 3, 1, 33, 44, 55, 45, 3 }, 13, ASN_OCTET_STR, + { .string = { .octet = "More more content", .len = 17 } } }, + { { 1, 4, 4, 1, 4, 0, 3, 1, 33, 44, 56, 44, 4 }, 13, ASN_OCTET_STR, + { .string = { .octet = "Even more content", .len = 17 } } }, + { { 1, 4, 4, 1, 4, 10000, 4, 1, 33, 44, 55, 44, 1 }, 13, ASN_OCTET_STR, + { .string = { .octet = "Still more content", .len = 18 } } }, +#endif + +#ifdef ENABLE_DOT3 + /* lldpXdot3LocPortAutoNegSupported */ + { { 1, 5, 4623, 1, 2, 1, 1, 1, 3 }, 9, ASN_INTEGER, { .integer = 1 } }, + { { 1, 5, 4623, 1, 2, 1, 1, 1, 4 }, 9, ASN_INTEGER, { .integer = 1 } }, + /* lldpXdot3LocPortAutoNegEnabled */ + { { 1, 5, 4623, 1, 2, 1, 1, 2, 3 }, 9, ASN_INTEGER, { .integer = 1 } }, + { { 1, 5, 4623, 1, 2, 1, 1, 2, 4 }, 9, ASN_INTEGER, { .integer = 1 } }, + /* lldpXdot3LocPortAutoNegAdvertisedCap */ + { { 1, 5, 4623, 1, 2, 1, 1, 3, 3 }, 9, ASN_OCTET_STR, + { .string = { .octet = "\x0c\x00", .len = 2 } } }, + { { 1, 5, 4623, 1, 2, 1, 1, 3, 4 }, 9, ASN_OCTET_STR, + { .string = { .octet = "\x04\x01", .len = 2 } } }, + /* lldpXdot3LocPortOperMauType */ + { { 1, 5, 4623, 1, 2, 1, 1, 4, 3 }, 9, ASN_INTEGER, { .integer = 16 } }, + { { 1, 5, 4623, 1, 2, 1, 1, 4, 4 }, 9, ASN_INTEGER, { .integer = 30 } }, + + /* lldpXdot3LocPowerPortClass */ + { { 1, 5, 4623, 1, 2, 2, 1, 1, 3 }, 9, ASN_INTEGER, { .integer = 2 } }, + /* lldpXdot3LocPowerMDISupported */ + { { 1, 5, 4623, 1, 2, 2, 1, 2, 3 }, 9, ASN_INTEGER, { .integer = 1 } }, + /* lldpXdot3LocPowerMDIEnabled */ + { { 1, 5, 4623, 1, 2, 2, 1, 3, 3 }, 9, ASN_INTEGER, { .integer = 1 } }, + /* lldpXdot3LocPowerPairControlable */ + { { 1, 5, 4623, 1, 2, 2, 1, 4, 3 }, 9, ASN_INTEGER, { .integer = 1 } }, + /* lldpXdot3LocPowerPairs */ + { { 1, 5, 4623, 1, 2, 2, 1, 5, 3 }, 9, ASN_INTEGER, { .integer = 2 } }, + /* lldpXdot3LocPowerClass */ + { { 1, 5, 4623, 1, 2, 2, 1, 6, 3 }, 9, ASN_INTEGER, { .integer = 3 } }, + /* As per 802.3at-2009, not sure of the OID... */ + /* lldpXdot3LocPowerType */ + { { 1, 5, 4623, 1, 2, 2, 1, 7, 3 }, 9, ASN_OCTET_STR, + { .string = { .octet = "\xC0", .len = 1 } } }, + /* lldpXdot3LocPowerSource */ + { { 1, 5, 4623, 1, 2, 2, 1, 8, 3 }, 9, ASN_OCTET_STR, + { .string = { .octet = "\xC0", .len = 1 } } }, + /* lldpXdot3LocPowerPriority */ + { { 1, 5, 4623, 1, 2, 2, 1, 9, 3 }, 9, ASN_INTEGER, { .integer = 1 } }, + /* lldpXdot3LocPDRequestedPowerValue */ + { { 1, 5, 4623, 1, 2, 2, 1, 10, 3 }, 9, ASN_INTEGER, { .integer = 2000 } }, + /* lldpXdot3LocPSEAllocatedPowerValue */ + { { 1, 5, 4623, 1, 2, 2, 1, 11, 3 }, 9, ASN_INTEGER, { .integer = 2500 } }, + + /* lldpXdot3LocLinkAggStatus */ + { { 1, 5, 4623, 1, 2, 3, 1, 1, 3 }, 9, ASN_OCTET_STR, + { .string = { .octet = "\x00", .len = 1 } } }, + { { 1, 5, 4623, 1, 2, 3, 1, 1, 4 }, 9, ASN_OCTET_STR, + { .string = { .octet = "\xC0", .len = 1 } } }, + /* lldpXdot3LocLinkAggPortId */ + { { 1, 5, 4623, 1, 2, 3, 1, 2, 3 }, 9, ASN_INTEGER, { .integer = 0 } }, + { { 1, 5, 4623, 1, 2, 3, 1, 2, 4 }, 9, ASN_INTEGER, { .integer = 3 } }, + + /* lldpXdot3LocMaxFrameSize */ + { { 1, 5, 4623, 1, 2, 4, 1, 1, 3 }, 9, ASN_INTEGER, { .integer = 1600 } }, + { { 1, 5, 4623, 1, 2, 4, 1, 1, 4 }, 9, ASN_INTEGER, { .integer = 9000 } }, + + /* lldpXdot3RemPortAutoNegSupported */ + { { 1, 5, 4623, 1, 3, 1, 1, 1, 0, 3, 1 }, 11, ASN_INTEGER, { .integer = 1 } }, + { { 1, 5, 4623, 1, 3, 1, 1, 1, 8000, 3, 4 }, 11, ASN_INTEGER, + { .integer = 2 } }, + { { 1, 5, 4623, 1, 3, 1, 1, 1, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 1 } }, + /* lldpXdot3RemPortAutoNegEnabled */ + { { 1, 5, 4623, 1, 3, 1, 1, 2, 0, 3, 1 }, 11, ASN_INTEGER, { .integer = 1 } }, + { { 1, 5, 4623, 1, 3, 1, 1, 2, 8000, 3, 4 }, 11, ASN_INTEGER, + { .integer = 2 } }, + { { 1, 5, 4623, 1, 3, 1, 1, 2, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 1 } }, + /* lldpXdot3RemPortAutoNegAdvertisedCap */ + { { 1, 5, 4623, 1, 3, 1, 1, 3, 0, 3, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "\x04\x01", .len = 2 } } }, + { { 1, 5, 4623, 1, 3, 1, 1, 3, 8000, 3, 4 }, 11, ASN_OCTET_STR, + { .string = { .octet = "\x00\x00", .len = 2 } } }, + { { 1, 5, 4623, 1, 3, 1, 1, 3, 10000, 4, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "\x0c\x00", .len = 2 } } }, + /* lldpXdot3RemPortOperMauType */ + { { 1, 5, 4623, 1, 3, 1, 1, 4, 0, 3, 1 }, 11, ASN_INTEGER, { .integer = 30 } }, + { { 1, 5, 4623, 1, 3, 1, 1, 4, 8000, 3, 4 }, 11, ASN_INTEGER, + { .integer = 0 } }, + { { 1, 5, 4623, 1, 3, 1, 1, 4, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 16 } }, + + /* lldpXdot3RemPowerPortClass */ + { { 1, 5, 4623, 1, 3, 2, 1, 1, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 2 } }, + /* lldpXdot3RemPowerMDISupported */ + { { 1, 5, 4623, 1, 3, 2, 1, 2, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 1 } }, + /* lldpXdot3RemPowerMDIEnabled */ + { { 1, 5, 4623, 1, 3, 2, 1, 3, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 1 } }, + /* lldpXdot3RemPowerPairControlable */ + { { 1, 5, 4623, 1, 3, 2, 1, 4, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 1 } }, + /* lldpXdot3RemPowerPairs */ + { { 1, 5, 4623, 1, 3, 2, 1, 5, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 2 } }, + /* lldpXdot3RemPowerClass */ + { { 1, 5, 4623, 1, 3, 2, 1, 6, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 3 } }, + /* As per 802.3at-2009, not sure of the OID... */ + /* lldpXdot3RemPowerType */ + { { 1, 5, 4623, 1, 3, 2, 1, 7, 10000, 4, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "\xC0", .len = 1 } } }, + /* lldpXdot3RemPowerSource */ + { { 1, 5, 4623, 1, 3, 2, 1, 8, 10000, 4, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "\xC0", .len = 1 } } }, + /* lldpXdot3RemPowerPriority */ + { { 1, 5, 4623, 1, 3, 2, 1, 9, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 1 } }, + /* lldpXdot3RemPDRequestedPowerValue */ + { { 1, 5, 4623, 1, 3, 2, 1, 10, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 2000 } }, + /* lldpXdot3RemPSEAllocatedPowerValue */ + { { 1, 5, 4623, 1, 3, 2, 1, 11, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 2500 } }, + + /* lldpXdot3RemLinkAggStatus */ + { { 1, 5, 4623, 1, 3, 3, 1, 1, 0, 3, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "\xC0", .len = 1 } } }, + { { 1, 5, 4623, 1, 3, 3, 1, 1, 8000, 3, 4 }, 11, ASN_OCTET_STR, + { .string = { .octet = "\x00", .len = 1 } } }, + { { 1, 5, 4623, 1, 3, 3, 1, 1, 10000, 4, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "\x00", .len = 1 } } }, + /* lldpXdot3RemLinkAggPortId */ + { { 1, 5, 4623, 1, 3, 3, 1, 2, 0, 3, 1 }, 11, ASN_INTEGER, { .integer = 3 } }, + { { 1, 5, 4623, 1, 3, 3, 1, 2, 8000, 3, 4 }, 11, ASN_INTEGER, + { .integer = 0 } }, + { { 1, 5, 4623, 1, 3, 3, 1, 2, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 0 } }, + + /* lldpXdot3RemMaxFrameSize */ + { { 1, 5, 4623, 1, 3, 4, 1, 1, 0, 3, 1 }, 11, ASN_INTEGER, + { .integer = 9000 } }, + { { 1, 5, 4623, 1, 3, 4, 1, 1, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 1600 } }, +#endif +#ifdef ENABLE_LLDPMED + /* lldpXMedLocDeviceClass */ + { { 1, 5, 4795, 1, 1, 1, 0 }, 7, ASN_INTEGER, { .integer = 2 } }, + + /* lldpXMedLocMediaPolicyVlanID */ + { { 1, 5, 4795, 1, 2, 1, 1, 2, 3, 3 }, 10, ASN_INTEGER, { .integer = 475 } }, + { { 1, 5, 4795, 1, 2, 1, 1, 2, 3, 7 }, 10, ASN_INTEGER, { .integer = 472 } }, + { { 1, 5, 4795, 1, 2, 1, 1, 2, 4, 3 }, 10, ASN_INTEGER, { .integer = 475 } }, + { { 1, 5, 4795, 1, 2, 1, 1, 2, 4, 6 }, 10, ASN_INTEGER, { .integer = 1007 } }, + /* lldpXMedLocMediaPolicyPriority */ + { { 1, 5, 4795, 1, 2, 1, 1, 3, 3, 3 }, 10, ASN_INTEGER, { .integer = 3 } }, + { { 1, 5, 4795, 1, 2, 1, 1, 3, 3, 7 }, 10, ASN_INTEGER, { .integer = 1 } }, + { { 1, 5, 4795, 1, 2, 1, 1, 3, 4, 3 }, 10, ASN_INTEGER, { .integer = 3 } }, + { { 1, 5, 4795, 1, 2, 1, 1, 3, 4, 6 }, 10, ASN_INTEGER, { .integer = 1 } }, + /* lldpXMedLocMediaPolicyDscp */ + { { 1, 5, 4795, 1, 2, 1, 1, 4, 3, 3 }, 10, ASN_INTEGER, { .integer = 62 } }, + { { 1, 5, 4795, 1, 2, 1, 1, 4, 3, 7 }, 10, ASN_INTEGER, { .integer = 60 } }, + { { 1, 5, 4795, 1, 2, 1, 1, 4, 4, 3 }, 10, ASN_INTEGER, { .integer = 62 } }, + { { 1, 5, 4795, 1, 2, 1, 1, 4, 4, 6 }, 10, ASN_INTEGER, { .integer = 49 } }, + /* lldpXMedLocMediaPolicyUnknown */ + { { 1, 5, 4795, 1, 2, 1, 1, 5, 3, 3 }, 10, ASN_INTEGER, { .integer = 1 } }, + { { 1, 5, 4795, 1, 2, 1, 1, 5, 3, 7 }, 10, ASN_INTEGER, { .integer = 2 } }, + { { 1, 5, 4795, 1, 2, 1, 1, 5, 4, 3 }, 10, ASN_INTEGER, { .integer = 1 } }, + { { 1, 5, 4795, 1, 2, 1, 1, 5, 4, 6 }, 10, ASN_INTEGER, { .integer = 2 } }, + /* lldpXMedLocMediaPolicyTagged */ + { { 1, 5, 4795, 1, 2, 1, 1, 6, 3, 3 }, 10, ASN_INTEGER, { .integer = 1 } }, + { { 1, 5, 4795, 1, 2, 1, 1, 6, 3, 7 }, 10, ASN_INTEGER, { .integer = 1 } }, + { { 1, 5, 4795, 1, 2, 1, 1, 6, 4, 3 }, 10, ASN_INTEGER, { .integer = 1 } }, + { { 1, 5, 4795, 1, 2, 1, 1, 6, 4, 6 }, 10, ASN_INTEGER, { .integer = 2 } }, + + /* lldpXMedLocHardwareRev */ + { { 1, 5, 4795, 1, 2, 2, 0 }, 7, ASN_OCTET_STR, + { .string = { .octet = "Hardware 1", .len = 10 } } }, + /* lldpXMedLocSoftwareRev */ + { { 1, 5, 4795, 1, 2, 4, 0 }, 7, ASN_OCTET_STR, + { .string = { .octet = "Software 1", .len = 10 } } }, + /* lldpXMedLocSerialNum */ + { { 1, 5, 4795, 1, 2, 5, 0 }, 7, ASN_OCTET_STR, + { .string = { .octet = "00-00-0000-AAAA", .len = 15 } } }, + /* lldpXMedLocMfgName */ + { { 1, 5, 4795, 1, 2, 6, 0 }, 7, ASN_OCTET_STR, + { .string = { .octet = "Manufacturer 1", .len = 14 } } }, + /* lldpXMedLocModelName */ + { { 1, 5, 4795, 1, 2, 7, 0 }, 7, ASN_OCTET_STR, + { .string = { .octet = "Model 1", .len = 7 } } }, + /* lldpXMedLocAssetID */ + { { 1, 5, 4795, 1, 2, 8, 0 }, 7, ASN_OCTET_STR, + { .string = { .octet = "Asset 1", .len = 7 } } }, + + /* lldpXMedLocLocationInfo */ + { { 1, 5, 4795, 1, 2, 9, 1, 2, 3, 3 }, 10, ASN_OCTET_STR, + { .string = { .octet = "\x15" + "\x02" + "FR" + "\x06" + "\x0d" + "Commercial Rd" + "\x13" + "\x01" + "4", + .len = 22 } } }, + { { 1, 5, 4795, 1, 2, 9, 1, 2, 4, 2 }, 10, ASN_OCTET_STR, + { .string = { .octet = "Not interpreted", .len = 15 } } }, + + /* lldpXMedLocXPoEDeviceType */ + { { 1, 5, 4795, 1, 2, 10, 0 }, 7, ASN_INTEGER, { .integer = 3 } }, + /* lldpXMedLocXPoEPDPowerReq */ + { { 1, 5, 4795, 1, 2, 13, 0 }, 7, ASN_GAUGE, { .integer = 100 } }, + /* lldpXMedLocXPoEPDPowerSource */ + { { 1, 5, 4795, 1, 2, 14, 0 }, 7, ASN_INTEGER, { .integer = 3 } }, + /* lldpXMedLocXPoEPDPowerPriority */ + { { 1, 5, 4795, 1, 2, 15, 0 }, 7, ASN_INTEGER, { .integer = 3 } }, + + /* lldpXMedRemCapSupported */ + { { 1, 5, 4795, 1, 3, 1, 1, 1, 0, 3, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "\xFC", .len = 1 } } }, + { { 1, 5, 4795, 1, 3, 1, 1, 1, 10000, 4, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "\xFC", .len = 1 } } }, + /* lldpXMedRemCapCurrent */ + { { 1, 5, 4795, 1, 3, 1, 1, 2, 0, 3, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "\xFC", .len = 1 } } }, + { { 1, 5, 4795, 1, 3, 1, 1, 2, 10000, 4, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "\xEC", .len = 1 } } }, + /* lldpXMedRemDeviceClass */ + { { 1, 5, 4795, 1, 3, 1, 1, 3, 0, 3, 1 }, 11, ASN_INTEGER, { .integer = 2 } }, + { { 1, 5, 4795, 1, 3, 1, 1, 3, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 2 } }, + + /* lldpXMedRemMediaPolicyVlanID */ + { { 1, 5, 4795, 1, 3, 2, 1, 2, 0, 3, 1, 3 }, 12, ASN_INTEGER, + { .integer = 475 } }, + { { 1, 5, 4795, 1, 3, 2, 1, 2, 0, 3, 1, 6 }, 12, ASN_INTEGER, + { .integer = 1007 } }, + { { 1, 5, 4795, 1, 3, 2, 1, 2, 10000, 4, 1, 3 }, 12, ASN_INTEGER, + { .integer = 475 } }, + { { 1, 5, 4795, 1, 3, 2, 1, 2, 10000, 4, 1, 7 }, 12, ASN_INTEGER, + { .integer = 472 } }, + /* lldpXMedRemMediaPolicyPriority */ + { { 1, 5, 4795, 1, 3, 2, 1, 3, 0, 3, 1, 3 }, 12, ASN_INTEGER, + { .integer = 3 } }, + { { 1, 5, 4795, 1, 3, 2, 1, 3, 0, 3, 1, 6 }, 12, ASN_INTEGER, + { .integer = 1 } }, + { { 1, 5, 4795, 1, 3, 2, 1, 3, 10000, 4, 1, 3 }, 12, ASN_INTEGER, + { .integer = 3 } }, + { { 1, 5, 4795, 1, 3, 2, 1, 3, 10000, 4, 1, 7 }, 12, ASN_INTEGER, + { .integer = 1 } }, + /* lldpXMedLocMediaPolicyDscp */ + { { 1, 5, 4795, 1, 3, 2, 1, 4, 0, 3, 1, 3 }, 12, ASN_INTEGER, + { .integer = 62 } }, + { { 1, 5, 4795, 1, 3, 2, 1, 4, 0, 3, 1, 6 }, 12, ASN_INTEGER, + { .integer = 49 } }, + { { 1, 5, 4795, 1, 3, 2, 1, 4, 10000, 4, 1, 3 }, 12, ASN_INTEGER, + { .integer = 62 } }, + { { 1, 5, 4795, 1, 3, 2, 1, 4, 10000, 4, 1, 7 }, 12, ASN_INTEGER, + { .integer = 60 } }, + /* lldpXMedLocMediaPolicyUnknown */ + { { 1, 5, 4795, 1, 3, 2, 1, 5, 0, 3, 1, 3 }, 12, ASN_INTEGER, + { .integer = 1 } }, + { { 1, 5, 4795, 1, 3, 2, 1, 5, 0, 3, 1, 6 }, 12, ASN_INTEGER, + { .integer = 2 } }, + { { 1, 5, 4795, 1, 3, 2, 1, 5, 10000, 4, 1, 3 }, 12, ASN_INTEGER, + { .integer = 1 } }, + { { 1, 5, 4795, 1, 3, 2, 1, 5, 10000, 4, 1, 7 }, 12, ASN_INTEGER, + { .integer = 2 } }, + /* lldpXMedLocMediaPolicyTagged */ + { { 1, 5, 4795, 1, 3, 2, 1, 6, 0, 3, 1, 3 }, 12, ASN_INTEGER, + { .integer = 1 } }, + { { 1, 5, 4795, 1, 3, 2, 1, 6, 0, 3, 1, 6 }, 12, ASN_INTEGER, + { .integer = 2 } }, + { { 1, 5, 4795, 1, 3, 2, 1, 6, 10000, 4, 1, 3 }, 12, ASN_INTEGER, + { .integer = 1 } }, + { { 1, 5, 4795, 1, 3, 2, 1, 6, 10000, 4, 1, 7 }, 12, ASN_INTEGER, + { .integer = 1 } }, + + /* lldpXMedRemHardwareRev */ + { { 1, 5, 4795, 1, 3, 3, 1, 1, 0, 3, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "Hardware 1", .len = 10 } } }, + { { 1, 5, 4795, 1, 3, 3, 1, 1, 10000, 4, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "Hardware 1", .len = 10 } } }, + /* lldpXMedRemSoftwareRev */ + { { 1, 5, 4795, 1, 3, 3, 1, 3, 0, 3, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "Software 1", .len = 10 } } }, + { { 1, 5, 4795, 1, 3, 3, 1, 3, 10000, 4, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "Software 1", .len = 10 } } }, + /* lldpXMedRemSerialNum */ + { { 1, 5, 4795, 1, 3, 3, 1, 4, 0, 3, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "00-00-0000-AAAA", .len = 15 } } }, + { { 1, 5, 4795, 1, 3, 3, 1, 4, 10000, 4, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "00-00-0000-AAAA", .len = 15 } } }, + /* lldpXMedRemMfgName */ + { { 1, 5, 4795, 1, 3, 3, 1, 5, 0, 3, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "Manufacturer 1", .len = 14 } } }, + { { 1, 5, 4795, 1, 3, 3, 1, 5, 10000, 4, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "Manufacturer 1", .len = 14 } } }, + /* lldpXMedRemModelName */ + { { 1, 5, 4795, 1, 3, 3, 1, 6, 0, 3, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "Model 1", .len = 7 } } }, + { { 1, 5, 4795, 1, 3, 3, 1, 6, 10000, 4, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "Model 1", .len = 7 } } }, + /* lldpXMedRemAssetID */ + { { 1, 5, 4795, 1, 3, 3, 1, 7, 0, 3, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "Asset 1", .len = 7 } } }, + { { 1, 5, 4795, 1, 3, 3, 1, 7, 10000, 4, 1 }, 11, ASN_OCTET_STR, + { .string = { .octet = "Asset 1", .len = 7 } } }, + + /* lldpXMedLocLocationInfo */ + { { 1, 5, 4795, 1, 3, 4, 1, 2, 0, 3, 1, 2 }, 12, ASN_OCTET_STR, + { .string = { .octet = "Not interpreted", .len = 15 } } }, + { { 1, 5, 4795, 1, 3, 4, 1, 2, 10000, 4, 1, 3 }, 12, ASN_OCTET_STR, + { .string = { .octet = "\x15" + "\x02" + "FR" + "\x06" + "\x0d" + "Commercial Rd" + "\x13" + "\x01" + "4", + .len = 22 } } }, + + /* lldpXMedRemXPoEDeviceType */ + { { 1, 5, 4795, 1, 3, 5, 1, 1, 0, 3, 1 }, 11, ASN_INTEGER, { .integer = 4 } }, + { { 1, 5, 4795, 1, 3, 5, 1, 1, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 3 } }, + + /* lldpXMedRemXPoEPDPowerReq */ + { { 1, 5, 4795, 1, 3, 7, 1, 1, 10000, 4, 1 }, 11, ASN_GAUGE, + { .integer = 100 } }, + /* lldpXMedRemXPoEPDPowerSource */ + { { 1, 5, 4795, 1, 3, 7, 1, 2, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 3 } }, + /* lldpXMedRemXPoEPDPowerPriority */ + { { 1, 5, 4795, 1, 3, 7, 1, 3, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 3 } }, + +#endif +#ifdef ENABLE_DOT1 + /* lldpXdot1LocPortVlanId */ + { { 1, 5, 32962, 1, 2, 1, 1, 1, 3 }, 9, ASN_INTEGER, { .integer = 47 } }, + { { 1, 5, 32962, 1, 2, 1, 1, 1, 4 }, 9, ASN_INTEGER, { .integer = 0 } }, + /* lldpXdot1LocProtoVlanSupported */ + { { 1, 5, 32962, 1, 2, 2, 1, 2, 3, 47 }, 10, ASN_INTEGER, { .integer = 1 } }, + { { 1, 5, 32962, 1, 2, 2, 1, 2, 3, 118 }, 10, ASN_INTEGER, { .integer = 1 } }, + /* lldpXdot1LocProtoVlanEnabled */ + { { 1, 5, 32962, 1, 2, 2, 1, 3, 3, 47 }, 10, ASN_INTEGER, { .integer = 1 } }, + { { 1, 5, 32962, 1, 2, 2, 1, 3, 3, 118 }, 10, ASN_INTEGER, { .integer = 1 } }, + /* lldpXdot1LocVlanName */ + { { 1, 5, 32962, 1, 2, 3, 1, 2, 3, 47 }, 10, ASN_OCTET_STR, + { .string = { .octet = "VLAN #47", .len = 8 } } }, + { { 1, 5, 32962, 1, 2, 3, 1, 2, 3, 49 }, 10, ASN_OCTET_STR, + { .string = { .octet = "VLAN #49", .len = 8 } } }, + { { 1, 5, 32962, 1, 2, 3, 1, 2, 3, 1449 }, 10, ASN_OCTET_STR, + { .string = { .octet = "VLAN #1449", .len = 10 } } }, + /* lldpXdot1LocProtocolId */ + { { 1, 5, 32962, 1, 2, 4, 1, 2, 3, 30321 }, 10, ASN_OCTET_STR, + { .string = { .octet = "\x88\x8e\x01", .len = 3 } } }, + { { 1, 5, 32962, 1, 2, 4, 1, 2, 3, 30515 }, 10, ASN_OCTET_STR, + { .string = { .octet = "\x88\xcc", .len = 2 } } }, + + /* lldpXdot1RemPortVlanId */ + { { 1, 5, 32962, 1, 3, 1, 1, 1, 0, 3, 1 }, 11, ASN_INTEGER, { .integer = 0 } }, + { { 1, 5, 32962, 1, 3, 1, 1, 1, 8000, 3, 4 }, 11, ASN_INTEGER, + { .integer = 0 } }, + { { 1, 5, 32962, 1, 3, 1, 1, 1, 10000, 4, 1 }, 11, ASN_INTEGER, + { .integer = 47 } }, + /* lldpXdot1RemProtoVlanSupported */ + { { 1, 5, 32962, 1, 3, 2, 1, 2, 10000, 4, 1, 47 }, 12, ASN_INTEGER, + { .integer = 1 } }, + { { 1, 5, 32962, 1, 3, 2, 1, 2, 10000, 4, 1, 118 }, 12, ASN_INTEGER, + { .integer = 1 } }, + /* lldpXdot1RemProtoVlanEnabled */ + { { 1, 5, 32962, 1, 3, 2, 1, 3, 10000, 4, 1, 47 }, 12, ASN_INTEGER, + { .integer = 1 } }, + { { 1, 5, 32962, 1, 3, 2, 1, 3, 10000, 4, 1, 118 }, 12, ASN_INTEGER, + { .integer = 1 } }, + /* lldpXdot1RemVlanName */ + { { 1, 5, 32962, 1, 3, 3, 1, 2, 10000, 4, 1, 47 }, 12, ASN_OCTET_STR, + { .string = { .octet = "VLAN #47", .len = 8 } } }, + { { 1, 5, 32962, 1, 3, 3, 1, 2, 10000, 4, 1, 49 }, 12, ASN_OCTET_STR, + { .string = { .octet = "VLAN #49", .len = 8 } } }, + { { 1, 5, 32962, 1, 3, 3, 1, 2, 10000, 4, 1, 1449 }, 12, ASN_OCTET_STR, + { .string = { .octet = "VLAN #1449", .len = 10 } } }, + /* lldpXdot1RemProtocolId */ + { { 1, 5, 32962, 1, 3, 4, 1, 2, 10000, 4, 1, 30321 }, 12, ASN_OCTET_STR, + { .string = { .octet = "\x88\x8e\x01", .len = 3 } } }, + { { 1, 5, 32962, 1, 3, 4, 1, 2, 10000, 4, 1, 30515 }, 12, ASN_OCTET_STR, + { .string = { .octet = "\x88\xcc", .len = 2 } } } +#endif +}; + +static char * +tohex(char *str, size_t len) +{ + static char *hex[] = { NULL, NULL }; + static int which = 0; + free(hex[which]); + hex[which] = NULL; + hex[which] = malloc(len * 3 + 1); + fail_unless(hex[which] != NULL, "Not enough memory?"); + for (size_t i = 0; i < len; i++) + snprintf(hex[which] + 3 * i, 4, "%02X ", (unsigned char)str[i]); + which = 1 - which; + return hex[1 - which]; +} + +static int +snmp_is_prefix_of(struct variable8 *vp, struct tree_node *n, char *repr) +{ + if (n->namelen < vp->namelen) return 0; + if (memcmp(n->name, vp->name, vp->namelen * sizeof(oid))) return 0; + fail_unless(n->type == vp->type, "Inappropriate type for OID %s", repr); + return 1; +} + +static void +snmp_merge(struct variable8 *v1, struct tree_node *n, struct variable *vp, oid *target, + size_t *targetlen) +{ + vp->magic = v1->magic; + vp->type = v1->type; + vp->acl = v1->acl; + vp->findVar = v1->findVar; + vp->namelen = v1->namelen + sizeof(lldp_oid) / sizeof(oid); + memcpy(vp->name, lldp_oid, sizeof(lldp_oid)); + memcpy(vp->name + sizeof(lldp_oid) / sizeof(oid), v1->name, + v1->namelen * sizeof(oid)); + *targetlen = n->namelen + sizeof(lldp_oid) / sizeof(oid); + memcpy(target, lldp_oid, sizeof(lldp_oid)); + memcpy(target + sizeof(lldp_oid) / sizeof(oid), n->name, + n->namelen * sizeof(oid)); +} + +static void +snmp_compare(struct tree_node *n, u_char *result, size_t varlen, oid *target, + size_t targetlen, char *repr) +{ + unsigned long int value; + fail_unless((targetlen == sizeof(lldp_oid) / sizeof(oid) + n->namelen) && + !memcmp(target, lldp_oid, sizeof(lldp_oid)) && + !memcmp(target + sizeof(lldp_oid) / sizeof(oid), n->name, + n->namelen * sizeof(oid)), + "Bad OID returned when querying %s: got %s", repr, + snmp_oidrepr(target, targetlen)); + switch (n->type) { + case ASN_INTEGER: + case ASN_TIMETICKS: + case ASN_GAUGE: + case ASN_COUNTER: + fail_unless(varlen == sizeof(unsigned long int), + "Inappropriate length for integer type for OID %s", repr); + memcpy(&value, result, sizeof(value)); + fail_unless(n->value.integer == value, + "For OID %s, expected value %lu but got %lu instead", repr, + n->value.integer, value); + break; + default: + fail_unless(((n->value.string.len == varlen) && + !memcmp(n->value.string.octet, result, varlen)), + "OID %s: wanted %s, got %s", repr, + tohex(n->value.string.octet, n->value.string.len), + tohex((char *)result, varlen)); + } +} + +START_TEST(test_variable_order) +{ + size_t i; + for (i = 0; i < agent_lldp_vars_size() - 1; i++) { + fail_unless(snmp_oid_compare(agent_lldp_vars[i].name, + agent_lldp_vars[i].namelen, agent_lldp_vars[i + 1].name, + agent_lldp_vars[i + 1].namelen) < 0, + "Registered OID are out of orders (see %s and next one)", + snmp_oidrepr(agent_lldp_vars[i].name, agent_lldp_vars[i].namelen)); + } +} +END_TEST + +START_TEST(test_get) +{ + size_t j; + for (j = 0; j < sizeof(snmp_tree) / sizeof(struct tree_node); j++) { + size_t i; + int found = 0; + struct variable vp; + oid target[MAX_OID_LEN]; + size_t targetlen; + size_t varlen; + u_char *result; + WriteMethod *wmethod; + char *repr = snmp_oidrepr(snmp_tree[j].name, snmp_tree[j].namelen); + + for (i = 0; i < agent_lldp_vars_size(); i++) { + /* Search for the appropriate prefix. */ + if (!snmp_is_prefix_of(&agent_lldp_vars[i], &snmp_tree[j], + repr)) + continue; + + /* We have our prefix. Fill out the vp struct + correctly. We need to complete OID with + LLDP prefix. */ + snmp_merge(&agent_lldp_vars[i], &snmp_tree[j], &vp, target, + &targetlen); + + /* Invoke the function */ + result = + vp.findVar(&vp, target, &targetlen, 1, &varlen, &wmethod); + + /* Check the result */ + fail_unless(result != NULL, "No result when querying %s", repr); + snmp_compare(&snmp_tree[j], result, varlen, target, targetlen, + repr); + + found = 1; + break; + } + if (!found) fail("OID %s not found", repr); + } +} +END_TEST + +START_TEST(test_getnext) +{ + size_t j; + size_t end = sizeof(snmp_tree) / sizeof(struct tree_node); + for (j = 0; j < end; j++) { + size_t i; + struct variable vp; + oid target[MAX_OID_LEN]; + size_t targetlen; + size_t varlen; + u_char *result = NULL; + WriteMethod *wmethod; + char *repr = snmp_oidrepr(snmp_tree[j].name, snmp_tree[j].namelen); + for (i = 0; i < agent_lldp_vars_size(); i++) { + snmp_merge(&agent_lldp_vars[i], &snmp_tree[j], &vp, target, + &targetlen); + result = + vp.findVar(&vp, target, &targetlen, 0, &varlen, &wmethod); + if (result) /* Check next! */ + break; + } + if (!result) { + fail_unless(j == end - 1, "No next result found for %s", repr); + return; + } + fail_unless(j < end - 1, "More results after %s", repr); + + /* For unknown reasons, snmp_compare can be executed + even when the above test fails... */ + if (j < end - 1) + snmp_compare(&snmp_tree[j + 1], result, varlen, target, + targetlen, repr); + } +} +END_TEST + +static Suite * +snmp_suite(void) +{ + Suite *s = suite_create("SNMP"); + + TCase *tc_snmp = tcase_create("SNMP"); + tcase_add_checked_fixture(tc_snmp, snmp_config, NULL); + tcase_add_test(tc_snmp, test_variable_order); + tcase_add_test(tc_snmp, test_get); + tcase_add_test(tc_snmp, test_getnext); + suite_add_tcase(s, tc_snmp); + + return s; +} + +int +main() +{ + int number_failed; + Suite *s = snmp_suite(); + SRunner *sr = srunner_create(s); + srunner_run_all(sr, CK_ENV); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/tests/check_sonmp.c b/tests/check_sonmp.c new file mode 100644 index 0000000..604f5e3 --- /dev/null +++ b/tests/check_sonmp.c @@ -0,0 +1,221 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2015 Vincent Bernat <bernat@luffy.cx> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdlib.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <check.h> +#include "common.h" + +char filenameprefix[] = "sonmp_send"; + +#ifdef ENABLE_SONMP + +START_TEST(test_send_sonmp) +{ + int n; + /* Packet we should build: +IEEE 802.3 Ethernet + Destination: Bay-Networks-(Synoptics)-autodiscovery (01:00:81:00:01:00) + Source: 5e:10:8e:e7:84:ad (5e:10:8e:e7:84:ad) + Length: 19 +Logical-Link Control + DSAP: SNAP (0xaa) + IG Bit: Individual + SSAP: SNAP (0xaa) + CR Bit: Command + Control field: U, func=UI (0x03) + 000. 00.. = Command: Unnumbered Information (0x00) + .... ..11 = Frame type: Unnumbered frame (0x03) + Organization Code: Nortel Networks SONMP (0x000081) + PID: SONMP segment hello (0x01a2) +Nortel Networks / SynOptics Network Management Protocol + NMM IP address: 172.17.142.37 (172.17.142.37) + Segment Identifier: 0x000004 + Chassis type: Unknown (1) + Backplane type: ethernet, fast ethernet and gigabit ethernet (12) + NMM state: New (3) + Number of links: 1 + +IEEE 802.3 Ethernet + Destination: Bay-Networks-(Synoptics)-autodiscovery (01:00:81:00:01:01) + Source: 5e:10:8e:e7:84:ad (5e:10:8e:e7:84:ad) + Length: 19 +Logical-Link Control + DSAP: SNAP (0xaa) + IG Bit: Individual + SSAP: SNAP (0xaa) + CR Bit: Command + Control field: U, func=UI (0x03) + 000. 00.. = Command: Unnumbered Information (0x00) + .... ..11 = Frame type: Unnumbered frame (0x03) + Organization Code: Nortel Networks SONMP (0x000081) + PID: SONMP flatnet hello (0x01a1) +Nortel Networks / SynOptics Network Management Protocol + NMM IP address: 172.17.142.37 (172.17.142.37) + Segment Identifier: 0x000004 + Chassis type: Unknown (1) + Backplane type: ethernet, fast ethernet and gigabit ethernet (12) + NMM state: New (3) + Number of links: 1 + */ + char pkt1[] = { 0x01, 0x00, 0x81, 0x00, 0x01, 0x00, 0x5e, 0x10, 0x8e, 0xe7, + 0x84, 0xad, 0x00, 0x13, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x81, 0x01, 0xa2, + 0xac, 0x11, 0x8e, 0x25, 0x00, 0x00, 0x04, 0x01, 0x0c, 0x03, 0x01 }; + char pkt2[] = { 0x01, 0x00, 0x81, 0x00, 0x01, 0x01, 0x5e, 0x10, 0x8e, 0xe7, + 0x84, 0xad, 0x00, 0x13, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x81, 0x01, 0xa1, + 0xac, 0x11, 0x8e, 0x25, 0x00, 0x00, 0x04, 0x01, 0x0c, 0x03, 0x01 }; + struct packet *pkt; + in_addr_t addr; + struct lldpd_mgmt *mgmt; + + /* Populate port and chassis */ + hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_IFNAME; + hardware.h_lport.p_id = "Not used"; + hardware.h_lport.p_id_len = strlen(hardware.h_lport.p_id); + chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR; + chassis.c_id = macaddress; + chassis.c_id_len = ETHER_ADDR_LEN; + TAILQ_INIT(&chassis.c_mgmt); + addr = inet_addr("172.17.142.37"); + mgmt = lldpd_alloc_mgmt(LLDPD_AF_IPV4, &addr, sizeof(in_addr_t), 0); + if (mgmt == NULL) ck_abort(); + TAILQ_INSERT_TAIL(&chassis.c_mgmt, mgmt, m_entries); + + /* Build packet */ + n = sonmp_send(NULL, &hardware); + if (n != 0) { + fail("unable to build packet"); + return; + } + if (TAILQ_EMPTY(&pkts)) { + fail("no packets sent"); + return; + } + pkt = TAILQ_FIRST(&pkts); + ck_assert_int_eq(pkt->size, sizeof(pkt1)); + fail_unless(memcmp(pkt->data, pkt1, sizeof(pkt1)) == 0); + pkt = TAILQ_NEXT(pkt, next); + if (!pkt) { + fail("need one more packet"); + return; + } + ck_assert_int_eq(pkt->size, sizeof(pkt2)); + fail_unless(memcmp(pkt->data, pkt2, sizeof(pkt2)) == 0); + fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than two packets sent"); +} +END_TEST + +START_TEST(test_recv_sonmp) +{ + char pkt1[] = { 0x01, 0x00, 0x81, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x25, 0x08, + 0x50, 0x47, 0x00, 0x13, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x81, 0x01, 0xa2, + 0xac, 0x10, 0x65, 0xa8, 0x00, 0x02, 0x08, 0x38, 0x0c, 0x02, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 }; + /* This is: +IEEE 802.3 Ethernet + Destination: Bay-Networks-(Synoptics)-autodiscovery (01:00:81:00:01:00) + Source: Nortel_08:50:47 (00:1b:25:08:50:47) + Length: 19 + Trailer: 000000000000000000000000000000000000000000000000... +Logical-Link Control + DSAP: SNAP (0xaa) + IG Bit: Individual + SSAP: SNAP (0xaa) + CR Bit: Command + Control field: U, func=UI (0x03) + 000. 00.. = Command: Unnumbered Information (0x00) + .... ..11 = Frame type: Unnumbered frame (0x03) + Organization Code: Nortel Networks SONMP (0x000081) + PID: SONMP segment hello (0x01a2) +Nortel Networks / SynOptics Network Management Protocol + NMM IP address: 172.16.101.168 (172.16.101.168) + Segment Identifier: 0x000208 + Chassis type: Accelar 8610 L3 switch (56) + Backplane type: ethernet, fast ethernet and gigabit ethernet (12) + NMM state: Heartbeat (2) + Number of links: 1 + */ + struct lldpd_chassis *nchassis = NULL; + struct lldpd_port *nport = NULL; + char cid[5]; + in_addr_t ip; + + fail_unless( + sonmp_decode(NULL, pkt1, sizeof(pkt1), &hardware, &nchassis, &nport) != -1); + if (!nchassis || !nport) { + fail("unable to decode packet"); + return; + } + ck_assert_int_eq(nchassis->c_id_subtype, LLDP_CHASSISID_SUBTYPE_ADDR); + ck_assert_int_eq(nchassis->c_id_len, 5); + cid[0] = 1; + ip = inet_addr("172.16.101.168"); + memcpy(cid + 1, &ip, sizeof(in_addr_t)); + fail_unless(memcmp(nchassis->c_id, cid, 5) == 0); + ck_assert_str_eq(nchassis->c_name, "172.16.101.168"); + ck_assert_str_eq(nchassis->c_descr, "Nortel Ethernet Routing 8610 L3 Switch"); + ck_assert_int_eq(TAILQ_FIRST(&nchassis->c_mgmt)->m_addr.inet.s_addr, + (u_int32_t)inet_addr("172.16.101.168")); + ck_assert_int_eq(TAILQ_FIRST(&nchassis->c_mgmt)->m_iface, 0); + ck_assert_str_eq(nport->p_descr, "port 2/8"); + ck_assert_int_eq(nport->p_id_subtype, LLDP_PORTID_SUBTYPE_LOCAL); + ck_assert_int_eq(nport->p_id_len, strlen("00-02-08")); + fail_unless(memcmp(nport->p_id, "00-02-08", strlen("00-02-08")) == 0); + ck_assert_int_eq(nchassis->c_cap_enabled, 0); +} +END_TEST + +#endif + +static Suite * +sonmp_suite(void) +{ + Suite *s = suite_create("SONMP"); + +#ifdef ENABLE_SONMP + TCase *tc_send = tcase_create("Send SONMP packets"); + TCase *tc_receive = tcase_create("Receive SONMP packets"); + + tcase_add_checked_fixture(tc_send, pcap_setup, pcap_teardown); + tcase_add_test(tc_send, test_send_sonmp); + suite_add_tcase(s, tc_send); + + tcase_add_test(tc_receive, test_recv_sonmp); + suite_add_tcase(s, tc_receive); +#endif + + return s; +} + +int +main() +{ + int number_failed; + Suite *s = sonmp_suite(); + SRunner *sr = srunner_create(s); + srunner_set_fork_status(sr, CK_NOFORK); /* Can't fork because + we need to write + files */ + srunner_run_all(sr, CK_ENV); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/tests/common.c b/tests/common.c new file mode 100644 index 0000000..ec2a7ca --- /dev/null +++ b/tests/common.c @@ -0,0 +1,153 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2015 Vincent Bernat <bernat@luffy.cx> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <time.h> +#include <fcntl.h> +#include <check.h> +#include "common.h" + +int dump = -1; +char *filename = NULL; +struct pkts_t pkts; +char macaddress[ETHER_ADDR_LEN] = { 0x5e, 0x10, 0x8e, 0xe7, 0x84, 0xad }; +struct lldpd_hardware hardware; +struct lldpd_chassis chassis; + +int +pcap_send(struct lldpd *cfg, struct lldpd_hardware *hardware, char *buffer, size_t size) +{ + struct pcaprec_hdr hdr; + struct packet *pkt; + int n; + + /* Write pcap record header */ + hdr.ts_sec = time(NULL); + hdr.ts_usec = 0; + hdr.incl_len = hdr.orig_len = size; + n = write(dump, &hdr, sizeof(hdr)); + if (n == 1) { + fail("unable to write pcap record header to %s", filename); + return -1; + } + + /* Write data */ + n = write(dump, buffer, size); + if (n == -1) { + fail("unable to write pcap data to %s", filename); + return -1; + } + + /* Append to list of packets */ + pkt = + (struct packet *)malloc(size + sizeof(TAILQ_HEAD(, packet)) + sizeof(int)); + if (!pkt) { + fail("unable to allocate packet"); + return -1; + } + memcpy(pkt->data, buffer, size); + pkt->size = size; + TAILQ_INSERT_TAIL(&pkts, pkt, next); + return 0; +} + +struct lldpd_ops pcap_ops = { + .send = pcap_send, + .recv = NULL, /* Won't be used */ + .cleanup = NULL, /* Won't be used */ +}; + +void +pcap_setup(void) +{ + static int serial = 0; + struct pcap_hdr hdr; + int n; + /* Prepare packet buffer */ + TAILQ_INIT(&pkts); + /* Open a new dump file */ + n = asprintf(&filename, "%s_%04d.pcap", filenameprefix, serial++); + if (n == -1) { + fail("unable to compute filename"); + return; + } + dump = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (dump == -1) { + fail("unable to open %s", filename); + return; + } + /* Write a PCAP header */ + hdr.magic_number = 0xa1b2c3d4; + hdr.version_major = 2; + hdr.version_minor = 4; + hdr.thiszone = 0; + hdr.sigfigs = 0; + hdr.snaplen = 65535; + hdr.network = 1; + n = write(dump, &hdr, sizeof(hdr)); + if (n == -1) { + fail("unable to write pcap header to %s", filename); + return; + } + /* Prepare hardware */ + memset(&hardware, 0, sizeof(struct lldpd_hardware)); + TAILQ_INIT(&hardware.h_rports); +#ifdef ENABLE_DOT1 + TAILQ_INIT(&hardware.h_lport.p_vlans); + TAILQ_INIT(&hardware.h_lport.p_ppvids); + TAILQ_INIT(&hardware.h_lport.p_pids); +#endif + hardware.h_mtu = 1500; + hardware.h_ifindex = 4; + strlcpy(hardware.h_ifname, "test", sizeof(hardware.h_ifname)); + memcpy(hardware.h_lladdr, macaddress, ETHER_ADDR_LEN); + hardware.h_ops = &pcap_ops; + /* Prepare chassis */ + memset(&chassis, 0, sizeof(struct lldpd_chassis)); + hardware.h_lport.p_chassis = &chassis; +} + +void +pcap_teardown() +{ + struct packet *npkt, *pkt; + for (pkt = TAILQ_FIRST(&pkts); pkt != NULL; pkt = npkt) { + npkt = TAILQ_NEXT(pkt, next); + TAILQ_REMOVE(&pkts, pkt, next); + free(pkt); + } + if (dump != -1) { + close(dump); + dump = -1; + } + if (filename) { + free(filename); + filename = NULL; + } +} + +/* Disable leak detection sanitizer */ +int __lsan_is_turned_off(void); +int +__lsan_is_turned_off(void) +{ + return 1; +} diff --git a/tests/common.h b/tests/common.h new file mode 100644 index 0000000..a5fe275 --- /dev/null +++ b/tests/common.h @@ -0,0 +1,45 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2015 Vincent Bernat <bernat@luffy.cx> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _COMMON_H +#define _COMMON_H + +#include "check-compat.h" +#include "pcap-hdr.h" +#include "../src/daemon/lldpd.h" + +struct packet { + TAILQ_ENTRY(packet) next; + int size; + char data[]; +}; +TAILQ_HEAD(pkts_t, packet); + +extern int dump; /* Dump file descriptor in pcap format */ +extern char filenameprefix[]; /* Prefix for filename dumping */ +extern char *filename; /* Filename we are dumping to */ +extern char macaddress[]; /* MAC address we use to send */ + +extern struct pkts_t pkts; /* List of sent packets */ +extern struct lldpd_hardware hardware; +extern struct lldpd_chassis chassis; + +int pcap_send(struct lldpd *, struct lldpd_hardware *, char *, size_t); +void pcap_setup(void); +void pcap_teardown(void); + +#endif diff --git a/tests/decode.c b/tests/decode.c new file mode 100644 index 0000000..cbe832b --- /dev/null +++ b/tests/decode.c @@ -0,0 +1,265 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2015 Vincent Bernat <bernat@luffy.cx> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdlib.h> +#include <unistd.h> +#include <inttypes.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <arpa/inet.h> +#include "pcap-hdr.h" +#include "../src/daemon/lldpd.h" + +#define BUFSIZE 2000 + +static char * +tohex(char *str, size_t len) +{ + static char *hex = NULL; + free(hex); + hex = NULL; + if ((hex = malloc(len * 3 + 1)) == NULL) return NULL; + for (size_t i = 0; i < len; i++) + snprintf(hex + 3 * i, 4, "%02X ", (unsigned char)str[i]); + return hex; +} + +/* We need an assert macro which doesn't abort */ +#define assert(x) \ + while (!(x)) { \ + fprintf(stderr, "%s:%d: %s: Assertion `%s' failed.\n", __FILE__, __LINE__, \ + __func__, #x); \ + exit(5); \ + } + +static int +decode(char *frame, int size, struct lldpd_hardware *hardware, + struct lldpd_chassis **nchassis, struct lldpd_port **nport) +{ + /* For decoding, we only need a very basic hardware */ + memset(hardware, 0, sizeof(struct lldpd_hardware)); + hardware->h_mtu = 1500; + strlcpy(hardware->h_ifname, "test", sizeof(hardware->h_ifname)); + + int decoded = 0; + if (lldp_decode(NULL, frame, size, hardware, nchassis, nport) == -1) { + fprintf(stderr, "Not decoded as a LLDP frame\n"); + } else { + fprintf(stderr, "Decoded as a LLDP frame\n"); + decoded = 1; + } +#if defined ENABLE_CDP || defined ENABLE_FDP + if (cdp_decode(NULL, frame, size, hardware, nchassis, nport) == -1) { + fprintf(stderr, "Not decoded as a CDP frame\n"); + } else { + fprintf(stderr, "Decoded as a CDP frame\n"); + decoded = 1; + } +#endif +#ifdef ENABLE_SONMP + if (sonmp_decode(NULL, frame, size, hardware, nchassis, nport) == -1) { + fprintf(stderr, "Not decoded as a SONMP frame\n"); + } else { + fprintf(stderr, "Decoded as a SONMP frame\n"); + decoded = 1; + } +#endif +#ifdef ENABLE_EDP + if (edp_decode(NULL, frame, size, hardware, nchassis, nport) == -1) { + fprintf(stderr, "Not decoded as a EDP frame\n"); + } else { + fprintf(stderr, "Decoded as a EDP frame\n"); + decoded = 1; + } +#endif + return decoded; +} + +static void +usage(void) +{ + fprintf(stderr, "Usage: %s PCAP\n", "decode"); + fprintf(stderr, "Version: %s\n", PACKAGE_STRING); + + fprintf(stderr, "\n"); + + fprintf(stderr, "Decode content of PCAP files and display a summary\n"); + fprintf(stderr, "on standard output. Only the first packet is decoded.\n"); + exit(1); +} + +int +main(int argc, char **argv) +{ + if (argc != 2 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) usage(); + + int fd = open(argv[1], O_RDONLY); + assert(fd != -1); + + char buf[BUFSIZE]; + ssize_t len = read(fd, buf, BUFSIZE); + assert(len != -1); + + struct pcap_hdr hdr; + assert(len >= sizeof(hdr)); + memcpy(&hdr, buf, sizeof(hdr)); + assert(hdr.magic_number == 0xa1b2c3d4); /* Assume the same byte order as us */ + assert(hdr.version_major == 2); + assert(hdr.version_minor == 4); + assert(hdr.thiszone == 0); + /* Don't care about other flags */ + + struct pcaprec_hdr rechdr; + assert(len >= sizeof(hdr) + sizeof(rechdr)); + memcpy(&rechdr, buf + sizeof(hdr), sizeof(rechdr)); + assert(len >= sizeof(hdr) + sizeof(rechdr) + rechdr.incl_len); + + struct lldpd_hardware hardware; + struct lldpd_chassis *nchassis = NULL; + struct lldpd_port *nport = NULL; + if (!decode(buf + sizeof(hdr) + sizeof(rechdr), rechdr.incl_len, &hardware, + &nchassis, &nport)) + exit(1); + + printf("Chassis:\n"); + printf(" Index: %" PRIu16 "\n", nchassis->c_index); + printf(" Protocol: %" PRIu8 "\n", nchassis->c_protocol); + printf(" ID subtype: %" PRIu8 "\n", nchassis->c_id_subtype); + printf(" ID: %s\n", tohex(nchassis->c_id, nchassis->c_id_len)); + printf(" Name: %s\n", nchassis->c_name ? nchassis->c_name : "(null)"); + printf(" Description: %s\n", nchassis->c_descr ? nchassis->c_descr : "(null)"); + printf(" Cap available: %" PRIu16 "\n", nchassis->c_cap_available); + printf(" Cap enabled: %" PRIu16 "\n", nchassis->c_cap_enabled); + struct lldpd_mgmt *mgmt; + TAILQ_FOREACH (mgmt, &nchassis->c_mgmt, m_entries) { + char ipaddress[INET6_ADDRSTRLEN + 1]; + int af; + size_t alen; + switch (mgmt->m_family) { + case LLDPD_AF_IPV4: + alen = INET_ADDRSTRLEN + 1; + af = AF_INET; + break; + case LLDPD_AF_IPV6: + alen = INET6_ADDRSTRLEN + 1; + af = AF_INET6; + break; + default: + len = 0; + } + if (len == 0) continue; + if (inet_ntop(af, &mgmt->m_addr, ipaddress, alen) == NULL) break; + printf(" mgmt: %s\n", ipaddress); + } +#ifdef ENABLE_LLDPMED + printf(" MED cap: %" PRIu16 "\n", nchassis->c_med_cap_available); + printf(" MED type: %" PRIu8 "\n", nchassis->c_med_type); + printf(" MED HW: %s\n", nchassis->c_med_hw ? nchassis->c_med_hw : "(null)"); + printf(" MED FW: %s\n", nchassis->c_med_fw ? nchassis->c_med_fw : "(null)"); + printf(" MED SW: %s\n", nchassis->c_med_sw ? nchassis->c_med_sw : "(null)"); + printf(" MED SN: %s\n", nchassis->c_med_sn ? nchassis->c_med_sn : "(null)"); + printf(" MED manufacturer: %s\n", + nchassis->c_med_manuf ? nchassis->c_med_manuf : "(null)"); + printf(" MED model: %s\n", + nchassis->c_med_model ? nchassis->c_med_model : "(null)"); + printf(" MED asset: %s\n", + nchassis->c_med_asset ? nchassis->c_med_asset : "(null)"); +#endif + + printf("Port:\n"); + printf(" ID subtype: %" PRIu8 "\n", nport->p_id_subtype); + printf(" ID: %s\n", tohex(nport->p_id, nport->p_id_len)); + printf(" Description: %s\n", nport->p_descr ? nport->p_descr : "(null)"); + printf(" MFS: %" PRIu16 "\n", nport->p_mfs); + printf(" TTL: %" PRIu16 "\n", nport->p_ttl); +#ifdef ENABLE_DOT3 + printf(" Dot3 aggrID: %" PRIu32 "\n", nport->p_aggregid); + printf(" Dot3 MAC/phy autoneg supported: %" PRIu8 "\n", + nport->p_macphy.autoneg_support); + printf(" Dot3 MAC/phy autoneg enabled: %" PRIu8 "\n", + nport->p_macphy.autoneg_enabled); + printf(" Dot3 MAC/phy autoneg advertised: %" PRIu16 "\n", + nport->p_macphy.autoneg_advertised); + printf(" Dot3 MAC/phy MAU type: %" PRIu16 "\n", nport->p_macphy.mau_type); + printf(" Dot3 power device type: %" PRIu8 "\n", nport->p_power.devicetype); + printf(" Dot3 power supported: %" PRIu8 "\n", nport->p_power.supported); + printf(" Dot3 power enabled: %" PRIu8 "\n", nport->p_power.enabled); + printf(" Dot3 power pair control: %" PRIu8 "\n", nport->p_power.paircontrol); + printf(" Dot3 power pairs: %" PRIu8 "\n", nport->p_power.pairs); + printf(" Dot3 power class: %" PRIu8 "\n", nport->p_power.class); + printf(" Dot3 power type: %" PRIu8 "\n", nport->p_power.powertype); + printf(" Dot3 power source: %" PRIu8 "\n", nport->p_power.source); + printf(" Dot3 power priority: %" PRIu8 "\n", nport->p_power.priority); + printf(" Dot3 power requested: %" PRIu16 "\n", nport->p_power.requested); + printf(" Dot3 power allocated: %" PRIu16 "\n", nport->p_power.allocated); +#endif +#ifdef ENABLE_LLDPMED + printf(" MED cap: %" PRIu16 "\n", nport->p_med_cap_enabled); + for (int i = 0; i < LLDP_MED_APPTYPE_LAST; i++) { + if (nport->p_med_policy[i].type == 0) continue; + printf(" MED policy type: %" PRIu8 "\n", nport->p_med_policy[i].type); + printf(" MED policy unknown: %" PRIu8 "\n", + nport->p_med_policy[i].unknown); + printf(" MED policy tagged: %" PRIu8 "\n", + nport->p_med_policy[i].tagged); + printf(" MED policy vid: %" PRIu16 "\n", nport->p_med_policy[i].vid); + printf(" MED policy priority: %" PRIu8 "\n", + nport->p_med_policy[i].priority); + printf(" MED policy dscp: %" PRIu8 "\n", nport->p_med_policy[i].dscp); + } + for (int i = 0; i < LLDP_MED_LOCFORMAT_LAST; i++) { + if (nport->p_med_location[i].format == 0) continue; + printf(" MED location format: %" PRIu8 "\n", + nport->p_med_location[i].format); + printf(" MED location: %s\n", + tohex(nport->p_med_location[i].data, + nport->p_med_location[i].data_len)); + } + printf(" MED power device type: %" PRIu8 "\n", nport->p_med_power.devicetype); + printf(" MED power source: %" PRIu8 "\n", nport->p_med_power.source); + printf(" MED power priority: %" PRIu8 "\n", nport->p_med_power.priority); + printf(" MED power value: %" PRIu16 "\n", nport->p_med_power.val); +#endif +#ifdef ENABLE_DOT1 + printf(" Dot1 PVID: %" PRIu16 "\n", nport->p_pvid); + struct lldpd_vlan *vlan; + TAILQ_FOREACH (vlan, &nport->p_vlans, v_entries) { + printf(" Dot1 VLAN: %s (%" PRIu16 ")\n", vlan->v_name, vlan->v_vid); + } + struct lldpd_ppvid *ppvid; + TAILQ_FOREACH (ppvid, &nport->p_ppvids, p_entries) { + printf(" Dot1 PPVID: %" PRIu16 " (status: %" PRIu8 ")\n", + ppvid->p_ppvid, ppvid->p_cap_status); + } + struct lldpd_pi *pid; + TAILQ_FOREACH (pid, &nport->p_pids, p_entries) { + printf(" Dot1 PI: %s\n", tohex(pid->p_pi, pid->p_pi_len)); + } +#endif +#ifdef ENABLE_CUSTOM + struct lldpd_custom *custom; + TAILQ_FOREACH (custom, &nport->p_custom_list, next) { + printf(" Custom OUI: %s\n", + tohex((char *)custom->oui, sizeof(custom->oui))); + printf(" Custom subtype: %" PRIu8 "\n", custom->subtype); + printf(" Custom info: %s\n", + tohex((char *)custom->oui_info, custom->oui_info_len)); + } +#endif + exit(0); +} diff --git a/tests/fuzz_cdp.c b/tests/fuzz_cdp.c new file mode 100644 index 0000000..e0fa569 --- /dev/null +++ b/tests/fuzz_cdp.c @@ -0,0 +1,54 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2023 Vincent Bernat <bernat@luffy.cx> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "../src/daemon/lldpd.h" + +#define kMinInputLength 5 +#define kMaxInputLength 2048 + +/* Use this callback to avoid some logs */ +void donothing(int pri, const char *msg) {}; + +extern int +LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{ + if (Size < kMinInputLength || Size > kMaxInputLength) { + return 1; + } + + struct lldpd_chassis *nchassis = NULL; + struct lldpd_port *nport = NULL; + struct lldpd_hardware hardware; + + log_register(donothing); + + if (!cdpv2_guess((char *)Data, Size)) { + return 1; + } + + cdp_decode(NULL, (char *)Data, Size, &hardware, &nchassis, &nport); + + if (!nchassis || !nport) { + return 1; + } + + lldpd_port_cleanup(nport, 1); + free(nport); + lldpd_chassis_cleanup(nchassis, 1); + + return 0; +} diff --git a/tests/fuzz_edp.c b/tests/fuzz_edp.c new file mode 100644 index 0000000..c670c5c --- /dev/null +++ b/tests/fuzz_edp.c @@ -0,0 +1,54 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2023 Vincent Bernat <bernat@luffy.cx> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "../src/daemon/lldpd.h" + +#define kMinInputLength 5 +#define kMaxInputLength 2048 + +/* Use this callback to avoid some logs */ +void donothing(int pri, const char *msg) {}; + +extern int +LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{ + if (Size < kMinInputLength || Size > kMaxInputLength) { + return 1; + } + + struct lldpd cfg; + cfg.g_config.c_mgmt_pattern = NULL; + cfg.g_config.c_tx_hold = LLDPD_TX_HOLD; + + struct lldpd_chassis *nchassis = NULL; + struct lldpd_port *nport = NULL; + struct lldpd_hardware hardware; + TAILQ_INIT(&hardware.h_rports); + log_register(donothing); + + edp_decode(&cfg, (char *)Data, Size, &hardware, &nchassis, &nport); + + if (!nchassis || !nport) { + return 1; + } + + lldpd_port_cleanup(nport, 1); + free(nport); + lldpd_chassis_cleanup(nchassis, 1); + + return 0; +} diff --git a/tests/fuzz_lldp.c b/tests/fuzz_lldp.c new file mode 100644 index 0000000..62b812a --- /dev/null +++ b/tests/fuzz_lldp.c @@ -0,0 +1,50 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2023 Vincent Bernat <bernat@luffy.cx> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "../src/daemon/lldpd.h" + +#define kMinInputLength 5 +#define kMaxInputLength 2048 + +/* Use this callback to avoid some logs */ +void donothing(int pri, const char *msg) {}; + +extern int +LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{ + if (Size < kMinInputLength || Size > kMaxInputLength) { + return 1; + } + + struct lldpd_chassis *nchassis = NULL; + struct lldpd_port *nport = NULL; + struct lldpd_hardware hardware; + + log_register(donothing); + + lldp_decode(NULL, (char *)Data, Size, &hardware, &nchassis, &nport); + + if (!nchassis || !nport) { + return 1; + } + + lldpd_port_cleanup(nport, 1); + free(nport); + lldpd_chassis_cleanup(nchassis, 1); + + return 0; +} diff --git a/tests/fuzz_sonmp.c b/tests/fuzz_sonmp.c new file mode 100644 index 0000000..0594673 --- /dev/null +++ b/tests/fuzz_sonmp.c @@ -0,0 +1,50 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2023 Vincent Bernat <bernat@luffy.cx> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "../src/daemon/lldpd.h" + +#define kMinInputLength 5 +#define kMaxInputLength 2048 + +/* Use this callback to avoid some logs */ +void donothing(int pri, const char *msg) {}; + +extern int +LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{ + if (Size < kMinInputLength || Size > kMaxInputLength) { + return 1; + } + + struct lldpd_chassis *nchassis = NULL; + struct lldpd_port *nport = NULL; + struct lldpd_hardware hardware; + + log_register(donothing); + + sonmp_decode(NULL, (char *)Data, Size, &hardware, &nchassis, &nport); + + if (!nchassis || !nport) { + return 1; + } + + lldpd_port_cleanup(nport, 1); + free(nport); + lldpd_chassis_cleanup(nchassis, 1); + + return 0; +} diff --git a/tests/pcap-hdr.h b/tests/pcap-hdr.h new file mode 100644 index 0000000..a08905b --- /dev/null +++ b/tests/pcap-hdr.h @@ -0,0 +1,25 @@ +#ifndef _PCAP_HDR_H +#define _PCAP_HDR_H + +#include <stdint.h> + +/* See: + * http://wiki.wireshark.org/Development/LibpcapFileFormat + */ +struct pcap_hdr { + uint32_t magic_number; /* magic number */ + uint16_t version_major; /* major version number */ + uint16_t version_minor; /* minor version number */ + uint32_t thiszone; /* GMT to local correction */ + uint32_t sigfigs; /* accuracy of timestamps */ + uint32_t snaplen; /* max length of captured packets, in octets */ + uint32_t network; /* data link type */ +}; +struct pcaprec_hdr { + uint32_t ts_sec; /* timestamp seconds */ + uint32_t ts_usec; /* timestamp microseconds */ + uint32_t incl_len; /* number of octets of packet saved in file */ + uint32_t orig_len; /* actual length of packet */ +}; + +#endif |