From: Roy Marples Date: Thu, 24 Sep 2020 02:31:43 +0000 (+0100) Subject: BSD: NetBSD is the odd man out with SIOCGIFDATA X-Git-Tag: v9.3.0~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ec4013c25f1d3fea81fff0b8410dc75a4c7eaa30;p=thirdparty%2Fdhcpcd.git BSD: NetBSD is the odd man out with SIOCGIFDATA So setup the #defines like so. On OpenBSD, pledge blocks it and there is no escape. Luckily we already allow indirect ioctls via privsep so it works fine. --- diff --git a/src/if-bsd.c b/src/if-bsd.c index 52cc5b4e..8e832303 100644 --- a/src/if-bsd.c +++ b/src/if-bsd.c @@ -359,6 +359,23 @@ if_ignore(struct dhcpcd_ctx *ctx, const char *ifname) #endif } +static int if_indirect_ioctl(struct dhcpcd_ctx *ctx, + const char *ifname, unsigned long cmd, void *data, size_t len) +{ + struct ifreq ifr = { .ifr_flags = 0 }; + +#if defined(PRIVSEP) && defined(HAVE_PLEDGE) + if (IN_PRIVSEP(ctx)) + return (int)ps_root_indirectioctl(ctx, cmd, ifname, data, len); +#else + UNUSED(len); +#endif + + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + ifr.ifr_data = data; + return ioctl(ctx->pf_inet_fd, cmd, &ifr); +} + static int if_carrier0(struct interface *ifp) { @@ -387,26 +404,29 @@ if_carrier(struct interface *ifp) if (carrier != LINK_UNKNOWN) return carrier; -#ifdef __DragonFly__ - struct if_data ifd = { .ifi_link_state = 0 }; - struct ifreq ifr = { .ifr_data = &ifd }; - struct if_data *ifdata = &ifd; - - strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); - if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFDATA, &ifr) == -1) - return LINK_UNKNOWN; -#else +#ifdef __NetBSD__ struct ifdatareq ifdr = { .ifdr_data.ifi_link_state = 0 }; struct if_data *ifdata = &ifdr.ifdr_data; strlcpy(ifdr.ifdr_name, ifp->name, sizeof(ifdr.ifdr_name)); if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFDATA, &ifdr) == -1) return LINK_UNKNOWN; +#else + struct if_data ifd = { .ifi_link_state = 0 }; + struct if_data *ifdata = &ifd; + + if (if_indirect_ioctl(ifp->ctx, ifp->name, SIOCGIFDATA, + &ifd, sizeof(ifd)) == -1) + return LINK_UNKNOWN; #endif switch (ifdata->ifi_link_state) { case LINK_STATE_DOWN: return LINK_DOWN; +#ifdef LINK_STATE_HALF_DUPLEX + case LINK_STATE_HALF_DUPLEX: + case LINK_STATE_FULL_DUPLEX: +#endif case LINK_STATE_UP: return LINK_UP; } @@ -420,7 +440,7 @@ if_carrier(struct interface *ifp) int if_carrier_ifadata(struct interface *ifp, void *ifadata) { - int carrier = if_carrier0(ifp); + int carrier = if_carrier(ifp); struct if_data *ifdata; if (carrier != LINK_UNKNOWN || ifadata == NULL) @@ -447,25 +467,6 @@ if_linkaddr(struct sockaddr_dl *sdl, const struct interface *ifp) sdl->sdl_index = (unsigned short)ifp->index; } -#if defined(SIOCG80211NWID) || defined(SIOCGETVLAN) -static int if_indirect_ioctl(struct dhcpcd_ctx *ctx, - const char *ifname, unsigned long cmd, void *data, size_t len) -{ - struct ifreq ifr = { .ifr_flags = 0 }; - -#if defined(PRIVSEP) && defined(HAVE_PLEDGE) - if (IN_PRIVSEP(ctx)) - return (int)ps_root_indirectioctl(ctx, cmd, ifname, data, len); -#else - UNUSED(len); -#endif - - strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); - ifr.ifr_data = data; - return ioctl(ctx->pf_inet_fd, cmd, &ifr); -} -#endif - static int if_getssid1(struct dhcpcd_ctx *ctx, const char *ifname, void *ssid) { diff --git a/src/privsep-bsd.c b/src/privsep-bsd.c index d09686d8..2dc1d749 100644 --- a/src/privsep-bsd.c +++ b/src/privsep-bsd.c @@ -55,6 +55,9 @@ ps_root_doioctldom(int domain, unsigned long req, void *data, size_t len) /* Only allow these ioctls */ switch(req) { +#ifdef SIOCGIFDATA + case SIOCGIFDATA: /* FALLTHROUGH */ +#endif #ifdef SIOCG80211NWID case SIOCG80211NWID: /* FALLTHROUGH */ #endif