From: Roy Marples Date: Tue, 16 Sep 2008 09:55:46 +0000 (+0000) Subject: Move AF_LINK discovery to if-bsd.c. Also, we only work with IFT_ETHER types currently... X-Git-Tag: v5.0.0~244 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=43b2edaf432212eeee9f97ca5e476af95e2c373e;p=thirdparty%2Fdhcpcd.git Move AF_LINK discovery to if-bsd.c. Also, we only work with IFT_ETHER types currently, so skip others. --- diff --git a/if-bsd.c b/if-bsd.c index 3024616e..ef5c1f2d 100644 --- a/if-bsd.c +++ b/if-bsd.c @@ -39,15 +39,18 @@ #include #include +#include #include #include #include #include +#include #include #include "config.h" #include "common.h" #include "dhcp.h" +#include "if-options.h" #include "net.h" /* Darwin doesn't define this for some very odd reason */ @@ -289,11 +292,68 @@ manage_link(int fd, } } +static void +discover_link(struct interface **ifs, int argc, char * const *argv, + struct ifreq *ifr) +{ + struct interface *ifp, *ifl = NULL; + struct sockaddr_dl *sdl; + int n; + + if (ifr->ifr_addr.sa_family != AF_LINK) + return; + for (ifp = *ifs; ifp; ifp = ifp->next) { + if (strcmp(ifp->name, ifr->ifr_name) == 0) + return; + ifl = ifp; + } + if (argc > 0) { + for (n = 0; n < argc; n++) + if (strcmp(ifr->ifr_name, argv[n]) == 0) + return; + } else { + for (n = 0; n < ifdc; n++) + if (fnmatch(ifdv[n], ifr->ifr_name, 0) == 0) + return; + for (n = 0; n < ifac; n++) + if (fnmatch(ifav[n], ifr->ifr_name, 0) == 0) + break; + if (ifac && n == ifac) + return; + } + if (!(ifp = init_interface(ifr->ifr_name))) + return; + sdl = xmalloc(ifr->ifr_addr.sa_len); + memcpy(sdl, &ifr->ifr_addr, ifr->ifr_addr.sa_len); + switch(sdl->sdl_type) { + case IFT_ETHER: + ifp->family = ARPHRD_ETHER; + ifp->hwlen = sdl->sdl_alen; + memcpy(ifp->hwaddr, LLADDR(sdl), sdl->sdl_alen); + break; + default: + /* Don't needlessly spam console on startup */ + if (!(options & DHCPCD_MASTER && + !(options & DHCPCD_DAEMONISED) && + options & DHCPCD_QUIET)) + syslog(LOG_ERR, "%s: unsupported interface type", + ifr->ifr_name); + free(ifp); + ifp = NULL; + break; + } + free(sdl); + if (ifp && ifl) + ifl->next = ifp; + else + *ifs = ifp; +} + struct interface * discover_interfaces(int argc, char * const *argv) { struct interface *ifs = NULL; - do_interface(NULL, &ifs, argc, argv, NULL, NULL, 2); + do_interface(NULL, discover_link, &ifs, argc, argv, NULL, NULL, 2); return ifs; } diff --git a/net.c b/net.c index 71575e91..311adf22 100644 --- a/net.c +++ b/net.c @@ -47,6 +47,7 @@ # include #endif #ifdef BSD +# include # include #endif #ifdef __linux__ @@ -61,7 +62,6 @@ #include #include -#include #include #include #include @@ -138,7 +138,7 @@ hwaddr_ntoa(const unsigned char *hwaddr, size_t hwlen) char *p = hwaddr_buffer; size_t i; - for (i = 0; i < hwlen && i < sizeof(hwaddr_buffer) / 3; i++) { + for (i = 0; i < hwlen && i < HWADDR_LEN; i++) { if (i > 0) *p ++= ':'; p += snprintf(p, 3, "%.2x", hwaddr[i]); @@ -244,9 +244,6 @@ init_interface(const char *ifname) } memcpy(iface->hwaddr, ifr.ifr_hwaddr.sa_data, iface->hwlen); iface->family = ifr.ifr_hwaddr.sa_family; - -#else - iface->family = ARPHRD_ETHER; #endif if (ioctl(s, SIOCGIFMTU, &ifr) == -1) @@ -316,8 +313,8 @@ free_interface(struct interface *iface) int do_interface(const char *ifname, - _unused struct interface **ifs, - _unused int argc, _unused char * const *argv, + void (*do_link)(struct interface **, int, char * const *, struct ifreq *), + struct interface **ifs, int argc, char * const *argv, struct in_addr *addr, struct in_addr *net, int act) { int s; @@ -333,11 +330,6 @@ do_interface(const char *ifname, struct sockaddr_in address; struct ifreq *ifr; struct sockaddr_in netmask; -#ifdef AF_LINK - int n; - struct sockaddr_dl *sdl; - struct interface *ifp, *ifl = NULL, *ifn = NULL; -#endif if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) return -1; @@ -383,48 +375,11 @@ do_interface(const char *ifname, found = 1; -#ifdef AF_LINK /* Interface discovery for BSD's */ - if (act == 2 && ifr->ifr_addr.sa_family == AF_LINK) { - for (ifp = *ifs; ifp; ifp = ifp->next) { - ifl = ifp; - if (strcmp(ifp->name, ifr->ifr_name) == 0) - break; - } - if (ifp) - continue; - if (argc > 0) { - for (n = 0; n < argc; n++) - if (strcmp(ifr->ifr_name, argv[n]) == 0) - break; - if (n == argc) - continue; - } else { - for (n = 0; n < ifdc; n++) - if (!fnmatch(ifdv[n], ifr->ifr_name, 0)) - break; - if (n < ifdc) - continue; - for (n = 0; n < ifac; n++) - if (!fnmatch(ifav[n], ifr->ifr_name, 0)) - break; - if (ifac && n == ifac) - continue; - } - ifn = init_interface(ifr->ifr_name); - if (!ifn) - continue; - if (ifl) - ifp = ifl->next = ifn; - else - ifp = *ifs = ifn; - sdl = xmalloc(ifr->ifr_addr.sa_len); - memcpy(sdl, &ifr->ifr_addr, ifr->ifr_addr.sa_len); - ifp->hwlen = sdl->sdl_alen; - memcpy(ifp->hwaddr, LLADDR(sdl), sdl->sdl_alen); - free(sdl); + if (act == 2 && do_link) { + do_link(ifs, argc, argv, ifr); + continue; } -#endif if (ifr->ifr_addr.sa_family == AF_INET && addr) { memcpy(&address, &ifr->ifr_addr, sizeof(address)); diff --git a/net.h b/net.h index 806b5a19..43cd650c 100644 --- a/net.h +++ b/net.h @@ -102,8 +102,8 @@ int inet_ntocidr(struct in_addr); int inet_cidrtoaddr(int, struct in_addr *); int up_interface(const char *); -int do_interface(const char *, struct interface **, - int argc, char * const *argv, +int do_interface(const char *, void (*)(struct interface **, int, char * const *, struct ifreq *), + struct interface **, int, char * const *, struct in_addr *, struct in_addr *, int); int if_address(const struct interface *, const struct in_addr *, const struct in_addr *,