]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Darwin: Add initial support for macOS (#613)
authorRoy Marples <roy@marples.name>
Sun, 24 May 2026 15:19:01 +0000 (16:19 +0100)
committerGitHub <noreply@github.com>
Sun, 24 May 2026 15:19:01 +0000 (16:19 +0100)
Apple route(4) has some limitations as does getifaddrs(3).
Basically there is no means of being notified of carrier state
because Apple only reports this via media state which is an ioctl.

The good news is that we can build macOS on github so we
can get some BSD traceability at least.

Fixes #524

14 files changed:
.github/workflows/build.yml
compat/crypt/sha256.c
configure
src/dhcp6.c
src/dhcpcd.c
src/if-bsd.c
src/if.c
src/if.h
src/ipv4.h
src/ipv6nd.c
src/privsep-bpf.c
src/privsep-bsd.c
src/sa.h
tests/eloop-bench/eloop-bench.c

index aef45668fac0d1e15e8ff6ddccd2b7094bc9378b..84a4015d5e3193330699ae4ca1660dacacc57f41 100644 (file)
@@ -10,6 +10,25 @@ env:
   CC: clang
 
 jobs:
+  # macos is a good platform as we know it ships with a sanitizer we can use
+  macos:
+    strategy:
+      matrix:
+        os: [ macos-26 ]
+    runs-on: ${{ matrix.os }}
+
+    steps:
+    - uses: actions/checkout@v6
+
+    - name: Configure
+      run: ./configure --sanitize
+
+    - name: Build
+      run: make
+
+    - name: Tests
+      run: make tests
+
   ubuntu:
     strategy:
       matrix:
@@ -17,7 +36,7 @@ jobs:
     runs-on: ${{ matrix.os }}
 
     steps:
-    - uses: actions/checkout@v2
+    - uses: actions/checkout@v6
     
     - name: Configure
       run: ./configure
index dc145e328c201d8af99b82b9658ed0742d610d85..5c6e26358018eb9af105bf74ae87bb55e05fa0a6 100644 (file)
@@ -36,7 +36,7 @@
 #ifdef __GLIBC__
 #  include <endian.h>
 #endif
-#ifdef BSD
+#if defined(BSD) || defined(__APPLE__)
 #  ifndef __QNX__
 #    include <sys/endian.h>
 #  endif
index 5c77cc6a995559c26d90351439283185ee364bf4..44ba0d02184fafc4f40a3b987c9b06fa0f3b634a 100755 (executable)
--- a/configure
+++ b/configure
@@ -260,6 +260,10 @@ if [ -z "$OS" ]; then
        esac
        # Special case
        case "$OS" in
+       darwin*)
+               # Can't install /libexec
+               : ${PREFIX:=/usr/local}
+               ;;
        dragonfly*)
                # This means /usr HAS to be mounted not via dhcpcd
                : ${LIBEXECDIR:=${PREFIX:-/usr}/libexec}
@@ -376,7 +380,7 @@ else
        ALLOW_USR_LIBS=true
 fi
 case "$OS" in
-linux*|solaris*|sunos*|kfreebsd*|dragonfly*|freebsd*) ;;
+darwin*|linux*|solaris*|sunos*|kfreebsd*|dragonfly*|freebsd*) ;;
 *)
        # There might be more than one ...
        for LDELFN in /libexec/ld-elf.so.[0-9]*; do
@@ -589,8 +593,7 @@ if [ "$PRIVSEP" = yes ]; then
        if [ -z "$PRIVSEP_USER" ]; then
                printf "Detecting a suitable user for dhcpcd ... "
                for x in _dhcpcd _dhcp dhcpcd; do
-                       home=$(getent passwd $x 2>/dev/null | cut -d: -f6)
-                       if [ -d "$home" ]; then
+                       if id "$x" >/dev/null 2>&1; then
                                PRIVSEP_USER="$x"
                                break
                        fi
@@ -649,7 +652,7 @@ _CC=false
 if $XCC _test.c -o _test >/dev/null 2>&3; then
        [ -x _test ] && _CC=true
 fi
-rm -f _test.c _test
+rm -rf _test.* _test
 if ! $_CC; then
        echo $XCC
        echo "$CC does not create executables" >&2
