Added a mechanism for quering driver wrappers for available interfaces
The new INTERFACE_LIST global control interface command can be used to request a list of all available network interfaces that could be used with the enabled driver wrappers. This could be used to enable interfaces automatically by external programs (e.g., wpa_gui).
This commit is contained in:
parent
3cf85239bd
commit
4b4a8ae547
6 changed files with 129 additions and 3 deletions
|
@ -125,6 +125,23 @@ struct wpa_scan_results {
|
||||||
size_t num;
|
size_t num;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct wpa_interface_info - Network interface information
|
||||||
|
* @next: Pointer to the next interface or NULL if this is the last one
|
||||||
|
* @ifname: Interface name that can be used with init() or init2()
|
||||||
|
* @desc: Human readable adapter description (e.g., vendor/model) or NULL if
|
||||||
|
* not available
|
||||||
|
* @drv_bame: struct wpa_driver_ops::name (note: unlike other strings, this one
|
||||||
|
* is not an allocated copy, i.e., get_interfaces() caller will not free
|
||||||
|
* this)
|
||||||
|
*/
|
||||||
|
struct wpa_interface_info {
|
||||||
|
struct wpa_interface_info *next;
|
||||||
|
char *ifname;
|
||||||
|
char *desc;
|
||||||
|
const char *drv_name;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct wpa_driver_associate_params - Association parameters
|
* struct wpa_driver_associate_params - Association parameters
|
||||||
* Data for struct wpa_driver_ops::associate().
|
* Data for struct wpa_driver_ops::associate().
|
||||||
|
@ -991,6 +1008,15 @@ struct wpa_driver_ops {
|
||||||
* uses global data.
|
* uses global data.
|
||||||
*/
|
*/
|
||||||
void * (*init2)(void *ctx, const char *ifname, void *global_priv);
|
void * (*init2)(void *ctx, const char *ifname, void *global_priv);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_interfaces - Get information about available interfaces
|
||||||
|
* @global_priv: private driver global data from global_init()
|
||||||
|
* Returns: Allocated buffer of interface information (caller is
|
||||||
|
* responsible for freeing the data structure) on success, NULL on
|
||||||
|
* failure
|
||||||
|
*/
|
||||||
|
struct wpa_interface_info * (*get_interfaces)(void *global_priv);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Function to check whether a driver is for wired connections */
|
/* Function to check whether a driver is for wired connections */
|
||||||
|
|
|
@ -2887,5 +2887,6 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = {
|
||||||
NULL /* set_country */,
|
NULL /* set_country */,
|
||||||
NULL /* global_init */,
|
NULL /* global_init */,
|
||||||
NULL /* global_deinit */,
|
NULL /* global_deinit */,
|
||||||
NULL /* init2 */
|
NULL /* init2 */,
|
||||||
|
NULL /* get_interfaces */
|
||||||
};
|
};
|
||||||
|
|
|
@ -778,7 +778,8 @@ struct wpa_driver_ops wpa_driver_privsep_ops = {
|
||||||
NULL /* set_country */,
|
NULL /* set_country */,
|
||||||
NULL /* global_init */,
|
NULL /* global_init */,
|
||||||
NULL /* global_deinit */,
|
NULL /* global_deinit */,
|
||||||
NULL /* init2 */
|
NULL /* init2 */,
|
||||||
|
NULL /* get_interfaces */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1147,6 +1147,29 @@ static void wpa_driver_test_global_deinit(void *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct wpa_interface_info *
|
||||||
|
wpa_driver_test_get_interfaces(void *global_priv)
|
||||||
|
{
|
||||||
|
/* struct wpa_driver_test_global *global = priv; */
|
||||||
|
struct wpa_interface_info *iface;
|
||||||
|
|
||||||
|
iface = os_zalloc(sizeof(*iface));
|
||||||
|
if (iface == NULL)
|
||||||
|
return iface;
|
||||||
|
iface->ifname = os_strdup("sta0");
|
||||||
|
iface->desc = os_strdup("test interface 0");
|
||||||
|
iface->drv_name = "test";
|
||||||
|
iface->next = os_zalloc(sizeof(*iface));
|
||||||
|
if (iface->next) {
|
||||||
|
iface->next->ifname = os_strdup("sta1");
|
||||||
|
iface->next->desc = os_strdup("test interface 1");
|
||||||
|
iface->next->drv_name = "test";
|
||||||
|
}
|
||||||
|
|
||||||
|
return iface;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const struct wpa_driver_ops wpa_driver_test_ops = {
|
const struct wpa_driver_ops wpa_driver_test_ops = {
|
||||||
"test",
|
"test",
|
||||||
"wpa_supplicant test driver",
|
"wpa_supplicant test driver",
|
||||||
|
@ -1200,5 +1223,6 @@ const struct wpa_driver_ops wpa_driver_test_ops = {
|
||||||
NULL /* set_country */,
|
NULL /* set_country */,
|
||||||
wpa_driver_test_global_init,
|
wpa_driver_test_global_init,
|
||||||
wpa_driver_test_global_deinit,
|
wpa_driver_test_global_deinit,
|
||||||
wpa_driver_test_init2
|
wpa_driver_test_init2,
|
||||||
|
wpa_driver_test_get_interfaces
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,7 +30,10 @@
|
||||||
#include "wps_supplicant.h"
|
#include "wps_supplicant.h"
|
||||||
#include "wps/wps.h"
|
#include "wps/wps.h"
|
||||||
|
|
||||||
|
extern struct wpa_driver_ops *wpa_supplicant_drivers[];
|
||||||
|
|
||||||
|
static int wpa_supplicant_global_iface_list(struct wpa_global *global,
|
||||||
|
char *buf, int len);
|
||||||
static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
|
static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
|
||||||
char *buf, int len);
|
char *buf, int len);
|
||||||
|
|
||||||
|
@ -1624,6 +1627,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
||||||
} else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) {
|
} else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) {
|
||||||
if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8))
|
if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8))
|
||||||
reply_len = -1;
|
reply_len = -1;
|
||||||
|
} else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
|
||||||
|
reply_len = wpa_supplicant_global_iface_list(
|
||||||
|
wpa_s->global, reply, reply_size);
|
||||||
} else if (os_strcmp(buf, "INTERFACES") == 0) {
|
} else if (os_strcmp(buf, "INTERFACES") == 0) {
|
||||||
reply_len = wpa_supplicant_global_iface_interfaces(
|
reply_len = wpa_supplicant_global_iface_interfaces(
|
||||||
wpa_s->global, reply, reply_size);
|
wpa_s->global, reply, reply_size);
|
||||||
|
@ -1739,6 +1745,63 @@ static int wpa_supplicant_global_iface_remove(struct wpa_global *global,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wpa_free_iface_info(struct wpa_interface_info *iface)
|
||||||
|
{
|
||||||
|
struct wpa_interface_info *prev;
|
||||||
|
|
||||||
|
while (iface) {
|
||||||
|
prev = iface;
|
||||||
|
iface = iface->next;
|
||||||
|
|
||||||
|
os_free(prev->ifname);
|
||||||
|
os_free(prev->desc);
|
||||||
|
os_free(prev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_supplicant_global_iface_list(struct wpa_global *global,
|
||||||
|
char *buf, int len)
|
||||||
|
{
|
||||||
|
int i, res;
|
||||||
|
struct wpa_interface_info *iface = NULL, *last = NULL, *tmp;
|
||||||
|
char *pos, *end;
|
||||||
|
|
||||||
|
for (i = 0; wpa_supplicant_drivers[i]; i++) {
|
||||||
|
struct wpa_driver_ops *drv = wpa_supplicant_drivers[i];
|
||||||
|
if (drv->get_interfaces == NULL)
|
||||||
|
continue;
|
||||||
|
tmp = drv->get_interfaces(global->drv_priv);
|
||||||
|
if (tmp == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (last == NULL)
|
||||||
|
iface = last = tmp;
|
||||||
|
else
|
||||||
|
last->next = tmp;
|
||||||
|
while (last->next)
|
||||||
|
last = last->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = buf;
|
||||||
|
end = buf + len;
|
||||||
|
for (tmp = iface; tmp; tmp = tmp->next) {
|
||||||
|
res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n",
|
||||||
|
tmp->drv_name, tmp->ifname,
|
||||||
|
tmp->desc ? tmp->desc : "");
|
||||||
|
if (res < 0 || res >= end - pos) {
|
||||||
|
*pos = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += res;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_free_iface_info(iface);
|
||||||
|
|
||||||
|
return pos - buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
|
static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
|
||||||
char *buf, int len)
|
char *buf, int len)
|
||||||
{
|
{
|
||||||
|
@ -1791,6 +1854,9 @@ char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
|
||||||
} else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) {
|
} else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) {
|
||||||
if (wpa_supplicant_global_iface_remove(global, buf + 17))
|
if (wpa_supplicant_global_iface_remove(global, buf + 17))
|
||||||
reply_len = -1;
|
reply_len = -1;
|
||||||
|
} else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
|
||||||
|
reply_len = wpa_supplicant_global_iface_list(
|
||||||
|
global, reply, reply_size);
|
||||||
} else if (os_strcmp(buf, "INTERFACES") == 0) {
|
} else if (os_strcmp(buf, "INTERFACES") == 0) {
|
||||||
reply_len = wpa_supplicant_global_iface_interfaces(
|
reply_len = wpa_supplicant_global_iface_interfaces(
|
||||||
global, reply, reply_size);
|
global, reply, reply_size);
|
||||||
|
|
|
@ -1120,6 +1120,13 @@ static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct wpa_cli_cmd {
|
struct wpa_cli_cmd {
|
||||||
const char *cmd;
|
const char *cmd;
|
||||||
int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
|
int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
|
||||||
|
@ -1166,6 +1173,7 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
|
||||||
{ "terminate", wpa_cli_cmd_terminate },
|
{ "terminate", wpa_cli_cmd_terminate },
|
||||||
{ "interface_add", wpa_cli_cmd_interface_add },
|
{ "interface_add", wpa_cli_cmd_interface_add },
|
||||||
{ "interface_remove", wpa_cli_cmd_interface_remove },
|
{ "interface_remove", wpa_cli_cmd_interface_remove },
|
||||||
|
{ "interface_list", wpa_cli_cmd_interface_list },
|
||||||
{ "ap_scan", wpa_cli_cmd_ap_scan },
|
{ "ap_scan", wpa_cli_cmd_ap_scan },
|
||||||
{ "stkstart", wpa_cli_cmd_stkstart },
|
{ "stkstart", wpa_cli_cmd_stkstart },
|
||||||
{ "ft_ds", wpa_cli_cmd_ft_ds },
|
{ "ft_ds", wpa_cli_cmd_ft_ds },
|
||||||
|
|
Loading…
Reference in a new issue