Add control interface commands for fetching wpa_config values

The new "DUMP" and "SET <variable>" control interface commands can be
used to fetch global wpa_supplicant configuration parameters.

Signed-off-by: Ola Olsson <ola.olsson@sonymobile.com>
This commit is contained in:
Ola Olsson 2015-01-28 00:22:06 +01:00 committed by Jouni Malinen
parent 2265376271
commit 10263dc2a4
4 changed files with 103 additions and 6 deletions

View file

@ -3556,6 +3556,8 @@ struct global_parse_data {
char *name;
int (*parser)(const struct global_parse_data *data,
struct wpa_config *config, int line, const char *value);
int (*get)(const char *name, struct wpa_config *config, long offset,
char *buf, size_t buflen, int pretty_print);
void *param1, *param2, *param3;
unsigned int changed_flag;
};
@ -4015,22 +4017,55 @@ static int wpa_config_process_no_ctrl_interface(
#endif /* CONFIG_CTRL_IFACE */
static int wpa_config_get_int(const char *name, struct wpa_config *config,
long offset, char *buf, size_t buflen,
int pretty_print)
{
int *val = (int *) (((u8 *) config) + (long) offset);
if (pretty_print)
return os_snprintf(buf, buflen, "%s=%d\n", name, *val);
return os_snprintf(buf, buflen, "%d", *val);
}
static int wpa_config_get_str(const char *name, struct wpa_config *config,
long offset, char *buf, size_t buflen,
int pretty_print)
{
char **val = (char **) (((u8 *) config) + (long) offset);
int res;
if (pretty_print)
res = os_snprintf(buf, buflen, "%s=%s\n", name,
*val ? *val : "null");
else if (!*val)
return -1;
else
res = os_snprintf(buf, buflen, "%s", *val);
if (os_snprintf_error(buflen, res))
res = -1;
return res;
}
#ifdef OFFSET
#undef OFFSET
#endif /* OFFSET */
/* OFFSET: Get offset of a variable within the wpa_config structure */
#define OFFSET(v) ((void *) &((struct wpa_config *) 0)->v)
#define FUNC(f) #f, wpa_config_process_ ## f, OFFSET(f), NULL, NULL
#define FUNC_NO_VAR(f) #f, wpa_config_process_ ## f, NULL, NULL, NULL
#define _INT(f) #f, wpa_global_config_parse_int, OFFSET(f)
#define FUNC(f) #f, wpa_config_process_ ## f, NULL, OFFSET(f), NULL, NULL
#define FUNC_NO_VAR(f) #f, wpa_config_process_ ## f, NULL, NULL, NULL, NULL
#define _INT(f) #f, wpa_global_config_parse_int, wpa_config_get_int, OFFSET(f)
#define INT(f) _INT(f), NULL, NULL
#define INT_RANGE(f, min, max) _INT(f), (void *) min, (void *) max
#define _STR(f) #f, wpa_global_config_parse_str, OFFSET(f)
#define _STR(f) #f, wpa_global_config_parse_str, wpa_config_get_str, OFFSET(f)
#define STR(f) _STR(f), NULL, NULL
#define STR_RANGE(f, min, max) _STR(f), (void *) min, (void *) max
#define BIN(f) #f, wpa_global_config_parse_bin, OFFSET(f), NULL, NULL
#define IPV4(f) #f, wpa_global_config_parse_ipv4, OFFSET(f), NULL, NULL
#define BIN(f) #f, wpa_global_config_parse_bin, NULL, OFFSET(f), NULL, NULL
#define IPV4(f) #f, wpa_global_config_parse_ipv4, NULL, OFFSET(f), NULL, NULL
static const struct global_parse_data global_fields[] = {
#ifdef CONFIG_CTRL_IFACE
@ -4164,6 +4199,50 @@ static const struct global_parse_data global_fields[] = {
#define NUM_GLOBAL_FIELDS ARRAY_SIZE(global_fields)
int wpa_config_dump_values(struct wpa_config *config, char *buf, size_t buflen)
{
int result = 0;
size_t i;
for (i = 0; i < NUM_GLOBAL_FIELDS; i++) {
const struct global_parse_data *field = &global_fields[i];
int tmp;
if (!field->get)
continue;
tmp = field->get(field->name, config, (long) field->param1,
buf, buflen, 1);
if (tmp < 0)
return -1;
buf += tmp;
buflen -= tmp;
result += tmp;
}
return result;
}
int wpa_config_get_value(const char *name, struct wpa_config *config,
char *buf, size_t buflen)
{
size_t i;
for (i = 0; i < NUM_GLOBAL_FIELDS; i++) {
const struct global_parse_data *field = &global_fields[i];
if (os_strcmp(name, field->name) != 0)
continue;
if (!field->get)
break;
return field->get(name, config, (long) field->param1,
buf, buflen, 0);
}
return -1;
}
int wpa_config_process_global(struct wpa_config *config, char *pos, int line)
{
size_t i;

View file

@ -1167,6 +1167,11 @@ int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value,
int line);
int wpa_config_set_quoted(struct wpa_ssid *ssid, const char *var,
const char *value);
int wpa_config_dump_values(struct wpa_config *config, char *buf,
size_t buflen);
int wpa_config_get_value(const char *name, struct wpa_config *config,
char *buf, size_t buflen);
char ** wpa_config_get_all(struct wpa_ssid *ssid, int get_keys);
char * wpa_config_get(struct wpa_ssid *ssid, const char *var);
char * wpa_config_get_no_key(struct wpa_ssid *ssid, const char *var);

View file

@ -498,6 +498,8 @@ static int wpa_supplicant_ctrl_iface_get(struct wpa_supplicant *wpa_s,
#endif /* CONFIG_TESTING_GET_GTK */
} else if (os_strcmp(cmd, "tls_library") == 0) {
res = tls_get_library_version(buf, buflen);
} else {
res = wpa_config_get_value(cmd, wpa_s->conf, buf, buflen);
}
if (os_snprintf_error(buflen, res))
@ -7838,6 +7840,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
} else if (os_strncmp(buf, "SET ", 4) == 0) {
if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4))
reply_len = -1;
} else if (os_strncmp(buf, "DUMP", 4) == 0) {
reply_len = wpa_config_dump_values(wpa_s->conf,
reply, reply_size);
} else if (os_strncmp(buf, "GET ", 4) == 0) {
reply_len = wpa_supplicant_ctrl_iface_get(wpa_s, buf + 4,
reply, reply_size);

View file

@ -658,6 +658,11 @@ static char ** wpa_cli_complete_set(const char *str, int pos)
return NULL;
}
static int wpa_cli_cmd_dump(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
return wpa_ctrl_command(ctrl, "DUMP");
}
static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
@ -2616,6 +2621,9 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
cli_cmd_flag_none,
"= set variables (shows list of variables when run without "
"arguments)" },
{ "dump", wpa_cli_cmd_dump, NULL,
cli_cmd_flag_none,
"= dump config variables" },
{ "get", wpa_cli_cmd_get, NULL,
cli_cmd_flag_none,
"<name> = get information" },