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