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