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-2013, 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;
84 #if defined(CONFIG_P2P) && defined(ANDROID_P2P)
85 static char* redirect_interface = NULL;
88 struct cli_txt_entry {
93 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
94 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
95 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
98 static void print_help(const char *cmd);
99 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
100 static void wpa_cli_close_connection(void);
101 static char * wpa_cli_get_default_ifname(void);
102 static char ** wpa_list_cmd_list(void);
105 static void usage(void)
107 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
108 "[-a<action file>] \\\n"
109 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
111 " -h = help (show this usage text)\n"
112 " -v = shown version information\n"
113 " -a = run in daemon mode executing the action file based on "
116 " -B = run a daemon in the background\n"
117 " default path: " CONFIG_CTRL_IFACE_DIR "\n"
118 " default interface: first interface found in socket path\n");
123 static void cli_txt_list_free(struct cli_txt_entry *e)
125 dl_list_del(&e->list);
131 static void cli_txt_list_flush(struct dl_list *list)
133 struct cli_txt_entry *e;
134 while ((e = dl_list_first(list, struct cli_txt_entry, list)))
135 cli_txt_list_free(e);
139 static struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list,
142 struct cli_txt_entry *e;
143 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
144 if (os_strcmp(e->txt, txt) == 0)
151 static void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
153 struct cli_txt_entry *e;
154 e = cli_txt_list_get(txt_list, txt);
156 cli_txt_list_free(e);
160 static void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt)
164 if (hwaddr_aton(txt, addr) < 0)
166 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
167 cli_txt_list_del(txt_list, buf);
172 static void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt)
176 end = os_strchr(txt, ' ');
178 end = txt + os_strlen(txt);
179 buf = os_malloc(end - txt + 1);
182 os_memcpy(buf, txt, end - txt);
183 buf[end - txt] = '\0';
184 cli_txt_list_del(txt_list, buf);
187 #endif /* CONFIG_P2P */
190 static int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
192 struct cli_txt_entry *e;
193 e = cli_txt_list_get(txt_list, txt);
196 e = os_zalloc(sizeof(*e));
199 e->txt = os_strdup(txt);
200 if (e->txt == NULL) {
204 dl_list_add(txt_list, &e->list);
210 static int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
214 if (hwaddr_aton(txt, addr) < 0)
216 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
217 return cli_txt_list_add(txt_list, buf);
221 static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt)
226 end = os_strchr(txt, ' ');
228 end = txt + os_strlen(txt);
229 buf = os_malloc(end - txt + 1);
232 os_memcpy(buf, txt, end - txt);
233 buf[end - txt] = '\0';
234 ret = cli_txt_list_add(txt_list, buf);
238 #endif /* CONFIG_P2P */
241 static char ** cli_txt_list_array(struct dl_list *txt_list)
243 unsigned int i, count = dl_list_len(txt_list);
245 struct cli_txt_entry *e;
247 res = os_calloc(count + 1, sizeof(char *));
252 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
253 res[i] = os_strdup(e->txt);
263 static int get_cmd_arg_num(const char *str, int pos)
267 for (i = 0; i <= pos; i++) {
270 while (i <= pos && str[i] != ' ')
281 static int str_starts(const char *src, const char *match)
283 return os_strncmp(src, match, os_strlen(match)) == 0;
287 static int wpa_cli_show_event(const char *event)
291 start = os_strchr(event, '>');
297 * Skip BSS added/removed events since they can be relatively frequent
298 * and are likely of not much use for an interactive user.
300 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
301 str_starts(start, WPA_EVENT_BSS_REMOVED))
308 static int wpa_cli_open_connection(const char *ifname, int attach)
310 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
311 ctrl_conn = wpa_ctrl_open(ifname);
312 if (ctrl_conn == NULL)
315 if (attach && interactive)
316 mon_conn = wpa_ctrl_open(ifname);
319 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
327 if (access(ctrl_iface_dir, F_OK) < 0) {
328 cfile = os_strdup(ifname);
335 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
336 cfile = os_malloc(flen);
339 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
341 if (res < 0 || res >= flen) {
347 ctrl_conn = wpa_ctrl_open(cfile);
348 if (ctrl_conn == NULL) {
353 if (attach && interactive)
354 mon_conn = wpa_ctrl_open(cfile);
358 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
361 if (wpa_ctrl_attach(mon_conn) == 0) {
362 wpa_cli_attached = 1;
364 eloop_register_read_sock(
365 wpa_ctrl_get_fd(mon_conn),
366 wpa_cli_mon_receive, NULL, NULL);
368 printf("Warning: Failed to attach to "
369 "wpa_supplicant.\n");
370 wpa_cli_close_connection();
379 static void wpa_cli_close_connection(void)
381 if (ctrl_conn == NULL)
384 if (wpa_cli_attached) {
385 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
386 wpa_cli_attached = 0;
388 wpa_ctrl_close(ctrl_conn);
391 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
392 wpa_ctrl_close(mon_conn);
398 static void wpa_cli_msg_cb(char *msg, size_t len)
404 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
407 #if defined(CONFIG_P2P) && defined(ANDROID_P2P)
413 if (ctrl_conn == NULL) {
414 printf("Not connected to wpa_supplicant - command dropped.\n");
417 #if defined(CONFIG_P2P) && defined(ANDROID_P2P)
418 if (redirect_interface) {
420 arg = os_strchr(cmd, ' ');
423 ret = os_snprintf(_cmd, sizeof(_cmd), "%s %s %s", cmd, redirect_interface, arg);
426 ret = os_snprintf(_cmd, sizeof(_cmd), "%s %s", cmd, redirect_interface);
429 os_free(redirect_interface);
430 redirect_interface = NULL;
433 len = sizeof(buf) - 1;
434 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
437 printf("'%s' command timed out.\n", cmd);
439 } else if (ret < 0) {
440 printf("'%s' command failed.\n", cmd);
446 if (interactive && len > 0 && buf[len - 1] != '\n')
453 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
455 return _wpa_ctrl_command(ctrl, cmd, 1);
459 static int write_cmd(char *buf, size_t buflen, const char *cmd, int argc,
468 res = os_snprintf(pos, end - pos, "%s", cmd);
469 if (res < 0 || res >= end - pos)
473 for (i = 0; i < argc; i++) {
474 res = os_snprintf(pos, end - pos, " %s", argv[i]);
475 if (res < 0 || res >= end - pos)
480 buf[buflen - 1] = '\0';
484 printf("Too long command\n");
489 static int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args,
490 int argc, char *argv[])
493 if (argc < min_args) {
494 printf("Invalid %s command - at least %d argument%s "
495 "required.\n", cmd, min_args,
496 min_args > 1 ? "s are" : " is");
499 if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0)
501 return wpa_ctrl_command(ctrl, buf);
505 static int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[])
507 return wpa_ctrl_command(ctrl, "IFNAME");
511 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
513 if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
514 return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
515 if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
516 return wpa_ctrl_command(ctrl, "STATUS-WPS");
517 return wpa_ctrl_command(ctrl, "STATUS");
521 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
523 return wpa_ctrl_command(ctrl, "PING");
527 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
529 return wpa_ctrl_command(ctrl, "RELOG");
533 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
535 return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv);
539 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
541 return wpa_ctrl_command(ctrl, "MIB");
545 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
547 return wpa_ctrl_command(ctrl, "PMKSA");
551 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
553 print_help(argc > 0 ? argv[0] : NULL);
558 static char ** wpa_cli_complete_help(const char *str, int pos)
560 int arg = get_cmd_arg_num(str, pos);
565 res = wpa_list_cmd_list();
573 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
575 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
580 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
589 static void wpa_cli_show_variables(void)
591 printf("set variables:\n"
592 " EAPOL::heldPeriod (EAPOL state machine held period, "
594 " EAPOL::authPeriod (EAPOL state machine authentication "
595 "period, in seconds)\n"
596 " EAPOL::startPeriod (EAPOL state machine start period, in "
598 " EAPOL::maxStart (EAPOL state machine maximum start "
600 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
602 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
603 " threshold\n\tpercentage)\n"
604 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
605 "security\n\tassociation in seconds)\n");
609 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
615 wpa_cli_show_variables();
619 if (argc != 1 && argc != 2) {
620 printf("Invalid SET command: needs two arguments (variable "
621 "name and value)\n");
626 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
628 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s",
630 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
631 printf("Too long SET command.\n");
634 return wpa_ctrl_command(ctrl, cmd);
638 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
640 return wpa_cli_cmd(ctrl, "GET", 1, argc, argv);
644 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
646 return wpa_ctrl_command(ctrl, "LOGOFF");
650 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
652 return wpa_ctrl_command(ctrl, "LOGON");
656 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
659 return wpa_ctrl_command(ctrl, "REASSOCIATE");
663 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
666 return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv);
670 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
672 return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv);
676 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
679 return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv);
683 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
686 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv);
690 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
693 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv);
697 static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
703 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0");
705 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]);
706 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
707 printf("Too long BSS_FLUSH command.\n");
710 return wpa_ctrl_command(ctrl, cmd);
714 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
717 return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv);
721 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
723 return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv);
727 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
729 return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv);
733 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
736 printf("Invalid WPS_PIN command: need one or two arguments:\n"
737 "- BSSID: use 'any' to select any\n"
738 "- PIN: optional, used only with devices that have no "
743 return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv);
747 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
750 return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv);
754 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
757 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
761 #ifdef CONFIG_WPS_NFC
763 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
765 return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv);
769 static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
772 return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
776 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
779 return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv);
783 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
791 printf("Invalid 'wps_nfc_tag_read' command - one argument "
796 buflen = 18 + os_strlen(argv[0]);
797 buf = os_malloc(buflen);
800 os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
802 ret = wpa_ctrl_command(ctrl, buf);
809 static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc,
812 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv);
816 static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc,
819 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv);
823 static int wpa_cli_cmd_nfc_rx_handover_req(struct wpa_ctrl *ctrl, int argc,
831 printf("Invalid 'nfc_rx_handover_req' command - one argument "
836 buflen = 21 + os_strlen(argv[0]);
837 buf = os_malloc(buflen);
840 os_snprintf(buf, buflen, "NFC_RX_HANDOVER_REQ %s", argv[0]);
842 ret = wpa_ctrl_command(ctrl, buf);
849 static int wpa_cli_cmd_nfc_rx_handover_sel(struct wpa_ctrl *ctrl, int argc,
857 printf("Invalid 'nfc_rx_handover_sel' command - one argument "
862 buflen = 21 + os_strlen(argv[0]);
863 buf = os_malloc(buflen);
866 os_snprintf(buf, buflen, "NFC_RX_HANDOVER_SEL %s", argv[0]);
868 ret = wpa_ctrl_command(ctrl, buf);
875 static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc,
878 return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv);
881 #endif /* CONFIG_WPS_NFC */
884 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
890 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
892 else if (argc == 5 || argc == 6) {
893 char ssid_hex[2 * 32 + 1];
894 char key_hex[2 * 64 + 1];
898 for (i = 0; i < 32; i++) {
899 if (argv[2][i] == '\0')
901 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
906 for (i = 0; i < 64; i++) {
907 if (argv[5][i] == '\0')
909 os_snprintf(&key_hex[i * 2], 3, "%02x",
914 res = os_snprintf(cmd, sizeof(cmd),
915 "WPS_REG %s %s %s %s %s %s",
916 argv[0], argv[1], ssid_hex, argv[3], argv[4],
919 printf("Invalid WPS_REG command: need two arguments:\n"
920 "- BSSID of the target AP\n"
922 printf("Alternatively, six arguments can be used to "
923 "reconfigure the AP:\n"
924 "- BSSID of the target AP\n"
927 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
928 "- new encr (NONE, WEP, TKIP, CCMP)\n"
933 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
934 printf("Too long WPS_REG command.\n");
937 return wpa_ctrl_command(ctrl, cmd);
941 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
944 return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv);
948 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
951 return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv);
955 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
958 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
963 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
967 printf("Invalid WPS_ER_PIN command: need at least two "
969 "- UUID: use 'any' to select any\n"
970 "- PIN: Enrollee PIN\n"
971 "optional: - Enrollee MAC address\n");
975 return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv);
979 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
982 return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv);
986 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
990 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
991 "- UUID: specify which AP to use\n"
996 return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv);
1000 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
1004 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1006 "- UUID: specify which AP to use\n"
1007 "- Network configuration id\n");
1011 return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv);
1015 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
1021 if (argc == 5 || argc == 6) {
1022 char ssid_hex[2 * 32 + 1];
1023 char key_hex[2 * 64 + 1];
1027 for (i = 0; i < 32; i++) {
1028 if (argv[2][i] == '\0')
1030 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1035 for (i = 0; i < 64; i++) {
1036 if (argv[5][i] == '\0')
1038 os_snprintf(&key_hex[i * 2], 3, "%02x",
1043 res = os_snprintf(cmd, sizeof(cmd),
1044 "WPS_ER_CONFIG %s %s %s %s %s %s",
1045 argv[0], argv[1], ssid_hex, argv[3], argv[4],
1048 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1052 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1053 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1058 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1059 printf("Too long WPS_ER_CONFIG command.\n");
1062 return wpa_ctrl_command(ctrl, cmd);
1066 #ifdef CONFIG_WPS_NFC
1067 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
1071 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
1073 "- WPS/NDEF: token format\n"
1074 "- UUID: specify which AP to use\n");
1078 return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv);
1080 #endif /* CONFIG_WPS_NFC */
1083 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1085 return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv);
1089 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1091 return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv);
1095 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1097 char cmd[256], *pos, *end;
1101 printf("Invalid IDENTITY command: needs two arguments "
1102 "(network id and identity)\n");
1106 end = cmd + sizeof(cmd);
1108 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1110 if (ret < 0 || ret >= end - pos) {
1111 printf("Too long IDENTITY command.\n");
1115 for (i = 2; i < argc; i++) {
1116 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1117 if (ret < 0 || ret >= end - pos) {
1118 printf("Too long IDENTITY command.\n");
1124 return wpa_ctrl_command(ctrl, cmd);
1128 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1130 char cmd[256], *pos, *end;
1134 printf("Invalid PASSWORD command: needs two arguments "
1135 "(network id and password)\n");
1139 end = cmd + sizeof(cmd);
1141 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1143 if (ret < 0 || ret >= end - pos) {
1144 printf("Too long PASSWORD command.\n");
1148 for (i = 2; i < argc; i++) {
1149 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1150 if (ret < 0 || ret >= end - pos) {
1151 printf("Too long PASSWORD command.\n");
1157 return wpa_ctrl_command(ctrl, cmd);
1161 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1164 char cmd[256], *pos, *end;
1168 printf("Invalid NEW_PASSWORD command: needs two arguments "
1169 "(network id and password)\n");
1173 end = cmd + sizeof(cmd);
1175 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1177 if (ret < 0 || ret >= end - pos) {
1178 printf("Too long NEW_PASSWORD command.\n");
1182 for (i = 2; i < argc; i++) {
1183 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1184 if (ret < 0 || ret >= end - pos) {
1185 printf("Too long NEW_PASSWORD command.\n");
1191 return wpa_ctrl_command(ctrl, cmd);
1195 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1197 char cmd[256], *pos, *end;
1201 printf("Invalid PIN command: needs two arguments "
1202 "(network id and pin)\n");
1206 end = cmd + sizeof(cmd);
1208 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1210 if (ret < 0 || ret >= end - pos) {
1211 printf("Too long PIN command.\n");
1215 for (i = 2; i < argc; i++) {
1216 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1217 if (ret < 0 || ret >= end - pos) {
1218 printf("Too long PIN command.\n");
1223 return wpa_ctrl_command(ctrl, cmd);
1227 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1229 char cmd[256], *pos, *end;
1233 printf("Invalid OTP command: needs two arguments (network "
1234 "id and password)\n");
1238 end = cmd + sizeof(cmd);
1240 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1242 if (ret < 0 || ret >= end - pos) {
1243 printf("Too long OTP command.\n");
1247 for (i = 2; i < argc; i++) {
1248 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1249 if (ret < 0 || ret >= end - pos) {
1250 printf("Too long OTP command.\n");
1256 return wpa_ctrl_command(ctrl, cmd);
1260 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1263 char cmd[256], *pos, *end;
1267 printf("Invalid PASSPHRASE command: needs two arguments "
1268 "(network id and passphrase)\n");
1272 end = cmd + sizeof(cmd);
1274 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1276 if (ret < 0 || ret >= end - pos) {
1277 printf("Too long PASSPHRASE command.\n");
1281 for (i = 2; i < argc; i++) {
1282 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1283 if (ret < 0 || ret >= end - pos) {
1284 printf("Too long PASSPHRASE command.\n");
1290 return wpa_ctrl_command(ctrl, cmd);
1294 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1297 printf("Invalid BSSID command: needs two arguments (network "
1302 return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv);
1306 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1308 return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv);
1312 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1314 return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv);
1318 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1321 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1325 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1328 return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv);
1332 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1335 return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv);
1339 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1342 return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv);
1346 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1349 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1353 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1356 return wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv);
1360 static void wpa_cli_show_network_variables(void)
1362 printf("set_network variables:\n"
1363 " ssid (network name, SSID)\n"
1364 " psk (WPA passphrase or pre-shared key)\n"
1365 " key_mgmt (key management protocol)\n"
1366 " identity (EAP identity)\n"
1367 " password (EAP password)\n"
1370 "Note: Values are entered in the same format as the "
1371 "configuration file is using,\n"
1372 "i.e., strings values need to be inside double quotation "
1374 "For example: set_network 1 ssid \"network name\"\n"
1376 "Please see wpa_supplicant.conf documentation for full list "
1377 "of\navailable variables.\n");
1381 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1385 wpa_cli_show_network_variables();
1390 printf("Invalid SET_NETWORK command: needs three arguments\n"
1391 "(network id, variable name, and value)\n");
1395 return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv);
1399 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1403 wpa_cli_show_network_variables();
1408 printf("Invalid GET_NETWORK command: needs two arguments\n"
1409 "(network id and variable name)\n");
1413 return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv);
1417 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1420 return wpa_ctrl_command(ctrl, "LIST_CREDS");
1424 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1426 return wpa_ctrl_command(ctrl, "ADD_CRED");
1430 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1433 return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv);
1437 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1440 printf("Invalid SET_CRED command: needs three arguments\n"
1441 "(cred id, variable name, and value)\n");
1445 return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv);
1449 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1452 return wpa_ctrl_command(ctrl, "DISCONNECT");
1456 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1459 return wpa_ctrl_command(ctrl, "RECONNECT");
1463 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1466 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1470 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1472 return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
1476 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1479 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1483 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1485 return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
1489 static char ** wpa_cli_complete_bss(const char *str, int pos)
1491 int arg = get_cmd_arg_num(str, pos);
1496 res = cli_txt_list_array(&bsses);
1504 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1507 if (argc < 1 || argc > 2) {
1508 printf("Invalid GET_CAPABILITY command: need either one or "
1513 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1514 printf("Invalid GET_CAPABILITY command: second argument, "
1515 "if any, must be 'strict'\n");
1519 return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv);
1523 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1525 printf("Available interfaces:\n");
1526 return wpa_ctrl_command(ctrl, "INTERFACES");
1530 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1533 wpa_cli_list_interfaces(ctrl);
1537 wpa_cli_close_connection();
1538 os_free(ctrl_ifname);
1539 ctrl_ifname = os_strdup(argv[0]);
1541 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1542 printf("Connected to interface '%s.\n", ctrl_ifname);
1544 printf("Could not connect to interface '%s' - re-trying\n",
1551 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1554 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1558 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1561 return wpa_ctrl_command(ctrl, "TERMINATE");
1565 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1572 printf("Invalid INTERFACE_ADD command: needs at least one "
1573 "argument (interface name)\n"
1574 "All arguments: ifname confname driver ctrl_interface "
1575 "driver_param bridge_name\n");
1580 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1581 * <driver_param>TAB<bridge_name>
1583 res = os_snprintf(cmd, sizeof(cmd),
1584 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1586 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1587 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1588 argc > 5 ? argv[5] : "");
1589 if (res < 0 || (size_t) res >= sizeof(cmd))
1591 cmd[sizeof(cmd) - 1] = '\0';
1592 return wpa_ctrl_command(ctrl, cmd);
1596 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1599 return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv);
1603 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1606 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1611 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1613 return wpa_cli_cmd(ctrl, "STA", 1, argc, argv);
1617 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1618 char *addr, size_t addr_len)
1620 char buf[4096], *pos;
1624 if (ctrl_conn == NULL) {
1625 printf("Not connected to hostapd - command dropped.\n");
1628 len = sizeof(buf) - 1;
1629 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
1632 printf("'%s' command timed out.\n", cmd);
1634 } else if (ret < 0) {
1635 printf("'%s' command failed.\n", cmd);
1640 if (os_memcmp(buf, "FAIL", 4) == 0)
1645 while (*pos != '\0' && *pos != '\n')
1648 os_strlcpy(addr, buf, addr_len);
1653 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1655 char addr[32], cmd[64];
1657 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1660 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1661 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1667 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
1670 return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv);
1674 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
1677 return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv);
1679 #endif /* CONFIG_AP */
1682 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1684 return wpa_ctrl_command(ctrl, "SUSPEND");
1688 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1690 return wpa_ctrl_command(ctrl, "RESUME");
1694 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1696 return wpa_ctrl_command(ctrl, "DROP_SA");
1700 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1702 return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv);
1708 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1710 return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv);
1714 static char ** wpa_cli_complete_p2p_find(const char *str, int pos)
1717 int arg = get_cmd_arg_num(str, pos);
1719 res = os_calloc(6, sizeof(char *));
1722 res[0] = os_strdup("type=social");
1723 if (res[0] == NULL) {
1727 res[1] = os_strdup("type=progressive");
1730 res[2] = os_strdup("delay=");
1733 res[3] = os_strdup("dev_id=");
1737 res[4] = os_strdup("[timeout]");
1743 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1746 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1750 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1753 return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv);
1757 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
1759 int arg = get_cmd_arg_num(str, pos);
1764 res = cli_txt_list_array(&p2p_peers);
1772 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1775 return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv);
1779 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1782 return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv);
1786 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
1788 int arg = get_cmd_arg_num(str, pos);
1793 res = cli_txt_list_array(&p2p_groups);
1801 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1804 return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv);
1808 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1811 if (argc != 2 && argc != 3) {
1812 printf("Invalid P2P_PROV_DISC command: needs at least "
1813 "two arguments, address and config method\n"
1814 "(display, keypad, or pbc) and an optional join\n");
1818 return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv);
1822 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1825 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1829 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1834 if (argc != 2 && argc != 4) {
1835 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1836 "arguments (address and TLVs) or four arguments "
1837 "(address, \"upnp\", version, search target "
1842 if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0)
1844 return wpa_ctrl_command(ctrl, cmd);
1848 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1849 int argc, char *argv[])
1851 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv);
1855 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1862 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1863 "arguments (freq, address, dialog token, and TLVs)\n");
1867 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1868 argv[0], argv[1], argv[2], argv[3]);
1869 if (res < 0 || (size_t) res >= sizeof(cmd))
1871 cmd[sizeof(cmd) - 1] = '\0';
1872 return wpa_ctrl_command(ctrl, cmd);
1876 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
1879 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1883 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1884 int argc, char *argv[])
1886 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv);
1890 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1893 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1897 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1903 if (argc != 3 && argc != 4) {
1904 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1910 res = os_snprintf(cmd, sizeof(cmd),
1911 "P2P_SERVICE_ADD %s %s %s %s",
1912 argv[0], argv[1], argv[2], argv[3]);
1914 res = os_snprintf(cmd, sizeof(cmd),
1915 "P2P_SERVICE_ADD %s %s %s",
1916 argv[0], argv[1], argv[2]);
1917 if (res < 0 || (size_t) res >= sizeof(cmd))
1919 cmd[sizeof(cmd) - 1] = '\0';
1920 return wpa_ctrl_command(ctrl, cmd);
1924 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
1930 if (argc != 2 && argc != 3) {
1931 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1937 res = os_snprintf(cmd, sizeof(cmd),
1938 "P2P_SERVICE_DEL %s %s %s",
1939 argv[0], argv[1], argv[2]);
1941 res = os_snprintf(cmd, sizeof(cmd),
1942 "P2P_SERVICE_DEL %s %s",
1944 if (res < 0 || (size_t) res >= sizeof(cmd))
1946 cmd[sizeof(cmd) - 1] = '\0';
1947 return wpa_ctrl_command(ctrl, cmd);
1951 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
1952 int argc, char *argv[])
1954 return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv);
1958 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
1959 int argc, char *argv[])
1961 return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv);
1965 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
1967 return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv);
1971 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
1973 int arg = get_cmd_arg_num(str, pos);
1978 res = cli_txt_list_array(&p2p_peers);
1986 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
1987 char *addr, size_t addr_len,
1990 char buf[4096], *pos;
1994 if (ctrl_conn == NULL)
1996 len = sizeof(buf) - 1;
1997 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2000 printf("'%s' command timed out.\n", cmd);
2002 } else if (ret < 0) {
2003 printf("'%s' command failed.\n", cmd);
2008 if (os_memcmp(buf, "FAIL", 4) == 0)
2012 while (*pos != '\0' && *pos != '\n')
2015 os_strlcpy(addr, buf, addr_len);
2016 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2017 printf("%s\n", addr);
2022 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2024 char addr[32], cmd[64];
2027 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2029 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2030 addr, sizeof(addr), discovered))
2033 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2034 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2041 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2043 return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv);
2047 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2049 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2053 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2056 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2060 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2063 return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv);
2067 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2070 if (argc != 0 && argc != 2 && argc != 4) {
2071 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2072 "(preferred duration, interval; in microsecods).\n"
2073 "Optional second pair can be used to provide "
2074 "acceptable values.\n");
2078 return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv);
2082 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2085 if (argc != 0 && argc != 2) {
2086 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2087 "(availability period, availability interval; in "
2089 "Extended Listen Timing can be cancelled with this "
2090 "command when used without parameters.\n");
2094 return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv);
2097 #endif /* CONFIG_P2P */
2099 #ifdef CONFIG_WIFI_DISPLAY
2101 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc,
2107 if (argc != 1 && argc != 2) {
2108 printf("Invalid WFD_SUBELEM_SET command: needs one or two "
2109 "arguments (subelem, hexdump)\n");
2113 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s",
2114 argv[0], argc > 1 ? argv[1] : "");
2115 if (res < 0 || (size_t) res >= sizeof(cmd))
2117 cmd[sizeof(cmd) - 1] = '\0';
2118 return wpa_ctrl_command(ctrl, cmd);
2122 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc,
2129 printf("Invalid WFD_SUBELEM_GET command: needs one "
2130 "argument (subelem)\n");
2134 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s",
2136 if (res < 0 || (size_t) res >= sizeof(cmd))
2138 cmd[sizeof(cmd) - 1] = '\0';
2139 return wpa_ctrl_command(ctrl, cmd);
2141 #endif /* CONFIG_WIFI_DISPLAY */
2144 #ifdef CONFIG_INTERWORKING
2145 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2148 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2152 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2155 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2159 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2162 return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv);
2166 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2169 return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv);
2173 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2175 return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv);
2179 static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc,
2182 return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv);
2186 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc,
2189 return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv);
2191 #endif /* CONFIG_INTERWORKING */
2196 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2199 return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv);
2203 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2209 printf("Command needs one or two arguments (dst mac addr and "
2210 "optional home realm)\n");
2214 if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST",
2218 return wpa_ctrl_command(ctrl, cmd);
2221 #endif /* CONFIG_HS20 */
2224 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2227 return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv);
2231 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2234 return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv);
2238 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2241 return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv);
2245 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2248 return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv);
2252 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2255 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2259 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
2262 return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
2266 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2269 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2273 #ifdef CONFIG_AUTOSCAN
2275 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
2278 return wpa_ctrl_command(ctrl, "AUTOSCAN ");
2280 return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv);
2283 #endif /* CONFIG_AUTOSCAN */
2288 static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[])
2290 return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv);
2293 #endif /* CONFIG_WNM */
2296 static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
2300 return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
2305 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
2312 printf("Invalid DRIVER command: needs one argument (cmd)\n");
2316 len = os_snprintf(cmd, sizeof(cmd), "DRIVER %s", argv[0]);
2317 for (i=1; i < argc; i++)
2318 len += os_snprintf(cmd + len, sizeof(cmd) - len, " %s", argv[i]);
2319 cmd[sizeof(cmd) - 1] = '\0';
2320 printf("%s: %s\n", __func__, cmd);
2321 return wpa_ctrl_command(ctrl, cmd);
2326 enum wpa_cli_cmd_flags {
2327 cli_cmd_flag_none = 0x00,
2328 cli_cmd_flag_sensitive = 0x01
2331 struct wpa_cli_cmd {
2333 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2334 char ** (*completion)(const char *str, int pos);
2335 enum wpa_cli_cmd_flags flags;
2339 static struct wpa_cli_cmd wpa_cli_commands[] = {
2340 { "status", wpa_cli_cmd_status, NULL,
2342 "[verbose] = get current WPA/EAPOL/EAP status" },
2343 { "ifname", wpa_cli_cmd_ifname, NULL,
2345 "= get current interface name" },
2346 { "ping", wpa_cli_cmd_ping, NULL,
2348 "= pings wpa_supplicant" },
2349 { "relog", wpa_cli_cmd_relog, NULL,
2351 "= re-open log-file (allow rolling logs)" },
2352 { "note", wpa_cli_cmd_note, NULL,
2354 "<text> = add a note to wpa_supplicant debug log" },
2355 { "mib", wpa_cli_cmd_mib, NULL,
2357 "= get MIB variables (dot1x, dot11)" },
2358 { "help", wpa_cli_cmd_help, wpa_cli_complete_help,
2360 "[command] = show usage help" },
2361 { "interface", wpa_cli_cmd_interface, NULL,
2363 "[ifname] = show interfaces/select interface" },
2364 { "level", wpa_cli_cmd_level, NULL,
2366 "<debug level> = change debug level" },
2367 { "license", wpa_cli_cmd_license, NULL,
2369 "= show full wpa_cli license" },
2370 { "quit", wpa_cli_cmd_quit, NULL,
2373 { "set", wpa_cli_cmd_set, NULL,
2375 "= set variables (shows list of variables when run without "
2377 { "get", wpa_cli_cmd_get, NULL,
2379 "<name> = get information" },
2380 { "logon", wpa_cli_cmd_logon, NULL,
2382 "= IEEE 802.1X EAPOL state machine logon" },
2383 { "logoff", wpa_cli_cmd_logoff, NULL,
2385 "= IEEE 802.1X EAPOL state machine logoff" },
2386 { "pmksa", wpa_cli_cmd_pmksa, NULL,
2388 "= show PMKSA cache" },
2389 { "reassociate", wpa_cli_cmd_reassociate, NULL,
2391 "= force reassociation" },
2392 { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
2394 "<BSSID> = force preauthentication" },
2395 { "identity", wpa_cli_cmd_identity, NULL,
2397 "<network id> <identity> = configure identity for an SSID" },
2398 { "password", wpa_cli_cmd_password, NULL,
2399 cli_cmd_flag_sensitive,
2400 "<network id> <password> = configure password for an SSID" },
2401 { "new_password", wpa_cli_cmd_new_password, NULL,
2402 cli_cmd_flag_sensitive,
2403 "<network id> <password> = change password for an SSID" },
2404 { "pin", wpa_cli_cmd_pin, NULL,
2405 cli_cmd_flag_sensitive,
2406 "<network id> <pin> = configure pin for an SSID" },
2407 { "otp", wpa_cli_cmd_otp, NULL,
2408 cli_cmd_flag_sensitive,
2409 "<network id> <password> = configure one-time-password for an SSID"
2411 { "passphrase", wpa_cli_cmd_passphrase, NULL,
2412 cli_cmd_flag_sensitive,
2413 "<network id> <passphrase> = configure private key passphrase\n"
2415 { "bssid", wpa_cli_cmd_bssid, NULL,
2417 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2418 { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss,
2420 "<BSSID> = add a BSSID to the blacklist\n"
2421 "blacklist clear = clear the blacklist\n"
2422 "blacklist = display the blacklist" },
2423 { "log_level", wpa_cli_cmd_log_level, NULL,
2425 "<level> [<timestamp>] = update the log level/timestamp\n"
2426 "log_level = display the current log level and log options" },
2427 { "list_networks", wpa_cli_cmd_list_networks, NULL,
2429 "= list configured networks" },
2430 { "select_network", wpa_cli_cmd_select_network, NULL,
2432 "<network id> = select a network (disable others)" },
2433 { "enable_network", wpa_cli_cmd_enable_network, NULL,
2435 "<network id> = enable a network" },
2436 { "disable_network", wpa_cli_cmd_disable_network, NULL,
2438 "<network id> = disable a network" },
2439 { "add_network", wpa_cli_cmd_add_network, NULL,
2441 "= add a network" },
2442 { "remove_network", wpa_cli_cmd_remove_network, NULL,
2444 "<network id> = remove a network" },
2445 { "set_network", wpa_cli_cmd_set_network, NULL,
2446 cli_cmd_flag_sensitive,
2447 "<network id> <variable> <value> = set network variables (shows\n"
2448 " list of variables when run without arguments)" },
2449 { "get_network", wpa_cli_cmd_get_network, NULL,
2451 "<network id> <variable> = get network variables" },
2452 { "list_creds", wpa_cli_cmd_list_creds, NULL,
2454 "= list configured credentials" },
2455 { "add_cred", wpa_cli_cmd_add_cred, NULL,
2457 "= add a credential" },
2458 { "remove_cred", wpa_cli_cmd_remove_cred, NULL,
2460 "<cred id> = remove a credential" },
2461 { "set_cred", wpa_cli_cmd_set_cred, NULL,
2462 cli_cmd_flag_sensitive,
2463 "<cred id> <variable> <value> = set credential variables" },
2464 { "save_config", wpa_cli_cmd_save_config, NULL,
2466 "= save the current configuration" },
2467 { "disconnect", wpa_cli_cmd_disconnect, NULL,
2469 "= disconnect and wait for reassociate/reconnect command before\n"
2471 { "reconnect", wpa_cli_cmd_reconnect, NULL,
2473 "= like reassociate, but only takes effect if already disconnected"
2475 { "scan", wpa_cli_cmd_scan, NULL,
2477 "= request new BSS scan" },
2478 { "scan_results", wpa_cli_cmd_scan_results, NULL,
2480 "= get latest scan results" },
2481 { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
2483 "<<idx> | <bssid>> = get detailed scan result info" },
2484 { "get_capability", wpa_cli_cmd_get_capability, NULL,
2486 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels> "
2487 "= get capabilies" },
2488 { "reconfigure", wpa_cli_cmd_reconfigure, NULL,
2490 "= force wpa_supplicant to re-read its configuration file" },
2491 { "terminate", wpa_cli_cmd_terminate, NULL,
2493 "= terminate wpa_supplicant" },
2494 { "interface_add", wpa_cli_cmd_interface_add, NULL,
2496 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2497 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2499 { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
2501 "<ifname> = removes the interface" },
2502 { "interface_list", wpa_cli_cmd_interface_list, NULL,
2504 "= list available interfaces" },
2505 { "ap_scan", wpa_cli_cmd_ap_scan, NULL,
2507 "<value> = set ap_scan parameter" },
2508 { "scan_interval", wpa_cli_cmd_scan_interval, NULL,
2510 "<value> = set scan_interval parameter (in seconds)" },
2511 { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
2513 "<value> = set BSS expiration age parameter" },
2514 { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
2516 "<value> = set BSS expiration scan count parameter" },
2517 { "bss_flush", wpa_cli_cmd_bss_flush, NULL,
2519 "<value> = set BSS flush age (0 by default)" },
2520 { "stkstart", wpa_cli_cmd_stkstart, NULL,
2522 "<addr> = request STK negotiation with <addr>" },
2523 { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
2525 "<addr> = request over-the-DS FT with <addr>" },
2526 { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
2528 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2529 { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
2530 cli_cmd_flag_sensitive,
2531 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2533 { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
2534 cli_cmd_flag_sensitive,
2535 "<PIN> = verify PIN checksum" },
2536 { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
2537 "Cancels the pending WPS operation" },
2538 #ifdef CONFIG_WPS_NFC
2539 { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
2541 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
2542 { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
2544 "<WPS|NDEF> = build configuration token" },
2545 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
2547 "<WPS|NDEF> = create password token" },
2548 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
2549 cli_cmd_flag_sensitive,
2550 "<hexdump of payload> = report read NFC tag with WPS data" },
2551 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
2553 "<NDEF> <WPS> = create NFC handover request" },
2554 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
2556 "<NDEF> <WPS> = create NFC handover select" },
2557 { "nfc_rx_handover_req", wpa_cli_cmd_nfc_rx_handover_req, NULL,
2559 "<hexdump of payload> = report received NFC handover request" },
2560 { "nfc_rx_handover_sel", wpa_cli_cmd_nfc_rx_handover_sel, NULL,
2562 "<hexdump of payload> = report received NFC handover select" },
2563 { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
2565 "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
2567 #endif /* CONFIG_WPS_NFC */
2568 { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
2569 cli_cmd_flag_sensitive,
2570 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2571 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
2572 cli_cmd_flag_sensitive,
2573 "[params..] = enable/disable AP PIN" },
2574 { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
2576 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2577 { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
2579 "= stop Wi-Fi Protected Setup External Registrar" },
2580 { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
2581 cli_cmd_flag_sensitive,
2582 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2583 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
2585 "<UUID> = accept an Enrollee PBC using External Registrar" },
2586 { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
2587 cli_cmd_flag_sensitive,
2588 "<UUID> <PIN> = learn AP configuration" },
2589 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
2591 "<UUID> <network id> = set AP configuration for enrolling" },
2592 { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
2593 cli_cmd_flag_sensitive,
2594 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2595 #ifdef CONFIG_WPS_NFC
2596 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
2598 "<WPS/NDEF> <UUID> = build NFC configuration token" },
2599 #endif /* CONFIG_WPS_NFC */
2600 { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
2602 "<addr> = request RSN authentication with <addr> in IBSS" },
2604 { "sta", wpa_cli_cmd_sta, NULL,
2606 "<addr> = get information about an associated station (AP)" },
2607 { "all_sta", wpa_cli_cmd_all_sta, NULL,
2609 "= get information about all associated stations (AP)" },
2610 { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL,
2612 "<addr> = deauthenticate a station" },
2613 { "disassociate", wpa_cli_cmd_disassociate, NULL,
2615 "<addr> = disassociate a station" },
2616 #endif /* CONFIG_AP */
2617 { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
2618 "= notification of suspend/hibernate" },
2619 { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
2620 "= notification of resume/thaw" },
2621 { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
2622 "= drop SA without deauth/disassoc (test command)" },
2623 { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
2625 "<addr> = roam to the specified BSS" },
2627 { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
2629 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2630 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
2631 "= stop P2P Devices search" },
2632 { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
2634 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
2635 { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
2636 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2637 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
2638 wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
2639 "<ifname> = remove P2P group interface (terminate group if GO)" },
2640 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
2641 "[ht40] = add a new P2P group (local end as GO)" },
2642 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
2643 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2644 "<addr> <method> = request provisioning discovery" },
2645 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
2647 "= get the passphrase for a group (GO only)" },
2648 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2649 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2650 "<addr> <TLVs> = schedule service discovery request" },
2651 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2652 NULL, cli_cmd_flag_none,
2653 "<id> = cancel pending service discovery request" },
2654 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
2656 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2657 { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
2659 "= indicate change in local services" },
2660 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
2662 "<external> = set external processing of service discovery" },
2663 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
2665 "= remove all stored service entries" },
2666 { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
2668 "<bonjour|upnp> <query|version> <response|service> = add a local "
2670 { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
2672 "<bonjour|upnp> <query|version> [|service] = remove a local "
2674 { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
2676 "<addr> = reject connection attempts from a specific peer" },
2677 { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
2679 "<cmd> [peer=addr] = invite peer" },
2680 { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
2681 "[discovered] = list known (optionally, only fully discovered) P2P "
2683 { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
2685 "<address> = show information about known P2P peer" },
2686 { "p2p_set", wpa_cli_cmd_p2p_set, NULL, cli_cmd_flag_none,
2687 "<field> <value> = set a P2P parameter" },
2688 { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
2689 "= flush P2P state" },
2690 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
2691 "= cancel P2P group formation" },
2692 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
2693 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2694 "<address> = unauthorize a peer" },
2695 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
2697 "[<duration> <interval>] [<duration> <interval>] = request GO "
2699 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
2701 "[<period> <interval>] = set extended listen timing" },
2702 #endif /* CONFIG_P2P */
2703 #ifdef CONFIG_WIFI_DISPLAY
2704 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
2706 "<subelem> [contents] = set Wi-Fi Display subelement" },
2707 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
2709 "<subelem> = get Wi-Fi Display subelement" },
2710 #endif /* CONFIG_WIFI_DISPLAY */
2711 #ifdef CONFIG_INTERWORKING
2712 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
2713 "= fetch ANQP information for all APs" },
2714 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
2716 "= stop fetch_anqp operation" },
2717 { "interworking_select", wpa_cli_cmd_interworking_select, NULL,
2719 "[auto] = perform Interworking network selection" },
2720 { "interworking_connect", wpa_cli_cmd_interworking_connect,
2721 wpa_cli_complete_bss, cli_cmd_flag_none,
2722 "<BSSID> = connect using Interworking credentials" },
2723 { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
2725 "<addr> <info id>[,<info id>]... = request ANQP information" },
2726 { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
2728 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
2729 { "gas_response_get", wpa_cli_cmd_gas_response_get,
2730 wpa_cli_complete_bss, cli_cmd_flag_none,
2731 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
2732 #endif /* CONFIG_INTERWORKING */
2734 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
2736 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
2738 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
2739 wpa_cli_complete_bss, cli_cmd_flag_none,
2740 "<addr> <home realm> = get HS20 nai home realm list" },
2741 #endif /* CONFIG_HS20 */
2742 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
2744 "<0/1> = disable/enable automatic reconnection" },
2745 { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
2747 "<addr> = request TDLS discovery with <addr>" },
2748 { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
2750 "<addr> = request TDLS setup with <addr>" },
2751 { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
2753 "<addr> = tear down TDLS with <addr>" },
2754 { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
2756 "= get signal parameters" },
2757 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
2759 "= get TX/RX packet counters" },
2760 { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
2762 "= trigger IEEE 802.1X/EAPOL reauthentication" },
2763 #ifdef CONFIG_AUTOSCAN
2764 { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
2765 "[params] = Set or unset (if none) autoscan parameters" },
2766 #endif /* CONFIG_AUTOSCAN */
2768 { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
2769 "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
2770 #endif /* CONFIG_WNM */
2771 { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
2772 "<params..> = Sent unprocessed command" },
2774 { "driver", wpa_cli_cmd_driver, NULL,
2776 "<command> = driver private commands" },
2778 { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
2783 * Prints command usage, lines are padded with the specified string.
2785 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2790 printf("%s%s ", pad, cmd->cmd);
2791 for (n = 0; (c = cmd->usage[n]); n++) {
2800 static void print_help(const char *cmd)
2803 printf("commands:\n");
2804 for (n = 0; wpa_cli_commands[n].cmd; n++) {
2805 if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd))
2806 print_cmd_help(&wpa_cli_commands[n], " ");
2811 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
2813 const char *c, *delim;
2817 delim = os_strchr(cmd, ' ');
2821 len = os_strlen(cmd);
2823 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2824 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2825 return (wpa_cli_commands[n].flags &
2826 cli_cmd_flag_sensitive);
2832 static char ** wpa_list_cmd_list(void)
2837 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
2838 res = os_calloc(count, sizeof(char *));
2842 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2843 res[i] = os_strdup(wpa_cli_commands[i].cmd);
2852 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
2857 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2858 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
2859 if (wpa_cli_commands[i].completion)
2860 return wpa_cli_commands[i].completion(str,
2863 printf("\r%s\n", wpa_cli_commands[i].usage);
2873 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
2879 end = os_strchr(str, ' ');
2880 if (end == NULL || str + pos < end)
2881 return wpa_list_cmd_list();
2883 cmd = os_malloc(pos + 1);
2886 os_memcpy(cmd, str, pos);
2887 cmd[end - str] = '\0';
2888 res = wpa_cli_cmd_completion(cmd, str, pos);
2894 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
2896 struct wpa_cli_cmd *cmd, *match = NULL;
2901 cmd = wpa_cli_commands;
2903 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
2906 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
2907 /* we have an exact match */
2917 printf("Ambiguous command '%s'; possible commands:", argv[0]);
2918 cmd = wpa_cli_commands;
2920 if (os_strncasecmp(cmd->cmd, argv[0],
2921 os_strlen(argv[0])) == 0) {
2922 printf(" %s", cmd->cmd);
2928 } else if (count == 0) {
2929 printf("Unknown command '%s'\n", argv[0]);
2932 #if defined(CONFIG_P2P) && defined(ANDROID_P2P)
2933 if ( (argc >= 2) && (os_strncmp(argv[1], "interface=", 10) == 0)) {
2934 redirect_interface = os_strdup(argv[1]);
2935 ret = match->handler(ctrl, argc - 2, &argv[2]);
2939 ret = match->handler(ctrl, argc - 1, &argv[1]);
2946 static int str_match(const char *a, const char *b)
2948 return os_strncmp(a, b, os_strlen(b)) == 0;
2952 static int wpa_cli_exec(const char *program, const char *arg1,
2960 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
2961 cmd = os_malloc(len);
2964 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
2965 if (res < 0 || (size_t) res >= len) {
2969 cmd[len - 1] = '\0';
2971 if (system(cmd) < 0)
2973 #endif /* _WIN32_WCE */
2980 static void wpa_cli_action_process(const char *msg)
2983 char *copy = NULL, *id, *pos2;
2988 pos = os_strchr(pos, '>');
2995 if (str_match(pos, WPA_EVENT_CONNECTED)) {
2997 os_unsetenv("WPA_ID");
2998 os_unsetenv("WPA_ID_STR");
2999 os_unsetenv("WPA_CTRL_DIR");
3001 pos = os_strstr(pos, "[id=");
3003 copy = os_strdup(pos + 4);
3007 while (*pos2 && *pos2 != ' ')
3011 os_setenv("WPA_ID", id, 1);
3012 while (*pos2 && *pos2 != '=')
3017 while (*pos2 && *pos2 != ']')
3020 os_setenv("WPA_ID_STR", id, 1);
3024 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3026 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
3027 wpa_cli_connected = 1;
3028 wpa_cli_last_id = new_id;
3029 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
3031 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3032 if (wpa_cli_connected) {
3033 wpa_cli_connected = 0;
3034 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
3036 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3037 wpa_cli_exec(action_file, ctrl_ifname, pos);
3038 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3039 wpa_cli_exec(action_file, ctrl_ifname, pos);
3040 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3041 wpa_cli_exec(action_file, ctrl_ifname, pos);
3042 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3043 wpa_cli_exec(action_file, ctrl_ifname, pos);
3044 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3045 wpa_cli_exec(action_file, ctrl_ifname, pos);
3046 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3047 wpa_cli_exec(action_file, ctrl_ifname, pos);
3048 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3049 wpa_cli_exec(action_file, ctrl_ifname, pos);
3050 } else if (str_match(pos, AP_STA_CONNECTED)) {
3051 wpa_cli_exec(action_file, ctrl_ifname, pos);
3052 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3053 wpa_cli_exec(action_file, ctrl_ifname, pos);
3054 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3055 printf("wpa_supplicant is terminating - stop monitoring\n");
3061 #ifndef CONFIG_ANSI_C_EXTRA
3062 static void wpa_cli_action_cb(char *msg, size_t len)
3064 wpa_cli_action_process(msg);
3066 #endif /* CONFIG_ANSI_C_EXTRA */
3069 static void wpa_cli_reconnect(void)
3071 wpa_cli_close_connection();
3072 if (wpa_cli_open_connection(ctrl_ifname, 1) < 0)
3077 printf("\rConnection to wpa_supplicant re-established\n");
3083 static void cli_event(const char *str)
3085 const char *start, *s;
3087 start = os_strchr(str, '>');
3093 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3094 s = os_strchr(start, ' ');
3097 s = os_strchr(s + 1, ' ');
3100 cli_txt_list_add(&bsses, s + 1);
3104 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3105 s = os_strchr(start, ' ');
3108 s = os_strchr(s + 1, ' ');
3111 cli_txt_list_del_addr(&bsses, s + 1);
3116 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3117 s = os_strstr(start, " p2p_dev_addr=");
3120 cli_txt_list_add_addr(&p2p_peers, s + 14);
3124 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3125 s = os_strstr(start, " p2p_dev_addr=");
3128 cli_txt_list_del_addr(&p2p_peers, s + 14);
3132 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3133 s = os_strchr(start, ' ');
3136 cli_txt_list_add_word(&p2p_groups, s + 1);
3140 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3141 s = os_strchr(start, ' ');
3144 cli_txt_list_del_word(&p2p_groups, s + 1);
3147 #endif /* CONFIG_P2P */
3151 static int check_terminating(const char *msg)
3153 const char *pos = msg;
3157 pos = os_strchr(pos, '>');
3164 if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
3166 printf("\rConnection to wpa_supplicant lost - trying to "
3169 wpa_cli_attached = 0;
3170 wpa_cli_close_connection();
3178 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3180 if (ctrl_conn == NULL) {
3181 wpa_cli_reconnect();
3184 while (wpa_ctrl_pending(ctrl) > 0) {
3186 size_t len = sizeof(buf) - 1;
3187 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3190 wpa_cli_action_process(buf);
3193 if (wpa_cli_show_event(buf)) {
3195 printf("\r%s\n", buf);
3199 if (interactive && check_terminating(buf) > 0)
3203 printf("Could not read pending message.\n");
3208 if (wpa_ctrl_pending(ctrl) < 0) {
3209 printf("Connection to wpa_supplicant lost - trying to "
3211 wpa_cli_reconnect();
3217 static int tokenize_cmd(char *cmd, char *argv[])
3230 if (argc == max_args)
3233 char *pos2 = os_strrchr(pos, '"');
3237 while (*pos != '\0' && *pos != ' ')
3247 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3249 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3250 printf("Connection to wpa_supplicant lost - trying to "
3252 wpa_cli_close_connection();
3255 wpa_cli_reconnect();
3256 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3260 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3262 wpa_cli_recv_pending(mon_conn, 0);
3266 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3268 char *argv[max_args];
3270 argc = tokenize_cmd(cmd, argv);
3272 wpa_request(ctrl_conn, argc, argv);
3276 static void wpa_cli_edit_eof_cb(void *ctx)
3282 static int warning_displayed = 0;
3283 static char *hfile = NULL;
3284 static int edit_started = 0;
3286 static void start_edit(void)
3291 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3292 ps = wpa_ctrl_get_remote_ifname(ctrl_conn);
3293 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3295 home = getenv("HOME");
3297 const char *fname = ".wpa_cli_history";
3298 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3299 hfile = os_malloc(hfile_len);
3301 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3304 if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3305 wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
3311 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3315 static void try_connection(void *eloop_ctx, void *timeout_ctx)
3317 if (ctrl_ifname == NULL)
3318 ctrl_ifname = wpa_cli_get_default_ifname();
3320 if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3321 if (!warning_displayed) {
3322 printf("Could not connect to wpa_supplicant: "
3323 "%s - re-trying\n", ctrl_ifname);
3324 warning_displayed = 1;
3326 eloop_register_timeout(1, 0, try_connection, NULL, NULL);
3330 if (warning_displayed)
3331 printf("Connection established.\n");
3337 static void wpa_cli_interactive(void)
3339 printf("\nInteractive mode\n\n");
3341 eloop_register_timeout(0, 0, try_connection, NULL, NULL);
3343 eloop_cancel_timeout(try_connection, NULL, NULL);
3345 cli_txt_list_flush(&p2p_peers);
3346 cli_txt_list_flush(&p2p_groups);
3347 cli_txt_list_flush(&bsses);
3349 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3351 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3352 wpa_cli_close_connection();
3356 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3358 #ifdef CONFIG_ANSI_C_EXTRA
3359 /* TODO: ANSI C version(?) */
3360 printf("Action processing not supported in ANSI C build.\n");
3361 #else /* CONFIG_ANSI_C_EXTRA */
3365 char buf[256]; /* note: large enough to fit in unsolicited messages */
3368 fd = wpa_ctrl_get_fd(ctrl);
3370 while (!wpa_cli_quit) {
3373 tv.tv_sec = ping_interval;
3375 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3376 if (res < 0 && errno != EINTR) {
3381 if (FD_ISSET(fd, &rfds))
3382 wpa_cli_recv_pending(ctrl, 1);
3384 /* verify that connection is still working */
3385 len = sizeof(buf) - 1;
3386 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3387 wpa_cli_action_cb) < 0 ||
3388 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3389 printf("wpa_supplicant did not reply to PING "
3390 "command - exiting\n");
3395 #endif /* CONFIG_ANSI_C_EXTRA */
3399 static void wpa_cli_cleanup(void)
3401 wpa_cli_close_connection();
3403 os_daemonize_terminate(pid_file);
3405 os_program_deinit();
3409 static void wpa_cli_terminate(int sig, void *ctx)
3415 static char * wpa_cli_get_default_ifname(void)
3417 char *ifname = NULL;
3419 #ifdef CONFIG_CTRL_IFACE_UNIX
3420 struct dirent *dent;
3421 DIR *dir = opendir(ctrl_iface_dir);
3424 char ifprop[PROPERTY_VALUE_MAX];
3425 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3426 ifname = os_strdup(ifprop);
3427 printf("Using interface '%s'\n", ifname);
3430 #endif /* ANDROID */
3433 while ((dent = readdir(dir))) {
3434 #ifdef _DIRENT_HAVE_D_TYPE
3436 * Skip the file if it is not a socket. Also accept
3437 * DT_UNKNOWN (0) in case the C library or underlying
3438 * file system does not support d_type.
3440 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3442 #endif /* _DIRENT_HAVE_D_TYPE */
3443 if (os_strcmp(dent->d_name, ".") == 0 ||
3444 os_strcmp(dent->d_name, "..") == 0)
3446 printf("Selected interface '%s'\n", dent->d_name);
3447 ifname = os_strdup(dent->d_name);
3451 #endif /* CONFIG_CTRL_IFACE_UNIX */
3453 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3454 char buf[2048], *pos;
3456 struct wpa_ctrl *ctrl;
3459 ctrl = wpa_ctrl_open(NULL);
3463 len = sizeof(buf) - 1;
3464 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3467 pos = os_strchr(buf, '\n');
3470 ifname = os_strdup(buf);
3472 wpa_ctrl_close(ctrl);
3473 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3479 int main(int argc, char *argv[])
3484 const char *global = NULL;
3486 if (os_program_init())
3490 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3495 action_file = optarg;
3504 ping_interval = atoi(optarg);
3510 printf("%s\n", wpa_cli_version);
3513 os_free(ctrl_ifname);
3514 ctrl_ifname = os_strdup(optarg);
3517 ctrl_iface_dir = optarg;
3528 interactive = (argc == optind) && (action_file == NULL);
3531 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3537 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3538 ctrl_conn = wpa_ctrl_open(NULL);
3539 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3540 ctrl_conn = wpa_ctrl_open(global);
3541 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3542 if (ctrl_conn == NULL) {
3543 fprintf(stderr, "Failed to connect to wpa_supplicant "
3544 "global interface: %s error: %s\n",
3545 global, strerror(errno));
3550 eloop_register_signal_terminate(wpa_cli_terminate, NULL);
3552 if (ctrl_ifname == NULL)
3553 ctrl_ifname = wpa_cli_get_default_ifname();
3556 wpa_cli_interactive();
3559 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3560 fprintf(stderr, "Failed to connect to non-global "
3561 "ctrl_ifname: %s error: %s\n",
3562 ctrl_ifname, strerror(errno));
3567 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3568 wpa_cli_attached = 1;
3570 printf("Warning: Failed to attach to "
3571 "wpa_supplicant.\n");
3576 if (daemonize && os_daemonize(pid_file))
3580 wpa_cli_action(ctrl_conn);
3582 ret = wpa_request(ctrl_conn, argc - optind,
3586 os_free(ctrl_ifname);
3593 #else /* CONFIG_CTRL_IFACE */
3594 int main(int argc, char *argv[])
3596 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3599 #endif /* CONFIG_CTRL_IFACE */