Select the BSD license terms as the only license alternative
[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-2012, Jouni Malinen <j@w1.fi> and contributors";
39 static const char *wpa_cli_license =
40 "This software may be distributed under the terms of the BSD license.\n"
41 "See README for more details.\n";
43 static const char *wpa_cli_full_license =
44 "This software may be distributed under the terms of the BSD license.\n"
45 "\n"
46 "Redistribution and use in source and binary forms, with or without\n"
47 "modification, are permitted provided that the following conditions are\n"
48 "met:\n"
49 "\n"
50 "1. Redistributions of source code must retain the above copyright\n"
51 "   notice, this list of conditions and the following disclaimer.\n"
52 "\n"
53 "2. Redistributions in binary form must reproduce the above copyright\n"
54 "   notice, this list of conditions and the following disclaimer in the\n"
55 "   documentation and/or other materials provided with the distribution.\n"
56 "\n"
57 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
58 "   names of its contributors may be used to endorse or promote products\n"
59 "   derived from this software without specific prior written permission.\n"
60 "\n"
61 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
62 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
63 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
64 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
65 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
66 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
67 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
68 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
69 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
70 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
71 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
72 "\n";
74 static struct wpa_ctrl *ctrl_conn;
75 static struct wpa_ctrl *mon_conn;
76 static int wpa_cli_quit = 0;
77 static int wpa_cli_attached = 0;
78 static int wpa_cli_connected = 0;
79 static int wpa_cli_last_id = 0;
80 #ifndef CONFIG_CTRL_IFACE_DIR
81 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
82 #endif /* CONFIG_CTRL_IFACE_DIR */
83 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
84 static char *ctrl_ifname = NULL;
85 static const char *pid_file = NULL;
86 static const char *action_file = NULL;
87 static int ping_interval = 5;
88 static int interactive = 0;
90 struct cli_txt_entry {
91         struct dl_list list;
92         char *txt;
93 };
95 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
96 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
97 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
100 static void print_help(void);
101 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
104 static void usage(void)
106         printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
107                "[-a<action file>] \\\n"
108                "        [-P<pid file>] [-g<global ctrl>] [-G<ping interval>]  "
109                "[command..]\n"
110                "  -h = help (show this usage text)\n"
111                "  -v = shown version information\n"
112                "  -a = run in daemon mode executing the action file based on "
113                "events from\n"
114                "       wpa_supplicant\n"
115                "  -B = run a daemon in the background\n"
116                "  default path: " CONFIG_CTRL_IFACE_DIR "\n"
117                "  default interface: first interface found in socket path\n");
118         print_help();
122 static void cli_txt_list_free(struct cli_txt_entry *e)
124         dl_list_del(&e->list);
125         os_free(e->txt);
126         os_free(e);
130 static void cli_txt_list_flush(struct dl_list *list)
132         struct cli_txt_entry *e;
133         while ((e = dl_list_first(list, struct cli_txt_entry, list)))
134                 cli_txt_list_free(e);
138 static struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list,
139                                                const char *txt)
141         struct cli_txt_entry *e;
142         dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
143                 if (os_strcmp(e->txt, txt) == 0)
144                         return e;
145         }
146         return NULL;
150 static void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
152         struct cli_txt_entry *e;
153         e = cli_txt_list_get(txt_list, txt);
154         if (e)
155                 cli_txt_list_free(e);
159 static void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt)
161         u8 addr[ETH_ALEN];
162         char buf[18];
163         if (hwaddr_aton(txt, addr) < 0)
164                 return;
165         os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
166         cli_txt_list_del(txt_list, buf);
170 #ifdef CONFIG_P2P
171 static void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt)
173         const char *end;
174         char *buf;
175         end = os_strchr(txt, ' ');
176         if (end == NULL)
177                 end = txt + os_strlen(txt);
178         buf = os_malloc(end - txt + 1);
179         if (buf == NULL)
180                 return;
181         os_memcpy(buf, txt, end - txt);
182         buf[end - txt] = '\0';
183         cli_txt_list_del(txt_list, buf);
184         os_free(buf);
186 #endif /* CONFIG_P2P */
189 static int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
191         struct cli_txt_entry *e;
192         e = cli_txt_list_get(txt_list, txt);
193         if (e)
194                 return 0;
195         e = os_zalloc(sizeof(*e));
196         if (e == NULL)
197                 return -1;
198         e->txt = os_strdup(txt);
199         if (e->txt == NULL) {
200                 os_free(e);
201                 return -1;
202         }
203         dl_list_add(txt_list, &e->list);
204         return 0;
208 #ifdef CONFIG_P2P
209 static int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
211         u8 addr[ETH_ALEN];
212         char buf[18];
213         if (hwaddr_aton(txt, addr) < 0)
214                 return -1;
215         os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
216         return cli_txt_list_add(txt_list, buf);
220 static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt)
222         const char *end;
223         char *buf;
224         int ret;
225         end = os_strchr(txt, ' ');
226         if (end == NULL)
227                 end = txt + os_strlen(txt);
228         buf = os_malloc(end - txt + 1);
229         if (buf == NULL)
230                 return -1;
231         os_memcpy(buf, txt, end - txt);
232         buf[end - txt] = '\0';
233         ret = cli_txt_list_add(txt_list, buf);
234         os_free(buf);
235         return ret;
237 #endif /* CONFIG_P2P */
240 static char ** cli_txt_list_array(struct dl_list *txt_list)
242         unsigned int i, count = dl_list_len(txt_list);
243         char **res;
244         struct cli_txt_entry *e;
246         res = os_zalloc((count + 1) * sizeof(char *));
247         if (res == NULL)
248                 return NULL;
250         i = 0;
251         dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
252                 res[i] = os_strdup(e->txt);
253                 if (res[i] == NULL)
254                         break;
255                 i++;
256         }
258         return res;
262 static int get_cmd_arg_num(const char *str, int pos)
264         int arg = 0, i;
266         for (i = 0; i <= pos; i++) {
267                 if (str[i] != ' ') {
268                         arg++;
269                         while (i <= pos && str[i] != ' ')
270                                 i++;
271                 }
272         }
274         if (arg > 0)
275                 arg--;
276         return arg;
280 static int str_starts(const char *src, const char *match)
282         return os_strncmp(src, match, os_strlen(match)) == 0;
286 static int wpa_cli_show_event(const char *event)
288         const char *start;
290         start = os_strchr(event, '>');
291         if (start == NULL)
292                 return 1;
294         start++;
295         /*
296          * Skip BSS added/removed events since they can be relatively frequent
297          * and are likely of not much use for an interactive user.
298          */
299         if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
300             str_starts(start, WPA_EVENT_BSS_REMOVED))
301                 return 0;
303         return 1;
307 static int wpa_cli_open_connection(const char *ifname, int attach)
309 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
310         ctrl_conn = wpa_ctrl_open(ifname);
311         if (ctrl_conn == NULL)
312                 return -1;
314         if (attach && interactive)
315                 mon_conn = wpa_ctrl_open(ifname);
316         else
317                 mon_conn = NULL;
318 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
319         char *cfile = NULL;
320         int flen, res;
322         if (ifname == NULL)
323                 return -1;
325 #ifdef ANDROID
326         if (access(ctrl_iface_dir, F_OK) < 0) {
327                 cfile = os_strdup(ifname);
328                 if (cfile == NULL)
329                         return -1;
330         }
331 #endif /* ANDROID */
333         if (cfile == NULL) {
334                 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
335                 cfile = os_malloc(flen);
336                 if (cfile == NULL)
337                         return -1;
338                 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
339                                   ifname);
340                 if (res < 0 || res >= flen) {
341                         os_free(cfile);
342                         return -1;
343                 }
344         }
346         ctrl_conn = wpa_ctrl_open(cfile);
347         if (ctrl_conn == NULL) {
348                 os_free(cfile);
349                 return -1;
350         }
352         if (attach && interactive)
353                 mon_conn = wpa_ctrl_open(cfile);
354         else
355                 mon_conn = NULL;
356         os_free(cfile);
357 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
359         if (mon_conn) {
360                 if (wpa_ctrl_attach(mon_conn) == 0) {
361                         wpa_cli_attached = 1;
362                         if (interactive)
363                                 eloop_register_read_sock(
364                                         wpa_ctrl_get_fd(mon_conn),
365                                         wpa_cli_mon_receive, NULL, NULL);
366                 } else {
367                         printf("Warning: Failed to attach to "
368                                "wpa_supplicant.\n");
369                         return -1;
370                 }
371         }
373         return 0;
377 static void wpa_cli_close_connection(void)
379         if (ctrl_conn == NULL)
380                 return;
382         if (wpa_cli_attached) {
383                 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
384                 wpa_cli_attached = 0;
385         }
386         wpa_ctrl_close(ctrl_conn);
387         ctrl_conn = NULL;
388         if (mon_conn) {
389                 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
390                 wpa_ctrl_close(mon_conn);
391                 mon_conn = NULL;
392         }
396 static void wpa_cli_msg_cb(char *msg, size_t len)
398         printf("%s\n", msg);
402 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
404         char buf[2048];
405         size_t len;
406         int ret;
408         if (ctrl_conn == NULL) {
409                 printf("Not connected to wpa_supplicant - command dropped.\n");
410                 return -1;
411         }
412         len = sizeof(buf) - 1;
413         ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
414                                wpa_cli_msg_cb);
415         if (ret == -2) {
416                 printf("'%s' command timed out.\n", cmd);
417                 return -2;
418         } else if (ret < 0) {
419                 printf("'%s' command failed.\n", cmd);
420                 return -1;
421         }
422         if (print) {
423                 buf[len] = '\0';
424                 printf("%s", buf);
425                 if (interactive && len > 0 && buf[len - 1] != '\n')
426                         printf("\n");
427         }
428         return 0;
432 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
434         return _wpa_ctrl_command(ctrl, cmd, 1);
438 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
440         if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
441                 return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
442         if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
443                 return wpa_ctrl_command(ctrl, "STATUS-WPS");
444         return wpa_ctrl_command(ctrl, "STATUS");
448 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
450         return wpa_ctrl_command(ctrl, "PING");
454 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
456         return wpa_ctrl_command(ctrl, "RELOG");
460 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
462         char cmd[256];
463         int ret;
464         if (argc == 0)
465                 return -1;
466         ret = os_snprintf(cmd, sizeof(cmd), "NOTE %s", argv[0]);
467         if (ret < 0 || (size_t) ret >= sizeof(cmd))
468                 return -1;
469         return wpa_ctrl_command(ctrl, cmd);
473 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
475         return wpa_ctrl_command(ctrl, "MIB");
479 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
481         return wpa_ctrl_command(ctrl, "PMKSA");
485 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
487         print_help();
488         return 0;
492 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
494         printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
495         return 0;
499 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
501         wpa_cli_quit = 1;
502         if (interactive)
503                 eloop_terminate();
504         return 0;
508 static void wpa_cli_show_variables(void)
510         printf("set variables:\n"
511                "  EAPOL::heldPeriod (EAPOL state machine held period, "
512                "in seconds)\n"
513                "  EAPOL::authPeriod (EAPOL state machine authentication "
514                "period, in seconds)\n"
515                "  EAPOL::startPeriod (EAPOL state machine start period, in "
516                "seconds)\n"
517                "  EAPOL::maxStart (EAPOL state machine maximum start "
518                "attempts)\n");
519         printf("  dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
520                "seconds)\n"
521                "  dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
522                " threshold\n\tpercentage)\n"
523                "  dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
524                "security\n\tassociation in seconds)\n");
528 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
530         char cmd[256];
531         int res;
533         if (argc == 0) {
534                 wpa_cli_show_variables();
535                 return 0;
536         }
538         if (argc != 1 && argc != 2) {
539                 printf("Invalid SET command: needs two arguments (variable "
540                        "name and value)\n");
541                 return -1;
542         }
544         if (argc == 1)
545                 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
546         else
547                 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s",
548                                   argv[0], argv[1]);
549         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
550                 printf("Too long SET command.\n");
551                 return -1;
552         }
553         return wpa_ctrl_command(ctrl, cmd);
557 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
559         char cmd[256];
560         int res;
562         if (argc != 1) {
563                 printf("Invalid GET command: need one argument (variable "
564                        "name)\n");
565                 return -1;
566         }
568         res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
569         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
570                 printf("Too long GET command.\n");
571                 return -1;
572         }
573         return wpa_ctrl_command(ctrl, cmd);
577 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
579         return wpa_ctrl_command(ctrl, "LOGOFF");
583 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
585         return wpa_ctrl_command(ctrl, "LOGON");
589 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
590                                    char *argv[])
592         return wpa_ctrl_command(ctrl, "REASSOCIATE");
596 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
597                                        char *argv[])
599         char cmd[256];
600         int res;
602         if (argc != 1) {
603                 printf("Invalid PREAUTH command: needs one argument "
604                        "(BSSID)\n");
605                 return -1;
606         }
608         res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
609         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
610                 printf("Too long PREAUTH command.\n");
611                 return -1;
612         }
613         return wpa_ctrl_command(ctrl, cmd);
617 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
619         char cmd[256];
620         int res;
622         if (argc != 1) {
623                 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
624                        "value)\n");
625                 return -1;
626         }
627         res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
628         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
629                 printf("Too long AP_SCAN command.\n");
630                 return -1;
631         }
632         return wpa_ctrl_command(ctrl, cmd);
636 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
637                                      char *argv[])
639         char cmd[256];
640         int res;
642         if (argc != 1) {
643                 printf("Invalid SCAN_INTERVAL command: needs one argument "
644                        "scan_interval value)\n");
645                 return -1;
646         }
647         res = os_snprintf(cmd, sizeof(cmd), "SCAN_INTERVAL %s", argv[0]);
648         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
649                 printf("Too long SCAN_INTERVAL command.\n");
650                 return -1;
651         }
652         return wpa_ctrl_command(ctrl, cmd);
656 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
657                                       char *argv[])
659         char cmd[256];
660         int res;
662         if (argc != 1) {
663                 printf("Invalid BSS_EXPIRE_AGE command: needs one argument "
664                        "(bss_expire_age value)\n");
665                 return -1;
666         }
667         res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_AGE %s", argv[0]);
668         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
669                 printf("Too long BSS_EXPIRE_AGE command.\n");
670                 return -1;
671         }
672         return wpa_ctrl_command(ctrl, cmd);
676 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
677                                         char *argv[])
679         char cmd[256];
680         int res;
682         if (argc != 1) {
683                 printf("Invalid BSS_EXPIRE_COUNT command: needs one argument "
684                        "(bss_expire_count value)\n");
685                 return -1;
686         }
687         res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_COUNT %s", argv[0]);
688         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
689                 printf("Too long BSS_EXPIRE_COUNT command.\n");
690                 return -1;
691         }
692         return wpa_ctrl_command(ctrl, cmd);
696 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
697                                 char *argv[])
699         char cmd[256];
700         int res;
702         if (argc != 1) {
703                 printf("Invalid STKSTART command: needs one argument "
704                        "(Peer STA MAC address)\n");
705                 return -1;
706         }
708         res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
709         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
710                 printf("Too long STKSTART command.\n");
711                 return -1;
712         }
713         return wpa_ctrl_command(ctrl, cmd);
717 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
719         char cmd[256];
720         int res;
722         if (argc != 1) {
723                 printf("Invalid FT_DS command: needs one argument "
724                        "(Target AP MAC address)\n");
725                 return -1;
726         }
728         res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
729         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
730                 printf("Too long FT_DS command.\n");
731                 return -1;
732         }
733         return wpa_ctrl_command(ctrl, cmd);
737 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
739         char cmd[256];
740         int res;
742         if (argc == 0) {
743                 /* Any BSSID */
744                 return wpa_ctrl_command(ctrl, "WPS_PBC");
745         }
747         /* Specific BSSID */
748         res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
749         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
750                 printf("Too long WPS_PBC command.\n");
751                 return -1;
752         }
753         return wpa_ctrl_command(ctrl, cmd);
757 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
759         char cmd[256];
760         int res;
762         if (argc == 0) {
763                 printf("Invalid WPS_PIN command: need one or two arguments:\n"
764                        "- BSSID: use 'any' to select any\n"
765                        "- PIN: optional, used only with devices that have no "
766                        "display\n");
767                 return -1;
768         }
770         if (argc == 1) {
771                 /* Use dynamically generated PIN (returned as reply) */
772                 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
773                 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
774                         printf("Too long WPS_PIN command.\n");
775                         return -1;
776                 }
777                 return wpa_ctrl_command(ctrl, cmd);
778         }
780         /* Use hardcoded PIN from a label */
781         res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
782         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
783                 printf("Too long WPS_PIN command.\n");
784                 return -1;
785         }
786         return wpa_ctrl_command(ctrl, cmd);
790 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
791                                      char *argv[])
793         char cmd[256];
794         int res;
796         if (argc != 1 && argc != 2) {
797                 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
798                        "- PIN to be verified\n");
799                 return -1;
800         }
802         if (argc == 2)
803                 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
804                                   argv[0], argv[1]);
805         else
806                 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
807                                   argv[0]);
808         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
809                 printf("Too long WPS_CHECK_PIN command.\n");
810                 return -1;
811         }
812         return wpa_ctrl_command(ctrl, cmd);
816 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
817                                   char *argv[])
819         return wpa_ctrl_command(ctrl, "WPS_CANCEL");
823 #ifdef CONFIG_WPS_OOB
824 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
826         char cmd[256];
827         int res;
829         if (argc != 3 && argc != 4) {
830                 printf("Invalid WPS_OOB command: need three or four "
831                        "arguments:\n"
832                        "- DEV_TYPE: use 'ufd' or 'nfc'\n"
833                        "- PATH: path of OOB device like '/mnt'\n"
834                        "- METHOD: OOB method 'pin-e' or 'pin-r', "
835                        "'cred'\n"
836                        "- DEV_NAME: (only for NFC) device name like "
837                        "'pn531'\n");
838                 return -1;
839         }
841         if (argc == 3)
842                 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
843                                   argv[0], argv[1], argv[2]);
844         else
845                 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
846                                   argv[0], argv[1], argv[2], argv[3]);
847         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
848                 printf("Too long WPS_OOB command.\n");
849                 return -1;
850         }
851         return wpa_ctrl_command(ctrl, cmd);
853 #endif /* CONFIG_WPS_OOB */
856 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
858         char cmd[256];
859         int res;
861         if (argc == 2)
862                 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
863                                   argv[0], argv[1]);
864         else if (argc == 5 || argc == 6) {
865                 char ssid_hex[2 * 32 + 1];
866                 char key_hex[2 * 64 + 1];
867                 int i;
869                 ssid_hex[0] = '\0';
870                 for (i = 0; i < 32; i++) {
871                         if (argv[2][i] == '\0')
872                                 break;
873                         os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
874                 }
876                 key_hex[0] = '\0';
877                 if (argc == 6) {
878                         for (i = 0; i < 64; i++) {
879                                 if (argv[5][i] == '\0')
880                                         break;
881                                 os_snprintf(&key_hex[i * 2], 3, "%02x",
882                                             argv[5][i]);
883                         }
884                 }
886                 res = os_snprintf(cmd, sizeof(cmd),
887                                   "WPS_REG %s %s %s %s %s %s",
888                                   argv[0], argv[1], ssid_hex, argv[3], argv[4],
889                                   key_hex);
890         } else {
891                 printf("Invalid WPS_REG command: need two arguments:\n"
892                        "- BSSID of the target AP\n"
893                        "- AP PIN\n");
894                 printf("Alternatively, six arguments can be used to "
895                        "reconfigure the AP:\n"
896                        "- BSSID of the target AP\n"
897                        "- AP PIN\n"
898                        "- new SSID\n"
899                        "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
900                        "- new encr (NONE, WEP, TKIP, CCMP)\n"
901                        "- new key\n");
902                 return -1;
903         }
905         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
906                 printf("Too long WPS_REG command.\n");
907                 return -1;
908         }
909         return wpa_ctrl_command(ctrl, cmd);
913 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
914                                   char *argv[])
916         char cmd[256];
917         int res;
919         if (argc < 1) {
920                 printf("Invalid WPS_AP_PIN command: needs at least one "
921                        "argument\n");
922                 return -1;
923         }
925         if (argc > 2)
926                 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s %s",
927                                   argv[0], argv[1], argv[2]);
928         else if (argc > 1)
929                 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s",
930                                   argv[0], argv[1]);
931         else
932                 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s",
933                                   argv[0]);
934         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
935                 printf("Too long WPS_AP_PIN command.\n");
936                 return -1;
937         }
938         return wpa_ctrl_command(ctrl, cmd);
942 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
943                                     char *argv[])
945         char cmd[100];
946         if (argc > 0) {
947                 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
948                 return wpa_ctrl_command(ctrl, cmd);
949         }
950         return wpa_ctrl_command(ctrl, "WPS_ER_START");
954 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
955                                    char *argv[])
957         return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
962 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
963                                   char *argv[])
965         char cmd[256];
966         int res;
968         if (argc < 2) {
969                 printf("Invalid WPS_ER_PIN command: need at least two "
970                        "arguments:\n"
971                        "- UUID: use 'any' to select any\n"
972                        "- PIN: Enrollee PIN\n"
973                        "optional: - Enrollee MAC address\n");
974                 return -1;
975         }
977         if (argc > 2)
978                 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
979                                   argv[0], argv[1], argv[2]);
980         else
981                 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
982                                   argv[0], argv[1]);
983         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
984                 printf("Too long WPS_ER_PIN command.\n");
985                 return -1;
986         }
987         return wpa_ctrl_command(ctrl, cmd);
991 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
992                                   char *argv[])
994         char cmd[256];
995         int res;
997         if (argc != 1) {
998                 printf("Invalid WPS_ER_PBC command: need one argument:\n"
999                        "- UUID: Specify the Enrollee\n");
1000                 return -1;
1001         }
1003         res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
1004                           argv[0]);
1005         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1006                 printf("Too long WPS_ER_PBC command.\n");
1007                 return -1;
1008         }
1009         return wpa_ctrl_command(ctrl, cmd);
1013 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
1014                                     char *argv[])
1016         char cmd[256];
1017         int res;
1019         if (argc != 2) {
1020                 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1021                        "- UUID: specify which AP to use\n"
1022                        "- PIN: AP PIN\n");
1023                 return -1;
1024         }
1026         res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
1027                           argv[0], argv[1]);
1028         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1029                 printf("Too long WPS_ER_LEARN command.\n");
1030                 return -1;
1031         }
1032         return wpa_ctrl_command(ctrl, cmd);
1036 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
1037                                          char *argv[])
1039         char cmd[256];
1040         int res;
1042         if (argc != 2) {
1043                 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1044                        "arguments:\n"
1045                        "- UUID: specify which AP to use\n"
1046                        "- Network configuration id\n");
1047                 return -1;
1048         }
1050         res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_SET_CONFIG %s %s",
1051                           argv[0], argv[1]);
1052         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1053                 printf("Too long WPS_ER_SET_CONFIG command.\n");
1054                 return -1;
1055         }
1056         return wpa_ctrl_command(ctrl, cmd);
1060 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
1061                                      char *argv[])
1063         char cmd[256];
1064         int res;
1066         if (argc == 5 || argc == 6) {
1067                 char ssid_hex[2 * 32 + 1];
1068                 char key_hex[2 * 64 + 1];
1069                 int i;
1071                 ssid_hex[0] = '\0';
1072                 for (i = 0; i < 32; i++) {
1073                         if (argv[2][i] == '\0')
1074                                 break;
1075                         os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1076                 }
1078                 key_hex[0] = '\0';
1079                 if (argc == 6) {
1080                         for (i = 0; i < 64; i++) {
1081                                 if (argv[5][i] == '\0')
1082                                         break;
1083                                 os_snprintf(&key_hex[i * 2], 3, "%02x",
1084                                             argv[5][i]);
1085                         }
1086                 }
1088                 res = os_snprintf(cmd, sizeof(cmd),
1089                                   "WPS_ER_CONFIG %s %s %s %s %s %s",
1090                                   argv[0], argv[1], ssid_hex, argv[3], argv[4],
1091                                   key_hex);
1092         } else {
1093                 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1094                        "- AP UUID\n"
1095                        "- AP PIN\n"
1096                        "- new SSID\n"
1097                        "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1098                        "- new encr (NONE, WEP, TKIP, CCMP)\n"
1099                        "- new key\n");
1100                 return -1;
1101         }
1103         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1104                 printf("Too long WPS_ER_CONFIG command.\n");
1105                 return -1;
1106         }
1107         return wpa_ctrl_command(ctrl, cmd);
1111 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1113         char cmd[256];
1114         int res;
1116         if (argc != 1) {
1117                 printf("Invalid IBSS_RSN command: needs one argument "
1118                        "(Peer STA MAC address)\n");
1119                 return -1;
1120         }
1122         res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
1123         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1124                 printf("Too long IBSS_RSN command.\n");
1125                 return -1;
1126         }
1127         return wpa_ctrl_command(ctrl, cmd);
1131 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1133         char cmd[256];
1134         int res;
1136         if (argc != 1) {
1137                 printf("Invalid LEVEL command: needs one argument (debug "
1138                        "level)\n");
1139                 return -1;
1140         }
1141         res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
1142         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1143                 printf("Too long LEVEL command.\n");
1144                 return -1;
1145         }
1146         return wpa_ctrl_command(ctrl, cmd);
1150 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1152         char cmd[256], *pos, *end;
1153         int i, ret;
1155         if (argc < 2) {
1156                 printf("Invalid IDENTITY command: needs two arguments "
1157                        "(network id and identity)\n");
1158                 return -1;
1159         }
1161         end = cmd + sizeof(cmd);
1162         pos = cmd;
1163         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1164                           argv[0], argv[1]);
1165         if (ret < 0 || ret >= end - pos) {
1166                 printf("Too long IDENTITY command.\n");
1167                 return -1;
1168         }
1169         pos += ret;
1170         for (i = 2; i < argc; i++) {
1171                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1172                 if (ret < 0 || ret >= end - pos) {
1173                         printf("Too long IDENTITY command.\n");
1174                         return -1;
1175                 }
1176                 pos += ret;
1177         }
1179         return wpa_ctrl_command(ctrl, cmd);
1183 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1185         char cmd[256], *pos, *end;
1186         int i, ret;
1188         if (argc < 2) {
1189                 printf("Invalid PASSWORD command: needs two arguments "
1190                        "(network id and password)\n");
1191                 return -1;
1192         }
1194         end = cmd + sizeof(cmd);
1195         pos = cmd;
1196         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1197                           argv[0], argv[1]);
1198         if (ret < 0 || ret >= end - pos) {
1199                 printf("Too long PASSWORD command.\n");
1200                 return -1;
1201         }
1202         pos += ret;
1203         for (i = 2; i < argc; i++) {
1204                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1205                 if (ret < 0 || ret >= end - pos) {
1206                         printf("Too long PASSWORD command.\n");
1207                         return -1;
1208                 }
1209                 pos += ret;
1210         }
1212         return wpa_ctrl_command(ctrl, cmd);
1216 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1217                                     char *argv[])
1219         char cmd[256], *pos, *end;
1220         int i, ret;
1222         if (argc < 2) {
1223                 printf("Invalid NEW_PASSWORD command: needs two arguments "
1224                        "(network id and password)\n");
1225                 return -1;
1226         }
1228         end = cmd + sizeof(cmd);
1229         pos = cmd;
1230         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1231                           argv[0], argv[1]);
1232         if (ret < 0 || ret >= end - pos) {
1233                 printf("Too long NEW_PASSWORD command.\n");
1234                 return -1;
1235         }
1236         pos += ret;
1237         for (i = 2; i < argc; i++) {
1238                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1239                 if (ret < 0 || ret >= end - pos) {
1240                         printf("Too long NEW_PASSWORD command.\n");
1241                         return -1;
1242                 }
1243                 pos += ret;
1244         }
1246         return wpa_ctrl_command(ctrl, cmd);
1250 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1252         char cmd[256], *pos, *end;
1253         int i, ret;
1255         if (argc < 2) {
1256                 printf("Invalid PIN command: needs two arguments "
1257                        "(network id and pin)\n");
1258                 return -1;
1259         }
1261         end = cmd + sizeof(cmd);
1262         pos = cmd;
1263         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1264                           argv[0], argv[1]);
1265         if (ret < 0 || ret >= end - pos) {
1266                 printf("Too long PIN command.\n");
1267                 return -1;
1268         }
1269         pos += ret;
1270         for (i = 2; i < argc; i++) {
1271                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1272                 if (ret < 0 || ret >= end - pos) {
1273                         printf("Too long PIN command.\n");
1274                         return -1;
1275                 }
1276                 pos += ret;
1277         }
1278         return wpa_ctrl_command(ctrl, cmd);
1282 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1284         char cmd[256], *pos, *end;
1285         int i, ret;
1287         if (argc < 2) {
1288                 printf("Invalid OTP command: needs two arguments (network "
1289                        "id and password)\n");
1290                 return -1;
1291         }
1293         end = cmd + sizeof(cmd);
1294         pos = cmd;
1295         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1296                           argv[0], argv[1]);
1297         if (ret < 0 || ret >= end - pos) {
1298                 printf("Too long OTP command.\n");
1299                 return -1;
1300         }
1301         pos += ret;
1302         for (i = 2; i < argc; i++) {
1303                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1304                 if (ret < 0 || ret >= end - pos) {
1305                         printf("Too long OTP command.\n");
1306                         return -1;
1307                 }
1308                 pos += ret;
1309         }
1311         return wpa_ctrl_command(ctrl, cmd);
1315 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1316                                   char *argv[])
1318         char cmd[256], *pos, *end;
1319         int i, ret;
1321         if (argc < 2) {
1322                 printf("Invalid PASSPHRASE command: needs two arguments "
1323                        "(network id and passphrase)\n");
1324                 return -1;
1325         }
1327         end = cmd + sizeof(cmd);
1328         pos = cmd;
1329         ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1330                           argv[0], argv[1]);
1331         if (ret < 0 || ret >= end - pos) {
1332                 printf("Too long PASSPHRASE command.\n");
1333                 return -1;
1334         }
1335         pos += ret;
1336         for (i = 2; i < argc; i++) {
1337                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1338                 if (ret < 0 || ret >= end - pos) {
1339                         printf("Too long PASSPHRASE command.\n");
1340                         return -1;
1341                 }
1342                 pos += ret;
1343         }
1345         return wpa_ctrl_command(ctrl, cmd);
1349 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1351         char cmd[256], *pos, *end;
1352         int i, ret;
1354         if (argc < 2) {
1355                 printf("Invalid BSSID command: needs two arguments (network "
1356                        "id and BSSID)\n");
1357                 return -1;
1358         }
1360         end = cmd + sizeof(cmd);
1361         pos = cmd;
1362         ret = os_snprintf(pos, end - pos, "BSSID");
1363         if (ret < 0 || ret >= end - pos) {
1364                 printf("Too long BSSID command.\n");
1365                 return -1;
1366         }
1367         pos += ret;
1368         for (i = 0; i < argc; i++) {
1369                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1370                 if (ret < 0 || ret >= end - pos) {
1371                         printf("Too long BSSID command.\n");
1372                         return -1;
1373                 }
1374                 pos += ret;
1375         }
1377         return wpa_ctrl_command(ctrl, cmd);
1381 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1383         char cmd[256], *pos, *end;
1384         int i, ret;
1386         end = cmd + sizeof(cmd);
1387         pos = cmd;
1388         ret = os_snprintf(pos, end - pos, "BLACKLIST");
1389         if (ret < 0 || ret >= end - pos) {
1390                 printf("Too long BLACKLIST command.\n");
1391                 return -1;
1392         }
1393         pos += ret;
1394         for (i = 0; i < argc; i++) {
1395                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1396                 if (ret < 0 || ret >= end - pos) {
1397                         printf("Too long BLACKLIST command.\n");
1398                         return -1;
1399                 }
1400                 pos += ret;
1401         }
1403         return wpa_ctrl_command(ctrl, cmd);
1407 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1409         char cmd[256], *pos, *end;
1410         int i, ret;
1412         end = cmd + sizeof(cmd);
1413         pos = cmd;
1414         ret = os_snprintf(pos, end - pos, "LOG_LEVEL");
1415         if (ret < 0 || ret >= end - pos) {
1416                 printf("Too long LOG_LEVEL command.\n");
1417                 return -1;
1418         }
1419         pos += ret;
1420         for (i = 0; i < argc; i++) {
1421                 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1422                 if (ret < 0 || ret >= end - pos) {
1423                         printf("Too long LOG_LEVEL command.\n");
1424                         return -1;
1425                 }
1426                 pos += ret;
1427         }
1429         return wpa_ctrl_command(ctrl, cmd);
1433 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1434                                      char *argv[])
1436         return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1440 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1441                                       char *argv[])
1443         char cmd[32];
1444         int res;
1446         if (argc < 1) {
1447                 printf("Invalid SELECT_NETWORK command: needs one argument "
1448                        "(network id)\n");
1449                 return -1;
1450         }
1452         res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1453         if (res < 0 || (size_t) res >= sizeof(cmd))
1454                 return -1;
1455         cmd[sizeof(cmd) - 1] = '\0';
1457         return wpa_ctrl_command(ctrl, cmd);
1461 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1462                                       char *argv[])
1464         char cmd[32];
1465         int res;
1467         if (argc < 1) {
1468                 printf("Invalid ENABLE_NETWORK command: needs one argument "
1469                        "(network id)\n");
1470                 return -1;
1471         }
1473         res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1474         if (res < 0 || (size_t) res >= sizeof(cmd))
1475                 return -1;
1476         cmd[sizeof(cmd) - 1] = '\0';
1478         return wpa_ctrl_command(ctrl, cmd);
1482 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1483                                        char *argv[])
1485         char cmd[32];
1486         int res;
1488         if (argc < 1) {
1489                 printf("Invalid DISABLE_NETWORK command: needs one argument "
1490                        "(network id)\n");
1491                 return -1;
1492         }
1494         res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1495         if (res < 0 || (size_t) res >= sizeof(cmd))
1496                 return -1;
1497         cmd[sizeof(cmd) - 1] = '\0';
1499         return wpa_ctrl_command(ctrl, cmd);
1503 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1504                                    char *argv[])
1506         return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1510 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1511                                       char *argv[])
1513         char cmd[32];
1514         int res;
1516         if (argc < 1) {
1517                 printf("Invalid REMOVE_NETWORK command: needs one argument "
1518                        "(network id)\n");
1519                 return -1;
1520         }
1522         res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1523         if (res < 0 || (size_t) res >= sizeof(cmd))
1524                 return -1;
1525         cmd[sizeof(cmd) - 1] = '\0';
1527         return wpa_ctrl_command(ctrl, cmd);
1531 static void wpa_cli_show_network_variables(void)
1533         printf("set_network variables:\n"
1534                "  ssid (network name, SSID)\n"
1535                "  psk (WPA passphrase or pre-shared key)\n"
1536                "  key_mgmt (key management protocol)\n"
1537                "  identity (EAP identity)\n"
1538                "  password (EAP password)\n"
1539                "  ...\n"
1540                "\n"
1541                "Note: Values are entered in the same format as the "
1542                "configuration file is using,\n"
1543                "i.e., strings values need to be inside double quotation "
1544                "marks.\n"
1545                "For example: set_network 1 ssid \"network name\"\n"
1546                "\n"
1547                "Please see wpa_supplicant.conf documentation for full list "
1548                "of\navailable variables.\n");
1552 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1553                                    char *argv[])
1555         char cmd[256];
1556         int res;
1558         if (argc == 0) {
1559                 wpa_cli_show_network_variables();
1560                 return 0;
1561         }
1563         if (argc != 3) {
1564                 printf("Invalid SET_NETWORK command: needs three arguments\n"
1565                        "(network id, variable name, and value)\n");
1566                 return -1;
1567         }
1569         res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1570                           argv[0], argv[1], argv[2]);
1571         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1572                 printf("Too long SET_NETWORK command.\n");
1573                 return -1;
1574         }
1575         return wpa_ctrl_command(ctrl, cmd);
1579 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1580                                    char *argv[])
1582         char cmd[256];
1583         int res;
1585         if (argc == 0) {
1586                 wpa_cli_show_network_variables();
1587                 return 0;
1588         }
1590         if (argc != 2) {
1591                 printf("Invalid GET_NETWORK command: needs two arguments\n"
1592                        "(network id and variable name)\n");
1593                 return -1;
1594         }
1596         res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1597                           argv[0], argv[1]);
1598         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1599                 printf("Too long GET_NETWORK command.\n");
1600                 return -1;
1601         }
1602         return wpa_ctrl_command(ctrl, cmd);
1606 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1607                                   char *argv[])
1609         return wpa_ctrl_command(ctrl, "DISCONNECT");
1613 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1614                                   char *argv[])
1616         return wpa_ctrl_command(ctrl, "RECONNECT");
1620 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1621                                    char *argv[])
1623         return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1627 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1629         return wpa_ctrl_command(ctrl, "SCAN");
1633 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1634                                     char *argv[])
1636         return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1640 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1642         char cmd[64];
1643         int res;
1645         if (argc != 1) {
1646                 printf("Invalid BSS command: need one argument (index or "
1647                        "BSSID)\n");
1648                 return -1;
1649         }
1651         res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1652         if (res < 0 || (size_t) res >= sizeof(cmd))
1653                 return -1;
1654         cmd[sizeof(cmd) - 1] = '\0';
1656         return wpa_ctrl_command(ctrl, cmd);
1660 static char ** wpa_cli_complete_bss(const char *str, int pos)
1662         int arg = get_cmd_arg_num(str, pos);
1663         char **res = NULL;
1665         switch (arg) {
1666         case 1:
1667                 res = cli_txt_list_array(&bsses);
1668                 break;
1669         }
1671         return res;
1675 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1676                                       char *argv[])
1678         char cmd[64];
1679         int res;
1681         if (argc < 1 || argc > 2) {
1682                 printf("Invalid GET_CAPABILITY command: need either one or "
1683                        "two arguments\n");
1684                 return -1;
1685         }
1687         if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1688                 printf("Invalid GET_CAPABILITY command: second argument, "
1689                        "if any, must be 'strict'\n");
1690                 return -1;
1691         }
1693         res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1694                           (argc == 2) ? " strict" : "");
1695         if (res < 0 || (size_t) res >= sizeof(cmd))
1696                 return -1;
1697         cmd[sizeof(cmd) - 1] = '\0';
1699         return wpa_ctrl_command(ctrl, cmd);
1703 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1705         printf("Available interfaces:\n");
1706         return wpa_ctrl_command(ctrl, "INTERFACES");
1710 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1712         if (argc < 1) {
1713                 wpa_cli_list_interfaces(ctrl);
1714                 return 0;
1715         }
1717         wpa_cli_close_connection();
1718         os_free(ctrl_ifname);
1719         ctrl_ifname = os_strdup(argv[0]);
1721         if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1722                 printf("Connected to interface '%s.\n", ctrl_ifname);
1723         } else {
1724                 printf("Could not connect to interface '%s' - re-trying\n",
1725                        ctrl_ifname);
1726         }
1727         return 0;
1731 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1732                                    char *argv[])
1734         return wpa_ctrl_command(ctrl, "RECONFIGURE");
1738 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1739                                  char *argv[])
1741         return wpa_ctrl_command(ctrl, "TERMINATE");
1745 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1746                                      char *argv[])
1748         char cmd[256];
1749         int res;
1751         if (argc < 1) {
1752                 printf("Invalid INTERFACE_ADD command: needs at least one "
1753                        "argument (interface name)\n"
1754                        "All arguments: ifname confname driver ctrl_interface "
1755                        "driver_param bridge_name\n");
1756                 return -1;
1757         }
1759         /*
1760          * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1761          * <driver_param>TAB<bridge_name>
1762          */
1763         res = os_snprintf(cmd, sizeof(cmd),
1764                           "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1765                           argv[0],
1766                           argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1767                           argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1768                           argc > 5 ? argv[5] : "");
1769         if (res < 0 || (size_t) res >= sizeof(cmd))
1770                 return -1;
1771         cmd[sizeof(cmd) - 1] = '\0';
1772         return wpa_ctrl_command(ctrl, cmd);
1776 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1777                                         char *argv[])
1779         char cmd[128];
1780         int res;
1782         if (argc != 1) {
1783                 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1784                        "(interface name)\n");
1785                 return -1;
1786         }
1788         res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1789         if (res < 0 || (size_t) res >= sizeof(cmd))
1790                 return -1;
1791         cmd[sizeof(cmd) - 1] = '\0';
1792         return wpa_ctrl_command(ctrl, cmd);
1796 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1797                                       char *argv[])
1799         return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1803 #ifdef CONFIG_AP
1804 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1806         char buf[64];
1807         if (argc != 1) {
1808                 printf("Invalid 'sta' command - exactly one argument, STA "
1809                        "address, is required.\n");
1810                 return -1;
1811         }
1812         os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1813         return wpa_ctrl_command(ctrl, buf);
1817 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1818                                 char *addr, size_t addr_len)
1820         char buf[4096], *pos;
1821         size_t len;
1822         int ret;
1824         if (ctrl_conn == NULL) {
1825                 printf("Not connected to hostapd - command dropped.\n");
1826                 return -1;
1827         }
1828         len = sizeof(buf) - 1;
1829         ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1830                                wpa_cli_msg_cb);
1831         if (ret == -2) {
1832                 printf("'%s' command timed out.\n", cmd);
1833                 return -2;
1834         } else if (ret < 0) {
1835                 printf("'%s' command failed.\n", cmd);
1836                 return -1;
1837         }
1839         buf[len] = '\0';
1840         if (memcmp(buf, "FAIL", 4) == 0)
1841                 return -1;
1842         printf("%s", buf);
1844         pos = buf;
1845         while (*pos != '\0' && *pos != '\n')
1846                 pos++;
1847         *pos = '\0';
1848         os_strlcpy(addr, buf, addr_len);
1849         return 0;
1853 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1855         char addr[32], cmd[64];
1857         if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1858                 return 0;
1859         do {
1860                 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1861         } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1863         return -1;
1865 #endif /* CONFIG_AP */
1868 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1870         return wpa_ctrl_command(ctrl, "SUSPEND");
1874 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1876         return wpa_ctrl_command(ctrl, "RESUME");
1880 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1882         return wpa_ctrl_command(ctrl, "DROP_SA");
1886 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1888         char cmd[128];
1889         int res;
1891         if (argc != 1) {
1892                 printf("Invalid ROAM command: needs one argument "
1893                        "(target AP's BSSID)\n");
1894                 return -1;
1895         }
1897         res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1898         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1899                 printf("Too long ROAM command.\n");
1900                 return -1;
1901         }
1902         return wpa_ctrl_command(ctrl, cmd);
1906 #ifdef CONFIG_P2P
1908 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1910         char cmd[128];
1911         int res;
1913         if (argc == 0)
1914                 return wpa_ctrl_command(ctrl, "P2P_FIND");
1916         if (argc > 2)
1917                 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s %s",
1918                                   argv[0], argv[1], argv[2]);
1919         else if (argc > 1)
1920                 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
1921                                   argv[0], argv[1]);
1922         else
1923                 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
1924         if (res < 0 || (size_t) res >= sizeof(cmd))
1925                 return -1;
1926         cmd[sizeof(cmd) - 1] = '\0';
1927         return wpa_ctrl_command(ctrl, cmd);
1931 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1932                                      char *argv[])
1934         return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1938 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1939                                    char *argv[])
1941         char cmd[128];
1942         int res;
1944         if (argc < 2) {
1945                 printf("Invalid P2P_CONNECT command: needs at least two "
1946                        "arguments (address and pbc/PIN)\n");
1947                 return -1;
1948         }
1950         if (argc > 4)
1951                 res = os_snprintf(cmd, sizeof(cmd),
1952                                   "P2P_CONNECT %s %s %s %s %s",
1953                                   argv[0], argv[1], argv[2], argv[3],
1954                                   argv[4]);
1955         else if (argc > 3)
1956                 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
1957                                   argv[0], argv[1], argv[2], argv[3]);
1958         else if (argc > 2)
1959                 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
1960                                   argv[0], argv[1], argv[2]);
1961         else
1962                 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1963                                   argv[0], argv[1]);
1964         if (res < 0 || (size_t) res >= sizeof(cmd))
1965                 return -1;
1966         cmd[sizeof(cmd) - 1] = '\0';
1967         return wpa_ctrl_command(ctrl, cmd);
1971 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
1973         int arg = get_cmd_arg_num(str, pos);
1974         char **res = NULL;
1976         switch (arg) {
1977         case 1:
1978                 res = cli_txt_list_array(&p2p_peers);
1979                 break;
1980         }
1982         return res;
1986 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1987                                   char *argv[])
1989         char cmd[128];
1990         int res;
1992         if (argc == 0)
1993                 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
1995         res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
1996         if (res < 0 || (size_t) res >= sizeof(cmd))
1997                 return -1;
1998         cmd[sizeof(cmd) - 1] = '\0';
1999         return wpa_ctrl_command(ctrl, cmd);
2003 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
2004                                         char *argv[])
2006         char cmd[128];
2007         int res;
2009         if (argc != 1) {
2010                 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
2011                        "(interface name)\n");
2012                 return -1;
2013         }
2015         res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
2016         if (res < 0 || (size_t) res >= sizeof(cmd))
2017                 return -1;
2018         cmd[sizeof(cmd) - 1] = '\0';
2019         return wpa_ctrl_command(ctrl, cmd);
2023 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
2025         int arg = get_cmd_arg_num(str, pos);
2026         char **res = NULL;
2028         switch (arg) {
2029         case 1:
2030                 res = cli_txt_list_array(&p2p_groups);
2031                 break;
2032         }
2034         return res;
2038 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
2039                                         char *argv[])
2041         char cmd[128];
2042         int res;
2044         if (argc == 0)
2045                 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
2047         if (argc > 1)
2048                 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s %s",
2049                                   argv[0], argv[1]);
2050         else
2051                 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s",
2052                                   argv[0]);
2053         if (res < 0 || (size_t) res >= sizeof(cmd))
2054                 return -1;
2055         cmd[sizeof(cmd) - 1] = '\0';
2056         return wpa_ctrl_command(ctrl, cmd);
2060 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
2061                                      char *argv[])
2063         char cmd[128];
2064         int res;
2066         if (argc != 2 && argc != 3) {
2067                 printf("Invalid P2P_PROV_DISC command: needs at least "
2068                        "two arguments, address and config method\n"
2069                        "(display, keypad, or pbc) and an optional join\n");
2070                 return -1;
2071         }
2073         if (argc == 3)
2074                 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s %s",
2075                                   argv[0], argv[1], argv[2]);
2076         else
2077                 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
2078                                   argv[0], argv[1]);
2079         if (res < 0 || (size_t) res >= sizeof(cmd))
2080                 return -1;
2081         cmd[sizeof(cmd) - 1] = '\0';
2082         return wpa_ctrl_command(ctrl, cmd);
2086 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
2087                                           char *argv[])
2089         return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
2093 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
2094                                          char *argv[])
2096         char cmd[4096];
2097         int res;
2099         if (argc != 2 && argc != 4) {
2100                 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2101                        "arguments (address and TLVs) or four arguments "
2102                        "(address, \"upnp\", version, search target "
2103                        "(SSDP ST:)\n");
2104                 return -1;
2105         }
2107         if (argc == 4)
2108                 res = os_snprintf(cmd, sizeof(cmd),
2109                                   "P2P_SERV_DISC_REQ %s %s %s %s",
2110                                   argv[0], argv[1], argv[2], argv[3]);
2111         else
2112                 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
2113                                   argv[0], argv[1]);
2114         if (res < 0 || (size_t) res >= sizeof(cmd))
2115                 return -1;
2116         cmd[sizeof(cmd) - 1] = '\0';
2117         return wpa_ctrl_command(ctrl, cmd);
2121 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
2122                                                 int argc, char *argv[])
2124         char cmd[128];
2125         int res;
2127         if (argc != 1) {
2128                 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
2129                        "argument (pending request identifier)\n");
2130                 return -1;
2131         }
2133         res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
2134                           argv[0]);
2135         if (res < 0 || (size_t) res >= sizeof(cmd))
2136                 return -1;
2137         cmd[sizeof(cmd) - 1] = '\0';
2138         return wpa_ctrl_command(ctrl, cmd);
2142 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
2143                                           char *argv[])
2145         char cmd[4096];
2146         int res;
2148         if (argc != 4) {
2149                 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2150                        "arguments (freq, address, dialog token, and TLVs)\n");
2151                 return -1;
2152         }
2154         res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
2155                           argv[0], argv[1], argv[2], argv[3]);
2156         if (res < 0 || (size_t) res >= sizeof(cmd))
2157                 return -1;
2158         cmd[sizeof(cmd) - 1] = '\0';
2159         return wpa_ctrl_command(ctrl, cmd);
2163 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
2164                                           char *argv[])
2166         return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
2170 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
2171                                               int argc, char *argv[])
2173         char cmd[128];
2174         int res;
2176         if (argc != 1) {
2177                 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
2178                        "argument (external processing: 0/1)\n");
2179                 return -1;
2180         }
2182         res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
2183                           argv[0]);
2184         if (res < 0 || (size_t) res >= sizeof(cmd))
2185                 return -1;
2186         cmd[sizeof(cmd) - 1] = '\0';
2187         return wpa_ctrl_command(ctrl, cmd);
2191 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
2192                                          char *argv[])
2194         return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
2198 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
2199                                        char *argv[])
2201         char cmd[4096];
2202         int res;
2204         if (argc != 3 && argc != 4) {
2205                 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
2206                        "arguments\n");
2207                 return -1;
2208         }
2210         if (argc == 4)
2211                 res = os_snprintf(cmd, sizeof(cmd),
2212                                   "P2P_SERVICE_ADD %s %s %s %s",
2213                                   argv[0], argv[1], argv[2], argv[3]);
2214         else
2215                 res = os_snprintf(cmd, sizeof(cmd),
2216                                   "P2P_SERVICE_ADD %s %s %s",
2217                                   argv[0], argv[1], argv[2]);
2218         if (res < 0 || (size_t) res >= sizeof(cmd))
2219                 return -1;
2220         cmd[sizeof(cmd) - 1] = '\0';
2221         return wpa_ctrl_command(ctrl, cmd);
2225 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2226                                        char *argv[])
2228         char cmd[4096];
2229         int res;
2231         if (argc != 2 && argc != 3) {
2232                 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2233                        "arguments\n");
2234                 return -1;
2235         }
2237         if (argc == 3)
2238                 res = os_snprintf(cmd, sizeof(cmd),
2239                                   "P2P_SERVICE_DEL %s %s %s",
2240                                   argv[0], argv[1], argv[2]);
2241         else
2242                 res = os_snprintf(cmd, sizeof(cmd),
2243                                   "P2P_SERVICE_DEL %s %s",
2244                                   argv[0], argv[1]);
2245         if (res < 0 || (size_t) res >= sizeof(cmd))
2246                 return -1;
2247         cmd[sizeof(cmd) - 1] = '\0';
2248         return wpa_ctrl_command(ctrl, cmd);
2252 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2253                                   int argc, char *argv[])
2255         char cmd[128];
2256         int res;
2258         if (argc != 1) {
2259                 printf("Invalid P2P_REJECT command: needs one argument "
2260                        "(peer address)\n");
2261                 return -1;
2262         }
2264         res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
2265         if (res < 0 || (size_t) res >= sizeof(cmd))
2266                 return -1;
2267         cmd[sizeof(cmd) - 1] = '\0';
2268         return wpa_ctrl_command(ctrl, cmd);
2272 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2273                                   int argc, char *argv[])
2275         char cmd[128];
2276         int res;
2278         if (argc < 1) {
2279                 printf("Invalid P2P_INVITE command: needs at least one "
2280                        "argument\n");
2281                 return -1;
2282         }
2284         if (argc > 2)
2285                 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
2286                                   argv[0], argv[1], argv[2]);
2287         else if (argc > 1)
2288                 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
2289                                   argv[0], argv[1]);
2290         else
2291                 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
2292         if (res < 0 || (size_t) res >= sizeof(cmd))
2293                 return -1;
2294         cmd[sizeof(cmd) - 1] = '\0';
2295         return wpa_ctrl_command(ctrl, cmd);
2299 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2301         char buf[64];
2302         if (argc != 1) {
2303                 printf("Invalid 'p2p_peer' command - exactly one argument, "
2304                        "P2P peer device address, is required.\n");
2305                 return -1;
2306         }
2307         os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
2308         return wpa_ctrl_command(ctrl, buf);
2312 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2314         int arg = get_cmd_arg_num(str, pos);
2315         char **res = NULL;
2317         switch (arg) {
2318         case 1:
2319                 res = cli_txt_list_array(&p2p_peers);
2320                 break;
2321         }
2323         return res;
2327 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2328                                      char *addr, size_t addr_len,
2329                                      int discovered)
2331         char buf[4096], *pos;
2332         size_t len;
2333         int ret;
2335         if (ctrl_conn == NULL)
2336                 return -1;
2337         len = sizeof(buf) - 1;
2338         ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
2339                                wpa_cli_msg_cb);
2340         if (ret == -2) {
2341                 printf("'%s' command timed out.\n", cmd);
2342                 return -2;
2343         } else if (ret < 0) {
2344                 printf("'%s' command failed.\n", cmd);
2345                 return -1;
2346         }
2348         buf[len] = '\0';
2349         if (memcmp(buf, "FAIL", 4) == 0)
2350                 return -1;
2352         pos = buf;
2353         while (*pos != '\0' && *pos != '\n')
2354                 pos++;
2355         *pos++ = '\0';
2356         os_strlcpy(addr, buf, addr_len);
2357         if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2358                 printf("%s\n", addr);
2359         return 0;
2363 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2365         char addr[32], cmd[64];
2366         int discovered;
2368         discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2370         if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2371                                       addr, sizeof(addr), discovered))
2372                 return -1;
2373         do {
2374                 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2375         } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2376                          discovered) == 0);
2378         return 0;
2382 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2384         char cmd[100];
2385         int res;
2387         if (argc != 2) {
2388                 printf("Invalid P2P_SET command: needs two arguments (field, "
2389                        "value)\n");
2390                 return -1;
2391         }
2393         res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2394         if (res < 0 || (size_t) res >= sizeof(cmd))
2395                 return -1;
2396         cmd[sizeof(cmd) - 1] = '\0';
2397         return wpa_ctrl_command(ctrl, cmd);
2401 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2403         return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2407 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2408                                   char *argv[])
2410         return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2414 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2415                                        char *argv[])
2417         char cmd[100];
2418         int res;
2420         if (argc != 1) {
2421                 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2422                        "(peer address)\n");
2423                 return -1;
2424         }
2426         res = os_snprintf(cmd, sizeof(cmd), "P2P_UNAUTHORIZE %s", argv[0]);
2428         if (res < 0 || (size_t) res >= sizeof(cmd))
2429                 return -1;
2431         cmd[sizeof(cmd) - 1] = '\0';
2432         return wpa_ctrl_command(ctrl, cmd);
2436 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2437                                         char *argv[])
2439         char cmd[100];
2440         int res;
2442         if (argc != 0 && argc != 2 && argc != 4) {
2443                 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2444                        "(preferred duration, interval; in microsecods).\n"
2445                        "Optional second pair can be used to provide "
2446                        "acceptable values.\n");
2447                 return -1;
2448         }
2450         if (argc == 4)
2451                 res = os_snprintf(cmd, sizeof(cmd),
2452                                   "P2P_PRESENCE_REQ %s %s %s %s",
2453                                   argv[0], argv[1], argv[2], argv[3]);
2454         else if (argc == 2)
2455                 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2456                                   argv[0], argv[1]);
2457         else
2458                 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2459         if (res < 0 || (size_t) res >= sizeof(cmd))
2460                 return -1;
2461         cmd[sizeof(cmd) - 1] = '\0';
2462         return wpa_ctrl_command(ctrl, cmd);
2466 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2467                                       char *argv[])
2469         char cmd[100];
2470         int res;
2472         if (argc != 0 && argc != 2) {
2473                 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2474                        "(availability period, availability interval; in "
2475                        "millisecods).\n"
2476                        "Extended Listen Timing can be cancelled with this "
2477                        "command when used without parameters.\n");
2478                 return -1;
2479         }
2481         if (argc == 2)
2482                 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2483                                   argv[0], argv[1]);
2484         else
2485                 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2486         if (res < 0 || (size_t) res >= sizeof(cmd))
2487                 return -1;
2488         cmd[sizeof(cmd) - 1] = '\0';
2489         return wpa_ctrl_command(ctrl, cmd);
2492 #endif /* CONFIG_P2P */
2495 #ifdef CONFIG_INTERWORKING
2496 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2497                                   char *argv[])
2499         return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2503 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2504                                        char *argv[])
2506         return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2510 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2511                                            char *argv[])
2513         char cmd[100];
2514         int res;
2516         if (argc == 0)
2517                 return wpa_ctrl_command(ctrl, "INTERWORKING_SELECT");
2519         res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_SELECT %s", argv[0]);
2520         if (res < 0 || (size_t) res >= sizeof(cmd))
2521                 return -1;
2522         cmd[sizeof(cmd) - 1] = '\0';
2523         return wpa_ctrl_command(ctrl, cmd);
2527 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2528                                             char *argv[])
2530         char cmd[100];
2531         int res;
2533         if (argc != 1) {
2534                 printf("Invalid INTERWORKING_CONNECT commands: needs one "
2535                        "argument (BSSID)\n");
2536                 return -1;
2537         }
2539         res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_CONNECT %s",
2540                           argv[0]);
2541         if (res < 0 || (size_t) res >= sizeof(cmd))
2542                 return -1;
2543         cmd[sizeof(cmd) - 1] = '\0';
2544         return wpa_ctrl_command(ctrl, cmd);
2548 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2550         char cmd[100];
2551         int res;
2553         if (argc != 2) {
2554                 printf("Invalid ANQP_GET command: needs two arguments "
2555                        "(addr and info id list)\n");
2556                 return -1;
2557         }
2559         res = os_snprintf(cmd, sizeof(cmd), "ANQP_GET %s %s",
2560                           argv[0], argv[1]);
2561         if (res < 0 || (size_t) res >= sizeof(cmd))
2562                 return -1;
2563         cmd[sizeof(cmd) - 1] = '\0';
2564         return wpa_ctrl_command(ctrl, cmd);
2566 #endif /* CONFIG_INTERWORKING */
2569 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2570                                        char *argv[])
2572         char cmd[256];
2573         int res;
2575         if (argc != 1) {
2576                 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2577                        "(0/1 = disable/enable automatic reconnection)\n");
2578                 return -1;
2579         }
2580         res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2581         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2582                 printf("Too long STA_AUTOCONNECT command.\n");
2583                 return -1;
2584         }
2585         return wpa_ctrl_command(ctrl, cmd);
2589 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2590                                      char *argv[])
2592         char cmd[256];
2593         int res;
2595         if (argc != 1) {
2596                 printf("Invalid TDLS_DISCOVER command: needs one argument "
2597                        "(Peer STA MAC address)\n");
2598                 return -1;
2599         }
2601         res = os_snprintf(cmd, sizeof(cmd), "TDLS_DISCOVER %s", argv[0]);
2602         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2603                 printf("Too long TDLS_DISCOVER command.\n");
2604                 return -1;
2605         }
2606         return wpa_ctrl_command(ctrl, cmd);
2610 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2611                                   char *argv[])
2613         char cmd[256];
2614         int res;
2616         if (argc != 1) {
2617                 printf("Invalid TDLS_SETUP command: needs one argument "
2618                        "(Peer STA MAC address)\n");
2619                 return -1;
2620         }
2622         res = os_snprintf(cmd, sizeof(cmd), "TDLS_SETUP %s", argv[0]);
2623         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2624                 printf("Too long TDLS_SETUP command.\n");
2625                 return -1;
2626         }
2627         return wpa_ctrl_command(ctrl, cmd);
2631 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2632                                      char *argv[])
2634         char cmd[256];
2635         int res;
2637         if (argc != 1) {
2638                 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2639                        "(Peer STA MAC address)\n");
2640                 return -1;
2641         }
2643         res = os_snprintf(cmd, sizeof(cmd), "TDLS_TEARDOWN %s", argv[0]);
2644         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2645                 printf("Too long TDLS_TEARDOWN command.\n");
2646                 return -1;
2647         }
2648         return wpa_ctrl_command(ctrl, cmd);
2652 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2653                                    char *argv[])
2655         return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2659 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2660                                       char *argv[])
2662         return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2666 enum wpa_cli_cmd_flags {
2667         cli_cmd_flag_none               = 0x00,
2668         cli_cmd_flag_sensitive          = 0x01
2669 };
2671 struct wpa_cli_cmd {
2672         const char *cmd;
2673         int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2674         enum wpa_cli_cmd_flags flags;
2675         const char *usage;
2676 };
2678 static struct wpa_cli_cmd wpa_cli_commands[] = {
2679         { "status", wpa_cli_cmd_status,
2680           cli_cmd_flag_none,
2681           "[verbose] = get current WPA/EAPOL/EAP status" },
2682         { "ping", wpa_cli_cmd_ping,
2683           cli_cmd_flag_none,
2684           "= pings wpa_supplicant" },
2685         { "relog", wpa_cli_cmd_relog,
2686           cli_cmd_flag_none,
2687           "= re-open log-file (allow rolling logs)" },
2688         { "note", wpa_cli_cmd_note,
2689           cli_cmd_flag_none,
2690           "<text> = add a note to wpa_supplicant debug log" },
2691         { "mib", wpa_cli_cmd_mib,
2692           cli_cmd_flag_none,
2693           "= get MIB variables (dot1x, dot11)" },
2694         { "help", wpa_cli_cmd_help,
2695           cli_cmd_flag_none,
2696           "= show this usage help" },
2697         { "interface", wpa_cli_cmd_interface,
2698           cli_cmd_flag_none,
2699           "[ifname] = show interfaces/select interface" },
2700         { "level", wpa_cli_cmd_level,
2701           cli_cmd_flag_none,
2702           "<debug level> = change debug level" },
2703         { "license", wpa_cli_cmd_license,
2704           cli_cmd_flag_none,
2705           "= show full wpa_cli license" },
2706         { "quit", wpa_cli_cmd_quit,
2707           cli_cmd_flag_none,
2708           "= exit wpa_cli" },
2709         { "set", wpa_cli_cmd_set,
2710           cli_cmd_flag_none,
2711           "= set variables (shows list of variables when run without "
2712           "arguments)" },
2713         { "get", wpa_cli_cmd_get,
2714           cli_cmd_flag_none,
2715           "<name> = get information" },
2716         { "logon", wpa_cli_cmd_logon,
2717           cli_cmd_flag_none,
2718           "= IEEE 802.1X EAPOL state machine logon" },
2719         { "logoff", wpa_cli_cmd_logoff,
2720           cli_cmd_flag_none,
2721           "= IEEE 802.1X EAPOL state machine logoff" },
2722         { "pmksa", wpa_cli_cmd_pmksa,
2723           cli_cmd_flag_none,
2724           "= show PMKSA cache" },
2725         { "reassociate", wpa_cli_cmd_reassociate,
2726           cli_cmd_flag_none,
2727           "= force reassociation" },
2728         { "preauthenticate", wpa_cli_cmd_preauthenticate,
2729           cli_cmd_flag_none,
2730           "<BSSID> = force preauthentication" },
2731         { "identity", wpa_cli_cmd_identity,
2732           cli_cmd_flag_none,
2733           "<network id> <identity> = configure identity for an SSID" },
2734         { "password", wpa_cli_cmd_password,
2735           cli_cmd_flag_sensitive,
2736           "<network id> <password> = configure password for an SSID" },
2737         { "new_password", wpa_cli_cmd_new_password,
2738           cli_cmd_flag_sensitive,
2739           "<network id> <password> = change password for an SSID" },
2740         { "pin", wpa_cli_cmd_pin,
2741           cli_cmd_flag_sensitive,
2742           "<network id> <pin> = configure pin for an SSID" },
2743         { "otp", wpa_cli_cmd_otp,
2744           cli_cmd_flag_sensitive,
2745           "<network id> <password> = configure one-time-password for an SSID"
2746         },
2747         { "passphrase", wpa_cli_cmd_passphrase,
2748           cli_cmd_flag_sensitive,
2749           "<network id> <passphrase> = configure private key passphrase\n"
2750           "  for an SSID" },
2751         { "bssid", wpa_cli_cmd_bssid,
2752           cli_cmd_flag_none,
2753           "<network id> <BSSID> = set preferred BSSID for an SSID" },
2754         { "blacklist", wpa_cli_cmd_blacklist,
2755           cli_cmd_flag_none,
2756           "<BSSID> = add a BSSID to the blacklist\n"
2757           "blacklist clear = clear the blacklist\n"
2758           "blacklist = display the blacklist" },
2759         { "log_level", wpa_cli_cmd_log_level,
2760           cli_cmd_flag_none,
2761           "<level> [<timestamp>] = update the log level/timestamp\n"
2762           "log_level = display the current log level and log options" },
2763         { "list_networks", wpa_cli_cmd_list_networks,
2764           cli_cmd_flag_none,
2765           "= list configured networks" },
2766         { "select_network", wpa_cli_cmd_select_network,
2767           cli_cmd_flag_none,
2768           "<network id> = select a network (disable others)" },
2769         { "enable_network", wpa_cli_cmd_enable_network,
2770           cli_cmd_flag_none,
2771           "<network id> = enable a network" },
2772         { "disable_network", wpa_cli_cmd_disable_network,
2773           cli_cmd_flag_none,
2774           "<network id> = disable a network" },
2775         { "add_network", wpa_cli_cmd_add_network,
2776           cli_cmd_flag_none,
2777           "= add a network" },
2778         { "remove_network", wpa_cli_cmd_remove_network,
2779           cli_cmd_flag_none,
2780           "<network id> = remove a network" },
2781         { "set_network", wpa_cli_cmd_set_network,
2782           cli_cmd_flag_sensitive,
2783           "<network id> <variable> <value> = set network variables (shows\n"
2784           "  list of variables when run without arguments)" },
2785         { "get_network", wpa_cli_cmd_get_network,
2786           cli_cmd_flag_none,
2787           "<network id> <variable> = get network variables" },
2788         { "save_config", wpa_cli_cmd_save_config,
2789           cli_cmd_flag_none,
2790           "= save the current configuration" },
2791         { "disconnect", wpa_cli_cmd_disconnect,
2792           cli_cmd_flag_none,
2793           "= disconnect and wait for reassociate/reconnect command before\n"
2794           "  connecting" },
2795         { "reconnect", wpa_cli_cmd_reconnect,
2796           cli_cmd_flag_none,
2797           "= like reassociate, but only takes effect if already disconnected"
2798         },
2799         { "scan", wpa_cli_cmd_scan,
2800           cli_cmd_flag_none,
2801           "= request new BSS scan" },
2802         { "scan_results", wpa_cli_cmd_scan_results,
2803           cli_cmd_flag_none,
2804           "= get latest scan results" },
2805         { "bss", wpa_cli_cmd_bss,
2806           cli_cmd_flag_none,
2807           "<<idx> | <bssid>> = get detailed scan result info" },
2808         { "get_capability", wpa_cli_cmd_get_capability,
2809           cli_cmd_flag_none,
2810           "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2811         { "reconfigure", wpa_cli_cmd_reconfigure,
2812           cli_cmd_flag_none,
2813           "= force wpa_supplicant to re-read its configuration file" },
2814         { "terminate", wpa_cli_cmd_terminate,
2815           cli_cmd_flag_none,
2816           "= terminate wpa_supplicant" },
2817         { "interface_add", wpa_cli_cmd_interface_add,
2818           cli_cmd_flag_none,
2819           "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2820           "  <bridge_name> = adds new interface, all parameters but <ifname>\n"
2821           "  are optional" },
2822         { "interface_remove", wpa_cli_cmd_interface_remove,
2823           cli_cmd_flag_none,
2824           "<ifname> = removes the interface" },
2825         { "interface_list", wpa_cli_cmd_interface_list,
2826           cli_cmd_flag_none,
2827           "= list available interfaces" },
2828         { "ap_scan", wpa_cli_cmd_ap_scan,
2829           cli_cmd_flag_none,
2830           "<value> = set ap_scan parameter" },
2831         { "scan_interval", wpa_cli_cmd_scan_interval,
2832           cli_cmd_flag_none,
2833           "<value> = set scan_interval parameter (in seconds)" },
2834         { "bss_expire_age", wpa_cli_cmd_bss_expire_age,
2835           cli_cmd_flag_none,
2836           "<value> = set BSS expiration age parameter" },
2837         { "bss_expire_count", wpa_cli_cmd_bss_expire_count,
2838           cli_cmd_flag_none,
2839           "<value> = set BSS expiration scan count parameter" },
2840         { "stkstart", wpa_cli_cmd_stkstart,
2841           cli_cmd_flag_none,
2842           "<addr> = request STK negotiation with <addr>" },
2843         { "ft_ds", wpa_cli_cmd_ft_ds,
2844           cli_cmd_flag_none,
2845           "<addr> = request over-the-DS FT with <addr>" },
2846         { "wps_pbc", wpa_cli_cmd_wps_pbc,
2847           cli_cmd_flag_none,
2848           "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2849         { "wps_pin", wpa_cli_cmd_wps_pin,
2850           cli_cmd_flag_sensitive,
2851           "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2852           "hardcoded)" },
2853         { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
2854           cli_cmd_flag_sensitive,
2855           "<PIN> = verify PIN checksum" },
2856         { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
2857           "Cancels the pending WPS operation" },
2858 #ifdef CONFIG_WPS_OOB
2859         { "wps_oob", wpa_cli_cmd_wps_oob,
2860           cli_cmd_flag_sensitive,
2861           "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2862 #endif /* CONFIG_WPS_OOB */
2863         { "wps_reg", wpa_cli_cmd_wps_reg,
2864           cli_cmd_flag_sensitive,
2865           "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2866         { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin,
2867           cli_cmd_flag_sensitive,
2868           "[params..] = enable/disable AP PIN" },
2869         { "wps_er_start", wpa_cli_cmd_wps_er_start,
2870           cli_cmd_flag_none,
2871           "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2872         { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2873           cli_cmd_flag_none,
2874           "= stop Wi-Fi Protected Setup External Registrar" },
2875         { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2876           cli_cmd_flag_sensitive,
2877           "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2878         { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2879           cli_cmd_flag_none,
2880           "<UUID> = accept an Enrollee PBC using External Registrar" },
2881         { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2882           cli_cmd_flag_sensitive,
2883           "<UUID> <PIN> = learn AP configuration" },
2884         { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
2885           cli_cmd_flag_none,
2886           "<UUID> <network id> = set AP configuration for enrolling" },
2887         { "wps_er_config", wpa_cli_cmd_wps_er_config,
2888           cli_cmd_flag_sensitive,
2889           "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2890         { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2891           cli_cmd_flag_none,
2892           "<addr> = request RSN authentication with <addr> in IBSS" },
2893 #ifdef CONFIG_AP
2894         { "sta", wpa_cli_cmd_sta,
2895           cli_cmd_flag_none,
2896           "<addr> = get information about an associated station (AP)" },
2897         { "all_sta", wpa_cli_cmd_all_sta,
2898           cli_cmd_flag_none,
2899           "= get information about all associated stations (AP)" },
2900 #endif /* CONFIG_AP */
2901         { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2902           "= notification of suspend/hibernate" },
2903         { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2904           "= notification of resume/thaw" },
2905         { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2906           "= drop SA without deauth/disassoc (test command)" },
2907         { "roam", wpa_cli_cmd_roam,
2908           cli_cmd_flag_none,
2909           "<addr> = roam to the specified BSS" },
2910 #ifdef CONFIG_P2P
2911         { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2912           "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2913         { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2914           "= stop P2P Devices search" },
2915         { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2916           "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2917         { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2918           "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2919         { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2920           "<ifname> = remove P2P group interface (terminate group if GO)" },
2921         { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2922           "= add a new P2P group (local end as GO)" },
2923         { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2924           "<addr> <method> = request provisioning discovery" },
2925         { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2926           cli_cmd_flag_none,
2927           "= get the passphrase for a group (GO only)" },
2928         { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2929           cli_cmd_flag_none,
2930           "<addr> <TLVs> = schedule service discovery request" },
2931         { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2932           cli_cmd_flag_none,
2933           "<id> = cancel pending service discovery request" },
2934         { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2935           cli_cmd_flag_none,
2936           "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2937         { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2938           cli_cmd_flag_none,
2939           "= indicate change in local services" },
2940         { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2941           cli_cmd_flag_none,
2942           "<external> = set external processing of service discovery" },
2943         { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2944           cli_cmd_flag_none,
2945           "= remove all stored service entries" },
2946         { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2947           cli_cmd_flag_none,
2948           "<bonjour|upnp> <query|version> <response|service> = add a local "
2949           "service" },
2950         { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2951           cli_cmd_flag_none,
2952           "<bonjour|upnp> <query|version> [|service] = remove a local "
2953           "service" },
2954         { "p2p_reject", wpa_cli_cmd_p2p_reject,
2955           cli_cmd_flag_none,
2956           "<addr> = reject connection attempts from a specific peer" },
2957         { "p2p_invite", wpa_cli_cmd_p2p_invite,
2958           cli_cmd_flag_none,
2959           "<cmd> [peer=addr] = invite peer" },
2960         { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2961           "[discovered] = list known (optionally, only fully discovered) P2P "
2962           "peers" },
2963         { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2964           "<address> = show information about known P2P peer" },
2965         { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
2966           "<field> <value> = set a P2P parameter" },
2967         { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
2968           "= flush P2P state" },
2969         { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
2970           "= cancel P2P group formation" },
2971         { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none,
2972           "<address> = unauthorize a peer" },
2973         { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
2974           "[<duration> <interval>] [<duration> <interval>] = request GO "
2975           "presence" },
2976         { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
2977           "[<period> <interval>] = set extended listen timing" },
2978 #endif /* CONFIG_P2P */
2980 #ifdef CONFIG_INTERWORKING
2981         { "fetch_anqp", wpa_cli_cmd_fetch_anqp, cli_cmd_flag_none,
2982           "= fetch ANQP information for all APs" },
2983         { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, cli_cmd_flag_none,
2984           "= stop fetch_anqp operation" },
2985         { "interworking_select", wpa_cli_cmd_interworking_select,
2986           cli_cmd_flag_none,
2987           "[auto] = perform Interworking network selection" },
2988         { "interworking_connect", wpa_cli_cmd_interworking_connect,
2989           cli_cmd_flag_none,
2990           "<BSSID> = connect using Interworking credentials" },
2991         { "anqp_get", wpa_cli_cmd_anqp_get, cli_cmd_flag_none,
2992           "<addr> <info id>[,<info id>]... = request ANQP information" },
2993 #endif /* CONFIG_INTERWORKING */
2994         { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
2995           "<0/1> = disable/enable automatic reconnection" },
2996         { "tdls_discover", wpa_cli_cmd_tdls_discover,
2997           cli_cmd_flag_none,
2998           "<addr> = request TDLS discovery with <addr>" },
2999         { "tdls_setup", wpa_cli_cmd_tdls_setup,
3000           cli_cmd_flag_none,
3001           "<addr> = request TDLS setup with <addr>" },
3002         { "tdls_teardown", wpa_cli_cmd_tdls_teardown,
3003           cli_cmd_flag_none,
3004           "<addr> = tear down TDLS with <addr>" },
3005         { "signal_poll", wpa_cli_cmd_signal_poll,
3006           cli_cmd_flag_none,
3007           "= get signal parameters" },
3008         { "reauthenticate", wpa_cli_cmd_reauthenticate, cli_cmd_flag_none,
3009           "= trigger IEEE 802.1X/EAPOL reauthentication" },
3010         { NULL, NULL, cli_cmd_flag_none, NULL }
3011 };
3014 /*
3015  * Prints command usage, lines are padded with the specified string.
3016  */
3017 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
3019         char c;
3020         size_t n;
3022         printf("%s%s ", pad, cmd->cmd);
3023         for (n = 0; (c = cmd->usage[n]); n++) {
3024                 printf("%c", c);
3025                 if (c == '\n')
3026                         printf("%s", pad);
3027         }
3028         printf("\n");
3032 static void print_help(void)
3034         int n;
3035         printf("commands:\n");
3036         for (n = 0; wpa_cli_commands[n].cmd; n++)
3037                 print_cmd_help(&wpa_cli_commands[n], "  ");
3041 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
3043         const char *c, *delim;
3044         int n;
3045         size_t len;
3047         delim = os_strchr(cmd, ' ');
3048         if (delim)
3049                 len = delim - cmd;
3050         else
3051                 len = os_strlen(cmd);
3053         for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
3054                 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
3055                         return (wpa_cli_commands[n].flags &
3056                                 cli_cmd_flag_sensitive);
3057         }
3058         return 0;
3062 static char ** wpa_list_cmd_list(void)
3064         char **res;
3065         int i, count;
3067         count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
3068         res = os_zalloc(count * sizeof(char *));
3069         if (res == NULL)
3070                 return NULL;
3072         for (i = 0; wpa_cli_commands[i].cmd; i++) {
3073                 res[i] = os_strdup(wpa_cli_commands[i].cmd);
3074                 if (res[i] == NULL)
3075                         break;
3076         }
3078         return res;
3082 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
3083                                       int pos)
3085         int i;
3087         if (os_strcasecmp(cmd, "bss") == 0)
3088                 return wpa_cli_complete_bss(str, pos);
3089 #ifdef CONFIG_P2P
3090         if (os_strcasecmp(cmd, "p2p_connect") == 0)
3091                 return wpa_cli_complete_p2p_connect(str, pos);
3092         if (os_strcasecmp(cmd, "p2p_peer") == 0)
3093                 return wpa_cli_complete_p2p_peer(str, pos);
3094         if (os_strcasecmp(cmd, "p2p_group_remove") == 0)
3095                 return wpa_cli_complete_p2p_group_remove(str, pos);
3096 #endif /* CONFIG_P2P */
3098         for (i = 0; wpa_cli_commands[i].cmd; i++) {
3099                 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
3100                         edit_clear_line();
3101                         printf("\r%s\n", wpa_cli_commands[i].usage);
3102                         edit_redraw();
3103                         break;
3104                 }
3105         }
3107         return NULL;
3111 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
3113         char **res;
3114         const char *end;
3115         char *cmd;
3117         end = os_strchr(str, ' ');
3118         if (end == NULL || str + pos < end)
3119                 return wpa_list_cmd_list();
3121         cmd = os_malloc(pos + 1);
3122         if (cmd == NULL)
3123                 return NULL;
3124         os_memcpy(cmd, str, pos);
3125         cmd[end - str] = '\0';
3126         res = wpa_cli_cmd_completion(cmd, str, pos);
3127         os_free(cmd);
3128         return res;
3132 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3134         struct wpa_cli_cmd *cmd, *match = NULL;
3135         int count;
3136         int ret = 0;
3138         count = 0;
3139         cmd = wpa_cli_commands;
3140         while (cmd->cmd) {
3141                 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3142                 {
3143                         match = cmd;
3144                         if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3145                                 /* we have an exact match */
3146                                 count = 1;
3147                                 break;
3148                         }
3149                         count++;
3150                 }
3151                 cmd++;
3152         }
3154         if (count > 1) {
3155                 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3156                 cmd = wpa_cli_commands;
3157                 while (cmd->cmd) {
3158                         if (os_strncasecmp(cmd->cmd, argv[0],
3159                                            os_strlen(argv[0])) == 0) {
3160                                 printf(" %s", cmd->cmd);
3161                         }
3162                         cmd++;
3163                 }
3164                 printf("\n");
3165                 ret = 1;
3166         } else if (count == 0) {
3167                 printf("Unknown command '%s'\n", argv[0]);
3168                 ret = 1;
3169         } else {
3170                 ret = match->handler(ctrl, argc - 1, &argv[1]);
3171         }
3173         return ret;
3177 static int str_match(const char *a, const char *b)
3179         return os_strncmp(a, b, os_strlen(b)) == 0;
3183 static int wpa_cli_exec(const char *program, const char *arg1,
3184                         const char *arg2)
3186         char *cmd;
3187         size_t len;
3188         int res;
3189         int ret = 0;
3191         len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
3192         cmd = os_malloc(len);
3193         if (cmd == NULL)
3194                 return -1;
3195         res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
3196         if (res < 0 || (size_t) res >= len) {
3197                 os_free(cmd);
3198                 return -1;
3199         }
3200         cmd[len - 1] = '\0';
3201 #ifndef _WIN32_WCE
3202         if (system(cmd) < 0)
3203                 ret = -1;
3204 #endif /* _WIN32_WCE */
3205         os_free(cmd);
3207         return ret;
3211 static void wpa_cli_action_process(const char *msg)
3213         const char *pos;
3214         char *copy = NULL, *id, *pos2;
3216         pos = msg;
3217         if (*pos == '<') {
3218                 /* skip priority */
3219                 pos = os_strchr(pos, '>');
3220                 if (pos)
3221                         pos++;
3222                 else
3223                         pos = msg;
3224         }
3226         if (str_match(pos, WPA_EVENT_CONNECTED)) {
3227                 int new_id = -1;
3228                 os_unsetenv("WPA_ID");
3229                 os_unsetenv("WPA_ID_STR");
3230                 os_unsetenv("WPA_CTRL_DIR");
3232                 pos = os_strstr(pos, "[id=");
3233                 if (pos)
3234                         copy = os_strdup(pos + 4);
3236                 if (copy) {
3237                         pos2 = id = copy;
3238                         while (*pos2 && *pos2 != ' ')
3239                          &n