From: Roy Marples Date: Wed, 17 Sep 2008 10:32:55 +0000 (+0000) Subject: Move wireless detection from net.c into if-bsd.c and if-linux.c X-Git-Tag: v5.0.0~238 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f52769ba71d9fac5acbe71a435e6018f2eacd571;p=thirdparty%2Fdhcpcd.git Move wireless detection from net.c into if-bsd.c and if-linux.c --- diff --git a/if-bsd.c b/if-bsd.c index 02f3814d..c4f65e66 100644 --- a/if-bsd.c +++ b/if-bsd.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -61,6 +62,37 @@ 1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(long) - 1) ) ) #endif +int +if_wireless(const char *ifname) +{ + int s, retval = -1; +#if defined(SIOCG80211NWID) + struct ifreq ifr; + struct ieee80211_nwid nwid; +#elif defined(IEEE80211_IOC_SSID) + struct ieee80211req ireq; +#endif + + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) + return retval; +#if defined(SIOCG80211NWID) /* NetBSD */ + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + memset(&nwid, 0, sizeof(nwid)); + ifr.ifr_data = (void *)&nwid; + if (ioctl(s, SIOCG80211NWID, &ifr) == 0) + retval = 0; +#elif defined(IEEE80211_IOC_SSID) /* FreeBSD */ + memset(&ireq, 0, sizeof(ireq)); + strlcpy(ireq.i_name, ifname, sizeof(ireq.i_name)); + ireq.i_type = IEEE80211_IOC_NUMSSIDS; + if (ioctl(s, SIOCG80211, &ireq) == 0) + retval = 0; +#endif + close(s); + return retval; +} + int if_address(const struct interface *iface, const struct in_addr *address, const struct in_addr *netmask, const struct in_addr *broadcast, diff --git a/if-linux.c b/if-linux.c index 590bad18..3fecfe04 100644 --- a/if-linux.c +++ b/if-linux.c @@ -39,6 +39,14 @@ #include #include +# define SIOCGIWNAME 0x8B01 +/* FIXME: Some linux kernel verisons DO NOT like this include + * They have the error: + * /usr/include/linux/if.h:92: error: redefinition of `struct ifmap' + * We work around this by defining the above ioctl and using an ifreq + * structure which seems to work fine. */ +//# include + #include #include #include @@ -64,6 +72,22 @@ static void (*nl_carrier)(const char *) = NULL; static void (*nl_add)(const char *) = NULL; static void (*nl_remove)(const char *) = NULL; +int +if_wireless(const char *ifname) +{ + int s, retval = -1; + struct ifreq ifr; + + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) + return retval; + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + if (ioctl(s, SIOCGIWNAME, &ifr) == 0) + retval = 0; + close(s); + return retval; +} + int open_link_socket(void) { diff --git a/net.c b/net.c index 311adf22..f99251b5 100644 --- a/net.c +++ b/net.c @@ -40,25 +40,9 @@ #define __FAVOR_BSD /* Nasty glibc hack so we can use BSD semantics for UDP */ #include #undef __FAVOR_BSD -#ifdef AF_LINK -# include -#endif #ifdef SIOCGIFMEDIA # include #endif -#ifdef BSD -# include -# include -#endif -#ifdef __linux__ -# define SIOCGIWNAME 0x8B01 -/* FIXME: Some linux kernel verisons DO NOT like this include - * They have the error: - * /usr/include/linux/if.h:92: error: redefinition of `struct ifmap' - * We work around this by defining the above ioctl and using an ifreq - * structure which seems to work fine. */ -//# include -#endif #include #include @@ -193,14 +177,6 @@ init_interface(const char *ifname) int s, arpable; struct ifreq ifr; struct interface *iface = NULL; -#if defined(SIOCGIWNAME) -// FIXME: See comment in includes above -// struct iwreq iwr; -#elif defined(SIOCG80211NWID) - struct ieee80211_nwid nwid; -#elif defined(IEEE80211_IOC_SSID) - struct ieee80211req ireq; -#endif memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); @@ -217,7 +193,11 @@ init_interface(const char *ifname) iface = xzalloc(sizeof(*iface)); strlcpy(iface->name, ifname, sizeof(iface->name)); - iface->metric = 100 + if_nametoindex(iface->name); + /* We reserve the 100 range for virtual interfaces, if and when + * we can work them out. */ + iface->metric = 200 + if_nametoindex(iface->name); + if (if_wireless(ifname) == 0) + iface->metric += 100; #ifdef SIOCGIFHWADDR strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); @@ -239,7 +219,8 @@ init_interface(const char *ifname) if (!(options & DHCPCD_MASTER && !(options & DHCPCD_DAEMONISED) && options & DHCPCD_QUIET)) - syslog(LOG_ERR, "%s: unsupported media family", iface->name); + syslog(LOG_ERR, "%s: unsupported media family", + iface->name); goto eexit; } memcpy(iface->hwaddr, ifr.ifr_hwaddr.sa_data, iface->hwlen); @@ -256,32 +237,11 @@ init_interface(const char *ifname) goto eexit; } - /* If the interface is wireless, add 100 to the metric. - * We do this so we prefer other interfaces if they provide - * similar configuration on the same subnet. */ -#if defined(SIOCGIWNAME) /* Linux */ - if (ioctl(s, SIOCGIWNAME, &ifr) != -1) - iface->metric += 100; -#elif defined(SIOCG80211NWID) /* NetBSD */ - memset(&nwid, 0, sizeof(nwid)); - ifr.ifr_data = (void *)&nwid; - if (ioctl(s, SIOCG80211NWID) != -1) - iface->metric += 100; -#elif defined(IEEE80211_IOC_SSID) /* FreeBSD */ - memset(&ireq, 0, sizeof(ireq)); - strlcpy(ireq.i_name, ifname, sizeof(ireq.i_name)); - ireq.i_type = IEEE80211_IOC_NUMSSIDS; - if (ioctl(s, SIOCG80211, &ireq) != -1) - iface->metric += 100; -#endif - if (up_interface(ifname) != 0) goto eexit; - snprintf(iface->leasefile, sizeof(iface->leasefile), LEASEFILE, ifname); iface->arpable = arpable; - /* 0 is a valid fd, so init to -1 */ iface->raw_fd = -1; iface->udp_fd = -1; diff --git a/net.h b/net.h index 5750349a..29e7df36 100644 --- a/net.h +++ b/net.h @@ -91,6 +91,7 @@ uint32_t get_netmask(uint32_t); char *hwaddr_ntoa(const unsigned char *, size_t); size_t hwaddr_aton(unsigned char *, const char *); +int if_wireless(const char *); struct interface *init_interface(const char *); struct interface *discover_interfaces(int, char * const *); void free_interface(struct interface *);