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