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