2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
11 #ifdef CONFIG_CTRL_IFACE
13 #ifdef CONFIG_CTRL_IFACE_UNIX
15 #endif /* CONFIG_CTRL_IFACE_UNIX */
17 #include "common/wpa_ctrl.h"
18 #include "utils/common.h"
19 #include "utils/eloop.h"
20 #include "utils/edit.h"
21 #include "utils/list.h"
22 #include "common/version.h"
23 #include "common/ieee802_11_defs.h"
25 #include <cutils/properties.h>
29 static const char *wpa_cli_version =
30 "wpa_cli v" VERSION_STR "\n"
31 "Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> and contributors";
34 static const char *wpa_cli_license =
35 "This software may be distributed under the terms of the BSD license.\n"
36 "See README for more details.\n";
38 static const char *wpa_cli_full_license =
39 "This software may be distributed under the terms of the BSD license.\n"
41 "Redistribution and use in source and binary forms, with or without\n"
42 "modification, are permitted provided that the following conditions are\n"
45 "1. Redistributions of source code must retain the above copyright\n"
46 " notice, this list of conditions and the following disclaimer.\n"
48 "2. Redistributions in binary form must reproduce the above copyright\n"
49 " notice, this list of conditions and the following disclaimer in the\n"
50 " documentation and/or other materials provided with the distribution.\n"
52 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
53 " names of its contributors may be used to endorse or promote products\n"
54 " derived from this software without specific prior written permission.\n"
56 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
57 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
58 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
59 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
60 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
61 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
62 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
63 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
64 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
65 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
66 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
69 static struct wpa_ctrl *ctrl_conn;
70 static struct wpa_ctrl *mon_conn;
71 static int wpa_cli_quit = 0;
72 static int wpa_cli_attached = 0;
73 static int wpa_cli_connected = 0;
74 static int wpa_cli_last_id = 0;
75 #ifndef CONFIG_CTRL_IFACE_DIR
76 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
77 #endif /* CONFIG_CTRL_IFACE_DIR */
78 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
79 static char *ctrl_ifname = NULL;
80 static const char *pid_file = NULL;
81 static const char *action_file = NULL;
82 static int ping_interval = 5;
83 static int interactive = 0;
84 #if defined(CONFIG_P2P) && defined(ANDROID_P2P)
85 static char* redirect_interface = NULL;
88 struct cli_txt_entry {
93 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
94 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
95 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
98 static void print_help(void);
99 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
102 static void usage(void)
104 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
105 "[-a<action file>] \\\n"
106 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
108 " -h = help (show this usage text)\n"
109 " -v = shown version information\n"
110 " -a = run in daemon mode executing the action file based on "
113 " -B = run a daemon in the background\n"
114 " default path: " CONFIG_CTRL_IFACE_DIR "\n"
115 " default interface: first interface found in socket path\n");
120 static void cli_txt_list_free(struct cli_txt_entry *e)
122 dl_list_del(&e->list);
128 static void cli_txt_list_flush(struct dl_list *list)
130 struct cli_txt_entry *e;
131 while ((e = dl_list_first(list, struct cli_txt_entry, list)))
132 cli_txt_list_free(e);
136 static struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list,
139 struct cli_txt_entry *e;
140 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
141 if (os_strcmp(e->txt, txt) == 0)
148 static void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
150 struct cli_txt_entry *e;
151 e = cli_txt_list_get(txt_list, txt);
153 cli_txt_list_free(e);
157 static void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt)
161 if (hwaddr_aton(txt, addr) < 0)
163 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
164 cli_txt_list_del(txt_list, buf);
169 static void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt)
173 end = os_strchr(txt, ' ');
175 end = txt + os_strlen(txt);
176 buf = os_malloc(end - txt + 1);
179 os_memcpy(buf, txt, end - txt);
180 buf[end - txt] = '\0';
181 cli_txt_list_del(txt_list, buf);
184 #endif /* CONFIG_P2P */
187 static int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
189 struct cli_txt_entry *e;
190 e = cli_txt_list_get(txt_list, txt);
193 e = os_zalloc(sizeof(*e));
196 e->txt = os_strdup(txt);
197 if (e->txt == NULL) {
201 dl_list_add(txt_list, &e->list);
207 static int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
211 if (hwaddr_aton(txt, addr) < 0)
213 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
214 return cli_txt_list_add(txt_list, buf);
218 static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt)
223 end = os_strchr(txt, ' ');
225 end = txt + os_strlen(txt);
226 buf = os_malloc(end - txt + 1);
229 os_memcpy(buf, txt, end - txt);
230 buf[end - txt] = '\0';
231 ret = cli_txt_list_add(txt_list, buf);
235 #endif /* CONFIG_P2P */
238 static char ** cli_txt_list_array(struct dl_list *txt_list)
240 unsigned int i, count = dl_list_len(txt_list);
242 struct cli_txt_entry *e;
244 res = os_zalloc((count + 1) * sizeof(char *));
249 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
250 res[i] = os_strdup(e->txt);
260 static int get_cmd_arg_num(const char *str, int pos)
264 for (i = 0; i <= pos; i++) {
267 while (i <= pos && str[i] != ' ')
278 static int str_starts(const char *src, const char *match)
280 return os_strncmp(src, match, os_strlen(match)) == 0;
284 static int wpa_cli_show_event(const char *event)
288 start = os_strchr(event, '>');
294 * Skip BSS added/removed events since they can be relatively frequent
295 * and are likely of not much use for an interactive user.
297 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
298 str_starts(start, WPA_EVENT_BSS_REMOVED))
305 static int wpa_cli_open_connection(const char *ifname, int attach)
307 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
308 ctrl_conn = wpa_ctrl_open(ifname);
309 if (ctrl_conn == NULL)
312 if (attach && interactive)
313 mon_conn = wpa_ctrl_open(ifname);
316 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
324 if (access(ctrl_iface_dir, F_OK) < 0) {
325 cfile = os_strdup(ifname);
332 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
333 cfile = os_malloc(flen);
336 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
338 if (res < 0 || res >= flen) {
344 ctrl_conn = wpa_ctrl_open(cfile);
345 if (ctrl_conn == NULL) {
350 if (attach && interactive)
351 mon_conn = wpa_ctrl_open(cfile);
355 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
358 if (wpa_ctrl_attach(mon_conn) == 0) {
359 wpa_cli_attached = 1;
361 eloop_register_read_sock(
362 wpa_ctrl_get_fd(mon_conn),
363 wpa_cli_mon_receive, NULL, NULL);
365 printf("Warning: Failed to attach to "
366 "wpa_supplicant.\n");
375 static void wpa_cli_close_connection(void)
377 if (ctrl_conn == NULL)
380 if (wpa_cli_attached) {
381 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
382 wpa_cli_attached = 0;
384 wpa_ctrl_close(ctrl_conn);
387 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
388 wpa_ctrl_close(mon_conn);
394 static void wpa_cli_msg_cb(char *msg, size_t len)
400 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
407 #if defined(CONFIG_P2P) && defined(ANDROID_P2P)
413 if (ctrl_conn == NULL) {
414 printf("Not connected to wpa_supplicant - command dropped.\n");
417 #if defined(CONFIG_P2P) && defined(ANDROID_P2P)
418 if (redirect_interface) {
420 arg = os_strchr(cmd, ' ');
423 ret = os_snprintf(_cmd, sizeof(_cmd), "%s %s %s", cmd, redirect_interface, arg);
426 ret = os_snprintf(_cmd, sizeof(_cmd), "%s %s", cmd, redirect_interface);
429 os_free(redirect_interface);
430 redirect_interface = NULL;
433 len = sizeof(buf) - 1;
434 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
437 printf("'%s' command timed out.\n", cmd);
439 } else if (ret < 0) {
440 printf("'%s' command failed.\n", cmd);
446 if (interactive && len > 0 && buf[len - 1] != '\n')
453 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
455 return _wpa_ctrl_command(ctrl, cmd, 1);
459 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
461 if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
462 return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
463 if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
464 return wpa_ctrl_command(ctrl, "STATUS-WPS");
465 return wpa_ctrl_command(ctrl, "STATUS");
469 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
471 return wpa_ctrl_command(ctrl, "PING");
475 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
477 return wpa_ctrl_command(ctrl, "RELOG");
481 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
487 ret = os_snprintf(cmd, sizeof(cmd), "NOTE %s", argv[0]);
488 if (ret < 0 || (size_t) ret >= sizeof(cmd))
490 return wpa_ctrl_command(ctrl, cmd);
494 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
496 return wpa_ctrl_command(ctrl, "MIB");
500 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
502 return wpa_ctrl_command(ctrl, "PMKSA");
506 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
513 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
515 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
520 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
529 static void wpa_cli_show_variables(void)
531 printf("set variables:\n"
532 " EAPOL::heldPeriod (EAPOL state machine held period, "
534 " EAPOL::authPeriod (EAPOL state machine authentication "
535 "period, in seconds)\n"
536 " EAPOL::startPeriod (EAPOL state machine start period, in "
538 " EAPOL::maxStart (EAPOL state machine maximum start "
540 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
542 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
543 " threshold\n\tpercentage)\n"
544 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
545 "security\n\tassociation in seconds)\n");
549 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
555 wpa_cli_show_variables();
559 if (argc != 1 && argc != 2) {
560 printf("Invalid SET command: needs two arguments (variable "
561 "name and value)\n");
566 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
568 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s",
570 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
571 printf("Too long SET command.\n");
574 return wpa_ctrl_command(ctrl, cmd);
578 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
584 printf("Invalid GET command: need one argument (variable "
589 res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
590 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
591 printf("Too long GET command.\n");
594 return wpa_ctrl_command(ctrl, cmd);
598 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
600 return wpa_ctrl_command(ctrl, "LOGOFF");
604 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
606 return wpa_ctrl_command(ctrl, "LOGON");
610 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
613 return wpa_ctrl_command(ctrl, "REASSOCIATE");
617 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
624 printf("Invalid PREAUTH command: needs one argument "
629 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
630 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
631 printf("Too long PREAUTH command.\n");
634 return wpa_ctrl_command(ctrl, cmd);
638 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
644 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
648 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
649 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
650 printf("Too long AP_SCAN command.\n");
653 return wpa_ctrl_command(ctrl, cmd);
657 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
664 printf("Invalid SCAN_INTERVAL command: needs one argument "
665 "scan_interval value)\n");
668 res = os_snprintf(cmd, sizeof(cmd), "SCAN_INTERVAL %s", argv[0]);
669 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
670 printf("Too long SCAN_INTERVAL command.\n");
673 return wpa_ctrl_command(ctrl, cmd);
677 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
684 printf("Invalid BSS_EXPIRE_AGE command: needs one argument "
685 "(bss_expire_age value)\n");
688 res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_AGE %s", argv[0]);
689 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
690 printf("Too long BSS_EXPIRE_AGE command.\n");
693 return wpa_ctrl_command(ctrl, cmd);
697 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
704 printf("Invalid BSS_EXPIRE_COUNT command: needs one argument "
705 "(bss_expire_count value)\n");
708 res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_COUNT %s", argv[0]);
709 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
710 printf("Too long BSS_EXPIRE_COUNT command.\n");
713 return wpa_ctrl_command(ctrl, cmd);
717 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
724 printf("Invalid STKSTART command: needs one argument "
725 "(Peer STA MAC address)\n");
729 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
730 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
731 printf("Too long STKSTART command.\n");
734 return wpa_ctrl_command(ctrl, cmd);
738 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
744 printf("Invalid FT_DS command: needs one argument "
745 "(Target AP MAC address)\n");
749 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
750 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
751 printf("Too long FT_DS command.\n");
754 return wpa_ctrl_command(ctrl, cmd);
758 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
765 return wpa_ctrl_command(ctrl, "WPS_PBC");
769 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
770 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
771 printf("Too long WPS_PBC command.\n");
774 return wpa_ctrl_command(ctrl, cmd);
778 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
784 printf("Invalid WPS_PIN command: need one or two arguments:\n"
785 "- BSSID: use 'any' to select any\n"
786 "- PIN: optional, used only with devices that have no "
792 /* Use dynamically generated PIN (returned as reply) */
793 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
794 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
795 printf("Too long WPS_PIN command.\n");
798 return wpa_ctrl_command(ctrl, cmd);
801 /* Use hardcoded PIN from a label */
802 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
803 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
804 printf("Too long WPS_PIN command.\n");
807 return wpa_ctrl_command(ctrl, cmd);
811 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
817 if (argc != 1 && argc != 2) {
818 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
819 "- PIN to be verified\n");
824 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
827 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
829 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
830 printf("Too long WPS_CHECK_PIN command.\n");
833 return wpa_ctrl_command(ctrl, cmd);
837 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
840 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
844 #ifdef CONFIG_WPS_OOB
845 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
850 if (argc != 3 && argc != 4) {
851 printf("Invalid WPS_OOB command: need three or four "
853 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
854 "- PATH: path of OOB device like '/mnt'\n"
855 "- METHOD: OOB method 'pin-e' or 'pin-r', "
857 "- DEV_NAME: (only for NFC) device name like "
863 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
864 argv[0], argv[1], argv[2]);
866 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
867 argv[0], argv[1], argv[2], argv[3]);
868 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
869 printf("Too long WPS_OOB command.\n");
872 return wpa_ctrl_command(ctrl, cmd);
874 #endif /* CONFIG_WPS_OOB */
877 #ifdef CONFIG_WPS_NFC
879 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
885 res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC %s",
888 res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC");
889 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
890 printf("Too long WPS_NFC command.\n");
893 return wpa_ctrl_command(ctrl, cmd);
897 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
904 printf("Invalid WPS_NFC_TOKEN command: need one argument:\n"
905 "format: WPS or NDEF\n");
909 res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC_TOKEN %s",
912 res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC_TOKEN");
913 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
914 printf("Too long WPS_NFC_TOKEN command.\n");
917 return wpa_ctrl_command(ctrl, cmd);
921 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
929 printf("Invalid 'wps_nfc_tag_read' command - one argument "
934 buflen = 18 + os_strlen(argv[0]);
935 buf = os_malloc(buflen);
938 os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
940 ret = wpa_ctrl_command(ctrl, buf);
946 #endif /* CONFIG_WPS_NFC */
949 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
955 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
957 else if (argc == 5 || argc == 6) {
958 char ssid_hex[2 * 32 + 1];
959 char key_hex[2 * 64 + 1];
963 for (i = 0; i < 32; i++) {
964 if (argv[2][i] == '\0')
966 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
971 for (i = 0; i < 64; i++) {
972 if (argv[5][i] == '\0')
974 os_snprintf(&key_hex[i * 2], 3, "%02x",
979 res = os_snprintf(cmd, sizeof(cmd),
980 "WPS_REG %s %s %s %s %s %s",
981 argv[0], argv[1], ssid_hex, argv[3], argv[4],
984 printf("Invalid WPS_REG command: need two arguments:\n"
985 "- BSSID of the target AP\n"
987 printf("Alternatively, six arguments can be used to "
988 "reconfigure the AP:\n"
989 "- BSSID of the target AP\n"
992 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
993 "- new encr (NONE, WEP, TKIP, CCMP)\n"
998 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
999 printf("Too long WPS_REG command.\n");
1002 return wpa_ctrl_command(ctrl, cmd);
1006 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
1013 printf("Invalid WPS_AP_PIN command: needs at least one "
1019 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s %s",
1020 argv[0], argv[1], argv[2]);
1022 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s",
1025 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s",
1027 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1028 printf("Too long WPS_AP_PIN command.\n");
1031 return wpa_ctrl_command(ctrl, cmd);
1035 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
1040 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
1041 return wpa_ctrl_command(ctrl, cmd);
1043 return wpa_ctrl_command(ctrl, "WPS_ER_START");
1047 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
1050 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
1055 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
1062 printf("Invalid WPS_ER_PIN command: need at least two "
1064 "- UUID: use 'any' to select any\n"
1065 "- PIN: Enrollee PIN\n"
1066 "optional: - Enrollee MAC address\n");
1071 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
1072 argv[0], argv[1], argv[2]);
1074 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
1076 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1077 printf("Too long WPS_ER_PIN command.\n");
1080 return wpa_ctrl_command(ctrl, cmd);
1084 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
1091 printf("Invalid WPS_ER_PBC command: need one argument:\n"
1092 "- UUID: Specify the Enrollee\n");
1096 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
1098 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1099 printf("Too long WPS_ER_PBC command.\n");
1102 return wpa_ctrl_command(ctrl, cmd);
1106 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
1113 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1114 "- UUID: specify which AP to use\n"
1119 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
1121 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1122 printf("Too long WPS_ER_LEARN command.\n");
1125 return wpa_ctrl_command(ctrl, cmd);
1129 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
1136 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1138 "- UUID: specify which AP to use\n"
1139 "- Network configuration id\n");
1143 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_SET_CONFIG %s %s",
1145 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1146 printf("Too long WPS_ER_SET_CONFIG command.\n");
1149 return wpa_ctrl_command(ctrl, cmd);
1153 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
1159 if (argc == 5 || argc == 6) {
1160 char ssid_hex[2 * 32 + 1];
1161 char key_hex[2 * 64 + 1];
1165 for (i = 0; i < 32; i++) {
1166 if (argv[2][i] == '\0')
1168 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1173 for (i = 0; i < 64; i++) {
1174 if (argv[5][i] == '\0')
1176 os_snprintf(&key_hex[i * 2], 3, "%02x",
1181 res = os_snprintf(cmd, sizeof(cmd),
1182 "WPS_ER_CONFIG %s %s %s %s %s %s",
1183 argv[0], argv[1], ssid_hex, argv[3], argv[4],
1186 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1190 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1191 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1196 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1197 printf("Too long WPS_ER_CONFIG command.\n");
1200 return wpa_ctrl_command(ctrl, cmd);
1204 #ifdef CONFIG_WPS_NFC
1205 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
1212 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
1214 "- WPS/NDEF: token format\n"
1215 "- UUID: specify which AP to use\n");
1219 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_NFC_CONFIG_TOKEN %s %s",
1221 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1222 printf("Too long WPS_ER_NFC_CONFIG_TOKEN command.\n");
1225 return wpa_ctrl_command(ctrl, cmd);
1227 #endif /* CONFIG_WPS_NFC */
1230 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1236 printf("Invalid IBSS_RSN command: needs one argument "
1237 "(Peer STA MAC address)\n");
1241 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
1242 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1243 printf("Too long IBSS_RSN command.\n");
1246 return wpa_ctrl_command(ctrl, cmd);
1250 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1256 printf("Invalid LEVEL command: needs one argument (debug "
1260 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
1261 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1262 printf("Too long LEVEL command.\n");
1265 return wpa_ctrl_command(ctrl, cmd);
1269 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1271 char cmd[256], *pos, *end;
1275 printf("Invalid IDENTITY command: needs two arguments "
1276 "(network id and identity)\n");
1280 end = cmd + sizeof(cmd);
1282 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1284 if (ret < 0 || ret >= end - pos) {
1285 printf("Too long IDENTITY command.\n");
1289 for (i = 2; i < argc; i++) {
1290 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1291 if (ret < 0 || ret >= end - pos) {
1292 printf("Too long IDENTITY command.\n");
1298 return wpa_ctrl_command(ctrl, cmd);
1302 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1304 char cmd[256], *pos, *end;
1308 printf("Invalid PASSWORD command: needs two arguments "
1309 "(network id and password)\n");
1313 end = cmd + sizeof(cmd);
1315 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1317 if (ret < 0 || ret >= end - pos) {
1318 printf("Too long PASSWORD command.\n");
1322 for (i = 2; i < argc; i++) {
1323 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1324 if (ret < 0 || ret >= end - pos) {
1325 printf("Too long PASSWORD command.\n");
1331 return wpa_ctrl_command(ctrl, cmd);
1335 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1338 char cmd[256], *pos, *end;
1342 printf("Invalid NEW_PASSWORD command: needs two arguments "
1343 "(network id and password)\n");
1347 end = cmd + sizeof(cmd);
1349 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1351 if (ret < 0 || ret >= end - pos) {
1352 printf("Too long NEW_PASSWORD command.\n");
1356 for (i = 2; i < argc; i++) {
1357 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1358 if (ret < 0 || ret >= end - pos) {
1359 printf("Too long NEW_PASSWORD command.\n");
1365 return wpa_ctrl_command(ctrl, cmd);
1369 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1371 char cmd[256], *pos, *end;
1375 printf("Invalid PIN command: needs two arguments "
1376 "(network id and pin)\n");
1380 end = cmd + sizeof(cmd);
1382 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1384 if (ret < 0 || ret >= end - pos) {
1385 printf("Too long PIN command.\n");
1389 for (i = 2; i < argc; i++) {
1390 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1391 if (ret < 0 || ret >= end - pos) {
1392 printf("Too long PIN command.\n");
1397 return wpa_ctrl_command(ctrl, cmd);
1401 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1403 char cmd[256], *pos, *end;
1407 printf("Invalid OTP command: needs two arguments (network "
1408 "id and password)\n");
1412 end = cmd + sizeof(cmd);
1414 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1416 if (ret < 0 || ret >= end - pos) {
1417 printf("Too long OTP command.\n");
1421 for (i = 2; i < argc; i++) {
1422 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1423 if (ret < 0 || ret >= end - pos) {
1424 printf("Too long OTP command.\n");
1430 return wpa_ctrl_command(ctrl, cmd);
1434 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1437 char cmd[256], *pos, *end;
1441 printf("Invalid PASSPHRASE command: needs two arguments "
1442 "(network id and passphrase)\n");
1446 end = cmd + sizeof(cmd);
1448 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1450 if (ret < 0 || ret >= end - pos) {
1451 printf("Too long PASSPHRASE command.\n");
1455 for (i = 2; i < argc; i++) {
1456 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1457 if (ret < 0 || ret >= end - pos) {
1458 printf("Too long PASSPHRASE command.\n");
1464 return wpa_ctrl_command(ctrl, cmd);
1468 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1470 char cmd[256], *pos, *end;
1474 printf("Invalid BSSID command: needs two arguments (network "
1479 end = cmd + sizeof(cmd);
1481 ret = os_snprintf(pos, end - pos, "BSSID");
1482 if (ret < 0 || ret >= end - pos) {
1483 printf("Too long BSSID 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 BSSID command.\n");
1496 return wpa_ctrl_command(ctrl, cmd);
1500 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1502 char cmd[256], *pos, *end;
1505 end = cmd + sizeof(cmd);
1507 ret = os_snprintf(pos, end - pos, "BLACKLIST");
1508 if (ret < 0 || ret >= end - pos) {
1509 printf("Too long BLACKLIST command.\n");
1513 for (i = 0; i < argc; i++) {
1514 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1515 if (ret < 0 || ret >= end - pos) {
1516 printf("Too long BLACKLIST command.\n");
1522 return wpa_ctrl_command(ctrl, cmd);
1526 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1528 char cmd[256], *pos, *end;
1531 end = cmd + sizeof(cmd);
1533 ret = os_snprintf(pos, end - pos, "LOG_LEVEL");
1534 if (ret < 0 || ret >= end - pos) {
1535 printf("Too long LOG_LEVEL command.\n");
1539 for (i = 0; i < argc; i++) {
1540 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1541 if (ret < 0 || ret >= end - pos) {
1542 printf("Too long LOG_LEVEL command.\n");
1548 return wpa_ctrl_command(ctrl, cmd);
1552 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1555 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1559 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1566 printf("Invalid SELECT_NETWORK command: needs one argument "
1571 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1572 if (res < 0 || (size_t) res >= sizeof(cmd))
1574 cmd[sizeof(cmd) - 1] = '\0';
1576 return wpa_ctrl_command(ctrl, cmd);
1580 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1587 printf("Invalid ENABLE_NETWORK command: needs one argument "
1593 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s %s",
1596 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s",
1598 if (res < 0 || (size_t) res >= sizeof(cmd))
1600 cmd[sizeof(cmd) - 1] = '\0';
1602 return wpa_ctrl_command(ctrl, cmd);
1606 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1613 printf("Invalid DISABLE_NETWORK command: needs one argument "
1618 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1619 if (res < 0 || (size_t) res >= sizeof(cmd))
1621 cmd[sizeof(cmd) - 1] = '\0';
1623 return wpa_ctrl_command(ctrl, cmd);
1627 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1630 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1634 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1641 printf("Invalid REMOVE_NETWORK command: needs one argument "
1646 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1647 if (res < 0 || (size_t) res >= sizeof(cmd))
1649 cmd[sizeof(cmd) - 1] = '\0';
1651 return wpa_ctrl_command(ctrl, cmd);
1655 static void wpa_cli_show_network_variables(void)
1657 printf("set_network variables:\n"
1658 " ssid (network name, SSID)\n"
1659 " psk (WPA passphrase or pre-shared key)\n"
1660 " key_mgmt (key management protocol)\n"
1661 " identity (EAP identity)\n"
1662 " password (EAP password)\n"
1665 "Note: Values are entered in the same format as the "
1666 "configuration file is using,\n"
1667 "i.e., strings values need to be inside double quotation "
1669 "For example: set_network 1 ssid \"network name\"\n"
1671 "Please see wpa_supplicant.conf documentation for full list "
1672 "of\navailable variables.\n");
1676 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1683 wpa_cli_show_network_variables();
1688 printf("Invalid SET_NETWORK command: needs three arguments\n"
1689 "(network id, variable name, and value)\n");
1693 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1694 argv[0], argv[1], argv[2]);
1695 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1696 printf("Too long SET_NETWORK command.\n");
1699 return wpa_ctrl_command(ctrl, cmd);
1703 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1710 wpa_cli_show_network_variables();
1715 printf("Invalid GET_NETWORK command: needs two arguments\n"
1716 "(network id and variable name)\n");
1720 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1722 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1723 printf("Too long GET_NETWORK command.\n");
1726 return wpa_ctrl_command(ctrl, cmd);
1730 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1733 return wpa_ctrl_command(ctrl, "LIST_CREDS");
1737 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1739 return wpa_ctrl_command(ctrl, "ADD_CRED");
1743 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1750 printf("Invalid REMOVE_CRED command: needs one argument "
1755 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_CRED %s", argv[0]);
1756 if (res < 0 || (size_t) res >= sizeof(cmd))
1758 cmd[sizeof(cmd) - 1] = '\0';
1760 return wpa_ctrl_command(ctrl, cmd);
1764 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1770 printf("Invalid SET_CRED command: needs three arguments\n"
1771 "(cred id, variable name, and value)\n");
1775 res = os_snprintf(cmd, sizeof(cmd), "SET_CRED %s %s %s",
1776 argv[0], argv[1], argv[2]);
1777 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1778 printf("Too long SET_CRED command.\n");
1781 return wpa_ctrl_command(ctrl, cmd);
1785 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1788 return wpa_ctrl_command(ctrl, "DISCONNECT");
1792 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1795 return wpa_ctrl_command(ctrl, "RECONNECT");
1799 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1802 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1806 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1808 return wpa_ctrl_command(ctrl, "SCAN");
1812 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1815 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1819 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1825 printf("Invalid BSS command: need at least one argument"
1826 "(index or BSSID)\n");
1830 res = os_snprintf(cmd, sizeof(cmd), "BSS %s%s%s%s%s", argv[0],
1831 argc > 1 ? " " : "", argc > 1 ? argv[1] : "",
1832 argc > 2 ? " " : "", argc > 2 ? argv[2] : "");
1834 if (res < 0 || (size_t) res >= sizeof(cmd))
1836 cmd[sizeof(cmd) - 1] = '\0';
1838 return wpa_ctrl_command(ctrl, cmd);
1842 static char ** wpa_cli_complete_bss(const char *str, int pos)
1844 int arg = get_cmd_arg_num(str, pos);
1849 res = cli_txt_list_array(&bsses);
1857 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1863 if (argc < 1 || argc > 2) {
1864 printf("Invalid GET_CAPABILITY command: need either one or "
1869 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1870 printf("Invalid GET_CAPABILITY command: second argument, "
1871 "if any, must be 'strict'\n");
1875 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1876 (argc == 2) ? " strict" : "");
1877 if (res < 0 || (size_t) res >= sizeof(cmd))
1879 cmd[sizeof(cmd) - 1] = '\0';
1881 return wpa_ctrl_command(ctrl, cmd);
1885 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1887 printf("Available interfaces:\n");
1888 return wpa_ctrl_command(ctrl, "INTERFACES");
1892 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1895 wpa_cli_list_interfaces(ctrl);
1899 wpa_cli_close_connection();
1900 os_free(ctrl_ifname);
1901 ctrl_ifname = os_strdup(argv[0]);
1903 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1904 printf("Connected to interface '%s.\n", ctrl_ifname);
1906 printf("Could not connect to interface '%s' - re-trying\n",
1913 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1916 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1920 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1923 return wpa_ctrl_command(ctrl, "TERMINATE");
1927 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1934 printf("Invalid INTERFACE_ADD command: needs at least one "
1935 "argument (interface name)\n"
1936 "All arguments: ifname confname driver ctrl_interface "
1937 "driver_param bridge_name\n");
1942 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1943 * <driver_param>TAB<bridge_name>
1945 res = os_snprintf(cmd, sizeof(cmd),
1946 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1948 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1949 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1950 argc > 5 ? argv[5] : "");
1951 if (res < 0 || (size_t) res >= sizeof(cmd))
1953 cmd[sizeof(cmd) - 1] = '\0';
1954 return wpa_ctrl_command(ctrl, cmd);
1958 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1965 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1966 "(interface name)\n");
1970 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1971 if (res < 0 || (size_t) res >= sizeof(cmd))
1973 cmd[sizeof(cmd) - 1] = '\0';
1974 return wpa_ctrl_command(ctrl, cmd);
1978 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1981 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1986 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1990 printf("Invalid 'sta' command - exactly one argument, STA "
1991 "address, is required.\n");
1994 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1995 return wpa_ctrl_command(ctrl, buf);
1999 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
2000 char *addr, size_t addr_len)
2002 char buf[4096], *pos;
2006 if (ctrl_conn == NULL) {
2007 printf("Not connected to hostapd - command dropped.\n");
2010 len = sizeof(buf) - 1;
2011 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2014 printf("'%s' command timed out.\n", cmd);
2016 } else if (ret < 0) {
2017 printf("'%s' command failed.\n", cmd);
2022 if (os_memcmp(buf, "FAIL", 4) == 0)
2027 while (*pos != '\0' && *pos != '\n')
2030 os_strlcpy(addr, buf, addr_len);
2035 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
2037 char addr[32], cmd[64];
2039 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
2042 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
2043 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
2049 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
2054 printf("Invalid 'deauthenticate' command - exactly one "
2055 "argument, STA address, is required.\n");
2059 os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s %s",
2062 os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s", argv[0]);
2063 return wpa_ctrl_command(ctrl, buf);
2067 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
2072 printf("Invalid 'disassociate' command - exactly one "
2073 "argument, STA address, is required.\n");
2077 os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s %s",
2080 os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s", argv[0]);
2081 return wpa_ctrl_command(ctrl, buf);
2083 #endif /* CONFIG_AP */
2086 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
2088 return wpa_ctrl_command(ctrl, "SUSPEND");
2092 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
2094 return wpa_ctrl_command(ctrl, "RESUME");
2098 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
2100 return wpa_ctrl_command(ctrl, "DROP_SA");
2104 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
2110 printf("Invalid ROAM command: needs one argument "
2111 "(target AP's BSSID)\n");
2115 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
2116 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2117 printf("Too long ROAM command.\n");
2120 return wpa_ctrl_command(ctrl, cmd);
2126 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
2132 return wpa_ctrl_command(ctrl, "P2P_FIND");
2135 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s %s",
2136 argv[0], argv[1], argv[2]);
2138 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
2141 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
2142 if (res < 0 || (size_t) res >= sizeof(cmd))
2144 cmd[sizeof(cmd) - 1] = '\0';
2145 return wpa_ctrl_command(ctrl, cmd);
2149 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
2152 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
2156 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
2163 printf("Invalid P2P_CONNECT command: needs at least two "
2164 "arguments (address and pbc/PIN)\n");
2169 res = os_snprintf(cmd, sizeof(cmd),
2170 "P2P_CONNECT %s %s %s %s %s %s",
2171 argv[0], argv[1], argv[2], argv[3],
2176 res = os_snprintf(cmd, sizeof(cmd),
2177 "P2P_CONNECT %s %s %s %s %s",
2178 argv[0], argv[1], argv[2], argv[3],
2181 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
2182 argv[0], argv[1], argv[2], argv[3]);
2184 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
2185 argv[0], argv[1], argv[2]);
2187 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
2189 if (res < 0 || (size_t) res >= sizeof(cmd))
2191 cmd[sizeof(cmd) - 1] = '\0';
2192 return wpa_ctrl_command(ctrl, cmd);
2196 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
2198 int arg = get_cmd_arg_num(str, pos);
2203 res = cli_txt_list_array(&p2p_peers);
2211 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
2218 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
2220 res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
2221 if (res < 0 || (size_t) res >= sizeof(cmd))
2223 cmd[sizeof(cmd) - 1] = '\0';
2224 return wpa_ctrl_command(ctrl, cmd);
2228 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
2235 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
2236 "(interface name)\n");
2240 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
2241 if (res < 0 || (size_t) res >= sizeof(cmd))
2243 cmd[sizeof(cmd) - 1] = '\0';
2244 return wpa_ctrl_command(ctrl, cmd);
2248 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
2250 int arg = get_cmd_arg_num(str, pos);
2255 res = cli_txt_list_array(&p2p_groups);
2263 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
2270 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
2273 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s %s",
2276 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %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_prov_disc(struct wpa_ctrl *ctrl, int argc,
2291 if (argc != 2 && argc != 3) {
2292 printf("Invalid P2P_PROV_DISC command: needs at least "
2293 "two arguments, address and config method\n"
2294 "(display, keypad, or pbc) and an optional join\n");
2299 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s %s",
2300 argv[0], argv[1], argv[2]);
2302 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
2304 if (res < 0 || (size_t) res >= sizeof(cmd))
2306 cmd[sizeof(cmd) - 1] = '\0';
2307 return wpa_ctrl_command(ctrl, cmd);
2311 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
2314 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
2318 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
2324 if (argc != 2 && argc != 4) {
2325 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2326 "arguments (address and TLVs) or four arguments "
2327 "(address, \"upnp\", version, search target "
2333 res = os_snprintf(cmd, sizeof(cmd),
2334 "P2P_SERV_DISC_REQ %s %s %s %s",
2335 argv[0], argv[1], argv[2], argv[3]);
2337 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %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_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
2347 int argc, char *argv[])
2353 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
2354 "argument (pending request identifier)\n");
2358 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
2360 if (res < 0 || (size_t) res >= sizeof(cmd))
2362 cmd[sizeof(cmd) - 1] = '\0';
2363 return wpa_ctrl_command(ctrl, cmd);
2367 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
2374 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2375 "arguments (freq, address, dialog token, and TLVs)\n");
2379 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
2380 argv[0], argv[1], argv[2], argv[3]);
2381 if (res < 0 || (size_t) res >= sizeof(cmd))
2383 cmd[sizeof(cmd) - 1] = '\0';
2384 return wpa_ctrl_command(ctrl, cmd);
2388 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
2391 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
2395 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
2396 int argc, char *argv[])
2402 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
2403 "argument (external processing: 0/1)\n");
2407 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
2409 if (res < 0 || (size_t) res >= sizeof(cmd))
2411 cmd[sizeof(cmd) - 1] = '\0';
2412 return wpa_ctrl_command(ctrl, cmd);
2416 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
2419 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
2423 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
2429 if (argc != 3 && argc != 4) {
2430 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
2436 res = os_snprintf(cmd, sizeof(cmd),
2437 "P2P_SERVICE_ADD %s %s %s %s",
2438 argv[0], argv[1], argv[2], argv[3]);
2440 res = os_snprintf(cmd, sizeof(cmd),
2441 "P2P_SERVICE_ADD %s %s %s",
2442 argv[0], argv[1], argv[2]);
2443 if (res < 0 || (size_t) res >= sizeof(cmd))
2445 cmd[sizeof(cmd) - 1] = '\0';
2446 return wpa_ctrl_command(ctrl, cmd);
2450 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2456 if (argc != 2 && argc != 3) {
2457 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2463 res = os_snprintf(cmd, sizeof(cmd),
2464 "P2P_SERVICE_DEL %s %s %s",
2465 argv[0], argv[1], argv[2]);
2467 res = os_snprintf(cmd, sizeof(cmd),
2468 "P2P_SERVICE_DEL %s %s",
2470 if (res < 0 || (size_t) res >= sizeof(cmd))
2472 cmd[sizeof(cmd) - 1] = '\0';
2473 return wpa_ctrl_command(ctrl, cmd);
2477 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2478 int argc, char *argv[])
2484 printf("Invalid P2P_REJECT command: needs one argument "
2485 "(peer address)\n");
2489 res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
2490 if (res < 0 || (size_t) res >= sizeof(cmd))
2492 cmd[sizeof(cmd) - 1] = '\0';
2493 return wpa_ctrl_command(ctrl, cmd);
2497 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2498 int argc, char *argv[])
2504 printf("Invalid P2P_INVITE command: needs at least one "
2510 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
2511 argv[0], argv[1], argv[2]);
2513 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
2516 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
2517 if (res < 0 || (size_t) res >= sizeof(cmd))
2519 cmd[sizeof(cmd) - 1] = '\0';
2520 return wpa_ctrl_command(ctrl, cmd);
2524 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2528 printf("Invalid 'p2p_peer' command - exactly one argument, "
2529 "P2P peer device address, is required.\n");
2532 os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
2533 return wpa_ctrl_command(ctrl, buf);
2537 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2539 int arg = get_cmd_arg_num(str, pos);
2544 res = cli_txt_list_array(&p2p_peers);
2552 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2553 char *addr, size_t addr_len,
2556 char buf[4096], *pos;
2560 if (ctrl_conn == NULL)
2562 len = sizeof(buf) - 1;
2563 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2566 printf("'%s' command timed out.\n", cmd);
2568 } else if (ret < 0) {
2569 printf("'%s' command failed.\n", cmd);
2574 if (os_memcmp(buf, "FAIL", 4) == 0)
2578 while (*pos != '\0' && *pos != '\n')
2581 os_strlcpy(addr, buf, addr_len);
2582 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2583 printf("%s\n", addr);
2588 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2590 char addr[32], cmd[64];
2593 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2595 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2596 addr, sizeof(addr), discovered))
2599 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2600 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2607 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2613 printf("Invalid P2P_SET command: needs two arguments (field, "
2618 res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2619 if (res < 0 || (size_t) res >= sizeof(cmd))
2621 cmd[sizeof(cmd) - 1] = '\0';
2622 return wpa_ctrl_command(ctrl, cmd);
2626 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2628 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2632 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2635 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2639 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2646 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2647 "(peer address)\n");
2651 res = os_snprintf(cmd, sizeof(cmd), "P2P_UNAUTHORIZE %s", argv[0]);
2653 if (res < 0 || (size_t) res >= sizeof(cmd))
2656 cmd[sizeof(cmd) - 1] = '\0';
2657 return wpa_ctrl_command(ctrl, cmd);
2661 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2667 if (argc != 0 && argc != 2 && argc != 4) {
2668 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2669 "(preferred duration, interval; in microsecods).\n"
2670 "Optional second pair can be used to provide "
2671 "acceptable values.\n");
2676 res = os_snprintf(cmd, sizeof(cmd),
2677 "P2P_PRESENCE_REQ %s %s %s %s",
2678 argv[0], argv[1], argv[2], argv[3]);
2680 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2683 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2684 if (res < 0 || (size_t) res >= sizeof(cmd))
2686 cmd[sizeof(cmd) - 1] = '\0';
2687 return wpa_ctrl_command(ctrl, cmd);
2691 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2697 if (argc != 0 && argc != 2) {
2698 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2699 "(availability period, availability interval; in "
2701 "Extended Listen Timing can be cancelled with this "
2702 "command when used without parameters.\n");
2707 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2710 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2711 if (res < 0 || (size_t) res >= sizeof(cmd))
2713 cmd[sizeof(cmd) - 1] = '\0';
2714 return wpa_ctrl_command(ctrl, cmd);
2717 #endif /* CONFIG_P2P */
2720 #ifdef CONFIG_INTERWORKING
2721 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2724 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2728 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2731 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2735 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2742 return wpa_ctrl_command(ctrl, "INTERWORKING_SELECT");
2744 res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_SELECT %s", argv[0]);
2745 if (res < 0 || (size_t) res >= sizeof(cmd))
2747 cmd[sizeof(cmd) - 1] = '\0';
2748 return wpa_ctrl_command(ctrl, cmd);
2752 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2759 printf("Invalid INTERWORKING_CONNECT commands: needs one "
2760 "argument (BSSID)\n");
2764 res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_CONNECT %s",
2766 if (res < 0 || (size_t) res >= sizeof(cmd))
2768 cmd[sizeof(cmd) - 1] = '\0';
2769 return wpa_ctrl_command(ctrl, cmd);
2773 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2779 printf("Invalid ANQP_GET command: needs two arguments "
2780 "(addr and info id list)\n");
2784 res = os_snprintf(cmd, sizeof(cmd), "ANQP_GET %s %s",
2786 if (res < 0 || (size_t) res >= sizeof(cmd))
2788 cmd[sizeof(cmd) - 1] = '\0';
2789 return wpa_ctrl_command(ctrl, cmd);
2791 #endif /* CONFIG_INTERWORKING */
2796 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2803 printf("Invalid HS20_ANQP_GET command: needs two arguments "
2804 "(addr and subtype list)\n");
2808 res = os_snprintf(cmd, sizeof(cmd), "HS20_ANQP_GET %s %s",
2810 if (res < 0 || (size_t) res >= sizeof(cmd))
2812 cmd[sizeof(cmd) - 1] = '\0';
2813 return wpa_ctrl_command(ctrl, cmd);
2817 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2824 printf("Command needs one or two arguments (dst mac addr and "
2825 "optional home realm)\n");
2830 res = os_snprintf(cmd, sizeof(cmd),
2831 "HS20_GET_NAI_HOME_REALM_LIST %s",
2834 res = os_snprintf(cmd, sizeof(cmd),
2835 "HS20_GET_NAI_HOME_REALM_LIST %s %s",
2837 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2838 printf("Too long command.\n");
2842 return wpa_ctrl_command(ctrl, cmd);
2845 #endif /* CONFIG_HS20 */
2848 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2855 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2856 "(0/1 = disable/enable automatic reconnection)\n");
2859 res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2860 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2861 printf("Too long STA_AUTOCONNECT command.\n");
2864 return wpa_ctrl_command(ctrl, cmd);
2868 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2875 printf("Invalid TDLS_DISCOVER command: needs one argument "
2876 "(Peer STA MAC address)\n");
2880 res = os_snprintf(cmd, sizeof(cmd), "TDLS_DISCOVER %s", argv[0]);
2881 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2882 printf("Too long TDLS_DISCOVER command.\n");
2885 return wpa_ctrl_command(ctrl, cmd);
2889 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2896 printf("Invalid TDLS_SETUP command: needs one argument "
2897 "(Peer STA MAC address)\n");
2901 res = os_snprintf(cmd, sizeof(cmd), "TDLS_SETUP %s", argv[0]);
2902 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2903 printf("Too long TDLS_SETUP command.\n");
2906 return wpa_ctrl_command(ctrl, cmd);
2910 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2917 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2918 "(Peer STA MAC address)\n");
2922 res = os_snprintf(cmd, sizeof(cmd), "TDLS_TEARDOWN %s", argv[0]);
2923 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2924 printf("Too long TDLS_TEARDOWN command.\n");
2927 return wpa_ctrl_command(ctrl, cmd);
2931 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2934 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2938 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
2941 return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
2945 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2948 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2952 #ifdef CONFIG_AUTOSCAN
2954 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
2960 return wpa_ctrl_command(ctrl, "AUTOSCAN ");
2962 res = os_snprintf(cmd, sizeof(cmd), "AUTOSCAN %s", argv[0]);
2963 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2964 printf("Too long AUTOSCAN command.\n");
2968 return wpa_ctrl_command(ctrl, cmd);
2971 #endif /* CONFIG_AUTOSCAN */
2975 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
2982 printf("Invalid DRIVER command: needs one argument (cmd)\n");
2986 len = os_snprintf(cmd, sizeof(cmd), "DRIVER %s", argv[0]);
2987 for (i=1; i < argc; i++)
2988 len += os_snprintf(cmd + len, sizeof(cmd) - len, " %s", argv[i]);
2989 cmd[sizeof(cmd) - 1] = '\0';
2990 printf("%s: %s\n", __func__, cmd);
2991 return wpa_ctrl_command(ctrl, cmd);
2995 enum wpa_cli_cmd_flags {
2996 cli_cmd_flag_none = 0x00,
2997 cli_cmd_flag_sensitive = 0x01
3000 struct wpa_cli_cmd {
3002 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
3003 enum wpa_cli_cmd_flags flags;
3007 static struct wpa_cli_cmd wpa_cli_commands[] = {
3008 { "status", wpa_cli_cmd_status,
3010 "[verbose] = get current WPA/EAPOL/EAP status" },
3011 { "ping", wpa_cli_cmd_ping,
3013 "= pings wpa_supplicant" },
3014 { "relog", wpa_cli_cmd_relog,
3016 "= re-open log-file (allow rolling logs)" },
3017 { "note", wpa_cli_cmd_note,
3019 "<text> = add a note to wpa_supplicant debug log" },
3020 { "mib", wpa_cli_cmd_mib,
3022 "= get MIB variables (dot1x, dot11)" },
3023 { "help", wpa_cli_cmd_help,
3025 "= show this usage help" },
3026 { "interface", wpa_cli_cmd_interface,
3028 "[ifname] = show interfaces/select interface" },
3029 { "level", wpa_cli_cmd_level,
3031 "<debug level> = change debug level" },
3032 { "license", wpa_cli_cmd_license,
3034 "= show full wpa_cli license" },
3035 { "quit", wpa_cli_cmd_quit,
3038 { "set", wpa_cli_cmd_set,
3040 "= set variables (shows list of variables when run without "
3042 { "get", wpa_cli_cmd_get,
3044 "<name> = get information" },
3045 { "logon", wpa_cli_cmd_logon,
3047 "= IEEE 802.1X EAPOL state machine logon" },
3048 { "logoff", wpa_cli_cmd_logoff,
3050 "= IEEE 802.1X EAPOL state machine logoff" },
3051 { "pmksa", wpa_cli_cmd_pmksa,
3053 "= show PMKSA cache" },
3054 { "reassociate", wpa_cli_cmd_reassociate,
3056 "= force reassociation" },
3057 { "preauthenticate", wpa_cli_cmd_preauthenticate,
3059 "<BSSID> = force preauthentication" },
3060 { "identity", wpa_cli_cmd_identity,
3062 "<network id> <identity> = configure identity for an SSID" },
3063 { "password", wpa_cli_cmd_password,
3064 cli_cmd_flag_sensitive,
3065 "<network id> <password> = configure password for an SSID" },
3066 { "new_password", wpa_cli_cmd_new_password,
3067 cli_cmd_flag_sensitive,
3068 "<network id> <password> = change password for an SSID" },
3069 { "pin", wpa_cli_cmd_pin,
3070 cli_cmd_flag_sensitive,
3071 "<network id> <pin> = configure pin for an SSID" },
3072 { "otp", wpa_cli_cmd_otp,
3073 cli_cmd_flag_sensitive,
3074 "<network id> <password> = configure one-time-password for an SSID"
3076 { "passphrase", wpa_cli_cmd_passphrase,
3077 cli_cmd_flag_sensitive,
3078 "<network id> <passphrase> = configure private key passphrase\n"
3080 { "bssid", wpa_cli_cmd_bssid,
3082 "<network id> <BSSID> = set preferred BSSID for an SSID" },
3083 { "blacklist", wpa_cli_cmd_blacklist,
3085 "<BSSID> = add a BSSID to the blacklist\n"
3086 "blacklist clear = clear the blacklist\n"
3087 "blacklist = display the blacklist" },
3088 { "log_level", wpa_cli_cmd_log_level,
3090 "<level> [<timestamp>] = update the log level/timestamp\n"
3091 "log_level = display the current log level and log options" },
3092 { "list_networks", wpa_cli_cmd_list_networks,
3094 "= list configured networks" },
3095 { "select_network", wpa_cli_cmd_select_network,
3097 "<network id> = select a network (disable others)" },
3098 { "enable_network", wpa_cli_cmd_enable_network,
3100 "<network id> = enable a network" },
3101 { "disable_network", wpa_cli_cmd_disable_network,
3103 "<network id> = disable a network" },
3104 { "add_network", wpa_cli_cmd_add_network,
3106 "= add a network" },
3107 { "remove_network", wpa_cli_cmd_remove_network,
3109 "<network id> = remove a network" },
3110 { "set_network", wpa_cli_cmd_set_network,
3111 cli_cmd_flag_sensitive,
3112 "<network id> <variable> <value> = set network variables (shows\n"
3113 " list of variables when run without arguments)" },
3114 { "get_network", wpa_cli_cmd_get_network,
3116 "<network id> <variable> = get network variables" },
3117 { "list_creds", wpa_cli_cmd_list_creds,
3119 "= list configured credentials" },
3120 { "add_cred", wpa_cli_cmd_add_cred,
3122 "= add a credential" },
3123 { "remove_cred", wpa_cli_cmd_remove_cred,
3125 "<cred id> = remove a credential" },
3126 { "set_cred", wpa_cli_cmd_set_cred,
3127 cli_cmd_flag_sensitive,
3128 "<cred id> <variable> <value> = set credential variables" },
3129 { "save_config", wpa_cli_cmd_save_config,
3131 "= save the current configuration" },
3132 { "disconnect", wpa_cli_cmd_disconnect,
3134 "= disconnect and wait for reassociate/reconnect command before\n"
3136 { "reconnect", wpa_cli_cmd_reconnect,
3138 "= like reassociate, but only takes effect if already disconnected"
3140 { "scan", wpa_cli_cmd_scan,
3142 "= request new BSS scan" },
3143 { "scan_results", wpa_cli_cmd_scan_results,
3145 "= get latest scan results" },
3146 { "bss", wpa_cli_cmd_bss,
3148 "<<idx> | <bssid>> = get detailed scan result info" },
3149 { "get_capability", wpa_cli_cmd_get_capability,
3151 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels>\n"
3152 " = get capabilities" },
3153 { "reconfigure", wpa_cli_cmd_reconfigure,
3155 "= force wpa_supplicant to re-read its configuration file" },
3156 { "terminate", wpa_cli_cmd_terminate,
3158 "= terminate wpa_supplicant" },
3159 { "interface_add", wpa_cli_cmd_interface_add,
3161 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
3162 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
3164 { "interface_remove", wpa_cli_cmd_interface_remove,
3166 "<ifname> = removes the interface" },
3167 { "interface_list", wpa_cli_cmd_interface_list,
3169 "= list available interfaces" },
3170 { "ap_scan", wpa_cli_cmd_ap_scan,
3172 "<value> = set ap_scan parameter" },
3173 { "scan_interval", wpa_cli_cmd_scan_interval,
3175 "<value> = set scan_interval parameter (in seconds)" },
3176 { "bss_expire_age", wpa_cli_cmd_bss_expire_age,
3178 "<value> = set BSS expiration age parameter" },
3179 { "bss_expire_count", wpa_cli_cmd_bss_expire_count,
3181 "<value> = set BSS expiration scan count parameter" },
3182 { "stkstart", wpa_cli_cmd_stkstart,
3184 "<addr> = request STK negotiation with <addr>" },
3185 { "ft_ds", wpa_cli_cmd_ft_ds,
3187 "<addr> = request over-the-DS FT with <addr>" },
3188 { "wps_pbc", wpa_cli_cmd_wps_pbc,
3190 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
3191 { "wps_pin", wpa_cli_cmd_wps_pin,
3192 cli_cmd_flag_sensitive,
3193 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
3195 { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
3196 cli_cmd_flag_sensitive,
3197 "<PIN> = verify PIN checksum" },
3198 { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
3199 "Cancels the pending WPS operation" },
3200 #ifdef CONFIG_WPS_OOB
3201 { "wps_oob", wpa_cli_cmd_wps_oob,
3202 cli_cmd_flag_sensitive,
3203 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
3204 #endif /* CONFIG_WPS_OOB */
3205 #ifdef CONFIG_WPS_NFC
3206 { "wps_nfc", wpa_cli_cmd_wps_nfc,
3208 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
3209 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token,
3211 "<WPS|NDEF> = create password token" },
3212 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read,
3213 cli_cmd_flag_sensitive,
3214 "<hexdump of payload> = report read NFC tag with WPS data" },
3215 #endif /* CONFIG_WPS_NFC */
3216 { "wps_reg", wpa_cli_cmd_wps_reg,
3217 cli_cmd_flag_sensitive,
3218 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
3219 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin,
3220 cli_cmd_flag_sensitive,
3221 "[params..] = enable/disable AP PIN" },
3222 { "wps_er_start", wpa_cli_cmd_wps_er_start,
3224 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
3225 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
3227 "= stop Wi-Fi Protected Setup External Registrar" },
3228 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
3229 cli_cmd_flag_sensitive,
3230 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
3231 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
3233 "<UUID> = accept an Enrollee PBC using External Registrar" },
3234 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
3235 cli_cmd_flag_sensitive,
3236 "<UUID> <PIN> = learn AP configuration" },
3237 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
3239 "<UUID> <network id> = set AP configuration for enrolling" },
3240 { "wps_er_config", wpa_cli_cmd_wps_er_config,
3241 cli_cmd_flag_sensitive,
3242 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
3243 #ifdef CONFIG_WPS_NFC
3244 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token,
3246 "<WPS/NDEF> <UUID> = build NFC configuration token" },
3247 #endif /* CONFIG_WPS_NFC */
3248 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
3250 "<addr> = request RSN authentication with <addr> in IBSS" },
3252 { "sta", wpa_cli_cmd_sta,
3254 "<addr> = get information about an associated station (AP)" },
3255 { "all_sta", wpa_cli_cmd_all_sta,
3257 "= get information about all associated stations (AP)" },
3258 { "deauthenticate", wpa_cli_cmd_deauthenticate,
3260 "<addr> = deauthenticate a station" },
3261 { "disassociate", wpa_cli_cmd_disassociate,
3263 "<addr> = disassociate a station" },
3264 #endif /* CONFIG_AP */
3265 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
3266 "= notification of suspend/hibernate" },
3267 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
3268 "= notification of resume/thaw" },
3269 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
3270 "= drop SA without deauth/disassoc (test command)" },
3271 { "roam", wpa_cli_cmd_roam,
3273 "<addr> = roam to the specified BSS" },
3275 { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
3276 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
3277 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
3278 "= stop P2P Devices search" },
3279 { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
3280 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
3281 { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
3282 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
3283 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
3284 "<ifname> = remove P2P group interface (terminate group if GO)" },
3285 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
3286 "= add a new P2P group (local end as GO)" },
3287 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
3288 "<addr> <method> = request provisioning discovery" },
3289 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
3291 "= get the passphrase for a group (GO only)" },
3292 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
3294 "<addr> <TLVs> = schedule service discovery request" },
3295 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
3297 "<id> = cancel pending service discovery request" },
3298 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
3300 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
3301 { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
3303 "= indicate change in local services" },
3304 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
3306 "<external> = set external processing of service discovery" },
3307 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
3309 "= remove all stored service entries" },
3310 { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
3312 "<bonjour|upnp> <query|version> <response|service> = add a local "
3314 { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
3316 "<bonjour|upnp> <query|version> [|service] = remove a local "
3318 { "p2p_reject", wpa_cli_cmd_p2p_reject,
3320 "<addr> = reject connection attempts from a specific peer" },
3321 { "p2p_invite", wpa_cli_cmd_p2p_invite,
3323 "<cmd> [peer=addr] = invite peer" },
3324 { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
3325 "[discovered] = list known (optionally, only fully discovered) P2P "
3327 { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
3328 "<address> = show information about known P2P peer" },
3329 { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
3330 "<field> <value> = set a P2P parameter" },
3331 { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
3332 "= flush P2P state" },
3333 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
3334 "= cancel P2P group formation" },
3335 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none,
3336 "<address> = unauthorize a peer" },
3337 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
3338 "[<duration> <interval>] [<duration> <interval>] = request GO "
3340 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
3341 "[<period> <interval>] = set extended listen timing" },
3342 #endif /* CONFIG_P2P */
3344 #ifdef CONFIG_INTERWORKING
3345 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, cli_cmd_flag_none,
3346 "= fetch ANQP information for all APs" },
3347 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, cli_cmd_flag_none,
3348 "= stop fetch_anqp operation" },
3349 { "interworking_select", wpa_cli_cmd_interworking_select,
3351 "[auto] = perform Interworking network selection" },
3352 { "interworking_connect", wpa_cli_cmd_interworking_connect,
3354 "<BSSID> = connect using Interworking credentials" },
3355 { "anqp_get", wpa_cli_cmd_anqp_get, cli_cmd_flag_none,
3356 "<addr> <info id>[,<info id>]... = request ANQP information" },
3357 #endif /* CONFIG_INTERWORKING */
3359 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, cli_cmd_flag_none,
3360 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
3362 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
3364 "<addr> <home realm> = get HS20 nai home realm list" },
3365 #endif /* CONFIG_HS20 */
3366 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
3367 "<0/1> = disable/enable automatic reconnection" },
3368 { "tdls_discover", wpa_cli_cmd_tdls_discover,
3370 "<addr> = request TDLS discovery with <addr>" },
3371 { "tdls_setup", wpa_cli_cmd_tdls_setup,
3373 "<addr> = request TDLS setup with <addr>" },
3374 { "tdls_teardown", wpa_cli_cmd_tdls_teardown,
3376 "<addr> = tear down TDLS with <addr>" },
3377 { "signal_poll", wpa_cli_cmd_signal_poll,
3379 "= get signal parameters" },
3380 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll,
3382 "= get TX/RX packet counters" },
3383 { "reauthenticate", wpa_cli_cmd_reauthenticate, cli_cmd_flag_none,
3384 "= trigger IEEE 802.1X/EAPOL reauthentication" },
3385 #ifdef CONFIG_AUTOSCAN
3386 { "autoscan", wpa_cli_cmd_autoscan, cli_cmd_flag_none,
3387 "[params] = Set or unset (if none) autoscan parameters" },
3388 #endif /* CONFIG_AUTOSCAN */
3390 { "driver", wpa_cli_cmd_driver,
3392 "<command> = driver private commands" },
3394 { NULL, NULL, cli_cmd_flag_none, NULL }
3399 * Prints command usage, lines are padded with the specified string.
3401 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
3406 printf("%s%s ", pad, cmd->cmd);
3407 for (n = 0; (c = cmd->usage[n]); n++) {
3416 static void print_help(void)
3419 printf("commands:\n");
3420 for (n = 0; wpa_cli_commands[n].cmd; n++)
3421 print_cmd_help(&wpa_cli_commands[n], " ");
3425 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
3427 const char *c, *delim;
3431 delim = os_strchr(cmd, ' ');
3435 len = os_strlen(cmd);
3437 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
3438 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
3439 return (wpa_cli_commands[n].flags &
3440 cli_cmd_flag_sensitive);
3446 static char ** wpa_list_cmd_list(void)
3451 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
3452 res = os_zalloc(count * sizeof(char *));
3456 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3457 res[i] = os_strdup(wpa_cli_commands[i].cmd);
3466 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
3471 if (os_strcasecmp(cmd, "bss") == 0)
3472 return wpa_cli_complete_bss(str, pos);
3474 if (os_strcasecmp(cmd, "p2p_connect") == 0)
3475 return wpa_cli_complete_p2p_connect(str, pos);
3476 if (os_strcasecmp(cmd, "p2p_peer") == 0)
3477 return wpa_cli_complete_p2p_peer(str, pos);
3478 if (os_strcasecmp(cmd, "p2p_group_remove") == 0)
3479 return wpa_cli_complete_p2p_group_remove(str, pos);
3480 #endif /* CONFIG_P2P */
3482 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3483 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
3485 printf("\r%s\n", wpa_cli_commands[i].usage);
3495 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
3501 end = os_strchr(str, ' ');
3502 if (end == NULL || str + pos < end)
3503 return wpa_list_cmd_list();
3505 cmd = os_malloc(pos + 1);
3508 os_memcpy(cmd, str, pos);
3509 cmd[end - str] = '\0';
3510 res = wpa_cli_cmd_completion(cmd, str, pos);
3516 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3518 struct wpa_cli_cmd *cmd, *match = NULL;
3523 cmd = wpa_cli_commands;
3525 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3528 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3529 /* we have an exact match */
3539 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3540 cmd = wpa_cli_commands;
3542 if (os_strncasecmp(cmd->cmd, argv[0],
3543 os_strlen(argv[0])) == 0) {
3544 printf(" %s", cmd->cmd);
3550 } else if (count == 0) {
3551 printf("Unknown command '%s'\n", argv[0]);
3554 #if defined(CONFIG_P2P) && defined(ANDROID_P2P)
3555 if ( (argc >= 2) && (os_strncmp(argv[1], "interface=", 10) == 0)) {
3556 redirect_interface = os_strdup(argv[1]);
3557 ret = match->handler(ctrl, argc - 2, &argv[2]);
3561 ret = match->handler(ctrl, argc - 1, &argv[1]);
3568 static int str_match(const char *a, const char *b)
3570 return os_strncmp(a, b, os_strlen(b)) == 0;
3574 static int wpa_cli_exec(const char *program, const char *arg1,
3582 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
3583 cmd = os_malloc(len);
3586 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
3587 if (res < 0 || (size_t) res >= len) {
3591 cmd[len - 1] = '\0';
3593 if (system(cmd) < 0)
3595 #endif /* _WIN32_WCE */
3602 static void wpa_cli_action_process(const char *msg)
3605 char *copy = NULL, *id, *pos2;
3610 pos = os_strchr(pos, '>');
3617 if (str_match(pos, WPA_EVENT_CONNECTED)) {
3619 os_unsetenv("WPA_ID");
3620 os_unsetenv("WPA_ID_STR");
3621 os_unsetenv("WPA_CTRL_DIR");
3623 pos = os_strstr(pos, "[id=");
3625 copy = os_strdup(pos + 4);
3629 while (*pos2 && *pos2 != ' ')
3633 os_setenv("WPA_ID", id, 1);
3634 while (*pos2 && *pos2 != '=')
3639 while (*pos2 && *pos2 != ']')
3642 os_setenv("WPA_ID_STR", id, 1);
3646 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3648 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
3649 wpa_cli_connected = 1;
3650 wpa_cli_last_id = new_id;
3651 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
3653 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3654 if (wpa_cli_connected) {
3655 wpa_cli_connected = 0;
3656 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
3658 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3659 wpa_cli_exec(action_file, ctrl_ifname, pos);
3660 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3661 wpa_cli_exec(action_file, ctrl_ifname, pos);
3662 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3663 wpa_cli_exec(action_file, ctrl_ifname, pos);
3664 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3665 wpa_cli_exec(action_file, ctrl_ifname, pos);
3666 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3667 wpa_cli_exec(action_file, ctrl_ifname, pos);
3668 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3669 wpa_cli_exec(action_file, ctrl_ifname, pos);
3670 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3671 wpa_cli_exec(action_file, ctrl_ifname, pos);
3672 } else if (str_match(pos, AP_STA_CONNECTED)) {
3673 wpa_cli_exec(action_file, ctrl_ifname, pos);
3674 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3675 wpa_cli_exec(action_file, ctrl_ifname, pos);
3676 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3677 printf("wpa_supplicant is terminating - stop monitoring\n");
3683 #ifndef CONFIG_ANSI_C_EXTRA
3684 static void wpa_cli_action_cb(char *msg, size_t len)
3686 wpa_cli_action_process(msg);
3688 #endif /* CONFIG_ANSI_C_EXTRA */
3691 static void wpa_cli_reconnect(void)
3693 wpa_cli_close_connection();
3694 wpa_cli_open_connection(ctrl_ifname, 1);
3698 static void cli_event(const char *str)
3700 const char *start, *s;
3702 start = os_strchr(str, '>');
3708 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3709 s = os_strchr(start, ' ');
3712 s = os_strchr(s + 1, ' ');
3715 cli_txt_list_add(&bsses, s + 1);
3719 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3720 s = os_strchr(start, ' ');
3723 s = os_strchr(s + 1, ' ');
3726 cli_txt_list_del_addr(&bsses, s + 1);
3731 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3732 s = os_strstr(start, " p2p_dev_addr=");
3735 cli_txt_list_add_addr(&p2p_peers, s + 14);
3739 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3740 s = os_strstr(start, " p2p_dev_addr=");
3743 cli_txt_list_del_addr(&p2p_peers, s + 14);
3747 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3748 s = os_strchr(start, ' ');
3751 cli_txt_list_add_word(&p2p_groups, s + 1);
3755 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3756 s = os_strchr(start, ' ');
3759 cli_txt_list_del_word(&p2p_groups, s + 1);
3762 #endif /* CONFIG_P2P */
3766 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3768 if (ctrl_conn == NULL) {
3769 wpa_cli_reconnect();
3772 while (wpa_ctrl_pending(ctrl) > 0) {
3774 size_t len = sizeof(buf) - 1;
3775 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3778 wpa_cli_action_process(buf);
3781 if (wpa_cli_show_event(buf)) {
3783 printf("\r%s\n", buf);
3788 printf("Could not read pending message.\n");
3793 if (wpa_ctrl_pending(ctrl) < 0) {
3794 printf("Connection to wpa_supplicant lost - trying to "
3796 wpa_cli_reconnect();
3802 static int tokenize_cmd(char *cmd, char *argv[])
3815 if (argc == max_args)
3818 char *pos2 = os_strrchr(pos, '"');
3822 while (*pos != '\0' && *pos != ' ')
3832 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3834 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3835 printf("Connection to wpa_supplicant lost - trying to "
3837 wpa_cli_close_connection();
3840 wpa_cli_reconnect();
3841 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3845 static void wpa_cli_eloop_terminate(int sig, void *signal_ctx)
3851 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3853 wpa_cli_recv_pending(mon_conn, 0);
3857 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3859 char *argv[max_args];
3861 argc = tokenize_cmd(cmd, argv);
3863 wpa_request(ctrl_conn, argc, argv);
3867 static void wpa_cli_edit_eof_cb(void *ctx)
3873 static void wpa_cli_interactive(void)
3875 char *home, *hfile = NULL;
3877 printf("\nInteractive mode\n\n");
3879 home = getenv("HOME");
3881 const char *fname = ".wpa_cli_history";
3882 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3883 hfile = os_malloc(hfile_len);
3885 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3888 eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
3889 edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3890 wpa_cli_edit_completion_cb, NULL, hfile);
3891 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3895 cli_txt_list_flush(&p2p_peers);
3896 cli_txt_list_flush(&p2p_groups);
3897 cli_txt_list_flush(&bsses);
3898 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3900 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3901 wpa_cli_close_connection();
3905 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3907 #ifdef CONFIG_ANSI_C_EXTRA
3908 /* TODO: ANSI C version(?) */
3909 printf("Action processing not supported in ANSI C build.\n");
3910 #else /* CONFIG_ANSI_C_EXTRA */
3914 char buf[256]; /* note: large enough to fit in unsolicited messages */
3917 fd = wpa_ctrl_get_fd(ctrl);
3919 while (!wpa_cli_quit) {
3922 tv.tv_sec = ping_interval;
3924 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3925 if (res < 0 && errno != EINTR) {
3930 if (FD_ISSET(fd, &rfds))
3931 wpa_cli_recv_pending(ctrl, 1);
3933 /* verify that connection is still working */
3934 len = sizeof(buf) - 1;
3935 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3936 wpa_cli_action_cb) < 0 ||
3937 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3938 printf("wpa_supplicant did not reply to PING "
3939 "command - exiting\n");
3944 #endif /* CONFIG_ANSI_C_EXTRA */
3948 static void wpa_cli_cleanup(void)
3950 wpa_cli_close_connection();
3952 os_daemonize_terminate(pid_file);
3954 os_program_deinit();
3957 static void wpa_cli_terminate(int sig)
3964 static char * wpa_cli_get_default_ifname(void)
3966 char *ifname = NULL;
3968 #ifdef CONFIG_CTRL_IFACE_UNIX
3969 struct dirent *dent;
3970 DIR *dir = opendir(ctrl_iface_dir);
3973 char ifprop[PROPERTY_VALUE_MAX];
3974 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3975 ifname = os_strdup(ifprop);
3976 printf("Using interface '%s'\n", ifname);
3979 #endif /* ANDROID */
3982 while ((dent = readdir(dir))) {
3983 #ifdef _DIRENT_HAVE_D_TYPE
3985 * Skip the file if it is not a socket. Also accept
3986 * DT_UNKNOWN (0) in case the C library or underlying
3987 * file system does not support d_type.
3989 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3991 #endif /* _DIRENT_HAVE_D_TYPE */
3992 if (os_strcmp(dent->d_name, ".") == 0 ||
3993 os_strcmp(dent->d_name, "..") == 0)
3995 printf("Selected interface '%s'\n", dent->d_name);
3996 ifname = os_strdup(dent->d_name);
4000 #endif /* CONFIG_CTRL_IFACE_UNIX */
4002 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
4004 char buf[4096], *pos;
4006 char buf[2048], *pos;
4009 struct wpa_ctrl *ctrl;
4012 ctrl = wpa_ctrl_open(NULL);
4016 len = sizeof(buf) - 1;
4017 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
4020 pos = os_strchr(buf, '\n');
4023 ifname = os_strdup(buf);
4025 wpa_ctrl_close(ctrl);
4026 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4032 int main(int argc, char *argv[])
4034 int warning_displayed = 0;
4038 const char *global = NULL;
4040 if (os_program_init())
4044 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
4049 action_file = optarg;
4058 ping_interval = atoi(optarg);
4064 printf("%s\n", wpa_cli_version);
4067 os_free(ctrl_ifname);
4068 ctrl_ifname = os_strdup(optarg);
4071 ctrl_iface_dir = optarg;
4082 interactive = (argc == optind) && (action_file == NULL);
4085 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
4091 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
4092 ctrl_conn = wpa_ctrl_open(NULL);
4093 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4094 ctrl_conn = wpa_ctrl_open(global);
4095 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4096 if (ctrl_conn == NULL) {
4097 fprintf(stderr, "Failed to connect to wpa_supplicant "
4098 "global interface: %s error: %s\n",
4099 global, strerror(errno));
4105 signal(SIGINT, wpa_cli_terminate);
4106 signal(SIGTERM, wpa_cli_terminate);
4107 #endif /* _WIN32_WCE */
4109 if (ctrl_ifname == NULL)
4110 ctrl_ifname = wpa_cli_get_default_ifname();
4114 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
4115 if (warning_displayed)
4116 printf("Connection established.\n");
4120 if (!warning_displayed) {
4121 printf("Could not connect to wpa_supplicant: "
4122 "%s - re-trying\n", ctrl_ifname);
4123 warning_displayed = 1;
4130 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
4131 fprintf(stderr, "Failed to connect to non-global "
4132 "ctrl_ifname: %s error: %s\n",
4133 ctrl_ifname, strerror(errno));
4138 if (wpa_ctrl_attach(ctrl_conn) == 0) {
4139 wpa_cli_attached = 1;
4141 printf("Warning: Failed to attach to "
4142 "wpa_supplicant.\n");
4148 if (daemonize && os_daemonize(pid_file))
4152 wpa_cli_interactive();
4153 else if (action_file)
4154 wpa_cli_action(ctrl_conn);
4156 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
4158 os_free(ctrl_ifname);
4165 #else /* CONFIG_CTRL_IFACE */
4166 int main(int argc, char *argv[])
4168 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
4171 #endif /* CONFIG_CTRL_IFACE */