wpa_cli.c
Go to the documentation of this file.
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 */


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Jan 2 2014 11:26:39