@@ -672,7 +675,7 @@ EOF
        else
                echo "no"
        fi
-       rm -f _capsicum.c _capsicum
+       rm -rf _capsicum.* _capsicum
 
        printf "Testing for pledge ... "
        cat <<EOF >_pledge.c
@@ -687,7 +690,7 @@ EOF
        else
                echo "no"
        fi
-       rm -f _pledge.c _pledge
+       rm -rf _pledge.* _pledge
 fi
 
 # This block needs to be after the compiler test due to embedded quotes.
@@ -715,7 +718,7 @@ EOF
                echo "no"
                echo "DHCPCD_SRCS+=     if-linux-wext.c" >>$CONFIG_MK
        fi
-       rm -f _nl80211.c _nl80211
+       rm -rf _nl80211.* _nl80211
 
        printf "Testing for IN6_ADDR_GEN_MODE_NONE ... "
        cat <<EOF >_IN6_ADDR_GEN_MODE_NONE.c
@@ -731,7 +734,7 @@ EOF
        else
                echo "no"
        fi
-       rm -f _IN6_ADDR_GEN_MODE_NONE.c _IN6_ADDR_GEN_MODE_NONE
+       rm -rf _IN6_ADDR_GEN_MODE_NONE.* _IN6_ADDR_GEN_MODE_NONE
 else
        printf "Testing for ifam_pid ... "
        cat <<EOF >_ifam_pid.c
@@ -747,7 +750,7 @@ EOF
        else
                echo "no"
        fi
-       rm -f _ifam_pid.c _ifam_pid
+       rm -rf _ifam_pid.* _ifam_pid
 
        printf "Testing for ifam_addrflags ... "
        cat <<EOF >_ifam_addrflags.c
@@ -763,7 +766,7 @@ EOF
        else
                echo "no"
        fi
-       rm -f _ifam_addrflags.c _ifam_addrflags
+       rm -rf _ifam_addrflags.* _ifam_addrflags
 fi
 
 abort=false
@@ -789,7 +792,7 @@ else
        echo "libc support for getifaddrs is required - aborting" >&2
        abort=true
 fi
-rm -f _getifaddrs.c _getifaddrs
+rm -rf _getifaddrs.* _getifaddrs
 $abort && exit 1
 
 printf "Testing for ifaddrs.ifa_addrflags ... "
@@ -808,7 +811,7 @@ if $XCC _getifaddrs_addrflags.c -o _getifaddrs_addrflags $LIBSOCKET 2>&3; then
 else
        echo "no"
 fi
-rm -f _getifaddrs_addrflags.c _getifaddrs_addrflags
+rm -rf _getifaddrs_addrflags.* _getifaddrs_addrflags
 
 printf "Testing for clock_gettime ... "
 cat <<EOF >_clock_gettime.c
@@ -828,7 +831,7 @@ else
        echo "libc support for clock_getttime is required - aborting" >&2
        abort=true
 fi
-rm -f _clock_gettime.c _clock_gettime
+rm -rf _clock_gettime.* _clock_gettime
 $abort && exit 1
 
 if [ -z "$CLOSEFROM" ]; then
@@ -848,7 +851,7 @@ EOF
        fi
        echo "$CLOSEFROM"
 fi
-rm -f _closefrom.c _closefrom
+rm -rf _closefrom.* _closefrom
 if [ "$CLOSEFROM" = no ]; then
        echo "COMPAT_SRCS+=     compat/closefrom.c" >>$CONFIG_MK
        echo "#include                  \"compat/closefrom.h\"" >>$CONFIG_H
@@ -873,7 +876,7 @@ echo "$IOCTL_REQ"
 if [ "$IOCTL_REQ" != "unsigned long" ]; then
        echo "#define   IOCTL_REQUEST_TYPE      $IOCTL_REQ" >>$CONFIG_H
 fi
-rm -f _ioctl.c _ioctl
+rm -rf _ioctl.* _ioctl
 
 printf "Testing for inet_ntoa ... "
 cat <<EOF >_inet_ntoa.c
@@ -898,7 +901,7 @@ else
        echo "libc support for inet_ntoa is required - aborting" >&2
        abort=true
 fi
-rm -f _inet_ntoa.c _inet_ntoa
+rm -rf _inet_ntoa.* _inet_ntoa
 $abort && exit 1
 
 if [ -z "$ARC4RANDOM" ]; then
