]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Linux: Add support for ARPHRD_NONE
authorRoy Marples <roy@marples.name>
Tue, 20 Aug 2019 21:59:47 +0000 (22:59 +0100)
committerRoy Marples <roy@marples.name>
Tue, 20 Aug 2019 21:59:47 +0000 (22:59 +0100)
So apprently I've been doing this wrong for years - on glibc at
least, getifaddrs(3) never reported a hardware address for
AF_PACKET addresses. Infact, it reported nothing but useless
stats in ifa_data.

I view this as a bug because SIOCGIFHWADDR will get a sockaddr
with a sa_family set correctly. getifaddrs should do the same.
Anyway, if we have the ioctl and no address for the AF_PACKET
"address", call upon the above ioctl to get the correct family
for the interface.

While here, replace if_nametoindex with an ioctl to save libc
from doing it for us.

src/bpf.c
src/duid.c
src/if.c

index 10404ffe9ec3bff8c787114be8ed36a848ab5d63..06bbf3f1e1b5e1b1c2c2fc62de192c6ab147271e 100644 (file)
--- a/src/bpf.c
+++ b/src/bpf.c
@@ -558,13 +558,13 @@ bpf_arp(struct interface *ifp, int fd)
 #define        BPF_M_UDP       3
 #define        BPF_M_UDPLEN    4
 
-#ifdef ARPHRD_NETROM
-static const struct bpf_insn bpf_bootp_netrom[] = {
+#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_NETROM_LEN   __arraycount(bpf_bootp_netrom)
+#define BPF_BOOTP_NONE_LEN     __arraycount(bpf_bootp_none)
 #endif
 
 static const struct bpf_insn bpf_bootp_ether[] = {
@@ -674,10 +674,10 @@ bpf_bootp(struct interface *ifp, int fd)
        bp = bpf;
        /* Check frame header. */
        switch(ifp->family) {
-#ifdef ARPHRD_NETROM
-       case ARPHRD_NETROM:
-               memcpy(bp, bpf_bootp_netrom, sizeof(bpf_bootp_netrom));
-               bp += BPF_BOOTP_NETROM_LEN;
+#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:
index 60e4be37013d124930a906d653e1a01efbbc75d8..d6c2b498e5e477a78d14bfa5cb85fd06225c3fef 100644 (file)
 #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 interface *ifp)
                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 857294effca3f7ffa830713e75658447648df5dd..d9f5d19f2b92631fa8b4f34d6231f9f17ad175c6 100644 (file)
--- a/src/if.c
+++ b/src/if.c
@@ -307,17 +307,16 @@ if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs,
        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 +511,18 @@ if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs,
                                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 {
+                       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. */
@@ -528,9 +535,6 @@ if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs,
                            ctx->ifac == 0 && !if_hasconf(ctx, ifp->name))
                                active = IF_INACTIVE;
                        switch (ifp->family) {
-#ifdef ARPHRD_NETROM
-                       case ARPHRD_NETROM:
-#endif
                        case ARPHRD_IEEE1394:
                        case ARPHRD_INFINIBAND:
 #ifdef ARPHRD_LOOPBACK
@@ -538,6 +542,9 @@ if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs,
 #endif
 #ifdef ARPHRD_PPP
                        case ARPHRD_PPP:
+#endif
+#ifdef ARPHRD_NONE
+                       case ARPHRD_NONE:
 #endif
                                /* We don't warn for supported families */
                                break;