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