@@ -915,7 +918,7 @@ EOF
                ARC4RANDOM=no
        fi
        echo "$ARC4RANDOM"
-       rm -f _arc4random.c _arc4random
+       rm -rf _arc4random.* _arc4random
 fi
 if [ "$ARC4RANDOM" = no ]; then
        echo "COMPAT_SRCS+=     compat/arc4random.c" >>$CONFIG_MK
@@ -936,7 +939,7 @@ EOF
                ARC4RANDOM_UNIFORM=no
        fi
        echo "$ARC4RANDOM_UNIFORM"
-       rm -f _arc4random_uniform.c _arc4random_uniform
+       rm -rf _arc4random_uniform.* _arc4random_uniform
 fi
 if [ "$ARC4RANDOM_UNIFORM" = no ]; then
        echo "COMPAT_SRCS+=     compat/arc4random_uniform.c" >>$CONFIG_MK
@@ -960,7 +963,7 @@ EOF
                MEMSET_EXPLICIT=no
        fi
        echo "$MEMSET_EXPLICIT"
-       rm -f _memset_explicit.c _memset_explicit
+       rm -rf _memset_explicit.* _memset_explicit
 fi
 if [ "$MEMSET_EXPLICIT" = yes ]; then
        echo "#define   HAVE_MEMSET_EXPLICIT" >>$CONFIG_H
@@ -983,7 +986,7 @@ EOF
                EXPLICIT_BZERO=no
        fi
        echo "$EXPLICIT_BZERO"
-       rm -f _explicit_bzero.c _explicit_bzero
+       rm -rf _explicit_bzero.* _explicit_bzero
 fi
 if [ "$EXPLICIT_BZERO" = yes ]; then
        echo "#define   HAVE_EXPLICIT_BZERO" >>$CONFIG_H
@@ -1006,7 +1009,7 @@ EOF
                MEMSET_S=no
        fi
        echo "$MEMSET_S"
-       rm -f _memset_s.c _memset_s
+       rm -rf _memset_s.* _memset_s
 fi
 if [ "$MEMSET_S" = yes ]; then
        echo "#define   __STDC_WANT_LIB_EXT1__  1" >>$CONFIG_H
@@ -1027,7 +1030,7 @@ EOF
                OPEN_MEMSTREAM=no
        fi
        echo "$OPEN_MEMSTREAM"
-       rm -f _open_memstream.c _open_memstream
+       rm -rf _open_memstream.* _open_memstream
 fi
 if [ "$OPEN_MEMSTREAM" = yes ]; then
        echo "#define   HAVE_OPEN_MEMSTREAM" >>$CONFIG_H
@@ -1059,7 +1062,7 @@ EOF
                PIDFILE_LOCK=no
        fi
        echo "$PIDFILE_LOCK"
-       rm -f _pidfile.c _pidfile
+       rm -rf _pidfile.* _pidfile
 fi
 if [ "$PIDFILE_LOCK" = no ]; then
        echo "COMPAT_SRCS+=     compat/pidfile.c" >>$CONFIG_MK
@@ -1087,11 +1090,11 @@ EOF
                SETPROCTITLE=no
        fi
        echo "$SETPROCTITLE"
-       rm -f _setproctitle.c _setproctitle
+       rm -rf _setproctitle.* _setproctitle
 fi
 if [ "$SETPROCTITLE" = no ]; then
        case "$OS" in
-       solaris*|sunos*)
+       darwin*|solaris*|sunos*)
                echo "$OS has no support for setting process title"
                echo "#define   setproctitle(...)" >>$CONFIG_H
                ;;
@@ -1099,9 +1102,13 @@ if [ "$SETPROCTITLE" = no ]; then
                echo "COMPAT_SRCS+=     compat/setproctitle.c" >>$CONFIG_MK
                echo "#include                  \"compat/setproctitle.h\"" \
                        >>$CONFIG_H
+               SETPROCTITLE=yes
                ;;
        esac
 fi
+if [ "$SETPROCTITLE" = yes ]; then
+       echo "#define HAVE_SETPROCTITLE" >>$CONFIG_H
+fi
 
 if [ -z "$STRLCPY" ]; then
        printf "Testing for strlcpy ... "
