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