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(const char *cmd
);
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);
99 static char ** wpa_list_cmd_list(void);
102 static void usage(void)
104 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
105 "[-a<action file>] \\\n"
106 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
108 " -h = help (show this usage text)\n"
109 " -v = shown version information\n"
110 " -a = run in daemon mode executing the action file based on "
113 " -B = run a daemon in the background\n"
114 " default path: " CONFIG_CTRL_IFACE_DIR
"\n"
115 " default interface: first interface found in socket path\n");
120 static void cli_txt_list_free(struct cli_txt_entry
*e
)
122 dl_list_del(&e
->list
);
128 static void cli_txt_list_flush(struct dl_list
*list
)
130 struct cli_txt_entry
*e
;
131 while ((e
= dl_list_first(list
, struct cli_txt_entry
, list
)))
132 cli_txt_list_free(e
);
136 static struct cli_txt_entry
* cli_txt_list_get(struct dl_list
*txt_list
,
139 struct cli_txt_entry
*e
;
140 dl_list_for_each(e
, txt_list
, struct cli_txt_entry
, list
) {
141 if (os_strcmp(e
->txt
, txt
) == 0)
148 static void cli_txt_list_del(struct dl_list
*txt_list
, const char *txt
)
150 struct cli_txt_entry
*e
;
151 e
= cli_txt_list_get(txt_list
, txt
);
153 cli_txt_list_free(e
);
157 static void cli_txt_list_del_addr(struct dl_list
*txt_list
, const char *txt
)
161 if (hwaddr_aton(txt
, addr
) < 0)
163 os_snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
164 cli_txt_list_del(txt_list
, buf
);
169 static void cli_txt_list_del_word(struct dl_list
*txt_list
, const char *txt
)
173 end
= os_strchr(txt
, ' ');
175 end
= txt
+ os_strlen(txt
);
176 buf
= os_malloc(end
- txt
+ 1);
179 os_memcpy(buf
, txt
, end
- txt
);
180 buf
[end
- txt
] = '\0';
181 cli_txt_list_del(txt_list
, buf
);
184 #endif /* CONFIG_P2P */
187 static int cli_txt_list_add(struct dl_list
*txt_list
, const char *txt
)
189 struct cli_txt_entry
*e
;
190 e
= cli_txt_list_get(txt_list
, txt
);
193 e
= os_zalloc(sizeof(*e
));
196 e
->txt
= os_strdup(txt
);
197 if (e
->txt
== NULL
) {
201 dl_list_add(txt_list
, &e
->list
);
207 static int cli_txt_list_add_addr(struct dl_list
*txt_list
, const char *txt
)
211 if (hwaddr_aton(txt
, addr
) < 0)
213 os_snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
214 return cli_txt_list_add(txt_list
, buf
);
218 static int cli_txt_list_add_word(struct dl_list
*txt_list
, const char *txt
)
223 end
= os_strchr(txt
, ' ');
225 end
= txt
+ os_strlen(txt
);
226 buf
= os_malloc(end
- txt
+ 1);
229 os_memcpy(buf
, txt
, end
- txt
);
230 buf
[end
- txt
] = '\0';
231 ret
= cli_txt_list_add(txt_list
, buf
);
235 #endif /* CONFIG_P2P */
238 static char ** cli_txt_list_array(struct dl_list
*txt_list
)
240 unsigned int i
, count
= dl_list_len(txt_list
);
242 struct cli_txt_entry
*e
;
244 res
= os_calloc(count
+ 1, sizeof(char *));
249 dl_list_for_each(e
, txt_list
, struct cli_txt_entry
, list
) {
250 res
[i
] = os_strdup(e
->txt
);
260 static int get_cmd_arg_num(const char *str
, int pos
)
264 for (i
= 0; i
<= pos
; i
++) {
267 while (i
<= pos
&& str
[i
] != ' ')
278 static int str_starts(const char *src
, const char *match
)
280 return os_strncmp(src
, match
, os_strlen(match
)) == 0;
284 static int wpa_cli_show_event(const char *event
)
288 start
= os_strchr(event
, '>');
294 * Skip BSS added/removed events since they can be relatively frequent
295 * and are likely of not much use for an interactive user.
297 if (str_starts(start
, WPA_EVENT_BSS_ADDED
) ||
298 str_starts(start
, WPA_EVENT_BSS_REMOVED
))
305 static int wpa_cli_open_connection(const char *ifname
, int attach
)
307 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
308 ctrl_conn
= wpa_ctrl_open(ifname
);
309 if (ctrl_conn
== NULL
)
312 if (attach
&& interactive
)
313 mon_conn
= wpa_ctrl_open(ifname
);
316 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
324 if (access(ctrl_iface_dir
, F_OK
) < 0) {
325 cfile
= os_strdup(ifname
);
332 flen
= os_strlen(ctrl_iface_dir
) + os_strlen(ifname
) + 2;
333 cfile
= os_malloc(flen
);
336 res
= os_snprintf(cfile
, flen
, "%s/%s", ctrl_iface_dir
,
338 if (res
< 0 || res
>= flen
) {
344 ctrl_conn
= wpa_ctrl_open(cfile
);
345 if (ctrl_conn
== NULL
) {
350 if (attach
&& interactive
)
351 mon_conn
= wpa_ctrl_open(cfile
);
355 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
358 if (wpa_ctrl_attach(mon_conn
) == 0) {
359 wpa_cli_attached
= 1;
361 eloop_register_read_sock(
362 wpa_ctrl_get_fd(mon_conn
),
363 wpa_cli_mon_receive
, NULL
, NULL
);
365 printf("Warning: Failed to attach to "
366 "wpa_supplicant.\n");
367 wpa_cli_close_connection();
376 static void wpa_cli_close_connection(void)
378 if (ctrl_conn
== NULL
)
381 if (wpa_cli_attached
) {
382 wpa_ctrl_detach(interactive
? mon_conn
: ctrl_conn
);
383 wpa_cli_attached
= 0;
385 wpa_ctrl_close(ctrl_conn
);
388 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn
));
389 wpa_ctrl_close(mon_conn
);
395 static void wpa_cli_msg_cb(char *msg
, size_t len
)
401 static int _wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
, int print
)
407 if (ctrl_conn
== NULL
) {
408 printf("Not connected to wpa_supplicant - command dropped.\n");
411 len
= sizeof(buf
) - 1;
412 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
415 printf("'%s' command timed out.\n", cmd
);
417 } else if (ret
< 0) {
418 printf("'%s' command failed.\n", cmd
);
424 if (interactive
&& len
> 0 && buf
[len
- 1] != '\n')
431 static int wpa_ctrl_command(struct wpa_ctrl
*ctrl
, char *cmd
)
433 return _wpa_ctrl_command(ctrl
, cmd
, 1);
437 static int write_cmd(char *buf
, size_t buflen
, const char *cmd
, int argc
,
446 res
= os_snprintf(pos
, end
- pos
, "%s", cmd
);
447 if (res
< 0 || res
>= end
- pos
)
451 for (i
= 0; i
< argc
; i
++) {
452 res
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
453 if (res
< 0 || res
>= end
- pos
)
458 buf
[buflen
- 1] = '\0';
462 printf("Too long command\n");
467 static int wpa_cli_cmd(struct wpa_ctrl
*ctrl
, const char *cmd
, int min_args
,
468 int argc
, char *argv
[])
471 if (argc
< min_args
) {
472 printf("Invalid %s command - at least %d argument%s "
473 "required.\n", cmd
, min_args
,
474 min_args
> 1 ? "s are" : " is");
477 if (write_cmd(buf
, sizeof(buf
), cmd
, argc
, argv
) < 0)
479 return wpa_ctrl_command(ctrl
, buf
);
483 static int wpa_cli_cmd_ifname(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
485 return wpa_ctrl_command(ctrl
, "IFNAME");
489 static int wpa_cli_cmd_status(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
491 if (argc
> 0 && os_strcmp(argv
[0], "verbose") == 0)
492 return wpa_ctrl_command(ctrl
, "STATUS-VERBOSE");
493 if (argc
> 0 && os_strcmp(argv
[0], "wps") == 0)
494 return wpa_ctrl_command(ctrl
, "STATUS-WPS");
495 return wpa_ctrl_command(ctrl
, "STATUS");
499 static int wpa_cli_cmd_ping(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
501 return wpa_ctrl_command(ctrl
, "PING");
505 static int wpa_cli_cmd_relog(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
507 return wpa_ctrl_command(ctrl
, "RELOG");
511 static int wpa_cli_cmd_note(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
513 return wpa_cli_cmd(ctrl
, "NOTE", 1, argc
, argv
);
517 static int wpa_cli_cmd_mib(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
519 return wpa_ctrl_command(ctrl
, "MIB");
523 static int wpa_cli_cmd_pmksa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
525 return wpa_ctrl_command(ctrl
, "PMKSA");
529 static int wpa_cli_cmd_help(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
531 print_help(argc
> 0 ? argv
[0] : NULL
);
536 static char ** wpa_cli_complete_help(const char *str
, int pos
)
538 int arg
= get_cmd_arg_num(str
, pos
);
543 res
= wpa_list_cmd_list();
551 static int wpa_cli_cmd_license(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
553 printf("%s\n\n%s\n", wpa_cli_version
, wpa_cli_full_license
);
558 static int wpa_cli_cmd_quit(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
567 static void wpa_cli_show_variables(void)
569 printf("set variables:\n"
570 " EAPOL::heldPeriod (EAPOL state machine held period, "
572 " EAPOL::authPeriod (EAPOL state machine authentication "
573 "period, in seconds)\n"
574 " EAPOL::startPeriod (EAPOL state machine start period, in "
576 " EAPOL::maxStart (EAPOL state machine maximum start "
578 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
580 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
581 " threshold\n\tpercentage)\n"
582 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
583 "security\n\tassociation in seconds)\n");
587 static int wpa_cli_cmd_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
593 wpa_cli_show_variables();
597 if (argc
!= 1 && argc
!= 2) {
598 printf("Invalid SET command: needs two arguments (variable "
599 "name and value)\n");
604 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s ", argv
[0]);
606 res
= os_snprintf(cmd
, sizeof(cmd
), "SET %s %s",
608 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
609 printf("Too long SET command.\n");
612 return wpa_ctrl_command(ctrl
, cmd
);
616 static int wpa_cli_cmd_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
618 return wpa_cli_cmd(ctrl
, "GET", 1, argc
, argv
);
622 static int wpa_cli_cmd_logoff(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
624 return wpa_ctrl_command(ctrl
, "LOGOFF");
628 static int wpa_cli_cmd_logon(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
630 return wpa_ctrl_command(ctrl
, "LOGON");
634 static int wpa_cli_cmd_reassociate(struct wpa_ctrl
*ctrl
, int argc
,
637 return wpa_ctrl_command(ctrl
, "REASSOCIATE");
641 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
644 return wpa_cli_cmd(ctrl
, "PREAUTH", 1, argc
, argv
);
648 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
650 return wpa_cli_cmd(ctrl
, "AP_SCAN", 1, argc
, argv
);
654 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl
*ctrl
, int argc
,
657 return wpa_cli_cmd(ctrl
, "SCAN_INTERVAL", 1, argc
, argv
);
661 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl
*ctrl
, int argc
,
664 return wpa_cli_cmd(ctrl
, "BSS_EXPIRE_AGE", 1, argc
, argv
);
668 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl
*ctrl
, int argc
,
671 return wpa_cli_cmd(ctrl
, "BSS_EXPIRE_COUNT", 1, argc
, argv
);
675 static int wpa_cli_cmd_bss_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
681 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS_FLUSH 0");
683 res
= os_snprintf(cmd
, sizeof(cmd
), "BSS_FLUSH %s", argv
[0]);
684 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
685 printf("Too long BSS_FLUSH command.\n");
688 return wpa_ctrl_command(ctrl
, cmd
);
692 static int wpa_cli_cmd_stkstart(struct wpa_ctrl
*ctrl
, int argc
,
695 return wpa_cli_cmd(ctrl
, "STKSTART", 1, argc
, argv
);
699 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
701 return wpa_cli_cmd(ctrl
, "FT_DS", 1, argc
, argv
);
705 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
707 return wpa_cli_cmd(ctrl
, "WPS_PBC", 0, argc
, argv
);
711 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
714 printf("Invalid WPS_PIN command: need one or two arguments:\n"
715 "- BSSID: use 'any' to select any\n"
716 "- PIN: optional, used only with devices that have no "
721 return wpa_cli_cmd(ctrl
, "WPS_PIN", 1, argc
, argv
);
725 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl
*ctrl
, int argc
,
728 return wpa_cli_cmd(ctrl
, "WPS_CHECK_PIN", 1, argc
, argv
);
732 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl
*ctrl
, int argc
,
735 return wpa_ctrl_command(ctrl
, "WPS_CANCEL");
739 #ifdef CONFIG_WPS_OOB
740 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
742 if (argc
!= 3 && argc
!= 4) {
743 printf("Invalid WPS_OOB command: need three or four "
745 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
746 "- PATH: path of OOB device like '/mnt'\n"
747 "- METHOD: OOB method 'pin-e' or 'pin-r', "
749 "- DEV_NAME: (only for NFC) device name like "
754 return wpa_cli_cmd(ctrl
, "WPS_OOB", 3, argc
, argv
);
756 #endif /* CONFIG_WPS_OOB */
759 #ifdef CONFIG_WPS_NFC
761 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
763 return wpa_cli_cmd(ctrl
, "WPS_NFC", 0, argc
, argv
);
767 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl
*ctrl
, int argc
,
770 return wpa_cli_cmd(ctrl
, "WPS_NFC_TOKEN", 1, argc
, argv
);
774 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl
*ctrl
, int argc
,
782 printf("Invalid 'wps_nfc_tag_read' command - one argument "
787 buflen
= 18 + os_strlen(argv
[0]);
788 buf
= os_malloc(buflen
);
791 os_snprintf(buf
, buflen
, "WPS_NFC_TAG_READ %s", argv
[0]);
793 ret
= wpa_ctrl_command(ctrl
, buf
);
800 static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl
*ctrl
, int argc
,
803 return wpa_cli_cmd(ctrl
, "NFC_GET_HANDOVER_REQ", 2, argc
, argv
);
807 static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl
*ctrl
, int argc
,
810 return wpa_cli_cmd(ctrl
, "NFC_GET_HANDOVER_SEL", 2, argc
, argv
);
814 static int wpa_cli_cmd_nfc_rx_handover_req(struct wpa_ctrl
*ctrl
, int argc
,
822 printf("Invalid 'nfc_rx_handover_req' command - one argument "
827 buflen
= 21 + os_strlen(argv
[0]);
828 buf
= os_malloc(buflen
);
831 os_snprintf(buf
, buflen
, "NFC_RX_HANDOVER_REQ %s", argv
[0]);
833 ret
= wpa_ctrl_command(ctrl
, buf
);
840 static int wpa_cli_cmd_nfc_rx_handover_sel(struct wpa_ctrl
*ctrl
, int argc
,
848 printf("Invalid 'nfc_rx_handover_sel' command - one argument "
853 buflen
= 21 + os_strlen(argv
[0]);
854 buf
= os_malloc(buflen
);
857 os_snprintf(buf
, buflen
, "NFC_RX_HANDOVER_SEL %s", argv
[0]);
859 ret
= wpa_ctrl_command(ctrl
, buf
);
865 #endif /* CONFIG_WPS_NFC */
868 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
874 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
876 else if (argc
== 5 || argc
== 6) {
877 char ssid_hex
[2 * 32 + 1];
878 char key_hex
[2 * 64 + 1];
882 for (i
= 0; i
< 32; i
++) {
883 if (argv
[2][i
] == '\0')
885 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
890 for (i
= 0; i
< 64; i
++) {
891 if (argv
[5][i
] == '\0')
893 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
898 res
= os_snprintf(cmd
, sizeof(cmd
),
899 "WPS_REG %s %s %s %s %s %s",
900 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
903 printf("Invalid WPS_REG command: need two arguments:\n"
904 "- BSSID of the target AP\n"
906 printf("Alternatively, six arguments can be used to "
907 "reconfigure the AP:\n"
908 "- BSSID of the target AP\n"
911 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
912 "- new encr (NONE, WEP, TKIP, CCMP)\n"
917 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
918 printf("Too long WPS_REG command.\n");
921 return wpa_ctrl_command(ctrl
, cmd
);
925 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl
*ctrl
, int argc
,
928 return wpa_cli_cmd(ctrl
, "WPS_AP_PIN", 1, argc
, argv
);
932 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
935 return wpa_cli_cmd(ctrl
, "WPS_ER_START", 0, argc
, argv
);
939 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
942 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
947 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
951 printf("Invalid WPS_ER_PIN command: need at least two "
953 "- UUID: use 'any' to select any\n"
954 "- PIN: Enrollee PIN\n"
955 "optional: - Enrollee MAC address\n");
959 return wpa_cli_cmd(ctrl
, "WPS_ER_PIN", 2, argc
, argv
);
963 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
966 return wpa_cli_cmd(ctrl
, "WPS_ER_PBC", 1, argc
, argv
);
970 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
974 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
975 "- UUID: specify which AP to use\n"
980 return wpa_cli_cmd(ctrl
, "WPS_ER_LEARN", 2, argc
, argv
);
984 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl
*ctrl
, int argc
,
988 printf("Invalid WPS_ER_SET_CONFIG command: need two "
990 "- UUID: specify which AP to use\n"
991 "- Network configuration id\n");
995 return wpa_cli_cmd(ctrl
, "WPS_ER_SET_CONFIG", 2, argc
, argv
);
999 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl
*ctrl
, int argc
,
1005 if (argc
== 5 || argc
== 6) {
1006 char ssid_hex
[2 * 32 + 1];
1007 char key_hex
[2 * 64 + 1];
1011 for (i
= 0; i
< 32; i
++) {
1012 if (argv
[2][i
] == '\0')
1014 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
1019 for (i
= 0; i
< 64; i
++) {
1020 if (argv
[5][i
] == '\0')
1022 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
1027 res
= os_snprintf(cmd
, sizeof(cmd
),
1028 "WPS_ER_CONFIG %s %s %s %s %s %s",
1029 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
1032 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1036 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1037 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1042 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
1043 printf("Too long WPS_ER_CONFIG command.\n");
1046 return wpa_ctrl_command(ctrl
, cmd
);
1050 #ifdef CONFIG_WPS_NFC
1051 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl
*ctrl
, int argc
,
1055 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
1057 "- WPS/NDEF: token format\n"
1058 "- UUID: specify which AP to use\n");
1062 return wpa_cli_cmd(ctrl
, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc
, argv
);
1064 #endif /* CONFIG_WPS_NFC */
1067 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1069 return wpa_cli_cmd(ctrl
, "IBSS_RSN", 1, argc
, argv
);
1073 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1075 return wpa_cli_cmd(ctrl
, "LEVEL", 1, argc
, argv
);
1079 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1081 char cmd
[256], *pos
, *end
;
1085 printf("Invalid IDENTITY command: needs two arguments "
1086 "(network id and identity)\n");
1090 end
= cmd
+ sizeof(cmd
);
1092 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
1094 if (ret
< 0 || ret
>= end
- pos
) {
1095 printf("Too long IDENTITY command.\n");
1099 for (i
= 2; i
< argc
; i
++) {
1100 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1101 if (ret
< 0 || ret
>= end
- pos
) {
1102 printf("Too long IDENTITY command.\n");
1108 return wpa_ctrl_command(ctrl
, cmd
);
1112 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1114 char cmd
[256], *pos
, *end
;
1118 printf("Invalid PASSWORD command: needs two arguments "
1119 "(network id and password)\n");
1123 end
= cmd
+ sizeof(cmd
);
1125 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
1127 if (ret
< 0 || ret
>= end
- pos
) {
1128 printf("Too long PASSWORD 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 PASSWORD command.\n");
1141 return wpa_ctrl_command(ctrl
, cmd
);
1145 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
1148 char cmd
[256], *pos
, *end
;
1152 printf("Invalid NEW_PASSWORD command: needs two arguments "
1153 "(network id and password)\n");
1157 end
= cmd
+ sizeof(cmd
);
1159 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
1161 if (ret
< 0 || ret
>= end
- pos
) {
1162 printf("Too long NEW_PASSWORD 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 NEW_PASSWORD command.\n");
1175 return wpa_ctrl_command(ctrl
, cmd
);
1179 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1181 char cmd
[256], *pos
, *end
;
1185 printf("Invalid PIN command: needs two arguments "
1186 "(network id and pin)\n");
1190 end
= cmd
+ sizeof(cmd
);
1192 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
1194 if (ret
< 0 || ret
>= end
- pos
) {
1195 printf("Too long PIN command.\n");
1199 for (i
= 2; i
< argc
; i
++) {
1200 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1201 if (ret
< 0 || ret
>= end
- pos
) {
1202 printf("Too long PIN command.\n");
1207 return wpa_ctrl_command(ctrl
, cmd
);
1211 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1213 char cmd
[256], *pos
, *end
;
1217 printf("Invalid OTP command: needs two arguments (network "
1218 "id and password)\n");
1222 end
= cmd
+ sizeof(cmd
);
1224 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
1226 if (ret
< 0 || ret
>= end
- pos
) {
1227 printf("Too long OTP command.\n");
1231 for (i
= 2; i
< argc
; i
++) {
1232 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1233 if (ret
< 0 || ret
>= end
- pos
) {
1234 printf("Too long OTP command.\n");
1240 return wpa_ctrl_command(ctrl
, cmd
);
1244 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1247 char cmd
[256], *pos
, *end
;
1251 printf("Invalid PASSPHRASE command: needs two arguments "
1252 "(network id and passphrase)\n");
1256 end
= cmd
+ sizeof(cmd
);
1258 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
1260 if (ret
< 0 || ret
>= end
- pos
) {
1261 printf("Too long PASSPHRASE command.\n");
1265 for (i
= 2; i
< argc
; i
++) {
1266 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1267 if (ret
< 0 || ret
>= end
- pos
) {
1268 printf("Too long PASSPHRASE command.\n");
1274 return wpa_ctrl_command(ctrl
, cmd
);
1278 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1281 printf("Invalid BSSID command: needs two arguments (network "
1286 return wpa_cli_cmd(ctrl
, "BSSID", 2, argc
, argv
);
1290 static int wpa_cli_cmd_blacklist(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1292 return wpa_cli_cmd(ctrl
, "BLACKLIST", 0, argc
, argv
);
1296 static int wpa_cli_cmd_log_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1298 return wpa_cli_cmd(ctrl
, "LOG_LEVEL", 0, argc
, argv
);
1302 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
1305 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
1309 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
1312 return wpa_cli_cmd(ctrl
, "SELECT_NETWORK", 1, argc
, argv
);
1316 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
1319 return wpa_cli_cmd(ctrl
, "ENABLE_NETWORK", 1, argc
, argv
);
1323 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
1326 return wpa_cli_cmd(ctrl
, "DISABLE_NETWORK", 1, argc
, argv
);
1330 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
1333 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
1337 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
1340 return wpa_cli_cmd(ctrl
, "REMOVE_NETWORK", 1, argc
, argv
);
1344 static void wpa_cli_show_network_variables(void)
1346 printf("set_network variables:\n"
1347 " ssid (network name, SSID)\n"
1348 " psk (WPA passphrase or pre-shared key)\n"
1349 " key_mgmt (key management protocol)\n"
1350 " identity (EAP identity)\n"
1351 " password (EAP password)\n"
1354 "Note: Values are entered in the same format as the "
1355 "configuration file is using,\n"
1356 "i.e., strings values need to be inside double quotation "
1358 "For example: set_network 1 ssid \"network name\"\n"
1360 "Please see wpa_supplicant.conf documentation for full list "
1361 "of\navailable variables.\n");
1365 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
1369 wpa_cli_show_network_variables();
1374 printf("Invalid SET_NETWORK command: needs three arguments\n"
1375 "(network id, variable name, and value)\n");
1379 return wpa_cli_cmd(ctrl
, "SET_NETWORK", 3, argc
, argv
);
1383 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1387 wpa_cli_show_network_variables();
1392 printf("Invalid GET_NETWORK command: needs two arguments\n"
1393 "(network id and variable name)\n");
1397 return wpa_cli_cmd(ctrl
, "GET_NETWORK", 2, argc
, argv
);
1401 static int wpa_cli_cmd_list_creds(struct wpa_ctrl
*ctrl
, int argc
,
1404 return wpa_ctrl_command(ctrl
, "LIST_CREDS");
1408 static int wpa_cli_cmd_add_cred(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1410 return wpa_ctrl_command(ctrl
, "ADD_CRED");
1414 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl
*ctrl
, int argc
,
1417 return wpa_cli_cmd(ctrl
, "REMOVE_CRED", 1, argc
, argv
);
1421 static int wpa_cli_cmd_set_cred(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1424 printf("Invalid SET_CRED command: needs three arguments\n"
1425 "(cred id, variable name, and value)\n");
1429 return wpa_cli_cmd(ctrl
, "SET_CRED", 3, argc
, argv
);
1433 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1436 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1440 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1443 return wpa_ctrl_command(ctrl
, "RECONNECT");
1447 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
1450 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
1454 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1456 return wpa_ctrl_command(ctrl
, "SCAN");
1460 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
1463 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1467 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1469 return wpa_cli_cmd(ctrl
, "BSS", 1, argc
, argv
);
1473 static char ** wpa_cli_complete_bss(const char *str
, int pos
)
1475 int arg
= get_cmd_arg_num(str
, pos
);
1480 res
= cli_txt_list_array(&bsses
);
1488 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1491 if (argc
< 1 || argc
> 2) {
1492 printf("Invalid GET_CAPABILITY command: need either one or "
1497 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
1498 printf("Invalid GET_CAPABILITY command: second argument, "
1499 "if any, must be 'strict'\n");
1503 return wpa_cli_cmd(ctrl
, "GET_CAPABILITY", 1, argc
, argv
);
1507 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
1509 printf("Available interfaces:\n");
1510 return wpa_ctrl_command(ctrl
, "INTERFACES");
1514 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1517 wpa_cli_list_interfaces(ctrl
);
1521 wpa_cli_close_connection();
1522 os_free(ctrl_ifname
);
1523 ctrl_ifname
= os_strdup(argv
[0]);
1525 if (wpa_cli_open_connection(ctrl_ifname
, 1)) {
1526 printf("Connected to interface '%s.\n", ctrl_ifname
);
1528 printf("Could not connect to interface '%s' - re-trying\n",
1535 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1538 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1542 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1545 return wpa_ctrl_command(ctrl
, "TERMINATE");
1549 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1556 printf("Invalid INTERFACE_ADD command: needs at least one "
1557 "argument (interface name)\n"
1558 "All arguments: ifname confname driver ctrl_interface "
1559 "driver_param bridge_name\n");
1564 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1565 * <driver_param>TAB<bridge_name>
1567 res
= os_snprintf(cmd
, sizeof(cmd
),
1568 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1570 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1571 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1572 argc
> 5 ? argv
[5] : "");
1573 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1575 cmd
[sizeof(cmd
) - 1] = '\0';
1576 return wpa_ctrl_command(ctrl
, cmd
);
1580 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1583 return wpa_cli_cmd(ctrl
, "INTERFACE_REMOVE", 1, argc
, argv
);
1587 static int wpa_cli_cmd_interface_list(struct wpa_ctrl
*ctrl
, int argc
,
1590 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1595 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1597 return wpa_cli_cmd(ctrl
, "STA", 1, argc
, argv
);
1601 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
1602 char *addr
, size_t addr_len
)
1604 char buf
[4096], *pos
;
1608 if (ctrl_conn
== NULL
) {
1609 printf("Not connected to hostapd - command dropped.\n");
1612 len
= sizeof(buf
) - 1;
1613 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
1616 printf("'%s' command timed out.\n", cmd
);
1618 } else if (ret
< 0) {
1619 printf("'%s' command failed.\n", cmd
);
1624 if (os_memcmp(buf
, "FAIL", 4) == 0)
1629 while (*pos
!= '\0' && *pos
!= '\n')
1632 os_strlcpy(addr
, buf
, addr_len
);
1637 static int wpa_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1639 char addr
[32], cmd
[64];
1641 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
1644 os_snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1645 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
1651 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
1654 return wpa_cli_cmd(ctrl
, "DEAUTHENTICATE", 1, argc
, argv
);
1658 static int wpa_cli_cmd_disassociate(struct wpa_ctrl
*ctrl
, int argc
,
1661 return wpa_cli_cmd(ctrl
, "DISASSOCIATE", 1, argc
, argv
);
1663 #endif /* CONFIG_AP */
1666 static int wpa_cli_cmd_suspend(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1668 return wpa_ctrl_command(ctrl
, "SUSPEND");
1672 static int wpa_cli_cmd_resume(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1674 return wpa_ctrl_command(ctrl
, "RESUME");
1678 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1680 return wpa_ctrl_command(ctrl
, "DROP_SA");
1684 static int wpa_cli_cmd_roam(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1686 return wpa_cli_cmd(ctrl
, "ROAM", 1, argc
, argv
);
1692 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1694 return wpa_cli_cmd(ctrl
, "P2P_FIND", 0, argc
, argv
);
1698 static char ** wpa_cli_complete_p2p_find(const char *str
, int pos
)
1701 int arg
= get_cmd_arg_num(str
, pos
);
1703 res
= os_calloc(6, sizeof(char *));
1706 res
[0] = os_strdup("type=social");
1707 if (res
[0] == NULL
) {
1711 res
[1] = os_strdup("type=progressive");
1714 res
[2] = os_strdup("delay=");
1717 res
[3] = os_strdup("dev_id=");
1721 res
[4] = os_strdup("[timeout]");
1727 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl
*ctrl
, int argc
,
1730 return wpa_ctrl_command(ctrl
, "P2P_STOP_FIND");
1734 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl
*ctrl
, int argc
,
1737 return wpa_cli_cmd(ctrl
, "P2P_CONNECT", 2, argc
, argv
);
1741 static char ** wpa_cli_complete_p2p_connect(const char *str
, int pos
)
1743 int arg
= get_cmd_arg_num(str
, pos
);
1748 res
= cli_txt_list_array(&p2p_peers
);
1756 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl
*ctrl
, int argc
,
1759 return wpa_cli_cmd(ctrl
, "P2P_LISTEN", 0, argc
, argv
);
1763 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl
*ctrl
, int argc
,
1766 return wpa_cli_cmd(ctrl
, "P2P_GROUP_REMOVE", 1, argc
, argv
);
1770 static char ** wpa_cli_complete_p2p_group_remove(const char *str
, int pos
)
1772 int arg
= get_cmd_arg_num(str
, pos
);
1777 res
= cli_txt_list_array(&p2p_groups
);
1785 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl
*ctrl
, int argc
,
1788 return wpa_cli_cmd(ctrl
, "P2P_GROUP_ADD", 0, argc
, argv
);
1792 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl
*ctrl
, int argc
,
1795 if (argc
!= 2 && argc
!= 3) {
1796 printf("Invalid P2P_PROV_DISC command: needs at least "
1797 "two arguments, address and config method\n"
1798 "(display, keypad, or pbc) and an optional join\n");
1802 return wpa_cli_cmd(ctrl
, "P2P_PROV_DISC", 2, argc
, argv
);
1806 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1809 return wpa_ctrl_command(ctrl
, "P2P_GET_PASSPHRASE");
1813 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl
*ctrl
, int argc
,
1818 if (argc
!= 2 && argc
!= 4) {
1819 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1820 "arguments (address and TLVs) or four arguments "
1821 "(address, \"upnp\", version, search target "
1826 if (write_cmd(cmd
, sizeof(cmd
), "P2P_SERV_DISC_REQ", argc
, argv
) < 0)
1828 return wpa_ctrl_command(ctrl
, cmd
);
1832 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl
*ctrl
,
1833 int argc
, char *argv
[])
1835 return wpa_cli_cmd(ctrl
, "P2P_SERV_DISC_CANCEL_REQ", 1, argc
, argv
);
1839 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl
*ctrl
, int argc
,
1846 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1847 "arguments (freq, address, dialog token, and TLVs)\n");
1851 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_RESP %s %s %s %s",
1852 argv
[0], argv
[1], argv
[2], argv
[3]);
1853 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1855 cmd
[sizeof(cmd
) - 1] = '\0';
1856 return wpa_ctrl_command(ctrl
, cmd
);
1860 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl
*ctrl
, int argc
,
1863 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_UPDATE");
1867 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl
*ctrl
,
1868 int argc
, char *argv
[])
1870 return wpa_cli_cmd(ctrl
, "P2P_SERV_DISC_EXTERNAL", 1, argc
, argv
);
1874 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl
*ctrl
, int argc
,
1877 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_FLUSH");
1881 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl
*ctrl
, int argc
,
1887 if (argc
!= 3 && argc
!= 4) {
1888 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1894 res
= os_snprintf(cmd
, sizeof(cmd
),
1895 "P2P_SERVICE_ADD %s %s %s %s",
1896 argv
[0], argv
[1], argv
[2], argv
[3]);
1898 res
= os_snprintf(cmd
, sizeof(cmd
),
1899 "P2P_SERVICE_ADD %s %s %s",
1900 argv
[0], argv
[1], argv
[2]);
1901 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1903 cmd
[sizeof(cmd
) - 1] = '\0';
1904 return wpa_ctrl_command(ctrl
, cmd
);
1908 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl
*ctrl
, int argc
,
1914 if (argc
!= 2 && argc
!= 3) {
1915 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1921 res
= os_snprintf(cmd
, sizeof(cmd
),
1922 "P2P_SERVICE_DEL %s %s %s",
1923 argv
[0], argv
[1], argv
[2]);
1925 res
= os_snprintf(cmd
, sizeof(cmd
),
1926 "P2P_SERVICE_DEL %s %s",
1928 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1930 cmd
[sizeof(cmd
) - 1] = '\0';
1931 return wpa_ctrl_command(ctrl
, cmd
);
1935 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl
*ctrl
,
1936 int argc
, char *argv
[])
1938 return wpa_cli_cmd(ctrl
, "P2P_REJECT", 1, argc
, argv
);
1942 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl
*ctrl
,
1943 int argc
, char *argv
[])
1945 return wpa_cli_cmd(ctrl
, "P2P_INVITE", 1, argc
, argv
);
1949 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1951 return wpa_cli_cmd(ctrl
, "P2P_PEER", 1, argc
, argv
);
1955 static char ** wpa_cli_complete_p2p_peer(const char *str
, int pos
)
1957 int arg
= get_cmd_arg_num(str
, pos
);
1962 res
= cli_txt_list_array(&p2p_peers
);
1970 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl
*ctrl
, char *cmd
,
1971 char *addr
, size_t addr_len
,
1974 char buf
[4096], *pos
;
1978 if (ctrl_conn
== NULL
)
1980 len
= sizeof(buf
) - 1;
1981 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
1984 printf("'%s' command timed out.\n", cmd
);
1986 } else if (ret
< 0) {
1987 printf("'%s' command failed.\n", cmd
);
1992 if (os_memcmp(buf
, "FAIL", 4) == 0)
1996 while (*pos
!= '\0' && *pos
!= '\n')
1999 os_strlcpy(addr
, buf
, addr_len
);
2000 if (!discovered
|| os_strstr(pos
, "[PROBE_REQ_ONLY]") == NULL
)
2001 printf("%s\n", addr
);
2006 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2008 char addr
[32], cmd
[64];
2011 discovered
= argc
> 0 && os_strcmp(argv
[0], "discovered") == 0;
2013 if (wpa_ctrl_command_p2p_peer(ctrl
, "P2P_PEER FIRST",
2014 addr
, sizeof(addr
), discovered
))
2017 os_snprintf(cmd
, sizeof(cmd
), "P2P_PEER NEXT-%s", addr
);
2018 } while (wpa_ctrl_command_p2p_peer(ctrl
, cmd
, addr
, sizeof(addr
),
2025 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2027 return wpa_cli_cmd(ctrl
, "P2P_SET", 2, argc
, argv
);
2031 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2033 return wpa_ctrl_command(ctrl
, "P2P_FLUSH");
2037 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl
*ctrl
, int argc
,
2040 return wpa_ctrl_command(ctrl
, "P2P_CANCEL");
2044 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl
*ctrl
, int argc
,
2047 return wpa_cli_cmd(ctrl
, "P2P_UNAUTHORIZE", 1, argc
, argv
);
2051 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl
*ctrl
, int argc
,
2054 if (argc
!= 0 && argc
!= 2 && argc
!= 4) {
2055 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2056 "(preferred duration, interval; in microsecods).\n"
2057 "Optional second pair can be used to provide "
2058 "acceptable values.\n");
2062 return wpa_cli_cmd(ctrl
, "P2P_PRESENCE_REQ", 0, argc
, argv
);
2066 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl
*ctrl
, int argc
,
2069 if (argc
!= 0 && argc
!= 2) {
2070 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2071 "(availability period, availability interval; in "
2073 "Extended Listen Timing can be cancelled with this "
2074 "command when used without parameters.\n");
2078 return wpa_cli_cmd(ctrl
, "P2P_EXT_LISTEN", 0, argc
, argv
);
2081 #endif /* CONFIG_P2P */
2083 #ifdef CONFIG_WIFI_DISPLAY
2085 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl
*ctrl
, int argc
,
2091 if (argc
!= 1 && argc
!= 2) {
2092 printf("Invalid WFD_SUBELEM_SET command: needs one or two "
2093 "arguments (subelem, hexdump)\n");
2097 res
= os_snprintf(cmd
, sizeof(cmd
), "WFD_SUBELEM_SET %s %s",
2098 argv
[0], argc
> 1 ? argv
[1] : "");
2099 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2101 cmd
[sizeof(cmd
) - 1] = '\0';
2102 return wpa_ctrl_command(ctrl
, cmd
);
2106 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl
*ctrl
, int argc
,
2113 printf("Invalid WFD_SUBELEM_GET command: needs one "
2114 "argument (subelem)\n");
2118 res
= os_snprintf(cmd
, sizeof(cmd
), "WFD_SUBELEM_GET %s",
2120 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
2122 cmd
[sizeof(cmd
) - 1] = '\0';
2123 return wpa_ctrl_command(ctrl
, cmd
);
2125 #endif /* CONFIG_WIFI_DISPLAY */
2128 #ifdef CONFIG_INTERWORKING
2129 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2132 return wpa_ctrl_command(ctrl
, "FETCH_ANQP");
2136 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2139 return wpa_ctrl_command(ctrl
, "STOP_FETCH_ANQP");
2143 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl
*ctrl
, int argc
,
2146 return wpa_cli_cmd(ctrl
, "INTERWORKING_SELECT", 0, argc
, argv
);
2150 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl
*ctrl
, int argc
,
2153 return wpa_cli_cmd(ctrl
, "INTERWORKING_CONNECT", 1, argc
, argv
);
2157 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2159 return wpa_cli_cmd(ctrl
, "ANQP_GET", 2, argc
, argv
);
2163 static int wpa_cli_cmd_gas_request(struct wpa_ctrl
*ctrl
, int argc
,
2166 return wpa_cli_cmd(ctrl
, "GAS_REQUEST", 2, argc
, argv
);
2170 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl
*ctrl
, int argc
,
2173 return wpa_cli_cmd(ctrl
, "GAS_RESPONSE_GET", 2, argc
, argv
);
2175 #endif /* CONFIG_INTERWORKING */
2180 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl
*ctrl
, int argc
,
2183 return wpa_cli_cmd(ctrl
, "HS20_ANQP_GET", 2, argc
, argv
);
2187 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl
*ctrl
, int argc
,
2193 printf("Command needs one or two arguments (dst mac addr and "
2194 "optional home realm)\n");
2198 if (write_cmd(cmd
, sizeof(cmd
), "HS20_GET_NAI_HOME_REALM_LIST",
2202 return wpa_ctrl_command(ctrl
, cmd
);
2205 #endif /* CONFIG_HS20 */
2208 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl
*ctrl
, int argc
,
2211 return wpa_cli_cmd(ctrl
, "STA_AUTOCONNECT", 1, argc
, argv
);
2215 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl
*ctrl
, int argc
,
2218 return wpa_cli_cmd(ctrl
, "TDLS_DISCOVER", 1, argc
, argv
);
2222 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl
*ctrl
, int argc
,
2225 return wpa_cli_cmd(ctrl
, "TDLS_SETUP", 1, argc
, argv
);
2229 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl
*ctrl
, int argc
,
2232 return wpa_cli_cmd(ctrl
, "TDLS_TEARDOWN", 1, argc
, argv
);
2236 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl
*ctrl
, int argc
,
2239 return wpa_ctrl_command(ctrl
, "SIGNAL_POLL");
2243 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl
*ctrl
, int argc
,
2246 return wpa_ctrl_command(ctrl
, "PKTCNT_POLL");
2250 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
2253 return wpa_ctrl_command(ctrl
, "REAUTHENTICATE");
2257 #ifdef CONFIG_AUTOSCAN
2259 static int wpa_cli_cmd_autoscan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2262 return wpa_ctrl_command(ctrl
, "AUTOSCAN ");
2264 return wpa_cli_cmd(ctrl
, "AUTOSCAN", 0, argc
, argv
);
2267 #endif /* CONFIG_AUTOSCAN */
2270 static int wpa_cli_cmd_raw(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2274 return wpa_cli_cmd(ctrl
, argv
[0], 0, argc
- 1, &argv
[1]);
2278 enum wpa_cli_cmd_flags
{
2279 cli_cmd_flag_none
= 0x00,
2280 cli_cmd_flag_sensitive
= 0x01
2283 struct wpa_cli_cmd
{
2285 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
2286 char ** (*completion
)(const char *str
, int pos
);
2287 enum wpa_cli_cmd_flags flags
;
2291 static struct wpa_cli_cmd wpa_cli_commands
[] = {
2292 { "status", wpa_cli_cmd_status
, NULL
,
2294 "[verbose] = get current WPA/EAPOL/EAP status" },
2295 { "ifname", wpa_cli_cmd_ifname
, NULL
,
2297 "= get current interface name" },
2298 { "ping", wpa_cli_cmd_ping
, NULL
,
2300 "= pings wpa_supplicant" },
2301 { "relog", wpa_cli_cmd_relog
, NULL
,
2303 "= re-open log-file (allow rolling logs)" },
2304 { "note", wpa_cli_cmd_note
, NULL
,
2306 "<text> = add a note to wpa_supplicant debug log" },
2307 { "mib", wpa_cli_cmd_mib
, NULL
,
2309 "= get MIB variables (dot1x, dot11)" },
2310 { "help", wpa_cli_cmd_help
, wpa_cli_complete_help
,
2312 "[command] = show usage help" },
2313 { "interface", wpa_cli_cmd_interface
, NULL
,
2315 "[ifname] = show interfaces/select interface" },
2316 { "level", wpa_cli_cmd_level
, NULL
,
2318 "<debug level> = change debug level" },
2319 { "license", wpa_cli_cmd_license
, NULL
,
2321 "= show full wpa_cli license" },
2322 { "quit", wpa_cli_cmd_quit
, NULL
,
2325 { "set", wpa_cli_cmd_set
, NULL
,
2327 "= set variables (shows list of variables when run without "
2329 { "get", wpa_cli_cmd_get
, NULL
,
2331 "<name> = get information" },
2332 { "logon", wpa_cli_cmd_logon
, NULL
,
2334 "= IEEE 802.1X EAPOL state machine logon" },
2335 { "logoff", wpa_cli_cmd_logoff
, NULL
,
2337 "= IEEE 802.1X EAPOL state machine logoff" },
2338 { "pmksa", wpa_cli_cmd_pmksa
, NULL
,
2340 "= show PMKSA cache" },
2341 { "reassociate", wpa_cli_cmd_reassociate
, NULL
,
2343 "= force reassociation" },
2344 { "preauthenticate", wpa_cli_cmd_preauthenticate
, wpa_cli_complete_bss
,
2346 "<BSSID> = force preauthentication" },
2347 { "identity", wpa_cli_cmd_identity
, NULL
,
2349 "<network id> <identity> = configure identity for an SSID" },
2350 { "password", wpa_cli_cmd_password
, NULL
,
2351 cli_cmd_flag_sensitive
,
2352 "<network id> <password> = configure password for an SSID" },
2353 { "new_password", wpa_cli_cmd_new_password
, NULL
,
2354 cli_cmd_flag_sensitive
,
2355 "<network id> <password> = change password for an SSID" },
2356 { "pin", wpa_cli_cmd_pin
, NULL
,
2357 cli_cmd_flag_sensitive
,
2358 "<network id> <pin> = configure pin for an SSID" },
2359 { "otp", wpa_cli_cmd_otp
, NULL
,
2360 cli_cmd_flag_sensitive
,
2361 "<network id> <password> = configure one-time-password for an SSID"
2363 { "passphrase", wpa_cli_cmd_passphrase
, NULL
,
2364 cli_cmd_flag_sensitive
,
2365 "<network id> <passphrase> = configure private key passphrase\n"
2367 { "bssid", wpa_cli_cmd_bssid
, NULL
,
2369 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2370 { "blacklist", wpa_cli_cmd_blacklist
, wpa_cli_complete_bss
,
2372 "<BSSID> = add a BSSID to the blacklist\n"
2373 "blacklist clear = clear the blacklist\n"
2374 "blacklist = display the blacklist" },
2375 { "log_level", wpa_cli_cmd_log_level
, NULL
,
2377 "<level> [<timestamp>] = update the log level/timestamp\n"
2378 "log_level = display the current log level and log options" },
2379 { "list_networks", wpa_cli_cmd_list_networks
, NULL
,
2381 "= list configured networks" },
2382 { "select_network", wpa_cli_cmd_select_network
, NULL
,
2384 "<network id> = select a network (disable others)" },
2385 { "enable_network", wpa_cli_cmd_enable_network
, NULL
,
2387 "<network id> = enable a network" },
2388 { "disable_network", wpa_cli_cmd_disable_network
, NULL
,
2390 "<network id> = disable a network" },
2391 { "add_network", wpa_cli_cmd_add_network
, NULL
,
2393 "= add a network" },
2394 { "remove_network", wpa_cli_cmd_remove_network
, NULL
,
2396 "<network id> = remove a network" },
2397 { "set_network", wpa_cli_cmd_set_network
, NULL
,
2398 cli_cmd_flag_sensitive
,
2399 "<network id> <variable> <value> = set network variables (shows\n"
2400 " list of variables when run without arguments)" },
2401 { "get_network", wpa_cli_cmd_get_network
, NULL
,
2403 "<network id> <variable> = get network variables" },
2404 { "list_creds", wpa_cli_cmd_list_creds
, NULL
,
2406 "= list configured credentials" },
2407 { "add_cred", wpa_cli_cmd_add_cred
, NULL
,
2409 "= add a credential" },
2410 { "remove_cred", wpa_cli_cmd_remove_cred
, NULL
,
2412 "<cred id> = remove a credential" },
2413 { "set_cred", wpa_cli_cmd_set_cred
, NULL
,
2414 cli_cmd_flag_sensitive
,
2415 "<cred id> <variable> <value> = set credential variables" },
2416 { "save_config", wpa_cli_cmd_save_config
, NULL
,
2418 "= save the current configuration" },
2419 { "disconnect", wpa_cli_cmd_disconnect
, NULL
,
2421 "= disconnect and wait for reassociate/reconnect command before\n"
2423 { "reconnect", wpa_cli_cmd_reconnect
, NULL
,
2425 "= like reassociate, but only takes effect if already disconnected"
2427 { "scan", wpa_cli_cmd_scan
, NULL
,
2429 "= request new BSS scan" },
2430 { "scan_results", wpa_cli_cmd_scan_results
, NULL
,
2432 "= get latest scan results" },
2433 { "bss", wpa_cli_cmd_bss
, wpa_cli_complete_bss
,
2435 "<<idx> | <bssid>> = get detailed scan result info" },
2436 { "get_capability", wpa_cli_cmd_get_capability
, NULL
,
2438 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels> "
2439 "= get capabilies" },
2440 { "reconfigure", wpa_cli_cmd_reconfigure
, NULL
,
2442 "= force wpa_supplicant to re-read its configuration file" },
2443 { "terminate", wpa_cli_cmd_terminate
, NULL
,
2445 "= terminate wpa_supplicant" },
2446 { "interface_add", wpa_cli_cmd_interface_add
, NULL
,
2448 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2449 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2451 { "interface_remove", wpa_cli_cmd_interface_remove
, NULL
,
2453 "<ifname> = removes the interface" },
2454 { "interface_list", wpa_cli_cmd_interface_list
, NULL
,
2456 "= list available interfaces" },
2457 { "ap_scan", wpa_cli_cmd_ap_scan
, NULL
,
2459 "<value> = set ap_scan parameter" },
2460 { "scan_interval", wpa_cli_cmd_scan_interval
, NULL
,
2462 "<value> = set scan_interval parameter (in seconds)" },
2463 { "bss_expire_age", wpa_cli_cmd_bss_expire_age
, NULL
,
2465 "<value> = set BSS expiration age parameter" },
2466 { "bss_expire_count", wpa_cli_cmd_bss_expire_count
, NULL
,
2468 "<value> = set BSS expiration scan count parameter" },
2469 { "bss_flush", wpa_cli_cmd_bss_flush
, NULL
,
2471 "<value> = set BSS flush age (0 by default)" },
2472 { "stkstart", wpa_cli_cmd_stkstart
, NULL
,
2474 "<addr> = request STK negotiation with <addr>" },
2475 { "ft_ds", wpa_cli_cmd_ft_ds
, wpa_cli_complete_bss
,
2477 "<addr> = request over-the-DS FT with <addr>" },
2478 { "wps_pbc", wpa_cli_cmd_wps_pbc
, wpa_cli_complete_bss
,
2480 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2481 { "wps_pin", wpa_cli_cmd_wps_pin
, wpa_cli_complete_bss
,
2482 cli_cmd_flag_sensitive
,
2483 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2485 { "wps_check_pin", wpa_cli_cmd_wps_check_pin
, NULL
,
2486 cli_cmd_flag_sensitive
,
2487 "<PIN> = verify PIN checksum" },
2488 { "wps_cancel", wpa_cli_cmd_wps_cancel
, NULL
, cli_cmd_flag_none
,
2489 "Cancels the pending WPS operation" },
2490 #ifdef CONFIG_WPS_OOB
2491 { "wps_oob", wpa_cli_cmd_wps_oob
, NULL
,
2492 cli_cmd_flag_sensitive
,
2493 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2494 #endif /* CONFIG_WPS_OOB */
2495 #ifdef CONFIG_WPS_NFC
2496 { "wps_nfc", wpa_cli_cmd_wps_nfc
, wpa_cli_complete_bss
,
2498 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
2499 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token
, NULL
,
2501 "<WPS|NDEF> = create password token" },
2502 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read
, NULL
,
2503 cli_cmd_flag_sensitive
,
2504 "<hexdump of payload> = report read NFC tag with WPS data" },
2505 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req
, NULL
,
2507 "<NDEF> <WPS> = create NFC handover request" },
2508 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel
, NULL
,
2510 "<NDEF> <WPS> = create NFC handover select" },
2511 { "nfc_rx_handover_req", wpa_cli_cmd_nfc_rx_handover_req
, NULL
,
2513 "<hexdump of payload> = report received NFC handover request" },
2514 { "nfc_rx_handover_sel", wpa_cli_cmd_nfc_rx_handover_sel
, NULL
,
2516 "<hexdump of payload> = report received NFC handover select" },
2517 #endif /* CONFIG_WPS_NFC */
2518 { "wps_reg", wpa_cli_cmd_wps_reg
, wpa_cli_complete_bss
,
2519 cli_cmd_flag_sensitive
,
2520 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2521 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin
, NULL
,
2522 cli_cmd_flag_sensitive
,
2523 "[params..] = enable/disable AP PIN" },
2524 { "wps_er_start", wpa_cli_cmd_wps_er_start
, NULL
,
2526 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2527 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
, NULL
,
2529 "= stop Wi-Fi Protected Setup External Registrar" },
2530 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
, NULL
,
2531 cli_cmd_flag_sensitive
,
2532 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2533 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
, NULL
,
2535 "<UUID> = accept an Enrollee PBC using External Registrar" },
2536 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
, NULL
,
2537 cli_cmd_flag_sensitive
,
2538 "<UUID> <PIN> = learn AP configuration" },
2539 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config
, NULL
,
2541 "<UUID> <network id> = set AP configuration for enrolling" },
2542 { "wps_er_config", wpa_cli_cmd_wps_er_config
, NULL
,
2543 cli_cmd_flag_sensitive
,
2544 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2545 #ifdef CONFIG_WPS_NFC
2546 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token
, NULL
,
2548 "<WPS/NDEF> <UUID> = build NFC configuration token" },
2549 #endif /* CONFIG_WPS_NFC */
2550 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
, NULL
,
2552 "<addr> = request RSN authentication with <addr> in IBSS" },
2554 { "sta", wpa_cli_cmd_sta
, NULL
,
2556 "<addr> = get information about an associated station (AP)" },
2557 { "all_sta", wpa_cli_cmd_all_sta
, NULL
,
2559 "= get information about all associated stations (AP)" },
2560 { "deauthenticate", wpa_cli_cmd_deauthenticate
, NULL
,
2562 "<addr> = deauthenticate a station" },
2563 { "disassociate", wpa_cli_cmd_disassociate
, NULL
,
2565 "<addr> = disassociate a station" },
2566 #endif /* CONFIG_AP */
2567 { "suspend", wpa_cli_cmd_suspend
, NULL
, cli_cmd_flag_none
,
2568 "= notification of suspend/hibernate" },
2569 { "resume", wpa_cli_cmd_resume
, NULL
, cli_cmd_flag_none
,
2570 "= notification of resume/thaw" },
2571 { "drop_sa", wpa_cli_cmd_drop_sa
, NULL
, cli_cmd_flag_none
,
2572 "= drop SA without deauth/disassoc (test command)" },
2573 { "roam", wpa_cli_cmd_roam
, wpa_cli_complete_bss
,
2575 "<addr> = roam to the specified BSS" },
2577 { "p2p_find", wpa_cli_cmd_p2p_find
, wpa_cli_complete_p2p_find
,
2579 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2580 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find
, NULL
, cli_cmd_flag_none
,
2581 "= stop P2P Devices search" },
2582 { "p2p_connect", wpa_cli_cmd_p2p_connect
, wpa_cli_complete_p2p_connect
,
2584 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
2585 { "p2p_listen", wpa_cli_cmd_p2p_listen
, NULL
, cli_cmd_flag_none
,
2586 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2587 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove
,
2588 wpa_cli_complete_p2p_group_remove
, cli_cmd_flag_none
,
2589 "<ifname> = remove P2P group interface (terminate group if GO)" },
2590 { "p2p_group_add", wpa_cli_cmd_p2p_group_add
, NULL
, cli_cmd_flag_none
,
2591 "[ht40] = add a new P2P group (local end as GO)" },
2592 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc
,
2593 wpa_cli_complete_p2p_peer
, cli_cmd_flag_none
,
2594 "<addr> <method> = request provisioning discovery" },
2595 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase
, NULL
,
2597 "= get the passphrase for a group (GO only)" },
2598 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req
,
2599 wpa_cli_complete_p2p_peer
, cli_cmd_flag_none
,
2600 "<addr> <TLVs> = schedule service discovery request" },
2601 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req
,
2602 NULL
, cli_cmd_flag_none
,
2603 "<id> = cancel pending service discovery request" },
2604 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp
, NULL
,
2606 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2607 { "p2p_service_update", wpa_cli_cmd_p2p_service_update
, NULL
,
2609 "= indicate change in local services" },
2610 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external
, NULL
,
2612 "<external> = set external processing of service discovery" },
2613 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush
, NULL
,
2615 "= remove all stored service entries" },
2616 { "p2p_service_add", wpa_cli_cmd_p2p_service_add
, NULL
,
2618 "<bonjour|upnp> <query|version> <response|service> = add a local "
2620 { "p2p_service_del", wpa_cli_cmd_p2p_service_del
, NULL
,
2622 "<bonjour|upnp> <query|version> [|service] = remove a local "
2624 { "p2p_reject", wpa_cli_cmd_p2p_reject
, wpa_cli_complete_p2p_peer
,
2626 "<addr> = reject connection attempts from a specific peer" },
2627 { "p2p_invite", wpa_cli_cmd_p2p_invite
, NULL
,
2629 "<cmd> [peer=addr] = invite peer" },
2630 { "p2p_peers", wpa_cli_cmd_p2p_peers
, NULL
, cli_cmd_flag_none
,
2631 "[discovered] = list known (optionally, only fully discovered) P2P "
2633 { "p2p_peer", wpa_cli_cmd_p2p_peer
, wpa_cli_complete_p2p_peer
,
2635 "<address> = show information about known P2P peer" },
2636 { "p2p_set", wpa_cli_cmd_p2p_set
, NULL
, cli_cmd_flag_none
,
2637 "<field> <value> = set a P2P parameter" },
2638 { "p2p_flush", wpa_cli_cmd_p2p_flush
, NULL
, cli_cmd_flag_none
,
2639 "= flush P2P state" },
2640 { "p2p_cancel", wpa_cli_cmd_p2p_cancel
, NULL
, cli_cmd_flag_none
,
2641 "= cancel P2P group formation" },
2642 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize
,
2643 wpa_cli_complete_p2p_peer
, cli_cmd_flag_none
,
2644 "<address> = unauthorize a peer" },
2645 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req
, NULL
,
2647 "[<duration> <interval>] [<duration> <interval>] = request GO "
2649 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen
, NULL
,
2651 "[<period> <interval>] = set extended listen timing" },
2652 #endif /* CONFIG_P2P */
2653 #ifdef CONFIG_WIFI_DISPLAY
2654 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set
, NULL
,
2656 "<subelem> [contents] = set Wi-Fi Display subelement" },
2657 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get
, NULL
,
2659 "<subelem> = get Wi-Fi Display subelement" },
2660 #endif /* CONFIG_WIFI_DISPLAY */
2661 #ifdef CONFIG_INTERWORKING
2662 { "fetch_anqp", wpa_cli_cmd_fetch_anqp
, NULL
, cli_cmd_flag_none
,
2663 "= fetch ANQP information for all APs" },
2664 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp
, NULL
,
2666 "= stop fetch_anqp operation" },
2667 { "interworking_select", wpa_cli_cmd_interworking_select
, NULL
,
2669 "[auto] = perform Interworking network selection" },
2670 { "interworking_connect", wpa_cli_cmd_interworking_connect
,
2671 wpa_cli_complete_bss
, cli_cmd_flag_none
,
2672 "<BSSID> = connect using Interworking credentials" },
2673 { "anqp_get", wpa_cli_cmd_anqp_get
, wpa_cli_complete_bss
,
2675 "<addr> <info id>[,<info id>]... = request ANQP information" },
2676 { "gas_request", wpa_cli_cmd_gas_request
, wpa_cli_complete_bss
,
2678 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
2679 { "gas_response_get", wpa_cli_cmd_gas_response_get
,
2680 wpa_cli_complete_bss
, cli_cmd_flag_none
,
2681 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
2682 #endif /* CONFIG_INTERWORKING */
2684 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get
, wpa_cli_complete_bss
,
2686 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
2688 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list
,
2689 wpa_cli_complete_bss
, cli_cmd_flag_none
,
2690 "<addr> <home realm> = get HS20 nai home realm list" },
2691 #endif /* CONFIG_HS20 */
2692 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect
, NULL
,
2694 "<0/1> = disable/enable automatic reconnection" },
2695 { "tdls_discover", wpa_cli_cmd_tdls_discover
, NULL
,
2697 "<addr> = request TDLS discovery with <addr>" },
2698 { "tdls_setup", wpa_cli_cmd_tdls_setup
, NULL
,
2700 "<addr> = request TDLS setup with <addr>" },
2701 { "tdls_teardown", wpa_cli_cmd_tdls_teardown
, NULL
,
2703 "<addr> = tear down TDLS with <addr>" },
2704 { "signal_poll", wpa_cli_cmd_signal_poll
, NULL
,
2706 "= get signal parameters" },
2707 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll
, NULL
,
2709 "= get TX/RX packet counters" },
2710 { "reauthenticate", wpa_cli_cmd_reauthenticate
, NULL
,
2712 "= trigger IEEE 802.1X/EAPOL reauthentication" },
2713 #ifdef CONFIG_AUTOSCAN
2714 { "autoscan", wpa_cli_cmd_autoscan
, NULL
, cli_cmd_flag_none
,
2715 "[params] = Set or unset (if none) autoscan parameters" },
2716 #endif /* CONFIG_AUTOSCAN */
2717 { "raw", wpa_cli_cmd_raw
, NULL
, cli_cmd_flag_sensitive
,
2718 "<params..> = Sent unprocessed command" },
2719 { NULL
, NULL
, NULL
, cli_cmd_flag_none
, NULL
}
2724 * Prints command usage, lines are padded with the specified string.
2726 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
2731 printf("%s%s ", pad
, cmd
->cmd
);
2732 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
2741 static void print_help(const char *cmd
)
2744 printf("commands:\n");
2745 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++) {
2746 if (cmd
== NULL
|| str_starts(wpa_cli_commands
[n
].cmd
, cmd
))
2747 print_cmd_help(&wpa_cli_commands
[n
], " ");
2752 static int wpa_cli_edit_filter_history_cb(void *ctx
, const char *cmd
)
2754 const char *c
, *delim
;
2758 delim
= os_strchr(cmd
, ' ');
2762 len
= os_strlen(cmd
);
2764 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
2765 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
2766 return (wpa_cli_commands
[n
].flags
&
2767 cli_cmd_flag_sensitive
);
2773 static char ** wpa_list_cmd_list(void)
2778 count
= sizeof(wpa_cli_commands
) / sizeof(wpa_cli_commands
[0]);
2779 res
= os_calloc(count
, sizeof(char *));
2783 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2784 res
[i
] = os_strdup(wpa_cli_commands
[i
].cmd
);
2793 static char ** wpa_cli_cmd_completion(const char *cmd
, const char *str
,
2798 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2799 if (os_strcasecmp(wpa_cli_commands
[i
].cmd
, cmd
) == 0) {
2800 if (wpa_cli_commands
[i
].completion
)
2801 return wpa_cli_commands
[i
].completion(str
,
2804 printf("\r%s\n", wpa_cli_commands
[i
].usage
);
2814 static char ** wpa_cli_edit_completion_cb(void *ctx
, const char *str
, int pos
)
2820 end
= os_strchr(str
, ' ');
2821 if (end
== NULL
|| str
+ pos
< end
)
2822 return wpa_list_cmd_list();
2824 cmd
= os_malloc(pos
+ 1);
2827 os_memcpy(cmd
, str
, pos
);
2828 cmd
[end
- str
] = '\0';
2829 res
= wpa_cli_cmd_completion(cmd
, str
, pos
);
2835 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2837 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
2842 cmd
= wpa_cli_commands
;
2844 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
2847 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
2848 /* we have an exact match */
2858 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
2859 cmd
= wpa_cli_commands
;
2861 if (os_strncasecmp(cmd
->cmd
, argv
[0],
2862 os_strlen(argv
[0])) == 0) {
2863 printf(" %s", cmd
->cmd
);
2869 } else if (count
== 0) {
2870 printf("Unknown command '%s'\n", argv
[0]);
2873 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
2880 static int str_match(const char *a
, const char *b
)
2882 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
2886 static int wpa_cli_exec(const char *program
, const char *arg1
,
2894 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
2895 cmd
= os_malloc(len
);
2898 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
2899 if (res
< 0 || (size_t) res
>= len
) {
2903 cmd
[len
- 1] = '\0';
2905 if (system(cmd
) < 0)
2907 #endif /* _WIN32_WCE */
2914 static void wpa_cli_action_process(const char *msg
)
2917 char *copy
= NULL
, *id
, *pos2
;
2922 pos
= os_strchr(pos
, '>');
2929 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
2931 os_unsetenv("WPA_ID");
2932 os_unsetenv("WPA_ID_STR");
2933 os_unsetenv("WPA_CTRL_DIR");
2935 pos
= os_strstr(pos
, "[id=");
2937 copy
= os_strdup(pos
+ 4);
2941 while (*pos2
&& *pos2
!= ' ')
2945 os_setenv("WPA_ID", id
, 1);
2946 while (*pos2
&& *pos2
!= '=')
2951 while (*pos2
&& *pos2
!= ']')
2954 os_setenv("WPA_ID_STR", id
, 1);
2958 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
2960 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
2961 wpa_cli_connected
= 1;
2962 wpa_cli_last_id
= new_id
;
2963 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
2965 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
2966 if (wpa_cli_connected
) {
2967 wpa_cli_connected
= 0;
2968 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
2970 } else if (str_match(pos
, P2P_EVENT_GROUP_STARTED
)) {
2971 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2972 } else if (str_match(pos
, P2P_EVENT_GROUP_REMOVED
)) {
2973 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2974 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_ENABLE
)) {
2975 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2976 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_DISABLE
)) {
2977 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2978 } else if (str_match(pos
, P2P_EVENT_GO_NEG_FAILURE
)) {
2979 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2980 } else if (str_match(pos
, WPS_EVENT_SUCCESS
)) {
2981 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2982 } else if (str_match(pos
, WPS_EVENT_FAIL
)) {
2983 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2984 } else if (str_match(pos
, AP_STA_CONNECTED
)) {
2985 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2986 } else if (str_match(pos
, AP_STA_DISCONNECTED
)) {
2987 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2988 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
2989 printf("wpa_supplicant is terminating - stop monitoring\n");
2995 #ifndef CONFIG_ANSI_C_EXTRA
2996 static void wpa_cli_action_cb(char *msg
, size_t len
)
2998 wpa_cli_action_process(msg
);
3000 #endif /* CONFIG_ANSI_C_EXTRA */
3003 static void wpa_cli_reconnect(void)
3005 wpa_cli_close_connection();
3006 if (wpa_cli_open_connection(ctrl_ifname
, 1) < 0)
3011 printf("\rConnection to wpa_supplicant re-established\n");
3017 static void cli_event(const char *str
)
3019 const char *start
, *s
;
3021 start
= os_strchr(str
, '>');
3027 if (str_starts(start
, WPA_EVENT_BSS_ADDED
)) {
3028 s
= os_strchr(start
, ' ');
3031 s
= os_strchr(s
+ 1, ' ');
3034 cli_txt_list_add(&bsses
, s
+ 1);
3038 if (str_starts(start
, WPA_EVENT_BSS_REMOVED
)) {
3039 s
= os_strchr(start
, ' ');
3042 s
= os_strchr(s
+ 1, ' ');
3045 cli_txt_list_del_addr(&bsses
, s
+ 1);
3050 if (str_starts(start
, P2P_EVENT_DEVICE_FOUND
)) {
3051 s
= os_strstr(start
, " p2p_dev_addr=");
3054 cli_txt_list_add_addr(&p2p_peers
, s
+ 14);
3058 if (str_starts(start
, P2P_EVENT_DEVICE_LOST
)) {
3059 s
= os_strstr(start
, " p2p_dev_addr=");
3062 cli_txt_list_del_addr(&p2p_peers
, s
+ 14);
3066 if (str_starts(start
, P2P_EVENT_GROUP_STARTED
)) {
3067 s
= os_strchr(start
, ' ');
3070 cli_txt_list_add_word(&p2p_groups
, s
+ 1);
3074 if (str_starts(start
, P2P_EVENT_GROUP_REMOVED
)) {
3075 s
= os_strchr(start
, ' ');
3078 cli_txt_list_del_word(&p2p_groups
, s
+ 1);
3081 #endif /* CONFIG_P2P */
3085 static int check_terminating(const char *msg
)
3087 const char *pos
= msg
;
3091 pos
= os_strchr(pos
, '>');
3098 if (str_match(pos
, WPA_EVENT_TERMINATING
) && ctrl_conn
) {
3100 printf("\rConnection to wpa_supplicant lost - trying to "
3103 wpa_cli_attached
= 0;
3104 wpa_cli_close_connection();
3112 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int action_monitor
)
3114 if (ctrl_conn
== NULL
) {
3115 wpa_cli_reconnect();
3118 while (wpa_ctrl_pending(ctrl
) > 0) {
3120 size_t len
= sizeof(buf
) - 1;
3121 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
3124 wpa_cli_action_process(buf
);
3127 if (wpa_cli_show_event(buf
)) {
3129 printf("\r%s\n", buf
);
3133 if (interactive
&& check_terminating(buf
) > 0)
3137 printf("Could not read pending message.\n");
3142 if (wpa_ctrl_pending(ctrl
) < 0) {
3143 printf("Connection to wpa_supplicant lost - trying to "
3145 wpa_cli_reconnect();
3151 static int tokenize_cmd(char *cmd
, char *argv
[])
3164 if (argc
== max_args
)
3167 char *pos2
= os_strrchr(pos
, '"');
3171 while (*pos
!= '\0' && *pos
!= ' ')
3181 static void wpa_cli_ping(void *eloop_ctx
, void *timeout_ctx
)
3183 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
3184 printf("Connection to wpa_supplicant lost - trying to "
3186 wpa_cli_close_connection();
3189 wpa_cli_reconnect();
3190 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3194 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
)
3196 wpa_cli_recv_pending(mon_conn
, 0);
3200 static void wpa_cli_edit_cmd_cb(void *ctx
, char *cmd
)
3202 char *argv
[max_args
];
3204 argc
= tokenize_cmd(cmd
, argv
);
3206 wpa_request(ctrl_conn
, argc
, argv
);
3210 static void wpa_cli_edit_eof_cb(void *ctx
)
3216 static int warning_displayed
= 0;
3217 static char *hfile
= NULL
;
3218 static int edit_started
= 0;
3220 static void start_edit(void)
3225 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3226 ps
= wpa_ctrl_get_remote_ifname(ctrl_conn
);
3227 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3229 home
= getenv("HOME");
3231 const char *fname
= ".wpa_cli_history";
3232 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
3233 hfile
= os_malloc(hfile_len
);
3235 os_snprintf(hfile
, hfile_len
, "%s/%s", home
, fname
);
3238 if (edit_init(wpa_cli_edit_cmd_cb
, wpa_cli_edit_eof_cb
,
3239 wpa_cli_edit_completion_cb
, NULL
, hfile
, ps
) < 0) {
3245 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3249 static void try_connection(void *eloop_ctx
, void *timeout_ctx
)
3251 if (ctrl_ifname
== NULL
)
3252 ctrl_ifname
= wpa_cli_get_default_ifname();
3254 if (!wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
3255 if (!warning_displayed
) {
3256 printf("Could not connect to wpa_supplicant: "
3257 "%s - re-trying\n", ctrl_ifname
);
3258 warning_displayed
= 1;
3260 eloop_register_timeout(1, 0, try_connection
, NULL
, NULL
);
3264 if (warning_displayed
)
3265 printf("Connection established.\n");
3271 static void wpa_cli_interactive(void)
3273 printf("\nInteractive mode\n\n");
3275 eloop_register_timeout(0, 0, try_connection
, NULL
, NULL
);
3277 eloop_cancel_timeout(try_connection
, NULL
, NULL
);
3279 cli_txt_list_flush(&p2p_peers
);
3280 cli_txt_list_flush(&p2p_groups
);
3281 cli_txt_list_flush(&bsses
);
3283 edit_deinit(hfile
, wpa_cli_edit_filter_history_cb
);
3285 eloop_cancel_timeout(wpa_cli_ping
, NULL
, NULL
);
3286 wpa_cli_close_connection();
3290 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
3292 #ifdef CONFIG_ANSI_C_EXTRA
3293 /* TODO: ANSI C version(?) */
3294 printf("Action processing not supported in ANSI C build.\n");
3295 #else /* CONFIG_ANSI_C_EXTRA */
3299 char buf
[256]; /* note: large enough to fit in unsolicited messages */
3302 fd
= wpa_ctrl_get_fd(ctrl
);
3304 while (!wpa_cli_quit
) {
3307 tv
.tv_sec
= ping_interval
;
3309 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
3310 if (res
< 0 && errno
!= EINTR
) {
3315 if (FD_ISSET(fd
, &rfds
))
3316 wpa_cli_recv_pending(ctrl
, 1);
3318 /* verify that connection is still working */
3319 len
= sizeof(buf
) - 1;
3320 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
3321 wpa_cli_action_cb
) < 0 ||
3322 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
3323 printf("wpa_supplicant did not reply to PING "
3324 "command - exiting\n");
3329 #endif /* CONFIG_ANSI_C_EXTRA */
3333 static void wpa_cli_cleanup(void)
3335 wpa_cli_close_connection();
3337 os_daemonize_terminate(pid_file
);
3339 os_program_deinit();
3343 static void wpa_cli_terminate(int sig
, void *ctx
)
3349 static char * wpa_cli_get_default_ifname(void)
3351 char *ifname
= NULL
;
3353 #ifdef CONFIG_CTRL_IFACE_UNIX
3354 struct dirent
*dent
;
3355 DIR *dir
= opendir(ctrl_iface_dir
);
3358 char ifprop
[PROPERTY_VALUE_MAX
];
3359 if (property_get("wifi.interface", ifprop
, NULL
) != 0) {
3360 ifname
= os_strdup(ifprop
);
3361 printf("Using interface '%s'\n", ifname
);
3364 #endif /* ANDROID */
3367 while ((dent
= readdir(dir
))) {
3368 #ifdef _DIRENT_HAVE_D_TYPE
3370 * Skip the file if it is not a socket. Also accept
3371 * DT_UNKNOWN (0) in case the C library or underlying
3372 * file system does not support d_type.
3374 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
3376 #endif /* _DIRENT_HAVE_D_TYPE */
3377 if (os_strcmp(dent
->d_name
, ".") == 0 ||
3378 os_strcmp(dent
->d_name
, "..") == 0)
3380 printf("Selected interface '%s'\n", dent
->d_name
);
3381 ifname
= os_strdup(dent
->d_name
);
3385 #endif /* CONFIG_CTRL_IFACE_UNIX */
3387 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3388 char buf
[2048], *pos
;
3390 struct wpa_ctrl
*ctrl
;
3393 ctrl
= wpa_ctrl_open(NULL
);
3397 len
= sizeof(buf
) - 1;
3398 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
3401 pos
= os_strchr(buf
, '\n');
3404 ifname
= os_strdup(buf
);
3406 wpa_ctrl_close(ctrl
);
3407 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3413 int main(int argc
, char *argv
[])
3418 const char *global
= NULL
;
3420 if (os_program_init())
3424 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
3429 action_file
= optarg
;
3438 ping_interval
= atoi(optarg
);
3444 printf("%s\n", wpa_cli_version
);
3447 os_free(ctrl_ifname
);
3448 ctrl_ifname
= os_strdup(optarg
);
3451 ctrl_iface_dir
= optarg
;
3462 interactive
= (argc
== optind
) && (action_file
== NULL
);
3465 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
3471 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3472 ctrl_conn
= wpa_ctrl_open(NULL
);
3473 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3474 ctrl_conn
= wpa_ctrl_open(global
);
3475 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3476 if (ctrl_conn
== NULL
) {
3477 fprintf(stderr
, "Failed to connect to wpa_supplicant "
3478 "global interface: %s error: %s\n",
3479 global
, strerror(errno
));
3484 eloop_register_signal_terminate(wpa_cli_terminate
, NULL
);
3486 if (ctrl_ifname
== NULL
)
3487 ctrl_ifname
= wpa_cli_get_default_ifname();
3490 wpa_cli_interactive();
3493 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
3494 fprintf(stderr
, "Failed to connect to non-global "
3495 "ctrl_ifname: %s error: %s\n",
3496 ctrl_ifname
, strerror(errno
));
3501 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
3502 wpa_cli_attached
= 1;
3504 printf("Warning: Failed to attach to "
3505 "wpa_supplicant.\n");
3510 if (daemonize
&& os_daemonize(pid_file
))
3514 wpa_cli_action(ctrl_conn
);
3516 ret
= wpa_request(ctrl_conn
, argc
- optind
,
3520 os_free(ctrl_ifname
);
3527 #else /* CONFIG_CTRL_IFACE */
3528 int main(int argc
, char *argv
[])
3530 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3533 #endif /* CONFIG_CTRL_IFACE */