@@ -1119,7 +1126,7 @@ EOF
                STRLCPY=no
        fi
        echo "$STRLCPY"
-       rm -f _strlcpy.c _strlcpy
+       rm -rf _strlcpy.* _strlcpy
 fi
 if [ "$STRLCPY" = no ]; then
        echo "COMPAT_SRCS+=     compat/strlcpy.c" >>$CONFIG_MK
@@ -1143,7 +1150,7 @@ EOF
                STRTOI=no
        fi
        echo "$STRTOI"
-       rm -f _strtoi.c _strtoi
+       rm -rf _strtoi.* _strtoi
 fi
 if [ "$STRTOI" = no ]; then
        echo "COMPAT_SRCS+=     compat/strtoi.c compat/strtou.c" >>$CONFIG_MK
@@ -1164,7 +1171,7 @@ EOF
                CONSTTIME_MEMEQUAL=no
        fi
        echo "$CONSTTIME_MEMEQUAL"
-       rm -f _consttime_memequal.c _consttime_memequal
+       rm -rf _consttime_memequal.* _consttime_memequal
 fi
 if [ "$CONSTTIME_MEMEQUAL" = no ] && [ -z "$TIMINGSAFE_BCMP" ]; then
        printf "Testing for timingsafe_bcmp ... "
@@ -1180,7 +1187,7 @@ EOF
                TIMINGSAFE_BCMP=no
        fi
        echo "$TIMINGSAFE_BCMP"
-       rm -f _timingsafe_bcmp.c _timingsafe_bcmp
+       rm -rf _timingsafe_bcmp.* _timingsafe_bcmp
 fi
 
 if [ "$CONSTTIME_MEMEQUAL" = no ]; then
@@ -1207,7 +1214,7 @@ EOF
                DPRINTF=no
        fi
        echo "$DPRINTF"
-       rm -f _dprintf.c _dprintf
+       rm -rf _dprintf.* _dprintf
 fi
 if [ "$DPRINTF" = no ]; then
        echo "COMPAT_SRCS+=     compat/dprintf.c" >>$CONFIG_MK
@@ -1231,7 +1238,7 @@ EOF
                RBTREE=no
        fi
        echo "$RBTREE"
-       rm -f _rbtree.c _rbtree
+       rm -rf _rbtree.* _rbtree
 fi
 if [ "$RBTREE" = no ]; then
        echo "VENDOR_SRCS+=     vendor/rbtree.c" >>$CONFIG_MK
@@ -1261,7 +1268,7 @@ EOF
                REALLOCARRAY=no
        fi
        echo "$REALLOCARRAY"
-       rm -f _reallocarray.c _reallocarray
+       rm -rf _reallocarray.* _reallocarray
 fi
 if [ "$REALLOCARRAY" = no ]; then
        echo "COMPAT_SRCS+=     compat/reallocarray.c" >>$CONFIG_MK
@@ -1286,7 +1293,7 @@ EOF
                BE64ENC=no
        fi
        echo "$BE64ENC"
-       rm -f _be64enc.c _be64enc
+       rm -rf _be64enc.* _be64enc
 fi
 if [ "$BE64ENC" = no ]; then
        echo "#include                  \"compat/endian.h\"" >>$CONFIG_H
@@ -1306,7 +1313,7 @@ EOF
                FLS64=no
        fi
        echo "$FLS64"
-       rm -f _fls64.c _fls64
+       rm -rf _fls64.* _fls64
 fi
 if [ "$FLS64" = yes ]; then
        echo "#define   HAVE_SYS_BITOPS_H" >>$CONFIG_H
@@ -1340,7 +1347,7 @@ EOF
                MD5=no
        fi
        echo "$MD5"
-       rm -f _md5.c _md5
+       rm -rf _md5.* _md5
 fi
 
 if [ -z "$SHA2_H" ]; then
@@ -1390,7 +1397,7 @@ EOF
                SHA2=no
        fi
        echo "$SHA2"
-       rm -f _sha256.c _sha256
+       rm -rf _sha256.* _sha256
        if [ "$SHA2" = no ]; then
                # Did OpenBSD really change this? grrrr
                printf "Testing for SHA256Init ... "
@@ -1424,7 +1431,7 @@ EOF
                        SHA2=no
                fi
                echo "$SHA2"
