ctrl_iface.c revision 2fb777c379ad560c309c54b96c2c13291da23f54
1/* 2 * WPA Supplicant / Control interface (shared code for all backends) 3 * Copyright (c) 2004-2010, 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 "utils/includes.h" 10 11#include "utils/common.h" 12#include "utils/eloop.h" 13#include "common/version.h" 14#include "common/ieee802_11_defs.h" 15#include "common/wpa_ctrl.h" 16#include "eap_peer/eap.h" 17#include "eapol_supp/eapol_supp_sm.h" 18#include "rsn_supp/wpa.h" 19#include "rsn_supp/preauth.h" 20#include "rsn_supp/pmksa_cache.h" 21#include "l2_packet/l2_packet.h" 22#include "wps/wps.h" 23#include "config.h" 24#include "wpa_supplicant_i.h" 25#include "driver_i.h" 26#include "wps_supplicant.h" 27#include "ibss_rsn.h" 28#include "ap.h" 29#include "p2p_supplicant.h" 30#include "p2p/p2p.h" 31#include "notify.h" 32#include "bss.h" 33#include "scan.h" 34#include "ctrl_iface.h" 35#include "interworking.h" 36#include "blacklist.h" 37#include "wpas_glue.h" 38 39extern struct wpa_driver_ops *wpa_drivers[]; 40 41static int wpa_supplicant_global_iface_list(struct wpa_global *global, 42 char *buf, int len); 43static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global, 44 char *buf, int len); 45 46 47static int pno_start(struct wpa_supplicant *wpa_s) 48{ 49 int ret; 50 size_t i, num_ssid; 51 struct wpa_ssid *ssid; 52 struct wpa_driver_scan_params params; 53 54 if (wpa_s->pno) 55 return 0; 56 57 os_memset(¶ms, 0, sizeof(params)); 58 59 num_ssid = 0; 60 ssid = wpa_s->conf->ssid; 61 while (ssid) { 62 if (!ssid->disabled) 63 num_ssid++; 64 ssid = ssid->next; 65 } 66 if (num_ssid > WPAS_MAX_SCAN_SSIDS) { 67 wpa_printf(MSG_DEBUG, "PNO: Use only the first %u SSIDs from " 68 "%u", WPAS_MAX_SCAN_SSIDS, (unsigned int) num_ssid); 69 num_ssid = WPAS_MAX_SCAN_SSIDS; 70 } 71 72 if (num_ssid == 0) { 73 wpa_printf(MSG_DEBUG, "PNO: No configured SSIDs"); 74 return -1; 75 } 76 77 params.filter_ssids = os_malloc(sizeof(struct wpa_driver_scan_filter) * 78 num_ssid); 79 if (params.filter_ssids == NULL) 80 return -1; 81 i = 0; 82 ssid = wpa_s->conf->ssid; 83 while (ssid) { 84 if (!ssid->disabled) { 85 params.ssids[i].ssid = ssid->ssid; 86 params.ssids[i].ssid_len = ssid->ssid_len; 87 params.num_ssids++; 88 os_memcpy(params.filter_ssids[i].ssid, ssid->ssid, 89 ssid->ssid_len); 90 params.filter_ssids[i].ssid_len = ssid->ssid_len; 91 params.num_filter_ssids++; 92 i++; 93 if (i == num_ssid) 94 break; 95 } 96 ssid = ssid->next; 97 } 98 99 ret = wpa_drv_sched_scan(wpa_s, ¶ms, 10 * 1000); 100 os_free(params.filter_ssids); 101 if (ret == 0) 102 wpa_s->pno = 1; 103 return ret; 104} 105 106 107static int pno_stop(struct wpa_supplicant *wpa_s) 108{ 109 if (wpa_s->pno) { 110 wpa_s->pno = 0; 111 return wpa_drv_stop_sched_scan(wpa_s); 112 } 113 return 0; 114} 115 116 117static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s, 118 char *cmd) 119{ 120 char *value; 121 int ret = 0; 122 123 value = os_strchr(cmd, ' '); 124 if (value == NULL) 125 return -1; 126 *value++ = '\0'; 127 128 wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value); 129 if (os_strcasecmp(cmd, "EAPOL::heldPeriod") == 0) { 130 eapol_sm_configure(wpa_s->eapol, 131 atoi(value), -1, -1, -1); 132 } else if (os_strcasecmp(cmd, "EAPOL::authPeriod") == 0) { 133 eapol_sm_configure(wpa_s->eapol, 134 -1, atoi(value), -1, -1); 135 } else if (os_strcasecmp(cmd, "EAPOL::startPeriod") == 0) { 136 eapol_sm_configure(wpa_s->eapol, 137 -1, -1, atoi(value), -1); 138 } else if (os_strcasecmp(cmd, "EAPOL::maxStart") == 0) { 139 eapol_sm_configure(wpa_s->eapol, 140 -1, -1, -1, atoi(value)); 141 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) { 142 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME, 143 atoi(value))) 144 ret = -1; 145 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") == 146 0) { 147 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD, 148 atoi(value))) 149 ret = -1; 150 } else if (os_strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) { 151 if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value))) 152 ret = -1; 153 } else if (os_strcasecmp(cmd, "wps_fragment_size") == 0) { 154 wpa_s->wps_fragment_size = atoi(value); 155#ifdef CONFIG_WPS_TESTING 156 } else if (os_strcasecmp(cmd, "wps_version_number") == 0) { 157 long int val; 158 val = strtol(value, NULL, 0); 159 if (val < 0 || val > 0xff) { 160 ret = -1; 161 wpa_printf(MSG_DEBUG, "WPS: Invalid " 162 "wps_version_number %ld", val); 163 } else { 164 wps_version_number = val; 165 wpa_printf(MSG_DEBUG, "WPS: Testing - force WPS " 166 "version %u.%u", 167 (wps_version_number & 0xf0) >> 4, 168 wps_version_number & 0x0f); 169 } 170 } else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) { 171 wps_testing_dummy_cred = atoi(value); 172 wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d", 173 wps_testing_dummy_cred); 174#endif /* CONFIG_WPS_TESTING */ 175 } else if (os_strcasecmp(cmd, "ampdu") == 0) { 176 if (wpa_drv_ampdu(wpa_s, atoi(value)) < 0) 177 ret = -1; 178#ifdef CONFIG_TDLS_TESTING 179 } else if (os_strcasecmp(cmd, "tdls_testing") == 0) { 180 extern unsigned int tdls_testing; 181 tdls_testing = strtol(value, NULL, 0); 182 wpa_printf(MSG_DEBUG, "TDLS: tdls_testing=0x%x", tdls_testing); 183#endif /* CONFIG_TDLS_TESTING */ 184#ifdef CONFIG_TDLS 185 } else if (os_strcasecmp(cmd, "tdls_disabled") == 0) { 186 int disabled = atoi(value); 187 wpa_printf(MSG_DEBUG, "TDLS: tdls_disabled=%d", disabled); 188 if (disabled) { 189 if (wpa_drv_tdls_oper(wpa_s, TDLS_DISABLE, NULL) < 0) 190 ret = -1; 191 } else if (wpa_drv_tdls_oper(wpa_s, TDLS_ENABLE, NULL) < 0) 192 ret = -1; 193 wpa_tdls_enable(wpa_s->wpa, !disabled); 194#endif /* CONFIG_TDLS */ 195 } else if (os_strcasecmp(cmd, "pno") == 0) { 196 if (atoi(value)) 197 ret = pno_start(wpa_s); 198 else 199 ret = pno_stop(wpa_s); 200 } else if (os_strcasecmp(cmd, "ps") == 0) { 201 ret = wpa_drv_set_p2p_powersave(wpa_s, atoi(value), -1, -1); 202 } else { 203 value[-1] = '='; 204 ret = wpa_config_process_global(wpa_s->conf, cmd, -1); 205 if (ret == 0) 206 wpa_supplicant_update_config(wpa_s); 207 } 208 209 return ret; 210} 211 212 213static int wpa_supplicant_ctrl_iface_get(struct wpa_supplicant *wpa_s, 214 char *cmd, char *buf, size_t buflen) 215{ 216 int res = -1; 217 218 wpa_printf(MSG_DEBUG, "CTRL_IFACE GET '%s'", cmd); 219 220 if (os_strcmp(cmd, "version") == 0) { 221 res = os_snprintf(buf, buflen, "%s", VERSION_STR); 222 } else if (os_strcasecmp(cmd, "country") == 0) { 223 if (wpa_s->conf->country[0] && wpa_s->conf->country[1]) 224 res = os_snprintf(buf, buflen, "%c%c", 225 wpa_s->conf->country[0], 226 wpa_s->conf->country[1]); 227 } 228 229 if (res < 0 || (unsigned int) res >= buflen) 230 return -1; 231 return res; 232} 233 234 235#ifdef IEEE8021X_EAPOL 236static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s, 237 char *addr) 238{ 239 u8 bssid[ETH_ALEN]; 240 struct wpa_ssid *ssid = wpa_s->current_ssid; 241 242 if (hwaddr_aton(addr, bssid)) { 243 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address " 244 "'%s'", addr); 245 return -1; 246 } 247 248 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid)); 249 rsn_preauth_deinit(wpa_s->wpa); 250 if (rsn_preauth_init(wpa_s->wpa, bssid, ssid ? &ssid->eap : NULL)) 251 return -1; 252 253 return 0; 254} 255#endif /* IEEE8021X_EAPOL */ 256 257 258#ifdef CONFIG_PEERKEY 259/* MLME-STKSTART.request(peer) */ 260static int wpa_supplicant_ctrl_iface_stkstart( 261 struct wpa_supplicant *wpa_s, char *addr) 262{ 263 u8 peer[ETH_ALEN]; 264 265 if (hwaddr_aton(addr, peer)) { 266 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid " 267 "address '%s'", addr); 268 return -1; 269 } 270 271 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART " MACSTR, 272 MAC2STR(peer)); 273 274 return wpa_sm_stkstart(wpa_s->wpa, peer); 275} 276#endif /* CONFIG_PEERKEY */ 277 278 279#ifdef CONFIG_TDLS 280 281static int wpa_supplicant_ctrl_iface_tdls_discover( 282 struct wpa_supplicant *wpa_s, char *addr) 283{ 284 u8 peer[ETH_ALEN]; 285 int ret; 286 287 if (hwaddr_aton(addr, peer)) { 288 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER: invalid " 289 "address '%s'", addr); 290 return -1; 291 } 292 293 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER " MACSTR, 294 MAC2STR(peer)); 295 296 if (wpa_tdls_is_external_setup(wpa_s->wpa)) 297 ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer); 298 else 299 ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer); 300 301 return ret; 302} 303 304 305static int wpa_supplicant_ctrl_iface_tdls_setup( 306 struct wpa_supplicant *wpa_s, char *addr) 307{ 308 u8 peer[ETH_ALEN]; 309 int ret; 310 311 if (hwaddr_aton(addr, peer)) { 312 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP: invalid " 313 "address '%s'", addr); 314 return -1; 315 } 316 317 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP " MACSTR, 318 MAC2STR(peer)); 319 320 ret = wpa_tdls_reneg(wpa_s->wpa, peer); 321 if (ret) { 322 if (wpa_tdls_is_external_setup(wpa_s->wpa)) 323 ret = wpa_tdls_start(wpa_s->wpa, peer); 324 else 325 ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer); 326 } 327 328 return ret; 329} 330 331 332static int wpa_supplicant_ctrl_iface_tdls_teardown( 333 struct wpa_supplicant *wpa_s, char *addr) 334{ 335 u8 peer[ETH_ALEN]; 336 337 if (hwaddr_aton(addr, peer)) { 338 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN: invalid " 339 "address '%s'", addr); 340 return -1; 341 } 342 343 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN " MACSTR, 344 MAC2STR(peer)); 345 346 return wpa_tdls_teardown_link(wpa_s->wpa, peer, 347 WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED); 348} 349 350#endif /* CONFIG_TDLS */ 351 352 353#ifdef CONFIG_IEEE80211R 354static int wpa_supplicant_ctrl_iface_ft_ds( 355 struct wpa_supplicant *wpa_s, char *addr) 356{ 357 u8 target_ap[ETH_ALEN]; 358 struct wpa_bss *bss; 359 const u8 *mdie; 360 361 if (hwaddr_aton(addr, target_ap)) { 362 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS: invalid " 363 "address '%s'", addr); 364 return -1; 365 } 366 367 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS " MACSTR, MAC2STR(target_ap)); 368 369 bss = wpa_bss_get_bssid(wpa_s, target_ap); 370 if (bss) 371 mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN); 372 else 373 mdie = NULL; 374 375 return wpa_ft_start_over_ds(wpa_s->wpa, target_ap, mdie); 376} 377#endif /* CONFIG_IEEE80211R */ 378 379 380#ifdef CONFIG_WPS 381static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s, 382 char *cmd) 383{ 384 u8 bssid[ETH_ALEN], *_bssid = bssid; 385#ifdef CONFIG_P2P 386 u8 p2p_dev_addr[ETH_ALEN]; 387#endif /* CONFIG_P2P */ 388#ifdef CONFIG_AP 389 u8 *_p2p_dev_addr = NULL; 390#endif /* CONFIG_AP */ 391 392 if (cmd == NULL || os_strcmp(cmd, "any") == 0) { 393 _bssid = NULL; 394#ifdef CONFIG_P2P 395 } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) { 396 if (hwaddr_aton(cmd + 13, p2p_dev_addr)) { 397 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid " 398 "P2P Device Address '%s'", 399 cmd + 13); 400 return -1; 401 } 402 _p2p_dev_addr = p2p_dev_addr; 403#endif /* CONFIG_P2P */ 404 } else if (hwaddr_aton(cmd, bssid)) { 405 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'", 406 cmd); 407 return -1; 408 } 409 410#ifdef CONFIG_AP 411 if (wpa_s->ap_iface) 412 return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr); 413#endif /* CONFIG_AP */ 414 415 return wpas_wps_start_pbc(wpa_s, _bssid, 0); 416} 417 418 419static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s, 420 char *cmd, char *buf, 421 size_t buflen) 422{ 423 u8 bssid[ETH_ALEN], *_bssid = bssid; 424 char *pin; 425 int ret; 426 427 pin = os_strchr(cmd, ' '); 428 if (pin) 429 *pin++ = '\0'; 430 431 if (os_strcmp(cmd, "any") == 0) 432 _bssid = NULL; 433 else if (os_strcmp(cmd, "get") == 0) { 434 ret = wps_generate_pin(); 435 goto done; 436 } else if (hwaddr_aton(cmd, bssid)) { 437 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'", 438 cmd); 439 return -1; 440 } 441 442#ifdef CONFIG_AP 443 if (wpa_s->ap_iface) 444 return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin, 445 buf, buflen); 446#endif /* CONFIG_AP */ 447 448 if (pin) { 449 ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0, 450 DEV_PW_DEFAULT); 451 if (ret < 0) 452 return -1; 453 ret = os_snprintf(buf, buflen, "%s", pin); 454 if (ret < 0 || (size_t) ret >= buflen) 455 return -1; 456 return ret; 457 } 458 459 ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0, DEV_PW_DEFAULT); 460 if (ret < 0) 461 return -1; 462 463done: 464 /* Return the generated PIN */ 465 ret = os_snprintf(buf, buflen, "%08d", ret); 466 if (ret < 0 || (size_t) ret >= buflen) 467 return -1; 468 return ret; 469} 470 471 472static int wpa_supplicant_ctrl_iface_wps_check_pin( 473 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) 474{ 475 char pin[9]; 476 size_t len; 477 char *pos; 478 int ret; 479 480 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS_CHECK_PIN", 481 (u8 *) cmd, os_strlen(cmd)); 482 for (pos = cmd, len = 0; *pos != '\0'; pos++) { 483 if (*pos < '0' || *pos > '9') 484 continue; 485 pin[len++] = *pos; 486 if (len == 9) { 487 wpa_printf(MSG_DEBUG, "WPS: Too long PIN"); 488 return -1; 489 } 490 } 491 if (len != 4 && len != 8) { 492 wpa_printf(MSG_DEBUG, "WPS: Invalid PIN length %d", (int) len); 493 return -1; 494 } 495 pin[len] = '\0'; 496 497 if (len == 8) { 498 unsigned int pin_val; 499 pin_val = atoi(pin); 500 if (!wps_pin_valid(pin_val)) { 501 wpa_printf(MSG_DEBUG, "WPS: Invalid checksum digit"); 502 ret = os_snprintf(buf, buflen, "FAIL-CHECKSUM\n"); 503 if (ret < 0 || (size_t) ret >= buflen) 504 return -1; 505 return ret; 506 } 507 } 508 509 ret = os_snprintf(buf, buflen, "%s", pin); 510 if (ret < 0 || (size_t) ret >= buflen) 511 return -1; 512 513 return ret; 514} 515 516 517#ifdef CONFIG_WPS_OOB 518static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant *wpa_s, 519 char *cmd) 520{ 521 char *path, *method, *name; 522 523 path = os_strchr(cmd, ' '); 524 if (path == NULL) 525 return -1; 526 *path++ = '\0'; 527 528 method = os_strchr(path, ' '); 529 if (method == NULL) 530 return -1; 531 *method++ = '\0'; 532 533 name = os_strchr(method, ' '); 534 if (name != NULL) 535 *name++ = '\0'; 536 537 return wpas_wps_start_oob(wpa_s, cmd, path, method, name); 538} 539#endif /* CONFIG_WPS_OOB */ 540 541 542static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s, 543 char *cmd) 544{ 545 u8 bssid[ETH_ALEN]; 546 char *pin; 547 char *new_ssid; 548 char *new_auth; 549 char *new_encr; 550 char *new_key; 551 struct wps_new_ap_settings ap; 552 553 pin = os_strchr(cmd, ' '); 554 if (pin == NULL) 555 return -1; 556 *pin++ = '\0'; 557 558 if (hwaddr_aton(cmd, bssid)) { 559 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_REG: invalid BSSID '%s'", 560 cmd); 561 return -1; 562 } 563 564 new_ssid = os_strchr(pin, ' '); 565 if (new_ssid == NULL) 566 return wpas_wps_start_reg(wpa_s, bssid, pin, NULL); 567 *new_ssid++ = '\0'; 568 569 new_auth = os_strchr(new_ssid, ' '); 570 if (new_auth == NULL) 571 return -1; 572 *new_auth++ = '\0'; 573 574 new_encr = os_strchr(new_auth, ' '); 575 if (new_encr == NULL) 576 return -1; 577 *new_encr++ = '\0'; 578 579 new_key = os_strchr(new_encr, ' '); 580 if (new_key == NULL) 581 return -1; 582 *new_key++ = '\0'; 583 584 os_memset(&ap, 0, sizeof(ap)); 585 ap.ssid_hex = new_ssid; 586 ap.auth = new_auth; 587 ap.encr = new_encr; 588 ap.key_hex = new_key; 589 return wpas_wps_start_reg(wpa_s, bssid, pin, &ap); 590} 591 592 593#ifdef CONFIG_AP 594static int wpa_supplicant_ctrl_iface_wps_ap_pin(struct wpa_supplicant *wpa_s, 595 char *cmd, char *buf, 596 size_t buflen) 597{ 598 int timeout = 300; 599 char *pos; 600 const char *pin_txt; 601 602 if (!wpa_s->ap_iface) 603 return -1; 604 605 pos = os_strchr(cmd, ' '); 606 if (pos) 607 *pos++ = '\0'; 608 609 if (os_strcmp(cmd, "disable") == 0) { 610 wpas_wps_ap_pin_disable(wpa_s); 611 return os_snprintf(buf, buflen, "OK\n"); 612 } 613 614 if (os_strcmp(cmd, "random") == 0) { 615 if (pos) 616 timeout = atoi(pos); 617 pin_txt = wpas_wps_ap_pin_random(wpa_s, timeout); 618 if (pin_txt == NULL) 619 return -1; 620 return os_snprintf(buf, buflen, "%s", pin_txt); 621 } 622 623 if (os_strcmp(cmd, "get") == 0) { 624 pin_txt = wpas_wps_ap_pin_get(wpa_s); 625 if (pin_txt == NULL) 626 return -1; 627 return os_snprintf(buf, buflen, "%s", pin_txt); 628 } 629 630 if (os_strcmp(cmd, "set") == 0) { 631 char *pin; 632 if (pos == NULL) 633 return -1; 634 pin = pos; 635 pos = os_strchr(pos, ' '); 636 if (pos) { 637 *pos++ = '\0'; 638 timeout = atoi(pos); 639 } 640 if (os_strlen(pin) > buflen) 641 return -1; 642 if (wpas_wps_ap_pin_set(wpa_s, pin, timeout) < 0) 643 return -1; 644 return os_snprintf(buf, buflen, "%s", pin); 645 } 646 647 return -1; 648} 649#endif /* CONFIG_AP */ 650 651 652#ifdef CONFIG_WPS_ER 653static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant *wpa_s, 654 char *cmd) 655{ 656 char *uuid = cmd, *pin, *pos; 657 u8 addr_buf[ETH_ALEN], *addr = NULL; 658 pin = os_strchr(uuid, ' '); 659 if (pin == NULL) 660 return -1; 661 *pin++ = '\0'; 662 pos = os_strchr(pin, ' '); 663 if (pos) { 664 *pos++ = '\0'; 665 if (hwaddr_aton(pos, addr_buf) == 0) 666 addr = addr_buf; 667 } 668 return wpas_wps_er_add_pin(wpa_s, addr, uuid, pin); 669} 670 671 672static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant *wpa_s, 673 char *cmd) 674{ 675 char *uuid = cmd, *pin; 676 pin = os_strchr(uuid, ' '); 677 if (pin == NULL) 678 return -1; 679 *pin++ = '\0'; 680 return wpas_wps_er_learn(wpa_s, uuid, pin); 681} 682 683 684static int wpa_supplicant_ctrl_iface_wps_er_set_config( 685 struct wpa_supplicant *wpa_s, char *cmd) 686{ 687 char *uuid = cmd, *id; 688 id = os_strchr(uuid, ' '); 689 if (id == NULL) 690 return -1; 691 *id++ = '\0'; 692 return wpas_wps_er_set_config(wpa_s, uuid, atoi(id)); 693} 694 695 696static int wpa_supplicant_ctrl_iface_wps_er_config( 697 struct wpa_supplicant *wpa_s, char *cmd) 698{ 699 char *pin; 700 char *new_ssid; 701 char *new_auth; 702 char *new_encr; 703 char *new_key; 704 struct wps_new_ap_settings ap; 705 706 pin = os_strchr(cmd, ' '); 707 if (pin == NULL) 708 return -1; 709 *pin++ = '\0'; 710 711 new_ssid = os_strchr(pin, ' '); 712 if (new_ssid == NULL) 713 return -1; 714 *new_ssid++ = '\0'; 715 716 new_auth = os_strchr(new_ssid, ' '); 717 if (new_auth == NULL) 718 return -1; 719 *new_auth++ = '\0'; 720 721 new_encr = os_strchr(new_auth, ' '); 722 if (new_encr == NULL) 723 return -1; 724 *new_encr++ = '\0'; 725 726 new_key = os_strchr(new_encr, ' '); 727 if (new_key == NULL) 728 return -1; 729 *new_key++ = '\0'; 730 731 os_memset(&ap, 0, sizeof(ap)); 732 ap.ssid_hex = new_ssid; 733 ap.auth = new_auth; 734 ap.encr = new_encr; 735 ap.key_hex = new_key; 736 return wpas_wps_er_config(wpa_s, cmd, pin, &ap); 737} 738#endif /* CONFIG_WPS_ER */ 739 740#endif /* CONFIG_WPS */ 741 742 743#ifdef CONFIG_IBSS_RSN 744static int wpa_supplicant_ctrl_iface_ibss_rsn( 745 struct wpa_supplicant *wpa_s, char *addr) 746{ 747 u8 peer[ETH_ALEN]; 748 749 if (hwaddr_aton(addr, peer)) { 750 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN: invalid " 751 "address '%s'", addr); 752 return -1; 753 } 754 755 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN " MACSTR, 756 MAC2STR(peer)); 757 758 return ibss_rsn_start(wpa_s->ibss_rsn, peer); 759} 760#endif /* CONFIG_IBSS_RSN */ 761 762 763int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s, 764 struct wpa_ssid *ssid, 765 const char *field, 766 const char *value) 767{ 768#ifdef IEEE8021X_EAPOL 769 struct eap_peer_config *eap = &ssid->eap; 770 771 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field); 772 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value", 773 (const u8 *) value, os_strlen(value)); 774 775 switch (wpa_supplicant_ctrl_req_from_string(field)) { 776 case WPA_CTRL_REQ_EAP_IDENTITY: 777 os_free(eap->identity); 778 eap->identity = (u8 *) os_strdup(value); 779 eap->identity_len = os_strlen(value); 780 eap->pending_req_identity = 0; 781 if (ssid == wpa_s->current_ssid) 782 wpa_s->reassociate = 1; 783 break; 784 case WPA_CTRL_REQ_EAP_PASSWORD: 785 os_free(eap->password); 786 eap->password = (u8 *) os_strdup(value); 787 eap->password_len = os_strlen(value); 788 eap->pending_req_password = 0; 789 if (ssid == wpa_s->current_ssid) 790 wpa_s->reassociate = 1; 791 break; 792 case WPA_CTRL_REQ_EAP_NEW_PASSWORD: 793 os_free(eap->new_password); 794 eap->new_password = (u8 *) os_strdup(value); 795 eap->new_password_len = os_strlen(value); 796 eap->pending_req_new_password = 0; 797 if (ssid == wpa_s->current_ssid) 798 wpa_s->reassociate = 1; 799 break; 800 case WPA_CTRL_REQ_EAP_PIN: 801 os_free(eap->pin); 802 eap->pin = os_strdup(value); 803 eap->pending_req_pin = 0; 804 if (ssid == wpa_s->current_ssid) 805 wpa_s->reassociate = 1; 806 break; 807 case WPA_CTRL_REQ_EAP_OTP: 808 os_free(eap->otp); 809 eap->otp = (u8 *) os_strdup(value); 810 eap->otp_len = os_strlen(value); 811 os_free(eap->pending_req_otp); 812 eap->pending_req_otp = NULL; 813 eap->pending_req_otp_len = 0; 814 break; 815 case WPA_CTRL_REQ_EAP_PASSPHRASE: 816 os_free(eap->private_key_passwd); 817 eap->private_key_passwd = (u8 *) os_strdup(value); 818 eap->pending_req_passphrase = 0; 819 if (ssid == wpa_s->current_ssid) 820 wpa_s->reassociate = 1; 821 break; 822 default: 823 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field); 824 return -1; 825 } 826 827 return 0; 828#else /* IEEE8021X_EAPOL */ 829 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included"); 830 return -1; 831#endif /* IEEE8021X_EAPOL */ 832} 833 834 835static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s, 836 char *rsp) 837{ 838#ifdef IEEE8021X_EAPOL 839 char *pos, *id_pos; 840 int id; 841 struct wpa_ssid *ssid; 842 843 pos = os_strchr(rsp, '-'); 844 if (pos == NULL) 845 return -1; 846 *pos++ = '\0'; 847 id_pos = pos; 848 pos = os_strchr(pos, ':'); 849 if (pos == NULL) 850 return -1; 851 *pos++ = '\0'; 852 id = atoi(id_pos); 853 wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id); 854 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value", 855 (u8 *) pos, os_strlen(pos)); 856 857 ssid = wpa_config_get_network(wpa_s->conf, id); 858 if (ssid == NULL) { 859 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 860 "to update", id); 861 return -1; 862 } 863 864 return wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s, ssid, rsp, 865 pos); 866#else /* IEEE8021X_EAPOL */ 867 wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included"); 868 return -1; 869#endif /* IEEE8021X_EAPOL */ 870} 871 872 873static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, 874 const char *params, 875 char *buf, size_t buflen) 876{ 877 char *pos, *end, tmp[30]; 878 int res, verbose, wps, ret; 879 880 verbose = os_strcmp(params, "-VERBOSE") == 0; 881 wps = os_strcmp(params, "-WPS") == 0; 882 pos = buf; 883 end = buf + buflen; 884 if (wpa_s->wpa_state >= WPA_ASSOCIATED) { 885 struct wpa_ssid *ssid = wpa_s->current_ssid; 886 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n", 887 MAC2STR(wpa_s->bssid)); 888 if (ret < 0 || ret >= end - pos) 889 return pos - buf; 890 pos += ret; 891 if (ssid) { 892 u8 *_ssid = ssid->ssid; 893 size_t ssid_len = ssid->ssid_len; 894 u8 ssid_buf[MAX_SSID_LEN]; 895 if (ssid_len == 0) { 896 int _res = wpa_drv_get_ssid(wpa_s, ssid_buf); 897 if (_res < 0) 898 ssid_len = 0; 899 else 900 ssid_len = _res; 901 _ssid = ssid_buf; 902 } 903 ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n", 904 wpa_ssid_txt(_ssid, ssid_len), 905 ssid->id); 906 if (ret < 0 || ret >= end - pos) 907 return pos - buf; 908 pos += ret; 909 910 if (wps && ssid->passphrase && 911 wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && 912 (ssid->mode == WPAS_MODE_AP || 913 ssid->mode == WPAS_MODE_P2P_GO)) { 914 ret = os_snprintf(pos, end - pos, 915 "passphrase=%s\n", 916 ssid->passphrase); 917 if (ret < 0 || ret >= end - pos) 918 return pos - buf; 919 pos += ret; 920 } 921 if (ssid->id_str) { 922 ret = os_snprintf(pos, end - pos, 923 "id_str=%s\n", 924 ssid->id_str); 925 if (ret < 0 || ret >= end - pos) 926 return pos - buf; 927 pos += ret; 928 } 929 930 switch (ssid->mode) { 931 case WPAS_MODE_INFRA: 932 ret = os_snprintf(pos, end - pos, 933 "mode=station\n"); 934 break; 935 case WPAS_MODE_IBSS: 936 ret = os_snprintf(pos, end - pos, 937 "mode=IBSS\n"); 938 break; 939 case WPAS_MODE_AP: 940 ret = os_snprintf(pos, end - pos, 941 "mode=AP\n"); 942 break; 943 case WPAS_MODE_P2P_GO: 944 ret = os_snprintf(pos, end - pos, 945 "mode=P2P GO\n"); 946 break; 947 case WPAS_MODE_P2P_GROUP_FORMATION: 948 ret = os_snprintf(pos, end - pos, 949 "mode=P2P GO - group " 950 "formation\n"); 951 break; 952 default: 953 ret = 0; 954 break; 955 } 956 if (ret < 0 || ret >= end - pos) 957 return pos - buf; 958 pos += ret; 959 } 960 961#ifdef CONFIG_AP 962 if (wpa_s->ap_iface) { 963 pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos, 964 end - pos, 965 verbose); 966 } else 967#endif /* CONFIG_AP */ 968 pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose); 969 } 970 ret = os_snprintf(pos, end - pos, "wpa_state=%s\n", 971 wpa_supplicant_state_txt(wpa_s->wpa_state)); 972 if (ret < 0 || ret >= end - pos) 973 return pos - buf; 974 pos += ret; 975 976 if (wpa_s->l2 && 977 l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) { 978 ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp); 979 if (ret < 0 || ret >= end - pos) 980 return pos - buf; 981 pos += ret; 982 } 983 984#ifdef CONFIG_P2P 985 if (wpa_s->global->p2p) { 986 ret = os_snprintf(pos, end - pos, "p2p_device_address=" MACSTR 987 "\n", MAC2STR(wpa_s->global->p2p_dev_addr)); 988 if (ret < 0 || ret >= end - pos) 989 return pos - buf; 990 pos += ret; 991 } 992#endif /* CONFIG_P2P */ 993 994 ret = os_snprintf(pos, end - pos, "address=" MACSTR "\n", 995 MAC2STR(wpa_s->own_addr)); 996 if (ret < 0 || ret >= end - pos) 997 return pos - buf; 998 pos += ret; 999 1000 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) || 1001 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) { 1002 res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos, 1003 verbose); 1004 if (res >= 0) 1005 pos += res; 1006 } 1007 1008 res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose); 1009 if (res >= 0) 1010 pos += res; 1011 1012#ifdef ANDROID 1013 wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_STATE_CHANGE 1014 "id=%d state=%d BSSID=" MACSTR " SSID=%s", 1015 wpa_s->current_ssid ? wpa_s->current_ssid->id : -1, 1016 wpa_s->wpa_state, 1017 MAC2STR(wpa_s->pending_bssid), 1018 wpa_s->current_ssid ? wpa_s->current_ssid->ssid : ""); 1019 if (wpa_s->wpa_state == WPA_COMPLETED) { 1020 struct wpa_ssid *ssid = wpa_s->current_ssid; 1021 wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- connection to " 1022 MACSTR " completed %s [id=%d id_str=%s]", 1023 MAC2STR(wpa_s->bssid), wpa_s->reassociated_connection ? 1024 "(reauth)" : "(auth)", 1025 ssid ? ssid->id : -1, 1026 ssid && ssid->id_str ? ssid->id_str : ""); 1027 } 1028#endif /* ANDROID */ 1029 1030 return pos - buf; 1031} 1032 1033 1034static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s, 1035 char *cmd) 1036{ 1037 char *pos; 1038 int id; 1039 struct wpa_ssid *ssid; 1040 u8 bssid[ETH_ALEN]; 1041 1042 /* cmd: "<network id> <BSSID>" */ 1043 pos = os_strchr(cmd, ' '); 1044 if (pos == NULL) 1045 return -1; 1046 *pos++ = '\0'; 1047 id = atoi(cmd); 1048 wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos); 1049 if (hwaddr_aton(pos, bssid)) { 1050 wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos); 1051 return -1; 1052 } 1053 1054 ssid = wpa_config_get_network(wpa_s->conf, id); 1055 if (ssid == NULL) { 1056 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 1057 "to update", id); 1058 return -1; 1059 } 1060 1061 os_memcpy(ssid->bssid, bssid, ETH_ALEN); 1062 ssid->bssid_set = !is_zero_ether_addr(bssid); 1063 1064 return 0; 1065} 1066 1067 1068static int wpa_supplicant_ctrl_iface_blacklist(struct wpa_supplicant *wpa_s, 1069 char *cmd, char *buf, 1070 size_t buflen) 1071{ 1072 u8 bssid[ETH_ALEN]; 1073 struct wpa_blacklist *e; 1074 char *pos, *end; 1075 int ret; 1076 1077 /* cmd: "BLACKLIST [<BSSID>]" */ 1078 if (*cmd == '\0') { 1079 pos = buf; 1080 end = buf + buflen; 1081 e = wpa_s->blacklist; 1082 while (e) { 1083 ret = os_snprintf(pos, end - pos, MACSTR "\n", 1084 MAC2STR(e->bssid)); 1085 if (ret < 0 || ret >= end - pos) 1086 return pos - buf; 1087 pos += ret; 1088 e = e->next; 1089 } 1090 return pos - buf; 1091 } 1092 1093 cmd++; 1094 if (os_strncmp(cmd, "clear", 5) == 0) { 1095 wpa_blacklist_clear(wpa_s); 1096 os_memcpy(buf, "OK\n", 3); 1097 return 3; 1098 } 1099 1100 wpa_printf(MSG_DEBUG, "CTRL_IFACE: BLACKLIST bssid='%s'", cmd); 1101 if (hwaddr_aton(cmd, bssid)) { 1102 wpa_printf(MSG_DEBUG, "CTRL_IFACE: invalid BSSID '%s'", cmd); 1103 return -1; 1104 } 1105 1106 /* 1107 * Add the BSSID twice, so its count will be 2, causing it to be 1108 * skipped when processing scan results. 1109 */ 1110 ret = wpa_blacklist_add(wpa_s, bssid); 1111 if (ret != 0) 1112 return -1; 1113 ret = wpa_blacklist_add(wpa_s, bssid); 1114 if (ret != 0) 1115 return -1; 1116 os_memcpy(buf, "OK\n", 3); 1117 return 3; 1118} 1119 1120 1121extern int wpa_debug_level; 1122extern int wpa_debug_timestamp; 1123 1124static const char * debug_level_str(int level) 1125{ 1126 switch (level) { 1127 case MSG_EXCESSIVE: 1128 return "EXCESSIVE"; 1129 case MSG_MSGDUMP: 1130 return "MSGDUMP"; 1131 case MSG_DEBUG: 1132 return "DEBUG"; 1133 case MSG_INFO: 1134 return "INFO"; 1135 case MSG_WARNING: 1136 return "WARNING"; 1137 case MSG_ERROR: 1138 return "ERROR"; 1139 default: 1140 return "?"; 1141 } 1142} 1143 1144 1145static int str_to_debug_level(const char *s) 1146{ 1147 if (os_strcasecmp(s, "EXCESSIVE") == 0) 1148 return MSG_EXCESSIVE; 1149 if (os_strcasecmp(s, "MSGDUMP") == 0) 1150 return MSG_MSGDUMP; 1151 if (os_strcasecmp(s, "DEBUG") == 0) 1152 return MSG_DEBUG; 1153 if (os_strcasecmp(s, "INFO") == 0) 1154 return MSG_INFO; 1155 if (os_strcasecmp(s, "WARNING") == 0) 1156 return MSG_WARNING; 1157 if (os_strcasecmp(s, "ERROR") == 0) 1158 return MSG_ERROR; 1159 return -1; 1160} 1161 1162 1163static int wpa_supplicant_ctrl_iface_log_level(struct wpa_supplicant *wpa_s, 1164 char *cmd, char *buf, 1165 size_t buflen) 1166{ 1167 char *pos, *end, *stamp; 1168 int ret; 1169 1170 if (cmd == NULL) { 1171 return -1; 1172 } 1173 1174 /* cmd: "LOG_LEVEL [<level>]" */ 1175 if (*cmd == '\0') { 1176 pos = buf; 1177 end = buf + buflen; 1178 ret = os_snprintf(pos, end - pos, "Current level: %s\n" 1179 "Timestamp: %d\n", 1180 debug_level_str(wpa_debug_level), 1181 wpa_debug_timestamp); 1182 if (ret < 0 || ret >= end - pos) 1183 ret = 0; 1184 1185 return ret; 1186 } 1187 1188 while (*cmd == ' ') 1189 cmd++; 1190 1191 stamp = os_strchr(cmd, ' '); 1192 if (stamp) { 1193 *stamp++ = '\0'; 1194 while (*stamp == ' ') { 1195 stamp++; 1196 } 1197 } 1198 1199 if (cmd && os_strlen(cmd)) { 1200 int level = str_to_debug_level(cmd); 1201 if (level < 0) 1202 return -1; 1203 wpa_debug_level = level; 1204 } 1205 1206 if (stamp && os_strlen(stamp)) 1207 wpa_debug_timestamp = atoi(stamp); 1208 1209 os_memcpy(buf, "OK\n", 3); 1210 return 3; 1211} 1212 1213 1214static int wpa_supplicant_ctrl_iface_list_networks( 1215 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 1216{ 1217 char *pos, *end; 1218 struct wpa_ssid *ssid; 1219 int ret; 1220 1221 pos = buf; 1222 end = buf + buflen; 1223 ret = os_snprintf(pos, end - pos, 1224 "network id / ssid / bssid / flags\n"); 1225 if (ret < 0 || ret >= end - pos) 1226 return pos - buf; 1227 pos += ret; 1228 1229 ssid = wpa_s->conf->ssid; 1230 while (ssid) { 1231 ret = os_snprintf(pos, end - pos, "%d\t%s", 1232 ssid->id, 1233 wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 1234 if (ret < 0 || ret >= end - pos) 1235 return pos - buf; 1236 pos += ret; 1237 if (ssid->bssid_set) { 1238 ret = os_snprintf(pos, end - pos, "\t" MACSTR, 1239 MAC2STR(ssid->bssid)); 1240 } else { 1241 ret = os_snprintf(pos, end - pos, "\tany"); 1242 } 1243 if (ret < 0 || ret >= end - pos) 1244 return pos - buf; 1245 pos += ret; 1246 ret = os_snprintf(pos, end - pos, "\t%s%s%s", 1247 ssid == wpa_s->current_ssid ? 1248 "[CURRENT]" : "", 1249 ssid->disabled ? "[DISABLED]" : "", 1250 ssid->disabled == 2 ? "[P2P-PERSISTENT]" : 1251 ""); 1252 if (ret < 0 || ret >= end - pos) 1253 return pos - buf; 1254 pos += ret; 1255 ret = os_snprintf(pos, end - pos, "\n"); 1256 if (ret < 0 || ret >= end - pos) 1257 return pos - buf; 1258 pos += ret; 1259 1260 ssid = ssid->next; 1261 } 1262 1263 return pos - buf; 1264} 1265 1266 1267static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher) 1268{ 1269 int first = 1, ret; 1270 ret = os_snprintf(pos, end - pos, "-"); 1271 if (ret < 0 || ret >= end - pos) 1272 return pos; 1273 pos += ret; 1274 if (cipher & WPA_CIPHER_NONE) { 1275 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : "+"); 1276 if (ret < 0 || ret >= end - pos) 1277 return pos; 1278 pos += ret; 1279 first = 0; 1280 } 1281 if (cipher & WPA_CIPHER_WEP40) { 1282 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : "+"); 1283 if (ret < 0 || ret >= end - pos) 1284 return pos; 1285 pos += ret; 1286 first = 0; 1287 } 1288 if (cipher & WPA_CIPHER_WEP104) { 1289 ret = os_snprintf(pos, end - pos, "%sWEP104", 1290 first ? "" : "+"); 1291 if (ret < 0 || ret >= end - pos) 1292 return pos; 1293 pos += ret; 1294 first = 0; 1295 } 1296 if (cipher & WPA_CIPHER_TKIP) { 1297 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : "+"); 1298 if (ret < 0 || ret >= end - pos) 1299 return pos; 1300 pos += ret; 1301 first = 0; 1302 } 1303 if (cipher & WPA_CIPHER_CCMP) { 1304 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : "+"); 1305 if (ret < 0 || ret >= end - pos) 1306 return pos; 1307 pos += ret; 1308 first = 0; 1309 } 1310 return pos; 1311} 1312 1313 1314static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto, 1315 const u8 *ie, size_t ie_len) 1316{ 1317 struct wpa_ie_data data; 1318 int first, ret; 1319 1320 ret = os_snprintf(pos, end - pos, "[%s-", proto); 1321 if (ret < 0 || ret >= end - pos) 1322 return pos; 1323 pos += ret; 1324 1325 if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) { 1326 ret = os_snprintf(pos, end - pos, "?]"); 1327 if (ret < 0 || ret >= end - pos) 1328 return pos; 1329 pos += ret; 1330 return pos; 1331 } 1332 1333 first = 1; 1334 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) { 1335 ret = os_snprintf(pos, end - pos, "%sEAP", first ? "" : "+"); 1336 if (ret < 0 || ret >= end - pos) 1337 return pos; 1338 pos += ret; 1339 first = 0; 1340 } 1341 if (data.key_mgmt & WPA_KEY_MGMT_PSK) { 1342 ret = os_snprintf(pos, end - pos, "%sPSK", first ? "" : "+"); 1343 if (ret < 0 || ret >= end - pos) 1344 return pos; 1345 pos += ret; 1346 first = 0; 1347 } 1348 if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) { 1349 ret = os_snprintf(pos, end - pos, "%sNone", first ? "" : "+"); 1350 if (ret < 0 || ret >= end - pos) 1351 return pos; 1352 pos += ret; 1353 first = 0; 1354 } 1355#ifdef CONFIG_IEEE80211R 1356 if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) { 1357 ret = os_snprintf(pos, end - pos, "%sFT/EAP", 1358 first ? "" : "+"); 1359 if (ret < 0 || ret >= end - pos) 1360 return pos; 1361 pos += ret; 1362 first = 0; 1363 } 1364 if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) { 1365 ret = os_snprintf(pos, end - pos, "%sFT/PSK", 1366 first ? "" : "+"); 1367 if (ret < 0 || ret >= end - pos) 1368 return pos; 1369 pos += ret; 1370 first = 0; 1371 } 1372#endif /* CONFIG_IEEE80211R */ 1373#ifdef CONFIG_IEEE80211W 1374 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) { 1375 ret = os_snprintf(pos, end - pos, "%sEAP-SHA256", 1376 first ? "" : "+"); 1377 if (ret < 0 || ret >= end - pos) 1378 return pos; 1379 pos += ret; 1380 first = 0; 1381 } 1382 if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) { 1383 ret = os_snprintf(pos, end - pos, "%sPSK-SHA256", 1384 first ? "" : "+"); 1385 if (ret < 0 || ret >= end - pos) 1386 return pos; 1387 pos += ret; 1388 first = 0; 1389 } 1390#endif /* CONFIG_IEEE80211W */ 1391 1392 pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher); 1393 1394 if (data.capabilities & WPA_CAPABILITY_PREAUTH) { 1395 ret = os_snprintf(pos, end - pos, "-preauth"); 1396 if (ret < 0 || ret >= end - pos) 1397 return pos; 1398 pos += ret; 1399 } 1400 1401 ret = os_snprintf(pos, end - pos, "]"); 1402 if (ret < 0 || ret >= end - pos) 1403 return pos; 1404 pos += ret; 1405 1406 return pos; 1407} 1408 1409 1410#ifdef CONFIG_WPS 1411static char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant *wpa_s, 1412 char *pos, char *end, 1413 struct wpabuf *wps_ie) 1414{ 1415 int ret; 1416 const char *txt; 1417 1418 if (wps_ie == NULL) 1419 return pos; 1420 if (wps_is_selected_pbc_registrar(wps_ie)) 1421 txt = "[WPS-PBC]"; 1422#ifdef CONFIG_WPS2 1423 else if (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 0)) 1424 txt = "[WPS-AUTH]"; 1425#endif /* CONFIG_WPS2 */ 1426 else if (wps_is_selected_pin_registrar(wps_ie)) 1427 txt = "[WPS-PIN]"; 1428 else 1429 txt = "[WPS]"; 1430 1431 ret = os_snprintf(pos, end - pos, "%s", txt); 1432 if (ret >= 0 && ret < end - pos) 1433 pos += ret; 1434 wpabuf_free(wps_ie); 1435 return pos; 1436} 1437#endif /* CONFIG_WPS */ 1438 1439 1440static char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant *wpa_s, 1441 char *pos, char *end, 1442 const struct wpa_bss *bss) 1443{ 1444#ifdef CONFIG_WPS 1445 struct wpabuf *wps_ie; 1446 wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); 1447 return wpa_supplicant_wps_ie_txt_buf(wpa_s, pos, end, wps_ie); 1448#else /* CONFIG_WPS */ 1449 return pos; 1450#endif /* CONFIG_WPS */ 1451} 1452 1453 1454/* Format one result on one text line into a buffer. */ 1455static int wpa_supplicant_ctrl_iface_scan_result( 1456 struct wpa_supplicant *wpa_s, 1457 const struct wpa_bss *bss, char *buf, size_t buflen) 1458{ 1459 char *pos, *end; 1460 int ret; 1461 const u8 *ie, *ie2, *p2p; 1462 1463 p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE); 1464 if (p2p && bss->ssid_len == P2P_WILDCARD_SSID_LEN && 1465 os_memcmp(bss->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) == 1466 0) 1467 return 0; /* Do not show P2P listen discovery results here */ 1468 1469 pos = buf; 1470 end = buf + buflen; 1471 1472 ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t", 1473 MAC2STR(bss->bssid), bss->freq, bss->level); 1474 if (ret < 0 || ret >= end - pos) 1475 return -1; 1476 pos += ret; 1477 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); 1478 if (ie) 1479 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]); 1480 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN); 1481 if (ie2) 1482 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]); 1483 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss); 1484 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) { 1485 ret = os_snprintf(pos, end - pos, "[WEP]"); 1486 if (ret < 0 || ret >= end - pos) 1487 return -1; 1488 pos += ret; 1489 } 1490 if (bss->caps & IEEE80211_CAP_IBSS) { 1491 ret = os_snprintf(pos, end - pos, "[IBSS]"); 1492 if (ret < 0 || ret >= end - pos) 1493 return -1; 1494 pos += ret; 1495 } 1496 if (bss->caps & IEEE80211_CAP_ESS) { 1497 ret = os_snprintf(pos, end - pos, "[ESS]"); 1498 if (ret < 0 || ret >= end - pos) 1499 return -1; 1500 pos += ret; 1501 } 1502 if (p2p) { 1503 ret = os_snprintf(pos, end - pos, "[P2P]"); 1504 if (ret < 0 || ret >= end - pos) 1505 return -1; 1506 pos += ret; 1507 } 1508 1509 ret = os_snprintf(pos, end - pos, "\t%s", 1510 wpa_ssid_txt(bss->ssid, bss->ssid_len)); 1511 if (ret < 0 || ret >= end - pos) 1512 return -1; 1513 pos += ret; 1514 1515 ret = os_snprintf(pos, end - pos, "\n"); 1516 if (ret < 0 || ret >= end - pos) 1517 return -1; 1518 pos += ret; 1519 1520 return pos - buf; 1521} 1522 1523 1524static int wpa_supplicant_ctrl_iface_scan_results( 1525 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 1526{ 1527 char *pos, *end; 1528 struct wpa_bss *bss; 1529 int ret; 1530 1531 pos = buf; 1532 end = buf + buflen; 1533 ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / " 1534 "flags / ssid\n"); 1535 if (ret < 0 || ret >= end - pos) 1536 return pos - buf; 1537 pos += ret; 1538 1539 dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) { 1540 ret = wpa_supplicant_ctrl_iface_scan_result(wpa_s, bss, pos, 1541 end - pos); 1542 if (ret < 0 || ret >= end - pos) 1543 return pos - buf; 1544 pos += ret; 1545 } 1546 1547 return pos - buf; 1548} 1549 1550 1551static int wpa_supplicant_ctrl_iface_select_network( 1552 struct wpa_supplicant *wpa_s, char *cmd) 1553{ 1554 int id; 1555 struct wpa_ssid *ssid; 1556 1557 /* cmd: "<network id>" or "any" */ 1558 if (os_strcmp(cmd, "any") == 0) { 1559 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any"); 1560 ssid = NULL; 1561 } else { 1562 id = atoi(cmd); 1563 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id); 1564 1565 ssid = wpa_config_get_network(wpa_s->conf, id); 1566 if (ssid == NULL) { 1567 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " 1568 "network id=%d", id); 1569 return -1; 1570 } 1571 if (ssid->disabled == 2) { 1572 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use " 1573 "SELECT_NETWORK with persistent P2P group"); 1574 return -1; 1575 } 1576 } 1577 1578 wpa_supplicant_select_network(wpa_s, ssid); 1579 1580 return 0; 1581} 1582 1583 1584static int wpa_supplicant_ctrl_iface_enable_network( 1585 struct wpa_supplicant *wpa_s, char *cmd) 1586{ 1587 int id; 1588 struct wpa_ssid *ssid; 1589 1590 /* cmd: "<network id>" or "all" */ 1591 if (os_strcmp(cmd, "all") == 0) { 1592 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all"); 1593 ssid = NULL; 1594 } else { 1595 id = atoi(cmd); 1596 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id); 1597 1598 ssid = wpa_config_get_network(wpa_s->conf, id); 1599 if (ssid == NULL) { 1600 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " 1601 "network id=%d", id); 1602 return -1; 1603 } 1604 if (ssid->disabled == 2) { 1605 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use " 1606 "ENABLE_NETWORK with persistent P2P group"); 1607 return -1; 1608 } 1609 } 1610 wpa_supplicant_enable_network(wpa_s, ssid); 1611 1612 return 0; 1613} 1614 1615 1616static int wpa_supplicant_ctrl_iface_disable_network( 1617 struct wpa_supplicant *wpa_s, char *cmd) 1618{ 1619 int id; 1620 struct wpa_ssid *ssid; 1621 1622 /* cmd: "<network id>" or "all" */ 1623 if (os_strcmp(cmd, "all") == 0) { 1624 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all"); 1625 ssid = NULL; 1626 } else { 1627 id = atoi(cmd); 1628 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id); 1629 1630 ssid = wpa_config_get_network(wpa_s->conf, id); 1631 if (ssid == NULL) { 1632 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " 1633 "network id=%d", id); 1634 return -1; 1635 } 1636 if (ssid->disabled == 2) { 1637 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use " 1638 "DISABLE_NETWORK with persistent P2P " 1639 "group"); 1640 return -1; 1641 } 1642 } 1643 wpa_supplicant_disable_network(wpa_s, ssid); 1644 1645 return 0; 1646} 1647 1648 1649static int wpa_supplicant_ctrl_iface_add_network( 1650 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 1651{ 1652 struct wpa_ssid *ssid; 1653 int ret; 1654 1655 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK"); 1656 1657 ssid = wpa_config_add_network(wpa_s->conf); 1658 if (ssid == NULL) 1659 return -1; 1660 1661 wpas_notify_network_added(wpa_s, ssid); 1662 1663 ssid->disabled = 1; 1664 wpa_config_set_network_defaults(ssid); 1665 1666 ret = os_snprintf(buf, buflen, "%d\n", ssid->id); 1667 if (ret < 0 || (size_t) ret >= buflen) 1668 return -1; 1669 return ret; 1670} 1671 1672 1673static int wpa_supplicant_ctrl_iface_remove_network( 1674 struct wpa_supplicant *wpa_s, char *cmd) 1675{ 1676 int id; 1677 struct wpa_ssid *ssid; 1678 1679 /* cmd: "<network id>" or "all" */ 1680 if (os_strcmp(cmd, "all") == 0) { 1681 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all"); 1682 ssid = wpa_s->conf->ssid; 1683 while (ssid) { 1684 struct wpa_ssid *remove_ssid = ssid; 1685 id = ssid->id; 1686 ssid = ssid->next; 1687 wpas_notify_network_removed(wpa_s, remove_ssid); 1688 wpa_config_remove_network(wpa_s->conf, id); 1689 } 1690 eapol_sm_invalidate_cached_session(wpa_s->eapol); 1691 if (wpa_s->current_ssid) { 1692 wpa_sm_set_config(wpa_s->wpa, NULL); 1693 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); 1694 wpa_supplicant_disassociate(wpa_s, 1695 WLAN_REASON_DEAUTH_LEAVING); 1696 } 1697 return 0; 1698 } 1699 1700 id = atoi(cmd); 1701 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id); 1702 1703 ssid = wpa_config_get_network(wpa_s->conf, id); 1704 if (ssid) 1705 wpas_notify_network_removed(wpa_s, ssid); 1706 if (ssid == NULL || 1707 wpa_config_remove_network(wpa_s->conf, id) < 0) { 1708 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 1709 "id=%d", id); 1710 return -1; 1711 } 1712 1713 if (ssid == wpa_s->current_ssid || wpa_s->current_ssid == NULL) { 1714 /* 1715 * Invalidate the EAP session cache if the current or 1716 * previously used network is removed. 1717 */ 1718 eapol_sm_invalidate_cached_session(wpa_s->eapol); 1719 } 1720 1721 if (ssid == wpa_s->current_ssid) { 1722 wpa_sm_set_config(wpa_s->wpa, NULL); 1723 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); 1724 1725 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); 1726 } 1727 1728 return 0; 1729} 1730 1731 1732static int wpa_supplicant_ctrl_iface_set_network( 1733 struct wpa_supplicant *wpa_s, char *cmd) 1734{ 1735 int id; 1736 struct wpa_ssid *ssid; 1737 char *name, *value; 1738 1739 /* cmd: "<network id> <variable name> <value>" */ 1740 name = os_strchr(cmd, ' '); 1741 if (name == NULL) 1742 return -1; 1743 *name++ = '\0'; 1744 1745 value = os_strchr(name, ' '); 1746 if (value == NULL) 1747 return -1; 1748 *value++ = '\0'; 1749 1750 id = atoi(cmd); 1751 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'", 1752 id, name); 1753 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value", 1754 (u8 *) value, os_strlen(value)); 1755 1756 ssid = wpa_config_get_network(wpa_s->conf, id); 1757 if (ssid == NULL) { 1758 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 1759 "id=%d", id); 1760 return -1; 1761 } 1762 1763 if (wpa_config_set(ssid, name, value, 0) < 0) { 1764 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network " 1765 "variable '%s'", name); 1766 return -1; 1767 } 1768 1769 wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid); 1770 1771 if (wpa_s->current_ssid == ssid || wpa_s->current_ssid == NULL) { 1772 /* 1773 * Invalidate the EAP session cache if anything in the current 1774 * or previously used configuration changes. 1775 */ 1776 eapol_sm_invalidate_cached_session(wpa_s->eapol); 1777 } 1778 1779 if ((os_strcmp(name, "psk") == 0 && 1780 value[0] == '"' && ssid->ssid_len) || 1781 (os_strcmp(name, "ssid") == 0 && ssid->passphrase)) 1782 wpa_config_update_psk(ssid); 1783 else if (os_strcmp(name, "priority") == 0) 1784 wpa_config_update_prio_list(wpa_s->conf); 1785 1786 return 0; 1787} 1788 1789 1790static int wpa_supplicant_ctrl_iface_get_network( 1791 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) 1792{ 1793 int id; 1794 size_t res; 1795 struct wpa_ssid *ssid; 1796 char *name, *value; 1797 1798 /* cmd: "<network id> <variable name>" */ 1799 name = os_strchr(cmd, ' '); 1800 if (name == NULL || buflen == 0) 1801 return -1; 1802 *name++ = '\0'; 1803 1804 id = atoi(cmd); 1805 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'", 1806 id, name); 1807 1808 ssid = wpa_config_get_network(wpa_s->conf, id); 1809 if (ssid == NULL) { 1810 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 1811 "id=%d", id); 1812 return -1; 1813 } 1814 1815 value = wpa_config_get_no_key(ssid, name); 1816 if (value == NULL) { 1817 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network " 1818 "variable '%s'", name); 1819 return -1; 1820 } 1821 1822 res = os_strlcpy(buf, value, buflen); 1823 if (res >= buflen) { 1824 os_free(value); 1825 return -1; 1826 } 1827 1828 os_free(value); 1829 1830 return res; 1831} 1832 1833 1834#ifndef CONFIG_NO_CONFIG_WRITE 1835static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s) 1836{ 1837 int ret; 1838 1839 if (!wpa_s->conf->update_config) { 1840 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed " 1841 "to update configuration (update_config=0)"); 1842 return -1; 1843 } 1844 1845 ret = wpa_config_write(wpa_s->confname, wpa_s->conf); 1846 if (ret) { 1847 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to " 1848 "update configuration"); 1849 } else { 1850 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration" 1851 " updated"); 1852 } 1853 1854 return ret; 1855} 1856#endif /* CONFIG_NO_CONFIG_WRITE */ 1857 1858 1859static int ctrl_iface_get_capability_pairwise(int res, char *strict, 1860 struct wpa_driver_capa *capa, 1861 char *buf, size_t buflen) 1862{ 1863 int ret, first = 1; 1864 char *pos, *end; 1865 size_t len; 1866 1867 pos = buf; 1868 end = pos + buflen; 1869 1870 if (res < 0) { 1871 if (strict) 1872 return 0; 1873 len = os_strlcpy(buf, "CCMP TKIP NONE", buflen); 1874 if (len >= buflen) 1875 return -1; 1876 return len; 1877 } 1878 1879 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) { 1880 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " "); 1881 if (ret < 0 || ret >= end - pos) 1882 return pos - buf; 1883 pos += ret; 1884 first = 0; 1885 } 1886 1887 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) { 1888 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " "); 1889 if (ret < 0 || ret >= end - pos) 1890 return pos - buf; 1891 pos += ret; 1892 first = 0; 1893 } 1894 1895 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { 1896 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : " "); 1897 if (ret < 0 || ret >= end - pos) 1898 return pos - buf; 1899 pos += ret; 1900 first = 0; 1901 } 1902 1903 return pos - buf; 1904} 1905 1906 1907static int ctrl_iface_get_capability_group(int res, char *strict, 1908 struct wpa_driver_capa *capa, 1909 char *buf, size_t buflen) 1910{ 1911 int ret, first = 1; 1912 char *pos, *end; 1913 size_t len; 1914 1915 pos = buf; 1916 end = pos + buflen; 1917 1918 if (res < 0) { 1919 if (strict) 1920 return 0; 1921 len = os_strlcpy(buf, "CCMP TKIP WEP104 WEP40", buflen); 1922 if (len >= buflen) 1923 return -1; 1924 return len; 1925 } 1926 1927 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) { 1928 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " "); 1929 if (ret < 0 || ret >= end - pos) 1930 return pos - buf; 1931 pos += ret; 1932 first = 0; 1933 } 1934 1935 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) { 1936 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " "); 1937 if (ret < 0 || ret >= end - pos) 1938 return pos - buf; 1939 pos += ret; 1940 first = 0; 1941 } 1942 1943 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP104) { 1944 ret = os_snprintf(pos, end - pos, "%sWEP104", 1945 first ? "" : " "); 1946 if (ret < 0 || ret >= end - pos) 1947 return pos - buf; 1948 pos += ret; 1949 first = 0; 1950 } 1951 1952 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP40) { 1953 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : " "); 1954 if (ret < 0 || ret >= end - pos) 1955 return pos - buf; 1956 pos += ret; 1957 first = 0; 1958 } 1959 1960 return pos - buf; 1961} 1962 1963 1964static int ctrl_iface_get_capability_key_mgmt(int res, char *strict, 1965 struct wpa_driver_capa *capa, 1966 char *buf, size_t buflen) 1967{ 1968 int ret; 1969 char *pos, *end; 1970 size_t len; 1971 1972 pos = buf; 1973 end = pos + buflen; 1974 1975 if (res < 0) { 1976 if (strict) 1977 return 0; 1978 len = os_strlcpy(buf, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE " 1979 "NONE", buflen); 1980 if (len >= buflen) 1981 return -1; 1982 return len; 1983 } 1984 1985 ret = os_snprintf(pos, end - pos, "NONE IEEE8021X"); 1986 if (ret < 0 || ret >= end - pos) 1987 return pos - buf; 1988 pos += ret; 1989 1990 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | 1991 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) { 1992 ret = os_snprintf(pos, end - pos, " WPA-EAP"); 1993 if (ret < 0 || ret >= end - pos) 1994 return pos - buf; 1995 pos += ret; 1996 } 1997 1998 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | 1999 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { 2000 ret = os_snprintf(pos, end - pos, " WPA-PSK"); 2001 if (ret < 0 || ret >= end - pos) 2002 return pos - buf; 2003 pos += ret; 2004 } 2005 2006 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { 2007 ret = os_snprintf(pos, end - pos, " WPA-NONE"); 2008 if (ret < 0 || ret >= end - pos) 2009 return pos - buf; 2010 pos += ret; 2011 } 2012 2013 return pos - buf; 2014} 2015 2016 2017static int ctrl_iface_get_capability_proto(int res, char *strict, 2018 struct wpa_driver_capa *capa, 2019 char *buf, size_t buflen) 2020{ 2021 int ret, first = 1; 2022 char *pos, *end; 2023 size_t len; 2024 2025 pos = buf; 2026 end = pos + buflen; 2027 2028 if (res < 0) { 2029 if (strict) 2030 return 0; 2031 len = os_strlcpy(buf, "RSN WPA", buflen); 2032 if (len >= buflen) 2033 return -1; 2034 return len; 2035 } 2036 2037 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | 2038 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { 2039 ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " "); 2040 if (ret < 0 || ret >= end - pos) 2041 return pos - buf; 2042 pos += ret; 2043 first = 0; 2044 } 2045 2046 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | 2047 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) { 2048 ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " "); 2049 if (ret < 0 || ret >= end - pos) 2050 return pos - buf; 2051 pos += ret; 2052 first = 0; 2053 } 2054 2055 return pos - buf; 2056} 2057 2058 2059static int ctrl_iface_get_capability_auth_alg(int res, char *strict, 2060 struct wpa_driver_capa *capa, 2061 char *buf, size_t buflen) 2062{ 2063 int ret, first = 1; 2064 char *pos, *end; 2065 size_t len; 2066 2067 pos = buf; 2068 end = pos + buflen; 2069 2070 if (res < 0) { 2071 if (strict) 2072 return 0; 2073 len = os_strlcpy(buf, "OPEN SHARED LEAP", buflen); 2074 if (len >= buflen) 2075 return -1; 2076 return len; 2077 } 2078 2079 if (capa->auth & (WPA_DRIVER_AUTH_OPEN)) { 2080 ret = os_snprintf(pos, end - pos, "%sOPEN", first ? "" : " "); 2081 if (ret < 0 || ret >= end - pos) 2082 return pos - buf; 2083 pos += ret; 2084 first = 0; 2085 } 2086 2087 if (capa->auth & (WPA_DRIVER_AUTH_SHARED)) { 2088 ret = os_snprintf(pos, end - pos, "%sSHARED", 2089 first ? "" : " "); 2090 if (ret < 0 || ret >= end - pos) 2091 return pos - buf; 2092 pos += ret; 2093 first = 0; 2094 } 2095 2096 if (capa->auth & (WPA_DRIVER_AUTH_LEAP)) { 2097 ret = os_snprintf(pos, end - pos, "%sLEAP", first ? "" : " "); 2098 if (ret < 0 || ret >= end - pos) 2099 return pos - buf; 2100 pos += ret; 2101 first = 0; 2102 } 2103 2104 return pos - buf; 2105} 2106 2107 2108static int wpa_supplicant_ctrl_iface_get_capability( 2109 struct wpa_supplicant *wpa_s, const char *_field, char *buf, 2110 size_t buflen) 2111{ 2112 struct wpa_driver_capa capa; 2113 int res; 2114 char *strict; 2115 char field[30]; 2116 size_t len; 2117 2118 /* Determine whether or not strict checking was requested */ 2119 len = os_strlcpy(field, _field, sizeof(field)); 2120 if (len >= sizeof(field)) 2121 return -1; 2122 strict = os_strchr(field, ' '); 2123 if (strict != NULL) { 2124 *strict++ = '\0'; 2125 if (os_strcmp(strict, "strict") != 0) 2126 return -1; 2127 } 2128 2129 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s", 2130 field, strict ? strict : ""); 2131 2132 if (os_strcmp(field, "eap") == 0) { 2133 return eap_get_names(buf, buflen); 2134 } 2135 2136 res = wpa_drv_get_capa(wpa_s, &capa); 2137 2138 if (os_strcmp(field, "pairwise") == 0) 2139 return ctrl_iface_get_capability_pairwise(res, strict, &capa, 2140 buf, buflen); 2141 2142 if (os_strcmp(field, "group") == 0) 2143 return ctrl_iface_get_capability_group(res, strict, &capa, 2144 buf, buflen); 2145 2146 if (os_strcmp(field, "key_mgmt") == 0) 2147 return ctrl_iface_get_capability_key_mgmt(res, strict, &capa, 2148 buf, buflen); 2149 2150 if (os_strcmp(field, "proto") == 0) 2151 return ctrl_iface_get_capability_proto(res, strict, &capa, 2152 buf, buflen); 2153 2154 if (os_strcmp(field, "auth_alg") == 0) 2155 return ctrl_iface_get_capability_auth_alg(res, strict, &capa, 2156 buf, buflen); 2157 2158 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'", 2159 field); 2160 2161 return -1; 2162} 2163 2164 2165#ifdef CONFIG_INTERWORKING 2166static char * anqp_add_hex(char *pos, char *end, const char *title, 2167 struct wpabuf *data) 2168{ 2169 char *start = pos; 2170 size_t i; 2171 int ret; 2172 const u8 *d; 2173 2174 if (data == NULL) 2175 return start; 2176 2177 ret = os_snprintf(pos, end - pos, "%s=", title); 2178 if (ret < 0 || ret >= end - pos) 2179 return start; 2180 pos += ret; 2181 2182 d = wpabuf_head_u8(data); 2183 for (i = 0; i < wpabuf_len(data); i++) { 2184 ret = os_snprintf(pos, end - pos, "%02x", *d++); 2185 if (ret < 0 || ret >= end - pos) 2186 return start; 2187 pos += ret; 2188 } 2189 2190 ret = os_snprintf(pos, end - pos, "\n"); 2191 if (ret < 0 || ret >= end - pos) 2192 return start; 2193 pos += ret; 2194 2195 return pos; 2196} 2197#endif /* CONFIG_INTERWORKING */ 2198 2199 2200static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, 2201 unsigned long mask, char *buf, size_t buflen) 2202{ 2203 size_t i; 2204 int ret; 2205 char *pos, *end; 2206 const u8 *ie, *ie2; 2207 struct os_time now; 2208 2209 os_get_time(&now); 2210 pos = buf; 2211 end = buf + buflen; 2212 2213 if (mask & WPA_BSS_MASK_ID) { 2214 ret = os_snprintf(pos, end - pos, "id=%u\n", bss->id); 2215 if (ret < 0 || ret >= end - pos) 2216 return 0; 2217 pos += ret; 2218 } 2219 2220 if (mask & WPA_BSS_MASK_BSSID) { 2221 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n", 2222 MAC2STR(bss->bssid)); 2223 if (ret < 0 || ret >= end - pos) 2224 return 0; 2225 pos += ret; 2226 } 2227 2228 if (mask & WPA_BSS_MASK_FREQ) { 2229 ret = os_snprintf(pos, end - pos, "freq=%d\n", bss->freq); 2230 if (ret < 0 || ret >= end - pos) 2231 return 0; 2232 pos += ret; 2233 } 2234 2235 if (mask & WPA_BSS_MASK_BEACON_INT) { 2236 ret = os_snprintf(pos, end - pos, "beacon_int=%d\n", 2237 bss->beacon_int); 2238 if (ret < 0 || ret >= end - pos) 2239 return 0; 2240 pos += ret; 2241 } 2242 2243 if (mask & WPA_BSS_MASK_CAPABILITIES) { 2244 ret = os_snprintf(pos, end - pos, "capabilities=0x%04x\n", 2245 bss->caps); 2246 if (ret < 0 || ret >= end - pos) 2247 return 0; 2248 pos += ret; 2249 } 2250 2251 if (mask & WPA_BSS_MASK_QUAL) { 2252 ret = os_snprintf(pos, end - pos, "qual=%d\n", bss->qual); 2253 if (ret < 0 || ret >= end - pos) 2254 return 0; 2255 pos += ret; 2256 } 2257 2258 if (mask & WPA_BSS_MASK_NOISE) { 2259 ret = os_snprintf(pos, end - pos, "noise=%d\n", bss->noise); 2260 if (ret < 0 || ret >= end - pos) 2261 return 0; 2262 pos += ret; 2263 } 2264 2265 if (mask & WPA_BSS_MASK_LEVEL) { 2266 ret = os_snprintf(pos, end - pos, "level=%d\n", bss->level); 2267 if (ret < 0 || ret >= end - pos) 2268 return 0; 2269 pos += ret; 2270 } 2271 2272 if (mask & WPA_BSS_MASK_TSF) { 2273 ret = os_snprintf(pos, end - pos, "tsf=%016llu\n", 2274 (unsigned long long) bss->tsf); 2275 if (ret < 0 || ret >= end - pos) 2276 return 0; 2277 pos += ret; 2278 } 2279 2280 if (mask & WPA_BSS_MASK_AGE) { 2281 ret = os_snprintf(pos, end - pos, "age=%d\n", 2282 (int) (now.sec - bss->last_update.sec)); 2283 if (ret < 0 || ret >= end - pos) 2284 return 0; 2285 pos += ret; 2286 } 2287 2288 if (mask & WPA_BSS_MASK_IE) { 2289 ret = os_snprintf(pos, end - pos, "ie="); 2290 if (ret < 0 || ret >= end - pos) 2291 return 0; 2292 pos += ret; 2293 2294 ie = (const u8 *) (bss + 1); 2295 for (i = 0; i < bss->ie_len; i++) { 2296 ret = os_snprintf(pos, end - pos, "%02x", *ie++); 2297 if (ret < 0 || ret >= end - pos) 2298 return 0; 2299 pos += ret; 2300 } 2301 2302 ret = os_snprintf(pos, end - pos, "\n"); 2303 if (ret < 0 || ret >= end - pos) 2304 return 0; 2305 pos += ret; 2306 } 2307 2308 if (mask & WPA_BSS_MASK_FLAGS) { 2309 ret = os_snprintf(pos, end - pos, "flags="); 2310 if (ret < 0 || ret >= end - pos) 2311 return 0; 2312 pos += ret; 2313 2314 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); 2315 if (ie) 2316 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2317 2 + ie[1]); 2318 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN); 2319 if (ie2) 2320 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2321 2 + ie2[1]); 2322 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss); 2323 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) { 2324 ret = os_snprintf(pos, end - pos, "[WEP]"); 2325 if (ret < 0 || ret >= end - pos) 2326 return 0; 2327 pos += ret; 2328 } 2329 if (bss->caps & IEEE80211_CAP_IBSS) { 2330 ret = os_snprintf(pos, end - pos, "[IBSS]"); 2331 if (ret < 0 || ret >= end - pos) 2332 return 0; 2333 pos += ret; 2334 } 2335 if (bss->caps & IEEE80211_CAP_ESS) { 2336 ret = os_snprintf(pos, end - pos, "[ESS]"); 2337 if (ret < 0 || ret >= end - pos) 2338 return 0; 2339 pos += ret; 2340 } 2341 if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE)) { 2342 ret = os_snprintf(pos, end - pos, "[P2P]"); 2343 if (ret < 0 || ret >= end - pos) 2344 return 0; 2345 pos += ret; 2346 } 2347 2348 ret = os_snprintf(pos, end - pos, "\n"); 2349 if (ret < 0 || ret >= end - pos) 2350 return 0; 2351 pos += ret; 2352 } 2353 2354 if (mask & WPA_BSS_MASK_SSID) { 2355 ret = os_snprintf(pos, end - pos, "ssid=%s\n", 2356 wpa_ssid_txt(bss->ssid, bss->ssid_len)); 2357 if (ret < 0 || ret >= end - pos) 2358 return 0; 2359 pos += ret; 2360 } 2361 2362#ifdef CONFIG_WPS 2363 if (mask & WPA_BSS_MASK_WPS_SCAN) { 2364 ie = (const u8 *) (bss + 1); 2365 ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end); 2366 if (ret < 0 || ret >= end - pos) 2367 return 0; 2368 pos += ret; 2369 } 2370#endif /* CONFIG_WPS */ 2371 2372#ifdef CONFIG_P2P 2373 if (mask & WPA_BSS_MASK_P2P_SCAN) { 2374 ie = (const u8 *) (bss + 1); 2375 ret = wpas_p2p_scan_result_text(ie, bss->ie_len, pos, end); 2376 if (ret < 0 || ret >= end - pos) 2377 return 0; 2378 pos += ret; 2379 } 2380#endif /* CONFIG_P2P */ 2381 2382#ifdef CONFIG_INTERWORKING 2383 if (mask & WPA_BSS_MASK_INTERNETW) { 2384 pos = anqp_add_hex(pos, end, "anqp_venue_name", 2385 bss->anqp_venue_name); 2386 pos = anqp_add_hex(pos, end, "anqp_network_auth_type", 2387 bss->anqp_network_auth_type); 2388 pos = anqp_add_hex(pos, end, "anqp_roaming_consortium", 2389 bss->anqp_roaming_consortium); 2390 pos = anqp_add_hex(pos, end, "anqp_ip_addr_type_availability", 2391 bss->anqp_ip_addr_type_availability); 2392 pos = anqp_add_hex(pos, end, "anqp_nai_realm", 2393 bss->anqp_nai_realm); 2394 pos = anqp_add_hex(pos, end, "anqp_3gpp", bss->anqp_3gpp); 2395 pos = anqp_add_hex(pos, end, "anqp_domain_name", 2396 bss->anqp_domain_name); 2397 } 2398#endif /* CONFIG_INTERWORKING */ 2399 2400 return pos - buf; 2401} 2402 2403static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s, 2404 const char *cmd, char *buf, 2405 size_t buflen) 2406{ 2407 u8 bssid[ETH_ALEN]; 2408 size_t i; 2409 struct wpa_bss *bss = NULL; 2410 struct wpa_bss *bsslast = NULL; 2411 struct dl_list *next; 2412 int ret = 0; 2413 int len; 2414 char *ctmp; 2415 unsigned long mask = WPA_BSS_MASK_ALL; 2416 2417 if (os_strncmp(cmd, "RANGE=", 6) == 0) { 2418 if (os_strncmp(cmd + 6, "ALL", 3) == 0) { 2419 bss = dl_list_first(&wpa_s->bss_id, struct wpa_bss, 2420 list_id); 2421 bsslast = dl_list_last(&wpa_s->bss_id, struct wpa_bss, 2422 list_id); 2423 } else { /* N1-N2 */ 2424 if ((ctmp = os_strchr(cmd + 6, '-')) != NULL) { 2425 int id1, id2; 2426 id1 = atoi(cmd + 6); 2427 bss = wpa_bss_get_id(wpa_s, id1); 2428 id2 = atoi(ctmp + 1); 2429 if (id2 == 0) 2430 bsslast = dl_list_last(&wpa_s->bss_id, 2431 struct wpa_bss, 2432 list_id); 2433 else 2434 bsslast = wpa_bss_get_id(wpa_s, id2); 2435 } else { 2436 wpa_printf(MSG_ERROR, "Wrong range format"); 2437 return 0; 2438 } 2439 } 2440 if ((ctmp = os_strstr(cmd, "MASK=")) != NULL) { 2441 mask = strtoul(ctmp + 5, NULL, 0x10); 2442 if (mask == 0) 2443 mask = WPA_BSS_MASK_ALL; 2444 } 2445 } else if (os_strcmp(cmd, "FIRST") == 0) 2446 bss = dl_list_first(&wpa_s->bss, struct wpa_bss, list); 2447 else if (os_strncmp(cmd, "ID-", 3) == 0) { 2448 i = atoi(cmd + 3); 2449 bss = wpa_bss_get_id(wpa_s, i); 2450 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) { 2451 i = atoi(cmd + 5); 2452 bss = wpa_bss_get_id(wpa_s, i); 2453 if (bss) { 2454 next = bss->list_id.next; 2455 if (next == &wpa_s->bss_id) 2456 bss = NULL; 2457 else 2458 bss = dl_list_entry(next, struct wpa_bss, 2459 list_id); 2460 } 2461#ifdef CONFIG_P2P 2462 } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) { 2463 if (hwaddr_aton(cmd + 13, bssid) == 0) 2464 bss = wpa_bss_get_p2p_dev_addr(wpa_s, bssid); 2465 else 2466 bss = NULL; 2467#endif /* CONFIG_P2P */ 2468 } else if (hwaddr_aton(cmd, bssid) == 0) 2469 bss = wpa_bss_get_bssid(wpa_s, bssid); 2470 else { 2471 struct wpa_bss *tmp; 2472 i = atoi(cmd); 2473 bss = NULL; 2474 dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id) 2475 { 2476 if (i-- == 0) { 2477 bss = tmp; 2478 break; 2479 } 2480 } 2481 } 2482 2483 if (bss == NULL) 2484 return 0; 2485 2486 if (bsslast == NULL) 2487 bsslast = bss; 2488 do { 2489 len = print_bss_info(wpa_s, bss, mask, buf, buflen); 2490 ret += len; 2491 buf += len; 2492 buflen -= len; 2493 if (bss == bsslast) 2494 break; 2495 next = bss->list_id.next; 2496 if (next == &wpa_s->bss_id) 2497 break; 2498 bss = dl_list_entry(next, struct wpa_bss, list_id); 2499 } while (bss && len); 2500 2501 return ret; 2502} 2503 2504 2505static int wpa_supplicant_ctrl_iface_ap_scan( 2506 struct wpa_supplicant *wpa_s, char *cmd) 2507{ 2508 int ap_scan = atoi(cmd); 2509 return wpa_supplicant_set_ap_scan(wpa_s, ap_scan); 2510} 2511 2512 2513static int wpa_supplicant_ctrl_iface_scan_interval( 2514 struct wpa_supplicant *wpa_s, char *cmd) 2515{ 2516 int scan_int = atoi(cmd); 2517 if (scan_int < 0) 2518 return -1; 2519 wpa_s->scan_interval = scan_int; 2520 return 0; 2521} 2522 2523 2524static int wpa_supplicant_ctrl_iface_bss_expire_age( 2525 struct wpa_supplicant *wpa_s, char *cmd) 2526{ 2527 int expire_age = atoi(cmd); 2528 return wpa_supplicant_set_bss_expiration_age(wpa_s, expire_age); 2529} 2530 2531 2532static int wpa_supplicant_ctrl_iface_bss_expire_count( 2533 struct wpa_supplicant *wpa_s, char *cmd) 2534{ 2535 int expire_count = atoi(cmd); 2536 return wpa_supplicant_set_bss_expiration_count(wpa_s, expire_count); 2537} 2538 2539 2540static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s) 2541{ 2542 wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication"); 2543 /* MLME-DELETEKEYS.request */ 2544 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0); 2545 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0); 2546 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0); 2547 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0); 2548#ifdef CONFIG_IEEE80211W 2549 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0); 2550 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0); 2551#endif /* CONFIG_IEEE80211W */ 2552 2553 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL, 2554 0); 2555 /* MLME-SETPROTECTION.request(None) */ 2556 wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid, 2557 MLME_SETPROTECTION_PROTECT_TYPE_NONE, 2558 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE); 2559 wpa_sm_drop_sa(wpa_s->wpa); 2560} 2561 2562 2563static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s, 2564 char *addr) 2565{ 2566#ifdef CONFIG_NO_SCAN_PROCESSING 2567 return -1; 2568#else /* CONFIG_NO_SCAN_PROCESSING */ 2569 u8 bssid[ETH_ALEN]; 2570 struct wpa_bss *bss; 2571 struct wpa_ssid *ssid = wpa_s->current_ssid; 2572 2573 if (hwaddr_aton(addr, bssid)) { 2574 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid " 2575 "address '%s'", addr); 2576 return -1; 2577 } 2578 2579 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM " MACSTR, MAC2STR(bssid)); 2580 2581 bss = wpa_bss_get_bssid(wpa_s, bssid); 2582 if (!bss) { 2583 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: Target AP not found " 2584 "from BSS table"); 2585 return -1; 2586 } 2587 2588 /* 2589 * TODO: Find best network configuration block from configuration to 2590 * allow roaming to other networks 2591 */ 2592 2593 if (!ssid) { 2594 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: No network " 2595 "configuration known for the target AP"); 2596 return -1; 2597 } 2598 2599 wpa_s->reassociate = 1; 2600 wpa_supplicant_connect(wpa_s, bss, ssid); 2601 2602 return 0; 2603#endif /* CONFIG_NO_SCAN_PROCESSING */ 2604} 2605 2606 2607#ifdef CONFIG_P2P 2608static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd) 2609{ 2610 unsigned int timeout = atoi(cmd); 2611 enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL; 2612 u8 dev_id[ETH_ALEN], *_dev_id = NULL; 2613 char *pos; 2614 2615 if (os_strstr(cmd, "type=social")) 2616 type = P2P_FIND_ONLY_SOCIAL; 2617 else if (os_strstr(cmd, "type=progressive")) 2618 type = P2P_FIND_PROGRESSIVE; 2619 2620 pos = os_strstr(cmd, "dev_id="); 2621 if (pos) { 2622 pos += 7; 2623 if (hwaddr_aton(pos, dev_id)) 2624 return -1; 2625 _dev_id = dev_id; 2626 } 2627 2628 return wpas_p2p_find(wpa_s, timeout, type, 0, NULL, _dev_id); 2629} 2630 2631 2632static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd, 2633 char *buf, size_t buflen) 2634{ 2635 u8 addr[ETH_ALEN]; 2636 char *pos, *pos2; 2637 char *pin = NULL; 2638 enum p2p_wps_method wps_method; 2639 int new_pin; 2640 int ret; 2641 int persistent_group; 2642 int join; 2643 int auth; 2644 int go_intent = -1; 2645 int freq = 0; 2646 2647 /* <addr> <"pbc" | "pin" | PIN> [label|display|keypad] [persistent] 2648 * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] */ 2649 2650 if (hwaddr_aton(cmd, addr)) 2651 return -1; 2652 2653 pos = cmd + 17; 2654 if (*pos != ' ') 2655 return -1; 2656 pos++; 2657 2658 persistent_group = os_strstr(pos, " persistent") != NULL; 2659 join = os_strstr(pos, " join") != NULL; 2660 auth = os_strstr(pos, " auth") != NULL; 2661 2662 pos2 = os_strstr(pos, " go_intent="); 2663 if (pos2) { 2664 pos2 += 11; 2665 go_intent = atoi(pos2); 2666 if (go_intent < 0 || go_intent > 15) 2667 return -1; 2668 } 2669 2670 pos2 = os_strstr(pos, " freq="); 2671 if (pos2) { 2672 pos2 += 6; 2673 freq = atoi(pos2); 2674 if (freq <= 0) 2675 return -1; 2676 } 2677 2678 if (os_strncmp(pos, "pin", 3) == 0) { 2679 /* Request random PIN (to be displayed) and enable the PIN */ 2680 wps_method = WPS_PIN_DISPLAY; 2681 } else if (os_strncmp(pos, "pbc", 3) == 0) { 2682 wps_method = WPS_PBC; 2683 } else { 2684 pin = pos; 2685 pos = os_strchr(pin, ' '); 2686 wps_method = WPS_PIN_KEYPAD; 2687 if (pos) { 2688 *pos++ = '\0'; 2689 if (os_strncmp(pos, "display", 7) == 0) 2690 wps_method = WPS_PIN_DISPLAY; 2691 } 2692 } 2693 2694 new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method, 2695 persistent_group, join, auth, go_intent, 2696 freq); 2697 if (new_pin == -2) { 2698 os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25); 2699 return 25; 2700 } 2701 if (new_pin == -3) { 2702 os_memcpy(buf, "FAIL-CHANNEL-UNSUPPORTED\n", 25); 2703 return 25; 2704 } 2705 if (new_pin < 0) 2706 return -1; 2707 if (wps_method == WPS_PIN_DISPLAY && pin == NULL) { 2708 ret = os_snprintf(buf, buflen, "%08d", new_pin); 2709 if (ret < 0 || (size_t) ret >= buflen) 2710 return -1; 2711 return ret; 2712 } 2713 2714 os_memcpy(buf, "OK\n", 3); 2715 return 3; 2716} 2717 2718 2719static int p2p_ctrl_listen(struct wpa_supplicant *wpa_s, char *cmd) 2720{ 2721 unsigned int timeout = atoi(cmd); 2722 return wpas_p2p_listen(wpa_s, timeout); 2723} 2724 2725 2726static int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd) 2727{ 2728 u8 addr[ETH_ALEN]; 2729 char *pos; 2730 2731 /* <addr> <config method> [join] */ 2732 2733 if (hwaddr_aton(cmd, addr)) 2734 return -1; 2735 2736 pos = cmd + 17; 2737 if (*pos != ' ') 2738 return -1; 2739 pos++; 2740 2741 return wpas_p2p_prov_disc(wpa_s, addr, pos, 2742 os_strstr(pos, "join") != NULL); 2743} 2744 2745 2746static int p2p_get_passphrase(struct wpa_supplicant *wpa_s, char *buf, 2747 size_t buflen) 2748{ 2749 struct wpa_ssid *ssid = wpa_s->current_ssid; 2750 2751 if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO || 2752 ssid->passphrase == NULL) 2753 return -1; 2754 2755 os_strlcpy(buf, ssid->passphrase, buflen); 2756 return os_strlen(buf); 2757} 2758 2759 2760static int p2p_ctrl_serv_disc_req(struct wpa_supplicant *wpa_s, char *cmd, 2761 char *buf, size_t buflen) 2762{ 2763 u64 ref; 2764 int res; 2765 u8 dst_buf[ETH_ALEN], *dst; 2766 struct wpabuf *tlvs; 2767 char *pos; 2768 size_t len; 2769 2770 if (hwaddr_aton(cmd, dst_buf)) 2771 return -1; 2772 dst = dst_buf; 2773 if (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 && 2774 dst[3] == 0 && dst[4] == 0 && dst[5] == 0) 2775 dst = NULL; 2776 pos = cmd + 17; 2777 if (*pos != ' ') 2778 return -1; 2779 pos++; 2780 2781 if (os_strncmp(pos, "upnp ", 5) == 0) { 2782 u8 version; 2783 pos += 5; 2784 if (hexstr2bin(pos, &version, 1) < 0) 2785 return -1; 2786 pos += 2; 2787 if (*pos != ' ') 2788 return -1; 2789 pos++; 2790 ref = wpas_p2p_sd_request_upnp(wpa_s, dst, version, pos); 2791 } else { 2792 len = os_strlen(pos); 2793 if (len & 1) 2794 return -1; 2795 len /= 2; 2796 tlvs = wpabuf_alloc(len); 2797 if (tlvs == NULL) 2798 return -1; 2799 if (hexstr2bin(pos, wpabuf_put(tlvs, len), len) < 0) { 2800 wpabuf_free(tlvs); 2801 return -1; 2802 } 2803 2804 ref = wpas_p2p_sd_request(wpa_s, dst, tlvs); 2805 wpabuf_free(tlvs); 2806 } 2807 if (ref == 0) 2808 return -1; 2809 res = os_snprintf(buf, buflen, "%llx", (long long unsigned) ref); 2810 if (res < 0 || (unsigned) res >= buflen) 2811 return -1; 2812 return res; 2813} 2814 2815 2816static int p2p_ctrl_serv_disc_cancel_req(struct wpa_supplicant *wpa_s, 2817 char *cmd) 2818{ 2819 long long unsigned val; 2820 u64 req; 2821 if (sscanf(cmd, "%llx", &val) != 1) 2822 return -1; 2823 req = val; 2824 return wpas_p2p_sd_cancel_request(wpa_s, req); 2825} 2826 2827 2828static int p2p_ctrl_serv_disc_resp(struct wpa_supplicant *wpa_s, char *cmd) 2829{ 2830 int freq; 2831 u8 dst[ETH_ALEN]; 2832 u8 dialog_token; 2833 struct wpabuf *resp_tlvs; 2834 char *pos, *pos2; 2835 size_t len; 2836 2837 pos = os_strchr(cmd, ' '); 2838 if (pos == NULL) 2839 return -1; 2840 *pos++ = '\0'; 2841 freq = atoi(cmd); 2842 if (freq == 0) 2843 return -1; 2844 2845 if (hwaddr_aton(pos, dst)) 2846 return -1; 2847 pos += 17; 2848 if (*pos != ' ') 2849 return -1; 2850 pos++; 2851 2852 pos2 = os_strchr(pos, ' '); 2853 if (pos2 == NULL) 2854 return -1; 2855 *pos2++ = '\0'; 2856 dialog_token = atoi(pos); 2857 2858 len = os_strlen(pos2); 2859 if (len & 1) 2860 return -1; 2861 len /= 2; 2862 resp_tlvs = wpabuf_alloc(len); 2863 if (resp_tlvs == NULL) 2864 return -1; 2865 if (hexstr2bin(pos2, wpabuf_put(resp_tlvs, len), len) < 0) { 2866 wpabuf_free(resp_tlvs); 2867 return -1; 2868 } 2869 2870 wpas_p2p_sd_response(wpa_s, freq, dst, dialog_token, resp_tlvs); 2871 wpabuf_free(resp_tlvs); 2872 return 0; 2873} 2874 2875 2876static int p2p_ctrl_serv_disc_external(struct wpa_supplicant *wpa_s, 2877 char *cmd) 2878{ 2879 wpa_s->p2p_sd_over_ctrl_iface = atoi(cmd); 2880 return 0; 2881} 2882 2883 2884static int p2p_ctrl_service_add_bonjour(struct wpa_supplicant *wpa_s, 2885 char *cmd) 2886{ 2887 char *pos; 2888 size_t len; 2889 struct wpabuf *query, *resp; 2890 2891 pos = os_strchr(cmd, ' '); 2892 if (pos == NULL) 2893 return -1; 2894 *pos++ = '\0'; 2895 2896 len = os_strlen(cmd); 2897 if (len & 1) 2898 return -1; 2899 len /= 2; 2900 query = wpabuf_alloc(len); 2901 if (query == NULL) 2902 return -1; 2903 if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) { 2904 wpabuf_free(query); 2905 return -1; 2906 } 2907 2908 len = os_strlen(pos); 2909 if (len & 1) { 2910 wpabuf_free(query); 2911 return -1; 2912 } 2913 len /= 2; 2914 resp = wpabuf_alloc(len); 2915 if (resp == NULL) { 2916 wpabuf_free(query); 2917 return -1; 2918 } 2919 if (hexstr2bin(pos, wpabuf_put(resp, len), len) < 0) { 2920 wpabuf_free(query); 2921 wpabuf_free(resp); 2922 return -1; 2923 } 2924 2925 if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0) { 2926 wpabuf_free(query); 2927 wpabuf_free(resp); 2928 return -1; 2929 } 2930 return 0; 2931} 2932 2933 2934static int p2p_ctrl_service_add_upnp(struct wpa_supplicant *wpa_s, char *cmd) 2935{ 2936 char *pos; 2937 u8 version; 2938 2939 pos = os_strchr(cmd, ' '); 2940 if (pos == NULL) 2941 return -1; 2942 *pos++ = '\0'; 2943 2944 if (hexstr2bin(cmd, &version, 1) < 0) 2945 return -1; 2946 2947 return wpas_p2p_service_add_upnp(wpa_s, version, pos); 2948} 2949 2950 2951static int p2p_ctrl_service_add(struct wpa_supplicant *wpa_s, char *cmd) 2952{ 2953 char *pos; 2954 2955 pos = os_strchr(cmd, ' '); 2956 if (pos == NULL) 2957 return -1; 2958 *pos++ = '\0'; 2959 2960 if (os_strcmp(cmd, "bonjour") == 0) 2961 return p2p_ctrl_service_add_bonjour(wpa_s, pos); 2962 if (os_strcmp(cmd, "upnp") == 0) 2963 return p2p_ctrl_service_add_upnp(wpa_s, pos); 2964 wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd); 2965 return -1; 2966} 2967 2968 2969static int p2p_ctrl_service_del_bonjour(struct wpa_supplicant *wpa_s, 2970 char *cmd) 2971{ 2972 size_t len; 2973 struct wpabuf *query; 2974 int ret; 2975 2976 len = os_strlen(cmd); 2977 if (len & 1) 2978 return -1; 2979 len /= 2; 2980 query = wpabuf_alloc(len); 2981 if (query == NULL) 2982 return -1; 2983 if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) { 2984 wpabuf_free(query); 2985 return -1; 2986 } 2987 2988 ret = wpas_p2p_service_del_bonjour(wpa_s, query); 2989 wpabuf_free(query); 2990 return ret; 2991} 2992 2993 2994static int p2p_ctrl_service_del_upnp(struct wpa_supplicant *wpa_s, char *cmd) 2995{ 2996 char *pos; 2997 u8 version; 2998 2999 pos = os_strchr(cmd, ' '); 3000 if (pos == NULL) 3001 return -1; 3002 *pos++ = '\0'; 3003 3004 if (hexstr2bin(cmd, &version, 1) < 0) 3005 return -1; 3006 3007 return wpas_p2p_service_del_upnp(wpa_s, version, pos); 3008} 3009 3010 3011static int p2p_ctrl_service_del(struct wpa_supplicant *wpa_s, char *cmd) 3012{ 3013 char *pos; 3014 3015 pos = os_strchr(cmd, ' '); 3016 if (pos == NULL) 3017 return -1; 3018 *pos++ = '\0'; 3019 3020 if (os_strcmp(cmd, "bonjour") == 0) 3021 return p2p_ctrl_service_del_bonjour(wpa_s, pos); 3022 if (os_strcmp(cmd, "upnp") == 0) 3023 return p2p_ctrl_service_del_upnp(wpa_s, pos); 3024 wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd); 3025 return -1; 3026} 3027 3028 3029static int p2p_ctrl_reject(struct wpa_supplicant *wpa_s, char *cmd) 3030{ 3031 u8 addr[ETH_ALEN]; 3032 3033 /* <addr> */ 3034 3035 if (hwaddr_aton(cmd, addr)) 3036 return -1; 3037 3038 return wpas_p2p_reject(wpa_s, addr); 3039} 3040 3041 3042static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd) 3043{ 3044 char *pos; 3045 int id; 3046 struct wpa_ssid *ssid; 3047 u8 peer[ETH_ALEN]; 3048 3049 id = atoi(cmd); 3050 pos = os_strstr(cmd, " peer="); 3051 if (pos) { 3052 pos += 6; 3053 if (hwaddr_aton(pos, peer)) 3054 return -1; 3055 } 3056 ssid = wpa_config_get_network(wpa_s->conf, id); 3057 if (ssid == NULL || ssid->disabled != 2) { 3058 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 3059 "for persistent P2P group", 3060 id); 3061 return -1; 3062 } 3063 3064 return wpas_p2p_invite(wpa_s, pos ? peer : NULL, ssid, NULL); 3065} 3066 3067 3068static int p2p_ctrl_invite_group(struct wpa_supplicant *wpa_s, char *cmd) 3069{ 3070 char *pos; 3071 u8 peer[ETH_ALEN], go_dev_addr[ETH_ALEN], *go_dev = NULL; 3072 3073 pos = os_strstr(cmd, " peer="); 3074 if (!pos) 3075 return -1; 3076 3077 *pos = '\0'; 3078 pos += 6; 3079 if (hwaddr_aton(pos, peer)) { 3080 wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'", pos); 3081 return -1; 3082 } 3083 3084 pos = os_strstr(pos, " go_dev_addr="); 3085 if (pos) { 3086 pos += 13; 3087 if (hwaddr_aton(pos, go_dev_addr)) { 3088 wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'", 3089 pos); 3090 return -1; 3091 } 3092 go_dev = go_dev_addr; 3093 } 3094 3095 return wpas_p2p_invite_group(wpa_s, cmd, peer, go_dev); 3096} 3097 3098 3099static int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd) 3100{ 3101 if (os_strncmp(cmd, "persistent=", 11) == 0) 3102 return p2p_ctrl_invite_persistent(wpa_s, cmd + 11); 3103 if (os_strncmp(cmd, "group=", 6) == 0) 3104 return p2p_ctrl_invite_group(wpa_s, cmd + 6); 3105 3106 return -1; 3107} 3108 3109 3110static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s, 3111 char *cmd, int freq) 3112{ 3113 int id; 3114 struct wpa_ssid *ssid; 3115 3116 id = atoi(cmd); 3117 ssid = wpa_config_get_network(wpa_s->conf, id); 3118 if (ssid == NULL || ssid->disabled != 2) { 3119 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 3120 "for persistent P2P group", 3121 id); 3122 return -1; 3123 } 3124 3125 return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq); 3126} 3127 3128 3129static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd) 3130{ 3131 int freq = 0; 3132 char *pos; 3133 3134 pos = os_strstr(cmd, "freq="); 3135 if (pos) 3136 freq = atoi(pos + 5); 3137 3138 if (os_strncmp(cmd, "persistent=", 11) == 0) 3139 return p2p_ctrl_group_add_persistent(wpa_s, cmd + 11, freq); 3140 if (os_strcmp(cmd, "persistent") == 0 || 3141 os_strncmp(cmd, "persistent ", 11) == 0) 3142 return wpas_p2p_group_add(wpa_s, 1, freq); 3143 if (os_strncmp(cmd, "freq=", 5) == 0) 3144 return wpas_p2p_group_add(wpa_s, 0, freq); 3145 3146 wpa_printf(MSG_DEBUG, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'", 3147 cmd); 3148 return -1; 3149} 3150 3151 3152static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd, 3153 char *buf, size_t buflen) 3154{ 3155 u8 addr[ETH_ALEN], *addr_ptr; 3156 int next, res; 3157 const struct p2p_peer_info *info; 3158 char *pos, *end; 3159 char devtype[WPS_DEV_TYPE_BUFSIZE]; 3160 struct wpa_ssid *ssid; 3161 3162 if (!wpa_s->global->p2p) 3163 return -1; 3164 3165 if (os_strcmp(cmd, "FIRST") == 0) { 3166 addr_ptr = NULL; 3167 next = 0; 3168 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) { 3169 if (hwaddr_aton(cmd + 5, addr) < 0) 3170 return -1; 3171 addr_ptr = addr; 3172 next = 1; 3173 } else { 3174 if (hwaddr_aton(cmd, addr) < 0) 3175 return -1; 3176 addr_ptr = addr; 3177 next = 0; 3178 } 3179 3180 info = p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next); 3181 if (info == NULL) 3182 return -1; 3183 3184 pos = buf; 3185 end = buf + buflen; 3186 3187 res = os_snprintf(pos, end - pos, MACSTR "\n" 3188 "pri_dev_type=%s\n" 3189 "device_name=%s\n" 3190 "manufacturer=%s\n" 3191 "model_name=%s\n" 3192 "model_number=%s\n" 3193 "serial_number=%s\n" 3194 "config_methods=0x%x\n" 3195 "dev_capab=0x%x\n" 3196 "group_capab=0x%x\n" 3197 "level=%d\n", 3198 MAC2STR(info->p2p_device_addr), 3199 wps_dev_type_bin2str(info->pri_dev_type, 3200 devtype, sizeof(devtype)), 3201 info->device_name, 3202 info->manufacturer, 3203 info->model_name, 3204 info->model_number, 3205 info->serial_number, 3206 info->config_methods, 3207 info->dev_capab, 3208 info->group_capab, 3209 info->level); 3210 if (res < 0 || res >= end - pos) 3211 return pos - buf; 3212 pos += res; 3213 3214 ssid = wpas_p2p_get_persistent(wpa_s, info->p2p_device_addr, NULL, 0); 3215 if (ssid) { 3216 res = os_snprintf(pos, end - pos, "persistent=%d\n", ssid->id); 3217 if (res < 0 || res >= end - pos) 3218 return pos - buf; 3219 pos += res; 3220 } 3221 3222 res = p2p_get_peer_info_txt(info, pos, end - pos); 3223 if (res < 0) 3224 return pos - buf; 3225 pos += res; 3226 3227 return pos - buf; 3228} 3229 3230 3231static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd) 3232{ 3233 char *param; 3234 3235 if (wpa_s->global->p2p == NULL) 3236 return -1; 3237 3238 param = os_strchr(cmd, ' '); 3239 if (param == NULL) 3240 return -1; 3241 *param++ = '\0'; 3242 3243 if (os_strcmp(cmd, "discoverability") == 0) { 3244 p2p_set_client_discoverability(wpa_s->global->p2p, 3245 atoi(param)); 3246 return 0; 3247 } 3248 3249 if (os_strcmp(cmd, "managed") == 0) { 3250 p2p_set_managed_oper(wpa_s->global->p2p, atoi(param)); 3251 return 0; 3252 } 3253 3254 if (os_strcmp(cmd, "listen_channel") == 0) { 3255 return p2p_set_listen_channel(wpa_s->global->p2p, 81, 3256 atoi(param)); 3257 } 3258 3259 if (os_strcmp(cmd, "ssid_postfix") == 0) { 3260 return p2p_set_ssid_postfix(wpa_s->global->p2p, (u8 *) param, 3261 os_strlen(param)); 3262 } 3263 3264 if (os_strcmp(cmd, "noa") == 0) { 3265 char *pos; 3266 int count, start, duration; 3267 /* GO NoA parameters: count,start_offset(ms),duration(ms) */ 3268 count = atoi(param); 3269 pos = os_strchr(param, ','); 3270 if (pos == NULL) 3271 return -1; 3272 pos++; 3273 start = atoi(pos); 3274 pos = os_strchr(pos, ','); 3275 if (pos == NULL) 3276 return -1; 3277 pos++; 3278 duration = atoi(pos); 3279 if (count < 0 || count > 255 || start < 0 || duration < 0) 3280 return -1; 3281 if (count == 0 && duration > 0) 3282 return -1; 3283 wpa_printf(MSG_DEBUG, "CTRL_IFACE: P2P_SET GO NoA: count=%d " 3284 "start=%d duration=%d", count, start, duration); 3285 return wpas_p2p_set_noa(wpa_s, count, start, duration); 3286 } 3287 3288 if (os_strcmp(cmd, "ps") == 0) 3289 return wpa_drv_set_p2p_powersave(wpa_s, atoi(param), -1, -1); 3290 3291 if (os_strcmp(cmd, "oppps") == 0) 3292 return wpa_drv_set_p2p_powersave(wpa_s, -1, atoi(param), -1); 3293 3294 if (os_strcmp(cmd, "ctwindow") == 0) 3295 return wpa_drv_set_p2p_powersave(wpa_s, -1, -1, atoi(param)); 3296 3297 if (os_strcmp(cmd, "disabled") == 0) { 3298 wpa_s->global->p2p_disabled = atoi(param); 3299 wpa_printf(MSG_DEBUG, "P2P functionality %s", 3300 wpa_s->global->p2p_disabled ? 3301 "disabled" : "enabled"); 3302 if (wpa_s->global->p2p_disabled) { 3303 wpas_p2p_stop_find(wpa_s); 3304 os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); 3305 p2p_flush(wpa_s->global->p2p); 3306 } 3307 return 0; 3308 } 3309#ifdef ANDROID_P2P 3310 if (os_strcmp(cmd, "conc_pref") == 0) { 3311 if (os_strcmp(param, "sta") == 0) 3312 wpa_s->global->conc_pref = WPA_CONC_PREF_STA; 3313 else if (os_strcmp(param, "p2p") == 0) 3314 wpa_s->global->conc_pref = WPA_CONC_PREF_P2P; 3315 else { 3316 wpa_printf(MSG_INFO, "Invalid conc_pref value"); 3317 return -1; 3318 } 3319 wpa_printf(MSG_DEBUG, "Single channel concurrency preference: " 3320 "%s", param); 3321 return 0; 3322 } 3323#endif 3324 if (os_strcmp(cmd, "force_long_sd") == 0) { 3325 wpa_s->force_long_sd = atoi(param); 3326 return 0; 3327 } 3328 3329 if (os_strcmp(cmd, "peer_filter") == 0) { 3330 u8 addr[ETH_ALEN]; 3331 if (hwaddr_aton(param, addr)) 3332 return -1; 3333 p2p_set_peer_filter(wpa_s->global->p2p, addr); 3334 return 0; 3335 } 3336 3337 if (os_strcmp(cmd, "cross_connect") == 0) 3338 return wpas_p2p_set_cross_connect(wpa_s, atoi(param)); 3339 3340 if (os_strcmp(cmd, "go_apsd") == 0) { 3341 if (os_strcmp(param, "disable") == 0) 3342 wpa_s->set_ap_uapsd = 0; 3343 else { 3344 wpa_s->set_ap_uapsd = 1; 3345 wpa_s->ap_uapsd = atoi(param); 3346 } 3347 return 0; 3348 } 3349 3350 if (os_strcmp(cmd, "client_apsd") == 0) { 3351 if (os_strcmp(param, "disable") == 0) 3352 wpa_s->set_sta_uapsd = 0; 3353 else { 3354 int be, bk, vi, vo; 3355 char *pos; 3356 /* format: BE,BK,VI,VO;max SP Length */ 3357 be = atoi(param); 3358 pos = os_strchr(param, ','); 3359 if (pos == NULL) 3360 return -1; 3361 pos++; 3362 bk = atoi(pos); 3363 pos = os_strchr(pos, ','); 3364 if (pos == NULL) 3365 return -1; 3366 pos++; 3367 vi = atoi(pos); 3368 pos = os_strchr(pos, ','); 3369 if (pos == NULL) 3370 return -1; 3371 pos++; 3372 vo = atoi(pos); 3373 /* ignore max SP Length for now */ 3374 3375 wpa_s->set_sta_uapsd = 1; 3376 wpa_s->sta_uapsd = 0; 3377 if (be) 3378 wpa_s->sta_uapsd |= BIT(0); 3379 if (bk) 3380 wpa_s->sta_uapsd |= BIT(1); 3381 if (vi) 3382 wpa_s->sta_uapsd |= BIT(2); 3383 if (vo) 3384 wpa_s->sta_uapsd |= BIT(3); 3385 } 3386 return 0; 3387 } 3388 3389 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'", 3390 cmd); 3391 3392 return -1; 3393} 3394 3395 3396static int p2p_ctrl_presence_req(struct wpa_supplicant *wpa_s, char *cmd) 3397{ 3398 char *pos, *pos2; 3399 unsigned int dur1 = 0, int1 = 0, dur2 = 0, int2 = 0; 3400 3401 if (cmd[0]) { 3402 pos = os_strchr(cmd, ' '); 3403 if (pos == NULL) 3404 return -1; 3405 *pos++ = '\0'; 3406 dur1 = atoi(cmd); 3407 3408 pos2 = os_strchr(pos, ' '); 3409 if (pos2) 3410 *pos2++ = '\0'; 3411 int1 = atoi(pos); 3412 } else 3413 pos2 = NULL; 3414 3415 if (pos2) { 3416 pos = os_strchr(pos2, ' '); 3417 if (pos == NULL) 3418 return -1; 3419 *pos++ = '\0'; 3420 dur2 = atoi(pos2); 3421 int2 = atoi(pos); 3422 } 3423 3424 return wpas_p2p_presence_req(wpa_s, dur1, int1, dur2, int2); 3425} 3426 3427 3428static int p2p_ctrl_ext_listen(struct wpa_supplicant *wpa_s, char *cmd) 3429{ 3430 char *pos; 3431 unsigned int period = 0, interval = 0; 3432 3433 if (cmd[0]) { 3434 pos = os_strchr(cmd, ' '); 3435 if (pos == NULL) 3436 return -1; 3437 *pos++ = '\0'; 3438 period = atoi(cmd); 3439 interval = atoi(pos); 3440 } 3441 3442 return wpas_p2p_ext_listen(wpa_s, period, interval); 3443} 3444 3445#endif /* CONFIG_P2P */ 3446 3447 3448#ifdef CONFIG_INTERWORKING 3449static int ctrl_interworking_connect(struct wpa_supplicant *wpa_s, char *dst) 3450{ 3451 u8 bssid[ETH_ALEN]; 3452 struct wpa_bss *bss; 3453 3454 if (hwaddr_aton(dst, bssid)) { 3455 wpa_printf(MSG_DEBUG, "Invalid BSSID '%s'", dst); 3456 return -1; 3457 } 3458 3459 bss = wpa_bss_get_bssid(wpa_s, bssid); 3460 if (bss == NULL) { 3461 wpa_printf(MSG_DEBUG, "Could not find BSS " MACSTR, 3462 MAC2STR(bssid)); 3463 return -1; 3464 } 3465 3466 return interworking_connect(wpa_s, bss); 3467} 3468 3469 3470static int get_anqp(struct wpa_supplicant *wpa_s, char *dst) 3471{ 3472 u8 dst_addr[ETH_ALEN]; 3473 int used; 3474 char *pos; 3475#define MAX_ANQP_INFO_ID 100 3476 u16 id[MAX_ANQP_INFO_ID]; 3477 size_t num_id = 0; 3478 3479 used = hwaddr_aton2(dst, dst_addr); 3480 if (used < 0) 3481 return -1; 3482 pos = dst + used; 3483 while (num_id < MAX_ANQP_INFO_ID) { 3484 id[num_id] = atoi(pos); 3485 if (id[num_id]) 3486 num_id++; 3487 pos = os_strchr(pos + 1, ','); 3488 if (pos == NULL) 3489 break; 3490 pos++; 3491 } 3492 3493 if (num_id == 0) 3494 return -1; 3495 3496 return anqp_send_req(wpa_s, dst_addr, id, num_id); 3497} 3498#endif /* CONFIG_INTERWORKING */ 3499 3500 3501static int wpa_supplicant_ctrl_iface_sta_autoconnect( 3502 struct wpa_supplicant *wpa_s, char *cmd) 3503{ 3504 wpa_s->auto_reconnect_disabled = atoi(cmd) == 0 ? 1 : 0; 3505 return 0; 3506} 3507 3508 3509static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf, 3510 size_t buflen) 3511{ 3512 struct wpa_signal_info si; 3513 int ret; 3514 3515 ret = wpa_drv_signal_poll(wpa_s, &si); 3516 if (ret) 3517 return -1; 3518 3519 ret = os_snprintf(buf, buflen, "RSSI=%d\nLINKSPEED=%d\n" 3520 "NOISE=%d\nFREQUENCY=%u\n", 3521 si.current_signal, si.current_txrate / 1000, 3522 si.current_noise, si.frequency); 3523 if (ret < 0 || (unsigned int) ret > buflen) 3524 return -1; 3525 return ret; 3526} 3527 3528#ifdef ANDROID 3529static int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s, char *cmd, 3530 char *buf, size_t buflen) 3531{ 3532 int ret; 3533 3534 ret = wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen); 3535 if (ret == 0) 3536 ret = sprintf(buf, "%s\n", "OK"); 3537 return ret; 3538} 3539#endif 3540 3541char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, 3542 char *buf, size_t *resp_len) 3543{ 3544 char *reply; 3545 const int reply_size = 4096; 3546 int ctrl_rsp = 0; 3547 int reply_len; 3548 3549 if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 || 3550 os_strncmp(buf, "SET_NETWORK ", 12) == 0) { 3551 wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface", 3552 (const u8 *) buf, os_strlen(buf)); 3553 } else { 3554 int level = MSG_DEBUG; 3555 if (os_strcmp(buf, "PING") == 0) 3556 level = MSG_EXCESSIVE; 3557 wpa_hexdump_ascii(level, "RX ctrl_iface", 3558 (const u8 *) buf, os_strlen(buf)); 3559 } 3560 3561 reply = os_malloc(reply_size); 3562 if (reply == NULL) { 3563 *resp_len = 1; 3564 return NULL; 3565 } 3566 3567 os_memcpy(reply, "OK\n", 3); 3568 reply_len = 3; 3569 3570 if (os_strcmp(buf, "PING") == 0) { 3571 os_memcpy(reply, "PONG\n", 5); 3572 reply_len = 5; 3573 } else if (os_strncmp(buf, "RELOG", 5) == 0) { 3574 if (wpa_debug_reopen_file() < 0) 3575 reply_len = -1; 3576 } else if (os_strncmp(buf, "NOTE ", 5) == 0) { 3577 wpa_printf(MSG_INFO, "NOTE: %s", buf + 5); 3578 } else if (os_strcmp(buf, "MIB") == 0) { 3579 reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); 3580 if (reply_len >= 0) { 3581 int res; 3582 res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len, 3583 reply_size - reply_len); 3584 if (res < 0) 3585 reply_len = -1; 3586 else 3587 reply_len += res; 3588 } 3589 } else if (os_strncmp(buf, "STATUS", 6) == 0) { 3590 reply_len = wpa_supplicant_ctrl_iface_status( 3591 wpa_s, buf + 6, reply, reply_size); 3592 } else if (os_strcmp(buf, "PMKSA") == 0) { 3593 reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, reply, 3594 reply_size); 3595 } else if (os_strncmp(buf, "SET ", 4) == 0) { 3596 if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4)) 3597 reply_len = -1; 3598 } else if (os_strncmp(buf, "GET ", 4) == 0) { 3599 reply_len = wpa_supplicant_ctrl_iface_get(wpa_s, buf + 4, 3600 reply, reply_size); 3601 } else if (os_strcmp(buf, "LOGON") == 0) { 3602 eapol_sm_notify_logoff(wpa_s->eapol, FALSE); 3603 } else if (os_strcmp(buf, "LOGOFF") == 0) { 3604 eapol_sm_notify_logoff(wpa_s->eapol, TRUE); 3605 } else if (os_strcmp(buf, "REASSOCIATE") == 0) { 3606 wpa_s->normal_scans = 0; 3607 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) 3608 reply_len = -1; 3609 else { 3610 wpa_s->disconnected = 0; 3611 wpa_s->reassociate = 1; 3612 wpa_supplicant_req_scan(wpa_s, 0, 0); 3613 } 3614 } else if (os_strcmp(buf, "RECONNECT") == 0) { 3615 wpa_s->normal_scans = 0; 3616 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) 3617 reply_len = -1; 3618 else if (wpa_s->disconnected) { 3619 wpa_s->disconnected = 0; 3620 wpa_s->reassociate = 1; 3621 wpa_supplicant_req_scan(wpa_s, 0, 0); 3622 } 3623#ifdef IEEE8021X_EAPOL 3624 } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) { 3625 if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8)) 3626 reply_len = -1; 3627#endif /* IEEE8021X_EAPOL */ 3628#ifdef CONFIG_PEERKEY 3629 } else if (os_strncmp(buf, "STKSTART ", 9) == 0) { 3630 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9)) 3631 reply_len = -1; 3632#endif /* CONFIG_PEERKEY */ 3633#ifdef CONFIG_IEEE80211R 3634 } else if (os_strncmp(buf, "FT_DS ", 6) == 0) { 3635 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6)) 3636 reply_len = -1; 3637#endif /* CONFIG_IEEE80211R */ 3638#ifdef CONFIG_WPS 3639 } else if (os_strcmp(buf, "WPS_PBC") == 0) { 3640 int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, NULL); 3641 if (res == -2) { 3642 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17); 3643 reply_len = 17; 3644 } else if (res) 3645 reply_len = -1; 3646 } else if (os_strncmp(buf, "WPS_PBC ", 8) == 0) { 3647 int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, buf + 8); 3648 if (res == -2) { 3649 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17); 3650 reply_len = 17; 3651 } else if (res) 3652 reply_len = -1; 3653 } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) { 3654 reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8, 3655 reply, 3656 reply_size); 3657 } else if (os_strncmp(buf, "WPS_CHECK_PIN ", 14) == 0) { 3658 reply_len = wpa_supplicant_ctrl_iface_wps_check_pin( 3659 wpa_s, buf + 14, reply, reply_size); 3660 } else if (os_strcmp(buf, "WPS_CANCEL") == 0) { 3661 if (wpas_wps_cancel(wpa_s)) 3662 reply_len = -1; 3663#ifdef CONFIG_WPS_OOB 3664 } else if (os_strncmp(buf, "WPS_OOB ", 8) == 0) { 3665 if (wpa_supplicant_ctrl_iface_wps_oob(wpa_s, buf + 8)) 3666 reply_len = -1; 3667#endif /* CONFIG_WPS_OOB */ 3668 } else if (os_strncmp(buf, "WPS_REG ", 8) == 0) { 3669 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8)) 3670 reply_len = -1; 3671#ifdef CONFIG_AP 3672 } else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) { 3673 reply_len = wpa_supplicant_ctrl_iface_wps_ap_pin( 3674 wpa_s, buf + 11, reply, reply_size); 3675#endif /* CONFIG_AP */ 3676#ifdef CONFIG_WPS_ER 3677 } else if (os_strcmp(buf, "WPS_ER_START") == 0) { 3678 if (wpas_wps_er_start(wpa_s, NULL)) 3679 reply_len = -1; 3680 } else if (os_strncmp(buf, "WPS_ER_START ", 13) == 0) { 3681 if (wpas_wps_er_start(wpa_s, buf + 13)) 3682 reply_len = -1; 3683 } else if (os_strcmp(buf, "WPS_ER_STOP") == 0) { 3684 if (wpas_wps_er_stop(wpa_s)) 3685 reply_len = -1; 3686 } else if (os_strncmp(buf, "WPS_ER_PIN ", 11) == 0) { 3687 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s, buf + 11)) 3688 reply_len = -1; 3689 } else if (os_strncmp(buf, "WPS_ER_PBC ", 11) == 0) { 3690 int ret = wpas_wps_er_pbc(wpa_s, buf + 11); 3691 if (ret == -2) { 3692 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17); 3693 reply_len = 17; 3694 } else if (ret == -3) { 3695 os_memcpy(reply, "FAIL-UNKNOWN-UUID\n", 18); 3696 reply_len = 18; 3697 } else if (ret == -4) { 3698 os_memcpy(reply, "FAIL-NO-AP-SETTINGS\n", 20); 3699 reply_len = 20; 3700 } else if (ret) 3701 reply_len = -1; 3702 } else if (os_strncmp(buf, "WPS_ER_LEARN ", 13) == 0) { 3703 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s, buf + 13)) 3704 reply_len = -1; 3705 } else if (os_strncmp(buf, "WPS_ER_SET_CONFIG ", 18) == 0) { 3706 if (wpa_supplicant_ctrl_iface_wps_er_set_config(wpa_s, 3707 buf + 18)) 3708 reply_len = -1; 3709 } else if (os_strncmp(buf, "WPS_ER_CONFIG ", 14) == 0) { 3710 if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s, buf + 14)) 3711 reply_len = -1; 3712#endif /* CONFIG_WPS_ER */ 3713#endif /* CONFIG_WPS */ 3714#ifdef CONFIG_IBSS_RSN 3715 } else if (os_strncmp(buf, "IBSS_RSN ", 9) == 0) { 3716 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s, buf + 9)) 3717 reply_len = -1; 3718#endif /* CONFIG_IBSS_RSN */ 3719#ifdef CONFIG_P2P 3720 } else if (os_strncmp(buf, "P2P_FIND ", 9) == 0) { 3721 if (p2p_ctrl_find(wpa_s, buf + 9)) 3722 reply_len = -1; 3723 } else if (os_strcmp(buf, "P2P_FIND") == 0) { 3724 if (p2p_ctrl_find(wpa_s, "")) 3725 reply_len = -1; 3726 } else if (os_strcmp(buf, "P2P_STOP_FIND") == 0) { 3727 wpas_p2p_stop_find(wpa_s); 3728 } else if (os_strncmp(buf, "P2P_CONNECT ", 12) == 0) { 3729 reply_len = p2p_ctrl_connect(wpa_s, buf + 12, reply, 3730 reply_size); 3731 } else if (os_strncmp(buf, "P2P_LISTEN ", 11) == 0) { 3732 if (p2p_ctrl_listen(wpa_s, buf + 11)) 3733 reply_len = -1; 3734 } else if (os_strcmp(buf, "P2P_LISTEN") == 0) { 3735 if (p2p_ctrl_listen(wpa_s, "")) 3736 reply_len = -1; 3737 } else if (os_strncmp(buf, "P2P_GROUP_REMOVE ", 17) == 0) { 3738 if (wpas_p2p_group_remove(wpa_s, buf + 17)) 3739 reply_len = -1; 3740 } else if (os_strcmp(buf, "P2P_GROUP_ADD") == 0) { 3741 if (wpas_p2p_group_add(wpa_s, 0, 0)) 3742 reply_len = -1; 3743 } else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) { 3744 if (p2p_ctrl_group_add(wpa_s, buf + 14)) 3745 reply_len = -1; 3746 } else if (os_strncmp(buf, "P2P_PROV_DISC ", 14) == 0) { 3747 if (p2p_ctrl_prov_disc(wpa_s, buf + 14)) 3748 reply_len = -1; 3749 } else if (os_strcmp(buf, "P2P_GET_PASSPHRASE") == 0) { 3750 reply_len = p2p_get_passphrase(wpa_s, reply, reply_size); 3751 } else if (os_strncmp(buf, "P2P_SERV_DISC_REQ ", 18) == 0) { 3752 reply_len = p2p_ctrl_serv_disc_req(wpa_s, buf + 18, reply, 3753 reply_size); 3754 } else if (os_strncmp(buf, "P2P_SERV_DISC_CANCEL_REQ ", 25) == 0) { 3755 if (p2p_ctrl_serv_disc_cancel_req(wpa_s, buf + 25) < 0) 3756 reply_len = -1; 3757 } else if (os_strncmp(buf, "P2P_SERV_DISC_RESP ", 19) == 0) { 3758 if (p2p_ctrl_serv_disc_resp(wpa_s, buf + 19) < 0) 3759 reply_len = -1; 3760 } else if (os_strcmp(buf, "P2P_SERVICE_UPDATE") == 0) { 3761 wpas_p2p_sd_service_update(wpa_s); 3762 } else if (os_strncmp(buf, "P2P_SERV_DISC_EXTERNAL ", 23) == 0) { 3763 if (p2p_ctrl_serv_disc_external(wpa_s, buf + 23) < 0) 3764 reply_len = -1; 3765 } else if (os_strcmp(buf, "P2P_SERVICE_FLUSH") == 0) { 3766 wpas_p2p_service_flush(wpa_s); 3767 } else if (os_strncmp(buf, "P2P_SERVICE_ADD ", 16) == 0) { 3768 if (p2p_ctrl_service_add(wpa_s, buf + 16) < 0) 3769 reply_len = -1; 3770 } else if (os_strncmp(buf, "P2P_SERVICE_DEL ", 16) == 0) { 3771 if (p2p_ctrl_service_del(wpa_s, buf + 16) < 0) 3772 reply_len = -1; 3773 } else if (os_strncmp(buf, "P2P_REJECT ", 11) == 0) { 3774 if (p2p_ctrl_reject(wpa_s, buf + 11) < 0) 3775 reply_len = -1; 3776 } else if (os_strncmp(buf, "P2P_INVITE ", 11) == 0) { 3777 if (p2p_ctrl_invite(wpa_s, buf + 11) < 0) 3778 reply_len = -1; 3779 } else if (os_strncmp(buf, "P2P_PEER ", 9) == 0) { 3780 reply_len = p2p_ctrl_peer(wpa_s, buf + 9, reply, 3781 reply_size); 3782 } else if (os_strncmp(buf, "P2P_SET ", 8) == 0) { 3783 if (p2p_ctrl_set(wpa_s, buf + 8) < 0) 3784 reply_len = -1; 3785 } else if (os_strcmp(buf, "P2P_FLUSH") == 0) { 3786 os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); 3787 wpa_s->force_long_sd = 0; 3788 if (wpa_s->global->p2p) 3789 p2p_flush(wpa_s->global->p2p); 3790 } else if (os_strncmp(buf, "P2P_UNAUTHORIZE ", 16) == 0) { 3791 if (wpas_p2p_unauthorize(wpa_s, buf + 16) < 0) 3792 reply_len = -1; 3793 } else if (os_strcmp(buf, "P2P_CANCEL") == 0) { 3794 if (wpas_p2p_cancel(wpa_s)) 3795 reply_len = -1; 3796 } else if (os_strncmp(buf, "P2P_PRESENCE_REQ ", 17) == 0) { 3797 if (p2p_ctrl_presence_req(wpa_s, buf + 17) < 0) 3798 reply_len = -1; 3799 } else if (os_strcmp(buf, "P2P_PRESENCE_REQ") == 0) { 3800 if (p2p_ctrl_presence_req(wpa_s, "") < 0) 3801 reply_len = -1; 3802 } else if (os_strncmp(buf, "P2P_EXT_LISTEN ", 15) == 0) { 3803 if (p2p_ctrl_ext_listen(wpa_s, buf + 15) < 0) 3804 reply_len = -1; 3805 } else if (os_strcmp(buf, "P2P_EXT_LISTEN") == 0) { 3806 if (p2p_ctrl_ext_listen(wpa_s, "") < 0) 3807 reply_len = -1; 3808#endif /* CONFIG_P2P */ 3809#ifdef CONFIG_INTERWORKING 3810 } else if (os_strcmp(buf, "FETCH_ANQP") == 0) { 3811 if (interworking_fetch_anqp(wpa_s) < 0) 3812 reply_len = -1; 3813 } else if (os_strcmp(buf, "STOP_FETCH_ANQP") == 0) { 3814 interworking_stop_fetch_anqp(wpa_s); 3815 } else if (os_strncmp(buf, "INTERWORKING_SELECT", 19) == 0) { 3816 if (interworking_select(wpa_s, os_strstr(buf + 19, "auto") != 3817 NULL) < 0) 3818 reply_len = -1; 3819 } else if (os_strncmp(buf, "INTERWORKING_CONNECT ", 21) == 0) { 3820 if (ctrl_interworking_connect(wpa_s, buf + 21) < 0) 3821 reply_len = -1; 3822 } else if (os_strncmp(buf, "ANQP_GET ", 9) == 0) { 3823 if (get_anqp(wpa_s, buf + 9) < 0) 3824 reply_len = -1; 3825#endif /* CONFIG_INTERWORKING */ 3826 } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0) 3827 { 3828 if (wpa_supplicant_ctrl_iface_ctrl_rsp( 3829 wpa_s, buf + os_strlen(WPA_CTRL_RSP))) 3830 reply_len = -1; 3831 else 3832 ctrl_rsp = 1; 3833 } else if (os_strcmp(buf, "RECONFIGURE") == 0) { 3834 if (wpa_supplicant_reload_configuration(wpa_s)) 3835 reply_len = -1; 3836 } else if (os_strcmp(buf, "TERMINATE") == 0) { 3837 wpa_supplicant_terminate_proc(wpa_s->global); 3838 } else if (os_strncmp(buf, "BSSID ", 6) == 0) { 3839 if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6)) 3840 reply_len = -1; 3841 } else if (os_strncmp(buf, "BLACKLIST", 9) == 0) { 3842 reply_len = wpa_supplicant_ctrl_iface_blacklist( 3843 wpa_s, buf + 9, reply, reply_size); 3844 } else if (os_strncmp(buf, "LOG_LEVEL", 9) == 0) { 3845 reply_len = wpa_supplicant_ctrl_iface_log_level( 3846 wpa_s, buf + 9, reply, reply_size); 3847 } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) { 3848 reply_len = wpa_supplicant_ctrl_iface_list_networks( 3849 wpa_s, reply, reply_size); 3850 } else if (os_strcmp(buf, "DISCONNECT") == 0) { 3851 wpa_s->reassociate = 0; 3852 wpa_s->disconnected = 1; 3853 wpa_supplicant_cancel_sched_scan(wpa_s); 3854 wpa_supplicant_deauthenticate(wpa_s, 3855 WLAN_REASON_DEAUTH_LEAVING); 3856 } else if (os_strcmp(buf, "SCAN") == 0) { 3857 wpa_s->normal_scans = 0; 3858 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) 3859 reply_len = -1; 3860 else { 3861 if (!wpa_s->scanning && 3862 ((wpa_s->wpa_state <= WPA_SCANNING) || 3863 (wpa_s->wpa_state == WPA_COMPLETED))) { 3864 wpa_s->scan_req = 2; 3865 wpa_supplicant_req_scan(wpa_s, 0, 0); 3866 } else { 3867 wpa_printf(MSG_DEBUG, "Ongoing scan action - " 3868 "reject new request"); 3869 reply_len = os_snprintf(reply, reply_size, 3870 "FAIL-BUSY\n"); 3871 } 3872 } 3873 } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) { 3874 reply_len = wpa_supplicant_ctrl_iface_scan_results( 3875 wpa_s, reply, reply_size); 3876 } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) { 3877 if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15)) 3878 reply_len = -1; 3879 } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) { 3880 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15)) 3881 reply_len = -1; 3882 } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) { 3883 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16)) 3884 reply_len = -1; 3885 } else if (os_strcmp(buf, "ADD_NETWORK") == 0) { 3886 reply_len = wpa_supplicant_ctrl_iface_add_network( 3887 wpa_s, reply, reply_size); 3888 } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) { 3889 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15)) 3890 reply_len = -1; 3891 } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) { 3892 if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12)) 3893 reply_len = -1; 3894 } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) { 3895 reply_len = wpa_supplicant_ctrl_iface_get_network( 3896 wpa_s, buf + 12, reply, reply_size); 3897#ifndef CONFIG_NO_CONFIG_WRITE 3898 } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) { 3899 if (wpa_supplicant_ctrl_iface_save_config(wpa_s)) 3900 reply_len = -1; 3901#endif /* CONFIG_NO_CONFIG_WRITE */ 3902 } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) { 3903 reply_len = wpa_supplicant_ctrl_iface_get_capability( 3904 wpa_s, buf + 15, reply, reply_size); 3905 } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) { 3906 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8)) 3907 reply_len = -1; 3908 } else if (os_strncmp(buf, "SCAN_INTERVAL ", 14) == 0) { 3909 if (wpa_supplicant_ctrl_iface_scan_interval(wpa_s, buf + 14)) 3910 reply_len = -1; 3911 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) { 3912 reply_len = wpa_supplicant_global_iface_list( 3913 wpa_s->global, reply, reply_size); 3914 } else if (os_strcmp(buf, "INTERFACES") == 0) { 3915 reply_len = wpa_supplicant_global_iface_interfaces( 3916 wpa_s->global, reply, reply_size); 3917 } else if (os_strncmp(buf, "BSS ", 4) == 0) { 3918 reply_len = wpa_supplicant_ctrl_iface_bss( 3919 wpa_s, buf + 4, reply, reply_size); 3920#ifdef CONFIG_AP 3921 } else if (os_strcmp(buf, "STA-FIRST") == 0) { 3922 reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); 3923 } else if (os_strncmp(buf, "STA ", 4) == 0) { 3924 reply_len = ap_ctrl_iface_sta(wpa_s, buf + 4, reply, 3925 reply_size); 3926 } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { 3927 reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, 3928 reply_size); 3929#endif /* CONFIG_AP */ 3930 } else if (os_strcmp(buf, "SUSPEND") == 0) { 3931 wpas_notify_suspend(wpa_s->global); 3932 } else if (os_strcmp(buf, "RESUME") == 0) { 3933 wpas_notify_resume(wpa_s->global); 3934 } else if (os_strcmp(buf, "DROP_SA") == 0) { 3935 wpa_supplicant_ctrl_iface_drop_sa(wpa_s); 3936 } else if (os_strncmp(buf, "ROAM ", 5) == 0) { 3937 if (wpa_supplicant_ctrl_iface_roam(wpa_s, buf + 5)) 3938 reply_len = -1; 3939 } else if (os_strncmp(buf, "STA_AUTOCONNECT ", 16) == 0) { 3940 if (wpa_supplicant_ctrl_iface_sta_autoconnect(wpa_s, buf + 16)) 3941 reply_len = -1; 3942 } else if (os_strncmp(buf, "BSS_EXPIRE_AGE ", 15) == 0) { 3943 if (wpa_supplicant_ctrl_iface_bss_expire_age(wpa_s, buf + 15)) 3944 reply_len = -1; 3945 } else if (os_strncmp(buf, "BSS_EXPIRE_COUNT ", 17) == 0) { 3946 if (wpa_supplicant_ctrl_iface_bss_expire_count(wpa_s, 3947 buf + 17)) 3948 reply_len = -1; 3949#ifdef CONFIG_TDLS 3950 } else if (os_strncmp(buf, "TDLS_DISCOVER ", 14) == 0) { 3951 if (wpa_supplicant_ctrl_iface_tdls_discover(wpa_s, buf + 14)) 3952 reply_len = -1; 3953 } else if (os_strncmp(buf, "TDLS_SETUP ", 11) == 0) { 3954 if (wpa_supplicant_ctrl_iface_tdls_setup(wpa_s, buf + 11)) 3955 reply_len = -1; 3956 } else if (os_strncmp(buf, "TDLS_TEARDOWN ", 14) == 0) { 3957 if (wpa_supplicant_ctrl_iface_tdls_teardown(wpa_s, buf + 14)) 3958 reply_len = -1; 3959#endif /* CONFIG_TDLS */ 3960 } else if (os_strncmp(buf, "SIGNAL_POLL", 11) == 0) { 3961 reply_len = wpa_supplicant_signal_poll(wpa_s, reply, 3962 reply_size); 3963#ifdef ANDROID 3964 } else if (os_strncmp(buf, "DRIVER ", 7) == 0) { 3965 reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply, 3966 reply_size); 3967#endif 3968 } else if (os_strcmp(buf, "REAUTHENTICATE") == 0) { 3969 eapol_sm_request_reauth(wpa_s->eapol); 3970 } else { 3971 os_memcpy(reply, "UNKNOWN COMMAND\n", 16); 3972 reply_len = 16; 3973 } 3974 3975 if (reply_len < 0) { 3976 os_memcpy(reply, "FAIL\n", 5); 3977 reply_len = 5; 3978 } 3979 3980 if (ctrl_rsp) 3981 eapol_sm_notify_ctrl_response(wpa_s->eapol); 3982 3983 *resp_len = reply_len; 3984 return reply; 3985} 3986 3987 3988static int wpa_supplicant_global_iface_add(struct wpa_global *global, 3989 char *cmd) 3990{ 3991 struct wpa_interface iface; 3992 char *pos; 3993 3994 /* 3995 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param> 3996 * TAB<bridge_ifname> 3997 */ 3998 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd); 3999 4000 os_memset(&iface, 0, sizeof(iface)); 4001 4002 do { 4003 iface.ifname = pos = cmd; 4004 pos = os_strchr(pos, '\t'); 4005 if (pos) 4006 *pos++ = '\0'; 4007 if (iface.ifname[0] == '\0') 4008 return -1; 4009 if (pos == NULL) 4010 break; 4011 4012 iface.confname = pos; 4013 pos = os_strchr(pos, '\t'); 4014 if (pos) 4015 *pos++ = '\0'; 4016 if (iface.confname[0] == '\0') 4017 iface.confname = NULL; 4018 if (pos == NULL) 4019 break; 4020 4021 iface.driver = pos; 4022 pos = os_strchr(pos, '\t'); 4023 if (pos) 4024 *pos++ = '\0'; 4025 if (iface.driver[0] == '\0') 4026 iface.driver = NULL; 4027 if (pos == NULL) 4028 break; 4029 4030 iface.ctrl_interface = pos; 4031 pos = os_strchr(pos, '\t'); 4032 if (pos) 4033 *pos++ = '\0'; 4034 if (iface.ctrl_interface[0] == '\0') 4035 iface.ctrl_interface = NULL; 4036 if (pos == NULL) 4037 break; 4038 4039 iface.driver_param = pos; 4040 pos = os_strchr(pos, '\t'); 4041 if (pos) 4042 *pos++ = '\0'; 4043 if (iface.driver_param[0] == '\0') 4044 iface.driver_param = NULL; 4045 if (pos == NULL) 4046 break; 4047 4048 iface.bridge_ifname = pos; 4049 pos = os_strchr(pos, '\t'); 4050 if (pos) 4051 *pos++ = '\0'; 4052 if (iface.bridge_ifname[0] == '\0') 4053 iface.bridge_ifname = NULL; 4054 if (pos == NULL) 4055 break; 4056 } while (0); 4057 4058 if (wpa_supplicant_get_iface(global, iface.ifname)) 4059 return -1; 4060 4061 return wpa_supplicant_add_iface(global, &iface) ? 0 : -1; 4062} 4063 4064 4065static int wpa_supplicant_global_iface_remove(struct wpa_global *global, 4066 char *cmd) 4067{ 4068 struct wpa_supplicant *wpa_s; 4069 4070 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd); 4071 4072 wpa_s = wpa_supplicant_get_iface(global, cmd); 4073 if (wpa_s == NULL) 4074 return -1; 4075 return wpa_supplicant_remove_iface(global, wpa_s, 0); 4076} 4077 4078 4079static void wpa_free_iface_info(struct wpa_interface_info *iface) 4080{ 4081 struct wpa_interface_info *prev; 4082 4083 while (iface) { 4084 prev = iface; 4085 iface = iface->next; 4086 4087 os_free(prev->ifname); 4088 os_free(prev->desc); 4089 os_free(prev); 4090 } 4091} 4092 4093 4094static int wpa_supplicant_global_iface_list(struct wpa_global *global, 4095 char *buf, int len) 4096{ 4097 int i, res; 4098 struct wpa_interface_info *iface = NULL, *last = NULL, *tmp; 4099 char *pos, *end; 4100 4101 for (i = 0; wpa_drivers[i]; i++) { 4102 struct wpa_driver_ops *drv = wpa_drivers[i]; 4103 if (drv->get_interfaces == NULL) 4104 continue; 4105 tmp = drv->get_interfaces(global->drv_priv[i]); 4106 if (tmp == NULL) 4107 continue; 4108 4109 if (last == NULL) 4110 iface = last = tmp; 4111 else 4112 last->next = tmp; 4113 while (last->next) 4114 last = last->next; 4115 } 4116 4117 pos = buf; 4118 end = buf + len; 4119 for (tmp = iface; tmp; tmp = tmp->next) { 4120 res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n", 4121 tmp->drv_name, tmp->ifname, 4122 tmp->desc ? tmp->desc : ""); 4123 if (res < 0 || res >= end - pos) { 4124 *pos = '\0'; 4125 break; 4126 } 4127 pos += res; 4128 } 4129 4130 wpa_free_iface_info(iface); 4131 4132 return pos - buf; 4133} 4134 4135 4136static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global, 4137 char *buf, int len) 4138{ 4139 int res; 4140 char *pos, *end; 4141 struct wpa_supplicant *wpa_s; 4142 4143 wpa_s = global->ifaces; 4144 pos = buf; 4145 end = buf + len; 4146 4147 while (wpa_s) { 4148 res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname); 4149 if (res < 0 || res >= end - pos) { 4150 *pos = '\0'; 4151 break; 4152 } 4153 pos += res; 4154 wpa_s = wpa_s->next; 4155 } 4156 return pos - buf; 4157} 4158 4159 4160char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global, 4161 char *buf, size_t *resp_len) 4162{ 4163 char *reply; 4164 const int reply_size = 2048; 4165 int reply_len; 4166 int level = MSG_DEBUG; 4167 4168 if (os_strcmp(buf, "PING") == 0) 4169 level = MSG_EXCESSIVE; 4170 wpa_hexdump_ascii(level, "RX global ctrl_iface", 4171 (const u8 *) buf, os_strlen(buf)); 4172 4173 reply = os_malloc(reply_size); 4174 if (reply == NULL) { 4175 *resp_len = 1; 4176 return NULL; 4177 } 4178 4179 os_memcpy(reply, "OK\n", 3); 4180 reply_len = 3; 4181 4182 if (os_strcmp(buf, "PING") == 0) { 4183 os_memcpy(reply, "PONG\n", 5); 4184 reply_len = 5; 4185 } else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) { 4186 if (wpa_supplicant_global_iface_add(global, buf + 14)) 4187 reply_len = -1; 4188 } else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) { 4189 if (wpa_supplicant_global_iface_remove(global, buf + 17)) 4190 reply_len = -1; 4191 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) { 4192 reply_len = wpa_supplicant_global_iface_list( 4193 global, reply, reply_size); 4194 } else if (os_strcmp(buf, "INTERFACES") == 0) { 4195 reply_len = wpa_supplicant_global_iface_interfaces( 4196 global, reply, reply_size); 4197 } else if (os_strcmp(buf, "TERMINATE") == 0) { 4198 wpa_supplicant_terminate_proc(global); 4199 } else if (os_strcmp(buf, "SUSPEND") == 0) { 4200 wpas_notify_suspend(global); 4201 } else if (os_strcmp(buf, "RESUME") == 0) { 4202 wpas_notify_resume(global); 4203 } else { 4204 os_memcpy(reply, "UNKNOWN COMMAND\n", 16); 4205 reply_len = 16; 4206 } 4207 4208 if (reply_len < 0) { 4209 os_memcpy(reply, "FAIL\n", 5); 4210 reply_len = 5; 4211 } 4212 4213 *resp_len = reply_len; 4214 return reply; 4215} 4216