diff options
Diffstat (limited to 'hostapd/hostapd_cli.c')
-rw-r--r-- | hostapd/hostapd_cli.c | 332 |
1 files changed, 295 insertions, 37 deletions
diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c index e8e1bb24a1c5..3f00cbbf0cc7 100644 --- a/hostapd/hostapd_cli.c +++ b/hostapd/hostapd_cli.c @@ -1,6 +1,6 @@ /* * hostapd - command line interface for hostapd daemon - * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> + * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi> * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -18,7 +18,7 @@ static const char *hostapd_cli_version = "hostapd_cli v" VERSION_STR "\n" -"Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> and contributors"; +"Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi> and contributors"; static const char *hostapd_cli_license = @@ -79,6 +79,7 @@ static const char *commands_help = #endif /* CONFIG_WPS_NFC */ " wps_ap_pin <cmd> [params..] enable/disable AP PIN\n" " wps_config <SSID> <auth> <encr> <key> configure AP\n" +" wps_get_status show current WPS status\n" #endif /* CONFIG_WPS */ " get_config show current configuration\n" " help show this usage help\n" @@ -90,7 +91,12 @@ static const char *commands_help = static struct wpa_ctrl *ctrl_conn; static int hostapd_cli_quit = 0; static int hostapd_cli_attached = 0; -static const char *ctrl_iface_dir = "/var/run/hostapd"; + +#ifndef CONFIG_CTRL_IFACE_DIR +#define CONFIG_CTRL_IFACE_DIR "/var/run/hostapd" +#endif /* CONFIG_CTRL_IFACE_DIR */ +static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR; + static char *ctrl_ifname = NULL; static const char *pid_file = NULL; static const char *action_file = NULL; @@ -210,8 +216,21 @@ static int hostapd_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[]) } +static int hostapd_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + if (argc > 0 && os_strcmp(argv[0], "driver") == 0) + return wpa_ctrl_command(ctrl, "STATUS-DRIVER"); + return wpa_ctrl_command(ctrl, "STATUS"); +} + + static int hostapd_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[]) { + if (argc > 0) { + char buf[100]; + os_snprintf(buf, sizeof(buf), "MIB %s", argv[0]); + return wpa_ctrl_command(ctrl, buf); + } return wpa_ctrl_command(ctrl, "MIB"); } @@ -219,28 +238,19 @@ static int hostapd_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[]) static int hostapd_cli_exec(const char *program, const char *arg1, const char *arg2) { - char *cmd; + char *arg; size_t len; int res; - int ret = 0; - len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3; - cmd = os_malloc(len); - if (cmd == NULL) - return -1; - res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2); - if (res < 0 || (size_t) res >= len) { - os_free(cmd); + len = os_strlen(arg1) + os_strlen(arg2) + 2; + arg = os_malloc(len); + if (arg == NULL) return -1; - } - cmd[len - 1] = '\0'; -#ifndef _WIN32_WCE - if (system(cmd) < 0) - ret = -1; -#endif /* _WIN32_WCE */ - os_free(cmd); + os_snprintf(arg, len, "%s %s", arg1, arg2); + res = os_exec(program, arg, 1); + os_free(arg); - return ret; + return res; } @@ -264,12 +274,15 @@ static void hostapd_cli_action_process(char *msg, size_t len) static int hostapd_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) { char buf[64]; - if (argc != 1) { - printf("Invalid 'sta' command - exactly one argument, STA " + if (argc < 1) { + printf("Invalid 'sta' command - at least one argument, STA " "address, is required.\n"); return -1; } - snprintf(buf, sizeof(buf), "STA %s", argv[0]); + if (argc > 1) + snprintf(buf, sizeof(buf), "STA %s %s", argv[0], argv[1]); + else + snprintf(buf, sizeof(buf), "STA %s", argv[0]); return wpa_ctrl_command(ctrl, buf); } @@ -380,7 +393,7 @@ static int hostapd_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc, else res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { + if (os_snprintf_error(sizeof(cmd), res)) { printf("Too long WPS_CHECK_PIN command.\n"); return -1; } @@ -443,7 +456,7 @@ static int hostapd_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC_CONFIG_TOKEN %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { + if (os_snprintf_error(sizeof(cmd), res)) { printf("Too long WPS_NFC_CONFIG_TOKEN command.\n"); return -1; } @@ -464,12 +477,35 @@ static int hostapd_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, } res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC_TOKEN %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { + if (os_snprintf_error(sizeof(cmd), res)) { printf("Too long WPS_NFC_TOKEN command.\n"); return -1; } return wpa_ctrl_command(ctrl, cmd); } + + +static int hostapd_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, + int argc, char *argv[]) +{ + char cmd[64]; + int res; + + if (argc != 2) { + printf("Invalid 'nfc_get_handover_sel' command - two arguments " + "are required.\n"); + return -1; + } + + res = os_snprintf(cmd, sizeof(cmd), "NFC_GET_HANDOVER_SEL %s %s", + argv[0], argv[1]); + if (os_snprintf_error(sizeof(cmd), res)) { + printf("Too long NFC_GET_HANDOVER_SEL command.\n"); + return -1; + } + return wpa_ctrl_command(ctrl, cmd); +} + #endif /* CONFIG_WPS_NFC */ @@ -494,6 +530,13 @@ static int hostapd_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc, } +static int hostapd_cli_cmd_wps_get_status(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_ctrl_command(ctrl, "WPS_GET_STATUS"); +} + + static int hostapd_cli_cmd_wps_config(struct wpa_ctrl *ctrl, int argc, char *argv[]) { @@ -553,7 +596,7 @@ static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc, res = os_snprintf(buf, sizeof(buf), "DISASSOC_IMMINENT %s %s", argv[0], argv[1]); - if (res < 0 || res >= (int) sizeof(buf)) + if (os_snprintf_error(sizeof(buf), res)) return -1; return wpa_ctrl_command(ctrl, buf); } @@ -565,16 +608,43 @@ static int hostapd_cli_cmd_ess_disassoc(struct wpa_ctrl *ctrl, int argc, char buf[300]; int res; - if (argc < 2) { - printf("Invalid 'ess_disassoc' command - two arguments (STA " - "addr and URL) are needed\n"); + if (argc < 3) { + printf("Invalid 'ess_disassoc' command - three arguments (STA " + "addr, disassoc timer, and URL) are needed\n"); return -1; } - res = os_snprintf(buf, sizeof(buf), "ESS_DISASSOC %s %s", - argv[0], argv[1]); - if (res < 0 || res >= (int) sizeof(buf)) + res = os_snprintf(buf, sizeof(buf), "ESS_DISASSOC %s %s %s", + argv[0], argv[1], argv[2]); + if (os_snprintf_error(sizeof(buf), res)) + return -1; + return wpa_ctrl_command(ctrl, buf); +} + + +static int hostapd_cli_cmd_bss_tm_req(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + char buf[2000], *tmp; + int res, i, total; + + if (argc < 1) { + printf("Invalid 'bss_tm_req' command - at least one argument (STA addr) is needed\n"); + return -1; + } + + res = os_snprintf(buf, sizeof(buf), "BSS_TM_REQ %s", argv[0]); + if (os_snprintf_error(sizeof(buf), res)) return -1; + + total = res; + for (i = 1; i < argc; i++) { + tmp = &buf[total]; + res = os_snprintf(tmp, sizeof(buf) - total, " %s", argv[i]); + if (os_snprintf_error(sizeof(buf) - total, res)) + return -1; + total += res; + } return wpa_ctrl_command(ctrl, buf); } @@ -652,6 +722,90 @@ static int hostapd_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, } +static int hostapd_cli_cmd_set_qos_map_set(struct wpa_ctrl *ctrl, + int argc, char *argv[]) +{ + char buf[200]; + int res; + + if (argc != 1) { + printf("Invalid 'set_qos_map_set' command - " + "one argument (comma delimited QoS map set) " + "is needed\n"); + return -1; + } + + res = os_snprintf(buf, sizeof(buf), "SET_QOS_MAP_SET %s", argv[0]); + if (os_snprintf_error(sizeof(buf), res)) + return -1; + return wpa_ctrl_command(ctrl, buf); +} + + +static int hostapd_cli_cmd_send_qos_map_conf(struct wpa_ctrl *ctrl, + int argc, char *argv[]) +{ + char buf[50]; + int res; + + if (argc != 1) { + printf("Invalid 'send_qos_map_conf' command - " + "one argument (STA addr) is needed\n"); + return -1; + } + + res = os_snprintf(buf, sizeof(buf), "SEND_QOS_MAP_CONF %s", argv[0]); + if (os_snprintf_error(sizeof(buf), res)) + return -1; + return wpa_ctrl_command(ctrl, buf); +} + + +static int hostapd_cli_cmd_hs20_wnm_notif(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + char buf[300]; + int res; + + if (argc < 2) { + printf("Invalid 'hs20_wnm_notif' command - two arguments (STA " + "addr and URL) are needed\n"); + return -1; + } + + res = os_snprintf(buf, sizeof(buf), "HS20_WNM_NOTIF %s %s", + argv[0], argv[1]); + if (os_snprintf_error(sizeof(buf), res)) + return -1; + return wpa_ctrl_command(ctrl, buf); +} + + +static int hostapd_cli_cmd_hs20_deauth_req(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + char buf[300]; + int res; + + if (argc < 3) { + printf("Invalid 'hs20_deauth_req' command - at least three arguments (STA addr, Code, Re-auth Delay) are needed\n"); + return -1; + } + + if (argc > 3) + res = os_snprintf(buf, sizeof(buf), + "HS20_DEAUTH_REQ %s %s %s %s", + argv[0], argv[1], argv[2], argv[3]); + else + res = os_snprintf(buf, sizeof(buf), + "HS20_DEAUTH_REQ %s %s %s", + argv[0], argv[1], argv[2]); + if (os_snprintf_error(sizeof(buf), res)) + return -1; + return wpa_ctrl_command(ctrl, buf); +} + + static int hostapd_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[]) { hostapd_cli_quit = 1; @@ -706,8 +860,10 @@ static int hostapd_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, } hostapd_cli_close_connection(); - free(ctrl_ifname); - ctrl_ifname = strdup(argv[0]); + os_free(ctrl_ifname); + ctrl_ifname = os_strdup(argv[0]); + if (ctrl_ifname == NULL) + return -1; if (hostapd_cli_open_connection(ctrl_ifname)) { printf("Connected to interface '%s.\n", ctrl_ifname); @@ -737,7 +893,7 @@ static int hostapd_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) } res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { + if (os_snprintf_error(sizeof(cmd), res)) { printf("Too long SET command.\n"); return -1; } @@ -757,7 +913,7 @@ static int hostapd_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) } res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]); - if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { + if (os_snprintf_error(sizeof(cmd), res)) { printf("Too long GET command.\n"); return -1; } @@ -765,6 +921,94 @@ static int hostapd_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) } +static int hostapd_cli_cmd_chan_switch(struct wpa_ctrl *ctrl, + int argc, char *argv[]) +{ + char cmd[256]; + int res; + int i; + char *tmp; + int total; + + if (argc < 2) { + printf("Invalid chan_switch command: needs at least two " + "arguments (count and freq)\n" + "usage: <cs_count> <freq> [sec_channel_offset=] " + "[center_freq1=] [center_freq2=] [bandwidth=] " + "[blocktx] [ht|vht]\n"); + return -1; + } + + res = os_snprintf(cmd, sizeof(cmd), "CHAN_SWITCH %s %s", + argv[0], argv[1]); + if (os_snprintf_error(sizeof(cmd), res)) { + printf("Too long CHAN_SWITCH command.\n"); + return -1; + } + + total = res; + for (i = 2; i < argc; i++) { + tmp = cmd + total; + res = os_snprintf(tmp, sizeof(cmd) - total, " %s", argv[i]); + if (os_snprintf_error(sizeof(cmd) - total, res)) { + printf("Too long CHAN_SWITCH command.\n"); + return -1; + } + total += res; + } + return wpa_ctrl_command(ctrl, cmd); +} + + +static int hostapd_cli_cmd_enable(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_ctrl_command(ctrl, "ENABLE"); +} + + +static int hostapd_cli_cmd_reload(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_ctrl_command(ctrl, "RELOAD"); +} + + +static int hostapd_cli_cmd_disable(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_ctrl_command(ctrl, "DISABLE"); +} + + +static int hostapd_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + char cmd[256]; + int res; + + if (argc < 2 || argc > 3) { + printf("Invalid vendor command\n" + "usage: <vendor id> <command id> [<hex formatted command argument>]\n"); + return -1; + } + + res = os_snprintf(cmd, sizeof(cmd), "VENDOR %s %s %s", argv[0], argv[1], + argc == 3 ? argv[2] : ""); + if (os_snprintf_error(sizeof(cmd), res)) { + printf("Too long VENDOR command.\n"); + return -1; + } + return wpa_ctrl_command(ctrl, cmd); +} + + +static int hostapd_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_ctrl_command(ctrl, "ERP_FLUSH"); +} + + struct hostapd_cli_cmd { const char *cmd; int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]); @@ -774,6 +1018,7 @@ static struct hostapd_cli_cmd hostapd_cli_commands[] = { { "ping", hostapd_cli_cmd_ping }, { "mib", hostapd_cli_cmd_mib }, { "relog", hostapd_cli_cmd_relog }, + { "status", hostapd_cli_cmd_status }, { "sta", hostapd_cli_cmd_sta }, { "all_sta", hostapd_cli_cmd_all_sta }, { "new_sta", hostapd_cli_cmd_new_sta }, @@ -791,12 +1036,15 @@ static struct hostapd_cli_cmd hostapd_cli_commands[] = { { "wps_nfc_tag_read", hostapd_cli_cmd_wps_nfc_tag_read }, { "wps_nfc_config_token", hostapd_cli_cmd_wps_nfc_config_token }, { "wps_nfc_token", hostapd_cli_cmd_wps_nfc_token }, + { "nfc_get_handover_sel", hostapd_cli_cmd_nfc_get_handover_sel }, #endif /* CONFIG_WPS_NFC */ { "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin }, { "wps_config", hostapd_cli_cmd_wps_config }, + { "wps_get_status", hostapd_cli_cmd_wps_get_status }, #endif /* CONFIG_WPS */ { "disassoc_imminent", hostapd_cli_cmd_disassoc_imminent }, { "ess_disassoc", hostapd_cli_cmd_ess_disassoc }, + { "bss_tm_req", hostapd_cli_cmd_bss_tm_req }, { "get_config", hostapd_cli_cmd_get_config }, { "help", hostapd_cli_cmd_help }, { "interface", hostapd_cli_cmd_interface }, @@ -805,6 +1053,16 @@ static struct hostapd_cli_cmd hostapd_cli_commands[] = { { "quit", hostapd_cli_cmd_quit }, { "set", hostapd_cli_cmd_set }, { "get", hostapd_cli_cmd_get }, + { "set_qos_map_set", hostapd_cli_cmd_set_qos_map_set }, + { "send_qos_map_conf", hostapd_cli_cmd_send_qos_map_conf }, + { "chan_switch", hostapd_cli_cmd_chan_switch }, + { "hs20_wnm_notif", hostapd_cli_cmd_hs20_wnm_notif }, + { "hs20_deauth_req", hostapd_cli_cmd_hs20_deauth_req }, + { "vendor", hostapd_cli_cmd_vendor }, + { "enable", hostapd_cli_cmd_enable }, + { "reload", hostapd_cli_cmd_reload }, + { "disable", hostapd_cli_cmd_disable }, + { "erp_flush", hostapd_cli_cmd_erp_flush }, { NULL, NULL } }; |