2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
11 #ifdef CONFIG_CTRL_IFACE
13 #ifdef CONFIG_CTRL_IFACE_UNIX
15 #endif /* CONFIG_CTRL_IFACE_UNIX */
17 #include "common/wpa_ctrl.h"
18 #include "utils/common.h"
19 #include "utils/eloop.h"
20 #include "utils/edit.h"
21 #include "utils/list.h"
22 #include "common/version.h"
23 #include "common/ieee802_11_defs.h"
25 #include <cutils/properties.h>
29 static const char *wpa_cli_version
=
30 "wpa_cli v" VERSION_STR
"\n"
31 "Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> and contributors";
34 static const char *wpa_cli_license
=
35 "This software may be distributed under the terms of the BSD license.\n"
36 "See README for more details.\n";
38 static const char *wpa_cli_full_license
=
39 "This software may be distributed under the terms of the BSD license.\n"
41 "Redistribution and use in source and binary forms, with or without\n"
42 "modification, are permitted provided that the following conditions are\n"
45 "1. Redistributions of source code must retain the above copyright\n"
46 " notice, this list of conditions and the following disclaimer.\n"
48 "2. Redistributions in binary form must reproduce the above copyright\n"
49 " notice, this list of conditions and the following disclaimer in the\n"
50 " documentation and/or other materials provided with the distribution.\n"
52 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
53 " names of its contributors may be used to endorse or promote products\n"
54 " derived from this software without specific prior written permission.\n"
56 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
57 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
58 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
59 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
60 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
61 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
62 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
63 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
64 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
65 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
66 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
69 static struct wpa_ctrl
*ctrl_conn
;
70 static struct wpa_ctrl
*mon_conn
;
71 static int wpa_cli_quit
= 0;
72 static int wpa_cli_attached
= 0;
73 static int wpa_cli_connected
= 0;
74 static int wpa_cli_last_id
= 0;
75 #ifndef CONFIG_CTRL_IFACE_DIR
76 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
77 #endif /* CONFIG_CTRL_IFACE_DIR */
78 static const char *ctrl_iface_dir
= CONFIG_CTRL_IFACE_DIR
;
79 static char *ctrl_ifname
= NULL
;
80 static const char *pid_file
= NULL
;
81 static const char *action_file
= NULL
;
82 static int ping_interval
= 5;
83 static int interactive
= 0;
85 struct cli_txt_entry
{
90 static DEFINE_DL_LIST(bsses
); /* struct cli_txt_entry */
91 static DEFINE_DL_LIST(p2p_peers
); /* struct cli_txt_entry */
92 static DEFINE_DL_LIST(p2p_groups
); /* struct cli_txt_entry */
95 static void print_help(void);
96 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
);
97 static void wpa_cli_close_connection(void);
98 static char * wpa_cli_get_default_ifname(void);
101 static void usage(void)
103 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
104 "[-a<action file>] \\\n"
105 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
107 " -h = help (show this usage text)\n"
108 " -v = shown version information\n"
109 " -a = run in daemon mode executing the action file based on "
112 " -B = run a daemon in the background\n"
113 " default path: " CONFIG_CTRL_IFACE_DIR
"\n"
114 " default interface: first interface found in socket path\n");
119 static void cli_txt_list_free(struct cli_txt_entry
*e
)
121 dl_list_del(&e
->list
);
127 static void cli_txt_list_flush(struct dl_list
*list
)
129 struct cli_txt_entry
*e
;
130 while ((e
= dl_list_first(list
, struct cli_txt_entry
, list
)))
131 cli_txt_list_free(e
);
135 static struct cli_txt_entry
* cli_txt_list_get(struct dl_list
*txt_list
,
138 struct cli_txt_entry
*e
;
139 dl_list_for_each(e
, txt_list
, struct cli_txt_entry
, list
) {
140 if (os_strcmp(e
->txt
, txt
) == 0)
147 static void cli_txt_list_del(struct dl_list
*txt_list
, const char *txt
)
149 struct cli_txt_entry
*e
;
150 e
= cli_txt_list_get(txt_list
, txt
);
152 cli_txt_list_free(e
);
156 static void cli_txt_list_del_addr(struct dl_list
*txt_list
, const char *txt
)
160 if (hwaddr_aton(txt
, addr
) < 0)
162 os_snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
163 cli_txt_list_del(txt_list
, buf
);
168 static void cli_txt_list_del_word(struct dl_list
*txt_list
, const char *txt
)
172 end
= os_strchr(txt
, ' ');
174 end
= txt
+ os_strlen(txt
);
175 buf
= os_malloc(end
- txt
+ 1);
178 os_memcpy(buf
, txt
, end
- txt
);
179 buf
[end
- txt
] = '\0';
180 cli_txt_list_del(txt_list
, buf
);
183 #endif /* CONFIG_P2P */
186 static int cli_txt_list_add(struct dl_list
*txt_list
, const char *txt
)
188 struct cli_txt_entry
*e
;
189 e
= cli_txt_list_get(txt_list
, txt
);
192 e
= os_zalloc(sizeof(*e
));
195 e
->txt
= os_strdup(txt
);
196 if (e
->txt
== NULL
) {
200 dl_list_add(txt_list
, &e
->list
);
206 static int cli_txt_list_add_addr(struct dl_list
*txt_list
, const char *txt
)
210 if (hwaddr_aton(txt
, addr
) < 0)
212 os_snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
213 return cli_txt_list_add(txt_list
, buf
);
217 static int cli_txt_list_add_word(struct dl_list
*txt_list
, const char *txt
)
222 end
= os_strchr(txt
, ' ');
224 end
= txt
+ os_strlen(txt
);
225 buf
= os_malloc(end
- txt
+ 1);
228 os_memcpy(buf
, txt
, end
- txt
);
229 buf
[end
- txt
] = '\0';
230 ret
= cli_txt_list_add(txt_list
, buf
);
234 #endif /* CONFIG_P2P */
237 static char ** cli_txt_list_array(struct dl_list
*txt_list
)
239 unsigned int i
, count
= dl_list_len(txt_list
);
241 struct cli_txt_entry
*e
;
243 res
= os_calloc(count
+ 1, sizeof(char *));
248 dl_list_for_each(e
, txt_list
, struct cli_txt_entry
, list
) {
249 res
[i
] = os_strdup(e
->txt
);
259 static int get_cmd_arg_num(const char *str
, int pos
)
263 for (i
= 0; i
<= pos
; i
++) {
266 while (i
<= pos
&& str
[i
] != ' ')
277 static int str_starts(const char *src
, const char *match
)
279 return os_strncmp(src
, match
, os_strlen(match
)) == 0;
283 static int wpa_cli_show_event(const char *event
)
287 start
= os_strchr(event
, '>');
293 * Skip BSS added/removed events since they can be relatively frequent
294 * and are likely of not much use for an interactive user.
296 if (str_starts(start
, WPA_EVENT_BSS_ADDED
) ||
297 str_starts(start
, WPA_EVENT_BSS_REMOVED
))
304 static int wpa_cli_open_connection(const char *ifname
, int attach
)
306 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
307 ctrl_conn
= wpa_ctrl_open(ifname
);
308 if (ctrl_conn
== NULL
)
311 if (attach
&& interactive
)
312 mon_conn
= wpa_ctrl_open(ifname
);
315 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
323 if (access(ctrl_iface_dir
, F_OK
) < 0) {
324 cfile
= os_strdup(ifname
);
331 flen
= os_strlen(ctrl_iface_dir
) + os_strlen(ifname
) + 2;
332 cfile
= os_malloc(flen
);
335 res
= os_snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
,
337 if (res
< 0 || res
>= flen
) {
343 ctrl_conn
= wpa_ctrl_open(cfile
);
344 if (ctrl_conn
== NULL
) {
349 if (attach
&& interactive
)
350 mon_conn
= wpa_ctrl_open(cfile
);
354 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
357 if (wpa_ctrl_attach(mon_conn
) == 0) {
358 wpa_cli_attached
= 1;
360 eloop_register_read_sock(
361 wpa_ctrl_get_fd(mon_conn
),
362 wpa_cli_mon_receive
, NULL
, NULL
);
364 printf("Warning: Failed to attach to "
365 "wpa_supplicant.\n");
366 wpa_cli_close_connection();
375 static void wpa_cli_close_connection(void)
377 if (ctrl_conn
== NULL
)
380 if (wpa_cli_attached
) {
381 wpa_ctrl_detach(interactive
? mon_conn
: ctrl_conn
);
382 wpa_cli_attached
= 0;
384 wpa_ctrl_close(ctrl_conn
);
387 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn
));
388 wpa_ctrl_close(mon_conn
);
394 static void wpa_cli_msg_cb(char *msg
, size_t len
)
400 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
406 if (ctrl_conn
== NULL
) {
407 printf("Not connected to wpa_supplicant - command dropped.\n");
410 len
= sizeof(buf
) - 1;
411 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
414 printf("'%s' command timed out.\n", cmd
);
416 } else if (ret
< 0) {
417 printf("'%s' command failed.\n", cmd
);
423 if (interactive
&& len
> 0 && buf
[len
- 1] != '\n')
430 static int wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
)
432 return _wpa_ctrl_command(ctrl
, cmd
, 1);
436 static int write_cmd(char *buf
, size_t buflen
, const char *cmd
, int argc
,
445 res
= os_snprintf(pos
, end
- pos
, "%s", cmd
);
446 if (res
< 0 || res
>= end
- pos
)
450 for (i
= 0; i
< argc
; i
++) {
451 res
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
452 if (res
< 0 || res
>= end
- pos
)
457 buf
[buflen
- 1] = '\0';
461 printf("Too long command\n");
466 static int wpa_cli_cmd(struct wpa_ctrl
*ctrl
, const char *cmd
, int min_args
,
467 int argc
, char *argv
[])
470 if (argc
< min_args
) {
471 printf("Invalid %s command - at least %d argument%s "
472 "required.\n", cmd
, min_args
,
473 min_args
> 1 ? "s are" : " is");
476 if (write_cmd(buf
, sizeof(buf
), cmd
, argc
, argv
) < 0)
478 return wpa_ctrl_command(ctrl
, buf
);
482 static int wpa_cli_cmd_ifname(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
484 return wpa_ctrl_command(ctrl
, "IFNAME");
488 static int wpa_cli_cmd_status(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
490 if (argc
> 0 && os_strcmp(argv
[0], "verbose") == 0)
491 return wpa_ctrl_command(ctrl
, "STATUS-VERBOSE");
492 if (argc
> 0 && os_strcmp(argv
[0], "wps") == 0)
493 return wpa_ctrl_command(ctrl
, "STATUS-WPS");
494 return wpa_ctrl_command(ctrl
, "STATUS");
498 static int wpa_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
500 return wpa_ctrl_command(ctrl
, "PING");
504 static int wpa_cli_cmd_relog(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
506 return wpa_ctrl_command(ctrl
, "RELOG");
510 static int wpa_cli_cmd_note(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
512 return wpa_cli_cmd(ctrl
, "NOTE", 1, argc
, argv
);
516 static int wpa_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
518 return wpa_ctrl_command(ctrl
, "MIB");
522 static int wpa_cli_cmd_pmksa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
524 return wpa_ctrl_command(ctrl
, "PMKSA");
528 static int wpa_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
535 static int wpa_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
537 printf("%s\n\n%s\n", wpa_cli_version
, wpa_cli_full_license
);
542 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
551 static void wpa_cli_show_variables(void)
553 printf("set variables:\n"
554 " EAPOL::heldPeriod (EAPOL state machine held period, "
556 " EAPOL::authPeriod (EAPOL state machine authentication "
557 "period, in seconds)\n"
558 " EAPOL::startPeriod (EAPOL state machine start period, in "
560 " EAPOL::maxStart (EAPOL state machine maximum start "
562 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
564 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
565 " threshold\n\tpercentage)\n"
566 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
567 "security\n\tassociation in seconds)\n");
571 static int wpa_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
577 wpa_cli_show_variables();
581 if (argc
!= 1 && argc
!= 2) {
582 printf("Invalid SET command: needs two arguments (variable "
583 "name and value)\n");
588 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s ", argv
[0]);
590 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s",
592 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
593 printf("Too long SET command.\n");
596 return wpa_ctrl_command(ctrl
, cmd
);
600 static int wpa_cli_cmd_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
602 return wpa_cli_cmd(ctrl
, "GET", 1, argc
, argv
);
606 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
608 return wpa_ctrl_command(ctrl
, "LOGOFF");
612 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
614 return wpa_ctrl_command(ctrl
, "LOGON");
618 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
621 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
625 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
628 return wpa_cli_cmd(ctrl
, "PREAUTH", 1, argc
, argv
);
632 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
634 return wpa_cli_cmd(ctrl
, "AP_SCAN", 1, argc
, argv
);
638 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl
*ctrl
, int argc
,
641 return wpa_cli_cmd(ctrl
, "SCAN_INTERVAL", 1, argc
, argv
);
645 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl
*ctrl
, int argc
,
648 return wpa_cli_cmd(ctrl
, "BSS_EXPIRE_AGE", 1, argc
, argv
);
652 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl
*ctrl
, int argc
,
655 return wpa_cli_cmd(ctrl
, "BSS_EXPIRE_COUNT", 1, argc
, argv
);
659 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
662 return wpa_cli_cmd(ctrl
, "STKSTART", 1, argc
, argv
);
666 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
668 return wpa_cli_cmd(ctrl
, "FT_DS", 1, argc
, argv
);
672 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
674 return wpa_cli_cmd(ctrl
, "WPS_PBC", 0, argc
, argv
);
678 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
681 printf("Invalid WPS_PIN command: need one or two arguments:\n"
682 "- BSSID: use 'any' to select any\n"
683 "- PIN: optional, used only with devices that have no "
688 return wpa_cli_cmd(ctrl
, "WPS_PIN", 1, argc
, argv
);
692 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl
*ctrl
, int argc
,
695 return wpa_cli_cmd(ctrl
, "WPS_CHECK_PIN", 1, argc
, argv
);
699 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl
*ctrl
, int argc
,
702 return wpa_ctrl_command(ctrl
, "WPS_CANCEL");
706 #ifdef CONFIG_WPS_OOB
707 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
709 if (argc
!= 3 && argc
!= 4) {
710 printf("Invalid WPS_OOB command: need three or four "
712 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
713 "- PATH: path of OOB device like '/mnt'\n"
714 "- METHOD: OOB method 'pin-e' or 'pin-r', "
716 "- DEV_NAME: (only for NFC) device name like "
721 return wpa_cli_cmd(ctrl
, "WPS_OOB", 3, argc
, argv
);
723 #endif /* CONFIG_WPS_OOB */
726 #ifdef CONFIG_WPS_NFC
728 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
730 return wpa_cli_cmd(ctrl
, "WPS_NFC", 0, argc
, argv
);
734 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl
*ctrl
, int argc
,
737 return wpa_cli_cmd(ctrl
, "WPS_NFC_TOKEN", 1, argc
, argv
);
741 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl
*ctrl
, int argc
,
749 printf("Invalid 'wps_nfc_tag_read' command - one argument "
754 buflen
= 18 + os_strlen(argv
[0]);
755 buf
= os_malloc(buflen
);
758 os_snprintf(buf
, buflen
, "WPS_NFC_TAG_READ %s", argv
[0]);
760 ret
= wpa_ctrl_command(ctrl
, buf
);
766 #endif /* CONFIG_WPS_NFC */
769 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
775 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
777 else if (argc
== 5 || argc
== 6) {
778 char ssid_hex
[2 * 32 + 1];
779 char key_hex
[2 * 64 + 1];
783 for (i
= 0; i
< 32; i
++) {
784 if (argv
[2][i
] == '\0')
786 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
791 for (i
= 0; i
< 64; i
++) {
792 if (argv
[5][i
] == '\0')
794 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
799 res
= os_snprintf(cmd
, sizeof(cmd
),
800 "WPS_REG %s %s %s %s %s %s",
801 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
804 printf("Invalid WPS_REG command: need two arguments:\n"
805 "- BSSID of the target AP\n"
807 printf("Alternatively, six arguments can be used to "
808 "reconfigure the AP:\n"
809 "- BSSID of the target AP\n"
812 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
813 "- new encr (NONE, WEP, TKIP, CCMP)\n"
818 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
819 printf("Too long WPS_REG command.\n");
822 return wpa_ctrl_command(ctrl
, cmd
);
826 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl
*ctrl
, int argc
,
829 return wpa_cli_cmd(ctrl
, "WPS_AP_PIN", 1, argc
, argv
);
833 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
836 return wpa_cli_cmd(ctrl
, "WPS_ER_START", 0, argc
, argv
);
840 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
843 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
848 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
852 printf("Invalid WPS_ER_PIN command: need at least two "
854 "- UUID: use 'any' to select any\n"
855 "- PIN: Enrollee PIN\n"
856 "optional: - Enrollee MAC address\n");
860 return wpa_cli_cmd(ctrl
, "WPS_ER_PIN", 2, argc
, argv
);
864 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
867 return wpa_cli_cmd(ctrl
, "WPS_ER_PBC", 1, argc
, argv
);
871 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
875 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
876 "- UUID: specify which AP to use\n"
881 return wpa_cli_cmd(ctrl
, "WPS_ER_LEARN", 2, argc
, argv
);
885 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl
*ctrl
, int argc
,
889 printf("Invalid WPS_ER_SET_CONFIG command: need two "
891 "- UUID: specify which AP to use\n"
892 "- Network configuration id\n");
896 return wpa_cli_cmd(ctrl
, "WPS_ER_SET_CONFIG", 2, argc
, argv
);
900 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl
*ctrl
, int argc
,
906 if (argc
== 5 || argc
== 6) {
907 char ssid_hex
[2 * 32 + 1];
908 char key_hex
[2 * 64 + 1];
912 for (i
= 0; i
< 32; i
++) {
913 if (argv
[2][i
] == '\0')
915 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
920 for (i
= 0; i
< 64; i
++) {
921 if (argv
[5][i
] == '\0')
923 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
928 res
= os_snprintf(cmd
, sizeof(cmd
),
929 "WPS_ER_CONFIG %s %s %s %s %s %s",
930 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
933 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
937 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
938 "- new encr (NONE, WEP, TKIP, CCMP)\n"
943 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
944 printf("Too long WPS_ER_CONFIG command.\n");
947 return wpa_ctrl_command(ctrl
, cmd
);
951 #ifdef CONFIG_WPS_NFC
952 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl
*ctrl
, int argc
,
956 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
958 "- WPS/NDEF: token format\n"
959 "- UUID: specify which AP to use\n");
963 return wpa_cli_cmd(ctrl
, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc
, argv
);
965 #endif /* CONFIG_WPS_NFC */
968 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
970 return wpa_cli_cmd(ctrl
, "IBSS_RSN", 1, argc
, argv
);
974 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
976 return wpa_cli_cmd(ctrl
, "LEVEL", 1, argc
, argv
);
980 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
982 char cmd
[256], *pos
, *end
;
986 printf("Invalid IDENTITY command: needs two arguments "
987 "(network id and identity)\n");
991 end
= cmd
+ sizeof(cmd
);
993 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
995 if (ret
< 0 || ret
>= end
- pos
) {
996 printf("Too long IDENTITY command.\n");
1000 for (i
= 2; i
< argc
; i
++) {
1001 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1002 if (ret
< 0 || ret
>= end
- pos
) {
1003 printf("Too long IDENTITY command.\n");
1009 return wpa_ctrl_command(ctrl
, cmd
);
1013 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1015 char cmd
[256], *pos
, *end
;
1019 printf("Invalid PASSWORD command: needs two arguments "
1020 "(network id and password)\n");
1024 end
= cmd
+ sizeof(cmd
);
1026 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
1028 if (ret
< 0 || ret
>= end
- pos
) {
1029 printf("Too long PASSWORD command.\n");
1033 for (i
= 2; i
< argc
; i
++) {
1034 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1035 if (ret
< 0 || ret
>= end
- pos
) {
1036 printf("Too long PASSWORD command.\n");
1042 return wpa_ctrl_command(ctrl
, cmd
);
1046 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
1049 char cmd
[256], *pos
, *end
;
1053 printf("Invalid NEW_PASSWORD command: needs two arguments "
1054 "(network id and password)\n");
1058 end
= cmd
+ sizeof(cmd
);
1060 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
1062 if (ret
< 0 || ret
>= end
- pos
) {
1063 printf("Too long NEW_PASSWORD command.\n");
1067 for (i
= 2; i
< argc
; i
++) {
1068 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1069 if (ret
< 0 || ret
>= end
- pos
) {
1070 printf("Too long NEW_PASSWORD command.\n");
1076 return wpa_ctrl_command(ctrl
, cmd
);
1080 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1082 char cmd
[256], *pos
, *end
;
1086 printf("Invalid PIN command: needs two arguments "
1087 "(network id and pin)\n");
1091 end
= cmd
+ sizeof(cmd
);
1093 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
1095 if (ret
< 0 || ret
>= end
- pos
) {
1096 printf("Too long PIN command.\n");
1100 for (i
= 2; i
< argc
; i
++) {
1101 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1102 if (ret
< 0 || ret
>= end
- pos
) {
1103 printf("Too long PIN command.\n");
1108 return wpa_ctrl_command(ctrl
, cmd
);
1112 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1114 char cmd
[256], *pos
, *end
;
1118 printf("Invalid OTP command: needs two arguments (network "
1119 "id and password)\n");
1123 end
= cmd
+ sizeof(cmd
);
1125 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
1127 if (ret
< 0 || ret
>= end
- pos
) {
1128 printf("Too long OTP command.\n");
1132 for (i
= 2; i
< argc
; i
++) {
1133 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1134 if (ret
< 0 || ret
>= end
- pos
) {
1135 printf("Too long OTP command.\n");
1141 return wpa_ctrl_command(ctrl
, cmd
);
1145 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1148 char cmd
[256], *pos
, *end
;
1152 printf("Invalid PASSPHRASE command: needs two arguments "
1153 "(network id and passphrase)\n");
1157 end
= cmd
+ sizeof(cmd
);
1159 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
1161 if (ret
< 0 || ret
>= end
- pos
) {
1162 printf("Too long PASSPHRASE command.\n");
1166 for (i
= 2; i
< argc
; i
++) {
1167 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1168 if (ret
< 0 || ret
>= end
- pos
) {
1169 printf("Too long PASSPHRASE command.\n");
1175 return wpa_ctrl_command(ctrl
, cmd
);
1179 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1182 printf("Invalid BSSID command: needs two arguments (network "
1187 return wpa_cli_cmd(ctrl
, "BSSID", 2, argc
, argv
);
1191 static int wpa_cli_cmd_blacklist(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1193 return wpa_cli_cmd(ctrl
, "BLACKLIST", 0, argc
, argv
);
1197 static int wpa_cli_cmd_log_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1199 return wpa_cli_cmd(ctrl
, "LOG_LEVEL", 0, argc
, argv
);
1203 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
1206 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
1210 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
1213 return wpa_cli_cmd(ctrl
, "SELECT_NETWORK", 1, argc
, argv
);
1217 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
1220 return wpa_cli_cmd(ctrl
, "ENABLE_NETWORK", 1, argc
, argv
);
1224 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
1227 return wpa_cli_cmd(ctrl
, "DISABLE_NETWORK", 1, argc
, argv
);
1231 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
1234 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
1238 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
1241 return wpa_cli_cmd(ctrl
, "REMOVE_NETWORK", 1, argc
, argv
);
1245 static void wpa_cli_show_network_variables(void)
1247 printf("set_network variables:\n"
1248 " ssid (network name, SSID)\n"
1249 " psk (WPA passphrase or pre-shared key)\n"
1250 " key_mgmt (key management protocol)\n"
1251 " identity (EAP identity)\n"
1252 " password (EAP password)\n"
1255 "Note: Values are entered in the same format as the "
1256 "configuration file is using,\n"
1257 "i.e., strings values need to be inside double quotation "
1259 "For example: set_network 1 ssid \"network name\"\n"
1261 "Please see wpa_supplicant.conf documentation for full list "
1262 "of\navailable variables.\n");
1266 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
1270 wpa_cli_show_network_variables();
1275 printf("Invalid SET_NETWORK command: needs three arguments\n"
1276 "(network id, variable name, and value)\n");
1280 return wpa_cli_cmd(ctrl
, "SET_NETWORK", 3, argc
, argv
);
1284 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1288 wpa_cli_show_network_variables();
1293 printf("Invalid GET_NETWORK command: needs two arguments\n"
1294 "(network id and variable name)\n");
1298 return wpa_cli_cmd(ctrl
, "GET_NETWORK", 2, argc
, argv
);
1302 static int wpa_cli_cmd_list_creds(struct wpa_ctrl
*ctrl
, int argc
,
1305 return wpa_ctrl_command(ctrl
, "LIST_CREDS");
1309 static int wpa_cli_cmd_add_cred(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1311 return wpa_ctrl_command(ctrl
, "ADD_CRED");
1315 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl
*ctrl
, int argc
,
1318 return wpa_cli_cmd(ctrl
, "REMOVE_CRED", 1, argc
, argv
);
1322 static int wpa_cli_cmd_set_cred(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1325 printf("Invalid SET_CRED command: needs three arguments\n"
1326 "(cred id, variable name, and value)\n");
1330 return wpa_cli_cmd(ctrl
, "SET_CRED", 3, argc
, argv
);
1334 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1337 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1341 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1344 return wpa_ctrl_command(ctrl
, "RECONNECT");
1348 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
1351 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
1355 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1357 return wpa_ctrl_command(ctrl
, "SCAN");
1361 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
1364 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1368 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1370 return wpa_cli_cmd(ctrl
, "BSS", 1, argc
, argv
);
1374 static char ** wpa_cli_complete_bss(const char *str
, int pos
)
1376 int arg
= get_cmd_arg_num(str
, pos
);
1381 res
= cli_txt_list_array(&bsses
);
1389 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1392 if (argc
< 1 || argc
> 2) {
1393 printf("Invalid GET_CAPABILITY command: need either one or "
1398 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
1399 printf("Invalid GET_CAPABILITY command: second argument, "
1400 "if any, must be 'strict'\n");
1404 return wpa_cli_cmd(ctrl
, "GET_CAPABILITY", 1, argc
, argv
);
1408 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
1410 printf("Available interfaces:\n");
1411 return wpa_ctrl_command(ctrl
, "INTERFACES");
1415 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1418 wpa_cli_list_interfaces(ctrl
);
1422 wpa_cli_close_connection();
1423 os_free(ctrl_ifname
);
1424 ctrl_ifname
= os_strdup(argv
[0]);
1426 if (wpa_cli_open_connection(ctrl_ifname
, 1)) {
1427 printf("Connected to interface '%s.\n", ctrl_ifname
);
1429 printf("Could not connect to interface '%s' - re-trying\n",
1436 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1439 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1443 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1446 return wpa_ctrl_command(ctrl
, "TERMINATE");
1450 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1457 printf("Invalid INTERFACE_ADD command: needs at least one "
1458 "argument (interface name)\n"
1459 "All arguments: ifname confname driver ctrl_interface "
1460 "driver_param bridge_name\n");
1465 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1466 * <driver_param>TAB<bridge_name>
1468 res
= os_snprintf(cmd
, sizeof(cmd
),
1469 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1471 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1472 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1473 argc
> 5 ? argv
[5] : "");
1474 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1476 cmd
[sizeof(cmd
) - 1] = '\0';
1477 return wpa_ctrl_command(ctrl
, cmd
);
1481 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1484 return wpa_cli_cmd(ctrl
, "INTERFACE_REMOVE", 1, argc
, argv
);
1488 static int wpa_cli_cmd_interface_list(struct wpa_ctrl
*ctrl
, int argc
,
1491 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1496 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1498 return wpa_cli_cmd(ctrl
, "STA", 1, argc
, argv
);
1502 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
1503 char *addr
, size_t addr_len
)
1505 char buf
[4096], *pos
;
1509 if (ctrl_conn
== NULL
) {
1510 printf("Not connected to hostapd - command dropped.\n");
1513 len
= sizeof(buf
) - 1;
1514 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
1517 printf("'%s' command timed out.\n", cmd
);
1519 } else if (ret
< 0) {
1520 printf("'%s' command failed.\n", cmd
);
1525 if (os_memcmp(buf
, "FAIL", 4) == 0)
1530 while (*pos
!= '\0' && *pos
!= '\n')
1533 os_strlcpy(addr
, buf
, addr_len
);
1538 static int wpa_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1540 char addr
[32], cmd
[64];
1542 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
1545 os_snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1546 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
1552 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
1555 return wpa_cli_cmd(ctrl
, "DEAUTHENTICATE", 1, argc
, argv
);
1559 static int wpa_cli_cmd_disassociate(struct wpa_ctrl
*ctrl
, int argc
,
1562 return wpa_cli_cmd(ctrl
, "DISASSOCIATE", 1, argc
, argv
);
1564 #endif /* CONFIG_AP */
1567 static int wpa_cli_cmd_suspend(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1569 return wpa_ctrl_command(ctrl
, "SUSPEND");
1573 static int wpa_cli_cmd_resume(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1575 return wpa_ctrl_command(ctrl
, "RESUME");
1579 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1581 return wpa_ctrl_command(ctrl
, "DROP_SA");
1585 static int wpa_cli_cmd_roam(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1587 return wpa_cli_cmd(ctrl
, "ROAM", 1, argc
, argv
);
1593 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1595 return wpa_cli_cmd(ctrl
, "P2P_FIND", 0, argc
, argv
);
1599 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl
*ctrl
, int argc
,
1602 return wpa_ctrl_command(ctrl
, "P2P_STOP_FIND");
1606 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl
*ctrl
, int argc
,
1609 return wpa_cli_cmd(ctrl
, "P2P_CONNECT", 2, argc
, argv
);
1613 static char ** wpa_cli_complete_p2p_connect(const char *str
, int pos
)
1615 int arg
= get_cmd_arg_num(str
, pos
);
1620 res
= cli_txt_list_array(&p2p_peers
);
1628 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl
*ctrl
, int argc
,
1631 return wpa_cli_cmd(ctrl
, "P2P_LISTEN", 0, argc
, argv
);
1635 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl
*ctrl
, int argc
,
1638 return wpa_cli_cmd(ctrl
, "P2P_GROUP_REMOVE", 1, argc
, argv
);
1642 static char ** wpa_cli_complete_p2p_group_remove(const char *str
, int pos
)
1644 int arg
= get_cmd_arg_num(str
, pos
);
1649 res
= cli_txt_list_array(&p2p_groups
);
1657 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl
*ctrl
, int argc
,
1660 return wpa_cli_cmd(ctrl
, "P2P_GROUP_ADD", 0, argc
, argv
);
1664 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl
*ctrl
, int argc
,
1667 if (argc
!= 2 && argc
!= 3) {
1668 printf("Invalid P2P_PROV_DISC command: needs at least "
1669 "two arguments, address and config method\n"
1670 "(display, keypad, or pbc) and an optional join\n");
1674 return wpa_cli_cmd(ctrl
, "P2P_PROV_DISC", 2, argc
, argv
);
1678 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1681 return wpa_ctrl_command(ctrl
, "P2P_GET_PASSPHRASE");
1685 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl
*ctrl
, int argc
,
1690 if (argc
!= 2 && argc
!= 4) {
1691 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1692 "arguments (address and TLVs) or four arguments "
1693 "(address, \"upnp\", version, search target "
1698 if (write_cmd(cmd
, sizeof(cmd
), "P2P_SERV_DISC_REQ", argc
, argv
) < 0)
1700 return wpa_ctrl_command(ctrl
, cmd
);
1704 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl
*ctrl
,
1705 int argc
, char *argv
[])
1707 return wpa_cli_cmd(ctrl
, "P2P_SERV_DISC_CANCEL_REQ", 1, argc
, argv
);
1711 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl
*ctrl
, int argc
,
1718 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1719 "arguments (freq, address, dialog token, and TLVs)\n");
1723 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_RESP %s %s %s %s",
1724 argv
[0], argv
[1], argv
[2], argv
[3]);
1725 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1727 cmd
[sizeof(cmd
) - 1] = '\0';
1728 return wpa_ctrl_command(ctrl
, cmd
);
1732 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl
*ctrl
, int argc
,
1735 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_UPDATE");
1739 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl
*ctrl
,
1740 int argc
, char *argv
[])
1742 return wpa_cli_cmd(ctrl
, "P2P_SERV_DISC_EXTERNAL", 1, argc
, argv
);
1746 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl
*ctrl
, int argc
,
1749 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_FLUSH");
1753 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl
*ctrl
, int argc
,
1759 if (argc
!= 3 && argc
!= 4) {
1760 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1766 res
= os_snprintf(cmd
, sizeof(cmd
),
1767 "P2P_SERVICE_ADD %s %s %s %s",
1768 argv
[0], argv
[1], argv
[2], argv
[3]);
1770 res
= os_snprintf(cmd
, sizeof(cmd
),
1771 "P2P_SERVICE_ADD %s %s %s",
1772 argv
[0], argv
[1], argv
[2]);
1773 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1775 cmd
[sizeof(cmd
) - 1] = '\0';
1776 return wpa_ctrl_command(ctrl
, cmd
);
1780 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl
*ctrl
, int argc
,
1786 if (argc
!= 2 && argc
!= 3) {
1787 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1793 res
= os_snprintf(cmd
, sizeof(cmd
),
1794 "P2P_SERVICE_DEL %s %s %s",
1795 argv
[0], argv
[1], argv
[2]);
1797 res
= os_snprintf(cmd
, sizeof(cmd
),
1798 "P2P_SERVICE_DEL %s %s",
1800 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1802 cmd
[sizeof(cmd
) - 1] = '\0';
1803 return wpa_ctrl_command(ctrl
, cmd
);
1807 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl
*ctrl
,
1808 int argc
, char *argv
[])
1810 return wpa_cli_cmd(ctrl
, "P2P_REJECT", 1, argc
, argv
);
1814 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl
*ctrl
,
1815 int argc
, char *argv
[])
1817 return wpa_cli_cmd(ctrl
, "P2P_INVITE", 1, argc
, argv
);
1821 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1823 return wpa_cli_cmd(ctrl
, "P2P_PEER", 1, argc
, argv
);
1827 static char ** wpa_cli_complete_p2p_peer(const char *str
, int pos
)
1829 int arg
= get_cmd_arg_num(str
, pos
);
1834 res
= cli_txt_list_array(&p2p_peers
);
1842 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl
*ctrl
, char *cmd
,
1843 char *addr
, size_t addr_len
,
1846 char buf
[4096], *pos
;
1850 if (ctrl_conn
== NULL
)
1852 len
= sizeof(buf
) - 1;
1853 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
1856 printf("'%s' command timed out.\n", cmd
);
1858 } else if (ret
< 0) {
1859 printf("'%s' command failed.\n", cmd
);
1864 if (os_memcmp(buf
, "FAIL", 4) == 0)
1868 while (*pos
!= '\0' && *pos
!= '\n')
1871 os_strlcpy(addr
, buf
, addr_len
);
1872 if (!discovered
|| os_strstr(pos
, "[PROBE_REQ_ONLY]") == NULL
)
1873 printf("%s\n", addr
);
1878 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1880 char addr
[32], cmd
[64];
1883 discovered
= argc
> 0 && os_strcmp(argv
[0], "discovered") == 0;
1885 if (wpa_ctrl_command_p2p_peer(ctrl
, "P2P_PEER FIRST",
1886 addr
, sizeof(addr
), discovered
))
1889 os_snprintf(cmd
, sizeof(cmd
), "P2P_PEER NEXT-%s", addr
);
1890 } while (wpa_ctrl_command_p2p_peer(ctrl
, cmd
, addr
, sizeof(addr
),
1897 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1899 return wpa_cli_cmd(ctrl
, "P2P_SET", 2, argc
, argv
);
1903 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1905 return wpa_ctrl_command(ctrl
, "P2P_FLUSH");
1909 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl
*ctrl
, int argc
,
1912 return wpa_ctrl_command(ctrl
, "P2P_CANCEL");
1916 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl
*ctrl
, int argc
,
1919 return wpa_cli_cmd(ctrl
, "P2P_UNAUTHORIZE", 1, argc
, argv
);
1923 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl
*ctrl
, int argc
,
1926 if (argc
!= 0 && argc
!= 2 && argc
!= 4) {
1927 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
1928 "(preferred duration, interval; in microsecods).\n"
1929 "Optional second pair can be used to provide "
1930 "acceptable values.\n");
1934 return wpa_cli_cmd(ctrl
, "P2P_PRESENCE_REQ", 0, argc
, argv
);
1938 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl
*ctrl
, int argc
,
1941 if (argc
!= 0 && argc
!= 2) {
1942 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
1943 "(availability period, availability interval; in "
1945 "Extended Listen Timing can be cancelled with this "
1946 "command when used without parameters.\n");
1950 return wpa_cli_cmd(ctrl
, "P2P_EXT_LISTEN", 0, argc
, argv
);
1953 #endif /* CONFIG_P2P */
1956 #ifdef CONFIG_INTERWORKING
1957 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
1960 return wpa_ctrl_command(ctrl
, "FETCH_ANQP");
1964 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
1967 return wpa_ctrl_command(ctrl
, "STOP_FETCH_ANQP");
1971 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl
*ctrl
, int argc
,
1974 return wpa_cli_cmd(ctrl
, "INTERWORKING_SELECT", 0, argc
, argv
);
1978 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl
*ctrl
, int argc
,
1981 return wpa_cli_cmd(ctrl
, "INTERWORKING_CONNECT", 1, argc
, argv
);
1985 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1987 return wpa_cli_cmd(ctrl
, "ANQP_GET", 2, argc
, argv
);
1989 #endif /* CONFIG_INTERWORKING */
1994 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl
*ctrl
, int argc
,
1997 return wpa_cli_cmd(ctrl
, "HS20_ANQP_GET", 2, argc
, argv
);
2001 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl
*ctrl
, int argc
,
2007 printf("Command needs one or two arguments (dst mac addr and "
2008 "optional home realm)\n");
2012 if (write_cmd(cmd
, sizeof(cmd
), "HS20_GET_NAI_HOME_REALM_LIST",
2016 return wpa_ctrl_command(ctrl
, cmd
);
2019 #endif /* CONFIG_HS20 */
2022 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl
*ctrl
, int argc
,
2025 return wpa_cli_cmd(ctrl
, "STA_AUTOCONNECT", 1, argc
, argv
);
2029 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl
*ctrl
, int argc
,
2032 return wpa_cli_cmd(ctrl
, "TDLS_DISCOVER", 1, argc
, argv
);
2036 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl
*ctrl
, int argc
,
2039 return wpa_cli_cmd(ctrl
, "TDLS_SETUP", 1, argc
, argv
);
2043 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl
*ctrl
, int argc
,
2046 return wpa_cli_cmd(ctrl
, "TDLS_TEARDOWN", 1, argc
, argv
);
2050 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl
*ctrl
, int argc
,
2053 return wpa_ctrl_command(ctrl
, "SIGNAL_POLL");
2057 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
2060 return wpa_ctrl_command(ctrl
, "REAUTHENTICATE");
2064 #ifdef CONFIG_AUTOSCAN
2066 static int wpa_cli_cmd_autoscan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2069 return wpa_ctrl_command(ctrl
, "AUTOSCAN ");
2071 return wpa_cli_cmd(ctrl
, "AUTOSCAN", 0, argc
, argv
);
2074 #endif /* CONFIG_AUTOSCAN */
2077 enum wpa_cli_cmd_flags
{
2078 cli_cmd_flag_none
= 0x00,
2079 cli_cmd_flag_sensitive
= 0x01
2082 struct wpa_cli_cmd
{
2084 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
2085 enum wpa_cli_cmd_flags flags
;
2089 static struct wpa_cli_cmd wpa_cli_commands
[] = {
2090 { "status", wpa_cli_cmd_status
,
2092 "[verbose] = get current WPA/EAPOL/EAP status" },
2093 { "ifname", wpa_cli_cmd_ifname
,
2095 "= get current interface name" },
2096 { "ping", wpa_cli_cmd_ping
,
2098 "= pings wpa_supplicant" },
2099 { "relog", wpa_cli_cmd_relog
,
2101 "= re-open log-file (allow rolling logs)" },
2102 { "note", wpa_cli_cmd_note
,
2104 "<text> = add a note to wpa_supplicant debug log" },
2105 { "mib", wpa_cli_cmd_mib
,
2107 "= get MIB variables (dot1x, dot11)" },
2108 { "help", wpa_cli_cmd_help
,
2110 "= show this usage help" },
2111 { "interface", wpa_cli_cmd_interface
,
2113 "[ifname] = show interfaces/select interface" },
2114 { "level", wpa_cli_cmd_level
,
2116 "<debug level> = change debug level" },
2117 { "license", wpa_cli_cmd_license
,
2119 "= show full wpa_cli license" },
2120 { "quit", wpa_cli_cmd_quit
,
2123 { "set", wpa_cli_cmd_set
,
2125 "= set variables (shows list of variables when run without "
2127 { "get", wpa_cli_cmd_get
,
2129 "<name> = get information" },
2130 { "logon", wpa_cli_cmd_logon
,
2132 "= IEEE 802.1X EAPOL state machine logon" },
2133 { "logoff", wpa_cli_cmd_logoff
,
2135 "= IEEE 802.1X EAPOL state machine logoff" },
2136 { "pmksa", wpa_cli_cmd_pmksa
,
2138 "= show PMKSA cache" },
2139 { "reassociate", wpa_cli_cmd_reassociate
,
2141 "= force reassociation" },
2142 { "preauthenticate", wpa_cli_cmd_preauthenticate
,
2144 "<BSSID> = force preauthentication" },
2145 { "identity", wpa_cli_cmd_identity
,
2147 "<network id> <identity> = configure identity for an SSID" },
2148 { "password", wpa_cli_cmd_password
,
2149 cli_cmd_flag_sensitive
,
2150 "<network id> <password> = configure password for an SSID" },
2151 { "new_password", wpa_cli_cmd_new_password
,
2152 cli_cmd_flag_sensitive
,
2153 "<network id> <password> = change password for an SSID" },
2154 { "pin", wpa_cli_cmd_pin
,
2155 cli_cmd_flag_sensitive
,
2156 "<network id> <pin> = configure pin for an SSID" },
2157 { "otp", wpa_cli_cmd_otp
,
2158 cli_cmd_flag_sensitive
,
2159 "<network id> <password> = configure one-time-password for an SSID"
2161 { "passphrase", wpa_cli_cmd_passphrase
,
2162 cli_cmd_flag_sensitive
,
2163 "<network id> <passphrase> = configure private key passphrase\n"
2165 { "bssid", wpa_cli_cmd_bssid
,
2167 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2168 { "blacklist", wpa_cli_cmd_blacklist
,
2170 "<BSSID> = add a BSSID to the blacklist\n"
2171 "blacklist clear = clear the blacklist\n"
2172 "blacklist = display the blacklist" },
2173 { "log_level", wpa_cli_cmd_log_level
,
2175 "<level> [<timestamp>] = update the log level/timestamp\n"
2176 "log_level = display the current log level and log options" },
2177 { "list_networks", wpa_cli_cmd_list_networks
,
2179 "= list configured networks" },
2180 { "select_network", wpa_cli_cmd_select_network
,
2182 "<network id> = select a network (disable others)" },
2183 { "enable_network", wpa_cli_cmd_enable_network
,
2185 "<network id> = enable a network" },
2186 { "disable_network", wpa_cli_cmd_disable_network
,
2188 "<network id> = disable a network" },
2189 { "add_network", wpa_cli_cmd_add_network
,
2191 "= add a network" },
2192 { "remove_network", wpa_cli_cmd_remove_network
,
2194 "<network id> = remove a network" },
2195 { "set_network", wpa_cli_cmd_set_network
,
2196 cli_cmd_flag_sensitive
,
2197 "<network id> <variable> <value> = set network variables (shows\n"
2198 " list of variables when run without arguments)" },
2199 { "get_network", wpa_cli_cmd_get_network
,
2201 "<network id> <variable> = get network variables" },
2202 { "list_creds", wpa_cli_cmd_list_creds
,
2204 "= list configured credentials" },
2205 { "add_cred", wpa_cli_cmd_add_cred
,
2207 "= add a credential" },
2208 { "remove_cred", wpa_cli_cmd_remove_cred
,
2210 "<cred id> = remove a credential" },
2211 { "set_cred", wpa_cli_cmd_set_cred
,
2212 cli_cmd_flag_sensitive
,
2213 "<cred id> <variable> <value> = set credential variables" },
2214 { "save_config", wpa_cli_cmd_save_config
,
2216 "= save the current configuration" },
2217 { "disconnect", wpa_cli_cmd_disconnect
,
2219 "= disconnect and wait for reassociate/reconnect command before\n"
2221 { "reconnect", wpa_cli_cmd_reconnect
,
2223 "= like reassociate, but only takes effect if already disconnected"
2225 { "scan", wpa_cli_cmd_scan
,
2227 "= request new BSS scan" },
2228 { "scan_results", wpa_cli_cmd_scan_results
,
2230 "= get latest scan results" },
2231 { "bss", wpa_cli_cmd_bss
,
2233 "<<idx> | <bssid>> = get detailed scan result info" },
2234 { "get_capability", wpa_cli_cmd_get_capability
,
2236 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels> "
2237 "= get capabilies" },
2238 { "reconfigure", wpa_cli_cmd_reconfigure
,
2240 "= force wpa_supplicant to re-read its configuration file" },
2241 { "terminate", wpa_cli_cmd_terminate
,
2243 "= terminate wpa_supplicant" },
2244 { "interface_add", wpa_cli_cmd_interface_add
,
2246 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2247 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2249 { "interface_remove", wpa_cli_cmd_interface_remove
,
2251 "<ifname> = removes the interface" },
2252 { "interface_list", wpa_cli_cmd_interface_list
,
2254 "= list available interfaces" },
2255 { "ap_scan", wpa_cli_cmd_ap_scan
,
2257 "<value> = set ap_scan parameter" },
2258 { "scan_interval", wpa_cli_cmd_scan_interval
,
2260 "<value> = set scan_interval parameter (in seconds)" },
2261 { "bss_expire_age", wpa_cli_cmd_bss_expire_age
,
2263 "<value> = set BSS expiration age parameter" },
2264 { "bss_expire_count", wpa_cli_cmd_bss_expire_count
,
2266 "<value> = set BSS expiration scan count parameter" },
2267 { "stkstart", wpa_cli_cmd_stkstart
,
2269 "<addr> = request STK negotiation with <addr>" },
2270 { "ft_ds", wpa_cli_cmd_ft_ds
,
2272 "<addr> = request over-the-DS FT with <addr>" },
2273 { "wps_pbc", wpa_cli_cmd_wps_pbc
,
2275 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2276 { "wps_pin", wpa_cli_cmd_wps_pin
,
2277 cli_cmd_flag_sensitive
,
2278 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2280 { "wps_check_pin", wpa_cli_cmd_wps_check_pin
,
2281 cli_cmd_flag_sensitive
,
2282 "<PIN> = verify PIN checksum" },
2283 { "wps_cancel", wpa_cli_cmd_wps_cancel
, cli_cmd_flag_none
,
2284 "Cancels the pending WPS operation" },
2285 #ifdef CONFIG_WPS_OOB
2286 { "wps_oob", wpa_cli_cmd_wps_oob
,
2287 cli_cmd_flag_sensitive
,
2288 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2289 #endif /* CONFIG_WPS_OOB */
2290 #ifdef CONFIG_WPS_NFC
2291 { "wps_nfc", wpa_cli_cmd_wps_nfc
,
2293 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
2294 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token
,
2296 "<WPS|NDEF> = create password token" },
2297 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read
,
2298 cli_cmd_flag_sensitive
,
2299 "<hexdump of payload> = report read NFC tag with WPS data" },
2300 #endif /* CONFIG_WPS_NFC */
2301 { "wps_reg", wpa_cli_cmd_wps_reg
,
2302 cli_cmd_flag_sensitive
,
2303 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2304 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin
,
2305 cli_cmd_flag_sensitive
,
2306 "[params..] = enable/disable AP PIN" },
2307 { "wps_er_start", wpa_cli_cmd_wps_er_start
,
2309 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2310 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
,
2312 "= stop Wi-Fi Protected Setup External Registrar" },
2313 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
,
2314 cli_cmd_flag_sensitive
,
2315 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2316 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
,
2318 "<UUID> = accept an Enrollee PBC using External Registrar" },
2319 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
,
2320 cli_cmd_flag_sensitive
,
2321 "<UUID> <PIN> = learn AP configuration" },
2322 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config
,
2324 "<UUID> <network id> = set AP configuration for enrolling" },
2325 { "wps_er_config", wpa_cli_cmd_wps_er_config
,
2326 cli_cmd_flag_sensitive
,
2327 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2328 #ifdef CONFIG_WPS_NFC
2329 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token
,
2331 "<WPS/NDEF> <UUID> = build NFC configuration token" },
2332 #endif /* CONFIG_WPS_NFC */
2333 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
,
2335 "<addr> = request RSN authentication with <addr> in IBSS" },
2337 { "sta", wpa_cli_cmd_sta
,
2339 "<addr> = get information about an associated station (AP)" },
2340 { "all_sta", wpa_cli_cmd_all_sta
,
2342 "= get information about all associated stations (AP)" },
2343 { "deauthenticate", wpa_cli_cmd_deauthenticate
,
2345 "<addr> = deauthenticate a station" },
2346 { "disassociate", wpa_cli_cmd_disassociate
,
2348 "<addr> = disassociate a station" },
2349 #endif /* CONFIG_AP */
2350 { "suspend", wpa_cli_cmd_suspend
, cli_cmd_flag_none
,
2351 "= notification of suspend/hibernate" },
2352 { "resume", wpa_cli_cmd_resume
, cli_cmd_flag_none
,
2353 "= notification of resume/thaw" },
2354 { "drop_sa", wpa_cli_cmd_drop_sa
, cli_cmd_flag_none
,
2355 "= drop SA without deauth/disassoc (test command)" },
2356 { "roam", wpa_cli_cmd_roam
,
2358 "<addr> = roam to the specified BSS" },
2360 { "p2p_find", wpa_cli_cmd_p2p_find
, cli_cmd_flag_none
,
2361 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2362 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find
, cli_cmd_flag_none
,
2363 "= stop P2P Devices search" },
2364 { "p2p_connect", wpa_cli_cmd_p2p_connect
, cli_cmd_flag_none
,
2365 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
2366 { "p2p_listen", wpa_cli_cmd_p2p_listen
, cli_cmd_flag_none
,
2367 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2368 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove
, cli_cmd_flag_none
,
2369 "<ifname> = remove P2P group interface (terminate group if GO)" },
2370 { "p2p_group_add", wpa_cli_cmd_p2p_group_add
, cli_cmd_flag_none
,
2371 "[ht40] = add a new P2P group (local end as GO)" },
2372 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc
, cli_cmd_flag_none
,
2373 "<addr> <method> = request provisioning discovery" },
2374 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase
,
2376 "= get the passphrase for a group (GO only)" },
2377 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req
,
2379 "<addr> <TLVs> = schedule service discovery request" },
2380 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req
,
2382 "<id> = cancel pending service discovery request" },
2383 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp
,
2385 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2386 { "p2p_service_update", wpa_cli_cmd_p2p_service_update
,
2388 "= indicate change in local services" },
2389 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external
,
2391 "<external> = set external processing of service discovery" },
2392 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush
,
2394 "= remove all stored service entries" },
2395 { "p2p_service_add", wpa_cli_cmd_p2p_service_add
,
2397 "<bonjour|upnp> <query|version> <response|service> = add a local "
2399 { "p2p_service_del", wpa_cli_cmd_p2p_service_del
,
2401 "<bonjour|upnp> <query|version> [|service] = remove a local "
2403 { "p2p_reject", wpa_cli_cmd_p2p_reject
,
2405 "<addr> = reject connection attempts from a specific peer" },
2406 { "p2p_invite", wpa_cli_cmd_p2p_invite
,
2408 "<cmd> [peer=addr] = invite peer" },
2409 { "p2p_peers", wpa_cli_cmd_p2p_peers
, cli_cmd_flag_none
,
2410 "[discovered] = list known (optionally, only fully discovered) P2P "
2412 { "p2p_peer", wpa_cli_cmd_p2p_peer
, cli_cmd_flag_none
,
2413 "<address> = show information about known P2P peer" },
2414 { "p2p_set", wpa_cli_cmd_p2p_set
, cli_cmd_flag_none
,
2415 "<field> <value> = set a P2P parameter" },
2416 { "p2p_flush", wpa_cli_cmd_p2p_flush
, cli_cmd_flag_none
,
2417 "= flush P2P state" },
2418 { "p2p_cancel", wpa_cli_cmd_p2p_cancel
, cli_cmd_flag_none
,
2419 "= cancel P2P group formation" },
2420 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize
, cli_cmd_flag_none
,
2421 "<address> = unauthorize a peer" },
2422 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req
, cli_cmd_flag_none
,
2423 "[<duration> <interval>] [<duration> <interval>] = request GO "
2425 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen
, cli_cmd_flag_none
,
2426 "[<period> <interval>] = set extended listen timing" },
2427 #endif /* CONFIG_P2P */
2429 #ifdef CONFIG_INTERWORKING
2430 { "fetch_anqp", wpa_cli_cmd_fetch_anqp
, cli_cmd_flag_none
,
2431 "= fetch ANQP information for all APs" },
2432 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp
, cli_cmd_flag_none
,
2433 "= stop fetch_anqp operation" },
2434 { "interworking_select", wpa_cli_cmd_interworking_select
,
2436 "[auto] = perform Interworking network selection" },
2437 { "interworking_connect", wpa_cli_cmd_interworking_connect
,
2439 "<BSSID> = connect using Interworking credentials" },
2440 { "anqp_get", wpa_cli_cmd_anqp_get
, cli_cmd_flag_none
,
2441 "<addr> <info id>[,<info id>]... = request ANQP information" },
2442 #endif /* CONFIG_INTERWORKING */
2444 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get
, cli_cmd_flag_none
,
2445 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
2447 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list
,
2449 "<addr> <home realm> = get HS20 nai home realm list" },
2450 #endif /* CONFIG_HS20 */
2451 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect
, cli_cmd_flag_none
,
2452 "<0/1> = disable/enable automatic reconnection" },
2453 { "tdls_discover", wpa_cli_cmd_tdls_discover
,
2455 "<addr> = request TDLS discovery with <addr>" },
2456 { "tdls_setup", wpa_cli_cmd_tdls_setup
,
2458 "<addr> = request TDLS setup with <addr>" },
2459 { "tdls_teardown", wpa_cli_cmd_tdls_teardown
,
2461 "<addr> = tear down TDLS with <addr>" },
2462 { "signal_poll", wpa_cli_cmd_signal_poll
,
2464 "= get signal parameters" },
2465 { "reauthenticate", wpa_cli_cmd_reauthenticate
, cli_cmd_flag_none
,
2466 "= trigger IEEE 802.1X/EAPOL reauthentication" },
2467 #ifdef CONFIG_AUTOSCAN
2468 { "autoscan", wpa_cli_cmd_autoscan
, cli_cmd_flag_none
,
2469 "[params] = Set or unset (if none) autoscan parameters" },
2470 #endif /* CONFIG_AUTOSCAN */
2471 { NULL
, NULL
, cli_cmd_flag_none
, NULL
}
2476 * Prints command usage, lines are padded with the specified string.
2478 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
2483 printf("%s%s ", pad
, cmd
->cmd
);
2484 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
2493 static void print_help(void)
2496 printf("commands:\n");
2497 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++)
2498 print_cmd_help(&wpa_cli_commands
[n
], " ");
2502 static int wpa_cli_edit_filter_history_cb(void *ctx
, const char *cmd
)
2504 const char *c
, *delim
;
2508 delim
= os_strchr(cmd
, ' ');
2512 len
= os_strlen(cmd
);
2514 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
2515 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
2516 return (wpa_cli_commands
[n
].flags
&
2517 cli_cmd_flag_sensitive
);
2523 static char ** wpa_list_cmd_list(void)
2528 count
= sizeof(wpa_cli_commands
) / sizeof(wpa_cli_commands
[0]);
2529 res
= os_calloc(count
, sizeof(char *));
2533 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2534 res
[i
] = os_strdup(wpa_cli_commands
[i
].cmd
);
2543 static char ** wpa_cli_cmd_completion(const char *cmd
, const char *str
,
2548 if (os_strcasecmp(cmd
, "bss") == 0)
2549 return wpa_cli_complete_bss(str
, pos
);
2551 if (os_strcasecmp(cmd
, "p2p_connect") == 0)
2552 return wpa_cli_complete_p2p_connect(str
, pos
);
2553 if (os_strcasecmp(cmd
, "p2p_peer") == 0)
2554 return wpa_cli_complete_p2p_peer(str
, pos
);
2555 if (os_strcasecmp(cmd
, "p2p_group_remove") == 0)
2556 return wpa_cli_complete_p2p_group_remove(str
, pos
);
2557 #endif /* CONFIG_P2P */
2559 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2560 if (os_strcasecmp(wpa_cli_commands
[i
].cmd
, cmd
) == 0) {
2562 printf("\r%s\n", wpa_cli_commands
[i
].usage
);
2572 static char ** wpa_cli_edit_completion_cb(void *ctx
, const char *str
, int pos
)
2578 end
= os_strchr(str
, ' ');
2579 if (end
== NULL
|| str
+ pos
< end
)
2580 return wpa_list_cmd_list();
2582 cmd
= os_malloc(pos
+ 1);
2585 os_memcpy(cmd
, str
, pos
);
2586 cmd
[end
- str
] = '\0';
2587 res
= wpa_cli_cmd_completion(cmd
, str
, pos
);
2593 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2595 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
2600 cmd
= wpa_cli_commands
;
2602 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
2605 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
2606 /* we have an exact match */
2616 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
2617 cmd
= wpa_cli_commands
;
2619 if (os_strncasecmp(cmd
->cmd
, argv
[0],
2620 os_strlen(argv
[0])) == 0) {
2621 printf(" %s", cmd
->cmd
);
2627 } else if (count
== 0) {
2628 printf("Unknown command '%s'\n", argv
[0]);
2631 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
2638 static int str_match(const char *a
, const char *b
)
2640 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
2644 static int wpa_cli_exec(const char *program
, const char *arg1
,
2652 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
2653 cmd
= os_malloc(len
);
2656 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
2657 if (res
< 0 || (size_t) res
>= len
) {
2661 cmd
[len
- 1] = '\0';
2663 if (system(cmd
) < 0)
2665 #endif /* _WIN32_WCE */
2672 static void wpa_cli_action_process(const char *msg
)
2675 char *copy
= NULL
, *id
, *pos2
;
2680 pos
= os_strchr(pos
, '>');
2687 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
2689 os_unsetenv("WPA_ID");
2690 os_unsetenv("WPA_ID_STR");
2691 os_unsetenv("WPA_CTRL_DIR");
2693 pos
= os_strstr(pos
, "[id=");
2695 copy
= os_strdup(pos
+ 4);
2699 while (*pos2
&& *pos2
!= ' ')
2703 os_setenv("WPA_ID", id
, 1);
2704 while (*pos2
&& *pos2
!= '=')
2709 while (*pos2
&& *pos2
!= ']')
2712 os_setenv("WPA_ID_STR", id
, 1);
2716 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
2718 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
2719 wpa_cli_connected
= 1;
2720 wpa_cli_last_id
= new_id
;
2721 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
2723 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
2724 if (wpa_cli_connected
) {
2725 wpa_cli_connected
= 0;
2726 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
2728 } else if (str_match(pos
, P2P_EVENT_GROUP_STARTED
)) {
2729 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2730 } else if (str_match(pos
, P2P_EVENT_GROUP_REMOVED
)) {
2731 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2732 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_ENABLE
)) {
2733 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2734 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_DISABLE
)) {
2735 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2736 } else if (str_match(pos
, P2P_EVENT_GO_NEG_FAILURE
)) {
2737 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2738 } else if (str_match(pos
, WPS_EVENT_SUCCESS
)) {
2739 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2740 } else if (str_match(pos
, WPS_EVENT_FAIL
)) {
2741 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2742 } else if (str_match(pos
, AP_STA_CONNECTED
)) {
2743 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2744 } else if (str_match(pos
, AP_STA_DISCONNECTED
)) {
2745 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2746 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
2747 printf("wpa_supplicant is terminating - stop monitoring\n");
2753 #ifndef CONFIG_ANSI_C_EXTRA
2754 static void wpa_cli_action_cb(char *msg
, size_t len
)
2756 wpa_cli_action_process(msg
);
2758 #endif /* CONFIG_ANSI_C_EXTRA */
2761 static void wpa_cli_reconnect(void)
2763 wpa_cli_close_connection();
2764 if (wpa_cli_open_connection(ctrl_ifname
, 1) < 0)
2769 printf("\rConnection to wpa_supplicant re-established\n");
2775 static void cli_event(const char *str
)
2777 const char *start
, *s
;
2779 start
= os_strchr(str
, '>');
2785 if (str_starts(start
, WPA_EVENT_BSS_ADDED
)) {
2786 s
= os_strchr(start
, ' ');
2789 s
= os_strchr(s
+ 1, ' ');
2792 cli_txt_list_add(&bsses
, s
+ 1);
2796 if (str_starts(start
, WPA_EVENT_BSS_REMOVED
)) {
2797 s
= os_strchr(start
, ' ');
2800 s
= os_strchr(s
+ 1, ' ');
2803 cli_txt_list_del_addr(&bsses
, s
+ 1);
2808 if (str_starts(start
, P2P_EVENT_DEVICE_FOUND
)) {
2809 s
= os_strstr(start
, " p2p_dev_addr=");
2812 cli_txt_list_add_addr(&p2p_peers
, s
+ 14);
2816 if (str_starts(start
, P2P_EVENT_DEVICE_LOST
)) {
2817 s
= os_strstr(start
, " p2p_dev_addr=");
2820 cli_txt_list_del_addr(&p2p_peers
, s
+ 14);
2824 if (str_starts(start
, P2P_EVENT_GROUP_STARTED
)) {
2825 s
= os_strchr(start
, ' ');
2828 cli_txt_list_add_word(&p2p_groups
, s
+ 1);
2832 if (str_starts(start
, P2P_EVENT_GROUP_REMOVED
)) {
2833 s
= os_strchr(start
, ' ');
2836 cli_txt_list_del_word(&p2p_groups
, s
+ 1);
2839 #endif /* CONFIG_P2P */
2843 static int check_terminating(const char *msg
)
2845 const char *pos
= msg
;
2849 pos
= os_strchr(pos
, '>');
2856 if (str_match(pos
, WPA_EVENT_TERMINATING
) && ctrl_conn
) {
2858 printf("\rConnection to wpa_supplicant lost - trying to "
2861 wpa_cli_attached
= 0;
2862 wpa_cli_close_connection();
2870 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int action_monitor
)
2872 if (ctrl_conn
== NULL
) {
2873 wpa_cli_reconnect();
2876 while (wpa_ctrl_pending(ctrl
) > 0) {
2878 size_t len
= sizeof(buf
) - 1;
2879 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
2882 wpa_cli_action_process(buf
);
2885 if (wpa_cli_show_event(buf
)) {
2887 printf("\r%s\n", buf
);
2891 if (interactive
&& check_terminating(buf
) > 0)
2895 printf("Could not read pending message.\n");
2900 if (wpa_ctrl_pending(ctrl
) < 0) {
2901 printf("Connection to wpa_supplicant lost - trying to "
2903 wpa_cli_reconnect();
2909 static int tokenize_cmd(char *cmd
, char *argv
[])
2922 if (argc
== max_args
)
2925 char *pos2
= os_strrchr(pos
, '"');
2929 while (*pos
!= '\0' && *pos
!= ' ')
2939 static void wpa_cli_ping(void *eloop_ctx
, void *timeout_ctx
)
2941 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
2942 printf("Connection to wpa_supplicant lost - trying to "
2944 wpa_cli_close_connection();
2947 wpa_cli_reconnect();
2948 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
2952 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
)
2954 wpa_cli_recv_pending(mon_conn
, 0);
2958 static void wpa_cli_edit_cmd_cb(void *ctx
, char *cmd
)
2960 char *argv
[max_args
];
2962 argc
= tokenize_cmd(cmd
, argv
);
2964 wpa_request(ctrl_conn
, argc
, argv
);
2968 static void wpa_cli_edit_eof_cb(void *ctx
)
2974 static int warning_displayed
= 0;
2975 static char *hfile
= NULL
;
2976 static int edit_started
= 0;
2978 static void start_edit(void)
2983 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
2984 ps
= wpa_ctrl_get_remote_ifname(ctrl_conn
);
2985 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
2987 home
= getenv("HOME");
2989 const char *fname
= ".wpa_cli_history";
2990 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
2991 hfile
= os_malloc(hfile_len
);
2993 os_snprintf(hfile
, hfile_len
, "%s/%s", home
, fname
);
2996 if (edit_init(wpa_cli_edit_cmd_cb
, wpa_cli_edit_eof_cb
,
2997 wpa_cli_edit_completion_cb
, NULL
, hfile
, ps
) < 0) {
3003 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3007 static void try_connection(void *eloop_ctx
, void *timeout_ctx
)
3009 if (ctrl_ifname
== NULL
)
3010 ctrl_ifname
= wpa_cli_get_default_ifname();
3012 if (!wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
3013 if (!warning_displayed
) {
3014 printf("Could not connect to wpa_supplicant: "
3015 "%s - re-trying\n", ctrl_ifname
);
3016 warning_displayed
= 1;
3018 eloop_register_timeout(1, 0, try_connection
, NULL
, NULL
);
3022 if (warning_displayed
)
3023 printf("Connection established.\n");
3029 static void wpa_cli_interactive(void)
3031 printf("\nInteractive mode\n\n");
3033 eloop_register_timeout(0, 0, try_connection
, NULL
, NULL
);
3035 eloop_cancel_timeout(try_connection
, NULL
, NULL
);
3037 cli_txt_list_flush(&p2p_peers
);
3038 cli_txt_list_flush(&p2p_groups
);
3039 cli_txt_list_flush(&bsses
);
3041 edit_deinit(hfile
, wpa_cli_edit_filter_history_cb
);
3043 eloop_cancel_timeout(wpa_cli_ping
, NULL
, NULL
);
3044 wpa_cli_close_connection();
3048 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
3050 #ifdef CONFIG_ANSI_C_EXTRA
3051 /* TODO: ANSI C version(?) */
3052 printf("Action processing not supported in ANSI C build.\n");
3053 #else /* CONFIG_ANSI_C_EXTRA */
3057 char buf
[256]; /* note: large enough to fit in unsolicited messages */
3060 fd
= wpa_ctrl_get_fd(ctrl
);
3062 while (!wpa_cli_quit
) {
3065 tv
.tv_sec
= ping_interval
;
3067 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
3068 if (res
< 0 && errno
!= EINTR
) {
3073 if (FD_ISSET(fd
, &rfds
))
3074 wpa_cli_recv_pending(ctrl
, 1);
3076 /* verify that connection is still working */
3077 len
= sizeof(buf
) - 1;
3078 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
3079 wpa_cli_action_cb
) < 0 ||
3080 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
3081 printf("wpa_supplicant did not reply to PING "
3082 "command - exiting\n");
3087 #endif /* CONFIG_ANSI_C_EXTRA */
3091 static void wpa_cli_cleanup(void)
3093 wpa_cli_close_connection();
3095 os_daemonize_terminate(pid_file
);
3097 os_program_deinit();
3101 static void wpa_cli_terminate(int sig
, void *ctx
)
3107 static char * wpa_cli_get_default_ifname(void)
3109 char *ifname
= NULL
;
3111 #ifdef CONFIG_CTRL_IFACE_UNIX
3112 struct dirent
*dent
;
3113 DIR *dir
= opendir(ctrl_iface_dir
);
3116 char ifprop
[PROPERTY_VALUE_MAX
];
3117 if (property_get("wifi.interface", ifprop
, NULL
) != 0) {
3118 ifname
= os_strdup(ifprop
);
3119 printf("Using interface '%s'\n", ifname
);
3122 #endif /* ANDROID */
3125 while ((dent
= readdir(dir
))) {
3126 #ifdef _DIRENT_HAVE_D_TYPE
3128 * Skip the file if it is not a socket. Also accept
3129 * DT_UNKNOWN (0) in case the C library or underlying
3130 * file system does not support d_type.
3132 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
3134 #endif /* _DIRENT_HAVE_D_TYPE */
3135 if (os_strcmp(dent
->d_name
, ".") == 0 ||
3136 os_strcmp(dent
->d_name
, "..") == 0)
3138 printf("Selected interface '%s'\n", dent
->d_name
);
3139 ifname
= os_strdup(dent
->d_name
);
3143 #endif /* CONFIG_CTRL_IFACE_UNIX */
3145 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3146 char buf
[2048], *pos
;
3148 struct wpa_ctrl
*ctrl
;
3151 ctrl
= wpa_ctrl_open(NULL
);
3155 len
= sizeof(buf
) - 1;
3156 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
3159 pos
= os_strchr(buf
, '\n');
3162 ifname
= os_strdup(buf
);
3164 wpa_ctrl_close(ctrl
);
3165 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3171 int main(int argc
, char *argv
[])
3176 const char *global
= NULL
;
3178 if (os_program_init())
3182 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
3187 action_file
= optarg
;
3196 ping_interval
= atoi(optarg
);
3202 printf("%s\n", wpa_cli_version
);
3205 os_free(ctrl_ifname
);
3206 ctrl_ifname
= os_strdup(optarg
);
3209 ctrl_iface_dir
= optarg
;
3220 interactive
= (argc
== optind
) && (action_file
== NULL
);
3223 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
3229 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3230 ctrl_conn
= wpa_ctrl_open(NULL
);
3231 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3232 ctrl_conn
= wpa_ctrl_open(global
);
3233 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3234 if (ctrl_conn
== NULL
) {
3235 fprintf(stderr
, "Failed to connect to wpa_supplicant "
3236 "global interface: %s error: %s\n",
3237 global
, strerror(errno
));
3242 eloop_register_signal_terminate(wpa_cli_terminate
, NULL
);
3244 if (ctrl_ifname
== NULL
)
3245 ctrl_ifname
= wpa_cli_get_default_ifname();
3248 wpa_cli_interactive();
3251 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
3252 fprintf(stderr
, "Failed to connect to non-global "
3253 "ctrl_ifname: %s error: %s\n",
3254 ctrl_ifname
, strerror(errno
));
3259 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
3260 wpa_cli_attached
= 1;
3262 printf("Warning: Failed to attach to "
3263 "wpa_supplicant.\n");
3268 if (daemonize
&& os_daemonize(pid_file
))
3272 wpa_cli_action(ctrl_conn
);
3274 ret
= wpa_request(ctrl_conn
, argc
- optind
,
3278 os_free(ctrl_ifname
);
3285 #else /* CONFIG_CTRL_IFACE */
3286 int main(int argc
, char *argv
[])
3288 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3291 #endif /* CONFIG_CTRL_IFACE */