2 * WPA Supplicant - command line interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2016, 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/cli.h"
18 #include "common/wpa_ctrl.h"
19 #include "utils/common.h"
20 #include "utils/eloop.h"
21 #include "utils/edit.h"
22 #include "utils/list.h"
23 #include "common/version.h"
24 #include "common/ieee802_11_defs.h"
26 #include <cutils/properties.h>
30 static const char *const wpa_cli_version =
31 "wpa_cli v" VERSION_STR "\n"
32 "Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi> and contributors";
35 static const char *const wpa_cli_license =
36 "This software may be distributed under the terms of the BSD license.\n"
37 "See README for more details.\n";
39 static const char *const wpa_cli_full_license =
40 "This software may be distributed under the terms of the BSD license.\n"
42 "Redistribution and use in source and binary forms, with or without\n"
43 "modification, are permitted provided that the following conditions are\n"
46 "1. Redistributions of source code must retain the above copyright\n"
47 " notice, this list of conditions and the following disclaimer.\n"
49 "2. Redistributions in binary form must reproduce the above copyright\n"
50 " notice, this list of conditions and the following disclaimer in the\n"
51 " documentation and/or other materials provided with the distribution.\n"
53 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
54 " names of its contributors may be used to endorse or promote products\n"
55 " derived from this software without specific prior written permission.\n"
57 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
58 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
59 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
60 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
61 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
62 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
63 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
64 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
65 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
66 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
67 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
70 #define VENDOR_ELEM_FRAME_ID \
71 " 0: Probe Req (P2P), 1: Probe Resp (P2P) , 2: Probe Resp (GO), " \
72 "3: Beacon (GO), 4: PD Req, 5: PD Resp, 6: GO Neg Req, " \
73 "7: GO Neg Resp, 8: GO Neg Conf, 9: Inv Req, 10: Inv Resp, " \
74 "11: Assoc Req (P2P), 12: Assoc Resp (P2P)"
76 static struct wpa_ctrl *ctrl_conn;
77 static struct wpa_ctrl *mon_conn;
78 static int wpa_cli_quit = 0;
79 static int wpa_cli_attached = 0;
80 static int wpa_cli_connected = -1;
81 static int wpa_cli_last_id = 0;
82 #ifndef CONFIG_CTRL_IFACE_DIR
83 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
84 #endif /* CONFIG_CTRL_IFACE_DIR */
85 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
86 static const char *client_socket_dir = NULL;
87 static char *ctrl_ifname = NULL;
88 static const char *pid_file = NULL;
89 static const char *action_file = NULL;
90 static int ping_interval = 5;
91 static int interactive = 0;
92 static char *ifname_prefix = NULL;
94 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
95 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
96 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
97 static DEFINE_DL_LIST(ifnames); /* struct cli_txt_entry */
98 static DEFINE_DL_LIST(networks); /* struct cli_txt_entry */
101 static void print_help(const char *cmd);
102 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
103 static void wpa_cli_close_connection(void);
104 static char * wpa_cli_get_default_ifname(void);
105 static char ** wpa_list_cmd_list(void);
106 static void update_networks(struct wpa_ctrl *ctrl);
109 static void usage(void)
111 printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
112 "[-a<action file>] \\\n"
113 " [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
115 " [-s<wpa_client_socket_file_path>] "
117 " -h = help (show this usage text)\n"
118 " -v = shown version information\n"
119 " -a = run in daemon mode executing the action file based on "
122 " -B = run a daemon in the background\n"
123 " default path: " CONFIG_CTRL_IFACE_DIR "\n"
124 " default interface: first interface found in socket path\n");
129 static int get_cmd_arg_num(const char *str, int pos)
133 for (i = 0; i <= pos; i++) {
136 while (i <= pos && str[i] != ' ')
147 static int str_starts(const char *src, const char *match)
149 return os_strncmp(src, match, os_strlen(match)) == 0;
153 static int wpa_cli_show_event(const char *event)
157 start = os_strchr(event, '>');
163 * Skip BSS added/removed events since they can be relatively frequent
164 * and are likely of not much use for an interactive user.
166 if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
167 str_starts(start, WPA_EVENT_BSS_REMOVED))
174 static int wpa_cli_open_connection(const char *ifname, int attach)
176 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
177 ctrl_conn = wpa_ctrl_open(ifname);
178 if (ctrl_conn == NULL)
181 if (attach && interactive)
182 mon_conn = wpa_ctrl_open(ifname);
185 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
193 if (access(ctrl_iface_dir, F_OK) < 0) {
194 cfile = os_strdup(ifname);
200 if (client_socket_dir && client_socket_dir[0] &&
201 access(client_socket_dir, F_OK) < 0) {
202 perror(client_socket_dir);
208 flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
209 cfile = os_malloc(flen);
212 res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
214 if (os_snprintf_error(flen, res)) {
220 ctrl_conn = wpa_ctrl_open2(cfile, client_socket_dir);
221 if (ctrl_conn == NULL) {
226 if (attach && interactive)
227 mon_conn = wpa_ctrl_open2(cfile, client_socket_dir);
231 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
234 if (wpa_ctrl_attach(mon_conn) == 0) {
235 wpa_cli_attached = 1;
237 eloop_register_read_sock(
238 wpa_ctrl_get_fd(mon_conn),
239 wpa_cli_mon_receive, NULL, NULL);
241 printf("Warning: Failed to attach to "
242 "wpa_supplicant.\n");
243 wpa_cli_close_connection();
252 static void wpa_cli_close_connection(void)
254 if (ctrl_conn == NULL)
257 if (wpa_cli_attached) {
258 wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
259 wpa_cli_attached = 0;
261 wpa_ctrl_close(ctrl_conn);
264 eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
265 wpa_ctrl_close(mon_conn);
271 static void wpa_cli_msg_cb(char *msg, size_t len)
277 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
283 if (ctrl_conn == NULL) {
284 printf("Not connected to wpa_supplicant - command dropped.\n");
288 os_snprintf(buf, sizeof(buf), "IFNAME=%s %s",
290 buf[sizeof(buf) - 1] = '\0';
293 len = sizeof(buf) - 1;
294 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
297 printf("'%s' command timed out.\n", cmd);
299 } else if (ret < 0) {
300 printf("'%s' command failed.\n", cmd);
306 if (interactive && len > 0 && buf[len - 1] != '\n')
313 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
315 return _wpa_ctrl_command(ctrl, cmd, 1);
319 static int write_cmd(char *buf, size_t buflen, const char *cmd, int argc,
328 res = os_snprintf(pos, end - pos, "%s", cmd);
329 if (os_snprintf_error(end - pos, res))
333 for (i = 0; i < argc; i++) {
334 res = os_snprintf(pos, end - pos, " %s", argv[i]);
335 if (os_snprintf_error(end - pos, res))
340 buf[buflen - 1] = '\0';
344 printf("Too long command\n");
349 static int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args,
350 int argc, char *argv[])
353 if (argc < min_args) {
354 printf("Invalid %s command - at least %d argument%s "
355 "required.\n", cmd, min_args,
356 min_args > 1 ? "s are" : " is");
359 if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0)
361 return wpa_ctrl_command(ctrl, buf);
365 static int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[])
367 return wpa_ctrl_command(ctrl, "IFNAME");
371 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
373 if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
374 return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
375 if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
376 return wpa_ctrl_command(ctrl, "STATUS-WPS");
377 if (argc > 0 && os_strcmp(argv[0], "driver") == 0)
378 return wpa_ctrl_command(ctrl, "STATUS-DRIVER");
380 if (argc > 0 && os_strcmp(argv[0], "no_events") == 0)
381 return wpa_ctrl_command(ctrl, "STATUS-NO_EVENTS");
383 return wpa_ctrl_command(ctrl, "STATUS");
387 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
389 return wpa_ctrl_command(ctrl, "PING");
393 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
395 return wpa_ctrl_command(ctrl, "RELOG");
399 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
401 return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv);
405 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
407 return wpa_ctrl_command(ctrl, "MIB");
411 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
413 return wpa_ctrl_command(ctrl, "PMKSA");
417 static int wpa_cli_cmd_pmksa_flush(struct wpa_ctrl *ctrl, int argc,
420 return wpa_ctrl_command(ctrl, "PMKSA_FLUSH");
424 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
426 print_help(argc > 0 ? argv[0] : NULL);
431 static char ** wpa_cli_complete_help(const char *str, int pos)
433 int arg = get_cmd_arg_num(str, pos);
438 res = wpa_list_cmd_list();
446 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
448 printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
453 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
462 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
468 res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
469 if (os_snprintf_error(sizeof(cmd), res)) {
470 printf("Too long SET command.\n");
473 return wpa_ctrl_command(ctrl, cmd);
476 return wpa_cli_cmd(ctrl, "SET", 2, argc, argv);
480 static char ** wpa_cli_complete_set(const char *str, int pos)
482 int arg = get_cmd_arg_num(str, pos);
483 const char *fields[] = {
485 "EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod",
486 "EAPOL::maxStart", "dot11RSNAConfigPMKLifetime",
487 "dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout",
488 "wps_fragment_size", "wps_version_number", "ampdu",
489 "tdls_testing", "tdls_disabled", "pno", "radio_disabled",
490 "uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps",
492 /* global configuration parameters */
493 #ifdef CONFIG_CTRL_IFACE
494 "ctrl_interface", "no_ctrl_interface", "ctrl_interface_group",
495 #endif /* CONFIG_CTRL_IFACE */
496 "eapol_version", "ap_scan", "bgscan",
498 "user_mpm", "max_peer_links", "mesh_max_inactivity",
499 "dot11RSNASAERetransPeriod",
500 #endif /* CONFIG_MESH */
501 "disable_scan_offload", "fast_reauth", "opensc_engine_path",
502 "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
503 "pcsc_reader", "pcsc_pin", "external_sim", "driver_param",
504 "dot11RSNAConfigPMKLifetime",
505 "dot11RSNAConfigPMKReauthThreshold",
506 "dot11RSNAConfigSATimeout",
507 #ifndef CONFIG_NO_CONFIG_WRITE
509 #endif /* CONFIG_NO_CONFIG_WRITE */
512 "uuid", "device_name", "manufacturer", "model_name",
513 "model_number", "serial_number", "device_type", "os_version",
514 "config_methods", "wps_cred_processing", "wps_vendor_ext_m1",
515 #endif /* CONFIG_WPS */
518 "p2p_listen_reg_class", "p2p_listen_channel",
519 "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent",
520 "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss",
521 "p2p_group_idle", "p2p_passphrase_len", "p2p_pref_chan",
522 "p2p_no_go_freq", "p2p_add_cli_chan",
523 "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht",
524 "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface",
525 "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask",
526 "ip_addr_start", "ip_addr_end",
527 #endif /* CONFIG_P2P */
528 "country", "bss_max_count", "bss_expiration_age",
529 "bss_expiration_scan_count", "filter_ssids", "filter_rssi",
530 "max_num_sta", "disassoc_low_ack",
533 #endif /* CONFIG_HS20 */
534 "interworking", "hessid", "access_network_type", "pbc_in_m1",
535 "autoscan", "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey",
536 "wps_nfc_dh_privkey", "wps_nfc_dev_pw", "ext_password_backend",
537 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
538 "sae_groups", "dtim_period", "beacon_int",
539 "ap_vendor_elements", "ignore_old_scan_res", "freq_list",
540 "scan_cur_freq", "sched_scan_interval",
541 "tdls_external_control", "osu_dir", "wowlan_triggers",
542 "p2p_search_delay", "mac_addr", "rand_addr_lifetime",
543 "preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
544 "reassoc_same_bss_optim", "wps_priority"
546 int i, num_fields = ARRAY_SIZE(fields);
549 char **res = os_calloc(num_fields + 1, sizeof(char *));
552 for (i = 0; i < num_fields; i++) {
553 res[i] = os_strdup(fields[i]);
560 if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0)
561 return cli_txt_list_array(&bsses);
566 static int wpa_cli_cmd_dump(struct wpa_ctrl *ctrl, int argc, char *argv[])
568 return wpa_ctrl_command(ctrl, "DUMP");
572 static int wpa_cli_cmd_driver_flags(struct wpa_ctrl *ctrl, int argc,
575 return wpa_ctrl_command(ctrl, "DRIVER_FLAGS");
579 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
581 return wpa_cli_cmd(ctrl, "GET", 1, argc, argv);
585 static char ** wpa_cli_complete_get(const char *str, int pos)
587 int arg = get_cmd_arg_num(str, pos);
588 const char *fields[] = {
589 #ifdef CONFIG_CTRL_IFACE
590 "ctrl_interface", "ctrl_interface_group",
591 #endif /* CONFIG_CTRL_IFACE */
592 "eapol_version", "ap_scan",
594 "user_mpm", "max_peer_links", "mesh_max_inactivity",
595 #endif /* CONFIG_MESH */
596 "disable_scan_offload", "fast_reauth", "opensc_engine_path",
597 "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
598 "pcsc_reader", "pcsc_pin", "external_sim", "driver_param",
599 "dot11RSNAConfigPMKLifetime",
600 "dot11RSNAConfigPMKReauthThreshold",
601 "dot11RSNAConfigSATimeout",
602 #ifndef CONFIG_NO_CONFIG_WRITE
604 #endif /* CONFIG_NO_CONFIG_WRITE */
606 "device_name", "manufacturer", "model_name", "model_number",
607 "serial_number", "config_methods", "wps_cred_processing",
608 #endif /* CONFIG_WPS */
610 "p2p_listen_reg_class", "p2p_listen_channel",
611 "p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent",
612 "p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss",
613 "p2p_group_idle", "p2p_passphrase_len", "p2p_add_cli_chan",
614 "p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht",
615 "p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface",
616 "p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask",
617 "ip_addr_start", "ip_addr_end",
618 #endif /* CONFIG_P2P */
619 "bss_max_count", "bss_expiration_age",
620 "bss_expiration_scan_count", "filter_ssids", "filter_rssi",
621 "max_num_sta", "disassoc_low_ack",
624 #endif /* CONFIG_HS20 */
625 "interworking", "access_network_type", "pbc_in_m1", "autoscan",
626 "wps_nfc_dev_pw_id", "ext_password_backend",
627 "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
628 "dtim_period", "beacon_int", "ignore_old_scan_res",
629 "scan_cur_freq", "sched_scan_interval",
630 "tdls_external_control", "osu_dir", "wowlan_triggers",
631 "p2p_search_delay", "mac_addr", "rand_addr_lifetime",
632 "preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
633 "reassoc_same_bss_optim"
635 int i, num_fields = ARRAY_SIZE(fields);
638 char **res = os_calloc(num_fields + 1, sizeof(char *));
641 for (i = 0; i < num_fields; i++) {
642 res[i] = os_strdup(fields[i]);
653 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
655 return wpa_ctrl_command(ctrl, "LOGOFF");
659 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
661 return wpa_ctrl_command(ctrl, "LOGON");
665 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
668 return wpa_ctrl_command(ctrl, "REASSOCIATE");
672 static int wpa_cli_cmd_reattach(struct wpa_ctrl *ctrl, int argc, char *argv[])
674 return wpa_ctrl_command(ctrl, "REATTACH");
678 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
681 return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv);
685 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
687 return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv);
691 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
694 return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv);
698 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
701 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv);
705 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
708 return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv);
712 static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
718 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0");
720 res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]);
721 if (os_snprintf_error(sizeof(cmd), res)) {
722 printf("Too long BSS_FLUSH command.\n");
725 return wpa_ctrl_command(ctrl, cmd);
729 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
732 return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv);
736 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
738 return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv);
742 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
744 return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv);
748 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
751 printf("Invalid WPS_PIN command: need one or two arguments:\n"
752 "- BSSID: use 'any' to select any\n"
753 "- PIN: optional, used only with devices that have no "
758 return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv);
762 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
765 return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv);
769 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
772 return wpa_ctrl_command(ctrl, "WPS_CANCEL");
776 #ifdef CONFIG_WPS_NFC
778 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
780 return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv);
784 static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
787 return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
791 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
794 return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv);
798 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
806 printf("Invalid 'wps_nfc_tag_read' command - one argument "
811 buflen = 18 + os_strlen(argv[0]);
812 buf = os_malloc(buflen);
815 os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
817 ret = wpa_ctrl_command(ctrl, buf);
824 static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc,
827 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv);
831 static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc,
834 return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv);
838 static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc,
841 return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv);
844 #endif /* CONFIG_WPS_NFC */
847 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
853 res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
855 else if (argc == 5 || argc == 6) {
856 char ssid_hex[2 * SSID_MAX_LEN + 1];
857 char key_hex[2 * 64 + 1];
861 for (i = 0; i < SSID_MAX_LEN; i++) {
862 if (argv[2][i] == '\0')
864 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
869 for (i = 0; i < 64; i++) {
870 if (argv[5][i] == '\0')
872 os_snprintf(&key_hex[i * 2], 3, "%02x",
877 res = os_snprintf(cmd, sizeof(cmd),
878 "WPS_REG %s %s %s %s %s %s",
879 argv[0], argv[1], ssid_hex, argv[3], argv[4],
882 printf("Invalid WPS_REG command: need two arguments:\n"
883 "- BSSID of the target AP\n"
885 printf("Alternatively, six arguments can be used to "
886 "reconfigure the AP:\n"
887 "- BSSID of the target AP\n"
890 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
891 "- new encr (NONE, WEP, TKIP, CCMP)\n"
896 if (os_snprintf_error(sizeof(cmd), res)) {
897 printf("Too long WPS_REG command.\n");
900 return wpa_ctrl_command(ctrl, cmd);
904 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
907 return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv);
911 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
914 return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv);
918 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
921 return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
926 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
930 printf("Invalid WPS_ER_PIN command: need at least two "
932 "- UUID: use 'any' to select any\n"
933 "- PIN: Enrollee PIN\n"
934 "optional: - Enrollee MAC address\n");
938 return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv);
942 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
945 return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv);
949 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
953 printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
954 "- UUID: specify which AP to use\n"
959 return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv);
963 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
967 printf("Invalid WPS_ER_SET_CONFIG command: need two "
969 "- UUID: specify which AP to use\n"
970 "- Network configuration id\n");
974 return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv);
978 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
984 if (argc == 5 || argc == 6) {
985 char ssid_hex[2 * SSID_MAX_LEN + 1];
986 char key_hex[2 * 64 + 1];
990 for (i = 0; i < SSID_MAX_LEN; i++) {
991 if (argv[2][i] == '\0')
993 os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
998 for (i = 0; i < 64; i++) {
999 if (argv[5][i] == '\0')
1001 os_snprintf(&key_hex[i * 2], 3, "%02x",
1006 res = os_snprintf(cmd, sizeof(cmd),
1007 "WPS_ER_CONFIG %s %s %s %s %s %s",
1008 argv[0], argv[1], ssid_hex, argv[3], argv[4],
1011 printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
1015 "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1016 "- new encr (NONE, WEP, TKIP, CCMP)\n"
1021 if (os_snprintf_error(sizeof(cmd), res)) {
1022 printf("Too long WPS_ER_CONFIG command.\n");
1025 return wpa_ctrl_command(ctrl, cmd);
1029 #ifdef CONFIG_WPS_NFC
1030 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
1034 printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
1036 "- WPS/NDEF: token format\n"
1037 "- UUID: specify which AP to use\n");
1041 return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv);
1043 #endif /* CONFIG_WPS_NFC */
1046 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1048 return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv);
1052 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1054 return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv);
1058 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1060 char cmd[256], *pos, *end;
1064 printf("Invalid IDENTITY command: needs two arguments "
1065 "(network id and identity)\n");
1069 end = cmd + sizeof(cmd);
1071 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1073 if (os_snprintf_error(end - pos, ret)) {
1074 printf("Too long IDENTITY command.\n");
1078 for (i = 2; i < argc; i++) {
1079 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1080 if (os_snprintf_error(end - pos, ret)) {
1081 printf("Too long IDENTITY command.\n");
1087 return wpa_ctrl_command(ctrl, cmd);
1091 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1093 char cmd[256], *pos, *end;
1097 printf("Invalid PASSWORD command: needs two arguments "
1098 "(network id and password)\n");
1102 end = cmd + sizeof(cmd);
1104 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1106 if (os_snprintf_error(end - pos, ret)) {
1107 printf("Too long PASSWORD command.\n");
1111 for (i = 2; i < argc; i++) {
1112 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1113 if (os_snprintf_error(end - pos, ret)) {
1114 printf("Too long PASSWORD command.\n");
1120 return wpa_ctrl_command(ctrl, cmd);
1124 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1127 char cmd[256], *pos, *end;
1131 printf("Invalid NEW_PASSWORD command: needs two arguments "
1132 "(network id and password)\n");
1136 end = cmd + sizeof(cmd);
1138 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1140 if (os_snprintf_error(end - pos, ret)) {
1141 printf("Too long NEW_PASSWORD command.\n");
1145 for (i = 2; i < argc; i++) {
1146 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1147 if (os_snprintf_error(end - pos, ret)) {
1148 printf("Too long NEW_PASSWORD command.\n");
1154 return wpa_ctrl_command(ctrl, cmd);
1158 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1160 char cmd[256], *pos, *end;
1164 printf("Invalid PIN command: needs two arguments "
1165 "(network id and pin)\n");
1169 end = cmd + sizeof(cmd);
1171 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1173 if (os_snprintf_error(end - pos, ret)) {
1174 printf("Too long PIN command.\n");
1178 for (i = 2; i < argc; i++) {
1179 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1180 if (os_snprintf_error(end - pos, ret)) {
1181 printf("Too long PIN command.\n");
1186 return wpa_ctrl_command(ctrl, cmd);
1190 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1192 char cmd[256], *pos, *end;
1196 printf("Invalid OTP command: needs two arguments (network "
1197 "id and password)\n");
1201 end = cmd + sizeof(cmd);
1203 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1205 if (os_snprintf_error(end - pos, ret)) {
1206 printf("Too long OTP command.\n");
1210 for (i = 2; i < argc; i++) {
1211 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1212 if (os_snprintf_error(end - pos, ret)) {
1213 printf("Too long OTP command.\n");
1219 return wpa_ctrl_command(ctrl, cmd);
1223 static int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[])
1225 char cmd[256], *pos, *end;
1229 printf("Invalid SIM command: needs two arguments "
1230 "(network id and SIM operation response)\n");
1234 end = cmd + sizeof(cmd);
1236 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s",
1238 if (os_snprintf_error(end - pos, ret)) {
1239 printf("Too long SIM command.\n");
1243 for (i = 2; i < argc; i++) {
1244 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1245 if (os_snprintf_error(end - pos, ret)) {
1246 printf("Too long SIM command.\n");
1251 return wpa_ctrl_command(ctrl, cmd);
1255 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1258 char cmd[256], *pos, *end;
1262 printf("Invalid PASSPHRASE command: needs two arguments "
1263 "(network id and passphrase)\n");
1267 end = cmd + sizeof(cmd);
1269 ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1271 if (os_snprintf_error(end - pos, ret)) {
1272 printf("Too long PASSPHRASE command.\n");
1276 for (i = 2; i < argc; i++) {
1277 ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1278 if (os_snprintf_error(end - pos, ret)) {
1279 printf("Too long PASSPHRASE command.\n");
1285 return wpa_ctrl_command(ctrl, cmd);
1289 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1292 printf("Invalid BSSID command: needs two arguments (network "
1297 return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv);
1301 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
1303 return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv);
1307 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1309 return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv);
1313 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
1316 return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
1320 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
1323 return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv);
1327 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
1330 return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv);
1334 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
1337 return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv);
1341 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
1344 int res = wpa_ctrl_command(ctrl, "ADD_NETWORK");
1346 update_networks(ctrl);
1351 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
1354 int res = wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv);
1356 update_networks(ctrl);
1361 static void wpa_cli_show_network_variables(void)
1363 printf("set_network variables:\n"
1364 " ssid (network name, SSID)\n"
1365 " psk (WPA passphrase or pre-shared key)\n"
1366 " key_mgmt (key management protocol)\n"
1367 " identity (EAP identity)\n"
1368 " password (EAP password)\n"
1371 "Note: Values are entered in the same format as the "
1372 "configuration file is using,\n"
1373 "i.e., strings values need to be inside double quotation "
1375 "For example: set_network 1 ssid \"network name\"\n"
1377 "Please see wpa_supplicant.conf documentation for full list "
1378 "of\navailable variables.\n");
1382 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
1386 wpa_cli_show_network_variables();
1391 printf("Invalid SET_NETWORK command: needs three arguments\n"
1392 "(network id, variable name, and value)\n");
1396 return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv);
1400 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
1404 wpa_cli_show_network_variables();
1409 printf("Invalid GET_NETWORK command: needs two arguments\n"
1410 "(network id and variable name)\n");
1414 return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv);
1418 static const char *network_fields[] = {
1419 "ssid", "scan_ssid", "bssid", "bssid_blacklist",
1420 "bssid_whitelist", "psk", "proto", "key_mgmt",
1421 "bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq",
1422 "freq_list", "max_oper_chwidth",
1423 #ifdef IEEE8021X_EAPOL
1424 "eap", "identity", "anonymous_identity", "password", "ca_cert",
1425 "ca_path", "client_cert", "private_key", "private_key_passwd",
1426 "dh_file", "subject_match", "altsubject_match",
1427 "domain_suffix_match", "domain_match", "ca_cert2", "ca_path2",
1428 "client_cert2", "private_key2", "private_key2_passwd",
1429 "dh_file2", "subject_match2", "altsubject_match2",
1430 "domain_suffix_match2", "domain_match2", "phase1", "phase2",
1431 "pcsc", "pin", "engine_id", "key_id", "cert_id", "ca_cert_id",
1432 "pin2", "engine2_id", "key2_id", "cert2_id", "ca_cert2_id",
1433 "engine", "engine2", "eapol_flags", "sim_num",
1434 "openssl_ciphers", "erp",
1435 #endif /* IEEE8021X_EAPOL */
1436 "wep_key0", "wep_key1", "wep_key2", "wep_key3",
1437 "wep_tx_keyidx", "priority",
1438 #ifdef IEEE8021X_EAPOL
1439 "eap_workaround", "pac_file", "fragment_size", "ocsp",
1440 #endif /* IEEE8021X_EAPOL */
1442 "mode", "no_auto_peer",
1443 #else /* CONFIG_MESH */
1445 #endif /* CONFIG_MESH */
1446 "proactive_key_caching", "disabled", "id_str",
1447 #ifdef CONFIG_IEEE80211W
1449 #endif /* CONFIG_IEEE80211W */
1450 "peerkey", "mixed_cell", "frequency", "fixed_freq",
1452 "mesh_basic_rates", "dot11MeshMaxRetries",
1453 "dot11MeshRetryTimeout", "dot11MeshConfirmTimeout",
1454 "dot11MeshHoldingTimeout",
1455 #endif /* CONFIG_MESH */
1456 "wpa_ptk_rekey", "bgscan", "ignore_broadcast_ssid",
1458 "go_p2p_dev_addr", "p2p_client_list", "psk_list",
1459 #endif /* CONFIG_P2P */
1460 #ifdef CONFIG_HT_OVERRIDES
1461 "disable_ht", "disable_ht40", "disable_sgi", "disable_ldpc",
1462 "ht40_intolerant", "disable_max_amsdu", "ampdu_factor",
1463 "ampdu_density", "ht_mcs",
1464 #endif /* CONFIG_HT_OVERRIDES */
1465 #ifdef CONFIG_VHT_OVERRIDES
1466 "disable_vht", "vht_capa", "vht_capa_mask", "vht_rx_mcs_nss_1",
1467 "vht_rx_mcs_nss_2", "vht_rx_mcs_nss_3", "vht_rx_mcs_nss_4",
1468 "vht_rx_mcs_nss_5", "vht_rx_mcs_nss_6", "vht_rx_mcs_nss_7",
1469 "vht_rx_mcs_nss_8", "vht_tx_mcs_nss_1", "vht_tx_mcs_nss_2",
1470 "vht_tx_mcs_nss_3", "vht_tx_mcs_nss_4", "vht_tx_mcs_nss_5",
1471 "vht_tx_mcs_nss_6", "vht_tx_mcs_nss_7", "vht_tx_mcs_nss_8",
1472 #endif /* CONFIG_VHT_OVERRIDES */
1473 "ap_max_inactivity", "dtim_period", "beacon_int",
1474 #ifdef CONFIG_MACSEC
1476 #endif /* CONFIG_MACSEC */
1478 "update_identifier",
1479 #endif /* CONFIG_HS20 */
1480 "mac_addr", "pbss", "wps_disabled"
1484 static char ** wpa_cli_complete_network(const char *str, int pos)
1486 int arg = get_cmd_arg_num(str, pos);
1487 int i, num_fields = ARRAY_SIZE(network_fields);
1492 res = cli_txt_list_array(&networks);
1495 res = os_calloc(num_fields + 1, sizeof(char *));
1498 for (i = 0; i < num_fields; i++) {
1499 res[i] = os_strdup(network_fields[i]);
1508 static char ** wpa_cli_complete_network_id(const char *str, int pos)
1510 int arg = get_cmd_arg_num(str, pos);
1512 return cli_txt_list_array(&networks);
1517 static int wpa_cli_cmd_dup_network(struct wpa_ctrl *ctrl, int argc,
1521 wpa_cli_show_network_variables();
1526 printf("Invalid DUP_NETWORK command: needs three arguments\n"
1527 "(src netid, dest netid, and variable name)\n");
1531 return wpa_cli_cmd(ctrl, "DUP_NETWORK", 3, argc, argv);
1535 static char ** wpa_cli_complete_dup_network(const char *str, int pos)
1537 int arg = get_cmd_arg_num(str, pos);
1538 int i, num_fields = ARRAY_SIZE(network_fields);
1544 res = cli_txt_list_array(&networks);
1547 res = os_calloc(num_fields + 1, sizeof(char *));
1550 for (i = 0; i < num_fields; i++) {
1551 res[i] = os_strdup(network_fields[i]);
1560 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1563 return wpa_ctrl_command(ctrl, "LIST_CREDS");
1567 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1569 return wpa_ctrl_command(ctrl, "ADD_CRED");
1573 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1576 return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv);
1580 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1583 printf("Invalid SET_CRED command: needs three arguments\n"
1584 "(cred id, variable name, and value)\n");
1588 return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv);
1592 static int wpa_cli_cmd_get_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1595 printf("Invalid GET_CRED command: needs two arguments\n"
1596 "(cred id, variable name)\n");
1600 return wpa_cli_cmd(ctrl, "GET_CRED", 2, argc, argv);
1604 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
1607 return wpa_ctrl_command(ctrl, "DISCONNECT");
1611 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1614 return wpa_ctrl_command(ctrl, "RECONNECT");
1618 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1621 return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
1625 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1627 return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
1631 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1634 return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
1638 static int wpa_cli_cmd_abort_scan(struct wpa_ctrl *ctrl, int argc,
1641 return wpa_ctrl_command(ctrl, "ABORT_SCAN");
1645 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1647 return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
1651 static char ** wpa_cli_complete_bss(const char *str, int pos)
1653 int arg = get_cmd_arg_num(str, pos);
1658 res = cli_txt_list_array(&bsses);
1666 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1669 if (argc < 1 || argc > 2) {
1670 printf("Invalid GET_CAPABILITY command: need either one or "
1675 if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
1676 printf("Invalid GET_CAPABILITY command: second argument, "
1677 "if any, must be 'strict'\n");
1681 return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv);
1685 static char ** wpa_cli_complete_get_capability(const char *str, int pos)
1687 int arg = get_cmd_arg_num(str, pos);
1688 const char *fields[] = {
1689 "eap", "pairwise", "group", "group_mgmt", "key_mgmt",
1690 "proto", "auth_alg", "modes", "channels", "freq",
1693 #endif /* CONFIG_TDLS */
1696 #endif /* CONFIG_ERP */
1699 #endif /* CONFIG_FIPS */
1702 #endif /* CONFIG_ACS */
1704 int i, num_fields = ARRAY_SIZE(fields);
1708 res = os_calloc(num_fields + 1, sizeof(char *));
1711 for (i = 0; i < num_fields; i++) {
1712 res[i] = os_strdup(fields[i]);
1718 res = os_calloc(1 + 1, sizeof(char *));
1721 res[0] = os_strdup("strict");
1727 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
1729 printf("Available interfaces:\n");
1730 return wpa_ctrl_command(ctrl, "INTERFACES");
1734 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
1737 wpa_cli_list_interfaces(ctrl);
1741 wpa_cli_close_connection();
1742 os_free(ctrl_ifname);
1743 ctrl_ifname = os_strdup(argv[0]);
1745 printf("Failed to allocate memory\n");
1749 if (wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
1750 printf("Connected to interface '%s.\n", ctrl_ifname);
1752 printf("Could not connect to interface '%s' - re-trying\n",
1759 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1762 return wpa_ctrl_command(ctrl, "RECONFIGURE");
1766 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1769 return wpa_ctrl_command(ctrl, "TERMINATE");
1773 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
1780 printf("Invalid INTERFACE_ADD command: needs at least one "
1781 "argument (interface name)\n"
1782 "All arguments: ifname confname driver ctrl_interface "
1783 "driver_param bridge_name [create]\n");
1788 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1789 * <driver_param>TAB<bridge_name>[TAB<create>[TAB<type>]]
1791 res = os_snprintf(cmd, sizeof(cmd),
1792 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
1794 argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
1795 argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
1796 argc > 5 ? argv[5] : "", argc > 6 ? argv[6] : "",
1797 argc > 7 ? argv[7] : "");
1798 if (os_snprintf_error(sizeof(cmd), res))
1800 cmd[sizeof(cmd) - 1] = '\0';
1801 return wpa_ctrl_command(ctrl, cmd);
1805 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
1808 return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv);
1812 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
1815 return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
1820 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1822 return wpa_cli_cmd(ctrl, "STA", 1, argc, argv);
1826 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
1827 char *addr, size_t addr_len)
1829 char buf[4096], *pos;
1833 if (ctrl_conn == NULL) {
1834 printf("Not connected to hostapd - command dropped.\n");
1837 if (ifname_prefix) {
1838 os_snprintf(buf, sizeof(buf), "IFNAME=%s %s",
1839 ifname_prefix, cmd);
1840 buf[sizeof(buf) - 1] = '\0';
1843 len = sizeof(buf) - 1;
1844 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
1847 printf("'%s' command timed out.\n", cmd);
1849 } else if (ret < 0) {
1850 printf("'%s' command failed.\n", cmd);
1855 if (os_memcmp(buf, "FAIL", 4) == 0)
1860 while (*pos != '\0' && *pos != '\n')
1863 os_strlcpy(addr, buf, addr_len);
1868 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
1870 char addr[32], cmd[64];
1872 if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
1875 os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
1876 } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
1882 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
1885 return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv);
1889 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
1892 return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv);
1895 static int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc,
1898 return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv);
1901 #endif /* CONFIG_AP */
1904 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1906 return wpa_ctrl_command(ctrl, "SUSPEND");
1910 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1912 return wpa_ctrl_command(ctrl, "RESUME");
1916 #ifdef CONFIG_TESTING_OPTIONS
1917 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1919 return wpa_ctrl_command(ctrl, "DROP_SA");
1921 #endif /* CONFIG_TESTING_OPTIONS */
1924 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1926 return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv);
1932 static int wpa_cli_cmd_mesh_interface_add(struct wpa_ctrl *ctrl, int argc,
1935 return wpa_cli_cmd(ctrl, "MESH_INTERFACE_ADD", 0, argc, argv);
1939 static int wpa_cli_cmd_mesh_group_add(struct wpa_ctrl *ctrl, int argc,
1942 return wpa_cli_cmd(ctrl, "MESH_GROUP_ADD", 1, argc, argv);
1946 static int wpa_cli_cmd_mesh_group_remove(struct wpa_ctrl *ctrl, int argc,
1949 return wpa_cli_cmd(ctrl, "MESH_GROUP_REMOVE", 1, argc, argv);
1953 static int wpa_cli_cmd_mesh_peer_remove(struct wpa_ctrl *ctrl, int argc,
1956 return wpa_cli_cmd(ctrl, "MESH_PEER_REMOVE", 1, argc, argv);
1960 static int wpa_cli_cmd_mesh_peer_add(struct wpa_ctrl *ctrl, int argc,
1963 return wpa_cli_cmd(ctrl, "MESH_PEER_ADD", 1, argc, argv);
1966 #endif /* CONFIG_MESH */
1971 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1973 return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv);
1977 static char ** wpa_cli_complete_p2p_find(const char *str, int pos)
1980 int arg = get_cmd_arg_num(str, pos);
1982 res = os_calloc(6, sizeof(char *));
1985 res[0] = os_strdup("type=social");
1986 if (res[0] == NULL) {
1990 res[1] = os_strdup("type=progressive");
1993 res[2] = os_strdup("delay=");
1996 res[3] = os_strdup("dev_id=");
2000 res[4] = os_strdup("[timeout]");
2006 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
2009 return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
2013 static int wpa_cli_cmd_p2p_asp_provision(struct wpa_ctrl *ctrl, int argc,
2016 return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION", 3, argc, argv);
2020 static int wpa_cli_cmd_p2p_asp_provision_resp(struct wpa_ctrl *ctrl, int argc,
2023 return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION_RESP", 2, argc, argv);
2027 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
2030 return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv);
2034 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
2036 int arg = get_cmd_arg_num(str, pos);
2041 res = cli_txt_list_array(&p2p_peers);
2049 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
2052 return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv);
2056 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
2059 return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv);
2063 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
2065 int arg = get_cmd_arg_num(str, pos);
2070 res = cli_txt_list_array(&p2p_groups);
2078 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
2081 return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv);
2085 static int wpa_cli_cmd_p2p_group_member(struct wpa_ctrl *ctrl, int argc,
2088 return wpa_cli_cmd(ctrl, "P2P_GROUP_MEMBER", 1, argc, argv);
2092 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
2095 if (argc != 2 && argc != 3) {
2096 printf("Invalid P2P_PROV_DISC command: needs at least "
2097 "two arguments, address and config method\n"
2098 "(display, keypad, or pbc) and an optional join\n");
2102 return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv);
2106 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
2109 return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
2113 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
2119 printf("Invalid P2P_SERV_DISC_REQ command: needs two "
2120 "or more arguments (address and TLVs)\n");
2124 if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0)
2126 return wpa_ctrl_command(ctrl, cmd);
2130 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
2131 int argc, char *argv[])
2133 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv);
2137 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
2144 printf("Invalid P2P_SERV_DISC_RESP command: needs four "
2145 "arguments (freq, address, dialog token, and TLVs)\n");
2149 res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
2150 argv[0], argv[1], argv[2], argv[3]);
2151 if (os_snprintf_error(sizeof(cmd), res))
2153 cmd[sizeof(cmd) - 1] = '\0';
2154 return wpa_ctrl_command(ctrl, cmd);
2158 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
2161 return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
2165 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
2166 int argc, char *argv[])
2168 return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv);
2172 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
2175 return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
2179 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
2183 printf("Invalid P2P_SERVICE_ADD command: needs 3-6 arguments\n");
2187 return wpa_cli_cmd(ctrl, "P2P_SERVICE_ADD", 3, argc, argv);
2191 static int wpa_cli_cmd_p2p_service_rep(struct wpa_ctrl *ctrl, int argc,
2194 if (argc < 5 || argc > 6) {
2195 printf("Invalid P2P_SERVICE_REP command: needs 5-6 "
2200 return wpa_cli_cmd(ctrl, "P2P_SERVICE_REP", 5, argc, argv);
2204 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2210 if (argc != 2 && argc != 3) {
2211 printf("Invalid P2P_SERVICE_DEL command: needs two or three "
2217 res = os_snprintf(cmd, sizeof(cmd),
2218 "P2P_SERVICE_DEL %s %s %s",
2219 argv[0], argv[1], argv[2]);
2221 res = os_snprintf(cmd, sizeof(cmd),
2222 "P2P_SERVICE_DEL %s %s",
2224 if (os_snprintf_error(sizeof(cmd), res))
2226 cmd[sizeof(cmd) - 1] = '\0';
2227 return wpa_ctrl_command(ctrl, cmd);
2231 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2232 int argc, char *argv[])
2234 return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv);
2238 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2239 int argc, char *argv[])
2241 return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv);
2245 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2247 return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv);
2251 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2253 int arg = get_cmd_arg_num(str, pos);
2258 res = cli_txt_list_array(&p2p_peers);
2266 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
2267 char *addr, size_t addr_len,
2270 char buf[4096], *pos;
2274 if (ctrl_conn == NULL)
2276 len = sizeof(buf) - 1;
2277 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2280 printf("'%s' command timed out.\n", cmd);
2282 } else if (ret < 0) {
2283 printf("'%s' command failed.\n", cmd);
2288 if (os_memcmp(buf, "FAIL", 4) == 0)
2292 while (*pos != '\0' && *pos != '\n')
2295 os_strlcpy(addr, buf, addr_len);
2296 if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2297 printf("%s\n", addr);
2302 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2304 char addr[32], cmd[64];
2307 discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2309 if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2310 addr, sizeof(addr), discovered))
2313 os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2314 } while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2321 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2323 return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv);
2327 static char ** wpa_cli_complete_p2p_set(const char *str, int pos)
2329 int arg = get_cmd_arg_num(str, pos);
2330 const char *fields[] = {
2350 int i, num_fields = ARRAY_SIZE(fields);
2353 char **res = os_calloc(num_fields + 1, sizeof(char *));
2356 for (i = 0; i < num_fields; i++) {
2357 res[i] = os_strdup(fields[i]);
2364 if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0)
2365 return cli_txt_list_array(&p2p_peers);
2371 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2373 return wpa_ctrl_command(ctrl, "P2P_FLUSH");
2377 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2380 return wpa_ctrl_command(ctrl, "P2P_CANCEL");
2384 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2387 return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv);
2391 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2394 if (argc != 0 && argc != 2 && argc != 4) {
2395 printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
2396 "(preferred duration, interval; in microsecods).\n"
2397 "Optional second pair can be used to provide "
2398 "acceptable values.\n");
2402 return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv);
2406 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2409 if (argc != 0 && argc != 2) {
2410 printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
2411 "(availability period, availability interval; in "
2413 "Extended Listen Timing can be cancelled with this "
2414 "command when used without parameters.\n");
2418 return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv);
2422 static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc,
2425 return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv);
2429 static int wpa_cli_cmd_vendor_elem_add(struct wpa_ctrl *ctrl, int argc,
2432 return wpa_cli_cmd(ctrl, "VENDOR_ELEM_ADD", 2, argc, argv);
2436 static int wpa_cli_cmd_vendor_elem_get(struct wpa_ctrl *ctrl, int argc,
2439 return wpa_cli_cmd(ctrl, "VENDOR_ELEM_GET", 1, argc, argv);
2443 static int wpa_cli_cmd_vendor_elem_remove(struct wpa_ctrl *ctrl, int argc,
2446 return wpa_cli_cmd(ctrl, "VENDOR_ELEM_REMOVE", 2, argc, argv);
2449 #endif /* CONFIG_P2P */
2451 #ifdef CONFIG_WIFI_DISPLAY
2453 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc,
2459 if (argc != 1 && argc != 2) {
2460 printf("Invalid WFD_SUBELEM_SET command: needs one or two "
2461 "arguments (subelem, hexdump)\n");
2465 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s",
2466 argv[0], argc > 1 ? argv[1] : "");
2467 if (os_snprintf_error(sizeof(cmd), res))
2469 cmd[sizeof(cmd) - 1] = '\0';
2470 return wpa_ctrl_command(ctrl, cmd);
2474 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc,
2481 printf("Invalid WFD_SUBELEM_GET command: needs one "
2482 "argument (subelem)\n");
2486 res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s",
2488 if (os_snprintf_error(sizeof(cmd), res))
2490 cmd[sizeof(cmd) - 1] = '\0';
2491 return wpa_ctrl_command(ctrl, cmd);
2493 #endif /* CONFIG_WIFI_DISPLAY */
2496 #ifdef CONFIG_INTERWORKING
2497 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2500 return wpa_ctrl_command(ctrl, "FETCH_ANQP");
2504 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2507 return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
2511 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2514 return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv);
2518 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2521 return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv);
2525 static int wpa_cli_cmd_interworking_add_network(struct wpa_ctrl *ctrl, int argc,
2528 return wpa_cli_cmd(ctrl, "INTERWORKING_ADD_NETWORK", 1, argc, argv);
2532 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2534 return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv);
2538 static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc,
2541 return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv);
2545 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc,
2548 return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv);
2550 #endif /* CONFIG_INTERWORKING */
2555 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2558 return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv);
2562 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2568 printf("Command needs one or two arguments (dst mac addr and "
2569 "optional home realm)\n");
2573 if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST",
2577 return wpa_ctrl_command(ctrl, cmd);
2581 static int wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl *ctrl, int argc,
2587 printf("Command needs two arguments (dst mac addr and "
2592 if (write_cmd(cmd, sizeof(cmd), "HS20_ICON_REQUEST", argc, argv) < 0)
2595 return wpa_ctrl_command(ctrl, cmd);
2599 static int wpa_cli_cmd_fetch_osu(struct wpa_ctrl *ctrl, int argc, char *argv[])
2601 return wpa_ctrl_command(ctrl, "FETCH_OSU");
2605 static int wpa_cli_cmd_cancel_fetch_osu(struct wpa_ctrl *ctrl, int argc,
2608 return wpa_ctrl_command(ctrl, "CANCEL_FETCH_OSU");
2611 #endif /* CONFIG_HS20 */
2614 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2617 return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv);
2621 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2624 return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv);
2628 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2631 return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv);
2635 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2638 return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv);
2642 static int wpa_cli_cmd_tdls_link_status(struct wpa_ctrl *ctrl, int argc,
2645 return wpa_cli_cmd(ctrl, "TDLS_LINK_STATUS", 1, argc, argv);
2649 static int wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl *ctrl, int argc,
2652 return wpa_cli_cmd(ctrl, "WMM_AC_ADDTS", 3, argc, argv);
2656 static int wpa_cli_cmd_wmm_ac_delts(struct wpa_ctrl *ctrl, int argc,
2659 return wpa_cli_cmd(ctrl, "WMM_AC_DELTS", 1, argc, argv);
2663 static int wpa_cli_cmd_wmm_ac_status(struct wpa_ctrl *ctrl, int argc,
2666 return wpa_ctrl_command(ctrl, "WMM_AC_STATUS");
2670 static int wpa_cli_cmd_tdls_chan_switch(struct wpa_ctrl *ctrl, int argc,
2673 return wpa_cli_cmd(ctrl, "TDLS_CHAN_SWITCH", 2, argc, argv);
2677 static int wpa_cli_cmd_tdls_cancel_chan_switch(struct wpa_ctrl *ctrl, int argc,
2680 return wpa_cli_cmd(ctrl, "TDLS_CANCEL_CHAN_SWITCH", 1, argc, argv);
2684 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2687 return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
2691 static int wpa_cli_cmd_signal_monitor(struct wpa_ctrl *ctrl, int argc,
2694 return wpa_cli_cmd(ctrl, "SIGNAL_MONITOR", 0, argc, argv);
2698 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
2701 return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
2705 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2708 return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
2712 #ifdef CONFIG_AUTOSCAN
2714 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
2717 return wpa_ctrl_command(ctrl, "AUTOSCAN ");
2719 return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv);
2722 #endif /* CONFIG_AUTOSCAN */
2727 static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[])
2729 return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv);
2733 static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
2735 return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv);
2738 #endif /* CONFIG_WNM */
2741 static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
2745 return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
2750 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
2752 return wpa_cli_cmd(ctrl, "DRIVER", 1, argc, argv);
2754 #endif /* ANDROID */
2757 static int wpa_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
2759 return wpa_cli_cmd(ctrl, "VENDOR", 1, argc, argv);
2763 static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2765 return wpa_ctrl_command(ctrl, "FLUSH");
2769 static int wpa_cli_cmd_radio_work(struct wpa_ctrl *ctrl, int argc, char *argv[])
2771 return wpa_cli_cmd(ctrl, "RADIO_WORK", 1, argc, argv);
2775 static int wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl *ctrl, int argc,
2778 return wpa_cli_cmd(ctrl, "NEIGHBOR_REP_REQUEST", 0, argc, argv);
2782 static int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2784 return wpa_ctrl_command(ctrl, "ERP_FLUSH");
2788 static int wpa_cli_cmd_mac_rand_scan(struct wpa_ctrl *ctrl, int argc,
2791 return wpa_cli_cmd(ctrl, "MAC_RAND_SCAN", 1, argc, argv);
2795 static int wpa_cli_cmd_get_pref_freq_list(struct wpa_ctrl *ctrl, int argc,
2798 return wpa_cli_cmd(ctrl, "GET_PREF_FREQ_LIST", 1, argc, argv);
2802 static int wpa_cli_cmd_p2p_lo_start(struct wpa_ctrl *ctrl, int argc,
2805 return wpa_cli_cmd(ctrl, "P2P_LO_START", 4, argc, argv);
2809 static int wpa_cli_cmd_p2p_lo_stop(struct wpa_ctrl *ctrl, int argc,
2812 return wpa_cli_cmd(ctrl, "P2P_LO_STOP", 0, argc, argv);
2816 enum wpa_cli_cmd_flags {
2817 cli_cmd_flag_none = 0x00,
2818 cli_cmd_flag_sensitive = 0x01
2821 struct wpa_cli_cmd {
2823 int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2824 char ** (*completion)(const char *str, int pos);
2825 enum wpa_cli_cmd_flags flags;
2829 static const struct wpa_cli_cmd wpa_cli_commands[] = {
2830 { "status", wpa_cli_cmd_status, NULL,
2832 "[verbose] = get current WPA/EAPOL/EAP status" },
2833 { "ifname", wpa_cli_cmd_ifname, NULL,
2835 "= get current interface name" },
2836 { "ping", wpa_cli_cmd_ping, NULL,
2838 "= pings wpa_supplicant" },
2839 { "relog", wpa_cli_cmd_relog, NULL,
2841 "= re-open log-file (allow rolling logs)" },
2842 { "note", wpa_cli_cmd_note, NULL,
2844 "<text> = add a note to wpa_supplicant debug log" },
2845 { "mib", wpa_cli_cmd_mib, NULL,
2847 "= get MIB variables (dot1x, dot11)" },
2848 { "help", wpa_cli_cmd_help, wpa_cli_complete_help,
2850 "[command] = show usage help" },
2851 { "interface", wpa_cli_cmd_interface, NULL,
2853 "[ifname] = show interfaces/select interface" },
2854 { "level", wpa_cli_cmd_level, NULL,
2856 "<debug level> = change debug level" },
2857 { "license", wpa_cli_cmd_license, NULL,
2859 "= show full wpa_cli license" },
2860 { "quit", wpa_cli_cmd_quit, NULL,
2863 { "set", wpa_cli_cmd_set, wpa_cli_complete_set,
2865 "= set variables (shows list of variables when run without "
2867 { "dump", wpa_cli_cmd_dump, NULL,
2869 "= dump config variables" },
2870 { "get", wpa_cli_cmd_get, wpa_cli_complete_get,
2872 "<name> = get information" },
2873 { "driver_flags", wpa_cli_cmd_driver_flags, NULL,
2875 "= list driver flags" },
2876 { "logon", wpa_cli_cmd_logon, NULL,
2878 "= IEEE 802.1X EAPOL state machine logon" },
2879 { "logoff", wpa_cli_cmd_logoff, NULL,
2881 "= IEEE 802.1X EAPOL state machine logoff" },
2882 { "pmksa", wpa_cli_cmd_pmksa, NULL,
2884 "= show PMKSA cache" },
2885 { "pmksa_flush", wpa_cli_cmd_pmksa_flush, NULL,
2887 "= flush PMKSA cache entries" },
2888 { "reassociate", wpa_cli_cmd_reassociate, NULL,
2890 "= force reassociation" },
2891 { "reattach", wpa_cli_cmd_reattach, NULL,
2893 "= force reassociation back to the same BSS" },
2894 { "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
2896 "<BSSID> = force preauthentication" },
2897 { "identity", wpa_cli_cmd_identity, NULL,
2899 "<network id> <identity> = configure identity for an SSID" },
2900 { "password", wpa_cli_cmd_password, NULL,
2901 cli_cmd_flag_sensitive,
2902 "<network id> <password> = configure password for an SSID" },
2903 { "new_password", wpa_cli_cmd_new_password, NULL,
2904 cli_cmd_flag_sensitive,
2905 "<network id> <password> = change password for an SSID" },
2906 { "pin", wpa_cli_cmd_pin, NULL,
2907 cli_cmd_flag_sensitive,
2908 "<network id> <pin> = configure pin for an SSID" },
2909 { "otp", wpa_cli_cmd_otp, NULL,
2910 cli_cmd_flag_sensitive,
2911 "<network id> <password> = configure one-time-password for an SSID"
2913 { "passphrase", wpa_cli_cmd_passphrase, NULL,
2914 cli_cmd_flag_sensitive,
2915 "<network id> <passphrase> = configure private key passphrase\n"
2917 { "sim", wpa_cli_cmd_sim, NULL,
2918 cli_cmd_flag_sensitive,
2919 "<network id> <pin> = report SIM operation result" },
2920 { "bssid", wpa_cli_cmd_bssid, NULL,
2922 "<network id> <BSSID> = set preferred BSSID for an SSID" },
2923 { "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss,
2925 "<BSSID> = add a BSSID to the blacklist\n"
2926 "blacklist clear = clear the blacklist\n"
2927 "blacklist = display the blacklist" },
2928 { "log_level", wpa_cli_cmd_log_level, NULL,
2930 "<level> [<timestamp>] = update the log level/timestamp\n"
2931 "log_level = display the current log level and log options" },
2932 { "list_networks", wpa_cli_cmd_list_networks, NULL,
2934 "= list configured networks" },
2935 { "select_network", wpa_cli_cmd_select_network,
2936 wpa_cli_complete_network_id,
2938 "<network id> = select a network (disable others)" },
2939 { "enable_network", wpa_cli_cmd_enable_network,
2940 wpa_cli_complete_network_id,
2942 "<network id> = enable a network" },
2943 { "disable_network", wpa_cli_cmd_disable_network,
2944 wpa_cli_complete_network_id,
2946 "<network id> = disable a network" },
2947 { "add_network", wpa_cli_cmd_add_network, NULL,
2949 "= add a network" },
2950 { "remove_network", wpa_cli_cmd_remove_network,
2951 wpa_cli_complete_network_id,
2953 "<network id> = remove a network" },
2954 { "set_network", wpa_cli_cmd_set_network, wpa_cli_complete_network,
2955 cli_cmd_flag_sensitive,
2956 "<network id> <variable> <value> = set network variables (shows\n"
2957 " list of variables when run without arguments)" },
2958 { "get_network", wpa_cli_cmd_get_network, wpa_cli_complete_network,
2960 "<network id> <variable> = get network variables" },
2961 { "dup_network", wpa_cli_cmd_dup_network, wpa_cli_complete_dup_network,
2963 "<src network id> <dst network id> <variable> = duplicate network variables"
2965 { "list_creds", wpa_cli_cmd_list_creds, NULL,
2967 "= list configured credentials" },
2968 { "add_cred", wpa_cli_cmd_add_cred, NULL,
2970 "= add a credential" },
2971 { "remove_cred", wpa_cli_cmd_remove_cred, NULL,
2973 "<cred id> = remove a credential" },
2974 { "set_cred", wpa_cli_cmd_set_cred, NULL,
2975 cli_cmd_flag_sensitive,
2976 "<cred id> <variable> <value> = set credential variables" },
2977 { "get_cred", wpa_cli_cmd_get_cred, NULL,
2979 "<cred id> <variable> = get credential variables" },
2980 { "save_config", wpa_cli_cmd_save_config, NULL,
2982 "= save the current configuration" },
2983 { "disconnect", wpa_cli_cmd_disconnect, NULL,
2985 "= disconnect and wait for reassociate/reconnect command before\n"
2987 { "reconnect", wpa_cli_cmd_reconnect, NULL,
2989 "= like reassociate, but only takes effect if already disconnected"
2991 { "scan", wpa_cli_cmd_scan, NULL,
2993 "= request new BSS scan" },
2994 { "scan_results", wpa_cli_cmd_scan_results, NULL,
2996 "= get latest scan results" },
2997 { "abort_scan", wpa_cli_cmd_abort_scan, NULL,
2999 "= request ongoing scan to be aborted" },
3000 { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
3002 "<<idx> | <bssid>> = get detailed scan result info" },
3003 { "get_capability", wpa_cli_cmd_get_capability,
3004 wpa_cli_complete_get_capability, cli_cmd_flag_none,
3005 "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
3006 "= get capabilities" },
3007 { "reconfigure", wpa_cli_cmd_reconfigure, NULL,
3009 "= force wpa_supplicant to re-read its configuration file" },
3010 { "terminate", wpa_cli_cmd_terminate, NULL,
3012 "= terminate wpa_supplicant" },
3013 { "interface_add", wpa_cli_cmd_interface_add, NULL,
3015 "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
3016 " <bridge_name> <create> <type> = adds new interface, all "
3018 " <ifname> are optional. Supported types are station ('sta') and "
3020 { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
3022 "<ifname> = removes the interface" },
3023 { "interface_list", wpa_cli_cmd_interface_list, NULL,
3025 "= list available interfaces" },
3026 { "ap_scan", wpa_cli_cmd_ap_scan, NULL,
3028 "<value> = set ap_scan parameter" },
3029 { "scan_interval", wpa_cli_cmd_scan_interval, NULL,
3031 "<value> = set scan_interval parameter (in seconds)" },
3032 { "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
3034 "<value> = set BSS expiration age parameter" },
3035 { "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
3037 "<value> = set BSS expiration scan count parameter" },
3038 { "bss_flush", wpa_cli_cmd_bss_flush, NULL,
3040 "<value> = set BSS flush age (0 by default)" },
3041 { "stkstart", wpa_cli_cmd_stkstart, NULL,
3043 "<addr> = request STK negotiation with <addr>" },
3044 { "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
3046 "<addr> = request over-the-DS FT with <addr>" },
3047 { "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
3049 "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
3050 { "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
3051 cli_cmd_flag_sensitive,
3052 "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
3054 { "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
3055 cli_cmd_flag_sensitive,
3056 "<PIN> = verify PIN checksum" },
3057 { "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
3058 "Cancels the pending WPS operation" },
3059 #ifdef CONFIG_WPS_NFC
3060 { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
3062 "[BSSID] = start Wi-Fi Protected Setup: NFC" },
3063 { "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
3065 "<WPS|NDEF> = build configuration token" },
3066 { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
3068 "<WPS|NDEF> = create password token" },
3069 { "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
3070 cli_cmd_flag_sensitive,
3071 "<hexdump of payload> = report read NFC tag with WPS data" },
3072 { "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
3074 "<NDEF> <WPS> = create NFC handover request" },
3075 { "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
3077 "<NDEF> <WPS> = create NFC handover select" },
3078 { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
3080 "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
3082 #endif /* CONFIG_WPS_NFC */
3083 { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
3084 cli_cmd_flag_sensitive,
3085 "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
3086 { "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
3087 cli_cmd_flag_sensitive,
3088 "[params..] = enable/disable AP PIN" },
3089 { "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
3091 "[IP address] = start Wi-Fi Protected Setup External Registrar" },
3092 { "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
3094 "= stop Wi-Fi Protected Setup External Registrar" },
3095 { "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
3096 cli_cmd_flag_sensitive,
3097 "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
3098 { "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
3100 "<UUID> = accept an Enrollee PBC using External Registrar" },
3101 { "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
3102 cli_cmd_flag_sensitive,
3103 "<UUID> <PIN> = learn AP configuration" },
3104 { "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
3106 "<UUID> <network id> = set AP configuration for enrolling" },
3107 { "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
3108 cli_cmd_flag_sensitive,
3109 "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
3110 #ifdef CONFIG_WPS_NFC
3111 { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
3113 "<WPS/NDEF> <UUID> = build NFC configuration token" },
3114 #endif /* CONFIG_WPS_NFC */
3115 { "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
3117 "<addr> = request RSN authentication with <addr> in IBSS" },
3119 { "sta", wpa_cli_cmd_sta, NULL,
3121 "<addr> = get information about an associated station (AP)" },
3122 { "all_sta", wpa_cli_cmd_all_sta, NULL,
3124 "= get information about all associated stations (AP)" },
3125 { "deauthenticate", wpa_cli_cmd_deauthenticate, NULL,
3127 "<addr> = deauthenticate a station" },
3128 { "disassociate", wpa_cli_cmd_disassociate, NULL,
3130 "<addr> = disassociate a station" },
3131 { "chan_switch", wpa_cli_cmd_chanswitch, NULL,
3133 "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]"
3134 " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]"
3135 " = CSA parameters" },
3136 #endif /* CONFIG_AP */
3137 { "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
3138 "= notification of suspend/hibernate" },
3139 { "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
3140 "= notification of resume/thaw" },
3141 #ifdef CONFIG_TESTING_OPTIONS
3142 { "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
3143 "= drop SA without deauth/disassoc (test command)" },
3144 #endif /* CONFIG_TESTING_OPTIONS */
3145 { "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
3147 "<addr> = roam to the specified BSS" },
3149 { "mesh_interface_add", wpa_cli_cmd_mesh_interface_add, NULL,
3151 "[ifname] = Create a new mesh interface" },
3152 { "mesh_group_add", wpa_cli_cmd_mesh_group_add, NULL,
3154 "<network id> = join a mesh network (disable others)" },
3155 { "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL,
3157 "<ifname> = Remove mesh group interface" },
3158 { "mesh_peer_remove", wpa_cli_cmd_mesh_peer_remove, NULL,
3160 "<addr> = Remove a mesh peer" },
3161 { "mesh_peer_add", wpa_cli_cmd_mesh_peer_add, NULL,
3163 "<addr> [duration=<seconds>] = Add a mesh peer" },
3164 #endif /* CONFIG_MESH */
3166 { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
3168 "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
3169 { "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
3170 "= stop P2P Devices search" },
3171 { "p2p_asp_provision", wpa_cli_cmd_p2p_asp_provision, NULL,
3173 "<addr> adv_id=<adv_id> conncap=<conncap> [info=<infodata>] = provision with a P2P ASP Device" },
3174 { "p2p_asp_provision_resp", wpa_cli_cmd_p2p_asp_provision_resp, NULL,
3176 "<addr> adv_id=<adv_id> [role<conncap>] [info=<infodata>] = provision with a P2P ASP Device" },
3177 { "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
3179 "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
3180 { "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
3181 "[timeout] = listen for P2P Devices for up-to timeout seconds" },
3182 { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
3183 wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
3184 "<ifname> = remove P2P group interface (terminate group if GO)" },
3185 { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
3186 "[ht40] = add a new P2P group (local end as GO)" },
3187 { "p2p_group_member", wpa_cli_cmd_p2p_group_member, NULL,
3189 "<dev_addr> = Get peer interface address on local GO using peer Device Address" },
3190 { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
3191 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3192 "<addr> <method> = request provisioning discovery" },
3193 { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
3195 "= get the passphrase for a group (GO only)" },
3196 { "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
3197 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3198 "<addr> <TLVs> = schedule service discovery request" },
3199 { "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
3200 NULL, cli_cmd_flag_none,
3201 "<id> = cancel pending service discovery request" },
3202 { "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
3204 "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
3205 { "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
3207 "= indicate change in local services" },
3208 { "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
3210 "<external> = set external processing of service discovery" },
3211 { "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
3213 "= remove all stored service entries" },
3214 { "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
3216 "<bonjour|upnp|asp> <query|version> <response|service> = add a local "
3218 { "p2p_service_rep", wpa_cli_cmd_p2p_service_rep, NULL,
3220 "asp <auto> <adv_id> <svc_state> <svc_string> [<svc_info>] = replace "
3221 "local ASP service" },
3222 { "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
3224 "<bonjour|upnp> <query|version> [|service] = remove a local "
3226 { "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
3228 "<addr> = reject connection attempts from a specific peer" },
3229 { "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
3231 "<cmd> [peer=addr] = invite peer" },
3232 { "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
3233 "[discovered] = list known (optionally, only fully discovered) P2P "
3235 { "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
3237 "<address> = show information about known P2P peer" },
3238 { "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set,
3240 "<field> <value> = set a P2P parameter" },
3241 { "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
3242 "= flush P2P state" },
3243 { "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
3244 "= cancel P2P group formation" },
3245 { "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
3246 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3247 "<address> = unauthorize a peer" },
3248 { "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
3250 "[<duration> <interval>] [<duration> <interval>] = request GO "
3252 { "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
3254 "[<period> <interval>] = set extended listen timing" },
3255 { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client,
3256 wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3257 "<address|iface=address> = remove a peer from all groups" },
3258 { "vendor_elem_add", wpa_cli_cmd_vendor_elem_add, NULL,
3260 "<frame id> <hexdump of elem(s)> = add vendor specific IEs to frame(s)\n"
3261 VENDOR_ELEM_FRAME_ID },
3262 { "vendor_elem_get", wpa_cli_cmd_vendor_elem_get, NULL,
3264 "<frame id> = get vendor specific IE(s) to frame(s)\n"
3265 VENDOR_ELEM_FRAME_ID },
3266 { "vendor_elem_remove", wpa_cli_cmd_vendor_elem_remove, NULL,
3268 "<frame id> <hexdump of elem(s)> = remove vendor specific IE(s) in frame(s)\n"
3269 VENDOR_ELEM_FRAME_ID },
3270 #endif /* CONFIG_P2P */
3271 #ifdef CONFIG_WIFI_DISPLAY
3272 { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
3274 "<subelem> [contents] = set Wi-Fi Display subelement" },
3275 { "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
3277 "<subelem> = get Wi-Fi Display subelement" },
3278 #endif /* CONFIG_WIFI_DISPLAY */
3279 #ifdef CONFIG_INTERWORKING
3280 { "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
3281 "= fetch ANQP information for all APs" },
3282 { "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
3284 "= stop fetch_anqp operation" },
3285 { "interworking_select", wpa_cli_cmd_interworking_select, NULL,
3287 "[auto] = perform Interworking network selection" },
3288 { "interworking_connect", wpa_cli_cmd_interworking_connect,
3289 wpa_cli_complete_bss, cli_cmd_flag_none,
3290 "<BSSID> = connect using Interworking credentials" },
3291 { "interworking_add_network", wpa_cli_cmd_interworking_add_network,
3292 wpa_cli_complete_bss, cli_cmd_flag_none,
3293 "<BSSID> = connect using Interworking credentials" },
3294 { "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
3296 "<addr> <info id>[,<info id>]... = request ANQP information" },
3297 { "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
3299 "<addr> <AdvProtoID> [QueryReq] = GAS request" },
3300 { "gas_response_get", wpa_cli_cmd_gas_response_get,
3301 wpa_cli_complete_bss, cli_cmd_flag_none,
3302 "<addr> <dialog token> [start,len] = Fetch last GAS response" },
3303 #endif /* CONFIG_INTERWORKING */
3305 { "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
3307 "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
3309 { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
3310 wpa_cli_complete_bss, cli_cmd_flag_none,
3311 "<addr> <home realm> = get HS20 nai home realm list" },
3312 { "hs20_icon_request", wpa_cli_cmd_hs20_icon_request,
3313 wpa_cli_complete_bss, cli_cmd_flag_none,
3314 "<addr> <icon name> = get Hotspot 2.0 OSU icon" },
3315 { "fetch_osu", wpa_cli_cmd_fetch_osu, NULL, cli_cmd_flag_none,
3316 "= fetch OSU provider information from all APs" },
3317 { "cancel_fetch_osu", wpa_cli_cmd_cancel_fetch_osu, NULL,
3319 "= cancel fetch_osu command" },
3320 #endif /* CONFIG_HS20 */
3321 { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
3323 "<0/1> = disable/enable automatic reconnection" },
3324 { "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
3326 "<addr> = request TDLS discovery with <addr>" },
3327 { "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
3329 "<addr> = request TDLS setup with <addr>" },
3330 { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
3332 "<addr> = tear down TDLS with <addr>" },
3333 { "tdls_link_status", wpa_cli_cmd_tdls_link_status, NULL,
3335 "<addr> = TDLS link status with <addr>" },
3336 { "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL,
3338 "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] "
3339 "[mean_data_rate=#] [min_phy_rate=#] [sba=#] [fixed_nominal_msdu] "
3340 "= add WMM-AC traffic stream" },
3341 { "wmm_ac_delts", wpa_cli_cmd_wmm_ac_delts, NULL,
3343 "<tsid> = delete WMM-AC traffic stream" },
3344 { "wmm_ac_status", wpa_cli_cmd_wmm_ac_status, NULL,
3346 "= show status for Wireless Multi-Media Admission-Control" },
3347 { "tdls_chan_switch", wpa_cli_cmd_tdls_chan_switch, NULL,
3349 "<addr> <oper class> <freq> [sec_channel_offset=] [center_freq1=] "
3350 "[center_freq2=] [bandwidth=] [ht|vht] = enable channel switching "
3352 { "tdls_cancel_chan_switch", wpa_cli_cmd_tdls_cancel_chan_switch, NULL,
3354 "<addr> = disable channel switching with TDLS peer <addr>" },
3355 { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
3357 "= get signal parameters" },
3358 { "signal_monitor", wpa_cli_cmd_signal_monitor, NULL,
3360 "= set signal monitor parameters" },
3361 { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
3363 "= get TX/RX packet counters" },
3364 { "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
3366 "= trigger IEEE 802.1X/EAPOL reauthentication" },
3367 #ifdef CONFIG_AUTOSCAN
3368 { "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
3369 "[params] = Set or unset (if none) autoscan parameters" },
3370 #endif /* CONFIG_AUTOSCAN */
3372 { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
3373 "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
3374 { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
3375 "<query reason> [list] = Send BSS Transition Management Query" },
3376 #endif /* CONFIG_WNM */
3377 { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
3378 "<params..> = Sent unprocessed command" },
3379 { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
3380 "= flush wpa_supplicant state" },
3382 { "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none,
3383 "<command> = driver private commands" },
3384 #endif /* ANDROID */
3385 { "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none,
3386 "= radio_work <show/add/done>" },
3387 { "vendor", wpa_cli_cmd_vendor, NULL, cli_cmd_flag_none,
3388 "<vendor id> <command id> [<hex formatted command argument>] = Send vendor command"
3390 { "neighbor_rep_request",
3391 wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none,
3392 "[ssid=<SSID>] [lci] [civic] = Trigger request to AP for neighboring AP report (with optional given SSID in hex or enclosed in double quotes, default: current SSID; with optional LCI and location civic request)"
3394 { "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none,
3395 "= flush ERP keys" },
3397 wpa_cli_cmd_mac_rand_scan, NULL, cli_cmd_flag_none,
3398 "<scan|sched|pno|all> enable=<0/1> [addr=mac-address "
3399 "mask=mac-address-mask] = scan MAC randomization"
3401 { "get_pref_freq_list", wpa_cli_cmd_get_pref_freq_list, NULL,
3403 "<interface type> = retrieve preferred freq list for the specified interface type" },
3404 { "p2p_lo_start", wpa_cli_cmd_p2p_lo_start, NULL,
3406 "<freq> <period> <interval> <count> = start P2P listen offload" },
3407 { "p2p_lo_stop", wpa_cli_cmd_p2p_lo_stop, NULL,
3409 "= stop P2P listen offload" },
3410 { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
3415 * Prints command usage, lines are padded with the specified string.
3417 static void print_cmd_help(const struct wpa_cli_cmd *cmd, const char *pad)
3422 printf("%s%s ", pad, cmd->cmd);
3423 for (n = 0; (c = cmd->usage[n]); n++) {
3432 static void print_help(const char *cmd)
3435 printf("commands:\n");
3436 for (n = 0; wpa_cli_commands[n].cmd; n++) {
3437 if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd))
3438 print_cmd_help(&wpa_cli_commands[n], " ");
3443 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
3445 const char *c, *delim;
3449 delim = os_strchr(cmd, ' ');
3453 len = os_strlen(cmd);
3455 for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
3456 if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
3457 return (wpa_cli_commands[n].flags &
3458 cli_cmd_flag_sensitive);
3464 static char ** wpa_list_cmd_list(void)
3468 struct cli_txt_entry *e;
3470 count = ARRAY_SIZE(wpa_cli_commands);
3471 count += dl_list_len(&p2p_groups);
3472 count += dl_list_len(&ifnames);
3473 res = os_calloc(count + 1, sizeof(char *));
3477 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3478 res[i] = os_strdup(wpa_cli_commands[i].cmd);
3483 dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) {
3484 size_t len = 8 + os_strlen(e->txt);
3485 res[i] = os_malloc(len);
3488 os_snprintf(res[i], len, "ifname=%s", e->txt);
3492 dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) {
3493 res[i] = os_strdup(e->txt);
3503 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
3508 for (i = 0; wpa_cli_commands[i].cmd; i++) {
3509 if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
3510 if (wpa_cli_commands[i].completion)
3511 return wpa_cli_commands[i].completion(str,
3514 printf("\r%s\n", wpa_cli_commands[i].usage);
3524 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
3530 if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) {
3531 end = os_strchr(str, ' ');
3532 if (end && pos > end - str) {
3533 pos -= end - str + 1;
3538 end = os_strchr(str, ' ');
3539 if (end == NULL || str + pos < end)
3540 return wpa_list_cmd_list();
3542 cmd = os_malloc(pos + 1);
3545 os_memcpy(cmd, str, pos);
3546 cmd[end - str] = '\0';
3547 res = wpa_cli_cmd_completion(cmd, str, pos);
3553 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3555 const struct wpa_cli_cmd *cmd, *match = NULL;
3559 if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) {
3560 ifname_prefix = argv[0] + 7;
3564 ifname_prefix = NULL;
3570 cmd = wpa_cli_commands;
3572 if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3575 if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3576 /* we have an exact match */
3586 printf("Ambiguous command '%s'; possible commands:", argv[0]);
3587 cmd = wpa_cli_commands;
3589 if (os_strncasecmp(cmd->cmd, argv[0],
3590 os_strlen(argv[0])) == 0) {
3591 printf(" %s", cmd->cmd);
3597 } else if (count == 0) {
3598 printf("Unknown command '%s'\n", argv[0]);
3601 ret = match->handler(ctrl, argc - 1, &argv[1]);
3608 static int str_match(const char *a, const char *b)
3610 return os_strncmp(a, b, os_strlen(b)) == 0;
3614 static int wpa_cli_exec(const char *program, const char *arg1,
3621 /* If no interface is specified, set the global */
3625 len = os_strlen(arg1) + os_strlen(arg2) + 2;
3626 arg = os_malloc(len);
3629 os_snprintf(arg, len, "%s %s", arg1, arg2);
3630 res = os_exec(program, arg, 1);
3637 static void wpa_cli_action_process(const char *msg)
3640 char *copy = NULL, *id, *pos2;
3641 const char *ifname = ctrl_ifname;
3642 char ifname_buf[100];
3644 if (eloop_terminated())
3648 if (os_strncmp(pos, "IFNAME=", 7) == 0) {
3650 end = os_strchr(pos + 7, ' ');
3651 if (end && (unsigned int) (end - pos) < sizeof(ifname_buf)) {
3653 os_memcpy(ifname_buf, pos, end - pos);
3654 ifname_buf[end - pos] = '\0';
3655 ifname = ifname_buf;
3660 const char *prev = pos;
3662 pos = os_strchr(pos, '>');
3669 if (str_match(pos, WPA_EVENT_CONNECTED)) {
3671 os_unsetenv("WPA_ID");
3672 os_unsetenv("WPA_ID_STR");
3673 os_unsetenv("WPA_CTRL_DIR");
3675 pos = os_strstr(pos, "[id=");
3677 copy = os_strdup(pos + 4);
3681 while (*pos2 && *pos2 != ' ')
3685 os_setenv("WPA_ID", id, 1);
3686 while (*pos2 && *pos2 != '=')
3691 while (*pos2 && *pos2 != ']')
3694 os_setenv("WPA_ID_STR", id, 1);
3698 os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
3700 if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) {
3701 wpa_cli_connected = 1;
3702 wpa_cli_last_id = new_id;
3703 wpa_cli_exec(action_file, ifname, "CONNECTED");
3705 } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
3706 if (wpa_cli_connected) {
3707 wpa_cli_connected = 0;
3708 wpa_cli_exec(action_file, ifname, "DISCONNECTED");
3710 } else if (str_match(pos, AP_EVENT_ENABLED)) {
3711 wpa_cli_exec(action_file, ctrl_ifname, pos);
3712 } else if (str_match(pos, AP_EVENT_DISABLED)) {
3713 wpa_cli_exec(action_file, ctrl_ifname, pos);
3714 } else if (str_match(pos, MESH_GROUP_STARTED)) {
3715 wpa_cli_exec(action_file, ctrl_ifname, pos);
3716 } else if (str_match(pos, MESH_GROUP_REMOVED)) {
3717 wpa_cli_exec(action_file, ctrl_ifname, pos);
3718 } else if (str_match(pos, MESH_PEER_CONNECTED)) {
3719 wpa_cli_exec(action_file, ctrl_ifname, pos);
3720 } else if (str_match(pos, MESH_PEER_DISCONNECTED)) {
3721 wpa_cli_exec(action_file, ctrl_ifname, pos);
3722 } else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
3723 wpa_cli_exec(action_file, ifname, pos);
3724 } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
3725 wpa_cli_exec(action_file, ifname, pos);
3726 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
3727 wpa_cli_exec(action_file, ifname, pos);
3728 } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
3729 wpa_cli_exec(action_file, ifname, pos);
3730 } else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
3731 wpa_cli_exec(action_file, ifname, pos);
3732 } else if (str_match(pos, WPS_EVENT_SUCCESS)) {
3733 wpa_cli_exec(action_file, ifname, pos);
3734 } else if (str_match(pos, WPS_EVENT_FAIL)) {
3735 wpa_cli_exec(action_file, ifname, pos);
3736 } else if (str_match(pos, AP_STA_CONNECTED)) {
3737 wpa_cli_exec(action_file, ifname, pos);
3738 } else if (str_match(pos, AP_STA_DISCONNECTED)) {
3739 wpa_cli_exec(action_file, ifname, pos);
3740 } else if (str_match(pos, ESS_DISASSOC_IMMINENT)) {
3741 wpa_cli_exec(action_file, ifname, pos);
3742 } else if (str_match(pos, HS20_SUBSCRIPTION_REMEDIATION)) {
3743 wpa_cli_exec(action_file, ifname, pos);
3744 } else if (str_match(pos, HS20_DEAUTH_IMMINENT_NOTICE)) {
3745 wpa_cli_exec(action_file, ifname, pos);
3746 } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
3747 printf("wpa_supplicant is terminating - stop monitoring\n");
3753 #ifndef CONFIG_ANSI_C_EXTRA
3754 static void wpa_cli_action_cb(char *msg, size_t len)
3756 wpa_cli_action_process(msg);
3758 #endif /* CONFIG_ANSI_C_EXTRA */
3761 static void wpa_cli_reconnect(void)
3763 wpa_cli_close_connection();
3764 if (wpa_cli_open_connection(ctrl_ifname, 1) < 0)
3769 printf("\rConnection to wpa_supplicant re-established\n");
3775 static void cli_event(const char *str)
3777 const char *start, *s;
3779 start = os_strchr(str, '>');
3785 if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
3786 s = os_strchr(start, ' ');
3789 s = os_strchr(s + 1, ' ');
3792 cli_txt_list_add(&bsses, s + 1);
3796 if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
3797 s = os_strchr(start, ' ');
3800 s = os_strchr(s + 1, ' ');
3803 cli_txt_list_del_addr(&bsses, s + 1);
3808 if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
3809 s = os_strstr(start, " p2p_dev_addr=");
3812 cli_txt_list_add_addr(&p2p_peers, s + 14);
3816 if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
3817 s = os_strstr(start, " p2p_dev_addr=");
3820 cli_txt_list_del_addr(&p2p_peers, s + 14);
3824 if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
3825 s = os_strchr(start, ' ');
3828 cli_txt_list_add_word(&p2p_groups, s + 1, ' ');
3832 if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
3833 s = os_strchr(start, ' ');
3836 cli_txt_list_del_word(&p2p_groups, s + 1, ' ');
3839 #endif /* CONFIG_P2P */
3843 static int check_terminating(const char *msg)
3845 const char *pos = msg;
3849 pos = os_strchr(pos, '>');
3856 if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
3858 printf("\rConnection to wpa_supplicant lost - trying to "
3861 wpa_cli_attached = 0;
3862 wpa_cli_close_connection();
3870 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
3872 if (ctrl_conn == NULL) {
3873 wpa_cli_reconnect();
3876 while (wpa_ctrl_pending(ctrl) > 0) {
3878 size_t len = sizeof(buf) - 1;
3879 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
3882 wpa_cli_action_process(buf);
3885 if (wpa_cli_show_event(buf)) {
3887 printf("\r%s\n", buf);
3891 if (interactive && check_terminating(buf) > 0)
3895 printf("Could not read pending message.\n");
3900 if (wpa_ctrl_pending(ctrl) < 0) {
3901 printf("Connection to wpa_supplicant lost - trying to "
3903 wpa_cli_reconnect();
3909 static int tokenize_cmd(char *cmd, char *argv[])
3922 if (argc == max_args)
3925 char *pos2 = os_strrchr(pos, '"');
3929 while (*pos != '\0' && *pos != ' ')
3939 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
3943 char *prefix = ifname_prefix;
3945 ifname_prefix = NULL;
3946 res = _wpa_ctrl_command(ctrl_conn, "PING", 0);
3947 ifname_prefix = prefix;
3949 printf("Connection to wpa_supplicant lost - trying to "
3951 wpa_cli_close_connection();
3955 wpa_cli_reconnect();
3956 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
3960 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
3962 wpa_cli_recv_pending(mon_conn, 0);
3966 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
3968 char *argv[max_args];
3970 argc = tokenize_cmd(cmd, argv);
3972 wpa_request(ctrl_conn, argc, argv);
3976 static void wpa_cli_edit_eof_cb(void *ctx)
3982 static int warning_displayed = 0;
3983 static char *hfile = NULL;
3984 static int edit_started = 0;
3986 static void start_edit(void)
3991 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
3992 ps = wpa_ctrl_get_remote_ifname(ctrl_conn);
3993 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
3995 #ifdef CONFIG_WPA_CLI_HISTORY_DIR
3996 home = CONFIG_WPA_CLI_HISTORY_DIR;
3997 #else /* CONFIG_WPA_CLI_HISTORY_DIR */
3998 home = getenv("HOME");
3999 #endif /* CONFIG_WPA_CLI_HISTORY_DIR */
4001 const char *fname = ".wpa_cli_history";
4002 int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
4003 hfile = os_malloc(hfile_len);
4005 os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
4008 if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
4009 wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
4015 eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
4019 static void update_bssid_list(struct wpa_ctrl *ctrl)
4022 size_t len = sizeof(buf);
4024 char *cmd = "BSS RANGE=ALL MASK=0x2";
4029 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
4036 pos = os_strstr(pos, "bssid=");
4040 end = os_strchr(pos, '\n');
4044 cli_txt_list_add(&bsses, pos);
4050 static void update_ifnames(struct wpa_ctrl *ctrl)
4053 size_t len = sizeof(buf);
4055 char *cmd = "INTERFACES";
4059 cli_txt_list_flush(&ifnames);
4063 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
4070 end = os_strchr(pos, '\n');
4074 ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos);
4075 if (!os_snprintf_error(sizeof(txt), ret))
4076 cli_txt_list_add(&ifnames, txt);
4082 static void update_networks(struct wpa_ctrl *ctrl)
4085 size_t len = sizeof(buf);
4087 char *cmd = "LIST_NETWORKS";
4091 cli_txt_list_flush(&networks);
4095 ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
4102 end = os_strchr(pos, '\n');
4107 cli_txt_list_add_word(&networks, pos, '\t');
4114 static void try_connection(void *eloop_ctx, void *timeout_ctx)
4119 if (ctrl_ifname == NULL)
4120 ctrl_ifname = wpa_cli_get_default_ifname();
4122 if (wpa_cli_open_connection(ctrl_ifname, 1)) {
4123 if (!warning_displayed) {
4124 printf("Could not connect to wpa_supplicant: "
4126 ctrl_ifname ? ctrl_ifname : "(nil)");
4127 warning_displayed = 1;
4129 eloop_register_timeout(1, 0, try_connection, NULL, NULL);
4133 update_bssid_list(ctrl_conn);
4134 update_networks(ctrl_conn);
4136 if (warning_displayed)
4137 printf("Connection established.\n");
4144 static void wpa_cli_interactive(void)
4146 printf("\nInteractive mode\n\n");
4148 eloop_register_timeout(0, 0, try_connection, NULL, NULL);
4150 eloop_cancel_timeout(try_connection, NULL, NULL);
4152 cli_txt_list_flush(&p2p_peers);
4153 cli_txt_list_flush(&p2p_groups);
4154 cli_txt_list_flush(&bsses);
4155 cli_txt_list_flush(&ifnames);
4156 cli_txt_list_flush(&networks);
4158 edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
4160 eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
4161 wpa_cli_close_connection();
4165 static void wpa_cli_action_ping(void *eloop_ctx, void *timeout_ctx)
4167 struct wpa_ctrl *ctrl = eloop_ctx;
4171 /* verify that connection is still working */
4172 len = sizeof(buf) - 1;
4173 if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
4174 wpa_cli_action_cb) < 0 ||
4175 len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
4176 printf("wpa_supplicant did not reply to PING command - exiting\n");
4180 eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping,
4185 static void wpa_cli_action_receive(int sock, void *eloop_ctx, void *sock_ctx)
4187 struct wpa_ctrl *ctrl = eloop_ctx;
4189 wpa_cli_recv_pending(ctrl, 1);
4193 static void wpa_cli_action(struct wpa_ctrl *ctrl)
4195 #ifdef CONFIG_ANSI_C_EXTRA
4196 /* TODO: ANSI C version(?) */
4197 printf("Action processing not supported in ANSI C build.\n");
4198 #else /* CONFIG_ANSI_C_EXTRA */
4201 fd = wpa_ctrl_get_fd(ctrl);
4202 eloop_register_timeout(ping_interval, 0, wpa_cli_action_ping,
4204 eloop_register_read_sock(fd, wpa_cli_action_receive, ctrl, NULL);
4206 eloop_cancel_timeout(wpa_cli_action_ping, ctrl, NULL);
4207 eloop_unregister_read_sock(fd);
4208 #endif /* CONFIG_ANSI_C_EXTRA */
4212 static void wpa_cli_cleanup(void)
4214 wpa_cli_close_connection();
4216 os_daemonize_terminate(pid_file);
4218 os_program_deinit();
4222 static void wpa_cli_terminate(int sig, void *ctx)
4228 static char * wpa_cli_get_default_ifname(void)
4230 char *ifname = NULL;
4233 char ifprop[PROPERTY_VALUE_MAX];
4234 if (property_get("wifi.interface", ifprop, NULL) != 0) {
4235 ifname = os_strdup(ifprop);
4236 printf("Using interface '%s'\n", ifname ? ifname : "N/A");
4239 #ifdef CONFIG_CTRL_IFACE_UNIX
4240 struct dirent *dent;
4241 DIR *dir = opendir(ctrl_iface_dir);
4245 while ((dent = readdir(dir))) {
4246 #ifdef _DIRENT_HAVE_D_TYPE
4248 * Skip the file if it is not a socket. Also accept
4249 * DT_UNKNOWN (0) in case the C library or underlying
4250 * file system does not support d_type.
4252 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
4254 #endif /* _DIRENT_HAVE_D_TYPE */
4255 if (os_strcmp(dent->d_name, ".") == 0 ||
4256 os_strcmp(dent->d_name, "..") == 0)
4258 printf("Selected interface '%s'\n", dent->d_name);
4259 ifname = os_strdup(dent->d_name);
4263 #endif /* CONFIG_CTRL_IFACE_UNIX */
4265 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
4266 char buf[4096], *pos;
4268 struct wpa_ctrl *ctrl;
4271 ctrl = wpa_ctrl_open(NULL);
4275 len = sizeof(buf) - 1;
4276 ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
4279 pos = os_strchr(buf, '\n');
4282 ifname = os_strdup(buf);
4284 wpa_ctrl_close(ctrl);
4285 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4286 #endif /* ANDROID */
4292 int main(int argc, char *argv[])
4297 const char *global = NULL;
4299 if (os_program_init())
4303 c = getopt(argc, argv, "a:Bg:G:hi:p:P:s:v");
4308 action_file = optarg;
4317 ping_interval = atoi(optarg);
4323 printf("%s\n", wpa_cli_version);
4326 os_free(ctrl_ifname);
4327 ctrl_ifname = os_strdup(optarg);
4330 ctrl_iface_dir = optarg;
4336 client_socket_dir = optarg;
4344 interactive = (argc == optind) && (action_file == NULL);
4347 printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
4353 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
4354 ctrl_conn = wpa_ctrl_open(NULL);
4355 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4356 ctrl_conn = wpa_ctrl_open(global);
4357 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
4358 if (ctrl_conn == NULL) {
4359 fprintf(stderr, "Failed to connect to wpa_supplicant "
4360 "global interface: %s error: %s\n",
4361 global, strerror(errno));
4366 update_ifnames(ctrl_conn);
4367 mon_conn = wpa_ctrl_open(global);
4369 if (wpa_ctrl_attach(mon_conn) == 0) {
4370 wpa_cli_attached = 1;
4371 eloop_register_read_sock(
4372 wpa_ctrl_get_fd(mon_conn),
4373 wpa_cli_mon_receive,
4376 printf("Failed to open monitor "
4377 "connection through global "
4378 "control interface\n");
4384 eloop_register_signal_terminate(wpa_cli_terminate, NULL);
4386 if (ctrl_ifname == NULL)
4387 ctrl_ifname = wpa_cli_get_default_ifname();
4390 wpa_cli_interactive();
4393 wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
4394 fprintf(stderr, "Failed to connect to non-global "
4395 "ctrl_ifname: %s error: %s\n",
4396 ctrl_ifname ? ctrl_ifname : "(nil)",
4402 if (wpa_ctrl_attach(ctrl_conn) == 0) {
4403 wpa_cli_attached = 1;
4405 printf("Warning: Failed to attach to "
4406 "wpa_supplicant.\n");
4411 if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue())
4415 wpa_cli_action(ctrl_conn);
4417 ret = wpa_request(ctrl_conn, argc - optind,
4421 os_free(ctrl_ifname);
4428 #else /* CONFIG_CTRL_IFACE */
4429 int main(int argc, char *argv[])
4431 printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
4434 #endif /* CONFIG_CTRL_IFACE */