]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - build-utilities/hostap.git/blob - wpa_supplicant/wpa_cli.c
WPS ER: Add PIN configuration and SetSelectedRegistrar call
[build-utilities/hostap.git] / wpa_supplicant / wpa_cli.c
1 /*
2  * WPA Supplicant - command line interface for wpa_supplicant daemon
3  * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
15 #include "includes.h"
17 #ifdef CONFIG_CTRL_IFACE
19 #ifdef CONFIG_CTRL_IFACE_UNIX
20 #include <dirent.h>
21 #endif /* CONFIG_CTRL_IFACE_UNIX */
22 #ifdef CONFIG_READLINE
23 #include <readline/readline.h>
24 #include <readline/history.h>
25 #endif /* CONFIG_READLINE */
27 #include "wpa_ctrl.h"
28 #include "common.h"
29 #include "version.h"
32 static const char *wpa_cli_version =
33 "wpa_cli v" VERSION_STR "\n"
34 "Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> and contributors";
37 static const char *wpa_cli_license =
38 "This program is free software. You can distribute it and/or modify it\n"
39 "under the terms of the GNU General Public License version 2.\n"
40 "\n"
41 "Alternatively, this software may be distributed under the terms of the\n"
42 "BSD license. See README and COPYING for more details.\n";
44 static const char *wpa_cli_full_license =
45 "This program is free software; you can redistribute it and/or modify\n"
46 "it under the terms of the GNU General Public License version 2 as\n"
47 "published by the Free Software Foundation.\n"
48 "\n"
49 "This program is distributed in the hope that it will be useful,\n"
50 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
51 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
52 "GNU General Public License for more details.\n"
53 "\n"
54 "You should have received a copy of the GNU General Public License\n"
55 "along with this program; if not, write to the Free Software\n"
56 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n"
57 "\n"
58 "Alternatively, this software may be distributed under the terms of the\n"
59 "BSD license.\n"
60 "\n"
61 "Redistribution and use in source and binary forms, with or without\n"
62 "modification, are permitted provided that the following conditions are\n"
63 "met:\n"
64 "\n"
65 "1. Redistributions of source code must retain the above copyright\n"
66 "   notice, this list of conditions and the following disclaimer.\n"
67 "\n"
68 "2. Redistributions in binary form must reproduce the above copyright\n"
69 "   notice, this list of conditions and the following disclaimer in the\n"
70 "   documentation and/or other materials provided with the distribution.\n"
71 "\n"
72 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
73 "   names of its contributors may be used to endorse or promote products\n"
74 "   derived from this software without specific prior written permission.\n"
75 "\n"
76 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
77 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
78 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
79 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
80 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
81 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
82 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
83 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
84 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
85 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
86 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
87 "\n";
89 static struct wpa_ctrl *ctrl_conn;
90 static int wpa_cli_quit = 0;
91 static int wpa_cli_attached = 0;
92 static int wpa_cli_connected = 0;
93 static int wpa_cli_last_id = 0;
94 static const char *ctrl_iface_dir = "/var/run/wpa_supplicant";
95 static char *ctrl_ifname = NULL;
96 static const char *pid_file = NULL;
97 static const char *action_file = NULL;
98 static int ping_interval = 5;
101 static void print_help();
104 static void usage(void)
106         printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
107                "[-a<action file>] \\\n"
108                "        [-P<pid file>] [-g<global ctrl>] [-G<ping interval>]  "
109                "[command..]\n"
110                "  -h = help (show this usage text)\n"
111                "  -v = shown version information\n"
112                "  -a = run in daemon mode executing the action file based on "
113                "events from\n"
114                "       wpa_supplicant\n"
115                "  -B = run a daemon in the background\n"
116                "  default path: /var/run/wpa_supplicant\n"
117                "  default interface: first interface found in socket path\n");
118         print_help();
122 static struct wpa_ctrl * wpa_cli_open_connection(const char *ifname)
124 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
125         ctrl_conn = wpa_ctrl_open(ifname);
126         return ctrl_conn;
127 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
128         char *cfile;
129         int flen, res;
131         if (ifname == NULL)
132                 return NULL;
134         flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
135         cfile = os_malloc(flen);
136         if (cfile == NULL)
137                 return NULL;
138         res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
139         if (res < 0 || res >= flen) {
140                 os_free(cfile);
141                 return NULL;
142         }
144         ctrl_conn = wpa_ctrl_open(cfile);
145         os_free(cfile);
146         return ctrl_conn;
147 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
151 static void wpa_cli_close_connection(void)
153         if (ctrl_conn == NULL)
154                 return;
156         if (wpa_cli_attached) {
157                 wpa_ctrl_detach(ctrl_conn);
158                 wpa_cli_attached = 0;
159         }
160         wpa_ctrl_close(ctrl_conn);
161         ctrl_conn = NULL;
165 static void wpa_cli_msg_cb(char *msg, size_t len)
167         printf("%s\n", msg);
171 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
173         char buf[2048];
174         size_t len;
175         int ret;
177         if (ctrl_conn == NULL) {
178                 printf("Not connected to wpa_supplicant - command dropped.\n");
179                 return -1;
180         }
181         len = sizeof(buf) - 1;
182         ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
183                                wpa_cli_msg_cb);
184         if (ret == -2) {
185                 printf("'%s' command timed out.\n", cmd);
186                 return -2;
187         } else if (ret < 0) {
188                 printf("'%s' command failed.\n", cmd);
189                 return -1;
190         }
191         if (print) {
192                 buf[len] = '\0';
193                 printf("%s", buf);
194         }
195         return 0;
199 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
201         return _wpa_ctrl_command(ctrl, cmd, 1);
205 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
207         int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
208         return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
212 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
214         return wpa_ctrl_command(ctrl, "PING");
218 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
220         return wpa_ctrl_command(ctrl, "MIB");
224 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
226         return wpa_ctrl_command(ctrl, "PMKSA");
230 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
232         print_help();
233         return 0;
237 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
239         printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
240         return 0;
244 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
246         wpa_cli_quit = 1;
247         return 0;
251 static void wpa_cli_show_variables(void)
253         printf("set variables:\n"
254                "  EAPOL::heldPeriod (EAPOL state machine held period, "
255                "in seconds)\n"
256                "  EAPOL::authPeriod (EAPOL state machine authentication "
257                "period, in seconds)\n"
258                "  EAPOL::startPeriod (EAPOL state machine start period, in "
259                "seconds)\n"
260                "  EAPOL::maxStart (EAPOL state machine maximum start "
261                "attempts)\n");
262         printf("  dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
263                "seconds)\n"
264                "  dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
265                " threshold\n\tpercentage)\n"
266                "  dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
267                "security\n\tassociation in seconds)\n");
271 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
273         char cmd[256];
274         int res;
276         if (argc == 0) {
277                 wpa_cli_show_variables();
278                 return 0;
279         }
281         if (argc != 2) {
282                 printf("Invalid SET command: needs two arguments (variable "
283                        "name and value)\n");
284                 return -1;
285         }
287         res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
288         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
289                 printf("Too long SET command.\n");
290                 return -1;
291         }
292         return wpa_ctrl_command(ctrl, cmd);
296 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
298         return wpa_ctrl_command(ctrl, "LOGOFF");
302 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
304         return wpa_ctrl_command(ctrl, "LOGON");
308 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
309                                    char *argv[])
311         return wpa_ctrl_command(ctrl, "REASSOCIATE");
315 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
316                                        char *argv[])
318         char cmd[256];
319         int res;
321         if (argc != 1) {
322                 printf("Invalid PREAUTH command: needs one argument "
323                        "(BSSID)\n");
324                 return -1;
325         }
327         res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
328         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
329                 printf("Too long PREAUTH command.\n");
330                 return -1;
331         }
332         return wpa_ctrl_command(ctrl, cmd);
336 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
338         char cmd[256];
339         int res;
341         if (argc != 1) {
342                 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
343                        "value)\n");
344                 return -1;
345         }
346         res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
347         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
348                 printf("Too long AP_SCAN command.\n");
349                 return -1;
350         }
351         return wpa_ctrl_command(ctrl, cmd);
355 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
356                                 char *argv[])
358         char cmd[256];
359         int res;
361         if (argc != 1) {
362                 printf("Invalid STKSTART command: needs one argument "
363                        "(Peer STA MAC address)\n");
364                 return -1;
365         }
367         res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
368         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
369                 printf("Too long STKSTART command.\n");
370                 return -1;
371         }
372         return wpa_ctrl_command(ctrl, cmd);
376 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
378         char cmd[256];
379         int res;
381         if (argc != 1) {
382                 printf("Invalid FT_DS command: needs one argument "
383                        "(Target AP MAC address)\n");
384                 return -1;
385         }
387         res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
388         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
389                 printf("Too long FT_DS command.\n");
390                 return -1;
391         }
392         return wpa_ctrl_command(ctrl, cmd);
396 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
398         char cmd[256];
399         int res;
401         if (argc == 0) {
402                 /* Any BSSID */
403                 return wpa_ctrl_command(ctrl, "WPS_PBC");
404         }
406         /* Specific BSSID */
407         res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
408         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
409                 printf("Too long WPS_PBC command.\n");
410                 return -1;
411         }
412         return wpa_ctrl_command(ctrl, cmd);
416 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
418         char cmd[256];
419         int res;
421         if (argc == 0) {
422                 printf("Invalid WPS_PIN command: need one or two arguments:\n"
423                        "- BSSID: use 'any' to select any\n"
424                        "- PIN: optional, used only with devices that have no "
425                        "display\n");
426                 return -1;
427         }
429         if (argc == 1) {
430                 /* Use dynamically generated PIN (returned as reply) */
431                 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
432                 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
433                         printf("Too long WPS_PIN command.\n");
434                         return -1;
435                 }
436                 return wpa_ctrl_command(ctrl, cmd);
437         }
439         /* Use hardcoded PIN from a label */
440         res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
441         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
442                 printf("Too long WPS_PIN command.\n");
443                 return -1;
444         }
445         return wpa_ctrl_command(ctrl, cmd);
449 #ifdef CONFIG_WPS_OOB
450 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
452         char cmd[256];
453         int res;
455         if (argc != 3 && argc != 4) {
456                 printf("Invalid WPS_OOB command: need three or four "
457                        "arguments:\n"
458                        "- DEV_TYPE: use 'ufd' or 'nfc'\n"
459                        "- PATH: path of OOB device like '/mnt'\n"
460                        "- METHOD: OOB method 'pin-e' or 'pin-r', "
461                        "'cred'\n"
462                        "- DEV_NAME: (only for NFC) device name like "
463                        "'pn531'\n");
464                 return -1;
465         }
467         if (argc == 3)
468                 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
469                                   argv[0], argv[1], argv[2]);
470         else
471                 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
472                                   argv[0], argv[1], argv[2], argv[3]);
473         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
474                 printf("Too long WPS_OOB command.\n");
475                 return -1;
476         }
477         return wpa_ctrl_command(ctrl, cmd);
479 #endif /* CONFIG_WPS_OOB */
482 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
484         char cmd[256];
485         int res;
487         if (argc == 2)
488                 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
489                                   argv[0], argv[1]);
490         else if (argc == 6) {
491                 char ssid_hex[2 * 32 + 1];
492                 char key_hex[2 * 64 + 1];
493                 int i;
495                 ssid_hex[0] = '\0';
496                 for (i = 0; i < 32; i++) {
497                         if (argv[2][i] == '\0')
498                                 break;
499                         os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
500                 }
502                 key_hex[0] = '\0';
503                 for (i = 0; i < 64; i++) {
504                         if (argv[5][i] == '\0')
505                                 break;
506                         os_snprintf(&key_hex[i * 2], 3, "%02x", argv[5][i]);
507                 }
509                 res = os_snprintf(cmd, sizeof(cmd),
510                                   "WPS_REG %s %s %s %s %s %s",
511                                   argv[0], argv[1], ssid_hex, argv[3], argv[4],
512                                   key_hex);
513         } else {
514                 printf("Invalid WPS_REG command: need two arguments:\n"
515                        "- BSSID: use 'any' to select any\n"
516                        "- AP PIN\n");
517                 printf("Alternatively, six arguments can be used to "
518                        "reconfigure the AP:\n"
519                        "- BSSID: use 'any' to select any\n"
520                        "- AP PIN\n"
521                        "- new SSID\n"
522                        "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
523                        "- new encr (NONE, WEP, TKIP, CCMP)\n"
524                        "- new key\n");
525                 return -1;
526         }
528         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
529                 printf("Too long WPS_REG command.\n");
530                 return -1;
531         }
532         return wpa_ctrl_command(ctrl, cmd);
536 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
537                                     char *argv[])
539         return wpa_ctrl_command(ctrl, "WPS_ER_START");
544 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
545                                    char *argv[])
547         return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
552 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
553                                   char *argv[])
555         char cmd[256];
556         int res;
558         if (argc != 2) {
559                 printf("Invalid WPS_ER_PIN command: need two arguments:\n"
560                        "- UUID: use 'any' to select any\n"
561                        "- PIN: Enrollee PIN\n");
562                 return -1;
563         }
565         res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
566                           argv[0], argv[1]);
567         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
568                 printf("Too long WPS_ER_PIN command.\n");
569                 return -1;
570         }
571         return wpa_ctrl_command(ctrl, cmd);
575 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
577         char cmd[256];
578         int res;
580         if (argc != 1) {
581                 printf("Invalid IBSS_RSN command: needs one argument "
582                        "(Peer STA MAC address)\n");
583                 return -1;
584         }
586         res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
587         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
588                 printf("Too long IBSS_RSN command.\n");
589                 return -1;
590         }
591         return wpa_ctrl_command(ctrl, cmd);
595 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
597         char cmd[256];
598         int res;
600         if (argc != 1) {
601                 printf("Invalid LEVEL command: needs one argument (debug "
602                        "level)\n");
603                 return -1;
604         }
605         res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
606         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
607                 printf("Too long LEVEL command.\n");
608                 return -1;
609         }
610         return wpa_ctrl_command(ctrl, cmd);
614 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
616         char cmd[256], *pos, *end;
617         int i, ret;
619         if (argc < 2) {
620                 printf("Invalid IDENTITY command: needs two arguments "
621                        "(network id and identity)\n");
622                 return -1;
623         }
625         end = cmd + sizeof(cmd);
626         pos = cmd;
627         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
628                           argv[0], argv[1]);
629         if (ret < 0 || ret >= end - pos) {
630                 printf("Too long IDENTITY command.\n");
631                 return -1;
632         }
633         pos += ret;
634         for (i = 2; i < argc; i++) {
635                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
636                 if (ret < 0 || ret >= end - pos) {
637                         printf("Too long IDENTITY command.\n");
638                         return -1;
639                 }
640                 pos += ret;
641         }
643         return wpa_ctrl_command(ctrl, cmd);
647 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
649         char cmd[256], *pos, *end;
650         int i, ret;
652         if (argc < 2) {
653                 printf("Invalid PASSWORD command: needs two arguments "
654                        "(network id and password)\n");
655                 return -1;
656         }
658         end = cmd + sizeof(cmd);
659         pos = cmd;
660         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
661                           argv[0], argv[1]);
662         if (ret < 0 || ret >= end - pos) {
663                 printf("Too long PASSWORD command.\n");
664                 return -1;
665         }
666         pos += ret;
667         for (i = 2; i < argc; i++) {
668                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
669                 if (ret < 0 || ret >= end - pos) {
670                         printf("Too long PASSWORD command.\n");
671                         return -1;
672                 }
673                 pos += ret;
674         }
676         return wpa_ctrl_command(ctrl, cmd);
680 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
681                                     char *argv[])
683         char cmd[256], *pos, *end;
684         int i, ret;
686         if (argc < 2) {
687                 printf("Invalid NEW_PASSWORD command: needs two arguments "
688                        "(network id and password)\n");
689                 return -1;
690         }
692         end = cmd + sizeof(cmd);
693         pos = cmd;
694         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
695                           argv[0], argv[1]);
696         if (ret < 0 || ret >= end - pos) {
697                 printf("Too long NEW_PASSWORD command.\n");
698                 return -1;
699         }
700         pos += ret;
701         for (i = 2; i < argc; i++) {
702                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
703                 if (ret < 0 || ret >= end - pos) {
704                         printf("Too long NEW_PASSWORD command.\n");
705                         return -1;
706                 }
707                 pos += ret;
708         }
710         return wpa_ctrl_command(ctrl, cmd);
714 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
716         char cmd[256], *pos, *end;
717         int i, ret;
719         if (argc < 2) {
720                 printf("Invalid PIN command: needs two arguments "
721                        "(network id and pin)\n");
722                 return -1;
723         }
725         end = cmd + sizeof(cmd);
726         pos = cmd;
727         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
728                           argv[0], argv[1]);
729         if (ret < 0 || ret >= end - pos) {
730                 printf("Too long PIN command.\n");
731                 return -1;
732         }
733         pos += ret;
734         for (i = 2; i < argc; i++) {
735                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
736                 if (ret < 0 || ret >= end - pos) {
737                         printf("Too long PIN command.\n");
738                         return -1;
739                 }
740                 pos += ret;
741         }
742         return wpa_ctrl_command(ctrl, cmd);
746 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
748         char cmd[256], *pos, *end;
749         int i, ret;
751         if (argc < 2) {
752                 printf("Invalid OTP command: needs two arguments (network "
753                        "id and password)\n");
754                 return -1;
755         }
757         end = cmd + sizeof(cmd);
758         pos = cmd;
759         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
760                           argv[0], argv[1]);
761         if (ret < 0 || ret >= end - pos) {
762                 printf("Too long OTP command.\n");
763                 return -1;
764         }
765         pos += ret;
766         for (i = 2; i < argc; i++) {
767                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
768                 if (ret < 0 || ret >= end - pos) {
769                         printf("Too long OTP command.\n");
770                         return -1;
771                 }
772                 pos += ret;
773         }
775         return wpa_ctrl_command(ctrl, cmd);
779 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
780                                   char *argv[])
782         char cmd[256], *pos, *end;
783         int i, ret;
785         if (argc < 2) {
786                 printf("Invalid PASSPHRASE command: needs two arguments "
787                        "(network id and passphrase)\n");
788                 return -1;
789         }
791         end = cmd + sizeof(cmd);
792         pos = cmd;
793         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
794                           argv[0], argv[1]);
795         if (ret < 0 || ret >= end - pos) {
796                 printf("Too long PASSPHRASE command.\n");
797                 return -1;
798         }
799         pos += ret;
800         for (i = 2; i < argc; i++) {
801                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
802                 if (ret < 0 || ret >= end - pos) {
803                         printf("Too long PASSPHRASE command.\n");
804                         return -1;
805                 }
806                 pos += ret;
807         }
809         return wpa_ctrl_command(ctrl, cmd);
813 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
815         char cmd[256], *pos, *end;
816         int i, ret;
818         if (argc < 2) {
819                 printf("Invalid BSSID command: needs two arguments (network "
820                        "id and BSSID)\n");
821                 return -1;
822         }
824         end = cmd + sizeof(cmd);
825         pos = cmd;
826         ret = os_snprintf(pos, end - pos, "BSSID");
827         if (ret < 0 || ret >= end - pos) {
828                 printf("Too long BSSID command.\n");
829                 return -1;
830         }
831         pos += ret;
832         for (i = 0; i < argc; i++) {
833                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
834                 if (ret < 0 || ret >= end - pos) {
835                         printf("Too long BSSID command.\n");
836                         return -1;
837                 }
838                 pos += ret;
839         }
841         return wpa_ctrl_command(ctrl, cmd);
845 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
846                                      char *argv[])
848         return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
852 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
853                                       char *argv[])
855         char cmd[32];
856         int res;
858         if (argc < 1) {
859                 printf("Invalid SELECT_NETWORK command: needs one argument "
860                        "(network id)\n");
861                 return -1;
862         }
864         res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
865         if (res < 0 || (size_t) res >= sizeof(cmd))
866                 return -1;
867         cmd[sizeof(cmd) - 1] = '\0';
869         return wpa_ctrl_command(ctrl, cmd);
873 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
874                                       char *argv[])
876         char cmd[32];
877         int res;
879         if (argc < 1) {
880                 printf("Invalid ENABLE_NETWORK command: needs one argument "
881                        "(network id)\n");
882                 return -1;
883         }
885         res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
886         if (res < 0 || (size_t) res >= sizeof(cmd))
887                 return -1;
888         cmd[sizeof(cmd) - 1] = '\0';
890         return wpa_ctrl_command(ctrl, cmd);
894 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
895                                        char *argv[])
897         char cmd[32];
898         int res;
900         if (argc < 1) {
901                 printf("Invalid DISABLE_NETWORK command: needs one argument "
902                        "(network id)\n");
903                 return -1;
904         }
906         res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
907         if (res < 0 || (size_t) res >= sizeof(cmd))
908                 return -1;
909         cmd[sizeof(cmd) - 1] = '\0';
911         return wpa_ctrl_command(ctrl, cmd);
915 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
916                                    char *argv[])
918         return wpa_ctrl_command(ctrl, "ADD_NETWORK");
922 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
923                                       char *argv[])
925         char cmd[32];
926         int res;
928         if (argc < 1) {
929                 printf("Invalid REMOVE_NETWORK command: needs one argument "
930                        "(network id)\n");
931                 return -1;
932         }
934         res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
935         if (res < 0 || (size_t) res >= sizeof(cmd))
936                 return -1;
937         cmd[sizeof(cmd) - 1] = '\0';
939         return wpa_ctrl_command(ctrl, cmd);
943 static void wpa_cli_show_network_variables(void)
945         printf("set_network variables:\n"
946                "  ssid (network name, SSID)\n"
947                "  psk (WPA passphrase or pre-shared key)\n"
948                "  key_mgmt (key management protocol)\n"
949                "  identity (EAP identity)\n"
950                "  password (EAP password)\n"
951                "  ...\n"
952                "\n"
953                "Note: Values are entered in the same format as the "
954                "configuration file is using,\n"
955                "i.e., strings values need to be inside double quotation "
956                "marks.\n"
957                "For example: set_network 1 ssid \"network name\"\n"
958                "\n"
959                "Please see wpa_supplicant.conf documentation for full list "
960                "of\navailable variables.\n");
964 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
965                                    char *argv[])
967         char cmd[256];
968         int res;
970         if (argc == 0) {
971                 wpa_cli_show_network_variables();
972                 return 0;
973         }
975         if (argc != 3) {
976                 printf("Invalid SET_NETWORK command: needs three arguments\n"
977                        "(network id, variable name, and value)\n");
978                 return -1;
979         }
981         res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
982                           argv[0], argv[1], argv[2]);
983         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
984                 printf("Too long SET_NETWORK command.\n");
985                 return -1;
986         }
987         return wpa_ctrl_command(ctrl, cmd);
991 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
992                                    char *argv[])
994         char cmd[256];
995         int res;
997         if (argc == 0) {
998                 wpa_cli_show_network_variables();
999                 return 0;
1000         }
1002         if (argc != 2) {
1003                 printf("Invalid GET_NETWORK command: needs two arguments\n"
1004                        "(network id and variable name)\n");
1005                 return -1;
1006         }
1008         res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1009                           argv[0], argv[1]);
1010         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1011                 printf("Too long GET_NETWORK command.\n");
1012                 return -1;
1013         }
1014         return wpa_ctrl_command(ctrl, cmd);
1018 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1019                                   char *argv[])
1021         return wpa_ctrl_command(ctrl, "DISCONNECT");
1025 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1026                                   char *argv[])
1028         return wpa_ctrl_command(ctrl, "RECONNECT");
1032 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1033                                    char *argv[])
1035         return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1039 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1041         return wpa_ctrl_command(ctrl, "SCAN");
1045 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1046                                     char *argv[])
1048         return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1052 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1054         char cmd[64];
1055         int res;
1057         if (argc != 1) {
1058                 printf("Invalid BSS command: need one argument (index or "
1059                        "BSSID)\n");
1060                 return -1;
1061         }
1063         res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1064         if (res < 0 || (size_t) res >= sizeof(cmd))
1065                 return -1;
1066         cmd[sizeof(cmd) - 1] = '\0';
1068         return wpa_ctrl_command(ctrl, cmd);
1072 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1073                                       char *argv[])
1075         char cmd[64];
1076         int res;
1078         if (argc < 1 || argc > 2) {
1079                 printf("Invalid GET_CAPABILITY command: need either one or "
1080                        "two arguments\n");
1081                 return -1;
1082         }
1084         if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1085                 printf("Invalid GET_CAPABILITY command: second argument, "
1086                        "if any, must be 'strict'\n");
1087                 return -1;
1088         }
1090         res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1091                           (argc == 2) ? " strict" : "");
1092         if (res < 0 || (size_t) res >= sizeof(cmd))
1093                 return -1;
1094         cmd[sizeof(cmd) - 1] = '\0';
1096         return wpa_ctrl_command(ctrl, cmd);
1100 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1102         printf("Available interfaces:\n");
1103         return wpa_ctrl_command(ctrl, "INTERFACES");
1107 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1109         if (argc < 1) {
1110                 wpa_cli_list_interfaces(ctrl);
1111                 return 0;
1112         }
1114         wpa_cli_close_connection();
1115         os_free(ctrl_ifname);
1116         ctrl_ifname = os_strdup(argv[0]);
1118         if (wpa_cli_open_connection(ctrl_ifname)) {
1119                 printf("Connected to interface '%s.\n", ctrl_ifname);
1120                 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1121                         wpa_cli_attached = 1;
1122                 } else {
1123                         printf("Warning: Failed to attach to "
1124                                "wpa_supplicant.\n");
1125                 }
1126         } else {
1127                 printf("Could not connect to interface '%s' - re-trying\n",
1128                        ctrl_ifname);
1129         }
1130         return 0;
1134 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1135                                    char *argv[])
1137         return wpa_ctrl_command(ctrl, "RECONFIGURE");
1141 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1142                                  char *argv[])
1144         return wpa_ctrl_command(ctrl, "TERMINATE");
1148 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1149                                      char *argv[])
1151         char cmd[256];
1152         int res;
1154         if (argc < 1) {
1155                 printf("Invalid INTERFACE_ADD command: needs at least one "
1156                        "argument (interface name)\n"
1157                        "All arguments: ifname confname driver ctrl_interface "
1158                        "driver_param bridge_name\n");
1159                 return -1;
1160         }
1162         /*
1163          * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1164          * <driver_param>TAB<bridge_name>
1165          */
1166         res = os_snprintf(cmd, sizeof(cmd),
1167                           "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1168                           argv[0],
1169                           argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1170                           argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1171                           argc > 5 ? argv[5] : "");
1172         if (res < 0 || (size_t) res >= sizeof(cmd))
1173                 return -1;
1174         cmd[sizeof(cmd) - 1] = '\0';
1175         return wpa_ctrl_command(ctrl, cmd);
1179 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1180                                         char *argv[])
1182         char cmd[128];
1183         int res;
1185         if (argc != 1) {
1186                 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1187                        "(interface name)\n");
1188                 return -1;
1189         }
1191         res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1192         if (res < 0 || (size_t) res >= sizeof(cmd))
1193                 return -1;
1194         cmd[sizeof(cmd) - 1] = '\0';
1195         return wpa_ctrl_command(ctrl, cmd);
1199 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1200                                       char *argv[])
1202         return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1206 #ifdef CONFIG_AP
1207 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1209         char buf[64];
1210         if (argc != 1) {
1211                 printf("Invalid 'sta' command - exactly one argument, STA "
1212                        "address, is required.\n");
1213                 return -1;
1214         }
1215         snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1216         return wpa_ctrl_command(ctrl, buf);
1220 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1221                                 char *addr, size_t addr_len)
1223         char buf[4096], *pos;
1224         size_t len;
1225         int ret;
1227         if (ctrl_conn == NULL) {
1228                 printf("Not connected to hostapd - command dropped.\n");
1229                 return -1;
1230         }
1231         len = sizeof(buf) - 1;
1232         ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1233                                wpa_cli_msg_cb);
1234         if (ret == -2) {
1235                 printf("'%s' command timed out.\n", cmd);
1236                 return -2;
1237         } else if (ret < 0) {
1238                 printf("'%s' command failed.\n", cmd);
1239                 return -1;
1240         }
1242         buf[len] = '\0';
1243         if (memcmp(buf, "FAIL", 4) == 0)
1244                 return -1;
1245         printf("%s", buf);
1247         pos = buf;
1248         while (*pos != '\0' && *pos != '\n')
1249                 pos++;
1250         *pos = '\0';
1251         os_strlcpy(addr, buf, addr_len);
1252         return 0;
1256 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1258         char addr[32], cmd[64];
1260         if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1261                 return 0;
1262         do {
1263                 snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1264         } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1266         return -1;
1268 #endif /* CONFIG_AP */
1271 enum wpa_cli_cmd_flags {
1272         cli_cmd_flag_none               = 0x00,
1273         cli_cmd_flag_sensitive          = 0x01
1274 };
1276 struct wpa_cli_cmd {
1277         const char *cmd;
1278         int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
1279         enum wpa_cli_cmd_flags flags;
1280         const char *usage;
1281 };
1283 static struct wpa_cli_cmd wpa_cli_commands[] = {
1284         { "status", wpa_cli_cmd_status,
1285           cli_cmd_flag_none,
1286           "[verbose] = get current WPA/EAPOL/EAP status" },
1287         { "ping", wpa_cli_cmd_ping,
1288           cli_cmd_flag_none,
1289           "= pings wpa_supplicant" },
1290         { "mib", wpa_cli_cmd_mib,
1291           cli_cmd_flag_none,
1292           "= get MIB variables (dot1x, dot11)" },
1293         { "help", wpa_cli_cmd_help,
1294           cli_cmd_flag_none,
1295           "= show this usage help" },
1296         { "interface", wpa_cli_cmd_interface,
1297           cli_cmd_flag_none,
1298           "[ifname] = show interfaces/select interface" },
1299         { "level", wpa_cli_cmd_level,
1300           cli_cmd_flag_none,
1301           "<debug level> = change debug level" },
1302         { "license", wpa_cli_cmd_license,
1303           cli_cmd_flag_none,
1304           "= show full wpa_cli license" },
1305         { "quit", wpa_cli_cmd_quit,
1306           cli_cmd_flag_none,
1307           "= exit wpa_cli" },
1308         { "set", wpa_cli_cmd_set,
1309           cli_cmd_flag_none,
1310           "= set variables (shows list of variables when run without "
1311           "arguments)" },
1312         { "logon", wpa_cli_cmd_logon,
1313           cli_cmd_flag_none,
1314           "= IEEE 802.1X EAPOL state machine logon" },
1315         { "logoff", wpa_cli_cmd_logoff,
1316           cli_cmd_flag_none,
1317           "= IEEE 802.1X EAPOL state machine logoff" },
1318         { "pmksa", wpa_cli_cmd_pmksa,
1319           cli_cmd_flag_none,
1320           "= show PMKSA cache" },
1321         { "reassociate", wpa_cli_cmd_reassociate,
1322           cli_cmd_flag_none,
1323           "= force reassociation" },
1324         { "preauthenticate", wpa_cli_cmd_preauthenticate,
1325           cli_cmd_flag_none,
1326           "<BSSID> = force preauthentication" },
1327         { "identity", wpa_cli_cmd_identity,
1328           cli_cmd_flag_none,
1329           "<network id> <identity> = configure identity for an SSID" },
1330         { "password", wpa_cli_cmd_password,
1331           cli_cmd_flag_sensitive,
1332           "<network id> <password> = configure password for an SSID" },
1333         { "new_password", wpa_cli_cmd_new_password,
1334           cli_cmd_flag_sensitive,
1335           "<network id> <password> = change password for an SSID" },
1336         { "pin", wpa_cli_cmd_pin,
1337           cli_cmd_flag_sensitive,
1338           "<network id> <pin> = configure pin for an SSID" },
1339         { "otp", wpa_cli_cmd_otp,
1340           cli_cmd_flag_sensitive,
1341           "<network id> <password> = configure one-time-password for an SSID"
1342         },
1343         { "passphrase", wpa_cli_cmd_passphrase,
1344           cli_cmd_flag_sensitive,
1345           "<network id> <passphrase> = configure private key passphrase\n"
1346           "  for an SSID" },
1347         { "bssid", wpa_cli_cmd_bssid,
1348           cli_cmd_flag_none,
1349           "<network id> <BSSID> = set preferred BSSID for an SSID" },
1350         { "list_networks", wpa_cli_cmd_list_networks,
1351           cli_cmd_flag_none,
1352           "= list configured networks" },
1353         { "select_network", wpa_cli_cmd_select_network,
1354           cli_cmd_flag_none,
1355           "<network id> = select a network (disable others)" },
1356         { "enable_network", wpa_cli_cmd_enable_network,
1357           cli_cmd_flag_none,
1358           "<network id> = enable a network" },
1359         { "disable_network", wpa_cli_cmd_disable_network,
1360           cli_cmd_flag_none,
1361           "<network id> = disable a network" },
1362         { "add_network", wpa_cli_cmd_add_network,
1363           cli_cmd_flag_none,
1364           "= add a network" },
1365         { "remove_network", wpa_cli_cmd_remove_network,
1366           cli_cmd_flag_none,
1367           "<network id> = remove a network" },
1368         { "set_network", wpa_cli_cmd_set_network,
1369           cli_cmd_flag_sensitive,
1370           "<network id> <variable> <value> = set network variables (shows\n"
1371           "  list of variables when run without arguments)" },
1372         { "get_network", wpa_cli_cmd_get_network,
1373           cli_cmd_flag_none,
1374           "<network id> <variable> = get network variables" },
1375         { "save_config", wpa_cli_cmd_save_config,
1376           cli_cmd_flag_none,
1377           "= save the current configuration" },
1378         { "disconnect", wpa_cli_cmd_disconnect,
1379           cli_cmd_flag_none,
1380           "= disconnect and wait for reassociate/reconnect command before\n"
1381           "  connecting" },
1382         { "reconnect", wpa_cli_cmd_reconnect,
1383           cli_cmd_flag_none,
1384           "= like reassociate, but only takes effect if already disconnected"
1385         },
1386         { "scan", wpa_cli_cmd_scan,
1387           cli_cmd_flag_none,
1388           "= request new BSS scan" },
1389         { "scan_results", wpa_cli_cmd_scan_results,
1390           cli_cmd_flag_none,
1391           "= get latest scan results" },
1392         { "bss", wpa_cli_cmd_bss,
1393           cli_cmd_flag_none,
1394           "<<idx> | <bssid>> = get detailed scan result info" },
1395         { "get_capability", wpa_cli_cmd_get_capability,
1396           cli_cmd_flag_none,
1397           "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
1398         { "reconfigure", wpa_cli_cmd_reconfigure,
1399           cli_cmd_flag_none,
1400           "= force wpa_supplicant to re-read its configuration file" },
1401         { "terminate", wpa_cli_cmd_terminate,
1402           cli_cmd_flag_none,
1403           "= terminate wpa_supplicant" },
1404         { "interface_add", wpa_cli_cmd_interface_add,
1405           cli_cmd_flag_none,
1406           "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
1407           "  <bridge_name> = adds new interface, all parameters but <ifname>\n"
1408           "  are optional" },
1409         { "interface_remove", wpa_cli_cmd_interface_remove,
1410           cli_cmd_flag_none,
1411           "<ifname> = removes the interface" },
1412         { "interface_list", wpa_cli_cmd_interface_list,
1413           cli_cmd_flag_none,
1414           "= list available interfaces" },
1415         { "ap_scan", wpa_cli_cmd_ap_scan,
1416           cli_cmd_flag_none,
1417           "<value> = set ap_scan parameter" },
1418         { "stkstart", wpa_cli_cmd_stkstart,
1419           cli_cmd_flag_none,
1420           "<addr> = request STK negotiation with <addr>" },
1421         { "ft_ds", wpa_cli_cmd_ft_ds,
1422           cli_cmd_flag_none,
1423           "<addr> = request over-the-DS FT with <addr>" },
1424         { "wps_pbc", wpa_cli_cmd_wps_pbc,
1425           cli_cmd_flag_none,
1426           "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
1427         { "wps_pin", wpa_cli_cmd_wps_pin,
1428           cli_cmd_flag_sensitive,
1429           "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
1430           "hardcoded)" },
1431 #ifdef CONFIG_WPS_OOB
1432         { "wps_oob", wpa_cli_cmd_wps_oob,
1433           cli_cmd_flag_sensitive,
1434           "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
1435 #endif /* CONFIG_WPS_OOB */
1436         { "wps_reg", wpa_cli_cmd_wps_reg,
1437           cli_cmd_flag_sensitive,
1438           "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
1439         { "wps_er_start", wpa_cli_cmd_wps_er_start,
1440           cli_cmd_flag_none,
1441           "= start Wi-Fi Protected Setup External Registrar" },
1442         { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
1443           cli_cmd_flag_none,
1444           "= stop Wi-Fi Protected Setup External Registrar" },
1445         { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
1446           cli_cmd_flag_sensitive,
1447           "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
1448         { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
1449           cli_cmd_flag_none,
1450           "<addr> = request RSN authentication with <addr> in IBSS" },
1451 #ifdef CONFIG_AP
1452         { "sta", wpa_cli_cmd_sta,
1453           cli_cmd_flag_none,
1454           "<addr> = get information about an associated station (AP)" },
1455         { "all_sta", wpa_cli_cmd_all_sta,
1456           cli_cmd_flag_none,
1457           "= get information about all associated stations (AP)" },
1458 #endif /* CONFIG_AP */
1459         { NULL, NULL, cli_cmd_flag_none, NULL }
1460 };
1463 /*
1464  * Prints command usage, lines are padded with the specified string.
1465  */
1466 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
1468         char c;
1469         size_t n;
1471         printf("%s%s ", pad, cmd->cmd);
1472         for (n = 0; (c = cmd->usage[n]); n++) {
1473                 printf("%c", c);
1474                 if (c == '\n')
1475                         printf("%s", pad);
1476         }
1477         printf("\n");
1481 static void print_help(void)
1483         int n;
1484         printf("commands:\n");
1485         for (n = 0; wpa_cli_commands[n].cmd; n++)
1486                 print_cmd_help(&wpa_cli_commands[n], "  ");
1490 #ifdef CONFIG_READLINE
1491 static int cmd_has_sensitive_data(const char *cmd)
1493         const char *c, *delim;
1494         int n;
1495         size_t len;
1497         delim = os_strchr(cmd, ' ');
1498         if (delim)
1499                 len = delim - cmd;
1500         else
1501                 len = os_strlen(cmd);
1503         for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
1504                 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
1505                         return (wpa_cli_commands[n].flags &
1506                                 cli_cmd_flag_sensitive);
1507         }
1508         return 0;
1510 #endif /* CONFIG_READLINE */
1513 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
1515         struct wpa_cli_cmd *cmd, *match = NULL;
1516         int count;
1517         int ret = 0;
1519         count = 0;
1520         cmd = wpa_cli_commands;
1521         while (cmd->cmd) {
1522                 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
1523                 {
1524                         match = cmd;
1525                         if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
1526                                 /* we have an exact match */
1527                                 count = 1;
1528                                 break;
1529                         }
1530                         count++;
1531                 }
1532                 cmd++;
1533         }
1535         if (count > 1) {
1536                 printf("Ambiguous command '%s'; possible commands:", argv[0]);
1537                 cmd = wpa_cli_commands;
1538                 while (cmd->cmd) {
1539                         if (os_strncasecmp(cmd->cmd, argv[0],
1540                                            os_strlen(argv[0])) == 0) {
1541                                 printf(" %s", cmd->cmd);
1542                         }
1543                         cmd++;
1544                 }
1545                 printf("\n");
1546                 ret = 1;
1547         } else if (count == 0) {
1548                 printf("Unknown command '%s'\n", argv[0]);
1549                 ret = 1;
1550         } else {
1551                 ret = match->handler(ctrl, argc - 1, &argv[1]);
1552         }
1554         return ret;
1558 static int str_match(const char *a, const char *b)
1560         return os_strncmp(a, b, os_strlen(b)) == 0;
1564 static int wpa_cli_exec(const char *program, const char *arg1,
1565                         const char *arg2)
1567         char *cmd;
1568         size_t len;
1569         int res;
1570         int ret = 0;
1572         len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
1573         cmd = os_malloc(len);
1574         if (cmd == NULL)
1575                 return -1;
1576         res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
1577         if (res < 0 || (size_t) res >= len) {
1578                 os_free(cmd);
1579                 return -1;
1580         }
1581         cmd[len - 1] = '\0';
1582 #ifndef _WIN32_WCE
1583         if (system(cmd) < 0)
1584                 ret = -1;
1585 #endif /* _WIN32_WCE */
1586         os_free(cmd);
1588         return ret;
1592 static void wpa_cli_action_process(const char *msg)
1594         const char *pos;
1595         char *copy = NULL, *id, *pos2;
1597         pos = msg;
1598         if (*pos == '<') {
1599                 /* skip priority */
1600                 pos = os_strchr(pos, '>');
1601                 if (pos)
1602                         pos++;
1603                 else
1604                         pos = msg;
1605         }
1607         if (str_match(pos, WPA_EVENT_CONNECTED)) {
1608                 int new_id = -1;
1609                 os_unsetenv("WPA_ID");
1610                 os_unsetenv("WPA_ID_STR");
1611                 os_unsetenv("WPA_CTRL_DIR");
1613                 pos = os_strstr(pos, "[id=");
1614                 if (pos)
1615                         copy = os_strdup(pos + 4);
1617                 if (copy) {
1618                         pos2 = id = copy;
1619                         while (*pos2 && *pos2 != ' ')
1620                                 pos2++;
1621                         *pos2++ = '\0';
1622                         new_id = atoi(id);
1623                         os_setenv("WPA_ID", id, 1);
1624                         while (*pos2 && *pos2 != '=')
1625                                 pos2++;
1626                         if (*pos2 == '=')
1627                                 pos2++;
1628                         id = pos2;
1629                         while (*pos2 && *pos2 != ']')
1630                                 pos2++;
1631                         *pos2 = '\0';
1632                         os_setenv("WPA_ID_STR", id, 1);
1633                         os_free(copy);
1634                 }
1636                 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
1638                 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
1639                         wpa_cli_connected = 1;
1640                         wpa_cli_last_id = new_id;
1641                         wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
1642                 }
1643         } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
1644                 if (wpa_cli_connected) {
1645                         wpa_cli_connected = 0;
1646                         wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
1647                 }
1648         } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
1649                 printf("wpa_supplicant is terminating - stop monitoring\n");
1650                 wpa_cli_quit = 1;
1651         }
1655 #ifndef CONFIG_ANSI_C_EXTRA
1656 static void wpa_cli_action_cb(char *msg, size_t len)
1658         wpa_cli_action_process(msg);
1660 #endif /* CONFIG_ANSI_C_EXTRA */
1663 static void wpa_cli_reconnect(void)
1665         wpa_cli_close_connection();
1666         ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
1667         if (ctrl_conn) {
1668                 printf("Connection to wpa_supplicant re-established\n");
1669                 if (wpa_ctrl_attach(ctrl_conn) == 0) {
1670                         wpa_cli_attached = 1;
1671                 } else {
1672                         printf("Warning: Failed to attach to "
1673                                "wpa_supplicant.\n");
1674                 }
1675         }
1679 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
1680                                  int action_monitor)
1682         int first = 1;
1683         if (ctrl_conn == NULL) {
1684                 wpa_cli_reconnect();
1685                 return;
1686         }
1687         while (wpa_ctrl_pending(ctrl) > 0) {
1688                 char buf[256];
1689                 size_t len = sizeof(buf) - 1;
1690                 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
1691                         buf[len] = '\0';
1692                         if (action_monitor)
1693                                 wpa_cli_action_process(buf);
1694                         else {
1695                                 if (in_read && first)
1696                                         printf("\n");
1697                                 first = 0;
1698                                 printf("%s\n", buf);
1699                         }
1700                 } else {
1701                         printf("Could not read pending message.\n");
1702                         break;
1703                 }
1704         }
1706         if (wpa_ctrl_pending(ctrl) < 0) {
1707                 printf("Connection to wpa_supplicant lost - trying to "
1708                        "reconnect\n");
1709                 wpa_cli_reconnect();
1710         }
1714 #ifdef CONFIG_READLINE
1715 static char * wpa_cli_cmd_gen(const char *text, int state)
1717         static int i, len;
1718         const char *cmd;
1720         if (state == 0) {
1721                 i = 0;
1722                 len = os_strlen(text);
1723         }
1725         while ((cmd = wpa_cli_commands[i].cmd)) {
1726                 i++;
1727                 if (os_strncasecmp(cmd, text, len) == 0)
1728                         return os_strdup(cmd);
1729         }
1731         return NULL;
1735 static char * wpa_cli_dummy_gen(const char *text, int state)
1737         return NULL;
1741 static char ** wpa_cli_completion(const char *text, int start, int end)
1743         return rl_completion_matches(text, start == 0 ?
1744                                      wpa_cli_cmd_gen : wpa_cli_dummy_gen);
1746 #endif /* CONFIG_READLINE */
1749 static void wpa_cli_interactive(void)
1751 #define max_args 10
1752         char cmdbuf[256], *cmd, *argv[max_args], *pos;
1753         int argc;
1754 #ifdef CONFIG_READLINE
1755         char *home, *hfile = NULL;
1756 #endif /* CONFIG_READLINE */
1758         printf("\nInteractive mode\n\n");
1760 #ifdef CONFIG_READLINE
1761         rl_attempted_completion_function = wpa_cli_completion;
1762         home = getenv("HOME");
1763         if (home) {
1764                 const char *fname = ".wpa_cli_history";
1765                 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
1766                 hfile = os_malloc(hfile_len);
1767                 if (hfile) {
1768                         int res;
1769                         res = os_snprintf(hfile, hfile_len, "%s/%s", home,
1770                                           fname);
1771                         if (res >= 0 && res < hfile_len) {
1772                                 hfile[hfile_len - 1] = '\0';
1773                                 read_history(hfile);
1774                                 stifle_history(100);
1775                         }
1776                 }
1777         }
1778 #endif /* CONFIG_READLINE */
1780         do {
1781                 wpa_cli_recv_pending(ctrl_conn, 0, 0);
1782 #ifndef CONFIG_NATIVE_WINDOWS
1783                 alarm(ping_interval);
1784 #endif /* CONFIG_NATIVE_WINDOWS */
1785 #ifdef CONFIG_READLINE
1786                 cmd = readline("> ");
1787                 if (cmd && *cmd) {
1788                         HIST_ENTRY *h;
1789                         while (next_history())
1790                                 ;
1791                         h = previous_history();
1792                         if (h == NULL || os_strcmp(cmd, h->line) != 0)
1793                                 add_history(cmd);
1794                         next_history();
1795                 }
1796 #else /* CONFIG_READLINE */
1797                 printf("> ");
1798                 cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
1799 #endif /* CONFIG_READLINE */
1800 #ifndef CONFIG_NATIVE_WINDOWS
1801                 alarm(0);
1802 #endif /* CONFIG_NATIVE_WINDOWS */
1803                 if (cmd == NULL)
1804                         break;
1805                 wpa_cli_recv_pending(ctrl_conn, 0, 0);
1806                 pos = cmd;
1807                 while (*pos != '\0') {
1808                         if (*pos == '\n') {
1809                                 *pos = '\0';
1810                                 break;
1811                         }
1812                         pos++;
1813                 }
1814                 argc = 0;
1815                 pos = cmd;
1816                 for (;;) {
1817                         while (*pos == ' ')
1818                                 pos++;
1819                         if (*pos == '\0')
1820                                 break;
1821                         argv[argc] = pos;
1822                         argc++;
1823                         if (argc == max_args)
1824                                 break;
1825                         if (*pos == '"') {
1826                                 char *pos2 = os_strrchr(pos, '"');
1827                                 if (pos2)
1828                                         pos = pos2 + 1;
1829                         }
1830                         while (*pos != '\0' && *pos != ' ')
1831                                 pos++;
1832                         if (*pos == ' ')
1833                                 *pos++ = '\0';
1834                 }
1835                 if (argc)
1836                         wpa_request(ctrl_conn, argc, argv);
1838                 if (cmd != cmdbuf)
1839                         os_free(cmd);
1840         } while (!wpa_cli_quit);
1842 #ifdef CONFIG_READLINE
1843         if (hfile) {
1844                 /* Save command history, excluding lines that may contain
1845                  * passwords. */
1846                 HIST_ENTRY *h;
1847                 history_set_pos(0);
1848                 while ((h = current_history())) {
1849                         char *p = h->line;
1850                         while (*p == ' ' || *p == '\t')
1851                                 p++;
1852                         if (cmd_has_sensitive_data(p)) {
1853                                 h = remove_history(where_history());
1854                                 if (h) {
1855                                         os_free(h->line);
1856                                         os_free(h->data);
1857                                         os_free(h);
1858                                 } else
1859                                         next_history();
1860                         } else
1861                                 next_history();
1862                 }
1863                 write_history(hfile);
1864                 os_free(hfile);
1865         }
1866 #endif /* CONFIG_READLINE */
1870 static void wpa_cli_action(struct wpa_ctrl *ctrl)
1872 #ifdef CONFIG_ANSI_C_EXTRA
1873         /* TODO: ANSI C version(?) */
1874         printf("Action processing not supported in ANSI C build.\n");
1875 #else /* CONFIG_ANSI_C_EXTRA */
1876         fd_set rfds;
1877         int fd, res;
1878         struct timeval tv;
1879         char buf[256]; /* note: large enough to fit in unsolicited messages */
1880         size_t len;
1882         fd = wpa_ctrl_get_fd(ctrl);
1884         while (!wpa_cli_quit) {
1885                 FD_ZERO(&rfds);
1886                 FD_SET(fd, &rfds);
1887                 tv.tv_sec = ping_interval;
1888                 tv.tv_usec = 0;
1889                 res = select(fd + 1, &rfds, NULL, NULL, &tv);
1890                 if (res < 0 && errno != EINTR) {
1891                         perror("select");
1892                         break;
1893                 }
1895                 if (FD_ISSET(fd, &rfds))
1896                         wpa_cli_recv_pending(ctrl, 0, 1);
1897                 else {
1898                         /* verify that connection is still working */
1899                         len = sizeof(buf) - 1;
1900                         if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
1901                                              wpa_cli_action_cb) < 0 ||
1902                             len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
1903                                 printf("wpa_supplicant did not reply to PING "
1904                                        "command - exiting\n");
1905                                 break;
1906                         }
1907                 }
1908         }
1909 #endif /* CONFIG_ANSI_C_EXTRA */
1913 static void wpa_cli_cleanup(void)
1915         wpa_cli_close_connection();
1916         if (pid_file)
1917                 os_daemonize_terminate(pid_file);
1919         os_program_deinit();
1922 static void wpa_cli_terminate(int sig)
1924         wpa_cli_cleanup();
1925         exit(0);
1929 #ifndef CONFIG_NATIVE_WINDOWS
1930 static void wpa_cli_alarm(int sig)
1932         if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
1933                 printf("Connection to wpa_supplicant lost - trying to "
1934                        "reconnect\n");
1935                 wpa_cli_close_connection();
1936         }
1937         if (!ctrl_conn)
1938                 wpa_cli_reconnect();
1939         if (ctrl_conn)
1940                 wpa_cli_recv_pending(ctrl_conn, 1, 0);
1941         alarm(ping_interval);
1943 #endif /* CONFIG_NATIVE_WINDOWS */
1946 static char * wpa_cli_get_default_ifname(void)
1948         char *ifname = NULL;
1950 #ifdef CONFIG_CTRL_IFACE_UNIX
1951         struct dirent *dent;
1952         DIR *dir = opendir(ctrl_iface_dir);
1953         if (!dir)
1954                 return NULL;
1955         while ((dent = readdir(dir))) {
1956 #ifdef _DIRENT_HAVE_D_TYPE
1957                 /*
1958                  * Skip the file if it is not a socket. Also accept
1959                  * DT_UNKNOWN (0) in case the C library or underlying
1960                  * file system does not support d_type.
1961                  */
1962                 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
1963                         continue;
1964 #endif /* _DIRENT_HAVE_D_TYPE */
1965                 if (os_strcmp(dent->d_name, ".") == 0 ||
1966                     os_strcmp(dent->d_name, "..") == 0)
1967                         continue;
1968                 printf("Selected interface '%s'\n", dent->d_name);
1969                 ifname = os_strdup(dent->d_name);
1970                 break;
1971         }
1972         closedir(dir);
1973 #endif /* CONFIG_CTRL_IFACE_UNIX */
1975 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
1976         char buf[2048], *pos;
1977         size_t len;
1978         struct wpa_ctrl *ctrl;
1979         int ret;
1981         ctrl = wpa_ctrl_open(NULL);
1982         if (ctrl == NULL)
1983                 return NULL;
1985         len = sizeof(buf) - 1;
1986         ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
1987         if (ret >= 0) {
1988                 buf[len] = '\0';
1989                 pos = os_strchr(buf, '\n');
1990                 if (pos)
1991                         *pos = '\0';
1992                 ifname = os_strdup(buf);
1993         }
1994         wpa_ctrl_close(ctrl);
1995 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
1997         return ifname;
2001 int main(int argc, char *argv[])
2003         int interactive;
2004         int warning_displayed = 0;
2005         int c;
2006         int daemonize = 0;
2007         int ret = 0;
2008         const char *global = NULL;
2010         if (os_program_init())
2011                 return -1;
2013         for (;;) {
2014                 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
2015                 if (c < 0)
2016                         break;
2017                 switch (c) {
2018                 case 'a':
2019                         action_file = optarg;
2020                         break;
2021                 case 'B':
2022                         daemonize = 1;
2023                         break;
2024                 case 'g':
2025                         global = optarg;
2026                         break;
2027                 case 'G':
2028                         ping_interval = atoi(optarg);
2029                         break;
2030                 case 'h':
2031                         usage();
2032                         return 0;
2033                 case 'v':
2034                         printf("%s\n", wpa_cli_version);
2035                         return 0;
2036                 case 'i':
2037                         os_free(ctrl_ifname);
2038                         ctrl_ifname = os_strdup(optarg);
2039                         break;
2040                 case 'p':
2041                         ctrl_iface_dir = optarg;
2042                         break;
2043                 case 'P':
2044                         pid_file = optarg;
2045                         break;
2046                 default:
2047                         usage();
2048                         return -1;
2049                 }
2050         }
2052         interactive = (argc == optind) && (action_file == NULL);
2054         if (interactive)
2055                 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
2057         if (global) {
2058 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
2059                 ctrl_conn = wpa_ctrl_open(NULL);
2060 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2061                 ctrl_conn = wpa_ctrl_open(global);
2062 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2063                 if (ctrl_conn == NULL) {
2064                         perror("Failed to connect to wpa_supplicant - "
2065                                "wpa_ctrl_open");
2066                         return -1;
2067                 }
2068         }
2070         for (; !global;) {
2071                 if (ctrl_ifname == NULL)
2072                         ctrl_ifname = wpa_cli_get_default_ifname();
2073                 ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
2074                 if (ctrl_conn) {
2075                         if (warning_displayed)
2076                                 printf("Connection established.\n");
2077                         break;
2078                 }
2080                 if (!interactive) {
2081                         perror("Failed to connect to wpa_supplicant - "
2082                                "wpa_ctrl_open");
2083                         return -1;
2084                 }
2086                 if (!warning_displayed) {
2087                         printf("Could not connect to wpa_supplicant - "
2088                                "re-trying\n");
2089                         warning_displayed = 1;
2090                 }
2091                 os_sleep(1, 0);
2092                 continue;
2093         }
2095 #ifndef _WIN32_WCE
2096         signal(SIGINT, wpa_cli_terminate);
2097         signal(SIGTERM, wpa_cli_terminate);
2098 #endif /* _WIN32_WCE */
2099 #ifndef CONFIG_NATIVE_WINDOWS
2100         signal(SIGALRM, wpa_cli_alarm);
2101 #endif /* CONFIG_NATIVE_WINDOWS */
2103         if (interactive || action_file) {
2104                 if (wpa_ctrl_attach(ctrl_conn) == 0) {
2105                         wpa_cli_attached = 1;
2106                 } else {
2107                         printf("Warning: Failed to attach to "
2108                                "wpa_supplicant.\n");
2109                         if (!interactive)
2110                                 return -1;
2111                 }
2112         }
2114         if (daemonize && os_daemonize(pid_file))
2115                 return -1;
2117         if (interactive)
2118                 wpa_cli_interactive();
2119         else if (action_file)
2120                 wpa_cli_action(ctrl_conn);
2121         else
2122                 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
2124         os_free(ctrl_ifname);
2125         wpa_cli_cleanup();
2127         return ret;
2130 #else /* CONFIG_CTRL_IFACE */
2131 int main(int argc, char *argv[])
2133         printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
2134         return -1;
2136 #endif /* CONFIG_CTRL_IFACE */