]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - build-utilities/hostap.git/blob - wpa_supplicant/wpa_cli.c
6ca79392e937378e8c0438b0b89f7b92a5e39739
[build-utilities/hostap.git] / wpa_supplicant / wpa_cli.c
1 /*
2  * WPA Supplicant - command line interface for wpa_supplicant daemon
3  * Copyright (c) 2004-2011, 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 */
23 #include "common/wpa_ctrl.h"
24 #include "utils/common.h"
25 #include "utils/eloop.h"
26 #include "utils/edit.h"
27 #include "utils/list.h"
28 #include "common/version.h"
29 #ifdef ANDROID
30 #include <cutils/properties.h>
31 #endif /* ANDROID */
34 static const char *wpa_cli_version =
35 "wpa_cli v" VERSION_STR "\n"
36 "Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi> and contributors";
39 static const char *wpa_cli_license =
40 "This program is free software. You can distribute it and/or modify it\n"
41 "under the terms of the GNU General Public License version 2.\n"
42 "\n"
43 "Alternatively, this software may be distributed under the terms of the\n"
44 "BSD license. See README and COPYING for more details.\n";
46 static const char *wpa_cli_full_license =
47 "This program is free software; you can redistribute it and/or modify\n"
48 "it under the terms of the GNU General Public License version 2 as\n"
49 "published by the Free Software Foundation.\n"
50 "\n"
51 "This program is distributed in the hope that it will be useful,\n"
52 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
53 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
54 "GNU General Public License for more details.\n"
55 "\n"
56 "You should have received a copy of the GNU General Public License\n"
57 "along with this program; if not, write to the Free Software\n"
58 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n"
59 "\n"
60 "Alternatively, this software may be distributed under the terms of the\n"
61 "BSD license.\n"
62 "\n"
63 "Redistribution and use in source and binary forms, with or without\n"
64 "modification, are permitted provided that the following conditions are\n"
65 "met:\n"
66 "\n"
67 "1. Redistributions of source code must retain the above copyright\n"
68 "   notice, this list of conditions and the following disclaimer.\n"
69 "\n"
70 "2. Redistributions in binary form must reproduce the above copyright\n"
71 "   notice, this list of conditions and the following disclaimer in the\n"
72 "   documentation and/or other materials provided with the distribution.\n"
73 "\n"
74 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
75 "   names of its contributors may be used to endorse or promote products\n"
76 "   derived from this software without specific prior written permission.\n"
77 "\n"
78 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
79 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
80 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
81 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
82 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
83 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
84 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
85 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
86 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
87 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
88 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
89 "\n";
91 static struct wpa_ctrl *ctrl_conn;
92 static struct wpa_ctrl *mon_conn;
93 static int wpa_cli_quit = 0;
94 static int wpa_cli_attached = 0;
95 static int wpa_cli_connected = 0;
96 static int wpa_cli_last_id = 0;
97 #ifndef CONFIG_CTRL_IFACE_DIR
98 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
99 #endif /* CONFIG_CTRL_IFACE_DIR */
100 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
101 static char *ctrl_ifname = NULL;
102 static const char *pid_file = NULL;
103 static const char *action_file = NULL;
104 static int ping_interval = 5;
105 static int interactive = 0;
107 struct cli_txt_entry {
108         struct dl_list list;
109         char *txt;
110 };
112 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
113 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
114 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
117 static void print_help(void);
118 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
121 static void usage(void)
123         printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
124                "[-a<action file>] \\\n"
125                "        [-P<pid file>] [-g<global ctrl>] [-G<ping interval>]  "
126                "[command..]\n"
127                "  -h = help (show this usage text)\n"
128                "  -v = shown version information\n"
129                "  -a = run in daemon mode executing the action file based on "
130                "events from\n"
131                "       wpa_supplicant\n"
132                "  -B = run a daemon in the background\n"
133                "  default path: " CONFIG_CTRL_IFACE_DIR "\n"
134                "  default interface: first interface found in socket path\n");
135         print_help();
139 static void cli_txt_list_free(struct cli_txt_entry *e)
141         dl_list_del(&e->list);
142         os_free(e->txt);
143         os_free(e);
147 static void cli_txt_list_flush(struct dl_list *list)
149         struct cli_txt_entry *e;
150         while ((e = dl_list_first(list, struct cli_txt_entry, list)))
151                 cli_txt_list_free(e);
155 static struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list,
156                                                const char *txt)
158         struct cli_txt_entry *e;
159         dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
160                 if (os_strcmp(e->txt, txt) == 0)
161                         return e;
162         }
163         return NULL;
167 static void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
169         struct cli_txt_entry *e;
170         e = cli_txt_list_get(txt_list, txt);
171         if (e)
172                 cli_txt_list_free(e);
176 static void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt)
178         u8 addr[ETH_ALEN];
179         char buf[18];
180         if (hwaddr_aton(txt, addr) < 0)
181                 return;
182         os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
183         cli_txt_list_del(txt_list, buf);
187 #ifdef CONFIG_P2P
188 static void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt)
190         const char *end;
191         char *buf;
192         end = os_strchr(txt, ' ');
193         if (end == NULL)
194                 end = txt + os_strlen(txt);
195         buf = os_malloc(end - txt + 1);
196         if (buf == NULL)
197                 return;
198         os_memcpy(buf, txt, end - txt);
199         buf[end - txt] = '\0';
200         cli_txt_list_del(txt_list, buf);
201         os_free(buf);
203 #endif /* CONFIG_P2P */
206 static int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
208         struct cli_txt_entry *e;
209         e = cli_txt_list_get(txt_list, txt);
210         if (e)
211                 return 0;
212         e = os_zalloc(sizeof(*e));
213         if (e == NULL)
214                 return -1;
215         e->txt = os_strdup(txt);
216         if (e->txt == NULL) {
217                 os_free(e);
218                 return -1;
219         }
220         dl_list_add(txt_list, &e->list);
221         return 0;
225 #ifdef CONFIG_P2P
226 static int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
228         u8 addr[ETH_ALEN];
229         char buf[18];
230         if (hwaddr_aton(txt, addr) < 0)
231                 return -1;
232         os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
233         return cli_txt_list_add(txt_list, buf);
237 static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt)
239         const char *end;
240         char *buf;
241         int ret;
242         end = os_strchr(txt, ' ');
243         if (end == NULL)
244                 end = txt + os_strlen(txt);
245         buf = os_malloc(end - txt + 1);
246         if (buf == NULL)
247                 return -1;
248         os_memcpy(buf, txt, end - txt);
249         buf[end - txt] = '\0';
250         ret = cli_txt_list_add(txt_list, buf);
251         os_free(buf);
252         return ret;
254 #endif /* CONFIG_P2P */
257 static char ** cli_txt_list_array(struct dl_list *txt_list)
259         unsigned int i, count = dl_list_len(txt_list);
260         char **res;
261         struct cli_txt_entry *e;
263         res = os_zalloc((count + 1) * sizeof(char *));
264         if (res == NULL)
265                 return NULL;
267         i = 0;
268         dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
269                 res[i] = os_strdup(e->txt);
270                 if (res[i] == NULL)
271                         break;
272                 i++;
273         }
275         return res;
279 static int get_cmd_arg_num(const char *str, int pos)
281         int arg = 0, i;
283         for (i = 0; i <= pos; i++) {
284                 if (str[i] != ' ') {
285                         arg++;
286                         while (i <= pos && str[i] != ' ')
287                                 i++;
288                 }
289         }
291         if (arg > 0)
292                 arg--;
293         return arg;
297 static int str_starts(const char *src, const char *match)
299         return os_strncmp(src, match, os_strlen(match)) == 0;
303 static int wpa_cli_show_event(const char *event)
305         const char *start;
307         start = os_strchr(event, '>');
308         if (start == NULL)
309                 return 1;
311         start++;
312         /*
313          * Skip BSS added/removed events since they can be relatively frequent
314          * and are likely of not much use for an interactive user.
315          */
316         if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
317             str_starts(start, WPA_EVENT_BSS_REMOVED))
318                 return 0;
320         return 1;
324 static int wpa_cli_open_connection(const char *ifname, int attach)
326 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
327         ctrl_conn = wpa_ctrl_open(ifname);
328         if (ctrl_conn == NULL)
329                 return -1;
331         if (attach && interactive)
332                 mon_conn = wpa_ctrl_open(ifname);
333         else
334                 mon_conn = NULL;
335 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
336         char *cfile = NULL;
337         int flen, res;
339         if (ifname == NULL)
340                 return -1;
342 #ifdef ANDROID
343         if (access(ctrl_iface_dir, F_OK) < 0) {
344                 cfile = os_strdup(ifname);
345                 if (cfile == NULL)
346                         return -1;
347         }
348 #endif /* ANDROID */
350         if (cfile == NULL) {
351                 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
352                 cfile = os_malloc(flen);
353                 if (cfile == NULL)
354                         return -1;
355                 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
356                                   ifname);
357                 if (res < 0 || res >= flen) {
358                         os_free(cfile);
359                         return -1;
360                 }
361         }
363         ctrl_conn = wpa_ctrl_open(cfile);
364         if (ctrl_conn == NULL) {
365                 os_free(cfile);
366                 return -1;
367         }
369         if (attach && interactive)
370                 mon_conn = wpa_ctrl_open(cfile);
371         else
372                 mon_conn = NULL;
373         os_free(cfile);
374 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
376         if (mon_conn) {
377                 if (wpa_ctrl_attach(mon_conn) == 0) {
378                         wpa_cli_attached = 1;
379                         if (interactive)
380                                 eloop_register_read_sock(
381                                         wpa_ctrl_get_fd(mon_conn),
382                                         wpa_cli_mon_receive, NULL, NULL);
383                 } else {
384                         printf("Warning: Failed to attach to "
385                                "wpa_supplicant.\n");
386                         return -1;
387                 }
388         }
390         return 0;
394 static void wpa_cli_close_connection(void)
396         if (ctrl_conn == NULL)
397                 return;
399         if (wpa_cli_attached) {
400                 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
401                 wpa_cli_attached = 0;
402         }
403         wpa_ctrl_close(ctrl_conn);
404         ctrl_conn = NULL;
405         if (mon_conn) {
406                 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
407                 wpa_ctrl_close(mon_conn);
408                 mon_conn = NULL;
409         }
413 static void wpa_cli_msg_cb(char *msg, size_t len)
415         printf("%s\n", msg);
419 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
421         char buf[2048];
422         size_t len;
423         int ret;
425         if (ctrl_conn == NULL) {
426                 printf("Not connected to wpa_supplicant - command dropped.\n");
427                 return -1;
428         }
429         len = sizeof(buf) - 1;
430         ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
431                                wpa_cli_msg_cb);
432         if (ret == -2) {
433                 printf("'%s' command timed out.\n", cmd);
434                 return -2;
435         } else if (ret < 0) {
436                 printf("'%s' command failed.\n", cmd);
437                 return -1;
438         }
439         if (print) {
440                 buf[len] = '\0';
441                 printf("%s", buf);
442                 if (interactive && len > 0 && buf[len - 1] != '\n')
443                         printf("\n");
444         }
445         return 0;
449 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
451         return _wpa_ctrl_command(ctrl, cmd, 1);
455 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
457         if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
458                 return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
459         if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
460                 return wpa_ctrl_command(ctrl, "STATUS-WPS");
461         return wpa_ctrl_command(ctrl, "STATUS");
465 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
467         return wpa_ctrl_command(ctrl, "PING");
471 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
473         return wpa_ctrl_command(ctrl, "RELOG");
477 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
479         char cmd[256];
480         int ret;
481         if (argc == 0)
482                 return -1;
483         ret = os_snprintf(cmd, sizeof(cmd), "NOTE %s", argv[0]);
484         if (ret < 0 || (size_t) ret >= sizeof(cmd))
485                 return -1;
486         return wpa_ctrl_command(ctrl, cmd);
490 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
492         return wpa_ctrl_command(ctrl, "MIB");
496 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
498         return wpa_ctrl_command(ctrl, "PMKSA");
502 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
504         print_help();
505         return 0;
509 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
511         printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
512         return 0;
516 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
518         wpa_cli_quit = 1;
519         if (interactive)
520                 eloop_terminate();
521         return 0;
525 static void wpa_cli_show_variables(void)
527         printf("set variables:\n"
528                "  EAPOL::heldPeriod (EAPOL state machine held period, "
529                "in seconds)\n"
530                "  EAPOL::authPeriod (EAPOL state machine authentication "
531                "period, in seconds)\n"
532                "  EAPOL::startPeriod (EAPOL state machine start period, in "
533                "seconds)\n"
534                "  EAPOL::maxStart (EAPOL state machine maximum start "
535                "attempts)\n");
536         printf("  dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
537                "seconds)\n"
538                "  dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
539                " threshold\n\tpercentage)\n"
540                "  dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
541                "security\n\tassociation in seconds)\n");
545 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
547         char cmd[256];
548         int res;
550         if (argc == 0) {
551                 wpa_cli_show_variables();
552                 return 0;
553         }
555         if (argc != 1 && argc != 2) {
556                 printf("Invalid SET command: needs two arguments (variable "
557                        "name and value)\n");
558                 return -1;
559         }
561         if (argc == 1)
562                 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
563         else
564                 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s",
565                                   argv[0], argv[1]);
566         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
567                 printf("Too long SET command.\n");
568                 return -1;
569         }
570         return wpa_ctrl_command(ctrl, cmd);
574 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
576         char cmd[256];
577         int res;
579         if (argc != 1) {
580                 printf("Invalid GET command: need one argument (variable "
581                        "name)\n");
582                 return -1;
583         }
585         res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
586         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
587                 printf("Too long GET command.\n");
588                 return -1;
589         }
590         return wpa_ctrl_command(ctrl, cmd);
594 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
596         return wpa_ctrl_command(ctrl, "LOGOFF");
600 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
602         return wpa_ctrl_command(ctrl, "LOGON");
606 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
607                                    char *argv[])
609         return wpa_ctrl_command(ctrl, "REASSOCIATE");
613 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
614                                        char *argv[])
616         char cmd[256];
617         int res;
619         if (argc != 1) {
620                 printf("Invalid PREAUTH command: needs one argument "
621                        "(BSSID)\n");
622                 return -1;
623         }
625         res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
626         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
627                 printf("Too long PREAUTH command.\n");
628                 return -1;
629         }
630         return wpa_ctrl_command(ctrl, cmd);
634 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
636         char cmd[256];
637         int res;
639         if (argc != 1) {
640                 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
641                        "value)\n");
642                 return -1;
643         }
644         res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
645         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
646                 printf("Too long AP_SCAN command.\n");
647                 return -1;
648         }
649         return wpa_ctrl_command(ctrl, cmd);
653 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
654                                      char *argv[])
656         char cmd[256];
657         int res;
659         if (argc != 1) {
660                 printf("Invalid SCAN_INTERVAL command: needs one argument "
661                        "scan_interval value)\n");
662                 return -1;
663         }
664         res = os_snprintf(cmd, sizeof(cmd), "SCAN_INTERVAL %s", argv[0]);
665         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
666                 printf("Too long SCAN_INTERVAL command.\n");
667                 return -1;
668         }
669         return wpa_ctrl_command(ctrl, cmd);
673 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
674                                       char *argv[])
676         char cmd[256];
677         int res;
679         if (argc != 1) {
680                 printf("Invalid BSS_EXPIRE_AGE command: needs one argument "
681                        "(bss_expire_age value)\n");
682                 return -1;
683         }
684         res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_AGE %s", argv[0]);
685         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
686                 printf("Too long BSS_EXPIRE_AGE command.\n");
687                 return -1;
688         }
689         return wpa_ctrl_command(ctrl, cmd);
693 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
694                                         char *argv[])
696         char cmd[256];
697         int res;
699         if (argc != 1) {
700                 printf("Invalid BSS_EXPIRE_COUNT command: needs one argument "
701                        "(bss_expire_count value)\n");
702                 return -1;
703         }
704         res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_COUNT %s", argv[0]);
705         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
706                 printf("Too long BSS_EXPIRE_COUNT command.\n");
707                 return -1;
708         }
709         return wpa_ctrl_command(ctrl, cmd);
713 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
714                                 char *argv[])
716         char cmd[256];
717         int res;
719         if (argc != 1) {
720                 printf("Invalid STKSTART command: needs one argument "
721                        "(Peer STA MAC address)\n");
722                 return -1;
723         }
725         res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
726         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
727                 printf("Too long STKSTART command.\n");
728                 return -1;
729         }
730         return wpa_ctrl_command(ctrl, cmd);
734 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
736         char cmd[256];
737         int res;
739         if (argc != 1) {
740                 printf("Invalid FT_DS command: needs one argument "
741                        "(Target AP MAC address)\n");
742                 return -1;
743         }
745         res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
746         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
747                 printf("Too long FT_DS command.\n");
748                 return -1;
749         }
750         return wpa_ctrl_command(ctrl, cmd);
754 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
756         char cmd[256];
757         int res;
759         if (argc == 0) {
760                 /* Any BSSID */
761                 return wpa_ctrl_command(ctrl, "WPS_PBC");
762         }
764         /* Specific BSSID */
765         res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
766         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
767                 printf("Too long WPS_PBC command.\n");
768                 return -1;
769         }
770         return wpa_ctrl_command(ctrl, cmd);
774 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
776         char cmd[256];
777         int res;
779         if (argc == 0) {
780                 printf("Invalid WPS_PIN command: need one or two arguments:\n"
781                        "- BSSID: use 'any' to select any\n"
782                        "- PIN: optional, used only with devices that have no "
783                        "display\n");
784                 return -1;
785         }
787         if (argc == 1) {
788                 /* Use dynamically generated PIN (returned as reply) */
789                 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
790                 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
791                         printf("Too long WPS_PIN command.\n");
792                         return -1;
793                 }
794                 return wpa_ctrl_command(ctrl, cmd);
795         }
797         /* Use hardcoded PIN from a label */
798         res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
799         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
800                 printf("Too long WPS_PIN command.\n");
801                 return -1;
802         }
803         return wpa_ctrl_command(ctrl, cmd);
807 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
808                                      char *argv[])
810         char cmd[256];
811         int res;
813         if (argc != 1 && argc != 2) {
814                 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
815                        "- PIN to be verified\n");
816                 return -1;
817         }
819         if (argc == 2)
820                 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
821                                   argv[0], argv[1]);
822         else
823                 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
824                                   argv[0]);
825         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
826                 printf("Too long WPS_CHECK_PIN command.\n");
827                 return -1;
828         }
829         return wpa_ctrl_command(ctrl, cmd);
833 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
834                                   char *argv[])
836         return wpa_ctrl_command(ctrl, "WPS_CANCEL");
840 #ifdef CONFIG_WPS_OOB
841 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
843         char cmd[256];
844         int res;
846         if (argc != 3 && argc != 4) {
847                 printf("Invalid WPS_OOB command: need three or four "
848                        "arguments:\n"
849                        "- DEV_TYPE: use 'ufd' or 'nfc'\n"
850                        "- PATH: path of OOB device like '/mnt'\n"
851                        "- METHOD: OOB method 'pin-e' or 'pin-r', "
852                        "'cred'\n"
853                        "- DEV_NAME: (only for NFC) device name like "
854                        "'pn531'\n");
855                 return -1;
856         }
858         if (argc == 3)
859                 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
860                                   argv[0], argv[1], argv[2]);
861         else
862                 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
863                                   argv[0], argv[1], argv[2], argv[3]);
864         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
865                 printf("Too long WPS_OOB command.\n");
866                 return -1;
867         }
868         return wpa_ctrl_command(ctrl, cmd);
870 #endif /* CONFIG_WPS_OOB */
873 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
875         char cmd[256];
876         int res;
878         if (argc == 2)
879                 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
880                                   argv[0], argv[1]);
881         else if (argc == 5 || argc == 6) {
882                 char ssid_hex[2 * 32 + 1];
883                 char key_hex[2 * 64 + 1];
884                 int i;
886                 ssid_hex[0] = '\0';
887                 for (i = 0; i < 32; i++) {
888                         if (argv[2][i] == '\0')
889                                 break;
890                         os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
891                 }
893                 key_hex[0] = '\0';
894                 if (argc == 6) {
895                         for (i = 0; i < 64; i++) {
896                                 if (argv[5][i] == '\0')
897                                         break;
898                                 os_snprintf(&key_hex[i * 2], 3, "%02x",
899                                             argv[5][i]);
900                         }
901                 }
903                 res = os_snprintf(cmd, sizeof(cmd),
904                                   "WPS_REG %s %s %s %s %s %s",
905                                   argv[0], argv[1], ssid_hex, argv[3], argv[4],
906                                   key_hex);
907         } else {
908                 printf("Invalid WPS_REG command: need two arguments:\n"
909                        "- BSSID of the target AP\n"
910                        "- AP PIN\n");
911                 printf("Alternatively, six arguments can be used to "
912                        "reconfigure the AP:\n"
913                        "- BSSID of the target AP\n"
914                        "- AP PIN\n"
915                        "- new SSID\n"
916                        "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
917                        "- new encr (NONE, WEP, TKIP, CCMP)\n"
918                        "- new key\n");
919                 return -1;
920         }
922         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
923                 printf("Too long WPS_REG command.\n");
924                 return -1;
925         }
926         return wpa_ctrl_command(ctrl, cmd);
930 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
931                                   char *argv[])
933         char cmd[256];
934         int res;
936         if (argc < 1) {
937                 printf("Invalid WPS_AP_PIN command: needs at least one "
938                        "argument\n");
939                 return -1;
940         }
942         if (argc > 2)
943                 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s %s",
944                                   argv[0], argv[1], argv[2]);
945         else if (argc > 1)
946                 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s",
947                                   argv[0], argv[1]);
948         else
949                 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s",
950                                   argv[0]);
951         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
952                 printf("Too long WPS_AP_PIN command.\n");
953                 return -1;
954         }
955         return wpa_ctrl_command(ctrl, cmd);
959 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
960                                     char *argv[])
962         char cmd[100];
963         if (argc > 0) {
964                 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
965                 return wpa_ctrl_command(ctrl, cmd);
966         }
967         return wpa_ctrl_command(ctrl, "WPS_ER_START");
971 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
972                                    char *argv[])
974         return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
979 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
980                                   char *argv[])
982         char cmd[256];
983         int res;
985         if (argc < 2) {
986                 printf("Invalid WPS_ER_PIN command: need at least two "
987                        "arguments:\n"
988                        "- UUID: use 'any' to select any\n"
989                        "- PIN: Enrollee PIN\n"
990                        "optional: - Enrollee MAC address\n");
991                 return -1;
992         }
994         if (argc > 2)
995                 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
996                                   argv[0], argv[1], argv[2]);
997         else
998                 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
999                                   argv[0], argv[1]);
1000         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1001                 printf("Too long WPS_ER_PIN command.\n");
1002                 return -1;
1003         }
1004         return wpa_ctrl_command(ctrl, cmd);
1008 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
1009                                   char *argv[])
1011         char cmd[256];
1012         int res;
1014         if (argc != 1) {
1015                 printf("Invalid WPS_ER_PBC command: need one argument:\n"
1016                        "- UUID: Specify the Enrollee\n");
1017                 return -1;
1018         }
1020         res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
1021                           argv[0]);
1022         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1023                 printf("Too long WPS_ER_PBC command.\n");
1024                 return -1;
1025         }
1026         return wpa_ctrl_command(ctrl, cmd);
1030 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
1031                                     char *argv[])
1033         char cmd[256];
1034         int res;
1036         if (argc != 2) {
1037                 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1038                        "- UUID: specify which AP to use\n"
1039                        "- PIN: AP PIN\n");
1040                 return -1;
1041         }
1043         res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
1044                           argv[0], argv[1]);
1045         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1046                 printf("Too long WPS_ER_LEARN command.\n");
1047                 return -1;
1048         }
1049         return wpa_ctrl_command(ctrl, cmd);
1053 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
1054                                          char *argv[])
1056         char cmd[256];
1057         int res;
1059         if (argc != 2) {
1060                 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1061                        "arguments:\n"
1062                        "- UUID: specify which AP to use\n"
1063                        "- Network configuration id\n");
1064                 return -1;
1065         }
1067         res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_SET_CONFIG %s %s",
1068                           argv[0], argv[1]);
1069         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1070                 printf("Too long WPS_ER_SET_CONFIG command.\n");
1071                 return -1;
1072         }
1073         return wpa_ctrl_command(ctrl, cmd);
1077 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
1078                                      char *argv[])
1080         char cmd[256];
1081         int res;
1083         if (argc == 5 || argc == 6) {
1084                 char ssid_hex[2 * 32 + 1];
1085                 char key_hex[2 * 64 + 1];
1086                 int i;
1088                 ssid_hex[0] = '\0';
1089                 for (i = 0; i < 32; i++) {
1090                         if (argv[2][i] == '\0')
1091                                 break;
1092                         os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1093                 }
1095                 key_hex[0] = '\0';
1096                 if (argc == 6) {
1097                         for (i = 0; i < 64; i++) {
1098                                 if (argv[5][i] == '\0')
1099                                         break;
1100                                 os_snprintf(&key_hex[i * 2], 3, "%02x",
1101                                             argv[5][i]);
1102                         }
1103                 }
1105                 res = os_snprintf(cmd, sizeof(cmd),
1106                                   "WPS_ER_CONFIG %s %s %s %s %s %s",
1107                                   argv[0], argv[1], ssid_hex, argv[3], argv[4],
1108                                   key_hex);
1109         } else {
1110                 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1111                        "- AP UUID\n"
1112                        "- AP PIN\n"
1113                        "- new SSID\n"
1114                        "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1115                        "- new encr (NONE, WEP, TKIP, CCMP)\n"
1116                        "- new key\n");
1117                 return -1;
1118         }
1120         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1121                 printf("Too long WPS_ER_CONFIG command.\n");
1122                 return -1;
1123         }
1124         return wpa_ctrl_command(ctrl, cmd);
1128 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1130         char cmd[256];
1131         int res;
1133         if (argc != 1) {
1134                 printf("Invalid IBSS_RSN command: needs one argument "
1135                        "(Peer STA MAC address)\n");
1136                 return -1;
1137         }
1139         res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
1140         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1141                 printf("Too long IBSS_RSN command.\n");
1142                 return -1;
1143         }
1144         return wpa_ctrl_command(ctrl, cmd);
1148 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1150         char cmd[256];
1151         int res;
1153         if (argc != 1) {
1154                 printf("Invalid LEVEL command: needs one argument (debug "
1155                        "level)\n");
1156                 return -1;
1157         }
1158         res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
1159         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1160                 printf("Too long LEVEL command.\n");
1161                 return -1;
1162         }
1163         return wpa_ctrl_command(ctrl, cmd);
1167 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1169         char cmd[256], *pos, *end;
1170         int i, ret;
1172         if (argc < 2) {
1173                 printf("Invalid IDENTITY command: needs two arguments "
1174                        "(network id and identity)\n");
1175                 return -1;
1176         }
1178         end = cmd + sizeof(cmd);
1179         pos = cmd;
1180         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1181                           argv[0], argv[1]);
1182         if (ret < 0 || ret >= end - pos) {
1183                 printf("Too long IDENTITY command.\n");
1184                 return -1;
1185         }
1186         pos += ret;
1187         for (i = 2; i < argc; i++) {
1188                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1189                 if (ret < 0 || ret >= end - pos) {
1190                         printf("Too long IDENTITY command.\n");
1191                         return -1;
1192                 }
1193                 pos += ret;
1194         }
1196         return wpa_ctrl_command(ctrl, cmd);
1200 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1202         char cmd[256], *pos, *end;
1203         int i, ret;
1205         if (argc < 2) {
1206                 printf("Invalid PASSWORD command: needs two arguments "
1207                        "(network id and password)\n");
1208                 return -1;
1209         }
1211         end = cmd + sizeof(cmd);
1212         pos = cmd;
1213         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1214                           argv[0], argv[1]);
1215         if (ret < 0 || ret >= end - pos) {
1216                 printf("Too long PASSWORD command.\n");
1217                 return -1;
1218         }
1219         pos += ret;
1220         for (i = 2; i < argc; i++) {
1221                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1222                 if (ret < 0 || ret >= end - pos) {
1223                         printf("Too long PASSWORD command.\n");
1224                         return -1;
1225                 }
1226                 pos += ret;
1227         }
1229         return wpa_ctrl_command(ctrl, cmd);
1233 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1234                                     char *argv[])
1236         char cmd[256], *pos, *end;
1237         int i, ret;
1239         if (argc < 2) {
1240                 printf("Invalid NEW_PASSWORD command: needs two arguments "
1241                        "(network id and password)\n");
1242                 return -1;
1243         }
1245         end = cmd + sizeof(cmd);
1246         pos = cmd;
1247         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1248                           argv[0], argv[1]);
1249         if (ret < 0 || ret >= end - pos) {
1250                 printf("Too long NEW_PASSWORD command.\n");
1251                 return -1;
1252         }
1253         pos += ret;
1254         for (i = 2; i < argc; i++) {
1255                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1256                 if (ret < 0 || ret >= end - pos) {
1257                         printf("Too long NEW_PASSWORD command.\n");
1258                         return -1;
1259                 }
1260                 pos += ret;
1261         }
1263         return wpa_ctrl_command(ctrl, cmd);
1267 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1269         char cmd[256], *pos, *end;
1270         int i, ret;
1272         if (argc < 2) {
1273                 printf("Invalid PIN command: needs two arguments "
1274                        "(network id and pin)\n");
1275                 return -1;
1276         }
1278         end = cmd + sizeof(cmd);
1279         pos = cmd;
1280         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1281                           argv[0], argv[1]);
1282         if (ret < 0 || ret >= end - pos) {
1283                 printf("Too long PIN command.\n");
1284                 return -1;
1285         }
1286         pos += ret;
1287         for (i = 2; i < argc; i++) {
1288                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1289                 if (ret < 0 || ret >= end - pos) {
1290                         printf("Too long PIN command.\n");
1291                         return -1;
1292                 }
1293                 pos += ret;
1294         }
1295         return wpa_ctrl_command(ctrl, cmd);
1299 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1301         char cmd[256], *pos, *end;
1302         int i, ret;
1304         if (argc < 2) {
1305                 printf("Invalid OTP command: needs two arguments (network "
1306                        "id and password)\n");
1307                 return -1;
1308         }
1310         end = cmd + sizeof(cmd);
1311         pos = cmd;
1312         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1313                           argv[0], argv[1]);
1314         if (ret < 0 || ret >= end - pos) {
1315                 printf("Too long OTP command.\n");
1316                 return -1;
1317         }
1318         pos += ret;
1319         for (i = 2; i < argc; i++) {
1320                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1321                 if (ret < 0 || ret >= end - pos) {
1322                         printf("Too long OTP command.\n");
1323                         return -1;
1324                 }
1325                 pos += ret;
1326         }
1328         return wpa_ctrl_command(ctrl, cmd);
1332 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1333                                   char *argv[])
1335         char cmd[256], *pos, *end;
1336         int i, ret;
1338         if (argc < 2) {
1339                 printf("Invalid PASSPHRASE command: needs two arguments "
1340                        "(network id and passphrase)\n");
1341                 return -1;
1342         }
1344         end = cmd + sizeof(cmd);
1345         pos = cmd;
1346         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1347                           argv[0], argv[1]);
1348         if (ret < 0 || ret >= end - pos) {
1349                 printf("Too long PASSPHRASE command.\n");
1350                 return -1;
1351         }
1352         pos += ret;
1353         for (i = 2; i < argc; i++) {
1354                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1355                 if (ret < 0 || ret >= end - pos) {
1356                         printf("Too long PASSPHRASE command.\n");
1357                         return -1;
1358                 }
1359                 pos += ret;
1360         }
1362         return wpa_ctrl_command(ctrl, cmd);
1366 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1368         char cmd[256], *pos, *end;
1369         int i, ret;
1371         if (argc < 2) {
1372                 printf("Invalid BSSID command: needs two arguments (network "
1373                        "id and BSSID)\n");
1374                 return -1;
1375         }
1377         end = cmd + sizeof(cmd);
1378         pos = cmd;
1379         ret = os_snprintf(pos, end - pos, "BSSID");
1380         if (ret < 0 || ret >= end - pos) {
1381                 printf("Too long BSSID command.\n");
1382                 return -1;
1383         }
1384         pos += ret;
1385         for (i = 0; i < argc; i++) {
1386                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1387                 if (ret < 0 || ret >= end - pos) {
1388                         printf("Too long BSSID command.\n");
1389                         return -1;
1390                 }
1391                 pos += ret;
1392         }
1394         return wpa_ctrl_command(ctrl, cmd);
1398 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1400         char cmd[256], *pos, *end;
1401         int i, ret;
1403         end = cmd + sizeof(cmd);
1404         pos = cmd;
1405         ret = os_snprintf(pos, end - pos, "BLACKLIST");
1406         if (ret < 0 || ret >= end - pos) {
1407                 printf("Too long BLACKLIST command.\n");
1408                 return -1;
1409         }
1410         pos += ret;
1411         for (i = 0; i < argc; i++) {
1412                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1413                 if (ret < 0 || ret >= end - pos) {
1414                         printf("Too long BLACKLIST command.\n");
1415                         return -1;
1416                 }
1417                 pos += ret;
1418         }
1420         return wpa_ctrl_command(ctrl, cmd);
1424 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1426         char cmd[256], *pos, *end;
1427         int i, ret;
1429         end = cmd + sizeof(cmd);
1430         pos = cmd;
1431         ret = os_snprintf(pos, end - pos, "LOG_LEVEL");
1432         if (ret < 0 || ret >= end - pos) {
1433                 printf("Too long LOG_LEVEL command.\n");
1434                 return -1;
1435         }
1436         pos += ret;
1437         for (i = 0; i < argc; i++) {
1438                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1439                 if (ret < 0 || ret >= end - pos) {
1440                         printf("Too long LOG_LEVEL command.\n");
1441                         return -1;
1442                 }
1443                 pos += ret;
1444         }
1446         return wpa_ctrl_command(ctrl, cmd);
1450 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1451                                      char *argv[])
1453         return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1457 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1458                                       char *argv[])
1460         char cmd[32];
1461         int res;
1463         if (argc < 1) {
1464                 printf("Invalid SELECT_NETWORK command: needs one argument "
1465                        "(network id)\n");
1466                 return -1;
1467         }
1469         res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1470         if (res < 0 || (size_t) res >= sizeof(cmd))
1471                 return -1;
1472         cmd[sizeof(cmd) - 1] = '\0';
1474         return wpa_ctrl_command(ctrl, cmd);
1478 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1479                                       char *argv[])
1481         char cmd[32];
1482         int res;
1484         if (argc < 1) {
1485                 printf("Invalid ENABLE_NETWORK command: needs one argument "
1486                        "(network id)\n");
1487                 return -1;
1488         }
1490         res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1491         if (res < 0 || (size_t) res >= sizeof(cmd))
1492                 return -1;
1493         cmd[sizeof(cmd) - 1] = '\0';
1495         return wpa_ctrl_command(ctrl, cmd);
1499 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1500                                        char *argv[])
1502         char cmd[32];
1503         int res;
1505         if (argc < 1) {
1506                 printf("Invalid DISABLE_NETWORK command: needs one argument "
1507                        "(network id)\n");
1508                 return -1;
1509         }
1511         res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1512         if (res < 0 || (size_t) res >= sizeof(cmd))
1513                 return -1;
1514         cmd[sizeof(cmd) - 1] = '\0';
1516         return wpa_ctrl_command(ctrl, cmd);
1520 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1521                                    char *argv[])
1523         return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1527 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1528                                       char *argv[])
1530         char cmd[32];
1531         int res;
1533         if (argc < 1) {
1534                 printf("Invalid REMOVE_NETWORK command: needs one argument "
1535                        "(network id)\n");
1536                 return -1;
1537         }
1539         res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1540         if (res < 0 || (size_t) res >= sizeof(cmd))
1541                 return -1;
1542         cmd[sizeof(cmd) - 1] = '\0';
1544         return wpa_ctrl_command(ctrl, cmd);
1548 static void wpa_cli_show_network_variables(void)
1550         printf("set_network variables:\n"
1551                "  ssid (network name, SSID)\n"
1552                "  psk (WPA passphrase or pre-shared key)\n"
1553                "  key_mgmt (key management protocol)\n"
1554                "  identity (EAP identity)\n"
1555                "  password (EAP password)\n"
1556                "  ...\n"
1557                "\n"
1558                "Note: Values are entered in the same format as the "
1559                "configuration file is using,\n"
1560                "i.e., strings values need to be inside double quotation "
1561                "marks.\n"
1562                "For example: set_network 1 ssid \"network name\"\n"
1563                "\n"
1564                "Please see wpa_supplicant.conf documentation for full list "
1565                "of\navailable variables.\n");
1569 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1570                                    char *argv[])
1572         char cmd[256];
1573         int res;
1575         if (argc == 0) {
1576                 wpa_cli_show_network_variables();
1577                 return 0;
1578         }
1580         if (argc != 3) {
1581                 printf("Invalid SET_NETWORK command: needs three arguments\n"
1582                        "(network id, variable name, and value)\n");
1583                 return -1;
1584         }
1586         res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1587                           argv[0], argv[1], argv[2]);
1588         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1589                 printf("Too long SET_NETWORK command.\n");
1590                 return -1;
1591         }
1592         return wpa_ctrl_command(ctrl, cmd);
1596 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1597                                    char *argv[])
1599         char cmd[256];
1600         int res;
1602         if (argc == 0) {
1603                 wpa_cli_show_network_variables();
1604                 return 0;
1605         }
1607         if (argc != 2) {
1608                 printf("Invalid GET_NETWORK command: needs two arguments\n"
1609                        "(network id and variable name)\n");
1610                 return -1;
1611         }
1613         res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1614                           argv[0], argv[1]);
1615         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1616                 printf("Too long GET_NETWORK command.\n");
1617                 return -1;
1618         }
1619         return wpa_ctrl_command(ctrl, cmd);
1623 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1624                                   char *argv[])
1626         return wpa_ctrl_command(ctrl, "DISCONNECT");
1630 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1631                                   char *argv[])
1633         return wpa_ctrl_command(ctrl, "RECONNECT");
1637 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1638                                    char *argv[])
1640         return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1644 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1646         return wpa_ctrl_command(ctrl, "SCAN");
1650 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1651                                     char *argv[])
1653         return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1657 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1659         char cmd[64];
1660         int res;
1662         if (argc != 1) {
1663                 printf("Invalid BSS command: need one argument (index or "
1664                        "BSSID)\n");
1665                 return -1;
1666         }
1668         res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1669         if (res < 0 || (size_t) res >= sizeof(cmd))
1670                 return -1;
1671         cmd[sizeof(cmd) - 1] = '\0';
1673         return wpa_ctrl_command(ctrl, cmd);
1677 static char ** wpa_cli_complete_bss(const char *str, int pos)
1679         int arg = get_cmd_arg_num(str, pos);
1680         char **res = NULL;
1682         switch (arg) {
1683         case 1:
1684                 res = cli_txt_list_array(&bsses);
1685                 break;
1686         }
1688         return res;
1692 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1693                                       char *argv[])
1695         char cmd[64];
1696         int res;
1698         if (argc < 1 || argc > 2) {
1699                 printf("Invalid GET_CAPABILITY command: need either one or "
1700                        "two arguments\n");
1701                 return -1;
1702         }
1704         if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1705                 printf("Invalid GET_CAPABILITY command: second argument, "
1706                        "if any, must be 'strict'\n");
1707                 return -1;
1708         }
1710         res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1711                           (argc == 2) ? " strict" : "");
1712         if (res < 0 || (size_t) res >= sizeof(cmd))
1713                 return -1;
1714         cmd[sizeof(cmd) - 1] = '\0';
1716         return wpa_ctrl_command(ctrl, cmd);
1720 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1722         printf("Available interfaces:\n");
1723         return wpa_ctrl_command(ctrl, "INTERFACES");
1727 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1729         if (argc < 1) {
1730                 wpa_cli_list_interfaces(ctrl);
1731                 return 0;
1732         }
1734         wpa_cli_close_connection();
1735         os_free(ctrl_ifname);
1736         ctrl_ifname = os_strdup(argv[0]);
1738         if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1739                 printf("Connected to interface '%s.\n", ctrl_ifname);
1740         } else {
1741                 printf("Could not connect to interface '%s' - re-trying\n",
1742                        ctrl_ifname);
1743         }
1744         return 0;
1748 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1749                                    char *argv[])
1751         return wpa_ctrl_command(ctrl, "RECONFIGURE");
1755 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1756                                  char *argv[])
1758         return wpa_ctrl_command(ctrl, "TERMINATE");
1762 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1763                                      char *argv[])
1765         char cmd[256];
1766         int res;
1768         if (argc < 1) {
1769                 printf("Invalid INTERFACE_ADD command: needs at least one "
1770                        "argument (interface name)\n"
1771                        "All arguments: ifname confname driver ctrl_interface "
1772                        "driver_param bridge_name\n");
1773                 return -1;
1774         }
1776         /*
1777          * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1778          * <driver_param>TAB<bridge_name>
1779          */
1780         res = os_snprintf(cmd, sizeof(cmd),
1781                           "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1782                           argv[0],
1783                           argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1784                           argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1785                           argc > 5 ? argv[5] : "");
1786         if (res < 0 || (size_t) res >= sizeof(cmd))
1787                 return -1;
1788         cmd[sizeof(cmd) - 1] = '\0';
1789         return wpa_ctrl_command(ctrl, cmd);
1793 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1794                                         char *argv[])
1796         char cmd[128];
1797         int res;
1799         if (argc != 1) {
1800                 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1801                        "(interface name)\n");
1802                 return -1;
1803         }
1805         res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1806         if (res < 0 || (size_t) res >= sizeof(cmd))
1807                 return -1;
1808         cmd[sizeof(cmd) - 1] = '\0';
1809         return wpa_ctrl_command(ctrl, cmd);
1813 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1814                                       char *argv[])
1816         return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1820 #ifdef CONFIG_AP
1821 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1823         char buf[64];
1824         if (argc != 1) {
1825                 printf("Invalid 'sta' command - exactly one argument, STA "
1826                        "address, is required.\n");
1827                 return -1;
1828         }
1829         os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1830         return wpa_ctrl_command(ctrl, buf);
1834 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1835                                 char *addr, size_t addr_len)
1837         char buf[4096], *pos;
1838         size_t len;
1839         int ret;
1841         if (ctrl_conn == NULL) {
1842                 printf("Not connected to hostapd - command dropped.\n");
1843                 return -1;
1844         }
1845         len = sizeof(buf) - 1;
1846         ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1847                                wpa_cli_msg_cb);
1848         if (ret == -2) {
1849                 printf("'%s' command timed out.\n", cmd);
1850                 return -2;
1851         } else if (ret < 0) {
1852                 printf("'%s' command failed.\n", cmd);
1853                 return -1;
1854         }
1856         buf[len] = '\0';
1857         if (memcmp(buf, "FAIL", 4) == 0)
1858                 return -1;
1859         printf("%s", buf);
1861         pos = buf;
1862         while (*pos != '\0' && *pos != '\n')
1863                 pos++;
1864         *pos = '\0';
1865         os_strlcpy(addr, buf, addr_len);
1866         return 0;
1870 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1872         char addr[32], cmd[64];
1874         if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1875                 return 0;
1876         do {
1877                 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1878         } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1880         return -1;
1882 #endif /* CONFIG_AP */
1885 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1887         return wpa_ctrl_command(ctrl, "SUSPEND");
1891 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1893         return wpa_ctrl_command(ctrl, "RESUME");
1897 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1899         return wpa_ctrl_command(ctrl, "DROP_SA");
1903 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1905         char cmd[128];
1906         int res;
1908         if (argc != 1) {
1909                 printf("Invalid ROAM command: needs one argument "
1910                        "(target AP's BSSID)\n");
1911                 return -1;
1912         }
1914         res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1915         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1916                 printf("Too long ROAM command.\n");
1917                 return -1;
1918         }
1919         return wpa_ctrl_command(ctrl, cmd);
1923 #ifdef CONFIG_P2P
1925 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1927         char cmd[128];
1928         int res;
1930         if (argc == 0)
1931                 return wpa_ctrl_command(ctrl, "P2P_FIND");
1933         if (argc > 1)
1934                 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
1935                                   argv[0], argv[1]);
1936         else
1937                 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
1938         if (res < 0 || (size_t) res >= sizeof(cmd))
1939                 return -1;
1940         cmd[sizeof(cmd) - 1] = '\0';
1941         return wpa_ctrl_command(ctrl, cmd);
1945 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1946                                      char *argv[])
1948         return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1952 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1953                                    char *argv[])
1955         char cmd[128];
1956         int res;
1958         if (argc < 2) {
1959                 printf("Invalid P2P_CONNECT command: needs at least two "
1960                        "arguments (address and pbc/PIN)\n");
1961                 return -1;
1962         }
1964         if (argc > 4)
1965                 res = os_snprintf(cmd, sizeof(cmd),
1966                                   "P2P_CONNECT %s %s %s %s %s",
1967                                   argv[0], argv[1], argv[2], argv[3],
1968                                   argv[4]);
1969         else if (argc > 3)
1970                 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
1971                                   argv[0], argv[1], argv[2], argv[3]);
1972         else if (argc > 2)
1973                 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
1974                                   argv[0], argv[1], argv[2]);
1975         else
1976                 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1977                                   argv[0], argv[1]);
1978         if (res < 0 || (size_t) res >= sizeof(cmd))
1979                 return -1;
1980         cmd[sizeof(cmd) - 1] = '\0';
1981         return wpa_ctrl_command(ctrl, cmd);
1985 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
1987         int arg = get_cmd_arg_num(str, pos);
1988         char **res = NULL;
1990         switch (arg) {
1991         case 1:
1992                 res = cli_txt_list_array(&p2p_peers);
1993                 break;
1994         }
1996         return res;
2000 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
2001                                   char *argv[])
2003         char cmd[128];
2004         int res;
2006         if (argc == 0)
2007                 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
2009         res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
2010         if (res < 0 || (size_t) res >= sizeof(cmd))
2011                 return -1;
2012         cmd[sizeof(cmd) - 1] = '\0';
2013         return wpa_ctrl_command(ctrl, cmd);
2017 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
2018                                         char *argv[])
2020         char cmd[128];
2021         int res;
2023         if (argc != 1) {
2024                 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
2025                        "(interface name)\n");
2026                 return -1;
2027         }
2029         res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
2030         if (res < 0 || (size_t) res >= sizeof(cmd))
2031                 return -1;
2032         cmd[sizeof(cmd) - 1] = '\0';
2033         return wpa_ctrl_command(ctrl, cmd);
2037 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
2039         int arg = get_cmd_arg_num(str, pos);
2040         char **res = NULL;
2042         switch (arg) {
2043         case 1:
2044                 res = cli_txt_list_array(&p2p_groups);
2045                 break;
2046         }
2048         return res;
2052 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
2053                                         char *argv[])
2055         char cmd[128];
2056         int res;
2058         if (argc == 0)
2059                 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
2061         if (argc > 1)
2062                 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s %s",
2063                                   argv[0], argv[1]);
2064         else
2065                 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s",
2066                                   argv[0]);
2067         if (res < 0 || (size_t) res >= sizeof(cmd))
2068                 return -1;
2069         cmd[sizeof(cmd) - 1] = '\0';
2070         return wpa_ctrl_command(ctrl, cmd);
2074 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
2075                                      char *argv[])
2077         char cmd[128];
2078         int res;
2080         if (argc != 2 && argc != 3) {
2081                 printf("Invalid P2P_PROV_DISC command: needs at least "
2082                        "two arguments, address and config method\n"
2083                        "(display, keypad, or pbc) and an optional join\n");
2084                 return -1;
2085         }
2087         if (argc == 3)
2088                 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s %s",
2089                                   argv[0], argv[1], argv[2]);
2090         else
2091                 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
2092                                   argv[0], argv[1]);
2093         if (res < 0 || (size_t) res >= sizeof(cmd))
2094                 return -1;
2095         cmd[sizeof(cmd) - 1] = '\0';
2096         return wpa_ctrl_command(ctrl, cmd);
2100 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
2101                                           char *argv[])
2103         return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
2107 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
2108                                          char *argv[])
2110         char cmd[4096];
2111         int res;
2113         if (argc != 2 && argc != 4) {
2114                 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2115                        "arguments (address and TLVs) or four arguments "
2116                        "(address, \"upnp\", version, search target "
2117                        "(SSDP ST:)\n");
2118                 return -1;
2119         }
2121         if (argc == 4)
2122                 res = os_snprintf(cmd, sizeof(cmd),
2123                                   "P2P_SERV_DISC_REQ %s %s %s %s",
2124                                   argv[0], argv[1], argv[2], argv[3]);
2125         else
2126                 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
2127                                   argv[0], argv[1]);
2128         if (res < 0 || (size_t) res >= sizeof(cmd))
2129                 return -1;
2130         cmd[sizeof(cmd) - 1] = '\0';
2131         return wpa_ctrl_command(ctrl, cmd);
2135 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
2136                                                 int argc, char *argv[])
2138         char cmd[128];
2139         int res;
2141         if (argc != 1) {
2142                 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
2143                        "argument (pending request identifier)\n");
2144                 return -1;
2145         }
2147         res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
2148                           argv[0]);
2149         if (res < 0 || (size_t) res >= sizeof(cmd))
2150                 return -1;
2151         cmd[sizeof(cmd) - 1] = '\0';
2152         return wpa_ctrl_command(ctrl, cmd);
2156 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
2157                                           char *argv[])
2159         char cmd[4096];
2160         int res;
2162         if (argc != 4) {
2163                 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2164                        "arguments (freq, address, dialog token, and TLVs)\n");
2165                 return -1;
2166         }
2168         res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
2169                           argv[0], argv[1], argv[2], argv[3]);
2170         if (res < 0 || (size_t) res >= sizeof(cmd))
2171                 return -1;
2172         cmd[sizeof(cmd) - 1] = '\0';
2173         return wpa_ctrl_command(ctrl, cmd);
2177 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
2178                                           char *argv[])
2180         return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
2184 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
2185                                               int argc, char *argv[])
2187         char cmd[128];
2188         int res;
2190         if (argc != 1) {
2191                 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
2192                        "argument (external processing: 0/1)\n");
2193                 return -1;
2194         }
2196         res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
2197                           argv[0]);
2198         if (res < 0 || (size_t) res >= sizeof(cmd))
2199                 return -1;
2200         cmd[sizeof(cmd) - 1] = '\0';
2201         return wpa_ctrl_command(ctrl, cmd);
2205 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
2206                                          char *argv[])
2208         return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
2212 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
2213                                        char *argv[])
2215         char cmd[4096];
2216         int res;
2218         if (argc != 3 && argc != 4) {
2219                 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
2220                        "arguments\n");
2221                 return -1;
2222         }
2224         if (argc == 4)
2225                 res = os_snprintf(cmd, sizeof(cmd),
2226                                   "P2P_SERVICE_ADD %s %s %s %s",
2227                                   argv[0], argv[1], argv[2], argv[3]);
2228         else
2229                 res = os_snprintf(cmd, sizeof(cmd),
2230                                   "P2P_SERVICE_ADD %s %s %s",
2231                                   argv[0], argv[1], argv[2]);
2232         if (res < 0 || (size_t) res >= sizeof(cmd))
2233                 return -1;
2234         cmd[sizeof(cmd) - 1] = '\0';
2235         return wpa_ctrl_command(ctrl, cmd);
2239 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2240                                        char *argv[])
2242         char cmd[4096];
2243         int res;
2245         if (argc != 2 && argc != 3) {
2246                 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2247                        "arguments\n");
2248                 return -1;
2249         }
2251         if (argc == 3)
2252                 res = os_snprintf(cmd, sizeof(cmd),
2253                                   "P2P_SERVICE_DEL %s %s %s",
2254                                   argv[0], argv[1], argv[2]);
2255         else
2256                 res = os_snprintf(cmd, sizeof(cmd),
2257                                   "P2P_SERVICE_DEL %s %s",
2258                                   argv[0], argv[1]);
2259         if (res < 0 || (size_t) res >= sizeof(cmd))
2260                 return -1;
2261         cmd[sizeof(cmd) - 1] = '\0';
2262         return wpa_ctrl_command(ctrl, cmd);
2266 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2267                                   int argc, char *argv[])
2269         char cmd[128];
2270         int res;
2272         if (argc != 1) {
2273                 printf("Invalid P2P_REJECT command: needs one argument "
2274                        "(peer address)\n");
2275                 return -1;
2276         }
2278         res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
2279         if (res < 0 || (size_t) res >= sizeof(cmd))
2280                 return -1;
2281         cmd[sizeof(cmd) - 1] = '\0';
2282         return wpa_ctrl_command(ctrl, cmd);
2286 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2287                                   int argc, char *argv[])
2289         char cmd[128];
2290         int res;
2292         if (argc < 1) {
2293                 printf("Invalid P2P_INVITE command: needs at least one "
2294                        "argument\n");
2295                 return -1;
2296         }
2298         if (argc > 2)
2299                 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
2300                                   argv[0], argv[1], argv[2]);
2301         else if (argc > 1)
2302                 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
2303                                   argv[0], argv[1]);
2304         else
2305                 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
2306         if (res < 0 || (size_t) res >= sizeof(cmd))
2307                 return -1;
2308         cmd[sizeof(cmd) - 1] = '\0';
2309         return wpa_ctrl_command(ctrl, cmd);
2313 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2315         char buf[64];
2316         if (argc != 1) {
2317                 printf("Invalid 'p2p_peer' command - exactly one argument, "
2318                        "P2P peer device address, is required.\n");
2319                 return -1;
2320         }
2321         os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
2322         return wpa_ctrl_command(ctrl, buf);
2326 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2328         int arg = get_cmd_arg_num(str, pos);
2329         char **res = NULL;
2331         switch (arg) {
2332         case 1:
2333                 res = cli_txt_list_array(&p2p_peers);
2334                 break;
2335         }
2337         return res;
2341 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2342                                      char *addr, size_t addr_len,
2343                                      int discovered)
2345         char buf[4096], *pos;
2346         size_t len;
2347         int ret;
2349         if (ctrl_conn == NULL)
2350                 return -1;
2351         len = sizeof(buf) - 1;
2352         ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
2353                                wpa_cli_msg_cb);
2354         if (ret == -2) {
2355                 printf("'%s' command timed out.\n", cmd);
2356                 return -2;
2357         } else if (ret < 0) {
2358                 printf("'%s' command failed.\n", cmd);
2359                 return -1;
2360         }
2362         buf[len] = '\0';
2363         if (memcmp(buf, "FAIL", 4) == 0)
2364                 return -1;
2366         pos = buf;
2367         while (*pos != '\0' && *pos != '\n')
2368                 pos++;
2369         *pos++ = '\0';
2370         os_strlcpy(addr, buf, addr_len);
2371         if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2372                 printf("%s\n", addr);
2373         return 0;
2377 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2379         char addr[32], cmd[64];
2380         int discovered;
2382         discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2384         if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2385                                       addr, sizeof(addr), discovered))
2386                 return -1;
2387         do {
2388                 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2389         } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2390                          discovered) == 0);
2392         return 0;
2396 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2398         char cmd[100];
2399         int res;
2401         if (argc != 2) {
2402                 printf("Invalid P2P_SET command: needs two arguments (field, "
2403                        "value)\n");
2404                 return -1;
2405         }
2407         res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2408         if (res < 0 || (size_t) res >= sizeof(cmd))
2409                 return -1;
2410         cmd[sizeof(cmd) - 1] = '\0';
2411         return wpa_ctrl_command(ctrl, cmd);
2415 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2417         return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2421 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2422                                   char *argv[])
2424         return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2428 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2429                                        char *argv[])
2431         char cmd[100];
2432         int res;
2434         if (argc != 1) {
2435                 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2436                        "(peer address)\n");
2437                 return -1;
2438         }
2440         res = os_snprintf(cmd, sizeof(cmd), "P2P_UNAUTHORIZE %s", argv[0]);
2442         if (res < 0 || (size_t) res >= sizeof(cmd))
2443                 return -1;
2445         cmd[sizeof(cmd) - 1] = '\0';
2446         return wpa_ctrl_command(ctrl, cmd);
2450 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2451                                         char *argv[])
2453         char cmd[100];
2454         int res;
2456         if (argc != 0 && argc != 2 && argc != 4) {
2457                 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2458                        "(preferred duration, interval; in microsecods).\n"
2459                        "Optional second pair can be used to provide "
2460                        "acceptable values.\n");
2461                 return -1;
2462         }
2464         if (argc == 4)
2465                 res = os_snprintf(cmd, sizeof(cmd),
2466                                   "P2P_PRESENCE_REQ %s %s %s %s",
2467                                   argv[0], argv[1], argv[2], argv[3]);
2468         else if (argc == 2)
2469                 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2470                                   argv[0], argv[1]);
2471         else
2472                 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2473         if (res < 0 || (size_t) res >= sizeof(cmd))
2474                 return -1;
2475         cmd[sizeof(cmd) - 1] = '\0';
2476         return wpa_ctrl_command(ctrl, cmd);
2480 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2481                                       char *argv[])
2483         char cmd[100];
2484         int res;
2486         if (argc != 0 && argc != 2) {
2487                 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2488                        "(availability period, availability interval; in "
2489                        "millisecods).\n"
2490                        "Extended Listen Timing can be cancelled with this "
2491                        "command when used without parameters.\n");
2492                 return -1;
2493         }
2495         if (argc == 2)
2496                 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2497                                   argv[0], argv[1]);
2498         else
2499                 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2500         if (res < 0 || (size_t) res >= sizeof(cmd))
2501                 return -1;
2502         cmd[sizeof(cmd) - 1] = '\0';
2503         return wpa_ctrl_command(ctrl, cmd);
2506 #endif /* CONFIG_P2P */
2509 #ifdef CONFIG_INTERWORKING
2510 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2511                                   char *argv[])
2513         return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2517 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2518                                        char *argv[])
2520         return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2524 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2525                                            char *argv[])
2527         char cmd[100];
2528         int res;
2530         if (argc == 0)
2531                 return wpa_ctrl_command(ctrl, "INTERWORKING_SELECT");
2533         res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_SELECT %s", argv[0]);
2534         if (res < 0 || (size_t) res >= sizeof(cmd))
2535                 return -1;
2536         cmd[sizeof(cmd) - 1] = '\0';
2537         return wpa_ctrl_command(ctrl, cmd);
2541 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2542                                             char *argv[])
2544         char cmd[100];
2545         int res;
2547         if (argc != 1) {
2548                 printf("Invalid INTERWORKING_CONNECT commands: needs one "
2549                        "argument (BSSID)\n");
2550                 return -1;
2551         }
2553         res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_CONNECT %s",
2554                           argv[0]);
2555         if (res < 0 || (size_t) res >= sizeof(cmd))
2556                 return -1;
2557         cmd[sizeof(cmd) - 1] = '\0';
2558         return wpa_ctrl_command(ctrl, cmd);
2562 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2564         char cmd[100];
2565         int res;
2567         if (argc != 2) {
2568                 printf("Invalid ANQP_GET command: needs two arguments "
2569                        "(addr and info id list)\n");
2570                 return -1;
2571         }
2573         res = os_snprintf(cmd, sizeof(cmd), "ANQP_GET %s %s",
2574                           argv[0], argv[1]);
2575         if (res < 0 || (size_t) res >= sizeof(cmd))
2576                 return -1;
2577         cmd[sizeof(cmd) - 1] = '\0';
2578         return wpa_ctrl_command(ctrl, cmd);
2580 #endif /* CONFIG_INTERWORKING */
2583 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2584                                        char *argv[])
2586         char cmd[256];
2587         int res;
2589         if (argc != 1) {
2590                 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2591                        "(0/1 = disable/enable automatic reconnection)\n");
2592                 return -1;
2593         }
2594         res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2595         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2596                 printf("Too long STA_AUTOCONNECT command.\n");
2597                 return -1;
2598         }
2599         return wpa_ctrl_command(ctrl, cmd);
2603 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2604                                      char *argv[])
2606         char cmd[256];
2607         int res;
2609         if (argc != 1) {
2610                 printf("Invalid TDLS_DISCOVER command: needs one argument "
2611                        "(Peer STA MAC address)\n");
2612                 return -1;
2613         }
2615         res = os_snprintf(cmd, sizeof(cmd), "TDLS_DISCOVER %s", argv[0]);
2616         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2617                 printf("Too long TDLS_DISCOVER command.\n");
2618                 return -1;
2619         }
2620         return wpa_ctrl_command(ctrl, cmd);
2624 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2625                                   char *argv[])
2627         char cmd[256];
2628         int res;
2630         if (argc != 1) {
2631                 printf("Invalid TDLS_SETUP command: needs one argument "
2632                        "(Peer STA MAC address)\n");
2633                 return -1;
2634         }
2636         res = os_snprintf(cmd, sizeof(cmd), "TDLS_SETUP %s", argv[0]);
2637         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2638                 printf("Too long TDLS_SETUP command.\n");
2639                 return -1;
2640         }
2641         return wpa_ctrl_command(ctrl, cmd);
2645 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2646                                      char *argv[])
2648         char cmd[256];
2649         int res;
2651         if (argc != 1) {
2652                 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2653                        "(Peer STA MAC address)\n");
2654                 return -1;
2655         }
2657         res = os_snprintf(cmd, sizeof(cmd), "TDLS_TEARDOWN %s", argv[0]);
2658         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2659                 printf("Too long TDLS_TEARDOWN command.\n");
2660                 return -1;
2661         }
2662         return wpa_ctrl_command(ctrl, cmd);
2666 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2667                                    char *argv[])
2669         return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2673 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2674                                       char *argv[])
2676         return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2680 enum wpa_cli_cmd_flags {
2681         cli_cmd_flag_none               = 0x00,
2682         cli_cmd_flag_sensitive          = 0x01
2683 };
2685 struct wpa_cli_cmd {
2686         const char *cmd;
2687         int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2688         enum wpa_cli_cmd_flags flags;
2689         const char *usage;
2690 };
2692 static struct wpa_cli_cmd wpa_cli_commands[] = {
2693         { "status", wpa_cli_cmd_status,
2694           cli_cmd_flag_none,
2695           "[verbose] = get current WPA/EAPOL/EAP status" },
2696         { "ping", wpa_cli_cmd_ping,
2697           cli_cmd_flag_none,
2698           "= pings wpa_supplicant" },
2699         { "relog", wpa_cli_cmd_relog,
2700           cli_cmd_flag_none,
2701           "= re-open log-file (allow rolling logs)" },
2702         { "note", wpa_cli_cmd_note,
2703           cli_cmd_flag_none,
2704           "<text> = add a note to wpa_supplicant debug log" },
2705         { "mib", wpa_cli_cmd_mib,
2706           cli_cmd_flag_none,
2707           "= get MIB variables (dot1x, dot11)" },
2708         { "help", wpa_cli_cmd_help,
2709           cli_cmd_flag_none,
2710           "= show this usage help" },
2711         { "interface", wpa_cli_cmd_interface,
2712           cli_cmd_flag_none,
2713           "[ifname] = show interfaces/select interface" },
2714         { "level", wpa_cli_cmd_level,
2715           cli_cmd_flag_none,
2716           "<debug level> = change debug level" },
2717         { "license", wpa_cli_cmd_license,
2718           cli_cmd_flag_none,
2719           "= show full wpa_cli license" },
2720         { "quit", wpa_cli_cmd_quit,
2721           cli_cmd_flag_none,
2722           "= exit wpa_cli" },
2723         { "set", wpa_cli_cmd_set,
2724           cli_cmd_flag_none,
2725           "= set variables (shows list of variables when run without "
2726           "arguments)" },
2727         { "get", wpa_cli_cmd_get,
2728           cli_cmd_flag_none,
2729           "<name> = get information" },
2730         { "logon", wpa_cli_cmd_logon,
2731           cli_cmd_flag_none,
2732           "= IEEE 802.1X EAPOL state machine logon" },
2733         { "logoff", wpa_cli_cmd_logoff,
2734           cli_cmd_flag_none,
2735           "= IEEE 802.1X EAPOL state machine logoff" },
2736         { "pmksa", wpa_cli_cmd_pmksa,
2737           cli_cmd_flag_none,
2738           "= show PMKSA cache" },
2739         { "reassociate", wpa_cli_cmd_reassociate,
2740           cli_cmd_flag_none,
2741           "= force reassociation" },
2742         { "preauthenticate", wpa_cli_cmd_preauthenticate,
2743           cli_cmd_flag_none,
2744           "<BSSID> = force preauthentication" },
2745         { "identity", wpa_cli_cmd_identity,
2746           cli_cmd_flag_none,
2747           "<network id> <identity> = configure identity for an SSID" },
2748         { "password", wpa_cli_cmd_password,
2749           cli_cmd_flag_sensitive,
2750           "<network id> <password> = configure password for an SSID" },
2751         { "new_password", wpa_cli_cmd_new_password,
2752           cli_cmd_flag_sensitive,
2753           "<network id> <password> = change password for an SSID" },
2754         { "pin", wpa_cli_cmd_pin,
2755           cli_cmd_flag_sensitive,
2756           "<network id> <pin> = configure pin for an SSID" },
2757         { "otp", wpa_cli_cmd_otp,
2758           cli_cmd_flag_sensitive,
2759           "<network id> <password> = configure one-time-password for an SSID"
2760         },
2761         { "passphrase", wpa_cli_cmd_passphrase,
2762           cli_cmd_flag_sensitive,
2763           "<network id> <passphrase> = configure private key passphrase\n"
2764           "  for an SSID" },
2765         { "bssid", wpa_cli_cmd_bssid,
2766           cli_cmd_flag_none,
2767           "<network id> <BSSID> = set preferred BSSID for an SSID" },
2768         { "blacklist", wpa_cli_cmd_blacklist,
2769           cli_cmd_flag_none,
2770           "<BSSID> = add a BSSID to the blacklist\n"
2771           "blacklist clear = clear the blacklist\n"
2772           "blacklist = display the blacklist" },
2773         { "log_level", wpa_cli_cmd_log_level,
2774           cli_cmd_flag_none,
2775           "<level> [<timestamp>] = update the log level/timestamp\n"
2776           "log_level = display the current log level and log options" },
2777         { "list_networks", wpa_cli_cmd_list_networks,
2778           cli_cmd_flag_none,
2779           "= list configured networks" },
2780         { "select_network", wpa_cli_cmd_select_network,
2781           cli_cmd_flag_none,
2782           "<network id> = select a network (disable others)" },
2783         { "enable_network", wpa_cli_cmd_enable_network,
2784           cli_cmd_flag_none,
2785           "<network id> = enable a network" },
2786         { "disable_network", wpa_cli_cmd_disable_network,
2787           cli_cmd_flag_none,
2788           "<network id> = disable a network" },
2789         { "add_network", wpa_cli_cmd_add_network,
2790           cli_cmd_flag_none,
2791           "= add a network" },
2792         { "remove_network", wpa_cli_cmd_remove_network,
2793           cli_cmd_flag_none,
2794           "<network id> = remove a network" },
2795         { "set_network", wpa_cli_cmd_set_network,
2796           cli_cmd_flag_sensitive,
2797           "<network id> <variable> <value> = set network variables (shows\n"
2798           "  list of variables when run without arguments)" },
2799         { "get_network", wpa_cli_cmd_get_network,
2800           cli_cmd_flag_none,
2801           "<network id> <variable> = get network variables" },
2802         { "save_config", wpa_cli_cmd_save_config,
2803           cli_cmd_flag_none,
2804           "= save the current configuration" },
2805         { "disconnect", wpa_cli_cmd_disconnect,
2806           cli_cmd_flag_none,
2807           "= disconnect and wait for reassociate/reconnect command before\n"
2808           "  connecting" },
2809         { "reconnect", wpa_cli_cmd_reconnect,
2810           cli_cmd_flag_none,
2811           "= like reassociate, but only takes effect if already disconnected"
2812         },
2813         { "scan", wpa_cli_cmd_scan,
2814           cli_cmd_flag_none,
2815           "= request new BSS scan" },
2816         { "scan_results", wpa_cli_cmd_scan_results,
2817           cli_cmd_flag_none,
2818           "= get latest scan results" },
2819         { "bss", wpa_cli_cmd_bss,
2820           cli_cmd_flag_none,
2821           "<<idx> | <bssid>> = get detailed scan result info" },
2822         { "get_capability", wpa_cli_cmd_get_capability,
2823           cli_cmd_flag_none,
2824           "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2825         { "reconfigure", wpa_cli_cmd_reconfigure,
2826           cli_cmd_flag_none,
2827           "= force wpa_supplicant to re-read its configuration file" },
2828         { "terminate", wpa_cli_cmd_terminate,
2829           cli_cmd_flag_none,
2830           "= terminate wpa_supplicant" },
2831         { "interface_add", wpa_cli_cmd_interface_add,
2832           cli_cmd_flag_none,
2833           "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2834           "  <bridge_name> = adds new interface, all parameters but <ifname>\n"
2835           "  are optional" },
2836         { "interface_remove", wpa_cli_cmd_interface_remove,
2837           cli_cmd_flag_none,
2838           "<ifname> = removes the interface" },
2839         { "interface_list", wpa_cli_cmd_interface_list,
2840           cli_cmd_flag_none,
2841           "= list available interfaces" },
2842         { "ap_scan", wpa_cli_cmd_ap_scan,
2843           cli_cmd_flag_none,
2844           "<value> = set ap_scan parameter" },
2845         { "scan_interval", wpa_cli_cmd_scan_interval,
2846           cli_cmd_flag_none,
2847           "<value> = set scan_interval parameter (in seconds)" },
2848         { "bss_expire_age", wpa_cli_cmd_bss_expire_age,
2849           cli_cmd_flag_none,
2850           "<value> = set BSS expiration age parameter" },
2851         { "bss_expire_count", wpa_cli_cmd_bss_expire_count,
2852           cli_cmd_flag_none,
2853           "<value> = set BSS expiration scan count parameter" },
2854         { "stkstart", wpa_cli_cmd_stkstart,
2855           cli_cmd_flag_none,
2856           "<addr> = request STK negotiation with <addr>" },
2857         { "ft_ds", wpa_cli_cmd_ft_ds,
2858           cli_cmd_flag_none,
2859           "<addr> = request over-the-DS FT with <addr>" },
2860         { "wps_pbc", wpa_cli_cmd_wps_pbc,
2861           cli_cmd_flag_none,
2862           "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2863         { "wps_pin", wpa_cli_cmd_wps_pin,
2864           cli_cmd_flag_sensitive,
2865           "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2866           "hardcoded)" },
2867         { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
2868           cli_cmd_flag_sensitive,
2869           "<PIN> = verify PIN checksum" },
2870         { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
2871           "Cancels the pending WPS operation" },
2872 #ifdef CONFIG_WPS_OOB
2873         { "wps_oob", wpa_cli_cmd_wps_oob,
2874           cli_cmd_flag_sensitive,
2875           "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2876 #endif /* CONFIG_WPS_OOB */
2877         { "wps_reg", wpa_cli_cmd_wps_reg,
2878           cli_cmd_flag_sensitive,
2879           "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2880         { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin,
2881           cli_cmd_flag_sensitive,
2882           "[params..] = enable/disable AP PIN" },
2883         { "wps_er_start", wpa_cli_cmd_wps_er_start,
2884           cli_cmd_flag_none,
2885           "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2886         { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2887           cli_cmd_flag_none,
2888           "= stop Wi-Fi Protected Setup External Registrar" },
2889         { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2890           cli_cmd_flag_sensitive,
2891           "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2892         { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2893           cli_cmd_flag_none,
2894           "<UUID> = accept an Enrollee PBC using External Registrar" },
2895         { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2896           cli_cmd_flag_sensitive,
2897           "<UUID> <PIN> = learn AP configuration" },
2898         { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
2899           cli_cmd_flag_none,
2900           "<UUID> <network id> = set AP configuration for enrolling" },
2901         { "wps_er_config", wpa_cli_cmd_wps_er_config,
2902           cli_cmd_flag_sensitive,
2903           "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2904         { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2905           cli_cmd_flag_none,
2906           "<addr> = request RSN authentication with <addr> in IBSS" },
2907 #ifdef CONFIG_AP
2908         { "sta", wpa_cli_cmd_sta,
2909           cli_cmd_flag_none,
2910           "<addr> = get information about an associated station (AP)" },
2911         { "all_sta", wpa_cli_cmd_all_sta,
2912           cli_cmd_flag_none,
2913           "= get information about all associated stations (AP)" },
2914 #endif /* CONFIG_AP */
2915         { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2916           "= notification of suspend/hibernate" },
2917         { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2918           "= notification of resume/thaw" },
2919         { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2920           "= drop SA without deauth/disassoc (test command)" },
2921         { "roam", wpa_cli_cmd_roam,
2922           cli_cmd_flag_none,
2923           "<addr> = roam to the specified BSS" },
2924 #ifdef CONFIG_P2P
2925         { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2926           "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2927         { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2928           "= stop P2P Devices search" },
2929         { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2930           "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2931         { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2932           "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2933         { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2934           "<ifname> = remove P2P group interface (terminate group if GO)" },
2935         { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2936           "= add a new P2P group (local end as GO)" },
2937         { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2938           "<addr> <method> = request provisioning discovery" },
2939         { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2940           cli_cmd_flag_none,
2941           "= get the passphrase for a group (GO only)" },
2942         { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2943           cli_cmd_flag_none,
2944           "<addr> <TLVs> = schedule service discovery request" },
2945         { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2946           cli_cmd_flag_none,
2947           "<id> = cancel pending service discovery request" },
2948         { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2949           cli_cmd_flag_none,
2950           "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2951         { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2952           cli_cmd_flag_none,
2953           "= indicate change in local services" },
2954         { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2955           cli_cmd_flag_none,
2956           "<external> = set external processing of service discovery" },
2957         { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2958           cli_cmd_flag_none,
2959           "= remove all stored service entries" },
2960         { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2961           cli_cmd_flag_none,
2962           "<bonjour|upnp> <query|version> <response|service> = add a local "
2963           "service" },
2964         { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2965           cli_cmd_flag_none,
2966           "<bonjour|upnp> <query|version> [|service] = remove a local "
2967           "service" },
2968         { "p2p_reject", wpa_cli_cmd_p2p_reject,
2969           cli_cmd_flag_none,
2970           "<addr> = reject connection attempts from a specific peer" },
2971         { "p2p_invite", wpa_cli_cmd_p2p_invite,
2972           cli_cmd_flag_none,
2973           "<cmd> [peer=addr] = invite peer" },
2974         { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2975           "[discovered] = list known (optionally, only fully discovered) P2P "
2976           "peers" },
2977         { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2978           "<address> = show information about known P2P peer" },
2979         { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
2980           "<field> <value> = set a P2P parameter" },
2981         { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
2982           "= flush P2P state" },
2983         { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
2984           "= cancel P2P group formation" },
2985         { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none,
2986           "<address> = unauthorize a peer" },
2987         { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
2988           "[<duration> <interval>] [<duration> <interval>] = request GO "
2989           "presence" },
2990         { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
2991           "[<period> <interval>] = set extended listen timing" },
2992 #endif /* CONFIG_P2P */
2994 #ifdef CONFIG_INTERWORKING
2995         { "fetch_anqp", wpa_cli_cmd_fetch_anqp, cli_cmd_flag_none,
2996           "= fetch ANQP information for all APs" },
2997         { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, cli_cmd_flag_none,
2998           "= stop fetch_anqp operation" },
2999         { "interworking_select", wpa_cli_cmd_interworking_select,
3000           cli_cmd_flag_none,
3001           "[auto] = perform Interworking network selection" },
3002         { "interworking_connect", wpa_cli_cmd_interworking_connect,
3003           cli_cmd_flag_none,
3004           "<BSSID> = connect using Interworking credentials" },
3005         { "anqp_get", wpa_cli_cmd_anqp_get, cli_cmd_flag_none,
3006           "<addr> <info id>[,<info id>]... = request ANQP information" },
3007 #endif /* CONFIG_INTERWORKING */
3008         { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
3009           "<0/1> = disable/enable automatic reconnection" },
3010         { "tdls_discover", wpa_cli_cmd_tdls_discover,
3011           cli_cmd_flag_none,
3012           "<addr> = request TDLS discovery with <addr>" },
3013         { "tdls_setup", wpa_cli_cmd_tdls_setup,
3014           cli_cmd_flag_none,
3015           "<addr> = request TDLS setup with <addr>" },
3016         { "tdls_teardown", wpa_cli_cmd_tdls_teardown,
3017           cli_cmd_flag_none,
3018           "<addr> = tear down TDLS with <addr>" },
3019         { "signal_poll", wpa_cli_cmd_signal_poll,
3020           cli_cmd_flag_none,
3021           "= get signal parameters" },
3022         { "reauthenticate", wpa_cli_cmd_reauthenticate, cli_cmd_flag_none,
3023           "= trigger IEEE 802.1X/EAPOL reauthentication" },
3024         { NULL, NULL, cli_cmd_flag_none, NULL }
3025 };
3028 /*
3029  * Prints command usage, lines are padded with the specified string.
3030  */
3031 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
3033         char c;
3034         size_t n;
3036         printf("%s%s ", pad, cmd->cmd);
3037         for (n = 0; (c = cmd->usage[n]); n++) {
3038                 printf("%c", c);
3039                 if (c == '\n')
3040                         printf("%s", pad);
3041         }
3042         printf("\n");
3046 static void print_help(void)
3048         int n;
3049         printf("commands:\n");
3050         for (n = 0; wpa_cli_commands[n].cmd; n++)
3051                 print_cmd_help(&wpa_cli_commands[n], "  ");
3055 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
3057         const char *c, *delim;
3058         int n;
3059         size_t len;
3061         delim = os_strchr(cmd, ' ');
3062         if (delim)
3063                 len = delim - cmd;
3064         else
3065                 len = os_strlen(cmd);
3067         for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
3068                 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
3069                         return (wpa_cli_commands[n].flags &
3070                                 cli_cmd_flag_sensitive);
3071         }
3072         return 0;
3076 static char ** wpa_list_cmd_list(void)
3078         char **res;
3079         int i, count;
3081         count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
3082         res = os_zalloc(count * sizeof(char *));
3083         if (res == NULL)
3084                 return NULL;
3086         for (i = 0; wpa_cli_commands[i].cmd; i++) {
3087                 res[i] = os_strdup(wpa_cli_commands[i].cmd);
3088                 if (res[i] == NULL)
3089                         break;
3090         }
3092         return res;
3096 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
3097                                       int pos)
3099         int i;
3101         if (os_strcasecmp(cmd, "bss") == 0)
3102                 return wpa_cli_complete_bss(str, pos);
3103 #ifdef CONFIG_P2P
3104         if (os_strcasecmp(cmd, "p2p_connect") == 0)
3105                 return wpa_cli_complete_p2p_connect(str, pos);
3106         if (os_strcasecmp(cmd, "p2p_peer") == 0)
3107                 return wpa_cli_complete_p2p_peer(str, pos);
3108         if (os_strcasecmp(cmd, "p2p_group_remove") == 0)
3109                 return wpa_cli_complete_p2p_group_remove(str, pos);
3110 #endif /* CONFIG_P2P */
3112         for (i = 0; wpa_cli_commands[i].cmd; i++) {
3113                 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
3114                         edit_clear_line();
3115                         printf("\r%s\n", wpa_cli_commands[i].usage);
3116                         edit_redraw();
3117                         break;
3118                 }
3119         }
3121         return NULL;
3125 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
3127         char **res;
3128         const char *end;
3129         char *cmd;
3131         end = os_strchr(str, ' ');
3132         if (end == NULL || str + pos < end)
3133                 return wpa_list_cmd_list();
3135         cmd = os_malloc(pos + 1);
3136         if (cmd == NULL)
3137                 return NULL;
3138         os_memcpy(cmd, str, pos);
3139         cmd[end - str] = '\0';
3140         res = wpa_cli_cmd_completion(cmd, str, pos);
3141         os_free(cmd);
3142         return res;
3146 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3148         struct wpa_cli_cmd *cmd, *match = NULL;
3149         int count;
3150         int ret = 0;
3152         count = 0;
3153         cmd = wpa_cli_commands;
3154         while (cmd->cmd) {
3155                 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3156                 {
3157                         match = cmd;
3158                         if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3159                                 /* we have an exact match */
3160                                 count = 1;
3161                                 break;
3162                         }
3163                         count++;
3164                 }
3165                 cmd++;
3166         }
3168         if (count > 1) {
3169                 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3170                 cmd = wpa_cli_commands;
3171                 while (cmd->cmd) {
3172                         if (os_strncasecmp(cmd->cmd, argv[0],
3173                                            os_strlen(argv[0])) == 0) {
3174                                 printf(" %s", cmd->cmd);
3175                         }
3176                         cmd++;
3177                 }
3178                 printf("\n");
3179                 ret = 1;
3180         } else if (count == 0) {
3181                 printf("Unknown command '%s'\n", argv[0]);
3182                 ret = 1;
3183         } else {
3184                 ret = match->handler(ctrl, argc - 1, &argv[1]);
3185         }
3187         return ret;
3191 static int str_match(const char *a, const char *b)
3193         return os_strncmp(a, b, os_strlen(b)) == 0;
3197 static int wpa_cli_exec(const char *program, const char *arg1,
3198                         const char *arg2)
3200         char *cmd;
3201         size_t len;
3202         int res;
3203         int ret = 0;
3205         len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
3206         cmd = os_malloc(len);
3207         if (cmd == NULL)
3208                 return -1;
3209         res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
3210         if (res < 0 || (size_t) res >= len) {
3211                 os_free(cmd);
3212                 return -1;
3213         }
3214         cmd[len - 1] = '\0';
3215 #ifndef _WIN32_WCE
3216         if (system(cmd) < 0)
3217                 ret = -1;
3218 #endif /* _WIN32_WCE */
3219         os_free(cmd);
3221         return ret;
3225 static void wpa_cli_action_process(const char *msg)
3227         const char *pos;
3228         char *copy = NULL, *id, *pos2;
3230         pos = msg;
3231         if (*pos == '<') {
3232                 /* skip priority */
3233                 pos = os_strchr(pos, '>');
3234                 if (pos)
3235                         pos++;
3236                 else
3237                         pos = msg;
3238         }
3240         if (str_match(pos, WPA_EVENT_CONNECTED)) {
3241                 int new_id = -1;
3242                 os_unsetenv("WPA_ID");
3243                 os_unsetenv("WPA_ID_STR");
3244                 os_unsetenv("WPA_CTRL_DIR");
3246                 pos = os_strstr(pos, "[id=");
3247                 if (pos)
3248                         copy = os_strdup(pos + 4);
3250                 if (copy) {
3251                         pos2 = id = copy;
3252                         while (*pos2 && *pos2 != ' ')
3253                                 pos2++;
3254                         *pos2++ = '\0';
3255                         new_id = atoi(id);
3256                         os_setenv("WPA_ID", id, 1);
3257                         while (*pos2 && *pos2 != '=')
3258                                 pos2++;
3259                         if (*pos2 == '=')
3260                                 pos2++;
3261                         id = pos2;
3262                         while (*pos2 && *pos2 != ']')
3263                                 pos2++;
3264                         *pos2 = '\0';
3265                         os_setenv("WPA_ID_STR", id, 1);
3266                         os_free(copy);
3267                 }
3269                 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3271                 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
3272                         wpa_cli_connected = 1;
3273                         wpa_cli_last_id = new_id;
3274                         wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
3275                 }
3276         } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3277                 if (wpa_cli_connected) {
3278                         wpa_cli_connected = 0;
3279                         wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
3280                 }
3281         } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3282                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3283         } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3284                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3285         } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3286                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3287         } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3288                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3289         } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3290                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3291         } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3292                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3293         } else if (str_match(pos, WPS_EVENT_FAIL)) {
3294                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3295         } else if (str_match(pos, AP_STA_CONNECTED)) {
3296                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3297         } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3298                 wpa_cli_exec(action_file, ctrl_ifname, pos);
3299         } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3300                 printf("wpa_supplicant is terminating - stop monitoring\n");
3301                 wpa_cli_quit = 1;
3302         }
3306 #ifndef CONFIG_ANSI_C_EXTRA
3307 static void wpa_cli_action_cb(char *msg, size_t len)
3309         wpa_cli_action_process(msg);
3311 #endif /* CONFIG_ANSI_C_EXTRA */
3314 static void wpa_cli_reconnect(void)
3316         wpa_cli_close_connection();
3317         wpa_cli_open_connection(ctrl_ifname, 1);
3321 static void cli_event(const char *str)
3323         const char *start, *s;
3325         start = os_strchr(str, '>');
3326         if (start == NULL)
3327                 return;
3329         start++;
3331         if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3332                 s = os_strchr(start, ' ');
3333                 if (s == NULL)
3334                         return;
3335                 s = os_strchr(s + 1, ' ');
3336                 if (s == NULL)
3337                         return;
3338                 cli_txt_list_add(&bsses, s + 1);
3339                 return;
3340         }
3342         if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3343                 s = os_strchr(start, ' ');
3344                 if (s == NULL)
3345                         return;
3346                 s = os_strchr(s + 1, ' ');
3347                 if (s == NULL)
3348                         return;
3349                 cli_txt_list_del_addr(&bsses, s + 1);
3350                 return;
3351         }
3353 #ifdef CONFIG_P2P
3354         if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3355                 s = os_strstr(start, " p2p_dev_addr=");
3356                 if (s == NULL)
3357                         return;
3358                 cli_txt_list_add_addr(&p2p_peers, s + 14);
3359                 return;
3360         }
3362         if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3363                 s = os_strstr(start, " p2p_dev_addr=");
3364                 if (s == NULL)
3365                         return;
3366                 cli_txt_list_del_addr(&p2p_peers, s + 14);
3367                 return;
3368         }
3370         if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3371                 s = os_strchr(start, ' ');
3372                 if (s == NULL)
3373                         return;
3374                 cli_txt_list_add_word(&p2p_groups, s + 1);
3375                 return;
3376         }
3378         if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3379                 s = os_strchr(start, ' ');
3380                 if (s == NULL)
3381                         return;
3382                 cli_txt_list_del_word(&p2p_groups, s + 1);
3383                 return;
3384         }
3385 #endif /* CONFIG_P2P */
3389 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3391         if (ctrl_conn == NULL) {
3392                 wpa_cli_reconnect();
3393                 return;
3394         }
3395         while (wpa_ctrl_pending(ctrl) > 0) {
3396                 char buf[256];
3397                 size_t len = sizeof(buf) - 1;
3398                 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3399                         buf[len] = '\0';
3400                         if (action_monitor)
3401                                 wpa_cli_action_process(buf);
3402                         else {
3403                                 cli_event(buf);
3404                                 if (wpa_cli_show_event(buf)) {
3405                                         edit_clear_line();
3406                                         printf("\r%s\n", buf);
3407                                         edit_redraw();
3408                                 }
3409                         }
3410                 } else {
3411                         printf("Could not read pending message.\n");
3412                         break;
3413                 }
3414         }
3416         if (wpa_ctrl_pending(ctrl) < 0) {
3417                 printf("Connection to wpa_supplicant lost - trying to "
3418                        "reconnect\n");
3419                 wpa_cli_reconnect();
3420         }
3423 #define max_args 10
3425 static int tokenize_cmd(char *cmd, char *argv[])
3427         char *pos;
3428         int argc = 0;
3430         pos = cmd;
3431         for (;;) {
3432                 while (*pos == ' ')
3433                         pos++;
3434                 if (*pos == '\0')
3435                         break;
3436                 argv[argc] = pos;
3437                 argc++;
3438                 if (argc == max_args)
3439                         break;
3440                 if (*pos == '"') {
3441                         char *pos2 = os_strrchr(pos, '"');
3442                         if (pos2)
3443                                 pos = pos2 + 1;
3444                 }
3445                 while (*pos != '\0' && *pos != ' ')
3446                         pos++;
3447                 if (*pos == ' ')
3448                         *pos++ = '\0';
3449         }
3451         return argc;
3455 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3457         if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3458                 printf("Connection to wpa_supplicant lost - trying to "
3459                        "reconnect\n");
3460                 wpa_cli_close_connection();
3461         }
3462         if (!ctrl_conn)
3463                 wpa_cli_reconnect();
3464         eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3468 static void wpa_cli_eloop_terminate(int sig, void *signal_ctx)
3470         eloop_terminate();
3474 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3476         wpa_cli_recv_pending(mon_conn, 0);
3480 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3482         char *argv[max_args];
3483         int argc;
3484         argc = tokenize_cmd(cmd, argv);
3485         if (argc)
3486                 wpa_request(ctrl_conn, argc, argv);
3490 static void wpa_cli_edit_eof_cb(void *ctx)
3492         eloop_terminate();
3496 static void wpa_cli_interactive(void)
3498         char *home, *hfile = NULL;
3500         printf("\nInteractive mode\n\n");
3502         home = getenv("HOME");
3503         if (home) {
3504                 const char *fname = ".wpa_cli_history";
3505                 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3506                 hfile = os_malloc(hfile_len);
3507                 if (hfile)
3508                         os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3509         }
3511         eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
3512         edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3513                   wpa_cli_edit_completion_cb, NULL, hfile);
3514         eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3516         eloop_run();
3518         cli_txt_list_flush(&p2p_peers);
3519         cli_txt_list_flush(&p2p_groups);
3520         cli_txt_list_flush(&bsses);
3521         edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3522         os_free(hfile);
3523         eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3524         wpa_cli_close_connection();
3528 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3530 #ifdef CONFIG_ANSI_C_EXTRA
3531         /* TODO: ANSI C version(?) */
3532         printf("Action processing not supported in ANSI C build.\n");
3533 #else /* CONFIG_ANSI_C_EXTRA */
3534         fd_set rfds;
3535         int fd, res;
3536         struct timeval tv;
3537         char buf[256]; /* note: large enough to fit in unsolicited messages */
3538         size_t len;
3540         fd = wpa_ctrl_get_fd(ctrl);
3542         while (!wpa_cli_quit) {
3543                 FD_ZERO(&rfds);
3544                 FD_SET(fd, &rfds);
3545                 tv.tv_sec = ping_interval;
3546                 tv.tv_usec = 0;
3547                 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3548                 if (res < 0 && errno != EINTR) {
3549                         perror("select");
3550                         break;
3551                 }
3553                 if (FD_ISSET(fd, &rfds))
3554                         wpa_cli_recv_pending(ctrl, 1);
3555                 else {
3556                         /* verify that connection is still working */
3557                         len = sizeof(buf) - 1;
3558                         if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3559                                              wpa_cli_action_cb) < 0 ||
3560                             len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3561                                 printf("wpa_supplicant did not reply to PING "
3562                                        "command - exiting\n");
3563                                 break;
3564                         }
3565                 }
3566         }
3567 #endif /* CONFIG_ANSI_C_EXTRA */
3571 static void wpa_cli_cleanup(void)
3573         wpa_cli_close_connection();
3574         if (pid_file)
3575                 os_daemonize_terminate(pid_file);
3577         os_program_deinit();
3580 static void wpa_cli_terminate(int sig)
3582         wpa_cli_cleanup();
3583         exit(0);
3587 static char * wpa_cli_get_default_ifname(void)
3589         char *ifname = NULL;
3591 #ifdef CONFIG_CTRL_IFACE_UNIX
3592         struct dirent *dent;
3593         DIR *dir = opendir(ctrl_iface_dir);
3594         if (!dir) {
3595 #ifdef ANDROID
3596                 char ifprop[PROPERTY_VALUE_MAX];
3597                 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3598                         ifname = os_strdup(ifprop);
3599                         printf("Using interface '%s'\n", ifname);
3600                         return ifname;
3601                 }
3602 #endif /* ANDROID */
3603                 return NULL;
3604         }
3605         while ((dent = readdir(dir))) {
3606 #ifdef _DIRENT_HAVE_D_TYPE
3607                 /*
3608                  * Skip the file if it is not a socket. Also accept
3609                  * DT_UNKNOWN (0) in case the C library or underlying
3610                  * file system does not support d_type.
3611                  */
3612                 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3613                         continue;
3614 #endif /* _DIRENT_HAVE_D_TYPE */
3615                 if (os_strcmp(dent->d_name, ".") == 0 ||
3616                     os_strcmp(dent->d_name, "..") == 0)
3617                         continue;
3618                 printf("Selected interface '%s'\n", dent->d_name);
3619                 ifname = os_strdup(dent->d_name);
3620                 break;
3621         }
3622         closedir(dir);
3623 #endif /* CONFIG_CTRL_IFACE_UNIX */
3625 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3626         char buf[2048], *pos;
3627         size_t len;
3628         struct wpa_ctrl *ctrl;
3629         int ret;
3631         ctrl = wpa_ctrl_open(NULL);
3632         if (ctrl == NULL)
3633                 return NULL;
3635         len = sizeof(buf) - 1;
3636         ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3637         if (ret >= 0) {
3638                 buf[len] = '\0';
3639                 pos = os_strchr(buf, '\n');
3640                 if (pos)
3641                         *pos = '\0';
3642                 ifname = os_strdup(buf);
3643         }
3644         wpa_ctrl_close(ctrl);
3645 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3647         return ifname;
3651 int main(int argc, char *argv[])
3653         int warning_displayed = 0;
3654         int c;
3655         int daemonize = 0;
3656         int ret = 0;
3657         const char *global = NULL;
3659         if (os_program_init())
3660                 return -1;
3662         for (;;) {
3663                 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3664                 if (c < 0)
3665                         break;
3666                 switch (c) {
3667                 case 'a':
3668                         action_file = optarg;
3669                         break;
3670                 case 'B':
3671                         daemonize = 1;
3672                         break;
3673                 case 'g':
3674                         global = optarg;
3675                         break;
3676                 case 'G':
3677                         ping_interval = atoi(optarg);
3678                         break;
3679                 case 'h':
3680                         usage();
3681                         return 0;
3682                 case 'v':
3683                         printf("%s\n", wpa_cli_version);
3684                         return 0;
3685                 case 'i':
3686                         os_free(ctrl_ifname);
3687                         ctrl_ifname = os_strdup(optarg);
3688                         break;
3689                 case 'p':
3690                         ctrl_iface_dir = optarg;
3691                         break;
3692                 case 'P':
3693                         pid_file = optarg;
3694                         break;
3695                 default:
3696                         usage();
3697                         return -1;
3698                 }
3699         }
3701         interactive = (argc == optind) && (action_file == NULL);
3703         if (interactive)
3704                 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3706         if (eloop_init())
3707                 return -1;
3709         if (global) {
3710 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3711                 ctrl_conn = wpa_ctrl_open(NULL);
3712 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3713                 ctrl_conn = wpa_ctrl_open(global);
3714 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3715                 if (ctrl_conn == NULL) {
3716                         perror("Failed to connect to wpa_supplicant - "
3717                                "wpa_ctrl_open");
3718                         return -1;
3719                 }
3720         }
3722 #ifndef _WIN32_WCE
3723         signal(SIGINT, wpa_cli_terminate);
3724         signal(SIGTERM, wpa_cli_terminate);
3725 #endif /* _WIN32_WCE */
3727         if (ctrl_ifname == NULL)
3728                 ctrl_ifname = wpa_cli_get_default_ifname();
3730         if (interactive) {
3731                 for (; !global;) {
3732                         if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3733                                 if (warning_displayed)
3734                                         printf("Connection established.\n");
3735                                 break;
3736                         }
3738                         if (!warning_displayed) {
3739                                 printf("Could not connect to wpa_supplicant - "
3740                                        "re-trying\n");
3741                                 warning_displayed = 1;
3742                         }
3743                         os_sleep(1, 0);
3744                         continue;
3745                 }
3746         } else {
3747                 if (!global &&
3748                     wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3749                         perror("Failed to connect to wpa_supplicant - "
3750                                "wpa_ctrl_open");
3751                         return -1;
3752                 }
3754                 if (action_file) {
3755                         if (wpa_ctrl_attach(ctrl_conn) == 0) {
3756                                 wpa_cli_attached = 1;
3757                         } else {
3758                                 printf("Warning: Failed to attach to "
3759                                        "wpa_supplicant.\n");
3760                                 return -1;
3761                         }
3762                 }
3763         }
3765         if (daemonize && os_daemonize(pid_file))
3766                 return -1;
3768         if (interactive)
3769                 wpa_cli_interactive();
3770         else if (action_file)
3771                 wpa_cli_action(ctrl_conn);
3772         else
3773                 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3775         os_free(ctrl_ifname);
3776         eloop_destroy();
3777         wpa_cli_cleanup();
3779         return ret;
3782 #else /* CONFIG_CTRL_IFACE */
3783 int main(int argc, char *argv[])
3785         printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3786         return -1;
3788 #endif /* CONFIG_CTRL_IFACE */