1 /* 2 * WPA Supplicant - command line interface for wpa_supplicant daemon 3 * Copyright (c) 2004-2009, Jouni Malinen <j (at) 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 #ifdef CONFIG_READLINE 23 #include <readline/readline.h> 24 #include <readline/history.h> 25 #endif /* CONFIG_READLINE */ 26 27 #define CTRL_INTERFACE_2_SOCKETS 28 29 #include "wpa_ctrl.h" 30 #include "common.h" 31 #include "version.h" 32 #ifdef ANDROID 33 #include <cutils/properties.h> 34 #endif 35 36 37 static const char *wpa_cli_version = 38 "wpa_cli v" VERSION_STR "\n" 39 "Copyright (c) 2004-2009, Jouni Malinen <j (at) w1.fi> and contributors"; 40 41 42 static const char *wpa_cli_license = 43 "This program is free software. You can distribute it and/or modify it\n" 44 "under the terms of the GNU General Public License version 2.\n" 45 "\n" 46 "Alternatively, this software may be distributed under the terms of the\n" 47 "BSD license. See README and COPYING for more details.\n"; 48 49 static const char *wpa_cli_full_license = 50 "This program is free software; you can redistribute it and/or modify\n" 51 "it under the terms of the GNU General Public License version 2 as\n" 52 "published by the Free Software Foundation.\n" 53 "\n" 54 "This program is distributed in the hope that it will be useful,\n" 55 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 56 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" 57 "GNU General Public License for more details.\n" 58 "\n" 59 "You should have received a copy of the GNU General Public License\n" 60 "along with this program; if not, write to the Free Software\n" 61 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n" 62 "\n" 63 "Alternatively, this software may be distributed under the terms of the\n" 64 "BSD license.\n" 65 "\n" 66 "Redistribution and use in source and binary forms, with or without\n" 67 "modification, are permitted provided that the following conditions are\n" 68 "met:\n" 69 "\n" 70 "1. Redistributions of source code must retain the above copyright\n" 71 " notice, this list of conditions and the following disclaimer.\n" 72 "\n" 73 "2. Redistributions in binary form must reproduce the above copyright\n" 74 " notice, this list of conditions and the following disclaimer in the\n" 75 " documentation and/or other materials provided with the distribution.\n" 76 "\n" 77 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n" 78 " names of its contributors may be used to endorse or promote products\n" 79 " derived from this software without specific prior written permission.\n" 80 "\n" 81 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n" 82 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n" 83 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n" 84 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n" 85 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n" 86 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n" 87 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n" 88 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n" 89 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" 90 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n" 91 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" 92 "\n"; 93 94 static struct wpa_ctrl *ctrl_conn; 95 static struct wpa_ctrl *monitor_conn; 96 static int wpa_cli_quit = 0; 97 static int wpa_cli_attached = 0; 98 static int wpa_cli_connected = 0; 99 static int wpa_cli_last_id = 0; 100 #ifdef ANDROID 101 static const char *ctrl_iface_dir = "/data/system/wpa_supplicant"; 102 #else 103 static const char *ctrl_iface_dir = "/var/run/wpa_supplicant"; 104 #endif 105 static char *ctrl_ifname = NULL; 106 static const char *pid_file = NULL; 107 static const char *action_file = NULL; 108 static int ping_interval = 5; 109 110 111 static void print_help(); 112 113 114 static void usage(void) 115 { 116 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] " 117 "[-a<action file>] \\\n" 118 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] " 119 "[command..]\n" 120 " -h = help (show this usage text)\n" 121 " -v = shown version information\n" 122 " -a = run in daemon mode executing the action file based on " 123 "events from\n" 124 " wpa_supplicant\n" 125 " -B = run a daemon in the background\n" 126 " default path: /var/run/wpa_supplicant\n" 127 " default interface: first interface found in socket path\n"); 128 print_help(); 129 } 130 131 132 static struct wpa_ctrl * wpa_cli_open_connection(const char *ifname) 133 { 134 struct wpa_ctrl *cur_conn; 135 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE) 136 cur_conn = wpa_ctrl_open(ifname); 137 return cur_conn; 138 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ 139 char *cfile; 140 int flen, res; 141 142 if (ifname == NULL) 143 return NULL; 144 145 #ifdef ANDROID 146 if (access(ctrl_iface_dir, F_OK) < 0) 147 cfile = (char *)ifname; 148 else { 149 #endif 150 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2; 151 cfile = os_malloc(flen); 152 if (cfile == NULL) 153 return NULL; 154 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname); 155 if (res < 0 || res >= flen) { 156 os_free(cfile); 157 return NULL; 158 } 159 #ifdef ANDROID 160 } 161 #endif 162 163 cur_conn = wpa_ctrl_open(cfile); 164 #ifdef CTRL_INTERFACE_2_SOCKETS 165 monitor_conn = wpa_ctrl_open(cfile); 166 #else 167 monitor_conn = cur_conn; 168 #endif 169 #ifdef ANDROID 170 if (cfile != ifname) 171 #endif 172 os_free(cfile); 173 return cur_conn; 174 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ 175 } 176 177 178 static void wpa_cli_close_connection(void) 179 { 180 if (ctrl_conn == NULL) 181 return; 182 183 if (wpa_cli_attached) { 184 wpa_ctrl_detach(monitor_conn); 185 wpa_cli_attached = 0; 186 } 187 #ifdef CTRL_INTERFACE_2_SOCKETS 188 wpa_ctrl_close(monitor_conn); 189 #endif 190 wpa_ctrl_close(ctrl_conn); 191 ctrl_conn = monitor_conn = NULL; 192 } 193 194 195 static void wpa_cli_msg_cb(char *msg, size_t len) 196 { 197 printf("%s\n", msg); 198 } 199 200 201 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print) 202 { 203 char buf[4096]; 204 size_t len; 205 int ret; 206 207 if (ctrl_conn == NULL) { 208 printf("Not connected to wpa_supplicant - command dropped.\n"); 209 return -1; 210 } 211 len = sizeof(buf) - 1; 212 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, 213 wpa_cli_msg_cb); 214 if (ret == -2) { 215 printf("'%s' command timed out.\n", cmd); 216 return -2; 217 } else if (ret < 0) { 218 printf("'%s' command failed.\n", cmd); 219 return -1; 220 } 221 if (print) { 222 buf[len] = '\0'; 223 printf("%s", buf); 224 } 225 return 0; 226 } 227 228 229 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd) 230 { 231 return _wpa_ctrl_command(ctrl, cmd, 1); 232 } 233 234 235 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[]) 236 { 237 int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0; 238 return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS"); 239 } 240 241 242 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[]) 243 { 244 return wpa_ctrl_command(ctrl, "PING"); 245 } 246 247 248 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[]) 249 { 250 return wpa_ctrl_command(ctrl, "MIB"); 251 } 252 253 254 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[]) 255 { 256 return wpa_ctrl_command(ctrl, "PMKSA"); 257 } 258 259 260 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[]) 261 { 262 print_help(); 263 return 0; 264 } 265 266 267 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[]) 268 { 269 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license); 270 return 0; 271 } 272 273 274 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[]) 275 { 276 wpa_cli_quit = 1; 277 return 0; 278 } 279 280 281 static void wpa_cli_show_variables(void) 282 { 283 printf("set variables:\n" 284 " EAPOL::heldPeriod (EAPOL state machine held period, " 285 "in seconds)\n" 286 " EAPOL::authPeriod (EAPOL state machine authentication " 287 "period, in seconds)\n" 288 " EAPOL::startPeriod (EAPOL state machine start period, in " 289 "seconds)\n" 290 " EAPOL::maxStart (EAPOL state machine maximum start " 291 "attempts)\n"); 292 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in " 293 "seconds)\n" 294 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication" 295 " threshold\n\tpercentage)\n" 296 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing " 297 "security\n\tassociation in seconds)\n"); 298 } 299 300 301 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[]) 302 { 303 char cmd[256]; 304 int res; 305 306 if (argc == 0) { 307 wpa_cli_show_variables(); 308 return 0; 309 } 310 311 if (argc != 2) { 312 printf("Invalid SET command: needs two arguments (variable " 313 "name and value)\n"); 314 return -1; 315 } 316 317 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]); 318 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 319 printf("Too long SET command.\n"); 320 return -1; 321 } 322 return wpa_ctrl_command(ctrl, cmd); 323 } 324 325 326 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[]) 327 { 328 return wpa_ctrl_command(ctrl, "LOGOFF"); 329 } 330 331 332 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[]) 333 { 334 return wpa_ctrl_command(ctrl, "LOGON"); 335 } 336 337 338 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc, 339 char *argv[]) 340 { 341 return wpa_ctrl_command(ctrl, "REASSOCIATE"); 342 } 343 344 345 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc, 346 char *argv[]) 347 { 348 char cmd[256]; 349 int res; 350 351 if (argc != 1) { 352 printf("Invalid PREAUTH command: needs one argument " 353 "(BSSID)\n"); 354 return -1; 355 } 356 357 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]); 358 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 359 printf("Too long PREAUTH command.\n"); 360 return -1; 361 } 362 return wpa_ctrl_command(ctrl, cmd); 363 } 364 365 366 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 367 { 368 char cmd[256]; 369 int res; 370 371 if (argc != 1) { 372 printf("Invalid AP_SCAN command: needs one argument (ap_scan " 373 "value)\n"); 374 return -1; 375 } 376 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]); 377 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 378 printf("Too long AP_SCAN command.\n"); 379 return -1; 380 } 381 return wpa_ctrl_command(ctrl, cmd); 382 } 383 384 385 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc, 386 char *argv[]) 387 { 388 char cmd[256]; 389 int res; 390 391 if (argc != 1) { 392 printf("Invalid STKSTART command: needs one argument " 393 "(Peer STA MAC address)\n"); 394 return -1; 395 } 396 397 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]); 398 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 399 printf("Too long STKSTART command.\n"); 400 return -1; 401 } 402 return wpa_ctrl_command(ctrl, cmd); 403 } 404 405 406 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[]) 407 { 408 char cmd[256]; 409 int res; 410 411 if (argc != 1) { 412 printf("Invalid FT_DS command: needs one argument " 413 "(Target AP MAC address)\n"); 414 return -1; 415 } 416 417 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]); 418 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 419 printf("Too long FT_DS command.\n"); 420 return -1; 421 } 422 return wpa_ctrl_command(ctrl, cmd); 423 } 424 425 426 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[]) 427 { 428 char cmd[256]; 429 int res; 430 431 if (argc == 0) { 432 /* Any BSSID */ 433 return wpa_ctrl_command(ctrl, "WPS_PBC"); 434 } 435 436 /* Specific BSSID */ 437 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]); 438 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 439 printf("Too long WPS_PBC command.\n"); 440 return -1; 441 } 442 return wpa_ctrl_command(ctrl, cmd); 443 } 444 445 446 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) 447 { 448 char cmd[256]; 449 int res; 450 451 if (argc == 0) { 452 printf("Invalid WPS_PIN command: need one or two arguments:\n" 453 "- BSSID: use 'any' to select any\n" 454 "- PIN: optional, used only with devices that have no " 455 "display\n"); 456 return -1; 457 } 458 459 if (argc == 1) { 460 /* Use dynamically generated PIN (returned as reply) */ 461 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]); 462 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 463 printf("Too long WPS_PIN command.\n"); 464 return -1; 465 } 466 return wpa_ctrl_command(ctrl, cmd); 467 } 468 469 /* Use hardcoded PIN from a label */ 470 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]); 471 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 472 printf("Too long WPS_PIN command.\n"); 473 return -1; 474 } 475 return wpa_ctrl_command(ctrl, cmd); 476 } 477 478 479 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[]) 480 { 481 char cmd[256]; 482 int res; 483 484 if (argc != 2) { 485 printf("Invalid WPS_REG command: need two arguments:\n" 486 "- BSSID: use 'any' to select any\n" 487 "- AP PIN\n"); 488 return -1; 489 } 490 491 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s", argv[0], argv[1]); 492 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 493 printf("Too long WPS_REG command.\n"); 494 return -1; 495 } 496 return wpa_ctrl_command(ctrl, cmd); 497 } 498 499 500 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) 501 { 502 char cmd[256]; 503 int res; 504 505 if (argc != 1) { 506 printf("Invalid LEVEL command: needs one argument (debug " 507 "level)\n"); 508 return -1; 509 } 510 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]); 511 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 512 printf("Too long LEVEL command.\n"); 513 return -1; 514 } 515 return wpa_ctrl_command(ctrl, cmd); 516 } 517 518 519 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[]) 520 { 521 char cmd[256], *pos, *end; 522 int i, ret; 523 524 if (argc < 2) { 525 printf("Invalid IDENTITY command: needs two arguments " 526 "(network id and identity)\n"); 527 return -1; 528 } 529 530 end = cmd + sizeof(cmd); 531 pos = cmd; 532 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s", 533 argv[0], argv[1]); 534 if (ret < 0 || ret >= end - pos) { 535 printf("Too long IDENTITY command.\n"); 536 return -1; 537 } 538 pos += ret; 539 for (i = 2; i < argc; i++) { 540 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 541 if (ret < 0 || ret >= end - pos) { 542 printf("Too long IDENTITY command.\n"); 543 return -1; 544 } 545 pos += ret; 546 } 547 548 return wpa_ctrl_command(ctrl, cmd); 549 } 550 551 552 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[]) 553 { 554 char cmd[256], *pos, *end; 555 int i, ret; 556 557 if (argc < 2) { 558 printf("Invalid PASSWORD command: needs two arguments " 559 "(network id and password)\n"); 560 return -1; 561 } 562 563 end = cmd + sizeof(cmd); 564 pos = cmd; 565 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s", 566 argv[0], argv[1]); 567 if (ret < 0 || ret >= end - pos) { 568 printf("Too long PASSWORD command.\n"); 569 return -1; 570 } 571 pos += ret; 572 for (i = 2; i < argc; i++) { 573 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 574 if (ret < 0 || ret >= end - pos) { 575 printf("Too long PASSWORD command.\n"); 576 return -1; 577 } 578 pos += ret; 579 } 580 581 return wpa_ctrl_command(ctrl, cmd); 582 } 583 584 585 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc, 586 char *argv[]) 587 { 588 char cmd[256], *pos, *end; 589 int i, ret; 590 591 if (argc < 2) { 592 printf("Invalid NEW_PASSWORD command: needs two arguments " 593 "(network id and password)\n"); 594 return -1; 595 } 596 597 end = cmd + sizeof(cmd); 598 pos = cmd; 599 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s", 600 argv[0], argv[1]); 601 if (ret < 0 || ret >= end - pos) { 602 printf("Too long NEW_PASSWORD command.\n"); 603 return -1; 604 } 605 pos += ret; 606 for (i = 2; i < argc; i++) { 607 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 608 if (ret < 0 || ret >= end - pos) { 609 printf("Too long NEW_PASSWORD command.\n"); 610 return -1; 611 } 612 pos += ret; 613 } 614 615 return wpa_ctrl_command(ctrl, cmd); 616 } 617 618 619 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[]) 620 { 621 char cmd[256], *pos, *end; 622 int i, ret; 623 624 if (argc < 2) { 625 printf("Invalid PIN command: needs two arguments " 626 "(network id and pin)\n"); 627 return -1; 628 } 629 630 end = cmd + sizeof(cmd); 631 pos = cmd; 632 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s", 633 argv[0], argv[1]); 634 if (ret < 0 || ret >= end - pos) { 635 printf("Too long PIN command.\n"); 636 return -1; 637 } 638 pos += ret; 639 for (i = 2; i < argc; i++) { 640 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 641 if (ret < 0 || ret >= end - pos) { 642 printf("Too long PIN command.\n"); 643 return -1; 644 } 645 pos += ret; 646 } 647 return wpa_ctrl_command(ctrl, cmd); 648 } 649 650 651 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[]) 652 { 653 char cmd[256], *pos, *end; 654 int i, ret; 655 656 if (argc < 2) { 657 printf("Invalid OTP command: needs two arguments (network " 658 "id and password)\n"); 659 return -1; 660 } 661 662 end = cmd + sizeof(cmd); 663 pos = cmd; 664 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s", 665 argv[0], argv[1]); 666 if (ret < 0 || ret >= end - pos) { 667 printf("Too long OTP command.\n"); 668 return -1; 669 } 670 pos += ret; 671 for (i = 2; i < argc; i++) { 672 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 673 if (ret < 0 || ret >= end - pos) { 674 printf("Too long OTP command.\n"); 675 return -1; 676 } 677 pos += ret; 678 } 679 680 return wpa_ctrl_command(ctrl, cmd); 681 } 682 683 684 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc, 685 char *argv[]) 686 { 687 char cmd[256], *pos, *end; 688 int i, ret; 689 690 if (argc < 2) { 691 printf("Invalid PASSPHRASE command: needs two arguments " 692 "(network id and passphrase)\n"); 693 return -1; 694 } 695 696 end = cmd + sizeof(cmd); 697 pos = cmd; 698 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s", 699 argv[0], argv[1]); 700 if (ret < 0 || ret >= end - pos) { 701 printf("Too long PASSPHRASE command.\n"); 702 return -1; 703 } 704 pos += ret; 705 for (i = 2; i < argc; i++) { 706 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 707 if (ret < 0 || ret >= end - pos) { 708 printf("Too long PASSPHRASE command.\n"); 709 return -1; 710 } 711 pos += ret; 712 } 713 714 return wpa_ctrl_command(ctrl, cmd); 715 } 716 717 718 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[]) 719 { 720 char cmd[256], *pos, *end; 721 int i, ret; 722 723 if (argc < 2) { 724 printf("Invalid BSSID command: needs two arguments (network " 725 "id and BSSID)\n"); 726 return -1; 727 } 728 729 end = cmd + sizeof(cmd); 730 pos = cmd; 731 ret = os_snprintf(pos, end - pos, "BSSID"); 732 if (ret < 0 || ret >= end - pos) { 733 printf("Too long BSSID command.\n"); 734 return -1; 735 } 736 pos += ret; 737 for (i = 0; i < argc; i++) { 738 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 739 if (ret < 0 || ret >= end - pos) { 740 printf("Too long BSSID command.\n"); 741 return -1; 742 } 743 pos += ret; 744 } 745 746 return wpa_ctrl_command(ctrl, cmd); 747 } 748 749 750 #ifdef ANDROID 751 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc, 752 char *argv[]) 753 { 754 char cmd[256]; 755 int res; 756 757 if (argc != 1) { 758 printf("Invalid SCAN_INTERVAL command: needs one argument " 759 "scan_interval value)\n"); 760 return -1; 761 } 762 res = os_snprintf(cmd, sizeof(cmd), "SCAN_INTERVAL %s", argv[0]); 763 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 764 printf("Too long SCAN_INTERVAL command.\n"); 765 return -1; 766 } 767 return wpa_ctrl_command(ctrl, cmd); 768 } 769 770 771 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[]) 772 { 773 char cmd[256], *pos, *end; 774 int i, ret; 775 776 end = cmd + sizeof(cmd); 777 pos = cmd; 778 ret = os_snprintf(pos, end - pos, "BLACKLIST"); 779 if (ret < 0 || ret >= end - pos) { 780 printf("Too long BLACKLIST command.\n"); 781 return -1; 782 } 783 pos += ret; 784 for (i = 0; i < argc; i++) { 785 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 786 if (ret < 0 || ret >= end - pos) { 787 printf("Too long BLACKLIST command.\n"); 788 return -1; 789 } 790 pos += ret; 791 } 792 793 return wpa_ctrl_command(ctrl, cmd); 794 } 795 796 797 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) 798 { 799 char cmd[256], *pos, *end; 800 int i, ret; 801 802 end = cmd + sizeof(cmd); 803 pos = cmd; 804 ret = os_snprintf(pos, end - pos, "LOG_LEVEL"); 805 if (ret < 0 || ret >= end - pos) { 806 printf("Too long LOG_LEVEL command.\n"); 807 return -1; 808 } 809 pos += ret; 810 for (i = 0; i < argc; i++) { 811 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 812 if (ret < 0 || ret >= end - pos) { 813 printf("Too long LOG_LEVEL command.\n"); 814 return -1; 815 } 816 pos += ret; 817 } 818 819 return wpa_ctrl_command(ctrl, cmd); 820 } 821 #endif /* ANDROID */ 822 823 824 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc, 825 char *argv[]) 826 { 827 return wpa_ctrl_command(ctrl, "LIST_NETWORKS"); 828 } 829 830 831 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc, 832 char *argv[]) 833 { 834 char cmd[32]; 835 int res; 836 837 if (argc < 1) { 838 printf("Invalid SELECT_NETWORK command: needs one argument " 839 "(network id)\n"); 840 return -1; 841 } 842 843 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]); 844 if (res < 0 || (size_t) res >= sizeof(cmd)) 845 return -1; 846 cmd[sizeof(cmd) - 1] = '\0'; 847 848 return wpa_ctrl_command(ctrl, cmd); 849 } 850 851 852 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc, 853 char *argv[]) 854 { 855 char cmd[32]; 856 int res; 857 858 if (argc < 1) { 859 printf("Invalid ENABLE_NETWORK command: needs one argument " 860 "(network id)\n"); 861 return -1; 862 } 863 864 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]); 865 if (res < 0 || (size_t) res >= sizeof(cmd)) 866 return -1; 867 cmd[sizeof(cmd) - 1] = '\0'; 868 869 return wpa_ctrl_command(ctrl, cmd); 870 } 871 872 873 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc, 874 char *argv[]) 875 { 876 char cmd[32]; 877 int res; 878 879 if (argc < 1) { 880 printf("Invalid DISABLE_NETWORK command: needs one argument " 881 "(network id)\n"); 882 return -1; 883 } 884 885 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]); 886 if (res < 0 || (size_t) res >= sizeof(cmd)) 887 return -1; 888 cmd[sizeof(cmd) - 1] = '\0'; 889 890 return wpa_ctrl_command(ctrl, cmd); 891 } 892 893 894 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc, 895 char *argv[]) 896 { 897 return wpa_ctrl_command(ctrl, "ADD_NETWORK"); 898 } 899 900 901 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc, 902 char *argv[]) 903 { 904 char cmd[32]; 905 int res; 906 907 if (argc < 1) { 908 printf("Invalid REMOVE_NETWORK command: needs one argument " 909 "(network id)\n"); 910 return -1; 911 } 912 913 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]); 914 if (res < 0 || (size_t) res >= sizeof(cmd)) 915 return -1; 916 cmd[sizeof(cmd) - 1] = '\0'; 917 918 return wpa_ctrl_command(ctrl, cmd); 919 } 920 921 922 static void wpa_cli_show_network_variables(void) 923 { 924 printf("set_network variables:\n" 925 " ssid (network name, SSID)\n" 926 " psk (WPA passphrase or pre-shared key)\n" 927 " key_mgmt (key management protocol)\n" 928 " identity (EAP identity)\n" 929 " password (EAP password)\n" 930 " ...\n" 931 "\n" 932 "Note: Values are entered in the same format as the " 933 "configuration file is using,\n" 934 "i.e., strings values need to be inside double quotation " 935 "marks.\n" 936 "For example: set_network 1 ssid \"network name\"\n" 937 "\n" 938 "Please see wpa_supplicant.conf documentation for full list " 939 "of\navailable variables.\n"); 940 } 941 942 943 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc, 944 char *argv[]) 945 { 946 char cmd[256]; 947 int res; 948 949 if (argc == 0) { 950 wpa_cli_show_network_variables(); 951 return 0; 952 } 953 954 if (argc != 3) { 955 printf("Invalid SET_NETWORK command: needs three arguments\n" 956 "(network id, variable name, and value)\n"); 957 return -1; 958 } 959 960 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s", 961 argv[0], argv[1], argv[2]); 962 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 963 printf("Too long SET_NETWORK command.\n"); 964 return -1; 965 } 966 return wpa_ctrl_command(ctrl, cmd); 967 } 968 969 970 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc, 971 char *argv[]) 972 { 973 char cmd[256]; 974 int res; 975 976 if (argc == 0) { 977 wpa_cli_show_network_variables(); 978 return 0; 979 } 980 981 if (argc != 2) { 982 printf("Invalid GET_NETWORK command: needs two arguments\n" 983 "(network id and variable name)\n"); 984 return -1; 985 } 986 987 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s", 988 argv[0], argv[1]); 989 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 990 printf("Too long GET_NETWORK command.\n"); 991 return -1; 992 } 993 return wpa_ctrl_command(ctrl, cmd); 994 } 995 996 997 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc, 998 char *argv[]) 999 { 1000 return wpa_ctrl_command(ctrl, "DISCONNECT"); 1001 } 1002 1003 1004 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc, 1005 char *argv[]) 1006 { 1007 return wpa_ctrl_command(ctrl, "RECONNECT"); 1008 } 1009 1010 1011 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc, 1012 char *argv[]) 1013 { 1014 return wpa_ctrl_command(ctrl, "SAVE_CONFIG"); 1015 } 1016 1017 1018 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1019 { 1020 return wpa_ctrl_command(ctrl, "SCAN"); 1021 } 1022 1023 1024 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc, 1025 char *argv[]) 1026 { 1027 return wpa_ctrl_command(ctrl, "SCAN_RESULTS"); 1028 } 1029 1030 1031 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1032 { 1033 char cmd[64]; 1034 int res; 1035 1036 if (argc != 1) { 1037 printf("Invalid BSS command: need one argument (index or " 1038 "BSSID)\n"); 1039 return -1; 1040 } 1041 1042 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]); 1043 if (res < 0 || (size_t) res >= sizeof(cmd)) 1044 return -1; 1045 cmd[sizeof(cmd) - 1] = '\0'; 1046 1047 return wpa_ctrl_command(ctrl, cmd); 1048 } 1049 1050 1051 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc, 1052 char *argv[]) 1053 { 1054 char cmd[64]; 1055 int res; 1056 1057 if (argc < 1 || argc > 2) { 1058 printf("Invalid GET_CAPABILITY command: need either one or " 1059 "two arguments\n"); 1060 return -1; 1061 } 1062 1063 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) { 1064 printf("Invalid GET_CAPABILITY command: second argument, " 1065 "if any, must be 'strict'\n"); 1066 return -1; 1067 } 1068 1069 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0], 1070 (argc == 2) ? " strict" : ""); 1071 if (res < 0 || (size_t) res >= sizeof(cmd)) 1072 return -1; 1073 cmd[sizeof(cmd) - 1] = '\0'; 1074 1075 return wpa_ctrl_command(ctrl, cmd); 1076 } 1077 1078 1079 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl) 1080 { 1081 printf("Available interfaces:\n"); 1082 return wpa_ctrl_command(ctrl, "INTERFACES"); 1083 } 1084 1085 1086 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1087 { 1088 if (argc < 1) { 1089 wpa_cli_list_interfaces(ctrl); 1090 return 0; 1091 } 1092 1093 wpa_cli_close_connection(); 1094 os_free(ctrl_ifname); 1095 ctrl_ifname = os_strdup(argv[0]); 1096 1097 if ((ctrl_conn = wpa_cli_open_connection(ctrl_ifname)) != NULL) { 1098 printf("Connected to interface '%s.\n", ctrl_ifname); 1099 if (wpa_ctrl_attach(monitor_conn) == 0) { 1100 wpa_cli_attached = 1; 1101 } else { 1102 printf("Warning: Failed to attach to " 1103 "wpa_supplicant.\n"); 1104 } 1105 } else { 1106 printf("Could not connect to interface '%s' - re-trying\n", 1107 ctrl_ifname); 1108 } 1109 return 0; 1110 } 1111 1112 1113 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc, 1114 char *argv[]) 1115 { 1116 return wpa_ctrl_command(ctrl, "RECONFIGURE"); 1117 } 1118 1119 1120 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc, 1121 char *argv[]) 1122 { 1123 return wpa_ctrl_command(ctrl, "TERMINATE"); 1124 } 1125 1126 1127 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc, 1128 char *argv[]) 1129 { 1130 char cmd[256]; 1131 int res; 1132 1133 if (argc < 1) { 1134 printf("Invalid INTERFACE_ADD command: needs at least one " 1135 "argument (interface name)\n" 1136 "All arguments: ifname confname driver ctrl_interface " 1137 "driver_param bridge_name\n"); 1138 return -1; 1139 } 1140 1141 /* 1142 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB 1143 * <driver_param>TAB<bridge_name> 1144 */ 1145 res = os_snprintf(cmd, sizeof(cmd), 1146 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s", 1147 argv[0], 1148 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "", 1149 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "", 1150 argc > 5 ? argv[5] : ""); 1151 if (res < 0 || (size_t) res >= sizeof(cmd)) 1152 return -1; 1153 cmd[sizeof(cmd) - 1] = '\0'; 1154 return wpa_ctrl_command(ctrl, cmd); 1155 } 1156 1157 1158 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc, 1159 char *argv[]) 1160 { 1161 char cmd[128]; 1162 int res; 1163 1164 if (argc != 1) { 1165 printf("Invalid INTERFACE_REMOVE command: needs one argument " 1166 "(interface name)\n"); 1167 return -1; 1168 } 1169 1170 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]); 1171 if (res < 0 || (size_t) res >= sizeof(cmd)) 1172 return -1; 1173 cmd[sizeof(cmd) - 1] = '\0'; 1174 return wpa_ctrl_command(ctrl, cmd); 1175 } 1176 1177 1178 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc, 1179 char *argv[]) 1180 { 1181 return wpa_ctrl_command(ctrl, "INTERFACE_LIST"); 1182 } 1183 1184 1185 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, 1186 char *argv[]) 1187 { 1188 char cmd[32]; 1189 1190 if (argc < 1) { 1191 printf("Invalid DRIVER command: needs one argument (cmd)\n"); 1192 return -1; 1193 } 1194 1195 if (argc > 1) 1196 os_snprintf(cmd, sizeof(cmd), "DRIVER %s %s", argv[0], argv[1]); 1197 else 1198 os_snprintf(cmd, sizeof(cmd), "DRIVER %s", argv[0]); 1199 cmd[sizeof(cmd) - 1] = '\0'; 1200 1201 return wpa_ctrl_command(ctrl, cmd); 1202 } 1203 1204 1205 enum wpa_cli_cmd_flags { 1206 cli_cmd_flag_none = 0x00, 1207 cli_cmd_flag_sensitive = 0x01 1208 }; 1209 1210 struct wpa_cli_cmd { 1211 const char *cmd; 1212 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]); 1213 enum wpa_cli_cmd_flags flags; 1214 const char *usage; 1215 }; 1216 1217 static struct wpa_cli_cmd wpa_cli_commands[] = { 1218 { "status", wpa_cli_cmd_status, 1219 cli_cmd_flag_none, 1220 "[verbose] = get current WPA/EAPOL/EAP status" }, 1221 { "ping", wpa_cli_cmd_ping, 1222 cli_cmd_flag_none, 1223 "= pings wpa_supplicant" }, 1224 { "mib", wpa_cli_cmd_mib, 1225 cli_cmd_flag_none, 1226 "= get MIB variables (dot1x, dot11)" }, 1227 { "help", wpa_cli_cmd_help, 1228 cli_cmd_flag_none, 1229 "= show this usage help" }, 1230 { "interface", wpa_cli_cmd_interface, 1231 cli_cmd_flag_none, 1232 "[ifname] = show interfaces/select interface" }, 1233 { "level", wpa_cli_cmd_level, 1234 cli_cmd_flag_none, 1235 "<debug level> = change debug level" }, 1236 { "license", wpa_cli_cmd_license, 1237 cli_cmd_flag_none, 1238 "= show full wpa_cli license" }, 1239 { "quit", wpa_cli_cmd_quit, 1240 cli_cmd_flag_none, 1241 "= exit wpa_cli" }, 1242 { "set", wpa_cli_cmd_set, 1243 cli_cmd_flag_none, 1244 "= set variables (shows list of variables when run without " 1245 "arguments)" }, 1246 { "logon", wpa_cli_cmd_logon, 1247 cli_cmd_flag_none, 1248 "= IEEE 802.1X EAPOL state machine logon" }, 1249 { "logoff", wpa_cli_cmd_logoff, 1250 cli_cmd_flag_none, 1251 "= IEEE 802.1X EAPOL state machine logoff" }, 1252 { "pmksa", wpa_cli_cmd_pmksa, 1253 cli_cmd_flag_none, 1254 "= show PMKSA cache" }, 1255 { "reassociate", wpa_cli_cmd_reassociate, 1256 cli_cmd_flag_none, 1257 "= force reassociation" }, 1258 { "preauthenticate", wpa_cli_cmd_preauthenticate, 1259 cli_cmd_flag_none, 1260 "<BSSID> = force preauthentication" }, 1261 { "identity", wpa_cli_cmd_identity, 1262 cli_cmd_flag_none, 1263 "<network id> <identity> = configure identity for an SSID" }, 1264 { "password", wpa_cli_cmd_password, 1265 cli_cmd_flag_sensitive, 1266 "<network id> <password> = configure password for an SSID" }, 1267 { "new_password", wpa_cli_cmd_new_password, 1268 cli_cmd_flag_sensitive, 1269 "<network id> <password> = change password for an SSID" }, 1270 { "pin", wpa_cli_cmd_pin, 1271 cli_cmd_flag_sensitive, 1272 "<network id> <pin> = configure pin for an SSID" }, 1273 { "otp", wpa_cli_cmd_otp, 1274 cli_cmd_flag_sensitive, 1275 "<network id> <password> = configure one-time-password for an SSID" 1276 }, 1277 { "passphrase", wpa_cli_cmd_passphrase, 1278 cli_cmd_flag_sensitive, 1279 "<network id> <passphrase> = configure private key passphrase\n" 1280 " for an SSID" }, 1281 { "bssid", wpa_cli_cmd_bssid, 1282 cli_cmd_flag_none, 1283 "<network id> <BSSID> = set preferred BSSID for an SSID" }, 1284 #ifdef ANDROID 1285 { "scan_interval", wpa_cli_cmd_scan_interval, 1286 cli_cmd_flag_none, 1287 "<value> = set scan_interval parameter" }, 1288 { "blacklist", wpa_cli_cmd_blacklist, 1289 cli_cmd_flag_none, 1290 "<BSSID> = add a BSSID to the blacklist\n" 1291 "blacklist clear = clear the blacklist\n" 1292 "blacklist = display the blacklist" }, 1293 { "log_level", wpa_cli_cmd_log_level, 1294 cli_cmd_flag_none, 1295 "<level> [<timestamp>] = update the log level/timestamp of wpa_supplicant\n" 1296 "log_level = display the current log level and log options" }, 1297 #endif 1298 { "list_networks", wpa_cli_cmd_list_networks, 1299 cli_cmd_flag_none, 1300 "= list configured networks" }, 1301 { "select_network", wpa_cli_cmd_select_network, 1302 cli_cmd_flag_none, 1303 "<network id> = select a network (disable others)" }, 1304 { "enable_network", wpa_cli_cmd_enable_network, 1305 cli_cmd_flag_none, 1306 "<network id> = enable a network" }, 1307 { "disable_network", wpa_cli_cmd_disable_network, 1308 cli_cmd_flag_none, 1309 "<network id> = disable a network" }, 1310 { "add_network", wpa_cli_cmd_add_network, 1311 cli_cmd_flag_none, 1312 "= add a network" }, 1313 { "remove_network", wpa_cli_cmd_remove_network, 1314 cli_cmd_flag_none, 1315 "<network id> = remove a network" }, 1316 { "set_network", wpa_cli_cmd_set_network, 1317 cli_cmd_flag_sensitive, 1318 "<network id> <variable> <value> = set network variables (shows\n" 1319 " list of variables when run without arguments)" }, 1320 { "get_network", wpa_cli_cmd_get_network, 1321 cli_cmd_flag_none, 1322 "<network id> <variable> = get network variables" }, 1323 { "save_config", wpa_cli_cmd_save_config, 1324 cli_cmd_flag_none, 1325 "= save the current configuration" }, 1326 { "disconnect", wpa_cli_cmd_disconnect, 1327 cli_cmd_flag_none, 1328 "= disconnect and wait for reassociate/reconnect command before\n" 1329 " connecting" }, 1330 { "reconnect", wpa_cli_cmd_reconnect, 1331 cli_cmd_flag_none, 1332 "= like reassociate, but only takes effect if already disconnected" 1333 }, 1334 { "scan", wpa_cli_cmd_scan, 1335 cli_cmd_flag_none, 1336 "= request new BSS scan" }, 1337 { "scan_results", wpa_cli_cmd_scan_results, 1338 cli_cmd_flag_none, 1339 "= get latest scan results" }, 1340 { "bss", wpa_cli_cmd_bss, 1341 cli_cmd_flag_none, 1342 "<<idx> | <bssid>> = get detailed scan result info" }, 1343 { "get_capability", wpa_cli_cmd_get_capability, 1344 cli_cmd_flag_none, 1345 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" }, 1346 { "reconfigure", wpa_cli_cmd_reconfigure, 1347 cli_cmd_flag_none, 1348 "= force wpa_supplicant to re-read its configuration file" }, 1349 { "terminate", wpa_cli_cmd_terminate, 1350 cli_cmd_flag_none, 1351 "= terminate wpa_supplicant" }, 1352 { "interface_add", wpa_cli_cmd_interface_add, 1353 cli_cmd_flag_none, 1354 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n" 1355 " <bridge_name> = adds new interface, all parameters but <ifname>\n" 1356 " are optional" }, 1357 { "interface_remove", wpa_cli_cmd_interface_remove, 1358 cli_cmd_flag_none, 1359 "<ifname> = removes the interface" }, 1360 { "interface_list", wpa_cli_cmd_interface_list, 1361 cli_cmd_flag_none, 1362 "= list available interfaces" }, 1363 { "ap_scan", wpa_cli_cmd_ap_scan, 1364 cli_cmd_flag_none, 1365 "<value> = set ap_scan parameter" }, 1366 { "stkstart", wpa_cli_cmd_stkstart, 1367 cli_cmd_flag_none, 1368 "<addr> = request STK negotiation with <addr>" }, 1369 { "ft_ds", wpa_cli_cmd_ft_ds, 1370 cli_cmd_flag_none, 1371 "<addr> = request over-the-DS FT with <addr>" }, 1372 { "wps_pbc", wpa_cli_cmd_wps_pbc, 1373 cli_cmd_flag_none, 1374 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" }, 1375 { "wps_pin", wpa_cli_cmd_wps_pin, 1376 cli_cmd_flag_sensitive, 1377 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not " 1378 "hardcoded)" }, 1379 { "wps_reg", wpa_cli_cmd_wps_reg, 1380 cli_cmd_flag_sensitive, 1381 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" }, 1382 { "driver", wpa_cli_cmd_driver, 1383 cli_cmd_flag_none, 1384 "<command> = driver private commands" }, 1385 { NULL, NULL, cli_cmd_flag_none, NULL } 1386 }; 1387 1388 1389 /* 1390 * Prints command usage, lines are padded with the specified string. 1391 */ 1392 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad) 1393 { 1394 char c; 1395 size_t n; 1396 1397 printf("%s%s ", pad, cmd->cmd); 1398 for (n = 0; (c = cmd->usage[n]); n++) { 1399 printf("%c", c); 1400 if (c == '\n') 1401 printf("%s", pad); 1402 } 1403 printf("\n"); 1404 } 1405 1406 1407 static void print_help(void) 1408 { 1409 int n; 1410 printf("commands:\n"); 1411 for (n = 0; wpa_cli_commands[n].cmd; n++) 1412 print_cmd_help(&wpa_cli_commands[n], " "); 1413 } 1414 1415 1416 #ifdef CONFIG_READLINE 1417 static int cmd_has_sensitive_data(const char *cmd) 1418 { 1419 const char *c, *delim; 1420 int n; 1421 size_t len; 1422 1423 delim = os_strchr(cmd, ' '); 1424 if (delim) 1425 len = delim - cmd; 1426 else 1427 len = os_strlen(cmd); 1428 1429 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) { 1430 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c)) 1431 return (wpa_cli_commands[n].flags & 1432 cli_cmd_flag_sensitive); 1433 } 1434 return 0; 1435 } 1436 #endif /* CONFIG_READLINE */ 1437 1438 1439 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1440 { 1441 struct wpa_cli_cmd *cmd, *match = NULL; 1442 int count; 1443 int ret = 0; 1444 1445 count = 0; 1446 cmd = wpa_cli_commands; 1447 while (cmd->cmd) { 1448 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0) 1449 { 1450 match = cmd; 1451 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) { 1452 /* we have an exact match */ 1453 count = 1; 1454 break; 1455 } 1456 count++; 1457 } 1458 cmd++; 1459 } 1460 1461 if (count > 1) { 1462 printf("Ambiguous command '%s'; possible commands:", argv[0]); 1463 cmd = wpa_cli_commands; 1464 while (cmd->cmd) { 1465 if (os_strncasecmp(cmd->cmd, argv[0], 1466 os_strlen(argv[0])) == 0) { 1467 printf(" %s", cmd->cmd); 1468 } 1469 cmd++; 1470 } 1471 printf("\n"); 1472 ret = 1; 1473 } else if (count == 0) { 1474 printf("Unknown command '%s'\n", argv[0]); 1475 ret = 1; 1476 } else { 1477 if( os_strncasecmp( "level", argv[0], os_strlen(argv[0]) ) == 0 ) { 1478 ctrl = monitor_conn; 1479 } 1480 ret = match->handler(ctrl, argc - 1, &argv[1]); 1481 } 1482 1483 return ret; 1484 } 1485 1486 1487 static int str_match(const char *a, const char *b) 1488 { 1489 return os_strncmp(a, b, os_strlen(b)) == 0; 1490 } 1491 1492 1493 static int wpa_cli_exec(const char *program, const char *arg1, 1494 const char *arg2) 1495 { 1496 char *cmd; 1497 size_t len; 1498 int res; 1499 int ret = 0; 1500 1501 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3; 1502 cmd = os_malloc(len); 1503 if (cmd == NULL) 1504 return -1; 1505 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2); 1506 if (res < 0 || (size_t) res >= len) { 1507 os_free(cmd); 1508 return -1; 1509 } 1510 cmd[len - 1] = '\0'; 1511 #ifndef _WIN32_WCE 1512 if (system(cmd) < 0) 1513 ret = -1; 1514 #endif /* _WIN32_WCE */ 1515 os_free(cmd); 1516 1517 return ret; 1518 } 1519 1520 1521 static void wpa_cli_action_process(const char *msg) 1522 { 1523 const char *pos; 1524 char *copy = NULL, *id, *pos2; 1525 1526 pos = msg; 1527 if (*pos == '<') { 1528 /* skip priority */ 1529 pos = os_strchr(pos, '>'); 1530 if (pos) 1531 pos++; 1532 else 1533 pos = msg; 1534 } 1535 1536 if (str_match(pos, WPA_EVENT_CONNECTED)) { 1537 int new_id = -1; 1538 os_unsetenv("WPA_ID"); 1539 os_unsetenv("WPA_ID_STR"); 1540 os_unsetenv("WPA_CTRL_DIR"); 1541 1542 pos = os_strstr(pos, "[id="); 1543 if (pos) 1544 copy = os_strdup(pos + 4); 1545 1546 if (copy) { 1547 pos2 = id = copy; 1548 while (*pos2 && *pos2 != ' ') 1549 pos2++; 1550 *pos2++ = '\0'; 1551 new_id = atoi(id); 1552 os_setenv("WPA_ID", id, 1); 1553 while (*pos2 && *pos2 != '=') 1554 pos2++; 1555 if (*pos2 == '=') 1556 pos2++; 1557 id = pos2; 1558 while (*pos2 && *pos2 != ']') 1559 pos2++; 1560 *pos2 = '\0'; 1561 os_setenv("WPA_ID_STR", id, 1); 1562 os_free(copy); 1563 } 1564 1565 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1); 1566 1567 if (!wpa_cli_connected || new_id != wpa_cli_last_id) { 1568 wpa_cli_connected = 1; 1569 wpa_cli_last_id = new_id; 1570 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED"); 1571 } 1572 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) { 1573 if (wpa_cli_connected) { 1574 wpa_cli_connected = 0; 1575 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED"); 1576 } 1577 } else if (str_match(pos, WPA_EVENT_TERMINATING)) { 1578 printf("wpa_supplicant is terminating - stop monitoring\n"); 1579 wpa_cli_quit = 1; 1580 } 1581 } 1582 1583 1584 #ifndef CONFIG_ANSI_C_EXTRA 1585 static void wpa_cli_action_cb(char *msg, size_t len) 1586 { 1587 wpa_cli_action_process(msg); 1588 } 1589 #endif /* CONFIG_ANSI_C_EXTRA */ 1590 1591 1592 static void wpa_cli_reconnect(void) 1593 { 1594 wpa_cli_close_connection(); 1595 ctrl_conn = wpa_cli_open_connection(ctrl_ifname); 1596 if (ctrl_conn) { 1597 printf("Connection to wpa_supplicant re-established\n"); 1598 if (wpa_ctrl_attach(monitor_conn) == 0) { 1599 wpa_cli_attached = 1; 1600 } else { 1601 printf("Warning: Failed to attach to " 1602 "wpa_supplicant.\n"); 1603 } 1604 } 1605 } 1606 1607 1608 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read, 1609 int action_monitor) 1610 { 1611 int first = 1; 1612 if (ctrl == NULL) { 1613 wpa_cli_reconnect(); 1614 return; 1615 } 1616 while (wpa_ctrl_pending(ctrl) > 0) { 1617 char buf[256]; 1618 size_t len = sizeof(buf) - 1; 1619 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) { 1620 buf[len] = '\0'; 1621 if (action_monitor) 1622 wpa_cli_action_process(buf); 1623 else { 1624 if (in_read && first) 1625 printf("\n"); 1626 first = 0; 1627 printf("%s\n", buf); 1628 } 1629 } else { 1630 printf("Could not read pending message.\n"); 1631 break; 1632 } 1633 } 1634 1635 if (wpa_ctrl_pending(ctrl) < 0) { 1636 printf("Connection to wpa_supplicant lost - trying to " 1637 "reconnect\n"); 1638 wpa_cli_reconnect(); 1639 } 1640 } 1641 1642 1643 #ifdef CONFIG_READLINE 1644 static char * wpa_cli_cmd_gen(const char *text, int state) 1645 { 1646 static int i, len; 1647 const char *cmd; 1648 1649 if (state == 0) { 1650 i = 0; 1651 len = os_strlen(text); 1652 } 1653 1654 while ((cmd = wpa_cli_commands[i].cmd)) { 1655 i++; 1656 if (os_strncasecmp(cmd, text, len) == 0) 1657 return os_strdup(cmd); 1658 } 1659 1660 return NULL; 1661 } 1662 1663 1664 static char * wpa_cli_dummy_gen(const char *text, int state) 1665 { 1666 return NULL; 1667 } 1668 1669 1670 static char ** wpa_cli_completion(const char *text, int start, int end) 1671 { 1672 return rl_completion_matches(text, start == 0 ? 1673 wpa_cli_cmd_gen : wpa_cli_dummy_gen); 1674 } 1675 #endif /* CONFIG_READLINE */ 1676 1677 1678 static void wpa_cli_interactive(void) 1679 { 1680 #define max_args 10 1681 char cmdbuf[256], *cmd, *argv[max_args], *pos; 1682 int argc; 1683 #ifdef CONFIG_READLINE 1684 char *home, *hfile = NULL; 1685 #endif /* CONFIG_READLINE */ 1686 1687 printf("\nInteractive mode\n\n"); 1688 1689 #ifdef CONFIG_READLINE 1690 rl_attempted_completion_function = wpa_cli_completion; 1691 home = getenv("HOME"); 1692 if (home) { 1693 const char *fname = ".wpa_cli_history"; 1694 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1; 1695 hfile = os_malloc(hfile_len); 1696 if (hfile) { 1697 int res; 1698 res = os_snprintf(hfile, hfile_len, "%s/%s", home, 1699 fname); 1700 if (res >= 0 && res < hfile_len) { 1701 hfile[hfile_len - 1] = '\0'; 1702 read_history(hfile); 1703 stifle_history(100); 1704 } 1705 } 1706 } 1707 #endif /* CONFIG_READLINE */ 1708 1709 do { 1710 wpa_cli_recv_pending(monitor_conn, 0, 0); 1711 #ifndef CONFIG_NATIVE_WINDOWS 1712 alarm(ping_interval); 1713 #endif /* CONFIG_NATIVE_WINDOWS */ 1714 #ifdef CONFIG_READLINE 1715 cmd = readline("> "); 1716 if (cmd && *cmd) { 1717 HIST_ENTRY *h; 1718 while (next_history()) 1719 ; 1720 h = previous_history(); 1721 if (h == NULL || os_strcmp(cmd, h->line) != 0) 1722 add_history(cmd); 1723 next_history(); 1724 } 1725 #else /* CONFIG_READLINE */ 1726 printf("> "); 1727 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin); 1728 #endif /* CONFIG_READLINE */ 1729 #ifndef CONFIG_NATIVE_WINDOWS 1730 alarm(0); 1731 #endif /* CONFIG_NATIVE_WINDOWS */ 1732 if (cmd == NULL) 1733 break; 1734 wpa_cli_recv_pending(monitor_conn, 0, 0); 1735 pos = cmd; 1736 while (*pos != '\0') { 1737 if (*pos == '\n') { 1738 *pos = '\0'; 1739 break; 1740 } 1741 pos++; 1742 } 1743 argc = 0; 1744 pos = cmd; 1745 for (;;) { 1746 while (*pos == ' ') 1747 pos++; 1748 if (*pos == '\0') 1749 break; 1750 argv[argc] = pos; 1751 argc++; 1752 if (argc == max_args) 1753 break; 1754 if (*pos == '"') { 1755 char *pos2 = os_strrchr(pos, '"'); 1756 if (pos2) 1757 pos = pos2 + 1; 1758 } 1759 while (*pos != '\0' && *pos != ' ') 1760 pos++; 1761 if (*pos == ' ') 1762 *pos++ = '\0'; 1763 } 1764 if (argc) 1765 wpa_request(ctrl_conn, argc, argv); 1766 1767 if (cmd != cmdbuf) 1768 os_free(cmd); 1769 } while (!wpa_cli_quit); 1770 1771 #ifdef CONFIG_READLINE 1772 if (hfile) { 1773 /* Save command history, excluding lines that may contain 1774 * passwords. */ 1775 HIST_ENTRY *h; 1776 history_set_pos(0); 1777 while ((h = current_history())) { 1778 char *p = h->line; 1779 while (*p == ' ' || *p == '\t') 1780 p++; 1781 if (cmd_has_sensitive_data(p)) { 1782 h = remove_history(where_history()); 1783 if (h) { 1784 os_free(h->line); 1785 os_free(h->data); 1786 os_free(h); 1787 } else 1788 next_history(); 1789 } else 1790 next_history(); 1791 } 1792 write_history(hfile); 1793 os_free(hfile); 1794 } 1795 #endif /* CONFIG_READLINE */ 1796 } 1797 1798 1799 static void wpa_cli_action(struct wpa_ctrl *ctrl) 1800 { 1801 #ifdef CONFIG_ANSI_C_EXTRA 1802 /* TODO: ANSI C version(?) */ 1803 printf("Action processing not supported in ANSI C build.\n"); 1804 #else /* CONFIG_ANSI_C_EXTRA */ 1805 fd_set rfds; 1806 int fd, res; 1807 struct timeval tv; 1808 char buf[256]; /* note: large enough to fit in unsolicited messages */ 1809 size_t len; 1810 1811 fd = wpa_ctrl_get_fd(ctrl); 1812 1813 while (!wpa_cli_quit) { 1814 FD_ZERO(&rfds); 1815 FD_SET(fd, &rfds); 1816 tv.tv_sec = ping_interval; 1817 tv.tv_usec = 0; 1818 res = select(fd + 1, &rfds, NULL, NULL, &tv); 1819 if (res < 0 && errno != EINTR) { 1820 perror("select"); 1821 break; 1822 } 1823 1824 if (FD_ISSET(fd, &rfds)) 1825 wpa_cli_recv_pending(ctrl, 0, 1); 1826 else { 1827 /* verify that connection is still working */ 1828 len = sizeof(buf) - 1; 1829 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len, 1830 wpa_cli_action_cb) < 0 || 1831 len < 4 || os_memcmp(buf, "PONG", 4) != 0) { 1832 printf("wpa_supplicant did not reply to PING " 1833 "command - exiting\n"); 1834 break; 1835 } 1836 } 1837 } 1838 #endif /* CONFIG_ANSI_C_EXTRA */ 1839 } 1840 1841 1842 static void wpa_cli_cleanup(void) 1843 { 1844 wpa_cli_close_connection(); 1845 if (pid_file) 1846 os_daemonize_terminate(pid_file); 1847 1848 os_program_deinit(); 1849 } 1850 1851 static void wpa_cli_terminate(int sig) 1852 { 1853 wpa_cli_cleanup(); 1854 exit(0); 1855 } 1856 1857 1858 #ifndef CONFIG_NATIVE_WINDOWS 1859 static void wpa_cli_alarm(int sig) 1860 { 1861 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) { 1862 printf("Connection to wpa_supplicant lost - trying to " 1863 "reconnect\n"); 1864 wpa_cli_close_connection(); 1865 } 1866 if (!monitor_conn) 1867 wpa_cli_reconnect(); 1868 if (monitor_conn) 1869 wpa_cli_recv_pending(monitor_conn, 1, 0); 1870 alarm(ping_interval); 1871 } 1872 #endif /* CONFIG_NATIVE_WINDOWS */ 1873 1874 1875 static char * wpa_cli_get_default_ifname(void) 1876 { 1877 char *ifname = NULL; 1878 1879 #ifdef CONFIG_CTRL_IFACE_UNIX 1880 struct dirent *dent; 1881 DIR *dir = opendir(ctrl_iface_dir); 1882 if (!dir) { 1883 #ifdef ANDROID 1884 char ifprop[PROPERTY_VALUE_MAX]; 1885 if (property_get("wifi.interface", ifprop, NULL) != 0) { 1886 ifname = os_strdup(ifprop); 1887 printf("Using interface '%s'\n", ifname); 1888 return ifname; 1889 } 1890 #endif 1891 return NULL; 1892 } 1893 while ((dent = readdir(dir))) { 1894 #ifdef _DIRENT_HAVE_D_TYPE 1895 /* 1896 * Skip the file if it is not a socket. Also accept 1897 * DT_UNKNOWN (0) in case the C library or underlying 1898 * file system does not support d_type. 1899 */ 1900 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN) 1901 continue; 1902 #endif /* _DIRENT_HAVE_D_TYPE */ 1903 if (os_strcmp(dent->d_name, ".") == 0 || 1904 os_strcmp(dent->d_name, "..") == 0) 1905 continue; 1906 printf("Selected interface '%s'\n", dent->d_name); 1907 ifname = os_strdup(dent->d_name); 1908 break; 1909 } 1910 closedir(dir); 1911 #endif /* CONFIG_CTRL_IFACE_UNIX */ 1912 1913 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 1914 char buf[4096], *pos; 1915 size_t len; 1916 struct wpa_ctrl *ctrl; 1917 int ret; 1918 1919 ctrl = wpa_ctrl_open(NULL); 1920 if (ctrl == NULL) 1921 return NULL; 1922 1923 len = sizeof(buf) - 1; 1924 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL); 1925 if (ret >= 0) { 1926 buf[len] = '\0'; 1927 pos = os_strchr(buf, '\n'); 1928 if (pos) 1929 *pos = '\0'; 1930 ifname = os_strdup(buf); 1931 } 1932 wpa_ctrl_close(ctrl); 1933 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 1934 1935 return ifname; 1936 } 1937 1938 1939 int main(int argc, char *argv[]) 1940 { 1941 int interactive; 1942 int warning_displayed = 0; 1943 int c; 1944 int daemonize = 0; 1945 int ret = 0; 1946 const char *global = NULL; 1947 1948 if (os_program_init()) 1949 return -1; 1950 1951 for (;;) { 1952 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v"); 1953 if (c < 0) 1954 break; 1955 switch (c) { 1956 case 'a': 1957 action_file = optarg; 1958 break; 1959 case 'B': 1960 daemonize = 1; 1961 break; 1962 case 'g': 1963 global = optarg; 1964 break; 1965 case 'G': 1966 ping_interval = atoi(optarg); 1967 break; 1968 case 'h': 1969 usage(); 1970 return 0; 1971 case 'v': 1972 printf("%s\n", wpa_cli_version); 1973 return 0; 1974 case 'i': 1975 os_free(ctrl_ifname); 1976 ctrl_ifname = os_strdup(optarg); 1977 break; 1978 case 'p': 1979 ctrl_iface_dir = optarg; 1980 break; 1981 case 'P': 1982 pid_file = optarg; 1983 break; 1984 default: 1985 usage(); 1986 return -1; 1987 } 1988 } 1989 1990 interactive = (argc == optind) && (action_file == NULL); 1991 1992 if (interactive) 1993 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license); 1994 1995 if (global) { 1996 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 1997 ctrl_conn = wpa_ctrl_open(NULL); 1998 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 1999 ctrl_conn = wpa_ctrl_open(global); 2000 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 2001 if (ctrl_conn == NULL) { 2002 perror("Failed to connect to wpa_supplicant - " 2003 "wpa_ctrl_open"); 2004 return -1; 2005 } 2006 } 2007 2008 for (; !global;) { 2009 if (ctrl_ifname == NULL) 2010 ctrl_ifname = wpa_cli_get_default_ifname(); 2011 ctrl_conn = wpa_cli_open_connection(ctrl_ifname); 2012 if (ctrl_conn) { 2013 if (warning_displayed) 2014 printf("Connection established.\n"); 2015 break; 2016 } 2017 2018 if (!interactive) { 2019 perror("Failed to connect to wpa_supplicant - " 2020 "wpa_ctrl_open"); 2021 return -1; 2022 } 2023 2024 if (!warning_displayed) { 2025 printf("Could not connect to wpa_supplicant - " 2026 "re-trying\n"); 2027 warning_displayed = 1; 2028 } 2029 os_sleep(1, 0); 2030 continue; 2031 } 2032 2033 #ifndef _WIN32_WCE 2034 signal(SIGINT, wpa_cli_terminate); 2035 signal(SIGTERM, wpa_cli_terminate); 2036 #endif /* _WIN32_WCE */ 2037 #ifndef CONFIG_NATIVE_WINDOWS 2038 signal(SIGALRM, wpa_cli_alarm); 2039 #endif /* CONFIG_NATIVE_WINDOWS */ 2040 2041 if (interactive || action_file) { 2042 if (wpa_ctrl_attach(monitor_conn) == 0) { 2043 wpa_cli_attached = 1; 2044 } else { 2045 printf("Warning: Failed to attach to " 2046 "wpa_supplicant.\n"); 2047 if (!interactive) 2048 return -1; 2049 } 2050 } 2051 2052 if (daemonize && os_daemonize(pid_file)) 2053 return -1; 2054 2055 if (interactive) 2056 wpa_cli_interactive(); 2057 else if (action_file) 2058 wpa_cli_action(ctrl_conn); 2059 else 2060 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]); 2061 2062 os_free(ctrl_ifname); 2063 wpa_cli_cleanup(); 2064 2065 return ret; 2066 } 2067 2068 #else /* CONFIG_CTRL_IFACE */ 2069 int main(int argc, char *argv[]) 2070 { 2071 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n"); 2072 return -1; 2073 } 2074 #endif /* CONFIG_CTRL_IFACE */ 2075