From: Roy Marples Date: Tue, 20 Aug 2019 21:59:47 +0000 (+0100) Subject: Linux: Add support for ARPHRD_NONE X-Git-Tag: v8.0.3~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=208b25190faffe0735c19e69c03e122e5c54dfbf;p=thirdparty%2Fdhcpcd.git Linux: Add support for ARPHRD_NONE 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. --- diff --git a/src/bpf.c b/src/bpf.c index 10404ffe..06bbf3f1 100644 --- 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: diff --git a/src/duid.c b/src/duid.c index 60e4be37..d6c2b498 100644 --- a/src/duid.c +++ b/src/duid.c @@ -52,10 +52,6 @@ #include #include -#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) { diff --git a/src/if.c b/src/if.c index 857294ef..d9f5d19f 100644 --- 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;