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