changeset 995:9816d4283941 draft

Move wireless detection from net.c into if-bsd.c and if-linux.c
author Roy Marples <roy@marples.name>
date Wed, 17 Sep 2008 10:32:55 +0000
parents 2f75a16390e0
children 46cb7799f9d3
files if-bsd.c if-linux.c net.c net.h
diffstat 4 files changed, 64 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/if-bsd.c	Wed Sep 17 10:32:34 2008 +0000
+++ b/if-bsd.c	Wed Sep 17 10:32:55 2008 +0000
@@ -37,6 +37,7 @@
 #include <net/if_types.h>
 #include <net/route.h>
 #include <netinet/in.h>
+#include <net80211/ieee80211_ioctl.h>
 
 #include <errno.h>
 #include <fnmatch.h>
@@ -62,6 +63,37 @@
 #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,
 	   int action)
--- a/if-linux.c	Wed Sep 17 10:32:34 2008 +0000
+++ b/if-linux.c	Wed Sep 17 10:32:55 2008 +0000
@@ -39,6 +39,14 @@
 #include <netinet/ether.h>
 #include <netpacket/packet.h>
 
+# 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 <linux/wireless.h>
+
 #include <errno.h>
 #include <ctype.h>
 #include <fnmatch.h>
@@ -65,6 +73,22 @@
 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)
 {
 	int fd;
--- a/net.c	Wed Sep 17 10:32:34 2008 +0000
+++ b/net.c	Wed Sep 17 10:32:55 2008 +0000
@@ -40,25 +40,9 @@
 #define __FAVOR_BSD /* Nasty glibc hack so we can use BSD semantics for UDP */
 #include <netinet/udp.h>
 #undef __FAVOR_BSD
-#ifdef AF_LINK
-# include <net/if_dl.h>
-#endif
 #ifdef SIOCGIFMEDIA
 # include <net/if_media.h>
 #endif
-#ifdef BSD
-# include <net/if_types.h>
-# include <net80211/ieee80211_ioctl.h>
-#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 <linux/wireless.h>
-#endif
 
 #include <ctype.h>
 #include <errno.h>
@@ -193,14 +177,6 @@
 	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 @@
 
 	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 @@
 		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 @@
 			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;
--- a/net.h	Wed Sep 17 10:32:34 2008 +0000
+++ b/net.h	Wed Sep 17 10:32:55 2008 +0000
@@ -91,6 +91,7 @@
 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 *);