2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
11 #ifdef CONFIG_CTRL_IFACE
13 #ifdef CONFIG_CTRL_IFACE_UNIX
15 #endif /* CONFIG_CTRL_IFACE_UNIX */
17 #include "common/wpa_ctrl.h"
18 #include "utils/common.h"
19 #include "utils/eloop.h"
20 #include "utils/edit.h"
21 #include "utils/list.h"
22 #include "common/version.h"
23 #include "common/ieee802_11_defs.h"
25 #include <cutils/properties.h>
29 static const char *wpa_cli_version =
30 "wpa_cli v" VERSION_STR "\n"
31 "Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> and contributors";
34 static const char *wpa_cli_license =
35 "This software may be distributed under the terms of the BSD license.\n"
36 "See README for more details.\n";
38 static const char *wpa_cli_full_license =
39 "This software may be distributed under the terms of the BSD license.\n"
41 "Redistribution and use in source and binary forms, with or without\n"
42 "modification, are permitted provided that the following conditions are\n"
45 "1. Redistributions of source code must retain the above copyright\n"
46 " notice, this list of conditions and the following disclaimer.\n"
48 "2. Redistributions in binary form must reproduce the above copyright\n"
49 " notice, this list of conditions and the following disclaimer in the\n"
50 " documentation and/or other materials provided with the distribution.\n"
52 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
53 " names of its contributors may be used to endorse or promote products\n"
54 " derived from this software without specific prior written permission.\n"
56 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
57 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
58 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
59 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
60 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
61 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
62 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
63 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
64 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
65 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
66 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
69 static struct wpa_ctrl *ctrl_conn;
70 static struct wpa_ctrl *mon_conn;
71 static int wpa_cli_quit = 0;
72 static int wpa_cli_attached = 0;
73 static int wpa_cli_connected = 0;
74 static int wpa_cli_last_id = 0;
75 #ifndef CONFIG_CTRL_IFACE_DIR
76 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
77 #endif /* CONFIG_CTRL_IFACE_DIR */
78 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
79 static char *ctrl_ifname = NULL;
80 static const char *pid_file = NULL;
81 static const char *action_file = NULL;
82 static int ping_interval = 5;
83 static int interactive = 0;
85 struct cli_txt_entry {
90 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
91 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
92 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
95 static void print_help(void);
96 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
99 static void usage(void)
101 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
102 "[-a<action file>] \\\n"
103 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
105 " -h = help (show this usage text)\n"
106 " -v = shown version information\n"
107 " -a = run in daemon mode executing the action file based on "
110 " -B = run a daemon in the background\n"
111 " default path: " CONFIG_CTRL_IFACE_DIR "\n"
112 " default interface: first interface found in socket path\n");
117 static void cli_txt_list_free(struct cli_txt_entry *e)
119 dl_list_del(&e->list);
125 static void cli_txt_list_flush(struct dl_list *list)
127 struct cli_txt_entry *e;
128 while ((e = dl_list_first(list, struct cli_txt_entry, list)))
129 cli_txt_list_free(e);
133 static struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list,
136 struct cli_txt_entry *e;
137 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
138 if (os_strcmp(e->txt, txt) == 0)
145 static void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
147 struct cli_txt_entry *e;
148 e = cli_txt_list_get(txt_list, txt);
150 cli_txt_list_free(e);
154 static void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt)
158 if (hwaddr_aton(txt, addr) < 0)
160 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
161 cli_txt_list_del(txt_list, buf);
166 static void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt)
170 end = os_strchr(txt, ' ');
172 end = txt + os_strlen(txt);
173 buf = os_malloc(end - txt + 1);
176 os_memcpy(buf, txt, end - txt);
177 buf[end - txt] = '\0';
178 cli_txt_list_del(txt_list, buf);
181 #endif /* CONFIG_P2P */
184 static int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
186 struct cli_txt_entry *e;
187 e = cli_txt_list_get(txt_list, txt);
190 e = os_zalloc(sizeof(*e));
193 e->txt = os_strdup(txt);
194 if (e->txt == NULL) {
198 dl_list_add(txt_list, &e->list);
204 static int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
208 if (hwaddr_aton(txt, addr) < 0)
210 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
211 return cli_txt_list_add(txt_list, buf);
215 static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt)
220 end = os_strchr(txt, ' ');
222 end = txt + os_strlen(txt);
223 buf = os_malloc(end - txt + 1);
226 os_memcpy(buf, txt, end - txt);
227 buf[end - txt] = '\0';
228 ret = cli_txt_list_add(txt_list, buf);
232 #endif /* CONFIG_P2P */
235 static char ** cli_txt_list_array(struct dl_list *txt_list)
237 unsigned int i, count = dl_list_len(txt_list);
239 struct cli_txt_entry *e;
241 res = os_zalloc((count + 1) * sizeof(char *));
246 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
247 res[i] = os_strdup(e->txt);
257 static int get_cmd_arg_num(const char *str, int pos)
261 for (i = 0; i <= pos; i++) {
264 while (i <= pos && str[i] != ' ')
275 static int str_starts(const char *src, const char *match)
277 return os_strncmp(src, match, os_strlen(match)) == 0;
281 static int wpa_cli_show_event(const char *event)
285 start = os_strchr(event, '>');
291 * Skip BSS added/removed events since they can be relatively frequent
292 * and are likely of not much use for an interactive user.
294 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
295 str_starts(start, WPA_EVENT_BSS_REMOVED))
302 static int wpa_cli_open_connection(const char *ifname, int attach)
304 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
305 ctrl_conn = wpa_ctrl_open(ifname);
306 if (ctrl_conn == NULL)
309 if (attach && interactive)
310 mon_conn = wpa_ctrl_open(ifname);
313 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
321 if (access(ctrl_iface_dir, F_OK) < 0) {
322 cfile = os_strdup(ifname);
329 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
330 cfile = os_malloc(flen);
333 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
335 if (res < 0 || res >= flen) {
341 ctrl_conn = wpa_ctrl_open(cfile);
342 if (ctrl_conn == NULL) {
347 if (attach && interactive)
348 mon_conn = wpa_ctrl_open(cfile);
352 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
355 if (wpa_ctrl_attach(mon_conn) == 0) {
356 wpa_cli_attached = 1;
358 eloop_register_read_sock(
359 wpa_ctrl_get_fd(mon_conn),
360 wpa_cli_mon_receive, NULL, NULL);
362 printf("Warning: Failed to attach to "
363 "wpa_supplicant.\n");
372 static void wpa_cli_close_connection(void)
374 if (ctrl_conn == NULL)
377 if (wpa_cli_attached) {
378 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
379 wpa_cli_attached = 0;
381 wpa_ctrl_close(ctrl_conn);
384 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
385 wpa_ctrl_close(mon_conn);
391 static void wpa_cli_msg_cb(char *msg, size_t len)
397 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
403 if (ctrl_conn == NULL) {
404 printf("Not connected to wpa_supplicant - command dropped.\n");
407 len = sizeof(buf) - 1;
408 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
411 printf("'%s' command timed out.\n", cmd);
413 } else if (ret < 0) {
414 printf("'%s' command failed.\n", cmd);
420 if (interactive && len > 0 && buf[len - 1] != '\n')
427 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
429 return _wpa_ctrl_command(ctrl, cmd, 1);
433 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
435 if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
436 return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
437 if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
438 return wpa_ctrl_command(ctrl, "STATUS-WPS");
439 return wpa_ctrl_command(ctrl, "STATUS");
443 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
445 return wpa_ctrl_command(ctrl, "PING");
449 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
451 return wpa_ctrl_command(ctrl, "RELOG");
455 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
461 ret = os_snprintf(cmd, sizeof(cmd), "NOTE %s", argv[0]);
462 if (ret < 0 || (size_t) ret >= sizeof(cmd))
464 return wpa_ctrl_command(ctrl, cmd);
468 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
470 return wpa_ctrl_command(ctrl, "MIB");
474 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
476 return wpa_ctrl_command(ctrl, "PMKSA");
480 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
487 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
489 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
494 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
503 static void wpa_cli_show_variables(void)
505 printf("set variables:\n"
506 " EAPOL::heldPeriod (EAPOL state machine held period, "
508 " EAPOL::authPeriod (EAPOL state machine authentication "
509 "period, in seconds)\n"
510 " EAPOL::startPeriod (EAPOL state machine start period, in "
512 " EAPOL::maxStart (EAPOL state machine maximum start "
514 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
516 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
517 " threshold\n\tpercentage)\n"
518 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
519 "security\n\tassociation in seconds)\n");
523 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
529 wpa_cli_show_variables();
533 if (argc != 1 && argc != 2) {
534 printf("Invalid SET command: needs two arguments (variable "
535 "name and value)\n");
540 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
542 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s",
544 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
545 printf("Too long SET command.\n");
548 return wpa_ctrl_command(ctrl, cmd);
552 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
558 printf("Invalid GET command: need one argument (variable "
563 res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
564 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
565 printf("Too long GET command.\n");
568 return wpa_ctrl_command(ctrl, cmd);
572 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
574 return wpa_ctrl_command(ctrl, "LOGOFF");
578 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
580 return wpa_ctrl_command(ctrl, "LOGON");
584 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
587 return wpa_ctrl_command(ctrl, "REASSOCIATE");
591 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
598 printf("Invalid PREAUTH command: needs one argument "
603 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
604 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
605 printf("Too long PREAUTH command.\n");
608 return wpa_ctrl_command(ctrl, cmd);
612 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
618 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
622 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
623 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
624 printf("Too long AP_SCAN command.\n");
627 return wpa_ctrl_command(ctrl, cmd);
631 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
638 printf("Invalid SCAN_INTERVAL command: needs one argument "
639 "scan_interval value)\n");
642 res = os_snprintf(cmd, sizeof(cmd), "SCAN_INTERVAL %s", argv[0]);
643 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
644 printf("Too long SCAN_INTERVAL command.\n");
647 return wpa_ctrl_command(ctrl, cmd);
651 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
658 printf("Invalid BSS_EXPIRE_AGE command: needs one argument "
659 "(bss_expire_age value)\n");
662 res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_AGE %s", argv[0]);
663 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
664 printf("Too long BSS_EXPIRE_AGE command.\n");
667 return wpa_ctrl_command(ctrl, cmd);
671 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
678 printf("Invalid BSS_EXPIRE_COUNT command: needs one argument "
679 "(bss_expire_count value)\n");
682 res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_COUNT %s", argv[0]);
683 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
684 printf("Too long BSS_EXPIRE_COUNT command.\n");
687 return wpa_ctrl_command(ctrl, cmd);
691 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
698 printf("Invalid STKSTART command: needs one argument "
699 "(Peer STA MAC address)\n");
703 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
704 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
705 printf("Too long STKSTART command.\n");
708 return wpa_ctrl_command(ctrl, cmd);
712 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
718 printf("Invalid FT_DS command: needs one argument "
719 "(Target AP MAC address)\n");
723 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
724 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
725 printf("Too long FT_DS command.\n");
728 return wpa_ctrl_command(ctrl, cmd);
732 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
739 return wpa_ctrl_command(ctrl, "WPS_PBC");
743 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
744 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
745 printf("Too long WPS_PBC command.\n");
748 return wpa_ctrl_command(ctrl, cmd);
752 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
758 printf("Invalid WPS_PIN command: need one or two arguments:\n"
759 "- BSSID: use 'any' to select any\n"
760 "- PIN: optional, used only with devices that have no "
766 /* Use dynamically generated PIN (returned as reply) */
767 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
768 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
769 printf("Too long WPS_PIN command.\n");
772 return wpa_ctrl_command(ctrl, cmd);
775 /* Use hardcoded PIN from a label */
776 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
777 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
778 printf("Too long WPS_PIN command.\n");
781 return wpa_ctrl_command(ctrl, cmd);
785 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
791 if (argc != 1 && argc != 2) {
792 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
793 "- PIN to be verified\n");
798 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
801 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
803 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
804 printf("Too long WPS_CHECK_PIN command.\n");
807 return wpa_ctrl_command(ctrl, cmd);
811 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
814 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
818 #ifdef CONFIG_WPS_OOB
819 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
824 if (argc != 3 && argc != 4) {
825 printf("Invalid WPS_OOB command: need three or four "
827 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
828 "- PATH: path of OOB device like '/mnt'\n"
829 "- METHOD: OOB method 'pin-e' or 'pin-r', "
831 "- DEV_NAME: (only for NFC) device name like "
837 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
838 argv[0], argv[1], argv[2]);
840 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
841 argv[0], argv[1], argv[2], argv[3]);
842 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
843 printf("Too long WPS_OOB command.\n");
846 return wpa_ctrl_command(ctrl, cmd);
848 #endif /* CONFIG_WPS_OOB */
851 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
857 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
859 else if (argc == 5 || argc == 6) {
860 char ssid_hex[2 * 32 + 1];
861 char key_hex[2 * 64 + 1];
865 for (i = 0; i < 32; i++) {
866 if (argv[2][i] == '\0')
868 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
873 for (i = 0; i < 64; i++) {
874 if (argv[5][i] == '\0')
876 os_snprintf(&key_hex[i * 2], 3, "%02x",
881 res = os_snprintf(cmd, sizeof(cmd),
882 "WPS_REG %s %s %s %s %s %s",
883 argv[0], argv[1], ssid_hex, argv[3], argv[4],
886 printf("Invalid WPS_REG command: need two arguments:\n"
887 "- BSSID of the target AP\n"
889 printf("Alternatively, six arguments can be used to "
890 "reconfigure the AP:\n"
891 "- BSSID of the target AP\n"
894 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
895 "- new encr (NONE, WEP, TKIP, CCMP)\n"
900 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
901 printf("Too long WPS_REG command.\n");
904 return wpa_ctrl_command(ctrl, cmd);
908 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
915 printf("Invalid WPS_AP_PIN command: needs at least one "
921 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s %s",
922 argv[0], argv[1], argv[2]);
924 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s",
927 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s",
929 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
930 printf("Too long WPS_AP_PIN command.\n");
933 return wpa_ctrl_command(ctrl, cmd);
937 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
942 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
943 return wpa_ctrl_command(ctrl, cmd);
945 return wpa_ctrl_command(ctrl, "WPS_ER_START");
949 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
952 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
957 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
964 printf("Invalid WPS_ER_PIN command: need at least two "
966 "- UUID: use 'any' to select any\n"
967 "- PIN: Enrollee PIN\n"
968 "optional: - Enrollee MAC address\n");
973 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
974 argv[0], argv[1], argv[2]);
976 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
978 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
979 printf("Too long WPS_ER_PIN command.\n");
982 return wpa_ctrl_command(ctrl, cmd);
986 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
993 printf("Invalid WPS_ER_PBC command: need one argument:\n"
994 "- UUID: Specify the Enrollee\n");
998 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
1000 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1001 printf("Too long WPS_ER_PBC command.\n");
1004 return wpa_ctrl_command(ctrl, cmd);
1008 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
1015 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1016 "- UUID: specify which AP to use\n"
1021 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
1023 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1024 printf("Too long WPS_ER_LEARN command.\n");
1027 return wpa_ctrl_command(ctrl, cmd);
1031 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
1038 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1040 "- UUID: specify which AP to use\n"
1041 "- Network configuration id\n");
1045 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_SET_CONFIG %s %s",
1047 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1048 printf("Too long WPS_ER_SET_CONFIG command.\n");
1051 return wpa_ctrl_command(ctrl, cmd);
1055 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
1061 if (argc == 5 || argc == 6) {
1062 char ssid_hex[2 * 32 + 1];
1063 char key_hex[2 * 64 + 1];
1067 for (i = 0; i < 32; i++) {
1068 if (argv[2][i] == '\0')
1070 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1075 for (i = 0; i < 64; i++) {
1076 if (argv[5][i] == '\0')
1078 os_snprintf(&key_hex[i * 2], 3, "%02x",
1083 res = os_snprintf(cmd, sizeof(cmd),
1084 "WPS_ER_CONFIG %s %s %s %s %s %s",
1085 argv[0], argv[1], ssid_hex, argv[3], argv[4],
1088 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1092 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1093 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1098 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1099 printf("Too long WPS_ER_CONFIG command.\n");
1102 return wpa_ctrl_command(ctrl, cmd);
1106 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1112 printf("Invalid IBSS_RSN command: needs one argument "
1113 "(Peer STA MAC address)\n");
1117 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
1118 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1119 printf("Too long IBSS_RSN command.\n");
1122 return wpa_ctrl_command(ctrl, cmd);
1126 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1132 printf("Invalid LEVEL command: needs one argument (debug "
1136 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
1137 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1138 printf("Too long LEVEL command.\n");
1141 return wpa_ctrl_command(ctrl, cmd);
1145 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1147 char cmd[256], *pos, *end;
1151 printf("Invalid IDENTITY command: needs two arguments "
1152 "(network id and identity)\n");
1156 end = cmd + sizeof(cmd);
1158 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1160 if (ret < 0 || ret >= end - pos) {
1161 printf("Too long IDENTITY 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 IDENTITY command.\n");
1174 return wpa_ctrl_command(ctrl, cmd);
1178 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1180 char cmd[256], *pos, *end;
1184 printf("Invalid PASSWORD command: needs two arguments "
1185 "(network id and password)\n");
1189 end = cmd + sizeof(cmd);
1191 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1193 if (ret < 0 || ret >= end - pos) {
1194 printf("Too long PASSWORD command.\n");
1198 for (i = 2; i < argc; i++) {
1199 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1200 if (ret < 0 || ret >= end - pos) {
1201 printf("Too long PASSWORD command.\n");
1207 return wpa_ctrl_command(ctrl, cmd);
1211 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1214 char cmd[256], *pos, *end;
1218 printf("Invalid NEW_PASSWORD command: needs two arguments "
1219 "(network id and password)\n");
1223 end = cmd + sizeof(cmd);
1225 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1227 if (ret < 0 || ret >= end - pos) {
1228 printf("Too long NEW_PASSWORD command.\n");
1232 for (i = 2; i < argc; i++) {
1233 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1234 if (ret < 0 || ret >= end - pos) {
1235 printf("Too long NEW_PASSWORD command.\n");
1241 return wpa_ctrl_command(ctrl, cmd);
1245 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1247 char cmd[256], *pos, *end;
1251 printf("Invalid PIN command: needs two arguments "
1252 "(network id and pin)\n");
1256 end = cmd + sizeof(cmd);
1258 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1260 if (ret < 0 || ret >= end - pos) {
1261 printf("Too long PIN command.\n");
1265 for (i = 2; i < argc; i++) {
1266 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1267 if (ret < 0 || ret >= end - pos) {
1268 printf("Too long PIN command.\n");
1273 return wpa_ctrl_command(ctrl, cmd);
1277 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1279 char cmd[256], *pos, *end;
1283 printf("Invalid OTP command: needs two arguments (network "
1284 "id and password)\n");
1288 end = cmd + sizeof(cmd);
1290 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1292 if (ret < 0 || ret >= end - pos) {
1293 printf("Too long OTP command.\n");
1297 for (i = 2; i < argc; i++) {
1298 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1299 if (ret < 0 || ret >= end - pos) {
1300 printf("Too long OTP command.\n");
1306 return wpa_ctrl_command(ctrl, cmd);
1310 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1313 char cmd[256], *pos, *end;
1317 printf("Invalid PASSPHRASE command: needs two arguments "
1318 "(network id and passphrase)\n");
1322 end = cmd + sizeof(cmd);
1324 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1326 if (ret < 0 || ret >= end - pos) {
1327 printf("Too long PASSPHRASE command.\n");
1331 for (i = 2; i < argc; i++) {
1332 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1333 if (ret < 0 || ret >= end - pos) {
1334 printf("Too long PASSPHRASE command.\n");
1340 return wpa_ctrl_command(ctrl, cmd);
1344 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1346 char cmd[256], *pos, *end;
1350 printf("Invalid BSSID command: needs two arguments (network "
1355 end = cmd + sizeof(cmd);
1357 ret = os_snprintf(pos, end - pos, "BSSID");
1358 if (ret < 0 || ret >= end - pos) {
1359 printf("Too long BSSID command.\n");
1363 for (i = 0; i < argc; i++) {
1364 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1365 if (ret < 0 || ret >= end - pos) {
1366 printf("Too long BSSID command.\n");
1372 return wpa_ctrl_command(ctrl, cmd);
1376 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1378 char cmd[256], *pos, *end;
1381 end = cmd + sizeof(cmd);
1383 ret = os_snprintf(pos, end - pos, "BLACKLIST");
1384 if (ret < 0 || ret >= end - pos) {
1385 printf("Too long BLACKLIST command.\n");
1389 for (i = 0; i < argc; i++) {
1390 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1391 if (ret < 0 || ret >= end - pos) {
1392 printf("Too long BLACKLIST command.\n");
1398 return wpa_ctrl_command(ctrl, cmd);
1402 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1404 char cmd[256], *pos, *end;
1407 end = cmd + sizeof(cmd);
1409 ret = os_snprintf(pos, end - pos, "LOG_LEVEL");
1410 if (ret < 0 || ret >= end - pos) {
1411 printf("Too long LOG_LEVEL command.\n");
1415 for (i = 0; i < argc; i++) {
1416 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1417 if (ret < 0 || ret >= end - pos) {
1418 printf("Too long LOG_LEVEL command.\n");
1424 return wpa_ctrl_command(ctrl, cmd);
1428 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1431 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1435 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1442 printf("Invalid SELECT_NETWORK command: needs one argument "
1447 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1448 if (res < 0 || (size_t) res >= sizeof(cmd))
1450 cmd[sizeof(cmd) - 1] = '\0';
1452 return wpa_ctrl_command(ctrl, cmd);
1456 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1463 printf("Invalid ENABLE_NETWORK command: needs one argument "
1469 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s %s",
1472 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s",
1474 if (res < 0 || (size_t) res >= sizeof(cmd))
1476 cmd[sizeof(cmd) - 1] = '\0';
1478 return wpa_ctrl_command(ctrl, cmd);
1482 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1489 printf("Invalid DISABLE_NETWORK command: needs one argument "
1494 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1495 if (res < 0 || (size_t) res >= sizeof(cmd))
1497 cmd[sizeof(cmd) - 1] = '\0';
1499 return wpa_ctrl_command(ctrl, cmd);
1503 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1506 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1510 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1517 printf("Invalid REMOVE_NETWORK command: needs one argument "
1522 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1523 if (res < 0 || (size_t) res >= sizeof(cmd))
1525 cmd[sizeof(cmd) - 1] = '\0';
1527 return wpa_ctrl_command(ctrl, cmd);
1531 static void wpa_cli_show_network_variables(void)
1533 printf("set_network variables:\n"
1534 " ssid (network name, SSID)\n"
1535 " psk (WPA passphrase or pre-shared key)\n"
1536 " key_mgmt (key management protocol)\n"
1537 " identity (EAP identity)\n"
1538 " password (EAP password)\n"
1541 "Note: Values are entered in the same format as the "
1542 "configuration file is using,\n"
1543 "i.e., strings values need to be inside double quotation "
1545 "For example: set_network 1 ssid \"network name\"\n"
1547 "Please see wpa_supplicant.conf documentation for full list "
1548 "of\navailable variables.\n");
1552 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1559 wpa_cli_show_network_variables();
1564 printf("Invalid SET_NETWORK command: needs three arguments\n"
1565 "(network id, variable name, and value)\n");
1569 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1570 argv[0], argv[1], argv[2]);
1571 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1572 printf("Too long SET_NETWORK command.\n");
1575 return wpa_ctrl_command(ctrl, cmd);
1579 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1586 wpa_cli_show_network_variables();
1591 printf("Invalid GET_NETWORK command: needs two arguments\n"
1592 "(network id and variable name)\n");
1596 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1598 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1599 printf("Too long GET_NETWORK command.\n");
1602 return wpa_ctrl_command(ctrl, cmd);
1606 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1609 return wpa_ctrl_command(ctrl, "LIST_CREDS");
1613 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1615 return wpa_ctrl_command(ctrl, "ADD_CRED");
1619 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1626 printf("Invalid REMOVE_CRED command: needs one argument "
1631 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_CRED %s", argv[0]);
1632 if (res < 0 || (size_t) res >= sizeof(cmd))
1634 cmd[sizeof(cmd) - 1] = '\0';
1636 return wpa_ctrl_command(ctrl, cmd);
1640 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1646 printf("Invalid SET_CRED command: needs three arguments\n"
1647 "(cred id, variable name, and value)\n");
1651 res = os_snprintf(cmd, sizeof(cmd), "SET_CRED %s %s %s",
1652 argv[0], argv[1], argv[2]);
1653 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1654 printf("Too long SET_CRED command.\n");
1657 return wpa_ctrl_command(ctrl, cmd);
1661 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1664 return wpa_ctrl_command(ctrl, "DISCONNECT");
1668 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1671 return wpa_ctrl_command(ctrl, "RECONNECT");
1675 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1678 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1682 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1684 return wpa_ctrl_command(ctrl, "SCAN");
1688 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1691 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1695 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1701 printf("Invalid BSS command: need at least one argument"
1702 "(index or BSSID)\n");
1706 res = os_snprintf(cmd, sizeof(cmd), "BSS %s%s%s%s%s", argv[0],
1707 argc > 1 ? " " : "", argc > 1 ? argv[1] : "",
1708 argc > 2 ? " " : "", argc > 2 ? argv[2] : "");
1710 if (res < 0 || (size_t) res >= sizeof(cmd))
1712 cmd[sizeof(cmd) - 1] = '\0';
1714 return wpa_ctrl_command(ctrl, cmd);
1718 static char ** wpa_cli_complete_bss(const char *str, int pos)
1720 int arg = get_cmd_arg_num(str, pos);
1725 res = cli_txt_list_array(&bsses);
1733 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1739 if (argc < 1 || argc > 2) {
1740 printf("Invalid GET_CAPABILITY command: need either one or "
1745 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1746 printf("Invalid GET_CAPABILITY command: second argument, "
1747 "if any, must be 'strict'\n");
1751 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1752 (argc == 2) ? " strict" : "");
1753 if (res < 0 || (size_t) res >= sizeof(cmd))
1755 cmd[sizeof(cmd) - 1] = '\0';
1757 return wpa_ctrl_command(ctrl, cmd);
1761 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1763 printf("Available interfaces:\n");
1764 return wpa_ctrl_command(ctrl, "INTERFACES");
1768 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1771 wpa_cli_list_interfaces(ctrl);
1775 wpa_cli_close_connection();
1776 os_free(ctrl_ifname);
1777 ctrl_ifname = os_strdup(argv[0]);
1779 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1780 printf("Connected to interface '%s.\n", ctrl_ifname);
1782 printf("Could not connect to interface '%s' - re-trying\n",
1789 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1792 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1796 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1799 return wpa_ctrl_command(ctrl, "TERMINATE");
1803 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1810 printf("Invalid INTERFACE_ADD command: needs at least one "
1811 "argument (interface name)\n"
1812 "All arguments: ifname confname driver ctrl_interface "
1813 "driver_param bridge_name\n");
1818 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1819 * <driver_param>TAB<bridge_name>
1821 res = os_snprintf(cmd, sizeof(cmd),
1822 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1824 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1825 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1826 argc > 5 ? argv[5] : "");
1827 if (res < 0 || (size_t) res >= sizeof(cmd))
1829 cmd[sizeof(cmd) - 1] = '\0';
1830 return wpa_ctrl_command(ctrl, cmd);
1834 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1841 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1842 "(interface name)\n");
1846 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1847 if (res < 0 || (size_t) res >= sizeof(cmd))
1849 cmd[sizeof(cmd) - 1] = '\0';
1850 return wpa_ctrl_command(ctrl, cmd);
1854 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1857 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1862 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1866 printf("Invalid 'sta' command - exactly one argument, STA "
1867 "address, is required.\n");
1870 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1871 return wpa_ctrl_command(ctrl, buf);
1875 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1876 char *addr, size_t addr_len)
1878 char buf[4096], *pos;
1882 if (ctrl_conn == NULL) {
1883 printf("Not connected to hostapd - command dropped.\n");
1886 len = sizeof(buf) - 1;
1887 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
1890 printf("'%s' command timed out.\n", cmd);
1892 } else if (ret < 0) {
1893 printf("'%s' command failed.\n", cmd);
1898 if (os_memcmp(buf, "FAIL", 4) == 0)
1903 while (*pos != '\0' && *pos != '\n')
1906 os_strlcpy(addr, buf, addr_len);
1911 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1913 char addr[32], cmd[64];
1915 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1918 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1919 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1925 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
1930 printf("Invalid 'deauthenticate' command - exactly one "
1931 "argument, STA address, is required.\n");
1935 os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s %s",
1938 os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s", argv[0]);
1939 return wpa_ctrl_command(ctrl, buf);
1943 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
1948 printf("Invalid 'disassociate' command - exactly one "
1949 "argument, STA address, is required.\n");
1953 os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s %s",
1956 os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s", argv[0]);
1957 return wpa_ctrl_command(ctrl, buf);
1959 #endif /* CONFIG_AP */
1962 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1964 return wpa_ctrl_command(ctrl, "SUSPEND");
1968 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1970 return wpa_ctrl_command(ctrl, "RESUME");
1974 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1976 return wpa_ctrl_command(ctrl, "DROP_SA");
1980 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1986 printf("Invalid ROAM command: needs one argument "
1987 "(target AP's BSSID)\n");
1991 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1992 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1993 printf("Too long ROAM command.\n");
1996 return wpa_ctrl_command(ctrl, cmd);
2002 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
2008 return wpa_ctrl_command(ctrl, "P2P_FIND");
2011 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s %s",
2012 argv[0], argv[1], argv[2]);
2014 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
2017 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
2018 if (res < 0 || (size_t) res >= sizeof(cmd))
2020 cmd[sizeof(cmd) - 1] = '\0';
2021 return wpa_ctrl_command(ctrl, cmd);
2025 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
2028 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
2032 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
2039 printf("Invalid P2P_CONNECT command: needs at least two "
2040 "arguments (address and pbc/PIN)\n");
2045 res = os_snprintf(cmd, sizeof(cmd),
2046 "P2P_CONNECT %s %s %s %s %s",
2047 argv[0], argv[1], argv[2], argv[3],
2050 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
2051 argv[0], argv[1], argv[2], argv[3]);
2053 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
2054 argv[0], argv[1], argv[2]);
2056 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
2058 if (res < 0 || (size_t) res >= sizeof(cmd))
2060 cmd[sizeof(cmd) - 1] = '\0';
2061 return wpa_ctrl_command(ctrl, cmd);
2065 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
2067 int arg = get_cmd_arg_num(str, pos);
2072 res = cli_txt_list_array(&p2p_peers);
2080 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
2087 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
2089 res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
2090 if (res < 0 || (size_t) res >= sizeof(cmd))
2092 cmd[sizeof(cmd) - 1] = '\0';
2093 return wpa_ctrl_command(ctrl, cmd);
2097 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
2104 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
2105 "(interface name)\n");
2109 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
2110 if (res < 0 || (size_t) res >= sizeof(cmd))
2112 cmd[sizeof(cmd) - 1] = '\0';
2113 return wpa_ctrl_command(ctrl, cmd);
2117 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
2119 int arg = get_cmd_arg_num(str, pos);
2124 res = cli_txt_list_array(&p2p_groups);
2132 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
2139 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
2142 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s %s",
2145 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s",
2147 if (res < 0 || (size_t) res >= sizeof(cmd))
2149 cmd[sizeof(cmd) - 1] = '\0';
2150 return wpa_ctrl_command(ctrl, cmd);
2154 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
2160 if (argc != 2 && argc != 3) {
2161 printf("Invalid P2P_PROV_DISC command: needs at least "
2162 "two arguments, address and config method\n"
2163 "(display, keypad, or pbc) and an optional join\n");
2168 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s %s",
2169 argv[0], argv[1], argv[2]);
2171 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
2173 if (res < 0 || (size_t) res >= sizeof(cmd))
2175 cmd[sizeof(cmd) - 1] = '\0';
2176 return wpa_ctrl_command(ctrl, cmd);
2180 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
2183 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
2187 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
2193 if (argc != 2 && argc != 4) {
2194 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2195 "arguments (address and TLVs) or four arguments "
2196 "(address, \"upnp\", version, search target "
2202 res = os_snprintf(cmd, sizeof(cmd),
2203 "P2P_SERV_DISC_REQ %s %s %s %s",
2204 argv[0], argv[1], argv[2], argv[3]);
2206 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
2208 if (res < 0 || (size_t) res >= sizeof(cmd))
2210 cmd[sizeof(cmd) - 1] = '\0';
2211 return wpa_ctrl_command(ctrl, cmd);
2215 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
2216 int argc, char *argv[])
2222 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
2223 "argument (pending request identifier)\n");
2227 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
2229 if (res < 0 || (size_t) res >= sizeof(cmd))
2231 cmd[sizeof(cmd) - 1] = '\0';
2232 return wpa_ctrl_command(ctrl, cmd);
2236 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
2243 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2244 "arguments (freq, address, dialog token, and TLVs)\n");
2248 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
2249 argv[0], argv[1], argv[2], argv[3]);
2250 if (res < 0 || (size_t) res >= sizeof(cmd))
2252 cmd[sizeof(cmd) - 1] = '\0';
2253 return wpa_ctrl_command(ctrl, cmd);
2257 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
2260 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
2264 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
2265 int argc, char *argv[])
2271 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
2272 "argument (external processing: 0/1)\n");
2276 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
2278 if (res < 0 || (size_t) res >= sizeof(cmd))
2280 cmd[sizeof(cmd) - 1] = '\0';
2281 return wpa_ctrl_command(ctrl, cmd);
2285 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
2288 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
2292 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
2298 if (argc != 3 && argc != 4) {
2299 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
2305 res = os_snprintf(cmd, sizeof(cmd),
2306 "P2P_SERVICE_ADD %s %s %s %s",
2307 argv[0], argv[1], argv[2], argv[3]);
2309 res = os_snprintf(cmd, sizeof(cmd),
2310 "P2P_SERVICE_ADD %s %s %s",
2311 argv[0], argv[1], argv[2]);
2312 if (res < 0 || (size_t) res >= sizeof(cmd))
2314 cmd[sizeof(cmd) - 1] = '\0';
2315 return wpa_ctrl_command(ctrl, cmd);
2319 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2325 if (argc != 2 && argc != 3) {
2326 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2332 res = os_snprintf(cmd, sizeof(cmd),
2333 "P2P_SERVICE_DEL %s %s %s",
2334 argv[0], argv[1], argv[2]);
2336 res = os_snprintf(cmd, sizeof(cmd),
2337 "P2P_SERVICE_DEL %s %s",
2339 if (res < 0 || (size_t) res >= sizeof(cmd))
2341 cmd[sizeof(cmd) - 1] = '\0';
2342 return wpa_ctrl_command(ctrl, cmd);
2346 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2347 int argc, char *argv[])
2353 printf("Invalid P2P_REJECT command: needs one argument "
2354 "(peer address)\n");
2358 res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
2359 if (res < 0 || (size_t) res >= sizeof(cmd))
2361 cmd[sizeof(cmd) - 1] = '\0';
2362 return wpa_ctrl_command(ctrl, cmd);
2366 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2367 int argc, char *argv[])
2373 printf("Invalid P2P_INVITE command: needs at least one "
2379 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
2380 argv[0], argv[1], argv[2]);
2382 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
2385 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
2386 if (res < 0 || (size_t) res >= sizeof(cmd))
2388 cmd[sizeof(cmd) - 1] = '\0';
2389 return wpa_ctrl_command(ctrl, cmd);
2393 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2397 printf("Invalid 'p2p_peer' command - exactly one argument, "
2398 "P2P peer device address, is required.\n");
2401 os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
2402 return wpa_ctrl_command(ctrl, buf);
2406 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2408 int arg = get_cmd_arg_num(str, pos);
2413 res = cli_txt_list_array(&p2p_peers);
2421 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2422 char *addr, size_t addr_len,
2425 char buf[4096], *pos;
2429 if (ctrl_conn == NULL)
2431 len = sizeof(buf) - 1;
2432 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2435 printf("'%s' command timed out.\n", cmd);
2437 } else if (ret < 0) {
2438 printf("'%s' command failed.\n", cmd);
2443 if (os_memcmp(buf, "FAIL", 4) == 0)
2447 while (*pos != '\0' && *pos != '\n')
2450 os_strlcpy(addr, buf, addr_len);
2451 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2452 printf("%s\n", addr);
2457 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2459 char addr[32], cmd[64];
2462 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2464 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2465 addr, sizeof(addr), discovered))
2468 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2469 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2476 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2482 printf("Invalid P2P_SET command: needs two arguments (field, "
2487 res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2488 if (res < 0 || (size_t) res >= sizeof(cmd))
2490 cmd[sizeof(cmd) - 1] = '\0';
2491 return wpa_ctrl_command(ctrl, cmd);
2495 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2497 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2501 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2504 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2508 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2515 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2516 "(peer address)\n");
2520 res = os_snprintf(cmd, sizeof(cmd), "P2P_UNAUTHORIZE %s", argv[0]);
2522 if (res < 0 || (size_t) res >= sizeof(cmd))
2525 cmd[sizeof(cmd) - 1] = '\0';
2526 return wpa_ctrl_command(ctrl, cmd);
2530 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2536 if (argc != 0 && argc != 2 && argc != 4) {
2537 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2538 "(preferred duration, interval; in microsecods).\n"
2539 "Optional second pair can be used to provide "
2540 "acceptable values.\n");
2545 res = os_snprintf(cmd, sizeof(cmd),
2546 "P2P_PRESENCE_REQ %s %s %s %s",
2547 argv[0], argv[1], argv[2], argv[3]);
2549 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2552 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2553 if (res < 0 || (size_t) res >= sizeof(cmd))
2555 cmd[sizeof(cmd) - 1] = '\0';
2556 return wpa_ctrl_command(ctrl, cmd);
2560 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2566 if (argc != 0 && argc != 2) {
2567 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2568 "(availability period, availability interval; in "
2570 "Extended Listen Timing can be cancelled with this "
2571 "command when used without parameters.\n");
2576 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2579 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2580 if (res < 0 || (size_t) res >= sizeof(cmd))
2582 cmd[sizeof(cmd) - 1] = '\0';
2583 return wpa_ctrl_command(ctrl, cmd);
2586 #endif /* CONFIG_P2P */
2589 #ifdef CONFIG_INTERWORKING
2590 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2593 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2597 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2600 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2604 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2611 return wpa_ctrl_command(ctrl, "INTERWORKING_SELECT");
2613 res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_SELECT %s", argv[0]);
2614 if (res < 0 || (size_t) res >= sizeof(cmd))
2616 cmd[sizeof(cmd) - 1] = '\0';
2617 return wpa_ctrl_command(ctrl, cmd);
2621 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2628 printf("Invalid INTERWORKING_CONNECT commands: needs one "
2629 "argument (BSSID)\n");
2633 res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_CONNECT %s",
2635 if (res < 0 || (size_t) res >= sizeof(cmd))
2637 cmd[sizeof(cmd) - 1] = '\0';
2638 return wpa_ctrl_command(ctrl, cmd);
2642 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2648 printf("Invalid ANQP_GET command: needs two arguments "
2649 "(addr and info id list)\n");
2653 res = os_snprintf(cmd, sizeof(cmd), "ANQP_GET %s %s",
2655 if (res < 0 || (size_t) res >= sizeof(cmd))
2657 cmd[sizeof(cmd) - 1] = '\0';
2658 return wpa_ctrl_command(ctrl, cmd);
2660 #endif /* CONFIG_INTERWORKING */
2665 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2672 printf("Invalid HS20_ANQP_GET command: needs two arguments "
2673 "(addr and subtype list)\n");
2677 res = os_snprintf(cmd, sizeof(cmd), "HS20_ANQP_GET %s %s",
2679 if (res < 0 || (size_t) res >= sizeof(cmd))
2681 cmd[sizeof(cmd) - 1] = '\0';
2682 return wpa_ctrl_command(ctrl, cmd);
2686 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2693 printf("Command needs one or two arguments (dst mac addr and "
2694 "optional home realm)\n");
2699 res = os_snprintf(cmd, sizeof(cmd),
2700 "HS20_GET_NAI_HOME_REALM_LIST %s",
2703 res = os_snprintf(cmd, sizeof(cmd),
2704 "HS20_GET_NAI_HOME_REALM_LIST %s %s",
2706 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2707 printf("Too long command.\n");
2711 return wpa_ctrl_command(ctrl, cmd);
2714 #endif /* CONFIG_HS20 */
2717 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2724 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2725 "(0/1 = disable/enable automatic reconnection)\n");
2728 res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2729 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2730 printf("Too long STA_AUTOCONNECT command.\n");
2733 return wpa_ctrl_command(ctrl, cmd);
2737 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2744 printf("Invalid TDLS_DISCOVER command: needs one argument "
2745 "(Peer STA MAC address)\n");
2749 res = os_snprintf(cmd, sizeof(cmd), "TDLS_DISCOVER %s", argv[0]);
2750 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2751 printf("Too long TDLS_DISCOVER command.\n");
2754 return wpa_ctrl_command(ctrl, cmd);
2758 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2765 printf("Invalid TDLS_SETUP command: needs one argument "
2766 "(Peer STA MAC address)\n");
2770 res = os_snprintf(cmd, sizeof(cmd), "TDLS_SETUP %s", argv[0]);
2771 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2772 printf("Too long TDLS_SETUP command.\n");
2775 return wpa_ctrl_command(ctrl, cmd);
2779 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2786 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2787 "(Peer STA MAC address)\n");
2791 res = os_snprintf(cmd, sizeof(cmd), "TDLS_TEARDOWN %s", argv[0]);
2792 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2793 printf("Too long TDLS_TEARDOWN command.\n");
2796 return wpa_ctrl_command(ctrl, cmd);
2800 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2803 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2807 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2810 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2814 enum wpa_cli_cmd_flags {
2815 cli_cmd_flag_none = 0x00,
2816 cli_cmd_flag_sensitive = 0x01
2819 struct wpa_cli_cmd {
2821 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2822 enum wpa_cli_cmd_flags flags;
2826 static struct wpa_cli_cmd wpa_cli_commands[] = {
2827 { "status", wpa_cli_cmd_status,
2829 "[verbose] = get current WPA/EAPOL/EAP status" },
2830 { "ping", wpa_cli_cmd_ping,
2832 "= pings wpa_supplicant" },
2833 { "relog", wpa_cli_cmd_relog,
2835 "= re-open log-file (allow rolling logs)" },
2836 { "note", wpa_cli_cmd_note,
2838 "<text> = add a note to wpa_supplicant debug log" },
2839 { "mib", wpa_cli_cmd_mib,
2841 "= get MIB variables (dot1x, dot11)" },
2842 { "help", wpa_cli_cmd_help,
2844 "= show this usage help" },
2845 { "interface", wpa_cli_cmd_interface,
2847 "[ifname] = show interfaces/select interface" },
2848 { "level", wpa_cli_cmd_level,
2850 "<debug level> = change debug level" },
2851 { "license", wpa_cli_cmd_license,
2853 "= show full wpa_cli license" },
2854 { "quit", wpa_cli_cmd_quit,
2857 { "set", wpa_cli_cmd_set,
2859 "= set variables (shows list of variables when run without "
2861 { "get", wpa_cli_cmd_get,
2863 "<name> = get information" },
2864 { "logon", wpa_cli_cmd_logon,
2866 "= IEEE 802.1X EAPOL state machine logon" },
2867 { "logoff", wpa_cli_cmd_logoff,
2869 "= IEEE 802.1X EAPOL state machine logoff" },
2870 { "pmksa", wpa_cli_cmd_pmksa,
2872 "= show PMKSA cache" },
2873 { "reassociate", wpa_cli_cmd_reassociate,
2875 "= force reassociation" },
2876 { "preauthenticate", wpa_cli_cmd_preauthenticate,
2878 "<BSSID> = force preauthentication" },
2879 { "identity", wpa_cli_cmd_identity,
2881 "<network id> <identity> = configure identity for an SSID" },
2882 { "password", wpa_cli_cmd_password,
2883 cli_cmd_flag_sensitive,
2884 "<network id> <password> = configure password for an SSID" },
2885 { "new_password", wpa_cli_cmd_new_password,
2886 cli_cmd_flag_sensitive,
2887 "<network id> <password> = change password for an SSID" },
2888 { "pin", wpa_cli_cmd_pin,
2889 cli_cmd_flag_sensitive,
2890 "<network id> <pin> = configure pin for an SSID" },
2891 { "otp", wpa_cli_cmd_otp,
2892 cli_cmd_flag_sensitive,
2893 "<network id> <password> = configure one-time-password for an SSID"
2895 { "passphrase", wpa_cli_cmd_passphrase,
2896 cli_cmd_flag_sensitive,
2897 "<network id> <passphrase> = configure private key passphrase\n"
2899 { "bssid", wpa_cli_cmd_bssid,
2901 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2902 { "blacklist", wpa_cli_cmd_blacklist,
2904 "<BSSID> = add a BSSID to the blacklist\n"
2905 "blacklist clear = clear the blacklist\n"
2906 "blacklist = display the blacklist" },
2907 { "log_level", wpa_cli_cmd_log_level,
2909 "<level> [<timestamp>] = update the log level/timestamp\n"
2910 "log_level = display the current log level and log options" },
2911 { "list_networks", wpa_cli_cmd_list_networks,
2913 "= list configured networks" },
2914 { "select_network", wpa_cli_cmd_select_network,
2916 "<network id> = select a network (disable others)" },
2917 { "enable_network", wpa_cli_cmd_enable_network,
2919 "<network id> = enable a network" },
2920 { "disable_network", wpa_cli_cmd_disable_network,
2922 "<network id> = disable a network" },
2923 { "add_network", wpa_cli_cmd_add_network,
2925 "= add a network" },
2926 { "remove_network", wpa_cli_cmd_remove_network,
2928 "<network id> = remove a network" },
2929 { "set_network", wpa_cli_cmd_set_network,
2930 cli_cmd_flag_sensitive,
2931 "<network id> <variable> <value> = set network variables (shows\n"
2932 " list of variables when run without arguments)" },
2933 { "get_network", wpa_cli_cmd_get_network,
2935 "<network id> <variable> = get network variables" },
2936 { "list_creds", wpa_cli_cmd_list_creds,
2938 "= list configured credentials" },
2939 { "add_cred", wpa_cli_cmd_add_cred,
2941 "= add a credential" },
2942 { "remove_cred", wpa_cli_cmd_remove_cred,
2944 "<cred id> = remove a credential" },
2945 { "set_cred", wpa_cli_cmd_set_cred,
2946 cli_cmd_flag_sensitive,
2947 "<cred id> <variable> <value> = set credential variables" },
2948 { "save_config", wpa_cli_cmd_save_config,
2950 "= save the current configuration" },
2951 { "disconnect", wpa_cli_cmd_disconnect,
2953 "= disconnect and wait for reassociate/reconnect command before\n"
2955 { "reconnect", wpa_cli_cmd_reconnect,
2957 "= like reassociate, but only takes effect if already disconnected"
2959 { "scan", wpa_cli_cmd_scan,
2961 "= request new BSS scan" },
2962 { "scan_results", wpa_cli_cmd_scan_results,
2964 "= get latest scan results" },
2965 { "bss", wpa_cli_cmd_bss,
2967 "<<idx> | <bssid>> = get detailed scan result info" },
2968 { "get_capability", wpa_cli_cmd_get_capability,
2970 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2971 { "reconfigure", wpa_cli_cmd_reconfigure,
2973 "= force wpa_supplicant to re-read its configuration file" },
2974 { "terminate", wpa_cli_cmd_terminate,
2976 "= terminate wpa_supplicant" },
2977 { "interface_add", wpa_cli_cmd_interface_add,
2979 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2980 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2982 { "interface_remove", wpa_cli_cmd_interface_remove,
2984 "<ifname> = removes the interface" },
2985 { "interface_list", wpa_cli_cmd_interface_list,
2987 "= list available interfaces" },
2988 { "ap_scan", wpa_cli_cmd_ap_scan,
2990 "<value> = set ap_scan parameter" },
2991 { "scan_interval", wpa_cli_cmd_scan_interval,
2993 "<value> = set scan_interval parameter (in seconds)" },
2994 { "bss_expire_age", wpa_cli_cmd_bss_expire_age,
2996 "<value> = set BSS expiration age parameter" },
2997 { "bss_expire_count", wpa_cli_cmd_bss_expire_count,
2999 "<value> = set BSS expiration scan count parameter" },
3000 { "stkstart", wpa_cli_cmd_stkstart,
3002 "<addr> = request STK negotiation with <addr>" },
3003 { "ft_ds", wpa_cli_cmd_ft_ds,
3005 "<addr> = request over-the-DS FT with <addr>" },
3006 { "wps_pbc", wpa_cli_cmd_wps_pbc,
3008 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
3009 { "wps_pin", wpa_cli_cmd_wps_pin,
3010 cli_cmd_flag_sensitive,
3011 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
3013 { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
3014 cli_cmd_flag_sensitive,
3015 "<PIN> = verify PIN checksum" },
3016 { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
3017 "Cancels the pending WPS operation" },
3018 #ifdef CONFIG_WPS_OOB
3019 { "wps_oob", wpa_cli_cmd_wps_oob,
3020 cli_cmd_flag_sensitive,
3021 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
3022 #endif /* CONFIG_WPS_OOB */
3023 { "wps_reg", wpa_cli_cmd_wps_reg,
3024 cli_cmd_flag_sensitive,
3025 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
3026 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin,
3027 cli_cmd_flag_sensitive,
3028 "[params..] = enable/disable AP PIN" },
3029 { "wps_er_start", wpa_cli_cmd_wps_er_start,
3031 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
3032 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
3034 "= stop Wi-Fi Protected Setup External Registrar" },
3035 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
3036 cli_cmd_flag_sensitive,
3037 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
3038 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
3040 "<UUID> = accept an Enrollee PBC using External Registrar" },
3041 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
3042 cli_cmd_flag_sensitive,
3043 "<UUID> <PIN> = learn AP configuration" },
3044 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
3046 "<UUID> <network id> = set AP configuration for enrolling" },
3047 { "wps_er_config", wpa_cli_cmd_wps_er_config,
3048 cli_cmd_flag_sensitive,
3049 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
3050 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
3052 "<addr> = request RSN authentication with <addr> in IBSS" },
3054 { "sta", wpa_cli_cmd_sta,
3056 "<addr> = get information about an associated station (AP)" },
3057 { "all_sta", wpa_cli_cmd_all_sta,
3059 "= get information about all associated stations (AP)" },
3060 { "deauthenticate", wpa_cli_cmd_deauthenticate,
3062 "<addr> = deauthenticate a station" },
3063 { "disassociate", wpa_cli_cmd_disassociate,
3065 "<addr> = disassociate a station" },
3066 #endif /* CONFIG_AP */
3067 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
3068 "= notification of suspend/hibernate" },
3069 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
3070 "= notification of resume/thaw" },
3071 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
3072 "= drop SA without deauth/disassoc (test command)" },
3073 { "roam", wpa_cli_cmd_roam,
3075 "<addr> = roam to the specified BSS" },
3077 { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
3078 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
3079 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
3080 "= stop P2P Devices search" },
3081 { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
3082 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
3083 { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
3084 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
3085 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
3086 "<ifname> = remove P2P group interface (terminate group if GO)" },
3087 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
3088 "= add a new P2P group (local end as GO)" },
3089 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
3090 "<addr> <method> = request provisioning discovery" },
3091 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
3093 "= get the passphrase for a group (GO only)" },
3094 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
3096 "<addr> <TLVs> = schedule service discovery request" },
3097 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
3099 "<id> = cancel pending service discovery request" },
3100 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
3102 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
3103 { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
3105 "= indicate change in local services" },
3106 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
3108 "<external> = set external processing of service discovery" },
3109 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
3111 "= remove all stored service entries" },
3112 { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
3114 "<bonjour|upnp> <query|version> <response|service> = add a local "
3116 { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
3118 "<bonjour|upnp> <query|version> [|service] = remove a local "
3120 { "p2p_reject", wpa_cli_cmd_p2p_reject,
3122 "<addr> = reject connection attempts from a specific peer" },
3123 { "p2p_invite", wpa_cli_cmd_p2p_invite,
3125 "<cmd> [peer=addr] = invite peer" },
3126 { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
3127 "[discovered] = list known (optionally, only fully discovered) P2P "
3129 { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
3130 "<address> = show information about known P2P peer" },
3131 { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
3132 "<field> <value> = set a P2P parameter" },
3133 { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
3134 "= flush P2P state" },
3135 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
3136 "= cancel P2P group formation" },
3137 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none,
3138 "<address> = unauthorize a peer" },
3139 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
3140 "[<duration> <interval>] [<duration> <interval>] = request GO "
3142 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
3143 "[<period> <interval>] = set extended listen timing" },
3144 #endif /* CONFIG_P2P */
3146 #ifdef CONFIG_INTERWORKING
3147 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, cli_cmd_flag_none,
3148 "= fetch ANQP information for all APs" },
3149 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, cli_cmd_flag_none,
3150 "= stop fetch_anqp operation" },
3151 { "interworking_select", wpa_cli_cmd_interworking_select,
3153 "[auto] = perform Interworking network selection" },
3154 { "interworking_connect", wpa_cli_cmd_interworking_connect,
3156 "<BSSID> = connect using Interworking credentials" },
3157 { "anqp_get", wpa_cli_cmd_anqp_get, cli_cmd_flag_none,
3158 "<addr> <info id>[,<info id>]... = request ANQP information" },
3159 #endif /* CONFIG_INTERWORKING */
3161 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, cli_cmd_flag_none,
3162 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
3164 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
3166 "<addr> <home realm> = get HS20 nai home realm list" },
3167 #endif /* CONFIG_HS20 */
3168 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
3169 "<0/1> = disable/enable automatic reconnection" },
3170 { "tdls_discover", wpa_cli_cmd_tdls_discover,
3172 "<addr> = request TDLS discovery with <addr>" },
3173 { "tdls_setup", wpa_cli_cmd_tdls_setup,
3175 "<addr> = request TDLS setup with <addr>" },
3176 { "tdls_teardown", wpa_cli_cmd_tdls_teardown,
3178 "<addr> = tear down TDLS with <addr>" },
3179 { "signal_poll", wpa_cli_cmd_signal_poll,
3181 "= get signal parameters" },
3182 { "reauthenticate", wpa_cli_cmd_reauthenticate, cli_cmd_flag_none,
3183 "= trigger IEEE 802.1X/EAPOL reauthentication" },
3184 { NULL, NULL, cli_cmd_flag_none, NULL }
3189 * Prints command usage, lines are padded with the specified string.
3191 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
3196 printf("%s%s ", pad, cmd->cmd);
3197 for (n = 0; (c = cmd->usage[n]); n++) {
3206 static void print_help(void)
3209 printf("commands:\n");
3210 for (n = 0; wpa_cli_commands[n].cmd; n++)
3211 print_cmd_help(&wpa_cli_commands[n], " ");
3215 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
3217 const char *c, *delim;
3221 delim = os_strchr(cmd, ' ');
3225 len = os_strlen(cmd);
3227 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
3228 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
3229 return (wpa_cli_commands[n].flags &
3230 cli_cmd_flag_sensitive);
3236 static char ** wpa_list_cmd_list(void)
3241 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
3242 res = os_zalloc(count * sizeof(char *));
3246 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3247 res[i] = os_strdup(wpa_cli_commands[i].cmd);
3256 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
3261 if (os_strcasecmp(cmd, "bss") == 0)
3262 return wpa_cli_complete_bss(str, pos);
3264 if (os_strcasecmp(cmd, "p2p_connect") == 0)
3265 return wpa_cli_complete_p2p_connect(str, pos);
3266 if (os_strcasecmp(cmd, "p2p_peer") == 0)
3267 return wpa_cli_complete_p2p_peer(str, pos);
3268 if (os_strcasecmp(cmd, "p2p_group_remove") == 0)
3269 return wpa_cli_complete_p2p_group_remove(str, pos);
3270 #endif /* CONFIG_P2P */
3272 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3273 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
3275 printf("\r%s\n", wpa_cli_commands[i].usage);
3285 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
3291 end = os_strchr(str, ' ');
3292 if (end == NULL || str + pos < end)
3293 return wpa_list_cmd_list();
3295 cmd = os_malloc(pos + 1);
3298 os_memcpy(cmd, str, pos);
3299 cmd[end - str] = '\0';
3300 res = wpa_cli_cmd_completion(cmd, str, pos);
3306 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3308 struct wpa_cli_cmd *cmd, *match = NULL;
3313 cmd = wpa_cli_commands;
3315 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3318 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3319 /* we have an exact match */
3329 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3330 cmd = wpa_cli_commands;
3332 if (os_strncasecmp(cmd->cmd, argv[0],
3333 os_strlen(argv[0])) == 0) {
3334 printf(" %s", cmd->cmd);
3340 } else if (count == 0) {
3341 printf("Unknown command '%s'\n", argv[0]);
3344 ret = match->handler(ctrl, argc - 1, &argv[1]);
3351 static int str_match(const char *a, const char *b)
3353 return os_strncmp(a, b, os_strlen(b)) == 0;
3357 static int wpa_cli_exec(const char *program, const char *arg1,
3365 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
3366 cmd = os_malloc(len);
3369 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
3370 if (res < 0 || (size_t) res >= len) {
3374 cmd[len - 1] = '\0';
3376 if (system(cmd) < 0)
3378 #endif /* _WIN32_WCE */
3385 static void wpa_cli_action_process(const char *msg)
3388 char *copy = NULL, *id, *pos2;
3393 pos = os_strchr(pos, '>');
3400 if (str_match(pos, WPA_EVENT_CONNECTED)) {
3402 os_unsetenv("WPA_ID");
3403 os_unsetenv("WPA_ID_STR");
3404 os_unsetenv("WPA_CTRL_DIR");
3406 pos = os_strstr(pos, "[id=");
3408 copy = os_strdup(pos + 4);
3412 while (*pos2 && *pos2 != ' ')
3416 os_setenv("WPA_ID", id, 1);
3417 while (*pos2 && *pos2 != '=')
3422 while (*pos2 && *pos2 != ']')
3425 os_setenv("WPA_ID_STR", id, 1);
3429 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3431 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
3432 wpa_cli_connected = 1;
3433 wpa_cli_last_id = new_id;
3434 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
3436 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3437 if (wpa_cli_connected) {
3438 wpa_cli_connected = 0;
3439 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
3441 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3442 wpa_cli_exec(action_file, ctrl_ifname, pos);
3443 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3444 wpa_cli_exec(action_file, ctrl_ifname, pos);
3445 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3446 wpa_cli_exec(action_file, ctrl_ifname, pos);
3447 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3448 wpa_cli_exec(action_file, ctrl_ifname, pos);
3449 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3450 wpa_cli_exec(action_file, ctrl_ifname, pos);
3451 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3452 wpa_cli_exec(action_file, ctrl_ifname, pos);
3453 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3454 wpa_cli_exec(action_file, ctrl_ifname, pos);
3455 } else if (str_match(pos, AP_STA_CONNECTED)) {
3456 wpa_cli_exec(action_file, ctrl_ifname, pos);
3457 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3458 wpa_cli_exec(action_file, ctrl_ifname, pos);
3459 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3460 printf("wpa_supplicant is terminating - stop monitoring\n");
3466 #ifndef CONFIG_ANSI_C_EXTRA
3467 static void wpa_cli_action_cb(char *msg, size_t len)
3469 wpa_cli_action_process(msg);
3471 #endif /* CONFIG_ANSI_C_EXTRA */
3474 static void wpa_cli_reconnect(void)
3476 wpa_cli_close_connection();
3477 wpa_cli_open_connection(ctrl_ifname, 1);
3481 static void cli_event(const char *str)
3483 const char *start, *s;
3485 start = os_strchr(str, '>');
3491 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3492 s = os_strchr(start, ' ');
3495 s = os_strchr(s + 1, ' ');
3498 cli_txt_list_add(&bsses, s + 1);
3502 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3503 s = os_strchr(start, ' ');
3506 s = os_strchr(s + 1, ' ');
3509 cli_txt_list_del_addr(&bsses, s + 1);
3514 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3515 s = os_strstr(start, " p2p_dev_addr=");
3518 cli_txt_list_add_addr(&p2p_peers, s + 14);
3522 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3523 s = os_strstr(start, " p2p_dev_addr=");
3526 cli_txt_list_del_addr(&p2p_peers, s + 14);
3530 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3531 s = os_strchr(start, ' ');
3534 cli_txt_list_add_word(&p2p_groups, s + 1);
3538 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3539 s = os_strchr(start, ' ');
3542 cli_txt_list_del_word(&p2p_groups, s + 1);
3545 #endif /* CONFIG_P2P */
3549 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3551 if (ctrl_conn == NULL) {
3552 wpa_cli_reconnect();
3555 while (wpa_ctrl_pending(ctrl) > 0) {
3557 size_t len = sizeof(buf) - 1;
3558 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3561 wpa_cli_action_process(buf);
3564 if (wpa_cli_show_event(buf)) {
3566 printf("\r%s\n", buf);
3571 printf("Could not read pending message.\n");
3576 if (wpa_ctrl_pending(ctrl) < 0) {
3577 printf("Connection to wpa_supplicant lost - trying to "
3579 wpa_cli_reconnect();
3585 static int tokenize_cmd(char *cmd, char *argv[])
3598 if (argc == max_args)
3601 char *pos2 = os_strrchr(pos, '"');
3605 while (*pos != '\0' && *pos != ' ')
3615 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3617 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3618 printf("Connection to wpa_supplicant lost - trying to "
3620 wpa_cli_close_connection();
3623 wpa_cli_reconnect();
3624 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3628 static void wpa_cli_eloop_terminate(int sig, void *signal_ctx)
3634 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3636 wpa_cli_recv_pending(mon_conn, 0);
3640 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3642 char *argv[max_args];
3644 argc = tokenize_cmd(cmd, argv);
3646 wpa_request(ctrl_conn, argc, argv);
3650 static void wpa_cli_edit_eof_cb(void *ctx)
3656 static void wpa_cli_interactive(void)
3658 char *home, *hfile = NULL;
3660 printf("\nInteractive mode\n\n");
3662 home = getenv("HOME");
3664 const char *fname = ".wpa_cli_history";
3665 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3666 hfile = os_malloc(hfile_len);
3668 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3671 eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
3672 edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3673 wpa_cli_edit_completion_cb, NULL, hfile);
3674 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3678 cli_txt_list_flush(&p2p_peers);
3679 cli_txt_list_flush(&p2p_groups);
3680 cli_txt_list_flush(&bsses);
3681 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3683 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3684 wpa_cli_close_connection();
3688 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3690 #ifdef CONFIG_ANSI_C_EXTRA
3691 /* TODO: ANSI C version(?) */
3692 printf("Action processing not supported in ANSI C build.\n");
3693 #else /* CONFIG_ANSI_C_EXTRA */
3697 char buf[256]; /* note: large enough to fit in unsolicited messages */
3700 fd = wpa_ctrl_get_fd(ctrl);
3702 while (!wpa_cli_quit) {
3705 tv.tv_sec = ping_interval;
3707 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3708 if (res < 0 && errno != EINTR) {
3713 if (FD_ISSET(fd, &rfds))
3714 wpa_cli_recv_pending(ctrl, 1);
3716 /* verify that connection is still working */
3717 len = sizeof(buf) - 1;
3718 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3719 wpa_cli_action_cb) < 0 ||
3720 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3721 printf("wpa_supplicant did not reply to PING "
3722 "command - exiting\n");
3727 #endif /* CONFIG_ANSI_C_EXTRA */
3731 static void wpa_cli_cleanup(void)
3733 wpa_cli_close_connection();
3735 os_daemonize_terminate(pid_file);
3737 os_program_deinit();
3740 static void wpa_cli_terminate(int sig)
3747 static char * wpa_cli_get_default_ifname(void)
3749 char *ifname = NULL;
3751 #ifdef CONFIG_CTRL_IFACE_UNIX
3752 struct dirent *dent;
3753 DIR *dir = opendir(ctrl_iface_dir);
3756 char ifprop[PROPERTY_VALUE_MAX];
3757 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3758 ifname = os_strdup(ifprop);
3759 printf("Using interface '%s'\n", ifname);
3762 #endif /* ANDROID */
3765 while ((dent = readdir(dir))) {
3766 #ifdef _DIRENT_HAVE_D_TYPE
3768 * Skip the file if it is not a socket. Also accept
3769 * DT_UNKNOWN (0) in case the C library or underlying
3770 * file system does not support d_type.
3772 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3774 #endif /* _DIRENT_HAVE_D_TYPE */
3775 if (os_strcmp(dent->d_name, ".") == 0 ||
3776 os_strcmp(dent->d_name, "..") == 0)
3778 printf("Selected interface '%s'\n", dent->d_name);
3779 ifname = os_strdup(dent->d_name);
3783 #endif /* CONFIG_CTRL_IFACE_UNIX */
3785 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3786 char buf[2048], *pos;
3788 struct wpa_ctrl *ctrl;
3791 ctrl = wpa_ctrl_open(NULL);
3795 len = sizeof(buf) - 1;
3796 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3799 pos = os_strchr(buf, '\n');
3802 ifname = os_strdup(buf);
3804 wpa_ctrl_close(ctrl);
3805 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3811 int main(int argc, char *argv[])
3813 int warning_displayed = 0;
3817 const char *global = NULL;
3819 if (os_program_init())
3823 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3828 action_file = optarg;
3837 ping_interval = atoi(optarg);
3843 printf("%s\n", wpa_cli_version);
3846 os_free(ctrl_ifname);
3847 ctrl_ifname = os_strdup(optarg);
3850 ctrl_iface_dir = optarg;
3861 interactive = (argc == optind) && (action_file == NULL);
3864 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3870 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3871 ctrl_conn = wpa_ctrl_open(NULL);
3872 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3873 ctrl_conn = wpa_ctrl_open(global);
3874 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3875 if (ctrl_conn == NULL) {
3876 fprintf(stderr, "Failed to connect to wpa_supplicant "
3877 "global interface: %s error: %s\n",
3878 global, strerror(errno));
3884 signal(SIGINT, wpa_cli_terminate);
3885 signal(SIGTERM, wpa_cli_terminate);
3886 #endif /* _WIN32_WCE */
3888 if (ctrl_ifname == NULL)
3889 ctrl_ifname = wpa_cli_get_default_ifname();
3893 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3894 if (warning_displayed)
3895 printf("Connection established.\n");
3899 if (!warning_displayed) {
3900 printf("Could not connect to wpa_supplicant: "
3901 "%s - re-trying\n", ctrl_ifname);
3902 warning_displayed = 1;
3909 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3910 fprintf(stderr, "Failed to connect to non-global "
3911 "ctrl_ifname: %s error: %s\n",
3912 ctrl_ifname, strerror(errno));
3917 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3918 wpa_cli_attached = 1;
3920 printf("Warning: Failed to attach to "
3921 "wpa_supplicant.\n");
3927 if (daemonize && os_daemonize(pid_file))
3931 wpa_cli_interactive();
3932 else if (action_file)
3933 wpa_cli_action(ctrl_conn);
3935 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3937 os_free(ctrl_ifname);
3944 #else /* CONFIG_CTRL_IFACE */
3945 int main(int argc, char *argv[])
3947 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3950 #endif /* CONFIG_CTRL_IFACE */