-               rm -f _sha256.c _sha256
+               rm -rf _sha256.* _sha256
        fi
 fi
 
@@ -1457,7 +1464,7 @@ EOF
                fi
        fi
        echo "$HMAC"
-       rm -f _hmac.c _hmac
+       rm -rf _hmac.* _hmac
 fi
 
 if [ "$OPENSSL" = yes ] ||
@@ -1491,7 +1498,7 @@ EOF
                OPENSSL=no
        fi
        echo "$OPENSSL"
-       rm -f _openssl.c _openssl
+       rm -rf _openssl.* _openssl
 fi
 
 if [ "$OPENSSL" = yes ]; then
@@ -1516,7 +1523,7 @@ EOF
        SHA2_LIB=
        SHA2_RENAMED=
        echo "$SHA2"
-       rm -f _openssl_sha.c _openssl_sha
+       rm -rf _openssl_sha.* _openssl_sha
 fi
 
 if [ "$LIBPCAP" = yes ]; then
@@ -1542,7 +1549,7 @@ EOF
                        echo "no"
                        abort=true
                fi
-               rm -f _libpcap.c libpcap
+               rm -rf _libpcap.* libpcap
                $abort && exit 1
        fi
        echo "CFLAGS+=  $LIBPCAP_CFLAGS" >>$CONFIG_MK
@@ -1563,7 +1570,7 @@ EOF
        else
                echo "no"
        fi
-       rm -f _libpcap_imm.c libpcap_imm
+       rm -rf _libpcap_imm.* libpcap_imm
 
        printf "Testing for pcap_setwritefilter() ... "
        cat <<EOF >_libpcap_write.c
@@ -1579,7 +1586,7 @@ EOF
        else
                echo "no"
        fi
-       rm -f _libpcap_write.c libpcap_write
+       rm -rf _libpcap_write.* libpcap_write
 
        printf "Testing for pcap_lockfilter() ... "
        cat <<EOF >_libpcap_lock.c
@@ -1595,7 +1602,7 @@ EOF
        else
                echo "no"
        fi
-       rm -f _libpcap_lock.c libpcap_lock
+       rm -rf _libpcap_lock.* libpcap_lock
 fi
 
 # Workaround for DragonFlyBSD import
@@ -1709,7 +1716,7 @@ EOF
                echo "LIBUDEV_CPPFLAGS+=        -DLIBUDEV_NOFILTER" >>$CONFIG_MK
                echo "no"
        fi
-       rm -f _udev.c _udev
+       rm -rf _udev.* _udev
 
        printf "Checking udev_device_get_is_initialized ... "
        cat <<EOF >_udev.c
@@ -1726,7 +1733,7 @@ EOF
                echo "LIBUDEV_CPPFLAGS+=        -DLIBUDEV_NOINIT" >>$CONFIG_MK
                echo "no"
        fi
-       rm -f _udev.c _udev
+       rm -rf _udev.* _udev
 elif [ "$DEV" != no ] && [ "$UDEV" != no ] && [ -n "$UDEV" ]; then
        echo "udev has been explicitly requested ... aborting" >&2
        exit 1
@@ -1761,7 +1768,7 @@ EOF
                echo "no"
                echo "libc for dlopen is required - aborting"
        fi
-       rm -f _dlopen.c _dlopen
+       rm -rf _dlopen.* _dlopen
        $abort && exit 1
 fi
 
index d9e8b70935500a0784ee445f79dd23c1a590e531..c734c8aed569f7fd7d4ebdcc84db3c421df54cae 100644 (file)
@@ -26,6 +26,8 @@
  * SUCH DAMAGE.
  */
 
+#define __APPLE_USE_RFC_3542
+
 #include <sys/types.h>
 #include <sys/utsname.h>
 
index b5c5ae2854501b759b0b77318038c34b2ac98880..1fa7c3ab7307e8d4ce9fbbdfd0aba8fa262e2ff4 100644 (file)
@@ -1984,6 +1984,29 @@ dup_null(int fd)
        return err;
 }
 
