diff options
Diffstat (limited to 'wpa_supplicant/wpa_cli.c')
-rw-r--r-- | wpa_supplicant/wpa_cli.c | 463 |
1 files changed, 414 insertions, 49 deletions
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index a848b7737db51..779355440a01d 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -1,6 +1,6 @@ /* * WPA Supplicant - command line interface for wpa_supplicant daemon - * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi> + * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi> * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -29,7 +29,7 @@ static const char *const wpa_cli_version = "wpa_cli v" VERSION_STR "\n" -"Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi> and contributors"; +"Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi> and contributors"; #define VENDOR_ELEM_FRAME_ID \ " 0: Probe Req (P2P), 1: Probe Resp (P2P) , 2: Probe Resp (GO), " \ @@ -60,6 +60,10 @@ static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */ static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */ static DEFINE_DL_LIST(ifnames); /* struct cli_txt_entry */ static DEFINE_DL_LIST(networks); /* struct cli_txt_entry */ +static DEFINE_DL_LIST(creds); /* struct cli_txt_entry */ +#ifdef CONFIG_AP +static DEFINE_DL_LIST(stations); /* struct cli_txt_entry */ +#endif /* CONFIG_AP */ static void print_help(const char *cmd); @@ -67,7 +71,9 @@ static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx); static void wpa_cli_close_connection(void); static char * wpa_cli_get_default_ifname(void); static char ** wpa_list_cmd_list(void); +static void update_creds(struct wpa_ctrl *ctrl); static void update_networks(struct wpa_ctrl *ctrl); +static void update_stations(struct wpa_ctrl *ctrl); static void usage(void) @@ -214,7 +220,7 @@ static void wpa_cli_msg_cb(char *msg, size_t len) } -static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print) +static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd, int print) { char buf[4096]; size_t len; @@ -250,7 +256,7 @@ static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print) } -static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd) +static int wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd) { return _wpa_ctrl_command(ctrl, cmd, 1); } @@ -331,6 +337,39 @@ static int wpa_cli_cmd_pmksa_flush(struct wpa_ctrl *ctrl, int argc, } +#ifdef CONFIG_PMKSA_CACHE_EXTERNAL + +static int wpa_cli_cmd_pmksa_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + return wpa_cli_cmd(ctrl, "PMKSA_GET", 1, argc, argv); +} + + +static int wpa_cli_cmd_pmksa_add(struct wpa_ctrl *ctrl, int argc, char *argv[]) +{ + return wpa_cli_cmd(ctrl, "PMKSA_ADD", 8, argc, argv); +} + + +#ifdef CONFIG_MESH + +static int wpa_cli_mesh_cmd_pmksa_get(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "MESH_PMKSA_GET", 1, argc, argv); +} + + +static int wpa_cli_mesh_cmd_pmksa_add(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "MESH_PMKSA_ADD", 4, argc, argv); +} + +#endif /* CONFIG_MESH */ +#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */ + + static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[]) { print_help(argc > 0 ? argv[0] : NULL); @@ -437,11 +476,13 @@ static char ** wpa_cli_complete_set(const char *str, int pos) #endif /* CONFIG_P2P */ "country", "bss_max_count", "bss_expiration_age", "bss_expiration_scan_count", "filter_ssids", "filter_rssi", - "max_num_sta", "disassoc_low_ack", + "max_num_sta", "disassoc_low_ack", "ap_isolate", #ifdef CONFIG_HS20 "hs20", #endif /* CONFIG_HS20 */ "interworking", "hessid", "access_network_type", "pbc_in_m1", + "go_interworking", "go_access_network_type", "go_internet", + "go_venue_group", "go_venue_type", "autoscan", "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey", "wps_nfc_dh_privkey", "wps_nfc_dev_pw", "ext_password_backend", "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf", @@ -455,6 +496,7 @@ static char ** wpa_cli_complete_set(const char *str, int pos) #ifdef CONFIG_TESTING_OPTIONS "ignore_auth_resp", #endif /* CONFIG_TESTING_OPTIONS */ + "relative_rssi", "relative_band_adjust", }; int i, num_fields = ARRAY_SIZE(fields); @@ -531,15 +573,18 @@ static char ** wpa_cli_complete_get(const char *str, int pos) #endif /* CONFIG_P2P */ "bss_max_count", "bss_expiration_age", "bss_expiration_scan_count", "filter_ssids", "filter_rssi", - "max_num_sta", "disassoc_low_ack", + "max_num_sta", "disassoc_low_ack", "ap_isolate", #ifdef CONFIG_HS20 "hs20", #endif /* CONFIG_HS20 */ "interworking", "access_network_type", "pbc_in_m1", "autoscan", + "go_interworking", "go_access_network_type", "go_internet", + "go_venue_group", "go_venue_type", "wps_nfc_dev_pw_id", "ext_password_backend", "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf", "dtim_period", "beacon_int", "ignore_old_scan_res", "scan_cur_freq", "sched_scan_interval", + "sched_scan_start_delay", "tdls_external_control", "osu_dir", "wowlan_triggers", "p2p_search_delay", "mac_addr", "rand_addr_lifetime", "preassoc_mac_addr", "key_mgmt_offload", "passive_scan", @@ -639,13 +684,6 @@ static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) } -static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc, - char *argv[]) -{ - return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv); -} - - static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[]) { return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv); @@ -1332,7 +1370,8 @@ static const char *network_fields[] = { "ssid", "scan_ssid", "bssid", "bssid_blacklist", "bssid_whitelist", "psk", "proto", "key_mgmt", "bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq", - "freq_list", "max_oper_chwidth", + "freq_list", "max_oper_chwidth", "ht40", "vht", "vht_center_freq1", + "vht_center_freq2", "ht", #ifdef IEEE8021X_EAPOL "eap", "identity", "anonymous_identity", "password", "ca_cert", "ca_path", "client_cert", "private_key", "private_key_passwd", @@ -1352,7 +1391,7 @@ static const char *network_fields[] = { "eap_workaround", "pac_file", "fragment_size", "ocsp", #endif /* IEEE8021X_EAPOL */ #ifdef CONFIG_MESH - "mode", "no_auto_peer", + "mode", "no_auto_peer", "mesh_rssi_threshold", #else /* CONFIG_MESH */ "mode", #endif /* CONFIG_MESH */ @@ -1360,7 +1399,7 @@ static const char *network_fields[] = { #ifdef CONFIG_IEEE80211W "ieee80211w", #endif /* CONFIG_IEEE80211W */ - "peerkey", "mixed_cell", "frequency", "fixed_freq", + "mixed_cell", "frequency", "fixed_freq", #ifdef CONFIG_MESH "mesh_basic_rates", "dot11MeshMaxRetries", "dot11MeshRetryTimeout", "dot11MeshConfirmTimeout", @@ -1386,6 +1425,9 @@ static const char *network_fields[] = { "ap_max_inactivity", "dtim_period", "beacon_int", #ifdef CONFIG_MACSEC "macsec_policy", + "macsec_integ_only", + "macsec_port", + "mka_priority", #endif /* CONFIG_MACSEC */ #ifdef CONFIG_HS20 "update_identifier", @@ -1479,14 +1521,56 @@ static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - return wpa_ctrl_command(ctrl, "ADD_CRED"); + int res = wpa_ctrl_command(ctrl, "ADD_CRED"); + if (interactive) + update_creds(ctrl); + return res; } static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) { - return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv); + int res = wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv); + if (interactive) + update_creds(ctrl); + return res; +} + + +static const char * const cred_fields[] = { + "temporary", "priority", "sp_priority", "pcsc", "eap", + "update_identifier", "min_dl_bandwidth_home", "min_ul_bandwidth_home", + "min_dl_bandwidth_roaming", "min_ul_bandwidth_roaming", "max_bss_load", + "req_conn_capab", "ocsp", "sim_num", "realm", "username", "password", + "ca_cert", "client_cert", "private_key", "private_key_passwd", "imsi", + "milenage", "domain_suffix_match", "domain", "phase1", "phase2", + "roaming_consortium", "required_roaming_consortium", "excluded_ssid", + "roaming_partner", "provisioning_sp" +}; + + +static char ** wpa_cli_complete_cred(const char *str, int pos) +{ + int arg = get_cmd_arg_num(str, pos); + int i, num_fields = ARRAY_SIZE(cred_fields); + char **res = NULL; + + switch (arg) { + case 1: + res = cli_txt_list_array(&creds); + break; + case 2: + res = os_calloc(num_fields + 1, sizeof(char *)); + if (res == NULL) + return NULL; + for (i = 0; i < num_fields; i++) { + res[i] = os_strdup(cred_fields[i]); + if (res[i] == NULL) + break; + } + } + return res; } @@ -1736,8 +1820,23 @@ static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) } -static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd, - char *addr, size_t addr_len) +static char ** wpa_cli_complete_sta(const char *str, int pos) +{ + int arg = get_cmd_arg_num(str, pos); + char **res = NULL; + + switch (arg) { + case 1: + res = cli_txt_list_array(&stations); + break; + } + + return res; +} + + +static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, const char *cmd, + char *addr, size_t addr_len, int print) { char buf[4096], *pos; size_t len; @@ -1765,9 +1864,11 @@ static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd, } buf[len] = '\0'; - if (os_memcmp(buf, "FAIL", 4) == 0) + if (os_memcmp(buf, "FAIL", 4) == 0 || + os_memcmp(buf, "UNKNOWN COMMAND", 15) == 0) return -1; - printf("%s", buf); + if (print) + printf("%s", buf); pos = buf; while (*pos != '\0' && *pos != '\n') @@ -1782,16 +1883,33 @@ static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) { char addr[32], cmd[64]; - if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr))) + if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 1)) return 0; do { os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); - } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0); + } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 1) == 0); return -1; } +static int wpa_cli_cmd_list_sta(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + char addr[32], cmd[64]; + + if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 0)) + return 0; + do { + if (os_strcmp(addr, "") != 0) + printf("%s\n", addr); + os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); + } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 0) == 0); + + return 0; +} + + static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc, char *argv[]) { @@ -1799,12 +1917,43 @@ static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc, } +static char ** wpa_cli_complete_deauthenticate(const char *str, int pos) +{ + int arg = get_cmd_arg_num(str, pos); + char **res = NULL; + + switch (arg) { + case 1: + res = cli_txt_list_array(&stations); + break; + } + + return res; +} + + static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc, char *argv[]) { return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv); } + +static char ** wpa_cli_complete_disassociate(const char *str, int pos) +{ + int arg = get_cmd_arg_num(str, pos); + char **res = NULL; + + switch (arg) { + case 1: + res = cli_txt_list_array(&stations); + break; + } + + return res; +} + + static int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc, char *argv[]) { @@ -2176,7 +2325,7 @@ static char ** wpa_cli_complete_p2p_peer(const char *str, int pos) } -static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd, +static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, const char *cmd, char *addr, size_t addr_len, int discovered) { @@ -2338,6 +2487,8 @@ static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc, return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv); } +#endif /* CONFIG_P2P */ + static int wpa_cli_cmd_vendor_elem_add(struct wpa_ctrl *ctrl, int argc, char *argv[]) @@ -2359,7 +2510,6 @@ static int wpa_cli_cmd_vendor_elem_remove(struct wpa_ctrl *ctrl, int argc, return wpa_cli_cmd(ctrl, "VENDOR_ELEM_REMOVE", 2, argc, argv); } -#endif /* CONFIG_P2P */ #ifdef CONFIG_WIFI_DISPLAY @@ -2726,6 +2876,101 @@ static int wpa_cli_cmd_p2p_lo_stop(struct wpa_ctrl *ctrl, int argc, } +#ifdef CONFIG_DPP + +static int wpa_cli_cmd_dpp_qr_code(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "DPP_QR_CODE", 1, argc, argv); +} + + +static int wpa_cli_cmd_dpp_bootstrap_gen(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_GEN", 1, argc, argv); +} + + +static int wpa_cli_cmd_dpp_bootstrap_remove(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_REMOVE", 1, argc, argv); +} + + +static int wpa_cli_cmd_dpp_bootstrap_get_uri(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_GET_URI", 1, argc, argv); +} + + +static int wpa_cli_cmd_dpp_bootstrap_info(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_INFO", 1, argc, argv); +} + + +static int wpa_cli_cmd_dpp_auth_init(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "DPP_AUTH_INIT", 1, argc, argv); +} + + +static int wpa_cli_cmd_dpp_listen(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "DPP_LISTEN", 1, argc, argv); +} + + +static int wpa_cli_cmd_dpp_stop_listen(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_ctrl_command(ctrl, "DPP_STOP_LISTEN"); +} + + +static int wpa_cli_cmd_dpp_configurator_add(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_ADD", 0, argc, argv); +} + + +static int wpa_cli_cmd_dpp_configurator_remove(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_REMOVE", 1, argc, argv); +} + + +static int wpa_cli_cmd_dpp_configurator_get_key(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_GET_KEY", 1, argc, argv); +} + + +static int wpa_cli_cmd_dpp_pkex_add(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "DPP_PKEX_ADD", 1, argc, argv); +} + + +static int wpa_cli_cmd_dpp_pkex_remove(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "DPP_PKEX_REMOVE", 1, argc, argv); +} + +#endif /* CONFIG_DPP */ + + enum wpa_cli_cmd_flags { cli_cmd_flag_none = 0x00, cli_cmd_flag_sensitive = 0x01 @@ -2798,6 +3043,22 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = { { "pmksa_flush", wpa_cli_cmd_pmksa_flush, NULL, cli_cmd_flag_none, "= flush PMKSA cache entries" }, +#ifdef CONFIG_PMKSA_CACHE_EXTERNAL + { "pmksa_get", wpa_cli_cmd_pmksa_get, NULL, + cli_cmd_flag_none, + "<network_id> = fetch all stored PMKSA cache entries" }, + { "pmksa_add", wpa_cli_cmd_pmksa_add, NULL, + cli_cmd_flag_sensitive, + "<network_id> <BSSID> <PMKID> <PMK> <reauth_time in seconds> <expiration in seconds> <akmp> <opportunistic> = store PMKSA cache entry from external storage" }, +#ifdef CONFIG_MESH + { "mesh_pmksa_get", wpa_cli_mesh_cmd_pmksa_get, NULL, + cli_cmd_flag_none, + "<peer MAC address | any> = fetch all stored mesh PMKSA cache entries" }, + { "mesh_pmksa_add", wpa_cli_mesh_cmd_pmksa_add, NULL, + cli_cmd_flag_sensitive, + "<BSSID> <PMKID> <PMK> <expiration in seconds> = store mesh PMKSA cache entry from external storage" }, +#endif /* CONFIG_MESH */ +#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */ { "reassociate", wpa_cli_cmd_reassociate, NULL, cli_cmd_flag_none, "= force reassociation" }, @@ -2807,30 +3068,30 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = { { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss, cli_cmd_flag_none, "<BSSID> = force preauthentication" }, - { "identity", wpa_cli_cmd_identity, NULL, + { "identity", wpa_cli_cmd_identity, wpa_cli_complete_network_id, cli_cmd_flag_none, "<network id> <identity> = configure identity for an SSID" }, - { "password", wpa_cli_cmd_password, NULL, + { "password", wpa_cli_cmd_password, wpa_cli_complete_network_id, cli_cmd_flag_sensitive, "<network id> <password> = configure password for an SSID" }, - { "new_password", wpa_cli_cmd_new_password, NULL, - cli_cmd_flag_sensitive, + { "new_password", wpa_cli_cmd_new_password, + wpa_cli_complete_network_id, cli_cmd_flag_sensitive, "<network id> <password> = change password for an SSID" }, - { "pin", wpa_cli_cmd_pin, NULL, + { "pin", wpa_cli_cmd_pin, wpa_cli_complete_network_id, cli_cmd_flag_sensitive, "<network id> <pin> = configure pin for an SSID" }, - { "otp", wpa_cli_cmd_otp, NULL, + { "otp", wpa_cli_cmd_otp, wpa_cli_complete_network_id, cli_cmd_flag_sensitive, "<network id> <password> = configure one-time-password for an SSID" }, - { "passphrase", wpa_cli_cmd_passphrase, NULL, + { "passphrase", wpa_cli_cmd_passphrase, wpa_cli_complete_network_id, cli_cmd_flag_sensitive, "<network id> <passphrase> = configure private key passphrase\n" " for an SSID" }, - { "sim", wpa_cli_cmd_sim, NULL, + { "sim", wpa_cli_cmd_sim, wpa_cli_complete_network_id, cli_cmd_flag_sensitive, "<network id> <pin> = report SIM operation result" }, - { "bssid", wpa_cli_cmd_bssid, NULL, + { "bssid", wpa_cli_cmd_bssid, wpa_cli_complete_network_id, cli_cmd_flag_none, "<network id> <BSSID> = set preferred BSSID for an SSID" }, { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss, @@ -2884,10 +3145,10 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = { { "remove_cred", wpa_cli_cmd_remove_cred, NULL, cli_cmd_flag_none, "<cred id> = remove a credential" }, - { "set_cred", wpa_cli_cmd_set_cred, NULL, + { "set_cred", wpa_cli_cmd_set_cred, wpa_cli_complete_cred, cli_cmd_flag_sensitive, "<cred id> <variable> <value> = set credential variables" }, - { "get_cred", wpa_cli_cmd_get_cred, NULL, + { "get_cred", wpa_cli_cmd_get_cred, wpa_cli_complete_cred, cli_cmd_flag_none, "<cred id> <variable> = get credential variables" }, { "save_config", wpa_cli_cmd_save_config, NULL, @@ -2951,9 +3212,6 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = { { "bss_flush", wpa_cli_cmd_bss_flush, NULL, cli_cmd_flag_none, "<value> = set BSS flush age (0 by default)" }, - { "stkstart", wpa_cli_cmd_stkstart, NULL, - cli_cmd_flag_none, - "<addr> = request STK negotiation with <addr>" }, { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss, cli_cmd_flag_none, "<addr> = request over-the-DS FT with <addr>" }, @@ -3029,17 +3287,20 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = { cli_cmd_flag_none, "<addr> = request RSN authentication with <addr> in IBSS" }, #ifdef CONFIG_AP - { "sta", wpa_cli_cmd_sta, NULL, + { "sta", wpa_cli_cmd_sta, wpa_cli_complete_sta, cli_cmd_flag_none, "<addr> = get information about an associated station (AP)" }, { "all_sta", wpa_cli_cmd_all_sta, NULL, cli_cmd_flag_none, "= get information about all associated stations (AP)" }, - { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL, + { "list_sta", wpa_cli_cmd_list_sta, NULL, cli_cmd_flag_none, + "= list all stations (AP)" }, + { "deauthenticate", wpa_cli_cmd_deauthenticate, + wpa_cli_complete_deauthenticate, cli_cmd_flag_none, "<addr> = deauthenticate a station" }, - { "disassociate", wpa_cli_cmd_disassociate, NULL, - cli_cmd_flag_none, + { "disassociate", wpa_cli_cmd_disassociate, + wpa_cli_complete_disassociate, cli_cmd_flag_none, "<addr> = disassociate a station" }, { "chan_switch", wpa_cli_cmd_chanswitch, NULL, cli_cmd_flag_none, @@ -3168,6 +3429,7 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = { { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client, wpa_cli_complete_p2p_peer, cli_cmd_flag_none, "<address|iface=address> = remove a peer from all groups" }, +#endif /* CONFIG_P2P */ { "vendor_elem_add", wpa_cli_cmd_vendor_elem_add, NULL, cli_cmd_flag_none, "<frame id> <hexdump of elem(s)> = add vendor specific IEs to frame(s)\n" @@ -3180,7 +3442,6 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = { cli_cmd_flag_none, "<frame id> <hexdump of elem(s)> = remove vendor specific IE(s) in frame(s)\n" VENDOR_ELEM_FRAME_ID }, -#endif /* CONFIG_P2P */ #ifdef CONFIG_WIFI_DISPLAY { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL, cli_cmd_flag_none, @@ -3285,7 +3546,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = { { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none, "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" }, { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none, - "<query reason> [list] = Send BSS Transition Management Query" }, + "<query reason> [list]" + " [neighbor=<BSSID>,<BSSID information>,<operating class>,<channel number>,<PHY type>[,<hexdump of optional subelements>]" + " = Send BSS Transition Management Query" }, #endif /* CONFIG_WNM */ { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive, "<params..> = Sent unprocessed command" }, @@ -3320,6 +3583,44 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = { { "p2p_lo_stop", wpa_cli_cmd_p2p_lo_stop, NULL, cli_cmd_flag_none, "= stop P2P listen offload" }, +#ifdef CONFIG_DPP + { "dpp_qr_code", wpa_cli_cmd_dpp_qr_code, NULL, cli_cmd_flag_none, + "report a scanned DPP URI from a QR Code" }, + { "dpp_bootstrap_gen", wpa_cli_cmd_dpp_bootstrap_gen, NULL, + cli_cmd_flag_sensitive, + "type=<qrcode> [chan=..] [mac=..] [info=..] [curve=..] [key=..] = generate DPP bootstrap information" }, + { "dpp_bootstrap_remove", wpa_cli_cmd_dpp_bootstrap_remove, NULL, + cli_cmd_flag_none, + "*|<id> = remove DPP bootstrap information" }, + { "dpp_bootstrap_get_uri", wpa_cli_cmd_dpp_bootstrap_get_uri, NULL, + cli_cmd_flag_none, + "<id> = get DPP bootstrap URI" }, + { "dpp_bootstrap_info", wpa_cli_cmd_dpp_bootstrap_info, NULL, + cli_cmd_flag_none, + "<id> = show DPP bootstrap information" }, + { "dpp_auth_init", wpa_cli_cmd_dpp_auth_init, NULL, cli_cmd_flag_none, + "peer=<id> [own=<id>] = initiate DPP bootstrapping" }, + { "dpp_listen", wpa_cli_cmd_dpp_listen, NULL, cli_cmd_flag_none, + "<freq in MHz> = start DPP listen" }, + { "dpp_stop_listen", wpa_cli_cmd_dpp_stop_listen, NULL, + cli_cmd_flag_none, + "= stop DPP listen" }, + { "dpp_configurator_add", wpa_cli_cmd_dpp_configurator_add, NULL, + cli_cmd_flag_sensitive, + "[curve=..] [key=..] = add DPP configurator" }, + { "dpp_configurator_remove", wpa_cli_cmd_dpp_configurator_remove, NULL, + cli_cmd_flag_none, + "*|<id> = remove DPP configurator" }, + { "dpp_configurator_get_key", wpa_cli_cmd_dpp_configurator_get_key, + NULL, cli_cmd_flag_none, + "<id> = Get DPP configurator's private key" }, + { "dpp_pkex_add", wpa_cli_cmd_dpp_pkex_add, NULL, + cli_cmd_flag_sensitive, + "add PKEX code" }, + { "dpp_pkex_remove", wpa_cli_cmd_dpp_pkex_remove, NULL, + cli_cmd_flag_none, + "*|<id> = remove DPP pkex information" }, +#endif /* CONFIG_DPP */ { NULL, NULL, NULL, cli_cmd_flag_none, NULL } }; @@ -3638,6 +3939,10 @@ static void wpa_cli_action_process(const char *msg) wpa_cli_exec(action_file, ifname, pos); } else if (str_starts(pos, WPS_EVENT_SUCCESS)) { wpa_cli_exec(action_file, ifname, pos); + } else if (str_starts(pos, WPS_EVENT_ACTIVE)) { + wpa_cli_exec(action_file, ifname, pos); + } else if (str_starts(pos, WPS_EVENT_TIMEOUT)) { + wpa_cli_exec(action_file, ifname, pos); } else if (str_starts(pos, WPS_EVENT_FAIL)) { wpa_cli_exec(action_file, ifname, pos); } else if (str_starts(pos, AP_STA_CONNECTED)) { @@ -3650,6 +3955,8 @@ static void wpa_cli_action_process(const char *msg) wpa_cli_exec(action_file, ifname, pos); } else if (str_starts(pos, HS20_DEAUTH_IMMINENT_NOTICE)) { wpa_cli_exec(action_file, ifname, pos); + } else if (str_starts(pos, HS20_T_C_ACCEPTANCE)) { + wpa_cli_exec(action_file, ifname, pos); } else if (str_starts(pos, WPA_EVENT_TERMINATING)) { printf("wpa_supplicant is terminating - stop monitoring\n"); wpa_cli_quit = 1; @@ -3675,6 +3982,7 @@ static void wpa_cli_reconnect(void) edit_clear_line(); printf("\rConnection to wpa_supplicant re-established\n"); edit_redraw(); + update_stations(ctrl_conn); } } @@ -3897,7 +4205,7 @@ static void update_bssid_list(struct wpa_ctrl *ctrl) char buf[4096]; size_t len = sizeof(buf); int ret; - char *cmd = "BSS RANGE=ALL MASK=0x2"; + const char *cmd = "BSS RANGE=ALL MASK=0x2"; char *pos, *end; if (ctrl == NULL) @@ -3928,7 +4236,7 @@ static void update_ifnames(struct wpa_ctrl *ctrl) char buf[4096]; size_t len = sizeof(buf); int ret; - char *cmd = "INTERFACES"; + const char *cmd = "INTERFACES"; char *pos, *end; char txt[200]; @@ -3955,12 +4263,44 @@ static void update_ifnames(struct wpa_ctrl *ctrl) } +static void update_creds(struct wpa_ctrl *ctrl) +{ + char buf[4096]; + size_t len = sizeof(buf); + int ret; + const char *cmd = "LIST_CREDS"; + char *pos, *end; + int header = 1; + + cli_txt_list_flush(&creds); + + if (ctrl == NULL) + return; + ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); + if (ret < 0) + return; + buf[len] = '\0'; + + pos = buf; + while (pos) { + end = os_strchr(pos, '\n'); + if (end == NULL) + break; + *end = '\0'; + if (!header) + cli_txt_list_add_word(&creds, pos, '\t'); + header = 0; + pos = end + 1; + } +} + + static void update_networks(struct wpa_ctrl *ctrl) { char buf[4096]; size_t len = sizeof(buf); int ret; - char *cmd = "LIST_NETWORKS"; + const char *cmd = "LIST_NETWORKS"; char *pos, *end; int header = 1; @@ -3987,6 +4327,27 @@ static void update_networks(struct wpa_ctrl *ctrl) } +static void update_stations(struct wpa_ctrl *ctrl) +{ +#ifdef CONFIG_AP + char addr[32], cmd[64]; + + if (!ctrl || !interactive) + return; + + cli_txt_list_flush(&stations); + + if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 0)) + return; + do { + if (os_strcmp(addr, "") != 0) + cli_txt_list_add(&stations, addr); + os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); + } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 0) == 0); +#endif /* CONFIG_AP */ +} + + static void try_connection(void *eloop_ctx, void *timeout_ctx) { if (ctrl_conn) @@ -4007,7 +4368,9 @@ static void try_connection(void *eloop_ctx, void *timeout_ctx) } update_bssid_list(ctrl_conn); + update_creds(ctrl_conn); update_networks(ctrl_conn); + update_stations(ctrl_conn); if (warning_displayed) printf("Connection established.\n"); @@ -4029,6 +4392,7 @@ static void wpa_cli_interactive(void) cli_txt_list_flush(&p2p_groups); cli_txt_list_flush(&bsses); cli_txt_list_flush(&ifnames); + cli_txt_list_flush(&creds); cli_txt_list_flush(&networks); if (edit_started) edit_deinit(hfile, wpa_cli_edit_filter_history_cb); @@ -4254,6 +4618,7 @@ int main(int argc, char *argv[]) "control interface\n"); } } + update_stations(ctrl_conn); } } |