1 /* 2 * WPA Supplicant / Control interface (shared code for all backends) 3 * Copyright (c) 2004-2010, Jouni Malinen <j (at) 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 39 extern struct wpa_driver_ops *wpa_drivers[]; 40 41 static int wpa_supplicant_global_iface_list(struct wpa_global *global, 42 char *buf, int len); 43 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global, 44 char *buf, int len); 45 46 47 static 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 107 static 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 117 static 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 213 static 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 236 static 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) */ 260 static 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 281 static 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 305 static 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 332 static 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 354 static 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 381 static 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 419 static 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 463 done: 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 472 static 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 518 static 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 542 static 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 594 static 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 653 static 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 672 static 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 684 static 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 696 static 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 744 static 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 763 int 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 835 static 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 873 static 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 wpa_ssid_txt(wpa_s->current_ssid->ssid, 1020 wpa_s->current_ssid->ssid_len) : ""); 1021 if (wpa_s->wpa_state == WPA_COMPLETED) { 1022 struct wpa_ssid *ssid = wpa_s->current_ssid; 1023 wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- connection to " 1024 MACSTR " completed %s [id=%d id_str=%s]", 1025 MAC2STR(wpa_s->bssid), wpa_s->reassociated_connection ? 1026 "(reauth)" : "(auth)", 1027 ssid ? ssid->id : -1, 1028 ssid && ssid->id_str ? ssid->id_str : ""); 1029 } 1030 #endif /* ANDROID */ 1031 1032 return pos - buf; 1033 } 1034 1035 1036 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s, 1037 char *cmd) 1038 { 1039 char *pos; 1040 int id; 1041 struct wpa_ssid *ssid; 1042 u8 bssid[ETH_ALEN]; 1043 1044 /* cmd: "<network id> <BSSID>" */ 1045 pos = os_strchr(cmd, ' '); 1046 if (pos == NULL) 1047 return -1; 1048 *pos++ = '\0'; 1049 id = atoi(cmd); 1050 wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos); 1051 if (hwaddr_aton(pos, bssid)) { 1052 wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos); 1053 return -1; 1054 } 1055 1056 ssid = wpa_config_get_network(wpa_s->conf, id); 1057 if (ssid == NULL) { 1058 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 1059 "to update", id); 1060 return -1; 1061 } 1062 1063 os_memcpy(ssid->bssid, bssid, ETH_ALEN); 1064 ssid->bssid_set = !is_zero_ether_addr(bssid); 1065 1066 return 0; 1067 } 1068 1069 1070 static int wpa_supplicant_ctrl_iface_blacklist(struct wpa_supplicant *wpa_s, 1071 char *cmd, char *buf, 1072 size_t buflen) 1073 { 1074 u8 bssid[ETH_ALEN]; 1075 struct wpa_blacklist *e; 1076 char *pos, *end; 1077 int ret; 1078 1079 /* cmd: "BLACKLIST [<BSSID>]" */ 1080 if (*cmd == '\0') { 1081 pos = buf; 1082 end = buf + buflen; 1083 e = wpa_s->blacklist; 1084 while (e) { 1085 ret = os_snprintf(pos, end - pos, MACSTR "\n", 1086 MAC2STR(e->bssid)); 1087 if (ret < 0 || ret >= end - pos) 1088 return pos - buf; 1089 pos += ret; 1090 e = e->next; 1091 } 1092 return pos - buf; 1093 } 1094 1095 cmd++; 1096 if (os_strncmp(cmd, "clear", 5) == 0) { 1097 wpa_blacklist_clear(wpa_s); 1098 os_memcpy(buf, "OK\n", 3); 1099 return 3; 1100 } 1101 1102 wpa_printf(MSG_DEBUG, "CTRL_IFACE: BLACKLIST bssid='%s'", cmd); 1103 if (hwaddr_aton(cmd, bssid)) { 1104 wpa_printf(MSG_DEBUG, "CTRL_IFACE: invalid BSSID '%s'", cmd); 1105 return -1; 1106 } 1107 1108 /* 1109 * Add the BSSID twice, so its count will be 2, causing it to be 1110 * skipped when processing scan results. 1111 */ 1112 ret = wpa_blacklist_add(wpa_s, bssid); 1113 if (ret != 0) 1114 return -1; 1115 ret = wpa_blacklist_add(wpa_s, bssid); 1116 if (ret != 0) 1117 return -1; 1118 os_memcpy(buf, "OK\n", 3); 1119 return 3; 1120 } 1121 1122 1123 extern int wpa_debug_level; 1124 extern int wpa_debug_timestamp; 1125 1126 static const char * debug_level_str(int level) 1127 { 1128 switch (level) { 1129 case MSG_EXCESSIVE: 1130 return "EXCESSIVE"; 1131 case MSG_MSGDUMP: 1132 return "MSGDUMP"; 1133 case MSG_DEBUG: 1134 return "DEBUG"; 1135 case MSG_INFO: 1136 return "INFO"; 1137 case MSG_WARNING: 1138 return "WARNING"; 1139 case MSG_ERROR: 1140 return "ERROR"; 1141 default: 1142 return "?"; 1143 } 1144 } 1145 1146 1147 static int str_to_debug_level(const char *s) 1148 { 1149 if (os_strcasecmp(s, "EXCESSIVE") == 0) 1150 return MSG_EXCESSIVE; 1151 if (os_strcasecmp(s, "MSGDUMP") == 0) 1152 return MSG_MSGDUMP; 1153 if (os_strcasecmp(s, "DEBUG") == 0) 1154 return MSG_DEBUG; 1155 if (os_strcasecmp(s, "INFO") == 0) 1156 return MSG_INFO; 1157 if (os_strcasecmp(s, "WARNING") == 0) 1158 return MSG_WARNING; 1159 if (os_strcasecmp(s, "ERROR") == 0) 1160 return MSG_ERROR; 1161 return -1; 1162 } 1163 1164 1165 static int wpa_supplicant_ctrl_iface_log_level(struct wpa_supplicant *wpa_s, 1166 char *cmd, char *buf, 1167 size_t buflen) 1168 { 1169 char *pos, *end, *stamp; 1170 int ret; 1171 1172 if (cmd == NULL) { 1173 return -1; 1174 } 1175 1176 /* cmd: "LOG_LEVEL [<level>]" */ 1177 if (*cmd == '\0') { 1178 pos = buf; 1179 end = buf + buflen; 1180 ret = os_snprintf(pos, end - pos, "Current level: %s\n" 1181 "Timestamp: %d\n", 1182 debug_level_str(wpa_debug_level), 1183 wpa_debug_timestamp); 1184 if (ret < 0 || ret >= end - pos) 1185 ret = 0; 1186 1187 return ret; 1188 } 1189 1190 while (*cmd == ' ') 1191 cmd++; 1192 1193 stamp = os_strchr(cmd, ' '); 1194 if (stamp) { 1195 *stamp++ = '\0'; 1196 while (*stamp == ' ') { 1197 stamp++; 1198 } 1199 } 1200 1201 if (cmd && os_strlen(cmd)) { 1202 int level = str_to_debug_level(cmd); 1203 if (level < 0) 1204 return -1; 1205 wpa_debug_level = level; 1206 } 1207 1208 if (stamp && os_strlen(stamp)) 1209 wpa_debug_timestamp = atoi(stamp); 1210 1211 os_memcpy(buf, "OK\n", 3); 1212 return 3; 1213 } 1214 1215 1216 static int wpa_supplicant_ctrl_iface_list_networks( 1217 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 1218 { 1219 char *pos, *end; 1220 struct wpa_ssid *ssid; 1221 int ret; 1222 1223 pos = buf; 1224 end = buf + buflen; 1225 ret = os_snprintf(pos, end - pos, 1226 "network id / ssid / bssid / flags\n"); 1227 if (ret < 0 || ret >= end - pos) 1228 return pos - buf; 1229 pos += ret; 1230 1231 ssid = wpa_s->conf->ssid; 1232 while (ssid) { 1233 ret = os_snprintf(pos, end - pos, "%d\t%s", 1234 ssid->id, 1235 wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 1236 if (ret < 0 || ret >= end - pos) 1237 return pos - buf; 1238 pos += ret; 1239 if (ssid->bssid_set) { 1240 ret = os_snprintf(pos, end - pos, "\t" MACSTR, 1241 MAC2STR(ssid->bssid)); 1242 } else { 1243 ret = os_snprintf(pos, end - pos, "\tany"); 1244 } 1245 if (ret < 0 || ret >= end - pos) 1246 return pos - buf; 1247 pos += ret; 1248 ret = os_snprintf(pos, end - pos, "\t%s%s%s", 1249 ssid == wpa_s->current_ssid ? 1250 "[CURRENT]" : "", 1251 ssid->disabled ? "[DISABLED]" : "", 1252 ssid->disabled == 2 ? "[P2P-PERSISTENT]" : 1253 ""); 1254 if (ret < 0 || ret >= end - pos) 1255 return pos - buf; 1256 pos += ret; 1257 ret = os_snprintf(pos, end - pos, "\n"); 1258 if (ret < 0 || ret >= end - pos) 1259 return pos - buf; 1260 pos += ret; 1261 1262 ssid = ssid->next; 1263 } 1264 1265 return pos - buf; 1266 } 1267 1268 1269 static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher) 1270 { 1271 int first = 1, ret; 1272 ret = os_snprintf(pos, end - pos, "-"); 1273 if (ret < 0 || ret >= end - pos) 1274 return pos; 1275 pos += ret; 1276 if (cipher & WPA_CIPHER_NONE) { 1277 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : "+"); 1278 if (ret < 0 || ret >= end - pos) 1279 return pos; 1280 pos += ret; 1281 first = 0; 1282 } 1283 if (cipher & WPA_CIPHER_WEP40) { 1284 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : "+"); 1285 if (ret < 0 || ret >= end - pos) 1286 return pos; 1287 pos += ret; 1288 first = 0; 1289 } 1290 if (cipher & WPA_CIPHER_WEP104) { 1291 ret = os_snprintf(pos, end - pos, "%sWEP104", 1292 first ? "" : "+"); 1293 if (ret < 0 || ret >= end - pos) 1294 return pos; 1295 pos += ret; 1296 first = 0; 1297 } 1298 if (cipher & WPA_CIPHER_TKIP) { 1299 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : "+"); 1300 if (ret < 0 || ret >= end - pos) 1301 return pos; 1302 pos += ret; 1303 first = 0; 1304 } 1305 if (cipher & WPA_CIPHER_CCMP) { 1306 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : "+"); 1307 if (ret < 0 || ret >= end - pos) 1308 return pos; 1309 pos += ret; 1310 first = 0; 1311 } 1312 return pos; 1313 } 1314 1315 1316 static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto, 1317 const u8 *ie, size_t ie_len) 1318 { 1319 struct wpa_ie_data data; 1320 int first, ret; 1321 1322 ret = os_snprintf(pos, end - pos, "[%s-", proto); 1323 if (ret < 0 || ret >= end - pos) 1324 return pos; 1325 pos += ret; 1326 1327 if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) { 1328 ret = os_snprintf(pos, end - pos, "?]"); 1329 if (ret < 0 || ret >= end - pos) 1330 return pos; 1331 pos += ret; 1332 return pos; 1333 } 1334 1335 first = 1; 1336 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) { 1337 ret = os_snprintf(pos, end - pos, "%sEAP", first ? "" : "+"); 1338 if (ret < 0 || ret >= end - pos) 1339 return pos; 1340 pos += ret; 1341 first = 0; 1342 } 1343 if (data.key_mgmt & WPA_KEY_MGMT_PSK) { 1344 ret = os_snprintf(pos, end - pos, "%sPSK", first ? "" : "+"); 1345 if (ret < 0 || ret >= end - pos) 1346 return pos; 1347 pos += ret; 1348 first = 0; 1349 } 1350 if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) { 1351 ret = os_snprintf(pos, end - pos, "%sNone", first ? "" : "+"); 1352 if (ret < 0 || ret >= end - pos) 1353 return pos; 1354 pos += ret; 1355 first = 0; 1356 } 1357 #ifdef CONFIG_IEEE80211R 1358 if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) { 1359 ret = os_snprintf(pos, end - pos, "%sFT/EAP", 1360 first ? "" : "+"); 1361 if (ret < 0 || ret >= end - pos) 1362 return pos; 1363 pos += ret; 1364 first = 0; 1365 } 1366 if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) { 1367 ret = os_snprintf(pos, end - pos, "%sFT/PSK", 1368 first ? "" : "+"); 1369 if (ret < 0 || ret >= end - pos) 1370 return pos; 1371 pos += ret; 1372 first = 0; 1373 } 1374 #endif /* CONFIG_IEEE80211R */ 1375 #ifdef CONFIG_IEEE80211W 1376 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) { 1377 ret = os_snprintf(pos, end - pos, "%sEAP-SHA256", 1378 first ? "" : "+"); 1379 if (ret < 0 || ret >= end - pos) 1380 return pos; 1381 pos += ret; 1382 first = 0; 1383 } 1384 if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) { 1385 ret = os_snprintf(pos, end - pos, "%sPSK-SHA256", 1386 first ? "" : "+"); 1387 if (ret < 0 || ret >= end - pos) 1388 return pos; 1389 pos += ret; 1390 first = 0; 1391 } 1392 #endif /* CONFIG_IEEE80211W */ 1393 1394 pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher); 1395 1396 if (data.capabilities & WPA_CAPABILITY_PREAUTH) { 1397 ret = os_snprintf(pos, end - pos, "-preauth"); 1398 if (ret < 0 || ret >= end - pos) 1399 return pos; 1400 pos += ret; 1401 } 1402 1403 ret = os_snprintf(pos, end - pos, "]"); 1404 if (ret < 0 || ret >= end - pos) 1405 return pos; 1406 pos += ret; 1407 1408 return pos; 1409 } 1410 1411 1412 #ifdef CONFIG_WPS 1413 static char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant *wpa_s, 1414 char *pos, char *end, 1415 struct wpabuf *wps_ie) 1416 { 1417 int ret; 1418 const char *txt; 1419 1420 if (wps_ie == NULL) 1421 return pos; 1422 if (wps_is_selected_pbc_registrar(wps_ie)) 1423 txt = "[WPS-PBC]"; 1424 #ifdef CONFIG_WPS2 1425 else if (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 0)) 1426 txt = "[WPS-AUTH]"; 1427 #endif /* CONFIG_WPS2 */ 1428 else if (wps_is_selected_pin_registrar(wps_ie)) 1429 txt = "[WPS-PIN]"; 1430 else 1431 txt = "[WPS]"; 1432 1433 ret = os_snprintf(pos, end - pos, "%s", txt); 1434 if (ret >= 0 && ret < end - pos) 1435 pos += ret; 1436 wpabuf_free(wps_ie); 1437 return pos; 1438 } 1439 #endif /* CONFIG_WPS */ 1440 1441 1442 static char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant *wpa_s, 1443 char *pos, char *end, 1444 const struct wpa_bss *bss) 1445 { 1446 #ifdef CONFIG_WPS 1447 struct wpabuf *wps_ie; 1448 wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); 1449 return wpa_supplicant_wps_ie_txt_buf(wpa_s, pos, end, wps_ie); 1450 #else /* CONFIG_WPS */ 1451 return pos; 1452 #endif /* CONFIG_WPS */ 1453 } 1454 1455 1456 /* Format one result on one text line into a buffer. */ 1457 static int wpa_supplicant_ctrl_iface_scan_result( 1458 struct wpa_supplicant *wpa_s, 1459 const struct wpa_bss *bss, char *buf, size_t buflen) 1460 { 1461 char *pos, *end; 1462 int ret; 1463 const u8 *ie, *ie2, *p2p; 1464 1465 p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE); 1466 if (p2p && bss->ssid_len == P2P_WILDCARD_SSID_LEN && 1467 os_memcmp(bss->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) == 1468 0) 1469 return 0; /* Do not show P2P listen discovery results here */ 1470 1471 pos = buf; 1472 end = buf + buflen; 1473 1474 ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t", 1475 MAC2STR(bss->bssid), bss->freq, bss->level); 1476 if (ret < 0 || ret >= end - pos) 1477 return -1; 1478 pos += ret; 1479 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); 1480 if (ie) 1481 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]); 1482 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN); 1483 if (ie2) 1484 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]); 1485 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss); 1486 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) { 1487 ret = os_snprintf(pos, end - pos, "[WEP]"); 1488 if (ret < 0 || ret >= end - pos) 1489 return -1; 1490 pos += ret; 1491 } 1492 if (bss->caps & IEEE80211_CAP_IBSS) { 1493 ret = os_snprintf(pos, end - pos, "[IBSS]"); 1494 if (ret < 0 || ret >= end - pos) 1495 return -1; 1496 pos += ret; 1497 } 1498 if (bss->caps & IEEE80211_CAP_ESS) { 1499 ret = os_snprintf(pos, end - pos, "[ESS]"); 1500 if (ret < 0 || ret >= end - pos) 1501 return -1; 1502 pos += ret; 1503 } 1504 if (p2p) { 1505 ret = os_snprintf(pos, end - pos, "[P2P]"); 1506 if (ret < 0 || ret >= end - pos) 1507 return -1; 1508 pos += ret; 1509 } 1510 1511 ret = os_snprintf(pos, end - pos, "\t%s", 1512 wpa_ssid_txt(bss->ssid, bss->ssid_len)); 1513 if (ret < 0 || ret >= end - pos) 1514 return -1; 1515 pos += ret; 1516 1517 ret = os_snprintf(pos, end - pos, "\n"); 1518 if (ret < 0 || ret >= end - pos) 1519 return -1; 1520 pos += ret; 1521 1522 return pos - buf; 1523 } 1524 1525 1526 static int wpa_supplicant_ctrl_iface_scan_results( 1527 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 1528 { 1529 char *pos, *end; 1530 struct wpa_bss *bss; 1531 int ret; 1532 1533 pos = buf; 1534 end = buf + buflen; 1535 ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / " 1536 "flags / ssid\n"); 1537 if (ret < 0 || ret >= end - pos) 1538 return pos - buf; 1539 pos += ret; 1540 1541 dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) { 1542 ret = wpa_supplicant_ctrl_iface_scan_result(wpa_s, bss, pos, 1543 end - pos); 1544 if (ret < 0 || ret >= end - pos) 1545 return pos - buf; 1546 pos += ret; 1547 } 1548 1549 return pos - buf; 1550 } 1551 1552 1553 static int wpa_supplicant_ctrl_iface_select_network( 1554 struct wpa_supplicant *wpa_s, char *cmd) 1555 { 1556 int id; 1557 struct wpa_ssid *ssid; 1558 1559 /* cmd: "<network id>" or "any" */ 1560 if (os_strcmp(cmd, "any") == 0) { 1561 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any"); 1562 ssid = NULL; 1563 } else { 1564 id = atoi(cmd); 1565 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id); 1566 1567 ssid = wpa_config_get_network(wpa_s->conf, id); 1568 if (ssid == NULL) { 1569 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " 1570 "network id=%d", id); 1571 return -1; 1572 } 1573 if (ssid->disabled == 2) { 1574 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use " 1575 "SELECT_NETWORK with persistent P2P group"); 1576 return -1; 1577 } 1578 } 1579 1580 wpa_supplicant_select_network(wpa_s, ssid); 1581 1582 return 0; 1583 } 1584 1585 1586 static int wpa_supplicant_ctrl_iface_enable_network( 1587 struct wpa_supplicant *wpa_s, char *cmd) 1588 { 1589 int id; 1590 struct wpa_ssid *ssid; 1591 1592 /* cmd: "<network id>" or "all" */ 1593 if (os_strcmp(cmd, "all") == 0) { 1594 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all"); 1595 ssid = NULL; 1596 } else { 1597 id = atoi(cmd); 1598 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id); 1599 1600 ssid = wpa_config_get_network(wpa_s->conf, id); 1601 if (ssid == NULL) { 1602 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " 1603 "network id=%d", id); 1604 return -1; 1605 } 1606 if (ssid->disabled == 2) { 1607 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use " 1608 "ENABLE_NETWORK with persistent P2P group"); 1609 return -1; 1610 } 1611 } 1612 wpa_supplicant_enable_network(wpa_s, ssid); 1613 1614 return 0; 1615 } 1616 1617 1618 static int wpa_supplicant_ctrl_iface_disable_network( 1619 struct wpa_supplicant *wpa_s, char *cmd) 1620 { 1621 int id; 1622 struct wpa_ssid *ssid; 1623 1624 /* cmd: "<network id>" or "all" */ 1625 if (os_strcmp(cmd, "all") == 0) { 1626 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all"); 1627 ssid = NULL; 1628 } else { 1629 id = atoi(cmd); 1630 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id); 1631 1632 ssid = wpa_config_get_network(wpa_s->conf, id); 1633 if (ssid == NULL) { 1634 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " 1635 "network id=%d", id); 1636 return -1; 1637 } 1638 if (ssid->disabled == 2) { 1639 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use " 1640 "DISABLE_NETWORK with persistent P2P " 1641 "group"); 1642 return -1; 1643 } 1644 } 1645 wpa_supplicant_disable_network(wpa_s, ssid); 1646 1647 return 0; 1648 } 1649 1650 1651 static int wpa_supplicant_ctrl_iface_add_network( 1652 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 1653 { 1654 struct wpa_ssid *ssid; 1655 int ret; 1656 1657 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK"); 1658 1659 ssid = wpa_config_add_network(wpa_s->conf); 1660 if (ssid == NULL) 1661 return -1; 1662 1663 wpas_notify_network_added(wpa_s, ssid); 1664 1665 ssid->disabled = 1; 1666 wpa_config_set_network_defaults(ssid); 1667 1668 ret = os_snprintf(buf, buflen, "%d\n", ssid->id); 1669 if (ret < 0 || (size_t) ret >= buflen) 1670 return -1; 1671 return ret; 1672 } 1673 1674 1675 static int wpa_supplicant_ctrl_iface_remove_network( 1676 struct wpa_supplicant *wpa_s, char *cmd) 1677 { 1678 int id; 1679 struct wpa_ssid *ssid; 1680 1681 /* cmd: "<network id>" or "all" */ 1682 if (os_strcmp(cmd, "all") == 0) { 1683 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all"); 1684 ssid = wpa_s->conf->ssid; 1685 while (ssid) { 1686 struct wpa_ssid *remove_ssid = ssid; 1687 id = ssid->id; 1688 ssid = ssid->next; 1689 wpas_notify_network_removed(wpa_s, remove_ssid); 1690 wpa_config_remove_network(wpa_s->conf, id); 1691 } 1692 eapol_sm_invalidate_cached_session(wpa_s->eapol); 1693 if (wpa_s->current_ssid) { 1694 wpa_sm_set_config(wpa_s->wpa, NULL); 1695 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); 1696 wpa_supplicant_disassociate(wpa_s, 1697 WLAN_REASON_DEAUTH_LEAVING); 1698 } 1699 return 0; 1700 } 1701 1702 id = atoi(cmd); 1703 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id); 1704 1705 ssid = wpa_config_get_network(wpa_s->conf, id); 1706 if (ssid) 1707 wpas_notify_network_removed(wpa_s, ssid); 1708 if (ssid == NULL || 1709 wpa_config_remove_network(wpa_s->conf, id) < 0) { 1710 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 1711 "id=%d", id); 1712 return -1; 1713 } 1714 1715 if (ssid == wpa_s->current_ssid || wpa_s->current_ssid == NULL) { 1716 /* 1717 * Invalidate the EAP session cache if the current or 1718 * previously used network is removed. 1719 */ 1720 eapol_sm_invalidate_cached_session(wpa_s->eapol); 1721 } 1722 1723 if (ssid == wpa_s->current_ssid) { 1724 wpa_sm_set_config(wpa_s->wpa, NULL); 1725 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); 1726 1727 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); 1728 } 1729 1730 return 0; 1731 } 1732 1733 1734 static int wpa_supplicant_ctrl_iface_set_network( 1735 struct wpa_supplicant *wpa_s, char *cmd) 1736 { 1737 int id; 1738 struct wpa_ssid *ssid; 1739 char *name, *value; 1740 1741 /* cmd: "<network id> <variable name> <value>" */ 1742 name = os_strchr(cmd, ' '); 1743 if (name == NULL) 1744 return -1; 1745 *name++ = '\0'; 1746 1747 value = os_strchr(name, ' '); 1748 if (value == NULL) 1749 return -1; 1750 *value++ = '\0'; 1751 1752 id = atoi(cmd); 1753 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'", 1754 id, name); 1755 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value", 1756 (u8 *) value, os_strlen(value)); 1757 1758 ssid = wpa_config_get_network(wpa_s->conf, id); 1759 if (ssid == NULL) { 1760 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 1761 "id=%d", id); 1762 return -1; 1763 } 1764 1765 if (wpa_config_set(ssid, name, value, 0) < 0) { 1766 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network " 1767 "variable '%s'", name); 1768 return -1; 1769 } 1770 1771 wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid); 1772 1773 if (wpa_s->current_ssid == ssid || wpa_s->current_ssid == NULL) { 1774 /* 1775 * Invalidate the EAP session cache if anything in the current 1776 * or previously used configuration changes. 1777 */ 1778 eapol_sm_invalidate_cached_session(wpa_s->eapol); 1779 } 1780 1781 if ((os_strcmp(name, "psk") == 0 && 1782 value[0] == '"' && ssid->ssid_len) || 1783 (os_strcmp(name, "ssid") == 0 && ssid->passphrase)) 1784 wpa_config_update_psk(ssid); 1785 else if (os_strcmp(name, "priority") == 0) 1786 wpa_config_update_prio_list(wpa_s->conf); 1787 1788 return 0; 1789 } 1790 1791 1792 static int wpa_supplicant_ctrl_iface_get_network( 1793 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) 1794 { 1795 int id; 1796 size_t res; 1797 struct wpa_ssid *ssid; 1798 char *name, *value; 1799 1800 /* cmd: "<network id> <variable name>" */ 1801 name = os_strchr(cmd, ' '); 1802 if (name == NULL || buflen == 0) 1803 return -1; 1804 *name++ = '\0'; 1805 1806 id = atoi(cmd); 1807 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'", 1808 id, name); 1809 1810 ssid = wpa_config_get_network(wpa_s->conf, id); 1811 if (ssid == NULL) { 1812 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 1813 "id=%d", id); 1814 return -1; 1815 } 1816 1817 value = wpa_config_get_no_key(ssid, name); 1818 if (value == NULL) { 1819 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network " 1820 "variable '%s'", name); 1821 return -1; 1822 } 1823 1824 res = os_strlcpy(buf, value, buflen); 1825 if (res >= buflen) { 1826 os_free(value); 1827 return -1; 1828 } 1829 1830 os_free(value); 1831 1832 return res; 1833 } 1834 1835 1836 #ifndef CONFIG_NO_CONFIG_WRITE 1837 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s) 1838 { 1839 int ret; 1840 1841 if (!wpa_s->conf->update_config) { 1842 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed " 1843 "to update configuration (update_config=0)"); 1844 return -1; 1845 } 1846 1847 ret = wpa_config_write(wpa_s->confname, wpa_s->conf); 1848 if (ret) { 1849 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to " 1850 "update configuration"); 1851 } else { 1852 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration" 1853 " updated"); 1854 } 1855 1856 return ret; 1857 } 1858 #endif /* CONFIG_NO_CONFIG_WRITE */ 1859 1860 1861 static int ctrl_iface_get_capability_pairwise(int res, char *strict, 1862 struct wpa_driver_capa *capa, 1863 char *buf, size_t buflen) 1864 { 1865 int ret, first = 1; 1866 char *pos, *end; 1867 size_t len; 1868 1869 pos = buf; 1870 end = pos + buflen; 1871 1872 if (res < 0) { 1873 if (strict) 1874 return 0; 1875 len = os_strlcpy(buf, "CCMP TKIP NONE", buflen); 1876 if (len >= buflen) 1877 return -1; 1878 return len; 1879 } 1880 1881 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) { 1882 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " "); 1883 if (ret < 0 || ret >= end - pos) 1884 return pos - buf; 1885 pos += ret; 1886 first = 0; 1887 } 1888 1889 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) { 1890 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " "); 1891 if (ret < 0 || ret >= end - pos) 1892 return pos - buf; 1893 pos += ret; 1894 first = 0; 1895 } 1896 1897 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { 1898 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : " "); 1899 if (ret < 0 || ret >= end - pos) 1900 return pos - buf; 1901 pos += ret; 1902 first = 0; 1903 } 1904 1905 return pos - buf; 1906 } 1907 1908 1909 static int ctrl_iface_get_capability_group(int res, char *strict, 1910 struct wpa_driver_capa *capa, 1911 char *buf, size_t buflen) 1912 { 1913 int ret, first = 1; 1914 char *pos, *end; 1915 size_t len; 1916 1917 pos = buf; 1918 end = pos + buflen; 1919 1920 if (res < 0) { 1921 if (strict) 1922 return 0; 1923 len = os_strlcpy(buf, "CCMP TKIP WEP104 WEP40", buflen); 1924 if (len >= buflen) 1925 return -1; 1926 return len; 1927 } 1928 1929 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) { 1930 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " "); 1931 if (ret < 0 || ret >= end - pos) 1932 return pos - buf; 1933 pos += ret; 1934 first = 0; 1935 } 1936 1937 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) { 1938 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " "); 1939 if (ret < 0 || ret >= end - pos) 1940 return pos - buf; 1941 pos += ret; 1942 first = 0; 1943 } 1944 1945 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP104) { 1946 ret = os_snprintf(pos, end - pos, "%sWEP104", 1947 first ? "" : " "); 1948 if (ret < 0 || ret >= end - pos) 1949 return pos - buf; 1950 pos += ret; 1951 first = 0; 1952 } 1953 1954 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP40) { 1955 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : " "); 1956 if (ret < 0 || ret >= end - pos) 1957 return pos - buf; 1958 pos += ret; 1959 first = 0; 1960 } 1961 1962 return pos - buf; 1963 } 1964 1965 1966 static int ctrl_iface_get_capability_key_mgmt(int res, char *strict, 1967 struct wpa_driver_capa *capa, 1968 char *buf, size_t buflen) 1969 { 1970 int ret; 1971 char *pos, *end; 1972 size_t len; 1973 1974 pos = buf; 1975 end = pos + buflen; 1976 1977 if (res < 0) { 1978 if (strict) 1979 return 0; 1980 len = os_strlcpy(buf, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE " 1981 "NONE", buflen); 1982 if (len >= buflen) 1983 return -1; 1984 return len; 1985 } 1986 1987 ret = os_snprintf(pos, end - pos, "NONE IEEE8021X"); 1988 if (ret < 0 || ret >= end - pos) 1989 return pos - buf; 1990 pos += ret; 1991 1992 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | 1993 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) { 1994 ret = os_snprintf(pos, end - pos, " WPA-EAP"); 1995 if (ret < 0 || ret >= end - pos) 1996 return pos - buf; 1997 pos += ret; 1998 } 1999 2000 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | 2001 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { 2002 ret = os_snprintf(pos, end - pos, " WPA-PSK"); 2003 if (ret < 0 || ret >= end - pos) 2004 return pos - buf; 2005 pos += ret; 2006 } 2007 2008 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { 2009 ret = os_snprintf(pos, end - pos, " WPA-NONE"); 2010 if (ret < 0 || ret >= end - pos) 2011 return pos - buf; 2012 pos += ret; 2013 } 2014 2015 return pos - buf; 2016 } 2017 2018 2019 static int ctrl_iface_get_capability_proto(int res, char *strict, 2020 struct wpa_driver_capa *capa, 2021 char *buf, size_t buflen) 2022 { 2023 int ret, first = 1; 2024 char *pos, *end; 2025 size_t len; 2026 2027 pos = buf; 2028 end = pos + buflen; 2029 2030 if (res < 0) { 2031 if (strict) 2032 return 0; 2033 len = os_strlcpy(buf, "RSN WPA", buflen); 2034 if (len >= buflen) 2035 return -1; 2036 return len; 2037 } 2038 2039 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | 2040 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { 2041 ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " "); 2042 if (ret < 0 || ret >= end - pos) 2043 return pos - buf; 2044 pos += ret; 2045 first = 0; 2046 } 2047 2048 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | 2049 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) { 2050 ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " "); 2051 if (ret < 0 || ret >= end - pos) 2052 return pos - buf; 2053 pos += ret; 2054 first = 0; 2055 } 2056 2057 return pos - buf; 2058 } 2059 2060 2061 static int ctrl_iface_get_capability_auth_alg(int res, char *strict, 2062 struct wpa_driver_capa *capa, 2063 char *buf, size_t buflen) 2064 { 2065 int ret, first = 1; 2066 char *pos, *end; 2067 size_t len; 2068 2069 pos = buf; 2070 end = pos + buflen; 2071 2072 if (res < 0) { 2073 if (strict) 2074 return 0; 2075 len = os_strlcpy(buf, "OPEN SHARED LEAP", buflen); 2076 if (len >= buflen) 2077 return -1; 2078 return len; 2079 } 2080 2081 if (capa->auth & (WPA_DRIVER_AUTH_OPEN)) { 2082 ret = os_snprintf(pos, end - pos, "%sOPEN", first ? "" : " "); 2083 if (ret < 0 || ret >= end - pos) 2084 return pos - buf; 2085 pos += ret; 2086 first = 0; 2087 } 2088 2089 if (capa->auth & (WPA_DRIVER_AUTH_SHARED)) { 2090 ret = os_snprintf(pos, end - pos, "%sSHARED", 2091 first ? "" : " "); 2092 if (ret < 0 || ret >= end - pos) 2093 return pos - buf; 2094 pos += ret; 2095 first = 0; 2096 } 2097 2098 if (capa->auth & (WPA_DRIVER_AUTH_LEAP)) { 2099 ret = os_snprintf(pos, end - pos, "%sLEAP", first ? "" : " "); 2100 if (ret < 0 || ret >= end - pos) 2101 return pos - buf; 2102 pos += ret; 2103 first = 0; 2104 } 2105 2106 return pos - buf; 2107 } 2108 2109 2110 static int wpa_supplicant_ctrl_iface_get_capability( 2111 struct wpa_supplicant *wpa_s, const char *_field, char *buf, 2112 size_t buflen) 2113 { 2114 struct wpa_driver_capa capa; 2115 int res; 2116 char *strict; 2117 char field[30]; 2118 size_t len; 2119 2120 /* Determine whether or not strict checking was requested */ 2121 len = os_strlcpy(field, _field, sizeof(field)); 2122 if (len >= sizeof(field)) 2123 return -1; 2124 strict = os_strchr(field, ' '); 2125 if (strict != NULL) { 2126 *strict++ = '\0'; 2127 if (os_strcmp(strict, "strict") != 0) 2128 return -1; 2129 } 2130 2131 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s", 2132 field, strict ? strict : ""); 2133 2134 if (os_strcmp(field, "eap") == 0) { 2135 return eap_get_names(buf, buflen); 2136 } 2137 2138 res = wpa_drv_get_capa(wpa_s, &capa); 2139 2140 if (os_strcmp(field, "pairwise") == 0) 2141 return ctrl_iface_get_capability_pairwise(res, strict, &capa, 2142 buf, buflen); 2143 2144 if (os_strcmp(field, "group") == 0) 2145 return ctrl_iface_get_capability_group(res, strict, &capa, 2146 buf, buflen); 2147 2148 if (os_strcmp(field, "key_mgmt") == 0) 2149 return ctrl_iface_get_capability_key_mgmt(res, strict, &capa, 2150 buf, buflen); 2151 2152 if (os_strcmp(field, "proto") == 0) 2153 return ctrl_iface_get_capability_proto(res, strict, &capa, 2154 buf, buflen); 2155 2156 if (os_strcmp(field, "auth_alg") == 0) 2157 return ctrl_iface_get_capability_auth_alg(res, strict, &capa, 2158 buf, buflen); 2159 2160 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'", 2161 field); 2162 2163 return -1; 2164 } 2165 2166 2167 #ifdef CONFIG_INTERWORKING 2168 static char * anqp_add_hex(char *pos, char *end, const char *title, 2169 struct wpabuf *data) 2170 { 2171 char *start = pos; 2172 size_t i; 2173 int ret; 2174 const u8 *d; 2175 2176 if (data == NULL) 2177 return start; 2178 2179 ret = os_snprintf(pos, end - pos, "%s=", title); 2180 if (ret < 0 || ret >= end - pos) 2181 return start; 2182 pos += ret; 2183 2184 d = wpabuf_head_u8(data); 2185 for (i = 0; i < wpabuf_len(data); i++) { 2186 ret = os_snprintf(pos, end - pos, "%02x", *d++); 2187 if (ret < 0 || ret >= end - pos) 2188 return start; 2189 pos += ret; 2190 } 2191 2192 ret = os_snprintf(pos, end - pos, "\n"); 2193 if (ret < 0 || ret >= end - pos) 2194 return start; 2195 pos += ret; 2196 2197 return pos; 2198 } 2199 #endif /* CONFIG_INTERWORKING */ 2200 2201 2202 static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, 2203 unsigned long mask, char *buf, size_t buflen) 2204 { 2205 size_t i; 2206 int ret; 2207 char *pos, *end; 2208 const u8 *ie, *ie2; 2209 struct os_time now; 2210 2211 os_get_time(&now); 2212 pos = buf; 2213 end = buf + buflen; 2214 2215 if (mask & WPA_BSS_MASK_ID) { 2216 ret = os_snprintf(pos, end - pos, "id=%u\n", bss->id); 2217 if (ret < 0 || ret >= end - pos) 2218 return 0; 2219 pos += ret; 2220 } 2221 2222 if (mask & WPA_BSS_MASK_BSSID) { 2223 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n", 2224 MAC2STR(bss->bssid)); 2225 if (ret < 0 || ret >= end - pos) 2226 return 0; 2227 pos += ret; 2228 } 2229 2230 if (mask & WPA_BSS_MASK_FREQ) { 2231 ret = os_snprintf(pos, end - pos, "freq=%d\n", bss->freq); 2232 if (ret < 0 || ret >= end - pos) 2233 return 0; 2234 pos += ret; 2235 } 2236 2237 if (mask & WPA_BSS_MASK_BEACON_INT) { 2238 ret = os_snprintf(pos, end - pos, "beacon_int=%d\n", 2239 bss->beacon_int); 2240 if (ret < 0 || ret >= end - pos) 2241 return 0; 2242 pos += ret; 2243 } 2244 2245 if (mask & WPA_BSS_MASK_CAPABILITIES) { 2246 ret = os_snprintf(pos, end - pos, "capabilities=0x%04x\n", 2247 bss->caps); 2248 if (ret < 0 || ret >= end - pos) 2249 return 0; 2250 pos += ret; 2251 } 2252 2253 if (mask & WPA_BSS_MASK_QUAL) { 2254 ret = os_snprintf(pos, end - pos, "qual=%d\n", bss->qual); 2255 if (ret < 0 || ret >= end - pos) 2256 return 0; 2257 pos += ret; 2258 } 2259 2260 if (mask & WPA_BSS_MASK_NOISE) { 2261 ret = os_snprintf(pos, end - pos, "noise=%d\n", bss->noise); 2262 if (ret < 0 || ret >= end - pos) 2263 return 0; 2264 pos += ret; 2265 } 2266 2267 if (mask & WPA_BSS_MASK_LEVEL) { 2268 ret = os_snprintf(pos, end - pos, "level=%d\n", bss->level); 2269 if (ret < 0 || ret >= end - pos) 2270 return 0; 2271 pos += ret; 2272 } 2273 2274 if (mask & WPA_BSS_MASK_TSF) { 2275 ret = os_snprintf(pos, end - pos, "tsf=%016llu\n", 2276 (unsigned long long) bss->tsf); 2277 if (ret < 0 || ret >= end - pos) 2278 return 0; 2279 pos += ret; 2280 } 2281 2282 if (mask & WPA_BSS_MASK_AGE) { 2283 ret = os_snprintf(pos, end - pos, "age=%d\n", 2284 (int) (now.sec - bss->last_update.sec)); 2285 if (ret < 0 || ret >= end - pos) 2286 return 0; 2287 pos += ret; 2288 } 2289 2290 if (mask & WPA_BSS_MASK_IE) { 2291 ret = os_snprintf(pos, end - pos, "ie="); 2292 if (ret < 0 || ret >= end - pos) 2293 return 0; 2294 pos += ret; 2295 2296 ie = (const u8 *) (bss + 1); 2297 for (i = 0; i < bss->ie_len; i++) { 2298 ret = os_snprintf(pos, end - pos, "%02x", *ie++); 2299 if (ret < 0 || ret >= end - pos) 2300 return 0; 2301 pos += ret; 2302 } 2303 2304 ret = os_snprintf(pos, end - pos, "\n"); 2305 if (ret < 0 || ret >= end - pos) 2306 return 0; 2307 pos += ret; 2308 } 2309 2310 if (mask & WPA_BSS_MASK_FLAGS) { 2311 ret = os_snprintf(pos, end - pos, "flags="); 2312 if (ret < 0 || ret >= end - pos) 2313 return 0; 2314 pos += ret; 2315 2316 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); 2317 if (ie) 2318 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2319 2 + ie[1]); 2320 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN); 2321 if (ie2) 2322 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2323 2 + ie2[1]); 2324 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss); 2325 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) { 2326 ret = os_snprintf(pos, end - pos, "[WEP]"); 2327 if (ret < 0 || ret >= end - pos) 2328 return 0; 2329 pos += ret; 2330 } 2331 if (bss->caps & IEEE80211_CAP_IBSS) { 2332 ret = os_snprintf(pos, end - pos, "[IBSS]"); 2333 if (ret < 0 || ret >= end - pos) 2334 return 0; 2335 pos += ret; 2336 } 2337 if (bss->caps & IEEE80211_CAP_ESS) { 2338 ret = os_snprintf(pos, end - pos, "[ESS]"); 2339 if (ret < 0 || ret >= end - pos) 2340 return 0; 2341 pos += ret; 2342 } 2343 if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE)) { 2344 ret = os_snprintf(pos, end - pos, "[P2P]"); 2345 if (ret < 0 || ret >= end - pos) 2346 return 0; 2347 pos += ret; 2348 } 2349 2350 ret = os_snprintf(pos, end - pos, "\n"); 2351 if (ret < 0 || ret >= end - pos) 2352 return 0; 2353 pos += ret; 2354 } 2355 2356 if (mask & WPA_BSS_MASK_SSID) { 2357 ret = os_snprintf(pos, end - pos, "ssid=%s\n", 2358 wpa_ssid_txt(bss->ssid, bss->ssid_len)); 2359 if (ret < 0 || ret >= end - pos) 2360 return 0; 2361 pos += ret; 2362 } 2363 2364 #ifdef CONFIG_WPS 2365 if (mask & WPA_BSS_MASK_WPS_SCAN) { 2366 ie = (const u8 *) (bss + 1); 2367 ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end); 2368 if (ret < 0 || ret >= end - pos) 2369 return 0; 2370 pos += ret; 2371 } 2372 #endif /* CONFIG_WPS */ 2373 2374 #ifdef CONFIG_P2P 2375 if (mask & WPA_BSS_MASK_P2P_SCAN) { 2376 ie = (const u8 *) (bss + 1); 2377 ret = wpas_p2p_scan_result_text(ie, bss->ie_len, pos, end); 2378 if (ret < 0 || ret >= end - pos) 2379 return 0; 2380 pos += ret; 2381 } 2382 #endif /* CONFIG_P2P */ 2383 2384 #ifdef CONFIG_INTERWORKING 2385 if (mask & WPA_BSS_MASK_INTERNETW) { 2386 pos = anqp_add_hex(pos, end, "anqp_venue_name", 2387 bss->anqp_venue_name); 2388 pos = anqp_add_hex(pos, end, "anqp_network_auth_type", 2389 bss->anqp_network_auth_type); 2390 pos = anqp_add_hex(pos, end, "anqp_roaming_consortium", 2391 bss->anqp_roaming_consortium); 2392 pos = anqp_add_hex(pos, end, "anqp_ip_addr_type_availability", 2393 bss->anqp_ip_addr_type_availability); 2394 pos = anqp_add_hex(pos, end, "anqp_nai_realm", 2395 bss->anqp_nai_realm); 2396 pos = anqp_add_hex(pos, end, "anqp_3gpp", bss->anqp_3gpp); 2397 pos = anqp_add_hex(pos, end, "anqp_domain_name", 2398 bss->anqp_domain_name); 2399 } 2400 #endif /* CONFIG_INTERWORKING */ 2401 2402 return pos - buf; 2403 } 2404 2405 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s, 2406 const char *cmd, char *buf, 2407 size_t buflen) 2408 { 2409 u8 bssid[ETH_ALEN]; 2410 size_t i; 2411 struct wpa_bss *bss = NULL; 2412 struct wpa_bss *bsslast = NULL; 2413 struct dl_list *next; 2414 int ret = 0; 2415 int len; 2416 char *ctmp; 2417 unsigned long mask = WPA_BSS_MASK_ALL; 2418 2419 if (os_strncmp(cmd, "RANGE=", 6) == 0) { 2420 if (os_strncmp(cmd + 6, "ALL", 3) == 0) { 2421 bss = dl_list_first(&wpa_s->bss_id, struct wpa_bss, 2422 list_id); 2423 bsslast = dl_list_last(&wpa_s->bss_id, struct wpa_bss, 2424 list_id); 2425 } else { /* N1-N2 */ 2426 if ((ctmp = os_strchr(cmd + 6, '-')) != NULL) { 2427 int id1, id2; 2428 id1 = atoi(cmd + 6); 2429 bss = wpa_bss_get_id(wpa_s, id1); 2430 id2 = atoi(ctmp + 1); 2431 if (id2 == 0) 2432 bsslast = dl_list_last(&wpa_s->bss_id, 2433 struct wpa_bss, 2434 list_id); 2435 else 2436 bsslast = wpa_bss_get_id(wpa_s, id2); 2437 } else { 2438 wpa_printf(MSG_ERROR, "Wrong range format"); 2439 return 0; 2440 } 2441 } 2442 if ((ctmp = os_strstr(cmd, "MASK=")) != NULL) { 2443 mask = strtoul(ctmp + 5, NULL, 0x10); 2444 if (mask == 0) 2445 mask = WPA_BSS_MASK_ALL; 2446 } 2447 } else if (os_strcmp(cmd, "FIRST") == 0) 2448 bss = dl_list_first(&wpa_s->bss, struct wpa_bss, list); 2449 else if (os_strncmp(cmd, "ID-", 3) == 0) { 2450 i = atoi(cmd + 3); 2451 bss = wpa_bss_get_id(wpa_s, i); 2452 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) { 2453 i = atoi(cmd + 5); 2454 bss = wpa_bss_get_id(wpa_s, i); 2455 if (bss) { 2456 next = bss->list_id.next; 2457 if (next == &wpa_s->bss_id) 2458 bss = NULL; 2459 else 2460 bss = dl_list_entry(next, struct wpa_bss, 2461 list_id); 2462 } 2463 #ifdef CONFIG_P2P 2464 } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) { 2465 if (hwaddr_aton(cmd + 13, bssid) == 0) 2466 bss = wpa_bss_get_p2p_dev_addr(wpa_s, bssid); 2467 else 2468 bss = NULL; 2469 #endif /* CONFIG_P2P */ 2470 } else if (hwaddr_aton(cmd, bssid) == 0) 2471 bss = wpa_bss_get_bssid(wpa_s, bssid); 2472 else { 2473 struct wpa_bss *tmp; 2474 i = atoi(cmd); 2475 bss = NULL; 2476 dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id) 2477 { 2478 if (i-- == 0) { 2479 bss = tmp; 2480 break; 2481 } 2482 } 2483 } 2484 2485 if (bss == NULL) 2486 return 0; 2487 2488 if (bsslast == NULL) 2489 bsslast = bss; 2490 do { 2491 len = print_bss_info(wpa_s, bss, mask, buf, buflen); 2492 ret += len; 2493 buf += len; 2494 buflen -= len; 2495 if (bss == bsslast) 2496 break; 2497 next = bss->list_id.next; 2498 if (next == &wpa_s->bss_id) 2499 break; 2500 bss = dl_list_entry(next, struct wpa_bss, list_id); 2501 } while (bss && len); 2502 2503 return ret; 2504 } 2505 2506 2507 static int wpa_supplicant_ctrl_iface_ap_scan( 2508 struct wpa_supplicant *wpa_s, char *cmd) 2509 { 2510 int ap_scan = atoi(cmd); 2511 return wpa_supplicant_set_ap_scan(wpa_s, ap_scan); 2512 } 2513 2514 2515 static int wpa_supplicant_ctrl_iface_scan_interval( 2516 struct wpa_supplicant *wpa_s, char *cmd) 2517 { 2518 int scan_int = atoi(cmd); 2519 if (scan_int < 0) 2520 return -1; 2521 wpa_s->scan_interval = scan_int; 2522 return 0; 2523 } 2524 2525 2526 static int wpa_supplicant_ctrl_iface_bss_expire_age( 2527 struct wpa_supplicant *wpa_s, char *cmd) 2528 { 2529 int expire_age = atoi(cmd); 2530 return wpa_supplicant_set_bss_expiration_age(wpa_s, expire_age); 2531 } 2532 2533 2534 static int wpa_supplicant_ctrl_iface_bss_expire_count( 2535 struct wpa_supplicant *wpa_s, char *cmd) 2536 { 2537 int expire_count = atoi(cmd); 2538 return wpa_supplicant_set_bss_expiration_count(wpa_s, expire_count); 2539 } 2540 2541 2542 static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s) 2543 { 2544 wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication"); 2545 /* MLME-DELETEKEYS.request */ 2546 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0); 2547 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0); 2548 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0); 2549 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0); 2550 #ifdef CONFIG_IEEE80211W 2551 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0); 2552 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0); 2553 #endif /* CONFIG_IEEE80211W */ 2554 2555 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL, 2556 0); 2557 /* MLME-SETPROTECTION.request(None) */ 2558 wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid, 2559 MLME_SETPROTECTION_PROTECT_TYPE_NONE, 2560 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE); 2561 wpa_sm_drop_sa(wpa_s->wpa); 2562 } 2563 2564 2565 static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s, 2566 char *addr) 2567 { 2568 #ifdef CONFIG_NO_SCAN_PROCESSING 2569 return -1; 2570 #else /* CONFIG_NO_SCAN_PROCESSING */ 2571 u8 bssid[ETH_ALEN]; 2572 struct wpa_bss *bss; 2573 struct wpa_ssid *ssid = wpa_s->current_ssid; 2574 2575 if (hwaddr_aton(addr, bssid)) { 2576 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid " 2577 "address '%s'", addr); 2578 return -1; 2579 } 2580 2581 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM " MACSTR, MAC2STR(bssid)); 2582 2583 bss = wpa_bss_get_bssid(wpa_s, bssid); 2584 if (!bss) { 2585 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: Target AP not found " 2586 "from BSS table"); 2587 return -1; 2588 } 2589 2590 /* 2591 * TODO: Find best network configuration block from configuration to 2592 * allow roaming to other networks 2593 */ 2594 2595 if (!ssid) { 2596 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: No network " 2597 "configuration known for the target AP"); 2598 return -1; 2599 } 2600 2601 wpa_s->reassociate = 1; 2602 wpa_supplicant_connect(wpa_s, bss, ssid); 2603 2604 return 0; 2605 #endif /* CONFIG_NO_SCAN_PROCESSING */ 2606 } 2607 2608 2609 #ifdef CONFIG_P2P 2610 static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd) 2611 { 2612 unsigned int timeout = atoi(cmd); 2613 enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL; 2614 u8 dev_id[ETH_ALEN], *_dev_id = NULL; 2615 char *pos; 2616 2617 if (os_strstr(cmd, "type=social")) 2618 type = P2P_FIND_ONLY_SOCIAL; 2619 else if (os_strstr(cmd, "type=progressive")) 2620 type = P2P_FIND_PROGRESSIVE; 2621 2622 pos = os_strstr(cmd, "dev_id="); 2623 if (pos) { 2624 pos += 7; 2625 if (hwaddr_aton(pos, dev_id)) 2626 return -1; 2627 _dev_id = dev_id; 2628 } 2629 2630 return wpas_p2p_find(wpa_s, timeout, type, 0, NULL, _dev_id); 2631 } 2632 2633 2634 static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd, 2635 char *buf, size_t buflen) 2636 { 2637 u8 addr[ETH_ALEN]; 2638 char *pos, *pos2; 2639 char *pin = NULL; 2640 enum p2p_wps_method wps_method; 2641 int new_pin; 2642 int ret; 2643 int persistent_group; 2644 int join; 2645 int auth; 2646 int go_intent = -1; 2647 int freq = 0; 2648 2649 /* <addr> <"pbc" | "pin" | PIN> [label|display|keypad] [persistent] 2650 * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] */ 2651 2652 if (hwaddr_aton(cmd, addr)) 2653 return -1; 2654 2655 pos = cmd + 17; 2656 if (*pos != ' ') 2657 return -1; 2658 pos++; 2659 2660 persistent_group = os_strstr(pos, " persistent") != NULL; 2661 join = os_strstr(pos, " join") != NULL; 2662 auth = os_strstr(pos, " auth") != NULL; 2663 2664 pos2 = os_strstr(pos, " go_intent="); 2665 if (pos2) { 2666 pos2 += 11; 2667 go_intent = atoi(pos2); 2668 if (go_intent < 0 || go_intent > 15) 2669 return -1; 2670 } 2671 2672 pos2 = os_strstr(pos, " freq="); 2673 if (pos2) { 2674 pos2 += 6; 2675 freq = atoi(pos2); 2676 if (freq <= 0) 2677 return -1; 2678 } 2679 2680 if (os_strncmp(pos, "pin", 3) == 0) { 2681 /* Request random PIN (to be displayed) and enable the PIN */ 2682 wps_method = WPS_PIN_DISPLAY; 2683 } else if (os_strncmp(pos, "pbc", 3) == 0) { 2684 wps_method = WPS_PBC; 2685 } else { 2686 pin = pos; 2687 pos = os_strchr(pin, ' '); 2688 wps_method = WPS_PIN_KEYPAD; 2689 if (pos) { 2690 *pos++ = '\0'; 2691 if (os_strncmp(pos, "display", 7) == 0) 2692 wps_method = WPS_PIN_DISPLAY; 2693 } 2694 } 2695 2696 new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method, 2697 persistent_group, join, auth, go_intent, 2698 freq); 2699 if (new_pin == -2) { 2700 os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25); 2701 return 25; 2702 } 2703 if (new_pin == -3) { 2704 os_memcpy(buf, "FAIL-CHANNEL-UNSUPPORTED\n", 25); 2705 return 25; 2706 } 2707 if (new_pin < 0) 2708 return -1; 2709 if (wps_method == WPS_PIN_DISPLAY && pin == NULL) { 2710 ret = os_snprintf(buf, buflen, "%08d", new_pin); 2711 if (ret < 0 || (size_t) ret >= buflen) 2712 return -1; 2713 return ret; 2714 } 2715 2716 os_memcpy(buf, "OK\n", 3); 2717 return 3; 2718 } 2719 2720 2721 static int p2p_ctrl_listen(struct wpa_supplicant *wpa_s, char *cmd) 2722 { 2723 unsigned int timeout = atoi(cmd); 2724 return wpas_p2p_listen(wpa_s, timeout); 2725 } 2726 2727 2728 static int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd) 2729 { 2730 u8 addr[ETH_ALEN]; 2731 char *pos; 2732 2733 /* <addr> <config method> [join] */ 2734 2735 if (hwaddr_aton(cmd, addr)) 2736 return -1; 2737 2738 pos = cmd + 17; 2739 if (*pos != ' ') 2740 return -1; 2741 pos++; 2742 2743 return wpas_p2p_prov_disc(wpa_s, addr, pos, 2744 os_strstr(pos, "join") != NULL); 2745 } 2746 2747 2748 static int p2p_get_passphrase(struct wpa_supplicant *wpa_s, char *buf, 2749 size_t buflen) 2750 { 2751 struct wpa_ssid *ssid = wpa_s->current_ssid; 2752 2753 if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO || 2754 ssid->passphrase == NULL) 2755 return -1; 2756 2757 os_strlcpy(buf, ssid->passphrase, buflen); 2758 return os_strlen(buf); 2759 } 2760 2761 2762 static int p2p_ctrl_serv_disc_req(struct wpa_supplicant *wpa_s, char *cmd, 2763 char *buf, size_t buflen) 2764 { 2765 u64 ref; 2766 int res; 2767 u8 dst_buf[ETH_ALEN], *dst; 2768 struct wpabuf *tlvs; 2769 char *pos; 2770 size_t len; 2771 2772 if (hwaddr_aton(cmd, dst_buf)) 2773 return -1; 2774 dst = dst_buf; 2775 if (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 && 2776 dst[3] == 0 && dst[4] == 0 && dst[5] == 0) 2777 dst = NULL; 2778 pos = cmd + 17; 2779 if (*pos != ' ') 2780 return -1; 2781 pos++; 2782 2783 if (os_strncmp(pos, "upnp ", 5) == 0) { 2784 u8 version; 2785 pos += 5; 2786 if (hexstr2bin(pos, &version, 1) < 0) 2787 return -1; 2788 pos += 2; 2789 if (*pos != ' ') 2790 return -1; 2791 pos++; 2792 ref = wpas_p2p_sd_request_upnp(wpa_s, dst, version, pos); 2793 } else { 2794 len = os_strlen(pos); 2795 if (len & 1) 2796 return -1; 2797 len /= 2; 2798 tlvs = wpabuf_alloc(len); 2799 if (tlvs == NULL) 2800 return -1; 2801 if (hexstr2bin(pos, wpabuf_put(tlvs, len), len) < 0) { 2802 wpabuf_free(tlvs); 2803 return -1; 2804 } 2805 2806 ref = wpas_p2p_sd_request(wpa_s, dst, tlvs); 2807 wpabuf_free(tlvs); 2808 } 2809 if (ref == 0) 2810 return -1; 2811 res = os_snprintf(buf, buflen, "%llx", (long long unsigned) ref); 2812 if (res < 0 || (unsigned) res >= buflen) 2813 return -1; 2814 return res; 2815 } 2816 2817 2818 static int p2p_ctrl_serv_disc_cancel_req(struct wpa_supplicant *wpa_s, 2819 char *cmd) 2820 { 2821 long long unsigned val; 2822 u64 req; 2823 if (sscanf(cmd, "%llx", &val) != 1) 2824 return -1; 2825 req = val; 2826 return wpas_p2p_sd_cancel_request(wpa_s, req); 2827 } 2828 2829 2830 static int p2p_ctrl_serv_disc_resp(struct wpa_supplicant *wpa_s, char *cmd) 2831 { 2832 int freq; 2833 u8 dst[ETH_ALEN]; 2834 u8 dialog_token; 2835 struct wpabuf *resp_tlvs; 2836 char *pos, *pos2; 2837 size_t len; 2838 2839 pos = os_strchr(cmd, ' '); 2840 if (pos == NULL) 2841 return -1; 2842 *pos++ = '\0'; 2843 freq = atoi(cmd); 2844 if (freq == 0) 2845 return -1; 2846 2847 if (hwaddr_aton(pos, dst)) 2848 return -1; 2849 pos += 17; 2850 if (*pos != ' ') 2851 return -1; 2852 pos++; 2853 2854 pos2 = os_strchr(pos, ' '); 2855 if (pos2 == NULL) 2856 return -1; 2857 *pos2++ = '\0'; 2858 dialog_token = atoi(pos); 2859 2860 len = os_strlen(pos2); 2861 if (len & 1) 2862 return -1; 2863 len /= 2; 2864 resp_tlvs = wpabuf_alloc(len); 2865 if (resp_tlvs == NULL) 2866 return -1; 2867 if (hexstr2bin(pos2, wpabuf_put(resp_tlvs, len), len) < 0) { 2868 wpabuf_free(resp_tlvs); 2869 return -1; 2870 } 2871 2872 wpas_p2p_sd_response(wpa_s, freq, dst, dialog_token, resp_tlvs); 2873 wpabuf_free(resp_tlvs); 2874 return 0; 2875 } 2876 2877 2878 static int p2p_ctrl_serv_disc_external(struct wpa_supplicant *wpa_s, 2879 char *cmd) 2880 { 2881 wpa_s->p2p_sd_over_ctrl_iface = atoi(cmd); 2882 return 0; 2883 } 2884 2885 2886 static int p2p_ctrl_service_add_bonjour(struct wpa_supplicant *wpa_s, 2887 char *cmd) 2888 { 2889 char *pos; 2890 size_t len; 2891 struct wpabuf *query, *resp; 2892 2893 pos = os_strchr(cmd, ' '); 2894 if (pos == NULL) 2895 return -1; 2896 *pos++ = '\0'; 2897 2898 len = os_strlen(cmd); 2899 if (len & 1) 2900 return -1; 2901 len /= 2; 2902 query = wpabuf_alloc(len); 2903 if (query == NULL) 2904 return -1; 2905 if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) { 2906 wpabuf_free(query); 2907 return -1; 2908 } 2909 2910 len = os_strlen(pos); 2911 if (len & 1) { 2912 wpabuf_free(query); 2913 return -1; 2914 } 2915 len /= 2; 2916 resp = wpabuf_alloc(len); 2917 if (resp == NULL) { 2918 wpabuf_free(query); 2919 return -1; 2920 } 2921 if (hexstr2bin(pos, wpabuf_put(resp, len), len) < 0) { 2922 wpabuf_free(query); 2923 wpabuf_free(resp); 2924 return -1; 2925 } 2926 2927 if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0) { 2928 wpabuf_free(query); 2929 wpabuf_free(resp); 2930 return -1; 2931 } 2932 return 0; 2933 } 2934 2935 2936 static int p2p_ctrl_service_add_upnp(struct wpa_supplicant *wpa_s, char *cmd) 2937 { 2938 char *pos; 2939 u8 version; 2940 2941 pos = os_strchr(cmd, ' '); 2942 if (pos == NULL) 2943 return -1; 2944 *pos++ = '\0'; 2945 2946 if (hexstr2bin(cmd, &version, 1) < 0) 2947 return -1; 2948 2949 return wpas_p2p_service_add_upnp(wpa_s, version, pos); 2950 } 2951 2952 2953 static int p2p_ctrl_service_add(struct wpa_supplicant *wpa_s, char *cmd) 2954 { 2955 char *pos; 2956 2957 pos = os_strchr(cmd, ' '); 2958 if (pos == NULL) 2959 return -1; 2960 *pos++ = '\0'; 2961 2962 if (os_strcmp(cmd, "bonjour") == 0) 2963 return p2p_ctrl_service_add_bonjour(wpa_s, pos); 2964 if (os_strcmp(cmd, "upnp") == 0) 2965 return p2p_ctrl_service_add_upnp(wpa_s, pos); 2966 wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd); 2967 return -1; 2968 } 2969 2970 2971 static int p2p_ctrl_service_del_bonjour(struct wpa_supplicant *wpa_s, 2972 char *cmd) 2973 { 2974 size_t len; 2975 struct wpabuf *query; 2976 int ret; 2977 2978 len = os_strlen(cmd); 2979 if (len & 1) 2980 return -1; 2981 len /= 2; 2982 query = wpabuf_alloc(len); 2983 if (query == NULL) 2984 return -1; 2985 if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) { 2986 wpabuf_free(query); 2987 return -1; 2988 } 2989 2990 ret = wpas_p2p_service_del_bonjour(wpa_s, query); 2991 wpabuf_free(query); 2992 return ret; 2993 } 2994 2995 2996 static int p2p_ctrl_service_del_upnp(struct wpa_supplicant *wpa_s, char *cmd) 2997 { 2998 char *pos; 2999 u8 version; 3000 3001 pos = os_strchr(cmd, ' '); 3002 if (pos == NULL) 3003 return -1; 3004 *pos++ = '\0'; 3005 3006 if (hexstr2bin(cmd, &version, 1) < 0) 3007 return -1; 3008 3009 return wpas_p2p_service_del_upnp(wpa_s, version, pos); 3010 } 3011 3012 3013 static int p2p_ctrl_service_del(struct wpa_supplicant *wpa_s, char *cmd) 3014 { 3015 char *pos; 3016 3017 pos = os_strchr(cmd, ' '); 3018 if (pos == NULL) 3019 return -1; 3020 *pos++ = '\0'; 3021 3022 if (os_strcmp(cmd, "bonjour") == 0) 3023 return p2p_ctrl_service_del_bonjour(wpa_s, pos); 3024 if (os_strcmp(cmd, "upnp") == 0) 3025 return p2p_ctrl_service_del_upnp(wpa_s, pos); 3026 wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd); 3027 return -1; 3028 } 3029 3030 3031 static int p2p_ctrl_reject(struct wpa_supplicant *wpa_s, char *cmd) 3032 { 3033 u8 addr[ETH_ALEN]; 3034 3035 /* <addr> */ 3036 3037 if (hwaddr_aton(cmd, addr)) 3038 return -1; 3039 3040 return wpas_p2p_reject(wpa_s, addr); 3041 } 3042 3043 3044 static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd) 3045 { 3046 char *pos; 3047 int id; 3048 struct wpa_ssid *ssid; 3049 u8 peer[ETH_ALEN]; 3050 3051 id = atoi(cmd); 3052 pos = os_strstr(cmd, " peer="); 3053 if (pos) { 3054 pos += 6; 3055 if (hwaddr_aton(pos, peer)) 3056 return -1; 3057 } 3058 ssid = wpa_config_get_network(wpa_s->conf, id); 3059 if (ssid == NULL || ssid->disabled != 2) { 3060 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 3061 "for persistent P2P group", 3062 id); 3063 return -1; 3064 } 3065 3066 return wpas_p2p_invite(wpa_s, pos ? peer : NULL, ssid, NULL); 3067 } 3068 3069 3070 static int p2p_ctrl_invite_group(struct wpa_supplicant *wpa_s, char *cmd) 3071 { 3072 char *pos; 3073 u8 peer[ETH_ALEN], go_dev_addr[ETH_ALEN], *go_dev = NULL; 3074 3075 pos = os_strstr(cmd, " peer="); 3076 if (!pos) 3077 return -1; 3078 3079 *pos = '\0'; 3080 pos += 6; 3081 if (hwaddr_aton(pos, peer)) { 3082 wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'", pos); 3083 return -1; 3084 } 3085 3086 pos = os_strstr(pos, " go_dev_addr="); 3087 if (pos) { 3088 pos += 13; 3089 if (hwaddr_aton(pos, go_dev_addr)) { 3090 wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'", 3091 pos); 3092 return -1; 3093 } 3094 go_dev = go_dev_addr; 3095 } 3096 3097 return wpas_p2p_invite_group(wpa_s, cmd, peer, go_dev); 3098 } 3099 3100 3101 static int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd) 3102 { 3103 if (os_strncmp(cmd, "persistent=", 11) == 0) 3104 return p2p_ctrl_invite_persistent(wpa_s, cmd + 11); 3105 if (os_strncmp(cmd, "group=", 6) == 0) 3106 return p2p_ctrl_invite_group(wpa_s, cmd + 6); 3107 3108 return -1; 3109 } 3110 3111 3112 static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s, 3113 char *cmd, int freq) 3114 { 3115 int id; 3116 struct wpa_ssid *ssid; 3117 3118 id = atoi(cmd); 3119 ssid = wpa_config_get_network(wpa_s->conf, id); 3120 if (ssid == NULL || ssid->disabled != 2) { 3121 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 3122 "for persistent P2P group", 3123 id); 3124 return -1; 3125 } 3126 3127 return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq); 3128 } 3129 3130 3131 static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd) 3132 { 3133 int freq = 0; 3134 char *pos; 3135 3136 pos = os_strstr(cmd, "freq="); 3137 if (pos) 3138 freq = atoi(pos + 5); 3139 3140 if (os_strncmp(cmd, "persistent=", 11) == 0) 3141 return p2p_ctrl_group_add_persistent(wpa_s, cmd + 11, freq); 3142 if (os_strcmp(cmd, "persistent") == 0 || 3143 os_strncmp(cmd, "persistent ", 11) == 0) 3144 return wpas_p2p_group_add(wpa_s, 1, freq); 3145 if (os_strncmp(cmd, "freq=", 5) == 0) 3146 return wpas_p2p_group_add(wpa_s, 0, freq); 3147 3148 wpa_printf(MSG_DEBUG, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'", 3149 cmd); 3150 return -1; 3151 } 3152 3153 3154 static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd, 3155 char *buf, size_t buflen) 3156 { 3157 u8 addr[ETH_ALEN], *addr_ptr; 3158 int next, res; 3159 const struct p2p_peer_info *info; 3160 char *pos, *end; 3161 char devtype[WPS_DEV_TYPE_BUFSIZE]; 3162 struct wpa_ssid *ssid; 3163 3164 if (!wpa_s->global->p2p) 3165 return -1; 3166 3167 if (os_strcmp(cmd, "FIRST") == 0) { 3168 addr_ptr = NULL; 3169 next = 0; 3170 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) { 3171 if (hwaddr_aton(cmd + 5, addr) < 0) 3172 return -1; 3173 addr_ptr = addr; 3174 next = 1; 3175 } else { 3176 if (hwaddr_aton(cmd, addr) < 0) 3177 return -1; 3178 addr_ptr = addr; 3179 next = 0; 3180 } 3181 3182 info = p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next); 3183 if (info == NULL) 3184 return -1; 3185 3186 pos = buf; 3187 end = buf + buflen; 3188 3189 res = os_snprintf(pos, end - pos, MACSTR "\n" 3190 "pri_dev_type=%s\n" 3191 "device_name=%s\n" 3192 "manufacturer=%s\n" 3193 "model_name=%s\n" 3194 "model_number=%s\n" 3195 "serial_number=%s\n" 3196 "config_methods=0x%x\n" 3197 "dev_capab=0x%x\n" 3198 "group_capab=0x%x\n" 3199 "level=%d\n", 3200 MAC2STR(info->p2p_device_addr), 3201 wps_dev_type_bin2str(info->pri_dev_type, 3202 devtype, sizeof(devtype)), 3203 info->device_name, 3204 info->manufacturer, 3205 info->model_name, 3206 info->model_number, 3207 info->serial_number, 3208 info->config_methods, 3209 info->dev_capab, 3210 info->group_capab, 3211 info->level); 3212 if (res < 0 || res >= end - pos) 3213 return pos - buf; 3214 pos += res; 3215 3216 ssid = wpas_p2p_get_persistent(wpa_s, info->p2p_device_addr, NULL, 0); 3217 if (ssid) { 3218 res = os_snprintf(pos, end - pos, "persistent=%d\n", ssid->id); 3219 if (res < 0 || res >= end - pos) 3220 return pos - buf; 3221 pos += res; 3222 } 3223 3224 res = p2p_get_peer_info_txt(info, pos, end - pos); 3225 if (res < 0) 3226 return pos - buf; 3227 pos += res; 3228 3229 return pos - buf; 3230 } 3231 3232 3233 static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd) 3234 { 3235 char *param; 3236 3237 if (wpa_s->global->p2p == NULL) 3238 return -1; 3239 3240 param = os_strchr(cmd, ' '); 3241 if (param == NULL) 3242 return -1; 3243 *param++ = '\0'; 3244 3245 if (os_strcmp(cmd, "discoverability") == 0) { 3246 p2p_set_client_discoverability(wpa_s->global->p2p, 3247 atoi(param)); 3248 return 0; 3249 } 3250 3251 if (os_strcmp(cmd, "managed") == 0) { 3252 p2p_set_managed_oper(wpa_s->global->p2p, atoi(param)); 3253 return 0; 3254 } 3255 3256 if (os_strcmp(cmd, "listen_channel") == 0) { 3257 return p2p_set_listen_channel(wpa_s->global->p2p, 81, 3258 atoi(param)); 3259 } 3260 3261 if (os_strcmp(cmd, "ssid_postfix") == 0) { 3262 return p2p_set_ssid_postfix(wpa_s->global->p2p, (u8 *) param, 3263 os_strlen(param)); 3264 } 3265 3266 if (os_strcmp(cmd, "noa") == 0) { 3267 char *pos; 3268 int count, start, duration; 3269 /* GO NoA parameters: count,start_offset(ms),duration(ms) */ 3270 count = atoi(param); 3271 pos = os_strchr(param, ','); 3272 if (pos == NULL) 3273 return -1; 3274 pos++; 3275 start = atoi(pos); 3276 pos = os_strchr(pos, ','); 3277 if (pos == NULL) 3278 return -1; 3279 pos++; 3280 duration = atoi(pos); 3281 if (count < 0 || count > 255 || start < 0 || duration < 0) 3282 return -1; 3283 if (count == 0 && duration > 0) 3284 return -1; 3285 wpa_printf(MSG_DEBUG, "CTRL_IFACE: P2P_SET GO NoA: count=%d " 3286 "start=%d duration=%d", count, start, duration); 3287 return wpas_p2p_set_noa(wpa_s, count, start, duration); 3288 } 3289 3290 if (os_strcmp(cmd, "ps") == 0) 3291 return wpa_drv_set_p2p_powersave(wpa_s, atoi(param), -1, -1); 3292 3293 if (os_strcmp(cmd, "oppps") == 0) 3294 return wpa_drv_set_p2p_powersave(wpa_s, -1, atoi(param), -1); 3295 3296 if (os_strcmp(cmd, "ctwindow") == 0) 3297 return wpa_drv_set_p2p_powersave(wpa_s, -1, -1, atoi(param)); 3298 3299 if (os_strcmp(cmd, "disabled") == 0) { 3300 wpa_s->global->p2p_disabled = atoi(param); 3301 wpa_printf(MSG_DEBUG, "P2P functionality %s", 3302 wpa_s->global->p2p_disabled ? 3303 "disabled" : "enabled"); 3304 if (wpa_s->global->p2p_disabled) { 3305 wpas_p2p_stop_find(wpa_s); 3306 os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); 3307 p2p_flush(wpa_s->global->p2p); 3308 } 3309 return 0; 3310 } 3311 #ifdef ANDROID_P2P 3312 if (os_strcmp(cmd, "conc_pref") == 0) { 3313 if (os_strcmp(param, "sta") == 0) 3314 wpa_s->global->conc_pref = WPA_CONC_PREF_STA; 3315 else if (os_strcmp(param, "p2p") == 0) 3316 wpa_s->global->conc_pref = WPA_CONC_PREF_P2P; 3317 else { 3318 wpa_printf(MSG_INFO, "Invalid conc_pref value"); 3319 return -1; 3320 } 3321 wpa_printf(MSG_DEBUG, "Single channel concurrency preference: " 3322 "%s", param); 3323 return 0; 3324 } 3325 #endif 3326 if (os_strcmp(cmd, "force_long_sd") == 0) { 3327 wpa_s->force_long_sd = atoi(param); 3328 return 0; 3329 } 3330 3331 if (os_strcmp(cmd, "peer_filter") == 0) { 3332 u8 addr[ETH_ALEN]; 3333 if (hwaddr_aton(param, addr)) 3334 return -1; 3335 p2p_set_peer_filter(wpa_s->global->p2p, addr); 3336 return 0; 3337 } 3338 3339 if (os_strcmp(cmd, "cross_connect") == 0) 3340 return wpas_p2p_set_cross_connect(wpa_s, atoi(param)); 3341 3342 if (os_strcmp(cmd, "go_apsd") == 0) { 3343 if (os_strcmp(param, "disable") == 0) 3344 wpa_s->set_ap_uapsd = 0; 3345 else { 3346 wpa_s->set_ap_uapsd = 1; 3347 wpa_s->ap_uapsd = atoi(param); 3348 } 3349 return 0; 3350 } 3351 3352 if (os_strcmp(cmd, "client_apsd") == 0) { 3353 if (os_strcmp(param, "disable") == 0) 3354 wpa_s->set_sta_uapsd = 0; 3355 else { 3356 int be, bk, vi, vo; 3357 char *pos; 3358 /* format: BE,BK,VI,VO;max SP Length */ 3359 be = atoi(param); 3360 pos = os_strchr(param, ','); 3361 if (pos == NULL) 3362 return -1; 3363 pos++; 3364 bk = atoi(pos); 3365 pos = os_strchr(pos, ','); 3366 if (pos == NULL) 3367 return -1; 3368 pos++; 3369 vi = atoi(pos); 3370 pos = os_strchr(pos, ','); 3371 if (pos == NULL) 3372 return -1; 3373 pos++; 3374 vo = atoi(pos); 3375 /* ignore max SP Length for now */ 3376 3377 wpa_s->set_sta_uapsd = 1; 3378 wpa_s->sta_uapsd = 0; 3379 if (be) 3380 wpa_s->sta_uapsd |= BIT(0); 3381 if (bk) 3382 wpa_s->sta_uapsd |= BIT(1); 3383 if (vi) 3384 wpa_s->sta_uapsd |= BIT(2); 3385 if (vo) 3386 wpa_s->sta_uapsd |= BIT(3); 3387 } 3388 return 0; 3389 } 3390 3391 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'", 3392 cmd); 3393 3394 return -1; 3395 } 3396 3397 3398 static int p2p_ctrl_presence_req(struct wpa_supplicant *wpa_s, char *cmd) 3399 { 3400 char *pos, *pos2; 3401 unsigned int dur1 = 0, int1 = 0, dur2 = 0, int2 = 0; 3402 3403 if (cmd[0]) { 3404 pos = os_strchr(cmd, ' '); 3405 if (pos == NULL) 3406 return -1; 3407 *pos++ = '\0'; 3408 dur1 = atoi(cmd); 3409 3410 pos2 = os_strchr(pos, ' '); 3411 if (pos2) 3412 *pos2++ = '\0'; 3413 int1 = atoi(pos); 3414 } else 3415 pos2 = NULL; 3416 3417 if (pos2) { 3418 pos = os_strchr(pos2, ' '); 3419 if (pos == NULL) 3420 return -1; 3421 *pos++ = '\0'; 3422 dur2 = atoi(pos2); 3423 int2 = atoi(pos); 3424 } 3425 3426 return wpas_p2p_presence_req(wpa_s, dur1, int1, dur2, int2); 3427 } 3428 3429 3430 static int p2p_ctrl_ext_listen(struct wpa_supplicant *wpa_s, char *cmd) 3431 { 3432 char *pos; 3433 unsigned int period = 0, interval = 0; 3434 3435 if (cmd[0]) { 3436 pos = os_strchr(cmd, ' '); 3437 if (pos == NULL) 3438 return -1; 3439 *pos++ = '\0'; 3440 period = atoi(cmd); 3441 interval = atoi(pos); 3442 } 3443 3444 return wpas_p2p_ext_listen(wpa_s, period, interval); 3445 } 3446 3447 #endif /* CONFIG_P2P */ 3448 3449 3450 #ifdef CONFIG_INTERWORKING 3451 static int ctrl_interworking_connect(struct wpa_supplicant *wpa_s, char *dst) 3452 { 3453 u8 bssid[ETH_ALEN]; 3454 struct wpa_bss *bss; 3455 3456 if (hwaddr_aton(dst, bssid)) { 3457 wpa_printf(MSG_DEBUG, "Invalid BSSID '%s'", dst); 3458 return -1; 3459 } 3460 3461 bss = wpa_bss_get_bssid(wpa_s, bssid); 3462 if (bss == NULL) { 3463 wpa_printf(MSG_DEBUG, "Could not find BSS " MACSTR, 3464 MAC2STR(bssid)); 3465 return -1; 3466 } 3467 3468 return interworking_connect(wpa_s, bss); 3469 } 3470 3471 3472 static int get_anqp(struct wpa_supplicant *wpa_s, char *dst) 3473 { 3474 u8 dst_addr[ETH_ALEN]; 3475 int used; 3476 char *pos; 3477 #define MAX_ANQP_INFO_ID 100 3478 u16 id[MAX_ANQP_INFO_ID]; 3479 size_t num_id = 0; 3480 3481 used = hwaddr_aton2(dst, dst_addr); 3482 if (used < 0) 3483 return -1; 3484 pos = dst + used; 3485 while (num_id < MAX_ANQP_INFO_ID) { 3486 id[num_id] = atoi(pos); 3487 if (id[num_id]) 3488 num_id++; 3489 pos = os_strchr(pos + 1, ','); 3490 if (pos == NULL) 3491 break; 3492 pos++; 3493 } 3494 3495 if (num_id == 0) 3496 return -1; 3497 3498 return anqp_send_req(wpa_s, dst_addr, id, num_id); 3499 } 3500 #endif /* CONFIG_INTERWORKING */ 3501 3502 3503 static int wpa_supplicant_ctrl_iface_sta_autoconnect( 3504 struct wpa_supplicant *wpa_s, char *cmd) 3505 { 3506 wpa_s->auto_reconnect_disabled = atoi(cmd) == 0 ? 1 : 0; 3507 return 0; 3508 } 3509 3510 3511 static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf, 3512 size_t buflen) 3513 { 3514 struct wpa_signal_info si; 3515 int ret; 3516 3517 ret = wpa_drv_signal_poll(wpa_s, &si); 3518 if (ret) 3519 return -1; 3520 3521 ret = os_snprintf(buf, buflen, "RSSI=%d\nLINKSPEED=%d\n" 3522 "NOISE=%d\nFREQUENCY=%u\n", 3523 si.current_signal, si.current_txrate / 1000, 3524 si.current_noise, si.frequency); 3525 if (ret < 0 || (unsigned int) ret > buflen) 3526 return -1; 3527 return ret; 3528 } 3529 3530 #ifdef ANDROID 3531 static int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s, char *cmd, 3532 char *buf, size_t buflen) 3533 { 3534 int ret; 3535 3536 ret = wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen); 3537 if (ret == 0) 3538 ret = sprintf(buf, "%s\n", "OK"); 3539 return ret; 3540 } 3541 #endif 3542 3543 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, 3544 char *buf, size_t *resp_len) 3545 { 3546 char *reply; 3547 const int reply_size = 4096; 3548 int ctrl_rsp = 0; 3549 int reply_len; 3550 3551 if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 || 3552 os_strncmp(buf, "SET_NETWORK ", 12) == 0) { 3553 wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface", 3554 (const u8 *) buf, os_strlen(buf)); 3555 } else { 3556 int level = MSG_DEBUG; 3557 if (os_strcmp(buf, "PING") == 0) 3558 level = MSG_EXCESSIVE; 3559 wpa_hexdump_ascii(level, "RX ctrl_iface", 3560 (const u8 *) buf, os_strlen(buf)); 3561 } 3562 3563 reply = os_malloc(reply_size); 3564 if (reply == NULL) { 3565 *resp_len = 1; 3566 return NULL; 3567 } 3568 3569 os_memcpy(reply, "OK\n", 3); 3570 reply_len = 3; 3571 3572 if (os_strcmp(buf, "PING") == 0) { 3573 os_memcpy(reply, "PONG\n", 5); 3574 reply_len = 5; 3575 } else if (os_strncmp(buf, "RELOG", 5) == 0) { 3576 if (wpa_debug_reopen_file() < 0) 3577 reply_len = -1; 3578 } else if (os_strncmp(buf, "NOTE ", 5) == 0) { 3579 wpa_printf(MSG_INFO, "NOTE: %s", buf + 5); 3580 } else if (os_strcmp(buf, "MIB") == 0) { 3581 reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); 3582 if (reply_len >= 0) { 3583 int res; 3584 res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len, 3585 reply_size - reply_len); 3586 if (res < 0) 3587 reply_len = -1; 3588 else 3589 reply_len += res; 3590 } 3591 } else if (os_strncmp(buf, "STATUS", 6) == 0) { 3592 reply_len = wpa_supplicant_ctrl_iface_status( 3593 wpa_s, buf + 6, reply, reply_size); 3594 } else if (os_strcmp(buf, "PMKSA") == 0) { 3595 reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, reply, 3596 reply_size); 3597 } else if (os_strncmp(buf, "SET ", 4) == 0) { 3598 if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4)) 3599 reply_len = -1; 3600 } else if (os_strncmp(buf, "GET ", 4) == 0) { 3601 reply_len = wpa_supplicant_ctrl_iface_get(wpa_s, buf + 4, 3602 reply, reply_size); 3603 } else if (os_strcmp(buf, "LOGON") == 0) { 3604 eapol_sm_notify_logoff(wpa_s->eapol, FALSE); 3605 } else if (os_strcmp(buf, "LOGOFF") == 0) { 3606 eapol_sm_notify_logoff(wpa_s->eapol, TRUE); 3607 } else if (os_strcmp(buf, "REASSOCIATE") == 0) { 3608 wpa_s->normal_scans = 0; 3609 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) 3610 reply_len = -1; 3611 else { 3612 wpa_s->disconnected = 0; 3613 wpa_s->reassociate = 1; 3614 wpa_supplicant_req_scan(wpa_s, 0, 0); 3615 } 3616 } else if (os_strcmp(buf, "RECONNECT") == 0) { 3617 wpa_s->normal_scans = 0; 3618 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) 3619 reply_len = -1; 3620 else if (wpa_s->disconnected) { 3621 wpa_s->disconnected = 0; 3622 wpa_s->reassociate = 1; 3623 wpa_supplicant_req_scan(wpa_s, 0, 0); 3624 } 3625 #ifdef IEEE8021X_EAPOL 3626 } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) { 3627 if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8)) 3628 reply_len = -1; 3629 #endif /* IEEE8021X_EAPOL */ 3630 #ifdef CONFIG_PEERKEY 3631 } else if (os_strncmp(buf, "STKSTART ", 9) == 0) { 3632 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9)) 3633 reply_len = -1; 3634 #endif /* CONFIG_PEERKEY */ 3635 #ifdef CONFIG_IEEE80211R 3636 } else if (os_strncmp(buf, "FT_DS ", 6) == 0) { 3637 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6)) 3638 reply_len = -1; 3639 #endif /* CONFIG_IEEE80211R */ 3640 #ifdef CONFIG_WPS 3641 } else if (os_strcmp(buf, "WPS_PBC") == 0) { 3642 int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, NULL); 3643 if (res == -2) { 3644 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17); 3645 reply_len = 17; 3646 } else if (res) 3647 reply_len = -1; 3648 } else if (os_strncmp(buf, "WPS_PBC ", 8) == 0) { 3649 int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, buf + 8); 3650 if (res == -2) { 3651 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17); 3652 reply_len = 17; 3653 } else if (res) 3654 reply_len = -1; 3655 } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) { 3656 reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8, 3657 reply, 3658 reply_size); 3659 } else if (os_strncmp(buf, "WPS_CHECK_PIN ", 14) == 0) { 3660 reply_len = wpa_supplicant_ctrl_iface_wps_check_pin( 3661 wpa_s, buf + 14, reply, reply_size); 3662 } else if (os_strcmp(buf, "WPS_CANCEL") == 0) { 3663 if (wpas_wps_cancel(wpa_s)) 3664 reply_len = -1; 3665 #ifdef CONFIG_WPS_OOB 3666 } else if (os_strncmp(buf, "WPS_OOB ", 8) == 0) { 3667 if (wpa_supplicant_ctrl_iface_wps_oob(wpa_s, buf + 8)) 3668 reply_len = -1; 3669 #endif /* CONFIG_WPS_OOB */ 3670 } else if (os_strncmp(buf, "WPS_REG ", 8) == 0) { 3671 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8)) 3672 reply_len = -1; 3673 #ifdef CONFIG_AP 3674 } else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) { 3675 reply_len = wpa_supplicant_ctrl_iface_wps_ap_pin( 3676 wpa_s, buf + 11, reply, reply_size); 3677 #endif /* CONFIG_AP */ 3678 #ifdef CONFIG_WPS_ER 3679 } else if (os_strcmp(buf, "WPS_ER_START") == 0) { 3680 if (wpas_wps_er_start(wpa_s, NULL)) 3681 reply_len = -1; 3682 } else if (os_strncmp(buf, "WPS_ER_START ", 13) == 0) { 3683 if (wpas_wps_er_start(wpa_s, buf + 13)) 3684 reply_len = -1; 3685 } else if (os_strcmp(buf, "WPS_ER_STOP") == 0) { 3686 if (wpas_wps_er_stop(wpa_s)) 3687 reply_len = -1; 3688 } else if (os_strncmp(buf, "WPS_ER_PIN ", 11) == 0) { 3689 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s, buf + 11)) 3690 reply_len = -1; 3691 } else if (os_strncmp(buf, "WPS_ER_PBC ", 11) == 0) { 3692 int ret = wpas_wps_er_pbc(wpa_s, buf + 11); 3693 if (ret == -2) { 3694 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17); 3695 reply_len = 17; 3696 } else if (ret == -3) { 3697 os_memcpy(reply, "FAIL-UNKNOWN-UUID\n", 18); 3698 reply_len = 18; 3699 } else if (ret == -4) { 3700 os_memcpy(reply, "FAIL-NO-AP-SETTINGS\n", 20); 3701 reply_len = 20; 3702 } else if (ret) 3703 reply_len = -1; 3704 } else if (os_strncmp(buf, "WPS_ER_LEARN ", 13) == 0) { 3705 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s, buf + 13)) 3706 reply_len = -1; 3707 } else if (os_strncmp(buf, "WPS_ER_SET_CONFIG ", 18) == 0) { 3708 if (wpa_supplicant_ctrl_iface_wps_er_set_config(wpa_s, 3709 buf + 18)) 3710 reply_len = -1; 3711 } else if (os_strncmp(buf, "WPS_ER_CONFIG ", 14) == 0) { 3712 if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s, buf + 14)) 3713 reply_len = -1; 3714 #endif /* CONFIG_WPS_ER */ 3715 #endif /* CONFIG_WPS */ 3716 #ifdef CONFIG_IBSS_RSN 3717 } else if (os_strncmp(buf, "IBSS_RSN ", 9) == 0) { 3718 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s, buf + 9)) 3719 reply_len = -1; 3720 #endif /* CONFIG_IBSS_RSN */ 3721 #ifdef CONFIG_P2P 3722 } else if (os_strncmp(buf, "P2P_FIND ", 9) == 0) { 3723 if (p2p_ctrl_find(wpa_s, buf + 9)) 3724 reply_len = -1; 3725 } else if (os_strcmp(buf, "P2P_FIND") == 0) { 3726 if (p2p_ctrl_find(wpa_s, "")) 3727 reply_len = -1; 3728 } else if (os_strcmp(buf, "P2P_STOP_FIND") == 0) { 3729 wpas_p2p_stop_find(wpa_s); 3730 } else if (os_strncmp(buf, "P2P_CONNECT ", 12) == 0) { 3731 reply_len = p2p_ctrl_connect(wpa_s, buf + 12, reply, 3732 reply_size); 3733 } else if (os_strncmp(buf, "P2P_LISTEN ", 11) == 0) { 3734 if (p2p_ctrl_listen(wpa_s, buf + 11)) 3735 reply_len = -1; 3736 } else if (os_strcmp(buf, "P2P_LISTEN") == 0) { 3737 if (p2p_ctrl_listen(wpa_s, "")) 3738 reply_len = -1; 3739 } else if (os_strncmp(buf, "P2P_GROUP_REMOVE ", 17) == 0) { 3740 if (wpas_p2p_group_remove(wpa_s, buf + 17)) 3741 reply_len = -1; 3742 } else if (os_strcmp(buf, "P2P_GROUP_ADD") == 0) { 3743 if (wpas_p2p_group_add(wpa_s, 0, 0)) 3744 reply_len = -1; 3745 } else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) { 3746 if (p2p_ctrl_group_add(wpa_s, buf + 14)) 3747 reply_len = -1; 3748 } else if (os_strncmp(buf, "P2P_PROV_DISC ", 14) == 0) { 3749 if (p2p_ctrl_prov_disc(wpa_s, buf + 14)) 3750 reply_len = -1; 3751 } else if (os_strcmp(buf, "P2P_GET_PASSPHRASE") == 0) { 3752 reply_len = p2p_get_passphrase(wpa_s, reply, reply_size); 3753 } else if (os_strncmp(buf, "P2P_SERV_DISC_REQ ", 18) == 0) { 3754 reply_len = p2p_ctrl_serv_disc_req(wpa_s, buf + 18, reply, 3755 reply_size); 3756 } else if (os_strncmp(buf, "P2P_SERV_DISC_CANCEL_REQ ", 25) == 0) { 3757 if (p2p_ctrl_serv_disc_cancel_req(wpa_s, buf + 25) < 0) 3758 reply_len = -1; 3759 } else if (os_strncmp(buf, "P2P_SERV_DISC_RESP ", 19) == 0) { 3760 if (p2p_ctrl_serv_disc_resp(wpa_s, buf + 19) < 0) 3761 reply_len = -1; 3762 } else if (os_strcmp(buf, "P2P_SERVICE_UPDATE") == 0) { 3763 wpas_p2p_sd_service_update(wpa_s); 3764 } else if (os_strncmp(buf, "P2P_SERV_DISC_EXTERNAL ", 23) == 0) { 3765 if (p2p_ctrl_serv_disc_external(wpa_s, buf + 23) < 0) 3766 reply_len = -1; 3767 } else if (os_strcmp(buf, "P2P_SERVICE_FLUSH") == 0) { 3768 wpas_p2p_service_flush(wpa_s); 3769 } else if (os_strncmp(buf, "P2P_SERVICE_ADD ", 16) == 0) { 3770 if (p2p_ctrl_service_add(wpa_s, buf + 16) < 0) 3771 reply_len = -1; 3772 } else if (os_strncmp(buf, "P2P_SERVICE_DEL ", 16) == 0) { 3773 if (p2p_ctrl_service_del(wpa_s, buf + 16) < 0) 3774 reply_len = -1; 3775 } else if (os_strncmp(buf, "P2P_REJECT ", 11) == 0) { 3776 if (p2p_ctrl_reject(wpa_s, buf + 11) < 0) 3777 reply_len = -1; 3778 } else if (os_strncmp(buf, "P2P_INVITE ", 11) == 0) { 3779 if (p2p_ctrl_invite(wpa_s, buf + 11) < 0) 3780 reply_len = -1; 3781 } else if (os_strncmp(buf, "P2P_PEER ", 9) == 0) { 3782 reply_len = p2p_ctrl_peer(wpa_s, buf + 9, reply, 3783 reply_size); 3784 } else if (os_strncmp(buf, "P2P_SET ", 8) == 0) { 3785 if (p2p_ctrl_set(wpa_s, buf + 8) < 0) 3786 reply_len = -1; 3787 } else if (os_strcmp(buf, "P2P_FLUSH") == 0) { 3788 os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); 3789 wpa_s->force_long_sd = 0; 3790 if (wpa_s->global->p2p) 3791 p2p_flush(wpa_s->global->p2p); 3792 } else if (os_strncmp(buf, "P2P_UNAUTHORIZE ", 16) == 0) { 3793 if (wpas_p2p_unauthorize(wpa_s, buf + 16) < 0) 3794 reply_len = -1; 3795 } else if (os_strcmp(buf, "P2P_CANCEL") == 0) { 3796 if (wpas_p2p_cancel(wpa_s)) 3797 reply_len = -1; 3798 } else if (os_strncmp(buf, "P2P_PRESENCE_REQ ", 17) == 0) { 3799 if (p2p_ctrl_presence_req(wpa_s, buf + 17) < 0) 3800 reply_len = -1; 3801 } else if (os_strcmp(buf, "P2P_PRESENCE_REQ") == 0) { 3802 if (p2p_ctrl_presence_req(wpa_s, "") < 0) 3803 reply_len = -1; 3804 } else if (os_strncmp(buf, "P2P_EXT_LISTEN ", 15) == 0) { 3805 if (p2p_ctrl_ext_listen(wpa_s, buf + 15) < 0) 3806 reply_len = -1; 3807 } else if (os_strcmp(buf, "P2P_EXT_LISTEN") == 0) { 3808 if (p2p_ctrl_ext_listen(wpa_s, "") < 0) 3809 reply_len = -1; 3810 #endif /* CONFIG_P2P */ 3811 #ifdef CONFIG_INTERWORKING 3812 } else if (os_strcmp(buf, "FETCH_ANQP") == 0) { 3813 if (interworking_fetch_anqp(wpa_s) < 0) 3814 reply_len = -1; 3815 } else if (os_strcmp(buf, "STOP_FETCH_ANQP") == 0) { 3816 interworking_stop_fetch_anqp(wpa_s); 3817 } else if (os_strncmp(buf, "INTERWORKING_SELECT", 19) == 0) { 3818 if (interworking_select(wpa_s, os_strstr(buf + 19, "auto") != 3819 NULL) < 0) 3820 reply_len = -1; 3821 } else if (os_strncmp(buf, "INTERWORKING_CONNECT ", 21) == 0) { 3822 if (ctrl_interworking_connect(wpa_s, buf + 21) < 0) 3823 reply_len = -1; 3824 } else if (os_strncmp(buf, "ANQP_GET ", 9) == 0) { 3825 if (get_anqp(wpa_s, buf + 9) < 0) 3826 reply_len = -1; 3827 #endif /* CONFIG_INTERWORKING */ 3828 } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0) 3829 { 3830 if (wpa_supplicant_ctrl_iface_ctrl_rsp( 3831 wpa_s, buf + os_strlen(WPA_CTRL_RSP))) 3832 reply_len = -1; 3833 else 3834 ctrl_rsp = 1; 3835 } else if (os_strcmp(buf, "RECONFIGURE") == 0) { 3836 if (wpa_supplicant_reload_configuration(wpa_s)) 3837 reply_len = -1; 3838 } else if (os_strcmp(buf, "TERMINATE") == 0) { 3839 wpa_supplicant_terminate_proc(wpa_s->global); 3840 } else if (os_strncmp(buf, "BSSID ", 6) == 0) { 3841 if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6)) 3842 reply_len = -1; 3843 } else if (os_strncmp(buf, "BLACKLIST", 9) == 0) { 3844 reply_len = wpa_supplicant_ctrl_iface_blacklist( 3845 wpa_s, buf + 9, reply, reply_size); 3846 } else if (os_strncmp(buf, "LOG_LEVEL", 9) == 0) { 3847 reply_len = wpa_supplicant_ctrl_iface_log_level( 3848 wpa_s, buf + 9, reply, reply_size); 3849 } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) { 3850 reply_len = wpa_supplicant_ctrl_iface_list_networks( 3851 wpa_s, reply, reply_size); 3852 } else if (os_strcmp(buf, "DISCONNECT") == 0) { 3853 wpa_s->reassociate = 0; 3854 wpa_s->disconnected = 1; 3855 wpa_supplicant_cancel_sched_scan(wpa_s); 3856 wpa_supplicant_deauthenticate(wpa_s, 3857 WLAN_REASON_DEAUTH_LEAVING); 3858 } else if (os_strcmp(buf, "SCAN") == 0) { 3859 wpa_s->normal_scans = 0; 3860 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) 3861 reply_len = -1; 3862 else { 3863 if (!wpa_s->scanning && 3864 ((wpa_s->wpa_state <= WPA_SCANNING) || 3865 (wpa_s->wpa_state == WPA_COMPLETED))) { 3866 wpa_s->scan_req = 2; 3867 wpa_supplicant_req_scan(wpa_s, 0, 0); 3868 } else { 3869 wpa_printf(MSG_DEBUG, "Ongoing scan action - " 3870 "reject new request"); 3871 reply_len = os_snprintf(reply, reply_size, 3872 "FAIL-BUSY\n"); 3873 } 3874 } 3875 } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) { 3876 reply_len = wpa_supplicant_ctrl_iface_scan_results( 3877 wpa_s, reply, reply_size); 3878 } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) { 3879 if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15)) 3880 reply_len = -1; 3881 } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) { 3882 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15)) 3883 reply_len = -1; 3884 } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) { 3885 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16)) 3886 reply_len = -1; 3887 } else if (os_strcmp(buf, "ADD_NETWORK") == 0) { 3888 reply_len = wpa_supplicant_ctrl_iface_add_network( 3889 wpa_s, reply, reply_size); 3890 } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) { 3891 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15)) 3892 reply_len = -1; 3893 } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) { 3894 if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12)) 3895 reply_len = -1; 3896 } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) { 3897 reply_len = wpa_supplicant_ctrl_iface_get_network( 3898 wpa_s, buf + 12, reply, reply_size); 3899 #ifndef CONFIG_NO_CONFIG_WRITE 3900 } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) { 3901 if (wpa_supplicant_ctrl_iface_save_config(wpa_s)) 3902 reply_len = -1; 3903 #endif /* CONFIG_NO_CONFIG_WRITE */ 3904 } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) { 3905 reply_len = wpa_supplicant_ctrl_iface_get_capability( 3906 wpa_s, buf + 15, reply, reply_size); 3907 } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) { 3908 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8)) 3909 reply_len = -1; 3910 } else if (os_strncmp(buf, "SCAN_INTERVAL ", 14) == 0) { 3911 if (wpa_supplicant_ctrl_iface_scan_interval(wpa_s, buf + 14)) 3912 reply_len = -1; 3913 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) { 3914 reply_len = wpa_supplicant_global_iface_list( 3915 wpa_s->global, reply, reply_size); 3916 } else if (os_strcmp(buf, "INTERFACES") == 0) { 3917 reply_len = wpa_supplicant_global_iface_interfaces( 3918 wpa_s->global, reply, reply_size); 3919 } else if (os_strncmp(buf, "BSS ", 4) == 0) { 3920 reply_len = wpa_supplicant_ctrl_iface_bss( 3921 wpa_s, buf + 4, reply, reply_size); 3922 #ifdef CONFIG_AP 3923 } else if (os_strcmp(buf, "STA-FIRST") == 0) { 3924 reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); 3925 } else if (os_strncmp(buf, "STA ", 4) == 0) { 3926 reply_len = ap_ctrl_iface_sta(wpa_s, buf + 4, reply, 3927 reply_size); 3928 } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { 3929 reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, 3930 reply_size); 3931 #endif /* CONFIG_AP */ 3932 } else if (os_strcmp(buf, "SUSPEND") == 0) { 3933 wpas_notify_suspend(wpa_s->global); 3934 } else if (os_strcmp(buf, "RESUME") == 0) { 3935 wpas_notify_resume(wpa_s->global); 3936 } else if (os_strcmp(buf, "DROP_SA") == 0) { 3937 wpa_supplicant_ctrl_iface_drop_sa(wpa_s); 3938 } else if (os_strncmp(buf, "ROAM ", 5) == 0) { 3939 if (wpa_supplicant_ctrl_iface_roam(wpa_s, buf + 5)) 3940 reply_len = -1; 3941 } else if (os_strncmp(buf, "STA_AUTOCONNECT ", 16) == 0) { 3942 if (wpa_supplicant_ctrl_iface_sta_autoconnect(wpa_s, buf + 16)) 3943 reply_len = -1; 3944 } else if (os_strncmp(buf, "BSS_EXPIRE_AGE ", 15) == 0) { 3945 if (wpa_supplicant_ctrl_iface_bss_expire_age(wpa_s, buf + 15)) 3946 reply_len = -1; 3947 } else if (os_strncmp(buf, "BSS_EXPIRE_COUNT ", 17) == 0) { 3948 if (wpa_supplicant_ctrl_iface_bss_expire_count(wpa_s, 3949 buf + 17)) 3950 reply_len = -1; 3951 #ifdef CONFIG_TDLS 3952 } else if (os_strncmp(buf, "TDLS_DISCOVER ", 14) == 0) { 3953 if (wpa_supplicant_ctrl_iface_tdls_discover(wpa_s, buf + 14)) 3954 reply_len = -1; 3955 } else if (os_strncmp(buf, "TDLS_SETUP ", 11) == 0) { 3956 if (wpa_supplicant_ctrl_iface_tdls_setup(wpa_s, buf + 11)) 3957 reply_len = -1; 3958 } else if (os_strncmp(buf, "TDLS_TEARDOWN ", 14) == 0) { 3959 if (wpa_supplicant_ctrl_iface_tdls_teardown(wpa_s, buf + 14)) 3960 reply_len = -1; 3961 #endif /* CONFIG_TDLS */ 3962 } else if (os_strncmp(buf, "SIGNAL_POLL", 11) == 0) { 3963 reply_len = wpa_supplicant_signal_poll(wpa_s, reply, 3964 reply_size); 3965 #ifdef ANDROID 3966 } else if (os_strncmp(buf, "DRIVER ", 7) == 0) { 3967 reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply, 3968 reply_size); 3969 #endif 3970 } else if (os_strcmp(buf, "REAUTHENTICATE") == 0) { 3971 eapol_sm_request_reauth(wpa_s->eapol); 3972 } else { 3973 os_memcpy(reply, "UNKNOWN COMMAND\n", 16); 3974 reply_len = 16; 3975 } 3976 3977 if (reply_len < 0) { 3978 os_memcpy(reply, "FAIL\n", 5); 3979 reply_len = 5; 3980 } 3981 3982 if (ctrl_rsp) 3983 eapol_sm_notify_ctrl_response(wpa_s->eapol); 3984 3985 *resp_len = reply_len; 3986 return reply; 3987 } 3988 3989 3990 static int wpa_supplicant_global_iface_add(struct wpa_global *global, 3991 char *cmd) 3992 { 3993 struct wpa_interface iface; 3994 char *pos; 3995 3996 /* 3997 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param> 3998 * TAB<bridge_ifname> 3999 */ 4000 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd); 4001 4002 os_memset(&iface, 0, sizeof(iface)); 4003 4004 do { 4005 iface.ifname = pos = cmd; 4006 pos = os_strchr(pos, '\t'); 4007 if (pos) 4008 *pos++ = '\0'; 4009 if (iface.ifname[0] == '\0') 4010 return -1; 4011 if (pos == NULL) 4012 break; 4013 4014 iface.confname = pos; 4015 pos = os_strchr(pos, '\t'); 4016 if (pos) 4017 *pos++ = '\0'; 4018 if (iface.confname[0] == '\0') 4019 iface.confname = NULL; 4020 if (pos == NULL) 4021 break; 4022 4023 iface.driver = pos; 4024 pos = os_strchr(pos, '\t'); 4025 if (pos) 4026 *pos++ = '\0'; 4027 if (iface.driver[0] == '\0') 4028 iface.driver = NULL; 4029 if (pos == NULL) 4030 break; 4031 4032 iface.ctrl_interface = pos; 4033 pos = os_strchr(pos, '\t'); 4034 if (pos) 4035 *pos++ = '\0'; 4036 if (iface.ctrl_interface[0] == '\0') 4037 iface.ctrl_interface = NULL; 4038 if (pos == NULL) 4039 break; 4040 4041 iface.driver_param = pos; 4042 pos = os_strchr(pos, '\t'); 4043 if (pos) 4044 *pos++ = '\0'; 4045 if (iface.driver_param[0] == '\0') 4046 iface.driver_param = NULL; 4047 if (pos == NULL) 4048 break; 4049 4050 iface.bridge_ifname = pos; 4051 pos = os_strchr(pos, '\t'); 4052 if (pos) 4053 *pos++ = '\0'; 4054 if (iface.bridge_ifname[0] == '\0') 4055 iface.bridge_ifname = NULL; 4056 if (pos == NULL) 4057 break; 4058 } while (0); 4059 4060 if (wpa_supplicant_get_iface(global, iface.ifname)) 4061 return -1; 4062 4063 return wpa_supplicant_add_iface(global, &iface) ? 0 : -1; 4064 } 4065 4066 4067 static int wpa_supplicant_global_iface_remove(struct wpa_global *global, 4068 char *cmd) 4069 { 4070 struct wpa_supplicant *wpa_s; 4071 4072 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd); 4073 4074 wpa_s = wpa_supplicant_get_iface(global, cmd); 4075 if (wpa_s == NULL) 4076 return -1; 4077 return wpa_supplicant_remove_iface(global, wpa_s, 0); 4078 } 4079 4080 4081 static void wpa_free_iface_info(struct wpa_interface_info *iface) 4082 { 4083 struct wpa_interface_info *prev; 4084 4085 while (iface) { 4086 prev = iface; 4087 iface = iface->next; 4088 4089 os_free(prev->ifname); 4090 os_free(prev->desc); 4091 os_free(prev); 4092 } 4093 } 4094 4095 4096 static int wpa_supplicant_global_iface_list(struct wpa_global *global, 4097 char *buf, int len) 4098 { 4099 int i, res; 4100 struct wpa_interface_info *iface = NULL, *last = NULL, *tmp; 4101 char *pos, *end; 4102 4103 for (i = 0; wpa_drivers[i]; i++) { 4104 struct wpa_driver_ops *drv = wpa_drivers[i]; 4105 if (drv->get_interfaces == NULL) 4106 continue; 4107 tmp = drv->get_interfaces(global->drv_priv[i]); 4108 if (tmp == NULL) 4109 continue; 4110 4111 if (last == NULL) 4112 iface = last = tmp; 4113 else 4114 last->next = tmp; 4115 while (last->next) 4116 last = last->next; 4117 } 4118 4119 pos = buf; 4120 end = buf + len; 4121 for (tmp = iface; tmp; tmp = tmp->next) { 4122 res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n", 4123 tmp->drv_name, tmp->ifname, 4124 tmp->desc ? tmp->desc : ""); 4125 if (res < 0 || res >= end - pos) { 4126 *pos = '\0'; 4127 break; 4128 } 4129 pos += res; 4130 } 4131 4132 wpa_free_iface_info(iface); 4133 4134 return pos - buf; 4135 } 4136 4137 4138 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global, 4139 char *buf, int len) 4140 { 4141 int res; 4142 char *pos, *end; 4143 struct wpa_supplicant *wpa_s; 4144 4145 wpa_s = global->ifaces; 4146 pos = buf; 4147 end = buf + len; 4148 4149 while (wpa_s) { 4150 res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname); 4151 if (res < 0 || res >= end - pos) { 4152 *pos = '\0'; 4153 break; 4154 } 4155 pos += res; 4156 wpa_s = wpa_s->next; 4157 } 4158 return pos - buf; 4159 } 4160 4161 4162 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global, 4163 char *buf, size_t *resp_len) 4164 { 4165 char *reply; 4166 const int reply_size = 2048; 4167 int reply_len; 4168 int level = MSG_DEBUG; 4169 4170 if (os_strcmp(buf, "PING") == 0) 4171 level = MSG_EXCESSIVE; 4172 wpa_hexdump_ascii(level, "RX global ctrl_iface", 4173 (const u8 *) buf, os_strlen(buf)); 4174 4175 reply = os_malloc(reply_size); 4176 if (reply == NULL) { 4177 *resp_len = 1; 4178 return NULL; 4179 } 4180 4181 os_memcpy(reply, "OK\n", 3); 4182 reply_len = 3; 4183 4184 if (os_strcmp(buf, "PING") == 0) { 4185 os_memcpy(reply, "PONG\n", 5); 4186 reply_len = 5; 4187 } else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) { 4188 if (wpa_supplicant_global_iface_add(global, buf + 14)) 4189 reply_len = -1; 4190 } else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) { 4191 if (wpa_supplicant_global_iface_remove(global, buf + 17)) 4192 reply_len = -1; 4193 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) { 4194 reply_len = wpa_supplicant_global_iface_list( 4195 global, reply, reply_size); 4196 } else if (os_strcmp(buf, "INTERFACES") == 0) { 4197 reply_len = wpa_supplicant_global_iface_interfaces( 4198 global, reply, reply_size); 4199 } else if (os_strcmp(buf, "TERMINATE") == 0) { 4200 wpa_supplicant_terminate_proc(global); 4201 } else if (os_strcmp(buf, "SUSPEND") == 0) { 4202 wpas_notify_suspend(global); 4203 } else if (os_strcmp(buf, "RESUME") == 0) { 4204 wpas_notify_resume(global); 4205 } else { 4206 os_memcpy(reply, "UNKNOWN COMMAND\n", 16); 4207 reply_len = 16; 4208 } 4209 4210 if (reply_len < 0) { 4211 os_memcpy(reply, "FAIL\n", 5); 4212 reply_len = 5; 4213 } 4214 4215 *resp_len = reply_len; 4216 return reply; 4217 } 4218