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