[PATCH 3/5] -m <ifname_match> matches interface names via fnmatch(3) and assigns them the default configuration file, like so

Roy Marples roy
Tue May 26 14:25:16 PDT 2009


wpa_supplicant -c /etc/wpa_supplicant.conf -m "*"

This makes every interface try to initialize with the default driver,
whch distribution setup a lot easier.
This can be used in the future to for wpa_supplicant to startup
on interfaces that do not exist at boot, like for say pcmcia interfaces.

Signed-off-by: Roy Marples <roy at marples.name>
---
 wpa_supplicant/main.c             |   50 +++++++++++++++++++++++++++++++++---
 wpa_supplicant/wpa_supplicant.c   |   22 ++++++++++++++++
 wpa_supplicant/wpa_supplicant_i.h |   14 ++++++++++
 3 files changed, 81 insertions(+), 5 deletions(-)

diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c
index 7e77e3f..2869b45 100644
--- a/wpa_supplicant/main.c
+++ b/wpa_supplicant/main.c
@@ -16,6 +16,7 @@
 #ifdef __linux__
 #include <fcntl.h>
 #endif /* __linux__ */
+#include <net/if.h>
 
 #include "common.h"
 #include "wpa_supplicant_i.h"
@@ -30,7 +31,7 @@ static void usage(void)
 	printf("%s\n\n%s\n"
 	       "usage:\n"
 	       "  wpa_supplicant [-BddhKLqqstuvW] [-P<pid file>] "
-	       "[-g<global ctrl>] \\\n"
+	       "[-g<global ctrl>] -[m<ifname_match] \\\n"
 	       "        -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] "
 	       "[-p<driver_param>] \\\n"
 	       "        [-b<br_ifname>] [-f<debug file>] \\\n"
@@ -67,6 +68,7 @@ static void usage(void)
 	printf("  -t = include timestamp in debug messages\n"
 	       "  -h = show this help text\n"
 	       "  -L = show license (GPL and BSD)\n"
+	       "  -m = dynamically add/remove matching interface names\n"
 	       "  -p = driver parameters\n"
 	       "  -P = PID file\n"
 	       "  -q = decrease debugging verbosity (-qq even less)\n");
@@ -118,13 +120,15 @@ static void wpa_supplicant_fd_workaround(void)
 }
 
 
-int main(int argc, char *argv[])
+int main(int argc, char **argv)
 {
 	int c, i;
 	struct wpa_interface *ifaces, *iface;
-	int iface_count, exitcode = -1;
+	int iface_count, exitcode = -1, ifname_count = 0;
 	struct wpa_params params;
 	struct wpa_global *global;
+	struct if_nameindex *ifi;
+	char **ifname_match = NULL;
 
 	if (os_program_init())
 		return -1;
@@ -140,7 +144,7 @@ int main(int argc, char *argv[])
 	wpa_supplicant_fd_workaround();
 
 	for (;;) {
-		c = getopt(argc, argv, "b:Bc:C:D:df:g:hi:KLNp:P:qstuvW");
+		c = getopt(argc, argv, "b:Bc:C:D:df:g:hi:KLm:Np:P:qstuvW");
 		if (c < 0)
 			break;
 		switch (c) {
@@ -184,6 +188,19 @@ int main(int argc, char *argv[])
 		case 'i':
 			iface->ifname = optarg;
 			break;
+		case 'm':
+			ifname_count++;
+			ifname_match = os_realloc(params.ifname_match,
+					sizeof(char *) *
+					(ifname_count + 1));
+			if (ifname_match == NULL)
+				goto out;
+			ifname_match[ifname_count - 1] = optarg;
+			ifname_match[ifname_count] = NULL;
+			params.ifname_match = ifname_match;
+			break;
+
+			break;
 		case 'K':
 			params.wpa_debug_show_keys++;
 			break;
@@ -237,6 +254,14 @@ int main(int argc, char *argv[])
 			goto out;
 		}
 	}
+	argc -= optind;
+	argv += optind;
+
+	/* If we're matching, use the default config. */
+	if (ifname_match != NULL) {
+		params.confname = ifaces[0].confname;
+		params.ifname_match = ifname_match;
+	}
 
 	exitcode = 0;
 	global = wpa_supplicant_init(&params);
@@ -251,7 +276,8 @@ int main(int argc, char *argv[])
 		     ifaces[i].ctrl_interface == NULL) ||
 		    ifaces[i].ifname == NULL) {
 			if (iface_count == 1 && (params.ctrl_interface ||
-						 params.dbus_ctrl_interface))
+						 params.dbus_ctrl_interface ||
+						 params.ifname_match))
 				break;
 			usage();
 			exitcode = -1;
