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 "
1468 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s %s",
1471 res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s",
1473 if (res < 0 || (size_t) res >= sizeof(cmd))
1475 cmd[sizeof(cmd) - 1] = '\0';
1477 return wpa_ctrl_command(ctrl, cmd);
1481 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1488 printf("Invalid DISABLE_NETWORK command: needs one argument "
1493 res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
1494 if (res < 0 || (size_t) res >= sizeof(cmd))
1496 cmd[sizeof(cmd) - 1] = '\0';
1498 return wpa_ctrl_command(ctrl, cmd);
1502 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1505 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1509 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1516 printf("Invalid REMOVE_NETWORK command: needs one argument "
1521 res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
1522 if (res < 0 || (size_t) res >= sizeof(cmd))
1524 cmd[sizeof(cmd) - 1] = '\0';
1526 return wpa_ctrl_command(ctrl, cmd);
1530 static void wpa_cli_show_network_variables(void)
1532 printf("set_network variables:\n"
1533 " ssid (network name, SSID)\n"
1534 " psk (WPA passphrase or pre-shared key)\n"
1535 " key_mgmt (key management protocol)\n"
1536 " identity (EAP identity)\n"
1537 " password (EAP password)\n"
1540 "Note: Values are entered in the same format as the "
1541 "configuration file is using,\n"
1542 "i.e., strings values need to be inside double quotation "
1544 "For example: set_network 1 ssid \"network name\"\n"
1546 "Please see wpa_supplicant.conf documentation for full list "
1547 "of\navailable variables.\n");
1551 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1558 wpa_cli_show_network_variables();
1563 printf("Invalid SET_NETWORK command: needs three arguments\n"
1564 "(network id, variable name, and value)\n");
1568 res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
1569 argv[0], argv[1], argv[2]);
1570 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1571 printf("Too long SET_NETWORK command.\n");
1574 return wpa_ctrl_command(ctrl, cmd);
1578 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1585 wpa_cli_show_network_variables();
1590 printf("Invalid GET_NETWORK command: needs two arguments\n"
1591 "(network id and variable name)\n");
1595 res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
1597 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1598 printf("Too long GET_NETWORK command.\n");
1601 return wpa_ctrl_command(ctrl, cmd);
1605 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1608 return wpa_ctrl_command(ctrl, "DISCONNECT");
1612 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1615 return wpa_ctrl_command(ctrl, "RECONNECT");
1619 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1622 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1626 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1628 return wpa_ctrl_command(ctrl, "SCAN");
1632 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1635 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1639 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1645 printf("Invalid BSS command: need one argument (index or "
1650 res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
1651 if (res < 0 || (size_t) res >= sizeof(cmd))
1653 cmd[sizeof(cmd) - 1] = '\0';
1655 return wpa_ctrl_command(ctrl, cmd);
1659 static char ** wpa_cli_complete_bss(const char *str, int pos)
1661 int arg = get_cmd_arg_num(str, pos);
1666 res = cli_txt_list_array(&bsses);
1674 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1680 if (argc < 1 || argc > 2) {
1681 printf("Invalid GET_CAPABILITY command: need either one or "
1686 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1687 printf("Invalid GET_CAPABILITY command: second argument, "
1688 "if any, must be 'strict'\n");
1692 res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
1693 (argc == 2) ? " strict" : "");
1694 if (res < 0 || (size_t) res >= sizeof(cmd))
1696 cmd[sizeof(cmd) - 1] = '\0';
1698 return wpa_ctrl_command(ctrl, cmd);
1702 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1704 printf("Available interfaces:\n");
1705 return wpa_ctrl_command(ctrl, "INTERFACES");
1709 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1712 wpa_cli_list_interfaces(ctrl);
1716 wpa_cli_close_connection();
1717 os_free(ctrl_ifname);
1718 ctrl_ifname = os_strdup(argv[0]);
1720 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1721 printf("Connected to interface '%s.\n", ctrl_ifname);
1723 printf("Could not connect to interface '%s' - re-trying\n",
1730 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1733 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1737 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1740 return wpa_ctrl_command(ctrl, "TERMINATE");
1744 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1751 printf("Invalid INTERFACE_ADD command: needs at least one "
1752 "argument (interface name)\n"
1753 "All arguments: ifname confname driver ctrl_interface "
1754 "driver_param bridge_name\n");
1759 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1760 * <driver_param>TAB<bridge_name>
1762 res = os_snprintf(cmd, sizeof(cmd),
1763 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1765 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1766 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1767 argc > 5 ? argv[5] : "");
1768 if (res < 0 || (size_t) res >= sizeof(cmd))
1770 cmd[sizeof(cmd) - 1] = '\0';
1771 return wpa_ctrl_command(ctrl, cmd);
1775 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1782 printf("Invalid INTERFACE_REMOVE command: needs one argument "
1783 "(interface name)\n");
1787 res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
1788 if (res < 0 || (size_t) res >= sizeof(cmd))
1790 cmd[sizeof(cmd) - 1] = '\0';
1791 return wpa_ctrl_command(ctrl, cmd);
1795 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1798 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1803 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1807 printf("Invalid 'sta' command - exactly one argument, STA "
1808 "address, is required.\n");
1811 os_snprintf(buf, sizeof(buf), "STA %s", argv[0]);
1812 return wpa_ctrl_command(ctrl, buf);
1816 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1817 char *addr, size_t addr_len)
1819 char buf[4096], *pos;
1823 if (ctrl_conn == NULL) {
1824 printf("Not connected to hostapd - command dropped.\n");
1827 len = sizeof(buf) - 1;
1828 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
1831 printf("'%s' command timed out.\n", cmd);
1833 } else if (ret < 0) {
1834 printf("'%s' command failed.\n", cmd);
1839 if (memcmp(buf, "FAIL", 4) == 0)
1844 while (*pos != '\0' && *pos != '\n')
1847 os_strlcpy(addr, buf, addr_len);
1852 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1854 char addr[32], cmd[64];
1856 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1859 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1860 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1864 #endif /* CONFIG_AP */
1867 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1869 return wpa_ctrl_command(ctrl, "SUSPEND");
1873 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1875 return wpa_ctrl_command(ctrl, "RESUME");
1879 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1881 return wpa_ctrl_command(ctrl, "DROP_SA");
1885 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1891 printf("Invalid ROAM command: needs one argument "
1892 "(target AP's BSSID)\n");
1896 res = os_snprintf(cmd, sizeof(cmd), "ROAM %s", argv[0]);
1897 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1898 printf("Too long ROAM command.\n");
1901 return wpa_ctrl_command(ctrl, cmd);
1907 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1913 return wpa_ctrl_command(ctrl, "P2P_FIND");
1916 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s %s",
1917 argv[0], argv[1], argv[2]);
1919 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s %s",
1922 res = os_snprintf(cmd, sizeof(cmd), "P2P_FIND %s", argv[0]);
1923 if (res < 0 || (size_t) res >= sizeof(cmd))
1925 cmd[sizeof(cmd) - 1] = '\0';
1926 return wpa_ctrl_command(ctrl, cmd);
1930 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1933 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1937 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1944 printf("Invalid P2P_CONNECT command: needs at least two "
1945 "arguments (address and pbc/PIN)\n");
1950 res = os_snprintf(cmd, sizeof(cmd),
1951 "P2P_CONNECT %s %s %s %s %s",
1952 argv[0], argv[1], argv[2], argv[3],
1955 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s %s",
1956 argv[0], argv[1], argv[2], argv[3]);
1958 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s %s",
1959 argv[0], argv[1], argv[2]);
1961 res = os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
1963 if (res < 0 || (size_t) res >= sizeof(cmd))
1965 cmd[sizeof(cmd) - 1] = '\0';
1966 return wpa_ctrl_command(ctrl, cmd);
1970 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
1972 int arg = get_cmd_arg_num(str, pos);
1977 res = cli_txt_list_array(&p2p_peers);
1985 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1992 return wpa_ctrl_command(ctrl, "P2P_LISTEN");
1994 res = os_snprintf(cmd, sizeof(cmd), "P2P_LISTEN %s", argv[0]);
1995 if (res < 0 || (size_t) res >= sizeof(cmd))
1997 cmd[sizeof(cmd) - 1] = '\0';
1998 return wpa_ctrl_command(ctrl, cmd);
2002 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
2009 printf("Invalid P2P_GROUP_REMOVE command: needs one argument "
2010 "(interface name)\n");
2014 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s", argv[0]);
2015 if (res < 0 || (size_t) res >= sizeof(cmd))
2017 cmd[sizeof(cmd) - 1] = '\0';
2018 return wpa_ctrl_command(ctrl, cmd);
2022 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
2024 int arg = get_cmd_arg_num(str, pos);
2029 res = cli_txt_list_array(&p2p_groups);
2037 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
2044 return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
2047 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s %s",
2050 res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s",
2052 if (res < 0 || (size_t) res >= sizeof(cmd))
2054 cmd[sizeof(cmd) - 1] = '\0';
2055 return wpa_ctrl_command(ctrl, cmd);
2059 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
2065 if (argc != 2 && argc != 3) {
2066 printf("Invalid P2P_PROV_DISC command: needs at least "
2067 "two arguments, address and config method\n"
2068 "(display, keypad, or pbc) and an optional join\n");
2073 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s %s",
2074 argv[0], argv[1], argv[2]);
2076 res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
2078 if (res < 0 || (size_t) res >= sizeof(cmd))
2080 cmd[sizeof(cmd) - 1] = '\0';
2081 return wpa_ctrl_command(ctrl, cmd);
2085 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
2088 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
2092 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
2098 if (argc != 2 && argc != 4) {
2099 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2100 "arguments (address and TLVs) or four arguments "
2101 "(address, \"upnp\", version, search target "
2107 res = os_snprintf(cmd, sizeof(cmd),
2108 "P2P_SERV_DISC_REQ %s %s %s %s",
2109 argv[0], argv[1], argv[2], argv[3]);
2111 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ %s %s",
2113 if (res < 0 || (size_t) res >= sizeof(cmd))
2115 cmd[sizeof(cmd) - 1] = '\0';
2116 return wpa_ctrl_command(ctrl, cmd);
2120 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
2121 int argc, char *argv[])
2127 printf("Invalid P2P_SERV_DISC_CANCEL_REQ command: needs one "
2128 "argument (pending request identifier)\n");
2132 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_CANCEL_REQ %s",
2134 if (res < 0 || (size_t) res >= sizeof(cmd))
2136 cmd[sizeof(cmd) - 1] = '\0';
2137 return wpa_ctrl_command(ctrl, cmd);
2141 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
2148 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2149 "arguments (freq, address, dialog token, and TLVs)\n");
2153 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
2154 argv[0], argv[1], argv[2], argv[3]);
2155 if (res < 0 || (size_t) res >= sizeof(cmd))
2157 cmd[sizeof(cmd) - 1] = '\0';
2158 return wpa_ctrl_command(ctrl, cmd);
2162 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
2165 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
2169 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
2170 int argc, char *argv[])
2176 printf("Invalid P2P_SERV_DISC_EXTERNAL command: needs one "
2177 "argument (external processing: 0/1)\n");
2181 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_EXTERNAL %s",
2183 if (res < 0 || (size_t) res >= sizeof(cmd))
2185 cmd[sizeof(cmd) - 1] = '\0';
2186 return wpa_ctrl_command(ctrl, cmd);
2190 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
2193 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
2197 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
2203 if (argc != 3 && argc != 4) {
2204 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
2210 res = os_snprintf(cmd, sizeof(cmd),
2211 "P2P_SERVICE_ADD %s %s %s %s",
2212 argv[0], argv[1], argv[2], argv[3]);
2214 res = os_snprintf(cmd, sizeof(cmd),
2215 "P2P_SERVICE_ADD %s %s %s",
2216 argv[0], argv[1], argv[2]);
2217 if (res < 0 || (size_t) res >= sizeof(cmd))
2219 cmd[sizeof(cmd) - 1] = '\0';
2220 return wpa_ctrl_command(ctrl, cmd);
2224 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2230 if (argc != 2 && argc != 3) {
2231 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2237 res = os_snprintf(cmd, sizeof(cmd),
2238 "P2P_SERVICE_DEL %s %s %s",
2239 argv[0], argv[1], argv[2]);
2241 res = os_snprintf(cmd, sizeof(cmd),
2242 "P2P_SERVICE_DEL %s %s",
2244 if (res < 0 || (size_t) res >= sizeof(cmd))
2246 cmd[sizeof(cmd) - 1] = '\0';
2247 return wpa_ctrl_command(ctrl, cmd);
2251 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2252 int argc, char *argv[])
2258 printf("Invalid P2P_REJECT command: needs one argument "
2259 "(peer address)\n");
2263 res = os_snprintf(cmd, sizeof(cmd), "P2P_REJECT %s", argv[0]);
2264 if (res < 0 || (size_t) res >= sizeof(cmd))
2266 cmd[sizeof(cmd) - 1] = '\0';
2267 return wpa_ctrl_command(ctrl, cmd);
2271 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2272 int argc, char *argv[])
2278 printf("Invalid P2P_INVITE command: needs at least one "
2284 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s %s",
2285 argv[0], argv[1], argv[2]);
2287 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s %s",
2290 res = os_snprintf(cmd, sizeof(cmd), "P2P_INVITE %s", argv[0]);
2291 if (res < 0 || (size_t) res >= sizeof(cmd))
2293 cmd[sizeof(cmd) - 1] = '\0';
2294 return wpa_ctrl_command(ctrl, cmd);
2298 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2302 printf("Invalid 'p2p_peer' command - exactly one argument, "
2303 "P2P peer device address, is required.\n");
2306 os_snprintf(buf, sizeof(buf), "P2P_PEER %s", argv[0]);
2307 return wpa_ctrl_command(ctrl, buf);
2311 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2313 int arg = get_cmd_arg_num(str, pos);
2318 res = cli_txt_list_array(&p2p_peers);
2326 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2327 char *addr, size_t addr_len,
2330 char buf[4096], *pos;
2334 if (ctrl_conn == NULL)
2336 len = sizeof(buf) - 1;
2337 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
2340 printf("'%s' command timed out.\n", cmd);
2342 } else if (ret < 0) {
2343 printf("'%s' command failed.\n", cmd);
2348 if (memcmp(buf, "FAIL", 4) == 0)
2352 while (*pos != '\0' && *pos != '\n')
2355 os_strlcpy(addr, buf, addr_len);
2356 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2357 printf("%s\n", addr);
2362 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2364 char addr[32], cmd[64];
2367 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2369 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2370 addr, sizeof(addr), discovered))
2373 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2374 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2381 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2387 printf("Invalid P2P_SET command: needs two arguments (field, "
2392 res = os_snprintf(cmd, sizeof(cmd), "P2P_SET %s %s", argv[0], argv[1]);
2393 if (res < 0 || (size_t) res >= sizeof(cmd))
2395 cmd[sizeof(cmd) - 1] = '\0';
2396 return wpa_ctrl_command(ctrl, cmd);
2400 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2402 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2406 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2409 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2413 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2420 printf("Invalid P2P_UNAUTHORIZE command: needs one argument "
2421 "(peer address)\n");
2425 res = os_snprintf(cmd, sizeof(cmd), "P2P_UNAUTHORIZE %s", argv[0]);
2427 if (res < 0 || (size_t) res >= sizeof(cmd))
2430 cmd[sizeof(cmd) - 1] = '\0';
2431 return wpa_ctrl_command(ctrl, cmd);
2435 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2441 if (argc != 0 && argc != 2 && argc != 4) {
2442 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2443 "(preferred duration, interval; in microsecods).\n"
2444 "Optional second pair can be used to provide "
2445 "acceptable values.\n");
2450 res = os_snprintf(cmd, sizeof(cmd),
2451 "P2P_PRESENCE_REQ %s %s %s %s",
2452 argv[0], argv[1], argv[2], argv[3]);
2454 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ %s %s",
2457 res = os_snprintf(cmd, sizeof(cmd), "P2P_PRESENCE_REQ");
2458 if (res < 0 || (size_t) res >= sizeof(cmd))
2460 cmd[sizeof(cmd) - 1] = '\0';
2461 return wpa_ctrl_command(ctrl, cmd);
2465 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2471 if (argc != 0 && argc != 2) {
2472 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2473 "(availability period, availability interval; in "
2475 "Extended Listen Timing can be cancelled with this "
2476 "command when used without parameters.\n");
2481 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN %s %s",
2484 res = os_snprintf(cmd, sizeof(cmd), "P2P_EXT_LISTEN");
2485 if (res < 0 || (size_t) res >= sizeof(cmd))
2487 cmd[sizeof(cmd) - 1] = '\0';
2488 return wpa_ctrl_command(ctrl, cmd);
2491 #endif /* CONFIG_P2P */
2494 #ifdef CONFIG_INTERWORKING
2495 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2498 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2502 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2505 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2509 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2516 return wpa_ctrl_command(ctrl, "INTERWORKING_SELECT");
2518 res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_SELECT %s", argv[0]);
2519 if (res < 0 || (size_t) res >= sizeof(cmd))
2521 cmd[sizeof(cmd) - 1] = '\0';
2522 return wpa_ctrl_command(ctrl, cmd);
2526 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2533 printf("Invalid INTERWORKING_CONNECT commands: needs one "
2534 "argument (BSSID)\n");
2538 res = os_snprintf(cmd, sizeof(cmd), "INTERWORKING_CONNECT %s",
2540 if (res < 0 || (size_t) res >= sizeof(cmd))
2542 cmd[sizeof(cmd) - 1] = '\0';
2543 return wpa_ctrl_command(ctrl, cmd);
2547 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2553 printf("Invalid ANQP_GET command: needs two arguments "
2554 "(addr and info id list)\n");
2558 res = os_snprintf(cmd, sizeof(cmd), "ANQP_GET %s %s",
2560 if (res < 0 || (size_t) res >= sizeof(cmd))
2562 cmd[sizeof(cmd) - 1] = '\0';
2563 return wpa_ctrl_command(ctrl, cmd);
2565 #endif /* CONFIG_INTERWORKING */
2568 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2575 printf("Invalid STA_AUTOCONNECT command: needs one argument "
2576 "(0/1 = disable/enable automatic reconnection)\n");
2579 res = os_snprintf(cmd, sizeof(cmd), "STA_AUTOCONNECT %s", argv[0]);
2580 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2581 printf("Too long STA_AUTOCONNECT command.\n");
2584 return wpa_ctrl_command(ctrl, cmd);
2588 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2595 printf("Invalid TDLS_DISCOVER command: needs one argument "
2596 "(Peer STA MAC address)\n");
2600 res = os_snprintf(cmd, sizeof(cmd), "TDLS_DISCOVER %s", argv[0]);
2601 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2602 printf("Too long TDLS_DISCOVER command.\n");
2605 return wpa_ctrl_command(ctrl, cmd);
2609 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2616 printf("Invalid TDLS_SETUP command: needs one argument "
2617 "(Peer STA MAC address)\n");
2621 res = os_snprintf(cmd, sizeof(cmd), "TDLS_SETUP %s", argv[0]);
2622 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2623 printf("Too long TDLS_SETUP command.\n");
2626 return wpa_ctrl_command(ctrl, cmd);
2630 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2637 printf("Invalid TDLS_TEARDOWN command: needs one argument "
2638 "(Peer STA MAC address)\n");
2642 res = os_snprintf(cmd, sizeof(cmd), "TDLS_TEARDOWN %s", argv[0]);
2643 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
2644 printf("Too long TDLS_TEARDOWN command.\n");
2647 return wpa_ctrl_command(ctrl, cmd);
2651 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2654 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2658 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2661 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2665 enum wpa_cli_cmd_flags {
2666 cli_cmd_flag_none = 0x00,
2667 cli_cmd_flag_sensitive = 0x01
2670 struct wpa_cli_cmd {
2672 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2673 enum wpa_cli_cmd_flags flags;
2677 static struct wpa_cli_cmd wpa_cli_commands[] = {
2678 { "status", wpa_cli_cmd_status,
2680 "[verbose] = get current WPA/EAPOL/EAP status" },
2681 { "ping", wpa_cli_cmd_ping,
2683 "= pings wpa_supplicant" },
2684 { "relog", wpa_cli_cmd_relog,
2686 "= re-open log-file (allow rolling logs)" },
2687 { "note", wpa_cli_cmd_note,
2689 "<text> = add a note to wpa_supplicant debug log" },
2690 { "mib", wpa_cli_cmd_mib,
2692 "= get MIB variables (dot1x, dot11)" },
2693 { "help", wpa_cli_cmd_help,
2695 "= show this usage help" },
2696 { "interface", wpa_cli_cmd_interface,
2698 "[ifname] = show interfaces/select interface" },
2699 { "level", wpa_cli_cmd_level,
2701 "<debug level> = change debug level" },
2702 { "license", wpa_cli_cmd_license,
2704 "= show full wpa_cli license" },
2705 { "quit", wpa_cli_cmd_quit,
2708 { "set", wpa_cli_cmd_set,
2710 "= set variables (shows list of variables when run without "
2712 { "get", wpa_cli_cmd_get,
2714 "<name> = get information" },
2715 { "logon", wpa_cli_cmd_logon,
2717 "= IEEE 802.1X EAPOL state machine logon" },
2718 { "logoff", wpa_cli_cmd_logoff,
2720 "= IEEE 802.1X EAPOL state machine logoff" },
2721 { "pmksa", wpa_cli_cmd_pmksa,
2723 "= show PMKSA cache" },
2724 { "reassociate", wpa_cli_cmd_reassociate,
2726 "= force reassociation" },
2727 { "preauthenticate", wpa_cli_cmd_preauthenticate,
2729 "<BSSID> = force preauthentication" },
2730 { "identity", wpa_cli_cmd_identity,
2732 "<network id> <identity> = configure identity for an SSID" },
2733 { "password", wpa_cli_cmd_password,
2734 cli_cmd_flag_sensitive,
2735 "<network id> <password> = configure password for an SSID" },
2736 { "new_password", wpa_cli_cmd_new_password,
2737 cli_cmd_flag_sensitive,
2738 "<network id> <password> = change password for an SSID" },
2739 { "pin", wpa_cli_cmd_pin,
2740 cli_cmd_flag_sensitive,
2741 "<network id> <pin> = configure pin for an SSID" },
2742 { "otp", wpa_cli_cmd_otp,
2743 cli_cmd_flag_sensitive,
2744 "<network id> <password> = configure one-time-password for an SSID"
2746 { "passphrase", wpa_cli_cmd_passphrase,
2747 cli_cmd_flag_sensitive,
2748 "<network id> <passphrase> = configure private key passphrase\n"
2750 { "bssid", wpa_cli_cmd_bssid,
2752 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2753 { "blacklist", wpa_cli_cmd_blacklist,
2755 "<BSSID> = add a BSSID to the blacklist\n"
2756 "blacklist clear = clear the blacklist\n"
2757 "blacklist = display the blacklist" },
2758 { "log_level", wpa_cli_cmd_log_level,
2760 "<level> [<timestamp>] = update the log level/timestamp\n"
2761 "log_level = display the current log level and log options" },
2762 { "list_networks", wpa_cli_cmd_list_networks,
2764 "= list configured networks" },
2765 { "select_network", wpa_cli_cmd_select_network,
2767 "<network id> = select a network (disable others)" },
2768 { "enable_network", wpa_cli_cmd_enable_network,
2770 "<network id> = enable a network" },
2771 { "disable_network", wpa_cli_cmd_disable_network,
2773 "<network id> = disable a network" },
2774 { "add_network", wpa_cli_cmd_add_network,
2776 "= add a network" },
2777 { "remove_network", wpa_cli_cmd_remove_network,
2779 "<network id> = remove a network" },
2780 { "set_network", wpa_cli_cmd_set_network,
2781 cli_cmd_flag_sensitive,
2782 "<network id> <variable> <value> = set network variables (shows\n"
2783 " list of variables when run without arguments)" },
2784 { "get_network", wpa_cli_cmd_get_network,
2786 "<network id> <variable> = get network variables" },
2787 { "save_config", wpa_cli_cmd_save_config,
2789 "= save the current configuration" },
2790 { "disconnect", wpa_cli_cmd_disconnect,
2792 "= disconnect and wait for reassociate/reconnect command before\n"
2794 { "reconnect", wpa_cli_cmd_reconnect,
2796 "= like reassociate, but only takes effect if already disconnected"
2798 { "scan", wpa_cli_cmd_scan,
2800 "= request new BSS scan" },
2801 { "scan_results", wpa_cli_cmd_scan_results,
2803 "= get latest scan results" },
2804 { "bss", wpa_cli_cmd_bss,
2806 "<<idx> | <bssid>> = get detailed scan result info" },
2807 { "get_capability", wpa_cli_cmd_get_capability,
2809 "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
2810 { "reconfigure", wpa_cli_cmd_reconfigure,
2812 "= force wpa_supplicant to re-read its configuration file" },
2813 { "terminate", wpa_cli_cmd_terminate,
2815 "= terminate wpa_supplicant" },
2816 { "interface_add", wpa_cli_cmd_interface_add,
2818 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2819 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2821 { "interface_remove", wpa_cli_cmd_interface_remove,
2823 "<ifname> = removes the interface" },
2824 { "interface_list", wpa_cli_cmd_interface_list,
2826 "= list available interfaces" },
2827 { "ap_scan", wpa_cli_cmd_ap_scan,
2829 "<value> = set ap_scan parameter" },
2830 { "scan_interval", wpa_cli_cmd_scan_interval,
2832 "<value> = set scan_interval parameter (in seconds)" },
2833 { "bss_expire_age", wpa_cli_cmd_bss_expire_age,
2835 "<value> = set BSS expiration age parameter" },
2836 { "bss_expire_count", wpa_cli_cmd_bss_expire_count,
2838 "<value> = set BSS expiration scan count parameter" },
2839 { "stkstart", wpa_cli_cmd_stkstart,
2841 "<addr> = request STK negotiation with <addr>" },
2842 { "ft_ds", wpa_cli_cmd_ft_ds,
2844 "<addr> = request over-the-DS FT with <addr>" },
2845 { "wps_pbc", wpa_cli_cmd_wps_pbc,
2847 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2848 { "wps_pin", wpa_cli_cmd_wps_pin,
2849 cli_cmd_flag_sensitive,
2850 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2852 { "wps_check_pin", wpa_cli_cmd_wps_check_pin,
2853 cli_cmd_flag_sensitive,
2854 "<PIN> = verify PIN checksum" },
2855 { "wps_cancel", wpa_cli_cmd_wps_cancel, cli_cmd_flag_none,
2856 "Cancels the pending WPS operation" },
2857 #ifdef CONFIG_WPS_OOB
2858 { "wps_oob", wpa_cli_cmd_wps_oob,
2859 cli_cmd_flag_sensitive,
2860 "<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
2861 #endif /* CONFIG_WPS_OOB */
2862 { "wps_reg", wpa_cli_cmd_wps_reg,
2863 cli_cmd_flag_sensitive,
2864 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2865 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin,
2866 cli_cmd_flag_sensitive,
2867 "[params..] = enable/disable AP PIN" },
2868 { "wps_er_start", wpa_cli_cmd_wps_er_start,
2870 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2871 { "wps_er_stop", wpa_cli_cmd_wps_er_stop,
2873 "= stop Wi-Fi Protected Setup External Registrar" },
2874 { "wps_er_pin", wpa_cli_cmd_wps_er_pin,
2875 cli_cmd_flag_sensitive,
2876 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2877 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc,
2879 "<UUID> = accept an Enrollee PBC using External Registrar" },
2880 { "wps_er_learn", wpa_cli_cmd_wps_er_learn,
2881 cli_cmd_flag_sensitive,
2882 "<UUID> <PIN> = learn AP configuration" },
2883 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config,
2885 "<UUID> <network id> = set AP configuration for enrolling" },
2886 { "wps_er_config", wpa_cli_cmd_wps_er_config,
2887 cli_cmd_flag_sensitive,
2888 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2889 { "ibss_rsn", wpa_cli_cmd_ibss_rsn,
2891 "<addr> = request RSN authentication with <addr> in IBSS" },
2893 { "sta", wpa_cli_cmd_sta,
2895 "<addr> = get information about an associated station (AP)" },
2896 { "all_sta", wpa_cli_cmd_all_sta,
2898 "= get information about all associated stations (AP)" },
2899 #endif /* CONFIG_AP */
2900 { "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
2901 "= notification of suspend/hibernate" },
2902 { "resume", wpa_cli_cmd_resume, cli_cmd_flag_none,
2903 "= notification of resume/thaw" },
2904 { "drop_sa", wpa_cli_cmd_drop_sa, cli_cmd_flag_none,
2905 "= drop SA without deauth/disassoc (test command)" },
2906 { "roam", wpa_cli_cmd_roam,
2908 "<addr> = roam to the specified BSS" },
2910 { "p2p_find", wpa_cli_cmd_p2p_find, cli_cmd_flag_none,
2911 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2912 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
2913 "= stop P2P Devices search" },
2914 { "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
2915 "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
2916 { "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
2917 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2918 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
2919 "<ifname> = remove P2P group interface (terminate group if GO)" },
2920 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
2921 "= add a new P2P group (local end as GO)" },
2922 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
2923 "<addr> <method> = request provisioning discovery" },
2924 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
2926 "= get the passphrase for a group (GO only)" },
2927 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2929 "<addr> <TLVs> = schedule service discovery request" },
2930 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2932 "<id> = cancel pending service discovery request" },
2933 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp,
2935 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2936 { "p2p_service_update", wpa_cli_cmd_p2p_service_update,
2938 "= indicate change in local services" },
2939 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external,
2941 "<external> = set external processing of service discovery" },
2942 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush,
2944 "= remove all stored service entries" },
2945 { "p2p_service_add", wpa_cli_cmd_p2p_service_add,
2947 "<bonjour|upnp> <query|version> <response|service> = add a local "
2949 { "p2p_service_del", wpa_cli_cmd_p2p_service_del,
2951 "<bonjour|upnp> <query|version> [|service] = remove a local "
2953 { "p2p_reject", wpa_cli_cmd_p2p_reject,
2955 "<addr> = reject connection attempts from a specific peer" },
2956 { "p2p_invite", wpa_cli_cmd_p2p_invite,
2958 "<cmd> [peer=addr] = invite peer" },
2959 { "p2p_peers", wpa_cli_cmd_p2p_peers, cli_cmd_flag_none,
2960 "[discovered] = list known (optionally, only fully discovered) P2P "
2962 { "p2p_peer", wpa_cli_cmd_p2p_peer, cli_cmd_flag_none,
2963 "<address> = show information about known P2P peer" },
2964 { "p2p_set", wpa_cli_cmd_p2p_set, cli_cmd_flag_none,
2965 "<field> <value> = set a P2P parameter" },
2966 { "p2p_flush", wpa_cli_cmd_p2p_flush, cli_cmd_flag_none,
2967 "= flush P2P state" },
2968 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, cli_cmd_flag_none,
2969 "= cancel P2P group formation" },
2970 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize, cli_cmd_flag_none,
2971 "<address> = unauthorize a peer" },
2972 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, cli_cmd_flag_none,
2973 "[<duration> <interval>] [<duration> <interval>] = request GO "
2975 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, cli_cmd_flag_none,
2976 "[<period> <interval>] = set extended listen timing" },
2977 #endif /* CONFIG_P2P */
2979 #ifdef CONFIG_INTERWORKING
2980 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, cli_cmd_flag_none,
2981 "= fetch ANQP information for all APs" },
2982 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, cli_cmd_flag_none,
2983 "= stop fetch_anqp operation" },
2984 { "interworking_select", wpa_cli_cmd_interworking_select,
2986 "[auto] = perform Interworking network selection" },
2987 { "interworking_connect", wpa_cli_cmd_interworking_connect,
2989 "<BSSID> = connect using Interworking credentials" },
2990 { "anqp_get", wpa_cli_cmd_anqp_get, cli_cmd_flag_none,
2991 "<addr> <info id>[,<info id>]... = request ANQP information" },
2992 #endif /* CONFIG_INTERWORKING */
2993 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
2994 "<0/1> = disable/enable automatic reconnection" },
2995 { "tdls_discover", wpa_cli_cmd_tdls_discover,
2997 "<addr> = request TDLS discovery with <addr>" },
2998 { "tdls_setup", wpa_cli_cmd_tdls_setup,
3000 "<addr> = request TDLS setup with <addr>" },
3001 { "tdls_teardown", wpa_cli_cmd_tdls_teardown,
3003 "<addr> = tear down TDLS with <addr>" },
3004 { "signal_poll", wpa_cli_cmd_signal_poll,
3006 "= get signal parameters" },
3007 { "reauthenticate", wpa_cli_cmd_reauthenticate, cli_cmd_flag_none,
3008 "= trigger IEEE 802.1X/EAPOL reauthentication" },
3009 { NULL, NULL, cli_cmd_flag_none, NULL }
3014 * Prints command usage, lines are padded with the specified string.
3016 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
3021 printf("%s%s ", pad, cmd->cmd);
3022 for (n = 0; (c = cmd->usage[n]); n++) {
3031 static void print_help(void)
3034 printf("commands:\n");
3035 for (n = 0; wpa_cli_commands[n].cmd; n++)
3036 print_cmd_help(&wpa_cli_commands[n], " ");
3040 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
3042 const char *c, *delim;
3046 delim = os_strchr(cmd, ' ');
3050 len = os_strlen(cmd);
3052 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
3053 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
3054 return (wpa_cli_commands[n].flags &
3055 cli_cmd_flag_sensitive);
3061 static char ** wpa_list_cmd_list(void)
3066 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
3067 res = os_zalloc(count * sizeof(char *));
3071 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3072 res[i] = os_strdup(wpa_cli_commands[i].cmd);
3081 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
3086 if (os_strcasecmp(cmd, "bss") == 0)
3087 return wpa_cli_complete_bss(str, pos);
3089 if (os_strcasecmp(cmd, "p2p_connect") == 0)
3090 return wpa_cli_complete_p2p_connect(str, pos);
3091 if (os_strcasecmp(cmd, "p2p_peer") == 0)
3092 return wpa_cli_complete_p2p_peer(str, pos);
3093 if (os_strcasecmp(cmd, "p2p_group_remove") == 0)
3094 return wpa_cli_complete_p2p_group_remove(str, pos);
3095 #endif /* CONFIG_P2P */
3097 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3098 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
3100 printf("\r%s\n", wpa_cli_commands[i].usage);
3110 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
3116 end = os_strchr(str, ' ');
3117 if (end == NULL || str + pos < end)
3118 return wpa_list_cmd_list();
3120 cmd = os_malloc(pos + 1);
3123 os_memcpy(cmd, str, pos);
3124 cmd[end - str] = '\0';
3125 res = wpa_cli_cmd_completion(cmd, str, pos);
3131 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3133 struct wpa_cli_cmd *cmd, *match = NULL;
3138 cmd = wpa_cli_commands;
3140 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3143 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3144 /* we have an exact match */
3154 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3155 cmd = wpa_cli_commands;
3157 if (os_strncasecmp(cmd->cmd, argv[0],
3158 os_strlen(argv[0])) == 0) {
3159 printf(" %s", cmd->cmd);
3165 } else if (count == 0) {
3166 printf("Unknown command '%s'\n", argv[0]);
3169 ret = match->handler(ctrl, argc - 1, &argv[1]);
3176 static int str_match(const char *a, const char *b)
3178 return os_strncmp(a, b, os_strlen(b)) == 0;
3182 static int wpa_cli_exec(const char *program, const char *arg1,
3190 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
3191 cmd = os_malloc(len);
3194 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
3195 if (res < 0 || (size_t) res >= len) {
3199 cmd[len - 1] = '\0';
3201 if (system(cmd) < 0)
3203 #endif /* _WIN32_WCE */
3210 static void wpa_cli_action_process(const char *msg)
3213 char *copy = NULL, *id, *pos2;
3218 pos = os_strchr(pos, '>');
3225 if (str_match(pos, WPA_EVENT_CONNECTED)) {
3227 os_unsetenv("WPA_ID");
3228 os_unsetenv("WPA_ID_STR");
3229 os_unsetenv("WPA_CTRL_DIR");
3231 pos = os_strstr(pos, "[id=");
3233 copy = os_strdup(pos + 4);
3237 while (*pos2 && *pos2 != ' ')
3241 os_setenv("WPA_ID", id, 1);
3242 while (*pos2 && *pos2 != '=')
3247 while (*pos2 && *pos2 != ']')
3250 os_setenv("WPA_ID_STR", id, 1);
3254 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3256 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
3257 wpa_cli_connected = 1;
3258 wpa_cli_last_id = new_id;
3259 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
3261 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3262 if (wpa_cli_connected) {
3263 wpa_cli_connected = 0;
3264 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
3266 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3267 wpa_cli_exec(action_file, ctrl_ifname, pos);
3268 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3269 wpa_cli_exec(action_file, ctrl_ifname, pos);
3270 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3271 wpa_cli_exec(action_file, ctrl_ifname, pos);
3272 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3273 wpa_cli_exec(action_file, ctrl_ifname, pos);
3274 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3275 wpa_cli_exec(action_file, ctrl_ifname, pos);
3276 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3277 wpa_cli_exec(action_file, ctrl_ifname, pos);
3278 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3279 wpa_cli_exec(action_file, ctrl_ifname, pos);
3280 } else if (str_match(pos, AP_STA_CONNECTED)) {
3281 wpa_cli_exec(action_file, ctrl_ifname, pos);
3282 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3283 wpa_cli_exec(action_file, ctrl_ifname, pos);
3284 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3285 printf("wpa_supplicant is terminating - stop monitoring\n");
3291 #ifndef CONFIG_ANSI_C_EXTRA
3292 static void wpa_cli_action_cb(char *msg, size_t len)
3294 wpa_cli_action_process(msg);
3296 #endif /* CONFIG_ANSI_C_EXTRA */
3299 static void wpa_cli_reconnect(void)
3301 wpa_cli_close_connection();
3302 wpa_cli_open_connection(ctrl_ifname, 1);
3306 static void cli_event(const char *str)
3308 const char *start, *s;
3310 start = os_strchr(str, '>');
3316 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3317 s = os_strchr(start, ' ');
3320 s = os_strchr(s + 1, ' ');
3323 cli_txt_list_add(&bsses, s + 1);
3327 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3328 s = os_strchr(start, ' ');
3331 s = os_strchr(s + 1, ' ');
3334 cli_txt_list_del_addr(&bsses, s + 1);
3339 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3340 s = os_strstr(start, " p2p_dev_addr=");
3343 cli_txt_list_add_addr(&p2p_peers, s + 14);
3347 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3348 s = os_strstr(start, " p2p_dev_addr=");
3351 cli_txt_list_del_addr(&p2p_peers, s + 14);
3355 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3356 s = os_strchr(start, ' ');
3359 cli_txt_list_add_word(&p2p_groups, s + 1);
3363 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3364 s = os_strchr(start, ' ');
3367 cli_txt_list_del_word(&p2p_groups, s + 1);
3370 #endif /* CONFIG_P2P */
3374 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3376 if (ctrl_conn == NULL) {
3377 wpa_cli_reconnect();
3380 while (wpa_ctrl_pending(ctrl) > 0) {
3382 size_t len = sizeof(buf) - 1;
3383 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3386 wpa_cli_action_process(buf);
3389 if (wpa_cli_show_event(buf)) {
3391 printf("\r%s\n", buf);
3396 printf("Could not read pending message.\n");
3401 if (wpa_ctrl_pending(ctrl) < 0) {
3402 printf("Connection to wpa_supplicant lost - trying to "
3404 wpa_cli_reconnect();
3410 static int tokenize_cmd(char *cmd, char *argv[])
3423 if (argc == max_args)
3426 char *pos2 = os_strrchr(pos, '"');
3430 while (*pos != '\0' && *pos != ' ')
3440 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3442 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3443 printf("Connection to wpa_supplicant lost - trying to "
3445 wpa_cli_close_connection();
3448 wpa_cli_reconnect();
3449 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3453 static void wpa_cli_eloop_terminate(int sig, void *signal_ctx)
3459 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3461 wpa_cli_recv_pending(mon_conn, 0);
3465 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3467 char *argv[max_args];
3469 argc = tokenize_cmd(cmd, argv);
3471 wpa_request(ctrl_conn, argc, argv);
3475 static void wpa_cli_edit_eof_cb(void *ctx)
3481 static void wpa_cli_interactive(void)
3483 char *home, *hfile = NULL;
3485 printf("\nInteractive mode\n\n");
3487 home = getenv("HOME");
3489 const char *fname = ".wpa_cli_history";
3490 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3491 hfile = os_malloc(hfile_len);
3493 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3496 eloop_register_signal_terminate(wpa_cli_eloop_terminate, NULL);
3497 edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3498 wpa_cli_edit_completion_cb, NULL, hfile);
3499 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3503 cli_txt_list_flush(&p2p_peers);
3504 cli_txt_list_flush(&p2p_groups);
3505 cli_txt_list_flush(&bsses);
3506 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3508 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3509 wpa_cli_close_connection();
3513 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3515 #ifdef CONFIG_ANSI_C_EXTRA
3516 /* TODO: ANSI C version(?) */
3517 printf("Action processing not supported in ANSI C build.\n");
3518 #else /* CONFIG_ANSI_C_EXTRA */
3522 char buf[256]; /* note: large enough to fit in unsolicited messages */
3525 fd = wpa_ctrl_get_fd(ctrl);
3527 while (!wpa_cli_quit) {
3530 tv.tv_sec = ping_interval;
3532 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3533 if (res < 0 && errno != EINTR) {
3538 if (FD_ISSET(fd, &rfds))
3539 wpa_cli_recv_pending(ctrl, 1);
3541 /* verify that connection is still working */
3542 len = sizeof(buf) - 1;
3543 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3544 wpa_cli_action_cb) < 0 ||
3545 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3546 printf("wpa_supplicant did not reply to PING "
3547 "command - exiting\n");
3552 #endif /* CONFIG_ANSI_C_EXTRA */
3556 static void wpa_cli_cleanup(void)
3558 wpa_cli_close_connection();
3560 os_daemonize_terminate(pid_file);
3562 os_program_deinit();
3565 static void wpa_cli_terminate(int sig)
3572 static char * wpa_cli_get_default_ifname(void)
3574 char *ifname = NULL;
3576 #ifdef CONFIG_CTRL_IFACE_UNIX
3577 struct dirent *dent;
3578 DIR *dir = opendir(ctrl_iface_dir);
3581 char ifprop[PROPERTY_VALUE_MAX];
3582 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3583 ifname = os_strdup(ifprop);
3584 printf("Using interface '%s'\n", ifname);
3587 #endif /* ANDROID */
3590 while ((dent = readdir(dir))) {
3591 #ifdef _DIRENT_HAVE_D_TYPE
3593 * Skip the file if it is not a socket. Also accept
3594 * DT_UNKNOWN (0) in case the C library or underlying
3595 * file system does not support d_type.
3597 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3599 #endif /* _DIRENT_HAVE_D_TYPE */
3600 if (os_strcmp(dent->d_name, ".") == 0 ||
3601 os_strcmp(dent->d_name, "..") == 0)
3603 printf("Selected interface '%s'\n", dent->d_name);
3604 ifname = os_strdup(dent->d_name);
3608 #endif /* CONFIG_CTRL_IFACE_UNIX */
3610 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3611 char buf[2048], *pos;
3613 struct wpa_ctrl *ctrl;
3616 ctrl = wpa_ctrl_open(NULL);
3620 len = sizeof(buf) - 1;
3621 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3624 pos = os_strchr(buf, '\n');
3627 ifname = os_strdup(buf);
3629 wpa_ctrl_close(ctrl);
3630 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3636 int main(int argc, char *argv[])
3638 int warning_displayed = 0;
3642 const char *global = NULL;
3644 if (os_program_init())
3648 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3653 action_file = optarg;
3662 ping_interval = atoi(optarg);
3668 printf("%s\n", wpa_cli_version);
3671 os_free(ctrl_ifname);
3672 ctrl_ifname = os_strdup(optarg);
3675 ctrl_iface_dir = optarg;
3686 interactive = (argc == optind) && (action_file == NULL);
3689 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3695 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3696 ctrl_conn = wpa_ctrl_open(NULL);
3697 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3698 ctrl_conn = wpa_ctrl_open(global);
3699 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3700 if (ctrl_conn == NULL) {
3701 perror("Failed to connect to wpa_supplicant - "
3708 signal(SIGINT, wpa_cli_terminate);
3709 signal(SIGTERM, wpa_cli_terminate);
3710 #endif /* _WIN32_WCE */
3712 if (ctrl_ifname == NULL)
3713 ctrl_ifname = wpa_cli_get_default_ifname();
3717 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3718 if (warning_displayed)
3719 printf("Connection established.\n");
3723 if (!warning_displayed) {
3724 printf("Could not connect to wpa_supplicant - "
3726 warning_displayed = 1;
3733 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3734 perror("Failed to connect to wpa_supplicant - "
3740 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3741 wpa_cli_attached = 1;
3743 printf("Warning: Failed to attach to "
3744 "wpa_supplicant.\n");
3750 if (daemonize && os_daemonize(pid_file))
3754 wpa_cli_interactive();
3755 else if (action_file)
3756 wpa_cli_action(ctrl_conn);
3758 ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
3760 os_free(ctrl_ifname);
3767 #else /* CONFIG_CTRL_IFACE */
3768 int main(int argc, char *argv[])
3770 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3773 #endif /* CONFIG_CTRL_IFACE */