1 /*
2  * WPA CLI commands
3  * Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 #include "includes.h"
9 
10 #include "common/cli.h"
11 #include "common/wpa_ctrl.h"
12 #include "utils/common.h"
13 #include "utils/eloop.h"
14 #include "utils/edit.h"
15 #include "utils/list.h"
16 #include "wpa_supplicant_i.h"
17 #include "ctrl_iface.h"
18 #include "common/version.h"
19 #include "common/ieee802_11_defs.h"
20 
21 #define CMD_BUF_LEN  1024
22 
23 #define VENDOR_ELEM_FRAME_ID \
24 	"  0: Probe Req (P2P), 1: Probe Resp (P2P) , 2: Probe Resp (GO), " \
25 	"3: Beacon (GO), 4: PD Req, 5: PD Resp, 6: GO Neg Req, " \
26 	"7: GO Neg Resp, 8: GO Neg Conf, 9: Inv Req, 10: Inv Resp, " \
27 	"11: Assoc Req (P2P), 12: Assoc Resp (P2P)"
28 
29 static DEFINE_DL_LIST(bsses); /* struct cli_txt_entry */
30 static DEFINE_DL_LIST(p2p_peers); /* struct cli_txt_entry */
31 static DEFINE_DL_LIST(p2p_groups); /* struct cli_txt_entry */
32 static DEFINE_DL_LIST(ifnames); /* struct cli_txt_entry */
33 static DEFINE_DL_LIST(networks); /* struct cli_txt_entry */
34 static DEFINE_DL_LIST(creds); /* struct cli_txt_entry */
35 #ifdef CONFIG_AP
36 static DEFINE_DL_LIST(stations); /* struct cli_txt_entry */
37 #endif /* CONFIG_AP */
38 
wpa_cli_cmd(struct wpa_ctrl * ctrl,const char * cmd,int min_args,int argc,char * argv[])39 static int wpa_cli_cmd(struct wpa_ctrl *ctrl, const char *cmd, int min_args,
40 		       int argc, char *argv[])
41 {
42 	char buf[CMD_BUF_LEN] = {0};
43 	int ret = 0;
44 	bool interactive = 0;
45 
46 	for (int i = 0; i < argc; i++) {
47 		if (strcmp(argv[i], "interactive") == 0) {
48 			interactive = 1;
49 			argv[i] = NULL;
50 			argc--;
51 			break;
52 		}
53 	}
54 
55 	if (argc < min_args) {
56 		wpa_printf(MSG_INFO, "Invalid %s command - at least %d argument%s "
57 		       "required.\n", cmd, min_args,
58 		       min_args > 1 ? "s are" : " is");
59 		return -1;
60 	}
61 
62 	if (write_cmd(buf, CMD_BUF_LEN, cmd, argc, argv) < 0){
63 		ret = -1;
64 		goto out;
65 	}
66 
67 	if (interactive)
68 		ret = wpa_ctrl_command_interactive(ctrl, buf);
69 	else
70 		ret = wpa_ctrl_command(ctrl, buf);
71 
72 out:
73 	return ret;
74 }
75 
76 
77 static const char *network_fields[] = {
78 	"ssid", "scan_ssid", "bssid", "bssid_ignore",
79 	"bssid_accept", "psk", "proto", "key_mgmt",
80 	"bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq",
81 	"freq_list", "max_oper_chwidth", "ht40", "vht", "vht_center_freq1",
82 	"vht_center_freq2", "ht", "edmg",
83 #ifdef IEEE8021X_EAPOL
84 	"eap", "identity", "anonymous_identity", "password", "ca_cert",
85 	"ca_path", "client_cert", "private_key", "private_key_passwd",
86 	"dh_file", "subject_match", "altsubject_match",
87 	"check_cert_subject",
88 	"domain_suffix_match", "domain_match", "ca_cert2", "ca_path2",
89 	"client_cert2", "private_key2", "private_key2_passwd",
90 	"dh_file2", "subject_match2", "altsubject_match2",
91 	"check_cert_subject2",
92 	"domain_suffix_match2", "domain_match2", "phase1", "phase2",
93 	"pcsc", "pin", "engine_id", "key_id", "cert_id", "ca_cert_id",
94 	"pin2", "engine2_id", "key2_id", "cert2_id", "ca_cert2_id",
95 	"engine", "engine2", "eapol_flags", "sim_num",
96 	"openssl_ciphers", "erp",
97 #endif /* IEEE8021X_EAPOL */
98 	"wep_key0", "wep_key1", "wep_key2", "wep_key3",
99 	"wep_tx_keyidx", "priority",
100 #ifdef IEEE8021X_EAPOL
101 	"eap_workaround", "pac_file", "fragment_size", "ocsp",
102 #endif /* IEEE8021X_EAPOL */
103 	"mode",
104 	"proactive_key_caching", "disabled", "id_str",
105 	"ieee80211w",
106 	"mixed_cell", "frequency", "fixed_freq",
107 #ifdef CONFIG_MESH
108 	"no_auto_peer", "mesh_rssi_threshold",
109 	"mesh_basic_rates", "dot11MeshMaxRetries",
110 	"dot11MeshRetryTimeout", "dot11MeshConfirmTimeout",
111 	"dot11MeshHoldingTimeout",
112 #endif /* CONFIG_MESH */
113 	"wpa_ptk_rekey", "bgscan", "ignore_broadcast_ssid",
114 	"wpa_deny_ptk0_rekey",
115 	"enable_edmg", "edmg_channel",
116 #ifdef CONFIG_P2P
117 	"go_p2p_dev_addr", "p2p_client_list", "psk_list",
118 #endif /* CONFIG_P2P */
119 #ifdef CONFIG_HT_OVERRIDES
120 	"disable_ht", "disable_ht40", "disable_sgi", "disable_ldpc",
121 	"ht40_intolerant", "disable_max_amsdu", "ampdu_factor",
122 	"ampdu_density", "ht_mcs", "rx_stbc", "tx_stbc",
123 #endif /* CONFIG_HT_OVERRIDES */
124 #ifdef CONFIG_VHT_OVERRIDES
125 	"disable_vht", "vht_capa", "vht_capa_mask", "vht_rx_mcs_nss_1",
126 	"vht_rx_mcs_nss_2", "vht_rx_mcs_nss_3", "vht_rx_mcs_nss_4",
127 	"vht_rx_mcs_nss_5", "vht_rx_mcs_nss_6", "vht_rx_mcs_nss_7",
128 	"vht_rx_mcs_nss_8", "vht_tx_mcs_nss_1", "vht_tx_mcs_nss_2",
129 	"vht_tx_mcs_nss_3", "vht_tx_mcs_nss_4", "vht_tx_mcs_nss_5",
130 	"vht_tx_mcs_nss_6", "vht_tx_mcs_nss_7", "vht_tx_mcs_nss_8",
131 #endif /* CONFIG_VHT_OVERRIDES */
132 #ifdef CONFIG_HE_OVERRIDES
133 	"disable_he",
134 #endif /* CONFIG_HE_OVERRIDES */
135 	"ap_max_inactivity", "dtim_period", "beacon_int",
136 #ifdef CONFIG_MACSEC
137 	"macsec_policy",
138 	"macsec_integ_only",
139 	"macsec_replay_protect",
140 	"macsec_replay_window",
141 	"macsec_port",
142 	"mka_priority",
143 #endif /* CONFIG_MACSEC */
144 #ifdef CONFIG_HS20
145 	"update_identifier",
146 #endif /* CONFIG_HS20 */
147 	"mac_addr", "pbss", "wps_disabled"
148 };
149 
150 
wpa_cli_complete_network(const char * str,int pos)151 static char ** wpa_cli_complete_network(const char *str, int pos)
152 {
153 	int arg = get_cmd_arg_num(str, pos);
154 	int i, num_fields = ARRAY_SIZE(network_fields);
155 	char **res = NULL;
156 
157 	switch (arg) {
158 	case 1:
159 		res = cli_txt_list_array(&networks);
160 		break;
161 	case 2:
162 		res = os_calloc(num_fields + 1, sizeof(char *));
163 		if (res == NULL)
164 			return NULL;
165 		for (i = 0; i < num_fields; i++) {
166 			res[i] = os_strdup(network_fields[i]);
167 			if (res[i] == NULL)
168 				break;
169 		}
170 	}
171 	return res;
172 }
173 
wpa_cli_complete_network_id(const char * str,int pos)174 static char ** wpa_cli_complete_network_id(const char *str, int pos)
175 {
176 	int arg = get_cmd_arg_num(str, pos);
177 	if (arg == 1)
178 		return cli_txt_list_array(&networks);
179 	return NULL;
180 }
181 
wpa_cli_show_network_variables(void)182 static void wpa_cli_show_network_variables(void)
183 {
184 	wpa_printf(MSG_INFO, "set_network variables:\n"
185 	       "  ssid (network name, SSID)\n"
186 	       "  psk (WPA passphrase or pre-shared key)\n"
187 	       "  key_mgmt (key management protocol)\n"
188 	       "  identity (EAP identity)\n"
189 	       "  password (EAP password)\n"
190 	       "  ...\n"
191 	       "\n"
192 	       "Note: Values are entered in the same format as the "
193 	       "configuration file is using,\n"
194 	       "i.e., strings values need to be inside double quotation "
195 	       "marks.\n"
196 	       "For example: set_network 1 ssid \"network name\"\n"
197 	       "\n"
198 	       "Please see wpa_supplicant.conf documentation for full list "
199 	       "of\navailable variables.\n");
200 }
201 
202 
wpa_cli_cmd_set_network(struct wpa_ctrl * ctrl,int argc,char * argv[])203 static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
204 				   char *argv[])
205 {
206 	if (argc == 0) {
207 		wpa_cli_show_network_variables();
208 		return 0;
209 	}
210 
211 	if (argc < 3) {
212 		wpa_printf(MSG_INFO, "Invalid SET_NETWORK command: needs three arguments\n"
213 		       "(network id, variable name, and value)\n");
214 		return -1;
215 	}
216 
217 	return wpa_cli_cmd(ctrl, "SET_NETWORK", 3, argc, argv);
218 }
219 
220 
wpa_cli_cmd_get_network(struct wpa_ctrl * ctrl,int argc,char * argv[])221 static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
222 				   char *argv[])
223 {
224 	if (argc == 0) {
225 		wpa_cli_show_network_variables();
226 		return 0;
227 	}
228 
229 	if (argc < 2) {
230 		wpa_printf(MSG_INFO, "Invalid GET_NETWORK command: needs two arguments\n"
231 		       "(network id and variable name)\n");
232 		return -1;
233 	}
234 
235 	return wpa_cli_cmd(ctrl, "GET_NETWORK", 2, argc, argv);
236 }
237 
wpa_cli_cmd_list_networks(struct wpa_ctrl * ctrl,int argc,char * argv[])238 static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
239 				     char *argv[])
240 {
241 	return wpa_cli_cmd(ctrl, "LIST_NETWORKS", 0, argc, argv);
242 }
243 
244 
wpa_cli_cmd_select_network(struct wpa_ctrl * ctrl,int argc,char * argv[])245 static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
246 				      char *argv[])
247 {
248 	return wpa_cli_cmd(ctrl, "SELECT_NETWORK", 1, argc, argv);
249 }
250 
251 
wpa_cli_cmd_enable_network(struct wpa_ctrl * ctrl,int argc,char * argv[])252 static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
253 				      char *argv[])
254 {
255 	return wpa_cli_cmd(ctrl, "ENABLE_NETWORK", 1, argc, argv);
256 }
257 
258 
wpa_cli_cmd_disable_network(struct wpa_ctrl * ctrl,int argc,char * argv[])259 static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
260 				       char *argv[])
261 {
262 	return wpa_cli_cmd(ctrl, "DISABLE_NETWORK", 1, argc, argv);
263 }
264 
265 
wpa_cli_cmd_add_network(struct wpa_ctrl * ctrl,int argc,char * argv[])266 static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
267 				   char *argv[])
268 {
269 	return wpa_cli_cmd(ctrl, "ADD_NETWORK", 0, argc, argv);
270 }
271 
272 
wpa_cli_cmd_remove_network(struct wpa_ctrl * ctrl,int argc,char * argv[])273 static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
274 				      char *argv[])
275 {
276 	return wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv);
277 }
278 
279 
wpa_cli_cmd_disconnect(struct wpa_ctrl * ctrl,int argc,char * argv[])280 static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
281 				  char *argv[])
282 {
283 	return wpa_cli_cmd(ctrl, "DISCONNECT", 0, argc, argv);
284 }
285 
286 
wpa_cli_cmd_status(struct wpa_ctrl * ctrl,int argc,char * argv[])287 static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
288 {
289 	if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
290 		return wpa_cli_cmd(ctrl, "STATUS-VERBOSE", 0, argc, argv);
291 	if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
292 		return wpa_cli_cmd(ctrl, "STATUS-WPS", 0, argc, argv);
293 	if (argc > 0 && os_strcmp(argv[0], "driver") == 0)
294 		return wpa_cli_cmd(ctrl, "STATUS-DRIVER", 0, argc, argv);
295 	return wpa_cli_cmd(ctrl, "STATUS", 0, argc, argv);
296 }
297 
298 
wpa_cli_cmd_interface_add(struct wpa_ctrl * ctrl,int argc,char * argv[])299 static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
300 				     char *argv[])
301 {
302 	char cmd[256];
303 	int res;
304 
305 	if (argc < 1) {
306 		wpa_printf(MSG_INFO, "Invalid INTERFACE_ADD command: needs at least one "
307 		       "argument (interface name)\n"
308 		       "All arguments: ifname confname driver ctrl_interface "
309 		       "driver_param bridge_name [create]\n");
310 		return -1;
311 	}
312 
313 	/*
314 	 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
315 	 * <driver_param>TAB<bridge_name>[TAB<create>[TAB<type>]]
316 	 */
317 	res = os_snprintf(cmd, sizeof(cmd),
318 			  "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
319 			  argv[0],
320 			  argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
321 			  argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
322 			  argc > 5 ? argv[5] : "", argc > 6 ? argv[6] : "",
323 			  argc > 7 ? argv[7] : "");
324 	if (os_snprintf_error(sizeof(cmd), res))
325 		return -1;
326 	cmd[sizeof(cmd) - 1] = '\0';
327 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
328 }
329 
330 
wpa_cli_cmd_interface_remove(struct wpa_ctrl * ctrl,int argc,char * argv[])331 static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
332 					char *argv[])
333 {
334 	return wpa_cli_cmd(ctrl, "INTERFACE_REMOVE", 1, argc, argv);
335 }
336 
337 
wpa_cli_cmd_interface_list(struct wpa_ctrl * ctrl,int argc,char * argv[])338 static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
339 				      char *argv[])
340 {
341 	return wpa_cli_cmd(ctrl, "INTERFACE_LIST", 0, argc, argv);
342 }
343 
wpa_cli_cmd_set(struct wpa_ctrl * ctrl,int argc,char * argv[])344 static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
345 {
346 	char cmd[256];
347 	int res;
348 
349 	if (argc == 1) {
350 		res = os_snprintf(cmd, sizeof(cmd), "SET %s ", argv[0]);
351 		if (os_snprintf_error(sizeof(cmd), res)) {
352 			wpa_printf(MSG_INFO, "Too long SET command.\n");
353 			return -1;
354 		}
355 		return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
356 	}
357 
358 	return wpa_cli_cmd(ctrl, "SET", 2, argc, argv);
359 }
360 
361 
wpa_cli_complete_set(const char * str,int pos)362 static char ** wpa_cli_complete_set(const char *str, int pos)
363 {
364 	int arg = get_cmd_arg_num(str, pos);
365 	const char *fields[] = {
366 		/* runtime values */
367 		"EAPOL::heldPeriod", "EAPOL::authPeriod", "EAPOL::startPeriod",
368 		"EAPOL::maxStart", "dot11RSNAConfigPMKLifetime",
369 		"dot11RSNAConfigPMKReauthThreshold", "dot11RSNAConfigSATimeout",
370 		"wps_fragment_size", "wps_version_number", "ampdu",
371 		"tdls_testing", "tdls_disabled", "pno", "radio_disabled",
372 		"uapsd", "ps", "wifi_display", "bssid_filter", "disallow_aps",
373 		"no_keep_alive",
374 		/* global configuration parameters */
375 		"ctrl_interface", "no_ctrl_interface", "ctrl_interface_group",
376 		"eapol_version", "ap_scan", "bgscan",
377 #ifdef CONFIG_MESH
378 		"user_mpm", "max_peer_links", "mesh_max_inactivity",
379 		"dot11RSNASAERetransPeriod",
380 #endif /* CONFIG_MESH */
381 		"disable_scan_offload", "fast_reauth", "opensc_engine_path",
382 		"pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
383 		"pcsc_reader", "pcsc_pin", "external_sim", "driver_param",
384 		"dot11RSNAConfigPMKLifetime",
385 		"dot11RSNAConfigPMKReauthThreshold",
386 		"dot11RSNAConfigSATimeout",
387 #ifndef CONFIG_NO_CONFIG_WRITE
388 		"update_config",
389 #endif /* CONFIG_NO_CONFIG_WRITE */
390 		"load_dynamic_eap",
391 #ifdef CONFIG_WPS
392 		"uuid", "device_name", "manufacturer", "model_name",
393 		"model_number", "serial_number", "device_type", "os_version",
394 		"config_methods", "wps_cred_processing", "wps_vendor_ext_m1",
395 #endif /* CONFIG_WPS */
396 #ifdef CONFIG_P2P
397 		"sec_device_type",
398 		"p2p_listen_reg_class", "p2p_listen_channel",
399 		"p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent",
400 		"p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss",
401 		"p2p_group_idle", "p2p_passphrase_len", "p2p_pref_chan",
402 		"p2p_no_go_freq", "p2p_add_cli_chan",
403 		"p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht",
404 		"p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface",
405 		"p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask",
406 		"ip_addr_start", "ip_addr_end", "p2p_go_edmg",
407 #endif /* CONFIG_P2P */
408 		"country", "bss_max_count", "bss_expiration_age",
409 		"bss_expiration_scan_count", "filter_ssids", "filter_rssi",
410 		"max_num_sta", "disassoc_low_ack", "ap_isolate",
411 #ifdef CONFIG_HS20
412 		"hs20",
413 #endif /* CONFIG_HS20 */
414 		"interworking", "hessid", "access_network_type", "pbc_in_m1",
415 		"go_interworking", "go_access_network_type", "go_internet",
416 		"go_venue_group", "go_venue_type",
417 		"autoscan", "wps_nfc_dev_pw_id", "wps_nfc_dh_pubkey",
418 		"wps_nfc_dh_privkey", "wps_nfc_dev_pw", "ext_password_backend",
419 		"p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
420 		"sae_groups", "dtim_period", "beacon_int",
421 		"ap_vendor_elements", "ignore_old_scan_res", "freq_list",
422 		"scan_cur_freq", "scan_res_valid_for_connect",
423 		"sched_scan_interval",
424 		"tdls_external_control", "osu_dir", "wowlan_triggers",
425 		"p2p_search_delay", "mac_addr", "rand_addr_lifetime",
426 		"preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
427 		"reassoc_same_bss_optim", "wps_priority",
428 		"ap_assocresp_elements",
429 #ifdef CONFIG_TESTING_OPTIONS
430 		"ignore_auth_resp",
431 #endif /* CONFIG_TESTING_OPTIONS */
432 		"relative_rssi", "relative_band_adjust",
433 		"extended_key_id",
434 	};
435 	int i, num_fields = ARRAY_SIZE(fields);
436 
437 	if (arg == 1) {
438 		char **res = os_calloc(num_fields + 1, sizeof(char *));
439 		if (res == NULL)
440 			return NULL;
441 		for (i = 0; i < num_fields; i++) {
442 			res[i] = os_strdup(fields[i]);
443 			if (res[i] == NULL)
444 				return res;
445 		}
446 		return res;
447 	}
448 
449 	if (arg > 1 && os_strncasecmp(str, "set bssid_filter ", 17) == 0)
450 		return cli_txt_list_array(&bsses);
451 
452 	return NULL;
453 }
454 
455 #if CONFIG_AP || CONFIG_P2P || \
456 	!defined(__ZEPHYR__) || (defined(__ZEPHYR__) && defined(CONFIG_WPA_CLI))
wpa_cli_msg_cb(char * msg,size_t len)457 static void wpa_cli_msg_cb(char *msg, size_t len)
458 {
459 	wpa_printf(MSG_INFO, "%s\n", msg);
460 }
461 #endif
462 
463 #ifdef CONFIG_AP
wpa_cli_cmd_sta(struct wpa_ctrl * ctrl,int argc,char * argv[])464 static int wpa_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
465 {
466 	return wpa_cli_cmd(ctrl, "STA", 1, argc, argv);
467 }
468 
469 
wpa_cli_complete_sta(const char * str,int pos)470 static char **wpa_cli_complete_sta(const char *str, int pos)
471 {
472 	int arg = get_cmd_arg_num(str, pos);
473 	char **res = NULL;
474 
475 	switch (arg) {
476 	case 1:
477 		res = cli_txt_list_array(&stations);
478 		break;
479 	}
480 
481 	return res;
482 }
483 
484 
wpa_ctrl_command_sta(struct wpa_ctrl * ctrl,const char * cmd,char * addr,size_t addr_len,int print)485 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, const char *cmd,
486 				char *addr, size_t addr_len, int print)
487 {
488 	char buf[CMD_BUF_LEN], *pos;
489 	size_t len;
490 	int ret;
491 
492 	if (ctrl_conn == NULL) {
493 		wpa_printf(MSG_INFO, "Not connected to hostapd - command dropped.\n");
494 		return -1;
495 	}
496 	if (ifname_prefix) {
497 		os_snprintf(buf, sizeof(buf), "IFNAME=%s %s",
498 			    ifname_prefix, cmd);
499 		buf[sizeof(buf) - 1] = '\0';
500 		cmd = buf;
501 	}
502 	len = sizeof(buf) - 1;
503 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
504 			       wpa_cli_msg_cb);
505 	if (ret == -2) {
506 		wpa_printf(MSG_INFO, "'%s' command timed out.\n", cmd);
507 		return -2;
508 	} else if (ret < 0) {
509 		wpa_printf(MSG_INFO, "'%s' command failed.\n", cmd);
510 		return -1;
511 	}
512 
513 	buf[len] = '\0';
514 	if (os_memcmp(buf, "FAIL", 4) == 0 ||
515 	    os_memcmp(buf, "UNKNOWN COMMAND", 15) == 0)
516 		return -1;
517 	if (print)
518 		wpa_printf(MSG_INFO, "%s", buf);
519 
520 	pos = buf;
521 	while (*pos != '\0' && *pos != '\n')
522 		pos++;
523 	*pos = '\0';
524 	os_strlcpy(addr, buf, addr_len);
525 	return 0;
526 }
527 
528 
wpa_cli_cmd_all_sta(struct wpa_ctrl * ctrl,int argc,char * argv[])529 static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
530 {
531 	char addr[32], cmd[64];
532 
533 	if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 1))
534 		return 0;
535 	do {
536 		os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
537 	} while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 1) == 0);
538 
539 	return -1;
540 }
541 
542 
wpa_cli_cmd_list_sta(struct wpa_ctrl * ctrl,int argc,char * argv[])543 static int wpa_cli_cmd_list_sta(struct wpa_ctrl *ctrl, int argc,
544 				char *argv[])
545 {
546 	char addr[32], cmd[64];
547 
548 	if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr), 0))
549 		return 0;
550 	do {
551 		if (os_strcmp(addr, "") != 0)
552 			wpa_printf(MSG_INFO, "%s\n", addr);
553 		os_snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
554 	} while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr), 0) == 0);
555 
556 	return 0;
557 }
558 
559 
wpa_cli_cmd_deauthenticate(struct wpa_ctrl * ctrl,int argc,char * argv[])560 static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
561 				      char *argv[])
562 {
563 	return wpa_cli_cmd(ctrl, "DEAUTHENTICATE", 1, argc, argv);
564 }
565 
566 
wpa_cli_complete_deauthenticate(const char * str,int pos)567 static char **wpa_cli_complete_deauthenticate(const char *str, int pos)
568 {
569 	int arg = get_cmd_arg_num(str, pos);
570 	char **res = NULL;
571 
572 	switch (arg) {
573 	case 1:
574 		res = cli_txt_list_array(&stations);
575 		break;
576 	}
577 
578 	return res;
579 }
580 
581 
wpa_cli_cmd_disassociate(struct wpa_ctrl * ctrl,int argc,char * argv[])582 static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
583 				    char *argv[])
584 {
585 	return wpa_cli_cmd(ctrl, "DISASSOCIATE", 1, argc, argv);
586 }
587 
588 
wpa_cli_complete_disassociate(const char * str,int pos)589 static char **wpa_cli_complete_disassociate(const char *str, int pos)
590 {
591 	int arg = get_cmd_arg_num(str, pos);
592 	char **res = NULL;
593 
594 	switch (arg) {
595 	case 1:
596 		res = cli_txt_list_array(&stations);
597 		break;
598 	}
599 
600 	return res;
601 }
602 
603 
wpa_cli_cmd_chanswitch(struct wpa_ctrl * ctrl,int argc,char * argv[])604 static int wpa_cli_cmd_chanswitch(struct wpa_ctrl *ctrl, int argc,
605 				    char *argv[])
606 {
607 	return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv);
608 }
609 
610 
wpa_cli_cmd_update_beacon(struct wpa_ctrl * ctrl,int argc,char * argv[])611 static int wpa_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc,
612 				     char *argv[])
613 {
614 	return wpa_cli_cmd(ctrl, "UPDATE_BEACON", 0, argc, argv);
615 }
616 #endif /* CONFIG_AP */
617 
618 #if !defined(__ZEPHYR__) || (defined(__ZEPHYR__) && defined(CONFIG_WPA_CLI))
wpa_cli_cmd_ifname(struct wpa_ctrl * ctrl,int argc,char * argv[])619 static int wpa_cli_cmd_ifname(struct wpa_ctrl *ctrl, int argc, char *argv[])
620 {
621 	return wpa_cli_cmd(ctrl, "IFNAME", 0, argc, argv);
622 }
623 
624 
wpa_cli_cmd_ping(struct wpa_ctrl * ctrl,int argc,char * argv[])625 static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
626 {
627 	return wpa_cli_cmd(ctrl, "PING", 0, argc, argv);
628 }
629 
630 
wpa_cli_cmd_relog(struct wpa_ctrl * ctrl,int argc,char * argv[])631 static int wpa_cli_cmd_relog(struct wpa_ctrl *ctrl, int argc, char *argv[])
632 {
633 	return wpa_cli_cmd(ctrl, "RELOG", 0, argc, argv);
634 }
635 
636 
wpa_cli_cmd_note(struct wpa_ctrl * ctrl,int argc,char * argv[])637 static int wpa_cli_cmd_note(struct wpa_ctrl *ctrl, int argc, char *argv[])
638 {
639 	return wpa_cli_cmd(ctrl, "NOTE", 1, argc, argv);
640 }
641 
642 
wpa_cli_cmd_mib(struct wpa_ctrl * ctrl,int argc,char * argv[])643 static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
644 {
645 	return wpa_cli_cmd(ctrl, "MIB", 0, argc, argv);
646 }
647 
648 
wpa_cli_cmd_pmksa(struct wpa_ctrl * ctrl,int argc,char * argv[])649 static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
650 {
651 	return wpa_cli_cmd(ctrl, "PMKSA", 0, argc, argv);
652 }
653 
654 
wpa_cli_cmd_pmksa_flush(struct wpa_ctrl * ctrl,int argc,char * argv[])655 static int wpa_cli_cmd_pmksa_flush(struct wpa_ctrl *ctrl, int argc,
656 				   char *argv[])
657 {
658 	return wpa_cli_cmd(ctrl, "PMKSA_FLUSH", 0, argc, argv);
659 }
660 
661 
662 #ifdef CONFIG_PMKSA_CACHE_EXTERNAL
663 
wpa_cli_cmd_pmksa_get(struct wpa_ctrl * ctrl,int argc,char * argv[])664 static int wpa_cli_cmd_pmksa_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
665 {
666 	return wpa_cli_cmd(ctrl, "PMKSA_GET", 1, argc, argv);
667 }
668 
669 
wpa_cli_cmd_pmksa_add(struct wpa_ctrl * ctrl,int argc,char * argv[])670 static int wpa_cli_cmd_pmksa_add(struct wpa_ctrl *ctrl, int argc, char *argv[])
671 {
672 	return wpa_cli_cmd(ctrl, "PMKSA_ADD", 8, argc, argv);
673 }
674 
675 
676 #ifdef CONFIG_MESH
677 
wpa_cli_mesh_cmd_pmksa_get(struct wpa_ctrl * ctrl,int argc,char * argv[])678 static int wpa_cli_mesh_cmd_pmksa_get(struct wpa_ctrl *ctrl, int argc,
679 				      char *argv[])
680 {
681 	return wpa_cli_cmd(ctrl, "MESH_PMKSA_GET", 1, argc, argv);
682 }
683 
684 
wpa_cli_mesh_cmd_pmksa_add(struct wpa_ctrl * ctrl,int argc,char * argv[])685 static int wpa_cli_mesh_cmd_pmksa_add(struct wpa_ctrl *ctrl, int argc,
686 				      char *argv[])
687 {
688 	return wpa_cli_cmd(ctrl, "MESH_PMKSA_ADD", 4, argc, argv);
689 }
690 
691 #endif /* CONFIG_MESH */
692 #endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
693 
694 
wpa_cli_cmd_dump(struct wpa_ctrl * ctrl,int argc,char * argv[])695 static int wpa_cli_cmd_dump(struct wpa_ctrl *ctrl, int argc, char *argv[])
696 {
697 	return wpa_cli_cmd(ctrl, "DUMP", 0, argc, argv);
698 }
699 
700 
wpa_cli_cmd_driver_flags(struct wpa_ctrl * ctrl,int argc,char * argv[])701 static int wpa_cli_cmd_driver_flags(struct wpa_ctrl *ctrl, int argc,
702 				    char *argv[])
703 {
704 	return wpa_cli_cmd(ctrl, "DRIVER_FLAGS", 0, argc, argv);
705 }
706 
707 
wpa_cli_cmd_get(struct wpa_ctrl * ctrl,int argc,char * argv[])708 static int wpa_cli_cmd_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
709 {
710 	return wpa_cli_cmd(ctrl, "GET", 1, argc, argv);
711 }
712 
713 
wpa_cli_complete_get(const char * str,int pos)714 static char ** wpa_cli_complete_get(const char *str, int pos)
715 {
716 	int arg = get_cmd_arg_num(str, pos);
717 	const char *fields[] = {
718 		"ctrl_interface", "ctrl_interface_group",
719 		"eapol_version", "ap_scan",
720 #ifdef CONFIG_MESH
721 		"user_mpm", "max_peer_links", "mesh_max_inactivity",
722 #endif /* CONFIG_MESH */
723 		"disable_scan_offload", "fast_reauth", "opensc_engine_path",
724 		"pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
725 		"pcsc_reader", "pcsc_pin", "external_sim", "driver_param",
726 		"dot11RSNAConfigPMKLifetime",
727 		"dot11RSNAConfigPMKReauthThreshold",
728 		"dot11RSNAConfigSATimeout",
729 #ifndef CONFIG_NO_CONFIG_WRITE
730 		"update_config",
731 #endif /* CONFIG_NO_CONFIG_WRITE */
732 #ifdef CONFIG_WPS
733 		"device_name", "manufacturer", "model_name", "model_number",
734 		"serial_number", "config_methods", "wps_cred_processing",
735 #endif /* CONFIG_WPS */
736 #ifdef CONFIG_P2P
737 		"p2p_listen_reg_class", "p2p_listen_channel",
738 		"p2p_oper_reg_class", "p2p_oper_channel", "p2p_go_intent",
739 		"p2p_ssid_postfix", "persistent_reconnect", "p2p_intra_bss",
740 		"p2p_group_idle", "p2p_passphrase_len", "p2p_add_cli_chan",
741 		"p2p_optimize_listen_chan", "p2p_go_ht40", "p2p_go_vht",
742 		"p2p_disabled", "p2p_go_ctwindow", "p2p_no_group_iface",
743 		"p2p_ignore_shared_freq", "ip_addr_go", "ip_addr_mask",
744 		"ip_addr_start", "ip_addr_end",
745 #endif /* CONFIG_P2P */
746 		"bss_max_count", "bss_expiration_age",
747 		"bss_expiration_scan_count", "filter_ssids", "filter_rssi",
748 		"max_num_sta", "disassoc_low_ack", "ap_isolate",
749 #ifdef CONFIG_HS20
750 		"hs20",
751 #endif /* CONFIG_HS20 */
752 		"interworking", "access_network_type", "pbc_in_m1", "autoscan",
753 		"go_interworking", "go_access_network_type", "go_internet",
754 		"go_venue_group", "go_venue_type",
755 		"wps_nfc_dev_pw_id", "ext_password_backend",
756 		"p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
757 		"dtim_period", "beacon_int", "ignore_old_scan_res",
758 		"scan_cur_freq", "scan_res_valid_for_connect",
759 		"sched_scan_interval",
760 		"sched_scan_start_delay",
761 		"tdls_external_control", "osu_dir", "wowlan_triggers",
762 		"p2p_search_delay", "mac_addr", "rand_addr_lifetime",
763 		"preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
764 		"reassoc_same_bss_optim", "extended_key_id"
765 	};
766 	int i, num_fields = ARRAY_SIZE(fields);
767 
768 	if (arg == 1) {
769 		char **res = os_calloc(num_fields + 1, sizeof(char *));
770 		if (res == NULL)
771 			return NULL;
772 		for (i = 0; i < num_fields; i++) {
773 			res[i] = os_strdup(fields[i]);
774 			if (res[i] == NULL)
775 				return res;
776 		}
777 		return res;
778 	}
779 
780 	return NULL;
781 }
782 
783 
wpa_cli_cmd_logoff(struct wpa_ctrl * ctrl,int argc,char * argv[])784 static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
785 {
786 	return wpa_cli_cmd(ctrl, "LOGOFF", 0, argc, argv);
787 }
788 
789 
wpa_cli_cmd_logon(struct wpa_ctrl * ctrl,int argc,char * argv[])790 static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
791 {
792 	return wpa_cli_cmd(ctrl, "LOGON", 0, argc, argv);
793 }
794 
795 
wpa_cli_cmd_reassociate(struct wpa_ctrl * ctrl,int argc,char * argv[])796 static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
797 				   char *argv[])
798 {
799 	return wpa_cli_cmd(ctrl, "REASSOCIATE", 0, argc, argv);
800 }
801 
802 
wpa_cli_cmd_reattach(struct wpa_ctrl * ctrl,int argc,char * argv[])803 static int wpa_cli_cmd_reattach(struct wpa_ctrl *ctrl, int argc, char *argv[])
804 {
805 	return wpa_cli_cmd(ctrl, "REATTACH", 0, argc, argv);
806 }
807 
808 
wpa_cli_cmd_preauthenticate(struct wpa_ctrl * ctrl,int argc,char * argv[])809 static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
810 				       char *argv[])
811 {
812 	return wpa_cli_cmd(ctrl, "PREAUTH", 1, argc, argv);
813 }
814 
815 
wpa_cli_cmd_ap_scan(struct wpa_ctrl * ctrl,int argc,char * argv[])816 static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
817 {
818 	return wpa_cli_cmd(ctrl, "AP_SCAN", 1, argc, argv);
819 }
820 
821 
wpa_cli_cmd_scan_interval(struct wpa_ctrl * ctrl,int argc,char * argv[])822 static int wpa_cli_cmd_scan_interval(struct wpa_ctrl *ctrl, int argc,
823 				     char *argv[])
824 {
825 	return wpa_cli_cmd(ctrl, "SCAN_INTERVAL", 1, argc, argv);
826 }
827 
828 
wpa_cli_cmd_bss_expire_age(struct wpa_ctrl * ctrl,int argc,char * argv[])829 static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
830 				      char *argv[])
831 {
832 	return wpa_cli_cmd(ctrl, "BSS_EXPIRE_AGE", 1, argc, argv);
833 }
834 
835 
wpa_cli_cmd_bss_expire_count(struct wpa_ctrl * ctrl,int argc,char * argv[])836 static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
837 				        char *argv[])
838 {
839 	return wpa_cli_cmd(ctrl, "BSS_EXPIRE_COUNT", 1, argc, argv);
840 }
841 
842 
wpa_cli_cmd_bss_flush(struct wpa_ctrl * ctrl,int argc,char * argv[])843 static int wpa_cli_cmd_bss_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
844 {
845 	char cmd[256];
846 	int res;
847 
848 	if (argc < 1)
849 		res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH 0");
850 	else
851 		res = os_snprintf(cmd, sizeof(cmd), "BSS_FLUSH %s", argv[0]);
852 	if (os_snprintf_error(sizeof(cmd), res)) {
853 		wpa_printf(MSG_INFO, "Too long BSS_FLUSH command.\n");
854 		return -1;
855 	}
856 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
857 }
858 
859 
wpa_cli_cmd_ft_ds(struct wpa_ctrl * ctrl,int argc,char * argv[])860 static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
861 {
862 	return wpa_cli_cmd(ctrl, "FT_DS", 1, argc, argv);
863 }
864 
865 
wpa_cli_cmd_wps_pbc(struct wpa_ctrl * ctrl,int argc,char * argv[])866 static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
867 {
868 	return wpa_cli_cmd(ctrl, "WPS_PBC", 0, argc, argv);
869 }
870 
871 
wpa_cli_cmd_wps_pin(struct wpa_ctrl * ctrl,int argc,char * argv[])872 static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
873 {
874 	if (argc == 0) {
875 		wpa_printf(MSG_INFO, "Invalid WPS_PIN command: need one or two arguments:\n"
876 		       "- BSSID: use 'any' to select any\n"
877 		       "- PIN: optional, used only with devices that have no "
878 		       "display\n");
879 		return -1;
880 	}
881 
882 	return wpa_cli_cmd(ctrl, "WPS_PIN", 1, argc, argv);
883 }
884 
885 
wpa_cli_cmd_wps_check_pin(struct wpa_ctrl * ctrl,int argc,char * argv[])886 static int wpa_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
887 				     char *argv[])
888 {
889 	return wpa_cli_cmd(ctrl, "WPS_CHECK_PIN", 1, argc, argv);
890 }
891 
892 
wpa_cli_cmd_wps_cancel(struct wpa_ctrl * ctrl,int argc,char * argv[])893 static int wpa_cli_cmd_wps_cancel(struct wpa_ctrl *ctrl, int argc,
894 				  char *argv[])
895 {
896 	return wpa_cli_cmd(ctrl, "WPS_CANCEL", 0, argc, argv);
897 }
898 
899 
900 #ifdef CONFIG_WPS_NFC
901 
wpa_cli_cmd_wps_nfc(struct wpa_ctrl * ctrl,int argc,char * argv[])902 static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
903 {
904 	return wpa_cli_cmd(ctrl, "WPS_NFC", 0, argc, argv);
905 }
906 
907 
wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl * ctrl,int argc,char * argv[])908 static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
909 					    char *argv[])
910 {
911 	return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
912 }
913 
914 
wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl * ctrl,int argc,char * argv[])915 static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
916 				     char *argv[])
917 {
918 	return wpa_cli_cmd(ctrl, "WPS_NFC_TOKEN", 1, argc, argv);
919 }
920 
921 
wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl * ctrl,int argc,char * argv[])922 static int wpa_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
923 					char *argv[])
924 {
925 	int ret;
926 	char *buf;
927 	size_t buflen;
928 
929 	if (argc != 1) {
930 		wpa_printf(MSG_INFO, "Invalid 'wps_nfc_tag_read' command - one argument "
931 		       "is required.\n");
932 		return -1;
933 	}
934 
935 	buflen = 18 + os_strlen(argv[0]);
936 	buf = os_malloc(buflen);
937 	if (buf == NULL)
938 		return -1;
939 	os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
940 
941 	ret = wpa_cli_cmd(ctrl, buf, 0, argc, argv);
942 	os_free(buf);
943 
944 	return ret;
945 }
946 
947 
wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl * ctrl,int argc,char * argv[])948 static int wpa_cli_cmd_nfc_get_handover_req(struct wpa_ctrl *ctrl, int argc,
949 					    char *argv[])
950 {
951 	return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_REQ", 2, argc, argv);
952 }
953 
954 
wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl * ctrl,int argc,char * argv[])955 static int wpa_cli_cmd_nfc_get_handover_sel(struct wpa_ctrl *ctrl, int argc,
956 					    char *argv[])
957 {
958 	return wpa_cli_cmd(ctrl, "NFC_GET_HANDOVER_SEL", 2, argc, argv);
959 }
960 
961 
wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl * ctrl,int argc,char * argv[])962 static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc,
963 					   char *argv[])
964 {
965 	return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv);
966 }
967 
968 #endif /* CONFIG_WPS_NFC */
969 
970 
wpa_cli_cmd_wps_reg(struct wpa_ctrl * ctrl,int argc,char * argv[])971 static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
972 {
973 	char cmd[256];
974 	int res;
975 
976 	if (argc == 2)
977 		res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s",
978 				  argv[0], argv[1]);
979 	else if (argc == 5 || argc == 6) {
980 		char ssid_hex[2 * SSID_MAX_LEN + 1];
981 		char key_hex[2 * 64 + 1];
982 		int i;
983 
984 		ssid_hex[0] = '\0';
985 		for (i = 0; i < SSID_MAX_LEN; i++) {
986 			if (argv[2][i] == '\0')
987 				break;
988 			os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
989 		}
990 
991 		key_hex[0] = '\0';
992 		if (argc == 6) {
993 			for (i = 0; i < 64; i++) {
994 				if (argv[5][i] == '\0')
995 					break;
996 				os_snprintf(&key_hex[i * 2], 3, "%02x",
997 					    argv[5][i]);
998 			}
999 		}
1000 
1001 		res = os_snprintf(cmd, sizeof(cmd),
1002 				  "WPS_REG %s %s %s %s %s %s",
1003 				  argv[0], argv[1], ssid_hex, argv[3], argv[4],
1004 				  key_hex);
1005 	} else {
1006 		wpa_printf(MSG_INFO, "Invalid WPS_REG command: need two arguments:\n"
1007 		       "- BSSID of the target AP\n"
1008 		       "- AP PIN\n");
1009 		wpa_printf(MSG_INFO, "Alternatively, six arguments can be used to "
1010 		       "reconfigure the AP:\n"
1011 		       "- BSSID of the target AP\n"
1012 		       "- AP PIN\n"
1013 		       "- new SSID\n"
1014 		       "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1015 		       "- new encr (NONE, WEP, TKIP, CCMP)\n"
1016 		       "- new key\n");
1017 		return -1;
1018 	}
1019 
1020 	if (os_snprintf_error(sizeof(cmd), res)) {
1021 		wpa_printf(MSG_INFO, "Too long WPS_REG command.\n");
1022 		return -1;
1023 	}
1024 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
1025 }
1026 
1027 
wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl * ctrl,int argc,char * argv[])1028 static int wpa_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
1029 				  char *argv[])
1030 {
1031 	return wpa_cli_cmd(ctrl, "WPS_AP_PIN", 1, argc, argv);
1032 }
1033 
1034 
wpa_cli_cmd_wps_er_start(struct wpa_ctrl * ctrl,int argc,char * argv[])1035 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
1036 				    char *argv[])
1037 {
1038 	return wpa_cli_cmd(ctrl, "WPS_ER_START", 0, argc, argv);
1039 }
1040 
1041 
wpa_cli_cmd_wps_er_stop(struct wpa_ctrl * ctrl,int argc,char * argv[])1042 static int wpa_cli_cmd_wps_er_stop(struct wpa_ctrl *ctrl, int argc,
1043 				   char *argv[])
1044 {
1045 	return wpa_cli_cmd(ctrl, "WPS_ER_STOP", 0, argc, argv);
1046 
1047 }
1048 
1049 
wpa_cli_cmd_wps_er_pin(struct wpa_ctrl * ctrl,int argc,char * argv[])1050 static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
1051 				  char *argv[])
1052 {
1053 	if (argc < 2) {
1054 		wpa_printf(MSG_INFO, "Invalid WPS_ER_PIN command: need at least two "
1055 		       "arguments:\n"
1056 		       "- UUID: use 'any' to select any\n"
1057 		       "- PIN: Enrollee PIN\n"
1058 		       "optional: - Enrollee MAC address\n");
1059 		return -1;
1060 	}
1061 
1062 	return wpa_cli_cmd(ctrl, "WPS_ER_PIN", 2, argc, argv);
1063 }
1064 
1065 
wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl * ctrl,int argc,char * argv[])1066 static int wpa_cli_cmd_wps_er_pbc(struct wpa_ctrl *ctrl, int argc,
1067 				  char *argv[])
1068 {
1069 	return wpa_cli_cmd(ctrl, "WPS_ER_PBC", 1, argc, argv);
1070 }
1071 
1072 
wpa_cli_cmd_wps_er_learn(struct wpa_ctrl * ctrl,int argc,char * argv[])1073 static int wpa_cli_cmd_wps_er_learn(struct wpa_ctrl *ctrl, int argc,
1074 				    char *argv[])
1075 {
1076 	if (argc != 2) {
1077 		wpa_printf(MSG_INFO, "Invalid WPS_ER_LEARN command: need two arguments:\n"
1078 		       "- UUID: specify which AP to use\n"
1079 		       "- PIN: AP PIN\n");
1080 		return -1;
1081 	}
1082 
1083 	return wpa_cli_cmd(ctrl, "WPS_ER_LEARN", 2, argc, argv);
1084 }
1085 
1086 
wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl * ctrl,int argc,char * argv[])1087 static int wpa_cli_cmd_wps_er_set_config(struct wpa_ctrl *ctrl, int argc,
1088 					 char *argv[])
1089 {
1090 	if (argc != 2) {
1091 		wpa_printf(MSG_INFO, "Invalid WPS_ER_SET_CONFIG command: need two "
1092 		       "arguments:\n"
1093 		       "- UUID: specify which AP to use\n"
1094 		       "- Network configuration id\n");
1095 		return -1;
1096 	}
1097 
1098 	return wpa_cli_cmd(ctrl, "WPS_ER_SET_CONFIG", 2, argc, argv);
1099 }
1100 
1101 
wpa_cli_cmd_wps_er_config(struct wpa_ctrl * ctrl,int argc,char * argv[])1102 static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc,
1103 				     char *argv[])
1104 {
1105 	char cmd[256];
1106 	int res;
1107 
1108 	if (argc == 5 || argc == 6) {
1109 		char ssid_hex[2 * SSID_MAX_LEN + 1];
1110 		char key_hex[2 * 64 + 1];
1111 		int i;
1112 
1113 		ssid_hex[0] = '\0';
1114 		for (i = 0; i < SSID_MAX_LEN; i++) {
1115 			if (argv[2][i] == '\0')
1116 				break;
1117 			os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[2][i]);
1118 		}
1119 
1120 		key_hex[0] = '\0';
1121 		if (argc == 6) {
1122 			for (i = 0; i < 64; i++) {
1123 				if (argv[5][i] == '\0')
1124 					break;
1125 				os_snprintf(&key_hex[i * 2], 3, "%02x",
1126 					    argv[5][i]);
1127 			}
1128 		}
1129 
1130 		res = os_snprintf(cmd, sizeof(cmd),
1131 				  "WPS_ER_CONFIG %s %s %s %s %s %s",
1132 				  argv[0], argv[1], ssid_hex, argv[3], argv[4],
1133 				  key_hex);
1134 	} else {
1135 		wpa_printf(MSG_INFO, "Invalid WPS_ER_CONFIG command: need six arguments:\n"
1136 		       "- AP UUID\n"
1137 		       "- AP PIN\n"
1138 		       "- new SSID\n"
1139 		       "- new auth (OPEN, WPAPSK, WPA2PSK)\n"
1140 		       "- new encr (NONE, WEP, TKIP, CCMP)\n"
1141 		       "- new key\n");
1142 		return -1;
1143 	}
1144 
1145 	if (os_snprintf_error(sizeof(cmd), res)) {
1146 		wpa_printf(MSG_INFO, "Too long WPS_ER_CONFIG command.\n");
1147 		return -1;
1148 	}
1149 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
1150 }
1151 
1152 
1153 #ifdef CONFIG_WPS_NFC
wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl * ctrl,int argc,char * argv[])1154 static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
1155 					       char *argv[])
1156 {
1157 	if (argc != 2) {
1158 		wpa_printf(MSG_INFO, "Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two "
1159 		       "arguments:\n"
1160 		       "- WPS/NDEF: token format\n"
1161 		       "- UUID: specify which AP to use\n");
1162 		return -1;
1163 	}
1164 
1165 	return wpa_cli_cmd(ctrl, "WPS_ER_NFC_CONFIG_TOKEN", 2, argc, argv);
1166 }
1167 #endif /* CONFIG_WPS_NFC */
1168 
1169 
wpa_cli_cmd_ibss_rsn(struct wpa_ctrl * ctrl,int argc,char * argv[])1170 static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
1171 {
1172 	return wpa_cli_cmd(ctrl, "IBSS_RSN", 1, argc, argv);
1173 }
1174 
wpa_cli_cmd_identity(struct wpa_ctrl * ctrl,int argc,char * argv[])1175 static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
1176 {
1177 	char cmd[256], *pos, *end;
1178 	int i, ret;
1179 
1180 	if (argc < 2) {
1181 		wpa_printf(MSG_INFO, "Invalid IDENTITY command: needs two arguments "
1182 		       "(network id and identity)\n");
1183 		return -1;
1184 	}
1185 
1186 	end = cmd + sizeof(cmd);
1187 	pos = cmd;
1188 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
1189 			  argv[0], argv[1]);
1190 	if (os_snprintf_error(end - pos, ret)) {
1191 		wpa_printf(MSG_INFO, "Too long IDENTITY command.\n");
1192 		return -1;
1193 	}
1194 	pos += ret;
1195 	for (i = 2; i < argc; i++) {
1196 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1197 		if (os_snprintf_error(end - pos, ret)) {
1198 			wpa_printf(MSG_INFO, "Too long IDENTITY command.\n");
1199 			return -1;
1200 		}
1201 		pos += ret;
1202 	}
1203 
1204 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
1205 }
1206 
1207 
wpa_cli_cmd_password(struct wpa_ctrl * ctrl,int argc,char * argv[])1208 static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
1209 {
1210 	char cmd[256], *pos, *end;
1211 	int i, ret;
1212 
1213 	if (argc < 2) {
1214 		wpa_printf(MSG_INFO, "Invalid PASSWORD command: needs two arguments "
1215 		       "(network id and password)\n");
1216 		return -1;
1217 	}
1218 
1219 	end = cmd + sizeof(cmd);
1220 	pos = cmd;
1221 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
1222 			  argv[0], argv[1]);
1223 	if (os_snprintf_error(end - pos, ret)) {
1224 		wpa_printf(MSG_INFO, "Too long PASSWORD command.\n");
1225 		return -1;
1226 	}
1227 	pos += ret;
1228 	for (i = 2; i < argc; i++) {
1229 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1230 		if (os_snprintf_error(end - pos, ret)) {
1231 			wpa_printf(MSG_INFO, "Too long PASSWORD command.\n");
1232 			return -1;
1233 		}
1234 		pos += ret;
1235 	}
1236 
1237 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
1238 }
1239 
1240 
wpa_cli_cmd_new_password(struct wpa_ctrl * ctrl,int argc,char * argv[])1241 static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
1242 				    char *argv[])
1243 {
1244 	char cmd[256], *pos, *end;
1245 	int i, ret;
1246 
1247 	if (argc < 2) {
1248 		wpa_printf(MSG_INFO, "Invalid NEW_PASSWORD command: needs two arguments "
1249 		       "(network id and password)\n");
1250 		return -1;
1251 	}
1252 
1253 	end = cmd + sizeof(cmd);
1254 	pos = cmd;
1255 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
1256 			  argv[0], argv[1]);
1257 	if (os_snprintf_error(end - pos, ret)) {
1258 		wpa_printf(MSG_INFO, "Too long NEW_PASSWORD command.\n");
1259 		return -1;
1260 	}
1261 	pos += ret;
1262 	for (i = 2; i < argc; i++) {
1263 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1264 		if (os_snprintf_error(end - pos, ret)) {
1265 			wpa_printf(MSG_INFO, "Too long NEW_PASSWORD command.\n");
1266 			return -1;
1267 		}
1268 		pos += ret;
1269 	}
1270 
1271 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
1272 }
1273 
1274 
wpa_cli_cmd_pin(struct wpa_ctrl * ctrl,int argc,char * argv[])1275 static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
1276 {
1277 	char cmd[256], *pos, *end;
1278 	int i, ret;
1279 
1280 	if (argc < 2) {
1281 		wpa_printf(MSG_INFO, "Invalid PIN command: needs two arguments "
1282 		       "(network id and pin)\n");
1283 		return -1;
1284 	}
1285 
1286 	end = cmd + sizeof(cmd);
1287 	pos = cmd;
1288 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
1289 			  argv[0], argv[1]);
1290 	if (os_snprintf_error(end - pos, ret)) {
1291 		wpa_printf(MSG_INFO, "Too long PIN command.\n");
1292 		return -1;
1293 	}
1294 	pos += ret;
1295 	for (i = 2; i < argc; i++) {
1296 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1297 		if (os_snprintf_error(end - pos, ret)) {
1298 			wpa_printf(MSG_INFO, "Too long PIN command.\n");
1299 			return -1;
1300 		}
1301 		pos += ret;
1302 	}
1303 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
1304 }
1305 
1306 
wpa_cli_cmd_otp(struct wpa_ctrl * ctrl,int argc,char * argv[])1307 static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
1308 {
1309 	char cmd[256], *pos, *end;
1310 	int i, ret;
1311 
1312 	if (argc < 2) {
1313 		wpa_printf(MSG_INFO, "Invalid OTP command: needs two arguments (network "
1314 		       "id and password)\n");
1315 		return -1;
1316 	}
1317 
1318 	end = cmd + sizeof(cmd);
1319 	pos = cmd;
1320 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
1321 			  argv[0], argv[1]);
1322 	if (os_snprintf_error(end - pos, ret)) {
1323 		wpa_printf(MSG_INFO, "Too long OTP command.\n");
1324 		return -1;
1325 	}
1326 	pos += ret;
1327 	for (i = 2; i < argc; i++) {
1328 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1329 		if (os_snprintf_error(end - pos, ret)) {
1330 			wpa_printf(MSG_INFO, "Too long OTP command.\n");
1331 			return -1;
1332 		}
1333 		pos += ret;
1334 	}
1335 
1336 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
1337 }
1338 
1339 
wpa_cli_cmd_sim(struct wpa_ctrl * ctrl,int argc,char * argv[])1340 static int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[])
1341 {
1342 	char cmd[256], *pos, *end;
1343 	int i, ret;
1344 
1345 	if (argc < 2) {
1346 		wpa_printf(MSG_INFO, "Invalid SIM command: needs two arguments "
1347 		       "(network id and SIM operation response)\n");
1348 		return -1;
1349 	}
1350 
1351 	end = cmd + sizeof(cmd);
1352 	pos = cmd;
1353 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s",
1354 			  argv[0], argv[1]);
1355 	if (os_snprintf_error(end - pos, ret)) {
1356 		wpa_printf(MSG_INFO, "Too long SIM command.\n");
1357 		return -1;
1358 	}
1359 	pos += ret;
1360 	for (i = 2; i < argc; i++) {
1361 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1362 		if (os_snprintf_error(end - pos, ret)) {
1363 			wpa_printf(MSG_INFO, "Too long SIM command.\n");
1364 			return -1;
1365 		}
1366 		pos += ret;
1367 	}
1368 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
1369 }
1370 
1371 
wpa_cli_cmd_psk_passphrase(struct wpa_ctrl * ctrl,int argc,char * argv[])1372 static int wpa_cli_cmd_psk_passphrase(struct wpa_ctrl *ctrl, int argc,
1373 				      char *argv[])
1374 {
1375 	char cmd[256], *pos, *end;
1376 	int i, ret;
1377 
1378 	if (argc < 2) {
1379 		wpa_printf(MSG_INFO, "Invalid PSK_PASSPHRASE command: needs two arguments (network id and PSK/passphrase)\n");
1380 		return -1;
1381 	}
1382 
1383 	end = cmd + sizeof(cmd);
1384 	pos = cmd;
1385 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PSK_PASSPHRASE-%s:%s",
1386 			  argv[0], argv[1]);
1387 	if (os_snprintf_error(end - pos, ret)) {
1388 		wpa_printf(MSG_INFO, "Too long PSK_PASSPHRASE command.\n");
1389 		return -1;
1390 	}
1391 	pos += ret;
1392 	for (i = 2; i < argc; i++) {
1393 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1394 		if (os_snprintf_error(end - pos, ret)) {
1395 			wpa_printf(MSG_INFO, "Too long PSK_PASSPHRASE command.\n");
1396 			return -1;
1397 		}
1398 		pos += ret;
1399 	}
1400 
1401 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
1402 }
1403 
1404 
wpa_cli_cmd_passphrase(struct wpa_ctrl * ctrl,int argc,char * argv[])1405 static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
1406 				  char *argv[])
1407 {
1408 	char cmd[256], *pos, *end;
1409 	int i, ret;
1410 
1411 	if (argc < 2) {
1412 		wpa_printf(MSG_INFO, "Invalid PASSPHRASE command: needs two arguments "
1413 		       "(network id and passphrase)\n");
1414 		return -1;
1415 	}
1416 
1417 	end = cmd + sizeof(cmd);
1418 	pos = cmd;
1419 	ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
1420 			  argv[0], argv[1]);
1421 	if (os_snprintf_error(end - pos, ret)) {
1422 		wpa_printf(MSG_INFO, "Too long PASSPHRASE command.\n");
1423 		return -1;
1424 	}
1425 	pos += ret;
1426 	for (i = 2; i < argc; i++) {
1427 		ret = os_snprintf(pos, end - pos, " %s", argv[i]);
1428 		if (os_snprintf_error(end - pos, ret)) {
1429 			wpa_printf(MSG_INFO, "Too long PASSPHRASE command.\n");
1430 			return -1;
1431 		}
1432 		pos += ret;
1433 	}
1434 
1435 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
1436 }
1437 
1438 
wpa_cli_cmd_bssid(struct wpa_ctrl * ctrl,int argc,char * argv[])1439 static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
1440 {
1441 	if (argc < 2) {
1442 		wpa_printf(MSG_INFO, "Invalid BSSID command: needs two arguments (network "
1443 		       "id and BSSID)\n");
1444 		return -1;
1445 	}
1446 
1447 	return wpa_cli_cmd(ctrl, "BSSID", 2, argc, argv);
1448 }
1449 
1450 
wpa_cli_cmd_bssid_ignore(struct wpa_ctrl * ctrl,int argc,char * argv[])1451 static int wpa_cli_cmd_bssid_ignore(struct wpa_ctrl *ctrl, int argc,
1452 				    char *argv[])
1453 {
1454 	return wpa_cli_cmd(ctrl, "BSSID_IGNORE", 0, argc, argv);
1455 }
1456 
1457 
wpa_cli_cmd_log_level(struct wpa_ctrl * ctrl,int argc,char * argv[])1458 static int wpa_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
1459 {
1460 	return wpa_cli_cmd(ctrl, "LOG_LEVEL", 0, argc, argv);
1461 }
1462 
1463 
wpa_cli_cmd_dup_network(struct wpa_ctrl * ctrl,int argc,char * argv[])1464 static int wpa_cli_cmd_dup_network(struct wpa_ctrl *ctrl, int argc,
1465 				   char *argv[])
1466 {
1467 	if (argc == 0) {
1468 		wpa_cli_show_network_variables();
1469 		return 0;
1470 	}
1471 
1472 	if (argc < 3) {
1473 		wpa_printf(MSG_INFO, "Invalid DUP_NETWORK command: needs three arguments\n"
1474 		       "(src netid, dest netid, and variable name)\n");
1475 		return -1;
1476 	}
1477 
1478 	return wpa_cli_cmd(ctrl, "DUP_NETWORK", 3, argc, argv);
1479 }
1480 
1481 
wpa_cli_complete_dup_network(const char * str,int pos)1482 static char ** wpa_cli_complete_dup_network(const char *str, int pos)
1483 {
1484 	int arg = get_cmd_arg_num(str, pos);
1485 	int i, num_fields = ARRAY_SIZE(network_fields);
1486 	char **res = NULL;
1487 
1488 	switch (arg) {
1489 	case 1:
1490 	case 2:
1491 		res = cli_txt_list_array(&networks);
1492 		break;
1493 	case 3:
1494 		res = os_calloc(num_fields + 1, sizeof(char *));
1495 		if (res == NULL)
1496 			return NULL;
1497 		for (i = 0; i < num_fields; i++) {
1498 			res[i] = os_strdup(network_fields[i]);
1499 			if (res[i] == NULL)
1500 				break;
1501 		}
1502 	}
1503 	return res;
1504 }
1505 
1506 
wpa_cli_cmd_list_creds(struct wpa_ctrl * ctrl,int argc,char * argv[])1507 static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
1508 				  char *argv[])
1509 {
1510 	return wpa_cli_cmd(ctrl, "LIST_CREDS", 0, argc, argv);
1511 }
1512 
1513 
wpa_cli_cmd_add_cred(struct wpa_ctrl * ctrl,int argc,char * argv[])1514 static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1515 {
1516 	return wpa_cli_cmd(ctrl, "ADD_CRED", 0, argc, argv);
1517 }
1518 
1519 
wpa_cli_cmd_remove_cred(struct wpa_ctrl * ctrl,int argc,char * argv[])1520 static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
1521 				   char *argv[])
1522 {
1523 	return wpa_cli_cmd(ctrl, "REMOVE_CRED", 1, argc, argv);
1524 }
1525 
1526 
1527 static const char * const cred_fields[] = {
1528 	"temporary", "priority", "sp_priority", "pcsc", "eap",
1529 	"update_identifier", "min_dl_bandwidth_home", "min_ul_bandwidth_home",
1530 	"min_dl_bandwidth_roaming", "min_ul_bandwidth_roaming", "max_bss_load",
1531 	"req_conn_capab", "ocsp", "sim_num", "realm", "username", "password",
1532 	"ca_cert", "client_cert", "private_key", "private_key_passwd", "imsi",
1533 	"ca_cert_id", "cert_id", "key_id", "engine_id", "engine",
1534 	"milenage", "domain_suffix_match", "domain", "phase1", "phase2",
1535 	"roaming_consortium", "required_roaming_consortium", "excluded_ssid",
1536 	"roaming_partner", "provisioning_sp"
1537 };
1538 
1539 
wpa_cli_complete_cred(const char * str,int pos)1540 static char ** wpa_cli_complete_cred(const char *str, int pos)
1541 {
1542 	int arg = get_cmd_arg_num(str, pos);
1543 	int i, num_fields = ARRAY_SIZE(cred_fields);
1544 	char **res = NULL;
1545 
1546 	switch (arg) {
1547 	case 1:
1548 		res = cli_txt_list_array(&creds);
1549 		break;
1550 	case 2:
1551 		res = os_calloc(num_fields + 1, sizeof(char *));
1552 		if (res == NULL)
1553 			return NULL;
1554 		for (i = 0; i < num_fields; i++) {
1555 			res[i] = os_strdup(cred_fields[i]);
1556 			if (res[i] == NULL)
1557 				break;
1558 		}
1559 	}
1560 	return res;
1561 }
1562 
1563 
wpa_cli_cmd_set_cred(struct wpa_ctrl * ctrl,int argc,char * argv[])1564 static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1565 {
1566 	if (argc != 3) {
1567 		wpa_printf(MSG_INFO, "Invalid SET_CRED command: needs three arguments\n"
1568 		       "(cred id, variable name, and value)\n");
1569 		return -1;
1570 	}
1571 
1572 	return wpa_cli_cmd(ctrl, "SET_CRED", 3, argc, argv);
1573 }
1574 
1575 
wpa_cli_cmd_get_cred(struct wpa_ctrl * ctrl,int argc,char * argv[])1576 static int wpa_cli_cmd_get_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
1577 {
1578 	if (argc != 2) {
1579 		wpa_printf(MSG_INFO, "Invalid GET_CRED command: needs two arguments\n"
1580 		       "(cred id, variable name)\n");
1581 		return -1;
1582 	}
1583 
1584 	return wpa_cli_cmd(ctrl, "GET_CRED", 2, argc, argv);
1585 }
1586 
1587 
wpa_cli_cmd_reconnect(struct wpa_ctrl * ctrl,int argc,char * argv[])1588 static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
1589 				  char *argv[])
1590 {
1591 	return wpa_cli_cmd(ctrl, "RECONNECT", 0, argc, argv);
1592 }
1593 
1594 
wpa_cli_cmd_save_config(struct wpa_ctrl * ctrl,int argc,char * argv[])1595 static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
1596 				   char *argv[])
1597 {
1598 	return wpa_cli_cmd(ctrl, "SAVE_CONFIG", 0, argc, argv);
1599 }
1600 
1601 
wpa_cli_cmd_scan(struct wpa_ctrl * ctrl,int argc,char * argv[])1602 static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
1603 {
1604 	return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
1605 }
1606 
1607 
wpa_cli_cmd_scan_results(struct wpa_ctrl * ctrl,int argc,char * argv[])1608 static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
1609 				    char *argv[])
1610 {
1611 	return wpa_cli_cmd(ctrl, "SCAN_RESULTS", 0, argc, argv);
1612 }
1613 
1614 
wpa_cli_cmd_abort_scan(struct wpa_ctrl * ctrl,int argc,char * argv[])1615 static int wpa_cli_cmd_abort_scan(struct wpa_ctrl *ctrl, int argc,
1616 				  char *argv[])
1617 {
1618 	return wpa_cli_cmd(ctrl, "ABORT_SCAN", 0, argc, argv);
1619 }
1620 
1621 
wpa_cli_cmd_bss(struct wpa_ctrl * ctrl,int argc,char * argv[])1622 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
1623 {
1624 	return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
1625 }
1626 
1627 
wpa_cli_complete_bss(const char * str,int pos)1628 static char ** wpa_cli_complete_bss(const char *str, int pos)
1629 {
1630 	int arg = get_cmd_arg_num(str, pos);
1631 	char **res = NULL;
1632 
1633 	switch (arg) {
1634 	case 1:
1635 		res = cli_txt_list_array(&bsses);
1636 		break;
1637 	}
1638 
1639 	return res;
1640 }
1641 
1642 
wpa_cli_cmd_get_capability(struct wpa_ctrl * ctrl,int argc,char * argv[])1643 static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
1644 				      char *argv[])
1645 {
1646 	if (argc < 1 || argc > 3) {
1647 		wpa_printf(MSG_INFO, "Invalid GET_CAPABILITY command: need at least one argument and max three arguments\n");
1648 		return -1;
1649 	}
1650 
1651 	if (argc > 1 && os_strcmp(argv[0], "key_mgmt") != 0 &&
1652 	    os_strncmp(argv[1], "iftype=", 7) == 0) {
1653 		wpa_printf(MSG_INFO, "Invalid GET_CAPABILITY command: 'iftype=' param is allowed only for 'key_mgmt'\n");
1654 		return -1;
1655 	}
1656 
1657 	if (argc == 2 && os_strcmp(argv[1], "strict") != 0 &&
1658 	    os_strncmp(argv[1], "iftype=", 7) != 0) {
1659 		wpa_printf(MSG_INFO, "Invalid GET_CAPABILITY command: the second argument, if any, must be 'strict' OR 'iftype=<iftype_name>'\n");
1660 		return -1;
1661 	}
1662 
1663 	if (argc == 3 && os_strcmp(argv[2], "strict") != 0) {
1664 		wpa_printf(MSG_INFO, "Invalid GET_CAPABILITY command: the third argument, if any, must be 'strict'\n");
1665 		return -1;
1666 	}
1667 
1668 	return wpa_cli_cmd(ctrl, "GET_CAPABILITY", 1, argc, argv);
1669 }
1670 
1671 
wpa_cli_complete_get_capability(const char * str,int pos)1672 static char ** wpa_cli_complete_get_capability(const char *str, int pos)
1673 {
1674 	int arg = get_cmd_arg_num(str, pos);
1675 	const char *fields[] = {
1676 		"eap", "pairwise", "group", "group_mgmt", "key_mgmt",
1677 		"proto", "auth_alg", "modes", "channels", "freq",
1678 #ifdef CONFIG_TDLS
1679 		"tdls",
1680 #endif /* CONFIG_TDLS */
1681 #ifdef CONFIG_ERP
1682 		"erp",
1683 #endif /* CONFIG_ERP */
1684 #ifdef CONFIG_FIPS
1685 		"fips",
1686 #endif /* CONFIG_FIPS */
1687 #ifdef CONFIG_ACS
1688 		"acs",
1689 #endif /* CONFIG_ACS */
1690 	};
1691 	const char *iftypes[] = {
1692 		"iftype=STATION", "iftype=AP", "iftype=P2P_CLIENT",
1693 		"iftype=P2P_GO", "iftype=AP_VLAN", "iftype=IBSS", "iftype=NAN",
1694 		"iftype=P2P_DEVICE", "iftype=MESH",
1695 	};
1696 	int i, num_fields = ARRAY_SIZE(fields);
1697 	int num_iftypes = ARRAY_SIZE(iftypes);
1698 	char **res = NULL;
1699 
1700 	if (arg == 1) {
1701 		res = os_calloc(num_fields + 1, sizeof(char *));
1702 		if (res == NULL)
1703 			return NULL;
1704 		for (i = 0; i < num_fields; i++) {
1705 			res[i] = os_strdup(fields[i]);
1706 			if (res[i] == NULL)
1707 				return res;
1708 		}
1709 	}
1710 	if (arg == 2) {
1711 		/* the second argument can be "iftype=<iftype_name>" OR
1712 		 * "strict" */
1713 		res = os_calloc(num_iftypes + 2, sizeof(char *));
1714 		if (!res)
1715 			return NULL;
1716 		res[0] = os_strdup("strict");
1717 		if (!res[0])
1718 			return res;
1719 		for (i = 0; i < num_iftypes; i++) {
1720 			res[i + 1] = os_strdup(iftypes[i]);
1721 			if (!res[i + 1])
1722 				return res;
1723 		}
1724 	}
1725 	if (arg == 3) {
1726 		res = os_calloc(1 + 1, sizeof(char *));
1727 		if (res == NULL)
1728 			return NULL;
1729 		res[0] = os_strdup("strict");
1730 	}
1731 	return res;
1732 }
1733 
wpa_cli_cmd_reconfigure(struct wpa_ctrl * ctrl,int argc,char * argv[])1734 static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
1735 				   char *argv[])
1736 {
1737 	return wpa_cli_cmd(ctrl, "RECONFIGURE", 0, argc, argv);
1738 }
1739 
1740 
wpa_cli_cmd_terminate(struct wpa_ctrl * ctrl,int argc,char * argv[])1741 static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
1742 				 char *argv[])
1743 {
1744 	return wpa_cli_cmd(ctrl, "TERMINATE", 0, argc, argv);
1745 }
1746 
1747 
wpa_cli_cmd_suspend(struct wpa_ctrl * ctrl,int argc,char * argv[])1748 static int wpa_cli_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
1749 {
1750 	return wpa_cli_cmd(ctrl, "SUSPEND", 0, argc, argv);
1751 }
1752 
1753 
wpa_cli_cmd_resume(struct wpa_ctrl * ctrl,int argc,char * argv[])1754 static int wpa_cli_cmd_resume(struct wpa_ctrl *ctrl, int argc, char *argv[])
1755 {
1756 	return wpa_cli_cmd(ctrl, "RESUME", 0, argc, argv);
1757 }
1758 
1759 
1760 #ifdef CONFIG_TESTING_OPTIONS
wpa_cli_cmd_drop_sa(struct wpa_ctrl * ctrl,int argc,char * argv[])1761 static int wpa_cli_cmd_drop_sa(struct wpa_ctrl *ctrl, int argc, char *argv[])
1762 {
1763 	return wpa_cli_cmd(ctrl, "DROP_SA", 0, argc, argv);
1764 }
1765 #endif /* CONFIG_TESTING_OPTIONS */
1766 
1767 
wpa_cli_cmd_roam(struct wpa_ctrl * ctrl,int argc,char * argv[])1768 static int wpa_cli_cmd_roam(struct wpa_ctrl *ctrl, int argc, char *argv[])
1769 {
1770 	return wpa_cli_cmd(ctrl, "ROAM", 1, argc, argv);
1771 }
1772 
1773 
1774 #ifdef CONFIG_MESH
1775 
wpa_cli_cmd_mesh_interface_add(struct wpa_ctrl * ctrl,int argc,char * argv[])1776 static int wpa_cli_cmd_mesh_interface_add(struct wpa_ctrl *ctrl, int argc,
1777 					  char *argv[])
1778 {
1779 	return wpa_cli_cmd(ctrl, "MESH_INTERFACE_ADD", 0, argc, argv);
1780 }
1781 
1782 
wpa_cli_cmd_mesh_group_add(struct wpa_ctrl * ctrl,int argc,char * argv[])1783 static int wpa_cli_cmd_mesh_group_add(struct wpa_ctrl *ctrl, int argc,
1784 				      char *argv[])
1785 {
1786 	return wpa_cli_cmd(ctrl, "MESH_GROUP_ADD", 1, argc, argv);
1787 }
1788 
1789 
wpa_cli_cmd_mesh_group_remove(struct wpa_ctrl * ctrl,int argc,char * argv[])1790 static int wpa_cli_cmd_mesh_group_remove(struct wpa_ctrl *ctrl, int argc,
1791 					 char *argv[])
1792 {
1793 	return wpa_cli_cmd(ctrl, "MESH_GROUP_REMOVE", 1, argc, argv);
1794 }
1795 
1796 
wpa_cli_cmd_mesh_peer_remove(struct wpa_ctrl * ctrl,int argc,char * argv[])1797 static int wpa_cli_cmd_mesh_peer_remove(struct wpa_ctrl *ctrl, int argc,
1798 					char *argv[])
1799 {
1800 	return wpa_cli_cmd(ctrl, "MESH_PEER_REMOVE", 1, argc, argv);
1801 }
1802 
1803 
wpa_cli_cmd_mesh_peer_add(struct wpa_ctrl * ctrl,int argc,char * argv[])1804 static int wpa_cli_cmd_mesh_peer_add(struct wpa_ctrl *ctrl, int argc,
1805 				     char *argv[])
1806 {
1807 	return wpa_cli_cmd(ctrl, "MESH_PEER_ADD", 1, argc, argv);
1808 }
1809 
1810 
wpa_cli_cmd_mesh_link_probe(struct wpa_ctrl * ctrl,int argc,char * argv[])1811 static int wpa_cli_cmd_mesh_link_probe(struct wpa_ctrl *ctrl, int argc,
1812 				       char *argv[])
1813 {
1814 	return wpa_cli_cmd(ctrl, "MESH_LINK_PROBE", 1, argc, argv);
1815 }
1816 
1817 #endif /* CONFIG_MESH */
1818 
1819 
1820 #ifdef CONFIG_P2P
1821 
wpa_cli_cmd_p2p_find(struct wpa_ctrl * ctrl,int argc,char * argv[])1822 static int wpa_cli_cmd_p2p_find(struct wpa_ctrl *ctrl, int argc, char *argv[])
1823 {
1824 	return wpa_cli_cmd(ctrl, "P2P_FIND", 0, argc, argv);
1825 }
1826 
1827 
wpa_cli_complete_p2p_find(const char * str,int pos)1828 static char ** wpa_cli_complete_p2p_find(const char *str, int pos)
1829 {
1830 	char **res = NULL;
1831 	int arg = get_cmd_arg_num(str, pos);
1832 
1833 	res = os_calloc(6, sizeof(char *));
1834 	if (res == NULL)
1835 		return NULL;
1836 	res[0] = os_strdup("type=social");
1837 	if (res[0] == NULL) {
1838 		os_free(res);
1839 		return NULL;
1840 	}
1841 	res[1] = os_strdup("type=progressive");
1842 	if (res[1] == NULL)
1843 		return res;
1844 	res[2] = os_strdup("delay=");
1845 	if (res[2] == NULL)
1846 		return res;
1847 	res[3] = os_strdup("dev_id=");
1848 	if (res[3] == NULL)
1849 		return res;
1850 	if (arg == 1)
1851 		res[4] = os_strdup("[timeout]");
1852 
1853 	return res;
1854 }
1855 
1856 
wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl * ctrl,int argc,char * argv[])1857 static int wpa_cli_cmd_p2p_stop_find(struct wpa_ctrl *ctrl, int argc,
1858 				     char *argv[])
1859 {
1860 	return wpa_cli_cmd(ctrl, "P2P_STOP_FIND", 0, argc, argv);
1861 }
1862 
1863 
wpa_cli_cmd_p2p_asp_provision(struct wpa_ctrl * ctrl,int argc,char * argv[])1864 static int wpa_cli_cmd_p2p_asp_provision(struct wpa_ctrl *ctrl, int argc,
1865 					 char *argv[])
1866 {
1867 	return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION", 3, argc, argv);
1868 }
1869 
1870 
wpa_cli_cmd_p2p_asp_provision_resp(struct wpa_ctrl * ctrl,int argc,char * argv[])1871 static int wpa_cli_cmd_p2p_asp_provision_resp(struct wpa_ctrl *ctrl, int argc,
1872 					      char *argv[])
1873 {
1874 	return wpa_cli_cmd(ctrl, "P2P_ASP_PROVISION_RESP", 2, argc, argv);
1875 }
1876 
1877 
wpa_cli_cmd_p2p_connect(struct wpa_ctrl * ctrl,int argc,char * argv[])1878 static int wpa_cli_cmd_p2p_connect(struct wpa_ctrl *ctrl, int argc,
1879 				   char *argv[])
1880 {
1881 	return wpa_cli_cmd(ctrl, "P2P_CONNECT", 2, argc, argv);
1882 }
1883 
1884 
wpa_cli_complete_p2p_connect(const char * str,int pos)1885 static char ** wpa_cli_complete_p2p_connect(const char *str, int pos)
1886 {
1887 	int arg = get_cmd_arg_num(str, pos);
1888 	char **res = NULL;
1889 
1890 	switch (arg) {
1891 	case 1:
1892 		res = cli_txt_list_array(&p2p_peers);
1893 		break;
1894 	}
1895 
1896 	return res;
1897 }
1898 
1899 
wpa_cli_cmd_p2p_listen(struct wpa_ctrl * ctrl,int argc,char * argv[])1900 static int wpa_cli_cmd_p2p_listen(struct wpa_ctrl *ctrl, int argc,
1901 				  char *argv[])
1902 {
1903 	return wpa_cli_cmd(ctrl, "P2P_LISTEN", 0, argc, argv);
1904 }
1905 
1906 
wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl * ctrl,int argc,char * argv[])1907 static int wpa_cli_cmd_p2p_group_remove(struct wpa_ctrl *ctrl, int argc,
1908 					char *argv[])
1909 {
1910 	return wpa_cli_cmd(ctrl, "P2P_GROUP_REMOVE", 1, argc, argv);
1911 }
1912 
1913 
wpa_cli_complete_p2p_group_remove(const char * str,int pos)1914 static char ** wpa_cli_complete_p2p_group_remove(const char *str, int pos)
1915 {
1916 	int arg = get_cmd_arg_num(str, pos);
1917 	char **res = NULL;
1918 
1919 	switch (arg) {
1920 	case 1:
1921 		res = cli_txt_list_array(&p2p_groups);
1922 		break;
1923 	}
1924 
1925 	return res;
1926 }
1927 
1928 
wpa_cli_cmd_p2p_group_add(struct wpa_ctrl * ctrl,int argc,char * argv[])1929 static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
1930 					char *argv[])
1931 {
1932 	return wpa_cli_cmd(ctrl, "P2P_GROUP_ADD", 0, argc, argv);
1933 }
1934 
1935 
wpa_cli_cmd_p2p_group_member(struct wpa_ctrl * ctrl,int argc,char * argv[])1936 static int wpa_cli_cmd_p2p_group_member(struct wpa_ctrl *ctrl, int argc,
1937 					char *argv[])
1938 {
1939 	return wpa_cli_cmd(ctrl, "P2P_GROUP_MEMBER", 1, argc, argv);
1940 }
1941 
1942 
wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl * ctrl,int argc,char * argv[])1943 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
1944 				     char *argv[])
1945 {
1946 	if (argc != 2 && argc != 3) {
1947 		wpa_printf(MSG_INFO, "Invalid P2P_PROV_DISC command: needs at least "
1948 		       "two arguments, address and config method\n"
1949 		       "(display, keypad, or pbc) and an optional join\n");
1950 		return -1;
1951 	}
1952 
1953 	return wpa_cli_cmd(ctrl, "P2P_PROV_DISC", 2, argc, argv);
1954 }
1955 
1956 
wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl * ctrl,int argc,char * argv[])1957 static int wpa_cli_cmd_p2p_get_passphrase(struct wpa_ctrl *ctrl, int argc,
1958 					  char *argv[])
1959 {
1960 	return wpa_cli_cmd(ctrl, "P2P_GET_PASSPHRASE", 0, argc, argv);
1961 }
1962 
1963 
wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl * ctrl,int argc,char * argv[])1964 static int wpa_cli_cmd_p2p_serv_disc_req(struct wpa_ctrl *ctrl, int argc,
1965 					 char *argv[])
1966 {
1967 	char cmd[CMD_BUF_LEN];
1968 
1969 	if (argc < 2) {
1970 		wpa_printf(MSG_INFO, "Invalid P2P_SERV_DISC_REQ command: needs two "
1971 		       "or more arguments (address and TLVs)\n");
1972 		return -1;
1973 	}
1974 
1975 	if (write_cmd(cmd, sizeof(cmd), "P2P_SERV_DISC_REQ", argc, argv) < 0)
1976 		return -1;
1977 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
1978 }
1979 
1980 
wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl * ctrl,int argc,char * argv[])1981 static int wpa_cli_cmd_p2p_serv_disc_cancel_req(struct wpa_ctrl *ctrl,
1982 						int argc, char *argv[])
1983 {
1984 	return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_CANCEL_REQ", 1, argc, argv);
1985 }
1986 
1987 
wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl * ctrl,int argc,char * argv[])1988 static int wpa_cli_cmd_p2p_serv_disc_resp(struct wpa_ctrl *ctrl, int argc,
1989 					  char *argv[])
1990 {
1991 	char cmd[CMD_BUF_LEN];
1992 	int res;
1993 
1994 	if (argc != 4) {
1995 		wpa_printf(MSG_INFO, "Invalid P2P_SERV_DISC_RESP command: needs four "
1996 		       "arguments (freq, address, dialog token, and TLVs)\n");
1997 		return -1;
1998 	}
1999 
2000 	res = os_snprintf(cmd, sizeof(cmd), "P2P_SERV_DISC_RESP %s %s %s %s",
2001 			  argv[0], argv[1], argv[2], argv[3]);
2002 	if (os_snprintf_error(sizeof(cmd), res))
2003 		return -1;
2004 	cmd[sizeof(cmd) - 1] = '\0';
2005 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
2006 }
2007 
2008 
wpa_cli_cmd_p2p_service_update(struct wpa_ctrl * ctrl,int argc,char * argv[])2009 static int wpa_cli_cmd_p2p_service_update(struct wpa_ctrl *ctrl, int argc,
2010 					  char *argv[])
2011 {
2012 	return wpa_cli_cmd(ctrl, "P2P_SERVICE_UPDATE", 0, argc, argv);
2013 }
2014 
2015 
wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl * ctrl,int argc,char * argv[])2016 static int wpa_cli_cmd_p2p_serv_disc_external(struct wpa_ctrl *ctrl,
2017 					      int argc, char *argv[])
2018 {
2019 	return wpa_cli_cmd(ctrl, "P2P_SERV_DISC_EXTERNAL", 1, argc, argv);
2020 }
2021 
2022 
wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl * ctrl,int argc,char * argv[])2023 static int wpa_cli_cmd_p2p_service_flush(struct wpa_ctrl *ctrl, int argc,
2024 					 char *argv[])
2025 {
2026 	return wpa_cli_cmd(ctrl, "P2P_SERVICE_FLUSH", 0, argc, argv);
2027 }
2028 
2029 
wpa_cli_cmd_p2p_service_add(struct wpa_ctrl * ctrl,int argc,char * argv[])2030 static int wpa_cli_cmd_p2p_service_add(struct wpa_ctrl *ctrl, int argc,
2031 				       char *argv[])
2032 {
2033 	if (argc < 3) {
2034 		wpa_printf(MSG_INFO, "Invalid P2P_SERVICE_ADD command: needs 3-6 arguments\n");
2035 		return -1;
2036 	}
2037 
2038 	return wpa_cli_cmd(ctrl, "P2P_SERVICE_ADD", 3, argc, argv);
2039 }
2040 
2041 
wpa_cli_cmd_p2p_service_rep(struct wpa_ctrl * ctrl,int argc,char * argv[])2042 static int wpa_cli_cmd_p2p_service_rep(struct wpa_ctrl *ctrl, int argc,
2043 				       char *argv[])
2044 {
2045 	if (argc < 5 || argc > 6) {
2046 		wpa_printf(MSG_INFO, "Invalid P2P_SERVICE_REP command: needs 5-6 "
2047 		       "arguments\n");
2048 		return -1;
2049 	}
2050 
2051 	return wpa_cli_cmd(ctrl, "P2P_SERVICE_REP", 5, argc, argv);
2052 }
2053 
2054 
wpa_cli_cmd_p2p_service_del(struct wpa_ctrl * ctrl,int argc,char * argv[])2055 static int wpa_cli_cmd_p2p_service_del(struct wpa_ctrl *ctrl, int argc,
2056 				       char *argv[])
2057 {
2058 	char cmd[CMD_BUF_LEN];
2059 	int res;
2060 
2061 	if (argc != 2 && argc != 3) {
2062 		wpa_printf(MSG_INFO, "Invalid P2P_SERVICE_DEL command: needs two or three "
2063 		       "arguments\n");
2064 		return -1;
2065 	}
2066 
2067 	if (argc == 3)
2068 		res = os_snprintf(cmd, sizeof(cmd),
2069 				  "P2P_SERVICE_DEL %s %s %s",
2070 				  argv[0], argv[1], argv[2]);
2071 	else
2072 		res = os_snprintf(cmd, sizeof(cmd),
2073 				  "P2P_SERVICE_DEL %s %s",
2074 				  argv[0], argv[1]);
2075 	if (os_snprintf_error(sizeof(cmd), res))
2076 		return -1;
2077 	cmd[sizeof(cmd) - 1] = '\0';
2078 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
2079 }
2080 
2081 
wpa_cli_cmd_p2p_reject(struct wpa_ctrl * ctrl,int argc,char * argv[])2082 static int wpa_cli_cmd_p2p_reject(struct wpa_ctrl *ctrl,
2083 				  int argc, char *argv[])
2084 {
2085 	return wpa_cli_cmd(ctrl, "P2P_REJECT", 1, argc, argv);
2086 }
2087 
2088 
wpa_cli_cmd_p2p_invite(struct wpa_ctrl * ctrl,int argc,char * argv[])2089 static int wpa_cli_cmd_p2p_invite(struct wpa_ctrl *ctrl,
2090 				  int argc, char *argv[])
2091 {
2092 	return wpa_cli_cmd(ctrl, "P2P_INVITE", 1, argc, argv);
2093 }
2094 
2095 
wpa_cli_cmd_p2p_peer(struct wpa_ctrl * ctrl,int argc,char * argv[])2096 static int wpa_cli_cmd_p2p_peer(struct wpa_ctrl *ctrl, int argc, char *argv[])
2097 {
2098 	return wpa_cli_cmd(ctrl, "P2P_PEER", 1, argc, argv);
2099 }
2100 
2101 
wpa_cli_complete_p2p_peer(const char * str,int pos)2102 static char ** wpa_cli_complete_p2p_peer(const char *str, int pos)
2103 {
2104 	int arg = get_cmd_arg_num(str, pos);
2105 	char **res = NULL;
2106 
2107 	switch (arg) {
2108 	case 1:
2109 		res = cli_txt_list_array(&p2p_peers);
2110 		break;
2111 	}
2112 
2113 	return res;
2114 }
2115 
2116 
wpa_ctrl_command_p2p_peer(struct wpa_ctrl * ctrl,const char * cmd,char * addr,size_t addr_len,int discovered)2117 static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, const char *cmd,
2118 				     char *addr, size_t addr_len,
2119 				     int discovered)
2120 {
2121 	char buf[CMD_BUF_LEN], *pos;
2122 	size_t len;
2123 	int ret;
2124 
2125 	if (ctrl_conn == NULL)
2126 		return -1;
2127 	len = sizeof(buf) - 1;
2128 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2129 			       wpa_cli_msg_cb);
2130 	if (ret == -2) {
2131 		wpa_printf(MSG_INFO, "'%s' command timed out.\n", cmd);
2132 		return -2;
2133 	} else if (ret < 0) {
2134 		wpa_printf(MSG_INFO, "'%s' command failed.\n", cmd);
2135 		return -1;
2136 	}
2137 
2138 	buf[len] = '\0';
2139 	if (os_memcmp(buf, "FAIL", 4) == 0)
2140 		return -1;
2141 
2142 	pos = buf;
2143 	while (*pos != '\0' && *pos != '\n')
2144 		pos++;
2145 	*pos++ = '\0';
2146 	os_strlcpy(addr, buf, addr_len);
2147 	if (!discovered || os_strstr(pos, "[PROBE_REQ_ONLY]") == NULL)
2148 		wpa_printf(MSG_INFO, "%s\n", addr);
2149 	return 0;
2150 }
2151 
2152 
wpa_cli_cmd_p2p_peers(struct wpa_ctrl * ctrl,int argc,char * argv[])2153 static int wpa_cli_cmd_p2p_peers(struct wpa_ctrl *ctrl, int argc, char *argv[])
2154 {
2155 	char addr[32], cmd[64];
2156 	int discovered;
2157 
2158 	discovered = argc > 0 && os_strcmp(argv[0], "discovered") == 0;
2159 
2160 	if (wpa_ctrl_command_p2p_peer(ctrl, "P2P_PEER FIRST",
2161 				      addr, sizeof(addr), discovered))
2162 		return -1;
2163 	do {
2164 		os_snprintf(cmd, sizeof(cmd), "P2P_PEER NEXT-%s", addr);
2165 	} while (wpa_ctrl_command_p2p_peer(ctrl, cmd, addr, sizeof(addr),
2166 			 discovered) == 0);
2167 
2168 	return 0;
2169 }
2170 
2171 
wpa_cli_cmd_p2p_set(struct wpa_ctrl * ctrl,int argc,char * argv[])2172 static int wpa_cli_cmd_p2p_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
2173 {
2174 	return wpa_cli_cmd(ctrl, "P2P_SET", 2, argc, argv);
2175 }
2176 
2177 
wpa_cli_complete_p2p_set(const char * str,int pos)2178 static char ** wpa_cli_complete_p2p_set(const char *str, int pos)
2179 {
2180 	int arg = get_cmd_arg_num(str, pos);
2181 	const char *fields[] = {
2182 		"discoverability",
2183 		"managed",
2184 		"listen_channel",
2185 		"ssid_postfix",
2186 		"noa",
2187 		"ps",
2188 		"oppps",
2189 		"ctwindow",
2190 		"disabled",
2191 		"conc_pref",
2192 		"force_long_sd",
2193 		"peer_filter",
2194 		"cross_connect",
2195 		"go_apsd",
2196 		"client_apsd",
2197 		"disallow_freq",
2198 		"disc_int",
2199 		"per_sta_psk",
2200 	};
2201 	int i, num_fields = ARRAY_SIZE(fields);
2202 
2203 	if (arg == 1) {
2204 		char **res = os_calloc(num_fields + 1, sizeof(char *));
2205 		if (res == NULL)
2206 			return NULL;
2207 		for (i = 0; i < num_fields; i++) {
2208 			res[i] = os_strdup(fields[i]);
2209 			if (res[i] == NULL)
2210 				return res;
2211 		}
2212 		return res;
2213 	}
2214 
2215 	if (arg == 2 && os_strncasecmp(str, "p2p_set peer_filter ", 20) == 0)
2216 		return cli_txt_list_array(&p2p_peers);
2217 
2218 	return NULL;
2219 }
2220 
2221 
wpa_cli_cmd_p2p_flush(struct wpa_ctrl * ctrl,int argc,char * argv[])2222 static int wpa_cli_cmd_p2p_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2223 {
2224 	return wpa_cli_cmd(ctrl, "P2P_FLUSH", 0, argc, argv);
2225 }
2226 
2227 
wpa_cli_cmd_p2p_cancel(struct wpa_ctrl * ctrl,int argc,char * argv[])2228 static int wpa_cli_cmd_p2p_cancel(struct wpa_ctrl *ctrl, int argc,
2229 				  char *argv[])
2230 {
2231 	return wpa_cli_cmd(ctrl, "P2P_CANCEL", 0, argc, argv);
2232 }
2233 
2234 
wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl * ctrl,int argc,char * argv[])2235 static int wpa_cli_cmd_p2p_unauthorize(struct wpa_ctrl *ctrl, int argc,
2236 				       char *argv[])
2237 {
2238 	return wpa_cli_cmd(ctrl, "P2P_UNAUTHORIZE", 1, argc, argv);
2239 }
2240 
2241 
wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl * ctrl,int argc,char * argv[])2242 static int wpa_cli_cmd_p2p_presence_req(struct wpa_ctrl *ctrl, int argc,
2243 					char *argv[])
2244 {
2245 	if (argc != 0 && argc != 2 && argc != 4) {
2246 		wpa_printf(MSG_INFO, "Invalid P2P_PRESENCE_REQ command: needs two arguments "
2247 		       "(preferred duration, interval; in microsecods).\n"
2248 		       "Optional second pair can be used to provide "
2249 		       "acceptable values.\n");
2250 		return -1;
2251 	}
2252 
2253 	return wpa_cli_cmd(ctrl, "P2P_PRESENCE_REQ", 0, argc, argv);
2254 }
2255 
2256 
wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl * ctrl,int argc,char * argv[])2257 static int wpa_cli_cmd_p2p_ext_listen(struct wpa_ctrl *ctrl, int argc,
2258 				      char *argv[])
2259 {
2260 	if (argc != 0 && argc != 2) {
2261 		wpa_printf(MSG_INFO, "Invalid P2P_EXT_LISTEN command: needs two arguments "
2262 		       "(availability period, availability interval; in "
2263 		       "millisecods).\n"
2264 		       "Extended Listen Timing can be cancelled with this "
2265 		       "command when used without parameters.\n");
2266 		return -1;
2267 	}
2268 
2269 	return wpa_cli_cmd(ctrl, "P2P_EXT_LISTEN", 0, argc, argv);
2270 }
2271 
2272 
wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl * ctrl,int argc,char * argv[])2273 static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc,
2274 					 char *argv[])
2275 {
2276 	return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv);
2277 }
2278 
2279 #endif /* CONFIG_P2P */
2280 
2281 
wpa_cli_cmd_vendor_elem_add(struct wpa_ctrl * ctrl,int argc,char * argv[])2282 static int wpa_cli_cmd_vendor_elem_add(struct wpa_ctrl *ctrl, int argc,
2283 				       char *argv[])
2284 {
2285 	return wpa_cli_cmd(ctrl, "VENDOR_ELEM_ADD", 2, argc, argv);
2286 }
2287 
2288 
wpa_cli_cmd_vendor_elem_get(struct wpa_ctrl * ctrl,int argc,char * argv[])2289 static int wpa_cli_cmd_vendor_elem_get(struct wpa_ctrl *ctrl, int argc,
2290 				       char *argv[])
2291 {
2292 	return wpa_cli_cmd(ctrl, "VENDOR_ELEM_GET", 1, argc, argv);
2293 }
2294 
2295 
wpa_cli_cmd_vendor_elem_remove(struct wpa_ctrl * ctrl,int argc,char * argv[])2296 static int wpa_cli_cmd_vendor_elem_remove(struct wpa_ctrl *ctrl, int argc,
2297 					  char *argv[])
2298 {
2299 	return wpa_cli_cmd(ctrl, "VENDOR_ELEM_REMOVE", 2, argc, argv);
2300 }
2301 
2302 
2303 #ifdef CONFIG_WIFI_DISPLAY
2304 
wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl * ctrl,int argc,char * argv[])2305 static int wpa_cli_cmd_wfd_subelem_set(struct wpa_ctrl *ctrl, int argc,
2306 				       char *argv[])
2307 {
2308 	char cmd[100];
2309 	int res;
2310 
2311 	if (argc != 1 && argc != 2) {
2312 		wpa_printf(MSG_INFO, "Invalid WFD_SUBELEM_SET command: needs one or two "
2313 		       "arguments (subelem, hexdump)\n");
2314 		return -1;
2315 	}
2316 
2317 	res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_SET %s %s",
2318 			  argv[0], argc > 1 ? argv[1] : "");
2319 	if (os_snprintf_error(sizeof(cmd), res))
2320 		return -1;
2321 	cmd[sizeof(cmd) - 1] = '\0';
2322 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
2323 }
2324 
2325 
wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl * ctrl,int argc,char * argv[])2326 static int wpa_cli_cmd_wfd_subelem_get(struct wpa_ctrl *ctrl, int argc,
2327 				       char *argv[])
2328 {
2329 	char cmd[100];
2330 	int res;
2331 
2332 	if (argc != 1) {
2333 		wpa_printf(MSG_INFO, "Invalid WFD_SUBELEM_GET command: needs one "
2334 		       "argument (subelem)\n");
2335 		return -1;
2336 	}
2337 
2338 	res = os_snprintf(cmd, sizeof(cmd), "WFD_SUBELEM_GET %s",
2339 			  argv[0]);
2340 	if (os_snprintf_error(sizeof(cmd), res))
2341 		return -1;
2342 	cmd[sizeof(cmd) - 1] = '\0';
2343 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
2344 }
2345 #endif /* CONFIG_WIFI_DISPLAY */
2346 
2347 
2348 #ifdef CONFIG_INTERWORKING
wpa_cli_cmd_fetch_anqp(struct wpa_ctrl * ctrl,int argc,char * argv[])2349 static int wpa_cli_cmd_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2350 				  char *argv[])
2351 {
2352 	return wpa_cli_cmd(ctrl, "FETCH_ANQP", 0, argc, argv);
2353 }
2354 
2355 
wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl * ctrl,int argc,char * argv[])2356 static int wpa_cli_cmd_stop_fetch_anqp(struct wpa_ctrl *ctrl, int argc,
2357 				       char *argv[])
2358 {
2359 	return wpa_cli_cmd(ctrl, "STOP_FETCH_ANQP", 0, argc, argv);
2360 }
2361 
2362 
wpa_cli_cmd_interworking_select(struct wpa_ctrl * ctrl,int argc,char * argv[])2363 static int wpa_cli_cmd_interworking_select(struct wpa_ctrl *ctrl, int argc,
2364 					   char *argv[])
2365 {
2366 	return wpa_cli_cmd(ctrl, "INTERWORKING_SELECT", 0, argc, argv);
2367 }
2368 
2369 
wpa_cli_cmd_interworking_connect(struct wpa_ctrl * ctrl,int argc,char * argv[])2370 static int wpa_cli_cmd_interworking_connect(struct wpa_ctrl *ctrl, int argc,
2371 					    char *argv[])
2372 {
2373 	return wpa_cli_cmd(ctrl, "INTERWORKING_CONNECT", 1, argc, argv);
2374 }
2375 
2376 
wpa_cli_cmd_interworking_add_network(struct wpa_ctrl * ctrl,int argc,char * argv[])2377 static int wpa_cli_cmd_interworking_add_network(struct wpa_ctrl *ctrl, int argc,
2378 						char *argv[])
2379 {
2380 	return wpa_cli_cmd(ctrl, "INTERWORKING_ADD_NETWORK", 1, argc, argv);
2381 }
2382 
2383 
wpa_cli_cmd_anqp_get(struct wpa_ctrl * ctrl,int argc,char * argv[])2384 static int wpa_cli_cmd_anqp_get(struct wpa_ctrl *ctrl, int argc, char *argv[])
2385 {
2386 	return wpa_cli_cmd(ctrl, "ANQP_GET", 2, argc, argv);
2387 }
2388 
2389 
wpa_cli_cmd_gas_request(struct wpa_ctrl * ctrl,int argc,char * argv[])2390 static int wpa_cli_cmd_gas_request(struct wpa_ctrl *ctrl, int argc,
2391 				   char *argv[])
2392 {
2393 	return wpa_cli_cmd(ctrl, "GAS_REQUEST", 2, argc, argv);
2394 }
2395 
2396 
wpa_cli_cmd_gas_response_get(struct wpa_ctrl * ctrl,int argc,char * argv[])2397 static int wpa_cli_cmd_gas_response_get(struct wpa_ctrl *ctrl, int argc,
2398 					char *argv[])
2399 {
2400 	return wpa_cli_cmd(ctrl, "GAS_RESPONSE_GET", 2, argc, argv);
2401 }
2402 #endif /* CONFIG_INTERWORKING */
2403 
2404 
2405 #ifdef CONFIG_HS20
2406 
wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl * ctrl,int argc,char * argv[])2407 static int wpa_cli_cmd_hs20_anqp_get(struct wpa_ctrl *ctrl, int argc,
2408 				     char *argv[])
2409 {
2410 	return wpa_cli_cmd(ctrl, "HS20_ANQP_GET", 2, argc, argv);
2411 }
2412 
2413 
wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl * ctrl,int argc,char * argv[])2414 static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc,
2415 					       char *argv[])
2416 {
2417 	char cmd[512];
2418 
2419 	if (argc == 0) {
2420 		wpa_printf(MSG_INFO, "Command needs one or two arguments (dst mac addr and "
2421 		       "optional home realm)\n");
2422 		return -1;
2423 	}
2424 
2425 	if (write_cmd(cmd, sizeof(cmd), "HS20_GET_NAI_HOME_REALM_LIST",
2426 		      argc, argv) < 0)
2427 		return -1;
2428 
2429 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
2430 }
2431 
2432 
wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl * ctrl,int argc,char * argv[])2433 static int wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl *ctrl, int argc,
2434 					 char *argv[])
2435 {
2436 	char cmd[512];
2437 
2438 	if (argc < 2) {
2439 		wpa_printf(MSG_INFO, "Command needs two arguments (dst mac addr and "
2440 		       "icon name)\n");
2441 		return -1;
2442 	}
2443 
2444 	if (write_cmd(cmd, sizeof(cmd), "HS20_ICON_REQUEST", argc, argv) < 0)
2445 		return -1;
2446 
2447 	return wpa_cli_cmd(ctrl, cmd, 0, argc, argv);
2448 }
2449 
2450 
wpa_cli_cmd_fetch_osu(struct wpa_ctrl * ctrl,int argc,char * argv[])2451 static int wpa_cli_cmd_fetch_osu(struct wpa_ctrl *ctrl, int argc, char *argv[])
2452 {
2453 	return wpa_cli_cmd(ctrl, "FETCH_OSU", 0, argc, argv);
2454 }
2455 
2456 
wpa_cli_cmd_cancel_fetch_osu(struct wpa_ctrl * ctrl,int argc,char * argv[])2457 static int wpa_cli_cmd_cancel_fetch_osu(struct wpa_ctrl *ctrl, int argc,
2458 					char *argv[])
2459 {
2460 	return wpa_cli_cmd(ctrl, "CANCEL_FETCH_OSU", 0, argc, argv);
2461 }
2462 
2463 #endif /* CONFIG_HS20 */
2464 
2465 
wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl * ctrl,int argc,char * argv[])2466 static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
2467 				       char *argv[])
2468 {
2469 	return wpa_cli_cmd(ctrl, "STA_AUTOCONNECT", 1, argc, argv);
2470 }
2471 
2472 
wpa_cli_cmd_tdls_discover(struct wpa_ctrl * ctrl,int argc,char * argv[])2473 static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
2474 				     char *argv[])
2475 {
2476 	return wpa_cli_cmd(ctrl, "TDLS_DISCOVER", 1, argc, argv);
2477 }
2478 
2479 
wpa_cli_cmd_tdls_setup(struct wpa_ctrl * ctrl,int argc,char * argv[])2480 static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
2481 				  char *argv[])
2482 {
2483 	return wpa_cli_cmd(ctrl, "TDLS_SETUP", 1, argc, argv);
2484 }
2485 
2486 
wpa_cli_cmd_tdls_teardown(struct wpa_ctrl * ctrl,int argc,char * argv[])2487 static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
2488 				     char *argv[])
2489 {
2490 	return wpa_cli_cmd(ctrl, "TDLS_TEARDOWN", 1, argc, argv);
2491 }
2492 
2493 
wpa_cli_cmd_tdls_link_status(struct wpa_ctrl * ctrl,int argc,char * argv[])2494 static int wpa_cli_cmd_tdls_link_status(struct wpa_ctrl *ctrl, int argc,
2495 					char *argv[])
2496 {
2497 	return wpa_cli_cmd(ctrl, "TDLS_LINK_STATUS", 1, argc, argv);
2498 }
2499 
2500 #ifndef CONFIG_NO_WMM_AC
wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl * ctrl,int argc,char * argv[])2501 static int wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl *ctrl, int argc,
2502 				    char *argv[])
2503 {
2504 	return wpa_cli_cmd(ctrl, "WMM_AC_ADDTS", 3, argc, argv);
2505 }
2506 
2507 
wpa_cli_cmd_wmm_ac_delts(struct wpa_ctrl * ctrl,int argc,char * argv[])2508 static int wpa_cli_cmd_wmm_ac_delts(struct wpa_ctrl *ctrl, int argc,
2509 				    char *argv[])
2510 {
2511 	return wpa_cli_cmd(ctrl, "WMM_AC_DELTS", 1, argc, argv);
2512 }
2513 
2514 
wpa_cli_cmd_wmm_ac_status(struct wpa_ctrl * ctrl,int argc,char * argv[])2515 static int wpa_cli_cmd_wmm_ac_status(struct wpa_ctrl *ctrl, int argc,
2516 				    char *argv[])
2517 {
2518 	return wpa_cli_cmd(ctrl, "WMM_AC_STATUS", 0, argc, argv);
2519 }
2520 #endif /* !CONFIG_NO_WMM_AC */
2521 
wpa_cli_cmd_tdls_chan_switch(struct wpa_ctrl * ctrl,int argc,char * argv[])2522 static int wpa_cli_cmd_tdls_chan_switch(struct wpa_ctrl *ctrl, int argc,
2523 					char *argv[])
2524 {
2525 	return wpa_cli_cmd(ctrl, "TDLS_CHAN_SWITCH", 2, argc, argv);
2526 }
2527 
2528 
wpa_cli_cmd_tdls_cancel_chan_switch(struct wpa_ctrl * ctrl,int argc,char * argv[])2529 static int wpa_cli_cmd_tdls_cancel_chan_switch(struct wpa_ctrl *ctrl, int argc,
2530 					       char *argv[])
2531 {
2532 	return wpa_cli_cmd(ctrl, "TDLS_CANCEL_CHAN_SWITCH", 1, argc, argv);
2533 }
2534 
2535 
wpa_cli_cmd_signal_poll(struct wpa_ctrl * ctrl,int argc,char * argv[])2536 static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
2537 				   char *argv[])
2538 {
2539 	return wpa_cli_cmd(ctrl, "SIGNAL_POLL", 0, argc, argv);
2540 }
2541 
2542 
wpa_cli_cmd_signal_monitor(struct wpa_ctrl * ctrl,int argc,char * argv[])2543 static int wpa_cli_cmd_signal_monitor(struct wpa_ctrl *ctrl, int argc,
2544 				   char *argv[])
2545 {
2546 	return wpa_cli_cmd(ctrl, "SIGNAL_MONITOR", 0, argc, argv);
2547 }
2548 
2549 
wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl * ctrl,int argc,char * argv[])2550 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
2551 				   char *argv[])
2552 {
2553 	return wpa_cli_cmd(ctrl, "PKTCNT_POLL", 0, argc, argv);
2554 }
2555 
2556 
wpa_cli_cmd_reauthenticate(struct wpa_ctrl * ctrl,int argc,char * argv[])2557 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
2558 				      char *argv[])
2559 {
2560 	return wpa_cli_cmd(ctrl, "REAUTHENTICATE", 0, argc, argv);
2561 }
2562 
2563 
2564 #ifdef CONFIG_AUTOSCAN
2565 
wpa_cli_cmd_autoscan(struct wpa_ctrl * ctrl,int argc,char * argv[])2566 static int wpa_cli_cmd_autoscan(struct wpa_ctrl *ctrl, int argc, char *argv[])
2567 {
2568 	if (argc == 0)
2569 		return wpa_cli_cmd(ctrl, "AUTOSCAN ", 0, argc, argv);
2570 
2571 	return wpa_cli_cmd(ctrl, "AUTOSCAN", 0, argc, argv);
2572 }
2573 
2574 #endif /* CONFIG_AUTOSCAN */
2575 
2576 
2577 #ifdef CONFIG_WNM
2578 
wpa_cli_cmd_wnm_sleep(struct wpa_ctrl * ctrl,int argc,char * argv[])2579 static int wpa_cli_cmd_wnm_sleep(struct wpa_ctrl *ctrl, int argc, char *argv[])
2580 {
2581 	return wpa_cli_cmd(ctrl, "WNM_SLEEP", 0, argc, argv);
2582 }
2583 
2584 
wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl * ctrl,int argc,char * argv[])2585 static int wpa_cli_cmd_wnm_bss_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
2586 {
2587 	return wpa_cli_cmd(ctrl, "WNM_BSS_QUERY", 1, argc, argv);
2588 }
2589 
2590 #endif /* CONFIG_WNM */
2591 
2592 
wpa_cli_cmd_raw(struct wpa_ctrl * ctrl,int argc,char * argv[])2593 static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
2594 {
2595 	if (argc == 0)
2596 		return -1;
2597 	return wpa_cli_cmd(ctrl, argv[0], 0, argc - 1, &argv[1]);
2598 }
2599 
wpa_cli_cmd_vendor(struct wpa_ctrl * ctrl,int argc,char * argv[])2600 static int wpa_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
2601 {
2602 	return wpa_cli_cmd(ctrl, "VENDOR", 1, argc, argv);
2603 }
2604 
2605 
wpa_cli_cmd_flush(struct wpa_ctrl * ctrl,int argc,char * argv[])2606 static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2607 {
2608 	return wpa_cli_cmd(ctrl, "FLUSH", 0, argc, argv);
2609 }
2610 
2611 
wpa_cli_cmd_radio_work(struct wpa_ctrl * ctrl,int argc,char * argv[])2612 static int wpa_cli_cmd_radio_work(struct wpa_ctrl *ctrl, int argc, char *argv[])
2613 {
2614 	return wpa_cli_cmd(ctrl, "RADIO_WORK", 1, argc, argv);
2615 }
2616 
2617 
wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl * ctrl,int argc,char * argv[])2618 static int wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl *ctrl, int argc,
2619 					    char *argv[])
2620 {
2621 	return wpa_cli_cmd(ctrl, "NEIGHBOR_REP_REQUEST", 0, argc, argv);
2622 }
2623 
2624 
wpa_cli_cmd_twt_setup(struct wpa_ctrl * ctrl,int argc,char * argv[])2625 static int wpa_cli_cmd_twt_setup(struct wpa_ctrl *ctrl, int argc,
2626 				 char *argv[])
2627 {
2628 	return wpa_cli_cmd(ctrl, "TWT_SETUP", 0, argc, argv);
2629 }
2630 
2631 
wpa_cli_cmd_twt_teardown(struct wpa_ctrl * ctrl,int argc,char * argv[])2632 static int wpa_cli_cmd_twt_teardown(struct wpa_ctrl *ctrl, int argc,
2633 				    char *argv[])
2634 {
2635 	return wpa_cli_cmd(ctrl, "TWT_TEARDOWN", 0, argc, argv);
2636 }
2637 
2638 
wpa_cli_cmd_erp_flush(struct wpa_ctrl * ctrl,int argc,char * argv[])2639 static int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
2640 {
2641 	return wpa_cli_cmd(ctrl, "ERP_FLUSH", 0, argc, argv);
2642 }
2643 
2644 
wpa_cli_cmd_mac_rand_scan(struct wpa_ctrl * ctrl,int argc,char * argv[])2645 static int wpa_cli_cmd_mac_rand_scan(struct wpa_ctrl *ctrl, int argc,
2646 				     char *argv[])
2647 {
2648 	return wpa_cli_cmd(ctrl, "MAC_RAND_SCAN", 1, argc, argv);
2649 }
2650 
2651 
wpa_cli_cmd_get_pref_freq_list(struct wpa_ctrl * ctrl,int argc,char * argv[])2652 static int wpa_cli_cmd_get_pref_freq_list(struct wpa_ctrl *ctrl, int argc,
2653 					  char *argv[])
2654 {
2655 	return wpa_cli_cmd(ctrl, "GET_PREF_FREQ_LIST", 1, argc, argv);
2656 }
2657 
2658 
wpa_cli_cmd_p2p_lo_start(struct wpa_ctrl * ctrl,int argc,char * argv[])2659 static int wpa_cli_cmd_p2p_lo_start(struct wpa_ctrl *ctrl, int argc,
2660 				    char *argv[])
2661 {
2662 	return wpa_cli_cmd(ctrl, "P2P_LO_START", 4, argc, argv);
2663 }
2664 
2665 
wpa_cli_cmd_p2p_lo_stop(struct wpa_ctrl * ctrl,int argc,char * argv[])2666 static int wpa_cli_cmd_p2p_lo_stop(struct wpa_ctrl *ctrl, int argc,
2667 				   char *argv[])
2668 {
2669 	return wpa_cli_cmd(ctrl, "P2P_LO_STOP", 0, argc, argv);
2670 }
2671 
2672 
2673 #ifdef CONFIG_DPP
2674 
wpa_cli_cmd_dpp_qr_code(struct wpa_ctrl * ctrl,int argc,char * argv[])2675 static int wpa_cli_cmd_dpp_qr_code(struct wpa_ctrl *ctrl, int argc,
2676 				   char *argv[])
2677 {
2678 	return wpa_cli_cmd(ctrl, "DPP_QR_CODE", 1, argc, argv);
2679 }
2680 
2681 
wpa_cli_cmd_dpp_bootstrap_gen(struct wpa_ctrl * ctrl,int argc,char * argv[])2682 static int wpa_cli_cmd_dpp_bootstrap_gen(struct wpa_ctrl *ctrl, int argc,
2683 					 char *argv[])
2684 {
2685 	return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_GEN", 1, argc, argv);
2686 }
2687 
2688 
wpa_cli_cmd_dpp_bootstrap_remove(struct wpa_ctrl * ctrl,int argc,char * argv[])2689 static int wpa_cli_cmd_dpp_bootstrap_remove(struct wpa_ctrl *ctrl, int argc,
2690 					    char *argv[])
2691 {
2692 	return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_REMOVE", 1, argc, argv);
2693 }
2694 
2695 
wpa_cli_cmd_dpp_bootstrap_get_uri(struct wpa_ctrl * ctrl,int argc,char * argv[])2696 static int wpa_cli_cmd_dpp_bootstrap_get_uri(struct wpa_ctrl *ctrl, int argc,
2697 					     char *argv[])
2698 {
2699 	return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_GET_URI", 1, argc, argv);
2700 }
2701 
2702 
wpa_cli_cmd_dpp_bootstrap_info(struct wpa_ctrl * ctrl,int argc,char * argv[])2703 static int wpa_cli_cmd_dpp_bootstrap_info(struct wpa_ctrl *ctrl, int argc,
2704 					  char *argv[])
2705 {
2706 	return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_INFO", 1, argc, argv);
2707 }
2708 
2709 
wpa_cli_cmd_dpp_bootstrap_set(struct wpa_ctrl * ctrl,int argc,char * argv[])2710 static int wpa_cli_cmd_dpp_bootstrap_set(struct wpa_ctrl *ctrl, int argc,
2711 					 char *argv[])
2712 {
2713 	return wpa_cli_cmd(ctrl, "DPP_BOOTSTRAP_SET", 1, argc, argv);
2714 }
2715 
2716 
wpa_cli_cmd_dpp_auth_init(struct wpa_ctrl * ctrl,int argc,char * argv[])2717 static int wpa_cli_cmd_dpp_auth_init(struct wpa_ctrl *ctrl, int argc,
2718 				     char *argv[])
2719 {
2720 	return wpa_cli_cmd(ctrl, "DPP_AUTH_INIT", 1, argc, argv);
2721 }
2722 
2723 
wpa_cli_cmd_dpp_listen(struct wpa_ctrl * ctrl,int argc,char * argv[])2724 static int wpa_cli_cmd_dpp_listen(struct wpa_ctrl *ctrl, int argc,
2725 				  char *argv[])
2726 {
2727 	return wpa_cli_cmd(ctrl, "DPP_LISTEN", 1, argc, argv);
2728 }
2729 
2730 
wpa_cli_cmd_dpp_stop_listen(struct wpa_ctrl * ctrl,int argc,char * argv[])2731 static int wpa_cli_cmd_dpp_stop_listen(struct wpa_ctrl *ctrl, int argc,
2732 				       char *argv[])
2733 {
2734 	return wpa_cli_cmd(ctrl, "DPP_STOP_LISTEN", 0, argc, argv);
2735 }
2736 
2737 
wpa_cli_cmd_dpp_configurator_add(struct wpa_ctrl * ctrl,int argc,char * argv[])2738 static int wpa_cli_cmd_dpp_configurator_add(struct wpa_ctrl *ctrl, int argc,
2739 					    char *argv[])
2740 {
2741 	return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_ADD", 0, argc, argv);
2742 }
2743 
2744 
wpa_cli_cmd_dpp_configurator_remove(struct wpa_ctrl * ctrl,int argc,char * argv[])2745 static int wpa_cli_cmd_dpp_configurator_remove(struct wpa_ctrl *ctrl, int argc,
2746 					       char *argv[])
2747 {
2748 	return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_REMOVE", 1, argc, argv);
2749 }
2750 
2751 
wpa_cli_cmd_dpp_configurator_get_key(struct wpa_ctrl * ctrl,int argc,char * argv[])2752 static int wpa_cli_cmd_dpp_configurator_get_key(struct wpa_ctrl *ctrl, int argc,
2753 						char *argv[])
2754 {
2755 	return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_GET_KEY", 1, argc, argv);
2756 }
2757 
2758 
wpa_cli_cmd_dpp_configurator_sign(struct wpa_ctrl * ctrl,int argc,char * argv[])2759 static int wpa_cli_cmd_dpp_configurator_sign(struct wpa_ctrl *ctrl, int argc,
2760 					     char *argv[])
2761 {
2762 	return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_SIGN", 1, argc, argv);
2763 }
2764 
2765 
wpa_cli_cmd_dpp_pkex_add(struct wpa_ctrl * ctrl,int argc,char * argv[])2766 static int wpa_cli_cmd_dpp_pkex_add(struct wpa_ctrl *ctrl, int argc,
2767 				    char *argv[])
2768 {
2769 	return wpa_cli_cmd(ctrl, "DPP_PKEX_ADD", 1, argc, argv);
2770 }
2771 
2772 
wpa_cli_cmd_dpp_pkex_remove(struct wpa_ctrl * ctrl,int argc,char * argv[])2773 static int wpa_cli_cmd_dpp_pkex_remove(struct wpa_ctrl *ctrl, int argc,
2774 				       char *argv[])
2775 {
2776 	return wpa_cli_cmd(ctrl, "DPP_PKEX_REMOVE", 1, argc, argv);
2777 }
2778 
2779 
2780 #ifdef CONFIG_DPP2
2781 
wpa_cli_cmd_dpp_controller_start(struct wpa_ctrl * ctrl,int argc,char * argv[])2782 static int wpa_cli_cmd_dpp_controller_start(struct wpa_ctrl *ctrl, int argc,
2783 					    char *argv[])
2784 {
2785 	return wpa_cli_cmd(ctrl, "DPP_CONTROLLER_START", 1, argc, argv);
2786 }
2787 
2788 
wpa_cli_cmd_dpp_controller_stop(struct wpa_ctrl * ctrl,int argc,char * argv[])2789 static int wpa_cli_cmd_dpp_controller_stop(struct wpa_ctrl *ctrl, int argc,
2790 					    char *argv[])
2791 {
2792 	return wpa_cli_cmd(ctrl, "DPP_CONTROLLER_STOP", 0, argc, argv);
2793 }
2794 
2795 
wpa_cli_cmd_dpp_chirp(struct wpa_ctrl * ctrl,int argc,char * argv[])2796 static int wpa_cli_cmd_dpp_chirp(struct wpa_ctrl *ctrl, int argc,
2797 				 char *argv[])
2798 {
2799 	return wpa_cli_cmd(ctrl, "DPP_CHIRP", 1, argc, argv);
2800 }
2801 
2802 
wpa_cli_cmd_dpp_stop_chirp(struct wpa_ctrl * ctrl,int argc,char * argv[])2803 static int wpa_cli_cmd_dpp_stop_chirp(struct wpa_ctrl *ctrl, int argc,
2804 				      char *argv[])
2805 {
2806 	return wpa_cli_cmd(ctrl, "DPP_STOP_CHIRP", 0, argc, argv);
2807 }
2808 
2809 #endif /* CONFIG_DPP2 */
2810 #endif /* CONFIG_DPP */
2811 
2812 
wpa_ctrl_command_bss(struct wpa_ctrl * ctrl,const char * cmd)2813 static int wpa_ctrl_command_bss(struct wpa_ctrl *ctrl, const char *cmd)
2814 {
2815 	char buf[512], *pos, *bssid = NULL, *freq = NULL, *level = NULL,
2816 		*flags = NULL, *ssid = NULL;
2817 	size_t len;
2818 	int ret, id = -1;
2819 
2820 	if (!ctrl_conn)
2821 		return -1;
2822 	len = sizeof(buf) - 1;
2823 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
2824 			       wpa_cli_msg_cb);
2825 	if (ret == -2) {
2826 		wpa_printf(MSG_INFO, "'%s' command timed out.\n", cmd);
2827 		return -2;
2828 	} else if (ret < 0) {
2829 		wpa_printf(MSG_INFO, "'%s' command failed.\n", cmd);
2830 		return -1;
2831 	}
2832 
2833 	buf[len] = '\0';
2834 	if (os_memcmp(buf, "FAIL", 4) == 0)
2835 		return -1;
2836 
2837 	pos = buf;
2838 	while (*pos != '\0') {
2839 		if (str_starts(pos, "id="))
2840 			id = atoi(pos + 3);
2841 		if (str_starts(pos, "bssid="))
2842 			bssid = pos + 6;
2843 		if (str_starts(pos, "freq="))
2844 			freq = pos + 5;
2845 		if (str_starts(pos, "level="))
2846 			level = pos + 6;
2847 		if (str_starts(pos, "flags="))
2848 			flags = pos + 6;
2849 		if (str_starts(pos, "ssid="))
2850 			ssid = pos + 5;
2851 
2852 		while (*pos != '\0' && *pos != '\n')
2853 			pos++;
2854 		*pos++ = '\0';
2855 	}
2856 	if (id != -1)
2857 		wpa_printf(MSG_INFO, "%s\t%s\t%s\t%s\t%s\n", bssid ? bssid : "N/A",
2858 		       freq ? freq : "N/A", level ? level : "N/A",
2859 		       flags ? flags : "N/A", ssid ? ssid : "N/A");
2860 	return id;
2861 }
2862 
2863 
wpa_cli_cmd_all_bss(struct wpa_ctrl * ctrl,int argc,char * argv[])2864 static int wpa_cli_cmd_all_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
2865 {
2866 	char cmd[64];
2867 	int id = -1;
2868 	unsigned int mask;
2869 
2870 	wpa_printf(MSG_INFO, "bssid / frequency / signal level / flags / ssid\n");
2871 
2872 	mask = WPA_BSS_MASK_ID | WPA_BSS_MASK_BSSID | WPA_BSS_MASK_FREQ |
2873 		WPA_BSS_MASK_LEVEL | WPA_BSS_MASK_FLAGS | WPA_BSS_MASK_SSID;
2874 	do {
2875 		if (id < 0)
2876 			os_snprintf(cmd, sizeof(cmd), "BSS FIRST MASK=0x%x",
2877 				    mask);
2878 		else
2879 			os_snprintf(cmd, sizeof(cmd), "BSS NEXT-%d MASK=0x%x",
2880 				    id, mask);
2881 		id = wpa_ctrl_command_bss(ctrl, cmd);
2882 	} while (id >= 0);
2883 
2884 	return 0;
2885 }
2886 
2887 
2888 #ifdef CONFIG_PASN
2889 
wpa_cli_cmd_pasn_auth_start(struct wpa_ctrl * ctrl,int argc,char * argv[])2890 static int wpa_cli_cmd_pasn_auth_start(struct wpa_ctrl *ctrl, int argc,
2891 				       char *argv[])
2892 {
2893 	return wpa_cli_cmd(ctrl, "PASN_AUTH_START", 4, argc, argv);
2894 }
2895 
2896 
wpa_cli_cmd_pasn_auth_stop(struct wpa_ctrl * ctrl,int argc,char * argv[])2897 static int wpa_cli_cmd_pasn_auth_stop(struct wpa_ctrl *ctrl, int argc,
2898 				      char *argv[])
2899 {
2900 	return wpa_cli_cmd(ctrl, "PASN_AUTH_STOP", 0, argc, argv);
2901 }
2902 
wpa_cli_cmd_ptksa_cache_list(struct wpa_ctrl * ctrl,int argc,char * argv[])2903 static int wpa_cli_cmd_ptksa_cache_list(struct wpa_ctrl *ctrl, int argc,
2904 					char *argv[])
2905 {
2906 	return wpa_cli_cmd(ctrl, "PTKSA_CACHE_LIST", 0, argc, argv);
2907 }
2908 
2909 
wpa_cli_cmd_pasn_deauth(struct wpa_ctrl * ctrl,int argc,char * argv[])2910 static int wpa_cli_cmd_pasn_deauth(struct wpa_ctrl *ctrl, int argc,
2911 				   char *argv[])
2912 {
2913 	return wpa_cli_cmd(ctrl, "PASN_DEAUTH", 1, argc, argv);
2914 }
2915 
2916 #endif /* CONFIG_PASN */
2917 
2918 
wpa_cli_cmd_mscs(struct wpa_ctrl * ctrl,int argc,char * argv[])2919 static int wpa_cli_cmd_mscs(struct wpa_ctrl *ctrl, int argc, char *argv[])
2920 {
2921 	return wpa_cli_cmd(ctrl, "MSCS", 1, argc, argv);
2922 }
2923 
2924 
wpa_cli_cmd_scs(struct wpa_ctrl * ctrl,int argc,char * argv[])2925 static int wpa_cli_cmd_scs(struct wpa_ctrl *ctrl, int argc, char *argv[])
2926 {
2927 	return wpa_cli_cmd(ctrl, "SCS", 2, argc, argv);
2928 }
2929 
2930 
wpa_cli_cmd_dscp_resp(struct wpa_ctrl * ctrl,int argc,char * argv[])2931 static int wpa_cli_cmd_dscp_resp(struct wpa_ctrl *ctrl, int argc, char *argv[])
2932 {
2933 	return wpa_cli_cmd(ctrl, "DSCP_RESP", 1, argc, argv);
2934 }
2935 
2936 
wpa_cli_cmd_dscp_query(struct wpa_ctrl * ctrl,int argc,char * argv[])2937 static int wpa_cli_cmd_dscp_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
2938 {
2939 	return wpa_cli_cmd(ctrl, "DSCP_QUERY", 1, argc, argv);
2940 }
2941 
2942 #endif /* !__ZEPHYR__ || (__ZEPHYR__ && CONFIG_WPA_CLI)*/
2943 
2944 
2945 enum wpa_cli_cmd_flags {
2946 	cli_cmd_flag_none		= 0x00,
2947 	cli_cmd_flag_sensitive		= 0x01
2948 };
2949 
2950 struct wpa_cli_cmd {
2951 	const char *cmd;
2952 	int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
2953 	char ** (*completion)(const char *str, int pos);
2954 	enum wpa_cli_cmd_flags flags;
2955 	const char *usage;
2956 };
2957 
2958 static const struct wpa_cli_cmd wpa_cli_commands[] = {
2959 	{ "status", wpa_cli_cmd_status, NULL,
2960 	  cli_cmd_flag_none,
2961 	  "[verbose] = get current WPA/EAPOL/EAP status" },
2962 	{ "set_network", wpa_cli_cmd_set_network, wpa_cli_complete_network,
2963 	  cli_cmd_flag_sensitive,
2964 	  "<network id> <variable> <value> = set network variables (shows\n"
2965 	  "  list of variables when run without arguments)" },
2966 	{ "get_network", wpa_cli_cmd_get_network, wpa_cli_complete_network,
2967 	  cli_cmd_flag_none,
2968 	  "<network id> <variable> = get network variables" },
2969 	{ "list_networks", wpa_cli_cmd_list_networks, NULL,
2970 	  cli_cmd_flag_none,
2971 	  "= list configured networks" },
2972 	{ "select_network", wpa_cli_cmd_select_network,
2973 	  wpa_cli_complete_network_id,
2974 	  cli_cmd_flag_none,
2975 	  "<network id> = select a network (disable others)" },
2976 	{ "enable_network", wpa_cli_cmd_enable_network,
2977 	  wpa_cli_complete_network_id,
2978 	  cli_cmd_flag_none,
2979 	  "<network id> = enable a network" },
2980 	{ "disable_network", wpa_cli_cmd_disable_network,
2981 	  wpa_cli_complete_network_id,
2982 	  cli_cmd_flag_none,
2983 	  "<network id> = disable a network" },
2984 	{ "add_network", wpa_cli_cmd_add_network, NULL,
2985 	  cli_cmd_flag_none,
2986 	  "= add a network" },
2987 	{ "remove_network", wpa_cli_cmd_remove_network,
2988 	  wpa_cli_complete_network_id,
2989 	  cli_cmd_flag_none,
2990 	  "<network id> = remove a network" },
2991 	{ "disconnect", wpa_cli_cmd_disconnect, NULL,
2992 	  cli_cmd_flag_none,
2993 	  "= disconnect and wait for reassociate/reconnect command before\n"
2994 	  "  connecting" },
2995 	{ "interface_add", wpa_cli_cmd_interface_add, NULL,
2996 	  cli_cmd_flag_none,
2997 	  "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
2998 	  "  <bridge_name> <create> <type> = adds new interface, all "
2999 	  "parameters but\n"
3000 	  "  <ifname> are optional. Supported types are station ('sta') and "
3001 	  "AP ('ap')" },
3002 	{ "interface_remove", wpa_cli_cmd_interface_remove, NULL,
3003 	  cli_cmd_flag_none,
3004 	  "<ifname> = removes the interface" },
3005 	{ "interface_list", wpa_cli_cmd_interface_list, NULL,
3006 	  cli_cmd_flag_none,
3007 	  "= list available interfaces" },
3008 	{ "set", wpa_cli_cmd_set, wpa_cli_complete_set,
3009 	  cli_cmd_flag_none,
3010 	  "= set variables (shows list of variables when run without "
3011 	  "arguments)" },
3012 #ifdef CONFIG_AP
3013 	{ "sta", wpa_cli_cmd_sta, wpa_cli_complete_sta,
3014 	  cli_cmd_flag_none,
3015 	  "<addr> = get information about an associated station (AP)" },
3016 	{ "all_sta", wpa_cli_cmd_all_sta, NULL,
3017 	  cli_cmd_flag_none,
3018 	  "= get information about all associated stations (AP)" },
3019 	{ "list_sta", wpa_cli_cmd_list_sta, NULL,
3020 	  cli_cmd_flag_none,
3021 	  "= list all stations (AP)" },
3022 	{ "deauthenticate", wpa_cli_cmd_deauthenticate,
3023 	  wpa_cli_complete_deauthenticate, cli_cmd_flag_none,
3024 	  "<addr> = deauthenticate a station" },
3025 	{ "disassociate", wpa_cli_cmd_disassociate,
3026 	  wpa_cli_complete_disassociate, cli_cmd_flag_none,
3027 	  "<addr> = disassociate a station" },
3028 	{ "chan_switch", wpa_cli_cmd_chanswitch, NULL,
3029 	  cli_cmd_flag_none,
3030 	  "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]"
3031 	  " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]"
3032 	  " = CSA parameters" },
3033 	{ "update_beacon", wpa_cli_cmd_update_beacon, NULL,
3034 	  cli_cmd_flag_none,
3035 	  "= update Beacon frame contents"},
3036 #endif /* CONFIG_AP */
3037 #if !defined(__ZEPHYR__) || (defined(__ZEPHYR__) && defined(CONFIG_WPA_CLI))
3038 	{ "ifname", wpa_cli_cmd_ifname, NULL,
3039 	  cli_cmd_flag_none,
3040 	  "= get current interface name" },
3041 	{ "ping", wpa_cli_cmd_ping, NULL,
3042 	  cli_cmd_flag_none,
3043 	  "= pings wpa_supplicant" },
3044 	{ "relog", wpa_cli_cmd_relog, NULL,
3045 	  cli_cmd_flag_none,
3046 	  "= re-open log-file (allow rolling logs)" },
3047 	{ "note", wpa_cli_cmd_note, NULL,
3048 	  cli_cmd_flag_none,
3049 	  "<text> = add a note to wpa_supplicant debug log" },
3050 	{ "mib", wpa_cli_cmd_mib, NULL,
3051 	  cli_cmd_flag_none,
3052 	  "= get MIB variables (dot1x, dot11)" },
3053 	{ "dump", wpa_cli_cmd_dump, NULL,
3054 	  cli_cmd_flag_none,
3055 	  "= dump config variables" },
3056 	{ "get", wpa_cli_cmd_get, wpa_cli_complete_get,
3057 	  cli_cmd_flag_none,
3058 	  "<name> = get information" },
3059 	{ "driver_flags", wpa_cli_cmd_driver_flags, NULL,
3060 	  cli_cmd_flag_none,
3061 	  "= list driver flags" },
3062 	{ "logon", wpa_cli_cmd_logon, NULL,
3063 	  cli_cmd_flag_none,
3064 	  "= IEEE 802.1X EAPOL state machine logon" },
3065 	{ "logoff", wpa_cli_cmd_logoff, NULL,
3066 	  cli_cmd_flag_none,
3067 	  "= IEEE 802.1X EAPOL state machine logoff" },
3068 	{ "pmksa", wpa_cli_cmd_pmksa, NULL,
3069 	  cli_cmd_flag_none,
3070 	  "= show PMKSA cache" },
3071 	{ "pmksa_flush", wpa_cli_cmd_pmksa_flush, NULL,
3072 	  cli_cmd_flag_none,
3073 	  "= flush PMKSA cache entries" },
3074 #ifdef CONFIG_PMKSA_CACHE_EXTERNAL
3075 	{ "pmksa_get", wpa_cli_cmd_pmksa_get, NULL,
3076 	  cli_cmd_flag_none,
3077 	  "<network_id> = fetch all stored PMKSA cache entries" },
3078 	{ "pmksa_add", wpa_cli_cmd_pmksa_add, NULL,
3079 	  cli_cmd_flag_sensitive,
3080 	  "<network_id> <BSSID> <PMKID> <PMK> <reauth_time in seconds> <expiration in seconds> <akmp> <opportunistic> = store PMKSA cache entry from external storage" },
3081 #ifdef CONFIG_MESH
3082 	{ "mesh_pmksa_get", wpa_cli_mesh_cmd_pmksa_get, NULL,
3083 	  cli_cmd_flag_none,
3084 	  "<peer MAC address | any> = fetch all stored mesh PMKSA cache entries" },
3085 	{ "mesh_pmksa_add", wpa_cli_mesh_cmd_pmksa_add, NULL,
3086 	  cli_cmd_flag_sensitive,
3087 	  "<BSSID> <PMKID> <PMK> <expiration in seconds> = store mesh PMKSA cache entry from external storage" },
3088 #endif /* CONFIG_MESH */
3089 #endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
3090 	{ "reassociate", wpa_cli_cmd_reassociate, NULL,
3091 	  cli_cmd_flag_none,
3092 	  "= force reassociation" },
3093 	{ "reattach", wpa_cli_cmd_reattach, NULL,
3094 	  cli_cmd_flag_none,
3095 	  "= force reassociation back to the same BSS" },
3096 	{ "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
3097 	  cli_cmd_flag_none,
3098 	  "<BSSID> = force preauthentication" },
3099 	{ "identity", wpa_cli_cmd_identity, wpa_cli_complete_network_id,
3100 	  cli_cmd_flag_none,
3101 	  "<network id> <identity> = configure identity for an SSID" },
3102 	{ "password", wpa_cli_cmd_password, wpa_cli_complete_network_id,
3103 	  cli_cmd_flag_sensitive,
3104 	  "<network id> <password> = configure password for an SSID" },
3105 	{ "new_password", wpa_cli_cmd_new_password,
3106 	  wpa_cli_complete_network_id, cli_cmd_flag_sensitive,
3107 	  "<network id> <password> = change password for an SSID" },
3108 	{ "pin", wpa_cli_cmd_pin, wpa_cli_complete_network_id,
3109 	  cli_cmd_flag_sensitive,
3110 	  "<network id> <pin> = configure pin for an SSID" },
3111 	{ "otp", wpa_cli_cmd_otp, wpa_cli_complete_network_id,
3112 	  cli_cmd_flag_sensitive,
3113 	  "<network id> <password> = configure one-time-password for an SSID"
3114 	},
3115 	{ "psk_passphrase", wpa_cli_cmd_psk_passphrase,
3116 	  wpa_cli_complete_network_id, cli_cmd_flag_sensitive,
3117 	  "<network id> <PSK/passphrase> = configure PSK/passphrase for an SSID" },
3118 	{ "passphrase", wpa_cli_cmd_passphrase, wpa_cli_complete_network_id,
3119 	  cli_cmd_flag_sensitive,
3120 	  "<network id> <passphrase> = configure private key passphrase\n"
3121 	  "  for an SSID" },
3122 	{ "sim", wpa_cli_cmd_sim, wpa_cli_complete_network_id,
3123 	  cli_cmd_flag_sensitive,
3124 	  "<network id> <pin> = report SIM operation result" },
3125 	{ "bssid", wpa_cli_cmd_bssid, wpa_cli_complete_network_id,
3126 	  cli_cmd_flag_none,
3127 	  "<network id> <BSSID> = set preferred BSSID for an SSID" },
3128 	{ "bssid_ignore", wpa_cli_cmd_bssid_ignore, wpa_cli_complete_bss,
3129 	  cli_cmd_flag_none,
3130 	  "<BSSID> = add a BSSID to the list of temporarily ignored BSSs\n"
3131 	  "bssid_ignore clear = clear the list of temporarily ignored BSSIDs\n"
3132 	  "bssid_ignore = display the list of temporarily ignored BSSIDs" },
3133 	{ "blacklist", /* deprecated alias for bssid_ignore */
3134 	  wpa_cli_cmd_bssid_ignore, wpa_cli_complete_bss,
3135 	  cli_cmd_flag_none,
3136 	  "= deprecated alias for bssid_ignore" },
3137 	{ "log_level", wpa_cli_cmd_log_level, NULL,
3138 	  cli_cmd_flag_none,
3139 	  "<level> [<timestamp>] = update the log level/timestamp\n"
3140 	  "log_level = display the current log level and log options" },
3141 	{ "dup_network", wpa_cli_cmd_dup_network, wpa_cli_complete_dup_network,
3142 	  cli_cmd_flag_none,
3143 	  "<src network id> <dst network id> <variable> = duplicate network variables"
3144 	},
3145 	{ "list_creds", wpa_cli_cmd_list_creds, NULL,
3146 	  cli_cmd_flag_none,
3147 	  "= list configured credentials" },
3148 	{ "add_cred", wpa_cli_cmd_add_cred, NULL,
3149 	  cli_cmd_flag_none,
3150 	  "= add a credential" },
3151 	{ "remove_cred", wpa_cli_cmd_remove_cred, NULL,
3152 	  cli_cmd_flag_none,
3153 	  "<cred id> = remove a credential" },
3154 	{ "set_cred", wpa_cli_cmd_set_cred, wpa_cli_complete_cred,
3155 	  cli_cmd_flag_sensitive,
3156 	  "<cred id> <variable> <value> = set credential variables" },
3157 	{ "get_cred", wpa_cli_cmd_get_cred, wpa_cli_complete_cred,
3158 	  cli_cmd_flag_none,
3159 	  "<cred id> <variable> = get credential variables" },
3160 	{ "save_config", wpa_cli_cmd_save_config, NULL,
3161 	  cli_cmd_flag_none,
3162 	  "= save the current configuration" },
3163 	{ "reconnect", wpa_cli_cmd_reconnect, NULL,
3164 	  cli_cmd_flag_none,
3165 	  "= like reassociate, but only takes effect if already disconnected"
3166 	},
3167 	{ "scan", wpa_cli_cmd_scan, NULL,
3168 	  cli_cmd_flag_none,
3169 	  "= request new BSS scan" },
3170 	{ "scan_results", wpa_cli_cmd_scan_results, NULL,
3171 	  cli_cmd_flag_none,
3172 	  "= get latest scan results" },
3173 	{ "abort_scan", wpa_cli_cmd_abort_scan, NULL,
3174 	  cli_cmd_flag_none,
3175 	  "= request ongoing scan to be aborted" },
3176 	{ "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
3177 	  cli_cmd_flag_none,
3178 	  "<<idx> | <bssid>> = get detailed scan result info" },
3179 	{ "get_capability", wpa_cli_cmd_get_capability,
3180 	  wpa_cli_complete_get_capability, cli_cmd_flag_none,
3181 	  "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
3182 	  "= get capabilities" },
3183 	{ "reconfigure", wpa_cli_cmd_reconfigure, NULL,
3184 	  cli_cmd_flag_none,
3185 	  "= force wpa_supplicant to re-read its configuration file" },
3186 	{ "terminate", wpa_cli_cmd_terminate, NULL,
3187 	  cli_cmd_flag_none,
3188 	  "= terminate wpa_supplicant" },
3189 	{ "ap_scan", wpa_cli_cmd_ap_scan, NULL,
3190 	  cli_cmd_flag_none,
3191 	  "<value> = set ap_scan parameter" },
3192 	{ "scan_interval", wpa_cli_cmd_scan_interval, NULL,
3193 	  cli_cmd_flag_none,
3194 	  "<value> = set scan_interval parameter (in seconds)" },
3195 	{ "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
3196 	  cli_cmd_flag_none,
3197 	  "<value> = set BSS expiration age parameter" },
3198 	{ "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
3199 	  cli_cmd_flag_none,
3200 	  "<value> = set BSS expiration scan count parameter" },
3201 	{ "bss_flush", wpa_cli_cmd_bss_flush, NULL,
3202 	  cli_cmd_flag_none,
3203 	  "<value> = set BSS flush age (0 by default)" },
3204 	{ "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
3205 	  cli_cmd_flag_none,
3206 	  "<addr> = request over-the-DS FT with <addr>" },
3207 	{ "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
3208 	  cli_cmd_flag_none,
3209 	  "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
3210 	{ "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
3211 	  cli_cmd_flag_sensitive,
3212 	  "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
3213 	  "hardcoded)" },
3214 	{ "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
3215 	  cli_cmd_flag_sensitive,
3216 	  "<PIN> = verify PIN checksum" },
3217 	{ "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
3218 	  "Cancels the pending WPS operation" },
3219 #ifdef CONFIG_WPS_NFC
3220 	{ "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
3221 	  cli_cmd_flag_none,
3222 	  "[BSSID] = start Wi-Fi Protected Setup: NFC" },
3223 	{ "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
3224 	  cli_cmd_flag_none,
3225 	  "<WPS|NDEF> = build configuration token" },
3226 	{ "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
3227 	  cli_cmd_flag_none,
3228 	  "<WPS|NDEF> = create password token" },
3229 	{ "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
3230 	  cli_cmd_flag_sensitive,
3231 	  "<hexdump of payload> = report read NFC tag with WPS data" },
3232 	{ "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
3233 	  cli_cmd_flag_none,
3234 	  "<NDEF> <WPS> = create NFC handover request" },
3235 	{ "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
3236 	  cli_cmd_flag_none,
3237 	  "<NDEF> <WPS> = create NFC handover select" },
3238 	{ "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
3239 	  cli_cmd_flag_none,
3240 	  "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
3241 	  "NFC handover" },
3242 #endif /* CONFIG_WPS_NFC */
3243 	{ "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
3244 	  cli_cmd_flag_sensitive,
3245 	  "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
3246 	{ "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
3247 	  cli_cmd_flag_sensitive,
3248 	  "[params..] = enable/disable AP PIN" },
3249 	{ "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
3250 	  cli_cmd_flag_none,
3251 	  "[IP address] = start Wi-Fi Protected Setup External Registrar" },
3252 	{ "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
3253 	  cli_cmd_flag_none,
3254 	  "= stop Wi-Fi Protected Setup External Registrar" },
3255 	{ "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
3256 	  cli_cmd_flag_sensitive,
3257 	  "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
3258 	{ "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
3259 	  cli_cmd_flag_none,
3260 	  "<UUID> = accept an Enrollee PBC using External Registrar" },
3261 	{ "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
3262 	  cli_cmd_flag_sensitive,
3263 	  "<UUID> <PIN> = learn AP configuration" },
3264 	{ "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
3265 	  cli_cmd_flag_none,
3266 	  "<UUID> <network id> = set AP configuration for enrolling" },
3267 	{ "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
3268 	  cli_cmd_flag_sensitive,
3269 	  "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
3270 #ifdef CONFIG_WPS_NFC
3271 	{ "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
3272 	  cli_cmd_flag_none,
3273 	  "<WPS/NDEF> <UUID> = build NFC configuration token" },
3274 #endif /* CONFIG_WPS_NFC */
3275 	{ "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
3276 	  cli_cmd_flag_none,
3277 	  "<addr> = request RSN authentication with <addr> in IBSS" },
3278 	{ "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
3279 	  "= notification of suspend/hibernate" },
3280 	{ "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
3281 	  "= notification of resume/thaw" },
3282 #ifdef CONFIG_TESTING_OPTIONS
3283 	{ "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
3284 	  "= drop SA without deauth/disassoc (test command)" },
3285 #endif /* CONFIG_TESTING_OPTIONS */
3286 	{ "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
3287 	  cli_cmd_flag_none,
3288 	  "<addr> = roam to the specified BSS" },
3289 #ifdef CONFIG_MESH
3290 	{ "mesh_interface_add", wpa_cli_cmd_mesh_interface_add, NULL,
3291 	  cli_cmd_flag_none,
3292 	  "[ifname] = Create a new mesh interface" },
3293 	{ "mesh_group_add", wpa_cli_cmd_mesh_group_add, NULL,
3294 	  cli_cmd_flag_none,
3295 	  "<network id> = join a mesh network (disable others)" },
3296 	{ "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL,
3297 	  cli_cmd_flag_none,
3298 	  "<ifname> = Remove mesh group interface" },
3299 	{ "mesh_peer_remove", wpa_cli_cmd_mesh_peer_remove, NULL,
3300 	  cli_cmd_flag_none,
3301 	  "<addr> = Remove a mesh peer" },
3302 	{ "mesh_peer_add", wpa_cli_cmd_mesh_peer_add, NULL,
3303 	  cli_cmd_flag_none,
3304 	  "<addr> [duration=<seconds>] = Add a mesh peer" },
3305 	{ "mesh_link_probe", wpa_cli_cmd_mesh_link_probe, NULL,
3306 	  cli_cmd_flag_none,
3307 	  "<addr> [payload=<hex dump of payload>] = Probe a mesh link for a given peer by injecting a frame." },
3308 #endif /* CONFIG_MESH */
3309 #ifdef CONFIG_P2P
3310 	{ "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
3311 	  cli_cmd_flag_none,
3312 	  "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
3313 	{ "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
3314 	  "= stop P2P Devices search" },
3315 	{ "p2p_asp_provision", wpa_cli_cmd_p2p_asp_provision, NULL,
3316 	  cli_cmd_flag_none,
3317 	  "<addr> adv_id=<adv_id> conncap=<conncap> [info=<infodata>] = provision with a P2P ASP Device" },
3318 	{ "p2p_asp_provision_resp", wpa_cli_cmd_p2p_asp_provision_resp, NULL,
3319 	  cli_cmd_flag_none,
3320 	  "<addr> adv_id=<adv_id> [role<conncap>] [info=<infodata>] = provision with a P2P ASP Device" },
3321 	{ "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
3322 	  cli_cmd_flag_none,
3323 	  "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
3324 	{ "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
3325 	  "[timeout] = listen for P2P Devices for up-to timeout seconds" },
3326 	{ "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
3327 	  wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
3328 	  "<ifname> = remove P2P group interface (terminate group if GO)" },
3329 	{ "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
3330 	  "[ht40] = add a new P2P group (local end as GO)" },
3331 	{ "p2p_group_member", wpa_cli_cmd_p2p_group_member, NULL,
3332 	  cli_cmd_flag_none,
3333 	  "<dev_addr> = Get peer interface address on local GO using peer Device Address" },
3334 	{ "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
3335 	  wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3336 	  "<addr> <method> = request provisioning discovery" },
3337 	{ "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
3338 	  cli_cmd_flag_none,
3339 	  "= get the passphrase for a group (GO only)" },
3340 	{ "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
3341 	  wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3342 	  "<addr> <TLVs> = schedule service discovery request" },
3343 	{ "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
3344 	  NULL, cli_cmd_flag_none,
3345 	  "<id> = cancel pending service discovery request" },
3346 	{ "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
3347 	  cli_cmd_flag_none,
3348 	  "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
3349 	{ "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
3350 	  cli_cmd_flag_none,
3351 	  "= indicate change in local services" },
3352 	{ "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
3353 	  cli_cmd_flag_none,
3354 	  "<external> = set external processing of service discovery" },
3355 	{ "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
3356 	  cli_cmd_flag_none,
3357 	  "= remove all stored service entries" },
3358 	{ "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
3359 	  cli_cmd_flag_none,
3360 	  "<bonjour|upnp|asp> <query|version> <response|service> = add a local "
3361 	  "service" },
3362 	{ "p2p_service_rep", wpa_cli_cmd_p2p_service_rep, NULL,
3363 	  cli_cmd_flag_none,
3364 	  "asp <auto> <adv_id> <svc_state> <svc_string> [<svc_info>] = replace "
3365 	  "local ASP service" },
3366 	{ "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
3367 	  cli_cmd_flag_none,
3368 	  "<bonjour|upnp> <query|version> [|service] = remove a local "
3369 	  "service" },
3370 	{ "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
3371 	  cli_cmd_flag_none,
3372 	  "<addr> = reject connection attempts from a specific peer" },
3373 	{ "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
3374 	  cli_cmd_flag_none,
3375 	  "<cmd> [peer=addr] = invite peer" },
3376 	{ "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
3377 	  "[discovered] = list known (optionally, only fully discovered) P2P "
3378 	  "peers" },
3379 	{ "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
3380 	  cli_cmd_flag_none,
3381 	  "<address> = show information about known P2P peer" },
3382 	{ "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set,
3383 	  cli_cmd_flag_none,
3384 	  "<field> <value> = set a P2P parameter" },
3385 	{ "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
3386 	  "= flush P2P state" },
3387 	{ "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
3388 	  "= cancel P2P group formation" },
3389 	{ "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
3390 	  wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3391 	  "<address> = unauthorize a peer" },
3392 	{ "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
3393 	  cli_cmd_flag_none,
3394 	  "[<duration> <interval>] [<duration> <interval>] = request GO "
3395 	  "presence" },
3396 	{ "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
3397 	  cli_cmd_flag_none,
3398 	  "[<period> <interval>] = set extended listen timing" },
3399 	{ "p2p_remove_client", wpa_cli_cmd_p2p_remove_client,
3400 	  wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
3401 	  "<address|iface=address> = remove a peer from all groups" },
3402 #endif /* CONFIG_P2P */
3403 	{ "vendor_elem_add", wpa_cli_cmd_vendor_elem_add, NULL,
3404 	  cli_cmd_flag_none,
3405 	  "<frame id> <hexdump of elem(s)> = add vendor specific IEs to frame(s)\n"
3406 	  VENDOR_ELEM_FRAME_ID },
3407 	{ "vendor_elem_get", wpa_cli_cmd_vendor_elem_get, NULL,
3408 	  cli_cmd_flag_none,
3409 	  "<frame id> = get vendor specific IE(s) to frame(s)\n"
3410 	  VENDOR_ELEM_FRAME_ID },
3411 	{ "vendor_elem_remove", wpa_cli_cmd_vendor_elem_remove, NULL,
3412 	  cli_cmd_flag_none,
3413 	  "<frame id> <hexdump of elem(s)> = remove vendor specific IE(s) in frame(s)\n"
3414 	  VENDOR_ELEM_FRAME_ID },
3415 #ifdef CONFIG_WIFI_DISPLAY
3416 	{ "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
3417 	  cli_cmd_flag_none,
3418 	  "<subelem> [contents] = set Wi-Fi Display subelement" },
3419 	{ "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
3420 	  cli_cmd_flag_none,
3421 	  "<subelem> = get Wi-Fi Display subelement" },
3422 #endif /* CONFIG_WIFI_DISPLAY */
3423 #ifdef CONFIG_INTERWORKING
3424 	{ "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
3425 	  "= fetch ANQP information for all APs" },
3426 	{ "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
3427 	  cli_cmd_flag_none,
3428 	  "= stop fetch_anqp operation" },
3429 	{ "interworking_select", wpa_cli_cmd_interworking_select, NULL,
3430 	  cli_cmd_flag_none,
3431 	  "[auto] = perform Interworking network selection" },
3432 	{ "interworking_connect", wpa_cli_cmd_interworking_connect,
3433 	  wpa_cli_complete_bss, cli_cmd_flag_none,
3434 	  "<BSSID> = connect using Interworking credentials" },
3435 	{ "interworking_add_network", wpa_cli_cmd_interworking_add_network,
3436 	  wpa_cli_complete_bss, cli_cmd_flag_none,
3437 	  "<BSSID> = connect using Interworking credentials" },
3438 	{ "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
3439 	  cli_cmd_flag_none,
3440 	  "<addr> <info id>[,<info id>]... = request ANQP information" },
3441 	{ "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
3442 	  cli_cmd_flag_none,
3443 	  "<addr> <AdvProtoID> [QueryReq] = GAS request" },
3444 	{ "gas_response_get", wpa_cli_cmd_gas_response_get,
3445 	  wpa_cli_complete_bss, cli_cmd_flag_none,
3446 	  "<addr> <dialog token> [start,len] = Fetch last GAS response" },
3447 #endif /* CONFIG_INTERWORKING */
3448 #ifdef CONFIG_HS20
3449 	{ "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
3450 	  cli_cmd_flag_none,
3451 	  "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
3452 	},
3453 	{ "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
3454 	  wpa_cli_complete_bss, cli_cmd_flag_none,
3455 	  "<addr> <home realm> = get HS20 nai home realm list" },
3456 	{ "hs20_icon_request", wpa_cli_cmd_hs20_icon_request,
3457 	  wpa_cli_complete_bss, cli_cmd_flag_none,
3458 	  "<addr> <icon name> = get Hotspot 2.0 OSU icon" },
3459 	{ "fetch_osu", wpa_cli_cmd_fetch_osu, NULL, cli_cmd_flag_none,
3460 	  "= fetch OSU provider information from all APs" },
3461 	{ "cancel_fetch_osu", wpa_cli_cmd_cancel_fetch_osu, NULL,
3462 	  cli_cmd_flag_none,
3463 	  "= cancel fetch_osu command" },
3464 #endif /* CONFIG_HS20 */
3465 	{ "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
3466 	  cli_cmd_flag_none,
3467 	  "<0/1> = disable/enable automatic reconnection" },
3468 	{ "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
3469 	  cli_cmd_flag_none,
3470 	  "<addr> = request TDLS discovery with <addr>" },
3471 	{ "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
3472 	  cli_cmd_flag_none,
3473 	  "<addr> = request TDLS setup with <addr>" },
3474 	{ "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
3475 	  cli_cmd_flag_none,
3476 	  "<addr> = tear down TDLS with <addr>" },
3477 	{ "tdls_link_status", wpa_cli_cmd_tdls_link_status, NULL,
3478 	  cli_cmd_flag_none,
3479 	  "<addr> = TDLS link status with <addr>" },
3480 #ifndef CONFIG_NO_WMM_AC
3481 	{ "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL,
3482 	  cli_cmd_flag_none,
3483 	  "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] "
3484 	  "[mean_data_rate=#] [min_phy_rate=#] [sba=#] [fixed_nominal_msdu] "
3485 	  "= add WMM-AC traffic stream" },
3486 	{ "wmm_ac_delts", wpa_cli_cmd_wmm_ac_delts, NULL,
3487 	  cli_cmd_flag_none,
3488 	  "<tsid> = delete WMM-AC traffic stream" },
3489 	{ "wmm_ac_status", wpa_cli_cmd_wmm_ac_status, NULL,
3490 	  cli_cmd_flag_none,
3491 	  "= show status for Wireless Multi-Media Admission-Control" },
3492 #endif /* !CONFIG_NO_WMM_AC */
3493 	{ "tdls_chan_switch", wpa_cli_cmd_tdls_chan_switch, NULL,
3494 	  cli_cmd_flag_none,
3495 	  "<addr> <oper class> <freq> [sec_channel_offset=] [center_freq1=] "
3496 	  "[center_freq2=] [bandwidth=] [ht|vht] = enable channel switching "
3497 	  "with TDLS peer" },
3498 	{ "tdls_cancel_chan_switch", wpa_cli_cmd_tdls_cancel_chan_switch, NULL,
3499 	  cli_cmd_flag_none,
3500 	  "<addr> = disable channel switching with TDLS peer <addr>" },
3501 	{ "signal_poll", wpa_cli_cmd_signal_poll, NULL,
3502 	  cli_cmd_flag_none,
3503 	  "= get signal parameters" },
3504 	{ "signal_monitor", wpa_cli_cmd_signal_monitor, NULL,
3505 	  cli_cmd_flag_none,
3506 	  "= set signal monitor parameters" },
3507 	{ "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
3508 	  cli_cmd_flag_none,
3509 	  "= get TX/RX packet counters" },
3510 	{ "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
3511 	  cli_cmd_flag_none,
3512 	  "= trigger IEEE 802.1X/EAPOL reauthentication" },
3513 #ifdef CONFIG_AUTOSCAN
3514 	{ "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
3515 	  "[params] = Set or unset (if none) autoscan parameters" },
3516 #endif /* CONFIG_AUTOSCAN */
3517 #ifdef CONFIG_WNM
3518 	{ "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
3519 	  "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
3520 	{ "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
3521 	  "<query reason> [list]"
3522 	  " [neighbor=<BSSID>,<BSSID information>,<operating class>,<channel number>,<PHY type>[,<hexdump of optional subelements>]"
3523 	  " = Send BSS Transition Management Query" },
3524 #endif /* CONFIG_WNM */
3525 	{ "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
3526 	  "<params..> = Sent unprocessed command" },
3527 	{ "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
3528 	  "= flush wpa_supplicant state" },
3529 	{ "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none,
3530 	  "= radio_work <show/add/done>" },
3531 	{ "vendor", wpa_cli_cmd_vendor, NULL, cli_cmd_flag_none,
3532 	  "<vendor id> <command id> [<hex formatted command argument>] = Send vendor command"
3533 	},
3534 	{ "neighbor_rep_request",
3535 	  wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none,
3536 	  "[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)"
3537 	},
3538 	{ "twt_setup",
3539 	  wpa_cli_cmd_twt_setup, NULL, cli_cmd_flag_none,
3540 	  "[dialog=<token>] [exponent=<exponent>] [mantissa=<mantissa>] [min_twt=<Min TWT>] [setup_cmd=<setup-cmd>] [twt=<u64>] [requestor=0|1] [trigger=0|1] [implicit=0|1] [flow_type=0|1] [flow_id=<3-bit-id>] [protection=0|1] [twt_channel=<twt chanel id>] [control=<control-u8>] = Send TWT Setup frame"
3541 	},
3542 	{ "twt_teardown",
3543 	  wpa_cli_cmd_twt_teardown, NULL, cli_cmd_flag_none,
3544 	  "[flags=<value>] = Send TWT Teardown frame"
3545 	},
3546 	{ "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none,
3547 	  "= flush ERP keys" },
3548 	{ "mac_rand_scan",
3549 	  wpa_cli_cmd_mac_rand_scan, NULL, cli_cmd_flag_none,
3550 	  "<scan|sched|pno|all> enable=<0/1> [addr=mac-address "
3551 	  "mask=mac-address-mask] = scan MAC randomization"
3552 	},
3553 	{ "get_pref_freq_list", wpa_cli_cmd_get_pref_freq_list, NULL,
3554 	  cli_cmd_flag_none,
3555 	  "<interface type> = retrieve preferred freq list for the specified interface type" },
3556 	{ "p2p_lo_start", wpa_cli_cmd_p2p_lo_start, NULL,
3557 	  cli_cmd_flag_none,
3558 	  "<freq> <period> <interval> <count> = start P2P listen offload" },
3559 	{ "p2p_lo_stop", wpa_cli_cmd_p2p_lo_stop, NULL,
3560 	  cli_cmd_flag_none,
3561 	  "= stop P2P listen offload" },
3562 #ifdef CONFIG_DPP
3563 	{ "dpp_qr_code", wpa_cli_cmd_dpp_qr_code, NULL, cli_cmd_flag_none,
3564 	  "report a scanned DPP URI from a QR Code" },
3565 	{ "dpp_bootstrap_gen", wpa_cli_cmd_dpp_bootstrap_gen, NULL,
3566 	  cli_cmd_flag_sensitive,
3567 	  "type=<qrcode> [chan=..] [mac=..] [info=..] [curve=..] [key=..] = generate DPP bootstrap information" },
3568 	{ "dpp_bootstrap_remove", wpa_cli_cmd_dpp_bootstrap_remove, NULL,
3569 	  cli_cmd_flag_none,
3570 	  "*|<id> = remove DPP bootstrap information" },
3571 	{ "dpp_bootstrap_get_uri", wpa_cli_cmd_dpp_bootstrap_get_uri, NULL,
3572 	  cli_cmd_flag_none,
3573 	  "<id> = get DPP bootstrap URI" },
3574 	{ "dpp_bootstrap_info", wpa_cli_cmd_dpp_bootstrap_info, NULL,
3575 	  cli_cmd_flag_none,
3576 	  "<id> = show DPP bootstrap information" },
3577 	{ "dpp_bootstrap_set", wpa_cli_cmd_dpp_bootstrap_set, NULL,
3578 	  cli_cmd_flag_none,
3579 	  "<id> [conf=..] [ssid=<SSID>] [ssid_charset=#] [psk=<PSK>] [pass=<passphrase>] [configurator=<id>] [conn_status=#] [akm_use_selector=<0|1>] [group_id=..] [expiry=#] [csrattrs=..] = set DPP configurator parameters" },
3580 	{ "dpp_auth_init", wpa_cli_cmd_dpp_auth_init, NULL, cli_cmd_flag_none,
3581 	  "peer=<id> [own=<id>] = initiate DPP bootstrapping" },
3582 	{ "dpp_listen", wpa_cli_cmd_dpp_listen, NULL, cli_cmd_flag_none,
3583 	  "<freq in MHz> = start DPP listen" },
3584 	{ "dpp_stop_listen", wpa_cli_cmd_dpp_stop_listen, NULL,
3585 	  cli_cmd_flag_none,
3586 	  "= stop DPP listen" },
3587 	{ "dpp_configurator_add", wpa_cli_cmd_dpp_configurator_add, NULL,
3588 	  cli_cmd_flag_sensitive,
3589 	  "[curve=..] [key=..] = add DPP configurator" },
3590 	{ "dpp_configurator_remove", wpa_cli_cmd_dpp_configurator_remove, NULL,
3591 	  cli_cmd_flag_none,
3592 	  "*|<id> = remove DPP configurator" },
3593 	{ "dpp_configurator_get_key", wpa_cli_cmd_dpp_configurator_get_key,
3594 	  NULL, cli_cmd_flag_none,
3595 	  "<id> = Get DPP configurator's private key" },
3596 	{ "dpp_configurator_sign", wpa_cli_cmd_dpp_configurator_sign, NULL,
3597 	  cli_cmd_flag_none,
3598 	  "conf=<role> configurator=<id> = generate self DPP configuration" },
3599 	{ "dpp_pkex_add", wpa_cli_cmd_dpp_pkex_add, NULL,
3600 	  cli_cmd_flag_sensitive,
3601 	  "add PKEX code" },
3602 	{ "dpp_pkex_remove", wpa_cli_cmd_dpp_pkex_remove, NULL,
3603 	  cli_cmd_flag_none,
3604 	  "*|<id> = remove DPP pkex information" },
3605 #ifdef CONFIG_DPP2
3606 	{ "dpp_controller_start", wpa_cli_cmd_dpp_controller_start, NULL,
3607 	  cli_cmd_flag_none,
3608 	  "[tcp_port=<port>] [role=..] = start DPP controller" },
3609 	{ "dpp_controller_stop", wpa_cli_cmd_dpp_controller_stop, NULL,
3610 	  cli_cmd_flag_none,
3611 	  "= stop DPP controller" },
3612 	{ "dpp_chirp", wpa_cli_cmd_dpp_chirp, NULL,
3613 	  cli_cmd_flag_none,
3614 	  "own=<BI ID> iter=<count> = start DPP chirp" },
3615 	{ "dpp_stop_chirp", wpa_cli_cmd_dpp_stop_chirp, NULL,
3616 	  cli_cmd_flag_none,
3617 	  "= stop DPP chirp" },
3618 #endif /* CONFIG_DPP2 */
3619 #endif /* CONFIG_DPP */
3620 	{ "all_bss", wpa_cli_cmd_all_bss, NULL, cli_cmd_flag_none,
3621 	  "= list all BSS entries (scan results)" },
3622 #ifdef CONFIG_PASN
3623 	{ "pasn_auth_start", wpa_cli_cmd_pasn_auth_start, NULL,
3624 	  cli_cmd_flag_none,
3625 	  "bssid=<BSSID> akmp=<WPA key mgmt> cipher=<WPA cipher> group=<group> nid=<network id> = Start PASN authentication" },
3626 	{ "pasn_auth_stop", wpa_cli_cmd_pasn_auth_stop, NULL,
3627 	  cli_cmd_flag_none,
3628 	  "= Stop PASN authentication" },
3629 	{ "ptksa_cache_list", wpa_cli_cmd_ptksa_cache_list, NULL,
3630 	  cli_cmd_flag_none,
3631 	  "= Get the PTKSA Cache" },
3632 	{ "pasn_deauth", wpa_cli_cmd_pasn_deauth, NULL,
3633 	  cli_cmd_flag_none,
3634 	  "bssid=<BSSID> = Remove PASN PTKSA state" },
3635 #endif /* CONFIG_PASN */
3636 	{ "mscs", wpa_cli_cmd_mscs, NULL,
3637 	  cli_cmd_flag_none,
3638 	  "<add|remove|change> [up_bitmap=<hex byte>] [up_limit=<integer>] [stream_timeout=<in TUs>] [frame_classifier=<hex bytes>] = Configure MSCS request" },
3639 	{ "scs", wpa_cli_cmd_scs, NULL,
3640 	  cli_cmd_flag_none,
3641 	  "[scs_id=<decimal number>] <add|remove|change> [scs_up=<0-7>] [classifier_type=<4|10>] [classifier params based on classifier type] [tclas_processing=<0|1>] [scs_id=<decimal number>] ... = Send SCS request" },
3642 	{ "dscp_resp", wpa_cli_cmd_dscp_resp, NULL,
3643 	  cli_cmd_flag_none,
3644 	  "<[reset]>/<[solicited] [policy_id=1 status=0...]> [more] = Send DSCP response" },
3645 	{ "dscp_query", wpa_cli_cmd_dscp_query, NULL,
3646 	  cli_cmd_flag_none,
3647 	  "wildcard/domain_name=<string> = Send DSCP Query" },
3648 #endif  /* !__ZEPHYR__ || (__ZEPHYR__ && CONFIG_WPA_CLI)*/
3649 	{ NULL, NULL, NULL, cli_cmd_flag_none, NULL }
3650 };
3651 
wpa_request(struct wpa_ctrl * ctrl,int argc,char * argv[])3652 int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
3653 {
3654 	const struct wpa_cli_cmd *cmd, *match = NULL;
3655 	int count;
3656 	int ret = 0;
3657 
3658 	if (argc > 1 && os_strncasecmp(argv[0], "IFNAME=", 7) == 0) {
3659 		ifname_prefix = argv[0] + 7;
3660 		argv = &argv[1];
3661 		argc--;
3662 	} else
3663 		ifname_prefix = NULL;
3664 
3665 	if (argc == 0)
3666 		return -1;
3667 
3668 	count = 0;
3669 	cmd = wpa_cli_commands;
3670 	while (cmd->cmd) {
3671 		if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
3672 		{
3673 			match = cmd;
3674 			if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
3675 				/* we have an exact match */
3676 				count = 1;
3677 				break;
3678 			}
3679 			count++;
3680 		}
3681 		cmd++;
3682 	}
3683 
3684 	if (count > 1) {
3685 		wpa_printf(MSG_INFO, "Ambiguous command '%s'; possible commands:", argv[0]);
3686 		cmd = wpa_cli_commands;
3687 		while (cmd->cmd) {
3688 			if (os_strncasecmp(cmd->cmd, argv[0],
3689 					   os_strlen(argv[0])) == 0) {
3690 				wpa_printf(MSG_INFO, " %s", cmd->cmd);
3691 			}
3692 			cmd++;
3693 		}
3694 		wpa_printf(MSG_INFO, "\n");
3695 		ret = 1;
3696 	} else if (count == 0) {
3697 		wpa_printf(MSG_INFO, "Unknown command '%s'\n", argv[0]);
3698 		ret = 1;
3699 	} else {
3700 		ret = match->handler(ctrl, argc - 1, &argv[1]);
3701 	}
3702 
3703 	return ret;
3704 }
3705