Home | History | Annotate | Download | only in wpa_supplicant
      1 /*
      2  * WPA Supplicant - command line interface for wpa_supplicant daemon
      3  * Copyright (c) 2004-2013, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "includes.h"
     10 
     11 #ifdef CONFIG_CTRL_IFACE
     12 
     13 #ifdef CONFIG_CTRL_IFACE_UNIX
     14 #include <dirent.h>
     15 #endif /* CONFIG_CTRL_IFACE_UNIX */
     16 
     17 #include "common/wpa_ctrl.h"
     18 #include "utils/common.h"
     19 #include "utils/eloop.h"
     20 #include "utils/edit.h"
     21 #include "utils/list.h"
     22 #include "common/version.h"
     23 #include "common/ieee802_11_defs.h"
     24 #ifdef ANDROID
     25 #include <cutils/properties.h>
     26 #endif /* ANDROID */
     27 
     28 
     29 static const char *wpa_cli_version =
     30 "wpa_cli v" VERSION_STR "\n"
     31 "Copyright (c) 2004-2013, Jouni Malinen <j (at) w1.fi> and contributors";
     32 
     33 
     34 static const char *wpa_cli_license =
     35 "This software may be distributed under the terms of the BSD license.\n"
     36 "See README for more details.\n";
     37 
     38 static const char *wpa_cli_full_license =
     39 "This software may be distributed under the terms of the BSD license.\n"
     40 "\n"
     41 "Redistribution and use in source and binary forms, with or without\n"
     42 "modification, are permitted provided that the following conditions are\n"
     43 "met:\n"
     44 "\n"
     45 "1. Redistributions of source code must retain the above copyright\n"
     46 "   notice, this list of conditions and the following disclaimer.\n"
     47 "\n"
     48 "2. Redistributions in binary form must reproduce the above copyright\n"
     49 "   notice, this list of conditions and the following disclaimer in the\n"
     50 "   documentation and/or other materials provided with the distribution.\n"
     51 "\n"
     52 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
     53 "   names of its contributors may be used to endorse or promote products\n"
     54 "   derived from this software without specific prior written permission.\n"
     55 "\n"
     56 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
     57 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
     58 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
     59 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
     60 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
     61 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
     62 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
     63 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
     64 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
     65 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
     66 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
     67 "\n";
     68 
     69 static struct wpa_ctrl *ctrl_conn;
     70 static struct wpa_ctrl *mon_conn;
     71 static int wpa_cli_quit = 0;
     72 static int wpa_cli_attached = 0;
     73 static int wpa_cli_connected = -1;
     74 static int wpa_cli_last_id = 0;
     75 #ifndef CONFIG_CTRL_IFACE_DIR
     76 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
     77 #endif /* CONFIG_CTRL_IFACE_DIR */
     78 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
     79 static char *ctrl_ifname = NULL;
     80 static const char *pid_file = NULL;
     81 static const char *action_file = NULL;
     82 static int ping_interval = 5;
     83 static int interactive = 0;
     84 static char *ifname_prefix = NULL;
     85 
     86 struct cli_txt_entry {
     87 	struct dl_list list;
     88 	char *txt;
     89 };
     90 
     91 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
     92 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
     93 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
     94 static DEFINE_DL_LIST(ifnames); /* struct cli_txt_entry */
     95 
     96 
     97 static void print_help(const char *cmd);
     98 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx);
     99 static void wpa_cli_close_connection(void);
    100 static char * wpa_cli_get_default_ifname(void);
    101 static char ** wpa_list_cmd_list(void);
    102 
    103 
    104 static void usage(void)
    105 {
    106 	printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
    107 	       "[-a<action file>] \\\n"
    108 	       "        [-P<pid file>] [-g<global ctrl>] [-G<ping interval>]  "
    109 	       "[command..]\n"
    110 	       "  -h = help (show this usage text)\n"
    111 	       "  -v = shown version information\n"
    112 	       "  -a = run in daemon mode executing the action file based on "
    113 	       "events from\n"
    114 	       "       wpa_supplicant\n"
    115 	       "  -B = run a daemon in the background\n"
    116 	       "  default path: " CONFIG_CTRL_IFACE_DIR "\n"
    117 	       "  default interface: first interface found in socket path\n");
    118 	print_help(NULL);
    119 }
    120 
    121 
    122 static void cli_txt_list_free(struct cli_txt_entry *e)
    123 {
    124 	dl_list_del(&e->list);
    125 	os_free(e->txt);
    126 	os_free(e);
    127 }
    128 
    129 
    130 static void cli_txt_list_flush(struct dl_list *list)
    131 {
    132 	struct cli_txt_entry *e;
    133 	while ((e = dl_list_first(list, struct cli_txt_entry, list)))
    134 		cli_txt_list_free(e);
    135 }
    136 
    137 
    138 static struct cli_txt_entry * cli_txt_list_get(struct dl_list *txt_list,
    139 					       const char *txt)
    140 {
    141 	struct cli_txt_entry *e;
    142 	dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
    143 		if (os_strcmp(e->txt, txt) == 0)
    144 			return e;
    145 	}
    146 	return NULL;
    147 }
    148 
    149 
    150 static void cli_txt_list_del(struct dl_list *txt_list, const char *txt)
    151 {
    152 	struct cli_txt_entry *e;
    153 	e = cli_txt_list_get(txt_list, txt);
    154 	if (e)
    155 		cli_txt_list_free(e);
    156 }
    157 
    158 
    159 static void cli_txt_list_del_addr(struct dl_list *txt_list, const char *txt)
    160 {
    161 	u8 addr[ETH_ALEN];
    162 	char buf[18];
    163 	if (hwaddr_aton(txt, addr) < 0)
    164 		return;
    165 	os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
    166 	cli_txt_list_del(txt_list, buf);
    167 }
    168 
    169 
    170 #ifdef CONFIG_P2P
    171 static void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt)
    172 {
    173 	const char *end;
    174 	char *buf;
    175 	end = os_strchr(txt, ' ');
    176 	if (end == NULL)
    177 		end = txt + os_strlen(txt);
    178 	buf = dup_binstr(txt, end - txt);
    179 	if (buf == NULL)
    180 		return;
    181 	cli_txt_list_del(txt_list, buf);
    182 	os_free(buf);
    183 }
    184 #endif /* CONFIG_P2P */
    185 
    186 
    187 static int cli_txt_list_add(struct dl_list *txt_list, const char *txt)
    188 {
    189 	struct cli_txt_entry *e;
    190 	e = cli_txt_list_get(txt_list, txt);
    191 	if (e)
    192 		return 0;
    193 	e = os_zalloc(sizeof(*e));
    194 	if (e == NULL)
    195 		return -1;
    196 	e->txt = os_strdup(txt);
    197 	if (e->txt == NULL) {
    198 		os_free(e);
    199 		return -1;
    200 	}
    201 	dl_list_add(txt_list, &e->list);
    202 	return 0;
    203 }
    204 
    205 
    206 #ifdef CONFIG_P2P
    207 static int cli_txt_list_add_addr(struct dl_list *txt_list, const char *txt)
    208 {
    209 	u8 addr[ETH_ALEN];
    210 	char buf[18];
    211 	if (hwaddr_aton(txt, addr) < 0)
    212 		return -1;
    213 	os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
    214 	return cli_txt_list_add(txt_list, buf);
    215 }
    216 
    217 
    218 static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt)
    219 {
    220 	const char *end;
    221 	char *buf;
    222 	int ret;
    223 	end = os_strchr(txt, ' ');
    224 	if (end == NULL)
    225 		end = txt + os_strlen(txt);
    226 	buf = dup_binstr(txt, end - txt);
    227 	if (buf == NULL)
    228 		return -1;
    229 	ret = cli_txt_list_add(txt_list, buf);
    230 	os_free(buf);
    231 	return ret;
    232 }
    233 #endif /* CONFIG_P2P */
    234 
    235 
    236 static char ** cli_txt_list_array(struct dl_list *txt_list)
    237 {
    238 	unsigned int i, count = dl_list_len(txt_list);
    239 	char **res;
    240 	struct cli_txt_entry *e;
    241 
    242 	res = os_calloc(count + 1, sizeof(char *));
    243 	if (res == NULL)
    244 		return NULL;
    245 
    246 	i = 0;
    247 	dl_list_for_each(e, txt_list, struct cli_txt_entry, list) {
    248 		res[i] = os_strdup(e->txt);
    249 		if (res[i] == NULL)
    250 			break;
    251 		i++;
    252 	}
    253 
    254 	return res;
    255 }
    256 
    257 
    258 static int get_cmd_arg_num(const char *str, int pos)
    259 {
    260 	int arg = 0, i;
    261 
    262 	for (i = 0; i <= pos; i++) {
    263 		if (str[i] != ' ') {
    264 			arg++;
    265 			while (i <= pos && str[i] != ' ')
    266 				i++;
    267 		}
    268 	}
    269 
    270 	if (arg > 0)
    271 		arg--;
    272 	return arg;
    273 }
    274 
    275 
    276 static int str_starts(const char *src, const char *match)
    277 {
    278 	return os_strncmp(src, match, os_strlen(match)) == 0;
    279 }
    280 
    281 
    282 static int wpa_cli_show_event(const char *event)
    283 {
    284 	const char *start;
    285 
    286 	start = os_strchr(event, '>');
    287 	if (start == NULL)
    288 		return 1;
    289 
    290 	start++;
    291 	/*
    292 	 * Skip BSS added/removed events since they can be relatively frequent
    293 	 * and are likely of not much use for an interactive user.
    294 	 */
    295 	if (str_starts(start, WPA_EVENT_BSS_ADDED) ||
    296 	    str_starts(start, WPA_EVENT_BSS_REMOVED))
    297 		return 0;
    298 
    299 	return 1;
    300 }
    301 
    302 
    303 static int wpa_cli_open_connection(const char *ifname, int attach)
    304 {
    305 #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
    306 	ctrl_conn = wpa_ctrl_open(ifname);
    307 	if (ctrl_conn == NULL)
    308 		return -1;
    309 
    310 	if (attach && interactive)
    311 		mon_conn = wpa_ctrl_open(ifname);
    312 	else
    313 		mon_conn = NULL;
    314 #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
    315 	char *cfile = NULL;
    316 	int flen, res;
    317 
    318 	if (ifname == NULL)
    319 		return -1;
    320 
    321 #ifdef ANDROID
    322 	if (access(ctrl_iface_dir, F_OK) < 0) {
    323 		cfile = os_strdup(ifname);
    324 		if (cfile == NULL)
    325 			return -1;
    326 	}
    327 #endif /* ANDROID */
    328 
    329 	if (cfile == NULL) {
    330 		flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
    331 		cfile = os_malloc(flen);
    332 		if (cfile == NULL)
    333 			return -1;
    334 		res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir,
    335 				  ifname);
    336 		if (res < 0 || res >= flen) {
    337 			os_free(cfile);
    338 			return -1;
    339 		}
    340 	}
    341 
    342 	ctrl_conn = wpa_ctrl_open(cfile);
    343 	if (ctrl_conn == NULL) {
    344 		os_free(cfile);
    345 		return -1;
    346 	}
    347 
    348 	if (attach && interactive)
    349 		mon_conn = wpa_ctrl_open(cfile);
    350 	else
    351 		mon_conn = NULL;
    352 	os_free(cfile);
    353 #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
    354 
    355 	if (mon_conn) {
    356 		if (wpa_ctrl_attach(mon_conn) == 0) {
    357 			wpa_cli_attached = 1;
    358 			if (interactive)
    359 				eloop_register_read_sock(
    360 					wpa_ctrl_get_fd(mon_conn),
    361 					wpa_cli_mon_receive, NULL, NULL);
    362 		} else {
    363 			printf("Warning: Failed to attach to "
    364 			       "wpa_supplicant.\n");
    365 			wpa_cli_close_connection();
    366 			return -1;
    367 		}
    368 	}
    369 
    370 	return 0;
    371 }
    372 
    373 
    374 static void wpa_cli_close_connection(void)
    375 {
    376 	if (ctrl_conn == NULL)
    377 		return;
    378 
    379 	if (wpa_cli_attached) {
    380 		wpa_ctrl_detach(interactive ? mon_conn : ctrl_conn);
    381 		wpa_cli_attached = 0;
    382 	}
    383 	wpa_ctrl_close(ctrl_conn);
    384 	ctrl_conn = NULL;
    385 	if (mon_conn) {
    386 		eloop_unregister_read_sock(wpa_ctrl_get_fd(mon_conn));
    387 		wpa_ctrl_close(mon_conn);
    388 		mon_conn = NULL;
    389 	}
    390 }
    391 
    392 
    393 static void wpa_cli_msg_cb(char *msg, size_t len)
    394 {
    395 	printf("%s\n", msg);
    396 }
    397 
    398 
    399 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
    400 {
    401 	char buf[4096];
    402 	size_t len;
    403 	int ret;
    404 
    405 	if (ctrl_conn == NULL) {
    406 		printf("Not connected to wpa_supplicant - command dropped.\n");
    407 		return -1;
    408 	}
    409 	if (ifname_prefix) {
    410 		os_snprintf(buf, sizeof(buf), "IFNAME=%s %s",
    411 			    ifname_prefix, cmd);
    412 		buf[sizeof(buf) - 1] = '\0';
    413 		cmd = buf;
    414 	}
    415 	len = sizeof(buf) - 1;
    416 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
    417 			       wpa_cli_msg_cb);
    418 	if (ret == -2) {
    419 		printf("'%s' command timed out.\n", cmd);
    420 		return -2;
    421 	} else if (ret < 0) {
    422 		printf("'%s' command failed.\n", cmd);
    423 		return -1;
    424 	}
    425 	if (print) {
    426 		buf[len] = '\0';
    427 		printf("%s", buf);
    428 		if (interactive && len > 0 && buf[len - 1] != '\n')
    429 			printf("\n");
    430 	}
    431 	return 0;
    432 }
    433 
    434 
    435 static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
    436 {
    437 	return _wpa_ctrl_command(ctrl, cmd, 1);
    438 }
    439 
    440 
    441 static int write_cmd(char *buf, size_t buflen, const char *cmd, int argc,
    442 		     char *argv[])
    443 {
    444 	int i, res;
    445 	char *pos, *end;
    446 
    447 	pos = buf;
    448 	end = buf + buflen;
    449 
    450 	res = os_snprintf(pos, end - pos, "%s", cmd);
    451 	if (res < 0 || res >= end - pos)
    452 		goto fail;
    453 	pos += res;
    454 
    455 	for (i = 0; i < argc; i++) {
    456 		res = os_snprintf(pos, end - pos, " %s", argv[i]);
    457 		if (res < 0 || res >= end - pos)
    458 			goto fail;
    459 		pos += res;
    460 	}
    461 
    462 	buf[buflen - 1] = '\0';
    463 	return 0;
    464 
    465 fail:
    466 	printf("Too long command\n");
    467 	return -1;
    468 }
    469 
    470 
    471 static int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args,
    472 		       int argc, char *argv[])
    473 {
    474 	char buf[4096];
    475 	if (argc < min_args) {
    476 		printf("Invalid %s command - at least %d argument%s "
    477 		       "required.\n", cmd, min_args,
    478 		       min_args > 1 ? "s are" : " is");
    479 		return -1;
    480 	}
    481 	if (write_cmd(buf, sizeof(buf), cmd, argc, argv) < 0)
    482 		return -1;
    483 	return wpa_ctrl_command(ctrl, buf);
    484 }
    485 
    486 
    487 static int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[])
    488 {
    489 	return wpa_ctrl_command(ctrl, "IFNAME");
    490 }
    491 
    492 
    493 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
    494 {
    495 	if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
    496 		return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
    497 	if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
    498 		return wpa_ctrl_command(ctrl, "STATUS-WPS");
    499 	return wpa_ctrl_command(ctrl, "STATUS");
    500 }
    501 
    502 
    503 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
    504 {
    505 	return wpa_ctrl_command(ctrl, "PING");
    506 }
    507 
    508 
    509 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
    510 {
    511 	return wpa_ctrl_command(ctrl, "RELOG");
    512 }
    513 
    514 
    515 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
    516 {
    517 	return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv);
    518 }
    519 
    520 
    521 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
    522 {
    523 	return wpa_ctrl_command(ctrl, "MIB");
    524 }
    525 
    526 
    527 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
    528 {
    529 	return wpa_ctrl_command(ctrl, "PMKSA");
    530 }
    531 
    532 
    533 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
    534 {
    535 	print_help(argc > 0 ? argv[0] : NULL);
    536 	return 0;
    537 }
    538 
    539 
    540 static char ** wpa_cli_complete_help(const char *str, int pos)
    541 {
    542 	int arg = get_cmd_arg_num(str, pos);
    543 	char **res = NULL;
    544 
    545 	switch (arg) {
    546 	case 1:
    547 		res = wpa_list_cmd_list();
    548 		break;
    549 	}
    550 
    551 	return res;
    552 }
    553 
    554 
    555 static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
    556 {
    557 	printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
    558 	return 0;
    559 }
    560 
    561 
    562 static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
    563 {
    564 	wpa_cli_quit = 1;
    565 	if (interactive)
    566 		eloop_terminate();
    567 	return 0;
    568 }
    569 
    570 
    571 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
    572 {
    573 	char cmd[256];
    574 	int res;
    575 
    576 	if (argc == 1) {
    577 		res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
    578 		if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    579 			printf("Too long SET command.\n");
    580 			return -1;
    581 		}
    582 		return wpa_ctrl_command(ctrl, cmd);
    583 	}
    584 
    585 	return wpa_cli_cmd(ctrl, "SET", 2, argc, argv);
    586 }
    587 
    588 
    589 static char ** wpa_cli_complete_set(const char *str, int pos)
    590 {
    591 	int arg = get_cmd_arg_num(str, pos);
    592 	const char *fields[] = {
    593 		/* runtime values */
    594 		"EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod",
    595 		"EAPOL::maxStart", "dot11RSNAConfigPMKLifetime",
    596 		"dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout",
    597 		"wps_fragment_size", "wps_version_number", "ampdu",
    598 		"tdls_testing", "tdls_disabled", "pno", "radio_disabled",
    599 		"uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps",
    600 		"no_keep_alive",
    601 		/* global configuration parameters */
    602 		"eapol_version", "ap_scan", "disable_scan_offload",
    603 		"fast_reauth", "opensc_engine_path", "pkcs11_engine_path",
    604 		"pkcs11_module_path", "pcsc_reader", "pcsc_pin",
    605 		"driver_param", "dot11RSNAConfigPMKLifetime",
    606 		"dot11RSNAConfigPMKReauthThreshold",
    607 		"dot11RSNAConfigSATimeout",
    608 		"update_config", "load_dynamic_eap", "uuid", "device_name",
    609 		"manufacturer", "model_name", "model_number", "serial_number",
    610 		"device_type", "os_version", "config_methods",
    611 		"wps_cred_processing", "wps_vendor_ext_m1", "sec_device_type",
    612 		"p2p_listen_reg_class", "p2p_listen_channel",
    613 		"p2p_oper_reg_class", "p2p_oper_channel",
    614 		"p2p_go_intent", "p2p_ssid_postfix", "persistent_reconnect",
    615 		"p2p_intra_bss", "p2p_group_idle", "p2p_pref_chan",
    616 		"p2p_go_ht40", "p2p_disabled", "p2p_no_group_iface",
    617 		"p2p_ignore_shared_freq", "country", "bss_max_count",
    618 		"bss_expiration_age", "bss_expiration_scan_count",
    619 		"filter_ssids", "filter_rssi", "max_num_sta",
    620 		"disassoc_low_ack", "hs20", "interworking", "hessid",
    621 		"access_network_type", "pbc_in_m1", "autoscan",
    622 		"wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey", "wps_nfc_dh_privkey",
    623 		"wps_nfc_dev_pw", "ext_password_backend",
    624 		"p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
    625 		"sae_groups", "dtim_period", "beacon_int", "ap_vendor_elements",
    626 		"ignore_old_scan_res", "freq_list"
    627 	};
    628 	int i, num_fields = sizeof(fields) / sizeof(fields[0]);
    629 
    630 	if (arg == 1) {
    631 		char **res = os_calloc(num_fields + 1, sizeof(char *));
    632 		if (res == NULL)
    633 			return NULL;
    634 		for (i = 0; i < num_fields; i++) {
    635 			res[i] = os_strdup(fields[i]);
    636 			if (res[i] == NULL)
    637 				return res;
    638 		}
    639 		return res;
    640 	}
    641 
    642 	if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0)
    643 		return cli_txt_list_array(&bsses);
    644 
    645 	return NULL;
    646 }
    647 
    648 
    649 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
    650 {
    651 	return wpa_cli_cmd(ctrl, "GET", 1, argc, argv);
    652 }
    653 
    654 
    655 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
    656 {
    657 	return wpa_ctrl_command(ctrl, "LOGOFF");
    658 }
    659 
    660 
    661 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
    662 {
    663 	return wpa_ctrl_command(ctrl, "LOGON");
    664 }
    665 
    666 
    667 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
    668 				   char *argv[])
    669 {
    670 	return wpa_ctrl_command(ctrl, "REASSOCIATE");
    671 }
    672 
    673 
    674 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
    675 				       char *argv[])
    676 {
    677 	return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv);
    678 }
    679 
    680 
    681 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
    682 {
    683 	return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv);
    684 }
    685 
    686 
    687 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
    688 				     char *argv[])
    689 {
    690 	return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv);
    691 }
    692 
    693 
    694 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
    695 				      char *argv[])
    696 {
    697 	return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv);
    698 }
    699 
    700 
    701 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
    702 				        char *argv[])
    703 {
    704 	return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv);
    705 }
    706 
    707 
    708 static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
    709 {
    710 	char cmd[256];
    711 	int res;
    712 
    713 	if (argc < 1)
    714 		res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0");
    715 	else
    716 		res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]);
    717 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    718 		printf("Too long BSS_FLUSH command.\n");
    719 		return -1;
    720 	}
    721 	return wpa_ctrl_command(ctrl, cmd);
    722 }
    723 
    724 
    725 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
    726 				char *argv[])
    727 {
    728 	return wpa_cli_cmd(ctrl, "STKSTART", 1, argc, argv);
    729 }
    730 
    731 
    732 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
    733 {
    734 	return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv);
    735 }
    736 
    737 
    738 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
    739 {
    740 	return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv);
    741 }
    742 
    743 
    744 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
    745 {
    746 	if (argc == 0) {
    747 		printf("Invalid WPS_PIN command: need one or two arguments:\n"
    748 		       "- BSSID: use 'any' to select any\n"
    749 		       "- PIN: optional, used only with devices that have no "
    750 		       "display\n");
    751 		return -1;
    752 	}
    753 
    754 	return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv);
    755 }
    756 
    757 
    758 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
    759 				     char *argv[])
    760 {
    761 	return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv);
    762 }
    763 
    764 
    765 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
    766 				  char *argv[])
    767 {
    768 	return wpa_ctrl_command(ctrl, "WPS_CANCEL");
    769 }
    770 
    771 
    772 #ifdef CONFIG_WPS_NFC
    773 
    774 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
    775 {
    776 	return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv);
    777 }
    778 
    779 
    780 static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
    781 					    char *argv[])
    782 {
    783 	return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
    784 }
    785 
    786 
    787 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
    788 				     char *argv[])
    789 {
    790 	return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv);
    791 }
    792 
    793 
    794 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
    795 					char *argv[])
    796 {
    797 	int ret;
    798 	char *buf;
    799 	size_t buflen;
    800 
    801 	if (argc != 1) {
    802 		printf("Invalid 'wps_nfc_tag_read' command - one argument "
    803 		       "is required.\n");
    804 		return -1;
    805 	}
    806 
    807 	buflen = 18 + os_strlen(argv[0]);
    808 	buf = os_malloc(buflen);
    809 	if (buf == NULL)
    810 		return -1;
    811 	os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
    812 
    813 	ret = wpa_ctrl_command(ctrl, buf);
    814 	os_free(buf);
    815 
    816 	return ret;
    817 }
    818 
    819 
    820 static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc,
    821 					    char *argv[])
    822 {
    823 	return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv);
    824 }
    825 
    826 
    827 static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc,
    828 					    char *argv[])
    829 {
    830 	return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv);
    831 }
    832 
    833 
    834 static int wpa_cli_cmd_nfc_rx_handover_req(struct wpa_ctrl *ctrl, int argc,
    835 					   char *argv[])
    836 {
    837 	int ret;
    838 	char *buf;
    839 	size_t buflen;
    840 
    841 	if (argc != 1) {
    842 		printf("Invalid 'nfc_rx_handover_req' command - one argument "
    843 		       "is required.\n");
    844 		return -1;
    845 	}
    846 
    847 	buflen = 21 + os_strlen(argv[0]);
    848 	buf = os_malloc(buflen);
    849 	if (buf == NULL)
    850 		return -1;
    851 	os_snprintf(buf, buflen, "NFC_RX_HANDOVER_REQ %s", argv[0]);
    852 
    853 	ret = wpa_ctrl_command(ctrl, buf);
    854 	os_free(buf);
    855 
    856 	return ret;
    857 }
    858 
    859 
    860 static int wpa_cli_cmd_nfc_rx_handover_sel(struct wpa_ctrl *ctrl, int argc,
    861 					   char *argv[])
    862 {
    863 	int ret;
    864 	char *buf;
    865 	size_t buflen;
    866 
    867 	if (argc != 1) {
    868 		printf("Invalid 'nfc_rx_handover_sel' command - one argument "
    869 		       "is required.\n");
    870 		return -1;
    871 	}
    872 
    873 	buflen = 21 + os_strlen(argv[0]);
    874 	buf = os_malloc(buflen);
    875 	if (buf == NULL)
    876 		return -1;
    877 	os_snprintf(buf, buflen, "NFC_RX_HANDOVER_SEL %s", argv[0]);
    878 
    879 	ret = wpa_ctrl_command(ctrl, buf);
    880 	os_free(buf);
    881 
    882 	return ret;
    883 }
    884 
    885 
    886 static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc,
    887 					   char *argv[])
    888 {
    889 	return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv);
    890 }
    891 
    892 #endif /* CONFIG_WPS_NFC */
    893 
    894 
    895 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
    896 {
    897 	char cmd[256];
    898 	int res;
    899 
    900 	if (argc == 2)
    901 		res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
    902 				  argv[0], argv[1]);
    903 	else if (argc == 5 || argc == 6) {
    904 		char ssid_hex[2 * 32 + 1];
    905 		char key_hex[2 * 64 + 1];
    906 		int i;
    907 
    908 		ssid_hex[0] = '\0';
    909 		for (i = 0; i < 32; i++) {
    910 			if (argv[2][i] == '\0')
    911 				break;
    912 			os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
    913 		}
    914 
    915 		key_hex[0] = '\0';
    916 		if (argc == 6) {
    917 			for (i = 0; i < 64; i++) {
    918 				if (argv[5][i] == '\0')
    919 					break;
    920 				os_snprintf(&key_hex[i * 2], 3, "%02x",
    921 					    argv[5][i]);
    922 			}
    923 		}
    924 
    925 		res = os_snprintf(cmd, sizeof(cmd),
    926 				  "WPS_REG %s %s %s %s %s %s",
    927 				  argv[0], argv[1], ssid_hex, argv[3], argv[4],
    928 				  key_hex);
    929 	} else {
    930 		printf("Invalid WPS_REG command: need two arguments:\n"
    931 		       "- BSSID of the target AP\n"
    932 		       "- AP PIN\n");
    933 		printf("Alternatively, six arguments can be used to "
    934 		       "reconfigure the AP:\n"
    935 		       "- BSSID of the target AP\n"
    936 		       "- AP PIN\n"
    937 		       "- new SSID\n"
    938 		       "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
    939 		       "- new encr (NONE, WEP, TKIP, CCMP)\n"
    940 		       "- new key\n");
    941 		return -1;
    942 	}
    943 
    944 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
    945 		printf("Too long WPS_REG command.\n");
    946 		return -1;
    947 	}
    948 	return wpa_ctrl_command(ctrl, cmd);
    949 }
    950 
    951 
    952 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
    953 				  char *argv[])
    954 {
    955 	return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv);
    956 }
    957 
    958 
    959 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
    960 				    char *argv[])
    961 {
    962 	return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv);
    963 }
    964 
    965 
    966 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
    967 				   char *argv[])
    968 {
    969 	return wpa_ctrl_command(ctrl, "WPS_ER_STOP");
    970 
    971 }
    972 
    973 
    974 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
    975 				  char *argv[])
    976 {
    977 	if (argc < 2) {
    978 		printf("Invalid WPS_ER_PIN command: need at least two "
    979 		       "arguments:\n"
    980 		       "- UUID: use 'any' to select any\n"
    981 		       "- PIN: Enrollee PIN\n"
    982 		       "optional: - Enrollee MAC address\n");
    983 		return -1;
    984 	}
    985 
    986 	return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv);
    987 }
    988 
    989 
    990 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
    991 				  char *argv[])
    992 {
    993 	return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv);
    994 }
    995 
    996 
    997 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
    998 				    char *argv[])
    999 {
   1000 	if (argc != 2) {
   1001 		printf("Invalid WPS_ER_LEARN command: need two arguments:\n"
   1002 		       "- UUID: specify which AP to use\n"
   1003 		       "- PIN: AP PIN\n");
   1004 		return -1;
   1005 	}
   1006 
   1007 	return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv);
   1008 }
   1009 
   1010 
   1011 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
   1012 					 char *argv[])
   1013 {
   1014 	if (argc != 2) {
   1015 		printf("Invalid WPS_ER_SET_CONFIG command: need two "
   1016 		       "arguments:\n"
   1017 		       "- UUID: specify which AP to use\n"
   1018 		       "- Network configuration id\n");
   1019 		return -1;
   1020 	}
   1021 
   1022 	return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv);
   1023 }
   1024 
   1025 
   1026 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
   1027 				     char *argv[])
   1028 {
   1029 	char cmd[256];
   1030 	int res;
   1031 
   1032 	if (argc == 5 || argc == 6) {
   1033 		char ssid_hex[2 * 32 + 1];
   1034 		char key_hex[2 * 64 + 1];
   1035 		int i;
   1036 
   1037 		ssid_hex[0] = '\0';
   1038 		for (i = 0; i < 32; i++) {
   1039 			if (argv[2][i] == '\0')
   1040 				break;
   1041 			os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
   1042 		}
   1043 
   1044 		key_hex[0] = '\0';
   1045 		if (argc == 6) {
   1046 			for (i = 0; i < 64; i++) {
   1047 				if (argv[5][i] == '\0')
   1048 					break;
   1049 				os_snprintf(&key_hex[i * 2], 3, "%02x",
   1050 					    argv[5][i]);
   1051 			}
   1052 		}
   1053 
   1054 		res = os_snprintf(cmd, sizeof(cmd),
   1055 				  "WPS_ER_CONFIG %s %s %s %s %s %s",
   1056 				  argv[0], argv[1], ssid_hex, argv[3], argv[4],
   1057 				  key_hex);
   1058 	} else {
   1059 		printf("Invalid WPS_ER_CONFIG command: need six arguments:\n"
   1060 		       "- AP UUID\n"
   1061 		       "- AP PIN\n"
   1062 		       "- new SSID\n"
   1063 		       "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
   1064 		       "- new encr (NONE, WEP, TKIP, CCMP)\n"
   1065 		       "- new key\n");
   1066 		return -1;
   1067 	}
   1068 
   1069 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
   1070 		printf("Too long WPS_ER_CONFIG command.\n");
   1071 		return -1;
   1072 	}
   1073 	return wpa_ctrl_command(ctrl, cmd);
   1074 }
   1075 
   1076 
   1077 #ifdef CONFIG_WPS_NFC
   1078 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
   1079 					       char *argv[])
   1080 {
   1081 	if (argc != 2) {
   1082 		printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
   1083 		       "arguments:\n"
   1084 		       "- WPS/NDEF: token format\n"
   1085 		       "- UUID: specify which AP to use\n");
   1086 		return -1;
   1087 	}
   1088 
   1089 	return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv);
   1090 }
   1091 #endif /* CONFIG_WPS_NFC */
   1092 
   1093 
   1094 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1095 {
   1096 	return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv);
   1097 }
   1098 
   1099 
   1100 static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1101 {
   1102 	return wpa_cli_cmd(ctrl, "LEVEL", 1, argc, argv);
   1103 }
   1104 
   1105 
   1106 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1107 {
   1108 	char cmd[256], *pos, *end;
   1109 	int i, ret;
   1110 
   1111 	if (argc < 2) {
   1112 		printf("Invalid IDENTITY command: needs two arguments "
   1113 		       "(network id and identity)\n");
   1114 		return -1;
   1115 	}
   1116 
   1117 	end = cmd + sizeof(cmd);
   1118 	pos = cmd;
   1119 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
   1120 			  argv[0], argv[1]);
   1121 	if (ret < 0 || ret >= end - pos) {
   1122 		printf("Too long IDENTITY command.\n");
   1123 		return -1;
   1124 	}
   1125 	pos += ret;
   1126 	for (i = 2; i < argc; i++) {
   1127 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
   1128 		if (ret < 0 || ret >= end - pos) {
   1129 			printf("Too long IDENTITY command.\n");
   1130 			return -1;
   1131 		}
   1132 		pos += ret;
   1133 	}
   1134 
   1135 	return wpa_ctrl_command(ctrl, cmd);
   1136 }
   1137 
   1138 
   1139 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1140 {
   1141 	char cmd[256], *pos, *end;
   1142 	int i, ret;
   1143 
   1144 	if (argc < 2) {
   1145 		printf("Invalid PASSWORD command: needs two arguments "
   1146 		       "(network id and password)\n");
   1147 		return -1;
   1148 	}
   1149 
   1150 	end = cmd + sizeof(cmd);
   1151 	pos = cmd;
   1152 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
   1153 			  argv[0], argv[1]);
   1154 	if (ret < 0 || ret >= end - pos) {
   1155 		printf("Too long PASSWORD command.\n");
   1156 		return -1;
   1157 	}
   1158 	pos += ret;
   1159 	for (i = 2; i < argc; i++) {
   1160 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
   1161 		if (ret < 0 || ret >= end - pos) {
   1162 			printf("Too long PASSWORD command.\n");
   1163 			return -1;
   1164 		}
   1165 		pos += ret;
   1166 	}
   1167 
   1168 	return wpa_ctrl_command(ctrl, cmd);
   1169 }
   1170 
   1171 
   1172 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
   1173 				    char *argv[])
   1174 {
   1175 	char cmd[256], *pos, *end;
   1176 	int i, ret;
   1177 
   1178 	if (argc < 2) {
   1179 		printf("Invalid NEW_PASSWORD command: needs two arguments "
   1180 		       "(network id and password)\n");
   1181 		return -1;
   1182 	}
   1183 
   1184 	end = cmd + sizeof(cmd);
   1185 	pos = cmd;
   1186 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
   1187 			  argv[0], argv[1]);
   1188 	if (ret < 0 || ret >= end - pos) {
   1189 		printf("Too long NEW_PASSWORD command.\n");
   1190 		return -1;
   1191 	}
   1192 	pos += ret;
   1193 	for (i = 2; i < argc; i++) {
   1194 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
   1195 		if (ret < 0 || ret >= end - pos) {
   1196 			printf("Too long NEW_PASSWORD command.\n");
   1197 			return -1;
   1198 		}
   1199 		pos += ret;
   1200 	}
   1201 
   1202 	return wpa_ctrl_command(ctrl, cmd);
   1203 }
   1204 
   1205 
   1206 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1207 {
   1208 	char cmd[256], *pos, *end;
   1209 	int i, ret;
   1210 
   1211 	if (argc < 2) {
   1212 		printf("Invalid PIN command: needs two arguments "
   1213 		       "(network id and pin)\n");
   1214 		return -1;
   1215 	}
   1216 
   1217 	end = cmd + sizeof(cmd);
   1218 	pos = cmd;
   1219 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
   1220 			  argv[0], argv[1]);
   1221 	if (ret < 0 || ret >= end - pos) {
   1222 		printf("Too long PIN command.\n");
   1223 		return -1;
   1224 	}
   1225 	pos += ret;
   1226 	for (i = 2; i < argc; i++) {
   1227 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
   1228 		if (ret < 0 || ret >= end - pos) {
   1229 			printf("Too long PIN command.\n");
   1230 			return -1;
   1231 		}
   1232 		pos += ret;
   1233 	}
   1234 	return wpa_ctrl_command(ctrl, cmd);
   1235 }
   1236 
   1237 
   1238 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1239 {
   1240 	char cmd[256], *pos, *end;
   1241 	int i, ret;
   1242 
   1243 	if (argc < 2) {
   1244 		printf("Invalid OTP command: needs two arguments (network "
   1245 		       "id and password)\n");
   1246 		return -1;
   1247 	}
   1248 
   1249 	end = cmd + sizeof(cmd);
   1250 	pos = cmd;
   1251 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
   1252 			  argv[0], argv[1]);
   1253 	if (ret < 0 || ret >= end - pos) {
   1254 		printf("Too long OTP command.\n");
   1255 		return -1;
   1256 	}
   1257 	pos += ret;
   1258 	for (i = 2; i < argc; i++) {
   1259 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
   1260 		if (ret < 0 || ret >= end - pos) {
   1261 			printf("Too long OTP command.\n");
   1262 			return -1;
   1263 		}
   1264 		pos += ret;
   1265 	}
   1266 
   1267 	return wpa_ctrl_command(ctrl, cmd);
   1268 }
   1269 
   1270 
   1271 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
   1272 				  char *argv[])
   1273 {
   1274 	char cmd[256], *pos, *end;
   1275 	int i, ret;
   1276 
   1277 	if (argc < 2) {
   1278 		printf("Invalid PASSPHRASE command: needs two arguments "
   1279 		       "(network id and passphrase)\n");
   1280 		return -1;
   1281 	}
   1282 
   1283 	end = cmd + sizeof(cmd);
   1284 	pos = cmd;
   1285 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
   1286 			  argv[0], argv[1]);
   1287 	if (ret < 0 || ret >= end - pos) {
   1288 		printf("Too long PASSPHRASE command.\n");
   1289 		return -1;
   1290 	}
   1291 	pos += ret;
   1292 	for (i = 2; i < argc; i++) {
   1293 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
   1294 		if (ret < 0 || ret >= end - pos) {
   1295 			printf("Too long PASSPHRASE command.\n");
   1296 			return -1;
   1297 		}
   1298 		pos += ret;
   1299 	}
   1300 
   1301 	return wpa_ctrl_command(ctrl, cmd);
   1302 }
   1303 
   1304 
   1305 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1306 {
   1307 	if (argc < 2) {
   1308 		printf("Invalid BSSID command: needs two arguments (network "
   1309 		       "id and BSSID)\n");
   1310 		return -1;
   1311 	}
   1312 
   1313 	return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv);
   1314 }
   1315 
   1316 
   1317 static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1318 {
   1319 	return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv);
   1320 }
   1321 
   1322 
   1323 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1324 {
   1325 	return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv);
   1326 }
   1327 
   1328 
   1329 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
   1330 				     char *argv[])
   1331 {
   1332 	return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
   1333 }
   1334 
   1335 
   1336 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
   1337 				      char *argv[])
   1338 {
   1339 	return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv);
   1340 }
   1341 
   1342 
   1343 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
   1344 				      char *argv[])
   1345 {
   1346 	return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv);
   1347 }
   1348 
   1349 
   1350 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
   1351 				       char *argv[])
   1352 {
   1353 	return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv);
   1354 }
   1355 
   1356 
   1357 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
   1358 				   char *argv[])
   1359 {
   1360 	return wpa_ctrl_command(ctrl, "ADD_NETWORK");
   1361 }
   1362 
   1363 
   1364 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
   1365 				      char *argv[])
   1366 {
   1367 	return wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv);
   1368 }
   1369 
   1370 
   1371 static void wpa_cli_show_network_variables(void)
   1372 {
   1373 	printf("set_network variables:\n"
   1374 	       "  ssid (network name, SSID)\n"
   1375 	       "  psk (WPA passphrase or pre-shared key)\n"
   1376 	       "  key_mgmt (key management protocol)\n"
   1377 	       "  identity (EAP identity)\n"
   1378 	       "  password (EAP password)\n"
   1379 	       "  ...\n"
   1380 	       "\n"
   1381 	       "Note: Values are entered in the same format as the "
   1382 	       "configuration file is using,\n"
   1383 	       "i.e., strings values need to be inside double quotation "
   1384 	       "marks.\n"
   1385 	       "For example: set_network 1 ssid \"network name\"\n"
   1386 	       "\n"
   1387 	       "Please see wpa_supplicant.conf documentation for full list "
   1388 	       "of\navailable variables.\n");
   1389 }
   1390 
   1391 
   1392 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
   1393 				   char *argv[])
   1394 {
   1395 	if (argc == 0) {
   1396 		wpa_cli_show_network_variables();
   1397 		return 0;
   1398 	}
   1399 
   1400 	if (argc < 3) {
   1401 		printf("Invalid SET_NETWORK command: needs three arguments\n"
   1402 		       "(network id, variable name, and value)\n");
   1403 		return -1;
   1404 	}
   1405 
   1406 	return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv);
   1407 }
   1408 
   1409 
   1410 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
   1411 				   char *argv[])
   1412 {
   1413 	if (argc == 0) {
   1414 		wpa_cli_show_network_variables();
   1415 		return 0;
   1416 	}
   1417 
   1418 	if (argc != 2) {
   1419 		printf("Invalid GET_NETWORK command: needs two arguments\n"
   1420 		       "(network id and variable name)\n");
   1421 		return -1;
   1422 	}
   1423 
   1424 	return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv);
   1425 }
   1426 
   1427 
   1428 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
   1429 				  char *argv[])
   1430 {
   1431 	return wpa_ctrl_command(ctrl, "LIST_CREDS");
   1432 }
   1433 
   1434 
   1435 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1436 {
   1437 	return wpa_ctrl_command(ctrl, "ADD_CRED");
   1438 }
   1439 
   1440 
   1441 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
   1442 				   char *argv[])
   1443 {
   1444 	return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv);
   1445 }
   1446 
   1447 
   1448 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1449 {
   1450 	if (argc != 3) {
   1451 		printf("Invalid SET_CRED command: needs three arguments\n"
   1452 		       "(cred id, variable name, and value)\n");
   1453 		return -1;
   1454 	}
   1455 
   1456 	return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv);
   1457 }
   1458 
   1459 
   1460 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
   1461 				  char *argv[])
   1462 {
   1463 	return wpa_ctrl_command(ctrl, "DISCONNECT");
   1464 }
   1465 
   1466 
   1467 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
   1468 				  char *argv[])
   1469 {
   1470 	return wpa_ctrl_command(ctrl, "RECONNECT");
   1471 }
   1472 
   1473 
   1474 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
   1475 				   char *argv[])
   1476 {
   1477 	return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
   1478 }
   1479 
   1480 
   1481 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1482 {
   1483 	return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
   1484 }
   1485 
   1486 
   1487 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
   1488 				    char *argv[])
   1489 {
   1490 	return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
   1491 }
   1492 
   1493 
   1494 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1495 {
   1496 	return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
   1497 }
   1498 
   1499 
   1500 static char ** wpa_cli_complete_bss(const char *str, int pos)
   1501 {
   1502 	int arg = get_cmd_arg_num(str, pos);
   1503 	char **res = NULL;
   1504 
   1505 	switch (arg) {
   1506 	case 1:
   1507 		res = cli_txt_list_array(&bsses);
   1508 		break;
   1509 	}
   1510 
   1511 	return res;
   1512 }
   1513 
   1514 
   1515 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
   1516 				      char *argv[])
   1517 {
   1518 	if (argc < 1 || argc > 2) {
   1519 		printf("Invalid GET_CAPABILITY command: need either one or "
   1520 		       "two arguments\n");
   1521 		return -1;
   1522 	}
   1523 
   1524 	if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
   1525 		printf("Invalid GET_CAPABILITY command: second argument, "
   1526 		       "if any, must be 'strict'\n");
   1527 		return -1;
   1528 	}
   1529 
   1530 	return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv);
   1531 }
   1532 
   1533 
   1534 static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
   1535 {
   1536 	printf("Available interfaces:\n");
   1537 	return wpa_ctrl_command(ctrl, "INTERFACES");
   1538 }
   1539 
   1540 
   1541 static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1542 {
   1543 	if (argc < 1) {
   1544 		wpa_cli_list_interfaces(ctrl);
   1545 		return 0;
   1546 	}
   1547 
   1548 	wpa_cli_close_connection();
   1549 	os_free(ctrl_ifname);
   1550 	ctrl_ifname = os_strdup(argv[0]);
   1551 
   1552 	if (wpa_cli_open_connection(ctrl_ifname, 1)) {
   1553 		printf("Connected to interface '%s.\n", ctrl_ifname);
   1554 	} else {
   1555 		printf("Could not connect to interface '%s' - re-trying\n",
   1556 		       ctrl_ifname);
   1557 	}
   1558 	return 0;
   1559 }
   1560 
   1561 
   1562 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
   1563 				   char *argv[])
   1564 {
   1565 	return wpa_ctrl_command(ctrl, "RECONFIGURE");
   1566 }
   1567 
   1568 
   1569 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
   1570 				 char *argv[])
   1571 {
   1572 	return wpa_ctrl_command(ctrl, "TERMINATE");
   1573 }
   1574 
   1575 
   1576 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
   1577 				     char *argv[])
   1578 {
   1579 	char cmd[256];
   1580 	int res;
   1581 
   1582 	if (argc < 1) {
   1583 		printf("Invalid INTERFACE_ADD command: needs at least one "
   1584 		       "argument (interface name)\n"
   1585 		       "All arguments: ifname confname driver ctrl_interface "
   1586 		       "driver_param bridge_name\n");
   1587 		return -1;
   1588 	}
   1589 
   1590 	/*
   1591 	 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
   1592 	 * <driver_param>TAB<bridge_name>
   1593 	 */
   1594 	res = os_snprintf(cmd, sizeof(cmd),
   1595 			  "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
   1596 			  argv[0],
   1597 			  argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
   1598 			  argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
   1599 			  argc > 5 ? argv[5] : "");
   1600 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1601 		return -1;
   1602 	cmd[sizeof(cmd) - 1] = '\0';
   1603 	return wpa_ctrl_command(ctrl, cmd);
   1604 }
   1605 
   1606 
   1607 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
   1608 					char *argv[])
   1609 {
   1610 	return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv);
   1611 }
   1612 
   1613 
   1614 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
   1615 				      char *argv[])
   1616 {
   1617 	return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
   1618 }
   1619 
   1620 
   1621 #ifdef CONFIG_AP
   1622 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1623 {
   1624 	return wpa_cli_cmd(ctrl, "STA", 1, argc, argv);
   1625 }
   1626 
   1627 
   1628 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
   1629 				char *addr, size_t addr_len)
   1630 {
   1631 	char buf[4096], *pos;
   1632 	size_t len;
   1633 	int ret;
   1634 
   1635 	if (ctrl_conn == NULL) {
   1636 		printf("Not connected to hostapd - command dropped.\n");
   1637 		return -1;
   1638 	}
   1639 	len = sizeof(buf) - 1;
   1640 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
   1641 			       wpa_cli_msg_cb);
   1642 	if (ret == -2) {
   1643 		printf("'%s' command timed out.\n", cmd);
   1644 		return -2;
   1645 	} else if (ret < 0) {
   1646 		printf("'%s' command failed.\n", cmd);
   1647 		return -1;
   1648 	}
   1649 
   1650 	buf[len] = '\0';
   1651 	if (os_memcmp(buf, "FAIL", 4) == 0)
   1652 		return -1;
   1653 	printf("%s", buf);
   1654 
   1655 	pos = buf;
   1656 	while (*pos != '\0' && *pos != '\n')
   1657 		pos++;
   1658 	*pos = '\0';
   1659 	os_strlcpy(addr, buf, addr_len);
   1660 	return 0;
   1661 }
   1662 
   1663 
   1664 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1665 {
   1666 	char addr[32], cmd[64];
   1667 
   1668 	if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
   1669 		return 0;
   1670 	do {
   1671 		os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
   1672 	} while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
   1673 
   1674 	return -1;
   1675 }
   1676 
   1677 
   1678 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
   1679 				      char *argv[])
   1680 {
   1681 	return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv);
   1682 }
   1683 
   1684 
   1685 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
   1686 				    char *argv[])
   1687 {
   1688 	return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv);
   1689 }
   1690 #endif /* CONFIG_AP */
   1691 
   1692 
   1693 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1694 {
   1695 	return wpa_ctrl_command(ctrl, "SUSPEND");
   1696 }
   1697 
   1698 
   1699 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1700 {
   1701 	return wpa_ctrl_command(ctrl, "RESUME");
   1702 }
   1703 
   1704 
   1705 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1706 {
   1707 	return wpa_ctrl_command(ctrl, "DROP_SA");
   1708 }
   1709 
   1710 
   1711 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1712 {
   1713 	return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv);
   1714 }
   1715 
   1716 
   1717 #ifdef CONFIG_P2P
   1718 
   1719 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1720 {
   1721 	return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv);
   1722 }
   1723 
   1724 
   1725 static char ** wpa_cli_complete_p2p_find(const char *str, int pos)
   1726 {
   1727 	char **res = NULL;
   1728 	int arg = get_cmd_arg_num(str, pos);
   1729 
   1730 	res = os_calloc(6, sizeof(char *));
   1731 	if (res == NULL)
   1732 		return NULL;
   1733 	res[0] = os_strdup("type=social");
   1734 	if (res[0] == NULL) {
   1735 		os_free(res);
   1736 		return NULL;
   1737 	}
   1738 	res[1] = os_strdup("type=progressive");
   1739 	if (res[1] == NULL)
   1740 		return res;
   1741 	res[2] = os_strdup("delay=");
   1742 	if (res[2] == NULL)
   1743 		return res;
   1744 	res[3] = os_strdup("dev_id=");
   1745 	if (res[3] == NULL)
   1746 		return res;
   1747 	if (arg == 1)
   1748 		res[4] = os_strdup("[timeout]");
   1749 
   1750 	return res;
   1751 }
   1752 
   1753 
   1754 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
   1755 				     char *argv[])
   1756 {
   1757 	return wpa_ctrl_command(ctrl, "P2P_STOP_FIND");
   1758 }
   1759 
   1760 
   1761 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
   1762 				   char *argv[])
   1763 {
   1764 	return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv);
   1765 }
   1766 
   1767 
   1768 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
   1769 {
   1770 	int arg = get_cmd_arg_num(str, pos);
   1771 	char **res = NULL;
   1772 
   1773 	switch (arg) {
   1774 	case 1:
   1775 		res = cli_txt_list_array(&p2p_peers);
   1776 		break;
   1777 	}
   1778 
   1779 	return res;
   1780 }
   1781 
   1782 
   1783 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
   1784 				  char *argv[])
   1785 {
   1786 	return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv);
   1787 }
   1788 
   1789 
   1790 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
   1791 					char *argv[])
   1792 {
   1793 	return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv);
   1794 }
   1795 
   1796 
   1797 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
   1798 {
   1799 	int arg = get_cmd_arg_num(str, pos);
   1800 	char **res = NULL;
   1801 
   1802 	switch (arg) {
   1803 	case 1:
   1804 		res = cli_txt_list_array(&p2p_groups);
   1805 		break;
   1806 	}
   1807 
   1808 	return res;
   1809 }
   1810 
   1811 
   1812 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
   1813 					char *argv[])
   1814 {
   1815 	return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv);
   1816 }
   1817 
   1818 
   1819 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
   1820 				     char *argv[])
   1821 {
   1822 	if (argc != 2 && argc != 3) {
   1823 		printf("Invalid P2P_PROV_DISC command: needs at least "
   1824 		       "two arguments, address and config method\n"
   1825 		       "(display, keypad, or pbc) and an optional join\n");
   1826 		return -1;
   1827 	}
   1828 
   1829 	return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv);
   1830 }
   1831 
   1832 
   1833 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
   1834 					  char *argv[])
   1835 {
   1836 	return wpa_ctrl_command(ctrl, "P2P_GET_PASSPHRASE");
   1837 }
   1838 
   1839 
   1840 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
   1841 					 char *argv[])
   1842 {
   1843 	char cmd[4096];
   1844 
   1845 	if (argc != 2 && argc != 4) {
   1846 		printf("Invalid P2P_SERV_DISC_REQ command: needs two "
   1847 		       "arguments (address and TLVs) or four arguments "
   1848 		       "(address, \"upnp\", version, search target "
   1849 		       "(SSDP ST:)\n");
   1850 		return -1;
   1851 	}
   1852 
   1853 	if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0)
   1854 		return -1;
   1855 	return wpa_ctrl_command(ctrl, cmd);
   1856 }
   1857 
   1858 
   1859 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
   1860 						int argc, char *argv[])
   1861 {
   1862 	return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv);
   1863 }
   1864 
   1865 
   1866 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
   1867 					  char *argv[])
   1868 {
   1869 	char cmd[4096];
   1870 	int res;
   1871 
   1872 	if (argc != 4) {
   1873 		printf("Invalid P2P_SERV_DISC_RESP command: needs four "
   1874 		       "arguments (freq, address, dialog token, and TLVs)\n");
   1875 		return -1;
   1876 	}
   1877 
   1878 	res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
   1879 			  argv[0], argv[1], argv[2], argv[3]);
   1880 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1881 		return -1;
   1882 	cmd[sizeof(cmd) - 1] = '\0';
   1883 	return wpa_ctrl_command(ctrl, cmd);
   1884 }
   1885 
   1886 
   1887 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
   1888 					  char *argv[])
   1889 {
   1890 	return wpa_ctrl_command(ctrl, "P2P_SERVICE_UPDATE");
   1891 }
   1892 
   1893 
   1894 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
   1895 					      int argc, char *argv[])
   1896 {
   1897 	return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv);
   1898 }
   1899 
   1900 
   1901 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
   1902 					 char *argv[])
   1903 {
   1904 	return wpa_ctrl_command(ctrl, "P2P_SERVICE_FLUSH");
   1905 }
   1906 
   1907 
   1908 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
   1909 				       char *argv[])
   1910 {
   1911 	char cmd[4096];
   1912 	int res;
   1913 
   1914 	if (argc != 3 && argc != 4) {
   1915 		printf("Invalid P2P_SERVICE_ADD command: needs three or four "
   1916 		       "arguments\n");
   1917 		return -1;
   1918 	}
   1919 
   1920 	if (argc == 4)
   1921 		res = os_snprintf(cmd, sizeof(cmd),
   1922 				  "P2P_SERVICE_ADD %s %s %s %s",
   1923 				  argv[0], argv[1], argv[2], argv[3]);
   1924 	else
   1925 		res = os_snprintf(cmd, sizeof(cmd),
   1926 				  "P2P_SERVICE_ADD %s %s %s",
   1927 				  argv[0], argv[1], argv[2]);
   1928 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1929 		return -1;
   1930 	cmd[sizeof(cmd) - 1] = '\0';
   1931 	return wpa_ctrl_command(ctrl, cmd);
   1932 }
   1933 
   1934 
   1935 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
   1936 				       char *argv[])
   1937 {
   1938 	char cmd[4096];
   1939 	int res;
   1940 
   1941 	if (argc != 2 && argc != 3) {
   1942 		printf("Invalid P2P_SERVICE_DEL command: needs two or three "
   1943 		       "arguments\n");
   1944 		return -1;
   1945 	}
   1946 
   1947 	if (argc == 3)
   1948 		res = os_snprintf(cmd, sizeof(cmd),
   1949 				  "P2P_SERVICE_DEL %s %s %s",
   1950 				  argv[0], argv[1], argv[2]);
   1951 	else
   1952 		res = os_snprintf(cmd, sizeof(cmd),
   1953 				  "P2P_SERVICE_DEL %s %s",
   1954 				  argv[0], argv[1]);
   1955 	if (res < 0 || (size_t) res >= sizeof(cmd))
   1956 		return -1;
   1957 	cmd[sizeof(cmd) - 1] = '\0';
   1958 	return wpa_ctrl_command(ctrl, cmd);
   1959 }
   1960 
   1961 
   1962 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
   1963 				  int argc, char *argv[])
   1964 {
   1965 	return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv);
   1966 }
   1967 
   1968 
   1969 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
   1970 				  int argc, char *argv[])
   1971 {
   1972 	return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv);
   1973 }
   1974 
   1975 
   1976 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
   1977 {
   1978 	return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv);
   1979 }
   1980 
   1981 
   1982 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
   1983 {
   1984 	int arg = get_cmd_arg_num(str, pos);
   1985 	char **res = NULL;
   1986 
   1987 	switch (arg) {
   1988 	case 1:
   1989 		res = cli_txt_list_array(&p2p_peers);
   1990 		break;
   1991 	}
   1992 
   1993 	return res;
   1994 }
   1995 
   1996 
   1997 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, char *cmd,
   1998 				     char *addr, size_t addr_len,
   1999 				     int discovered)
   2000 {
   2001 	char buf[4096], *pos;
   2002 	size_t len;
   2003 	int ret;
   2004 
   2005 	if (ctrl_conn == NULL)
   2006 		return -1;
   2007 	len = sizeof(buf) - 1;
   2008 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
   2009 			       wpa_cli_msg_cb);
   2010 	if (ret == -2) {
   2011 		printf("'%s' command timed out.\n", cmd);
   2012 		return -2;
   2013 	} else if (ret < 0) {
   2014 		printf("'%s' command failed.\n", cmd);
   2015 		return -1;
   2016 	}
   2017 
   2018 	buf[len] = '\0';
   2019 	if (os_memcmp(buf, "FAIL", 4) == 0)
   2020 		return -1;
   2021 
   2022 	pos = buf;
   2023 	while (*pos != '\0' && *pos != '\n')
   2024 		pos++;
   2025 	*pos++ = '\0';
   2026 	os_strlcpy(addr, buf, addr_len);
   2027 	if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
   2028 		printf("%s\n", addr);
   2029 	return 0;
   2030 }
   2031 
   2032 
   2033 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
   2034 {
   2035 	char addr[32], cmd[64];
   2036 	int discovered;
   2037 
   2038 	discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
   2039 
   2040 	if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
   2041 				      addr, sizeof(addr), discovered))
   2042 		return -1;
   2043 	do {
   2044 		os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
   2045 	} while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
   2046 			 discovered) == 0);
   2047 
   2048 	return 0;
   2049 }
   2050 
   2051 
   2052 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
   2053 {
   2054 	return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv);
   2055 }
   2056 
   2057 
   2058 static char ** wpa_cli_complete_p2p_set(const char *str, int pos)
   2059 {
   2060 	int arg = get_cmd_arg_num(str, pos);
   2061 	const char *fields[] = {
   2062 		"discoverability",
   2063 		"managed",
   2064 		"listen_channel",
   2065 		"ssid_postfix",
   2066 		"noa",
   2067 		"ps",
   2068 		"oppps",
   2069 		"ctwindow",
   2070 		"disabled",
   2071 		"conc_pref",
   2072 		"force_long_sd",
   2073 		"peer_filter",
   2074 		"cross_connect",
   2075 		"go_apsd",
   2076 		"client_apsd",
   2077 		"disallow_freq",
   2078 		"disc_int",
   2079 		"per_sta_psk",
   2080 	};
   2081 	int i, num_fields = sizeof(fields) / sizeof(fields[0]);
   2082 
   2083 	if (arg == 1) {
   2084 		char **res = os_calloc(num_fields + 1, sizeof(char *));
   2085 		if (res == NULL)
   2086 			return NULL;
   2087 		for (i = 0; i < num_fields; i++) {
   2088 			res[i] = os_strdup(fields[i]);
   2089 			if (res[i] == NULL)
   2090 				return res;
   2091 		}
   2092 		return res;
   2093 	}
   2094 
   2095 	if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0)
   2096 		return cli_txt_list_array(&p2p_peers);
   2097 
   2098 	return NULL;
   2099 }
   2100 
   2101 
   2102 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
   2103 {
   2104 	return wpa_ctrl_command(ctrl, "P2P_FLUSH");
   2105 }
   2106 
   2107 
   2108 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
   2109 				  char *argv[])
   2110 {
   2111 	return wpa_ctrl_command(ctrl, "P2P_CANCEL");
   2112 }
   2113 
   2114 
   2115 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
   2116 				       char *argv[])
   2117 {
   2118 	return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv);
   2119 }
   2120 
   2121 
   2122 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
   2123 					char *argv[])
   2124 {
   2125 	if (argc != 0 && argc != 2 && argc != 4) {
   2126 		printf("Invalid P2P_PRESENCE_REQ command: needs two arguments "
   2127 		       "(preferred duration, interval; in microsecods).\n"
   2128 		       "Optional second pair can be used to provide "
   2129 		       "acceptable values.\n");
   2130 		return -1;
   2131 	}
   2132 
   2133 	return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv);
   2134 }
   2135 
   2136 
   2137 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
   2138 				      char *argv[])
   2139 {
   2140 	if (argc != 0 && argc != 2) {
   2141 		printf("Invalid P2P_EXT_LISTEN command: needs two arguments "
   2142 		       "(availability period, availability interval; in "
   2143 		       "millisecods).\n"
   2144 		       "Extended Listen Timing can be cancelled with this "
   2145 		       "command when used without parameters.\n");
   2146 		return -1;
   2147 	}
   2148 
   2149 	return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv);
   2150 }
   2151 
   2152 
   2153 static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc,
   2154 					 char *argv[])
   2155 {
   2156 	return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv);
   2157 }
   2158 
   2159 #endif /* CONFIG_P2P */
   2160 
   2161 #ifdef CONFIG_WIFI_DISPLAY
   2162 
   2163 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc,
   2164 				       char *argv[])
   2165 {
   2166 	char cmd[100];
   2167 	int res;
   2168 
   2169 	if (argc != 1 && argc != 2) {
   2170 		printf("Invalid WFD_SUBELEM_SET command: needs one or two "
   2171 		       "arguments (subelem, hexdump)\n");
   2172 		return -1;
   2173 	}
   2174 
   2175 	res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s",
   2176 			  argv[0], argc > 1 ? argv[1] : "");
   2177 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2178 		return -1;
   2179 	cmd[sizeof(cmd) - 1] = '\0';
   2180 	return wpa_ctrl_command(ctrl, cmd);
   2181 }
   2182 
   2183 
   2184 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc,
   2185 				       char *argv[])
   2186 {
   2187 	char cmd[100];
   2188 	int res;
   2189 
   2190 	if (argc != 1) {
   2191 		printf("Invalid WFD_SUBELEM_GET command: needs one "
   2192 		       "argument (subelem)\n");
   2193 		return -1;
   2194 	}
   2195 
   2196 	res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s",
   2197 			  argv[0]);
   2198 	if (res < 0 || (size_t) res >= sizeof(cmd))
   2199 		return -1;
   2200 	cmd[sizeof(cmd) - 1] = '\0';
   2201 	return wpa_ctrl_command(ctrl, cmd);
   2202 }
   2203 #endif /* CONFIG_WIFI_DISPLAY */
   2204 
   2205 
   2206 #ifdef CONFIG_INTERWORKING
   2207 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
   2208 				  char *argv[])
   2209 {
   2210 	return wpa_ctrl_command(ctrl, "FETCH_ANQP");
   2211 }
   2212 
   2213 
   2214 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
   2215 				       char *argv[])
   2216 {
   2217 	return wpa_ctrl_command(ctrl, "STOP_FETCH_ANQP");
   2218 }
   2219 
   2220 
   2221 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
   2222 					   char *argv[])
   2223 {
   2224 	return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv);
   2225 }
   2226 
   2227 
   2228 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
   2229 					    char *argv[])
   2230 {
   2231 	return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv);
   2232 }
   2233 
   2234 
   2235 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
   2236 {
   2237 	return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv);
   2238 }
   2239 
   2240 
   2241 static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc,
   2242 				   char *argv[])
   2243 {
   2244 	return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv);
   2245 }
   2246 
   2247 
   2248 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc,
   2249 					char *argv[])
   2250 {
   2251 	return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv);
   2252 }
   2253 #endif /* CONFIG_INTERWORKING */
   2254 
   2255 
   2256 #ifdef CONFIG_HS20
   2257 
   2258 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
   2259 				     char *argv[])
   2260 {
   2261 	return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv);
   2262 }
   2263 
   2264 
   2265 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
   2266 					       char *argv[])
   2267 {
   2268 	char cmd[512];
   2269 
   2270 	if (argc == 0) {
   2271 		printf("Command needs one or two arguments (dst mac addr and "
   2272 		       "optional home realm)\n");
   2273 		return -1;
   2274 	}
   2275 
   2276 	if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST",
   2277 		      argc, argv) < 0)
   2278 		return -1;
   2279 
   2280 	return wpa_ctrl_command(ctrl, cmd);
   2281 }
   2282 
   2283 #endif /* CONFIG_HS20 */
   2284 
   2285 
   2286 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
   2287 				       char *argv[])
   2288 {
   2289 	return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv);
   2290 }
   2291 
   2292 
   2293 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
   2294 				     char *argv[])
   2295 {
   2296 	return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv);
   2297 }
   2298 
   2299 
   2300 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
   2301 				  char *argv[])
   2302 {
   2303 	return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv);
   2304 }
   2305 
   2306 
   2307 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
   2308 				     char *argv[])
   2309 {
   2310 	return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv);
   2311 }
   2312 
   2313 
   2314 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
   2315 				   char *argv[])
   2316 {
   2317 	return wpa_ctrl_command(ctrl, "SIGNAL_POLL");
   2318 }
   2319 
   2320 
   2321 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
   2322 				   char *argv[])
   2323 {
   2324 	return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
   2325 }
   2326 
   2327 
   2328 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
   2329 				      char *argv[])
   2330 {
   2331 	return wpa_ctrl_command(ctrl, "REAUTHENTICATE");
   2332 }
   2333 
   2334 
   2335 #ifdef CONFIG_AUTOSCAN
   2336 
   2337 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
   2338 {
   2339 	if (argc == 0)
   2340 		return wpa_ctrl_command(ctrl, "AUTOSCAN ");
   2341 
   2342 	return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv);
   2343 }
   2344 
   2345 #endif /* CONFIG_AUTOSCAN */
   2346 
   2347 
   2348 #ifdef CONFIG_WNM
   2349 
   2350 static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[])
   2351 {
   2352 	return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv);
   2353 }
   2354 
   2355 
   2356 static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
   2357 {
   2358 	return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv);
   2359 }
   2360 
   2361 #endif /* CONFIG_WNM */
   2362 
   2363 
   2364 static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
   2365 {
   2366 	if (argc == 0)
   2367 		return -1;
   2368 	return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
   2369 }
   2370 
   2371 
   2372 #ifdef ANDROID
   2373 static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
   2374 {
   2375 	char cmd[256];
   2376 	int i;
   2377 	int len;
   2378 
   2379 	if (argc < 1) {
   2380 		printf("Invalid DRIVER command: needs one argument (cmd)\n");
   2381 		return -1;
   2382 	}
   2383 
   2384 	len = os_snprintf(cmd, sizeof(cmd), "DRIVER %s", argv[0]);
   2385 	for (i=1; i < argc; i++)
   2386 		len += os_snprintf(cmd + len, sizeof(cmd) - len, " %s", argv[i]);
   2387 	cmd[sizeof(cmd) - 1] = '\0';
   2388 	printf("%s: %s\n", __func__, cmd);
   2389 	return wpa_ctrl_command(ctrl, cmd);
   2390 }
   2391 #endif
   2392 
   2393 
   2394 static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
   2395 {
   2396 	return wpa_ctrl_command(ctrl, "FLUSH");
   2397 }
   2398 
   2399 
   2400 enum wpa_cli_cmd_flags {
   2401 	cli_cmd_flag_none		= 0x00,
   2402 	cli_cmd_flag_sensitive		= 0x01
   2403 };
   2404 
   2405 struct wpa_cli_cmd {
   2406 	const char *cmd;
   2407 	int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
   2408 	char ** (*completion)(const char *str, int pos);
   2409 	enum wpa_cli_cmd_flags flags;
   2410 	const char *usage;
   2411 };
   2412 
   2413 static struct wpa_cli_cmd wpa_cli_commands[] = {
   2414 	{ "status", wpa_cli_cmd_status, NULL,
   2415 	  cli_cmd_flag_none,
   2416 	  "[verbose] = get current WPA/EAPOL/EAP status" },
   2417 	{ "ifname", wpa_cli_cmd_ifname, NULL,
   2418 	  cli_cmd_flag_none,
   2419 	  "= get current interface name" },
   2420 	{ "ping", wpa_cli_cmd_ping, NULL,
   2421 	  cli_cmd_flag_none,
   2422 	  "= pings wpa_supplicant" },
   2423 	{ "relog", wpa_cli_cmd_relog, NULL,
   2424 	  cli_cmd_flag_none,
   2425 	  "= re-open log-file (allow rolling logs)" },
   2426 	{ "note", wpa_cli_cmd_note, NULL,
   2427 	  cli_cmd_flag_none,
   2428 	  "<text> = add a note to wpa_supplicant debug log" },
   2429 	{ "mib", wpa_cli_cmd_mib, NULL,
   2430 	  cli_cmd_flag_none,
   2431 	  "= get MIB variables (dot1x, dot11)" },
   2432 	{ "help", wpa_cli_cmd_help, wpa_cli_complete_help,
   2433 	  cli_cmd_flag_none,
   2434 	  "[command] = show usage help" },
   2435 	{ "interface", wpa_cli_cmd_interface, NULL,
   2436 	  cli_cmd_flag_none,
   2437 	  "[ifname] = show interfaces/select interface" },
   2438 	{ "level", wpa_cli_cmd_level, NULL,
   2439 	  cli_cmd_flag_none,
   2440 	  "<debug level> = change debug level" },
   2441 	{ "license", wpa_cli_cmd_license, NULL,
   2442 	  cli_cmd_flag_none,
   2443 	  "= show full wpa_cli license" },
   2444 	{ "quit", wpa_cli_cmd_quit, NULL,
   2445 	  cli_cmd_flag_none,
   2446 	  "= exit wpa_cli" },
   2447 	{ "set", wpa_cli_cmd_set, wpa_cli_complete_set,
   2448 	  cli_cmd_flag_none,
   2449 	  "= set variables (shows list of variables when run without "
   2450 	  "arguments)" },
   2451 	{ "get", wpa_cli_cmd_get, NULL,
   2452 	  cli_cmd_flag_none,
   2453 	  "<name> = get information" },
   2454 	{ "logon", wpa_cli_cmd_logon, NULL,
   2455 	  cli_cmd_flag_none,
   2456 	  "= IEEE 802.1X EAPOL state machine logon" },
   2457 	{ "logoff", wpa_cli_cmd_logoff, NULL,
   2458 	  cli_cmd_flag_none,
   2459 	  "= IEEE 802.1X EAPOL state machine logoff" },
   2460 	{ "pmksa", wpa_cli_cmd_pmksa, NULL,
   2461 	  cli_cmd_flag_none,
   2462 	  "= show PMKSA cache" },
   2463 	{ "reassociate", wpa_cli_cmd_reassociate, NULL,
   2464 	  cli_cmd_flag_none,
   2465 	  "= force reassociation" },
   2466 	{ "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
   2467 	  cli_cmd_flag_none,
   2468 	  "<BSSID> = force preauthentication" },
   2469 	{ "identity", wpa_cli_cmd_identity, NULL,
   2470 	  cli_cmd_flag_none,
   2471 	  "<network id> <identity> = configure identity for an SSID" },
   2472 	{ "password", wpa_cli_cmd_password, NULL,
   2473 	  cli_cmd_flag_sensitive,
   2474 	  "<network id> <password> = configure password for an SSID" },
   2475 	{ "new_password", wpa_cli_cmd_new_password, NULL,
   2476 	  cli_cmd_flag_sensitive,
   2477 	  "<network id> <password> = change password for an SSID" },
   2478 	{ "pin", wpa_cli_cmd_pin, NULL,
   2479 	  cli_cmd_flag_sensitive,
   2480 	  "<network id> <pin> = configure pin for an SSID" },
   2481 	{ "otp", wpa_cli_cmd_otp, NULL,
   2482 	  cli_cmd_flag_sensitive,
   2483 	  "<network id> <password> = configure one-time-password for an SSID"
   2484 	},
   2485 	{ "passphrase", wpa_cli_cmd_passphrase, NULL,
   2486 	  cli_cmd_flag_sensitive,
   2487 	  "<network id> <passphrase> = configure private key passphrase\n"
   2488 	  "  for an SSID" },
   2489 	{ "bssid", wpa_cli_cmd_bssid, NULL,
   2490 	  cli_cmd_flag_none,
   2491 	  "<network id> <BSSID> = set preferred BSSID for an SSID" },
   2492 	{ "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss,
   2493 	  cli_cmd_flag_none,
   2494 	  "<BSSID> = add a BSSID to the blacklist\n"
   2495 	  "blacklist clear = clear the blacklist\n"
   2496 	  "blacklist = display the blacklist" },
   2497 	{ "log_level", wpa_cli_cmd_log_level, NULL,
   2498 	  cli_cmd_flag_none,
   2499 	  "<level> [<timestamp>] = update the log level/timestamp\n"
   2500 	  "log_level = display the current log level and log options" },
   2501 	{ "list_networks", wpa_cli_cmd_list_networks, NULL,
   2502 	  cli_cmd_flag_none,
   2503 	  "= list configured networks" },
   2504 	{ "select_network", wpa_cli_cmd_select_network, NULL,
   2505 	  cli_cmd_flag_none,
   2506 	  "<network id> = select a network (disable others)" },
   2507 	{ "enable_network", wpa_cli_cmd_enable_network, NULL,
   2508 	  cli_cmd_flag_none,
   2509 	  "<network id> = enable a network" },
   2510 	{ "disable_network", wpa_cli_cmd_disable_network, NULL,
   2511 	  cli_cmd_flag_none,
   2512 	  "<network id> = disable a network" },
   2513 	{ "add_network", wpa_cli_cmd_add_network, NULL,
   2514 	  cli_cmd_flag_none,
   2515 	  "= add a network" },
   2516 	{ "remove_network", wpa_cli_cmd_remove_network, NULL,
   2517 	  cli_cmd_flag_none,
   2518 	  "<network id> = remove a network" },
   2519 	{ "set_network", wpa_cli_cmd_set_network, NULL,
   2520 	  cli_cmd_flag_sensitive,
   2521 	  "<network id> <variable> <value> = set network variables (shows\n"
   2522 	  "  list of variables when run without arguments)" },
   2523 	{ "get_network", wpa_cli_cmd_get_network, NULL,
   2524 	  cli_cmd_flag_none,
   2525 	  "<network id> <variable> = get network variables" },
   2526 	{ "list_creds", wpa_cli_cmd_list_creds, NULL,
   2527 	  cli_cmd_flag_none,
   2528 	  "= list configured credentials" },
   2529 	{ "add_cred", wpa_cli_cmd_add_cred, NULL,
   2530 	  cli_cmd_flag_none,
   2531 	  "= add a credential" },
   2532 	{ "remove_cred", wpa_cli_cmd_remove_cred, NULL,
   2533 	  cli_cmd_flag_none,
   2534 	  "<cred id> = remove a credential" },
   2535 	{ "set_cred", wpa_cli_cmd_set_cred, NULL,
   2536 	  cli_cmd_flag_sensitive,
   2537 	  "<cred id> <variable> <value> = set credential variables" },
   2538 	{ "save_config", wpa_cli_cmd_save_config, NULL,
   2539 	  cli_cmd_flag_none,
   2540 	  "= save the current configuration" },
   2541 	{ "disconnect", wpa_cli_cmd_disconnect, NULL,
   2542 	  cli_cmd_flag_none,
   2543 	  "= disconnect and wait for reassociate/reconnect command before\n"
   2544 	  "  connecting" },
   2545 	{ "reconnect", wpa_cli_cmd_reconnect, NULL,
   2546 	  cli_cmd_flag_none,
   2547 	  "= like reassociate, but only takes effect if already disconnected"
   2548 	},
   2549 	{ "scan", wpa_cli_cmd_scan, NULL,
   2550 	  cli_cmd_flag_none,
   2551 	  "= request new BSS scan" },
   2552 	{ "scan_results", wpa_cli_cmd_scan_results, NULL,
   2553 	  cli_cmd_flag_none,
   2554 	  "= get latest scan results" },
   2555 	{ "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
   2556 	  cli_cmd_flag_none,
   2557 	  "<<idx> | <bssid>> = get detailed scan result info" },
   2558 	{ "get_capability", wpa_cli_cmd_get_capability, NULL,
   2559 	  cli_cmd_flag_none,
   2560 	  "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
   2561 	  "= get capabilies" },
   2562 	{ "reconfigure", wpa_cli_cmd_reconfigure, NULL,
   2563 	  cli_cmd_flag_none,
   2564 	  "= force wpa_supplicant to re-read its configuration file" },
   2565 	{ "terminate", wpa_cli_cmd_terminate, NULL,
   2566 	  cli_cmd_flag_none,
   2567 	  "= terminate wpa_supplicant" },
   2568 	{ "interface_add", wpa_cli_cmd_interface_add, NULL,
   2569 	  cli_cmd_flag_none,
   2570 	  "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
   2571 	  "  <bridge_name> = adds new interface, all parameters but <ifname>\n"
   2572 	  "  are optional" },
   2573 	{ "interface_remove", wpa_cli_cmd_interface_remove, NULL,
   2574 	  cli_cmd_flag_none,
   2575 	  "<ifname> = removes the interface" },
   2576 	{ "interface_list", wpa_cli_cmd_interface_list, NULL,
   2577 	  cli_cmd_flag_none,
   2578 	  "= list available interfaces" },
   2579 	{ "ap_scan", wpa_cli_cmd_ap_scan, NULL,
   2580 	  cli_cmd_flag_none,
   2581 	  "<value> = set ap_scan parameter" },
   2582 	{ "scan_interval", wpa_cli_cmd_scan_interval, NULL,
   2583 	  cli_cmd_flag_none,
   2584 	  "<value> = set scan_interval parameter (in seconds)" },
   2585 	{ "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
   2586 	  cli_cmd_flag_none,
   2587 	  "<value> = set BSS expiration age parameter" },
   2588 	{ "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
   2589 	  cli_cmd_flag_none,
   2590 	  "<value> = set BSS expiration scan count parameter" },
   2591 	{ "bss_flush", wpa_cli_cmd_bss_flush, NULL,
   2592 	  cli_cmd_flag_none,
   2593 	  "<value> = set BSS flush age (0 by default)" },
   2594 	{ "stkstart", wpa_cli_cmd_stkstart, NULL,
   2595 	  cli_cmd_flag_none,
   2596 	  "<addr> = request STK negotiation with <addr>" },
   2597 	{ "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
   2598 	  cli_cmd_flag_none,
   2599 	  "<addr> = request over-the-DS FT with <addr>" },
   2600 	{ "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
   2601 	  cli_cmd_flag_none,
   2602 	  "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
   2603 	{ "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
   2604 	  cli_cmd_flag_sensitive,
   2605 	  "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
   2606 	  "hardcoded)" },
   2607 	{ "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
   2608 	  cli_cmd_flag_sensitive,
   2609 	  "<PIN> = verify PIN checksum" },
   2610 	{ "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
   2611 	  "Cancels the pending WPS operation" },
   2612 #ifdef CONFIG_WPS_NFC
   2613 	{ "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
   2614 	  cli_cmd_flag_none,
   2615 	  "[BSSID] = start Wi-Fi Protected Setup: NFC" },
   2616 	{ "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
   2617 	  cli_cmd_flag_none,
   2618 	  "<WPS|NDEF> = build configuration token" },
   2619 	{ "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
   2620 	  cli_cmd_flag_none,
   2621 	  "<WPS|NDEF> = create password token" },
   2622 	{ "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
   2623 	  cli_cmd_flag_sensitive,
   2624 	  "<hexdump of payload> = report read NFC tag with WPS data" },
   2625 	{ "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
   2626 	  cli_cmd_flag_none,
   2627 	  "<NDEF> <WPS> = create NFC handover request" },
   2628 	{ "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
   2629 	  cli_cmd_flag_none,
   2630 	  "<NDEF> <WPS> = create NFC handover select" },
   2631 	{ "nfc_rx_handover_req", wpa_cli_cmd_nfc_rx_handover_req, NULL,
   2632 	  cli_cmd_flag_none,
   2633 	  "<hexdump of payload> = report received NFC handover request" },
   2634 	{ "nfc_rx_handover_sel", wpa_cli_cmd_nfc_rx_handover_sel, NULL,
   2635 	  cli_cmd_flag_none,
   2636 	  "<hexdump of payload> = report received NFC handover select" },
   2637 	{ "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
   2638 	  cli_cmd_flag_none,
   2639 	  "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
   2640 	  "NFC handover" },
   2641 #endif /* CONFIG_WPS_NFC */
   2642 	{ "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
   2643 	  cli_cmd_flag_sensitive,
   2644 	  "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
   2645 	{ "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
   2646 	  cli_cmd_flag_sensitive,
   2647 	  "[params..] = enable/disable AP PIN" },
   2648 	{ "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
   2649 	  cli_cmd_flag_none,
   2650 	  "[IP address] = start Wi-Fi Protected Setup External Registrar" },
   2651 	{ "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
   2652 	  cli_cmd_flag_none,
   2653 	  "= stop Wi-Fi Protected Setup External Registrar" },
   2654 	{ "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
   2655 	  cli_cmd_flag_sensitive,
   2656 	  "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
   2657 	{ "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
   2658 	  cli_cmd_flag_none,
   2659 	  "<UUID> = accept an Enrollee PBC using External Registrar" },
   2660 	{ "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
   2661 	  cli_cmd_flag_sensitive,
   2662 	  "<UUID> <PIN> = learn AP configuration" },
   2663 	{ "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
   2664 	  cli_cmd_flag_none,
   2665 	  "<UUID> <network id> = set AP configuration for enrolling" },
   2666 	{ "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
   2667 	  cli_cmd_flag_sensitive,
   2668 	  "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
   2669 #ifdef CONFIG_WPS_NFC
   2670 	{ "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
   2671 	  cli_cmd_flag_none,
   2672 	  "<WPS/NDEF> <UUID> = build NFC configuration token" },
   2673 #endif /* CONFIG_WPS_NFC */
   2674 	{ "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
   2675 	  cli_cmd_flag_none,
   2676 	  "<addr> = request RSN authentication with <addr> in IBSS" },
   2677 #ifdef CONFIG_AP
   2678 	{ "sta", wpa_cli_cmd_sta, NULL,
   2679 	  cli_cmd_flag_none,
   2680 	  "<addr> = get information about an associated station (AP)" },
   2681 	{ "all_sta", wpa_cli_cmd_all_sta, NULL,
   2682 	  cli_cmd_flag_none,
   2683 	  "= get information about all associated stations (AP)" },
   2684 	{ "deauthenticate", wpa_cli_cmd_deauthenticate, NULL,
   2685 	  cli_cmd_flag_none,
   2686 	  "<addr> = deauthenticate a station" },
   2687 	{ "disassociate", wpa_cli_cmd_disassociate, NULL,
   2688 	  cli_cmd_flag_none,
   2689 	  "<addr> = disassociate a station" },
   2690 #endif /* CONFIG_AP */
   2691 	{ "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
   2692 	  "= notification of suspend/hibernate" },
   2693 	{ "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
   2694 	  "= notification of resume/thaw" },
   2695 	{ "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
   2696 	  "= drop SA without deauth/disassoc (test command)" },
   2697 	{ "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
   2698 	  cli_cmd_flag_none,
   2699 	  "<addr> = roam to the specified BSS" },
   2700 #ifdef CONFIG_P2P
   2701 	{ "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
   2702 	  cli_cmd_flag_none,
   2703 	  "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
   2704 	{ "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
   2705 	  "= stop P2P Devices search" },
   2706 	{ "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
   2707 	  cli_cmd_flag_none,
   2708 	  "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
   2709 	{ "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
   2710 	  "[timeout] = listen for P2P Devices for up-to timeout seconds" },
   2711 	{ "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
   2712 	  wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
   2713 	  "<ifname> = remove P2P group interface (terminate group if GO)" },
   2714 	{ "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
   2715 	  "[ht40] = add a new P2P group (local end as GO)" },
   2716 	{ "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
   2717 	  wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
   2718 	  "<addr> <method> = request provisioning discovery" },
   2719 	{ "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
   2720 	  cli_cmd_flag_none,
   2721 	  "= get the passphrase for a group (GO only)" },
   2722 	{ "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
   2723 	  wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
   2724 	  "<addr> <TLVs> = schedule service discovery request" },
   2725 	{ "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
   2726 	  NULL, cli_cmd_flag_none,
   2727 	  "<id> = cancel pending service discovery request" },
   2728 	{ "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
   2729 	  cli_cmd_flag_none,
   2730 	  "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
   2731 	{ "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
   2732 	  cli_cmd_flag_none,
   2733 	  "= indicate change in local services" },
   2734 	{ "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
   2735 	  cli_cmd_flag_none,
   2736 	  "<external> = set external processing of service discovery" },
   2737 	{ "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
   2738 	  cli_cmd_flag_none,
   2739 	  "= remove all stored service entries" },
   2740 	{ "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
   2741 	  cli_cmd_flag_none,
   2742 	  "<bonjour|upnp> <query|version> <response|service> = add a local "
   2743 	  "service" },
   2744 	{ "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
   2745 	  cli_cmd_flag_none,
   2746 	  "<bonjour|upnp> <query|version> [|service] = remove a local "
   2747 	  "service" },
   2748 	{ "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
   2749 	  cli_cmd_flag_none,
   2750 	  "<addr> = reject connection attempts from a specific peer" },
   2751 	{ "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
   2752 	  cli_cmd_flag_none,
   2753 	  "<cmd> [peer=addr] = invite peer" },
   2754 	{ "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
   2755 	  "[discovered] = list known (optionally, only fully discovered) P2P "
   2756 	  "peers" },
   2757 	{ "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
   2758 	  cli_cmd_flag_none,
   2759 	  "<address> = show information about known P2P peer" },
   2760 	{ "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set,
   2761 	  cli_cmd_flag_none,
   2762 	  "<field> <value> = set a P2P parameter" },
   2763 	{ "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
   2764 	  "= flush P2P state" },
   2765 	{ "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
   2766 	  "= cancel P2P group formation" },
   2767 	{ "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
   2768 	  wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
   2769 	  "<address> = unauthorize a peer" },
   2770 	{ "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
   2771 	  cli_cmd_flag_none,
   2772 	  "[<duration> <interval>] [<duration> <interval>] = request GO "
   2773 	  "presence" },
   2774 	{ "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
   2775 	  cli_cmd_flag_none,
   2776 	  "[<period> <interval>] = set extended listen timing" },
   2777 	{ "p2p_remove_client", wpa_cli_cmd_p2p_remove_client,
   2778 	  wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
   2779 	  "<address|iface=address> = remove a peer from all groups" },
   2780 #endif /* CONFIG_P2P */
   2781 #ifdef CONFIG_WIFI_DISPLAY
   2782 	{ "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
   2783 	  cli_cmd_flag_none,
   2784 	  "<subelem> [contents] = set Wi-Fi Display subelement" },
   2785 	{ "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
   2786 	  cli_cmd_flag_none,
   2787 	  "<subelem> = get Wi-Fi Display subelement" },
   2788 #endif /* CONFIG_WIFI_DISPLAY */
   2789 #ifdef CONFIG_INTERWORKING
   2790 	{ "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
   2791 	  "= fetch ANQP information for all APs" },
   2792 	{ "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
   2793 	  cli_cmd_flag_none,
   2794 	  "= stop fetch_anqp operation" },
   2795 	{ "interworking_select", wpa_cli_cmd_interworking_select, NULL,
   2796 	  cli_cmd_flag_none,
   2797 	  "[auto] = perform Interworking network selection" },
   2798 	{ "interworking_connect", wpa_cli_cmd_interworking_connect,
   2799 	  wpa_cli_complete_bss, cli_cmd_flag_none,
   2800 	  "<BSSID> = connect using Interworking credentials" },
   2801 	{ "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
   2802 	  cli_cmd_flag_none,
   2803 	  "<addr> <info id>[,<info id>]... = request ANQP information" },
   2804 	{ "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
   2805 	  cli_cmd_flag_none,
   2806 	  "<addr> <AdvProtoID> [QueryReq] = GAS request" },
   2807 	{ "gas_response_get", wpa_cli_cmd_gas_response_get,
   2808 	  wpa_cli_complete_bss, cli_cmd_flag_none,
   2809 	  "<addr> <dialog token> [start,len] = Fetch last GAS response" },
   2810 #endif /* CONFIG_INTERWORKING */
   2811 #ifdef CONFIG_HS20
   2812 	{ "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
   2813 	  cli_cmd_flag_none,
   2814 	  "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
   2815 	},
   2816 	{ "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
   2817 	  wpa_cli_complete_bss, cli_cmd_flag_none,
   2818 	  "<addr> <home realm> = get HS20 nai home realm list" },
   2819 #endif /* CONFIG_HS20 */
   2820 	{ "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
   2821 	  cli_cmd_flag_none,
   2822 	  "<0/1> = disable/enable automatic reconnection" },
   2823 	{ "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
   2824 	  cli_cmd_flag_none,
   2825 	  "<addr> = request TDLS discovery with <addr>" },
   2826 	{ "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
   2827 	  cli_cmd_flag_none,
   2828 	  "<addr> = request TDLS setup with <addr>" },
   2829 	{ "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
   2830 	  cli_cmd_flag_none,
   2831 	  "<addr> = tear down TDLS with <addr>" },
   2832 	{ "signal_poll", wpa_cli_cmd_signal_poll, NULL,
   2833 	  cli_cmd_flag_none,
   2834 	  "= get signal parameters" },
   2835 	{ "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
   2836 	  cli_cmd_flag_none,
   2837 	  "= get TX/RX packet counters" },
   2838 	{ "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
   2839 	  cli_cmd_flag_none,
   2840 	  "= trigger IEEE 802.1X/EAPOL reauthentication" },
   2841 #ifdef CONFIG_AUTOSCAN
   2842 	{ "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
   2843 	  "[params] = Set or unset (if none) autoscan parameters" },
   2844 #endif /* CONFIG_AUTOSCAN */
   2845 #ifdef CONFIG_WNM
   2846 	{ "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
   2847 	  "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
   2848 	{ "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
   2849 	  "<query reason> = Send BSS Transition Management Query" },
   2850 #endif /* CONFIG_WNM */
   2851 	{ "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
   2852 	  "<params..> = Sent unprocessed command" },
   2853 	{ "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
   2854 	  "= flush wpa_supplicant state" },
   2855 #ifdef ANDROID
   2856 	{ "driver", wpa_cli_cmd_driver, NULL,
   2857 	  cli_cmd_flag_none,
   2858 	  "<command> = driver private commands" },
   2859 #endif
   2860 	{ NULL, NULL, NULL, cli_cmd_flag_none, NULL }
   2861 };
   2862 
   2863 
   2864 /*
   2865  * Prints command usage, lines are padded with the specified string.
   2866  */
   2867 static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
   2868 {
   2869 	char c;
   2870 	size_t n;
   2871 
   2872 	printf("%s%s ", pad, cmd->cmd);
   2873 	for (n = 0; (c = cmd->usage[n]); n++) {
   2874 		printf("%c", c);
   2875 		if (c == '\n')
   2876 			printf("%s", pad);
   2877 	}
   2878 	printf("\n");
   2879 }
   2880 
   2881 
   2882 static void print_help(const char *cmd)
   2883 {
   2884 	int n;
   2885 	printf("commands:\n");
   2886 	for (n = 0; wpa_cli_commands[n].cmd; n++) {
   2887 		if (cmd == NULL || str_starts(wpa_cli_commands[n].cmd, cmd))
   2888 			print_cmd_help(&wpa_cli_commands[n], "  ");
   2889 	}
   2890 }
   2891 
   2892 
   2893 static int wpa_cli_edit_filter_history_cb(void *ctx, const char *cmd)
   2894 {
   2895 	const char *c, *delim;
   2896 	int n;
   2897 	size_t len;
   2898 
   2899 	delim = os_strchr(cmd, ' ');
   2900 	if (delim)
   2901 		len = delim - cmd;
   2902 	else
   2903 		len = os_strlen(cmd);
   2904 
   2905 	for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
   2906 		if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
   2907 			return (wpa_cli_commands[n].flags &
   2908 				cli_cmd_flag_sensitive);
   2909 	}
   2910 	return 0;
   2911 }
   2912 
   2913 
   2914 static char ** wpa_list_cmd_list(void)
   2915 {
   2916 	char **res;
   2917 	int i, count;
   2918 	struct cli_txt_entry *e;
   2919 
   2920 	count = sizeof(wpa_cli_commands) / sizeof(wpa_cli_commands[0]);
   2921 	count += dl_list_len(&p2p_groups);
   2922 	count += dl_list_len(&ifnames);
   2923 	res = os_calloc(count + 1, sizeof(char *));
   2924 	if (res == NULL)
   2925 		return NULL;
   2926 
   2927 	for (i = 0; wpa_cli_commands[i].cmd; i++) {
   2928 		res[i] = os_strdup(wpa_cli_commands[i].cmd);
   2929 		if (res[i] == NULL)
   2930 			break;
   2931 	}
   2932 
   2933 	dl_list_for_each(e, &p2p_groups, struct cli_txt_entry, list) {
   2934 		size_t len = 8 + os_strlen(e->txt);
   2935 		res[i] = os_malloc(len);
   2936 		if (res[i] == NULL)
   2937 			break;
   2938 		os_snprintf(res[i], len, "ifname=%s", e->txt);
   2939 		i++;
   2940 	}
   2941 
   2942 	dl_list_for_each(e, &ifnames, struct cli_txt_entry, list) {
   2943 		res[i] = os_strdup(e->txt);
   2944 		if (res[i] == NULL)
   2945 			break;
   2946 		i++;
   2947 	}
   2948 
   2949 	return res;
   2950 }
   2951 
   2952 
   2953 static char ** wpa_cli_cmd_completion(const char *cmd, const char *str,
   2954 				      int pos)
   2955 {
   2956 	int i;
   2957 
   2958 	for (i = 0; wpa_cli_commands[i].cmd; i++) {
   2959 		if (os_strcasecmp(wpa_cli_commands[i].cmd, cmd) == 0) {
   2960 			if (wpa_cli_commands[i].completion)
   2961 				return wpa_cli_commands[i].completion(str,
   2962 								      pos);
   2963 			edit_clear_line();
   2964 			printf("\r%s\n", wpa_cli_commands[i].usage);
   2965 			edit_redraw();
   2966 			break;
   2967 		}
   2968 	}
   2969 
   2970 	return NULL;
   2971 }
   2972 
   2973 
   2974 static char ** wpa_cli_edit_completion_cb(void *ctx, const char *str, int pos)
   2975 {
   2976 	char **res;
   2977 	const char *end;
   2978 	char *cmd;
   2979 
   2980 	if (pos > 7 && os_strncasecmp(str, "IFNAME=", 7) == 0) {
   2981 		end = os_strchr(str, ' ');
   2982 		if (end && pos > end - str) {
   2983 			pos -= end - str + 1;
   2984 			str = end + 1;
   2985 		}
   2986 	}
   2987 
   2988 	end = os_strchr(str, ' ');
   2989 	if (end == NULL || str + pos < end)
   2990 		return wpa_list_cmd_list();
   2991 
   2992 	cmd = os_malloc(pos + 1);
   2993 	if (cmd == NULL)
   2994 		return NULL;
   2995 	os_memcpy(cmd, str, pos);
   2996 	cmd[end - str] = '\0';
   2997 	res = wpa_cli_cmd_completion(cmd, str, pos);
   2998 	os_free(cmd);
   2999 	return res;
   3000 }
   3001 
   3002 
   3003 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
   3004 {
   3005 	struct wpa_cli_cmd *cmd, *match = NULL;
   3006 	int count;
   3007 	int ret = 0;
   3008 
   3009 	if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) {
   3010 		ifname_prefix = argv[0] + 7;
   3011 		argv = &argv[1];
   3012 		argc--;
   3013 	} else
   3014 		ifname_prefix = NULL;
   3015 
   3016 	if (argc == 0)
   3017 		return -1;
   3018 
   3019 	count = 0;
   3020 	cmd = wpa_cli_commands;
   3021 	while (cmd->cmd) {
   3022 		if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
   3023 		{
   3024 			match = cmd;
   3025 			if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
   3026 				/* we have an exact match */
   3027 				count = 1;
   3028 				break;
   3029 			}
   3030 			count++;
   3031 		}
   3032 		cmd++;
   3033 	}
   3034 
   3035 	if (count > 1) {
   3036 		printf("Ambiguous command '%s'; possible commands:", argv[0]);
   3037 		cmd = wpa_cli_commands;
   3038 		while (cmd->cmd) {
   3039 			if (os_strncasecmp(cmd->cmd, argv[0],
   3040 					   os_strlen(argv[0])) == 0) {
   3041 				printf(" %s", cmd->cmd);
   3042 			}
   3043 			cmd++;
   3044 		}
   3045 		printf("\n");
   3046 		ret = 1;
   3047 	} else if (count == 0) {
   3048 		printf("Unknown command '%s'\n", argv[0]);
   3049 		ret = 1;
   3050 	} else {
   3051 		ret = match->handler(ctrl, argc - 1, &argv[1]);
   3052 	}
   3053 
   3054 	return ret;
   3055 }
   3056 
   3057 
   3058 static int str_match(const char *a, const char *b)
   3059 {
   3060 	return os_strncmp(a, b, os_strlen(b)) == 0;
   3061 }
   3062 
   3063 
   3064 static int wpa_cli_exec(const char *program, const char *arg1,
   3065 			const char *arg2)
   3066 {
   3067 	char *cmd;
   3068 	size_t len;
   3069 	int res;
   3070 	int ret = 0;
   3071 
   3072 	len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
   3073 	cmd = os_malloc(len);
   3074 	if (cmd == NULL)
   3075 		return -1;
   3076 	res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
   3077 	if (res < 0 || (size_t) res >= len) {
   3078 		os_free(cmd);
   3079 		return -1;
   3080 	}
   3081 	cmd[len - 1] = '\0';
   3082 #ifndef _WIN32_WCE
   3083 	if (system(cmd) < 0)
   3084 		ret = -1;
   3085 #endif /* _WIN32_WCE */
   3086 	os_free(cmd);
   3087 
   3088 	return ret;
   3089 }
   3090 
   3091 
   3092 static void wpa_cli_action_process(const char *msg)
   3093 {
   3094 	const char *pos;
   3095 	char *copy = NULL, *id, *pos2;
   3096 
   3097 	pos = msg;
   3098 	if (*pos == '<') {
   3099 		/* skip priority */
   3100 		pos = os_strchr(pos, '>');
   3101 		if (pos)
   3102 			pos++;
   3103 		else
   3104 			pos = msg;
   3105 	}
   3106 
   3107 	if (str_match(pos, WPA_EVENT_CONNECTED)) {
   3108 		int new_id = -1;
   3109 		os_unsetenv("WPA_ID");
   3110 		os_unsetenv("WPA_ID_STR");
   3111 		os_unsetenv("WPA_CTRL_DIR");
   3112 
   3113 		pos = os_strstr(pos, "[id=");
   3114 		if (pos)
   3115 			copy = os_strdup(pos + 4);
   3116 
   3117 		if (copy) {
   3118 			pos2 = id = copy;
   3119 			while (*pos2 && *pos2 != ' ')
   3120 				pos2++;
   3121 			*pos2++ = '\0';
   3122 			new_id = atoi(id);
   3123 			os_setenv("WPA_ID", id, 1);
   3124 			while (*pos2 && *pos2 != '=')
   3125 				pos2++;
   3126 			if (*pos2 == '=')
   3127 				pos2++;
   3128 			id = pos2;
   3129 			while (*pos2 && *pos2 != ']')
   3130 				pos2++;
   3131 			*pos2 = '\0';
   3132 			os_setenv("WPA_ID_STR", id, 1);
   3133 			os_free(copy);
   3134 		}
   3135 
   3136 		os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
   3137 
   3138 		if (wpa_cli_connected <= 0 || new_id != wpa_cli_last_id) {
   3139 			wpa_cli_connected = 1;
   3140 			wpa_cli_last_id = new_id;
   3141 			wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
   3142 		}
   3143 	} else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
   3144 		if (wpa_cli_connected) {
   3145 			wpa_cli_connected = 0;
   3146 			wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
   3147 		}
   3148 	} else if (str_match(pos, P2P_EVENT_GROUP_STARTED)) {
   3149 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3150 	} else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
   3151 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3152 	} else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
   3153 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3154 	} else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
   3155 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3156 	} else if (str_match(pos, P2P_EVENT_GO_NEG_FAILURE)) {
   3157 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3158 	} else if (str_match(pos, WPS_EVENT_SUCCESS)) {
   3159 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3160 	} else if (str_match(pos, WPS_EVENT_FAIL)) {
   3161 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3162 	} else if (str_match(pos, AP_STA_CONNECTED)) {
   3163 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3164 	} else if (str_match(pos, AP_STA_DISCONNECTED)) {
   3165 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3166 	} else if (str_match(pos, ESS_DISASSOC_IMMINENT)) {
   3167 		wpa_cli_exec(action_file, ctrl_ifname, pos);
   3168 	} else if (str_match(pos, WPA_EVENT_TERMINATING)) {
   3169 		printf("wpa_supplicant is terminating - stop monitoring\n");
   3170 		wpa_cli_quit = 1;
   3171 	}
   3172 }
   3173 
   3174 
   3175 #ifndef CONFIG_ANSI_C_EXTRA
   3176 static void wpa_cli_action_cb(char *msg, size_t len)
   3177 {
   3178 	wpa_cli_action_process(msg);
   3179 }
   3180 #endif /* CONFIG_ANSI_C_EXTRA */
   3181 
   3182 
   3183 static void wpa_cli_reconnect(void)
   3184 {
   3185 	wpa_cli_close_connection();
   3186 	if (wpa_cli_open_connection(ctrl_ifname, 1) < 0)
   3187 		return;
   3188 
   3189 	if (interactive) {
   3190 		edit_clear_line();
   3191 		printf("\rConnection to wpa_supplicant re-established\n");
   3192 		edit_redraw();
   3193 	}
   3194 }
   3195 
   3196 
   3197 static void cli_event(const char *str)
   3198 {
   3199 	const char *start, *s;
   3200 
   3201 	start = os_strchr(str, '>');
   3202 	if (start == NULL)
   3203 		return;
   3204 
   3205 	start++;
   3206 
   3207 	if (str_starts(start, WPA_EVENT_BSS_ADDED)) {
   3208 		s = os_strchr(start, ' ');
   3209 		if (s == NULL)
   3210 			return;
   3211 		s = os_strchr(s + 1, ' ');
   3212 		if (s == NULL)
   3213 			return;
   3214 		cli_txt_list_add(&bsses, s + 1);
   3215 		return;
   3216 	}
   3217 
   3218 	if (str_starts(start, WPA_EVENT_BSS_REMOVED)) {
   3219 		s = os_strchr(start, ' ');
   3220 		if (s == NULL)
   3221 			return;
   3222 		s = os_strchr(s + 1, ' ');
   3223 		if (s == NULL)
   3224 			return;
   3225 		cli_txt_list_del_addr(&bsses, s + 1);
   3226 		return;
   3227 	}
   3228 
   3229 #ifdef CONFIG_P2P
   3230 	if (str_starts(start, P2P_EVENT_DEVICE_FOUND)) {
   3231 		s = os_strstr(start, " p2p_dev_addr=");
   3232 		if (s == NULL)
   3233 			return;
   3234 		cli_txt_list_add_addr(&p2p_peers, s + 14);
   3235 		return;
   3236 	}
   3237 
   3238 	if (str_starts(start, P2P_EVENT_DEVICE_LOST)) {
   3239 		s = os_strstr(start, " p2p_dev_addr=");
   3240 		if (s == NULL)
   3241 			return;
   3242 		cli_txt_list_del_addr(&p2p_peers, s + 14);
   3243 		return;
   3244 	}
   3245 
   3246 	if (str_starts(start, P2P_EVENT_GROUP_STARTED)) {
   3247 		s = os_strchr(start, ' ');
   3248 		if (s == NULL)
   3249 			return;
   3250 		cli_txt_list_add_word(&p2p_groups, s + 1);
   3251 		return;
   3252 	}
   3253 
   3254 	if (str_starts(start, P2P_EVENT_GROUP_REMOVED)) {
   3255 		s = os_strchr(start, ' ');
   3256 		if (s == NULL)
   3257 			return;
   3258 		cli_txt_list_del_word(&p2p_groups, s + 1);
   3259 		return;
   3260 	}
   3261 #endif /* CONFIG_P2P */
   3262 }
   3263 
   3264 
   3265 static int check_terminating(const char *msg)
   3266 {
   3267 	const char *pos = msg;
   3268 
   3269 	if (*pos == '<') {
   3270 		/* skip priority */
   3271 		pos = os_strchr(pos, '>');
   3272 		if (pos)
   3273 			pos++;
   3274 		else
   3275 			pos = msg;
   3276 	}
   3277 
   3278 	if (str_match(pos, WPA_EVENT_TERMINATING) && ctrl_conn) {
   3279 		edit_clear_line();
   3280 		printf("\rConnection to wpa_supplicant lost - trying to "
   3281 		       "reconnect\n");
   3282 		edit_redraw();
   3283 		wpa_cli_attached = 0;
   3284 		wpa_cli_close_connection();
   3285 		return 1;
   3286 	}
   3287 
   3288 	return 0;
   3289 }
   3290 
   3291 
   3292 static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int action_monitor)
   3293 {
   3294 	if (ctrl_conn == NULL) {
   3295 		wpa_cli_reconnect();
   3296 		return;
   3297 	}
   3298 	while (wpa_ctrl_pending(ctrl) > 0) {
   3299 		char buf[256];
   3300 		size_t len = sizeof(buf) - 1;
   3301 		if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
   3302 			buf[len] = '\0';
   3303 			if (action_monitor)
   3304 				wpa_cli_action_process(buf);
   3305 			else {
   3306 				cli_event(buf);
   3307 				if (wpa_cli_show_event(buf)) {
   3308 					edit_clear_line();
   3309 					printf("\r%s\n", buf);
   3310 					edit_redraw();
   3311 				}
   3312 
   3313 				if (interactive && check_terminating(buf) > 0)
   3314 					return;
   3315 			}
   3316 		} else {
   3317 			printf("Could not read pending message.\n");
   3318 			break;
   3319 		}
   3320 	}
   3321 
   3322 	if (wpa_ctrl_pending(ctrl) < 0) {
   3323 		printf("Connection to wpa_supplicant lost - trying to "
   3324 		       "reconnect\n");
   3325 		wpa_cli_reconnect();
   3326 	}
   3327 }
   3328 
   3329 #define max_args 10
   3330 
   3331 static int tokenize_cmd(char *cmd, char *argv[])
   3332 {
   3333 	char *pos;
   3334 	int argc = 0;
   3335 
   3336 	pos = cmd;
   3337 	for (;;) {
   3338 		while (*pos == ' ')
   3339 			pos++;
   3340 		if (*pos == '\0')
   3341 			break;
   3342 		argv[argc] = pos;
   3343 		argc++;
   3344 		if (argc == max_args)
   3345 			break;
   3346 		if (*pos == '"') {
   3347 			char *pos2 = os_strrchr(pos, '"');
   3348 			if (pos2)
   3349 				pos = pos2 + 1;
   3350 		}
   3351 		while (*pos != '\0' && *pos != ' ')
   3352 			pos++;
   3353 		if (*pos == ' ')
   3354 			*pos++ = '\0';
   3355 	}
   3356 
   3357 	return argc;
   3358 }
   3359 
   3360 
   3361 static void wpa_cli_ping(void *eloop_ctx, void *timeout_ctx)
   3362 {
   3363 	if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
   3364 		printf("Connection to wpa_supplicant lost - trying to "
   3365 		       "reconnect\n");
   3366 		wpa_cli_close_connection();
   3367 	}
   3368 	if (!ctrl_conn)
   3369 		wpa_cli_reconnect();
   3370 	eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
   3371 }
   3372 
   3373 
   3374 static void wpa_cli_mon_receive(int sock, void *eloop_ctx, void *sock_ctx)
   3375 {
   3376 	wpa_cli_recv_pending(mon_conn, 0);
   3377 }
   3378 
   3379 
   3380 static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
   3381 {
   3382 	char *argv[max_args];
   3383 	int argc;
   3384 	argc = tokenize_cmd(cmd, argv);
   3385 	if (argc)
   3386 		wpa_request(ctrl_conn, argc, argv);
   3387 }
   3388 
   3389 
   3390 static void wpa_cli_edit_eof_cb(void *ctx)
   3391 {
   3392 	eloop_terminate();
   3393 }
   3394 
   3395 
   3396 static int warning_displayed = 0;
   3397 static char *hfile = NULL;
   3398 static int edit_started = 0;
   3399 
   3400 static void start_edit(void)
   3401 {
   3402 	char *home;
   3403 	char *ps = NULL;
   3404 
   3405 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
   3406 	ps = wpa_ctrl_get_remote_ifname(ctrl_conn);
   3407 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
   3408 
   3409 	home = getenv("HOME");
   3410 	if (home) {
   3411 		const char *fname = ".wpa_cli_history";
   3412 		int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
   3413 		hfile = os_malloc(hfile_len);
   3414 		if (hfile)
   3415 			os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
   3416 	}
   3417 
   3418 	if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
   3419 		      wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
   3420 		eloop_terminate();
   3421 		return;
   3422 	}
   3423 
   3424 	edit_started = 1;
   3425 	eloop_register_timeout(ping_interval, 0, wpa_cli_ping, NULL, NULL);
   3426 }
   3427 
   3428 
   3429 static void update_bssid_list(struct wpa_ctrl *ctrl)
   3430 {
   3431 	char buf[4096];
   3432 	size_t len = sizeof(buf);
   3433 	int ret;
   3434 	char *cmd = "BSS RANGE=ALL MASK=0x2";
   3435 	char *pos, *end;
   3436 
   3437 	if (ctrl == NULL)
   3438 		return;
   3439 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
   3440 	if (ret < 0)
   3441 		return;
   3442 	buf[len] = '\0';
   3443 
   3444 	pos = buf;
   3445 	while (pos) {
   3446 		pos = os_strstr(pos, "bssid=");
   3447 		if (pos == NULL)
   3448 			break;
   3449 		pos += 6;
   3450 		end = os_strchr(pos, '\n');
   3451 		if (end == NULL)
   3452 			break;
   3453 		*end = '\0';
   3454 		cli_txt_list_add(&bsses, pos);
   3455 		pos = end + 1;
   3456 	}
   3457 }
   3458 
   3459 
   3460 static void update_ifnames(struct wpa_ctrl *ctrl)
   3461 {
   3462 	char buf[4096];
   3463 	size_t len = sizeof(buf);
   3464 	int ret;
   3465 	char *cmd = "INTERFACES";
   3466 	char *pos, *end;
   3467 	char txt[200];
   3468 
   3469 	cli_txt_list_flush(&ifnames);
   3470 
   3471 	if (ctrl == NULL)
   3472 		return;
   3473 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, NULL);
   3474 	if (ret < 0)
   3475 		return;
   3476 	buf[len] = '\0';
   3477 
   3478 	pos = buf;
   3479 	while (pos) {
   3480 		end = os_strchr(pos, '\n');
   3481 		if (end == NULL)
   3482 			break;
   3483 		*end = '\0';
   3484 		ret = os_snprintf(txt, sizeof(txt), "ifname=%s", pos);
   3485 		if (ret > 0 && ret < (int) sizeof(txt))
   3486 			cli_txt_list_add(&ifnames, txt);
   3487 		pos = end + 1;
   3488 	}
   3489 }
   3490 
   3491 
   3492 static void try_connection(void *eloop_ctx, void *timeout_ctx)
   3493 {
   3494 	if (ctrl_conn)
   3495 		goto done;
   3496 
   3497 	if (ctrl_ifname == NULL)
   3498 		ctrl_ifname = wpa_cli_get_default_ifname();
   3499 
   3500 	if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
   3501 		if (!warning_displayed) {
   3502 			printf("Could not connect to wpa_supplicant: "
   3503 			       "%s - re-trying\n", ctrl_ifname);
   3504 			warning_displayed = 1;
   3505 		}
   3506 		eloop_register_timeout(1, 0, try_connection, NULL, NULL);
   3507 		return;
   3508 	}
   3509 
   3510 	update_bssid_list(ctrl_conn);
   3511 
   3512 	if (warning_displayed)
   3513 		printf("Connection established.\n");
   3514 
   3515 done:
   3516 	start_edit();
   3517 }
   3518 
   3519 
   3520 static void wpa_cli_interactive(void)
   3521 {
   3522 	printf("\nInteractive mode\n\n");
   3523 
   3524 	eloop_register_timeout(0, 0, try_connection, NULL, NULL);
   3525 	eloop_run();
   3526 	eloop_cancel_timeout(try_connection, NULL, NULL);
   3527 
   3528 	cli_txt_list_flush(&p2p_peers);
   3529 	cli_txt_list_flush(&p2p_groups);
   3530 	cli_txt_list_flush(&bsses);
   3531 	cli_txt_list_flush(&ifnames);
   3532 	if (edit_started)
   3533 		edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
   3534 	os_free(hfile);
   3535 	eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
   3536 	wpa_cli_close_connection();
   3537 }
   3538 
   3539 
   3540 static void wpa_cli_action(struct wpa_ctrl *ctrl)
   3541 {
   3542 #ifdef CONFIG_ANSI_C_EXTRA
   3543 	/* TODO: ANSI C version(?) */
   3544 	printf("Action processing not supported in ANSI C build.\n");
   3545 #else /* CONFIG_ANSI_C_EXTRA */
   3546 	fd_set rfds;
   3547 	int fd, res;
   3548 	struct timeval tv;
   3549 	char buf[256]; /* note: large enough to fit in unsolicited messages */
   3550 	size_t len;
   3551 
   3552 	fd = wpa_ctrl_get_fd(ctrl);
   3553 
   3554 	while (!wpa_cli_quit) {
   3555 		FD_ZERO(&rfds);
   3556 		FD_SET(fd, &rfds);
   3557 		tv.tv_sec = ping_interval;
   3558 		tv.tv_usec = 0;
   3559 		res = select(fd + 1, &rfds, NULL, NULL, &tv);
   3560 		if (res < 0 && errno != EINTR) {
   3561 			perror("select");
   3562 			break;
   3563 		}
   3564 
   3565 		if (FD_ISSET(fd, &rfds))
   3566 			wpa_cli_recv_pending(ctrl, 1);
   3567 		else {
   3568 			/* verify that connection is still working */
   3569 			len = sizeof(buf) - 1;
   3570 			if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
   3571 					     wpa_cli_action_cb) < 0 ||
   3572 			    len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
   3573 				printf("wpa_supplicant did not reply to PING "
   3574 				       "command - exiting\n");
   3575 				break;
   3576 			}
   3577 		}
   3578 	}
   3579 #endif /* CONFIG_ANSI_C_EXTRA */
   3580 }
   3581 
   3582 
   3583 static void wpa_cli_cleanup(void)
   3584 {
   3585 	wpa_cli_close_connection();
   3586 	if (pid_file)
   3587 		os_daemonize_terminate(pid_file);
   3588 
   3589 	os_program_deinit();
   3590 }
   3591 
   3592 
   3593 static void wpa_cli_terminate(int sig, void *ctx)
   3594 {
   3595 	eloop_terminate();
   3596 }
   3597 
   3598 
   3599 static char * wpa_cli_get_default_ifname(void)
   3600 {
   3601 	char *ifname = NULL;
   3602 
   3603 #ifdef CONFIG_CTRL_IFACE_UNIX
   3604 	struct dirent *dent;
   3605 	DIR *dir = opendir(ctrl_iface_dir);
   3606 	if (!dir) {
   3607 #ifdef ANDROID
   3608 		char ifprop[PROPERTY_VALUE_MAX];
   3609 		if (property_get("wifi.interface", ifprop, NULL) != 0) {
   3610 			ifname = os_strdup(ifprop);
   3611 			printf("Using interface '%s'\n", ifname);
   3612 			return ifname;
   3613 		}
   3614 #endif /* ANDROID */
   3615 		return NULL;
   3616 	}
   3617 	while ((dent = readdir(dir))) {
   3618 #ifdef _DIRENT_HAVE_D_TYPE
   3619 		/*
   3620 		 * Skip the file if it is not a socket. Also accept
   3621 		 * DT_UNKNOWN (0) in case the C library or underlying
   3622 		 * file system does not support d_type.
   3623 		 */
   3624 		if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
   3625 			continue;
   3626 #endif /* _DIRENT_HAVE_D_TYPE */
   3627 		if (os_strcmp(dent->d_name, ".") == 0 ||
   3628 		    os_strcmp(dent->d_name, "..") == 0)
   3629 			continue;
   3630 		printf("Selected interface '%s'\n", dent->d_name);
   3631 		ifname = os_strdup(dent->d_name);
   3632 		break;
   3633 	}
   3634 	closedir(dir);
   3635 #endif /* CONFIG_CTRL_IFACE_UNIX */
   3636 
   3637 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
   3638 	char buf[4096], *pos;
   3639 	size_t len;
   3640 	struct wpa_ctrl *ctrl;
   3641 	int ret;
   3642 
   3643 	ctrl = wpa_ctrl_open(NULL);
   3644 	if (ctrl == NULL)
   3645 		return NULL;
   3646 
   3647 	len = sizeof(buf) - 1;
   3648 	ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
   3649 	if (ret >= 0) {
   3650 		buf[len] = '\0';
   3651 		pos = os_strchr(buf, '\n');
   3652 		if (pos)
   3653 			*pos = '\0';
   3654 		ifname = os_strdup(buf);
   3655 	}
   3656 	wpa_ctrl_close(ctrl);
   3657 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
   3658 
   3659 	return ifname;
   3660 }
   3661 
   3662 
   3663 int main(int argc, char *argv[])
   3664 {
   3665 	int c;
   3666 	int daemonize = 0;
   3667 	int ret = 0;
   3668 	const char *global = NULL;
   3669 
   3670 	if (os_program_init())
   3671 		return -1;
   3672 
   3673 	for (;;) {
   3674 		c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
   3675 		if (c < 0)
   3676 			break;
   3677 		switch (c) {
   3678 		case 'a':
   3679 			action_file = optarg;
   3680 			break;
   3681 		case 'B':
   3682 			daemonize = 1;
   3683 			break;
   3684 		case 'g':
   3685 			global = optarg;
   3686 			break;
   3687 		case 'G':
   3688 			ping_interval = atoi(optarg);
   3689 			break;
   3690 		case 'h':
   3691 			usage();
   3692 			return 0;
   3693 		case 'v':
   3694 			printf("%s\n", wpa_cli_version);
   3695 			return 0;
   3696 		case 'i':
   3697 			os_free(ctrl_ifname);
   3698 			ctrl_ifname = os_strdup(optarg);
   3699 			break;
   3700 		case 'p':
   3701 			ctrl_iface_dir = optarg;
   3702 			break;
   3703 		case 'P':
   3704 			pid_file = optarg;
   3705 			break;
   3706 		default:
   3707 			usage();
   3708 			return -1;
   3709 		}
   3710 	}
   3711 
   3712 	interactive = (argc == optind) && (action_file == NULL);
   3713 
   3714 	if (interactive)
   3715 		printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
   3716 
   3717 	if (eloop_init())
   3718 		return -1;
   3719 
   3720 	if (global) {
   3721 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
   3722 		ctrl_conn = wpa_ctrl_open(NULL);
   3723 #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
   3724 		ctrl_conn = wpa_ctrl_open(global);
   3725 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
   3726 		if (ctrl_conn == NULL) {
   3727 			fprintf(stderr, "Failed to connect to wpa_supplicant "
   3728 				"global interface: %s  error: %s\n",
   3729 				global, strerror(errno));
   3730 			return -1;
   3731 		}
   3732 
   3733 		if (interactive) {
   3734 			update_ifnames(ctrl_conn);
   3735 			mon_conn = wpa_ctrl_open(global);
   3736 			if (mon_conn) {
   3737 				if (wpa_ctrl_attach(mon_conn) == 0) {
   3738 					wpa_cli_attached = 1;
   3739 					eloop_register_read_sock(
   3740 						wpa_ctrl_get_fd(mon_conn),
   3741 						wpa_cli_mon_receive,
   3742 						NULL, NULL);
   3743 				} else {
   3744 					printf("Failed to open monitor "
   3745 					       "connection through global "
   3746 					       "control interface\n");
   3747 				}
   3748 			}
   3749 		}
   3750 	}
   3751 
   3752 	eloop_register_signal_terminate(wpa_cli_terminate, NULL);
   3753 
   3754 	if (ctrl_ifname == NULL)
   3755 		ctrl_ifname = wpa_cli_get_default_ifname();
   3756 
   3757 	if (interactive) {
   3758 		wpa_cli_interactive();
   3759 	} else {
   3760 		if (!global &&
   3761 		    wpa_cli_open_connection(ctrl_ifname, 0) < 0) {
   3762 			fprintf(stderr, "Failed to connect to non-global "
   3763 				"ctrl_ifname: %s  error: %s\n",
   3764 				ctrl_ifname, strerror(errno));
   3765 			return -1;
   3766 		}
   3767 
   3768 		if (action_file) {
   3769 			if (wpa_ctrl_attach(ctrl_conn) == 0) {
   3770 				wpa_cli_attached = 1;
   3771 			} else {
   3772 				printf("Warning: Failed to attach to "
   3773 				       "wpa_supplicant.\n");
   3774 				return -1;
   3775 			}
   3776 		}
   3777 
   3778 		if (daemonize && os_daemonize(pid_file))
   3779 			return -1;
   3780 
   3781 		if (action_file)
   3782 			wpa_cli_action(ctrl_conn);
   3783 		else
   3784 			ret = wpa_request(ctrl_conn, argc - optind,
   3785 					  &argv[optind]);
   3786 	}
   3787 
   3788 	os_free(ctrl_ifname);
   3789 	eloop_destroy();
   3790 	wpa_cli_cleanup();
   3791 
   3792 	return ret;
   3793 }
   3794 
   3795 #else /* CONFIG_CTRL_IFACE */
   3796 int main(int argc, char *argv[])
   3797 {
   3798 	printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
   3799 	return -1;
   3800 }
   3801 #endif /* CONFIG_CTRL_IFACE */
   3802