@@ -261,6 +287,19 @@ int main(int argc, char *argv[])
 			exitcode = -1;
 	}
 
+	/* Add initial interfaces */
+	if (ifname_match != NULL) {
+		for (ifi = if_nameindex(); ifi->if_name; ifi++) {
+			if (!wpa_supplicant_match_iface(global, ifi->if_name))
+				continue;
+			iface = os_zalloc(sizeof(*iface));
+			iface->ifname = ifi->if_name;
+			iface->confname = params.confname;
+			wpa_supplicant_add_iface(global, iface);
+			os_free(iface);
+		}
+	}
+
 	if (exitcode == 0)
 		exitcode = wpa_supplicant_run(global);
 
@@ -268,6 +307,7 @@ int main(int argc, char *argv[])
 
 out:
 	os_free(ifaces);
+	os_free(ifname_match);
 	os_free(params.pid_file);
 
 	os_program_deinit();
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 4c6c248..457d8e0 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -16,6 +16,8 @@
  * functions for managing network connections.
  */
 
+#include <fnmatch.h>
+
 #include "includes.h"
 
 #include "common.h"
@@ -1987,6 +1989,24 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s)
 		wpa_drv_deinit(wpa_s);
 }
 
+/**
+ * wpa_supplicant_match_iface - See if an interface name matches allowed names
+ * @global: Pointer to global data from wpa_supplicant_init()
+ * @ifname: Name of the interface to match
+ * Returns: Pointer to the name of the interface
+ */
+const char * wpa_supplicant_match_iface(struct wpa_global *global,
+					const char *ifname)
+{
+	char **p;
+
+	for (p = global->params.ifname_match; p && *p; p++) {
+		if (fnmatch(*p, ifname, 0) == 0)
+			return ifname;
+	}
+	errno = ESRCH;
+	return NULL;
+}
 
 /**
  * wpa_supplicant_add_iface - Add a new network interface
@@ -2141,6 +2161,8 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
 	global->params.daemonize = params->daemonize;
 	global->params.wait_for_monitor = params->wait_for_monitor;
 	global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
+	global->params.ifname_match = params->ifname_match;
+	global->params.confname = params->confname;
 	if (params->pid_file)
 		global->params.pid_file = os_strdup(params->pid_file);
 	if (params->ctrl_interface)
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 25e5ab2..565a961 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -160,6 +160,18 @@ struct wpa_params {
 	 * wpa_debug_syslog - Enable log output through syslog
 	 */
 	int wpa_debug_syslog;
+
+	/**
+	 * ifname_match - list of interface names for fnmatch(3)
+	 */
+	char **ifname_match;
+
+	/**
+	 * confname - Configuration name (file or profile) name
+	 *
+	 * This is used as a default configuration for dynamically added interfaces
+	 */
+	const char *confname;
 };
 
 /**
@@ -416,6 +428,8 @@ void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s,
 
 void wpa_show_license(void);
 
+const char * wpa_supplicant_match_iface(struct wpa_global *global,
+					const char *ifname);
 struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
 						 struct wpa_interface *iface);
 int wpa_supplicant_remove_iface(struct wpa_global *global,
-- 
1.6.2.5




More information about the Hostap mailing list