1/* 2 * WPA Supplicant - command line interface for wpa_supplicant daemon 3 * Copyright (c) 2004-2017, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9#include "includes.h" 10 11#ifdef CONFIG_CTRL_IFACE 12 13#ifdef CONFIG_CTRL_IFACE_UNIX 14#include <dirent.h> 15#endif /* CONFIG_CTRL_IFACE_UNIX */ 16 17#include "common/cli.h" 18#include "common/wpa_ctrl.h" 19#include "utils/common.h" 20#include "utils/eloop.h" 21#include "utils/edit.h" 22#include "utils/list.h" 23#include "common/version.h" 24#include "common/ieee802_11_defs.h" 25#ifdef ANDROID 26#include <cutils/properties.h> 27#endif /* ANDROID */ 28 29 30static const char *const wpa_cli_version = 31"wpa_cli v" VERSION_STR "\n" 32"Copyright (c) 2004-2017, Jouni Malinen <j@w1.fi> and contributors"; 33 34#define VENDOR_ELEM_FRAME_ID \ 35 " 0: Probe Req (P2P), 1: Probe Resp (P2P) , 2: Probe Resp (GO), " \ 36 "3: Beacon (GO), 4: PD Req, 5: PD Resp, 6: GO Neg Req, " \ 37 "7: GO Neg Resp, 8: GO Neg Conf, 9: Inv Req, 10: Inv Resp, " \ 38 "11: Assoc Req (P2P), 12: Assoc Resp (P2P)" 39 40static struct wpa_ctrl *ctrl_conn; 41static struct wpa_ctrl *mon_conn; 42static int wpa_cli_quit = 0; 43static int wpa_cli_attached = 0; 44static int wpa_cli_connected = -1; 45static int wpa_cli_last_id = 0; 46#ifndef CONFIG_CTRL_IFACE_DIR 47#define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant" 48#endif /* CONFIG_CTRL_IFACE_DIR */ 49static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR; 50static const char *client_socket_dir = NULL; 51static char *ctrl_ifname = NULL; 52static const char *pid_file = NULL; 53static const char *action_file = NULL; 54static int ping_interval = 5; 55static int interactive = 0; 56static char *ifname_prefix = NULL; 57 58static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */ 59static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */ 60static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */ 61static DEFINE_DL_LIST(ifnames); /* struct cli_txt_entry */ 62static DEFINE_DL_LIST(networks); /* struct cli_txt_entry */ 63#ifdef CONFIG_AP 64static DEFINE_DL_LIST(stations); /* struct cli_txt_entry */ 65#endif /* CONFIG_AP */ 66 67 68static void print_help(const char *cmd); 69static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx); 70static void wpa_cli_close_connection(void); 71static char * wpa_cli_get_default_ifname(void); 72static char ** wpa_list_cmd_list(void); 73static void update_networks(struct wpa_ctrl *ctrl); 74static void update_stations(struct wpa_ctrl *ctrl); 75 76 77static void usage(void) 78{ 79 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] " 80 "[-a<action file>] \\\n" 81 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] " 82 "\\\n" 83 " [-s<wpa_client_socket_file_path>] " 84 "[command..]\n" 85 " -h = help (show this usage text)\n" 86 " -v = shown version information\n" 87 " -a = run in daemon mode executing the action file based on " 88 "events from\n" 89 " wpa_supplicant\n" 90 " -B = run a daemon in the background\n" 91 " default path: " CONFIG_CTRL_IFACE_DIR "\n" 92 " default interface: first interface found in socket path\n"); 93 print_help(NULL); 94} 95 96 97static int wpa_cli_show_event(const char *event) 98{ 99 const char *start; 100 101 start = os_strchr(event, '>'); 102 if (start == NULL) 103 return 1; 104 105 start++; 106 /* 107 * Skip BSS added/removed events since they can be relatively frequent 108 * and are likely of not much use for an interactive user. 109 */ 110 if (str_starts(start, WPA_EVENT_BSS_ADDED) || 111 str_starts(start, WPA_EVENT_BSS_REMOVED)) 112 return 0; 113 114 return 1; 115} 116 117 118static int wpa_cli_open_connection(const char *ifname, int attach) 119{ 120#if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE) 121 ctrl_conn = wpa_ctrl_open(ifname); 122 if (ctrl_conn == NULL) 123 return -1; 124 125 if (attach && interactive) 126 mon_conn = wpa_ctrl_open(ifname); 127 else 128 mon_conn = NULL; 129#else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ 130 char *cfile = NULL; 131 int flen, res; 132 133 if (ifname == NULL) 134 return -1; 135 136#ifdef ANDROID 137 if (access(ctrl_iface_dir, F_OK) < 0) { 138 cfile = os_strdup(ifname); 139 if (cfile == NULL) 140 return -1; 141 } 142#endif /* ANDROID */ 143 144 if (client_socket_dir && client_socket_dir[0] && 145 access(client_socket_dir, F_OK) < 0) { 146 perror(client_socket_dir); 147 os_free(cfile); 148 return -1; 149 } 150 151 if (cfile == NULL) { 152 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2; 153 cfile = os_malloc(flen); 154 if (cfile == NULL) 155 return -1; 156 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, 157 ifname); 158 if (os_snprintf_error(flen, res)) { 159 os_free(cfile); 160 return -1; 161 } 162 } 163 164 ctrl_conn = wpa_ctrl_open2(cfile, client_socket_dir); 165 if (ctrl_conn == NULL) { 166 os_free(cfile); 167 return -1; 168 } 169 170 if (attach && interactive) 171 mon_conn = wpa_ctrl_open2(cfile, client_socket_dir); 172 else 173 mon_conn = NULL; 174 os_free(cfile); 175#endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ 176 177 if (mon_conn) { 178 if (wpa_ctrl_attach(mon_conn) == 0) { 179 wpa_cli_attached = 1; 180 if (interactive) 181 eloop_register_read_sock( 182 wpa_ctrl_get_fd(mon_conn), 183 wpa_cli_mon_receive, NULL, NULL); 184 } else { 185 printf("Warning: Failed to attach to " 186 "wpa_supplicant.\n"); 187 wpa_cli_close_connection(); 188 return -1; 189 } 190 } 191 192 return 0; 193} 194 195 196static void wpa_cli_close_connection(void) 197{ 198 if (ctrl_conn == NULL) 199 return; 200 201 if (wpa_cli_attached) { 202 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn); 203 wpa_cli_attached = 0; 204 } 205 wpa_ctrl_close(ctrl_conn); 206 ctrl_conn = NULL; 207 if (mon_conn) { 208 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn)); 209 wpa_ctrl_close(mon_conn); 210 mon_conn = NULL; 211 } 212} 213 214 215static void wpa_cli_msg_cb(char *msg, size_t len) 216{ 217 printf("%s\n", msg); 218} 219 220 221static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd, int print) 222{ 223 char buf[4096]; 224 size_t len; 225 int ret; 226 227 if (ctrl_conn == NULL) { 228 printf("Not connected to wpa_supplicant - command dropped.\n"); 229 return -1; 230 } 231 if (ifname_prefix) { 232 os_snprintf(buf, sizeof(buf), "IFNAME=%s %s", 233 ifname_prefix, cmd); 234 buf[sizeof(buf) - 1] = '\0'; 235 cmd = buf; 236 } 237 len = sizeof(buf) - 1; 238 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 239 wpa_cli_msg_cb); 240 if (ret == -2) { 241 printf("'%s' command timed out.\n", cmd); 242 return -2; 243 } else if (ret < 0) { 244 printf("'%s' command failed.\n", cmd); 245 return -1; 246 } 247 if (print) { 248 buf[len] = '\0'; 249 printf("%s", buf); 250 if (interactive && len > 0 && buf[len - 1] != '\n') 251 printf("\n"); 252 } 253 return 0; 254} 255 256 257static int wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd) 258{ 259 return _wpa_ctrl_command(ctrl, cmd, 1); 260} 261 262 263static int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args, 264 int argc, char *argv[]) 265{ 266 char buf[4096]; 267 if (argc < min_args) { 268 printf("Invalid %s command - at least %d argument%s " 269 "required.\n", cmd, min_args, 270 min_args > 1 ? "s are" : " is"); 271 return -1; 272 } 273 if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0) 274 return -1; 275 return wpa_ctrl_command(ctrl, buf); 276} 277 278 279static int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[]) 280{ 281 return wpa_ctrl_command(ctrl, "IFNAME"); 282} 283 284 285static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[]) 286{ 287 if (argc > 0 && os_strcmp(argv[0], "verbose") == 0) 288 return wpa_ctrl_command(ctrl, "STATUS-VERBOSE"); 289 if (argc > 0 && os_strcmp(argv[0], "wps") == 0) 290 return wpa_ctrl_command(ctrl, "STATUS-WPS"); 291 if (argc > 0 && os_strcmp(argv[0], "driver") == 0) 292 return wpa_ctrl_command(ctrl, "STATUS-DRIVER"); 293#ifdef ANDROID 294 if (argc > 0 && os_strcmp(argv[0], "no_events") == 0) 295 return wpa_ctrl_command(ctrl, "STATUS-NO_EVENTS"); 296#endif /* ANDROID */ 297 return wpa_ctrl_command(ctrl, "STATUS"); 298} 299 300 301static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[]) 302{ 303 return wpa_ctrl_command(ctrl, "PING"); 304} 305 306 307static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[]) 308{ 309 return wpa_ctrl_command(ctrl, "RELOG"); 310} 311 312 313static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[]) 314{ 315 return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv); 316} 317 318 319static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[]) 320{ 321 return wpa_ctrl_command(ctrl, "MIB"); 322} 323 324 325static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[]) 326{ 327 return wpa_ctrl_command(ctrl, "PMKSA"); 328} 329 330 331static int wpa_cli_cmd_pmksa_flush(struct wpa_ctrl *ctrl, int argc, 332 char *argv[]) 333{ 334 return wpa_ctrl_command(ctrl, "PMKSA_FLUSH"); 335} 336 337 338#ifdef CONFIG_PMKSA_CACHE_EXTERNAL 339 340static int wpa_cli_cmd_pmksa_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) 341{ 342 return wpa_cli_cmd(ctrl, "PMKSA_GET", 1, argc, argv); 343} 344 345 346static int wpa_cli_cmd_pmksa_add(struct wpa_ctrl *ctrl, int argc, char *argv[]) 347{ 348 return wpa_cli_cmd(ctrl, "PMKSA_ADD", 8, argc, argv); 349} 350 351 352#ifdef CONFIG_MESH 353 354static int wpa_cli_mesh_cmd_pmksa_get(struct wpa_ctrl *ctrl, int argc, 355 char *argv[]) 356{ 357 return wpa_cli_cmd(ctrl, "MESH_PMKSA_GET", 1, argc, argv); 358} 359 360 361static int wpa_cli_mesh_cmd_pmksa_add(struct wpa_ctrl *ctrl, int argc, 362 char *argv[]) 363{ 364 return wpa_cli_cmd(ctrl, "MESH_PMKSA_ADD", 4, argc, argv); 365} 366 367#endif /* CONFIG_MESH */ 368#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */ 369 370 371static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[]) 372{ 373 print_help(argc > 0 ? argv[0] : NULL); 374 return 0; 375} 376 377 378static char ** wpa_cli_complete_help(const char *str, int pos) 379{ 380 int arg = get_cmd_arg_num(str, pos); 381 char **res = NULL; 382 383 switch (arg) { 384 case 1: 385 res = wpa_list_cmd_list(); 386 break; 387 } 388 389 return res; 390} 391 392 393static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[]) 394{ 395 printf("%s\n\n%s\n", wpa_cli_version, cli_full_license); 396 return 0; 397} 398 399 400static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[]) 401{ 402 wpa_cli_quit = 1; 403 if (interactive) 404 eloop_terminate(); 405 return 0; 406} 407 408 409static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) 410{ 411 char cmd[256]; 412 int res; 413 414 if (argc == 1) { 415 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]); 416 if (os_snprintf_error(sizeof(cmd), res)) { 417 printf("Too long SET command.\n"); 418 return -1; 419 } 420 return wpa_ctrl_command(ctrl, cmd); 421 } 422 423 return wpa_cli_cmd(ctrl, "SET", 2, argc, argv); 424} 425 426 427static char ** wpa_cli_complete_set(const char *str, int pos) 428{ 429 int arg = get_cmd_arg_num(str, pos); 430 const char *fields[] = { 431 /* runtime values */ 432 "EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod", 433 "EAPOL::maxStart", "dot11RSNAConfigPMKLifetime", 434 "dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout", 435 "wps_fragment_size", "wps_version_number", "ampdu", 436 "tdls_testing", "tdls_disabled", "pno", "radio_disabled", 437 "uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps", 438 "no_keep_alive", 439 /* global configuration parameters */ 440#ifdef CONFIG_CTRL_IFACE 441 "ctrl_interface", "no_ctrl_interface", "ctrl_interface_group", 442#endif /* CONFIG_CTRL_IFACE */ 443 "eapol_version", "ap_scan", "bgscan", 444#ifdef CONFIG_MESH 445 "user_mpm", "max_peer_links", "mesh_max_inactivity", 446 "dot11RSNASAERetransPeriod", 447#endif /* CONFIG_MESH */ 448 "disable_scan_offload", "fast_reauth", "opensc_engine_path", 449 "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers", 450 "pcsc_reader", "pcsc_pin", "external_sim", "driver_param", 451 "dot11RSNAConfigPMKLifetime", 452 "dot11RSNAConfigPMKReauthThreshold", 453 "dot11RSNAConfigSATimeout", 454#ifndef CONFIG_NO_CONFIG_WRITE 455 "update_config", 456#endif /* CONFIG_NO_CONFIG_WRITE */ 457 "load_dynamic_eap", 458#ifdef CONFIG_WPS 459 "uuid", "device_name", "manufacturer", "model_name", 460 "model_number", "serial_number", "device_type", "os_version", 461 "config_methods", "wps_cred_processing", "wps_vendor_ext_m1", 462#endif /* CONFIG_WPS */ 463#ifdef CONFIG_P2P 464 "sec_device_type", 465 "p2p_listen_reg_class", "p2p_listen_channel", 466 "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent", 467 "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss", 468 "p2p_group_idle", "p2p_passphrase_len", "p2p_pref_chan", 469 "p2p_no_go_freq", "p2p_add_cli_chan", 470 "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht", 471 "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface", 472 "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask", 473 "ip_addr_start", "ip_addr_end", 474#endif /* CONFIG_P2P */ 475 "country", "bss_max_count", "bss_expiration_age", 476 "bss_expiration_scan_count", "filter_ssids", "filter_rssi", 477 "max_num_sta", "disassoc_low_ack", 478#ifdef CONFIG_HS20 479 "hs20", 480#endif /* CONFIG_HS20 */ 481 "interworking", "hessid", "access_network_type", "pbc_in_m1", 482 "go_interworking", "go_access_network_type", "go_internet", 483 "go_venue_group", "go_venue_type", 484 "autoscan", "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey", 485 "wps_nfc_dh_privkey", "wps_nfc_dev_pw", "ext_password_backend", 486 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf", 487 "sae_groups", "dtim_period", "beacon_int", 488 "ap_vendor_elements", "ignore_old_scan_res", "freq_list", 489 "scan_cur_freq", "sched_scan_interval", 490 "tdls_external_control", "osu_dir", "wowlan_triggers", 491 "p2p_search_delay", "mac_addr", "rand_addr_lifetime", 492 "preassoc_mac_addr", "key_mgmt_offload", "passive_scan", 493 "reassoc_same_bss_optim", "wps_priority", 494#ifdef CONFIG_TESTING_OPTIONS 495 "ignore_auth_resp", 496#endif /* CONFIG_TESTING_OPTIONS */ 497 "relative_rssi", "relative_band_adjust", 498 }; 499 int i, num_fields = ARRAY_SIZE(fields); 500 501 if (arg == 1) { 502 char **res = os_calloc(num_fields + 1, sizeof(char *)); 503 if (res == NULL) 504 return NULL; 505 for (i = 0; i < num_fields; i++) { 506 res[i] = os_strdup(fields[i]); 507 if (res[i] == NULL) 508 return res; 509 } 510 return res; 511 } 512 513 if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0) 514 return cli_txt_list_array(&bsses); 515 516 return NULL; 517} 518 519static int wpa_cli_cmd_dump(struct wpa_ctrl *ctrl, int argc, char *argv[]) 520{ 521 return wpa_ctrl_command(ctrl, "DUMP"); 522} 523 524 525static int wpa_cli_cmd_driver_flags(struct wpa_ctrl *ctrl, int argc, 526 char *argv[]) 527{ 528 return wpa_ctrl_command(ctrl, "DRIVER_FLAGS"); 529} 530 531 532static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) 533{ 534 return wpa_cli_cmd(ctrl, "GET", 1, argc, argv); 535} 536 537 538static char ** wpa_cli_complete_get(const char *str, int pos) 539{ 540 int arg = get_cmd_arg_num(str, pos); 541 const char *fields[] = { 542#ifdef CONFIG_CTRL_IFACE 543 "ctrl_interface", "ctrl_interface_group", 544#endif /* CONFIG_CTRL_IFACE */ 545 "eapol_version", "ap_scan", 546#ifdef CONFIG_MESH 547 "user_mpm", "max_peer_links", "mesh_max_inactivity", 548#endif /* CONFIG_MESH */ 549 "disable_scan_offload", "fast_reauth", "opensc_engine_path", 550 "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers", 551 "pcsc_reader", "pcsc_pin", "external_sim", "driver_param", 552 "dot11RSNAConfigPMKLifetime", 553 "dot11RSNAConfigPMKReauthThreshold", 554 "dot11RSNAConfigSATimeout", 555#ifndef CONFIG_NO_CONFIG_WRITE 556 "update_config", 557#endif /* CONFIG_NO_CONFIG_WRITE */ 558#ifdef CONFIG_WPS 559 "device_name", "manufacturer", "model_name", "model_number", 560 "serial_number", "config_methods", "wps_cred_processing", 561#endif /* CONFIG_WPS */ 562#ifdef CONFIG_P2P 563 "p2p_listen_reg_class", "p2p_listen_channel", 564 "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent", 565 "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss", 566 "p2p_group_idle", "p2p_passphrase_len", "p2p_add_cli_chan", 567 "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht", 568 "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface", 569 "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask", 570 "ip_addr_start", "ip_addr_end", 571#endif /* CONFIG_P2P */ 572 "bss_max_count", "bss_expiration_age", 573 "bss_expiration_scan_count", "filter_ssids", "filter_rssi", 574 "max_num_sta", "disassoc_low_ack", 575#ifdef CONFIG_HS20 576 "hs20", 577#endif /* CONFIG_HS20 */ 578 "interworking", "access_network_type", "pbc_in_m1", "autoscan", 579 "go_interworking", "go_access_network_type", "go_internet", 580 "go_venue_group", "go_venue_type", 581 "wps_nfc_dev_pw_id", "ext_password_backend", 582 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf", 583 "dtim_period", "beacon_int", "ignore_old_scan_res", 584 "scan_cur_freq", "sched_scan_interval", 585 "sched_scan_start_delay", 586 "tdls_external_control", "osu_dir", "wowlan_triggers", 587 "p2p_search_delay", "mac_addr", "rand_addr_lifetime", 588 "preassoc_mac_addr", "key_mgmt_offload", "passive_scan", 589 "reassoc_same_bss_optim" 590 }; 591 int i, num_fields = ARRAY_SIZE(fields); 592 593 if (arg == 1) { 594 char **res = os_calloc(num_fields + 1, sizeof(char *)); 595 if (res == NULL) 596 return NULL; 597 for (i = 0; i < num_fields; i++) { 598 res[i] = os_strdup(fields[i]); 599 if (res[i] == NULL) 600 return res; 601 } 602 return res; 603 } 604 605 return NULL; 606} 607 608 609static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[]) 610{ 611 return wpa_ctrl_command(ctrl, "LOGOFF"); 612} 613 614 615static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[]) 616{ 617 return wpa_ctrl_command(ctrl, "LOGON"); 618} 619 620 621static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc, 622 char *argv[]) 623{ 624 return wpa_ctrl_command(ctrl, "REASSOCIATE"); 625} 626 627 628static int wpa_cli_cmd_reattach(struct wpa_ctrl *ctrl, int argc, char *argv[]) 629{ 630 return wpa_ctrl_command(ctrl, "REATTACH"); 631} 632 633 634static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc, 635 char *argv[]) 636{ 637 return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv); 638} 639 640 641static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 642{ 643 return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv); 644} 645 646 647static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc, 648 char *argv[]) 649{ 650 return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv); 651} 652 653 654static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc, 655 char *argv[]) 656{ 657 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv); 658} 659 660 661static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc, 662 char *argv[]) 663{ 664 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv); 665} 666 667 668static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 669{ 670 char cmd[256]; 671 int res; 672 673 if (argc < 1) 674 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0"); 675 else 676 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]); 677 if (os_snprintf_error(sizeof(cmd), res)) { 678 printf("Too long BSS_FLUSH command.\n"); 679 return -1; 680 } 681 return wpa_ctrl_command(ctrl, cmd); 682} 683 684 685static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[]) 686{ 687 return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv); 688} 689 690 691static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[]) 692{ 693 return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv); 694} 695 696 697static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) 698{ 699 if (argc == 0) { 700 printf("Invalid WPS_PIN command: need one or two arguments:\n" 701 "- BSSID: use 'any' to select any\n" 702 "- PIN: optional, used only with devices that have no " 703 "display\n"); 704 return -1; 705 } 706 707 return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv); 708} 709 710 711static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc, 712 char *argv[]) 713{ 714 return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv); 715} 716 717 718static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc, 719 char *argv[]) 720{ 721 return wpa_ctrl_command(ctrl, "WPS_CANCEL"); 722} 723 724 725#ifdef CONFIG_WPS_NFC 726 727static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[]) 728{ 729 return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv); 730} 731 732 733static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc, 734 char *argv[]) 735{ 736 return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv); 737} 738 739 740static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc, 741 char *argv[]) 742{ 743 return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv); 744} 745 746 747static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc, 748 char *argv[]) 749{ 750 int ret; 751 char *buf; 752 size_t buflen; 753 754 if (argc != 1) { 755 printf("Invalid 'wps_nfc_tag_read' command - one argument " 756 "is required.\n"); 757 return -1; 758 } 759 760 buflen = 18 + os_strlen(argv[0]); 761 buf = os_malloc(buflen); 762 if (buf == NULL) 763 return -1; 764 os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]); 765 766 ret = wpa_ctrl_command(ctrl, buf); 767 os_free(buf); 768 769 return ret; 770} 771 772 773static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc, 774 char *argv[]) 775{ 776 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv); 777} 778 779 780static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc, 781 char *argv[]) 782{ 783 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv); 784} 785 786 787static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc, 788 char *argv[]) 789{ 790 return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv); 791} 792 793#endif /* CONFIG_WPS_NFC */ 794 795 796static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[]) 797{ 798 char cmd[256]; 799 int res; 800 801 if (argc == 2) 802 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s", 803 argv[0], argv[1]); 804 else if (argc == 5 || argc == 6) { 805 char ssid_hex[2 * SSID_MAX_LEN + 1]; 806 char key_hex[2 * 64 + 1]; 807 int i; 808 809 ssid_hex[0] = '\0'; 810 for (i = 0; i < SSID_MAX_LEN; i++) { 811 if (argv[2][i] == '\0') 812 break; 813 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]); 814 } 815 816 key_hex[0] = '\0'; 817 if (argc == 6) { 818 for (i = 0; i < 64; i++) { 819 if (argv[5][i] == '\0') 820 break; 821 os_snprintf(&key_hex[i * 2], 3, "%02x", 822 argv[5][i]); 823 } 824 } 825 826 res = os_snprintf(cmd, sizeof(cmd), 827 "WPS_REG %s %s %s %s %s %s", 828 argv[0], argv[1], ssid_hex, argv[3], argv[4], 829 key_hex); 830 } else { 831 printf("Invalid WPS_REG command: need two arguments:\n" 832 "- BSSID of the target AP\n" 833 "- AP PIN\n"); 834 printf("Alternatively, six arguments can be used to " 835 "reconfigure the AP:\n" 836 "- BSSID of the target AP\n" 837 "- AP PIN\n" 838 "- new SSID\n" 839 "- new auth (OPEN, WPAPSK, WPA2PSK)\n" 840 "- new encr (NONE, WEP, TKIP, CCMP)\n" 841 "- new key\n"); 842 return -1; 843 } 844 845 if (os_snprintf_error(sizeof(cmd), res)) { 846 printf("Too long WPS_REG command.\n"); 847 return -1; 848 } 849 return wpa_ctrl_command(ctrl, cmd); 850} 851 852 853static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc, 854 char *argv[]) 855{ 856 return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv); 857} 858 859 860static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc, 861 char *argv[]) 862{ 863 return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv); 864} 865 866 867static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc, 868 char *argv[]) 869{ 870 return wpa_ctrl_command(ctrl, "WPS_ER_STOP"); 871 872} 873 874 875static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc, 876 char *argv[]) 877{ 878 if (argc < 2) { 879 printf("Invalid WPS_ER_PIN command: need at least two " 880 "arguments:\n" 881 "- UUID: use 'any' to select any\n" 882 "- PIN: Enrollee PIN\n" 883 "optional: - Enrollee MAC address\n"); 884 return -1; 885 } 886 887 return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv); 888} 889 890 891static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc, 892 char *argv[]) 893{ 894 return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv); 895} 896 897 898static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc, 899 char *argv[]) 900{ 901 if (argc != 2) { 902 printf("Invalid WPS_ER_LEARN command: need two arguments:\n" 903 "- UUID: specify which AP to use\n" 904 "- PIN: AP PIN\n"); 905 return -1; 906 } 907 908 return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv); 909} 910 911 912static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc, 913 char *argv[]) 914{ 915 if (argc != 2) { 916 printf("Invalid WPS_ER_SET_CONFIG command: need two " 917 "arguments:\n" 918 "- UUID: specify which AP to use\n" 919 "- Network configuration id\n"); 920 return -1; 921 } 922 923 return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv); 924} 925 926 927static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc, 928 char *argv[]) 929{ 930 char cmd[256]; 931 int res; 932 933 if (argc == 5 || argc == 6) { 934 char ssid_hex[2 * SSID_MAX_LEN + 1]; 935 char key_hex[2 * 64 + 1]; 936 int i; 937 938 ssid_hex[0] = '\0'; 939 for (i = 0; i < SSID_MAX_LEN; i++) { 940 if (argv[2][i] == '\0') 941 break; 942 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]); 943 } 944 945 key_hex[0] = '\0'; 946 if (argc == 6) { 947 for (i = 0; i < 64; i++) { 948 if (argv[5][i] == '\0') 949 break; 950 os_snprintf(&key_hex[i * 2], 3, "%02x", 951 argv[5][i]); 952 } 953 } 954 955 res = os_snprintf(cmd, sizeof(cmd), 956 "WPS_ER_CONFIG %s %s %s %s %s %s", 957 argv[0], argv[1], ssid_hex, argv[3], argv[4], 958 key_hex); 959 } else { 960 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n" 961 "- AP UUID\n" 962 "- AP PIN\n" 963 "- new SSID\n" 964 "- new auth (OPEN, WPAPSK, WPA2PSK)\n" 965 "- new encr (NONE, WEP, TKIP, CCMP)\n" 966 "- new key\n"); 967 return -1; 968 } 969 970 if (os_snprintf_error(sizeof(cmd), res)) { 971 printf("Too long WPS_ER_CONFIG command.\n"); 972 return -1; 973 } 974 return wpa_ctrl_command(ctrl, cmd); 975} 976 977 978#ifdef CONFIG_WPS_NFC 979static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc, 980 char *argv[]) 981{ 982 if (argc != 2) { 983 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two " 984 "arguments:\n" 985 "- WPS/NDEF: token format\n" 986 "- UUID: specify which AP to use\n"); 987 return -1; 988 } 989 990 return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv); 991} 992#endif /* CONFIG_WPS_NFC */ 993 994 995static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[]) 996{ 997 return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv); 998} 999 1000 1001static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1002{ 1003 return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv); 1004} 1005 1006 1007static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1008{ 1009 char cmd[256], *pos, *end; 1010 int i, ret; 1011 1012 if (argc < 2) { 1013 printf("Invalid IDENTITY command: needs two arguments " 1014 "(network id and identity)\n"); 1015 return -1; 1016 } 1017 1018 end = cmd + sizeof(cmd); 1019 pos = cmd; 1020 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s", 1021 argv[0], argv[1]); 1022 if (os_snprintf_error(end - pos, ret)) { 1023 printf("Too long IDENTITY command.\n"); 1024 return -1; 1025 } 1026 pos += ret; 1027 for (i = 2; i < argc; i++) { 1028 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1029 if (os_snprintf_error(end - pos, ret)) { 1030 printf("Too long IDENTITY command.\n"); 1031 return -1; 1032 } 1033 pos += ret; 1034 } 1035 1036 return wpa_ctrl_command(ctrl, cmd); 1037} 1038 1039 1040static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1041{ 1042 char cmd[256], *pos, *end; 1043 int i, ret; 1044 1045 if (argc < 2) { 1046 printf("Invalid PASSWORD command: needs two arguments " 1047 "(network id and password)\n"); 1048 return -1; 1049 } 1050 1051 end = cmd + sizeof(cmd); 1052 pos = cmd; 1053 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s", 1054 argv[0], argv[1]); 1055 if (os_snprintf_error(end - pos, ret)) { 1056 printf("Too long PASSWORD command.\n"); 1057 return -1; 1058 } 1059 pos += ret; 1060 for (i = 2; i < argc; i++) { 1061 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1062 if (os_snprintf_error(end - pos, ret)) { 1063 printf("Too long PASSWORD command.\n"); 1064 return -1; 1065 } 1066 pos += ret; 1067 } 1068 1069 return wpa_ctrl_command(ctrl, cmd); 1070} 1071 1072 1073static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc, 1074 char *argv[]) 1075{ 1076 char cmd[256], *pos, *end; 1077 int i, ret; 1078 1079 if (argc < 2) { 1080 printf("Invalid NEW_PASSWORD command: needs two arguments " 1081 "(network id and password)\n"); 1082 return -1; 1083 } 1084 1085 end = cmd + sizeof(cmd); 1086 pos = cmd; 1087 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s", 1088 argv[0], argv[1]); 1089 if (os_snprintf_error(end - pos, ret)) { 1090 printf("Too long NEW_PASSWORD command.\n"); 1091 return -1; 1092 } 1093 pos += ret; 1094 for (i = 2; i < argc; i++) { 1095 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1096 if (os_snprintf_error(end - pos, ret)) { 1097 printf("Too long NEW_PASSWORD command.\n"); 1098 return -1; 1099 } 1100 pos += ret; 1101 } 1102 1103 return wpa_ctrl_command(ctrl, cmd); 1104} 1105 1106 1107static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1108{ 1109 char cmd[256], *pos, *end; 1110 int i, ret; 1111 1112 if (argc < 2) { 1113 printf("Invalid PIN command: needs two arguments " 1114 "(network id and pin)\n"); 1115 return -1; 1116 } 1117 1118 end = cmd + sizeof(cmd); 1119 pos = cmd; 1120 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s", 1121 argv[0], argv[1]); 1122 if (os_snprintf_error(end - pos, ret)) { 1123 printf("Too long PIN command.\n"); 1124 return -1; 1125 } 1126 pos += ret; 1127 for (i = 2; i < argc; i++) { 1128 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1129 if (os_snprintf_error(end - pos, ret)) { 1130 printf("Too long PIN command.\n"); 1131 return -1; 1132 } 1133 pos += ret; 1134 } 1135 return wpa_ctrl_command(ctrl, cmd); 1136} 1137 1138 1139static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1140{ 1141 char cmd[256], *pos, *end; 1142 int i, ret; 1143 1144 if (argc < 2) { 1145 printf("Invalid OTP command: needs two arguments (network " 1146 "id and password)\n"); 1147 return -1; 1148 } 1149 1150 end = cmd + sizeof(cmd); 1151 pos = cmd; 1152 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s", 1153 argv[0], argv[1]); 1154 if (os_snprintf_error(end - pos, ret)) { 1155 printf("Too long OTP command.\n"); 1156 return -1; 1157 } 1158 pos += ret; 1159 for (i = 2; i < argc; i++) { 1160 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1161 if (os_snprintf_error(end - pos, ret)) { 1162 printf("Too long OTP command.\n"); 1163 return -1; 1164 } 1165 pos += ret; 1166 } 1167 1168 return wpa_ctrl_command(ctrl, cmd); 1169} 1170 1171 1172static int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1173{ 1174 char cmd[256], *pos, *end; 1175 int i, ret; 1176 1177 if (argc < 2) { 1178 printf("Invalid SIM command: needs two arguments " 1179 "(network id and SIM operation response)\n"); 1180 return -1; 1181 } 1182 1183 end = cmd + sizeof(cmd); 1184 pos = cmd; 1185 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s", 1186 argv[0], argv[1]); 1187 if (os_snprintf_error(end - pos, ret)) { 1188 printf("Too long SIM command.\n"); 1189 return -1; 1190 } 1191 pos += ret; 1192 for (i = 2; i < argc; i++) { 1193 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1194 if (os_snprintf_error(end - pos, ret)) { 1195 printf("Too long SIM command.\n"); 1196 return -1; 1197 } 1198 pos += ret; 1199 } 1200 return wpa_ctrl_command(ctrl, cmd); 1201} 1202 1203 1204static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc, 1205 char *argv[]) 1206{ 1207 char cmd[256], *pos, *end; 1208 int i, ret; 1209 1210 if (argc < 2) { 1211 printf("Invalid PASSPHRASE command: needs two arguments " 1212 "(network id and passphrase)\n"); 1213 return -1; 1214 } 1215 1216 end = cmd + sizeof(cmd); 1217 pos = cmd; 1218 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s", 1219 argv[0], argv[1]); 1220 if (os_snprintf_error(end - pos, ret)) { 1221 printf("Too long PASSPHRASE command.\n"); 1222 return -1; 1223 } 1224 pos += ret; 1225 for (i = 2; i < argc; i++) { 1226 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 1227 if (os_snprintf_error(end - pos, ret)) { 1228 printf("Too long PASSPHRASE command.\n"); 1229 return -1; 1230 } 1231 pos += ret; 1232 } 1233 1234 return wpa_ctrl_command(ctrl, cmd); 1235} 1236 1237 1238static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1239{ 1240 if (argc < 2) { 1241 printf("Invalid BSSID command: needs two arguments (network " 1242 "id and BSSID)\n"); 1243 return -1; 1244 } 1245 1246 return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv); 1247} 1248 1249 1250static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1251{ 1252 return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv); 1253} 1254 1255 1256static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1257{ 1258 return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv); 1259} 1260 1261 1262static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc, 1263 char *argv[]) 1264{ 1265 return wpa_ctrl_command(ctrl, "LIST_NETWORKS"); 1266} 1267 1268 1269static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc, 1270 char *argv[]) 1271{ 1272 return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv); 1273} 1274 1275 1276static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc, 1277 char *argv[]) 1278{ 1279 return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv); 1280} 1281 1282 1283static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc, 1284 char *argv[]) 1285{ 1286 return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv); 1287} 1288 1289 1290static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc, 1291 char *argv[]) 1292{ 1293 int res = wpa_ctrl_command(ctrl, "ADD_NETWORK"); 1294 if (interactive) 1295 update_networks(ctrl); 1296 return res; 1297} 1298 1299 1300static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc, 1301 char *argv[]) 1302{ 1303 int res = wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv); 1304 if (interactive) 1305 update_networks(ctrl); 1306 return res; 1307} 1308 1309 1310static void wpa_cli_show_network_variables(void) 1311{ 1312 printf("set_network variables:\n" 1313 " ssid (network name, SSID)\n" 1314 " psk (WPA passphrase or pre-shared key)\n" 1315 " key_mgmt (key management protocol)\n" 1316 " identity (EAP identity)\n" 1317 " password (EAP password)\n" 1318 " ...\n" 1319 "\n" 1320 "Note: Values are entered in the same format as the " 1321 "configuration file is using,\n" 1322 "i.e., strings values need to be inside double quotation " 1323 "marks.\n" 1324 "For example: set_network 1 ssid \"network name\"\n" 1325 "\n" 1326 "Please see wpa_supplicant.conf documentation for full list " 1327 "of\navailable variables.\n"); 1328} 1329 1330 1331static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc, 1332 char *argv[]) 1333{ 1334 if (argc == 0) { 1335 wpa_cli_show_network_variables(); 1336 return 0; 1337 } 1338 1339 if (argc < 3) { 1340 printf("Invalid SET_NETWORK command: needs three arguments\n" 1341 "(network id, variable name, and value)\n"); 1342 return -1; 1343 } 1344 1345 return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv); 1346} 1347 1348 1349static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc, 1350 char *argv[]) 1351{ 1352 if (argc == 0) { 1353 wpa_cli_show_network_variables(); 1354 return 0; 1355 } 1356 1357 if (argc != 2) { 1358 printf("Invalid GET_NETWORK command: needs two arguments\n" 1359 "(network id and variable name)\n"); 1360 return -1; 1361 } 1362 1363 return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv); 1364} 1365 1366 1367static const char *network_fields[] = { 1368 "ssid", "scan_ssid", "bssid", "bssid_blacklist", 1369 "bssid_whitelist", "psk", "proto", "key_mgmt", 1370 "bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq", 1371 "freq_list", "max_oper_chwidth", "ht40", "vht", "vht_center_freq1", 1372 "vht_center_freq2", "ht", 1373#ifdef IEEE8021X_EAPOL 1374 "eap", "identity", "anonymous_identity", "password", "ca_cert", 1375 "ca_path", "client_cert", "private_key", "private_key_passwd", 1376 "dh_file", "subject_match", "altsubject_match", 1377 "domain_suffix_match", "domain_match", "ca_cert2", "ca_path2", 1378 "client_cert2", "private_key2", "private_key2_passwd", 1379 "dh_file2", "subject_match2", "altsubject_match2", 1380 "domain_suffix_match2", "domain_match2", "phase1", "phase2", 1381 "pcsc", "pin", "engine_id", "key_id", "cert_id", "ca_cert_id", 1382 "pin2", "engine2_id", "key2_id", "cert2_id", "ca_cert2_id", 1383 "engine", "engine2", "eapol_flags", "sim_num", 1384 "openssl_ciphers", "erp", 1385#endif /* IEEE8021X_EAPOL */ 1386 "wep_key0", "wep_key1", "wep_key2", "wep_key3", 1387 "wep_tx_keyidx", "priority", 1388#ifdef IEEE8021X_EAPOL 1389 "eap_workaround", "pac_file", "fragment_size", "ocsp", 1390#endif /* IEEE8021X_EAPOL */ 1391#ifdef CONFIG_MESH 1392 "mode", "no_auto_peer", "mesh_rssi_threshold", 1393#else /* CONFIG_MESH */ 1394 "mode", 1395#endif /* CONFIG_MESH */ 1396 "proactive_key_caching", "disabled", "id_str", 1397#ifdef CONFIG_IEEE80211W 1398 "ieee80211w", 1399#endif /* CONFIG_IEEE80211W */ 1400 "mixed_cell", "frequency", "fixed_freq", 1401#ifdef CONFIG_MESH 1402 "mesh_basic_rates", "dot11MeshMaxRetries", 1403 "dot11MeshRetryTimeout", "dot11MeshConfirmTimeout", 1404 "dot11MeshHoldingTimeout", 1405#endif /* CONFIG_MESH */ 1406 "wpa_ptk_rekey", "bgscan", "ignore_broadcast_ssid", 1407#ifdef CONFIG_P2P 1408 "go_p2p_dev_addr", "p2p_client_list", "psk_list", 1409#endif /* CONFIG_P2P */ 1410#ifdef CONFIG_HT_OVERRIDES 1411 "disable_ht", "disable_ht40", "disable_sgi", "disable_ldpc", 1412 "ht40_intolerant", "disable_max_amsdu", "ampdu_factor", 1413 "ampdu_density", "ht_mcs", 1414#endif /* CONFIG_HT_OVERRIDES */ 1415#ifdef CONFIG_VHT_OVERRIDES 1416 "disable_vht", "vht_capa", "vht_capa_mask", "vht_rx_mcs_nss_1", 1417 "vht_rx_mcs_nss_2", "vht_rx_mcs_nss_3", "vht_rx_mcs_nss_4", 1418 "vht_rx_mcs_nss_5", "vht_rx_mcs_nss_6", "vht_rx_mcs_nss_7", 1419 "vht_rx_mcs_nss_8", "vht_tx_mcs_nss_1", "vht_tx_mcs_nss_2", 1420 "vht_tx_mcs_nss_3", "vht_tx_mcs_nss_4", "vht_tx_mcs_nss_5", 1421 "vht_tx_mcs_nss_6", "vht_tx_mcs_nss_7", "vht_tx_mcs_nss_8", 1422#endif /* CONFIG_VHT_OVERRIDES */ 1423 "ap_max_inactivity", "dtim_period", "beacon_int", 1424#ifdef CONFIG_MACSEC 1425 "macsec_policy", 1426 "macsec_integ_only", 1427 "macsec_port", 1428 "mka_priority", 1429#endif /* CONFIG_MACSEC */ 1430#ifdef CONFIG_HS20 1431 "update_identifier", 1432#endif /* CONFIG_HS20 */ 1433 "mac_addr", "pbss", "wps_disabled" 1434}; 1435 1436 1437static char ** wpa_cli_complete_network(const char *str, int pos) 1438{ 1439 int arg = get_cmd_arg_num(str, pos); 1440 int i, num_fields = ARRAY_SIZE(network_fields); 1441 char **res = NULL; 1442 1443 switch (arg) { 1444 case 1: 1445 res = cli_txt_list_array(&networks); 1446 break; 1447 case 2: 1448 res = os_calloc(num_fields + 1, sizeof(char *)); 1449 if (res == NULL) 1450 return NULL; 1451 for (i = 0; i < num_fields; i++) { 1452 res[i] = os_strdup(network_fields[i]); 1453 if (res[i] == NULL) 1454 break; 1455 } 1456 } 1457 return res; 1458} 1459 1460 1461static char ** wpa_cli_complete_network_id(const char *str, int pos) 1462{ 1463 int arg = get_cmd_arg_num(str, pos); 1464 if (arg == 1) 1465 return cli_txt_list_array(&networks); 1466 return NULL; 1467} 1468 1469 1470static int wpa_cli_cmd_dup_network(struct wpa_ctrl *ctrl, int argc, 1471 char *argv[]) 1472{ 1473 if (argc == 0) { 1474 wpa_cli_show_network_variables(); 1475 return 0; 1476 } 1477 1478 if (argc < 3) { 1479 printf("Invalid DUP_NETWORK command: needs three arguments\n" 1480 "(src netid, dest netid, and variable name)\n"); 1481 return -1; 1482 } 1483 1484 return wpa_cli_cmd(ctrl, "DUP_NETWORK", 3, argc, argv); 1485} 1486 1487 1488static char ** wpa_cli_complete_dup_network(const char *str, int pos) 1489{ 1490 int arg = get_cmd_arg_num(str, pos); 1491 int i, num_fields = ARRAY_SIZE(network_fields); 1492 char **res = NULL; 1493 1494 switch (arg) { 1495 case 1: 1496 case 2: 1497 res = cli_txt_list_array(&networks); 1498 break; 1499 case 3: 1500 res = os_calloc(num_fields + 1, sizeof(char *)); 1501 if (res == NULL) 1502 return NULL; 1503 for (i = 0; i < num_fields; i++) { 1504 res[i] = os_strdup(network_fields[i]); 1505 if (res[i] == NULL) 1506 break; 1507 } 1508 } 1509 return res; 1510} 1511 1512 1513static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc, 1514 char *argv[]) 1515{ 1516 return wpa_ctrl_command(ctrl, "LIST_CREDS"); 1517} 1518 1519 1520static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1521{ 1522 return wpa_ctrl_command(ctrl, "ADD_CRED"); 1523} 1524 1525 1526static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc, 1527 char *argv[]) 1528{ 1529 return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv); 1530} 1531 1532 1533static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1534{ 1535 if (argc != 3) { 1536 printf("Invalid SET_CRED command: needs three arguments\n" 1537 "(cred id, variable name, and value)\n"); 1538 return -1; 1539 } 1540 1541 return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv); 1542} 1543 1544 1545static int wpa_cli_cmd_get_cred(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1546{ 1547 if (argc != 2) { 1548 printf("Invalid GET_CRED command: needs two arguments\n" 1549 "(cred id, variable name)\n"); 1550 return -1; 1551 } 1552 1553 return wpa_cli_cmd(ctrl, "GET_CRED", 2, argc, argv); 1554} 1555 1556 1557static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc, 1558 char *argv[]) 1559{ 1560 return wpa_ctrl_command(ctrl, "DISCONNECT"); 1561} 1562 1563 1564static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc, 1565 char *argv[]) 1566{ 1567 return wpa_ctrl_command(ctrl, "RECONNECT"); 1568} 1569 1570 1571static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc, 1572 char *argv[]) 1573{ 1574 return wpa_ctrl_command(ctrl, "SAVE_CONFIG"); 1575} 1576 1577 1578static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1579{ 1580 return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv); 1581} 1582 1583 1584static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc, 1585 char *argv[]) 1586{ 1587 return wpa_ctrl_command(ctrl, "SCAN_RESULTS"); 1588} 1589 1590 1591static int wpa_cli_cmd_abort_scan(struct wpa_ctrl *ctrl, int argc, 1592 char *argv[]) 1593{ 1594 return wpa_ctrl_command(ctrl, "ABORT_SCAN"); 1595} 1596 1597 1598static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1599{ 1600 return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv); 1601} 1602 1603 1604static char ** wpa_cli_complete_bss(const char *str, int pos) 1605{ 1606 int arg = get_cmd_arg_num(str, pos); 1607 char **res = NULL; 1608 1609 switch (arg) { 1610 case 1: 1611 res = cli_txt_list_array(&bsses); 1612 break; 1613 } 1614 1615 return res; 1616} 1617 1618 1619static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc, 1620 char *argv[]) 1621{ 1622 if (argc < 1 || argc > 2) { 1623 printf("Invalid GET_CAPABILITY command: need either one or " 1624 "two arguments\n"); 1625 return -1; 1626 } 1627 1628 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) { 1629 printf("Invalid GET_CAPABILITY command: second argument, " 1630 "if any, must be 'strict'\n"); 1631 return -1; 1632 } 1633 1634 return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv); 1635} 1636 1637 1638static char ** wpa_cli_complete_get_capability(const char *str, int pos) 1639{ 1640 int arg = get_cmd_arg_num(str, pos); 1641 const char *fields[] = { 1642 "eap", "pairwise", "group", "group_mgmt", "key_mgmt", 1643 "proto", "auth_alg", "modes", "channels", "freq", 1644#ifdef CONFIG_TDLS 1645 "tdls", 1646#endif /* CONFIG_TDLS */ 1647#ifdef CONFIG_ERP 1648 "erp", 1649#endif /* CONFIG_ERP */ 1650#ifdef CONFIG_FIPS 1651 "fips", 1652#endif /* CONFIG_FIPS */ 1653#ifdef CONFIG_ACS 1654 "acs", 1655#endif /* CONFIG_ACS */ 1656 }; 1657 int i, num_fields = ARRAY_SIZE(fields); 1658 char **res = NULL; 1659 1660 if (arg == 1) { 1661 res = os_calloc(num_fields + 1, sizeof(char *)); 1662 if (res == NULL) 1663 return NULL; 1664 for (i = 0; i < num_fields; i++) { 1665 res[i] = os_strdup(fields[i]); 1666 if (res[i] == NULL) 1667 return res; 1668 } 1669 } 1670 if (arg == 2) { 1671 res = os_calloc(1 + 1, sizeof(char *)); 1672 if (res == NULL) 1673 return NULL; 1674 res[0] = os_strdup("strict"); 1675 } 1676 return res; 1677} 1678 1679 1680static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl) 1681{ 1682 printf("Available interfaces:\n"); 1683 return wpa_ctrl_command(ctrl, "INTERFACES"); 1684} 1685 1686 1687static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1688{ 1689 if (argc < 1) { 1690 wpa_cli_list_interfaces(ctrl); 1691 return 0; 1692 } 1693 1694 wpa_cli_close_connection(); 1695 os_free(ctrl_ifname); 1696 ctrl_ifname = os_strdup(argv[0]); 1697 if (!ctrl_ifname) { 1698 printf("Failed to allocate memory\n"); 1699 return 0; 1700 } 1701 1702 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) { 1703 printf("Connected to interface '%s.\n", ctrl_ifname); 1704 } else { 1705 printf("Could not connect to interface '%s' - re-trying\n", 1706 ctrl_ifname); 1707 } 1708 return 0; 1709} 1710 1711 1712static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc, 1713 char *argv[]) 1714{ 1715 return wpa_ctrl_command(ctrl, "RECONFIGURE"); 1716} 1717 1718 1719static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc, 1720 char *argv[]) 1721{ 1722 return wpa_ctrl_command(ctrl, "TERMINATE"); 1723} 1724 1725 1726static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc, 1727 char *argv[]) 1728{ 1729 char cmd[256]; 1730 int res; 1731 1732 if (argc < 1) { 1733 printf("Invalid INTERFACE_ADD command: needs at least one " 1734 "argument (interface name)\n" 1735 "All arguments: ifname confname driver ctrl_interface " 1736 "driver_param bridge_name [create]\n"); 1737 return -1; 1738 } 1739 1740 /* 1741 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB 1742 * <driver_param>TAB<bridge_name>[TAB<create>[TAB<type>]] 1743 */ 1744 res = os_snprintf(cmd, sizeof(cmd), 1745 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s\t%s\t%s", 1746 argv[0], 1747 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "", 1748 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "", 1749 argc > 5 ? argv[5] : "", argc > 6 ? argv[6] : "", 1750 argc > 7 ? argv[7] : ""); 1751 if (os_snprintf_error(sizeof(cmd), res)) 1752 return -1; 1753 cmd[sizeof(cmd) - 1] = '\0'; 1754 return wpa_ctrl_command(ctrl, cmd); 1755} 1756 1757 1758static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc, 1759 char *argv[]) 1760{ 1761 return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv); 1762} 1763 1764 1765static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc, 1766 char *argv[]) 1767{ 1768 return wpa_ctrl_command(ctrl, "INTERFACE_LIST"); 1769} 1770 1771 1772#ifdef CONFIG_AP 1773static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1774{ 1775 return wpa_cli_cmd(ctrl, "STA", 1, argc, argv); 1776} 1777 1778 1779static char ** wpa_cli_complete_sta(const char *str, int pos) 1780{ 1781 int arg = get_cmd_arg_num(str, pos); 1782 char **res = NULL; 1783 1784 switch (arg) { 1785 case 1: 1786 res = cli_txt_list_array(&stations); 1787 break; 1788 } 1789 1790 return res; 1791} 1792 1793 1794static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, const char *cmd, 1795 char *addr, size_t addr_len, int print) 1796{ 1797 char buf[4096], *pos; 1798 size_t len; 1799 int ret; 1800 1801 if (ctrl_conn == NULL) { 1802 printf("Not connected to hostapd - command dropped.\n"); 1803 return -1; 1804 } 1805 if (ifname_prefix) { 1806 os_snprintf(buf, sizeof(buf), "IFNAME=%s %s", 1807 ifname_prefix, cmd); 1808 buf[sizeof(buf) - 1] = '\0'; 1809 cmd = buf; 1810 } 1811 len = sizeof(buf) - 1; 1812 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 1813 wpa_cli_msg_cb); 1814 if (ret == -2) { 1815 printf("'%s' command timed out.\n", cmd); 1816 return -2; 1817 } else if (ret < 0) { 1818 printf("'%s' command failed.\n", cmd); 1819 return -1; 1820 } 1821 1822 buf[len] = '\0'; 1823 if (os_memcmp(buf, "FAIL", 4) == 0 || 1824 os_memcmp(buf, "UNKNOWN COMMAND", 15) == 0) 1825 return -1; 1826 if (print) 1827 printf("%s", buf); 1828 1829 pos = buf; 1830 while (*pos != '\0' && *pos != '\n') 1831 pos++; 1832 *pos = '\0'; 1833 os_strlcpy(addr, buf, addr_len); 1834 return 0; 1835} 1836 1837 1838static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1839{ 1840 char addr[32], cmd[64]; 1841 1842 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 1)) 1843 return 0; 1844 do { 1845 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); 1846 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 1) == 0); 1847 1848 return -1; 1849} 1850 1851 1852static int wpa_cli_cmd_list_sta(struct wpa_ctrl *ctrl, int argc, 1853 char *argv[]) 1854{ 1855 char addr[32], cmd[64]; 1856 1857 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 0)) 1858 return 0; 1859 do { 1860 if (os_strcmp(addr, "") != 0) 1861 printf("%s\n", addr); 1862 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); 1863 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 0) == 0); 1864 1865 return 0; 1866} 1867 1868 1869static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc, 1870 char *argv[]) 1871{ 1872 return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv); 1873} 1874 1875 1876static char ** wpa_cli_complete_deauthenticate(const char *str, int pos) 1877{ 1878 int arg = get_cmd_arg_num(str, pos); 1879 char **res = NULL; 1880 1881 switch (arg) { 1882 case 1: 1883 res = cli_txt_list_array(&stations); 1884 break; 1885 } 1886 1887 return res; 1888} 1889 1890 1891static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc, 1892 char *argv[]) 1893{ 1894 return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv); 1895} 1896 1897 1898static char ** wpa_cli_complete_disassociate(const char *str, int pos) 1899{ 1900 int arg = get_cmd_arg_num(str, pos); 1901 char **res = NULL; 1902 1903 switch (arg) { 1904 case 1: 1905 res = cli_txt_list_array(&stations); 1906 break; 1907 } 1908 1909 return res; 1910} 1911 1912 1913static int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc, 1914 char *argv[]) 1915{ 1916 return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv); 1917} 1918 1919#endif /* CONFIG_AP */ 1920 1921 1922static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1923{ 1924 return wpa_ctrl_command(ctrl, "SUSPEND"); 1925} 1926 1927 1928static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1929{ 1930 return wpa_ctrl_command(ctrl, "RESUME"); 1931} 1932 1933 1934#ifdef CONFIG_TESTING_OPTIONS 1935static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1936{ 1937 return wpa_ctrl_command(ctrl, "DROP_SA"); 1938} 1939#endif /* CONFIG_TESTING_OPTIONS */ 1940 1941 1942static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1943{ 1944 return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv); 1945} 1946 1947 1948#ifdef CONFIG_MESH 1949 1950static int wpa_cli_cmd_mesh_interface_add(struct wpa_ctrl *ctrl, int argc, 1951 char *argv[]) 1952{ 1953 return wpa_cli_cmd(ctrl, "MESH_INTERFACE_ADD", 0, argc, argv); 1954} 1955 1956 1957static int wpa_cli_cmd_mesh_group_add(struct wpa_ctrl *ctrl, int argc, 1958 char *argv[]) 1959{ 1960 return wpa_cli_cmd(ctrl, "MESH_GROUP_ADD", 1, argc, argv); 1961} 1962 1963 1964static int wpa_cli_cmd_mesh_group_remove(struct wpa_ctrl *ctrl, int argc, 1965 char *argv[]) 1966{ 1967 return wpa_cli_cmd(ctrl, "MESH_GROUP_REMOVE", 1, argc, argv); 1968} 1969 1970 1971static int wpa_cli_cmd_mesh_peer_remove(struct wpa_ctrl *ctrl, int argc, 1972 char *argv[]) 1973{ 1974 return wpa_cli_cmd(ctrl, "MESH_PEER_REMOVE", 1, argc, argv); 1975} 1976 1977 1978static int wpa_cli_cmd_mesh_peer_add(struct wpa_ctrl *ctrl, int argc, 1979 char *argv[]) 1980{ 1981 return wpa_cli_cmd(ctrl, "MESH_PEER_ADD", 1, argc, argv); 1982} 1983 1984#endif /* CONFIG_MESH */ 1985 1986 1987#ifdef CONFIG_P2P 1988 1989static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1990{ 1991 return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv); 1992} 1993 1994 1995static char ** wpa_cli_complete_p2p_find(const char *str, int pos) 1996{ 1997 char **res = NULL; 1998 int arg = get_cmd_arg_num(str, pos); 1999 2000 res = os_calloc(6, sizeof(char *)); 2001 if (res == NULL) 2002 return NULL; 2003 res[0] = os_strdup("type=social"); 2004 if (res[0] == NULL) { 2005 os_free(res); 2006 return NULL; 2007 } 2008 res[1] = os_strdup("type=progressive"); 2009 if (res[1] == NULL) 2010 return res; 2011 res[2] = os_strdup("delay="); 2012 if (res[2] == NULL) 2013 return res; 2014 res[3] = os_strdup("dev_id="); 2015 if (res[3] == NULL) 2016 return res; 2017 if (arg == 1) 2018 res[4] = os_strdup("[timeout]"); 2019 2020 return res; 2021} 2022 2023 2024static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc, 2025 char *argv[]) 2026{ 2027 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND"); 2028} 2029 2030 2031static int wpa_cli_cmd_p2p_asp_provision(struct wpa_ctrl *ctrl, int argc, 2032 char *argv[]) 2033{ 2034 return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION", 3, argc, argv); 2035} 2036 2037 2038static int wpa_cli_cmd_p2p_asp_provision_resp(struct wpa_ctrl *ctrl, int argc, 2039 char *argv[]) 2040{ 2041 return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION_RESP", 2, argc, argv); 2042} 2043 2044 2045static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc, 2046 char *argv[]) 2047{ 2048 return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv); 2049} 2050 2051 2052static char ** wpa_cli_complete_p2p_connect(const char *str, int pos) 2053{ 2054 int arg = get_cmd_arg_num(str, pos); 2055 char **res = NULL; 2056 2057 switch (arg) { 2058 case 1: 2059 res = cli_txt_list_array(&p2p_peers); 2060 break; 2061 } 2062 2063 return res; 2064} 2065 2066 2067static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc, 2068 char *argv[]) 2069{ 2070 return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv); 2071} 2072 2073 2074static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc, 2075 char *argv[]) 2076{ 2077 return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv); 2078} 2079 2080 2081static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos) 2082{ 2083 int arg = get_cmd_arg_num(str, pos); 2084 char **res = NULL; 2085 2086 switch (arg) { 2087 case 1: 2088 res = cli_txt_list_array(&p2p_groups); 2089 break; 2090 } 2091 2092 return res; 2093} 2094 2095 2096static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc, 2097 char *argv[]) 2098{ 2099 return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv); 2100} 2101 2102 2103static int wpa_cli_cmd_p2p_group_member(struct wpa_ctrl *ctrl, int argc, 2104 char *argv[]) 2105{ 2106 return wpa_cli_cmd(ctrl, "P2P_GROUP_MEMBER", 1, argc, argv); 2107} 2108 2109 2110static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc, 2111 char *argv[]) 2112{ 2113 if (argc != 2 && argc != 3) { 2114 printf("Invalid P2P_PROV_DISC command: needs at least " 2115 "two arguments, address and config method\n" 2116 "(display, keypad, or pbc) and an optional join\n"); 2117 return -1; 2118 } 2119 2120 return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv); 2121} 2122 2123 2124static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc, 2125 char *argv[]) 2126{ 2127 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE"); 2128} 2129 2130 2131static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc, 2132 char *argv[]) 2133{ 2134 char cmd[4096]; 2135 2136 if (argc < 2) { 2137 printf("Invalid P2P_SERV_DISC_REQ command: needs two " 2138 "or more arguments (address and TLVs)\n"); 2139 return -1; 2140 } 2141 2142 if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0) 2143 return -1; 2144 return wpa_ctrl_command(ctrl, cmd); 2145} 2146 2147 2148static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl, 2149 int argc, char *argv[]) 2150{ 2151 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv); 2152} 2153 2154 2155static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc, 2156 char *argv[]) 2157{ 2158 char cmd[4096]; 2159 int res; 2160 2161 if (argc != 4) { 2162 printf("Invalid P2P_SERV_DISC_RESP command: needs four " 2163 "arguments (freq, address, dialog token, and TLVs)\n"); 2164 return -1; 2165 } 2166 2167 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s", 2168 argv[0], argv[1], argv[2], argv[3]); 2169 if (os_snprintf_error(sizeof(cmd), res)) 2170 return -1; 2171 cmd[sizeof(cmd) - 1] = '\0'; 2172 return wpa_ctrl_command(ctrl, cmd); 2173} 2174 2175 2176static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc, 2177 char *argv[]) 2178{ 2179 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE"); 2180} 2181 2182 2183static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl, 2184 int argc, char *argv[]) 2185{ 2186 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv); 2187} 2188 2189 2190static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc, 2191 char *argv[]) 2192{ 2193 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH"); 2194} 2195 2196 2197static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc, 2198 char *argv[]) 2199{ 2200 if (argc < 3) { 2201 printf("Invalid P2P_SERVICE_ADD command: needs 3-6 arguments\n"); 2202 return -1; 2203 } 2204 2205 return wpa_cli_cmd(ctrl, "P2P_SERVICE_ADD", 3, argc, argv); 2206} 2207 2208 2209static int wpa_cli_cmd_p2p_service_rep(struct wpa_ctrl *ctrl, int argc, 2210 char *argv[]) 2211{ 2212 if (argc < 5 || argc > 6) { 2213 printf("Invalid P2P_SERVICE_REP command: needs 5-6 " 2214 "arguments\n"); 2215 return -1; 2216 } 2217 2218 return wpa_cli_cmd(ctrl, "P2P_SERVICE_REP", 5, argc, argv); 2219} 2220 2221 2222static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc, 2223 char *argv[]) 2224{ 2225 char cmd[4096]; 2226 int res; 2227 2228 if (argc != 2 && argc != 3) { 2229 printf("Invalid P2P_SERVICE_DEL command: needs two or three " 2230 "arguments\n"); 2231 return -1; 2232 } 2233 2234 if (argc == 3) 2235 res = os_snprintf(cmd, sizeof(cmd), 2236 "P2P_SERVICE_DEL %s %s %s", 2237 argv[0], argv[1], argv[2]); 2238 else 2239 res = os_snprintf(cmd, sizeof(cmd), 2240 "P2P_SERVICE_DEL %s %s", 2241 argv[0], argv[1]); 2242 if (os_snprintf_error(sizeof(cmd), res)) 2243 return -1; 2244 cmd[sizeof(cmd) - 1] = '\0'; 2245 return wpa_ctrl_command(ctrl, cmd); 2246} 2247 2248 2249static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl, 2250 int argc, char *argv[]) 2251{ 2252 return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv); 2253} 2254 2255 2256static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl, 2257 int argc, char *argv[]) 2258{ 2259 return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv); 2260} 2261 2262 2263static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2264{ 2265 return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv); 2266} 2267 2268 2269static char ** wpa_cli_complete_p2p_peer(const char *str, int pos) 2270{ 2271 int arg = get_cmd_arg_num(str, pos); 2272 char **res = NULL; 2273 2274 switch (arg) { 2275 case 1: 2276 res = cli_txt_list_array(&p2p_peers); 2277 break; 2278 } 2279 2280 return res; 2281} 2282 2283 2284static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, const char *cmd, 2285 char *addr, size_t addr_len, 2286 int discovered) 2287{ 2288 char buf[4096], *pos; 2289 size_t len; 2290 int ret; 2291 2292 if (ctrl_conn == NULL) 2293 return -1; 2294 len = sizeof(buf) - 1; 2295 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 2296 wpa_cli_msg_cb); 2297 if (ret == -2) { 2298 printf("'%s' command timed out.\n", cmd); 2299 return -2; 2300 } else if (ret < 0) { 2301 printf("'%s' command failed.\n", cmd); 2302 return -1; 2303 } 2304 2305 buf[len] = '\0'; 2306 if (os_memcmp(buf, "FAIL", 4) == 0) 2307 return -1; 2308 2309 pos = buf; 2310 while (*pos != '\0' && *pos != '\n') 2311 pos++; 2312 *pos++ = '\0'; 2313 os_strlcpy(addr, buf, addr_len); 2314 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL) 2315 printf("%s\n", addr); 2316 return 0; 2317} 2318 2319 2320static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2321{ 2322 char addr[32], cmd[64]; 2323 int discovered; 2324 2325 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0; 2326 2327 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST", 2328 addr, sizeof(addr), discovered)) 2329 return -1; 2330 do { 2331 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr); 2332 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr), 2333 discovered) == 0); 2334 2335 return 0; 2336} 2337 2338 2339static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2340{ 2341 return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv); 2342} 2343 2344 2345static char ** wpa_cli_complete_p2p_set(const char *str, int pos) 2346{ 2347 int arg = get_cmd_arg_num(str, pos); 2348 const char *fields[] = { 2349 "discoverability", 2350 "managed", 2351 "listen_channel", 2352 "ssid_postfix", 2353 "noa", 2354 "ps", 2355 "oppps", 2356 "ctwindow", 2357 "disabled", 2358 "conc_pref", 2359 "force_long_sd", 2360 "peer_filter", 2361 "cross_connect", 2362 "go_apsd", 2363 "client_apsd", 2364 "disallow_freq", 2365 "disc_int", 2366 "per_sta_psk", 2367 }; 2368 int i, num_fields = ARRAY_SIZE(fields); 2369 2370 if (arg == 1) { 2371 char **res = os_calloc(num_fields + 1, sizeof(char *)); 2372 if (res == NULL) 2373 return NULL; 2374 for (i = 0; i < num_fields; i++) { 2375 res[i] = os_strdup(fields[i]); 2376 if (res[i] == NULL) 2377 return res; 2378 } 2379 return res; 2380 } 2381 2382 if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0) 2383 return cli_txt_list_array(&p2p_peers); 2384 2385 return NULL; 2386} 2387 2388 2389static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2390{ 2391 return wpa_ctrl_command(ctrl, "P2P_FLUSH"); 2392} 2393 2394 2395static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc, 2396 char *argv[]) 2397{ 2398 return wpa_ctrl_command(ctrl, "P2P_CANCEL"); 2399} 2400 2401 2402static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc, 2403 char *argv[]) 2404{ 2405 return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv); 2406} 2407 2408 2409static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc, 2410 char *argv[]) 2411{ 2412 if (argc != 0 && argc != 2 && argc != 4) { 2413 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments " 2414 "(preferred duration, interval; in microsecods).\n" 2415 "Optional second pair can be used to provide " 2416 "acceptable values.\n"); 2417 return -1; 2418 } 2419 2420 return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv); 2421} 2422 2423 2424static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc, 2425 char *argv[]) 2426{ 2427 if (argc != 0 && argc != 2) { 2428 printf("Invalid P2P_EXT_LISTEN command: needs two arguments " 2429 "(availability period, availability interval; in " 2430 "millisecods).\n" 2431 "Extended Listen Timing can be cancelled with this " 2432 "command when used without parameters.\n"); 2433 return -1; 2434 } 2435 2436 return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv); 2437} 2438 2439 2440static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc, 2441 char *argv[]) 2442{ 2443 return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv); 2444} 2445 2446 2447static int wpa_cli_cmd_vendor_elem_add(struct wpa_ctrl *ctrl, int argc, 2448 char *argv[]) 2449{ 2450 return wpa_cli_cmd(ctrl, "VENDOR_ELEM_ADD", 2, argc, argv); 2451} 2452 2453 2454static int wpa_cli_cmd_vendor_elem_get(struct wpa_ctrl *ctrl, int argc, 2455 char *argv[]) 2456{ 2457 return wpa_cli_cmd(ctrl, "VENDOR_ELEM_GET", 1, argc, argv); 2458} 2459 2460 2461static int wpa_cli_cmd_vendor_elem_remove(struct wpa_ctrl *ctrl, int argc, 2462 char *argv[]) 2463{ 2464 return wpa_cli_cmd(ctrl, "VENDOR_ELEM_REMOVE", 2, argc, argv); 2465} 2466 2467#endif /* CONFIG_P2P */ 2468 2469#ifdef CONFIG_WIFI_DISPLAY 2470 2471static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc, 2472 char *argv[]) 2473{ 2474 char cmd[100]; 2475 int res; 2476 2477 if (argc != 1 && argc != 2) { 2478 printf("Invalid WFD_SUBELEM_SET command: needs one or two " 2479 "arguments (subelem, hexdump)\n"); 2480 return -1; 2481 } 2482 2483 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s", 2484 argv[0], argc > 1 ? argv[1] : ""); 2485 if (os_snprintf_error(sizeof(cmd), res)) 2486 return -1; 2487 cmd[sizeof(cmd) - 1] = '\0'; 2488 return wpa_ctrl_command(ctrl, cmd); 2489} 2490 2491 2492static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc, 2493 char *argv[]) 2494{ 2495 char cmd[100]; 2496 int res; 2497 2498 if (argc != 1) { 2499 printf("Invalid WFD_SUBELEM_GET command: needs one " 2500 "argument (subelem)\n"); 2501 return -1; 2502 } 2503 2504 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s", 2505 argv[0]); 2506 if (os_snprintf_error(sizeof(cmd), res)) 2507 return -1; 2508 cmd[sizeof(cmd) - 1] = '\0'; 2509 return wpa_ctrl_command(ctrl, cmd); 2510} 2511#endif /* CONFIG_WIFI_DISPLAY */ 2512 2513 2514#ifdef CONFIG_INTERWORKING 2515static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc, 2516 char *argv[]) 2517{ 2518 return wpa_ctrl_command(ctrl, "FETCH_ANQP"); 2519} 2520 2521 2522static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc, 2523 char *argv[]) 2524{ 2525 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP"); 2526} 2527 2528 2529static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc, 2530 char *argv[]) 2531{ 2532 return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv); 2533} 2534 2535 2536static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc, 2537 char *argv[]) 2538{ 2539 return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv); 2540} 2541 2542 2543static int wpa_cli_cmd_interworking_add_network(struct wpa_ctrl *ctrl, int argc, 2544 char *argv[]) 2545{ 2546 return wpa_cli_cmd(ctrl, "INTERWORKING_ADD_NETWORK", 1, argc, argv); 2547} 2548 2549 2550static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2551{ 2552 return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv); 2553} 2554 2555 2556static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc, 2557 char *argv[]) 2558{ 2559 return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv); 2560} 2561 2562 2563static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc, 2564 char *argv[]) 2565{ 2566 return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv); 2567} 2568#endif /* CONFIG_INTERWORKING */ 2569 2570 2571#ifdef CONFIG_HS20 2572 2573static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc, 2574 char *argv[]) 2575{ 2576 return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv); 2577} 2578 2579 2580static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc, 2581 char *argv[]) 2582{ 2583 char cmd[512]; 2584 2585 if (argc == 0) { 2586 printf("Command needs one or two arguments (dst mac addr and " 2587 "optional home realm)\n"); 2588 return -1; 2589 } 2590 2591 if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST", 2592 argc, argv) < 0) 2593 return -1; 2594 2595 return wpa_ctrl_command(ctrl, cmd); 2596} 2597 2598 2599static int wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl *ctrl, int argc, 2600 char *argv[]) 2601{ 2602 char cmd[512]; 2603 2604 if (argc < 2) { 2605 printf("Command needs two arguments (dst mac addr and " 2606 "icon name)\n"); 2607 return -1; 2608 } 2609 2610 if (write_cmd(cmd, sizeof(cmd), "HS20_ICON_REQUEST", argc, argv) < 0) 2611 return -1; 2612 2613 return wpa_ctrl_command(ctrl, cmd); 2614} 2615 2616 2617static int wpa_cli_cmd_fetch_osu(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2618{ 2619 return wpa_ctrl_command(ctrl, "FETCH_OSU"); 2620} 2621 2622 2623static int wpa_cli_cmd_cancel_fetch_osu(struct wpa_ctrl *ctrl, int argc, 2624 char *argv[]) 2625{ 2626 return wpa_ctrl_command(ctrl, "CANCEL_FETCH_OSU"); 2627} 2628 2629#endif /* CONFIG_HS20 */ 2630 2631 2632static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc, 2633 char *argv[]) 2634{ 2635 return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv); 2636} 2637 2638 2639static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc, 2640 char *argv[]) 2641{ 2642 return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv); 2643} 2644 2645 2646static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc, 2647 char *argv[]) 2648{ 2649 return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv); 2650} 2651 2652 2653static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc, 2654 char *argv[]) 2655{ 2656 return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv); 2657} 2658 2659 2660static int wpa_cli_cmd_tdls_link_status(struct wpa_ctrl *ctrl, int argc, 2661 char *argv[]) 2662{ 2663 return wpa_cli_cmd(ctrl, "TDLS_LINK_STATUS", 1, argc, argv); 2664} 2665 2666 2667static int wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl *ctrl, int argc, 2668 char *argv[]) 2669{ 2670 return wpa_cli_cmd(ctrl, "WMM_AC_ADDTS", 3, argc, argv); 2671} 2672 2673 2674static int wpa_cli_cmd_wmm_ac_delts(struct wpa_ctrl *ctrl, int argc, 2675 char *argv[]) 2676{ 2677 return wpa_cli_cmd(ctrl, "WMM_AC_DELTS", 1, argc, argv); 2678} 2679 2680 2681static int wpa_cli_cmd_wmm_ac_status(struct wpa_ctrl *ctrl, int argc, 2682 char *argv[]) 2683{ 2684 return wpa_ctrl_command(ctrl, "WMM_AC_STATUS"); 2685} 2686 2687 2688static int wpa_cli_cmd_tdls_chan_switch(struct wpa_ctrl *ctrl, int argc, 2689 char *argv[]) 2690{ 2691 return wpa_cli_cmd(ctrl, "TDLS_CHAN_SWITCH", 2, argc, argv); 2692} 2693 2694 2695static int wpa_cli_cmd_tdls_cancel_chan_switch(struct wpa_ctrl *ctrl, int argc, 2696 char *argv[]) 2697{ 2698 return wpa_cli_cmd(ctrl, "TDLS_CANCEL_CHAN_SWITCH", 1, argc, argv); 2699} 2700 2701 2702static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc, 2703 char *argv[]) 2704{ 2705 return wpa_ctrl_command(ctrl, "SIGNAL_POLL"); 2706} 2707 2708 2709static int wpa_cli_cmd_signal_monitor(struct wpa_ctrl *ctrl, int argc, 2710 char *argv[]) 2711{ 2712 return wpa_cli_cmd(ctrl, "SIGNAL_MONITOR", 0, argc, argv); 2713} 2714 2715 2716static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc, 2717 char *argv[]) 2718{ 2719 return wpa_ctrl_command(ctrl, "PKTCNT_POLL"); 2720} 2721 2722 2723static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc, 2724 char *argv[]) 2725{ 2726 return wpa_ctrl_command(ctrl, "REAUTHENTICATE"); 2727} 2728 2729 2730#ifdef CONFIG_AUTOSCAN 2731 2732static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2733{ 2734 if (argc == 0) 2735 return wpa_ctrl_command(ctrl, "AUTOSCAN "); 2736 2737 return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv); 2738} 2739 2740#endif /* CONFIG_AUTOSCAN */ 2741 2742 2743#ifdef CONFIG_WNM 2744 2745static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2746{ 2747 return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv); 2748} 2749 2750 2751static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2752{ 2753 return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv); 2754} 2755 2756#endif /* CONFIG_WNM */ 2757 2758 2759static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2760{ 2761 if (argc == 0) 2762 return -1; 2763 return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]); 2764} 2765 2766 2767#ifdef ANDROID 2768static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2769{ 2770 return wpa_cli_cmd(ctrl, "DRIVER", 1, argc, argv); 2771} 2772#endif /* ANDROID */ 2773 2774 2775static int wpa_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2776{ 2777 return wpa_cli_cmd(ctrl, "VENDOR", 1, argc, argv); 2778} 2779 2780 2781static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2782{ 2783 return wpa_ctrl_command(ctrl, "FLUSH"); 2784} 2785 2786 2787static int wpa_cli_cmd_radio_work(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2788{ 2789 return wpa_cli_cmd(ctrl, "RADIO_WORK", 1, argc, argv); 2790} 2791 2792 2793static int wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl *ctrl, int argc, 2794 char *argv[]) 2795{ 2796 return wpa_cli_cmd(ctrl, "NEIGHBOR_REP_REQUEST", 0, argc, argv); 2797} 2798 2799 2800static int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) 2801{ 2802 return wpa_ctrl_command(ctrl, "ERP_FLUSH"); 2803} 2804 2805 2806static int wpa_cli_cmd_mac_rand_scan(struct wpa_ctrl *ctrl, int argc, 2807 char *argv[]) 2808{ 2809 return wpa_cli_cmd(ctrl, "MAC_RAND_SCAN", 1, argc, argv); 2810} 2811 2812 2813static int wpa_cli_cmd_get_pref_freq_list(struct wpa_ctrl *ctrl, int argc, 2814 char *argv[]) 2815{ 2816 return wpa_cli_cmd(ctrl, "GET_PREF_FREQ_LIST", 1, argc, argv); 2817} 2818 2819 2820static int wpa_cli_cmd_p2p_lo_start(struct wpa_ctrl *ctrl, int argc, 2821 char *argv[]) 2822{ 2823 return wpa_cli_cmd(ctrl, "P2P_LO_START", 4, argc, argv); 2824} 2825 2826 2827static int wpa_cli_cmd_p2p_lo_stop(struct wpa_ctrl *ctrl, int argc, 2828 char *argv[]) 2829{ 2830 return wpa_cli_cmd(ctrl, "P2P_LO_STOP", 0, argc, argv); 2831} 2832 2833 2834#ifdef CONFIG_DPP 2835 2836static int wpa_cli_cmd_dpp_qr_code(struct wpa_ctrl *ctrl, int argc, 2837 char *argv[]) 2838{ 2839 return wpa_cli_cmd(ctrl, "DPP_QR_CODE", 1, argc, argv); 2840} 2841 2842 2843static int wpa_cli_cmd_dpp_bootstrap_gen(struct wpa_ctrl *ctrl, int argc, 2844 char *argv[]) 2845{ 2846 return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_GEN", 1, argc, argv); 2847} 2848 2849 2850static int wpa_cli_cmd_dpp_bootstrap_remove(struct wpa_ctrl *ctrl, int argc, 2851 char *argv[]) 2852{ 2853 return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_REMOVE", 1, argc, argv); 2854} 2855 2856 2857static int wpa_cli_cmd_dpp_bootstrap_get_uri(struct wpa_ctrl *ctrl, int argc, 2858 char *argv[]) 2859{ 2860 return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_GET_URI", 1, argc, argv); 2861} 2862 2863 2864static int wpa_cli_cmd_dpp_bootstrap_info(struct wpa_ctrl *ctrl, int argc, 2865 char *argv[]) 2866{ 2867 return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_INFO", 1, argc, argv); 2868} 2869 2870 2871static int wpa_cli_cmd_dpp_auth_init(struct wpa_ctrl *ctrl, int argc, 2872 char *argv[]) 2873{ 2874 return wpa_cli_cmd(ctrl, "DPP_AUTH_INIT", 1, argc, argv); 2875} 2876 2877 2878static int wpa_cli_cmd_dpp_listen(struct wpa_ctrl *ctrl, int argc, 2879 char *argv[]) 2880{ 2881 return wpa_cli_cmd(ctrl, "DPP_LISTEN", 1, argc, argv); 2882} 2883 2884 2885static int wpa_cli_cmd_dpp_stop_listen(struct wpa_ctrl *ctrl, int argc, 2886 char *argv[]) 2887{ 2888 return wpa_ctrl_command(ctrl, "DPP_STOP_LISTEN"); 2889} 2890 2891 2892static int wpa_cli_cmd_dpp_configurator_add(struct wpa_ctrl *ctrl, int argc, 2893 char *argv[]) 2894{ 2895 return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_ADD", 0, argc, argv); 2896} 2897 2898 2899static int wpa_cli_cmd_dpp_configurator_remove(struct wpa_ctrl *ctrl, int argc, 2900 char *argv[]) 2901{ 2902 return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_REMOVE", 1, argc, argv); 2903} 2904 2905 2906static int wpa_cli_cmd_dpp_pkex_add(struct wpa_ctrl *ctrl, int argc, 2907 char *argv[]) 2908{ 2909 return wpa_cli_cmd(ctrl, "DPP_PKEX_ADD", 1, argc, argv); 2910} 2911 2912 2913static int wpa_cli_cmd_dpp_pkex_remove(struct wpa_ctrl *ctrl, int argc, 2914 char *argv[]) 2915{ 2916 return wpa_cli_cmd(ctrl, "DPP_PKEX_REMOVE", 1, argc, argv); 2917} 2918 2919#endif /* CONFIG_DPP */ 2920 2921 2922enum wpa_cli_cmd_flags { 2923 cli_cmd_flag_none = 0x00, 2924 cli_cmd_flag_sensitive = 0x01 2925}; 2926 2927struct wpa_cli_cmd { 2928 const char *cmd; 2929 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]); 2930 char ** (*completion)(const char *str, int pos); 2931 enum wpa_cli_cmd_flags flags; 2932 const char *usage; 2933}; 2934 2935static const struct wpa_cli_cmd wpa_cli_commands[] = { 2936 { "status", wpa_cli_cmd_status, NULL, 2937 cli_cmd_flag_none, 2938 "[verbose] = get current WPA/EAPOL/EAP status" }, 2939 { "ifname", wpa_cli_cmd_ifname, NULL, 2940 cli_cmd_flag_none, 2941 "= get current interface name" }, 2942 { "ping", wpa_cli_cmd_ping, NULL, 2943 cli_cmd_flag_none, 2944 "= pings wpa_supplicant" }, 2945 { "relog", wpa_cli_cmd_relog, NULL, 2946 cli_cmd_flag_none, 2947 "= re-open log-file (allow rolling logs)" }, 2948 { "note", wpa_cli_cmd_note, NULL, 2949 cli_cmd_flag_none, 2950 "<text> = add a note to wpa_supplicant debug log" }, 2951 { "mib", wpa_cli_cmd_mib, NULL, 2952 cli_cmd_flag_none, 2953 "= get MIB variables (dot1x, dot11)" }, 2954 { "help", wpa_cli_cmd_help, wpa_cli_complete_help, 2955 cli_cmd_flag_none, 2956 "[command] = show usage help" }, 2957 { "interface", wpa_cli_cmd_interface, NULL, 2958 cli_cmd_flag_none, 2959 "[ifname] = show interfaces/select interface" }, 2960 { "level", wpa_cli_cmd_level, NULL, 2961 cli_cmd_flag_none, 2962 "<debug level> = change debug level" }, 2963 { "license", wpa_cli_cmd_license, NULL, 2964 cli_cmd_flag_none, 2965 "= show full wpa_cli license" }, 2966 { "quit", wpa_cli_cmd_quit, NULL, 2967 cli_cmd_flag_none, 2968 "= exit wpa_cli" }, 2969 { "set", wpa_cli_cmd_set, wpa_cli_complete_set, 2970 cli_cmd_flag_none, 2971 "= set variables (shows list of variables when run without " 2972 "arguments)" }, 2973 { "dump", wpa_cli_cmd_dump, NULL, 2974 cli_cmd_flag_none, 2975 "= dump config variables" }, 2976 { "get", wpa_cli_cmd_get, wpa_cli_complete_get, 2977 cli_cmd_flag_none, 2978 "<name> = get information" }, 2979 { "driver_flags", wpa_cli_cmd_driver_flags, NULL, 2980 cli_cmd_flag_none, 2981 "= list driver flags" }, 2982 { "logon", wpa_cli_cmd_logon, NULL, 2983 cli_cmd_flag_none, 2984 "= IEEE 802.1X EAPOL state machine logon" }, 2985 { "logoff", wpa_cli_cmd_logoff, NULL, 2986 cli_cmd_flag_none, 2987 "= IEEE 802.1X EAPOL state machine logoff" }, 2988 { "pmksa", wpa_cli_cmd_pmksa, NULL, 2989 cli_cmd_flag_none, 2990 "= show PMKSA cache" }, 2991 { "pmksa_flush", wpa_cli_cmd_pmksa_flush, NULL, 2992 cli_cmd_flag_none, 2993 "= flush PMKSA cache entries" }, 2994#ifdef CONFIG_PMKSA_CACHE_EXTERNAL 2995 { "pmksa_get", wpa_cli_cmd_pmksa_get, NULL, 2996 cli_cmd_flag_none, 2997 "<network_id> = fetch all stored PMKSA cache entries" }, 2998 { "pmksa_add", wpa_cli_cmd_pmksa_add, NULL, 2999 cli_cmd_flag_sensitive, 3000 "<network_id> <BSSID> <PMKID> <PMK> <reauth_time in seconds> <expiration in seconds> <akmp> <opportunistic> = store PMKSA cache entry from external storage" }, 3001#ifdef CONFIG_MESH 3002 { "mesh_pmksa_get", wpa_cli_mesh_cmd_pmksa_get, NULL, 3003 cli_cmd_flag_none, 3004 "<peer MAC address | any> = fetch all stored mesh PMKSA cache entries" }, 3005 { "mesh_pmksa_add", wpa_cli_mesh_cmd_pmksa_add, NULL, 3006 cli_cmd_flag_sensitive, 3007 "<BSSID> <PMKID> <PMK> <expiration in seconds> = store mesh PMKSA cache entry from external storage" }, 3008#endif /* CONFIG_MESH */ 3009#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */ 3010 { "reassociate", wpa_cli_cmd_reassociate, NULL, 3011 cli_cmd_flag_none, 3012 "= force reassociation" }, 3013 { "reattach", wpa_cli_cmd_reattach, NULL, 3014 cli_cmd_flag_none, 3015 "= force reassociation back to the same BSS" }, 3016 { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss, 3017 cli_cmd_flag_none, 3018 "<BSSID> = force preauthentication" }, 3019 { "identity", wpa_cli_cmd_identity, wpa_cli_complete_network_id, 3020 cli_cmd_flag_none, 3021 "<network id> <identity> = configure identity for an SSID" }, 3022 { "password", wpa_cli_cmd_password, wpa_cli_complete_network_id, 3023 cli_cmd_flag_sensitive, 3024 "<network id> <password> = configure password for an SSID" }, 3025 { "new_password", wpa_cli_cmd_new_password, 3026 wpa_cli_complete_network_id, cli_cmd_flag_sensitive, 3027 "<network id> <password> = change password for an SSID" }, 3028 { "pin", wpa_cli_cmd_pin, wpa_cli_complete_network_id, 3029 cli_cmd_flag_sensitive, 3030 "<network id> <pin> = configure pin for an SSID" }, 3031 { "otp", wpa_cli_cmd_otp, wpa_cli_complete_network_id, 3032 cli_cmd_flag_sensitive, 3033 "<network id> <password> = configure one-time-password for an SSID" 3034 }, 3035 { "passphrase", wpa_cli_cmd_passphrase, wpa_cli_complete_network_id, 3036 cli_cmd_flag_sensitive, 3037 "<network id> <passphrase> = configure private key passphrase\n" 3038 " for an SSID" }, 3039 { "sim", wpa_cli_cmd_sim, wpa_cli_complete_network_id, 3040 cli_cmd_flag_sensitive, 3041 "<network id> <pin> = report SIM operation result" }, 3042 { "bssid", wpa_cli_cmd_bssid, wpa_cli_complete_network_id, 3043 cli_cmd_flag_none, 3044 "<network id> <BSSID> = set preferred BSSID for an SSID" }, 3045 { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss, 3046 cli_cmd_flag_none, 3047 "<BSSID> = add a BSSID to the blacklist\n" 3048 "blacklist clear = clear the blacklist\n" 3049 "blacklist = display the blacklist" }, 3050 { "log_level", wpa_cli_cmd_log_level, NULL, 3051 cli_cmd_flag_none, 3052 "<level> [<timestamp>] = update the log level/timestamp\n" 3053 "log_level = display the current log level and log options" }, 3054 { "list_networks", wpa_cli_cmd_list_networks, NULL, 3055 cli_cmd_flag_none, 3056 "= list configured networks" }, 3057 { "select_network", wpa_cli_cmd_select_network, 3058 wpa_cli_complete_network_id, 3059 cli_cmd_flag_none, 3060 "<network id> = select a network (disable others)" }, 3061 { "enable_network", wpa_cli_cmd_enable_network, 3062 wpa_cli_complete_network_id, 3063 cli_cmd_flag_none, 3064 "<network id> = enable a network" }, 3065 { "disable_network", wpa_cli_cmd_disable_network, 3066 wpa_cli_complete_network_id, 3067 cli_cmd_flag_none, 3068 "<network id> = disable a network" }, 3069 { "add_network", wpa_cli_cmd_add_network, NULL, 3070 cli_cmd_flag_none, 3071 "= add a network" }, 3072 { "remove_network", wpa_cli_cmd_remove_network, 3073 wpa_cli_complete_network_id, 3074 cli_cmd_flag_none, 3075 "<network id> = remove a network" }, 3076 { "set_network", wpa_cli_cmd_set_network, wpa_cli_complete_network, 3077 cli_cmd_flag_sensitive, 3078 "<network id> <variable> <value> = set network variables (shows\n" 3079 " list of variables when run without arguments)" }, 3080 { "get_network", wpa_cli_cmd_get_network, wpa_cli_complete_network, 3081 cli_cmd_flag_none, 3082 "<network id> <variable> = get network variables" }, 3083 { "dup_network", wpa_cli_cmd_dup_network, wpa_cli_complete_dup_network, 3084 cli_cmd_flag_none, 3085 "<src network id> <dst network id> <variable> = duplicate network variables" 3086 }, 3087 { "list_creds", wpa_cli_cmd_list_creds, NULL, 3088 cli_cmd_flag_none, 3089 "= list configured credentials" }, 3090 { "add_cred", wpa_cli_cmd_add_cred, NULL, 3091 cli_cmd_flag_none, 3092 "= add a credential" }, 3093 { "remove_cred", wpa_cli_cmd_remove_cred, NULL, 3094 cli_cmd_flag_none, 3095 "<cred id> = remove a credential" }, 3096 { "set_cred", wpa_cli_cmd_set_cred, NULL, 3097 cli_cmd_flag_sensitive, 3098 "<cred id> <variable> <value> = set credential variables" }, 3099 { "get_cred", wpa_cli_cmd_get_cred, NULL, 3100 cli_cmd_flag_none, 3101 "<cred id> <variable> = get credential variables" }, 3102 { "save_config", wpa_cli_cmd_save_config, NULL, 3103 cli_cmd_flag_none, 3104 "= save the current configuration" }, 3105 { "disconnect", wpa_cli_cmd_disconnect, NULL, 3106 cli_cmd_flag_none, 3107 "= disconnect and wait for reassociate/reconnect command before\n" 3108 " connecting" }, 3109 { "reconnect", wpa_cli_cmd_reconnect, NULL, 3110 cli_cmd_flag_none, 3111 "= like reassociate, but only takes effect if already disconnected" 3112 }, 3113 { "scan", wpa_cli_cmd_scan, NULL, 3114 cli_cmd_flag_none, 3115 "= request new BSS scan" }, 3116 { "scan_results", wpa_cli_cmd_scan_results, NULL, 3117 cli_cmd_flag_none, 3118 "= get latest scan results" }, 3119 { "abort_scan", wpa_cli_cmd_abort_scan, NULL, 3120 cli_cmd_flag_none, 3121 "= request ongoing scan to be aborted" }, 3122 { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss, 3123 cli_cmd_flag_none, 3124 "<<idx> | <bssid>> = get detailed scan result info" }, 3125 { "get_capability", wpa_cli_cmd_get_capability, 3126 wpa_cli_complete_get_capability, cli_cmd_flag_none, 3127 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> " 3128 "= get capabilities" }, 3129 { "reconfigure", wpa_cli_cmd_reconfigure, NULL, 3130 cli_cmd_flag_none, 3131 "= force wpa_supplicant to re-read its configuration file" }, 3132 { "terminate", wpa_cli_cmd_terminate, NULL, 3133 cli_cmd_flag_none, 3134 "= terminate wpa_supplicant" }, 3135 { "interface_add", wpa_cli_cmd_interface_add, NULL, 3136 cli_cmd_flag_none, 3137 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n" 3138 " <bridge_name> <create> <type> = adds new interface, all " 3139 "parameters but\n" 3140 " <ifname> are optional. Supported types are station ('sta') and " 3141 "AP ('ap')" }, 3142 { "interface_remove", wpa_cli_cmd_interface_remove, NULL, 3143 cli_cmd_flag_none, 3144 "<ifname> = removes the interface" }, 3145 { "interface_list", wpa_cli_cmd_interface_list, NULL, 3146 cli_cmd_flag_none, 3147 "= list available interfaces" }, 3148 { "ap_scan", wpa_cli_cmd_ap_scan, NULL, 3149 cli_cmd_flag_none, 3150 "<value> = set ap_scan parameter" }, 3151 { "scan_interval", wpa_cli_cmd_scan_interval, NULL, 3152 cli_cmd_flag_none, 3153 "<value> = set scan_interval parameter (in seconds)" }, 3154 { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL, 3155 cli_cmd_flag_none, 3156 "<value> = set BSS expiration age parameter" }, 3157 { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL, 3158 cli_cmd_flag_none, 3159 "<value> = set BSS expiration scan count parameter" }, 3160 { "bss_flush", wpa_cli_cmd_bss_flush, NULL, 3161 cli_cmd_flag_none, 3162 "<value> = set BSS flush age (0 by default)" }, 3163 { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss, 3164 cli_cmd_flag_none, 3165 "<addr> = request over-the-DS FT with <addr>" }, 3166 { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss, 3167 cli_cmd_flag_none, 3168 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" }, 3169 { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss, 3170 cli_cmd_flag_sensitive, 3171 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not " 3172 "hardcoded)" }, 3173 { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL, 3174 cli_cmd_flag_sensitive, 3175 "<PIN> = verify PIN checksum" }, 3176 { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none, 3177 "Cancels the pending WPS operation" }, 3178#ifdef CONFIG_WPS_NFC 3179 { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss, 3180 cli_cmd_flag_none, 3181 "[BSSID] = start Wi-Fi Protected Setup: NFC" }, 3182 { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL, 3183 cli_cmd_flag_none, 3184 "<WPS|NDEF> = build configuration token" }, 3185 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL, 3186 cli_cmd_flag_none, 3187 "<WPS|NDEF> = create password token" }, 3188 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL, 3189 cli_cmd_flag_sensitive, 3190 "<hexdump of payload> = report read NFC tag with WPS data" }, 3191 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL, 3192 cli_cmd_flag_none, 3193 "<NDEF> <WPS> = create NFC handover request" }, 3194 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL, 3195 cli_cmd_flag_none, 3196 "<NDEF> <WPS> = create NFC handover select" }, 3197 { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL, 3198 cli_cmd_flag_none, 3199 "<role> <type> <hexdump of req> <hexdump of sel> = report completed " 3200 "NFC handover" }, 3201#endif /* CONFIG_WPS_NFC */ 3202 { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss, 3203 cli_cmd_flag_sensitive, 3204 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" }, 3205 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL, 3206 cli_cmd_flag_sensitive, 3207 "[params..] = enable/disable AP PIN" }, 3208 { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL, 3209 cli_cmd_flag_none, 3210 "[IP address] = start Wi-Fi Protected Setup External Registrar" }, 3211 { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL, 3212 cli_cmd_flag_none, 3213 "= stop Wi-Fi Protected Setup External Registrar" }, 3214 { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL, 3215 cli_cmd_flag_sensitive, 3216 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" }, 3217 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL, 3218 cli_cmd_flag_none, 3219 "<UUID> = accept an Enrollee PBC using External Registrar" }, 3220 { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL, 3221 cli_cmd_flag_sensitive, 3222 "<UUID> <PIN> = learn AP configuration" }, 3223 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL, 3224 cli_cmd_flag_none, 3225 "<UUID> <network id> = set AP configuration for enrolling" }, 3226 { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL, 3227 cli_cmd_flag_sensitive, 3228 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" }, 3229#ifdef CONFIG_WPS_NFC 3230 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL, 3231 cli_cmd_flag_none, 3232 "<WPS/NDEF> <UUID> = build NFC configuration token" }, 3233#endif /* CONFIG_WPS_NFC */ 3234 { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL, 3235 cli_cmd_flag_none, 3236 "<addr> = request RSN authentication with <addr> in IBSS" }, 3237#ifdef CONFIG_AP 3238 { "sta", wpa_cli_cmd_sta, wpa_cli_complete_sta, 3239 cli_cmd_flag_none, 3240 "<addr> = get information about an associated station (AP)" }, 3241 { "all_sta", wpa_cli_cmd_all_sta, NULL, 3242 cli_cmd_flag_none, 3243 "= get information about all associated stations (AP)" }, 3244 { "list_sta", wpa_cli_cmd_list_sta, NULL, 3245 cli_cmd_flag_none, 3246 "= list all stations (AP)" }, 3247 { "deauthenticate", wpa_cli_cmd_deauthenticate, 3248 wpa_cli_complete_deauthenticate, cli_cmd_flag_none, 3249 "<addr> = deauthenticate a station" }, 3250 { "disassociate", wpa_cli_cmd_disassociate, 3251 wpa_cli_complete_disassociate, cli_cmd_flag_none, 3252 "<addr> = disassociate a station" }, 3253 { "chan_switch", wpa_cli_cmd_chanswitch, NULL, 3254 cli_cmd_flag_none, 3255 "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]" 3256 " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]" 3257 " = CSA parameters" }, 3258#endif /* CONFIG_AP */ 3259 { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none, 3260 "= notification of suspend/hibernate" }, 3261 { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none, 3262 "= notification of resume/thaw" }, 3263#ifdef CONFIG_TESTING_OPTIONS 3264 { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none, 3265 "= drop SA without deauth/disassoc (test command)" }, 3266#endif /* CONFIG_TESTING_OPTIONS */ 3267 { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss, 3268 cli_cmd_flag_none, 3269 "<addr> = roam to the specified BSS" }, 3270#ifdef CONFIG_MESH 3271 { "mesh_interface_add", wpa_cli_cmd_mesh_interface_add, NULL, 3272 cli_cmd_flag_none, 3273 "[ifname] = Create a new mesh interface" }, 3274 { "mesh_group_add", wpa_cli_cmd_mesh_group_add, NULL, 3275 cli_cmd_flag_none, 3276 "<network id> = join a mesh network (disable others)" }, 3277 { "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL, 3278 cli_cmd_flag_none, 3279 "<ifname> = Remove mesh group interface" }, 3280 { "mesh_peer_remove", wpa_cli_cmd_mesh_peer_remove, NULL, 3281 cli_cmd_flag_none, 3282 "<addr> = Remove a mesh peer" }, 3283 { "mesh_peer_add", wpa_cli_cmd_mesh_peer_add, NULL, 3284 cli_cmd_flag_none, 3285 "<addr> [duration=<seconds>] = Add a mesh peer" }, 3286#endif /* CONFIG_MESH */ 3287#ifdef CONFIG_P2P 3288 { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find, 3289 cli_cmd_flag_none, 3290 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" }, 3291 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none, 3292 "= stop P2P Devices search" }, 3293 { "p2p_asp_provision", wpa_cli_cmd_p2p_asp_provision, NULL, 3294 cli_cmd_flag_none, 3295 "<addr> adv_id=<adv_id> conncap=<conncap> [info=<infodata>] = provision with a P2P ASP Device" }, 3296 { "p2p_asp_provision_resp", wpa_cli_cmd_p2p_asp_provision_resp, NULL, 3297 cli_cmd_flag_none, 3298 "<addr> adv_id=<adv_id> [role<conncap>] [info=<infodata>] = provision with a P2P ASP Device" }, 3299 { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect, 3300 cli_cmd_flag_none, 3301 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" }, 3302 { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none, 3303 "[timeout] = listen for P2P Devices for up-to timeout seconds" }, 3304 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, 3305 wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none, 3306 "<ifname> = remove P2P group interface (terminate group if GO)" }, 3307 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none, 3308 "[ht40] = add a new P2P group (local end as GO)" }, 3309 { "p2p_group_member", wpa_cli_cmd_p2p_group_member, NULL, 3310 cli_cmd_flag_none, 3311 "<dev_addr> = Get peer interface address on local GO using peer Device Address" }, 3312 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, 3313 wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3314 "<addr> <method> = request provisioning discovery" }, 3315 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL, 3316 cli_cmd_flag_none, 3317 "= get the passphrase for a group (GO only)" }, 3318 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req, 3319 wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3320 "<addr> <TLVs> = schedule service discovery request" }, 3321 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req, 3322 NULL, cli_cmd_flag_none, 3323 "<id> = cancel pending service discovery request" }, 3324 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL, 3325 cli_cmd_flag_none, 3326 "<freq> <addr> <dialog token> <TLVs> = service discovery response" }, 3327 { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL, 3328 cli_cmd_flag_none, 3329 "= indicate change in local services" }, 3330 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL, 3331 cli_cmd_flag_none, 3332 "<external> = set external processing of service discovery" }, 3333 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL, 3334 cli_cmd_flag_none, 3335 "= remove all stored service entries" }, 3336 { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL, 3337 cli_cmd_flag_none, 3338 "<bonjour|upnp|asp> <query|version> <response|service> = add a local " 3339 "service" }, 3340 { "p2p_service_rep", wpa_cli_cmd_p2p_service_rep, NULL, 3341 cli_cmd_flag_none, 3342 "asp <auto> <adv_id> <svc_state> <svc_string> [<svc_info>] = replace " 3343 "local ASP service" }, 3344 { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL, 3345 cli_cmd_flag_none, 3346 "<bonjour|upnp> <query|version> [|service] = remove a local " 3347 "service" }, 3348 { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer, 3349 cli_cmd_flag_none, 3350 "<addr> = reject connection attempts from a specific peer" }, 3351 { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL, 3352 cli_cmd_flag_none, 3353 "<cmd> [peer=addr] = invite peer" }, 3354 { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none, 3355 "[discovered] = list known (optionally, only fully discovered) P2P " 3356 "peers" }, 3357 { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer, 3358 cli_cmd_flag_none, 3359 "<address> = show information about known P2P peer" }, 3360 { "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set, 3361 cli_cmd_flag_none, 3362 "<field> <value> = set a P2P parameter" }, 3363 { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none, 3364 "= flush P2P state" }, 3365 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none, 3366 "= cancel P2P group formation" }, 3367 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, 3368 wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3369 "<address> = unauthorize a peer" }, 3370 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL, 3371 cli_cmd_flag_none, 3372 "[<duration> <interval>] [<duration> <interval>] = request GO " 3373 "presence" }, 3374 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL, 3375 cli_cmd_flag_none, 3376 "[<period> <interval>] = set extended listen timing" }, 3377 { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client, 3378 wpa_cli_complete_p2p_peer, cli_cmd_flag_none, 3379 "<address|iface=address> = remove a peer from all groups" }, 3380 { "vendor_elem_add", wpa_cli_cmd_vendor_elem_add, NULL, 3381 cli_cmd_flag_none, 3382 "<frame id> <hexdump of elem(s)> = add vendor specific IEs to frame(s)\n" 3383 VENDOR_ELEM_FRAME_ID }, 3384 { "vendor_elem_get", wpa_cli_cmd_vendor_elem_get, NULL, 3385 cli_cmd_flag_none, 3386 "<frame id> = get vendor specific IE(s) to frame(s)\n" 3387 VENDOR_ELEM_FRAME_ID }, 3388 { "vendor_elem_remove", wpa_cli_cmd_vendor_elem_remove, NULL, 3389 cli_cmd_flag_none, 3390 "<frame id> <hexdump of elem(s)> = remove vendor specific IE(s) in frame(s)\n" 3391 VENDOR_ELEM_FRAME_ID }, 3392#endif /* CONFIG_P2P */ 3393#ifdef CONFIG_WIFI_DISPLAY 3394 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL, 3395 cli_cmd_flag_none, 3396 "<subelem> [contents] = set Wi-Fi Display subelement" }, 3397 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL, 3398 cli_cmd_flag_none, 3399 "<subelem> = get Wi-Fi Display subelement" }, 3400#endif /* CONFIG_WIFI_DISPLAY */ 3401#ifdef CONFIG_INTERWORKING 3402 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none, 3403 "= fetch ANQP information for all APs" }, 3404 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL, 3405 cli_cmd_flag_none, 3406 "= stop fetch_anqp operation" }, 3407 { "interworking_select", wpa_cli_cmd_interworking_select, NULL, 3408 cli_cmd_flag_none, 3409 "[auto] = perform Interworking network selection" }, 3410 { "interworking_connect", wpa_cli_cmd_interworking_connect, 3411 wpa_cli_complete_bss, cli_cmd_flag_none, 3412 "<BSSID> = connect using Interworking credentials" }, 3413 { "interworking_add_network", wpa_cli_cmd_interworking_add_network, 3414 wpa_cli_complete_bss, cli_cmd_flag_none, 3415 "<BSSID> = connect using Interworking credentials" }, 3416 { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss, 3417 cli_cmd_flag_none, 3418 "<addr> <info id>[,<info id>]... = request ANQP information" }, 3419 { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss, 3420 cli_cmd_flag_none, 3421 "<addr> <AdvProtoID> [QueryReq] = GAS request" }, 3422 { "gas_response_get", wpa_cli_cmd_gas_response_get, 3423 wpa_cli_complete_bss, cli_cmd_flag_none, 3424 "<addr> <dialog token> [start,len] = Fetch last GAS response" }, 3425#endif /* CONFIG_INTERWORKING */ 3426#ifdef CONFIG_HS20 3427 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss, 3428 cli_cmd_flag_none, 3429 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information" 3430 }, 3431 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list, 3432 wpa_cli_complete_bss, cli_cmd_flag_none, 3433 "<addr> <home realm> = get HS20 nai home realm list" }, 3434 { "hs20_icon_request", wpa_cli_cmd_hs20_icon_request, 3435 wpa_cli_complete_bss, cli_cmd_flag_none, 3436 "<addr> <icon name> = get Hotspot 2.0 OSU icon" }, 3437 { "fetch_osu", wpa_cli_cmd_fetch_osu, NULL, cli_cmd_flag_none, 3438 "= fetch OSU provider information from all APs" }, 3439 { "cancel_fetch_osu", wpa_cli_cmd_cancel_fetch_osu, NULL, 3440 cli_cmd_flag_none, 3441 "= cancel fetch_osu command" }, 3442#endif /* CONFIG_HS20 */ 3443 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL, 3444 cli_cmd_flag_none, 3445 "<0/1> = disable/enable automatic reconnection" }, 3446 { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL, 3447 cli_cmd_flag_none, 3448 "<addr> = request TDLS discovery with <addr>" }, 3449 { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL, 3450 cli_cmd_flag_none, 3451 "<addr> = request TDLS setup with <addr>" }, 3452 { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL, 3453 cli_cmd_flag_none, 3454 "<addr> = tear down TDLS with <addr>" }, 3455 { "tdls_link_status", wpa_cli_cmd_tdls_link_status, NULL, 3456 cli_cmd_flag_none, 3457 "<addr> = TDLS link status with <addr>" }, 3458 { "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL, 3459 cli_cmd_flag_none, 3460 "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] " 3461 "[mean_data_rate=#] [min_phy_rate=#] [sba=#] [fixed_nominal_msdu] " 3462 "= add WMM-AC traffic stream" }, 3463 { "wmm_ac_delts", wpa_cli_cmd_wmm_ac_delts, NULL, 3464 cli_cmd_flag_none, 3465 "<tsid> = delete WMM-AC traffic stream" }, 3466 { "wmm_ac_status", wpa_cli_cmd_wmm_ac_status, NULL, 3467 cli_cmd_flag_none, 3468 "= show status for Wireless Multi-Media Admission-Control" }, 3469 { "tdls_chan_switch", wpa_cli_cmd_tdls_chan_switch, NULL, 3470 cli_cmd_flag_none, 3471 "<addr> <oper class> <freq> [sec_channel_offset=] [center_freq1=] " 3472 "[center_freq2=] [bandwidth=] [ht|vht] = enable channel switching " 3473 "with TDLS peer" }, 3474 { "tdls_cancel_chan_switch", wpa_cli_cmd_tdls_cancel_chan_switch, NULL, 3475 cli_cmd_flag_none, 3476 "<addr> = disable channel switching with TDLS peer <addr>" }, 3477 { "signal_poll", wpa_cli_cmd_signal_poll, NULL, 3478 cli_cmd_flag_none, 3479 "= get signal parameters" }, 3480 { "signal_monitor", wpa_cli_cmd_signal_monitor, NULL, 3481 cli_cmd_flag_none, 3482 "= set signal monitor parameters" }, 3483 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL, 3484 cli_cmd_flag_none, 3485 "= get TX/RX packet counters" }, 3486 { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL, 3487 cli_cmd_flag_none, 3488 "= trigger IEEE 802.1X/EAPOL reauthentication" }, 3489#ifdef CONFIG_AUTOSCAN 3490 { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none, 3491 "[params] = Set or unset (if none) autoscan parameters" }, 3492#endif /* CONFIG_AUTOSCAN */ 3493#ifdef CONFIG_WNM 3494 { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none, 3495 "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" }, 3496 { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none, 3497 "<query reason> [list]" 3498 " [neighbor=<BSSID>,<BSSID information>,<operating class>,<channel number>,<PHY type>[,<hexdump of optional subelements>]" 3499 " = Send BSS Transition Management Query" }, 3500#endif /* CONFIG_WNM */ 3501 { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive, 3502 "<params..> = Sent unprocessed command" }, 3503 { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none, 3504 "= flush wpa_supplicant state" }, 3505#ifdef ANDROID 3506 { "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none, 3507 "<command> = driver private commands" }, 3508#endif /* ANDROID */ 3509 { "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none, 3510 "= radio_work <show/add/done>" }, 3511 { "vendor", wpa_cli_cmd_vendor, NULL, cli_cmd_flag_none, 3512 "<vendor id> <command id> [<hex formatted command argument>] = Send vendor command" 3513 }, 3514 { "neighbor_rep_request", 3515 wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none, 3516 "[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)" 3517 }, 3518 { "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none, 3519 "= flush ERP keys" }, 3520 { "mac_rand_scan", 3521 wpa_cli_cmd_mac_rand_scan, NULL, cli_cmd_flag_none, 3522 "<scan|sched|pno|all> enable=<0/1> [addr=mac-address " 3523 "mask=mac-address-mask] = scan MAC randomization" 3524 }, 3525 { "get_pref_freq_list", wpa_cli_cmd_get_pref_freq_list, NULL, 3526 cli_cmd_flag_none, 3527 "<interface type> = retrieve preferred freq list for the specified interface type" }, 3528 { "p2p_lo_start", wpa_cli_cmd_p2p_lo_start, NULL, 3529 cli_cmd_flag_none, 3530 "<freq> <period> <interval> <count> = start P2P listen offload" }, 3531 { "p2p_lo_stop", wpa_cli_cmd_p2p_lo_stop, NULL, 3532 cli_cmd_flag_none, 3533 "= stop P2P listen offload" }, 3534#ifdef CONFIG_DPP 3535 { "dpp_qr_code", wpa_cli_cmd_dpp_qr_code, NULL, cli_cmd_flag_none, 3536 "report a scanned DPP URI from a QR Code" }, 3537 { "dpp_bootstrap_gen", wpa_cli_cmd_dpp_bootstrap_gen, NULL, 3538 cli_cmd_flag_sensitive, 3539 "type=<qrcode> [chan=..] [mac=..] [info=..] [curve=..] [key=..] = generate DPP bootstrap information" }, 3540 { "dpp_bootstrap_remove", wpa_cli_cmd_dpp_bootstrap_remove, NULL, 3541 cli_cmd_flag_none, 3542 "*|<id> = remove DPP bootstrap information" }, 3543 { "dpp_bootstrap_get_uri", wpa_cli_cmd_dpp_bootstrap_get_uri, NULL, 3544 cli_cmd_flag_none, 3545 "<id> = get DPP bootstrap URI" }, 3546 { "dpp_bootstrap_info", wpa_cli_cmd_dpp_bootstrap_info, NULL, 3547 cli_cmd_flag_none, 3548 "<id> = show DPP bootstrap information" }, 3549 { "dpp_auth_init", wpa_cli_cmd_dpp_auth_init, NULL, cli_cmd_flag_none, 3550 "peer=<id> [own=<id>] = initiate DPP bootstrapping" }, 3551 { "dpp_listen", wpa_cli_cmd_dpp_listen, NULL, cli_cmd_flag_none, 3552 "<freq in MHz> = start DPP listen" }, 3553 { "dpp_stop_listen", wpa_cli_cmd_dpp_stop_listen, NULL, 3554 cli_cmd_flag_none, 3555 "= stop DPP listen" }, 3556 { "dpp_configurator_add", wpa_cli_cmd_dpp_configurator_add, NULL, 3557 cli_cmd_flag_sensitive, 3558 "[curve=..] [key=..] = add DPP configurator" }, 3559 { "dpp_configurator_remove", wpa_cli_cmd_dpp_configurator_remove, NULL, 3560 cli_cmd_flag_none, 3561 "*|<id> = remove DPP configurator" }, 3562 { "dpp_pkex_add", wpa_cli_cmd_dpp_pkex_add, NULL, 3563 cli_cmd_flag_sensitive, 3564 "add PKEX code" }, 3565 { "dpp_pkex_remove", wpa_cli_cmd_dpp_pkex_remove, NULL, 3566 cli_cmd_flag_none, 3567 "*|<id> = remove DPP pkex information" }, 3568#endif /* CONFIG_DPP */ 3569 { NULL, NULL, NULL, cli_cmd_flag_none, NULL } 3570}; 3571 3572 3573/* 3574 * Prints command usage, lines are padded with the specified string. 3575 */ 3576static void print_cmd_help(const struct wpa_cli_cmd *cmd, const char *pad) 3577{ 3578 char c; 3579 size_t n; 3580 3581 printf("%s%s ", pad, cmd->cmd); 3582 for (n = 0; (c = cmd->usage[n]); n++) { 3583 printf("%c", c); 3584 if (c == '\n') 3585 printf("%s", pad); 3586 } 3587 printf("\n"); 3588} 3589 3590 3591static void print_help(const char *cmd) 3592{ 3593 int n; 3594 printf("commands:\n"); 3595 for (n = 0; wpa_cli_commands[n].cmd; n++) { 3596 if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd)) 3597 print_cmd_help(&wpa_cli_commands[n], " "); 3598 } 3599} 3600 3601 3602static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd) 3603{ 3604 const char *c, *delim; 3605 int n; 3606 size_t len; 3607 3608 delim = os_strchr(cmd, ' '); 3609 if (delim) 3610 len = delim - cmd; 3611 else 3612 len = os_strlen(cmd); 3613 3614 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) { 3615 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c)) 3616 return (wpa_cli_commands[n].flags & 3617 cli_cmd_flag_sensitive); 3618 } 3619 return 0; 3620} 3621 3622 3623static char ** wpa_list_cmd_list(void) 3624{ 3625 char **res; 3626 int i, count; 3627 struct cli_txt_entry *e; 3628 3629 count = ARRAY_SIZE(wpa_cli_commands); 3630 count += dl_list_len(&p2p_groups); 3631 count += dl_list_len(&ifnames); 3632 res = os_calloc(count + 1, sizeof(char *)); 3633 if (res == NULL) 3634 return NULL; 3635 3636 for (i = 0; wpa_cli_commands[i].cmd; i++) { 3637 res[i] = os_strdup(wpa_cli_commands[i].cmd); 3638 if (res[i] == NULL) 3639 break; 3640 } 3641 3642 dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) { 3643 size_t len = 8 + os_strlen(e->txt); 3644 res[i] = os_malloc(len); 3645 if (res[i] == NULL) 3646 break; 3647 os_snprintf(res[i], len, "ifname=%s", e->txt); 3648 i++; 3649 } 3650 3651 dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) { 3652 res[i] = os_strdup(e->txt); 3653 if (res[i] == NULL) 3654 break; 3655 i++; 3656 } 3657 3658 return res; 3659} 3660 3661 3662static char ** wpa_cli_cmd_completion(const char *cmd, const char *str, 3663 int pos) 3664{ 3665 int i; 3666 3667 for (i = 0; wpa_cli_commands[i].cmd; i++) { 3668 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) { 3669 if (wpa_cli_commands[i].completion) 3670 return wpa_cli_commands[i].completion(str, 3671 pos); 3672 edit_clear_line(); 3673 printf("\r%s\n", wpa_cli_commands[i].usage); 3674 edit_redraw(); 3675 break; 3676 } 3677 } 3678 3679 return NULL; 3680} 3681 3682 3683static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos) 3684{ 3685 char **res; 3686 const char *end; 3687 char *cmd; 3688 3689 if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) { 3690 end = os_strchr(str, ' '); 3691 if (end && pos > end - str) { 3692 pos -= end - str + 1; 3693 str = end + 1; 3694 } 3695 } 3696 3697 end = os_strchr(str, ' '); 3698 if (end == NULL || str + pos < end) 3699 return wpa_list_cmd_list(); 3700 3701 cmd = os_malloc(pos + 1); 3702 if (cmd == NULL) 3703 return NULL; 3704 os_memcpy(cmd, str, pos); 3705 cmd[end - str] = '\0'; 3706 res = wpa_cli_cmd_completion(cmd, str, pos); 3707 os_free(cmd); 3708 return res; 3709} 3710 3711 3712static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[]) 3713{ 3714 const struct wpa_cli_cmd *cmd, *match = NULL; 3715 int count; 3716 int ret = 0; 3717 3718 if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) { 3719 ifname_prefix = argv[0] + 7; 3720 argv = &argv[1]; 3721 argc--; 3722 } else 3723 ifname_prefix = NULL; 3724 3725 if (argc == 0) 3726 return -1; 3727 3728 count = 0; 3729 cmd = wpa_cli_commands; 3730 while (cmd->cmd) { 3731 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0) 3732 { 3733 match = cmd; 3734 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) { 3735 /* we have an exact match */ 3736 count = 1; 3737 break; 3738 } 3739 count++; 3740 } 3741 cmd++; 3742 } 3743 3744 if (count > 1) { 3745 printf("Ambiguous command '%s'; possible commands:", argv[0]); 3746 cmd = wpa_cli_commands; 3747 while (cmd->cmd) { 3748 if (os_strncasecmp(cmd->cmd, argv[0], 3749 os_strlen(argv[0])) == 0) { 3750 printf(" %s", cmd->cmd); 3751 } 3752 cmd++; 3753 } 3754 printf("\n"); 3755 ret = 1; 3756 } else if (count == 0) { 3757 printf("Unknown command '%s'\n", argv[0]); 3758 ret = 1; 3759 } else { 3760 ret = match->handler(ctrl, argc - 1, &argv[1]); 3761 } 3762 3763 return ret; 3764} 3765 3766 3767static int wpa_cli_exec(const char *program, const char *arg1, 3768 const char *arg2) 3769{ 3770 char *arg; 3771 size_t len; 3772 int res; 3773 3774 /* If no interface is specified, set the global */ 3775 if (!arg1) 3776 arg1 = "global"; 3777 3778 len = os_strlen(arg1) + os_strlen(arg2) + 2; 3779 arg = os_malloc(len); 3780 if (arg == NULL) 3781 return -1; 3782 os_snprintf(arg, len, "%s %s", arg1, arg2); 3783 res = os_exec(program, arg, 1); 3784 os_free(arg); 3785 3786 return res; 3787} 3788 3789 3790static void wpa_cli_action_process(const char *msg) 3791{ 3792 const char *pos; 3793 char *copy = NULL, *id, *pos2; 3794 const char *ifname = ctrl_ifname; 3795 char ifname_buf[100]; 3796 3797 if (eloop_terminated()) 3798 return; 3799 3800 pos = msg; 3801 if (os_strncmp(pos, "IFNAME=", 7) == 0) { 3802 const char *end; 3803 end = os_strchr(pos + 7, ' '); 3804 if (end && (unsigned int) (end - pos) < sizeof(ifname_buf)) { 3805 pos += 7; 3806 os_memcpy(ifname_buf, pos, end - pos); 3807 ifname_buf[end - pos] = '\0'; 3808 ifname = ifname_buf; 3809 pos = end + 1; 3810 } 3811 } 3812 if (*pos == '<') { 3813 const char *prev = pos; 3814 /* skip priority */ 3815 pos = os_strchr(pos, '>'); 3816 if (pos) 3817 pos++; 3818 else 3819 pos = prev; 3820 } 3821 3822 if (str_starts(pos, WPA_EVENT_CONNECTED)) { 3823 int new_id = -1; 3824 os_unsetenv("WPA_ID"); 3825 os_unsetenv("WPA_ID_STR"); 3826 os_unsetenv("WPA_CTRL_DIR"); 3827 3828 pos = os_strstr(pos, "[id="); 3829 if (pos) 3830 copy = os_strdup(pos + 4); 3831 3832 if (copy) { 3833 pos2 = id = copy; 3834 while (*pos2 && *pos2 != ' ') 3835 pos2++; 3836 *pos2++ = '\0'; 3837 new_id = atoi(id); 3838 os_setenv("WPA_ID", id, 1); 3839 while (*pos2 && *pos2 != '=') 3840 pos2++; 3841 if (*pos2 == '=') 3842 pos2++; 3843 id = pos2; 3844 while (*pos2 && *pos2 != ']') 3845 pos2++; 3846 *pos2 = '\0'; 3847 os_setenv("WPA_ID_STR", id, 1); 3848 os_free(copy); 3849 } 3850 3851 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1); 3852 3853 if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) { 3854 wpa_cli_connected = 1; 3855 wpa_cli_last_id = new_id; 3856 wpa_cli_exec(action_file, ifname, "CONNECTED"); 3857 } 3858 } else if (str_starts(pos, WPA_EVENT_DISCONNECTED)) { 3859 if (wpa_cli_connected) { 3860 wpa_cli_connected = 0; 3861 wpa_cli_exec(action_file, ifname, "DISCONNECTED"); 3862 } 3863 } else if (str_starts(pos, AP_EVENT_ENABLED)) { 3864 wpa_cli_exec(action_file, ctrl_ifname, pos); 3865 } else if (str_starts(pos, AP_EVENT_DISABLED)) { 3866 wpa_cli_exec(action_file, ctrl_ifname, pos); 3867 } else if (str_starts(pos, MESH_GROUP_STARTED)) { 3868 wpa_cli_exec(action_file, ctrl_ifname, pos); 3869 } else if (str_starts(pos, MESH_GROUP_REMOVED)) { 3870 wpa_cli_exec(action_file, ctrl_ifname, pos); 3871 } else if (str_starts(pos, MESH_PEER_CONNECTED)) { 3872 wpa_cli_exec(action_file, ctrl_ifname, pos); 3873 } else if (str_starts(pos, MESH_PEER_DISCONNECTED)) { 3874 wpa_cli_exec(action_file, ctrl_ifname, pos); 3875 } else if (str_starts(pos, P2P_EVENT_GROUP_STARTED)) { 3876 wpa_cli_exec(action_file, ifname, pos); 3877 } else if (str_starts(pos, P2P_EVENT_GROUP_REMOVED)) { 3878 wpa_cli_exec(action_file, ifname, pos); 3879 } else if (str_starts(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) { 3880 wpa_cli_exec(action_file, ifname, pos); 3881 } else if (str_starts(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) { 3882 wpa_cli_exec(action_file, ifname, pos); 3883 } else if (str_starts(pos, P2P_EVENT_GO_NEG_FAILURE)) { 3884 wpa_cli_exec(action_file, ifname, pos); 3885 } else if (str_starts(pos, WPS_EVENT_SUCCESS)) { 3886 wpa_cli_exec(action_file, ifname, pos); 3887 } else if (str_starts(pos, WPS_EVENT_ACTIVE)) { 3888 wpa_cli_exec(action_file, ifname, pos); 3889 } else if (str_starts(pos, WPS_EVENT_TIMEOUT)) { 3890 wpa_cli_exec(action_file, ifname, pos); 3891 } else if (str_starts(pos, WPS_EVENT_FAIL)) { 3892 wpa_cli_exec(action_file, ifname, pos); 3893 } else if (str_starts(pos, AP_STA_CONNECTED)) { 3894 wpa_cli_exec(action_file, ifname, pos); 3895 } else if (str_starts(pos, AP_STA_DISCONNECTED)) { 3896 wpa_cli_exec(action_file, ifname, pos); 3897 } else if (str_starts(pos, ESS_DISASSOC_IMMINENT)) { 3898 wpa_cli_exec(action_file, ifname, pos); 3899 } else if (str_starts(pos, HS20_SUBSCRIPTION_REMEDIATION)) { 3900 wpa_cli_exec(action_file, ifname, pos); 3901 } else if (str_starts(pos, HS20_DEAUTH_IMMINENT_NOTICE)) { 3902 wpa_cli_exec(action_file, ifname, pos); 3903 } else if (str_starts(pos, WPA_EVENT_TERMINATING)) { 3904 printf("wpa_supplicant is terminating - stop monitoring\n"); 3905 wpa_cli_quit = 1; 3906 } 3907} 3908 3909 3910#ifndef CONFIG_ANSI_C_EXTRA 3911static void wpa_cli_action_cb(char *msg, size_t len) 3912{ 3913 wpa_cli_action_process(msg); 3914} 3915#endif /* CONFIG_ANSI_C_EXTRA */ 3916 3917 3918static void wpa_cli_reconnect(void) 3919{ 3920 wpa_cli_close_connection(); 3921 if (wpa_cli_open_connection(ctrl_ifname, 1) < 0) 3922 return; 3923 3924 if (interactive) { 3925 edit_clear_line(); 3926 printf("\rConnection to wpa_supplicant re-established\n"); 3927 edit_redraw(); 3928 update_stations(ctrl_conn); 3929 } 3930} 3931 3932 3933static void cli_event(const char *str) 3934{ 3935 const char *start, *s; 3936 3937 start = os_strchr(str, '>'); 3938 if (start == NULL) 3939 return; 3940 3941 start++; 3942 3943 if (str_starts(start, WPA_EVENT_BSS_ADDED)) { 3944 s = os_strchr(start, ' '); 3945 if (s == NULL) 3946 return; 3947 s = os_strchr(s + 1, ' '); 3948 if (s == NULL) 3949 return; 3950 cli_txt_list_add(&bsses, s + 1); 3951 return; 3952 } 3953 3954 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) { 3955 s = os_strchr(start, ' '); 3956 if (s == NULL) 3957 return; 3958 s = os_strchr(s + 1, ' '); 3959 if (s == NULL) 3960 return; 3961 cli_txt_list_del_addr(&bsses, s + 1); 3962 return; 3963 } 3964 3965#ifdef CONFIG_P2P 3966 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) { 3967 s = os_strstr(start, " p2p_dev_addr="); 3968 if (s == NULL) 3969 return; 3970 cli_txt_list_add_addr(&p2p_peers, s + 14); 3971 return; 3972 } 3973 3974 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) { 3975 s = os_strstr(start, " p2p_dev_addr="); 3976 if (s == NULL) 3977 return; 3978 cli_txt_list_del_addr(&p2p_peers, s + 14); 3979 return; 3980 } 3981 3982 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) { 3983 s = os_strchr(start, ' '); 3984 if (s == NULL) 3985 return; 3986 cli_txt_list_add_word(&p2p_groups, s + 1, ' '); 3987 return; 3988 } 3989 3990 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) { 3991 s = os_strchr(start, ' '); 3992 if (s == NULL) 3993 return; 3994 cli_txt_list_del_word(&p2p_groups, s + 1, ' '); 3995 return; 3996 } 3997#endif /* CONFIG_P2P */ 3998} 3999 4000 4001static int check_terminating(const char *msg) 4002{ 4003 const char *pos = msg; 4004 4005 if (*pos == '<') { 4006 /* skip priority */ 4007 pos = os_strchr(pos, '>'); 4008 if (pos) 4009 pos++; 4010 else 4011 pos = msg; 4012 } 4013 4014 if (str_starts(pos, WPA_EVENT_TERMINATING) && ctrl_conn) { 4015 edit_clear_line(); 4016 printf("\rConnection to wpa_supplicant lost - trying to " 4017 "reconnect\n"); 4018 edit_redraw(); 4019 wpa_cli_attached = 0; 4020 wpa_cli_close_connection(); 4021 return 1; 4022 } 4023 4024 return 0; 4025} 4026 4027 4028static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor) 4029{ 4030 if (ctrl_conn == NULL) { 4031 wpa_cli_reconnect(); 4032 return; 4033 } 4034 while (wpa_ctrl_pending(ctrl) > 0) { 4035 char buf[4096]; 4036 size_t len = sizeof(buf) - 1; 4037 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) { 4038 buf[len] = '\0'; 4039 if (action_monitor) 4040 wpa_cli_action_process(buf); 4041 else { 4042 cli_event(buf); 4043 if (wpa_cli_show_event(buf)) { 4044 edit_clear_line(); 4045 printf("\r%s\n", buf); 4046 edit_redraw(); 4047 } 4048 4049 if (interactive && check_terminating(buf) > 0) 4050 return; 4051 } 4052 } else { 4053 printf("Could not read pending message.\n"); 4054 break; 4055 } 4056 } 4057 4058 if (wpa_ctrl_pending(ctrl) < 0) { 4059 printf("Connection to wpa_supplicant lost - trying to " 4060 "reconnect\n"); 4061 wpa_cli_reconnect(); 4062 } 4063} 4064 4065 4066static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx) 4067{ 4068 if (ctrl_conn) { 4069 int res; 4070 char *prefix = ifname_prefix; 4071 4072 ifname_prefix = NULL; 4073 res = _wpa_ctrl_command(ctrl_conn, "PING", 0); 4074 ifname_prefix = prefix; 4075 if (res) { 4076 printf("Connection to wpa_supplicant lost - trying to " 4077 "reconnect\n"); 4078 wpa_cli_close_connection(); 4079 } 4080 } 4081 if (!ctrl_conn) 4082 wpa_cli_reconnect(); 4083 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL); 4084} 4085 4086 4087static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx) 4088{ 4089 wpa_cli_recv_pending(mon_conn, 0); 4090} 4091 4092 4093static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd) 4094{ 4095 char *argv[max_args]; 4096 int argc; 4097 argc = tokenize_cmd(cmd, argv); 4098 if (argc) 4099 wpa_request(ctrl_conn, argc, argv); 4100} 4101 4102 4103static void wpa_cli_edit_eof_cb(void *ctx) 4104{ 4105 eloop_terminate(); 4106} 4107 4108 4109static int warning_displayed = 0; 4110static char *hfile = NULL; 4111static int edit_started = 0; 4112 4113static void start_edit(void) 4114{ 4115 char *home; 4116 char *ps = NULL; 4117 4118#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE 4119 ps = wpa_ctrl_get_remote_ifname(ctrl_conn); 4120#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */ 4121 4122#ifdef CONFIG_WPA_CLI_HISTORY_DIR 4123 home = CONFIG_WPA_CLI_HISTORY_DIR; 4124#else /* CONFIG_WPA_CLI_HISTORY_DIR */ 4125 home = getenv("HOME"); 4126#endif /* CONFIG_WPA_CLI_HISTORY_DIR */ 4127 if (home) { 4128 const char *fname = ".wpa_cli_history"; 4129 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1; 4130 hfile = os_malloc(hfile_len); 4131 if (hfile) 4132 os_snprintf(hfile, hfile_len, "%s/%s", home, fname); 4133 } 4134 4135 if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb, 4136 wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) { 4137 eloop_terminate(); 4138 return; 4139 } 4140 4141 edit_started = 1; 4142 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL); 4143} 4144 4145 4146static void update_bssid_list(struct wpa_ctrl *ctrl) 4147{ 4148 char buf[4096]; 4149 size_t len = sizeof(buf); 4150 int ret; 4151 const char *cmd = "BSS RANGE=ALL MASK=0x2"; 4152 char *pos, *end; 4153 4154 if (ctrl == NULL) 4155 return; 4156 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 4157 if (ret < 0) 4158 return; 4159 buf[len] = '\0'; 4160 4161 pos = buf; 4162 while (pos) { 4163 pos = os_strstr(pos, "bssid="); 4164 if (pos == NULL) 4165 break; 4166 pos += 6; 4167 end = os_strchr(pos, '\n'); 4168 if (end == NULL) 4169 break; 4170 *end = '\0'; 4171 cli_txt_list_add(&bsses, pos); 4172 pos = end + 1; 4173 } 4174} 4175 4176 4177static void update_ifnames(struct wpa_ctrl *ctrl) 4178{ 4179 char buf[4096]; 4180 size_t len = sizeof(buf); 4181 int ret; 4182 const char *cmd = "INTERFACES"; 4183 char *pos, *end; 4184 char txt[200]; 4185 4186 cli_txt_list_flush(&ifnames); 4187 4188 if (ctrl == NULL) 4189 return; 4190 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 4191 if (ret < 0) 4192 return; 4193 buf[len] = '\0'; 4194 4195 pos = buf; 4196 while (pos) { 4197 end = os_strchr(pos, '\n'); 4198 if (end == NULL) 4199 break; 4200 *end = '\0'; 4201 ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos); 4202 if (!os_snprintf_error(sizeof(txt), ret)) 4203 cli_txt_list_add(&ifnames, txt); 4204 pos = end + 1; 4205 } 4206} 4207 4208 4209static void update_networks(struct wpa_ctrl *ctrl) 4210{ 4211 char buf[4096]; 4212 size_t len = sizeof(buf); 4213 int ret; 4214 const char *cmd = "LIST_NETWORKS"; 4215 char *pos, *end; 4216 int header = 1; 4217 4218 cli_txt_list_flush(&networks); 4219 4220 if (ctrl == NULL) 4221 return; 4222 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL); 4223 if (ret < 0) 4224 return; 4225 buf[len] = '\0'; 4226 4227 pos = buf; 4228 while (pos) { 4229 end = os_strchr(pos, '\n'); 4230 if (end == NULL) 4231 break; 4232 *end = '\0'; 4233 if (!header) 4234 cli_txt_list_add_word(&networks, pos, '\t'); 4235 header = 0; 4236 pos = end + 1; 4237 } 4238} 4239 4240 4241static void update_stations(struct wpa_ctrl *ctrl) 4242{ 4243#ifdef CONFIG_AP 4244 char addr[32], cmd[64]; 4245 4246 if (!ctrl || !interactive) 4247 return; 4248 4249 cli_txt_list_flush(&stations); 4250 4251 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 0)) 4252 return; 4253 do { 4254 if (os_strcmp(addr, "") != 0) 4255 cli_txt_list_add(&stations, addr); 4256 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr); 4257 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 0) == 0); 4258#endif /* CONFIG_AP */ 4259} 4260 4261 4262static void try_connection(void *eloop_ctx, void *timeout_ctx) 4263{ 4264 if (ctrl_conn) 4265 goto done; 4266 4267 if (ctrl_ifname == NULL) 4268 ctrl_ifname = wpa_cli_get_default_ifname(); 4269 4270 if (wpa_cli_open_connection(ctrl_ifname, 1)) { 4271 if (!warning_displayed) { 4272 printf("Could not connect to wpa_supplicant: " 4273 "%s - re-trying\n", 4274 ctrl_ifname ? ctrl_ifname : "(nil)"); 4275 warning_displayed = 1; 4276 } 4277 eloop_register_timeout(1, 0, try_connection, NULL, NULL); 4278 return; 4279 } 4280 4281 update_bssid_list(ctrl_conn); 4282 update_networks(ctrl_conn); 4283 update_stations(ctrl_conn); 4284 4285 if (warning_displayed) 4286 printf("Connection established.\n"); 4287 4288done: 4289 start_edit(); 4290} 4291 4292 4293static void wpa_cli_interactive(void) 4294{ 4295 printf("\nInteractive mode\n\n"); 4296 4297 eloop_register_timeout(0, 0, try_connection, NULL, NULL); 4298 eloop_run(); 4299 eloop_cancel_timeout(try_connection, NULL, NULL); 4300 4301 cli_txt_list_flush(&p2p_peers); 4302 cli_txt_list_flush(&p2p_groups); 4303 cli_txt_list_flush(&bsses); 4304 cli_txt_list_flush(&ifnames); 4305 cli_txt_list_flush(&networks); 4306 if (edit_started) 4307 edit_deinit(hfile, wpa_cli_edit_filter_history_cb); 4308 os_free(hfile); 4309 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL); 4310 wpa_cli_close_connection(); 4311} 4312 4313 4314static void wpa_cli_action_ping(void *eloop_ctx, void *timeout_ctx) 4315{ 4316 struct wpa_ctrl *ctrl = eloop_ctx; 4317 char buf[256]; 4318 size_t len; 4319 4320 /* verify that connection is still working */ 4321 len = sizeof(buf) - 1; 4322 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len, 4323 wpa_cli_action_cb) < 0 || 4324 len < 4 || os_memcmp(buf, "PONG", 4) != 0) { 4325 printf("wpa_supplicant did not reply to PING command - exiting\n"); 4326 eloop_terminate(); 4327 return; 4328 } 4329 eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping, 4330 ctrl, NULL); 4331} 4332 4333 4334static void wpa_cli_action_receive(int sock, void *eloop_ctx, void *sock_ctx) 4335{ 4336 struct wpa_ctrl *ctrl = eloop_ctx; 4337 4338 wpa_cli_recv_pending(ctrl, 1); 4339} 4340 4341 4342static void wpa_cli_action(struct wpa_ctrl *ctrl) 4343{ 4344#ifdef CONFIG_ANSI_C_EXTRA 4345 /* TODO: ANSI C version(?) */ 4346 printf("Action processing not supported in ANSI C build.\n"); 4347#else /* CONFIG_ANSI_C_EXTRA */ 4348 int fd; 4349 4350 fd = wpa_ctrl_get_fd(ctrl); 4351 eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping, 4352 ctrl, NULL); 4353 eloop_register_read_sock(fd, wpa_cli_action_receive, ctrl, NULL); 4354 eloop_run(); 4355 eloop_cancel_timeout(wpa_cli_action_ping, ctrl, NULL); 4356 eloop_unregister_read_sock(fd); 4357#endif /* CONFIG_ANSI_C_EXTRA */ 4358} 4359 4360 4361static void wpa_cli_cleanup(void) 4362{ 4363 wpa_cli_close_connection(); 4364 if (pid_file) 4365 os_daemonize_terminate(pid_file); 4366 4367 os_program_deinit(); 4368} 4369 4370 4371static void wpa_cli_terminate(int sig, void *ctx) 4372{ 4373 eloop_terminate(); 4374} 4375 4376 4377static char * wpa_cli_get_default_ifname(void) 4378{ 4379 char *ifname = NULL; 4380 4381#ifdef ANDROID 4382 char ifprop[PROPERTY_VALUE_MAX]; 4383 if (property_get("wifi.interface", ifprop, NULL) != 0) { 4384 ifname = os_strdup(ifprop); 4385 printf("Using interface '%s'\n", ifname ? ifname : "N/A"); 4386 } 4387#else /* ANDROID */ 4388#ifdef CONFIG_CTRL_IFACE_UNIX 4389 struct dirent *dent; 4390 DIR *dir = opendir(ctrl_iface_dir); 4391 if (!dir) { 4392 return NULL; 4393 } 4394 while ((dent = readdir(dir))) { 4395#ifdef _DIRENT_HAVE_D_TYPE 4396 /* 4397 * Skip the file if it is not a socket. Also accept 4398 * DT_UNKNOWN (0) in case the C library or underlying 4399 * file system does not support d_type. 4400 */ 4401 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN) 4402 continue; 4403#endif /* _DIRENT_HAVE_D_TYPE */ 4404 if (os_strcmp(dent->d_name, ".") == 0 || 4405 os_strcmp(dent->d_name, "..") == 0) 4406 continue; 4407 printf("Selected interface '%s'\n", dent->d_name); 4408 ifname = os_strdup(dent->d_name); 4409 break; 4410 } 4411 closedir(dir); 4412#endif /* CONFIG_CTRL_IFACE_UNIX */ 4413 4414#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 4415 char buf[4096], *pos; 4416 size_t len; 4417 struct wpa_ctrl *ctrl; 4418 int ret; 4419 4420 ctrl = wpa_ctrl_open(NULL); 4421 if (ctrl == NULL) 4422 return NULL; 4423 4424 len = sizeof(buf) - 1; 4425 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL); 4426 if (ret >= 0) { 4427 buf[len] = '\0'; 4428 pos = os_strchr(buf, '\n'); 4429 if (pos) 4430 *pos = '\0'; 4431 ifname = os_strdup(buf); 4432 } 4433 wpa_ctrl_close(ctrl); 4434#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 4435#endif /* ANDROID */ 4436 4437 return ifname; 4438} 4439 4440 4441int main(int argc, char *argv[]) 4442{ 4443 int c; 4444 int daemonize = 0; 4445 int ret = 0; 4446 const char *global = NULL; 4447 4448 if (os_program_init()) 4449 return -1; 4450 4451 for (;;) { 4452 c = getopt(argc, argv, "a:Bg:G:hi:p:P:s:v"); 4453 if (c < 0) 4454 break; 4455 switch (c) { 4456 case 'a': 4457 action_file = optarg; 4458 break; 4459 case 'B': 4460 daemonize = 1; 4461 break; 4462 case 'g': 4463 global = optarg; 4464 break; 4465 case 'G': 4466 ping_interval = atoi(optarg); 4467 break; 4468 case 'h': 4469 usage(); 4470 return 0; 4471 case 'v': 4472 printf("%s\n", wpa_cli_version); 4473 return 0; 4474 case 'i': 4475 os_free(ctrl_ifname); 4476 ctrl_ifname = os_strdup(optarg); 4477 break; 4478 case 'p': 4479 ctrl_iface_dir = optarg; 4480 break; 4481 case 'P': 4482 pid_file = optarg; 4483 break; 4484 case 's': 4485 client_socket_dir = optarg; 4486 break; 4487 default: 4488 usage(); 4489 return -1; 4490 } 4491 } 4492 4493 interactive = (argc == optind) && (action_file == NULL); 4494 4495 if (interactive) 4496 printf("%s\n\n%s\n\n", wpa_cli_version, cli_license); 4497 4498 if (eloop_init()) 4499 return -1; 4500 4501 if (global) { 4502#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 4503 ctrl_conn = wpa_ctrl_open(NULL); 4504#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 4505 ctrl_conn = wpa_ctrl_open(global); 4506#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 4507 if (ctrl_conn == NULL) { 4508 fprintf(stderr, "Failed to connect to wpa_supplicant " 4509 "global interface: %s error: %s\n", 4510 global, strerror(errno)); 4511 return -1; 4512 } 4513 4514 if (interactive) { 4515 update_ifnames(ctrl_conn); 4516 mon_conn = wpa_ctrl_open(global); 4517 if (mon_conn) { 4518 if (wpa_ctrl_attach(mon_conn) == 0) { 4519 wpa_cli_attached = 1; 4520 eloop_register_read_sock( 4521 wpa_ctrl_get_fd(mon_conn), 4522 wpa_cli_mon_receive, 4523 NULL, NULL); 4524 } else { 4525 printf("Failed to open monitor " 4526 "connection through global " 4527 "control interface\n"); 4528 } 4529 } 4530 update_stations(ctrl_conn); 4531 } 4532 } 4533 4534 eloop_register_signal_terminate(wpa_cli_terminate, NULL); 4535 4536 if (ctrl_ifname == NULL) 4537 ctrl_ifname = wpa_cli_get_default_ifname(); 4538 4539 if (interactive) { 4540 wpa_cli_interactive(); 4541 } else { 4542 if (!global && 4543 wpa_cli_open_connection(ctrl_ifname, 0) < 0) { 4544 fprintf(stderr, "Failed to connect to non-global " 4545 "ctrl_ifname: %s error: %s\n", 4546 ctrl_ifname ? ctrl_ifname : "(nil)", 4547 strerror(errno)); 4548 return -1; 4549 } 4550 4551 if (action_file) { 4552 if (wpa_ctrl_attach(ctrl_conn) == 0) { 4553 wpa_cli_attached = 1; 4554 } else { 4555 printf("Warning: Failed to attach to " 4556 "wpa_supplicant.\n"); 4557 return -1; 4558 } 4559 } 4560 4561 if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue()) 4562 return -1; 4563 4564 if (action_file) 4565 wpa_cli_action(ctrl_conn); 4566 else 4567 ret = wpa_request(ctrl_conn, argc - optind, 4568 &argv[optind]); 4569 } 4570 4571 os_free(ctrl_ifname); 4572 eloop_destroy(); 4573 wpa_cli_cleanup(); 4574 4575 return ret; 4576} 4577 4578#else /* CONFIG_CTRL_IFACE */ 4579int main(int argc, char *argv[]) 4580{ 4581 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n"); 4582 return -1; 4583} 4584#endif /* CONFIG_CTRL_IFACE */ 4585