From: Roy Marples Date: Thu, 28 May 2009 15:09:56 +0100 Subject: [PATCH3/5] -m matches interface name and assigns a default config This allows wpa_supplicant -c /etc/wpa_supplicant.conf -m "*" which makes every interface try to initialize with the default driver, which 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. --- wpa_supplicant/main.c | 33 +++++++++++++++++++++++---- wpa_supplicant/wpa_supplicant.c | 45 +++++++++++++++++++++++++++++++++++++ wpa_supplicant/wpa_supplicant_i.h | 14 +++++++++++ 3 files changed, 87 insertions(+), 5 deletions(-) diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c index 7e77e3f..b1a5892 100644 --- a/wpa_supplicant/main.c +++ b/wpa_supplicant/main.c @@ -30,7 +30,7 @@ static void usage(void) printf("%s\n\n%s\n" "usage:\n" " wpa_supplicant [-BddhKLqqstuvW] [-P] " - "[-g] \\\n" + "[-g] -[m -c [-C] [-D] " "[-p] \\\n" " [-b] [-f] \\\n" @@ -67,6 +67,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 +119,14 @@ 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; + char **ifname_match = NULL; if (os_program_init()) return -1; @@ -140,7 +142,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 +186,17 @@ 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; case 'K': params.wpa_debug_show_keys++; break; @@ -237,6 +250,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(¶ms); @@ -251,7 +272,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; @@ -268,6 +290,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..4e795b7 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -44,6 +44,11 @@ #include "sme.h" #include "ap.h" +#ifndef CONFIG_NATIVE_WINDOWS +#include +#include +#endif + const char *wpa_supplicant_version = "wpa_supplicant v" VERSION_STR "\n" "Copyright (c) 2003-2009, Jouni Malinen and contributors"; @@ -1987,6 +1992,28 @@ 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++) { +#ifdef CONFIG_NATIVE_WINDOWS + if (strcmp(*p, ifname) == 0) +#else + if (fnmatch(*p, ifname, 0) == 0) +#endif + return ifname; + } + errno = ESRCH; + return NULL; +} /** * wpa_supplicant_add_iface - Add a new network interface @@ -2141,6 +2168,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) @@ -2214,6 +2243,22 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params) int wpa_supplicant_run(struct wpa_global *global) { struct wpa_supplicant *wpa_s; +#ifndef CONFIG_NATIVE_WINDOWS + struct if_nameindex *ifi; + struct wpa_interface iface; + + /* Add initial interfaces */ + if (global->params.ifname_match != NULL) { + for (ifi = if_nameindex(); ifi->if_name; ifi++) { + if (!wpa_supplicant_match_iface(global, ifi->if_name)) + continue; + os_memset(&iface, 0, sizeof(iface)); + iface.ifname = ifi->if_name; + iface.confname = global->params.confname; + wpa_supplicant_add_iface(global, &iface); + } + } +#endif if (global->params.daemonize && wpa_supplicant_daemon(global->params.pid_file)) 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