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/misc/wifi/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_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[]) 752 { 753 char cmd[256], *pos, *end; 754 int i, ret; 755 756 end = cmd + sizeof(cmd); 757 pos = cmd; 758 ret = os_snprintf(pos, end - pos, "BLACKLIST"); 759 if (ret < 0 || ret >= end - pos) { 760 printf("Too long BLACKLIST command.\n"); 761 return -1; 762 } 763 pos += ret; 764 for (i = 0; i < argc; i++) { 765 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 766 if (ret < 0 || ret >= end - pos) { 767 printf("Too long BLACKLIST command.\n"); 768 return -1; 769 } 770 pos += ret; 771 } 772 773 return wpa_ctrl_command(ctrl, cmd); 774 } 775 776 777 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[]) 778 { 779 char cmd[256], *pos, *end; 780 int i, ret; 781 782 end = cmd + sizeof(cmd); 783 pos = cmd; 784 ret = os_snprintf(pos, end - pos, "LOG_LEVEL"); 785 if (ret < 0 || ret >= end - pos) { 786 printf("Too long LOG_LEVEL command.\n"); 787 return -1; 788 } 789 pos += ret; 790 for (i = 0; i < argc; i++) { 791 ret = os_snprintf(pos, end - pos, " %s", argv[i]); 792 if (ret < 0 || ret >= end - pos) { 793 printf("Too long LOG_LEVEL command.\n"); 794 return -1; 795 } 796 pos += ret; 797 } 798 799 return wpa_ctrl_command(ctrl, cmd); 800 } 801 #endif /* ANDROID */ 802 803 804 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc, 805 char *argv[]) 806 { 807 return wpa_ctrl_command(ctrl, "LIST_NETWORKS"); 808 } 809 810 811 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc, 812 char *argv[]) 813 { 814 char cmd[32]; 815 int res; 816 817 if (argc < 1) { 818 printf("Invalid SELECT_NETWORK command: needs one argument " 819 "(network id)\n"); 820 return -1; 821 } 822 823 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]); 824 if (res < 0 || (size_t) res >= sizeof(cmd)) 825 return -1; 826 cmd[sizeof(cmd) - 1] = '\0'; 827 828 return wpa_ctrl_command(ctrl, cmd); 829 } 830 831 832 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc, 833 char *argv[]) 834 { 835 char cmd[32]; 836 int res; 837 838 if (argc < 1) { 839 printf("Invalid ENABLE_NETWORK command: needs one argument " 840 "(network id)\n"); 841 return -1; 842 } 843 844 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]); 845 if (res < 0 || (size_t) res >= sizeof(cmd)) 846 return -1; 847 cmd[sizeof(cmd) - 1] = '\0'; 848 849 return wpa_ctrl_command(ctrl, cmd); 850 } 851 852 853 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc, 854 char *argv[]) 855 { 856 char cmd[32]; 857 int res; 858 859 if (argc < 1) { 860 printf("Invalid DISABLE_NETWORK command: needs one argument " 861 "(network id)\n"); 862 return -1; 863 } 864 865 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]); 866 if (res < 0 || (size_t) res >= sizeof(cmd)) 867 return -1; 868 cmd[sizeof(cmd) - 1] = '\0'; 869 870 return wpa_ctrl_command(ctrl, cmd); 871 } 872 873 874 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc, 875 char *argv[]) 876 { 877 return wpa_ctrl_command(ctrl, "ADD_NETWORK"); 878 } 879 880 881 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc, 882 char *argv[]) 883 { 884 char cmd[32]; 885 int res; 886 887 if (argc < 1) { 888 printf("Invalid REMOVE_NETWORK command: needs one argument " 889 "(network id)\n"); 890 return -1; 891 } 892 893 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]); 894 if (res < 0 || (size_t) res >= sizeof(cmd)) 895 return -1; 896 cmd[sizeof(cmd) - 1] = '\0'; 897 898 return wpa_ctrl_command(ctrl, cmd); 899 } 900 901 902 static void wpa_cli_show_network_variables(void) 903 { 904 printf("set_network variables:\n" 905 " ssid (network name, SSID)\n" 906 " psk (WPA passphrase or pre-shared key)\n" 907 " key_mgmt (key management protocol)\n" 908 " identity (EAP identity)\n" 909 " password (EAP password)\n" 910 " ...\n" 911 "\n" 912 "Note: Values are entered in the same format as the " 913 "configuration file is using,\n" 914 "i.e., strings values need to be inside double quotation " 915 "marks.\n" 916 "For example: set_network 1 ssid \"network name\"\n" 917 "\n" 918 "Please see wpa_supplicant.conf documentation for full list " 919 "of\navailable variables.\n"); 920 } 921 922 923 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc, 924 char *argv[]) 925 { 926 char cmd[256]; 927 int res; 928 929 if (argc == 0) { 930 wpa_cli_show_network_variables(); 931 return 0; 932 } 933 934 if (argc != 3) { 935 printf("Invalid SET_NETWORK command: needs three arguments\n" 936 "(network id, variable name, and value)\n"); 937 return -1; 938 } 939 940 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s", 941 argv[0], argv[1], argv[2]); 942 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 943 printf("Too long SET_NETWORK command.\n"); 944 return -1; 945 } 946 return wpa_ctrl_command(ctrl, cmd); 947 } 948 949 950 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc, 951 char *argv[]) 952 { 953 char cmd[256]; 954 int res; 955 956 if (argc == 0) { 957 wpa_cli_show_network_variables(); 958 return 0; 959 } 960 961 if (argc != 2) { 962 printf("Invalid GET_NETWORK command: needs two arguments\n" 963 "(network id and variable name)\n"); 964 return -1; 965 } 966 967 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s", 968 argv[0], argv[1]); 969 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { 970 printf("Too long GET_NETWORK command.\n"); 971 return -1; 972 } 973 return wpa_ctrl_command(ctrl, cmd); 974 } 975 976 977 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc, 978 char *argv[]) 979 { 980 return wpa_ctrl_command(ctrl, "DISCONNECT"); 981 } 982 983 984 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc, 985 char *argv[]) 986 { 987 return wpa_ctrl_command(ctrl, "RECONNECT"); 988 } 989 990 991 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc, 992 char *argv[]) 993 { 994 return wpa_ctrl_command(ctrl, "SAVE_CONFIG"); 995 } 996 997 998 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[]) 999 { 1000 return wpa_ctrl_command(ctrl, "SCAN"); 1001 } 1002 1003 1004 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc, 1005 char *argv[]) 1006 { 1007 return wpa_ctrl_command(ctrl, "SCAN_RESULTS"); 1008 } 1009 1010 1011 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1012 { 1013 char cmd[64]; 1014 int res; 1015 1016 if (argc != 1) { 1017 printf("Invalid BSS command: need one argument (index or " 1018 "BSSID)\n"); 1019 return -1; 1020 } 1021 1022 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]); 1023 if (res < 0 || (size_t) res >= sizeof(cmd)) 1024 return -1; 1025 cmd[sizeof(cmd) - 1] = '\0'; 1026 1027 return wpa_ctrl_command(ctrl, cmd); 1028 } 1029 1030 1031 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc, 1032 char *argv[]) 1033 { 1034 char cmd[64]; 1035 int res; 1036 1037 if (argc < 1 || argc > 2) { 1038 printf("Invalid GET_CAPABILITY command: need either one or " 1039 "two arguments\n"); 1040 return -1; 1041 } 1042 1043 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) { 1044 printf("Invalid GET_CAPABILITY command: second argument, " 1045 "if any, must be 'strict'\n"); 1046 return -1; 1047 } 1048 1049 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0], 1050 (argc == 2) ? " strict" : ""); 1051 if (res < 0 || (size_t) res >= sizeof(cmd)) 1052 return -1; 1053 cmd[sizeof(cmd) - 1] = '\0'; 1054 1055 return wpa_ctrl_command(ctrl, cmd); 1056 } 1057 1058 1059 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl) 1060 { 1061 printf("Available interfaces:\n"); 1062 return wpa_ctrl_command(ctrl, "INTERFACES"); 1063 } 1064 1065 1066 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1067 { 1068 if (argc < 1) { 1069 wpa_cli_list_interfaces(ctrl); 1070 return 0; 1071 } 1072 1073 wpa_cli_close_connection(); 1074 os_free(ctrl_ifname); 1075 ctrl_ifname = os_strdup(argv[0]); 1076 1077 if ((ctrl_conn = wpa_cli_open_connection(ctrl_ifname)) != NULL) { 1078 printf("Connected to interface '%s.\n", ctrl_ifname); 1079 if (wpa_ctrl_attach(monitor_conn) == 0) { 1080 wpa_cli_attached = 1; 1081 } else { 1082 printf("Warning: Failed to attach to " 1083 "wpa_supplicant.\n"); 1084 } 1085 } else { 1086 printf("Could not connect to interface '%s' - re-trying\n", 1087 ctrl_ifname); 1088 } 1089 return 0; 1090 } 1091 1092 1093 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc, 1094 char *argv[]) 1095 { 1096 return wpa_ctrl_command(ctrl, "RECONFIGURE"); 1097 } 1098 1099 1100 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc, 1101 char *argv[]) 1102 { 1103 return wpa_ctrl_command(ctrl, "TERMINATE"); 1104 } 1105 1106 1107 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc, 1108 char *argv[]) 1109 { 1110 char cmd[256]; 1111 int res; 1112 1113 if (argc < 1) { 1114 printf("Invalid INTERFACE_ADD command: needs at least one " 1115 "argument (interface name)\n" 1116 "All arguments: ifname confname driver ctrl_interface " 1117 "driver_param bridge_name\n"); 1118 return -1; 1119 } 1120 1121 /* 1122 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB 1123 * <driver_param>TAB<bridge_name> 1124 */ 1125 res = os_snprintf(cmd, sizeof(cmd), 1126 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s", 1127 argv[0], 1128 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "", 1129 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "", 1130 argc > 5 ? argv[5] : ""); 1131 if (res < 0 || (size_t) res >= sizeof(cmd)) 1132 return -1; 1133 cmd[sizeof(cmd) - 1] = '\0'; 1134 return wpa_ctrl_command(ctrl, cmd); 1135 } 1136 1137 1138 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc, 1139 char *argv[]) 1140 { 1141 char cmd[128]; 1142 int res; 1143 1144 if (argc != 1) { 1145 printf("Invalid INTERFACE_REMOVE command: needs one argument " 1146 "(interface name)\n"); 1147 return -1; 1148 } 1149 1150 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]); 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_list(struct wpa_ctrl *ctrl, int argc, 1159 char *argv[]) 1160 { 1161 return wpa_ctrl_command(ctrl, "INTERFACE_LIST"); 1162 } 1163 1164 1165 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, 1166 char *argv[]) 1167 { 1168 char cmd[32]; 1169 1170 if (argc < 1) { 1171 printf("Invalid DRIVER command: needs one argument (cmd)\n"); 1172 return -1; 1173 } 1174 1175 if (argc > 1) 1176 os_snprintf(cmd, sizeof(cmd), "DRIVER %s %s", argv[0], argv[1]); 1177 else 1178 os_snprintf(cmd, sizeof(cmd), "DRIVER %s", argv[0]); 1179 cmd[sizeof(cmd) - 1] = '\0'; 1180 1181 return wpa_ctrl_command(ctrl, cmd); 1182 } 1183 1184 1185 enum wpa_cli_cmd_flags { 1186 cli_cmd_flag_none = 0x00, 1187 cli_cmd_flag_sensitive = 0x01 1188 }; 1189 1190 struct wpa_cli_cmd { 1191 const char *cmd; 1192 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]); 1193 enum wpa_cli_cmd_flags flags; 1194 const char *usage; 1195 }; 1196 1197 static struct wpa_cli_cmd wpa_cli_commands[] = { 1198 { "status", wpa_cli_cmd_status, 1199 cli_cmd_flag_none, 1200 "[verbose] = get current WPA/EAPOL/EAP status" }, 1201 { "ping", wpa_cli_cmd_ping, 1202 cli_cmd_flag_none, 1203 "= pings wpa_supplicant" }, 1204 { "mib", wpa_cli_cmd_mib, 1205 cli_cmd_flag_none, 1206 "= get MIB variables (dot1x, dot11)" }, 1207 { "help", wpa_cli_cmd_help, 1208 cli_cmd_flag_none, 1209 "= show this usage help" }, 1210 { "interface", wpa_cli_cmd_interface, 1211 cli_cmd_flag_none, 1212 "[ifname] = show interfaces/select interface" }, 1213 { "level", wpa_cli_cmd_level, 1214 cli_cmd_flag_none, 1215 "<debug level> = change debug level" }, 1216 { "license", wpa_cli_cmd_license, 1217 cli_cmd_flag_none, 1218 "= show full wpa_cli license" }, 1219 { "quit", wpa_cli_cmd_quit, 1220 cli_cmd_flag_none, 1221 "= exit wpa_cli" }, 1222 { "set", wpa_cli_cmd_set, 1223 cli_cmd_flag_none, 1224 "= set variables (shows list of variables when run without " 1225 "arguments)" }, 1226 { "logon", wpa_cli_cmd_logon, 1227 cli_cmd_flag_none, 1228 "= IEEE 802.1X EAPOL state machine logon" }, 1229 { "logoff", wpa_cli_cmd_logoff, 1230 cli_cmd_flag_none, 1231 "= IEEE 802.1X EAPOL state machine logoff" }, 1232 { "pmksa", wpa_cli_cmd_pmksa, 1233 cli_cmd_flag_none, 1234 "= show PMKSA cache" }, 1235 { "reassociate", wpa_cli_cmd_reassociate, 1236 cli_cmd_flag_none, 1237 "= force reassociation" }, 1238 { "preauthenticate", wpa_cli_cmd_preauthenticate, 1239 cli_cmd_flag_none, 1240 "<BSSID> = force preauthentication" }, 1241 { "identity", wpa_cli_cmd_identity, 1242 cli_cmd_flag_none, 1243 "<network id> <identity> = configure identity for an SSID" }, 1244 { "password", wpa_cli_cmd_password, 1245 cli_cmd_flag_sensitive, 1246 "<network id> <password> = configure password for an SSID" }, 1247 { "new_password", wpa_cli_cmd_new_password, 1248 cli_cmd_flag_sensitive, 1249 "<network id> <password> = change password for an SSID" }, 1250 { "pin", wpa_cli_cmd_pin, 1251 cli_cmd_flag_sensitive, 1252 "<network id> <pin> = configure pin for an SSID" }, 1253 { "otp", wpa_cli_cmd_otp, 1254 cli_cmd_flag_sensitive, 1255 "<network id> <password> = configure one-time-password for an SSID" 1256 }, 1257 { "passphrase", wpa_cli_cmd_passphrase, 1258 cli_cmd_flag_sensitive, 1259 "<network id> <passphrase> = configure private key passphrase\n" 1260 " for an SSID" }, 1261 { "bssid", wpa_cli_cmd_bssid, 1262 cli_cmd_flag_none, 1263 "<network id> <BSSID> = set preferred BSSID for an SSID" }, 1264 #ifdef ANDROID 1265 { "blacklist", wpa_cli_cmd_blacklist, 1266 cli_cmd_flag_none, 1267 "<BSSID> = add a BSSID to the blacklist\n" 1268 "blacklist clear = clear the blacklist\n" 1269 "blacklist = display the blacklist" }, 1270 { "log_level", wpa_cli_cmd_log_level, 1271 cli_cmd_flag_none, 1272 "<level> [<timestamp>] = update the log level/timestamp of wpa_supplicant\n" 1273 "log_level = display the current log level and log options" }, 1274 #endif 1275 { "list_networks", wpa_cli_cmd_list_networks, 1276 cli_cmd_flag_none, 1277 "= list configured networks" }, 1278 { "select_network", wpa_cli_cmd_select_network, 1279 cli_cmd_flag_none, 1280 "<network id> = select a network (disable others)" }, 1281 { "enable_network", wpa_cli_cmd_enable_network, 1282 cli_cmd_flag_none, 1283 "<network id> = enable a network" }, 1284 { "disable_network", wpa_cli_cmd_disable_network, 1285 cli_cmd_flag_none, 1286 "<network id> = disable a network" }, 1287 { "add_network", wpa_cli_cmd_add_network, 1288 cli_cmd_flag_none, 1289 "= add a network" }, 1290 { "remove_network", wpa_cli_cmd_remove_network, 1291 cli_cmd_flag_none, 1292 "<network id> = remove a network" }, 1293 { "set_network", wpa_cli_cmd_set_network, 1294 cli_cmd_flag_sensitive, 1295 "<network id> <variable> <value> = set network variables (shows\n" 1296 " list of variables when run without arguments)" }, 1297 { "get_network", wpa_cli_cmd_get_network, 1298 cli_cmd_flag_none, 1299 "<network id> <variable> = get network variables" }, 1300 { "save_config", wpa_cli_cmd_save_config, 1301 cli_cmd_flag_none, 1302 "= save the current configuration" }, 1303 { "disconnect", wpa_cli_cmd_disconnect, 1304 cli_cmd_flag_none, 1305 "= disconnect and wait for reassociate/reconnect command before\n" 1306 " connecting" }, 1307 { "reconnect", wpa_cli_cmd_reconnect, 1308 cli_cmd_flag_none, 1309 "= like reassociate, but only takes effect if already disconnected" 1310 }, 1311 { "scan", wpa_cli_cmd_scan, 1312 cli_cmd_flag_none, 1313 "= request new BSS scan" }, 1314 { "scan_results", wpa_cli_cmd_scan_results, 1315 cli_cmd_flag_none, 1316 "= get latest scan results" }, 1317 { "bss", wpa_cli_cmd_bss, 1318 cli_cmd_flag_none, 1319 "<<idx> | <bssid>> = get detailed scan result info" }, 1320 { "get_capability", wpa_cli_cmd_get_capability, 1321 cli_cmd_flag_none, 1322 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" }, 1323 { "reconfigure", wpa_cli_cmd_reconfigure, 1324 cli_cmd_flag_none, 1325 "= force wpa_supplicant to re-read its configuration file" }, 1326 { "terminate", wpa_cli_cmd_terminate, 1327 cli_cmd_flag_none, 1328 "= terminate wpa_supplicant" }, 1329 { "interface_add", wpa_cli_cmd_interface_add, 1330 cli_cmd_flag_none, 1331 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n" 1332 " <bridge_name> = adds new interface, all parameters but <ifname>\n" 1333 " are optional" }, 1334 { "interface_remove", wpa_cli_cmd_interface_remove, 1335 cli_cmd_flag_none, 1336 "<ifname> = removes the interface" }, 1337 { "interface_list", wpa_cli_cmd_interface_list, 1338 cli_cmd_flag_none, 1339 "= list available interfaces" }, 1340 { "ap_scan", wpa_cli_cmd_ap_scan, 1341 cli_cmd_flag_none, 1342 "<value> = set ap_scan parameter" }, 1343 { "stkstart", wpa_cli_cmd_stkstart, 1344 cli_cmd_flag_none, 1345 "<addr> = request STK negotiation with <addr>" }, 1346 { "ft_ds", wpa_cli_cmd_ft_ds, 1347 cli_cmd_flag_none, 1348 "<addr> = request over-the-DS FT with <addr>" }, 1349 { "wps_pbc", wpa_cli_cmd_wps_pbc, 1350 cli_cmd_flag_none, 1351 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" }, 1352 { "wps_pin", wpa_cli_cmd_wps_pin, 1353 cli_cmd_flag_sensitive, 1354 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not " 1355 "hardcoded)" }, 1356 { "wps_reg", wpa_cli_cmd_wps_reg, 1357 cli_cmd_flag_sensitive, 1358 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" }, 1359 { "driver", wpa_cli_cmd_driver, 1360 cli_cmd_flag_none, 1361 "<command> = driver private commands" }, 1362 { NULL, NULL, cli_cmd_flag_none, NULL } 1363 }; 1364 1365 1366 /* 1367 * Prints command usage, lines are padded with the specified string. 1368 */ 1369 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad) 1370 { 1371 char c; 1372 size_t n; 1373 1374 printf("%s%s ", pad, cmd->cmd); 1375 for (n = 0; (c = cmd->usage[n]); n++) { 1376 printf("%c", c); 1377 if (c == '\n') 1378 printf("%s", pad); 1379 } 1380 printf("\n"); 1381 } 1382 1383 1384 static void print_help(void) 1385 { 1386 int n; 1387 printf("commands:\n"); 1388 for (n = 0; wpa_cli_commands[n].cmd; n++) 1389 print_cmd_help(&wpa_cli_commands[n], " "); 1390 } 1391 1392 1393 #ifdef CONFIG_READLINE 1394 static int cmd_has_sensitive_data(const char *cmd) 1395 { 1396 const char *c, *delim; 1397 int n; 1398 size_t len; 1399 1400 delim = os_strchr(cmd, ' '); 1401 if (delim) 1402 len = delim - cmd; 1403 else 1404 len = os_strlen(cmd); 1405 1406 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) { 1407 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c)) 1408 return (wpa_cli_commands[n].flags & 1409 cli_cmd_flag_sensitive); 1410 } 1411 return 0; 1412 } 1413 #endif /* CONFIG_READLINE */ 1414 1415 1416 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[]) 1417 { 1418 struct wpa_cli_cmd *cmd, *match = NULL; 1419 int count; 1420 int ret = 0; 1421 1422 count = 0; 1423 cmd = wpa_cli_commands; 1424 while (cmd->cmd) { 1425 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0) 1426 { 1427 match = cmd; 1428 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) { 1429 /* we have an exact match */ 1430 count = 1; 1431 break; 1432 } 1433 count++; 1434 } 1435 cmd++; 1436 } 1437 1438 if (count > 1) { 1439 printf("Ambiguous command '%s'; possible commands:", argv[0]); 1440 cmd = wpa_cli_commands; 1441 while (cmd->cmd) { 1442 if (os_strncasecmp(cmd->cmd, argv[0], 1443 os_strlen(argv[0])) == 0) { 1444 printf(" %s", cmd->cmd); 1445 } 1446 cmd++; 1447 } 1448 printf("\n"); 1449 ret = 1; 1450 } else if (count == 0) { 1451 printf("Unknown command '%s'\n", argv[0]); 1452 ret = 1; 1453 } else { 1454 if( os_strncasecmp( "level", argv[0], os_strlen(argv[0]) ) == 0 ) { 1455 ctrl = monitor_conn; 1456 } 1457 ret = match->handler(ctrl, argc - 1, &argv[1]); 1458 } 1459 1460 return ret; 1461 } 1462 1463 1464 static int str_match(const char *a, const char *b) 1465 { 1466 return os_strncmp(a, b, os_strlen(b)) == 0; 1467 } 1468 1469 1470 static int wpa_cli_exec(const char *program, const char *arg1, 1471 const char *arg2) 1472 { 1473 char *cmd; 1474 size_t len; 1475 int res; 1476 int ret = 0; 1477 1478 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3; 1479 cmd = os_malloc(len); 1480 if (cmd == NULL) 1481 return -1; 1482 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2); 1483 if (res < 0 || (size_t) res >= len) { 1484 os_free(cmd); 1485 return -1; 1486 } 1487 cmd[len - 1] = '\0'; 1488 #ifndef _WIN32_WCE 1489 if (system(cmd) < 0) 1490 ret = -1; 1491 #endif /* _WIN32_WCE */ 1492 os_free(cmd); 1493 1494 return ret; 1495 } 1496 1497 1498 static void wpa_cli_action_process(const char *msg) 1499 { 1500 const char *pos; 1501 char *copy = NULL, *id, *pos2; 1502 1503 pos = msg; 1504 if (*pos == '<') { 1505 /* skip priority */ 1506 pos = os_strchr(pos, '>'); 1507 if (pos) 1508 pos++; 1509 else 1510 pos = msg; 1511 } 1512 1513 if (str_match(pos, WPA_EVENT_CONNECTED)) { 1514 int new_id = -1; 1515 os_unsetenv("WPA_ID"); 1516 os_unsetenv("WPA_ID_STR"); 1517 os_unsetenv("WPA_CTRL_DIR"); 1518 1519 pos = os_strstr(pos, "[id="); 1520 if (pos) 1521 copy = os_strdup(pos + 4); 1522 1523 if (copy) { 1524 pos2 = id = copy; 1525 while (*pos2 && *pos2 != ' ') 1526 pos2++; 1527 *pos2++ = '\0'; 1528 new_id = atoi(id); 1529 os_setenv("WPA_ID", id, 1); 1530 while (*pos2 && *pos2 != '=') 1531 pos2++; 1532 if (*pos2 == '=') 1533 pos2++; 1534 id = pos2; 1535 while (*pos2 && *pos2 != ']') 1536 pos2++; 1537 *pos2 = '\0'; 1538 os_setenv("WPA_ID_STR", id, 1); 1539 os_free(copy); 1540 } 1541 1542 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1); 1543 1544 if (!wpa_cli_connected || new_id != wpa_cli_last_id) { 1545 wpa_cli_connected = 1; 1546 wpa_cli_last_id = new_id; 1547 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED"); 1548 } 1549 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) { 1550 if (wpa_cli_connected) { 1551 wpa_cli_connected = 0; 1552 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED"); 1553 } 1554 } else if (str_match(pos, WPA_EVENT_TERMINATING)) { 1555 printf("wpa_supplicant is terminating - stop monitoring\n"); 1556 wpa_cli_quit = 1; 1557 } 1558 } 1559 1560 1561 #ifndef CONFIG_ANSI_C_EXTRA 1562 static void wpa_cli_action_cb(char *msg, size_t len) 1563 { 1564 wpa_cli_action_process(msg); 1565 } 1566 #endif /* CONFIG_ANSI_C_EXTRA */ 1567 1568 1569 static void wpa_cli_reconnect(void) 1570 { 1571 wpa_cli_close_connection(); 1572 ctrl_conn = wpa_cli_open_connection(ctrl_ifname); 1573 if (ctrl_conn) { 1574 printf("Connection to wpa_supplicant re-established\n"); 1575 if (wpa_ctrl_attach(monitor_conn) == 0) { 1576 wpa_cli_attached = 1; 1577 } else { 1578 printf("Warning: Failed to attach to " 1579 "wpa_supplicant.\n"); 1580 } 1581 } 1582 } 1583 1584 1585 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read, 1586 int action_monitor) 1587 { 1588 int first = 1; 1589 if (ctrl == NULL) { 1590 wpa_cli_reconnect(); 1591 return; 1592 } 1593 while (wpa_ctrl_pending(ctrl) > 0) { 1594 char buf[256]; 1595 size_t len = sizeof(buf) - 1; 1596 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) { 1597 buf[len] = '\0'; 1598 if (action_monitor) 1599 wpa_cli_action_process(buf); 1600 else { 1601 if (in_read && first) 1602 printf("\n"); 1603 first = 0; 1604 printf("%s\n", buf); 1605 } 1606 } else { 1607 printf("Could not read pending message.\n"); 1608 break; 1609 } 1610 } 1611 1612 if (wpa_ctrl_pending(ctrl) < 0) { 1613 printf("Connection to wpa_supplicant lost - trying to " 1614 "reconnect\n"); 1615 wpa_cli_reconnect(); 1616 } 1617 } 1618 1619 1620 #ifdef CONFIG_READLINE 1621 static char * wpa_cli_cmd_gen(const char *text, int state) 1622 { 1623 static int i, len; 1624 const char *cmd; 1625 1626 if (state == 0) { 1627 i = 0; 1628 len = os_strlen(text); 1629 } 1630 1631 while ((cmd = wpa_cli_commands[i].cmd)) { 1632 i++; 1633 if (os_strncasecmp(cmd, text, len) == 0) 1634 return os_strdup(cmd); 1635 } 1636 1637 return NULL; 1638 } 1639 1640 1641 static char * wpa_cli_dummy_gen(const char *text, int state) 1642 { 1643 return NULL; 1644 } 1645 1646 1647 static char ** wpa_cli_completion(const char *text, int start, int end) 1648 { 1649 return rl_completion_matches(text, start == 0 ? 1650 wpa_cli_cmd_gen : wpa_cli_dummy_gen); 1651 } 1652 #endif /* CONFIG_READLINE */ 1653 1654 1655 static void wpa_cli_interactive(void) 1656 { 1657 #define max_args 10 1658 char cmdbuf[256], *cmd, *argv[max_args], *pos; 1659 int argc; 1660 #ifdef CONFIG_READLINE 1661 char *home, *hfile = NULL; 1662 #endif /* CONFIG_READLINE */ 1663 1664 printf("\nInteractive mode\n\n"); 1665 1666 #ifdef CONFIG_READLINE 1667 rl_attempted_completion_function = wpa_cli_completion; 1668 home = getenv("HOME"); 1669 if (home) { 1670 const char *fname = ".wpa_cli_history"; 1671 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1; 1672 hfile = os_malloc(hfile_len); 1673 if (hfile) { 1674 int res; 1675 res = os_snprintf(hfile, hfile_len, "%s/%s", home, 1676 fname); 1677 if (res >= 0 && res < hfile_len) { 1678 hfile[hfile_len - 1] = '\0'; 1679 read_history(hfile); 1680 stifle_history(100); 1681 } 1682 } 1683 } 1684 #endif /* CONFIG_READLINE */ 1685 1686 do { 1687 wpa_cli_recv_pending(monitor_conn, 0, 0); 1688 #ifndef CONFIG_NATIVE_WINDOWS 1689 alarm(ping_interval); 1690 #endif /* CONFIG_NATIVE_WINDOWS */ 1691 #ifdef CONFIG_READLINE 1692 cmd = readline("> "); 1693 if (cmd && *cmd) { 1694 HIST_ENTRY *h; 1695 while (next_history()) 1696 ; 1697 h = previous_history(); 1698 if (h == NULL || os_strcmp(cmd, h->line) != 0) 1699 add_history(cmd); 1700 next_history(); 1701 } 1702 #else /* CONFIG_READLINE */ 1703 printf("> "); 1704 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin); 1705 #endif /* CONFIG_READLINE */ 1706 #ifndef CONFIG_NATIVE_WINDOWS 1707 alarm(0); 1708 #endif /* CONFIG_NATIVE_WINDOWS */ 1709 if (cmd == NULL) 1710 break; 1711 wpa_cli_recv_pending(monitor_conn, 0, 0); 1712 pos = cmd; 1713 while (*pos != '\0') { 1714 if (*pos == '\n') { 1715 *pos = '\0'; 1716 break; 1717 } 1718 pos++; 1719 } 1720 argc = 0; 1721 pos = cmd; 1722 for (;;) { 1723 while (*pos == ' ') 1724 pos++; 1725 if (*pos == '\0') 1726 break; 1727 argv[argc] = pos; 1728 argc++; 1729 if (argc == max_args) 1730 break; 1731 if (*pos == '"') { 1732 char *pos2 = os_strrchr(pos, '"'); 1733 if (pos2) 1734 pos = pos2 + 1; 1735 } 1736 while (*pos != '\0' && *pos != ' ') 1737 pos++; 1738 if (*pos == ' ') 1739 *pos++ = '\0'; 1740 } 1741 if (argc) 1742 wpa_request(ctrl_conn, argc, argv); 1743 1744 if (cmd != cmdbuf) 1745 os_free(cmd); 1746 } while (!wpa_cli_quit); 1747 1748 #ifdef CONFIG_READLINE 1749 if (hfile) { 1750 /* Save command history, excluding lines that may contain 1751 * passwords. */ 1752 HIST_ENTRY *h; 1753 history_set_pos(0); 1754 while ((h = current_history())) { 1755 char *p = h->line; 1756 while (*p == ' ' || *p == '\t') 1757 p++; 1758 if (cmd_has_sensitive_data(p)) { 1759 h = remove_history(where_history()); 1760 if (h) { 1761 os_free(h->line); 1762 os_free(h->data); 1763 os_free(h); 1764 } else 1765 next_history(); 1766 } else 1767 next_history(); 1768 } 1769 write_history(hfile); 1770 os_free(hfile); 1771 } 1772 #endif /* CONFIG_READLINE */ 1773 } 1774 1775 1776 static void wpa_cli_action(struct wpa_ctrl *ctrl) 1777 { 1778 #ifdef CONFIG_ANSI_C_EXTRA 1779 /* TODO: ANSI C version(?) */ 1780 printf("Action processing not supported in ANSI C build.\n"); 1781 #else /* CONFIG_ANSI_C_EXTRA */ 1782 fd_set rfds; 1783 int fd, res; 1784 struct timeval tv; 1785 char buf[256]; /* note: large enough to fit in unsolicited messages */ 1786 size_t len; 1787 1788 fd = wpa_ctrl_get_fd(ctrl); 1789 1790 while (!wpa_cli_quit) { 1791 FD_ZERO(&rfds); 1792 FD_SET(fd, &rfds); 1793 tv.tv_sec = ping_interval; 1794 tv.tv_usec = 0; 1795 res = select(fd + 1, &rfds, NULL, NULL, &tv); 1796 if (res < 0 && errno != EINTR) { 1797 perror("select"); 1798 break; 1799 } 1800 1801 if (FD_ISSET(fd, &rfds)) 1802 wpa_cli_recv_pending(ctrl, 0, 1); 1803 else { 1804 /* verify that connection is still working */ 1805 len = sizeof(buf) - 1; 1806 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len, 1807 wpa_cli_action_cb) < 0 || 1808 len < 4 || os_memcmp(buf, "PONG", 4) != 0) { 1809 printf("wpa_supplicant did not reply to PING " 1810 "command - exiting\n"); 1811 break; 1812 } 1813 } 1814 } 1815 #endif /* CONFIG_ANSI_C_EXTRA */ 1816 } 1817 1818 1819 static void wpa_cli_cleanup(void) 1820 { 1821 wpa_cli_close_connection(); 1822 if (pid_file) 1823 os_daemonize_terminate(pid_file); 1824 1825 os_program_deinit(); 1826 } 1827 1828 static void wpa_cli_terminate(int sig) 1829 { 1830 wpa_cli_cleanup(); 1831 exit(0); 1832 } 1833 1834 1835 #ifndef CONFIG_NATIVE_WINDOWS 1836 static void wpa_cli_alarm(int sig) 1837 { 1838 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) { 1839 printf("Connection to wpa_supplicant lost - trying to " 1840 "reconnect\n"); 1841 wpa_cli_close_connection(); 1842 } 1843 if (!monitor_conn) 1844 wpa_cli_reconnect(); 1845 if (monitor_conn) 1846 wpa_cli_recv_pending(monitor_conn, 1, 0); 1847 alarm(ping_interval); 1848 } 1849 #endif /* CONFIG_NATIVE_WINDOWS */ 1850 1851 1852 static char * wpa_cli_get_default_ifname(void) 1853 { 1854 char *ifname = NULL; 1855 1856 #ifdef CONFIG_CTRL_IFACE_UNIX 1857 struct dirent *dent; 1858 DIR *dir = opendir(ctrl_iface_dir); 1859 if (!dir) { 1860 #ifdef ANDROID 1861 char ifprop[PROPERTY_VALUE_MAX]; 1862 if (property_get("wifi.interface", ifprop, NULL) != 0) { 1863 ifname = os_strdup(ifprop); 1864 printf("Using interface '%s'\n", ifname); 1865 return ifname; 1866 } 1867 #endif 1868 return NULL; 1869 } 1870 while ((dent = readdir(dir))) { 1871 #ifdef _DIRENT_HAVE_D_TYPE 1872 /* 1873 * Skip the file if it is not a socket. Also accept 1874 * DT_UNKNOWN (0) in case the C library or underlying 1875 * file system does not support d_type. 1876 */ 1877 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN) 1878 continue; 1879 #endif /* _DIRENT_HAVE_D_TYPE */ 1880 if (os_strcmp(dent->d_name, ".") == 0 || 1881 os_strcmp(dent->d_name, "..") == 0) 1882 continue; 1883 printf("Selected interface '%s'\n", dent->d_name); 1884 ifname = os_strdup(dent->d_name); 1885 break; 1886 } 1887 closedir(dir); 1888 #endif /* CONFIG_CTRL_IFACE_UNIX */ 1889 1890 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 1891 char buf[4096], *pos; 1892 size_t len; 1893 struct wpa_ctrl *ctrl; 1894 int ret; 1895 1896 ctrl = wpa_ctrl_open(NULL); 1897 if (ctrl == NULL) 1898 return NULL; 1899 1900 len = sizeof(buf) - 1; 1901 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL); 1902 if (ret >= 0) { 1903 buf[len] = '\0'; 1904 pos = os_strchr(buf, '\n'); 1905 if (pos) 1906 *pos = '\0'; 1907 ifname = os_strdup(buf); 1908 } 1909 wpa_ctrl_close(ctrl); 1910 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 1911 1912 return ifname; 1913 } 1914 1915 1916 int main(int argc, char *argv[]) 1917 { 1918 int interactive; 1919 int warning_displayed = 0; 1920 int c; 1921 int daemonize = 0; 1922 int ret = 0; 1923 const char *global = NULL; 1924 1925 if (os_program_init()) 1926 return -1; 1927 1928 for (;;) { 1929 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v"); 1930 if (c < 0) 1931 break; 1932 switch (c) { 1933 case 'a': 1934 action_file = optarg; 1935 break; 1936 case 'B': 1937 daemonize = 1; 1938 break; 1939 case 'g': 1940 global = optarg; 1941 break; 1942 case 'G': 1943 ping_interval = atoi(optarg); 1944 break; 1945 case 'h': 1946 usage(); 1947 return 0; 1948 case 'v': 1949 printf("%s\n", wpa_cli_version); 1950 return 0; 1951 case 'i': 1952 os_free(ctrl_ifname); 1953 ctrl_ifname = os_strdup(optarg); 1954 break; 1955 case 'p': 1956 ctrl_iface_dir = optarg; 1957 break; 1958 case 'P': 1959 pid_file = optarg; 1960 break; 1961 default: 1962 usage(); 1963 return -1; 1964 } 1965 } 1966 1967 interactive = (argc == optind) && (action_file == NULL); 1968 1969 if (interactive) 1970 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license); 1971 1972 if (global) { 1973 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 1974 ctrl_conn = wpa_ctrl_open(NULL); 1975 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 1976 ctrl_conn = wpa_ctrl_open(global); 1977 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 1978 if (ctrl_conn == NULL) { 1979 perror("Failed to connect to wpa_supplicant - " 1980 "wpa_ctrl_open"); 1981 return -1; 1982 } 1983 } 1984 1985 for (; !global;) { 1986 if (ctrl_ifname == NULL) 1987 ctrl_ifname = wpa_cli_get_default_ifname(); 1988 ctrl_conn = wpa_cli_open_connection(ctrl_ifname); 1989 if (ctrl_conn) { 1990 if (warning_displayed) 1991 printf("Connection established.\n"); 1992 break; 1993 } 1994 1995 if (!interactive) { 1996 perror("Failed to connect to wpa_supplicant - " 1997 "wpa_ctrl_open"); 1998 return -1; 1999 } 2000 2001 if (!warning_displayed) { 2002 printf("Could not connect to wpa_supplicant - " 2003 "re-trying\n"); 2004 warning_displayed = 1; 2005 } 2006 os_sleep(1, 0); 2007 continue; 2008 } 2009 2010 #ifndef _WIN32_WCE 2011 signal(SIGINT, wpa_cli_terminate); 2012 signal(SIGTERM, wpa_cli_terminate); 2013 #endif /* _WIN32_WCE */ 2014 #ifndef CONFIG_NATIVE_WINDOWS 2015 signal(SIGALRM, wpa_cli_alarm); 2016 #endif /* CONFIG_NATIVE_WINDOWS */ 2017 2018 if (interactive || action_file) { 2019 if (wpa_ctrl_attach(monitor_conn) == 0) { 2020 wpa_cli_attached = 1; 2021 } else { 2022 printf("Warning: Failed to attach to " 2023 "wpa_supplicant.\n"); 2024 if (!interactive) 2025 return -1; 2026 } 2027 } 2028 2029 if (daemonize && os_daemonize(pid_file)) 2030 return -1; 2031 2032 if (interactive) 2033 wpa_cli_interactive(); 2034 else if (action_file) 2035 wpa_cli_action(ctrl_conn); 2036 else 2037 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]); 2038 2039 os_free(ctrl_ifname); 2040 wpa_cli_cleanup(); 2041 2042 return ret; 2043 } 2044 2045 #else /* CONFIG_CTRL_IFACE */ 2046 int main(int argc, char *argv[]) 2047 { 2048 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n"); 2049 return -1; 2050 } 2051 #endif /* CONFIG_CTRL_IFACE */ 2052