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