diff options
| author | Roy Marples <roy@marples.name> | 2020-09-24 03:31:43 +0100 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2020-09-24 03:31:43 +0100 |
| commit | ec4013c25f1d3fea81fff0b8410dc75a4c7eaa30 (patch) | |
| tree | 03d8412529cdbf55e49e88e7bd8376582972523a | |
| parent | fbae1f3873b31da041c58cefaa3667fe2282a629 (diff) | |
| download | dhcpcd-ec4013c25f1d3fea81fff0b8410dc75a4c7eaa30.tar.xz | |
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.
| -rw-r--r-- | src/if-bsd.c | 59 | ||||
| -rw-r--r-- | src/privsep-bsd.c | 3 |
2 files changed, 33 insertions, 29 deletions
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 |
