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 int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl
*ctrl
, int argc
,
1635 return wpa_ctrl_command(ctrl
, "P2P_STOP_FIND");
1639 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl
*ctrl
, int argc
,
1642 return wpa_cli_cmd(ctrl
, "P2P_CONNECT", 2, argc
, argv
);
1646 static char ** wpa_cli_complete_p2p_connect(const char *str
, int pos
)
1648 int arg
= get_cmd_arg_num(str
, pos
);
1653 res
= cli_txt_list_array(&p2p_peers
);
1661 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl
*ctrl
, int argc
,
1664 return wpa_cli_cmd(ctrl
, "P2P_LISTEN", 0, argc
, argv
);
1668 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl
*ctrl
, int argc
,
1671 return wpa_cli_cmd(ctrl
, "P2P_GROUP_REMOVE", 1, argc
, argv
);
1675 static char ** wpa_cli_complete_p2p_group_remove(const char *str
, int pos
)
1677 int arg
= get_cmd_arg_num(str
, pos
);
1682 res
= cli_txt_list_array(&p2p_groups
);
1690 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl
*ctrl
, int argc
,
1693 return wpa_cli_cmd(ctrl
, "P2P_GROUP_ADD", 0, argc
, argv
);
1697 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl
*ctrl
, int argc
,
1700 if (argc
!= 2 && argc
!= 3) {
1701 printf("Invalid P2P_PROV_DISC command: needs at least "
1702 "two arguments, address and config method\n"
1703 "(display, keypad, or pbc) and an optional join\n");
1707 return wpa_cli_cmd(ctrl
, "P2P_PROV_DISC", 2, argc
, argv
);
1711 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl
*ctrl
, int argc
,
1714 return wpa_ctrl_command(ctrl
, "P2P_GET_PASSPHRASE");
1718 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl
*ctrl
, int argc
,
1723 if (argc
!= 2 && argc
!= 4) {
1724 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1725 "arguments (address and TLVs) or four arguments "
1726 "(address, \"upnp\", version, search target "
1731 if (write_cmd(cmd
, sizeof(cmd
), "P2P_SERV_DISC_REQ", argc
, argv
) < 0)
1733 return wpa_ctrl_command(ctrl
, cmd
);
1737 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl
*ctrl
,
1738 int argc
, char *argv
[])
1740 return wpa_cli_cmd(ctrl
, "P2P_SERV_DISC_CANCEL_REQ", 1, argc
, argv
);
1744 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl
*ctrl
, int argc
,
1751 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1752 "arguments (freq, address, dialog token, and TLVs)\n");
1756 res
= os_snprintf(cmd
, sizeof(cmd
), "P2P_SERV_DISC_RESP %s %s %s %s",
1757 argv
[0], argv
[1], argv
[2], argv
[3]);
1758 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1760 cmd
[sizeof(cmd
) - 1] = '\0';
1761 return wpa_ctrl_command(ctrl
, cmd
);
1765 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl
*ctrl
, int argc
,
1768 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_UPDATE");
1772 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl
*ctrl
,
1773 int argc
, char *argv
[])
1775 return wpa_cli_cmd(ctrl
, "P2P_SERV_DISC_EXTERNAL", 1, argc
, argv
);
1779 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl
*ctrl
, int argc
,
1782 return wpa_ctrl_command(ctrl
, "P2P_SERVICE_FLUSH");
1786 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl
*ctrl
, int argc
,
1792 if (argc
!= 3 && argc
!= 4) {
1793 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1799 res
= os_snprintf(cmd
, sizeof(cmd
),
1800 "P2P_SERVICE_ADD %s %s %s %s",
1801 argv
[0], argv
[1], argv
[2], argv
[3]);
1803 res
= os_snprintf(cmd
, sizeof(cmd
),
1804 "P2P_SERVICE_ADD %s %s %s",
1805 argv
[0], argv
[1], argv
[2]);
1806 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1808 cmd
[sizeof(cmd
) - 1] = '\0';
1809 return wpa_ctrl_command(ctrl
, cmd
);
1813 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl
*ctrl
, int argc
,
1819 if (argc
!= 2 && argc
!= 3) {
1820 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1826 res
= os_snprintf(cmd
, sizeof(cmd
),
1827 "P2P_SERVICE_DEL %s %s %s",
1828 argv
[0], argv
[1], argv
[2]);
1830 res
= os_snprintf(cmd
, sizeof(cmd
),
1831 "P2P_SERVICE_DEL %s %s",
1833 if (res
< 0 || (size_t) res
>= sizeof(cmd
))
1835 cmd
[sizeof(cmd
) - 1] = '\0';
1836 return wpa_ctrl_command(ctrl
, cmd
);
1840 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl
*ctrl
,
1841 int argc
, char *argv
[])
1843 return wpa_cli_cmd(ctrl
, "P2P_REJECT", 1, argc
, argv
);
1847 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl
*ctrl
,
1848 int argc
, char *argv
[])
1850 return wpa_cli_cmd(ctrl
, "P2P_INVITE", 1, argc
, argv
);
1854 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1856 return wpa_cli_cmd(ctrl
, "P2P_PEER", 1, argc
, argv
);
1860 static char ** wpa_cli_complete_p2p_peer(const char *str
, int pos
)
1862 int arg
= get_cmd_arg_num(str
, pos
);
1867 res
= cli_txt_list_array(&p2p_peers
);
1875 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl
*ctrl
, char *cmd
,
1876 char *addr
, size_t addr_len
,
1879 char buf
[4096], *pos
;
1883 if (ctrl_conn
== NULL
)
1885 len
= sizeof(buf
) - 1;
1886 ret
= wpa_ctrl_request(ctrl
, cmd
, os_strlen(cmd
), buf
, &len
,
1889 printf("'%s' command timed out.\n", cmd
);
1891 } else if (ret
< 0) {
1892 printf("'%s' command failed.\n", cmd
);
1897 if (os_memcmp(buf
, "FAIL", 4) == 0)
1901 while (*pos
!= '\0' && *pos
!= '\n')
1904 os_strlcpy(addr
, buf
, addr_len
);
1905 if (!discovered
|| os_strstr(pos
, "[PROBE_REQ_ONLY]") == NULL
)
1906 printf("%s\n", addr
);
1911 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1913 char addr
[32], cmd
[64];
1916 discovered
= argc
> 0 && os_strcmp(argv
[0], "discovered") == 0;
1918 if (wpa_ctrl_command_p2p_peer(ctrl
, "P2P_PEER FIRST",
1919 addr
, sizeof(addr
), discovered
))
1922 os_snprintf(cmd
, sizeof(cmd
), "P2P_PEER NEXT-%s", addr
);
1923 } while (wpa_ctrl_command_p2p_peer(ctrl
, cmd
, addr
, sizeof(addr
),
1930 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1932 return wpa_cli_cmd(ctrl
, "P2P_SET", 2, argc
, argv
);
1936 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
1938 return wpa_ctrl_command(ctrl
, "P2P_FLUSH");
1942 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl
*ctrl
, int argc
,
1945 return wpa_ctrl_command(ctrl
, "P2P_CANCEL");
1949 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl
*ctrl
, int argc
,
1952 return wpa_cli_cmd(ctrl
, "P2P_UNAUTHORIZE", 1, argc
, argv
);
1956 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl
*ctrl
, int argc
,
1959 if (argc
!= 0 && argc
!= 2 && argc
!= 4) {
1960 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
1961 "(preferred duration, interval; in microsecods).\n"
1962 "Optional second pair can be used to provide "
1963 "acceptable values.\n");
1967 return wpa_cli_cmd(ctrl
, "P2P_PRESENCE_REQ", 0, argc
, argv
);
1971 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl
*ctrl
, int argc
,
1974 if (argc
!= 0 && argc
!= 2) {
1975 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
1976 "(availability period, availability interval; in "
1978 "Extended Listen Timing can be cancelled with this "
1979 "command when used without parameters.\n");
1983 return wpa_cli_cmd(ctrl
, "P2P_EXT_LISTEN", 0, argc
, argv
);
1986 #endif /* CONFIG_P2P */
1989 #ifdef CONFIG_INTERWORKING
1990 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
1993 return wpa_ctrl_command(ctrl
, "FETCH_ANQP");
1997 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl
*ctrl
, int argc
,
2000 return wpa_ctrl_command(ctrl
, "STOP_FETCH_ANQP");
2004 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl
*ctrl
, int argc
,
2007 return wpa_cli_cmd(ctrl
, "INTERWORKING_SELECT", 0, argc
, argv
);
2011 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl
*ctrl
, int argc
,
2014 return wpa_cli_cmd(ctrl
, "INTERWORKING_CONNECT", 1, argc
, argv
);
2018 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2020 return wpa_cli_cmd(ctrl
, "ANQP_GET", 2, argc
, argv
);
2024 static int wpa_cli_cmd_gas_request(struct wpa_ctrl
*ctrl
, int argc
,
2027 return wpa_cli_cmd(ctrl
, "GAS_REQUEST", 2, argc
, argv
);
2031 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl
*ctrl
, int argc
,
2034 return wpa_cli_cmd(ctrl
, "GAS_RESPONSE_GET", 2, argc
, argv
);
2036 #endif /* CONFIG_INTERWORKING */
2041 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl
*ctrl
, int argc
,
2044 return wpa_cli_cmd(ctrl
, "HS20_ANQP_GET", 2, argc
, argv
);
2048 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl
*ctrl
, int argc
,
2054 printf("Command needs one or two arguments (dst mac addr and "
2055 "optional home realm)\n");
2059 if (write_cmd(cmd
, sizeof(cmd
), "HS20_GET_NAI_HOME_REALM_LIST",
2063 return wpa_ctrl_command(ctrl
, cmd
);
2066 #endif /* CONFIG_HS20 */
2069 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl
*ctrl
, int argc
,
2072 return wpa_cli_cmd(ctrl
, "STA_AUTOCONNECT", 1, argc
, argv
);
2076 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl
*ctrl
, int argc
,
2079 return wpa_cli_cmd(ctrl
, "TDLS_DISCOVER", 1, argc
, argv
);
2083 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl
*ctrl
, int argc
,
2086 return wpa_cli_cmd(ctrl
, "TDLS_SETUP", 1, argc
, argv
);
2090 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl
*ctrl
, int argc
,
2093 return wpa_cli_cmd(ctrl
, "TDLS_TEARDOWN", 1, argc
, argv
);
2097 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl
*ctrl
, int argc
,
2100 return wpa_ctrl_command(ctrl
, "SIGNAL_POLL");
2104 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl
*ctrl
, int argc
,
2107 return wpa_ctrl_command(ctrl
, "REAUTHENTICATE");
2111 #ifdef CONFIG_AUTOSCAN
2113 static int wpa_cli_cmd_autoscan(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2116 return wpa_ctrl_command(ctrl
, "AUTOSCAN ");
2118 return wpa_cli_cmd(ctrl
, "AUTOSCAN", 0, argc
, argv
);
2121 #endif /* CONFIG_AUTOSCAN */
2124 static int wpa_cli_cmd_raw(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2128 return wpa_cli_cmd(ctrl
, argv
[0], 0, argc
- 1, &argv
[1]);
2132 enum wpa_cli_cmd_flags
{
2133 cli_cmd_flag_none
= 0x00,
2134 cli_cmd_flag_sensitive
= 0x01
2137 struct wpa_cli_cmd
{
2139 int (*handler
)(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[]);
2140 char ** (*completion
)(const char *str
, int pos
);
2141 enum wpa_cli_cmd_flags flags
;
2145 static struct wpa_cli_cmd wpa_cli_commands
[] = {
2146 { "status", wpa_cli_cmd_status
, NULL
,
2148 "[verbose] = get current WPA/EAPOL/EAP status" },
2149 { "ifname", wpa_cli_cmd_ifname
, NULL
,
2151 "= get current interface name" },
2152 { "ping", wpa_cli_cmd_ping
, NULL
,
2154 "= pings wpa_supplicant" },
2155 { "relog", wpa_cli_cmd_relog
, NULL
,
2157 "= re-open log-file (allow rolling logs)" },
2158 { "note", wpa_cli_cmd_note
, NULL
,
2160 "<text> = add a note to wpa_supplicant debug log" },
2161 { "mib", wpa_cli_cmd_mib
, NULL
,
2163 "= get MIB variables (dot1x, dot11)" },
2164 { "help", wpa_cli_cmd_help
, wpa_cli_complete_help
,
2166 "[command] = show usage help" },
2167 { "interface", wpa_cli_cmd_interface
, NULL
,
2169 "[ifname] = show interfaces/select interface" },
2170 { "level", wpa_cli_cmd_level
, NULL
,
2172 "<debug level> = change debug level" },
2173 { "license", wpa_cli_cmd_license
, NULL
,
2175 "= show full wpa_cli license" },
2176 { "quit", wpa_cli_cmd_quit
, NULL
,
2179 { "set", wpa_cli_cmd_set
, NULL
,
2181 "= set variables (shows list of variables when run without "
2183 { "get", wpa_cli_cmd_get
, NULL
,
2185 "<name> = get information" },
2186 { "logon", wpa_cli_cmd_logon
, NULL
,
2188 "= IEEE 802.1X EAPOL state machine logon" },
2189 { "logoff", wpa_cli_cmd_logoff
, NULL
,
2191 "= IEEE 802.1X EAPOL state machine logoff" },
2192 { "pmksa", wpa_cli_cmd_pmksa
, NULL
,
2194 "= show PMKSA cache" },
2195 { "reassociate", wpa_cli_cmd_reassociate
, NULL
,
2197 "= force reassociation" },
2198 { "preauthenticate", wpa_cli_cmd_preauthenticate
, wpa_cli_complete_bss
,
2200 "<BSSID> = force preauthentication" },
2201 { "identity", wpa_cli_cmd_identity
, NULL
,
2203 "<network id> <identity> = configure identity for an SSID" },
2204 { "password", wpa_cli_cmd_password
, NULL
,
2205 cli_cmd_flag_sensitive
,
2206 "<network id> <password> = configure password for an SSID" },
2207 { "new_password", wpa_cli_cmd_new_password
, NULL
,
2208 cli_cmd_flag_sensitive
,
2209 "<network id> <password> = change password for an SSID" },
2210 { "pin", wpa_cli_cmd_pin
, NULL
,
2211 cli_cmd_flag_sensitive
,
2212 "<network id> <pin> = configure pin for an SSID" },
2213 { "otp", wpa_cli_cmd_otp
, NULL
,
2214 cli_cmd_flag_sensitive
,
2215 "<network id> <password> = configure one-time-password for an SSID"
2217 { "passphrase", wpa_cli_cmd_passphrase
, NULL
,
2218 cli_cmd_flag_sensitive
,
2219 "<network id> <passphrase> = configure private key passphrase\n"
2221 { "bssid", wpa_cli_cmd_bssid
, NULL
,
2223 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2224 { "blacklist", wpa_cli_cmd_blacklist
, wpa_cli_complete_bss
,
2226 "<BSSID> = add a BSSID to the blacklist\n"
2227 "blacklist clear = clear the blacklist\n"
2228 "blacklist = display the blacklist" },
2229 { "log_level", wpa_cli_cmd_log_level
, NULL
,
2231 "<level> [<timestamp>] = update the log level/timestamp\n"
2232 "log_level = display the current log level and log options" },
2233 { "list_networks", wpa_cli_cmd_list_networks
, NULL
,
2235 "= list configured networks" },
2236 { "select_network", wpa_cli_cmd_select_network
, NULL
,
2238 "<network id> = select a network (disable others)" },
2239 { "enable_network", wpa_cli_cmd_enable_network
, NULL
,
2241 "<network id> = enable a network" },
2242 { "disable_network", wpa_cli_cmd_disable_network
, NULL
,
2244 "<network id> = disable a network" },
2245 { "add_network", wpa_cli_cmd_add_network
, NULL
,
2247 "= add a network" },
2248 { "remove_network", wpa_cli_cmd_remove_network
, NULL
,
2250 "<network id> = remove a network" },
2251 { "set_network", wpa_cli_cmd_set_network
, NULL
,
2252 cli_cmd_flag_sensitive
,
2253 "<network id> <variable> <value> = set network variables (shows\n"
2254 " list of variables when run without arguments)" },
2255 { "get_network", wpa_cli_cmd_get_network
, NULL
,
2257 "<network id> <variable> = get network variables" },
2258 { "list_creds", wpa_cli_cmd_list_creds
, NULL
,
2260 "= list configured credentials" },
2261 { "add_cred", wpa_cli_cmd_add_cred
, NULL
,
2263 "= add a credential" },
2264 { "remove_cred", wpa_cli_cmd_remove_cred
, NULL
,
2266 "<cred id> = remove a credential" },
2267 { "set_cred", wpa_cli_cmd_set_cred
, NULL
,
2268 cli_cmd_flag_sensitive
,
2269 "<cred id> <variable> <value> = set credential variables" },
2270 { "save_config", wpa_cli_cmd_save_config
, NULL
,
2272 "= save the current configuration" },
2273 { "disconnect", wpa_cli_cmd_disconnect
, NULL
,
2275 "= disconnect and wait for reassociate/reconnect command before\n"
2277 { "reconnect", wpa_cli_cmd_reconnect
, NULL
,
2279 "= like reassociate, but only takes effect if already disconnected"
2281 { "scan", wpa_cli_cmd_scan
, NULL
,
2283 "= request new BSS scan" },
2284 { "scan_results", wpa_cli_cmd_scan_results
, NULL
,
2286 "= get latest scan results" },
2287 { "bss", wpa_cli_cmd_bss
, wpa_cli_complete_bss
,
2289 "<<idx> | <bssid>> = get detailed scan result info" },
2290 { "get_capability", wpa_cli_cmd_get_capability
, NULL
,
2292 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels> "
2293 "= get capabilies" },
2294 { "reconfigure", wpa_cli_cmd_reconfigure
, NULL
,
2296 "= force wpa_supplicant to re-read its configuration file" },
2297 { "terminate", wpa_cli_cmd_terminate
, NULL
,
2299 "= terminate wpa_supplicant" },
2300 { "interface_add", wpa_cli_cmd_interface_add
, NULL
,
2302 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2303 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2305 { "interface_remove", wpa_cli_cmd_interface_remove
, NULL
,
2307 "<ifname> = removes the interface" },
2308 { "interface_list", wpa_cli_cmd_interface_list
, NULL
,
2310 "= list available interfaces" },
2311 { "ap_scan", wpa_cli_cmd_ap_scan
, NULL
,
2313 "<value> = set ap_scan parameter" },
2314 { "scan_interval", wpa_cli_cmd_scan_interval
, NULL
,
2316 "<value> = set scan_interval parameter (in seconds)" },
2317 { "bss_expire_age", wpa_cli_cmd_bss_expire_age
, NULL
,
2319 "<value> = set BSS expiration age parameter" },
2320 { "bss_expire_count", wpa_cli_cmd_bss_expire_count
, NULL
,
2322 "<value> = set BSS expiration scan count parameter" },
2323 { "bss_flush", wpa_cli_cmd_bss_flush
, NULL
,
2325 "<value> = set BSS flush age (0 by default)" },
2326 { "stkstart", wpa_cli_cmd_stkstart
, NULL
,
2328 "<addr> = request STK negotiation with <addr>" },
2329 { "ft_ds", wpa_cli_cmd_ft_ds
, wpa_cli_complete_bss
,
2331 "<addr> = request over-the-DS FT with <addr>" },
2332 { "wps_pbc", wpa_cli_cmd_wps_pbc
, wpa_cli_complete_bss
,
2334 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2335 { "wps_pin", wpa_cli_cmd_wps_pin
, wpa_cli_complete_bss
,
2336 cli_cmd_flag_sensitive
,
2337 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2339 { "wps_check_pin", wpa_cli_cmd_wps_check_pin
, NULL
,
2340 cli_cmd_flag_sensitive
,
2341 "<PIN> = verify PIN checksum" },
2342 { "wps_cancel", wpa_cli_cmd_wps_cancel
, NULL
, cli_cmd_flag_none
,
2343 "Cancels the pending WPS operation" },
2344 #ifdef CONFIG_WPS_OOB
2345 { "wps_oob", wpa_cli_cmd_wps_oob
, NULL
,
2346 cli_cmd_flag_sensitive
,
2347 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2348 #endif /* CONFIG_WPS_OOB */
2349 #ifdef CONFIG_WPS_NFC
2350 { "wps_nfc", wpa_cli_cmd_wps_nfc
, wpa_cli_complete_bss
,
2352 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
2353 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token
, NULL
,
2355 "<WPS|NDEF> = create password token" },
2356 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read
, NULL
,
2357 cli_cmd_flag_sensitive
,
2358 "<hexdump of payload> = report read NFC tag with WPS data" },
2359 #endif /* CONFIG_WPS_NFC */
2360 { "wps_reg", wpa_cli_cmd_wps_reg
, wpa_cli_complete_bss
,
2361 cli_cmd_flag_sensitive
,
2362 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2363 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin
, NULL
,
2364 cli_cmd_flag_sensitive
,
2365 "[params..] = enable/disable AP PIN" },
2366 { "wps_er_start", wpa_cli_cmd_wps_er_start
, NULL
,
2368 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2369 { "wps_er_stop", wpa_cli_cmd_wps_er_stop
, NULL
,
2371 "= stop Wi-Fi Protected Setup External Registrar" },
2372 { "wps_er_pin", wpa_cli_cmd_wps_er_pin
, NULL
,
2373 cli_cmd_flag_sensitive
,
2374 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2375 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc
, NULL
,
2377 "<UUID> = accept an Enrollee PBC using External Registrar" },
2378 { "wps_er_learn", wpa_cli_cmd_wps_er_learn
, NULL
,
2379 cli_cmd_flag_sensitive
,
2380 "<UUID> <PIN> = learn AP configuration" },
2381 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config
, NULL
,
2383 "<UUID> <network id> = set AP configuration for enrolling" },
2384 { "wps_er_config", wpa_cli_cmd_wps_er_config
, NULL
,
2385 cli_cmd_flag_sensitive
,
2386 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2387 #ifdef CONFIG_WPS_NFC
2388 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token
, NULL
,
2390 "<WPS/NDEF> <UUID> = build NFC configuration token" },
2391 #endif /* CONFIG_WPS_NFC */
2392 { "ibss_rsn", wpa_cli_cmd_ibss_rsn
, NULL
,
2394 "<addr> = request RSN authentication with <addr> in IBSS" },
2396 { "sta", wpa_cli_cmd_sta
, NULL
,
2398 "<addr> = get information about an associated station (AP)" },
2399 { "all_sta", wpa_cli_cmd_all_sta
, NULL
,
2401 "= get information about all associated stations (AP)" },
2402 { "deauthenticate", wpa_cli_cmd_deauthenticate
, NULL
,
2404 "<addr> = deauthenticate a station" },
2405 { "disassociate", wpa_cli_cmd_disassociate
, NULL
,
2407 "<addr> = disassociate a station" },
2408 #endif /* CONFIG_AP */
2409 { "suspend", wpa_cli_cmd_suspend
, NULL
, cli_cmd_flag_none
,
2410 "= notification of suspend/hibernate" },
2411 { "resume", wpa_cli_cmd_resume
, NULL
, cli_cmd_flag_none
,
2412 "= notification of resume/thaw" },
2413 { "drop_sa", wpa_cli_cmd_drop_sa
, NULL
, cli_cmd_flag_none
,
2414 "= drop SA without deauth/disassoc (test command)" },
2415 { "roam", wpa_cli_cmd_roam
, wpa_cli_complete_bss
,
2417 "<addr> = roam to the specified BSS" },
2419 { "p2p_find", wpa_cli_cmd_p2p_find
, NULL
, cli_cmd_flag_none
,
2420 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2421 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find
, NULL
, cli_cmd_flag_none
,
2422 "= stop P2P Devices search" },
2423 { "p2p_connect", wpa_cli_cmd_p2p_connect
, wpa_cli_complete_p2p_connect
,
2425 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
2426 { "p2p_listen", wpa_cli_cmd_p2p_listen
, NULL
, cli_cmd_flag_none
,
2427 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2428 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove
,
2429 wpa_cli_complete_p2p_group_remove
, cli_cmd_flag_none
,
2430 "<ifname> = remove P2P group interface (terminate group if GO)" },
2431 { "p2p_group_add", wpa_cli_cmd_p2p_group_add
, NULL
, cli_cmd_flag_none
,
2432 "[ht40] = add a new P2P group (local end as GO)" },
2433 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc
,
2434 wpa_cli_complete_p2p_peer
, cli_cmd_flag_none
,
2435 "<addr> <method> = request provisioning discovery" },
2436 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase
, NULL
,
2438 "= get the passphrase for a group (GO only)" },
2439 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req
,
2440 wpa_cli_complete_p2p_peer
, cli_cmd_flag_none
,
2441 "<addr> <TLVs> = schedule service discovery request" },
2442 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req
,
2443 NULL
, cli_cmd_flag_none
,
2444 "<id> = cancel pending service discovery request" },
2445 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp
, NULL
,
2447 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2448 { "p2p_service_update", wpa_cli_cmd_p2p_service_update
, NULL
,
2450 "= indicate change in local services" },
2451 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external
, NULL
,
2453 "<external> = set external processing of service discovery" },
2454 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush
, NULL
,
2456 "= remove all stored service entries" },
2457 { "p2p_service_add", wpa_cli_cmd_p2p_service_add
, NULL
,
2459 "<bonjour|upnp> <query|version> <response|service> = add a local "
2461 { "p2p_service_del", wpa_cli_cmd_p2p_service_del
, NULL
,
2463 "<bonjour|upnp> <query|version> [|service] = remove a local "
2465 { "p2p_reject", wpa_cli_cmd_p2p_reject
, wpa_cli_complete_p2p_peer
,
2467 "<addr> = reject connection attempts from a specific peer" },
2468 { "p2p_invite", wpa_cli_cmd_p2p_invite
, NULL
,
2470 "<cmd> [peer=addr] = invite peer" },
2471 { "p2p_peers", wpa_cli_cmd_p2p_peers
, NULL
, cli_cmd_flag_none
,
2472 "[discovered] = list known (optionally, only fully discovered) P2P "
2474 { "p2p_peer", wpa_cli_cmd_p2p_peer
, wpa_cli_complete_p2p_peer
,
2476 "<address> = show information about known P2P peer" },
2477 { "p2p_set", wpa_cli_cmd_p2p_set
, NULL
, cli_cmd_flag_none
,
2478 "<field> <value> = set a P2P parameter" },
2479 { "p2p_flush", wpa_cli_cmd_p2p_flush
, NULL
, cli_cmd_flag_none
,
2480 "= flush P2P state" },
2481 { "p2p_cancel", wpa_cli_cmd_p2p_cancel
, NULL
, cli_cmd_flag_none
,
2482 "= cancel P2P group formation" },
2483 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize
,
2484 wpa_cli_complete_p2p_peer
, cli_cmd_flag_none
,
2485 "<address> = unauthorize a peer" },
2486 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req
, NULL
,
2488 "[<duration> <interval>] [<duration> <interval>] = request GO "
2490 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen
, NULL
,
2492 "[<period> <interval>] = set extended listen timing" },
2493 #endif /* CONFIG_P2P */
2495 #ifdef CONFIG_INTERWORKING
2496 { "fetch_anqp", wpa_cli_cmd_fetch_anqp
, NULL
, cli_cmd_flag_none
,
2497 "= fetch ANQP information for all APs" },
2498 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp
, NULL
,
2500 "= stop fetch_anqp operation" },
2501 { "interworking_select", wpa_cli_cmd_interworking_select
, NULL
,
2503 "[auto] = perform Interworking network selection" },
2504 { "interworking_connect", wpa_cli_cmd_interworking_connect
,
2505 wpa_cli_complete_bss
, cli_cmd_flag_none
,
2506 "<BSSID> = connect using Interworking credentials" },
2507 { "anqp_get", wpa_cli_cmd_anqp_get
, wpa_cli_complete_bss
,
2509 "<addr> <info id>[,<info id>]... = request ANQP information" },
2510 { "gas_request", wpa_cli_cmd_gas_request
, wpa_cli_complete_bss
,
2512 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
2513 { "gas_response_get", wpa_cli_cmd_gas_response_get
,
2514 wpa_cli_complete_bss
, cli_cmd_flag_none
,
2515 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
2516 #endif /* CONFIG_INTERWORKING */
2518 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get
, wpa_cli_complete_bss
,
2520 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
2522 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list
,
2523 wpa_cli_complete_bss
, cli_cmd_flag_none
,
2524 "<addr> <home realm> = get HS20 nai home realm list" },
2525 #endif /* CONFIG_HS20 */
2526 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect
, NULL
,
2528 "<0/1> = disable/enable automatic reconnection" },
2529 { "tdls_discover", wpa_cli_cmd_tdls_discover
, NULL
,
2531 "<addr> = request TDLS discovery with <addr>" },
2532 { "tdls_setup", wpa_cli_cmd_tdls_setup
, NULL
,
2534 "<addr> = request TDLS setup with <addr>" },
2535 { "tdls_teardown", wpa_cli_cmd_tdls_teardown
, NULL
,
2537 "<addr> = tear down TDLS with <addr>" },
2538 { "signal_poll", wpa_cli_cmd_signal_poll
, NULL
,
2540 "= get signal parameters" },
2541 { "reauthenticate", wpa_cli_cmd_reauthenticate
, NULL
,
2543 "= trigger IEEE 802.1X/EAPOL reauthentication" },
2544 #ifdef CONFIG_AUTOSCAN
2545 { "autoscan", wpa_cli_cmd_autoscan
, NULL
, cli_cmd_flag_none
,
2546 "[params] = Set or unset (if none) autoscan parameters" },
2547 #endif /* CONFIG_AUTOSCAN */
2548 { "raw", wpa_cli_cmd_raw
, NULL
, cli_cmd_flag_sensitive
,
2549 "<params..> = Sent unprocessed command" },
2550 { NULL
, NULL
, NULL
, cli_cmd_flag_none
, NULL
}
2555 * Prints command usage, lines are padded with the specified string.
2557 static void print_cmd_help(struct wpa_cli_cmd
*cmd
, const char *pad
)
2562 printf("%s%s ", pad
, cmd
->cmd
);
2563 for (n
= 0; (c
= cmd
->usage
[n
]); n
++) {
2572 static void print_help(const char *cmd
)
2575 printf("commands:\n");
2576 for (n
= 0; wpa_cli_commands
[n
].cmd
; n
++) {
2577 if (cmd
== NULL
|| str_starts(wpa_cli_commands
[n
].cmd
, cmd
))
2578 print_cmd_help(&wpa_cli_commands
[n
], " ");
2583 static int wpa_cli_edit_filter_history_cb(void *ctx
, const char *cmd
)
2585 const char *c
, *delim
;
2589 delim
= os_strchr(cmd
, ' ');
2593 len
= os_strlen(cmd
);
2595 for (n
= 0; (c
= wpa_cli_commands
[n
].cmd
); n
++) {
2596 if (os_strncasecmp(cmd
, c
, len
) == 0 && len
== os_strlen(c
))
2597 return (wpa_cli_commands
[n
].flags
&
2598 cli_cmd_flag_sensitive
);
2604 static char ** wpa_list_cmd_list(void)
2609 count
= sizeof(wpa_cli_commands
) / sizeof(wpa_cli_commands
[0]);
2610 res
= os_calloc(count
, sizeof(char *));
2614 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2615 res
[i
] = os_strdup(wpa_cli_commands
[i
].cmd
);
2624 static char ** wpa_cli_cmd_completion(const char *cmd
, const char *str
,
2629 for (i
= 0; wpa_cli_commands
[i
].cmd
; i
++) {
2630 if (wpa_cli_commands
[i
].completion
)
2631 return wpa_cli_commands
[i
].completion(str
, pos
);
2632 if (os_strcasecmp(wpa_cli_commands
[i
].cmd
, cmd
) == 0) {
2634 printf("\r%s\n", wpa_cli_commands
[i
].usage
);
2644 static char ** wpa_cli_edit_completion_cb(void *ctx
, const char *str
, int pos
)
2650 end
= os_strchr(str
, ' ');
2651 if (end
== NULL
|| str
+ pos
< end
)
2652 return wpa_list_cmd_list();
2654 cmd
= os_malloc(pos
+ 1);
2657 os_memcpy(cmd
, str
, pos
);
2658 cmd
[end
- str
] = '\0';
2659 res
= wpa_cli_cmd_completion(cmd
, str
, pos
);
2665 static int wpa_request(struct wpa_ctrl
*ctrl
, int argc
, char *argv
[])
2667 struct wpa_cli_cmd
*cmd
, *match
= NULL
;
2672 cmd
= wpa_cli_commands
;
2674 if (os_strncasecmp(cmd
->cmd
, argv
[0], os_strlen(argv
[0])) == 0)
2677 if (os_strcasecmp(cmd
->cmd
, argv
[0]) == 0) {
2678 /* we have an exact match */
2688 printf("Ambiguous command '%s'; possible commands:", argv
[0]);
2689 cmd
= wpa_cli_commands
;
2691 if (os_strncasecmp(cmd
->cmd
, argv
[0],
2692 os_strlen(argv
[0])) == 0) {
2693 printf(" %s", cmd
->cmd
);
2699 } else if (count
== 0) {
2700 printf("Unknown command '%s'\n", argv
[0]);
2703 ret
= match
->handler(ctrl
, argc
- 1, &argv
[1]);
2710 static int str_match(const char *a
, const char *b
)
2712 return os_strncmp(a
, b
, os_strlen(b
)) == 0;
2716 static int wpa_cli_exec(const char *program
, const char *arg1
,
2724 len
= os_strlen(program
) + os_strlen(arg1
) + os_strlen(arg2
) + 3;
2725 cmd
= os_malloc(len
);
2728 res
= os_snprintf(cmd
, len
, "%s %s %s", program
, arg1
, arg2
);
2729 if (res
< 0 || (size_t) res
>= len
) {
2733 cmd
[len
- 1] = '\0';
2735 if (system(cmd
) < 0)
2737 #endif /* _WIN32_WCE */
2744 static void wpa_cli_action_process(const char *msg
)
2747 char *copy
= NULL
, *id
, *pos2
;
2752 pos
= os_strchr(pos
, '>');
2759 if (str_match(pos
, WPA_EVENT_CONNECTED
)) {
2761 os_unsetenv("WPA_ID");
2762 os_unsetenv("WPA_ID_STR");
2763 os_unsetenv("WPA_CTRL_DIR");
2765 pos
= os_strstr(pos
, "[id=");
2767 copy
= os_strdup(pos
+ 4);
2771 while (*pos2
&& *pos2
!= ' ')
2775 os_setenv("WPA_ID", id
, 1);
2776 while (*pos2
&& *pos2
!= '=')
2781 while (*pos2
&& *pos2
!= ']')
2784 os_setenv("WPA_ID_STR", id
, 1);
2788 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir
, 1);
2790 if (!wpa_cli_connected
|| new_id
!= wpa_cli_last_id
) {
2791 wpa_cli_connected
= 1;
2792 wpa_cli_last_id
= new_id
;
2793 wpa_cli_exec(action_file
, ctrl_ifname
, "CONNECTED");
2795 } else if (str_match(pos
, WPA_EVENT_DISCONNECTED
)) {
2796 if (wpa_cli_connected
) {
2797 wpa_cli_connected
= 0;
2798 wpa_cli_exec(action_file
, ctrl_ifname
, "DISCONNECTED");
2800 } else if (str_match(pos
, P2P_EVENT_GROUP_STARTED
)) {
2801 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2802 } else if (str_match(pos
, P2P_EVENT_GROUP_REMOVED
)) {
2803 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2804 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_ENABLE
)) {
2805 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2806 } else if (str_match(pos
, P2P_EVENT_CROSS_CONNECT_DISABLE
)) {
2807 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2808 } else if (str_match(pos
, P2P_EVENT_GO_NEG_FAILURE
)) {
2809 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2810 } else if (str_match(pos
, WPS_EVENT_SUCCESS
)) {
2811 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2812 } else if (str_match(pos
, WPS_EVENT_FAIL
)) {
2813 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2814 } else if (str_match(pos
, AP_STA_CONNECTED
)) {
2815 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2816 } else if (str_match(pos
, AP_STA_DISCONNECTED
)) {
2817 wpa_cli_exec(action_file
, ctrl_ifname
, pos
);
2818 } else if (str_match(pos
, WPA_EVENT_TERMINATING
)) {
2819 printf("wpa_supplicant is terminating - stop monitoring\n");
2825 #ifndef CONFIG_ANSI_C_EXTRA
2826 static void wpa_cli_action_cb(char *msg
, size_t len
)
2828 wpa_cli_action_process(msg
);
2830 #endif /* CONFIG_ANSI_C_EXTRA */
2833 static void wpa_cli_reconnect(void)
2835 wpa_cli_close_connection();
2836 if (wpa_cli_open_connection(ctrl_ifname
, 1) < 0)
2841 printf("\rConnection to wpa_supplicant re-established\n");
2847 static void cli_event(const char *str
)
2849 const char *start
, *s
;
2851 start
= os_strchr(str
, '>');
2857 if (str_starts(start
, WPA_EVENT_BSS_ADDED
)) {
2858 s
= os_strchr(start
, ' ');
2861 s
= os_strchr(s
+ 1, ' ');
2864 cli_txt_list_add(&bsses
, s
+ 1);
2868 if (str_starts(start
, WPA_EVENT_BSS_REMOVED
)) {
2869 s
= os_strchr(start
, ' ');
2872 s
= os_strchr(s
+ 1, ' ');
2875 cli_txt_list_del_addr(&bsses
, s
+ 1);
2880 if (str_starts(start
, P2P_EVENT_DEVICE_FOUND
)) {
2881 s
= os_strstr(start
, " p2p_dev_addr=");
2884 cli_txt_list_add_addr(&p2p_peers
, s
+ 14);
2888 if (str_starts(start
, P2P_EVENT_DEVICE_LOST
)) {
2889 s
= os_strstr(start
, " p2p_dev_addr=");
2892 cli_txt_list_del_addr(&p2p_peers
, s
+ 14);
2896 if (str_starts(start
, P2P_EVENT_GROUP_STARTED
)) {
2897 s
= os_strchr(start
, ' ');
2900 cli_txt_list_add_word(&p2p_groups
, s
+ 1);
2904 if (str_starts(start
, P2P_EVENT_GROUP_REMOVED
)) {
2905 s
= os_strchr(start
, ' ');
2908 cli_txt_list_del_word(&p2p_groups
, s
+ 1);
2911 #endif /* CONFIG_P2P */
2915 static int check_terminating(const char *msg
)
2917 const char *pos
= msg
;
2921 pos
= os_strchr(pos
, '>');
2928 if (str_match(pos
, WPA_EVENT_TERMINATING
) && ctrl_conn
) {
2930 printf("\rConnection to wpa_supplicant lost - trying to "
2933 wpa_cli_attached
= 0;
2934 wpa_cli_close_connection();
2942 static void wpa_cli_recv_pending(struct wpa_ctrl
*ctrl
, int action_monitor
)
2944 if (ctrl_conn
== NULL
) {
2945 wpa_cli_reconnect();
2948 while (wpa_ctrl_pending(ctrl
) > 0) {
2950 size_t len
= sizeof(buf
) - 1;
2951 if (wpa_ctrl_recv(ctrl
, buf
, &len
) == 0) {
2954 wpa_cli_action_process(buf
);
2957 if (wpa_cli_show_event(buf
)) {
2959 printf("\r%s\n", buf
);
2963 if (interactive
&& check_terminating(buf
) > 0)
2967 printf("Could not read pending message.\n");
2972 if (wpa_ctrl_pending(ctrl
) < 0) {
2973 printf("Connection to wpa_supplicant lost - trying to "
2975 wpa_cli_reconnect();
2981 static int tokenize_cmd(char *cmd
, char *argv
[])
2994 if (argc
== max_args
)
2997 char *pos2
= os_strrchr(pos
, '"');
3001 while (*pos
!= '\0' && *pos
!= ' ')
3011 static void wpa_cli_ping(void *eloop_ctx
, void *timeout_ctx
)
3013 if (ctrl_conn
&& _wpa_ctrl_command(ctrl_conn
, "PING", 0)) {
3014 printf("Connection to wpa_supplicant lost - trying to "
3016 wpa_cli_close_connection();
3019 wpa_cli_reconnect();
3020 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3024 static void wpa_cli_mon_receive(int sock
, void *eloop_ctx
, void *sock_ctx
)
3026 wpa_cli_recv_pending(mon_conn
, 0);
3030 static void wpa_cli_edit_cmd_cb(void *ctx
, char *cmd
)
3032 char *argv
[max_args
];
3034 argc
= tokenize_cmd(cmd
, argv
);
3036 wpa_request(ctrl_conn
, argc
, argv
);
3040 static void wpa_cli_edit_eof_cb(void *ctx
)
3046 static int warning_displayed
= 0;
3047 static char *hfile
= NULL
;
3048 static int edit_started
= 0;
3050 static void start_edit(void)
3055 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3056 ps
= wpa_ctrl_get_remote_ifname(ctrl_conn
);
3057 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3059 home
= getenv("HOME");
3061 const char *fname
= ".wpa_cli_history";
3062 int hfile_len
= os_strlen(home
) + 1 + os_strlen(fname
) + 1;
3063 hfile
= os_malloc(hfile_len
);
3065 os_snprintf(hfile
, hfile_len
, "%s/%s", home
, fname
);
3068 if (edit_init(wpa_cli_edit_cmd_cb
, wpa_cli_edit_eof_cb
,
3069 wpa_cli_edit_completion_cb
, NULL
, hfile
, ps
) < 0) {
3075 eloop_register_timeout(ping_interval
, 0, wpa_cli_ping
, NULL
, NULL
);
3079 static void try_connection(void *eloop_ctx
, void *timeout_ctx
)
3081 if (ctrl_ifname
== NULL
)
3082 ctrl_ifname
= wpa_cli_get_default_ifname();
3084 if (!wpa_cli_open_connection(ctrl_ifname
, 1) == 0) {
3085 if (!warning_displayed
) {
3086 printf("Could not connect to wpa_supplicant: "
3087 "%s - re-trying\n", ctrl_ifname
);
3088 warning_displayed
= 1;
3090 eloop_register_timeout(1, 0, try_connection
, NULL
, NULL
);
3094 if (warning_displayed
)
3095 printf("Connection established.\n");
3101 static void wpa_cli_interactive(void)
3103 printf("\nInteractive mode\n\n");
3105 eloop_register_timeout(0, 0, try_connection
, NULL
, NULL
);
3107 eloop_cancel_timeout(try_connection
, NULL
, NULL
);
3109 cli_txt_list_flush(&p2p_peers
);
3110 cli_txt_list_flush(&p2p_groups
);
3111 cli_txt_list_flush(&bsses
);
3113 edit_deinit(hfile
, wpa_cli_edit_filter_history_cb
);
3115 eloop_cancel_timeout(wpa_cli_ping
, NULL
, NULL
);
3116 wpa_cli_close_connection();
3120 static void wpa_cli_action(struct wpa_ctrl
*ctrl
)
3122 #ifdef CONFIG_ANSI_C_EXTRA
3123 /* TODO: ANSI C version(?) */
3124 printf("Action processing not supported in ANSI C build.\n");
3125 #else /* CONFIG_ANSI_C_EXTRA */
3129 char buf
[256]; /* note: large enough to fit in unsolicited messages */
3132 fd
= wpa_ctrl_get_fd(ctrl
);
3134 while (!wpa_cli_quit
) {
3137 tv
.tv_sec
= ping_interval
;
3139 res
= select(fd
+ 1, &rfds
, NULL
, NULL
, &tv
);
3140 if (res
< 0 && errno
!= EINTR
) {
3145 if (FD_ISSET(fd
, &rfds
))
3146 wpa_cli_recv_pending(ctrl
, 1);
3148 /* verify that connection is still working */
3149 len
= sizeof(buf
) - 1;
3150 if (wpa_ctrl_request(ctrl
, "PING", 4, buf
, &len
,
3151 wpa_cli_action_cb
) < 0 ||
3152 len
< 4 || os_memcmp(buf
, "PONG", 4) != 0) {
3153 printf("wpa_supplicant did not reply to PING "
3154 "command - exiting\n");
3159 #endif /* CONFIG_ANSI_C_EXTRA */
3163 static void wpa_cli_cleanup(void)
3165 wpa_cli_close_connection();
3167 os_daemonize_terminate(pid_file
);
3169 os_program_deinit();
3173 static void wpa_cli_terminate(int sig
, void *ctx
)
3179 static char * wpa_cli_get_default_ifname(void)
3181 char *ifname
= NULL
;
3183 #ifdef CONFIG_CTRL_IFACE_UNIX
3184 struct dirent
*dent
;
3185 DIR *dir
= opendir(ctrl_iface_dir
);
3188 char ifprop
[PROPERTY_VALUE_MAX
];
3189 if (property_get("wifi.interface", ifprop
, NULL
) != 0) {
3190 ifname
= os_strdup(ifprop
);
3191 printf("Using interface '%s'\n", ifname
);
3194 #endif /* ANDROID */
3197 while ((dent
= readdir(dir
))) {
3198 #ifdef _DIRENT_HAVE_D_TYPE
3200 * Skip the file if it is not a socket. Also accept
3201 * DT_UNKNOWN (0) in case the C library or underlying
3202 * file system does not support d_type.
3204 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
3206 #endif /* _DIRENT_HAVE_D_TYPE */
3207 if (os_strcmp(dent
->d_name
, ".") == 0 ||
3208 os_strcmp(dent
->d_name
, "..") == 0)
3210 printf("Selected interface '%s'\n", dent
->d_name
);
3211 ifname
= os_strdup(dent
->d_name
);
3215 #endif /* CONFIG_CTRL_IFACE_UNIX */
3217 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3218 char buf
[2048], *pos
;
3220 struct wpa_ctrl
*ctrl
;
3223 ctrl
= wpa_ctrl_open(NULL
);
3227 len
= sizeof(buf
) - 1;
3228 ret
= wpa_ctrl_request(ctrl
, "INTERFACES", 10, buf
, &len
, NULL
);
3231 pos
= os_strchr(buf
, '\n');
3234 ifname
= os_strdup(buf
);
3236 wpa_ctrl_close(ctrl
);
3237 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3243 int main(int argc
, char *argv
[])
3248 const char *global
= NULL
;
3250 if (os_program_init())
3254 c
= getopt(argc
, argv
, "a:Bg:G:hi:p:P:v");
3259 action_file
= optarg
;
3268 ping_interval
= atoi(optarg
);
3274 printf("%s\n", wpa_cli_version
);
3277 os_free(ctrl_ifname
);
3278 ctrl_ifname
= os_strdup(optarg
);
3281 ctrl_iface_dir
= optarg
;
3292 interactive
= (argc
== optind
) && (action_file
== NULL
);
3295 printf("%s\n\n%s\n\n", wpa_cli_version
, wpa_cli_license
);
3301 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3302 ctrl_conn
= wpa_ctrl_open(NULL
);
3303 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3304 ctrl_conn
= wpa_ctrl_open(global
);
3305 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3306 if (ctrl_conn
== NULL
) {
3307 fprintf(stderr
, "Failed to connect to wpa_supplicant "
3308 "global interface: %s error: %s\n",
3309 global
, strerror(errno
));
3314 eloop_register_signal_terminate(wpa_cli_terminate
, NULL
);
3316 if (ctrl_ifname
== NULL
)
3317 ctrl_ifname
= wpa_cli_get_default_ifname();
3320 wpa_cli_interactive();
3323 wpa_cli_open_connection(ctrl_ifname
, 0) < 0) {
3324 fprintf(stderr
, "Failed to connect to non-global "
3325 "ctrl_ifname: %s error: %s\n",
3326 ctrl_ifname
, strerror(errno
));
3331 if (wpa_ctrl_attach(ctrl_conn
) == 0) {
3332 wpa_cli_attached
= 1;
3334 printf("Warning: Failed to attach to "
3335 "wpa_supplicant.\n");
3340 if (daemonize
&& os_daemonize(pid_file
))
3344 wpa_cli_action(ctrl_conn
);
3346 ret
= wpa_request(ctrl_conn
, argc
- optind
,
3350 os_free(ctrl_ifname
);
3357 #else /* CONFIG_CTRL_IFACE */
3358 int main(int argc
, char *argv
[])
3360 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3363 #endif /* CONFIG_CTRL_IFACE */