2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
11 #ifdef CONFIG_CTRL_IFACE
13 #ifdef CONFIG_CTRL_IFACE_UNIX
15 #endif /* CONFIG_CTRL_IFACE_UNIX */
17 #include "common/wpa_ctrl.h"
18 #include "utils/common.h"
19 #include "utils/eloop.h"
20 #include "utils/edit.h"
21 #include "utils/list.h"
22 #include "common/version.h"
23 #include "common/ieee802_11_defs.h"
25 #include <cutils/properties.h>
29 static const char *wpa_cli_version =
30 "wpa_cli v" VERSION_STR "\n"
31 "Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi> and contributors";
34 static const char *wpa_cli_license =
35 "This software may be distributed under the terms of the BSD license.\n"
36 "See README for more details.\n";
38 static const char *wpa_cli_full_license =
39 "This software may be distributed under the terms of the BSD license.\n"
41 "Redistribution and use in source and binary forms, with or without\n"
42 "modification, are permitted provided that the following conditions are\n"
45 "1. Redistributions of source code must retain the above copyright\n"
46 " notice, this list of conditions and the following disclaimer.\n"
48 "2. Redistributions in binary form must reproduce the above copyright\n"
49 " notice, this list of conditions and the following disclaimer in the\n"
50 " documentation and/or other materials provided with the distribution.\n"
52 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
53 " names of its contributors may be used to endorse or promote products\n"
54 " derived from this software without specific prior written permission.\n"
56 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
57 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
58 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
59 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
60 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
61 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
62 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
63 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
64 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
65 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
66 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
69 static struct wpa_ctrl *ctrl_conn;
70 static struct wpa_ctrl *mon_conn;
71 static int wpa_cli_quit = 0;
72 static int wpa_cli_attached = 0;
73 static int wpa_cli_connected = 0;
74 static int wpa_cli_last_id = 0;
75 #ifndef CONFIG_CTRL_IFACE_DIR
76 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
77 #endif /* CONFIG_CTRL_IFACE_DIR */
78 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
79 static char *ctrl_ifname = NULL;
80 static const char *pid_file = NULL;
81 static const char *action_file = NULL;
82 static int ping_interval = 5;
83 static int interactive = 0;
84 static char *ifname_prefix = NULL;
86 struct cli_txt_entry {
91 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
92 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
93 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
96 static void print_help(const char *cmd);
97 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
98 static void wpa_cli_close_connection(void);
99 static char * wpa_cli_get_default_ifname(void);
100 static char ** wpa_list_cmd_list(void);
103 static void usage(void)
105 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
106 "[-a<action file>] \\\n"
107 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
109 " -h = help (show this usage text)\n"
110 " -v = shown version information\n"
111 " -a = run in daemon mode executing the action file based on "
114 " -B = run a daemon in the background\n"
115 " default path: " CONFIG_CTRL_IFACE_DIR "\n"
116 " default interface: first interface found in socket path\n");
121 static void cli_txt_list_free(struct cli_txt_entry *e)
123 dl_list_del(&e->list);
129 static void cli_txt_list_flush(struct dl_list *list)
131 struct cli_txt_entry *e;
132 while ((e = dl_list_first(list, struct cli_txt_entry, list)))
133 cli_txt_list_free(e);
137 static struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list,
140 struct cli_txt_entry *e;
141 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
142 if (os_strcmp(e->txt, txt) == 0)
149 static void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
151 struct cli_txt_entry *e;
152 e = cli_txt_list_get(txt_list, txt);
154 cli_txt_list_free(e);
158 static void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt)
162 if (hwaddr_aton(txt, addr) < 0)
164 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
165 cli_txt_list_del(txt_list, buf);
170 static void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt)
174 end = os_strchr(txt, ' ');
176 end = txt + os_strlen(txt);
177 buf = dup_binstr(txt, end - txt);
180 cli_txt_list_del(txt_list, buf);
183 #endif /* CONFIG_P2P */
186 static int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
188 struct cli_txt_entry *e;
189 e = cli_txt_list_get(txt_list, txt);
192 e = os_zalloc(sizeof(*e));
195 e->txt = os_strdup(txt);
196 if (e->txt == NULL) {
200 dl_list_add(txt_list, &e->list);
206 static int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
210 if (hwaddr_aton(txt, addr) < 0)
212 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
213 return cli_txt_list_add(txt_list, buf);
217 static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt)
222 end = os_strchr(txt, ' ');
224 end = txt + os_strlen(txt);
225 buf = dup_binstr(txt, end - txt);
228 ret = cli_txt_list_add(txt_list, buf);
232 #endif /* CONFIG_P2P */
235 static char ** cli_txt_list_array(struct dl_list *txt_list)
237 unsigned int i, count = dl_list_len(txt_list);
239 struct cli_txt_entry *e;
241 res = os_calloc(count + 1, sizeof(char *));
246 dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
247 res[i] = os_strdup(e->txt);
257 static int get_cmd_arg_num(const char *str, int pos)
261 for (i = 0; i <= pos; i++) {
264 while (i <= pos && str[i] != ' ')
275 static int str_starts(const char *src, const char *match)
277 return os_strncmp(src, match, os_strlen(match)) == 0;
281 static int wpa_cli_show_event(const char *event)
285 start = os_strchr(event, '>');
291 * Skip BSS added/removed events since they can be relatively frequent
292 * and are likely of not much use for an interactive user.
294 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
295 str_starts(start, WPA_EVENT_BSS_REMOVED))
302 static int wpa_cli_open_connection(const char *ifname, int attach)
304 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
305 ctrl_conn = wpa_ctrl_open(ifname);
306 if (ctrl_conn == NULL)
309 if (attach && interactive)
310 mon_conn = wpa_ctrl_open(ifname);
313 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
321 if (access(ctrl_iface_dir, F_OK) < 0) {
322 cfile = os_strdup(ifname);
329 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
330 cfile = os_malloc(flen);
333 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
335 if (res < 0 || res >= flen) {
341 ctrl_conn = wpa_ctrl_open(cfile);
342 if (ctrl_conn == NULL) {
347 if (attach && interactive)
348 mon_conn = wpa_ctrl_open(cfile);
352 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
355 if (wpa_ctrl_attach(mon_conn) == 0) {
356 wpa_cli_attached = 1;
358 eloop_register_read_sock(
359 wpa_ctrl_get_fd(mon_conn),
360 wpa_cli_mon_receive, NULL, NULL);
362 printf("Warning: Failed to attach to "
363 "wpa_supplicant.\n");
364 wpa_cli_close_connection();
373 static void wpa_cli_close_connection(void)
375 if (ctrl_conn == NULL)
378 if (wpa_cli_attached) {
379 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
380 wpa_cli_attached = 0;
382 wpa_ctrl_close(ctrl_conn);
385 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
386 wpa_ctrl_close(mon_conn);
392 static void wpa_cli_msg_cb(char *msg, size_t len)
398 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
404 if (ctrl_conn == NULL) {
405 printf("Not connected to wpa_supplicant - command dropped.\n");
409 os_snprintf(buf, sizeof(buf), "IFNAME=%s %s",
411 buf[sizeof(buf) - 1] = '\0';
414 len = sizeof(buf) - 1;
415 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
418 printf("'%s' command timed out.\n", cmd);
420 } else if (ret < 0) {
421 printf("'%s' command failed.\n", cmd);
427 if (interactive && len > 0 && buf[len - 1] != '\n')
434 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
436 return _wpa_ctrl_command(ctrl, cmd, 1);
440 static int write_cmd(char *buf, size_t buflen, const char *cmd, int argc,
449 res = os_snprintf(pos, end - pos, "%s", cmd);
450 if (res < 0 || res >= end - pos)
454 for (i = 0; i < argc; i++) {
455 res = os_snprintf(pos, end - pos, " %s", argv[i]);
456 if (res < 0 || res >= end - pos)
461 buf[buflen - 1] = '\0';
465 printf("Too long command\n");
470 static int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args,
471 int argc, char *argv[])
474 if (argc < min_args) {
475 printf("Invalid %s command - at least %d argument%s "
476 "required.\n", cmd, min_args,
477 min_args > 1 ? "s are" : " is");
480 if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0)
482 return wpa_ctrl_command(ctrl, buf);
486 static int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[])
488 return wpa_ctrl_command(ctrl, "IFNAME");
492 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
494 if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
495 return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
496 if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
497 return wpa_ctrl_command(ctrl, "STATUS-WPS");
498 return wpa_ctrl_command(ctrl, "STATUS");
502 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
504 return wpa_ctrl_command(ctrl, "PING");
508 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
510 return wpa_ctrl_command(ctrl, "RELOG");
514 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
516 return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv);
520 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
522 return wpa_ctrl_command(ctrl, "MIB");
526 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
528 return wpa_ctrl_command(ctrl, "PMKSA");
532 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
534 print_help(argc > 0 ? argv[0] : NULL);
539 static char ** wpa_cli_complete_help(const char *str, int pos)
541 int arg = get_cmd_arg_num(str, pos);
546 res = wpa_list_cmd_list();
554 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
556 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
561 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
570 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
576 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
577 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
578 printf("Too long SET command.\n");
581 return wpa_ctrl_command(ctrl, cmd);
584 return wpa_cli_cmd(ctrl, "SET", 2, argc, argv);
588 static char ** wpa_cli_complete_set(const char *str, int pos)
590 int arg = get_cmd_arg_num(str, pos);
591 const char *fields[] = {
593 "EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod",
594 "EAPOL::maxStart", "dot11RSNAConfigPMKLifetime",
595 "dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout",
596 "wps_fragment_size", "wps_version_number", "ampdu",
597 "tdls_testing", "tdls_disabled", "pno", "radio_disabled",
598 "uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps",
600 /* global configuration parameters */
601 "eapol_version", "ap_scan", "disable_scan_offload",
602 "fast_reauth", "opensc_engine_path", "pkcs11_engine_path",
603 "pkcs11_module_path", "pcsc_reader", "pcsc_pin",
604 "driver_param", "dot11RSNAConfigPMKLifetime",
605 "dot11RSNAConfigPMKReauthThreshold",
606 "dot11RSNAConfigSATimeout",
607 "update_config", "load_dynamic_eap", "uuid", "device_name",
608 "manufacturer", "model_name", "model_number", "serial_number",
609 "device_type", "os_version", "config_methods",
610 "wps_cred_processing", "wps_vendor_ext_m1", "sec_device_type",
611 "p2p_listen_reg_class", "p2p_listen_channel",
612 "p2p_oper_reg_class", "p2p_oper_channel",
613 "p2p_go_intent", "p2p_ssid_postfix", "persistent_reconnect",
614 "p2p_intra_bss", "p2p_group_idle", "p2p_pref_chan",
615 "p2p_go_ht40", "p2p_disabled", "p2p_no_group_iface",
616 "p2p_ignore_shared_freq", "country", "bss_max_count",
617 "bss_expiration_age", "bss_expiration_scan_count",
618 "filter_ssids", "filter_rssi", "max_num_sta",
619 "disassoc_low_ack", "hs20", "interworking", "hessid",
620 "access_network_type", "pbc_in_m1", "autoscan",
621 "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey", "wps_nfc_dh_privkey",
622 "wps_nfc_dev_pw", "ext_password_backend",
623 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
624 "sae_groups", "dtim_period", "beacon_int", "ap_vendor_elements",
625 "ignore_old_scan_res", "freq_list"
627 int i, num_fields = sizeof(fields) / sizeof(fields[0]);
630 char **res = os_calloc(num_fields + 1, sizeof(char *));
633 for (i = 0; i < num_fields; i++) {
634 res[i] = os_strdup(fields[i]);
641 if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0)
642 return cli_txt_list_array(&bsses);
648 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
650 return wpa_cli_cmd(ctrl, "GET", 1, argc, argv);
654 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
656 return wpa_ctrl_command(ctrl, "LOGOFF");
660 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
662 return wpa_ctrl_command(ctrl, "LOGON");
666 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
669 return wpa_ctrl_command(ctrl, "REASSOCIATE");
673 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
676 return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv);
680 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
682 return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv);
686 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
689 return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv);
693 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
696 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv);
700 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
703 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv);
707 static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
713 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0");
715 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]);
716 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
717 printf("Too long BSS_FLUSH command.\n");
720 return wpa_ctrl_command(ctrl, cmd);
724 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
727 return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv);
731 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
733 return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv);
737 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
739 return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv);
743 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
746 printf("Invalid WPS_PIN command: need one or two arguments:\n"
747 "- BSSID: use 'any' to select any\n"
748 "- PIN: optional, used only with devices that have no "
753 return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv);
757 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
760 return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv);
764 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
767 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
771 #ifdef CONFIG_WPS_NFC
773 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
775 return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv);
779 static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
782 return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
786 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
789 return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv);
793 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
801 printf("Invalid 'wps_nfc_tag_read' command - one argument "
806 buflen = 18 + os_strlen(argv[0]);
807 buf = os_malloc(buflen);
810 os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
812 ret = wpa_ctrl_command(ctrl, buf);
819 static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc,
822 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv);
826 static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc,
829 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv);
833 static int wpa_cli_cmd_nfc_rx_handover_req(struct wpa_ctrl *ctrl, int argc,
841 printf("Invalid 'nfc_rx_handover_req' command - one argument "
846 buflen = 21 + os_strlen(argv[0]);
847 buf = os_malloc(buflen);
850 os_snprintf(buf, buflen, "NFC_RX_HANDOVER_REQ %s", argv[0]);
852 ret = wpa_ctrl_command(ctrl, buf);
859 static int wpa_cli_cmd_nfc_rx_handover_sel(struct wpa_ctrl *ctrl, int argc,
867 printf("Invalid 'nfc_rx_handover_sel' command - one argument "
872 buflen = 21 + os_strlen(argv[0]);
873 buf = os_malloc(buflen);
876 os_snprintf(buf, buflen, "NFC_RX_HANDOVER_SEL %s", argv[0]);
878 ret = wpa_ctrl_command(ctrl, buf);
885 static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc,
888 return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv);
891 #endif /* CONFIG_WPS_NFC */
894 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
900 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
902 else if (argc == 5 || argc == 6) {
903 char ssid_hex[2 * 32 + 1];
904 char key_hex[2 * 64 + 1];
908 for (i = 0; i < 32; i++) {
909 if (argv[2][i] == '\0')
911 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
916 for (i = 0; i < 64; i++) {
917 if (argv[5][i] == '\0')
919 os_snprintf(&key_hex[i * 2], 3, "%02x",
924 res = os_snprintf(cmd, sizeof(cmd),
925 "WPS_REG %s %s %s %s %s %s",
926 argv[0], argv[1], ssid_hex, argv[3], argv[4],
929 printf("Invalid WPS_REG command: need two arguments:\n"
930 "- BSSID of the target AP\n"
932 printf("Alternatively, six arguments can be used to "
933 "reconfigure the AP:\n"
934 "- BSSID of the target AP\n"
937 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
938 "- new encr (NONE, WEP, TKIP, CCMP)\n"
943 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
944 printf("Too long WPS_REG command.\n");
947 return wpa_ctrl_command(ctrl, cmd);
951 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
954 return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv);
958 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
961 return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv);
965 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
968 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
973 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
977 printf("Invalid WPS_ER_PIN command: need at least two "
979 "- UUID: use 'any' to select any\n"
980 "- PIN: Enrollee PIN\n"
981 "optional: - Enrollee MAC address\n");
985 return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv);
989 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
992 return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv);
996 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
1000 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
1001 "- UUID: specify which AP to use\n"
1006 return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv);
1010 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
1014 printf("Invalid WPS_ER_SET_CONFIG command: need two "
1016 "- UUID: specify which AP to use\n"
1017 "- Network configuration id\n");
1021 return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv);
1025 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
1031 if (argc == 5 || argc == 6) {
1032 char ssid_hex[2 * 32 + 1];
1033 char key_hex[2 * 64 + 1];
1037 for (i = 0; i < 32; i++) {
1038 if (argv[2][i] == '\0')
1040 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1045 for (i = 0; i < 64; i++) {
1046 if (argv[5][i] == '\0')
1048 os_snprintf(&key_hex[i * 2], 3, "%02x",
1053 res = os_snprintf(cmd, sizeof(cmd),
1054 "WPS_ER_CONFIG %s %s %s %s %s %s",
1055 argv[0], argv[1], ssid_hex, argv[3], argv[4],
1058 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1062 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1063 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1068 if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
1069 printf("Too long WPS_ER_CONFIG command.\n");
1072 return wpa_ctrl_command(ctrl, cmd);
1076 #ifdef CONFIG_WPS_NFC
1077 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
1081 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
1083 "- WPS/NDEF: token format\n"
1084 "- UUID: specify which AP to use\n");
1088 return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv);
1090 #endif /* CONFIG_WPS_NFC */
1093 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1095 return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv);
1099 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1101 return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv);
1105 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1107 char cmd[256], *pos, *end;
1111 printf("Invalid IDENTITY command: needs two arguments "
1112 "(network id and identity)\n");
1116 end = cmd + sizeof(cmd);
1118 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1120 if (ret < 0 || ret >= end - pos) {
1121 printf("Too long IDENTITY command.\n");
1125 for (i = 2; i < argc; i++) {
1126 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1127 if (ret < 0 || ret >= end - pos) {
1128 printf("Too long IDENTITY command.\n");
1134 return wpa_ctrl_command(ctrl, cmd);
1138 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1140 char cmd[256], *pos, *end;
1144 printf("Invalid PASSWORD command: needs two arguments "
1145 "(network id and password)\n");
1149 end = cmd + sizeof(cmd);
1151 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1153 if (ret < 0 || ret >= end - pos) {
1154 printf("Too long PASSWORD command.\n");
1158 for (i = 2; i < argc; i++) {
1159 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1160 if (ret < 0 || ret >= end - pos) {
1161 printf("Too long PASSWORD command.\n");
1167 return wpa_ctrl_command(ctrl, cmd);
1171 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1174 char cmd[256], *pos, *end;
1178 printf("Invalid NEW_PASSWORD command: needs two arguments "
1179 "(network id and password)\n");
1183 end = cmd + sizeof(cmd);
1185 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1187 if (ret < 0 || ret >= end - pos) {
1188 printf("Too long NEW_PASSWORD command.\n");
1192 for (i = 2; i < argc; i++) {
1193 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1194 if (ret < 0 || ret >= end - pos) {
1195 printf("Too long NEW_PASSWORD command.\n");
1201 return wpa_ctrl_command(ctrl, cmd);
1205 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1207 char cmd[256], *pos, *end;
1211 printf("Invalid PIN command: needs two arguments "
1212 "(network id and pin)\n");
1216 end = cmd + sizeof(cmd);
1218 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1220 if (ret < 0 || ret >= end - pos) {
1221 printf("Too long PIN command.\n");
1225 for (i = 2; i < argc; i++) {
1226 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1227 if (ret < 0 || ret >= end - pos) {
1228 printf("Too long PIN command.\n");
1233 return wpa_ctrl_command(ctrl, cmd);
1237 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1239 char cmd[256], *pos, *end;
1243 printf("Invalid OTP command: needs two arguments (network "
1244 "id and password)\n");
1248 end = cmd + sizeof(cmd);
1250 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1252 if (ret < 0 || ret >= end - pos) {
1253 printf("Too long OTP command.\n");
1257 for (i = 2; i < argc; i++) {
1258 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1259 if (ret < 0 || ret >= end - pos) {
1260 printf("Too long OTP command.\n");
1266 return wpa_ctrl_command(ctrl, cmd);
1270 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1273 char cmd[256], *pos, *end;
1277 printf("Invalid PASSPHRASE command: needs two arguments "
1278 "(network id and passphrase)\n");
1282 end = cmd + sizeof(cmd);
1284 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1286 if (ret < 0 || ret >= end - pos) {
1287 printf("Too long PASSPHRASE command.\n");
1291 for (i = 2; i < argc; i++) {
1292 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1293 if (ret < 0 || ret >= end - pos) {
1294 printf("Too long PASSPHRASE command.\n");
1300 return wpa_ctrl_command(ctrl, cmd);
1304 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1307 printf("Invalid BSSID command: needs two arguments (network "
1312 return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv);
1316 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1318 return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv);
1322 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1324 return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv);
1328 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1331 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1335 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1338 return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv);
1342 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1345 return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv);
1349 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1352 return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv);
1356 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1359 return wpa_ctrl_command(ctrl, "ADD_NETWORK");
1363 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1366 return wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv);
1370 static void wpa_cli_show_network_variables(void)
1372 printf("set_network variables:\n"
1373 " ssid (network name, SSID)\n"
1374 " psk (WPA passphrase or pre-shared key)\n"
1375 " key_mgmt (key management protocol)\n"
1376 " identity (EAP identity)\n"
1377 " password (EAP password)\n"
1380 "Note: Values are entered in the same format as the "
1381 "configuration file is using,\n"
1382 "i.e., strings values need to be inside double quotation "
1384 "For example: set_network 1 ssid \"network name\"\n"
1386 "Please see wpa_supplicant.conf documentation for full list "
1387 "of\navailable variables.\n");
1391 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1395 wpa_cli_show_network_variables();
1400 printf("Invalid SET_NETWORK command: needs three arguments\n"
1401 "(network id, variable name, and value)\n");
1405 return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv);
1409 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1413 wpa_cli_show_network_variables();
1418 printf("Invalid GET_NETWORK command: needs two arguments\n"
1419 "(network id and variable name)\n");
1423 return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv);
1427 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1430 return wpa_ctrl_command(ctrl, "LIST_CREDS");
1434 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1436 return wpa_ctrl_command(ctrl, "ADD_CRED");
1440 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1443 return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv);
1447 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1450 printf("Invalid SET_CRED command: needs three arguments\n"
1451 "(cred id, variable name, and value)\n");
1455 return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv);
1459 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1462 return wpa_ctrl_command(ctrl, "DISCONNECT");
1466 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1469 return wpa_ctrl_command(ctrl, "RECONNECT");
1473 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1476 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1480 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1482 return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
1486 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1489 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1493 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1495 return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
1499 static char ** wpa_cli_complete_bss(const char *str, int pos)
1501 int arg = get_cmd_arg_num(str, pos);
1506 res = cli_txt_list_array(&bsses);
1514 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1517 if (argc < 1 || argc > 2) {
1518 printf("Invalid GET_CAPABILITY command: need either one or "
1523 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1524 printf("Invalid GET_CAPABILITY command: second argument, "
1525 "if any, must be 'strict'\n");
1529 return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv);
1533 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1535 printf("Available interfaces:\n");
1536 return wpa_ctrl_command(ctrl, "INTERFACES");
1540 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1543 wpa_cli_list_interfaces(ctrl);
1547 wpa_cli_close_connection();
1548 os_free(ctrl_ifname);
1549 ctrl_ifname = os_strdup(argv[0]);
1551 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
1552 printf("Connected to interface '%s.\n", ctrl_ifname);
1554 printf("Could not connect to interface '%s' - re-trying\n",
1561 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1564 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1568 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1571 return wpa_ctrl_command(ctrl, "TERMINATE");
1575 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1582 printf("Invalid INTERFACE_ADD command: needs at least one "
1583 "argument (interface name)\n"
1584 "All arguments: ifname confname driver ctrl_interface "
1585 "driver_param bridge_name\n");
1590 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1591 * <driver_param>TAB<bridge_name>
1593 res = os_snprintf(cmd, sizeof(cmd),
1594 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
1596 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1597 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1598 argc > 5 ? argv[5] : "");
1599 if (res < 0 || (size_t) res >= sizeof(cmd))
1601 cmd[sizeof(cmd) - 1] = '\0';
1602 return wpa_ctrl_command(ctrl, cmd);
1606 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1609 return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv);
1613 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1616 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1621 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1623 return wpa_cli_cmd(ctrl, "STA", 1, argc, argv);
1627 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1628 char *addr, size_t addr_len)
1630 char buf[4096], *pos;
1634 if (ctrl_conn == NULL) {
1635 printf("Not connected to hostapd - command dropped.\n");
1638 len = sizeof(buf) - 1;
1639 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
1642 printf("'%s' command timed out.\n", cmd);
1644 } else if (ret < 0) {
1645 printf("'%s' command failed.\n", cmd);
1650 if (os_memcmp(buf, "FAIL", 4) == 0)
1655 while (*pos != '\0' && *pos != '\n')
1658 os_strlcpy(addr, buf, addr_len);
1663 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1665 char addr[32], cmd[64];
1667 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1670 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1671 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1677 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
1680 return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv);
1684 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
1687 return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv);
1689 #endif /* CONFIG_AP */
1692 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1694 return wpa_ctrl_command(ctrl, "SUSPEND");
1698 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1700 return wpa_ctrl_command(ctrl, "RESUME");
1704 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1706 return wpa_ctrl_command(ctrl, "DROP_SA");
1710 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1712 return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv);
1718 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1720 return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv);
1724 static char ** wpa_cli_complete_p2p_find(const char *str, int pos)
1727 int arg = get_cmd_arg_num(str, pos);
1729 res = os_calloc(6, sizeof(char *));
1732 res[0] = os_strdup("type=social");
1733 if (res[0] == NULL) {
1737 res[1] = os_strdup("type=progressive");
1740 res[2] = os_strdup("delay=");
1743 res[3] = os_strdup("dev_id=");
1747 res[4] = os_strdup("[timeout]");
1753 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1756 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
1760 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1763 return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv);
1767 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
1769 int arg = get_cmd_arg_num(str, pos);
1774 res = cli_txt_list_array(&p2p_peers);
1782 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1785 return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv);
1789 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1792 return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv);
1796 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
1798 int arg = get_cmd_arg_num(str, pos);
1803 res = cli_txt_list_array(&p2p_groups);
1811 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1814 return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv);
1818 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1821 if (argc != 2 && argc != 3) {
1822 printf("Invalid P2P_PROV_DISC command: needs at least "
1823 "two arguments, address and config method\n"
1824 "(display, keypad, or pbc) and an optional join\n");
1828 return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv);
1832 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1835 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
1839 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1844 if (argc != 2 && argc != 4) {
1845 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
1846 "arguments (address and TLVs) or four arguments "
1847 "(address, \"upnp\", version, search target "
1852 if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0)
1854 return wpa_ctrl_command(ctrl, cmd);
1858 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1859 int argc, char *argv[])
1861 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv);
1865 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1872 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
1873 "arguments (freq, address, dialog token, and TLVs)\n");
1877 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
1878 argv[0], argv[1], argv[2], argv[3]);
1879 if (res < 0 || (size_t) res >= sizeof(cmd))
1881 cmd[sizeof(cmd) - 1] = '\0';
1882 return wpa_ctrl_command(ctrl, cmd);
1886 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
1889 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
1893 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
1894 int argc, char *argv[])
1896 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv);
1900 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
1903 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
1907 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
1913 if (argc != 3 && argc != 4) {
1914 printf("Invalid P2P_SERVICE_ADD command: needs three or four "
1920 res = os_snprintf(cmd, sizeof(cmd),
1921 "P2P_SERVICE_ADD %s %s %s %s",
1922 argv[0], argv[1], argv[2], argv[3]);
1924 res = os_snprintf(cmd, sizeof(cmd),
1925 "P2P_SERVICE_ADD %s %s %s",
1926 argv[0], argv[1], argv[2]);
1927 if (res < 0 || (size_t) res >= sizeof(cmd))
1929 cmd[sizeof(cmd) - 1] = '\0';
1930 return wpa_ctrl_command(ctrl, cmd);
1934 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
1940 if (argc != 2 && argc != 3) {
1941 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
1947 res = os_snprintf(cmd, sizeof(cmd),
1948 "P2P_SERVICE_DEL %s %s %s",
1949 argv[0], argv[1], argv[2]);
1951 res = os_snprintf(cmd, sizeof(cmd),
1952 "P2P_SERVICE_DEL %s %s",
1954 if (res < 0 || (size_t) res >= sizeof(cmd))
1956 cmd[sizeof(cmd) - 1] = '\0';
1957 return wpa_ctrl_command(ctrl, cmd);
1961 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
1962 int argc, char *argv[])
1964 return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv);
1968 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
1969 int argc, char *argv[])
1971 return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv);
1975 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
1977 return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv);
1981 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
1983 int arg = get_cmd_arg_num(str, pos);
1988 res = cli_txt_list_array(&p2p_peers);
1996 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
1997 char *addr, size_t addr_len,
2000 char buf[4096], *pos;
2004 if (ctrl_conn == NULL)
2006 len = sizeof(buf) - 1;
2007 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2010 printf("'%s' command timed out.\n", cmd);
2012 } else if (ret < 0) {
2013 printf("'%s' command failed.\n", cmd);
2018 if (os_memcmp(buf, "FAIL", 4) == 0)
2022 while (*pos != '\0' && *pos != '\n')
2025 os_strlcpy(addr, buf, addr_len);
2026 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2027 printf("%s\n", addr);
2032 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2034 char addr[32], cmd[64];
2037 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2039 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2040 addr, sizeof(addr), discovered))
2043 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2044 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2051 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2053 return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv);
2057 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2059 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2063 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2066 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2070 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2073 return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv);
2077 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2080 if (argc != 0 && argc != 2 && argc != 4) {
2081 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2082 "(preferred duration, interval; in microsecods).\n"
2083 "Optional second pair can be used to provide "
2084 "acceptable values.\n");
2088 return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv);
2092 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2095 if (argc != 0 && argc != 2) {
2096 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2097 "(availability period, availability interval; in "
2099 "Extended Listen Timing can be cancelled with this "
2100 "command when used without parameters.\n");
2104 return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv);
2107 #endif /* CONFIG_P2P */
2109 #ifdef CONFIG_WIFI_DISPLAY
2111 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc,
2117 if (argc != 1 && argc != 2) {
2118 printf("Invalid WFD_SUBELEM_SET command: needs one or two "
2119 "arguments (subelem, hexdump)\n");
2123 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s",
2124 argv[0], argc > 1 ? argv[1] : "");
2125 if (res < 0 || (size_t) res >= sizeof(cmd))
2127 cmd[sizeof(cmd) - 1] = '\0';
2128 return wpa_ctrl_command(ctrl, cmd);
2132 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc,
2139 printf("Invalid WFD_SUBELEM_GET command: needs one "
2140 "argument (subelem)\n");
2144 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s",
2146 if (res < 0 || (size_t) res >= sizeof(cmd))
2148 cmd[sizeof(cmd) - 1] = '\0';
2149 return wpa_ctrl_command(ctrl, cmd);
2151 #endif /* CONFIG_WIFI_DISPLAY */
2154 #ifdef CONFIG_INTERWORKING
2155 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2158 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2162 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2165 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2169 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2172 return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv);
2176 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2179 return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv);
2183 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2185 return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv);
2189 static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc,
2192 return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv);
2196 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc,
2199 return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv);
2201 #endif /* CONFIG_INTERWORKING */
2206 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2209 return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv);
2213 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2219 printf("Command needs one or two arguments (dst mac addr and "
2220 "optional home realm)\n");
2224 if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST",
2228 return wpa_ctrl_command(ctrl, cmd);
2231 #endif /* CONFIG_HS20 */
2234 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2237 return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv);
2241 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2244 return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv);
2248 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2251 return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv);
2255 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2258 return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv);
2262 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2265 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2269 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
2272 return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
2276 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2279 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2283 #ifdef CONFIG_AUTOSCAN
2285 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
2288 return wpa_ctrl_command(ctrl, "AUTOSCAN ");
2290 return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv);
2293 #endif /* CONFIG_AUTOSCAN */
2298 static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[])
2300 return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv);
2304 static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
2306 return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv);
2309 #endif /* CONFIG_WNM */
2312 static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
2316 return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
2320 static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2322 return wpa_ctrl_command(ctrl, "FLUSH");
2326 enum wpa_cli_cmd_flags {
2327 cli_cmd_flag_none = 0x00,
2328 cli_cmd_flag_sensitive = 0x01
2331 struct wpa_cli_cmd {
2333 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2334 char ** (*completion)(const char *str, int pos);
2335 enum wpa_cli_cmd_flags flags;
2339 static struct wpa_cli_cmd wpa_cli_commands[] = {
2340 { "status", wpa_cli_cmd_status, NULL,
2342 "[verbose] = get current WPA/EAPOL/EAP status" },
2343 { "ifname", wpa_cli_cmd_ifname, NULL,
2345 "= get current interface name" },
2346 { "ping", wpa_cli_cmd_ping, NULL,
2348 "= pings wpa_supplicant" },
2349 { "relog", wpa_cli_cmd_relog, NULL,
2351 "= re-open log-file (allow rolling logs)" },
2352 { "note", wpa_cli_cmd_note, NULL,
2354 "<text> = add a note to wpa_supplicant debug log" },
2355 { "mib", wpa_cli_cmd_mib, NULL,
2357 "= get MIB variables (dot1x, dot11)" },
2358 { "help", wpa_cli_cmd_help, wpa_cli_complete_help,
2360 "[command] = show usage help" },
2361 { "interface", wpa_cli_cmd_interface, NULL,
2363 "[ifname] = show interfaces/select interface" },
2364 { "level", wpa_cli_cmd_level, NULL,
2366 "<debug level> = change debug level" },
2367 { "license", wpa_cli_cmd_license, NULL,
2369 "= show full wpa_cli license" },
2370 { "quit", wpa_cli_cmd_quit, NULL,
2373 { "set", wpa_cli_cmd_set, wpa_cli_complete_set,
2375 "= set variables (shows list of variables when run without "
2377 { "get", wpa_cli_cmd_get, NULL,
2379 "<name> = get information" },
2380 { "logon", wpa_cli_cmd_logon, NULL,
2382 "= IEEE 802.1X EAPOL state machine logon" },
2383 { "logoff", wpa_cli_cmd_logoff, NULL,
2385 "= IEEE 802.1X EAPOL state machine logoff" },
2386 { "pmksa", wpa_cli_cmd_pmksa, NULL,
2388 "= show PMKSA cache" },
2389 { "reassociate", wpa_cli_cmd_reassociate, NULL,
2391 "= force reassociation" },
2392 { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
2394 "<BSSID> = force preauthentication" },
2395 { "identity", wpa_cli_cmd_identity, NULL,
2397 "<network id> <identity> = configure identity for an SSID" },
2398 { "password", wpa_cli_cmd_password, NULL,
2399 cli_cmd_flag_sensitive,
2400 "<network id> <password> = configure password for an SSID" },
2401 { "new_password", wpa_cli_cmd_new_password, NULL,
2402 cli_cmd_flag_sensitive,
2403 "<network id> <password> = change password for an SSID" },
2404 { "pin", wpa_cli_cmd_pin, NULL,
2405 cli_cmd_flag_sensitive,
2406 "<network id> <pin> = configure pin for an SSID" },
2407 { "otp", wpa_cli_cmd_otp, NULL,
2408 cli_cmd_flag_sensitive,
2409 "<network id> <password> = configure one-time-password for an SSID"
2411 { "passphrase", wpa_cli_cmd_passphrase, NULL,
2412 cli_cmd_flag_sensitive,
2413 "<network id> <passphrase> = configure private key passphrase\n"
2415 { "bssid", wpa_cli_cmd_bssid, NULL,
2417 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2418 { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss,
2420 "<BSSID> = add a BSSID to the blacklist\n"
2421 "blacklist clear = clear the blacklist\n"
2422 "blacklist = display the blacklist" },
2423 { "log_level", wpa_cli_cmd_log_level, NULL,
2425 "<level> [<timestamp>] = update the log level/timestamp\n"
2426 "log_level = display the current log level and log options" },
2427 { "list_networks", wpa_cli_cmd_list_networks, NULL,
2429 "= list configured networks" },
2430 { "select_network", wpa_cli_cmd_select_network, NULL,
2432 "<network id> = select a network (disable others)" },
2433 { "enable_network", wpa_cli_cmd_enable_network, NULL,
2435 "<network id> = enable a network" },
2436 { "disable_network", wpa_cli_cmd_disable_network, NULL,
2438 "<network id> = disable a network" },
2439 { "add_network", wpa_cli_cmd_add_network, NULL,
2441 "= add a network" },
2442 { "remove_network", wpa_cli_cmd_remove_network, NULL,
2444 "<network id> = remove a network" },
2445 { "set_network", wpa_cli_cmd_set_network, NULL,
2446 cli_cmd_flag_sensitive,
2447 "<network id> <variable> <value> = set network variables (shows\n"
2448 " list of variables when run without arguments)" },
2449 { "get_network", wpa_cli_cmd_get_network, NULL,
2451 "<network id> <variable> = get network variables" },
2452 { "list_creds", wpa_cli_cmd_list_creds, NULL,
2454 "= list configured credentials" },
2455 { "add_cred", wpa_cli_cmd_add_cred, NULL,
2457 "= add a credential" },
2458 { "remove_cred", wpa_cli_cmd_remove_cred, NULL,
2460 "<cred id> = remove a credential" },
2461 { "set_cred", wpa_cli_cmd_set_cred, NULL,
2462 cli_cmd_flag_sensitive,
2463 "<cred id> <variable> <value> = set credential variables" },
2464 { "save_config", wpa_cli_cmd_save_config, NULL,
2466 "= save the current configuration" },
2467 { "disconnect", wpa_cli_cmd_disconnect, NULL,
2469 "= disconnect and wait for reassociate/reconnect command before\n"
2471 { "reconnect", wpa_cli_cmd_reconnect, NULL,
2473 "= like reassociate, but only takes effect if already disconnected"
2475 { "scan", wpa_cli_cmd_scan, NULL,
2477 "= request new BSS scan" },
2478 { "scan_results", wpa_cli_cmd_scan_results, NULL,
2480 "= get latest scan results" },
2481 { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
2483 "<<idx> | <bssid>> = get detailed scan result info" },
2484 { "get_capability", wpa_cli_cmd_get_capability, NULL,
2486 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
2487 "= get capabilies" },
2488 { "reconfigure", wpa_cli_cmd_reconfigure, NULL,
2490 "= force wpa_supplicant to re-read its configuration file" },
2491 { "terminate", wpa_cli_cmd_terminate, NULL,
2493 "= terminate wpa_supplicant" },
2494 { "interface_add", wpa_cli_cmd_interface_add, NULL,
2496 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2497 " <bridge_name> = adds new interface, all parameters but <ifname>\n"
2499 { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
2501 "<ifname> = removes the interface" },
2502 { "interface_list", wpa_cli_cmd_interface_list, NULL,
2504 "= list available interfaces" },
2505 { "ap_scan", wpa_cli_cmd_ap_scan, NULL,
2507 "<value> = set ap_scan parameter" },
2508 { "scan_interval", wpa_cli_cmd_scan_interval, NULL,
2510 "<value> = set scan_interval parameter (in seconds)" },
2511 { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
2513 "<value> = set BSS expiration age parameter" },
2514 { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
2516 "<value> = set BSS expiration scan count parameter" },
2517 { "bss_flush", wpa_cli_cmd_bss_flush, NULL,
2519 "<value> = set BSS flush age (0 by default)" },
2520 { "stkstart", wpa_cli_cmd_stkstart, NULL,
2522 "<addr> = request STK negotiation with <addr>" },
2523 { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
2525 "<addr> = request over-the-DS FT with <addr>" },
2526 { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
2528 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
2529 { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
2530 cli_cmd_flag_sensitive,
2531 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
2533 { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
2534 cli_cmd_flag_sensitive,
2535 "<PIN> = verify PIN checksum" },
2536 { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
2537 "Cancels the pending WPS operation" },
2538 #ifdef CONFIG_WPS_NFC
2539 { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
2541 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
2542 { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
2544 "<WPS|NDEF> = build configuration token" },
2545 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
2547 "<WPS|NDEF> = create password token" },
2548 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
2549 cli_cmd_flag_sensitive,
2550 "<hexdump of payload> = report read NFC tag with WPS data" },
2551 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
2553 "<NDEF> <WPS> = create NFC handover request" },
2554 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
2556 "<NDEF> <WPS> = create NFC handover select" },
2557 { "nfc_rx_handover_req", wpa_cli_cmd_nfc_rx_handover_req, NULL,
2559 "<hexdump of payload> = report received NFC handover request" },
2560 { "nfc_rx_handover_sel", wpa_cli_cmd_nfc_rx_handover_sel, NULL,
2562 "<hexdump of payload> = report received NFC handover select" },
2563 { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
2565 "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
2567 #endif /* CONFIG_WPS_NFC */
2568 { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
2569 cli_cmd_flag_sensitive,
2570 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
2571 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
2572 cli_cmd_flag_sensitive,
2573 "[params..] = enable/disable AP PIN" },
2574 { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
2576 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
2577 { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
2579 "= stop Wi-Fi Protected Setup External Registrar" },
2580 { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
2581 cli_cmd_flag_sensitive,
2582 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
2583 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
2585 "<UUID> = accept an Enrollee PBC using External Registrar" },
2586 { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
2587 cli_cmd_flag_sensitive,
2588 "<UUID> <PIN> = learn AP configuration" },
2589 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
2591 "<UUID> <network id> = set AP configuration for enrolling" },
2592 { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
2593 cli_cmd_flag_sensitive,
2594 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
2595 #ifdef CONFIG_WPS_NFC
2596 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
2598 "<WPS/NDEF> <UUID> = build NFC configuration token" },
2599 #endif /* CONFIG_WPS_NFC */
2600 { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
2602 "<addr> = request RSN authentication with <addr> in IBSS" },
2604 { "sta", wpa_cli_cmd_sta, NULL,
2606 "<addr> = get information about an associated station (AP)" },
2607 { "all_sta", wpa_cli_cmd_all_sta, NULL,
2609 "= get information about all associated stations (AP)" },
2610 { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL,
2612 "<addr> = deauthenticate a station" },
2613 { "disassociate", wpa_cli_cmd_disassociate, NULL,
2615 "<addr> = disassociate a station" },
2616 #endif /* CONFIG_AP */
2617 { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
2618 "= notification of suspend/hibernate" },
2619 { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
2620 "= notification of resume/thaw" },
2621 { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
2622 "= drop SA without deauth/disassoc (test command)" },
2623 { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
2625 "<addr> = roam to the specified BSS" },
2627 { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
2629 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
2630 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
2631 "= stop P2P Devices search" },
2632 { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
2634 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
2635 { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
2636 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
2637 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
2638 wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
2639 "<ifname> = remove P2P group interface (terminate group if GO)" },
2640 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
2641 "[ht40] = add a new P2P group (local end as GO)" },
2642 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
2643 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2644 "<addr> <method> = request provisioning discovery" },
2645 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
2647 "= get the passphrase for a group (GO only)" },
2648 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
2649 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2650 "<addr> <TLVs> = schedule service discovery request" },
2651 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
2652 NULL, cli_cmd_flag_none,
2653 "<id> = cancel pending service discovery request" },
2654 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
2656 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
2657 { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
2659 "= indicate change in local services" },
2660 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
2662 "<external> = set external processing of service discovery" },
2663 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
2665 "= remove all stored service entries" },
2666 { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
2668 "<bonjour|upnp> <query|version> <response|service> = add a local "
2670 { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
2672 "<bonjour|upnp> <query|version> [|service] = remove a local "
2674 { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
2676 "<addr> = reject connection attempts from a specific peer" },
2677 { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
2679 "<cmd> [peer=addr] = invite peer" },
2680 { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
2681 "[discovered] = list known (optionally, only fully discovered) P2P "
2683 { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
2685 "<address> = show information about known P2P peer" },
2686 { "p2p_set", wpa_cli_cmd_p2p_set, NULL, cli_cmd_flag_none,
2687 "<field> <value> = set a P2P parameter" },
2688 { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
2689 "= flush P2P state" },
2690 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
2691 "= cancel P2P group formation" },
2692 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
2693 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
2694 "<address> = unauthorize a peer" },
2695 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
2697 "[<duration> <interval>] [<duration> <interval>] = request GO "
2699 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
2701 "[<period> <interval>] = set extended listen timing" },
2702 #endif /* CONFIG_P2P */
2703 #ifdef CONFIG_WIFI_DISPLAY
2704 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
2706 "<subelem> [contents] = set Wi-Fi Display subelement" },
2707 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
2709 "<subelem> = get Wi-Fi Display subelement" },
2710 #endif /* CONFIG_WIFI_DISPLAY */
2711 #ifdef CONFIG_INTERWORKING
2712 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
2713 "= fetch ANQP information for all APs" },
2714 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
2716 "= stop fetch_anqp operation" },
2717 { "interworking_select", wpa_cli_cmd_interworking_select, NULL,
2719 "[auto] = perform Interworking network selection" },
2720 { "interworking_connect", wpa_cli_cmd_interworking_connect,
2721 wpa_cli_complete_bss, cli_cmd_flag_none,
2722 "<BSSID> = connect using Interworking credentials" },
2723 { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
2725 "<addr> <info id>[,<info id>]... = request ANQP information" },
2726 { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
2728 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
2729 { "gas_response_get", wpa_cli_cmd_gas_response_get,
2730 wpa_cli_complete_bss, cli_cmd_flag_none,
2731 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
2732 #endif /* CONFIG_INTERWORKING */
2734 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
2736 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
2738 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
2739 wpa_cli_complete_bss, cli_cmd_flag_none,
2740 "<addr> <home realm> = get HS20 nai home realm list" },
2741 #endif /* CONFIG_HS20 */
2742 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
2744 "<0/1> = disable/enable automatic reconnection" },
2745 { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
2747 "<addr> = request TDLS discovery with <addr>" },
2748 { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
2750 "<addr> = request TDLS setup with <addr>" },
2751 { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
2753 "<addr> = tear down TDLS with <addr>" },
2754 { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
2756 "= get signal parameters" },
2757 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
2759 "= get TX/RX packet counters" },
2760 { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
2762 "= trigger IEEE 802.1X/EAPOL reauthentication" },
2763 #ifdef CONFIG_AUTOSCAN
2764 { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
2765 "[params] = Set or unset (if none) autoscan parameters" },
2766 #endif /* CONFIG_AUTOSCAN */
2768 { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
2769 "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
2770 { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
2771 "<query reason> = Send BSS Transition Management Query" },
2772 #endif /* CONFIG_WNM */
2773 { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
2774 "<params..> = Sent unprocessed command" },
2775 { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
2776 "= flush wpa_supplicant state" },
2777 { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
2782 * Prints command usage, lines are padded with the specified string.
2784 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
2789 printf("%s%s ", pad, cmd->cmd);
2790 for (n = 0; (c = cmd->usage[n]); n++) {
2799 static void print_help(const char *cmd)
2802 printf("commands:\n");
2803 for (n = 0; wpa_cli_commands[n].cmd; n++) {
2804 if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd))
2805 print_cmd_help(&wpa_cli_commands[n], " ");
2810 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
2812 const char *c, *delim;
2816 delim = os_strchr(cmd, ' ');
2820 len = os_strlen(cmd);
2822 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
2823 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
2824 return (wpa_cli_commands[n].flags &
2825 cli_cmd_flag_sensitive);
2831 static char ** wpa_list_cmd_list(void)
2836 count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
2837 res = os_calloc(count, sizeof(char *));
2841 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2842 res[i] = os_strdup(wpa_cli_commands[i].cmd);
2851 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
2856 for (i = 0; wpa_cli_commands[i].cmd; i++) {
2857 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
2858 if (wpa_cli_commands[i].completion)
2859 return wpa_cli_commands[i].completion(str,
2862 printf("\r%s\n", wpa_cli_commands[i].usage);
2872 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
2878 end = os_strchr(str, ' ');
2879 if (end == NULL || str + pos < end)
2880 return wpa_list_cmd_list();
2882 cmd = os_malloc(pos + 1);
2885 os_memcpy(cmd, str, pos);
2886 cmd[end - str] = '\0';
2887 res = wpa_cli_cmd_completion(cmd, str, pos);
2893 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
2895 struct wpa_cli_cmd *cmd, *match = NULL;
2899 if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) {
2900 ifname_prefix = argv[0] + 7;
2904 ifname_prefix = NULL;
2910 cmd = wpa_cli_commands;
2912 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
2915 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
2916 /* we have an exact match */
2926 printf("Ambiguous command '%s'; possible commands:", argv[0]);
2927 cmd = wpa_cli_commands;
2929 if (os_strncasecmp(cmd->cmd, argv[0],
2930 os_strlen(argv[0])) == 0) {
2931 printf(" %s", cmd->cmd);
2937 } else if (count == 0) {
2938 printf("Unknown command '%s'\n", argv[0]);
2941 ret = match->handler(ctrl, argc - 1, &argv[1]);
2948 static int str_match(const char *a, const char *b)
2950 return os_strncmp(a, b, os_strlen(b)) == 0;
2954 static int wpa_cli_exec(const char *program, const char *arg1,
2962 len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
2963 cmd = os_malloc(len);
2966 res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
2967 if (res < 0 || (size_t) res >= len) {
2971 cmd[len - 1] = '\0';
2973 if (system(cmd) < 0)
2975 #endif /* _WIN32_WCE */
2982 static void wpa_cli_action_process(const char *msg)
2985 char *copy = NULL, *id, *pos2;
2990 pos = os_strchr(pos, '>');
2997 if (str_match(pos, WPA_EVENT_CONNECTED)) {
2999 os_unsetenv("WPA_ID");
3000 os_unsetenv("WPA_ID_STR");
3001 os_unsetenv("WPA_CTRL_DIR");
3003 pos = os_strstr(pos, "[id=");
3005 copy = os_strdup(pos + 4);
3009 while (*pos2 && *pos2 != ' ')
3013 os_setenv("WPA_ID", id, 1);
3014 while (*pos2 && *pos2 != '=')
3019 while (*pos2 && *pos2 != ']')
3022 os_setenv("WPA_ID_STR", id, 1);
3026 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3028 if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
3029 wpa_cli_connected = 1;
3030 wpa_cli_last_id = new_id;
3031 wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
3033 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3034 if (wpa_cli_connected) {
3035 wpa_cli_connected = 0;
3036 wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
3038 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3039 wpa_cli_exec(action_file, ctrl_ifname, pos);
3040 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3041 wpa_cli_exec(action_file, ctrl_ifname, pos);
3042 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3043 wpa_cli_exec(action_file, ctrl_ifname, pos);
3044 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3045 wpa_cli_exec(action_file, ctrl_ifname, pos);
3046 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3047 wpa_cli_exec(action_file, ctrl_ifname, pos);
3048 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3049 wpa_cli_exec(action_file, ctrl_ifname, pos);
3050 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3051 wpa_cli_exec(action_file, ctrl_ifname, pos);
3052 } else if (str_match(pos, AP_STA_CONNECTED)) {
3053 wpa_cli_exec(action_file, ctrl_ifname, pos);
3054 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3055 wpa_cli_exec(action_file, ctrl_ifname, pos);
3056 } else if (str_match(pos, ESS_DISASSOC_IMMINENT)) {
3057 wpa_cli_exec(action_file, ctrl_ifname, pos);
3058 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3059 printf("wpa_supplicant is terminating - stop monitoring\n");
3065 #ifndef CONFIG_ANSI_C_EXTRA
3066 static void wpa_cli_action_cb(char *msg, size_t len)
3068 wpa_cli_action_process(msg);
3070 #endif /* CONFIG_ANSI_C_EXTRA */
3073 static void wpa_cli_reconnect(void)
3075 wpa_cli_close_connection();
3076 if (wpa_cli_open_connection(ctrl_ifname, 1) < 0)
3081 printf("\rConnection to wpa_supplicant re-established\n");
3087 static void cli_event(const char *str)
3089 const char *start, *s;
3091 start = os_strchr(str, '>');
3097 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3098 s = os_strchr(start, ' ');
3101 s = os_strchr(s + 1, ' ');
3104 cli_txt_list_add(&bsses, s + 1);
3108 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3109 s = os_strchr(start, ' ');
3112 s = os_strchr(s + 1, ' ');
3115 cli_txt_list_del_addr(&bsses, s + 1);
3120 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3121 s = os_strstr(start, " p2p_dev_addr=");
3124 cli_txt_list_add_addr(&p2p_peers, s + 14);
3128 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3129 s = os_strstr(start, " p2p_dev_addr=");
3132 cli_txt_list_del_addr(&p2p_peers, s + 14);
3136 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3137 s = os_strchr(start, ' ');
3140 cli_txt_list_add_word(&p2p_groups, s + 1);
3144 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3145 s = os_strchr(start, ' ');
3148 cli_txt_list_del_word(&p2p_groups, s + 1);
3151 #endif /* CONFIG_P2P */
3155 static int check_terminating(const char *msg)
3157 const char *pos = msg;
3161 pos = os_strchr(pos, '>');
3168 if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
3170 printf("\rConnection to wpa_supplicant lost - trying to "
3173 wpa_cli_attached = 0;
3174 wpa_cli_close_connection();
3182 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3184 if (ctrl_conn == NULL) {
3185 wpa_cli_reconnect();
3188 while (wpa_ctrl_pending(ctrl) > 0) {
3190 size_t len = sizeof(buf) - 1;
3191 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3194 wpa_cli_action_process(buf);
3197 if (wpa_cli_show_event(buf)) {
3199 printf("\r%s\n", buf);
3203 if (interactive && check_terminating(buf) > 0)
3207 printf("Could not read pending message.\n");
3212 if (wpa_ctrl_pending(ctrl) < 0) {
3213 printf("Connection to wpa_supplicant lost - trying to "
3215 wpa_cli_reconnect();
3221 static int tokenize_cmd(char *cmd, char *argv[])
3234 if (argc == max_args)
3237 char *pos2 = os_strrchr(pos, '"');
3241 while (*pos != '\0' && *pos != ' ')
3251 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3253 if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
3254 printf("Connection to wpa_supplicant lost - trying to "
3256 wpa_cli_close_connection();
3259 wpa_cli_reconnect();
3260 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3264 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3266 wpa_cli_recv_pending(mon_conn, 0);
3270 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3272 char *argv[max_args];
3274 argc = tokenize_cmd(cmd, argv);
3276 wpa_request(ctrl_conn, argc, argv);
3280 static void wpa_cli_edit_eof_cb(void *ctx)
3286 static int warning_displayed = 0;
3287 static char *hfile = NULL;
3288 static int edit_started = 0;
3290 static void start_edit(void)
3295 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3296 ps = wpa_ctrl_get_remote_ifname(ctrl_conn);
3297 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3299 home = getenv("HOME");
3301 const char *fname = ".wpa_cli_history";
3302 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
3303 hfile = os_malloc(hfile_len);
3305 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
3308 if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
3309 wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
3315 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3319 static void update_bssid_list(struct wpa_ctrl *ctrl)
3322 size_t len = sizeof(buf);
3324 char *cmd = "BSS RANGE=ALL MASK=0x2";
3329 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
3336 pos = os_strstr(pos, "bssid=");
3340 end = os_strchr(pos, '\n');
3344 cli_txt_list_add(&bsses, pos);
3350 static void try_connection(void *eloop_ctx, void *timeout_ctx)
3355 if (ctrl_ifname == NULL)
3356 ctrl_ifname = wpa_cli_get_default_ifname();
3358 if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
3359 if (!warning_displayed) {
3360 printf("Could not connect to wpa_supplicant: "
3361 "%s - re-trying\n", ctrl_ifname);
3362 warning_displayed = 1;
3364 eloop_register_timeout(1, 0, try_connection, NULL, NULL);
3368 update_bssid_list(ctrl_conn);
3370 if (warning_displayed)
3371 printf("Connection established.\n");
3378 static void wpa_cli_interactive(void)
3380 printf("\nInteractive mode\n\n");
3382 eloop_register_timeout(0, 0, try_connection, NULL, NULL);
3384 eloop_cancel_timeout(try_connection, NULL, NULL);
3386 cli_txt_list_flush(&p2p_peers);
3387 cli_txt_list_flush(&p2p_groups);
3388 cli_txt_list_flush(&bsses);
3390 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
3392 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
3393 wpa_cli_close_connection();
3397 static void wpa_cli_action(struct wpa_ctrl *ctrl)
3399 #ifdef CONFIG_ANSI_C_EXTRA
3400 /* TODO: ANSI C version(?) */
3401 printf("Action processing not supported in ANSI C build.\n");
3402 #else /* CONFIG_ANSI_C_EXTRA */
3406 char buf[256]; /* note: large enough to fit in unsolicited messages */
3409 fd = wpa_ctrl_get_fd(ctrl);
3411 while (!wpa_cli_quit) {
3414 tv.tv_sec = ping_interval;
3416 res = select(fd + 1, &rfds, NULL, NULL, &tv);
3417 if (res < 0 && errno != EINTR) {
3422 if (FD_ISSET(fd, &rfds))
3423 wpa_cli_recv_pending(ctrl, 1);
3425 /* verify that connection is still working */
3426 len = sizeof(buf) - 1;
3427 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
3428 wpa_cli_action_cb) < 0 ||
3429 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
3430 printf("wpa_supplicant did not reply to PING "
3431 "command - exiting\n");
3436 #endif /* CONFIG_ANSI_C_EXTRA */
3440 static void wpa_cli_cleanup(void)
3442 wpa_cli_close_connection();
3444 os_daemonize_terminate(pid_file);
3446 os_program_deinit();
3450 static void wpa_cli_terminate(int sig, void *ctx)
3456 static char * wpa_cli_get_default_ifname(void)
3458 char *ifname = NULL;
3460 #ifdef CONFIG_CTRL_IFACE_UNIX
3461 struct dirent *dent;
3462 DIR *dir = opendir(ctrl_iface_dir);
3465 char ifprop[PROPERTY_VALUE_MAX];
3466 if (property_get("wifi.interface", ifprop, NULL) != 0) {
3467 ifname = os_strdup(ifprop);
3468 printf("Using interface '%s'\n", ifname);
3471 #endif /* ANDROID */
3474 while ((dent = readdir(dir))) {
3475 #ifdef _DIRENT_HAVE_D_TYPE
3477 * Skip the file if it is not a socket. Also accept
3478 * DT_UNKNOWN (0) in case the C library or underlying
3479 * file system does not support d_type.
3481 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
3483 #endif /* _DIRENT_HAVE_D_TYPE */
3484 if (os_strcmp(dent->d_name, ".") == 0 ||
3485 os_strcmp(dent->d_name, "..") == 0)
3487 printf("Selected interface '%s'\n", dent->d_name);
3488 ifname = os_strdup(dent->d_name);
3492 #endif /* CONFIG_CTRL_IFACE_UNIX */
3494 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3495 char buf[4096], *pos;
3497 struct wpa_ctrl *ctrl;
3500 ctrl = wpa_ctrl_open(NULL);
3504 len = sizeof(buf) - 1;
3505 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
3508 pos = os_strchr(buf, '\n');
3511 ifname = os_strdup(buf);
3513 wpa_ctrl_close(ctrl);
3514 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3520 int main(int argc, char *argv[])
3525 const char *global = NULL;
3527 if (os_program_init())
3531 c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
3536 action_file = optarg;
3545 ping_interval = atoi(optarg);
3551 printf("%s\n", wpa_cli_version);
3554 os_free(ctrl_ifname);
3555 ctrl_ifname = os_strdup(optarg);
3558 ctrl_iface_dir = optarg;
3569 interactive = (argc == optind) && (action_file == NULL);
3572 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
3578 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
3579 ctrl_conn = wpa_ctrl_open(NULL);
3580 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3581 ctrl_conn = wpa_ctrl_open(global);
3582 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
3583 if (ctrl_conn == NULL) {
3584 fprintf(stderr, "Failed to connect to wpa_supplicant "
3585 "global interface: %s error: %s\n",
3586 global, strerror(errno));
3591 mon_conn = wpa_ctrl_open(global);
3593 if (wpa_ctrl_attach(mon_conn) == 0) {
3594 wpa_cli_attached = 1;
3595 eloop_register_read_sock(
3596 wpa_ctrl_get_fd(mon_conn),
3597 wpa_cli_mon_receive,
3600 printf("Failed to open monitor "
3601 "connection through global "
3602 "control interface\n");
3608 eloop_register_signal_terminate(wpa_cli_terminate, NULL);
3610 if (ctrl_ifname == NULL)
3611 ctrl_ifname = wpa_cli_get_default_ifname();
3614 wpa_cli_interactive();
3617 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
3618 fprintf(stderr, "Failed to connect to non-global "
3619 "ctrl_ifname: %s error: %s\n",
3620 ctrl_ifname, strerror(errno));
3625 if (wpa_ctrl_attach(ctrl_conn) == 0) {
3626 wpa_cli_attached = 1;
3628 printf("Warning: Failed to attach to "
3629 "wpa_supplicant.\n");
3634 if (daemonize && os_daemonize(pid_file))
3638 wpa_cli_action(ctrl_conn);
3640 ret = wpa_request(ctrl_conn, argc - optind,
3644 os_free(ctrl_ifname);
3651 #else /* CONFIG_CTRL_IFACE */
3652 int main(int argc, char *argv[])
3654 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
3657 #endif /* CONFIG_CTRL_IFACE */