1189251Ssam/* 2189251Ssam * WPA Supplicant - command line interface for wpa_supplicant daemon 3346981Scy * Copyright (c) 2004-2019, 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" 32346981Scy"Copyright (c) 2004-2019, 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; 52346981Scystatic const char *global = NULL; 53189251Ssamstatic const char *pid_file = NULL; 54189251Ssamstatic const char *action_file = NULL; 55189251Ssamstatic int ping_interval = 5; 56214734Srpaulostatic int interactive = 0; 57281806Srpaulostatic char *ifname_prefix = NULL; 58189251Ssam 59252726Srpaulostatic DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */ 60252726Srpaulostatic DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */ 61252726Srpaulostatic DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */ 62281806Srpaulostatic DEFINE_DL_LIST(ifnames); /* struct cli_txt_entry */ 63289549Srpaulostatic DEFINE_DL_LIST(networks); /* struct cli_txt_entry */ 64346981Scystatic DEFINE_DL_LIST(creds); /* struct cli_txt_entry */ 65346981Scy#ifdef CONFIG_AP 66346981Scystatic DEFINE_DL_LIST(stations); /* struct cli_txt_entry */ 67346981Scy#endif /* CONFIG_AP */ 68189251Ssam 69189251Ssam 70252726Srpaulostatic void print_help(const char *cmd); 71252726Srpaulostatic void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx); 72252726Srpaulostatic void wpa_cli_close_connection(void); 73252726Srpaulostatic char * wpa_cli_get_default_ifname(void); 74252726Srpaulostatic char ** wpa_list_cmd_list(void); 75346981Scystatic void update_creds(struct wpa_ctrl *ctrl); 76289549Srpaulostatic void update_networks(struct wpa_ctrl *ctrl); 77346981Scystatic void update_stations(struct wpa_ctrl *ctrl); 78346981Scystatic void update_ifnames(struct wpa_ctrl *ctrl); 79252726Srpaulo 80252726Srpaulo 81189251Ssamstatic void usage(void) 82189251Ssam{ 83189251Ssam printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] " 84189251Ssam "[-a<action file>] \\\n" 85289549Srpaulo " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] " 86289549Srpaulo "\\\n" 87289549Srpaulo " [-s<wpa_client_socket_file_path>] " 88189251Ssam "[command..]\n" 89189251Ssam " -h = help (show this usage text)\n" 90189251Ssam " -v = shown version information\n" 91189251Ssam " -a = run in daemon mode executing the action file based on " 92189251Ssam "events from\n" 93189251Ssam " wpa_supplicant\n" 94189251Ssam " -B = run a daemon in the background\n" 95252726Srpaulo " default path: " CONFIG_CTRL_IFACE_DIR "\n" 96189251Ssam " default interface: first interface found in socket path\n"); 97252726Srpaulo print_help(NULL); 98189251Ssam} 99189251Ssam 100189251Ssam 101252726Srpaulostatic int wpa_cli_show_event(const char *event) 102252726Srpaulo{ 103252726Srpaulo const char *start; 104252726Srpaulo 105252726Srpaulo start = os_strchr(event, '>'); 106252726Srpaulo if (start == NULL) 107252726Srpaulo return 1; 108252726Srpaulo 109252726Srpaulo start++; 110252726Srpaulo /* 111252726Srpaulo * Skip BSS added/removed events since they can be relatively frequent 112252726Srpaulo * and are likely of not much use for an interactive user. 113252726Srpaulo */ 114252726Srpaulo if (str_starts(start, WPA_EVENT_BSS_ADDED) || 115252726Srpaulo str_starts(start, WPA_EVENT_BSS_REMOVED)) 116252726Srpaulo return 0; 117252726Srpaulo 118252726Srpaulo return 1; 119252726Srpaulo} 120252726Srpaulo 121252726Srpaulo 122214734Srpaulostatic int wpa_cli_open_connection(const char *ifname, int attach) 123214734Srpaulo{ 124189251Ssam#if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE) 125189251Ssam ctrl_conn = wpa_ctrl_open(ifname); 126214734Srpaulo if (ctrl_conn == NULL) 127214734Srpaulo return -1; 128214734Srpaulo 129214734Srpaulo if (attach && interactive) 130214734Srpaulo mon_conn = wpa_ctrl_open(ifname); 131214734Srpaulo else 132214734Srpaulo mon_conn = NULL; 133189251Ssam#else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ 134252726Srpaulo char *cfile = NULL; 135189251Ssam int flen, res; 136189251Ssam 137189251Ssam if (ifname == NULL) 138214734Srpaulo return -1; 139189251Ssam 140252726Srpaulo#ifdef ANDROID 141252726Srpaulo if (access(ctrl_iface_dir, F_OK) < 0) { 142252726Srpaulo cfile = os_strdup(ifname); 143252726Srpaulo if (cfile == NULL) 144252726Srpaulo return -1; 145189251Ssam } 146252726Srpaulo#endif /* ANDROID */ 147189251Ssam 148289549Srpaulo if (client_socket_dir && client_socket_dir[0] && 149289549Srpaulo access(client_socket_dir, F_OK) < 0) { 150289549Srpaulo perror(client_socket_dir); 151289549Srpaulo os_free(cfile); 152289549Srpaulo return -1; 153289549Srpaulo } 154289549Srpaulo 155252726Srpaulo if (cfile == NULL) { 156252726Srpaulo flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2; 157252726Srpaulo cfile = os_malloc(flen); 158252726Srpaulo if (cfile == NULL) 159252726Srpaulo return -1; 160252726Srpaulo res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, 161252726Srpaulo ifname); 162281806Srpaulo if (os_snprintf_error(flen, res)) { 163252726Srpaulo os_free(cfile); 164252726Srpaulo return -1; 165252726Srpaulo } 166252726Srpaulo } 167252726Srpaulo 168289549Srpaulo ctrl_conn = wpa_ctrl_open2(cfile, client_socket_dir); 169214734Srpaulo if (ctrl_conn == NULL) { 170214734Srpaulo os_free(cfile); 171214734Srpaulo return -1; 172214734Srpaulo } 173214734Srpaulo 174214734Srpaulo if (attach && interactive) 175289549Srpaulo mon_conn = wpa_ctrl_open2(cfile, client_socket_dir); 176214734Srpaulo else 177214734Srpaulo mon_conn = NULL; 178189251Ssam os_free(cfile); 179189251Ssam#endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ 180214734Srpaulo 181214734Srpaulo if (mon_conn) { 182214734Srpaulo if (wpa_ctrl_attach(mon_conn) == 0) { 183214734Srpaulo wpa_cli_attached = 1; 184252726Srpaulo if (interactive) 185252726Srpaulo eloop_register_read_sock( 186252726Srpaulo wpa_ctrl_get_fd(mon_conn), 187252726Srpaulo wpa_cli_mon_receive, NULL, NULL); 188214734Srpaulo } else { 189214734Srpaulo printf("Warning: Failed to attach to " 190214734Srpaulo "wpa_supplicant.\n"); 191252726Srpaulo wpa_cli_close_connection(); 192214734Srpaulo return -1; 193214734Srpaulo } 194214734Srpaulo } 195214734Srpaulo 196214734Srpaulo return 0; 197189251Ssam} 198189251Ssam 199189251Ssam 200189251Ssamstatic void wpa_cli_close_connection(void) 201189251Ssam{ 202189251Ssam if (ctrl_conn == NULL) 203189251Ssam return; 204189251Ssam 205189251Ssam if (wpa_cli_attached) { 206214734Srpaulo wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn); 207189251Ssam wpa_cli_attached = 0; 208189251Ssam } 209189251Ssam wpa_ctrl_close(ctrl_conn); 210189251Ssam ctrl_conn = NULL; 211214734Srpaulo if (mon_conn) { 212252726Srpaulo eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn)); 213214734Srpaulo wpa_ctrl_close(mon_conn); 214214734Srpaulo mon_conn = NULL; 215214734Srpaulo } 216189251Ssam} 217189251Ssam 218189251Ssam 219189251Ssamstatic void wpa_cli_msg_cb(char *msg, size_t len) 220189251Ssam{ 221189251Ssam printf("%s\n", msg); 222189251Ssam} 223189251Ssam 224189251Ssam 225346981Scystatic int _wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd, int print) 226189251Ssam{ 227281806Srpaulo char buf[4096]; 228189251Ssam size_t len; 229189251Ssam int ret; 230189251Ssam 231189251Ssam if (ctrl_conn == NULL) { 232189251Ssam printf("Not connected to wpa_supplicant - command dropped.\n"); 233189251Ssam return -1; 234189251Ssam } 235281806Srpaulo if (ifname_prefix) { 236281806Srpaulo os_snprintf(buf, sizeof(buf), "IFNAME=%s %s", 237281806Srpaulo ifname_prefix, cmd); 238281806Srpaulo buf[sizeof(buf) - 1] = '\0'; 239281806Srpaulo cmd = buf; 240281806Srpaulo } 241189251Ssam len = sizeof(buf) - 1; 242189251Ssam ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 243189251Ssam wpa_cli_msg_cb); 244189251Ssam if (ret == -2) { 245189251Ssam printf("'%s' command timed out.\n", cmd); 246189251Ssam return -2; 247189251Ssam } else if (ret < 0) { 248189251Ssam printf("'%s' command failed.\n", cmd); 249189251Ssam return -1; 250189251Ssam } 251189251Ssam if (print) { 252189251Ssam buf[len] = '\0'; 253189251Ssam printf("%s", buf); 254252726Srpaulo if (interactive && len > 0 && buf[len - 1] != '\n') 255252726Srpaulo printf("\n"); 256189251Ssam } 257189251Ssam return 0; 258189251Ssam} 259189251Ssam 260189251Ssam 261346981Scystatic int wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd) 262189251Ssam{ 263189251Ssam return _wpa_ctrl_command(ctrl, cmd, 1); 264189251Ssam} 265189251Ssam 266189251Ssam 267252726Srpaulostatic int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args, 268252726Srpaulo int argc, char *argv[]) 269252726Srpaulo{ 270281806Srpaulo char buf[4096]; 271252726Srpaulo if (argc < min_args) { 272252726Srpaulo printf("Invalid %s command - at least %d argument%s " 273252726Srpaulo "required.\n", cmd, min_args, 274252726Srpaulo min_args > 1 ? "s are" : " is"); 275252726Srpaulo return -1; 276252726Srpaulo } 277252726Srpaulo if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0) 278252726Srpaulo return -1; 279252726Srpaulo return wpa_ctrl_command(ctrl, buf); 280252726Srpaulo} 281252726Srpaulo 282252726Srpaulo 283252726Srpaulostatic int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[]) 284252726Srpaulo{ 285252726Srpaulo return wpa_ctrl_command(ctrl, "IFNAME"); 286252726Srpaulo} 287252726Srpaulo 288252726Srpaulo 289189251Ssamstatic int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[]) 290189251Ssam{ 291252726Srpaulo if (argc > 0 && os_strcmp(argv[0], "verbose") == 0) 292252726Srpaulo return wpa_ctrl_command(ctrl, "STATUS-VERBOSE"); 293252726Srpaulo if (argc > 0 && os_strcmp(argv[0], "wps") == 0) 294252726Srpaulo return wpa_ctrl_command(ctrl, "STATUS-WPS"); 295281806Srpaulo if (argc > 0 && os_strcmp(argv[0], "driver") == 0) 296281806Srpaulo return wpa_ctrl_command(ctrl, "STATUS-DRIVER"); 297289549Srpaulo#ifdef ANDROID 298289549Srpaulo if (argc > 0 && os_strcmp(argv[0], "no_events") == 0) 299289549Srpaulo return wpa_ctrl_command(ctrl, "STATUS-NO_EVENTS"); 300289549Srpaulo#endif /* ANDROID */ 301252726Srpaulo return wpa_ctrl_command(ctrl, "STATUS"); 302189251Ssam} 303189251Ssam 304189251Ssam 305189251Ssamstatic int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[]) 306189251Ssam{ 307189251Ssam return wpa_ctrl_command(ctrl, "PING"); 308189251Ssam} 309189251Ssam 310189251Ssam 311252726Srpaulostatic int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[]) 312252726Srpaulo{ 313252726Srpaulo return wpa_ctrl_command(ctrl, "RELOG"); 314252726Srpaulo} 315252726Srpaulo 316252726Srpaulo 317252726Srpaulostatic int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[]) 318252726Srpaulo{ 319252726Srpaulo return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv); 320252726Srpaulo} 321252726Srpaulo 322252726Srpaulo 323189251Ssamstatic int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[]) 324189251Ssam{ 325189251Ssam return wpa_ctrl_command(ctrl, "MIB"); 326189251Ssam} 327189251Ssam 328189251Ssam 329189251Ssamstatic int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[]) 330189251Ssam{ 331189251Ssam return wpa_ctrl_command(ctrl, "PMKSA"); 332189251Ssam} 333189251Ssam 334189251Ssam 335281806Srpaulostatic int wpa_cli_cmd_pmksa_flush(struct wpa_ctrl *ctrl, int argc, 336281806Srpaulo char *argv[]) 337281806Srpaulo{ 338281806Srpaulo return wpa_ctrl_command(ctrl, "PMKSA_FLUSH"); 339281806Srpaulo} 340281806Srpaulo 341281806Srpaulo 342346981Scy#ifdef CONFIG_PMKSA_CACHE_EXTERNAL 343346981Scy 344346981Scystatic int wpa_cli_cmd_pmksa_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) 345346981Scy{ 346346981Scy return wpa_cli_cmd(ctrl, "PMKSA_GET", 1, argc, argv); 347346981Scy} 348346981Scy 349346981Scy 350346981Scystatic int wpa_cli_cmd_pmksa_add(struct wpa_ctrl *ctrl, int argc, char *argv[]) 351346981Scy{ 352346981Scy return wpa_cli_cmd(ctrl, "PMKSA_ADD", 8, argc, argv); 353346981Scy} 354346981Scy 355346981Scy 356346981Scy#ifdef CONFIG_MESH 357346981Scy 358346981Scystatic int wpa_cli_mesh_cmd_pmksa_get(struct wpa_ctrl *ctrl, int argc, 359346981Scy char *argv[]) 360346981Scy{ 361346981Scy return wpa_cli_cmd(ctrl, "MESH_PMKSA_GET", 1, argc, argv); 362346981Scy} 363346981Scy 364346981Scy 365346981Scystatic int wpa_cli_mesh_cmd_pmksa_add(struct wpa_ctrl *ctrl, int argc, 366346981Scy char *argv[]) 367346981Scy{ 368346981Scy return wpa_cli_cmd(ctrl, "MESH_PMKSA_ADD", 4, argc, argv); 369346981Scy} 370346981Scy 371346981Scy#endif /* CONFIG_MESH */ 372346981Scy#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */ 373346981Scy 374346981Scy 375189251Ssamstatic int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[]) 376189251Ssam{ 377252726Srpaulo print_help(argc > 0 ? argv[0] : NULL); 378189251Ssam return 0; 379189251Ssam} 380189251Ssam 381189251Ssam 382252726Srpaulostatic char ** wpa_cli_complete_help(const char *str, int pos) 383252726Srpaulo{ 384252726Srpaulo int arg = get_cmd_arg_num(str, pos); 385252726Srpaulo char **res = NULL; 386252726Srpaulo 387252726Srpaulo switch (arg) { 388252726Srpaulo case 1: 389252726Srpaulo res = wpa_list_cmd_list(); 390252726Srpaulo break; 391252726Srpaulo } 392252726Srpaulo 393252726Srpaulo return res; 394252726Srpaulo} 395252726Srpaulo 396252726Srpaulo 397189251Ssamstatic int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[]) 398189251Ssam{ 399337817Scy printf("%s\n\n%s\n", wpa_cli_version, cli_full_license); 400189251Ssam return 0; 401189251Ssam} 402189251Ssam 403189251Ssam 404189251Ssamstatic int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[]) 405189251Ssam{ 406189251Ssam wpa_cli_quit = 1; 407252726Srpaulo if (interactive) 408252726Srpaulo eloop_terminate(); 409189251Ssam return 0; 410189251Ssam} 411189251Ssam 412189251Ssam 413189251Ssamstatic int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) 414189251Ssam{ 415189251Ssam char cmd[256]; 416189251Ssam int res; 417189251Ssam 418281806Srpaulo if (argc == 1) { 419281806Srpaulo res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]); 420281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) { 421281806Srpaulo printf("Too long SET command.\n"); 422281806Srpaulo return -1; 423281806Srpaulo } 424281806Srpaulo return wpa_ctrl_command(ctrl, cmd); 425189251Ssam } 426189251Ssam 427281806Srpaulo return wpa_cli_cmd(ctrl, "SET", 2, argc, argv); 428281806Srpaulo} 429281806Srpaulo 430281806Srpaulo 431281806Srpaulostatic char ** wpa_cli_complete_set(const char *str, int pos) 432281806Srpaulo{ 433281806Srpaulo int arg = get_cmd_arg_num(str, pos); 434281806Srpaulo const char *fields[] = { 435281806Srpaulo /* runtime values */ 436281806Srpaulo "EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod", 437281806Srpaulo "EAPOL::maxStart", "dot11RSNAConfigPMKLifetime", 438281806Srpaulo "dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout", 439281806Srpaulo "wps_fragment_size", "wps_version_number", "ampdu", 440281806Srpaulo "tdls_testing", "tdls_disabled", "pno", "radio_disabled", 441281806Srpaulo "uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps", 442281806Srpaulo "no_keep_alive", 443281806Srpaulo /* global configuration parameters */ 444289549Srpaulo#ifdef CONFIG_CTRL_IFACE 445289549Srpaulo "ctrl_interface", "no_ctrl_interface", "ctrl_interface_group", 446289549Srpaulo#endif /* CONFIG_CTRL_IFACE */ 447289549Srpaulo "eapol_version", "ap_scan", "bgscan", 448289549Srpaulo#ifdef CONFIG_MESH 449289549Srpaulo "user_mpm", "max_peer_links", "mesh_max_inactivity", 450289549Srpaulo "dot11RSNASAERetransPeriod", 451289549Srpaulo#endif /* CONFIG_MESH */ 452289549Srpaulo "disable_scan_offload", "fast_reauth", "opensc_engine_path", 453289549Srpaulo "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers", 454289549Srpaulo "pcsc_reader", "pcsc_pin", "external_sim", "driver_param", 455289549Srpaulo "dot11RSNAConfigPMKLifetime", 456281806Srpaulo "dot11RSNAConfigPMKReauthThreshold", 457281806Srpaulo "dot11RSNAConfigSATimeout", 458289549Srpaulo#ifndef CONFIG_NO_CONFIG_WRITE 459289549Srpaulo "update_config", 460289549Srpaulo#endif /* CONFIG_NO_CONFIG_WRITE */ 461289549Srpaulo "load_dynamic_eap", 462289549Srpaulo#ifdef CONFIG_WPS 463289549Srpaulo "uuid", "device_name", "manufacturer", "model_name", 464289549Srpaulo "model_number", "serial_number", "device_type", "os_version", 465289549Srpaulo "config_methods", "wps_cred_processing", "wps_vendor_ext_m1", 466289549Srpaulo#endif /* CONFIG_WPS */ 467289549Srpaulo#ifdef CONFIG_P2P 468289549Srpaulo "sec_device_type", 469281806Srpaulo "p2p_listen_reg_class", "p2p_listen_channel", 470289549Srpaulo "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent", 471289549Srpaulo "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss", 472289549Srpaulo "p2p_group_idle", "p2p_passphrase_len", "p2p_pref_chan", 473289549Srpaulo "p2p_no_go_freq", "p2p_add_cli_chan", 474289549Srpaulo "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht", 475289549Srpaulo "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface", 476289549Srpaulo "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask", 477289549Srpaulo "ip_addr_start", "ip_addr_end", 478289549Srpaulo#endif /* CONFIG_P2P */ 479289549Srpaulo "country", "bss_max_count", "bss_expiration_age", 480289549Srpaulo "bss_expiration_scan_count", "filter_ssids", "filter_rssi", 481346981Scy "max_num_sta", "disassoc_low_ack", "ap_isolate", 482289549Srpaulo#ifdef CONFIG_HS20 483289549Srpaulo "hs20", 484289549Srpaulo#endif /* CONFIG_HS20 */ 485289549Srpaulo "interworking", "hessid", "access_network_type", "pbc_in_m1", 486346981Scy "go_interworking", "go_access_network_type", "go_internet", 487346981Scy "go_venue_group", "go_venue_type", 488289549Srpaulo "autoscan", "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey", 489289549Srpaulo "wps_nfc_dh_privkey", "wps_nfc_dev_pw", "ext_password_backend", 490281806Srpaulo "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf", 491289549Srpaulo "sae_groups", "dtim_period", "beacon_int", 492289549Srpaulo "ap_vendor_elements", "ignore_old_scan_res", "freq_list", 493289549Srpaulo "scan_cur_freq", "sched_scan_interval", 494289549Srpaulo "tdls_external_control", "osu_dir", "wowlan_triggers", 495289549Srpaulo "p2p_search_delay", "mac_addr", "rand_addr_lifetime", 496289549Srpaulo "preassoc_mac_addr", "key_mgmt_offload", "passive_scan", 497337817Scy "reassoc_same_bss_optim", "wps_priority", 498337817Scy#ifdef CONFIG_TESTING_OPTIONS 499337817Scy "ignore_auth_resp", 500337817Scy#endif /* CONFIG_TESTING_OPTIONS */ 501346981Scy "relative_rssi", "relative_band_adjust", 502281806Srpaulo }; 503281806Srpaulo int i, num_fields = ARRAY_SIZE(fields); 504281806Srpaulo 505281806Srpaulo if (arg == 1) { 506281806Srpaulo char **res = os_calloc(num_fields + 1, sizeof(char *)); 507281806Srpaulo if (res == NULL) 508281806Srpaulo return NULL; 509281806Srpaulo for (i = 0; i < num_fields; i++) { 510281806Srpaulo res[i] = os_strdup(fields[i]); 511281806Srpaulo if (res[i] == NULL) 512281806Srpaulo return res; 513281806Srpaulo } 514281806Srpaulo return res; 515189251Ssam } 516189251Ssam 517281806Srpaulo if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0) 518281806Srpaulo return cli_txt_list_array(&bsses); 519281806Srpaulo 520281806Srpaulo return NULL; 521189251Ssam} 522189251Ssam 523281806Srpaulostatic int wpa_cli_cmd_dump(struct wpa_ctrl *ctrl, int argc, char *argv[]) 524281806Srpaulo{ 525281806Srpaulo return wpa_ctrl_command(ctrl, "DUMP"); 526281806Srpaulo} 527189251Ssam 528281806Srpaulo 529337817Scystatic int wpa_cli_cmd_driver_flags(struct wpa_ctrl *ctrl, int argc, 530337817Scy char *argv[]) 531337817Scy{ 532337817Scy return wpa_ctrl_command(ctrl, "DRIVER_FLAGS"); 533337817Scy} 534337817Scy 535337817Scy 536252726Srpaulostatic int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) 537252726Srpaulo{ 538252726Srpaulo return wpa_cli_cmd(ctrl, "GET", 1, argc, argv); 539252726Srpaulo} 540252726Srpaulo 541252726Srpaulo 542289549Srpaulostatic char ** wpa_cli_complete_get(const char *str, int pos) 543289549Srpaulo{ 544289549Srpaulo int arg = get_cmd_arg_num(str, pos); 545289549Srpaulo const char *fields[] = { 546289549Srpaulo#ifdef CONFIG_CTRL_IFACE 547289549Srpaulo "ctrl_interface", "ctrl_interface_group", 548289549Srpaulo#endif /* CONFIG_CTRL_IFACE */ 549289549Srpaulo "eapol_version", "ap_scan", 550289549Srpaulo#ifdef CONFIG_MESH 551289549Srpaulo "user_mpm", "max_peer_links", "mesh_max_inactivity", 552289549Srpaulo#endif /* CONFIG_MESH */ 553289549Srpaulo "disable_scan_offload", "fast_reauth", "opensc_engine_path", 554289549Srpaulo "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers", 555289549Srpaulo "pcsc_reader", "pcsc_pin", "external_sim", "driver_param", 556289549Srpaulo "dot11RSNAConfigPMKLifetime", 557289549Srpaulo "dot11RSNAConfigPMKReauthThreshold", 558289549Srpaulo "dot11RSNAConfigSATimeout", 559289549Srpaulo#ifndef CONFIG_NO_CONFIG_WRITE 560289549Srpaulo "update_config", 561289549Srpaulo#endif /* CONFIG_NO_CONFIG_WRITE */ 562289549Srpaulo#ifdef CONFIG_WPS 563289549Srpaulo "device_name", "manufacturer", "model_name", "model_number", 564289549Srpaulo "serial_number", "config_methods", "wps_cred_processing", 565289549Srpaulo#endif /* CONFIG_WPS */ 566289549Srpaulo#ifdef CONFIG_P2P 567289549Srpaulo "p2p_listen_reg_class", "p2p_listen_channel", 568289549Srpaulo "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent", 569289549Srpaulo "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss", 570289549Srpaulo "p2p_group_idle", "p2p_passphrase_len", "p2p_add_cli_chan", 571289549Srpaulo "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht", 572289549Srpaulo "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface", 573289549Srpaulo "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask", 574289549Srpaulo "ip_addr_start", "ip_addr_end", 575289549Srpaulo#endif /* CONFIG_P2P */ 576289549Srpaulo "bss_max_count", "bss_expiration_age", 577289549Srpaulo "bss_expiration_scan_count", "filter_ssids", "filter_rssi", 578346981Scy "max_num_sta", "disassoc_low_ack", "ap_isolate", 579289549Srpaulo#ifdef CONFIG_HS20 580289549Srpaulo "hs20", 581289549Srpaulo#endif /* CONFIG_HS20 */ 582289549Srpaulo "interworking", "access_network_type", "pbc_in_m1", "autoscan", 583346981Scy "go_interworking", "go_access_network_type", "go_internet", 584346981Scy "go_venue_group", "go_venue_type", 585289549Srpaulo "wps_nfc_dev_pw_id", "ext_password_backend", 586289549Srpaulo "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf", 587289549Srpaulo "dtim_period", "beacon_int", "ignore_old_scan_res", 588289549Srpaulo "scan_cur_freq", "sched_scan_interval", 589346981Scy "sched_scan_start_delay", 590289549Srpaulo "tdls_external_control", "osu_dir", "wowlan_triggers", 591289549Srpaulo "p2p_search_delay", "mac_addr", "rand_addr_lifetime", 592289549Srpaulo "preassoc_mac_addr", "key_mgmt_offload", "passive_scan", 593289549Srpaulo "reassoc_same_bss_optim" 594289549Srpaulo }; 595289549Srpaulo int i, num_fields = ARRAY_SIZE(fields); 596289549Srpaulo 597289549Srpaulo if (arg == 1) { 598289549Srpaulo char **res = os_calloc(num_fields + 1, sizeof(char *)); 599289549Srpaulo if (res == NULL) 600289549Srpaulo return NULL; 601289549Srpaulo for (i = 0; i < num_fields; i++) { 602289549Srpaulo res[i] = os_strdup(fields[i]); 603289549Srpaulo if (res[i] == NULL) 604289549Srpaulo return res; 605289549Srpaulo } 606289549Srpaulo return res; 607289549Srpaulo } 608289549Srpaulo 609289549Srpaulo return NULL; 610289549Srpaulo} 611289549Srpaulo 612289549Srpaulo 613189251Ssamstatic int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[]) 614189251Ssam{ 615189251Ssam return wpa_ctrl_command(ctrl, "LOGOFF"); 616189251Ssam} 617189251Ssam 618189251Ssam 619189251Ssamstatic int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[]) 620189251Ssam{ 621189251Ssam return wpa_ctrl_command(ctrl, "LOGON"); 622189251Ssam} 623189251Ssam 624189251Ssam 625189251Ssamstatic int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc, 626189251Ssam char *argv[]) 627189251Ssam{ 628189251Ssam return wpa_ctrl_command(ctrl, "REASSOCIATE"); 629189251Ssam} 630189251Ssam 631189251Ssam 632281806Srpaulostatic int wpa_cli_cmd_reattach(struct wpa_ctrl *ctrl, int argc, char *argv[]) 633281806Srpaulo{ 634281806Srpaulo return wpa_ctrl_command(ctrl, "REATTACH"); 635281806Srpaulo} 636281806Srpaulo 637281806Srpaulo 638189251Ssamstatic int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc, 639189251Ssam char *argv[]) 640189251Ssam{ 641252726Srpaulo return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv); 642252726Srpaulo} 643189251Ssam 644189251Ssam 645252726Srpaulostatic int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 646252726Srpaulo{ 647252726Srpaulo return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv); 648189251Ssam} 649189251Ssam 650189251Ssam 651252726Srpaulostatic int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc, 652252726Srpaulo char *argv[]) 653189251Ssam{ 654252726Srpaulo return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv); 655252726Srpaulo} 656252726Srpaulo 657252726Srpaulo 658252726Srpaulostatic int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc, 659252726Srpaulo char *argv[]) 660252726Srpaulo{ 661252726Srpaulo return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv); 662252726Srpaulo} 663252726Srpaulo 664252726Srpaulo 665252726Srpaulostatic int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc, 666252726Srpaulo char *argv[]) 667252726Srpaulo{ 668252726Srpaulo return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv); 669252726Srpaulo} 670252726Srpaulo 671252726Srpaulo 672252726Srpaulostatic int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 673252726Srpaulo{ 674189251Ssam char cmd[256]; 675189251Ssam int res; 676189251Ssam 677252726Srpaulo if (argc < 1) 678252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0"); 679252726Srpaulo else 680252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]); 681281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) { 682252726Srpaulo printf("Too long BSS_FLUSH command.\n"); 683189251Ssam return -1; 684189251Ssam } 685189251Ssam return wpa_ctrl_command(ctrl, cmd); 686189251Ssam} 687189251Ssam 688189251Ssam 689252726Srpaulostatic int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[]) 690252726Srpaulo{ 691252726Srpaulo return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv); 692252726Srpaulo} 693252726Srpaulo 694252726Srpaulo 695252726Srpaulostatic int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[]) 696252726Srpaulo{ 697252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv); 698252726Srpaulo} 699252726Srpaulo 700252726Srpaulo 701252726Srpaulostatic int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) 702252726Srpaulo{ 703252726Srpaulo if (argc == 0) { 704252726Srpaulo printf("Invalid WPS_PIN command: need one or two arguments:\n" 705252726Srpaulo "- BSSID: use 'any' to select any\n" 706252726Srpaulo "- PIN: optional, used only with devices that have no " 707252726Srpaulo "display\n"); 708189251Ssam return -1; 709189251Ssam } 710189251Ssam 711252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv); 712189251Ssam} 713189251Ssam 714189251Ssam 715252726Srpaulostatic int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc, 716252726Srpaulo char *argv[]) 717189251Ssam{ 718252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv); 719252726Srpaulo} 720189251Ssam 721252726Srpaulo 722252726Srpaulostatic int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc, 723252726Srpaulo char *argv[]) 724252726Srpaulo{ 725252726Srpaulo return wpa_ctrl_command(ctrl, "WPS_CANCEL"); 726252726Srpaulo} 727252726Srpaulo 728252726Srpaulo 729252726Srpaulo#ifdef CONFIG_WPS_NFC 730252726Srpaulo 731252726Srpaulostatic int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[]) 732252726Srpaulo{ 733252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv); 734252726Srpaulo} 735252726Srpaulo 736252726Srpaulo 737281806Srpaulostatic int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc, 738281806Srpaulo char *argv[]) 739281806Srpaulo{ 740281806Srpaulo return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv); 741281806Srpaulo} 742281806Srpaulo 743281806Srpaulo 744252726Srpaulostatic int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc, 745252726Srpaulo char *argv[]) 746252726Srpaulo{ 747252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv); 748252726Srpaulo} 749252726Srpaulo 750252726Srpaulo 751252726Srpaulostatic int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc, 752252726Srpaulo char *argv[]) 753252726Srpaulo{ 754252726Srpaulo int ret; 755252726Srpaulo char *buf; 756252726Srpaulo size_t buflen; 757252726Srpaulo 758189251Ssam if (argc != 1) { 759252726Srpaulo printf("Invalid 'wps_nfc_tag_read' command - one argument " 760252726Srpaulo "is required.\n"); 761189251Ssam return -1; 762189251Ssam } 763189251Ssam 764252726Srpaulo buflen = 18 + os_strlen(argv[0]); 765252726Srpaulo buf = os_malloc(buflen); 766252726Srpaulo if (buf == NULL) 767189251Ssam return -1; 768252726Srpaulo os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]); 769252726Srpaulo 770252726Srpaulo ret = wpa_ctrl_command(ctrl, buf); 771252726Srpaulo os_free(buf); 772252726Srpaulo 773252726Srpaulo return ret; 774189251Ssam} 775189251Ssam 776189251Ssam 777252726Srpaulostatic int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc, 778252726Srpaulo char *argv[]) 779189251Ssam{ 780252726Srpaulo return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv); 781252726Srpaulo} 782189251Ssam 783189251Ssam 784252726Srpaulostatic int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc, 785252726Srpaulo char *argv[]) 786252726Srpaulo{ 787252726Srpaulo return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv); 788189251Ssam} 789189251Ssam 790189251Ssam 791281806Srpaulostatic int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc, 792252726Srpaulo char *argv[]) 793189251Ssam{ 794281806Srpaulo return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv); 795189251Ssam} 796189251Ssam 797252726Srpaulo#endif /* CONFIG_WPS_NFC */ 798214734Srpaulo 799252726Srpaulo 800189251Ssamstatic int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[]) 801189251Ssam{ 802189251Ssam char cmd[256]; 803189251Ssam int res; 804189251Ssam 805214734Srpaulo if (argc == 2) 806214734Srpaulo res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s", 807214734Srpaulo argv[0], argv[1]); 808252726Srpaulo else if (argc == 5 || argc == 6) { 809289549Srpaulo char ssid_hex[2 * SSID_MAX_LEN + 1]; 810214734Srpaulo char key_hex[2 * 64 + 1]; 811214734Srpaulo int i; 812214734Srpaulo 813214734Srpaulo ssid_hex[0] = '\0'; 814289549Srpaulo for (i = 0; i < SSID_MAX_LEN; i++) { 815214734Srpaulo if (argv[2][i] == '\0') 816214734Srpaulo break; 817214734Srpaulo os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]); 818214734Srpaulo } 819214734Srpaulo 820214734Srpaulo key_hex[0] = '\0'; 821252726Srpaulo if (argc == 6) { 822252726Srpaulo for (i = 0; i < 64; i++) { 823252726Srpaulo if (argv[5][i] == '\0') 824252726Srpaulo break; 825252726Srpaulo os_snprintf(&key_hex[i * 2], 3, "%02x", 826252726Srpaulo argv[5][i]); 827252726Srpaulo } 828214734Srpaulo } 829214734Srpaulo 830214734Srpaulo res = os_snprintf(cmd, sizeof(cmd), 831214734Srpaulo "WPS_REG %s %s %s %s %s %s", 832214734Srpaulo argv[0], argv[1], ssid_hex, argv[3], argv[4], 833214734Srpaulo key_hex); 834214734Srpaulo } else { 835189251Ssam printf("Invalid WPS_REG command: need two arguments:\n" 836252726Srpaulo "- BSSID of the target AP\n" 837189251Ssam "- AP PIN\n"); 838214734Srpaulo printf("Alternatively, six arguments can be used to " 839214734Srpaulo "reconfigure the AP:\n" 840252726Srpaulo "- BSSID of the target AP\n" 841214734Srpaulo "- AP PIN\n" 842214734Srpaulo "- new SSID\n" 843214734Srpaulo "- new auth (OPEN, WPAPSK, WPA2PSK)\n" 844214734Srpaulo "- new encr (NONE, WEP, TKIP, CCMP)\n" 845214734Srpaulo "- new key\n"); 846189251Ssam return -1; 847189251Ssam } 848189251Ssam 849281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) { 850189251Ssam printf("Too long WPS_REG command.\n"); 851189251Ssam return -1; 852189251Ssam } 853189251Ssam return wpa_ctrl_command(ctrl, cmd); 854189251Ssam} 855189251Ssam 856189251Ssam 857252726Srpaulostatic int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc, 858252726Srpaulo char *argv[]) 859252726Srpaulo{ 860252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv); 861252726Srpaulo} 862252726Srpaulo 863252726Srpaulo 864214734Srpaulostatic int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc, 865214734Srpaulo char *argv[]) 866214734Srpaulo{ 867252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv); 868214734Srpaulo} 869214734Srpaulo 870214734Srpaulo 871214734Srpaulostatic int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc, 872214734Srpaulo char *argv[]) 873214734Srpaulo{ 874214734Srpaulo return wpa_ctrl_command(ctrl, "WPS_ER_STOP"); 875214734Srpaulo 876214734Srpaulo} 877214734Srpaulo 878214734Srpaulo 879214734Srpaulostatic int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc, 880214734Srpaulo char *argv[]) 881214734Srpaulo{ 882252726Srpaulo if (argc < 2) { 883252726Srpaulo printf("Invalid WPS_ER_PIN command: need at least two " 884252726Srpaulo "arguments:\n" 885214734Srpaulo "- UUID: use 'any' to select any\n" 886252726Srpaulo "- PIN: Enrollee PIN\n" 887252726Srpaulo "optional: - Enrollee MAC address\n"); 888214734Srpaulo return -1; 889214734Srpaulo } 890214734Srpaulo 891252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv); 892214734Srpaulo} 893214734Srpaulo 894214734Srpaulo 895214734Srpaulostatic int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc, 896214734Srpaulo char *argv[]) 897214734Srpaulo{ 898252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv); 899214734Srpaulo} 900214734Srpaulo 901214734Srpaulo 902214734Srpaulostatic int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc, 903214734Srpaulo char *argv[]) 904214734Srpaulo{ 905214734Srpaulo if (argc != 2) { 906214734Srpaulo printf("Invalid WPS_ER_LEARN command: need two arguments:\n" 907214734Srpaulo "- UUID: specify which AP to use\n" 908214734Srpaulo "- PIN: AP PIN\n"); 909214734Srpaulo return -1; 910214734Srpaulo } 911214734Srpaulo 912252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv); 913252726Srpaulo} 914252726Srpaulo 915252726Srpaulo 916252726Srpaulostatic int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc, 917252726Srpaulo char *argv[]) 918252726Srpaulo{ 919252726Srpaulo if (argc != 2) { 920252726Srpaulo printf("Invalid WPS_ER_SET_CONFIG command: need two " 921252726Srpaulo "arguments:\n" 922252726Srpaulo "- UUID: specify which AP to use\n" 923252726Srpaulo "- Network configuration id\n"); 924214734Srpaulo return -1; 925214734Srpaulo } 926252726Srpaulo 927252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv); 928214734Srpaulo} 929214734Srpaulo 930214734Srpaulo 931252726Srpaulostatic int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc, 932252726Srpaulo char *argv[]) 933214734Srpaulo{ 934214734Srpaulo char cmd[256]; 935214734Srpaulo int res; 936214734Srpaulo 937252726Srpaulo if (argc == 5 || argc == 6) { 938289549Srpaulo char ssid_hex[2 * SSID_MAX_LEN + 1]; 939252726Srpaulo char key_hex[2 * 64 + 1]; 940252726Srpaulo int i; 941252726Srpaulo 942252726Srpaulo ssid_hex[0] = '\0'; 943289549Srpaulo for (i = 0; i < SSID_MAX_LEN; i++) { 944252726Srpaulo if (argv[2][i] == '\0') 945252726Srpaulo break; 946252726Srpaulo os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]); 947252726Srpaulo } 948252726Srpaulo 949252726Srpaulo key_hex[0] = '\0'; 950252726Srpaulo if (argc == 6) { 951252726Srpaulo for (i = 0; i < 64; i++) { 952252726Srpaulo if (argv[5][i] == '\0') 953252726Srpaulo break; 954252726Srpaulo os_snprintf(&key_hex[i * 2], 3, "%02x", 955252726Srpaulo argv[5][i]); 956252726Srpaulo } 957252726Srpaulo } 958252726Srpaulo 959252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), 960252726Srpaulo "WPS_ER_CONFIG %s %s %s %s %s %s", 961252726Srpaulo argv[0], argv[1], ssid_hex, argv[3], argv[4], 962252726Srpaulo key_hex); 963252726Srpaulo } else { 964252726Srpaulo printf("Invalid WPS_ER_CONFIG command: need six arguments:\n" 965252726Srpaulo "- AP UUID\n" 966252726Srpaulo "- AP PIN\n" 967252726Srpaulo "- new SSID\n" 968252726Srpaulo "- new auth (OPEN, WPAPSK, WPA2PSK)\n" 969252726Srpaulo "- new encr (NONE, WEP, TKIP, CCMP)\n" 970252726Srpaulo "- new key\n"); 971214734Srpaulo return -1; 972214734Srpaulo } 973214734Srpaulo 974281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) { 975252726Srpaulo printf("Too long WPS_ER_CONFIG command.\n"); 976214734Srpaulo return -1; 977214734Srpaulo } 978214734Srpaulo return wpa_ctrl_command(ctrl, cmd); 979214734Srpaulo} 980214734Srpaulo 981214734Srpaulo 982252726Srpaulo#ifdef CONFIG_WPS_NFC 983252726Srpaulostatic int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc, 984252726Srpaulo char *argv[]) 985189251Ssam{ 986252726Srpaulo if (argc != 2) { 987252726Srpaulo printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two " 988252726Srpaulo "arguments:\n" 989252726Srpaulo "- WPS/NDEF: token format\n" 990252726Srpaulo "- UUID: specify which AP to use\n"); 991189251Ssam return -1; 992189251Ssam } 993252726Srpaulo 994252726Srpaulo return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv); 995189251Ssam} 996252726Srpaulo#endif /* CONFIG_WPS_NFC */ 997189251Ssam 998189251Ssam 999252726Srpaulostatic int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1000252726Srpaulo{ 1001252726Srpaulo return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv); 1002252726Srpaulo} 1003252726Srpaulo 1004252726Srpaulo 1005252726Srpaulostatic int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1006252726Srpaulo{ 1007252726Srpaulo return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv); 1008252726Srpaulo} 1009252726Srpaulo 1010252726Srpaulo 1011189251Ssamstatic int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1012189251Ssam{ 1013189251Ssam char cmd[256], *pos, *end; 1014189251Ssam int i, ret; 1015189251Ssam 1016189251Ssam if (argc < 2) { 1017189251Ssam printf("Invalid IDENTITY command: needs two arguments " 1018189251Ssam "(network id and identity)\n"); 1019189251Ssam return -1; 1020189251Ssam } 1021189251Ssam 1022189251Ssam end = cmd + sizeof(cmd); 1023189251Ssam pos = cmd; 1024189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s", 1025189251Ssam argv[0], argv[1]); 1026281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1027189251Ssam printf("Too long IDENTITY command.\n"); 1028189251Ssam return -1; 1029189251Ssam } 1030189251Ssam pos += ret; 1031189251Ssam for (i = 2; i < argc; i++) { 1032189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1033281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1034189251Ssam printf("Too long IDENTITY command.\n"); 1035189251Ssam return -1; 1036189251Ssam } 1037189251Ssam pos += ret; 1038189251Ssam } 1039189251Ssam 1040189251Ssam return wpa_ctrl_command(ctrl, cmd); 1041189251Ssam} 1042189251Ssam 1043189251Ssam 1044189251Ssamstatic int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1045189251Ssam{ 1046189251Ssam char cmd[256], *pos, *end; 1047189251Ssam int i, ret; 1048189251Ssam 1049189251Ssam if (argc < 2) { 1050189251Ssam printf("Invalid PASSWORD command: needs two arguments " 1051189251Ssam "(network id and password)\n"); 1052189251Ssam return -1; 1053189251Ssam } 1054189251Ssam 1055189251Ssam end = cmd + sizeof(cmd); 1056189251Ssam pos = cmd; 1057189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s", 1058189251Ssam argv[0], argv[1]); 1059281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1060189251Ssam printf("Too long PASSWORD command.\n"); 1061189251Ssam return -1; 1062189251Ssam } 1063189251Ssam pos += ret; 1064189251Ssam for (i = 2; i < argc; i++) { 1065189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1066281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1067189251Ssam printf("Too long PASSWORD command.\n"); 1068189251Ssam return -1; 1069189251Ssam } 1070189251Ssam pos += ret; 1071189251Ssam } 1072189251Ssam 1073189251Ssam return wpa_ctrl_command(ctrl, cmd); 1074189251Ssam} 1075189251Ssam 1076189251Ssam 1077189251Ssamstatic int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc, 1078189251Ssam char *argv[]) 1079189251Ssam{ 1080189251Ssam char cmd[256], *pos, *end; 1081189251Ssam int i, ret; 1082189251Ssam 1083189251Ssam if (argc < 2) { 1084189251Ssam printf("Invalid NEW_PASSWORD command: needs two arguments " 1085189251Ssam "(network id and password)\n"); 1086189251Ssam return -1; 1087189251Ssam } 1088189251Ssam 1089189251Ssam end = cmd + sizeof(cmd); 1090189251Ssam pos = cmd; 1091189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s", 1092189251Ssam argv[0], argv[1]); 1093281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1094189251Ssam printf("Too long NEW_PASSWORD command.\n"); 1095189251Ssam return -1; 1096189251Ssam } 1097189251Ssam pos += ret; 1098189251Ssam for (i = 2; i < argc; i++) { 1099189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1100281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1101189251Ssam printf("Too long NEW_PASSWORD command.\n"); 1102189251Ssam return -1; 1103189251Ssam } 1104189251Ssam pos += ret; 1105189251Ssam } 1106189251Ssam 1107189251Ssam return wpa_ctrl_command(ctrl, cmd); 1108189251Ssam} 1109189251Ssam 1110189251Ssam 1111189251Ssamstatic int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1112189251Ssam{ 1113189251Ssam char cmd[256], *pos, *end; 1114189251Ssam int i, ret; 1115189251Ssam 1116189251Ssam if (argc < 2) { 1117189251Ssam printf("Invalid PIN command: needs two arguments " 1118189251Ssam "(network id and pin)\n"); 1119189251Ssam return -1; 1120189251Ssam } 1121189251Ssam 1122189251Ssam end = cmd + sizeof(cmd); 1123189251Ssam pos = cmd; 1124189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s", 1125189251Ssam argv[0], argv[1]); 1126281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1127189251Ssam printf("Too long PIN command.\n"); 1128189251Ssam return -1; 1129189251Ssam } 1130189251Ssam pos += ret; 1131189251Ssam for (i = 2; i < argc; i++) { 1132189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1133281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1134189251Ssam printf("Too long PIN command.\n"); 1135189251Ssam return -1; 1136189251Ssam } 1137189251Ssam pos += ret; 1138189251Ssam } 1139189251Ssam return wpa_ctrl_command(ctrl, cmd); 1140189251Ssam} 1141189251Ssam 1142189251Ssam 1143189251Ssamstatic int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1144189251Ssam{ 1145189251Ssam char cmd[256], *pos, *end; 1146189251Ssam int i, ret; 1147189251Ssam 1148189251Ssam if (argc < 2) { 1149189251Ssam printf("Invalid OTP command: needs two arguments (network " 1150189251Ssam "id and password)\n"); 1151189251Ssam return -1; 1152189251Ssam } 1153189251Ssam 1154189251Ssam end = cmd + sizeof(cmd); 1155189251Ssam pos = cmd; 1156189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s", 1157189251Ssam argv[0], argv[1]); 1158281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1159189251Ssam printf("Too long OTP command.\n"); 1160189251Ssam return -1; 1161189251Ssam } 1162189251Ssam pos += ret; 1163189251Ssam for (i = 2; i < argc; i++) { 1164189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1165281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1166189251Ssam printf("Too long OTP command.\n"); 1167189251Ssam return -1; 1168189251Ssam } 1169189251Ssam pos += ret; 1170189251Ssam } 1171189251Ssam 1172189251Ssam return wpa_ctrl_command(ctrl, cmd); 1173189251Ssam} 1174189251Ssam 1175189251Ssam 1176281806Srpaulostatic int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1177281806Srpaulo{ 1178281806Srpaulo char cmd[256], *pos, *end; 1179281806Srpaulo int i, ret; 1180281806Srpaulo 1181281806Srpaulo if (argc < 2) { 1182281806Srpaulo printf("Invalid SIM command: needs two arguments " 1183281806Srpaulo "(network id and SIM operation response)\n"); 1184281806Srpaulo return -1; 1185281806Srpaulo } 1186281806Srpaulo 1187281806Srpaulo end = cmd + sizeof(cmd); 1188281806Srpaulo pos = cmd; 1189281806Srpaulo ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s", 1190281806Srpaulo argv[0], argv[1]); 1191281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1192281806Srpaulo printf("Too long SIM command.\n"); 1193281806Srpaulo return -1; 1194281806Srpaulo } 1195281806Srpaulo pos += ret; 1196281806Srpaulo for (i = 2; i < argc; i++) { 1197281806Srpaulo ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1198281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1199281806Srpaulo printf("Too long SIM command.\n"); 1200281806Srpaulo return -1; 1201281806Srpaulo } 1202281806Srpaulo pos += ret; 1203281806Srpaulo } 1204281806Srpaulo return wpa_ctrl_command(ctrl, cmd); 1205281806Srpaulo} 1206281806Srpaulo 1207281806Srpaulo 1208346981Scystatic int wpa_cli_cmd_psk_passphrase(struct wpa_ctrl *ctrl, int argc, 1209346981Scy char *argv[]) 1210346981Scy{ 1211346981Scy char cmd[256], *pos, *end; 1212346981Scy int i, ret; 1213346981Scy 1214346981Scy if (argc < 2) { 1215346981Scy printf("Invalid PSK_PASSPHRASE command: needs two arguments (network id and PSK/passphrase)\n"); 1216346981Scy return -1; 1217346981Scy } 1218346981Scy 1219346981Scy end = cmd + sizeof(cmd); 1220346981Scy pos = cmd; 1221346981Scy ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PSK_PASSPHRASE-%s:%s", 1222346981Scy argv[0], argv[1]); 1223346981Scy if (os_snprintf_error(end - pos, ret)) { 1224346981Scy printf("Too long PSK_PASSPHRASE command.\n"); 1225346981Scy return -1; 1226346981Scy } 1227346981Scy pos += ret; 1228346981Scy for (i = 2; i < argc; i++) { 1229346981Scy ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1230346981Scy if (os_snprintf_error(end - pos, ret)) { 1231346981Scy printf("Too long PSK_PASSPHRASE command.\n"); 1232346981Scy return -1; 1233346981Scy } 1234346981Scy pos += ret; 1235346981Scy } 1236346981Scy 1237346981Scy return wpa_ctrl_command(ctrl, cmd); 1238346981Scy} 1239346981Scy 1240346981Scy 1241189251Ssamstatic int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc, 1242189251Ssam char *argv[]) 1243189251Ssam{ 1244189251Ssam char cmd[256], *pos, *end; 1245189251Ssam int i, ret; 1246189251Ssam 1247189251Ssam if (argc < 2) { 1248189251Ssam printf("Invalid PASSPHRASE command: needs two arguments " 1249189251Ssam "(network id and passphrase)\n"); 1250189251Ssam return -1; 1251189251Ssam } 1252189251Ssam 1253189251Ssam end = cmd + sizeof(cmd); 1254189251Ssam pos = cmd; 1255189251Ssam ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s", 1256189251Ssam argv[0], argv[1]); 1257281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1258189251Ssam printf("Too long PASSPHRASE command.\n"); 1259189251Ssam return -1; 1260189251Ssam } 1261189251Ssam pos += ret; 1262189251Ssam for (i = 2; i < argc; i++) { 1263189251Ssam ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1264281806Srpaulo if (os_snprintf_error(end - pos, ret)) { 1265189251Ssam printf("Too long PASSPHRASE command.\n"); 1266189251Ssam return -1; 1267189251Ssam } 1268189251Ssam pos += ret; 1269189251Ssam } 1270189251Ssam 1271189251Ssam return wpa_ctrl_command(ctrl, cmd); 1272189251Ssam} 1273189251Ssam 1274189251Ssam 1275189251Ssamstatic int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1276189251Ssam{ 1277189251Ssam if (argc < 2) { 1278189251Ssam printf("Invalid BSSID command: needs two arguments (network " 1279189251Ssam "id and BSSID)\n"); 1280189251Ssam return -1; 1281189251Ssam } 1282189251Ssam 1283252726Srpaulo return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv); 1284252726Srpaulo} 1285189251Ssam 1286252726Srpaulo 1287252726Srpaulostatic int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1288252726Srpaulo{ 1289252726Srpaulo return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv); 1290189251Ssam} 1291189251Ssam 1292189251Ssam 1293252726Srpaulostatic int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1294252726Srpaulo{ 1295252726Srpaulo return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv); 1296252726Srpaulo} 1297252726Srpaulo 1298252726Srpaulo 1299189251Ssamstatic int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc, 1300189251Ssam char *argv[]) 1301189251Ssam{ 1302189251Ssam return wpa_ctrl_command(ctrl, "LIST_NETWORKS"); 1303189251Ssam} 1304189251Ssam 1305189251Ssam 1306189251Ssamstatic int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc, 1307189251Ssam char *argv[]) 1308189251Ssam{ 1309252726Srpaulo return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv); 1310189251Ssam} 1311189251Ssam 1312189251Ssam 1313189251Ssamstatic int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc, 1314189251Ssam char *argv[]) 1315189251Ssam{ 1316252726Srpaulo return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv); 1317189251Ssam} 1318189251Ssam 1319189251Ssam 1320189251Ssamstatic int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc, 1321189251Ssam char *argv[]) 1322189251Ssam{ 1323252726Srpaulo return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv); 1324189251Ssam} 1325189251Ssam 1326189251Ssam 1327189251Ssamstatic int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc, 1328189251Ssam char *argv[]) 1329189251Ssam{ 1330289549Srpaulo int res = wpa_ctrl_command(ctrl, "ADD_NETWORK"); 1331289549Srpaulo if (interactive) 1332289549Srpaulo update_networks(ctrl); 1333289549Srpaulo return res; 1334189251Ssam} 1335189251Ssam 1336189251Ssam 1337189251Ssamstatic int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc, 1338189251Ssam char *argv[]) 1339189251Ssam{ 1340289549Srpaulo int res = wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv); 1341289549Srpaulo if (interactive) 1342289549Srpaulo update_networks(ctrl); 1343289549Srpaulo return res; 1344189251Ssam} 1345189251Ssam 1346189251Ssam 1347189251Ssamstatic void wpa_cli_show_network_variables(void) 1348189251Ssam{ 1349189251Ssam printf("set_network variables:\n" 1350189251Ssam " ssid (network name, SSID)\n" 1351189251Ssam " psk (WPA passphrase or pre-shared key)\n" 1352189251Ssam " key_mgmt (key management protocol)\n" 1353189251Ssam " identity (EAP identity)\n" 1354189251Ssam " password (EAP password)\n" 1355189251Ssam " ...\n" 1356189251Ssam "\n" 1357189251Ssam "Note: Values are entered in the same format as the " 1358189251Ssam "configuration file is using,\n" 1359189251Ssam "i.e., strings values need to be inside double quotation " 1360189251Ssam "marks.\n" 1361189251Ssam "For example: set_network 1 ssid \"network name\"\n" 1362189251Ssam "\n" 1363189251Ssam "Please see wpa_supplicant.conf documentation for full list " 1364189251Ssam "of\navailable variables.\n"); 1365189251Ssam} 1366189251Ssam 1367189251Ssam 1368189251Ssamstatic int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc, 1369189251Ssam char *argv[]) 1370189251Ssam{ 1371189251Ssam if (argc == 0) { 1372189251Ssam wpa_cli_show_network_variables(); 1373189251Ssam return 0; 1374189251Ssam } 1375189251Ssam 1376252726Srpaulo if (argc < 3) { 1377189251Ssam printf("Invalid SET_NETWORK command: needs three arguments\n" 1378189251Ssam "(network id, variable name, and value)\n"); 1379189251Ssam return -1; 1380189251Ssam } 1381189251Ssam 1382252726Srpaulo return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv); 1383189251Ssam} 1384189251Ssam 1385189251Ssam 1386189251Ssamstatic int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc, 1387189251Ssam char *argv[]) 1388189251Ssam{ 1389189251Ssam if (argc == 0) { 1390189251Ssam wpa_cli_show_network_variables(); 1391189251Ssam return 0; 1392189251Ssam } 1393189251Ssam 1394189251Ssam if (argc != 2) { 1395189251Ssam printf("Invalid GET_NETWORK command: needs two arguments\n" 1396189251Ssam "(network id and variable name)\n"); 1397189251Ssam return -1; 1398189251Ssam } 1399189251Ssam 1400252726Srpaulo return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv); 1401252726Srpaulo} 1402252726Srpaulo 1403252726Srpaulo 1404289549Srpaulostatic const char *network_fields[] = { 1405289549Srpaulo "ssid", "scan_ssid", "bssid", "bssid_blacklist", 1406289549Srpaulo "bssid_whitelist", "psk", "proto", "key_mgmt", 1407289549Srpaulo "bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq", 1408346981Scy "freq_list", "max_oper_chwidth", "ht40", "vht", "vht_center_freq1", 1409346981Scy "vht_center_freq2", "ht", 1410289549Srpaulo#ifdef IEEE8021X_EAPOL 1411289549Srpaulo "eap", "identity", "anonymous_identity", "password", "ca_cert", 1412289549Srpaulo "ca_path", "client_cert", "private_key", "private_key_passwd", 1413289549Srpaulo "dh_file", "subject_match", "altsubject_match", 1414346981Scy "check_cert_subject", 1415289549Srpaulo "domain_suffix_match", "domain_match", "ca_cert2", "ca_path2", 1416289549Srpaulo "client_cert2", "private_key2", "private_key2_passwd", 1417289549Srpaulo "dh_file2", "subject_match2", "altsubject_match2", 1418346981Scy "check_cert_subject2", 1419289549Srpaulo "domain_suffix_match2", "domain_match2", "phase1", "phase2", 1420289549Srpaulo "pcsc", "pin", "engine_id", "key_id", "cert_id", "ca_cert_id", 1421289549Srpaulo "pin2", "engine2_id", "key2_id", "cert2_id", "ca_cert2_id", 1422289549Srpaulo "engine", "engine2", "eapol_flags", "sim_num", 1423289549Srpaulo "openssl_ciphers", "erp", 1424289549Srpaulo#endif /* IEEE8021X_EAPOL */ 1425289549Srpaulo "wep_key0", "wep_key1", "wep_key2", "wep_key3", 1426289549Srpaulo "wep_tx_keyidx", "priority", 1427289549Srpaulo#ifdef IEEE8021X_EAPOL 1428289549Srpaulo "eap_workaround", "pac_file", "fragment_size", "ocsp", 1429289549Srpaulo#endif /* IEEE8021X_EAPOL */ 1430289549Srpaulo#ifdef CONFIG_MESH 1431346981Scy "mode", "no_auto_peer", "mesh_rssi_threshold", 1432289549Srpaulo#else /* CONFIG_MESH */ 1433289549Srpaulo "mode", 1434289549Srpaulo#endif /* CONFIG_MESH */ 1435289549Srpaulo "proactive_key_caching", "disabled", "id_str", 1436289549Srpaulo#ifdef CONFIG_IEEE80211W 1437289549Srpaulo "ieee80211w", 1438289549Srpaulo#endif /* CONFIG_IEEE80211W */ 1439346981Scy "mixed_cell", "frequency", "fixed_freq", 1440289549Srpaulo#ifdef CONFIG_MESH 1441289549Srpaulo "mesh_basic_rates", "dot11MeshMaxRetries", 1442289549Srpaulo "dot11MeshRetryTimeout", "dot11MeshConfirmTimeout", 1443289549Srpaulo "dot11MeshHoldingTimeout", 1444289549Srpaulo#endif /* CONFIG_MESH */ 1445289549Srpaulo "wpa_ptk_rekey", "bgscan", "ignore_broadcast_ssid", 1446289549Srpaulo#ifdef CONFIG_P2P 1447289549Srpaulo "go_p2p_dev_addr", "p2p_client_list", "psk_list", 1448289549Srpaulo#endif /* CONFIG_P2P */ 1449289549Srpaulo#ifdef CONFIG_HT_OVERRIDES 1450289549Srpaulo "disable_ht", "disable_ht40", "disable_sgi", "disable_ldpc", 1451289549Srpaulo "ht40_intolerant", "disable_max_amsdu", "ampdu_factor", 1452346981Scy "ampdu_density", "ht_mcs", "rx_stbc", "tx_stbc", 1453289549Srpaulo#endif /* CONFIG_HT_OVERRIDES */ 1454289549Srpaulo#ifdef CONFIG_VHT_OVERRIDES 1455289549Srpaulo "disable_vht", "vht_capa", "vht_capa_mask", "vht_rx_mcs_nss_1", 1456289549Srpaulo "vht_rx_mcs_nss_2", "vht_rx_mcs_nss_3", "vht_rx_mcs_nss_4", 1457289549Srpaulo "vht_rx_mcs_nss_5", "vht_rx_mcs_nss_6", "vht_rx_mcs_nss_7", 1458289549Srpaulo "vht_rx_mcs_nss_8", "vht_tx_mcs_nss_1", "vht_tx_mcs_nss_2", 1459289549Srpaulo "vht_tx_mcs_nss_3", "vht_tx_mcs_nss_4", "vht_tx_mcs_nss_5", 1460289549Srpaulo "vht_tx_mcs_nss_6", "vht_tx_mcs_nss_7", "vht_tx_mcs_nss_8", 1461289549Srpaulo#endif /* CONFIG_VHT_OVERRIDES */ 1462289549Srpaulo "ap_max_inactivity", "dtim_period", "beacon_int", 1463289549Srpaulo#ifdef CONFIG_MACSEC 1464289549Srpaulo "macsec_policy", 1465346981Scy "macsec_integ_only", 1466346981Scy "macsec_replay_protect", 1467346981Scy "macsec_replay_window", 1468346981Scy "macsec_port", 1469346981Scy "mka_priority", 1470289549Srpaulo#endif /* CONFIG_MACSEC */ 1471289549Srpaulo#ifdef CONFIG_HS20 1472289549Srpaulo "update_identifier", 1473289549Srpaulo#endif /* CONFIG_HS20 */ 1474337817Scy "mac_addr", "pbss", "wps_disabled" 1475289549Srpaulo}; 1476289549Srpaulo 1477289549Srpaulo 1478289549Srpaulostatic char ** wpa_cli_complete_network(const char *str, int pos) 1479289549Srpaulo{ 1480289549Srpaulo int arg = get_cmd_arg_num(str, pos); 1481289549Srpaulo int i, num_fields = ARRAY_SIZE(network_fields); 1482289549Srpaulo char **res = NULL; 1483289549Srpaulo 1484289549Srpaulo switch (arg) { 1485289549Srpaulo case 1: 1486289549Srpaulo res = cli_txt_list_array(&networks); 1487289549Srpaulo break; 1488289549Srpaulo case 2: 1489289549Srpaulo res = os_calloc(num_fields + 1, sizeof(char *)); 1490289549Srpaulo if (res == NULL) 1491289549Srpaulo return NULL; 1492289549Srpaulo for (i = 0; i < num_fields; i++) { 1493289549Srpaulo res[i] = os_strdup(network_fields[i]); 1494289549Srpaulo if (res[i] == NULL) 1495289549Srpaulo break; 1496289549Srpaulo } 1497289549Srpaulo } 1498289549Srpaulo return res; 1499289549Srpaulo} 1500289549Srpaulo 1501289549Srpaulo 1502289549Srpaulostatic char ** wpa_cli_complete_network_id(const char *str, int pos) 1503289549Srpaulo{ 1504289549Srpaulo int arg = get_cmd_arg_num(str, pos); 1505289549Srpaulo if (arg == 1) 1506289549Srpaulo return cli_txt_list_array(&networks); 1507289549Srpaulo return NULL; 1508289549Srpaulo} 1509289549Srpaulo 1510289549Srpaulo 1511281806Srpaulostatic int wpa_cli_cmd_dup_network(struct wpa_ctrl *ctrl, int argc, 1512281806Srpaulo char *argv[]) 1513281806Srpaulo{ 1514281806Srpaulo if (argc == 0) { 1515281806Srpaulo wpa_cli_show_network_variables(); 1516281806Srpaulo return 0; 1517281806Srpaulo } 1518281806Srpaulo 1519281806Srpaulo if (argc < 3) { 1520281806Srpaulo printf("Invalid DUP_NETWORK command: needs three arguments\n" 1521281806Srpaulo "(src netid, dest netid, and variable name)\n"); 1522281806Srpaulo return -1; 1523281806Srpaulo } 1524281806Srpaulo 1525281806Srpaulo return wpa_cli_cmd(ctrl, "DUP_NETWORK", 3, argc, argv); 1526281806Srpaulo} 1527281806Srpaulo 1528281806Srpaulo 1529289549Srpaulostatic char ** wpa_cli_complete_dup_network(const char *str, int pos) 1530289549Srpaulo{ 1531289549Srpaulo int arg = get_cmd_arg_num(str, pos); 1532289549Srpaulo int i, num_fields = ARRAY_SIZE(network_fields); 1533289549Srpaulo char **res = NULL; 1534289549Srpaulo 1535289549Srpaulo switch (arg) { 1536289549Srpaulo case 1: 1537289549Srpaulo case 2: 1538289549Srpaulo res = cli_txt_list_array(&networks); 1539289549Srpaulo break; 1540289549Srpaulo case 3: 1541289549Srpaulo res = os_calloc(num_fields + 1, sizeof(char *)); 1542289549Srpaulo if (res == NULL) 1543289549Srpaulo return NULL; 1544289549Srpaulo for (i = 0; i < num_fields; i++) { 1545289549Srpaulo res[i] = os_strdup(network_fields[i]); 1546289549Srpaulo if (res[i] == NULL) 1547289549Srpaulo break; 1548289549Srpaulo } 1549289549Srpaulo } 1550289549Srpaulo return res; 1551289549Srpaulo} 1552289549Srpaulo 1553289549Srpaulo 1554252726Srpaulostatic int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc, 1555252726Srpaulo char *argv[]) 1556252726Srpaulo{ 1557252726Srpaulo return wpa_ctrl_command(ctrl, "LIST_CREDS"); 1558252726Srpaulo} 1559252726Srpaulo 1560252726Srpaulo 1561252726Srpaulostatic int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1562252726Srpaulo{ 1563346981Scy int res = wpa_ctrl_command(ctrl, "ADD_CRED"); 1564346981Scy if (interactive) 1565346981Scy update_creds(ctrl); 1566346981Scy return res; 1567252726Srpaulo} 1568252726Srpaulo 1569252726Srpaulo 1570252726Srpaulostatic int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc, 1571252726Srpaulo char *argv[]) 1572252726Srpaulo{ 1573346981Scy int res = wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv); 1574346981Scy if (interactive) 1575346981Scy update_creds(ctrl); 1576346981Scy return res; 1577252726Srpaulo} 1578252726Srpaulo 1579252726Srpaulo 1580346981Scystatic const char * const cred_fields[] = { 1581346981Scy "temporary", "priority", "sp_priority", "pcsc", "eap", 1582346981Scy "update_identifier", "min_dl_bandwidth_home", "min_ul_bandwidth_home", 1583346981Scy "min_dl_bandwidth_roaming", "min_ul_bandwidth_roaming", "max_bss_load", 1584346981Scy "req_conn_capab", "ocsp", "sim_num", "realm", "username", "password", 1585346981Scy "ca_cert", "client_cert", "private_key", "private_key_passwd", "imsi", 1586346981Scy "milenage", "domain_suffix_match", "domain", "phase1", "phase2", 1587346981Scy "roaming_consortium", "required_roaming_consortium", "excluded_ssid", 1588346981Scy "roaming_partner", "provisioning_sp" 1589346981Scy}; 1590346981Scy 1591346981Scy 1592346981Scystatic char ** wpa_cli_complete_cred(const char *str, int pos) 1593346981Scy{ 1594346981Scy int arg = get_cmd_arg_num(str, pos); 1595346981Scy int i, num_fields = ARRAY_SIZE(cred_fields); 1596346981Scy char **res = NULL; 1597346981Scy 1598346981Scy switch (arg) { 1599346981Scy case 1: 1600346981Scy res = cli_txt_list_array(&creds); 1601346981Scy break; 1602346981Scy case 2: 1603346981Scy res = os_calloc(num_fields + 1, sizeof(char *)); 1604346981Scy if (res == NULL) 1605346981Scy return NULL; 1606346981Scy for (i = 0; i < num_fields; i++) { 1607346981Scy res[i] = os_strdup(cred_fields[i]); 1608346981Scy if (res[i] == NULL) 1609346981Scy break; 1610346981Scy } 1611346981Scy } 1612346981Scy return res; 1613346981Scy} 1614346981Scy 1615346981Scy 1616252726Srpaulostatic int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1617252726Srpaulo{ 1618252726Srpaulo if (argc != 3) { 1619252726Srpaulo printf("Invalid SET_CRED command: needs three arguments\n" 1620252726Srpaulo "(cred id, variable name, and value)\n"); 1621189251Ssam return -1; 1622189251Ssam } 1623252726Srpaulo 1624252726Srpaulo return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv); 1625189251Ssam} 1626189251Ssam 1627189251Ssam 1628281806Srpaulostatic int wpa_cli_cmd_get_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1629281806Srpaulo{ 1630281806Srpaulo if (argc != 2) { 1631281806Srpaulo printf("Invalid GET_CRED command: needs two arguments\n" 1632281806Srpaulo "(cred id, variable name)\n"); 1633281806Srpaulo return -1; 1634281806Srpaulo } 1635281806Srpaulo 1636281806Srpaulo return wpa_cli_cmd(ctrl, "GET_CRED", 2, argc, argv); 1637281806Srpaulo} 1638281806Srpaulo 1639281806Srpaulo 1640189251Ssamstatic int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc, 1641189251Ssam char *argv[]) 1642189251Ssam{ 1643189251Ssam return wpa_ctrl_command(ctrl, "DISCONNECT"); 1644189251Ssam} 1645189251Ssam 1646189251Ssam 1647189251Ssamstatic int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc, 1648189251Ssam char *argv[]) 1649189251Ssam{ 1650189251Ssam return wpa_ctrl_command(ctrl, "RECONNECT"); 1651189251Ssam} 1652189251Ssam 1653189251Ssam 1654189251Ssamstatic int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc, 1655189251Ssam char *argv[]) 1656189251Ssam{ 1657189251Ssam return wpa_ctrl_command(ctrl, "SAVE_CONFIG"); 1658189251Ssam} 1659189251Ssam 1660189251Ssam 1661189251Ssamstatic int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1662189251Ssam{ 1663281806Srpaulo return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv); 1664189251Ssam} 1665189251Ssam 1666189251Ssam 1667189251Ssamstatic int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc, 1668189251Ssam char *argv[]) 1669189251Ssam{ 1670189251Ssam return wpa_ctrl_command(ctrl, "SCAN_RESULTS"); 1671189251Ssam} 1672189251Ssam 1673189251Ssam 1674337817Scystatic int wpa_cli_cmd_abort_scan(struct wpa_ctrl *ctrl, int argc, 1675337817Scy char *argv[]) 1676337817Scy{ 1677337817Scy return wpa_ctrl_command(ctrl, "ABORT_SCAN"); 1678337817Scy} 1679337817Scy 1680337817Scy 1681189251Ssamstatic int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1682189251Ssam{ 1683252726Srpaulo return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv); 1684252726Srpaulo} 1685189251Ssam 1686252726Srpaulo 1687252726Srpaulostatic char ** wpa_cli_complete_bss(const char *str, int pos) 1688252726Srpaulo{ 1689252726Srpaulo int arg = get_cmd_arg_num(str, pos); 1690252726Srpaulo char **res = NULL; 1691252726Srpaulo 1692252726Srpaulo switch (arg) { 1693252726Srpaulo case 1: 1694252726Srpaulo res = cli_txt_list_array(&bsses); 1695252726Srpaulo break; 1696189251Ssam } 1697189251Ssam 1698252726Srpaulo return res; 1699189251Ssam} 1700189251Ssam 1701189251Ssam 1702189251Ssamstatic int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc, 1703189251Ssam char *argv[]) 1704189251Ssam{ 1705189251Ssam if (argc < 1 || argc > 2) { 1706189251Ssam printf("Invalid GET_CAPABILITY command: need either one or " 1707189251Ssam "two arguments\n"); 1708189251Ssam return -1; 1709189251Ssam } 1710189251Ssam 1711189251Ssam if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) { 1712189251Ssam printf("Invalid GET_CAPABILITY command: second argument, " 1713189251Ssam "if any, must be 'strict'\n"); 1714189251Ssam return -1; 1715189251Ssam } 1716189251Ssam 1717252726Srpaulo return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv); 1718189251Ssam} 1719189251Ssam 1720189251Ssam 1721337817Scystatic char ** wpa_cli_complete_get_capability(const char *str, int pos) 1722337817Scy{ 1723337817Scy int arg = get_cmd_arg_num(str, pos); 1724337817Scy const char *fields[] = { 1725337817Scy "eap", "pairwise", "group", "group_mgmt", "key_mgmt", 1726337817Scy "proto", "auth_alg", "modes", "channels", "freq", 1727337817Scy#ifdef CONFIG_TDLS 1728337817Scy "tdls", 1729337817Scy#endif /* CONFIG_TDLS */ 1730337817Scy#ifdef CONFIG_ERP 1731337817Scy "erp", 1732337817Scy#endif /* CONFIG_ERP */ 1733337817Scy#ifdef CONFIG_FIPS 1734337817Scy "fips", 1735337817Scy#endif /* CONFIG_FIPS */ 1736337817Scy#ifdef CONFIG_ACS 1737337817Scy "acs", 1738337817Scy#endif /* CONFIG_ACS */ 1739337817Scy }; 1740337817Scy int i, num_fields = ARRAY_SIZE(fields); 1741337817Scy char **res = NULL; 1742337817Scy 1743337817Scy if (arg == 1) { 1744337817Scy res = os_calloc(num_fields + 1, sizeof(char *)); 1745337817Scy if (res == NULL) 1746337817Scy return NULL; 1747337817Scy for (i = 0; i < num_fields; i++) { 1748337817Scy res[i] = os_strdup(fields[i]); 1749337817Scy if (res[i] == NULL) 1750337817Scy return res; 1751337817Scy } 1752337817Scy } 1753337817Scy if (arg == 2) { 1754337817Scy res = os_calloc(1 + 1, sizeof(char *)); 1755337817Scy if (res == NULL) 1756337817Scy return NULL; 1757337817Scy res[0] = os_strdup("strict"); 1758337817Scy } 1759337817Scy return res; 1760337817Scy} 1761337817Scy 1762337817Scy 1763189251Ssamstatic int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl) 1764189251Ssam{ 1765189251Ssam printf("Available interfaces:\n"); 1766189251Ssam return wpa_ctrl_command(ctrl, "INTERFACES"); 1767189251Ssam} 1768189251Ssam 1769189251Ssam 1770189251Ssamstatic int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1771189251Ssam{ 1772189251Ssam if (argc < 1) { 1773189251Ssam wpa_cli_list_interfaces(ctrl); 1774189251Ssam return 0; 1775189251Ssam } 1776189251Ssam 1777189251Ssam wpa_cli_close_connection(); 1778189251Ssam os_free(ctrl_ifname); 1779189251Ssam ctrl_ifname = os_strdup(argv[0]); 1780281806Srpaulo if (!ctrl_ifname) { 1781281806Srpaulo printf("Failed to allocate memory\n"); 1782281806Srpaulo return 0; 1783281806Srpaulo } 1784189251Ssam 1785281806Srpaulo if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) { 1786189251Ssam printf("Connected to interface '%s.\n", ctrl_ifname); 1787189251Ssam } else { 1788189251Ssam printf("Could not connect to interface '%s' - re-trying\n", 1789189251Ssam ctrl_ifname); 1790189251Ssam } 1791189251Ssam return 0; 1792189251Ssam} 1793189251Ssam 1794189251Ssam 1795189251Ssamstatic int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc, 1796189251Ssam char *argv[]) 1797189251Ssam{ 1798189251Ssam return wpa_ctrl_command(ctrl, "RECONFIGURE"); 1799189251Ssam} 1800189251Ssam 1801189251Ssam 1802189251Ssamstatic int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc, 1803189251Ssam char *argv[]) 1804189251Ssam{ 1805189251Ssam return wpa_ctrl_command(ctrl, "TERMINATE"); 1806189251Ssam} 1807189251Ssam 1808189251Ssam 1809189251Ssamstatic int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc, 1810189251Ssam char *argv[]) 1811189251Ssam{ 1812189251Ssam char cmd[256]; 1813189251Ssam int res; 1814189251Ssam 1815189251Ssam if (argc < 1) { 1816189251Ssam printf("Invalid INTERFACE_ADD command: needs at least one " 1817189251Ssam "argument (interface name)\n" 1818189251Ssam "All arguments: ifname confname driver ctrl_interface " 1819289549Srpaulo "driver_param bridge_name [create]\n"); 1820189251Ssam return -1; 1821189251Ssam } 1822189251Ssam 1823189251Ssam /* 1824189251Ssam * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB 1825337817Scy * <driver_param>TAB<bridge_name>[TAB<create>[TAB<type>]] 1826189251Ssam */ 1827189251Ssam res = os_snprintf(cmd, sizeof(cmd), 1828337817Scy "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s\t%s\t%s", 1829189251Ssam argv[0], 1830189251Ssam argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "", 1831189251Ssam argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "", 1832337817Scy argc > 5 ? argv[5] : "", argc > 6 ? argv[6] : "", 1833337817Scy argc > 7 ? argv[7] : ""); 1834281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 1835189251Ssam return -1; 1836189251Ssam cmd[sizeof(cmd) - 1] = '\0'; 1837189251Ssam return wpa_ctrl_command(ctrl, cmd); 1838189251Ssam} 1839189251Ssam 1840189251Ssam 1841189251Ssamstatic int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc, 1842189251Ssam char *argv[]) 1843189251Ssam{ 1844252726Srpaulo return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv); 1845189251Ssam} 1846189251Ssam 1847189251Ssam 1848189251Ssamstatic int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc, 1849189251Ssam char *argv[]) 1850189251Ssam{ 1851189251Ssam return wpa_ctrl_command(ctrl, "INTERFACE_LIST"); 1852189251Ssam} 1853189251Ssam 1854189251Ssam 1855214734Srpaulo#ifdef CONFIG_AP 1856214734Srpaulostatic int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1857214734Srpaulo{ 1858252726Srpaulo return wpa_cli_cmd(ctrl, "STA", 1, argc, argv); 1859214734Srpaulo} 1860214734Srpaulo 1861214734Srpaulo 1862346981Scystatic char ** wpa_cli_complete_sta(const char *str, int pos) 1863214734Srpaulo{ 1864346981Scy int arg = get_cmd_arg_num(str, pos); 1865346981Scy char **res = NULL; 1866346981Scy 1867346981Scy switch (arg) { 1868346981Scy case 1: 1869346981Scy res = cli_txt_list_array(&stations); 1870346981Scy break; 1871346981Scy } 1872346981Scy 1873346981Scy return res; 1874346981Scy} 1875346981Scy 1876346981Scy 1877346981Scystatic int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, const char *cmd, 1878346981Scy char *addr, size_t addr_len, int print) 1879346981Scy{ 1880214734Srpaulo char buf[4096], *pos; 1881214734Srpaulo size_t len; 1882214734Srpaulo int ret; 1883214734Srpaulo 1884214734Srpaulo if (ctrl_conn == NULL) { 1885214734Srpaulo printf("Not connected to hostapd - command dropped.\n"); 1886214734Srpaulo return -1; 1887214734Srpaulo } 1888337817Scy if (ifname_prefix) { 1889337817Scy os_snprintf(buf, sizeof(buf), "IFNAME=%s %s", 1890337817Scy ifname_prefix, cmd); 1891337817Scy buf[sizeof(buf) - 1] = '\0'; 1892337817Scy cmd = buf; 1893337817Scy } 1894214734Srpaulo len = sizeof(buf) - 1; 1895252726Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 1896214734Srpaulo wpa_cli_msg_cb); 1897214734Srpaulo if (ret == -2) { 1898214734Srpaulo printf("'%s' command timed out.\n", cmd); 1899214734Srpaulo return -2; 1900214734Srpaulo } else if (ret < 0) { 1901214734Srpaulo printf("'%s' command failed.\n", cmd); 1902214734Srpaulo return -1; 1903214734Srpaulo } 1904214734Srpaulo 1905214734Srpaulo buf[len] = '\0'; 1906346981Scy if (os_memcmp(buf, "FAIL", 4) == 0 || 1907346981Scy os_memcmp(buf, "UNKNOWN COMMAND", 15) == 0) 1908214734Srpaulo return -1; 1909346981Scy if (print) 1910346981Scy printf("%s", buf); 1911214734Srpaulo 1912214734Srpaulo pos = buf; 1913214734Srpaulo while (*pos != '\0' && *pos != '\n') 1914214734Srpaulo pos++; 1915214734Srpaulo *pos = '\0'; 1916214734Srpaulo os_strlcpy(addr, buf, addr_len); 1917214734Srpaulo return 0; 1918214734Srpaulo} 1919214734Srpaulo 1920214734Srpaulo 1921214734Srpaulostatic int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1922214734Srpaulo{ 1923214734Srpaulo char addr[32], cmd[64]; 1924214734Srpaulo 1925346981Scy if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 1)) 1926214734Srpaulo return 0; 1927214734Srpaulo do { 1928214734Srpaulo os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); 1929346981Scy } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 1) == 0); 1930214734Srpaulo 1931214734Srpaulo return -1; 1932214734Srpaulo} 1933252726Srpaulo 1934252726Srpaulo 1935346981Scystatic int wpa_cli_cmd_list_sta(struct wpa_ctrl *ctrl, int argc, 1936346981Scy char *argv[]) 1937346981Scy{ 1938346981Scy char addr[32], cmd[64]; 1939346981Scy 1940346981Scy if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 0)) 1941346981Scy return 0; 1942346981Scy do { 1943346981Scy if (os_strcmp(addr, "") != 0) 1944346981Scy printf("%s\n", addr); 1945346981Scy os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); 1946346981Scy } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 0) == 0); 1947346981Scy 1948346981Scy return 0; 1949346981Scy} 1950346981Scy 1951346981Scy 1952252726Srpaulostatic int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc, 1953252726Srpaulo char *argv[]) 1954252726Srpaulo{ 1955252726Srpaulo return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv); 1956252726Srpaulo} 1957252726Srpaulo 1958252726Srpaulo 1959346981Scystatic char ** wpa_cli_complete_deauthenticate(const char *str, int pos) 1960346981Scy{ 1961346981Scy int arg = get_cmd_arg_num(str, pos); 1962346981Scy char **res = NULL; 1963346981Scy 1964346981Scy switch (arg) { 1965346981Scy case 1: 1966346981Scy res = cli_txt_list_array(&stations); 1967346981Scy break; 1968346981Scy } 1969346981Scy 1970346981Scy return res; 1971346981Scy} 1972346981Scy 1973346981Scy 1974252726Srpaulostatic int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc, 1975252726Srpaulo char *argv[]) 1976252726Srpaulo{ 1977252726Srpaulo return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv); 1978252726Srpaulo} 1979281806Srpaulo 1980346981Scy 1981346981Scystatic char ** wpa_cli_complete_disassociate(const char *str, int pos) 1982346981Scy{ 1983346981Scy int arg = get_cmd_arg_num(str, pos); 1984346981Scy char **res = NULL; 1985346981Scy 1986346981Scy switch (arg) { 1987346981Scy case 1: 1988346981Scy res = cli_txt_list_array(&stations); 1989346981Scy break; 1990346981Scy } 1991346981Scy 1992346981Scy return res; 1993346981Scy} 1994346981Scy 1995346981Scy 1996281806Srpaulostatic int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc, 1997281806Srpaulo char *argv[]) 1998281806Srpaulo{ 1999281806Srpaulo return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv); 2000281806Srpaulo} 2001281806Srpaulo 2002214734Srpaulo#endif /* CONFIG_AP */ 2003214734Srpaulo 2004214734Srpaulo 2005214734Srpaulostatic int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2006214734Srpaulo{ 2007214734Srpaulo return wpa_ctrl_command(ctrl, "SUSPEND"); 2008214734Srpaulo} 2009214734Srpaulo 2010214734Srpaulo 2011214734Srpaulostatic int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2012214734Srpaulo{ 2013214734Srpaulo return wpa_ctrl_command(ctrl, "RESUME"); 2014214734Srpaulo} 2015214734Srpaulo 2016214734Srpaulo 2017281806Srpaulo#ifdef CONFIG_TESTING_OPTIONS 2018214734Srpaulostatic int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2019214734Srpaulo{ 2020214734Srpaulo return wpa_ctrl_command(ctrl, "DROP_SA"); 2021214734Srpaulo} 2022281806Srpaulo#endif /* CONFIG_TESTING_OPTIONS */ 2023214734Srpaulo 2024214734Srpaulo 2025214734Srpaulostatic int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2026214734Srpaulo{ 2027252726Srpaulo return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv); 2028252726Srpaulo} 2029252726Srpaulo 2030252726Srpaulo 2031281806Srpaulo#ifdef CONFIG_MESH 2032281806Srpaulo 2033281806Srpaulostatic int wpa_cli_cmd_mesh_interface_add(struct wpa_ctrl *ctrl, int argc, 2034281806Srpaulo char *argv[]) 2035281806Srpaulo{ 2036281806Srpaulo return wpa_cli_cmd(ctrl, "MESH_INTERFACE_ADD", 0, argc, argv); 2037281806Srpaulo} 2038281806Srpaulo 2039281806Srpaulo 2040281806Srpaulostatic int wpa_cli_cmd_mesh_group_add(struct wpa_ctrl *ctrl, int argc, 2041281806Srpaulo char *argv[]) 2042281806Srpaulo{ 2043281806Srpaulo return wpa_cli_cmd(ctrl, "MESH_GROUP_ADD", 1, argc, argv); 2044281806Srpaulo} 2045281806Srpaulo 2046281806Srpaulo 2047281806Srpaulostatic int wpa_cli_cmd_mesh_group_remove(struct wpa_ctrl *ctrl, int argc, 2048281806Srpaulo char *argv[]) 2049281806Srpaulo{ 2050281806Srpaulo return wpa_cli_cmd(ctrl, "MESH_GROUP_REMOVE", 1, argc, argv); 2051281806Srpaulo} 2052281806Srpaulo 2053337817Scy 2054337817Scystatic int wpa_cli_cmd_mesh_peer_remove(struct wpa_ctrl *ctrl, int argc, 2055337817Scy char *argv[]) 2056337817Scy{ 2057337817Scy return wpa_cli_cmd(ctrl, "MESH_PEER_REMOVE", 1, argc, argv); 2058337817Scy} 2059337817Scy 2060337817Scy 2061337817Scystatic int wpa_cli_cmd_mesh_peer_add(struct wpa_ctrl *ctrl, int argc, 2062337817Scy char *argv[]) 2063337817Scy{ 2064337817Scy return wpa_cli_cmd(ctrl, "MESH_PEER_ADD", 1, argc, argv); 2065337817Scy} 2066337817Scy 2067351611Scy 2068351611Scystatic int wpa_cli_cmd_mesh_link_probe(struct wpa_ctrl *ctrl, int argc, 2069351611Scy char *argv[]) 2070351611Scy{ 2071351611Scy return wpa_cli_cmd(ctrl, "MESH_LINK_PROBE", 1, argc, argv); 2072351611Scy} 2073351611Scy 2074281806Srpaulo#endif /* CONFIG_MESH */ 2075281806Srpaulo 2076281806Srpaulo 2077252726Srpaulo#ifdef CONFIG_P2P 2078252726Srpaulo 2079252726Srpaulostatic int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2080252726Srpaulo{ 2081252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv); 2082252726Srpaulo} 2083252726Srpaulo 2084252726Srpaulo 2085252726Srpaulostatic char ** wpa_cli_complete_p2p_find(const char *str, int pos) 2086252726Srpaulo{ 2087252726Srpaulo char **res = NULL; 2088252726Srpaulo int arg = get_cmd_arg_num(str, pos); 2089252726Srpaulo 2090252726Srpaulo res = os_calloc(6, sizeof(char *)); 2091252726Srpaulo if (res == NULL) 2092252726Srpaulo return NULL; 2093252726Srpaulo res[0] = os_strdup("type=social"); 2094252726Srpaulo if (res[0] == NULL) { 2095252726Srpaulo os_free(res); 2096252726Srpaulo return NULL; 2097252726Srpaulo } 2098252726Srpaulo res[1] = os_strdup("type=progressive"); 2099252726Srpaulo if (res[1] == NULL) 2100252726Srpaulo return res; 2101252726Srpaulo res[2] = os_strdup("delay="); 2102252726Srpaulo if (res[2] == NULL) 2103252726Srpaulo return res; 2104252726Srpaulo res[3] = os_strdup("dev_id="); 2105252726Srpaulo if (res[3] == NULL) 2106252726Srpaulo return res; 2107252726Srpaulo if (arg == 1) 2108252726Srpaulo res[4] = os_strdup("[timeout]"); 2109252726Srpaulo 2110252726Srpaulo return res; 2111252726Srpaulo} 2112252726Srpaulo 2113252726Srpaulo 2114252726Srpaulostatic int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc, 2115252726Srpaulo char *argv[]) 2116252726Srpaulo{ 2117252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_STOP_FIND"); 2118252726Srpaulo} 2119252726Srpaulo 2120252726Srpaulo 2121281806Srpaulostatic int wpa_cli_cmd_p2p_asp_provision(struct wpa_ctrl *ctrl, int argc, 2122281806Srpaulo char *argv[]) 2123281806Srpaulo{ 2124281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION", 3, argc, argv); 2125281806Srpaulo} 2126281806Srpaulo 2127281806Srpaulo 2128281806Srpaulostatic int wpa_cli_cmd_p2p_asp_provision_resp(struct wpa_ctrl *ctrl, int argc, 2129281806Srpaulo char *argv[]) 2130281806Srpaulo{ 2131281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION_RESP", 2, argc, argv); 2132281806Srpaulo} 2133281806Srpaulo 2134281806Srpaulo 2135252726Srpaulostatic int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc, 2136252726Srpaulo char *argv[]) 2137252726Srpaulo{ 2138252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv); 2139252726Srpaulo} 2140252726Srpaulo 2141252726Srpaulo 2142252726Srpaulostatic char ** wpa_cli_complete_p2p_connect(const char *str, int pos) 2143252726Srpaulo{ 2144252726Srpaulo int arg = get_cmd_arg_num(str, pos); 2145252726Srpaulo char **res = NULL; 2146252726Srpaulo 2147252726Srpaulo switch (arg) { 2148252726Srpaulo case 1: 2149252726Srpaulo res = cli_txt_list_array(&p2p_peers); 2150252726Srpaulo break; 2151252726Srpaulo } 2152252726Srpaulo 2153252726Srpaulo return res; 2154252726Srpaulo} 2155252726Srpaulo 2156252726Srpaulo 2157252726Srpaulostatic int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc, 2158252726Srpaulo char *argv[]) 2159252726Srpaulo{ 2160252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv); 2161252726Srpaulo} 2162252726Srpaulo 2163252726Srpaulo 2164252726Srpaulostatic int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc, 2165252726Srpaulo char *argv[]) 2166252726Srpaulo{ 2167252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv); 2168252726Srpaulo} 2169252726Srpaulo 2170252726Srpaulo 2171252726Srpaulostatic char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos) 2172252726Srpaulo{ 2173252726Srpaulo int arg = get_cmd_arg_num(str, pos); 2174252726Srpaulo char **res = NULL; 2175252726Srpaulo 2176252726Srpaulo switch (arg) { 2177252726Srpaulo case 1: 2178252726Srpaulo res = cli_txt_list_array(&p2p_groups); 2179252726Srpaulo break; 2180252726Srpaulo } 2181252726Srpaulo 2182252726Srpaulo return res; 2183252726Srpaulo} 2184252726Srpaulo 2185252726Srpaulo 2186252726Srpaulostatic int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc, 2187252726Srpaulo char *argv[]) 2188252726Srpaulo{ 2189252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv); 2190252726Srpaulo} 2191252726Srpaulo 2192252726Srpaulo 2193337817Scystatic int wpa_cli_cmd_p2p_group_member(struct wpa_ctrl *ctrl, int argc, 2194337817Scy char *argv[]) 2195337817Scy{ 2196337817Scy return wpa_cli_cmd(ctrl, "P2P_GROUP_MEMBER", 1, argc, argv); 2197337817Scy} 2198337817Scy 2199337817Scy 2200252726Srpaulostatic int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc, 2201252726Srpaulo char *argv[]) 2202252726Srpaulo{ 2203252726Srpaulo if (argc != 2 && argc != 3) { 2204252726Srpaulo printf("Invalid P2P_PROV_DISC command: needs at least " 2205252726Srpaulo "two arguments, address and config method\n" 2206252726Srpaulo "(display, keypad, or pbc) and an optional join\n"); 2207252726Srpaulo return -1; 2208252726Srpaulo } 2209252726Srpaulo 2210252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv); 2211252726Srpaulo} 2212252726Srpaulo 2213252726Srpaulo 2214252726Srpaulostatic int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc, 2215252726Srpaulo char *argv[]) 2216252726Srpaulo{ 2217252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE"); 2218252726Srpaulo} 2219252726Srpaulo 2220252726Srpaulo 2221252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc, 2222252726Srpaulo char *argv[]) 2223252726Srpaulo{ 2224252726Srpaulo char cmd[4096]; 2225252726Srpaulo 2226281806Srpaulo if (argc < 2) { 2227252726Srpaulo printf("Invalid P2P_SERV_DISC_REQ command: needs two " 2228281806Srpaulo "or more arguments (address and TLVs)\n"); 2229252726Srpaulo return -1; 2230252726Srpaulo } 2231252726Srpaulo 2232252726Srpaulo if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0) 2233252726Srpaulo return -1; 2234252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2235252726Srpaulo} 2236252726Srpaulo 2237252726Srpaulo 2238252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl, 2239252726Srpaulo int argc, char *argv[]) 2240252726Srpaulo{ 2241252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv); 2242252726Srpaulo} 2243252726Srpaulo 2244252726Srpaulo 2245252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc, 2246252726Srpaulo char *argv[]) 2247252726Srpaulo{ 2248252726Srpaulo char cmd[4096]; 2249214734Srpaulo int res; 2250214734Srpaulo 2251252726Srpaulo if (argc != 4) { 2252252726Srpaulo printf("Invalid P2P_SERV_DISC_RESP command: needs four " 2253252726Srpaulo "arguments (freq, address, dialog token, and TLVs)\n"); 2254252726Srpaulo return -1; 2255252726Srpaulo } 2256252726Srpaulo 2257252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s", 2258252726Srpaulo argv[0], argv[1], argv[2], argv[3]); 2259281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 2260252726Srpaulo return -1; 2261252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 2262252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2263252726Srpaulo} 2264252726Srpaulo 2265252726Srpaulo 2266252726Srpaulostatic int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc, 2267252726Srpaulo char *argv[]) 2268252726Srpaulo{ 2269252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE"); 2270252726Srpaulo} 2271252726Srpaulo 2272252726Srpaulo 2273252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl, 2274252726Srpaulo int argc, char *argv[]) 2275252726Srpaulo{ 2276252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv); 2277252726Srpaulo} 2278252726Srpaulo 2279252726Srpaulo 2280252726Srpaulostatic int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc, 2281252726Srpaulo char *argv[]) 2282252726Srpaulo{ 2283252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH"); 2284252726Srpaulo} 2285252726Srpaulo 2286252726Srpaulo 2287252726Srpaulostatic int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc, 2288252726Srpaulo char *argv[]) 2289252726Srpaulo{ 2290281806Srpaulo if (argc < 3) { 2291281806Srpaulo printf("Invalid P2P_SERVICE_ADD command: needs 3-6 arguments\n"); 2292281806Srpaulo return -1; 2293281806Srpaulo } 2294252726Srpaulo 2295281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERVICE_ADD", 3, argc, argv); 2296281806Srpaulo} 2297281806Srpaulo 2298281806Srpaulo 2299281806Srpaulostatic int wpa_cli_cmd_p2p_service_rep(struct wpa_ctrl *ctrl, int argc, 2300281806Srpaulo char *argv[]) 2301281806Srpaulo{ 2302281806Srpaulo if (argc < 5 || argc > 6) { 2303281806Srpaulo printf("Invalid P2P_SERVICE_REP command: needs 5-6 " 2304252726Srpaulo "arguments\n"); 2305252726Srpaulo return -1; 2306252726Srpaulo } 2307252726Srpaulo 2308281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERVICE_REP", 5, argc, argv); 2309252726Srpaulo} 2310252726Srpaulo 2311252726Srpaulo 2312252726Srpaulostatic int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc, 2313252726Srpaulo char *argv[]) 2314252726Srpaulo{ 2315252726Srpaulo char cmd[4096]; 2316252726Srpaulo int res; 2317252726Srpaulo 2318252726Srpaulo if (argc != 2 && argc != 3) { 2319252726Srpaulo printf("Invalid P2P_SERVICE_DEL command: needs two or three " 2320252726Srpaulo "arguments\n"); 2321252726Srpaulo return -1; 2322252726Srpaulo } 2323252726Srpaulo 2324252726Srpaulo if (argc == 3) 2325252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), 2326252726Srpaulo "P2P_SERVICE_DEL %s %s %s", 2327252726Srpaulo argv[0], argv[1], argv[2]); 2328252726Srpaulo else 2329252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), 2330252726Srpaulo "P2P_SERVICE_DEL %s %s", 2331252726Srpaulo argv[0], argv[1]); 2332281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 2333252726Srpaulo return -1; 2334252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 2335252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2336252726Srpaulo} 2337252726Srpaulo 2338252726Srpaulo 2339252726Srpaulostatic int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl, 2340252726Srpaulo int argc, char *argv[]) 2341252726Srpaulo{ 2342252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv); 2343252726Srpaulo} 2344252726Srpaulo 2345252726Srpaulo 2346252726Srpaulostatic int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl, 2347252726Srpaulo int argc, char *argv[]) 2348252726Srpaulo{ 2349252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv); 2350252726Srpaulo} 2351252726Srpaulo 2352252726Srpaulo 2353252726Srpaulostatic int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2354252726Srpaulo{ 2355252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv); 2356252726Srpaulo} 2357252726Srpaulo 2358252726Srpaulo 2359252726Srpaulostatic char ** wpa_cli_complete_p2p_peer(const char *str, int pos) 2360252726Srpaulo{ 2361252726Srpaulo int arg = get_cmd_arg_num(str, pos); 2362252726Srpaulo char **res = NULL; 2363252726Srpaulo 2364252726Srpaulo switch (arg) { 2365252726Srpaulo case 1: 2366252726Srpaulo res = cli_txt_list_array(&p2p_peers); 2367252726Srpaulo break; 2368252726Srpaulo } 2369252726Srpaulo 2370252726Srpaulo return res; 2371252726Srpaulo} 2372252726Srpaulo 2373252726Srpaulo 2374346981Scystatic int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, const char *cmd, 2375252726Srpaulo char *addr, size_t addr_len, 2376252726Srpaulo int discovered) 2377252726Srpaulo{ 2378252726Srpaulo char buf[4096], *pos; 2379252726Srpaulo size_t len; 2380252726Srpaulo int ret; 2381252726Srpaulo 2382252726Srpaulo if (ctrl_conn == NULL) 2383252726Srpaulo return -1; 2384252726Srpaulo len = sizeof(buf) - 1; 2385252726Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 2386252726Srpaulo wpa_cli_msg_cb); 2387252726Srpaulo if (ret == -2) { 2388252726Srpaulo printf("'%s' command timed out.\n", cmd); 2389252726Srpaulo return -2; 2390252726Srpaulo } else if (ret < 0) { 2391252726Srpaulo printf("'%s' command failed.\n", cmd); 2392252726Srpaulo return -1; 2393252726Srpaulo } 2394252726Srpaulo 2395252726Srpaulo buf[len] = '\0'; 2396252726Srpaulo if (os_memcmp(buf, "FAIL", 4) == 0) 2397252726Srpaulo return -1; 2398252726Srpaulo 2399252726Srpaulo pos = buf; 2400252726Srpaulo while (*pos != '\0' && *pos != '\n') 2401252726Srpaulo pos++; 2402252726Srpaulo *pos++ = '\0'; 2403252726Srpaulo os_strlcpy(addr, buf, addr_len); 2404252726Srpaulo if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL) 2405252726Srpaulo printf("%s\n", addr); 2406252726Srpaulo return 0; 2407252726Srpaulo} 2408252726Srpaulo 2409252726Srpaulo 2410252726Srpaulostatic int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2411252726Srpaulo{ 2412252726Srpaulo char addr[32], cmd[64]; 2413252726Srpaulo int discovered; 2414252726Srpaulo 2415252726Srpaulo discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0; 2416252726Srpaulo 2417252726Srpaulo if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST", 2418252726Srpaulo addr, sizeof(addr), discovered)) 2419252726Srpaulo return -1; 2420252726Srpaulo do { 2421252726Srpaulo os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr); 2422252726Srpaulo } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr), 2423252726Srpaulo discovered) == 0); 2424252726Srpaulo 2425252726Srpaulo return 0; 2426252726Srpaulo} 2427252726Srpaulo 2428252726Srpaulo 2429252726Srpaulostatic int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2430252726Srpaulo{ 2431252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv); 2432252726Srpaulo} 2433252726Srpaulo 2434252726Srpaulo 2435281806Srpaulostatic char ** wpa_cli_complete_p2p_set(const char *str, int pos) 2436281806Srpaulo{ 2437281806Srpaulo int arg = get_cmd_arg_num(str, pos); 2438281806Srpaulo const char *fields[] = { 2439281806Srpaulo "discoverability", 2440281806Srpaulo "managed", 2441281806Srpaulo "listen_channel", 2442281806Srpaulo "ssid_postfix", 2443281806Srpaulo "noa", 2444281806Srpaulo "ps", 2445281806Srpaulo "oppps", 2446281806Srpaulo "ctwindow", 2447281806Srpaulo "disabled", 2448281806Srpaulo "conc_pref", 2449281806Srpaulo "force_long_sd", 2450281806Srpaulo "peer_filter", 2451281806Srpaulo "cross_connect", 2452281806Srpaulo "go_apsd", 2453281806Srpaulo "client_apsd", 2454281806Srpaulo "disallow_freq", 2455281806Srpaulo "disc_int", 2456281806Srpaulo "per_sta_psk", 2457281806Srpaulo }; 2458281806Srpaulo int i, num_fields = ARRAY_SIZE(fields); 2459281806Srpaulo 2460281806Srpaulo if (arg == 1) { 2461281806Srpaulo char **res = os_calloc(num_fields + 1, sizeof(char *)); 2462281806Srpaulo if (res == NULL) 2463281806Srpaulo return NULL; 2464281806Srpaulo for (i = 0; i < num_fields; i++) { 2465281806Srpaulo res[i] = os_strdup(fields[i]); 2466281806Srpaulo if (res[i] == NULL) 2467281806Srpaulo return res; 2468281806Srpaulo } 2469281806Srpaulo return res; 2470281806Srpaulo } 2471281806Srpaulo 2472281806Srpaulo if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0) 2473281806Srpaulo return cli_txt_list_array(&p2p_peers); 2474281806Srpaulo 2475281806Srpaulo return NULL; 2476281806Srpaulo} 2477281806Srpaulo 2478281806Srpaulo 2479252726Srpaulostatic int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2480252726Srpaulo{ 2481252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_FLUSH"); 2482252726Srpaulo} 2483252726Srpaulo 2484252726Srpaulo 2485252726Srpaulostatic int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc, 2486252726Srpaulo char *argv[]) 2487252726Srpaulo{ 2488252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_CANCEL"); 2489252726Srpaulo} 2490252726Srpaulo 2491252726Srpaulo 2492252726Srpaulostatic int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc, 2493252726Srpaulo char *argv[]) 2494252726Srpaulo{ 2495252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv); 2496252726Srpaulo} 2497252726Srpaulo 2498252726Srpaulo 2499252726Srpaulostatic int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc, 2500252726Srpaulo char *argv[]) 2501252726Srpaulo{ 2502252726Srpaulo if (argc != 0 && argc != 2 && argc != 4) { 2503252726Srpaulo printf("Invalid P2P_PRESENCE_REQ command: needs two arguments " 2504252726Srpaulo "(preferred duration, interval; in microsecods).\n" 2505252726Srpaulo "Optional second pair can be used to provide " 2506252726Srpaulo "acceptable values.\n"); 2507252726Srpaulo return -1; 2508252726Srpaulo } 2509252726Srpaulo 2510252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv); 2511252726Srpaulo} 2512252726Srpaulo 2513252726Srpaulo 2514252726Srpaulostatic int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc, 2515252726Srpaulo char *argv[]) 2516252726Srpaulo{ 2517252726Srpaulo if (argc != 0 && argc != 2) { 2518252726Srpaulo printf("Invalid P2P_EXT_LISTEN command: needs two arguments " 2519252726Srpaulo "(availability period, availability interval; in " 2520252726Srpaulo "millisecods).\n" 2521252726Srpaulo "Extended Listen Timing can be cancelled with this " 2522252726Srpaulo "command when used without parameters.\n"); 2523252726Srpaulo return -1; 2524252726Srpaulo } 2525252726Srpaulo 2526252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv); 2527252726Srpaulo} 2528252726Srpaulo 2529281806Srpaulo 2530281806Srpaulostatic int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc, 2531281806Srpaulo char *argv[]) 2532281806Srpaulo{ 2533281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv); 2534281806Srpaulo} 2535281806Srpaulo 2536346981Scy#endif /* CONFIG_P2P */ 2537337817Scy 2538346981Scy 2539337817Scystatic int wpa_cli_cmd_vendor_elem_add(struct wpa_ctrl *ctrl, int argc, 2540337817Scy char *argv[]) 2541337817Scy{ 2542337817Scy return wpa_cli_cmd(ctrl, "VENDOR_ELEM_ADD", 2, argc, argv); 2543337817Scy} 2544337817Scy 2545337817Scy 2546337817Scystatic int wpa_cli_cmd_vendor_elem_get(struct wpa_ctrl *ctrl, int argc, 2547337817Scy char *argv[]) 2548337817Scy{ 2549337817Scy return wpa_cli_cmd(ctrl, "VENDOR_ELEM_GET", 1, argc, argv); 2550337817Scy} 2551337817Scy 2552337817Scy 2553337817Scystatic int wpa_cli_cmd_vendor_elem_remove(struct wpa_ctrl *ctrl, int argc, 2554337817Scy char *argv[]) 2555337817Scy{ 2556337817Scy return wpa_cli_cmd(ctrl, "VENDOR_ELEM_REMOVE", 2, argc, argv); 2557337817Scy} 2558337817Scy 2559252726Srpaulo 2560252726Srpaulo#ifdef CONFIG_WIFI_DISPLAY 2561252726Srpaulo 2562252726Srpaulostatic int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc, 2563252726Srpaulo char *argv[]) 2564252726Srpaulo{ 2565252726Srpaulo char cmd[100]; 2566252726Srpaulo int res; 2567252726Srpaulo 2568252726Srpaulo if (argc != 1 && argc != 2) { 2569252726Srpaulo printf("Invalid WFD_SUBELEM_SET command: needs one or two " 2570252726Srpaulo "arguments (subelem, hexdump)\n"); 2571252726Srpaulo return -1; 2572252726Srpaulo } 2573252726Srpaulo 2574252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s", 2575252726Srpaulo argv[0], argc > 1 ? argv[1] : ""); 2576281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 2577252726Srpaulo return -1; 2578252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 2579252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2580252726Srpaulo} 2581252726Srpaulo 2582252726Srpaulo 2583252726Srpaulostatic int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc, 2584252726Srpaulo char *argv[]) 2585252726Srpaulo{ 2586252726Srpaulo char cmd[100]; 2587252726Srpaulo int res; 2588252726Srpaulo 2589214734Srpaulo if (argc != 1) { 2590252726Srpaulo printf("Invalid WFD_SUBELEM_GET command: needs one " 2591252726Srpaulo "argument (subelem)\n"); 2592214734Srpaulo return -1; 2593214734Srpaulo } 2594214734Srpaulo 2595252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s", 2596252726Srpaulo argv[0]); 2597281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 2598214734Srpaulo return -1; 2599252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 2600252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2601252726Srpaulo} 2602252726Srpaulo#endif /* CONFIG_WIFI_DISPLAY */ 2603252726Srpaulo 2604252726Srpaulo 2605252726Srpaulo#ifdef CONFIG_INTERWORKING 2606252726Srpaulostatic int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc, 2607252726Srpaulo char *argv[]) 2608252726Srpaulo{ 2609252726Srpaulo return wpa_ctrl_command(ctrl, "FETCH_ANQP"); 2610252726Srpaulo} 2611252726Srpaulo 2612252726Srpaulo 2613252726Srpaulostatic int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc, 2614252726Srpaulo char *argv[]) 2615252726Srpaulo{ 2616252726Srpaulo return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP"); 2617252726Srpaulo} 2618252726Srpaulo 2619252726Srpaulo 2620252726Srpaulostatic int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc, 2621252726Srpaulo char *argv[]) 2622252726Srpaulo{ 2623252726Srpaulo return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv); 2624252726Srpaulo} 2625252726Srpaulo 2626252726Srpaulo 2627252726Srpaulostatic int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc, 2628252726Srpaulo char *argv[]) 2629252726Srpaulo{ 2630252726Srpaulo return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv); 2631252726Srpaulo} 2632252726Srpaulo 2633252726Srpaulo 2634281806Srpaulostatic int wpa_cli_cmd_interworking_add_network(struct wpa_ctrl *ctrl, int argc, 2635281806Srpaulo char *argv[]) 2636281806Srpaulo{ 2637281806Srpaulo return wpa_cli_cmd(ctrl, "INTERWORKING_ADD_NETWORK", 1, argc, argv); 2638281806Srpaulo} 2639281806Srpaulo 2640281806Srpaulo 2641252726Srpaulostatic int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2642252726Srpaulo{ 2643252726Srpaulo return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv); 2644252726Srpaulo} 2645252726Srpaulo 2646252726Srpaulo 2647252726Srpaulostatic int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc, 2648252726Srpaulo char *argv[]) 2649252726Srpaulo{ 2650252726Srpaulo return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv); 2651252726Srpaulo} 2652252726Srpaulo 2653252726Srpaulo 2654252726Srpaulostatic int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc, 2655252726Srpaulo char *argv[]) 2656252726Srpaulo{ 2657252726Srpaulo return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv); 2658252726Srpaulo} 2659252726Srpaulo#endif /* CONFIG_INTERWORKING */ 2660252726Srpaulo 2661252726Srpaulo 2662252726Srpaulo#ifdef CONFIG_HS20 2663252726Srpaulo 2664252726Srpaulostatic int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc, 2665252726Srpaulo char *argv[]) 2666252726Srpaulo{ 2667252726Srpaulo return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv); 2668252726Srpaulo} 2669252726Srpaulo 2670252726Srpaulo 2671252726Srpaulostatic int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc, 2672252726Srpaulo char *argv[]) 2673252726Srpaulo{ 2674252726Srpaulo char cmd[512]; 2675252726Srpaulo 2676252726Srpaulo if (argc == 0) { 2677252726Srpaulo printf("Command needs one or two arguments (dst mac addr and " 2678252726Srpaulo "optional home realm)\n"); 2679252726Srpaulo return -1; 2680214734Srpaulo } 2681252726Srpaulo 2682252726Srpaulo if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST", 2683252726Srpaulo argc, argv) < 0) 2684252726Srpaulo return -1; 2685252726Srpaulo 2686214734Srpaulo return wpa_ctrl_command(ctrl, cmd); 2687214734Srpaulo} 2688214734Srpaulo 2689281806Srpaulo 2690281806Srpaulostatic int wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl *ctrl, int argc, 2691281806Srpaulo char *argv[]) 2692281806Srpaulo{ 2693281806Srpaulo char cmd[512]; 2694281806Srpaulo 2695281806Srpaulo if (argc < 2) { 2696281806Srpaulo printf("Command needs two arguments (dst mac addr and " 2697281806Srpaulo "icon name)\n"); 2698281806Srpaulo return -1; 2699281806Srpaulo } 2700281806Srpaulo 2701281806Srpaulo if (write_cmd(cmd, sizeof(cmd), "HS20_ICON_REQUEST", argc, argv) < 0) 2702281806Srpaulo return -1; 2703281806Srpaulo 2704281806Srpaulo return wpa_ctrl_command(ctrl, cmd); 2705281806Srpaulo} 2706281806Srpaulo 2707281806Srpaulo 2708281806Srpaulostatic int wpa_cli_cmd_fetch_osu(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2709281806Srpaulo{ 2710281806Srpaulo return wpa_ctrl_command(ctrl, "FETCH_OSU"); 2711281806Srpaulo} 2712281806Srpaulo 2713281806Srpaulo 2714281806Srpaulostatic int wpa_cli_cmd_cancel_fetch_osu(struct wpa_ctrl *ctrl, int argc, 2715281806Srpaulo char *argv[]) 2716281806Srpaulo{ 2717281806Srpaulo return wpa_ctrl_command(ctrl, "CANCEL_FETCH_OSU"); 2718281806Srpaulo} 2719281806Srpaulo 2720252726Srpaulo#endif /* CONFIG_HS20 */ 2721214734Srpaulo 2722252726Srpaulo 2723252726Srpaulostatic int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc, 2724252726Srpaulo char *argv[]) 2725252726Srpaulo{ 2726252726Srpaulo return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv); 2727252726Srpaulo} 2728252726Srpaulo 2729252726Srpaulo 2730252726Srpaulostatic int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc, 2731252726Srpaulo char *argv[]) 2732252726Srpaulo{ 2733252726Srpaulo return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv); 2734252726Srpaulo} 2735252726Srpaulo 2736252726Srpaulo 2737252726Srpaulostatic int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc, 2738252726Srpaulo char *argv[]) 2739252726Srpaulo{ 2740252726Srpaulo return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv); 2741252726Srpaulo} 2742252726Srpaulo 2743252726Srpaulo 2744252726Srpaulostatic int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc, 2745252726Srpaulo char *argv[]) 2746252726Srpaulo{ 2747252726Srpaulo return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv); 2748252726Srpaulo} 2749252726Srpaulo 2750252726Srpaulo 2751289549Srpaulostatic int wpa_cli_cmd_tdls_link_status(struct wpa_ctrl *ctrl, int argc, 2752289549Srpaulo char *argv[]) 2753289549Srpaulo{ 2754289549Srpaulo return wpa_cli_cmd(ctrl, "TDLS_LINK_STATUS", 1, argc, argv); 2755289549Srpaulo} 2756289549Srpaulo 2757289549Srpaulo 2758281806Srpaulostatic int wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl *ctrl, int argc, 2759281806Srpaulo char *argv[]) 2760281806Srpaulo{ 2761281806Srpaulo return wpa_cli_cmd(ctrl, "WMM_AC_ADDTS", 3, argc, argv); 2762281806Srpaulo} 2763281806Srpaulo 2764281806Srpaulo 2765281806Srpaulostatic int wpa_cli_cmd_wmm_ac_delts(struct wpa_ctrl *ctrl, int argc, 2766281806Srpaulo char *argv[]) 2767281806Srpaulo{ 2768281806Srpaulo return wpa_cli_cmd(ctrl, "WMM_AC_DELTS", 1, argc, argv); 2769281806Srpaulo} 2770281806Srpaulo 2771281806Srpaulo 2772281806Srpaulostatic int wpa_cli_cmd_wmm_ac_status(struct wpa_ctrl *ctrl, int argc, 2773281806Srpaulo char *argv[]) 2774281806Srpaulo{ 2775281806Srpaulo return wpa_ctrl_command(ctrl, "WMM_AC_STATUS"); 2776281806Srpaulo} 2777281806Srpaulo 2778281806Srpaulo 2779281806Srpaulostatic int wpa_cli_cmd_tdls_chan_switch(struct wpa_ctrl *ctrl, int argc, 2780281806Srpaulo char *argv[]) 2781281806Srpaulo{ 2782281806Srpaulo return wpa_cli_cmd(ctrl, "TDLS_CHAN_SWITCH", 2, argc, argv); 2783281806Srpaulo} 2784281806Srpaulo 2785281806Srpaulo 2786281806Srpaulostatic int wpa_cli_cmd_tdls_cancel_chan_switch(struct wpa_ctrl *ctrl, int argc, 2787281806Srpaulo char *argv[]) 2788281806Srpaulo{ 2789281806Srpaulo return wpa_cli_cmd(ctrl, "TDLS_CANCEL_CHAN_SWITCH", 1, argc, argv); 2790281806Srpaulo} 2791281806Srpaulo 2792281806Srpaulo 2793252726Srpaulostatic int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc, 2794252726Srpaulo char *argv[]) 2795252726Srpaulo{ 2796252726Srpaulo return wpa_ctrl_command(ctrl, "SIGNAL_POLL"); 2797252726Srpaulo} 2798252726Srpaulo 2799252726Srpaulo 2800337817Scystatic int wpa_cli_cmd_signal_monitor(struct wpa_ctrl *ctrl, int argc, 2801337817Scy char *argv[]) 2802337817Scy{ 2803337817Scy return wpa_cli_cmd(ctrl, "SIGNAL_MONITOR", 0, argc, argv); 2804337817Scy} 2805337817Scy 2806337817Scy 2807252726Srpaulostatic int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc, 2808252726Srpaulo char *argv[]) 2809252726Srpaulo{ 2810252726Srpaulo return wpa_ctrl_command(ctrl, "PKTCNT_POLL"); 2811252726Srpaulo} 2812252726Srpaulo 2813252726Srpaulo 2814252726Srpaulostatic int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc, 2815252726Srpaulo char *argv[]) 2816252726Srpaulo{ 2817252726Srpaulo return wpa_ctrl_command(ctrl, "REAUTHENTICATE"); 2818252726Srpaulo} 2819252726Srpaulo 2820252726Srpaulo 2821252726Srpaulo#ifdef CONFIG_AUTOSCAN 2822252726Srpaulo 2823252726Srpaulostatic int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2824252726Srpaulo{ 2825252726Srpaulo if (argc == 0) 2826252726Srpaulo return wpa_ctrl_command(ctrl, "AUTOSCAN "); 2827252726Srpaulo 2828252726Srpaulo return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv); 2829252726Srpaulo} 2830252726Srpaulo 2831252726Srpaulo#endif /* CONFIG_AUTOSCAN */ 2832252726Srpaulo 2833252726Srpaulo 2834252726Srpaulo#ifdef CONFIG_WNM 2835252726Srpaulo 2836252726Srpaulostatic int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2837252726Srpaulo{ 2838252726Srpaulo return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv); 2839252726Srpaulo} 2840252726Srpaulo 2841281806Srpaulo 2842281806Srpaulostatic int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2843281806Srpaulo{ 2844281806Srpaulo return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv); 2845281806Srpaulo} 2846281806Srpaulo 2847252726Srpaulo#endif /* CONFIG_WNM */ 2848252726Srpaulo 2849252726Srpaulo 2850252726Srpaulostatic int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2851252726Srpaulo{ 2852252726Srpaulo if (argc == 0) 2853252726Srpaulo return -1; 2854252726Srpaulo return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]); 2855252726Srpaulo} 2856252726Srpaulo 2857252726Srpaulo 2858281806Srpaulo#ifdef ANDROID 2859281806Srpaulostatic int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2860281806Srpaulo{ 2861281806Srpaulo return wpa_cli_cmd(ctrl, "DRIVER", 1, argc, argv); 2862281806Srpaulo} 2863281806Srpaulo#endif /* ANDROID */ 2864281806Srpaulo 2865281806Srpaulo 2866281806Srpaulostatic int wpa_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2867281806Srpaulo{ 2868281806Srpaulo return wpa_cli_cmd(ctrl, "VENDOR", 1, argc, argv); 2869281806Srpaulo} 2870281806Srpaulo 2871281806Srpaulo 2872281806Srpaulostatic int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2873281806Srpaulo{ 2874281806Srpaulo return wpa_ctrl_command(ctrl, "FLUSH"); 2875281806Srpaulo} 2876281806Srpaulo 2877281806Srpaulo 2878281806Srpaulostatic int wpa_cli_cmd_radio_work(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2879281806Srpaulo{ 2880281806Srpaulo return wpa_cli_cmd(ctrl, "RADIO_WORK", 1, argc, argv); 2881281806Srpaulo} 2882281806Srpaulo 2883281806Srpaulo 2884281806Srpaulostatic int wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl *ctrl, int argc, 2885281806Srpaulo char *argv[]) 2886281806Srpaulo{ 2887281806Srpaulo return wpa_cli_cmd(ctrl, "NEIGHBOR_REP_REQUEST", 0, argc, argv); 2888281806Srpaulo} 2889281806Srpaulo 2890281806Srpaulo 2891281806Srpaulostatic int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2892281806Srpaulo{ 2893281806Srpaulo return wpa_ctrl_command(ctrl, "ERP_FLUSH"); 2894281806Srpaulo} 2895281806Srpaulo 2896281806Srpaulo 2897281806Srpaulostatic int wpa_cli_cmd_mac_rand_scan(struct wpa_ctrl *ctrl, int argc, 2898281806Srpaulo char *argv[]) 2899281806Srpaulo{ 2900281806Srpaulo return wpa_cli_cmd(ctrl, "MAC_RAND_SCAN", 1, argc, argv); 2901281806Srpaulo} 2902281806Srpaulo 2903281806Srpaulo 2904289549Srpaulostatic int wpa_cli_cmd_get_pref_freq_list(struct wpa_ctrl *ctrl, int argc, 2905289549Srpaulo char *argv[]) 2906289549Srpaulo{ 2907289549Srpaulo return wpa_cli_cmd(ctrl, "GET_PREF_FREQ_LIST", 1, argc, argv); 2908289549Srpaulo} 2909289549Srpaulo 2910289549Srpaulo 2911337817Scystatic int wpa_cli_cmd_p2p_lo_start(struct wpa_ctrl *ctrl, int argc, 2912337817Scy char *argv[]) 2913337817Scy{ 2914337817Scy return wpa_cli_cmd(ctrl, "P2P_LO_START", 4, argc, argv); 2915337817Scy} 2916337817Scy 2917337817Scy 2918337817Scystatic int wpa_cli_cmd_p2p_lo_stop(struct wpa_ctrl *ctrl, int argc, 2919337817Scy char *argv[]) 2920337817Scy{ 2921337817Scy return wpa_cli_cmd(ctrl, "P2P_LO_STOP", 0, argc, argv); 2922337817Scy} 2923337817Scy 2924337817Scy 2925346981Scy#ifdef CONFIG_DPP 2926346981Scy 2927346981Scystatic int wpa_cli_cmd_dpp_qr_code(struct wpa_ctrl *ctrl, int argc, 2928346981Scy char *argv[]) 2929346981Scy{ 2930346981Scy return wpa_cli_cmd(ctrl, "DPP_QR_CODE", 1, argc, argv); 2931346981Scy} 2932346981Scy 2933346981Scy 2934346981Scystatic int wpa_cli_cmd_dpp_bootstrap_gen(struct wpa_ctrl *ctrl, int argc, 2935346981Scy char *argv[]) 2936346981Scy{ 2937346981Scy return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_GEN", 1, argc, argv); 2938346981Scy} 2939346981Scy 2940346981Scy 2941346981Scystatic int wpa_cli_cmd_dpp_bootstrap_remove(struct wpa_ctrl *ctrl, int argc, 2942346981Scy char *argv[]) 2943346981Scy{ 2944346981Scy return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_REMOVE", 1, argc, argv); 2945346981Scy} 2946346981Scy 2947346981Scy 2948346981Scystatic int wpa_cli_cmd_dpp_bootstrap_get_uri(struct wpa_ctrl *ctrl, int argc, 2949346981Scy char *argv[]) 2950346981Scy{ 2951346981Scy return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_GET_URI", 1, argc, argv); 2952346981Scy} 2953346981Scy 2954346981Scy 2955346981Scystatic int wpa_cli_cmd_dpp_bootstrap_info(struct wpa_ctrl *ctrl, int argc, 2956346981Scy char *argv[]) 2957346981Scy{ 2958346981Scy return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_INFO", 1, argc, argv); 2959346981Scy} 2960346981Scy 2961346981Scy 2962346981Scystatic int wpa_cli_cmd_dpp_auth_init(struct wpa_ctrl *ctrl, int argc, 2963346981Scy char *argv[]) 2964346981Scy{ 2965346981Scy return wpa_cli_cmd(ctrl, "DPP_AUTH_INIT", 1, argc, argv); 2966346981Scy} 2967346981Scy 2968346981Scy 2969346981Scystatic int wpa_cli_cmd_dpp_listen(struct wpa_ctrl *ctrl, int argc, 2970346981Scy char *argv[]) 2971346981Scy{ 2972346981Scy return wpa_cli_cmd(ctrl, "DPP_LISTEN", 1, argc, argv); 2973346981Scy} 2974346981Scy 2975346981Scy 2976346981Scystatic int wpa_cli_cmd_dpp_stop_listen(struct wpa_ctrl *ctrl, int argc, 2977346981Scy char *argv[]) 2978346981Scy{ 2979346981Scy return wpa_ctrl_command(ctrl, "DPP_STOP_LISTEN"); 2980346981Scy} 2981346981Scy 2982346981Scy 2983346981Scystatic int wpa_cli_cmd_dpp_configurator_add(struct wpa_ctrl *ctrl, int argc, 2984346981Scy char *argv[]) 2985346981Scy{ 2986346981Scy return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_ADD", 0, argc, argv); 2987346981Scy} 2988346981Scy 2989346981Scy 2990346981Scystatic int wpa_cli_cmd_dpp_configurator_remove(struct wpa_ctrl *ctrl, int argc, 2991346981Scy char *argv[]) 2992346981Scy{ 2993346981Scy return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_REMOVE", 1, argc, argv); 2994346981Scy} 2995346981Scy 2996346981Scy 2997346981Scystatic int wpa_cli_cmd_dpp_configurator_get_key(struct wpa_ctrl *ctrl, int argc, 2998346981Scy char *argv[]) 2999346981Scy{ 3000346981Scy return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_GET_KEY", 1, argc, argv); 3001346981Scy} 3002346981Scy 3003346981Scy 3004346981Scystatic int wpa_cli_cmd_dpp_configurator_sign(struct wpa_ctrl *ctrl, int argc, 3005346981Scy char *argv[]) 3006346981Scy{ 3007346981Scy return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_SIGN", 1, argc, argv); 3008346981Scy} 3009346981Scy 3010346981Scy 3011346981Scystatic int wpa_cli_cmd_dpp_pkex_add(struct wpa_ctrl *ctrl, int argc, 3012346981Scy char *argv[]) 3013346981Scy{ 3014346981Scy return wpa_cli_cmd(ctrl, "DPP_PKEX_ADD", 1, argc, argv); 3015346981Scy} 3016346981Scy 3017346981Scy 3018346981Scystatic int wpa_cli_cmd_dpp_pkex_remove(struct wpa_ctrl *ctrl, int argc, 3019346981Scy char *argv[]) 3020346981Scy{ 3021346981Scy return wpa_cli_cmd(ctrl, "DPP_PKEX_REMOVE", 1, argc, argv); 3022346981Scy} 3023346981Scy 3024346981Scy#endif /* CONFIG_DPP */ 3025346981Scy 3026346981Scy 3027189251Ssamenum wpa_cli_cmd_flags { 3028189251Ssam cli_cmd_flag_none = 0x00, 3029189251Ssam cli_cmd_flag_sensitive = 0x01 3030189251Ssam}; 3031189251Ssam 3032189251Ssamstruct wpa_cli_cmd { 3033189251Ssam const char *cmd; 3034189251Ssam int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]); 3035252726Srpaulo char ** (*completion)(const char *str, int pos); 3036189251Ssam enum wpa_cli_cmd_flags flags; 3037189251Ssam const char *usage; 3038189251Ssam}; 3039189251Ssam 3040289549Srpaulostatic const struct wpa_cli_cmd wpa_cli_commands[] = { 3041252726Srpaulo { "status", wpa_cli_cmd_status, NULL, 3042189251Ssam cli_cmd_flag_none, 3043189251Ssam "[verbose] = get current WPA/EAPOL/EAP status" }, 3044252726Srpaulo { "ifname", wpa_cli_cmd_ifname, NULL, 3045189251Ssam cli_cmd_flag_none, 3046252726Srpaulo "= get current interface name" }, 3047252726Srpaulo { "ping", wpa_cli_cmd_ping, NULL, 3048252726Srpaulo cli_cmd_flag_none, 3049189251Ssam "= pings wpa_supplicant" }, 3050252726Srpaulo { "relog", wpa_cli_cmd_relog, NULL, 3051189251Ssam cli_cmd_flag_none, 3052252726Srpaulo "= re-open log-file (allow rolling logs)" }, 3053252726Srpaulo { "note", wpa_cli_cmd_note, NULL, 3054252726Srpaulo cli_cmd_flag_none, 3055252726Srpaulo "<text> = add a note to wpa_supplicant debug log" }, 3056252726Srpaulo { "mib", wpa_cli_cmd_mib, NULL, 3057252726Srpaulo cli_cmd_flag_none, 3058189251Ssam "= get MIB variables (dot1x, dot11)" }, 3059252726Srpaulo { "help", wpa_cli_cmd_help, wpa_cli_complete_help, 3060189251Ssam cli_cmd_flag_none, 3061252726Srpaulo "[command] = show usage help" }, 3062252726Srpaulo { "interface", wpa_cli_cmd_interface, NULL, 3063189251Ssam cli_cmd_flag_none, 3064189251Ssam "[ifname] = show interfaces/select interface" }, 3065252726Srpaulo { "level", wpa_cli_cmd_level, NULL, 3066189251Ssam cli_cmd_flag_none, 3067189251Ssam "<debug level> = change debug level" }, 3068252726Srpaulo { "license", wpa_cli_cmd_license, NULL, 3069189251Ssam cli_cmd_flag_none, 3070189251Ssam "= show full wpa_cli license" }, 3071252726Srpaulo { "quit", wpa_cli_cmd_quit, NULL, 3072189251Ssam cli_cmd_flag_none, 3073189251Ssam "= exit wpa_cli" }, 3074281806Srpaulo { "set", wpa_cli_cmd_set, wpa_cli_complete_set, 3075189251Ssam cli_cmd_flag_none, 3076189251Ssam "= set variables (shows list of variables when run without " 3077189251Ssam "arguments)" }, 3078281806Srpaulo { "dump", wpa_cli_cmd_dump, NULL, 3079281806Srpaulo cli_cmd_flag_none, 3080281806Srpaulo "= dump config variables" }, 3081289549Srpaulo { "get", wpa_cli_cmd_get, wpa_cli_complete_get, 3082189251Ssam cli_cmd_flag_none, 3083252726Srpaulo "<name> = get information" }, 3084337817Scy { "driver_flags", wpa_cli_cmd_driver_flags, NULL, 3085337817Scy cli_cmd_flag_none, 3086337817Scy "= list driver flags" }, 3087252726Srpaulo { "logon", wpa_cli_cmd_logon, NULL, 3088252726Srpaulo cli_cmd_flag_none, 3089189251Ssam "= IEEE 802.1X EAPOL state machine logon" }, 3090252726Srpaulo { "logoff", wpa_cli_cmd_logoff, NULL, 3091189251Ssam cli_cmd_flag_none, 3092189251Ssam "= IEEE 802.1X EAPOL state machine logoff" }, 3093252726Srpaulo { "pmksa", wpa_cli_cmd_pmksa, NULL, 3094189251Ssam cli_cmd_flag_none, 3095189251Ssam "= show PMKSA cache" }, 3096281806Srpaulo { "pmksa_flush", wpa_cli_cmd_pmksa_flush, NULL, 3097281806Srpaulo cli_cmd_flag_none, 3098281806Srpaulo "= flush PMKSA cache entries" }, 3099346981Scy#ifdef CONFIG_PMKSA_CACHE_EXTERNAL 3100346981Scy { "pmksa_get", wpa_cli_cmd_pmksa_get, NULL, 3101346981Scy cli_cmd_flag_none, 3102346981Scy "<network_id> = fetch all stored PMKSA cache entries" }, 3103346981Scy { "pmksa_add", wpa_cli_cmd_pmksa_add, NULL, 3104346981Scy cli_cmd_flag_sensitive, 3105346981Scy "<network_id> <BSSID> <PMKID> <PMK> <reauth_time in seconds> <expiration in seconds> <akmp> <opportunistic> = store PMKSA cache entry from external storage" }, 3106346981Scy#ifdef CONFIG_MESH 3107346981Scy { "mesh_pmksa_get", wpa_cli_mesh_cmd_pmksa_get, NULL, 3108346981Scy cli_cmd_flag_none, 3109346981Scy "<peer MAC address | any> = fetch all stored mesh PMKSA cache entries" }, 3110346981Scy { "mesh_pmksa_add", wpa_cli_mesh_cmd_pmksa_add, NULL, 3111346981Scy cli_cmd_flag_sensitive, 3112346981Scy "<BSSID> <PMKID> <PMK> <expiration in seconds> = store mesh PMKSA cache entry from external storage" }, 3113346981Scy#endif /* CONFIG_MESH */ 3114346981Scy#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */ 3115252726Srpaulo { "reassociate", wpa_cli_cmd_reassociate, NULL, 3116189251Ssam cli_cmd_flag_none, 3117189251Ssam "= force reassociation" }, 3118281806Srpaulo { "reattach", wpa_cli_cmd_reattach, NULL, 3119281806Srpaulo cli_cmd_flag_none, 3120281806Srpaulo "= force reassociation back to the same BSS" }, 3121252726Srpaulo { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss, 3122189251Ssam cli_cmd_flag_none, 3123189251Ssam "<BSSID> = force preauthentication" }, 3124346981Scy { "identity", wpa_cli_cmd_identity, wpa_cli_complete_network_id, 3125189251Ssam cli_cmd_flag_none, 3126189251Ssam "<network id> <identity> = configure identity for an SSID" }, 3127346981Scy { "password", wpa_cli_cmd_password, wpa_cli_complete_network_id, 3128189251Ssam cli_cmd_flag_sensitive, 3129189251Ssam "<network id> <password> = configure password for an SSID" }, 3130346981Scy { "new_password", wpa_cli_cmd_new_password, 3131346981Scy wpa_cli_complete_network_id, cli_cmd_flag_sensitive, 3132189251Ssam "<network id> <password> = change password for an SSID" }, 3133346981Scy { "pin", wpa_cli_cmd_pin, wpa_cli_complete_network_id, 3134189251Ssam cli_cmd_flag_sensitive, 3135189251Ssam "<network id> <pin> = configure pin for an SSID" }, 3136346981Scy { "otp", wpa_cli_cmd_otp, wpa_cli_complete_network_id, 3137189251Ssam cli_cmd_flag_sensitive, 3138189251Ssam "<network id> <password> = configure one-time-password for an SSID" 3139189251Ssam }, 3140346981Scy { "psk_passphrase", wpa_cli_cmd_psk_passphrase, 3141346981Scy wpa_cli_complete_network_id, cli_cmd_flag_sensitive, 3142346981Scy "<network id> <PSK/passphrase> = configure PSK/passphrase for an SSID" }, 3143346981Scy { "passphrase", wpa_cli_cmd_passphrase, wpa_cli_complete_network_id, 3144189251Ssam cli_cmd_flag_sensitive, 3145189251Ssam "<network id> <passphrase> = configure private key passphrase\n" 3146189251Ssam " for an SSID" }, 3147346981Scy { "sim", wpa_cli_cmd_sim, wpa_cli_complete_network_id, 3148281806Srpaulo cli_cmd_flag_sensitive, 3149281806Srpaulo "<network id> <pin> = report SIM operation result" }, 3150346981Scy { "bssid", wpa_cli_cmd_bssid, wpa_cli_complete_network_id, 3151189251Ssam cli_cmd_flag_none, 3152189251Ssam "<network id> <BSSID> = set preferred BSSID for an SSID" }, 3153252726Srpaulo { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss, 3154189251Ssam cli_cmd_flag_none, 3155252726Srpaulo "<BSSID> = add a BSSID to the blacklist\n" 3156252726Srpaulo "blacklist clear = clear the blacklist\n" 3157252726Srpaulo "blacklist = display the blacklist" }, 3158252726Srpaulo { "log_level", wpa_cli_cmd_log_level, NULL, 3159252726Srpaulo cli_cmd_flag_none, 3160252726Srpaulo "<level> [<timestamp>] = update the log level/timestamp\n" 3161252726Srpaulo "log_level = display the current log level and log options" }, 3162252726Srpaulo { "list_networks", wpa_cli_cmd_list_networks, NULL, 3163252726Srpaulo cli_cmd_flag_none, 3164189251Ssam "= list configured networks" }, 3165289549Srpaulo { "select_network", wpa_cli_cmd_select_network, 3166289549Srpaulo wpa_cli_complete_network_id, 3167189251Ssam cli_cmd_flag_none, 3168189251Ssam "<network id> = select a network (disable others)" }, 3169289549Srpaulo { "enable_network", wpa_cli_cmd_enable_network, 3170289549Srpaulo wpa_cli_complete_network_id, 3171189251Ssam cli_cmd_flag_none, 3172189251Ssam "<network id> = enable a network" }, 3173289549Srpaulo { "disable_network", wpa_cli_cmd_disable_network, 3174289549Srpaulo wpa_cli_complete_network_id, 3175189251Ssam cli_cmd_flag_none, 3176189251Ssam "<network id> = disable a network" }, 3177252726Srpaulo { "add_network", wpa_cli_cmd_add_network, NULL, 3178189251Ssam cli_cmd_flag_none, 3179189251Ssam "= add a network" }, 3180289549Srpaulo { "remove_network", wpa_cli_cmd_remove_network, 3181289549Srpaulo wpa_cli_complete_network_id, 3182189251Ssam cli_cmd_flag_none, 3183189251Ssam "<network id> = remove a network" }, 3184289549Srpaulo { "set_network", wpa_cli_cmd_set_network, wpa_cli_complete_network, 3185189251Ssam cli_cmd_flag_sensitive, 3186189251Ssam "<network id> <variable> <value> = set network variables (shows\n" 3187189251Ssam " list of variables when run without arguments)" }, 3188289549Srpaulo { "get_network", wpa_cli_cmd_get_network, wpa_cli_complete_network, 3189189251Ssam cli_cmd_flag_none, 3190189251Ssam "<network id> <variable> = get network variables" }, 3191289549Srpaulo { "dup_network", wpa_cli_cmd_dup_network, wpa_cli_complete_dup_network, 3192281806Srpaulo cli_cmd_flag_none, 3193281806Srpaulo "<src network id> <dst network id> <variable> = duplicate network variables" 3194281806Srpaulo }, 3195252726Srpaulo { "list_creds", wpa_cli_cmd_list_creds, NULL, 3196189251Ssam cli_cmd_flag_none, 3197252726Srpaulo "= list configured credentials" }, 3198252726Srpaulo { "add_cred", wpa_cli_cmd_add_cred, NULL, 3199252726Srpaulo cli_cmd_flag_none, 3200252726Srpaulo "= add a credential" }, 3201252726Srpaulo { "remove_cred", wpa_cli_cmd_remove_cred, NULL, 3202252726Srpaulo cli_cmd_flag_none, 3203252726Srpaulo "<cred id> = remove a credential" }, 3204346981Scy { "set_cred", wpa_cli_cmd_set_cred, wpa_cli_complete_cred, 3205252726Srpaulo cli_cmd_flag_sensitive, 3206252726Srpaulo "<cred id> <variable> <value> = set credential variables" }, 3207346981Scy { "get_cred", wpa_cli_cmd_get_cred, wpa_cli_complete_cred, 3208281806Srpaulo cli_cmd_flag_none, 3209281806Srpaulo "<cred id> <variable> = get credential variables" }, 3210252726Srpaulo { "save_config", wpa_cli_cmd_save_config, NULL, 3211252726Srpaulo cli_cmd_flag_none, 3212189251Ssam "= save the current configuration" }, 3213252726Srpaulo { "disconnect", wpa_cli_cmd_disconnect, NULL, 3214189251Ssam cli_cmd_flag_none, 3215189251Ssam "= disconnect and wait for reassociate/reconnect command before\n" 3216189251Ssam " connecting" }, 3217252726Srpaulo { "reconnect", wpa_cli_cmd_reconnect, NULL, 3218189251Ssam cli_cmd_flag_none, 3219189251Ssam "= like reassociate, but only takes effect if already disconnected" 3220189251Ssam }, 3221252726Srpaulo { "scan", wpa_cli_cmd_scan, NULL, 3222189251Ssam cli_cmd_flag_none, 3223189251Ssam "= request new BSS scan" }, 3224252726Srpaulo { "scan_results", wpa_cli_cmd_scan_results, NULL, 3225189251Ssam cli_cmd_flag_none, 3226189251Ssam "= get latest scan results" }, 3227337817Scy { "abort_scan", wpa_cli_cmd_abort_scan, NULL, 3228337817Scy cli_cmd_flag_none, 3229337817Scy "= request ongoing scan to be aborted" }, 3230252726Srpaulo { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss, 3231189251Ssam cli_cmd_flag_none, 3232189251Ssam "<<idx> | <bssid>> = get detailed scan result info" }, 3233337817Scy { "get_capability", wpa_cli_cmd_get_capability, 3234337817Scy wpa_cli_complete_get_capability, cli_cmd_flag_none, 3235281806Srpaulo "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> " 3236289549Srpaulo "= get capabilities" }, 3237252726Srpaulo { "reconfigure", wpa_cli_cmd_reconfigure, NULL, 3238189251Ssam cli_cmd_flag_none, 3239189251Ssam "= force wpa_supplicant to re-read its configuration file" }, 3240252726Srpaulo { "terminate", wpa_cli_cmd_terminate, NULL, 3241189251Ssam cli_cmd_flag_none, 3242189251Ssam "= terminate wpa_supplicant" }, 3243252726Srpaulo { "interface_add", wpa_cli_cmd_interface_add, NULL, 3244189251Ssam cli_cmd_flag_none, 3245189251Ssam "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n" 3246337817Scy " <bridge_name> <create> <type> = adds new interface, all " 3247337817Scy "parameters but\n" 3248337817Scy " <ifname> are optional. Supported types are station ('sta') and " 3249337817Scy "AP ('ap')" }, 3250252726Srpaulo { "interface_remove", wpa_cli_cmd_interface_remove, NULL, 3251189251Ssam cli_cmd_flag_none, 3252189251Ssam "<ifname> = removes the interface" }, 3253252726Srpaulo { "interface_list", wpa_cli_cmd_interface_list, NULL, 3254189251Ssam cli_cmd_flag_none, 3255189251Ssam "= list available interfaces" }, 3256252726Srpaulo { "ap_scan", wpa_cli_cmd_ap_scan, NULL, 3257189251Ssam cli_cmd_flag_none, 3258189251Ssam "<value> = set ap_scan parameter" }, 3259252726Srpaulo { "scan_interval", wpa_cli_cmd_scan_interval, NULL, 3260189251Ssam cli_cmd_flag_none, 3261252726Srpaulo "<value> = set scan_interval parameter (in seconds)" }, 3262252726Srpaulo { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL, 3263252726Srpaulo cli_cmd_flag_none, 3264252726Srpaulo "<value> = set BSS expiration age parameter" }, 3265252726Srpaulo { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL, 3266252726Srpaulo cli_cmd_flag_none, 3267252726Srpaulo "<value> = set BSS expiration scan count parameter" }, 3268252726Srpaulo { "bss_flush", wpa_cli_cmd_bss_flush, NULL, 3269252726Srpaulo cli_cmd_flag_none, 3270252726Srpaulo "<value> = set BSS flush age (0 by default)" }, 3271252726Srpaulo { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss, 3272189251Ssam cli_cmd_flag_none, 3273189251Ssam "<addr> = request over-the-DS FT with <addr>" }, 3274252726Srpaulo { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss, 3275189251Ssam cli_cmd_flag_none, 3276189251Ssam "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" }, 3277252726Srpaulo { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss, 3278189251Ssam cli_cmd_flag_sensitive, 3279189251Ssam "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not " 3280189251Ssam "hardcoded)" }, 3281252726Srpaulo { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL, 3282214734Srpaulo cli_cmd_flag_sensitive, 3283252726Srpaulo "<PIN> = verify PIN checksum" }, 3284252726Srpaulo { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none, 3285252726Srpaulo "Cancels the pending WPS operation" }, 3286252726Srpaulo#ifdef CONFIG_WPS_NFC 3287252726Srpaulo { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss, 3288252726Srpaulo cli_cmd_flag_none, 3289252726Srpaulo "[BSSID] = start Wi-Fi Protected Setup: NFC" }, 3290281806Srpaulo { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL, 3291281806Srpaulo cli_cmd_flag_none, 3292281806Srpaulo "<WPS|NDEF> = build configuration token" }, 3293252726Srpaulo { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL, 3294252726Srpaulo cli_cmd_flag_none, 3295252726Srpaulo "<WPS|NDEF> = create password token" }, 3296252726Srpaulo { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL, 3297189251Ssam cli_cmd_flag_sensitive, 3298252726Srpaulo "<hexdump of payload> = report read NFC tag with WPS data" }, 3299252726Srpaulo { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL, 3300252726Srpaulo cli_cmd_flag_none, 3301252726Srpaulo "<NDEF> <WPS> = create NFC handover request" }, 3302252726Srpaulo { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL, 3303252726Srpaulo cli_cmd_flag_none, 3304252726Srpaulo "<NDEF> <WPS> = create NFC handover select" }, 3305281806Srpaulo { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL, 3306252726Srpaulo cli_cmd_flag_none, 3307281806Srpaulo "<role> <type> <hexdump of req> <hexdump of sel> = report completed " 3308281806Srpaulo "NFC handover" }, 3309252726Srpaulo#endif /* CONFIG_WPS_NFC */ 3310252726Srpaulo { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss, 3311252726Srpaulo cli_cmd_flag_sensitive, 3312189251Ssam "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" }, 3313252726Srpaulo { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL, 3314252726Srpaulo cli_cmd_flag_sensitive, 3315252726Srpaulo "[params..] = enable/disable AP PIN" }, 3316252726Srpaulo { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL, 3317214734Srpaulo cli_cmd_flag_none, 3318252726Srpaulo "[IP address] = start Wi-Fi Protected Setup External Registrar" }, 3319252726Srpaulo { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL, 3320214734Srpaulo cli_cmd_flag_none, 3321214734Srpaulo "= stop Wi-Fi Protected Setup External Registrar" }, 3322252726Srpaulo { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL, 3323214734Srpaulo cli_cmd_flag_sensitive, 3324214734Srpaulo "<UUID> <PIN> = add an Enrollee PIN to External Registrar" }, 3325252726Srpaulo { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL, 3326214734Srpaulo cli_cmd_flag_none, 3327214734Srpaulo "<UUID> = accept an Enrollee PBC using External Registrar" }, 3328252726Srpaulo { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL, 3329214734Srpaulo cli_cmd_flag_sensitive, 3330214734Srpaulo "<UUID> <PIN> = learn AP configuration" }, 3331252726Srpaulo { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL, 3332214734Srpaulo cli_cmd_flag_none, 3333252726Srpaulo "<UUID> <network id> = set AP configuration for enrolling" }, 3334252726Srpaulo { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL, 3335252726Srpaulo cli_cmd_flag_sensitive, 3336252726Srpaulo "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" }, 3337252726Srpaulo#ifdef CONFIG_WPS_NFC 3338252726Srpaulo { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL, 3339252726Srpaulo cli_cmd_flag_none, 3340252726Srpaulo "<WPS/NDEF> <UUID> = build NFC configuration token" }, 3341252726Srpaulo#endif /* CONFIG_WPS_NFC */ 3342252726Srpaulo { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL, 3343252726Srpaulo cli_cmd_flag_none, 3344214734Srpaulo "<addr> = request RSN authentication with <addr> in IBSS" }, 3345214734Srpaulo#ifdef CONFIG_AP 3346346981Scy { "sta", wpa_cli_cmd_sta, wpa_cli_complete_sta, 3347214734Srpaulo cli_cmd_flag_none, 3348214734Srpaulo "<addr> = get information about an associated station (AP)" }, 3349252726Srpaulo { "all_sta", wpa_cli_cmd_all_sta, NULL, 3350214734Srpaulo cli_cmd_flag_none, 3351214734Srpaulo "= get information about all associated stations (AP)" }, 3352346981Scy { "list_sta", wpa_cli_cmd_list_sta, NULL, 3353252726Srpaulo cli_cmd_flag_none, 3354346981Scy "= list all stations (AP)" }, 3355346981Scy { "deauthenticate", wpa_cli_cmd_deauthenticate, 3356346981Scy wpa_cli_complete_deauthenticate, cli_cmd_flag_none, 3357252726Srpaulo "<addr> = deauthenticate a station" }, 3358346981Scy { "disassociate", wpa_cli_cmd_disassociate, 3359346981Scy wpa_cli_complete_disassociate, cli_cmd_flag_none, 3360252726Srpaulo "<addr> = disassociate a station" }, 3361281806Srpaulo { "chan_switch", wpa_cli_cmd_chanswitch, NULL, 3362281806Srpaulo cli_cmd_flag_none, 3363281806Srpaulo "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]" 3364281806Srpaulo " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]" 3365281806Srpaulo " = CSA parameters" }, 3366214734Srpaulo#endif /* CONFIG_AP */ 3367252726Srpaulo { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none, 3368214734Srpaulo "= notification of suspend/hibernate" }, 3369252726Srpaulo { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none, 3370214734Srpaulo "= notification of resume/thaw" }, 3371281806Srpaulo#ifdef CONFIG_TESTING_OPTIONS 3372252726Srpaulo { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none, 3373214734Srpaulo "= drop SA without deauth/disassoc (test command)" }, 3374281806Srpaulo#endif /* CONFIG_TESTING_OPTIONS */ 3375252726Srpaulo { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss, 3376214734Srpaulo cli_cmd_flag_none, 3377214734Srpaulo "<addr> = roam to the specified BSS" }, 3378281806Srpaulo#ifdef CONFIG_MESH 3379281806Srpaulo { "mesh_interface_add", wpa_cli_cmd_mesh_interface_add, NULL, 3380281806Srpaulo cli_cmd_flag_none, 3381281806Srpaulo "[ifname] = Create a new mesh interface" }, 3382281806Srpaulo { "mesh_group_add", wpa_cli_cmd_mesh_group_add, NULL, 3383281806Srpaulo cli_cmd_flag_none, 3384281806Srpaulo "<network id> = join a mesh network (disable others)" }, 3385281806Srpaulo { "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL, 3386281806Srpaulo cli_cmd_flag_none, 3387281806Srpaulo "<ifname> = Remove mesh group interface" }, 3388337817Scy { "mesh_peer_remove", wpa_cli_cmd_mesh_peer_remove, NULL, 3389337817Scy cli_cmd_flag_none, 3390337817Scy "<addr> = Remove a mesh peer" }, 3391337817Scy { "mesh_peer_add", wpa_cli_cmd_mesh_peer_add, NULL, 3392337817Scy cli_cmd_flag_none, 3393337817Scy "<addr> [duration=<seconds>] = Add a mesh peer" }, 3394351611Scy { "mesh_link_probe", wpa_cli_cmd_mesh_link_probe, NULL, 3395351611Scy cli_cmd_flag_none, 3396351611Scy "<addr> [payload=<hex dump of payload>] = Probe a mesh link for a given peer by injecting a frame." }, 3397281806Srpaulo#endif /* CONFIG_MESH */ 3398252726Srpaulo#ifdef CONFIG_P2P 3399252726Srpaulo { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find, 3400252726Srpaulo cli_cmd_flag_none, 3401252726Srpaulo "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" }, 3402252726Srpaulo { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none, 3403252726Srpaulo "= stop P2P Devices search" }, 3404281806Srpaulo { "p2p_asp_provision", wpa_cli_cmd_p2p_asp_provision, NULL, 3405281806Srpaulo cli_cmd_flag_none, 3406281806Srpaulo "<addr> adv_id=<adv_id> conncap=<conncap> [info=<infodata>] = provision with a P2P ASP Device" }, 3407281806Srpaulo { "p2p_asp_provision_resp", wpa_cli_cmd_p2p_asp_provision_resp, NULL, 3408281806Srpaulo cli_cmd_flag_none, 3409281806Srpaulo "<addr> adv_id=<adv_id> [role<conncap>] [info=<infodata>] = provision with a P2P ASP Device" }, 3410252726Srpaulo { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect, 3411252726Srpaulo cli_cmd_flag_none, 3412252726Srpaulo "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" }, 3413252726Srpaulo { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none, 3414252726Srpaulo "[timeout] = listen for P2P Devices for up-to timeout seconds" }, 3415252726Srpaulo { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, 3416252726Srpaulo wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none, 3417252726Srpaulo "<ifname> = remove P2P group interface (terminate group if GO)" }, 3418252726Srpaulo { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none, 3419252726Srpaulo "[ht40] = add a new P2P group (local end as GO)" }, 3420337817Scy { "p2p_group_member", wpa_cli_cmd_p2p_group_member, NULL, 3421337817Scy cli_cmd_flag_none, 3422337817Scy "<dev_addr> = Get peer interface address on local GO using peer Device Address" }, 3423252726Srpaulo { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, 3424252726Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3425252726Srpaulo "<addr> <method> = request provisioning discovery" }, 3426252726Srpaulo { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL, 3427252726Srpaulo cli_cmd_flag_none, 3428252726Srpaulo "= get the passphrase for a group (GO only)" }, 3429252726Srpaulo { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req, 3430252726Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3431252726Srpaulo "<addr> <TLVs> = schedule service discovery request" }, 3432252726Srpaulo { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req, 3433252726Srpaulo NULL, cli_cmd_flag_none, 3434252726Srpaulo "<id> = cancel pending service discovery request" }, 3435252726Srpaulo { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL, 3436252726Srpaulo cli_cmd_flag_none, 3437252726Srpaulo "<freq> <addr> <dialog token> <TLVs> = service discovery response" }, 3438252726Srpaulo { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL, 3439252726Srpaulo cli_cmd_flag_none, 3440252726Srpaulo "= indicate change in local services" }, 3441252726Srpaulo { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL, 3442252726Srpaulo cli_cmd_flag_none, 3443252726Srpaulo "<external> = set external processing of service discovery" }, 3444252726Srpaulo { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL, 3445252726Srpaulo cli_cmd_flag_none, 3446252726Srpaulo "= remove all stored service entries" }, 3447252726Srpaulo { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL, 3448252726Srpaulo cli_cmd_flag_none, 3449281806Srpaulo "<bonjour|upnp|asp> <query|version> <response|service> = add a local " 3450252726Srpaulo "service" }, 3451281806Srpaulo { "p2p_service_rep", wpa_cli_cmd_p2p_service_rep, NULL, 3452281806Srpaulo cli_cmd_flag_none, 3453281806Srpaulo "asp <auto> <adv_id> <svc_state> <svc_string> [<svc_info>] = replace " 3454281806Srpaulo "local ASP service" }, 3455252726Srpaulo { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL, 3456252726Srpaulo cli_cmd_flag_none, 3457252726Srpaulo "<bonjour|upnp> <query|version> [|service] = remove a local " 3458252726Srpaulo "service" }, 3459252726Srpaulo { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer, 3460252726Srpaulo cli_cmd_flag_none, 3461252726Srpaulo "<addr> = reject connection attempts from a specific peer" }, 3462252726Srpaulo { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL, 3463252726Srpaulo cli_cmd_flag_none, 3464252726Srpaulo "<cmd> [peer=addr] = invite peer" }, 3465252726Srpaulo { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none, 3466252726Srpaulo "[discovered] = list known (optionally, only fully discovered) P2P " 3467252726Srpaulo "peers" }, 3468252726Srpaulo { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer, 3469252726Srpaulo cli_cmd_flag_none, 3470252726Srpaulo "<address> = show information about known P2P peer" }, 3471281806Srpaulo { "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set, 3472281806Srpaulo cli_cmd_flag_none, 3473252726Srpaulo "<field> <value> = set a P2P parameter" }, 3474252726Srpaulo { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none, 3475252726Srpaulo "= flush P2P state" }, 3476252726Srpaulo { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none, 3477252726Srpaulo "= cancel P2P group formation" }, 3478252726Srpaulo { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, 3479252726Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3480252726Srpaulo "<address> = unauthorize a peer" }, 3481252726Srpaulo { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL, 3482252726Srpaulo cli_cmd_flag_none, 3483252726Srpaulo "[<duration> <interval>] [<duration> <interval>] = request GO " 3484252726Srpaulo "presence" }, 3485252726Srpaulo { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL, 3486252726Srpaulo cli_cmd_flag_none, 3487252726Srpaulo "[<period> <interval>] = set extended listen timing" }, 3488281806Srpaulo { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client, 3489281806Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3490281806Srpaulo "<address|iface=address> = remove a peer from all groups" }, 3491346981Scy#endif /* CONFIG_P2P */ 3492337817Scy { "vendor_elem_add", wpa_cli_cmd_vendor_elem_add, NULL, 3493337817Scy cli_cmd_flag_none, 3494337817Scy "<frame id> <hexdump of elem(s)> = add vendor specific IEs to frame(s)\n" 3495337817Scy VENDOR_ELEM_FRAME_ID }, 3496337817Scy { "vendor_elem_get", wpa_cli_cmd_vendor_elem_get, NULL, 3497337817Scy cli_cmd_flag_none, 3498337817Scy "<frame id> = get vendor specific IE(s) to frame(s)\n" 3499337817Scy VENDOR_ELEM_FRAME_ID }, 3500337817Scy { "vendor_elem_remove", wpa_cli_cmd_vendor_elem_remove, NULL, 3501337817Scy cli_cmd_flag_none, 3502337817Scy "<frame id> <hexdump of elem(s)> = remove vendor specific IE(s) in frame(s)\n" 3503337817Scy VENDOR_ELEM_FRAME_ID }, 3504252726Srpaulo#ifdef CONFIG_WIFI_DISPLAY 3505252726Srpaulo { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL, 3506252726Srpaulo cli_cmd_flag_none, 3507252726Srpaulo "<subelem> [contents] = set Wi-Fi Display subelement" }, 3508252726Srpaulo { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL, 3509252726Srpaulo cli_cmd_flag_none, 3510252726Srpaulo "<subelem> = get Wi-Fi Display subelement" }, 3511252726Srpaulo#endif /* CONFIG_WIFI_DISPLAY */ 3512252726Srpaulo#ifdef CONFIG_INTERWORKING 3513252726Srpaulo { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none, 3514252726Srpaulo "= fetch ANQP information for all APs" }, 3515252726Srpaulo { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL, 3516252726Srpaulo cli_cmd_flag_none, 3517252726Srpaulo "= stop fetch_anqp operation" }, 3518252726Srpaulo { "interworking_select", wpa_cli_cmd_interworking_select, NULL, 3519252726Srpaulo cli_cmd_flag_none, 3520252726Srpaulo "[auto] = perform Interworking network selection" }, 3521252726Srpaulo { "interworking_connect", wpa_cli_cmd_interworking_connect, 3522252726Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3523252726Srpaulo "<BSSID> = connect using Interworking credentials" }, 3524281806Srpaulo { "interworking_add_network", wpa_cli_cmd_interworking_add_network, 3525281806Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3526281806Srpaulo "<BSSID> = connect using Interworking credentials" }, 3527252726Srpaulo { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss, 3528252726Srpaulo cli_cmd_flag_none, 3529252726Srpaulo "<addr> <info id>[,<info id>]... = request ANQP information" }, 3530252726Srpaulo { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss, 3531252726Srpaulo cli_cmd_flag_none, 3532252726Srpaulo "<addr> <AdvProtoID> [QueryReq] = GAS request" }, 3533252726Srpaulo { "gas_response_get", wpa_cli_cmd_gas_response_get, 3534252726Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3535252726Srpaulo "<addr> <dialog token> [start,len] = Fetch last GAS response" }, 3536252726Srpaulo#endif /* CONFIG_INTERWORKING */ 3537252726Srpaulo#ifdef CONFIG_HS20 3538252726Srpaulo { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss, 3539252726Srpaulo cli_cmd_flag_none, 3540252726Srpaulo "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information" 3541252726Srpaulo }, 3542252726Srpaulo { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list, 3543252726Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3544252726Srpaulo "<addr> <home realm> = get HS20 nai home realm list" }, 3545281806Srpaulo { "hs20_icon_request", wpa_cli_cmd_hs20_icon_request, 3546281806Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3547281806Srpaulo "<addr> <icon name> = get Hotspot 2.0 OSU icon" }, 3548281806Srpaulo { "fetch_osu", wpa_cli_cmd_fetch_osu, NULL, cli_cmd_flag_none, 3549281806Srpaulo "= fetch OSU provider information from all APs" }, 3550281806Srpaulo { "cancel_fetch_osu", wpa_cli_cmd_cancel_fetch_osu, NULL, 3551281806Srpaulo cli_cmd_flag_none, 3552281806Srpaulo "= cancel fetch_osu command" }, 3553252726Srpaulo#endif /* CONFIG_HS20 */ 3554252726Srpaulo { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL, 3555252726Srpaulo cli_cmd_flag_none, 3556252726Srpaulo "<0/1> = disable/enable automatic reconnection" }, 3557252726Srpaulo { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL, 3558252726Srpaulo cli_cmd_flag_none, 3559252726Srpaulo "<addr> = request TDLS discovery with <addr>" }, 3560252726Srpaulo { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL, 3561252726Srpaulo cli_cmd_flag_none, 3562252726Srpaulo "<addr> = request TDLS setup with <addr>" }, 3563252726Srpaulo { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL, 3564252726Srpaulo cli_cmd_flag_none, 3565252726Srpaulo "<addr> = tear down TDLS with <addr>" }, 3566289549Srpaulo { "tdls_link_status", wpa_cli_cmd_tdls_link_status, NULL, 3567289549Srpaulo cli_cmd_flag_none, 3568289549Srpaulo "<addr> = TDLS link status with <addr>" }, 3569281806Srpaulo { "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL, 3570281806Srpaulo cli_cmd_flag_none, 3571281806Srpaulo "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] " 3572281806Srpaulo "[mean_data_rate=#] [min_phy_rate=#] [sba=#] [fixed_nominal_msdu] " 3573281806Srpaulo "= add WMM-AC traffic stream" }, 3574281806Srpaulo { "wmm_ac_delts", wpa_cli_cmd_wmm_ac_delts, NULL, 3575281806Srpaulo cli_cmd_flag_none, 3576281806Srpaulo "<tsid> = delete WMM-AC traffic stream" }, 3577281806Srpaulo { "wmm_ac_status", wpa_cli_cmd_wmm_ac_status, NULL, 3578281806Srpaulo cli_cmd_flag_none, 3579281806Srpaulo "= show status for Wireless Multi-Media Admission-Control" }, 3580281806Srpaulo { "tdls_chan_switch", wpa_cli_cmd_tdls_chan_switch, NULL, 3581281806Srpaulo cli_cmd_flag_none, 3582281806Srpaulo "<addr> <oper class> <freq> [sec_channel_offset=] [center_freq1=] " 3583281806Srpaulo "[center_freq2=] [bandwidth=] [ht|vht] = enable channel switching " 3584281806Srpaulo "with TDLS peer" }, 3585281806Srpaulo { "tdls_cancel_chan_switch", wpa_cli_cmd_tdls_cancel_chan_switch, NULL, 3586281806Srpaulo cli_cmd_flag_none, 3587281806Srpaulo "<addr> = disable channel switching with TDLS peer <addr>" }, 3588252726Srpaulo { "signal_poll", wpa_cli_cmd_signal_poll, NULL, 3589252726Srpaulo cli_cmd_flag_none, 3590252726Srpaulo "= get signal parameters" }, 3591337817Scy { "signal_monitor", wpa_cli_cmd_signal_monitor, NULL, 3592337817Scy cli_cmd_flag_none, 3593337817Scy "= set signal monitor parameters" }, 3594252726Srpaulo { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL, 3595252726Srpaulo cli_cmd_flag_none, 3596252726Srpaulo "= get TX/RX packet counters" }, 3597252726Srpaulo { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL, 3598252726Srpaulo cli_cmd_flag_none, 3599252726Srpaulo "= trigger IEEE 802.1X/EAPOL reauthentication" }, 3600252726Srpaulo#ifdef CONFIG_AUTOSCAN 3601252726Srpaulo { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none, 3602252726Srpaulo "[params] = Set or unset (if none) autoscan parameters" }, 3603252726Srpaulo#endif /* CONFIG_AUTOSCAN */ 3604252726Srpaulo#ifdef CONFIG_WNM 3605252726Srpaulo { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none, 3606252726Srpaulo "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" }, 3607281806Srpaulo { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none, 3608346981Scy "<query reason> [list]" 3609346981Scy " [neighbor=<BSSID>,<BSSID information>,<operating class>,<channel number>,<PHY type>[,<hexdump of optional subelements>]" 3610346981Scy " = Send BSS Transition Management Query" }, 3611252726Srpaulo#endif /* CONFIG_WNM */ 3612252726Srpaulo { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive, 3613252726Srpaulo "<params..> = Sent unprocessed command" }, 3614281806Srpaulo { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none, 3615281806Srpaulo "= flush wpa_supplicant state" }, 3616281806Srpaulo#ifdef ANDROID 3617281806Srpaulo { "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none, 3618281806Srpaulo "<command> = driver private commands" }, 3619281806Srpaulo#endif /* ANDROID */ 3620281806Srpaulo { "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none, 3621281806Srpaulo "= radio_work <show/add/done>" }, 3622281806Srpaulo { "vendor", wpa_cli_cmd_vendor, NULL, cli_cmd_flag_none, 3623281806Srpaulo "<vendor id> <command id> [<hex formatted command argument>] = Send vendor command" 3624281806Srpaulo }, 3625281806Srpaulo { "neighbor_rep_request", 3626281806Srpaulo wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none, 3627337817Scy "[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)" 3628281806Srpaulo }, 3629281806Srpaulo { "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none, 3630281806Srpaulo "= flush ERP keys" }, 3631281806Srpaulo { "mac_rand_scan", 3632281806Srpaulo wpa_cli_cmd_mac_rand_scan, NULL, cli_cmd_flag_none, 3633281806Srpaulo "<scan|sched|pno|all> enable=<0/1> [addr=mac-address " 3634281806Srpaulo "mask=mac-address-mask] = scan MAC randomization" 3635281806Srpaulo }, 3636289549Srpaulo { "get_pref_freq_list", wpa_cli_cmd_get_pref_freq_list, NULL, 3637289549Srpaulo cli_cmd_flag_none, 3638289549Srpaulo "<interface type> = retrieve preferred freq list for the specified interface type" }, 3639337817Scy { "p2p_lo_start", wpa_cli_cmd_p2p_lo_start, NULL, 3640337817Scy cli_cmd_flag_none, 3641337817Scy "<freq> <period> <interval> <count> = start P2P listen offload" }, 3642337817Scy { "p2p_lo_stop", wpa_cli_cmd_p2p_lo_stop, NULL, 3643337817Scy cli_cmd_flag_none, 3644337817Scy "= stop P2P listen offload" }, 3645346981Scy#ifdef CONFIG_DPP 3646346981Scy { "dpp_qr_code", wpa_cli_cmd_dpp_qr_code, NULL, cli_cmd_flag_none, 3647346981Scy "report a scanned DPP URI from a QR Code" }, 3648346981Scy { "dpp_bootstrap_gen", wpa_cli_cmd_dpp_bootstrap_gen, NULL, 3649346981Scy cli_cmd_flag_sensitive, 3650346981Scy "type=<qrcode> [chan=..] [mac=..] [info=..] [curve=..] [key=..] = generate DPP bootstrap information" }, 3651346981Scy { "dpp_bootstrap_remove", wpa_cli_cmd_dpp_bootstrap_remove, NULL, 3652346981Scy cli_cmd_flag_none, 3653346981Scy "*|<id> = remove DPP bootstrap information" }, 3654346981Scy { "dpp_bootstrap_get_uri", wpa_cli_cmd_dpp_bootstrap_get_uri, NULL, 3655346981Scy cli_cmd_flag_none, 3656346981Scy "<id> = get DPP bootstrap URI" }, 3657346981Scy { "dpp_bootstrap_info", wpa_cli_cmd_dpp_bootstrap_info, NULL, 3658346981Scy cli_cmd_flag_none, 3659346981Scy "<id> = show DPP bootstrap information" }, 3660346981Scy { "dpp_auth_init", wpa_cli_cmd_dpp_auth_init, NULL, cli_cmd_flag_none, 3661346981Scy "peer=<id> [own=<id>] = initiate DPP bootstrapping" }, 3662346981Scy { "dpp_listen", wpa_cli_cmd_dpp_listen, NULL, cli_cmd_flag_none, 3663346981Scy "<freq in MHz> = start DPP listen" }, 3664346981Scy { "dpp_stop_listen", wpa_cli_cmd_dpp_stop_listen, NULL, 3665346981Scy cli_cmd_flag_none, 3666346981Scy "= stop DPP listen" }, 3667346981Scy { "dpp_configurator_add", wpa_cli_cmd_dpp_configurator_add, NULL, 3668346981Scy cli_cmd_flag_sensitive, 3669346981Scy "[curve=..] [key=..] = add DPP configurator" }, 3670346981Scy { "dpp_configurator_remove", wpa_cli_cmd_dpp_configurator_remove, NULL, 3671346981Scy cli_cmd_flag_none, 3672346981Scy "*|<id> = remove DPP configurator" }, 3673346981Scy { "dpp_configurator_get_key", wpa_cli_cmd_dpp_configurator_get_key, 3674346981Scy NULL, cli_cmd_flag_none, 3675346981Scy "<id> = Get DPP configurator's private key" }, 3676346981Scy { "dpp_configurator_sign", wpa_cli_cmd_dpp_configurator_sign, NULL, 3677346981Scy cli_cmd_flag_none, 3678346981Scy "conf=<role> configurator=<id> = generate self DPP configuration" }, 3679346981Scy { "dpp_pkex_add", wpa_cli_cmd_dpp_pkex_add, NULL, 3680346981Scy cli_cmd_flag_sensitive, 3681346981Scy "add PKEX code" }, 3682346981Scy { "dpp_pkex_remove", wpa_cli_cmd_dpp_pkex_remove, NULL, 3683346981Scy cli_cmd_flag_none, 3684346981Scy "*|<id> = remove DPP pkex information" }, 3685346981Scy#endif /* CONFIG_DPP */ 3686252726Srpaulo { NULL, NULL, NULL, cli_cmd_flag_none, NULL } 3687189251Ssam}; 3688189251Ssam 3689189251Ssam 3690189251Ssam/* 3691189251Ssam * Prints command usage, lines are padded with the specified string. 3692189251Ssam */ 3693289549Srpaulostatic void print_cmd_help(const struct wpa_cli_cmd *cmd, const char *pad) 3694189251Ssam{ 3695189251Ssam char c; 3696189251Ssam size_t n; 3697189251Ssam 3698189251Ssam printf("%s%s ", pad, cmd->cmd); 3699189251Ssam for (n = 0; (c = cmd->usage[n]); n++) { 3700189251Ssam printf("%c", c); 3701189251Ssam if (c == '\n') 3702189251Ssam printf("%s", pad); 3703189251Ssam } 3704189251Ssam printf("\n"); 3705189251Ssam} 3706189251Ssam 3707189251Ssam 3708252726Srpaulostatic void print_help(const char *cmd) 3709189251Ssam{ 3710189251Ssam int n; 3711189251Ssam printf("commands:\n"); 3712252726Srpaulo for (n = 0; wpa_cli_commands[n].cmd; n++) { 3713252726Srpaulo if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd)) 3714252726Srpaulo print_cmd_help(&wpa_cli_commands[n], " "); 3715252726Srpaulo } 3716189251Ssam} 3717189251Ssam 3718189251Ssam 3719252726Srpaulostatic int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd) 3720189251Ssam{ 3721189251Ssam const char *c, *delim; 3722189251Ssam int n; 3723189251Ssam size_t len; 3724189251Ssam 3725189251Ssam delim = os_strchr(cmd, ' '); 3726189251Ssam if (delim) 3727189251Ssam len = delim - cmd; 3728189251Ssam else 3729189251Ssam len = os_strlen(cmd); 3730189251Ssam 3731189251Ssam for (n = 0; (c = wpa_cli_commands[n].cmd); n++) { 3732189251Ssam if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c)) 3733189251Ssam return (wpa_cli_commands[n].flags & 3734189251Ssam cli_cmd_flag_sensitive); 3735189251Ssam } 3736189251Ssam return 0; 3737189251Ssam} 3738189251Ssam 3739189251Ssam 3740252726Srpaulostatic char ** wpa_list_cmd_list(void) 3741252726Srpaulo{ 3742252726Srpaulo char **res; 3743252726Srpaulo int i, count; 3744281806Srpaulo struct cli_txt_entry *e; 3745252726Srpaulo 3746281806Srpaulo count = ARRAY_SIZE(wpa_cli_commands); 3747281806Srpaulo count += dl_list_len(&p2p_groups); 3748281806Srpaulo count += dl_list_len(&ifnames); 3749281806Srpaulo res = os_calloc(count + 1, sizeof(char *)); 3750252726Srpaulo if (res == NULL) 3751252726Srpaulo return NULL; 3752252726Srpaulo 3753252726Srpaulo for (i = 0; wpa_cli_commands[i].cmd; i++) { 3754252726Srpaulo res[i] = os_strdup(wpa_cli_commands[i].cmd); 3755252726Srpaulo if (res[i] == NULL) 3756252726Srpaulo break; 3757252726Srpaulo } 3758252726Srpaulo 3759281806Srpaulo dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) { 3760281806Srpaulo size_t len = 8 + os_strlen(e->txt); 3761281806Srpaulo res[i] = os_malloc(len); 3762281806Srpaulo if (res[i] == NULL) 3763281806Srpaulo break; 3764281806Srpaulo os_snprintf(res[i], len, "ifname=%s", e->txt); 3765281806Srpaulo i++; 3766281806Srpaulo } 3767281806Srpaulo 3768281806Srpaulo dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) { 3769281806Srpaulo res[i] = os_strdup(e->txt); 3770281806Srpaulo if (res[i] == NULL) 3771281806Srpaulo break; 3772281806Srpaulo i++; 3773281806Srpaulo } 3774281806Srpaulo 3775252726Srpaulo return res; 3776252726Srpaulo} 3777252726Srpaulo 3778252726Srpaulo 3779252726Srpaulostatic char ** wpa_cli_cmd_completion(const char *cmd, const char *str, 3780252726Srpaulo int pos) 3781252726Srpaulo{ 3782252726Srpaulo int i; 3783252726Srpaulo 3784252726Srpaulo for (i = 0; wpa_cli_commands[i].cmd; i++) { 3785252726Srpaulo if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) { 3786252726Srpaulo if (wpa_cli_commands[i].completion) 3787252726Srpaulo return wpa_cli_commands[i].completion(str, 3788252726Srpaulo pos); 3789252726Srpaulo edit_clear_line(); 3790252726Srpaulo printf("\r%s\n", wpa_cli_commands[i].usage); 3791252726Srpaulo edit_redraw(); 3792252726Srpaulo break; 3793252726Srpaulo } 3794252726Srpaulo } 3795252726Srpaulo 3796252726Srpaulo return NULL; 3797252726Srpaulo} 3798252726Srpaulo 3799252726Srpaulo 3800252726Srpaulostatic char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos) 3801252726Srpaulo{ 3802252726Srpaulo char **res; 3803252726Srpaulo const char *end; 3804252726Srpaulo char *cmd; 3805252726Srpaulo 3806281806Srpaulo if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) { 3807281806Srpaulo end = os_strchr(str, ' '); 3808281806Srpaulo if (end && pos > end - str) { 3809281806Srpaulo pos -= end - str + 1; 3810281806Srpaulo str = end + 1; 3811281806Srpaulo } 3812281806Srpaulo } 3813281806Srpaulo 3814252726Srpaulo end = os_strchr(str, ' '); 3815252726Srpaulo if (end == NULL || str + pos < end) 3816252726Srpaulo return wpa_list_cmd_list(); 3817252726Srpaulo 3818252726Srpaulo cmd = os_malloc(pos + 1); 3819252726Srpaulo if (cmd == NULL) 3820252726Srpaulo return NULL; 3821252726Srpaulo os_memcpy(cmd, str, pos); 3822252726Srpaulo cmd[end - str] = '\0'; 3823252726Srpaulo res = wpa_cli_cmd_completion(cmd, str, pos); 3824252726Srpaulo os_free(cmd); 3825252726Srpaulo return res; 3826252726Srpaulo} 3827252726Srpaulo 3828252726Srpaulo 3829189251Ssamstatic int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[]) 3830189251Ssam{ 3831289549Srpaulo const struct wpa_cli_cmd *cmd, *match = NULL; 3832189251Ssam int count; 3833189251Ssam int ret = 0; 3834189251Ssam 3835281806Srpaulo if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) { 3836281806Srpaulo ifname_prefix = argv[0] + 7; 3837281806Srpaulo argv = &argv[1]; 3838281806Srpaulo argc--; 3839281806Srpaulo } else 3840281806Srpaulo ifname_prefix = NULL; 3841281806Srpaulo 3842281806Srpaulo if (argc == 0) 3843281806Srpaulo return -1; 3844281806Srpaulo 3845189251Ssam count = 0; 3846189251Ssam cmd = wpa_cli_commands; 3847189251Ssam while (cmd->cmd) { 3848189251Ssam if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0) 3849189251Ssam { 3850189251Ssam match = cmd; 3851189251Ssam if (os_strcasecmp(cmd->cmd, argv[0]) == 0) { 3852189251Ssam /* we have an exact match */ 3853189251Ssam count = 1; 3854189251Ssam break; 3855189251Ssam } 3856189251Ssam count++; 3857189251Ssam } 3858189251Ssam cmd++; 3859189251Ssam } 3860189251Ssam 3861189251Ssam if (count > 1) { 3862189251Ssam printf("Ambiguous command '%s'; possible commands:", argv[0]); 3863189251Ssam cmd = wpa_cli_commands; 3864189251Ssam while (cmd->cmd) { 3865189251Ssam if (os_strncasecmp(cmd->cmd, argv[0], 3866189251Ssam os_strlen(argv[0])) == 0) { 3867189251Ssam printf(" %s", cmd->cmd); 3868189251Ssam } 3869189251Ssam cmd++; 3870189251Ssam } 3871189251Ssam printf("\n"); 3872189251Ssam ret = 1; 3873189251Ssam } else if (count == 0) { 3874189251Ssam printf("Unknown command '%s'\n", argv[0]); 3875189251Ssam ret = 1; 3876189251Ssam } else { 3877189251Ssam ret = match->handler(ctrl, argc - 1, &argv[1]); 3878189251Ssam } 3879189251Ssam 3880189251Ssam return ret; 3881189251Ssam} 3882189251Ssam 3883189251Ssam 3884189251Ssamstatic int wpa_cli_exec(const char *program, const char *arg1, 3885189251Ssam const char *arg2) 3886189251Ssam{ 3887281806Srpaulo char *arg; 3888189251Ssam size_t len; 3889189251Ssam int res; 3890189251Ssam 3891337817Scy /* If no interface is specified, set the global */ 3892337817Scy if (!arg1) 3893337817Scy arg1 = "global"; 3894337817Scy 3895281806Srpaulo len = os_strlen(arg1) + os_strlen(arg2) + 2; 3896281806Srpaulo arg = os_malloc(len); 3897281806Srpaulo if (arg == NULL) 3898189251Ssam return -1; 3899281806Srpaulo os_snprintf(arg, len, "%s %s", arg1, arg2); 3900281806Srpaulo res = os_exec(program, arg, 1); 3901281806Srpaulo os_free(arg); 3902189251Ssam 3903281806Srpaulo return res; 3904189251Ssam} 3905189251Ssam 3906189251Ssam 3907189251Ssamstatic void wpa_cli_action_process(const char *msg) 3908189251Ssam{ 3909189251Ssam const char *pos; 3910189251Ssam char *copy = NULL, *id, *pos2; 3911281806Srpaulo const char *ifname = ctrl_ifname; 3912281806Srpaulo char ifname_buf[100]; 3913189251Ssam 3914289549Srpaulo if (eloop_terminated()) 3915289549Srpaulo return; 3916289549Srpaulo 3917189251Ssam pos = msg; 3918281806Srpaulo if (os_strncmp(pos, "IFNAME=", 7) == 0) { 3919281806Srpaulo const char *end; 3920281806Srpaulo end = os_strchr(pos + 7, ' '); 3921281806Srpaulo if (end && (unsigned int) (end - pos) < sizeof(ifname_buf)) { 3922281806Srpaulo pos += 7; 3923281806Srpaulo os_memcpy(ifname_buf, pos, end - pos); 3924281806Srpaulo ifname_buf[end - pos] = '\0'; 3925281806Srpaulo ifname = ifname_buf; 3926281806Srpaulo pos = end + 1; 3927281806Srpaulo } 3928281806Srpaulo } 3929189251Ssam if (*pos == '<') { 3930281806Srpaulo const char *prev = pos; 3931189251Ssam /* skip priority */ 3932189251Ssam pos = os_strchr(pos, '>'); 3933189251Ssam if (pos) 3934189251Ssam pos++; 3935189251Ssam else 3936281806Srpaulo pos = prev; 3937189251Ssam } 3938189251Ssam 3939337817Scy if (str_starts(pos, WPA_EVENT_CONNECTED)) { 3940189251Ssam int new_id = -1; 3941189251Ssam os_unsetenv("WPA_ID"); 3942189251Ssam os_unsetenv("WPA_ID_STR"); 3943189251Ssam os_unsetenv("WPA_CTRL_DIR"); 3944189251Ssam 3945189251Ssam pos = os_strstr(pos, "[id="); 3946189251Ssam if (pos) 3947189251Ssam copy = os_strdup(pos + 4); 3948189251Ssam 3949189251Ssam if (copy) { 3950189251Ssam pos2 = id = copy; 3951189251Ssam while (*pos2 && *pos2 != ' ') 3952189251Ssam pos2++; 3953189251Ssam *pos2++ = '\0'; 3954189251Ssam new_id = atoi(id); 3955189251Ssam os_setenv("WPA_ID", id, 1); 3956189251Ssam while (*pos2 && *pos2 != '=') 3957189251Ssam pos2++; 3958189251Ssam if (*pos2 == '=') 3959189251Ssam pos2++; 3960189251Ssam id = pos2; 3961189251Ssam while (*pos2 && *pos2 != ']') 3962189251Ssam pos2++; 3963189251Ssam *pos2 = '\0'; 3964189251Ssam os_setenv("WPA_ID_STR", id, 1); 3965189251Ssam os_free(copy); 3966189251Ssam } 3967189251Ssam 3968189251Ssam os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1); 3969189251Ssam 3970281806Srpaulo if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) { 3971189251Ssam wpa_cli_connected = 1; 3972189251Ssam wpa_cli_last_id = new_id; 3973281806Srpaulo wpa_cli_exec(action_file, ifname, "CONNECTED"); 3974189251Ssam } 3975337817Scy } else if (str_starts(pos, WPA_EVENT_DISCONNECTED)) { 3976189251Ssam if (wpa_cli_connected) { 3977189251Ssam wpa_cli_connected = 0; 3978281806Srpaulo wpa_cli_exec(action_file, ifname, "DISCONNECTED"); 3979189251Ssam } 3980351611Scy } else if (str_starts(pos, WPA_EVENT_CHANNEL_SWITCH_STARTED)) { 3981351611Scy wpa_cli_exec(action_file, ctrl_ifname, pos); 3982337817Scy } else if (str_starts(pos, AP_EVENT_ENABLED)) { 3983281806Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 3984337817Scy } else if (str_starts(pos, AP_EVENT_DISABLED)) { 3985281806Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 3986337817Scy } else if (str_starts(pos, MESH_GROUP_STARTED)) { 3987281806Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 3988337817Scy } else if (str_starts(pos, MESH_GROUP_REMOVED)) { 3989281806Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 3990337817Scy } else if (str_starts(pos, MESH_PEER_CONNECTED)) { 3991337817Scy wpa_cli_exec(action_file, ctrl_ifname, pos); 3992337817Scy } else if (str_starts(pos, MESH_PEER_DISCONNECTED)) { 3993337817Scy wpa_cli_exec(action_file, ctrl_ifname, pos); 3994337817Scy } else if (str_starts(pos, P2P_EVENT_GROUP_STARTED)) { 3995281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3996337817Scy } else if (str_starts(pos, P2P_EVENT_GROUP_REMOVED)) { 3997281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3998337817Scy } else if (str_starts(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) { 3999281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 4000337817Scy } else if (str_starts(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) { 4001281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 4002337817Scy } else if (str_starts(pos, P2P_EVENT_GO_NEG_FAILURE)) { 4003281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 4004337817Scy } else if (str_starts(pos, WPS_EVENT_SUCCESS)) { 4005281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 4006346981Scy } else if (str_starts(pos, WPS_EVENT_ACTIVE)) { 4007346981Scy wpa_cli_exec(action_file, ifname, pos); 4008346981Scy } else if (str_starts(pos, WPS_EVENT_TIMEOUT)) { 4009346981Scy wpa_cli_exec(action_file, ifname, pos); 4010337817Scy } else if (str_starts(pos, WPS_EVENT_FAIL)) { 4011281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 4012337817Scy } else if (str_starts(pos, AP_STA_CONNECTED)) { 4013281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 4014337817Scy } else if (str_starts(pos, AP_STA_DISCONNECTED)) { 4015281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 4016337817Scy } else if (str_starts(pos, ESS_DISASSOC_IMMINENT)) { 4017281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 4018337817Scy } else if (str_starts(pos, HS20_SUBSCRIPTION_REMEDIATION)) { 4019281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 4020337817Scy } else if (str_starts(pos, HS20_DEAUTH_IMMINENT_NOTICE)) { 4021281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 4022346981Scy } else if (str_starts(pos, HS20_T_C_ACCEPTANCE)) { 4023346981Scy wpa_cli_exec(action_file, ifname, pos); 4024351611Scy } else if (str_starts(pos, DPP_EVENT_CONF_RECEIVED)) { 4025351611Scy wpa_cli_exec(action_file, ifname, pos); 4026351611Scy } else if (str_starts(pos, DPP_EVENT_CONFOBJ_AKM)) { 4027351611Scy wpa_cli_exec(action_file, ifname, pos); 4028351611Scy } else if (str_starts(pos, DPP_EVENT_CONFOBJ_SSID)) { 4029351611Scy wpa_cli_exec(action_file, ifname, pos); 4030351611Scy } else if (str_starts(pos, DPP_EVENT_CONNECTOR)) { 4031351611Scy wpa_cli_exec(action_file, ifname, pos); 4032351611Scy } else if (str_starts(pos, DPP_EVENT_CONFOBJ_PASS)) { 4033351611Scy wpa_cli_exec(action_file, ifname, pos); 4034351611Scy } else if (str_starts(pos, DPP_EVENT_CONFOBJ_PSK)) { 4035351611Scy wpa_cli_exec(action_file, ifname, pos); 4036351611Scy } else if (str_starts(pos, DPP_EVENT_C_SIGN_KEY)) { 4037351611Scy wpa_cli_exec(action_file, ifname, pos); 4038351611Scy } else if (str_starts(pos, DPP_EVENT_NET_ACCESS_KEY)) { 4039351611Scy wpa_cli_exec(action_file, ifname, pos); 4040337817Scy } else if (str_starts(pos, WPA_EVENT_TERMINATING)) { 4041189251Ssam printf("wpa_supplicant is terminating - stop monitoring\n"); 4042189251Ssam wpa_cli_quit = 1; 4043189251Ssam } 4044189251Ssam} 4045189251Ssam 4046189251Ssam 4047189251Ssam#ifndef CONFIG_ANSI_C_EXTRA 4048189251Ssamstatic void wpa_cli_action_cb(char *msg, size_t len) 4049189251Ssam{ 4050189251Ssam wpa_cli_action_process(msg); 4051189251Ssam} 4052189251Ssam#endif /* CONFIG_ANSI_C_EXTRA */ 4053189251Ssam 4054189251Ssam 4055346981Scystatic int wpa_cli_open_global_ctrl(void) 4056346981Scy{ 4057346981Scy#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 4058346981Scy ctrl_conn = wpa_ctrl_open(NULL); 4059346981Scy#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 4060346981Scy ctrl_conn = wpa_ctrl_open(global); 4061346981Scy#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 4062346981Scy if (!ctrl_conn) { 4063346981Scy fprintf(stderr, 4064346981Scy "Failed to connect to wpa_supplicant global interface: %s error: %s\n", 4065346981Scy global, strerror(errno)); 4066346981Scy return -1; 4067346981Scy } 4068346981Scy 4069346981Scy if (interactive) { 4070346981Scy update_ifnames(ctrl_conn); 4071346981Scy mon_conn = wpa_ctrl_open(global); 4072346981Scy if (mon_conn) { 4073346981Scy if (wpa_ctrl_attach(mon_conn) == 0) { 4074346981Scy wpa_cli_attached = 1; 4075346981Scy eloop_register_read_sock( 4076346981Scy wpa_ctrl_get_fd(mon_conn), 4077346981Scy wpa_cli_mon_receive, 4078346981Scy NULL, NULL); 4079346981Scy } else { 4080346981Scy printf("Failed to open monitor connection through global control interface\n"); 4081346981Scy } 4082346981Scy } 4083346981Scy update_stations(ctrl_conn); 4084346981Scy } 4085346981Scy 4086346981Scy return 0; 4087346981Scy} 4088346981Scy 4089346981Scy 4090189251Ssamstatic void wpa_cli_reconnect(void) 4091189251Ssam{ 4092189251Ssam wpa_cli_close_connection(); 4093346981Scy if ((global && wpa_cli_open_global_ctrl() < 0) || 4094346981Scy (!global && wpa_cli_open_connection(ctrl_ifname, 1) < 0)) 4095252726Srpaulo return; 4096252726Srpaulo 4097252726Srpaulo if (interactive) { 4098252726Srpaulo edit_clear_line(); 4099252726Srpaulo printf("\rConnection to wpa_supplicant re-established\n"); 4100252726Srpaulo edit_redraw(); 4101346981Scy update_stations(ctrl_conn); 4102252726Srpaulo } 4103189251Ssam} 4104189251Ssam 4105189251Ssam 4106252726Srpaulostatic void cli_event(const char *str) 4107189251Ssam{ 4108252726Srpaulo const char *start, *s; 4109252726Srpaulo 4110252726Srpaulo start = os_strchr(str, '>'); 4111252726Srpaulo if (start == NULL) 4112252726Srpaulo return; 4113252726Srpaulo 4114252726Srpaulo start++; 4115252726Srpaulo 4116252726Srpaulo if (str_starts(start, WPA_EVENT_BSS_ADDED)) { 4117252726Srpaulo s = os_strchr(start, ' '); 4118252726Srpaulo if (s == NULL) 4119252726Srpaulo return; 4120252726Srpaulo s = os_strchr(s + 1, ' '); 4121252726Srpaulo if (s == NULL) 4122252726Srpaulo return; 4123252726Srpaulo cli_txt_list_add(&bsses, s + 1); 4124252726Srpaulo return; 4125252726Srpaulo } 4126252726Srpaulo 4127252726Srpaulo if (str_starts(start, WPA_EVENT_BSS_REMOVED)) { 4128252726Srpaulo s = os_strchr(start, ' '); 4129252726Srpaulo if (s == NULL) 4130252726Srpaulo return; 4131252726Srpaulo s = os_strchr(s + 1, ' '); 4132252726Srpaulo if (s == NULL) 4133252726Srpaulo return; 4134252726Srpaulo cli_txt_list_del_addr(&bsses, s + 1); 4135252726Srpaulo return; 4136252726Srpaulo } 4137252726Srpaulo 4138252726Srpaulo#ifdef CONFIG_P2P 4139252726Srpaulo if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) { 4140252726Srpaulo s = os_strstr(start, " p2p_dev_addr="); 4141252726Srpaulo if (s == NULL) 4142252726Srpaulo return; 4143252726Srpaulo cli_txt_list_add_addr(&p2p_peers, s + 14); 4144252726Srpaulo return; 4145252726Srpaulo } 4146252726Srpaulo 4147252726Srpaulo if (str_starts(start, P2P_EVENT_DEVICE_LOST)) { 4148252726Srpaulo s = os_strstr(start, " p2p_dev_addr="); 4149252726Srpaulo if (s == NULL) 4150252726Srpaulo return; 4151252726Srpaulo cli_txt_list_del_addr(&p2p_peers, s + 14); 4152252726Srpaulo return; 4153252726Srpaulo } 4154252726Srpaulo 4155252726Srpaulo if (str_starts(start, P2P_EVENT_GROUP_STARTED)) { 4156252726Srpaulo s = os_strchr(start, ' '); 4157252726Srpaulo if (s == NULL) 4158252726Srpaulo return; 4159289549Srpaulo cli_txt_list_add_word(&p2p_groups, s + 1, ' '); 4160252726Srpaulo return; 4161252726Srpaulo } 4162252726Srpaulo 4163252726Srpaulo if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) { 4164252726Srpaulo s = os_strchr(start, ' '); 4165252726Srpaulo if (s == NULL) 4166252726Srpaulo return; 4167289549Srpaulo cli_txt_list_del_word(&p2p_groups, s + 1, ' '); 4168252726Srpaulo return; 4169252726Srpaulo } 4170252726Srpaulo#endif /* CONFIG_P2P */ 4171252726Srpaulo} 4172252726Srpaulo 4173252726Srpaulo 4174252726Srpaulostatic int check_terminating(const char *msg) 4175252726Srpaulo{ 4176252726Srpaulo const char *pos = msg; 4177252726Srpaulo 4178252726Srpaulo if (*pos == '<') { 4179252726Srpaulo /* skip priority */ 4180252726Srpaulo pos = os_strchr(pos, '>'); 4181252726Srpaulo if (pos) 4182252726Srpaulo pos++; 4183252726Srpaulo else 4184252726Srpaulo pos = msg; 4185252726Srpaulo } 4186252726Srpaulo 4187337817Scy if (str_starts(pos, WPA_EVENT_TERMINATING) && ctrl_conn) { 4188252726Srpaulo edit_clear_line(); 4189252726Srpaulo printf("\rConnection to wpa_supplicant lost - trying to " 4190252726Srpaulo "reconnect\n"); 4191252726Srpaulo edit_redraw(); 4192252726Srpaulo wpa_cli_attached = 0; 4193252726Srpaulo wpa_cli_close_connection(); 4194252726Srpaulo return 1; 4195252726Srpaulo } 4196252726Srpaulo 4197252726Srpaulo return 0; 4198252726Srpaulo} 4199252726Srpaulo 4200252726Srpaulo 4201252726Srpaulostatic void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor) 4202252726Srpaulo{ 4203189251Ssam if (ctrl_conn == NULL) { 4204189251Ssam wpa_cli_reconnect(); 4205189251Ssam return; 4206189251Ssam } 4207189251Ssam while (wpa_ctrl_pending(ctrl) > 0) { 4208281806Srpaulo char buf[4096]; 4209189251Ssam size_t len = sizeof(buf) - 1; 4210189251Ssam if (wpa_ctrl_recv(ctrl, buf, &len) == 0) { 4211189251Ssam buf[len] = '\0'; 4212189251Ssam if (action_monitor) 4213189251Ssam wpa_cli_action_process(buf); 4214189251Ssam else { 4215252726Srpaulo cli_event(buf); 4216252726Srpaulo if (wpa_cli_show_event(buf)) { 4217252726Srpaulo edit_clear_line(); 4218252726Srpaulo printf("\r%s\n", buf); 4219252726Srpaulo edit_redraw(); 4220252726Srpaulo } 4221252726Srpaulo 4222252726Srpaulo if (interactive && check_terminating(buf) > 0) 4223252726Srpaulo return; 4224189251Ssam } 4225189251Ssam } else { 4226189251Ssam printf("Could not read pending message.\n"); 4227189251Ssam break; 4228189251Ssam } 4229189251Ssam } 4230189251Ssam 4231189251Ssam if (wpa_ctrl_pending(ctrl) < 0) { 4232189251Ssam printf("Connection to wpa_supplicant lost - trying to " 4233189251Ssam "reconnect\n"); 4234189251Ssam wpa_cli_reconnect(); 4235189251Ssam } 4236189251Ssam} 4237189251Ssam 4238189251Ssam 4239252726Srpaulostatic void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx) 4240189251Ssam{ 4241281806Srpaulo if (ctrl_conn) { 4242281806Srpaulo int res; 4243281806Srpaulo char *prefix = ifname_prefix; 4244281806Srpaulo 4245281806Srpaulo ifname_prefix = NULL; 4246281806Srpaulo res = _wpa_ctrl_command(ctrl_conn, "PING", 0); 4247281806Srpaulo ifname_prefix = prefix; 4248281806Srpaulo if (res) { 4249281806Srpaulo printf("Connection to wpa_supplicant lost - trying to " 4250281806Srpaulo "reconnect\n"); 4251281806Srpaulo wpa_cli_close_connection(); 4252281806Srpaulo } 4253214734Srpaulo } 4254252726Srpaulo if (!ctrl_conn) 4255252726Srpaulo wpa_cli_reconnect(); 4256252726Srpaulo eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL); 4257189251Ssam} 4258189251Ssam 4259189251Ssam 4260252726Srpaulostatic void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx) 4261214734Srpaulo{ 4262252726Srpaulo wpa_cli_recv_pending(mon_conn, 0); 4263252726Srpaulo} 4264214734Srpaulo 4265214734Srpaulo 4266252726Srpaulostatic void wpa_cli_edit_cmd_cb(void *ctx, char *cmd) 4267252726Srpaulo{ 4268252726Srpaulo char *argv[max_args]; 4269252726Srpaulo int argc; 4270252726Srpaulo argc = tokenize_cmd(cmd, argv); 4271252726Srpaulo if (argc) 4272252726Srpaulo wpa_request(ctrl_conn, argc, argv); 4273214734Srpaulo} 4274214734Srpaulo 4275214734Srpaulo 4276252726Srpaulostatic void wpa_cli_edit_eof_cb(void *ctx) 4277189251Ssam{ 4278252726Srpaulo eloop_terminate(); 4279189251Ssam} 4280189251Ssam 4281189251Ssam 4282252726Srpaulostatic int warning_displayed = 0; 4283252726Srpaulostatic char *hfile = NULL; 4284252726Srpaulostatic int edit_started = 0; 4285252726Srpaulo 4286252726Srpaulostatic void start_edit(void) 4287189251Ssam{ 4288252726Srpaulo char *home; 4289252726Srpaulo char *ps = NULL; 4290189251Ssam 4291252726Srpaulo#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE 4292252726Srpaulo ps = wpa_ctrl_get_remote_ifname(ctrl_conn); 4293252726Srpaulo#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */ 4294189251Ssam 4295289549Srpaulo#ifdef CONFIG_WPA_CLI_HISTORY_DIR 4296289549Srpaulo home = CONFIG_WPA_CLI_HISTORY_DIR; 4297289549Srpaulo#else /* CONFIG_WPA_CLI_HISTORY_DIR */ 4298189251Ssam home = getenv("HOME"); 4299289549Srpaulo#endif /* CONFIG_WPA_CLI_HISTORY_DIR */ 4300189251Ssam if (home) { 4301189251Ssam const char *fname = ".wpa_cli_history"; 4302189251Ssam int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1; 4303189251Ssam hfile = os_malloc(hfile_len); 4304252726Srpaulo if (hfile) 4305252726Srpaulo os_snprintf(hfile, hfile_len, "%s/%s", home, fname); 4306189251Ssam } 4307189251Ssam 4308252726Srpaulo if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb, 4309252726Srpaulo wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) { 4310252726Srpaulo eloop_terminate(); 4311252726Srpaulo return; 4312252726Srpaulo } 4313189251Ssam 4314252726Srpaulo edit_started = 1; 4315252726Srpaulo eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL); 4316252726Srpaulo} 4317189251Ssam 4318252726Srpaulo 4319281806Srpaulostatic void update_bssid_list(struct wpa_ctrl *ctrl) 4320281806Srpaulo{ 4321281806Srpaulo char buf[4096]; 4322281806Srpaulo size_t len = sizeof(buf); 4323281806Srpaulo int ret; 4324346981Scy const char *cmd = "BSS RANGE=ALL MASK=0x2"; 4325281806Srpaulo char *pos, *end; 4326281806Srpaulo 4327281806Srpaulo if (ctrl == NULL) 4328281806Srpaulo return; 4329281806Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 4330281806Srpaulo if (ret < 0) 4331281806Srpaulo return; 4332281806Srpaulo buf[len] = '\0'; 4333281806Srpaulo 4334281806Srpaulo pos = buf; 4335281806Srpaulo while (pos) { 4336281806Srpaulo pos = os_strstr(pos, "bssid="); 4337281806Srpaulo if (pos == NULL) 4338281806Srpaulo break; 4339281806Srpaulo pos += 6; 4340281806Srpaulo end = os_strchr(pos, '\n'); 4341281806Srpaulo if (end == NULL) 4342281806Srpaulo break; 4343281806Srpaulo *end = '\0'; 4344281806Srpaulo cli_txt_list_add(&bsses, pos); 4345281806Srpaulo pos = end + 1; 4346281806Srpaulo } 4347281806Srpaulo} 4348281806Srpaulo 4349281806Srpaulo 4350281806Srpaulostatic void update_ifnames(struct wpa_ctrl *ctrl) 4351281806Srpaulo{ 4352281806Srpaulo char buf[4096]; 4353281806Srpaulo size_t len = sizeof(buf); 4354281806Srpaulo int ret; 4355346981Scy const char *cmd = "INTERFACES"; 4356281806Srpaulo char *pos, *end; 4357281806Srpaulo char txt[200]; 4358281806Srpaulo 4359281806Srpaulo cli_txt_list_flush(&ifnames); 4360281806Srpaulo 4361281806Srpaulo if (ctrl == NULL) 4362281806Srpaulo return; 4363281806Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 4364281806Srpaulo if (ret < 0) 4365281806Srpaulo return; 4366281806Srpaulo buf[len] = '\0'; 4367281806Srpaulo 4368281806Srpaulo pos = buf; 4369281806Srpaulo while (pos) { 4370281806Srpaulo end = os_strchr(pos, '\n'); 4371281806Srpaulo if (end == NULL) 4372281806Srpaulo break; 4373281806Srpaulo *end = '\0'; 4374281806Srpaulo ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos); 4375281806Srpaulo if (!os_snprintf_error(sizeof(txt), ret)) 4376281806Srpaulo cli_txt_list_add(&ifnames, txt); 4377281806Srpaulo pos = end + 1; 4378281806Srpaulo } 4379281806Srpaulo} 4380281806Srpaulo 4381281806Srpaulo 4382346981Scystatic void update_creds(struct wpa_ctrl *ctrl) 4383346981Scy{ 4384346981Scy char buf[4096]; 4385346981Scy size_t len = sizeof(buf); 4386346981Scy int ret; 4387346981Scy const char *cmd = "LIST_CREDS"; 4388346981Scy char *pos, *end; 4389346981Scy int header = 1; 4390346981Scy 4391346981Scy cli_txt_list_flush(&creds); 4392346981Scy 4393346981Scy if (ctrl == NULL) 4394346981Scy return; 4395346981Scy ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 4396346981Scy if (ret < 0) 4397346981Scy return; 4398346981Scy buf[len] = '\0'; 4399346981Scy 4400346981Scy pos = buf; 4401346981Scy while (pos) { 4402346981Scy end = os_strchr(pos, '\n'); 4403346981Scy if (end == NULL) 4404346981Scy break; 4405346981Scy *end = '\0'; 4406346981Scy if (!header) 4407346981Scy cli_txt_list_add_word(&creds, pos, '\t'); 4408346981Scy header = 0; 4409346981Scy pos = end + 1; 4410346981Scy } 4411346981Scy} 4412346981Scy 4413346981Scy 4414289549Srpaulostatic void update_networks(struct wpa_ctrl *ctrl) 4415289549Srpaulo{ 4416289549Srpaulo char buf[4096]; 4417289549Srpaulo size_t len = sizeof(buf); 4418289549Srpaulo int ret; 4419346981Scy const char *cmd = "LIST_NETWORKS"; 4420289549Srpaulo char *pos, *end; 4421289549Srpaulo int header = 1; 4422289549Srpaulo 4423289549Srpaulo cli_txt_list_flush(&networks); 4424289549Srpaulo 4425289549Srpaulo if (ctrl == NULL) 4426289549Srpaulo return; 4427289549Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 4428289549Srpaulo if (ret < 0) 4429289549Srpaulo return; 4430289549Srpaulo buf[len] = '\0'; 4431289549Srpaulo 4432289549Srpaulo pos = buf; 4433289549Srpaulo while (pos) { 4434289549Srpaulo end = os_strchr(pos, '\n'); 4435289549Srpaulo if (end == NULL) 4436289549Srpaulo break; 4437289549Srpaulo *end = '\0'; 4438289549Srpaulo if (!header) 4439289549Srpaulo cli_txt_list_add_word(&networks, pos, '\t'); 4440289549Srpaulo header = 0; 4441289549Srpaulo pos = end + 1; 4442289549Srpaulo } 4443289549Srpaulo} 4444289549Srpaulo 4445289549Srpaulo 4446346981Scystatic void update_stations(struct wpa_ctrl *ctrl) 4447346981Scy{ 4448346981Scy#ifdef CONFIG_AP 4449346981Scy char addr[32], cmd[64]; 4450346981Scy 4451346981Scy if (!ctrl || !interactive) 4452346981Scy return; 4453346981Scy 4454346981Scy cli_txt_list_flush(&stations); 4455346981Scy 4456346981Scy if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 0)) 4457346981Scy return; 4458346981Scy do { 4459346981Scy if (os_strcmp(addr, "") != 0) 4460346981Scy cli_txt_list_add(&stations, addr); 4461346981Scy os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); 4462346981Scy } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 0) == 0); 4463346981Scy#endif /* CONFIG_AP */ 4464346981Scy} 4465346981Scy 4466346981Scy 4467252726Srpaulostatic void try_connection(void *eloop_ctx, void *timeout_ctx) 4468252726Srpaulo{ 4469281806Srpaulo if (ctrl_conn) 4470281806Srpaulo goto done; 4471281806Srpaulo 4472252726Srpaulo if (ctrl_ifname == NULL) 4473252726Srpaulo ctrl_ifname = wpa_cli_get_default_ifname(); 4474252726Srpaulo 4475337817Scy if (wpa_cli_open_connection(ctrl_ifname, 1)) { 4476252726Srpaulo if (!warning_displayed) { 4477252726Srpaulo printf("Could not connect to wpa_supplicant: " 4478281806Srpaulo "%s - re-trying\n", 4479281806Srpaulo ctrl_ifname ? ctrl_ifname : "(nil)"); 4480252726Srpaulo warning_displayed = 1; 4481189251Ssam } 4482252726Srpaulo eloop_register_timeout(1, 0, try_connection, NULL, NULL); 4483252726Srpaulo return; 4484189251Ssam } 4485252726Srpaulo 4486281806Srpaulo update_bssid_list(ctrl_conn); 4487346981Scy update_creds(ctrl_conn); 4488289549Srpaulo update_networks(ctrl_conn); 4489346981Scy update_stations(ctrl_conn); 4490281806Srpaulo 4491252726Srpaulo if (warning_displayed) 4492252726Srpaulo printf("Connection established.\n"); 4493252726Srpaulo 4494281806Srpaulodone: 4495252726Srpaulo start_edit(); 4496189251Ssam} 4497189251Ssam 4498189251Ssam 4499252726Srpaulostatic void wpa_cli_interactive(void) 4500252726Srpaulo{ 4501252726Srpaulo printf("\nInteractive mode\n\n"); 4502252726Srpaulo 4503252726Srpaulo eloop_register_timeout(0, 0, try_connection, NULL, NULL); 4504252726Srpaulo eloop_run(); 4505252726Srpaulo eloop_cancel_timeout(try_connection, NULL, NULL); 4506252726Srpaulo 4507252726Srpaulo cli_txt_list_flush(&p2p_peers); 4508252726Srpaulo cli_txt_list_flush(&p2p_groups); 4509252726Srpaulo cli_txt_list_flush(&bsses); 4510281806Srpaulo cli_txt_list_flush(&ifnames); 4511346981Scy cli_txt_list_flush(&creds); 4512289549Srpaulo cli_txt_list_flush(&networks); 4513252726Srpaulo if (edit_started) 4514252726Srpaulo edit_deinit(hfile, wpa_cli_edit_filter_history_cb); 4515252726Srpaulo os_free(hfile); 4516252726Srpaulo eloop_cancel_timeout(wpa_cli_ping, NULL, NULL); 4517252726Srpaulo wpa_cli_close_connection(); 4518252726Srpaulo} 4519252726Srpaulo 4520252726Srpaulo 4521289549Srpaulostatic void wpa_cli_action_ping(void *eloop_ctx, void *timeout_ctx) 4522289549Srpaulo{ 4523289549Srpaulo struct wpa_ctrl *ctrl = eloop_ctx; 4524289549Srpaulo char buf[256]; 4525289549Srpaulo size_t len; 4526289549Srpaulo 4527289549Srpaulo /* verify that connection is still working */ 4528289549Srpaulo len = sizeof(buf) - 1; 4529289549Srpaulo if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len, 4530289549Srpaulo wpa_cli_action_cb) < 0 || 4531289549Srpaulo len < 4 || os_memcmp(buf, "PONG", 4) != 0) { 4532289549Srpaulo printf("wpa_supplicant did not reply to PING command - exiting\n"); 4533289549Srpaulo eloop_terminate(); 4534289549Srpaulo return; 4535289549Srpaulo } 4536289549Srpaulo eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping, 4537289549Srpaulo ctrl, NULL); 4538289549Srpaulo} 4539289549Srpaulo 4540289549Srpaulo 4541289549Srpaulostatic void wpa_cli_action_receive(int sock, void *eloop_ctx, void *sock_ctx) 4542289549Srpaulo{ 4543289549Srpaulo struct wpa_ctrl *ctrl = eloop_ctx; 4544289549Srpaulo 4545289549Srpaulo wpa_cli_recv_pending(ctrl, 1); 4546289549Srpaulo} 4547289549Srpaulo 4548289549Srpaulo 4549189251Ssamstatic void wpa_cli_action(struct wpa_ctrl *ctrl) 4550189251Ssam{ 4551189251Ssam#ifdef CONFIG_ANSI_C_EXTRA 4552189251Ssam /* TODO: ANSI C version(?) */ 4553189251Ssam printf("Action processing not supported in ANSI C build.\n"); 4554189251Ssam#else /* CONFIG_ANSI_C_EXTRA */ 4555289549Srpaulo int fd; 4556189251Ssam 4557189251Ssam fd = wpa_ctrl_get_fd(ctrl); 4558289549Srpaulo eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping, 4559289549Srpaulo ctrl, NULL); 4560289549Srpaulo eloop_register_read_sock(fd, wpa_cli_action_receive, ctrl, NULL); 4561289549Srpaulo eloop_run(); 4562289549Srpaulo eloop_cancel_timeout(wpa_cli_action_ping, ctrl, NULL); 4563289549Srpaulo eloop_unregister_read_sock(fd); 4564189251Ssam#endif /* CONFIG_ANSI_C_EXTRA */ 4565189251Ssam} 4566189251Ssam 4567189251Ssam 4568189251Ssamstatic void wpa_cli_cleanup(void) 4569189251Ssam{ 4570189251Ssam wpa_cli_close_connection(); 4571189251Ssam if (pid_file) 4572189251Ssam os_daemonize_terminate(pid_file); 4573189251Ssam 4574189251Ssam os_program_deinit(); 4575189251Ssam} 4576189251Ssam 4577189251Ssam 4578252726Srpaulostatic void wpa_cli_terminate(int sig, void *ctx) 4579214734Srpaulo{ 4580252726Srpaulo eloop_terminate(); 4581214734Srpaulo} 4582214734Srpaulo 4583214734Srpaulo 4584189251Ssamstatic char * wpa_cli_get_default_ifname(void) 4585189251Ssam{ 4586189251Ssam char *ifname = NULL; 4587189251Ssam 4588289549Srpaulo#ifdef ANDROID 4589289549Srpaulo char ifprop[PROPERTY_VALUE_MAX]; 4590289549Srpaulo if (property_get("wifi.interface", ifprop, NULL) != 0) { 4591289549Srpaulo ifname = os_strdup(ifprop); 4592289549Srpaulo printf("Using interface '%s'\n", ifname ? ifname : "N/A"); 4593289549Srpaulo } 4594289549Srpaulo#else /* ANDROID */ 4595189251Ssam#ifdef CONFIG_CTRL_IFACE_UNIX 4596189251Ssam struct dirent *dent; 4597189251Ssam DIR *dir = opendir(ctrl_iface_dir); 4598252726Srpaulo if (!dir) { 4599189251Ssam return NULL; 4600252726Srpaulo } 4601189251Ssam while ((dent = readdir(dir))) { 4602189251Ssam#ifdef _DIRENT_HAVE_D_TYPE 4603189251Ssam /* 4604189251Ssam * Skip the file if it is not a socket. Also accept 4605189251Ssam * DT_UNKNOWN (0) in case the C library or underlying 4606189251Ssam * file system does not support d_type. 4607189251Ssam */ 4608189251Ssam if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN) 4609189251Ssam continue; 4610189251Ssam#endif /* _DIRENT_HAVE_D_TYPE */ 4611189251Ssam if (os_strcmp(dent->d_name, ".") == 0 || 4612189251Ssam os_strcmp(dent->d_name, "..") == 0) 4613189251Ssam continue; 4614189251Ssam printf("Selected interface '%s'\n", dent->d_name); 4615189251Ssam ifname = os_strdup(dent->d_name); 4616189251Ssam break; 4617189251Ssam } 4618189251Ssam closedir(dir); 4619189251Ssam#endif /* CONFIG_CTRL_IFACE_UNIX */ 4620189251Ssam 4621189251Ssam#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 4622281806Srpaulo char buf[4096], *pos; 4623189251Ssam size_t len; 4624189251Ssam struct wpa_ctrl *ctrl; 4625189251Ssam int ret; 4626189251Ssam 4627189251Ssam ctrl = wpa_ctrl_open(NULL); 4628189251Ssam if (ctrl == NULL) 4629189251Ssam return NULL; 4630189251Ssam 4631189251Ssam len = sizeof(buf) - 1; 4632189251Ssam ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL); 4633189251Ssam if (ret >= 0) { 4634189251Ssam buf[len] = '\0'; 4635189251Ssam pos = os_strchr(buf, '\n'); 4636189251Ssam if (pos) 4637189251Ssam *pos = '\0'; 4638189251Ssam ifname = os_strdup(buf); 4639189251Ssam } 4640189251Ssam wpa_ctrl_close(ctrl); 4641189251Ssam#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 4642289549Srpaulo#endif /* ANDROID */ 4643189251Ssam 4644189251Ssam return ifname; 4645189251Ssam} 4646189251Ssam 4647189251Ssam 4648189251Ssamint main(int argc, char *argv[]) 4649189251Ssam{ 4650189251Ssam int c; 4651189251Ssam int daemonize = 0; 4652189251Ssam int ret = 0; 4653189251Ssam 4654189251Ssam if (os_program_init()) 4655189251Ssam return -1; 4656189251Ssam 4657189251Ssam for (;;) { 4658289549Srpaulo c = getopt(argc, argv, "a:Bg:G:hi:p:P:s:v"); 4659189251Ssam if (c < 0) 4660189251Ssam break; 4661189251Ssam switch (c) { 4662189251Ssam case 'a': 4663189251Ssam action_file = optarg; 4664189251Ssam break; 4665189251Ssam case 'B': 4666189251Ssam daemonize = 1; 4667189251Ssam break; 4668189251Ssam case 'g': 4669189251Ssam global = optarg; 4670189251Ssam break; 4671189251Ssam case 'G': 4672189251Ssam ping_interval = atoi(optarg); 4673189251Ssam break; 4674189251Ssam case 'h': 4675189251Ssam usage(); 4676189251Ssam return 0; 4677189251Ssam case 'v': 4678189251Ssam printf("%s\n", wpa_cli_version); 4679189251Ssam return 0; 4680189251Ssam case 'i': 4681189251Ssam os_free(ctrl_ifname); 4682189251Ssam ctrl_ifname = os_strdup(optarg); 4683189251Ssam break; 4684189251Ssam case 'p': 4685189251Ssam ctrl_iface_dir = optarg; 4686189251Ssam break; 4687189251Ssam case 'P': 4688189251Ssam pid_file = optarg; 4689189251Ssam break; 4690289549Srpaulo case 's': 4691289549Srpaulo client_socket_dir = optarg; 4692289549Srpaulo break; 4693189251Ssam default: 4694189251Ssam usage(); 4695189251Ssam return -1; 4696189251Ssam } 4697189251Ssam } 4698189251Ssam 4699189251Ssam interactive = (argc == optind) && (action_file == NULL); 4700189251Ssam 4701189251Ssam if (interactive) 4702337817Scy printf("%s\n\n%s\n\n", wpa_cli_version, cli_license); 4703189251Ssam 4704252726Srpaulo if (eloop_init()) 4705252726Srpaulo return -1; 4706252726Srpaulo 4707346981Scy if (global && wpa_cli_open_global_ctrl() < 0) 4708346981Scy return -1; 4709281806Srpaulo 4710252726Srpaulo eloop_register_signal_terminate(wpa_cli_terminate, NULL); 4711189251Ssam 4712214734Srpaulo if (ctrl_ifname == NULL) 4713214734Srpaulo ctrl_ifname = wpa_cli_get_default_ifname(); 4714214734Srpaulo 4715214734Srpaulo if (interactive) { 4716252726Srpaulo wpa_cli_interactive(); 4717214734Srpaulo } else { 4718214734Srpaulo if (!global && 4719214734Srpaulo wpa_cli_open_connection(ctrl_ifname, 0) < 0) { 4720252726Srpaulo fprintf(stderr, "Failed to connect to non-global " 4721252726Srpaulo "ctrl_ifname: %s error: %s\n", 4722281806Srpaulo ctrl_ifname ? ctrl_ifname : "(nil)", 4723281806Srpaulo strerror(errno)); 4724214734Srpaulo return -1; 4725214734Srpaulo } 4726214734Srpaulo 4727214734Srpaulo if (action_file) { 4728214734Srpaulo if (wpa_ctrl_attach(ctrl_conn) == 0) { 4729214734Srpaulo wpa_cli_attached = 1; 4730214734Srpaulo } else { 4731214734Srpaulo printf("Warning: Failed to attach to " 4732214734Srpaulo "wpa_supplicant.\n"); 4733189251Ssam return -1; 4734214734Srpaulo } 4735189251Ssam } 4736189251Ssam 4737337817Scy if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue()) 4738252726Srpaulo return -1; 4739189251Ssam 4740252726Srpaulo if (action_file) 4741252726Srpaulo wpa_cli_action(ctrl_conn); 4742252726Srpaulo else 4743252726Srpaulo ret = wpa_request(ctrl_conn, argc - optind, 4744252726Srpaulo &argv[optind]); 4745252726Srpaulo } 4746189251Ssam 4747189251Ssam os_free(ctrl_ifname); 4748252726Srpaulo eloop_destroy(); 4749189251Ssam wpa_cli_cleanup(); 4750189251Ssam 4751189251Ssam return ret; 4752189251Ssam} 4753189251Ssam 4754189251Ssam#else /* CONFIG_CTRL_IFACE */ 4755189251Ssamint main(int argc, char *argv[]) 4756189251Ssam{ 4757189251Ssam printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n"); 4758189251Ssam return -1; 4759189251Ssam} 4760189251Ssam#endif /* CONFIG_CTRL_IFACE */ 4761