summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 18:02:34 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 18:02:34 +0000
commitfadeddfbb2aa38a980dd959b5ec1ffba7afd43cb (patch)
treea7bde6111c84ea64619656a38fba50909fa0bf60 /tests
parentInitial commit. (diff)
downloadlldpd-fadeddfbb2aa38a980dd959b5ec1ffba7afd43cb.tar.xz
lldpd-fadeddfbb2aa38a980dd959b5ec1ffba7afd43cb.zip
Adding upstream version 1.0.18.upstream/1.0.18upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am85
-rw-r--r--tests/Makefile.in1419
-rw-r--r--tests/check-compat.h16
-rw-r--r--tests/check_bitmap.c77
-rw-r--r--tests/check_cdp.c536
-rw-r--r--tests/check_edp.c578
-rw-r--r--tests/check_fixedpoint.c353
-rw-r--r--tests/check_lldp.c835
-rw-r--r--tests/check_marshal.c925
-rw-r--r--tests/check_pattern.c148
-rw-r--r--tests/check_snmp.c1190
-rw-r--r--tests/check_sonmp.c221
-rw-r--r--tests/common.c153
-rw-r--r--tests/common.h45
-rw-r--r--tests/decode.c265
-rw-r--r--tests/fuzz_cdp.c54
-rw-r--r--tests/fuzz_edp.c54
-rw-r--r--tests/fuzz_lldp.c50
-rw-r--r--tests/fuzz_sonmp.c50
-rw-r--r--tests/pcap-hdr.h25
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=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ 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