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