changeset 989:8fdf3d467846 draft

Move AF_LINK discovery to if-bsd.c. Also, we only work with IFT_ETHER types currently, so skip others.
author Roy Marples <roy@marples.name>
date Tue, 16 Sep 2008 09:55:46 +0000
parents 8ce4e6b80d5c
children fc8bf2dc1c2d
files if-bsd.c net.c net.h
diffstat 3 files changed, 70 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/if-bsd.c	Mon Sep 15 19:31:18 2008 +0000
+++ b/if-bsd.c	Tue Sep 16 09:55:46 2008 +0000
@@ -39,15 +39,18 @@
 #include <netinet/in.h>
 
 #include <errno.h>
+#include <fnmatch.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <syslog.h>
 #include <unistd.h>
 
 #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 @@
 	}
 }
 
+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;
 }
--- a/net.c	Mon Sep 15 19:31:18 2008 +0000
+++ b/net.c	Tue Sep 16 09:55:46 2008 +0000
@@ -47,6 +47,7 @@
 # include <net/if_media.h>
 #endif
 #ifdef BSD
+# include <net/if_types.h>
 # include <net80211/ieee80211_ioctl.h>
 #endif
 #ifdef __linux__
@@ -61,7 +62,6 @@
 
 #include <ctype.h>
 #include <errno.h>
-#include <fnmatch.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -138,7 +138,7 @@
 	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 @@
 	}
 	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 @@
 
 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 @@
 	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 @@
 
 		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));
--- a/net.h	Mon Sep 15 19:31:18 2008 +0000
+++ b/net.h	Tue Sep 16 09:55:46 2008 +0000
@@ -102,8 +102,8 @@
 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 *,