wpa_cli.c revision 337817
1189251Ssam/* 2189251Ssam * WPA Supplicant - command line interface for wpa_supplicant daemon 3337817Scy * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi> 4189251Ssam * 5252726Srpaulo * This software may be distributed under the terms of the BSD license. 6252726Srpaulo * See README for more details. 7189251Ssam */ 8189251Ssam 9189251Ssam#include "includes.h" 10189251Ssam 11189251Ssam#ifdef CONFIG_CTRL_IFACE 12189251Ssam 13189251Ssam#ifdef CONFIG_CTRL_IFACE_UNIX 14189251Ssam#include <dirent.h> 15189251Ssam#endif /* CONFIG_CTRL_IFACE_UNIX */ 16189251Ssam 17337817Scy#include "common/cli.h" 18214734Srpaulo#include "common/wpa_ctrl.h" 19252726Srpaulo#include "utils/common.h" 20252726Srpaulo#include "utils/eloop.h" 21252726Srpaulo#include "utils/edit.h" 22252726Srpaulo#include "utils/list.h" 23214734Srpaulo#include "common/version.h" 24252726Srpaulo#include "common/ieee802_11_defs.h" 25252726Srpaulo#ifdef ANDROID 26252726Srpaulo#include <cutils/properties.h> 27252726Srpaulo#endif /* ANDROID */ 28189251Ssam 29189251Ssam 30289549Srpaulostatic const char *const wpa_cli_version = 31189251Ssam"wpa_cli v" VERSION_STR "\n" 32337817Scy"Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi> and contributors"; 33189251Ssam 34337817Scy#define VENDOR_ELEM_FRAME_ID \ 35337817Scy " 0: Probe Req (P2P), 1: Probe Resp (P2P) , 2: Probe Resp (GO), " \ 36337817Scy "3: Beacon (GO), 4: PD Req, 5: PD Resp, 6: GO Neg Req, " \ 37337817Scy "7: GO Neg Resp, 8: GO Neg Conf, 9: Inv Req, 10: Inv Resp, " \ 38337817Scy "11: Assoc Req (P2P), 12: Assoc Resp (P2P)" 39189251Ssam 40189251Ssamstatic struct wpa_ctrl *ctrl_conn; 41214734Srpaulostatic struct wpa_ctrl *mon_conn; 42189251Ssamstatic int wpa_cli_quit = 0; 43189251Ssamstatic int wpa_cli_attached = 0; 44281806Srpaulostatic int wpa_cli_connected = -1; 45189251Ssamstatic int wpa_cli_last_id = 0; 46252726Srpaulo#ifndef CONFIG_CTRL_IFACE_DIR 47252726Srpaulo#define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant" 48252726Srpaulo#endif /* CONFIG_CTRL_IFACE_DIR */ 49252726Srpaulostatic const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR; 50289549Srpaulostatic const char *client_socket_dir = NULL; 51189251Ssamstatic char *ctrl_ifname = NULL; 52189251Ssamstatic const char *pid_file = NULL; 53189251Ssamstatic const char *action_file = NULL; 54189251Ssamstatic int ping_interval = 5; 55214734Srpaulostatic int interactive = 0; 56281806Srpaulostatic char *ifname_prefix = NULL; 57189251Ssam 58252726Srpaulostatic DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */ 59252726Srpaulostatic DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */ 60252726Srpaulostatic DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */ 61281806Srpaulostatic DEFINE_DL_LIST(ifnames); /* struct cli_txt_entry */ 62289549Srpaulostatic DEFINE_DL_LIST(networks); /* struct cli_txt_entry */ 63189251Ssam 64189251Ssam 65252726Srpaulostatic void print_help(const char *cmd); 66252726Srpaulostatic void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx); 67252726Srpaulostatic void wpa_cli_close_connection(void); 68252726Srpaulostatic char * wpa_cli_get_default_ifname(void); 69252726Srpaulostatic char ** wpa_list_cmd_list(void); 70289549Srpaulostatic void update_networks(struct wpa_ctrl *ctrl); 71252726Srpaulo 72252726Srpaulo 73189251Ssamstatic void usage(void) 74189251Ssam{ 75189251Ssam printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] " 76189251Ssam "[-a<action file>] \\\n" 77289549Srpaulo " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] " 78289549Srpaulo "\\\n" 79289549Srpaulo " [-s<wpa_client_socket_file_path>] " 80189251Ssam "[command..]\n" 81189251Ssam " -h = help (show this usage text)\n" 82189251Ssam " -v = shown version information\n" 83189251Ssam " -a = run in daemon mode executing the action file based on " 84189251Ssam "events from\n" 85189251Ssam " wpa_supplicant\n" 86189251Ssam " -B = run a daemon in the background\n" 87252726Srpaulo " default path: " CONFIG_CTRL_IFACE_DIR "\n" 88189251Ssam " default interface: first interface found in socket path\n"); 89252726Srpaulo print_help(NULL); 90189251Ssam} 91189251Ssam 92189251Ssam 93252726Srpaulostatic int wpa_cli_show_event(const char *event) 94252726Srpaulo{ 95252726Srpaulo const char *start; 96252726Srpaulo 97252726Srpaulo start = os_strchr(event, '>'); 98252726Srpaulo if (start == NULL) 99252726Srpaulo return 1; 100252726Srpaulo 101252726Srpaulo start++; 102252726Srpaulo /* 103252726Srpaulo * Skip BSS added/removed events since they can be relatively frequent 104252726Srpaulo * and are likely of not much use for an interactive user. 105252726Srpaulo */ 106252726Srpaulo if (str_starts(start, WPA_EVENT_BSS_ADDED) || 107252726Srpaulo str_starts(start, WPA_EVENT_BSS_REMOVED)) 108252726Srpaulo return 0; 109252726Srpaulo 110252726Srpaulo return 1; 111252726Srpaulo} 112252726Srpaulo 113252726Srpaulo 114214734Srpaulostatic int wpa_cli_open_connection(const char *ifname, int attach) 115214734Srpaulo{ 116189251Ssam#if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE) 117189251Ssam ctrl_conn = wpa_ctrl_open(ifname); 118214734Srpaulo if (ctrl_conn == NULL) 119214734Srpaulo return -1; 120214734Srpaulo 121214734Srpaulo if (attach && interactive) 122214734Srpaulo mon_conn = wpa_ctrl_open(ifname); 123214734Srpaulo else 124214734Srpaulo mon_conn = NULL; 125189251Ssam#else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ 126252726Srpaulo char *cfile = NULL; 127189251Ssam int flen, res; 128189251Ssam 129189251Ssam if (ifname == NULL) 130214734Srpaulo return -1; 131189251Ssam 132252726Srpaulo#ifdef ANDROID 133252726Srpaulo if (access(ctrl_iface_dir, F_OK) < 0) { 134252726Srpaulo cfile = os_strdup(ifname); 135252726Srpaulo if (cfile == NULL) 136252726Srpaulo return -1; 137189251Ssam } 138252726Srpaulo#endif /* ANDROID */ 139189251Ssam 140289549Srpaulo if (client_socket_dir && client_socket_dir[0] && 141289549Srpaulo access(client_socket_dir, F_OK) < 0) { 142289549Srpaulo perror(client_socket_dir); 143289549Srpaulo os_free(cfile); 144289549Srpaulo return -1; 145289549Srpaulo } 146289549Srpaulo 147252726Srpaulo if (cfile == NULL) { 148252726Srpaulo flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2; 149252726Srpaulo cfile = os_malloc(flen); 150252726Srpaulo if (cfile == NULL) 151252726Srpaulo return -1; 152252726Srpaulo res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, 153252726Srpaulo ifname); 154281806Srpaulo if (os_snprintf_error(flen, res)) { 155252726Srpaulo os_free(cfile); 156252726Srpaulo return -1; 157252726Srpaulo } 158252726Srpaulo } 159252726Srpaulo 160289549Srpaulo ctrl_conn = wpa_ctrl_open2(cfile, client_socket_dir); 161214734Srpaulo if (ctrl_conn == NULL) { 162214734Srpaulo os_free(cfile); 163214734Srpaulo return -1; 164214734Srpaulo } 165214734Srpaulo 166214734Srpaulo if (attach && interactive) 167289549Srpaulo mon_conn = wpa_ctrl_open2(cfile, client_socket_dir); 168214734Srpaulo else 169214734Srpaulo mon_conn = NULL; 170189251Ssam os_free(cfile); 171189251Ssam#endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ 172214734Srpaulo 173214734Srpaulo if (mon_conn) { 174214734Srpaulo if (wpa_ctrl_attach(mon_conn) == 0) { 175214734Srpaulo wpa_cli_attached = 1; 176252726Srpaulo if (interactive) 177252726Srpaulo eloop_register_read_sock( 178252726Srpaulo wpa_ctrl_get_fd(mon_conn), 179252726Srpaulo wpa_cli_mon_receive, NULL, NULL); 180214734Srpaulo } else { 181214734Srpaulo printf("Warning: Failed to attach to " 182214734Srpaulo "wpa_supplicant.\n"); 183252726Srpaulo wpa_cli_close_connection(); 184214734Srpaulo return -1; 185214734Srpaulo } 186214734Srpaulo } 187214734Srpaulo 188214734Srpaulo return 0; 189189251Ssam} 190189251Ssam 191189251Ssam 192189251Ssamstatic void wpa_cli_close_connection(void) 193189251Ssam{ 194189251Ssam if (ctrl_conn == NULL) 195189251Ssam return; 196189251Ssam 197189251Ssam if (wpa_cli_attached) { 198214734Srpaulo wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn); 199189251Ssam wpa_cli_attached = 0; 200189251Ssam } 201189251Ssam wpa_ctrl_close(ctrl_conn); 202189251Ssam ctrl_conn = NULL; 203214734Srpaulo if (mon_conn) { 204252726Srpaulo eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn)); 205214734Srpaulo wpa_ctrl_close(mon_conn); 206214734Srpaulo mon_conn = NULL; 207214734Srpaulo } 208189251Ssam} 209189251Ssam 210189251Ssam 211189251Ssamstatic void wpa_cli_msg_cb(char *msg, size_t len) 212189251Ssam{ 213189251Ssam printf("%s\n", msg); 214189251Ssam} 215189251Ssam 216189251Ssam 217189251Ssamstatic int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print) 218189251Ssam{ 219281806Srpaulo char buf[4096]; 220189251Ssam size_t len; 221189251Ssam int ret; 222189251Ssam 223189251Ssam if (ctrl_conn == NULL) { 224189251Ssam printf("Not connected to wpa_supplicant - command dropped.\n"); 225189251Ssam return -1; 226189251Ssam } 227281806Srpaulo if (ifname_prefix) { 228281806Srpaulo os_snprintf(buf, sizeof(buf), "IFNAME=%s %s", 229281806Srpaulo ifname_prefix, cmd); 230281806Srpaulo buf[sizeof(buf) - 1] = '\0'; 231281806Srpaulo cmd = buf; 232281806Srpaulo } 233189251Ssam len = sizeof(buf) - 1; 234189251Ssam ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 235189251Ssam wpa_cli_msg_cb); 236189251Ssam if (ret == -2) { 237189251Ssam printf("'%s' command timed out.\n", cmd); 238189251Ssam return -2; 239189251Ssam } else if (ret < 0) { 240189251Ssam printf("'%s' command failed.\n", cmd); 241189251Ssam return -1; 242189251Ssam } 243189251Ssam if (print) { 244189251Ssam buf[len] = '\0'; 245189251Ssam printf("%s", buf); 246252726Srpaulo if (interactive && len > 0 && buf[len - 1] != '\n') 247252726Srpaulo printf("\n"); 248189251Ssam } 249189251Ssam return 0; 250189251Ssam} 251189251Ssam 252189251Ssam 253189251Ssamstatic int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd) 254189251Ssam{ 255189251Ssam return _wpa_ctrl_command(ctrl, cmd, 1); 256189251Ssam} 257189251Ssam 258189251Ssam 259252726Srpaulostatic int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args, 260252726Srpaulo int argc, char *argv[]) 261252726Srpaulo{ 262281806Srpaulo char buf[4096]; 263252726Srpaulo if (argc < min_args) { 264252726Srpaulo printf("Invalid %s command - at least %d argument%s " 265252726Srpaulo "required.\n", cmd, min_args, 266252726Srpaulo min_args > 1 ? "s are" : " is"); 267252726Srpaulo return -1; 268252726Srpaulo } 269252726Srpaulo if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0) 270252726Srpaulo return -1; 271252726Srpaulo return wpa_ctrl_command(ctrl, buf); 272252726Srpaulo} 273252726Srpaulo 274252726Srpaulo 275252726Srpaulostatic int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[]) 276252726Srpaulo{ 277252726Srpaulo return wpa_ctrl_command(ctrl, "IFNAME"); 278252726Srpaulo} 279252726Srpaulo 280252726Srpaulo 281189251Ssamstatic int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[]) 282189251Ssam{ 283252726Srpaulo if (argc > 0 && os_strcmp(argv[0], "verbose") == 0) 284252726Srpaulo return wpa_ctrl_command(ctrl, "STATUS-VERBOSE"); 285252726Srpaulo if (argc > 0 && os_strcmp(argv[0], "wps") == 0) 286252726Srpaulo return wpa_ctrl_command(ctrl, "STATUS-WPS"); 287281806Srpaulo if (argc > 0 && os_strcmp(argv[0], "driver") == 0) 288281806Srpaulo return wpa_ctrl_command(ctrl, "STATUS-DRIVER"); 289289549Srpaulo#ifdef ANDROID 290289549Srpaulo if (argc > 0 && os_strcmp(argv[0], "no_events") == 0) 291289549Srpaulo return wpa_ctrl_command(ctrl, "STATUS-NO_EVENTS"); 292289549Srpaulo#endif /* ANDROID */ 293252726Srpaulo return wpa_ctrl_command(ctrl, "STATUS"); 294189251Ssam} 295189251Ssam 296189251Ssam 297189251Ssamstatic int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[]) 298189251Ssam{ 299189251Ssam return wpa_ctrl_command(ctrl, "PING"); 300189251Ssam} 301189251Ssam 302189251Ssam 303252726Srpaulostatic int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[]) 304252726Srpaulo{ 305252726Srpaulo return wpa_ctrl_command(ctrl, "RELOG"); 306252726Srpaulo} 307252726Srpaulo 308252726Srpaulo 309252726Srpaulostatic int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[]) 310252726Srpaulo{ 311252726Srpaulo return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv); 312252726Srpaulo} 313252726Srpaulo 314252726Srpaulo 315189251Ssamstatic int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[]) 316189251Ssam{ 317189251Ssam return wpa_ctrl_command(ctrl, "MIB"); 318189251Ssam} 319189251Ssam 320189251Ssam 321189251Ssamstatic int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[]) 322189251Ssam{ 323189251Ssam return wpa_ctrl_command(ctrl, "PMKSA"); 324189251Ssam} 325189251Ssam 326189251Ssam 327281806Srpaulostatic int wpa_cli_cmd_pmksa_flush(struct wpa_ctrl *ctrl, int argc, 328281806Srpaulo char *argv[]) 329281806Srpaulo{ 330281806Srpaulo return wpa_ctrl_command(ctrl, "PMKSA_FLUSH"); 331281806Srpaulo} 332281806Srpaulo 333281806Srpaulo 334189251Ssamstatic int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[]) 335189251Ssam{ 336252726Srpaulo print_help(argc > 0 ? argv[0] : NULL); 337189251Ssam return 0; 338189251Ssam} 339189251Ssam 340189251Ssam 341252726Srpaulostatic char ** wpa_cli_complete_help(const char *str, int pos) 342252726Srpaulo{ 343252726Srpaulo int arg = get_cmd_arg_num(str, pos); 344252726Srpaulo char **res = NULL; 345252726Srpaulo 346252726Srpaulo switch (arg) { 347252726Srpaulo case 1: 348252726Srpaulo res = wpa_list_cmd_list(); 349252726Srpaulo break; 350252726Srpaulo } 351252726Srpaulo 352252726Srpaulo return res; 353252726Srpaulo} 354252726Srpaulo 355252726Srpaulo 356189251Ssamstatic int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[]) 357189251Ssam{ 358337817Scy printf("%s\n\n%s\n", wpa_cli_version, cli_full_license); 359189251Ssam return 0; 360189251Ssam} 361189251Ssam 362189251Ssam 363189251Ssamstatic int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[]) 364189251Ssam{ 365189251Ssam wpa_cli_quit = 1; 366252726Srpaulo if (interactive) 367252726Srpaulo eloop_terminate(); 368189251Ssam return 0; 369189251Ssam} 370189251Ssam 371189251Ssam 372189251Ssamstatic int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) 373189251Ssam{ 374189251Ssam char cmd[256]; 375189251Ssam int res; 376189251Ssam 377281806Srpaulo if (argc == 1) { 378281806Srpaulo res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]); 379281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) { 380281806Srpaulo printf("Too long SET command.\n"); 381281806Srpaulo return -1; 382281806Srpaulo } 383281806Srpaulo return wpa_ctrl_command(ctrl, cmd); 384189251Ssam } 385189251Ssam 386281806Srpaulo return wpa_cli_cmd(ctrl, "SET", 2, argc, argv); 387281806Srpaulo} 388281806Srpaulo 389281806Srpaulo 390281806Srpaulostatic char ** wpa_cli_complete_set(const char *str, int pos) 391281806Srpaulo{ 392281806Srpaulo int arg = get_cmd_arg_num(str, pos); 393281806Srpaulo const char *fields[] = { 394281806Srpaulo /* runtime values */ 395281806Srpaulo "EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod", 396281806Srpaulo "EAPOL::maxStart", "dot11RSNAConfigPMKLifetime", 397281806Srpaulo "dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout", 398281806Srpaulo "wps_fragment_size", "wps_version_number", "ampdu", 399281806Srpaulo "tdls_testing", "tdls_disabled", "pno", "radio_disabled", 400281806Srpaulo "uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps", 401281806Srpaulo "no_keep_alive", 402281806Srpaulo /* global configuration parameters */ 403289549Srpaulo#ifdef CONFIG_CTRL_IFACE 404289549Srpaulo "ctrl_interface", "no_ctrl_interface", "ctrl_interface_group", 405289549Srpaulo#endif /* CONFIG_CTRL_IFACE */ 406289549Srpaulo "eapol_version", "ap_scan", "bgscan", 407289549Srpaulo#ifdef CONFIG_MESH 408289549Srpaulo "user_mpm", "max_peer_links", "mesh_max_inactivity", 409289549Srpaulo "dot11RSNASAERetransPeriod", 410289549Srpaulo#endif /* CONFIG_MESH */ 411289549Srpaulo "disable_scan_offload", "fast_reauth", "opensc_engine_path", 412289549Srpaulo "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers", 413289549Srpaulo "pcsc_reader", "pcsc_pin", "external_sim", "driver_param", 414289549Srpaulo "dot11RSNAConfigPMKLifetime", 415281806Srpaulo "dot11RSNAConfigPMKReauthThreshold", 416281806Srpaulo "dot11RSNAConfigSATimeout", 417289549Srpaulo#ifndef CONFIG_NO_CONFIG_WRITE 418289549Srpaulo "update_config", 419289549Srpaulo#endif /* CONFIG_NO_CONFIG_WRITE */ 420289549Srpaulo "load_dynamic_eap", 421289549Srpaulo#ifdef CONFIG_WPS 422289549Srpaulo "uuid", "device_name", "manufacturer", "model_name", 423289549Srpaulo "model_number", "serial_number", "device_type", "os_version", 424289549Srpaulo "config_methods", "wps_cred_processing", "wps_vendor_ext_m1", 425289549Srpaulo#endif /* CONFIG_WPS */ 426289549Srpaulo#ifdef CONFIG_P2P 427289549Srpaulo "sec_device_type", 428281806Srpaulo "p2p_listen_reg_class", "p2p_listen_channel", 429289549Srpaulo "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent", 430289549Srpaulo "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss", 431289549Srpaulo "p2p_group_idle", "p2p_passphrase_len", "p2p_pref_chan", 432289549Srpaulo "p2p_no_go_freq", "p2p_add_cli_chan", 433289549Srpaulo "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht", 434289549Srpaulo "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface", 435289549Srpaulo "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask", 436289549Srpaulo "ip_addr_start", "ip_addr_end", 437289549Srpaulo#endif /* CONFIG_P2P */ 438289549Srpaulo "country", "bss_max_count", "bss_expiration_age", 439289549Srpaulo "bss_expiration_scan_count", "filter_ssids", "filter_rssi", 440289549Srpaulo "max_num_sta", "disassoc_low_ack", 441289549Srpaulo#ifdef CONFIG_HS20 442289549Srpaulo "hs20", 443289549Srpaulo#endif /* CONFIG_HS20 */ 444289549Srpaulo "interworking", "hessid", "access_network_type", "pbc_in_m1", 445289549Srpaulo "autoscan", "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey", 446289549Srpaulo "wps_nfc_dh_privkey", "wps_nfc_dev_pw", "ext_password_backend", 447281806Srpaulo "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf", 448289549Srpaulo "sae_groups", "dtim_period", "beacon_int", 449289549Srpaulo "ap_vendor_elements", "ignore_old_scan_res", "freq_list", 450289549Srpaulo "scan_cur_freq", "sched_scan_interval", 451289549Srpaulo "tdls_external_control", "osu_dir", "wowlan_triggers", 452289549Srpaulo "p2p_search_delay", "mac_addr", "rand_addr_lifetime", 453289549Srpaulo "preassoc_mac_addr", "key_mgmt_offload", "passive_scan", 454337817Scy "reassoc_same_bss_optim", "wps_priority", 455337817Scy#ifdef CONFIG_TESTING_OPTIONS 456337817Scy "ignore_auth_resp", 457337817Scy#endif /* CONFIG_TESTING_OPTIONS */ 458281806Srpaulo }; 459281806Srpaulo int i, num_fields = ARRAY_SIZE(fields); 460281806Srpaulo 461281806Srpaulo if (arg == 1) { 462281806Srpaulo char **res = os_calloc(num_fields + 1, sizeof(char *)); 463281806Srpaulo if (res == NULL) 464281806Srpaulo return NULL; 465281806Srpaulo for (i = 0; i < num_fields; i++) { 466281806Srpaulo res[i] = os_strdup(fields[i]); 467281806Srpaulo if (res[i] == NULL) 468281806Srpaulo return res; 469281806Srpaulo } 470281806Srpaulo return res; 471189251Ssam } 472189251Ssam 473281806Srpaulo if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0) 474281806Srpaulo return cli_txt_list_array(&bsses); 475281806Srpaulo 476281806Srpaulo return NULL; 477189251Ssam} 478189251Ssam 479281806Srpaulostatic int wpa_cli_cmd_dump(struct wpa_ctrl *ctrl, int argc, char *argv[]) 480281806Srpaulo{ 481281806Srpaulo return wpa_ctrl_command(ctrl, "DUMP"); 482281806Srpaulo} 483189251Ssam 484281806Srpaulo 485337817Scystatic int wpa_cli_cmd_driver_flags(struct wpa_ctrl *ctrl, int argc, 486337817Scy char *argv[]) 487337817Scy{ 488337817Scy return wpa_ctrl_command(ctrl, "DRIVER_FLAGS"); 489337817Scy} 490337817Scy 491337817Scy 492252726Srpaulostatic int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) 493252726Srpaulo{ 494252726Srpaulo return wpa_cli_cmd(ctrl, "GET", 1, argc, argv); 495252726Srpaulo} 496252726Srpaulo 497252726Srpaulo 498289549Srpaulostatic char ** wpa_cli_complete_get(const char *str, int pos) 499289549Srpaulo{ 500289549Srpaulo int arg = get_cmd_arg_num(str, pos); 501289549Srpaulo const char *fields[] = { 502289549Srpaulo#ifdef CONFIG_CTRL_IFACE 503289549Srpaulo "ctrl_interface", "ctrl_interface_group", 504289549Srpaulo#endif /* CONFIG_CTRL_IFACE */ 505289549Srpaulo "eapol_version", "ap_scan", 506289549Srpaulo#ifdef CONFIG_MESH 507289549Srpaulo "user_mpm", "max_peer_links", "mesh_max_inactivity", 508289549Srpaulo#endif /* CONFIG_MESH */ 509289549Srpaulo "disable_scan_offload", "fast_reauth", "opensc_engine_path", 510289549Srpaulo "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers", 511289549Srpaulo "pcsc_reader", "pcsc_pin", "external_sim", "driver_param", 512289549Srpaulo "dot11RSNAConfigPMKLifetime", 513289549Srpaulo "dot11RSNAConfigPMKReauthThreshold", 514289549Srpaulo "dot11RSNAConfigSATimeout", 515289549Srpaulo#ifndef CONFIG_NO_CONFIG_WRITE 516289549Srpaulo "update_config", 517289549Srpaulo#endif /* CONFIG_NO_CONFIG_WRITE */ 518289549Srpaulo#ifdef CONFIG_WPS 519289549Srpaulo "device_name", "manufacturer", "model_name", "model_number", 520289549Srpaulo "serial_number", "config_methods", "wps_cred_processing", 521289549Srpaulo#endif /* CONFIG_WPS */ 522289549Srpaulo#ifdef CONFIG_P2P 523289549Srpaulo "p2p_listen_reg_class", "p2p_listen_channel", 524289549Srpaulo "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent", 525289549Srpaulo "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss", 526289549Srpaulo "p2p_group_idle", "p2p_passphrase_len", "p2p_add_cli_chan", 527289549Srpaulo "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht", 528289549Srpaulo "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface", 529289549Srpaulo "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask", 530289549Srpaulo "ip_addr_start", "ip_addr_end", 531289549Srpaulo#endif /* CONFIG_P2P */ 532289549Srpaulo "bss_max_count", "bss_expiration_age", 533289549Srpaulo "bss_expiration_scan_count", "filter_ssids", "filter_rssi", 534289549Srpaulo "max_num_sta", "disassoc_low_ack", 535289549Srpaulo#ifdef CONFIG_HS20 536289549Srpaulo "hs20", 537289549Srpaulo#endif /* CONFIG_HS20 */ 538289549Srpaulo "interworking", "access_network_type", "pbc_in_m1", "autoscan", 539289549Srpaulo "wps_nfc_dev_pw_id", "ext_password_backend", 540289549Srpaulo "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf", 541289549Srpaulo "dtim_period", "beacon_int", "ignore_old_scan_res", 542289549Srpaulo "scan_cur_freq", "sched_scan_interval", 543289549Srpaulo "tdls_external_control", "osu_dir", "wowlan_triggers", 544289549Srpaulo "p2p_search_delay", "mac_addr", "rand_addr_lifetime", 545289549Srpaulo "preassoc_mac_addr", "key_mgmt_offload", "passive_scan", 546289549Srpaulo "reassoc_same_bss_optim" 547289549Srpaulo }; 548289549Srpaulo int i, num_fields = ARRAY_SIZE(fields); 549289549Srpaulo 550289549Srpaulo if (arg == 1) { 551289549Srpaulo char **res = os_calloc(num_fields + 1, sizeof(char *)); 552289549Srpaulo if (res == NULL) 553289549Srpaulo return NULL; 554289549Srpaulo for (i = 0; i < num_fields; i++) { 555289549Srpaulo res[i] = os_strdup(fields[i]); 556289549Srpaulo if (res[i] == NULL) 557289549Srpaulo return res; 558289549Srpaulo } 559289549Srpaulo return res; 560289549Srpaulo } 561289549Srpaulo 562289549Srpaulo return NULL; 563289549Srpaulo} 564289549Srpaulo 565289549Srpaulo 566189251Ssamstatic int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[]) 567189251Ssam{ 568189251Ssam return wpa_ctrl_command(ctrl, "LOGOFF"); 569189251Ssam} 570189251Ssam 571189251Ssam 572189251Ssamstatic int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[]) 573189251Ssam{ 574189251Ssam return wpa_ctrl_command(ctrl, "LOGON"); 575189251Ssam} 576189251Ssam 577189251Ssam 578189251Ssamstatic int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc, 579189251Ssam char *argv[]) 580189251Ssam{ 581189251Ssam return wpa_ctrl_command(ctrl, "REASSOCIATE"); 582189251Ssam} 583189251Ssam 584189251Ssam 585281806Srpaulostatic int wpa_cli_cmd_reattach(struct wpa_ctrl *ctrl, int argc, char *argv[]) 586281806Srpaulo{ 587281806Srpaulo return wpa_ctrl_command(ctrl, "REATTACH"); 588281806Srpaulo} 589281806Srpaulo 590281806Srpaulo 591189251Ssamstatic int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc, 592189251Ssam char *argv[]) 593189251Ssam{ 594252726Srpaulo return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv); 595252726Srpaulo} 596189251Ssam 597189251Ssam 598252726Srpaulostatic int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 599252726Srpaulo{ 600252726Srpaulo return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv); 601189251Ssam} 602189251Ssam 603189251Ssam 604252726Srpaulostatic int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc, 605252726Srpaulo char *argv[]) 606189251Ssam{ 607252726Srpaulo return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv); 608252726Srpaulo} 609252726Srpaulo 610252726Srpaulo 611252726Srpaulostatic int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc, 612252726Srpaulo char *argv[]) 613252726Srpaulo{ 614252726Srpaulo return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv); 615252726Srpaulo} 616252726Srpaulo 617252726Srpaulo 618252726Srpaulostatic int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc, 619252726Srpaulo char *argv[]) 620252726Srpaulo{ 621252726Srpaulo return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv); 622252726Srpaulo} 623252726Srpaulo 624252726Srpaulo 625252726Srpaulostatic int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 626252726Srpaulo{ 627189251Ssam char cmd[256]; 628189251Ssam int res; 629189251Ssam 630252726Srpaulo if (argc < 1) 631252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0"); 632252726Srpaulo else 633252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]); 634281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) { 635252726Srpaulo printf("Too long BSS_FLUSH command.\n"); 636189251Ssam return -1; 637189251Ssam } 638189251Ssam return wpa_ctrl_command(ctrl, cmd); 639189251Ssam} 640189251Ssam 641189251Ssam 642189251Ssamstatic int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc, 643189251Ssam char *argv[]) 644189251Ssam{ 645252726Srpaulo return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv); 646252726Srpaulo} 647189251Ssam 648252726Srpaulo 649252726Srpaulostatic int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[]) 650252726Srpaulo{ 651252726Srpaulo return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv); 652252726Srpaulo} 653252726Srpaulo 654252726Srpaulo 655252726Srpaulostatic int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[]) 656252726Srpaulo{ 657252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv); 658252726Srpaulo} 659252726Srpaulo 660252726Srpaulo 661252726Srpaulostatic int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) 662252726Srpaulo{ 663252726Srpaulo if (argc == 0) { 664252726Srpaulo printf("Invalid WPS_PIN command: need one or two arguments:\n" 665252726Srpaulo "- BSSID: use 'any' to select any\n" 666252726Srpaulo "- PIN: optional, used only with devices that have no " 667252726Srpaulo "display\n"); 668189251Ssam return -1; 669189251Ssam } 670189251Ssam 671252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv); 672189251Ssam} 673189251Ssam 674189251Ssam 675252726Srpaulostatic int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc, 676252726Srpaulo char *argv[]) 677189251Ssam{ 678252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv); 679252726Srpaulo} 680189251Ssam 681252726Srpaulo 682252726Srpaulostatic int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc, 683252726Srpaulo char *argv[]) 684252726Srpaulo{ 685252726Srpaulo return wpa_ctrl_command(ctrl, "WPS_CANCEL"); 686252726Srpaulo} 687252726Srpaulo 688252726Srpaulo 689252726Srpaulo#ifdef CONFIG_WPS_NFC 690252726Srpaulo 691252726Srpaulostatic int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[]) 692252726Srpaulo{ 693252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv); 694252726Srpaulo} 695252726Srpaulo 696252726Srpaulo 697281806Srpaulostatic int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc, 698281806Srpaulo char *argv[]) 699281806Srpaulo{ 700281806Srpaulo return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv); 701281806Srpaulo} 702281806Srpaulo 703281806Srpaulo 704252726Srpaulostatic int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc, 705252726Srpaulo char *argv[]) 706252726Srpaulo{ 707252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv); 708252726Srpaulo} 709252726Srpaulo 710252726Srpaulo 711252726Srpaulostatic int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc, 712252726Srpaulo char *argv[]) 713252726Srpaulo{ 714252726Srpaulo int ret; 715252726Srpaulo char *buf; 716252726Srpaulo size_t buflen; 717252726Srpaulo 718189251Ssam if (argc != 1) { 719252726Srpaulo printf("Invalid 'wps_nfc_tag_read' command - one argument " 720252726Srpaulo "is required.\n"); 721189251Ssam return -1; 722189251Ssam } 723189251Ssam 724252726Srpaulo buflen = 18 + os_strlen(argv[0]); 725252726Srpaulo buf = os_malloc(buflen); 726252726Srpaulo if (buf == NULL) 727189251Ssam return -1; 728252726Srpaulo os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]); 729252726Srpaulo 730252726Srpaulo ret = wpa_ctrl_command(ctrl, buf); 731252726Srpaulo os_free(buf); 732252726Srpaulo 733252726Srpaulo return ret; 734189251Ssam} 735189251Ssam 736189251Ssam 737252726Srpaulostatic int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc, 738252726Srpaulo char *argv[]) 739189251Ssam{ 740252726Srpaulo return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv); 741252726Srpaulo} 742189251Ssam 743189251Ssam 744252726Srpaulostatic int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc, 745252726Srpaulo char *argv[]) 746252726Srpaulo{ 747252726Srpaulo return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv); 748189251Ssam} 749189251Ssam 750189251Ssam 751281806Srpaulostatic int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc, 752252726Srpaulo char *argv[]) 753189251Ssam{ 754281806Srpaulo return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv); 755189251Ssam} 756189251Ssam 757252726Srpaulo#endif /* CONFIG_WPS_NFC */ 758214734Srpaulo 759252726Srpaulo 760189251Ssamstatic int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[]) 761189251Ssam{ 762189251Ssam char cmd[256]; 763189251Ssam int res; 764189251Ssam 765214734Srpaulo if (argc == 2) 766214734Srpaulo res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s", 767214734Srpaulo argv[0], argv[1]); 768252726Srpaulo else if (argc == 5 || argc == 6) { 769289549Srpaulo char ssid_hex[2 * SSID_MAX_LEN + 1]; 770214734Srpaulo char key_hex[2 * 64 + 1]; 771214734Srpaulo int i; 772214734Srpaulo 773214734Srpaulo ssid_hex[0] = '\0'; 774289549Srpaulo for (i = 0; i < SSID_MAX_LEN; i++) { 775214734Srpaulo if (argv[2][i] == '\0') 776214734Srpaulo break; 777214734Srpaulo os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]); 778214734Srpaulo } 779214734Srpaulo 780214734Srpaulo key_hex[0] = '\0'; 781252726Srpaulo if (argc == 6) { 782252726Srpaulo for (i = 0; i < 64; i++) { 783252726Srpaulo if (argv[5][i] == '\0') 784252726Srpaulo break; 785252726Srpaulo os_snprintf(&key_hex[i * 2], 3, "%02x", 786252726Srpaulo argv[5][i]); 787252726Srpaulo } 788214734Srpaulo } 789214734Srpaulo 790214734Srpaulo res = os_snprintf(cmd, sizeof(cmd), 791214734Srpaulo "WPS_REG %s %s %s %s %s %s", 792214734Srpaulo argv[0], argv[1], ssid_hex, argv[3], argv[4], 793214734Srpaulo key_hex); 794214734Srpaulo } else { 795189251Ssam printf("Invalid WPS_REG command: need two arguments:\n" 796252726Srpaulo "- BSSID of the target AP\n" 797189251Ssam "- AP PIN\n"); 798214734Srpaulo printf("Alternatively, six arguments can be used to " 799214734Srpaulo "reconfigure the AP:\n" 800252726Srpaulo "- BSSID of the target AP\n" 801214734Srpaulo "- AP PIN\n" 802214734Srpaulo "- new SSID\n" 803214734Srpaulo "- new auth (OPEN, WPAPSK, WPA2PSK)\n" 804214734Srpaulo "- new encr (NONE, WEP, TKIP, CCMP)\n" 805214734Srpaulo "- new key\n"); 806189251Ssam return -1; 807189251Ssam } 808189251Ssam 809281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) { 810189251Ssam printf("Too long WPS_REG command.\n"); 811189251Ssam return -1; 812189251Ssam } 813189251Ssam return wpa_ctrl_command(ctrl, cmd); 814189251Ssam} 815189251Ssam 816189251Ssam 817252726Srpaulostatic int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc, 818252726Srpaulo char *argv[]) 819252726Srpaulo{ 820252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv); 821252726Srpaulo} 822252726Srpaulo 823252726Srpaulo 824214734Srpaulostatic int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc, 825214734Srpaulo char *argv[]) 826214734Srpaulo{ 827252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv); 828214734Srpaulo} 829214734Srpaulo 830214734Srpaulo 831214734Srpaulostatic int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc, 832214734Srpaulo char *argv[]) 833214734Srpaulo{ 834214734Srpaulo return wpa_ctrl_command(ctrl, "WPS_ER_STOP"); 835214734Srpaulo 836214734Srpaulo} 837214734Srpaulo 838214734Srpaulo 839214734Srpaulostatic int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc, 840214734Srpaulo char *argv[]) 841214734Srpaulo{ 842252726Srpaulo if (argc < 2) { 843252726Srpaulo printf("Invalid WPS_ER_PIN command: need at least two " 844252726Srpaulo "arguments:\n" 845214734Srpaulo "- UUID: use 'any' to select any\n" 846252726Srpaulo "- PIN: Enrollee PIN\n" 847252726Srpaulo "optional: - Enrollee MAC address\n"); 848214734Srpaulo return -1; 849214734Srpaulo } 850214734Srpaulo 851252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv); 852214734Srpaulo} 853214734Srpaulo 854214734Srpaulo 855214734Srpaulostatic int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc, 856214734Srpaulo char *argv[]) 857214734Srpaulo{ 858252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv); 859214734Srpaulo} 860214734Srpaulo 861214734Srpaulo 862214734Srpaulostatic int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc, 863214734Srpaulo char *argv[]) 864214734Srpaulo{ 865214734Srpaulo if (argc != 2) { 866214734Srpaulo printf("Invalid WPS_ER_LEARN command: need two arguments:\n" 867214734Srpaulo "- UUID: specify which AP to use\n" 868214734Srpaulo "- PIN: AP PIN\n"); 869214734Srpaulo return -1; 870214734Srpaulo } 871214734Srpaulo 872252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv); 873252726Srpaulo} 874252726Srpaulo 875252726Srpaulo 876252726Srpaulostatic int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc, 877252726Srpaulo char *argv[]) 878252726Srpaulo{ 879252726Srpaulo if (argc != 2) { 880252726Srpaulo printf("Invalid WPS_ER_SET_CONFIG command: need two " 881252726Srpaulo "arguments:\n" 882252726Srpaulo "- UUID: specify which AP to use\n" 883252726Srpaulo "- Network configuration id\n"); 884214734Srpaulo return -1; 885214734Srpaulo } 886252726Srpaulo 887252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv); 888214734Srpaulo} 889214734Srpaulo 890214734Srpaulo 891252726Srpaulostatic int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc, 892252726Srpaulo char *argv[]) 893214734Srpaulo{ 894214734Srpaulo char cmd[256]; 895214734Srpaulo int res; 896214734Srpaulo 897252726Srpaulo if (argc == 5 || argc == 6) { 898289549Srpaulo char ssid_hex[2 * SSID_MAX_LEN + 1]; 899252726Srpaulo char key_hex[2 * 64 + 1]; 900252726Srpaulo int i; 901252726Srpaulo 902252726Srpaulo ssid_hex[0] = '\0'; 903289549Srpaulo for (i = 0; i < SSID_MAX_LEN; i++) { 904252726Srpaulo if (argv[2][i] == '\0') 905252726Srpaulo break; 906252726Srpaulo os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]); 907252726Srpaulo } 908252726Srpaulo 909252726Srpaulo key_hex[0] = '\0'; 910252726Srpaulo if (argc == 6) { 911252726Srpaulo for (i = 0; i < 64; i++) { 912252726Srpaulo if (argv[5][i] == '\0') 913252726Srpaulo break; 914252726Srpaulo os_snprintf(&key_hex[i * 2], 3, "%02x", 915252726Srpaulo argv[5][i]); 916252726Srpaulo } 917252726Srpaulo } 918252726Srpaulo 919252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), 920252726Srpaulo "WPS_ER_CONFIG %s %s %s %s %s %s", 921252726Srpaulo argv[0], argv[1], ssid_hex, argv[3], argv[4], 922252726Srpaulo key_hex); 923252726Srpaulo } else { 924252726Srpaulo printf("Invalid WPS_ER_CONFIG command: need six arguments:\n" 925252726Srpaulo "- AP UUID\n" 926252726Srpaulo "- AP PIN\n" 927252726Srpaulo "- new SSID\n" 928252726Srpaulo "- new auth (OPEN, WPAPSK, WPA2PSK)\n" 929252726Srpaulo "- new encr (NONE, WEP, TKIP, CCMP)\n" 930252726Srpaulo "- new key\n"); 931214734Srpaulo return -1; 932214734Srpaulo } 933214734Srpaulo 934281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) { 935252726Srpaulo printf("Too long WPS_ER_CONFIG command.\n"); 936214734Srpaulo return -1; 937214734Srpaulo } 938214734Srpaulo return wpa_ctrl_command(ctrl, cmd); 939214734Srpaulo} 940214734Srpaulo 941214734Srpaulo 942252726Srpaulo#ifdef CONFIG_WPS_NFC 943252726Srpaulostatic int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc, 944252726Srpaulo char *argv[]) 945189251Ssam{ 946252726Srpaulo if (argc != 2) { 947252726Srpaulo printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two " 948252726Srpaulo "arguments:\n" 949252726Srpaulo "- WPS/NDEF: token format\n" 950252726Srpaulo "- UUID: specify which AP to use\n"); 951189251Ssam return -1; 952189251Ssam } 953252726Srpaulo 954252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv); 955189251Ssam} 956252726Srpaulo#endif /* CONFIG_WPS_NFC */ 957189251Ssam 958189251Ssam 959252726Srpaulostatic int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[]) 960252726Srpaulo{ 961252726Srpaulo return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv); 962252726Srpaulo} 963252726Srpaulo 964252726Srpaulo 965252726Srpaulostatic int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) 966252726Srpaulo{ 967252726Srpaulo return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv); 968252726Srpaulo} 969252726Srpaulo 970252726Srpaulo 971189251Ssamstatic int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[]) 972189251Ssam{ 973189251Ssam char cmd[256], *pos, *end; 974189251Ssam int i, ret; 975189251Ssam 976189251Ssam if (argc < 2) { 977189251Ssam printf("Invalid IDENTITY command: needs two arguments " 978189251Ssam "(network id and identity)\n"); 979189251Ssam return -1; 980189251Ssam } 981189251Ssam 982189251Ssam end = cmd + sizeof(cmd); 983189251Ssam pos = cmd; 984189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s", 985189251Ssam argv[0], argv[1]); 986281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 987189251Ssam printf("Too long IDENTITY command.\n"); 988189251Ssam return -1; 989189251Ssam } 990189251Ssam pos += ret; 991189251Ssam for (i = 2; i < argc; i++) { 992189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 993281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 994189251Ssam printf("Too long IDENTITY command.\n"); 995189251Ssam return -1; 996189251Ssam } 997189251Ssam pos += ret; 998189251Ssam } 999189251Ssam 1000189251Ssam return wpa_ctrl_command(ctrl, cmd); 1001189251Ssam} 1002189251Ssam 1003189251Ssam 1004189251Ssamstatic int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1005189251Ssam{ 1006189251Ssam char cmd[256], *pos, *end; 1007189251Ssam int i, ret; 1008189251Ssam 1009189251Ssam if (argc < 2) { 1010189251Ssam printf("Invalid PASSWORD command: needs two arguments " 1011189251Ssam "(network id and password)\n"); 1012189251Ssam return -1; 1013189251Ssam } 1014189251Ssam 1015189251Ssam end = cmd + sizeof(cmd); 1016189251Ssam pos = cmd; 1017189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s", 1018189251Ssam argv[0], argv[1]); 1019281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1020189251Ssam printf("Too long PASSWORD command.\n"); 1021189251Ssam return -1; 1022189251Ssam } 1023189251Ssam pos += ret; 1024189251Ssam for (i = 2; i < argc; i++) { 1025189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1026281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1027189251Ssam printf("Too long PASSWORD command.\n"); 1028189251Ssam return -1; 1029189251Ssam } 1030189251Ssam pos += ret; 1031189251Ssam } 1032189251Ssam 1033189251Ssam return wpa_ctrl_command(ctrl, cmd); 1034189251Ssam} 1035189251Ssam 1036189251Ssam 1037189251Ssamstatic int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc, 1038189251Ssam char *argv[]) 1039189251Ssam{ 1040189251Ssam char cmd[256], *pos, *end; 1041189251Ssam int i, ret; 1042189251Ssam 1043189251Ssam if (argc < 2) { 1044189251Ssam printf("Invalid NEW_PASSWORD command: needs two arguments " 1045189251Ssam "(network id and password)\n"); 1046189251Ssam return -1; 1047189251Ssam } 1048189251Ssam 1049189251Ssam end = cmd + sizeof(cmd); 1050189251Ssam pos = cmd; 1051189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s", 1052189251Ssam argv[0], argv[1]); 1053281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1054189251Ssam printf("Too long NEW_PASSWORD command.\n"); 1055189251Ssam return -1; 1056189251Ssam } 1057189251Ssam pos += ret; 1058189251Ssam for (i = 2; i < argc; i++) { 1059189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1060281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1061189251Ssam printf("Too long NEW_PASSWORD command.\n"); 1062189251Ssam return -1; 1063189251Ssam } 1064189251Ssam pos += ret; 1065189251Ssam } 1066189251Ssam 1067189251Ssam return wpa_ctrl_command(ctrl, cmd); 1068189251Ssam} 1069189251Ssam 1070189251Ssam 1071189251Ssamstatic int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1072189251Ssam{ 1073189251Ssam char cmd[256], *pos, *end; 1074189251Ssam int i, ret; 1075189251Ssam 1076189251Ssam if (argc < 2) { 1077189251Ssam printf("Invalid PIN command: needs two arguments " 1078189251Ssam "(network id and pin)\n"); 1079189251Ssam return -1; 1080189251Ssam } 1081189251Ssam 1082189251Ssam end = cmd + sizeof(cmd); 1083189251Ssam pos = cmd; 1084189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s", 1085189251Ssam argv[0], argv[1]); 1086281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1087189251Ssam printf("Too long PIN command.\n"); 1088189251Ssam return -1; 1089189251Ssam } 1090189251Ssam pos += ret; 1091189251Ssam for (i = 2; i < argc; i++) { 1092189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1093281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1094189251Ssam printf("Too long PIN command.\n"); 1095189251Ssam return -1; 1096189251Ssam } 1097189251Ssam pos += ret; 1098189251Ssam } 1099189251Ssam return wpa_ctrl_command(ctrl, cmd); 1100189251Ssam} 1101189251Ssam 1102189251Ssam 1103189251Ssamstatic int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1104189251Ssam{ 1105189251Ssam char cmd[256], *pos, *end; 1106189251Ssam int i, ret; 1107189251Ssam 1108189251Ssam if (argc < 2) { 1109189251Ssam printf("Invalid OTP command: needs two arguments (network " 1110189251Ssam "id and password)\n"); 1111189251Ssam return -1; 1112189251Ssam } 1113189251Ssam 1114189251Ssam end = cmd + sizeof(cmd); 1115189251Ssam pos = cmd; 1116189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s", 1117189251Ssam argv[0], argv[1]); 1118281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1119189251Ssam printf("Too long OTP command.\n"); 1120189251Ssam return -1; 1121189251Ssam } 1122189251Ssam pos += ret; 1123189251Ssam for (i = 2; i < argc; i++) { 1124189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1125281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1126189251Ssam printf("Too long OTP command.\n"); 1127189251Ssam return -1; 1128189251Ssam } 1129189251Ssam pos += ret; 1130189251Ssam } 1131189251Ssam 1132189251Ssam return wpa_ctrl_command(ctrl, cmd); 1133189251Ssam} 1134189251Ssam 1135189251Ssam 1136281806Srpaulostatic int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1137281806Srpaulo{ 1138281806Srpaulo char cmd[256], *pos, *end; 1139281806Srpaulo int i, ret; 1140281806Srpaulo 1141281806Srpaulo if (argc < 2) { 1142281806Srpaulo printf("Invalid SIM command: needs two arguments " 1143281806Srpaulo "(network id and SIM operation response)\n"); 1144281806Srpaulo return -1; 1145281806Srpaulo } 1146281806Srpaulo 1147281806Srpaulo end = cmd + sizeof(cmd); 1148281806Srpaulo pos = cmd; 1149281806Srpaulo ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s", 1150281806Srpaulo argv[0], argv[1]); 1151281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1152281806Srpaulo printf("Too long SIM command.\n"); 1153281806Srpaulo return -1; 1154281806Srpaulo } 1155281806Srpaulo pos += ret; 1156281806Srpaulo for (i = 2; i < argc; i++) { 1157281806Srpaulo ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1158281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1159281806Srpaulo printf("Too long SIM command.\n"); 1160281806Srpaulo return -1; 1161281806Srpaulo } 1162281806Srpaulo pos += ret; 1163281806Srpaulo } 1164281806Srpaulo return wpa_ctrl_command(ctrl, cmd); 1165281806Srpaulo} 1166281806Srpaulo 1167281806Srpaulo 1168189251Ssamstatic int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc, 1169189251Ssam char *argv[]) 1170189251Ssam{ 1171189251Ssam char cmd[256], *pos, *end; 1172189251Ssam int i, ret; 1173189251Ssam 1174189251Ssam if (argc < 2) { 1175189251Ssam printf("Invalid PASSPHRASE command: needs two arguments " 1176189251Ssam "(network id and passphrase)\n"); 1177189251Ssam return -1; 1178189251Ssam } 1179189251Ssam 1180189251Ssam end = cmd + sizeof(cmd); 1181189251Ssam pos = cmd; 1182189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s", 1183189251Ssam argv[0], argv[1]); 1184281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1185189251Ssam printf("Too long PASSPHRASE command.\n"); 1186189251Ssam return -1; 1187189251Ssam } 1188189251Ssam pos += ret; 1189189251Ssam for (i = 2; i < argc; i++) { 1190189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1191281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1192189251Ssam printf("Too long PASSPHRASE command.\n"); 1193189251Ssam return -1; 1194189251Ssam } 1195189251Ssam pos += ret; 1196189251Ssam } 1197189251Ssam 1198189251Ssam return wpa_ctrl_command(ctrl, cmd); 1199189251Ssam} 1200189251Ssam 1201189251Ssam 1202189251Ssamstatic int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1203189251Ssam{ 1204189251Ssam if (argc < 2) { 1205189251Ssam printf("Invalid BSSID command: needs two arguments (network " 1206189251Ssam "id and BSSID)\n"); 1207189251Ssam return -1; 1208189251Ssam } 1209189251Ssam 1210252726Srpaulo return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv); 1211252726Srpaulo} 1212189251Ssam 1213252726Srpaulo 1214252726Srpaulostatic int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1215252726Srpaulo{ 1216252726Srpaulo return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv); 1217189251Ssam} 1218189251Ssam 1219189251Ssam 1220252726Srpaulostatic int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1221252726Srpaulo{ 1222252726Srpaulo return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv); 1223252726Srpaulo} 1224252726Srpaulo 1225252726Srpaulo 1226189251Ssamstatic int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc, 1227189251Ssam char *argv[]) 1228189251Ssam{ 1229189251Ssam return wpa_ctrl_command(ctrl, "LIST_NETWORKS"); 1230189251Ssam} 1231189251Ssam 1232189251Ssam 1233189251Ssamstatic int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc, 1234189251Ssam char *argv[]) 1235189251Ssam{ 1236252726Srpaulo return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv); 1237189251Ssam} 1238189251Ssam 1239189251Ssam 1240189251Ssamstatic int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc, 1241189251Ssam char *argv[]) 1242189251Ssam{ 1243252726Srpaulo return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv); 1244189251Ssam} 1245189251Ssam 1246189251Ssam 1247189251Ssamstatic int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc, 1248189251Ssam char *argv[]) 1249189251Ssam{ 1250252726Srpaulo return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv); 1251189251Ssam} 1252189251Ssam 1253189251Ssam 1254189251Ssamstatic int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc, 1255189251Ssam char *argv[]) 1256189251Ssam{ 1257289549Srpaulo int res = wpa_ctrl_command(ctrl, "ADD_NETWORK"); 1258289549Srpaulo if (interactive) 1259289549Srpaulo update_networks(ctrl); 1260289549Srpaulo return res; 1261189251Ssam} 1262189251Ssam 1263189251Ssam 1264189251Ssamstatic int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc, 1265189251Ssam char *argv[]) 1266189251Ssam{ 1267289549Srpaulo int res = wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv); 1268289549Srpaulo if (interactive) 1269289549Srpaulo update_networks(ctrl); 1270289549Srpaulo return res; 1271189251Ssam} 1272189251Ssam 1273189251Ssam 1274189251Ssamstatic void wpa_cli_show_network_variables(void) 1275189251Ssam{ 1276189251Ssam printf("set_network variables:\n" 1277189251Ssam " ssid (network name, SSID)\n" 1278189251Ssam " psk (WPA passphrase or pre-shared key)\n" 1279189251Ssam " key_mgmt (key management protocol)\n" 1280189251Ssam " identity (EAP identity)\n" 1281189251Ssam " password (EAP password)\n" 1282189251Ssam " ...\n" 1283189251Ssam "\n" 1284189251Ssam "Note: Values are entered in the same format as the " 1285189251Ssam "configuration file is using,\n" 1286189251Ssam "i.e., strings values need to be inside double quotation " 1287189251Ssam "marks.\n" 1288189251Ssam "For example: set_network 1 ssid \"network name\"\n" 1289189251Ssam "\n" 1290189251Ssam "Please see wpa_supplicant.conf documentation for full list " 1291189251Ssam "of\navailable variables.\n"); 1292189251Ssam} 1293189251Ssam 1294189251Ssam 1295189251Ssamstatic int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc, 1296189251Ssam char *argv[]) 1297189251Ssam{ 1298189251Ssam if (argc == 0) { 1299189251Ssam wpa_cli_show_network_variables(); 1300189251Ssam return 0; 1301189251Ssam } 1302189251Ssam 1303252726Srpaulo if (argc < 3) { 1304189251Ssam printf("Invalid SET_NETWORK command: needs three arguments\n" 1305189251Ssam "(network id, variable name, and value)\n"); 1306189251Ssam return -1; 1307189251Ssam } 1308189251Ssam 1309252726Srpaulo return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv); 1310189251Ssam} 1311189251Ssam 1312189251Ssam 1313189251Ssamstatic int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc, 1314189251Ssam char *argv[]) 1315189251Ssam{ 1316189251Ssam if (argc == 0) { 1317189251Ssam wpa_cli_show_network_variables(); 1318189251Ssam return 0; 1319189251Ssam } 1320189251Ssam 1321189251Ssam if (argc != 2) { 1322189251Ssam printf("Invalid GET_NETWORK command: needs two arguments\n" 1323189251Ssam "(network id and variable name)\n"); 1324189251Ssam return -1; 1325189251Ssam } 1326189251Ssam 1327252726Srpaulo return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv); 1328252726Srpaulo} 1329252726Srpaulo 1330252726Srpaulo 1331289549Srpaulostatic const char *network_fields[] = { 1332289549Srpaulo "ssid", "scan_ssid", "bssid", "bssid_blacklist", 1333289549Srpaulo "bssid_whitelist", "psk", "proto", "key_mgmt", 1334289549Srpaulo "bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq", 1335337817Scy "freq_list", "max_oper_chwidth", 1336289549Srpaulo#ifdef IEEE8021X_EAPOL 1337289549Srpaulo "eap", "identity", "anonymous_identity", "password", "ca_cert", 1338289549Srpaulo "ca_path", "client_cert", "private_key", "private_key_passwd", 1339289549Srpaulo "dh_file", "subject_match", "altsubject_match", 1340289549Srpaulo "domain_suffix_match", "domain_match", "ca_cert2", "ca_path2", 1341289549Srpaulo "client_cert2", "private_key2", "private_key2_passwd", 1342289549Srpaulo "dh_file2", "subject_match2", "altsubject_match2", 1343289549Srpaulo "domain_suffix_match2", "domain_match2", "phase1", "phase2", 1344289549Srpaulo "pcsc", "pin", "engine_id", "key_id", "cert_id", "ca_cert_id", 1345289549Srpaulo "pin2", "engine2_id", "key2_id", "cert2_id", "ca_cert2_id", 1346289549Srpaulo "engine", "engine2", "eapol_flags", "sim_num", 1347289549Srpaulo "openssl_ciphers", "erp", 1348289549Srpaulo#endif /* IEEE8021X_EAPOL */ 1349289549Srpaulo "wep_key0", "wep_key1", "wep_key2", "wep_key3", 1350289549Srpaulo "wep_tx_keyidx", "priority", 1351289549Srpaulo#ifdef IEEE8021X_EAPOL 1352289549Srpaulo "eap_workaround", "pac_file", "fragment_size", "ocsp", 1353289549Srpaulo#endif /* IEEE8021X_EAPOL */ 1354289549Srpaulo#ifdef CONFIG_MESH 1355289549Srpaulo "mode", "no_auto_peer", 1356289549Srpaulo#else /* CONFIG_MESH */ 1357289549Srpaulo "mode", 1358289549Srpaulo#endif /* CONFIG_MESH */ 1359289549Srpaulo "proactive_key_caching", "disabled", "id_str", 1360289549Srpaulo#ifdef CONFIG_IEEE80211W 1361289549Srpaulo "ieee80211w", 1362289549Srpaulo#endif /* CONFIG_IEEE80211W */ 1363289549Srpaulo "peerkey", "mixed_cell", "frequency", "fixed_freq", 1364289549Srpaulo#ifdef CONFIG_MESH 1365289549Srpaulo "mesh_basic_rates", "dot11MeshMaxRetries", 1366289549Srpaulo "dot11MeshRetryTimeout", "dot11MeshConfirmTimeout", 1367289549Srpaulo "dot11MeshHoldingTimeout", 1368289549Srpaulo#endif /* CONFIG_MESH */ 1369289549Srpaulo "wpa_ptk_rekey", "bgscan", "ignore_broadcast_ssid", 1370289549Srpaulo#ifdef CONFIG_P2P 1371289549Srpaulo "go_p2p_dev_addr", "p2p_client_list", "psk_list", 1372289549Srpaulo#endif /* CONFIG_P2P */ 1373289549Srpaulo#ifdef CONFIG_HT_OVERRIDES 1374289549Srpaulo "disable_ht", "disable_ht40", "disable_sgi", "disable_ldpc", 1375289549Srpaulo "ht40_intolerant", "disable_max_amsdu", "ampdu_factor", 1376289549Srpaulo "ampdu_density", "ht_mcs", 1377289549Srpaulo#endif /* CONFIG_HT_OVERRIDES */ 1378289549Srpaulo#ifdef CONFIG_VHT_OVERRIDES 1379289549Srpaulo "disable_vht", "vht_capa", "vht_capa_mask", "vht_rx_mcs_nss_1", 1380289549Srpaulo "vht_rx_mcs_nss_2", "vht_rx_mcs_nss_3", "vht_rx_mcs_nss_4", 1381289549Srpaulo "vht_rx_mcs_nss_5", "vht_rx_mcs_nss_6", "vht_rx_mcs_nss_7", 1382289549Srpaulo "vht_rx_mcs_nss_8", "vht_tx_mcs_nss_1", "vht_tx_mcs_nss_2", 1383289549Srpaulo "vht_tx_mcs_nss_3", "vht_tx_mcs_nss_4", "vht_tx_mcs_nss_5", 1384289549Srpaulo "vht_tx_mcs_nss_6", "vht_tx_mcs_nss_7", "vht_tx_mcs_nss_8", 1385289549Srpaulo#endif /* CONFIG_VHT_OVERRIDES */ 1386289549Srpaulo "ap_max_inactivity", "dtim_period", "beacon_int", 1387289549Srpaulo#ifdef CONFIG_MACSEC 1388289549Srpaulo "macsec_policy", 1389289549Srpaulo#endif /* CONFIG_MACSEC */ 1390289549Srpaulo#ifdef CONFIG_HS20 1391289549Srpaulo "update_identifier", 1392289549Srpaulo#endif /* CONFIG_HS20 */ 1393337817Scy "mac_addr", "pbss", "wps_disabled" 1394289549Srpaulo}; 1395289549Srpaulo 1396289549Srpaulo 1397289549Srpaulostatic char ** wpa_cli_complete_network(const char *str, int pos) 1398289549Srpaulo{ 1399289549Srpaulo int arg = get_cmd_arg_num(str, pos); 1400289549Srpaulo int i, num_fields = ARRAY_SIZE(network_fields); 1401289549Srpaulo char **res = NULL; 1402289549Srpaulo 1403289549Srpaulo switch (arg) { 1404289549Srpaulo case 1: 1405289549Srpaulo res = cli_txt_list_array(&networks); 1406289549Srpaulo break; 1407289549Srpaulo case 2: 1408289549Srpaulo res = os_calloc(num_fields + 1, sizeof(char *)); 1409289549Srpaulo if (res == NULL) 1410289549Srpaulo return NULL; 1411289549Srpaulo for (i = 0; i < num_fields; i++) { 1412289549Srpaulo res[i] = os_strdup(network_fields[i]); 1413289549Srpaulo if (res[i] == NULL) 1414289549Srpaulo break; 1415289549Srpaulo } 1416289549Srpaulo } 1417289549Srpaulo return res; 1418289549Srpaulo} 1419289549Srpaulo 1420289549Srpaulo 1421289549Srpaulostatic char ** wpa_cli_complete_network_id(const char *str, int pos) 1422289549Srpaulo{ 1423289549Srpaulo int arg = get_cmd_arg_num(str, pos); 1424289549Srpaulo if (arg == 1) 1425289549Srpaulo return cli_txt_list_array(&networks); 1426289549Srpaulo return NULL; 1427289549Srpaulo} 1428289549Srpaulo 1429289549Srpaulo 1430281806Srpaulostatic int wpa_cli_cmd_dup_network(struct wpa_ctrl *ctrl, int argc, 1431281806Srpaulo char *argv[]) 1432281806Srpaulo{ 1433281806Srpaulo if (argc == 0) { 1434281806Srpaulo wpa_cli_show_network_variables(); 1435281806Srpaulo return 0; 1436281806Srpaulo } 1437281806Srpaulo 1438281806Srpaulo if (argc < 3) { 1439281806Srpaulo printf("Invalid DUP_NETWORK command: needs three arguments\n" 1440281806Srpaulo "(src netid, dest netid, and variable name)\n"); 1441281806Srpaulo return -1; 1442281806Srpaulo } 1443281806Srpaulo 1444281806Srpaulo return wpa_cli_cmd(ctrl, "DUP_NETWORK", 3, argc, argv); 1445281806Srpaulo} 1446281806Srpaulo 1447281806Srpaulo 1448289549Srpaulostatic char ** wpa_cli_complete_dup_network(const char *str, int pos) 1449289549Srpaulo{ 1450289549Srpaulo int arg = get_cmd_arg_num(str, pos); 1451289549Srpaulo int i, num_fields = ARRAY_SIZE(network_fields); 1452289549Srpaulo char **res = NULL; 1453289549Srpaulo 1454289549Srpaulo switch (arg) { 1455289549Srpaulo case 1: 1456289549Srpaulo case 2: 1457289549Srpaulo res = cli_txt_list_array(&networks); 1458289549Srpaulo break; 1459289549Srpaulo case 3: 1460289549Srpaulo res = os_calloc(num_fields + 1, sizeof(char *)); 1461289549Srpaulo if (res == NULL) 1462289549Srpaulo return NULL; 1463289549Srpaulo for (i = 0; i < num_fields; i++) { 1464289549Srpaulo res[i] = os_strdup(network_fields[i]); 1465289549Srpaulo if (res[i] == NULL) 1466289549Srpaulo break; 1467289549Srpaulo } 1468289549Srpaulo } 1469289549Srpaulo return res; 1470289549Srpaulo} 1471289549Srpaulo 1472289549Srpaulo 1473252726Srpaulostatic int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc, 1474252726Srpaulo char *argv[]) 1475252726Srpaulo{ 1476252726Srpaulo return wpa_ctrl_command(ctrl, "LIST_CREDS"); 1477252726Srpaulo} 1478252726Srpaulo 1479252726Srpaulo 1480252726Srpaulostatic int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1481252726Srpaulo{ 1482252726Srpaulo return wpa_ctrl_command(ctrl, "ADD_CRED"); 1483252726Srpaulo} 1484252726Srpaulo 1485252726Srpaulo 1486252726Srpaulostatic int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc, 1487252726Srpaulo char *argv[]) 1488252726Srpaulo{ 1489252726Srpaulo return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv); 1490252726Srpaulo} 1491252726Srpaulo 1492252726Srpaulo 1493252726Srpaulostatic int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1494252726Srpaulo{ 1495252726Srpaulo if (argc != 3) { 1496252726Srpaulo printf("Invalid SET_CRED command: needs three arguments\n" 1497252726Srpaulo "(cred id, variable name, and value)\n"); 1498189251Ssam return -1; 1499189251Ssam } 1500252726Srpaulo 1501252726Srpaulo return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv); 1502189251Ssam} 1503189251Ssam 1504189251Ssam 1505281806Srpaulostatic int wpa_cli_cmd_get_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1506281806Srpaulo{ 1507281806Srpaulo if (argc != 2) { 1508281806Srpaulo printf("Invalid GET_CRED command: needs two arguments\n" 1509281806Srpaulo "(cred id, variable name)\n"); 1510281806Srpaulo return -1; 1511281806Srpaulo } 1512281806Srpaulo 1513281806Srpaulo return wpa_cli_cmd(ctrl, "GET_CRED", 2, argc, argv); 1514281806Srpaulo} 1515281806Srpaulo 1516281806Srpaulo 1517189251Ssamstatic int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc, 1518189251Ssam char *argv[]) 1519189251Ssam{ 1520189251Ssam return wpa_ctrl_command(ctrl, "DISCONNECT"); 1521189251Ssam} 1522189251Ssam 1523189251Ssam 1524189251Ssamstatic int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc, 1525189251Ssam char *argv[]) 1526189251Ssam{ 1527189251Ssam return wpa_ctrl_command(ctrl, "RECONNECT"); 1528189251Ssam} 1529189251Ssam 1530189251Ssam 1531189251Ssamstatic int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc, 1532189251Ssam char *argv[]) 1533189251Ssam{ 1534189251Ssam return wpa_ctrl_command(ctrl, "SAVE_CONFIG"); 1535189251Ssam} 1536189251Ssam 1537189251Ssam 1538189251Ssamstatic int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1539189251Ssam{ 1540281806Srpaulo return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv); 1541189251Ssam} 1542189251Ssam 1543189251Ssam 1544189251Ssamstatic int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc, 1545189251Ssam char *argv[]) 1546189251Ssam{ 1547189251Ssam return wpa_ctrl_command(ctrl, "SCAN_RESULTS"); 1548189251Ssam} 1549189251Ssam 1550189251Ssam 1551337817Scystatic int wpa_cli_cmd_abort_scan(struct wpa_ctrl *ctrl, int argc, 1552337817Scy char *argv[]) 1553337817Scy{ 1554337817Scy return wpa_ctrl_command(ctrl, "ABORT_SCAN"); 1555337817Scy} 1556337817Scy 1557337817Scy 1558189251Ssamstatic int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1559189251Ssam{ 1560252726Srpaulo return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv); 1561252726Srpaulo} 1562189251Ssam 1563252726Srpaulo 1564252726Srpaulostatic char ** wpa_cli_complete_bss(const char *str, int pos) 1565252726Srpaulo{ 1566252726Srpaulo int arg = get_cmd_arg_num(str, pos); 1567252726Srpaulo char **res = NULL; 1568252726Srpaulo 1569252726Srpaulo switch (arg) { 1570252726Srpaulo case 1: 1571252726Srpaulo res = cli_txt_list_array(&bsses); 1572252726Srpaulo break; 1573189251Ssam } 1574189251Ssam 1575252726Srpaulo return res; 1576189251Ssam} 1577189251Ssam 1578189251Ssam 1579189251Ssamstatic int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc, 1580189251Ssam char *argv[]) 1581189251Ssam{ 1582189251Ssam if (argc < 1 || argc > 2) { 1583189251Ssam printf("Invalid GET_CAPABILITY command: need either one or " 1584189251Ssam "two arguments\n"); 1585189251Ssam return -1; 1586189251Ssam } 1587189251Ssam 1588189251Ssam if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) { 1589189251Ssam printf("Invalid GET_CAPABILITY command: second argument, " 1590189251Ssam "if any, must be 'strict'\n"); 1591189251Ssam return -1; 1592189251Ssam } 1593189251Ssam 1594252726Srpaulo return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv); 1595189251Ssam} 1596189251Ssam 1597189251Ssam 1598337817Scystatic char ** wpa_cli_complete_get_capability(const char *str, int pos) 1599337817Scy{ 1600337817Scy int arg = get_cmd_arg_num(str, pos); 1601337817Scy const char *fields[] = { 1602337817Scy "eap", "pairwise", "group", "group_mgmt", "key_mgmt", 1603337817Scy "proto", "auth_alg", "modes", "channels", "freq", 1604337817Scy#ifdef CONFIG_TDLS 1605337817Scy "tdls", 1606337817Scy#endif /* CONFIG_TDLS */ 1607337817Scy#ifdef CONFIG_ERP 1608337817Scy "erp", 1609337817Scy#endif /* CONFIG_ERP */ 1610337817Scy#ifdef CONFIG_FIPS 1611337817Scy "fips", 1612337817Scy#endif /* CONFIG_FIPS */ 1613337817Scy#ifdef CONFIG_ACS 1614337817Scy "acs", 1615337817Scy#endif /* CONFIG_ACS */ 1616337817Scy }; 1617337817Scy int i, num_fields = ARRAY_SIZE(fields); 1618337817Scy char **res = NULL; 1619337817Scy 1620337817Scy if (arg == 1) { 1621337817Scy res = os_calloc(num_fields + 1, sizeof(char *)); 1622337817Scy if (res == NULL) 1623337817Scy return NULL; 1624337817Scy for (i = 0; i < num_fields; i++) { 1625337817Scy res[i] = os_strdup(fields[i]); 1626337817Scy if (res[i] == NULL) 1627337817Scy return res; 1628337817Scy } 1629337817Scy } 1630337817Scy if (arg == 2) { 1631337817Scy res = os_calloc(1 + 1, sizeof(char *)); 1632337817Scy if (res == NULL) 1633337817Scy return NULL; 1634337817Scy res[0] = os_strdup("strict"); 1635337817Scy } 1636337817Scy return res; 1637337817Scy} 1638337817Scy 1639337817Scy 1640189251Ssamstatic int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl) 1641189251Ssam{ 1642189251Ssam printf("Available interfaces:\n"); 1643189251Ssam return wpa_ctrl_command(ctrl, "INTERFACES"); 1644189251Ssam} 1645189251Ssam 1646189251Ssam 1647189251Ssamstatic int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1648189251Ssam{ 1649189251Ssam if (argc < 1) { 1650189251Ssam wpa_cli_list_interfaces(ctrl); 1651189251Ssam return 0; 1652189251Ssam } 1653189251Ssam 1654189251Ssam wpa_cli_close_connection(); 1655189251Ssam os_free(ctrl_ifname); 1656189251Ssam ctrl_ifname = os_strdup(argv[0]); 1657281806Srpaulo if (!ctrl_ifname) { 1658281806Srpaulo printf("Failed to allocate memory\n"); 1659281806Srpaulo return 0; 1660281806Srpaulo } 1661189251Ssam 1662281806Srpaulo if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) { 1663189251Ssam printf("Connected to interface '%s.\n", ctrl_ifname); 1664189251Ssam } else { 1665189251Ssam printf("Could not connect to interface '%s' - re-trying\n", 1666189251Ssam ctrl_ifname); 1667189251Ssam } 1668189251Ssam return 0; 1669189251Ssam} 1670189251Ssam 1671189251Ssam 1672189251Ssamstatic int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc, 1673189251Ssam char *argv[]) 1674189251Ssam{ 1675189251Ssam return wpa_ctrl_command(ctrl, "RECONFIGURE"); 1676189251Ssam} 1677189251Ssam 1678189251Ssam 1679189251Ssamstatic int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc, 1680189251Ssam char *argv[]) 1681189251Ssam{ 1682189251Ssam return wpa_ctrl_command(ctrl, "TERMINATE"); 1683189251Ssam} 1684189251Ssam 1685189251Ssam 1686189251Ssamstatic int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc, 1687189251Ssam char *argv[]) 1688189251Ssam{ 1689189251Ssam char cmd[256]; 1690189251Ssam int res; 1691189251Ssam 1692189251Ssam if (argc < 1) { 1693189251Ssam printf("Invalid INTERFACE_ADD command: needs at least one " 1694189251Ssam "argument (interface name)\n" 1695189251Ssam "All arguments: ifname confname driver ctrl_interface " 1696289549Srpaulo "driver_param bridge_name [create]\n"); 1697189251Ssam return -1; 1698189251Ssam } 1699189251Ssam 1700189251Ssam /* 1701189251Ssam * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB 1702337817Scy * <driver_param>TAB<bridge_name>[TAB<create>[TAB<type>]] 1703189251Ssam */ 1704189251Ssam res = os_snprintf(cmd, sizeof(cmd), 1705337817Scy "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s\t%s\t%s", 1706189251Ssam argv[0], 1707189251Ssam argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "", 1708189251Ssam argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "", 1709337817Scy argc > 5 ? argv[5] : "", argc > 6 ? argv[6] : "", 1710337817Scy argc > 7 ? argv[7] : ""); 1711281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 1712189251Ssam return -1; 1713189251Ssam cmd[sizeof(cmd) - 1] = '\0'; 1714189251Ssam return wpa_ctrl_command(ctrl, cmd); 1715189251Ssam} 1716189251Ssam 1717189251Ssam 1718189251Ssamstatic int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc, 1719189251Ssam char *argv[]) 1720189251Ssam{ 1721252726Srpaulo return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv); 1722189251Ssam} 1723189251Ssam 1724189251Ssam 1725189251Ssamstatic int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc, 1726189251Ssam char *argv[]) 1727189251Ssam{ 1728189251Ssam return wpa_ctrl_command(ctrl, "INTERFACE_LIST"); 1729189251Ssam} 1730189251Ssam 1731189251Ssam 1732214734Srpaulo#ifdef CONFIG_AP 1733214734Srpaulostatic int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1734214734Srpaulo{ 1735252726Srpaulo return wpa_cli_cmd(ctrl, "STA", 1, argc, argv); 1736214734Srpaulo} 1737214734Srpaulo 1738214734Srpaulo 1739214734Srpaulostatic int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd, 1740214734Srpaulo char *addr, size_t addr_len) 1741214734Srpaulo{ 1742214734Srpaulo char buf[4096], *pos; 1743214734Srpaulo size_t len; 1744214734Srpaulo int ret; 1745214734Srpaulo 1746214734Srpaulo if (ctrl_conn == NULL) { 1747214734Srpaulo printf("Not connected to hostapd - command dropped.\n"); 1748214734Srpaulo return -1; 1749214734Srpaulo } 1750337817Scy if (ifname_prefix) { 1751337817Scy os_snprintf(buf, sizeof(buf), "IFNAME=%s %s", 1752337817Scy ifname_prefix, cmd); 1753337817Scy buf[sizeof(buf) - 1] = '\0'; 1754337817Scy cmd = buf; 1755337817Scy } 1756214734Srpaulo len = sizeof(buf) - 1; 1757252726Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 1758214734Srpaulo wpa_cli_msg_cb); 1759214734Srpaulo if (ret == -2) { 1760214734Srpaulo printf("'%s' command timed out.\n", cmd); 1761214734Srpaulo return -2; 1762214734Srpaulo } else if (ret < 0) { 1763214734Srpaulo printf("'%s' command failed.\n", cmd); 1764214734Srpaulo return -1; 1765214734Srpaulo } 1766214734Srpaulo 1767214734Srpaulo buf[len] = '\0'; 1768252726Srpaulo if (os_memcmp(buf, "FAIL", 4) == 0) 1769214734Srpaulo return -1; 1770214734Srpaulo printf("%s", buf); 1771214734Srpaulo 1772214734Srpaulo pos = buf; 1773214734Srpaulo while (*pos != '\0' && *pos != '\n') 1774214734Srpaulo pos++; 1775214734Srpaulo *pos = '\0'; 1776214734Srpaulo os_strlcpy(addr, buf, addr_len); 1777214734Srpaulo return 0; 1778214734Srpaulo} 1779214734Srpaulo 1780214734Srpaulo 1781214734Srpaulostatic int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1782214734Srpaulo{ 1783214734Srpaulo char addr[32], cmd[64]; 1784214734Srpaulo 1785214734Srpaulo if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr))) 1786214734Srpaulo return 0; 1787214734Srpaulo do { 1788214734Srpaulo os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); 1789214734Srpaulo } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0); 1790214734Srpaulo 1791214734Srpaulo return -1; 1792214734Srpaulo} 1793252726Srpaulo 1794252726Srpaulo 1795252726Srpaulostatic int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc, 1796252726Srpaulo char *argv[]) 1797252726Srpaulo{ 1798252726Srpaulo return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv); 1799252726Srpaulo} 1800252726Srpaulo 1801252726Srpaulo 1802252726Srpaulostatic int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc, 1803252726Srpaulo char *argv[]) 1804252726Srpaulo{ 1805252726Srpaulo return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv); 1806252726Srpaulo} 1807281806Srpaulo 1808281806Srpaulostatic int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc, 1809281806Srpaulo char *argv[]) 1810281806Srpaulo{ 1811281806Srpaulo return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv); 1812281806Srpaulo} 1813281806Srpaulo 1814214734Srpaulo#endif /* CONFIG_AP */ 1815214734Srpaulo 1816214734Srpaulo 1817214734Srpaulostatic int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1818214734Srpaulo{ 1819214734Srpaulo return wpa_ctrl_command(ctrl, "SUSPEND"); 1820214734Srpaulo} 1821214734Srpaulo 1822214734Srpaulo 1823214734Srpaulostatic int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1824214734Srpaulo{ 1825214734Srpaulo return wpa_ctrl_command(ctrl, "RESUME"); 1826214734Srpaulo} 1827214734Srpaulo 1828214734Srpaulo 1829281806Srpaulo#ifdef CONFIG_TESTING_OPTIONS 1830214734Srpaulostatic int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1831214734Srpaulo{ 1832214734Srpaulo return wpa_ctrl_command(ctrl, "DROP_SA"); 1833214734Srpaulo} 1834281806Srpaulo#endif /* CONFIG_TESTING_OPTIONS */ 1835214734Srpaulo 1836214734Srpaulo 1837214734Srpaulostatic int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1838214734Srpaulo{ 1839252726Srpaulo return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv); 1840252726Srpaulo} 1841252726Srpaulo 1842252726Srpaulo 1843281806Srpaulo#ifdef CONFIG_MESH 1844281806Srpaulo 1845281806Srpaulostatic int wpa_cli_cmd_mesh_interface_add(struct wpa_ctrl *ctrl, int argc, 1846281806Srpaulo char *argv[]) 1847281806Srpaulo{ 1848281806Srpaulo return wpa_cli_cmd(ctrl, "MESH_INTERFACE_ADD", 0, argc, argv); 1849281806Srpaulo} 1850281806Srpaulo 1851281806Srpaulo 1852281806Srpaulostatic int wpa_cli_cmd_mesh_group_add(struct wpa_ctrl *ctrl, int argc, 1853281806Srpaulo char *argv[]) 1854281806Srpaulo{ 1855281806Srpaulo return wpa_cli_cmd(ctrl, "MESH_GROUP_ADD", 1, argc, argv); 1856281806Srpaulo} 1857281806Srpaulo 1858281806Srpaulo 1859281806Srpaulostatic int wpa_cli_cmd_mesh_group_remove(struct wpa_ctrl *ctrl, int argc, 1860281806Srpaulo char *argv[]) 1861281806Srpaulo{ 1862281806Srpaulo return wpa_cli_cmd(ctrl, "MESH_GROUP_REMOVE", 1, argc, argv); 1863281806Srpaulo} 1864281806Srpaulo 1865337817Scy 1866337817Scystatic int wpa_cli_cmd_mesh_peer_remove(struct wpa_ctrl *ctrl, int argc, 1867337817Scy char *argv[]) 1868337817Scy{ 1869337817Scy return wpa_cli_cmd(ctrl, "MESH_PEER_REMOVE", 1, argc, argv); 1870337817Scy} 1871337817Scy 1872337817Scy 1873337817Scystatic int wpa_cli_cmd_mesh_peer_add(struct wpa_ctrl *ctrl, int argc, 1874337817Scy char *argv[]) 1875337817Scy{ 1876337817Scy return wpa_cli_cmd(ctrl, "MESH_PEER_ADD", 1, argc, argv); 1877337817Scy} 1878337817Scy 1879281806Srpaulo#endif /* CONFIG_MESH */ 1880281806Srpaulo 1881281806Srpaulo 1882252726Srpaulo#ifdef CONFIG_P2P 1883252726Srpaulo 1884252726Srpaulostatic int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1885252726Srpaulo{ 1886252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv); 1887252726Srpaulo} 1888252726Srpaulo 1889252726Srpaulo 1890252726Srpaulostatic char ** wpa_cli_complete_p2p_find(const char *str, int pos) 1891252726Srpaulo{ 1892252726Srpaulo char **res = NULL; 1893252726Srpaulo int arg = get_cmd_arg_num(str, pos); 1894252726Srpaulo 1895252726Srpaulo res = os_calloc(6, sizeof(char *)); 1896252726Srpaulo if (res == NULL) 1897252726Srpaulo return NULL; 1898252726Srpaulo res[0] = os_strdup("type=social"); 1899252726Srpaulo if (res[0] == NULL) { 1900252726Srpaulo os_free(res); 1901252726Srpaulo return NULL; 1902252726Srpaulo } 1903252726Srpaulo res[1] = os_strdup("type=progressive"); 1904252726Srpaulo if (res[1] == NULL) 1905252726Srpaulo return res; 1906252726Srpaulo res[2] = os_strdup("delay="); 1907252726Srpaulo if (res[2] == NULL) 1908252726Srpaulo return res; 1909252726Srpaulo res[3] = os_strdup("dev_id="); 1910252726Srpaulo if (res[3] == NULL) 1911252726Srpaulo return res; 1912252726Srpaulo if (arg == 1) 1913252726Srpaulo res[4] = os_strdup("[timeout]"); 1914252726Srpaulo 1915252726Srpaulo return res; 1916252726Srpaulo} 1917252726Srpaulo 1918252726Srpaulo 1919252726Srpaulostatic int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc, 1920252726Srpaulo char *argv[]) 1921252726Srpaulo{ 1922252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_STOP_FIND"); 1923252726Srpaulo} 1924252726Srpaulo 1925252726Srpaulo 1926281806Srpaulostatic int wpa_cli_cmd_p2p_asp_provision(struct wpa_ctrl *ctrl, int argc, 1927281806Srpaulo char *argv[]) 1928281806Srpaulo{ 1929281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION", 3, argc, argv); 1930281806Srpaulo} 1931281806Srpaulo 1932281806Srpaulo 1933281806Srpaulostatic int wpa_cli_cmd_p2p_asp_provision_resp(struct wpa_ctrl *ctrl, int argc, 1934281806Srpaulo char *argv[]) 1935281806Srpaulo{ 1936281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION_RESP", 2, argc, argv); 1937281806Srpaulo} 1938281806Srpaulo 1939281806Srpaulo 1940252726Srpaulostatic int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc, 1941252726Srpaulo char *argv[]) 1942252726Srpaulo{ 1943252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv); 1944252726Srpaulo} 1945252726Srpaulo 1946252726Srpaulo 1947252726Srpaulostatic char ** wpa_cli_complete_p2p_connect(const char *str, int pos) 1948252726Srpaulo{ 1949252726Srpaulo int arg = get_cmd_arg_num(str, pos); 1950252726Srpaulo char **res = NULL; 1951252726Srpaulo 1952252726Srpaulo switch (arg) { 1953252726Srpaulo case 1: 1954252726Srpaulo res = cli_txt_list_array(&p2p_peers); 1955252726Srpaulo break; 1956252726Srpaulo } 1957252726Srpaulo 1958252726Srpaulo return res; 1959252726Srpaulo} 1960252726Srpaulo 1961252726Srpaulo 1962252726Srpaulostatic int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc, 1963252726Srpaulo char *argv[]) 1964252726Srpaulo{ 1965252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv); 1966252726Srpaulo} 1967252726Srpaulo 1968252726Srpaulo 1969252726Srpaulostatic int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc, 1970252726Srpaulo char *argv[]) 1971252726Srpaulo{ 1972252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv); 1973252726Srpaulo} 1974252726Srpaulo 1975252726Srpaulo 1976252726Srpaulostatic char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos) 1977252726Srpaulo{ 1978252726Srpaulo int arg = get_cmd_arg_num(str, pos); 1979252726Srpaulo char **res = NULL; 1980252726Srpaulo 1981252726Srpaulo switch (arg) { 1982252726Srpaulo case 1: 1983252726Srpaulo res = cli_txt_list_array(&p2p_groups); 1984252726Srpaulo break; 1985252726Srpaulo } 1986252726Srpaulo 1987252726Srpaulo return res; 1988252726Srpaulo} 1989252726Srpaulo 1990252726Srpaulo 1991252726Srpaulostatic int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc, 1992252726Srpaulo char *argv[]) 1993252726Srpaulo{ 1994252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv); 1995252726Srpaulo} 1996252726Srpaulo 1997252726Srpaulo 1998337817Scystatic int wpa_cli_cmd_p2p_group_member(struct wpa_ctrl *ctrl, int argc, 1999337817Scy char *argv[]) 2000337817Scy{ 2001337817Scy return wpa_cli_cmd(ctrl, "P2P_GROUP_MEMBER", 1, argc, argv); 2002337817Scy} 2003337817Scy 2004337817Scy 2005252726Srpaulostatic int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc, 2006252726Srpaulo char *argv[]) 2007252726Srpaulo{ 2008252726Srpaulo if (argc != 2 && argc != 3) { 2009252726Srpaulo printf("Invalid P2P_PROV_DISC command: needs at least " 2010252726Srpaulo "two arguments, address and config method\n" 2011252726Srpaulo "(display, keypad, or pbc) and an optional join\n"); 2012252726Srpaulo return -1; 2013252726Srpaulo } 2014252726Srpaulo 2015252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv); 2016252726Srpaulo} 2017252726Srpaulo 2018252726Srpaulo 2019252726Srpaulostatic int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc, 2020252726Srpaulo char *argv[]) 2021252726Srpaulo{ 2022252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE"); 2023252726Srpaulo} 2024252726Srpaulo 2025252726Srpaulo 2026252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc, 2027252726Srpaulo char *argv[]) 2028252726Srpaulo{ 2029252726Srpaulo char cmd[4096]; 2030252726Srpaulo 2031281806Srpaulo if (argc < 2) { 2032252726Srpaulo printf("Invalid P2P_SERV_DISC_REQ command: needs two " 2033281806Srpaulo "or more arguments (address and TLVs)\n"); 2034252726Srpaulo return -1; 2035252726Srpaulo } 2036252726Srpaulo 2037252726Srpaulo if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0) 2038252726Srpaulo return -1; 2039252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2040252726Srpaulo} 2041252726Srpaulo 2042252726Srpaulo 2043252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl, 2044252726Srpaulo int argc, char *argv[]) 2045252726Srpaulo{ 2046252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv); 2047252726Srpaulo} 2048252726Srpaulo 2049252726Srpaulo 2050252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc, 2051252726Srpaulo char *argv[]) 2052252726Srpaulo{ 2053252726Srpaulo char cmd[4096]; 2054214734Srpaulo int res; 2055214734Srpaulo 2056252726Srpaulo if (argc != 4) { 2057252726Srpaulo printf("Invalid P2P_SERV_DISC_RESP command: needs four " 2058252726Srpaulo "arguments (freq, address, dialog token, and TLVs)\n"); 2059252726Srpaulo return -1; 2060252726Srpaulo } 2061252726Srpaulo 2062252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s", 2063252726Srpaulo argv[0], argv[1], argv[2], argv[3]); 2064281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 2065252726Srpaulo return -1; 2066252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 2067252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2068252726Srpaulo} 2069252726Srpaulo 2070252726Srpaulo 2071252726Srpaulostatic int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc, 2072252726Srpaulo char *argv[]) 2073252726Srpaulo{ 2074252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE"); 2075252726Srpaulo} 2076252726Srpaulo 2077252726Srpaulo 2078252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl, 2079252726Srpaulo int argc, char *argv[]) 2080252726Srpaulo{ 2081252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv); 2082252726Srpaulo} 2083252726Srpaulo 2084252726Srpaulo 2085252726Srpaulostatic int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc, 2086252726Srpaulo char *argv[]) 2087252726Srpaulo{ 2088252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH"); 2089252726Srpaulo} 2090252726Srpaulo 2091252726Srpaulo 2092252726Srpaulostatic int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc, 2093252726Srpaulo char *argv[]) 2094252726Srpaulo{ 2095281806Srpaulo if (argc < 3) { 2096281806Srpaulo printf("Invalid P2P_SERVICE_ADD command: needs 3-6 arguments\n"); 2097281806Srpaulo return -1; 2098281806Srpaulo } 2099252726Srpaulo 2100281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERVICE_ADD", 3, argc, argv); 2101281806Srpaulo} 2102281806Srpaulo 2103281806Srpaulo 2104281806Srpaulostatic int wpa_cli_cmd_p2p_service_rep(struct wpa_ctrl *ctrl, int argc, 2105281806Srpaulo char *argv[]) 2106281806Srpaulo{ 2107281806Srpaulo if (argc < 5 || argc > 6) { 2108281806Srpaulo printf("Invalid P2P_SERVICE_REP command: needs 5-6 " 2109252726Srpaulo "arguments\n"); 2110252726Srpaulo return -1; 2111252726Srpaulo } 2112252726Srpaulo 2113281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERVICE_REP", 5, argc, argv); 2114252726Srpaulo} 2115252726Srpaulo 2116252726Srpaulo 2117252726Srpaulostatic int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc, 2118252726Srpaulo char *argv[]) 2119252726Srpaulo{ 2120252726Srpaulo char cmd[4096]; 2121252726Srpaulo int res; 2122252726Srpaulo 2123252726Srpaulo if (argc != 2 && argc != 3) { 2124252726Srpaulo printf("Invalid P2P_SERVICE_DEL command: needs two or three " 2125252726Srpaulo "arguments\n"); 2126252726Srpaulo return -1; 2127252726Srpaulo } 2128252726Srpaulo 2129252726Srpaulo if (argc == 3) 2130252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), 2131252726Srpaulo "P2P_SERVICE_DEL %s %s %s", 2132252726Srpaulo argv[0], argv[1], argv[2]); 2133252726Srpaulo else 2134252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), 2135252726Srpaulo "P2P_SERVICE_DEL %s %s", 2136252726Srpaulo argv[0], argv[1]); 2137281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 2138252726Srpaulo return -1; 2139252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 2140252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2141252726Srpaulo} 2142252726Srpaulo 2143252726Srpaulo 2144252726Srpaulostatic int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl, 2145252726Srpaulo int argc, char *argv[]) 2146252726Srpaulo{ 2147252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv); 2148252726Srpaulo} 2149252726Srpaulo 2150252726Srpaulo 2151252726Srpaulostatic int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl, 2152252726Srpaulo int argc, char *argv[]) 2153252726Srpaulo{ 2154252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv); 2155252726Srpaulo} 2156252726Srpaulo 2157252726Srpaulo 2158252726Srpaulostatic int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2159252726Srpaulo{ 2160252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv); 2161252726Srpaulo} 2162252726Srpaulo 2163252726Srpaulo 2164252726Srpaulostatic char ** wpa_cli_complete_p2p_peer(const char *str, int pos) 2165252726Srpaulo{ 2166252726Srpaulo int arg = get_cmd_arg_num(str, pos); 2167252726Srpaulo char **res = NULL; 2168252726Srpaulo 2169252726Srpaulo switch (arg) { 2170252726Srpaulo case 1: 2171252726Srpaulo res = cli_txt_list_array(&p2p_peers); 2172252726Srpaulo break; 2173252726Srpaulo } 2174252726Srpaulo 2175252726Srpaulo return res; 2176252726Srpaulo} 2177252726Srpaulo 2178252726Srpaulo 2179252726Srpaulostatic int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd, 2180252726Srpaulo char *addr, size_t addr_len, 2181252726Srpaulo int discovered) 2182252726Srpaulo{ 2183252726Srpaulo char buf[4096], *pos; 2184252726Srpaulo size_t len; 2185252726Srpaulo int ret; 2186252726Srpaulo 2187252726Srpaulo if (ctrl_conn == NULL) 2188252726Srpaulo return -1; 2189252726Srpaulo len = sizeof(buf) - 1; 2190252726Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 2191252726Srpaulo wpa_cli_msg_cb); 2192252726Srpaulo if (ret == -2) { 2193252726Srpaulo printf("'%s' command timed out.\n", cmd); 2194252726Srpaulo return -2; 2195252726Srpaulo } else if (ret < 0) { 2196252726Srpaulo printf("'%s' command failed.\n", cmd); 2197252726Srpaulo return -1; 2198252726Srpaulo } 2199252726Srpaulo 2200252726Srpaulo buf[len] = '\0'; 2201252726Srpaulo if (os_memcmp(buf, "FAIL", 4) == 0) 2202252726Srpaulo return -1; 2203252726Srpaulo 2204252726Srpaulo pos = buf; 2205252726Srpaulo while (*pos != '\0' && *pos != '\n') 2206252726Srpaulo pos++; 2207252726Srpaulo *pos++ = '\0'; 2208252726Srpaulo os_strlcpy(addr, buf, addr_len); 2209252726Srpaulo if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL) 2210252726Srpaulo printf("%s\n", addr); 2211252726Srpaulo return 0; 2212252726Srpaulo} 2213252726Srpaulo 2214252726Srpaulo 2215252726Srpaulostatic int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2216252726Srpaulo{ 2217252726Srpaulo char addr[32], cmd[64]; 2218252726Srpaulo int discovered; 2219252726Srpaulo 2220252726Srpaulo discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0; 2221252726Srpaulo 2222252726Srpaulo if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST", 2223252726Srpaulo addr, sizeof(addr), discovered)) 2224252726Srpaulo return -1; 2225252726Srpaulo do { 2226252726Srpaulo os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr); 2227252726Srpaulo } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr), 2228252726Srpaulo discovered) == 0); 2229252726Srpaulo 2230252726Srpaulo return 0; 2231252726Srpaulo} 2232252726Srpaulo 2233252726Srpaulo 2234252726Srpaulostatic int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2235252726Srpaulo{ 2236252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv); 2237252726Srpaulo} 2238252726Srpaulo 2239252726Srpaulo 2240281806Srpaulostatic char ** wpa_cli_complete_p2p_set(const char *str, int pos) 2241281806Srpaulo{ 2242281806Srpaulo int arg = get_cmd_arg_num(str, pos); 2243281806Srpaulo const char *fields[] = { 2244281806Srpaulo "discoverability", 2245281806Srpaulo "managed", 2246281806Srpaulo "listen_channel", 2247281806Srpaulo "ssid_postfix", 2248281806Srpaulo "noa", 2249281806Srpaulo "ps", 2250281806Srpaulo "oppps", 2251281806Srpaulo "ctwindow", 2252281806Srpaulo "disabled", 2253281806Srpaulo "conc_pref", 2254281806Srpaulo "force_long_sd", 2255281806Srpaulo "peer_filter", 2256281806Srpaulo "cross_connect", 2257281806Srpaulo "go_apsd", 2258281806Srpaulo "client_apsd", 2259281806Srpaulo "disallow_freq", 2260281806Srpaulo "disc_int", 2261281806Srpaulo "per_sta_psk", 2262281806Srpaulo }; 2263281806Srpaulo int i, num_fields = ARRAY_SIZE(fields); 2264281806Srpaulo 2265281806Srpaulo if (arg == 1) { 2266281806Srpaulo char **res = os_calloc(num_fields + 1, sizeof(char *)); 2267281806Srpaulo if (res == NULL) 2268281806Srpaulo return NULL; 2269281806Srpaulo for (i = 0; i < num_fields; i++) { 2270281806Srpaulo res[i] = os_strdup(fields[i]); 2271281806Srpaulo if (res[i] == NULL) 2272281806Srpaulo return res; 2273281806Srpaulo } 2274281806Srpaulo return res; 2275281806Srpaulo } 2276281806Srpaulo 2277281806Srpaulo if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0) 2278281806Srpaulo return cli_txt_list_array(&p2p_peers); 2279281806Srpaulo 2280281806Srpaulo return NULL; 2281281806Srpaulo} 2282281806Srpaulo 2283281806Srpaulo 2284252726Srpaulostatic int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2285252726Srpaulo{ 2286252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_FLUSH"); 2287252726Srpaulo} 2288252726Srpaulo 2289252726Srpaulo 2290252726Srpaulostatic int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc, 2291252726Srpaulo char *argv[]) 2292252726Srpaulo{ 2293252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_CANCEL"); 2294252726Srpaulo} 2295252726Srpaulo 2296252726Srpaulo 2297252726Srpaulostatic int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc, 2298252726Srpaulo char *argv[]) 2299252726Srpaulo{ 2300252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv); 2301252726Srpaulo} 2302252726Srpaulo 2303252726Srpaulo 2304252726Srpaulostatic int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc, 2305252726Srpaulo char *argv[]) 2306252726Srpaulo{ 2307252726Srpaulo if (argc != 0 && argc != 2 && argc != 4) { 2308252726Srpaulo printf("Invalid P2P_PRESENCE_REQ command: needs two arguments " 2309252726Srpaulo "(preferred duration, interval; in microsecods).\n" 2310252726Srpaulo "Optional second pair can be used to provide " 2311252726Srpaulo "acceptable values.\n"); 2312252726Srpaulo return -1; 2313252726Srpaulo } 2314252726Srpaulo 2315252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv); 2316252726Srpaulo} 2317252726Srpaulo 2318252726Srpaulo 2319252726Srpaulostatic int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc, 2320252726Srpaulo char *argv[]) 2321252726Srpaulo{ 2322252726Srpaulo if (argc != 0 && argc != 2) { 2323252726Srpaulo printf("Invalid P2P_EXT_LISTEN command: needs two arguments " 2324252726Srpaulo "(availability period, availability interval; in " 2325252726Srpaulo "millisecods).\n" 2326252726Srpaulo "Extended Listen Timing can be cancelled with this " 2327252726Srpaulo "command when used without parameters.\n"); 2328252726Srpaulo return -1; 2329252726Srpaulo } 2330252726Srpaulo 2331252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv); 2332252726Srpaulo} 2333252726Srpaulo 2334281806Srpaulo 2335281806Srpaulostatic int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc, 2336281806Srpaulo char *argv[]) 2337281806Srpaulo{ 2338281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv); 2339281806Srpaulo} 2340281806Srpaulo 2341337817Scy 2342337817Scystatic int wpa_cli_cmd_vendor_elem_add(struct wpa_ctrl *ctrl, int argc, 2343337817Scy char *argv[]) 2344337817Scy{ 2345337817Scy return wpa_cli_cmd(ctrl, "VENDOR_ELEM_ADD", 2, argc, argv); 2346337817Scy} 2347337817Scy 2348337817Scy 2349337817Scystatic int wpa_cli_cmd_vendor_elem_get(struct wpa_ctrl *ctrl, int argc, 2350337817Scy char *argv[]) 2351337817Scy{ 2352337817Scy return wpa_cli_cmd(ctrl, "VENDOR_ELEM_GET", 1, argc, argv); 2353337817Scy} 2354337817Scy 2355337817Scy 2356337817Scystatic int wpa_cli_cmd_vendor_elem_remove(struct wpa_ctrl *ctrl, int argc, 2357337817Scy char *argv[]) 2358337817Scy{ 2359337817Scy return wpa_cli_cmd(ctrl, "VENDOR_ELEM_REMOVE", 2, argc, argv); 2360337817Scy} 2361337817Scy 2362252726Srpaulo#endif /* CONFIG_P2P */ 2363252726Srpaulo 2364252726Srpaulo#ifdef CONFIG_WIFI_DISPLAY 2365252726Srpaulo 2366252726Srpaulostatic int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc, 2367252726Srpaulo char *argv[]) 2368252726Srpaulo{ 2369252726Srpaulo char cmd[100]; 2370252726Srpaulo int res; 2371252726Srpaulo 2372252726Srpaulo if (argc != 1 && argc != 2) { 2373252726Srpaulo printf("Invalid WFD_SUBELEM_SET command: needs one or two " 2374252726Srpaulo "arguments (subelem, hexdump)\n"); 2375252726Srpaulo return -1; 2376252726Srpaulo } 2377252726Srpaulo 2378252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s", 2379252726Srpaulo argv[0], argc > 1 ? argv[1] : ""); 2380281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 2381252726Srpaulo return -1; 2382252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 2383252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2384252726Srpaulo} 2385252726Srpaulo 2386252726Srpaulo 2387252726Srpaulostatic int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc, 2388252726Srpaulo char *argv[]) 2389252726Srpaulo{ 2390252726Srpaulo char cmd[100]; 2391252726Srpaulo int res; 2392252726Srpaulo 2393214734Srpaulo if (argc != 1) { 2394252726Srpaulo printf("Invalid WFD_SUBELEM_GET command: needs one " 2395252726Srpaulo "argument (subelem)\n"); 2396214734Srpaulo return -1; 2397214734Srpaulo } 2398214734Srpaulo 2399252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s", 2400252726Srpaulo argv[0]); 2401281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 2402214734Srpaulo return -1; 2403252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 2404252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2405252726Srpaulo} 2406252726Srpaulo#endif /* CONFIG_WIFI_DISPLAY */ 2407252726Srpaulo 2408252726Srpaulo 2409252726Srpaulo#ifdef CONFIG_INTERWORKING 2410252726Srpaulostatic int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc, 2411252726Srpaulo char *argv[]) 2412252726Srpaulo{ 2413252726Srpaulo return wpa_ctrl_command(ctrl, "FETCH_ANQP"); 2414252726Srpaulo} 2415252726Srpaulo 2416252726Srpaulo 2417252726Srpaulostatic int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc, 2418252726Srpaulo char *argv[]) 2419252726Srpaulo{ 2420252726Srpaulo return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP"); 2421252726Srpaulo} 2422252726Srpaulo 2423252726Srpaulo 2424252726Srpaulostatic int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc, 2425252726Srpaulo char *argv[]) 2426252726Srpaulo{ 2427252726Srpaulo return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv); 2428252726Srpaulo} 2429252726Srpaulo 2430252726Srpaulo 2431252726Srpaulostatic int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc, 2432252726Srpaulo char *argv[]) 2433252726Srpaulo{ 2434252726Srpaulo return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv); 2435252726Srpaulo} 2436252726Srpaulo 2437252726Srpaulo 2438281806Srpaulostatic int wpa_cli_cmd_interworking_add_network(struct wpa_ctrl *ctrl, int argc, 2439281806Srpaulo char *argv[]) 2440281806Srpaulo{ 2441281806Srpaulo return wpa_cli_cmd(ctrl, "INTERWORKING_ADD_NETWORK", 1, argc, argv); 2442281806Srpaulo} 2443281806Srpaulo 2444281806Srpaulo 2445252726Srpaulostatic int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2446252726Srpaulo{ 2447252726Srpaulo return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv); 2448252726Srpaulo} 2449252726Srpaulo 2450252726Srpaulo 2451252726Srpaulostatic int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc, 2452252726Srpaulo char *argv[]) 2453252726Srpaulo{ 2454252726Srpaulo return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv); 2455252726Srpaulo} 2456252726Srpaulo 2457252726Srpaulo 2458252726Srpaulostatic int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc, 2459252726Srpaulo char *argv[]) 2460252726Srpaulo{ 2461252726Srpaulo return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv); 2462252726Srpaulo} 2463252726Srpaulo#endif /* CONFIG_INTERWORKING */ 2464252726Srpaulo 2465252726Srpaulo 2466252726Srpaulo#ifdef CONFIG_HS20 2467252726Srpaulo 2468252726Srpaulostatic int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc, 2469252726Srpaulo char *argv[]) 2470252726Srpaulo{ 2471252726Srpaulo return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv); 2472252726Srpaulo} 2473252726Srpaulo 2474252726Srpaulo 2475252726Srpaulostatic int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc, 2476252726Srpaulo char *argv[]) 2477252726Srpaulo{ 2478252726Srpaulo char cmd[512]; 2479252726Srpaulo 2480252726Srpaulo if (argc == 0) { 2481252726Srpaulo printf("Command needs one or two arguments (dst mac addr and " 2482252726Srpaulo "optional home realm)\n"); 2483252726Srpaulo return -1; 2484214734Srpaulo } 2485252726Srpaulo 2486252726Srpaulo if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST", 2487252726Srpaulo argc, argv) < 0) 2488252726Srpaulo return -1; 2489252726Srpaulo 2490214734Srpaulo return wpa_ctrl_command(ctrl, cmd); 2491214734Srpaulo} 2492214734Srpaulo 2493281806Srpaulo 2494281806Srpaulostatic int wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl *ctrl, int argc, 2495281806Srpaulo char *argv[]) 2496281806Srpaulo{ 2497281806Srpaulo char cmd[512]; 2498281806Srpaulo 2499281806Srpaulo if (argc < 2) { 2500281806Srpaulo printf("Command needs two arguments (dst mac addr and " 2501281806Srpaulo "icon name)\n"); 2502281806Srpaulo return -1; 2503281806Srpaulo } 2504281806Srpaulo 2505281806Srpaulo if (write_cmd(cmd, sizeof(cmd), "HS20_ICON_REQUEST", argc, argv) < 0) 2506281806Srpaulo return -1; 2507281806Srpaulo 2508281806Srpaulo return wpa_ctrl_command(ctrl, cmd); 2509281806Srpaulo} 2510281806Srpaulo 2511281806Srpaulo 2512281806Srpaulostatic int wpa_cli_cmd_fetch_osu(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2513281806Srpaulo{ 2514281806Srpaulo return wpa_ctrl_command(ctrl, "FETCH_OSU"); 2515281806Srpaulo} 2516281806Srpaulo 2517281806Srpaulo 2518281806Srpaulostatic int wpa_cli_cmd_cancel_fetch_osu(struct wpa_ctrl *ctrl, int argc, 2519281806Srpaulo char *argv[]) 2520281806Srpaulo{ 2521281806Srpaulo return wpa_ctrl_command(ctrl, "CANCEL_FETCH_OSU"); 2522281806Srpaulo} 2523281806Srpaulo 2524252726Srpaulo#endif /* CONFIG_HS20 */ 2525214734Srpaulo 2526252726Srpaulo 2527252726Srpaulostatic int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc, 2528252726Srpaulo char *argv[]) 2529252726Srpaulo{ 2530252726Srpaulo return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv); 2531252726Srpaulo} 2532252726Srpaulo 2533252726Srpaulo 2534252726Srpaulostatic int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc, 2535252726Srpaulo char *argv[]) 2536252726Srpaulo{ 2537252726Srpaulo return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv); 2538252726Srpaulo} 2539252726Srpaulo 2540252726Srpaulo 2541252726Srpaulostatic int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc, 2542252726Srpaulo char *argv[]) 2543252726Srpaulo{ 2544252726Srpaulo return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv); 2545252726Srpaulo} 2546252726Srpaulo 2547252726Srpaulo 2548252726Srpaulostatic int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc, 2549252726Srpaulo char *argv[]) 2550252726Srpaulo{ 2551252726Srpaulo return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv); 2552252726Srpaulo} 2553252726Srpaulo 2554252726Srpaulo 2555289549Srpaulostatic int wpa_cli_cmd_tdls_link_status(struct wpa_ctrl *ctrl, int argc, 2556289549Srpaulo char *argv[]) 2557289549Srpaulo{ 2558289549Srpaulo return wpa_cli_cmd(ctrl, "TDLS_LINK_STATUS", 1, argc, argv); 2559289549Srpaulo} 2560289549Srpaulo 2561289549Srpaulo 2562281806Srpaulostatic int wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl *ctrl, int argc, 2563281806Srpaulo char *argv[]) 2564281806Srpaulo{ 2565281806Srpaulo return wpa_cli_cmd(ctrl, "WMM_AC_ADDTS", 3, argc, argv); 2566281806Srpaulo} 2567281806Srpaulo 2568281806Srpaulo 2569281806Srpaulostatic int wpa_cli_cmd_wmm_ac_delts(struct wpa_ctrl *ctrl, int argc, 2570281806Srpaulo char *argv[]) 2571281806Srpaulo{ 2572281806Srpaulo return wpa_cli_cmd(ctrl, "WMM_AC_DELTS", 1, argc, argv); 2573281806Srpaulo} 2574281806Srpaulo 2575281806Srpaulo 2576281806Srpaulostatic int wpa_cli_cmd_wmm_ac_status(struct wpa_ctrl *ctrl, int argc, 2577281806Srpaulo char *argv[]) 2578281806Srpaulo{ 2579281806Srpaulo return wpa_ctrl_command(ctrl, "WMM_AC_STATUS"); 2580281806Srpaulo} 2581281806Srpaulo 2582281806Srpaulo 2583281806Srpaulostatic int wpa_cli_cmd_tdls_chan_switch(struct wpa_ctrl *ctrl, int argc, 2584281806Srpaulo char *argv[]) 2585281806Srpaulo{ 2586281806Srpaulo return wpa_cli_cmd(ctrl, "TDLS_CHAN_SWITCH", 2, argc, argv); 2587281806Srpaulo} 2588281806Srpaulo 2589281806Srpaulo 2590281806Srpaulostatic int wpa_cli_cmd_tdls_cancel_chan_switch(struct wpa_ctrl *ctrl, int argc, 2591281806Srpaulo char *argv[]) 2592281806Srpaulo{ 2593281806Srpaulo return wpa_cli_cmd(ctrl, "TDLS_CANCEL_CHAN_SWITCH", 1, argc, argv); 2594281806Srpaulo} 2595281806Srpaulo 2596281806Srpaulo 2597252726Srpaulostatic int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc, 2598252726Srpaulo char *argv[]) 2599252726Srpaulo{ 2600252726Srpaulo return wpa_ctrl_command(ctrl, "SIGNAL_POLL"); 2601252726Srpaulo} 2602252726Srpaulo 2603252726Srpaulo 2604337817Scystatic int wpa_cli_cmd_signal_monitor(struct wpa_ctrl *ctrl, int argc, 2605337817Scy char *argv[]) 2606337817Scy{ 2607337817Scy return wpa_cli_cmd(ctrl, "SIGNAL_MONITOR", 0, argc, argv); 2608337817Scy} 2609337817Scy 2610337817Scy 2611252726Srpaulostatic int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc, 2612252726Srpaulo char *argv[]) 2613252726Srpaulo{ 2614252726Srpaulo return wpa_ctrl_command(ctrl, "PKTCNT_POLL"); 2615252726Srpaulo} 2616252726Srpaulo 2617252726Srpaulo 2618252726Srpaulostatic int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc, 2619252726Srpaulo char *argv[]) 2620252726Srpaulo{ 2621252726Srpaulo return wpa_ctrl_command(ctrl, "REAUTHENTICATE"); 2622252726Srpaulo} 2623252726Srpaulo 2624252726Srpaulo 2625252726Srpaulo#ifdef CONFIG_AUTOSCAN 2626252726Srpaulo 2627252726Srpaulostatic int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2628252726Srpaulo{ 2629252726Srpaulo if (argc == 0) 2630252726Srpaulo return wpa_ctrl_command(ctrl, "AUTOSCAN "); 2631252726Srpaulo 2632252726Srpaulo return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv); 2633252726Srpaulo} 2634252726Srpaulo 2635252726Srpaulo#endif /* CONFIG_AUTOSCAN */ 2636252726Srpaulo 2637252726Srpaulo 2638252726Srpaulo#ifdef CONFIG_WNM 2639252726Srpaulo 2640252726Srpaulostatic int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2641252726Srpaulo{ 2642252726Srpaulo return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv); 2643252726Srpaulo} 2644252726Srpaulo 2645281806Srpaulo 2646281806Srpaulostatic int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2647281806Srpaulo{ 2648281806Srpaulo return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv); 2649281806Srpaulo} 2650281806Srpaulo 2651252726Srpaulo#endif /* CONFIG_WNM */ 2652252726Srpaulo 2653252726Srpaulo 2654252726Srpaulostatic int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2655252726Srpaulo{ 2656252726Srpaulo if (argc == 0) 2657252726Srpaulo return -1; 2658252726Srpaulo return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]); 2659252726Srpaulo} 2660252726Srpaulo 2661252726Srpaulo 2662281806Srpaulo#ifdef ANDROID 2663281806Srpaulostatic int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2664281806Srpaulo{ 2665281806Srpaulo return wpa_cli_cmd(ctrl, "DRIVER", 1, argc, argv); 2666281806Srpaulo} 2667281806Srpaulo#endif /* ANDROID */ 2668281806Srpaulo 2669281806Srpaulo 2670281806Srpaulostatic int wpa_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2671281806Srpaulo{ 2672281806Srpaulo return wpa_cli_cmd(ctrl, "VENDOR", 1, argc, argv); 2673281806Srpaulo} 2674281806Srpaulo 2675281806Srpaulo 2676281806Srpaulostatic int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2677281806Srpaulo{ 2678281806Srpaulo return wpa_ctrl_command(ctrl, "FLUSH"); 2679281806Srpaulo} 2680281806Srpaulo 2681281806Srpaulo 2682281806Srpaulostatic int wpa_cli_cmd_radio_work(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2683281806Srpaulo{ 2684281806Srpaulo return wpa_cli_cmd(ctrl, "RADIO_WORK", 1, argc, argv); 2685281806Srpaulo} 2686281806Srpaulo 2687281806Srpaulo 2688281806Srpaulostatic int wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl *ctrl, int argc, 2689281806Srpaulo char *argv[]) 2690281806Srpaulo{ 2691281806Srpaulo return wpa_cli_cmd(ctrl, "NEIGHBOR_REP_REQUEST", 0, argc, argv); 2692281806Srpaulo} 2693281806Srpaulo 2694281806Srpaulo 2695281806Srpaulostatic int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2696281806Srpaulo{ 2697281806Srpaulo return wpa_ctrl_command(ctrl, "ERP_FLUSH"); 2698281806Srpaulo} 2699281806Srpaulo 2700281806Srpaulo 2701281806Srpaulostatic int wpa_cli_cmd_mac_rand_scan(struct wpa_ctrl *ctrl, int argc, 2702281806Srpaulo char *argv[]) 2703281806Srpaulo{ 2704281806Srpaulo return wpa_cli_cmd(ctrl, "MAC_RAND_SCAN", 1, argc, argv); 2705281806Srpaulo} 2706281806Srpaulo 2707281806Srpaulo 2708289549Srpaulostatic int wpa_cli_cmd_get_pref_freq_list(struct wpa_ctrl *ctrl, int argc, 2709289549Srpaulo char *argv[]) 2710289549Srpaulo{ 2711289549Srpaulo return wpa_cli_cmd(ctrl, "GET_PREF_FREQ_LIST", 1, argc, argv); 2712289549Srpaulo} 2713289549Srpaulo 2714289549Srpaulo 2715337817Scystatic int wpa_cli_cmd_p2p_lo_start(struct wpa_ctrl *ctrl, int argc, 2716337817Scy char *argv[]) 2717337817Scy{ 2718337817Scy return wpa_cli_cmd(ctrl, "P2P_LO_START", 4, argc, argv); 2719337817Scy} 2720337817Scy 2721337817Scy 2722337817Scystatic int wpa_cli_cmd_p2p_lo_stop(struct wpa_ctrl *ctrl, int argc, 2723337817Scy char *argv[]) 2724337817Scy{ 2725337817Scy return wpa_cli_cmd(ctrl, "P2P_LO_STOP", 0, argc, argv); 2726337817Scy} 2727337817Scy 2728337817Scy 2729189251Ssamenum wpa_cli_cmd_flags { 2730189251Ssam cli_cmd_flag_none = 0x00, 2731189251Ssam cli_cmd_flag_sensitive = 0x01 2732189251Ssam}; 2733189251Ssam 2734189251Ssamstruct wpa_cli_cmd { 2735189251Ssam const char *cmd; 2736189251Ssam int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]); 2737252726Srpaulo char ** (*completion)(const char *str, int pos); 2738189251Ssam enum wpa_cli_cmd_flags flags; 2739189251Ssam const char *usage; 2740189251Ssam}; 2741189251Ssam 2742289549Srpaulostatic const struct wpa_cli_cmd wpa_cli_commands[] = { 2743252726Srpaulo { "status", wpa_cli_cmd_status, NULL, 2744189251Ssam cli_cmd_flag_none, 2745189251Ssam "[verbose] = get current WPA/EAPOL/EAP status" }, 2746252726Srpaulo { "ifname", wpa_cli_cmd_ifname, NULL, 2747189251Ssam cli_cmd_flag_none, 2748252726Srpaulo "= get current interface name" }, 2749252726Srpaulo { "ping", wpa_cli_cmd_ping, NULL, 2750252726Srpaulo cli_cmd_flag_none, 2751189251Ssam "= pings wpa_supplicant" }, 2752252726Srpaulo { "relog", wpa_cli_cmd_relog, NULL, 2753189251Ssam cli_cmd_flag_none, 2754252726Srpaulo "= re-open log-file (allow rolling logs)" }, 2755252726Srpaulo { "note", wpa_cli_cmd_note, NULL, 2756252726Srpaulo cli_cmd_flag_none, 2757252726Srpaulo "<text> = add a note to wpa_supplicant debug log" }, 2758252726Srpaulo { "mib", wpa_cli_cmd_mib, NULL, 2759252726Srpaulo cli_cmd_flag_none, 2760189251Ssam "= get MIB variables (dot1x, dot11)" }, 2761252726Srpaulo { "help", wpa_cli_cmd_help, wpa_cli_complete_help, 2762189251Ssam cli_cmd_flag_none, 2763252726Srpaulo "[command] = show usage help" }, 2764252726Srpaulo { "interface", wpa_cli_cmd_interface, NULL, 2765189251Ssam cli_cmd_flag_none, 2766189251Ssam "[ifname] = show interfaces/select interface" }, 2767252726Srpaulo { "level", wpa_cli_cmd_level, NULL, 2768189251Ssam cli_cmd_flag_none, 2769189251Ssam "<debug level> = change debug level" }, 2770252726Srpaulo { "license", wpa_cli_cmd_license, NULL, 2771189251Ssam cli_cmd_flag_none, 2772189251Ssam "= show full wpa_cli license" }, 2773252726Srpaulo { "quit", wpa_cli_cmd_quit, NULL, 2774189251Ssam cli_cmd_flag_none, 2775189251Ssam "= exit wpa_cli" }, 2776281806Srpaulo { "set", wpa_cli_cmd_set, wpa_cli_complete_set, 2777189251Ssam cli_cmd_flag_none, 2778189251Ssam "= set variables (shows list of variables when run without " 2779189251Ssam "arguments)" }, 2780281806Srpaulo { "dump", wpa_cli_cmd_dump, NULL, 2781281806Srpaulo cli_cmd_flag_none, 2782281806Srpaulo "= dump config variables" }, 2783289549Srpaulo { "get", wpa_cli_cmd_get, wpa_cli_complete_get, 2784189251Ssam cli_cmd_flag_none, 2785252726Srpaulo "<name> = get information" }, 2786337817Scy { "driver_flags", wpa_cli_cmd_driver_flags, NULL, 2787337817Scy cli_cmd_flag_none, 2788337817Scy "= list driver flags" }, 2789252726Srpaulo { "logon", wpa_cli_cmd_logon, NULL, 2790252726Srpaulo cli_cmd_flag_none, 2791189251Ssam "= IEEE 802.1X EAPOL state machine logon" }, 2792252726Srpaulo { "logoff", wpa_cli_cmd_logoff, NULL, 2793189251Ssam cli_cmd_flag_none, 2794189251Ssam "= IEEE 802.1X EAPOL state machine logoff" }, 2795252726Srpaulo { "pmksa", wpa_cli_cmd_pmksa, NULL, 2796189251Ssam cli_cmd_flag_none, 2797189251Ssam "= show PMKSA cache" }, 2798281806Srpaulo { "pmksa_flush", wpa_cli_cmd_pmksa_flush, NULL, 2799281806Srpaulo cli_cmd_flag_none, 2800281806Srpaulo "= flush PMKSA cache entries" }, 2801252726Srpaulo { "reassociate", wpa_cli_cmd_reassociate, NULL, 2802189251Ssam cli_cmd_flag_none, 2803189251Ssam "= force reassociation" }, 2804281806Srpaulo { "reattach", wpa_cli_cmd_reattach, NULL, 2805281806Srpaulo cli_cmd_flag_none, 2806281806Srpaulo "= force reassociation back to the same BSS" }, 2807252726Srpaulo { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss, 2808189251Ssam cli_cmd_flag_none, 2809189251Ssam "<BSSID> = force preauthentication" }, 2810252726Srpaulo { "identity", wpa_cli_cmd_identity, NULL, 2811189251Ssam cli_cmd_flag_none, 2812189251Ssam "<network id> <identity> = configure identity for an SSID" }, 2813252726Srpaulo { "password", wpa_cli_cmd_password, NULL, 2814189251Ssam cli_cmd_flag_sensitive, 2815189251Ssam "<network id> <password> = configure password for an SSID" }, 2816252726Srpaulo { "new_password", wpa_cli_cmd_new_password, NULL, 2817189251Ssam cli_cmd_flag_sensitive, 2818189251Ssam "<network id> <password> = change password for an SSID" }, 2819252726Srpaulo { "pin", wpa_cli_cmd_pin, NULL, 2820189251Ssam cli_cmd_flag_sensitive, 2821189251Ssam "<network id> <pin> = configure pin for an SSID" }, 2822252726Srpaulo { "otp", wpa_cli_cmd_otp, NULL, 2823189251Ssam cli_cmd_flag_sensitive, 2824189251Ssam "<network id> <password> = configure one-time-password for an SSID" 2825189251Ssam }, 2826252726Srpaulo { "passphrase", wpa_cli_cmd_passphrase, NULL, 2827189251Ssam cli_cmd_flag_sensitive, 2828189251Ssam "<network id> <passphrase> = configure private key passphrase\n" 2829189251Ssam " for an SSID" }, 2830281806Srpaulo { "sim", wpa_cli_cmd_sim, NULL, 2831281806Srpaulo cli_cmd_flag_sensitive, 2832281806Srpaulo "<network id> <pin> = report SIM operation result" }, 2833252726Srpaulo { "bssid", wpa_cli_cmd_bssid, NULL, 2834189251Ssam cli_cmd_flag_none, 2835189251Ssam "<network id> <BSSID> = set preferred BSSID for an SSID" }, 2836252726Srpaulo { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss, 2837189251Ssam cli_cmd_flag_none, 2838252726Srpaulo "<BSSID> = add a BSSID to the blacklist\n" 2839252726Srpaulo "blacklist clear = clear the blacklist\n" 2840252726Srpaulo "blacklist = display the blacklist" }, 2841252726Srpaulo { "log_level", wpa_cli_cmd_log_level, NULL, 2842252726Srpaulo cli_cmd_flag_none, 2843252726Srpaulo "<level> [<timestamp>] = update the log level/timestamp\n" 2844252726Srpaulo "log_level = display the current log level and log options" }, 2845252726Srpaulo { "list_networks", wpa_cli_cmd_list_networks, NULL, 2846252726Srpaulo cli_cmd_flag_none, 2847189251Ssam "= list configured networks" }, 2848289549Srpaulo { "select_network", wpa_cli_cmd_select_network, 2849289549Srpaulo wpa_cli_complete_network_id, 2850189251Ssam cli_cmd_flag_none, 2851189251Ssam "<network id> = select a network (disable others)" }, 2852289549Srpaulo { "enable_network", wpa_cli_cmd_enable_network, 2853289549Srpaulo wpa_cli_complete_network_id, 2854189251Ssam cli_cmd_flag_none, 2855189251Ssam "<network id> = enable a network" }, 2856289549Srpaulo { "disable_network", wpa_cli_cmd_disable_network, 2857289549Srpaulo wpa_cli_complete_network_id, 2858189251Ssam cli_cmd_flag_none, 2859189251Ssam "<network id> = disable a network" }, 2860252726Srpaulo { "add_network", wpa_cli_cmd_add_network, NULL, 2861189251Ssam cli_cmd_flag_none, 2862189251Ssam "= add a network" }, 2863289549Srpaulo { "remove_network", wpa_cli_cmd_remove_network, 2864289549Srpaulo wpa_cli_complete_network_id, 2865189251Ssam cli_cmd_flag_none, 2866189251Ssam "<network id> = remove a network" }, 2867289549Srpaulo { "set_network", wpa_cli_cmd_set_network, wpa_cli_complete_network, 2868189251Ssam cli_cmd_flag_sensitive, 2869189251Ssam "<network id> <variable> <value> = set network variables (shows\n" 2870189251Ssam " list of variables when run without arguments)" }, 2871289549Srpaulo { "get_network", wpa_cli_cmd_get_network, wpa_cli_complete_network, 2872189251Ssam cli_cmd_flag_none, 2873189251Ssam "<network id> <variable> = get network variables" }, 2874289549Srpaulo { "dup_network", wpa_cli_cmd_dup_network, wpa_cli_complete_dup_network, 2875281806Srpaulo cli_cmd_flag_none, 2876281806Srpaulo "<src network id> <dst network id> <variable> = duplicate network variables" 2877281806Srpaulo }, 2878252726Srpaulo { "list_creds", wpa_cli_cmd_list_creds, NULL, 2879189251Ssam cli_cmd_flag_none, 2880252726Srpaulo "= list configured credentials" }, 2881252726Srpaulo { "add_cred", wpa_cli_cmd_add_cred, NULL, 2882252726Srpaulo cli_cmd_flag_none, 2883252726Srpaulo "= add a credential" }, 2884252726Srpaulo { "remove_cred", wpa_cli_cmd_remove_cred, NULL, 2885252726Srpaulo cli_cmd_flag_none, 2886252726Srpaulo "<cred id> = remove a credential" }, 2887252726Srpaulo { "set_cred", wpa_cli_cmd_set_cred, NULL, 2888252726Srpaulo cli_cmd_flag_sensitive, 2889252726Srpaulo "<cred id> <variable> <value> = set credential variables" }, 2890281806Srpaulo { "get_cred", wpa_cli_cmd_get_cred, NULL, 2891281806Srpaulo cli_cmd_flag_none, 2892281806Srpaulo "<cred id> <variable> = get credential variables" }, 2893252726Srpaulo { "save_config", wpa_cli_cmd_save_config, NULL, 2894252726Srpaulo cli_cmd_flag_none, 2895189251Ssam "= save the current configuration" }, 2896252726Srpaulo { "disconnect", wpa_cli_cmd_disconnect, NULL, 2897189251Ssam cli_cmd_flag_none, 2898189251Ssam "= disconnect and wait for reassociate/reconnect command before\n" 2899189251Ssam " connecting" }, 2900252726Srpaulo { "reconnect", wpa_cli_cmd_reconnect, NULL, 2901189251Ssam cli_cmd_flag_none, 2902189251Ssam "= like reassociate, but only takes effect if already disconnected" 2903189251Ssam }, 2904252726Srpaulo { "scan", wpa_cli_cmd_scan, NULL, 2905189251Ssam cli_cmd_flag_none, 2906189251Ssam "= request new BSS scan" }, 2907252726Srpaulo { "scan_results", wpa_cli_cmd_scan_results, NULL, 2908189251Ssam cli_cmd_flag_none, 2909189251Ssam "= get latest scan results" }, 2910337817Scy { "abort_scan", wpa_cli_cmd_abort_scan, NULL, 2911337817Scy cli_cmd_flag_none, 2912337817Scy "= request ongoing scan to be aborted" }, 2913252726Srpaulo { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss, 2914189251Ssam cli_cmd_flag_none, 2915189251Ssam "<<idx> | <bssid>> = get detailed scan result info" }, 2916337817Scy { "get_capability", wpa_cli_cmd_get_capability, 2917337817Scy wpa_cli_complete_get_capability, cli_cmd_flag_none, 2918281806Srpaulo "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> " 2919289549Srpaulo "= get capabilities" }, 2920252726Srpaulo { "reconfigure", wpa_cli_cmd_reconfigure, NULL, 2921189251Ssam cli_cmd_flag_none, 2922189251Ssam "= force wpa_supplicant to re-read its configuration file" }, 2923252726Srpaulo { "terminate", wpa_cli_cmd_terminate, NULL, 2924189251Ssam cli_cmd_flag_none, 2925189251Ssam "= terminate wpa_supplicant" }, 2926252726Srpaulo { "interface_add", wpa_cli_cmd_interface_add, NULL, 2927189251Ssam cli_cmd_flag_none, 2928189251Ssam "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n" 2929337817Scy " <bridge_name> <create> <type> = adds new interface, all " 2930337817Scy "parameters but\n" 2931337817Scy " <ifname> are optional. Supported types are station ('sta') and " 2932337817Scy "AP ('ap')" }, 2933252726Srpaulo { "interface_remove", wpa_cli_cmd_interface_remove, NULL, 2934189251Ssam cli_cmd_flag_none, 2935189251Ssam "<ifname> = removes the interface" }, 2936252726Srpaulo { "interface_list", wpa_cli_cmd_interface_list, NULL, 2937189251Ssam cli_cmd_flag_none, 2938189251Ssam "= list available interfaces" }, 2939252726Srpaulo { "ap_scan", wpa_cli_cmd_ap_scan, NULL, 2940189251Ssam cli_cmd_flag_none, 2941189251Ssam "<value> = set ap_scan parameter" }, 2942252726Srpaulo { "scan_interval", wpa_cli_cmd_scan_interval, NULL, 2943189251Ssam cli_cmd_flag_none, 2944252726Srpaulo "<value> = set scan_interval parameter (in seconds)" }, 2945252726Srpaulo { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL, 2946252726Srpaulo cli_cmd_flag_none, 2947252726Srpaulo "<value> = set BSS expiration age parameter" }, 2948252726Srpaulo { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL, 2949252726Srpaulo cli_cmd_flag_none, 2950252726Srpaulo "<value> = set BSS expiration scan count parameter" }, 2951252726Srpaulo { "bss_flush", wpa_cli_cmd_bss_flush, NULL, 2952252726Srpaulo cli_cmd_flag_none, 2953252726Srpaulo "<value> = set BSS flush age (0 by default)" }, 2954252726Srpaulo { "stkstart", wpa_cli_cmd_stkstart, NULL, 2955252726Srpaulo cli_cmd_flag_none, 2956189251Ssam "<addr> = request STK negotiation with <addr>" }, 2957252726Srpaulo { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss, 2958189251Ssam cli_cmd_flag_none, 2959189251Ssam "<addr> = request over-the-DS FT with <addr>" }, 2960252726Srpaulo { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss, 2961189251Ssam cli_cmd_flag_none, 2962189251Ssam "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" }, 2963252726Srpaulo { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss, 2964189251Ssam cli_cmd_flag_sensitive, 2965189251Ssam "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not " 2966189251Ssam "hardcoded)" }, 2967252726Srpaulo { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL, 2968214734Srpaulo cli_cmd_flag_sensitive, 2969252726Srpaulo "<PIN> = verify PIN checksum" }, 2970252726Srpaulo { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none, 2971252726Srpaulo "Cancels the pending WPS operation" }, 2972252726Srpaulo#ifdef CONFIG_WPS_NFC 2973252726Srpaulo { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss, 2974252726Srpaulo cli_cmd_flag_none, 2975252726Srpaulo "[BSSID] = start Wi-Fi Protected Setup: NFC" }, 2976281806Srpaulo { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL, 2977281806Srpaulo cli_cmd_flag_none, 2978281806Srpaulo "<WPS|NDEF> = build configuration token" }, 2979252726Srpaulo { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL, 2980252726Srpaulo cli_cmd_flag_none, 2981252726Srpaulo "<WPS|NDEF> = create password token" }, 2982252726Srpaulo { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL, 2983189251Ssam cli_cmd_flag_sensitive, 2984252726Srpaulo "<hexdump of payload> = report read NFC tag with WPS data" }, 2985252726Srpaulo { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL, 2986252726Srpaulo cli_cmd_flag_none, 2987252726Srpaulo "<NDEF> <WPS> = create NFC handover request" }, 2988252726Srpaulo { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL, 2989252726Srpaulo cli_cmd_flag_none, 2990252726Srpaulo "<NDEF> <WPS> = create NFC handover select" }, 2991281806Srpaulo { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL, 2992252726Srpaulo cli_cmd_flag_none, 2993281806Srpaulo "<role> <type> <hexdump of req> <hexdump of sel> = report completed " 2994281806Srpaulo "NFC handover" }, 2995252726Srpaulo#endif /* CONFIG_WPS_NFC */ 2996252726Srpaulo { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss, 2997252726Srpaulo cli_cmd_flag_sensitive, 2998189251Ssam "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" }, 2999252726Srpaulo { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL, 3000252726Srpaulo cli_cmd_flag_sensitive, 3001252726Srpaulo "[params..] = enable/disable AP PIN" }, 3002252726Srpaulo { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL, 3003214734Srpaulo cli_cmd_flag_none, 3004252726Srpaulo "[IP address] = start Wi-Fi Protected Setup External Registrar" }, 3005252726Srpaulo { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL, 3006214734Srpaulo cli_cmd_flag_none, 3007214734Srpaulo "= stop Wi-Fi Protected Setup External Registrar" }, 3008252726Srpaulo { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL, 3009214734Srpaulo cli_cmd_flag_sensitive, 3010214734Srpaulo "<UUID> <PIN> = add an Enrollee PIN to External Registrar" }, 3011252726Srpaulo { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL, 3012214734Srpaulo cli_cmd_flag_none, 3013214734Srpaulo "<UUID> = accept an Enrollee PBC using External Registrar" }, 3014252726Srpaulo { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL, 3015214734Srpaulo cli_cmd_flag_sensitive, 3016214734Srpaulo "<UUID> <PIN> = learn AP configuration" }, 3017252726Srpaulo { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL, 3018214734Srpaulo cli_cmd_flag_none, 3019252726Srpaulo "<UUID> <network id> = set AP configuration for enrolling" }, 3020252726Srpaulo { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL, 3021252726Srpaulo cli_cmd_flag_sensitive, 3022252726Srpaulo "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" }, 3023252726Srpaulo#ifdef CONFIG_WPS_NFC 3024252726Srpaulo { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL, 3025252726Srpaulo cli_cmd_flag_none, 3026252726Srpaulo "<WPS/NDEF> <UUID> = build NFC configuration token" }, 3027252726Srpaulo#endif /* CONFIG_WPS_NFC */ 3028252726Srpaulo { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL, 3029252726Srpaulo cli_cmd_flag_none, 3030214734Srpaulo "<addr> = request RSN authentication with <addr> in IBSS" }, 3031214734Srpaulo#ifdef CONFIG_AP 3032252726Srpaulo { "sta", wpa_cli_cmd_sta, NULL, 3033214734Srpaulo cli_cmd_flag_none, 3034214734Srpaulo "<addr> = get information about an associated station (AP)" }, 3035252726Srpaulo { "all_sta", wpa_cli_cmd_all_sta, NULL, 3036214734Srpaulo cli_cmd_flag_none, 3037214734Srpaulo "= get information about all associated stations (AP)" }, 3038252726Srpaulo { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL, 3039252726Srpaulo cli_cmd_flag_none, 3040252726Srpaulo "<addr> = deauthenticate a station" }, 3041252726Srpaulo { "disassociate", wpa_cli_cmd_disassociate, NULL, 3042252726Srpaulo cli_cmd_flag_none, 3043252726Srpaulo "<addr> = disassociate a station" }, 3044281806Srpaulo { "chan_switch", wpa_cli_cmd_chanswitch, NULL, 3045281806Srpaulo cli_cmd_flag_none, 3046281806Srpaulo "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]" 3047281806Srpaulo " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]" 3048281806Srpaulo " = CSA parameters" }, 3049214734Srpaulo#endif /* CONFIG_AP */ 3050252726Srpaulo { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none, 3051214734Srpaulo "= notification of suspend/hibernate" }, 3052252726Srpaulo { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none, 3053214734Srpaulo "= notification of resume/thaw" }, 3054281806Srpaulo#ifdef CONFIG_TESTING_OPTIONS 3055252726Srpaulo { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none, 3056214734Srpaulo "= drop SA without deauth/disassoc (test command)" }, 3057281806Srpaulo#endif /* CONFIG_TESTING_OPTIONS */ 3058252726Srpaulo { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss, 3059214734Srpaulo cli_cmd_flag_none, 3060214734Srpaulo "<addr> = roam to the specified BSS" }, 3061281806Srpaulo#ifdef CONFIG_MESH 3062281806Srpaulo { "mesh_interface_add", wpa_cli_cmd_mesh_interface_add, NULL, 3063281806Srpaulo cli_cmd_flag_none, 3064281806Srpaulo "[ifname] = Create a new mesh interface" }, 3065281806Srpaulo { "mesh_group_add", wpa_cli_cmd_mesh_group_add, NULL, 3066281806Srpaulo cli_cmd_flag_none, 3067281806Srpaulo "<network id> = join a mesh network (disable others)" }, 3068281806Srpaulo { "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL, 3069281806Srpaulo cli_cmd_flag_none, 3070281806Srpaulo "<ifname> = Remove mesh group interface" }, 3071337817Scy { "mesh_peer_remove", wpa_cli_cmd_mesh_peer_remove, NULL, 3072337817Scy cli_cmd_flag_none, 3073337817Scy "<addr> = Remove a mesh peer" }, 3074337817Scy { "mesh_peer_add", wpa_cli_cmd_mesh_peer_add, NULL, 3075337817Scy cli_cmd_flag_none, 3076337817Scy "<addr> [duration=<seconds>] = Add a mesh peer" }, 3077281806Srpaulo#endif /* CONFIG_MESH */ 3078252726Srpaulo#ifdef CONFIG_P2P 3079252726Srpaulo { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find, 3080252726Srpaulo cli_cmd_flag_none, 3081252726Srpaulo "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" }, 3082252726Srpaulo { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none, 3083252726Srpaulo "= stop P2P Devices search" }, 3084281806Srpaulo { "p2p_asp_provision", wpa_cli_cmd_p2p_asp_provision, NULL, 3085281806Srpaulo cli_cmd_flag_none, 3086281806Srpaulo "<addr> adv_id=<adv_id> conncap=<conncap> [info=<infodata>] = provision with a P2P ASP Device" }, 3087281806Srpaulo { "p2p_asp_provision_resp", wpa_cli_cmd_p2p_asp_provision_resp, NULL, 3088281806Srpaulo cli_cmd_flag_none, 3089281806Srpaulo "<addr> adv_id=<adv_id> [role<conncap>] [info=<infodata>] = provision with a P2P ASP Device" }, 3090252726Srpaulo { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect, 3091252726Srpaulo cli_cmd_flag_none, 3092252726Srpaulo "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" }, 3093252726Srpaulo { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none, 3094252726Srpaulo "[timeout] = listen for P2P Devices for up-to timeout seconds" }, 3095252726Srpaulo { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, 3096252726Srpaulo wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none, 3097252726Srpaulo "<ifname> = remove P2P group interface (terminate group if GO)" }, 3098252726Srpaulo { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none, 3099252726Srpaulo "[ht40] = add a new P2P group (local end as GO)" }, 3100337817Scy { "p2p_group_member", wpa_cli_cmd_p2p_group_member, NULL, 3101337817Scy cli_cmd_flag_none, 3102337817Scy "<dev_addr> = Get peer interface address on local GO using peer Device Address" }, 3103252726Srpaulo { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, 3104252726Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3105252726Srpaulo "<addr> <method> = request provisioning discovery" }, 3106252726Srpaulo { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL, 3107252726Srpaulo cli_cmd_flag_none, 3108252726Srpaulo "= get the passphrase for a group (GO only)" }, 3109252726Srpaulo { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req, 3110252726Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3111252726Srpaulo "<addr> <TLVs> = schedule service discovery request" }, 3112252726Srpaulo { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req, 3113252726Srpaulo NULL, cli_cmd_flag_none, 3114252726Srpaulo "<id> = cancel pending service discovery request" }, 3115252726Srpaulo { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL, 3116252726Srpaulo cli_cmd_flag_none, 3117252726Srpaulo "<freq> <addr> <dialog token> <TLVs> = service discovery response" }, 3118252726Srpaulo { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL, 3119252726Srpaulo cli_cmd_flag_none, 3120252726Srpaulo "= indicate change in local services" }, 3121252726Srpaulo { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL, 3122252726Srpaulo cli_cmd_flag_none, 3123252726Srpaulo "<external> = set external processing of service discovery" }, 3124252726Srpaulo { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL, 3125252726Srpaulo cli_cmd_flag_none, 3126252726Srpaulo "= remove all stored service entries" }, 3127252726Srpaulo { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL, 3128252726Srpaulo cli_cmd_flag_none, 3129281806Srpaulo "<bonjour|upnp|asp> <query|version> <response|service> = add a local " 3130252726Srpaulo "service" }, 3131281806Srpaulo { "p2p_service_rep", wpa_cli_cmd_p2p_service_rep, NULL, 3132281806Srpaulo cli_cmd_flag_none, 3133281806Srpaulo "asp <auto> <adv_id> <svc_state> <svc_string> [<svc_info>] = replace " 3134281806Srpaulo "local ASP service" }, 3135252726Srpaulo { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL, 3136252726Srpaulo cli_cmd_flag_none, 3137252726Srpaulo "<bonjour|upnp> <query|version> [|service] = remove a local " 3138252726Srpaulo "service" }, 3139252726Srpaulo { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer, 3140252726Srpaulo cli_cmd_flag_none, 3141252726Srpaulo "<addr> = reject connection attempts from a specific peer" }, 3142252726Srpaulo { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL, 3143252726Srpaulo cli_cmd_flag_none, 3144252726Srpaulo "<cmd> [peer=addr] = invite peer" }, 3145252726Srpaulo { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none, 3146252726Srpaulo "[discovered] = list known (optionally, only fully discovered) P2P " 3147252726Srpaulo "peers" }, 3148252726Srpaulo { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer, 3149252726Srpaulo cli_cmd_flag_none, 3150252726Srpaulo "<address> = show information about known P2P peer" }, 3151281806Srpaulo { "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set, 3152281806Srpaulo cli_cmd_flag_none, 3153252726Srpaulo "<field> <value> = set a P2P parameter" }, 3154252726Srpaulo { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none, 3155252726Srpaulo "= flush P2P state" }, 3156252726Srpaulo { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none, 3157252726Srpaulo "= cancel P2P group formation" }, 3158252726Srpaulo { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, 3159252726Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3160252726Srpaulo "<address> = unauthorize a peer" }, 3161252726Srpaulo { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL, 3162252726Srpaulo cli_cmd_flag_none, 3163252726Srpaulo "[<duration> <interval>] [<duration> <interval>] = request GO " 3164252726Srpaulo "presence" }, 3165252726Srpaulo { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL, 3166252726Srpaulo cli_cmd_flag_none, 3167252726Srpaulo "[<period> <interval>] = set extended listen timing" }, 3168281806Srpaulo { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client, 3169281806Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3170281806Srpaulo "<address|iface=address> = remove a peer from all groups" }, 3171337817Scy { "vendor_elem_add", wpa_cli_cmd_vendor_elem_add, NULL, 3172337817Scy cli_cmd_flag_none, 3173337817Scy "<frame id> <hexdump of elem(s)> = add vendor specific IEs to frame(s)\n" 3174337817Scy VENDOR_ELEM_FRAME_ID }, 3175337817Scy { "vendor_elem_get", wpa_cli_cmd_vendor_elem_get, NULL, 3176337817Scy cli_cmd_flag_none, 3177337817Scy "<frame id> = get vendor specific IE(s) to frame(s)\n" 3178337817Scy VENDOR_ELEM_FRAME_ID }, 3179337817Scy { "vendor_elem_remove", wpa_cli_cmd_vendor_elem_remove, NULL, 3180337817Scy cli_cmd_flag_none, 3181337817Scy "<frame id> <hexdump of elem(s)> = remove vendor specific IE(s) in frame(s)\n" 3182337817Scy VENDOR_ELEM_FRAME_ID }, 3183252726Srpaulo#endif /* CONFIG_P2P */ 3184252726Srpaulo#ifdef CONFIG_WIFI_DISPLAY 3185252726Srpaulo { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL, 3186252726Srpaulo cli_cmd_flag_none, 3187252726Srpaulo "<subelem> [contents] = set Wi-Fi Display subelement" }, 3188252726Srpaulo { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL, 3189252726Srpaulo cli_cmd_flag_none, 3190252726Srpaulo "<subelem> = get Wi-Fi Display subelement" }, 3191252726Srpaulo#endif /* CONFIG_WIFI_DISPLAY */ 3192252726Srpaulo#ifdef CONFIG_INTERWORKING 3193252726Srpaulo { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none, 3194252726Srpaulo "= fetch ANQP information for all APs" }, 3195252726Srpaulo { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL, 3196252726Srpaulo cli_cmd_flag_none, 3197252726Srpaulo "= stop fetch_anqp operation" }, 3198252726Srpaulo { "interworking_select", wpa_cli_cmd_interworking_select, NULL, 3199252726Srpaulo cli_cmd_flag_none, 3200252726Srpaulo "[auto] = perform Interworking network selection" }, 3201252726Srpaulo { "interworking_connect", wpa_cli_cmd_interworking_connect, 3202252726Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3203252726Srpaulo "<BSSID> = connect using Interworking credentials" }, 3204281806Srpaulo { "interworking_add_network", wpa_cli_cmd_interworking_add_network, 3205281806Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3206281806Srpaulo "<BSSID> = connect using Interworking credentials" }, 3207252726Srpaulo { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss, 3208252726Srpaulo cli_cmd_flag_none, 3209252726Srpaulo "<addr> <info id>[,<info id>]... = request ANQP information" }, 3210252726Srpaulo { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss, 3211252726Srpaulo cli_cmd_flag_none, 3212252726Srpaulo "<addr> <AdvProtoID> [QueryReq] = GAS request" }, 3213252726Srpaulo { "gas_response_get", wpa_cli_cmd_gas_response_get, 3214252726Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3215252726Srpaulo "<addr> <dialog token> [start,len] = Fetch last GAS response" }, 3216252726Srpaulo#endif /* CONFIG_INTERWORKING */ 3217252726Srpaulo#ifdef CONFIG_HS20 3218252726Srpaulo { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss, 3219252726Srpaulo cli_cmd_flag_none, 3220252726Srpaulo "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information" 3221252726Srpaulo }, 3222252726Srpaulo { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list, 3223252726Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3224252726Srpaulo "<addr> <home realm> = get HS20 nai home realm list" }, 3225281806Srpaulo { "hs20_icon_request", wpa_cli_cmd_hs20_icon_request, 3226281806Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3227281806Srpaulo "<addr> <icon name> = get Hotspot 2.0 OSU icon" }, 3228281806Srpaulo { "fetch_osu", wpa_cli_cmd_fetch_osu, NULL, cli_cmd_flag_none, 3229281806Srpaulo "= fetch OSU provider information from all APs" }, 3230281806Srpaulo { "cancel_fetch_osu", wpa_cli_cmd_cancel_fetch_osu, NULL, 3231281806Srpaulo cli_cmd_flag_none, 3232281806Srpaulo "= cancel fetch_osu command" }, 3233252726Srpaulo#endif /* CONFIG_HS20 */ 3234252726Srpaulo { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL, 3235252726Srpaulo cli_cmd_flag_none, 3236252726Srpaulo "<0/1> = disable/enable automatic reconnection" }, 3237252726Srpaulo { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL, 3238252726Srpaulo cli_cmd_flag_none, 3239252726Srpaulo "<addr> = request TDLS discovery with <addr>" }, 3240252726Srpaulo { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL, 3241252726Srpaulo cli_cmd_flag_none, 3242252726Srpaulo "<addr> = request TDLS setup with <addr>" }, 3243252726Srpaulo { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL, 3244252726Srpaulo cli_cmd_flag_none, 3245252726Srpaulo "<addr> = tear down TDLS with <addr>" }, 3246289549Srpaulo { "tdls_link_status", wpa_cli_cmd_tdls_link_status, NULL, 3247289549Srpaulo cli_cmd_flag_none, 3248289549Srpaulo "<addr> = TDLS link status with <addr>" }, 3249281806Srpaulo { "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL, 3250281806Srpaulo cli_cmd_flag_none, 3251281806Srpaulo "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] " 3252281806Srpaulo "[mean_data_rate=#] [min_phy_rate=#] [sba=#] [fixed_nominal_msdu] " 3253281806Srpaulo "= add WMM-AC traffic stream" }, 3254281806Srpaulo { "wmm_ac_delts", wpa_cli_cmd_wmm_ac_delts, NULL, 3255281806Srpaulo cli_cmd_flag_none, 3256281806Srpaulo "<tsid> = delete WMM-AC traffic stream" }, 3257281806Srpaulo { "wmm_ac_status", wpa_cli_cmd_wmm_ac_status, NULL, 3258281806Srpaulo cli_cmd_flag_none, 3259281806Srpaulo "= show status for Wireless Multi-Media Admission-Control" }, 3260281806Srpaulo { "tdls_chan_switch", wpa_cli_cmd_tdls_chan_switch, NULL, 3261281806Srpaulo cli_cmd_flag_none, 3262281806Srpaulo "<addr> <oper class> <freq> [sec_channel_offset=] [center_freq1=] " 3263281806Srpaulo "[center_freq2=] [bandwidth=] [ht|vht] = enable channel switching " 3264281806Srpaulo "with TDLS peer" }, 3265281806Srpaulo { "tdls_cancel_chan_switch", wpa_cli_cmd_tdls_cancel_chan_switch, NULL, 3266281806Srpaulo cli_cmd_flag_none, 3267281806Srpaulo "<addr> = disable channel switching with TDLS peer <addr>" }, 3268252726Srpaulo { "signal_poll", wpa_cli_cmd_signal_poll, NULL, 3269252726Srpaulo cli_cmd_flag_none, 3270252726Srpaulo "= get signal parameters" }, 3271337817Scy { "signal_monitor", wpa_cli_cmd_signal_monitor, NULL, 3272337817Scy cli_cmd_flag_none, 3273337817Scy "= set signal monitor parameters" }, 3274252726Srpaulo { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL, 3275252726Srpaulo cli_cmd_flag_none, 3276252726Srpaulo "= get TX/RX packet counters" }, 3277252726Srpaulo { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL, 3278252726Srpaulo cli_cmd_flag_none, 3279252726Srpaulo "= trigger IEEE 802.1X/EAPOL reauthentication" }, 3280252726Srpaulo#ifdef CONFIG_AUTOSCAN 3281252726Srpaulo { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none, 3282252726Srpaulo "[params] = Set or unset (if none) autoscan parameters" }, 3283252726Srpaulo#endif /* CONFIG_AUTOSCAN */ 3284252726Srpaulo#ifdef CONFIG_WNM 3285252726Srpaulo { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none, 3286252726Srpaulo "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" }, 3287281806Srpaulo { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none, 3288337817Scy "<query reason> [list] = Send BSS Transition Management Query" }, 3289252726Srpaulo#endif /* CONFIG_WNM */ 3290252726Srpaulo { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive, 3291252726Srpaulo "<params..> = Sent unprocessed command" }, 3292281806Srpaulo { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none, 3293281806Srpaulo "= flush wpa_supplicant state" }, 3294281806Srpaulo#ifdef ANDROID 3295281806Srpaulo { "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none, 3296281806Srpaulo "<command> = driver private commands" }, 3297281806Srpaulo#endif /* ANDROID */ 3298281806Srpaulo { "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none, 3299281806Srpaulo "= radio_work <show/add/done>" }, 3300281806Srpaulo { "vendor", wpa_cli_cmd_vendor, NULL, cli_cmd_flag_none, 3301281806Srpaulo "<vendor id> <command id> [<hex formatted command argument>] = Send vendor command" 3302281806Srpaulo }, 3303281806Srpaulo { "neighbor_rep_request", 3304281806Srpaulo wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none, 3305337817Scy "[ssid=<SSID>] [lci] [civic] = Trigger request to AP for neighboring AP report (with optional given SSID in hex or enclosed in double quotes, default: current SSID; with optional LCI and location civic request)" 3306281806Srpaulo }, 3307281806Srpaulo { "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none, 3308281806Srpaulo "= flush ERP keys" }, 3309281806Srpaulo { "mac_rand_scan", 3310281806Srpaulo wpa_cli_cmd_mac_rand_scan, NULL, cli_cmd_flag_none, 3311281806Srpaulo "<scan|sched|pno|all> enable=<0/1> [addr=mac-address " 3312281806Srpaulo "mask=mac-address-mask] = scan MAC randomization" 3313281806Srpaulo }, 3314289549Srpaulo { "get_pref_freq_list", wpa_cli_cmd_get_pref_freq_list, NULL, 3315289549Srpaulo cli_cmd_flag_none, 3316289549Srpaulo "<interface type> = retrieve preferred freq list for the specified interface type" }, 3317337817Scy { "p2p_lo_start", wpa_cli_cmd_p2p_lo_start, NULL, 3318337817Scy cli_cmd_flag_none, 3319337817Scy "<freq> <period> <interval> <count> = start P2P listen offload" }, 3320337817Scy { "p2p_lo_stop", wpa_cli_cmd_p2p_lo_stop, NULL, 3321337817Scy cli_cmd_flag_none, 3322337817Scy "= stop P2P listen offload" }, 3323252726Srpaulo { NULL, NULL, NULL, cli_cmd_flag_none, NULL } 3324189251Ssam}; 3325189251Ssam 3326189251Ssam 3327189251Ssam/* 3328189251Ssam * Prints command usage, lines are padded with the specified string. 3329189251Ssam */ 3330289549Srpaulostatic void print_cmd_help(const struct wpa_cli_cmd *cmd, const char *pad) 3331189251Ssam{ 3332189251Ssam char c; 3333189251Ssam size_t n; 3334189251Ssam 3335189251Ssam printf("%s%s ", pad, cmd->cmd); 3336189251Ssam for (n = 0; (c = cmd->usage[n]); n++) { 3337189251Ssam printf("%c", c); 3338189251Ssam if (c == '\n') 3339189251Ssam printf("%s", pad); 3340189251Ssam } 3341189251Ssam printf("\n"); 3342189251Ssam} 3343189251Ssam 3344189251Ssam 3345252726Srpaulostatic void print_help(const char *cmd) 3346189251Ssam{ 3347189251Ssam int n; 3348189251Ssam printf("commands:\n"); 3349252726Srpaulo for (n = 0; wpa_cli_commands[n].cmd; n++) { 3350252726Srpaulo if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd)) 3351252726Srpaulo print_cmd_help(&wpa_cli_commands[n], " "); 3352252726Srpaulo } 3353189251Ssam} 3354189251Ssam 3355189251Ssam 3356252726Srpaulostatic int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd) 3357189251Ssam{ 3358189251Ssam const char *c, *delim; 3359189251Ssam int n; 3360189251Ssam size_t len; 3361189251Ssam 3362189251Ssam delim = os_strchr(cmd, ' '); 3363189251Ssam if (delim) 3364189251Ssam len = delim - cmd; 3365189251Ssam else 3366189251Ssam len = os_strlen(cmd); 3367189251Ssam 3368189251Ssam for (n = 0; (c = wpa_cli_commands[n].cmd); n++) { 3369189251Ssam if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c)) 3370189251Ssam return (wpa_cli_commands[n].flags & 3371189251Ssam cli_cmd_flag_sensitive); 3372189251Ssam } 3373189251Ssam return 0; 3374189251Ssam} 3375189251Ssam 3376189251Ssam 3377252726Srpaulostatic char ** wpa_list_cmd_list(void) 3378252726Srpaulo{ 3379252726Srpaulo char **res; 3380252726Srpaulo int i, count; 3381281806Srpaulo struct cli_txt_entry *e; 3382252726Srpaulo 3383281806Srpaulo count = ARRAY_SIZE(wpa_cli_commands); 3384281806Srpaulo count += dl_list_len(&p2p_groups); 3385281806Srpaulo count += dl_list_len(&ifnames); 3386281806Srpaulo res = os_calloc(count + 1, sizeof(char *)); 3387252726Srpaulo if (res == NULL) 3388252726Srpaulo return NULL; 3389252726Srpaulo 3390252726Srpaulo for (i = 0; wpa_cli_commands[i].cmd; i++) { 3391252726Srpaulo res[i] = os_strdup(wpa_cli_commands[i].cmd); 3392252726Srpaulo if (res[i] == NULL) 3393252726Srpaulo break; 3394252726Srpaulo } 3395252726Srpaulo 3396281806Srpaulo dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) { 3397281806Srpaulo size_t len = 8 + os_strlen(e->txt); 3398281806Srpaulo res[i] = os_malloc(len); 3399281806Srpaulo if (res[i] == NULL) 3400281806Srpaulo break; 3401281806Srpaulo os_snprintf(res[i], len, "ifname=%s", e->txt); 3402281806Srpaulo i++; 3403281806Srpaulo } 3404281806Srpaulo 3405281806Srpaulo dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) { 3406281806Srpaulo res[i] = os_strdup(e->txt); 3407281806Srpaulo if (res[i] == NULL) 3408281806Srpaulo break; 3409281806Srpaulo i++; 3410281806Srpaulo } 3411281806Srpaulo 3412252726Srpaulo return res; 3413252726Srpaulo} 3414252726Srpaulo 3415252726Srpaulo 3416252726Srpaulostatic char ** wpa_cli_cmd_completion(const char *cmd, const char *str, 3417252726Srpaulo int pos) 3418252726Srpaulo{ 3419252726Srpaulo int i; 3420252726Srpaulo 3421252726Srpaulo for (i = 0; wpa_cli_commands[i].cmd; i++) { 3422252726Srpaulo if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) { 3423252726Srpaulo if (wpa_cli_commands[i].completion) 3424252726Srpaulo return wpa_cli_commands[i].completion(str, 3425252726Srpaulo pos); 3426252726Srpaulo edit_clear_line(); 3427252726Srpaulo printf("\r%s\n", wpa_cli_commands[i].usage); 3428252726Srpaulo edit_redraw(); 3429252726Srpaulo break; 3430252726Srpaulo } 3431252726Srpaulo } 3432252726Srpaulo 3433252726Srpaulo return NULL; 3434252726Srpaulo} 3435252726Srpaulo 3436252726Srpaulo 3437252726Srpaulostatic char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos) 3438252726Srpaulo{ 3439252726Srpaulo char **res; 3440252726Srpaulo const char *end; 3441252726Srpaulo char *cmd; 3442252726Srpaulo 3443281806Srpaulo if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) { 3444281806Srpaulo end = os_strchr(str, ' '); 3445281806Srpaulo if (end && pos > end - str) { 3446281806Srpaulo pos -= end - str + 1; 3447281806Srpaulo str = end + 1; 3448281806Srpaulo } 3449281806Srpaulo } 3450281806Srpaulo 3451252726Srpaulo end = os_strchr(str, ' '); 3452252726Srpaulo if (end == NULL || str + pos < end) 3453252726Srpaulo return wpa_list_cmd_list(); 3454252726Srpaulo 3455252726Srpaulo cmd = os_malloc(pos + 1); 3456252726Srpaulo if (cmd == NULL) 3457252726Srpaulo return NULL; 3458252726Srpaulo os_memcpy(cmd, str, pos); 3459252726Srpaulo cmd[end - str] = '\0'; 3460252726Srpaulo res = wpa_cli_cmd_completion(cmd, str, pos); 3461252726Srpaulo os_free(cmd); 3462252726Srpaulo return res; 3463252726Srpaulo} 3464252726Srpaulo 3465252726Srpaulo 3466189251Ssamstatic int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[]) 3467189251Ssam{ 3468289549Srpaulo const struct wpa_cli_cmd *cmd, *match = NULL; 3469189251Ssam int count; 3470189251Ssam int ret = 0; 3471189251Ssam 3472281806Srpaulo if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) { 3473281806Srpaulo ifname_prefix = argv[0] + 7; 3474281806Srpaulo argv = &argv[1]; 3475281806Srpaulo argc--; 3476281806Srpaulo } else 3477281806Srpaulo ifname_prefix = NULL; 3478281806Srpaulo 3479281806Srpaulo if (argc == 0) 3480281806Srpaulo return -1; 3481281806Srpaulo 3482189251Ssam count = 0; 3483189251Ssam cmd = wpa_cli_commands; 3484189251Ssam while (cmd->cmd) { 3485189251Ssam if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0) 3486189251Ssam { 3487189251Ssam match = cmd; 3488189251Ssam if (os_strcasecmp(cmd->cmd, argv[0]) == 0) { 3489189251Ssam /* we have an exact match */ 3490189251Ssam count = 1; 3491189251Ssam break; 3492189251Ssam } 3493189251Ssam count++; 3494189251Ssam } 3495189251Ssam cmd++; 3496189251Ssam } 3497189251Ssam 3498189251Ssam if (count > 1) { 3499189251Ssam printf("Ambiguous command '%s'; possible commands:", argv[0]); 3500189251Ssam cmd = wpa_cli_commands; 3501189251Ssam while (cmd->cmd) { 3502189251Ssam if (os_strncasecmp(cmd->cmd, argv[0], 3503189251Ssam os_strlen(argv[0])) == 0) { 3504189251Ssam printf(" %s", cmd->cmd); 3505189251Ssam } 3506189251Ssam cmd++; 3507189251Ssam } 3508189251Ssam printf("\n"); 3509189251Ssam ret = 1; 3510189251Ssam } else if (count == 0) { 3511189251Ssam printf("Unknown command '%s'\n", argv[0]); 3512189251Ssam ret = 1; 3513189251Ssam } else { 3514189251Ssam ret = match->handler(ctrl, argc - 1, &argv[1]); 3515189251Ssam } 3516189251Ssam 3517189251Ssam return ret; 3518189251Ssam} 3519189251Ssam 3520189251Ssam 3521189251Ssamstatic int wpa_cli_exec(const char *program, const char *arg1, 3522189251Ssam const char *arg2) 3523189251Ssam{ 3524281806Srpaulo char *arg; 3525189251Ssam size_t len; 3526189251Ssam int res; 3527189251Ssam 3528337817Scy /* If no interface is specified, set the global */ 3529337817Scy if (!arg1) 3530337817Scy arg1 = "global"; 3531337817Scy 3532281806Srpaulo len = os_strlen(arg1) + os_strlen(arg2) + 2; 3533281806Srpaulo arg = os_malloc(len); 3534281806Srpaulo if (arg == NULL) 3535189251Ssam return -1; 3536281806Srpaulo os_snprintf(arg, len, "%s %s", arg1, arg2); 3537281806Srpaulo res = os_exec(program, arg, 1); 3538281806Srpaulo os_free(arg); 3539189251Ssam 3540281806Srpaulo return res; 3541189251Ssam} 3542189251Ssam 3543189251Ssam 3544189251Ssamstatic void wpa_cli_action_process(const char *msg) 3545189251Ssam{ 3546189251Ssam const char *pos; 3547189251Ssam char *copy = NULL, *id, *pos2; 3548281806Srpaulo const char *ifname = ctrl_ifname; 3549281806Srpaulo char ifname_buf[100]; 3550189251Ssam 3551289549Srpaulo if (eloop_terminated()) 3552289549Srpaulo return; 3553289549Srpaulo 3554189251Ssam pos = msg; 3555281806Srpaulo if (os_strncmp(pos, "IFNAME=", 7) == 0) { 3556281806Srpaulo const char *end; 3557281806Srpaulo end = os_strchr(pos + 7, ' '); 3558281806Srpaulo if (end && (unsigned int) (end - pos) < sizeof(ifname_buf)) { 3559281806Srpaulo pos += 7; 3560281806Srpaulo os_memcpy(ifname_buf, pos, end - pos); 3561281806Srpaulo ifname_buf[end - pos] = '\0'; 3562281806Srpaulo ifname = ifname_buf; 3563281806Srpaulo pos = end + 1; 3564281806Srpaulo } 3565281806Srpaulo } 3566189251Ssam if (*pos == '<') { 3567281806Srpaulo const char *prev = pos; 3568189251Ssam /* skip priority */ 3569189251Ssam pos = os_strchr(pos, '>'); 3570189251Ssam if (pos) 3571189251Ssam pos++; 3572189251Ssam else 3573281806Srpaulo pos = prev; 3574189251Ssam } 3575189251Ssam 3576337817Scy if (str_starts(pos, WPA_EVENT_CONNECTED)) { 3577189251Ssam int new_id = -1; 3578189251Ssam os_unsetenv("WPA_ID"); 3579189251Ssam os_unsetenv("WPA_ID_STR"); 3580189251Ssam os_unsetenv("WPA_CTRL_DIR"); 3581189251Ssam 3582189251Ssam pos = os_strstr(pos, "[id="); 3583189251Ssam if (pos) 3584189251Ssam copy = os_strdup(pos + 4); 3585189251Ssam 3586189251Ssam if (copy) { 3587189251Ssam pos2 = id = copy; 3588189251Ssam while (*pos2 && *pos2 != ' ') 3589189251Ssam pos2++; 3590189251Ssam *pos2++ = '\0'; 3591189251Ssam new_id = atoi(id); 3592189251Ssam os_setenv("WPA_ID", id, 1); 3593189251Ssam while (*pos2 && *pos2 != '=') 3594189251Ssam pos2++; 3595189251Ssam if (*pos2 == '=') 3596189251Ssam pos2++; 3597189251Ssam id = pos2; 3598189251Ssam while (*pos2 && *pos2 != ']') 3599189251Ssam pos2++; 3600189251Ssam *pos2 = '\0'; 3601189251Ssam os_setenv("WPA_ID_STR", id, 1); 3602189251Ssam os_free(copy); 3603189251Ssam } 3604189251Ssam 3605189251Ssam os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1); 3606189251Ssam 3607281806Srpaulo if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) { 3608189251Ssam wpa_cli_connected = 1; 3609189251Ssam wpa_cli_last_id = new_id; 3610281806Srpaulo wpa_cli_exec(action_file, ifname, "CONNECTED"); 3611189251Ssam } 3612337817Scy } else if (str_starts(pos, WPA_EVENT_DISCONNECTED)) { 3613189251Ssam if (wpa_cli_connected) { 3614189251Ssam wpa_cli_connected = 0; 3615281806Srpaulo wpa_cli_exec(action_file, ifname, "DISCONNECTED"); 3616189251Ssam } 3617337817Scy } else if (str_starts(pos, AP_EVENT_ENABLED)) { 3618281806Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 3619337817Scy } else if (str_starts(pos, AP_EVENT_DISABLED)) { 3620281806Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 3621337817Scy } else if (str_starts(pos, MESH_GROUP_STARTED)) { 3622281806Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 3623337817Scy } else if (str_starts(pos, MESH_GROUP_REMOVED)) { 3624281806Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 3625337817Scy } else if (str_starts(pos, MESH_PEER_CONNECTED)) { 3626337817Scy wpa_cli_exec(action_file, ctrl_ifname, pos); 3627337817Scy } else if (str_starts(pos, MESH_PEER_DISCONNECTED)) { 3628337817Scy wpa_cli_exec(action_file, ctrl_ifname, pos); 3629337817Scy } else if (str_starts(pos, P2P_EVENT_GROUP_STARTED)) { 3630281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3631337817Scy } else if (str_starts(pos, P2P_EVENT_GROUP_REMOVED)) { 3632281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3633337817Scy } else if (str_starts(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) { 3634281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3635337817Scy } else if (str_starts(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) { 3636281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3637337817Scy } else if (str_starts(pos, P2P_EVENT_GO_NEG_FAILURE)) { 3638281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3639337817Scy } else if (str_starts(pos, WPS_EVENT_SUCCESS)) { 3640281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3641337817Scy } else if (str_starts(pos, WPS_EVENT_FAIL)) { 3642281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3643337817Scy } else if (str_starts(pos, AP_STA_CONNECTED)) { 3644281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3645337817Scy } else if (str_starts(pos, AP_STA_DISCONNECTED)) { 3646281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3647337817Scy } else if (str_starts(pos, ESS_DISASSOC_IMMINENT)) { 3648281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3649337817Scy } else if (str_starts(pos, HS20_SUBSCRIPTION_REMEDIATION)) { 3650281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3651337817Scy } else if (str_starts(pos, HS20_DEAUTH_IMMINENT_NOTICE)) { 3652281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3653337817Scy } else if (str_starts(pos, WPA_EVENT_TERMINATING)) { 3654189251Ssam printf("wpa_supplicant is terminating - stop monitoring\n"); 3655189251Ssam wpa_cli_quit = 1; 3656189251Ssam } 3657189251Ssam} 3658189251Ssam 3659189251Ssam 3660189251Ssam#ifndef CONFIG_ANSI_C_EXTRA 3661189251Ssamstatic void wpa_cli_action_cb(char *msg, size_t len) 3662189251Ssam{ 3663189251Ssam wpa_cli_action_process(msg); 3664189251Ssam} 3665189251Ssam#endif /* CONFIG_ANSI_C_EXTRA */ 3666189251Ssam 3667189251Ssam 3668189251Ssamstatic void wpa_cli_reconnect(void) 3669189251Ssam{ 3670189251Ssam wpa_cli_close_connection(); 3671252726Srpaulo if (wpa_cli_open_connection(ctrl_ifname, 1) < 0) 3672252726Srpaulo return; 3673252726Srpaulo 3674252726Srpaulo if (interactive) { 3675252726Srpaulo edit_clear_line(); 3676252726Srpaulo printf("\rConnection to wpa_supplicant re-established\n"); 3677252726Srpaulo edit_redraw(); 3678252726Srpaulo } 3679189251Ssam} 3680189251Ssam 3681189251Ssam 3682252726Srpaulostatic void cli_event(const char *str) 3683189251Ssam{ 3684252726Srpaulo const char *start, *s; 3685252726Srpaulo 3686252726Srpaulo start = os_strchr(str, '>'); 3687252726Srpaulo if (start == NULL) 3688252726Srpaulo return; 3689252726Srpaulo 3690252726Srpaulo start++; 3691252726Srpaulo 3692252726Srpaulo if (str_starts(start, WPA_EVENT_BSS_ADDED)) { 3693252726Srpaulo s = os_strchr(start, ' '); 3694252726Srpaulo if (s == NULL) 3695252726Srpaulo return; 3696252726Srpaulo s = os_strchr(s + 1, ' '); 3697252726Srpaulo if (s == NULL) 3698252726Srpaulo return; 3699252726Srpaulo cli_txt_list_add(&bsses, s + 1); 3700252726Srpaulo return; 3701252726Srpaulo } 3702252726Srpaulo 3703252726Srpaulo if (str_starts(start, WPA_EVENT_BSS_REMOVED)) { 3704252726Srpaulo s = os_strchr(start, ' '); 3705252726Srpaulo if (s == NULL) 3706252726Srpaulo return; 3707252726Srpaulo s = os_strchr(s + 1, ' '); 3708252726Srpaulo if (s == NULL) 3709252726Srpaulo return; 3710252726Srpaulo cli_txt_list_del_addr(&bsses, s + 1); 3711252726Srpaulo return; 3712252726Srpaulo } 3713252726Srpaulo 3714252726Srpaulo#ifdef CONFIG_P2P 3715252726Srpaulo if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) { 3716252726Srpaulo s = os_strstr(start, " p2p_dev_addr="); 3717252726Srpaulo if (s == NULL) 3718252726Srpaulo return; 3719252726Srpaulo cli_txt_list_add_addr(&p2p_peers, s + 14); 3720252726Srpaulo return; 3721252726Srpaulo } 3722252726Srpaulo 3723252726Srpaulo if (str_starts(start, P2P_EVENT_DEVICE_LOST)) { 3724252726Srpaulo s = os_strstr(start, " p2p_dev_addr="); 3725252726Srpaulo if (s == NULL) 3726252726Srpaulo return; 3727252726Srpaulo cli_txt_list_del_addr(&p2p_peers, s + 14); 3728252726Srpaulo return; 3729252726Srpaulo } 3730252726Srpaulo 3731252726Srpaulo if (str_starts(start, P2P_EVENT_GROUP_STARTED)) { 3732252726Srpaulo s = os_strchr(start, ' '); 3733252726Srpaulo if (s == NULL) 3734252726Srpaulo return; 3735289549Srpaulo cli_txt_list_add_word(&p2p_groups, s + 1, ' '); 3736252726Srpaulo return; 3737252726Srpaulo } 3738252726Srpaulo 3739252726Srpaulo if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) { 3740252726Srpaulo s = os_strchr(start, ' '); 3741252726Srpaulo if (s == NULL) 3742252726Srpaulo return; 3743289549Srpaulo cli_txt_list_del_word(&p2p_groups, s + 1, ' '); 3744252726Srpaulo return; 3745252726Srpaulo } 3746252726Srpaulo#endif /* CONFIG_P2P */ 3747252726Srpaulo} 3748252726Srpaulo 3749252726Srpaulo 3750252726Srpaulostatic int check_terminating(const char *msg) 3751252726Srpaulo{ 3752252726Srpaulo const char *pos = msg; 3753252726Srpaulo 3754252726Srpaulo if (*pos == '<') { 3755252726Srpaulo /* skip priority */ 3756252726Srpaulo pos = os_strchr(pos, '>'); 3757252726Srpaulo if (pos) 3758252726Srpaulo pos++; 3759252726Srpaulo else 3760252726Srpaulo pos = msg; 3761252726Srpaulo } 3762252726Srpaulo 3763337817Scy if (str_starts(pos, WPA_EVENT_TERMINATING) && ctrl_conn) { 3764252726Srpaulo edit_clear_line(); 3765252726Srpaulo printf("\rConnection to wpa_supplicant lost - trying to " 3766252726Srpaulo "reconnect\n"); 3767252726Srpaulo edit_redraw(); 3768252726Srpaulo wpa_cli_attached = 0; 3769252726Srpaulo wpa_cli_close_connection(); 3770252726Srpaulo return 1; 3771252726Srpaulo } 3772252726Srpaulo 3773252726Srpaulo return 0; 3774252726Srpaulo} 3775252726Srpaulo 3776252726Srpaulo 3777252726Srpaulostatic void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor) 3778252726Srpaulo{ 3779189251Ssam if (ctrl_conn == NULL) { 3780189251Ssam wpa_cli_reconnect(); 3781189251Ssam return; 3782189251Ssam } 3783189251Ssam while (wpa_ctrl_pending(ctrl) > 0) { 3784281806Srpaulo char buf[4096]; 3785189251Ssam size_t len = sizeof(buf) - 1; 3786189251Ssam if (wpa_ctrl_recv(ctrl, buf, &len) == 0) { 3787189251Ssam buf[len] = '\0'; 3788189251Ssam if (action_monitor) 3789189251Ssam wpa_cli_action_process(buf); 3790189251Ssam else { 3791252726Srpaulo cli_event(buf); 3792252726Srpaulo if (wpa_cli_show_event(buf)) { 3793252726Srpaulo edit_clear_line(); 3794252726Srpaulo printf("\r%s\n", buf); 3795252726Srpaulo edit_redraw(); 3796252726Srpaulo } 3797252726Srpaulo 3798252726Srpaulo if (interactive && check_terminating(buf) > 0) 3799252726Srpaulo return; 3800189251Ssam } 3801189251Ssam } else { 3802189251Ssam printf("Could not read pending message.\n"); 3803189251Ssam break; 3804189251Ssam } 3805189251Ssam } 3806189251Ssam 3807189251Ssam if (wpa_ctrl_pending(ctrl) < 0) { 3808189251Ssam printf("Connection to wpa_supplicant lost - trying to " 3809189251Ssam "reconnect\n"); 3810189251Ssam wpa_cli_reconnect(); 3811189251Ssam } 3812189251Ssam} 3813189251Ssam 3814189251Ssam 3815252726Srpaulostatic void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx) 3816189251Ssam{ 3817281806Srpaulo if (ctrl_conn) { 3818281806Srpaulo int res; 3819281806Srpaulo char *prefix = ifname_prefix; 3820281806Srpaulo 3821281806Srpaulo ifname_prefix = NULL; 3822281806Srpaulo res = _wpa_ctrl_command(ctrl_conn, "PING", 0); 3823281806Srpaulo ifname_prefix = prefix; 3824281806Srpaulo if (res) { 3825281806Srpaulo printf("Connection to wpa_supplicant lost - trying to " 3826281806Srpaulo "reconnect\n"); 3827281806Srpaulo wpa_cli_close_connection(); 3828281806Srpaulo } 3829214734Srpaulo } 3830252726Srpaulo if (!ctrl_conn) 3831252726Srpaulo wpa_cli_reconnect(); 3832252726Srpaulo eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL); 3833189251Ssam} 3834189251Ssam 3835189251Ssam 3836252726Srpaulostatic void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx) 3837214734Srpaulo{ 3838252726Srpaulo wpa_cli_recv_pending(mon_conn, 0); 3839252726Srpaulo} 3840214734Srpaulo 3841214734Srpaulo 3842252726Srpaulostatic void wpa_cli_edit_cmd_cb(void *ctx, char *cmd) 3843252726Srpaulo{ 3844252726Srpaulo char *argv[max_args]; 3845252726Srpaulo int argc; 3846252726Srpaulo argc = tokenize_cmd(cmd, argv); 3847252726Srpaulo if (argc) 3848252726Srpaulo wpa_request(ctrl_conn, argc, argv); 3849214734Srpaulo} 3850214734Srpaulo 3851214734Srpaulo 3852252726Srpaulostatic void wpa_cli_edit_eof_cb(void *ctx) 3853189251Ssam{ 3854252726Srpaulo eloop_terminate(); 3855189251Ssam} 3856189251Ssam 3857189251Ssam 3858252726Srpaulostatic int warning_displayed = 0; 3859252726Srpaulostatic char *hfile = NULL; 3860252726Srpaulostatic int edit_started = 0; 3861252726Srpaulo 3862252726Srpaulostatic void start_edit(void) 3863189251Ssam{ 3864252726Srpaulo char *home; 3865252726Srpaulo char *ps = NULL; 3866189251Ssam 3867252726Srpaulo#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE 3868252726Srpaulo ps = wpa_ctrl_get_remote_ifname(ctrl_conn); 3869252726Srpaulo#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */ 3870189251Ssam 3871289549Srpaulo#ifdef CONFIG_WPA_CLI_HISTORY_DIR 3872289549Srpaulo home = CONFIG_WPA_CLI_HISTORY_DIR; 3873289549Srpaulo#else /* CONFIG_WPA_CLI_HISTORY_DIR */ 3874189251Ssam home = getenv("HOME"); 3875289549Srpaulo#endif /* CONFIG_WPA_CLI_HISTORY_DIR */ 3876189251Ssam if (home) { 3877189251Ssam const char *fname = ".wpa_cli_history"; 3878189251Ssam int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1; 3879189251Ssam hfile = os_malloc(hfile_len); 3880252726Srpaulo if (hfile) 3881252726Srpaulo os_snprintf(hfile, hfile_len, "%s/%s", home, fname); 3882189251Ssam } 3883189251Ssam 3884252726Srpaulo if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb, 3885252726Srpaulo wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) { 3886252726Srpaulo eloop_terminate(); 3887252726Srpaulo return; 3888252726Srpaulo } 3889189251Ssam 3890252726Srpaulo edit_started = 1; 3891252726Srpaulo eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL); 3892252726Srpaulo} 3893189251Ssam 3894252726Srpaulo 3895281806Srpaulostatic void update_bssid_list(struct wpa_ctrl *ctrl) 3896281806Srpaulo{ 3897281806Srpaulo char buf[4096]; 3898281806Srpaulo size_t len = sizeof(buf); 3899281806Srpaulo int ret; 3900281806Srpaulo char *cmd = "BSS RANGE=ALL MASK=0x2"; 3901281806Srpaulo char *pos, *end; 3902281806Srpaulo 3903281806Srpaulo if (ctrl == NULL) 3904281806Srpaulo return; 3905281806Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 3906281806Srpaulo if (ret < 0) 3907281806Srpaulo return; 3908281806Srpaulo buf[len] = '\0'; 3909281806Srpaulo 3910281806Srpaulo pos = buf; 3911281806Srpaulo while (pos) { 3912281806Srpaulo pos = os_strstr(pos, "bssid="); 3913281806Srpaulo if (pos == NULL) 3914281806Srpaulo break; 3915281806Srpaulo pos += 6; 3916281806Srpaulo end = os_strchr(pos, '\n'); 3917281806Srpaulo if (end == NULL) 3918281806Srpaulo break; 3919281806Srpaulo *end = '\0'; 3920281806Srpaulo cli_txt_list_add(&bsses, pos); 3921281806Srpaulo pos = end + 1; 3922281806Srpaulo } 3923281806Srpaulo} 3924281806Srpaulo 3925281806Srpaulo 3926281806Srpaulostatic void update_ifnames(struct wpa_ctrl *ctrl) 3927281806Srpaulo{ 3928281806Srpaulo char buf[4096]; 3929281806Srpaulo size_t len = sizeof(buf); 3930281806Srpaulo int ret; 3931281806Srpaulo char *cmd = "INTERFACES"; 3932281806Srpaulo char *pos, *end; 3933281806Srpaulo char txt[200]; 3934281806Srpaulo 3935281806Srpaulo cli_txt_list_flush(&ifnames); 3936281806Srpaulo 3937281806Srpaulo if (ctrl == NULL) 3938281806Srpaulo return; 3939281806Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 3940281806Srpaulo if (ret < 0) 3941281806Srpaulo return; 3942281806Srpaulo buf[len] = '\0'; 3943281806Srpaulo 3944281806Srpaulo pos = buf; 3945281806Srpaulo while (pos) { 3946281806Srpaulo end = os_strchr(pos, '\n'); 3947281806Srpaulo if (end == NULL) 3948281806Srpaulo break; 3949281806Srpaulo *end = '\0'; 3950281806Srpaulo ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos); 3951281806Srpaulo if (!os_snprintf_error(sizeof(txt), ret)) 3952281806Srpaulo cli_txt_list_add(&ifnames, txt); 3953281806Srpaulo pos = end + 1; 3954281806Srpaulo } 3955281806Srpaulo} 3956281806Srpaulo 3957281806Srpaulo 3958289549Srpaulostatic void update_networks(struct wpa_ctrl *ctrl) 3959289549Srpaulo{ 3960289549Srpaulo char buf[4096]; 3961289549Srpaulo size_t len = sizeof(buf); 3962289549Srpaulo int ret; 3963289549Srpaulo char *cmd = "LIST_NETWORKS"; 3964289549Srpaulo char *pos, *end; 3965289549Srpaulo int header = 1; 3966289549Srpaulo 3967289549Srpaulo cli_txt_list_flush(&networks); 3968289549Srpaulo 3969289549Srpaulo if (ctrl == NULL) 3970289549Srpaulo return; 3971289549Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 3972289549Srpaulo if (ret < 0) 3973289549Srpaulo return; 3974289549Srpaulo buf[len] = '\0'; 3975289549Srpaulo 3976289549Srpaulo pos = buf; 3977289549Srpaulo while (pos) { 3978289549Srpaulo end = os_strchr(pos, '\n'); 3979289549Srpaulo if (end == NULL) 3980289549Srpaulo break; 3981289549Srpaulo *end = '\0'; 3982289549Srpaulo if (!header) 3983289549Srpaulo cli_txt_list_add_word(&networks, pos, '\t'); 3984289549Srpaulo header = 0; 3985289549Srpaulo pos = end + 1; 3986289549Srpaulo } 3987289549Srpaulo} 3988289549Srpaulo 3989289549Srpaulo 3990252726Srpaulostatic void try_connection(void *eloop_ctx, void *timeout_ctx) 3991252726Srpaulo{ 3992281806Srpaulo if (ctrl_conn) 3993281806Srpaulo goto done; 3994281806Srpaulo 3995252726Srpaulo if (ctrl_ifname == NULL) 3996252726Srpaulo ctrl_ifname = wpa_cli_get_default_ifname(); 3997252726Srpaulo 3998337817Scy if (wpa_cli_open_connection(ctrl_ifname, 1)) { 3999252726Srpaulo if (!warning_displayed) { 4000252726Srpaulo printf("Could not connect to wpa_supplicant: " 4001281806Srpaulo "%s - re-trying\n", 4002281806Srpaulo ctrl_ifname ? ctrl_ifname : "(nil)"); 4003252726Srpaulo warning_displayed = 1; 4004189251Ssam } 4005252726Srpaulo eloop_register_timeout(1, 0, try_connection, NULL, NULL); 4006252726Srpaulo return; 4007189251Ssam } 4008252726Srpaulo 4009281806Srpaulo update_bssid_list(ctrl_conn); 4010289549Srpaulo update_networks(ctrl_conn); 4011281806Srpaulo 4012252726Srpaulo if (warning_displayed) 4013252726Srpaulo printf("Connection established.\n"); 4014252726Srpaulo 4015281806Srpaulodone: 4016252726Srpaulo start_edit(); 4017189251Ssam} 4018189251Ssam 4019189251Ssam 4020252726Srpaulostatic void wpa_cli_interactive(void) 4021252726Srpaulo{ 4022252726Srpaulo printf("\nInteractive mode\n\n"); 4023252726Srpaulo 4024252726Srpaulo eloop_register_timeout(0, 0, try_connection, NULL, NULL); 4025252726Srpaulo eloop_run(); 4026252726Srpaulo eloop_cancel_timeout(try_connection, NULL, NULL); 4027252726Srpaulo 4028252726Srpaulo cli_txt_list_flush(&p2p_peers); 4029252726Srpaulo cli_txt_list_flush(&p2p_groups); 4030252726Srpaulo cli_txt_list_flush(&bsses); 4031281806Srpaulo cli_txt_list_flush(&ifnames); 4032289549Srpaulo cli_txt_list_flush(&networks); 4033252726Srpaulo if (edit_started) 4034252726Srpaulo edit_deinit(hfile, wpa_cli_edit_filter_history_cb); 4035252726Srpaulo os_free(hfile); 4036252726Srpaulo eloop_cancel_timeout(wpa_cli_ping, NULL, NULL); 4037252726Srpaulo wpa_cli_close_connection(); 4038252726Srpaulo} 4039252726Srpaulo 4040252726Srpaulo 4041289549Srpaulostatic void wpa_cli_action_ping(void *eloop_ctx, void *timeout_ctx) 4042289549Srpaulo{ 4043289549Srpaulo struct wpa_ctrl *ctrl = eloop_ctx; 4044289549Srpaulo char buf[256]; 4045289549Srpaulo size_t len; 4046289549Srpaulo 4047289549Srpaulo /* verify that connection is still working */ 4048289549Srpaulo len = sizeof(buf) - 1; 4049289549Srpaulo if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len, 4050289549Srpaulo wpa_cli_action_cb) < 0 || 4051289549Srpaulo len < 4 || os_memcmp(buf, "PONG", 4) != 0) { 4052289549Srpaulo printf("wpa_supplicant did not reply to PING command - exiting\n"); 4053289549Srpaulo eloop_terminate(); 4054289549Srpaulo return; 4055289549Srpaulo } 4056289549Srpaulo eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping, 4057289549Srpaulo ctrl, NULL); 4058289549Srpaulo} 4059289549Srpaulo 4060289549Srpaulo 4061289549Srpaulostatic void wpa_cli_action_receive(int sock, void *eloop_ctx, void *sock_ctx) 4062289549Srpaulo{ 4063289549Srpaulo struct wpa_ctrl *ctrl = eloop_ctx; 4064289549Srpaulo 4065289549Srpaulo wpa_cli_recv_pending(ctrl, 1); 4066289549Srpaulo} 4067289549Srpaulo 4068289549Srpaulo 4069189251Ssamstatic void wpa_cli_action(struct wpa_ctrl *ctrl) 4070189251Ssam{ 4071189251Ssam#ifdef CONFIG_ANSI_C_EXTRA 4072189251Ssam /* TODO: ANSI C version(?) */ 4073189251Ssam printf("Action processing not supported in ANSI C build.\n"); 4074189251Ssam#else /* CONFIG_ANSI_C_EXTRA */ 4075289549Srpaulo int fd; 4076189251Ssam 4077189251Ssam fd = wpa_ctrl_get_fd(ctrl); 4078289549Srpaulo eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping, 4079289549Srpaulo ctrl, NULL); 4080289549Srpaulo eloop_register_read_sock(fd, wpa_cli_action_receive, ctrl, NULL); 4081289549Srpaulo eloop_run(); 4082289549Srpaulo eloop_cancel_timeout(wpa_cli_action_ping, ctrl, NULL); 4083289549Srpaulo eloop_unregister_read_sock(fd); 4084189251Ssam#endif /* CONFIG_ANSI_C_EXTRA */ 4085189251Ssam} 4086189251Ssam 4087189251Ssam 4088189251Ssamstatic void wpa_cli_cleanup(void) 4089189251Ssam{ 4090189251Ssam wpa_cli_close_connection(); 4091189251Ssam if (pid_file) 4092189251Ssam os_daemonize_terminate(pid_file); 4093189251Ssam 4094189251Ssam os_program_deinit(); 4095189251Ssam} 4096189251Ssam 4097189251Ssam 4098252726Srpaulostatic void wpa_cli_terminate(int sig, void *ctx) 4099214734Srpaulo{ 4100252726Srpaulo eloop_terminate(); 4101214734Srpaulo} 4102214734Srpaulo 4103214734Srpaulo 4104189251Ssamstatic char * wpa_cli_get_default_ifname(void) 4105189251Ssam{ 4106189251Ssam char *ifname = NULL; 4107189251Ssam 4108289549Srpaulo#ifdef ANDROID 4109289549Srpaulo char ifprop[PROPERTY_VALUE_MAX]; 4110289549Srpaulo if (property_get("wifi.interface", ifprop, NULL) != 0) { 4111289549Srpaulo ifname = os_strdup(ifprop); 4112289549Srpaulo printf("Using interface '%s'\n", ifname ? ifname : "N/A"); 4113289549Srpaulo } 4114289549Srpaulo#else /* ANDROID */ 4115189251Ssam#ifdef CONFIG_CTRL_IFACE_UNIX 4116189251Ssam struct dirent *dent; 4117189251Ssam DIR *dir = opendir(ctrl_iface_dir); 4118252726Srpaulo if (!dir) { 4119189251Ssam return NULL; 4120252726Srpaulo } 4121189251Ssam while ((dent = readdir(dir))) { 4122189251Ssam#ifdef _DIRENT_HAVE_D_TYPE 4123189251Ssam /* 4124189251Ssam * Skip the file if it is not a socket. Also accept 4125189251Ssam * DT_UNKNOWN (0) in case the C library or underlying 4126189251Ssam * file system does not support d_type. 4127189251Ssam */ 4128189251Ssam if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN) 4129189251Ssam continue; 4130189251Ssam#endif /* _DIRENT_HAVE_D_TYPE */ 4131189251Ssam if (os_strcmp(dent->d_name, ".") == 0 || 4132189251Ssam os_strcmp(dent->d_name, "..") == 0) 4133189251Ssam continue; 4134189251Ssam printf("Selected interface '%s'\n", dent->d_name); 4135189251Ssam ifname = os_strdup(dent->d_name); 4136189251Ssam break; 4137189251Ssam } 4138189251Ssam closedir(dir); 4139189251Ssam#endif /* CONFIG_CTRL_IFACE_UNIX */ 4140189251Ssam 4141189251Ssam#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 4142281806Srpaulo char buf[4096], *pos; 4143189251Ssam size_t len; 4144189251Ssam struct wpa_ctrl *ctrl; 4145189251Ssam int ret; 4146189251Ssam 4147189251Ssam ctrl = wpa_ctrl_open(NULL); 4148189251Ssam if (ctrl == NULL) 4149189251Ssam return NULL; 4150189251Ssam 4151189251Ssam len = sizeof(buf) - 1; 4152189251Ssam ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL); 4153189251Ssam if (ret >= 0) { 4154189251Ssam buf[len] = '\0'; 4155189251Ssam pos = os_strchr(buf, '\n'); 4156189251Ssam if (pos) 4157189251Ssam *pos = '\0'; 4158189251Ssam ifname = os_strdup(buf); 4159189251Ssam } 4160189251Ssam wpa_ctrl_close(ctrl); 4161189251Ssam#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 4162289549Srpaulo#endif /* ANDROID */ 4163189251Ssam 4164189251Ssam return ifname; 4165189251Ssam} 4166189251Ssam 4167189251Ssam 4168189251Ssamint main(int argc, char *argv[]) 4169189251Ssam{ 4170189251Ssam int c; 4171189251Ssam int daemonize = 0; 4172189251Ssam int ret = 0; 4173189251Ssam const char *global = NULL; 4174189251Ssam 4175189251Ssam if (os_program_init()) 4176189251Ssam return -1; 4177189251Ssam 4178189251Ssam for (;;) { 4179289549Srpaulo c = getopt(argc, argv, "a:Bg:G:hi:p:P:s:v"); 4180189251Ssam if (c < 0) 4181189251Ssam break; 4182189251Ssam switch (c) { 4183189251Ssam case 'a': 4184189251Ssam action_file = optarg; 4185189251Ssam break; 4186189251Ssam case 'B': 4187189251Ssam daemonize = 1; 4188189251Ssam break; 4189189251Ssam case 'g': 4190189251Ssam global = optarg; 4191189251Ssam break; 4192189251Ssam case 'G': 4193189251Ssam ping_interval = atoi(optarg); 4194189251Ssam break; 4195189251Ssam case 'h': 4196189251Ssam usage(); 4197189251Ssam return 0; 4198189251Ssam case 'v': 4199189251Ssam printf("%s\n", wpa_cli_version); 4200189251Ssam return 0; 4201189251Ssam case 'i': 4202189251Ssam os_free(ctrl_ifname); 4203189251Ssam ctrl_ifname = os_strdup(optarg); 4204189251Ssam break; 4205189251Ssam case 'p': 4206189251Ssam ctrl_iface_dir = optarg; 4207189251Ssam break; 4208189251Ssam case 'P': 4209189251Ssam pid_file = optarg; 4210189251Ssam break; 4211289549Srpaulo case 's': 4212289549Srpaulo client_socket_dir = optarg; 4213289549Srpaulo break; 4214189251Ssam default: 4215189251Ssam usage(); 4216189251Ssam return -1; 4217189251Ssam } 4218189251Ssam } 4219189251Ssam 4220189251Ssam interactive = (argc == optind) && (action_file == NULL); 4221189251Ssam 4222189251Ssam if (interactive) 4223337817Scy printf("%s\n\n%s\n\n", wpa_cli_version, cli_license); 4224189251Ssam 4225252726Srpaulo if (eloop_init()) 4226252726Srpaulo return -1; 4227252726Srpaulo 4228189251Ssam if (global) { 4229189251Ssam#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 4230189251Ssam ctrl_conn = wpa_ctrl_open(NULL); 4231189251Ssam#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 4232189251Ssam ctrl_conn = wpa_ctrl_open(global); 4233189251Ssam#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 4234189251Ssam if (ctrl_conn == NULL) { 4235252726Srpaulo fprintf(stderr, "Failed to connect to wpa_supplicant " 4236252726Srpaulo "global interface: %s error: %s\n", 4237252726Srpaulo global, strerror(errno)); 4238189251Ssam return -1; 4239189251Ssam } 4240281806Srpaulo 4241281806Srpaulo if (interactive) { 4242281806Srpaulo update_ifnames(ctrl_conn); 4243281806Srpaulo mon_conn = wpa_ctrl_open(global); 4244281806Srpaulo if (mon_conn) { 4245281806Srpaulo if (wpa_ctrl_attach(mon_conn) == 0) { 4246281806Srpaulo wpa_cli_attached = 1; 4247281806Srpaulo eloop_register_read_sock( 4248281806Srpaulo wpa_ctrl_get_fd(mon_conn), 4249281806Srpaulo wpa_cli_mon_receive, 4250281806Srpaulo NULL, NULL); 4251281806Srpaulo } else { 4252281806Srpaulo printf("Failed to open monitor " 4253281806Srpaulo "connection through global " 4254281806Srpaulo "control interface\n"); 4255281806Srpaulo } 4256281806Srpaulo } 4257281806Srpaulo } 4258189251Ssam } 4259189251Ssam 4260252726Srpaulo eloop_register_signal_terminate(wpa_cli_terminate, NULL); 4261189251Ssam 4262214734Srpaulo if (ctrl_ifname == NULL) 4263214734Srpaulo ctrl_ifname = wpa_cli_get_default_ifname(); 4264214734Srpaulo 4265214734Srpaulo if (interactive) { 4266252726Srpaulo wpa_cli_interactive(); 4267214734Srpaulo } else { 4268214734Srpaulo if (!global && 4269214734Srpaulo wpa_cli_open_connection(ctrl_ifname, 0) < 0) { 4270252726Srpaulo fprintf(stderr, "Failed to connect to non-global " 4271252726Srpaulo "ctrl_ifname: %s error: %s\n", 4272281806Srpaulo ctrl_ifname ? ctrl_ifname : "(nil)", 4273281806Srpaulo strerror(errno)); 4274214734Srpaulo return -1; 4275214734Srpaulo } 4276214734Srpaulo 4277214734Srpaulo if (action_file) { 4278214734Srpaulo if (wpa_ctrl_attach(ctrl_conn) == 0) { 4279214734Srpaulo wpa_cli_attached = 1; 4280214734Srpaulo } else { 4281214734Srpaulo printf("Warning: Failed to attach to " 4282214734Srpaulo "wpa_supplicant.\n"); 4283189251Ssam return -1; 4284214734Srpaulo } 4285189251Ssam } 4286189251Ssam 4287337817Scy if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue()) 4288252726Srpaulo return -1; 4289189251Ssam 4290252726Srpaulo if (action_file) 4291252726Srpaulo wpa_cli_action(ctrl_conn); 4292252726Srpaulo else 4293252726Srpaulo ret = wpa_request(ctrl_conn, argc - optind, 4294252726Srpaulo &argv[optind]); 4295252726Srpaulo } 4296189251Ssam 4297189251Ssam os_free(ctrl_ifname); 4298252726Srpaulo eloop_destroy(); 4299189251Ssam wpa_cli_cleanup(); 4300189251Ssam 4301189251Ssam return ret; 4302189251Ssam} 4303189251Ssam 4304189251Ssam#else /* CONFIG_CTRL_IFACE */ 4305189251Ssamint main(int argc, char *argv[]) 4306189251Ssam{ 4307189251Ssam printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n"); 4308189251Ssam return -1; 4309189251Ssam} 4310189251Ssam#endif /* CONFIG_CTRL_IFACE */ 4311