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 #ifdef CONFIG_WPS_NFC
853 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
859 res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC %s",
862 res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC");
863 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
864 printf("Too long WPS_NFC command.\n");
867 return wpa_ctrl_command(ctrl, cmd);
871 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
878 printf("Invalid WPS_NFC_TOKEN command: need one argument:\n"
879 "format: WPS or NDEF\n");
883 res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC_TOKEN %s",
886 res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC_TOKEN");
887 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
888 printf("Too long WPS_NFC_TOKEN command.\n");
891 return wpa_ctrl_command(ctrl, cmd);
895 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
903 printf("Invalid 'wps_nfc_tag_read' command - one argument "
908 buflen = 18 + os_strlen(argv[0]);
909 buf = os_malloc(buflen);
912 os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
914 ret = wpa_ctrl_command(ctrl, buf);
920 #endif /* CONFIG_WPS_NFC */
923 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
929 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
931 else if (argc == 5 || argc == 6) {
932 char ssid_hex[2 * 32 + 1];
933 char key_hex[2 * 64 + 1];
937 for (i = 0; i < 32; i++) {
938 if (argv[2][i] == '\0')
940 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
945 for (i = 0; i < 64; i++) {
946 if (argv[5][i] == '\0')
948 os_snprintf(&key_hex[i * 2], 3, "%02x",
953 res = os_snprintf(cmd, sizeof(cmd),
954 "WPS_REG %s %s %s %s %s %s",
955 argv[0], argv[1], ssid_hex, argv[3], argv[4],
958 printf("Invalid WPS_REG command: need two arguments:\n"
959 "- BSSID of the target AP\n"
961 printf("Alternatively, six arguments can be used to "
962 "reconfigure the AP:\n"
963 "- BSSID of the target AP\n"
966 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
967 "- new encr (NONE, WEP, TKIP, CCMP)\n"
972 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
973 printf("Too long WPS_REG command.\n");
976 return wpa_ctrl_command(ctrl, cmd);
980 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
987 printf("Invalid WPS_AP_PIN command: needs at least one "
993 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s %s",
994 argv[0], argv[1], argv[2]);
996 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s",
999 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s",
1001 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1002 printf("Too long WPS_AP_PIN command.\n");
1005 return wpa_ctrl_command(ctrl, cmd);
1009 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
1014 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
1015 return wpa_ctrl_command(ctrl, cmd);
1017 return wpa_ctrl_command(ctrl, "WPS_ER_START");
1021 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
1024 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
1029 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
1036 printf("Invalid WPS_ER_PIN command: need at least two "
1038 "- UUID: use 'any' to select any\n"
1039 "- PIN: Enrollee PIN\n"
1040 "optional: - Enrollee MAC address\n");
1045 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
1046 argv[0], argv[1], argv[2]);
1048 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
1050 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1051 printf("Too long WPS_ER_PIN command.\n");
1054 return wpa_ctrl_command(ctrl, cmd);
1058 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
1065 printf("Invalid WPS_ER_PBC command: need one argument:\n"
1066 "- UUID: Specify the Enrollee\n");
1070 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
1072 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1073 printf("Too long WPS_ER_PBC command.\n");
1076 return wpa_ctrl_command(ctrl, cmd);
1080 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
1087 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1088 "- UUID: specify which AP to use\n"
1093 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
1095 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1096 printf("Too long WPS_ER_LEARN command.\n");
1099 return wpa_ctrl_command(ctrl, cmd);
1103 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
1110 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1112 "- UUID: specify which AP to use\n"
1113 "- Network configuration id\n");
1117 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_SET_CONFIG %s %s",
1119 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1120 printf("Too long WPS_ER_SET_CONFIG command.\n");
1123 return wpa_ctrl_command(ctrl, cmd);
1127 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
1133 if (argc == 5 || argc == 6) {
1134 char ssid_hex[2 * 32 + 1];
1135 char key_hex[2 * 64 + 1];
1139 for (i = 0; i < 32; i++) {
1140 if (argv[2][i] == '\0')
1142 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1147 for (i = 0; i < 64; i++) {
1148 if (argv[5][i] == '\0')
1150 os_snprintf(&key_hex[i * 2], 3, "%02x",
1155 res = os_snprintf(cmd, sizeof(cmd),
1156 "WPS_ER_CONFIG %s %s %s %s %s %s",
1157 argv[0], argv[1], ssid_hex, argv[3], argv[4],
1160 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1164 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1165 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1170 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1171 printf("Too long WPS_ER_CONFIG command.\n");
1174 return wpa_ctrl_command(ctrl, cmd);
1178 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1184 printf("Invalid IBSS_RSN command: needs one argument "
1185 "(Peer STA MAC address)\n");
1189 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
1190 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1191 printf("Too long IBSS_RSN command.\n");
1194 return wpa_ctrl_command(ctrl, cmd);
1198 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1204 printf("Invalid LEVEL command: needs one argument (debug "
1208 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
1209 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1210 printf("Too long LEVEL command.\n");
1213 return wpa_ctrl_command(ctrl, cmd);
1217 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1219 char cmd[256], *pos, *end;
1223 printf("Invalid IDENTITY command: needs two arguments "
1224 "(network id and identity)\n");
1228 end = cmd + sizeof(cmd);
1230 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1232 if (ret < 0 || ret >= end - pos) {
1233 printf("Too long IDENTITY command.\n");
1237 for (i = 2; i < argc; i++) {
1238 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1239 if (ret < 0 || ret >= end - pos) {
1240 printf("Too long IDENTITY command.\n");
1246 return wpa_ctrl_command(ctrl, cmd);
1250 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1252 char cmd[256], *pos, *end;
1256 printf("Invalid PASSWORD command: needs two arguments "
1257 "(network id and password)\n");
1261 end = cmd + sizeof(cmd);
1263 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1265 if (ret < 0 || ret >= end - pos) {
1266 printf("Too long PASSWORD command.\n");
1270 for (i = 2; i < argc; i++) {
1271 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1272 if (ret < 0 || ret >= end - pos) {
1273 printf("Too long PASSWORD command.\n");
1279 return wpa_ctrl_command(ctrl, cmd);
1283 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1286 char cmd[256], *pos, *end;
1290 printf("Invalid NEW_PASSWORD command: needs two arguments "
1291 "(network id and password)\n");
1295 end = cmd + sizeof(cmd);
1297 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1299 if (ret < 0 || ret >= end - pos) {
1300 printf("Too long NEW_PASSWORD command.\n");
1304 for (i = 2; i < argc; i++) {
1305 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1306 if (ret < 0 || ret >= end - pos) {
1307 printf("Too long NEW_PASSWORD command.\n");
1313 return wpa_ctrl_command(ctrl, cmd);
1317 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1319 char cmd[256], *pos, *end;
1323 printf("Invalid PIN command: needs two arguments "
1324 "(network id and pin)\n");
1328 end = cmd + sizeof(cmd);
1330 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1332 if (ret < 0 || ret >= end - pos) {
1333 printf("Too long PIN command.\n");
1337 for (i = 2; i < argc; i++) {
1338 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1339 if (ret < 0 || ret >= end - pos) {
1340 printf("Too long PIN command.\n");
1345 return wpa_ctrl_command(ctrl, cmd);
1349 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1351 char cmd[256], *pos, *end;
1355 printf("Invalid OTP command: needs two arguments (network "
1356 "id and password)\n");
1360 end = cmd + sizeof(cmd);
1362 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1364 if (ret < 0 || ret >= end - pos) {
1365 printf("Too long OTP command.\n");
1369 for (i = 2; i < argc; i++) {
1370 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1371 if (ret < 0 || ret >= end - pos) {
1372 printf("Too long OTP command.\n");
1378 return wpa_ctrl_command(ctrl, cmd);
1382 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1385 char cmd[256], *pos, *end;
1389 printf("Invalid PASSPHRASE command: needs two arguments "
1390 "(network id and passphrase)\n");
1394 end = cmd + sizeof(cmd);
1396 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1398 if (ret < 0 || ret >= end - pos) {
1399 printf("Too long PASSPHRASE command.\n");
1403 for (i = 2; i < argc; i++) {
1404 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1405 if (ret < 0 || ret >= end - pos) {
1406 printf("Too long PASSPHRASE command.\n");
1412 return wpa_ctrl_command(ctrl, cmd);
1416 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1418 char cmd[256], *pos, *end;
1422 printf("Invalid BSSID command: needs two arguments (network "
1427 end = cmd + sizeof(cmd);
1429 ret = os_snprintf(pos, end - pos, "BSSID");
1430 if (ret < 0 || ret >= end - pos) {
1431 printf("Too long BSSID command.\n");
1435 for (i = 0; i < argc; i++) {
1436 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1437 if (ret < 0 || ret >= end - pos) {
1438 printf("Too long BSSID command.\n");
1444 return wpa_ctrl_command(ctrl, cmd);
1448 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1450 char cmd[256], *pos, *end;
1453 end = cmd + sizeof(cmd);
1455 ret = os_snprintf(pos, end - pos, "BLACKLIST");
1456 if (ret < 0 || ret >= end - pos) {
1457 printf("Too long BLACKLIST command.\n");
1461 for (i = 0; i < argc; i++) {
1462 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1463 if (ret < 0 || ret >= end - pos) {
1464 printf("Too long BLACKLIST command.\n");
1470 return wpa_ctrl_command(ctrl, cmd);
1474 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1476 char cmd[256], *pos, *end;
1479 end = cmd + sizeof(cmd);
1481 ret = os_snprintf(pos, end - pos, "LOG_LEVEL");
1482 if (ret < 0 || ret >= end - pos) {
1483 printf("Too long LOG_LEVEL command.\n");
1487 for (i = 0; i < argc; i++) {
1488 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1489 if (ret < 0 || ret >= end - pos) {
1490 printf("Too long LOG_LEVEL command.\n");
1496 return wpa_ctrl_command(ctrl, cmd);
1500 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1503 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1507 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1514 printf("Invalid SELECT_NETWORK command: needs one argument "
1519 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1520 if (res < 0 || (size_t) res >= sizeof(cmd))
1522 cmd[sizeof(cmd) - 1] = '\0';
1524 return wpa_ctrl_command(ctrl, cmd);
1528 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1535 printf("Invalid ENABLE_NETWORK command: needs one argument "
1541 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s %s",
1544 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s",
1546 if (res < 0 || (size_t) res >= sizeof(cmd))
1548 cmd[sizeof(cmd) - 1] = '\0';
1550 return wpa_ctrl_command(ctrl, cmd);
1554 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1561 printf("Invalid DISABLE_NETWORK command: needs one argument "
1566 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1567 if (res < 0 || (size_t) res >= sizeof(cmd))
1569 cmd[sizeof(cmd) - 1] = '\0';
1571 return wpa_ctrl_command(ctrl, cmd);
1575 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1578 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1582 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1589 printf("Invalid REMOVE_NETWORK command: needs one argument "
1594 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1595 if (res < 0 || (size_t) res >= sizeof(cmd))
1597 cmd[sizeof(cmd) - 1] = '\0';
1599 return wpa_ctrl_command(ctrl, cmd);
1603 static void wpa_cli_show_network_variables(void)
1605 printf("set_network variables:\n"
1606 " ssid (network name, SSID)\n"
1607 " psk (WPA passphrase or pre-shared key)\n"
1608 " key_mgmt (key management protocol)\n"
1609 " identity (EAP identity)\n"
1610 " password (EAP password)\n"
1613 "Note: Values are entered in the same format as the "
1614 "configuration file is using,\n"
1615 "i.e., strings values need to be inside double quotation "
1617 "For example: set_network 1 ssid \"network name\"\n"
1619 "Please see wpa_supplicant.conf documentation for full list "
1620 "of\navailable variables.\n");
1624 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1631 wpa_cli_show_network_variables();
1636 printf("Invalid SET_NETWORK command: needs three arguments\n"
1637 "(network id, variable name, and value)\n");
1641 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1642 argv[0], argv[1], argv[2]);
1643 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1644 printf("Too long SET_NETWORK command.\n");
1647 return wpa_ctrl_command(ctrl, cmd);
1651 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1658 wpa_cli_show_network_variables();
1663 printf("Invalid GET_NETWORK command: needs two arguments\n"
1664 "(network id and variable name)\n");
1668 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1670 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1671 printf("Too long GET_NETWORK command.\n");
1674 return wpa_ctrl_command(ctrl, cmd);
1678 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1681 return wpa_ctrl_command(ctrl, "LIST_CREDS");
1685 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1687 return wpa_ctrl_command(ctrl, "ADD_CRED");
1691 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1698 printf("Invalid REMOVE_CRED command: needs one argument "
1703 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_CRED %s", argv[0]);
1704 if (res < 0 || (size_t) res >= sizeof(cmd))
1706 cmd[sizeof(cmd) - 1] = '\0';
1708 return wpa_ctrl_command(ctrl, cmd);
1712 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1718 printf("Invalid SET_CRED command: needs three arguments\n"
1719 "(cred id, variable name, and value)\n");
1723 res = os_snprintf(cmd, sizeof(cmd), "SET_CRED %s %s %s",
1724 argv[0], argv[1], argv[2]);
1725 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1726 printf("Too long SET_CRED command.\n");
1729 return wpa_ctrl_command(ctrl, cmd);
1733 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1736 return wpa_ctrl_command(ctrl, "DISCONNECT");
1740 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1743 return wpa_ctrl_command(ctrl, "RECONNECT");
1747 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1750 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1754 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1756 return wpa_ctrl_command(ctrl, "SCAN");
1760 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1763 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1767 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1773 printf("Invalid BSS command: need at least one argument"
1774 "(index or BSSID)\n");
1778 res = os_snprintf(cmd, sizeof(cmd), "BSS %s%s%s%s%s", argv[0],
1779 argc > 1 ? " " : "", argc > 1 ? argv[1] : "",
1780 argc > 2 ? " " : "", argc > 2 ? argv[2] : "");
1782 if (res < 0 || (size_t) res >= sizeof(cmd))
1784 cmd[sizeof(cmd) - 1] = '\0';
1786 return wpa_ctrl_command(ctrl, cmd);
1790 static char ** wpa_cli_complete_bss(const char *str, int pos)
1792 int arg = get_cmd_arg_num(str, pos);
1797 res = cli_txt_list_array(&bsses);
1805 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1811 if (argc < 1 || argc > 2) {
1812 printf("Invalid GET_CAPABILITY command: need either one or "
1817 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1818 printf("Invalid GET_CAPABILITY command: second argument, "
1819 "if any, must be 'strict'\n");
1823 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1824 (argc == 2) ? " strict" : "");
1825 if (res < 0 || (size_t) res >= sizeof(cmd))
1827 cmd[sizeof(cmd) - 1] = '\0';
1829 return wpa_ctrl_command(ctrl, cmd);
1833 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1835 printf("Available interfaces:\n");
1836 return wpa_ctrl_command(ctrl, "INTERFACES");
1840 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1843 wpa_cli_list_interfaces(ctrl);
1847 wpa_cli_close_connection();
1848 os_free(ctrl_ifname);
1849 ctrl_ifname = os_strdup(argv[0]);
1851 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1852 printf("Connected to interface '%s.\n", ctrl_ifname);
1854 printf("Could not connect to interface '%s' - re-trying\n",
1861 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1864 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1868 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1871 return wpa_ctrl_command(ctrl, "TERMINATE");
1875 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1882 printf("Invalid INTERFACE_ADD command: needs at least one "
1883 "argument (interface name)\n"
1884 "All arguments: ifname confname driver ctrl_interface "
1885 "driver_param bridge_name\n");
1890 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1891 * <driver_param>TAB<bridge_name>
1893 res = os_snprintf(cmd, sizeof(cmd),
1894 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1896 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1897 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1898 argc > 5 ? argv[5] : "");
1899 if (res < 0 || (size_t) res >= sizeof(cmd))
1901 cmd[sizeof(cmd) - 1] = '\0';
1902 return wpa_ctrl_command(ctrl, cmd);
1906 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1913 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1914 "(interface name)\n");
1918 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1919 if (res < 0 || (size_t) res >= sizeof(cmd))
1921 cmd[sizeof(cmd) - 1] = '\0';
1922 return wpa_ctrl_command(ctrl, cmd);
1926 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1929 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1934 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1938 printf("Invalid 'sta' command - exactly one argument, STA "
1939 "address, is required.\n");
1942 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1943 return wpa_ctrl_command(ctrl, buf);
1947 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1948 char *addr, size_t addr_len)
1950 char buf[4096], *pos;
1954 if (ctrl_conn == NULL) {
1955 printf("Not connected to hostapd - command dropped.\n");
1958 len = sizeof(buf) - 1;
1959 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
1962 printf("'%s' command timed out.\n", cmd);
1964 } else if (ret < 0) {
1965 printf("'%s' command failed.\n", cmd);
1970 if (os_memcmp(buf, "FAIL", 4) == 0)
1975 while (*pos != '\0' && *pos != '\n')
1978 os_strlcpy(addr, buf, addr_len);
1983 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1985 char addr[32], cmd[64];
1987 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1990 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1991 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1997 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
2002 printf("Invalid 'deauthenticate' command - exactly one "
2003 "argument, STA address, is required.\n");
2007 os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s %s",
2010 os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s", argv[0]);
2011 return wpa_ctrl_command(ctrl, buf);
2015 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
2020 printf("Invalid 'disassociate' command - exactly one "
2021 "argument, STA address, is required.\n");
2025 os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s %s",
2028 os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s", argv[0]);
2029 return wpa_ctrl_command(ctrl, buf);
2031 #endif /* CONFIG_AP */
2034 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
2036 return wpa_ctrl_command(ctrl, "SUSPEND");
2040 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
2042 return wpa_ctrl_command(ctrl, "RESUME");
2046 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
2048 return wpa_ctrl_command(ctrl, "DROP_SA");
2052 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
2058 printf("Invalid ROAM command: needs one argument "
2059 "(target AP's BSSID)\n");
2063 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
2064 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2065 printf("Too long ROAM command.\n");
2068 return wpa_ctrl_command(ctrl, cmd);
2074 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
2080 return wpa_ctrl_command(ctrl, "P2P_FIND");
2083 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s %s",
2084 argv[0], argv[1], argv[2]);
2086 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
2089 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %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_stop_find(struct wpa_ctrl *ctrl, int argc,
2100 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
2104 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
2111 printf("Invalid P2P_CONNECT command: needs at least two "
2112 "arguments (address and pbc/PIN)\n");
2117 res = os_snprintf(cmd, sizeof(cmd),
2118 "P2P_CONNECT %s %s %s %s %s",
2119 argv[0], argv[1], argv[2], argv[3],
2122 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
2123 argv[0], argv[1], argv[2], argv[3]);
2125 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
2126 argv[0], argv[1], argv[2]);
2128 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
2130 if (res < 0 || (size_t) res >= sizeof(cmd))
2132 cmd[sizeof(cmd) - 1] = '\0';
2133 return wpa_ctrl_command(ctrl, cmd);
2137 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
2139 int arg = get_cmd_arg_num(str, pos);
2144 res = cli_txt_list_array(&p2p_peers);
2152 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
2159 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
2161 res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
2162 if (res < 0 || (size_t) res >= sizeof(cmd))
2164 cmd[sizeof(cmd) - 1] = '\0';
2165 return wpa_ctrl_command(ctrl, cmd);
2169 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
2176 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
2177 "(interface name)\n");
2181 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
2182 if (res < 0 || (size_t) res >= sizeof(cmd))
2184 cmd[sizeof(cmd) - 1] = '\0';
2185 return wpa_ctrl_command(ctrl, cmd);
2189 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
2191 int arg = get_cmd_arg_num(str, pos);
2196 res = cli_txt_list_array(&p2p_groups);
2204 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
2211 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
2214 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s %s",
2217 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s",
2219 if (res < 0 || (size_t) res >= sizeof(cmd))
2221 cmd[sizeof(cmd) - 1] = '\0';
2222 return wpa_ctrl_command(ctrl, cmd);
2226 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
2232 if (argc != 2 && argc != 3) {
2233 printf("Invalid P2P_PROV_DISC command: needs at least "
2234 "two arguments, address and config method\n"
2235 "(display, keypad, or pbc) and an optional join\n");
2240 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s %s",
2241 argv[0], argv[1], argv[2]);
2243 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
2245 if (res < 0 || (size_t) res >= sizeof(cmd))
2247 cmd[sizeof(cmd) - 1] = '\0';
2248 return wpa_ctrl_command(ctrl, cmd);
2252 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
2255 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
2259 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
2265 if (argc != 2 && argc != 4) {
2266 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2267 "arguments (address and TLVs) or four arguments "
2268 "(address, \"upnp\", version, search target "
2274 res = os_snprintf(cmd, sizeof(cmd),
2275 "P2P_SERV_DISC_REQ %s %s %s %s",
2276 argv[0], argv[1], argv[2], argv[3]);
2278 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
2280 if (res < 0 || (size_t) res >= sizeof(cmd))
2282 cmd[sizeof(cmd) - 1] = '\0';
2283 return wpa_ctrl_command(ctrl, cmd);
2287 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
2288 int argc, char *argv[])
2294 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
2295 "argument (pending request identifier)\n");
2299 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
2301 if (res < 0 || (size_t) res >= sizeof(cmd))
2303 cmd[sizeof(cmd) - 1] = '\0';
2304 return wpa_ctrl_command(ctrl, cmd);
2308 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
2315 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2316 "arguments (freq, address, dialog token, and TLVs)\n");
2320 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
2321 argv[0], argv[1], argv[2], argv[3]);
2322 if (res < 0 || (size_t) res >= sizeof(cmd))
2324 cmd[sizeof(cmd) - 1] = '\0';
2325 return wpa_ctrl_command(ctrl, cmd);
2329 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
2332 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
2336 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
2337 int argc, char *argv[])
2343 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
2344 "argument (external processing: 0/1)\n");
2348 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
2350 if (res < 0 || (size_t) res >= sizeof(cmd))
2352 cmd[sizeof(cmd) - 1] = '\0';
2353 return wpa_ctrl_command(ctrl, cmd);
2357 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
2360 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
2364 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
2370 if (argc != 3 && argc != 4) {
2371 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
2377 res = os_snprintf(cmd, sizeof(cmd),
2378 "P2P_SERVICE_ADD %s %s %s %s",
2379 argv[0], argv[1], argv[2], argv[3]);
2381 res = os_snprintf(cmd, sizeof(cmd),
2382 "P2P_SERVICE_ADD %s %s %s",
2383 argv[0], argv[1], argv[2]);
2384 if (res < 0 || (size_t) res >= sizeof(cmd))
2386 cmd[sizeof(cmd) - 1] = '\0';
2387 return wpa_ctrl_command(ctrl, cmd);
2391 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2397 if (argc != 2 && argc != 3) {
2398 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2404 res = os_snprintf(cmd, sizeof(cmd),
2405 "P2P_SERVICE_DEL %s %s %s",
2406 argv[0], argv[1], argv[2]);
2408 res = os_snprintf(cmd, sizeof(cmd),
2409 "P2P_SERVICE_DEL %s %s",
2411 if (res < 0 || (size_t) res >= sizeof(cmd))
2413 cmd[sizeof(cmd) - 1] = '\0';
2414 return wpa_ctrl_command(ctrl, cmd);
2418 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2419 int argc, char *argv[])
2425 printf("Invalid P2P_REJECT command: needs one argument "
2426 "(peer address)\n");
2430 res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
2431 if (res < 0 || (size_t) res >= sizeof(cmd))
2433 cmd[sizeof(cmd) - 1] = '\0';
2434 return wpa_ctrl_command(ctrl, cmd);
2438 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2439 int argc, char *argv[])
2445 printf("Invalid P2P_INVITE command: needs at least one "
2451 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
2452 argv[0], argv[1], argv[2]);
2454 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
2457 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
2458 if (res < 0 || (size_t) res >= sizeof(cmd))
2460 cmd[sizeof(cmd) - 1] = '\0';
2461 return wpa_ctrl_command(ctrl, cmd);
2465 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2469 printf("Invalid 'p2p_peer' command - exactly one argument, "
2470 "P2P peer device address, is required.\n");
2473 os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
2474 return wpa_ctrl_command(ctrl, buf);
2478 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2480 int arg = get_cmd_arg_num(str, pos);
2485 res = cli_txt_list_array(&p2p_peers);
2493 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2494 char *addr, size_t addr_len,
2497 char buf[4096], *pos;
2501 if (ctrl_conn == NULL)
2503 len = sizeof(buf) - 1;
2504 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2507 printf("'%s' command timed out.\n", cmd);
2509 } else if (ret < 0) {
2510 printf("'%s' command failed.\n", cmd);
2515 if (os_memcmp(buf, "FAIL", 4) == 0)
2519 while (*pos != '\0' && *pos != '\n')
2522 os_strlcpy(addr, buf, addr_len);
2523 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2524 printf("%s\n", addr);
2529 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2531 char addr[32], cmd[64];
2534 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2536 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2537 addr, sizeof(addr), discovered))
2540 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2541 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2548 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2554 printf("Invalid P2P_SET command: needs two arguments (field, "
2559 res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2560 if (res < 0 || (size_t) res >= sizeof(cmd))
2562 cmd[sizeof(cmd) - 1] = '\0';
2563 return wpa_ctrl_command(ctrl, cmd);
2567 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2569 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2573 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2576 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2580 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2587 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2588 "(peer address)\n");
2592 res = os_snprintf(cmd, sizeof(cmd), "P2P_UNAUTHORIZE %s", argv[0]);
2594 if (res < 0 || (size_t) res >= sizeof(cmd))
2597 cmd[sizeof(cmd) - 1] = '\0';
2598 return wpa_ctrl_command(ctrl, cmd);
2602 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2608 if (argc != 0 && argc != 2 && argc != 4) {
2609 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2610 "(preferred duration, interval; in microsecods).\n"
2611 "Optional second pair can be used to provide "
2612 "acceptable values.\n");
2617 res = os_snprintf(cmd, sizeof(cmd),
2618 "P2P_PRESENCE_REQ %s %s %s %s",
2619 argv[0], argv[1], argv[2], argv[3]);
2621 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2624 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2625 if (res < 0 || (size_t) res >= sizeof(cmd))
2627 cmd[sizeof(cmd) - 1] = '\0';
2628 return wpa_ctrl_command(ctrl, cmd);
2632 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2638 if (argc != 0 && argc != 2) {
2639 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2640 "(availability period, availability interval; in "
2642 "Extended Listen Timing can be cancelled with this "
2643 "command when used without parameters.\n");
2648 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2651 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2652 if (res < 0 || (size_t) res >= sizeof(cmd))
2654 cmd[sizeof(cmd) - 1] = '\0';
2655 return wpa_ctrl_command(ctrl, cmd);
2658 #endif /* CONFIG_P2P */
2661 #ifdef CONFIG_INTERWORKING
2662 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2665 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2669 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2672 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2676 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2683 return wpa_ctrl_command(ctrl, "INTERWORKING_SELECT");
2685 res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_SELECT %s", argv[0]);
2686 if (res < 0 || (size_t) res >= sizeof(cmd))
2688 cmd[sizeof(cmd) - 1] = '\0';
2689 return wpa_ctrl_command(ctrl, cmd);
2693 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2700 printf("Invalid INTERWORKING_CONNECT commands: needs one "
2701 "argument (BSSID)\n");
2705 res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_CONNECT %s",
2707 if (res < 0 || (size_t) res >= sizeof(cmd))
2709 cmd[sizeof(cmd) - 1] = '\0';
2710 return wpa_ctrl_command(ctrl, cmd);
2714 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2720 printf("Invalid ANQP_GET command: needs two arguments "
2721 "(addr and info id list)\n");
2725 res = os_snprintf(cmd, sizeof(cmd), "ANQP_GET %s %s",
2727 if (res < 0 || (size_t) res >= sizeof(cmd))
2729 cmd[sizeof(cmd) - 1] = '\0';
2730 return wpa_ctrl_command(ctrl, cmd);
2732 #endif /* CONFIG_INTERWORKING */
2737 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2744 printf("Invalid HS20_ANQP_GET command: needs two arguments "
2745 "(addr and subtype list)\n");
2749 res = os_snprintf(cmd, sizeof(cmd), "HS20_ANQP_GET %s %s",
2751 if (res < 0 || (size_t) res >= sizeof(cmd))
2753 cmd[sizeof(cmd) - 1] = '\0';
2754 return wpa_ctrl_command(ctrl, cmd);
2758 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2765 printf("Command needs one or two arguments (dst mac addr and "
2766 "optional home realm)\n");
2771 res = os_snprintf(cmd, sizeof(cmd),
2772 "HS20_GET_NAI_HOME_REALM_LIST %s",
2775 res = os_snprintf(cmd, sizeof(cmd),
2776 "HS20_GET_NAI_HOME_REALM_LIST %s %s",
2778 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2779 printf("Too long command.\n");
2783 return wpa_ctrl_command(ctrl, cmd);
2786 #endif /* CONFIG_HS20 */
2789 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2796 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2797 "(0/1 = disable/enable automatic reconnection)\n");
2800 res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2801 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2802 printf("Too long STA_AUTOCONNECT command.\n");
2805 return wpa_ctrl_command(ctrl, cmd);
2809 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2816 printf("Invalid TDLS_DISCOVER command: needs one argument "
2817 "(Peer STA MAC address)\n");
2821 res = os_snprintf(cmd, sizeof(cmd), "TDLS_DISCOVER %s", argv[0]);
2822 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2823 printf("Too long TDLS_DISCOVER command.\n");
2826 return wpa_ctrl_command(ctrl, cmd);
2830 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2837 printf("Invalid TDLS_SETUP command: needs one argument "
2838 "(Peer STA MAC address)\n");
2842 res = os_snprintf(cmd, sizeof(cmd), "TDLS_SETUP %s", argv[0]);
2843 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2844 printf("Too long TDLS_SETUP command.\n");
2847 return wpa_ctrl_command(ctrl, cmd);
2851 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2858 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2859 "(Peer STA MAC address)\n");
2863 res = os_snprintf(cmd, sizeof(cmd), "TDLS_TEARDOWN %s", argv[0]);
2864 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2865 printf("Too long TDLS_TEARDOWN command.\n");
2868 return wpa_ctrl_command(ctrl, cmd);
2872 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2875 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2879 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2882 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2886 #ifdef CONFIG_AUTOSCAN
2888 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
2894 return wpa_ctrl_command(ctrl, "AUTOSCAN ");
2896 res = os_snprintf(cmd, sizeof(cmd), "AUTOSCAN %s", argv[0]);
2897 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2898 printf("Too long AUTOSCAN command.\n");
2902 return wpa_ctrl_command(ctrl, cmd);
2905 #endif /* CONFIG_AUTOSCAN */
2908 enum wpa_cli_cmd_flags {
2909 cli_cmd_flag_none = 0x00,
2910 cli_cmd_flag_sensitive = 0x01
2913 struct wpa_cli_cmd {
2915 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2916 enum wpa_cli_cmd_flags flags;
2920 static struct wpa_cli_cmd wpa_cli_commands[] = {
2921 { "status", wpa_cli_cmd_status,
2923 "[verbose] = get current WPA/EAPOL/EAP status" },
2924 { "ping", wpa_cli_cmd_ping,
2926 "= pings wpa_supplicant" },
2927 { "relog", wpa_cli_cmd_relog,
2929 "= re-open log-file (allow rolling logs)" },
2930 { "note", wpa_cli_cmd_note,
2932 "<text> = add a note to wpa_supplicant debug log" },
2933 { "mib", wpa_cli_cmd_mib,
2935 "= get MIB variables (dot1x, dot11)" },
2936 { "help", wpa_cli_cmd_help,
2938 "= show this usage help" },
2939 { "interface", wpa_cli_cmd_interface,
2941 "[ifname] = show interfaces/select interface" },
2942 { "level", wpa_cli_cmd_level,
2944 "<debug level> = change debug level" },
2945 { "license", wpa_cli_cmd_license,
2947 "= show full wpa_cli license" },
2948 { "quit", wpa_cli_cmd_quit,
2951 { "set", wpa_cli_cmd_set,
2953 "= set variables (shows list of variables when run without "
2955 { "get", wpa_cli_cmd_get,
2957 "<name> = get information" },
2958 { "logon", wpa_cli_cmd_logon,
2960 "= IEEE 802.1X EAPOL state machine logon" },
2961 { "logoff", wpa_cli_cmd_logoff,
2963 "= IEEE 802.1X EAPOL state machine logoff" },
2964 { "pmksa", wpa_cli_cmd_pmksa,
2966 "= show PMKSA cache" },
2967 { "reassociate", wpa_cli_cmd_reassociate,
2969 "= force reassociation" },
2970 { "preauthenticate", wpa_cli_cmd_preauthenticate,
2972 "<BSSID> = force preauthentication" },
2973 { "identity", wpa_cli_cmd_identity,
2975 "<network id> <identity> = configure identity for an SSID" },
2976 { "password", wpa_cli_cmd_password,
2977 cli_cmd_flag_sensitive,
2978 "<network id> <password> = configure password for an SSID" },
2979 { "new_password", wpa_cli_cmd_new_password,
2980 cli_cmd_flag_sensitive,
2981 "<network id> <password> = change password for an SSID" },
2982 { "pin", wpa_cli_cmd_pin,
2983 cli_cmd_flag_sensitive,
2984 "<network id> <pin> = configure pin for an SSID" },
2985 { "otp", wpa_cli_cmd_otp,
2986 cli_cmd_flag_sensitive,
2987 "<network id> <password> = configure one-time-password for an SSID"
2989 { "passphrase", wpa_cli_cmd_passphrase,
2990 cli_cmd_flag_sensitive,
2991 "<network id> <passphrase> = configure private key passphrase\n"
2993 { "bssid", wpa_cli_cmd_bssid,
2995 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2996 { "blacklist", wpa_cli_cmd_blacklist,
2998 "<BSSID> = add a BSSID to the blacklist\n"
2999 "blacklist clear = clear the blacklist\n"
3000 "blacklist = display the blacklist" },
3001 { "log_level", wpa_cli_cmd_log_level,
3003 "<level> [<timestamp>] = update the log level/timestamp\n"
3004 "log_level = display the current log level and log options" },
3005 { "list_networks", wpa_cli_cmd_list_networks,
3007 "= list configured networks" },
3008 { "select_network", wpa_cli_cmd_select_network,
3010 "<network id> = select a network (disable others)" },
3011 { "enable_network", wpa_cli_cmd_enable_network,
3013 "<network id> = enable a network" },
3014 { "disable_network", wpa_cli_cmd_disable_network,
3016 "<network id> = disable a network" },
3017 { "add_network", wpa_cli_cmd_add_network,
3019 "= add a network" },
3020 { "remove_network", wpa_cli_cmd_remove_network,
3022 "<network id> = remove a network" },
3023 { "set_network", wpa_cli_cmd_set_network,
3024 cli_cmd_flag_sensitive,
3025 "<network id> <variable> <value> = set network variables (shows\n"
3026 " list of variables when run without arguments)" },
3027 { "get_network", wpa_cli_cmd_get_network,
3029 "<network id> <variable> = get network variables" },
3030 { "list_creds", wpa_cli_cmd_list_creds,
3032 "= list configured credentials" },
3033 { "add_cred", wpa_cli_cmd_add_cred,
3035 "= add a credential" },
3036 { "remove_cred", wpa_cli_cmd_remove_cred,
3038 "<cred id> = remove a credential" },
3039 { "set_cred", wpa_cli_cmd_set_cred,
3040 cli_cmd_flag_sensitive,
3041 "<cred id> <variable> <value> = set credential variables" },
3042 { "save_config", wpa_cli_cmd_save_config,
3044 "= save the current configuration" },
3045 { "disconnect", wpa_cli_cmd_disconnect,
3047 "= disconnect and wait for reassociate/reconnect command before\n"
3049 { "reconnect", wpa_cli_cmd_reconnect,
3051 "= like reassociate, but only takes effect if already disconnected"
3053 { "scan", wpa_cli_cmd_scan,
3055 "= request new BSS scan" },
3056 { "scan_results", wpa_cli_cmd_scan_results,
3058 "= get latest scan results" },
3059 { "bss", wpa_cli_cmd_bss,
3061 "<<idx> | <bssid>> = get detailed scan result info" },
3062 { "get_capability", wpa_cli_cmd_get_capability,
3064 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
3065 { "reconfigure", wpa_cli_cmd_reconfigure,
3067 "= force wpa_supplicant to re-read its configuration file" },
3068 { "terminate", wpa_cli_cmd_terminate,
3070 "= terminate wpa_supplicant" },
3071 { "interface_add", wpa_cli_cmd_interface_add,
3073 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
3074 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
3076 { "interface_remove", wpa_cli_cmd_interface_remove,
3078 "<ifname> = removes the interface" },
3079 { "interface_list", wpa_cli_cmd_interface_list,
3081 "= list available interfaces" },
3082 { "ap_scan", wpa_cli_cmd_ap_scan,
3084 "<value> = set ap_scan parameter" },
3085 { "scan_interval", wpa_cli_cmd_scan_interval,
3087 "<value> = set scan_interval parameter (in seconds)" },
3088 { "bss_expire_age", wpa_cli_cmd_bss_expire_age,
3090 "<value> = set BSS expiration age parameter" },
3091 { "bss_expire_count", wpa_cli_cmd_bss_expire_count,
3093 "<value> = set BSS expiration scan count parameter" },
3094 { "stkstart", wpa_cli_cmd_stkstart,
3096 "<addr> = request STK negotiation with <addr>" },
3097 { "ft_ds", wpa_cli_cmd_ft_ds,
3099 "<addr> = request over-the-DS FT with <addr>" },
3100 { "wps_pbc", wpa_cli_cmd_wps_pbc,
3102 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
3103 { "wps_pin", wpa_cli_cmd_wps_pin,
3104 cli_cmd_flag_sensitive,
3105 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
3107 { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
3108 cli_cmd_flag_sensitive,
3109 "<PIN> = verify PIN checksum" },
3110 { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
3111 "Cancels the pending WPS operation" },
3112 #ifdef CONFIG_WPS_OOB
3113 { "wps_oob", wpa_cli_cmd_wps_oob,
3114 cli_cmd_flag_sensitive,
3115 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
3116 #endif /* CONFIG_WPS_OOB */
3117 #ifdef CONFIG_WPS_NFC
3118 { "wps_nfc", wpa_cli_cmd_wps_nfc,
3120 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
3121 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token,
3123 "<WPS|NDEF> = create password token" },
3124 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read,
3125 cli_cmd_flag_sensitive,
3126 "<hexdump of payload> = report read NFC tag with WPS data" },
3127 #endif /* CONFIG_WPS_NFC */
3128 { "wps_reg", wpa_cli_cmd_wps_reg,
3129 cli_cmd_flag_sensitive,
3130 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
3131 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin,
3132 cli_cmd_flag_sensitive,
3133 "[params..] = enable/disable AP PIN" },
3134 { "wps_er_start", wpa_cli_cmd_wps_er_start,
3136 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
3137 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
3139 "= stop Wi-Fi Protected Setup External Registrar" },
3140 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
3141 cli_cmd_flag_sensitive,
3142 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
3143 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
3145 "<UUID> = accept an Enrollee PBC using External Registrar" },
3146 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
3147 cli_cmd_flag_sensitive,
3148 "<UUID> <PIN> = learn AP configuration" },
3149 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
3151 "<UUID> <network id> = set AP configuration for enrolling" },
3152 { "wps_er_config", wpa_cli_cmd_wps_er_config,
3153 cli_cmd_flag_sensitive,
3154 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
3155 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
3157 "<addr> = request RSN authentication with <addr> in IBSS" },
3159 { "sta", wpa_cli_cmd_sta,
3161 "<addr> = get information about an associated station (AP)" },
3162 { "all_sta", wpa_cli_cmd_all_sta,
3164 "= get information about all associated stations (AP)" },
3165 { "deauthenticate", wpa_cli_cmd_deauthenticate,
3167 "<addr> = deauthenticate a station" },
3168 { "disassociate", wpa_cli_cmd_disassociate,
3170 "<addr> = disassociate a station" },
3171 #endif /* CONFIG_AP */
3172 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
3173 "= notification of suspend/hibernate" },
3174 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
3175 "= notification of resume/thaw" },
3176 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
3177 "= drop SA without deauth/disassoc (test command)" },
3178 { "roam", wpa_cli_cmd_roam,
3180 "<addr> = roam to the specified BSS" },
3182 { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
3183 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
3184 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
3185 "= stop P2P Devices search" },
3186 { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
3187 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
3188 { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
3189 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
3190 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
3191 "<ifname> = remove P2P group interface (terminate group if GO)" },
3192 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
3193 "= add a new P2P group (local end as GO)" },
3194 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
3195 "<addr> <method> = request provisioning discovery" },
3196 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
3198 "= get the passphrase for a group (GO only)" },
3199 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
3201 "<addr> <TLVs> = schedule service discovery request" },
3202 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
3204 "<id> = cancel pending service discovery request" },
3205 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
3207 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
3208 { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
3210 "= indicate change in local services" },
3211 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
3213 "<external> = set external processing of service discovery" },
3214 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
3216 "= remove all stored service entries" },
3217 { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
3219 "<bonjour|upnp> <query|version> <response|service> = add a local "
3221 { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
3223 "<bonjour|upnp> <query|version> [|service] = remove a local "
3225 { "p2p_reject", wpa_cli_cmd_p2p_reject,
3227 "<addr> = reject connection attempts from a specific peer" },
3228 { "p2p_invite", wpa_cli_cmd_p2p_invite,
3230 "<cmd> [peer=addr] = invite peer" },
3231 { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
3232 "[discovered] = list known (optionally, only fully discovered) P2P "
3234 { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
3235 "<address> = show information about known P2P peer" },
3236 { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
3237 "<field> <value> = set a P2P parameter" },
3238 { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
3239 "= flush P2P state" },
3240 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
3241 "= cancel P2P group formation" },
3242 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none,
3243 "<address> = unauthorize a peer" },
3244 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
3245 "[<duration> <interval>] [<duration> <interval>] = request GO "
3247 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
3248 "[<period> <interval>] = set extended listen timing" },
3249 #endif /* CONFIG_P2P */
3251 #ifdef CONFIG_INTERWORKING
3252 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, cli_cmd_flag_none,
3253 "= fetch ANQP information for all APs" },
3254 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, cli_cmd_flag_none,
3255 "= stop fetch_anqp operation" },
3256 { "interworking_select", wpa_cli_cmd_interworking_select,
3258 "[auto] = perform Interworking network selection" },
3259 { "interworking_connect", wpa_cli_cmd_interworking_connect,
3261 "<BSSID> = connect using Interworking credentials" },
3262 { "anqp_get", wpa_cli_cmd_anqp_get, cli_cmd_flag_none,
3263 "<addr> <info id>[,<info id>]... = request ANQP information" },
3264 #endif /* CONFIG_INTERWORKING */
3266 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, cli_cmd_flag_none,
3267 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
3269 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
3271 "<addr> <home realm> = get HS20 nai home realm list" },
3272 #endif /* CONFIG_HS20 */
3273 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
3274 "<0/1> = disable/enable automatic reconnection" },
3275 { "tdls_discover", wpa_cli_cmd_tdls_discover,
3277 "<addr> = request TDLS discovery with <addr>" },
3278 { "tdls_setup", wpa_cli_cmd_tdls_setup,
3280 "<addr> = request TDLS setup with <addr>" },
3281 { "tdls_teardown", wpa_cli_cmd_tdls_teardown,
3283 "<addr> = tear down TDLS with <addr>" },
3284 { "signal_poll", wpa_cli_cmd_signal_poll,
3286 "= get signal parameters" },
3287 { "reauthenticate", wpa_cli_cmd_reauthenticate, cli_cmd_flag_none,
3288 "= trigger IEEE 802.1X/EAPOL reauthentication" },
3289 #ifdef CONFIG_AUTOSCAN
3290 { "autoscan", wpa_cli_cmd_autoscan, cli_cmd_flag_none,
3291 "[params] = Set or unset (if none) autoscan parameters" },
3292 #endif /* CONFIG_AUTOSCAN */
3293 { NULL, NULL, cli_cmd_flag_none, NULL }
3298 * Prints command usage, lines are padded with the specified string.
3300 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
3305 printf("%s%s ", pad, cmd->cmd);
3306 for (n = 0; (c = cmd->usage[n]); n++) {
3315 static void print_help(void)
3318 printf("commands:\n");
3319 for (n = 0; wpa_cli_commands[n].cmd; n++)
3320 print_cmd_help(&wpa_cli_commands[n], " ");
3324 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
3326 const char *c, *delim;
3330 delim = os_strchr(cmd, ' ');
3334 len = os_strlen(cmd);
3336 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
3337 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
3338 return (wpa_cli_commands[n].flags &
3339 cli_cmd_flag_sensitive);
3345 static char ** wpa_list_cmd_list(void)
3350 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
3351 res = os_zalloc(count * sizeof(char *));
3355 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3356 res[i] = os_strdup(wpa_cli_commands[i].cmd);
3365 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
3370 if (os_strcasecmp(cmd, "bss") == 0)
3371 return wpa_cli_complete_bss(str, pos);
3373 if (os_strcasecmp(cmd, "p2p_connect") == 0)
3374 return wpa_cli_complete_p2p_connect(str, pos);
3375 if (os_strcasecmp(cmd, "p2p_peer") == 0)
3376 return wpa_cli_complete_p2p_peer(str, pos);
3377 if (os_strcasecmp(cmd, "p2p_group_remove") == 0)
3378 return wpa_cli_complete_p2p_group_remove(str, pos);
3379 #endif /* CONFIG_P2P */
3381 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3382 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
3384 printf("\r%s\n", wpa_cli_commands[i].usage);
3394 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
3400 end = os_strchr(str, ' ');
3401 if (end == NULL || str + pos < end)
3402 return wpa_list_cmd_list();
3404 cmd = os_malloc(pos + 1);
3407 os_memcpy(cmd, str, pos);
3408 cmd[end - str] = '\0';
3409 res = wpa_cli_cmd_completion(cmd, str, pos);
3415 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3417 struct wpa_cli_cmd *cmd, *match = NULL;
3422 cmd = wpa_cli_commands;
3424 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3427 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3428 /* we have an exact match */
3438 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3439 cmd = wpa_cli_commands;
3441 if (os_strncasecmp(cmd->cmd, argv[0],
3442 os_strlen(argv[0])) == 0) {
3443 printf(" %s", cmd->cmd);
3449 } else if (count == 0) {
3450 printf("Unknown command '%s'\n", argv[0]);
3453 ret = match->handler(ctrl, argc - 1, &argv[1]);
3460 static int str_match(const char *a, const char *b)
3462 return os_strncmp(a, b, os_strlen(b)) == 0;
3466 static int wpa_cli_exec(const char *program, const char *arg1,
3474 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
3475 cmd = os_malloc(len);
3478 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
3479 if (res < 0 || (size_t) res >= len) {
3483 cmd[len - 1] = '\0';
3485 if (system(cmd) < 0)
3487 #endif /* _WIN32_WCE */
3494 static void wpa_cli_action_process(const char *msg)
3497 char *copy = NULL, *id, *pos2;
3502 pos = os_strchr(pos, '>');
3509 if (str_match(pos, WPA_EVENT_CONNECTED)) {
3511 os_unsetenv("WPA_ID");
3512 os_unsetenv("WPA_ID_STR");
3513 os_unsetenv("WPA_CTRL_DIR");
3515 pos = os_strstr(pos, "[id=");
3517 copy = os_strdup(pos + 4);
3521 while (*pos2 && *pos2 != ' ')
3525 os_setenv("WPA_ID", id, 1);
3526 while (*pos2 && *pos2 != '=')
3531 while (*pos2 && *pos2 != ']')
3534 os_setenv("WPA_ID_STR", id, 1);
3538 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3540 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
3541 wpa_cli_connected = 1;
3542 wpa_cli_last_id = new_id;
3543 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
3545 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3546 if (wpa_cli_connected) {
3547 wpa_cli_connected = 0;
3548 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
3550 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3551 wpa_cli_exec(action_file, ctrl_ifname, pos);
3552 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3553 wpa_cli_exec(action_file, ctrl_ifname, pos);
3554 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3555 wpa_cli_exec(action_file, ctrl_ifname, pos);
3556 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3557 wpa_cli_exec(action_file, ctrl_ifname, pos);
3558 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3559 wpa_cli_exec(action_file, ctrl_ifname, pos);
3560 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3561 wpa_cli_exec(action_file, ctrl_ifname, pos);
3562 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3563 wpa_cli_exec(action_file, ctrl_ifname, pos);
3564 } else if (str_match(pos, AP_STA_CONNECTED)) {
3565 wpa_cli_exec(action_file, ctrl_ifname, pos);
3566 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3567 wpa_cli_exec(action_file, ctrl_ifname, pos);
3568 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3569 printf("wpa_supplicant is terminating - stop monitoring\n");
3575 #ifndef CONFIG_ANSI_C_EXTRA
3576 static void wpa_cli_action_cb(char *msg, size_t len)
3578 wpa_cli_action_process(msg);
3580 #endif /* CONFIG_ANSI_C_EXTRA */
3583 static void wpa_cli_reconnect(void)
3585 wpa_cli_close_connection();
3586 wpa_cli_open_connection(ctrl_ifname, 1);
3590 static void cli_event(const char *str)
3592 const char *start, *s;
3594 start = os_strchr(str, '>');
3600 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3601 s = os_strchr(start, ' ');
3604 s = os_strchr(s + 1, ' ');
3607 cli_txt_list_add(&bsses, s + 1);
3611 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3612 s = os_strchr(start, ' ');
3615 s = os_strchr(s + 1, ' ');
3618 cli_txt_list_del_addr(&bsses, s + 1);
3623 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3624 s = os_strstr(start, " p2p_dev_addr=");
3627 cli_txt_list_add_addr(&p2p_peers, s + 14);
3631 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3632 s = os_strstr(start, " p2p_dev_addr=");
3635 cli_txt_list_del_addr(&p2p_peers, s + 14);
3639 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3640 s = os_strchr(start, ' ');
3643 cli_txt_list_add_word(&p2p_groups, s + 1);
3647 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3648 s = os_strchr(start, ' ');
3651 cli_txt_list_del_word(&p2p_groups, s + 1);
3654 #endif /* CONFIG_P2P */
3658 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3660 if (ctrl_conn == NULL) {
3661 wpa_cli_reconnect();
3664 while (wpa_ctrl_pending(ctrl) > 0) {
3666 size_t len = sizeof(buf) - 1;
3667 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3670 wpa_cli_action_process(buf);
3673 if (wpa_cli_show_event(buf)) {
3675 printf("\r%s\n", buf);
3680 printf("Could not read pending message.\n");
3685 if (wpa_ctrl_pending(ctrl) < 0) {
3686 printf("Connection to wpa_supplicant lost - trying to "
3688 wpa_cli_reconnect();
3694 static int tokenize_cmd(char *cmd, char *argv[])
3707 if (argc == max_args)
3710 char *pos2 = os_strrchr(pos, '"');
3714 while (*pos != '\0' && *pos != ' ')
3724 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3726 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3727 printf("Connection to wpa_supplicant lost - trying to "
3729 wpa_cli_close_connection();
3732 wpa_cli_reconnect();
3733 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3737 static void wpa_cli_eloop_terminate(int sig, void *signal_ctx)
3743 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3745 wpa_cli_recv_pending(mon_conn, 0);
3749 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3751 char *argv[max_args];
3753 argc = tokenize_cmd(cmd, argv);
3755 wpa_request(ctrl_conn, argc, argv);
3759 static void wpa_cli_edit_eof_cb(void *ctx)
3765 static void wpa_cli_interactive(void)
3767 char *home, *hfile = NULL;
3769 printf("\nInteractive mode\n\n");
3771 home = getenv("HOME");
3773 const char *fname = ".wpa_cli_history";
3774 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3775 hfile = os_malloc(hfile_len);
3777 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3780 eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
3781 edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3782 wpa_cli_edit_completion_cb, NULL, hfile);
3783 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3787 cli_txt_list_flush(&p2p_peers);
3788 cli_txt_list_flush(&p2p_groups);
3789 cli_txt_list_flush(&bsses);
3790 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3792 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3793 wpa_cli_close_connection();
3797 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3799 #ifdef CONFIG_ANSI_C_EXTRA
3800 /* TODO: ANSI C version(?) */
3801 printf("Action processing not supported in ANSI C build.\n");
3802 #else /* CONFIG_ANSI_C_EXTRA */
3806 char buf[256]; /* note: large enough to fit in unsolicited messages */
3809 fd = wpa_ctrl_get_fd(ctrl);
3811 while (!wpa_cli_quit) {
3814 tv.tv_sec = ping_interval;
3816 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3817 if (res < 0 && errno != EINTR) {
3822 if (FD_ISSET(fd, &rfds))
3823 wpa_cli_recv_pending(ctrl, 1);
3825 /* verify that connection is still working */
3826 len = sizeof(buf) - 1;
3827 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3828 wpa_cli_action_cb) < 0 ||
3829 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3830 printf("wpa_supplicant did not reply to PING "
3831 "command - exiting\n");
3836 #endif /* CONFIG_ANSI_C_EXTRA */
3840 static void wpa_cli_cleanup(void)
3842 wpa_cli_close_connection();
3844 os_daemonize_terminate(pid_file);
3846 os_program_deinit();
3849 static void wpa_cli_terminate(int sig)
3856 static char * wpa_cli_get_default_ifname(void)
3858 char *ifname = NULL;
3860 #ifdef CONFIG_CTRL_IFACE_UNIX
3861 struct dirent *dent;
3862 DIR *dir = opendir(ctrl_iface_dir);
3865 char ifprop[PROPERTY_VALUE_MAX];
3866 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3867 ifname = os_strdup(ifprop);
3868 printf("Using interface '%s'\n", ifname);
3871 #endif /* ANDROID */
3874 while ((dent = readdir(dir))) {
3875 #ifdef _DIRENT_HAVE_D_TYPE
3877 * Skip the file if it is not a socket. Also accept
3878 * DT_UNKNOWN (0) in case the C library or underlying
3879 * file system does not support d_type.
3881 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3883 #endif /* _DIRENT_HAVE_D_TYPE */
3884 if (os_strcmp(dent->d_name, ".") == 0 ||
3885 os_strcmp(dent->d_name, "..") == 0)
3887 printf("Selected interface '%s'\n", dent->d_name);
3888 ifname = os_strdup(dent->d_name);
3892 #endif /* CONFIG_CTRL_IFACE_UNIX */
3894 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3895 char buf[2048], *pos;
3897 struct wpa_ctrl *ctrl;
3900 ctrl = wpa_ctrl_open(NULL);
3904 len = sizeof(buf) - 1;
3905 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3908 pos = os_strchr(buf, '\n');
3911 ifname = os_strdup(buf);
3913 wpa_ctrl_close(ctrl);
3914 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3920 int main(int argc, char *argv[])
3922 int warning_displayed = 0;
3926 const char *global = NULL;
3928 if (os_program_init())
3932 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3937 action_file = optarg;
3946 ping_interval = atoi(optarg);
3952 printf("%s\n", wpa_cli_version);
3955 os_free(ctrl_ifname);
3956 ctrl_ifname = os_strdup(optarg);
3959 ctrl_iface_dir = optarg;
3970 interactive = (argc == optind) && (action_file == NULL);
3973 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3979 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3980 ctrl_conn = wpa_ctrl_open(NULL);
3981 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3982 ctrl_conn = wpa_ctrl_open(global);
3983 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3984 if (ctrl_conn == NULL) {
3985 fprintf(stderr, "Failed to connect to wpa_supplicant "
3986 "global interface: %s error: %s\n",
3987 global, strerror(errno));
3993 signal(SIGINT, wpa_cli_terminate);
3994 signal(SIGTERM, wpa_cli_terminate);
3995 #endif /* _WIN32_WCE */
3997 if (ctrl_ifname == NULL)
3998 ctrl_ifname = wpa_cli_get_default_ifname();
4002 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
4003 if (warning_displayed)
4004 printf("Connection established.\n");
4008 if (!warning_displayed) {
4009 printf("Could not connect to wpa_supplicant: "
4010 "%s - re-trying\n", ctrl_ifname);
4011 warning_displayed = 1;
4018 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
4019 fprintf(stderr, "Failed to connect to non-global "
4020 "ctrl_ifname: %s error: %s\n",
4021 ctrl_ifname, strerror(errno));
4026 if (wpa_ctrl_attach(ctrl_conn) == 0) {
4027 wpa_cli_attached = 1;
4029 printf("Warning: Failed to attach to "
4030 "wpa_supplicant.\n");
4036 if (daemonize && os_daemonize(pid_file))
4040 wpa_cli_interactive();
4041 else if (action_file)
4042 wpa_cli_action(ctrl_conn);
4044 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
4046 os_free(ctrl_ifname);
4053 #else /* CONFIG_CTRL_IFACE */
4054 int main(int argc, char *argv[])
4056 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
4059 #endif /* CONFIG_CTRL_IFACE */