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