wpa_cli.c revision 346981
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 2067281806Srpaulo#endif /* CONFIG_MESH */ 2068281806Srpaulo 2069281806Srpaulo 2070252726Srpaulo#ifdef CONFIG_P2P 2071252726Srpaulo 2072252726Srpaulostatic int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2073252726Srpaulo{ 2074252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv); 2075252726Srpaulo} 2076252726Srpaulo 2077252726Srpaulo 2078252726Srpaulostatic char ** wpa_cli_complete_p2p_find(const char *str, int pos) 2079252726Srpaulo{ 2080252726Srpaulo char **res = NULL; 2081252726Srpaulo int arg = get_cmd_arg_num(str, pos); 2082252726Srpaulo 2083252726Srpaulo res = os_calloc(6, sizeof(char *)); 2084252726Srpaulo if (res == NULL) 2085252726Srpaulo return NULL; 2086252726Srpaulo res[0] = os_strdup("type=social"); 2087252726Srpaulo if (res[0] == NULL) { 2088252726Srpaulo os_free(res); 2089252726Srpaulo return NULL; 2090252726Srpaulo } 2091252726Srpaulo res[1] = os_strdup("type=progressive"); 2092252726Srpaulo if (res[1] == NULL) 2093252726Srpaulo return res; 2094252726Srpaulo res[2] = os_strdup("delay="); 2095252726Srpaulo if (res[2] == NULL) 2096252726Srpaulo return res; 2097252726Srpaulo res[3] = os_strdup("dev_id="); 2098252726Srpaulo if (res[3] == NULL) 2099252726Srpaulo return res; 2100252726Srpaulo if (arg == 1) 2101252726Srpaulo res[4] = os_strdup("[timeout]"); 2102252726Srpaulo 2103252726Srpaulo return res; 2104252726Srpaulo} 2105252726Srpaulo 2106252726Srpaulo 2107252726Srpaulostatic int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc, 2108252726Srpaulo char *argv[]) 2109252726Srpaulo{ 2110252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_STOP_FIND"); 2111252726Srpaulo} 2112252726Srpaulo 2113252726Srpaulo 2114281806Srpaulostatic int wpa_cli_cmd_p2p_asp_provision(struct wpa_ctrl *ctrl, int argc, 2115281806Srpaulo char *argv[]) 2116281806Srpaulo{ 2117281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION", 3, argc, argv); 2118281806Srpaulo} 2119281806Srpaulo 2120281806Srpaulo 2121281806Srpaulostatic int wpa_cli_cmd_p2p_asp_provision_resp(struct wpa_ctrl *ctrl, int argc, 2122281806Srpaulo char *argv[]) 2123281806Srpaulo{ 2124281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION_RESP", 2, argc, argv); 2125281806Srpaulo} 2126281806Srpaulo 2127281806Srpaulo 2128252726Srpaulostatic int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc, 2129252726Srpaulo char *argv[]) 2130252726Srpaulo{ 2131252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv); 2132252726Srpaulo} 2133252726Srpaulo 2134252726Srpaulo 2135252726Srpaulostatic char ** wpa_cli_complete_p2p_connect(const char *str, int pos) 2136252726Srpaulo{ 2137252726Srpaulo int arg = get_cmd_arg_num(str, pos); 2138252726Srpaulo char **res = NULL; 2139252726Srpaulo 2140252726Srpaulo switch (arg) { 2141252726Srpaulo case 1: 2142252726Srpaulo res = cli_txt_list_array(&p2p_peers); 2143252726Srpaulo break; 2144252726Srpaulo } 2145252726Srpaulo 2146252726Srpaulo return res; 2147252726Srpaulo} 2148252726Srpaulo 2149252726Srpaulo 2150252726Srpaulostatic int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc, 2151252726Srpaulo char *argv[]) 2152252726Srpaulo{ 2153252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv); 2154252726Srpaulo} 2155252726Srpaulo 2156252726Srpaulo 2157252726Srpaulostatic int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc, 2158252726Srpaulo char *argv[]) 2159252726Srpaulo{ 2160252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv); 2161252726Srpaulo} 2162252726Srpaulo 2163252726Srpaulo 2164252726Srpaulostatic char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos) 2165252726Srpaulo{ 2166252726Srpaulo int arg = get_cmd_arg_num(str, pos); 2167252726Srpaulo char **res = NULL; 2168252726Srpaulo 2169252726Srpaulo switch (arg) { 2170252726Srpaulo case 1: 2171252726Srpaulo res = cli_txt_list_array(&p2p_groups); 2172252726Srpaulo break; 2173252726Srpaulo } 2174252726Srpaulo 2175252726Srpaulo return res; 2176252726Srpaulo} 2177252726Srpaulo 2178252726Srpaulo 2179252726Srpaulostatic int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc, 2180252726Srpaulo char *argv[]) 2181252726Srpaulo{ 2182252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv); 2183252726Srpaulo} 2184252726Srpaulo 2185252726Srpaulo 2186337817Scystatic int wpa_cli_cmd_p2p_group_member(struct wpa_ctrl *ctrl, int argc, 2187337817Scy char *argv[]) 2188337817Scy{ 2189337817Scy return wpa_cli_cmd(ctrl, "P2P_GROUP_MEMBER", 1, argc, argv); 2190337817Scy} 2191337817Scy 2192337817Scy 2193252726Srpaulostatic int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc, 2194252726Srpaulo char *argv[]) 2195252726Srpaulo{ 2196252726Srpaulo if (argc != 2 && argc != 3) { 2197252726Srpaulo printf("Invalid P2P_PROV_DISC command: needs at least " 2198252726Srpaulo "two arguments, address and config method\n" 2199252726Srpaulo "(display, keypad, or pbc) and an optional join\n"); 2200252726Srpaulo return -1; 2201252726Srpaulo } 2202252726Srpaulo 2203252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv); 2204252726Srpaulo} 2205252726Srpaulo 2206252726Srpaulo 2207252726Srpaulostatic int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc, 2208252726Srpaulo char *argv[]) 2209252726Srpaulo{ 2210252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE"); 2211252726Srpaulo} 2212252726Srpaulo 2213252726Srpaulo 2214252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc, 2215252726Srpaulo char *argv[]) 2216252726Srpaulo{ 2217252726Srpaulo char cmd[4096]; 2218252726Srpaulo 2219281806Srpaulo if (argc < 2) { 2220252726Srpaulo printf("Invalid P2P_SERV_DISC_REQ command: needs two " 2221281806Srpaulo "or more arguments (address and TLVs)\n"); 2222252726Srpaulo return -1; 2223252726Srpaulo } 2224252726Srpaulo 2225252726Srpaulo if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0) 2226252726Srpaulo return -1; 2227252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2228252726Srpaulo} 2229252726Srpaulo 2230252726Srpaulo 2231252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl, 2232252726Srpaulo int argc, char *argv[]) 2233252726Srpaulo{ 2234252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv); 2235252726Srpaulo} 2236252726Srpaulo 2237252726Srpaulo 2238252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc, 2239252726Srpaulo char *argv[]) 2240252726Srpaulo{ 2241252726Srpaulo char cmd[4096]; 2242214734Srpaulo int res; 2243214734Srpaulo 2244252726Srpaulo if (argc != 4) { 2245252726Srpaulo printf("Invalid P2P_SERV_DISC_RESP command: needs four " 2246252726Srpaulo "arguments (freq, address, dialog token, and TLVs)\n"); 2247252726Srpaulo return -1; 2248252726Srpaulo } 2249252726Srpaulo 2250252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s", 2251252726Srpaulo argv[0], argv[1], argv[2], argv[3]); 2252281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 2253252726Srpaulo return -1; 2254252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 2255252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2256252726Srpaulo} 2257252726Srpaulo 2258252726Srpaulo 2259252726Srpaulostatic int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc, 2260252726Srpaulo char *argv[]) 2261252726Srpaulo{ 2262252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE"); 2263252726Srpaulo} 2264252726Srpaulo 2265252726Srpaulo 2266252726Srpaulostatic int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl, 2267252726Srpaulo int argc, char *argv[]) 2268252726Srpaulo{ 2269252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv); 2270252726Srpaulo} 2271252726Srpaulo 2272252726Srpaulo 2273252726Srpaulostatic int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc, 2274252726Srpaulo char *argv[]) 2275252726Srpaulo{ 2276252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH"); 2277252726Srpaulo} 2278252726Srpaulo 2279252726Srpaulo 2280252726Srpaulostatic int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc, 2281252726Srpaulo char *argv[]) 2282252726Srpaulo{ 2283281806Srpaulo if (argc < 3) { 2284281806Srpaulo printf("Invalid P2P_SERVICE_ADD command: needs 3-6 arguments\n"); 2285281806Srpaulo return -1; 2286281806Srpaulo } 2287252726Srpaulo 2288281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERVICE_ADD", 3, argc, argv); 2289281806Srpaulo} 2290281806Srpaulo 2291281806Srpaulo 2292281806Srpaulostatic int wpa_cli_cmd_p2p_service_rep(struct wpa_ctrl *ctrl, int argc, 2293281806Srpaulo char *argv[]) 2294281806Srpaulo{ 2295281806Srpaulo if (argc < 5 || argc > 6) { 2296281806Srpaulo printf("Invalid P2P_SERVICE_REP command: needs 5-6 " 2297252726Srpaulo "arguments\n"); 2298252726Srpaulo return -1; 2299252726Srpaulo } 2300252726Srpaulo 2301281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_SERVICE_REP", 5, argc, argv); 2302252726Srpaulo} 2303252726Srpaulo 2304252726Srpaulo 2305252726Srpaulostatic int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc, 2306252726Srpaulo char *argv[]) 2307252726Srpaulo{ 2308252726Srpaulo char cmd[4096]; 2309252726Srpaulo int res; 2310252726Srpaulo 2311252726Srpaulo if (argc != 2 && argc != 3) { 2312252726Srpaulo printf("Invalid P2P_SERVICE_DEL command: needs two or three " 2313252726Srpaulo "arguments\n"); 2314252726Srpaulo return -1; 2315252726Srpaulo } 2316252726Srpaulo 2317252726Srpaulo if (argc == 3) 2318252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), 2319252726Srpaulo "P2P_SERVICE_DEL %s %s %s", 2320252726Srpaulo argv[0], argv[1], argv[2]); 2321252726Srpaulo else 2322252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), 2323252726Srpaulo "P2P_SERVICE_DEL %s %s", 2324252726Srpaulo argv[0], argv[1]); 2325281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 2326252726Srpaulo return -1; 2327252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 2328252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2329252726Srpaulo} 2330252726Srpaulo 2331252726Srpaulo 2332252726Srpaulostatic int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl, 2333252726Srpaulo int argc, char *argv[]) 2334252726Srpaulo{ 2335252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv); 2336252726Srpaulo} 2337252726Srpaulo 2338252726Srpaulo 2339252726Srpaulostatic int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl, 2340252726Srpaulo int argc, char *argv[]) 2341252726Srpaulo{ 2342252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv); 2343252726Srpaulo} 2344252726Srpaulo 2345252726Srpaulo 2346252726Srpaulostatic int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2347252726Srpaulo{ 2348252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv); 2349252726Srpaulo} 2350252726Srpaulo 2351252726Srpaulo 2352252726Srpaulostatic char ** wpa_cli_complete_p2p_peer(const char *str, int pos) 2353252726Srpaulo{ 2354252726Srpaulo int arg = get_cmd_arg_num(str, pos); 2355252726Srpaulo char **res = NULL; 2356252726Srpaulo 2357252726Srpaulo switch (arg) { 2358252726Srpaulo case 1: 2359252726Srpaulo res = cli_txt_list_array(&p2p_peers); 2360252726Srpaulo break; 2361252726Srpaulo } 2362252726Srpaulo 2363252726Srpaulo return res; 2364252726Srpaulo} 2365252726Srpaulo 2366252726Srpaulo 2367346981Scystatic int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, const char *cmd, 2368252726Srpaulo char *addr, size_t addr_len, 2369252726Srpaulo int discovered) 2370252726Srpaulo{ 2371252726Srpaulo char buf[4096], *pos; 2372252726Srpaulo size_t len; 2373252726Srpaulo int ret; 2374252726Srpaulo 2375252726Srpaulo if (ctrl_conn == NULL) 2376252726Srpaulo return -1; 2377252726Srpaulo len = sizeof(buf) - 1; 2378252726Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 2379252726Srpaulo wpa_cli_msg_cb); 2380252726Srpaulo if (ret == -2) { 2381252726Srpaulo printf("'%s' command timed out.\n", cmd); 2382252726Srpaulo return -2; 2383252726Srpaulo } else if (ret < 0) { 2384252726Srpaulo printf("'%s' command failed.\n", cmd); 2385252726Srpaulo return -1; 2386252726Srpaulo } 2387252726Srpaulo 2388252726Srpaulo buf[len] = '\0'; 2389252726Srpaulo if (os_memcmp(buf, "FAIL", 4) == 0) 2390252726Srpaulo return -1; 2391252726Srpaulo 2392252726Srpaulo pos = buf; 2393252726Srpaulo while (*pos != '\0' && *pos != '\n') 2394252726Srpaulo pos++; 2395252726Srpaulo *pos++ = '\0'; 2396252726Srpaulo os_strlcpy(addr, buf, addr_len); 2397252726Srpaulo if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL) 2398252726Srpaulo printf("%s\n", addr); 2399252726Srpaulo return 0; 2400252726Srpaulo} 2401252726Srpaulo 2402252726Srpaulo 2403252726Srpaulostatic int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2404252726Srpaulo{ 2405252726Srpaulo char addr[32], cmd[64]; 2406252726Srpaulo int discovered; 2407252726Srpaulo 2408252726Srpaulo discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0; 2409252726Srpaulo 2410252726Srpaulo if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST", 2411252726Srpaulo addr, sizeof(addr), discovered)) 2412252726Srpaulo return -1; 2413252726Srpaulo do { 2414252726Srpaulo os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr); 2415252726Srpaulo } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr), 2416252726Srpaulo discovered) == 0); 2417252726Srpaulo 2418252726Srpaulo return 0; 2419252726Srpaulo} 2420252726Srpaulo 2421252726Srpaulo 2422252726Srpaulostatic int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2423252726Srpaulo{ 2424252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv); 2425252726Srpaulo} 2426252726Srpaulo 2427252726Srpaulo 2428281806Srpaulostatic char ** wpa_cli_complete_p2p_set(const char *str, int pos) 2429281806Srpaulo{ 2430281806Srpaulo int arg = get_cmd_arg_num(str, pos); 2431281806Srpaulo const char *fields[] = { 2432281806Srpaulo "discoverability", 2433281806Srpaulo "managed", 2434281806Srpaulo "listen_channel", 2435281806Srpaulo "ssid_postfix", 2436281806Srpaulo "noa", 2437281806Srpaulo "ps", 2438281806Srpaulo "oppps", 2439281806Srpaulo "ctwindow", 2440281806Srpaulo "disabled", 2441281806Srpaulo "conc_pref", 2442281806Srpaulo "force_long_sd", 2443281806Srpaulo "peer_filter", 2444281806Srpaulo "cross_connect", 2445281806Srpaulo "go_apsd", 2446281806Srpaulo "client_apsd", 2447281806Srpaulo "disallow_freq", 2448281806Srpaulo "disc_int", 2449281806Srpaulo "per_sta_psk", 2450281806Srpaulo }; 2451281806Srpaulo int i, num_fields = ARRAY_SIZE(fields); 2452281806Srpaulo 2453281806Srpaulo if (arg == 1) { 2454281806Srpaulo char **res = os_calloc(num_fields + 1, sizeof(char *)); 2455281806Srpaulo if (res == NULL) 2456281806Srpaulo return NULL; 2457281806Srpaulo for (i = 0; i < num_fields; i++) { 2458281806Srpaulo res[i] = os_strdup(fields[i]); 2459281806Srpaulo if (res[i] == NULL) 2460281806Srpaulo return res; 2461281806Srpaulo } 2462281806Srpaulo return res; 2463281806Srpaulo } 2464281806Srpaulo 2465281806Srpaulo if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0) 2466281806Srpaulo return cli_txt_list_array(&p2p_peers); 2467281806Srpaulo 2468281806Srpaulo return NULL; 2469281806Srpaulo} 2470281806Srpaulo 2471281806Srpaulo 2472252726Srpaulostatic int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2473252726Srpaulo{ 2474252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_FLUSH"); 2475252726Srpaulo} 2476252726Srpaulo 2477252726Srpaulo 2478252726Srpaulostatic int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc, 2479252726Srpaulo char *argv[]) 2480252726Srpaulo{ 2481252726Srpaulo return wpa_ctrl_command(ctrl, "P2P_CANCEL"); 2482252726Srpaulo} 2483252726Srpaulo 2484252726Srpaulo 2485252726Srpaulostatic int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc, 2486252726Srpaulo char *argv[]) 2487252726Srpaulo{ 2488252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv); 2489252726Srpaulo} 2490252726Srpaulo 2491252726Srpaulo 2492252726Srpaulostatic int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc, 2493252726Srpaulo char *argv[]) 2494252726Srpaulo{ 2495252726Srpaulo if (argc != 0 && argc != 2 && argc != 4) { 2496252726Srpaulo printf("Invalid P2P_PRESENCE_REQ command: needs two arguments " 2497252726Srpaulo "(preferred duration, interval; in microsecods).\n" 2498252726Srpaulo "Optional second pair can be used to provide " 2499252726Srpaulo "acceptable values.\n"); 2500252726Srpaulo return -1; 2501252726Srpaulo } 2502252726Srpaulo 2503252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv); 2504252726Srpaulo} 2505252726Srpaulo 2506252726Srpaulo 2507252726Srpaulostatic int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc, 2508252726Srpaulo char *argv[]) 2509252726Srpaulo{ 2510252726Srpaulo if (argc != 0 && argc != 2) { 2511252726Srpaulo printf("Invalid P2P_EXT_LISTEN command: needs two arguments " 2512252726Srpaulo "(availability period, availability interval; in " 2513252726Srpaulo "millisecods).\n" 2514252726Srpaulo "Extended Listen Timing can be cancelled with this " 2515252726Srpaulo "command when used without parameters.\n"); 2516252726Srpaulo return -1; 2517252726Srpaulo } 2518252726Srpaulo 2519252726Srpaulo return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv); 2520252726Srpaulo} 2521252726Srpaulo 2522281806Srpaulo 2523281806Srpaulostatic int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc, 2524281806Srpaulo char *argv[]) 2525281806Srpaulo{ 2526281806Srpaulo return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv); 2527281806Srpaulo} 2528281806Srpaulo 2529346981Scy#endif /* CONFIG_P2P */ 2530337817Scy 2531346981Scy 2532337817Scystatic int wpa_cli_cmd_vendor_elem_add(struct wpa_ctrl *ctrl, int argc, 2533337817Scy char *argv[]) 2534337817Scy{ 2535337817Scy return wpa_cli_cmd(ctrl, "VENDOR_ELEM_ADD", 2, argc, argv); 2536337817Scy} 2537337817Scy 2538337817Scy 2539337817Scystatic int wpa_cli_cmd_vendor_elem_get(struct wpa_ctrl *ctrl, int argc, 2540337817Scy char *argv[]) 2541337817Scy{ 2542337817Scy return wpa_cli_cmd(ctrl, "VENDOR_ELEM_GET", 1, argc, argv); 2543337817Scy} 2544337817Scy 2545337817Scy 2546337817Scystatic int wpa_cli_cmd_vendor_elem_remove(struct wpa_ctrl *ctrl, int argc, 2547337817Scy char *argv[]) 2548337817Scy{ 2549337817Scy return wpa_cli_cmd(ctrl, "VENDOR_ELEM_REMOVE", 2, argc, argv); 2550337817Scy} 2551337817Scy 2552252726Srpaulo 2553252726Srpaulo#ifdef CONFIG_WIFI_DISPLAY 2554252726Srpaulo 2555252726Srpaulostatic int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc, 2556252726Srpaulo char *argv[]) 2557252726Srpaulo{ 2558252726Srpaulo char cmd[100]; 2559252726Srpaulo int res; 2560252726Srpaulo 2561252726Srpaulo if (argc != 1 && argc != 2) { 2562252726Srpaulo printf("Invalid WFD_SUBELEM_SET command: needs one or two " 2563252726Srpaulo "arguments (subelem, hexdump)\n"); 2564252726Srpaulo return -1; 2565252726Srpaulo } 2566252726Srpaulo 2567252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s", 2568252726Srpaulo argv[0], argc > 1 ? argv[1] : ""); 2569281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 2570252726Srpaulo return -1; 2571252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 2572252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2573252726Srpaulo} 2574252726Srpaulo 2575252726Srpaulo 2576252726Srpaulostatic int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc, 2577252726Srpaulo char *argv[]) 2578252726Srpaulo{ 2579252726Srpaulo char cmd[100]; 2580252726Srpaulo int res; 2581252726Srpaulo 2582214734Srpaulo if (argc != 1) { 2583252726Srpaulo printf("Invalid WFD_SUBELEM_GET command: needs one " 2584252726Srpaulo "argument (subelem)\n"); 2585214734Srpaulo return -1; 2586214734Srpaulo } 2587214734Srpaulo 2588252726Srpaulo res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s", 2589252726Srpaulo argv[0]); 2590281806Srpaulo if (os_snprintf_error(sizeof(cmd), res)) 2591214734Srpaulo return -1; 2592252726Srpaulo cmd[sizeof(cmd) - 1] = '\0'; 2593252726Srpaulo return wpa_ctrl_command(ctrl, cmd); 2594252726Srpaulo} 2595252726Srpaulo#endif /* CONFIG_WIFI_DISPLAY */ 2596252726Srpaulo 2597252726Srpaulo 2598252726Srpaulo#ifdef CONFIG_INTERWORKING 2599252726Srpaulostatic int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc, 2600252726Srpaulo char *argv[]) 2601252726Srpaulo{ 2602252726Srpaulo return wpa_ctrl_command(ctrl, "FETCH_ANQP"); 2603252726Srpaulo} 2604252726Srpaulo 2605252726Srpaulo 2606252726Srpaulostatic int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc, 2607252726Srpaulo char *argv[]) 2608252726Srpaulo{ 2609252726Srpaulo return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP"); 2610252726Srpaulo} 2611252726Srpaulo 2612252726Srpaulo 2613252726Srpaulostatic int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc, 2614252726Srpaulo char *argv[]) 2615252726Srpaulo{ 2616252726Srpaulo return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv); 2617252726Srpaulo} 2618252726Srpaulo 2619252726Srpaulo 2620252726Srpaulostatic int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc, 2621252726Srpaulo char *argv[]) 2622252726Srpaulo{ 2623252726Srpaulo return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv); 2624252726Srpaulo} 2625252726Srpaulo 2626252726Srpaulo 2627281806Srpaulostatic int wpa_cli_cmd_interworking_add_network(struct wpa_ctrl *ctrl, int argc, 2628281806Srpaulo char *argv[]) 2629281806Srpaulo{ 2630281806Srpaulo return wpa_cli_cmd(ctrl, "INTERWORKING_ADD_NETWORK", 1, argc, argv); 2631281806Srpaulo} 2632281806Srpaulo 2633281806Srpaulo 2634252726Srpaulostatic int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2635252726Srpaulo{ 2636252726Srpaulo return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv); 2637252726Srpaulo} 2638252726Srpaulo 2639252726Srpaulo 2640252726Srpaulostatic int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc, 2641252726Srpaulo char *argv[]) 2642252726Srpaulo{ 2643252726Srpaulo return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv); 2644252726Srpaulo} 2645252726Srpaulo 2646252726Srpaulo 2647252726Srpaulostatic int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc, 2648252726Srpaulo char *argv[]) 2649252726Srpaulo{ 2650252726Srpaulo return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv); 2651252726Srpaulo} 2652252726Srpaulo#endif /* CONFIG_INTERWORKING */ 2653252726Srpaulo 2654252726Srpaulo 2655252726Srpaulo#ifdef CONFIG_HS20 2656252726Srpaulo 2657252726Srpaulostatic int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc, 2658252726Srpaulo char *argv[]) 2659252726Srpaulo{ 2660252726Srpaulo return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv); 2661252726Srpaulo} 2662252726Srpaulo 2663252726Srpaulo 2664252726Srpaulostatic int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc, 2665252726Srpaulo char *argv[]) 2666252726Srpaulo{ 2667252726Srpaulo char cmd[512]; 2668252726Srpaulo 2669252726Srpaulo if (argc == 0) { 2670252726Srpaulo printf("Command needs one or two arguments (dst mac addr and " 2671252726Srpaulo "optional home realm)\n"); 2672252726Srpaulo return -1; 2673214734Srpaulo } 2674252726Srpaulo 2675252726Srpaulo if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST", 2676252726Srpaulo argc, argv) < 0) 2677252726Srpaulo return -1; 2678252726Srpaulo 2679214734Srpaulo return wpa_ctrl_command(ctrl, cmd); 2680214734Srpaulo} 2681214734Srpaulo 2682281806Srpaulo 2683281806Srpaulostatic int wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl *ctrl, int argc, 2684281806Srpaulo char *argv[]) 2685281806Srpaulo{ 2686281806Srpaulo char cmd[512]; 2687281806Srpaulo 2688281806Srpaulo if (argc < 2) { 2689281806Srpaulo printf("Command needs two arguments (dst mac addr and " 2690281806Srpaulo "icon name)\n"); 2691281806Srpaulo return -1; 2692281806Srpaulo } 2693281806Srpaulo 2694281806Srpaulo if (write_cmd(cmd, sizeof(cmd), "HS20_ICON_REQUEST", argc, argv) < 0) 2695281806Srpaulo return -1; 2696281806Srpaulo 2697281806Srpaulo return wpa_ctrl_command(ctrl, cmd); 2698281806Srpaulo} 2699281806Srpaulo 2700281806Srpaulo 2701281806Srpaulostatic int wpa_cli_cmd_fetch_osu(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2702281806Srpaulo{ 2703281806Srpaulo return wpa_ctrl_command(ctrl, "FETCH_OSU"); 2704281806Srpaulo} 2705281806Srpaulo 2706281806Srpaulo 2707281806Srpaulostatic int wpa_cli_cmd_cancel_fetch_osu(struct wpa_ctrl *ctrl, int argc, 2708281806Srpaulo char *argv[]) 2709281806Srpaulo{ 2710281806Srpaulo return wpa_ctrl_command(ctrl, "CANCEL_FETCH_OSU"); 2711281806Srpaulo} 2712281806Srpaulo 2713252726Srpaulo#endif /* CONFIG_HS20 */ 2714214734Srpaulo 2715252726Srpaulo 2716252726Srpaulostatic int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc, 2717252726Srpaulo char *argv[]) 2718252726Srpaulo{ 2719252726Srpaulo return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv); 2720252726Srpaulo} 2721252726Srpaulo 2722252726Srpaulo 2723252726Srpaulostatic int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc, 2724252726Srpaulo char *argv[]) 2725252726Srpaulo{ 2726252726Srpaulo return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv); 2727252726Srpaulo} 2728252726Srpaulo 2729252726Srpaulo 2730252726Srpaulostatic int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc, 2731252726Srpaulo char *argv[]) 2732252726Srpaulo{ 2733252726Srpaulo return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv); 2734252726Srpaulo} 2735252726Srpaulo 2736252726Srpaulo 2737252726Srpaulostatic int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc, 2738252726Srpaulo char *argv[]) 2739252726Srpaulo{ 2740252726Srpaulo return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv); 2741252726Srpaulo} 2742252726Srpaulo 2743252726Srpaulo 2744289549Srpaulostatic int wpa_cli_cmd_tdls_link_status(struct wpa_ctrl *ctrl, int argc, 2745289549Srpaulo char *argv[]) 2746289549Srpaulo{ 2747289549Srpaulo return wpa_cli_cmd(ctrl, "TDLS_LINK_STATUS", 1, argc, argv); 2748289549Srpaulo} 2749289549Srpaulo 2750289549Srpaulo 2751281806Srpaulostatic int wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl *ctrl, int argc, 2752281806Srpaulo char *argv[]) 2753281806Srpaulo{ 2754281806Srpaulo return wpa_cli_cmd(ctrl, "WMM_AC_ADDTS", 3, argc, argv); 2755281806Srpaulo} 2756281806Srpaulo 2757281806Srpaulo 2758281806Srpaulostatic int wpa_cli_cmd_wmm_ac_delts(struct wpa_ctrl *ctrl, int argc, 2759281806Srpaulo char *argv[]) 2760281806Srpaulo{ 2761281806Srpaulo return wpa_cli_cmd(ctrl, "WMM_AC_DELTS", 1, argc, argv); 2762281806Srpaulo} 2763281806Srpaulo 2764281806Srpaulo 2765281806Srpaulostatic int wpa_cli_cmd_wmm_ac_status(struct wpa_ctrl *ctrl, int argc, 2766281806Srpaulo char *argv[]) 2767281806Srpaulo{ 2768281806Srpaulo return wpa_ctrl_command(ctrl, "WMM_AC_STATUS"); 2769281806Srpaulo} 2770281806Srpaulo 2771281806Srpaulo 2772281806Srpaulostatic int wpa_cli_cmd_tdls_chan_switch(struct wpa_ctrl *ctrl, int argc, 2773281806Srpaulo char *argv[]) 2774281806Srpaulo{ 2775281806Srpaulo return wpa_cli_cmd(ctrl, "TDLS_CHAN_SWITCH", 2, argc, argv); 2776281806Srpaulo} 2777281806Srpaulo 2778281806Srpaulo 2779281806Srpaulostatic int wpa_cli_cmd_tdls_cancel_chan_switch(struct wpa_ctrl *ctrl, int argc, 2780281806Srpaulo char *argv[]) 2781281806Srpaulo{ 2782281806Srpaulo return wpa_cli_cmd(ctrl, "TDLS_CANCEL_CHAN_SWITCH", 1, argc, argv); 2783281806Srpaulo} 2784281806Srpaulo 2785281806Srpaulo 2786252726Srpaulostatic int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc, 2787252726Srpaulo char *argv[]) 2788252726Srpaulo{ 2789252726Srpaulo return wpa_ctrl_command(ctrl, "SIGNAL_POLL"); 2790252726Srpaulo} 2791252726Srpaulo 2792252726Srpaulo 2793337817Scystatic int wpa_cli_cmd_signal_monitor(struct wpa_ctrl *ctrl, int argc, 2794337817Scy char *argv[]) 2795337817Scy{ 2796337817Scy return wpa_cli_cmd(ctrl, "SIGNAL_MONITOR", 0, argc, argv); 2797337817Scy} 2798337817Scy 2799337817Scy 2800252726Srpaulostatic int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc, 2801252726Srpaulo char *argv[]) 2802252726Srpaulo{ 2803252726Srpaulo return wpa_ctrl_command(ctrl, "PKTCNT_POLL"); 2804252726Srpaulo} 2805252726Srpaulo 2806252726Srpaulo 2807252726Srpaulostatic int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc, 2808252726Srpaulo char *argv[]) 2809252726Srpaulo{ 2810252726Srpaulo return wpa_ctrl_command(ctrl, "REAUTHENTICATE"); 2811252726Srpaulo} 2812252726Srpaulo 2813252726Srpaulo 2814252726Srpaulo#ifdef CONFIG_AUTOSCAN 2815252726Srpaulo 2816252726Srpaulostatic int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2817252726Srpaulo{ 2818252726Srpaulo if (argc == 0) 2819252726Srpaulo return wpa_ctrl_command(ctrl, "AUTOSCAN "); 2820252726Srpaulo 2821252726Srpaulo return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv); 2822252726Srpaulo} 2823252726Srpaulo 2824252726Srpaulo#endif /* CONFIG_AUTOSCAN */ 2825252726Srpaulo 2826252726Srpaulo 2827252726Srpaulo#ifdef CONFIG_WNM 2828252726Srpaulo 2829252726Srpaulostatic int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2830252726Srpaulo{ 2831252726Srpaulo return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv); 2832252726Srpaulo} 2833252726Srpaulo 2834281806Srpaulo 2835281806Srpaulostatic int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2836281806Srpaulo{ 2837281806Srpaulo return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv); 2838281806Srpaulo} 2839281806Srpaulo 2840252726Srpaulo#endif /* CONFIG_WNM */ 2841252726Srpaulo 2842252726Srpaulo 2843252726Srpaulostatic int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2844252726Srpaulo{ 2845252726Srpaulo if (argc == 0) 2846252726Srpaulo return -1; 2847252726Srpaulo return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]); 2848252726Srpaulo} 2849252726Srpaulo 2850252726Srpaulo 2851281806Srpaulo#ifdef ANDROID 2852281806Srpaulostatic int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2853281806Srpaulo{ 2854281806Srpaulo return wpa_cli_cmd(ctrl, "DRIVER", 1, argc, argv); 2855281806Srpaulo} 2856281806Srpaulo#endif /* ANDROID */ 2857281806Srpaulo 2858281806Srpaulo 2859281806Srpaulostatic int wpa_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2860281806Srpaulo{ 2861281806Srpaulo return wpa_cli_cmd(ctrl, "VENDOR", 1, argc, argv); 2862281806Srpaulo} 2863281806Srpaulo 2864281806Srpaulo 2865281806Srpaulostatic int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2866281806Srpaulo{ 2867281806Srpaulo return wpa_ctrl_command(ctrl, "FLUSH"); 2868281806Srpaulo} 2869281806Srpaulo 2870281806Srpaulo 2871281806Srpaulostatic int wpa_cli_cmd_radio_work(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2872281806Srpaulo{ 2873281806Srpaulo return wpa_cli_cmd(ctrl, "RADIO_WORK", 1, argc, argv); 2874281806Srpaulo} 2875281806Srpaulo 2876281806Srpaulo 2877281806Srpaulostatic int wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl *ctrl, int argc, 2878281806Srpaulo char *argv[]) 2879281806Srpaulo{ 2880281806Srpaulo return wpa_cli_cmd(ctrl, "NEIGHBOR_REP_REQUEST", 0, argc, argv); 2881281806Srpaulo} 2882281806Srpaulo 2883281806Srpaulo 2884281806Srpaulostatic int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2885281806Srpaulo{ 2886281806Srpaulo return wpa_ctrl_command(ctrl, "ERP_FLUSH"); 2887281806Srpaulo} 2888281806Srpaulo 2889281806Srpaulo 2890281806Srpaulostatic int wpa_cli_cmd_mac_rand_scan(struct wpa_ctrl *ctrl, int argc, 2891281806Srpaulo char *argv[]) 2892281806Srpaulo{ 2893281806Srpaulo return wpa_cli_cmd(ctrl, "MAC_RAND_SCAN", 1, argc, argv); 2894281806Srpaulo} 2895281806Srpaulo 2896281806Srpaulo 2897289549Srpaulostatic int wpa_cli_cmd_get_pref_freq_list(struct wpa_ctrl *ctrl, int argc, 2898289549Srpaulo char *argv[]) 2899289549Srpaulo{ 2900289549Srpaulo return wpa_cli_cmd(ctrl, "GET_PREF_FREQ_LIST", 1, argc, argv); 2901289549Srpaulo} 2902289549Srpaulo 2903289549Srpaulo 2904337817Scystatic int wpa_cli_cmd_p2p_lo_start(struct wpa_ctrl *ctrl, int argc, 2905337817Scy char *argv[]) 2906337817Scy{ 2907337817Scy return wpa_cli_cmd(ctrl, "P2P_LO_START", 4, argc, argv); 2908337817Scy} 2909337817Scy 2910337817Scy 2911337817Scystatic int wpa_cli_cmd_p2p_lo_stop(struct wpa_ctrl *ctrl, int argc, 2912337817Scy char *argv[]) 2913337817Scy{ 2914337817Scy return wpa_cli_cmd(ctrl, "P2P_LO_STOP", 0, argc, argv); 2915337817Scy} 2916337817Scy 2917337817Scy 2918346981Scy#ifdef CONFIG_DPP 2919346981Scy 2920346981Scystatic int wpa_cli_cmd_dpp_qr_code(struct wpa_ctrl *ctrl, int argc, 2921346981Scy char *argv[]) 2922346981Scy{ 2923346981Scy return wpa_cli_cmd(ctrl, "DPP_QR_CODE", 1, argc, argv); 2924346981Scy} 2925346981Scy 2926346981Scy 2927346981Scystatic int wpa_cli_cmd_dpp_bootstrap_gen(struct wpa_ctrl *ctrl, int argc, 2928346981Scy char *argv[]) 2929346981Scy{ 2930346981Scy return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_GEN", 1, argc, argv); 2931346981Scy} 2932346981Scy 2933346981Scy 2934346981Scystatic int wpa_cli_cmd_dpp_bootstrap_remove(struct wpa_ctrl *ctrl, int argc, 2935346981Scy char *argv[]) 2936346981Scy{ 2937346981Scy return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_REMOVE", 1, argc, argv); 2938346981Scy} 2939346981Scy 2940346981Scy 2941346981Scystatic int wpa_cli_cmd_dpp_bootstrap_get_uri(struct wpa_ctrl *ctrl, int argc, 2942346981Scy char *argv[]) 2943346981Scy{ 2944346981Scy return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_GET_URI", 1, argc, argv); 2945346981Scy} 2946346981Scy 2947346981Scy 2948346981Scystatic int wpa_cli_cmd_dpp_bootstrap_info(struct wpa_ctrl *ctrl, int argc, 2949346981Scy char *argv[]) 2950346981Scy{ 2951346981Scy return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_INFO", 1, argc, argv); 2952346981Scy} 2953346981Scy 2954346981Scy 2955346981Scystatic int wpa_cli_cmd_dpp_auth_init(struct wpa_ctrl *ctrl, int argc, 2956346981Scy char *argv[]) 2957346981Scy{ 2958346981Scy return wpa_cli_cmd(ctrl, "DPP_AUTH_INIT", 1, argc, argv); 2959346981Scy} 2960346981Scy 2961346981Scy 2962346981Scystatic int wpa_cli_cmd_dpp_listen(struct wpa_ctrl *ctrl, int argc, 2963346981Scy char *argv[]) 2964346981Scy{ 2965346981Scy return wpa_cli_cmd(ctrl, "DPP_LISTEN", 1, argc, argv); 2966346981Scy} 2967346981Scy 2968346981Scy 2969346981Scystatic int wpa_cli_cmd_dpp_stop_listen(struct wpa_ctrl *ctrl, int argc, 2970346981Scy char *argv[]) 2971346981Scy{ 2972346981Scy return wpa_ctrl_command(ctrl, "DPP_STOP_LISTEN"); 2973346981Scy} 2974346981Scy 2975346981Scy 2976346981Scystatic int wpa_cli_cmd_dpp_configurator_add(struct wpa_ctrl *ctrl, int argc, 2977346981Scy char *argv[]) 2978346981Scy{ 2979346981Scy return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_ADD", 0, argc, argv); 2980346981Scy} 2981346981Scy 2982346981Scy 2983346981Scystatic int wpa_cli_cmd_dpp_configurator_remove(struct wpa_ctrl *ctrl, int argc, 2984346981Scy char *argv[]) 2985346981Scy{ 2986346981Scy return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_REMOVE", 1, argc, argv); 2987346981Scy} 2988346981Scy 2989346981Scy 2990346981Scystatic int wpa_cli_cmd_dpp_configurator_get_key(struct wpa_ctrl *ctrl, int argc, 2991346981Scy char *argv[]) 2992346981Scy{ 2993346981Scy return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_GET_KEY", 1, argc, argv); 2994346981Scy} 2995346981Scy 2996346981Scy 2997346981Scystatic int wpa_cli_cmd_dpp_configurator_sign(struct wpa_ctrl *ctrl, int argc, 2998346981Scy char *argv[]) 2999346981Scy{ 3000346981Scy return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_SIGN", 1, argc, argv); 3001346981Scy} 3002346981Scy 3003346981Scy 3004346981Scystatic int wpa_cli_cmd_dpp_pkex_add(struct wpa_ctrl *ctrl, int argc, 3005346981Scy char *argv[]) 3006346981Scy{ 3007346981Scy return wpa_cli_cmd(ctrl, "DPP_PKEX_ADD", 1, argc, argv); 3008346981Scy} 3009346981Scy 3010346981Scy 3011346981Scystatic int wpa_cli_cmd_dpp_pkex_remove(struct wpa_ctrl *ctrl, int argc, 3012346981Scy char *argv[]) 3013346981Scy{ 3014346981Scy return wpa_cli_cmd(ctrl, "DPP_PKEX_REMOVE", 1, argc, argv); 3015346981Scy} 3016346981Scy 3017346981Scy#endif /* CONFIG_DPP */ 3018346981Scy 3019346981Scy 3020189251Ssamenum wpa_cli_cmd_flags { 3021189251Ssam cli_cmd_flag_none = 0x00, 3022189251Ssam cli_cmd_flag_sensitive = 0x01 3023189251Ssam}; 3024189251Ssam 3025189251Ssamstruct wpa_cli_cmd { 3026189251Ssam const char *cmd; 3027189251Ssam int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]); 3028252726Srpaulo char ** (*completion)(const char *str, int pos); 3029189251Ssam enum wpa_cli_cmd_flags flags; 3030189251Ssam const char *usage; 3031189251Ssam}; 3032189251Ssam 3033289549Srpaulostatic const struct wpa_cli_cmd wpa_cli_commands[] = { 3034252726Srpaulo { "status", wpa_cli_cmd_status, NULL, 3035189251Ssam cli_cmd_flag_none, 3036189251Ssam "[verbose] = get current WPA/EAPOL/EAP status" }, 3037252726Srpaulo { "ifname", wpa_cli_cmd_ifname, NULL, 3038189251Ssam cli_cmd_flag_none, 3039252726Srpaulo "= get current interface name" }, 3040252726Srpaulo { "ping", wpa_cli_cmd_ping, NULL, 3041252726Srpaulo cli_cmd_flag_none, 3042189251Ssam "= pings wpa_supplicant" }, 3043252726Srpaulo { "relog", wpa_cli_cmd_relog, NULL, 3044189251Ssam cli_cmd_flag_none, 3045252726Srpaulo "= re-open log-file (allow rolling logs)" }, 3046252726Srpaulo { "note", wpa_cli_cmd_note, NULL, 3047252726Srpaulo cli_cmd_flag_none, 3048252726Srpaulo "<text> = add a note to wpa_supplicant debug log" }, 3049252726Srpaulo { "mib", wpa_cli_cmd_mib, NULL, 3050252726Srpaulo cli_cmd_flag_none, 3051189251Ssam "= get MIB variables (dot1x, dot11)" }, 3052252726Srpaulo { "help", wpa_cli_cmd_help, wpa_cli_complete_help, 3053189251Ssam cli_cmd_flag_none, 3054252726Srpaulo "[command] = show usage help" }, 3055252726Srpaulo { "interface", wpa_cli_cmd_interface, NULL, 3056189251Ssam cli_cmd_flag_none, 3057189251Ssam "[ifname] = show interfaces/select interface" }, 3058252726Srpaulo { "level", wpa_cli_cmd_level, NULL, 3059189251Ssam cli_cmd_flag_none, 3060189251Ssam "<debug level> = change debug level" }, 3061252726Srpaulo { "license", wpa_cli_cmd_license, NULL, 3062189251Ssam cli_cmd_flag_none, 3063189251Ssam "= show full wpa_cli license" }, 3064252726Srpaulo { "quit", wpa_cli_cmd_quit, NULL, 3065189251Ssam cli_cmd_flag_none, 3066189251Ssam "= exit wpa_cli" }, 3067281806Srpaulo { "set", wpa_cli_cmd_set, wpa_cli_complete_set, 3068189251Ssam cli_cmd_flag_none, 3069189251Ssam "= set variables (shows list of variables when run without " 3070189251Ssam "arguments)" }, 3071281806Srpaulo { "dump", wpa_cli_cmd_dump, NULL, 3072281806Srpaulo cli_cmd_flag_none, 3073281806Srpaulo "= dump config variables" }, 3074289549Srpaulo { "get", wpa_cli_cmd_get, wpa_cli_complete_get, 3075189251Ssam cli_cmd_flag_none, 3076252726Srpaulo "<name> = get information" }, 3077337817Scy { "driver_flags", wpa_cli_cmd_driver_flags, NULL, 3078337817Scy cli_cmd_flag_none, 3079337817Scy "= list driver flags" }, 3080252726Srpaulo { "logon", wpa_cli_cmd_logon, NULL, 3081252726Srpaulo cli_cmd_flag_none, 3082189251Ssam "= IEEE 802.1X EAPOL state machine logon" }, 3083252726Srpaulo { "logoff", wpa_cli_cmd_logoff, NULL, 3084189251Ssam cli_cmd_flag_none, 3085189251Ssam "= IEEE 802.1X EAPOL state machine logoff" }, 3086252726Srpaulo { "pmksa", wpa_cli_cmd_pmksa, NULL, 3087189251Ssam cli_cmd_flag_none, 3088189251Ssam "= show PMKSA cache" }, 3089281806Srpaulo { "pmksa_flush", wpa_cli_cmd_pmksa_flush, NULL, 3090281806Srpaulo cli_cmd_flag_none, 3091281806Srpaulo "= flush PMKSA cache entries" }, 3092346981Scy#ifdef CONFIG_PMKSA_CACHE_EXTERNAL 3093346981Scy { "pmksa_get", wpa_cli_cmd_pmksa_get, NULL, 3094346981Scy cli_cmd_flag_none, 3095346981Scy "<network_id> = fetch all stored PMKSA cache entries" }, 3096346981Scy { "pmksa_add", wpa_cli_cmd_pmksa_add, NULL, 3097346981Scy cli_cmd_flag_sensitive, 3098346981Scy "<network_id> <BSSID> <PMKID> <PMK> <reauth_time in seconds> <expiration in seconds> <akmp> <opportunistic> = store PMKSA cache entry from external storage" }, 3099346981Scy#ifdef CONFIG_MESH 3100346981Scy { "mesh_pmksa_get", wpa_cli_mesh_cmd_pmksa_get, NULL, 3101346981Scy cli_cmd_flag_none, 3102346981Scy "<peer MAC address | any> = fetch all stored mesh PMKSA cache entries" }, 3103346981Scy { "mesh_pmksa_add", wpa_cli_mesh_cmd_pmksa_add, NULL, 3104346981Scy cli_cmd_flag_sensitive, 3105346981Scy "<BSSID> <PMKID> <PMK> <expiration in seconds> = store mesh PMKSA cache entry from external storage" }, 3106346981Scy#endif /* CONFIG_MESH */ 3107346981Scy#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */ 3108252726Srpaulo { "reassociate", wpa_cli_cmd_reassociate, NULL, 3109189251Ssam cli_cmd_flag_none, 3110189251Ssam "= force reassociation" }, 3111281806Srpaulo { "reattach", wpa_cli_cmd_reattach, NULL, 3112281806Srpaulo cli_cmd_flag_none, 3113281806Srpaulo "= force reassociation back to the same BSS" }, 3114252726Srpaulo { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss, 3115189251Ssam cli_cmd_flag_none, 3116189251Ssam "<BSSID> = force preauthentication" }, 3117346981Scy { "identity", wpa_cli_cmd_identity, wpa_cli_complete_network_id, 3118189251Ssam cli_cmd_flag_none, 3119189251Ssam "<network id> <identity> = configure identity for an SSID" }, 3120346981Scy { "password", wpa_cli_cmd_password, wpa_cli_complete_network_id, 3121189251Ssam cli_cmd_flag_sensitive, 3122189251Ssam "<network id> <password> = configure password for an SSID" }, 3123346981Scy { "new_password", wpa_cli_cmd_new_password, 3124346981Scy wpa_cli_complete_network_id, cli_cmd_flag_sensitive, 3125189251Ssam "<network id> <password> = change password for an SSID" }, 3126346981Scy { "pin", wpa_cli_cmd_pin, wpa_cli_complete_network_id, 3127189251Ssam cli_cmd_flag_sensitive, 3128189251Ssam "<network id> <pin> = configure pin for an SSID" }, 3129346981Scy { "otp", wpa_cli_cmd_otp, wpa_cli_complete_network_id, 3130189251Ssam cli_cmd_flag_sensitive, 3131189251Ssam "<network id> <password> = configure one-time-password for an SSID" 3132189251Ssam }, 3133346981Scy { "psk_passphrase", wpa_cli_cmd_psk_passphrase, 3134346981Scy wpa_cli_complete_network_id, cli_cmd_flag_sensitive, 3135346981Scy "<network id> <PSK/passphrase> = configure PSK/passphrase for an SSID" }, 3136346981Scy { "passphrase", wpa_cli_cmd_passphrase, wpa_cli_complete_network_id, 3137189251Ssam cli_cmd_flag_sensitive, 3138189251Ssam "<network id> <passphrase> = configure private key passphrase\n" 3139189251Ssam " for an SSID" }, 3140346981Scy { "sim", wpa_cli_cmd_sim, wpa_cli_complete_network_id, 3141281806Srpaulo cli_cmd_flag_sensitive, 3142281806Srpaulo "<network id> <pin> = report SIM operation result" }, 3143346981Scy { "bssid", wpa_cli_cmd_bssid, wpa_cli_complete_network_id, 3144189251Ssam cli_cmd_flag_none, 3145189251Ssam "<network id> <BSSID> = set preferred BSSID for an SSID" }, 3146252726Srpaulo { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss, 3147189251Ssam cli_cmd_flag_none, 3148252726Srpaulo "<BSSID> = add a BSSID to the blacklist\n" 3149252726Srpaulo "blacklist clear = clear the blacklist\n" 3150252726Srpaulo "blacklist = display the blacklist" }, 3151252726Srpaulo { "log_level", wpa_cli_cmd_log_level, NULL, 3152252726Srpaulo cli_cmd_flag_none, 3153252726Srpaulo "<level> [<timestamp>] = update the log level/timestamp\n" 3154252726Srpaulo "log_level = display the current log level and log options" }, 3155252726Srpaulo { "list_networks", wpa_cli_cmd_list_networks, NULL, 3156252726Srpaulo cli_cmd_flag_none, 3157189251Ssam "= list configured networks" }, 3158289549Srpaulo { "select_network", wpa_cli_cmd_select_network, 3159289549Srpaulo wpa_cli_complete_network_id, 3160189251Ssam cli_cmd_flag_none, 3161189251Ssam "<network id> = select a network (disable others)" }, 3162289549Srpaulo { "enable_network", wpa_cli_cmd_enable_network, 3163289549Srpaulo wpa_cli_complete_network_id, 3164189251Ssam cli_cmd_flag_none, 3165189251Ssam "<network id> = enable a network" }, 3166289549Srpaulo { "disable_network", wpa_cli_cmd_disable_network, 3167289549Srpaulo wpa_cli_complete_network_id, 3168189251Ssam cli_cmd_flag_none, 3169189251Ssam "<network id> = disable a network" }, 3170252726Srpaulo { "add_network", wpa_cli_cmd_add_network, NULL, 3171189251Ssam cli_cmd_flag_none, 3172189251Ssam "= add a network" }, 3173289549Srpaulo { "remove_network", wpa_cli_cmd_remove_network, 3174289549Srpaulo wpa_cli_complete_network_id, 3175189251Ssam cli_cmd_flag_none, 3176189251Ssam "<network id> = remove a network" }, 3177289549Srpaulo { "set_network", wpa_cli_cmd_set_network, wpa_cli_complete_network, 3178189251Ssam cli_cmd_flag_sensitive, 3179189251Ssam "<network id> <variable> <value> = set network variables (shows\n" 3180189251Ssam " list of variables when run without arguments)" }, 3181289549Srpaulo { "get_network", wpa_cli_cmd_get_network, wpa_cli_complete_network, 3182189251Ssam cli_cmd_flag_none, 3183189251Ssam "<network id> <variable> = get network variables" }, 3184289549Srpaulo { "dup_network", wpa_cli_cmd_dup_network, wpa_cli_complete_dup_network, 3185281806Srpaulo cli_cmd_flag_none, 3186281806Srpaulo "<src network id> <dst network id> <variable> = duplicate network variables" 3187281806Srpaulo }, 3188252726Srpaulo { "list_creds", wpa_cli_cmd_list_creds, NULL, 3189189251Ssam cli_cmd_flag_none, 3190252726Srpaulo "= list configured credentials" }, 3191252726Srpaulo { "add_cred", wpa_cli_cmd_add_cred, NULL, 3192252726Srpaulo cli_cmd_flag_none, 3193252726Srpaulo "= add a credential" }, 3194252726Srpaulo { "remove_cred", wpa_cli_cmd_remove_cred, NULL, 3195252726Srpaulo cli_cmd_flag_none, 3196252726Srpaulo "<cred id> = remove a credential" }, 3197346981Scy { "set_cred", wpa_cli_cmd_set_cred, wpa_cli_complete_cred, 3198252726Srpaulo cli_cmd_flag_sensitive, 3199252726Srpaulo "<cred id> <variable> <value> = set credential variables" }, 3200346981Scy { "get_cred", wpa_cli_cmd_get_cred, wpa_cli_complete_cred, 3201281806Srpaulo cli_cmd_flag_none, 3202281806Srpaulo "<cred id> <variable> = get credential variables" }, 3203252726Srpaulo { "save_config", wpa_cli_cmd_save_config, NULL, 3204252726Srpaulo cli_cmd_flag_none, 3205189251Ssam "= save the current configuration" }, 3206252726Srpaulo { "disconnect", wpa_cli_cmd_disconnect, NULL, 3207189251Ssam cli_cmd_flag_none, 3208189251Ssam "= disconnect and wait for reassociate/reconnect command before\n" 3209189251Ssam " connecting" }, 3210252726Srpaulo { "reconnect", wpa_cli_cmd_reconnect, NULL, 3211189251Ssam cli_cmd_flag_none, 3212189251Ssam "= like reassociate, but only takes effect if already disconnected" 3213189251Ssam }, 3214252726Srpaulo { "scan", wpa_cli_cmd_scan, NULL, 3215189251Ssam cli_cmd_flag_none, 3216189251Ssam "= request new BSS scan" }, 3217252726Srpaulo { "scan_results", wpa_cli_cmd_scan_results, NULL, 3218189251Ssam cli_cmd_flag_none, 3219189251Ssam "= get latest scan results" }, 3220337817Scy { "abort_scan", wpa_cli_cmd_abort_scan, NULL, 3221337817Scy cli_cmd_flag_none, 3222337817Scy "= request ongoing scan to be aborted" }, 3223252726Srpaulo { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss, 3224189251Ssam cli_cmd_flag_none, 3225189251Ssam "<<idx> | <bssid>> = get detailed scan result info" }, 3226337817Scy { "get_capability", wpa_cli_cmd_get_capability, 3227337817Scy wpa_cli_complete_get_capability, cli_cmd_flag_none, 3228281806Srpaulo "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> " 3229289549Srpaulo "= get capabilities" }, 3230252726Srpaulo { "reconfigure", wpa_cli_cmd_reconfigure, NULL, 3231189251Ssam cli_cmd_flag_none, 3232189251Ssam "= force wpa_supplicant to re-read its configuration file" }, 3233252726Srpaulo { "terminate", wpa_cli_cmd_terminate, NULL, 3234189251Ssam cli_cmd_flag_none, 3235189251Ssam "= terminate wpa_supplicant" }, 3236252726Srpaulo { "interface_add", wpa_cli_cmd_interface_add, NULL, 3237189251Ssam cli_cmd_flag_none, 3238189251Ssam "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n" 3239337817Scy " <bridge_name> <create> <type> = adds new interface, all " 3240337817Scy "parameters but\n" 3241337817Scy " <ifname> are optional. Supported types are station ('sta') and " 3242337817Scy "AP ('ap')" }, 3243252726Srpaulo { "interface_remove", wpa_cli_cmd_interface_remove, NULL, 3244189251Ssam cli_cmd_flag_none, 3245189251Ssam "<ifname> = removes the interface" }, 3246252726Srpaulo { "interface_list", wpa_cli_cmd_interface_list, NULL, 3247189251Ssam cli_cmd_flag_none, 3248189251Ssam "= list available interfaces" }, 3249252726Srpaulo { "ap_scan", wpa_cli_cmd_ap_scan, NULL, 3250189251Ssam cli_cmd_flag_none, 3251189251Ssam "<value> = set ap_scan parameter" }, 3252252726Srpaulo { "scan_interval", wpa_cli_cmd_scan_interval, NULL, 3253189251Ssam cli_cmd_flag_none, 3254252726Srpaulo "<value> = set scan_interval parameter (in seconds)" }, 3255252726Srpaulo { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL, 3256252726Srpaulo cli_cmd_flag_none, 3257252726Srpaulo "<value> = set BSS expiration age parameter" }, 3258252726Srpaulo { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL, 3259252726Srpaulo cli_cmd_flag_none, 3260252726Srpaulo "<value> = set BSS expiration scan count parameter" }, 3261252726Srpaulo { "bss_flush", wpa_cli_cmd_bss_flush, NULL, 3262252726Srpaulo cli_cmd_flag_none, 3263252726Srpaulo "<value> = set BSS flush age (0 by default)" }, 3264252726Srpaulo { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss, 3265189251Ssam cli_cmd_flag_none, 3266189251Ssam "<addr> = request over-the-DS FT with <addr>" }, 3267252726Srpaulo { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss, 3268189251Ssam cli_cmd_flag_none, 3269189251Ssam "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" }, 3270252726Srpaulo { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss, 3271189251Ssam cli_cmd_flag_sensitive, 3272189251Ssam "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not " 3273189251Ssam "hardcoded)" }, 3274252726Srpaulo { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL, 3275214734Srpaulo cli_cmd_flag_sensitive, 3276252726Srpaulo "<PIN> = verify PIN checksum" }, 3277252726Srpaulo { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none, 3278252726Srpaulo "Cancels the pending WPS operation" }, 3279252726Srpaulo#ifdef CONFIG_WPS_NFC 3280252726Srpaulo { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss, 3281252726Srpaulo cli_cmd_flag_none, 3282252726Srpaulo "[BSSID] = start Wi-Fi Protected Setup: NFC" }, 3283281806Srpaulo { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL, 3284281806Srpaulo cli_cmd_flag_none, 3285281806Srpaulo "<WPS|NDEF> = build configuration token" }, 3286252726Srpaulo { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL, 3287252726Srpaulo cli_cmd_flag_none, 3288252726Srpaulo "<WPS|NDEF> = create password token" }, 3289252726Srpaulo { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL, 3290189251Ssam cli_cmd_flag_sensitive, 3291252726Srpaulo "<hexdump of payload> = report read NFC tag with WPS data" }, 3292252726Srpaulo { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL, 3293252726Srpaulo cli_cmd_flag_none, 3294252726Srpaulo "<NDEF> <WPS> = create NFC handover request" }, 3295252726Srpaulo { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL, 3296252726Srpaulo cli_cmd_flag_none, 3297252726Srpaulo "<NDEF> <WPS> = create NFC handover select" }, 3298281806Srpaulo { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL, 3299252726Srpaulo cli_cmd_flag_none, 3300281806Srpaulo "<role> <type> <hexdump of req> <hexdump of sel> = report completed " 3301281806Srpaulo "NFC handover" }, 3302252726Srpaulo#endif /* CONFIG_WPS_NFC */ 3303252726Srpaulo { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss, 3304252726Srpaulo cli_cmd_flag_sensitive, 3305189251Ssam "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" }, 3306252726Srpaulo { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL, 3307252726Srpaulo cli_cmd_flag_sensitive, 3308252726Srpaulo "[params..] = enable/disable AP PIN" }, 3309252726Srpaulo { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL, 3310214734Srpaulo cli_cmd_flag_none, 3311252726Srpaulo "[IP address] = start Wi-Fi Protected Setup External Registrar" }, 3312252726Srpaulo { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL, 3313214734Srpaulo cli_cmd_flag_none, 3314214734Srpaulo "= stop Wi-Fi Protected Setup External Registrar" }, 3315252726Srpaulo { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL, 3316214734Srpaulo cli_cmd_flag_sensitive, 3317214734Srpaulo "<UUID> <PIN> = add an Enrollee PIN to External Registrar" }, 3318252726Srpaulo { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL, 3319214734Srpaulo cli_cmd_flag_none, 3320214734Srpaulo "<UUID> = accept an Enrollee PBC using External Registrar" }, 3321252726Srpaulo { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL, 3322214734Srpaulo cli_cmd_flag_sensitive, 3323214734Srpaulo "<UUID> <PIN> = learn AP configuration" }, 3324252726Srpaulo { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL, 3325214734Srpaulo cli_cmd_flag_none, 3326252726Srpaulo "<UUID> <network id> = set AP configuration for enrolling" }, 3327252726Srpaulo { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL, 3328252726Srpaulo cli_cmd_flag_sensitive, 3329252726Srpaulo "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" }, 3330252726Srpaulo#ifdef CONFIG_WPS_NFC 3331252726Srpaulo { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL, 3332252726Srpaulo cli_cmd_flag_none, 3333252726Srpaulo "<WPS/NDEF> <UUID> = build NFC configuration token" }, 3334252726Srpaulo#endif /* CONFIG_WPS_NFC */ 3335252726Srpaulo { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL, 3336252726Srpaulo cli_cmd_flag_none, 3337214734Srpaulo "<addr> = request RSN authentication with <addr> in IBSS" }, 3338214734Srpaulo#ifdef CONFIG_AP 3339346981Scy { "sta", wpa_cli_cmd_sta, wpa_cli_complete_sta, 3340214734Srpaulo cli_cmd_flag_none, 3341214734Srpaulo "<addr> = get information about an associated station (AP)" }, 3342252726Srpaulo { "all_sta", wpa_cli_cmd_all_sta, NULL, 3343214734Srpaulo cli_cmd_flag_none, 3344214734Srpaulo "= get information about all associated stations (AP)" }, 3345346981Scy { "list_sta", wpa_cli_cmd_list_sta, NULL, 3346252726Srpaulo cli_cmd_flag_none, 3347346981Scy "= list all stations (AP)" }, 3348346981Scy { "deauthenticate", wpa_cli_cmd_deauthenticate, 3349346981Scy wpa_cli_complete_deauthenticate, cli_cmd_flag_none, 3350252726Srpaulo "<addr> = deauthenticate a station" }, 3351346981Scy { "disassociate", wpa_cli_cmd_disassociate, 3352346981Scy wpa_cli_complete_disassociate, cli_cmd_flag_none, 3353252726Srpaulo "<addr> = disassociate a station" }, 3354281806Srpaulo { "chan_switch", wpa_cli_cmd_chanswitch, NULL, 3355281806Srpaulo cli_cmd_flag_none, 3356281806Srpaulo "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]" 3357281806Srpaulo " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]" 3358281806Srpaulo " = CSA parameters" }, 3359214734Srpaulo#endif /* CONFIG_AP */ 3360252726Srpaulo { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none, 3361214734Srpaulo "= notification of suspend/hibernate" }, 3362252726Srpaulo { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none, 3363214734Srpaulo "= notification of resume/thaw" }, 3364281806Srpaulo#ifdef CONFIG_TESTING_OPTIONS 3365252726Srpaulo { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none, 3366214734Srpaulo "= drop SA without deauth/disassoc (test command)" }, 3367281806Srpaulo#endif /* CONFIG_TESTING_OPTIONS */ 3368252726Srpaulo { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss, 3369214734Srpaulo cli_cmd_flag_none, 3370214734Srpaulo "<addr> = roam to the specified BSS" }, 3371281806Srpaulo#ifdef CONFIG_MESH 3372281806Srpaulo { "mesh_interface_add", wpa_cli_cmd_mesh_interface_add, NULL, 3373281806Srpaulo cli_cmd_flag_none, 3374281806Srpaulo "[ifname] = Create a new mesh interface" }, 3375281806Srpaulo { "mesh_group_add", wpa_cli_cmd_mesh_group_add, NULL, 3376281806Srpaulo cli_cmd_flag_none, 3377281806Srpaulo "<network id> = join a mesh network (disable others)" }, 3378281806Srpaulo { "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL, 3379281806Srpaulo cli_cmd_flag_none, 3380281806Srpaulo "<ifname> = Remove mesh group interface" }, 3381337817Scy { "mesh_peer_remove", wpa_cli_cmd_mesh_peer_remove, NULL, 3382337817Scy cli_cmd_flag_none, 3383337817Scy "<addr> = Remove a mesh peer" }, 3384337817Scy { "mesh_peer_add", wpa_cli_cmd_mesh_peer_add, NULL, 3385337817Scy cli_cmd_flag_none, 3386337817Scy "<addr> [duration=<seconds>] = Add a mesh peer" }, 3387281806Srpaulo#endif /* CONFIG_MESH */ 3388252726Srpaulo#ifdef CONFIG_P2P 3389252726Srpaulo { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find, 3390252726Srpaulo cli_cmd_flag_none, 3391252726Srpaulo "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" }, 3392252726Srpaulo { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none, 3393252726Srpaulo "= stop P2P Devices search" }, 3394281806Srpaulo { "p2p_asp_provision", wpa_cli_cmd_p2p_asp_provision, NULL, 3395281806Srpaulo cli_cmd_flag_none, 3396281806Srpaulo "<addr> adv_id=<adv_id> conncap=<conncap> [info=<infodata>] = provision with a P2P ASP Device" }, 3397281806Srpaulo { "p2p_asp_provision_resp", wpa_cli_cmd_p2p_asp_provision_resp, NULL, 3398281806Srpaulo cli_cmd_flag_none, 3399281806Srpaulo "<addr> adv_id=<adv_id> [role<conncap>] [info=<infodata>] = provision with a P2P ASP Device" }, 3400252726Srpaulo { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect, 3401252726Srpaulo cli_cmd_flag_none, 3402252726Srpaulo "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" }, 3403252726Srpaulo { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none, 3404252726Srpaulo "[timeout] = listen for P2P Devices for up-to timeout seconds" }, 3405252726Srpaulo { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, 3406252726Srpaulo wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none, 3407252726Srpaulo "<ifname> = remove P2P group interface (terminate group if GO)" }, 3408252726Srpaulo { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none, 3409252726Srpaulo "[ht40] = add a new P2P group (local end as GO)" }, 3410337817Scy { "p2p_group_member", wpa_cli_cmd_p2p_group_member, NULL, 3411337817Scy cli_cmd_flag_none, 3412337817Scy "<dev_addr> = Get peer interface address on local GO using peer Device Address" }, 3413252726Srpaulo { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, 3414252726Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3415252726Srpaulo "<addr> <method> = request provisioning discovery" }, 3416252726Srpaulo { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL, 3417252726Srpaulo cli_cmd_flag_none, 3418252726Srpaulo "= get the passphrase for a group (GO only)" }, 3419252726Srpaulo { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req, 3420252726Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3421252726Srpaulo "<addr> <TLVs> = schedule service discovery request" }, 3422252726Srpaulo { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req, 3423252726Srpaulo NULL, cli_cmd_flag_none, 3424252726Srpaulo "<id> = cancel pending service discovery request" }, 3425252726Srpaulo { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL, 3426252726Srpaulo cli_cmd_flag_none, 3427252726Srpaulo "<freq> <addr> <dialog token> <TLVs> = service discovery response" }, 3428252726Srpaulo { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL, 3429252726Srpaulo cli_cmd_flag_none, 3430252726Srpaulo "= indicate change in local services" }, 3431252726Srpaulo { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL, 3432252726Srpaulo cli_cmd_flag_none, 3433252726Srpaulo "<external> = set external processing of service discovery" }, 3434252726Srpaulo { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL, 3435252726Srpaulo cli_cmd_flag_none, 3436252726Srpaulo "= remove all stored service entries" }, 3437252726Srpaulo { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL, 3438252726Srpaulo cli_cmd_flag_none, 3439281806Srpaulo "<bonjour|upnp|asp> <query|version> <response|service> = add a local " 3440252726Srpaulo "service" }, 3441281806Srpaulo { "p2p_service_rep", wpa_cli_cmd_p2p_service_rep, NULL, 3442281806Srpaulo cli_cmd_flag_none, 3443281806Srpaulo "asp <auto> <adv_id> <svc_state> <svc_string> [<svc_info>] = replace " 3444281806Srpaulo "local ASP service" }, 3445252726Srpaulo { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL, 3446252726Srpaulo cli_cmd_flag_none, 3447252726Srpaulo "<bonjour|upnp> <query|version> [|service] = remove a local " 3448252726Srpaulo "service" }, 3449252726Srpaulo { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer, 3450252726Srpaulo cli_cmd_flag_none, 3451252726Srpaulo "<addr> = reject connection attempts from a specific peer" }, 3452252726Srpaulo { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL, 3453252726Srpaulo cli_cmd_flag_none, 3454252726Srpaulo "<cmd> [peer=addr] = invite peer" }, 3455252726Srpaulo { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none, 3456252726Srpaulo "[discovered] = list known (optionally, only fully discovered) P2P " 3457252726Srpaulo "peers" }, 3458252726Srpaulo { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer, 3459252726Srpaulo cli_cmd_flag_none, 3460252726Srpaulo "<address> = show information about known P2P peer" }, 3461281806Srpaulo { "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set, 3462281806Srpaulo cli_cmd_flag_none, 3463252726Srpaulo "<field> <value> = set a P2P parameter" }, 3464252726Srpaulo { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none, 3465252726Srpaulo "= flush P2P state" }, 3466252726Srpaulo { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none, 3467252726Srpaulo "= cancel P2P group formation" }, 3468252726Srpaulo { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, 3469252726Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3470252726Srpaulo "<address> = unauthorize a peer" }, 3471252726Srpaulo { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL, 3472252726Srpaulo cli_cmd_flag_none, 3473252726Srpaulo "[<duration> <interval>] [<duration> <interval>] = request GO " 3474252726Srpaulo "presence" }, 3475252726Srpaulo { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL, 3476252726Srpaulo cli_cmd_flag_none, 3477252726Srpaulo "[<period> <interval>] = set extended listen timing" }, 3478281806Srpaulo { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client, 3479281806Srpaulo wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3480281806Srpaulo "<address|iface=address> = remove a peer from all groups" }, 3481346981Scy#endif /* CONFIG_P2P */ 3482337817Scy { "vendor_elem_add", wpa_cli_cmd_vendor_elem_add, NULL, 3483337817Scy cli_cmd_flag_none, 3484337817Scy "<frame id> <hexdump of elem(s)> = add vendor specific IEs to frame(s)\n" 3485337817Scy VENDOR_ELEM_FRAME_ID }, 3486337817Scy { "vendor_elem_get", wpa_cli_cmd_vendor_elem_get, NULL, 3487337817Scy cli_cmd_flag_none, 3488337817Scy "<frame id> = get vendor specific IE(s) to frame(s)\n" 3489337817Scy VENDOR_ELEM_FRAME_ID }, 3490337817Scy { "vendor_elem_remove", wpa_cli_cmd_vendor_elem_remove, NULL, 3491337817Scy cli_cmd_flag_none, 3492337817Scy "<frame id> <hexdump of elem(s)> = remove vendor specific IE(s) in frame(s)\n" 3493337817Scy VENDOR_ELEM_FRAME_ID }, 3494252726Srpaulo#ifdef CONFIG_WIFI_DISPLAY 3495252726Srpaulo { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL, 3496252726Srpaulo cli_cmd_flag_none, 3497252726Srpaulo "<subelem> [contents] = set Wi-Fi Display subelement" }, 3498252726Srpaulo { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL, 3499252726Srpaulo cli_cmd_flag_none, 3500252726Srpaulo "<subelem> = get Wi-Fi Display subelement" }, 3501252726Srpaulo#endif /* CONFIG_WIFI_DISPLAY */ 3502252726Srpaulo#ifdef CONFIG_INTERWORKING 3503252726Srpaulo { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none, 3504252726Srpaulo "= fetch ANQP information for all APs" }, 3505252726Srpaulo { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL, 3506252726Srpaulo cli_cmd_flag_none, 3507252726Srpaulo "= stop fetch_anqp operation" }, 3508252726Srpaulo { "interworking_select", wpa_cli_cmd_interworking_select, NULL, 3509252726Srpaulo cli_cmd_flag_none, 3510252726Srpaulo "[auto] = perform Interworking network selection" }, 3511252726Srpaulo { "interworking_connect", wpa_cli_cmd_interworking_connect, 3512252726Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3513252726Srpaulo "<BSSID> = connect using Interworking credentials" }, 3514281806Srpaulo { "interworking_add_network", wpa_cli_cmd_interworking_add_network, 3515281806Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3516281806Srpaulo "<BSSID> = connect using Interworking credentials" }, 3517252726Srpaulo { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss, 3518252726Srpaulo cli_cmd_flag_none, 3519252726Srpaulo "<addr> <info id>[,<info id>]... = request ANQP information" }, 3520252726Srpaulo { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss, 3521252726Srpaulo cli_cmd_flag_none, 3522252726Srpaulo "<addr> <AdvProtoID> [QueryReq] = GAS request" }, 3523252726Srpaulo { "gas_response_get", wpa_cli_cmd_gas_response_get, 3524252726Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3525252726Srpaulo "<addr> <dialog token> [start,len] = Fetch last GAS response" }, 3526252726Srpaulo#endif /* CONFIG_INTERWORKING */ 3527252726Srpaulo#ifdef CONFIG_HS20 3528252726Srpaulo { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss, 3529252726Srpaulo cli_cmd_flag_none, 3530252726Srpaulo "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information" 3531252726Srpaulo }, 3532252726Srpaulo { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list, 3533252726Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3534252726Srpaulo "<addr> <home realm> = get HS20 nai home realm list" }, 3535281806Srpaulo { "hs20_icon_request", wpa_cli_cmd_hs20_icon_request, 3536281806Srpaulo wpa_cli_complete_bss, cli_cmd_flag_none, 3537281806Srpaulo "<addr> <icon name> = get Hotspot 2.0 OSU icon" }, 3538281806Srpaulo { "fetch_osu", wpa_cli_cmd_fetch_osu, NULL, cli_cmd_flag_none, 3539281806Srpaulo "= fetch OSU provider information from all APs" }, 3540281806Srpaulo { "cancel_fetch_osu", wpa_cli_cmd_cancel_fetch_osu, NULL, 3541281806Srpaulo cli_cmd_flag_none, 3542281806Srpaulo "= cancel fetch_osu command" }, 3543252726Srpaulo#endif /* CONFIG_HS20 */ 3544252726Srpaulo { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL, 3545252726Srpaulo cli_cmd_flag_none, 3546252726Srpaulo "<0/1> = disable/enable automatic reconnection" }, 3547252726Srpaulo { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL, 3548252726Srpaulo cli_cmd_flag_none, 3549252726Srpaulo "<addr> = request TDLS discovery with <addr>" }, 3550252726Srpaulo { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL, 3551252726Srpaulo cli_cmd_flag_none, 3552252726Srpaulo "<addr> = request TDLS setup with <addr>" }, 3553252726Srpaulo { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL, 3554252726Srpaulo cli_cmd_flag_none, 3555252726Srpaulo "<addr> = tear down TDLS with <addr>" }, 3556289549Srpaulo { "tdls_link_status", wpa_cli_cmd_tdls_link_status, NULL, 3557289549Srpaulo cli_cmd_flag_none, 3558289549Srpaulo "<addr> = TDLS link status with <addr>" }, 3559281806Srpaulo { "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL, 3560281806Srpaulo cli_cmd_flag_none, 3561281806Srpaulo "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] " 3562281806Srpaulo "[mean_data_rate=#] [min_phy_rate=#] [sba=#] [fixed_nominal_msdu] " 3563281806Srpaulo "= add WMM-AC traffic stream" }, 3564281806Srpaulo { "wmm_ac_delts", wpa_cli_cmd_wmm_ac_delts, NULL, 3565281806Srpaulo cli_cmd_flag_none, 3566281806Srpaulo "<tsid> = delete WMM-AC traffic stream" }, 3567281806Srpaulo { "wmm_ac_status", wpa_cli_cmd_wmm_ac_status, NULL, 3568281806Srpaulo cli_cmd_flag_none, 3569281806Srpaulo "= show status for Wireless Multi-Media Admission-Control" }, 3570281806Srpaulo { "tdls_chan_switch", wpa_cli_cmd_tdls_chan_switch, NULL, 3571281806Srpaulo cli_cmd_flag_none, 3572281806Srpaulo "<addr> <oper class> <freq> [sec_channel_offset=] [center_freq1=] " 3573281806Srpaulo "[center_freq2=] [bandwidth=] [ht|vht] = enable channel switching " 3574281806Srpaulo "with TDLS peer" }, 3575281806Srpaulo { "tdls_cancel_chan_switch", wpa_cli_cmd_tdls_cancel_chan_switch, NULL, 3576281806Srpaulo cli_cmd_flag_none, 3577281806Srpaulo "<addr> = disable channel switching with TDLS peer <addr>" }, 3578252726Srpaulo { "signal_poll", wpa_cli_cmd_signal_poll, NULL, 3579252726Srpaulo cli_cmd_flag_none, 3580252726Srpaulo "= get signal parameters" }, 3581337817Scy { "signal_monitor", wpa_cli_cmd_signal_monitor, NULL, 3582337817Scy cli_cmd_flag_none, 3583337817Scy "= set signal monitor parameters" }, 3584252726Srpaulo { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL, 3585252726Srpaulo cli_cmd_flag_none, 3586252726Srpaulo "= get TX/RX packet counters" }, 3587252726Srpaulo { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL, 3588252726Srpaulo cli_cmd_flag_none, 3589252726Srpaulo "= trigger IEEE 802.1X/EAPOL reauthentication" }, 3590252726Srpaulo#ifdef CONFIG_AUTOSCAN 3591252726Srpaulo { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none, 3592252726Srpaulo "[params] = Set or unset (if none) autoscan parameters" }, 3593252726Srpaulo#endif /* CONFIG_AUTOSCAN */ 3594252726Srpaulo#ifdef CONFIG_WNM 3595252726Srpaulo { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none, 3596252726Srpaulo "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" }, 3597281806Srpaulo { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none, 3598346981Scy "<query reason> [list]" 3599346981Scy " [neighbor=<BSSID>,<BSSID information>,<operating class>,<channel number>,<PHY type>[,<hexdump of optional subelements>]" 3600346981Scy " = Send BSS Transition Management Query" }, 3601252726Srpaulo#endif /* CONFIG_WNM */ 3602252726Srpaulo { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive, 3603252726Srpaulo "<params..> = Sent unprocessed command" }, 3604281806Srpaulo { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none, 3605281806Srpaulo "= flush wpa_supplicant state" }, 3606281806Srpaulo#ifdef ANDROID 3607281806Srpaulo { "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none, 3608281806Srpaulo "<command> = driver private commands" }, 3609281806Srpaulo#endif /* ANDROID */ 3610281806Srpaulo { "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none, 3611281806Srpaulo "= radio_work <show/add/done>" }, 3612281806Srpaulo { "vendor", wpa_cli_cmd_vendor, NULL, cli_cmd_flag_none, 3613281806Srpaulo "<vendor id> <command id> [<hex formatted command argument>] = Send vendor command" 3614281806Srpaulo }, 3615281806Srpaulo { "neighbor_rep_request", 3616281806Srpaulo wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none, 3617337817Scy "[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)" 3618281806Srpaulo }, 3619281806Srpaulo { "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none, 3620281806Srpaulo "= flush ERP keys" }, 3621281806Srpaulo { "mac_rand_scan", 3622281806Srpaulo wpa_cli_cmd_mac_rand_scan, NULL, cli_cmd_flag_none, 3623281806Srpaulo "<scan|sched|pno|all> enable=<0/1> [addr=mac-address " 3624281806Srpaulo "mask=mac-address-mask] = scan MAC randomization" 3625281806Srpaulo }, 3626289549Srpaulo { "get_pref_freq_list", wpa_cli_cmd_get_pref_freq_list, NULL, 3627289549Srpaulo cli_cmd_flag_none, 3628289549Srpaulo "<interface type> = retrieve preferred freq list for the specified interface type" }, 3629337817Scy { "p2p_lo_start", wpa_cli_cmd_p2p_lo_start, NULL, 3630337817Scy cli_cmd_flag_none, 3631337817Scy "<freq> <period> <interval> <count> = start P2P listen offload" }, 3632337817Scy { "p2p_lo_stop", wpa_cli_cmd_p2p_lo_stop, NULL, 3633337817Scy cli_cmd_flag_none, 3634337817Scy "= stop P2P listen offload" }, 3635346981Scy#ifdef CONFIG_DPP 3636346981Scy { "dpp_qr_code", wpa_cli_cmd_dpp_qr_code, NULL, cli_cmd_flag_none, 3637346981Scy "report a scanned DPP URI from a QR Code" }, 3638346981Scy { "dpp_bootstrap_gen", wpa_cli_cmd_dpp_bootstrap_gen, NULL, 3639346981Scy cli_cmd_flag_sensitive, 3640346981Scy "type=<qrcode> [chan=..] [mac=..] [info=..] [curve=..] [key=..] = generate DPP bootstrap information" }, 3641346981Scy { "dpp_bootstrap_remove", wpa_cli_cmd_dpp_bootstrap_remove, NULL, 3642346981Scy cli_cmd_flag_none, 3643346981Scy "*|<id> = remove DPP bootstrap information" }, 3644346981Scy { "dpp_bootstrap_get_uri", wpa_cli_cmd_dpp_bootstrap_get_uri, NULL, 3645346981Scy cli_cmd_flag_none, 3646346981Scy "<id> = get DPP bootstrap URI" }, 3647346981Scy { "dpp_bootstrap_info", wpa_cli_cmd_dpp_bootstrap_info, NULL, 3648346981Scy cli_cmd_flag_none, 3649346981Scy "<id> = show DPP bootstrap information" }, 3650346981Scy { "dpp_auth_init", wpa_cli_cmd_dpp_auth_init, NULL, cli_cmd_flag_none, 3651346981Scy "peer=<id> [own=<id>] = initiate DPP bootstrapping" }, 3652346981Scy { "dpp_listen", wpa_cli_cmd_dpp_listen, NULL, cli_cmd_flag_none, 3653346981Scy "<freq in MHz> = start DPP listen" }, 3654346981Scy { "dpp_stop_listen", wpa_cli_cmd_dpp_stop_listen, NULL, 3655346981Scy cli_cmd_flag_none, 3656346981Scy "= stop DPP listen" }, 3657346981Scy { "dpp_configurator_add", wpa_cli_cmd_dpp_configurator_add, NULL, 3658346981Scy cli_cmd_flag_sensitive, 3659346981Scy "[curve=..] [key=..] = add DPP configurator" }, 3660346981Scy { "dpp_configurator_remove", wpa_cli_cmd_dpp_configurator_remove, NULL, 3661346981Scy cli_cmd_flag_none, 3662346981Scy "*|<id> = remove DPP configurator" }, 3663346981Scy { "dpp_configurator_get_key", wpa_cli_cmd_dpp_configurator_get_key, 3664346981Scy NULL, cli_cmd_flag_none, 3665346981Scy "<id> = Get DPP configurator's private key" }, 3666346981Scy { "dpp_configurator_sign", wpa_cli_cmd_dpp_configurator_sign, NULL, 3667346981Scy cli_cmd_flag_none, 3668346981Scy "conf=<role> configurator=<id> = generate self DPP configuration" }, 3669346981Scy { "dpp_pkex_add", wpa_cli_cmd_dpp_pkex_add, NULL, 3670346981Scy cli_cmd_flag_sensitive, 3671346981Scy "add PKEX code" }, 3672346981Scy { "dpp_pkex_remove", wpa_cli_cmd_dpp_pkex_remove, NULL, 3673346981Scy cli_cmd_flag_none, 3674346981Scy "*|<id> = remove DPP pkex information" }, 3675346981Scy#endif /* CONFIG_DPP */ 3676252726Srpaulo { NULL, NULL, NULL, cli_cmd_flag_none, NULL } 3677189251Ssam}; 3678189251Ssam 3679189251Ssam 3680189251Ssam/* 3681189251Ssam * Prints command usage, lines are padded with the specified string. 3682189251Ssam */ 3683289549Srpaulostatic void print_cmd_help(const struct wpa_cli_cmd *cmd, const char *pad) 3684189251Ssam{ 3685189251Ssam char c; 3686189251Ssam size_t n; 3687189251Ssam 3688189251Ssam printf("%s%s ", pad, cmd->cmd); 3689189251Ssam for (n = 0; (c = cmd->usage[n]); n++) { 3690189251Ssam printf("%c", c); 3691189251Ssam if (c == '\n') 3692189251Ssam printf("%s", pad); 3693189251Ssam } 3694189251Ssam printf("\n"); 3695189251Ssam} 3696189251Ssam 3697189251Ssam 3698252726Srpaulostatic void print_help(const char *cmd) 3699189251Ssam{ 3700189251Ssam int n; 3701189251Ssam printf("commands:\n"); 3702252726Srpaulo for (n = 0; wpa_cli_commands[n].cmd; n++) { 3703252726Srpaulo if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd)) 3704252726Srpaulo print_cmd_help(&wpa_cli_commands[n], " "); 3705252726Srpaulo } 3706189251Ssam} 3707189251Ssam 3708189251Ssam 3709252726Srpaulostatic int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd) 3710189251Ssam{ 3711189251Ssam const char *c, *delim; 3712189251Ssam int n; 3713189251Ssam size_t len; 3714189251Ssam 3715189251Ssam delim = os_strchr(cmd, ' '); 3716189251Ssam if (delim) 3717189251Ssam len = delim - cmd; 3718189251Ssam else 3719189251Ssam len = os_strlen(cmd); 3720189251Ssam 3721189251Ssam for (n = 0; (c = wpa_cli_commands[n].cmd); n++) { 3722189251Ssam if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c)) 3723189251Ssam return (wpa_cli_commands[n].flags & 3724189251Ssam cli_cmd_flag_sensitive); 3725189251Ssam } 3726189251Ssam return 0; 3727189251Ssam} 3728189251Ssam 3729189251Ssam 3730252726Srpaulostatic char ** wpa_list_cmd_list(void) 3731252726Srpaulo{ 3732252726Srpaulo char **res; 3733252726Srpaulo int i, count; 3734281806Srpaulo struct cli_txt_entry *e; 3735252726Srpaulo 3736281806Srpaulo count = ARRAY_SIZE(wpa_cli_commands); 3737281806Srpaulo count += dl_list_len(&p2p_groups); 3738281806Srpaulo count += dl_list_len(&ifnames); 3739281806Srpaulo res = os_calloc(count + 1, sizeof(char *)); 3740252726Srpaulo if (res == NULL) 3741252726Srpaulo return NULL; 3742252726Srpaulo 3743252726Srpaulo for (i = 0; wpa_cli_commands[i].cmd; i++) { 3744252726Srpaulo res[i] = os_strdup(wpa_cli_commands[i].cmd); 3745252726Srpaulo if (res[i] == NULL) 3746252726Srpaulo break; 3747252726Srpaulo } 3748252726Srpaulo 3749281806Srpaulo dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) { 3750281806Srpaulo size_t len = 8 + os_strlen(e->txt); 3751281806Srpaulo res[i] = os_malloc(len); 3752281806Srpaulo if (res[i] == NULL) 3753281806Srpaulo break; 3754281806Srpaulo os_snprintf(res[i], len, "ifname=%s", e->txt); 3755281806Srpaulo i++; 3756281806Srpaulo } 3757281806Srpaulo 3758281806Srpaulo dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) { 3759281806Srpaulo res[i] = os_strdup(e->txt); 3760281806Srpaulo if (res[i] == NULL) 3761281806Srpaulo break; 3762281806Srpaulo i++; 3763281806Srpaulo } 3764281806Srpaulo 3765252726Srpaulo return res; 3766252726Srpaulo} 3767252726Srpaulo 3768252726Srpaulo 3769252726Srpaulostatic char ** wpa_cli_cmd_completion(const char *cmd, const char *str, 3770252726Srpaulo int pos) 3771252726Srpaulo{ 3772252726Srpaulo int i; 3773252726Srpaulo 3774252726Srpaulo for (i = 0; wpa_cli_commands[i].cmd; i++) { 3775252726Srpaulo if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) { 3776252726Srpaulo if (wpa_cli_commands[i].completion) 3777252726Srpaulo return wpa_cli_commands[i].completion(str, 3778252726Srpaulo pos); 3779252726Srpaulo edit_clear_line(); 3780252726Srpaulo printf("\r%s\n", wpa_cli_commands[i].usage); 3781252726Srpaulo edit_redraw(); 3782252726Srpaulo break; 3783252726Srpaulo } 3784252726Srpaulo } 3785252726Srpaulo 3786252726Srpaulo return NULL; 3787252726Srpaulo} 3788252726Srpaulo 3789252726Srpaulo 3790252726Srpaulostatic char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos) 3791252726Srpaulo{ 3792252726Srpaulo char **res; 3793252726Srpaulo const char *end; 3794252726Srpaulo char *cmd; 3795252726Srpaulo 3796281806Srpaulo if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) { 3797281806Srpaulo end = os_strchr(str, ' '); 3798281806Srpaulo if (end && pos > end - str) { 3799281806Srpaulo pos -= end - str + 1; 3800281806Srpaulo str = end + 1; 3801281806Srpaulo } 3802281806Srpaulo } 3803281806Srpaulo 3804252726Srpaulo end = os_strchr(str, ' '); 3805252726Srpaulo if (end == NULL || str + pos < end) 3806252726Srpaulo return wpa_list_cmd_list(); 3807252726Srpaulo 3808252726Srpaulo cmd = os_malloc(pos + 1); 3809252726Srpaulo if (cmd == NULL) 3810252726Srpaulo return NULL; 3811252726Srpaulo os_memcpy(cmd, str, pos); 3812252726Srpaulo cmd[end - str] = '\0'; 3813252726Srpaulo res = wpa_cli_cmd_completion(cmd, str, pos); 3814252726Srpaulo os_free(cmd); 3815252726Srpaulo return res; 3816252726Srpaulo} 3817252726Srpaulo 3818252726Srpaulo 3819189251Ssamstatic int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[]) 3820189251Ssam{ 3821289549Srpaulo const struct wpa_cli_cmd *cmd, *match = NULL; 3822189251Ssam int count; 3823189251Ssam int ret = 0; 3824189251Ssam 3825281806Srpaulo if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) { 3826281806Srpaulo ifname_prefix = argv[0] + 7; 3827281806Srpaulo argv = &argv[1]; 3828281806Srpaulo argc--; 3829281806Srpaulo } else 3830281806Srpaulo ifname_prefix = NULL; 3831281806Srpaulo 3832281806Srpaulo if (argc == 0) 3833281806Srpaulo return -1; 3834281806Srpaulo 3835189251Ssam count = 0; 3836189251Ssam cmd = wpa_cli_commands; 3837189251Ssam while (cmd->cmd) { 3838189251Ssam if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0) 3839189251Ssam { 3840189251Ssam match = cmd; 3841189251Ssam if (os_strcasecmp(cmd->cmd, argv[0]) == 0) { 3842189251Ssam /* we have an exact match */ 3843189251Ssam count = 1; 3844189251Ssam break; 3845189251Ssam } 3846189251Ssam count++; 3847189251Ssam } 3848189251Ssam cmd++; 3849189251Ssam } 3850189251Ssam 3851189251Ssam if (count > 1) { 3852189251Ssam printf("Ambiguous command '%s'; possible commands:", argv[0]); 3853189251Ssam cmd = wpa_cli_commands; 3854189251Ssam while (cmd->cmd) { 3855189251Ssam if (os_strncasecmp(cmd->cmd, argv[0], 3856189251Ssam os_strlen(argv[0])) == 0) { 3857189251Ssam printf(" %s", cmd->cmd); 3858189251Ssam } 3859189251Ssam cmd++; 3860189251Ssam } 3861189251Ssam printf("\n"); 3862189251Ssam ret = 1; 3863189251Ssam } else if (count == 0) { 3864189251Ssam printf("Unknown command '%s'\n", argv[0]); 3865189251Ssam ret = 1; 3866189251Ssam } else { 3867189251Ssam ret = match->handler(ctrl, argc - 1, &argv[1]); 3868189251Ssam } 3869189251Ssam 3870189251Ssam return ret; 3871189251Ssam} 3872189251Ssam 3873189251Ssam 3874189251Ssamstatic int wpa_cli_exec(const char *program, const char *arg1, 3875189251Ssam const char *arg2) 3876189251Ssam{ 3877281806Srpaulo char *arg; 3878189251Ssam size_t len; 3879189251Ssam int res; 3880189251Ssam 3881337817Scy /* If no interface is specified, set the global */ 3882337817Scy if (!arg1) 3883337817Scy arg1 = "global"; 3884337817Scy 3885281806Srpaulo len = os_strlen(arg1) + os_strlen(arg2) + 2; 3886281806Srpaulo arg = os_malloc(len); 3887281806Srpaulo if (arg == NULL) 3888189251Ssam return -1; 3889281806Srpaulo os_snprintf(arg, len, "%s %s", arg1, arg2); 3890281806Srpaulo res = os_exec(program, arg, 1); 3891281806Srpaulo os_free(arg); 3892189251Ssam 3893281806Srpaulo return res; 3894189251Ssam} 3895189251Ssam 3896189251Ssam 3897189251Ssamstatic void wpa_cli_action_process(const char *msg) 3898189251Ssam{ 3899189251Ssam const char *pos; 3900189251Ssam char *copy = NULL, *id, *pos2; 3901281806Srpaulo const char *ifname = ctrl_ifname; 3902281806Srpaulo char ifname_buf[100]; 3903189251Ssam 3904289549Srpaulo if (eloop_terminated()) 3905289549Srpaulo return; 3906289549Srpaulo 3907189251Ssam pos = msg; 3908281806Srpaulo if (os_strncmp(pos, "IFNAME=", 7) == 0) { 3909281806Srpaulo const char *end; 3910281806Srpaulo end = os_strchr(pos + 7, ' '); 3911281806Srpaulo if (end && (unsigned int) (end - pos) < sizeof(ifname_buf)) { 3912281806Srpaulo pos += 7; 3913281806Srpaulo os_memcpy(ifname_buf, pos, end - pos); 3914281806Srpaulo ifname_buf[end - pos] = '\0'; 3915281806Srpaulo ifname = ifname_buf; 3916281806Srpaulo pos = end + 1; 3917281806Srpaulo } 3918281806Srpaulo } 3919189251Ssam if (*pos == '<') { 3920281806Srpaulo const char *prev = pos; 3921189251Ssam /* skip priority */ 3922189251Ssam pos = os_strchr(pos, '>'); 3923189251Ssam if (pos) 3924189251Ssam pos++; 3925189251Ssam else 3926281806Srpaulo pos = prev; 3927189251Ssam } 3928189251Ssam 3929337817Scy if (str_starts(pos, WPA_EVENT_CONNECTED)) { 3930189251Ssam int new_id = -1; 3931189251Ssam os_unsetenv("WPA_ID"); 3932189251Ssam os_unsetenv("WPA_ID_STR"); 3933189251Ssam os_unsetenv("WPA_CTRL_DIR"); 3934189251Ssam 3935189251Ssam pos = os_strstr(pos, "[id="); 3936189251Ssam if (pos) 3937189251Ssam copy = os_strdup(pos + 4); 3938189251Ssam 3939189251Ssam if (copy) { 3940189251Ssam pos2 = id = copy; 3941189251Ssam while (*pos2 && *pos2 != ' ') 3942189251Ssam pos2++; 3943189251Ssam *pos2++ = '\0'; 3944189251Ssam new_id = atoi(id); 3945189251Ssam os_setenv("WPA_ID", id, 1); 3946189251Ssam while (*pos2 && *pos2 != '=') 3947189251Ssam pos2++; 3948189251Ssam if (*pos2 == '=') 3949189251Ssam pos2++; 3950189251Ssam id = pos2; 3951189251Ssam while (*pos2 && *pos2 != ']') 3952189251Ssam pos2++; 3953189251Ssam *pos2 = '\0'; 3954189251Ssam os_setenv("WPA_ID_STR", id, 1); 3955189251Ssam os_free(copy); 3956189251Ssam } 3957189251Ssam 3958189251Ssam os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1); 3959189251Ssam 3960281806Srpaulo if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) { 3961189251Ssam wpa_cli_connected = 1; 3962189251Ssam wpa_cli_last_id = new_id; 3963281806Srpaulo wpa_cli_exec(action_file, ifname, "CONNECTED"); 3964189251Ssam } 3965337817Scy } else if (str_starts(pos, WPA_EVENT_DISCONNECTED)) { 3966189251Ssam if (wpa_cli_connected) { 3967189251Ssam wpa_cli_connected = 0; 3968281806Srpaulo wpa_cli_exec(action_file, ifname, "DISCONNECTED"); 3969189251Ssam } 3970337817Scy } else if (str_starts(pos, AP_EVENT_ENABLED)) { 3971281806Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 3972337817Scy } else if (str_starts(pos, AP_EVENT_DISABLED)) { 3973281806Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 3974337817Scy } else if (str_starts(pos, MESH_GROUP_STARTED)) { 3975281806Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 3976337817Scy } else if (str_starts(pos, MESH_GROUP_REMOVED)) { 3977281806Srpaulo wpa_cli_exec(action_file, ctrl_ifname, pos); 3978337817Scy } else if (str_starts(pos, MESH_PEER_CONNECTED)) { 3979337817Scy wpa_cli_exec(action_file, ctrl_ifname, pos); 3980337817Scy } else if (str_starts(pos, MESH_PEER_DISCONNECTED)) { 3981337817Scy wpa_cli_exec(action_file, ctrl_ifname, pos); 3982337817Scy } else if (str_starts(pos, P2P_EVENT_GROUP_STARTED)) { 3983281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3984337817Scy } else if (str_starts(pos, P2P_EVENT_GROUP_REMOVED)) { 3985281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3986337817Scy } else if (str_starts(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) { 3987281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3988337817Scy } else if (str_starts(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) { 3989281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3990337817Scy } else if (str_starts(pos, P2P_EVENT_GO_NEG_FAILURE)) { 3991281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3992337817Scy } else if (str_starts(pos, WPS_EVENT_SUCCESS)) { 3993281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 3994346981Scy } else if (str_starts(pos, WPS_EVENT_ACTIVE)) { 3995346981Scy wpa_cli_exec(action_file, ifname, pos); 3996346981Scy } else if (str_starts(pos, WPS_EVENT_TIMEOUT)) { 3997346981Scy wpa_cli_exec(action_file, ifname, pos); 3998337817Scy } else if (str_starts(pos, WPS_EVENT_FAIL)) { 3999281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 4000337817Scy } else if (str_starts(pos, AP_STA_CONNECTED)) { 4001281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 4002337817Scy } else if (str_starts(pos, AP_STA_DISCONNECTED)) { 4003281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 4004337817Scy } else if (str_starts(pos, ESS_DISASSOC_IMMINENT)) { 4005281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 4006337817Scy } else if (str_starts(pos, HS20_SUBSCRIPTION_REMEDIATION)) { 4007281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 4008337817Scy } else if (str_starts(pos, HS20_DEAUTH_IMMINENT_NOTICE)) { 4009281806Srpaulo wpa_cli_exec(action_file, ifname, pos); 4010346981Scy } else if (str_starts(pos, HS20_T_C_ACCEPTANCE)) { 4011346981Scy wpa_cli_exec(action_file, ifname, pos); 4012337817Scy } else if (str_starts(pos, WPA_EVENT_TERMINATING)) { 4013189251Ssam printf("wpa_supplicant is terminating - stop monitoring\n"); 4014189251Ssam wpa_cli_quit = 1; 4015189251Ssam } 4016189251Ssam} 4017189251Ssam 4018189251Ssam 4019189251Ssam#ifndef CONFIG_ANSI_C_EXTRA 4020189251Ssamstatic void wpa_cli_action_cb(char *msg, size_t len) 4021189251Ssam{ 4022189251Ssam wpa_cli_action_process(msg); 4023189251Ssam} 4024189251Ssam#endif /* CONFIG_ANSI_C_EXTRA */ 4025189251Ssam 4026189251Ssam 4027346981Scystatic int wpa_cli_open_global_ctrl(void) 4028346981Scy{ 4029346981Scy#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 4030346981Scy ctrl_conn = wpa_ctrl_open(NULL); 4031346981Scy#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 4032346981Scy ctrl_conn = wpa_ctrl_open(global); 4033346981Scy#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 4034346981Scy if (!ctrl_conn) { 4035346981Scy fprintf(stderr, 4036346981Scy "Failed to connect to wpa_supplicant global interface: %s error: %s\n", 4037346981Scy global, strerror(errno)); 4038346981Scy return -1; 4039346981Scy } 4040346981Scy 4041346981Scy if (interactive) { 4042346981Scy update_ifnames(ctrl_conn); 4043346981Scy mon_conn = wpa_ctrl_open(global); 4044346981Scy if (mon_conn) { 4045346981Scy if (wpa_ctrl_attach(mon_conn) == 0) { 4046346981Scy wpa_cli_attached = 1; 4047346981Scy eloop_register_read_sock( 4048346981Scy wpa_ctrl_get_fd(mon_conn), 4049346981Scy wpa_cli_mon_receive, 4050346981Scy NULL, NULL); 4051346981Scy } else { 4052346981Scy printf("Failed to open monitor connection through global control interface\n"); 4053346981Scy } 4054346981Scy } 4055346981Scy update_stations(ctrl_conn); 4056346981Scy } 4057346981Scy 4058346981Scy return 0; 4059346981Scy} 4060346981Scy 4061346981Scy 4062189251Ssamstatic void wpa_cli_reconnect(void) 4063189251Ssam{ 4064189251Ssam wpa_cli_close_connection(); 4065346981Scy if ((global && wpa_cli_open_global_ctrl() < 0) || 4066346981Scy (!global && wpa_cli_open_connection(ctrl_ifname, 1) < 0)) 4067252726Srpaulo return; 4068252726Srpaulo 4069252726Srpaulo if (interactive) { 4070252726Srpaulo edit_clear_line(); 4071252726Srpaulo printf("\rConnection to wpa_supplicant re-established\n"); 4072252726Srpaulo edit_redraw(); 4073346981Scy update_stations(ctrl_conn); 4074252726Srpaulo } 4075189251Ssam} 4076189251Ssam 4077189251Ssam 4078252726Srpaulostatic void cli_event(const char *str) 4079189251Ssam{ 4080252726Srpaulo const char *start, *s; 4081252726Srpaulo 4082252726Srpaulo start = os_strchr(str, '>'); 4083252726Srpaulo if (start == NULL) 4084252726Srpaulo return; 4085252726Srpaulo 4086252726Srpaulo start++; 4087252726Srpaulo 4088252726Srpaulo if (str_starts(start, WPA_EVENT_BSS_ADDED)) { 4089252726Srpaulo s = os_strchr(start, ' '); 4090252726Srpaulo if (s == NULL) 4091252726Srpaulo return; 4092252726Srpaulo s = os_strchr(s + 1, ' '); 4093252726Srpaulo if (s == NULL) 4094252726Srpaulo return; 4095252726Srpaulo cli_txt_list_add(&bsses, s + 1); 4096252726Srpaulo return; 4097252726Srpaulo } 4098252726Srpaulo 4099252726Srpaulo if (str_starts(start, WPA_EVENT_BSS_REMOVED)) { 4100252726Srpaulo s = os_strchr(start, ' '); 4101252726Srpaulo if (s == NULL) 4102252726Srpaulo return; 4103252726Srpaulo s = os_strchr(s + 1, ' '); 4104252726Srpaulo if (s == NULL) 4105252726Srpaulo return; 4106252726Srpaulo cli_txt_list_del_addr(&bsses, s + 1); 4107252726Srpaulo return; 4108252726Srpaulo } 4109252726Srpaulo 4110252726Srpaulo#ifdef CONFIG_P2P 4111252726Srpaulo if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) { 4112252726Srpaulo s = os_strstr(start, " p2p_dev_addr="); 4113252726Srpaulo if (s == NULL) 4114252726Srpaulo return; 4115252726Srpaulo cli_txt_list_add_addr(&p2p_peers, s + 14); 4116252726Srpaulo return; 4117252726Srpaulo } 4118252726Srpaulo 4119252726Srpaulo if (str_starts(start, P2P_EVENT_DEVICE_LOST)) { 4120252726Srpaulo s = os_strstr(start, " p2p_dev_addr="); 4121252726Srpaulo if (s == NULL) 4122252726Srpaulo return; 4123252726Srpaulo cli_txt_list_del_addr(&p2p_peers, s + 14); 4124252726Srpaulo return; 4125252726Srpaulo } 4126252726Srpaulo 4127252726Srpaulo if (str_starts(start, P2P_EVENT_GROUP_STARTED)) { 4128252726Srpaulo s = os_strchr(start, ' '); 4129252726Srpaulo if (s == NULL) 4130252726Srpaulo return; 4131289549Srpaulo cli_txt_list_add_word(&p2p_groups, s + 1, ' '); 4132252726Srpaulo return; 4133252726Srpaulo } 4134252726Srpaulo 4135252726Srpaulo if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) { 4136252726Srpaulo s = os_strchr(start, ' '); 4137252726Srpaulo if (s == NULL) 4138252726Srpaulo return; 4139289549Srpaulo cli_txt_list_del_word(&p2p_groups, s + 1, ' '); 4140252726Srpaulo return; 4141252726Srpaulo } 4142252726Srpaulo#endif /* CONFIG_P2P */ 4143252726Srpaulo} 4144252726Srpaulo 4145252726Srpaulo 4146252726Srpaulostatic int check_terminating(const char *msg) 4147252726Srpaulo{ 4148252726Srpaulo const char *pos = msg; 4149252726Srpaulo 4150252726Srpaulo if (*pos == '<') { 4151252726Srpaulo /* skip priority */ 4152252726Srpaulo pos = os_strchr(pos, '>'); 4153252726Srpaulo if (pos) 4154252726Srpaulo pos++; 4155252726Srpaulo else 4156252726Srpaulo pos = msg; 4157252726Srpaulo } 4158252726Srpaulo 4159337817Scy if (str_starts(pos, WPA_EVENT_TERMINATING) && ctrl_conn) { 4160252726Srpaulo edit_clear_line(); 4161252726Srpaulo printf("\rConnection to wpa_supplicant lost - trying to " 4162252726Srpaulo "reconnect\n"); 4163252726Srpaulo edit_redraw(); 4164252726Srpaulo wpa_cli_attached = 0; 4165252726Srpaulo wpa_cli_close_connection(); 4166252726Srpaulo return 1; 4167252726Srpaulo } 4168252726Srpaulo 4169252726Srpaulo return 0; 4170252726Srpaulo} 4171252726Srpaulo 4172252726Srpaulo 4173252726Srpaulostatic void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor) 4174252726Srpaulo{ 4175189251Ssam if (ctrl_conn == NULL) { 4176189251Ssam wpa_cli_reconnect(); 4177189251Ssam return; 4178189251Ssam } 4179189251Ssam while (wpa_ctrl_pending(ctrl) > 0) { 4180281806Srpaulo char buf[4096]; 4181189251Ssam size_t len = sizeof(buf) - 1; 4182189251Ssam if (wpa_ctrl_recv(ctrl, buf, &len) == 0) { 4183189251Ssam buf[len] = '\0'; 4184189251Ssam if (action_monitor) 4185189251Ssam wpa_cli_action_process(buf); 4186189251Ssam else { 4187252726Srpaulo cli_event(buf); 4188252726Srpaulo if (wpa_cli_show_event(buf)) { 4189252726Srpaulo edit_clear_line(); 4190252726Srpaulo printf("\r%s\n", buf); 4191252726Srpaulo edit_redraw(); 4192252726Srpaulo } 4193252726Srpaulo 4194252726Srpaulo if (interactive && check_terminating(buf) > 0) 4195252726Srpaulo return; 4196189251Ssam } 4197189251Ssam } else { 4198189251Ssam printf("Could not read pending message.\n"); 4199189251Ssam break; 4200189251Ssam } 4201189251Ssam } 4202189251Ssam 4203189251Ssam if (wpa_ctrl_pending(ctrl) < 0) { 4204189251Ssam printf("Connection to wpa_supplicant lost - trying to " 4205189251Ssam "reconnect\n"); 4206189251Ssam wpa_cli_reconnect(); 4207189251Ssam } 4208189251Ssam} 4209189251Ssam 4210189251Ssam 4211252726Srpaulostatic void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx) 4212189251Ssam{ 4213281806Srpaulo if (ctrl_conn) { 4214281806Srpaulo int res; 4215281806Srpaulo char *prefix = ifname_prefix; 4216281806Srpaulo 4217281806Srpaulo ifname_prefix = NULL; 4218281806Srpaulo res = _wpa_ctrl_command(ctrl_conn, "PING", 0); 4219281806Srpaulo ifname_prefix = prefix; 4220281806Srpaulo if (res) { 4221281806Srpaulo printf("Connection to wpa_supplicant lost - trying to " 4222281806Srpaulo "reconnect\n"); 4223281806Srpaulo wpa_cli_close_connection(); 4224281806Srpaulo } 4225214734Srpaulo } 4226252726Srpaulo if (!ctrl_conn) 4227252726Srpaulo wpa_cli_reconnect(); 4228252726Srpaulo eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL); 4229189251Ssam} 4230189251Ssam 4231189251Ssam 4232252726Srpaulostatic void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx) 4233214734Srpaulo{ 4234252726Srpaulo wpa_cli_recv_pending(mon_conn, 0); 4235252726Srpaulo} 4236214734Srpaulo 4237214734Srpaulo 4238252726Srpaulostatic void wpa_cli_edit_cmd_cb(void *ctx, char *cmd) 4239252726Srpaulo{ 4240252726Srpaulo char *argv[max_args]; 4241252726Srpaulo int argc; 4242252726Srpaulo argc = tokenize_cmd(cmd, argv); 4243252726Srpaulo if (argc) 4244252726Srpaulo wpa_request(ctrl_conn, argc, argv); 4245214734Srpaulo} 4246214734Srpaulo 4247214734Srpaulo 4248252726Srpaulostatic void wpa_cli_edit_eof_cb(void *ctx) 4249189251Ssam{ 4250252726Srpaulo eloop_terminate(); 4251189251Ssam} 4252189251Ssam 4253189251Ssam 4254252726Srpaulostatic int warning_displayed = 0; 4255252726Srpaulostatic char *hfile = NULL; 4256252726Srpaulostatic int edit_started = 0; 4257252726Srpaulo 4258252726Srpaulostatic void start_edit(void) 4259189251Ssam{ 4260252726Srpaulo char *home; 4261252726Srpaulo char *ps = NULL; 4262189251Ssam 4263252726Srpaulo#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE 4264252726Srpaulo ps = wpa_ctrl_get_remote_ifname(ctrl_conn); 4265252726Srpaulo#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */ 4266189251Ssam 4267289549Srpaulo#ifdef CONFIG_WPA_CLI_HISTORY_DIR 4268289549Srpaulo home = CONFIG_WPA_CLI_HISTORY_DIR; 4269289549Srpaulo#else /* CONFIG_WPA_CLI_HISTORY_DIR */ 4270189251Ssam home = getenv("HOME"); 4271289549Srpaulo#endif /* CONFIG_WPA_CLI_HISTORY_DIR */ 4272189251Ssam if (home) { 4273189251Ssam const char *fname = ".wpa_cli_history"; 4274189251Ssam int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1; 4275189251Ssam hfile = os_malloc(hfile_len); 4276252726Srpaulo if (hfile) 4277252726Srpaulo os_snprintf(hfile, hfile_len, "%s/%s", home, fname); 4278189251Ssam } 4279189251Ssam 4280252726Srpaulo if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb, 4281252726Srpaulo wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) { 4282252726Srpaulo eloop_terminate(); 4283252726Srpaulo return; 4284252726Srpaulo } 4285189251Ssam 4286252726Srpaulo edit_started = 1; 4287252726Srpaulo eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL); 4288252726Srpaulo} 4289189251Ssam 4290252726Srpaulo 4291281806Srpaulostatic void update_bssid_list(struct wpa_ctrl *ctrl) 4292281806Srpaulo{ 4293281806Srpaulo char buf[4096]; 4294281806Srpaulo size_t len = sizeof(buf); 4295281806Srpaulo int ret; 4296346981Scy const char *cmd = "BSS RANGE=ALL MASK=0x2"; 4297281806Srpaulo char *pos, *end; 4298281806Srpaulo 4299281806Srpaulo if (ctrl == NULL) 4300281806Srpaulo return; 4301281806Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 4302281806Srpaulo if (ret < 0) 4303281806Srpaulo return; 4304281806Srpaulo buf[len] = '\0'; 4305281806Srpaulo 4306281806Srpaulo pos = buf; 4307281806Srpaulo while (pos) { 4308281806Srpaulo pos = os_strstr(pos, "bssid="); 4309281806Srpaulo if (pos == NULL) 4310281806Srpaulo break; 4311281806Srpaulo pos += 6; 4312281806Srpaulo end = os_strchr(pos, '\n'); 4313281806Srpaulo if (end == NULL) 4314281806Srpaulo break; 4315281806Srpaulo *end = '\0'; 4316281806Srpaulo cli_txt_list_add(&bsses, pos); 4317281806Srpaulo pos = end + 1; 4318281806Srpaulo } 4319281806Srpaulo} 4320281806Srpaulo 4321281806Srpaulo 4322281806Srpaulostatic void update_ifnames(struct wpa_ctrl *ctrl) 4323281806Srpaulo{ 4324281806Srpaulo char buf[4096]; 4325281806Srpaulo size_t len = sizeof(buf); 4326281806Srpaulo int ret; 4327346981Scy const char *cmd = "INTERFACES"; 4328281806Srpaulo char *pos, *end; 4329281806Srpaulo char txt[200]; 4330281806Srpaulo 4331281806Srpaulo cli_txt_list_flush(&ifnames); 4332281806Srpaulo 4333281806Srpaulo if (ctrl == NULL) 4334281806Srpaulo return; 4335281806Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 4336281806Srpaulo if (ret < 0) 4337281806Srpaulo return; 4338281806Srpaulo buf[len] = '\0'; 4339281806Srpaulo 4340281806Srpaulo pos = buf; 4341281806Srpaulo while (pos) { 4342281806Srpaulo end = os_strchr(pos, '\n'); 4343281806Srpaulo if (end == NULL) 4344281806Srpaulo break; 4345281806Srpaulo *end = '\0'; 4346281806Srpaulo ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos); 4347281806Srpaulo if (!os_snprintf_error(sizeof(txt), ret)) 4348281806Srpaulo cli_txt_list_add(&ifnames, txt); 4349281806Srpaulo pos = end + 1; 4350281806Srpaulo } 4351281806Srpaulo} 4352281806Srpaulo 4353281806Srpaulo 4354346981Scystatic void update_creds(struct wpa_ctrl *ctrl) 4355346981Scy{ 4356346981Scy char buf[4096]; 4357346981Scy size_t len = sizeof(buf); 4358346981Scy int ret; 4359346981Scy const char *cmd = "LIST_CREDS"; 4360346981Scy char *pos, *end; 4361346981Scy int header = 1; 4362346981Scy 4363346981Scy cli_txt_list_flush(&creds); 4364346981Scy 4365346981Scy if (ctrl == NULL) 4366346981Scy return; 4367346981Scy ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 4368346981Scy if (ret < 0) 4369346981Scy return; 4370346981Scy buf[len] = '\0'; 4371346981Scy 4372346981Scy pos = buf; 4373346981Scy while (pos) { 4374346981Scy end = os_strchr(pos, '\n'); 4375346981Scy if (end == NULL) 4376346981Scy break; 4377346981Scy *end = '\0'; 4378346981Scy if (!header) 4379346981Scy cli_txt_list_add_word(&creds, pos, '\t'); 4380346981Scy header = 0; 4381346981Scy pos = end + 1; 4382346981Scy } 4383346981Scy} 4384346981Scy 4385346981Scy 4386289549Srpaulostatic void update_networks(struct wpa_ctrl *ctrl) 4387289549Srpaulo{ 4388289549Srpaulo char buf[4096]; 4389289549Srpaulo size_t len = sizeof(buf); 4390289549Srpaulo int ret; 4391346981Scy const char *cmd = "LIST_NETWORKS"; 4392289549Srpaulo char *pos, *end; 4393289549Srpaulo int header = 1; 4394289549Srpaulo 4395289549Srpaulo cli_txt_list_flush(&networks); 4396289549Srpaulo 4397289549Srpaulo if (ctrl == NULL) 4398289549Srpaulo return; 4399289549Srpaulo ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 4400289549Srpaulo if (ret < 0) 4401289549Srpaulo return; 4402289549Srpaulo buf[len] = '\0'; 4403289549Srpaulo 4404289549Srpaulo pos = buf; 4405289549Srpaulo while (pos) { 4406289549Srpaulo end = os_strchr(pos, '\n'); 4407289549Srpaulo if (end == NULL) 4408289549Srpaulo break; 4409289549Srpaulo *end = '\0'; 4410289549Srpaulo if (!header) 4411289549Srpaulo cli_txt_list_add_word(&networks, pos, '\t'); 4412289549Srpaulo header = 0; 4413289549Srpaulo pos = end + 1; 4414289549Srpaulo } 4415289549Srpaulo} 4416289549Srpaulo 4417289549Srpaulo 4418346981Scystatic void update_stations(struct wpa_ctrl *ctrl) 4419346981Scy{ 4420346981Scy#ifdef CONFIG_AP 4421346981Scy char addr[32], cmd[64]; 4422346981Scy 4423346981Scy if (!ctrl || !interactive) 4424346981Scy return; 4425346981Scy 4426346981Scy cli_txt_list_flush(&stations); 4427346981Scy 4428346981Scy if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 0)) 4429346981Scy return; 4430346981Scy do { 4431346981Scy if (os_strcmp(addr, "") != 0) 4432346981Scy cli_txt_list_add(&stations, addr); 4433346981Scy os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); 4434346981Scy } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 0) == 0); 4435346981Scy#endif /* CONFIG_AP */ 4436346981Scy} 4437346981Scy 4438346981Scy 4439252726Srpaulostatic void try_connection(void *eloop_ctx, void *timeout_ctx) 4440252726Srpaulo{ 4441281806Srpaulo if (ctrl_conn) 4442281806Srpaulo goto done; 4443281806Srpaulo 4444252726Srpaulo if (ctrl_ifname == NULL) 4445252726Srpaulo ctrl_ifname = wpa_cli_get_default_ifname(); 4446252726Srpaulo 4447337817Scy if (wpa_cli_open_connection(ctrl_ifname, 1)) { 4448252726Srpaulo if (!warning_displayed) { 4449252726Srpaulo printf("Could not connect to wpa_supplicant: " 4450281806Srpaulo "%s - re-trying\n", 4451281806Srpaulo ctrl_ifname ? ctrl_ifname : "(nil)"); 4452252726Srpaulo warning_displayed = 1; 4453189251Ssam } 4454252726Srpaulo eloop_register_timeout(1, 0, try_connection, NULL, NULL); 4455252726Srpaulo return; 4456189251Ssam } 4457252726Srpaulo 4458281806Srpaulo update_bssid_list(ctrl_conn); 4459346981Scy update_creds(ctrl_conn); 4460289549Srpaulo update_networks(ctrl_conn); 4461346981Scy update_stations(ctrl_conn); 4462281806Srpaulo 4463252726Srpaulo if (warning_displayed) 4464252726Srpaulo printf("Connection established.\n"); 4465252726Srpaulo 4466281806Srpaulodone: 4467252726Srpaulo start_edit(); 4468189251Ssam} 4469189251Ssam 4470189251Ssam 4471252726Srpaulostatic void wpa_cli_interactive(void) 4472252726Srpaulo{ 4473252726Srpaulo printf("\nInteractive mode\n\n"); 4474252726Srpaulo 4475252726Srpaulo eloop_register_timeout(0, 0, try_connection, NULL, NULL); 4476252726Srpaulo eloop_run(); 4477252726Srpaulo eloop_cancel_timeout(try_connection, NULL, NULL); 4478252726Srpaulo 4479252726Srpaulo cli_txt_list_flush(&p2p_peers); 4480252726Srpaulo cli_txt_list_flush(&p2p_groups); 4481252726Srpaulo cli_txt_list_flush(&bsses); 4482281806Srpaulo cli_txt_list_flush(&ifnames); 4483346981Scy cli_txt_list_flush(&creds); 4484289549Srpaulo cli_txt_list_flush(&networks); 4485252726Srpaulo if (edit_started) 4486252726Srpaulo edit_deinit(hfile, wpa_cli_edit_filter_history_cb); 4487252726Srpaulo os_free(hfile); 4488252726Srpaulo eloop_cancel_timeout(wpa_cli_ping, NULL, NULL); 4489252726Srpaulo wpa_cli_close_connection(); 4490252726Srpaulo} 4491252726Srpaulo 4492252726Srpaulo 4493289549Srpaulostatic void wpa_cli_action_ping(void *eloop_ctx, void *timeout_ctx) 4494289549Srpaulo{ 4495289549Srpaulo struct wpa_ctrl *ctrl = eloop_ctx; 4496289549Srpaulo char buf[256]; 4497289549Srpaulo size_t len; 4498289549Srpaulo 4499289549Srpaulo /* verify that connection is still working */ 4500289549Srpaulo len = sizeof(buf) - 1; 4501289549Srpaulo if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len, 4502289549Srpaulo wpa_cli_action_cb) < 0 || 4503289549Srpaulo len < 4 || os_memcmp(buf, "PONG", 4) != 0) { 4504289549Srpaulo printf("wpa_supplicant did not reply to PING command - exiting\n"); 4505289549Srpaulo eloop_terminate(); 4506289549Srpaulo return; 4507289549Srpaulo } 4508289549Srpaulo eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping, 4509289549Srpaulo ctrl, NULL); 4510289549Srpaulo} 4511289549Srpaulo 4512289549Srpaulo 4513289549Srpaulostatic void wpa_cli_action_receive(int sock, void *eloop_ctx, void *sock_ctx) 4514289549Srpaulo{ 4515289549Srpaulo struct wpa_ctrl *ctrl = eloop_ctx; 4516289549Srpaulo 4517289549Srpaulo wpa_cli_recv_pending(ctrl, 1); 4518289549Srpaulo} 4519289549Srpaulo 4520289549Srpaulo 4521189251Ssamstatic void wpa_cli_action(struct wpa_ctrl *ctrl) 4522189251Ssam{ 4523189251Ssam#ifdef CONFIG_ANSI_C_EXTRA 4524189251Ssam /* TODO: ANSI C version(?) */ 4525189251Ssam printf("Action processing not supported in ANSI C build.\n"); 4526189251Ssam#else /* CONFIG_ANSI_C_EXTRA */ 4527289549Srpaulo int fd; 4528189251Ssam 4529189251Ssam fd = wpa_ctrl_get_fd(ctrl); 4530289549Srpaulo eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping, 4531289549Srpaulo ctrl, NULL); 4532289549Srpaulo eloop_register_read_sock(fd, wpa_cli_action_receive, ctrl, NULL); 4533289549Srpaulo eloop_run(); 4534289549Srpaulo eloop_cancel_timeout(wpa_cli_action_ping, ctrl, NULL); 4535289549Srpaulo eloop_unregister_read_sock(fd); 4536189251Ssam#endif /* CONFIG_ANSI_C_EXTRA */ 4537189251Ssam} 4538189251Ssam 4539189251Ssam 4540189251Ssamstatic void wpa_cli_cleanup(void) 4541189251Ssam{ 4542189251Ssam wpa_cli_close_connection(); 4543189251Ssam if (pid_file) 4544189251Ssam os_daemonize_terminate(pid_file); 4545189251Ssam 4546189251Ssam os_program_deinit(); 4547189251Ssam} 4548189251Ssam 4549189251Ssam 4550252726Srpaulostatic void wpa_cli_terminate(int sig, void *ctx) 4551214734Srpaulo{ 4552252726Srpaulo eloop_terminate(); 4553214734Srpaulo} 4554214734Srpaulo 4555214734Srpaulo 4556189251Ssamstatic char * wpa_cli_get_default_ifname(void) 4557189251Ssam{ 4558189251Ssam char *ifname = NULL; 4559189251Ssam 4560289549Srpaulo#ifdef ANDROID 4561289549Srpaulo char ifprop[PROPERTY_VALUE_MAX]; 4562289549Srpaulo if (property_get("wifi.interface", ifprop, NULL) != 0) { 4563289549Srpaulo ifname = os_strdup(ifprop); 4564289549Srpaulo printf("Using interface '%s'\n", ifname ? ifname : "N/A"); 4565289549Srpaulo } 4566289549Srpaulo#else /* ANDROID */ 4567189251Ssam#ifdef CONFIG_CTRL_IFACE_UNIX 4568189251Ssam struct dirent *dent; 4569189251Ssam DIR *dir = opendir(ctrl_iface_dir); 4570252726Srpaulo if (!dir) { 4571189251Ssam return NULL; 4572252726Srpaulo } 4573189251Ssam while ((dent = readdir(dir))) { 4574189251Ssam#ifdef _DIRENT_HAVE_D_TYPE 4575189251Ssam /* 4576189251Ssam * Skip the file if it is not a socket. Also accept 4577189251Ssam * DT_UNKNOWN (0) in case the C library or underlying 4578189251Ssam * file system does not support d_type. 4579189251Ssam */ 4580189251Ssam if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN) 4581189251Ssam continue; 4582189251Ssam#endif /* _DIRENT_HAVE_D_TYPE */ 4583189251Ssam if (os_strcmp(dent->d_name, ".") == 0 || 4584189251Ssam os_strcmp(dent->d_name, "..") == 0) 4585189251Ssam continue; 4586189251Ssam printf("Selected interface '%s'\n", dent->d_name); 4587189251Ssam ifname = os_strdup(dent->d_name); 4588189251Ssam break; 4589189251Ssam } 4590189251Ssam closedir(dir); 4591189251Ssam#endif /* CONFIG_CTRL_IFACE_UNIX */ 4592189251Ssam 4593189251Ssam#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 4594281806Srpaulo char buf[4096], *pos; 4595189251Ssam size_t len; 4596189251Ssam struct wpa_ctrl *ctrl; 4597189251Ssam int ret; 4598189251Ssam 4599189251Ssam ctrl = wpa_ctrl_open(NULL); 4600189251Ssam if (ctrl == NULL) 4601189251Ssam return NULL; 4602189251Ssam 4603189251Ssam len = sizeof(buf) - 1; 4604189251Ssam ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL); 4605189251Ssam if (ret >= 0) { 4606189251Ssam buf[len] = '\0'; 4607189251Ssam pos = os_strchr(buf, '\n'); 4608189251Ssam if (pos) 4609189251Ssam *pos = '\0'; 4610189251Ssam ifname = os_strdup(buf); 4611189251Ssam } 4612189251Ssam wpa_ctrl_close(ctrl); 4613189251Ssam#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 4614289549Srpaulo#endif /* ANDROID */ 4615189251Ssam 4616189251Ssam return ifname; 4617189251Ssam} 4618189251Ssam 4619189251Ssam 4620189251Ssamint main(int argc, char *argv[]) 4621189251Ssam{ 4622189251Ssam int c; 4623189251Ssam int daemonize = 0; 4624189251Ssam int ret = 0; 4625189251Ssam 4626189251Ssam if (os_program_init()) 4627189251Ssam return -1; 4628189251Ssam 4629189251Ssam for (;;) { 4630289549Srpaulo c = getopt(argc, argv, "a:Bg:G:hi:p:P:s:v"); 4631189251Ssam if (c < 0) 4632189251Ssam break; 4633189251Ssam switch (c) { 4634189251Ssam case 'a': 4635189251Ssam action_file = optarg; 4636189251Ssam break; 4637189251Ssam case 'B': 4638189251Ssam daemonize = 1; 4639189251Ssam break; 4640189251Ssam case 'g': 4641189251Ssam global = optarg; 4642189251Ssam break; 4643189251Ssam case 'G': 4644189251Ssam ping_interval = atoi(optarg); 4645189251Ssam break; 4646189251Ssam case 'h': 4647189251Ssam usage(); 4648189251Ssam return 0; 4649189251Ssam case 'v': 4650189251Ssam printf("%s\n", wpa_cli_version); 4651189251Ssam return 0; 4652189251Ssam case 'i': 4653189251Ssam os_free(ctrl_ifname); 4654189251Ssam ctrl_ifname = os_strdup(optarg); 4655189251Ssam break; 4656189251Ssam case 'p': 4657189251Ssam ctrl_iface_dir = optarg; 4658189251Ssam break; 4659189251Ssam case 'P': 4660189251Ssam pid_file = optarg; 4661189251Ssam break; 4662289549Srpaulo case 's': 4663289549Srpaulo client_socket_dir = optarg; 4664289549Srpaulo break; 4665189251Ssam default: 4666189251Ssam usage(); 4667189251Ssam return -1; 4668189251Ssam } 4669189251Ssam } 4670189251Ssam 4671189251Ssam interactive = (argc == optind) && (action_file == NULL); 4672189251Ssam 4673189251Ssam if (interactive) 4674337817Scy printf("%s\n\n%s\n\n", wpa_cli_version, cli_license); 4675189251Ssam 4676252726Srpaulo if (eloop_init()) 4677252726Srpaulo return -1; 4678252726Srpaulo 4679346981Scy if (global && wpa_cli_open_global_ctrl() < 0) 4680346981Scy return -1; 4681281806Srpaulo 4682252726Srpaulo eloop_register_signal_terminate(wpa_cli_terminate, NULL); 4683189251Ssam 4684214734Srpaulo if (ctrl_ifname == NULL) 4685214734Srpaulo ctrl_ifname = wpa_cli_get_default_ifname(); 4686214734Srpaulo 4687214734Srpaulo if (interactive) { 4688252726Srpaulo wpa_cli_interactive(); 4689214734Srpaulo } else { 4690214734Srpaulo if (!global && 4691214734Srpaulo wpa_cli_open_connection(ctrl_ifname, 0) < 0) { 4692252726Srpaulo fprintf(stderr, "Failed to connect to non-global " 4693252726Srpaulo "ctrl_ifname: %s error: %s\n", 4694281806Srpaulo ctrl_ifname ? ctrl_ifname : "(nil)", 4695281806Srpaulo strerror(errno)); 4696214734Srpaulo return -1; 4697214734Srpaulo } 4698214734Srpaulo 4699214734Srpaulo if (action_file) { 4700214734Srpaulo if (wpa_ctrl_attach(ctrl_conn) == 0) { 4701214734Srpaulo wpa_cli_attached = 1; 4702214734Srpaulo } else { 4703214734Srpaulo printf("Warning: Failed to attach to " 4704214734Srpaulo "wpa_supplicant.\n"); 4705189251Ssam return -1; 4706214734Srpaulo } 4707189251Ssam } 4708189251Ssam 4709337817Scy if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue()) 4710252726Srpaulo return -1; 4711189251Ssam 4712252726Srpaulo if (action_file) 4713252726Srpaulo wpa_cli_action(ctrl_conn); 4714252726Srpaulo else 4715252726Srpaulo ret = wpa_request(ctrl_conn, argc - optind, 4716252726Srpaulo &argv[optind]); 4717252726Srpaulo } 4718189251Ssam 4719189251Ssam os_free(ctrl_ifname); 4720252726Srpaulo eloop_destroy(); 4721189251Ssam wpa_cli_cleanup(); 4722189251Ssam 4723189251Ssam return ret; 4724189251Ssam} 4725189251Ssam 4726189251Ssam#else /* CONFIG_CTRL_IFACE */ 4727189251Ssamint main(int argc, char *argv[]) 4728189251Ssam{ 4729189251Ssam printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n"); 4730189251Ssam return -1; 4731189251Ssam} 4732189251Ssam#endif /* CONFIG_CTRL_IFACE */ 4733