aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant/wpa_supplicant.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2016-03-15 13:40:14 (GMT)
committerJouni Malinen <j@w1.fi>2016-03-22 15:41:37 (GMT)
commit2e997eece5776eca0a99d53893e343539f9f8eb2 (patch)
tree0cb953a6723f566c7c62400439ce911416e330bb /wpa_supplicant/wpa_supplicant.c
parent45e3fc72c61a61dbd1e2fc3fd9fd7bf853b9f5fe (diff)
downloadhostap-2e997eece5776eca0a99d53893e343539f9f8eb2.zip
hostap-2e997eece5776eca0a99d53893e343539f9f8eb2.tar.gz
hostap-2e997eece5776eca0a99d53893e343539f9f8eb2.tar.bz2
Add interface matching support with -M, guarded by CONFIG_MATCH_IFACE
The new wpa_supplicant command line argument -M can be used to describe matching rules with a wildcard interface name (e.g., "wlan*"). This is very useful for systems without udev (Linux) or devd (FreeBSD). Signed-off-by: Roy Marples <roy@marples.name>
Diffstat (limited to 'wpa_supplicant/wpa_supplicant.c')
-rw-r--r--wpa_supplicant/wpa_supplicant.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 7b43600..047ca10 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -11,6 +11,10 @@
*/
#include "includes.h"
+#ifdef CONFIG_MATCH_IFACE
+#include <net/if.h>
+#include <fnmatch.h>
+#endif /* CONFIG_MATCH_IFACE */
#include "common.h"
#include "crypto/random.h"
@@ -4911,6 +4915,74 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
}
+#ifdef CONFIG_MATCH_IFACE
+
+/**
+ * wpa_supplicant_match_iface - Match an interface description to a name
+ * @global: Pointer to global data from wpa_supplicant_init()
+ * @ifname: Name of the interface to match
+ * Returns: Pointer to the created interface description or %NULL on failure
+ */
+struct wpa_interface * wpa_supplicant_match_iface(struct wpa_global *global,
+ const char *ifname)
+{
+ int i;
+ struct wpa_interface *iface, *miface;
+
+ for (i = 0; i < global->params.match_iface_count; i++) {
+ miface = &global->params.match_ifaces[i];
+ if (!miface->ifname ||
+ fnmatch(miface->ifname, ifname, 0) == 0) {
+ iface = os_zalloc(sizeof(*iface));
+ if (!iface)
+ return NULL;
+ *iface = *miface;
+ iface->ifname = ifname;
+ return iface;
+ }
+ }
+
+ return NULL;
+}
+
+
+/**
+ * wpa_supplicant_match_existing - Match existing interfaces
+ * @global: Pointer to global data from wpa_supplicant_init()
+ * Returns: 0 on success, -1 on failure
+ */
+static int wpa_supplicant_match_existing(struct wpa_global *global)
+{
+ struct if_nameindex *ifi, *ifp;
+ struct wpa_supplicant *wpa_s;
+ struct wpa_interface *iface;
+
+ ifp = if_nameindex();
+ if (!ifp) {
+ wpa_printf(MSG_ERROR, "if_nameindex: %s", strerror(errno));
+ return -1;
+ }
+
+ for (ifi = ifp; ifi->if_name; ifi++) {
+ wpa_s = wpa_supplicant_get_iface(global, ifi->if_name);
+ if (wpa_s)
+ continue;
+ iface = wpa_supplicant_match_iface(global, ifi->if_name);
+ if (iface) {
+ wpa_s = wpa_supplicant_add_iface(global, iface, NULL);
+ os_free(iface);
+ if (wpa_s)
+ wpa_s->matched = 1;
+ }
+ }
+
+ if_freenameindex(ifp);
+ return 0;
+}
+
+#endif /* CONFIG_MATCH_IFACE */
+
+
/**
* wpa_supplicant_add_iface - Add a new network interface
* @global: Pointer to global data from wpa_supplicant_init()
@@ -5212,6 +5284,18 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
if (params->override_ctrl_interface)
global->params.override_ctrl_interface =
os_strdup(params->override_ctrl_interface);
+#ifdef CONFIG_MATCH_IFACE
+ global->params.match_iface_count = params->match_iface_count;
+ if (params->match_iface_count) {
+ global->params.match_ifaces =
+ os_calloc(params->match_iface_count,
+ sizeof(struct wpa_interface));
+ os_memcpy(global->params.match_ifaces,
+ params->match_ifaces,
+ params->match_iface_count *
+ sizeof(struct wpa_interface));
+ }
+#endif /* CONFIG_MATCH_IFACE */
#ifdef CONFIG_P2P
if (params->conf_p2p_dev)
global->params.conf_p2p_dev =
@@ -5291,6 +5375,11 @@ int wpa_supplicant_run(struct wpa_global *global)
eloop_sock_requeue()))
return -1;
+#ifdef CONFIG_MATCH_IFACE
+ if (wpa_supplicant_match_existing(global))
+ return -1;
+#endif
+
if (global->params.wait_for_monitor) {
for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
if (wpa_s->ctrl_iface && !wpa_s->p2p_mgmt)
@@ -5359,6 +5448,9 @@ void wpa_supplicant_deinit(struct wpa_global *global)
os_free(global->params.ctrl_interface_group);
os_free(global->params.override_driver);
os_free(global->params.override_ctrl_interface);
+#ifdef CONFIG_MATCH_IFACE
+ os_free(global->params.match_ifaces);
+#endif /* CONFIG_MATCH_IFACE */
#ifdef CONFIG_P2P
os_free(global->params.conf_p2p_dev);
#endif /* CONFIG_P2P */