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"
24 #include <cutils/properties.h>
28 static const char *wpa_cli_version =
29 "wpa_cli v" VERSION_STR "\n"
30 "Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> and contributors";
33 static const char *wpa_cli_license =
34 "This software may be distributed under the terms of the BSD license.\n"
35 "See README for more details.\n";
37 static const char *wpa_cli_full_license =
38 "This software may be distributed under the terms of the BSD license.\n"
40 "Redistribution and use in source and binary forms, with or without\n"
41 "modification, are permitted provided that the following conditions are\n"
44 "1. Redistributions of source code must retain the above copyright\n"
45 " notice, this list of conditions and the following disclaimer.\n"
47 "2. Redistributions in binary form must reproduce the above copyright\n"
48 " notice, this list of conditions and the following disclaimer in the\n"
49 " documentation and/or other materials provided with the distribution.\n"
51 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
52 " names of its contributors may be used to endorse or promote products\n"
53 " derived from this software without specific prior written permission.\n"
55 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
56 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
57 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
58 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
59 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
60 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
61 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
62 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
63 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
64 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
65 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
68 static struct wpa_ctrl *ctrl_conn;
69 static struct wpa_ctrl *mon_conn;
70 static int wpa_cli_quit = 0;
71 static int wpa_cli_attached = 0;
72 static int wpa_cli_connected = 0;
73 static int wpa_cli_last_id = 0;
74 #ifndef CONFIG_CTRL_IFACE_DIR
75 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
76 #endif /* CONFIG_CTRL_IFACE_DIR */
77 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
78 static char *ctrl_ifname = NULL;
79 static const char *pid_file = NULL;
80 static const char *action_file = NULL;
81 static int ping_interval = 5;
82 static int interactive = 0;
84 struct cli_txt_entry {
89 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
90 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
91 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
94 static void print_help(void);
95 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
98 static void usage(void)
100 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
101 "[-a<action file>] \\\n"
102 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
104 " -h = help (show this usage text)\n"
105 " -v = shown version information\n"
106 " -a = run in daemon mode executing the action file based on "
109 " -B = run a daemon in the background\n"
110 " default path: " CONFIG_CTRL_IFACE_DIR "\n"
111 " default interface: first interface found in socket path\n");
116 static void cli_txt_list_free(struct cli_txt_entry *e)
118 dl_list_del(&e->list);
124 static void cli_txt_list_flush(struct dl_list *list)
126 struct cli_txt_entry *e;
127 while ((e = dl_list_first(list, struct cli_txt_entry, list)))
128 cli_txt_list_free(e);
132 static struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list,
135 struct cli_txt_entry *e;
136 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
137 if (os_strcmp(e->txt, txt) == 0)
144 static void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
146 struct cli_txt_entry *e;
147 e = cli_txt_list_get(txt_list, txt);
149 cli_txt_list_free(e);
153 static void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt)
157 if (hwaddr_aton(txt, addr) < 0)
159 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
160 cli_txt_list_del(txt_list, buf);
165 static void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt)
169 end = os_strchr(txt, ' ');
171 end = txt + os_strlen(txt);
172 buf = os_malloc(end - txt + 1);
175 os_memcpy(buf, txt, end - txt);
176 buf[end - txt] = '\0';
177 cli_txt_list_del(txt_list, buf);
180 #endif /* CONFIG_P2P */
183 static int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
185 struct cli_txt_entry *e;
186 e = cli_txt_list_get(txt_list, txt);
189 e = os_zalloc(sizeof(*e));
192 e->txt = os_strdup(txt);
193 if (e->txt == NULL) {
197 dl_list_add(txt_list, &e->list);
203 static int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
207 if (hwaddr_aton(txt, addr) < 0)
209 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
210 return cli_txt_list_add(txt_list, buf);
214 static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt)
219 end = os_strchr(txt, ' ');
221 end = txt + os_strlen(txt);
222 buf = os_malloc(end - txt + 1);
225 os_memcpy(buf, txt, end - txt);
226 buf[end - txt] = '\0';
227 ret = cli_txt_list_add(txt_list, buf);
231 #endif /* CONFIG_P2P */
234 static char ** cli_txt_list_array(struct dl_list *txt_list)
236 unsigned int i, count = dl_list_len(txt_list);
238 struct cli_txt_entry *e;
240 res = os_zalloc((count + 1) * sizeof(char *));
245 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
246 res[i] = os_strdup(e->txt);
256 static int get_cmd_arg_num(const char *str, int pos)
260 for (i = 0; i <= pos; i++) {
263 while (i <= pos && str[i] != ' ')
274 static int str_starts(const char *src, const char *match)
276 return os_strncmp(src, match, os_strlen(match)) == 0;
280 static int wpa_cli_show_event(const char *event)
284 start = os_strchr(event, '>');
290 * Skip BSS added/removed events since they can be relatively frequent
291 * and are likely of not much use for an interactive user.
293 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
294 str_starts(start, WPA_EVENT_BSS_REMOVED))
301 static int wpa_cli_open_connection(const char *ifname, int attach)
303 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
304 ctrl_conn = wpa_ctrl_open(ifname);
305 if (ctrl_conn == NULL)
308 if (attach && interactive)
309 mon_conn = wpa_ctrl_open(ifname);
312 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
320 if (access(ctrl_iface_dir, F_OK) < 0) {
321 cfile = os_strdup(ifname);
328 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
329 cfile = os_malloc(flen);
332 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
334 if (res < 0 || res >= flen) {
340 ctrl_conn = wpa_ctrl_open(cfile);
341 if (ctrl_conn == NULL) {
346 if (attach && interactive)
347 mon_conn = wpa_ctrl_open(cfile);
351 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
354 if (wpa_ctrl_attach(mon_conn) == 0) {
355 wpa_cli_attached = 1;
357 eloop_register_read_sock(
358 wpa_ctrl_get_fd(mon_conn),
359 wpa_cli_mon_receive, NULL, NULL);
361 printf("Warning: Failed to attach to "
362 "wpa_supplicant.\n");
371 static void wpa_cli_close_connection(void)
373 if (ctrl_conn == NULL)
376 if (wpa_cli_attached) {
377 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
378 wpa_cli_attached = 0;
380 wpa_ctrl_close(ctrl_conn);
383 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
384 wpa_ctrl_close(mon_conn);
390 static void wpa_cli_msg_cb(char *msg, size_t len)
396 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
402 if (ctrl_conn == NULL) {
403 printf("Not connected to wpa_supplicant - command dropped.\n");
406 len = sizeof(buf) - 1;
407 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
410 printf("'%s' command timed out.\n", cmd);
412 } else if (ret < 0) {
413 printf("'%s' command failed.\n", cmd);
419 if (interactive && len > 0 && buf[len - 1] != '\n')
426 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
428 return _wpa_ctrl_command(ctrl, cmd, 1);
432 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
434 if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
435 return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
436 if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
437 return wpa_ctrl_command(ctrl, "STATUS-WPS");
438 return wpa_ctrl_command(ctrl, "STATUS");
442 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
444 return wpa_ctrl_command(ctrl, "PING");
448 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
450 return wpa_ctrl_command(ctrl, "RELOG");
454 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
460 ret = os_snprintf(cmd, sizeof(cmd), "NOTE %s", argv[0]);
461 if (ret < 0 || (size_t) ret >= sizeof(cmd))
463 return wpa_ctrl_command(ctrl, cmd);
467 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
469 return wpa_ctrl_command(ctrl, "MIB");
473 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
475 return wpa_ctrl_command(ctrl, "PMKSA");
479 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
486 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
488 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
493 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
502 static void wpa_cli_show_variables(void)
504 printf("set variables:\n"
505 " EAPOL::heldPeriod (EAPOL state machine held period, "
507 " EAPOL::authPeriod (EAPOL state machine authentication "
508 "period, in seconds)\n"
509 " EAPOL::startPeriod (EAPOL state machine start period, in "
511 " EAPOL::maxStart (EAPOL state machine maximum start "
513 printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
515 " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
516 " threshold\n\tpercentage)\n"
517 " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
518 "security\n\tassociation in seconds)\n");
522 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
528 wpa_cli_show_variables();
532 if (argc != 1 && argc != 2) {
533 printf("Invalid SET command: needs two arguments (variable "
534 "name and value)\n");
539 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
541 res = os_snprintf(cmd, sizeof(cmd), "SET %s %s",
543 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
544 printf("Too long SET command.\n");
547 return wpa_ctrl_command(ctrl, cmd);
551 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
557 printf("Invalid GET command: need one argument (variable "
562 res = os_snprintf(cmd, sizeof(cmd), "GET %s", argv[0]);
563 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
564 printf("Too long GET command.\n");
567 return wpa_ctrl_command(ctrl, cmd);
571 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
573 return wpa_ctrl_command(ctrl, "LOGOFF");
577 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
579 return wpa_ctrl_command(ctrl, "LOGON");
583 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
586 return wpa_ctrl_command(ctrl, "REASSOCIATE");
590 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
597 printf("Invalid PREAUTH command: needs one argument "
602 res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
603 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
604 printf("Too long PREAUTH command.\n");
607 return wpa_ctrl_command(ctrl, cmd);
611 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
617 printf("Invalid AP_SCAN command: needs one argument (ap_scan "
621 res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
622 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
623 printf("Too long AP_SCAN command.\n");
626 return wpa_ctrl_command(ctrl, cmd);
630 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
637 printf("Invalid SCAN_INTERVAL command: needs one argument "
638 "scan_interval value)\n");
641 res = os_snprintf(cmd, sizeof(cmd), "SCAN_INTERVAL %s", argv[0]);
642 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
643 printf("Too long SCAN_INTERVAL command.\n");
646 return wpa_ctrl_command(ctrl, cmd);
650 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
657 printf("Invalid BSS_EXPIRE_AGE command: needs one argument "
658 "(bss_expire_age value)\n");
661 res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_AGE %s", argv[0]);
662 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
663 printf("Too long BSS_EXPIRE_AGE command.\n");
666 return wpa_ctrl_command(ctrl, cmd);
670 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
677 printf("Invalid BSS_EXPIRE_COUNT command: needs one argument "
678 "(bss_expire_count value)\n");
681 res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_COUNT %s", argv[0]);
682 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
683 printf("Too long BSS_EXPIRE_COUNT command.\n");
686 return wpa_ctrl_command(ctrl, cmd);
690 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
697 printf("Invalid STKSTART command: needs one argument "
698 "(Peer STA MAC address)\n");
702 res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
703 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
704 printf("Too long STKSTART command.\n");
707 return wpa_ctrl_command(ctrl, cmd);
711 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
717 printf("Invalid FT_DS command: needs one argument "
718 "(Target AP MAC address)\n");
722 res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
723 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
724 printf("Too long FT_DS command.\n");
727 return wpa_ctrl_command(ctrl, cmd);
731 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
738 return wpa_ctrl_command(ctrl, "WPS_PBC");
742 res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
743 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
744 printf("Too long WPS_PBC command.\n");
747 return wpa_ctrl_command(ctrl, cmd);
751 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
757 printf("Invalid WPS_PIN command: need one or two arguments:\n"
758 "- BSSID: use 'any' to select any\n"
759 "- PIN: optional, used only with devices that have no "
765 /* Use dynamically generated PIN (returned as reply) */
766 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
767 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
768 printf("Too long WPS_PIN command.\n");
771 return wpa_ctrl_command(ctrl, cmd);
774 /* Use hardcoded PIN from a label */
775 res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
776 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
777 printf("Too long WPS_PIN command.\n");
780 return wpa_ctrl_command(ctrl, cmd);
784 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
790 if (argc != 1 && argc != 2) {
791 printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
792 "- PIN to be verified\n");
797 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
800 res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
802 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
803 printf("Too long WPS_CHECK_PIN command.\n");
806 return wpa_ctrl_command(ctrl, cmd);
810 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
813 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
817 #ifdef CONFIG_WPS_OOB
818 static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
823 if (argc != 3 && argc != 4) {
824 printf("Invalid WPS_OOB command: need three or four "
826 "- DEV_TYPE: use 'ufd' or 'nfc'\n"
827 "- PATH: path of OOB device like '/mnt'\n"
828 "- METHOD: OOB method 'pin-e' or 'pin-r', "
830 "- DEV_NAME: (only for NFC) device name like "
836 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
837 argv[0], argv[1], argv[2]);
839 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
840 argv[0], argv[1], argv[2], argv[3]);
841 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
842 printf("Too long WPS_OOB command.\n");
845 return wpa_ctrl_command(ctrl, cmd);
847 #endif /* CONFIG_WPS_OOB */
850 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
856 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
858 else if (argc == 5 || argc == 6) {
859 char ssid_hex[2 * 32 + 1];
860 char key_hex[2 * 64 + 1];
864 for (i = 0; i < 32; i++) {
865 if (argv[2][i] == '\0')
867 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
872 for (i = 0; i < 64; i++) {
873 if (argv[5][i] == '\0')
875 os_snprintf(&key_hex[i * 2], 3, "%02x",
880 res = os_snprintf(cmd, sizeof(cmd),
881 "WPS_REG %s %s %s %s %s %s",
882 argv[0], argv[1], ssid_hex, argv[3], argv[4],
885 printf("Invalid WPS_REG command: need two arguments:\n"
886 "- BSSID of the target AP\n"
888 printf("Alternatively, six arguments can be used to "
889 "reconfigure the AP:\n"
890 "- BSSID of the target AP\n"
893 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
894 "- new encr (NONE, WEP, TKIP, CCMP)\n"
899 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
900 printf("Too long WPS_REG command.\n");
903 return wpa_ctrl_command(ctrl, cmd);
907 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
914 printf("Invalid WPS_AP_PIN command: needs at least one "
920 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s %s",
921 argv[0], argv[1], argv[2]);
923 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s %s",
926 res = os_snprintf(cmd, sizeof(cmd), "WPS_AP_PIN %s",
928 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
929 printf("Too long WPS_AP_PIN command.\n");
932 return wpa_ctrl_command(ctrl, cmd);
936 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
941 os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
942 return wpa_ctrl_command(ctrl, cmd);
944 return wpa_ctrl_command(ctrl, "WPS_ER_START");
948 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
951 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
956 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
963 printf("Invalid WPS_ER_PIN command: need at least two "
965 "- UUID: use 'any' to select any\n"
966 "- PIN: Enrollee PIN\n"
967 "optional: - Enrollee MAC address\n");
972 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
973 argv[0], argv[1], argv[2]);
975 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
977 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
978 printf("Too long WPS_ER_PIN command.\n");
981 return wpa_ctrl_command(ctrl, cmd);
985 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
992 printf("Invalid WPS_ER_PBC command: need one argument:\n"
993 "- UUID: Specify the Enrollee\n");
997 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
999 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1000 printf("Too long WPS_ER_PBC command.\n");
1003 return wpa_ctrl_command(ctrl, cmd);
1007 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
1014 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1015 "- UUID: specify which AP to use\n"
1020 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
1022 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1023 printf("Too long WPS_ER_LEARN command.\n");
1026 return wpa_ctrl_command(ctrl, cmd);
1030 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
1037 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1039 "- UUID: specify which AP to use\n"
1040 "- Network configuration id\n");
1044 res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_SET_CONFIG %s %s",
1046 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1047 printf("Too long WPS_ER_SET_CONFIG command.\n");
1050 return wpa_ctrl_command(ctrl, cmd);
1054 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
1060 if (argc == 5 || argc == 6) {
1061 char ssid_hex[2 * 32 + 1];
1062 char key_hex[2 * 64 + 1];
1066 for (i = 0; i < 32; i++) {
1067 if (argv[2][i] == '\0')
1069 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1074 for (i = 0; i < 64; i++) {
1075 if (argv[5][i] == '\0')
1077 os_snprintf(&key_hex[i * 2], 3, "%02x",
1082 res = os_snprintf(cmd, sizeof(cmd),
1083 "WPS_ER_CONFIG %s %s %s %s %s %s",
1084 argv[0], argv[1], ssid_hex, argv[3], argv[4],
1087 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1091 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1092 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1097 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1098 printf("Too long WPS_ER_CONFIG command.\n");
1101 return wpa_ctrl_command(ctrl, cmd);
1105 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1111 printf("Invalid IBSS_RSN command: needs one argument "
1112 "(Peer STA MAC address)\n");
1116 res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
1117 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1118 printf("Too long IBSS_RSN command.\n");
1121 return wpa_ctrl_command(ctrl, cmd);
1125 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1131 printf("Invalid LEVEL command: needs one argument (debug "
1135 res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
1136 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1137 printf("Too long LEVEL command.\n");
1140 return wpa_ctrl_command(ctrl, cmd);
1144 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1146 char cmd[256], *pos, *end;
1150 printf("Invalid IDENTITY command: needs two arguments "
1151 "(network id and identity)\n");
1155 end = cmd + sizeof(cmd);
1157 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1159 if (ret < 0 || ret >= end - pos) {
1160 printf("Too long IDENTITY command.\n");
1164 for (i = 2; i < argc; i++) {
1165 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1166 if (ret < 0 || ret >= end - pos) {
1167 printf("Too long IDENTITY command.\n");
1173 return wpa_ctrl_command(ctrl, cmd);
1177 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1179 char cmd[256], *pos, *end;
1183 printf("Invalid PASSWORD command: needs two arguments "
1184 "(network id and password)\n");
1188 end = cmd + sizeof(cmd);
1190 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1192 if (ret < 0 || ret >= end - pos) {
1193 printf("Too long PASSWORD command.\n");
1197 for (i = 2; i < argc; i++) {
1198 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1199 if (ret < 0 || ret >= end - pos) {
1200 printf("Too long PASSWORD command.\n");
1206 return wpa_ctrl_command(ctrl, cmd);
1210 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1213 char cmd[256], *pos, *end;
1217 printf("Invalid NEW_PASSWORD command: needs two arguments "
1218 "(network id and password)\n");
1222 end = cmd + sizeof(cmd);
1224 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1226 if (ret < 0 || ret >= end - pos) {
1227 printf("Too long NEW_PASSWORD command.\n");
1231 for (i = 2; i < argc; i++) {
1232 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1233 if (ret < 0 || ret >= end - pos) {
1234 printf("Too long NEW_PASSWORD command.\n");
1240 return wpa_ctrl_command(ctrl, cmd);
1244 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1246 char cmd[256], *pos, *end;
1250 printf("Invalid PIN command: needs two arguments "
1251 "(network id and pin)\n");
1255 end = cmd + sizeof(cmd);
1257 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1259 if (ret < 0 || ret >= end - pos) {
1260 printf("Too long PIN command.\n");
1264 for (i = 2; i < argc; i++) {
1265 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1266 if (ret < 0 || ret >= end - pos) {
1267 printf("Too long PIN command.\n");
1272 return wpa_ctrl_command(ctrl, cmd);
1276 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1278 char cmd[256], *pos, *end;
1282 printf("Invalid OTP command: needs two arguments (network "
1283 "id and password)\n");
1287 end = cmd + sizeof(cmd);
1289 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1291 if (ret < 0 || ret >= end - pos) {
1292 printf("Too long OTP command.\n");
1296 for (i = 2; i < argc; i++) {
1297 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1298 if (ret < 0 || ret >= end - pos) {
1299 printf("Too long OTP command.\n");
1305 return wpa_ctrl_command(ctrl, cmd);
1309 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1312 char cmd[256], *pos, *end;
1316 printf("Invalid PASSPHRASE command: needs two arguments "
1317 "(network id and passphrase)\n");
1321 end = cmd + sizeof(cmd);
1323 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1325 if (ret < 0 || ret >= end - pos) {
1326 printf("Too long PASSPHRASE command.\n");
1330 for (i = 2; i < argc; i++) {
1331 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1332 if (ret < 0 || ret >= end - pos) {
1333 printf("Too long PASSPHRASE command.\n");
1339 return wpa_ctrl_command(ctrl, cmd);
1343 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1345 char cmd[256], *pos, *end;
1349 printf("Invalid BSSID command: needs two arguments (network "
1354 end = cmd + sizeof(cmd);
1356 ret = os_snprintf(pos, end - pos, "BSSID");
1357 if (ret < 0 || ret >= end - pos) {
1358 printf("Too long BSSID command.\n");
1362 for (i = 0; i < argc; i++) {
1363 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1364 if (ret < 0 || ret >= end - pos) {
1365 printf("Too long BSSID command.\n");
1371 return wpa_ctrl_command(ctrl, cmd);
1375 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1377 char cmd[256], *pos, *end;
1380 end = cmd + sizeof(cmd);
1382 ret = os_snprintf(pos, end - pos, "BLACKLIST");
1383 if (ret < 0 || ret >= end - pos) {
1384 printf("Too long BLACKLIST command.\n");
1388 for (i = 0; i < argc; i++) {
1389 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1390 if (ret < 0 || ret >= end - pos) {
1391 printf("Too long BLACKLIST command.\n");
1397 return wpa_ctrl_command(ctrl, cmd);
1401 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1403 char cmd[256], *pos, *end;
1406 end = cmd + sizeof(cmd);
1408 ret = os_snprintf(pos, end - pos, "LOG_LEVEL");
1409 if (ret < 0 || ret >= end - pos) {
1410 printf("Too long LOG_LEVEL command.\n");
1414 for (i = 0; i < argc; i++) {
1415 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1416 if (ret < 0 || ret >= end - pos) {
1417 printf("Too long LOG_LEVEL command.\n");
1423 return wpa_ctrl_command(ctrl, cmd);
1427 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1430 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1434 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1441 printf("Invalid SELECT_NETWORK command: needs one argument "
1446 res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
1447 if (res < 0 || (size_t) res >= sizeof(cmd))
1449 cmd[sizeof(cmd) - 1] = '\0';
1451 return wpa_ctrl_command(ctrl, cmd);
1455 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1462 printf("Invalid ENABLE_NETWORK command: needs one argument "
1467 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
1468 if (res < 0 || (size_t) res >= sizeof(cmd))
1470 cmd[sizeof(cmd) - 1] = '\0';
1472 return wpa_ctrl_command(ctrl, cmd);
1476 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1483 printf("Invalid DISABLE_NETWORK command: needs one argument "
1488 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1489 if (res < 0 || (size_t) res >= sizeof(cmd))
1491 cmd[sizeof(cmd) - 1] = '\0';
1493 return wpa_ctrl_command(ctrl, cmd);
1497 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1500 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1504 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1511 printf("Invalid REMOVE_NETWORK command: needs one argument "
1516 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1517 if (res < 0 || (size_t) res >= sizeof(cmd))
1519 cmd[sizeof(cmd) - 1] = '\0';
1521 return wpa_ctrl_command(ctrl, cmd);
1525 static void wpa_cli_show_network_variables(void)
1527 printf("set_network variables:\n"
1528 " ssid (network name, SSID)\n"
1529 " psk (WPA passphrase or pre-shared key)\n"
1530 " key_mgmt (key management protocol)\n"
1531 " identity (EAP identity)\n"
1532 " password (EAP password)\n"
1535 "Note: Values are entered in the same format as the "
1536 "configuration file is using,\n"
1537 "i.e., strings values need to be inside double quotation "
1539 "For example: set_network 1 ssid \"network name\"\n"
1541 "Please see wpa_supplicant.conf documentation for full list "
1542 "of\navailable variables.\n");
1546 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1553 wpa_cli_show_network_variables();
1558 printf("Invalid SET_NETWORK command: needs three arguments\n"
1559 "(network id, variable name, and value)\n");
1563 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1564 argv[0], argv[1], argv[2]);
1565 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1566 printf("Too long SET_NETWORK command.\n");
1569 return wpa_ctrl_command(ctrl, cmd);
1573 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1580 wpa_cli_show_network_variables();
1585 printf("Invalid GET_NETWORK command: needs two arguments\n"
1586 "(network id and variable name)\n");
1590 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1592 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1593 printf("Too long GET_NETWORK command.\n");
1596 return wpa_ctrl_command(ctrl, cmd);
1600 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1603 return wpa_ctrl_command(ctrl, "DISCONNECT");
1607 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1610 return wpa_ctrl_command(ctrl, "RECONNECT");
1614 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1617 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1621 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1623 return wpa_ctrl_command(ctrl, "SCAN");
1627 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1630 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1634 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1640 printf("Invalid BSS command: need one argument (index or "
1645 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1646 if (res < 0 || (size_t) res >= sizeof(cmd))
1648 cmd[sizeof(cmd) - 1] = '\0';
1650 return wpa_ctrl_command(ctrl, cmd);
1654 static char ** wpa_cli_complete_bss(const char *str, int pos)
1656 int arg = get_cmd_arg_num(str, pos);
1661 res = cli_txt_list_array(&bsses);
1669 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1675 if (argc < 1 || argc > 2) {
1676 printf("Invalid GET_CAPABILITY command: need either one or "
1681 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1682 printf("Invalid GET_CAPABILITY command: second argument, "
1683 "if any, must be 'strict'\n");
1687 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1688 (argc == 2) ? " strict" : "");
1689 if (res < 0 || (size_t) res >= sizeof(cmd))
1691 cmd[sizeof(cmd) - 1] = '\0';
1693 return wpa_ctrl_command(ctrl, cmd);
1697 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1699 printf("Available interfaces:\n");
1700 return wpa_ctrl_command(ctrl, "INTERFACES");
1704 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1707 wpa_cli_list_interfaces(ctrl);
1711 wpa_cli_close_connection();
1712 os_free(ctrl_ifname);
1713 ctrl_ifname = os_strdup(argv[0]);
1715 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1716 printf("Connected to interface '%s.\n", ctrl_ifname);
1718 printf("Could not connect to interface '%s' - re-trying\n",
1725 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1728 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1732 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1735 return wpa_ctrl_command(ctrl, "TERMINATE");
1739 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1746 printf("Invalid INTERFACE_ADD command: needs at least one "
1747 "argument (interface name)\n"
1748 "All arguments: ifname confname driver ctrl_interface "
1749 "driver_param bridge_name\n");
1754 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1755 * <driver_param>TAB<bridge_name>
1757 res = os_snprintf(cmd, sizeof(cmd),
1758 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1760 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1761 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1762 argc > 5 ? argv[5] : "");
1763 if (res < 0 || (size_t) res >= sizeof(cmd))
1765 cmd[sizeof(cmd) - 1] = '\0';
1766 return wpa_ctrl_command(ctrl, cmd);
1770 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1777 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1778 "(interface name)\n");
1782 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1783 if (res < 0 || (size_t) res >= sizeof(cmd))
1785 cmd[sizeof(cmd) - 1] = '\0';
1786 return wpa_ctrl_command(ctrl, cmd);
1790 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1793 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1798 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1802 printf("Invalid 'sta' command - exactly one argument, STA "
1803 "address, is required.\n");
1806 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1807 return wpa_ctrl_command(ctrl, buf);
1811 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1812 char *addr, size_t addr_len)
1814 char buf[4096], *pos;
1818 if (ctrl_conn == NULL) {
1819 printf("Not connected to hostapd - command dropped.\n");
1822 len = sizeof(buf) - 1;
1823 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1826 printf("'%s' command timed out.\n", cmd);
1828 } else if (ret < 0) {
1829 printf("'%s' command failed.\n", cmd);
1834 if (memcmp(buf, "FAIL", 4) == 0)
1839 while (*pos != '\0' && *pos != '\n')
1842 os_strlcpy(addr, buf, addr_len);
1847 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1849 char addr[32], cmd[64];
1851 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1854 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1855 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1859 #endif /* CONFIG_AP */
1862 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1864 return wpa_ctrl_command(ctrl, "SUSPEND");
1868 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1870 return wpa_ctrl_command(ctrl, "RESUME");
1874 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1876 return wpa_ctrl_command(ctrl, "DROP_SA");
1880 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1886 printf("Invalid ROAM command: needs one argument "
1887 "(target AP's BSSID)\n");
1891 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1892 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1893 printf("Too long ROAM command.\n");
1896 return wpa_ctrl_command(ctrl, cmd);
1902 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1908 return wpa_ctrl_command(ctrl, "P2P_FIND");
1911 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s %s",
1912 argv[0], argv[1], argv[2]);
1914 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
1917 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
1918 if (res < 0 || (size_t) res >= sizeof(cmd))
1920 cmd[sizeof(cmd) - 1] = '\0';
1921 return wpa_ctrl_command(ctrl, cmd);
1925 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1928 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1932 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1939 printf("Invalid P2P_CONNECT command: needs at least two "
1940 "arguments (address and pbc/PIN)\n");
1945 res = os_snprintf(cmd, sizeof(cmd),
1946 "P2P_CONNECT %s %s %s %s %s",
1947 argv[0], argv[1], argv[2], argv[3],
1950 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
1951 argv[0], argv[1], argv[2], argv[3]);
1953 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
1954 argv[0], argv[1], argv[2]);
1956 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1958 if (res < 0 || (size_t) res >= sizeof(cmd))
1960 cmd[sizeof(cmd) - 1] = '\0';
1961 return wpa_ctrl_command(ctrl, cmd);
1965 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
1967 int arg = get_cmd_arg_num(str, pos);
1972 res = cli_txt_list_array(&p2p_peers);
1980 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1987 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
1989 res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
1990 if (res < 0 || (size_t) res >= sizeof(cmd))
1992 cmd[sizeof(cmd) - 1] = '\0';
1993 return wpa_ctrl_command(ctrl, cmd);
1997 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
2004 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
2005 "(interface name)\n");
2009 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
2010 if (res < 0 || (size_t) res >= sizeof(cmd))
2012 cmd[sizeof(cmd) - 1] = '\0';
2013 return wpa_ctrl_command(ctrl, cmd);
2017 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
2019 int arg = get_cmd_arg_num(str, pos);
2024 res = cli_txt_list_array(&p2p_groups);
2032 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
2039 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
2042 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s %s",
2045 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s",
2047 if (res < 0 || (size_t) res >= sizeof(cmd))
2049 cmd[sizeof(cmd) - 1] = '\0';
2050 return wpa_ctrl_command(ctrl, cmd);
2054 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
2060 if (argc != 2 && argc != 3) {
2061 printf("Invalid P2P_PROV_DISC command: needs at least "
2062 "two arguments, address and config method\n"
2063 "(display, keypad, or pbc) and an optional join\n");
2068 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s %s",
2069 argv[0], argv[1], argv[2]);
2071 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
2073 if (res < 0 || (size_t) res >= sizeof(cmd))
2075 cmd[sizeof(cmd) - 1] = '\0';
2076 return wpa_ctrl_command(ctrl, cmd);
2080 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
2083 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
2087 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
2093 if (argc != 2 && argc != 4) {
2094 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2095 "arguments (address and TLVs) or four arguments "
2096 "(address, \"upnp\", version, search target "
2102 res = os_snprintf(cmd, sizeof(cmd),
2103 "P2P_SERV_DISC_REQ %s %s %s %s",
2104 argv[0], argv[1], argv[2], argv[3]);
2106 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
2108 if (res < 0 || (size_t) res >= sizeof(cmd))
2110 cmd[sizeof(cmd) - 1] = '\0';
2111 return wpa_ctrl_command(ctrl, cmd);
2115 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
2116 int argc, char *argv[])
2122 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
2123 "argument (pending request identifier)\n");
2127 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
2129 if (res < 0 || (size_t) res >= sizeof(cmd))
2131 cmd[sizeof(cmd) - 1] = '\0';
2132 return wpa_ctrl_command(ctrl, cmd);
2136 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
2143 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2144 "arguments (freq, address, dialog token, and TLVs)\n");
2148 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
2149 argv[0], argv[1], argv[2], argv[3]);
2150 if (res < 0 || (size_t) res >= sizeof(cmd))
2152 cmd[sizeof(cmd) - 1] = '\0';
2153 return wpa_ctrl_command(ctrl, cmd);
2157 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
2160 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
2164 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
2165 int argc, char *argv[])
2171 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
2172 "argument (external processing: 0/1)\n");
2176 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
2178 if (res < 0 || (size_t) res >= sizeof(cmd))
2180 cmd[sizeof(cmd) - 1] = '\0';
2181 return wpa_ctrl_command(ctrl, cmd);
2185 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
2188 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
2192 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
2198 if (argc != 3 && argc != 4) {
2199 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
2205 res = os_snprintf(cmd, sizeof(cmd),
2206 "P2P_SERVICE_ADD %s %s %s %s",
2207 argv[0], argv[1], argv[2], argv[3]);
2209 res = os_snprintf(cmd, sizeof(cmd),
2210 "P2P_SERVICE_ADD %s %s %s",
2211 argv[0], argv[1], argv[2]);
2212 if (res < 0 || (size_t) res >= sizeof(cmd))
2214 cmd[sizeof(cmd) - 1] = '\0';
2215 return wpa_ctrl_command(ctrl, cmd);
2219 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2225 if (argc != 2 && argc != 3) {
2226 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2232 res = os_snprintf(cmd, sizeof(cmd),
2233 "P2P_SERVICE_DEL %s %s %s",
2234 argv[0], argv[1], argv[2]);
2236 res = os_snprintf(cmd, sizeof(cmd),
2237 "P2P_SERVICE_DEL %s %s",
2239 if (res < 0 || (size_t) res >= sizeof(cmd))
2241 cmd[sizeof(cmd) - 1] = '\0';
2242 return wpa_ctrl_command(ctrl, cmd);
2246 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2247 int argc, char *argv[])
2253 printf("Invalid P2P_REJECT command: needs one argument "
2254 "(peer address)\n");
2258 res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
2259 if (res < 0 || (size_t) res >= sizeof(cmd))
2261 cmd[sizeof(cmd) - 1] = '\0';
2262 return wpa_ctrl_command(ctrl, cmd);
2266 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2267 int argc, char *argv[])
2273 printf("Invalid P2P_INVITE command: needs at least one "
2279 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
2280 argv[0], argv[1], argv[2]);
2282 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
2285 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
2286 if (res < 0 || (size_t) res >= sizeof(cmd))
2288 cmd[sizeof(cmd) - 1] = '\0';
2289 return wpa_ctrl_command(ctrl, cmd);
2293 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2297 printf("Invalid 'p2p_peer' command - exactly one argument, "
2298 "P2P peer device address, is required.\n");
2301 os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
2302 return wpa_ctrl_command(ctrl, buf);
2306 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2308 int arg = get_cmd_arg_num(str, pos);
2313 res = cli_txt_list_array(&p2p_peers);
2321 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2322 char *addr, size_t addr_len,
2325 char buf[4096], *pos;
2329 if (ctrl_conn == NULL)
2331 len = sizeof(buf) - 1;
2332 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
2335 printf("'%s' command timed out.\n", cmd);
2337 } else if (ret < 0) {
2338 printf("'%s' command failed.\n", cmd);
2343 if (memcmp(buf, "FAIL", 4) == 0)
2347 while (*pos != '\0' && *pos != '\n')
2350 os_strlcpy(addr, buf, addr_len);
2351 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2352 printf("%s\n", addr);
2357 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2359 char addr[32], cmd[64];
2362 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2364 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2365 addr, sizeof(addr), discovered))
2368 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2369 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2376 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2382 printf("Invalid P2P_SET command: needs two arguments (field, "
2387 res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2388 if (res < 0 || (size_t) res >= sizeof(cmd))
2390 cmd[sizeof(cmd) - 1] = '\0';
2391 return wpa_ctrl_command(ctrl, cmd);
2395 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2397 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2401 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2404 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2408 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2415 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2416 "(peer address)\n");
2420 res = os_snprintf(cmd, sizeof(cmd), "P2P_UNAUTHORIZE %s", argv[0]);
2422 if (res < 0 || (size_t) res >= sizeof(cmd))
2425 cmd[sizeof(cmd) - 1] = '\0';
2426 return wpa_ctrl_command(ctrl, cmd);
2430 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2436 if (argc != 0 && argc != 2 && argc != 4) {
2437 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2438 "(preferred duration, interval; in microsecods).\n"
2439 "Optional second pair can be used to provide "
2440 "acceptable values.\n");
2445 res = os_snprintf(cmd, sizeof(cmd),
2446 "P2P_PRESENCE_REQ %s %s %s %s",
2447 argv[0], argv[1], argv[2], argv[3]);
2449 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2452 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2453 if (res < 0 || (size_t) res >= sizeof(cmd))
2455 cmd[sizeof(cmd) - 1] = '\0';
2456 return wpa_ctrl_command(ctrl, cmd);
2460 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2466 if (argc != 0 && argc != 2) {
2467 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2468 "(availability period, availability interval; in "
2470 "Extended Listen Timing can be cancelled with this "
2471 "command when used without parameters.\n");
2476 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2479 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2480 if (res < 0 || (size_t) res >= sizeof(cmd))
2482 cmd[sizeof(cmd) - 1] = '\0';
2483 return wpa_ctrl_command(ctrl, cmd);
2486 #endif /* CONFIG_P2P */
2489 #ifdef CONFIG_INTERWORKING
2490 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2493 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2497 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2500 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2504 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2511 return wpa_ctrl_command(ctrl, "INTERWORKING_SELECT");
2513 res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_SELECT %s", argv[0]);
2514 if (res < 0 || (size_t) res >= sizeof(cmd))
2516 cmd[sizeof(cmd) - 1] = '\0';
2517 return wpa_ctrl_command(ctrl, cmd);
2521 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2528 printf("Invalid INTERWORKING_CONNECT commands: needs one "
2529 "argument (BSSID)\n");
2533 res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_CONNECT %s",
2535 if (res < 0 || (size_t) res >= sizeof(cmd))
2537 cmd[sizeof(cmd) - 1] = '\0';
2538 return wpa_ctrl_command(ctrl, cmd);
2542 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2548 printf("Invalid ANQP_GET command: needs two arguments "
2549 "(addr and info id list)\n");
2553 res = os_snprintf(cmd, sizeof(cmd), "ANQP_GET %s %s",
2555 if (res < 0 || (size_t) res >= sizeof(cmd))
2557 cmd[sizeof(cmd) - 1] = '\0';
2558 return wpa_ctrl_command(ctrl, cmd);
2560 #endif /* CONFIG_INTERWORKING */
2563 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2570 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2571 "(0/1 = disable/enable automatic reconnection)\n");
2574 res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2575 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2576 printf("Too long STA_AUTOCONNECT command.\n");
2579 return wpa_ctrl_command(ctrl, cmd);
2583 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2590 printf("Invalid TDLS_DISCOVER command: needs one argument "
2591 "(Peer STA MAC address)\n");
2595 res = os_snprintf(cmd, sizeof(cmd), "TDLS_DISCOVER %s", argv[0]);
2596 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2597 printf("Too long TDLS_DISCOVER command.\n");
2600 return wpa_ctrl_command(ctrl, cmd);
2604 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2611 printf("Invalid TDLS_SETUP command: needs one argument "
2612 "(Peer STA MAC address)\n");
2616 res = os_snprintf(cmd, sizeof(cmd), "TDLS_SETUP %s", argv[0]);
2617 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2618 printf("Too long TDLS_SETUP command.\n");
2621 return wpa_ctrl_command(ctrl, cmd);
2625 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2632 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2633 "(Peer STA MAC address)\n");
2637 res = os_snprintf(cmd, sizeof(cmd), "TDLS_TEARDOWN %s", argv[0]);
2638 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2639 printf("Too long TDLS_TEARDOWN command.\n");
2642 return wpa_ctrl_command(ctrl, cmd);
2646 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2649 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2653 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2656 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2660 enum wpa_cli_cmd_flags {
2661 cli_cmd_flag_none = 0x00,
2662 cli_cmd_flag_sensitive = 0x01
2665 struct wpa_cli_cmd {
2667 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2668 enum wpa_cli_cmd_flags flags;
2672 static struct wpa_cli_cmd wpa_cli_commands[] = {
2673 { "status", wpa_cli_cmd_status,
2675 "[verbose] = get current WPA/EAPOL/EAP status" },
2676 { "ping", wpa_cli_cmd_ping,
2678 "= pings wpa_supplicant" },
2679 { "relog", wpa_cli_cmd_relog,
2681 "= re-open log-file (allow rolling logs)" },
2682 { "note", wpa_cli_cmd_note,
2684 "<text> = add a note to wpa_supplicant debug log" },
2685 { "mib", wpa_cli_cmd_mib,
2687 "= get MIB variables (dot1x, dot11)" },
2688 { "help", wpa_cli_cmd_help,
2690 "= show this usage help" },
2691 { "interface", wpa_cli_cmd_interface,
2693 "[ifname] = show interfaces/select interface" },
2694 { "level", wpa_cli_cmd_level,
2696 "<debug level> = change debug level" },
2697 { "license", wpa_cli_cmd_license,
2699 "= show full wpa_cli license" },
2700 { "quit", wpa_cli_cmd_quit,
2703 { "set", wpa_cli_cmd_set,
2705 "= set variables (shows list of variables when run without "
2707 { "get", wpa_cli_cmd_get,
2709 "<name> = get information" },
2710 { "logon", wpa_cli_cmd_logon,
2712 "= IEEE 802.1X EAPOL state machine logon" },
2713 { "logoff", wpa_cli_cmd_logoff,
2715 "= IEEE 802.1X EAPOL state machine logoff" },
2716 { "pmksa", wpa_cli_cmd_pmksa,
2718 "= show PMKSA cache" },
2719 { "reassociate", wpa_cli_cmd_reassociate,
2721 "= force reassociation" },
2722 { "preauthenticate", wpa_cli_cmd_preauthenticate,
2724 "<BSSID> = force preauthentication" },
2725 { "identity", wpa_cli_cmd_identity,
2727 "<network id> <identity> = configure identity for an SSID" },
2728 { "password", wpa_cli_cmd_password,
2729 cli_cmd_flag_sensitive,
2730 "<network id> <password> = configure password for an SSID" },
2731 { "new_password", wpa_cli_cmd_new_password,
2732 cli_cmd_flag_sensitive,
2733 "<network id> <password> = change password for an SSID" },
2734 { "pin", wpa_cli_cmd_pin,
2735 cli_cmd_flag_sensitive,
2736 "<network id> <pin> = configure pin for an SSID" },
2737 { "otp", wpa_cli_cmd_otp,
2738 cli_cmd_flag_sensitive,
2739 "<network id> <password> = configure one-time-password for an SSID"
2741 { "passphrase", wpa_cli_cmd_passphrase,
2742 cli_cmd_flag_sensitive,
2743 "<network id> <passphrase> = configure private key passphrase\n"
2745 { "bssid", wpa_cli_cmd_bssid,
2747 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2748 { "blacklist", wpa_cli_cmd_blacklist,
2750 "<BSSID> = add a BSSID to the blacklist\n"
2751 "blacklist clear = clear the blacklist\n"
2752 "blacklist = display the blacklist" },
2753 { "log_level", wpa_cli_cmd_log_level,
2755 "<level> [<timestamp>] = update the log level/timestamp\n"
2756 "log_level = display the current log level and log options" },
2757 { "list_networks", wpa_cli_cmd_list_networks,
2759 "= list configured networks" },
2760 { "select_network", wpa_cli_cmd_select_network,
2762 "<network id> = select a network (disable others)" },
2763 { "enable_network", wpa_cli_cmd_enable_network,
2765 "<network id> = enable a network" },
2766 { "disable_network", wpa_cli_cmd_disable_network,
2768 "<network id> = disable a network" },
2769 { "add_network", wpa_cli_cmd_add_network,
2771 "= add a network" },
2772 { "remove_network", wpa_cli_cmd_remove_network,
2774 "<network id> = remove a network" },
2775 { "set_network", wpa_cli_cmd_set_network,
2776 cli_cmd_flag_sensitive,
2777 "<network id> <variable> <value> = set network variables (shows\n"
2778 " list of variables when run without arguments)" },
2779 { "get_network", wpa_cli_cmd_get_network,
2781 "<network id> <variable> = get network variables" },
2782 { "save_config", wpa_cli_cmd_save_config,
2784 "= save the current configuration" },
2785 { "disconnect", wpa_cli_cmd_disconnect,
2787 "= disconnect and wait for reassociate/reconnect command before\n"
2789 { "reconnect", wpa_cli_cmd_reconnect,
2791 "= like reassociate, but only takes effect if already disconnected"
2793 { "scan", wpa_cli_cmd_scan,
2795 "= request new BSS scan" },
2796 { "scan_results", wpa_cli_cmd_scan_results,
2798 "= get latest scan results" },
2799 { "bss", wpa_cli_cmd_bss,
2801 "<<idx> | <bssid>> = get detailed scan result info" },
2802 { "get_capability", wpa_cli_cmd_get_capability,
2804 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2805 { "reconfigure", wpa_cli_cmd_reconfigure,
2807 "= force wpa_supplicant to re-read its configuration file" },
2808 { "terminate", wpa_cli_cmd_terminate,
2810 "= terminate wpa_supplicant" },
2811 { "interface_add", wpa_cli_cmd_interface_add,
2813 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2814 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2816 { "interface_remove", wpa_cli_cmd_interface_remove,
2818 "<ifname> = removes the interface" },
2819 { "interface_list", wpa_cli_cmd_interface_list,
2821 "= list available interfaces" },
2822 { "ap_scan", wpa_cli_cmd_ap_scan,
2824 "<value> = set ap_scan parameter" },
2825 { "scan_interval", wpa_cli_cmd_scan_interval,
2827 "<value> = set scan_interval parameter (in seconds)" },
2828 { "bss_expire_age", wpa_cli_cmd_bss_expire_age,
2830 "<value> = set BSS expiration age parameter" },
2831 { "bss_expire_count", wpa_cli_cmd_bss_expire_count,
2833 "<value> = set BSS expiration scan count parameter" },
2834 { "stkstart", wpa_cli_cmd_stkstart,
2836 "<addr> = request STK negotiation with <addr>" },
2837 { "ft_ds", wpa_cli_cmd_ft_ds,
2839 "<addr> = request over-the-DS FT with <addr>" },
2840 { "wps_pbc", wpa_cli_cmd_wps_pbc,
2842 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2843 { "wps_pin", wpa_cli_cmd_wps_pin,
2844 cli_cmd_flag_sensitive,
2845 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2847 { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
2848 cli_cmd_flag_sensitive,
2849 "<PIN> = verify PIN checksum" },
2850 { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
2851 "Cancels the pending WPS operation" },
2852 #ifdef CONFIG_WPS_OOB
2853 { "wps_oob", wpa_cli_cmd_wps_oob,
2854 cli_cmd_flag_sensitive,
2855 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2856 #endif /* CONFIG_WPS_OOB */
2857 { "wps_reg", wpa_cli_cmd_wps_reg,
2858 cli_cmd_flag_sensitive,
2859 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2860 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin,
2861 cli_cmd_flag_sensitive,
2862 "[params..] = enable/disable AP PIN" },
2863 { "wps_er_start", wpa_cli_cmd_wps_er_start,
2865 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2866 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2868 "= stop Wi-Fi Protected Setup External Registrar" },
2869 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2870 cli_cmd_flag_sensitive,
2871 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2872 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2874 "<UUID> = accept an Enrollee PBC using External Registrar" },
2875 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2876 cli_cmd_flag_sensitive,
2877 "<UUID> <PIN> = learn AP configuration" },
2878 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
2880 "<UUID> <network id> = set AP configuration for enrolling" },
2881 { "wps_er_config", wpa_cli_cmd_wps_er_config,
2882 cli_cmd_flag_sensitive,
2883 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2884 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2886 "<addr> = request RSN authentication with <addr> in IBSS" },
2888 { "sta", wpa_cli_cmd_sta,
2890 "<addr> = get information about an associated station (AP)" },
2891 { "all_sta", wpa_cli_cmd_all_sta,
2893 "= get information about all associated stations (AP)" },
2894 #endif /* CONFIG_AP */
2895 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2896 "= notification of suspend/hibernate" },
2897 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2898 "= notification of resume/thaw" },
2899 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2900 "= drop SA without deauth/disassoc (test command)" },
2901 { "roam", wpa_cli_cmd_roam,
2903 "<addr> = roam to the specified BSS" },
2905 { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2906 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2907 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2908 "= stop P2P Devices search" },
2909 { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2910 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2911 { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2912 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2913 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2914 "<ifname> = remove P2P group interface (terminate group if GO)" },
2915 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2916 "= add a new P2P group (local end as GO)" },
2917 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2918 "<addr> <method> = request provisioning discovery" },
2919 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2921 "= get the passphrase for a group (GO only)" },
2922 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2924 "<addr> <TLVs> = schedule service discovery request" },
2925 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2927 "<id> = cancel pending service discovery request" },
2928 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2930 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2931 { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2933 "= indicate change in local services" },
2934 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2936 "<external> = set external processing of service discovery" },
2937 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2939 "= remove all stored service entries" },
2940 { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2942 "<bonjour|upnp> <query|version> <response|service> = add a local "
2944 { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2946 "<bonjour|upnp> <query|version> [|service] = remove a local "
2948 { "p2p_reject", wpa_cli_cmd_p2p_reject,
2950 "<addr> = reject connection attempts from a specific peer" },
2951 { "p2p_invite", wpa_cli_cmd_p2p_invite,
2953 "<cmd> [peer=addr] = invite peer" },
2954 { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2955 "[discovered] = list known (optionally, only fully discovered) P2P "
2957 { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2958 "<address> = show information about known P2P peer" },
2959 { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
2960 "<field> <value> = set a P2P parameter" },
2961 { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
2962 "= flush P2P state" },
2963 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
2964 "= cancel P2P group formation" },
2965 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none,
2966 "<address> = unauthorize a peer" },
2967 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
2968 "[<duration> <interval>] [<duration> <interval>] = request GO "
2970 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
2971 "[<period> <interval>] = set extended listen timing" },
2972 #endif /* CONFIG_P2P */
2974 #ifdef CONFIG_INTERWORKING
2975 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, cli_cmd_flag_none,
2976 "= fetch ANQP information for all APs" },
2977 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, cli_cmd_flag_none,
2978 "= stop fetch_anqp operation" },
2979 { "interworking_select", wpa_cli_cmd_interworking_select,
2981 "[auto] = perform Interworking network selection" },
2982 { "interworking_connect", wpa_cli_cmd_interworking_connect,
2984 "<BSSID> = connect using Interworking credentials" },
2985 { "anqp_get", wpa_cli_cmd_anqp_get, cli_cmd_flag_none,
2986 "<addr> <info id>[,<info id>]... = request ANQP information" },
2987 #endif /* CONFIG_INTERWORKING */
2988 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
2989 "<0/1> = disable/enable automatic reconnection" },
2990 { "tdls_discover", wpa_cli_cmd_tdls_discover,
2992 "<addr> = request TDLS discovery with <addr>" },
2993 { "tdls_setup", wpa_cli_cmd_tdls_setup,
2995 "<addr> = request TDLS setup with <addr>" },
2996 { "tdls_teardown", wpa_cli_cmd_tdls_teardown,
2998 "<addr> = tear down TDLS with <addr>" },
2999 { "signal_poll", wpa_cli_cmd_signal_poll,
3001 "= get signal parameters" },
3002 { "reauthenticate", wpa_cli_cmd_reauthenticate, cli_cmd_flag_none,
3003 "= trigger IEEE 802.1X/EAPOL reauthentication" },
3004 { NULL, NULL, cli_cmd_flag_none, NULL }
3009 * Prints command usage, lines are padded with the specified string.
3011 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
3016 printf("%s%s ", pad, cmd->cmd);
3017 for (n = 0; (c = cmd->usage[n]); n++) {
3026 static void print_help(void)
3029 printf("commands:\n");
3030 for (n = 0; wpa_cli_commands[n].cmd; n++)
3031 print_cmd_help(&wpa_cli_commands[n], " ");
3035 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
3037 const char *c, *delim;
3041 delim = os_strchr(cmd, ' ');
3045 len = os_strlen(cmd);
3047 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
3048 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
3049 return (wpa_cli_commands[n].flags &
3050 cli_cmd_flag_sensitive);
3056 static char ** wpa_list_cmd_list(void)
3061 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
3062 res = os_zalloc(count * sizeof(char *));
3066 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3067 res[i] = os_strdup(wpa_cli_commands[i].cmd);
3076 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
3081 if (os_strcasecmp(cmd, "bss") == 0)
3082 return wpa_cli_complete_bss(str, pos);
3084 if (os_strcasecmp(cmd, "p2p_connect") == 0)
3085 return wpa_cli_complete_p2p_connect(str, pos);
3086 if (os_strcasecmp(cmd, "p2p_peer") == 0)
3087 return wpa_cli_complete_p2p_peer(str, pos);
3088 if (os_strcasecmp(cmd, "p2p_group_remove") == 0)
3089 return wpa_cli_complete_p2p_group_remove(str, pos);
3090 #endif /* CONFIG_P2P */
3092 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3093 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
3095 printf("\r%s\n", wpa_cli_commands[i].usage);
3105 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
3111 end = os_strchr(str, ' ');
3112 if (end == NULL || str + pos < end)
3113 return wpa_list_cmd_list();
3115 cmd = os_malloc(pos + 1);
3118 os_memcpy(cmd, str, pos);
3119 cmd[end - str] = '\0';
3120 res = wpa_cli_cmd_completion(cmd, str, pos);
3126 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3128 struct wpa_cli_cmd *cmd, *match = NULL;
3133 cmd = wpa_cli_commands;
3135 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3138 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3139 /* we have an exact match */
3149 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3150 cmd = wpa_cli_commands;
3152 if (os_strncasecmp(cmd->cmd, argv[0],
3153 os_strlen(argv[0])) == 0) {
3154 printf(" %s", cmd->cmd);
3160 } else if (count == 0) {
3161 printf("Unknown command '%s'\n", argv[0]);
3164 ret = match->handler(ctrl, argc - 1, &argv[1]);
3171 static int str_match(const char *a, const char *b)
3173 return os_strncmp(a, b, os_strlen(b)) == 0;
3177 static int wpa_cli_exec(const char *program, const char *arg1,
3185 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
3186 cmd = os_malloc(len);
3189 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
3190 if (res < 0 || (size_t) res >= len) {
3194 cmd[len - 1] = '\0';
3196 if (system(cmd) < 0)
3198 #endif /* _WIN32_WCE */
3205 static void wpa_cli_action_process(const char *msg)
3208 char *copy = NULL, *id, *pos2;
3213 pos = os_strchr(pos, '>');
3220 if (str_match(pos, WPA_EVENT_CONNECTED)) {
3222 os_unsetenv("WPA_ID");
3223 os_unsetenv("WPA_ID_STR");
3224 os_unsetenv("WPA_CTRL_DIR");
3226 pos = os_strstr(pos, "[id=");
3228 copy = os_strdup(pos + 4);
3232 while (*pos2 && *pos2 != ' ')
3236 os_setenv("WPA_ID", id, 1);
3237 while (*pos2 && *pos2 != '=')
3242 while (*pos2 && *pos2 != ']')
3245 os_setenv("WPA_ID_STR", id, 1);
3249 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3251 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
3252 wpa_cli_connected = 1;
3253 wpa_cli_last_id = new_id;
3254 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
3256 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3257 if (wpa_cli_connected) {
3258 wpa_cli_connected = 0;
3259 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
3261 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3262 wpa_cli_exec(action_file, ctrl_ifname, pos);
3263 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3264 wpa_cli_exec(action_file, ctrl_ifname, pos);
3265 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3266 wpa_cli_exec(action_file, ctrl_ifname, pos);
3267 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3268 wpa_cli_exec(action_file, ctrl_ifname, pos);
3269 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3270 wpa_cli_exec(action_file, ctrl_ifname, pos);
3271 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3272 wpa_cli_exec(action_file, ctrl_ifname, pos);
3273 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3274 wpa_cli_exec(action_file, ctrl_ifname, pos);
3275 } else if (str_match(pos, AP_STA_CONNECTED)) {
3276 wpa_cli_exec(action_file, ctrl_ifname, pos);
3277 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3278 wpa_cli_exec(action_file, ctrl_ifname, pos);
3279 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3280 printf("wpa_supplicant is terminating - stop monitoring\n");
3286 #ifndef CONFIG_ANSI_C_EXTRA
3287 static void wpa_cli_action_cb(char *msg, size_t len)
3289 wpa_cli_action_process(msg);
3291 #endif /* CONFIG_ANSI_C_EXTRA */
3294 static void wpa_cli_reconnect(void)
3296 wpa_cli_close_connection();
3297 wpa_cli_open_connection(ctrl_ifname, 1);
3301 static void cli_event(const char *str)
3303 const char *start, *s;
3305 start = os_strchr(str, '>');
3311 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3312 s = os_strchr(start, ' ');
3315 s = os_strchr(s + 1, ' ');
3318 cli_txt_list_add(&bsses, s + 1);
3322 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3323 s = os_strchr(start, ' ');
3326 s = os_strchr(s + 1, ' ');
3329 cli_txt_list_del_addr(&bsses, s + 1);
3334 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3335 s = os_strstr(start, " p2p_dev_addr=");
3338 cli_txt_list_add_addr(&p2p_peers, s + 14);
3342 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3343 s = os_strstr(start, " p2p_dev_addr=");
3346 cli_txt_list_del_addr(&p2p_peers, s + 14);
3350 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3351 s = os_strchr(start, ' ');
3354 cli_txt_list_add_word(&p2p_groups, s + 1);
3358 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3359 s = os_strchr(start, ' ');
3362 cli_txt_list_del_word(&p2p_groups, s + 1);
3365 #endif /* CONFIG_P2P */
3369 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3371 if (ctrl_conn == NULL) {
3372 wpa_cli_reconnect();
3375 while (wpa_ctrl_pending(ctrl) > 0) {
3377 size_t len = sizeof(buf) - 1;
3378 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3381 wpa_cli_action_process(buf);
3384 if (wpa_cli_show_event(buf)) {
3386 printf("\r%s\n", buf);
3391 printf("Could not read pending message.\n");
3396 if (wpa_ctrl_pending(ctrl) < 0) {
3397 printf("Connection to wpa_supplicant lost - trying to "
3399 wpa_cli_reconnect();
3405 static int tokenize_cmd(char *cmd, char *argv[])
3418 if (argc == max_args)
3421 char *pos2 = os_strrchr(pos, '"');
3425 while (*pos != '\0' && *pos != ' ')
3435 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3437 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3438 printf("Connection to wpa_supplicant lost - trying to "
3440 wpa_cli_close_connection();
3443 wpa_cli_reconnect();
3444 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3448 static void wpa_cli_eloop_terminate(int sig, void *signal_ctx)
3454 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3456 wpa_cli_recv_pending(mon_conn, 0);
3460 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3462 char *argv[max_args];
3464 argc = tokenize_cmd(cmd, argv);
3466 wpa_request(ctrl_conn, argc, argv);
3470 static void wpa_cli_edit_eof_cb(void *ctx)
3476 static void wpa_cli_interactive(void)
3478 char *home, *hfile = NULL;
3480 printf("\nInteractive mode\n\n");
3482 home = getenv("HOME");
3484 const char *fname = ".wpa_cli_history";
3485 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3486 hfile = os_malloc(hfile_len);
3488 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3491 eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
3492 edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3493 wpa_cli_edit_completion_cb, NULL, hfile);
3494 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3498 cli_txt_list_flush(&p2p_peers);
3499 cli_txt_list_flush(&p2p_groups);
3500 cli_txt_list_flush(&bsses);
3501 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3503 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3504 wpa_cli_close_connection();
3508 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3510 #ifdef CONFIG_ANSI_C_EXTRA
3511 /* TODO: ANSI C version(?) */
3512 printf("Action processing not supported in ANSI C build.\n");
3513 #else /* CONFIG_ANSI_C_EXTRA */
3517 char buf[256]; /* note: large enough to fit in unsolicited messages */
3520 fd = wpa_ctrl_get_fd(ctrl);
3522 while (!wpa_cli_quit) {
3525 tv.tv_sec = ping_interval;
3527 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3528 if (res < 0 && errno != EINTR) {
3533 if (FD_ISSET(fd, &rfds))
3534 wpa_cli_recv_pending(ctrl, 1);
3536 /* verify that connection is still working */
3537 len = sizeof(buf) - 1;
3538 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3539 wpa_cli_action_cb) < 0 ||
3540 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3541 printf("wpa_supplicant did not reply to PING "
3542 "command - exiting\n");
3547 #endif /* CONFIG_ANSI_C_EXTRA */
3551 static void wpa_cli_cleanup(void)
3553 wpa_cli_close_connection();
3555 os_daemonize_terminate(pid_file);
3557 os_program_deinit();
3560 static void wpa_cli_terminate(int sig)
3567 static char * wpa_cli_get_default_ifname(void)
3569 char *ifname = NULL;
3571 #ifdef CONFIG_CTRL_IFACE_UNIX
3572 struct dirent *dent;
3573 DIR *dir = opendir(ctrl_iface_dir);
3576 char ifprop[PROPERTY_VALUE_MAX];
3577 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3578 ifname = os_strdup(ifprop);
3579 printf("Using interface '%s'\n", ifname);
3582 #endif /* ANDROID */
3585 while ((dent = readdir(dir))) {
3586 #ifdef _DIRENT_HAVE_D_TYPE
3588 * Skip the file if it is not a socket. Also accept
3589 * DT_UNKNOWN (0) in case the C library or underlying
3590 * file system does not support d_type.
3592 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3594 #endif /* _DIRENT_HAVE_D_TYPE */
3595 if (os_strcmp(dent->d_name, ".") == 0 ||
3596 os_strcmp(dent->d_name, "..") == 0)
3598 printf("Selected interface '%s'\n", dent->d_name);
3599 ifname = os_strdup(dent->d_name);
3603 #endif /* CONFIG_CTRL_IFACE_UNIX */
3605 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3606 char buf[2048], *pos;
3608 struct wpa_ctrl *ctrl;
3611 ctrl = wpa_ctrl_open(NULL);
3615 len = sizeof(buf) - 1;
3616 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3619 pos = os_strchr(buf, '\n');
3622 ifname = os_strdup(buf);
3624 wpa_ctrl_close(ctrl);
3625 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3631 int main(int argc, char *argv[])
3633 int warning_displayed = 0;
3637 const char *global = NULL;
3639 if (os_program_init())
3643 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3648 action_file = optarg;
3657 ping_interval = atoi(optarg);
3663 printf("%s\n", wpa_cli_version);
3666 os_free(ctrl_ifname);
3667 ctrl_ifname = os_strdup(optarg);
3670 ctrl_iface_dir = optarg;
3681 interactive = (argc == optind) && (action_file == NULL);
3684 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3690 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3691 ctrl_conn = wpa_ctrl_open(NULL);
3692 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3693 ctrl_conn = wpa_ctrl_open(global);
3694 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3695 if (ctrl_conn == NULL) {
3696 perror("Failed to connect to wpa_supplicant - "
3703 signal(SIGINT, wpa_cli_terminate);
3704 signal(SIGTERM, wpa_cli_terminate);
3705 #endif /* _WIN32_WCE */
3707 if (ctrl_ifname == NULL)
3708 ctrl_ifname = wpa_cli_get_default_ifname();
3712 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3713 if (warning_displayed)
3714 printf("Connection established.\n");
3718 if (!warning_displayed) {
3719 printf("Could not connect to wpa_supplicant - "
3721 warning_displayed = 1;
3728 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3729 perror("Failed to connect to wpa_supplicant - "
3735 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3736 wpa_cli_attached = 1;
3738 printf("Warning: Failed to attach to "
3739 "wpa_supplicant.\n");
3745 if (daemonize && os_daemonize(pid_file))
3749 wpa_cli_interactive();
3750 else if (action_file)
3751 wpa_cli_action(ctrl_conn);
3753 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3755 os_free(ctrl_ifname);
3762 #else /* CONFIG_CTRL_IFACE */
3763 int main(int argc, char *argv[])
3765 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3768 #endif /* CONFIG_CTRL_IFACE */