Module Name: src Committed By: martin Date: Thu Sep 5 08:56:55 UTC 2019
Modified Files: src/external/bsd/dhcpcd/dist [netbsd-9]: BUILDING.md Makefile Makefile.inc configure src/external/bsd/dhcpcd/dist/compat [netbsd-9]: rb.c rbtree.h src/external/bsd/dhcpcd/dist/hooks [netbsd-9]: Makefile src/external/bsd/dhcpcd/dist/src [netbsd-9]: Makefile bpf.c control.c control.h defs.h dhcp-common.c dhcp.c dhcp6.c dhcpcd.8.in dhcpcd.c dhcpcd.conf.5.in duid.c if-bsd.c if-linux.c if-options.c if-options.h if-sun.c if.c if.h ipv4.c ipv4.h ipv6.c ipv6.h ipv6nd.c ipv6nd.h route.c route.h sa.c script.c Log Message: Catch up to current for the following files, requested by roy in ticket #177: external/bsd/dhcpcd/dist/BUILDING.md up to 1.1.1.5 external/bsd/dhcpcd/dist/Makefile up to 1.1.1.7 external/bsd/dhcpcd/dist/Makefile.inc up to 1.1.1.3 external/bsd/dhcpcd/dist/configure up to 1.1.1.15 external/bsd/dhcpcd/dist/compat/rb.c up to 1.1.1.2 external/bsd/dhcpcd/dist/compat/rbtree.h up to 1.1.1.2 external/bsd/dhcpcd/dist/hooks/Makefile up to 1.1.1.2 external/bsd/dhcpcd/dist/src/Makefile up to 1.1.1.6 external/bsd/dhcpcd/dist/src/bpf.c up to 1.12 external/bsd/dhcpcd/dist/src/control.c up to 1.1.1.8 external/bsd/dhcpcd/dist/src/control.h up to 1.1.1.5 external/bsd/dhcpcd/dist/src/defs.h up to 1.1.1.27 external/bsd/dhcpcd/dist/src/dhcp-common.c up to 1.1.1.8 external/bsd/dhcpcd/dist/src/dhcp.c up to 1.25 external/bsd/dhcpcd/dist/src/dhcp6.c up to 1.12 external/bsd/dhcpcd/dist/src/dhcpcd.8.in up to 1.3 external/bsd/dhcpcd/dist/src/dhcpcd.c up to 1.25 external/bsd/dhcpcd/dist/src/dhcpcd.conf.5.in up to 1.1.1.14 external/bsd/dhcpcd/dist/src/duid.c up to 1.1.1.7 external/bsd/dhcpcd/dist/src/if-bsd.c up to 1.12 external/bsd/dhcpcd/dist/src/if-linux.c up to 1.1.1.16 external/bsd/dhcpcd/dist/src/if-options.c up to 1.17 external/bsd/dhcpcd/dist/src/if-options.h up to 1.1.1.11 external/bsd/dhcpcd/dist/src/if-sun.c up to 1.1.1.11 external/bsd/dhcpcd/dist/src/if.c up to 1.1.1.16 external/bsd/dhcpcd/dist/src/if.h up to 1.1.1.11 external/bsd/dhcpcd/dist/src/ipv4.c up to 1.1.1.17 external/bsd/dhcpcd/dist/src/ipv4.h up to 1.1.1.10 external/bsd/dhcpcd/dist/src/ipv6.c up to 1.4 external/bsd/dhcpcd/dist/src/ipv6.h up to 1.5 external/bsd/dhcpcd/dist/src/ipv6nd.c up to 1.11 external/bsd/dhcpcd/dist/src/ipv6nd.h up to 1.1.1.11 external/bsd/dhcpcd/dist/src/route.c up to 1.1.1.14 external/bsd/dhcpcd/dist/src/route.h up to 1.1.1.9 external/bsd/dhcpcd/dist/src/sa.c up to 1.1.1.6 external/bsd/dhcpcd/dist/src/script.c up to 1.1.1.11 Import dhcpcd-8.0.4 with the following changes: * BSD: Fixed router reachability tests * inet6: If router unreachable, just solicit a new one * inet6: Fon't install a default route if only lladdresses * inet6: Stop listening to NA messages * BSD: Listen to RTM_MISS messages * DHCP: Fix in_cksum for Big Endian * DHCP{,6}: Don't log an error if the lease file is truncated Changes in dhcpcd-8.0.3: * DHCP: Work with IP headers with options * script: Assert that env string are correctly terminated * script: Terminate env strings with no value * script: Don't attempt to use an invalid env string * route: Fix NULL deference error when using static routes * ARP: Respect IFF_NOARP * DHCP: Allow full DHCP support for PtP interfaces, but not by default * control: sends correct buffer to listeners dhcpcd-ui now correctly reports SSD association and all the addresses obtained (regression from dhcpcd-7) To generate a diff of this commit: cvs rdiff -u -r1.1.1.4 -r1.1.1.4.2.1 src/external/bsd/dhcpcd/dist/BUILDING.md cvs rdiff -u -r1.1.1.6 -r1.1.1.6.2.1 src/external/bsd/dhcpcd/dist/Makefile cvs rdiff -u -r1.1.1.2 -r1.1.1.2.8.1 \ src/external/bsd/dhcpcd/dist/Makefile.inc cvs rdiff -u -r1.1.1.14 -r1.1.1.14.2.1 src/external/bsd/dhcpcd/dist/configure cvs rdiff -u -r1.1.1.1 -r1.1.1.1.2.1 src/external/bsd/dhcpcd/dist/compat/rb.c \ src/external/bsd/dhcpcd/dist/compat/rbtree.h cvs rdiff -u -r1.1.1.1 -r1.1.1.1.20.1 \ src/external/bsd/dhcpcd/dist/hooks/Makefile cvs rdiff -u -r1.1.1.5 -r1.1.1.5.2.1 \ src/external/bsd/dhcpcd/dist/src/Makefile \ src/external/bsd/dhcpcd/dist/src/sa.c cvs rdiff -u -r1.11 -r1.11.2.1 src/external/bsd/dhcpcd/dist/src/bpf.c \ src/external/bsd/dhcpcd/dist/src/dhcp6.c cvs rdiff -u -r1.1.1.6 -r1.1.1.6.2.1 \ src/external/bsd/dhcpcd/dist/src/control.c \ src/external/bsd/dhcpcd/dist/src/dhcp-common.c \ src/external/bsd/dhcpcd/dist/src/duid.c cvs rdiff -u -r1.1.1.4 -r1.1.1.4.2.1 \ src/external/bsd/dhcpcd/dist/src/control.h cvs rdiff -u -r1.1.1.25 -r1.1.1.25.2.1 \ src/external/bsd/dhcpcd/dist/src/defs.h cvs rdiff -u -r1.23 -r1.23.2.1 src/external/bsd/dhcpcd/dist/src/dhcp.c \ src/external/bsd/dhcpcd/dist/src/dhcpcd.c cvs rdiff -u -r1.2 -r1.2.2.1 src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in cvs rdiff -u -r1.1.1.13 -r1.1.1.13.2.1 \ src/external/bsd/dhcpcd/dist/src/dhcpcd.conf.5.in cvs rdiff -u -r1.10 -r1.10.2.1 src/external/bsd/dhcpcd/dist/src/if-bsd.c \ src/external/bsd/dhcpcd/dist/src/ipv6nd.c cvs rdiff -u -r1.1.1.14 -r1.1.1.14.2.1 \ src/external/bsd/dhcpcd/dist/src/if-linux.c \ src/external/bsd/dhcpcd/dist/src/if.c cvs rdiff -u -r1.16 -r1.16.2.1 src/external/bsd/dhcpcd/dist/src/if-options.c cvs rdiff -u -r1.1.1.9 -r1.1.1.9.2.1 \ src/external/bsd/dhcpcd/dist/src/if-options.h \ src/external/bsd/dhcpcd/dist/src/ipv4.h cvs rdiff -u -r1.1.1.10 -r1.1.1.10.2.1 \ src/external/bsd/dhcpcd/dist/src/if-sun.c \ src/external/bsd/dhcpcd/dist/src/if.h \ src/external/bsd/dhcpcd/dist/src/ipv6nd.h \ src/external/bsd/dhcpcd/dist/src/script.c cvs rdiff -u -r1.1.1.16 -r1.1.1.16.2.1 \ src/external/bsd/dhcpcd/dist/src/ipv4.c cvs rdiff -u -r1.3 -r1.3.2.1 src/external/bsd/dhcpcd/dist/src/ipv6.c \ src/external/bsd/dhcpcd/dist/src/ipv6.h cvs rdiff -u -r1.1.1.12 -r1.1.1.12.2.1 \ src/external/bsd/dhcpcd/dist/src/route.c cvs rdiff -u -r1.1.1.7 -r1.1.1.7.2.1 src/external/bsd/dhcpcd/dist/src/route.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/bsd/dhcpcd/dist/BUILDING.md diff -u src/external/bsd/dhcpcd/dist/BUILDING.md:1.1.1.4 src/external/bsd/dhcpcd/dist/BUILDING.md:1.1.1.4.2.1 --- src/external/bsd/dhcpcd/dist/BUILDING.md:1.1.1.4 Tue Jul 30 10:23:01 2019 +++ src/external/bsd/dhcpcd/dist/BUILDING.md Thu Sep 5 08:56:55 2019 @@ -134,9 +134,13 @@ You can decide which polling mechanism d ## Importing into another source control system -To prepare dhcpcd for import into a platform source tree (like NetBSD) -you can use the make import target to create /tmp/dhcpcd-$version and -populate it with all the source files and hooks needed. +To import the full sources, use the import target. +To import only the needed sources and documentation, use the import-src +target. +Both targets support DESTDIR to set the installation directory, +if unset it defaults to `/tmp/dhcpcd-$VERSION` +Example: `make DESTDIR=/usr/src/contrib/dhcpcd import-src` + In this instance, you may wish to disable some configured tests when the binary has to run on older versions which lack support, such as getline. `./configure --without-getline` Index: src/external/bsd/dhcpcd/dist/Makefile diff -u src/external/bsd/dhcpcd/dist/Makefile:1.1.1.6 src/external/bsd/dhcpcd/dist/Makefile:1.1.1.6.2.1 --- src/external/bsd/dhcpcd/dist/Makefile:1.1.1.6 Wed Apr 17 23:33:08 2019 +++ src/external/bsd/dhcpcd/dist/Makefile Thu Sep 5 08:56:55 2019 @@ -2,8 +2,7 @@ SUBDIRS= src hooks VERSION!= sed -n 's/\#define VERSION[[:space:]]*"\(.*\)".*/\1/p' src/defs.h -DIST!= if test -f .fslckout; then echo "dist-fossil"; \ - elif test -d .git; then echo "dist-git"; \ +DIST!= if test -d .git; then echo "dist-git"; \ else echo "dist-inst"; fi FOSSILID?= current GITREF?= HEAD @@ -52,12 +51,6 @@ distclean: clean rm -f config.h config.mk config.log \ ${DISTFILE} ${DISTFILEGZ} ${DISTINFO} ${DISTINFOSIGN} - -dist-fossil: - fossil tarball --name ${DISTPREFIX} ${FOSSILID} ${DISTFILEGZ} - gunzip -c ${DISTFILEGZ} | xz >${DISTFILE} - rm ${DISTFILEGZ} - dist-git: git archive --prefix=${DISTPREFIX}/ ${GITREF} | xz >${DISTFILE} @@ -86,9 +79,28 @@ snapshot: tar cf - -C /tmp ${DISTPREFIX} | xz >${DISTFILE} ls -l ${DISTFILE} -import: dist - rm -rf /tmp/${DISTPREFIX} - ${INSTALL} -d /tmp/${DISTPREFIX} - tar xvJpf ${DISTFILE} -C /tmp +_import: dist + rm -rf ${DESTDIR}/* + ${INSTALL} -d ${DESTDIR} + tar xvpf ${DISTFILE} -C ${DESTDIR} --strip 1 + @${ECHO} + @${ECHO} "=============================================================" + @${ECHO} "dhcpcd-${VERSION} imported to ${DESTDIR}" + +import: + ${MAKE} _import DESTDIR=`if [ -n "${DESTDIR}" ]; then echo "${DESTDIR}"; else echo /tmp/${DISTPREFIX}; fi` + + +_import-src: + rm -rf ${DESTDIR}/* + ${INSTALL} -d ${DESTDIR} + cp LICENSE README.md ${DESTDIR}; + for x in ${SUBDIRS}; do cd $$x; ${MAKE} DESTDIR=${DESTDIR} $@ || exit $$?; cd ..; done + @${ECHO} + @${ECHO} "=============================================================" + @${ECHO} "dhcpcd-${VERSION} imported to ${DESTDIR}" + +import-src: + ${MAKE} _import-src DESTDIR=`if [ -n "${DESTDIR}" ]; then echo "${DESTDIR}"; else echo /tmp/${DISTPREFIX}; fi` include Makefile.inc Index: src/external/bsd/dhcpcd/dist/Makefile.inc diff -u src/external/bsd/dhcpcd/dist/Makefile.inc:1.1.1.2 src/external/bsd/dhcpcd/dist/Makefile.inc:1.1.1.2.8.1 --- src/external/bsd/dhcpcd/dist/Makefile.inc:1.1.1.2 Tue Sep 19 19:16:48 2017 +++ src/external/bsd/dhcpcd/dist/Makefile.inc Thu Sep 5 08:56:55 2019 @@ -8,6 +8,7 @@ MANMODE?= ${NONBINMODE} CONFMODE?= 0644 CC?= cc +ECHO?= echo INSTALL?= install LINT?= lint SED?= sed Index: src/external/bsd/dhcpcd/dist/configure diff -u src/external/bsd/dhcpcd/dist/configure:1.1.1.14 src/external/bsd/dhcpcd/dist/configure:1.1.1.14.2.1 --- src/external/bsd/dhcpcd/dist/configure:1.1.1.14 Tue Jul 30 10:23:02 2019 +++ src/external/bsd/dhcpcd/dist/configure Thu Sep 5 08:56:55 2019 @@ -179,25 +179,6 @@ done : ${WC:=wc} : ${FORK:=yes} -: ${SYSCONFDIR:=$PREFIX/etc} -: ${SBINDIR:=$PREFIX/sbin} -: ${LIBDIR:=$PREFIX/lib} -: ${LIBEXECDIR:=$PREFIX/libexec} -: ${STATEDIR:=/var} -: ${DBDIR:=$STATEDIR/db/dhcpcd} -: ${RUNDIR:=$STATEDIR/run} -: ${MANDIR:=${PREFIX:-/usr}/share/man} -: ${DATADIR:=${PREFIX:-/usr}/share} - -eval SYSCONFDIR="$SYSCONFDIR" -eval LIBDIR="$LIBDIR" -eval LIBEXECDIR="$LIBEXECDIR" -eval STATEDIR="$STATEDIR" -eval DBDIR="$DBDIR" -eval RUNDIR="$RUNDIR" -eval MANDIR="$MANDIR" -eval DATADIR="$DATADIR" - _which() { x="$(which "$1" 2>/dev/null)" @@ -252,6 +233,10 @@ if [ -z "$OS" ]; then esac # Special case case "$OS" in + dragonfly*) + # This means /usr HAS to be mounted not via dhcpcd + : ${LIBEXECDIR:=${PREFIX:-/usr}/libexec} + ;; gnu*) OS=hurd;; # No HURD support as yet esac fi @@ -261,6 +246,26 @@ rm -f $CONFIG_H $CONFIG_MK echo "# $OS" >$CONFIG_MK echo "/* $OS */" >$CONFIG_H +: ${SYSCONFDIR:=$PREFIX/etc} +: ${SBINDIR:=$PREFIX/sbin} +: ${LIBDIR:=$PREFIX/lib} +: ${LIBEXECDIR:=$PREFIX/libexec} +: ${STATEDIR:=/var} +: ${DBDIR:=$STATEDIR/db/dhcpcd} +: ${RUNDIR:=$STATEDIR/run} +: ${MANDIR:=${PREFIX:-/usr}/share/man} +: ${DATADIR:=${PREFIX:-/usr}/share} + +eval SYSCONFDIR="$SYSCONFDIR" +eval LIBDIR="$LIBDIR" +eval LIBEXECDIR="$LIBEXECDIR" +eval STATEDIR="$STATEDIR" +eval DBDIR="$DBDIR" +eval RUNDIR="$RUNDIR" +eval MANDIR="$MANDIR" +eval DATADIR="$DATADIR" + +echo "#ifndef SYSCONFDIR" >>$CONFIG_H for x in SYSCONFDIR SBINDIR LIBDIR LIBEXECDIR DBDIR RUNDIR; do eval v=\$$x # Make files look nice for import @@ -272,6 +277,8 @@ for x in SYSCONFDIR SBINDIR LIBDIR LIBEX [ $l -gt 2 ] && t=" " echo "#define $x$t \"$v\"" >>$CONFIG_H done +echo "#endif" >>$CONFIG_H + echo "LIBDIR= $LIBDIR" >>$CONFIG_MK echo "MANDIR= $MANDIR" >>$CONFIG_MK echo "DATADIR= $DATADIR" >>$CONFIG_MK @@ -452,8 +459,6 @@ qnx*) echo "DHCPCD_SRCS+= if-bsd.c" >>$CONFIG_MK ;; sunos*) - echo "WARNING!!! Solaris support is at early development stage!" >&2 - echo "so don't expect it to work just yet, patches welcome" >&2 echo "CPPFLAGS+= -D_XPG4_2 -D__EXTENSIONS__ -DBSD_COMP" \ >>$CONFIG_MK echo "DHCPCD_SRCS+= if-sun.c" >>$CONFIG_MK @@ -497,10 +502,6 @@ if [ -z "$AUTH" -o "$AUTH" = yes ]; then echo "Enabling Authentication" echo "CPPFLAGS+= -DAUTH" >>$CONFIG_MK echo "SRCS+= auth.c" >>$CONFIG_MK - echo "CRYPT_SRCS+= \${HMAC_SRC}" >>$CONFIG_MK -fi -if [ -z "$INET6" -o "$INET6" = yes -o -z "$AUTH" -o "$AUTH" = yes ]; then - echo "CRYPT_SRCS+= \${MD5_SRC} \${SHA256_SRC}" >>$CONFIG_MK fi echo "Using compiler .. $CC" @@ -931,6 +932,30 @@ EOF echo "$TAILQ_FOREACH_SAFE" rm -f _queue.c _queue fi +if [ "$TAILQ_FOREACH_SAFE" = no ] && [ -z "$TAILQ_FOREACH_MUTABLE" ]; then + printf "Testing for TAILQ_FOREACH_MUTABLE ... " + cat <<EOF >_queue.c +#include <sys/queue.h> +int main(void) { +#ifndef TAILQ_FOREACH_MUTABLE +#error TAILQ_FOREACH_MUTABLE +#endif + return 0; +} +EOF + if $XCC _queue.c -o _queue 2>&3; then + TAILQ_FOREACH_MUTABLE=yes + TAILQ_FOREACH_SAFE=yes + TAILQ_FOREACH=yes + echo "#define TAILQ_FOREACH_SAFE TAILQ_FOREACH_MUTABLE" \ + >> $CONFIG_H + else + TAILQ_FOREACH_MUTABLE=no + fi + echo "$TAILQ_FOREACH_MUTABLE" + rm -f _queue.c _queue +fi + if [ -z "$TAILQ_CONCAT" ]; then printf "Testing for TAILQ_CONCAT ..." @@ -1007,7 +1032,7 @@ EOF rm -f _rbtree.c _rbtree fi if [ "$RBTREE" = no ]; then - echo "CPPFLAGS+= -DRBTEST" >>$CONFIG_MK + echo "#define RBTEST" >>$CONFIG_H echo "COMPAT_SRCS+= compat/rb.c" >>$CONFIG_MK echo "#include \"compat/rbtree.h\"" >>$CONFIG_H else @@ -1186,6 +1211,14 @@ if [ "$FLS64" = yes ]; then echo "#define HAVE_SYS_BITOPS_H" >>$CONFIG_H fi +# Workaround for DragonFlyBSD import +if [ "$OS" = dragonfly ]; then + echo "#ifdef USE_PRIVATECRYPTO" >>$CONFIG_H + echo "#define HAVE_MD5_H" >>$CONFIG_H + echo "#define SHA2_H <sha256.h>" >>$CONFIG_H + echo "#else" >>$CONFIG_H +fi + if [ -z "$MD5" ]; then MD5_LIB= printf "Testing for MD5Init ... " @@ -1322,6 +1355,9 @@ else [ -n "$SHA2_LIB" ] && echo "LDADD+= $SHA2_LIB" >>$CONFIG_MK fi +# Workarond for DragonFlyBSD import +[ "$OS" = dragonfly ] && echo "#endif" >>$CONFIG_H + if [ -z "$HMAC" ]; then HMAC_LIB= printf "Testing for hmac ... " @@ -1363,6 +1399,21 @@ else echo "HMAC_SRC=" >>$CONFIG_MK fi +if [ -z "$AUTH" ] || [ "$AUTH" = yes ]; then + if [ "$HMAC" = no ]; then + echo "CRYPT_SRCS+= \${HMAC_SRC}" >>$CONFIG_MK + fi +fi +if [ -z "$INET6" ] || [ "$INET6" = yes ] || \ + [ -z "$AUTH" ] || [ "$AUTH" = yes ]; then + if [ "$MD5" = no ]; then + echo "CRYPT_SRCS+= \${MD5_SRC}" >>$CONFIG_MK + fi + if [ "$SHA2" = no ]; then + echo "CRYPT_SRCS+= \${SHA256_SRC}" >>$CONFIG_MK + fi +fi + if [ "$DEV" != no -a "$UDEV" != no ]; then printf "Checking for libudev ... " if type "$PKG_CONFIG" >/dev/null 2>&1; then Index: src/external/bsd/dhcpcd/dist/compat/rb.c diff -u src/external/bsd/dhcpcd/dist/compat/rb.c:1.1.1.1 src/external/bsd/dhcpcd/dist/compat/rb.c:1.1.1.1.2.1 --- src/external/bsd/dhcpcd/dist/compat/rb.c:1.1.1.1 Wed Jul 24 09:54:48 2019 +++ src/external/bsd/dhcpcd/dist/compat/rb.c Thu Sep 5 08:56:55 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rb.c,v 1.1.1.1 2019/07/24 09:54:48 roy Exp $ */ +/* $NetBSD: rb.c,v 1.1.1.1.2.1 2019/09/05 08:56:55 martin Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -29,6 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include "config.h" #include "common.h" #if !defined(_KERNEL) && !defined(_STANDALONE) @@ -43,10 +44,10 @@ #define KASSERT(s) do { } while (/*CONSTCOND*/ 0) #define __rbt_unused __unused #endif -__RCSID("$NetBSD: rb.c,v 1.1.1.1 2019/07/24 09:54:48 roy Exp $"); +__RCSID("$NetBSD: rb.c,v 1.1.1.1.2.1 2019/09/05 08:56:55 martin Exp $"); #else #include <lib/libkern/libkern.h> -__KERNEL_RCSID(0, "$NetBSD: rb.c,v 1.1.1.1 2019/07/24 09:54:48 roy Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rb.c,v 1.1.1.1.2.1 2019/09/05 08:56:55 martin Exp $"); #ifndef DIAGNOSTIC #define __rbt_unused __unused #else Index: src/external/bsd/dhcpcd/dist/compat/rbtree.h diff -u src/external/bsd/dhcpcd/dist/compat/rbtree.h:1.1.1.1 src/external/bsd/dhcpcd/dist/compat/rbtree.h:1.1.1.1.2.1 --- src/external/bsd/dhcpcd/dist/compat/rbtree.h:1.1.1.1 Wed Jul 24 09:54:48 2019 +++ src/external/bsd/dhcpcd/dist/compat/rbtree.h Thu Sep 5 08:56:55 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rbtree.h,v 1.1.1.1 2019/07/24 09:54:48 roy Exp $ */ +/* $NetBSD: rbtree.h,v 1.1.1.1.2.1 2019/09/05 08:56:55 martin Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -32,6 +32,7 @@ #ifndef _SYS_RBTREE_H_ #define _SYS_RBTREE_H_ +#include "config.h" #include "common.h" #if defined(_KERNEL) || defined(_STANDALONE) @@ -40,7 +41,11 @@ #include <stdbool.h> #include <inttypes.h> #endif +#ifdef HAVE_SYS_QUEUE_H +#include <sys/queue.h> +#else #include "queue.h" +#endif #if !defined(__linux__) && !defined(__QNX__) && !defined(__sun) #include <sys/endian.h> #else Index: src/external/bsd/dhcpcd/dist/hooks/Makefile diff -u src/external/bsd/dhcpcd/dist/hooks/Makefile:1.1.1.1 src/external/bsd/dhcpcd/dist/hooks/Makefile:1.1.1.1.20.1 --- src/external/bsd/dhcpcd/dist/hooks/Makefile:1.1.1.1 Fri Mar 31 20:51:16 2017 +++ src/external/bsd/dhcpcd/dist/hooks/Makefile Thu Sep 5 08:56:55 2019 @@ -61,4 +61,11 @@ import: ${HOOKSCRIPTS} ${INSTALL} -m ${NONBINMODE} ${SCRIPTS} /tmp/${DISTPREFIX}/dhcpcd-hooks ${INSTALL} -m ${NONBINMODE} ${FILES} /tmp/${DISTPREFIX}/dhcpcd-hooks +_import-src: + ${INSTALL} -d ${DESTDIR}/hooks + cp dhcpcd-run-hooks.in dhcpcd-run-hooks.8.in [0-9]* ${DESTDIR}/hooks + rm ${DESTDIR}/hooks/50-dhcpcd-compat + if [ `uname` = Linux ]; then rm ${DESTDIR}/hooks/50-ypbind.in; \ + else rm ${DESTDIR}/hooks/50-yp.conf; fi + include ${TOP}/Makefile.inc Index: src/external/bsd/dhcpcd/dist/src/Makefile diff -u src/external/bsd/dhcpcd/dist/src/Makefile:1.1.1.5 src/external/bsd/dhcpcd/dist/src/Makefile:1.1.1.5.2.1 --- src/external/bsd/dhcpcd/dist/src/Makefile:1.1.1.5 Wed Apr 17 23:33:08 2019 +++ src/external/bsd/dhcpcd/dist/src/Makefile Thu Sep 5 08:56:55 2019 @@ -135,4 +135,38 @@ clean: distclean: clean rm -f .depend +_import-src: ${SRCS} + ${INSTALL} -d ${DESTDIR}/src + touch if-bsd.h if-linux.h if-sun.h + cp defs.h ${SRCS} ${SRCS:.c=.h} dev.h ${MAN5}.in ${MAN8}.in ${DESTDIR}/src + rm if-bsd.h if-linux.h if-sun.h + rm -f ${DESTDIR}/src/if-bsd.h ${DESTDIR}/src/if-linux.h ${DESTDIR}/src/if-sun.h + if [ -n "${COMPAT_SRCS}" ]; then \ + ${INSTALL} -d ${DESTDIR}/compat; \ + cd ..; \ + touch compat/rb.h compat/strtou.h; \ + cp ${COMPAT_SRCS} ${COMPAT_SRCS:.c=.h} ${DESTDIR}/compat; \ + rm compat/rb.h compat/strtou.h; \ + rm -f ${DESTDIR}/compat/rb.h ${DESTDIR}/compat/strtou.h; \ + fi + if ! grep HAVE_SYS_BITOPS_H ../config.h; then \ + cp ../compat/bitops.h ${DESTDIR}/compat; \ + fi + if grep compat/consttime_memequal.h ../config.h; then \ + cp ../compat/consttime_memequal.h ${DESTDIR}/compat; \ + fi + if [ -e ${DESTDIR}/compat/rb.c ]; then \ + cp ../compat/rbtree.h ${DESTDIR}/compat; \ + fi + if [ -e ${DESTDIR}/compat/strtoi.c ]; then \ + cp ../compat/_strtoi.h ${DESTDIR}/compat; \ + fi + if [ -n "${CRYPT_SRCS}" ]; then \ + ${INSTALL} -d ${DESTDIR}/compat/crypt; \ + cd ..; \ + cp ${CRYPT_SRCS} ${CRYPT_SRCS:.c=.h} ${DESTDIR}/compat/crypt; \ + fi + # DragonFlyBSD builds base version with private crypto + if [ `uname` = DragonFly ]; then rm ${DESTDIR}/compat/crypt/md5* ${DESTDIR}/compat/crypt/sha256*; fi + include ${TOP}/Makefile.inc Index: src/external/bsd/dhcpcd/dist/src/sa.c diff -u src/external/bsd/dhcpcd/dist/src/sa.c:1.1.1.5 src/external/bsd/dhcpcd/dist/src/sa.c:1.1.1.5.2.1 --- src/external/bsd/dhcpcd/dist/src/sa.c:1.1.1.5 Wed Jul 24 09:54:55 2019 +++ src/external/bsd/dhcpcd/dist/src/sa.c Thu Sep 5 08:56:55 2019 @@ -288,11 +288,9 @@ sa_toprefix(const struct sockaddr *sa) #ifndef NDEBUG /* Ensure the calculation is correct */ if (!sa_inprefix) { - union sa_ss ss; + union sa_ss ss = { .sa.sa_family = sa->sa_family }; sa_inprefix = true; - memset(&ss, 0, sizeof(ss)); - ss.sa.sa_family = sa->sa_family; sa_fromprefix(&ss.sa, prefix); assert(sa_cmp(sa, &ss.sa) == 0); sa_inprefix = false; Index: src/external/bsd/dhcpcd/dist/src/bpf.c diff -u src/external/bsd/dhcpcd/dist/src/bpf.c:1.11 src/external/bsd/dhcpcd/dist/src/bpf.c:1.11.2.1 --- src/external/bsd/dhcpcd/dist/src/bpf.c:1.11 Tue Jul 30 10:25:03 2019 +++ src/external/bsd/dhcpcd/dist/src/bpf.c Thu Sep 5 08:56:55 2019 @@ -558,6 +558,15 @@ bpf_arp(struct interface *ifp, int fd) #define BPF_M_UDP 3 #define BPF_M_UDPLEN 4 +#ifdef ARPHRD_NONE +static const struct bpf_insn bpf_bootp_none[] = { + /* Set the frame header length to zero. */ + BPF_STMT(BPF_LD + BPF_IMM, 0), + BPF_STMT(BPF_ST, BPF_M_FHLEN), +}; +#define BPF_BOOTP_NONE_LEN __arraycount(bpf_bootp_none) +#endif + static const struct bpf_insn bpf_bootp_ether[] = { /* Make sure this is an IP packet. */ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, @@ -665,6 +674,12 @@ bpf_bootp(struct interface *ifp, int fd) bp = bpf; /* Check frame header. */ switch(ifp->family) { +#ifdef ARPHRD_NONE + case ARPHRD_NONE: + memcpy(bp, bpf_bootp_none, sizeof(bpf_bootp_none)); + bp += BPF_BOOTP_NONE_LEN; + break; +#endif case ARPHRD_ETHER: memcpy(bp, bpf_bootp_ether, sizeof(bpf_bootp_ether)); bp += BPF_BOOTP_ETHER_LEN; Index: src/external/bsd/dhcpcd/dist/src/dhcp6.c diff -u src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.11 src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.11.2.1 --- src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.11 Tue Jul 30 10:25:03 2019 +++ src/external/bsd/dhcpcd/dist/src/dhcp6.c Thu Sep 5 08:56:55 2019 @@ -2488,22 +2488,22 @@ dhcp6_readlease(struct interface *ifp, i struct dhcp6_state *state; struct stat st; int fd; - struct dhcp6_message *lease; time_t now; int retval; - bool fd_opened; + bool read_stdin, fd_opened; #ifdef AUTH uint8_t *o; uint16_t ol; #endif state = D6_STATE(ifp); - if (state->leasefile[0] == '\0') { + read_stdin = state->leasefile[0] == '\0'; + if (read_stdin) { logdebugx("reading standard input"); fd = fileno(stdin); fd_opened = false; } else { - logdebugx("%s: reading lease `%s'", ifp->name, state->leasefile); + logdebugx("%s: reading lease `%s'", ifp->name,state->leasefile); fd = open(state->leasefile, O_RDONLY); if (fd != -1 && fstat(fd, &st) == -1) { close(fd); @@ -2514,19 +2514,19 @@ dhcp6_readlease(struct interface *ifp, i if (fd == -1) return -1; retval = -1; - lease = NULL; free(state->new); - state->new_len = dhcp_read_lease_fd(fd, (void **)&lease); - state->new = lease; + state->new_len = dhcp_read_lease_fd(fd, (void **)&state->new); if (fd_opened) close(fd); - if (state->new_len == 0) - goto ex; - if (ifp->ctx->options & DHCPCD_DUMPLEASE || - state->leasefile[0] == '\0') + if (ifp->ctx->options & DHCPCD_DUMPLEASE || read_stdin) return 0; + if (state->new_len == 0) { + retval = 0; + goto ex; + } + /* If not validating IA's and if they have expired, * skip to the auth check. */ if (!validate) { @@ -2546,14 +2546,12 @@ dhcp6_readlease(struct interface *ifp, i goto ex; if (state->expire != ND6_INFINITE_LIFETIME && - state->leasefile[0] != '\0') + (time_t)state->expire < now - st.st_mtime && + !(ifp->options->options & DHCPCD_LASTLEASE_EXTEND)) { - if ((time_t)state->expire < now - st.st_mtime && - !(ifp->options->options & DHCPCD_LASTLEASE_EXTEND)) { - logdebugx("%s: discarding expired lease", ifp->name); - retval = 0; - goto ex; - } + logdebugx("%s: discarding expired lease", ifp->name); + retval = 0; + goto ex; } auth: @@ -2586,12 +2584,10 @@ auth: ex: dhcp6_freedrop_addrs(ifp, 0, NULL); + unlink(state->leasefile); free(state->new); state->new = NULL; state->new_len = 0; - if (!(ifp->ctx->options & DHCPCD_DUMPLEASE) && - state->leasefile[0] != '\0') - unlink(state->leasefile); return retval; } Index: src/external/bsd/dhcpcd/dist/src/control.c diff -u src/external/bsd/dhcpcd/dist/src/control.c:1.1.1.6 src/external/bsd/dhcpcd/dist/src/control.c:1.1.1.6.2.1 --- src/external/bsd/dhcpcd/dist/src/control.c:1.1.1.6 Wed Jul 24 09:54:49 2019 +++ src/external/bsd/dhcpcd/dist/src/control.c Thu Sep 5 08:56:55 2019 @@ -53,41 +53,26 @@ #endif static void -control_queue_purge(struct dhcpcd_ctx *ctx, char *data) -{ - int found; - struct fd_list *fp; - struct fd_data *fpd; - - /* If no other fd queue has the same data, free it */ - found = 0; - TAILQ_FOREACH(fp, &ctx->control_fds, next) { - TAILQ_FOREACH(fpd, &fp->queue, next) { - if (fpd->data == data) { - found = 1; - break; - } - } - } - if (!found) - free(data); -} - -static void control_queue_free(struct fd_list *fd) { struct fd_data *fdp; while ((fdp = TAILQ_FIRST(&fd->queue))) { TAILQ_REMOVE(&fd->queue, fdp, next); - if (fdp->freeit) - control_queue_purge(fd->ctx, fdp->data); + if (fdp->data_size != 0) + free(fdp->data); free(fdp); } + fd->queue_len = 0; + +#ifdef CTL_FREE_LIST while ((fdp = TAILQ_FIRST(&fd->free_queue))) { TAILQ_REMOVE(&fd->free_queue, fdp, next); + if (fdp->data_size != 0) + free(fdp->data); free(fdp); } +#endif } static void @@ -161,29 +146,33 @@ control_handle1(struct dhcpcd_ctx *ctx, len = sizeof(run); if ((fd = accept(lfd, (struct sockaddr *)&run, &len)) == -1) - return; + goto error; if ((flags = fcntl(fd, F_GETFD, 0)) == -1 || fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) - { - close(fd); - return; - } + goto error; if ((flags = fcntl(fd, F_GETFL, 0)) == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) - { - close(fd); - return; - } + goto error; + l = malloc(sizeof(*l)); - if (l) { - l->ctx = ctx; - l->fd = fd; - l->flags = fd_flags; - TAILQ_INIT(&l->queue); - TAILQ_INIT(&l->free_queue); - TAILQ_INSERT_TAIL(&ctx->control_fds, l, next); - eloop_event_add(ctx->eloop, l->fd, control_handle_data, l); - } else + if (l == NULL) + goto error; + + l->ctx = ctx; + l->fd = fd; + l->flags = fd_flags; + TAILQ_INIT(&l->queue); + l->queue_len = 0; +#ifdef CTL_FREE_LIST + TAILQ_INIT(&l->free_queue); +#endif + TAILQ_INSERT_TAIL(&ctx->control_fds, l, next); + eloop_event_add(ctx->eloop, l->fd, control_handle_data, l); + return; + +error: + logerr(__func__); + if (fd != -1) close(fd); } @@ -374,40 +363,88 @@ control_writeone(void *arg) } TAILQ_REMOVE(&fd->queue, data, next); - if (data->freeit) - control_queue_purge(fd->ctx, data->data); - data->data = NULL; /* safety */ - data->data_len = 0; + fd->queue_len--; +#ifdef CTL_FREE_LIST TAILQ_INSERT_TAIL(&fd->free_queue, data, next); +#else + if (data->data_size != 0) + free(data->data); + free(data); +#endif if (TAILQ_FIRST(&fd->queue) == NULL) eloop_event_remove_writecb(fd->ctx->eloop, fd->fd); } int -control_queue(struct fd_list *fd, char *data, size_t data_len, uint8_t fit) +control_queue(struct fd_list *fd, void *data, size_t data_len, bool fit) { struct fd_data *d; - size_t n; - d = TAILQ_FIRST(&fd->free_queue); - if (d) { - TAILQ_REMOVE(&fd->free_queue, d, next); - } else { - n = 0; - TAILQ_FOREACH(d, &fd->queue, next) { - if (++n == CONTROL_QUEUE_MAX) { - errno = ENOBUFS; - return -1; + if (data_len == 0) + return 0; + +#ifdef CTL_FREE_LIST + struct fd_data *df; + + d = NULL; + TAILQ_FOREACH(df, &fd->free_queue, next) { + if (!fit) { + if (df->data_size == 0) { + d = df; + break; } + continue; + } + if (d == NULL || d->data_size < df->data_size) { + d = df; + if (d->data_size <= data_len) + break; + } + } + if (d != NULL) + TAILQ_REMOVE(&fd->free_queue, d, next); + else +#endif + { + if (fd->queue_len == CONTROL_QUEUE_MAX) { + errno = ENOBUFS; + return -1; } - d = malloc(sizeof(*d)); + fd->queue_len++; + d = calloc(1, sizeof(*d)); if (d == NULL) return -1; } - d->data = data; + + if (!fit) { +#ifdef CTL_FREE_LIST + if (d->data_size != 0) { + free(d->data); + d->data_size = 0; + } +#endif + d->data = data; + d->data_len = data_len; + goto queue; + } + + if (d->data_size == 0) + d->data = NULL; + if (d->data_size < data_len) { + void *nbuf = realloc(d->data, data_len); + if (nbuf == NULL) { + free(d->data); + free(d); + return -1; + } + d->data = nbuf; + d->data_size = data_len; + } + memcpy(d->data, data, data_len); d->data_len = data_len; - d->freeit = fit; + +queue: TAILQ_INSERT_TAIL(&fd->queue, d, next); eloop_event_add_w(fd->ctx->eloop, fd->fd, control_writeone, fd); return 0; Index: src/external/bsd/dhcpcd/dist/src/dhcp-common.c diff -u src/external/bsd/dhcpcd/dist/src/dhcp-common.c:1.1.1.6 src/external/bsd/dhcpcd/dist/src/dhcp-common.c:1.1.1.6.2.1 --- src/external/bsd/dhcpcd/dist/src/dhcp-common.c:1.1.1.6 Wed Jul 24 09:54:49 2019 +++ src/external/bsd/dhcpcd/dist/src/dhcp-common.c Thu Sep 5 08:56:55 2019 @@ -622,6 +622,7 @@ print_option(FILE *fp, const char *prefi int vname, const uint8_t *data, size_t dl, const char *ifname) { + fpos_t fp_pos; const uint8_t *e, *t; uint16_t u16; int16_t s16; @@ -636,25 +637,32 @@ print_option(FILE *fp, const char *prefi if ((ssize_t)dl == -1) return 0; - if (fprintf(fp, "%s", prefix) == -1) + if (fgetpos(fp, &fp_pos) == -1) return -1; + if (fprintf(fp, "%s", prefix) == -1) + goto err; + + /* We printed something, so always goto err from now-on + * to terminate the string. */ if (vname) { if (fprintf(fp, "_%s", opt->var) == -1) - return -1; + goto err; } if (fputc('=', fp) == EOF) - return -1; + goto err; if (dl == 0) - return 1; + goto done; if (opt->type & OT_RFC1035) { char domain[NS_MAXDNAME]; sl = decode_rfc1035(domain, sizeof(domain), data, dl); - if (sl == 0 || sl == -1) - return sl; + if (sl == -1) + goto err; + if (sl == 0) + goto done; if (valid_domainname(domain, opt->type) == -1) - return -1; + goto err; return efprintf(fp, "%s", domain); } @@ -670,7 +678,7 @@ print_option(FILE *fp, const char *prefi char buf[1024]; if (print_string(buf, sizeof(buf), opt->type, data, dl) == -1) - return -1; + goto err; return efprintf(fp, "%s", buf); } @@ -690,12 +698,10 @@ print_option(FILE *fp, const char *prefi *data & (1 << sl)) { if (fputc(opt->bitflags[l], fp) == EOF) - return -1; + goto err; } } - if (fputc('\0', fp) == EOF) - return -1; - return 1; + goto done; } t = data; @@ -703,66 +709,71 @@ print_option(FILE *fp, const char *prefi while (data < e) { if (data != t) { if (fputc(' ', fp) == EOF) - return -1; + goto err; } if (opt->type & OT_UINT8) { if (fprintf(fp, "%u", *data) == -1) - return -1; + goto err; data++; } else if (opt->type & OT_INT8) { if (fprintf(fp, "%d", *data) == -1) - return -1; + goto err; data++; } else if (opt->type & OT_UINT16) { memcpy(&u16, data, sizeof(u16)); u16 = ntohs(u16); if (fprintf(fp, "%u", u16) == -1) - return -1; + goto err; data += sizeof(u16); } else if (opt->type & OT_INT16) { memcpy(&u16, data, sizeof(u16)); s16 = (int16_t)ntohs(u16); if (fprintf(fp, "%d", s16) == -1) - return -1; + goto err; data += sizeof(u16); } else if (opt->type & OT_UINT32) { memcpy(&u32, data, sizeof(u32)); u32 = ntohl(u32); if (fprintf(fp, "%u", u32) == -1) - return -1; + goto err; data += sizeof(u32); } else if (opt->type & OT_INT32) { memcpy(&u32, data, sizeof(u32)); s32 = (int32_t)ntohl(u32); if (fprintf(fp, "%d", s32) == -1) - return -1; + goto err; data += sizeof(u32); } else if (opt->type & OT_ADDRIPV4) { memcpy(&addr.s_addr, data, sizeof(addr.s_addr)); if (fprintf(fp, "%s", inet_ntoa(addr)) == -1) - return -1; + goto err; data += sizeof(addr.s_addr); } else if (opt->type & OT_ADDRIPV6) { char buf[INET6_ADDRSTRLEN]; if (inet_ntop(AF_INET6, data, buf, sizeof(buf)) == NULL) - return -1; + goto err; if (fprintf(fp, "%s", buf) == -1) - return -1; + goto err; if (data[0] == 0xfe && (data[1] & 0xc0) == 0x80) { if (fprintf(fp,"%%%s", ifname) == -1) - return -1; + goto err; } data += 16; } else { errno = EINVAL; - return -1; + goto err; } } +done: if (fputc('\0', fp) == EOF) return -1; return 1; + +err: + (void)fsetpos(fp, &fp_pos); + return -1; } int @@ -950,6 +961,8 @@ dhcp_read_lease_fd(int fd, void **lease) } sz = (size_t)st.st_size; + if (sz == 0) + goto out; if ((buf = malloc(sz)) == NULL) goto out; if ((len = read(fd, buf, sz)) == -1) { Index: src/external/bsd/dhcpcd/dist/src/duid.c diff -u src/external/bsd/dhcpcd/dist/src/duid.c:1.1.1.6 src/external/bsd/dhcpcd/dist/src/duid.c:1.1.1.6.2.1 --- src/external/bsd/dhcpcd/dist/src/duid.c:1.1.1.6 Wed Jul 24 09:54:52 2019 +++ src/external/bsd/dhcpcd/dist/src/duid.c Thu Sep 5 08:56:55 2019 @@ -52,10 +52,6 @@ #include <time.h> #include <unistd.h> -#ifndef ARPHRD_NETROM -# define ARPHRD_NETROM 0 -#endif - #include "common.h" #include "dhcpcd.h" #include "duid.h" @@ -189,10 +185,10 @@ duid_get(uint8_t **d, const struct inter return len; /* No UUID? OK, lets make one based on our interface */ - if (ifp->family == ARPHRD_NETROM) { - logwarnx("%s: is a NET/ROM pseudo interface", ifp->name); + if (ifp->hwlen == 0) { + logwarnx("%s: does not have hardware address", ifp->name); TAILQ_FOREACH(ifp2, ifp->ctx->ifaces, next) { - if (ifp2->family != ARPHRD_NETROM) + if (ifp2->hwlen != 0) break; } if (ifp2) { Index: src/external/bsd/dhcpcd/dist/src/control.h diff -u src/external/bsd/dhcpcd/dist/src/control.h:1.1.1.4 src/external/bsd/dhcpcd/dist/src/control.h:1.1.1.4.2.1 --- src/external/bsd/dhcpcd/dist/src/control.h:1.1.1.4 Wed Jul 24 09:54:49 2019 +++ src/external/bsd/dhcpcd/dist/src/control.h Thu Sep 5 08:56:55 2019 @@ -31,14 +31,20 @@ #include "dhcpcd.h" +#if !defined(CTL_FREE_LIST) +#define CTL_FREE_LIST 1 +#elif CTL_FREE_LIST == 0 +#undef CTL_FREE_LIST +#endif + /* Limit queue size per fd */ #define CONTROL_QUEUE_MAX 100 struct fd_data { TAILQ_ENTRY(fd_data) next; - char *data; + void *data; + size_t data_size; size_t data_len; - uint8_t freeit; }; TAILQ_HEAD(fd_data_head, fd_data); @@ -48,7 +54,10 @@ struct fd_list { int fd; unsigned int flags; struct fd_data_head queue; + size_t queue_len; +#ifdef CTL_FREE_LIST struct fd_data_head free_queue; +#endif }; TAILQ_HEAD(fd_list_head, fd_list); @@ -59,7 +68,7 @@ int control_start(struct dhcpcd_ctx *, c int control_stop(struct dhcpcd_ctx *); int control_open(const char *); ssize_t control_send(struct dhcpcd_ctx *, int, char * const *); -int control_queue(struct fd_list *fd, char *data, size_t data_len, uint8_t fit); +int control_queue(struct fd_list *, void *, size_t, bool); void control_close(struct dhcpcd_ctx *ctx); #endif Index: src/external/bsd/dhcpcd/dist/src/defs.h diff -u src/external/bsd/dhcpcd/dist/src/defs.h:1.1.1.25 src/external/bsd/dhcpcd/dist/src/defs.h:1.1.1.25.2.1 --- src/external/bsd/dhcpcd/dist/src/defs.h:1.1.1.25 Tue Jul 30 10:23:04 2019 +++ src/external/bsd/dhcpcd/dist/src/defs.h Thu Sep 5 08:56:55 2019 @@ -29,7 +29,7 @@ #define CONFIG_H #define PACKAGE "dhcpcd" -#define VERSION "8.0.2" +#define VERSION "8.0.4" #ifndef CONFIG # define CONFIG SYSCONFDIR "/" PACKAGE ".conf" Index: src/external/bsd/dhcpcd/dist/src/dhcp.c diff -u src/external/bsd/dhcpcd/dist/src/dhcp.c:1.23 src/external/bsd/dhcpcd/dist/src/dhcp.c:1.23.2.1 --- src/external/bsd/dhcpcd/dist/src/dhcp.c:1.23 Tue Jul 30 10:25:03 2019 +++ src/external/bsd/dhcpcd/dist/src/dhcp.c Thu Sep 5 08:56:55 2019 @@ -1176,11 +1176,8 @@ read_lease(struct interface *ifp, struct bytes = dhcp_read_lease_fd(fd, (void **)&lease); if (fd_opened) close(fd); - if (bytes == 0) { - free(lease); - logerr("%s: dhcp_read_lease_fd", __func__); + if (bytes == 0) return 0; - } /* Ensure the packet is at lease BOOTP sized * with a vendor area of 4 octets @@ -1584,24 +1581,24 @@ eexit: } static uint16_t -checksum(const void *data, size_t len) +in_cksum(const void *data, size_t len, uint32_t *isum) { - const uint8_t *addr = data; - uint32_t sum = 0; + const uint16_t *word = data; + uint32_t sum = isum != NULL ? *isum : 0; - while (len > 1) { - sum += (uint32_t)(addr[0] * 256 + addr[1]); - addr += 2; - len -= 2; - } + for (; len > 1; len -= sizeof(*word)) + sum += *word++; if (len == 1) - sum += (uint32_t)(*addr * 256); + sum += htons((uint16_t)(*(const uint8_t *)word << 8)); + + if (isum != NULL) + *isum = sum; sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); - return (uint16_t)~htons((uint16_t)sum); + return (uint16_t)~sum; } static struct bootp_pkt * @@ -1639,14 +1636,16 @@ dhcp_makeudppacket(size_t *sz, const uin udp->uh_dport = htons(BOOTPS); udp->uh_ulen = htons((uint16_t)(sizeof(*udp) + length)); ip->ip_len = udp->uh_ulen; - udp->uh_sum = checksum(udpp, sizeof(*ip) + sizeof(*udp) + length); + udp->uh_sum = in_cksum(udpp, sizeof(*ip) + sizeof(*udp) + length, NULL); ip->ip_v = IPVERSION; ip->ip_hl = sizeof(*ip) >> 2; ip->ip_id = (uint16_t)arc4random_uniform(UINT16_MAX); ip->ip_ttl = IPDEFTTL; ip->ip_len = htons((uint16_t)(sizeof(*ip) + sizeof(*udp) + length)); - ip->ip_sum = checksum(ip, sizeof(*ip)); + ip->ip_sum = in_cksum(ip, sizeof(*ip), NULL); + if (ip->ip_sum == 0) + ip->ip_sum = 0xffff; /* RFC 768 */ *sz = sizeof(*ip) + sizeof(*udp) + length; return udpp; @@ -2235,7 +2234,7 @@ dhcp_bind(struct interface *ifp) ipv4_applyaddr(ifp); #ifdef IP_PKTINFO - /* Close the BPF filter as we can now receive the DHCP renew messages + /* Close the BPF filter as we can now receive DHCP messages * on a UDP socket. */ if (state->udp_fd == -1 || (state->old != NULL && state->old->yiaddr != state->new->yiaddr)) @@ -2244,9 +2243,15 @@ dhcp_bind(struct interface *ifp) /* If not in master mode, open an address specific socket. */ if (ctx->udp_fd == -1) { state->udp_fd = dhcp_openudp(ifp); - if (state->udp_fd == -1) + if (state->udp_fd == -1) { logerr(__func__); - else + /* Address sharing without master mode is + * not supported. It's also possible another + * DHCP client could be running which is + * even worse. + * We still need to work, so re-open BPF. */ + dhcp_openbpf(ifp); + } else eloop_event_add(ctx->eloop, state->udp_fd, dhcp_handleifudp, ifp); } @@ -2363,7 +2368,10 @@ dhcp_arp_address(struct interface *ifp) return 0; } #else - if (ifp->options->options & DHCPCD_ARP && ia == NULL) { + if (!(ifp->flags & IFF_NOARP) && + ifp->options->options & DHCPCD_ARP && + ia == NULL) + { struct arp_state *astate; struct dhcp_lease l; @@ -3236,10 +3244,15 @@ valid_udp_packet(void *packet, size_t pl unsigned int flags) { struct ip *ip = packet; - char ip_hlv = *(char *)ip; + struct ip pseudo_ip = { + .ip_p = IPPROTO_UDP, + .ip_src = ip->ip_src, + .ip_dst = ip->ip_dst + }; size_t ip_hlen; uint16_t ip_len, uh_sum; struct udphdr *udp; + uint32_t csum; if (plen < sizeof(*ip)) { if (from != NULL) @@ -3252,13 +3265,13 @@ valid_udp_packet(void *packet, size_t pl from->s_addr = ip->ip_src.s_addr; ip_hlen = (size_t)ip->ip_hl * 4; - if (checksum(ip, ip_hlen) != 0) { + if (in_cksum(ip, ip_hlen, NULL) != 0) { errno = EINVAL; return -1; } - ip_len = ntohs(ip->ip_len); /* Check we have a payload */ + ip_len = ntohs(ip->ip_len); if (ip_len <= ip_hlen + sizeof(*udp)) { errno = ERANGE; return -1; @@ -3272,28 +3285,22 @@ valid_udp_packet(void *packet, size_t pl if (flags & BPF_PARTIALCSUM) return 0; - udp = (struct udphdr *)((char *)ip + ip_hlen); + /* UDP checksum is based on a pseudo IP header alongside + * the UDP header and payload. */ + udp = (struct udphdr *)(void *)((char *)ip + ip_hlen); if (udp->uh_sum == 0) return 0; - uh_sum = udp->uh_sum; - /* This does scribble on the packet, but at this point - * we don't care to keep it. */ + uh_sum = udp->uh_sum; udp->uh_sum = 0; - ip->ip_hl = 0; - ip->ip_v = 0; - ip->ip_tos = 0; - ip->ip_len = udp->uh_ulen; - ip->ip_id = 0; - ip->ip_off = 0; - ip->ip_ttl = 0; - ip->ip_sum = 0; - if (checksum(packet, ip_len) != uh_sum) { + pseudo_ip.ip_len = udp->uh_ulen; + csum = 0; + in_cksum(&pseudo_ip, sizeof(pseudo_ip), &csum); + csum = in_cksum(udp, ntohs(udp->uh_ulen), &csum); + if (csum != uh_sum) { errno = EINVAL; return -1; } - *(char *)ip = ip_hlv; - ip->ip_len = htons(ip_len); return 0; } @@ -3339,12 +3346,6 @@ dhcp_handlepacket(struct interface *ifp, ifp->name, inet_ntoa(from)); return; } - if (ifp->flags & IFF_POINTOPOINT && - (state->addr == NULL || state->addr->brd.s_addr != from.s_addr)) - { - logwarnx("%s: server %s is not destination", - ifp->name, inet_ntoa(from)); - } /* * DHCP has a variable option area rather than a fixed vendor area. @@ -3665,6 +3666,7 @@ static void dhcp_start1(void *arg) { struct interface *ifp = arg; + struct dhcpcd_ctx *ctx = ifp->ctx; struct if_options *ifo = ifp->options; struct dhcp_state *state; struct stat st; @@ -3675,17 +3677,19 @@ dhcp_start1(void *arg) return; /* Listen on *.*.*.*:bootpc so that the kernel never sends an - * ICMP port unreachable message back to the DHCP server */ - if (ifp->ctx->udp_fd == -1) { - ifp->ctx->udp_fd = dhcp_openudp(NULL); - if (ifp->ctx->udp_fd == -1) { + * ICMP port unreachable message back to the DHCP server. + * Only do this in master mode so we don't swallow messages + * for dhcpcd running on another interface. */ + if (ctx->udp_fd == -1 && ctx->options & DHCPCD_MASTER) { + ctx->udp_fd = dhcp_openudp(NULL); + if (ctx->udp_fd == -1) { /* Don't log an error if some other process * is handling this. */ if (errno != EADDRINUSE) logerr("%s: dhcp_openudp", __func__); } else - eloop_event_add(ifp->ctx->eloop, - ifp->ctx->udp_fd, dhcp_handleudp, ifp->ctx); + eloop_event_add(ctx->eloop, + ctx->udp_fd, dhcp_handleudp, ctx); } if (dhcp_init(ifp) == -1) { @@ -3721,12 +3725,6 @@ dhcp_start1(void *arg) return; } - if (ifp->hwlen == 0 && ifo->clientid[0] == '\0') { - logwarnx("%s: needs a clientid to configure", ifp->name); - dhcp_drop(ifp, "FAIL"); - eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); - return; - } /* We don't want to read the old lease if we NAK an old test */ nolease = state->offer && ifp->ctx->options & DHCPCD_TEST; if (!nolease && ifo->options & DHCPCD_DHCP) { Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.c diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.23 src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.23.2.1 --- src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.23 Tue Jul 30 10:25:03 2019 +++ src/external/bsd/dhcpcd/dist/src/dhcpcd.c Thu Sep 5 08:56:55 2019 @@ -458,11 +458,10 @@ configure_interface1(struct interface *i ifo->options &= ~DHCPCD_ARP; if (!(ifp->flags & IFF_MULTICAST)) ifo->options &= ~DHCPCD_IPV6RS; - if (!(ifo->options & DHCPCD_INFORM)) + if (!(ifo->options & (DHCPCD_INFORM | DHCPCD_WANTDHCP))) ifo->options |= DHCPCD_STATIC; } - if (ifp->flags & IFF_NOARP || - !(ifo->options & DHCPCD_ARP) || + if (!(ifo->options & DHCPCD_ARP) || ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)) ifo->options &= ~DHCPCD_IPV4LL; @@ -951,12 +950,7 @@ dhcpcd_prestartinterface(void *arg) if ((!(ifp->ctx->options & DHCPCD_MASTER) || ifp->options->options & DHCPCD_IF_UP) && - if_up(ifp) == -1 -#ifdef __sun - /* Interface could not yet be plumbed. */ - && errno != ENXIO -#endif - ) + if_up(ifp) == -1) logerr("%s: %s", __func__, ifp->name); dhcpcd_startinterface(ifp); @@ -1440,10 +1434,10 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx * write callback on the fd */ if (strcmp(*argv, "--version") == 0) { return control_queue(fd, UNCONST(VERSION), - strlen(VERSION) + 1, 0); + strlen(VERSION) + 1, false); } else if (strcmp(*argv, "--getconfigfile") == 0) { return control_queue(fd, UNCONST(fd->ctx->cffile), - strlen(fd->ctx->cffile) + 1, 0); + strlen(fd->ctx->cffile) + 1, false); } else if (strcmp(*argv, "--getinterfaces") == 0) { eloop_event_add_w(fd->ctx->eloop, fd->fd, dhcpcd_getinterfaces, fd); Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in:1.2 src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in:1.2.2.1 --- src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in:1.2 Fri Jul 26 10:39:29 2019 +++ src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in Thu Sep 5 08:56:55 2019 @@ -24,7 +24,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd July 25, 2019 +.Dd August 28, 2019 .Dt DHCPCD 8 .Os .Sh NAME @@ -71,7 +71,7 @@ .Fl k , Fl Fl release .Op interface .Nm -.Fl U, Fl Fl dumplease +.Fl U , Fl Fl dumplease .Ar interface .Nm .Fl Fl version @@ -260,7 +260,7 @@ otheriwse if persistent storage is avail (link local address + time) is generated, otherwise DUID-LL is generated (link local address). This, plus the IAID will be used as the -.Fl I, Fl Fl clientid . +.Fl I , Fl Fl clientid . The DUID generated will be held in .Pa @DBDIR@/duid and should not be copied to other hosts. @@ -470,7 +470,7 @@ This option is only needed when .Nm is not processing IPv6RA messages and the need for DHCPv6 Information Request exists. -.It Fl S, Fl Fl static Ar value +.It Fl S , Fl Fl static Ar value Configures a static DHCP .Ar value . If you set @@ -660,7 +660,7 @@ Quiet .Nm on the command line, only warnings and errors will be displayed. The messages are still logged though. -.It Fl T, Fl Fl test +.It Fl T , Fl Fl test On receipt of DHCP messages just call .Pa @SCRIPT@ with the reason of TEST which echos the DHCP variables found in the message @@ -673,7 +673,7 @@ option is not sent in TEST mode so that To test INFORM the interface needs to be configured with the desired address before starting .Nm . -.It Fl U, Fl Fl dumplease Ar interface +.It Fl U , Fl Fl dumplease Ar interface Dumps the last lease for the .Ar interface to stdout. @@ -683,20 +683,20 @@ Use the or .Fl 6 flags to specify an address family. -.It Fl V, Fl Fl variables +.It Fl V , Fl Fl variables Display a list of option codes, the associated variable and encoding for use in .Xr dhcpcd-run-hooks 8 . Variables are prefixed with new_ and old_ unless the option number is -. Variables without an option are part of the DHCP message and cannot be directly requested. -.It Fl W, Fl Fl whitelist Ar address Ns Op /cidr +.It Fl W , Fl Fl whitelist Ar address Ns Op /cidr Only accept packets from .Ar address Ns Op /cidr . -.Fl X, Fl Fl blacklist +.Fl X , Fl Fl blacklist is ignored if -.Fl W, Fl Fl whitelist +.Fl W , Fl Fl whitelist is set. -.It Fl X, Fl Fl blacklist Ar address Ns Op Ar /cidr +.It Fl X , Fl Fl blacklist Ar address Ns Op Ar /cidr Ignore all packets from .Ar address Ns Op Ar /cidr . .It Fl Z , Fl Fl denyinterfaces Ar pattern @@ -771,6 +771,7 @@ If you always use the same options, put .It Pa @SCRIPT@ Bourne shell script that is run to configure or de-configure an interface. .It Pa @LIBDIR@/dhcpcd/dev +Linux .Pa /dev management modules. .It Pa @HOOKDIR@ @@ -818,7 +819,7 @@ Control socket to per interface daemon. .Xr dhcpcd-run-hooks 8 , .Xr resolvconf 8 .Sh STANDARDS -RFC\ 951, RFC\ 1534, RFC\ 2104, RFC\ 2131, RFC\ 2132, RFC\ 2563, RFC\ 2855, +RFC\ 951, RFC\ 1534, RFC\ 2104, RFC\ 2131, RFC\ 2132, RFC\ 2563, RFC\ 2855, RFC\ 3004, RFC\ 3118, RFC\ 3203, RFC\ 3315, RFC\ 3361, RFC\ 3633, RFC\ 3396, RFC\ 3397, RFC\ 3442, RFC\ 3495, RFC\ 3925, RFC\ 3927, RFC\ 4039, RFC\ 4075, RFC\ 4242, RFC\ 4361, RFC\ 4390, RFC\ 4702, RFC\ 4074, RFC\ 4861, RFC\ 4833, Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.conf.5.in diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.conf.5.in:1.1.1.13 src/external/bsd/dhcpcd/dist/src/dhcpcd.conf.5.in:1.1.1.13.2.1 --- src/external/bsd/dhcpcd/dist/src/dhcpcd.conf.5.in:1.1.1.13 Wed Jul 24 09:54:52 2019 +++ src/external/bsd/dhcpcd/dist/src/dhcpcd.conf.5.in Thu Sep 5 08:56:55 2019 @@ -24,7 +24,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 24, 2019 +.Dd August 28, 2019 .Dt DHCPCD.CONF 5 .Os .Sh NAME @@ -622,7 +622,7 @@ with an infinite lease time. If you set .Ic ip6_address , .Nm dhcpcd -will continue auto-configuation as normal. +will continue auto-configuration as normal. .Pp Here is an example which configures two static address, overriding the default IPv4 broadcast address, an IPv4 router, DNS and disables IPv6 auto-configuration. @@ -705,9 +705,7 @@ Number with the .Ar data . This option can be set more than once to add more data, but the behaviour, -as per -.Xr RFC 3925 -is undefined if the Enterprise Number differs. +as per RFC 3925 is undefined if the Enterprise Number differs. .It Ic waitip Op 4 | 6 Wait for an address to be assigned before forking to the background. 4 means wait for an IPv4 address to be assigned. Index: src/external/bsd/dhcpcd/dist/src/if-bsd.c diff -u src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.10 src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.10.2.1 --- src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.10 Tue Jul 30 10:25:03 2019 +++ src/external/bsd/dhcpcd/dist/src/if-bsd.c Thu Sep 5 08:56:55 2019 @@ -141,7 +141,7 @@ if_opensockets_os(struct dhcpcd_ctx *ctx #ifdef RTM_IFANNOUNCE RTM_IFANNOUNCE, #endif - RTM_ADD, RTM_CHANGE, RTM_DELETE, + RTM_ADD, RTM_CHANGE, RTM_DELETE, RTM_MISS, #ifdef RTM_CHGADDR RTM_CHGADDR, #endif @@ -191,6 +191,8 @@ if_opensockets_os(struct dhcpcd_ctx *ctx if (setsockopt(ctx->link_fd, PF_ROUTE, ROUTE_MSGFILTER, &msgfilter_mask, sizeof(msgfilter_mask)) == -1) logerr(__func__); +#else +#warning kernel does not support route message filtering #endif return 0; @@ -637,7 +639,11 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct { const struct sockaddr *rti_info[RTAX_MAX]; - if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY)) { + if (!(rtm->rtm_addrs & RTA_DST)) { + errno = EINVAL; + return -1; + } + if (rtm->rtm_type != RTM_MISS && !(rtm->rtm_addrs & RTA_GATEWAY)) { errno = EINVAL; return -1; } @@ -660,11 +666,8 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct } #endif - /* We have already checked that at least one address must be - * present after the rtm structure. */ - /* coverity[ptr_arith] */ - if (get_addrs(rtm->rtm_addrs, rtm + 1, - rtm->rtm_msglen - sizeof(*rtm), rti_info) == -1) + if (get_addrs(rtm->rtm_addrs, (const char *)rtm + sizeof(*rtm), + rtm->rtm_msglen - sizeof(*rtm), rti_info) == -1) return -1; memset(rt, 0, sizeof(*rt)); @@ -675,12 +678,24 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct if (rt->rt_netmask.sa_family == 255) /* Why? */ rt->rt_netmask.sa_family = rt->rt_dest.sa_family; } - /* dhcpcd likes an unspecified gateway to indicate via the link. */ - if (rt->rt_flags & RTF_GATEWAY && - rti_info[RTAX_GATEWAY]->sa_family != AF_LINK) - if_copysa(&rt->rt_gateway, rti_info[RTAX_GATEWAY]); + + /* dhcpcd likes an unspecified gateway to indicate via the link. + * However we need to know if gateway was a link with an address. */ + if (rtm->rtm_addrs & RTA_GATEWAY) { + if (rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) { + const struct sockaddr_dl *sdl; + + sdl = (const struct sockaddr_dl*) + (const void *)rti_info[RTAX_GATEWAY]; + if (sdl->sdl_alen != 0) + rt->rt_dflags |= RTDF_GATELINK; + } else if (rtm->rtm_flags & RTF_GATEWAY) + if_copysa(&rt->rt_gateway, rti_info[RTAX_GATEWAY]); + } + if (rtm->rtm_addrs & RTA_IFA) if_copysa(&rt->rt_ifa, rti_info[RTAX_IFA]); + rt->rt_mtu = (unsigned int)rtm->rtm_rmx.rmx_mtu; if (rtm->rtm_index) @@ -692,6 +707,9 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct else rt->rt_ifp = if_findsa(ctx, rti_info[RTAX_DST]); + if (rt->rt_ifp == NULL && rtm->rtm_type == RTM_MISS) + rt->rt_ifp = if_find(ctx->ifaces, "lo0"); + if (rt->rt_ifp == NULL) { errno = ESRCH; return -1; @@ -1071,30 +1089,30 @@ if_rtm(struct dhcpcd_ctx *ctx, const str return 0; if (if_copyrt(ctx, &rt, rtm) == -1) - return -1; + return errno == ENOTSUP ? 0 : -1; #ifdef INET6 /* * BSD announces host routes. * As such, we should be notified of reachability by its * existance with a hardware address. + * Ensure we don't call this for a newly incomplete state. */ - if (rt.rt_dest.sa_family == AF_INET6 && rt.rt_flags & RTF_HOST) { - struct sockaddr_in6 dest; - struct sockaddr_dl sdl; + if (rt.rt_dest.sa_family == AF_INET6 && + (rt.rt_flags & RTF_HOST || rtm->rtm_type == RTM_MISS) && + !(rtm->rtm_type == RTM_ADD && !(rt.rt_dflags & RTDF_GATELINK))) + { + bool reachable; - memcpy(&dest, &rt.rt_dest, rt.rt_dest.sa_len); - if (rt.rt_gateway.sa_family == AF_LINK) - memcpy(&sdl, &rt.rt_gateway, rt.rt_gateway.sa_len); - else - sdl.sdl_alen = 0; - ipv6nd_neighbour(ctx, &dest.sin6_addr, - rtm->rtm_type != RTM_DELETE && sdl.sdl_alen ? - IPV6ND_REACHABLE : 0); + reachable = (rtm->rtm_type == RTM_ADD || + rtm->rtm_type == RTM_CHANGE) && + rt.rt_dflags & RTDF_GATELINK; + ipv6nd_neighbour(ctx, &rt.rt_ss_dest.sin6.sin6_addr, reachable); } #endif - rt_recvrt(rtm->rtm_type, &rt, rtm->rtm_pid); + if (rtm->rtm_type != RTM_MISS) + rt_recvrt(rtm->rtm_type, &rt, rtm->rtm_pid); return 0; } @@ -1115,10 +1133,7 @@ if_ifa(struct dhcpcd_ctx *ctx, const str if ((ifp = if_findindex(ctx->ifaces, ifam->ifam_index)) == NULL) return 0; - /* We have already checked that at least one address must be - * present after the ifam structure. */ - /* coverity[ptr_arith] */ - if (get_addrs(ifam->ifam_addrs, ifam + 1, + if (get_addrs(ifam->ifam_addrs, (const char *)ifam + sizeof(*ifam), ifam->ifam_msglen - sizeof(*ifam), rti_info) == -1) return -1; @@ -1303,7 +1318,8 @@ if_dispatch(struct dhcpcd_ctx *ctx, cons return if_ifinfo(ctx, (const void *)rtm); case RTM_ADD: /* FALLTHROUGH */ case RTM_CHANGE: /* FALLTHROUGH */ - case RTM_DELETE: + case RTM_DELETE: /* FALLTHROUGH */ + case RTM_MISS: return if_rtm(ctx, (const void *)rtm); #ifdef RTM_CHGADDR case RTM_CHGADDR: /* FALLTHROUGH */ @@ -1314,32 +1330,41 @@ if_dispatch(struct dhcpcd_ctx *ctx, cons #ifdef RTM_DESYNC case RTM_DESYNC: dhcpcd_linkoverflow(ctx); +#elif !defined(SO_RERROR) +#warning cannot detect route socket overflow within kernel #endif } return 0; } +__CTASSERT(offsetof(struct rt_msghdr, rtm_msglen) == 0); int if_handlelink(struct dhcpcd_ctx *ctx) { struct rtm rtm; - struct iovec iov = { .iov_base = &rtm, .iov_len = sizeof(rtm) }; - struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1 }; ssize_t len; - len = recvmsg(ctx->link_fd, &msg, 0); + len = read(ctx->link_fd, &rtm, sizeof(rtm)); if (len == -1) return -1; if (len == 0) return 0; - if (len < rtm.hdr.rtm_msglen) { + if ((size_t)len < sizeof(rtm.hdr.rtm_msglen) || + len != rtm.hdr.rtm_msglen) + { errno = EINVAL; return -1; } - /* We generally treat rtm.hdr has an array so we can easily - * access the following data. */ - /* coverity[callee_ptr_arith] */ + /* + * Coverity thinks that the data could be tainted from here. + * I have no idea how because the length of the data we read + * is guarded by len and checked to match rtm_msglen. + * The issue seems to be related to extracting the addresses + * at the end of the header, but seems to have no issues with the + * equivalent call in if_initrt. + */ + /* coverity[tainted_data] */ return if_dispatch(ctx, &rtm.hdr); } Index: src/external/bsd/dhcpcd/dist/src/ipv6nd.c diff -u src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.10 src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.10.2.1 --- src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.10 Tue Jul 30 10:25:03 2019 +++ src/external/bsd/dhcpcd/dist/src/ipv6nd.c Thu Sep 5 08:56:55 2019 @@ -217,7 +217,6 @@ ipv6nd_open0(void) goto eexit; ICMP6_FILTER_SETBLOCKALL(&filt); - ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filt); ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt); if (setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, sizeof(filt)) == -1) @@ -460,6 +459,11 @@ ipv6nd_advertise(struct ipv6_addr *ia) if (IN6_IS_ADDR_MULTICAST(&ia->addr)) return; +#ifdef __sun + if (!(ia->flags & IPV6_AF_AUTOCONF) && ia->flags & IPV6_AF_RAPFX) + return; +#endif + ctx = ia->iface->ctx; /* Find the most preferred address to advertise. */ iaf = NULL; @@ -555,45 +559,60 @@ ipv6nd_startexpire(struct interface *ifp ipv6nd_expire, ifp); } -static void -ipv6nd_reachable(struct ra *rap, int flags) +/* + * Neighbour reachability. + * + * RFC 4681 6.2.5 says when a node is no longer a router it MUST + * send a RA with a zero lifetime. + * All OS's I know of set the NA router flag if they are a router + * or not and disregard that they are actively advertising or + * shutting down. If the interface is disabled, it cant't send a NA at all. + * + * As such we CANNOT rely on the NA Router flag and MUST use + * unreachability or receive a RA with a lifetime of zero to remove + * the node as a default router. + */ +void +ipv6nd_neighbour(struct dhcpcd_ctx *ctx, struct in6_addr *addr, bool reachable) { + struct ra *rap, *rapr; + + if (ctx->ra_routers == NULL) + return; + + TAILQ_FOREACH(rap, ctx->ra_routers, next) { + if (IN6_ARE_ADDR_EQUAL(&rap->from, addr)) + break; + } - if (rap->lifetime == 0) + if (rap == NULL || rap->expired) return; - if (flags & IPV6ND_REACHABLE) { - if (rap->expired == 0) + if (reachable) { + if (rap->isreachable) return; loginfox("%s: %s is reachable again", rap->iface->name, rap->sfrom); - rap->expired = 0; + rap->isreachable = true; + return; } else { - if (rap->expired != 0) + if (!rap->isreachable) return; - logwarnx("%s: %s is unreachable, expiring it", + logwarnx("%s: %s is unreachable", rap->iface->name, rap->sfrom); - rap->expired = 1; + rap->isreachable = false; } - rt_build(rap->iface->ctx, AF_INET6); - /* XXX Not really an RA */ - script_runreason(rap->iface, "ROUTERADVERT"); -} - -void -ipv6nd_neighbour(struct dhcpcd_ctx *ctx, struct in6_addr *addr, int flags) -{ - struct ra *rap; - - if (ctx->ra_routers) { - TAILQ_FOREACH(rap, ctx->ra_routers, next) { - if (IN6_ARE_ADDR_EQUAL(&rap->from, addr)) { - ipv6nd_reachable(rap, flags); - break; - } - } + /* If we have no reachable default routers, try and solicit one. */ + TAILQ_FOREACH(rapr, ctx->ra_routers, next) { + if (rap == rapr || rap->iface != rapr->iface) + continue; + if (rapr->isreachable && !rapr->expired && rapr->lifetime) + break; } + + if (rapr == NULL) + ipv6nd_startrs(rap->iface); } const struct ipv6_addr * @@ -944,7 +963,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, struct in6_addr pi_prefix; struct ipv6_addr *ap; struct dhcp_opt *dho; - bool new_rap, new_data; + bool new_rap, new_data, has_address; uint32_t old_lifetime; __printflike(1, 2) void (*logfunc)(const char *, ...); #ifdef IPV6_MANAGETEMPADDR @@ -1026,6 +1045,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, strlcpy(rap->sfrom, sfrom, sizeof(rap->sfrom)); TAILQ_INIT(&rap->addrs); new_rap = true; + rap->isreachable = true; } else new_rap = false; if (rap->data_len == 0) { @@ -1044,7 +1064,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, * routers like to decrease the advertised valid and preferred times * in accordance with the own prefix times which would result in too * much needless log spam. */ - logfunc = new_rap ? loginfox : logdebugx, + logfunc = new_data || !rap->isreachable ? loginfox : logdebugx, logfunc("%s: Router Advertisement from %s", ifp->name, rap->sfrom); clock_gettime(CLOCK_MONOTONIC, &rap->acquired); @@ -1064,9 +1084,10 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, state->retrans = rap->retrans = ntohl(nd_ra->nd_ra_retransmit); } - if (rap->lifetime) - rap->expired = 0; - rap->hasdns = 0; + rap->expired = false; + rap->hasdns = false; + rap->isreachable = true; + has_address = false; #ifdef IPV6_AF_TEMPORARY ipv6_markaddrsstale(ifp, IPV6_AF_TEMPORARY); @@ -1200,6 +1221,9 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, ntohl(pi.nd_opt_pi_valid_time); ap->prefix_pltime = ntohl(pi.nd_opt_pi_preferred_time); + if (ap->prefix_vltime != 0 && + ap->flags & IPV6_AF_AUTOCONF) + has_address = true; #ifdef IPV6_MANAGETEMPADDR /* RFC4941 Section 3.3.3 */ @@ -1266,6 +1290,10 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, } } + if (new_data && !has_address && rap->lifetime && !ipv6_ifanyglobal(ifp)) + logwarnx("%s: no global addresses for default route", + ifp->name); + if (new_rap) add_router(ifp->ctx, rap); @@ -1316,20 +1344,21 @@ nodhcp6: ipv6nd_expirera(ifp); } -int -ipv6nd_hasra(const struct interface *ifp) +bool +ipv6nd_hasralifetime(const struct interface *ifp, bool lifetime) { const struct ra *rap; if (ifp->ctx->ra_routers) { TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) - if (rap->iface == ifp && !rap->expired) - return 1; + if (rap->iface == ifp && !rap->expired && + (!lifetime ||rap->lifetime)) + return true; } - return 0; + return false; } -int +bool ipv6nd_hasradhcp(const struct interface *ifp) { const struct ra *rap; @@ -1338,11 +1367,11 @@ ipv6nd_hasradhcp(const struct interface TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) { if (rap->iface == ifp && !rap->expired && - (rap->flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER))) - return 1; + (rap->flags &(ND_RA_FLAG_MANAGED|ND_RA_FLAG_OTHER))) + return true; } } - return 0; + return false; } static const uint8_t * @@ -1399,7 +1428,7 @@ ipv6nd_env(FILE *fp, const struct interf clock_gettime(CLOCK_MONOTONIC, &now); i = n = 0; TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) { - if (rap->iface != ifp) + if (rap->iface != ifp || rap->expired) continue; i++; snprintf(ndprefix, sizeof(ndprefix), "nd%zu", i); @@ -1503,7 +1532,7 @@ ipv6nd_expirera(void *arg) struct interface *ifp; struct ra *rap, *ran; struct timespec now, lt, expire, next; - bool expired, valid, validone; + bool expired, valid; struct ipv6_addr *ia; size_t len, olen; uint8_t *p; @@ -1522,9 +1551,9 @@ ipv6nd_expirera(void *arg) timespecclear(&next); TAILQ_FOREACH_SAFE(rap, ifp->ctx->ra_routers, next, ran) { - if (rap->iface != ifp) + if (rap->iface != ifp || rap->expired) continue; - valid = validone = false; + valid = false; if (rap->lifetime) { lt.tv_sec = (time_t)rap->lifetime; lt.tv_nsec = 0; @@ -1533,8 +1562,8 @@ ipv6nd_expirera(void *arg) if (!rap->expired) { logwarnx("%s: %s: router expired", ifp->name, rap->sfrom); - rap->expired = expired = 1; rap->lifetime = 0; + expired = true; } } else { valid = true; @@ -1552,7 +1581,7 @@ ipv6nd_expirera(void *arg) if (ia->prefix_vltime == 0) continue; if (ia->prefix_vltime == ND6_INFINITE_LIFETIME) { - validone = true; + valid = true; continue; } lt.tv_sec = (time_t)ia->prefix_vltime; @@ -1576,7 +1605,7 @@ ipv6nd_expirera(void *arg) if (!timespecisset(&next) || timespeccmp(&next, <, >)) next = lt; - validone = true; + valid = true; } } @@ -1626,7 +1655,7 @@ ipv6nd_expirera(void *arg) if (ltime == 0) continue; if (ltime == ND6_INFINITE_LIFETIME) { - validone = true; + valid = true; continue; } @@ -1643,15 +1672,15 @@ ipv6nd_expirera(void *arg) timespeccmp(&next, <, >)) { next = lt; - validone = true; + valid = true; } } - if (valid || validone) + if (valid) continue; - /* Router has expired. Let's not keep a lot of them. - * We should work out if all the options have expired .... */ + /* Router has expired. Let's not keep a lot of them. */ + rap->expired = true; if (++nexpired > EXPIRED_MAX) ipv6nd_free_ra(rap); } @@ -1670,7 +1699,7 @@ void ipv6nd_drop(struct interface *ifp) { struct ra *rap, *ran; - uint8_t expired = 0; + bool expired = false; if (ifp->ctx->ra_routers == NULL) return; @@ -1678,7 +1707,7 @@ ipv6nd_drop(struct interface *ifp) eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); TAILQ_FOREACH_SAFE(rap, ifp->ctx->ra_routers, next, ran) { if (rap->iface == ifp) { - rap->expired = expired = 1; + rap->expired = expired = true; ipv6nd_drop_ra(rap); } } @@ -1690,82 +1719,6 @@ ipv6nd_drop(struct interface *ifp) } static void -ipv6nd_handlena(struct dhcpcd_ctx *ctx, const char *sfrom, - struct interface *ifp, struct icmp6_hdr *icp, size_t len, int hoplimit) -{ - struct nd_neighbor_advert *nd_na; - struct in6_addr nd_na_target; - struct ra *rap; - uint32_t is_router, is_solicited; - char buf[INET6_ADDRSTRLEN]; - const char *taddr; - - if (ifp == NULL) { -#ifdef DEBUG_NS - logdebugx("NA for unexpected interface from %s", sfrom); -#endif - return; - } - - if ((size_t)len < sizeof(struct nd_neighbor_advert)) { - logerrx("%s: IPv6 NA too short from %s", ifp->name, sfrom); - return; - } - - /* RFC 4861 7.1.2 */ - if (hoplimit != 255) { - logerrx("invalid hoplimit(%d) in NA from %s", - hoplimit, sfrom); - return; - } - - nd_na = (struct nd_neighbor_advert *)icp; - is_router = nd_na->nd_na_flags_reserved & ND_NA_FLAG_ROUTER; - is_solicited = nd_na->nd_na_flags_reserved & ND_NA_FLAG_SOLICITED; - taddr = inet_ntop(AF_INET6, &nd_na->nd_na_target, - buf, INET6_ADDRSTRLEN); - - /* nd_na->nd_na_target is not aligned. */ - memcpy(&nd_na_target, &nd_na->nd_na_target, sizeof(nd_na_target)); - if (IN6_IS_ADDR_MULTICAST(&nd_na_target)) { - logerrx("%s: NA multicast address %s (%s)", - ifp->name, taddr, sfrom); - return; - } - - TAILQ_FOREACH(rap, ctx->ra_routers, next) { - if (rap->iface == ifp && - IN6_ARE_ADDR_EQUAL(&rap->from, &nd_na_target)) - break; - } - if (rap == NULL) { -#ifdef DEBUG_NS - logdebugx("%s: unexpected NA from %s for %s", - ifp->name, sfrom, taddr); -#endif - return; - } - -#ifdef DEBUG_NS - logdebugx("%s: %sNA for %s from %s", - ifp->name, is_solicited ? "solicited " : "", taddr, sfrom); -#endif - - /* Node is no longer a router, so remove it from consideration */ - if (!is_router && !rap->expired) { - loginfox("%s: %s not a router (%s)", - ifp->name, taddr, sfrom); - rap->expired = 1; - rt_build(ifp->ctx, AF_INET6); - script_runreason(ifp, "ROUTERADVERT"); - return; - } - - if (is_solicited && is_router && rap->lifetime) - ipv6nd_reachable(rap, IPV6ND_REACHABLE); -} - -static void ipv6nd_handledata(void *arg) { struct dhcpcd_ctx *ctx; @@ -1828,10 +1781,6 @@ ipv6nd_handledata(void *arg) icp = (struct icmp6_hdr *)buf; if (icp->icmp6_code == 0) { switch(icp->icmp6_type) { - case ND_NEIGHBOR_ADVERT: - ipv6nd_handlena(ctx, sfrom, - ifp, icp, (size_t)len, hoplimit); - return; case ND_ROUTER_ADVERT: ipv6nd_handlera(ctx, &from, sfrom, ifp, icp, (size_t)len, hoplimit); Index: src/external/bsd/dhcpcd/dist/src/if-linux.c diff -u src/external/bsd/dhcpcd/dist/src/if-linux.c:1.1.1.14 src/external/bsd/dhcpcd/dist/src/if-linux.c:1.1.1.14.2.1 --- src/external/bsd/dhcpcd/dist/src/if-linux.c:1.1.1.14 Wed Jul 24 09:54:53 2019 +++ src/external/bsd/dhcpcd/dist/src/if-linux.c Thu Sep 5 08:56:55 2019 @@ -680,8 +680,6 @@ link_neigh(struct dhcpcd_ctx *ctx, __unu struct ndmsg *r; struct rtattr *rta; size_t len; - struct in6_addr addr6; - int flags; if (nlm->nlmsg_type != RTM_NEWNEIGH && nlm->nlmsg_type != RTM_DELNEIGH) return 0; @@ -692,14 +690,13 @@ link_neigh(struct dhcpcd_ctx *ctx, __unu rta = (struct rtattr *)RTM_RTA(r); len = RTM_PAYLOAD(nlm); if (r->ndm_family == AF_INET6) { - flags = 0; - if (r->ndm_flags & NTF_ROUTER) - flags |= IPV6ND_ROUTER; - if (nlm->nlmsg_type == RTM_NEWNEIGH && + bool reachable; + struct in6_addr addr6; + + reachable = (nlm->nlmsg_type == RTM_NEWNEIGH && r->ndm_state & (NUD_REACHABLE | NUD_STALE | NUD_DELAY | NUD_PROBE | - NUD_PERMANENT)) - flags |= IPV6ND_REACHABLE; + NUD_PERMANENT)); memset(&addr6, 0, sizeof(addr6)); while (RTA_OK(rta, len)) { switch (rta->rta_type) { @@ -710,7 +707,7 @@ link_neigh(struct dhcpcd_ctx *ctx, __unu } rta = RTA_NEXT(rta, len); } - ipv6nd_neighbour(ctx, &addr6, flags); + ipv6nd_neighbour(ctx, &addr6, reachable); } return 0; @@ -1465,12 +1462,12 @@ bpf_read(struct interface *ifp, int s, v int bpf_attach(int s, void *filter, unsigned int filter_len) { - struct sock_fprog pf; + struct sock_fprog pf = { + .filter = filter, + .len = (unsigned short)filter_len, + }; /* Install the filter. */ - memset(&pf, 0, sizeof(pf)); - pf.filter = filter; - pf.len = (unsigned short)filter_len; return setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &pf, sizeof(pf)); } @@ -1480,7 +1477,9 @@ if_address(unsigned char cmd, const stru struct nlma nlm; struct ifa_cacheinfo cinfo; int retval = 0; +#ifdef IFA_F_NOPREFIXROUTE uint32_t flags = 0; +#endif memset(&nlm, 0, sizeof(nlm)); nlm.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); @@ -1507,8 +1506,8 @@ if_address(unsigned char cmd, const stru #ifdef IFA_F_NOPREFIXROUTE if (nlm.ifa.ifa_prefixlen < 32) flags |= IFA_F_NOPREFIXROUTE; -#endif add_attr_32(&nlm.hdr, sizeof(nlm), IFA_FLAGS, flags); +#endif add_attr_l(&nlm.hdr, sizeof(nlm), IFA_BROADCAST, &ia->brd.s_addr, sizeof(ia->brd.s_addr)); @@ -1542,7 +1541,9 @@ if_address6(unsigned char cmd, const str { struct nlma nlm; struct ifa_cacheinfo cinfo; +#if defined(IFA_F_MANAGETEMPADDR) || defined(IFA_F_NOPREFIXROUTE) uint32_t flags = 0; +#endif memset(&nlm, 0, sizeof(nlm)); nlm.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); @@ -1582,7 +1583,9 @@ if_address6(unsigned char cmd, const str if (!IN6_IS_ADDR_LINKLOCAL(&ia->addr)) flags |= IFA_F_NOPREFIXROUTE; #endif +#if defined(IFA_F_MANAGETEMPADDR) || defined(IFA_F_NOPREFIXROUTE) add_attr_32(&nlm.hdr, sizeof(nlm), IFA_FLAGS, flags); +#endif memset(&cinfo, 0, sizeof(cinfo)); cinfo.ifa_prefered = ia->prefix_pltime; Index: src/external/bsd/dhcpcd/dist/src/if.c diff -u src/external/bsd/dhcpcd/dist/src/if.c:1.1.1.14 src/external/bsd/dhcpcd/dist/src/if.c:1.1.1.14.2.1 --- src/external/bsd/dhcpcd/dist/src/if.c:1.1.1.14 Wed Jul 24 09:54:53 2019 +++ src/external/bsd/dhcpcd/dist/src/if.c Thu Sep 5 08:56:55 2019 @@ -72,6 +72,12 @@ #include "ipv6nd.h" #include "logerr.h" +#ifdef __sun +/* It has the ioctl, but the member is missing from the struct? + * No matter, our getifaddrs foo in if-sun.c will DTRT. */ +#undef SIOCGIFHWADDR +#endif + void if_free(struct interface *ifp) { @@ -235,6 +241,7 @@ if_learnaddrs(struct dhcpcd_ctx *ctx, st case AF_INET6: sin6 = (void *)ifa->ifa_addr; net6 = (void *)ifa->ifa_netmask; + #ifdef __KAME__ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) /* Remove the scope from the address */ @@ -307,17 +314,16 @@ if_discover(struct dhcpcd_ctx *ctx, stru struct if_spec spec; #ifdef AF_LINK const struct sockaddr_dl *sdl; -#ifdef SIOCGIFPRIORITY - struct ifreq ifr; -#endif #ifdef IFLR_ACTIVE struct if_laddrreq iflr = { .flags = IFLR_PREFIX }; int link_fd; #endif - #elif AF_PACKET const struct sockaddr_ll *sll; #endif +#if defined(SIOCGIFPRIORITY) || defined(SIOCGIFHWADDR) + struct ifreq ifr; +#endif if ((ifs = malloc(sizeof(*ifs))) == NULL) { logerr(__func__); @@ -512,10 +518,21 @@ if_discover(struct dhcpcd_ctx *ctx, stru memcpy(ifp->hwaddr, sll->sll_addr, ifp->hwlen); #endif } -#ifdef __linux__ - /* PPP addresses on Linux don't have hardware addresses */ - else - ifp->index = if_nametoindex(ifp->name); +#ifdef SIOCGIFHWADDR + else { + /* This is a huge bug in getifaddrs(3) as there + * is no reason why this can't be returned in + * ifa_addr. */ + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifa->ifa_name, + sizeof(ifr.ifr_name)); + if (ioctl(ctx->pf_inet_fd, SIOCGIFHWADDR, &ifr) == -1) + logerr("%s: SIOCGIFHWADDR", ifa->ifa_name); + ifp->family = ifr.ifr_hwaddr.sa_family; + if (ioctl(ctx->pf_inet_fd, SIOCGIFINDEX, &ifr) == -1) + logerr("%s: SIOCGIFINDEX", ifa->ifa_name); + ifp->index = (unsigned int)ifr.ifr_ifindex; + } #endif /* Ensure hardware address is valid. */ @@ -536,6 +553,9 @@ if_discover(struct dhcpcd_ctx *ctx, stru #ifdef ARPHRD_PPP case ARPHRD_PPP: #endif +#ifdef ARPHRD_NONE + case ARPHRD_NONE: +#endif /* We don't warn for supported families */ break; Index: src/external/bsd/dhcpcd/dist/src/if-options.c diff -u src/external/bsd/dhcpcd/dist/src/if-options.c:1.16 src/external/bsd/dhcpcd/dist/src/if-options.c:1.16.2.1 --- src/external/bsd/dhcpcd/dist/src/if-options.c:1.16 Tue Jul 30 10:25:03 2019 +++ src/external/bsd/dhcpcd/dist/src/if-options.c Thu Sep 5 08:56:55 2019 @@ -2062,7 +2062,7 @@ err_sla: ifo->auth.options &= ~DHCPCD_AUTH_REQUIRE; break; case O_DHCP: - ifo->options |= DHCPCD_DHCP | DHCPCD_IPV4; + ifo->options |= DHCPCD_DHCP | DHCPCD_WANTDHCP | DHCPCD_IPV4; break; case O_NODHCP: ifo->options &= ~DHCPCD_DHCP; @@ -2281,7 +2281,7 @@ default_config(struct dhcpcd_ctx *ctx) ifo->script = UNCONST(default_script); ifo->metric = -1; ifo->auth.options |= DHCPCD_AUTH_REQUIRE; - rb_tree_init(&ifo->routes, &rt_compare_proto_ops); + rb_tree_init(&ifo->routes, &rt_compare_list_ops); #ifdef AUTH TAILQ_INIT(&ifo->auth.tokens); #endif Index: src/external/bsd/dhcpcd/dist/src/if-options.h diff -u src/external/bsd/dhcpcd/dist/src/if-options.h:1.1.1.9 src/external/bsd/dhcpcd/dist/src/if-options.h:1.1.1.9.2.1 --- src/external/bsd/dhcpcd/dist/src/if-options.h:1.1.1.9 Wed Jul 24 09:54:53 2019 +++ src/external/bsd/dhcpcd/dist/src/if-options.h Thu Sep 5 08:56:55 2019 @@ -61,7 +61,7 @@ #define DHCPCD_ARP (1ULL << 0) #define DHCPCD_RELEASE (1ULL << 1) -// unused (1ULL << 2) +#define DHCPCD_RTBUILD (1ULL << 2) #define DHCPCD_GATEWAY (1ULL << 3) #define DHCPCD_STATIC (1ULL << 4) #define DHCPCD_DEBUG (1ULL << 5) @@ -110,7 +110,7 @@ #define DHCPCD_DHCP6 (1ULL << 50) #define DHCPCD_IF_UP (1ULL << 51) #define DHCPCD_INFORM6 (1ULL << 52) -// unused (1ULL << 53) +#define DHCPCD_WANTDHCP (1ULL << 53) #define DHCPCD_IPV6RA_AUTOCONF (1ULL << 54) #define DHCPCD_ROUTER_HOST_ROUTE_WARNED (1ULL << 55) #define DHCPCD_LASTLEASE_EXTEND (1ULL << 56) Index: src/external/bsd/dhcpcd/dist/src/ipv4.h diff -u src/external/bsd/dhcpcd/dist/src/ipv4.h:1.1.1.9 src/external/bsd/dhcpcd/dist/src/ipv4.h:1.1.1.9.2.1 --- src/external/bsd/dhcpcd/dist/src/ipv4.h:1.1.1.9 Tue Jul 30 10:23:09 2019 +++ src/external/bsd/dhcpcd/dist/src/ipv4.h Thu Sep 5 08:56:55 2019 @@ -63,8 +63,9 @@ * While it supports DaD, to seems to only expose IFF_DUPLICATE * so we have no way of knowing if it's tentative or not. * I don't even know if Solaris has any special treatment for tentative. */ +# define IN_IFF_TENTATIVE 0x01 # define IN_IFF_DUPLICATED 0x02 -# define IN_IFF_NOTUSEABLE IN_IFF_DUPLICATED +# define IN_IFF_DETACHED 0x00 #endif #ifdef IN_IFF_TENTATIVE Index: src/external/bsd/dhcpcd/dist/src/if-sun.c diff -u src/external/bsd/dhcpcd/dist/src/if-sun.c:1.1.1.10 src/external/bsd/dhcpcd/dist/src/if-sun.c:1.1.1.10.2.1 --- src/external/bsd/dhcpcd/dist/src/if-sun.c:1.1.1.10 Wed Jul 24 09:54:53 2019 +++ src/external/bsd/dhcpcd/dist/src/if-sun.c Thu Sep 5 08:56:55 2019 @@ -106,10 +106,27 @@ struct rtm char buffer[sizeof(struct sockaddr_storage) * RTAX_MAX]; }; +static int if_plumb(int, const struct dhcpcd_ctx *, int, const char *); + int -if_init(__unused struct interface *ifp) +if_init(struct interface *ifp) { +#ifdef INET + if (if_plumb(RTM_NEWADDR, ifp->ctx, AF_INET, ifp->name) == -1 && + errno != EEXIST) + return -1; +#endif + +#ifdef INET6 + if (if_plumb(RTM_NEWADDR, ifp->ctx, AF_INET6, ifp->name) == -1 && + errno != EEXIST) + return -1; +#endif + + if (ifp->index == 0) + ifp->index = if_nametoindex(ifp->name); + return 0; } @@ -622,13 +639,12 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct { const struct sockaddr *rti_info[RTAX_MAX]; - if (~rtm->rtm_addrs & RTA_DST) + if (~rtm->rtm_addrs & RTA_DST) { + errno = EINVAL; return -1; + } - /* We have already checked that at least one address must be - * present after the rtm structure. */ - /* coverity[ptr_arith] */ - if (get_addrs(rtm->rtm_addrs, rtm + 1, + if (get_addrs(rtm->rtm_addrs, (const char *)rtm + sizeof(*rtm), rtm->rtm_msglen - sizeof(*rtm), rti_info) == -1) return -1; @@ -638,10 +654,21 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct COPYSA(&rt->rt_dest, rti_info[RTAX_DST]); if (rtm->rtm_addrs & RTA_NETMASK) COPYSA(&rt->rt_netmask, rti_info[RTAX_NETMASK]); - /* dhcpcd likes an unspecified gateway to indicate via the link. */ - if (rtm->rtm_addrs & RTA_GATEWAY && - rti_info[RTAX_GATEWAY]->sa_family != AF_LINK) - COPYSA(&rt->rt_gateway, rti_info[RTAX_GATEWAY]); + + /* dhcpcd likes an unspecified gateway to indicate via the link. + * However we need to know if gateway was a link with an address. */ + if (rtm->rtm_addrs & RTA_GATEWAY) { + if (rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) { + const struct sockaddr_dl *sdl; + + sdl = (const struct sockaddr_dl*) + (const void *)rti_info[RTAX_GATEWAY]; + if (sdl->sdl_alen != 0) + rt->rt_dflags |= RTDF_GATELINK; + } else if (rtm->rtm_flags & RTF_GATEWAY) + COPYSA(&rt->rt_gateway, rti_info[RTAX_GATEWAY]); + } + if (rtm->rtm_addrs & RTA_SRC) COPYSA(&rt->rt_ifa, rti_info[RTAX_SRC]); rt->rt_mtu = (unsigned int)rtm->rtm_rmx.rmx_mtu; @@ -655,6 +682,9 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct else rt->rt_ifp = if_findsa(ctx, rti_info[RTAX_DST]); + if (rt->rt_ifp == NULL && rtm->rtm_type == RTM_MISS) + rt->rt_ifp = if_loopback(ctx); + if (rt->rt_ifp == NULL) { errno = ESRCH; return -1; @@ -757,21 +787,23 @@ if_finishrt(struct dhcpcd_ctx *ctx, stru return 0; } -static uint64_t -if_addrflags0(int fd, const char *ifname, const struct sockaddr *sa) +static int +if_addrflags0(int fd, int af, const char *ifname) { struct lifreq lifr; + int flags; memset(&lifr, 0, sizeof(lifr)); strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); if (ioctl(fd, SIOCGLIFFLAGS, &lifr) == -1) - return 0; - if (ioctl(fd, SIOCGLIFADDR, &lifr) == -1) - return 0; - if (sa_cmp(sa, (struct sockaddr *)&lifr.lifr_addr) != 0) - return 0; + return -1; - return lifr.lifr_flags; + flags = 0; + if (lifr.lifr_flags & IFF_DUPLICATE) + flags |= af == AF_INET6 ? IN6_IFF_DUPLICATED:IN_IFF_DUPLICATED; + else if (!(lifr.lifr_flags & IFF_UP)) + flags |= af == AF_INET6 ? IN6_IFF_TENTATIVE:IN_IFF_TENTATIVE; + return flags; } static int @@ -785,42 +817,29 @@ if_rtm(struct dhcpcd_ctx *ctx, const str return -1; } - sa = (const void *)(rtm + 1); - switch (sa->sa_family) { + if (if_copyrt(ctx, &rt, rtm) == -1 && errno != ESRCH) + return -1; + #ifdef INET6 - case AF_INET6: - if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY)) - break; - /* - * BSD announces host routes. - * But does this work on Solaris? - * As such, we should be notified of reachability by its - * existance with a hardware address. - */ - if (rtm->rtm_flags & (RTF_HOST)) { - const struct sockaddr *rti_info[RTAX_MAX]; - struct in6_addr dst6; - struct sockaddr_dl sdl; + /* + * BSD announces host routes. + * As such, we should be notified of reachability by its + * existance with a hardware address. + * Ensure we don't call this for a newly incomplete state. + */ + if (rt.rt_dest.sa_family == AF_INET6 && + (rt.rt_flags & RTF_HOST || rtm->rtm_type == RTM_MISS) && + !(rtm->rtm_type == RTM_ADD && !(rt.rt_dflags & RTDF_GATELINK))) + { + bool reachable; - if (get_addrs(rtm->rtm_addrs, sa, - rtm->rtm_msglen - sizeof(*rtm), rti_info) == -1) - return -1; - COPYOUT6(dst6, rti_info[RTAX_DST]); - if (rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) - memcpy(&sdl, rti_info[RTAX_GATEWAY], - sizeof(sdl)); - else - sdl.sdl_alen = 0; - ipv6nd_neighbour(ctx, &dst6, - rtm->rtm_type != RTM_DELETE && sdl.sdl_alen ? - IPV6ND_REACHABLE : 0); - } - break; + reachable = (rtm->rtm_type == RTM_ADD || + rtm->rtm_type == RTM_CHANGE) && + rt.rt_dflags & RTDF_GATELINK; + ipv6nd_neighbour(ctx, &rt.rt_ss_dest.sin6.sin6_addr, reachable); } #endif - if (if_copyrt(ctx, &rt, rtm) == -1 && errno != ESRCH) - return -1; if (if_finishrt(ctx, &rt) == -1) return -1; rt_recvrt(rtm->rtm_type, &rt, rtm->rtm_pid); @@ -885,10 +904,7 @@ if_ifa(struct dhcpcd_ctx *ctx, const str if (~ifam->ifam_addrs & RTA_IFA) return 0; - /* We have already checked that at least one address must be - * present after the ifam structure. */ - /* coverity[ptr_arith] */ - if (get_addrs(ifam->ifam_addrs, ifam + 1, + if (get_addrs(ifam->ifam_addrs, (const char *)ifam + sizeof(*ifam), ifam->ifam_msglen - sizeof(*ifam), rti_info) == -1) return -1; sa = rti_info[RTAX_IFA]; @@ -949,7 +965,7 @@ if_ifa(struct dhcpcd_ctx *ctx, const str if (if_getbrdaddr(ctx, ifalias, &bcast) == -1) return 0; } - flags = if_addrflags(ifp, &addr, ifalias); + flags = if_addrflags(ifp, NULL, ifalias); if (ifam->ifam_type == RTM_DELADDR) { if (flags != -1) return 0; @@ -982,7 +998,7 @@ if_ifa(struct dhcpcd_ctx *ctx, const str return 0; strlcpy(ifalias, ia->alias, sizeof(ifalias)); } - flags = if_addrflags6(ifp, &addr6, ifalias); + flags = if_addrflags6(ifp, NULL, ifalias); if (ifam->ifam_type == RTM_DELADDR) { if (flags != -1) return 0; @@ -1038,7 +1054,8 @@ if_dispatch(struct dhcpcd_ctx *ctx, cons return if_ifinfo(ctx, (const void *)rtm); case RTM_ADD: /* FALLTHROUGH */ case RTM_CHANGE: /* FALLTHROUGH */ - case RTM_DELETE: + case RTM_DELETE: /* FALLTHROUGH */ + case RTM_MISS: return if_rtm(ctx, (const void *)rtm); case RTM_CHGADDR: /* FALLTHROUGH */ case RTM_DELADDR: /* FALLTHROUGH */ @@ -1053,20 +1070,28 @@ int if_handlelink(struct dhcpcd_ctx *ctx) { struct rtm rtm; - struct iovec iov = { .iov_base = &rtm, .iov_len = sizeof(rtm) }; - struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1 }; ssize_t len; - if ((len = recvmsg(ctx->link_fd, &msg, 0)) == -1) - return -1; + len = read(ctx->link_fd, &rtm, sizeof(rtm)); if (len == -1) return -1; if (len == 0) return 0; - if (len < rtm.hdr.rtm_msglen) { + if ((size_t)len < sizeof(rtm.hdr.rtm_msglen) || + len != rtm.hdr.rtm_msglen) + { errno = EINVAL; return -1; } + /* + * Coverity thinks that the data could be tainted from here. + * I have no idea how because the length of the data we read + * is guarded by len and checked to match rtm_msglen. + * The issue seems to be related to extracting the addresses + * at the end of the header, but seems to have no issues with the + * equivalent call in if_initrt. + */ + /* coverity[tainted_data] */ return if_dispatch(ctx, &rtm.hdr); } @@ -1087,19 +1112,41 @@ if_octetstr(char *buf, const Octet_t *o, } static int +if_setflags(int fd, const char *ifname, uint64_t flags) +{ + struct lifreq lifr = { .lifr_addrlen = 0 }; + + strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); + if (ioctl(fd, SIOCGLIFFLAGS, &lifr) == -1) + return -1; + if ((lifr.lifr_flags & flags) != flags) { + lifr.lifr_flags |= flags; + if (ioctl(fd, SIOCSLIFFLAGS, &lifr) == -1) + return -1; + } + return 0; +} + +static int if_addaddr(int fd, const char *ifname, struct sockaddr_storage *addr, struct sockaddr_storage *mask, - struct sockaddr_storage *brd) + struct sockaddr_storage *brd, uint8_t plen) { - struct lifreq lifr; + struct lifreq lifr = { .lifr_addrlen = plen }; - memset(&lifr, 0, sizeof(lifr)); strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); /* First assign the netmask. */ lifr.lifr_addr = *mask; - if (ioctl(fd, SIOCSLIFNETMASK, &lifr) == -1) - return -1; + if (addr == NULL) { + lifr.lifr_addrlen = plen; + if (ioctl(fd, SIOCSLIFSUBNET, &lifr) == -1) + return -1; + goto up; + } else { + if (ioctl(fd, SIOCSLIFNETMASK, &lifr) == -1) + return -1; + } /* Then assign the address. */ lifr.lifr_addr = *addr; @@ -1113,15 +1160,39 @@ if_addaddr(int fd, const char *ifname, return -1; } - /* Now bring it up. */ - if (ioctl(fd, SIOCGLIFFLAGS, &lifr) == -1) - return -1; - if (!(lifr.lifr_flags & IFF_UP)) { - lifr.lifr_flags |= IFF_UP; - if (ioctl(fd, SIOCSLIFFLAGS, &lifr) == -1) - return -1; +up: + return if_setflags(fd, ifname, IFF_UP); +} + +static int +if_getaf_fd(const struct dhcpcd_ctx *ctx, int af) +{ + + if (af == AF_INET) + return ctx->pf_inet_fd; + if (af == AF_INET6) { + struct priv *priv; + + priv = (struct priv *)ctx->priv; + return priv->pf_inet6_fd; } + errno = EAFNOSUPPORT; + return -1; +} + +int +if_getsubnet(struct dhcpcd_ctx *ctx, const char *ifname, int af, + void *subnet, size_t subnet_len) +{ + struct lifreq lifr = { .lifr_addrlen = 0 }; + int fd; + + fd = if_getaf_fd(ctx, af); + strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); + if (ioctl(fd, SIOCGLIFSUBNET, &lifr) == -1) + return -1; + memcpy(subnet, &lifr.lifr_addr, MIN(subnet_len,sizeof(lifr.lifr_addr))); return 0; } @@ -1134,14 +1205,7 @@ if_plumblif(int cmd, const struct dhcpcd memset(&lifr, 0, sizeof(lifr)); strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); lifr.lifr_addr.ss_family = af; - if (af == AF_INET) - s = ctx->pf_inet_fd; - else { - struct priv *priv; - - priv = (struct priv *)ctx->priv; - s = priv->pf_inet6_fd; - } + s = if_getaf_fd(ctx, af); return ioctl(s, cmd == RTM_NEWADDR ? SIOCLIFADDIF : SIOCLIFREMOVEIF, &lifr) == -1 && errno != EEXIST ? -1 : 0; @@ -1161,23 +1225,18 @@ if_plumbif(const struct dhcpcd_ctx *ctx, if (if_nametospec(ifname, &spec) == -1) return -1; + af_fd = if_getaf_fd(ctx, af); + switch (af) { case AF_INET: flags = IFF_IPV4; - af_fd = ctx->pf_inet_fd; udp_dev = UDP_DEV_NAME; break; case AF_INET6: - { - struct priv *priv; - /* We will take care of setting the link local address. */ flags = IFF_IPV6 | IFF_NOLINKLOCAL; - priv = (struct priv *)ctx->priv; - af_fd = priv->pf_inet6_fd; udp_dev = UDP6_DEV_NAME; break; - } default: errno = EPROTONOSUPPORT; return -1; @@ -1271,28 +1330,9 @@ if_unplumbif(const struct dhcpcd_ctx *ct /* For the time being, don't unplumb the interface, just * set the address to zero. */ - switch (af) { -#ifdef INET - case AF_INET: - fd = ctx->pf_inet_fd; - break; -#endif -#ifdef INET6 - case AF_INET6: - { - struct priv *priv; - - priv = (struct priv *)ctx->priv; - fd = priv->pf_inet6_fd; - break; - } -#endif - default: - errno = EAFNOSUPPORT; - return -1; - } + fd = if_getaf_fd(ctx, af); return if_addaddr(fd, ifname, &addr, &addr, - af == AF_INET ? &addr : NULL); + af == AF_INET ? &addr : NULL, 0); } static int @@ -1567,9 +1607,11 @@ if_address(unsigned char cmd, const stru struct sockaddr sa; struct sockaddr_storage ss; } addr, mask, brd; + int fd = ia->iface->ctx->pf_inet_fd; /* Either remove the alias or ensure it exists. */ - if (if_plumb(cmd, ia->iface->ctx, AF_INET, ia->alias) == -1) + if (if_plumb(cmd, ia->iface->ctx, AF_INET, ia->alias) == -1 && + errno != EEXIST) return -1; if (cmd == RTM_DELADDR) @@ -1586,26 +1628,15 @@ if_address(unsigned char cmd, const stru sa_in_init(&addr.sa, &ia->addr); sa_in_init(&mask.sa, &ia->mask); sa_in_init(&brd.sa, &ia->brd); - return if_addaddr(ia->iface->ctx->pf_inet_fd, ia->alias, - &addr.ss, &mask.ss, &brd.ss); + return if_addaddr(fd, ia->alias, &addr.ss, &mask.ss, &brd.ss, 0); } int -if_addrflags(const struct interface *ifp, const struct in_addr *addr, +if_addrflags(const struct interface *ifp, __unused const struct in_addr * ia, const char *alias) { - union sa_ss ss; - uint64_t aflags; - int flags; - - sa_in_init(&ss.sa, addr); - aflags = if_addrflags0(ifp->ctx->pf_inet_fd, alias, &ss.sa); - if (aflags == 0) - return -1; - flags = 0; - if (aflags & IFF_DUPLICATE) - flags |= IN_IFF_DUPLICATED; - return flags; + + return if_addrflags0(ifp->ctx->pf_inet_fd, AF_INET, alias); } #endif @@ -1619,11 +1650,11 @@ if_address6(unsigned char cmd, const str struct sockaddr_in6 sin6; struct sockaddr_storage ss; } addr, mask; - const struct priv *priv; - int r; + int fd, r; /* Either remove the alias or ensure it exists. */ - if (if_plumb(cmd, ia->iface->ctx, AF_INET6, ia->alias) == -1) + if (if_plumb(cmd, ia->iface->ctx, AF_INET6, ia->alias) == -1 && + errno != EEXIST) return -1; if (cmd == RTM_DELADDR) @@ -1634,34 +1665,34 @@ if_address6(unsigned char cmd, const str return -1; } - sa_in6_init(&addr.sa, &ia->addr); - mask.sin6.sin6_family = AF_INET6; - ipv6_mask(&mask.sin6.sin6_addr, ia->prefix_len); - priv = (const struct priv *)ia->iface->ctx->priv; - r = if_addaddr(priv->pf_inet6_fd, ia->alias, &addr.ss, &mask.ss, NULL); + fd = if_getaf_fd(ia->iface->ctx, AF_INET6); + + if (!(ia->flags & IPV6_AF_AUTOCONF) && ia->flags & IPV6_AF_RAPFX) { + if (if_setflags(fd, ia->alias, IFF_NOLOCAL) ==-1) + return -1; + sa_in6_init(&mask.sa, &ia->prefix); + r = if_addaddr(fd, ia->alias, + NULL, &mask.ss, NULL, ia->prefix_len); + } else { + sa_in6_init(&addr.sa, &ia->addr); + mask.sin6.sin6_family = AF_INET6; + ipv6_mask(&mask.sin6.sin6_addr, ia->prefix_len); + r = if_addaddr(fd, ia->alias, + &addr.ss, &mask.ss, NULL, ia->prefix_len); + } if (r == -1 && errno == EEXIST) return 0; return r; } int -if_addrflags6(const struct interface *ifp, const struct in6_addr *addr, +if_addrflags6(const struct interface *ifp, __unused const struct in6_addr *ia, const char *alias) { - struct priv *priv; - union sa_ss ss; - uint64_t aflags; - int flags; + int fd; - priv = (struct priv *)ifp->ctx->priv; - sa_in6_init(&ss.sa, addr); - aflags = if_addrflags0(priv->pf_inet6_fd, alias, &ss.sa); - if (aflags == 0) - return -1; - flags = 0; - if (aflags & IFF_DUPLICATE) - flags |= IN6_IFF_DUPLICATED; - return flags; + fd = if_getaf_fd(ifp->ctx, AF_INET6); + return if_addrflags0(fd, AF_INET6, alias); } int Index: src/external/bsd/dhcpcd/dist/src/if.h diff -u src/external/bsd/dhcpcd/dist/src/if.h:1.1.1.10 src/external/bsd/dhcpcd/dist/src/if.h:1.1.1.10.2.1 --- src/external/bsd/dhcpcd/dist/src/if.h:1.1.1.10 Tue Jul 30 10:23:09 2019 +++ src/external/bsd/dhcpcd/dist/src/if.h Thu Sep 5 08:56:55 2019 @@ -107,6 +107,7 @@ struct ifaddrs; int if_getifaddrs(struct ifaddrs **); #define getifaddrs if_getifaddrs +int if_getsubnet(struct dhcpcd_ctx *, const char *, int, void *, size_t); #endif int if_getflags(struct interface *ifp); Index: src/external/bsd/dhcpcd/dist/src/ipv6nd.h diff -u src/external/bsd/dhcpcd/dist/src/ipv6nd.h:1.1.1.10 src/external/bsd/dhcpcd/dist/src/ipv6nd.h:1.1.1.10.2.1 --- src/external/bsd/dhcpcd/dist/src/ipv6nd.h:1.1.1.10 Wed Jul 24 09:54:55 2019 +++ src/external/bsd/dhcpcd/dist/src/ipv6nd.h Thu Sep 5 08:56:55 2019 @@ -51,8 +51,9 @@ struct ra { uint32_t retrans; uint32_t mtu; struct ipv6_addrhead addrs; - uint8_t hasdns; - uint8_t expired; + bool hasdns; + bool expired; + bool isreachable; }; TAILQ_HEAD(ra_head, ra); @@ -90,9 +91,6 @@ struct rs_state { #define RETRANS_TIMER 1000 /* milliseconds */ #define DELAY_FIRST_PROBE_TIME 5 /* seconds */ -#define IPV6ND_REACHABLE (1 << 0) -#define IPV6ND_ROUTER (1 << 1) - void ipv6nd_printoptions(const struct dhcpcd_ctx *, const struct dhcp_opt *, size_t); void ipv6nd_startrs(struct interface *); @@ -103,14 +101,15 @@ struct ipv6_addr *ipv6nd_findaddr(struct const struct in6_addr *, unsigned int); ssize_t ipv6nd_free(struct interface *); void ipv6nd_expirera(void *arg); -int ipv6nd_hasra(const struct interface *); -int ipv6nd_hasradhcp(const struct interface *); +bool ipv6nd_hasralifetime(const struct interface *, bool); +#define ipv6nd_hasra(i) ipv6nd_hasralifetime((i), false) +bool ipv6nd_hasradhcp(const struct interface *); void ipv6nd_handleifa(int, struct ipv6_addr *, pid_t); int ipv6nd_dadcompleted(const struct interface *); void ipv6nd_advertise(struct ipv6_addr *); void ipv6nd_startexpire(struct interface *); void ipv6nd_drop(struct interface *); -void ipv6nd_neighbour(struct dhcpcd_ctx *, struct in6_addr *, int); +void ipv6nd_neighbour(struct dhcpcd_ctx *, struct in6_addr *, bool); #endif /* INET6 */ #endif /* IPV6ND_H */ Index: src/external/bsd/dhcpcd/dist/src/script.c diff -u src/external/bsd/dhcpcd/dist/src/script.c:1.1.1.10 src/external/bsd/dhcpcd/dist/src/script.c:1.1.1.10.2.1 --- src/external/bsd/dhcpcd/dist/src/script.c:1.1.1.10 Tue Jul 30 10:23:09 2019 +++ src/external/bsd/dhcpcd/dist/src/script.c Thu Sep 5 08:56:55 2019 @@ -33,6 +33,7 @@ #include <netinet/in.h> #include <arpa/inet.h> +#include <assert.h> #include <ctype.h> #include <errno.h> #include <signal.h> @@ -172,12 +173,12 @@ efprintf(FILE *fp, const char *fmt, ...) return r; } -static ssize_t +static long make_env(const struct interface *ifp, const char *reason) { struct dhcpcd_ctx *ctx = ifp->ctx; FILE *fp; - char **env, **envp, *buf, *bufp, *endp, *path; + char **env, **envp, *bufp, *endp, *path; size_t nenv; long buf_pos, i; int protocol = PROTO_LINK; @@ -458,31 +459,38 @@ dumplease: logerr(__func__); goto eexit; } -#ifdef HAVE_OPEN_MEMSTREAM - buf = ctx->script_buf; -#else + +#ifndef HAVE_OPEN_MEMSTREAM size_t buf_len = (size_t)buf_pos; if (ctx->script_buflen < buf_len) { - buf = realloc(ctx->script_buf, buf_len); + char *buf = realloc(ctx->script_buf, buf_len); if (buf == NULL) goto eexit; ctx->script_buf = buf; ctx->script_buflen = buf_len; } - buf = ctx->script_buf; rewind(fp); - if (fread(buf, sizeof(char), buf_len, fp) != buf_len) + if (fread(ctx->script_buf, sizeof(char), buf_len, fp) != buf_len) goto eexit; fclose(fp); fp = NULL; #endif + /* Count the terminated env strings. + * Assert that the terminations are correct. */ nenv = 0; - endp = buf + buf_pos; - for (bufp = buf; bufp < endp; bufp++) { - if (*bufp == '\0') + endp = ctx->script_buf + buf_pos; + for (bufp = ctx->script_buf; bufp < endp; bufp++) { + if (*bufp == '\0') { +#ifndef NDEBUG + if (bufp + 1 < endp) + assert(*(bufp + 1) != '\0'); +#endif nenv++; + } } + assert(*(bufp - 1) == '\0'); + if (ctx->script_envlen < nenv) { env = reallocarray(ctx->script_env, nenv + 1, sizeof(*env)); if (env == NULL) @@ -490,7 +498,8 @@ dumplease: ctx->script_env = env; ctx->script_envlen = nenv; } - bufp = buf; + + bufp = ctx->script_buf; envp = ctx->script_env; *envp++ = bufp++; endp--; /* Avoid setting the last \0 to an invalid pointer */ @@ -500,7 +509,7 @@ dumplease: } *envp = NULL; - return (ssize_t)nenv; + return buf_pos - 1; eexit: logerr(__func__); @@ -516,10 +525,12 @@ send_interface1(struct fd_list *fd, cons const char *reason) { struct dhcpcd_ctx *ctx = ifp->ctx; + long len; - if (make_env(ifp, reason) == -1) + len = make_env(ifp, reason); + if (len == -1) return -1; - return control_queue(fd, ctx->script_buf, ctx->script_buflen, 1); + return control_queue(fd, ctx->script_buf, (size_t)len, 1); } int @@ -636,8 +647,8 @@ send_listeners: TAILQ_FOREACH(fd, &ctx->control_fds, next) { if (!(fd->flags & FD_LISTEN)) continue; - if (control_queue(fd, ctx->script_buf, ctx->script_buflen, 1) - == -1) + if (control_queue(fd, ctx->script_buf, ctx->script_buflen, + true) == -1) logerr("%s: control_queue", __func__); else status = 1; Index: src/external/bsd/dhcpcd/dist/src/ipv4.c diff -u src/external/bsd/dhcpcd/dist/src/ipv4.c:1.1.1.16 src/external/bsd/dhcpcd/dist/src/ipv4.c:1.1.1.16.2.1 --- src/external/bsd/dhcpcd/dist/src/ipv4.c:1.1.1.16 Tue Jul 30 10:23:09 2019 +++ src/external/bsd/dhcpcd/dist/src/ipv4.c Thu Sep 5 08:56:55 2019 @@ -268,13 +268,12 @@ inet_dhcproutes(rb_tree_t *routes, struc rb_tree_init(&nroutes, &rt_compare_proto_ops); /* First, add a subnet route. */ - if (!(ifp->flags & IFF_POINTOPOINT) && + if (state->addr->mask.s_addr != INADDR_ANY #ifndef BSD /* BSD adds a route in this instance */ - state->addr->mask.s_addr != INADDR_BROADCAST && + && state->addr->mask.s_addr != INADDR_BROADCAST #endif - state->addr->mask.s_addr != INADDR_ANY) - { + ) { if ((rt = rt_new(ifp)) == NULL) return -1; rt->rt_dflags |= RTDF_IFA_ROUTE; @@ -680,8 +679,10 @@ ipv4_addaddr(struct interface *ifp, cons logdebugx("%s: aliased %s", ia->alias, ia->saddr); #endif - logdebugx("%s: adding IP address %s broadcast %s", - ifp->name, ia->saddr, inet_ntoa(*bcast)); + logdebugx("%s: adding IP address %s %s %s", + ifp->name, ia->saddr, + ifp->flags & IFF_POINTOPOINT ? "destination" : "broadcast", + inet_ntoa(*bcast)); if (if_address(RTM_NEWADDR, ia) == -1) { if (errno != EEXIST) logerr("%s: if_addaddress", @@ -742,7 +743,8 @@ ipv4_applyaddr(void *arg) #ifdef ARP /* Announce the preferred address to * kick ARP caches. */ - arp_announceaddr(ifp->ctx, &lease->addr); + if (!(ifp->flags & IFF_NOARP)) + arp_announceaddr(ifp->ctx,&lease->addr); #endif } script_runreason(ifp, state->reason); @@ -804,7 +806,8 @@ ipv4_applyaddr(void *arg) rt_build(ifp->ctx, AF_INET); #ifdef ARP - arp_announceaddr(ifp->ctx, &state->addr->addr); + if (!(ifp->flags & IFF_NOARP)) + arp_announceaddr(ifp->ctx, &state->addr->addr); #endif if (state->state == DHS_BOUND) { Index: src/external/bsd/dhcpcd/dist/src/ipv6.c diff -u src/external/bsd/dhcpcd/dist/src/ipv6.c:1.3 src/external/bsd/dhcpcd/dist/src/ipv6.c:1.3.2.1 --- src/external/bsd/dhcpcd/dist/src/ipv6.c:1.3 Tue Jul 30 10:25:03 2019 +++ src/external/bsd/dhcpcd/dist/src/ipv6.c Thu Sep 5 08:56:55 2019 @@ -629,7 +629,7 @@ ipv6_addaddr1(struct ipv6_addr *ia, cons uint32_t pltime, vltime; __printflike(1, 2) void (*logfunc)(const char *, ...); #ifdef ND6_ADVERTISE - bool vltime_was_zero; + bool vltime_was_zero = ia->prefix_vltime == 0; #endif #ifdef __sun struct ipv6_state *state; @@ -641,7 +641,11 @@ ipv6_addaddr1(struct ipv6_addr *ia, cons if (ia->flags & IPV6_AF_DADCOMPLETED) { logdebugx("%s: IP address %s already exists", ia->iface->name, ia->saddr); +#ifdef ND6_ADVERTISE + goto advertise; +#else return 0; +#endif } #endif @@ -707,9 +711,6 @@ ipv6_addaddr1(struct ipv6_addr *ia, cons " seconds", ifp->name, ia->prefix_pltime, ia->prefix_vltime); -#ifdef ND6_ADVERTISE - vltime_was_zero = ia->prefix_vltime == 0; -#endif if (if_address6(RTM_NEWADDR, ia) == -1) { logerr(__func__); /* Restore real pltime and vltime */ @@ -774,6 +775,9 @@ ipv6_addaddr1(struct ipv6_addr *ia, cons #endif #ifdef ND6_ADVERTISE +#ifdef __sun +advertise: +#endif /* Re-advertise the preferred address to be safe. */ if (!vltime_was_zero) ipv6nd_advertise(ia); @@ -1060,6 +1064,31 @@ ipv6_getstate(struct interface *ifp) return state; } +struct ipv6_addr * +ipv6_ifanyglobal(struct interface *ifp) +{ + struct ipv6_state *state; + struct ipv6_addr *ia; + + if (ifp->carrier == LINK_DOWN) + return NULL; + + state = IPV6_STATE(ifp); + if (state == NULL) + return NULL; + + TAILQ_FOREACH(ia, &state->addrs, next) { + if (IN6_IS_ADDR_LINKLOCAL(&ia->addr)) + continue; + /* Let's be optimistic. + * Any decent OS won't forward or accept traffic + * from/to tentative or detached addresses. */ + if (!(ia->addr_flags & IN6_IFF_DUPLICATED)) + break; + } + return ia; +} + void ipv6_handleifa(struct dhcpcd_ctx *ctx, int cmd, struct if_head *ifs, const char *ifname, @@ -1069,6 +1098,22 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx, struct ipv6_state *state; struct ipv6_addr *ia; struct ll_callback *cb; + bool anyglobal; + +#ifdef __sun + struct sockaddr_in6 subnet; + + /* Solaris on-link route is an unspecified address! */ + if (IN6_IS_ADDR_UNSPECIFIED(addr)) { + if (if_getsubnet(ctx, ifname, AF_INET6, + &subnet, sizeof(subnet)) == -1) + { + logerr(__func__); + return; + } + addr = &subnet.sin6_addr; + } +#endif #if 0 char dbuf[INET6_ADDRSTRLEN]; @@ -1076,8 +1121,8 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx, dbp = inet_ntop(AF_INET6, &addr->s6_addr, dbuf, INET6_ADDRSTRLEN); - loginfox("%s: cmd %d addr %s", - ifname, cmd, dbp); + loginfox("%s: cmd %d addr %s addrflags %d", + ifname, cmd, dbp, addrflags); #endif if (ifs == NULL) @@ -1088,6 +1133,7 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx, return; if ((state = ipv6_getstate(ifp)) == NULL) return; + anyglobal = ipv6_ifanyglobal(ifp) != NULL; TAILQ_FOREACH(ia, &state->addrs, next) { if (IN6_ARE_ADDR_EQUAL(&ia->addr, addr)) @@ -1187,6 +1233,7 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx, if (ia == NULL) return; + ctx->options &= ~DHCPCD_RTBUILD; ipv6nd_handleifa(cmd, ia, pid); #ifdef DHCP6 dhcp6_handleifa(cmd, ia, pid); @@ -1198,6 +1245,15 @@ out: ipv6_freeaddr(ia); else if (!(ia->addr_flags & IN6_IFF_NOTUSEABLE)) ia->flags |= IPV6_AF_DADCOMPLETED; + + /* If we've not already called rt_build via the IPv6ND + * or DHCP6 handlers and the existance of any useable + * global address on the interface has changed, + * call rt_build to add/remove the default route. */ + if (ifp->active && ifp->options->options & DHCPCD_IPV6 && + !(ctx->options & DHCPCD_RTBUILD) && + (ipv6_ifanyglobal(ifp) != NULL) != anyglobal) + rt_build(ctx, AF_INET6); } int @@ -1498,7 +1554,13 @@ ipv6_newaddr(struct interface *ifp, cons goto err; } else if (ia->flags & IPV6_AF_RAPFX) { ia->prefix = *addr; +#ifdef __sun + ia->addr = *addr; + cbp = inet_ntop(AF_INET6, &ia->addr, buf, sizeof(buf)); + goto paddr; +#else return ia; +#endif } else if (ia->flags & (IPV6_AF_REQUEST | IPV6_AF_DELEGATEDPFX) && prefix_len != 128) { @@ -2273,6 +2335,8 @@ inet6_raroutes(rb_tree_t *routes, struct } if (rap->lifetime == 0) continue; + if (ipv6_ifanyglobal(rap->iface) == NULL) + continue; rt = inet6_makerouter(rap); if (rt == NULL) continue; Index: src/external/bsd/dhcpcd/dist/src/ipv6.h diff -u src/external/bsd/dhcpcd/dist/src/ipv6.h:1.3 src/external/bsd/dhcpcd/dist/src/ipv6.h:1.3.2.1 --- src/external/bsd/dhcpcd/dist/src/ipv6.h:1.3 Tue Jul 30 10:25:03 2019 +++ src/external/bsd/dhcpcd/dist/src/ipv6.h Thu Sep 5 08:56:55 2019 @@ -100,7 +100,8 @@ #endif /* This was fixed in NetBSD */ -#if defined(__NetBSD_Version__) && __NetBSD_Version__ >= 699002000 +#if (defined(__DragonFly_version) && __DragonFly_version >= 500704) || \ + (defined(__NetBSD_Version__) && __NetBSD_Version__ >= 699002000) # undef IPV6_POLLADDRFLAG #endif @@ -109,9 +110,9 @@ * While it supports DaD, to seems to only expose IFF_DUPLICATE * so we have no way of knowing if it's tentative or not. * I don't even know if Solaris has any special treatment for tentative. */ -# define IN6_IFF_TENTATIVE 0 +# define IN6_IFF_TENTATIVE 0x02 # define IN6_IFF_DUPLICATED 0x04 -# define IN6_IFF_DETACHED 0 +# define IN6_IFF_DETACHED 0x00 #endif #define IN6_IFF_NOTUSEABLE \ @@ -153,9 +154,12 @@ * ND6 Advertising is only used for IP address sharing to prefer * the address on a specific interface. * This just fails to work on OpenBSD and causes erroneous duplicate - * address messages on BSD's other then NetBSD. + * address messages on BSD's other then DragonFly and NetBSD. */ -#if !defined(SMALL) && (defined(__NetBSD__) || defined(__linux__)) +#if !defined(SMALL) && \ + ((defined(__DragonFly_version) && __DragonFly_version >= 500703) || \ + (defined(__NetBSD_Version__) && __NetBSD_Version__ >= 899002800) || \ + defined(__linux__) || defined(__sun)) # define ND6_ADVERTISE #endif @@ -269,6 +273,7 @@ int ipv6_handleifa_addrs(int, struct ipv struct ipv6_addr *ipv6_iffindaddr(struct interface *, const struct in6_addr *, int); int ipv6_hasaddr(const struct interface *); +struct ipv6_addr *ipv6_ifanyglobal(struct interface *); int ipv6_findaddrmatch(const struct ipv6_addr *, const struct in6_addr *, unsigned int); struct ipv6_addr *ipv6_findaddr(struct dhcpcd_ctx *, Index: src/external/bsd/dhcpcd/dist/src/route.c diff -u src/external/bsd/dhcpcd/dist/src/route.c:1.1.1.12 src/external/bsd/dhcpcd/dist/src/route.c:1.1.1.12.2.1 --- src/external/bsd/dhcpcd/dist/src/route.c:1.1.1.12 Tue Jul 30 10:23:09 2019 +++ src/external/bsd/dhcpcd/dist/src/route.c Thu Sep 5 08:56:55 2019 @@ -39,6 +39,7 @@ #include "common.h" #include "dhcpcd.h" #include "if.h" +#include "if-options.h" #include "ipv4.h" #include "ipv4ll.h" #include "ipv6.h" @@ -139,7 +140,19 @@ rt_compare_os(__unused void *context, co } static int -rt_compare_proto(__unused void *context, const void *node1, const void *node2) +rt_compare_list(__unused void *context, const void *node1, const void *node2) +{ + const struct rt *rt1 = node1, *rt2 = node2; + + if (rt1->rt_order > rt2->rt_order) + return 1; + if (rt1->rt_order < rt2->rt_order) + return -1; + return 0; +} + +static int +rt_compare_proto(void *context, const void *node1, const void *node2) { const struct rt *rt1 = node1, *rt2 = node2; int c; @@ -161,11 +174,7 @@ rt_compare_proto(__unused void *context, return c; /* Finally the order in which the route was given to us. */ - if (rt1->rt_order > rt2->rt_order) - return 1; - if (rt1->rt_order < rt2->rt_order) - return -1; - return 0; + return rt_compare_list(context, rt1, rt2); } static const rb_tree_ops_t rt_compare_os_ops = { @@ -175,6 +184,13 @@ static const rb_tree_ops_t rt_compare_os .rbto_context = NULL }; +const rb_tree_ops_t rt_compare_list_ops = { + .rbto_compare_nodes = rt_compare_list, + .rbto_compare_key = rt_compare_list, + .rbto_node_offset = offsetof(struct rt, rt_tree), + .rbto_context = NULL +}; + const rb_tree_ops_t rt_compare_proto_ops = { .rbto_compare_nodes = rt_compare_proto, .rbto_compare_key = rt_compare_proto, @@ -670,6 +686,7 @@ rt_build(struct dhcpcd_ctx *ctx, int af) rb_tree_init(&kroutes, &rt_compare_os_ops); if_initrt(ctx, &kroutes, af); ctx->rt_order = 0; + ctx->options |= DHCPCD_RTBUILD; switch (af) { #ifdef INET Index: src/external/bsd/dhcpcd/dist/src/route.h diff -u src/external/bsd/dhcpcd/dist/src/route.h:1.1.1.7 src/external/bsd/dhcpcd/dist/src/route.h:1.1.1.7.2.1 --- src/external/bsd/dhcpcd/dist/src/route.h:1.1.1.7 Wed Jul 24 09:54:55 2019 +++ src/external/bsd/dhcpcd/dist/src/route.h Thu Sep 5 08:56:55 2019 @@ -92,10 +92,12 @@ struct rt { #define RTDF_RA 0x08 /* Router Advertisement */ #define RTDF_DHCP 0x10 /* DHCP route */ #define RTDF_STATIC 0x20 /* Configured in dhcpcd */ +#define RTDF_GATELINK 0x40 /* Gateway is on link */ size_t rt_order; rb_node_t rt_tree; }; +extern const rb_tree_ops_t rt_compare_list_ops; extern const rb_tree_ops_t rt_compare_proto_ops; void rt_init(struct dhcpcd_ctx *);