diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 1ffc2dca2..ea633a61a 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -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; diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 6adf1eb38..2e5499402 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -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); diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 0162b6c51..bbc6bd60b 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -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); diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index af08e1303..5a0af0dc9 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -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, " = get information" },