diff options
Diffstat (limited to 'src/dhcp-manager')
21 files changed, 1853 insertions, 1135 deletions
diff --git a/src/dhcp-manager/Makefile.am b/src/dhcp-manager/Makefile.am index f32a2167..63eac9d5 100644 --- a/src/dhcp-manager/Makefile.am +++ b/src/dhcp-manager/Makefile.am @@ -1,71 +1,23 @@ -SUBDIRS = . tests +libexec_PROGRAMS = nm-dhcp-helper -AM_CPPFLAGS = \ - -I${top_srcdir} \ - -I${top_builddir}/include \ - -I${top_srcdir}/include \ - -I${top_builddir}/src/generated \ - -I${top_srcdir}/src/generated \ - -I${top_srcdir}/src/logging \ - -I${top_srcdir}/src/posix-signals \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ - -I${top_srcdir}/src \ - -DRUNDIR=\"$(rundir)\" +nm_dhcp_helper_SOURCES = nm-dhcp-helper.c -noinst_LTLIBRARIES = libdhcp-manager.la libdhcp-dhclient.la - -################## dhclient ################## - -libdhcp_dhclient_la_SOURCES = \ - nm-dhcp-dhclient-utils.h \ - nm-dhcp-dhclient-utils.c \ - nm-dhcp-dhclient.h \ - nm-dhcp-dhclient.c - -libdhcp_dhclient_la_CPPFLAGS = \ +nm_dhcp_helper_CPPFLAGS = \ $(DBUS_CFLAGS) \ - $(GLIB_CFLAGS) \ - $(AM_CPPFLAGS) \ - -DSYSCONFDIR=\"$(sysconfdir)\" \ - -DLIBEXECDIR=\"$(libexecdir)\" \ - -DLOCALSTATEDIR=\"$(localstatedir)\" \ - -DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \ - -DNMSTATEDIR=\"$(nmstatedir)\" \ - -DNMCONFDIR=\"$(nmconfdir)\" + -DG_LOG_DOMAIN=\""nm-dhcp-helper"\" \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + -DNMRUNDIR=\"$(nmrundir)\" -libdhcp_dhclient_la_LIBADD = \ - $(top_builddir)/src/logging/libnm-logging.la \ - $(top_builddir)/src/posix-signals/libnm-posix-signals.la \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(DBUS_LIBS) \ - $(GLIB_LIBS) +nm_dhcp_helper_LDADD = $(DBUS_LIBS) -################## main lib ################## -libdhcp_manager_la_SOURCES = \ - nm-dhcp-client.c \ - nm-dhcp-client.h \ - nm-dhcp-manager.c \ - nm-dhcp-manager.h \ - nm-dhcp-dhcpcd.h \ - nm-dhcp-dhcpcd.c +# FIXME: remove when dbus-glib >= 0.100 is required +dhcp_helper_conf = nm-dhcp-helper.conf -libdhcp_manager_la_CPPFLAGS = \ - $(DBUS_CFLAGS) \ - $(GLIB_CFLAGS) \ - $(AM_CPPFLAGS) \ - -DSYSCONFDIR=\"$(sysconfdir)\" \ - -DLIBEXECDIR=\"$(libexecdir)\" \ - -DLOCALSTATEDIR=\"$(localstatedir)\" \ - -DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \ - -DDHCPCD_PATH=\"$(DHCPCD_PATH)\" \ - -DNMSTATEDIR=\"$(nmstatedir)\" +if !HAVE_DBUS_GLIB_100 +dbusservicedir = $(DBUS_SYS_DIR) +dbusservice_DATA = $(dhcp_helper_conf) +endif -libdhcp_manager_la_LIBADD = \ - $(top_builddir)/src/logging/libnm-logging.la \ - $(top_builddir)/src/posix-signals/libnm-posix-signals.la \ - $(builddir)/libdhcp-dhclient.la \ - $(DBUS_LIBS) \ - $(GLIB_LIBS) +EXTRA_DIST = $(dhcp_helper_conf) diff --git a/src/dhcp-manager/Makefile.in b/src/dhcp-manager/Makefile.in index db4b0c91..5495b12f 100644 --- a/src/dhcp-manager/Makefile.in +++ b/src/dhcp-manager/Makefile.in @@ -14,6 +14,7 @@ @SET_MAKE@ + VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ @@ -78,11 +79,13 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +libexec_PROGRAMS = nm-dhcp-helper$(EXEEXT) subdir = src/dhcp-manager DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/build-aux/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -100,30 +103,17 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) +am__installdirs = "$(DESTDIR)$(libexecdir)" \ + "$(DESTDIR)$(dbusservicedir)" +PROGRAMS = $(libexec_PROGRAMS) +am_nm_dhcp_helper_OBJECTS = nm_dhcp_helper-nm-dhcp-helper.$(OBJEXT) +nm_dhcp_helper_OBJECTS = $(am_nm_dhcp_helper_OBJECTS) am__DEPENDENCIES_1 = -libdhcp_dhclient_la_DEPENDENCIES = \ - $(top_builddir)/src/logging/libnm-logging.la \ - $(top_builddir)/src/posix-signals/libnm-posix-signals.la \ - $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) -am_libdhcp_dhclient_la_OBJECTS = \ - libdhcp_dhclient_la-nm-dhcp-dhclient-utils.lo \ - libdhcp_dhclient_la-nm-dhcp-dhclient.lo -libdhcp_dhclient_la_OBJECTS = $(am_libdhcp_dhclient_la_OBJECTS) +nm_dhcp_helper_DEPENDENCIES = $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -libdhcp_manager_la_DEPENDENCIES = \ - $(top_builddir)/src/logging/libnm-logging.la \ - $(top_builddir)/src/posix-signals/libnm-posix-signals.la \ - $(builddir)/libdhcp-dhclient.la $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) -am_libdhcp_manager_la_OBJECTS = libdhcp_manager_la-nm-dhcp-client.lo \ - libdhcp_manager_la-nm-dhcp-manager.lo \ - libdhcp_manager_la-nm-dhcp-dhcpcd.lo -libdhcp_manager_la_OBJECTS = $(am_libdhcp_manager_la_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -158,30 +148,41 @@ 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 = $(libdhcp_dhclient_la_SOURCES) $(libdhcp_manager_la_SOURCES) -DIST_SOURCES = $(libdhcp_dhclient_la_SOURCES) \ - $(libdhcp_manager_la_SOURCES) -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 +SOURCES = $(nm_dhcp_helper_SOURCES) +DIST_SOURCES = $(nm_dhcp_helper_SOURCES) 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 +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +DATA = $(dbusservice_DATA) 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 @@ -201,33 +202,7 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -DIST_SUBDIRS = $(SUBDIRS) 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@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ @@ -253,12 +228,15 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIRNAME = @DATADIRNAME@ DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ DBUS_LIBS = @DBUS_LIBS@ DBUS_SYS_DIR = @DBUS_SYS_DIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ DNSMASQ_PATH = @DNSMASQ_PATH@ DSYMUTIL = @DSYMUTIL@ @@ -283,7 +261,6 @@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GTKDOC_CHECK = @GTKDOC_CHECK@ -GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ @@ -328,12 +305,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -350,6 +331,8 @@ MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ @@ -377,11 +360,16 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POLKIT_CFLAGS = @POLKIT_CFLAGS@ POLKIT_LIBS = @POLKIT_LIBS@ POSUB = @POSUB@ +PPPD_PATH = @PPPD_PATH@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -396,6 +384,7 @@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ VAPIGEN = @VAPIGEN@ VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ @@ -458,6 +447,7 @@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ +subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ target_alias = @target_alias@ @@ -468,76 +458,22 @@ with_dhclient = @with_dhclient@ with_dhcpcd = @with_dhcpcd@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ -SUBDIRS = . tests -AM_CPPFLAGS = \ - -I${top_srcdir} \ - -I${top_builddir}/include \ - -I${top_srcdir}/include \ - -I${top_builddir}/src/generated \ - -I${top_srcdir}/src/generated \ - -I${top_srcdir}/src/logging \ - -I${top_srcdir}/src/posix-signals \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ - -I${top_srcdir}/src \ - -DRUNDIR=\"$(rundir)\" - -noinst_LTLIBRARIES = libdhcp-manager.la libdhcp-dhclient.la - -################## dhclient ################## -libdhcp_dhclient_la_SOURCES = \ - nm-dhcp-dhclient-utils.h \ - nm-dhcp-dhclient-utils.c \ - nm-dhcp-dhclient.h \ - nm-dhcp-dhclient.c - -libdhcp_dhclient_la_CPPFLAGS = \ +with_valgrind = @with_valgrind@ +nm_dhcp_helper_SOURCES = nm-dhcp-helper.c +nm_dhcp_helper_CPPFLAGS = \ $(DBUS_CFLAGS) \ - $(GLIB_CFLAGS) \ - $(AM_CPPFLAGS) \ - -DSYSCONFDIR=\"$(sysconfdir)\" \ - -DLIBEXECDIR=\"$(libexecdir)\" \ - -DLOCALSTATEDIR=\"$(localstatedir)\" \ - -DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \ - -DNMSTATEDIR=\"$(nmstatedir)\" \ - -DNMCONFDIR=\"$(nmconfdir)\" - -libdhcp_dhclient_la_LIBADD = \ - $(top_builddir)/src/logging/libnm-logging.la \ - $(top_builddir)/src/posix-signals/libnm-posix-signals.la \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(DBUS_LIBS) \ - $(GLIB_LIBS) - - -################## main lib ################## -libdhcp_manager_la_SOURCES = \ - nm-dhcp-client.c \ - nm-dhcp-client.h \ - nm-dhcp-manager.c \ - nm-dhcp-manager.h \ - nm-dhcp-dhcpcd.h \ - nm-dhcp-dhcpcd.c - -libdhcp_manager_la_CPPFLAGS = \ - $(DBUS_CFLAGS) \ - $(GLIB_CFLAGS) \ - $(AM_CPPFLAGS) \ - -DSYSCONFDIR=\"$(sysconfdir)\" \ - -DLIBEXECDIR=\"$(libexecdir)\" \ - -DLOCALSTATEDIR=\"$(localstatedir)\" \ - -DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \ - -DDHCPCD_PATH=\"$(DHCPCD_PATH)\" \ - -DNMSTATEDIR=\"$(nmstatedir)\" - -libdhcp_manager_la_LIBADD = \ - $(top_builddir)/src/logging/libnm-logging.la \ - $(top_builddir)/src/posix-signals/libnm-posix-signals.la \ - $(builddir)/libdhcp-dhclient.la \ - $(DBUS_LIBS) \ - $(GLIB_LIBS) - -all: all-recursive + -DG_LOG_DOMAIN=\""nm-dhcp-helper"\" \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + -DNMRUNDIR=\"$(nmrundir)\" + +nm_dhcp_helper_LDADD = $(DBUS_LIBS) + +# FIXME: remove when dbus-glib >= 0.100 is required +dhcp_helper_conf = nm-dhcp-helper.conf +@HAVE_DBUS_GLIB_100_FALSE@dbusservicedir = $(DBUS_SYS_DIR) +@HAVE_DBUS_GLIB_100_FALSE@dbusservice_DATA = $(dhcp_helper_conf) +EXTRA_DIST = $(dhcp_helper_conf) +all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj @@ -571,23 +507,59 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(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}; \ - } - -libdhcp-dhclient.la: $(libdhcp_dhclient_la_OBJECTS) $(libdhcp_dhclient_la_DEPENDENCIES) $(EXTRA_libdhcp_dhclient_la_DEPENDENCIES) - $(AM_V_CCLD)$(LINK) $(libdhcp_dhclient_la_OBJECTS) $(libdhcp_dhclient_la_LIBADD) $(LIBS) - -libdhcp-manager.la: $(libdhcp_manager_la_OBJECTS) $(libdhcp_manager_la_DEPENDENCIES) $(EXTRA_libdhcp_manager_la_DEPENDENCIES) - $(AM_V_CCLD)$(LINK) $(libdhcp_manager_la_OBJECTS) $(libdhcp_manager_la_LIBADD) $(LIBS) +install-libexecPROGRAMS: $(libexec_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libexecdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libexecdir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-libexecPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(libexecdir)" && rm -f $$files + +clean-libexecPROGRAMS: + @list='$(libexec_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +nm-dhcp-helper$(EXEEXT): $(nm_dhcp_helper_OBJECTS) $(nm_dhcp_helper_DEPENDENCIES) $(EXTRA_nm_dhcp_helper_DEPENDENCIES) + @rm -f nm-dhcp-helper$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(nm_dhcp_helper_OBJECTS) $(nm_dhcp_helper_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -595,11 +567,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdhcp_dhclient_la-nm-dhcp-dhclient-utils.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdhcp_dhclient_la-nm-dhcp-dhclient.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdhcp_manager_la-nm-dhcp-client.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdhcp_manager_la-nm-dhcp-dhcpcd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdhcp_manager_la-nm-dhcp-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -622,102 +590,55 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -libdhcp_dhclient_la-nm-dhcp-dhclient-utils.lo: nm-dhcp-dhclient-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcp_dhclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdhcp_dhclient_la-nm-dhcp-dhclient-utils.lo -MD -MP -MF $(DEPDIR)/libdhcp_dhclient_la-nm-dhcp-dhclient-utils.Tpo -c -o libdhcp_dhclient_la-nm-dhcp-dhclient-utils.lo `test -f 'nm-dhcp-dhclient-utils.c' || echo '$(srcdir)/'`nm-dhcp-dhclient-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdhcp_dhclient_la-nm-dhcp-dhclient-utils.Tpo $(DEPDIR)/libdhcp_dhclient_la-nm-dhcp-dhclient-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-dhcp-dhclient-utils.c' object='libdhcp_dhclient_la-nm-dhcp-dhclient-utils.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcp_dhclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdhcp_dhclient_la-nm-dhcp-dhclient-utils.lo `test -f 'nm-dhcp-dhclient-utils.c' || echo '$(srcdir)/'`nm-dhcp-dhclient-utils.c - -libdhcp_dhclient_la-nm-dhcp-dhclient.lo: nm-dhcp-dhclient.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcp_dhclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdhcp_dhclient_la-nm-dhcp-dhclient.lo -MD -MP -MF $(DEPDIR)/libdhcp_dhclient_la-nm-dhcp-dhclient.Tpo -c -o libdhcp_dhclient_la-nm-dhcp-dhclient.lo `test -f 'nm-dhcp-dhclient.c' || echo '$(srcdir)/'`nm-dhcp-dhclient.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdhcp_dhclient_la-nm-dhcp-dhclient.Tpo $(DEPDIR)/libdhcp_dhclient_la-nm-dhcp-dhclient.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-dhcp-dhclient.c' object='libdhcp_dhclient_la-nm-dhcp-dhclient.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcp_dhclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdhcp_dhclient_la-nm-dhcp-dhclient.lo `test -f 'nm-dhcp-dhclient.c' || echo '$(srcdir)/'`nm-dhcp-dhclient.c - -libdhcp_manager_la-nm-dhcp-client.lo: nm-dhcp-client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcp_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdhcp_manager_la-nm-dhcp-client.lo -MD -MP -MF $(DEPDIR)/libdhcp_manager_la-nm-dhcp-client.Tpo -c -o libdhcp_manager_la-nm-dhcp-client.lo `test -f 'nm-dhcp-client.c' || echo '$(srcdir)/'`nm-dhcp-client.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdhcp_manager_la-nm-dhcp-client.Tpo $(DEPDIR)/libdhcp_manager_la-nm-dhcp-client.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-dhcp-client.c' object='libdhcp_manager_la-nm-dhcp-client.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcp_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdhcp_manager_la-nm-dhcp-client.lo `test -f 'nm-dhcp-client.c' || echo '$(srcdir)/'`nm-dhcp-client.c - -libdhcp_manager_la-nm-dhcp-manager.lo: nm-dhcp-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcp_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdhcp_manager_la-nm-dhcp-manager.lo -MD -MP -MF $(DEPDIR)/libdhcp_manager_la-nm-dhcp-manager.Tpo -c -o libdhcp_manager_la-nm-dhcp-manager.lo `test -f 'nm-dhcp-manager.c' || echo '$(srcdir)/'`nm-dhcp-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdhcp_manager_la-nm-dhcp-manager.Tpo $(DEPDIR)/libdhcp_manager_la-nm-dhcp-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-dhcp-manager.c' object='libdhcp_manager_la-nm-dhcp-manager.lo' libtool=yes @AMDEPBACKSLASH@ +nm_dhcp_helper-nm-dhcp-helper.o: nm-dhcp-helper.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_dhcp_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm_dhcp_helper-nm-dhcp-helper.o -MD -MP -MF $(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Tpo -c -o nm_dhcp_helper-nm-dhcp-helper.o `test -f 'nm-dhcp-helper.c' || echo '$(srcdir)/'`nm-dhcp-helper.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Tpo $(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-dhcp-helper.c' object='nm_dhcp_helper-nm-dhcp-helper.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcp_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdhcp_manager_la-nm-dhcp-manager.lo `test -f 'nm-dhcp-manager.c' || echo '$(srcdir)/'`nm-dhcp-manager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_dhcp_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm_dhcp_helper-nm-dhcp-helper.o `test -f 'nm-dhcp-helper.c' || echo '$(srcdir)/'`nm-dhcp-helper.c -libdhcp_manager_la-nm-dhcp-dhcpcd.lo: nm-dhcp-dhcpcd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcp_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdhcp_manager_la-nm-dhcp-dhcpcd.lo -MD -MP -MF $(DEPDIR)/libdhcp_manager_la-nm-dhcp-dhcpcd.Tpo -c -o libdhcp_manager_la-nm-dhcp-dhcpcd.lo `test -f 'nm-dhcp-dhcpcd.c' || echo '$(srcdir)/'`nm-dhcp-dhcpcd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdhcp_manager_la-nm-dhcp-dhcpcd.Tpo $(DEPDIR)/libdhcp_manager_la-nm-dhcp-dhcpcd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-dhcp-dhcpcd.c' object='libdhcp_manager_la-nm-dhcp-dhcpcd.lo' libtool=yes @AMDEPBACKSLASH@ +nm_dhcp_helper-nm-dhcp-helper.obj: nm-dhcp-helper.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_dhcp_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm_dhcp_helper-nm-dhcp-helper.obj -MD -MP -MF $(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Tpo -c -o nm_dhcp_helper-nm-dhcp-helper.obj `if test -f 'nm-dhcp-helper.c'; then $(CYGPATH_W) 'nm-dhcp-helper.c'; else $(CYGPATH_W) '$(srcdir)/nm-dhcp-helper.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Tpo $(DEPDIR)/nm_dhcp_helper-nm-dhcp-helper.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-dhcp-helper.c' object='nm_dhcp_helper-nm-dhcp-helper.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdhcp_manager_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdhcp_manager_la-nm-dhcp-dhcpcd.lo `test -f 'nm-dhcp-dhcpcd.c' || echo '$(srcdir)/'`nm-dhcp-dhcpcd.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_dhcp_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm_dhcp_helper-nm-dhcp-helper.obj `if test -f 'nm-dhcp-helper.c'; then $(CYGPATH_W) 'nm-dhcp-helper.c'; else $(CYGPATH_W) '$(srcdir)/nm-dhcp-helper.c'; fi` 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'; \ +install-dbusserviceDATA: $(dbusservice_DATA) + @$(NORMAL_INSTALL) + @list='$(dbusservice_DATA)'; test -n "$(dbusservicedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(dbusservicedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(dbusservicedir)" || 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" + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dbusservicedir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(dbusservicedir)" || exit $$?; \ + done + +uninstall-dbusserviceDATA: + @$(NORMAL_UNINSTALL) + @list='$(dbusservice_DATA)'; test -n "$(dbusservicedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(dbusservicedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-recursive +tags: tags-am 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 \ @@ -730,7 +651,7 @@ tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $$unique; \ fi; \ fi -ctags: ctags-recursive +ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) @@ -743,7 +664,7 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-recursive +cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ @@ -792,45 +713,22 @@ distdir: $(DISTFILES) || 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 +check: check-am +all-am: Makefile $(PROGRAMS) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(dbusservicedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -installcheck: installcheck-recursive +installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ @@ -852,93 +750,94 @@ distclean-generic: 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: clean-am -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ +clean-am: clean-generic clean-libexecPROGRAMS clean-libtool \ mostlyclean-am -distclean: distclean-recursive +distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags -dvi: dvi-recursive +dvi: dvi-am dvi-am: -html: html-recursive +html: html-am html-am: -info: info-recursive +info: info-am info-am: -install-data-am: +install-data-am: install-dbusserviceDATA -install-dvi: install-dvi-recursive +install-dvi: install-dvi-am install-dvi-am: -install-exec-am: +install-exec-am: install-libexecPROGRAMS -install-html: install-html-recursive +install-html: install-html-am install-html-am: -install-info: install-info-recursive +install-info: install-info-am install-info-am: install-man: -install-pdf: install-pdf-recursive +install-pdf: install-pdf-am install-pdf-am: -install-ps: install-ps-recursive +install-ps: install-ps-am install-ps-am: installcheck-am: -maintainer-clean: maintainer-clean-recursive +maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic -mostlyclean: mostlyclean-recursive +mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool -pdf: pdf-recursive +pdf: pdf-am pdf-am: -ps: ps-recursive +ps: ps-am ps-am: -uninstall-am: +uninstall-am: uninstall-dbusserviceDATA uninstall-libexecPROGRAMS -.MAKE: $(am__recursive_targets) install-am install-strip +.MAKE: install-am install-strip -.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am 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 \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libexecPROGRAMS clean-libtool 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-dbusserviceDATA 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 + install-html-am install-info install-info-am \ + install-libexecPROGRAMS install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-dbusserviceDATA \ + uninstall-libexecPROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c index 980fcab8..03c11c74 100644 --- a/src/dhcp-manager/nm-dhcp-client.c +++ b/src/dhcp-manager/nm-dhcp-client.c @@ -28,6 +28,7 @@ #include <stdlib.h> #include <uuid/uuid.h> +#include "NetworkManagerUtils.h" #include "nm-utils.h" #include "nm-logging.h" #include "nm-dbus-glib-types.h" @@ -38,6 +39,7 @@ typedef struct { GByteArray * hwaddr; gboolean ipv6; char * uuid; + guint priority; guint32 timeout; GByteArray * duid; @@ -57,9 +59,9 @@ typedef struct { G_DEFINE_TYPE_EXTENDED (NMDHCPClient, nm_dhcp_client, G_TYPE_OBJECT, G_TYPE_FLAG_ABSTRACT, {}) enum { - STATE_CHANGED, - TIMEOUT, - REMOVE, + SIGNAL_STATE_CHANGED, + SIGNAL_TIMEOUT, + SIGNAL_REMOVE, LAST_SIGNAL }; @@ -71,6 +73,7 @@ enum { PROP_HWADDR, PROP_IPV6, PROP_UUID, + PROP_PRIORITY, PROP_TIMEOUT, LAST_PROP }; @@ -80,7 +83,6 @@ enum { GPid nm_dhcp_client_get_pid (NMDHCPClient *self) { - g_return_val_if_fail (self != NULL, -1); g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), -1); return NM_DHCP_CLIENT_GET_PRIVATE (self)->pid; @@ -89,7 +91,6 @@ nm_dhcp_client_get_pid (NMDHCPClient *self) const char * nm_dhcp_client_get_iface (NMDHCPClient *self) { - g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); return NM_DHCP_CLIENT_GET_PRIVATE (self)->iface; @@ -98,7 +99,6 @@ nm_dhcp_client_get_iface (NMDHCPClient *self) gboolean nm_dhcp_client_get_ipv6 (NMDHCPClient *self) { - g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE); return NM_DHCP_CLIENT_GET_PRIVATE (self)->ipv6; @@ -107,7 +107,6 @@ nm_dhcp_client_get_ipv6 (NMDHCPClient *self) const char * nm_dhcp_client_get_uuid (NMDHCPClient *self) { - g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); return NM_DHCP_CLIENT_GET_PRIVATE (self)->uuid; @@ -138,9 +137,9 @@ watch_cleanup (NMDHCPClient *self) } void -nm_dhcp_client_stop_pid (GPid pid, const char *iface, guint timeout_secs) +nm_dhcp_client_stop_pid (GPid pid, const char *iface) { - int i = (timeout_secs ? timeout_secs : 3) * 5; /* default 3 seconds */ + int i = 5; /* roughly 0.5 seconds */ g_return_if_fail (pid > 0); @@ -167,7 +166,7 @@ nm_dhcp_client_stop_pid (GPid pid, const char *iface, guint timeout_secs) break; } } - g_usleep (G_USEC_PER_SEC / 5); + g_usleep (G_USEC_PER_SEC / 10); } if (i <= 0) { @@ -188,7 +187,6 @@ stop (NMDHCPClient *self, gboolean release, const GByteArray *duid) { NMDHCPClientPrivate *priv; - g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_DHCP_CLIENT (self)); priv = NM_DHCP_CLIENT_GET_PRIVATE (self); @@ -197,7 +195,7 @@ stop (NMDHCPClient *self, gboolean release, const GByteArray *duid) /* Clean up the watch handler since we're explicitly killing the daemon */ watch_cleanup (self); - nm_dhcp_client_stop_pid (priv->pid, priv->iface, 0); + nm_dhcp_client_stop_pid (priv->pid, priv->iface); priv->info_only = FALSE; } @@ -213,7 +211,7 @@ daemon_timeout (gpointer user_data) } else { nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 request timed out.", priv->iface); } - g_signal_emit (G_OBJECT (self), signals[TIMEOUT], 0); + g_signal_emit (G_OBJECT (self), signals[SIGNAL_TIMEOUT], 0); return FALSE; } @@ -223,7 +221,7 @@ signal_remove (gpointer user_data) NMDHCPClient *self = NM_DHCP_CLIENT (user_data); NM_DHCP_CLIENT_GET_PRIVATE (self)->remove_id = 0; - g_signal_emit (G_OBJECT (self), signals[REMOVE], 0); + g_signal_emit (G_OBJECT (self), signals[SIGNAL_REMOVE], 0); return FALSE; } @@ -238,12 +236,12 @@ dhcp_client_set_state (NMDHCPClient *self, priv->state = state; if (emit_state) - g_signal_emit (G_OBJECT (self), signals[STATE_CHANGED], 0, priv->state); + g_signal_emit (G_OBJECT (self), signals[SIGNAL_STATE_CHANGED], 0, priv->state); if (state == DHC_END || state == DHC_ABEND) { /* Start the remove signal timer */ if (remove_now) { - g_signal_emit (G_OBJECT (self), signals[REMOVE], 0); + g_signal_emit (G_OBJECT (self), signals[SIGNAL_REMOVE], 0); } else { if (!priv->remove_id) priv->remove_id = g_timeout_add_seconds (5, signal_remove, self); @@ -299,13 +297,12 @@ start_monitor (NMDHCPClient *self) gboolean nm_dhcp_client_start_ip4 (NMDHCPClient *self, - NMSettingIP4Config *s_ip4, - guint8 *dhcp_anycast_addr, + const char *dhcp_client_id, + GByteArray *dhcp_anycast_addr, const char *hostname) { NMDHCPClientPrivate *priv; - g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE); priv = NM_DHCP_CLIENT_GET_PRIVATE (self); @@ -316,7 +313,7 @@ nm_dhcp_client_start_ip4 (NMDHCPClient *self, nm_log_info (LOGD_DHCP, "Activation (%s) Beginning DHCPv4 transaction (timeout in %d seconds)", priv->iface, priv->timeout); - priv->pid = NM_DHCP_CLIENT_GET_CLASS (self)->ip4_start (self, s_ip4, dhcp_anycast_addr, hostname); + priv->pid = NM_DHCP_CLIENT_GET_CLASS (self)->ip4_start (self, dhcp_client_id, dhcp_anycast_addr, hostname); if (priv->pid) start_monitor (self); @@ -334,7 +331,7 @@ machine_id_parse (const char *in, uuid_t uu) g_return_val_if_fail (in != NULL, FALSE); g_return_val_if_fail (strlen (in) == 32, FALSE); - for (i = 0; i < 32; i++, cp++) { + for (i = 0; i < 32; i++) { if (!g_ascii_isxdigit (in[i])) return FALSE; } @@ -437,7 +434,7 @@ get_duid (NMDHCPClient *self) duid = generate_duid_from_machine_id (); g_assert (duid); - if (nm_logging_level_enabled (LOGL_DEBUG)) { + if (nm_logging_enabled (LOGL_DEBUG, LOGD_DHCP6)) { escaped = escape_duid (duid); nm_log_dbg (LOGD_DHCP6, "Generated DUID %s", escaped); g_free (escaped); @@ -454,15 +451,13 @@ get_duid (NMDHCPClient *self) gboolean nm_dhcp_client_start_ip6 (NMDHCPClient *self, - NMSettingIP6Config *s_ip6, - guint8 *dhcp_anycast_addr, + GByteArray *dhcp_anycast_addr, const char *hostname, gboolean info_only) { NMDHCPClientPrivate *priv; char *escaped; - g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE); priv = NM_DHCP_CLIENT_GET_PRIVATE (self); @@ -476,7 +471,7 @@ nm_dhcp_client_start_ip6 (NMDHCPClient *self, if (!priv->duid) priv->duid = NM_DHCP_CLIENT_GET_CLASS (self)->get_duid (self); - if (nm_logging_level_enabled (LOGL_DEBUG)) { + if (nm_logging_enabled (LOGL_DEBUG, LOGD_DHCP)) { escaped = escape_duid (priv->duid); nm_log_dbg (LOGD_DHCP, "(%s): DHCPv6 DUID is '%s'", priv->iface, escaped); g_free (escaped); @@ -488,7 +483,6 @@ nm_dhcp_client_start_ip6 (NMDHCPClient *self, priv->iface, priv->timeout); priv->pid = NM_DHCP_CLIENT_GET_CLASS (self)->ip6_start (self, - s_ip6, dhcp_anycast_addr, hostname, info_only, @@ -524,11 +518,13 @@ nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name) exe = proc_contents; if (!strcmp (exe, binary_name)) - nm_dhcp_client_stop_pid ((GPid) tmp, NULL, 0); + nm_dhcp_client_stop_pid ((GPid) tmp, NULL); } } - remove (pid_file); + if (remove (pid_file) == -1) + nm_log_dbg (LOGD_DHCP, "Could not remove dhcp pid file \"%s\": %d (%s)", pid_file, errno, g_strerror (errno)); + g_free (proc_path); g_free (pid_contents); g_free (proc_contents); @@ -539,7 +535,6 @@ nm_dhcp_client_stop (NMDHCPClient *self, gboolean release) { NMDHCPClientPrivate *priv; - g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_DHCP_CLIENT (self)); priv = NM_DHCP_CLIENT_GET_PRIVATE (self); @@ -582,63 +577,54 @@ state_is_bound (guint32 state) return FALSE; } -typedef struct { - NMDHCPState state; - const char *name; -} DhcState; - -#define STATE_TABLE_SIZE (sizeof (state_table) / sizeof (state_table[0])) - -static DhcState state_table[] = { - { DHC_NBI, "nbi" }, - { DHC_PREINIT, "preinit" }, - { DHC_PREINIT6,"preinit6" }, - { DHC_BOUND4, "bound" }, - { DHC_BOUND6, "bound6" }, - { DHC_IPV4LL, "ipv4ll" }, - { DHC_RENEW4, "renew" }, - { DHC_RENEW6, "renew6" }, - { DHC_REBOOT, "reboot" }, - { DHC_REBIND4, "rebind" }, - { DHC_REBIND6, "rebind6" }, - { DHC_STOP, "stop" }, - { DHC_STOP6, "stop6" }, - { DHC_MEDIUM, "medium" }, - { DHC_TIMEOUT, "timeout" }, - { DHC_FAIL, "fail" }, - { DHC_EXPIRE, "expire" }, - { DHC_EXPIRE6, "expire6" }, - { DHC_RELEASE, "release" }, - { DHC_RELEASE6,"release6" }, - { DHC_START, "start" }, - { DHC_ABEND, "abend" }, - { DHC_END, "end" }, - { DHC_DEPREF6, "depref6" }, +static const char *state_table[] = { + [DHC_NBI] = "nbi", + [DHC_PREINIT] = "preinit", + [DHC_PREINIT6] = "preinit6", + [DHC_BOUND4] = "bound", + [DHC_BOUND6] = "bound6", + [DHC_IPV4LL] = "ipv4ll", + [DHC_RENEW4] = "renew", + [DHC_RENEW6] = "renew6", + [DHC_REBOOT] = "reboot", + [DHC_REBIND4] = "rebind", + [DHC_REBIND6] = "rebind6", + [DHC_DEPREF6] = "depref6", + [DHC_STOP] = "stop", + [DHC_STOP6] = "stop6", + [DHC_MEDIUM] = "medium", + [DHC_TIMEOUT] = "timeout", + [DHC_FAIL] = "fail", + [DHC_EXPIRE] = "expire", + [DHC_EXPIRE6] = "expire6", + [DHC_RELEASE] = "release", + [DHC_RELEASE6] = "release6", + [DHC_START] = "start", + [DHC_ABEND] = "abend", + [DHC_END] = "end", }; -static inline const char * -state_to_string (guint32 state) +static const char * +state_to_string (NMDHCPState state) { - int i; - - for (i = 0; i < STATE_TABLE_SIZE; i++) { - if (state == state_table[i].state) - return state_table[i].name; - } - + if (state >= 0 && state < G_N_ELEMENTS (state_table)) + return state_table[state]; return NULL; } -static inline NMDHCPState +static NMDHCPState string_to_state (const char *name) { int i; - for (i = 0; i < STATE_TABLE_SIZE; i++) { - if (!strcasecmp (name, state_table[i].name)) - return state_table[i].state; - } + if (name) { + for (i = 0; i < G_N_ELEMENTS (state_table); i++) { + const char *n = state_table[i]; + if (n && !strcasecmp (name, n)) + return i; + } + } return 255; } @@ -705,7 +691,6 @@ nm_dhcp_client_new_options (NMDHCPClient *self, guint32 old_state; guint32 new_state; - g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_DHCP_CLIENT (self)); g_return_if_fail (options != NULL); g_return_if_fail (reason != NULL); @@ -766,7 +751,6 @@ nm_dhcp_client_foreach_option (NMDHCPClient *self, GHashTableIter iter; gpointer iterkey, itervalue; - g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE); g_return_val_if_fail (func != NULL, FALSE); @@ -813,10 +797,12 @@ nm_dhcp_client_foreach_option (NMDHCPClient *self, /********************************************/ static gboolean -ip4_process_dhcpcd_rfc3442_routes (const char *str, +ip4_process_dhcpcd_rfc3442_routes (NMDHCPClient *self, + const char *str, NMIP4Config *ip4_config, guint32 *gwaddr) { + NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); char **routes, **r; gboolean have_routes = FALSE; @@ -831,10 +817,9 @@ ip4_process_dhcpcd_rfc3442_routes (const char *str, for (r = routes; *r; r += 2) { char *slash; - NMIP4Route *route; + NMPlatformIP4Route route; int rt_cidr = 32; - struct in_addr rt_addr; - struct in_addr rt_route; + guint32 rt_addr, rt_route; slash = strchr(*r, '/'); if (slash) { @@ -856,17 +841,18 @@ ip4_process_dhcpcd_rfc3442_routes (const char *str, } have_routes = TRUE; - if (rt_cidr == 0 && rt_addr.s_addr == 0) { + if (rt_cidr == 0 && rt_addr == 0) { /* FIXME: how to handle multiple routers? */ - *gwaddr = rt_route.s_addr; + *gwaddr = rt_route; } else { - route = nm_ip4_route_new (); - nm_ip4_route_set_dest (route, (guint32) rt_addr.s_addr); - nm_ip4_route_set_prefix (route, rt_cidr); - nm_ip4_route_set_next_hop (route, (guint32) rt_route.s_addr); - - nm_ip4_config_take_route (ip4_config, route); nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s", *r, rt_cidr, *(r + 1)); + memset (&route, 0, sizeof (route)); + route.network = rt_addr; + route.plen = rt_cidr; + route.gateway = rt_route; + route.source = NM_PLATFORM_SOURCE_DHCP; + route.metric = priv->priority; + nm_ip4_config_add_route (ip4_config, &route); } } @@ -876,14 +862,15 @@ out: } static const char ** -process_dhclient_rfc3442_route (const char **octets, NMIP4Route **out_route) +process_dhclient_rfc3442_route (const char **octets, NMPlatformIP4Route *route, gboolean *success) { const char **o = octets; int addr_len = 0, i = 0; long int tmp; - NMIP4Route *route; char *next_hop; - struct in_addr tmp_addr; + guint32 tmp_addr; + + *success = FALSE; if (!*o) return o; /* no prefix */ @@ -892,8 +879,8 @@ process_dhclient_rfc3442_route (const char **octets, NMIP4Route **out_route) if (tmp < 0 || tmp > 32) /* 32 == max IP4 prefix length */ return o; - route = nm_ip4_route_new (); - nm_ip4_route_set_prefix (route, (guint32) tmp); + memset (route, 0, sizeof (*route)); + route->plen = tmp; o++; if (tmp > 0) @@ -915,8 +902,8 @@ process_dhclient_rfc3442_route (const char **octets, NMIP4Route **out_route) g_free (str_addr); goto error; } - tmp_addr.s_addr &= nm_utils_ip4_prefix_to_netmask ((guint32) tmp); - nm_ip4_route_set_dest (route, tmp_addr.s_addr); + tmp_addr &= nm_utils_ip4_prefix_to_netmask ((guint32) tmp); + route->network = tmp_addr; } /* Handle next hop */ @@ -925,25 +912,27 @@ process_dhclient_rfc3442_route (const char **octets, NMIP4Route **out_route) g_free (next_hop); goto error; } - nm_ip4_route_set_next_hop (route, tmp_addr.s_addr); + route->gateway = tmp_addr; g_free (next_hop); - *out_route = route; + *success = TRUE; return o + 4; /* advance to past the next hop */ error: - nm_ip4_route_unref (route); return o; } static gboolean -ip4_process_dhclient_rfc3442_routes (const char *str, +ip4_process_dhclient_rfc3442_routes (NMDHCPClient *self, + const char *str, NMIP4Config *ip4_config, guint32 *gwaddr) { + NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); char **octets, **o; gboolean have_routes = FALSE; - NMIP4Route *route = NULL; + NMPlatformIP4Route route; + gboolean success; o = octets = g_strsplit_set (str, " .", 0); if (g_strv_length (octets) < 5) { @@ -952,32 +941,28 @@ ip4_process_dhclient_rfc3442_routes (const char *str, } while (*o) { - route = NULL; - o = (char **) process_dhclient_rfc3442_route ((const char **) o, &route); - if (!route) { + memset (&route, 0, sizeof (route)); + o = (char **) process_dhclient_rfc3442_route ((const char **) o, &route, &success); + if (!success) { nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes"); break; } have_routes = TRUE; - if (nm_ip4_route_get_prefix (route) == 0) { + if (!route.plen) { /* gateway passed as classless static route */ - *gwaddr = nm_ip4_route_get_next_hop (route); - nm_ip4_route_unref (route); + *gwaddr = route.gateway; } else { - char addr[INET_ADDRSTRLEN + 1]; - char nh[INET_ADDRSTRLEN + 1]; - struct in_addr tmp; + char addr[INET_ADDRSTRLEN]; /* normal route */ - nm_ip4_config_take_route (ip4_config, route); + route.source = NM_PLATFORM_SOURCE_DHCP; + route.metric = priv->priority; + nm_ip4_config_add_route (ip4_config, &route); - tmp.s_addr = nm_ip4_route_get_dest (route); - inet_ntop (AF_INET, &tmp, addr, sizeof (addr)); - tmp.s_addr = nm_ip4_route_get_next_hop (route); - inet_ntop (AF_INET, &tmp, nh, sizeof (nh)); nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s", - addr, nm_ip4_route_get_prefix (route), nh); + nm_utils_inet4_ntop (route.network, addr), route.plen, + nm_utils_inet4_ntop (route.gateway, NULL)); } } @@ -987,7 +972,8 @@ out: } static gboolean -ip4_process_classless_routes (GHashTable *options, +ip4_process_classless_routes (NMDHCPClient *self, + GHashTable *options, NMIP4Config *ip4_config, guint32 *gwaddr) { @@ -1043,15 +1029,16 @@ ip4_process_classless_routes (GHashTable *options, if (strchr (str, '/')) { /* dhcpcd format */ - return ip4_process_dhcpcd_rfc3442_routes (str, ip4_config, gwaddr); + return ip4_process_dhcpcd_rfc3442_routes (self, str, ip4_config, gwaddr); } - return ip4_process_dhclient_rfc3442_routes (str, ip4_config, gwaddr); + return ip4_process_dhclient_rfc3442_routes (self, str, ip4_config, gwaddr); } static void -process_classful_routes (GHashTable *options, NMIP4Config *ip4_config) +process_classful_routes (NMDHCPClient *self, GHashTable *options, NMIP4Config *ip4_config) { + NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); const char *str; char **searches, **s; @@ -1066,9 +1053,8 @@ process_classful_routes (GHashTable *options, NMIP4Config *ip4_config) } for (s = searches; *s; s += 2) { - NMIP4Route *route; - struct in_addr rt_addr; - struct in_addr rt_route; + NMPlatformIP4Route route; + guint32 rt_addr, rt_route; if (inet_pton (AF_INET, *s, &rt_addr) <= 0) { nm_log_warn (LOGD_DHCP, "DHCP provided invalid static route address: '%s'", *s); @@ -1079,15 +1065,26 @@ process_classful_routes (GHashTable *options, NMIP4Config *ip4_config) continue; } - // FIXME: ensure the IP addresse and route are sane - - route = nm_ip4_route_new (); - nm_ip4_route_set_dest (route, (guint32) rt_addr.s_addr); - nm_ip4_route_set_prefix (route, 32); /* 255.255.255.255 */ - nm_ip4_route_set_next_hop (route, (guint32) rt_route.s_addr); + // FIXME: ensure the IP address and route are sane + + memset (&route, 0, sizeof (route)); + route.network = rt_addr; + /* RFC 2132, updated by RFC 3442: + The Static Routes option (option 33) does not provide a subnet mask + for each route - it is assumed that the subnet mask is implicit in + whatever network number is specified in each route entry */ + route.plen = nm_utils_ip4_get_default_prefix (rt_addr); + if (rt_addr & ~nm_utils_ip4_prefix_to_netmask (route.plen)) { + /* RFC 943: target not "this network"; using host routing */ + route.plen = 32; + } + route.gateway = rt_route; + route.source = NM_PLATFORM_SOURCE_DHCP; + route.metric = priv->priority; - nm_ip4_config_take_route (ip4_config, route); - nm_log_info (LOGD_DHCP, " static route %s gw %s", *s, *(s + 1)); + nm_ip4_config_add_route (ip4_config, &route); + nm_log_info (LOGD_DHCP, " static route %s", + nm_platform_ip4_route_to_string (&route)); } out: @@ -1145,59 +1142,47 @@ ip4_options_to_config (NMDHCPClient *self) { NMDHCPClientPrivate *priv; NMIP4Config *ip4_config = NULL; - struct in_addr tmp_addr; - NMIP4Address *addr = NULL; + guint32 tmp_addr; + NMPlatformIP4Address address; char *str = NULL; - guint32 gwaddr = 0, prefix = 0; + guint32 gwaddr = 0, plen = 0; - g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); priv = NM_DHCP_CLIENT_GET_PRIVATE (self); g_return_val_if_fail (priv->options != NULL, NULL); ip4_config = nm_ip4_config_new (); - if (!ip4_config) { - nm_log_warn (LOGD_DHCP4, "(%s): couldn't allocate memory for an IP4Config!", priv->iface); - return NULL; - } - - addr = nm_ip4_address_new (); - if (!addr) { - nm_log_warn (LOGD_DHCP4, "(%s): couldn't allocate memory for an IP4 Address!", priv->iface); - goto error; - } + memset (&address, 0, sizeof (address)); + address.timestamp = nm_utils_get_monotonic_timestamp_s (); str = g_hash_table_lookup (priv->options, "new_ip_address"); if (str && (inet_pton (AF_INET, str, &tmp_addr) > 0)) { - nm_ip4_address_set_address (addr, tmp_addr.s_addr); + address.address = tmp_addr; nm_log_info (LOGD_DHCP4, " address %s", str); } else goto error; str = g_hash_table_lookup (priv->options, "new_subnet_mask"); if (str && (inet_pton (AF_INET, str, &tmp_addr) > 0)) { - prefix = nm_utils_ip4_netmask_to_prefix (tmp_addr.s_addr); - nm_log_info (LOGD_DHCP4, " prefix %d (%s)", prefix, str); + plen = nm_utils_ip4_netmask_to_prefix (tmp_addr); + nm_log_info (LOGD_DHCP4, " plen %d (%s)", plen, str); } else { /* Get default netmask for the IP according to appropriate class. */ - prefix = nm_utils_ip4_get_default_prefix (nm_ip4_address_get_address (addr)); - nm_log_info (LOGD_DHCP4, " prefix %d (default)", prefix); + plen = nm_utils_ip4_get_default_prefix (address.address); + nm_log_info (LOGD_DHCP4, " plen %d (default)", plen); } - nm_ip4_address_set_prefix (addr, prefix); + address.plen = plen; /* Routes: if the server returns classless static routes, we MUST ignore * the 'static_routes' option. */ - if (!ip4_process_classless_routes (priv->options, ip4_config, &gwaddr)) - process_classful_routes (priv->options, ip4_config); + if (!ip4_process_classless_routes (self, priv->options, ip4_config, &gwaddr)) + process_classful_routes (self, priv->options, ip4_config); if (gwaddr) { - char buf[INET_ADDRSTRLEN + 1]; - - inet_ntop (AF_INET, &gwaddr, buf, sizeof (buf)); - nm_log_info (LOGD_DHCP4, " gateway %s", buf); - nm_ip4_address_set_gateway (addr, gwaddr); + nm_log_info (LOGD_DHCP4, " gateway %s", nm_utils_inet4_ntop (gwaddr, NULL)); + nm_ip4_config_set_gateway (ip4_config, gwaddr); } else { /* If the gateway wasn't provided as a classless static route with a * subnet length of 0, try to find it using the old-style 'routers' option. @@ -1209,8 +1194,8 @@ ip4_options_to_config (NMDHCPClient *self) for (s = routers; *s; s++) { /* FIXME: how to handle multiple routers? */ - if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { - nm_ip4_address_set_gateway (addr, tmp_addr.s_addr); + if (inet_pton (AF_INET, *s, &gwaddr) > 0) { + nm_ip4_config_set_gateway (ip4_config, gwaddr); nm_log_info (LOGD_DHCP4, " gateway %s", *s); break; } else @@ -1220,8 +1205,51 @@ ip4_options_to_config (NMDHCPClient *self) } } - nm_ip4_config_take_address (ip4_config, addr); - addr = NULL; + /* + * RFC 2132, section 9.7 + * DHCP clients use the contents of the 'server identifier' field + * as the destination address for any DHCP messages unicast to + * the DHCP server. + * + * Some ISP's provide leases from central servers that are on + * different subnets that the address offered. If the host + * does not configure the interface as the default route, the + * dhcp server may not be reachable via unicast, and a host + * specific route is needed. + **/ + str = g_hash_table_lookup (priv->options, "new_dhcp_server_identifier"); + if (str) { + if (inet_pton (AF_INET, str, &tmp_addr) > 0) { + NMPlatformIP4Route route; + guint32 mask = nm_utils_ip4_prefix_to_netmask (address.plen); + + nm_log_info (LOGD_DHCP4, " server identifier %s", str); + if ((tmp_addr & mask) != (address.address & mask)) { + /* DHCP server not on assigned subnet, route needed */ + memset (&route, 0, sizeof (route)); + route.network = tmp_addr; + route.plen = 32; + /* this will be a device route if gwaddr is 0 */ + route.gateway = gwaddr; + route.source = NM_PLATFORM_SOURCE_DHCP; + route.metric = priv->priority; + nm_ip4_config_add_route (ip4_config, &route); + nm_log_dbg (LOGD_IP, "adding route for server identifier: %s", + nm_platform_ip4_route_to_string (&route)); + } + } + else + nm_log_warn (LOGD_DHCP4, "ignoring invalid server identifier '%s'", str); + } + + str = g_hash_table_lookup (priv->options, "new_dhcp_lease_time"); + if (str) { + address.lifetime = address.preferred = strtoul (str, NULL, 10); + nm_log_info (LOGD_DHCP4, " lease time %d", address.lifetime); + } + + address.source = NM_PLATFORM_SOURCE_DHCP; + nm_ip4_config_add_address (ip4_config, &address); str = g_hash_table_lookup (priv->options, "new_host_name"); if (str) @@ -1234,7 +1262,7 @@ ip4_options_to_config (NMDHCPClient *self) for (s = searches; *s; s++) { if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { - nm_ip4_config_add_nameserver (ip4_config, tmp_addr.s_addr); + nm_ip4_config_add_nameserver (ip4_config, tmp_addr); nm_log_info (LOGD_DHCP4, " nameserver '%s'", *s); } else nm_log_warn (LOGD_DHCP4, "ignoring invalid nameserver '%s'", *s); @@ -1265,7 +1293,7 @@ ip4_options_to_config (NMDHCPClient *self) for (s = searches; *s; s++) { if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { - nm_ip4_config_add_wins (ip4_config, tmp_addr.s_addr); + nm_ip4_config_add_wins (ip4_config, tmp_addr); nm_log_info (LOGD_DHCP4, " wins '%s'", *s); } else nm_log_warn (LOGD_DHCP4, "ignoring invalid WINS server '%s'", *s); @@ -1299,7 +1327,7 @@ ip4_options_to_config (NMDHCPClient *self) for (s = searches; *s; s++) { if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { - nm_ip4_config_add_nis_server (ip4_config, tmp_addr.s_addr); + nm_ip4_config_add_nis_server (ip4_config, tmp_addr); nm_log_info (LOGD_DHCP4, " nis '%s'", *s); } else nm_log_warn (LOGD_DHCP4, "ignoring invalid NIS server '%s'", *s); @@ -1310,8 +1338,6 @@ ip4_options_to_config (NMDHCPClient *self) return ip4_config; error: - if (addr) - nm_ip4_address_unref (addr); g_object_unref (ip4_config); return NULL; } @@ -1321,7 +1347,6 @@ nm_dhcp_client_get_ip4_config (NMDHCPClient *self, gboolean test) { NMDHCPClientPrivate *priv; - g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); priv = NM_DHCP_CLIENT_GET_PRIVATE (self); @@ -1354,14 +1379,17 @@ ip6_options_to_config (NMDHCPClient *self) NMDHCPClientPrivate *priv; NMIP6Config *ip6_config = NULL; struct in6_addr tmp_addr; - NMIP6Address *addr = NULL; + NMPlatformIP6Address address; char *str = NULL; GHashTableIter iter; gpointer key, value; - g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); + memset (&address, 0, sizeof (address)); + address.plen = 128; + address.timestamp = nm_utils_get_monotonic_timestamp_s (); + priv = NM_DHCP_CLIENT_GET_PRIVATE (self); g_return_val_if_fail (priv->options != NULL, NULL); @@ -1372,9 +1400,17 @@ ip6_options_to_config (NMDHCPClient *self) } ip6_config = nm_ip6_config_new (); - if (!ip6_config) { - nm_log_warn (LOGD_DHCP6, "(%s): couldn't allocate memory for an IP6Config!", priv->iface); - return NULL; + + str = g_hash_table_lookup (priv->options, "new_max_life"); + if (str) { + address.lifetime = strtoul (str, NULL, 10); + nm_log_info (LOGD_DHCP6, " valid_lft %d", address.lifetime); + } + + str = g_hash_table_lookup (priv->options, "new_preferred_life"); + if (str) { + address.preferred = strtoul (str, NULL, 10); + nm_log_info (LOGD_DHCP6, " preferred_lft %d", address.preferred); } str = g_hash_table_lookup (priv->options, "new_ip6_address"); @@ -1385,14 +1421,10 @@ ip6_options_to_config (NMDHCPClient *self) goto error; } - addr = nm_ip6_address_new (); - g_assert (addr); - nm_ip6_address_set_address (addr, &tmp_addr); - /* DHCPv6 IA_NA assignments are single address only */ - nm_ip6_address_set_prefix (addr, 128); - nm_log_info (LOGD_DHCP6, " address %s/128", str); - - nm_ip6_config_take_address (ip6_config, addr); + address.address = tmp_addr; + address.source = NM_PLATFORM_SOURCE_DHCP; + nm_ip6_config_add_address (ip6_config, &address); + nm_log_info (LOGD_DHCP6, " address %s", str); } else if (priv->info_only == FALSE) { /* No address in Managed mode is a hard error */ goto error; @@ -1433,7 +1465,6 @@ nm_dhcp_client_get_ip6_config (NMDHCPClient *self, gboolean test) { NMDHCPClientPrivate *priv; - g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); priv = NM_DHCP_CLIENT_GET_PRIVATE (self); @@ -1481,6 +1512,9 @@ get_property (GObject *object, guint prop_id, case PROP_UUID: g_value_set_string (value, priv->uuid); break; + case PROP_PRIORITY: + g_value_set_uint (value, priv->priority); + break; case PROP_TIMEOUT: g_value_set_uint (value, priv->timeout); break; @@ -1513,6 +1547,10 @@ set_property (GObject *object, guint prop_id, /* construct-only */ priv->uuid = g_value_dup_string (value); break; + case PROP_PRIORITY: + /* construct-only */ + priv->priority = g_value_get_uint (value); + break; case PROP_TIMEOUT: priv->timeout = g_value_get_uint (value); break; @@ -1605,6 +1643,14 @@ nm_dhcp_client_class_init (NMDHCPClientClass *client_class) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property + (object_class, PROP_PRIORITY, + g_param_spec_uint (NM_DHCP_CLIENT_PRIORITY, + "priority", + "Priority", + 0, G_MAXUINT, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, PROP_TIMEOUT, g_param_spec_uint (NM_DHCP_CLIENT_TIMEOUT, "timeout", @@ -1613,8 +1659,8 @@ nm_dhcp_client_class_init (NMDHCPClientClass *client_class) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); /* signals */ - signals[STATE_CHANGED] = - g_signal_new ("state-changed", + signals[SIGNAL_STATE_CHANGED] = + g_signal_new (NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMDHCPClientClass, state_changed), @@ -1622,8 +1668,8 @@ nm_dhcp_client_class_init (NMDHCPClientClass *client_class) g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); - signals[TIMEOUT] = - g_signal_new ("timeout", + signals[SIGNAL_TIMEOUT] = + g_signal_new (NM_DHCP_CLIENT_SIGNAL_TIMEOUT, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMDHCPClientClass, timeout), @@ -1631,8 +1677,8 @@ nm_dhcp_client_class_init (NMDHCPClientClass *client_class) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - signals[REMOVE] = - g_signal_new ("remove", + signals[SIGNAL_REMOVE] = + g_signal_new (NM_DHCP_CLIENT_SIGNAL_REMOVE, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMDHCPClientClass, remove), diff --git a/src/dhcp-manager/nm-dhcp-client.h b/src/dhcp-manager/nm-dhcp-client.h index 930ec1a5..ad18926a 100644 --- a/src/dhcp-manager/nm-dhcp-client.h +++ b/src/dhcp-manager/nm-dhcp-client.h @@ -38,8 +38,13 @@ #define NM_DHCP_CLIENT_HWADDR "hwaddr" #define NM_DHCP_CLIENT_IPV6 "ipv6" #define NM_DHCP_CLIENT_UUID "uuid" +#define NM_DHCP_CLIENT_PRIORITY "priority" #define NM_DHCP_CLIENT_TIMEOUT "timeout" +#define NM_DHCP_CLIENT_SIGNAL_TIMEOUT "timeout" +#define NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED "state-changed" +#define NM_DHCP_CLIENT_SIGNAL_REMOVE "remove" + typedef enum { DHC_NBI = 0, /* no broadcast interfaces found */ DHC_PREINIT, /* configuration started */ @@ -78,13 +83,12 @@ typedef struct { /* Methods */ GPid (*ip4_start) (NMDHCPClient *self, - NMSettingIP4Config *s_ip4, - guint8 *anycast_addr, + const char *dhcp_client_id, + GByteArray *anycast_addr, const char *hostname); GPid (*ip6_start) (NMDHCPClient *self, - NMSettingIP6Config *s_ip6, - guint8 *anycast_addr, + GByteArray *anycast_addr, const char *hostname, gboolean info_only, const GByteArray *duid); @@ -121,13 +125,12 @@ gboolean nm_dhcp_client_get_ipv6 (NMDHCPClient *self); const char *nm_dhcp_client_get_uuid (NMDHCPClient *self); gboolean nm_dhcp_client_start_ip4 (NMDHCPClient *self, - NMSettingIP4Config *s_ip4, - guint8 *dhcp_anycast_addr, + const char *dhcp_client_id, + GByteArray *dhcp_anycast_addr, const char *hostname); gboolean nm_dhcp_client_start_ip6 (NMDHCPClient *self, - NMSettingIP6Config *s_ip6, - guint8 *dhcp_anycast_addr, + GByteArray *dhcp_anycast_addr, const char *hostname, gboolean info_only); @@ -148,7 +151,7 @@ NMIP6Config *nm_dhcp_client_get_ip6_config (NMDHCPClient *self, gboolean test) /* Backend helpers */ void nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name); -void nm_dhcp_client_stop_pid (GPid pid, const char *iface, guint timeout_secs); +void nm_dhcp_client_stop_pid (GPid pid, const char *iface); #endif /* NM_DHCP_CLIENT_H */ diff --git a/src/dhcp-manager/nm-dhcp-dhclient-utils.c b/src/dhcp-manager/nm-dhcp-dhclient-utils.c index db4bf7e8..8527e6c0 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient-utils.c +++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.c @@ -25,6 +25,9 @@ #include <ctype.h> #include "nm-dhcp-dhclient-utils.h" +#include "nm-ip4-config.h" +#include "nm-utils.h" +#include "NetworkManagerUtils.h" #define CLIENTID_TAG "send dhcp-client-identifier" #define CLIENTID_FORMAT CLIENTID_TAG " \"%s\"; # added by NetworkManager" @@ -68,33 +71,32 @@ add_hostname (GString *str, const char *format, const char *hostname) } static void -add_ip4_config (GString *str, NMSettingIP4Config *s_ip4, const char *hostname) +add_ip4_config (GString *str, const char *dhcp_client_id, const char *hostname) { - if (s_ip4) { - const char *tmp; - - tmp = nm_setting_ip4_config_get_dhcp_client_id (s_ip4); - if (tmp) { - gboolean is_octets = TRUE; - const char *p = tmp; - - while (*p) { - if (!g_ascii_isxdigit (*p) && (*p != ':')) { - is_octets = FALSE; - break; - } - p++; + if (dhcp_client_id) { + gboolean is_octets = TRUE; + int i = 0; + + while (dhcp_client_id[i]) { + if ((i % 3) != 2 && !g_ascii_isxdigit (dhcp_client_id[i])) { + is_octets = FALSE; + break; } - - /* If the client ID is just hex digits and : then don't use quotes, - * because dhclient expects either a quoted ASCII string, or a byte - * array formated as hex octets separated by : - */ - if (is_octets) - g_string_append_printf (str, CLIENTID_FORMAT_OCTETS "\n", tmp); - else - g_string_append_printf (str, CLIENTID_FORMAT "\n", tmp); + if ((i % 3) == 2 && dhcp_client_id[i] != ':') { + is_octets = FALSE; + break; + } + i++; } + + /* If the client ID is just hex digits and : then don't use quotes, + * because dhclient expects either a quoted ASCII string, or a byte + * array formated as hex octets separated by : + */ + if (is_octets) + g_string_append_printf (str, CLIENTID_FORMAT_OCTETS "\n", dhcp_client_id); + else + g_string_append_printf (str, CLIENTID_FORMAT "\n", dhcp_client_id); } add_hostname (str, HOSTNAME4_FORMAT "\n", hostname); @@ -113,7 +115,7 @@ add_ip4_config (GString *str, NMSettingIP4Config *s_ip4, const char *hostname) } static void -add_ip6_config (GString *str, NMSettingIP6Config *s_ip6, const char *hostname) +add_ip6_config (GString *str, const char *hostname) { add_hostname (str, HOSTNAME6_FORMAT "\n", hostname); g_string_append (str, @@ -125,9 +127,8 @@ add_ip6_config (GString *str, NMSettingIP6Config *s_ip6, const char *hostname) char * nm_dhcp_dhclient_create_config (const char *interface, gboolean is_ip6, - NMSettingIP4Config *s_ip4, - NMSettingIP6Config *s_ip6, - guint8 *anycast_addr, + const char *dhcp_client_id, + GByteArray *anycast_addr, const char *hostname, const char *orig_path, const char *orig_contents) @@ -155,9 +156,7 @@ nm_dhcp_dhclient_create_config (const char *interface, /* Override config file "dhcp-client-id" and use one from the * connection. */ - if ( s_ip4 - && nm_setting_ip4_config_get_dhcp_client_id (s_ip4) - && !strncmp (p, CLIENTID_TAG, strlen (CLIENTID_TAG))) + if (dhcp_client_id && !strncmp (p, CLIENTID_TAG, strlen (CLIENTID_TAG))) continue; /* Override config file hostname and use one from the connection */ @@ -222,13 +221,13 @@ nm_dhcp_dhclient_create_config (const char *interface, g_string_append_c (new_contents, '\n'); if (is_ip6) { - add_ip6_config (new_contents, s_ip6, hostname); + add_ip6_config (new_contents, hostname); add_also_request (alsoreq, "dhcp6.name-servers"); add_also_request (alsoreq, "dhcp6.domain-search"); add_also_request (alsoreq, "dhcp6.client-id"); add_also_request (alsoreq, "dhcp6.server-id"); } else { - add_ip4_config (new_contents, s_ip4, hostname); + add_ip4_config (new_contents, dhcp_client_id, hostname); add_also_request (alsoreq, "rfc3442-classless-static-routes"); add_also_request (alsoreq, "ms-classless-static-routes"); add_also_request (alsoreq, "static-routes"); @@ -247,17 +246,22 @@ nm_dhcp_dhclient_create_config (const char *interface, g_string_append_c (new_contents, '\n'); - if (anycast_addr) { + if (anycast_addr && anycast_addr->len == 6) { + const guint8 *p_anycast_addr = anycast_addr->data; + g_string_append_printf (new_contents, "interface \"%s\" {\n" " initial-interval 1; \n" " anycast-mac ethernet %02x:%02x:%02x:%02x:%02x:%02x;\n" "}\n", interface, - anycast_addr[0], anycast_addr[1], - anycast_addr[2], anycast_addr[3], - anycast_addr[4], anycast_addr[5]); + p_anycast_addr[0], p_anycast_addr[1], + p_anycast_addr[2], p_anycast_addr[3], + p_anycast_addr[4], p_anycast_addr[5]); } + /* Finally, assert that anycast_addr was unset or a 48 bit mac address. */ + g_return_val_if_fail (!anycast_addr || anycast_addr->len == 6, g_string_free (new_contents, FALSE)); + return g_string_free (new_contents, FALSE); } @@ -423,3 +427,238 @@ nm_dhcp_dhclient_save_duid (const char *leasefile, return success; } +static void +add_lease_option (GHashTable *hash, char *line) +{ + char *spc; + size_t len; + + /* Find the space after "option" */ + spc = strchr (line, ' '); + if (!spc) + return; + + /* Find the option tag's data, which is after the second space */ + if (g_str_has_prefix (line, "option ")) { + while (g_ascii_isspace (*spc)) + spc++; + spc = strchr (spc + 1, ' '); + if (!spc) + return; + } + + /* Split the line at the space */ + *spc = '\0'; + spc++; + + /* Kill the ';' at the end of the line, if any */ + len = strlen (spc); + if (*(spc + len - 1) == ';') + *(spc + len - 1) = '\0'; + + /* Strip leading quote */ + while (g_ascii_isspace (*spc)) + spc++; + if (*spc == '"') + spc++; + + /* Strip trailing quote */ + len = strlen (spc); + if (len > 0 && spc[len - 1] == '"') + spc[len - 1] = '\0'; + + if (spc[0]) + g_hash_table_insert (hash, g_strdup (line), g_strdup (spc)); +} + +#define LEASE_INVALID G_MININT64 +static GTimeSpan +lease_validity_span (const char *str_expire, GDateTime *now) +{ + GDateTime *expire = NULL; + struct tm expire_tm; + GTimeSpan span; + + g_return_val_if_fail (now != NULL, LEASE_INVALID); + g_return_val_if_fail (str_expire != NULL, LEASE_INVALID); + + /* Skip initial number (day of week?) */ + if (!isdigit (*str_expire++)) + return LEASE_INVALID; + if (!isspace (*str_expire++)) + return LEASE_INVALID; + /* Read lease expiration (in UTC) */ + if (!strptime (str_expire, "%t%Y/%m/%d %H:%M:%S", &expire_tm)) + return LEASE_INVALID; + + expire = g_date_time_new_utc (expire_tm.tm_year + 1900, + expire_tm.tm_mon + 1, + expire_tm.tm_mday, + expire_tm.tm_hour, + expire_tm.tm_min, + expire_tm.tm_sec); + if (!expire) + return LEASE_INVALID; + + span = g_date_time_difference (expire, now); + g_date_time_unref (expire); + + /* GDateTime only supports a range of less then 10000 years, so span can + * not overflow or be equal to LEASE_INVALID */ + return span; +} + +/** + * nm_dhcp_dhclient_read_lease_ip_configs: + * @iface: the interface name to match leases with + * @contents: the contents of a dhclient leasefile + * @ipv6: whether to read IPv4 or IPv6 leases + * @now: the current UTC date/time; pass %NULL to automatically use current + * UTC time. Testcases may need a different value for 'now' + * + * Reads dhclient leases from @contents and parses them into either + * #NMIP4Config or #NMIP6Config objects depending on the value of @ipv6. + * + * Returns: a #GSList of #NMIP4Config objects (if @ipv6 is %FALSE) or a list of + * #NMIP6Config objects (if @ipv6 is %TRUE) containing the lease data. + */ +GSList * +nm_dhcp_dhclient_read_lease_ip_configs (const char *iface, + const char *contents, + gboolean ipv6, + GDateTime *now) +{ + GSList *parsed = NULL, *iter, *leases = NULL; + char **line, **split = NULL; + GHashTable *hash = NULL; + gint32 now_monotonic_ts; + + g_return_val_if_fail (contents != NULL, NULL); + + split = g_strsplit_set (contents, "\n\r", -1); + if (!split) + return NULL; + + for (line = split; line && *line; line++) { + *line = g_strstrip (*line); + + if (*line[0] == '#') { + /* Comment */ + } else if (!strcmp (*line, "}")) { + /* Lease ends */ + parsed = g_slist_append (parsed, hash); + hash = NULL; + } else if (!strcmp (*line, "lease {")) { + /* Beginning of a new lease */ + if (hash) { + /* Ignore malformed lease that doesn't end before new one starts */ + g_hash_table_destroy (hash); + } + + hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + } else if (hash && strlen (*line)) + add_lease_option (hash, *line); + } + g_strfreev (split); + + /* Check if the last lease in the file was properly ended */ + if (hash) { + /* Ignore malformed lease that doesn't end before new one starts */ + g_hash_table_destroy (hash); + hash = NULL; + } + + if (now) + g_date_time_ref (now); + else + now = g_date_time_new_now_utc (); + now_monotonic_ts = nm_utils_get_monotonic_timestamp_s (); + + for (iter = parsed; iter; iter = g_slist_next (iter)) { + NMIP4Config *ip4; + NMPlatformIP4Address address; + const char *value; + GTimeSpan expiry; + guint32 tmp, gw = 0; + + hash = iter->data; + + /* Make sure this lease is for the interface we want */ + value = g_hash_table_lookup (hash, "interface"); + if (!value || strcmp (value, iface)) + continue; + + value = g_hash_table_lookup (hash, "expire"); + if (!value) + continue; + expiry = lease_validity_span (value, now); + if (expiry == LEASE_INVALID) + continue; + + /* scale expiry to seconds (and CLAMP into the range of guint32) */ + expiry = CLAMP (expiry / G_TIME_SPAN_SECOND, 0, NM_PLATFORM_LIFETIME_PERMANENT-1); + if (expiry <= 0) { + /* the address is already expired. Don't even add it. */ + continue; + } + + memset (&address, 0, sizeof (address)); + + /* IP4 address */ + value = g_hash_table_lookup (hash, "fixed-address"); + if (!value) + continue; + if (!inet_pton (AF_INET, value, &address.address)) + continue; + + /* Gateway */ + value = g_hash_table_lookup (hash, "option routers"); + if (!value) + continue; + if (!inet_pton (AF_INET, value, &gw)) + continue; + + /* Netmask */ + value = g_hash_table_lookup (hash, "option subnet-mask"); + if (value && inet_pton (AF_INET, value, &tmp)) + address.plen = nm_utils_ip4_netmask_to_prefix (tmp); + + /* Get default netmask for the IP according to appropriate class. */ + if (!address.plen) + address.plen = nm_utils_ip4_get_default_prefix (address.address); + + address.timestamp = now_monotonic_ts; + address.lifetime = address.preferred = expiry; + address.source = NM_PLATFORM_SOURCE_DHCP; + + ip4 = nm_ip4_config_new (); + nm_ip4_config_add_address (ip4, &address); + nm_ip4_config_set_gateway (ip4, gw); + + value = g_hash_table_lookup (hash, "option domain-name-servers"); + if (value) { + char **dns, **dns_iter; + + dns = g_strsplit_set (value, ",", -1); + for (dns_iter = dns; dns_iter && *dns_iter; dns_iter++) { + if (inet_pton (AF_INET, *dns_iter, &tmp)) + nm_ip4_config_add_nameserver (ip4, tmp); + } + if (dns) + g_strfreev (dns); + } + + value = g_hash_table_lookup (hash, "option domain-name"); + if (value && value[0]) + nm_ip4_config_add_domain (ip4, value); + + /* FIXME: static routes */ + + leases = g_slist_append (leases, ip4); + } + + g_date_time_unref (now); + g_slist_free_full (parsed, (GDestroyNotify) g_hash_table_destroy); + return leases; +} + diff --git a/src/dhcp-manager/nm-dhcp-dhclient-utils.h b/src/dhcp-manager/nm-dhcp-dhclient-utils.h index 95cb0568..e8d91b31 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient-utils.h +++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.h @@ -27,9 +27,8 @@ char *nm_dhcp_dhclient_create_config (const char *interface, gboolean is_ip6, - NMSettingIP4Config *s_ip4, - NMSettingIP6Config *s_ip6, - guint8 *anycast_addr, + const char *dhcp_client_id, + GByteArray *anycast_addr, const char *hostname, const char *orig_path, const char *orig_contents); @@ -44,5 +43,10 @@ gboolean nm_dhcp_dhclient_save_duid (const char *leasefile, const char *escaped_duid, GError **error); +GSList *nm_dhcp_dhclient_read_lease_ip_configs (const char *iface, + const char *contents, + gboolean ipv6, + GDateTime *now); + #endif /* NM_DHCP_DHCLIENT_UTILS_H */ diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c index 9a42f0e4..4232ee0c 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient.c +++ b/src/dhcp-manager/nm-dhcp-dhclient.c @@ -32,6 +32,7 @@ #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> +#include <ctype.h> #include <config.h> @@ -39,14 +40,13 @@ #include "nm-utils.h" #include "nm-logging.h" #include "nm-dhcp-dhclient-utils.h" +#include "nm-dhcp-manager.h" #include "nm-posix-signals.h" G_DEFINE_TYPE (NMDHCPDhclient, nm_dhcp_dhclient, NM_TYPE_DHCP_CLIENT) #define NM_DHCP_DHCLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_DHCLIENT, NMDHCPDhclientPrivate)) -#define ACTION_SCRIPT_PATH LIBEXECDIR "/nm-dhcp-client.action" - typedef struct { const char *path; char *conf_file; @@ -136,223 +136,37 @@ get_dhclient_leasefile (const char *iface, return NULL; } -static void -add_lease_option (GHashTable *hash, char *line) -{ - char *spc; - - spc = strchr (line, ' '); - if (!spc) { - nm_log_warn (LOGD_DHCP, "DHCP lease file line '%s' did not contain a space", line); - return; - } - - /* If it's an 'option' line, split at second space */ - if (g_str_has_prefix (line, "option ")) { - spc = strchr (spc + 1, ' '); - if (!spc) { - nm_log_warn (LOGD_DHCP, "DHCP lease file option line '%s' did not contain a second space", - line); - return; - } - } - - /* Split the line at the space */ - *spc = '\0'; - spc++; - - /* Kill the ';' at the end of the line, if any */ - if (*(spc + strlen (spc) - 1) == ';') - *(spc + strlen (spc) - 1) = '\0'; - - /* Treat 'interface' specially */ - if (g_str_has_prefix (line, "interface")) { - if (*(spc) == '"') - spc++; /* Jump past the " */ - if (*(spc + strlen (spc) - 1) == '"') - *(spc + strlen (spc) - 1) = '\0'; /* Kill trailing " */ - } - - g_hash_table_insert (hash, g_strdup (line), g_strdup (spc)); -} - GSList * -nm_dhcp_dhclient_get_lease_config (const char *iface, const char *uuid, gboolean ipv6) +nm_dhcp_dhclient_get_lease_ip_configs (const char *iface, + const char *uuid, + gboolean ipv6) { - GSList *parsed = NULL, *iter, *leases = NULL; char *contents = NULL; char *leasefile; - char **line, **split = NULL; - GHashTable *hash = NULL; - - /* IPv6 not supported */ - if (ipv6) - return NULL; + GSList *leases = NULL; leasefile = get_dhclient_leasefile (iface, uuid, FALSE, NULL); if (!leasefile) return NULL; - if (!g_file_test (leasefile, G_FILE_TEST_EXISTS)) - goto out; - - if (!g_file_get_contents (leasefile, &contents, NULL, NULL)) - goto out; + if ( g_file_test (leasefile, G_FILE_TEST_EXISTS) + && g_file_get_contents (leasefile, &contents, NULL, NULL) + && contents + && contents[0]) + leases = nm_dhcp_dhclient_read_lease_ip_configs (iface, contents, ipv6, NULL); - split = g_strsplit_set (contents, "\n\r", -1); + g_free (leasefile); g_free (contents); - if (!split) - goto out; - - for (line = split; line && *line; line++) { - *line = g_strstrip (*line); - - if (!strcmp (*line, "}")) { - /* Lease ends */ - parsed = g_slist_append (parsed, hash); - hash = NULL; - } else if (!strcmp (*line, "lease {")) { - /* Beginning of a new lease */ - if (hash) { - nm_log_warn (LOGD_DHCP, "DHCP lease file %s malformed; new lease started " - "without ending previous lease", - leasefile); - g_hash_table_destroy (hash); - } - - hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - } else if (strlen (*line)) - add_lease_option (hash, *line); - } - g_strfreev (split); - - /* Check if the last lease in the file was properly ended */ - if (hash) { - nm_log_warn (LOGD_DHCP, "DHCP lease file %s malformed; new lease started " - "without ending previous lease", - leasefile); - g_hash_table_destroy (hash); - hash = NULL; - } - - for (iter = parsed; iter; iter = g_slist_next (iter)) { - NMIP4Config *ip4; - NMIP4Address *addr; - const char *data; - struct in_addr tmp; - guint32 prefix; - struct tm expire; - - hash = iter->data; - - /* Make sure this lease is for the interface we want */ - data = g_hash_table_lookup (hash, "interface"); - if (!data || strcmp (data, iface)) - continue; - - data = g_hash_table_lookup (hash, "expire"); - if (data) { - time_t now_tt; - struct tm *now; - - /* Read lease expiration (in UTC) */ - if (!strptime (data, "%w %Y/%m/%d %H:%M:%S", &expire)) { - nm_log_warn (LOGD_DHCP, "couldn't parse DHCP lease file expire time '%s'", - data); - continue; - } - - now_tt = time (NULL); - now = gmtime(&now_tt); - - /* Ignore this lease if it's already expired */ - if (expire.tm_year < now->tm_year) - continue; - else if (expire.tm_year == now->tm_year) { - if (expire.tm_mon < now->tm_mon) - continue; - else if (expire.tm_mon == now->tm_mon) { - if (expire.tm_mday < now->tm_mday) - continue; - else if (expire.tm_mday == now->tm_mday) { - if (expire.tm_hour < now->tm_hour) - continue; - else if (expire.tm_hour == now->tm_hour) { - if (expire.tm_min < now->tm_min) - continue; - else if (expire.tm_min == now->tm_min) { - if (expire.tm_sec <= now->tm_sec) - continue; - } - } - } - } - } - /* If we get this far, the lease hasn't expired */ - } - data = g_hash_table_lookup (hash, "fixed-address"); - if (!data) - continue; - - ip4 = nm_ip4_config_new (); - addr = nm_ip4_address_new (); - - /* IP4 address */ - if (!inet_pton (AF_INET, data, &tmp)) { - nm_log_warn (LOGD_DHCP, "couldn't parse DHCP lease file IP4 address '%s'", data); - goto error; - } - nm_ip4_address_set_address (addr, tmp.s_addr); - - /* Netmask */ - data = g_hash_table_lookup (hash, "option subnet-mask"); - if (data) { - if (!inet_pton (AF_INET, data, &tmp)) { - nm_log_warn (LOGD_DHCP, "couldn't parse DHCP lease file IP4 subnet mask '%s'", data); - goto error; - } - prefix = nm_utils_ip4_netmask_to_prefix (tmp.s_addr); - } else { - /* Get default netmask for the IP according to appropriate class. */ - prefix = nm_utils_ip4_get_default_prefix (nm_ip4_address_get_address (addr)); - } - nm_ip4_address_set_prefix (addr, prefix); - - /* Gateway */ - data = g_hash_table_lookup (hash, "option routers"); - if (data) { - if (!inet_pton (AF_INET, data, &tmp)) { - nm_log_warn (LOGD_DHCP, "couldn't parse DHCP lease file IP4 gateway '%s'", data); - goto error; - } - nm_ip4_address_set_gateway (addr, tmp.s_addr); - } - - nm_ip4_config_take_address (ip4, addr); - leases = g_slist_append (leases, ip4); - continue; - - error: - nm_ip4_address_unref (addr); - g_object_unref (ip4); - } - -out: - g_slist_free_full (parsed, (GDestroyNotify) g_hash_table_destroy); - g_free (leasefile); return leases; } - - static gboolean merge_dhclient_config (const char *iface, const char *conf_file, gboolean is_ip6, - NMSettingIP4Config *s_ip4, - NMSettingIP6Config *s_ip6, - guint8 *anycast_addr, + const char *dhcp_client_id, + GByteArray *anycast_addr, const char *hostname, const char *orig_path, GError **error) @@ -363,7 +177,7 @@ merge_dhclient_config (const char *iface, g_return_val_if_fail (iface != NULL, FALSE); g_return_val_if_fail (conf_file != NULL, FALSE); - if (g_file_test (orig_path, G_FILE_TEST_EXISTS)) { + if (orig_path && g_file_test (orig_path, G_FILE_TEST_EXISTS)) { GError *read_error = NULL; if (!g_file_get_contents (orig_path, &orig, NULL, &read_error)) { @@ -373,7 +187,7 @@ merge_dhclient_config (const char *iface, } } - new = nm_dhcp_dhclient_create_config (iface, is_ip6, s_ip4, s_ip6, anycast_addr, hostname, orig_path, orig); + new = nm_dhcp_dhclient_create_config (iface, is_ip6, dhcp_client_id, anycast_addr, hostname, orig_path, orig); g_assert (new); success = g_file_set_contents (conf_file, new, -1, error); g_free (new); @@ -383,7 +197,7 @@ merge_dhclient_config (const char *iface, } static char * -get_dhclient_config (const char * iface, const char *uuid, gboolean ipv6) +find_existing_config (const char *iface, const char *uuid, gboolean ipv6) { char *path; @@ -393,17 +207,20 @@ get_dhclient_config (const char * iface, const char *uuid, gboolean ipv6) */ if (uuid) { path = g_strdup_printf (NMCONFDIR "/dhclient%s-%s.conf", ipv6 ? "6" : "", uuid); + nm_log_dbg (ipv6 ? LOGD_DHCP6 : LOGD_DHCP4, "(%s) looking for existing config %s", iface, path); if (g_file_test (path, G_FILE_TEST_EXISTS)) return path; g_free (path); } path = g_strdup_printf (NMCONFDIR "/dhclient%s-%s.conf", ipv6 ? "6" : "", iface); + nm_log_dbg (ipv6 ? LOGD_DHCP6 : LOGD_DHCP4, "(%s) looking for existing config %s", iface, path); if (g_file_test (path, G_FILE_TEST_EXISTS)) return path; g_free (path); path = g_strdup_printf (NMCONFDIR "/dhclient%s.conf", ipv6 ? "6" : ""); + nm_log_dbg (ipv6 ? LOGD_DHCP6 : LOGD_DHCP4, "(%s) looking for existing config %s", iface, path); if (g_file_test (path, G_FILE_TEST_EXISTS)) return path; g_free (path); @@ -417,21 +234,25 @@ get_dhclient_config (const char * iface, const char *uuid, gboolean ipv6) * (including Fedora) don't even provide a default configuration file. */ path = g_strdup_printf (SYSCONFDIR "/dhcp/dhclient%s-%s.conf", ipv6 ? "6" : "", iface); + nm_log_dbg (ipv6 ? LOGD_DHCP6 : LOGD_DHCP4, "(%s) looking for existing config %s", iface, path); if (g_file_test (path, G_FILE_TEST_EXISTS)) return path; g_free (path); path = g_strdup_printf (SYSCONFDIR "/dhclient%s-%s.conf", ipv6 ? "6" : "", iface); + nm_log_dbg (ipv6 ? LOGD_DHCP6 : LOGD_DHCP4, "(%s) looking for existing config %s", iface, path); if (g_file_test (path, G_FILE_TEST_EXISTS)) return path; g_free (path); path = g_strdup_printf (SYSCONFDIR "/dhcp/dhclient%s.conf", ipv6 ? "6" : ""); + nm_log_dbg (ipv6 ? LOGD_DHCP6 : LOGD_DHCP4, "(%s) looking for existing config %s", iface, path); if (g_file_test (path, G_FILE_TEST_EXISTS)) return path; g_free (path); path = g_strdup_printf (SYSCONFDIR "/dhclient%s.conf", ipv6 ? "6" : ""); + nm_log_dbg (ipv6 ? LOGD_DHCP6 : LOGD_DHCP4, "(%s) looking for existing config %s", iface, path); if (g_file_test (path, G_FILE_TEST_EXISTS)) return path; g_free (path); @@ -449,9 +270,9 @@ get_dhclient_config (const char * iface, const char *uuid, gboolean ipv6) static char * create_dhclient_config (const char *iface, gboolean is_ip6, - NMSettingIP4Config *s_ip4, - NMSettingIP6Config *s_ip6, - guint8 *dhcp_anycast_addr, + const char *uuid, + const char *dhcp_client_id, + GByteArray *dhcp_anycast_addr, const char *hostname) { char *orig = NULL, *new = NULL; @@ -461,11 +282,23 @@ create_dhclient_config (const char *iface, g_return_val_if_fail (iface != NULL, NULL); new = g_strdup_printf (NMSTATEDIR "/dhclient%s-%s.conf", is_ip6 ? "6" : "", iface); + nm_log_dbg (is_ip6 ? LOGD_DHCP6 : LOGD_DHCP4, + "(%s): creating composite dhclient config %s", + iface, new); + + orig = find_existing_config (iface, uuid, is_ip6); + if (orig) { + nm_log_dbg (is_ip6 ? LOGD_DHCP6 : LOGD_DHCP4, + "(%s): merging existing dhclient config %s", + iface, orig); + } else { + nm_log_dbg (is_ip6 ? LOGD_DHCP6 : LOGD_DHCP4, + "(%s): no existing dhclient configuration to merge", + iface); + } - /* TODO: also support UUID */ - orig = get_dhclient_config (iface, NULL, is_ip6); error = NULL; - success = merge_dhclient_config (iface, new, is_ip6, s_ip4, s_ip6, dhcp_anycast_addr, hostname, orig, &error); + success = merge_dhclient_config (iface, new, is_ip6, dhcp_client_id, dhcp_anycast_addr, hostname, orig, &error); if (!success) { nm_log_warn (LOGD_DHCP, "(%s): error creating dhclient%s configuration: %s", iface, is_ip6 ? "6" : "", error->message); @@ -523,10 +356,6 @@ dhclient_start (NMDHCPClient *client, pid_file = g_strdup_printf (LOCALSTATEDIR "/run/dhclient%s-%s.pid", ipv6 ? "6" : "", iface); - if (!pid_file) { - nm_log_warn (log_domain, "(%s): not enough memory for dhcpcd options.", iface); - return -1; - } /* Kill any existing dhclient from the pidfile */ binary_name = g_path_get_basename (priv->path); @@ -593,7 +422,7 @@ dhclient_start (NMDHCPClient *client, g_ptr_array_add (argv, (gpointer) mode_opt); } g_ptr_array_add (argv, (gpointer) "-sf"); /* Set script file */ - g_ptr_array_add (argv, (gpointer) ACTION_SCRIPT_PATH ); + g_ptr_array_add (argv, (gpointer) nm_dhcp_helper_path); if (pid_file) { g_ptr_array_add (argv, (gpointer) "-pf"); /* Set pid file */ @@ -644,16 +473,17 @@ dhclient_start (NMDHCPClient *client, static GPid ip4_start (NMDHCPClient *client, - NMSettingIP4Config *s_ip4, - guint8 *dhcp_anycast_addr, + const char *dhcp_client_id, + GByteArray *dhcp_anycast_addr, const char *hostname) { NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); - const char *iface; + const char *iface, *uuid; iface = nm_dhcp_client_get_iface (client); + uuid = nm_dhcp_client_get_uuid (client); - priv->conf_file = create_dhclient_config (iface, FALSE, s_ip4, NULL, dhcp_anycast_addr, hostname); + priv->conf_file = create_dhclient_config (iface, FALSE, uuid, dhcp_client_id, dhcp_anycast_addr, hostname); if (!priv->conf_file) { nm_log_warn (LOGD_DHCP4, "(%s): error creating dhclient configuration file.", iface); return -1; @@ -664,18 +494,18 @@ ip4_start (NMDHCPClient *client, static GPid ip6_start (NMDHCPClient *client, - NMSettingIP6Config *s_ip6, - guint8 *dhcp_anycast_addr, + GByteArray *dhcp_anycast_addr, const char *hostname, gboolean info_only, const GByteArray *duid) { NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); - const char *iface; + const char *iface, *uuid; iface = nm_dhcp_client_get_iface (client); + uuid = nm_dhcp_client_get_uuid (client); - priv->conf_file = create_dhclient_config (iface, TRUE, NULL, s_ip6, dhcp_anycast_addr, hostname); + priv->conf_file = create_dhclient_config (iface, TRUE, uuid, NULL, dhcp_anycast_addr, hostname); if (!priv->conf_file) { nm_log_warn (LOGD_DHCP6, "(%s): error creating dhclient6 configuration file.", iface); return -1; @@ -693,9 +523,11 @@ stop (NMDHCPClient *client, gboolean release, const GByteArray *duid) NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->stop (client, release, duid); if (priv->conf_file) - remove (priv->conf_file); + if (remove (priv->conf_file) == -1) + nm_log_dbg (LOGD_DHCP, "Could not remove dhcp config file \"%s\": %d (%s)", priv->conf_file, errno, g_strerror (errno)); if (priv->pid_file) { - remove (priv->pid_file); + if (remove (priv->pid_file) == -1) + nm_log_dbg (LOGD_DHCP, "Could not remove dhcp pid file \"%s\": %d (%s)", priv->pid_file, errno, g_strerror (errno)); g_free (priv->pid_file); priv->pid_file = NULL; } @@ -706,7 +538,7 @@ stop (NMDHCPClient *client, gboolean release, const GByteArray *duid) rpid = dhclient_start (client, NULL, duid, TRUE); if (rpid > 0) { /* Wait a few seconds for the release to happen */ - nm_dhcp_client_stop_pid (rpid, nm_dhcp_client_get_iface (client), 5); + nm_dhcp_client_stop_pid (rpid, nm_dhcp_client_get_iface (client)); } } } @@ -727,13 +559,13 @@ get_duid (NMDHCPClient *client) if (leasefile) { nm_log_dbg (LOGD_DHCP, "Looking for DHCPv6 DUID in '%s'.", leasefile); duid = nm_dhcp_dhclient_read_duid (leasefile, &error); - g_free (leasefile); if (error) { nm_log_warn (LOGD_DHCP, "Failed to read leasefile '%s': (%d) %s", leasefile, error->code, error->message); g_clear_error (&error); } + g_free (leasefile); } if (!duid && priv->def_leasefile) { diff --git a/src/dhcp-manager/nm-dhcp-dhclient.h b/src/dhcp-manager/nm-dhcp-dhclient.h index 89039189..20219a63 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient.h +++ b/src/dhcp-manager/nm-dhcp-dhclient.h @@ -41,7 +41,9 @@ typedef struct { GType nm_dhcp_dhclient_get_type (void); -GSList *nm_dhcp_dhclient_get_lease_config (const char *iface, const char *uuid, gboolean ipv6); +GSList *nm_dhcp_dhclient_get_lease_ip_configs (const char *iface, + const char *uuid, + gboolean ipv6); const char *nm_dhcp_dhclient_get_path (const char *try_first); diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.c b/src/dhcp-manager/nm-dhcp-dhcpcd.c index f978cccc..acfbee26 100644 --- a/src/dhcp-manager/nm-dhcp-dhcpcd.c +++ b/src/dhcp-manager/nm-dhcp-dhcpcd.c @@ -34,6 +34,7 @@ #include <arpa/inet.h> #include "nm-dhcp-dhcpcd.h" +#include "nm-dhcp-manager.h" #include "nm-utils.h" #include "nm-logging.h" #include "nm-posix-signals.h" @@ -42,8 +43,6 @@ G_DEFINE_TYPE (NMDHCPDhcpcd, nm_dhcp_dhcpcd, NM_TYPE_DHCP_CLIENT) #define NM_DHCP_DHCPCD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_DHCPCD, NMDHCPDhcpcdPrivate)) -#define ACTION_SCRIPT_PATH LIBEXECDIR "/nm-dhcp-client.action" - typedef struct { const char *path; char *pid_file; @@ -73,12 +72,6 @@ nm_dhcp_dhcpcd_get_path (const char *try_first) return *path; } -GSList * -nm_dhcp_dhcpcd_get_lease_config (const char *iface, const char *uuid, gboolean ipv6) -{ - return NULL; -} - static void dhcpcd_child_setup (gpointer user_data G_GNUC_UNUSED) { @@ -95,8 +88,8 @@ dhcpcd_child_setup (gpointer user_data G_GNUC_UNUSED) static GPid ip4_start (NMDHCPClient *client, - NMSettingIP4Config *s_ip4, - guint8 *dhcp_anycast_addr, + const char *dhcp_client_id, + GByteArray *dhcp_anycast_addr, const char *hostname) { NMDHCPDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (client); @@ -104,21 +97,16 @@ ip4_start (NMDHCPClient *client, GPid pid = -1; GError *error = NULL; char *pid_contents = NULL, *binary_name, *cmd_str; - const char *iface, *uuid; + const char *iface; g_return_val_if_fail (priv->pid_file == NULL, -1); iface = nm_dhcp_client_get_iface (client); - uuid = nm_dhcp_client_get_uuid (client); /* dhcpcd does not allow custom pidfiles; the pidfile is always * RUNDIR "dhcpcd-<ifname>.pid". */ priv->pid_file = g_strdup_printf (RUNDIR "/dhcpcd-%s.pid", iface); - if (!priv->pid_file) { - nm_log_warn (LOGD_DHCP4, "(%s): not enough memory for dhcpcd options.", iface); - return -1; - } if (!g_file_test (priv->path, G_FILE_TEST_EXISTS)) { nm_log_warn (LOGD_DHCP4, "%s does not exist.", priv->path); @@ -142,7 +130,7 @@ ip4_start (NMDHCPClient *client, g_ptr_array_add (argv, (gpointer) "-G"); /* Let NM handle routing */ g_ptr_array_add (argv, (gpointer) "-c"); /* Set script file */ - g_ptr_array_add (argv, (gpointer) ACTION_SCRIPT_PATH ); + g_ptr_array_add (argv, (gpointer) nm_dhcp_helper_path); #ifdef DHCPCD_SUPPORTS_IPV6 /* IPv4-only for now. NetworkManager knows better than dhcpcd when to @@ -179,8 +167,7 @@ ip4_start (NMDHCPClient *client, static GPid ip6_start (NMDHCPClient *client, - NMSettingIP6Config *s_ip6, - guint8 *dhcp_anycast_addr, + GByteArray *dhcp_anycast_addr, const char *hostname, gboolean info_only, const GByteArray *duid) @@ -197,8 +184,10 @@ stop (NMDHCPClient *client, gboolean release, const GByteArray *duid) /* Chain up to parent */ NM_DHCP_CLIENT_CLASS (nm_dhcp_dhcpcd_parent_class)->stop (client, release, duid); - if (priv->pid_file) - remove (priv->pid_file); + if (priv->pid_file) { + if (remove (priv->pid_file) == -1) + nm_log_dbg (LOGD_DHCP, "Could not remove dhcp pid file \"%s\": %d (%s)", priv->pid_file, errno, g_strerror (errno)); + } /* FIXME: implement release... */ } diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.h b/src/dhcp-manager/nm-dhcp-dhcpcd.h index c90dcb74..fb6b0628 100644 --- a/src/dhcp-manager/nm-dhcp-dhcpcd.h +++ b/src/dhcp-manager/nm-dhcp-dhcpcd.h @@ -41,8 +41,6 @@ typedef struct { GType nm_dhcp_dhcpcd_get_type (void); -GSList *nm_dhcp_dhcpcd_get_lease_config (const char *iface, const char *uuid, gboolean ipv6); - const char *nm_dhcp_dhcpcd_get_path (const char *try_first); #endif /* NM_DHCP_DHCPCD_H */ diff --git a/src/dhcp-manager/nm-dhcp-helper.c b/src/dhcp-manager/nm-dhcp-helper.c new file mode 100644 index 00000000..4ddfafe1 --- /dev/null +++ b/src/dhcp-manager/nm-dhcp-helper.c @@ -0,0 +1,345 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2007 - 2013 Red Hat, Inc. + */ + +/* for environ */ +#define _GNU_SOURCE + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> + +#include <config.h> + +#include <dbus/dbus.h> + +#define NM_DHCP_CLIENT_DBUS_IFACE "org.freedesktop.nm_dhcp_client" + +/** + * _dbus_dict_open_write: + * @iter: A valid dbus message iterator + * @iter_dict: on return, a dict iterator to pass to further dict functions + * + * Start a dict in a dbus message. Should be paired with a call to + * _dbus_dict_close_write(). + * + * Returns: %TRUE on success, %FALSE on failure + */ +static dbus_bool_t +_dbus_dict_open_write (DBusMessageIter *iter, DBusMessageIter *iter_dict) +{ + if (!iter || !iter_dict) + return FALSE; + + return dbus_message_iter_open_container (iter, + DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + iter_dict); +} + +/** + * _dbus_dict_close_write: + * @iter: valid dbus message iterator, same as passed to _dbus_dict_open_write() + * @iter_dict: a dbus dict iterator returned from _dbus_dict_open_write() + * + * End a dict element in a dbus message. Should be paired with a call to + * _dbus_dict_open_write(). + * + * Returns: %TRUE on success, %FALSE on failure + */ +static dbus_bool_t +_dbus_dict_close_write (DBusMessageIter *iter, DBusMessageIter *iter_dict) +{ + if (!iter || !iter_dict) + return FALSE; + + return dbus_message_iter_close_container (iter, iter_dict); +} + +static dbus_bool_t +_dbus_add_dict_entry_start (DBusMessageIter *iter_dict, + DBusMessageIter *iter_dict_entry, + const char *key, + const int value_type) +{ + if (!dbus_message_iter_open_container (iter_dict, DBUS_TYPE_DICT_ENTRY, NULL, iter_dict_entry)) + return FALSE; + + if (!dbus_message_iter_append_basic (iter_dict_entry, DBUS_TYPE_STRING, &key)) + return FALSE; + + return TRUE; +} + + +static dbus_bool_t +_dbus_add_dict_entry_end (DBusMessageIter *iter_dict, + DBusMessageIter *iter_dict_entry, + DBusMessageIter *iter_dict_val) +{ + if (!dbus_message_iter_close_container (iter_dict_entry, iter_dict_val)) + return FALSE; + if (!dbus_message_iter_close_container (iter_dict, iter_dict_entry)) + return FALSE; + + return TRUE; +} + +static dbus_bool_t +_dbus_add_dict_entry_byte_array (DBusMessageIter *iter_dict, + const char *key, + const char *value, + const dbus_uint32_t value_len) +{ + DBusMessageIter iter_dict_entry, iter_dict_val, iter_array; + dbus_uint32_t i; + + if (!_dbus_add_dict_entry_start (iter_dict, &iter_dict_entry, key, DBUS_TYPE_ARRAY)) + return FALSE; + + if (!dbus_message_iter_open_container (&iter_dict_entry, + DBUS_TYPE_VARIANT, + DBUS_TYPE_ARRAY_AS_STRING + DBUS_TYPE_BYTE_AS_STRING, + &iter_dict_val)) + return FALSE; + + if (!dbus_message_iter_open_container (&iter_dict_val, + DBUS_TYPE_ARRAY, + DBUS_TYPE_BYTE_AS_STRING, + &iter_array)) + return FALSE; + + for (i = 0; i < value_len; i++) { + if (!dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_BYTE, &(value[i]))) + return FALSE; + } + + if (!dbus_message_iter_close_container (&iter_dict_val, &iter_array)) + return FALSE; + + if (!_dbus_add_dict_entry_end (iter_dict, &iter_dict_entry, &iter_dict_val)) + return FALSE; + + return TRUE; +} + +/** + * _dbus_dict_append_byte_array: + * @iter_dict: A valid %DBusMessageIter returned from _dbus_dict_open_write() + * @key: The key of the dict item + * @value: The byte array + * @value_len: The length of the byte array, in bytes + * + * Add a byte array entry to the dict. + * + * Returns: %TRUE on success, %FALSE on failure + * + */ +static dbus_bool_t +_dbus_dict_append_byte_array (DBusMessageIter *iter_dict, + const char *key, + const char *value, + const dbus_uint32_t value_len) +{ + if (!key) + return FALSE; + if (!value && (value_len != 0)) + return FALSE; + return _dbus_add_dict_entry_byte_array (iter_dict, key, value, value_len); +} + + +static const char * ignore[] = {"PATH", "SHLVL", "_", "PWD", "dhc_dbus", NULL}; + +static dbus_bool_t +build_message (DBusMessage * message) +{ + char **item; + dbus_bool_t success = FALSE; + DBusMessageIter iter, iter_dict; + + dbus_message_iter_init_append (message, &iter); + if (!_dbus_dict_open_write (&iter, &iter_dict)) + goto out; + + /* List environment and format for dbus dict */ + for (item = environ; *item; item++) { + char *name, *val, **p; + + /* Split on the = */ + name = strdup (*item); + val = strchr (name, '='); + if (!val) + goto next; + *val++ = '\0'; + if (!strlen (val)) + val = NULL; + + /* Ignore non-DCHP-related environment variables */ + for (p = (char **) ignore; *p; p++) { + if (strncmp (name, *p, strlen (*p)) == 0) + goto next; + } + + /* Value passed as a byte array rather than a string, because there are + * no character encoding guarantees with DHCP, and D-Bus requires + * strings to be UTF-8. + */ + if (!_dbus_dict_append_byte_array (&iter_dict, + name, + val ? val : "\0", + val ? strlen (val) : 1)) { + fprintf (stderr, "Error: failed to add item '%s' to signal\n", name); + } + + next: + free (name); + } + + if (!_dbus_dict_close_write (&iter, &iter_dict)) + goto out; + + success = TRUE; + +out: + return success; +} + +#if !HAVE_DBUS_GLIB_100 +static DBusConnection * +shared_connection_init (void) +{ + DBusConnection * connection; + DBusError error; + int ret; + + dbus_connection_set_change_sigpipe (TRUE); + + dbus_error_init (&error); + connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); + if (dbus_error_is_set (&error)) { + fprintf (stderr, "Error: could not get the system bus. Make sure " + "the message bus daemon is running! Message: (%s) %s\n", + error.name, + error.message); + goto error; + } + + dbus_error_init (&error); + ret = dbus_bus_request_name (connection, "org.freedesktop.nm_dhcp_client", 0, &error); + if (dbus_error_is_set (&error)) { + fprintf (stderr, "Error: Could not acquire the NM DHCP client service. " + "Message: (%s) %s\n", + error.name, + error.message); + goto error; + } + + if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + fprintf (stderr, "Error: Could not acquire the NM DHCP client service " + "as it is already taken. Return: %d\n", + ret); + goto error; + } + + return connection; + +error: + if (dbus_error_is_set (&error)) + dbus_error_free (&error); + if (connection) + dbus_connection_unref (connection); + return NULL; +} +#endif + +static void +fatal_error (void) +{ + const char *pid_str = getenv ("pid"); + int pid = 0; + + if (pid_str) + pid = strtol (pid_str, NULL, 10); + if (pid) { + fprintf (stderr, "Fatal error occured, killing dhclient instance with pid %d.\n", pid); + kill (pid, SIGTERM); + } + + exit (1); +} + +int +main (int argc, char *argv[]) +{ + DBusConnection *connection; + DBusMessage *message; + dbus_bool_t result; + DBusError error; + + dbus_connection_set_change_sigpipe (TRUE); + + dbus_error_init (&error); + connection = dbus_connection_open_private ("unix:path=" NMRUNDIR "/private-dhcp", &error); + if (!connection) { +#if !HAVE_DBUS_GLIB_100 + connection = shared_connection_init (); +#endif + if (!connection) { + fprintf (stderr, "Error: could not connect to NetworkManager DBus socket: (%s) %s\n", + error.name, error.message); + dbus_error_free (&error); + fatal_error (); + } + } + dbus_connection_set_exit_on_disconnect (connection, FALSE); + + message = dbus_message_new_signal ("/", NM_DHCP_CLIENT_DBUS_IFACE, "Event"); + if (message == NULL) { + fprintf (stderr, "Error: Not enough memory to send DHCP Event signal.\n"); + fatal_error (); + } + + /* Dump environment variables into the message */ + result = build_message (message); + if (result == FALSE) { + fprintf (stderr, "Error: Not enough memory to send DHCP Event signal.\n"); + fatal_error (); + } + + /* queue the message */ + result = dbus_connection_send (connection, message, NULL); + if (!result) { + fprintf (stderr, "Error: Could not send send DHCP Event signal.\n"); + fatal_error (); + } + dbus_message_unref (message); + + /* Send out the message */ + dbus_connection_flush (connection); + + return 0; +} + diff --git a/src/dhcp-manager/nm-dhcp-helper.conf b/src/dhcp-manager/nm-dhcp-helper.conf new file mode 100644 index 00000000..0aeae603 --- /dev/null +++ b/src/dhcp-manager/nm-dhcp-helper.conf @@ -0,0 +1,13 @@ +<!DOCTYPE busconfig PUBLIC + "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + <policy user="root"> + <allow own="org.freedesktop.nm_dhcp_client"/> + </policy> + <policy context="default"> + <deny own="org.freedesktop.nm_dhcp_client"/> + <deny send_destination="org.freedesktop.nm_dhcp_client"/> + </policy> +</busconfig> + diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index d40eb48d..ab6966cb 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2010 Red Hat, Inc. + * Copyright (C) 2005 - 2013 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. * */ @@ -37,12 +37,12 @@ #include "nm-dhcp-manager.h" #include "nm-dhcp-dhclient.h" #include "nm-dhcp-dhcpcd.h" -#include "nm-marshal.h" #include "nm-logging.h" #include "nm-dbus-manager.h" -#include "nm-hostname-provider.h" +#include "nm-config.h" #include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" +#include "NetworkManagerUtils.h" GQuark nm_dhcp_manager_error_quark (void) @@ -55,23 +55,30 @@ nm_dhcp_manager_error_quark (void) return ret; } -#define NM_DHCP_CLIENT_DBUS_SERVICE "org.freedesktop.nm_dhcp_client" #define NM_DHCP_CLIENT_DBUS_IFACE "org.freedesktop.nm_dhcp_client" #define DHCP_TIMEOUT 45 /* default DHCP timeout, in seconds */ -static NMDHCPManager *singleton = NULL; +#define PRIV_SOCK_PATH NMRUNDIR "/private-dhcp" +#define PRIV_SOCK_TAG "dhcp" + +/* default to installed helper, but can be modified for testing */ +const char *nm_dhcp_helper_path = LIBEXECDIR "/nm-dhcp-helper"; typedef GSList * (*GetLeaseConfigFunc) (const char *iface, const char *uuid, gboolean ipv6); typedef struct { GType client_type; - GetLeaseConfigFunc get_lease_config_func; + GetLeaseConfigFunc get_lease_ip_configs_func; NMDBusManager * dbus_mgr; + guint new_conn_id; + guint dis_conn_id; + GHashTable * proxies; + GHashTable * clients; DBusGProxy * proxy; - NMHostnameProvider *hostname_provider; + char * default_hostname; } NMDHCPManagerPrivate; @@ -119,7 +126,6 @@ get_client_for_pid (NMDHCPManager *manager, GPid pid) GHashTableIter iter; gpointer value; - g_return_val_if_fail (manager != NULL, NULL); g_return_val_if_fail (NM_IS_DHCP_MANAGER (manager), NULL); priv = NM_DHCP_MANAGER_GET_PRIVATE (manager); @@ -144,7 +150,6 @@ get_client_for_iface (NMDHCPManager *manager, GHashTableIter iter; gpointer value; - g_return_val_if_fail (manager != NULL, NULL); g_return_val_if_fail (NM_IS_DHCP_MANAGER (manager), NULL); g_return_val_if_fail (iface, NULL); @@ -186,50 +191,46 @@ nm_dhcp_manager_handle_event (DBusGProxy *proxy, GHashTable *options, gpointer user_data) { - NMDHCPManager *manager; - NMDHCPManagerPrivate *priv; + NMDHCPManager *manager = NM_DHCP_MANAGER (user_data); NMDHCPClient *client; char *iface = NULL; char *pid_str = NULL; char *reason = NULL; - unsigned long temp; - - manager = NM_DHCP_MANAGER (user_data); - priv = NM_DHCP_MANAGER_GET_PRIVATE (manager); + long pid; iface = get_option (options, "interface"); if (iface == NULL) { - nm_log_warn (LOGD_DHCP, "DHCP event didn't have associated interface."); + nm_log_warn (LOGD_DHCP, "DHCP event: didn't have associated interface."); goto out; } pid_str = get_option (options, "pid"); - if (pid_str == NULL) { - nm_log_warn (LOGD_DHCP, "DHCP event didn't have associated PID."); - goto out; - } - - temp = strtoul (pid_str, NULL, 10); - if ((temp == ULONG_MAX) && (errno == ERANGE)) { - nm_log_warn (LOGD_DHCP, "couldn't convert PID"); + pid = nm_utils_ascii_str_to_int64 (pid_str, 10, 0, LONG_MAX, -1); + if (pid == -1 || pid != (GPid)pid) { + nm_log_warn (LOGD_DHCP, "DHCP event: couldn't convert PID '%s' to an integer", pid_str ? pid_str : "(null)"); goto out; } - client = get_client_for_pid (manager, (GPid) temp); + reason = get_option (options, "reason"); + client = get_client_for_pid (manager, (GPid) pid); if (client == NULL) { - nm_log_warn (LOGD_DHCP, "(pid %ld) unhandled DHCP event for interface %s", temp, iface); + if (reason && g_ascii_strcasecmp (reason, "RELEASE") == 0) { + /* This happens regularly, when the dhcp client gets killed and we receive its last message. + * Don't log a warning in this case. */ + nm_log_dbg (LOGD_DHCP, "(pid %ld) unhandled RELEASE DHCP event for interface %s", pid, iface); + } else + nm_log_warn (LOGD_DHCP, "(pid %ld) unhandled DHCP event for interface %s", pid, iface); goto out; } if (strcmp (iface, nm_dhcp_client_get_iface (client))) { nm_log_warn (LOGD_DHCP, "(pid %ld) received DHCP event from unexpected interface '%s' (expected '%s')", - temp, iface, nm_dhcp_client_get_iface (client)); + pid, iface, nm_dhcp_client_get_iface (client)); goto out; } - reason = get_option (options, "reason"); if (reason == NULL) { - nm_log_warn (LOGD_DHCP, "(pid %ld) DHCP event didn't have a reason", temp); + nm_log_warn (LOGD_DHCP, "(pid %ld) DHCP event didn't have a reason", pid); goto out; } @@ -241,6 +242,48 @@ out: g_free (reason); } +#if HAVE_DBUS_GLIB_100 +static void +new_connection_cb (NMDBusManager *mgr, + DBusGConnection *connection, + NMDHCPManager *self) +{ + NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self); + DBusGProxy *proxy; + + /* Create a new proxy for the client */ + proxy = dbus_g_proxy_new_for_peer (connection, "/", NM_DHCP_CLIENT_DBUS_IFACE); + dbus_g_proxy_add_signal (proxy, + "Event", + DBUS_TYPE_G_MAP_OF_VARIANT, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal (proxy, + "Event", + G_CALLBACK (nm_dhcp_manager_handle_event), + self, + NULL); + g_hash_table_insert (priv->proxies, connection, proxy); +} + +static void +dis_connection_cb (NMDBusManager *mgr, + DBusGConnection *connection, + NMDHCPManager *self) +{ + NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self); + DBusGProxy *proxy; + + proxy = g_hash_table_lookup (priv->proxies, connection); + if (proxy) { + dbus_g_proxy_disconnect_signal (proxy, + "Event", + G_CALLBACK (nm_dhcp_manager_handle_event), + self); + g_hash_table_remove (priv->proxies, connection); + } +} +#endif + static GType get_client_type (const char *client, GError **error) { @@ -250,8 +293,10 @@ get_client_type (const char *client, GError **error) /* If a client was disabled at build-time, its *_PATH define will be * an empty string. */ + /* coverity[array_null] */ if (DHCLIENT_PATH && strlen (DHCLIENT_PATH)) dhclient_path = nm_dhcp_dhclient_get_path (DHCLIENT_PATH); + /* coverity[array_null] */ if (DHCPCD_PATH && strlen (DHCPCD_PATH)) dhcpcd_path = nm_dhcp_dhcpcd_get_path (DHCPCD_PATH); @@ -264,7 +309,7 @@ get_client_type (const char *client, GError **error) g_set_error_literal (error, NM_DHCP_MANAGER_ERROR, NM_DHCP_MANAGER_ERROR_BAD_CLIENT, _("no usable DHCP client could be found.")); - return 0; + return G_TYPE_INVALID; } } @@ -273,7 +318,7 @@ get_client_type (const char *client, GError **error) g_set_error_literal (error, NM_DHCP_MANAGER_ERROR, NM_DHCP_MANAGER_ERROR_BAD_CLIENT, _("'dhclient' could be found.")); - return 0; + return G_TYPE_INVALID; } return NM_TYPE_DHCP_DHCLIENT; } @@ -283,7 +328,7 @@ get_client_type (const char *client, GError **error) g_set_error_literal (error, NM_DHCP_MANAGER_ERROR, NM_DHCP_MANAGER_ERROR_BAD_CLIENT, _("'dhcpcd' could be found.")); - return 0; + return G_TYPE_INVALID; } return NM_TYPE_DHCP_DHCPCD; } @@ -291,54 +336,7 @@ get_client_type (const char *client, GError **error) g_set_error (error, NM_DHCP_MANAGER_ERROR, NM_DHCP_MANAGER_ERROR_BAD_CLIENT, _("unsupported DHCP client '%s'"), client); - return 0; -} - -NMDHCPManager * -nm_dhcp_manager_new (const char *client, GError **error) -{ - NMDHCPManagerPrivate *priv; - DBusGConnection *g_connection; - - g_warn_if_fail (singleton == NULL); - - singleton = g_object_new (NM_TYPE_DHCP_MANAGER, NULL); - priv = NM_DHCP_MANAGER_GET_PRIVATE (singleton); - - /* Client-specific setup */ - priv->client_type = get_client_type (client, error); - if (priv->client_type == NM_TYPE_DHCP_DHCLIENT) - priv->get_lease_config_func = nm_dhcp_dhclient_get_lease_config; - else if (priv->client_type == NM_TYPE_DHCP_DHCPCD) - priv->get_lease_config_func = nm_dhcp_dhcpcd_get_lease_config; - else { - nm_log_warn (LOGD_DHCP, "No usable DHCP client found! DHCP configurations will fail."); - } - - priv->clients = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, - (GDestroyNotify) g_object_unref); - g_assert (priv->clients); - - priv->dbus_mgr = nm_dbus_manager_get (); - g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); - priv->proxy = dbus_g_proxy_new_for_name (g_connection, - NM_DHCP_CLIENT_DBUS_SERVICE, - "/", - NM_DHCP_CLIENT_DBUS_IFACE); - g_assert (priv->proxy); - - dbus_g_proxy_add_signal (priv->proxy, - "Event", - DBUS_TYPE_G_MAP_OF_VARIANT, - G_TYPE_INVALID); - - dbus_g_proxy_connect_signal (priv->proxy, "Event", - G_CALLBACK (nm_dhcp_manager_handle_event), - singleton, - NULL); - - return singleton; + return G_TYPE_INVALID; } #define REMOVE_ID_TAG "remove-id" @@ -372,10 +370,10 @@ add_client (NMDHCPManager *self, NMDHCPClient *client) NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self); guint id; - id = g_signal_connect_swapped (client, "remove", G_CALLBACK (remove_client), self); + id = g_signal_connect_swapped (client, NM_DHCP_CLIENT_SIGNAL_REMOVE, G_CALLBACK (remove_client), self); g_object_set_data (G_OBJECT (client), REMOVE_ID_TAG, GUINT_TO_POINTER (id)); - id = g_signal_connect_swapped (client, "timeout", G_CALLBACK (remove_client), self); + id = g_signal_connect_swapped (client, NM_DHCP_CLIENT_SIGNAL_TIMEOUT, G_CALLBACK (remove_client), self); g_object_set_data (G_OBJECT (client), TIMEOUT_ID_TAG, GUINT_TO_POINTER (id)); g_hash_table_insert (priv->clients, client, g_object_ref (client)); @@ -386,11 +384,11 @@ client_start (NMDHCPManager *self, const char *iface, const GByteArray *hwaddr, const char *uuid, + guint priority, gboolean ipv6, - NMSettingIP4Config *s_ip4, - NMSettingIP6Config *s_ip6, + const char *dhcp_client_id, guint32 timeout, - guint8 *dhcp_anycast_addr, + GByteArray *dhcp_anycast_addr, const char *hostname, gboolean info_only) { @@ -421,15 +419,16 @@ client_start (NMDHCPManager *self, NM_DHCP_CLIENT_HWADDR, hwaddr, NM_DHCP_CLIENT_IPV6, ipv6, NM_DHCP_CLIENT_UUID, uuid, + NM_DHCP_CLIENT_PRIORITY, priority, NM_DHCP_CLIENT_TIMEOUT, timeout ? timeout : DHCP_TIMEOUT, NULL); g_return_val_if_fail (client != NULL, NULL); add_client (self, client); if (ipv6) - success = nm_dhcp_client_start_ip6 (client, s_ip6, dhcp_anycast_addr, hostname, info_only); + success = nm_dhcp_client_start_ip6 (client, dhcp_anycast_addr, hostname, info_only); else - success = nm_dhcp_client_start_ip4 (client, s_ip4, dhcp_anycast_addr, hostname); + success = nm_dhcp_client_start_ip4 (client, dhcp_client_id, dhcp_anycast_addr, hostname); if (!success) { remove_client (self, client); @@ -440,54 +439,42 @@ client_start (NMDHCPManager *self, return client; } +static const char * +get_send_hostname (NMDHCPManager *self, const char *setting_hostname) +{ + NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self); + + /* Always prefer the explicit dhcp-send-hostname if given */ + return setting_hostname ? setting_hostname : priv->default_hostname; +} + /* Caller owns a reference to the NMDHCPClient on return */ NMDHCPClient * nm_dhcp_manager_start_ip4 (NMDHCPManager *self, const char *iface, const GByteArray *hwaddr, const char *uuid, + guint priority, NMSettingIP4Config *s_ip4, guint32 timeout, - guint8 *dhcp_anycast_addr) + GByteArray *dhcp_anycast_addr) { - NMDHCPManagerPrivate *priv; - const char *hostname = NULL; - gboolean send_hostname = TRUE; + const char *hostname = NULL, *method; + gboolean send_hostname; g_return_val_if_fail (self, NULL); g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); - priv = NM_DHCP_MANAGER_GET_PRIVATE (self); - - if (s_ip4) { - const char *method = nm_setting_ip4_config_get_method (s_ip4); - - if (method) { - /* Method must be 'auto' */ - g_return_val_if_fail (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, NULL); - } - - send_hostname = nm_setting_ip4_config_get_dhcp_send_hostname (s_ip4); - if (send_hostname) - hostname = nm_setting_ip4_config_get_dhcp_hostname (s_ip4); - } + method = nm_setting_ip4_config_get_method (s_ip4); + g_return_val_if_fail (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, NULL); - if (send_hostname) { - /* If we're supposed to send the hostname to the DHCP server but - * the user didn't specify one, then use the hostname from the - * hostname provider if there is one, otherwise use the persistent - * hostname. - */ - if (!hostname && priv->hostname_provider) { - hostname = nm_hostname_provider_get_hostname (priv->hostname_provider); - if ( hostname - && (!strcmp (hostname, "localhost.localdomain") || - !strcmp (hostname, "localhost6.localdomain6"))) - hostname = NULL; - } - } + send_hostname = nm_setting_ip4_config_get_dhcp_send_hostname (s_ip4); + if (send_hostname) + hostname = get_send_hostname (self, nm_setting_ip4_config_get_dhcp_hostname (s_ip4)); - return client_start (self, iface, hwaddr, uuid, FALSE, s_ip4, NULL, timeout, dhcp_anycast_addr, hostname, FALSE); + return client_start (self, iface, hwaddr, uuid, priority, FALSE, + nm_setting_ip4_config_get_dhcp_client_id (s_ip4), + timeout, dhcp_anycast_addr, hostname, FALSE); } /* Caller owns a reference to the NMDHCPClient on return */ @@ -496,63 +483,42 @@ nm_dhcp_manager_start_ip6 (NMDHCPManager *self, const char *iface, const GByteArray *hwaddr, const char *uuid, + guint priority, NMSettingIP6Config *s_ip6, guint32 timeout, - guint8 *dhcp_anycast_addr, + GByteArray *dhcp_anycast_addr, gboolean info_only) { - NMDHCPManagerPrivate *priv; - const char *hostname = NULL; + const char *hostname; - g_return_val_if_fail (self, NULL); g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); - priv = NM_DHCP_MANAGER_GET_PRIVATE (self); - - if (s_ip6) - hostname = nm_setting_ip6_config_get_dhcp_hostname (s_ip6); - if (!hostname && priv->hostname_provider) { - hostname = nm_hostname_provider_get_hostname (priv->hostname_provider); - if ( g_strcmp0 (hostname, "localhost.localdomain") == 0 - || g_strcmp0 (hostname, "localhost6.localdomain6") == 0) - hostname = NULL; - } - - return client_start (self, iface, hwaddr, uuid, TRUE, NULL, s_ip6, timeout, dhcp_anycast_addr, hostname, info_only); -} + hostname = get_send_hostname (self, nm_setting_ip6_config_get_dhcp_hostname (s_ip6)); -static void -hostname_provider_destroyed (gpointer data, GObject *destroyed_object) -{ - NM_DHCP_MANAGER_GET_PRIVATE (data)->hostname_provider = NULL; + return client_start (self, iface, hwaddr, uuid, priority, TRUE, + NULL, timeout, dhcp_anycast_addr, hostname, info_only); } void -nm_dhcp_manager_set_hostname_provider (NMDHCPManager *manager, - NMHostnameProvider *provider) +nm_dhcp_manager_set_default_hostname (NMDHCPManager *manager, const char *hostname) { - NMDHCPManagerPrivate *priv; - - g_return_if_fail (NM_IS_DHCP_MANAGER (manager)); + NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (manager); - priv = NM_DHCP_MANAGER_GET_PRIVATE (manager); + g_clear_pointer (&priv->default_hostname, g_free); - if (priv->hostname_provider) { - g_object_weak_unref (G_OBJECT (priv->hostname_provider), hostname_provider_destroyed, manager); - priv->hostname_provider = NULL; - } + /* Never send 'localhost'-type names to the DHCP server */ + if (g_strcmp0 (hostname, "localhost.localdomain") == 0 || + g_strcmp0 (hostname, "localhost6.localdomain6") == 0) + return; - if (provider) { - priv->hostname_provider = provider; - g_object_weak_ref (G_OBJECT (provider), hostname_provider_destroyed, manager); - } + priv->default_hostname = g_strdup (hostname); } GSList * -nm_dhcp_manager_get_lease_config (NMDHCPManager *self, - const char *iface, - const char *uuid, - gboolean ipv6) +nm_dhcp_manager_get_lease_ip_configs (NMDHCPManager *self, + const char *iface, + const char *uuid, + gboolean ipv6) { NMDHCPManagerPrivate *priv; @@ -562,10 +528,8 @@ nm_dhcp_manager_get_lease_config (NMDHCPManager *self, priv = NM_DHCP_MANAGER_GET_PRIVATE (self); - if (priv->get_lease_config_func) - return priv->get_lease_config_func (iface, uuid, ipv6); - - nm_log_warn (LOGD_DHCP, "Cannot get a DHCP lease config (no usable DHCP client was found!)"); + if (priv->get_lease_ip_configs_func) + return priv->get_lease_ip_configs_func (iface, uuid, ipv6); return NULL; } @@ -603,13 +567,70 @@ nm_dhcp_manager_test_ip4_options_to_config (const char *dhcp_client, NMDHCPManager * nm_dhcp_manager_get (void) { - g_warn_if_fail (singleton != NULL); - return g_object_ref (singleton); + static NMDHCPManager *singleton = NULL; + + if (G_UNLIKELY (singleton == NULL)) + singleton = g_object_new (NM_TYPE_DHCP_MANAGER, NULL); + g_assert (singleton); + return singleton; } static void -nm_dhcp_manager_init (NMDHCPManager *manager) +nm_dhcp_manager_init (NMDHCPManager *self) { + NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self); + const char *client; + GError *error = NULL; +#if !HAVE_DBUS_GLIB_100 + DBusGConnection *g_connection; +#endif + + /* Maps DBusGConnection :: DBusGProxy */ + priv->proxies = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); + + /* Client-specific setup */ + client = nm_config_get_dhcp_client (nm_config_get ()); + priv->client_type = get_client_type (client, &error); + + if (priv->client_type == NM_TYPE_DHCP_DHCLIENT) + priv->get_lease_ip_configs_func = nm_dhcp_dhclient_get_lease_ip_configs; + else if (priv->client_type == G_TYPE_INVALID) { + nm_log_warn (LOGD_DHCP, "No usable DHCP client found (%s)! DHCP configurations will fail.", + error->message); + } + g_clear_error (&error); + + priv->clients = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, + (GDestroyNotify) g_object_unref); + g_assert (priv->clients); + + priv->dbus_mgr = nm_dbus_manager_get (); + +#if HAVE_DBUS_GLIB_100 + /* Register the socket our DHCP clients will return lease info on */ + nm_dbus_manager_private_server_register (priv->dbus_mgr, PRIV_SOCK_PATH, PRIV_SOCK_TAG); + priv->new_conn_id = g_signal_connect (priv->dbus_mgr, + NM_DBUS_MANAGER_PRIVATE_CONNECTION_NEW "::" PRIV_SOCK_TAG, + (GCallback) new_connection_cb, + self); + priv->dis_conn_id = g_signal_connect (priv->dbus_mgr, + NM_DBUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED "::" PRIV_SOCK_TAG, + (GCallback) dis_connection_cb, + self); +#else + g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); + priv->proxy = dbus_g_proxy_new_for_name (g_connection, + "org.freedesktop.nm_dhcp_client", + "/", + NM_DHCP_CLIENT_DBUS_IFACE); + g_assert (priv->proxy); + dbus_g_proxy_add_signal (priv->proxy, "Event", DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->proxy, "Event", + G_CALLBACK (nm_dhcp_manager_handle_event), + self, + NULL); +#endif } static void @@ -625,6 +646,23 @@ dispose (GObject *object) g_list_free (values); } + if (priv->new_conn_id) { + g_signal_handler_disconnect (priv->dbus_mgr, priv->new_conn_id); + priv->new_conn_id = 0; + } + if (priv->dis_conn_id) { + g_signal_handler_disconnect (priv->dbus_mgr, priv->dis_conn_id); + priv->dis_conn_id = 0; + } + priv->dbus_mgr = NULL; + + if (priv->proxies) { + g_hash_table_destroy (priv->proxies); + priv->proxies = NULL; + } + if (priv->proxy) + g_object_unref (priv->proxy); + G_OBJECT_CLASS (nm_dhcp_manager_parent_class)->dispose (object); } @@ -633,17 +671,10 @@ finalize (GObject *object) { NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (object); - if (priv->hostname_provider) { - g_object_weak_unref (G_OBJECT (priv->hostname_provider), hostname_provider_destroyed, object); - priv->hostname_provider = NULL; - } + g_free (priv->default_hostname); if (priv->clients) g_hash_table_destroy (priv->clients); - if (priv->proxy) - g_object_unref (priv->proxy); - if (priv->dbus_mgr) - g_object_unref (priv->dbus_mgr); G_OBJECT_CLASS (nm_dhcp_manager_parent_class)->finalize (object); } @@ -659,4 +690,3 @@ nm_dhcp_manager_class_init (NMDHCPManagerClass *manager_class) object_class->finalize = finalize; object_class->dispose = dispose; } - diff --git a/src/dhcp-manager/nm-dhcp-manager.h b/src/dhcp-manager/nm-dhcp-manager.h index a29a33fd..efdd4378 100644 --- a/src/dhcp-manager/nm-dhcp-manager.h +++ b/src/dhcp-manager/nm-dhcp-manager.h @@ -31,7 +31,6 @@ #include "nm-dhcp-client.h" #include "nm-ip4-config.h" #include "nm-dhcp4-config.h" -#include "nm-hostname-provider.h" typedef enum { NM_DHCP_MANAGER_ERROR_BAD_CLIENT = 0, /*< nick=BadClient >*/ @@ -60,32 +59,34 @@ typedef struct { GType nm_dhcp_manager_get_type (void); -NMDHCPManager *nm_dhcp_manager_get (void); +NMDHCPManager *nm_dhcp_manager_get (void); -void nm_dhcp_manager_set_hostname_provider(NMDHCPManager *manager, - NMHostnameProvider *provider); +void nm_dhcp_manager_set_default_hostname (NMDHCPManager *manager, + const char *hostname); NMDHCPClient * nm_dhcp_manager_start_ip4 (NMDHCPManager *manager, const char *iface, const GByteArray *hwaddr, const char *uuid, + guint priority, NMSettingIP4Config *s_ip4, guint32 timeout, - guint8 *dhcp_anycast_addr); + GByteArray *dhcp_anycast_addr); NMDHCPClient * nm_dhcp_manager_start_ip6 (NMDHCPManager *manager, const char *iface, const GByteArray *hwaddr, const char *uuid, + guint priority, NMSettingIP6Config *s_ip6, guint32 timeout, - guint8 *dhcp_anycast_addr, + GByteArray *dhcp_anycast_addr, gboolean info_only); -GSList * nm_dhcp_manager_get_lease_config (NMDHCPManager *self, - const char *iface, - const char *uuid, - gboolean ipv6); +GSList * nm_dhcp_manager_get_lease_ip_configs (NMDHCPManager *self, + const char *iface, + const char *uuid, + gboolean ipv6); /* For testing only */ NMIP4Config *nm_dhcp_manager_test_ip4_options_to_config (const char *dhcp_client, @@ -93,7 +94,6 @@ NMIP4Config *nm_dhcp_manager_test_ip4_options_to_config (const char *dhcp_client GHashTable *options, const char *reason); -/* Only for main.c */ -NMDHCPManager *nm_dhcp_manager_new (const char *client, GError **error); +extern const char* nm_dhcp_helper_path; #endif /* NM_DHCP_MANAGER_H */ diff --git a/src/dhcp-manager/tests/Makefile.am b/src/dhcp-manager/tests/Makefile.am index bf859fe7..6ef828d5 100644 --- a/src/dhcp-manager/tests/Makefile.am +++ b/src/dhcp-manager/tests/Makefile.am @@ -1,12 +1,15 @@ -if ENABLE_TESTS - AM_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_builddir)/include \ -I${top_srcdir}/libnm-util \ -I${top_builddir}/libnm-util \ -I$(top_srcdir)/src/dhcp-manager \ - $(GLIB_CFLAGS) + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/platform \ + -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(GLIB_CFLAGS) \ + -DTESTDIR="\"$(abs_srcdir)\"" noinst_PROGRAMS = test-dhcp-dhclient @@ -15,22 +18,16 @@ noinst_PROGRAMS = test-dhcp-dhclient test_dhcp_dhclient_SOURCES = \ test-dhcp-dhclient.c -test_dhcp_dhclient_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -DTESTDIR="\"$(abs_srcdir)\"" - test_dhcp_dhclient_LDADD = \ - -ldl \ - $(top_builddir)/src/dhcp-manager/libdhcp-dhclient.la \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(GLIB_LIBS) - -check-local: test-dhcp-dhclient - $(abs_builddir)/test-dhcp-dhclient + $(top_builddir)/src/libNetworkManager.la -endif +TESTS = test-dhcp-dhclient EXTRA_DIST = \ test-dhclient-duid.leases \ - test-dhclient-commented-duid.leases + test-dhclient-commented-duid.leases \ + leases/basic.leases \ + leases/malformed1.leases \ + leases/malformed2.leases \ + leases/malformed3.leases diff --git a/src/dhcp-manager/tests/Makefile.in b/src/dhcp-manager/tests/Makefile.in index afcee2c0..d445838f 100644 --- a/src/dhcp-manager/tests/Makefile.in +++ b/src/dhcp-manager/tests/Makefile.in @@ -78,12 +78,14 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@ENABLE_TESTS_TRUE@noinst_PROGRAMS = test-dhcp-dhclient$(EXEEXT) +noinst_PROGRAMS = test-dhcp-dhclient$(EXEEXT) +TESTS = test-dhcp-dhclient$(EXEEXT) subdir = src/dhcp-manager/tests DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/build-aux/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -102,13 +104,10 @@ CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) -am__test_dhcp_dhclient_SOURCES_DIST = test-dhcp-dhclient.c -@ENABLE_TESTS_TRUE@am_test_dhcp_dhclient_OBJECTS = test_dhcp_dhclient-test-dhcp-dhclient.$(OBJEXT) +am_test_dhcp_dhclient_OBJECTS = test-dhcp-dhclient.$(OBJEXT) test_dhcp_dhclient_OBJECTS = $(am_test_dhcp_dhclient_OBJECTS) -am__DEPENDENCIES_1 = -@ENABLE_TESTS_TRUE@test_dhcp_dhclient_DEPENDENCIES = $(top_builddir)/src/dhcp-manager/libdhcp-dhclient.la \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ -@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +test_dhcp_dhclient_DEPENDENCIES = \ + $(top_builddir)/src/libNetworkManager.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -148,7 +147,7 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(test_dhcp_dhclient_SOURCES) -DIST_SOURCES = $(am__test_dhcp_dhclient_SOURCES_DIST) +DIST_SOURCES = $(test_dhcp_dhclient_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -173,6 +172,28 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -199,12 +220,15 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIRNAME = @DATADIRNAME@ DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ DBUS_LIBS = @DBUS_LIBS@ DBUS_SYS_DIR = @DBUS_SYS_DIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ DNSMASQ_PATH = @DNSMASQ_PATH@ DSYMUTIL = @DSYMUTIL@ @@ -229,7 +253,6 @@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GTKDOC_CHECK = @GTKDOC_CHECK@ -GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ @@ -274,12 +297,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -296,6 +323,8 @@ MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ @@ -323,11 +352,16 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POLKIT_CFLAGS = @POLKIT_CFLAGS@ POLKIT_LIBS = @POLKIT_LIBS@ POSUB = @POSUB@ +PPPD_PATH = @PPPD_PATH@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -342,6 +376,7 @@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ VAPIGEN = @VAPIGEN@ VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ @@ -404,6 +439,7 @@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ +subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ target_alias = @target_alias@ @@ -414,32 +450,35 @@ with_dhclient = @with_dhclient@ with_dhcpcd = @with_dhcpcd@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ -@ENABLE_TESTS_TRUE@AM_CPPFLAGS = \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/include \ -@ENABLE_TESTS_TRUE@ -I$(top_builddir)/include \ -@ENABLE_TESTS_TRUE@ -I${top_srcdir}/libnm-util \ -@ENABLE_TESTS_TRUE@ -I${top_builddir}/libnm-util \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/dhcp-manager \ -@ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) +with_valgrind = @with_valgrind@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-util \ + -I$(top_srcdir)/src/dhcp-manager \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/platform \ + -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(GLIB_CFLAGS) \ + -DTESTDIR="\"$(abs_srcdir)\"" ####### policy /etc/hosts test ####### -@ENABLE_TESTS_TRUE@test_dhcp_dhclient_SOURCES = \ -@ENABLE_TESTS_TRUE@ test-dhcp-dhclient.c - -@ENABLE_TESTS_TRUE@test_dhcp_dhclient_CPPFLAGS = \ -@ENABLE_TESTS_TRUE@ $(AM_CPPFLAGS) \ -@ENABLE_TESTS_TRUE@ -DTESTDIR="\"$(abs_srcdir)\"" +test_dhcp_dhclient_SOURCES = \ + test-dhcp-dhclient.c -@ENABLE_TESTS_TRUE@test_dhcp_dhclient_LDADD = \ -@ENABLE_TESTS_TRUE@ -ldl \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/src/dhcp-manager/libdhcp-dhclient.la \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ -@ENABLE_TESTS_TRUE@ $(GLIB_LIBS) +test_dhcp_dhclient_LDADD = \ + $(top_builddir)/src/libNetworkManager.la EXTRA_DIST = \ test-dhclient-duid.leases \ - test-dhclient-commented-duid.leases + test-dhclient-commented-duid.leases \ + leases/basic.leases \ + leases/malformed1.leases \ + leases/malformed2.leases \ + leases/malformed3.leases all: all-am @@ -495,7 +534,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-dhcp-dhclient.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -518,20 +557,6 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -test_dhcp_dhclient-test-dhcp-dhclient.o: test-dhcp-dhclient.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dhcp_dhclient_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_dhcp_dhclient-test-dhcp-dhclient.o -MD -MP -MF $(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Tpo -c -o test_dhcp_dhclient-test-dhcp-dhclient.o `test -f 'test-dhcp-dhclient.c' || echo '$(srcdir)/'`test-dhcp-dhclient.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Tpo $(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-dhcp-dhclient.c' object='test_dhcp_dhclient-test-dhcp-dhclient.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dhcp_dhclient_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_dhcp_dhclient-test-dhcp-dhclient.o `test -f 'test-dhcp-dhclient.c' || echo '$(srcdir)/'`test-dhcp-dhclient.c - -test_dhcp_dhclient-test-dhcp-dhclient.obj: test-dhcp-dhclient.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dhcp_dhclient_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_dhcp_dhclient-test-dhcp-dhclient.obj -MD -MP -MF $(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Tpo -c -o test_dhcp_dhclient-test-dhcp-dhclient.obj `if test -f 'test-dhcp-dhclient.c'; then $(CYGPATH_W) 'test-dhcp-dhclient.c'; else $(CYGPATH_W) '$(srcdir)/test-dhcp-dhclient.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Tpo $(DEPDIR)/test_dhcp_dhclient-test-dhcp-dhclient.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-dhcp-dhclient.c' object='test_dhcp_dhclient-test-dhcp-dhclient.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dhcp_dhclient_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_dhcp_dhclient-test-dhcp-dhclient.obj `if test -f 'test-dhcp-dhclient.c'; then $(CYGPATH_W) 'test-dhcp-dhclient.c'; else $(CYGPATH_W) '$(srcdir)/test-dhcp-dhclient.c'; fi` - mostlyclean-libtool: -rm -f *.lo @@ -590,6 +615,99 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -620,9 +738,8 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done -@ENABLE_TESTS_FALSE@check-local: check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-local + $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(PROGRAMS) installdirs: @@ -729,7 +846,7 @@ uninstall-am: .MAKE: check-am install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am check-local clean \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ @@ -744,9 +861,6 @@ uninstall-am: tags tags-am uninstall uninstall-am -@ENABLE_TESTS_TRUE@check-local: test-dhcp-dhclient -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-dhcp-dhclient - # 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/dhcp-manager/tests/leases/basic.leases b/src/dhcp-manager/tests/leases/basic.leases new file mode 100644 index 00000000..703d9247 --- /dev/null +++ b/src/dhcp-manager/tests/leases/basic.leases @@ -0,0 +1,31 @@ +lease { + interface "wlan0"; + fixed-address 192.168.1.180; + option subnet-mask 255.255.255.0; + option routers 192.168.1.1; + option dhcp-lease-time 600; + option dhcp-message-type 5; + option domain-name-servers 192.168.1.1; + option dhcp-server-identifier 192.168.1.1; + option broadcast-address 192.168.1.255; + renew 5 2013/11/01 19:56:15; + rebind 5 2013/11/01 20:00:44; + expire 5 2013/11/01 20:01:59; +} +lease { + interface "wlan0"; + fixed-address 10.77.52.141; + option subnet-mask 255.0.0.0; + option dhcp-lease-time 1200; + option routers 10.77.52.254; + option dhcp-message-type 5; + option dhcp-server-identifier 10.77.52.254; + option domain-name-servers 8.8.8.8,8.8.4.4; + option dhcp-renewal-time 600; + option dhcp-rebinding-time 1050; + option domain-name "morriesguest.local"; + renew 5 2013/11/01 20:01:08; + rebind 5 2013/11/01 20:05:00; + expire 5 2013/11/01 20:06:15; +} + diff --git a/src/dhcp-manager/tests/leases/malformed1.leases b/src/dhcp-manager/tests/leases/malformed1.leases new file mode 100644 index 00000000..401d982a --- /dev/null +++ b/src/dhcp-manager/tests/leases/malformed1.leases @@ -0,0 +1,15 @@ +# missing fixed-address option +lease { + interface "wlan0"; + option subnet-mask 255.255.255.0; + option routers 192.168.1.1; + option dhcp-lease-time 600; + option dhcp-message-type 5; + option domain-name-servers 192.168.1.1; + option dhcp-server-identifier 192.168.1.1; + option broadcast-address 192.168.1.255; + renew 5 2013/11/01 19:56:15; + rebind 5 2013/11/01 20:00:44; + expire 5 2013/11/01 20:01:59; +} + diff --git a/src/dhcp-manager/tests/leases/malformed2.leases b/src/dhcp-manager/tests/leases/malformed2.leases new file mode 100644 index 00000000..adf5f6de --- /dev/null +++ b/src/dhcp-manager/tests/leases/malformed2.leases @@ -0,0 +1,15 @@ +# missing routers option +lease { + interface "wlan0"; + fixed-address 192.168.1.180; + option subnet-mask 255.255.255.0; + option dhcp-lease-time 600; + option dhcp-message-type 5; + option domain-name-servers 192.168.1.1; + option dhcp-server-identifier 192.168.1.1; + option broadcast-address 192.168.1.255; + renew 5 2013/11/01 19:56:15; + rebind 5 2013/11/01 20:00:44; + expire 5 2013/11/01 20:01:59; +} + diff --git a/src/dhcp-manager/tests/leases/malformed3.leases b/src/dhcp-manager/tests/leases/malformed3.leases new file mode 100644 index 00000000..a2afc8b6 --- /dev/null +++ b/src/dhcp-manager/tests/leases/malformed3.leases @@ -0,0 +1,15 @@ +# missing expire time +lease { + interface "wlan0"; + fixed-address 192.168.1.180; + option subnet-mask 255.255.255.0; + option routers 192.168.1.1; + option dhcp-lease-time 600; + option dhcp-message-type 5; + option domain-name-servers 192.168.1.1; + option dhcp-server-identifier 192.168.1.1; + option broadcast-address 192.168.1.255; + renew 5 2013/11/01 19:56:15; + rebind 5 2013/11/01 20:00:44; +} + diff --git a/src/dhcp-manager/tests/test-dhcp-dhclient.c b/src/dhcp-manager/tests/test-dhcp-dhclient.c index 3f34c6e0..1ab182a7 100644 --- a/src/dhcp-manager/tests/test-dhcp-dhclient.c +++ b/src/dhcp-manager/tests/test-dhcp-dhclient.c @@ -24,6 +24,7 @@ #include "nm-dhcp-dhclient-utils.h" #include "nm-utils.h" +#include "nm-ip4-config.h" #define DEBUG 0 @@ -33,18 +34,13 @@ test_config (const char *orig, const char *hostname, const char *dhcp_client_id, const char *iface, - guint8 *anycast_addr) + GByteArray *anycast_addr) { - NMSettingIP4Config *s_ip4; char *new; - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, dhcp_client_id, NULL); - new = nm_dhcp_dhclient_create_config (iface, FALSE, - s_ip4, - NULL, + dhcp_client_id, anycast_addr, hostname, "/path/to/dhclient.conf", @@ -127,6 +123,62 @@ test_override_client_id (void) /*******************************************/ +static const char *quote_client_id_expected = \ + "# Created by NetworkManager\n" + "\n" + "send dhcp-client-identifier \"1234\"; # added by NetworkManager\n" + "\n" + "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" + "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" + "option wpad code 252 = string;\n" + "\n" + "also request rfc3442-classless-static-routes;\n" + "also request ms-classless-static-routes;\n" + "also request static-routes;\n" + "also request wpad;\n" + "also request ntp-servers;\n" + "\n"; + +static void +test_quote_client_id (void) +{ + test_config (NULL, quote_client_id_expected, + NULL, + "1234", + "eth0", + NULL); +} + +/*******************************************/ + +static const char *ascii_client_id_expected = \ + "# Created by NetworkManager\n" + "\n" + "send dhcp-client-identifier \"qb:cd:ef:12:34:56\"; # added by NetworkManager\n" + "\n" + "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" + "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" + "option wpad code 252 = string;\n" + "\n" + "also request rfc3442-classless-static-routes;\n" + "also request ms-classless-static-routes;\n" + "also request static-routes;\n" + "also request wpad;\n" + "also request ntp-servers;\n" + "\n"; + +static void +test_ascii_client_id (void) +{ + test_config (NULL, ascii_client_id_expected, + NULL, + "qb:cd:ef:12:34:56", + "eth0", + NULL); +} + +/*******************************************/ + static const char *override_hostname_orig = \ "send host-name \"foobar\";\n"; @@ -398,37 +450,164 @@ test_write_existing_commented_duid (void) /*******************************************/ -#if GLIB_CHECK_VERSION(2,25,12) -typedef GTestFixtureFunc TCFunc; -#else -typedef void (*TCFunc)(void); -#endif +static void +test_read_lease_ip4_config_basic (void) +{ + GError *error = NULL; + char *contents = NULL; + gboolean success; + const char *path = TESTDIR "/leases/basic.leases"; + GSList *leases; + GDateTime *now; + NMIP4Config *config; + const NMPlatformIP4Address *addr; + guint32 expected_addr; + + success = g_file_get_contents (path, &contents, NULL, &error); + g_assert_no_error (error); + g_assert (success); -#define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (TCFunc) t, NULL) + /* Date from before the least expiration */ + now = g_date_time_new_utc (2013, 11, 1, 19, 55, 32); + leases = nm_dhcp_dhclient_read_lease_ip_configs ("wlan0", contents, FALSE, now); + g_assert_cmpint (g_slist_length (leases), ==, 2); + + /* IP4Config #1 */ + config = g_slist_nth_data (leases, 0); + g_assert (NM_IS_IP4_CONFIG (config)); + + /* Address */ + g_assert_cmpint (nm_ip4_config_get_num_addresses (config), ==, 1); + g_assert (inet_aton ("192.168.1.180", (struct in_addr *) &expected_addr)); + addr = nm_ip4_config_get_address (config, 0); + g_assert_cmpint (addr->address, ==, expected_addr); + g_assert_cmpint (addr->plen, ==, 24); + + /* Gateway */ + g_assert (inet_aton ("192.168.1.1", (struct in_addr *) &expected_addr)); + g_assert_cmpint (nm_ip4_config_get_gateway (config), ==, expected_addr); + + /* DNS */ + g_assert_cmpint (nm_ip4_config_get_num_nameservers (config), ==, 1); + g_assert (inet_aton ("192.168.1.1", (struct in_addr *) &expected_addr)); + g_assert_cmpint (nm_ip4_config_get_nameserver (config, 0), ==, expected_addr); + + g_assert_cmpint (nm_ip4_config_get_num_domains (config), ==, 0); + + /* IP4Config #2 */ + config = g_slist_nth_data (leases, 1); + g_assert (NM_IS_IP4_CONFIG (config)); + + /* Address */ + g_assert_cmpint (nm_ip4_config_get_num_addresses (config), ==, 1); + g_assert (inet_aton ("10.77.52.141", (struct in_addr *) &expected_addr)); + addr = nm_ip4_config_get_address (config, 0); + g_assert_cmpint (addr->address, ==, expected_addr); + g_assert_cmpint (addr->plen, ==, 8); + + /* Gateway */ + g_assert (inet_aton ("10.77.52.254", (struct in_addr *) &expected_addr)); + g_assert_cmpint (nm_ip4_config_get_gateway (config), ==, expected_addr); + + /* DNS */ + g_assert_cmpint (nm_ip4_config_get_num_nameservers (config), ==, 2); + g_assert (inet_aton ("8.8.8.8", (struct in_addr *) &expected_addr)); + g_assert_cmpint (nm_ip4_config_get_nameserver (config, 0), ==, expected_addr); + g_assert (inet_aton ("8.8.4.4", (struct in_addr *) &expected_addr)); + g_assert_cmpint (nm_ip4_config_get_nameserver (config, 1), ==, expected_addr); + + /* Domains */ + g_assert_cmpint (nm_ip4_config_get_num_domains (config), ==, 1); + g_assert_cmpstr (nm_ip4_config_get_domain (config, 0), ==, "morriesguest.local"); + + g_slist_free_full (leases, g_object_unref); + g_date_time_unref (now); + g_free (contents); +} -int main (int argc, char **argv) +static void +test_read_lease_ip4_config_expired (void) { - GTestSuite *suite; + GError *error = NULL; + char *contents = NULL; + gboolean success; + const char *path = TESTDIR "/leases/basic.leases"; + GSList *leases; + GDateTime *now; - g_test_init (&argc, &argv, NULL); + success = g_file_get_contents (path, &contents, NULL, &error); + g_assert_no_error (error); + g_assert (success); - g_type_init (); + /* Date from *after* the lease expiration */ + now = g_date_time_new_utc (2013, 12, 1, 19, 55, 32); + leases = nm_dhcp_dhclient_read_lease_ip_configs ("wlan0", contents, FALSE, now); + g_assert (leases == NULL); + + g_date_time_unref (now); + g_free (contents); +} + +static void +test_read_lease_ip4_config_expect_failure (gconstpointer user_data) +{ + GError *error = NULL; + char *contents = NULL; + gboolean success; + GSList *leases; + GDateTime *now; + + success = g_file_get_contents ((const char *) user_data, &contents, NULL, &error); + g_assert_no_error (error); + g_assert (success); + + /* Date from before the least expiration */ + now = g_date_time_new_utc (2013, 11, 1, 1, 1, 1); + leases = nm_dhcp_dhclient_read_lease_ip_configs ("wlan0", contents, FALSE, now); + g_assert (leases == NULL); - suite = g_test_get_root (); + g_date_time_unref (now); + g_free (contents); +} - g_test_suite_add (suite, TESTCASE (test_orig_missing, NULL)); - g_test_suite_add (suite, TESTCASE (test_override_client_id, NULL)); - g_test_suite_add (suite, TESTCASE (test_override_hostname, NULL)); - g_test_suite_add (suite, TESTCASE (test_existing_alsoreq, NULL)); - g_test_suite_add (suite, TESTCASE (test_existing_multiline_alsoreq, NULL)); - g_test_suite_add (suite, TESTCASE (test_duids, NULL)); +/*******************************************/ - g_test_suite_add (suite, TESTCASE (test_read_duid_from_leasefile, NULL)); - g_test_suite_add (suite, TESTCASE (test_read_commented_duid_from_leasefile, NULL)); +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + +#if !GLIB_CHECK_VERSION (2, 35, 0) + g_type_init (); +#endif - g_test_suite_add (suite, TESTCASE (test_write_duid, NULL)); - g_test_suite_add (suite, TESTCASE (test_write_existing_duid, NULL)); - g_test_suite_add (suite, TESTCASE (test_write_existing_commented_duid, NULL)); + g_test_add_func ("/dhcp/dhclient/orig_missing", test_orig_missing); + g_test_add_func ("/dhcp/dhclient/override_client_id", test_override_client_id); + g_test_add_func ("/dhcp/dhclient/quote_client_id", test_quote_client_id); + g_test_add_func ("/dhcp/dhclient/ascii_client_id", test_ascii_client_id); + g_test_add_func ("/dhcp/dhclient/override_hostname", test_override_hostname); + g_test_add_func ("/dhcp/dhclient/existing_alsoreq", test_existing_alsoreq); + g_test_add_func ("/dhcp/dhclient/existing_multiline_alsoreq", test_existing_multiline_alsoreq); + g_test_add_func ("/dhcp/dhclient/duids", test_duids); + + g_test_add_func ("/dhcp/dhclient/read_duid_from_leasefile", test_read_duid_from_leasefile); + g_test_add_func ("/dhcp/dhclient/read_commented_duid_from_leasefile", test_read_commented_duid_from_leasefile); + + g_test_add_func ("/dhcp/dhclient/write_duid", test_write_duid); + g_test_add_func ("/dhcp/dhclient/write_existing_duid", test_write_existing_duid); + g_test_add_func ("/dhcp/dhclient/write_existing_commented_duid", test_write_existing_commented_duid); + + g_test_add_func ("/dhcp/dhclient/leases/ip4-config/basic", test_read_lease_ip4_config_basic); + g_test_add_func ("/dhcp/dhclient/leases/ip4-config/expired", test_read_lease_ip4_config_expired); + g_test_add_data_func ("/dhcp/dhclient/leases/ip4-config/missing-address", + TESTDIR "/leases/malformed1.leases", + test_read_lease_ip4_config_expect_failure); + g_test_add_data_func ("/dhcp/dhclient/leases/ip4-config/missing-gateway", + TESTDIR "/leases/malformed2.leases", + test_read_lease_ip4_config_expect_failure); + g_test_add_data_func ("/dhcp/dhclient/leases/ip4-config/missing-expire", + TESTDIR "/leases/malformed3.leases", + test_read_lease_ip4_config_expect_failure); return g_test_run (); } |