]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
BSD: NetBSD is the odd man out with SIOCGIFDATA
authorRoy Marples <roy@marples.name>
Thu, 24 Sep 2020 02:31:43 +0000 (03:31 +0100)
committerRoy Marples <roy@marples.name>
Thu, 24 Sep 2020 02:31:43 +0000 (03:31 +0100)
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.

src/if-bsd.c
src/privsep-bsd.c

index 52cc5b4efe6334e734a04cc980f119b4cce44613..8e832303160464bec08e782cfa84847700b250e0 100644 (file)
@@ -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)
 {
index d09686d81ec052187a0b3698bd662ec69e05ba4d..2dc1d7490051af8e403890a34f96fd894f0b2c63 100644 (file)
@@ -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