00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016
00017 #ifdef CONFIG_CTRL_IFACE
00018
00019 #ifdef CONFIG_CTRL_IFACE_UNIX
00020 #include <dirent.h>
00021 #endif
00022 #ifdef CONFIG_READLINE
00023 #include <readline/readline.h>
00024 #include <readline/history.h>
00025 #endif
00026 #ifdef CONFIG_WPA_CLI_FORK
00027 #include <sys/wait.h>
00028 #endif
00029
00030 #include "common/wpa_ctrl.h"
00031 #include "common.h"
00032 #include "common/version.h"
00033
00034
00035 static const char *wpa_cli_version =
00036 "wpa_cli v" VERSION_STR "\n"
00037 "Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> and contributors";
00038
00039
00040 static const char *wpa_cli_license =
00041 "This program is free software. You can distribute it and/or modify it\n"
00042 "under the terms of the GNU General Public License version 2.\n"
00043 "\n"
00044 "Alternatively, this software may be distributed under the terms of the\n"
00045 "BSD license. See README and COPYING for more details.\n";
00046
00047 static const char *wpa_cli_full_license =
00048 "This program is free software; you can redistribute it and/or modify\n"
00049 "it under the terms of the GNU General Public License version 2 as\n"
00050 "published by the Free Software Foundation.\n"
00051 "\n"
00052 "This program is distributed in the hope that it will be useful,\n"
00053 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00054 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00055 "GNU General Public License for more details.\n"
00056 "\n"
00057 "You should have received a copy of the GNU General Public License\n"
00058 "along with this program; if not, write to the Free Software\n"
00059 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
00060 "\n"
00061 "Alternatively, this software may be distributed under the terms of the\n"
00062 "BSD license.\n"
00063 "\n"
00064 "Redistribution and use in source and binary forms, with or without\n"
00065 "modification, are permitted provided that the following conditions are\n"
00066 "met:\n"
00067 "\n"
00068 "1. Redistributions of source code must retain the above copyright\n"
00069 " notice, this list of conditions and the following disclaimer.\n"
00070 "\n"
00071 "2. Redistributions in binary form must reproduce the above copyright\n"
00072 " notice, this list of conditions and the following disclaimer in the\n"
00073 " documentation and/or other materials provided with the distribution.\n"
00074 "\n"
00075 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
00076 " names of its contributors may be used to endorse or promote products\n"
00077 " derived from this software without specific prior written permission.\n"
00078 "\n"
00079 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
00080 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
00081 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
00082 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
00083 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
00084 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
00085 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
00086 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
00087 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
00088 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
00089 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
00090 "\n";
00091
00092 static struct wpa_ctrl *ctrl_conn;
00093 static struct wpa_ctrl *mon_conn;
00094 #ifdef CONFIG_WPA_CLI_FORK
00095 static pid_t mon_pid = 0;
00096 #endif
00097 static int wpa_cli_quit = 0;
00098 static int wpa_cli_attached = 0;
00099 static int wpa_cli_connected = 0;
00100 static int wpa_cli_last_id = 0;
00101 static const char *ctrl_iface_dir = "/var/run/wpa_supplicant";
00102 static char *ctrl_ifname = NULL;
00103 static const char *pid_file = NULL;
00104 static const char *action_file = NULL;
00105 static int ping_interval = 5;
00106 static int interactive = 0;
00107
00108
00109 static void print_help();
00110
00111
00112 static void usage(void)
00113 {
00114 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
00115 "[-a<action file>] \\\n"
00116 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
00117 "[command..]\n"
00118 " -h = help (show this usage text)\n"
00119 " -v = shown version information\n"
00120 " -a = run in daemon mode executing the action file based on "
00121 "events from\n"
00122 " wpa_supplicant\n"
00123 " -B = run a daemon in the background\n"
00124 " default path: /var/run/wpa_supplicant\n"
00125 " default interface: first interface found in socket path\n");
00126 print_help();
00127 }
00128
00129
00130 #ifdef CONFIG_WPA_CLI_FORK
00131 static int in_query = 0;
00132
00133 static void wpa_cli_monitor_sig(int sig)
00134 {
00135 if (sig == SIGUSR1)
00136 in_query = 1;
00137 else if (sig == SIGUSR2)
00138 in_query = 0;
00139 }
00140
00141 static void wpa_cli_monitor(void)
00142 {
00143 char buf[256];
00144 size_t len = sizeof(buf) - 1;
00145 struct timeval tv;
00146 fd_set rfds;
00147
00148 signal(SIGUSR1, wpa_cli_monitor_sig);
00149 signal(SIGUSR2, wpa_cli_monitor_sig);
00150
00151 while (mon_conn) {
00152 int s = wpa_ctrl_get_fd(mon_conn);
00153 tv.tv_sec = 5;
00154 tv.tv_usec = 0;
00155 FD_ZERO(&rfds);
00156 FD_SET(s, &rfds);
00157 if (select(s + 1, &rfds, NULL, NULL, &tv) < 0) {
00158 if (errno == EINTR)
00159 continue;
00160 perror("select");
00161 break;
00162 }
00163 if (mon_conn == NULL)
00164 break;
00165 if (FD_ISSET(s, &rfds)) {
00166 len = sizeof(buf) - 1;
00167 int res = wpa_ctrl_recv(mon_conn, buf, &len);
00168 if (res < 0) {
00169 perror("wpa_ctrl_recv");
00170 break;
00171 }
00172 buf[len] = '\0';
00173 if (in_query)
00174 printf("\r");
00175 printf("%s\n", buf);
00176 kill(getppid(), SIGUSR1);
00177 }
00178 }
00179 }
00180 #endif
00181
00182
00183 static int wpa_cli_open_connection(const char *ifname, int attach)
00184 {
00185 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
00186 ctrl_conn = wpa_ctrl_open(ifname);
00187 if (ctrl_conn == NULL)
00188 return -1;
00189
00190 if (attach && interactive)
00191 mon_conn = wpa_ctrl_open(ifname);
00192 else
00193 mon_conn = NULL;
00194 #else
00195 char *cfile;
00196 int flen, res;
00197
00198 if (ifname == NULL)
00199 return -1;
00200
00201 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
00202 cfile = os_malloc(flen);
00203 if (cfile == NULL)
00204 return -1L;
00205 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
00206 if (res < 0 || res >= flen) {
00207 os_free(cfile);
00208 return -1;
00209 }
00210
00211 ctrl_conn = wpa_ctrl_open(cfile);
00212 if (ctrl_conn == NULL) {
00213 os_free(cfile);
00214 return -1;
00215 }
00216
00217 if (attach && interactive)
00218 mon_conn = wpa_ctrl_open(cfile);
00219 else
00220 mon_conn = NULL;
00221 os_free(cfile);
00222 #endif
00223
00224 if (mon_conn) {
00225 if (wpa_ctrl_attach(mon_conn) == 0) {
00226 wpa_cli_attached = 1;
00227 } else {
00228 printf("Warning: Failed to attach to "
00229 "wpa_supplicant.\n");
00230 return -1;
00231 }
00232
00233 #ifdef CONFIG_WPA_CLI_FORK
00234 {
00235 pid_t p = fork();
00236 if (p < 0) {
00237 perror("fork");
00238 return -1;
00239 }
00240 if (p == 0) {
00241 wpa_cli_monitor();
00242 exit(0);
00243 } else
00244 mon_pid = p;
00245 }
00246 #endif
00247 }
00248
00249 return 0;
00250 }
00251
00252
00253 static void wpa_cli_close_connection(void)
00254 {
00255 if (ctrl_conn == NULL)
00256 return;
00257
00258 #ifdef CONFIG_WPA_CLI_FORK
00259 if (mon_pid) {
00260 int status;
00261 kill(mon_pid, SIGPIPE);
00262 wait(&status);
00263 mon_pid = 0;
00264 }
00265 #endif
00266
00267 if (wpa_cli_attached) {
00268 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
00269 wpa_cli_attached = 0;
00270 }
00271 wpa_ctrl_close(ctrl_conn);
00272 ctrl_conn = NULL;
00273 if (mon_conn) {
00274 wpa_ctrl_close(mon_conn);
00275 mon_conn = NULL;
00276 }
00277 }
00278
00279
00280 static void wpa_cli_msg_cb(char *msg, size_t len)
00281 {
00282 printf("%s\n", msg);
00283 }
00284
00285
00286 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
00287 {
00288 char buf[2048];
00289 size_t len;
00290 int ret;
00291
00292 if (ctrl_conn == NULL) {
00293 printf("Not connected to wpa_supplicant - command dropped.\n");
00294 return -1;
00295 }
00296 len = sizeof(buf) - 1;
00297 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
00298 wpa_cli_msg_cb);
00299 if (ret == -2) {
00300 printf("'%s' command timed out.\n", cmd);
00301 return -2;
00302 } else if (ret < 0) {
00303 printf("'%s' command failed.\n", cmd);
00304 return -1;
00305 }
00306 if (print) {
00307 buf[len] = '\0';
00308 printf("%s", buf);
00309 }
00310 return 0;
00311 }
00312
00313
00314 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
00315 {
00316 return _wpa_ctrl_command(ctrl, cmd, 1);
00317 }
00318
00319
00320 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
00321 {
00322 int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
00323 return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
00324 }
00325
00326
00327 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
00328 {
00329 return wpa_ctrl_command(ctrl, "PING");
00330 }
00331
00332
00333 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
00334 {
00335 return wpa_ctrl_command(ctrl, "MIB");
00336 }
00337
00338
00339 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
00340 {
00341 return wpa_ctrl_command(ctrl, "PMKSA");
00342 }
00343
00344
00345 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
00346 {
00347 print_help();
00348 return 0;
00349 }
00350
00351
00352 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
00353 {
00354 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
00355 return 0;
00356 }
00357
00358
00359 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
00360 {
00361 wpa_cli_quit = 1;
00362 return 0;
00363 }
00364
00365
00366 static void wpa_cli_show_variables(void)
00367 {
00368 printf("set variables:\n"
00369 " EAPOL::heldPeriod (EAPOL state machine held period, "
00370 "in seconds)\n"
00371 " EAPOL::authPeriod (EAPOL state machine authentication "
00372 "period, in seconds)\n"
00373 " EAPOL::startPeriod (EAPOL state machine start period, in "
00374 "seconds)\n"
00375 " EAPOL::maxStart (EAPOL state machine maximum start "
00376 "attempts)\n");
00377 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
00378 "seconds)\n"
00379 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
00380 " threshold\n\tpercentage)\n"
00381 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
00382 "security\n\tassociation in seconds)\n");
00383 }
00384
00385
00386 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
00387 {
00388 char cmd[256];
00389 int res;
00390
00391 if (argc == 0) {
00392 wpa_cli_show_variables();
00393 return 0;
00394 }
00395
00396 if (argc != 2) {
00397 printf("Invalid SET command: needs two arguments (variable "
00398 "name and value)\n");
00399 return -1;
00400 }
00401
00402 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
00403 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
00404 printf("Too long SET command.\n");
00405 return -1;
00406 }
00407 return wpa_ctrl_command(ctrl, cmd);
00408 }
00409
00410
00411 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
00412 {
00413 return wpa_ctrl_command(ctrl, "LOGOFF");
00414 }
00415
00416
00417 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
00418 {
00419 return wpa_ctrl_command(ctrl, "LOGON");
00420 }
00421
00422
00423 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
00424 char *argv[])
00425 {
00426 return wpa_ctrl_command(ctrl, "REASSOCIATE");
00427 }
00428
00429
00430 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
00431 char *argv[])
00432 {
00433 char cmd[256];
00434 int res;
00435
00436 if (argc != 1) {
00437 printf("Invalid PREAUTH command: needs one argument "
00438 "(BSSID)\n");
00439 return -1;
00440 }
00441
00442 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
00443 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
00444 printf("Too long PREAUTH command.\n");
00445 return -1;
00446 }
00447 return wpa_ctrl_command(ctrl, cmd);
00448 }
00449
00450
00451 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
00452 {
00453 char cmd[256];
00454 int res;
00455
00456 if (argc != 1) {
00457 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
00458 "value)\n");
00459 return -1;
00460 }
00461 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
00462 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
00463 printf("Too long AP_SCAN command.\n");
00464 return -1;
00465 }
00466 return wpa_ctrl_command(ctrl, cmd);
00467 }
00468
00469
00470 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
00471 char *argv[])
00472 {
00473 char cmd[256];
00474 int res;
00475
00476 if (argc != 1) {
00477 printf("Invalid STKSTART command: needs one argument "
00478 "(Peer STA MAC address)\n");
00479 return -1;
00480 }
00481
00482 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
00483 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
00484 printf("Too long STKSTART command.\n");
00485 return -1;
00486 }
00487 return wpa_ctrl_command(ctrl, cmd);
00488 }
00489
00490
00491 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
00492 {
00493 char cmd[256];
00494 int res;
00495
00496 if (argc != 1) {
00497 printf("Invalid FT_DS command: needs one argument "
00498 "(Target AP MAC address)\n");
00499 return -1;
00500 }
00501
00502 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
00503 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
00504 printf("Too long FT_DS command.\n");
00505 return -1;
00506 }
00507 return wpa_ctrl_command(ctrl, cmd);
00508 }
00509
00510
00511 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
00512 {
00513 char cmd[256];
00514 int res;
00515
00516 if (argc == 0) {
00517
00518 return wpa_ctrl_command(ctrl, "WPS_PBC");
00519 }
00520
00521
00522 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
00523 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
00524 printf("Too long WPS_PBC command.\n");
00525 return -1;
00526 }
00527 return wpa_ctrl_command(ctrl, cmd);
00528 }
00529
00530
00531 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
00532 {
00533 char cmd[256];
00534 int res;
00535
00536 if (argc == 0) {
00537 printf("Invalid WPS_PIN command: need one or two arguments:\n"
00538 "- BSSID: use 'any' to select any\n"
00539 "- PIN: optional, used only with devices that have no "
00540 "display\n");
00541 return -1;
00542 }
00543
00544 if (argc == 1) {
00545
00546 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
00547 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
00548 printf("Too long WPS_PIN command.\n");
00549 return -1;
00550 }
00551 return wpa_ctrl_command(ctrl, cmd);
00552 }
00553
00554
00555 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
00556 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
00557 printf("Too long WPS_PIN command.\n");
00558 return -1;
00559 }
00560 return wpa_ctrl_command(ctrl, cmd);
00561 }
00562
00563
00564 #ifdef CONFIG_WPS_OOB
00565 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
00566 {
00567 char cmd[256];
00568 int res;
00569
00570 if (argc != 3 && argc != 4) {
00571 printf("Invalid WPS_OOB command: need three or four "
00572 "arguments:\n"
00573 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
00574 "- PATH: path of OOB device like '/mnt'\n"
00575 "- METHOD: OOB method 'pin-e' or 'pin-r', "
00576 "'cred'\n"
00577 "- DEV_NAME: (only for NFC) device name like "
00578 "'pn531'\n");
00579 return -1;
00580 }
00581
00582 if (argc == 3)
00583 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
00584 argv[0], argv[1], argv[2]);
00585 else
00586 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
00587 argv[0], argv[1], argv[2], argv[3]);
00588 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
00589 printf("Too long WPS_OOB command.\n");
00590 return -1;
00591 }
00592 return wpa_ctrl_command(ctrl, cmd);
00593 }
00594 #endif
00595
00596
00597 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
00598 {
00599 char cmd[256];
00600 int res;
00601
00602 if (argc == 2)
00603 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
00604 argv[0], argv[1]);
00605 else if (argc == 6) {
00606 char ssid_hex[2 * 32 + 1];
00607 char key_hex[2 * 64 + 1];
00608 int i;
00609
00610 ssid_hex[0] = '\0';
00611 for (i = 0; i < 32; i++) {
00612 if (argv[2][i] == '\0')
00613 break;
00614 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
00615 }
00616
00617 key_hex[0] = '\0';
00618 for (i = 0; i < 64; i++) {
00619 if (argv[5][i] == '\0')
00620 break;
00621 os_snprintf(&key_hex[i * 2], 3, "%02x", argv[5][i]);
00622 }
00623
00624 res = os_snprintf(cmd, sizeof(cmd),
00625 "WPS_REG %s %s %s %s %s %s",
00626 argv[0], argv[1], ssid_hex, argv[3], argv[4],
00627 key_hex);
00628 } else {
00629 printf("Invalid WPS_REG command: need two arguments:\n"
00630 "- BSSID: use 'any' to select any\n"
00631 "- AP PIN\n");
00632 printf("Alternatively, six arguments can be used to "
00633 "reconfigure the AP:\n"
00634 "- BSSID: use 'any' to select any\n"
00635 "- AP PIN\n"
00636 "- new SSID\n"
00637 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
00638 "- new encr (NONE, WEP, TKIP, CCMP)\n"
00639 "- new key\n");
00640 return -1;
00641 }
00642
00643 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
00644 printf("Too long WPS_REG command.\n");
00645 return -1;
00646 }
00647 return wpa_ctrl_command(ctrl, cmd);
00648 }
00649
00650
00651 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
00652 char *argv[])
00653 {
00654 return wpa_ctrl_command(ctrl, "WPS_ER_START");
00655
00656 }
00657
00658
00659 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
00660 char *argv[])
00661 {
00662 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
00663
00664 }
00665
00666
00667 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
00668 char *argv[])
00669 {
00670 char cmd[256];
00671 int res;
00672
00673 if (argc != 2) {
00674 printf("Invalid WPS_ER_PIN command: need two arguments:\n"
00675 "- UUID: use 'any' to select any\n"
00676 "- PIN: Enrollee PIN\n");
00677 return -1;
00678 }
00679
00680 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
00681 argv[0], argv[1]);
00682 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
00683 printf("Too long WPS_ER_PIN command.\n");
00684 return -1;
00685 }
00686 return wpa_ctrl_command(ctrl, cmd);
00687 }
00688
00689
00690 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
00691 char *argv[])
00692 {
00693 char cmd[256];
00694 int res;
00695
00696 if (argc != 1) {
00697 printf("Invalid WPS_ER_PBC command: need one argument:\n"
00698 "- UUID: Specify the Enrollee\n");
00699 return -1;
00700 }
00701
00702 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
00703 argv[0]);
00704 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
00705 printf("Too long WPS_ER_PBC command.\n");
00706 return -1;
00707 }
00708 return wpa_ctrl_command(ctrl, cmd);
00709 }
00710
00711
00712 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
00713 char *argv[])
00714 {
00715 char cmd[256];
00716 int res;
00717
00718 if (argc != 2) {
00719 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
00720 "- UUID: specify which AP to use\n"
00721 "- PIN: AP PIN\n");
00722 return -1;
00723 }
00724
00725 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
00726 argv[0], argv[1]);
00727 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
00728 printf("Too long WPS_ER_LEARN command.\n");
00729 return -1;
00730 }
00731 return wpa_ctrl_command(ctrl, cmd);
00732 }
00733
00734
00735 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
00736 {
00737 char cmd[256];
00738 int res;
00739
00740 if (argc != 1) {
00741 printf("Invalid IBSS_RSN command: needs one argument "
00742 "(Peer STA MAC address)\n");
00743 return -1;
00744 }
00745
00746 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
00747 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
00748 printf("Too long IBSS_RSN command.\n");
00749 return -1;
00750 }
00751 return wpa_ctrl_command(ctrl, cmd);
00752 }
00753
00754
00755 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
00756 {
00757 char cmd[256];
00758 int res;
00759
00760 if (argc != 1) {
00761 printf("Invalid LEVEL command: needs one argument (debug "
00762 "level)\n");
00763 return -1;
00764 }
00765 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
00766 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
00767 printf("Too long LEVEL command.\n");
00768 return -1;
00769 }
00770 return wpa_ctrl_command(ctrl, cmd);
00771 }
00772
00773
00774 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
00775 {
00776 char cmd[256], *pos, *end;
00777 int i, ret;
00778
00779 if (argc < 2) {
00780 printf("Invalid IDENTITY command: needs two arguments "
00781 "(network id and identity)\n");
00782 return -1;
00783 }
00784
00785 end = cmd + sizeof(cmd);
00786 pos = cmd;
00787 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
00788 argv[0], argv[1]);
00789 if (ret < 0 || ret >= end - pos) {
00790 printf("Too long IDENTITY command.\n");
00791 return -1;
00792 }
00793 pos += ret;
00794 for (i = 2; i < argc; i++) {
00795 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
00796 if (ret < 0 || ret >= end - pos) {
00797 printf("Too long IDENTITY command.\n");
00798 return -1;
00799 }
00800 pos += ret;
00801 }
00802
00803 return wpa_ctrl_command(ctrl, cmd);
00804 }
00805
00806
00807 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
00808 {
00809 char cmd[256], *pos, *end;
00810 int i, ret;
00811
00812 if (argc < 2) {
00813 printf("Invalid PASSWORD command: needs two arguments "
00814 "(network id and password)\n");
00815 return -1;
00816 }
00817
00818 end = cmd + sizeof(cmd);
00819 pos = cmd;
00820 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
00821 argv[0], argv[1]);
00822 if (ret < 0 || ret >= end - pos) {
00823 printf("Too long PASSWORD command.\n");
00824 return -1;
00825 }
00826 pos += ret;
00827 for (i = 2; i < argc; i++) {
00828 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
00829 if (ret < 0 || ret >= end - pos) {
00830 printf("Too long PASSWORD command.\n");
00831 return -1;
00832 }
00833 pos += ret;
00834 }
00835
00836 return wpa_ctrl_command(ctrl, cmd);
00837 }
00838
00839
00840 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
00841 char *argv[])
00842 {
00843 char cmd[256], *pos, *end;
00844 int i, ret;
00845
00846 if (argc < 2) {
00847 printf("Invalid NEW_PASSWORD command: needs two arguments "
00848 "(network id and password)\n");
00849 return -1;
00850 }
00851
00852 end = cmd + sizeof(cmd);
00853 pos = cmd;
00854 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
00855 argv[0], argv[1]);
00856 if (ret < 0 || ret >= end - pos) {
00857 printf("Too long NEW_PASSWORD command.\n");
00858 return -1;
00859 }
00860 pos += ret;
00861 for (i = 2; i < argc; i++) {
00862 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
00863 if (ret < 0 || ret >= end - pos) {
00864 printf("Too long NEW_PASSWORD command.\n");
00865 return -1;
00866 }
00867 pos += ret;
00868 }
00869
00870 return wpa_ctrl_command(ctrl, cmd);
00871 }
00872
00873
00874 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
00875 {
00876 char cmd[256], *pos, *end;
00877 int i, ret;
00878
00879 if (argc < 2) {
00880 printf("Invalid PIN command: needs two arguments "
00881 "(network id and pin)\n");
00882 return -1;
00883 }
00884
00885 end = cmd + sizeof(cmd);
00886 pos = cmd;
00887 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
00888 argv[0], argv[1]);
00889 if (ret < 0 || ret >= end - pos) {
00890 printf("Too long PIN command.\n");
00891 return -1;
00892 }
00893 pos += ret;
00894 for (i = 2; i < argc; i++) {
00895 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
00896 if (ret < 0 || ret >= end - pos) {
00897 printf("Too long PIN command.\n");
00898 return -1;
00899 }
00900 pos += ret;
00901 }
00902 return wpa_ctrl_command(ctrl, cmd);
00903 }
00904
00905
00906 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
00907 {
00908 char cmd[256], *pos, *end;
00909 int i, ret;
00910
00911 if (argc < 2) {
00912 printf("Invalid OTP command: needs two arguments (network "
00913 "id and password)\n");
00914 return -1;
00915 }
00916
00917 end = cmd + sizeof(cmd);
00918 pos = cmd;
00919 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
00920 argv[0], argv[1]);
00921 if (ret < 0 || ret >= end - pos) {
00922 printf("Too long OTP command.\n");
00923 return -1;
00924 }
00925 pos += ret;
00926 for (i = 2; i < argc; i++) {
00927 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
00928 if (ret < 0 || ret >= end - pos) {
00929 printf("Too long OTP command.\n");
00930 return -1;
00931 }
00932 pos += ret;
00933 }
00934
00935 return wpa_ctrl_command(ctrl, cmd);
00936 }
00937
00938
00939 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
00940 char *argv[])
00941 {
00942 char cmd[256], *pos, *end;
00943 int i, ret;
00944
00945 if (argc < 2) {
00946 printf("Invalid PASSPHRASE command: needs two arguments "
00947 "(network id and passphrase)\n");
00948 return -1;
00949 }
00950
00951 end = cmd + sizeof(cmd);
00952 pos = cmd;
00953 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
00954 argv[0], argv[1]);
00955 if (ret < 0 || ret >= end - pos) {
00956 printf("Too long PASSPHRASE command.\n");
00957 return -1;
00958 }
00959 pos += ret;
00960 for (i = 2; i < argc; i++) {
00961 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
00962 if (ret < 0 || ret >= end - pos) {
00963 printf("Too long PASSPHRASE command.\n");
00964 return -1;
00965 }
00966 pos += ret;
00967 }
00968
00969 return wpa_ctrl_command(ctrl, cmd);
00970 }
00971
00972
00973 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
00974 {
00975 char cmd[256], *pos, *end;
00976 int i, ret;
00977
00978 if (argc < 2) {
00979 printf("Invalid BSSID command: needs two arguments (network "
00980 "id and BSSID)\n");
00981 return -1;
00982 }
00983
00984 end = cmd + sizeof(cmd);
00985 pos = cmd;
00986 ret = os_snprintf(pos, end - pos, "BSSID");
00987 if (ret < 0 || ret >= end - pos) {
00988 printf("Too long BSSID command.\n");
00989 return -1;
00990 }
00991 pos += ret;
00992 for (i = 0; i < argc; i++) {
00993 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
00994 if (ret < 0 || ret >= end - pos) {
00995 printf("Too long BSSID command.\n");
00996 return -1;
00997 }
00998 pos += ret;
00999 }
01000
01001 return wpa_ctrl_command(ctrl, cmd);
01002 }
01003
01004
01005 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
01006 char *argv[])
01007 {
01008 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
01009 }
01010
01011
01012 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
01013 char *argv[])
01014 {
01015 char cmd[32];
01016 int res;
01017
01018 if (argc < 1) {
01019 printf("Invalid SELECT_NETWORK command: needs one argument "
01020 "(network id)\n");
01021 return -1;
01022 }
01023
01024 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
01025 if (res < 0 || (size_t) res >= sizeof(cmd))
01026 return -1;
01027 cmd[sizeof(cmd) - 1] = '\0';
01028
01029 return wpa_ctrl_command(ctrl, cmd);
01030 }
01031
01032
01033 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
01034 char *argv[])
01035 {
01036 char cmd[32];
01037 int res;
01038
01039 if (argc < 1) {
01040 printf("Invalid ENABLE_NETWORK command: needs one argument "
01041 "(network id)\n");
01042 return -1;
01043 }
01044
01045 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
01046 if (res < 0 || (size_t) res >= sizeof(cmd))
01047 return -1;
01048 cmd[sizeof(cmd) - 1] = '\0';
01049
01050 return wpa_ctrl_command(ctrl, cmd);
01051 }
01052
01053
01054 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
01055 char *argv[])
01056 {
01057 char cmd[32];
01058 int res;
01059
01060 if (argc < 1) {
01061 printf("Invalid DISABLE_NETWORK command: needs one argument "
01062 "(network id)\n");
01063 return -1;
01064 }
01065
01066 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
01067 if (res < 0 || (size_t) res >= sizeof(cmd))
01068 return -1;
01069 cmd[sizeof(cmd) - 1] = '\0';
01070
01071 return wpa_ctrl_command(ctrl, cmd);
01072 }
01073
01074
01075 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
01076 char *argv[])
01077 {
01078 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
01079 }
01080
01081
01082 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
01083 char *argv[])
01084 {
01085 char cmd[32];
01086 int res;
01087
01088 if (argc < 1) {
01089 printf("Invalid REMOVE_NETWORK command: needs one argument "
01090 "(network id)\n");
01091 return -1;
01092 }
01093
01094 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
01095 if (res < 0 || (size_t) res >= sizeof(cmd))
01096 return -1;
01097 cmd[sizeof(cmd) - 1] = '\0';
01098
01099 return wpa_ctrl_command(ctrl, cmd);
01100 }
01101
01102
01103 static void wpa_cli_show_network_variables(void)
01104 {
01105 printf("set_network variables:\n"
01106 " ssid (network name, SSID)\n"
01107 " psk (WPA passphrase or pre-shared key)\n"
01108 " key_mgmt (key management protocol)\n"
01109 " identity (EAP identity)\n"
01110 " password (EAP password)\n"
01111 " ...\n"
01112 "\n"
01113 "Note: Values are entered in the same format as the "
01114 "configuration file is using,\n"
01115 "i.e., strings values need to be inside double quotation "
01116 "marks.\n"
01117 "For example: set_network 1 ssid \"network name\"\n"
01118 "\n"
01119 "Please see wpa_supplicant.conf documentation for full list "
01120 "of\navailable variables.\n");
01121 }
01122
01123
01124 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
01125 char *argv[])
01126 {
01127 char cmd[256];
01128 int res;
01129
01130 if (argc == 0) {
01131 wpa_cli_show_network_variables();
01132 return 0;
01133 }
01134
01135 if (argc != 3) {
01136 printf("Invalid SET_NETWORK command: needs three arguments\n"
01137 "(network id, variable name, and value)\n");
01138 return -1;
01139 }
01140
01141 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
01142 argv[0], argv[1], argv[2]);
01143 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
01144 printf("Too long SET_NETWORK command.\n");
01145 return -1;
01146 }
01147 return wpa_ctrl_command(ctrl, cmd);
01148 }
01149
01150
01151 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
01152 char *argv[])
01153 {
01154 char cmd[256];
01155 int res;
01156
01157 if (argc == 0) {
01158 wpa_cli_show_network_variables();
01159 return 0;
01160 }
01161
01162 if (argc != 2) {
01163 printf("Invalid GET_NETWORK command: needs two arguments\n"
01164 "(network id and variable name)\n");
01165 return -1;
01166 }
01167
01168 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
01169 argv[0], argv[1]);
01170 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
01171 printf("Too long GET_NETWORK command.\n");
01172 return -1;
01173 }
01174 return wpa_ctrl_command(ctrl, cmd);
01175 }
01176
01177
01178 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
01179 char *argv[])
01180 {
01181 return wpa_ctrl_command(ctrl, "DISCONNECT");
01182 }
01183
01184
01185 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
01186 char *argv[])
01187 {
01188 return wpa_ctrl_command(ctrl, "RECONNECT");
01189 }
01190
01191
01192 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
01193 char *argv[])
01194 {
01195 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
01196 }
01197
01198
01199 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
01200 {
01201 return wpa_ctrl_command(ctrl, "SCAN");
01202 }
01203
01204
01205 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
01206 char *argv[])
01207 {
01208 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
01209 }
01210
01211
01212 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
01213 {
01214 char cmd[64];
01215 int res;
01216
01217 if (argc != 1) {
01218 printf("Invalid BSS command: need one argument (index or "
01219 "BSSID)\n");
01220 return -1;
01221 }
01222
01223 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
01224 if (res < 0 || (size_t) res >= sizeof(cmd))
01225 return -1;
01226 cmd[sizeof(cmd) - 1] = '\0';
01227
01228 return wpa_ctrl_command(ctrl, cmd);
01229 }
01230
01231
01232 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
01233 char *argv[])
01234 {
01235 char cmd[64];
01236 int res;
01237
01238 if (argc < 1 || argc > 2) {
01239 printf("Invalid GET_CAPABILITY command: need either one or "
01240 "two arguments\n");
01241 return -1;
01242 }
01243
01244 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
01245 printf("Invalid GET_CAPABILITY command: second argument, "
01246 "if any, must be 'strict'\n");
01247 return -1;
01248 }
01249
01250 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
01251 (argc == 2) ? " strict" : "");
01252 if (res < 0 || (size_t) res >= sizeof(cmd))
01253 return -1;
01254 cmd[sizeof(cmd) - 1] = '\0';
01255
01256 return wpa_ctrl_command(ctrl, cmd);
01257 }
01258
01259
01260 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
01261 {
01262 printf("Available interfaces:\n");
01263 return wpa_ctrl_command(ctrl, "INTERFACES");
01264 }
01265
01266
01267 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
01268 {
01269 if (argc < 1) {
01270 wpa_cli_list_interfaces(ctrl);
01271 return 0;
01272 }
01273
01274 wpa_cli_close_connection();
01275 os_free(ctrl_ifname);
01276 ctrl_ifname = os_strdup(argv[0]);
01277
01278 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
01279 printf("Connected to interface '%s.\n", ctrl_ifname);
01280 } else {
01281 printf("Could not connect to interface '%s' - re-trying\n",
01282 ctrl_ifname);
01283 }
01284 return 0;
01285 }
01286
01287
01288 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
01289 char *argv[])
01290 {
01291 return wpa_ctrl_command(ctrl, "RECONFIGURE");
01292 }
01293
01294
01295 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
01296 char *argv[])
01297 {
01298 return wpa_ctrl_command(ctrl, "TERMINATE");
01299 }
01300
01301
01302 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
01303 char *argv[])
01304 {
01305 char cmd[256];
01306 int res;
01307
01308 if (argc < 1) {
01309 printf("Invalid INTERFACE_ADD command: needs at least one "
01310 "argument (interface name)\n"
01311 "All arguments: ifname confname driver ctrl_interface "
01312 "driver_param bridge_name\n");
01313 return -1;
01314 }
01315
01316
01317
01318
01319
01320 res = os_snprintf(cmd, sizeof(cmd),
01321 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
01322 argv[0],
01323 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
01324 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
01325 argc > 5 ? argv[5] : "");
01326 if (res < 0 || (size_t) res >= sizeof(cmd))
01327 return -1;
01328 cmd[sizeof(cmd) - 1] = '\0';
01329 return wpa_ctrl_command(ctrl, cmd);
01330 }
01331
01332
01333 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
01334 char *argv[])
01335 {
01336 char cmd[128];
01337 int res;
01338
01339 if (argc != 1) {
01340 printf("Invalid INTERFACE_REMOVE command: needs one argument "
01341 "(interface name)\n");
01342 return -1;
01343 }
01344
01345 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
01346 if (res < 0 || (size_t) res >= sizeof(cmd))
01347 return -1;
01348 cmd[sizeof(cmd) - 1] = '\0';
01349 return wpa_ctrl_command(ctrl, cmd);
01350 }
01351
01352
01353 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
01354 char *argv[])
01355 {
01356 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
01357 }
01358
01359
01360 #ifdef CONFIG_AP
01361 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
01362 {
01363 char buf[64];
01364 if (argc != 1) {
01365 printf("Invalid 'sta' command - exactly one argument, STA "
01366 "address, is required.\n");
01367 return -1;
01368 }
01369 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
01370 return wpa_ctrl_command(ctrl, buf);
01371 }
01372
01373
01374 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
01375 char *addr, size_t addr_len)
01376 {
01377 char buf[4096], *pos;
01378 size_t len;
01379 int ret;
01380
01381 if (ctrl_conn == NULL) {
01382 printf("Not connected to hostapd - command dropped.\n");
01383 return -1;
01384 }
01385 len = sizeof(buf) - 1;
01386 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
01387 wpa_cli_msg_cb);
01388 if (ret == -2) {
01389 printf("'%s' command timed out.\n", cmd);
01390 return -2;
01391 } else if (ret < 0) {
01392 printf("'%s' command failed.\n", cmd);
01393 return -1;
01394 }
01395
01396 buf[len] = '\0';
01397 if (memcmp(buf, "FAIL", 4) == 0)
01398 return -1;
01399 printf("%s", buf);
01400
01401 pos = buf;
01402 while (*pos != '\0' && *pos != '\n')
01403 pos++;
01404 *pos = '\0';
01405 os_strlcpy(addr, buf, addr_len);
01406 return 0;
01407 }
01408
01409
01410 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
01411 {
01412 char addr[32], cmd[64];
01413
01414 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
01415 return 0;
01416 do {
01417 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
01418 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
01419
01420 return -1;
01421 }
01422 #endif
01423
01424
01425 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
01426 {
01427 return wpa_ctrl_command(ctrl, "SUSPEND");
01428 }
01429
01430
01431 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
01432 {
01433 return wpa_ctrl_command(ctrl, "RESUME");
01434 }
01435
01436
01437 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
01438 {
01439 return wpa_ctrl_command(ctrl, "DROP_SA");
01440 }
01441
01442
01443 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
01444 {
01445 char cmd[128];
01446 int res;
01447
01448 if (argc != 1) {
01449 printf("Invalid ROAM command: needs one argument "
01450 "(target AP's BSSID)\n");
01451 return -1;
01452 }
01453
01454 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
01455 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
01456 printf("Too long ROAM command.\n");
01457 return -1;
01458 }
01459 return wpa_ctrl_command(ctrl, cmd);
01460 }
01461
01462
01463 enum wpa_cli_cmd_flags {
01464 cli_cmd_flag_none = 0x00,
01465 cli_cmd_flag_sensitive = 0x01
01466 };
01467
01468 struct wpa_cli_cmd {
01469 const char *cmd;
01470 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
01471 enum wpa_cli_cmd_flags flags;
01472 const char *usage;
01473 };
01474
01475 static struct wpa_cli_cmd wpa_cli_commands[] = {
01476 { "status", wpa_cli_cmd_status,
01477 cli_cmd_flag_none,
01478 "[verbose] = get current WPA/EAPOL/EAP status" },
01479 { "ping", wpa_cli_cmd_ping,
01480 cli_cmd_flag_none,
01481 "= pings wpa_supplicant" },
01482 { "mib", wpa_cli_cmd_mib,
01483 cli_cmd_flag_none,
01484 "= get MIB variables (dot1x, dot11)" },
01485 { "help", wpa_cli_cmd_help,
01486 cli_cmd_flag_none,
01487 "= show this usage help" },
01488 { "interface", wpa_cli_cmd_interface,
01489 cli_cmd_flag_none,
01490 "[ifname] = show interfaces/select interface" },
01491 { "level", wpa_cli_cmd_level,
01492 cli_cmd_flag_none,
01493 "<debug level> = change debug level" },
01494 { "license", wpa_cli_cmd_license,
01495 cli_cmd_flag_none,
01496 "= show full wpa_cli license" },
01497 { "quit", wpa_cli_cmd_quit,
01498 cli_cmd_flag_none,
01499 "= exit wpa_cli" },
01500 { "set", wpa_cli_cmd_set,
01501 cli_cmd_flag_none,
01502 "= set variables (shows list of variables when run without "
01503 "arguments)" },
01504 { "logon", wpa_cli_cmd_logon,
01505 cli_cmd_flag_none,
01506 "= IEEE 802.1X EAPOL state machine logon" },
01507 { "logoff", wpa_cli_cmd_logoff,
01508 cli_cmd_flag_none,
01509 "= IEEE 802.1X EAPOL state machine logoff" },
01510 { "pmksa", wpa_cli_cmd_pmksa,
01511 cli_cmd_flag_none,
01512 "= show PMKSA cache" },
01513 { "reassociate", wpa_cli_cmd_reassociate,
01514 cli_cmd_flag_none,
01515 "= force reassociation" },
01516 { "preauthenticate", wpa_cli_cmd_preauthenticate,
01517 cli_cmd_flag_none,
01518 "<BSSID> = force preauthentication" },
01519 { "identity", wpa_cli_cmd_identity,
01520 cli_cmd_flag_none,
01521 "<network id> <identity> = configure identity for an SSID" },
01522 { "password", wpa_cli_cmd_password,
01523 cli_cmd_flag_sensitive,
01524 "<network id> <password> = configure password for an SSID" },
01525 { "new_password", wpa_cli_cmd_new_password,
01526 cli_cmd_flag_sensitive,
01527 "<network id> <password> = change password for an SSID" },
01528 { "pin", wpa_cli_cmd_pin,
01529 cli_cmd_flag_sensitive,
01530 "<network id> <pin> = configure pin for an SSID" },
01531 { "otp", wpa_cli_cmd_otp,
01532 cli_cmd_flag_sensitive,
01533 "<network id> <password> = configure one-time-password for an SSID"
01534 },
01535 { "passphrase", wpa_cli_cmd_passphrase,
01536 cli_cmd_flag_sensitive,
01537 "<network id> <passphrase> = configure private key passphrase\n"
01538 " for an SSID" },
01539 { "bssid", wpa_cli_cmd_bssid,
01540 cli_cmd_flag_none,
01541 "<network id> <BSSID> = set preferred BSSID for an SSID" },
01542 { "list_networks", wpa_cli_cmd_list_networks,
01543 cli_cmd_flag_none,
01544 "= list configured networks" },
01545 { "select_network", wpa_cli_cmd_select_network,
01546 cli_cmd_flag_none,
01547 "<network id> = select a network (disable others)" },
01548 { "enable_network", wpa_cli_cmd_enable_network,
01549 cli_cmd_flag_none,
01550 "<network id> = enable a network" },
01551 { "disable_network", wpa_cli_cmd_disable_network,
01552 cli_cmd_flag_none,
01553 "<network id> = disable a network" },
01554 { "add_network", wpa_cli_cmd_add_network,
01555 cli_cmd_flag_none,
01556 "= add a network" },
01557 { "remove_network", wpa_cli_cmd_remove_network,
01558 cli_cmd_flag_none,
01559 "<network id> = remove a network" },
01560 { "set_network", wpa_cli_cmd_set_network,
01561 cli_cmd_flag_sensitive,
01562 "<network id> <variable> <value> = set network variables (shows\n"
01563 " list of variables when run without arguments)" },
01564 { "get_network", wpa_cli_cmd_get_network,
01565 cli_cmd_flag_none,
01566 "<network id> <variable> = get network variables" },
01567 { "save_config", wpa_cli_cmd_save_config,
01568 cli_cmd_flag_none,
01569 "= save the current configuration" },
01570 { "disconnect", wpa_cli_cmd_disconnect,
01571 cli_cmd_flag_none,
01572 "= disconnect and wait for reassociate/reconnect command before\n"
01573 " connecting" },
01574 { "reconnect", wpa_cli_cmd_reconnect,
01575 cli_cmd_flag_none,
01576 "= like reassociate, but only takes effect if already disconnected"
01577 },
01578 { "scan", wpa_cli_cmd_scan,
01579 cli_cmd_flag_none,
01580 "= request new BSS scan" },
01581 { "scan_results", wpa_cli_cmd_scan_results,
01582 cli_cmd_flag_none,
01583 "= get latest scan results" },
01584 { "bss", wpa_cli_cmd_bss,
01585 cli_cmd_flag_none,
01586 "<<idx> | <bssid>> = get detailed scan result info" },
01587 { "get_capability", wpa_cli_cmd_get_capability,
01588 cli_cmd_flag_none,
01589 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
01590 { "reconfigure", wpa_cli_cmd_reconfigure,
01591 cli_cmd_flag_none,
01592 "= force wpa_supplicant to re-read its configuration file" },
01593 { "terminate", wpa_cli_cmd_terminate,
01594 cli_cmd_flag_none,
01595 "= terminate wpa_supplicant" },
01596 { "interface_add", wpa_cli_cmd_interface_add,
01597 cli_cmd_flag_none,
01598 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
01599 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
01600 " are optional" },
01601 { "interface_remove", wpa_cli_cmd_interface_remove,
01602 cli_cmd_flag_none,
01603 "<ifname> = removes the interface" },
01604 { "interface_list", wpa_cli_cmd_interface_list,
01605 cli_cmd_flag_none,
01606 "= list available interfaces" },
01607 { "ap_scan", wpa_cli_cmd_ap_scan,
01608 cli_cmd_flag_none,
01609 "<value> = set ap_scan parameter" },
01610 { "stkstart", wpa_cli_cmd_stkstart,
01611 cli_cmd_flag_none,
01612 "<addr> = request STK negotiation with <addr>" },
01613 { "ft_ds", wpa_cli_cmd_ft_ds,
01614 cli_cmd_flag_none,
01615 "<addr> = request over-the-DS FT with <addr>" },
01616 { "wps_pbc", wpa_cli_cmd_wps_pbc,
01617 cli_cmd_flag_none,
01618 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
01619 { "wps_pin", wpa_cli_cmd_wps_pin,
01620 cli_cmd_flag_sensitive,
01621 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
01622 "hardcoded)" },
01623 #ifdef CONFIG_WPS_OOB
01624 { "wps_oob", wpa_cli_cmd_wps_oob,
01625 cli_cmd_flag_sensitive,
01626 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
01627 #endif
01628 { "wps_reg", wpa_cli_cmd_wps_reg,
01629 cli_cmd_flag_sensitive,
01630 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
01631 { "wps_er_start", wpa_cli_cmd_wps_er_start,
01632 cli_cmd_flag_none,
01633 "= start Wi-Fi Protected Setup External Registrar" },
01634 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
01635 cli_cmd_flag_none,
01636 "= stop Wi-Fi Protected Setup External Registrar" },
01637 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
01638 cli_cmd_flag_sensitive,
01639 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
01640 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
01641 cli_cmd_flag_none,
01642 "<UUID> = accept an Enrollee PBC using External Registrar" },
01643 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
01644 cli_cmd_flag_sensitive,
01645 "<UUID> <PIN> = learn AP configuration" },
01646 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
01647 cli_cmd_flag_none,
01648 "<addr> = request RSN authentication with <addr> in IBSS" },
01649 #ifdef CONFIG_AP
01650 { "sta", wpa_cli_cmd_sta,
01651 cli_cmd_flag_none,
01652 "<addr> = get information about an associated station (AP)" },
01653 { "all_sta", wpa_cli_cmd_all_sta,
01654 cli_cmd_flag_none,
01655 "= get information about all associated stations (AP)" },
01656 #endif
01657 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
01658 "= notification of suspend/hibernate" },
01659 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
01660 "= notification of resume/thaw" },
01661 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
01662 "= drop SA without deauth/disassoc (test command)" },
01663 { "roam", wpa_cli_cmd_roam,
01664 cli_cmd_flag_none,
01665 "<addr> = roam to the specified BSS" },
01666 { NULL, NULL, cli_cmd_flag_none, NULL }
01667 };
01668
01669
01670
01671
01672
01673 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
01674 {
01675 char c;
01676 size_t n;
01677
01678 printf("%s%s ", pad, cmd->cmd);
01679 for (n = 0; (c = cmd->usage[n]); n++) {
01680 printf("%c", c);
01681 if (c == '\n')
01682 printf("%s", pad);
01683 }
01684 printf("\n");
01685 }
01686
01687
01688 static void print_help(void)
01689 {
01690 int n;
01691 printf("commands:\n");
01692 for (n = 0; wpa_cli_commands[n].cmd; n++)
01693 print_cmd_help(&wpa_cli_commands[n], " ");
01694 }
01695
01696
01697 #ifdef CONFIG_READLINE
01698 static int cmd_has_sensitive_data(const char *cmd)
01699 {
01700 const char *c, *delim;
01701 int n;
01702 size_t len;
01703
01704 delim = os_strchr(cmd, ' ');
01705 if (delim)
01706 len = delim - cmd;
01707 else
01708 len = os_strlen(cmd);
01709
01710 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
01711 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
01712 return (wpa_cli_commands[n].flags &
01713 cli_cmd_flag_sensitive);
01714 }
01715 return 0;
01716 }
01717 #endif
01718
01719
01720 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
01721 {
01722 struct wpa_cli_cmd *cmd, *match = NULL;
01723 int count;
01724 int ret = 0;
01725
01726 count = 0;
01727 cmd = wpa_cli_commands;
01728 while (cmd->cmd) {
01729 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
01730 {
01731 match = cmd;
01732 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
01733
01734 count = 1;
01735 break;
01736 }
01737 count++;
01738 }
01739 cmd++;
01740 }
01741
01742 if (count > 1) {
01743 printf("Ambiguous command '%s'; possible commands:", argv[0]);
01744 cmd = wpa_cli_commands;
01745 while (cmd->cmd) {
01746 if (os_strncasecmp(cmd->cmd, argv[0],
01747 os_strlen(argv[0])) == 0) {
01748 printf(" %s", cmd->cmd);
01749 }
01750 cmd++;
01751 }
01752 printf("\n");
01753 ret = 1;
01754 } else if (count == 0) {
01755 printf("Unknown command '%s'\n", argv[0]);
01756 ret = 1;
01757 } else {
01758 ret = match->handler(ctrl, argc - 1, &argv[1]);
01759 }
01760
01761 return ret;
01762 }
01763
01764
01765 static int str_match(const char *a, const char *b)
01766 {
01767 return os_strncmp(a, b, os_strlen(b)) == 0;
01768 }
01769
01770
01771 static int wpa_cli_exec(const char *program, const char *arg1,
01772 const char *arg2)
01773 {
01774 char *cmd;
01775 size_t len;
01776 int res;
01777 int ret = 0;
01778
01779 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
01780 cmd = os_malloc(len);
01781 if (cmd == NULL)
01782 return -1;
01783 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
01784 if (res < 0 || (size_t) res >= len) {
01785 os_free(cmd);
01786 return -1;
01787 }
01788 cmd[len - 1] = '\0';
01789 #ifndef _WIN32_WCE
01790 if (system(cmd) < 0)
01791 ret = -1;
01792 #endif
01793 os_free(cmd);
01794
01795 return ret;
01796 }
01797
01798
01799 static void wpa_cli_action_process(const char *msg)
01800 {
01801 const char *pos;
01802 char *copy = NULL, *id, *pos2;
01803
01804 pos = msg;
01805 if (*pos == '<') {
01806
01807 pos = os_strchr(pos, '>');
01808 if (pos)
01809 pos++;
01810 else
01811 pos = msg;
01812 }
01813
01814 if (str_match(pos, WPA_EVENT_CONNECTED)) {
01815 int new_id = -1;
01816 os_unsetenv("WPA_ID");
01817 os_unsetenv("WPA_ID_STR");
01818 os_unsetenv("WPA_CTRL_DIR");
01819
01820 pos = os_strstr(pos, "[id=");
01821 if (pos)
01822 copy = os_strdup(pos + 4);
01823
01824 if (copy) {
01825 pos2 = id = copy;
01826 while (*pos2 && *pos2 != ' ')
01827 pos2++;
01828 *pos2++ = '\0';
01829 new_id = atoi(id);
01830 os_setenv("WPA_ID", id, 1);
01831 while (*pos2 && *pos2 != '=')
01832 pos2++;
01833 if (*pos2 == '=')
01834 pos2++;
01835 id = pos2;
01836 while (*pos2 && *pos2 != ']')
01837 pos2++;
01838 *pos2 = '\0';
01839 os_setenv("WPA_ID_STR", id, 1);
01840 os_free(copy);
01841 }
01842
01843 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
01844
01845 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
01846 wpa_cli_connected = 1;
01847 wpa_cli_last_id = new_id;
01848 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
01849 }
01850 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
01851 if (wpa_cli_connected) {
01852 wpa_cli_connected = 0;
01853 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
01854 }
01855 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
01856 printf("wpa_supplicant is terminating - stop monitoring\n");
01857 wpa_cli_quit = 1;
01858 }
01859 }
01860
01861
01862 #ifndef CONFIG_ANSI_C_EXTRA
01863 static void wpa_cli_action_cb(char *msg, size_t len)
01864 {
01865 wpa_cli_action_process(msg);
01866 }
01867 #endif
01868
01869
01870 static void wpa_cli_reconnect(void)
01871 {
01872 wpa_cli_close_connection();
01873 wpa_cli_open_connection(ctrl_ifname, 1);
01874 }
01875
01876
01877 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
01878 int action_monitor)
01879 {
01880 int first = 1;
01881 if (ctrl_conn == NULL) {
01882 wpa_cli_reconnect();
01883 return;
01884 }
01885 while (wpa_ctrl_pending(ctrl) > 0) {
01886 char buf[256];
01887 size_t len = sizeof(buf) - 1;
01888 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
01889 buf[len] = '\0';
01890 if (action_monitor)
01891 wpa_cli_action_process(buf);
01892 else {
01893 if (in_read && first)
01894 printf("\r");
01895 first = 0;
01896 printf("%s\n", buf);
01897 #ifdef CONFIG_READLINE
01898 rl_on_new_line();
01899 rl_redisplay();
01900 #endif
01901 }
01902 } else {
01903 printf("Could not read pending message.\n");
01904 break;
01905 }
01906 }
01907
01908 if (wpa_ctrl_pending(ctrl) < 0) {
01909 printf("Connection to wpa_supplicant lost - trying to "
01910 "reconnect\n");
01911 wpa_cli_reconnect();
01912 }
01913 }
01914
01915
01916 #ifdef CONFIG_READLINE
01917 static char * wpa_cli_cmd_gen(const char *text, int state)
01918 {
01919 static int i, len;
01920 const char *cmd;
01921
01922 if (state == 0) {
01923 i = 0;
01924 len = os_strlen(text);
01925 }
01926
01927 while ((cmd = wpa_cli_commands[i].cmd)) {
01928 i++;
01929 if (os_strncasecmp(cmd, text, len) == 0)
01930 return strdup(cmd);
01931 }
01932
01933 return NULL;
01934 }
01935
01936
01937 static char * wpa_cli_dummy_gen(const char *text, int state)
01938 {
01939 int i;
01940
01941 for (i = 0; wpa_cli_commands[i].cmd; i++) {
01942 const char *cmd = wpa_cli_commands[i].cmd;
01943 size_t len = os_strlen(cmd);
01944 if (os_strncasecmp(rl_line_buffer, cmd, len) == 0 &&
01945 rl_line_buffer[len] == ' ') {
01946 printf("\n%s\n", wpa_cli_commands[i].usage);
01947 rl_on_new_line();
01948 rl_redisplay();
01949 break;
01950 }
01951 }
01952
01953 rl_attempted_completion_over = 1;
01954 return NULL;
01955 }
01956
01957
01958 static char * wpa_cli_status_gen(const char *text, int state)
01959 {
01960 static int i, len;
01961 char *options[] = {
01962 "verbose", NULL
01963 };
01964 char *t;
01965
01966 if (state == 0) {
01967 i = 0;
01968 len = os_strlen(text);
01969 }
01970
01971 while ((t = options[i])) {
01972 i++;
01973 if (os_strncasecmp(t, text, len) == 0)
01974 return strdup(t);
01975 }
01976
01977 rl_attempted_completion_over = 1;
01978 return NULL;
01979 }
01980
01981
01982 static char ** wpa_cli_completion(const char *text, int start, int end)
01983 {
01984 char * (*func)(const char *text, int state);
01985
01986 if (start == 0)
01987 func = wpa_cli_cmd_gen;
01988 else if (os_strncasecmp(rl_line_buffer, "status ", 7) == 0)
01989 func = wpa_cli_status_gen;
01990 else
01991 func = wpa_cli_dummy_gen;
01992 return rl_completion_matches(text, func);
01993 }
01994 #endif
01995
01996
01997 static void wpa_cli_interactive(void)
01998 {
01999 #define max_args 10
02000 char cmdbuf[256], *cmd, *argv[max_args], *pos;
02001 int argc;
02002 #ifdef CONFIG_READLINE
02003 char *home, *hfile = NULL;
02004 #endif
02005
02006 printf("\nInteractive mode\n\n");
02007
02008 #ifdef CONFIG_READLINE
02009 rl_attempted_completion_function = wpa_cli_completion;
02010 home = getenv("HOME");
02011 if (home) {
02012 const char *fname = ".wpa_cli_history";
02013 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
02014 hfile = os_malloc(hfile_len);
02015 if (hfile) {
02016 int res;
02017 res = os_snprintf(hfile, hfile_len, "%s/%s", home,
02018 fname);
02019 if (res >= 0 && res < hfile_len) {
02020 hfile[hfile_len - 1] = '\0';
02021 read_history(hfile);
02022 stifle_history(100);
02023 }
02024 }
02025 }
02026 #endif
02027
02028 do {
02029 wpa_cli_recv_pending(mon_conn, 0, 0);
02030 #ifndef CONFIG_NATIVE_WINDOWS
02031 alarm(ping_interval);
02032 #endif
02033 #ifdef CONFIG_WPA_CLI_FORK
02034 if (mon_pid)
02035 kill(mon_pid, SIGUSR1);
02036 #endif
02037 #ifdef CONFIG_READLINE
02038 cmd = readline("> ");
02039 if (cmd && *cmd) {
02040 HIST_ENTRY *h;
02041 while (next_history())
02042 ;
02043 h = previous_history();
02044 if (h == NULL || os_strcmp(cmd, h->line) != 0)
02045 add_history(cmd);
02046 next_history();
02047 }
02048 #else
02049 printf("> ");
02050 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
02051 #endif
02052 #ifndef CONFIG_NATIVE_WINDOWS
02053 alarm(0);
02054 #endif
02055 if (cmd == NULL)
02056 break;
02057 wpa_cli_recv_pending(mon_conn, 0, 0);
02058 pos = cmd;
02059 while (*pos != '\0') {
02060 if (*pos == '\n') {
02061 *pos = '\0';
02062 break;
02063 }
02064 pos++;
02065 }
02066 argc = 0;
02067 pos = cmd;
02068 for (;;) {
02069 while (*pos == ' ')
02070 pos++;
02071 if (*pos == '\0')
02072 break;
02073 argv[argc] = pos;
02074 argc++;
02075 if (argc == max_args)
02076 break;
02077 if (*pos == '"') {
02078 char *pos2 = os_strrchr(pos, '"');
02079 if (pos2)
02080 pos = pos2 + 1;
02081 }
02082 while (*pos != '\0' && *pos != ' ')
02083 pos++;
02084 if (*pos == ' ')
02085 *pos++ = '\0';
02086 }
02087 if (argc)
02088 wpa_request(ctrl_conn, argc, argv);
02089
02090 if (cmd != cmdbuf)
02091 free(cmd);
02092 #ifdef CONFIG_WPA_CLI_FORK
02093 if (mon_pid)
02094 kill(mon_pid, SIGUSR2);
02095 #endif
02096 } while (!wpa_cli_quit);
02097
02098 #ifdef CONFIG_READLINE
02099 if (hfile) {
02100
02101
02102 HIST_ENTRY *h;
02103 history_set_pos(0);
02104 while ((h = current_history())) {
02105 char *p = h->line;
02106 while (*p == ' ' || *p == '\t')
02107 p++;
02108 if (cmd_has_sensitive_data(p)) {
02109 h = remove_history(where_history());
02110 if (h) {
02111 os_free(h->line);
02112 os_free(h->data);
02113 os_free(h);
02114 } else
02115 next_history();
02116 } else
02117 next_history();
02118 }
02119 write_history(hfile);
02120 os_free(hfile);
02121 }
02122 #endif
02123 }
02124
02125
02126 static void wpa_cli_action(struct wpa_ctrl *ctrl)
02127 {
02128 #ifdef CONFIG_ANSI_C_EXTRA
02129
02130 printf("Action processing not supported in ANSI C build.\n");
02131 #else
02132 fd_set rfds;
02133 int fd, res;
02134 struct timeval tv;
02135 char buf[256];
02136 size_t len;
02137
02138 fd = wpa_ctrl_get_fd(ctrl);
02139
02140 while (!wpa_cli_quit) {
02141 FD_ZERO(&rfds);
02142 FD_SET(fd, &rfds);
02143 tv.tv_sec = ping_interval;
02144 tv.tv_usec = 0;
02145 res = select(fd + 1, &rfds, NULL, NULL, &tv);
02146 if (res < 0 && errno != EINTR) {
02147 perror("select");
02148 break;
02149 }
02150
02151 if (FD_ISSET(fd, &rfds))
02152 wpa_cli_recv_pending(ctrl, 0, 1);
02153 else {
02154
02155 len = sizeof(buf) - 1;
02156 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
02157 wpa_cli_action_cb) < 0 ||
02158 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
02159 printf("wpa_supplicant did not reply to PING "
02160 "command - exiting\n");
02161 break;
02162 }
02163 }
02164 }
02165 #endif
02166 }
02167
02168
02169 static void wpa_cli_cleanup(void)
02170 {
02171 wpa_cli_close_connection();
02172 if (pid_file)
02173 os_daemonize_terminate(pid_file);
02174
02175 os_program_deinit();
02176 }
02177
02178 static void wpa_cli_terminate(int sig)
02179 {
02180 wpa_cli_cleanup();
02181 exit(0);
02182 }
02183
02184
02185 #ifdef CONFIG_WPA_CLI_FORK
02186 static void wpa_cli_usr1(int sig)
02187 {
02188 #ifdef CONFIG_READLINE
02189 rl_on_new_line();
02190 rl_redisplay();
02191 #endif
02192 }
02193 #endif
02194
02195
02196 #ifndef CONFIG_NATIVE_WINDOWS
02197 static void wpa_cli_alarm(int sig)
02198 {
02199 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
02200 printf("Connection to wpa_supplicant lost - trying to "
02201 "reconnect\n");
02202 wpa_cli_close_connection();
02203 }
02204 if (!ctrl_conn)
02205 wpa_cli_reconnect();
02206 if (mon_conn)
02207 wpa_cli_recv_pending(mon_conn, 1, 0);
02208 alarm(ping_interval);
02209 }
02210 #endif
02211
02212
02213 static char * wpa_cli_get_default_ifname(void)
02214 {
02215 char *ifname = NULL;
02216
02217 #ifdef CONFIG_CTRL_IFACE_UNIX
02218 struct dirent *dent;
02219 DIR *dir = opendir(ctrl_iface_dir);
02220 if (!dir)
02221 return NULL;
02222 while ((dent = readdir(dir))) {
02223 #ifdef _DIRENT_HAVE_D_TYPE
02224
02225
02226
02227
02228
02229 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
02230 continue;
02231 #endif
02232 if (os_strcmp(dent->d_name, ".") == 0 ||
02233 os_strcmp(dent->d_name, "..") == 0)
02234 continue;
02235 printf("Selected interface '%s'\n", dent->d_name);
02236 ifname = os_strdup(dent->d_name);
02237 break;
02238 }
02239 closedir(dir);
02240 #endif
02241
02242 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
02243 char buf[2048], *pos;
02244 size_t len;
02245 struct wpa_ctrl *ctrl;
02246 int ret;
02247
02248 ctrl = wpa_ctrl_open(NULL);
02249 if (ctrl == NULL)
02250 return NULL;
02251
02252 len = sizeof(buf) - 1;
02253 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
02254 if (ret >= 0) {
02255 buf[len] = '\0';
02256 pos = os_strchr(buf, '\n');
02257 if (pos)
02258 *pos = '\0';
02259 ifname = os_strdup(buf);
02260 }
02261 wpa_ctrl_close(ctrl);
02262 #endif
02263
02264 return ifname;
02265 }
02266
02267
02268 int main(int argc, char *argv[])
02269 {
02270 int warning_displayed = 0;
02271 int c;
02272 int daemonize = 0;
02273 int ret = 0;
02274 const char *global = NULL;
02275
02276 if (os_program_init())
02277 return -1;
02278
02279 for (;;) {
02280 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
02281 if (c < 0)
02282 break;
02283 switch (c) {
02284 case 'a':
02285 action_file = optarg;
02286 break;
02287 case 'B':
02288 daemonize = 1;
02289 break;
02290 case 'g':
02291 global = optarg;
02292 break;
02293 case 'G':
02294 ping_interval = atoi(optarg);
02295 break;
02296 case 'h':
02297 usage();
02298 return 0;
02299 case 'v':
02300 printf("%s\n", wpa_cli_version);
02301 return 0;
02302 case 'i':
02303 os_free(ctrl_ifname);
02304 ctrl_ifname = os_strdup(optarg);
02305 break;
02306 case 'p':
02307 ctrl_iface_dir = optarg;
02308 break;
02309 case 'P':
02310 pid_file = optarg;
02311 break;
02312 default:
02313 usage();
02314 return -1;
02315 }
02316 }
02317
02318 interactive = (argc == optind) && (action_file == NULL);
02319
02320 if (interactive)
02321 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
02322
02323 if (global) {
02324 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
02325 ctrl_conn = wpa_ctrl_open(NULL);
02326 #else
02327 ctrl_conn = wpa_ctrl_open(global);
02328 #endif
02329 if (ctrl_conn == NULL) {
02330 perror("Failed to connect to wpa_supplicant - "
02331 "wpa_ctrl_open");
02332 return -1;
02333 }
02334 }
02335
02336 #ifndef _WIN32_WCE
02337 signal(SIGINT, wpa_cli_terminate);
02338 signal(SIGTERM, wpa_cli_terminate);
02339 #endif
02340 #ifndef CONFIG_NATIVE_WINDOWS
02341 signal(SIGALRM, wpa_cli_alarm);
02342 #endif
02343 #ifdef CONFIG_WPA_CLI_FORK
02344 signal(SIGUSR1, wpa_cli_usr1);
02345 #endif
02346
02347 if (ctrl_ifname == NULL)
02348 ctrl_ifname = wpa_cli_get_default_ifname();
02349
02350 if (interactive) {
02351 for (; !global;) {
02352 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
02353 if (warning_displayed)
02354 printf("Connection established.\n");
02355 break;
02356 }
02357
02358 if (!warning_displayed) {
02359 printf("Could not connect to wpa_supplicant - "
02360 "re-trying\n");
02361 warning_displayed = 1;
02362 }
02363 os_sleep(1, 0);
02364 continue;
02365 }
02366 } else {
02367 if (!global &&
02368 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
02369 perror("Failed to connect to wpa_supplicant - "
02370 "wpa_ctrl_open");
02371 return -1;
02372 }
02373
02374 if (action_file) {
02375 if (wpa_ctrl_attach(ctrl_conn) == 0) {
02376 wpa_cli_attached = 1;
02377 } else {
02378 printf("Warning: Failed to attach to "
02379 "wpa_supplicant.\n");
02380 return -1;
02381 }
02382 }
02383 }
02384
02385 if (daemonize && os_daemonize(pid_file))
02386 return -1;
02387
02388 if (interactive)
02389 wpa_cli_interactive();
02390 else if (action_file)
02391 wpa_cli_action(ctrl_conn);
02392 else
02393 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
02394
02395 os_free(ctrl_ifname);
02396 wpa_cli_cleanup();
02397
02398 return ret;
02399 }
02400
02401 #else
02402 int main(int argc, char *argv[])
02403 {
02404 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
02405 return -1;
02406 }
02407 #endif