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
);
799 #endif /* CONFIG_WPS_NFC */
802 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
808 res
= os_snprintf(cmd
, sizeof(cmd
), "WPS_REG %s %s",
810 else if (argc
== 5 || argc
== 6) {
811 char ssid_hex
[2 * 32 + 1];
812 char key_hex
[2 * 64 + 1];
816 for (i
= 0; i
< 32; i
++) {
817 if (argv
[2][i
] == '\0')
819 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
824 for (i
= 0; i
< 64; i
++) {
825 if (argv
[5][i
] == '\0')
827 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
832 res
= os_snprintf(cmd
, sizeof(cmd
),
833 "WPS_REG %s %s %s %s %s %s",
834 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
837 printf("Invalid WPS_REG command: need two arguments:\n"
838 "- BSSID of the target AP\n"
840 printf("Alternatively, six arguments can be used to "
841 "reconfigure the AP:\n"
842 "- BSSID of the target AP\n"
845 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
846 "- new encr (NONE, WEP, TKIP, CCMP)\n"
851 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
852 printf("Too long WPS_REG command.\n");
855 return wpa_ctrl_command(ctrl
, cmd
);
859 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl
*ctrl
, int argc
,
862 return wpa_cli_cmd(ctrl
, "WPS_AP_PIN", 1, argc
, argv
);
866 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl
*ctrl
, int argc
,
869 return wpa_cli_cmd(ctrl
, "WPS_ER_START", 0, argc
, argv
);
873 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl
*ctrl
, int argc
,
876 return wpa_ctrl_command(ctrl
, "WPS_ER_STOP");
881 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl
*ctrl
, int argc
,
885 printf("Invalid WPS_ER_PIN command: need at least two "
887 "- UUID: use 'any' to select any\n"
888 "- PIN: Enrollee PIN\n"
889 "optional: - Enrollee MAC address\n");
893 return wpa_cli_cmd(ctrl
, "WPS_ER_PIN", 2, argc
, argv
);
897 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl
*ctrl
, int argc
,
900 return wpa_cli_cmd(ctrl
, "WPS_ER_PBC", 1, argc
, argv
);
904 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl
*ctrl
, int argc
,
908 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
909 "- UUID: specify which AP to use\n"
914 return wpa_cli_cmd(ctrl
, "WPS_ER_LEARN", 2, argc
, argv
);
918 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl
*ctrl
, int argc
,
922 printf("Invalid WPS_ER_SET_CONFIG command: need two "
924 "- UUID: specify which AP to use\n"
925 "- Network configuration id\n");
929 return wpa_cli_cmd(ctrl
, "WPS_ER_SET_CONFIG", 2, argc
, argv
);
933 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl
*ctrl
, int argc
,
939 if (argc
== 5 || argc
== 6) {
940 char ssid_hex
[2 * 32 + 1];
941 char key_hex
[2 * 64 + 1];
945 for (i
= 0; i
< 32; i
++) {
946 if (argv
[2][i
] == '\0')
948 os_snprintf(&ssid_hex
[i
* 2], 3, "%02x", argv
[2][i
]);
953 for (i
= 0; i
< 64; i
++) {
954 if (argv
[5][i
] == '\0')
956 os_snprintf(&key_hex
[i
* 2], 3, "%02x",
961 res
= os_snprintf(cmd
, sizeof(cmd
),
962 "WPS_ER_CONFIG %s %s %s %s %s %s",
963 argv
[0], argv
[1], ssid_hex
, argv
[3], argv
[4],
966 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
970 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
971 "- new encr (NONE, WEP, TKIP, CCMP)\n"
976 if (res
< 0 || (size_t) res
>= sizeof(cmd
) - 1) {
977 printf("Too long WPS_ER_CONFIG command.\n");
980 return wpa_ctrl_command(ctrl
, cmd
);
984 #ifdef CONFIG_WPS_NFC
985 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl
*ctrl
, int argc
,
989 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
991 "- WPS/NDEF: token format\n"
992 "- UUID: specify which AP to use\n");
996 return wpa_cli_cmd(ctrl
, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc
, argv
);
998 #endif /* CONFIG_WPS_NFC */
1001 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1003 return wpa_cli_cmd(ctrl
, "IBSS_RSN", 1, argc
, argv
);
1007 static int wpa_cli_cmd_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1009 return wpa_cli_cmd(ctrl
, "LEVEL", 1, argc
, argv
);
1013 static int wpa_cli_cmd_identity(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1015 char cmd
[256], *pos
, *end
;
1019 printf("Invalid IDENTITY command: needs two arguments "
1020 "(network id and identity)\n");
1024 end
= cmd
+ sizeof(cmd
);
1026 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"IDENTITY-%s:%s",
1028 if (ret
< 0 || ret
>= end
- pos
) {
1029 printf("Too long IDENTITY 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 IDENTITY command.\n");
1042 return wpa_ctrl_command(ctrl
, cmd
);
1046 static int wpa_cli_cmd_password(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1048 char cmd
[256], *pos
, *end
;
1052 printf("Invalid PASSWORD command: needs two arguments "
1053 "(network id and password)\n");
1057 end
= cmd
+ sizeof(cmd
);
1059 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSWORD-%s:%s",
1061 if (ret
< 0 || ret
>= end
- pos
) {
1062 printf("Too long PASSWORD command.\n");
1066 for (i
= 2; i
< argc
; i
++) {
1067 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1068 if (ret
< 0 || ret
>= end
- pos
) {
1069 printf("Too long PASSWORD command.\n");
1075 return wpa_ctrl_command(ctrl
, cmd
);
1079 static int wpa_cli_cmd_new_password(struct wpa_ctrl
*ctrl
, int argc
,
1082 char cmd
[256], *pos
, *end
;
1086 printf("Invalid NEW_PASSWORD command: needs two arguments "
1087 "(network id and password)\n");
1091 end
= cmd
+ sizeof(cmd
);
1093 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"NEW_PASSWORD-%s:%s",
1095 if (ret
< 0 || ret
>= end
- pos
) {
1096 printf("Too long NEW_PASSWORD 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 NEW_PASSWORD command.\n");
1109 return wpa_ctrl_command(ctrl
, cmd
);
1113 static int wpa_cli_cmd_pin(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1115 char cmd
[256], *pos
, *end
;
1119 printf("Invalid PIN command: needs two arguments "
1120 "(network id and pin)\n");
1124 end
= cmd
+ sizeof(cmd
);
1126 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PIN-%s:%s",
1128 if (ret
< 0 || ret
>= end
- pos
) {
1129 printf("Too long PIN command.\n");
1133 for (i
= 2; i
< argc
; i
++) {
1134 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1135 if (ret
< 0 || ret
>= end
- pos
) {
1136 printf("Too long PIN command.\n");
1141 return wpa_ctrl_command(ctrl
, cmd
);
1145 static int wpa_cli_cmd_otp(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1147 char cmd
[256], *pos
, *end
;
1151 printf("Invalid OTP command: needs two arguments (network "
1152 "id and password)\n");
1156 end
= cmd
+ sizeof(cmd
);
1158 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"OTP-%s:%s",
1160 if (ret
< 0 || ret
>= end
- pos
) {
1161 printf("Too long OTP command.\n");
1165 for (i
= 2; i
< argc
; i
++) {
1166 ret
= os_snprintf(pos
, end
- pos
, " %s", argv
[i
]);
1167 if (ret
< 0 || ret
>= end
- pos
) {
1168 printf("Too long OTP command.\n");
1174 return wpa_ctrl_command(ctrl
, cmd
);
1178 static int wpa_cli_cmd_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1181 char cmd
[256], *pos
, *end
;
1185 printf("Invalid PASSPHRASE command: needs two arguments "
1186 "(network id and passphrase)\n");
1190 end
= cmd
+ sizeof(cmd
);
1192 ret
= os_snprintf(pos
, end
- pos
, WPA_CTRL_RSP
"PASSPHRASE-%s:%s",
1194 if (ret
< 0 || ret
>= end
- pos
) {
1195 printf("Too long PASSPHRASE 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 PASSPHRASE command.\n");
1208 return wpa_ctrl_command(ctrl
, cmd
);
1212 static int wpa_cli_cmd_bssid(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1215 printf("Invalid BSSID command: needs two arguments (network "
1220 return wpa_cli_cmd(ctrl
, "BSSID", 2, argc
, argv
);
1224 static int wpa_cli_cmd_blacklist(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1226 return wpa_cli_cmd(ctrl
, "BLACKLIST", 0, argc
, argv
);
1230 static int wpa_cli_cmd_log_level(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1232 return wpa_cli_cmd(ctrl
, "LOG_LEVEL", 0, argc
, argv
);
1236 static int wpa_cli_cmd_list_networks(struct wpa_ctrl
*ctrl
, int argc
,
1239 return wpa_ctrl_command(ctrl
, "LIST_NETWORKS");
1243 static int wpa_cli_cmd_select_network(struct wpa_ctrl
*ctrl
, int argc
,
1246 return wpa_cli_cmd(ctrl
, "SELECT_NETWORK", 1, argc
, argv
);
1250 static int wpa_cli_cmd_enable_network(struct wpa_ctrl
*ctrl
, int argc
,
1253 return wpa_cli_cmd(ctrl
, "ENABLE_NETWORK", 1, argc
, argv
);
1257 static int wpa_cli_cmd_disable_network(struct wpa_ctrl
*ctrl
, int argc
,
1260 return wpa_cli_cmd(ctrl
, "DISABLE_NETWORK", 1, argc
, argv
);
1264 static int wpa_cli_cmd_add_network(struct wpa_ctrl
*ctrl
, int argc
,
1267 return wpa_ctrl_command(ctrl
, "ADD_NETWORK");
1271 static int wpa_cli_cmd_remove_network(struct wpa_ctrl
*ctrl
, int argc
,
1274 return wpa_cli_cmd(ctrl
, "REMOVE_NETWORK", 1, argc
, argv
);
1278 static void wpa_cli_show_network_variables(void)
1280 printf("set_network variables:\n"
1281 " ssid (network name, SSID)\n"
1282 " psk (WPA passphrase or pre-shared key)\n"
1283 " key_mgmt (key management protocol)\n"
1284 " identity (EAP identity)\n"
1285 " password (EAP password)\n"
1288 "Note: Values are entered in the same format as the "
1289 "configuration file is using,\n"
1290 "i.e., strings values need to be inside double quotation "
1292 "For example: set_network 1 ssid \"network name\"\n"
1294 "Please see wpa_supplicant.conf documentation for full list "
1295 "of\navailable variables.\n");
1299 static int wpa_cli_cmd_set_network(struct wpa_ctrl
*ctrl
, int argc
,
1303 wpa_cli_show_network_variables();
1308 printf("Invalid SET_NETWORK command: needs three arguments\n"
1309 "(network id, variable name, and value)\n");
1313 return wpa_cli_cmd(ctrl
, "SET_NETWORK", 3, argc
, argv
);
1317 static int wpa_cli_cmd_get_network(struct wpa_ctrl
*ctrl
, int argc
,
1321 wpa_cli_show_network_variables();
1326 printf("Invalid GET_NETWORK command: needs two arguments\n"
1327 "(network id and variable name)\n");
1331 return wpa_cli_cmd(ctrl
, "GET_NETWORK", 2, argc
, argv
);
1335 static int wpa_cli_cmd_list_creds(struct wpa_ctrl
*ctrl
, int argc
,
1338 return wpa_ctrl_command(ctrl
, "LIST_CREDS");
1342 static int wpa_cli_cmd_add_cred(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1344 return wpa_ctrl_command(ctrl
, "ADD_CRED");
1348 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl
*ctrl
, int argc
,
1351 return wpa_cli_cmd(ctrl
, "REMOVE_CRED", 1, argc
, argv
);
1355 static int wpa_cli_cmd_set_cred(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1358 printf("Invalid SET_CRED command: needs three arguments\n"
1359 "(cred id, variable name, and value)\n");
1363 return wpa_cli_cmd(ctrl
, "SET_CRED", 3, argc
, argv
);
1367 static int wpa_cli_cmd_disconnect(struct wpa_ctrl
*ctrl
, int argc
,
1370 return wpa_ctrl_command(ctrl
, "DISCONNECT");
1374 static int wpa_cli_cmd_reconnect(struct wpa_ctrl
*ctrl
, int argc
,
1377 return wpa_ctrl_command(ctrl
, "RECONNECT");
1381 static int wpa_cli_cmd_save_config(struct wpa_ctrl
*ctrl
, int argc
,
1384 return wpa_ctrl_command(ctrl
, "SAVE_CONFIG");
1388 static int wpa_cli_cmd_scan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1390 return wpa_ctrl_command(ctrl
, "SCAN");
1394 static int wpa_cli_cmd_scan_results(struct wpa_ctrl
*ctrl
, int argc
,
1397 return wpa_ctrl_command(ctrl
, "SCAN_RESULTS");
1401 static int wpa_cli_cmd_bss(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1403 return wpa_cli_cmd(ctrl
, "BSS", 1, argc
, argv
);
1407 static char ** wpa_cli_complete_bss(const char *str
, int pos
)
1409 int arg
= get_cmd_arg_num(str
, pos
);
1414 res
= cli_txt_list_array(&bsses
);
1422 static int wpa_cli_cmd_get_capability(struct wpa_ctrl
*ctrl
, int argc
,
1425 if (argc
< 1 || argc
> 2) {
1426 printf("Invalid GET_CAPABILITY command: need either one or "
1431 if ((argc
== 2) && os_strcmp(argv
[1], "strict") != 0) {
1432 printf("Invalid GET_CAPABILITY command: second argument, "
1433 "if any, must be 'strict'\n");
1437 return wpa_cli_cmd(ctrl
, "GET_CAPABILITY", 1, argc
, argv
);
1441 static int wpa_cli_list_interfaces(struct wpa_ctrl
*ctrl
)
1443 printf("Available interfaces:\n");
1444 return wpa_ctrl_command(ctrl
, "INTERFACES");
1448 static int wpa_cli_cmd_interface(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1451 wpa_cli_list_interfaces(ctrl
);
1455 wpa_cli_close_connection();
1456 os_free(ctrl_ifname
);
1457 ctrl_ifname
= os_strdup(argv
[0]);
1459 if (wpa_cli_open_connection(ctrl_ifname
, 1)) {
1460 printf("Connected to interface '%s.\n", ctrl_ifname
);
1462 printf("Could not connect to interface '%s' - re-trying\n",
1469 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl
*ctrl
, int argc
,
1472 return wpa_ctrl_command(ctrl
, "RECONFIGURE");
1476 static int wpa_cli_cmd_terminate(struct wpa_ctrl
*ctrl
, int argc
,
1479 return wpa_ctrl_command(ctrl
, "TERMINATE");
1483 static int wpa_cli_cmd_interface_add(struct wpa_ctrl
*ctrl
, int argc
,
1490 printf("Invalid INTERFACE_ADD command: needs at least one "
1491 "argument (interface name)\n"
1492 "All arguments: ifname confname driver ctrl_interface "
1493 "driver_param bridge_name\n");
1498 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1499 * <driver_param>TAB<bridge_name>
1501 res
= os_snprintf(cmd
, sizeof(cmd
),
1502 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1504 argc
> 1 ? argv
[1] : "", argc
> 2 ? argv
[2] : "",
1505 argc
> 3 ? argv
[3] : "", argc
> 4 ? argv
[4] : "",
1506 argc
> 5 ? argv
[5] : "");
1507 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1509 cmd
[sizeof(cmd
) - 1] = '\0';
1510 return wpa_ctrl_command(ctrl
, cmd
);
1514 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl
*ctrl
, int argc
,
1517 return wpa_cli_cmd(ctrl
, "INTERFACE_REMOVE", 1, argc
, argv
);
1521 static int wpa_cli_cmd_interface_list(struct wpa_ctrl
*ctrl
, int argc
,
1524 return wpa_ctrl_command(ctrl
, "INTERFACE_LIST");
1529 static int wpa_cli_cmd_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1531 return wpa_cli_cmd(ctrl
, "STA", 1, argc
, argv
);
1535 static int wpa_ctrl_command_sta(struct wpa_ctrl
*ctrl
, char *cmd
,
1536 char *addr
, size_t addr_len
)
1538 char buf
[4096], *pos
;
1542 if (ctrl_conn
== NULL
) {
1543 printf("Not connected to hostapd - command dropped.\n");
1546 len
= sizeof(buf
) - 1;
1547 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
1550 printf("'%s' command timed out.\n", cmd
);
1552 } else if (ret
< 0) {
1553 printf("'%s' command failed.\n", cmd
);
1558 if (os_memcmp(buf
, "FAIL", 4) == 0)
1563 while (*pos
!= '\0' && *pos
!= '\n')
1566 os_strlcpy(addr
, buf
, addr_len
);
1571 static int wpa_cli_cmd_all_sta(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1573 char addr
[32], cmd
[64];
1575 if (wpa_ctrl_command_sta(ctrl
, "STA-FIRST", addr
, sizeof(addr
)))
1578 os_snprintf(cmd
, sizeof(cmd
), "STA-NEXT %s", addr
);
1579 } while (wpa_ctrl_command_sta(ctrl
, cmd
, addr
, sizeof(addr
)) == 0);
1585 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
1588 return wpa_cli_cmd(ctrl
, "DEAUTHENTICATE", 1, argc
, argv
);
1592 static int wpa_cli_cmd_disassociate(struct wpa_ctrl
*ctrl
, int argc
,
1595 return wpa_cli_cmd(ctrl
, "DISASSOCIATE", 1, argc
, argv
);
1597 #endif /* CONFIG_AP */
1600 static int wpa_cli_cmd_suspend(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1602 return wpa_ctrl_command(ctrl
, "SUSPEND");
1606 static int wpa_cli_cmd_resume(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1608 return wpa_ctrl_command(ctrl
, "RESUME");
1612 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1614 return wpa_ctrl_command(ctrl
, "DROP_SA");
1618 static int wpa_cli_cmd_roam(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1620 return wpa_cli_cmd(ctrl
, "ROAM", 1, argc
, argv
);
1626 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1628 return wpa_cli_cmd(ctrl
, "P2P_FIND", 0, argc
, argv
);
1632 static char ** wpa_cli_complete_p2p_find(const char *str
, int pos
)
1635 int arg
= get_cmd_arg_num(str
, pos
);
1637 res
= os_calloc(6, sizeof(char *));
1640 res
[0] = os_strdup("type=social");
1641 if (res
[0] == NULL
) {
1645 res
[1] = os_strdup("type=progressive");
1648 res
[2] = os_strdup("delay=");
1651 res
[3] = os_strdup("dev_id=");
1655 res
[4] = os_strdup("[timeout]");
1661 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl
*ctrl
, int argc
,
1664 return wpa_ctrl_command(ctrl
, "P2P_STOP_FIND");
1668 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl
*ctrl
, int argc
,
1671 return wpa_cli_cmd(ctrl
, "P2P_CONNECT", 2, argc
, argv
);
1675 static char ** wpa_cli_complete_p2p_connect(const char *str
, int pos
)
1677 int arg
= get_cmd_arg_num(str
, pos
);
1682 res
= cli_txt_list_array(&p2p_peers
);
1690 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl
*ctrl
, int argc
,
1693 return wpa_cli_cmd(ctrl
, "P2P_LISTEN", 0, argc
, argv
);
1697 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl
*ctrl
, int argc
,
1700 return wpa_cli_cmd(ctrl
, "P2P_GROUP_REMOVE", 1, argc
, argv
);
1704 static char ** wpa_cli_complete_p2p_group_remove(const char *str
, int pos
)
1706 int arg
= get_cmd_arg_num(str
, pos
);
1711 res
= cli_txt_list_array(&p2p_groups
);
1719 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl
*ctrl
, int argc
,
1722 return wpa_cli_cmd(ctrl
, "P2P_GROUP_ADD", 0, argc
, argv
);
1726 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl
*ctrl
, int argc
,
1729 if (argc
!= 2 && argc
!= 3) {
1730 printf("Invalid P2P_PROV_DISC command: needs at least "
1731 "two arguments, address and config method\n"
1732 "(display, keypad, or pbc) and an optional join\n");
1736 return wpa_cli_cmd(ctrl
, "P2P_PROV_DISC", 2, argc
, argv
);
1740 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1743 return wpa_ctrl_command(ctrl
, "P2P_GET_PASSPHRASE");
1747 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl
*ctrl
, int argc
,
1752 if (argc
!= 2 && argc
!= 4) {
1753 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1754 "arguments (address and TLVs) or four arguments "
1755 "(address, \"upnp\", version, search target "
1760 if (write_cmd(cmd
, sizeof(cmd
), "P2P_SERV_DISC_REQ", argc
, argv
) < 0)
1762 return wpa_ctrl_command(ctrl
, cmd
);
1766 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl
*ctrl
,
1767 int argc
, char *argv
[])
1769 return wpa_cli_cmd(ctrl
, "P2P_SERV_DISC_CANCEL_REQ", 1, argc
, argv
);
1773 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl
*ctrl
, int argc
,
1780 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1781 "arguments (freq, address, dialog token, and TLVs)\n");
1785 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_RESP %s %s %s %s",
1786 argv
[0], argv
[1], argv
[2], argv
[3]);
1787 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1789 cmd
[sizeof(cmd
) - 1] = '\0';
1790 return wpa_ctrl_command(ctrl
, cmd
);
1794 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl
*ctrl
, int argc
,
1797 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_UPDATE");
1801 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl
*ctrl
,
1802 int argc
, char *argv
[])
1804 return wpa_cli_cmd(ctrl
, "P2P_SERV_DISC_EXTERNAL", 1, argc
, argv
);
1808 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl
*ctrl
, int argc
,
1811 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_FLUSH");
1815 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl
*ctrl
, int argc
,
1821 if (argc
!= 3 && argc
!= 4) {
1822 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1828 res
= os_snprintf(cmd
, sizeof(cmd
),
1829 "P2P_SERVICE_ADD %s %s %s %s",
1830 argv
[0], argv
[1], argv
[2], argv
[3]);
1832 res
= os_snprintf(cmd
, sizeof(cmd
),
1833 "P2P_SERVICE_ADD %s %s %s",
1834 argv
[0], argv
[1], argv
[2]);
1835 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1837 cmd
[sizeof(cmd
) - 1] = '\0';
1838 return wpa_ctrl_command(ctrl
, cmd
);
1842 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl
*ctrl
, int argc
,
1848 if (argc
!= 2 && argc
!= 3) {
1849 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1855 res
= os_snprintf(cmd
, sizeof(cmd
),
1856 "P2P_SERVICE_DEL %s %s %s",
1857 argv
[0], argv
[1], argv
[2]);
1859 res
= os_snprintf(cmd
, sizeof(cmd
),
1860 "P2P_SERVICE_DEL %s %s",
1862 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1864 cmd
[sizeof(cmd
) - 1] = '\0';
1865 return wpa_ctrl_command(ctrl
, cmd
);
1869 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl
*ctrl
,
1870 int argc
, char *argv
[])
1872 return wpa_cli_cmd(ctrl
, "P2P_REJECT", 1, argc
, argv
);
1876 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl
*ctrl
,
1877 int argc
, char *argv
[])
1879 return wpa_cli_cmd(ctrl
, "P2P_INVITE", 1, argc
, argv
);
1883 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1885 return wpa_cli_cmd(ctrl
, "P2P_PEER", 1, argc
, argv
);
1889 static char ** wpa_cli_complete_p2p_peer(const char *str
, int pos
)
1891 int arg
= get_cmd_arg_num(str
, pos
);
1896 res
= cli_txt_list_array(&p2p_peers
);
1904 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl
*ctrl
, char *cmd
,
1905 char *addr
, size_t addr_len
,
1908 char buf
[4096], *pos
;
1912 if (ctrl_conn
== NULL
)
1914 len
= sizeof(buf
) - 1;
1915 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
1918 printf("'%s' command timed out.\n", cmd
);
1920 } else if (ret
< 0) {
1921 printf("'%s' command failed.\n", cmd
);
1926 if (os_memcmp(buf
, "FAIL", 4) == 0)
1930 while (*pos
!= '\0' && *pos
!= '\n')
1933 os_strlcpy(addr
, buf
, addr_len
);
1934 if (!discovered
|| os_strstr(pos
, "[PROBE_REQ_ONLY]") == NULL
)
1935 printf("%s\n", addr
);
1940 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1942 char addr
[32], cmd
[64];
1945 discovered
= argc
> 0 && os_strcmp(argv
[0], "discovered") == 0;
1947 if (wpa_ctrl_command_p2p_peer(ctrl
, "P2P_PEER FIRST",
1948 addr
, sizeof(addr
), discovered
))
1951 os_snprintf(cmd
, sizeof(cmd
), "P2P_PEER NEXT-%s", addr
);
1952 } while (wpa_ctrl_command_p2p_peer(ctrl
, cmd
, addr
, sizeof(addr
),
1959 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1961 return wpa_cli_cmd(ctrl
, "P2P_SET", 2, argc
, argv
);
1965 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1967 return wpa_ctrl_command(ctrl
, "P2P_FLUSH");
1971 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl
*ctrl
, int argc
,
1974 return wpa_ctrl_command(ctrl
, "P2P_CANCEL");
1978 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl
*ctrl
, int argc
,
1981 return wpa_cli_cmd(ctrl
, "P2P_UNAUTHORIZE", 1, argc
, argv
);
1985 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl
*ctrl
, int argc
,
1988 if (argc
!= 0 && argc
!= 2 && argc
!= 4) {
1989 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
1990 "(preferred duration, interval; in microsecods).\n"
1991 "Optional second pair can be used to provide "
1992 "acceptable values.\n");
1996 return wpa_cli_cmd(ctrl
, "P2P_PRESENCE_REQ", 0, argc
, argv
);
2000 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl
*ctrl
, int argc
,
2003 if (argc
!= 0 && argc
!= 2) {
2004 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2005 "(availability period, availability interval; in "
2007 "Extended Listen Timing can be cancelled with this "
2008 "command when used without parameters.\n");
2012 return wpa_cli_cmd(ctrl
, "P2P_EXT_LISTEN", 0, argc
, argv
);
2015 #endif /* CONFIG_P2P */
2018 #ifdef CONFIG_INTERWORKING
2019 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2022 return wpa_ctrl_command(ctrl
, "FETCH_ANQP");
2026 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2029 return wpa_ctrl_command(ctrl
, "STOP_FETCH_ANQP");
2033 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl
*ctrl
, int argc
,
2036 return wpa_cli_cmd(ctrl
, "INTERWORKING_SELECT", 0, argc
, argv
);
2040 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl
*ctrl
, int argc
,
2043 return wpa_cli_cmd(ctrl
, "INTERWORKING_CONNECT", 1, argc
, argv
);
2047 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2049 return wpa_cli_cmd(ctrl
, "ANQP_GET", 2, argc
, argv
);
2053 static int wpa_cli_cmd_gas_request(struct wpa_ctrl
*ctrl
, int argc
,
2056 return wpa_cli_cmd(ctrl
, "GAS_REQUEST", 2, argc
, argv
);
2060 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl
*ctrl
, int argc
,
2063 return wpa_cli_cmd(ctrl
, "GAS_RESPONSE_GET", 2, argc
, argv
);
2065 #endif /* CONFIG_INTERWORKING */
2070 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl
*ctrl
, int argc
,
2073 return wpa_cli_cmd(ctrl
, "HS20_ANQP_GET", 2, argc
, argv
);
2077 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl
*ctrl
, int argc
,
2083 printf("Command needs one or two arguments (dst mac addr and "
2084 "optional home realm)\n");
2088 if (write_cmd(cmd
, sizeof(cmd
), "HS20_GET_NAI_HOME_REALM_LIST",
2092 return wpa_ctrl_command(ctrl
, cmd
);
2095 #endif /* CONFIG_HS20 */
2098 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl
*ctrl
, int argc
,
2101 return wpa_cli_cmd(ctrl
, "STA_AUTOCONNECT", 1, argc
, argv
);
2105 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl
*ctrl
, int argc
,
2108 return wpa_cli_cmd(ctrl
, "TDLS_DISCOVER", 1, argc
, argv
);
2112 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl
*ctrl
, int argc
,
2115 return wpa_cli_cmd(ctrl
, "TDLS_SETUP", 1, argc
, argv
);
2119 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl
*ctrl
, int argc
,
2122 return wpa_cli_cmd(ctrl
, "TDLS_TEARDOWN", 1, argc
, argv
);
2126 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl
*ctrl
, int argc
,
2129 return wpa_ctrl_command(ctrl
, "SIGNAL_POLL");
2133 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
2136 return wpa_ctrl_command(ctrl
, "REAUTHENTICATE");
2140 #ifdef CONFIG_AUTOSCAN
2142 static int wpa_cli_cmd_autoscan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2145 return wpa_ctrl_command(ctrl
, "AUTOSCAN ");
2147 return wpa_cli_cmd(ctrl
, "AUTOSCAN", 0, argc
, argv
);
2150 #endif /* CONFIG_AUTOSCAN */
2153 static int wpa_cli_cmd_raw(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2157 return wpa_cli_cmd(ctrl
, argv
[0], 0, argc
- 1, &argv
[1]);
2161 enum wpa_cli_cmd_flags
{
2162 cli_cmd_flag_none
= 0x00,
2163 cli_cmd_flag_sensitive
= 0x01
2166 struct wpa_cli_cmd
{
2168 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
2169 char ** (*completion
)(const char *str
, int pos
);
2170 enum wpa_cli_cmd_flags flags
;
2174 static struct wpa_cli_cmd wpa_cli_commands
[] = {
2175 { "status", wpa_cli_cmd_status
, NULL
,
2177 "[verbose] = get current WPA/EAPOL/EAP status" },
2178 { "ifname", wpa_cli_cmd_ifname
, NULL
,
2180 "= get current interface name" },
2181 { "ping", wpa_cli_cmd_ping
, NULL
,
2183 "= pings wpa_supplicant" },
2184 { "relog", wpa_cli_cmd_relog
, NULL
,
2186 "= re-open log-file (allow rolling logs)" },
2187 { "note", wpa_cli_cmd_note
, NULL
,
2189 "<text> = add a note to wpa_supplicant debug log" },
2190 { "mib", wpa_cli_cmd_mib
, NULL
,
2192 "= get MIB variables (dot1x, dot11)" },
2193 { "help", wpa_cli_cmd_help
, wpa_cli_complete_help
,
2195 "[command] = show usage help" },
2196 { "interface", wpa_cli_cmd_interface
, NULL
,
2198 "[ifname] = show interfaces/select interface" },
2199 { "level", wpa_cli_cmd_level
, NULL
,
2201 "<debug level> = change debug level" },
2202 { "license", wpa_cli_cmd_license
, NULL
,
2204 "= show full wpa_cli license" },
2205 { "quit", wpa_cli_cmd_quit
, NULL
,
2208 { "set", wpa_cli_cmd_set
, NULL
,
2210 "= set variables (shows list of variables when run without "
2212 { "get", wpa_cli_cmd_get
, NULL
,
2214 "<name> = get information" },
2215 { "logon", wpa_cli_cmd_logon
, NULL
,
2217 "= IEEE 802.1X EAPOL state machine logon" },
2218 { "logoff", wpa_cli_cmd_logoff
, NULL
,
2220 "= IEEE 802.1X EAPOL state machine logoff" },
2221 { "pmksa", wpa_cli_cmd_pmksa
, NULL
,
2223 "= show PMKSA cache" },
2224 { "reassociate", wpa_cli_cmd_reassociate
, NULL
,
2226 "= force reassociation" },
2227 { "preauthenticate", wpa_cli_cmd_preauthenticate
, wpa_cli_complete_bss
,
2229 "<BSSID> = force preauthentication" },
2230 { "identity", wpa_cli_cmd_identity
, NULL
,
2232 "<network id> <identity> = configure identity for an SSID" },
2233 { "password", wpa_cli_cmd_password
, NULL
,
2234 cli_cmd_flag_sensitive
,
2235 "<network id> <password> = configure password for an SSID" },
2236 { "new_password", wpa_cli_cmd_new_password
, NULL
,
2237 cli_cmd_flag_sensitive
,
2238 "<network id> <password> = change password for an SSID" },
2239 { "pin", wpa_cli_cmd_pin
, NULL
,
2240 cli_cmd_flag_sensitive
,
2241 "<network id> <pin> = configure pin for an SSID" },
2242 { "otp", wpa_cli_cmd_otp
, NULL
,
2243 cli_cmd_flag_sensitive
,
2244 "<network id> <password> = configure one-time-password for an SSID"
2246 { "passphrase", wpa_cli_cmd_passphrase
, NULL
,
2247 cli_cmd_flag_sensitive
,
2248 "<network id> <passphrase> = configure private key passphrase\n"
2250 { "bssid", wpa_cli_cmd_bssid
, NULL
,
2252 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2253 { "blacklist", wpa_cli_cmd_blacklist
, wpa_cli_complete_bss
,
2255 "<BSSID> = add a BSSID to the blacklist\n"
2256 "blacklist clear = clear the blacklist\n"
2257 "blacklist = display the blacklist" },
2258 { "log_level", wpa_cli_cmd_log_level
, NULL
,
2260 "<level> [<timestamp>] = update the log level/timestamp\n"
2261 "log_level = display the current log level and log options" },
2262 { "list_networks", wpa_cli_cmd_list_networks
, NULL
,
2264 "= list configured networks" },
2265 { "select_network", wpa_cli_cmd_select_network
, NULL
,
2267 "<network id> = select a network (disable others)" },
2268 { "enable_network", wpa_cli_cmd_enable_network
, NULL
,
2270 "<network id> = enable a network" },
2271 { "disable_network", wpa_cli_cmd_disable_network
, NULL
,
2273 "<network id> = disable a network" },
2274 { "add_network", wpa_cli_cmd_add_network
, NULL
,
2276 "= add a network" },
2277 { "remove_network", wpa_cli_cmd_remove_network
, NULL
,
2279 "<network id> = remove a network" },
2280 { "set_network", wpa_cli_cmd_set_network
, NULL
,
2281 cli_cmd_flag_sensitive
,
2282 "<network id> <variable> <value> = set network variables (shows\n"
2283 " list of variables when run without arguments)" },
2284 { "get_network", wpa_cli_cmd_get_network
, NULL
,
2286 "<network id> <variable> = get network variables" },
2287 { "list_creds", wpa_cli_cmd_list_creds
, NULL
,
2289 "= list configured credentials" },
2290 { "add_cred", wpa_cli_cmd_add_cred
, NULL
,
2292 "= add a credential" },
2293 { "remove_cred", wpa_cli_cmd_remove_cred
, NULL
,
2295 "<cred id> = remove a credential" },
2296 { "set_cred", wpa_cli_cmd_set_cred
, NULL
,
2297 cli_cmd_flag_sensitive
,
2298 "<cred id> <variable> <value> = set credential variables" },
2299 { "save_config", wpa_cli_cmd_save_config
, NULL
,
2301 "= save the current configuration" },
2302 { "disconnect", wpa_cli_cmd_disconnect
, NULL
,
2304 "= disconnect and wait for reassociate/reconnect command before\n"
2306 { "reconnect", wpa_cli_cmd_reconnect
, NULL
,
2308 "= like reassociate, but only takes effect if already disconnected"
2310 { "scan", wpa_cli_cmd_scan
, NULL
,
2312 "= request new BSS scan" },
2313 { "scan_results", wpa_cli_cmd_scan_results
, NULL
,
2315 "= get latest scan results" },
2316 { "bss", wpa_cli_cmd_bss
, wpa_cli_complete_bss
,
2318 "<<idx> | <bssid>> = get detailed scan result info" },
2319 { "get_capability", wpa_cli_cmd_get_capability
, NULL
,
2321 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels> "
2322 "= get capabilies" },
2323 { "reconfigure", wpa_cli_cmd_reconfigure
, NULL
,
2325 "= force wpa_supplicant to re-read its configuration file" },
2326 { "terminate", wpa_cli_cmd_terminate
, NULL
,
2328 "= terminate wpa_supplicant" },
2329 { "interface_add", wpa_cli_cmd_interface_add
, NULL
,
2331 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2332 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2334 { "interface_remove", wpa_cli_cmd_interface_remove
, NULL
,
2336 "<ifname> = removes the interface" },
2337 { "interface_list", wpa_cli_cmd_interface_list
, NULL
,
2339 "= list available interfaces" },
2340 { "ap_scan", wpa_cli_cmd_ap_scan
, NULL
,
2342 "<value> = set ap_scan parameter" },
2343 { "scan_interval", wpa_cli_cmd_scan_interval
, NULL
,
2345 "<value> = set scan_interval parameter (in seconds)" },
2346 { "bss_expire_age", wpa_cli_cmd_bss_expire_age
, NULL
,
2348 "<value> = set BSS expiration age parameter" },
2349 { "bss_expire_count", wpa_cli_cmd_bss_expire_count
, NULL
,
2351 "<value> = set BSS expiration scan count parameter" },
2352 { "bss_flush", wpa_cli_cmd_bss_flush
, NULL
,
2354 "<value> = set BSS flush age (0 by default)" },
2355 { "stkstart", wpa_cli_cmd_stkstart
, NULL
,
2357 "<addr> = request STK negotiation with <addr>" },
2358 { "ft_ds", wpa_cli_cmd_ft_ds
, wpa_cli_complete_bss
,
2360 "<addr> = request over-the-DS FT with <addr>" },
2361 { "wps_pbc", wpa_cli_cmd_wps_pbc
, wpa_cli_complete_bss
,
2363 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2364 { "wps_pin", wpa_cli_cmd_wps_pin
, wpa_cli_complete_bss
,
2365 cli_cmd_flag_sensitive
,
2366 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2368 { "wps_check_pin", wpa_cli_cmd_wps_check_pin
, NULL
,
2369 cli_cmd_flag_sensitive
,
2370 "<PIN> = verify PIN checksum" },
2371 { "wps_cancel", wpa_cli_cmd_wps_cancel
, NULL
, cli_cmd_flag_none
,
2372 "Cancels the pending WPS operation" },
2373 #ifdef CONFIG_WPS_OOB
2374 { "wps_oob", wpa_cli_cmd_wps_oob
, NULL
,
2375 cli_cmd_flag_sensitive
,
2376 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2377 #endif /* CONFIG_WPS_OOB */
2378 #ifdef CONFIG_WPS_NFC
2379 { "wps_nfc", wpa_cli_cmd_wps_nfc
, wpa_cli_complete_bss
,
2381 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
2382 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token
, NULL
,
2384 "<WPS|NDEF> = create password token" },
2385 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read
, NULL
,
2386 cli_cmd_flag_sensitive
,
2387 "<hexdump of payload> = report read NFC tag with WPS data" },
2388 #endif /* CONFIG_WPS_NFC */
2389 { "wps_reg", wpa_cli_cmd_wps_reg
, wpa_cli_complete_bss
,
2390 cli_cmd_flag_sensitive
,
2391 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2392 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin
, NULL
,
2393 cli_cmd_flag_sensitive
,
2394 "[params..] = enable/disable AP PIN" },
2395 { "wps_er_start", wpa_cli_cmd_wps_er_start
, NULL
,
2397 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2398 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
, NULL
,
2400 "= stop Wi-Fi Protected Setup External Registrar" },
2401 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
, NULL
,
2402 cli_cmd_flag_sensitive
,
2403 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2404 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
, NULL
,
2406 "<UUID> = accept an Enrollee PBC using External Registrar" },
2407 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
, NULL
,
2408 cli_cmd_flag_sensitive
,
2409 "<UUID> <PIN> = learn AP configuration" },
2410 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config
, NULL
,
2412 "<UUID> <network id> = set AP configuration for enrolling" },
2413 { "wps_er_config", wpa_cli_cmd_wps_er_config
, NULL
,
2414 cli_cmd_flag_sensitive
,
2415 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2416 #ifdef CONFIG_WPS_NFC
2417 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token
, NULL
,
2419 "<WPS/NDEF> <UUID> = build NFC configuration token" },
2420 #endif /* CONFIG_WPS_NFC */
2421 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
, NULL
,
2423 "<addr> = request RSN authentication with <addr> in IBSS" },
2425 { "sta", wpa_cli_cmd_sta
, NULL
,
2427 "<addr> = get information about an associated station (AP)" },
2428 { "all_sta", wpa_cli_cmd_all_sta
, NULL
,
2430 "= get information about all associated stations (AP)" },
2431 { "deauthenticate", wpa_cli_cmd_deauthenticate
, NULL
,
2433 "<addr> = deauthenticate a station" },
2434 { "disassociate", wpa_cli_cmd_disassociate
, NULL
,
2436 "<addr> = disassociate a station" },
2437 #endif /* CONFIG_AP */
2438 { "suspend", wpa_cli_cmd_suspend
, NULL
, cli_cmd_flag_none
,
2439 "= notification of suspend/hibernate" },
2440 { "resume", wpa_cli_cmd_resume
, NULL
, cli_cmd_flag_none
,
2441 "= notification of resume/thaw" },
2442 { "drop_sa", wpa_cli_cmd_drop_sa
, NULL
, cli_cmd_flag_none
,
2443 "= drop SA without deauth/disassoc (test command)" },
2444 { "roam", wpa_cli_cmd_roam
, wpa_cli_complete_bss
,
2446 "<addr> = roam to the specified BSS" },
2448 { "p2p_find", wpa_cli_cmd_p2p_find
, wpa_cli_complete_p2p_find
,
2450 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2451 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find
, NULL
, cli_cmd_flag_none
,
2452 "= stop P2P Devices search" },
2453 { "p2p_connect", wpa_cli_cmd_p2p_connect
, wpa_cli_complete_p2p_connect
,
2455 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
2456 { "p2p_listen", wpa_cli_cmd_p2p_listen
, NULL
, cli_cmd_flag_none
,
2457 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2458 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove
,
2459 wpa_cli_complete_p2p_group_remove
, cli_cmd_flag_none
,
2460 "<ifname> = remove P2P group interface (terminate group if GO)" },
2461 { "p2p_group_add", wpa_cli_cmd_p2p_group_add
, NULL
, cli_cmd_flag_none
,
2462 "[ht40] = add a new P2P group (local end as GO)" },
2463 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc
,
2464 wpa_cli_complete_p2p_peer
, cli_cmd_flag_none
,
2465 "<addr> <method> = request provisioning discovery" },
2466 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase
, NULL
,
2468 "= get the passphrase for a group (GO only)" },
2469 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req
,
2470 wpa_cli_complete_p2p_peer
, cli_cmd_flag_none
,
2471 "<addr> <TLVs> = schedule service discovery request" },
2472 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req
,
2473 NULL
, cli_cmd_flag_none
,
2474 "<id> = cancel pending service discovery request" },
2475 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp
, NULL
,
2477 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2478 { "p2p_service_update", wpa_cli_cmd_p2p_service_update
, NULL
,
2480 "= indicate change in local services" },
2481 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external
, NULL
,
2483 "<external> = set external processing of service discovery" },
2484 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush
, NULL
,
2486 "= remove all stored service entries" },
2487 { "p2p_service_add", wpa_cli_cmd_p2p_service_add
, NULL
,
2489 "<bonjour|upnp> <query|version> <response|service> = add a local "
2491 { "p2p_service_del", wpa_cli_cmd_p2p_service_del
, NULL
,
2493 "<bonjour|upnp> <query|version> [|service] = remove a local "
2495 { "p2p_reject", wpa_cli_cmd_p2p_reject
, wpa_cli_complete_p2p_peer
,
2497 "<addr> = reject connection attempts from a specific peer" },
2498 { "p2p_invite", wpa_cli_cmd_p2p_invite
, NULL
,
2500 "<cmd> [peer=addr] = invite peer" },
2501 { "p2p_peers", wpa_cli_cmd_p2p_peers
, NULL
, cli_cmd_flag_none
,
2502 "[discovered] = list known (optionally, only fully discovered) P2P "
2504 { "p2p_peer", wpa_cli_cmd_p2p_peer
, wpa_cli_complete_p2p_peer
,
2506 "<address> = show information about known P2P peer" },
2507 { "p2p_set", wpa_cli_cmd_p2p_set
, NULL
, cli_cmd_flag_none
,
2508 "<field> <value> = set a P2P parameter" },
2509 { "p2p_flush", wpa_cli_cmd_p2p_flush
, NULL
, cli_cmd_flag_none
,
2510 "= flush P2P state" },
2511 { "p2p_cancel", wpa_cli_cmd_p2p_cancel
, NULL
, cli_cmd_flag_none
,
2512 "= cancel P2P group formation" },
2513 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize
,
2514 wpa_cli_complete_p2p_peer
, cli_cmd_flag_none
,
2515 "<address> = unauthorize a peer" },
2516 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req
, NULL
,
2518 "[<duration> <interval>] [<duration> <interval>] = request GO "
2520 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen
, NULL
,
2522 "[<period> <interval>] = set extended listen timing" },
2523 #endif /* CONFIG_P2P */
2525 #ifdef CONFIG_INTERWORKING
2526 { "fetch_anqp", wpa_cli_cmd_fetch_anqp
, NULL
, cli_cmd_flag_none
,
2527 "= fetch ANQP information for all APs" },
2528 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp
, NULL
,
2530 "= stop fetch_anqp operation" },
2531 { "interworking_select", wpa_cli_cmd_interworking_select
, NULL
,
2533 "[auto] = perform Interworking network selection" },
2534 { "interworking_connect", wpa_cli_cmd_interworking_connect
,
2535 wpa_cli_complete_bss
, cli_cmd_flag_none
,
2536 "<BSSID> = connect using Interworking credentials" },
2537 { "anqp_get", wpa_cli_cmd_anqp_get
, wpa_cli_complete_bss
,
2539 "<addr> <info id>[,<info id>]... = request ANQP information" },
2540 { "gas_request", wpa_cli_cmd_gas_request
, wpa_cli_complete_bss
,
2542 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
2543 { "gas_response_get", wpa_cli_cmd_gas_response_get
,
2544 wpa_cli_complete_bss
, cli_cmd_flag_none
,
2545 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
2546 #endif /* CONFIG_INTERWORKING */
2548 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get
, wpa_cli_complete_bss
,
2550 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
2552 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list
,
2553 wpa_cli_complete_bss
, cli_cmd_flag_none
,
2554 "<addr> <home realm> = get HS20 nai home realm list" },
2555 #endif /* CONFIG_HS20 */
2556 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect
, NULL
,
2558 "<0/1> = disable/enable automatic reconnection" },
2559 { "tdls_discover", wpa_cli_cmd_tdls_discover
, NULL
,
2561 "<addr> = request TDLS discovery with <addr>" },
2562 { "tdls_setup", wpa_cli_cmd_tdls_setup
, NULL
,
2564 "<addr> = request TDLS setup with <addr>" },
2565 { "tdls_teardown", wpa_cli_cmd_tdls_teardown
, NULL
,
2567 "<addr> = tear down TDLS with <addr>" },
2568 { "signal_poll", wpa_cli_cmd_signal_poll
, NULL
,
2570 "= get signal parameters" },
2571 { "reauthenticate", wpa_cli_cmd_reauthenticate
, NULL
,
2573 "= trigger IEEE 802.1X/EAPOL reauthentication" },
2574 #ifdef CONFIG_AUTOSCAN
2575 { "autoscan", wpa_cli_cmd_autoscan
, NULL
, cli_cmd_flag_none
,
2576 "[params] = Set or unset (if none) autoscan parameters" },
2577 #endif /* CONFIG_AUTOSCAN */
2578 { "raw", wpa_cli_cmd_raw
, NULL
, cli_cmd_flag_sensitive
,
2579 "<params..> = Sent unprocessed command" },
2580 { NULL
, NULL
, NULL
, cli_cmd_flag_none
, NULL
}
2585 * Prints command usage, lines are padded with the specified string.
2587 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
2592 printf("%s%s ", pad
, cmd
->cmd
);
2593 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
2602 static void print_help(const char *cmd
)
2605 printf("commands:\n");
2606 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++) {
2607 if (cmd
== NULL
|| str_starts(wpa_cli_commands
[n
].cmd
, cmd
))
2608 print_cmd_help(&wpa_cli_commands
[n
], " ");
2613 static int wpa_cli_edit_filter_history_cb(void *ctx
, const char *cmd
)
2615 const char *c
, *delim
;
2619 delim
= os_strchr(cmd
, ' ');
2623 len
= os_strlen(cmd
);
2625 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
2626 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
2627 return (wpa_cli_commands
[n
].flags
&
2628 cli_cmd_flag_sensitive
);
2634 static char ** wpa_list_cmd_list(void)
2639 count
= sizeof(wpa_cli_commands
) / sizeof(wpa_cli_commands
[0]);
2640 res
= os_calloc(count
, sizeof(char *));
2644 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2645 res
[i
] = os_strdup(wpa_cli_commands
[i
].cmd
);
2654 static char ** wpa_cli_cmd_completion(const char *cmd
, const char *str
,
2659 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2660 if (os_strcasecmp(wpa_cli_commands
[i
].cmd
, cmd
) == 0) {
2661 if (wpa_cli_commands
[i
].completion
)
2662 return wpa_cli_commands
[i
].completion(str
,
2665 printf("\r%s\n", wpa_cli_commands
[i
].usage
);
2675 static char ** wpa_cli_edit_completion_cb(void *ctx
, const char *str
, int pos
)
2681 end
= os_strchr(str
, ' ');
2682 if (end
== NULL
|| str
+ pos
< end
)
2683 return wpa_list_cmd_list();
2685 cmd
= os_malloc(pos
+ 1);
2688 os_memcpy(cmd
, str
, pos
);
2689 cmd
[end
- str
] = '\0';
2690 res
= wpa_cli_cmd_completion(cmd
, str
, pos
);
2696 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2698 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
2703 cmd
= wpa_cli_commands
;
2705 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
2708 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
2709 /* we have an exact match */
2719 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
2720 cmd
= wpa_cli_commands
;
2722 if (os_strncasecmp(cmd
->cmd
, argv
[0],
2723 os_strlen(argv
[0])) == 0) {
2724 printf(" %s", cmd
->cmd
);
2730 } else if (count
== 0) {
2731 printf("Unknown command '%s'\n", argv
[0]);
2734 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
2741 static int str_match(const char *a
, const char *b
)
2743 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
2747 static int wpa_cli_exec(const char *program
, const char *arg1
,
2755 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
2756 cmd
= os_malloc(len
);
2759 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
2760 if (res
< 0 || (size_t) res
>= len
) {
2764 cmd
[len
- 1] = '\0';
2766 if (system(cmd
) < 0)
2768 #endif /* _WIN32_WCE */
2775 static void wpa_cli_action_process(const char *msg
)
2778 char *copy
= NULL
, *id
, *pos2
;
2783 pos
= os_strchr(pos
, '>');
2790 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
2792 os_unsetenv("WPA_ID");
2793 os_unsetenv("WPA_ID_STR");
2794 os_unsetenv("WPA_CTRL_DIR");
2796 pos
= os_strstr(pos
, "[id=");
2798 copy
= os_strdup(pos
+ 4);
2802 while (*pos2
&& *pos2
!= ' ')
2806 os_setenv("WPA_ID", id
, 1);
2807 while (*pos2
&& *pos2
!= '=')
2812 while (*pos2
&& *pos2
!= ']')
2815 os_setenv("WPA_ID_STR", id
, 1);
2819 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
2821 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
2822 wpa_cli_connected
= 1;
2823 wpa_cli_last_id
= new_id
;
2824 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
2826 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
2827 if (wpa_cli_connected
) {
2828 wpa_cli_connected
= 0;
2829 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
2831 } else if (str_match(pos
, P2P_EVENT_GROUP_STARTED
)) {
2832 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2833 } else if (str_match(pos
, P2P_EVENT_GROUP_REMOVED
)) {
2834 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2835 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_ENABLE
)) {
2836 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2837 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_DISABLE
)) {
2838 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2839 } else if (str_match(pos
, P2P_EVENT_GO_NEG_FAILURE
)) {
2840 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2841 } else if (str_match(pos
, WPS_EVENT_SUCCESS
)) {
2842 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2843 } else if (str_match(pos
, WPS_EVENT_FAIL
)) {
2844 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2845 } else if (str_match(pos
, AP_STA_CONNECTED
)) {
2846 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2847 } else if (str_match(pos
, AP_STA_DISCONNECTED
)) {
2848 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2849 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
2850 printf("wpa_supplicant is terminating - stop monitoring\n");
2856 #ifndef CONFIG_ANSI_C_EXTRA
2857 static void wpa_cli_action_cb(char *msg
, size_t len
)
2859 wpa_cli_action_process(msg
);
2861 #endif /* CONFIG_ANSI_C_EXTRA */
2864 static void wpa_cli_reconnect(void)
2866 wpa_cli_close_connection();
2867 if (wpa_cli_open_connection(ctrl_ifname
, 1) < 0)
2872 printf("\rConnection to wpa_supplicant re-established\n");
2878 static void cli_event(const char *str
)
2880 const char *start
, *s
;
2882 start
= os_strchr(str
, '>');
2888 if (str_starts(start
, WPA_EVENT_BSS_ADDED
)) {
2889 s
= os_strchr(start
, ' ');
2892 s
= os_strchr(s
+ 1, ' ');
2895 cli_txt_list_add(&bsses
, s
+ 1);
2899 if (str_starts(start
, WPA_EVENT_BSS_REMOVED
)) {
2900 s
= os_strchr(start
, ' ');
2903 s
= os_strchr(s
+ 1, ' ');
2906 cli_txt_list_del_addr(&bsses
, s
+ 1);
2911 if (str_starts(start
, P2P_EVENT_DEVICE_FOUND
)) {
2912 s
= os_strstr(start
, " p2p_dev_addr=");
2915 cli_txt_list_add_addr(&p2p_peers
, s
+ 14);
2919 if (str_starts(start
, P2P_EVENT_DEVICE_LOST
)) {
2920 s
= os_strstr(start
, " p2p_dev_addr=");
2923 cli_txt_list_del_addr(&p2p_peers
, s
+ 14);
2927 if (str_starts(start
, P2P_EVENT_GROUP_STARTED
)) {
2928 s
= os_strchr(start
, ' ');
2931 cli_txt_list_add_word(&p2p_groups
, s
+ 1);
2935 if (str_starts(start
, P2P_EVENT_GROUP_REMOVED
)) {
2936 s
= os_strchr(start
, ' ');
2939 cli_txt_list_del_word(&p2p_groups
, s
+ 1);
2942 #endif /* CONFIG_P2P */
2946 static int check_terminating(const char *msg
)
2948 const char *pos
= msg
;
2952 pos
= os_strchr(pos
, '>');
2959 if (str_match(pos
, WPA_EVENT_TERMINATING
) && ctrl_conn
) {
2961 printf("\rConnection to wpa_supplicant lost - trying to "
2964 wpa_cli_attached
= 0;
2965 wpa_cli_close_connection();
2973 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int action_monitor
)
2975 if (ctrl_conn
== NULL
) {
2976 wpa_cli_reconnect();
2979 while (wpa_ctrl_pending(ctrl
) > 0) {
2981 size_t len
= sizeof(buf
) - 1;
2982 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
2985 wpa_cli_action_process(buf
);
2988 if (wpa_cli_show_event(buf
)) {
2990 printf("\r%s\n", buf
);
2994 if (interactive
&& check_terminating(buf
) > 0)
2998 printf("Could not read pending message.\n");
3003 if (wpa_ctrl_pending(ctrl
) < 0) {
3004 printf("Connection to wpa_supplicant lost - trying to "
3006 wpa_cli_reconnect();
3012 static int tokenize_cmd(char *cmd
, char *argv
[])
3025 if (argc
== max_args
)
3028 char *pos2
= os_strrchr(pos
, '"');
3032 while (*pos
!= '\0' && *pos
!= ' ')
3042 static void wpa_cli_ping(void *eloop_ctx
, void *timeout_ctx
)
3044 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
3045 printf("Connection to wpa_supplicant lost - trying to "
3047 wpa_cli_close_connection();
3050 wpa_cli_reconnect();
3051 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3055 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
)
3057 wpa_cli_recv_pending(mon_conn
, 0);
3061 static void wpa_cli_edit_cmd_cb(void *ctx
, char *cmd
)
3063 char *argv
[max_args
];
3065 argc
= tokenize_cmd(cmd
, argv
);
3067 wpa_request(ctrl_conn
, argc
, argv
);
3071 static void wpa_cli_edit_eof_cb(void *ctx
)
3077 static int warning_displayed
= 0;
3078 static char *hfile
= NULL
;
3079 static int edit_started
= 0;
3081 static void start_edit(void)
3086 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3087 ps
= wpa_ctrl_get_remote_ifname(ctrl_conn
);
3088 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3090 home
= getenv("HOME");
3092 const char *fname
= ".wpa_cli_history";
3093 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
3094 hfile
= os_malloc(hfile_len
);
3096 os_snprintf(hfile
, hfile_len
, "%s/%s", home
, fname
);
3099 if (edit_init(wpa_cli_edit_cmd_cb
, wpa_cli_edit_eof_cb
,
3100 wpa_cli_edit_completion_cb
, NULL
, hfile
, ps
) < 0) {
3106 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3110 static void try_connection(void *eloop_ctx
, void *timeout_ctx
)
3112 if (ctrl_ifname
== NULL
)
3113 ctrl_ifname
= wpa_cli_get_default_ifname();
3115 if (!wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
3116 if (!warning_displayed
) {
3117 printf("Could not connect to wpa_supplicant: "
3118 "%s - re-trying\n", ctrl_ifname
);
3119 warning_displayed
= 1;
3121 eloop_register_timeout(1, 0, try_connection
, NULL
, NULL
);
3125 if (warning_displayed
)
3126 printf("Connection established.\n");
3132 static void wpa_cli_interactive(void)
3134 printf("\nInteractive mode\n\n");
3136 eloop_register_timeout(0, 0, try_connection
, NULL
, NULL
);
3138 eloop_cancel_timeout(try_connection
, NULL
, NULL
);
3140 cli_txt_list_flush(&p2p_peers
);
3141 cli_txt_list_flush(&p2p_groups
);
3142 cli_txt_list_flush(&bsses
);
3144 edit_deinit(hfile
, wpa_cli_edit_filter_history_cb
);
3146 eloop_cancel_timeout(wpa_cli_ping
, NULL
, NULL
);
3147 wpa_cli_close_connection();
3151 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
3153 #ifdef CONFIG_ANSI_C_EXTRA
3154 /* TODO: ANSI C version(?) */
3155 printf("Action processing not supported in ANSI C build.\n");
3156 #else /* CONFIG_ANSI_C_EXTRA */
3160 char buf
[256]; /* note: large enough to fit in unsolicited messages */
3163 fd
= wpa_ctrl_get_fd(ctrl
);
3165 while (!wpa_cli_quit
) {
3168 tv
.tv_sec
= ping_interval
;
3170 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
3171 if (res
< 0 && errno
!= EINTR
) {
3176 if (FD_ISSET(fd
, &rfds
))
3177 wpa_cli_recv_pending(ctrl
, 1);
3179 /* verify that connection is still working */
3180 len
= sizeof(buf
) - 1;
3181 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
3182 wpa_cli_action_cb
) < 0 ||
3183 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
3184 printf("wpa_supplicant did not reply to PING "
3185 "command - exiting\n");
3190 #endif /* CONFIG_ANSI_C_EXTRA */
3194 static void wpa_cli_cleanup(void)
3196 wpa_cli_close_connection();
3198 os_daemonize_terminate(pid_file
);
3200 os_program_deinit();
3204 static void wpa_cli_terminate(int sig
, void *ctx
)
3210 static char * wpa_cli_get_default_ifname(void)
3212 char *ifname
= NULL
;
3214 #ifdef CONFIG_CTRL_IFACE_UNIX
3215 struct dirent
*dent
;
3216 DIR *dir
= opendir(ctrl_iface_dir
);
3219 char ifprop
[PROPERTY_VALUE_MAX
];
3220 if (property_get("wifi.interface", ifprop
, NULL
) != 0) {
3221 ifname
= os_strdup(ifprop
);
3222 printf("Using interface '%s'\n", ifname
);
3225 #endif /* ANDROID */
3228 while ((dent
= readdir(dir
))) {
3229 #ifdef _DIRENT_HAVE_D_TYPE
3231 * Skip the file if it is not a socket. Also accept
3232 * DT_UNKNOWN (0) in case the C library or underlying
3233 * file system does not support d_type.
3235 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
3237 #endif /* _DIRENT_HAVE_D_TYPE */
3238 if (os_strcmp(dent
->d_name
, ".") == 0 ||
3239 os_strcmp(dent
->d_name
, "..") == 0)
3241 printf("Selected interface '%s'\n", dent
->d_name
);
3242 ifname
= os_strdup(dent
->d_name
);
3246 #endif /* CONFIG_CTRL_IFACE_UNIX */
3248 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3249 char buf
[2048], *pos
;
3251 struct wpa_ctrl
*ctrl
;
3254 ctrl
= wpa_ctrl_open(NULL
);
3258 len
= sizeof(buf
) - 1;
3259 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
3262 pos
= os_strchr(buf
, '\n');
3265 ifname
= os_strdup(buf
);
3267 wpa_ctrl_close(ctrl
);
3268 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3274 int main(int argc
, char *argv
[])
3279 const char *global
= NULL
;
3281 if (os_program_init())
3285 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
3290 action_file
= optarg
;
3299 ping_interval
= atoi(optarg
);
3305 printf("%s\n", wpa_cli_version
);
3308 os_free(ctrl_ifname
);
3309 ctrl_ifname
= os_strdup(optarg
);
3312 ctrl_iface_dir
= optarg
;
3323 interactive
= (argc
== optind
) && (action_file
== NULL
);
3326 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
3332 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3333 ctrl_conn
= wpa_ctrl_open(NULL
);
3334 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3335 ctrl_conn
= wpa_ctrl_open(global
);
3336 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3337 if (ctrl_conn
== NULL
) {
3338 fprintf(stderr
, "Failed to connect to wpa_supplicant "
3339 "global interface: %s error: %s\n",
3340 global
, strerror(errno
));
3345 eloop_register_signal_terminate(wpa_cli_terminate
, NULL
);
3347 if (ctrl_ifname
== NULL
)
3348 ctrl_ifname
= wpa_cli_get_default_ifname();
3351 wpa_cli_interactive();
3354 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
3355 fprintf(stderr
, "Failed to connect to non-global "
3356 "ctrl_ifname: %s error: %s\n",
3357 ctrl_ifname
, strerror(errno
));
3362 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
3363 wpa_cli_attached
= 1;
3365 printf("Warning: Failed to attach to "
3366 "wpa_supplicant.\n");
3371 if (daemonize
&& os_daemonize(pid_file
))
3375 wpa_cli_action(ctrl_conn
);
3377 ret
= wpa_request(ctrl_conn
, argc
- optind
,
3381 os_free(ctrl_ifname
);
3388 #else /* CONFIG_CTRL_IFACE */
3389 int main(int argc
, char *argv
[])
3391 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3394 #endif /* CONFIG_CTRL_IFACE */