+#ifdef __APPLE__
+#warning OS does not report interface link state change, polling every second
+static void
+dhcpcd_poll_carrier(void *arg)
+{
+       struct dhcpcd_ctx *ctx = arg;
+       struct interface *ifp;
+       int link_status;
+
+       if (ctx->options & DHCPCD_EXITING)
+               return;
+
+       TAILQ_FOREACH(ifp, ctx->ifaces, next) {
+               if (!(ifp->active))
+                       continue;
+               link_status = if_carrier(ifp, NULL);
+               dhcpcd_handlecarrier(ifp, link_status, ifp->flags);
+       }
+
+       eloop_timeout_add_sec(ctx->eloop, 1, dhcpcd_poll_carrier, ctx);
+}
+#endif
+
 int
 main(int argc, char **argv, char **envp)
 {
@@ -2721,6 +2744,10 @@ start_manager:
                            dhcpcd_prestartinterface, ifp);
        }
 
+#ifdef __APPLE__
+       dhcpcd_poll_carrier(&ctx);
+#endif
+
 run_loop:
        i = eloop_start(ctx.eloop);
        if (i < 0) {
index c533e024184fc49c1f31022fee9cf080ed2ea648..72d573b7cd145ded3bb2cdf0af212201e3b1bb8a 100644 (file)
 #include <arpa/inet.h>
 
 #include "config.h"
+#include "src/dhcpcd.h"
 #ifdef __NetBSD__
 #include <net/if_vlanvar.h> /* Needs netinet/if_ether.h */
 #elif defined(__DragonFly__)
 #include <net/vlan/if_vlan_var.h>
+#elif defined(__APPLE__)
+/* Apple doesn't ship this in include/net ... */
+struct vlanreq {
+       char vlr_parent[IFNAMSIZ];
+       u_short vlr_tag;
+};
 #else
 #include <net/if_vlan_var.h>
 #endif
 #ifdef __DragonFly__
 #include <netproto/802_11/ieee80211_ioctl.h>
-#else
+#elif !defined(__APPLE__)
 #include <net80211/ieee80211.h>
 #include <net80211/ieee80211_ioctl.h>
 #endif
 #include "sa.h"
 
 #ifndef RT_ROUNDUP
+#ifdef __APPLE__
+#define RT_ROUNDUP(a) \
+       ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
+#else
 #define RT_ROUNDUP(a) \
        ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+#endif
 #define RT_ADVANCE(x, n) (x += RT_ROUNDUP((n)->sa_len))
 #endif
-
 /* Ignore these interface names which look like ethernet but are virtual or
  * just won't work without explicit configuration. */
 static const char *const ifnames_ignore[] = { "bridge",
@@ -108,6 +119,9 @@ static const char *const ifnames_ignore[] = { "bridge",
        "fwe",                   /* Firewire */
        "fwip",                  /* Firewire */
        "tap", "vether", "xvif", /* XEN DOM0 -> guest interface */
+#ifdef __APPLE__
+       "ap", "awdl", "llw",
+#endif
        NULL };
 
 struct rtm {
@@ -227,7 +241,7 @@ if_opensockets_os(struct dhcpcd_ctx *ctx)
                ps_rights_limit_fd_sockopt(ctx->link_fd);
 #endif
 
-#if defined(SIOCALIFADDR) && defined(IFLR_ACTIVE) /*NetBSD */
+#if (defined(SIOCALIFADDR) && defined(IFLR_ACTIVE))
        priv->pf_link_fd = xsocket(PF_LINK, SOCK_DGRAM, 0);
        if (priv->pf_link_fd == -1)
                logerr("%s: socket(PF_LINK)", __func__);
@@ -400,6 +414,7 @@ if_indirect_ioctl(struct dhcpcd_ctx *ctx, const char *ifname, unsigned long cmd,
 int
 if_carrier(struct interface *ifp, const void *ifadata)
 {
+#ifdef LINK_STATE_UP
        const struct if_data *ifi = ifadata;
 
        /*
@@ -408,7 +423,6 @@ if_carrier(struct interface *ifp, const void *ifadata)
         * support SIOCGIFMEDIA.
         */
        assert(ifadata != NULL);
-
        if (ifi->ifi_link_state >= LINK_STATE_UP)
                return LINK_UP;
        if (ifi->ifi_link_state == LINK_STATE_UNKNOWN) {
@@ -421,6 +435,23 @@ if_carrier(struct interface *ifp, const void *ifadata)
                return LINK_UNKNOWN;
        }
        return LINK_DOWN;
+#elif defined(SIOCGIFXMEDIA)
+       struct dhcpcd_ctx *ctx = ifp->ctx;
+       struct ifmediareq ifmr = { .ifm_active = 0 };
+
+       UNUSED(ifadata);
+       strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name));
+       if (ioctl(ctx->pf_inet_fd, SIOCGIFXMEDIA, &ifmr) == -1)
+               return LINK_UNKNOWN;
+       if (!(ifmr.ifm_status & IFM_AVALID))
+               return LINK_UNKNOWN;
+       return ifmr.ifm_status & IFM_ACTIVE ? LINK_UP : LINK_DOWN;
+#else
+#warning OS does not report interface link state
+       UNUSED(ifp);
+       UNUSED(ifadata);
+       return LINK_UNKNOWN;
+#endif
 }
 
 bool
@@ -489,6 +520,10 @@ if_getssid1(struct dhcpcd_ctx *ctx, const char *ifname, void *ssid)
                }
        }
 #else
