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