$search
00001 /* 00002 * WPA Supplicant - command line interface for wpa_supplicant daemon 00003 * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 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 /* CONFIG_CTRL_IFACE_UNIX */ 00022 #ifdef CONFIG_READLINE 00023 #include <readline/readline.h> 00024 #include <readline/history.h> 00025 #endif /* CONFIG_READLINE */ 00026 #ifdef CONFIG_WPA_CLI_FORK 00027 #include <sys/wait.h> 00028 #endif /* CONFIG_WPA_CLI_FORK */ 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 /* CONFIG_WPA_CLI_FORK */ 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 /* CONFIG_WPA_CLI_FORK */ 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 /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ 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 /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */ 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 /* CONFIG_WPA_CLI_FORK */ 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 /* CONFIG_WPA_CLI_FORK */ 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 /* Any BSSID */ 00518 return wpa_ctrl_command(ctrl, "WPS_PBC"); 00519 } 00520 00521 /* Specific BSSID */ 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 /* Use dynamically generated PIN (returned as reply) */ 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 /* Use hardcoded PIN from a label */ 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 /* CONFIG_WPS_OOB */ 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 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB 01318 * <driver_param>TAB<bridge_name> 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 /* CONFIG_AP */ 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 /* CONFIG_WPS_OOB */ 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 /* CONFIG_AP */ 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 * Prints command usage, lines are padded with the specified string. 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 /* CONFIG_READLINE */ 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 /* we have an exact match */ 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 /* _WIN32_WCE */ 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 /* skip priority */ 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 /* CONFIG_ANSI_C_EXTRA */ 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 /* CONFIG_READLINE */ 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 /* CONFIG_READLINE */ 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 /* CONFIG_READLINE */ 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 /* CONFIG_READLINE */ 02027 02028 do { 02029 wpa_cli_recv_pending(mon_conn, 0, 0); 02030 #ifndef CONFIG_NATIVE_WINDOWS 02031 alarm(ping_interval); 02032 #endif /* CONFIG_NATIVE_WINDOWS */ 02033 #ifdef CONFIG_WPA_CLI_FORK 02034 if (mon_pid) 02035 kill(mon_pid, SIGUSR1); 02036 #endif /* CONFIG_WPA_CLI_FORK */ 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 /* CONFIG_READLINE */ 02049 printf("> "); 02050 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin); 02051 #endif /* CONFIG_READLINE */ 02052 #ifndef CONFIG_NATIVE_WINDOWS 02053 alarm(0); 02054 #endif /* CONFIG_NATIVE_WINDOWS */ 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 /* CONFIG_WPA_CLI_FORK */ 02096 } while (!wpa_cli_quit); 02097 02098 #ifdef CONFIG_READLINE 02099 if (hfile) { 02100 /* Save command history, excluding lines that may contain 02101 * passwords. */ 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 /* CONFIG_READLINE */ 02123 } 02124 02125 02126 static void wpa_cli_action(struct wpa_ctrl *ctrl) 02127 { 02128 #ifdef CONFIG_ANSI_C_EXTRA 02129 /* TODO: ANSI C version(?) */ 02130 printf("Action processing not supported in ANSI C build.\n"); 02131 #else /* CONFIG_ANSI_C_EXTRA */ 02132 fd_set rfds; 02133 int fd, res; 02134 struct timeval tv; 02135 char buf[256]; /* note: large enough to fit in unsolicited messages */ 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 /* verify that connection is still working */ 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 /* CONFIG_ANSI_C_EXTRA */ 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 /* CONFIG_READLINE */ 02192 } 02193 #endif /* CONFIG_WPA_CLI_FORK */ 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 /* CONFIG_NATIVE_WINDOWS */ 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 * Skip the file if it is not a socket. Also accept 02226 * DT_UNKNOWN (0) in case the C library or underlying 02227 * file system does not support d_type. 02228 */ 02229 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN) 02230 continue; 02231 #endif /* _DIRENT_HAVE_D_TYPE */ 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 /* CONFIG_CTRL_IFACE_UNIX */ 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 /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 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 /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 02327 ctrl_conn = wpa_ctrl_open(global); 02328 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 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 /* _WIN32_WCE */ 02340 #ifndef CONFIG_NATIVE_WINDOWS 02341 signal(SIGALRM, wpa_cli_alarm); 02342 #endif /* CONFIG_NATIVE_WINDOWS */ 02343 #ifdef CONFIG_WPA_CLI_FORK 02344 signal(SIGUSR1, wpa_cli_usr1); 02345 #endif /* CONFIG_WPA_CLI_FORK */ 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 /* CONFIG_CTRL_IFACE */ 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 /* CONFIG_CTRL_IFACE */