+#warning OS does not report interface SSID
+       UNUSED(ctx);
+       UNUSED(ifname);
+       UNUSED(ssid);
        errno = ENOSYS;
 #endif
 
@@ -528,7 +563,7 @@ if_vimaster(struct dhcpcd_ctx *ctx, const char *ifname)
                return -1;
        if (ifmr.ifm_status & IFM_AVALID &&
            IFM_TYPE(ifmr.ifm_active) == IFM_IEEE80211) {
-               if (if_getssid1(ctx, ifname, NULL) == -1)
+               if (if_getssid1(ctx, ifname, NULL) == -1 && errno != ENOSYS)
                        return 1;
        }
        return 0;
@@ -537,7 +572,7 @@ if_vimaster(struct dhcpcd_ctx *ctx, const char *ifname)
 unsigned short
 if_vlanid(const struct interface *ifp)
 {
-#ifdef SIOCGETVLAN
+#if defined(SIOCGETVLAN)
        struct vlanreq vlr = { .vlr_tag = 0 };
 
        if (if_indirect_ioctl(ifp->ctx, ifp->name, SIOCGETVLAN, &vlr,
@@ -929,7 +964,7 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, const struct rt_msghdr *rtm)
 }
 
 static int
-if_sysctl(struct dhcpcd_ctx *ctx, const int *name, u_int namelen, void *oldp,
+if_sysctl(struct dhcpcd_ctx *ctx, int *name, u_int namelen, void *oldp,
     size_t *oldlenp, void *newp, size_t newlen)
 {
 #if defined(PRIVSEP) && defined(HAVE_CAPSICUM)
@@ -1225,6 +1260,7 @@ if_getlifetime6(struct ipv6_addr *ia)
 }
 #endif
 
+#ifdef IFAN_ARRIVAL
 static int
 if_announce(struct dhcpcd_ctx *ctx, const struct if_announcemsghdr *ifan)
 {
@@ -1242,6 +1278,7 @@ if_announce(struct dhcpcd_ctx *ctx, const struct if_announcemsghdr *ifan)
 
        return 0;
 }
+#endif
 
 static int
 if_ifinfo(struct dhcpcd_ctx *ctx, const struct if_msghdr *ifm)
index e807acda004e8b397747d05fb37e6a57fd37f975..d1b4a02c2c98c8f709fb128fe940dabb4101d5eb 100644 (file)
--- a/src/if.c
+++ b/src/if.c
@@ -26,6 +26,8 @@
  * SUCH DAMAGE.
  */
 
+#define __APPLE_USE_RFC_3542
+
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/ioctl.h>
index 6150bca89d749a496c70f4040292c6be3bd99aa1..f4e14bd0705562dd46419a3460a3000363cdd276 100644 (file)
--- a/src/if.h
+++ b/src/if.h
@@ -128,7 +128,7 @@ struct priv {
 #ifdef INET6
        int pf_inet6_fd;
 #endif
-#if defined(SIOCALIFADDR) && defined(IFLR_ACTIVE) /*NetBSD */
+#if (defined(SIOCALIFADDR) && defined(IFLR_ACTIVE)) || defined(SIOCGIFSTATUS)
        int pf_link_fd;
 #endif
 };
index af3c73eb4d6e7d3b3383ea62dda5c0e01d393b11..90c9110c222084913d1bcb57f38f2f9362558c36 100644 (file)
        (IN_IFF_TENTATIVE | IN_IFF_DUPLICATED | IN_IFF_DETACHED)
 #endif
 
-#define IN_ARE_ADDR_EQUAL(a, b)          ((a)->s_addr == (b)->s_addr)
+#ifndef IN_ARE_ADDR_EQUAL
+#define IN_ARE_ADDR_EQUAL(a, b) ((a)->s_addr == (b)->s_addr)
+#endif
+#ifndef IN_IS_ADDR_UNSPECIFIED
 #define IN_IS_ADDR_UNSPECIFIED(a) ((a)->s_addr == INADDR_ANY)
+#endif
 
 #ifdef __linux__
 #define IP_LIFETIME
index eafcf4c9a08abdf348ec18bafedd4b4225e35945..68edf7ad0aed45335bb5371cb156c1b5275acf68 100644 (file)
@@ -26,6 +26,8 @@
  * SUCH DAMAGE.
  */
 
+#define __APPLE_USE_RFC_3542
+
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
index 940c576e2d46702f34988228885bbf1e324035d0..86da7e47f4ae0b3066b04e0b87d518ef469c86d2 100644 (file)
@@ -149,16 +149,20 @@ static int
 ps_bpf_start_bpf(struct ps_process *psp)
 {
        struct dhcpcd_ctx *ctx = psp->psp_ctx;
-       char *addr;
        struct in_addr *ia = &psp->psp_id.psi_addr.psa_in_addr;
+#ifdef HAVE_SETPROCTITLE
+       char *addr;
+#endif
 
-       if (ia->s_addr == INADDR_ANY) {
+       if (ia->s_addr == INADDR_ANY)
                ia = NULL;
-               addr = NULL;
-       } else
-               addr = inet_ntoa(*ia);
+
+#ifdef HAVE_SETPROCTITLE
+       addr = ia != NULL ? inet_ntoa(*ia) : NULL;
        setproctitle("[BPF %s] %s%s%s", psp->psp_protostr, psp->psp_ifname,
            addr != NULL ? " " : "", addr != NULL ? addr : "");
+#endif
+
        ps_freeprocesses(ctx, psp);
 
        psp->psp_bpf = bpf_open(&psp->psp_ifp, psp->psp_filter, ia);
index 836a9df9cfcc0d220fce9bd7b09e8a2caffaf60a..42bc45eba25c091f7d5529979fea423c438f4949 100644 (file)
 #include <netinet/if_ether.h>
 #elif defined(__DragonFly__)
 #include <net/vlan/if_vlan_var.h>
+#elif defined(__APPLE__)
 #else
 #include <net/if_vlan_var.h>
 #endif
 #ifdef __DragonFly__
 #include <netproto/802_11/ieee80211_ioctl.h>
-#else
+#elif !defined(__APPLE__)
 #include <net80211/ieee80211.h>
 #include <net80211/ieee80211_ioctl.h>
 #endif
index 4083d561b26c440586cf032ddc66331076441912..e40d68fe1907229f6b6b035fcea0cf12e8567e62 100644 (file)
--- a/src/sa.h
+++ b/src/sa.h
@@ -37,6 +37,7 @@ union sa_ss {
        struct sockaddr sa;
        struct sockaddr_in sin;
        struct sockaddr_in6 sin6;
+//     struct sockaddr_storage ss; /* avoids memory overrun */
 };
 
 #ifdef BSD
index 984c2e8b1f796465665a9562f59ca547f5d6f09d..bd177f33303c21ceb9ca0963e10b60e09ebbb7f3 100644 (file)
@@ -158,7 +158,7 @@ main(int argc, char **argv)
                err(EXIT_FAILURE, "malloc");
 
        for (i = 0, p = pipes; i < npipes; i++, p++) {
-               if (pipe2(p->fd, O_CLOEXEC | O_NONBLOCK) == -1)
+               if (pipe(p->fd) == -1)
                        err(EXIT_FAILURE, "pipe");
                if (eloop_event_add(e, p->fd[0], ELE_READ, read_cb, p) == -1)
                        err(EXIT_FAILURE, "eloop_event_add");