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