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