2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
17 #ifdef CONFIG_CTRL_IFACE
19 #ifdef CONFIG_CTRL_IFACE_UNIX
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"
30 #include <cutils/properties.h>
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"
46 "Redistribution and use in source and binary forms, with or without\n"
47 "modification, are permitted provided that the following conditions are\n"
50 "1. Redistributions of source code must retain the above copyright\n"
51 " notice, this list of conditions and the following disclaimer.\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"
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"
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"
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
{
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>] "
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 "
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");
122 static void cli_txt_list_free(struct cli_txt_entry
*e
)
124 dl_list_del(&e
->list
);
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
,
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)
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
);
155 cli_txt_list_free(e
);
159 static void cli_txt_list_del_addr(struct dl_list
*txt_list
, const char *txt
)
163 if (hwaddr_aton(txt
, addr
) < 0)
165 os_snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
166 cli_txt_list_del(txt_list
, buf
);
171 static void cli_txt_list_del_word(struct dl_list
*txt_list
, const char *txt
)
175 end
= os_strchr(txt
, ' ');
177 end
= txt
+ os_strlen(txt
);
178 buf
= os_malloc(end
- txt
+ 1);
181 os_memcpy(buf
, txt
, end
- txt
);
182 buf
[end
- txt
] = '\0';
183 cli_txt_list_del(txt_list
, 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
);
195 e
= os_zalloc(sizeof(*e
));
198 e
->txt
= os_strdup(txt
);
199 if (e
->txt
== NULL
) {
203 dl_list_add(txt_list
, &e
->list
);
209 static int cli_txt_list_add_addr(struct dl_list
*txt_list
, const char *txt
)
213 if (hwaddr_aton(txt
, addr
) < 0)
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
)
225 end
= os_strchr(txt
, ' ');
227 end
= txt
+ os_strlen(txt
);
228 buf
= os_malloc(end
- txt
+ 1);
231 os_memcpy(buf
, txt
, end
- txt
);
232 buf
[end
- txt
] = '\0';
233 ret
= cli_txt_list_add(txt_list
, buf
);
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
);
244 struct cli_txt_entry
*e
;
246 res
= os_zalloc((count
+ 1) * sizeof(char *));
251 dl_list_for_each(e
, txt_list
, struct cli_txt_entry
, list
) {
252 res
[i
] = os_strdup(e
->txt
);
262 static int get_cmd_arg_num(const char *str
, int pos
)
266 for (i
= 0; i
<= pos
; i
++) {
269 while (i
<= pos
&& str
[i
] != ' ')
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
)
290 start
= os_strchr(event
, '>');
296 * Skip BSS added/removed events since they can be relatively frequent
297 * and are likely of not much use for an interactive user.
299 if (str_starts(start
, WPA_EVENT_BSS_ADDED
) ||
300 str_starts(start
, WPA_EVENT_BSS_REMOVED
))
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
)
314 if (attach
&& interactive
)
315 mon_conn
= wpa_ctrl_open(ifname
);
318 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
326 if (access(ctrl_iface_dir
, F_OK
) < 0) {
327 cfile
= os_strdup(ifname
);
334 flen
= os_strlen(ctrl_iface_dir
) + os_strlen(ifname
) + 2;
335 cfile
= os_malloc(flen
);
338 res
= os_snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
,
340 if (res
< 0 || res
>= flen
) {
346 ctrl_conn
= wpa_ctrl_open(cfile
);
347 if (ctrl_conn
== NULL
) {
352 if (attach
&& interactive
)
353 mon_conn
= wpa_ctrl_open(cfile
);
357 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
360 if (wpa_ctrl_attach(mon_conn
) == 0) {
361 wpa_cli_attached
= 1;
363 eloop_register_read_sock(
364 wpa_ctrl_get_fd(mon_conn
),
365 wpa_cli_mon_receive
, NULL
, NULL
);
367 printf("Warning: Failed to attach to "
368 "wpa_supplicant.\n");
377 static void wpa_cli_close_connection(void)
379 if (ctrl_conn
== NULL
)
382 if (wpa_cli_attached
) {
383 wpa_ctrl_detach(interactive
? mon_conn
: ctrl_conn
);
384 wpa_cli_attached
= 0;
386 wpa_ctrl_close(ctrl_conn
);
389 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn
));
390 wpa_ctrl_close(mon_conn
);
396 static void wpa_cli_msg_cb(char *msg
, size_t len
)
402 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
408 if (ctrl_conn
== NULL
) {
409 printf("Not connected to wpa_supplicant - command dropped.\n");
412 len
= sizeof(buf
) - 1;
413 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
416 printf("'%s' command timed out.\n", cmd
);
418 } else if (ret
< 0) {
419 printf("'%s' command failed.\n", cmd
);
425 if (interactive
&& len
> 0 && buf
[len
- 1] != '\n')
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
[])
466 ret
= os_snprintf(cmd
, sizeof(cmd
), "NOTE %s", argv
[0]);
467 if (ret
< 0 || (size_t) ret
>= sizeof(cmd
))
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
[])
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
);
499 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
508 static void wpa_cli_show_variables(void)
510 printf("set variables:\n"
511 " EAPOL::heldPeriod (EAPOL state machine held period, "
513 " EAPOL::authPeriod (EAPOL state machine authentication "
514 "period, in seconds)\n"
515 " EAPOL::startPeriod (EAPOL state machine start period, in "
517 " EAPOL::maxStart (EAPOL state machine maximum start "
519 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
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
[])
534 wpa_cli_show_variables();
538 if (argc
!= 1 && argc
!= 2) {
539 printf("Invalid SET command: needs two arguments (variable "
540 "name and value)\n");
545 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s ", argv
[0]);
547 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s",
549 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
550 printf("Too long SET command.\n");
553 return wpa_ctrl_command(ctrl
, cmd
);
557 static int wpa_cli_cmd_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
563 printf("Invalid GET command: need one argument (variable "
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");
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
,
592 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
596 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
603 printf("Invalid PREAUTH command: needs one argument "
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");
613 return wpa_ctrl_command(ctrl
, cmd
);
617 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
623 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
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");
632 return wpa_ctrl_command(ctrl
, cmd
);
636 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl
*ctrl
, int argc
,
643 printf("Invalid SCAN_INTERVAL command: needs one argument "
644 "scan_interval value)\n");
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");
652 return wpa_ctrl_command(ctrl
, cmd
);
656 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl
*ctrl
, int argc
,
663 printf("Invalid BSS_EXPIRE_AGE command: needs one argument "
664 "(bss_expire_age value)\n");
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");
672 return wpa_ctrl_command(ctrl
, cmd
);
676 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl
*ctrl
, int argc
,
683 printf("Invalid BSS_EXPIRE_COUNT command: needs one argument "
684 "(bss_expire_count value)\n");
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");
692 return wpa_ctrl_command(ctrl
, cmd
);
696 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
703 printf("Invalid STKSTART command: needs one argument "
704 "(Peer STA MAC address)\n");
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");
713 return wpa_ctrl_command(ctrl
, cmd
);
717 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
723 printf("Invalid FT_DS command: needs one argument "
724 "(Target AP MAC address)\n");
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");
733 return wpa_ctrl_command(ctrl
, cmd
);
737 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
744 return wpa_ctrl_command(ctrl
, "WPS_PBC");
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");
753 return wpa_ctrl_command(ctrl
, cmd
);
757 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
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 "
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");
777 return wpa_ctrl_command(ctrl
, cmd
);
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");
786 return wpa_ctrl_command(ctrl
, cmd
);
790 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl
*ctrl
, int argc
,
796 if (argc
!= 1 && argc
!= 2) {
797 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
798 "- PIN to be verified\n");
803 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s %s",
806 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_CHECK_PIN %s",
808 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
809 printf("Too long WPS_CHECK_PIN command.\n");
812 return wpa_ctrl_command(ctrl
, cmd
);
816 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl
*ctrl
, int argc
,
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
[])
829 if (argc
!= 3 && argc
!= 4) {
830 printf("Invalid WPS_OOB command: need three or four "
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', "
836 "- DEV_NAME: (only for NFC) device name like "
842 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_OOB %s %s %s",
843 argv
[0], argv
[1], argv
[2]);
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");
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
[])
862 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
864 else if (argc
== 5 || argc
== 6) {
865 char ssid_hex
[2 * 32 + 1];
866 char key_hex
[2 * 64 + 1];
870 for (i
= 0; i
< 32; i
++) {
871 if (argv
[2][i
] == '\0')
873 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
878 for (i
= 0; i
< 64; i
++) {
879 if (argv
[5][i
] == '\0')
881 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
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],
891 printf("Invalid WPS_REG command: need two arguments:\n"
892 "- BSSID of the target AP\n"
894 printf("Alternatively, six arguments can be used to "
895 "reconfigure the AP:\n"
896 "- BSSID of the target AP\n"
899 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
900 "- new encr (NONE, WEP, TKIP, CCMP)\n"
905 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
906 printf("Too long WPS_REG command.\n");
909 return wpa_ctrl_command(ctrl
, cmd
);
913 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl
*ctrl
, int argc
,
920 printf("Invalid WPS_AP_PIN command: needs at least one "
926 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s %s %s",
927 argv
[0], argv
[1], argv
[2]);
929 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s %s",
932 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_AP_PIN %s",
934 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
935 printf("Too long WPS_AP_PIN command.\n");
938 return wpa_ctrl_command(ctrl
, cmd
);
942 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
947 os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_START %s", argv
[0]);
948 return wpa_ctrl_command(ctrl
, cmd
);
950 return wpa_ctrl_command(ctrl
, "WPS_ER_START");
954 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
957 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
962 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
969 printf("Invalid WPS_ER_PIN command: need at least two "
971 "- UUID: use 'any' to select any\n"
972 "- PIN: Enrollee PIN\n"
973 "optional: - Enrollee MAC address\n");
978 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s %s",
979 argv
[0], argv
[1], argv
[2]);
981 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PIN %s %s",
983 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
984 printf("Too long WPS_ER_PIN command.\n");
987 return wpa_ctrl_command(ctrl
, cmd
);
991 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
998 printf("Invalid WPS_ER_PBC command: need one argument:\n"
999 "- UUID: Specify the Enrollee\n");
1003 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_PBC %s",
1005 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1006 printf("Too long WPS_ER_PBC command.\n");
1009 return wpa_ctrl_command(ctrl
, cmd
);
1013 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
1020 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1021 "- UUID: specify which AP to use\n"
1026 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_LEARN %s %s",
1028 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1029 printf("Too long WPS_ER_LEARN command.\n");
1032 return wpa_ctrl_command(ctrl
, cmd
);
1036 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl
*ctrl
, int argc
,
1043 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1045 "- UUID: specify which AP to use\n"
1046 "- Network configuration id\n");
1050 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_ER_SET_CONFIG %s %s",
1052 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1053 printf("Too long WPS_ER_SET_CONFIG command.\n");
1056 return wpa_ctrl_command(ctrl
, cmd
);
1060 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl
*ctrl
, int argc
,
1066 if (argc
== 5 || argc
== 6) {
1067 char ssid_hex
[2 * 32 + 1];
1068 char key_hex
[2 * 64 + 1];
1072 for (i
= 0; i
< 32; i
++) {
1073 if (argv
[2][i
] == '\0')
1075 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
1080 for (i
= 0; i
< 64; i
++) {
1081 if (argv
[5][i
] == '\0')
1083 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
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],
1093 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1097 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1098 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1103 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1104 printf("Too long WPS_ER_CONFIG command.\n");
1107 return wpa_ctrl_command(ctrl
, cmd
);
1111 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1117 printf("Invalid IBSS_RSN command: needs one argument "
1118 "(Peer STA MAC address)\n");
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");
1127 return wpa_ctrl_command(ctrl
, cmd
);
1131 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1137 printf("Invalid LEVEL command: needs one argument (debug "
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");
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
;
1156 printf("Invalid IDENTITY command: needs two arguments "
1157 "(network id and identity)\n");
1161 end
= cmd
+ sizeof(cmd
);
1163 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
1165 if (ret
< 0 || ret
>= end
- pos
) {
1166 printf("Too long IDENTITY command.\n");
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");
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
;
1189 printf("Invalid PASSWORD command: needs two arguments "
1190 "(network id and password)\n");
1194 end
= cmd
+ sizeof(cmd
);
1196 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
1198 if (ret
< 0 || ret
>= end
- pos
) {
1199 printf("Too long PASSWORD command.\n");
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");
1212 return wpa_ctrl_command(ctrl
, cmd
);
1216 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
1219 char cmd
[256], *pos
, *end
;
1223 printf("Invalid NEW_PASSWORD command: needs two arguments "
1224 "(network id and password)\n");
1228 end
= cmd
+ sizeof(cmd
);
1230 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
1232 if (ret
< 0 || ret
>= end
- pos
) {
1233 printf("Too long NEW_PASSWORD command.\n");
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");
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
;
1256 printf("Invalid PIN command: needs two arguments "
1257 "(network id and pin)\n");
1261 end
= cmd
+ sizeof(cmd
);
1263 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
1265 if (ret
< 0 || ret
>= end
- pos
) {
1266 printf("Too long PIN command.\n");
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");
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
;
1288 printf("Invalid OTP command: needs two arguments (network "
1289 "id and password)\n");
1293 end
= cmd
+ sizeof(cmd
);
1295 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
1297 if (ret
< 0 || ret
>= end
- pos
) {
1298 printf("Too long OTP command.\n");
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");
1311 return wpa_ctrl_command(ctrl
, cmd
);
1315 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1318 char cmd
[256], *pos
, *end
;
1322 printf("Invalid PASSPHRASE command: needs two arguments "
1323 "(network id and passphrase)\n");
1327 end
= cmd
+ sizeof(cmd
);
1329 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
1331 if (ret
< 0 || ret
>= end
- pos
) {
1332 printf("Too long PASSPHRASE command.\n");
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");
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
;
1355 printf("Invalid BSSID command: needs two arguments (network "
1360 end
= cmd
+ sizeof(cmd
);
1362 ret
= os_snprintf(pos
, end
- pos
, "BSSID");
1363 if (ret
< 0 || ret
>= end
- pos
) {
1364 printf("Too long BSSID command.\n");
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");
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
;
1386 end
= cmd
+ sizeof(cmd
);
1388 ret
= os_snprintf(pos
, end
- pos
, "BLACKLIST");
1389 if (ret
< 0 || ret
>= end
- pos
) {
1390 printf("Too long BLACKLIST command.\n");
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");
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
;
1412 end
= cmd
+ sizeof(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");
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");
1429 return wpa_ctrl_command(ctrl
, cmd
);
1433 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
1436 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
1440 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
1447 printf("Invalid SELECT_NETWORK command: needs one argument "
1452 res
= os_snprintf(cmd
, sizeof(cmd
), "SELECT_NETWORK %s", argv
[0]);
1453 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
,
1468 printf("Invalid ENABLE_NETWORK command: needs one argument "
1473 res
= os_snprintf(cmd
, sizeof(cmd
), "ENABLE_NETWORK %s", argv
[0]);
1474 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
,
1489 printf("Invalid DISABLE_NETWORK command: needs one argument "
1494 res
= os_snprintf(cmd
, sizeof(cmd
), "DISABLE_NETWORK %s", argv
[0]);
1495 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
,
1506 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
1510 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
1517 printf("Invalid REMOVE_NETWORK command: needs one argument "
1522 res
= os_snprintf(cmd
, sizeof(cmd
), "REMOVE_NETWORK %s", argv
[0]);
1523 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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"
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 "
1545 "For example: set_network 1 ssid \"network name\"\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
,
1559 wpa_cli_show_network_variables();
1564 printf("Invalid SET_NETWORK command: needs three arguments\n"
1565 "(network id, variable name, and value)\n");
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");
1575 return wpa_ctrl_command(ctrl
, cmd
);
1579 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1586 wpa_cli_show_network_variables();
1591 printf("Invalid GET_NETWORK command: needs two arguments\n"
1592 "(network id and variable name)\n");
1596 res
= os_snprintf(cmd
, sizeof(cmd
), "GET_NETWORK %s %s",
1598 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1599 printf("Too long GET_NETWORK command.\n");
1602 return wpa_ctrl_command(ctrl
, cmd
);
1606 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1609 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1613 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1616 return wpa_ctrl_command(ctrl
, "RECONNECT");
1620 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
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
,
1636 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1640 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1646 printf("Invalid BSS command: need one argument (index or "
1651 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS %s", argv
[0]);
1652 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
);
1667 res
= cli_txt_list_array(&bsses
);
1675 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1681 if (argc
< 1 || argc
> 2) {
1682 printf("Invalid GET_CAPABILITY command: need either one or "
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");
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
))
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
[])
1713 wpa_cli_list_interfaces(ctrl
);
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
);
1724 printf("Could not connect to interface '%s' - re-trying\n",
1731 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1734 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1738 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1741 return wpa_ctrl_command(ctrl
, "TERMINATE");
1745 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
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");
1760 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1761 * <driver_param>TAB<bridge_name>
1763 res
= os_snprintf(cmd
, sizeof(cmd
),
1764 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
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
))
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
,
1783 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1784 "(interface name)\n");
1788 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERFACE_REMOVE %s", argv
[0]);
1789 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
,
1799 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1804 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1808 printf("Invalid 'sta' command - exactly one argument, STA "
1809 "address, is required.\n");
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
;
1824 if (ctrl_conn
== NULL
) {
1825 printf("Not connected to hostapd - command dropped.\n");
1828 len
= sizeof(buf
) - 1;
1829 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
1832 printf("'%s' command timed out.\n", cmd
);
1834 } else if (ret
< 0) {
1835 printf("'%s' command failed.\n", cmd
);
1840 if (memcmp(buf
, "FAIL", 4) == 0)
1845 while (*pos
!= '\0' && *pos
!= '\n')
1848 os_strlcpy(addr
, buf
, addr_len
);
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
)))
1860 os_snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1861 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
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
[])
1892 printf("Invalid ROAM command: needs one argument "
1893 "(target AP's BSSID)\n");
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");
1902 return wpa_ctrl_command(ctrl
, cmd
);
1908 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1914 return wpa_ctrl_command(ctrl
, "P2P_FIND");
1917 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s %s %s",
1918 argv
[0], argv
[1], argv
[2]);
1920 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s %s",
1923 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_FIND %s", argv
[0]);
1924 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
,
1934 return wpa_ctrl_command(ctrl
, "P2P_STOP_FIND");
1938 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl
*ctrl
, int argc
,
1945 printf("Invalid P2P_CONNECT command: needs at least two "
1946 "arguments (address and pbc/PIN)\n");
1951 res
= os_snprintf(cmd
, sizeof(cmd
),
1952 "P2P_CONNECT %s %s %s %s %s",
1953 argv
[0], argv
[1], argv
[2], argv
[3],
1956 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s %s",
1957 argv
[0], argv
[1], argv
[2], argv
[3]);
1959 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s %s",
1960 argv
[0], argv
[1], argv
[2]);
1962 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_CONNECT %s %s",
1964 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
);
1978 res
= cli_txt_list_array(&p2p_peers
);
1986 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl
*ctrl
, int argc
,
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
))
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
,
2010 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
2011 "(interface name)\n");
2015 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_REMOVE %s", argv
[0]);
2016 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
);
2030 res
= cli_txt_list_array(&p2p_groups
);
2038 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl
*ctrl
, int argc
,
2045 return wpa_ctrl_command(ctrl
, "P2P_GROUP_ADD");
2048 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_ADD %s %s",
2051 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_GROUP_ADD %s",
2053 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
,
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");
2074 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PROV_DISC %s %s %s",
2075 argv
[0], argv
[1], argv
[2]);
2077 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PROV_DISC %s %s",
2079 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
,
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
,
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 "
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]);
2112 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_REQ %s %s",
2114 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
[])
2128 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
2129 "argument (pending request identifier)\n");
2133 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_CANCEL_REQ %s",
2135 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
,
2149 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2150 "arguments (freq, address, dialog token, and TLVs)\n");
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
))
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
,
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
[])
2177 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
2178 "argument (external processing: 0/1)\n");
2182 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_EXTERNAL %s",
2184 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
,
2194 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_FLUSH");
2198 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl
*ctrl
, int argc
,
2204 if (argc
!= 3 && argc
!= 4) {
2205 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
2211 res
= os_snprintf(cmd
, sizeof(cmd
),
2212 "P2P_SERVICE_ADD %s %s %s %s",
2213 argv
[0], argv
[1], argv
[2], argv
[3]);
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
))
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
,
2231 if (argc
!= 2 && argc
!= 3) {
2232 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2238 res
= os_snprintf(cmd
, sizeof(cmd
),
2239 "P2P_SERVICE_DEL %s %s %s",
2240 argv
[0], argv
[1], argv
[2]);
2242 res
= os_snprintf(cmd
, sizeof(cmd
),
2243 "P2P_SERVICE_DEL %s %s",
2245 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
[])
2259 printf("Invalid P2P_REJECT command: needs one argument "
2260 "(peer address)\n");
2264 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_REJECT %s", argv
[0]);
2265 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
[])
2279 printf("Invalid P2P_INVITE command: needs at least one "
2285 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s %s",
2286 argv
[0], argv
[1], argv
[2]);
2288 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s %s",
2291 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_INVITE %s", argv
[0]);
2292 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
[])
2303 printf("Invalid 'p2p_peer' command - exactly one argument, "
2304 "P2P peer device address, is required.\n");
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
);
2319 res
= cli_txt_list_array(&p2p_peers
);
2327 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl
*ctrl
, char *cmd
,
2328 char *addr
, size_t addr_len
,
2331 char buf
[4096], *pos
;
2335 if (ctrl_conn
== NULL
)
2337 len
= sizeof(buf
) - 1;
2338 ret
= wpa_ctrl_request(ctrl
, cmd
, strlen(cmd
), buf
, &len
,
2341 printf("'%s' command timed out.\n", cmd
);
2343 } else if (ret
< 0) {
2344 printf("'%s' command failed.\n", cmd
);
2349 if (memcmp(buf
, "FAIL", 4) == 0)
2353 while (*pos
!= '\0' && *pos
!= '\n')
2356 os_strlcpy(addr
, buf
, addr_len
);
2357 if (!discovered
|| os_strstr(pos
, "[PROBE_REQ_ONLY]") == NULL
)
2358 printf("%s\n", addr
);
2363 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2365 char addr
[32], cmd
[64];
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
))
2374 os_snprintf(cmd
, sizeof(cmd
), "P2P_PEER NEXT-%s", addr
);
2375 } while (wpa_ctrl_command_p2p_peer(ctrl
, cmd
, addr
, sizeof(addr
),
2382 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2388 printf("Invalid P2P_SET command: needs two arguments (field, "
2393 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SET %s %s", argv
[0], argv
[1]);
2394 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
,
2410 return wpa_ctrl_command(ctrl
, "P2P_CANCEL");
2414 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl
*ctrl
, int argc
,
2421 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2422 "(peer address)\n");
2426 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_UNAUTHORIZE %s", argv
[0]);
2428 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
,
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");
2451 res
= os_snprintf(cmd
, sizeof(cmd
),
2452 "P2P_PRESENCE_REQ %s %s %s %s",
2453 argv
[0], argv
[1], argv
[2], argv
[3]);
2455 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ %s %s",
2458 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_PRESENCE_REQ");
2459 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
,
2472 if (argc
!= 0 && argc
!= 2) {
2473 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2474 "(availability period, availability interval; in "
2476 "Extended Listen Timing can be cancelled with this "
2477 "command when used without parameters.\n");
2482 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN %s %s",
2485 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_EXT_LISTEN");
2486 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
,
2499 return wpa_ctrl_command(ctrl
, "FETCH_ANQP");
2503 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2506 return wpa_ctrl_command(ctrl
, "STOP_FETCH_ANQP");
2510 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl
*ctrl
, int argc
,
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
))
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
,
2534 printf("Invalid INTERWORKING_CONNECT commands: needs one "
2535 "argument (BSSID)\n");
2539 res
= os_snprintf(cmd
, sizeof(cmd
), "INTERWORKING_CONNECT %s",
2541 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
[])
2554 printf("Invalid ANQP_GET command: needs two arguments "
2555 "(addr and info id list)\n");
2559 res
= os_snprintf(cmd
, sizeof(cmd
), "ANQP_GET %s %s",
2561 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
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
,
2576 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2577 "(0/1 = disable/enable automatic reconnection)\n");
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");
2585 return wpa_ctrl_command(ctrl
, cmd
);
2589 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl
*ctrl
, int argc
,
2596 printf("Invalid TDLS_DISCOVER command: needs one argument "
2597 "(Peer STA MAC address)\n");
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");
2606 return wpa_ctrl_command(ctrl
, cmd
);
2610 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl
*ctrl
, int argc
,
2617 printf("Invalid TDLS_SETUP command: needs one argument "
2618 "(Peer STA MAC address)\n");
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");
2627 return wpa_ctrl_command(ctrl
, cmd
);
2631 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl
*ctrl
, int argc
,
2638 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2639 "(Peer STA MAC address)\n");
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");
2648 return wpa_ctrl_command(ctrl
, cmd
);
2652 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl
*ctrl
, int argc
,
2655 return wpa_ctrl_command(ctrl
, "SIGNAL_POLL");
2659 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
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
2671 struct wpa_cli_cmd
{
2673 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
2674 enum wpa_cli_cmd_flags flags
;
2678 static struct wpa_cli_cmd wpa_cli_commands
[] = {
2679 { "status", wpa_cli_cmd_status
,
2681 "[verbose] = get current WPA/EAPOL/EAP status" },
2682 { "ping", wpa_cli_cmd_ping
,
2684 "= pings wpa_supplicant" },
2685 { "relog", wpa_cli_cmd_relog
,
2687 "= re-open log-file (allow rolling logs)" },
2688 { "note", wpa_cli_cmd_note
,
2690 "<text> = add a note to wpa_supplicant debug log" },
2691 { "mib", wpa_cli_cmd_mib
,
2693 "= get MIB variables (dot1x, dot11)" },
2694 { "help", wpa_cli_cmd_help
,
2696 "= show this usage help" },
2697 { "interface", wpa_cli_cmd_interface
,
2699 "[ifname] = show interfaces/select interface" },
2700 { "level", wpa_cli_cmd_level
,
2702 "<debug level> = change debug level" },
2703 { "license", wpa_cli_cmd_license
,
2705 "= show full wpa_cli license" },
2706 { "quit", wpa_cli_cmd_quit
,
2709 { "set", wpa_cli_cmd_set
,
2711 "= set variables (shows list of variables when run without "
2713 { "get", wpa_cli_cmd_get
,
2715 "<name> = get information" },
2716 { "logon", wpa_cli_cmd_logon
,
2718 "= IEEE 802.1X EAPOL state machine logon" },
2719 { "logoff", wpa_cli_cmd_logoff
,
2721 "= IEEE 802.1X EAPOL state machine logoff" },
2722 { "pmksa", wpa_cli_cmd_pmksa
,
2724 "= show PMKSA cache" },
2725 { "reassociate", wpa_cli_cmd_reassociate
,
2727 "= force reassociation" },
2728 { "preauthenticate", wpa_cli_cmd_preauthenticate
,
2730 "<BSSID> = force preauthentication" },
2731 { "identity", wpa_cli_cmd_identity
,
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"
2747 { "passphrase", wpa_cli_cmd_passphrase
,
2748 cli_cmd_flag_sensitive
,
2749 "<network id> <passphrase> = configure private key passphrase\n"
2751 { "bssid", wpa_cli_cmd_bssid
,
2753 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2754 { "blacklist", wpa_cli_cmd_blacklist
,
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
,
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
,
2765 "= list configured networks" },
2766 { "select_network", wpa_cli_cmd_select_network
,
2768 "<network id> = select a network (disable others)" },
2769 { "enable_network", wpa_cli_cmd_enable_network
,
2771 "<network id> = enable a network" },
2772 { "disable_network", wpa_cli_cmd_disable_network
,
2774 "<network id> = disable a network" },
2775 { "add_network", wpa_cli_cmd_add_network
,
2777 "= add a network" },
2778 { "remove_network", wpa_cli_cmd_remove_network
,
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
,
2787 "<network id> <variable> = get network variables" },
2788 { "save_config", wpa_cli_cmd_save_config
,
2790 "= save the current configuration" },
2791 { "disconnect", wpa_cli_cmd_disconnect
,
2793 "= disconnect and wait for reassociate/reconnect command before\n"
2795 { "reconnect", wpa_cli_cmd_reconnect
,
2797 "= like reassociate, but only takes effect if already disconnected"
2799 { "scan", wpa_cli_cmd_scan
,
2801 "= request new BSS scan" },
2802 { "scan_results", wpa_cli_cmd_scan_results
,
2804 "= get latest scan results" },
2805 { "bss", wpa_cli_cmd_bss
,
2807 "<<idx> | <bssid>> = get detailed scan result info" },
2808 { "get_capability", wpa_cli_cmd_get_capability
,
2810 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2811 { "reconfigure", wpa_cli_cmd_reconfigure
,
2813 "= force wpa_supplicant to re-read its configuration file" },
2814 { "terminate", wpa_cli_cmd_terminate
,
2816 "= terminate wpa_supplicant" },
2817 { "interface_add", wpa_cli_cmd_interface_add
,
2819 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2820 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2822 { "interface_remove", wpa_cli_cmd_interface_remove
,
2824 "<ifname> = removes the interface" },
2825 { "interface_list", wpa_cli_cmd_interface_list
,
2827 "= list available interfaces" },
2828 { "ap_scan", wpa_cli_cmd_ap_scan
,
2830 "<value> = set ap_scan parameter" },
2831 { "scan_interval", wpa_cli_cmd_scan_interval
,
2833 "<value> = set scan_interval parameter (in seconds)" },
2834 { "bss_expire_age", wpa_cli_cmd_bss_expire_age
,
2836 "<value> = set BSS expiration age parameter" },
2837 { "bss_expire_count", wpa_cli_cmd_bss_expire_count
,
2839 "<value> = set BSS expiration scan count parameter" },
2840 { "stkstart", wpa_cli_cmd_stkstart
,
2842 "<addr> = request STK negotiation with <addr>" },
2843 { "ft_ds", wpa_cli_cmd_ft_ds
,
2845 "<addr> = request over-the-DS FT with <addr>" },
2846 { "wps_pbc", wpa_cli_cmd_wps_pbc
,
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 "
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
,
2871 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2872 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
,
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
,
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
,
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
,
2892 "<addr> = request RSN authentication with <addr> in IBSS" },
2894 { "sta", wpa_cli_cmd_sta
,
2896 "<addr> = get information about an associated station (AP)" },
2897 { "all_sta", wpa_cli_cmd_all_sta
,
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
,
2909 "<addr> = roam to the specified BSS" },
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
,
2927 "= get the passphrase for a group (GO only)" },
2928 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req
,
2930 "<addr> <TLVs> = schedule service discovery request" },
2931 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req
,
2933 "<id> = cancel pending service discovery request" },
2934 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp
,
2936 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2937 { "p2p_service_update", wpa_cli_cmd_p2p_service_update
,
2939 "= indicate change in local services" },
2940 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external
,
2942 "<external> = set external processing of service discovery" },
2943 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush
,
2945 "= remove all stored service entries" },
2946 { "p2p_service_add", wpa_cli_cmd_p2p_service_add
,
2948 "<bonjour|upnp> <query|version> <response|service> = add a local "
2950 { "p2p_service_del", wpa_cli_cmd_p2p_service_del
,
2952 "<bonjour|upnp> <query|version> [|service] = remove a local "
2954 { "p2p_reject", wpa_cli_cmd_p2p_reject
,
2956 "<addr> = reject connection attempts from a specific peer" },
2957 { "p2p_invite", wpa_cli_cmd_p2p_invite
,
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 "
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 "
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
,
2987 "[auto] = perform Interworking network selection" },
2988 { "interworking_connect", wpa_cli_cmd_interworking_connect
,
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
,
2998 "<addr> = request TDLS discovery with <addr>" },
2999 { "tdls_setup", wpa_cli_cmd_tdls_setup
,
3001 "<addr> = request TDLS setup with <addr>" },
3002 { "tdls_teardown", wpa_cli_cmd_tdls_teardown
,
3004 "<addr> = tear down TDLS with <addr>" },
3005 { "signal_poll", wpa_cli_cmd_signal_poll
,
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
}
3015 * Prints command usage, lines are padded with the specified string.
3017 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
3022 printf("%s%s ", pad
, cmd
->cmd
);
3023 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
3032 static void print_help(void)
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
;
3047 delim
= os_strchr(cmd
, ' ');
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
);
3062 static char ** wpa_list_cmd_list(void)
3067 count
= sizeof(wpa_cli_commands
) / sizeof(wpa_cli_commands
[0]);
3068 res
= os_zalloc(count
* sizeof(char *));
3072 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
3073 res
[i
] = os_strdup(wpa_cli_commands
[i
].cmd
);
3082 static char ** wpa_cli_cmd_completion(const char *cmd
, const char *str
,
3087 if (os_strcasecmp(cmd
, "bss") == 0)
3088 return wpa_cli_complete_bss(str
, pos
);
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) {
3101 printf("\r%s\n", wpa_cli_commands
[i
].usage
);
3111 static char ** wpa_cli_edit_completion_cb(void *ctx
, const char *str
, int pos
)
3117 end
= os_strchr(str
, ' ');
3118 if (end
== NULL
|| str
+ pos
< end
)
3119 return wpa_list_cmd_list();
3121 cmd
= os_malloc(pos
+ 1);
3124 os_memcpy(cmd
, str
, pos
);
3125 cmd
[end
- str
] = '\0';
3126 res
= wpa_cli_cmd_completion(cmd
, str
, pos
);
3132 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
3134 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
3139 cmd
= wpa_cli_commands
;
3141 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
3144 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
3145 /* we have an exact match */
3155 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
3156 cmd
= wpa_cli_commands
;
3158 if (os_strncasecmp(cmd
->cmd
, argv
[0],
3159 os_strlen(argv
[0])) == 0) {
3160 printf(" %s", cmd
->cmd
);
3166 } else if (count
== 0) {
3167 printf("Unknown command '%s'\n", argv
[0]);
3170 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
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
,
3191 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
3192 cmd
= os_malloc(len
);
3195 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
3196 if (res
< 0 || (size_t) res
>= len
) {
3200 cmd
[len
- 1] = '\0';
3202 if (system(cmd
) < 0)
3204 #endif /* _WIN32_WCE */
3211 static void wpa_cli_action_process(const char *msg
)
3214 char *copy
= NULL
, *id
, *pos2
;
3219 pos
= os_strchr(pos
, '>');
3226 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
3228 os_unsetenv("WPA_ID");
3229 os_unsetenv("WPA_ID_STR");
3230 os_unsetenv("WPA_CTRL_DIR");
3232 pos
= os_strstr(pos
, "[id=");
3234 copy
= os_strdup(pos
+ 4);
3238 while (*pos2
&& *pos2
!= ' ')
3242 os_setenv("WPA_ID", id
, 1);
3243 while (*pos2
&& *pos2
!= '=')
3248 while (*pos2
&& *pos2
!= ']')
3251 os_setenv("WPA_ID_STR", id
, 1);
3255 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
3257 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
3258 wpa_cli_connected
= 1;
3259 wpa_cli_last_id
= new_id
;
3260 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
3262 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
3263 if (wpa_cli_connected
) {
3264 wpa_cli_connected
= 0;
3265 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
3267 } else if (str_match(pos
, P2P_EVENT_GROUP_STARTED
)) {
3268 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3269 } else if (str_match(pos
, P2P_EVENT_GROUP_REMOVED
)) {
3270 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3271 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_ENABLE
)) {
3272 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3273 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_DISABLE
)) {
3274 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3275 } else if (str_match(pos
, P2P_EVENT_GO_NEG_FAILURE
)) {
3276 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3277 } else if (str_match(pos
, WPS_EVENT_SUCCESS
)) {
3278 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3279 } else if (str_match(pos
, WPS_EVENT_FAIL
)) {
3280 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3281 } else if (str_match(pos
, AP_STA_CONNECTED
)) {
3282 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3283 } else if (str_match(pos
, AP_STA_DISCONNECTED
)) {
3284 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
3285 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
3286 printf("wpa_supplicant is terminating - stop monitoring\n");
3292 #ifndef CONFIG_ANSI_C_EXTRA
3293 static void wpa_cli_action_cb(char *msg
, size_t len
)
3295 wpa_cli_action_process(msg
);
3297 #endif /* CONFIG_ANSI_C_EXTRA */
3300 static void wpa_cli_reconnect(void)
3302 wpa_cli_close_connection();
3303 wpa_cli_open_connection(ctrl_ifname
, 1);
3307 static void cli_event(const char *str
)
3309 const char *start
, *s
;
3311 start
= os_strchr(str
, '>');
3317 if (str_starts(start
, WPA_EVENT_BSS_ADDED
)) {
3318 s
= os_strchr(start
, ' ');
3321 s
= os_strchr(s
+ 1, ' ');
3324 cli_txt_list_add(&bsses
, s
+ 1);
3328 if (str_starts(start
, WPA_EVENT_BSS_REMOVED
)) {
3329 s
= os_strchr(start
, ' ');
3332 s
= os_strchr(s
+ 1, ' ');
3335 cli_txt_list_del_addr(&bsses
, s
+ 1);
3340 if (str_starts(start
, P2P_EVENT_DEVICE_FOUND
)) {
3341 s
= os_strstr(start
, " p2p_dev_addr=");
3344 cli_txt_list_add_addr(&p2p_peers
, s
+ 14);
3348 if (str_starts(start
, P2P_EVENT_DEVICE_LOST
)) {
3349 s
= os_strstr(start
, " p2p_dev_addr=");
3352 cli_txt_list_del_addr(&p2p_peers
, s
+ 14);
3356 if (str_starts(start
, P2P_EVENT_GROUP_STARTED
)) {
3357 s
= os_strchr(start
, ' ');
3360 cli_txt_list_add_word(&p2p_groups
, s
+ 1);
3364 if (str_starts(start
, P2P_EVENT_GROUP_REMOVED
)) {
3365 s
= os_strchr(start
, ' ');
3368 cli_txt_list_del_word(&p2p_groups
, s
+ 1);
3371 #endif /* CONFIG_P2P */
3375 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int action_monitor
)
3377 if (ctrl_conn
== NULL
) {
3378 wpa_cli_reconnect();
3381 while (wpa_ctrl_pending(ctrl
) > 0) {
3383 size_t len
= sizeof(buf
) - 1;
3384 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
3387 wpa_cli_action_process(buf
);
3390 if (wpa_cli_show_event(buf
)) {
3392 printf("\r%s\n", buf
);
3397 printf("Could not read pending message.\n");
3402 if (wpa_ctrl_pending(ctrl
) < 0) {
3403 printf("Connection to wpa_supplicant lost - trying to "
3405 wpa_cli_reconnect();
3411 static int tokenize_cmd(char *cmd
, char *argv
[])
3424 if (argc
== max_args
)
3427 char *pos2
= os_strrchr(pos
, '"');
3431 while (*pos
!= '\0' && *pos
!= ' ')
3441 static void wpa_cli_ping(void *eloop_ctx
, void *timeout_ctx
)
3443 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
3444 printf("Connection to wpa_supplicant lost - trying to "
3446 wpa_cli_close_connection();
3449 wpa_cli_reconnect();
3450 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3454 static void wpa_cli_eloop_terminate(int sig
, void *signal_ctx
)
3460 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
)
3462 wpa_cli_recv_pending(mon_conn
, 0);
3466 static void wpa_cli_edit_cmd_cb(void *ctx
, char *cmd
)
3468 char *argv
[max_args
];
3470 argc
= tokenize_cmd(cmd
, argv
);
3472 wpa_request(ctrl_conn
, argc
, argv
);
3476 static void wpa_cli_edit_eof_cb(void *ctx
)
3482 static void wpa_cli_interactive(void)
3484 char *home
, *hfile
= NULL
;
3486 printf("\nInteractive mode\n\n");
3488 home
= getenv("HOME");
3490 const char *fname
= ".wpa_cli_history";
3491 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
3492 hfile
= os_malloc(hfile_len
);
3494 os_snprintf(hfile
, hfile_len
, "%s/%s", home
, fname
);
3497 eloop_register_signal_terminate(wpa_cli_eloop_terminate
, NULL
);
3498 edit_init(wpa_cli_edit_cmd_cb
, wpa_cli_edit_eof_cb
,
3499 wpa_cli_edit_completion_cb
, NULL
, hfile
);
3500 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3504 cli_txt_list_flush(&p2p_peers
);
3505 cli_txt_list_flush(&p2p_groups
);
3506 cli_txt_list_flush(&bsses
);
3507 edit_deinit(hfile
, wpa_cli_edit_filter_history_cb
);
3509 eloop_cancel_timeout(wpa_cli_ping
, NULL
, NULL
);
3510 wpa_cli_close_connection();
3514 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
3516 #ifdef CONFIG_ANSI_C_EXTRA
3517 /* TODO: ANSI C version(?) */
3518 printf("Action processing not supported in ANSI C build.\n");
3519 #else /* CONFIG_ANSI_C_EXTRA */
3523 char buf
[256]; /* note: large enough to fit in unsolicited messages */
3526 fd
= wpa_ctrl_get_fd(ctrl
);
3528 while (!wpa_cli_quit
) {
3531 tv
.tv_sec
= ping_interval
;
3533 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
3534 if (res
< 0 && errno
!= EINTR
) {
3539 if (FD_ISSET(fd
, &rfds
))
3540 wpa_cli_recv_pending(ctrl
, 1);
3542 /* verify that connection is still working */
3543 len
= sizeof(buf
) - 1;
3544 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
3545 wpa_cli_action_cb
) < 0 ||
3546 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
3547 printf("wpa_supplicant did not reply to PING "
3548 "command - exiting\n");
3553 #endif /* CONFIG_ANSI_C_EXTRA */
3557 static void wpa_cli_cleanup(void)
3559 wpa_cli_close_connection();
3561 os_daemonize_terminate(pid_file
);
3563 os_program_deinit();
3566 static void wpa_cli_terminate(int sig
)
3573 static char * wpa_cli_get_default_ifname(void)
3575 char *ifname
= NULL
;
3577 #ifdef CONFIG_CTRL_IFACE_UNIX
3578 struct dirent
*dent
;
3579 DIR *dir
= opendir(ctrl_iface_dir
);
3582 char ifprop
[PROPERTY_VALUE_MAX
];
3583 if (property_get("wifi.interface", ifprop
, NULL
) != 0) {
3584 ifname
= os_strdup(ifprop
);
3585 printf("Using interface '%s'\n", ifname
);
3588 #endif /* ANDROID */
3591 while ((dent
= readdir(dir
))) {
3592 #ifdef _DIRENT_HAVE_D_TYPE
3594 * Skip the file if it is not a socket. Also accept
3595 * DT_UNKNOWN (0) in case the C library or underlying
3596 * file system does not support d_type.
3598 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
3600 #endif /* _DIRENT_HAVE_D_TYPE */
3601 if (os_strcmp(dent
->d_name
, ".") == 0 ||
3602 os_strcmp(dent
->d_name
, "..") == 0)
3604 printf("Selected interface '%s'\n", dent
->d_name
);
3605 ifname
= os_strdup(dent
->d_name
);
3609 #endif /* CONFIG_CTRL_IFACE_UNIX */
3611 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3612 char buf
[2048], *pos
;
3614 struct wpa_ctrl
*ctrl
;
3617 ctrl
= wpa_ctrl_open(NULL
);
3621 len
= sizeof(buf
) - 1;
3622 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
3625 pos
= os_strchr(buf
, '\n');
3628 ifname
= os_strdup(buf
);
3630 wpa_ctrl_close(ctrl
);
3631 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3637 int main(int argc
, char *argv
[])
3639 int warning_displayed
= 0;
3643 const char *global
= NULL
;
3645 if (os_program_init())
3649 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
3654 action_file
= optarg
;
3663 ping_interval
= atoi(optarg
);
3669 printf("%s\n", wpa_cli_version
);
3672 os_free(ctrl_ifname
);
3673 ctrl_ifname
= os_strdup(optarg
);
3676 ctrl_iface_dir
= optarg
;
3687 interactive
= (argc
== optind
) && (action_file
== NULL
);
3690 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
3696 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3697 ctrl_conn
= wpa_ctrl_open(NULL
);
3698 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3699 ctrl_conn
= wpa_ctrl_open(global
);
3700 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3701 if (ctrl_conn
== NULL
) {
3702 perror("Failed to connect to wpa_supplicant - "
3709 signal(SIGINT
, wpa_cli_terminate
);
3710 signal(SIGTERM
, wpa_cli_terminate
);
3711 #endif /* _WIN32_WCE */
3713 if (ctrl_ifname
== NULL
)
3714 ctrl_ifname
= wpa_cli_get_default_ifname();
3718 if (wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
3719 if (warning_displayed
)
3720 printf("Connection established.\n");
3724 if (!warning_displayed
) {
3725 printf("Could not connect to wpa_supplicant - "
3727 warning_displayed
= 1;
3734 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
3735 perror("Failed to connect to wpa_supplicant - "
3741 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
3742 wpa_cli_attached
= 1;
3744 printf("Warning: Failed to attach to "
3745 "wpa_supplicant.\n");
3751 if (daemonize
&& os_daemonize(pid_file
))
3755 wpa_cli_interactive();
3756 else if (action_file
)
3757 wpa_cli_action(ctrl_conn
);
3759 ret
= wpa_request(ctrl_conn
, argc
- optind
, &argv
[optind
]);
3761 os_free(ctrl_ifname
);
3768 #else /* CONFIG_CTRL_IFACE */
3769 int main(int argc
, char *argv
[])
3771 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3774 #endif /* CONFIG_CTRL_IFACE */