diff options
Diffstat (limited to 'src/lib/dhcp/testutils')
-rw-r--r-- | src/lib/dhcp/testutils/Makefile.am | 25 | ||||
-rw-r--r-- | src/lib/dhcp/testutils/Makefile.in | 921 | ||||
-rw-r--r-- | src/lib/dhcp/testutils/iface_mgr_test_config.cc | 209 | ||||
-rw-r--r-- | src/lib/dhcp/testutils/iface_mgr_test_config.h | 273 | ||||
-rw-r--r-- | src/lib/dhcp/testutils/pkt_captures.h | 103 | ||||
-rw-r--r-- | src/lib/dhcp/testutils/pkt_captures4.cc | 389 | ||||
-rw-r--r-- | src/lib/dhcp/testutils/pkt_captures6.cc | 511 | ||||
-rw-r--r-- | src/lib/dhcp/testutils/pkt_filter6_test_stub.cc | 48 | ||||
-rw-r--r-- | src/lib/dhcp/testutils/pkt_filter6_test_stub.h | 107 | ||||
-rw-r--r-- | src/lib/dhcp/testutils/pkt_filter_test_stub.cc | 66 | ||||
-rw-r--r-- | src/lib/dhcp/testutils/pkt_filter_test_stub.h | 126 |
11 files changed, 2778 insertions, 0 deletions
diff --git a/src/lib/dhcp/testutils/Makefile.am b/src/lib/dhcp/testutils/Makefile.am new file mode 100644 index 0000000..ae75a27 --- /dev/null +++ b/src/lib/dhcp/testutils/Makefile.am @@ -0,0 +1,25 @@ +SUBDIRS = . + +AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib +AM_CPPFLAGS += $(BOOST_INCLUDES) + +AM_CXXFLAGS = $(KEA_CXXFLAGS) + +CLEANFILES = *.gcno *.gcda + +if HAVE_GTEST + +noinst_LTLIBRARIES = libdhcptest.la + +libdhcptest_la_SOURCES = iface_mgr_test_config.cc iface_mgr_test_config.h +libdhcptest_la_SOURCES += pkt_filter_test_stub.cc pkt_filter_test_stub.h +libdhcptest_la_SOURCES += pkt_filter6_test_stub.cc pkt_filter6_test_stub.h +libdhcptest_la_SOURCES += pkt_captures4.cc pkt_captures6.cc pkt_captures.h + +libdhcptest_la_CXXFLAGS = $(AM_CXXFLAGS) +libdhcptest_la_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) + +libdhcptest_la_LIBADD = +libdhcptest_la_LIBADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la + +endif diff --git a/src/lib/dhcp/testutils/Makefile.in b/src/lib/dhcp/testutils/Makefile.in new file mode 100644 index 0000000..c563f05 --- /dev/null +++ b/src/lib/dhcp/testutils/Makefile.in @@ -0,0 +1,921 @@ +# 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@ +subdir = src/lib/dhcp/testutils +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4macros/ax_boost_for_kea.m4 \ + $(top_srcdir)/m4macros/ax_cpp14.m4 \ + $(top_srcdir)/m4macros/ax_cpp20.m4 \ + $(top_srcdir)/m4macros/ax_crypto.m4 \ + $(top_srcdir)/m4macros/ax_find_library.m4 \ + $(top_srcdir)/m4macros/ax_gssapi.m4 \ + $(top_srcdir)/m4macros/ax_gtest.m4 \ + $(top_srcdir)/m4macros/ax_isc_rpath.m4 \ + $(top_srcdir)/m4macros/ax_netconf.m4 \ + $(top_srcdir)/m4macros/libtool.m4 \ + $(top_srcdir)/m4macros/ltoptions.m4 \ + $(top_srcdir)/m4macros/ltsugar.m4 \ + $(top_srcdir)/m4macros/ltversion.m4 \ + $(top_srcdir)/m4macros/lt~obsolete.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 = +LTLIBRARIES = $(noinst_LTLIBRARIES) +@HAVE_GTEST_TRUE@libdhcptest_la_DEPENDENCIES = $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la +am__libdhcptest_la_SOURCES_DIST = iface_mgr_test_config.cc \ + iface_mgr_test_config.h pkt_filter_test_stub.cc \ + pkt_filter_test_stub.h pkt_filter6_test_stub.cc \ + pkt_filter6_test_stub.h pkt_captures4.cc pkt_captures6.cc \ + pkt_captures.h +@HAVE_GTEST_TRUE@am_libdhcptest_la_OBJECTS = \ +@HAVE_GTEST_TRUE@ libdhcptest_la-iface_mgr_test_config.lo \ +@HAVE_GTEST_TRUE@ libdhcptest_la-pkt_filter_test_stub.lo \ +@HAVE_GTEST_TRUE@ libdhcptest_la-pkt_filter6_test_stub.lo \ +@HAVE_GTEST_TRUE@ libdhcptest_la-pkt_captures4.lo \ +@HAVE_GTEST_TRUE@ libdhcptest_la-pkt_captures6.lo +libdhcptest_la_OBJECTS = $(am_libdhcptest_la_OBJECTS) +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 = +libdhcptest_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(libdhcptest_la_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +@HAVE_GTEST_TRUE@am_libdhcptest_la_rpath = +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)/libdhcptest_la-iface_mgr_test_config.Plo \ + ./$(DEPDIR)/libdhcptest_la-pkt_captures4.Plo \ + ./$(DEPDIR)/libdhcptest_la-pkt_captures6.Plo \ + ./$(DEPDIR)/libdhcptest_la-pkt_filter6_test_stub.Plo \ + ./$(DEPDIR)/libdhcptest_la-pkt_filter_test_stub.Plo +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +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 = $(libdhcptest_la_SOURCES) +DIST_SOURCES = $(am__libdhcptest_la_SOURCES_DIST) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +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)` +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +ASCIIDOC = @ASCIIDOC@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BOOST_INCLUDES = @BOOST_INCLUDES@ +BOOST_LIBS = @BOOST_LIBS@ +BOTAN_TOOL = @BOTAN_TOOL@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONTRIB_DIR = @CONTRIB_DIR@ +CPPFLAGS = @CPPFLAGS@ +CRYPTO_CFLAGS = @CRYPTO_CFLAGS@ +CRYPTO_INCLUDES = @CRYPTO_INCLUDES@ +CRYPTO_LDFLAGS = @CRYPTO_LDFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ +CRYPTO_PACKAGE = @CRYPTO_PACKAGE@ +CRYPTO_RPATH = @CRYPTO_RPATH@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DISTCHECK_BOOST_CONFIGURE_FLAG = @DISTCHECK_BOOST_CONFIGURE_FLAG@ +DISTCHECK_CONTRIB_CONFIGURE_FLAG = @DISTCHECK_CONTRIB_CONFIGURE_FLAG@ +DISTCHECK_CRYPTO_CONFIGURE_FLAG = @DISTCHECK_CRYPTO_CONFIGURE_FLAG@ +DISTCHECK_GSSAPI_CONFIGURE_FLAG = @DISTCHECK_GSSAPI_CONFIGURE_FLAG@ +DISTCHECK_GTEST_CONFIGURE_FLAG = @DISTCHECK_GTEST_CONFIGURE_FLAG@ +DISTCHECK_KEA_SHELL_CONFIGURE_FLAG = @DISTCHECK_KEA_SHELL_CONFIGURE_FLAG@ +DISTCHECK_LIBYANGCPP_CONFIGURE_FLAG = @DISTCHECK_LIBYANGCPP_CONFIGURE_FLAG@ +DISTCHECK_LIBYANG_CONFIGURE_FLAG = @DISTCHECK_LIBYANG_CONFIGURE_FLAG@ +DISTCHECK_LOG4CPLUS_CONFIGURE_FLAG = @DISTCHECK_LOG4CPLUS_CONFIGURE_FLAG@ +DISTCHECK_MYSQL_CONFIGURE_FLAG = @DISTCHECK_MYSQL_CONFIGURE_FLAG@ +DISTCHECK_PERFDHCP_CONFIGURE_FLAG = @DISTCHECK_PERFDHCP_CONFIGURE_FLAG@ +DISTCHECK_PGSQL_CONFIGURE_FLAG = @DISTCHECK_PGSQL_CONFIGURE_FLAG@ +DISTCHECK_PREMIUM_CONFIGURE_FLAG = @DISTCHECK_PREMIUM_CONFIGURE_FLAG@ +DISTCHECK_SYSREPOCPP_CONFIGURE_FLAG = @DISTCHECK_SYSREPOCPP_CONFIGURE_FLAG@ +DISTCHECK_SYSREPO_CONFIGURE_FLAG = @DISTCHECK_SYSREPO_CONFIGURE_FLAG@ +DLLTOOL = @DLLTOOL@ +DPKG = @DPKG@ +DPKGQUERY = @DPKGQUERY@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILECMD = @FILECMD@ +GENHTML = @GENHTML@ +GREP = @GREP@ +GSSAPI_CFLAGS = @GSSAPI_CFLAGS@ +GSSAPI_LIBS = @GSSAPI_LIBS@ +GTEST_CONFIG = @GTEST_CONFIG@ +GTEST_INCLUDES = @GTEST_INCLUDES@ +GTEST_LDADD = @GTEST_LDADD@ +GTEST_LDFLAGS = @GTEST_LDFLAGS@ +GTEST_SOURCE = @GTEST_SOURCE@ +HAVE_NETCONF = @HAVE_NETCONF@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KEA_CXXFLAGS = @KEA_CXXFLAGS@ +KEA_SRCID = @KEA_SRCID@ +KRB5_CONFIG = @KRB5_CONFIG@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBYANGCPP_CPPFLAGS = @LIBYANGCPP_CPPFLAGS@ +LIBYANGCPP_INCLUDEDIR = @LIBYANGCPP_INCLUDEDIR@ +LIBYANGCPP_LIBS = @LIBYANGCPP_LIBS@ +LIBYANGCPP_PREFIX = @LIBYANGCPP_PREFIX@ +LIBYANGCPP_VERSION = @LIBYANGCPP_VERSION@ +LIBYANG_CPPFLAGS = @LIBYANG_CPPFLAGS@ +LIBYANG_INCLUDEDIR = @LIBYANG_INCLUDEDIR@ +LIBYANG_LIBS = @LIBYANG_LIBS@ +LIBYANG_PREFIX = @LIBYANG_PREFIX@ +LIBYANG_VERSION = @LIBYANG_VERSION@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOG4CPLUS_INCLUDES = @LOG4CPLUS_INCLUDES@ +LOG4CPLUS_LIBS = @LOG4CPLUS_LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +MYSQL_LIBS = @MYSQL_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@ +PACKAGE_VERSION_TYPE = @PACKAGE_VERSION_TYPE@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PDFLATEX = @PDFLATEX@ +PERL = @PERL@ +PGSQL_CPPFLAGS = @PGSQL_CPPFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PKGPYTHONDIR = @PKGPYTHONDIR@ +PKG_CONFIG = @PKG_CONFIG@ +PLANTUML = @PLANTUML@ +PREMIUM_DIR = @PREMIUM_DIR@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SEP = @SEP@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPHINXBUILD = @SPHINXBUILD@ +SRPD_PLUGINS_PATH = @SRPD_PLUGINS_PATH@ +SR_PLUGINS_PATH = @SR_PLUGINS_PATH@ +SR_REPO_PATH = @SR_REPO_PATH@ +STRIP = @STRIP@ +SYSREPOCPP_CPPFLAGS = @SYSREPOCPP_CPPFLAGS@ +SYSREPOCPP_INCLUDEDIR = @SYSREPOCPP_INCLUDEDIR@ +SYSREPOCPP_LIBS = @SYSREPOCPP_LIBS@ +SYSREPOCPP_PREFIX = @SYSREPOCPP_PREFIX@ +SYSREPOCPP_VERSION = @SYSREPOCPP_VERSION@ +SYSREPO_CPPFLAGS = @SYSREPO_CPPFLAGS@ +SYSREPO_INCLUDEDIR = @SYSREPO_INCLUDEDIR@ +SYSREPO_LIBS = @SYSREPO_LIBS@ +SYSREPO_PREFIX = @SYSREPO_PREFIX@ +SYSREPO_VERSION = @SYSREPO_VERSION@ +USE_LCOV = @USE_LCOV@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARNING_GCC_44_STRICT_ALIASING_CFLAG = @WARNING_GCC_44_STRICT_ALIASING_CFLAG@ +XMLLINT = @XMLLINT@ +YACC = @YACC@ +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_CXX = @ac_ct_CXX@ +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@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +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@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = . +AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib \ + $(BOOST_INCLUDES) +AM_CXXFLAGS = $(KEA_CXXFLAGS) +CLEANFILES = *.gcno *.gcda +@HAVE_GTEST_TRUE@noinst_LTLIBRARIES = libdhcptest.la +@HAVE_GTEST_TRUE@libdhcptest_la_SOURCES = iface_mgr_test_config.cc \ +@HAVE_GTEST_TRUE@ iface_mgr_test_config.h \ +@HAVE_GTEST_TRUE@ pkt_filter_test_stub.cc \ +@HAVE_GTEST_TRUE@ pkt_filter_test_stub.h \ +@HAVE_GTEST_TRUE@ pkt_filter6_test_stub.cc \ +@HAVE_GTEST_TRUE@ pkt_filter6_test_stub.h pkt_captures4.cc \ +@HAVE_GTEST_TRUE@ pkt_captures6.cc pkt_captures.h +@HAVE_GTEST_TRUE@libdhcptest_la_CXXFLAGS = $(AM_CXXFLAGS) +@HAVE_GTEST_TRUE@libdhcptest_la_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) +@HAVE_GTEST_TRUE@libdhcptest_la_LIBADD = $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .cc .lo .o .obj +$(srcdir)/Makefile.in: $(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 src/lib/dhcp/testutils/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/lib/dhcp/testutils/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: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libdhcptest.la: $(libdhcptest_la_OBJECTS) $(libdhcptest_la_DEPENDENCIES) $(EXTRA_libdhcptest_la_DEPENDENCIES) + $(AM_V_CXXLD)$(libdhcptest_la_LINK) $(am_libdhcptest_la_rpath) $(libdhcptest_la_OBJECTS) $(libdhcptest_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdhcptest_la-iface_mgr_test_config.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdhcptest_la-pkt_captures4.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdhcptest_la-pkt_captures6.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdhcptest_la-pkt_filter6_test_stub.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdhcptest_la-pkt_filter_test_stub.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.cc.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cc.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +libdhcptest_la-iface_mgr_test_config.lo: iface_mgr_test_config.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcptest_la_CPPFLAGS) $(CPPFLAGS) $(libdhcptest_la_CXXFLAGS) $(CXXFLAGS) -MT libdhcptest_la-iface_mgr_test_config.lo -MD -MP -MF $(DEPDIR)/libdhcptest_la-iface_mgr_test_config.Tpo -c -o libdhcptest_la-iface_mgr_test_config.lo `test -f 'iface_mgr_test_config.cc' || echo '$(srcdir)/'`iface_mgr_test_config.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdhcptest_la-iface_mgr_test_config.Tpo $(DEPDIR)/libdhcptest_la-iface_mgr_test_config.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='iface_mgr_test_config.cc' object='libdhcptest_la-iface_mgr_test_config.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcptest_la_CPPFLAGS) $(CPPFLAGS) $(libdhcptest_la_CXXFLAGS) $(CXXFLAGS) -c -o libdhcptest_la-iface_mgr_test_config.lo `test -f 'iface_mgr_test_config.cc' || echo '$(srcdir)/'`iface_mgr_test_config.cc + +libdhcptest_la-pkt_filter_test_stub.lo: pkt_filter_test_stub.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcptest_la_CPPFLAGS) $(CPPFLAGS) $(libdhcptest_la_CXXFLAGS) $(CXXFLAGS) -MT libdhcptest_la-pkt_filter_test_stub.lo -MD -MP -MF $(DEPDIR)/libdhcptest_la-pkt_filter_test_stub.Tpo -c -o libdhcptest_la-pkt_filter_test_stub.lo `test -f 'pkt_filter_test_stub.cc' || echo '$(srcdir)/'`pkt_filter_test_stub.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdhcptest_la-pkt_filter_test_stub.Tpo $(DEPDIR)/libdhcptest_la-pkt_filter_test_stub.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pkt_filter_test_stub.cc' object='libdhcptest_la-pkt_filter_test_stub.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcptest_la_CPPFLAGS) $(CPPFLAGS) $(libdhcptest_la_CXXFLAGS) $(CXXFLAGS) -c -o libdhcptest_la-pkt_filter_test_stub.lo `test -f 'pkt_filter_test_stub.cc' || echo '$(srcdir)/'`pkt_filter_test_stub.cc + +libdhcptest_la-pkt_filter6_test_stub.lo: pkt_filter6_test_stub.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcptest_la_CPPFLAGS) $(CPPFLAGS) $(libdhcptest_la_CXXFLAGS) $(CXXFLAGS) -MT libdhcptest_la-pkt_filter6_test_stub.lo -MD -MP -MF $(DEPDIR)/libdhcptest_la-pkt_filter6_test_stub.Tpo -c -o libdhcptest_la-pkt_filter6_test_stub.lo `test -f 'pkt_filter6_test_stub.cc' || echo '$(srcdir)/'`pkt_filter6_test_stub.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdhcptest_la-pkt_filter6_test_stub.Tpo $(DEPDIR)/libdhcptest_la-pkt_filter6_test_stub.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pkt_filter6_test_stub.cc' object='libdhcptest_la-pkt_filter6_test_stub.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcptest_la_CPPFLAGS) $(CPPFLAGS) $(libdhcptest_la_CXXFLAGS) $(CXXFLAGS) -c -o libdhcptest_la-pkt_filter6_test_stub.lo `test -f 'pkt_filter6_test_stub.cc' || echo '$(srcdir)/'`pkt_filter6_test_stub.cc + +libdhcptest_la-pkt_captures4.lo: pkt_captures4.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcptest_la_CPPFLAGS) $(CPPFLAGS) $(libdhcptest_la_CXXFLAGS) $(CXXFLAGS) -MT libdhcptest_la-pkt_captures4.lo -MD -MP -MF $(DEPDIR)/libdhcptest_la-pkt_captures4.Tpo -c -o libdhcptest_la-pkt_captures4.lo `test -f 'pkt_captures4.cc' || echo '$(srcdir)/'`pkt_captures4.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdhcptest_la-pkt_captures4.Tpo $(DEPDIR)/libdhcptest_la-pkt_captures4.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pkt_captures4.cc' object='libdhcptest_la-pkt_captures4.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcptest_la_CPPFLAGS) $(CPPFLAGS) $(libdhcptest_la_CXXFLAGS) $(CXXFLAGS) -c -o libdhcptest_la-pkt_captures4.lo `test -f 'pkt_captures4.cc' || echo '$(srcdir)/'`pkt_captures4.cc + +libdhcptest_la-pkt_captures6.lo: pkt_captures6.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcptest_la_CPPFLAGS) $(CPPFLAGS) $(libdhcptest_la_CXXFLAGS) $(CXXFLAGS) -MT libdhcptest_la-pkt_captures6.lo -MD -MP -MF $(DEPDIR)/libdhcptest_la-pkt_captures6.Tpo -c -o libdhcptest_la-pkt_captures6.lo `test -f 'pkt_captures6.cc' || echo '$(srcdir)/'`pkt_captures6.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdhcptest_la-pkt_captures6.Tpo $(DEPDIR)/libdhcptest_la-pkt_captures6.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pkt_captures6.cc' object='libdhcptest_la-pkt_captures6.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcptest_la_CPPFLAGS) $(CPPFLAGS) $(libdhcptest_la_CXXFLAGS) $(CXXFLAGS) -c -o libdhcptest_la-pkt_captures6.lo `test -f 'pkt_captures6.cc' || echo '$(srcdir)/'`pkt_captures6.cc + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(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-recursive + +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-recursive + +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 +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 + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +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: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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-recursive + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/libdhcptest_la-iface_mgr_test_config.Plo + -rm -f ./$(DEPDIR)/libdhcptest_la-pkt_captures4.Plo + -rm -f ./$(DEPDIR)/libdhcptest_la-pkt_captures6.Plo + -rm -f ./$(DEPDIR)/libdhcptest_la-pkt_filter6_test_stub.Plo + -rm -f ./$(DEPDIR)/libdhcptest_la-pkt_filter_test_stub.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/libdhcptest_la-iface_mgr_test_config.Plo + -rm -f ./$(DEPDIR)/libdhcptest_la-pkt_captures4.Plo + -rm -f ./$(DEPDIR)/libdhcptest_la-pkt_captures6.Plo + -rm -f ./$(DEPDIR)/libdhcptest_la-pkt_filter6_test_stub.Plo + -rm -f ./$(DEPDIR)/libdhcptest_la-pkt_filter_test_stub.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-generic clean-libtool \ + clean-noinstLTLIBRARIES 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 \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am 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/src/lib/dhcp/testutils/iface_mgr_test_config.cc b/src/lib/dhcp/testutils/iface_mgr_test_config.cc new file mode 100644 index 0000000..c22d2e1 --- /dev/null +++ b/src/lib/dhcp/testutils/iface_mgr_test_config.cc @@ -0,0 +1,209 @@ +// Copyright (C) 2014-2024 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <dhcp/pkt_filter.h> +#include <dhcp/pkt_filter_inet.h> +#include <dhcp/pkt_filter_inet6.h> +#include <dhcp/testutils/iface_mgr_test_config.h> +#include <dhcp/testutils/pkt_filter_test_stub.h> +#include <dhcp/testutils/pkt_filter6_test_stub.h> + +using namespace isc::asiolink; + +namespace isc { +namespace dhcp { +namespace test { + +IfaceMgrTestConfig::IfaceMgrTestConfig(const bool default_config) { + IfaceMgr::instance().setTestMode(true); + IfaceMgr::instance().closeSockets(); + IfaceMgr::instance().clearIfaces(); + IfaceMgr::instance().getPacketQueueMgr4()->destroyPacketQueue(); + IfaceMgr::instance().getPacketQueueMgr6()->destroyPacketQueue(); + packet_filter4_ = PktFilterPtr(new PktFilterTestStub()); + packet_filter6_ = PktFilter6Ptr(new PktFilter6TestStub()); + IfaceMgr::instance().setPacketFilter(packet_filter4_); + IfaceMgr::instance().setPacketFilter(packet_filter6_); + + // Create default set of fake interfaces: lo, eth0, eth1 and eth1961. + if (default_config) { + createIfaces(); + } +} + +IfaceMgrTestConfig::~IfaceMgrTestConfig() { + IfaceMgr::instance().stopDHCPReceiver(); + IfaceMgr::instance().closeSockets(); + IfaceMgr::instance().getPacketQueueMgr4()->destroyPacketQueue(); + IfaceMgr::instance().getPacketQueueMgr6()->destroyPacketQueue(); + IfaceMgr::instance().clearIfaces(); + IfaceMgr::instance().setPacketFilter(PktFilterPtr(new PktFilterInet())); + IfaceMgr::instance().setPacketFilter(PktFilter6Ptr(new PktFilterInet6())); + IfaceMgr::instance().setTestMode(false); + IfaceMgr::instance().detectIfaces(); +} + +void +IfaceMgrTestConfig::addAddress(const std::string& iface_name, + const IOAddress& address) { + IfacePtr iface = IfaceMgr::instance().getIface(iface_name); + if (!iface) { + isc_throw(isc::BadValue, "interface '" << iface_name + << "' doesn't exist"); + } + iface->addAddress(address); +} + +void +IfaceMgrTestConfig::addIface(const IfacePtr& iface) { + IfaceMgr::instance().addInterface(iface); +} + +void +IfaceMgrTestConfig::addIface(const std::string& name, + const unsigned int ifindex) { + IfaceMgr::instance().addInterface(createIface(name, ifindex)); +} + +IfacePtr +IfaceMgrTestConfig::createIface(const std::string& name, + const unsigned int ifindex, + const std::string& mac) { + IfacePtr iface(new Iface(name, ifindex)); + if (name == "lo") { + iface->flag_loopback_ = true; + // Don't open sockets on the loopback interface. + iface->inactive4_ = true; + iface->inactive6_ = true; + } else { + iface->inactive4_ = false; + iface->inactive6_ = false; + } + iface->flag_multicast_ = true; + // On BSD systems, the SO_BINDTODEVICE option is not supported. + // Therefore the IfaceMgr will throw an exception on attempt to + // open sockets on more than one broadcast-capable interface at + // the same time. In order to prevent this error, we mark all + // interfaces broadcast-incapable for unit testing. + iface->flag_broadcast_ = false; + iface->flag_up_ = true; + iface->flag_running_ = true; + + // Set MAC address. + HWAddr hwaddr = HWAddr::fromText(mac); + std::vector<uint8_t> mac_vec = hwaddr.hwaddr_; + iface->setMac(&mac_vec[0], mac_vec.size()); + iface->setHWType(HTYPE_ETHER); + + return (iface); +} + +void +IfaceMgrTestConfig::createIfaces() { + // local loopback + addIface("lo", LO_INDEX); + addAddress("lo", IOAddress("127.0.0.1")); + addAddress("lo", IOAddress("::1")); + // eth0 + addIface("eth0", ETH0_INDEX); + addAddress("eth0", IOAddress("10.0.0.1")); + addAddress("eth0", IOAddress("fe80::3a60:77ff:fed5:cdef")); + addAddress("eth0", IOAddress("2001:db8:1::1")); + // eth1 + addIface("eth1", ETH1_INDEX); + addAddress("eth1", IOAddress("192.0.2.3")); + addAddress("eth1", IOAddress("192.0.2.5")); + addAddress("eth1", IOAddress("fe80::3a60:77ff:fed5:abcd")); + // eth1961 + addIface("eth1961", ETH1961_INDEX); + addAddress("eth1961", IOAddress("198.51.100.1")); + addAddress("eth1961", IOAddress("fe80::3a60:77ff:fed5:9876")); +} + +void +IfaceMgrTestConfig::setDirectResponse(const bool direct_resp) { + boost::shared_ptr<PktFilterTestStub> stub = + boost::dynamic_pointer_cast<PktFilterTestStub>(getPacketFilter4()); + if (!stub) { + isc_throw(isc::Unexpected, "unable to set direct response capability for" + " test packet filter - current packet filter is not" + " of a PktFilterTestStub"); + } + stub->direct_response_supported_ = direct_resp; +} + +void +IfaceMgrTestConfig::setIfaceFlags(const std::string& name, + const FlagLoopback& loopback, + const FlagUp& up, + const FlagRunning& running, + const FlagInactive4& inactive4, + const FlagInactive6& inactive6) { + IfacePtr iface = IfaceMgr::instance().getIface(name); + if (iface == NULL) { + isc_throw(isc::BadValue, "interface '" << name << "' doesn't exist"); + } + iface->flag_loopback_ = loopback.flag_; + iface->flag_up_ = up.flag_; + iface->flag_running_ = running.flag_; + iface->inactive4_ = inactive4.flag_; + iface->inactive6_ = inactive6.flag_; +} + +bool +IfaceMgrTestConfig::socketOpen(const std::string& iface_name, + const int family) const { + IfacePtr iface = IfaceMgr::instance().getIface(iface_name); + if (iface == NULL) { + isc_throw(Unexpected, "No such interface '" << iface_name << "'"); + } + + for (auto const& sock : iface->getSockets()) { + if (sock.family_ == family) { + return (true); + } + } + return (false); +} + +bool +IfaceMgrTestConfig::socketOpen(const std::string& iface_name, + const std::string& address) const { + IfacePtr iface = IfaceMgr::instance().getIface(iface_name); + if (!iface) { + isc_throw(Unexpected, "No such interface '" << iface_name << "'"); + } + + for (auto const& sock : iface->getSockets()) { + if ((sock.family_ == AF_INET) && + (sock.addr_ == IOAddress(address))) { + return (true); + } + } + return (false); +} + +bool +IfaceMgrTestConfig::unicastOpen(const std::string& iface_name) const { + IfacePtr iface = IfaceMgr::instance().getIface(iface_name); + if (!iface) { + isc_throw(Unexpected, "No such interface '" << iface_name << "'"); + } + + for (auto const& sock : iface->getSockets()) { + if ((!sock.addr_.isV6LinkLocal()) && + (!sock.addr_.isV6Multicast())) { + return (true); + } + } + return (false); +} + +} // end of namespace isc::dhcp::test +} // end of namespace isc::dhcp +} // end of namespace isc diff --git a/src/lib/dhcp/testutils/iface_mgr_test_config.h b/src/lib/dhcp/testutils/iface_mgr_test_config.h new file mode 100644 index 0000000..2839e4e --- /dev/null +++ b/src/lib/dhcp/testutils/iface_mgr_test_config.h @@ -0,0 +1,273 @@ +// Copyright (C) 2014-2023 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef IFACE_MGR_TEST_CONFIG_H +#define IFACE_MGR_TEST_CONFIG_H + +#include <asiolink/io_address.h> +#include <dhcp/iface_mgr.h> +#include <boost/noncopyable.hpp> + +namespace isc { +namespace dhcp { +namespace test { + +//@{ +/// @brief Index of the lo fake interface. +const uint32_t LO_INDEX = 0; + +/// @brief Index of the eth0 fake interface. +const uint32_t ETH0_INDEX = 1; + +/// @brief Index of the eth1 fake interface. +const uint32_t ETH1_INDEX = 2; + +/// @brief Index of the eth1961 fake interface. +const uint32_t ETH1961_INDEX = 1962; +//@} + +/// +/// @name Set of structures describing interface flags. +/// +/// These flags encapsulate the boolean type to pass the flags values +/// to @c IfaceMgrTestConfig methods. If the values passed to these methods +/// were not encapsulated by the types defined here, the API would become +/// prone to errors like swapping parameters being passed to specific functions. +/// For example, in the call to @c IfaceMgrTestConfig::setIfaceFlags: +/// @code +/// IfaceMgrTestConfig test_config(true); +/// test_config.setIfaceFlags("eth1", false, false, true, false, false); +/// @endcode +/// +/// it is quite likely that the developer by mistake swaps the values and +/// assigns them to wrong flags. When the flags are encapsulated with dedicated +/// structs, the compiler will return an error if values are swapped. For +/// example: +/// @code +/// IfaceMgrTestConfig test_config(true); +/// test_config.setIfaceFlags("eth1", FlagLoopback(false), FlagUp(false), +/// FlagRunning(true), FlagInactive4(false), +/// FlagInactive6(false)); +/// @endcode +/// will succeed, but the following code will result in the compilation error +/// and thus protect a developer from making an error: +/// @code +/// IfaceMgrTestConfig test_config(true); +/// test_config.setIfaceFlags("eth1", FlagLoopback(false), +/// FlagRunning(true), FlagUp(false), +/// FlagInactive4(false), FlagInactive6(false)); +/// @endcode +/// +//@{ +/// @brief Structure describing the loopback interface flag. +struct FlagLoopback { + explicit FlagLoopback(bool flag) : flag_(flag) { } + bool flag_; +}; + +/// @brief Structure describing the up interface flag. +struct FlagUp { + explicit FlagUp(bool flag) : flag_(flag) { } + bool flag_; +}; + +/// @brief Structure describing the running interface flag. +struct FlagRunning { + explicit FlagRunning(bool flag) : flag_(flag) { } + bool flag_; +}; + +/// @brief Structure describing the inactive4 interface flag. +struct FlagInactive4 { + explicit FlagInactive4(bool flag) : flag_(flag) { } + bool flag_; +}; + +/// @brief Structure describing the inactive6 interface flag. +struct FlagInactive6 { + explicit FlagInactive6(bool flag) : flag_(flag) { } + bool flag_; +}; +//@} + +/// @brief Convenience class for configuring @c IfaceMgr for unit testing. +/// +/// This class is used by various unit tests which test the code relaying +/// on IfaceMgr. The use of this class is not limited to libdhcp++ validation. +/// There are other libraries and applications (e.g. DHCP servers) which +/// depend on @c IfaceMgr. +/// +/// During the normal operation, the @c IfaceMgr detects interfaces present +/// on the machine where it is running. It also provides the means for +/// applications to open sockets on these interfaces and perform other +/// IO operations. This however creates dependency of the applications +/// using @c IfaceMgr on the physical properties of the system and effectively +/// makes it very hard to unit test the dependent code. +/// +/// Unit tests usually require that @c IfaceMgr holds a list of well known +/// interfaces with the well known set of IP addresses and other properties +/// (a.k.a. interface flags). The solution which works for many test scenarios +/// is to provide a set of well known fake interfaces, by bypassing the +/// standard interface detection procedure and manually adding @c Iface objects +/// which encapsulate the fake interfaces. As a consequence, it becomes +/// impossible to test IO operations (e.g. sending packets) because real sockets +/// can't be opened on these interfaces. The @c PktFilterTestStub class +/// is used by this class to mimic behavior of IO operations on fake sockets. +/// +/// This class provides a set of convenience functions that should be called +/// by unit tests to configure the @c IfaceMgr with fake interfaces. +/// +/// The class allows the caller to create custom fake interfaces (with custom +/// IPv4 and IPv6 addresses, flags etc.), but it also provides a default +/// test configuration for interfaces as follows: +/// - lo #0 +/// - 127.0.0.1 +/// - ::1 +/// - eth0 #1 +/// - 10.0.0.1 +/// - fe80::3a60:77ff:fed5:cdef +/// - 2001:db8:1::1 +/// - eth1 #2 +/// - 192.0.2.3 +/// - fe80::3a60:77ff:fed5:abcd +/// - eth1961 #1962 +/// - 198.51.100.1 +/// - fe80::3a60:77ff:fed5:9876 +/// +/// For all interfaces the following flags are set: +/// - multicast +/// - up +/// - running +class IfaceMgrTestConfig : public boost::noncopyable { +public: + + /// @brief Constructor. + /// + /// It closes all sockets opened by @c IfaceMgr and removes all interfaces + /// being used by @c IfaceMgr. + IfaceMgrTestConfig(const bool default_config = false); + + /// @brief Destructor. + /// + /// Closes all currently opened sockets, removes current interfaces and + /// sets the default packet filtering classes. The default packet filtering + /// classes are used for IO operations on real sockets/interfaces. + /// Receiver is stopped. + /// + /// Destructor also re-detects real interfaces. + ~IfaceMgrTestConfig(); + + /// @brief Adds new IPv4 or IPv6 address to the interface. + /// + /// @param iface_name Name of the interface on which new address should + /// be configured. + /// @param address IPv4 or IPv6 address to be configured on the interface. + void addAddress(const std::string& iface_name, + const asiolink::IOAddress& address); + + /// @brief Configures new interface for the @c IfaceMgr. + /// + /// @param iface Object encapsulating interface to be added. + void addIface(const IfacePtr& iface); + + /// @brief Configures new interface for the @c IfaceMgr. + /// + /// @param name Name of the new interface. + /// @param ifindex Index for a new interface. + void addIface(const std::string& name, const unsigned int ifindex); + + /// @brief Create an object representing interface. + /// + /// Apart from creating an interface, this function also sets the + /// interface flags: + /// - loopback flag if interface name is "lo" + /// - up always true + /// - running always true + /// - inactive4 set to false for non-loopback interface + /// - inactive6 set to false for non-loopback interface + /// - multicast always to true + /// - broadcast always to false + /// + /// @param name A name of the interface to be created. + /// @param ifindex An index of the interface to be created. + /// @param mac The mac of the interface. + /// + /// @return An object representing interface. + static IfacePtr createIface(const std::string& name, + const unsigned int ifindex, + const std::string& mac = "08:08:08:08:08:08"); + + /// @brief Creates a default (example) set of fake interfaces. + void createIfaces(); + + /// @brief Returns currently used packet filter for DHCPv4. + PktFilterPtr getPacketFilter4() const { + return (packet_filter4_); + } + + /// @brief Sets the direct response capability for current packet filter. + /// + /// The test uses stub implementation of packet filter object. It is + /// possible to configure that object to report having a capability + /// to directly respond to clients which don't have an address yet. + /// This function sets this property for packet filter object. + /// + /// @param direct_resp Value to be set. + /// + /// @throw isc::Unexpected if unable to set the property. + void setDirectResponse(const bool direct_resp); + + /// @brief Sets various flags on the specified interface. + /// + /// This function configures interface with new values for flags. + /// + /// @param name Interface name. + /// @param loopback Specifies if interface is a loopback interface. + /// @param up Specifies if the interface is up. + /// @param running Specifies if the interface is running. + /// @param inactive4 Specifies if the interface is inactive for V4 + /// traffic, i.e. @c IfaceMgr opens V4 sockets on this interface. + /// @param inactive6 Specifies if the interface is inactive for V6 + /// traffic, i.e. @c IfaceMgr opens V6 sockets on this interface. + void setIfaceFlags(const std::string& name, + const FlagLoopback& loopback, + const FlagUp& up, + const FlagRunning& running, + const FlagInactive4& inactive4, + const FlagInactive6& inactive6); + + /// @brief Checks if socket of the specified family is opened on interface. + /// + /// @param iface_name Interface name. + /// @param family One of: AF_INET or AF_INET6 + bool socketOpen(const std::string& iface_name, const int family) const; + + /// @brief Checks is socket is opened on the interface and bound to a + /// specified address. + /// + /// @param iface_name Interface name. + /// @param address Address to which the socket is bound. + bool socketOpen(const std::string& iface_name, + const std::string& address) const; + + /// @brief Checks if unicast socket is opened on interface. + /// + /// @param iface_name Interface name. + bool unicastOpen(const std::string& iface_name) const; + +private: + /// @brief Currently used packet filter for DHCPv4. + PktFilterPtr packet_filter4_; + + /// @brief Currently used packet filter for DHCPv6. + PktFilter6Ptr packet_filter6_; +}; + +} // end of namespace isc::dhcp::test +} // end of namespace isc::dhcp +} // end of namespace isc + +#endif // IFACE_MGR_TEST_CONFIG_H diff --git a/src/lib/dhcp/testutils/pkt_captures.h b/src/lib/dhcp/testutils/pkt_captures.h new file mode 100644 index 0000000..7f4723a --- /dev/null +++ b/src/lib/dhcp/testutils/pkt_captures.h @@ -0,0 +1,103 @@ +// Copyright (C) 2014-2023 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef PKT_CAPTURES_H +#define PKT_CAPTURES_H + +#include <dhcp/pkt4.h> +#include <dhcp/pkt6.h> + +namespace isc { +namespace dhcp { +namespace test { + +class PktCaptures { +public: + + /// @brief returns captured DISCOVER that went through a relay + /// + /// See method code for a detailed explanation. This is a discover from + /// docsis3.0 device (Cable Modem) + /// + /// @return relayed DISCOVER + static isc::dhcp::Pkt4Ptr captureRelayedDiscover(); + + /// @brief returns captured DISCOVER that went through a relay + /// + /// See method code for a detailed explanation. This is a discover from + /// eRouter1.0 device (CPE device integrated with cable modem) + /// + /// @return relayed DISCOVER + static isc::dhcp::Pkt4Ptr captureRelayedDiscover2(); + + /// @brief returns captured DISCOVER that went through a relay + /// + /// See method code for a detailed explanation. This is a discover from + /// a buggy relay device with a bad suboption. + /// + /// @return relayed DISCOVER + static isc::dhcp::Pkt4Ptr captureBadRelayedDiscover(); + + /// @brief returns captured DISCOVER that contains a valid VIVSO option + /// + /// See method code for a detailed explanation. + /// + /// @return relayed DISCOVER + static isc::dhcp::Pkt4Ptr discoverWithValidVIVSO(); + + /// @brief returns captured DISCOVER that contains a truncated VIVSO option + /// + /// See method code for a detailed explanation. + /// + /// @return relayed DISCOVER + static isc::dhcp::Pkt4Ptr discoverWithTruncatedVIVSO(); + + /// @brief returns captured DISCOVER from Genexis hardware. + /// + /// This device in uncommon, because it doesn't send VIVSO in Discover, but + /// expects one in Offer. + /// @return DISCOVER. + static isc::dhcp::Pkt4Ptr discoverGenexis(); + + // see pkt_captures6.cc for descriptions + // The descriptions are too large and too closely related to the + // code, so it is kept in .cc rather than traditionally in .h + static isc::dhcp::Pkt6Ptr captureSimpleSolicit(); + static isc::dhcp::Pkt6Ptr captureRelayedSolicit(); + static isc::dhcp::Pkt6Ptr captureDocsisRelayedSolicit(); + static isc::dhcp::Pkt6Ptr captureeRouterRelayedSolicit(); + static isc::dhcp::Pkt6Ptr captureCableLabsShortVendorClass(); + static isc::dhcp::Pkt6Ptr captureRelayed2xRSOO(); + static isc::dhcp::Pkt6Ptr captureSolicitWithVIVSO(); + static isc::dhcp::Pkt6Ptr captureSolicitWithTruncatedVIVSO(); + +protected: + /// @brief Auxiliary method that sets Pkt6 fields + /// + /// Used to reconstruct captured packets. Sets UDP ports, interface names, + /// and other fields to some believable values. + /// @param pkt packet that will have its fields set + static void captureSetDefaultFields(const isc::dhcp::Pkt6Ptr& pkt); + + + /// @brief generates a DHCPv4 packet based on provided hex string + /// + /// @return created packet + static isc::dhcp::Pkt4Ptr packetFromCapture(const std::string& hex_string); + + /// @brief sets default fields in a captured packet + /// + /// Sets UDP ports, addresses and interface. + /// + /// @param pkt packet to have default fields set + static void captureSetDefaultFields(const isc::dhcp::Pkt4Ptr& pkt); +}; + +}; // end of namespace isc::dhcp::test +}; // end of namespace isc::dhcp +}; // end of namespace isc + +#endif diff --git a/src/lib/dhcp/testutils/pkt_captures4.cc b/src/lib/dhcp/testutils/pkt_captures4.cc new file mode 100644 index 0000000..3ba9013 --- /dev/null +++ b/src/lib/dhcp/testutils/pkt_captures4.cc @@ -0,0 +1,389 @@ +// Copyright (C) 2013-2024 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <asiolink/io_address.h> +#include <dhcp/testutils/pkt_captures.h> +#include <util/encode/encode.h> + +#include <string> + +/// @file pkt_captures.cc +/// +/// @brief contains packet captures imported from Wireshark +/// +/// These are actual packets captured over wire. They are used in various +/// tests. +/// +/// The procedure to export Wireshark -> unit-tests is manual, but rather +/// easy to follow: +/// 1. Open a file in wireshark +/// 2. Find the packet you want to export +/// 3. There's a protocol stack (Frame, Ethernet, IPv6, UDP, DHCPv6, ...) +/// 4. Right click on DHCPv6 -> Copy -> Bytes -> Hex Stream +/// 5. Paste it as: string hex_string="[paste here]"; +/// 6. Coding guidelines line restrictions apply, so wrap your code as necessary +/// 7. Make sure you describe the capture appropriately +/// 8. Follow whatever rest of the methods are doing (set ports, ifaces etc.) +/// 9. To easily copy packet description, click File... -> Extract packet +/// dissections -> as plain text file... +/// (Make sure that the packet is expanded in the view. The text file will +/// contain whatever expansion level you have in the graphical tree.) + +using namespace std; +using namespace isc::dhcp; +using namespace isc::asiolink; + +namespace isc { +namespace dhcp { +namespace test { + +Pkt4Ptr PktCaptures::packetFromCapture(const std::string& hex_string) { + std::vector<uint8_t> bin; + + // Decode the hex string and store it in bin (which happens + // to be OptionBuffer format) + isc::util::encode::decodeHex(hex_string, bin); + + Pkt4Ptr pkt(new Pkt4(&bin[0], bin.size())); + captureSetDefaultFields(pkt); + + return (pkt); +} + +void PktCaptures::captureSetDefaultFields(const Pkt4Ptr& pkt) { + pkt->setRemotePort(546); + pkt->setRemoteAddr(IOAddress("10.0.0.2")); + pkt->setLocalPort(0); + pkt->setLocalAddr(IOAddress("10.0.0.1")); + pkt->setIndex(2); + pkt->setIface("eth0"); +} + +Pkt4Ptr PktCaptures::captureRelayedDiscover() { + +/* This is packet 1 from capture + dhcp-val/pcap/docsis-*-CG3000DCR-Registration-Filtered.cap + +string exported from Wireshark: + +User Datagram Protocol, Src Port: bootps (67), Dst Port: bootps (67) + Source port: bootps (67) + Destination port: bootps (67) + Length: 541 + Checksum: 0x2181 [validation disabled] + +Bootstrap Protocol + Message type: Boot Request (1) + Hardware type: Ethernet + Hardware address length: 6 + Hops: 1 + Transaction ID: 0x5d05478d + Seconds elapsed: 0 + Bootp flags: 0x0000 (Unicast) + Client IP address: 0.0.0.0 (0.0.0.0) + Your (client) IP address: 0.0.0.0 (0.0.0.0) + Next server IP address: 0.0.0.0 (0.0.0.0) + Relay agent IP address: 10.254.226.1 (10.254.226.1) + Client MAC address: Netgear_b8:15:14 (20:e5:2a:b8:15:14) + Client hardware address padding: 00000000000000000000 + Server host name not given + Boot file name not given + Magic cookie: DHCP + Option: (53) DHCP Message Type + Option: (55) Parameter Request List + Option: (60) Vendor class identifier (docsis3.0) + Option: (125) V-I Vendor-specific Information + - suboption 1 (Option Request): requesting option 2 + - suboption 5 (Modem Caps): 117 bytes + Option: (43) Vendor-Specific Information (CableLabs) + Option: (61) Client identifier + Option: (57) Maximum DHCP Message Size + Option: (82) Agent Information Option + Option: (255) End */ + + string hex_string = + "010106015d05478d000000000000000000000000000000000afee20120e52ab8151400" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000638253633501013707" + "0102030407067d3c0a646f63736973332e303a7d7f0000118b7a010102057501010102" + "010303010104010105010106010107010f0801100901030a01010b01180c01010d0200" + "400e0200100f010110040000000211010014010015013f160101170101180104190104" + "1a01041b01201c01021d01081e01201f01102001102101022201012301002401002501" + "01260200ff2701012b59020345434d030b45434d3a45524f55544552040d3242523232" + "39553430303434430504312e3034060856312e33332e30330707322e332e3052320806" + "30303039354209094347333030304443520a074e657467656172fe01083d0fff2ab815" + "140003000120e52ab81514390205dc5219010420000002020620e52ab8151409090000" + "118b0401020300ff"; + + return (packetFromCapture(hex_string)); +} + +Pkt4Ptr PktCaptures::captureRelayedDiscover2() { + +/* This is packet 5 from capture + dhcp-val/pcap/docsis-*-CG3000DCR-Registration-Filtered.cap + +string exported from Wireshark: + +User Datagram Protocol, Src Port: bootps (67), Dst Port: bootps (67) +Bootstrap Protocol + Message type: Boot Request (1) + Hardware type: Ethernet (0x01) + Hardware address length: 6 + Hops: 1 + Transaction ID: 0x5d05478f + Seconds elapsed: 5 + Bootp flags: 0x0000 (Unicast) + Client IP address: 0.0.0.0 (0.0.0.0) + Your (client) IP address: 0.0.0.0 (0.0.0.0) + Next server IP address: 0.0.0.0 (0.0.0.0) + Relay agent IP address: 10.254.226.1 (10.254.226.1) + Client MAC address: Netgear_b8:15:15 (20:e5:2a:b8:15:15) + Client hardware address padding: 00000000000000000000 + Server host name not given + Boot file name not given + Magic cookie: DHCP + Option: (53) DHCP Message Type + Option: (55) Parameter Request List + Option: (43) Vendor-Specific Information + Option: (60) Vendor class identifier (eRouter1.0) + Option: (15) Domain Name + Option: (61) Client identifier + Option: (57) Maximum DHCP Message Size + Option: (82) Agent Information Option + Option: (255) End */ + + string hex_string = + "010106015d05478f000500000000000000000000000000000afee20120e52ab8151500" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000063825363350101370e" + "480102030406070c0f171a36337a2b63020745524f55544552030b45434d3a45524f55" + "544552040d324252323239553430303434430504312e3034060856312e33332e303307" + "07322e332e305232080630303039354209094347333030304443520a074e6574676561" + "720f0745524f555445523c0a65526f75746572312e300f14687364312e70612e636f6d" + "636173742e6e65742e3d0fff2ab815150003000120e52ab81515390205dc5219010420" + "000002020620e52ab8151409090000118b0401020300ff"; + + return (packetFromCapture(hex_string)); +} + +Pkt4Ptr PktCaptures::captureBadRelayedDiscover() { + +/* Modified packet 1 with a bad RAI. + +Bootstrap Protocol + Message type: Boot Request (1) + Hardware type: Ethernet + Hardware address length: 6 + Hops: 1 + Transaction ID: 0x5d05478d + Seconds elapsed: 0 + Bootp flags: 0x0000 (Unicast) + Client IP address: 0.0.0.0 (0.0.0.0) + Your (client) IP address: 0.0.0.0 (0.0.0.0) + Next server IP address: 0.0.0.0 (0.0.0.0) + Relay agent IP address: 10.254.226.1 (10.254.226.1) + Client MAC address: Netgear_b8:15:14 (20:e5:2a:b8:15:14) + Client hardware address padding: 00000000000000000000 + Server host name not given + Boot file name not given + Magic cookie: DHCP + Option: (53) DHCP Message Type + Option: (55) Parameter Request List + Option: (60) Vendor class identifier (docsis3.0) + Option: (125) V-I Vendor-specific Information + - suboption 1 (Option Request): requesting option 2 + - suboption 5 (Modem Caps): 117 bytes + Option: (43) Vendor-Specific Information (CableLabs) + Option: (61) Client identifier + Option: (57) Maximum DHCP Message Size + Option: (82) Agent Information Option */ + + string hex_string = + "010106015d05478d000000000000000000000000000000000afee20120e52ab8151400" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000638253633501013707" + "0102030407067d3c0a646f63736973332e303a7d7f0000118b7a010102057501010102" + "010303010104010105010106010107010f0801100901030a01010b01180c01010d0200" + "400e0200100f010110040000000211010014010015013f160101170101180104190104" + "1a01041b01201c01021d01081e01201f01102001102101022201012301002401002501" + "01260200ff2701012b59020345434d030b45434d3a45524f55544552040d3242523232" + "39553430303434430504312e3034060856312e33332e30330707322e332e3052320806" + "30303039354209094347333030304443520a074e657467656172fe01083d0fff2ab815" + "140003000120e52ab81514390205dc52205141000102030405060708090a0b0c0d0e0f" + "101112131415161718191a1b1c1d"; + + return (packetFromCapture(hex_string)); +} + +Pkt4Ptr PktCaptures::discoverWithValidVIVSO() { +/* DISCOVER that contains a valid VIVSO option 125 +User Datagram Protocol, Src Port: 67, Dst Port: 67 +Bootstrap Protocol (Discover) + Message type: Boot Request (1) + Hardware type: Ethernet (0x01) + Hardware address length: 6 + Hops: 1 + Transaction ID: 0x2d5d43cb + Seconds elapsed: 0 + Bootp flags: 0x8000, Broadcast flag (Broadcast) + Client IP address: 0.0.0.0 + Your (client) IP address: 0.0.0.0 + Next server IP address: 0.0.0.0 + Relay agent IP address: 10.206.80.1 + Client MAC address: ArrisGro_5e:f7:af (78:96:84:5e:f7:af) + Client hardware address padding: 00000000000000000000 + Server host name not given + Boot file name not given + Magic cookie: DHCP + Option: (53) DHCP Message Type (Discover) + Option: (55) Parameter Request List + Option: (60) Vendor class identifier + Option: (125) V-I Vendor-specific Information + Option: (43) Vendor-Specific Information (CableLabs) + Option: (61) Client identifier + Option: (57) Maximum DHCP Message Size + Option: (82) Agent Information Option + Option: (255) End +*/ + string hex_string = + "010106012d5d43cb000080000000000000000000000000000ace50017896845ef7af0" + "000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000063825363350" + "10137070102030407067d3c0a646f63736973332e303a7d850000118b80010102057b" + "01010102010303010104010105010106010107010f0801100901030a01010b01180c0" + "1010d0201000e0201000f010110040000000211010113010114010015013f16010117" + "01011801041901041a01041b01201c01021d01081e01201f011020011021010222010" + "1230100240100250101260200ff2701012801d82b7c020345434d030b45434d3a4552" + "4f5554455208030020400418333936373739343234343335353037373031303134303" + "035050131061e534247365838322d382e362e302e302d47412d30312d3937312d4e4f" + "5348070432343030090a534247363738322d41430a144d6f746f726f6c6120436f727" + "06f726174696f6e3d0fff845ef7af000300017896845ef7af390205dc521b01048005" + "03f802067896845ef7af090b0000118b06010401020300ff"; + + return (packetFromCapture(hex_string)); +} + +Pkt4Ptr PktCaptures::discoverWithTruncatedVIVSO() { +/* DISCOVER that contains VIVSO option 125 with an INVALID length of 01 +User Datagram Protocol, Src Port: 67, Dst Port: 67 +Bootstrap Protocol (Discover) + Message type: Boot Request (1) + Hardware type: Ethernet (0x01) + Hardware address length: 6 + Hops: 1 + Transaction ID: 0x2d5d43cb + Seconds elapsed: 0 + Bootp flags: 0x8000, Broadcast flag (Broadcast) + Client IP address: 0.0.0.0 + Your (client) IP address: 0.0.0.0 + Next server IP address: 0.0.0.0 + Relay agent IP address: 10.206.80.1 + Client MAC address: ArrisGro_5e:f7:af (78:96:84:5e:f7:af) + Client hardware address padding: 00000000000000000000 + Server host name not given + Boot file name not given + Magic cookie: DHCP + Option: (53) DHCP Message Type (Discover) + Option: (55) Parameter Request List + Option: (60) Vendor class identifier + Option: (125) V-I Vendor-specific Information + Option: (43) Vendor-Specific Information (CableLabs) + Option: (61) Client identifier + Option: (57) Maximum DHCP Message Size + Option: (82) Agent Information Option + Option: (255) End +*/ + string hex_string = + "010106012d5d43cb000080000000000000000000000000000ace50017896845ef7af0" + "000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000063825363350" + "10137070102030407067d3c0a646f63736973332e303a7d010000118b80010102057b" + "01010102010303010104010105010106010107010f0801100901030a01010b01180c0" + "1010d0201000e0201000f010110040000000211010113010114010015013f16010117" + "01011801041901041a01041b01201c01021d01081e01201f011020011021010222010" + "1230100240100250101260200ff2701012801d82b7c020345434d030b45434d3a4552" + "4f5554455208030020400418333936373739343234343335353037373031303134303" + "035050131061e534247365838322d382e362e302e302d47412d30312d3937312d4e4f" + "5348070432343030090a534247363738322d41430a144d6f746f726f6c6120436f727" + "06f726174696f6e3d0fff845ef7af000300017896845ef7af390205dc521b01048005" + "03f802067896845ef7af090b0000118b06010401020300ff"; + + return (packetFromCapture(hex_string)); +} + +Pkt4Ptr PktCaptures::discoverGenexis() { + +/* Bootstrap Protocol (Discover) + Message type: Boot Request (1) + Hardware type: Ethernet (0x01) + Hardware address length: 6 + Hops: 0 + Transaction ID: 0x946a5b5a + Seconds elapsed: 0 + Bootp flags: 0x8000, Broadcast flag (Broadcast) + Client IP address: 0.0.0.0 + Your (client) IP address: 0.0.0.0 + Next server IP address: 0.0.0.0 + Relay agent IP address: 0.0.0.0 + Client MAC address: GenexisB_6a:1a:93 (00:0f:94:6a:1a:93) + Client hardware address padding: 00000000000000000000 + Server host name not given + Boot file name not given + Magic cookie: DHCP + Option: (53) DHCP Message Type (Discover) + Option: (60) Vendor class identifier (HMC1000.v1.3.0-R,Element-P1090,genexis.eu) + Option: (51) IP Address Lease Time + Option: (55) Parameter Request List + Option: (255) End + Padding: 000000000000000000000000000000000000000000000000... */ + + string hex_string = + "01010600946a5b5a0000800000000000000000000000000000000000000f946a1a9300" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000638253633501013c29" + "484d43313030302e76312e332e302d522c456c656d656e742d50313039302c67656e65" + "7869732e65753304ffffffff37040103067dff00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000"; + return (packetFromCapture(hex_string)); +} + +}; // end of isc::dhcp::test namespace +}; // end of isc::dhcp namespace +}; // end of isc namespace diff --git a/src/lib/dhcp/testutils/pkt_captures6.cc b/src/lib/dhcp/testutils/pkt_captures6.cc new file mode 100644 index 0000000..f2bd8ec --- /dev/null +++ b/src/lib/dhcp/testutils/pkt_captures6.cc @@ -0,0 +1,511 @@ +// Copyright (C) 2013-2024 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <dhcp/pkt6.h> +#include <dhcp/testutils/pkt_captures.h> +#include <util/encode/encode.h> + +#include <string> + +/// @file pkt_captures6.cc +/// +/// @brief contains packet captures imported from Wireshark +/// +/// These are actual packets captured over wire. They are used in various +/// tests. +/// +/// The procedure to export Wireshark -> unit-tests is manual, but rather +/// easy to follow: +/// 1. Open a file in wireshark +/// 2. Find the packet you want to export +/// 3. There's a protocol stack (Frame, Ethernet, IPv6, UDP, DHCPv6, ...) +/// 4. Right click on DHCPv6 -> Copy -> Bytes -> Hex Stream +/// 5. Paste it as: string hex_string="[paste here]"; +/// 6. Coding guidelines line restrictions apply, so wrap your code as necessary +/// 7. Make sure you describe the capture appropriately +/// 8. Follow whatever rest of the methods are doing (set ports, ifaces etc.) +/// 9. To easily copy packet description, click File... -> Extract packet +/// dissections -> as plain text file... +/// (Make sure that the packet is expanded in the view. The text file will +/// contain whatever expansion level you have in the graphical tree.) + +using namespace isc::dhcp; +using namespace isc::asiolink; +using namespace std; + +namespace isc { +namespace dhcp { +namespace test { + +void PktCaptures::captureSetDefaultFields(const Pkt6Ptr& pkt) { + pkt->setRemotePort(546); + pkt->setRemoteAddr(IOAddress("fe80::1")); + pkt->setLocalPort(0); + pkt->setLocalAddr(IOAddress("ff02::1:2")); + pkt->setIndex(2); + pkt->setIface("eth0"); +} + +// This function returns buffer for very simple Solicit +Pkt6Ptr PktCaptures::captureSimpleSolicit() { + uint8_t data[] = { + 1, // type 1 = SOLICIT + 0xca, 0xfe, 0x01, // trans-id = 0xcafe01 + 0, 1, // option type 1 (client-id) + 0, 10, // option length 10 + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // DUID + 0, 3, // option type 3 (IA_NA) + 0, 12, // option length 12 + 0, 0, 0, 1, // iaid = 1 + 0, 0, 0, 0, // T1 = 0 + 0, 0, 0, 0 // T2 = 0 + }; + + Pkt6Ptr pkt(new Pkt6(data, sizeof(data))); + captureSetDefaultFields(pkt); + + return (pkt); +} + +Pkt6Ptr PktCaptures::captureRelayedSolicit() { + + // This is a very simple relayed SOLICIT message: + // RELAY-FORW + // - interface-id + // - relay-message + // - SOLICIT + // - client-id + // - IA_NA (iaid=1, t1=0, t2=0) + // - ORO (7) + + // string exported from Wireshark + string hex_string = + "0c0500000000000000000000000000000000fc00000000000000000000000000000900" + "12000231350009002c010517100001000e0001000151b5e46208002758f1e80003000c" + "000000010000000000000000000600020007"; + + std::vector<uint8_t> bin; + + // Decode the hex string and store it in bin (which happens + // to be OptionBuffer format) + isc::util::encode::decodeHex(hex_string, bin); + + Pkt6Ptr pkt(new Pkt6(&bin[0], bin.size())); + captureSetDefaultFields(pkt); + + return (pkt); +} + +/// returns a buffer with relayed SOLICIT (from DOCSIS3.0 cable modem) +Pkt6Ptr PktCaptures::captureDocsisRelayedSolicit() { + + // This is an actual DOCSIS packet + // RELAY-FORW (12) + // - Relay Message + // - SOLICIT (1) + // - client-id + // - IA_NA (iaid=7f000788, t2=0, t2=0) + // - IAAddress (::, pref=0,valid=0) + // - rapid-commit + // - elapsed + // - ORO + // - Reconfigure-accept + // - Vendor-Class ("docsis3.0") + // - Vendor-specific Info + // - subopt 1: Option request = 32,33,34,37,38 + // - subopt 36: Device identifier + // - subopt 35: TLV5 + // - subopt 2: Device type = ECM + // - subopt 3: Embedded components + // - subopt 4: Serial Number + // - subopt 5: Hardware version + // - subopt 6: Software version + // - subopt 7: Boot ROM Version + // - subopt 8: Organization Unique Identifier + // - subopt 9: Model Number + // - subopt 10: Vendor Name (Netgear) + // - subopt 15: unknown + // - Interface-Id + // - Vendor-specific Information + // - Suboption 1025: CMTS capabilities + // - Suboption 1026: Cable Modem MAC addr = 10:0d:7f:00:07:88 + + // string exported from Wireshark + string hex_string = + "0c002a0288fe00fe00015a8d09fffe7af955fe80000000000000120d7ffffe00078800" + "090189010d397f0001000a00030001100d7f000788000300287f000788000000000000" + "000000050018000000000000000000000000000000000000000000000000000e000000" + "0800020000000600020011001400000010000f0000118b0009646f63736973332e3000" + "1101200000118b0001000a0020002100220025002600240006100d7f00078800230081" + "0101010201030301010401010501010601010701180801080901000a01010b01180c01" + "010d0200400e0200100f01011004000000021101011301011401001501381601011701" + "011801041901041a01041b01281c01021d01081e01201f011020011821010222010123" + "010124011825010126020040270101120701100d7f00078a0002000345434d0003000b" + "45434d3a45524f555445520004000d3335463132395550303030353200050004332e31" + "310006000956312e30312e31315400070013505350552d426f6f7420312e302e31362e" + "323200080006303030393542000900084347343030305444000a00074e657467656172" + "000f000745524f5554455200120012427531264361312f3000100d7f00078800000011" + "00160000118b040100040102030004020006100d7f000788"; + + std::vector<uint8_t> bin; + + // Decode the hex string and store it in bin (which happens + // to be OptionBuffer format) + isc::util::encode::decodeHex(hex_string, bin); + + Pkt6Ptr pkt(new Pkt6(&bin[0], bin.size())); + captureSetDefaultFields(pkt); + return (pkt); +} + +/// returns a buffer with relayed SOLICIT (from DOCSIS3.0 eRouter) +Pkt6Ptr PktCaptures::captureeRouterRelayedSolicit() { + +/* Packet description exported from wireshark: +DHCPv6 + Message type: Relay-forw (12) + Hopcount: 0 + Link address: 2001:558:ffa8::1 (2001:558:ffa8::1) + Peer address: fe80::22e5:2aff:feb8:1515 (fe80::22e5:2aff:feb8:1515) + Relay Message + Option: Relay Message (9) + Length: 241 + Value: 01a90044000e000000140000000600080011001700180019... + DHCPv6 + Message type: Solicit (1) + Transaction ID: 0xa90044 + Rapid Commit + Option: Rapid Commit (14) + Length: 0 + Reconfigure Accept + Option: Reconfigure Accept (20) + Length: 0 + Option Request + Option: Option Request (6) + Length: 8 + Value: 0011001700180019 + Requested Option code: Vendor-specific Information (17) + Requested Option code: DNS recursive name server (23) + Requested Option code: Domain Search List (24) + Requested Option code: Identity Association for Prefix Delegation (25) + Vendor Class + Option: Vendor Class (16) + Length: 16 + Value: 0000118b000a65526f75746572312e30 + Enterprise ID: Cable Television Laboratories, Inc. (4491) + vendor-class-data: eRouter1.0 + Vendor-specific Information + Option: Vendor-specific Information (17) + Length: 112 + Value: 0000118b0002000745524f555445520003000b45434d3a45... + Enterprise ID: Cable Television Laboratories, Inc. (4491) + Suboption: Device Type = (2)"EROUTER" + Suboption: Embedded Components = (3)"ECM:EROUTER" + Suboption: Serial Number = (4)"2BR229U40044C" + Suboption: Hardware Version = (5)"1.04" + Suboption: Software Version = (6)"V1.33.03" + Suboption: Boot ROM Version = (7)"2.3.0R2" + Suboption: Organization Unique Identifier = (8)"00095B" + Suboption: Model Number = (9)"CG3000DCR" + Suboption: Vendor Name = (10)"Netgear" + Client Identifier + Option: Client Identifier (1) + Length: 10 + Value: 0003000120e52ab81515 + DUID: 0003000120e52ab81515 + DUID Type: link-layer address (3) + Hardware type: Ethernet (1) + Link-layer address: 20:e5:2a:b8:15:15 + Identity Association for Prefix Delegation + Option: Identity Association for Prefix Delegation (25) + Length: 41 + Value: 2ab815150000000000000000001a00190000000000000000... + IAID: 2ab81515 + T1: 0 + T2: 0 + IA Prefix + Option: IA Prefix (26) + Length: 25 + Value: 000000000000000038000000000000000000000000000000... + Preferred lifetime: 0 + Valid lifetime: 0 + Prefix length: 56 + Prefix address: :: (::) + Identity Association for Non-temporary Address + Option: Identity Association for Non-temporary Address (3) + Length: 12 + Value: 2ab815150000000000000000 + IAID: 2ab81515 + T1: 0 + T2: 0 + Elapsed time + Option: Elapsed time (8) + Length: 2 + Value: 0000 + Elapsed time: 0 ms + Vendor-specific Information + Option: Vendor-specific Information (17) + Length: 22 + Value: 0000118b0402000620e52ab815140401000401020300 + Enterprise ID: Cable Television Laboratories, Inc. (4491) + Suboption: CM MAC Address Option = (1026)20:e5:2a:b8:15:14 + Suboption: CMTS Capabilities Option : (1025) + Interface-Id + Option: Interface-Id (18) + Length: 4 + Value: 00000022 + Interface-ID: + Remote Identifier + Option: Remote Identifier (37) + Length: 14 + Value: 0000101300015c228d4110000122 + Enterprise ID: Arris Interactive LLC (4115) + Remote-ID: 00015c228d4110000122 + DHCP option 53 + Option: Unknown (53) + Length: 10 + Value: 0003000100015c228d3d + DUID: 0003000100015c228d3d + DUID Type: link-layer address (3) + Hardware type: Ethernet (1) + Link-layer address: 00:01:5c:22:8d:3d */ + + // string exported from Wireshark + string hex_string = + "0c0020010558ffa800000000000000000001fe8000000000000022e52afffeb8151500" + "0900f101a90044000e000000140000000600080011001700180019001000100000118b" + "000a65526f75746572312e30001100700000118b0002000745524f555445520003000b" + "45434d3a45524f555445520004000d3242523232395534303034344300050004312e30" + "340006000856312e33332e303300070007322e332e3052320008000630303039354200" + "090009434733303030444352000a00074e6574676561720001000a0003000120e52ab8" + "1515001900292ab815150000000000000000001a001900000000000000003800000000" + "0000000000000000000000000003000c2ab81515000000000000000000080002000000" + "1100160000118b0402000620e52ab81514040100040102030000120004000000220025" + "000e0000101300015c228d41100001220035000a0003000100015c228d3d"; + + std::vector<uint8_t> bin; + + // Decode the hex string and store it in bin (which happens + // to be OptionBuffer format) + isc::util::encode::decodeHex(hex_string, bin); + + Pkt6Ptr pkt(new Pkt6(&bin[0], bin.size())); + captureSetDefaultFields(pkt); + return (pkt); +} + +Pkt6Ptr PktCaptures::captureCableLabsShortVendorClass() { + // This is a simple non-relayed Solicit: + // - client-identifier + // - IA_NA + // - Vendor Class (4 bytes) + // - enterprise-id 4491 + // - Vendor-specific Information + // - enterprise-id 4491 + std::string hex_string = + "01671cb90001000e0001000152ea903a08002758f1e80003000c00004bd10000000000" + "000000001000040000118b0011000a0000118b000100020020"; + + std::vector<uint8_t> bin; + + // Decode the hex string and store it in bin (which happens + // to be OptionBuffer format) + isc::util::encode::decodeHex(hex_string, bin); + + Pkt6Ptr pkt(new Pkt6(&bin[0], bin.size())); + captureSetDefaultFields(pkt); + return (pkt); + +} + +/// @brief creates doubly relayed solicit message +/// +/// This is a traffic capture exported from wireshark and manually modified +/// to include necessary options (RSOO). It includes a SOLICIT message +/// that passed through two relays. It is especially interesting, +/// because of the following properties: +/// - double encapsulation +/// - first relay inserts relay-msg before extra options +/// - second relay inserts relay-msg after extra options +/// - both relays are from different vendors +/// - interface-id are different for each relay +/// - first relay inserts valid remote-id +/// - second relay inserts remote-id with empty vendor data +/// - the solicit message requests for custom options in ORO +/// - there are option types in RELAY-FORW that do not appear in SOLICIT +/// - there are option types in SOLICT that do not appear in RELAY-FORW +/// +/// RELAY-FORW +/// - relay message option +/// - RELAY-FORW +/// - rsoo (66) +/// - option 255 (len 4) +/// - option 256 (len 9) +/// - remote-id option (37) +/// - relay message option +/// - SOLICIT +/// - client-id option +/// - ia_na option +/// - elapsed time +/// - ORO +/// - interface-id option (18) +/// - remote-id option (37) +/// +/// The original capture was posted to dibbler users mailing list. +/// +/// @return created double relayed SOLICIT message +isc::dhcp::Pkt6Ptr PktCaptures::captureRelayed2xRSOO() { + + // string exported from Wireshark + string hex_string = + "0c01200108880db800010000000000000000fe80000000000000020021fffe5c18a9" + "0009007d0c0000000000000000000000000000000000fe80000000000000020021fffe5c18a9" + "00420015" // RSOO (includes ... + "00ff000401020304" // ... option 255, len 4, content 0x01020304 + "01000009010203040506070809" // ... option 256, len 9, content 0x010203040506070809 + "0025000400000de9" // remote-id + "00090036" // relay-msg, len 54 + "016b4fe2" // solicit" + "0001000e0001000118b033410000215c18a9" // client-id + "0003000c00000001ffffffffffffffff" // ia-na + "000800020000" + "00060006001700f200f3" + "0012001c4953414d3134347c3239397c697076367c6e743a76703a313a" // vendor-class + "313130002500120000197f0001000118b033410000215c18a9"; + + std::vector<uint8_t> bin; + + // Decode the hex string and store it in bin (which happens + // to be OptionBuffer format) + isc::util::encode::decodeHex(hex_string, bin); + + Pkt6Ptr pkt(new Pkt6(&bin[0], bin.size())); + pkt->setRemotePort(547); + pkt->setRemoteAddr(IOAddress("fe80::1234")); + pkt->setLocalPort(547); + pkt->setLocalAddr(IOAddress("ff05::1:3")); + pkt->setIndex(2); + pkt->setIface("eth0"); + return (pkt); +} + +isc::dhcp::Pkt6Ptr PktCaptures::captureSolicitWithVIVSO() { + + // Message type: Solicit (1) + // Transaction ID: 0xba048e + // Client Identifier + // Option: Client Identifier (1) + // Length: 10 + // Value: 0003000108002725d3f4 + // DUID: 0003000108002725d3f4 + // DUID Type: link-layer address (3) + // Hardware type: Ethernet (1) + // Link-layer address: 08:00:27:25:d3:f4 + // Identity Association for Non-temporary Address + // Option: Identity Association for Non-temporary Address (3) + // Length: 40 + // Value: 00aabbcc0000000000000000000500180000000000000000... + // IAID: 00aabbcc + // T1: 0 + // T2: 0 + // IA Address + // Option: IA Address (5) + // Length: 24 + // Value: 000000000000000000000000000000000000000000000000 + // IPv6 address: :: + // Preferred lifetime: 0 + // Valid lifetime: + // Option Request + // Option: Option Request (6) + // Length: 6 + // Value: 00d100d2000c + // Vendor-specific Information + // Option: Vendor-specific Information (17) + // Length: 4 + // Value: 00001e61 + // Enterprise ID: E-DYNAMICS.ORG (7777) + string hex_string = + "01ba048e0001000a0003000108002725d3f40003002800aabbcc" + "00000000000000000005001800000000000000000000000000000" + "00000000000000000000006000600d100d2000c0011000400001e61"; + + std::vector<uint8_t> bin; + + // Decode the hex string and store it in bin (which happens + // to be OptionBuffer format) + isc::util::encode::decodeHex(hex_string, bin); + + Pkt6Ptr pkt(new Pkt6(&bin[0], bin.size())); + pkt->setRemotePort(547); + pkt->setRemoteAddr(IOAddress("fe80::1234")); + pkt->setLocalPort(547); + pkt->setLocalAddr(IOAddress("ff05::1:3")); + pkt->setIndex(2); + pkt->setIface("eth0"); + return (pkt); +} + +isc::dhcp::Pkt6Ptr PktCaptures::captureSolicitWithTruncatedVIVSO() { + + // Message type: Solicit (1) + // Transaction ID: 0xba048e + // Client Identifier + // Option: Client Identifier (1) + // Length: 10 + // Value: 0003000108002725d3f4 + // DUID: 0003000108002725d3f4 + // DUID Type: link-layer address (3) + // Hardware type: Ethernet (1) + // Link-layer address: 08:00:27:25:d3:f4 + // Identity Association for Non-temporary Address + // Option: Identity Association for Non-temporary Address (3) + // Length: 40 + // Value: 00aabbcc0000000000000000000500180000000000000000... + // IAID: 00aabbcc + // T1: 0 + // T2: 0 + // IA Address + // Option: IA Address (5) + // Length: 24 + // Value: 000000000000000000000000000000000000000000000000 + // IPv6 address: :: + // Preferred lifetime: 0 + // Valid lifetime: + // Option Request + // Option: Option Request (6) + // Length: 6 + // Value: 00d100d2000c + // Vendor-specific Information + // Option: Vendor-specific Information (17) + // Length: 1 <-------- length too short! + // Value: 00001e61 + // Enterprise ID: E-DYNAMICS.ORG (7777) + string hex_string = + "01ba048e0001000a0003000108002725d3f40003002800aabbcc" + "00000000000000000005001800000000000000000000000000000" + "00000000000000000000006000600d100d2000c0011000100001e61"; + + std::vector<uint8_t> bin; + + // Decode the hex string and store it in bin (which happens + // to be OptionBuffer format) + isc::util::encode::decodeHex(hex_string, bin); + + Pkt6Ptr pkt(new Pkt6(&bin[0], bin.size())); + pkt->setRemotePort(547); + pkt->setRemoteAddr(IOAddress("fe80::1234")); + pkt->setLocalPort(547); + pkt->setLocalAddr(IOAddress("ff05::1:3")); + pkt->setIndex(2); + pkt->setIface("eth0"); + return (pkt); +} + +}; // end of isc::dhcp::test namespace +}; // end of isc::dhcp namespace +}; // end of isc namespace diff --git a/src/lib/dhcp/testutils/pkt_filter6_test_stub.cc b/src/lib/dhcp/testutils/pkt_filter6_test_stub.cc new file mode 100644 index 0000000..0a2cb4b --- /dev/null +++ b/src/lib/dhcp/testutils/pkt_filter6_test_stub.cc @@ -0,0 +1,48 @@ +// Copyright (C) 2014-2023 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> +#include <fcntl.h> + +#include <dhcp/testutils/pkt_filter6_test_stub.h> + +namespace isc { +namespace dhcp { +namespace test { + +PktFilter6TestStub::PktFilter6TestStub() : open_socket_callback_() { +} + +SocketInfo +PktFilter6TestStub::openSocket(const Iface&, + const isc::asiolink::IOAddress& addr, + const uint16_t port, const bool) { + if (open_socket_callback_) { + open_socket_callback_(port); + } + + return (SocketInfo(addr, port, 0)); +} + +Pkt6Ptr +PktFilter6TestStub::receive(const SocketInfo&) { + return Pkt6Ptr(); +} + +bool +PktFilter6TestStub::joinMulticast(int, const std::string&, + const std::string &) { + return (true); +} + +int +PktFilter6TestStub::send(const Iface&, uint16_t, const Pkt6Ptr&) { + return (0); +} + +} +} +} diff --git a/src/lib/dhcp/testutils/pkt_filter6_test_stub.h b/src/lib/dhcp/testutils/pkt_filter6_test_stub.h new file mode 100644 index 0000000..6cf6e52 --- /dev/null +++ b/src/lib/dhcp/testutils/pkt_filter6_test_stub.h @@ -0,0 +1,107 @@ +// Copyright (C) 2014-2023 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef PKT_FILTER6_TEST_STUB_H +#define PKT_FILTER6_TEST_STUB_H + +#include <asiolink/io_address.h> +#include <dhcp/iface_mgr.h> +#include <dhcp/pkt_filter6.h> +#include <dhcp/pkt6.h> + +namespace isc { +namespace dhcp { +namespace test { + +/// @brief An open socket callback that can be use for a testing purposes. +/// +/// @param port Port number to bind socket to. +typedef std::function<void(uint16_t port)> PktFilter6OpenSocketCallback; + +/// @brief A stub implementation of the PktFilter6 class. +/// +/// This class implements abstract methods of the @c isc::dhcp::PktFilter6 +/// class. It is used by unit tests, which test protected methods of the +/// @c isc::dhcp::test::PktFilter6 class. The implemented abstract methods are +/// no-op. +class PktFilter6TestStub : public PktFilter6 { +public: + + /// @brief Constructor. + PktFilter6TestStub(); + + /// @brief Simulate opening of the socket. + /// + /// This function simulates opening a primary socket. In reality, it doesn't + /// open a socket but the socket descriptor returned in the SocketInfo + /// structure is always set to 0. + /// + /// @param iface An interface descriptor. + /// @param addr Address on the interface to be used to send packets. + /// @param port Port number to bind socket to. + /// @param join_multicast A flag which indicates if the socket should be + /// configured to join multicast (if true). + /// + /// @note All parameters are ignored. + /// + /// @return A SocketInfo structure with the socket descriptor set to 0. The + /// fallback socket descriptor is set to a negative value. + virtual SocketInfo openSocket(const Iface& iface, + const isc::asiolink::IOAddress& addr, + const uint16_t port, + const bool join_multicast); + + /// @brief Simulate reception of the DHCPv6 message. + /// + /// @param socket_info A structure holding socket information. + /// + /// @note All parameters are ignored. + /// + /// @return always a NULL object. + virtual Pkt6Ptr receive(const SocketInfo& socket_info); + + /// @brief Simulates sending a DHCPv6 message. + /// + /// This function does nothing. + /// + /// @param iface An interface to be used to send DHCPv6 message. + /// @param port A port used to send a message. + /// @param pkt A DHCPv6 to be sent. + /// + /// @note All parameters are ignored. + /// + /// @return 0. + virtual int send(const Iface& iface, uint16_t port, const Pkt6Ptr& pkt); + + /// @brief Simulate joining IPv6 multicast group on a socket. + /// + /// @note All parameters are ignored. + /// + /// @param sock A socket descriptor (socket must be bound). + /// @param ifname An interface name (for link-scoped multicast groups). + /// @param mcast A multicast address to join (e.g. "ff02::1:2"). + /// + /// @return true if multicast join was successful + static bool joinMulticast(int sock, const std::string& ifname, + const std::string & mcast); + + /// @brief Set an open socket callback. Use it for testing + /// purposes, e.g. counting the number of calls or throwing an exception. + void setOpenSocketCallback(PktFilter6OpenSocketCallback callback) { + open_socket_callback_ = callback; + } + +private: + + /// @brief The callback used when opening socket. + PktFilter6OpenSocketCallback open_socket_callback_; +}; + +} // namespace isc::dhcp::test +} // namespace isc::dhcp +} // namespace isc + +#endif // PKT_FILTER6_TEST_STUB_H diff --git a/src/lib/dhcp/testutils/pkt_filter_test_stub.cc b/src/lib/dhcp/testutils/pkt_filter_test_stub.cc new file mode 100644 index 0000000..7fa4104 --- /dev/null +++ b/src/lib/dhcp/testutils/pkt_filter_test_stub.cc @@ -0,0 +1,66 @@ +// Copyright (C) 2014-2024 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> + +#include <dhcp/testutils/pkt_filter_test_stub.h> + +namespace isc { +namespace dhcp { +namespace test { + +PktFilterTestStub::PktFilterTestStub() + : direct_response_supported_(true), open_socket_callback_() { +} + +bool +PktFilterTestStub::isDirectResponseSupported() const { + return (direct_response_supported_); +} + +bool +PktFilterTestStub::isSocketReceivedTimeSupported() const { +#ifdef SO_TIMESTAMP + return (true); +#else + return (false); +#endif +} + +SocketInfo +PktFilterTestStub::openSocket(Iface&, + const isc::asiolink::IOAddress& addr, + const uint16_t port, const bool, const bool) { + int fd = open("/dev/null", O_RDONLY); + if (fd < 0) { + const char* errmsg = strerror(errno); + isc_throw(Unexpected, + "PktFilterTestStub: cannot open /dev/null:" << errmsg); + } + + if (open_socket_callback_) { + open_socket_callback_(port); + } + + return (SocketInfo(addr, port, fd)); +} + +Pkt4Ptr +PktFilterTestStub::receive(Iface&, const SocketInfo&) { + return Pkt4Ptr(); +} + +int +PktFilterTestStub::send(const Iface&, uint16_t, const Pkt4Ptr&) { + return (0); +} + +} +} +} diff --git a/src/lib/dhcp/testutils/pkt_filter_test_stub.h b/src/lib/dhcp/testutils/pkt_filter_test_stub.h new file mode 100644 index 0000000..22df019 --- /dev/null +++ b/src/lib/dhcp/testutils/pkt_filter_test_stub.h @@ -0,0 +1,126 @@ +// Copyright (C) 2014-2024 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef PKT_FILTER_TEST_STUB_H +#define PKT_FILTER_TEST_STUB_H + +#include <asiolink/io_address.h> +#include <dhcp/iface_mgr.h> +#include <dhcp/pkt_filter.h> +#include <dhcp/pkt4.h> + +namespace isc { +namespace dhcp { +namespace test { + +/// @brief An open socket callback that can be use for a testing purposes. +/// +/// @param port Port number to bind socket to. +typedef std::function<void(uint16_t port)> PktFilterOpenSocketCallback; + +/// @brief A stub implementation of the PktFilter class. +/// +/// This class implements abstract methods of the @c isc::dhcp::PktFilter +/// class. It is used by unit tests, which test protected methods of the +/// @c isc::dhcp::test::PktFilter class. The implemented abstract methods are +/// no-op. +class PktFilterTestStub : public PktFilter { +public: + + /// @brief Constructor. + PktFilterTestStub(); + + /// @brief Checks if the direct DHCPv4 response is supported. + /// + /// This function checks if the direct response capability is supported, + /// i.e. if the server can respond to the client which doesn't have an + /// address yet. For this dummy class, the true is always returned. + /// + /// @return always true. + virtual bool isDirectResponseSupported() const; + + /// @brief Check if the socket received time is supported. + /// + /// If true, then packets received through this filter will include + /// a SOCKET_RECEIVED event in its event stack. Other than direct + /// clients using BPF for which this is always true, this function + /// is true provided SO_TIMESTAMP is defined. + /// + /// @return True if it is supported. + virtual bool isSocketReceivedTimeSupported() const; + + /// @brief Simulate opening of the socket. + /// + /// This function simulates opening a primary socket. Rather than open + /// an actual socket, the stub performs a read-only open of "/dev/null". + /// The fd returned by this open saved as the socket's descriptor in the + /// SocketInfo structure. This way the filter consumes an actual + /// descriptor and retains it until its socket is closed. + /// + /// @param iface An interface descriptor. + /// @param addr Address on the interface to be used to send packets. + /// @param port Port number to bind socket to. + /// @param receive_bcast A flag which indicates if socket should be + /// configured to receive broadcast packets (if true). + /// @param send_bcast A flag which indicates if the socket should be + /// configured to send broadcast packets (if true). + /// + /// @note All parameters are ignored. + /// + /// @return A SocketInfo structure with the socket descriptor set to 0. The + /// fallback socket descriptor is set to a negative value. + virtual SocketInfo openSocket(Iface& iface, + const isc::asiolink::IOAddress& addr, + const uint16_t port, + const bool receive_bcast, + const bool send_bcast); + + /// @brief Simulate reception of the DHCPv4 message. + /// + /// @param iface An interface to be used to receive DHCPv4 message. + /// @param sock_info A descriptor of the primary and fallback sockets. + /// + /// @note All parameters are ignored. + /// + /// @return always a NULL object. + virtual Pkt4Ptr receive(Iface& iface, const SocketInfo& sock_info); + + /// @brief Simulates sending a DHCPv4 message. + /// + /// This function does nothing. + /// + /// @param iface An interface to be used to send DHCPv4 message. + /// @param port A port used to send a message. + /// @param pkt A DHCPv4 to be sent. + /// + /// @note All parameters are ignored. + /// + /// @return 0. + virtual int send(const Iface& iface, uint16_t port, const Pkt4Ptr& pkt); + + // Change the scope of the protected function so as they can be unit tested. + using PktFilter::openFallbackSocket; + + /// @brief Set an open socket callback. Use it for testing + /// purposes, e.g. counting the number of calls or throwing an exception. + void setOpenSocketCallback(PktFilterOpenSocketCallback callback) { + open_socket_callback_ = callback; + } + + /// @brief Flag which indicates if direct response capability is supported. + bool direct_response_supported_; + +private: + + /// @brief The callback used when opening socket. + PktFilterOpenSocketCallback open_socket_callback_; +}; + +} // namespace isc::dhcp::test +} // namespace isc::dhcp +} // namespace isc + +#endif // PKT_FILTER_TEST_STUB_H |