1 /* 2 * WPA Supplicant / Control interface (shared code for all backends) 3 * Copyright (c) 2004-2012, 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/ieee802_11_common.h" 16 #include "common/wpa_ctrl.h" 17 #include "eap_peer/eap.h" 18 #include "eapol_supp/eapol_supp_sm.h" 19 #include "rsn_supp/wpa.h" 20 #include "rsn_supp/preauth.h" 21 #include "rsn_supp/pmksa_cache.h" 22 #include "l2_packet/l2_packet.h" 23 #include "wps/wps.h" 24 #include "config.h" 25 #include "wpa_supplicant_i.h" 26 #include "driver_i.h" 27 #include "wps_supplicant.h" 28 #include "ibss_rsn.h" 29 #include "ap.h" 30 #include "p2p_supplicant.h" 31 #include "p2p/p2p.h" 32 #include "hs20_supplicant.h" 33 #include "wifi_display.h" 34 #include "notify.h" 35 #include "bss.h" 36 #include "scan.h" 37 #include "ctrl_iface.h" 38 #include "interworking.h" 39 #include "blacklist.h" 40 #include "autoscan.h" 41 #include "wnm_sta.h" 42 43 extern struct wpa_driver_ops *wpa_drivers[]; 44 45 static int wpa_supplicant_global_iface_list(struct wpa_global *global, 46 char *buf, int len); 47 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global, 48 char *buf, int len); 49 50 51 static int pno_start(struct wpa_supplicant *wpa_s) 52 { 53 int ret; 54 size_t i, num_ssid; 55 struct wpa_ssid *ssid; 56 struct wpa_driver_scan_params params; 57 58 if (wpa_s->pno) 59 return 0; 60 61 if (wpa_s->wpa_state == WPA_SCANNING) { 62 wpa_supplicant_cancel_sched_scan(wpa_s); 63 wpa_supplicant_cancel_scan(wpa_s); 64 } 65 66 os_memset(¶ms, 0, sizeof(params)); 67 68 num_ssid = 0; 69 ssid = wpa_s->conf->ssid; 70 while (ssid) { 71 if (!wpas_network_disabled(wpa_s, ssid)) 72 num_ssid++; 73 ssid = ssid->next; 74 } 75 if (num_ssid > WPAS_MAX_SCAN_SSIDS) { 76 wpa_printf(MSG_DEBUG, "PNO: Use only the first %u SSIDs from " 77 "%u", WPAS_MAX_SCAN_SSIDS, (unsigned int) num_ssid); 78 num_ssid = WPAS_MAX_SCAN_SSIDS; 79 } 80 81 if (num_ssid == 0) { 82 wpa_printf(MSG_DEBUG, "PNO: No configured SSIDs"); 83 return -1; 84 } 85 86 params.filter_ssids = os_malloc(sizeof(struct wpa_driver_scan_filter) * 87 num_ssid); 88 if (params.filter_ssids == NULL) 89 return -1; 90 i = 0; 91 ssid = wpa_s->conf->ssid; 92 while (ssid) { 93 if (!wpas_network_disabled(wpa_s, ssid)) { 94 params.ssids[i].ssid = ssid->ssid; 95 params.ssids[i].ssid_len = ssid->ssid_len; 96 params.num_ssids++; 97 os_memcpy(params.filter_ssids[i].ssid, ssid->ssid, 98 ssid->ssid_len); 99 params.filter_ssids[i].ssid_len = ssid->ssid_len; 100 params.num_filter_ssids++; 101 i++; 102 if (i == num_ssid) 103 break; 104 } 105 ssid = ssid->next; 106 } 107 108 if (wpa_s->conf->filter_rssi) 109 params.filter_rssi = wpa_s->conf->filter_rssi; 110 111 ret = wpa_drv_sched_scan(wpa_s, ¶ms, 10 * 1000); 112 os_free(params.filter_ssids); 113 if (ret == 0) 114 wpa_s->pno = 1; 115 return ret; 116 } 117 118 119 static int pno_stop(struct wpa_supplicant *wpa_s) 120 { 121 int ret = 0; 122 123 if (wpa_s->pno) { 124 wpa_s->pno = 0; 125 ret = wpa_drv_stop_sched_scan(wpa_s); 126 } 127 128 if (wpa_s->wpa_state == WPA_SCANNING) 129 wpa_supplicant_req_scan(wpa_s, 0, 0); 130 131 return ret; 132 } 133 134 135 static int set_bssid_filter(struct wpa_supplicant *wpa_s, char *val) 136 { 137 char *pos; 138 u8 addr[ETH_ALEN], *filter = NULL, *n; 139 size_t count = 0; 140 141 pos = val; 142 while (pos) { 143 if (*pos == '\0') 144 break; 145 if (hwaddr_aton(pos, addr)) { 146 os_free(filter); 147 return -1; 148 } 149 n = os_realloc_array(filter, count + 1, ETH_ALEN); 150 if (n == NULL) { 151 os_free(filter); 152 return -1; 153 } 154 filter = n; 155 os_memcpy(filter + count * ETH_ALEN, addr, ETH_ALEN); 156 count++; 157 158 pos = os_strchr(pos, ' '); 159 if (pos) 160 pos++; 161 } 162 163 wpa_hexdump(MSG_DEBUG, "bssid_filter", filter, count * ETH_ALEN); 164 os_free(wpa_s->bssid_filter); 165 wpa_s->bssid_filter = filter; 166 wpa_s->bssid_filter_count = count; 167 168 return 0; 169 } 170 171 172 static int set_disallow_aps(struct wpa_supplicant *wpa_s, char *val) 173 { 174 char *pos; 175 u8 addr[ETH_ALEN], *bssid = NULL, *n; 176 struct wpa_ssid_value *ssid = NULL, *ns; 177 size_t count = 0, ssid_count = 0; 178 struct wpa_ssid *c; 179 180 /* 181 * disallow_list ::= <ssid_spec> | <bssid_spec> | <disallow_list> | 182 * SSID_SPEC ::= ssid <SSID_HEX> 183 * BSSID_SPEC ::= bssid <BSSID_HEX> 184 */ 185 186 pos = val; 187 while (pos) { 188 if (*pos == '\0') 189 break; 190 if (os_strncmp(pos, "bssid ", 6) == 0) { 191 int res; 192 pos += 6; 193 res = hwaddr_aton2(pos, addr); 194 if (res < 0) { 195 os_free(ssid); 196 os_free(bssid); 197 wpa_printf(MSG_DEBUG, "Invalid disallow_aps " 198 "BSSID value '%s'", pos); 199 return -1; 200 } 201 pos += res; 202 n = os_realloc_array(bssid, count + 1, ETH_ALEN); 203 if (n == NULL) { 204 os_free(ssid); 205 os_free(bssid); 206 return -1; 207 } 208 bssid = n; 209 os_memcpy(bssid + count * ETH_ALEN, addr, ETH_ALEN); 210 count++; 211 } else if (os_strncmp(pos, "ssid ", 5) == 0) { 212 char *end; 213 pos += 5; 214 215 end = pos; 216 while (*end) { 217 if (*end == '\0' || *end == ' ') 218 break; 219 end++; 220 } 221 222 ns = os_realloc_array(ssid, ssid_count + 1, 223 sizeof(struct wpa_ssid_value)); 224 if (ns == NULL) { 225 os_free(ssid); 226 os_free(bssid); 227 return -1; 228 } 229 ssid = ns; 230 231 if ((end - pos) & 0x01 || end - pos > 2 * 32 || 232 hexstr2bin(pos, ssid[ssid_count].ssid, 233 (end - pos) / 2) < 0) { 234 os_free(ssid); 235 os_free(bssid); 236 wpa_printf(MSG_DEBUG, "Invalid disallow_aps " 237 "SSID value '%s'", pos); 238 return -1; 239 } 240 ssid[ssid_count].ssid_len = (end - pos) / 2; 241 wpa_hexdump_ascii(MSG_DEBUG, "disallow_aps SSID", 242 ssid[ssid_count].ssid, 243 ssid[ssid_count].ssid_len); 244 ssid_count++; 245 pos = end; 246 } else { 247 wpa_printf(MSG_DEBUG, "Unexpected disallow_aps value " 248 "'%s'", pos); 249 os_free(ssid); 250 os_free(bssid); 251 return -1; 252 } 253 254 pos = os_strchr(pos, ' '); 255 if (pos) 256 pos++; 257 } 258 259 wpa_hexdump(MSG_DEBUG, "disallow_aps_bssid", bssid, count * ETH_ALEN); 260 os_free(wpa_s->disallow_aps_bssid); 261 wpa_s->disallow_aps_bssid = bssid; 262 wpa_s->disallow_aps_bssid_count = count; 263 264 wpa_printf(MSG_DEBUG, "disallow_aps_ssid_count %d", (int) ssid_count); 265 os_free(wpa_s->disallow_aps_ssid); 266 wpa_s->disallow_aps_ssid = ssid; 267 wpa_s->disallow_aps_ssid_count = ssid_count; 268 269 if (!wpa_s->current_ssid || wpa_s->wpa_state < WPA_AUTHENTICATING) 270 return 0; 271 272 c = wpa_s->current_ssid; 273 if (c->mode != WPAS_MODE_INFRA && c->mode != WPAS_MODE_IBSS) 274 return 0; 275 276 if (!disallowed_bssid(wpa_s, wpa_s->bssid) && 277 !disallowed_ssid(wpa_s, c->ssid, c->ssid_len)) 278 return 0; 279 280 wpa_printf(MSG_DEBUG, "Disconnect and try to find another network " 281 "because current AP was marked disallowed"); 282 283 #ifdef CONFIG_SME 284 wpa_s->sme.prev_bssid_set = 0; 285 #endif /* CONFIG_SME */ 286 wpa_s->reassociate = 1; 287 wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); 288 wpa_supplicant_req_scan(wpa_s, 0, 0); 289 290 return 0; 291 } 292 293 294 static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s, 295 char *cmd) 296 { 297 char *value; 298 int ret = 0; 299 300 value = os_strchr(cmd, ' '); 301 if (value == NULL) 302 return -1; 303 *value++ = '\0'; 304 305 wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value); 306 if (os_strcasecmp(cmd, "EAPOL::heldPeriod") == 0) { 307 eapol_sm_configure(wpa_s->eapol, 308 atoi(value), -1, -1, -1); 309 } else if (os_strcasecmp(cmd, "EAPOL::authPeriod") == 0) { 310 eapol_sm_configure(wpa_s->eapol, 311 -1, atoi(value), -1, -1); 312 } else if (os_strcasecmp(cmd, "EAPOL::startPeriod") == 0) { 313 eapol_sm_configure(wpa_s->eapol, 314 -1, -1, atoi(value), -1); 315 } else if (os_strcasecmp(cmd, "EAPOL::maxStart") == 0) { 316 eapol_sm_configure(wpa_s->eapol, 317 -1, -1, -1, atoi(value)); 318 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) { 319 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME, 320 atoi(value))) 321 ret = -1; 322 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") == 323 0) { 324 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD, 325 atoi(value))) 326 ret = -1; 327 } else if (os_strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) { 328 if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value))) 329 ret = -1; 330 } else if (os_strcasecmp(cmd, "wps_fragment_size") == 0) { 331 wpa_s->wps_fragment_size = atoi(value); 332 #ifdef CONFIG_WPS_TESTING 333 } else if (os_strcasecmp(cmd, "wps_version_number") == 0) { 334 long int val; 335 val = strtol(value, NULL, 0); 336 if (val < 0 || val > 0xff) { 337 ret = -1; 338 wpa_printf(MSG_DEBUG, "WPS: Invalid " 339 "wps_version_number %ld", val); 340 } else { 341 wps_version_number = val; 342 wpa_printf(MSG_DEBUG, "WPS: Testing - force WPS " 343 "version %u.%u", 344 (wps_version_number & 0xf0) >> 4, 345 wps_version_number & 0x0f); 346 } 347 } else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) { 348 wps_testing_dummy_cred = atoi(value); 349 wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d", 350 wps_testing_dummy_cred); 351 #endif /* CONFIG_WPS_TESTING */ 352 } else if (os_strcasecmp(cmd, "ampdu") == 0) { 353 if (wpa_drv_ampdu(wpa_s, atoi(value)) < 0) 354 ret = -1; 355 #ifdef CONFIG_TDLS_TESTING 356 } else if (os_strcasecmp(cmd, "tdls_testing") == 0) { 357 extern unsigned int tdls_testing; 358 tdls_testing = strtol(value, NULL, 0); 359 wpa_printf(MSG_DEBUG, "TDLS: tdls_testing=0x%x", tdls_testing); 360 #endif /* CONFIG_TDLS_TESTING */ 361 #ifdef CONFIG_TDLS 362 } else if (os_strcasecmp(cmd, "tdls_disabled") == 0) { 363 int disabled = atoi(value); 364 wpa_printf(MSG_DEBUG, "TDLS: tdls_disabled=%d", disabled); 365 if (disabled) { 366 if (wpa_drv_tdls_oper(wpa_s, TDLS_DISABLE, NULL) < 0) 367 ret = -1; 368 } else if (wpa_drv_tdls_oper(wpa_s, TDLS_ENABLE, NULL) < 0) 369 ret = -1; 370 wpa_tdls_enable(wpa_s->wpa, !disabled); 371 #endif /* CONFIG_TDLS */ 372 } else if (os_strcasecmp(cmd, "pno") == 0) { 373 if (atoi(value)) 374 ret = pno_start(wpa_s); 375 else 376 ret = pno_stop(wpa_s); 377 } else if (os_strcasecmp(cmd, "radio_disabled") == 0) { 378 int disabled = atoi(value); 379 if (wpa_drv_radio_disable(wpa_s, disabled) < 0) 380 ret = -1; 381 else if (disabled) 382 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); 383 } else if (os_strcasecmp(cmd, "uapsd") == 0) { 384 if (os_strcmp(value, "disable") == 0) 385 wpa_s->set_sta_uapsd = 0; 386 else { 387 int be, bk, vi, vo; 388 char *pos; 389 /* format: BE,BK,VI,VO;max SP Length */ 390 be = atoi(value); 391 pos = os_strchr(value, ','); 392 if (pos == NULL) 393 return -1; 394 pos++; 395 bk = atoi(pos); 396 pos = os_strchr(pos, ','); 397 if (pos == NULL) 398 return -1; 399 pos++; 400 vi = atoi(pos); 401 pos = os_strchr(pos, ','); 402 if (pos == NULL) 403 return -1; 404 pos++; 405 vo = atoi(pos); 406 /* ignore max SP Length for now */ 407 408 wpa_s->set_sta_uapsd = 1; 409 wpa_s->sta_uapsd = 0; 410 if (be) 411 wpa_s->sta_uapsd |= BIT(0); 412 if (bk) 413 wpa_s->sta_uapsd |= BIT(1); 414 if (vi) 415 wpa_s->sta_uapsd |= BIT(2); 416 if (vo) 417 wpa_s->sta_uapsd |= BIT(3); 418 } 419 } else if (os_strcasecmp(cmd, "ps") == 0) { 420 ret = wpa_drv_set_p2p_powersave(wpa_s, atoi(value), -1, -1); 421 #ifdef CONFIG_WIFI_DISPLAY 422 } else if (os_strcasecmp(cmd, "wifi_display") == 0) { 423 wifi_display_enable(wpa_s->global, !!atoi(value)); 424 #endif /* CONFIG_WIFI_DISPLAY */ 425 } else if (os_strcasecmp(cmd, "bssid_filter") == 0) { 426 ret = set_bssid_filter(wpa_s, value); 427 } else if (os_strcasecmp(cmd, "disallow_aps") == 0) { 428 ret = set_disallow_aps(wpa_s, value); 429 } else if (os_strcasecmp(cmd, "no_keep_alive") == 0) { 430 wpa_s->no_keep_alive = !!atoi(value); 431 } else { 432 value[-1] = '='; 433 ret = wpa_config_process_global(wpa_s->conf, cmd, -1); 434 if (ret == 0) 435 wpa_supplicant_update_config(wpa_s); 436 } 437 438 return ret; 439 } 440 441 442 static int wpa_supplicant_ctrl_iface_get(struct wpa_supplicant *wpa_s, 443 char *cmd, char *buf, size_t buflen) 444 { 445 int res = -1; 446 447 wpa_printf(MSG_DEBUG, "CTRL_IFACE GET '%s'", cmd); 448 449 if (os_strcmp(cmd, "version") == 0) { 450 res = os_snprintf(buf, buflen, "%s", VERSION_STR); 451 } else if (os_strcasecmp(cmd, "country") == 0) { 452 if (wpa_s->conf->country[0] && wpa_s->conf->country[1]) 453 res = os_snprintf(buf, buflen, "%c%c", 454 wpa_s->conf->country[0], 455 wpa_s->conf->country[1]); 456 #ifdef CONFIG_WIFI_DISPLAY 457 } else if (os_strcasecmp(cmd, "wifi_display") == 0) { 458 res = os_snprintf(buf, buflen, "%d", 459 wpa_s->global->wifi_display); 460 if (res < 0 || (unsigned int) res >= buflen) 461 return -1; 462 return res; 463 #endif /* CONFIG_WIFI_DISPLAY */ 464 } 465 466 if (res < 0 || (unsigned int) res >= buflen) 467 return -1; 468 return res; 469 } 470 471 472 #ifdef IEEE8021X_EAPOL 473 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s, 474 char *addr) 475 { 476 u8 bssid[ETH_ALEN]; 477 struct wpa_ssid *ssid = wpa_s->current_ssid; 478 479 if (hwaddr_aton(addr, bssid)) { 480 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address " 481 "'%s'", addr); 482 return -1; 483 } 484 485 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid)); 486 rsn_preauth_deinit(wpa_s->wpa); 487 if (rsn_preauth_init(wpa_s->wpa, bssid, ssid ? &ssid->eap : NULL)) 488 return -1; 489 490 return 0; 491 } 492 #endif /* IEEE8021X_EAPOL */ 493 494 495 #ifdef CONFIG_PEERKEY 496 /* MLME-STKSTART.request(peer) */ 497 static int wpa_supplicant_ctrl_iface_stkstart( 498 struct wpa_supplicant *wpa_s, char *addr) 499 { 500 u8 peer[ETH_ALEN]; 501 502 if (hwaddr_aton(addr, peer)) { 503 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid " 504 "address '%s'", addr); 505 return -1; 506 } 507 508 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART " MACSTR, 509 MAC2STR(peer)); 510 511 return wpa_sm_stkstart(wpa_s->wpa, peer); 512 } 513 #endif /* CONFIG_PEERKEY */ 514 515 516 #ifdef CONFIG_TDLS 517 518 static int wpa_supplicant_ctrl_iface_tdls_discover( 519 struct wpa_supplicant *wpa_s, char *addr) 520 { 521 u8 peer[ETH_ALEN]; 522 int ret; 523 524 if (hwaddr_aton(addr, peer)) { 525 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER: invalid " 526 "address '%s'", addr); 527 return -1; 528 } 529 530 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER " MACSTR, 531 MAC2STR(peer)); 532 533 if (wpa_tdls_is_external_setup(wpa_s->wpa)) 534 ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer); 535 else 536 ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer); 537 538 return ret; 539 } 540 541 542 static int wpa_supplicant_ctrl_iface_tdls_setup( 543 struct wpa_supplicant *wpa_s, char *addr) 544 { 545 u8 peer[ETH_ALEN]; 546 int ret; 547 548 if (hwaddr_aton(addr, peer)) { 549 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP: invalid " 550 "address '%s'", addr); 551 return -1; 552 } 553 554 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP " MACSTR, 555 MAC2STR(peer)); 556 557 wpa_tdls_remove(wpa_s->wpa, peer); 558 559 if (wpa_tdls_is_external_setup(wpa_s->wpa)) 560 ret = wpa_tdls_start(wpa_s->wpa, peer); 561 else 562 ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer); 563 564 return ret; 565 } 566 567 568 static int wpa_supplicant_ctrl_iface_tdls_teardown( 569 struct wpa_supplicant *wpa_s, char *addr) 570 { 571 u8 peer[ETH_ALEN]; 572 573 if (hwaddr_aton(addr, peer)) { 574 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN: invalid " 575 "address '%s'", addr); 576 return -1; 577 } 578 579 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN " MACSTR, 580 MAC2STR(peer)); 581 582 return wpa_tdls_teardown_link(wpa_s->wpa, peer, 583 WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED); 584 } 585 586 #endif /* CONFIG_TDLS */ 587 588 589 #ifdef CONFIG_IEEE80211R 590 static int wpa_supplicant_ctrl_iface_ft_ds( 591 struct wpa_supplicant *wpa_s, char *addr) 592 { 593 u8 target_ap[ETH_ALEN]; 594 struct wpa_bss *bss; 595 const u8 *mdie; 596 597 if (hwaddr_aton(addr, target_ap)) { 598 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS: invalid " 599 "address '%s'", addr); 600 return -1; 601 } 602 603 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS " MACSTR, MAC2STR(target_ap)); 604 605 bss = wpa_bss_get_bssid(wpa_s, target_ap); 606 if (bss) 607 mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN); 608 else 609 mdie = NULL; 610 611 return wpa_ft_start_over_ds(wpa_s->wpa, target_ap, mdie); 612 } 613 #endif /* CONFIG_IEEE80211R */ 614 615 616 #ifdef CONFIG_WPS 617 static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s, 618 char *cmd) 619 { 620 u8 bssid[ETH_ALEN], *_bssid = bssid; 621 #ifdef CONFIG_P2P 622 u8 p2p_dev_addr[ETH_ALEN]; 623 #endif /* CONFIG_P2P */ 624 #ifdef CONFIG_AP 625 u8 *_p2p_dev_addr = NULL; 626 #endif /* CONFIG_AP */ 627 628 if (cmd == NULL || os_strcmp(cmd, "any") == 0 || cmd[0] == '\0') { 629 _bssid = NULL; 630 #ifdef CONFIG_P2P 631 } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) { 632 if (hwaddr_aton(cmd + 13, p2p_dev_addr)) { 633 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid " 634 "P2P Device Address '%s'", 635 cmd + 13); 636 return -1; 637 } 638 _p2p_dev_addr = p2p_dev_addr; 639 #endif /* CONFIG_P2P */ 640 } else if (hwaddr_aton(cmd, bssid)) { 641 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'", 642 cmd); 643 return -1; 644 } 645 646 #ifdef CONFIG_AP 647 if (wpa_s->ap_iface) 648 return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr); 649 #endif /* CONFIG_AP */ 650 651 return wpas_wps_start_pbc(wpa_s, _bssid, 0); 652 } 653 654 655 static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s, 656 char *cmd, char *buf, 657 size_t buflen) 658 { 659 u8 bssid[ETH_ALEN], *_bssid = bssid; 660 char *pin; 661 int ret; 662 663 pin = os_strchr(cmd, ' '); 664 if (pin) 665 *pin++ = '\0'; 666 667 if (os_strcmp(cmd, "any") == 0) 668 _bssid = NULL; 669 else if (os_strcmp(cmd, "get") == 0) { 670 ret = wps_generate_pin(); 671 goto done; 672 } else if (hwaddr_aton(cmd, bssid)) { 673 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'", 674 cmd); 675 return -1; 676 } 677 678 #ifdef CONFIG_AP 679 if (wpa_s->ap_iface) { 680 int timeout = 0; 681 char *pos; 682 683 if (pin) { 684 pos = os_strchr(pin, ' '); 685 if (pos) { 686 *pos++ = '\0'; 687 timeout = atoi(pos); 688 } 689 } 690 691 return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin, 692 buf, buflen, timeout); 693 } 694 #endif /* CONFIG_AP */ 695 696 if (pin) { 697 ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0, 698 DEV_PW_DEFAULT); 699 if (ret < 0) 700 return -1; 701 ret = os_snprintf(buf, buflen, "%s", pin); 702 if (ret < 0 || (size_t) ret >= buflen) 703 return -1; 704 return ret; 705 } 706 707 ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0, DEV_PW_DEFAULT); 708 if (ret < 0) 709 return -1; 710 711 done: 712 /* Return the generated PIN */ 713 ret = os_snprintf(buf, buflen, "%08d", ret); 714 if (ret < 0 || (size_t) ret >= buflen) 715 return -1; 716 return ret; 717 } 718 719 720 static int wpa_supplicant_ctrl_iface_wps_check_pin( 721 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) 722 { 723 char pin[9]; 724 size_t len; 725 char *pos; 726 int ret; 727 728 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS_CHECK_PIN", 729 (u8 *) cmd, os_strlen(cmd)); 730 for (pos = cmd, len = 0; *pos != '\0'; pos++) { 731 if (*pos < '0' || *pos > '9') 732 continue; 733 pin[len++] = *pos; 734 if (len == 9) { 735 wpa_printf(MSG_DEBUG, "WPS: Too long PIN"); 736 return -1; 737 } 738 } 739 if (len != 4 && len != 8) { 740 wpa_printf(MSG_DEBUG, "WPS: Invalid PIN length %d", (int) len); 741 return -1; 742 } 743 pin[len] = '\0'; 744 745 if (len == 8) { 746 unsigned int pin_val; 747 pin_val = atoi(pin); 748 if (!wps_pin_valid(pin_val)) { 749 wpa_printf(MSG_DEBUG, "WPS: Invalid checksum digit"); 750 ret = os_snprintf(buf, buflen, "FAIL-CHECKSUM\n"); 751 if (ret < 0 || (size_t) ret >= buflen) 752 return -1; 753 return ret; 754 } 755 } 756 757 ret = os_snprintf(buf, buflen, "%s", pin); 758 if (ret < 0 || (size_t) ret >= buflen) 759 return -1; 760 761 return ret; 762 } 763 764 765 #ifdef CONFIG_WPS_NFC 766 767 static int wpa_supplicant_ctrl_iface_wps_nfc(struct wpa_supplicant *wpa_s, 768 char *cmd) 769 { 770 u8 bssid[ETH_ALEN], *_bssid = bssid; 771 772 if (cmd == NULL || cmd[0] == '\0') 773 _bssid = NULL; 774 else if (hwaddr_aton(cmd, bssid)) 775 return -1; 776 777 return wpas_wps_start_nfc(wpa_s, _bssid); 778 } 779 780 781 static int wpa_supplicant_ctrl_iface_wps_nfc_config_token( 782 struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len) 783 { 784 int ndef; 785 struct wpabuf *buf; 786 int res; 787 char *pos; 788 789 pos = os_strchr(cmd, ' '); 790 if (pos) 791 *pos++ = '\0'; 792 if (os_strcmp(cmd, "WPS") == 0) 793 ndef = 0; 794 else if (os_strcmp(cmd, "NDEF") == 0) 795 ndef = 1; 796 else 797 return -1; 798 799 buf = wpas_wps_nfc_config_token(wpa_s, ndef, pos); 800 if (buf == NULL) 801 return -1; 802 803 res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf), 804 wpabuf_len(buf)); 805 reply[res++] = '\n'; 806 reply[res] = '\0'; 807 808 wpabuf_free(buf); 809 810 return res; 811 } 812 813 814 static int wpa_supplicant_ctrl_iface_wps_nfc_token( 815 struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len) 816 { 817 int ndef; 818 struct wpabuf *buf; 819 int res; 820 821 if (os_strcmp(cmd, "WPS") == 0) 822 ndef = 0; 823 else if (os_strcmp(cmd, "NDEF") == 0) 824 ndef = 1; 825 else 826 return -1; 827 828 buf = wpas_wps_nfc_token(wpa_s, ndef); 829 if (buf == NULL) 830 return -1; 831 832 res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf), 833 wpabuf_len(buf)); 834 reply[res++] = '\n'; 835 reply[res] = '\0'; 836 837 wpabuf_free(buf); 838 839 return res; 840 } 841 842 843 static int wpa_supplicant_ctrl_iface_wps_nfc_tag_read( 844 struct wpa_supplicant *wpa_s, char *pos) 845 { 846 size_t len; 847 struct wpabuf *buf; 848 int ret; 849 850 len = os_strlen(pos); 851 if (len & 0x01) 852 return -1; 853 len /= 2; 854 855 buf = wpabuf_alloc(len); 856 if (buf == NULL) 857 return -1; 858 if (hexstr2bin(pos, wpabuf_put(buf, len), len) < 0) { 859 wpabuf_free(buf); 860 return -1; 861 } 862 863 ret = wpas_wps_nfc_tag_read(wpa_s, buf); 864 wpabuf_free(buf); 865 866 return ret; 867 } 868 869 870 static int wpas_ctrl_nfc_get_handover_req_wps(struct wpa_supplicant *wpa_s, 871 char *reply, size_t max_len, 872 int cr) 873 { 874 struct wpabuf *buf; 875 int res; 876 877 buf = wpas_wps_nfc_handover_req(wpa_s, cr); 878 if (buf == NULL) 879 return -1; 880 881 res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf), 882 wpabuf_len(buf)); 883 reply[res++] = '\n'; 884 reply[res] = '\0'; 885 886 wpabuf_free(buf); 887 888 return res; 889 } 890 891 892 static int wpas_ctrl_nfc_get_handover_req(struct wpa_supplicant *wpa_s, 893 char *cmd, char *reply, 894 size_t max_len) 895 { 896 char *pos; 897 898 pos = os_strchr(cmd, ' '); 899 if (pos == NULL) 900 return -1; 901 *pos++ = '\0'; 902 903 if (os_strcmp(cmd, "NDEF") != 0) 904 return -1; 905 906 if (os_strcmp(pos, "WPS") == 0 || os_strcmp(pos, "WPS-CR") == 0) { 907 return wpas_ctrl_nfc_get_handover_req_wps( 908 wpa_s, reply, max_len, os_strcmp(pos, "WPS-CR") == 0); 909 } 910 911 return -1; 912 } 913 914 915 static int wpas_ctrl_nfc_get_handover_sel_wps(struct wpa_supplicant *wpa_s, 916 char *reply, size_t max_len, 917 int ndef, int cr, char *uuid) 918 { 919 struct wpabuf *buf; 920 int res; 921 922 buf = wpas_wps_nfc_handover_sel(wpa_s, ndef, cr, uuid); 923 if (buf == NULL) 924 return -1; 925 926 res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf), 927 wpabuf_len(buf)); 928 reply[res++] = '\n'; 929 reply[res] = '\0'; 930 931 wpabuf_free(buf); 932 933 return res; 934 } 935 936 937 static int wpas_ctrl_nfc_get_handover_sel(struct wpa_supplicant *wpa_s, 938 char *cmd, char *reply, 939 size_t max_len) 940 { 941 char *pos, *pos2; 942 int ndef; 943 944 pos = os_strchr(cmd, ' '); 945 if (pos == NULL) 946 return -1; 947 *pos++ = '\0'; 948 949 if (os_strcmp(cmd, "WPS") == 0) 950 ndef = 0; 951 else if (os_strcmp(cmd, "NDEF") == 0) 952 ndef = 1; 953 else 954 return -1; 955 956 pos2 = os_strchr(pos, ' '); 957 if (pos2) 958 *pos2++ = '\0'; 959 if (os_strcmp(pos, "WPS") == 0 || os_strcmp(pos, "WPS-CR") == 0) { 960 return wpas_ctrl_nfc_get_handover_sel_wps( 961 wpa_s, reply, max_len, ndef, 962 os_strcmp(pos, "WPS-CR") == 0, pos2); 963 } 964 965 return -1; 966 } 967 968 969 static int wpas_ctrl_nfc_rx_handover_req(struct wpa_supplicant *wpa_s, 970 char *cmd, char *reply, 971 size_t max_len) 972 { 973 size_t len; 974 struct wpabuf *buf; 975 int ret; 976 977 len = os_strlen(cmd); 978 if (len & 0x01) 979 return -1; 980 len /= 2; 981 982 buf = wpabuf_alloc(len); 983 if (buf == NULL) 984 return -1; 985 if (hexstr2bin(cmd, wpabuf_put(buf, len), len) < 0) { 986 wpabuf_free(buf); 987 return -1; 988 } 989 990 ret = wpas_wps_nfc_rx_handover_req(wpa_s, buf); 991 wpabuf_free(buf); 992 993 return ret; 994 } 995 996 997 static int wpas_ctrl_nfc_rx_handover_sel(struct wpa_supplicant *wpa_s, 998 char *cmd) 999 { 1000 size_t len; 1001 struct wpabuf *buf; 1002 int ret; 1003 1004 len = os_strlen(cmd); 1005 if (len & 0x01) 1006 return -1; 1007 len /= 2; 1008 1009 buf = wpabuf_alloc(len); 1010 if (buf == NULL) 1011 return -1; 1012 if (hexstr2bin(cmd, wpabuf_put(buf, len), len) < 0) { 1013 wpabuf_free(buf); 1014 return -1; 1015 } 1016 1017 ret = wpas_wps_nfc_rx_handover_sel(wpa_s, buf); 1018 wpabuf_free(buf); 1019 1020 return ret; 1021 } 1022 1023 1024 static int wpas_ctrl_nfc_report_handover(struct wpa_supplicant *wpa_s, 1025 char *cmd) 1026 { 1027 size_t len; 1028 struct wpabuf *req, *sel; 1029 int ret; 1030 char *pos, *role, *type, *pos2; 1031 1032 role = cmd; 1033 pos = os_strchr(role, ' '); 1034 if (pos == NULL) 1035 return -1; 1036 *pos++ = '\0'; 1037 1038 type = pos; 1039 pos = os_strchr(type, ' '); 1040 if (pos == NULL) 1041 return -1; 1042 *pos++ = '\0'; 1043 1044 pos2 = os_strchr(pos, ' '); 1045 if (pos2 == NULL) 1046 return -1; 1047 *pos2++ = '\0'; 1048 1049 len = os_strlen(pos); 1050 if (len & 0x01) 1051 return -1; 1052 len /= 2; 1053 1054 req = wpabuf_alloc(len); 1055 if (req == NULL) 1056 return -1; 1057 if (hexstr2bin(pos, wpabuf_put(req, len), len) < 0) { 1058 wpabuf_free(req); 1059 return -1; 1060 } 1061 1062 len = os_strlen(pos2); 1063 if (len & 0x01) { 1064 wpabuf_free(req); 1065 return -1; 1066 } 1067 len /= 2; 1068 1069 sel = wpabuf_alloc(len); 1070 if (sel == NULL) { 1071 wpabuf_free(req); 1072 return -1; 1073 } 1074 if (hexstr2bin(pos2, wpabuf_put(sel, len), len) < 0) { 1075 wpabuf_free(req); 1076 wpabuf_free(sel); 1077 return -1; 1078 } 1079 1080 if (os_strcmp(role, "INIT") == 0 && os_strcmp(type, "WPS") == 0) { 1081 ret = wpas_wps_nfc_report_handover(wpa_s, req, sel); 1082 } else { 1083 wpa_printf(MSG_DEBUG, "NFC: Unsupported connection handover " 1084 "reported: role=%s type=%s", role, type); 1085 ret = -1; 1086 } 1087 wpabuf_free(req); 1088 wpabuf_free(sel); 1089 1090 return ret; 1091 } 1092 1093 #endif /* CONFIG_WPS_NFC */ 1094 1095 1096 static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s, 1097 char *cmd) 1098 { 1099 u8 bssid[ETH_ALEN]; 1100 char *pin; 1101 char *new_ssid; 1102 char *new_auth; 1103 char *new_encr; 1104 char *new_key; 1105 struct wps_new_ap_settings ap; 1106 1107 pin = os_strchr(cmd, ' '); 1108 if (pin == NULL) 1109 return -1; 1110 *pin++ = '\0'; 1111 1112 if (hwaddr_aton(cmd, bssid)) { 1113 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_REG: invalid BSSID '%s'", 1114 cmd); 1115 return -1; 1116 } 1117 1118 new_ssid = os_strchr(pin, ' '); 1119 if (new_ssid == NULL) 1120 return wpas_wps_start_reg(wpa_s, bssid, pin, NULL); 1121 *new_ssid++ = '\0'; 1122 1123 new_auth = os_strchr(new_ssid, ' '); 1124 if (new_auth == NULL) 1125 return -1; 1126 *new_auth++ = '\0'; 1127 1128 new_encr = os_strchr(new_auth, ' '); 1129 if (new_encr == NULL) 1130 return -1; 1131 *new_encr++ = '\0'; 1132 1133 new_key = os_strchr(new_encr, ' '); 1134 if (new_key == NULL) 1135 return -1; 1136 *new_key++ = '\0'; 1137 1138 os_memset(&ap, 0, sizeof(ap)); 1139 ap.ssid_hex = new_ssid; 1140 ap.auth = new_auth; 1141 ap.encr = new_encr; 1142 ap.key_hex = new_key; 1143 return wpas_wps_start_reg(wpa_s, bssid, pin, &ap); 1144 } 1145 1146 1147 #ifdef CONFIG_AP 1148 static int wpa_supplicant_ctrl_iface_wps_ap_pin(struct wpa_supplicant *wpa_s, 1149 char *cmd, char *buf, 1150 size_t buflen) 1151 { 1152 int timeout = 300; 1153 char *pos; 1154 const char *pin_txt; 1155 1156 if (!wpa_s->ap_iface) 1157 return -1; 1158 1159 pos = os_strchr(cmd, ' '); 1160 if (pos) 1161 *pos++ = '\0'; 1162 1163 if (os_strcmp(cmd, "disable") == 0) { 1164 wpas_wps_ap_pin_disable(wpa_s); 1165 return os_snprintf(buf, buflen, "OK\n"); 1166 } 1167 1168 if (os_strcmp(cmd, "random") == 0) { 1169 if (pos) 1170 timeout = atoi(pos); 1171 pin_txt = wpas_wps_ap_pin_random(wpa_s, timeout); 1172 if (pin_txt == NULL) 1173 return -1; 1174 return os_snprintf(buf, buflen, "%s", pin_txt); 1175 } 1176 1177 if (os_strcmp(cmd, "get") == 0) { 1178 pin_txt = wpas_wps_ap_pin_get(wpa_s); 1179 if (pin_txt == NULL) 1180 return -1; 1181 return os_snprintf(buf, buflen, "%s", pin_txt); 1182 } 1183 1184 if (os_strcmp(cmd, "set") == 0) { 1185 char *pin; 1186 if (pos == NULL) 1187 return -1; 1188 pin = pos; 1189 pos = os_strchr(pos, ' '); 1190 if (pos) { 1191 *pos++ = '\0'; 1192 timeout = atoi(pos); 1193 } 1194 if (os_strlen(pin) > buflen) 1195 return -1; 1196 if (wpas_wps_ap_pin_set(wpa_s, pin, timeout) < 0) 1197 return -1; 1198 return os_snprintf(buf, buflen, "%s", pin); 1199 } 1200 1201 return -1; 1202 } 1203 #endif /* CONFIG_AP */ 1204 1205 1206 #ifdef CONFIG_WPS_ER 1207 static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant *wpa_s, 1208 char *cmd) 1209 { 1210 char *uuid = cmd, *pin, *pos; 1211 u8 addr_buf[ETH_ALEN], *addr = NULL; 1212 pin = os_strchr(uuid, ' '); 1213 if (pin == NULL) 1214 return -1; 1215 *pin++ = '\0'; 1216 pos = os_strchr(pin, ' '); 1217 if (pos) { 1218 *pos++ = '\0'; 1219 if (hwaddr_aton(pos, addr_buf) == 0) 1220 addr = addr_buf; 1221 } 1222 return wpas_wps_er_add_pin(wpa_s, addr, uuid, pin); 1223 } 1224 1225 1226 static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant *wpa_s, 1227 char *cmd) 1228 { 1229 char *uuid = cmd, *pin; 1230 pin = os_strchr(uuid, ' '); 1231 if (pin == NULL) 1232 return -1; 1233 *pin++ = '\0'; 1234 return wpas_wps_er_learn(wpa_s, uuid, pin); 1235 } 1236 1237 1238 static int wpa_supplicant_ctrl_iface_wps_er_set_config( 1239 struct wpa_supplicant *wpa_s, char *cmd) 1240 { 1241 char *uuid = cmd, *id; 1242 id = os_strchr(uuid, ' '); 1243 if (id == NULL) 1244 return -1; 1245 *id++ = '\0'; 1246 return wpas_wps_er_set_config(wpa_s, uuid, atoi(id)); 1247 } 1248 1249 1250 static int wpa_supplicant_ctrl_iface_wps_er_config( 1251 struct wpa_supplicant *wpa_s, char *cmd) 1252 { 1253 char *pin; 1254 char *new_ssid; 1255 char *new_auth; 1256 char *new_encr; 1257 char *new_key; 1258 struct wps_new_ap_settings ap; 1259 1260 pin = os_strchr(cmd, ' '); 1261 if (pin == NULL) 1262 return -1; 1263 *pin++ = '\0'; 1264 1265 new_ssid = os_strchr(pin, ' '); 1266 if (new_ssid == NULL) 1267 return -1; 1268 *new_ssid++ = '\0'; 1269 1270 new_auth = os_strchr(new_ssid, ' '); 1271 if (new_auth == NULL) 1272 return -1; 1273 *new_auth++ = '\0'; 1274 1275 new_encr = os_strchr(new_auth, ' '); 1276 if (new_encr == NULL) 1277 return -1; 1278 *new_encr++ = '\0'; 1279 1280 new_key = os_strchr(new_encr, ' '); 1281 if (new_key == NULL) 1282 return -1; 1283 *new_key++ = '\0'; 1284 1285 os_memset(&ap, 0, sizeof(ap)); 1286 ap.ssid_hex = new_ssid; 1287 ap.auth = new_auth; 1288 ap.encr = new_encr; 1289 ap.key_hex = new_key; 1290 return wpas_wps_er_config(wpa_s, cmd, pin, &ap); 1291 } 1292 1293 1294 #ifdef CONFIG_WPS_NFC 1295 static int wpa_supplicant_ctrl_iface_wps_er_nfc_config_token( 1296 struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len) 1297 { 1298 int ndef; 1299 struct wpabuf *buf; 1300 int res; 1301 char *uuid; 1302 1303 uuid = os_strchr(cmd, ' '); 1304 if (uuid == NULL) 1305 return -1; 1306 *uuid++ = '\0'; 1307 1308 if (os_strcmp(cmd, "WPS") == 0) 1309 ndef = 0; 1310 else if (os_strcmp(cmd, "NDEF") == 0) 1311 ndef = 1; 1312 else 1313 return -1; 1314 1315 buf = wpas_wps_er_nfc_config_token(wpa_s, ndef, uuid); 1316 if (buf == NULL) 1317 return -1; 1318 1319 res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf), 1320 wpabuf_len(buf)); 1321 reply[res++] = '\n'; 1322 reply[res] = '\0'; 1323 1324 wpabuf_free(buf); 1325 1326 return res; 1327 } 1328 #endif /* CONFIG_WPS_NFC */ 1329 #endif /* CONFIG_WPS_ER */ 1330 1331 #endif /* CONFIG_WPS */ 1332 1333 1334 #ifdef CONFIG_IBSS_RSN 1335 static int wpa_supplicant_ctrl_iface_ibss_rsn( 1336 struct wpa_supplicant *wpa_s, char *addr) 1337 { 1338 u8 peer[ETH_ALEN]; 1339 1340 if (hwaddr_aton(addr, peer)) { 1341 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN: invalid " 1342 "address '%s'", addr); 1343 return -1; 1344 } 1345 1346 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN " MACSTR, 1347 MAC2STR(peer)); 1348 1349 return ibss_rsn_start(wpa_s->ibss_rsn, peer); 1350 } 1351 #endif /* CONFIG_IBSS_RSN */ 1352 1353 1354 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s, 1355 char *rsp) 1356 { 1357 #ifdef IEEE8021X_EAPOL 1358 char *pos, *id_pos; 1359 int id; 1360 struct wpa_ssid *ssid; 1361 1362 pos = os_strchr(rsp, '-'); 1363 if (pos == NULL) 1364 return -1; 1365 *pos++ = '\0'; 1366 id_pos = pos; 1367 pos = os_strchr(pos, ':'); 1368 if (pos == NULL) 1369 return -1; 1370 *pos++ = '\0'; 1371 id = atoi(id_pos); 1372 wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id); 1373 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value", 1374 (u8 *) pos, os_strlen(pos)); 1375 1376 ssid = wpa_config_get_network(wpa_s->conf, id); 1377 if (ssid == NULL) { 1378 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 1379 "to update", id); 1380 return -1; 1381 } 1382 1383 return wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s, ssid, rsp, 1384 pos); 1385 #else /* IEEE8021X_EAPOL */ 1386 wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included"); 1387 return -1; 1388 #endif /* IEEE8021X_EAPOL */ 1389 } 1390 1391 1392 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, 1393 const char *params, 1394 char *buf, size_t buflen) 1395 { 1396 char *pos, *end, tmp[30]; 1397 int res, verbose, wps, ret; 1398 1399 verbose = os_strcmp(params, "-VERBOSE") == 0; 1400 wps = os_strcmp(params, "-WPS") == 0; 1401 pos = buf; 1402 end = buf + buflen; 1403 if (wpa_s->wpa_state >= WPA_ASSOCIATED) { 1404 struct wpa_ssid *ssid = wpa_s->current_ssid; 1405 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n", 1406 MAC2STR(wpa_s->bssid)); 1407 if (ret < 0 || ret >= end - pos) 1408 return pos - buf; 1409 pos += ret; 1410 if (ssid) { 1411 u8 *_ssid = ssid->ssid; 1412 size_t ssid_len = ssid->ssid_len; 1413 u8 ssid_buf[MAX_SSID_LEN]; 1414 if (ssid_len == 0) { 1415 int _res = wpa_drv_get_ssid(wpa_s, ssid_buf); 1416 if (_res < 0) 1417 ssid_len = 0; 1418 else 1419 ssid_len = _res; 1420 _ssid = ssid_buf; 1421 } 1422 ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n", 1423 wpa_ssid_txt(_ssid, ssid_len), 1424 ssid->id); 1425 if (ret < 0 || ret >= end - pos) 1426 return pos - buf; 1427 pos += ret; 1428 1429 if (wps && ssid->passphrase && 1430 wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && 1431 (ssid->mode == WPAS_MODE_AP || 1432 ssid->mode == WPAS_MODE_P2P_GO)) { 1433 ret = os_snprintf(pos, end - pos, 1434 "passphrase=%s\n", 1435 ssid->passphrase); 1436 if (ret < 0 || ret >= end - pos) 1437 return pos - buf; 1438 pos += ret; 1439 } 1440 if (ssid->id_str) { 1441 ret = os_snprintf(pos, end - pos, 1442 "id_str=%s\n", 1443 ssid->id_str); 1444 if (ret < 0 || ret >= end - pos) 1445 return pos - buf; 1446 pos += ret; 1447 } 1448 1449 switch (ssid->mode) { 1450 case WPAS_MODE_INFRA: 1451 ret = os_snprintf(pos, end - pos, 1452 "mode=station\n"); 1453 break; 1454 case WPAS_MODE_IBSS: 1455 ret = os_snprintf(pos, end - pos, 1456 "mode=IBSS\n"); 1457 break; 1458 case WPAS_MODE_AP: 1459 ret = os_snprintf(pos, end - pos, 1460 "mode=AP\n"); 1461 break; 1462 case WPAS_MODE_P2P_GO: 1463 ret = os_snprintf(pos, end - pos, 1464 "mode=P2P GO\n"); 1465 break; 1466 case WPAS_MODE_P2P_GROUP_FORMATION: 1467 ret = os_snprintf(pos, end - pos, 1468 "mode=P2P GO - group " 1469 "formation\n"); 1470 break; 1471 default: 1472 ret = 0; 1473 break; 1474 } 1475 if (ret < 0 || ret >= end - pos) 1476 return pos - buf; 1477 pos += ret; 1478 } 1479 1480 #ifdef CONFIG_AP 1481 if (wpa_s->ap_iface) { 1482 pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos, 1483 end - pos, 1484 verbose); 1485 } else 1486 #endif /* CONFIG_AP */ 1487 pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose); 1488 } 1489 #ifdef CONFIG_SAE 1490 if (wpa_s->wpa_state >= WPA_ASSOCIATED && 1491 wpa_s->sme.sae.state == SAE_ACCEPTED && !wpa_s->ap_iface) { 1492 ret = os_snprintf(pos, end - pos, "sae_group=%d\n", 1493 wpa_s->sme.sae.group); 1494 if (ret < 0 || ret >= end - pos) 1495 return pos - buf; 1496 pos += ret; 1497 } 1498 #endif /* CONFIG_SAE */ 1499 ret = os_snprintf(pos, end - pos, "wpa_state=%s\n", 1500 wpa_supplicant_state_txt(wpa_s->wpa_state)); 1501 if (ret < 0 || ret >= end - pos) 1502 return pos - buf; 1503 pos += ret; 1504 1505 if (wpa_s->l2 && 1506 l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) { 1507 ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp); 1508 if (ret < 0 || ret >= end - pos) 1509 return pos - buf; 1510 pos += ret; 1511 } 1512 1513 #ifdef CONFIG_P2P 1514 if (wpa_s->global->p2p) { 1515 ret = os_snprintf(pos, end - pos, "p2p_device_address=" MACSTR 1516 "\n", MAC2STR(wpa_s->global->p2p_dev_addr)); 1517 if (ret < 0 || ret >= end - pos) 1518 return pos - buf; 1519 pos += ret; 1520 } 1521 #endif /* CONFIG_P2P */ 1522 1523 ret = os_snprintf(pos, end - pos, "address=" MACSTR "\n", 1524 MAC2STR(wpa_s->own_addr)); 1525 if (ret < 0 || ret >= end - pos) 1526 return pos - buf; 1527 pos += ret; 1528 1529 #ifdef CONFIG_HS20 1530 if (wpa_s->current_bss && 1531 wpa_bss_get_vendor_ie(wpa_s->current_bss, HS20_IE_VENDOR_TYPE) && 1532 wpa_s->wpa_proto == WPA_PROTO_RSN && 1533 wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) { 1534 ret = os_snprintf(pos, end - pos, "hs20=1\n"); 1535 if (ret < 0 || ret >= end - pos) 1536 return pos - buf; 1537 pos += ret; 1538 } 1539 1540 if (wpa_s->current_ssid) { 1541 struct wpa_cred *cred; 1542 char *type; 1543 1544 for (cred = wpa_s->conf->cred; cred; cred = cred->next) { 1545 if (wpa_s->current_ssid->parent_cred != cred) 1546 continue; 1547 if (!cred->domain) 1548 continue; 1549 1550 ret = os_snprintf(pos, end - pos, "home_sp=%s\n", 1551 cred->domain); 1552 if (ret < 0 || ret >= end - pos) 1553 return pos - buf; 1554 pos += ret; 1555 1556 if (wpa_s->current_bss == NULL || 1557 wpa_s->current_bss->anqp == NULL) 1558 res = -1; 1559 else 1560 res = interworking_home_sp_cred( 1561 wpa_s, cred, 1562 wpa_s->current_bss->anqp->domain_name); 1563 if (res > 0) 1564 type = "home"; 1565 else if (res == 0) 1566 type = "roaming"; 1567 else 1568 type = "unknown"; 1569 1570 ret = os_snprintf(pos, end - pos, "sp_type=%s\n", type); 1571 if (ret < 0 || ret >= end - pos) 1572 return pos - buf; 1573 pos += ret; 1574 1575 break; 1576 } 1577 } 1578 #endif /* CONFIG_HS20 */ 1579 1580 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) || 1581 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) { 1582 res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos, 1583 verbose); 1584 if (res >= 0) 1585 pos += res; 1586 } 1587 1588 res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose); 1589 if (res >= 0) 1590 pos += res; 1591 1592 #ifdef ANDROID 1593 wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_STATE_CHANGE 1594 "id=%d state=%d BSSID=" MACSTR " SSID=%s", 1595 wpa_s->current_ssid ? wpa_s->current_ssid->id : -1, 1596 wpa_s->wpa_state, 1597 MAC2STR(wpa_s->bssid), 1598 wpa_s->current_ssid && wpa_s->current_ssid->ssid ? 1599 wpa_ssid_txt(wpa_s->current_ssid->ssid, 1600 wpa_s->current_ssid->ssid_len) : ""); 1601 if (wpa_s->wpa_state == WPA_COMPLETED) { 1602 struct wpa_ssid *ssid = wpa_s->current_ssid; 1603 wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- connection to " 1604 MACSTR " completed %s [id=%d id_str=%s]", 1605 MAC2STR(wpa_s->bssid), "(auth)", 1606 ssid ? ssid->id : -1, 1607 ssid && ssid->id_str ? ssid->id_str : ""); 1608 } 1609 #endif /* ANDROID */ 1610 1611 return pos - buf; 1612 } 1613 1614 1615 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s, 1616 char *cmd) 1617 { 1618 char *pos; 1619 int id; 1620 struct wpa_ssid *ssid; 1621 u8 bssid[ETH_ALEN]; 1622 1623 /* cmd: "<network id> <BSSID>" */ 1624 pos = os_strchr(cmd, ' '); 1625 if (pos == NULL) 1626 return -1; 1627 *pos++ = '\0'; 1628 id = atoi(cmd); 1629 wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos); 1630 if (hwaddr_aton(pos, bssid)) { 1631 wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos); 1632 return -1; 1633 } 1634 1635 ssid = wpa_config_get_network(wpa_s->conf, id); 1636 if (ssid == NULL) { 1637 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 1638 "to update", id); 1639 return -1; 1640 } 1641 1642 os_memcpy(ssid->bssid, bssid, ETH_ALEN); 1643 ssid->bssid_set = !is_zero_ether_addr(bssid); 1644 1645 return 0; 1646 } 1647 1648 1649 static int wpa_supplicant_ctrl_iface_blacklist(struct wpa_supplicant *wpa_s, 1650 char *cmd, char *buf, 1651 size_t buflen) 1652 { 1653 u8 bssid[ETH_ALEN]; 1654 struct wpa_blacklist *e; 1655 char *pos, *end; 1656 int ret; 1657 1658 /* cmd: "BLACKLIST [<BSSID>]" */ 1659 if (*cmd == '\0') { 1660 pos = buf; 1661 end = buf + buflen; 1662 e = wpa_s->blacklist; 1663 while (e) { 1664 ret = os_snprintf(pos, end - pos, MACSTR "\n", 1665 MAC2STR(e->bssid)); 1666 if (ret < 0 || ret >= end - pos) 1667 return pos - buf; 1668 pos += ret; 1669 e = e->next; 1670 } 1671 return pos - buf; 1672 } 1673 1674 cmd++; 1675 if (os_strncmp(cmd, "clear", 5) == 0) { 1676 wpa_blacklist_clear(wpa_s); 1677 os_memcpy(buf, "OK\n", 3); 1678 return 3; 1679 } 1680 1681 wpa_printf(MSG_DEBUG, "CTRL_IFACE: BLACKLIST bssid='%s'", cmd); 1682 if (hwaddr_aton(cmd, bssid)) { 1683 wpa_printf(MSG_DEBUG, "CTRL_IFACE: invalid BSSID '%s'", cmd); 1684 return -1; 1685 } 1686 1687 /* 1688 * Add the BSSID twice, so its count will be 2, causing it to be 1689 * skipped when processing scan results. 1690 */ 1691 ret = wpa_blacklist_add(wpa_s, bssid); 1692 if (ret != 0) 1693 return -1; 1694 ret = wpa_blacklist_add(wpa_s, bssid); 1695 if (ret != 0) 1696 return -1; 1697 os_memcpy(buf, "OK\n", 3); 1698 return 3; 1699 } 1700 1701 1702 extern int wpa_debug_level; 1703 extern int wpa_debug_timestamp; 1704 1705 static const char * debug_level_str(int level) 1706 { 1707 switch (level) { 1708 case MSG_EXCESSIVE: 1709 return "EXCESSIVE"; 1710 case MSG_MSGDUMP: 1711 return "MSGDUMP"; 1712 case MSG_DEBUG: 1713 return "DEBUG"; 1714 case MSG_INFO: 1715 return "INFO"; 1716 case MSG_WARNING: 1717 return "WARNING"; 1718 case MSG_ERROR: 1719 return "ERROR"; 1720 default: 1721 return "?"; 1722 } 1723 } 1724 1725 1726 static int str_to_debug_level(const char *s) 1727 { 1728 if (os_strcasecmp(s, "EXCESSIVE") == 0) 1729 return MSG_EXCESSIVE; 1730 if (os_strcasecmp(s, "MSGDUMP") == 0) 1731 return MSG_MSGDUMP; 1732 if (os_strcasecmp(s, "DEBUG") == 0) 1733 return MSG_DEBUG; 1734 if (os_strcasecmp(s, "INFO") == 0) 1735 return MSG_INFO; 1736 if (os_strcasecmp(s, "WARNING") == 0) 1737 return MSG_WARNING; 1738 if (os_strcasecmp(s, "ERROR") == 0) 1739 return MSG_ERROR; 1740 return -1; 1741 } 1742 1743 1744 static int wpa_supplicant_ctrl_iface_log_level(struct wpa_supplicant *wpa_s, 1745 char *cmd, char *buf, 1746 size_t buflen) 1747 { 1748 char *pos, *end, *stamp; 1749 int ret; 1750 1751 if (cmd == NULL) { 1752 return -1; 1753 } 1754 1755 /* cmd: "LOG_LEVEL [<level>]" */ 1756 if (*cmd == '\0') { 1757 pos = buf; 1758 end = buf + buflen; 1759 ret = os_snprintf(pos, end - pos, "Current level: %s\n" 1760 "Timestamp: %d\n", 1761 debug_level_str(wpa_debug_level), 1762 wpa_debug_timestamp); 1763 if (ret < 0 || ret >= end - pos) 1764 ret = 0; 1765 1766 return ret; 1767 } 1768 1769 while (*cmd == ' ') 1770 cmd++; 1771 1772 stamp = os_strchr(cmd, ' '); 1773 if (stamp) { 1774 *stamp++ = '\0'; 1775 while (*stamp == ' ') { 1776 stamp++; 1777 } 1778 } 1779 1780 if (cmd && os_strlen(cmd)) { 1781 int level = str_to_debug_level(cmd); 1782 if (level < 0) 1783 return -1; 1784 wpa_debug_level = level; 1785 } 1786 1787 if (stamp && os_strlen(stamp)) 1788 wpa_debug_timestamp = atoi(stamp); 1789 1790 os_memcpy(buf, "OK\n", 3); 1791 return 3; 1792 } 1793 1794 1795 static int wpa_supplicant_ctrl_iface_list_networks( 1796 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 1797 { 1798 char *pos, *end; 1799 struct wpa_ssid *ssid; 1800 int ret; 1801 1802 pos = buf; 1803 end = buf + buflen; 1804 ret = os_snprintf(pos, end - pos, 1805 "network id / ssid / bssid / flags\n"); 1806 if (ret < 0 || ret >= end - pos) 1807 return pos - buf; 1808 pos += ret; 1809 1810 ssid = wpa_s->conf->ssid; 1811 while (ssid) { 1812 ret = os_snprintf(pos, end - pos, "%d\t%s", 1813 ssid->id, 1814 wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 1815 if (ret < 0 || ret >= end - pos) 1816 return pos - buf; 1817 pos += ret; 1818 if (ssid->bssid_set) { 1819 ret = os_snprintf(pos, end - pos, "\t" MACSTR, 1820 MAC2STR(ssid->bssid)); 1821 } else { 1822 ret = os_snprintf(pos, end - pos, "\tany"); 1823 } 1824 if (ret < 0 || ret >= end - pos) 1825 return pos - buf; 1826 pos += ret; 1827 ret = os_snprintf(pos, end - pos, "\t%s%s%s%s", 1828 ssid == wpa_s->current_ssid ? 1829 "[CURRENT]" : "", 1830 ssid->disabled ? "[DISABLED]" : "", 1831 ssid->disabled_until.sec ? 1832 "[TEMP-DISABLED]" : "", 1833 ssid->disabled == 2 ? "[P2P-PERSISTENT]" : 1834 ""); 1835 if (ret < 0 || ret >= end - pos) 1836 return pos - buf; 1837 pos += ret; 1838 ret = os_snprintf(pos, end - pos, "\n"); 1839 if (ret < 0 || ret >= end - pos) 1840 return pos - buf; 1841 pos += ret; 1842 1843 ssid = ssid->next; 1844 } 1845 1846 return pos - buf; 1847 } 1848 1849 1850 static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher) 1851 { 1852 int ret; 1853 ret = os_snprintf(pos, end - pos, "-"); 1854 if (ret < 0 || ret >= end - pos) 1855 return pos; 1856 pos += ret; 1857 ret = wpa_write_ciphers(pos, end, cipher, "+"); 1858 if (ret < 0) 1859 return pos; 1860 pos += ret; 1861 return pos; 1862 } 1863 1864 1865 static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto, 1866 const u8 *ie, size_t ie_len) 1867 { 1868 struct wpa_ie_data data; 1869 int first, ret; 1870 1871 ret = os_snprintf(pos, end - pos, "[%s-", proto); 1872 if (ret < 0 || ret >= end - pos) 1873 return pos; 1874 pos += ret; 1875 1876 if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) { 1877 ret = os_snprintf(pos, end - pos, "?]"); 1878 if (ret < 0 || ret >= end - pos) 1879 return pos; 1880 pos += ret; 1881 return pos; 1882 } 1883 1884 first = 1; 1885 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) { 1886 ret = os_snprintf(pos, end - pos, "%sEAP", first ? "" : "+"); 1887 if (ret < 0 || ret >= end - pos) 1888 return pos; 1889 pos += ret; 1890 first = 0; 1891 } 1892 if (data.key_mgmt & WPA_KEY_MGMT_PSK) { 1893 ret = os_snprintf(pos, end - pos, "%sPSK", first ? "" : "+"); 1894 if (ret < 0 || ret >= end - pos) 1895 return pos; 1896 pos += ret; 1897 first = 0; 1898 } 1899 if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) { 1900 ret = os_snprintf(pos, end - pos, "%sNone", first ? "" : "+"); 1901 if (ret < 0 || ret >= end - pos) 1902 return pos; 1903 pos += ret; 1904 first = 0; 1905 } 1906 #ifdef CONFIG_IEEE80211R 1907 if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) { 1908 ret = os_snprintf(pos, end - pos, "%sFT/EAP", 1909 first ? "" : "+"); 1910 if (ret < 0 || ret >= end - pos) 1911 return pos; 1912 pos += ret; 1913 first = 0; 1914 } 1915 if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) { 1916 ret = os_snprintf(pos, end - pos, "%sFT/PSK", 1917 first ? "" : "+"); 1918 if (ret < 0 || ret >= end - pos) 1919 return pos; 1920 pos += ret; 1921 first = 0; 1922 } 1923 #endif /* CONFIG_IEEE80211R */ 1924 #ifdef CONFIG_IEEE80211W 1925 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) { 1926 ret = os_snprintf(pos, end - pos, "%sEAP-SHA256", 1927 first ? "" : "+"); 1928 if (ret < 0 || ret >= end - pos) 1929 return pos; 1930 pos += ret; 1931 first = 0; 1932 } 1933 if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) { 1934 ret = os_snprintf(pos, end - pos, "%sPSK-SHA256", 1935 first ? "" : "+"); 1936 if (ret < 0 || ret >= end - pos) 1937 return pos; 1938 pos += ret; 1939 first = 0; 1940 } 1941 #endif /* CONFIG_IEEE80211W */ 1942 1943 pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher); 1944 1945 if (data.capabilities & WPA_CAPABILITY_PREAUTH) { 1946 ret = os_snprintf(pos, end - pos, "-preauth"); 1947 if (ret < 0 || ret >= end - pos) 1948 return pos; 1949 pos += ret; 1950 } 1951 1952 ret = os_snprintf(pos, end - pos, "]"); 1953 if (ret < 0 || ret >= end - pos) 1954 return pos; 1955 pos += ret; 1956 1957 return pos; 1958 } 1959 1960 1961 #ifdef CONFIG_WPS 1962 static char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant *wpa_s, 1963 char *pos, char *end, 1964 struct wpabuf *wps_ie) 1965 { 1966 int ret; 1967 const char *txt; 1968 1969 if (wps_ie == NULL) 1970 return pos; 1971 if (wps_is_selected_pbc_registrar(wps_ie)) 1972 txt = "[WPS-PBC]"; 1973 #ifdef CONFIG_WPS2 1974 else if (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 0)) 1975 txt = "[WPS-AUTH]"; 1976 #endif /* CONFIG_WPS2 */ 1977 else if (wps_is_selected_pin_registrar(wps_ie)) 1978 txt = "[WPS-PIN]"; 1979 else 1980 txt = "[WPS]"; 1981 1982 ret = os_snprintf(pos, end - pos, "%s", txt); 1983 if (ret >= 0 && ret < end - pos) 1984 pos += ret; 1985 wpabuf_free(wps_ie); 1986 return pos; 1987 } 1988 #endif /* CONFIG_WPS */ 1989 1990 1991 static char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant *wpa_s, 1992 char *pos, char *end, 1993 const struct wpa_bss *bss) 1994 { 1995 #ifdef CONFIG_WPS 1996 struct wpabuf *wps_ie; 1997 wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); 1998 return wpa_supplicant_wps_ie_txt_buf(wpa_s, pos, end, wps_ie); 1999 #else /* CONFIG_WPS */ 2000 return pos; 2001 #endif /* CONFIG_WPS */ 2002 } 2003 2004 2005 /* Format one result on one text line into a buffer. */ 2006 static int wpa_supplicant_ctrl_iface_scan_result( 2007 struct wpa_supplicant *wpa_s, 2008 const struct wpa_bss *bss, char *buf, size_t buflen) 2009 { 2010 char *pos, *end; 2011 int ret; 2012 const u8 *ie, *ie2, *p2p; 2013 2014 p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE); 2015 if (p2p && bss->ssid_len == P2P_WILDCARD_SSID_LEN && 2016 os_memcmp(bss->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) == 2017 0) 2018 return 0; /* Do not show P2P listen discovery results here */ 2019 2020 pos = buf; 2021 end = buf + buflen; 2022 2023 ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t", 2024 MAC2STR(bss->bssid), bss->freq, bss->level); 2025 if (ret < 0 || ret >= end - pos) 2026 return -1; 2027 pos += ret; 2028 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); 2029 if (ie) 2030 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]); 2031 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN); 2032 if (ie2) 2033 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]); 2034 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss); 2035 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) { 2036 ret = os_snprintf(pos, end - pos, "[WEP]"); 2037 if (ret < 0 || ret >= end - pos) 2038 return -1; 2039 pos += ret; 2040 } 2041 if (bss->caps & IEEE80211_CAP_IBSS) { 2042 ret = os_snprintf(pos, end - pos, "[IBSS]"); 2043 if (ret < 0 || ret >= end - pos) 2044 return -1; 2045 pos += ret; 2046 } 2047 if (bss->caps & IEEE80211_CAP_ESS) { 2048 ret = os_snprintf(pos, end - pos, "[ESS]"); 2049 if (ret < 0 || ret >= end - pos) 2050 return -1; 2051 pos += ret; 2052 } 2053 if (p2p) { 2054 ret = os_snprintf(pos, end - pos, "[P2P]"); 2055 if (ret < 0 || ret >= end - pos) 2056 return -1; 2057 pos += ret; 2058 } 2059 #ifdef CONFIG_HS20 2060 if (wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE) && ie2) { 2061 ret = os_snprintf(pos, end - pos, "[HS20]"); 2062 if (ret < 0 || ret >= end - pos) 2063 return -1; 2064 pos += ret; 2065 } 2066 #endif /* CONFIG_HS20 */ 2067 2068 ret = os_snprintf(pos, end - pos, "\t%s", 2069 wpa_ssid_txt(bss->ssid, bss->ssid_len)); 2070 if (ret < 0 || ret >= end - pos) 2071 return -1; 2072 pos += ret; 2073 2074 ret = os_snprintf(pos, end - pos, "\n"); 2075 if (ret < 0 || ret >= end - pos) 2076 return -1; 2077 pos += ret; 2078 2079 return pos - buf; 2080 } 2081 2082 2083 static int wpa_supplicant_ctrl_iface_scan_results( 2084 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 2085 { 2086 char *pos, *end; 2087 struct wpa_bss *bss; 2088 int ret; 2089 2090 pos = buf; 2091 end = buf + buflen; 2092 ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / " 2093 "flags / ssid\n"); 2094 if (ret < 0 || ret >= end - pos) 2095 return pos - buf; 2096 pos += ret; 2097 2098 dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) { 2099 ret = wpa_supplicant_ctrl_iface_scan_result(wpa_s, bss, pos, 2100 end - pos); 2101 if (ret < 0 || ret >= end - pos) 2102 return pos - buf; 2103 pos += ret; 2104 } 2105 2106 return pos - buf; 2107 } 2108 2109 2110 static int wpa_supplicant_ctrl_iface_select_network( 2111 struct wpa_supplicant *wpa_s, char *cmd) 2112 { 2113 int id; 2114 struct wpa_ssid *ssid; 2115 2116 /* cmd: "<network id>" or "any" */ 2117 if (os_strcmp(cmd, "any") == 0) { 2118 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any"); 2119 ssid = NULL; 2120 } else { 2121 id = atoi(cmd); 2122 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id); 2123 2124 ssid = wpa_config_get_network(wpa_s->conf, id); 2125 if (ssid == NULL) { 2126 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " 2127 "network id=%d", id); 2128 return -1; 2129 } 2130 if (ssid->disabled == 2) { 2131 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use " 2132 "SELECT_NETWORK with persistent P2P group"); 2133 return -1; 2134 } 2135 } 2136 2137 wpa_supplicant_select_network(wpa_s, ssid); 2138 2139 return 0; 2140 } 2141 2142 2143 static int wpa_supplicant_ctrl_iface_enable_network( 2144 struct wpa_supplicant *wpa_s, char *cmd) 2145 { 2146 int id; 2147 struct wpa_ssid *ssid; 2148 2149 /* cmd: "<network id>" or "all" */ 2150 if (os_strcmp(cmd, "all") == 0) { 2151 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all"); 2152 ssid = NULL; 2153 } else { 2154 id = atoi(cmd); 2155 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id); 2156 2157 ssid = wpa_config_get_network(wpa_s->conf, id); 2158 if (ssid == NULL) { 2159 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " 2160 "network id=%d", id); 2161 return -1; 2162 } 2163 if (ssid->disabled == 2) { 2164 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use " 2165 "ENABLE_NETWORK with persistent P2P group"); 2166 return -1; 2167 } 2168 2169 if (os_strstr(cmd, " no-connect")) { 2170 ssid->disabled = 0; 2171 return 0; 2172 } 2173 } 2174 wpa_supplicant_enable_network(wpa_s, ssid); 2175 2176 return 0; 2177 } 2178 2179 2180 static int wpa_supplicant_ctrl_iface_disable_network( 2181 struct wpa_supplicant *wpa_s, char *cmd) 2182 { 2183 int id; 2184 struct wpa_ssid *ssid; 2185 2186 /* cmd: "<network id>" or "all" */ 2187 if (os_strcmp(cmd, "all") == 0) { 2188 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all"); 2189 ssid = NULL; 2190 } else { 2191 id = atoi(cmd); 2192 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id); 2193 2194 ssid = wpa_config_get_network(wpa_s->conf, id); 2195 if (ssid == NULL) { 2196 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " 2197 "network id=%d", id); 2198 return -1; 2199 } 2200 if (ssid->disabled == 2) { 2201 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use " 2202 "DISABLE_NETWORK with persistent P2P " 2203 "group"); 2204 return -1; 2205 } 2206 } 2207 wpa_supplicant_disable_network(wpa_s, ssid); 2208 2209 return 0; 2210 } 2211 2212 2213 static int wpa_supplicant_ctrl_iface_add_network( 2214 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 2215 { 2216 struct wpa_ssid *ssid; 2217 int ret; 2218 2219 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK"); 2220 2221 ssid = wpa_config_add_network(wpa_s->conf); 2222 if (ssid == NULL) 2223 return -1; 2224 2225 wpas_notify_network_added(wpa_s, ssid); 2226 2227 ssid->disabled = 1; 2228 wpa_config_set_network_defaults(ssid); 2229 2230 ret = os_snprintf(buf, buflen, "%d\n", ssid->id); 2231 if (ret < 0 || (size_t) ret >= buflen) 2232 return -1; 2233 return ret; 2234 } 2235 2236 2237 static int wpa_supplicant_ctrl_iface_remove_network( 2238 struct wpa_supplicant *wpa_s, char *cmd) 2239 { 2240 int id; 2241 struct wpa_ssid *ssid; 2242 int was_disabled; 2243 2244 /* cmd: "<network id>" or "all" */ 2245 if (os_strcmp(cmd, "all") == 0) { 2246 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all"); 2247 if (wpa_s->sched_scanning) 2248 wpa_supplicant_cancel_sched_scan(wpa_s); 2249 2250 eapol_sm_invalidate_cached_session(wpa_s->eapol); 2251 if (wpa_s->current_ssid) { 2252 #ifdef CONFIG_SME 2253 wpa_s->sme.prev_bssid_set = 0; 2254 #endif /* CONFIG_SME */ 2255 wpa_sm_set_config(wpa_s->wpa, NULL); 2256 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); 2257 wpa_supplicant_deauthenticate( 2258 wpa_s, WLAN_REASON_DEAUTH_LEAVING); 2259 } 2260 ssid = wpa_s->conf->ssid; 2261 while (ssid) { 2262 struct wpa_ssid *remove_ssid = ssid; 2263 id = ssid->id; 2264 ssid = ssid->next; 2265 wpas_notify_network_removed(wpa_s, remove_ssid); 2266 wpa_config_remove_network(wpa_s->conf, id); 2267 } 2268 return 0; 2269 } 2270 2271 id = atoi(cmd); 2272 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id); 2273 2274 ssid = wpa_config_get_network(wpa_s->conf, id); 2275 if (ssid) 2276 wpas_notify_network_removed(wpa_s, ssid); 2277 if (ssid == NULL) { 2278 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 2279 "id=%d", id); 2280 return -1; 2281 } 2282 2283 if (ssid == wpa_s->current_ssid || wpa_s->current_ssid == NULL) { 2284 #ifdef CONFIG_SME 2285 wpa_s->sme.prev_bssid_set = 0; 2286 #endif /* CONFIG_SME */ 2287 /* 2288 * Invalidate the EAP session cache if the current or 2289 * previously used network is removed. 2290 */ 2291 eapol_sm_invalidate_cached_session(wpa_s->eapol); 2292 } 2293 2294 if (ssid == wpa_s->current_ssid) { 2295 wpa_sm_set_config(wpa_s->wpa, NULL); 2296 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); 2297 2298 wpa_supplicant_deauthenticate(wpa_s, 2299 WLAN_REASON_DEAUTH_LEAVING); 2300 } 2301 2302 was_disabled = ssid->disabled; 2303 2304 if (wpa_config_remove_network(wpa_s->conf, id) < 0) { 2305 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Not able to remove the " 2306 "network id=%d", id); 2307 return -1; 2308 } 2309 2310 if (!was_disabled && wpa_s->sched_scanning) { 2311 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to remove " 2312 "network from filters"); 2313 wpa_supplicant_cancel_sched_scan(wpa_s); 2314 wpa_supplicant_req_scan(wpa_s, 0, 0); 2315 } 2316 2317 return 0; 2318 } 2319 2320 2321 static int wpa_supplicant_ctrl_iface_set_network( 2322 struct wpa_supplicant *wpa_s, char *cmd) 2323 { 2324 int id; 2325 struct wpa_ssid *ssid; 2326 char *name, *value; 2327 2328 /* cmd: "<network id> <variable name> <value>" */ 2329 name = os_strchr(cmd, ' '); 2330 if (name == NULL) 2331 return -1; 2332 *name++ = '\0'; 2333 2334 value = os_strchr(name, ' '); 2335 if (value == NULL) 2336 return -1; 2337 *value++ = '\0'; 2338 2339 id = atoi(cmd); 2340 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'", 2341 id, name); 2342 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value", 2343 (u8 *) value, os_strlen(value)); 2344 2345 ssid = wpa_config_get_network(wpa_s->conf, id); 2346 if (ssid == NULL) { 2347 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 2348 "id=%d", id); 2349 return -1; 2350 } 2351 2352 if (wpa_config_set(ssid, name, value, 0) < 0) { 2353 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network " 2354 "variable '%s'", name); 2355 return -1; 2356 } 2357 2358 if (os_strcmp(name, "bssid") != 0 && 2359 os_strcmp(name, "priority") != 0) 2360 wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid); 2361 2362 if (wpa_s->current_ssid == ssid || wpa_s->current_ssid == NULL) { 2363 /* 2364 * Invalidate the EAP session cache if anything in the current 2365 * or previously used configuration changes. 2366 */ 2367 eapol_sm_invalidate_cached_session(wpa_s->eapol); 2368 } 2369 2370 if ((os_strcmp(name, "psk") == 0 && 2371 value[0] == '"' && ssid->ssid_len) || 2372 (os_strcmp(name, "ssid") == 0 && ssid->passphrase)) 2373 wpa_config_update_psk(ssid); 2374 else if (os_strcmp(name, "priority") == 0) 2375 wpa_config_update_prio_list(wpa_s->conf); 2376 2377 return 0; 2378 } 2379 2380 2381 static int wpa_supplicant_ctrl_iface_get_network( 2382 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) 2383 { 2384 int id; 2385 size_t res; 2386 struct wpa_ssid *ssid; 2387 char *name, *value; 2388 2389 /* cmd: "<network id> <variable name>" */ 2390 name = os_strchr(cmd, ' '); 2391 if (name == NULL || buflen == 0) 2392 return -1; 2393 *name++ = '\0'; 2394 2395 id = atoi(cmd); 2396 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'", 2397 id, name); 2398 2399 ssid = wpa_config_get_network(wpa_s->conf, id); 2400 if (ssid == NULL) { 2401 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 2402 "id=%d", id); 2403 return -1; 2404 } 2405 2406 value = wpa_config_get_no_key(ssid, name); 2407 if (value == NULL) { 2408 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network " 2409 "variable '%s'", name); 2410 return -1; 2411 } 2412 2413 res = os_strlcpy(buf, value, buflen); 2414 if (res >= buflen) { 2415 os_free(value); 2416 return -1; 2417 } 2418 2419 os_free(value); 2420 2421 return res; 2422 } 2423 2424 2425 static int wpa_supplicant_ctrl_iface_list_creds(struct wpa_supplicant *wpa_s, 2426 char *buf, size_t buflen) 2427 { 2428 char *pos, *end; 2429 struct wpa_cred *cred; 2430 int ret; 2431 2432 pos = buf; 2433 end = buf + buflen; 2434 ret = os_snprintf(pos, end - pos, 2435 "cred id / realm / username / domain / imsi\n"); 2436 if (ret < 0 || ret >= end - pos) 2437 return pos - buf; 2438 pos += ret; 2439 2440 cred = wpa_s->conf->cred; 2441 while (cred) { 2442 ret = os_snprintf(pos, end - pos, "%d\t%s\t%s\t%s\t%s\n", 2443 cred->id, cred->realm ? cred->realm : "", 2444 cred->username ? cred->username : "", 2445 cred->domain ? cred->domain : "", 2446 cred->imsi ? cred->imsi : ""); 2447 if (ret < 0 || ret >= end - pos) 2448 return pos - buf; 2449 pos += ret; 2450 2451 cred = cred->next; 2452 } 2453 2454 return pos - buf; 2455 } 2456 2457 2458 static int wpa_supplicant_ctrl_iface_add_cred(struct wpa_supplicant *wpa_s, 2459 char *buf, size_t buflen) 2460 { 2461 struct wpa_cred *cred; 2462 int ret; 2463 2464 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_CRED"); 2465 2466 cred = wpa_config_add_cred(wpa_s->conf); 2467 if (cred == NULL) 2468 return -1; 2469 2470 ret = os_snprintf(buf, buflen, "%d\n", cred->id); 2471 if (ret < 0 || (size_t) ret >= buflen) 2472 return -1; 2473 return ret; 2474 } 2475 2476 2477 static int wpas_ctrl_remove_cred(struct wpa_supplicant *wpa_s, 2478 struct wpa_cred *cred) 2479 { 2480 struct wpa_ssid *ssid; 2481 char str[20]; 2482 2483 if (cred == NULL || wpa_config_remove_cred(wpa_s->conf, cred->id) < 0) { 2484 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find cred"); 2485 return -1; 2486 } 2487 2488 /* Remove any network entry created based on the removed credential */ 2489 ssid = wpa_s->conf->ssid; 2490 while (ssid) { 2491 if (ssid->parent_cred == cred) { 2492 wpa_printf(MSG_DEBUG, "Remove network id %d since it " 2493 "used the removed credential", ssid->id); 2494 os_snprintf(str, sizeof(str), "%d", ssid->id); 2495 ssid = ssid->next; 2496 wpa_supplicant_ctrl_iface_remove_network(wpa_s, str); 2497 } else 2498 ssid = ssid->next; 2499 } 2500 2501 return 0; 2502 } 2503 2504 2505 static int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant *wpa_s, 2506 char *cmd) 2507 { 2508 int id; 2509 struct wpa_cred *cred, *prev; 2510 2511 /* cmd: "<cred id>", "all", or "sp_fqdn=<FQDN>" */ 2512 if (os_strcmp(cmd, "all") == 0) { 2513 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED all"); 2514 cred = wpa_s->conf->cred; 2515 while (cred) { 2516 prev = cred; 2517 cred = cred->next; 2518 wpas_ctrl_remove_cred(wpa_s, prev); 2519 } 2520 return 0; 2521 } 2522 2523 if (os_strncmp(cmd, "sp_fqdn=", 8) == 0) { 2524 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED SP FQDN '%s'", 2525 cmd + 8); 2526 cred = wpa_s->conf->cred; 2527 while (cred) { 2528 prev = cred; 2529 cred = cred->next; 2530 if (prev->domain && 2531 os_strcmp(prev->domain, cmd + 8) == 0) 2532 wpas_ctrl_remove_cred(wpa_s, prev); 2533 } 2534 return 0; 2535 } 2536 2537 id = atoi(cmd); 2538 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED id=%d", id); 2539 2540 cred = wpa_config_get_cred(wpa_s->conf, id); 2541 return wpas_ctrl_remove_cred(wpa_s, cred); 2542 } 2543 2544 2545 static int wpa_supplicant_ctrl_iface_set_cred(struct wpa_supplicant *wpa_s, 2546 char *cmd) 2547 { 2548 int id; 2549 struct wpa_cred *cred; 2550 char *name, *value; 2551 2552 /* cmd: "<cred id> <variable name> <value>" */ 2553 name = os_strchr(cmd, ' '); 2554 if (name == NULL) 2555 return -1; 2556 *name++ = '\0'; 2557 2558 value = os_strchr(name, ' '); 2559 if (value == NULL) 2560 return -1; 2561 *value++ = '\0'; 2562 2563 id = atoi(cmd); 2564 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_CRED id=%d name='%s'", 2565 id, name); 2566 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value", 2567 (u8 *) value, os_strlen(value)); 2568 2569 cred = wpa_config_get_cred(wpa_s->conf, id); 2570 if (cred == NULL) { 2571 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find cred id=%d", 2572 id); 2573 return -1; 2574 } 2575 2576 if (wpa_config_set_cred(cred, name, value, 0) < 0) { 2577 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set cred " 2578 "variable '%s'", name); 2579 return -1; 2580 } 2581 2582 return 0; 2583 } 2584 2585 2586 #ifndef CONFIG_NO_CONFIG_WRITE 2587 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s) 2588 { 2589 int ret; 2590 2591 if (!wpa_s->conf->update_config) { 2592 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed " 2593 "to update configuration (update_config=0)"); 2594 return -1; 2595 } 2596 2597 ret = wpa_config_write(wpa_s->confname, wpa_s->conf); 2598 if (ret) { 2599 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to " 2600 "update configuration"); 2601 } else { 2602 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration" 2603 " updated"); 2604 } 2605 2606 return ret; 2607 } 2608 #endif /* CONFIG_NO_CONFIG_WRITE */ 2609 2610 2611 static int ctrl_iface_get_capability_pairwise(int res, char *strict, 2612 struct wpa_driver_capa *capa, 2613 char *buf, size_t buflen) 2614 { 2615 int ret, first = 1; 2616 char *pos, *end; 2617 size_t len; 2618 2619 pos = buf; 2620 end = pos + buflen; 2621 2622 if (res < 0) { 2623 if (strict) 2624 return 0; 2625 len = os_strlcpy(buf, "CCMP TKIP NONE", buflen); 2626 if (len >= buflen) 2627 return -1; 2628 return len; 2629 } 2630 2631 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) { 2632 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " "); 2633 if (ret < 0 || ret >= end - pos) 2634 return pos - buf; 2635 pos += ret; 2636 first = 0; 2637 } 2638 2639 if (capa->enc & WPA_DRIVER_CAPA_ENC_GCMP) { 2640 ret = os_snprintf(pos, end - pos, "%sGCMP", first ? "" : " "); 2641 if (ret < 0 || ret >= end - pos) 2642 return pos - buf; 2643 pos += ret; 2644 first = 0; 2645 } 2646 2647 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) { 2648 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " "); 2649 if (ret < 0 || ret >= end - pos) 2650 return pos - buf; 2651 pos += ret; 2652 first = 0; 2653 } 2654 2655 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { 2656 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : " "); 2657 if (ret < 0 || ret >= end - pos) 2658 return pos - buf; 2659 pos += ret; 2660 first = 0; 2661 } 2662 2663 return pos - buf; 2664 } 2665 2666 2667 static int ctrl_iface_get_capability_group(int res, char *strict, 2668 struct wpa_driver_capa *capa, 2669 char *buf, size_t buflen) 2670 { 2671 int ret, first = 1; 2672 char *pos, *end; 2673 size_t len; 2674 2675 pos = buf; 2676 end = pos + buflen; 2677 2678 if (res < 0) { 2679 if (strict) 2680 return 0; 2681 len = os_strlcpy(buf, "CCMP TKIP WEP104 WEP40", buflen); 2682 if (len >= buflen) 2683 return -1; 2684 return len; 2685 } 2686 2687 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) { 2688 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " "); 2689 if (ret < 0 || ret >= end - pos) 2690 return pos - buf; 2691 pos += ret; 2692 first = 0; 2693 } 2694 2695 if (capa->enc & WPA_DRIVER_CAPA_ENC_GCMP) { 2696 ret = os_snprintf(pos, end - pos, "%sGCMP", first ? "" : " "); 2697 if (ret < 0 || ret >= end - pos) 2698 return pos - buf; 2699 pos += ret; 2700 first = 0; 2701 } 2702 2703 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) { 2704 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " "); 2705 if (ret < 0 || ret >= end - pos) 2706 return pos - buf; 2707 pos += ret; 2708 first = 0; 2709 } 2710 2711 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP104) { 2712 ret = os_snprintf(pos, end - pos, "%sWEP104", 2713 first ? "" : " "); 2714 if (ret < 0 || ret >= end - pos) 2715 return pos - buf; 2716 pos += ret; 2717 first = 0; 2718 } 2719 2720 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP40) { 2721 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : " "); 2722 if (ret < 0 || ret >= end - pos) 2723 return pos - buf; 2724 pos += ret; 2725 first = 0; 2726 } 2727 2728 return pos - buf; 2729 } 2730 2731 2732 static int ctrl_iface_get_capability_key_mgmt(int res, char *strict, 2733 struct wpa_driver_capa *capa, 2734 char *buf, size_t buflen) 2735 { 2736 int ret; 2737 char *pos, *end; 2738 size_t len; 2739 2740 pos = buf; 2741 end = pos + buflen; 2742 2743 if (res < 0) { 2744 if (strict) 2745 return 0; 2746 len = os_strlcpy(buf, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE " 2747 "NONE", buflen); 2748 if (len >= buflen) 2749 return -1; 2750 return len; 2751 } 2752 2753 ret = os_snprintf(pos, end - pos, "NONE IEEE8021X"); 2754 if (ret < 0 || ret >= end - pos) 2755 return pos - buf; 2756 pos += ret; 2757 2758 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | 2759 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) { 2760 ret = os_snprintf(pos, end - pos, " WPA-EAP"); 2761 if (ret < 0 || ret >= end - pos) 2762 return pos - buf; 2763 pos += ret; 2764 } 2765 2766 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | 2767 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { 2768 ret = os_snprintf(pos, end - pos, " WPA-PSK"); 2769 if (ret < 0 || ret >= end - pos) 2770 return pos - buf; 2771 pos += ret; 2772 } 2773 2774 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { 2775 ret = os_snprintf(pos, end - pos, " WPA-NONE"); 2776 if (ret < 0 || ret >= end - pos) 2777 return pos - buf; 2778 pos += ret; 2779 } 2780 2781 return pos - buf; 2782 } 2783 2784 2785 static int ctrl_iface_get_capability_proto(int res, char *strict, 2786 struct wpa_driver_capa *capa, 2787 char *buf, size_t buflen) 2788 { 2789 int ret, first = 1; 2790 char *pos, *end; 2791 size_t len; 2792 2793 pos = buf; 2794 end = pos + buflen; 2795 2796 if (res < 0) { 2797 if (strict) 2798 return 0; 2799 len = os_strlcpy(buf, "RSN WPA", buflen); 2800 if (len >= buflen) 2801 return -1; 2802 return len; 2803 } 2804 2805 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | 2806 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { 2807 ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " "); 2808 if (ret < 0 || ret >= end - pos) 2809 return pos - buf; 2810 pos += ret; 2811 first = 0; 2812 } 2813 2814 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | 2815 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) { 2816 ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " "); 2817 if (ret < 0 || ret >= end - pos) 2818 return pos - buf; 2819 pos += ret; 2820 first = 0; 2821 } 2822 2823 return pos - buf; 2824 } 2825 2826 2827 static int ctrl_iface_get_capability_auth_alg(int res, char *strict, 2828 struct wpa_driver_capa *capa, 2829 char *buf, size_t buflen) 2830 { 2831 int ret, first = 1; 2832 char *pos, *end; 2833 size_t len; 2834 2835 pos = buf; 2836 end = pos + buflen; 2837 2838 if (res < 0) { 2839 if (strict) 2840 return 0; 2841 len = os_strlcpy(buf, "OPEN SHARED LEAP", buflen); 2842 if (len >= buflen) 2843 return -1; 2844 return len; 2845 } 2846 2847 if (capa->auth & (WPA_DRIVER_AUTH_OPEN)) { 2848 ret = os_snprintf(pos, end - pos, "%sOPEN", first ? "" : " "); 2849 if (ret < 0 || ret >= end - pos) 2850 return pos - buf; 2851 pos += ret; 2852 first = 0; 2853 } 2854 2855 if (capa->auth & (WPA_DRIVER_AUTH_SHARED)) { 2856 ret = os_snprintf(pos, end - pos, "%sSHARED", 2857 first ? "" : " "); 2858 if (ret < 0 || ret >= end - pos) 2859 return pos - buf; 2860 pos += ret; 2861 first = 0; 2862 } 2863 2864 if (capa->auth & (WPA_DRIVER_AUTH_LEAP)) { 2865 ret = os_snprintf(pos, end - pos, "%sLEAP", first ? "" : " "); 2866 if (ret < 0 || ret >= end - pos) 2867 return pos - buf; 2868 pos += ret; 2869 first = 0; 2870 } 2871 2872 return pos - buf; 2873 } 2874 2875 2876 static int ctrl_iface_get_capability_modes(int res, char *strict, 2877 struct wpa_driver_capa *capa, 2878 char *buf, size_t buflen) 2879 { 2880 int ret, first = 1; 2881 char *pos, *end; 2882 size_t len; 2883 2884 pos = buf; 2885 end = pos + buflen; 2886 2887 if (res < 0) { 2888 if (strict) 2889 return 0; 2890 len = os_strlcpy(buf, "IBSS AP", buflen); 2891 if (len >= buflen) 2892 return -1; 2893 return len; 2894 } 2895 2896 if (capa->flags & WPA_DRIVER_FLAGS_IBSS) { 2897 ret = os_snprintf(pos, end - pos, "%sIBSS", first ? "" : " "); 2898 if (ret < 0 || ret >= end - pos) 2899 return pos - buf; 2900 pos += ret; 2901 first = 0; 2902 } 2903 2904 if (capa->flags & WPA_DRIVER_FLAGS_AP) { 2905 ret = os_snprintf(pos, end - pos, "%sAP", first ? "" : " "); 2906 if (ret < 0 || ret >= end - pos) 2907 return pos - buf; 2908 pos += ret; 2909 first = 0; 2910 } 2911 2912 return pos - buf; 2913 } 2914 2915 2916 static int ctrl_iface_get_capability_channels(struct wpa_supplicant *wpa_s, 2917 char *buf, size_t buflen) 2918 { 2919 struct hostapd_channel_data *chnl; 2920 int ret, i, j; 2921 char *pos, *end, *hmode; 2922 2923 pos = buf; 2924 end = pos + buflen; 2925 2926 for (j = 0; j < wpa_s->hw.num_modes; j++) { 2927 switch (wpa_s->hw.modes[j].mode) { 2928 case HOSTAPD_MODE_IEEE80211B: 2929 hmode = "B"; 2930 break; 2931 case HOSTAPD_MODE_IEEE80211G: 2932 hmode = "G"; 2933 break; 2934 case HOSTAPD_MODE_IEEE80211A: 2935 hmode = "A"; 2936 break; 2937 case HOSTAPD_MODE_IEEE80211AD: 2938 hmode = "AD"; 2939 break; 2940 default: 2941 continue; 2942 } 2943 ret = os_snprintf(pos, end - pos, "Mode[%s] Channels:", hmode); 2944 if (ret < 0 || ret >= end - pos) 2945 return pos - buf; 2946 pos += ret; 2947 chnl = wpa_s->hw.modes[j].channels; 2948 for (i = 0; i < wpa_s->hw.modes[j].num_channels; i++) { 2949 if (chnl[i].flag & HOSTAPD_CHAN_DISABLED) 2950 continue; 2951 ret = os_snprintf(pos, end - pos, " %d", chnl[i].chan); 2952 if (ret < 0 || ret >= end - pos) 2953 return pos - buf; 2954 pos += ret; 2955 } 2956 ret = os_snprintf(pos, end - pos, "\n"); 2957 if (ret < 0 || ret >= end - pos) 2958 return pos - buf; 2959 pos += ret; 2960 } 2961 2962 return pos - buf; 2963 } 2964 2965 2966 static int wpa_supplicant_ctrl_iface_get_capability( 2967 struct wpa_supplicant *wpa_s, const char *_field, char *buf, 2968 size_t buflen) 2969 { 2970 struct wpa_driver_capa capa; 2971 int res; 2972 char *strict; 2973 char field[30]; 2974 size_t len; 2975 2976 /* Determine whether or not strict checking was requested */ 2977 len = os_strlcpy(field, _field, sizeof(field)); 2978 if (len >= sizeof(field)) 2979 return -1; 2980 strict = os_strchr(field, ' '); 2981 if (strict != NULL) { 2982 *strict++ = '\0'; 2983 if (os_strcmp(strict, "strict") != 0) 2984 return -1; 2985 } 2986 2987 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s", 2988 field, strict ? strict : ""); 2989 2990 if (os_strcmp(field, "eap") == 0) { 2991 return eap_get_names(buf, buflen); 2992 } 2993 2994 res = wpa_drv_get_capa(wpa_s, &capa); 2995 2996 if (os_strcmp(field, "pairwise") == 0) 2997 return ctrl_iface_get_capability_pairwise(res, strict, &capa, 2998 buf, buflen); 2999 3000 if (os_strcmp(field, "group") == 0) 3001 return ctrl_iface_get_capability_group(res, strict, &capa, 3002 buf, buflen); 3003 3004 if (os_strcmp(field, "key_mgmt") == 0) 3005 return ctrl_iface_get_capability_key_mgmt(res, strict, &capa, 3006 buf, buflen); 3007 3008 if (os_strcmp(field, "proto") == 0) 3009 return ctrl_iface_get_capability_proto(res, strict, &capa, 3010 buf, buflen); 3011 3012 if (os_strcmp(field, "auth_alg") == 0) 3013 return ctrl_iface_get_capability_auth_alg(res, strict, &capa, 3014 buf, buflen); 3015 3016 if (os_strcmp(field, "modes") == 0) 3017 return ctrl_iface_get_capability_modes(res, strict, &capa, 3018 buf, buflen); 3019 3020 if (os_strcmp(field, "channels") == 0) 3021 return ctrl_iface_get_capability_channels(wpa_s, buf, buflen); 3022 3023 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'", 3024 field); 3025 3026 return -1; 3027 } 3028 3029 3030 #ifdef CONFIG_INTERWORKING 3031 static char * anqp_add_hex(char *pos, char *end, const char *title, 3032 struct wpabuf *data) 3033 { 3034 char *start = pos; 3035 size_t i; 3036 int ret; 3037 const u8 *d; 3038 3039 if (data == NULL) 3040 return start; 3041 3042 ret = os_snprintf(pos, end - pos, "%s=", title); 3043 if (ret < 0 || ret >= end - pos) 3044 return start; 3045 pos += ret; 3046 3047 d = wpabuf_head_u8(data); 3048 for (i = 0; i < wpabuf_len(data); i++) { 3049 ret = os_snprintf(pos, end - pos, "%02x", *d++); 3050 if (ret < 0 || ret >= end - pos) 3051 return start; 3052 pos += ret; 3053 } 3054 3055 ret = os_snprintf(pos, end - pos, "\n"); 3056 if (ret < 0 || ret >= end - pos) 3057 return start; 3058 pos += ret; 3059 3060 return pos; 3061 } 3062 #endif /* CONFIG_INTERWORKING */ 3063 3064 3065 static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, 3066 unsigned long mask, char *buf, size_t buflen) 3067 { 3068 size_t i; 3069 int ret; 3070 char *pos, *end; 3071 const u8 *ie, *ie2; 3072 3073 pos = buf; 3074 end = buf + buflen; 3075 3076 if (mask & WPA_BSS_MASK_ID) { 3077 ret = os_snprintf(pos, end - pos, "id=%u\n", bss->id); 3078 if (ret < 0 || ret >= end - pos) 3079 return 0; 3080 pos += ret; 3081 } 3082 3083 if (mask & WPA_BSS_MASK_BSSID) { 3084 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n", 3085 MAC2STR(bss->bssid)); 3086 if (ret < 0 || ret >= end - pos) 3087 return 0; 3088 pos += ret; 3089 } 3090 3091 if (mask & WPA_BSS_MASK_FREQ) { 3092 ret = os_snprintf(pos, end - pos, "freq=%d\n", bss->freq); 3093 if (ret < 0 || ret >= end - pos) 3094 return 0; 3095 pos += ret; 3096 } 3097 3098 if (mask & WPA_BSS_MASK_BEACON_INT) { 3099 ret = os_snprintf(pos, end - pos, "beacon_int=%d\n", 3100 bss->beacon_int); 3101 if (ret < 0 || ret >= end - pos) 3102 return 0; 3103 pos += ret; 3104 } 3105 3106 if (mask & WPA_BSS_MASK_CAPABILITIES) { 3107 ret = os_snprintf(pos, end - pos, "capabilities=0x%04x\n", 3108 bss->caps); 3109 if (ret < 0 || ret >= end - pos) 3110 return 0; 3111 pos += ret; 3112 } 3113 3114 if (mask & WPA_BSS_MASK_QUAL) { 3115 ret = os_snprintf(pos, end - pos, "qual=%d\n", bss->qual); 3116 if (ret < 0 || ret >= end - pos) 3117 return 0; 3118 pos += ret; 3119 } 3120 3121 if (mask & WPA_BSS_MASK_NOISE) { 3122 ret = os_snprintf(pos, end - pos, "noise=%d\n", bss->noise); 3123 if (ret < 0 || ret >= end - pos) 3124 return 0; 3125 pos += ret; 3126 } 3127 3128 if (mask & WPA_BSS_MASK_LEVEL) { 3129 ret = os_snprintf(pos, end - pos, "level=%d\n", bss->level); 3130 if (ret < 0 || ret >= end - pos) 3131 return 0; 3132 pos += ret; 3133 } 3134 3135 if (mask & WPA_BSS_MASK_TSF) { 3136 ret = os_snprintf(pos, end - pos, "tsf=%016llu\n", 3137 (unsigned long long) bss->tsf); 3138 if (ret < 0 || ret >= end - pos) 3139 return 0; 3140 pos += ret; 3141 } 3142 3143 if (mask & WPA_BSS_MASK_AGE) { 3144 struct os_time now; 3145 3146 os_get_time(&now); 3147 ret = os_snprintf(pos, end - pos, "age=%d\n", 3148 (int) (now.sec - bss->last_update.sec)); 3149 if (ret < 0 || ret >= end - pos) 3150 return 0; 3151 pos += ret; 3152 } 3153 3154 if (mask & WPA_BSS_MASK_IE) { 3155 ret = os_snprintf(pos, end - pos, "ie="); 3156 if (ret < 0 || ret >= end - pos) 3157 return 0; 3158 pos += ret; 3159 3160 ie = (const u8 *) (bss + 1); 3161 for (i = 0; i < bss->ie_len; i++) { 3162 ret = os_snprintf(pos, end - pos, "%02x", *ie++); 3163 if (ret < 0 || ret >= end - pos) 3164 return 0; 3165 pos += ret; 3166 } 3167 3168 ret = os_snprintf(pos, end - pos, "\n"); 3169 if (ret < 0 || ret >= end - pos) 3170 return 0; 3171 pos += ret; 3172 } 3173 3174 if (mask & WPA_BSS_MASK_FLAGS) { 3175 ret = os_snprintf(pos, end - pos, "flags="); 3176 if (ret < 0 || ret >= end - pos) 3177 return 0; 3178 pos += ret; 3179 3180 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); 3181 if (ie) 3182 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 3183 2 + ie[1]); 3184 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN); 3185 if (ie2) 3186 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 3187 2 + ie2[1]); 3188 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss); 3189 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) { 3190 ret = os_snprintf(pos, end - pos, "[WEP]"); 3191 if (ret < 0 || ret >= end - pos) 3192 return 0; 3193 pos += ret; 3194 } 3195 if (bss->caps & IEEE80211_CAP_IBSS) { 3196 ret = os_snprintf(pos, end - pos, "[IBSS]"); 3197 if (ret < 0 || ret >= end - pos) 3198 return 0; 3199 pos += ret; 3200 } 3201 if (bss->caps & IEEE80211_CAP_ESS) { 3202 ret = os_snprintf(pos, end - pos, "[ESS]"); 3203 if (ret < 0 || ret >= end - pos) 3204 return 0; 3205 pos += ret; 3206 } 3207 if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE)) { 3208 ret = os_snprintf(pos, end - pos, "[P2P]"); 3209 if (ret < 0 || ret >= end - pos) 3210 return 0; 3211 pos += ret; 3212 } 3213 #ifdef CONFIG_HS20 3214 if (wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE)) { 3215 ret = os_snprintf(pos, end - pos, "[HS20]"); 3216 if (ret < 0 || ret >= end - pos) 3217 return 0; 3218 pos += ret; 3219 } 3220 #endif /* CONFIG_HS20 */ 3221 3222 ret = os_snprintf(pos, end - pos, "\n"); 3223 if (ret < 0 || ret >= end - pos) 3224 return 0; 3225 pos += ret; 3226 } 3227 3228 if (mask & WPA_BSS_MASK_SSID) { 3229 ret = os_snprintf(pos, end - pos, "ssid=%s\n", 3230 wpa_ssid_txt(bss->ssid, bss->ssid_len)); 3231 if (ret < 0 || ret >= end - pos) 3232 return 0; 3233 pos += ret; 3234 } 3235 3236 #ifdef CONFIG_WPS 3237 if (mask & WPA_BSS_MASK_WPS_SCAN) { 3238 ie = (const u8 *) (bss + 1); 3239 ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end); 3240 if (ret < 0 || ret >= end - pos) 3241 return 0; 3242 pos += ret; 3243 } 3244 #endif /* CONFIG_WPS */ 3245 3246 #ifdef CONFIG_P2P 3247 if (mask & WPA_BSS_MASK_P2P_SCAN) { 3248 ie = (const u8 *) (bss + 1); 3249 ret = wpas_p2p_scan_result_text(ie, bss->ie_len, pos, end); 3250 if (ret < 0 || ret >= end - pos) 3251 return 0; 3252 pos += ret; 3253 } 3254 #endif /* CONFIG_P2P */ 3255 3256 #ifdef CONFIG_WIFI_DISPLAY 3257 if (mask & WPA_BSS_MASK_WIFI_DISPLAY) { 3258 struct wpabuf *wfd; 3259 ie = (const u8 *) (bss + 1); 3260 wfd = ieee802_11_vendor_ie_concat(ie, bss->ie_len, 3261 WFD_IE_VENDOR_TYPE); 3262 if (wfd) { 3263 ret = os_snprintf(pos, end - pos, "wfd_subelems="); 3264 if (ret < 0 || ret >= end - pos) 3265 return 0; 3266 pos += ret; 3267 3268 pos += wpa_snprintf_hex(pos, end - pos, 3269 wpabuf_head(wfd), 3270 wpabuf_len(wfd)); 3271 wpabuf_free(wfd); 3272 3273 ret = os_snprintf(pos, end - pos, "\n"); 3274 if (ret < 0 || ret >= end - pos) 3275 return 0; 3276 pos += ret; 3277 } 3278 } 3279 #endif /* CONFIG_WIFI_DISPLAY */ 3280 3281 #ifdef CONFIG_INTERWORKING 3282 if ((mask & WPA_BSS_MASK_INTERNETW) && bss->anqp) { 3283 struct wpa_bss_anqp *anqp = bss->anqp; 3284 pos = anqp_add_hex(pos, end, "anqp_venue_name", 3285 anqp->venue_name); 3286 pos = anqp_add_hex(pos, end, "anqp_network_auth_type", 3287 anqp->network_auth_type); 3288 pos = anqp_add_hex(pos, end, "anqp_roaming_consortium", 3289 anqp->roaming_consortium); 3290 pos = anqp_add_hex(pos, end, "anqp_ip_addr_type_availability", 3291 anqp->ip_addr_type_availability); 3292 pos = anqp_add_hex(pos, end, "anqp_nai_realm", 3293 anqp->nai_realm); 3294 pos = anqp_add_hex(pos, end, "anqp_3gpp", anqp->anqp_3gpp); 3295 pos = anqp_add_hex(pos, end, "anqp_domain_name", 3296 anqp->domain_name); 3297 #ifdef CONFIG_HS20 3298 pos = anqp_add_hex(pos, end, "hs20_operator_friendly_name", 3299 anqp->hs20_operator_friendly_name); 3300 pos = anqp_add_hex(pos, end, "hs20_wan_metrics", 3301 anqp->hs20_wan_metrics); 3302 pos = anqp_add_hex(pos, end, "hs20_connection_capability", 3303 anqp->hs20_connection_capability); 3304 #endif /* CONFIG_HS20 */ 3305 } 3306 #endif /* CONFIG_INTERWORKING */ 3307 3308 if (mask & WPA_BSS_MASK_DELIM) { 3309 ret = os_snprintf(pos, end - pos, "====\n"); 3310 if (ret < 0 || ret >= end - pos) 3311 return 0; 3312 pos += ret; 3313 } 3314 3315 return pos - buf; 3316 } 3317 3318 3319 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s, 3320 const char *cmd, char *buf, 3321 size_t buflen) 3322 { 3323 u8 bssid[ETH_ALEN]; 3324 size_t i; 3325 struct wpa_bss *bss; 3326 struct wpa_bss *bsslast = NULL; 3327 struct dl_list *next; 3328 int ret = 0; 3329 int len; 3330 char *ctmp; 3331 unsigned long mask = WPA_BSS_MASK_ALL; 3332 3333 if (os_strncmp(cmd, "RANGE=", 6) == 0) { 3334 if (os_strncmp(cmd + 6, "ALL", 3) == 0) { 3335 bss = dl_list_first(&wpa_s->bss_id, struct wpa_bss, 3336 list_id); 3337 bsslast = dl_list_last(&wpa_s->bss_id, struct wpa_bss, 3338 list_id); 3339 } else { /* N1-N2 */ 3340 unsigned int id1, id2; 3341 3342 if ((ctmp = os_strchr(cmd + 6, '-')) == NULL) { 3343 wpa_printf(MSG_INFO, "Wrong BSS range " 3344 "format"); 3345 return 0; 3346 } 3347 3348 if (*(cmd + 6) == '-') 3349 id1 = 0; 3350 else 3351 id1 = atoi(cmd + 6); 3352 ctmp++; 3353 if (*ctmp >= '0' && *ctmp <= '9') 3354 id2 = atoi(ctmp); 3355 else 3356 id2 = (unsigned int) -1; 3357 bss = wpa_bss_get_id_range(wpa_s, id1, id2); 3358 if (id2 == (unsigned int) -1) 3359 bsslast = dl_list_last(&wpa_s->bss_id, 3360 struct wpa_bss, 3361 list_id); 3362 else { 3363 bsslast = wpa_bss_get_id(wpa_s, id2); 3364 if (bsslast == NULL && bss && id2 > id1) { 3365 struct wpa_bss *tmp = bss; 3366 for (;;) { 3367 next = tmp->list_id.next; 3368 if (next == &wpa_s->bss_id) 3369 break; 3370 tmp = dl_list_entry( 3371 next, struct wpa_bss, 3372 list_id); 3373 if (tmp->id > id2) 3374 break; 3375 bsslast = tmp; 3376 } 3377 } 3378 } 3379 } 3380 } else if (os_strncmp(cmd, "FIRST", 5) == 0) 3381 bss = dl_list_first(&wpa_s->bss_id, struct wpa_bss, list_id); 3382 else if (os_strncmp(cmd, "LAST", 4) == 0) 3383 bss = dl_list_last(&wpa_s->bss_id, struct wpa_bss, list_id); 3384 else if (os_strncmp(cmd, "ID-", 3) == 0) { 3385 i = atoi(cmd + 3); 3386 bss = wpa_bss_get_id(wpa_s, i); 3387 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) { 3388 i = atoi(cmd + 5); 3389 bss = wpa_bss_get_id(wpa_s, i); 3390 if (bss) { 3391 next = bss->list_id.next; 3392 if (next == &wpa_s->bss_id) 3393 bss = NULL; 3394 else 3395 bss = dl_list_entry(next, struct wpa_bss, 3396 list_id); 3397 } 3398 #ifdef CONFIG_P2P 3399 } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) { 3400 if (hwaddr_aton(cmd + 13, bssid) == 0) 3401 bss = wpa_bss_get_p2p_dev_addr(wpa_s, bssid); 3402 else 3403 bss = NULL; 3404 #endif /* CONFIG_P2P */ 3405 } else if (hwaddr_aton(cmd, bssid) == 0) 3406 bss = wpa_bss_get_bssid(wpa_s, bssid); 3407 else { 3408 struct wpa_bss *tmp; 3409 i = atoi(cmd); 3410 bss = NULL; 3411 dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id) 3412 { 3413 if (i-- == 0) { 3414 bss = tmp; 3415 break; 3416 } 3417 } 3418 } 3419 3420 if ((ctmp = os_strstr(cmd, "MASK=")) != NULL) { 3421 mask = strtoul(ctmp + 5, NULL, 0x10); 3422 if (mask == 0) 3423 mask = WPA_BSS_MASK_ALL; 3424 } 3425 3426 if (bss == NULL) 3427 return 0; 3428 3429 if (bsslast == NULL) 3430 bsslast = bss; 3431 do { 3432 len = print_bss_info(wpa_s, bss, mask, buf, buflen); 3433 ret += len; 3434 buf += len; 3435 buflen -= len; 3436 if (bss == bsslast) { 3437 if ((mask & WPA_BSS_MASK_DELIM) && len && 3438 (bss == dl_list_last(&wpa_s->bss_id, 3439 struct wpa_bss, list_id))) 3440 os_snprintf(buf - 5, 5, "####\n"); 3441 break; 3442 } 3443 next = bss->list_id.next; 3444 if (next == &wpa_s->bss_id) 3445 break; 3446 bss = dl_list_entry(next, struct wpa_bss, list_id); 3447 } while (bss && len); 3448 3449 return ret; 3450 } 3451 3452 3453 static int wpa_supplicant_ctrl_iface_ap_scan( 3454 struct wpa_supplicant *wpa_s, char *cmd) 3455 { 3456 int ap_scan = atoi(cmd); 3457 return wpa_supplicant_set_ap_scan(wpa_s, ap_scan); 3458 } 3459 3460 3461 static int wpa_supplicant_ctrl_iface_scan_interval( 3462 struct wpa_supplicant *wpa_s, char *cmd) 3463 { 3464 int scan_int = atoi(cmd); 3465 return wpa_supplicant_set_scan_interval(wpa_s, scan_int); 3466 } 3467 3468 3469 static int wpa_supplicant_ctrl_iface_bss_expire_age( 3470 struct wpa_supplicant *wpa_s, char *cmd) 3471 { 3472 int expire_age = atoi(cmd); 3473 return wpa_supplicant_set_bss_expiration_age(wpa_s, expire_age); 3474 } 3475 3476 3477 static int wpa_supplicant_ctrl_iface_bss_expire_count( 3478 struct wpa_supplicant *wpa_s, char *cmd) 3479 { 3480 int expire_count = atoi(cmd); 3481 return wpa_supplicant_set_bss_expiration_count(wpa_s, expire_count); 3482 } 3483 3484 3485 static int wpa_supplicant_ctrl_iface_bss_flush( 3486 struct wpa_supplicant *wpa_s, char *cmd) 3487 { 3488 int flush_age = atoi(cmd); 3489 3490 if (flush_age == 0) 3491 wpa_bss_flush(wpa_s); 3492 else 3493 wpa_bss_flush_by_age(wpa_s, flush_age); 3494 return 0; 3495 } 3496 3497 3498 static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s) 3499 { 3500 wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication"); 3501 /* MLME-DELETEKEYS.request */ 3502 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0); 3503 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0); 3504 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0); 3505 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0); 3506 #ifdef CONFIG_IEEE80211W 3507 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0); 3508 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0); 3509 #endif /* CONFIG_IEEE80211W */ 3510 3511 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL, 3512 0); 3513 /* MLME-SETPROTECTION.request(None) */ 3514 wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid, 3515 MLME_SETPROTECTION_PROTECT_TYPE_NONE, 3516 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE); 3517 wpa_sm_drop_sa(wpa_s->wpa); 3518 } 3519 3520 3521 static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s, 3522 char *addr) 3523 { 3524 #ifdef CONFIG_NO_SCAN_PROCESSING 3525 return -1; 3526 #else /* CONFIG_NO_SCAN_PROCESSING */ 3527 u8 bssid[ETH_ALEN]; 3528 struct wpa_bss *bss; 3529 struct wpa_ssid *ssid = wpa_s->current_ssid; 3530 3531 if (hwaddr_aton(addr, bssid)) { 3532 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid " 3533 "address '%s'", addr); 3534 return -1; 3535 } 3536 3537 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM " MACSTR, MAC2STR(bssid)); 3538 3539 if (!ssid) { 3540 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: No network " 3541 "configuration known for the target AP"); 3542 return -1; 3543 } 3544 3545 bss = wpa_bss_get(wpa_s, bssid, ssid->ssid, ssid->ssid_len); 3546 if (!bss) { 3547 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: Target AP not found " 3548 "from BSS table"); 3549 return -1; 3550 } 3551 3552 /* 3553 * TODO: Find best network configuration block from configuration to 3554 * allow roaming to other networks 3555 */ 3556 3557 wpa_s->reassociate = 1; 3558 wpa_supplicant_connect(wpa_s, bss, ssid); 3559 3560 return 0; 3561 #endif /* CONFIG_NO_SCAN_PROCESSING */ 3562 } 3563 3564 3565 #ifdef CONFIG_P2P 3566 static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd) 3567 { 3568 unsigned int timeout = atoi(cmd); 3569 enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL; 3570 u8 dev_id[ETH_ALEN], *_dev_id = NULL; 3571 char *pos; 3572 unsigned int search_delay; 3573 3574 if (os_strstr(cmd, "type=social")) 3575 type = P2P_FIND_ONLY_SOCIAL; 3576 else if (os_strstr(cmd, "type=progressive")) 3577 type = P2P_FIND_PROGRESSIVE; 3578 3579 pos = os_strstr(cmd, "dev_id="); 3580 if (pos) { 3581 pos += 7; 3582 if (hwaddr_aton(pos, dev_id)) 3583 return -1; 3584 _dev_id = dev_id; 3585 } 3586 3587 pos = os_strstr(cmd, "delay="); 3588 if (pos) { 3589 pos += 6; 3590 search_delay = atoi(pos); 3591 } else 3592 search_delay = wpas_p2p_search_delay(wpa_s); 3593 3594 return wpas_p2p_find(wpa_s, timeout, type, 0, NULL, _dev_id, 3595 search_delay); 3596 } 3597 3598 3599 static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd, 3600 char *buf, size_t buflen) 3601 { 3602 u8 addr[ETH_ALEN]; 3603 char *pos, *pos2; 3604 char *pin = NULL; 3605 enum p2p_wps_method wps_method; 3606 int new_pin; 3607 int ret; 3608 int persistent_group, persistent_id = -1; 3609 int join; 3610 int auth; 3611 int automatic; 3612 int go_intent = -1; 3613 int freq = 0; 3614 int pd; 3615 int ht40; 3616 3617 /* <addr> <"pbc" | "pin" | PIN> [label|display|keypad] 3618 * [persistent|persistent=<network id>] 3619 * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] [provdisc] 3620 * [ht40] */ 3621 3622 if (hwaddr_aton(cmd, addr)) 3623 return -1; 3624 3625 pos = cmd + 17; 3626 if (*pos != ' ') 3627 return -1; 3628 pos++; 3629 3630 persistent_group = os_strstr(pos, " persistent") != NULL; 3631 pos2 = os_strstr(pos, " persistent="); 3632 if (pos2) { 3633 struct wpa_ssid *ssid; 3634 persistent_id = atoi(pos2 + 12); 3635 ssid = wpa_config_get_network(wpa_s->conf, persistent_id); 3636 if (ssid == NULL || ssid->disabled != 2 || 3637 ssid->mode != WPAS_MODE_P2P_GO) { 3638 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find " 3639 "SSID id=%d for persistent P2P group (GO)", 3640 persistent_id); 3641 return -1; 3642 } 3643 } 3644 join = os_strstr(pos, " join") != NULL; 3645 auth = os_strstr(pos, " auth") != NULL; 3646 automatic = os_strstr(pos, " auto") != NULL; 3647 pd = os_strstr(pos, " provdisc") != NULL; 3648 ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40; 3649 3650 pos2 = os_strstr(pos, " go_intent="); 3651 if (pos2) { 3652 pos2 += 11; 3653 go_intent = atoi(pos2); 3654 if (go_intent < 0 || go_intent > 15) 3655 return -1; 3656 } 3657 3658 pos2 = os_strstr(pos, " freq="); 3659 if (pos2) { 3660 pos2 += 6; 3661 freq = atoi(pos2); 3662 if (freq <= 0) 3663 return -1; 3664 } 3665 3666 if (os_strncmp(pos, "pin", 3) == 0) { 3667 /* Request random PIN (to be displayed) and enable the PIN */ 3668 wps_method = WPS_PIN_DISPLAY; 3669 } else if (os_strncmp(pos, "pbc", 3) == 0) { 3670 wps_method = WPS_PBC; 3671 } else { 3672 pin = pos; 3673 pos = os_strchr(pin, ' '); 3674 wps_method = WPS_PIN_KEYPAD; 3675 if (pos) { 3676 *pos++ = '\0'; 3677 if (os_strncmp(pos, "display", 7) == 0) 3678 wps_method = WPS_PIN_DISPLAY; 3679 } 3680 if (!wps_pin_str_valid(pin)) { 3681 os_memcpy(buf, "FAIL-INVALID-PIN\n", 17); 3682 return 17; 3683 } 3684 } 3685 3686 new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method, 3687 persistent_group, automatic, join, 3688 auth, go_intent, freq, persistent_id, pd, 3689 ht40); 3690 if (new_pin == -2) { 3691 os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25); 3692 return 25; 3693 } 3694 if (new_pin == -3) { 3695 os_memcpy(buf, "FAIL-CHANNEL-UNSUPPORTED\n", 25); 3696 return 25; 3697 } 3698 if (new_pin < 0) 3699 return -1; 3700 if (wps_method == WPS_PIN_DISPLAY && pin == NULL) { 3701 ret = os_snprintf(buf, buflen, "%08d", new_pin); 3702 if (ret < 0 || (size_t) ret >= buflen) 3703 return -1; 3704 return ret; 3705 } 3706 3707 os_memcpy(buf, "OK\n", 3); 3708 return 3; 3709 } 3710 3711 3712 static int p2p_ctrl_listen(struct wpa_supplicant *wpa_s, char *cmd) 3713 { 3714 unsigned int timeout = atoi(cmd); 3715 return wpas_p2p_listen(wpa_s, timeout); 3716 } 3717 3718 3719 static int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd) 3720 { 3721 u8 addr[ETH_ALEN]; 3722 char *pos; 3723 enum wpas_p2p_prov_disc_use use = WPAS_P2P_PD_FOR_GO_NEG; 3724 3725 /* <addr> <config method> [join|auto] */ 3726 3727 if (hwaddr_aton(cmd, addr)) 3728 return -1; 3729 3730 pos = cmd + 17; 3731 if (*pos != ' ') 3732 return -1; 3733 pos++; 3734 3735 if (os_strstr(pos, " join") != NULL) 3736 use = WPAS_P2P_PD_FOR_JOIN; 3737 else if (os_strstr(pos, " auto") != NULL) 3738 use = WPAS_P2P_PD_AUTO; 3739 3740 return wpas_p2p_prov_disc(wpa_s, addr, pos, use); 3741 } 3742 3743 3744 static int p2p_get_passphrase(struct wpa_supplicant *wpa_s, char *buf, 3745 size_t buflen) 3746 { 3747 struct wpa_ssid *ssid = wpa_s->current_ssid; 3748 3749 if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO || 3750 ssid->passphrase == NULL) 3751 return -1; 3752 3753 os_strlcpy(buf, ssid->passphrase, buflen); 3754 return os_strlen(buf); 3755 } 3756 3757 3758 static int p2p_ctrl_serv_disc_req(struct wpa_supplicant *wpa_s, char *cmd, 3759 char *buf, size_t buflen) 3760 { 3761 u64 ref; 3762 int res; 3763 u8 dst_buf[ETH_ALEN], *dst; 3764 struct wpabuf *tlvs; 3765 char *pos; 3766 size_t len; 3767 3768 if (hwaddr_aton(cmd, dst_buf)) 3769 return -1; 3770 dst = dst_buf; 3771 if (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 && 3772 dst[3] == 0 && dst[4] == 0 && dst[5] == 0) 3773 dst = NULL; 3774 pos = cmd + 17; 3775 if (*pos != ' ') 3776 return -1; 3777 pos++; 3778 3779 if (os_strncmp(pos, "upnp ", 5) == 0) { 3780 u8 version; 3781 pos += 5; 3782 if (hexstr2bin(pos, &version, 1) < 0) 3783 return -1; 3784 pos += 2; 3785 if (*pos != ' ') 3786 return -1; 3787 pos++; 3788 ref = wpas_p2p_sd_request_upnp(wpa_s, dst, version, pos); 3789 #ifdef CONFIG_WIFI_DISPLAY 3790 } else if (os_strncmp(pos, "wifi-display ", 13) == 0) { 3791 ref = wpas_p2p_sd_request_wifi_display(wpa_s, dst, pos + 13); 3792 #endif /* CONFIG_WIFI_DISPLAY */ 3793 } else { 3794 len = os_strlen(pos); 3795 if (len & 1) 3796 return -1; 3797 len /= 2; 3798 tlvs = wpabuf_alloc(len); 3799 if (tlvs == NULL) 3800 return -1; 3801 if (hexstr2bin(pos, wpabuf_put(tlvs, len), len) < 0) { 3802 wpabuf_free(tlvs); 3803 return -1; 3804 } 3805 3806 ref = wpas_p2p_sd_request(wpa_s, dst, tlvs); 3807 wpabuf_free(tlvs); 3808 } 3809 if (ref == 0) 3810 return -1; 3811 res = os_snprintf(buf, buflen, "%llx", (long long unsigned) ref); 3812 if (res < 0 || (unsigned) res >= buflen) 3813 return -1; 3814 return res; 3815 } 3816 3817 3818 static int p2p_ctrl_serv_disc_cancel_req(struct wpa_supplicant *wpa_s, 3819 char *cmd) 3820 { 3821 long long unsigned val; 3822 u64 req; 3823 if (sscanf(cmd, "%llx", &val) != 1) 3824 return -1; 3825 req = val; 3826 return wpas_p2p_sd_cancel_request(wpa_s, req); 3827 } 3828 3829 3830 static int p2p_ctrl_serv_disc_resp(struct wpa_supplicant *wpa_s, char *cmd) 3831 { 3832 int freq; 3833 u8 dst[ETH_ALEN]; 3834 u8 dialog_token; 3835 struct wpabuf *resp_tlvs; 3836 char *pos, *pos2; 3837 size_t len; 3838 3839 pos = os_strchr(cmd, ' '); 3840 if (pos == NULL) 3841 return -1; 3842 *pos++ = '\0'; 3843 freq = atoi(cmd); 3844 if (freq == 0) 3845 return -1; 3846 3847 if (hwaddr_aton(pos, dst)) 3848 return -1; 3849 pos += 17; 3850 if (*pos != ' ') 3851 return -1; 3852 pos++; 3853 3854 pos2 = os_strchr(pos, ' '); 3855 if (pos2 == NULL) 3856 return -1; 3857 *pos2++ = '\0'; 3858 dialog_token = atoi(pos); 3859 3860 len = os_strlen(pos2); 3861 if (len & 1) 3862 return -1; 3863 len /= 2; 3864 resp_tlvs = wpabuf_alloc(len); 3865 if (resp_tlvs == NULL) 3866 return -1; 3867 if (hexstr2bin(pos2, wpabuf_put(resp_tlvs, len), len) < 0) { 3868 wpabuf_free(resp_tlvs); 3869 return -1; 3870 } 3871 3872 wpas_p2p_sd_response(wpa_s, freq, dst, dialog_token, resp_tlvs); 3873 wpabuf_free(resp_tlvs); 3874 return 0; 3875 } 3876 3877 3878 static int p2p_ctrl_serv_disc_external(struct wpa_supplicant *wpa_s, 3879 char *cmd) 3880 { 3881 if (os_strcmp(cmd, "0") && os_strcmp(cmd, "1")) 3882 return -1; 3883 wpa_s->p2p_sd_over_ctrl_iface = atoi(cmd); 3884 return 0; 3885 } 3886 3887 3888 static int p2p_ctrl_service_add_bonjour(struct wpa_supplicant *wpa_s, 3889 char *cmd) 3890 { 3891 char *pos; 3892 size_t len; 3893 struct wpabuf *query, *resp; 3894 3895 pos = os_strchr(cmd, ' '); 3896 if (pos == NULL) 3897 return -1; 3898 *pos++ = '\0'; 3899 3900 len = os_strlen(cmd); 3901 if (len & 1) 3902 return -1; 3903 len /= 2; 3904 query = wpabuf_alloc(len); 3905 if (query == NULL) 3906 return -1; 3907 if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) { 3908 wpabuf_free(query); 3909 return -1; 3910 } 3911 3912 len = os_strlen(pos); 3913 if (len & 1) { 3914 wpabuf_free(query); 3915 return -1; 3916 } 3917 len /= 2; 3918 resp = wpabuf_alloc(len); 3919 if (resp == NULL) { 3920 wpabuf_free(query); 3921 return -1; 3922 } 3923 if (hexstr2bin(pos, wpabuf_put(resp, len), len) < 0) { 3924 wpabuf_free(query); 3925 wpabuf_free(resp); 3926 return -1; 3927 } 3928 3929 if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0) { 3930 wpabuf_free(query); 3931 wpabuf_free(resp); 3932 return -1; 3933 } 3934 return 0; 3935 } 3936 3937 3938 static int p2p_ctrl_service_add_upnp(struct wpa_supplicant *wpa_s, char *cmd) 3939 { 3940 char *pos; 3941 u8 version; 3942 3943 pos = os_strchr(cmd, ' '); 3944 if (pos == NULL) 3945 return -1; 3946 *pos++ = '\0'; 3947 3948 if (hexstr2bin(cmd, &version, 1) < 0) 3949 return -1; 3950 3951 return wpas_p2p_service_add_upnp(wpa_s, version, pos); 3952 } 3953 3954 3955 static int p2p_ctrl_service_add(struct wpa_supplicant *wpa_s, char *cmd) 3956 { 3957 char *pos; 3958 3959 pos = os_strchr(cmd, ' '); 3960 if (pos == NULL) 3961 return -1; 3962 *pos++ = '\0'; 3963 3964 if (os_strcmp(cmd, "bonjour") == 0) 3965 return p2p_ctrl_service_add_bonjour(wpa_s, pos); 3966 if (os_strcmp(cmd, "upnp") == 0) 3967 return p2p_ctrl_service_add_upnp(wpa_s, pos); 3968 wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd); 3969 return -1; 3970 } 3971 3972 3973 static int p2p_ctrl_service_del_bonjour(struct wpa_supplicant *wpa_s, 3974 char *cmd) 3975 { 3976 size_t len; 3977 struct wpabuf *query; 3978 int ret; 3979 3980 len = os_strlen(cmd); 3981 if (len & 1) 3982 return -1; 3983 len /= 2; 3984 query = wpabuf_alloc(len); 3985 if (query == NULL) 3986 return -1; 3987 if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) { 3988 wpabuf_free(query); 3989 return -1; 3990 } 3991 3992 ret = wpas_p2p_service_del_bonjour(wpa_s, query); 3993 wpabuf_free(query); 3994 return ret; 3995 } 3996 3997 3998 static int p2p_ctrl_service_del_upnp(struct wpa_supplicant *wpa_s, char *cmd) 3999 { 4000 char *pos; 4001 u8 version; 4002 4003 pos = os_strchr(cmd, ' '); 4004 if (pos == NULL) 4005 return -1; 4006 *pos++ = '\0'; 4007 4008 if (hexstr2bin(cmd, &version, 1) < 0) 4009 return -1; 4010 4011 return wpas_p2p_service_del_upnp(wpa_s, version, pos); 4012 } 4013 4014 4015 static int p2p_ctrl_service_del(struct wpa_supplicant *wpa_s, char *cmd) 4016 { 4017 char *pos; 4018 4019 pos = os_strchr(cmd, ' '); 4020 if (pos == NULL) 4021 return -1; 4022 *pos++ = '\0'; 4023 4024 if (os_strcmp(cmd, "bonjour") == 0) 4025 return p2p_ctrl_service_del_bonjour(wpa_s, pos); 4026 if (os_strcmp(cmd, "upnp") == 0) 4027 return p2p_ctrl_service_del_upnp(wpa_s, pos); 4028 wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd); 4029 return -1; 4030 } 4031 4032 4033 static int p2p_ctrl_reject(struct wpa_supplicant *wpa_s, char *cmd) 4034 { 4035 u8 addr[ETH_ALEN]; 4036 4037 /* <addr> */ 4038 4039 if (hwaddr_aton(cmd, addr)) 4040 return -1; 4041 4042 return wpas_p2p_reject(wpa_s, addr); 4043 } 4044 4045 4046 static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd) 4047 { 4048 char *pos; 4049 int id; 4050 struct wpa_ssid *ssid; 4051 u8 *_peer = NULL, peer[ETH_ALEN]; 4052 int freq = 0, pref_freq = 0; 4053 int ht40; 4054 4055 id = atoi(cmd); 4056 pos = os_strstr(cmd, " peer="); 4057 if (pos) { 4058 pos += 6; 4059 if (hwaddr_aton(pos, peer)) 4060 return -1; 4061 _peer = peer; 4062 } 4063 ssid = wpa_config_get_network(wpa_s->conf, id); 4064 if (ssid == NULL || ssid->disabled != 2) { 4065 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 4066 "for persistent P2P group", 4067 id); 4068 return -1; 4069 } 4070 4071 pos = os_strstr(cmd, " freq="); 4072 if (pos) { 4073 pos += 6; 4074 freq = atoi(pos); 4075 if (freq <= 0) 4076 return -1; 4077 } 4078 4079 pos = os_strstr(cmd, " pref="); 4080 if (pos) { 4081 pos += 6; 4082 pref_freq = atoi(pos); 4083 if (pref_freq <= 0) 4084 return -1; 4085 } 4086 4087 ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40; 4088 4089 return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, ht40, pref_freq); 4090 } 4091 4092 4093 static int p2p_ctrl_invite_group(struct wpa_supplicant *wpa_s, char *cmd) 4094 { 4095 char *pos; 4096 u8 peer[ETH_ALEN], go_dev_addr[ETH_ALEN], *go_dev = NULL; 4097 4098 pos = os_strstr(cmd, " peer="); 4099 if (!pos) 4100 return -1; 4101 4102 *pos = '\0'; 4103 pos += 6; 4104 if (hwaddr_aton(pos, peer)) { 4105 wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'", pos); 4106 return -1; 4107 } 4108 4109 pos = os_strstr(pos, " go_dev_addr="); 4110 if (pos) { 4111 pos += 13; 4112 if (hwaddr_aton(pos, go_dev_addr)) { 4113 wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'", 4114 pos); 4115 return -1; 4116 } 4117 go_dev = go_dev_addr; 4118 } 4119 4120 return wpas_p2p_invite_group(wpa_s, cmd, peer, go_dev); 4121 } 4122 4123 4124 static int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd) 4125 { 4126 if (os_strncmp(cmd, "persistent=", 11) == 0) 4127 return p2p_ctrl_invite_persistent(wpa_s, cmd + 11); 4128 if (os_strncmp(cmd, "group=", 6) == 0) 4129 return p2p_ctrl_invite_group(wpa_s, cmd + 6); 4130 4131 return -1; 4132 } 4133 4134 4135 static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s, 4136 char *cmd, int freq, int ht40) 4137 { 4138 int id; 4139 struct wpa_ssid *ssid; 4140 4141 id = atoi(cmd); 4142 ssid = wpa_config_get_network(wpa_s->conf, id); 4143 if (ssid == NULL || ssid->disabled != 2) { 4144 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 4145 "for persistent P2P group", 4146 id); 4147 return -1; 4148 } 4149 4150 return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, ht40, NULL); 4151 } 4152 4153 4154 static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd) 4155 { 4156 int freq = 0, ht40; 4157 char *pos; 4158 4159 pos = os_strstr(cmd, "freq="); 4160 if (pos) 4161 freq = atoi(pos + 5); 4162 4163 ht40 = (os_strstr(cmd, "ht40") != NULL) || wpa_s->conf->p2p_go_ht40; 4164 4165 if (os_strncmp(cmd, "persistent=", 11) == 0) 4166 return p2p_ctrl_group_add_persistent(wpa_s, cmd + 11, freq, 4167 ht40); 4168 if (os_strcmp(cmd, "persistent") == 0 || 4169 os_strncmp(cmd, "persistent ", 11) == 0) 4170 return wpas_p2p_group_add(wpa_s, 1, freq, ht40); 4171 if (os_strncmp(cmd, "freq=", 5) == 0) 4172 return wpas_p2p_group_add(wpa_s, 0, freq, ht40); 4173 if (ht40) 4174 return wpas_p2p_group_add(wpa_s, 0, freq, ht40); 4175 4176 wpa_printf(MSG_DEBUG, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'", 4177 cmd); 4178 return -1; 4179 } 4180 4181 4182 static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd, 4183 char *buf, size_t buflen) 4184 { 4185 u8 addr[ETH_ALEN], *addr_ptr; 4186 int next, res; 4187 const struct p2p_peer_info *info; 4188 char *pos, *end; 4189 char devtype[WPS_DEV_TYPE_BUFSIZE]; 4190 struct wpa_ssid *ssid; 4191 size_t i; 4192 4193 if (!wpa_s->global->p2p) 4194 return -1; 4195 4196 if (os_strcmp(cmd, "FIRST") == 0) { 4197 addr_ptr = NULL; 4198 next = 0; 4199 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) { 4200 if (hwaddr_aton(cmd + 5, addr) < 0) 4201 return -1; 4202 addr_ptr = addr; 4203 next = 1; 4204 } else { 4205 if (hwaddr_aton(cmd, addr) < 0) 4206 return -1; 4207 addr_ptr = addr; 4208 next = 0; 4209 } 4210 4211 info = p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next); 4212 if (info == NULL) 4213 return -1; 4214 4215 pos = buf; 4216 end = buf + buflen; 4217 4218 res = os_snprintf(pos, end - pos, MACSTR "\n" 4219 "pri_dev_type=%s\n" 4220 "device_name=%s\n" 4221 "manufacturer=%s\n" 4222 "model_name=%s\n" 4223 "model_number=%s\n" 4224 "serial_number=%s\n" 4225 "config_methods=0x%x\n" 4226 "dev_capab=0x%x\n" 4227 "group_capab=0x%x\n" 4228 "level=%d\n", 4229 MAC2STR(info->p2p_device_addr), 4230 wps_dev_type_bin2str(info->pri_dev_type, 4231 devtype, sizeof(devtype)), 4232 info->device_name, 4233 info->manufacturer, 4234 info->model_name, 4235 info->model_number, 4236 info->serial_number, 4237 info->config_methods, 4238 info->dev_capab, 4239 info->group_capab, 4240 info->level); 4241 if (res < 0 || res >= end - pos) 4242 return pos - buf; 4243 pos += res; 4244 4245 for (i = 0; i < info->wps_sec_dev_type_list_len / WPS_DEV_TYPE_LEN; i++) 4246 { 4247 const u8 *t; 4248 t = &info->wps_sec_dev_type_list[i * WPS_DEV_TYPE_LEN]; 4249 res = os_snprintf(pos, end - pos, "sec_dev_type=%s\n", 4250 wps_dev_type_bin2str(t, devtype, 4251 sizeof(devtype))); 4252 if (res < 0 || res >= end - pos) 4253 return pos - buf; 4254 pos += res; 4255 } 4256 4257 ssid = wpas_p2p_get_persistent(wpa_s, info->p2p_device_addr, NULL, 0); 4258 if (ssid) { 4259 res = os_snprintf(pos, end - pos, "persistent=%d\n", ssid->id); 4260 if (res < 0 || res >= end - pos) 4261 return pos - buf; 4262 pos += res; 4263 } 4264 4265 res = p2p_get_peer_info_txt(info, pos, end - pos); 4266 if (res < 0) 4267 return pos - buf; 4268 pos += res; 4269 4270 return pos - buf; 4271 } 4272 4273 4274 static int p2p_ctrl_disallow_freq(struct wpa_supplicant *wpa_s, 4275 const char *param) 4276 { 4277 struct wpa_freq_range *freq = NULL, *n; 4278 unsigned int count = 0, i; 4279 const char *pos, *pos2, *pos3; 4280 4281 if (wpa_s->global->p2p == NULL) 4282 return -1; 4283 4284 /* 4285 * param includes comma separated frequency range. 4286 * For example: 2412-2432,2462,5000-6000 4287 */ 4288 pos = param; 4289 while (pos && pos[0]) { 4290 n = os_realloc_array(freq, count + 1, 4291 sizeof(struct wpa_freq_range)); 4292 if (n == NULL) { 4293 os_free(freq); 4294 return -1; 4295 } 4296 freq = n; 4297 freq[count].min = atoi(pos); 4298 pos2 = os_strchr(pos, '-'); 4299 pos3 = os_strchr(pos, ','); 4300 if (pos2 && (!pos3 || pos2 < pos3)) { 4301 pos2++; 4302 freq[count].max = atoi(pos2); 4303 } else 4304 freq[count].max = freq[count].min; 4305 pos = pos3; 4306 if (pos) 4307 pos++; 4308 count++; 4309 } 4310 4311 for (i = 0; i < count; i++) { 4312 wpa_printf(MSG_DEBUG, "P2P: Disallowed frequency range %u-%u", 4313 freq[i].min, freq[i].max); 4314 } 4315 4316 os_free(wpa_s->global->p2p_disallow_freq); 4317 wpa_s->global->p2p_disallow_freq = freq; 4318 wpa_s->global->num_p2p_disallow_freq = count; 4319 wpas_p2p_update_channel_list(wpa_s); 4320 return 0; 4321 } 4322 4323 4324 static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd) 4325 { 4326 char *param; 4327 4328 if (wpa_s->global->p2p == NULL) 4329 return -1; 4330 4331 param = os_strchr(cmd, ' '); 4332 if (param == NULL) 4333 return -1; 4334 *param++ = '\0'; 4335 4336 if (os_strcmp(cmd, "discoverability") == 0) { 4337 p2p_set_client_discoverability(wpa_s->global->p2p, 4338 atoi(param)); 4339 return 0; 4340 } 4341 4342 if (os_strcmp(cmd, "managed") == 0) { 4343 p2p_set_managed_oper(wpa_s->global->p2p, atoi(param)); 4344 return 0; 4345 } 4346 4347 if (os_strcmp(cmd, "listen_channel") == 0) { 4348 return p2p_set_listen_channel(wpa_s->global->p2p, 81, 4349 atoi(param)); 4350 } 4351 4352 if (os_strcmp(cmd, "ssid_postfix") == 0) { 4353 return p2p_set_ssid_postfix(wpa_s->global->p2p, (u8 *) param, 4354 os_strlen(param)); 4355 } 4356 4357 if (os_strcmp(cmd, "noa") == 0) { 4358 char *pos; 4359 int count, start, duration; 4360 /* GO NoA parameters: count,start_offset(ms),duration(ms) */ 4361 count = atoi(param); 4362 pos = os_strchr(param, ','); 4363 if (pos == NULL) 4364 return -1; 4365 pos++; 4366 start = atoi(pos); 4367 pos = os_strchr(pos, ','); 4368 if (pos == NULL) 4369 return -1; 4370 pos++; 4371 duration = atoi(pos); 4372 if (count < 0 || count > 255 || start < 0 || duration < 0) 4373 return -1; 4374 if (count == 0 && duration > 0) 4375 return -1; 4376 wpa_printf(MSG_DEBUG, "CTRL_IFACE: P2P_SET GO NoA: count=%d " 4377 "start=%d duration=%d", count, start, duration); 4378 return wpas_p2p_set_noa(wpa_s, count, start, duration); 4379 } 4380 4381 if (os_strcmp(cmd, "ps") == 0) 4382 return wpa_drv_set_p2p_powersave(wpa_s, atoi(param), -1, -1); 4383 4384 if (os_strcmp(cmd, "oppps") == 0) 4385 return wpa_drv_set_p2p_powersave(wpa_s, -1, atoi(param), -1); 4386 4387 if (os_strcmp(cmd, "ctwindow") == 0) 4388 return wpa_drv_set_p2p_powersave(wpa_s, -1, -1, atoi(param)); 4389 4390 if (os_strcmp(cmd, "disabled") == 0) { 4391 wpa_s->global->p2p_disabled = atoi(param); 4392 wpa_printf(MSG_DEBUG, "P2P functionality %s", 4393 wpa_s->global->p2p_disabled ? 4394 "disabled" : "enabled"); 4395 if (wpa_s->global->p2p_disabled) { 4396 wpas_p2p_stop_find(wpa_s); 4397 os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); 4398 p2p_flush(wpa_s->global->p2p); 4399 } 4400 return 0; 4401 } 4402 4403 if (os_strcmp(cmd, "conc_pref") == 0) { 4404 if (os_strcmp(param, "sta") == 0) 4405 wpa_s->global->conc_pref = WPA_CONC_PREF_STA; 4406 else if (os_strcmp(param, "p2p") == 0) 4407 wpa_s->global->conc_pref = WPA_CONC_PREF_P2P; 4408 else { 4409 wpa_printf(MSG_INFO, "Invalid conc_pref value"); 4410 return -1; 4411 } 4412 wpa_printf(MSG_DEBUG, "Single channel concurrency preference: " 4413 "%s", param); 4414 return 0; 4415 } 4416 4417 if (os_strcmp(cmd, "force_long_sd") == 0) { 4418 wpa_s->force_long_sd = atoi(param); 4419 return 0; 4420 } 4421 4422 if (os_strcmp(cmd, "peer_filter") == 0) { 4423 u8 addr[ETH_ALEN]; 4424 if (hwaddr_aton(param, addr)) 4425 return -1; 4426 p2p_set_peer_filter(wpa_s->global->p2p, addr); 4427 return 0; 4428 } 4429 4430 if (os_strcmp(cmd, "cross_connect") == 0) 4431 return wpas_p2p_set_cross_connect(wpa_s, atoi(param)); 4432 4433 if (os_strcmp(cmd, "go_apsd") == 0) { 4434 if (os_strcmp(param, "disable") == 0) 4435 wpa_s->set_ap_uapsd = 0; 4436 else { 4437 wpa_s->set_ap_uapsd = 1; 4438 wpa_s->ap_uapsd = atoi(param); 4439 } 4440 return 0; 4441 } 4442 4443 if (os_strcmp(cmd, "client_apsd") == 0) { 4444 if (os_strcmp(param, "disable") == 0) 4445 wpa_s->set_sta_uapsd = 0; 4446 else { 4447 int be, bk, vi, vo; 4448 char *pos; 4449 /* format: BE,BK,VI,VO;max SP Length */ 4450 be = atoi(param); 4451 pos = os_strchr(param, ','); 4452 if (pos == NULL) 4453 return -1; 4454 pos++; 4455 bk = atoi(pos); 4456 pos = os_strchr(pos, ','); 4457 if (pos == NULL) 4458 return -1; 4459 pos++; 4460 vi = atoi(pos); 4461 pos = os_strchr(pos, ','); 4462 if (pos == NULL) 4463 return -1; 4464 pos++; 4465 vo = atoi(pos); 4466 /* ignore max SP Length for now */ 4467 4468 wpa_s->set_sta_uapsd = 1; 4469 wpa_s->sta_uapsd = 0; 4470 if (be) 4471 wpa_s->sta_uapsd |= BIT(0); 4472 if (bk) 4473 wpa_s->sta_uapsd |= BIT(1); 4474 if (vi) 4475 wpa_s->sta_uapsd |= BIT(2); 4476 if (vo) 4477 wpa_s->sta_uapsd |= BIT(3); 4478 } 4479 return 0; 4480 } 4481 4482 if (os_strcmp(cmd, "disallow_freq") == 0) 4483 return p2p_ctrl_disallow_freq(wpa_s, param); 4484 4485 if (os_strcmp(cmd, "disc_int") == 0) { 4486 int min_disc_int, max_disc_int, max_disc_tu; 4487 char *pos; 4488 4489 pos = param; 4490 4491 min_disc_int = atoi(pos); 4492 pos = os_strchr(pos, ' '); 4493 if (pos == NULL) 4494 return -1; 4495 *pos++ = '\0'; 4496 4497 max_disc_int = atoi(pos); 4498 pos = os_strchr(pos, ' '); 4499 if (pos == NULL) 4500 return -1; 4501 *pos++ = '\0'; 4502 4503 max_disc_tu = atoi(pos); 4504 4505 return p2p_set_disc_int(wpa_s->global->p2p, min_disc_int, 4506 max_disc_int, max_disc_tu); 4507 } 4508 4509 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'", 4510 cmd); 4511 4512 return -1; 4513 } 4514 4515 4516 static void p2p_ctrl_flush(struct wpa_supplicant *wpa_s) 4517 { 4518 os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); 4519 wpa_s->force_long_sd = 0; 4520 if (wpa_s->global->p2p) 4521 p2p_flush(wpa_s->global->p2p); 4522 } 4523 4524 4525 static int p2p_ctrl_presence_req(struct wpa_supplicant *wpa_s, char *cmd) 4526 { 4527 char *pos, *pos2; 4528 unsigned int dur1 = 0, int1 = 0, dur2 = 0, int2 = 0; 4529 4530 if (cmd[0]) { 4531 pos = os_strchr(cmd, ' '); 4532 if (pos == NULL) 4533 return -1; 4534 *pos++ = '\0'; 4535 dur1 = atoi(cmd); 4536 4537 pos2 = os_strchr(pos, ' '); 4538 if (pos2) 4539 *pos2++ = '\0'; 4540 int1 = atoi(pos); 4541 } else 4542 pos2 = NULL; 4543 4544 if (pos2) { 4545 pos = os_strchr(pos2, ' '); 4546 if (pos == NULL) 4547 return -1; 4548 *pos++ = '\0'; 4549 dur2 = atoi(pos2); 4550 int2 = atoi(pos); 4551 } 4552 4553 return wpas_p2p_presence_req(wpa_s, dur1, int1, dur2, int2); 4554 } 4555 4556 4557 static int p2p_ctrl_ext_listen(struct wpa_supplicant *wpa_s, char *cmd) 4558 { 4559 char *pos; 4560 unsigned int period = 0, interval = 0; 4561 4562 if (cmd[0]) { 4563 pos = os_strchr(cmd, ' '); 4564 if (pos == NULL) 4565 return -1; 4566 *pos++ = '\0'; 4567 period = atoi(cmd); 4568 interval = atoi(pos); 4569 } 4570 4571 return wpas_p2p_ext_listen(wpa_s, period, interval); 4572 } 4573 4574 #endif /* CONFIG_P2P */ 4575 4576 4577 #ifdef CONFIG_INTERWORKING 4578 static int ctrl_interworking_connect(struct wpa_supplicant *wpa_s, char *dst) 4579 { 4580 u8 bssid[ETH_ALEN]; 4581 struct wpa_bss *bss; 4582 4583 if (hwaddr_aton(dst, bssid)) { 4584 wpa_printf(MSG_DEBUG, "Invalid BSSID '%s'", dst); 4585 return -1; 4586 } 4587 4588 bss = wpa_bss_get_bssid(wpa_s, bssid); 4589 if (bss == NULL) { 4590 wpa_printf(MSG_DEBUG, "Could not find BSS " MACSTR, 4591 MAC2STR(bssid)); 4592 return -1; 4593 } 4594 4595 return interworking_connect(wpa_s, bss); 4596 } 4597 4598 4599 static int get_anqp(struct wpa_supplicant *wpa_s, char *dst) 4600 { 4601 u8 dst_addr[ETH_ALEN]; 4602 int used; 4603 char *pos; 4604 #define MAX_ANQP_INFO_ID 100 4605 u16 id[MAX_ANQP_INFO_ID]; 4606 size_t num_id = 0; 4607 4608 used = hwaddr_aton2(dst, dst_addr); 4609 if (used < 0) 4610 return -1; 4611 pos = dst + used; 4612 while (num_id < MAX_ANQP_INFO_ID) { 4613 id[num_id] = atoi(pos); 4614 if (id[num_id]) 4615 num_id++; 4616 pos = os_strchr(pos + 1, ','); 4617 if (pos == NULL) 4618 break; 4619 pos++; 4620 } 4621 4622 if (num_id == 0) 4623 return -1; 4624 4625 return anqp_send_req(wpa_s, dst_addr, id, num_id); 4626 } 4627 4628 4629 static int gas_request(struct wpa_supplicant *wpa_s, char *cmd) 4630 { 4631 u8 dst_addr[ETH_ALEN]; 4632 struct wpabuf *advproto, *query = NULL; 4633 int used, ret = -1; 4634 char *pos, *end; 4635 size_t len; 4636 4637 used = hwaddr_aton2(cmd, dst_addr); 4638 if (used < 0) 4639 return -1; 4640 4641 pos = cmd + used; 4642 while (*pos == ' ') 4643 pos++; 4644 4645 /* Advertisement Protocol ID */ 4646 end = os_strchr(pos, ' '); 4647 if (end) 4648 len = end - pos; 4649 else 4650 len = os_strlen(pos); 4651 if (len & 0x01) 4652 return -1; 4653 len /= 2; 4654 if (len == 0) 4655 return -1; 4656 advproto = wpabuf_alloc(len); 4657 if (advproto == NULL) 4658 return -1; 4659 if (hexstr2bin(pos, wpabuf_put(advproto, len), len) < 0) 4660 goto fail; 4661 4662 if (end) { 4663 /* Optional Query Request */ 4664 pos = end + 1; 4665 while (*pos == ' ') 4666 pos++; 4667 4668 len = os_strlen(pos); 4669 if (len) { 4670 if (len & 0x01) 4671 goto fail; 4672 len /= 2; 4673 if (len == 0) 4674 goto fail; 4675 query = wpabuf_alloc(len); 4676 if (query == NULL) 4677 goto fail; 4678 if (hexstr2bin(pos, wpabuf_put(query, len), len) < 0) 4679 goto fail; 4680 } 4681 } 4682 4683 ret = gas_send_request(wpa_s, dst_addr, advproto, query); 4684 4685 fail: 4686 wpabuf_free(advproto); 4687 wpabuf_free(query); 4688 4689 return ret; 4690 } 4691 4692 4693 static int gas_response_get(struct wpa_supplicant *wpa_s, char *cmd, char *buf, 4694 size_t buflen) 4695 { 4696 u8 addr[ETH_ALEN]; 4697 int dialog_token; 4698 int used; 4699 char *pos; 4700 size_t resp_len, start, requested_len; 4701 4702 if (!wpa_s->last_gas_resp) 4703 return -1; 4704 4705 used = hwaddr_aton2(cmd, addr); 4706 if (used < 0) 4707 return -1; 4708 4709 pos = cmd + used; 4710 while (*pos == ' ') 4711 pos++; 4712 dialog_token = atoi(pos); 4713 4714 if (os_memcmp(addr, wpa_s->last_gas_addr, ETH_ALEN) != 0 || 4715 dialog_token != wpa_s->last_gas_dialog_token) 4716 return -1; 4717 4718 resp_len = wpabuf_len(wpa_s->last_gas_resp); 4719 start = 0; 4720 requested_len = resp_len; 4721 4722 pos = os_strchr(pos, ' '); 4723 if (pos) { 4724 start = atoi(pos); 4725 if (start > resp_len) 4726 return os_snprintf(buf, buflen, "FAIL-Invalid range"); 4727 pos = os_strchr(pos, ','); 4728 if (pos == NULL) 4729 return -1; 4730 pos++; 4731 requested_len = atoi(pos); 4732 if (start + requested_len > resp_len) 4733 return os_snprintf(buf, buflen, "FAIL-Invalid range"); 4734 } 4735 4736 if (requested_len * 2 + 1 > buflen) 4737 return os_snprintf(buf, buflen, "FAIL-Too long response"); 4738 4739 return wpa_snprintf_hex(buf, buflen, 4740 wpabuf_head_u8(wpa_s->last_gas_resp) + start, 4741 requested_len); 4742 } 4743 #endif /* CONFIG_INTERWORKING */ 4744 4745 4746 #ifdef CONFIG_HS20 4747 4748 static int get_hs20_anqp(struct wpa_supplicant *wpa_s, char *dst) 4749 { 4750 u8 dst_addr[ETH_ALEN]; 4751 int used; 4752 char *pos; 4753 u32 subtypes = 0; 4754 4755 used = hwaddr_aton2(dst, dst_addr); 4756 if (used < 0) 4757 return -1; 4758 pos = dst + used; 4759 for (;;) { 4760 int num = atoi(pos); 4761 if (num <= 0 || num > 31) 4762 return -1; 4763 subtypes |= BIT(num); 4764 pos = os_strchr(pos + 1, ','); 4765 if (pos == NULL) 4766 break; 4767 pos++; 4768 } 4769 4770 if (subtypes == 0) 4771 return -1; 4772 4773 return hs20_anqp_send_req(wpa_s, dst_addr, subtypes, NULL, 0); 4774 } 4775 4776 4777 static int hs20_nai_home_realm_list(struct wpa_supplicant *wpa_s, 4778 const u8 *addr, const char *realm) 4779 { 4780 u8 *buf; 4781 size_t rlen, len; 4782 int ret; 4783 4784 rlen = os_strlen(realm); 4785 len = 3 + rlen; 4786 buf = os_malloc(len); 4787 if (buf == NULL) 4788 return -1; 4789 buf[0] = 1; /* NAI Home Realm Count */ 4790 buf[1] = 0; /* Formatted in accordance with RFC 4282 */ 4791 buf[2] = rlen; 4792 os_memcpy(buf + 3, realm, rlen); 4793 4794 ret = hs20_anqp_send_req(wpa_s, addr, 4795 BIT(HS20_STYPE_NAI_HOME_REALM_QUERY), 4796 buf, len); 4797 4798 os_free(buf); 4799 4800 return ret; 4801 } 4802 4803 4804 static int hs20_get_nai_home_realm_list(struct wpa_supplicant *wpa_s, 4805 char *dst) 4806 { 4807 struct wpa_cred *cred = wpa_s->conf->cred; 4808 u8 dst_addr[ETH_ALEN]; 4809 int used; 4810 u8 *buf; 4811 size_t len; 4812 int ret; 4813 4814 used = hwaddr_aton2(dst, dst_addr); 4815 if (used < 0) 4816 return -1; 4817 4818 while (dst[used] == ' ') 4819 used++; 4820 if (os_strncmp(dst + used, "realm=", 6) == 0) 4821 return hs20_nai_home_realm_list(wpa_s, dst_addr, 4822 dst + used + 6); 4823 4824 len = os_strlen(dst + used); 4825 4826 if (len == 0 && cred && cred->realm) 4827 return hs20_nai_home_realm_list(wpa_s, dst_addr, cred->realm); 4828 4829 if (len % 1) 4830 return -1; 4831 len /= 2; 4832 buf = os_malloc(len); 4833 if (buf == NULL) 4834 return -1; 4835 if (hexstr2bin(dst + used, buf, len) < 0) { 4836 os_free(buf); 4837 return -1; 4838 } 4839 4840 ret = hs20_anqp_send_req(wpa_s, dst_addr, 4841 BIT(HS20_STYPE_NAI_HOME_REALM_QUERY), 4842 buf, len); 4843 os_free(buf); 4844 4845 return ret; 4846 } 4847 4848 #endif /* CONFIG_HS20 */ 4849 4850 4851 static int wpa_supplicant_ctrl_iface_sta_autoconnect( 4852 struct wpa_supplicant *wpa_s, char *cmd) 4853 { 4854 wpa_s->auto_reconnect_disabled = atoi(cmd) == 0 ? 1 : 0; 4855 return 0; 4856 } 4857 4858 4859 #ifdef CONFIG_AUTOSCAN 4860 4861 static int wpa_supplicant_ctrl_iface_autoscan(struct wpa_supplicant *wpa_s, 4862 char *cmd) 4863 { 4864 enum wpa_states state = wpa_s->wpa_state; 4865 char *new_params = NULL; 4866 4867 if (os_strlen(cmd) > 0) { 4868 new_params = os_strdup(cmd); 4869 if (new_params == NULL) 4870 return -1; 4871 } 4872 4873 os_free(wpa_s->conf->autoscan); 4874 wpa_s->conf->autoscan = new_params; 4875 4876 if (wpa_s->conf->autoscan == NULL) 4877 autoscan_deinit(wpa_s); 4878 else if (state == WPA_DISCONNECTED || state == WPA_INACTIVE) 4879 autoscan_init(wpa_s, 1); 4880 else if (state == WPA_SCANNING) 4881 wpa_supplicant_reinit_autoscan(wpa_s); 4882 4883 return 0; 4884 } 4885 4886 #endif /* CONFIG_AUTOSCAN */ 4887 4888 4889 #ifdef CONFIG_WNM 4890 4891 static int wpas_ctrl_iface_wnm_sleep(struct wpa_supplicant *wpa_s, char *cmd) 4892 { 4893 int enter; 4894 int intval = 0; 4895 char *pos; 4896 int ret; 4897 struct wpabuf *tfs_req = NULL; 4898 4899 if (os_strncmp(cmd, "enter", 5) == 0) 4900 enter = 1; 4901 else if (os_strncmp(cmd, "exit", 4) == 0) 4902 enter = 0; 4903 else 4904 return -1; 4905 4906 pos = os_strstr(cmd, " interval="); 4907 if (pos) 4908 intval = atoi(pos + 10); 4909 4910 pos = os_strstr(cmd, " tfs_req="); 4911 if (pos) { 4912 char *end; 4913 size_t len; 4914 pos += 9; 4915 end = os_strchr(pos, ' '); 4916 if (end) 4917 len = end - pos; 4918 else 4919 len = os_strlen(pos); 4920 if (len & 1) 4921 return -1; 4922 len /= 2; 4923 tfs_req = wpabuf_alloc(len); 4924 if (tfs_req == NULL) 4925 return -1; 4926 if (hexstr2bin(pos, wpabuf_put(tfs_req, len), len) < 0) { 4927 wpabuf_free(tfs_req); 4928 return -1; 4929 } 4930 } 4931 4932 ret = ieee802_11_send_wnmsleep_req(wpa_s, enter ? WNM_SLEEP_MODE_ENTER : 4933 WNM_SLEEP_MODE_EXIT, intval, 4934 tfs_req); 4935 wpabuf_free(tfs_req); 4936 4937 return ret; 4938 } 4939 4940 #endif /* CONFIG_WNM */ 4941 4942 4943 static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf, 4944 size_t buflen) 4945 { 4946 struct wpa_signal_info si; 4947 int ret; 4948 4949 ret = wpa_drv_signal_poll(wpa_s, &si); 4950 if (ret) 4951 return -1; 4952 4953 ret = os_snprintf(buf, buflen, "RSSI=%d\nLINKSPEED=%d\n" 4954 "NOISE=%d\nFREQUENCY=%u\n", 4955 si.current_signal, si.current_txrate / 1000, 4956 si.current_noise, si.frequency); 4957 if (ret < 0 || (unsigned int) ret > buflen) 4958 return -1; 4959 return ret; 4960 } 4961 4962 4963 static int wpa_supplicant_pktcnt_poll(struct wpa_supplicant *wpa_s, char *buf, 4964 size_t buflen) 4965 { 4966 struct hostap_sta_driver_data sta; 4967 int ret; 4968 4969 ret = wpa_drv_pktcnt_poll(wpa_s, &sta); 4970 if (ret) 4971 return -1; 4972 4973 ret = os_snprintf(buf, buflen, "TXGOOD=%lu\nTXBAD=%lu\nRXGOOD=%lu\n", 4974 sta.tx_packets, sta.tx_retry_failed, sta.rx_packets); 4975 if (ret < 0 || (size_t) ret > buflen) 4976 return -1; 4977 return ret; 4978 } 4979 4980 4981 #ifdef ANDROID 4982 static int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s, char *cmd, 4983 char *buf, size_t buflen) 4984 { 4985 int ret; 4986 4987 ret = wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen); 4988 if (ret == 0) 4989 ret = sprintf(buf, "%s\n", "OK"); 4990 return ret; 4991 } 4992 #endif 4993 4994 4995 static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s) 4996 { 4997 wpa_dbg(wpa_s, MSG_DEBUG, "Flush all wpa_supplicant state"); 4998 4999 #ifdef CONFIG_P2P 5000 wpas_p2p_stop_find(wpa_s); 5001 p2p_ctrl_flush(wpa_s); 5002 wpas_p2p_group_remove(wpa_s, "*"); 5003 #endif /* CONFIG_P2P */ 5004 5005 #ifdef CONFIG_WPS_TESTING 5006 wps_version_number = 0x20; 5007 wps_testing_dummy_cred = 0; 5008 #endif /* CONFIG_WPS_TESTING */ 5009 #ifdef CONFIG_WPS 5010 wpas_wps_cancel(wpa_s); 5011 #endif /* CONFIG_WPS */ 5012 5013 #ifdef CONFIG_TDLS_TESTING 5014 extern unsigned int tdls_testing; 5015 tdls_testing = 0; 5016 #endif /* CONFIG_TDLS_TESTING */ 5017 #ifdef CONFIG_TDLS 5018 wpa_drv_tdls_oper(wpa_s, TDLS_ENABLE, NULL); 5019 wpa_tdls_enable(wpa_s->wpa, 1); 5020 #endif /* CONFIG_TDLS */ 5021 5022 wpa_s->no_keep_alive = 0; 5023 5024 os_free(wpa_s->disallow_aps_bssid); 5025 wpa_s->disallow_aps_bssid = NULL; 5026 wpa_s->disallow_aps_bssid_count = 0; 5027 os_free(wpa_s->disallow_aps_ssid); 5028 wpa_s->disallow_aps_ssid = NULL; 5029 wpa_s->disallow_aps_ssid_count = 0; 5030 5031 wpa_s->set_sta_uapsd = 0; 5032 wpa_s->sta_uapsd = 0; 5033 5034 wpa_drv_radio_disable(wpa_s, 0); 5035 5036 wpa_bss_flush(wpa_s); 5037 wpa_blacklist_clear(wpa_s); 5038 wpa_supplicant_ctrl_iface_remove_network(wpa_s, "all"); 5039 wpa_supplicant_ctrl_iface_remove_cred(wpa_s, "all"); 5040 } 5041 5042 5043 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, 5044 char *buf, size_t *resp_len) 5045 { 5046 char *reply; 5047 const int reply_size = 4096; 5048 int ctrl_rsp = 0; 5049 int reply_len; 5050 5051 if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 || 5052 os_strncmp(buf, "SET_NETWORK ", 12) == 0 || 5053 os_strncmp(buf, "WPS_NFC_TAG_READ", 16) == 0 || 5054 os_strncmp(buf, "NFC_REPORT_HANDOVER", 19) == 0 || 5055 os_strncmp(buf, "NFC_RX_HANDOVER_SEL", 19) == 0) { 5056 wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface", 5057 (const u8 *) buf, os_strlen(buf)); 5058 } else { 5059 int level = MSG_DEBUG; 5060 if (os_strcmp(buf, "PING") == 0) 5061 level = MSG_EXCESSIVE; 5062 wpa_hexdump_ascii(level, "RX ctrl_iface", 5063 (const u8 *) buf, os_strlen(buf)); 5064 wpa_dbg(wpa_s, level, "Control interface command '%s'", buf); 5065 } 5066 5067 reply = os_malloc(reply_size); 5068 if (reply == NULL) { 5069 *resp_len = 1; 5070 return NULL; 5071 } 5072 5073 os_memcpy(reply, "OK\n", 3); 5074 reply_len = 3; 5075 5076 if (os_strcmp(buf, "PING") == 0) { 5077 os_memcpy(reply, "PONG\n", 5); 5078 reply_len = 5; 5079 } else if (os_strcmp(buf, "IFNAME") == 0) { 5080 reply_len = os_strlen(wpa_s->ifname); 5081 os_memcpy(reply, wpa_s->ifname, reply_len); 5082 } else if (os_strncmp(buf, "RELOG", 5) == 0) { 5083 if (wpa_debug_reopen_file() < 0) 5084 reply_len = -1; 5085 } else if (os_strncmp(buf, "NOTE ", 5) == 0) { 5086 wpa_printf(MSG_INFO, "NOTE: %s", buf + 5); 5087 } else if (os_strcmp(buf, "MIB") == 0) { 5088 reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); 5089 if (reply_len >= 0) { 5090 int res; 5091 res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len, 5092 reply_size - reply_len); 5093 if (res < 0) 5094 reply_len = -1; 5095 else 5096 reply_len += res; 5097 } 5098 } else if (os_strncmp(buf, "STATUS", 6) == 0) { 5099 reply_len = wpa_supplicant_ctrl_iface_status( 5100 wpa_s, buf + 6, reply, reply_size); 5101 } else if (os_strcmp(buf, "PMKSA") == 0) { 5102 reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, reply, 5103 reply_size); 5104 } else if (os_strncmp(buf, "SET ", 4) == 0) { 5105 if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4)) 5106 reply_len = -1; 5107 } else if (os_strncmp(buf, "GET ", 4) == 0) { 5108 reply_len = wpa_supplicant_ctrl_iface_get(wpa_s, buf + 4, 5109 reply, reply_size); 5110 } else if (os_strcmp(buf, "LOGON") == 0) { 5111 eapol_sm_notify_logoff(wpa_s->eapol, FALSE); 5112 } else if (os_strcmp(buf, "LOGOFF") == 0) { 5113 eapol_sm_notify_logoff(wpa_s->eapol, TRUE); 5114 } else if (os_strcmp(buf, "REASSOCIATE") == 0) { 5115 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) 5116 reply_len = -1; 5117 else 5118 wpas_request_connection(wpa_s); 5119 } else if (os_strcmp(buf, "RECONNECT") == 0) { 5120 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) 5121 reply_len = -1; 5122 else if (wpa_s->disconnected) 5123 wpas_request_connection(wpa_s); 5124 #ifdef IEEE8021X_EAPOL 5125 } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) { 5126 if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8)) 5127 reply_len = -1; 5128 #endif /* IEEE8021X_EAPOL */ 5129 #ifdef CONFIG_PEERKEY 5130 } else if (os_strncmp(buf, "STKSTART ", 9) == 0) { 5131 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9)) 5132 reply_len = -1; 5133 #endif /* CONFIG_PEERKEY */ 5134 #ifdef CONFIG_IEEE80211R 5135 } else if (os_strncmp(buf, "FT_DS ", 6) == 0) { 5136 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6)) 5137 reply_len = -1; 5138 #endif /* CONFIG_IEEE80211R */ 5139 #ifdef CONFIG_WPS 5140 } else if (os_strcmp(buf, "WPS_PBC") == 0) { 5141 int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, NULL); 5142 if (res == -2) { 5143 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17); 5144 reply_len = 17; 5145 } else if (res) 5146 reply_len = -1; 5147 } else if (os_strncmp(buf, "WPS_PBC ", 8) == 0) { 5148 int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, buf + 8); 5149 if (res == -2) { 5150 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17); 5151 reply_len = 17; 5152 } else if (res) 5153 reply_len = -1; 5154 } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) { 5155 reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8, 5156 reply, 5157 reply_size); 5158 } else if (os_strncmp(buf, "WPS_CHECK_PIN ", 14) == 0) { 5159 reply_len = wpa_supplicant_ctrl_iface_wps_check_pin( 5160 wpa_s, buf + 14, reply, reply_size); 5161 } else if (os_strcmp(buf, "WPS_CANCEL") == 0) { 5162 if (wpas_wps_cancel(wpa_s)) 5163 reply_len = -1; 5164 #ifdef CONFIG_WPS_NFC 5165 } else if (os_strcmp(buf, "WPS_NFC") == 0) { 5166 if (wpa_supplicant_ctrl_iface_wps_nfc(wpa_s, NULL)) 5167 reply_len = -1; 5168 } else if (os_strncmp(buf, "WPS_NFC ", 8) == 0) { 5169 if (wpa_supplicant_ctrl_iface_wps_nfc(wpa_s, buf + 8)) 5170 reply_len = -1; 5171 } else if (os_strncmp(buf, "WPS_NFC_CONFIG_TOKEN ", 21) == 0) { 5172 reply_len = wpa_supplicant_ctrl_iface_wps_nfc_config_token( 5173 wpa_s, buf + 21, reply, reply_size); 5174 } else if (os_strncmp(buf, "WPS_NFC_TOKEN ", 14) == 0) { 5175 reply_len = wpa_supplicant_ctrl_iface_wps_nfc_token( 5176 wpa_s, buf + 14, reply, reply_size); 5177 } else if (os_strncmp(buf, "WPS_NFC_TAG_READ ", 17) == 0) { 5178 if (wpa_supplicant_ctrl_iface_wps_nfc_tag_read(wpa_s, 5179 buf + 17)) 5180 reply_len = -1; 5181 } else if (os_strncmp(buf, "NFC_GET_HANDOVER_REQ ", 21) == 0) { 5182 reply_len = wpas_ctrl_nfc_get_handover_req( 5183 wpa_s, buf + 21, reply, reply_size); 5184 } else if (os_strncmp(buf, "NFC_GET_HANDOVER_SEL ", 21) == 0) { 5185 reply_len = wpas_ctrl_nfc_get_handover_sel( 5186 wpa_s, buf + 21, reply, reply_size); 5187 } else if (os_strncmp(buf, "NFC_RX_HANDOVER_REQ ", 20) == 0) { 5188 reply_len = wpas_ctrl_nfc_rx_handover_req( 5189 wpa_s, buf + 20, reply, reply_size); 5190 } else if (os_strncmp(buf, "NFC_RX_HANDOVER_SEL ", 20) == 0) { 5191 if (wpas_ctrl_nfc_rx_handover_sel(wpa_s, buf + 20)) 5192 reply_len = -1; 5193 } else if (os_strncmp(buf, "NFC_REPORT_HANDOVER ", 20) == 0) { 5194 if (wpas_ctrl_nfc_report_handover(wpa_s, buf + 20)) 5195 reply_len = -1; 5196 #endif /* CONFIG_WPS_NFC */ 5197 } else if (os_strncmp(buf, "WPS_REG ", 8) == 0) { 5198 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8)) 5199 reply_len = -1; 5200 #ifdef CONFIG_AP 5201 } else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) { 5202 reply_len = wpa_supplicant_ctrl_iface_wps_ap_pin( 5203 wpa_s, buf + 11, reply, reply_size); 5204 #endif /* CONFIG_AP */ 5205 #ifdef CONFIG_WPS_ER 5206 } else if (os_strcmp(buf, "WPS_ER_START") == 0) { 5207 if (wpas_wps_er_start(wpa_s, NULL)) 5208 reply_len = -1; 5209 } else if (os_strncmp(buf, "WPS_ER_START ", 13) == 0) { 5210 if (wpas_wps_er_start(wpa_s, buf + 13)) 5211 reply_len = -1; 5212 } else if (os_strcmp(buf, "WPS_ER_STOP") == 0) { 5213 if (wpas_wps_er_stop(wpa_s)) 5214 reply_len = -1; 5215 } else if (os_strncmp(buf, "WPS_ER_PIN ", 11) == 0) { 5216 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s, buf + 11)) 5217 reply_len = -1; 5218 } else if (os_strncmp(buf, "WPS_ER_PBC ", 11) == 0) { 5219 int ret = wpas_wps_er_pbc(wpa_s, buf + 11); 5220 if (ret == -2) { 5221 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17); 5222 reply_len = 17; 5223 } else if (ret == -3) { 5224 os_memcpy(reply, "FAIL-UNKNOWN-UUID\n", 18); 5225 reply_len = 18; 5226 } else if (ret == -4) { 5227 os_memcpy(reply, "FAIL-NO-AP-SETTINGS\n", 20); 5228 reply_len = 20; 5229 } else if (ret) 5230 reply_len = -1; 5231 } else if (os_strncmp(buf, "WPS_ER_LEARN ", 13) == 0) { 5232 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s, buf + 13)) 5233 reply_len = -1; 5234 } else if (os_strncmp(buf, "WPS_ER_SET_CONFIG ", 18) == 0) { 5235 if (wpa_supplicant_ctrl_iface_wps_er_set_config(wpa_s, 5236 buf + 18)) 5237 reply_len = -1; 5238 } else if (os_strncmp(buf, "WPS_ER_CONFIG ", 14) == 0) { 5239 if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s, buf + 14)) 5240 reply_len = -1; 5241 #ifdef CONFIG_WPS_NFC 5242 } else if (os_strncmp(buf, "WPS_ER_NFC_CONFIG_TOKEN ", 24) == 0) { 5243 reply_len = wpa_supplicant_ctrl_iface_wps_er_nfc_config_token( 5244 wpa_s, buf + 24, reply, reply_size); 5245 #endif /* CONFIG_WPS_NFC */ 5246 #endif /* CONFIG_WPS_ER */ 5247 #endif /* CONFIG_WPS */ 5248 #ifdef CONFIG_IBSS_RSN 5249 } else if (os_strncmp(buf, "IBSS_RSN ", 9) == 0) { 5250 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s, buf + 9)) 5251 reply_len = -1; 5252 #endif /* CONFIG_IBSS_RSN */ 5253 #ifdef CONFIG_P2P 5254 } else if (os_strncmp(buf, "P2P_FIND ", 9) == 0) { 5255 if (p2p_ctrl_find(wpa_s, buf + 9)) 5256 reply_len = -1; 5257 } else if (os_strcmp(buf, "P2P_FIND") == 0) { 5258 if (p2p_ctrl_find(wpa_s, "")) 5259 reply_len = -1; 5260 } else if (os_strcmp(buf, "P2P_STOP_FIND") == 0) { 5261 wpas_p2p_stop_find(wpa_s); 5262 } else if (os_strncmp(buf, "P2P_CONNECT ", 12) == 0) { 5263 reply_len = p2p_ctrl_connect(wpa_s, buf + 12, reply, 5264 reply_size); 5265 } else if (os_strncmp(buf, "P2P_LISTEN ", 11) == 0) { 5266 if (p2p_ctrl_listen(wpa_s, buf + 11)) 5267 reply_len = -1; 5268 } else if (os_strcmp(buf, "P2P_LISTEN") == 0) { 5269 if (p2p_ctrl_listen(wpa_s, "")) 5270 reply_len = -1; 5271 } else if (os_strncmp(buf, "P2P_GROUP_REMOVE ", 17) == 0) { 5272 if (wpas_p2p_group_remove(wpa_s, buf + 17)) 5273 reply_len = -1; 5274 } else if (os_strcmp(buf, "P2P_GROUP_ADD") == 0) { 5275 if (wpas_p2p_group_add(wpa_s, 0, 0, 0)) 5276 reply_len = -1; 5277 } else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) { 5278 if (p2p_ctrl_group_add(wpa_s, buf + 14)) 5279 reply_len = -1; 5280 } else if (os_strncmp(buf, "P2P_PROV_DISC ", 14) == 0) { 5281 if (p2p_ctrl_prov_disc(wpa_s, buf + 14)) 5282 reply_len = -1; 5283 } else if (os_strcmp(buf, "P2P_GET_PASSPHRASE") == 0) { 5284 reply_len = p2p_get_passphrase(wpa_s, reply, reply_size); 5285 } else if (os_strncmp(buf, "P2P_SERV_DISC_REQ ", 18) == 0) { 5286 reply_len = p2p_ctrl_serv_disc_req(wpa_s, buf + 18, reply, 5287 reply_size); 5288 } else if (os_strncmp(buf, "P2P_SERV_DISC_CANCEL_REQ ", 25) == 0) { 5289 if (p2p_ctrl_serv_disc_cancel_req(wpa_s, buf + 25) < 0) 5290 reply_len = -1; 5291 } else if (os_strncmp(buf, "P2P_SERV_DISC_RESP ", 19) == 0) { 5292 if (p2p_ctrl_serv_disc_resp(wpa_s, buf + 19) < 0) 5293 reply_len = -1; 5294 } else if (os_strcmp(buf, "P2P_SERVICE_UPDATE") == 0) { 5295 #ifdef ANDROID_P2P 5296 wpas_p2p_sd_service_update(wpa_s, SRV_UPDATE); 5297 #else 5298 wpas_p2p_sd_service_update(wpa_s); 5299 #endif 5300 } else if (os_strncmp(buf, "P2P_SERV_DISC_EXTERNAL ", 23) == 0) { 5301 if (p2p_ctrl_serv_disc_external(wpa_s, buf + 23) < 0) 5302 reply_len = -1; 5303 } else if (os_strcmp(buf, "P2P_SERVICE_FLUSH") == 0) { 5304 wpas_p2p_service_flush(wpa_s); 5305 } else if (os_strncmp(buf, "P2P_SERVICE_ADD ", 16) == 0) { 5306 if (p2p_ctrl_service_add(wpa_s, buf + 16) < 0) 5307 reply_len = -1; 5308 } else if (os_strncmp(buf, "P2P_SERVICE_DEL ", 16) == 0) { 5309 if (p2p_ctrl_service_del(wpa_s, buf + 16) < 0) 5310 reply_len = -1; 5311 } else if (os_strncmp(buf, "P2P_REJECT ", 11) == 0) { 5312 if (p2p_ctrl_reject(wpa_s, buf + 11) < 0) 5313 reply_len = -1; 5314 } else if (os_strncmp(buf, "P2P_INVITE ", 11) == 0) { 5315 if (p2p_ctrl_invite(wpa_s, buf + 11) < 0) 5316 reply_len = -1; 5317 } else if (os_strncmp(buf, "P2P_PEER ", 9) == 0) { 5318 reply_len = p2p_ctrl_peer(wpa_s, buf + 9, reply, 5319 reply_size); 5320 } else if (os_strncmp(buf, "P2P_SET ", 8) == 0) { 5321 if (p2p_ctrl_set(wpa_s, buf + 8) < 0) 5322 reply_len = -1; 5323 } else if (os_strcmp(buf, "P2P_FLUSH") == 0) { 5324 p2p_ctrl_flush(wpa_s); 5325 } else if (os_strncmp(buf, "P2P_UNAUTHORIZE ", 16) == 0) { 5326 if (wpas_p2p_unauthorize(wpa_s, buf + 16) < 0) 5327 reply_len = -1; 5328 } else if (os_strcmp(buf, "P2P_CANCEL") == 0) { 5329 if (wpas_p2p_cancel(wpa_s)) 5330 reply_len = -1; 5331 } else if (os_strncmp(buf, "P2P_PRESENCE_REQ ", 17) == 0) { 5332 if (p2p_ctrl_presence_req(wpa_s, buf + 17) < 0) 5333 reply_len = -1; 5334 } else if (os_strcmp(buf, "P2P_PRESENCE_REQ") == 0) { 5335 if (p2p_ctrl_presence_req(wpa_s, "") < 0) 5336 reply_len = -1; 5337 } else if (os_strncmp(buf, "P2P_EXT_LISTEN ", 15) == 0) { 5338 if (p2p_ctrl_ext_listen(wpa_s, buf + 15) < 0) 5339 reply_len = -1; 5340 } else if (os_strcmp(buf, "P2P_EXT_LISTEN") == 0) { 5341 if (p2p_ctrl_ext_listen(wpa_s, "") < 0) 5342 reply_len = -1; 5343 #endif /* CONFIG_P2P */ 5344 #ifdef CONFIG_WIFI_DISPLAY 5345 } else if (os_strncmp(buf, "WFD_SUBELEM_SET ", 16) == 0) { 5346 if (wifi_display_subelem_set(wpa_s->global, buf + 16) < 0) 5347 reply_len = -1; 5348 } else if (os_strncmp(buf, "WFD_SUBELEM_GET ", 16) == 0) { 5349 reply_len = wifi_display_subelem_get(wpa_s->global, buf + 16, 5350 reply, reply_size); 5351 #endif /* CONFIG_WIFI_DISPLAY */ 5352 #ifdef CONFIG_INTERWORKING 5353 } else if (os_strcmp(buf, "FETCH_ANQP") == 0) { 5354 if (interworking_fetch_anqp(wpa_s) < 0) 5355 reply_len = -1; 5356 } else if (os_strcmp(buf, "STOP_FETCH_ANQP") == 0) { 5357 interworking_stop_fetch_anqp(wpa_s); 5358 } else if (os_strncmp(buf, "INTERWORKING_SELECT", 19) == 0) { 5359 if (interworking_select(wpa_s, os_strstr(buf + 19, "auto") != 5360 NULL) < 0) 5361 reply_len = -1; 5362 } else if (os_strncmp(buf, "INTERWORKING_CONNECT ", 21) == 0) { 5363 if (ctrl_interworking_connect(wpa_s, buf + 21) < 0) 5364 reply_len = -1; 5365 } else if (os_strncmp(buf, "ANQP_GET ", 9) == 0) { 5366 if (get_anqp(wpa_s, buf + 9) < 0) 5367 reply_len = -1; 5368 } else if (os_strncmp(buf, "GAS_REQUEST ", 12) == 0) { 5369 if (gas_request(wpa_s, buf + 12) < 0) 5370 reply_len = -1; 5371 } else if (os_strncmp(buf, "GAS_RESPONSE_GET ", 17) == 0) { 5372 reply_len = gas_response_get(wpa_s, buf + 17, reply, 5373 reply_size); 5374 #endif /* CONFIG_INTERWORKING */ 5375 #ifdef CONFIG_HS20 5376 } else if (os_strncmp(buf, "HS20_ANQP_GET ", 14) == 0) { 5377 if (get_hs20_anqp(wpa_s, buf + 14) < 0) 5378 reply_len = -1; 5379 } else if (os_strncmp(buf, "HS20_GET_NAI_HOME_REALM_LIST ", 29) == 0) { 5380 if (hs20_get_nai_home_realm_list(wpa_s, buf + 29) < 0) 5381 reply_len = -1; 5382 #endif /* CONFIG_HS20 */ 5383 } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0) 5384 { 5385 if (wpa_supplicant_ctrl_iface_ctrl_rsp( 5386 wpa_s, buf + os_strlen(WPA_CTRL_RSP))) 5387 reply_len = -1; 5388 else 5389 ctrl_rsp = 1; 5390 } else if (os_strcmp(buf, "RECONFIGURE") == 0) { 5391 if (wpa_supplicant_reload_configuration(wpa_s)) 5392 reply_len = -1; 5393 } else if (os_strcmp(buf, "TERMINATE") == 0) { 5394 wpa_supplicant_terminate_proc(wpa_s->global); 5395 } else if (os_strncmp(buf, "BSSID ", 6) == 0) { 5396 if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6)) 5397 reply_len = -1; 5398 } else if (os_strncmp(buf, "BLACKLIST", 9) == 0) { 5399 reply_len = wpa_supplicant_ctrl_iface_blacklist( 5400 wpa_s, buf + 9, reply, reply_size); 5401 } else if (os_strncmp(buf, "LOG_LEVEL", 9) == 0) { 5402 reply_len = wpa_supplicant_ctrl_iface_log_level( 5403 wpa_s, buf + 9, reply, reply_size); 5404 } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) { 5405 reply_len = wpa_supplicant_ctrl_iface_list_networks( 5406 wpa_s, reply, reply_size); 5407 } else if (os_strcmp(buf, "DISCONNECT") == 0) { 5408 #ifdef CONFIG_SME 5409 wpa_s->sme.prev_bssid_set = 0; 5410 #endif /* CONFIG_SME */ 5411 wpa_s->reassociate = 0; 5412 wpa_s->disconnected = 1; 5413 wpa_supplicant_cancel_sched_scan(wpa_s); 5414 wpa_supplicant_cancel_scan(wpa_s); 5415 wpa_supplicant_deauthenticate(wpa_s, 5416 WLAN_REASON_DEAUTH_LEAVING); 5417 } else if (os_strcmp(buf, "SCAN") == 0 || 5418 os_strncmp(buf, "SCAN ", 5) == 0) { 5419 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) 5420 reply_len = -1; 5421 else { 5422 if (os_strlen(buf) > 4 && 5423 os_strncasecmp(buf + 5, "TYPE=ONLY", 9) == 0) 5424 wpa_s->scan_res_handler = scan_only_handler; 5425 if (!wpa_s->sched_scanning && !wpa_s->scanning && 5426 ((wpa_s->wpa_state <= WPA_SCANNING) || 5427 (wpa_s->wpa_state == WPA_COMPLETED))) { 5428 wpa_s->normal_scans = 0; 5429 wpa_s->scan_req = MANUAL_SCAN_REQ; 5430 wpa_supplicant_req_scan(wpa_s, 0, 0); 5431 } else if (wpa_s->sched_scanning) { 5432 wpa_printf(MSG_DEBUG, "Stop ongoing " 5433 "sched_scan to allow requested " 5434 "full scan to proceed"); 5435 wpa_supplicant_cancel_sched_scan(wpa_s); 5436 wpa_s->scan_req = MANUAL_SCAN_REQ; 5437 wpa_supplicant_req_scan(wpa_s, 0, 0); 5438 } else { 5439 wpa_printf(MSG_DEBUG, "Ongoing scan action - " 5440 "reject new request"); 5441 reply_len = os_snprintf(reply, reply_size, 5442 "FAIL-BUSY\n"); 5443 } 5444 } 5445 } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) { 5446 reply_len = wpa_supplicant_ctrl_iface_scan_results( 5447 wpa_s, reply, reply_size); 5448 } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) { 5449 if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15)) 5450 reply_len = -1; 5451 } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) { 5452 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15)) 5453 reply_len = -1; 5454 } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) { 5455 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16)) 5456 reply_len = -1; 5457 } else if (os_strcmp(buf, "ADD_NETWORK") == 0) { 5458 reply_len = wpa_supplicant_ctrl_iface_add_network( 5459 wpa_s, reply, reply_size); 5460 } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) { 5461 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15)) 5462 reply_len = -1; 5463 } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) { 5464 if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12)) 5465 reply_len = -1; 5466 } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) { 5467 reply_len = wpa_supplicant_ctrl_iface_get_network( 5468 wpa_s, buf + 12, reply, reply_size); 5469 } else if (os_strcmp(buf, "LIST_CREDS") == 0) { 5470 reply_len = wpa_supplicant_ctrl_iface_list_creds( 5471 wpa_s, reply, reply_size); 5472 } else if (os_strcmp(buf, "ADD_CRED") == 0) { 5473 reply_len = wpa_supplicant_ctrl_iface_add_cred( 5474 wpa_s, reply, reply_size); 5475 } else if (os_strncmp(buf, "REMOVE_CRED ", 12) == 0) { 5476 if (wpa_supplicant_ctrl_iface_remove_cred(wpa_s, buf + 12)) 5477 reply_len = -1; 5478 } else if (os_strncmp(buf, "SET_CRED ", 9) == 0) { 5479 if (wpa_supplicant_ctrl_iface_set_cred(wpa_s, buf + 9)) 5480 reply_len = -1; 5481 #ifndef CONFIG_NO_CONFIG_WRITE 5482 } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) { 5483 if (wpa_supplicant_ctrl_iface_save_config(wpa_s)) 5484 reply_len = -1; 5485 #endif /* CONFIG_NO_CONFIG_WRITE */ 5486 } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) { 5487 reply_len = wpa_supplicant_ctrl_iface_get_capability( 5488 wpa_s, buf + 15, reply, reply_size); 5489 } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) { 5490 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8)) 5491 reply_len = -1; 5492 } else if (os_strncmp(buf, "SCAN_INTERVAL ", 14) == 0) { 5493 if (wpa_supplicant_ctrl_iface_scan_interval(wpa_s, buf + 14)) 5494 reply_len = -1; 5495 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) { 5496 reply_len = wpa_supplicant_global_iface_list( 5497 wpa_s->global, reply, reply_size); 5498 } else if (os_strcmp(buf, "INTERFACES") == 0) { 5499 reply_len = wpa_supplicant_global_iface_interfaces( 5500 wpa_s->global, reply, reply_size); 5501 } else if (os_strncmp(buf, "BSS ", 4) == 0) { 5502 reply_len = wpa_supplicant_ctrl_iface_bss( 5503 wpa_s, buf + 4, reply, reply_size); 5504 #ifdef CONFIG_AP 5505 } else if (os_strcmp(buf, "STA-FIRST") == 0) { 5506 reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); 5507 } else if (os_strncmp(buf, "STA ", 4) == 0) { 5508 reply_len = ap_ctrl_iface_sta(wpa_s, buf + 4, reply, 5509 reply_size); 5510 } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { 5511 reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, 5512 reply_size); 5513 } else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) { 5514 if (ap_ctrl_iface_sta_deauthenticate(wpa_s, buf + 15)) 5515 reply_len = -1; 5516 } else if (os_strncmp(buf, "DISASSOCIATE ", 13) == 0) { 5517 if (ap_ctrl_iface_sta_disassociate(wpa_s, buf + 13)) 5518 reply_len = -1; 5519 #endif /* CONFIG_AP */ 5520 } else if (os_strcmp(buf, "SUSPEND") == 0) { 5521 wpas_notify_suspend(wpa_s->global); 5522 } else if (os_strcmp(buf, "RESUME") == 0) { 5523 wpas_notify_resume(wpa_s->global); 5524 } else if (os_strcmp(buf, "DROP_SA") == 0) { 5525 wpa_supplicant_ctrl_iface_drop_sa(wpa_s); 5526 } else if (os_strncmp(buf, "ROAM ", 5) == 0) { 5527 if (wpa_supplicant_ctrl_iface_roam(wpa_s, buf + 5)) 5528 reply_len = -1; 5529 } else if (os_strncmp(buf, "STA_AUTOCONNECT ", 16) == 0) { 5530 if (wpa_supplicant_ctrl_iface_sta_autoconnect(wpa_s, buf + 16)) 5531 reply_len = -1; 5532 } else if (os_strncmp(buf, "BSS_EXPIRE_AGE ", 15) == 0) { 5533 if (wpa_supplicant_ctrl_iface_bss_expire_age(wpa_s, buf + 15)) 5534 reply_len = -1; 5535 } else if (os_strncmp(buf, "BSS_EXPIRE_COUNT ", 17) == 0) { 5536 if (wpa_supplicant_ctrl_iface_bss_expire_count(wpa_s, 5537 buf + 17)) 5538 reply_len = -1; 5539 } else if (os_strncmp(buf, "BSS_FLUSH ", 10) == 0) { 5540 if (wpa_supplicant_ctrl_iface_bss_flush(wpa_s, buf + 10)) 5541 reply_len = -1; 5542 #ifdef CONFIG_TDLS 5543 } else if (os_strncmp(buf, "TDLS_DISCOVER ", 14) == 0) { 5544 if (wpa_supplicant_ctrl_iface_tdls_discover(wpa_s, buf + 14)) 5545 reply_len = -1; 5546 } else if (os_strncmp(buf, "TDLS_SETUP ", 11) == 0) { 5547 if (wpa_supplicant_ctrl_iface_tdls_setup(wpa_s, buf + 11)) 5548 reply_len = -1; 5549 } else if (os_strncmp(buf, "TDLS_TEARDOWN ", 14) == 0) { 5550 if (wpa_supplicant_ctrl_iface_tdls_teardown(wpa_s, buf + 14)) 5551 reply_len = -1; 5552 #endif /* CONFIG_TDLS */ 5553 } else if (os_strncmp(buf, "SIGNAL_POLL", 11) == 0) { 5554 reply_len = wpa_supplicant_signal_poll(wpa_s, reply, 5555 reply_size); 5556 } else if (os_strncmp(buf, "PKTCNT_POLL", 11) == 0) { 5557 reply_len = wpa_supplicant_pktcnt_poll(wpa_s, reply, 5558 reply_size); 5559 #ifdef CONFIG_AUTOSCAN 5560 } else if (os_strncmp(buf, "AUTOSCAN ", 9) == 0) { 5561 if (wpa_supplicant_ctrl_iface_autoscan(wpa_s, buf + 9)) 5562 reply_len = -1; 5563 #endif /* CONFIG_AUTOSCAN */ 5564 #ifdef ANDROID 5565 } else if (os_strncmp(buf, "DRIVER ", 7) == 0) { 5566 reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply, 5567 reply_size); 5568 #endif 5569 } else if (os_strcmp(buf, "REAUTHENTICATE") == 0) { 5570 pmksa_cache_clear_current(wpa_s->wpa); 5571 eapol_sm_request_reauth(wpa_s->eapol); 5572 #ifdef CONFIG_WNM 5573 } else if (os_strncmp(buf, "WNM_SLEEP ", 10) == 0) { 5574 if (wpas_ctrl_iface_wnm_sleep(wpa_s, buf + 10)) 5575 reply_len = -1; 5576 #endif /* CONFIG_WNM */ 5577 } else if (os_strcmp(buf, "FLUSH") == 0) { 5578 wpa_supplicant_ctrl_iface_flush(wpa_s); 5579 } else { 5580 os_memcpy(reply, "UNKNOWN COMMAND\n", 16); 5581 reply_len = 16; 5582 } 5583 5584 if (reply_len < 0) { 5585 os_memcpy(reply, "FAIL\n", 5); 5586 reply_len = 5; 5587 } 5588 5589 if (ctrl_rsp) 5590 eapol_sm_notify_ctrl_response(wpa_s->eapol); 5591 5592 *resp_len = reply_len; 5593 return reply; 5594 } 5595 5596 5597 static int wpa_supplicant_global_iface_add(struct wpa_global *global, 5598 char *cmd) 5599 { 5600 struct wpa_interface iface; 5601 char *pos; 5602 5603 /* 5604 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param> 5605 * TAB<bridge_ifname> 5606 */ 5607 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd); 5608 5609 os_memset(&iface, 0, sizeof(iface)); 5610 5611 do { 5612 iface.ifname = pos = cmd; 5613 pos = os_strchr(pos, '\t'); 5614 if (pos) 5615 *pos++ = '\0'; 5616 if (iface.ifname[0] == '\0') 5617 return -1; 5618 if (pos == NULL) 5619 break; 5620 5621 iface.confname = pos; 5622 pos = os_strchr(pos, '\t'); 5623 if (pos) 5624 *pos++ = '\0'; 5625 if (iface.confname[0] == '\0') 5626 iface.confname = NULL; 5627 if (pos == NULL) 5628 break; 5629 5630 iface.driver = pos; 5631 pos = os_strchr(pos, '\t'); 5632 if (pos) 5633 *pos++ = '\0'; 5634 if (iface.driver[0] == '\0') 5635 iface.driver = NULL; 5636 if (pos == NULL) 5637 break; 5638 5639 iface.ctrl_interface = pos; 5640 pos = os_strchr(pos, '\t'); 5641 if (pos) 5642 *pos++ = '\0'; 5643 if (iface.ctrl_interface[0] == '\0') 5644 iface.ctrl_interface = NULL; 5645 if (pos == NULL) 5646 break; 5647 5648 iface.driver_param = pos; 5649 pos = os_strchr(pos, '\t'); 5650 if (pos) 5651 *pos++ = '\0'; 5652 if (iface.driver_param[0] == '\0') 5653 iface.driver_param = NULL; 5654 if (pos == NULL) 5655 break; 5656 5657 iface.bridge_ifname = pos; 5658 pos = os_strchr(pos, '\t'); 5659 if (pos) 5660 *pos++ = '\0'; 5661 if (iface.bridge_ifname[0] == '\0') 5662 iface.bridge_ifname = NULL; 5663 if (pos == NULL) 5664 break; 5665 } while (0); 5666 5667 if (wpa_supplicant_get_iface(global, iface.ifname)) 5668 return -1; 5669 5670 return wpa_supplicant_add_iface(global, &iface) ? 0 : -1; 5671 } 5672 5673 5674 static int wpa_supplicant_global_iface_remove(struct wpa_global *global, 5675 char *cmd) 5676 { 5677 struct wpa_supplicant *wpa_s; 5678 5679 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd); 5680 5681 wpa_s = wpa_supplicant_get_iface(global, cmd); 5682 if (wpa_s == NULL) 5683 return -1; 5684 return wpa_supplicant_remove_iface(global, wpa_s, 0); 5685 } 5686 5687 5688 static void wpa_free_iface_info(struct wpa_interface_info *iface) 5689 { 5690 struct wpa_interface_info *prev; 5691 5692 while (iface) { 5693 prev = iface; 5694 iface = iface->next; 5695 5696 os_free(prev->ifname); 5697 os_free(prev->desc); 5698 os_free(prev); 5699 } 5700 } 5701 5702 5703 static int wpa_supplicant_global_iface_list(struct wpa_global *global, 5704 char *buf, int len) 5705 { 5706 int i, res; 5707 struct wpa_interface_info *iface = NULL, *last = NULL, *tmp; 5708 char *pos, *end; 5709 5710 for (i = 0; wpa_drivers[i]; i++) { 5711 struct wpa_driver_ops *drv = wpa_drivers[i]; 5712 if (drv->get_interfaces == NULL) 5713 continue; 5714 tmp = drv->get_interfaces(global->drv_priv[i]); 5715 if (tmp == NULL) 5716 continue; 5717 5718 if (last == NULL) 5719 iface = last = tmp; 5720 else 5721 last->next = tmp; 5722 while (last->next) 5723 last = last->next; 5724 } 5725 5726 pos = buf; 5727 end = buf + len; 5728 for (tmp = iface; tmp; tmp = tmp->next) { 5729 res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n", 5730 tmp->drv_name, tmp->ifname, 5731 tmp->desc ? tmp->desc : ""); 5732 if (res < 0 || res >= end - pos) { 5733 *pos = '\0'; 5734 break; 5735 } 5736 pos += res; 5737 } 5738 5739 wpa_free_iface_info(iface); 5740 5741 return pos - buf; 5742 } 5743 5744 5745 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global, 5746 char *buf, int len) 5747 { 5748 int res; 5749 char *pos, *end; 5750 struct wpa_supplicant *wpa_s; 5751 5752 wpa_s = global->ifaces; 5753 pos = buf; 5754 end = buf + len; 5755 5756 while (wpa_s) { 5757 res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname); 5758 if (res < 0 || res >= end - pos) { 5759 *pos = '\0'; 5760 break; 5761 } 5762 pos += res; 5763 wpa_s = wpa_s->next; 5764 } 5765 return pos - buf; 5766 } 5767 5768 5769 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global, 5770 char *buf, size_t *resp_len) 5771 { 5772 char *reply; 5773 const int reply_size = 2048; 5774 int reply_len; 5775 int level = MSG_DEBUG; 5776 5777 if (os_strcmp(buf, "PING") == 0) 5778 level = MSG_EXCESSIVE; 5779 wpa_hexdump_ascii(level, "RX global ctrl_iface", 5780 (const u8 *) buf, os_strlen(buf)); 5781 5782 reply = os_malloc(reply_size); 5783 if (reply == NULL) { 5784 *resp_len = 1; 5785 return NULL; 5786 } 5787 5788 os_memcpy(reply, "OK\n", 3); 5789 reply_len = 3; 5790 5791 if (os_strcmp(buf, "PING") == 0) { 5792 os_memcpy(reply, "PONG\n", 5); 5793 reply_len = 5; 5794 } else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) { 5795 if (wpa_supplicant_global_iface_add(global, buf + 14)) 5796 reply_len = -1; 5797 } else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) { 5798 if (wpa_supplicant_global_iface_remove(global, buf + 17)) 5799 reply_len = -1; 5800 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) { 5801 reply_len = wpa_supplicant_global_iface_list( 5802 global, reply, reply_size); 5803 } else if (os_strcmp(buf, "INTERFACES") == 0) { 5804 reply_len = wpa_supplicant_global_iface_interfaces( 5805 global, reply, reply_size); 5806 } else if (os_strcmp(buf, "TERMINATE") == 0) { 5807 wpa_supplicant_terminate_proc(global); 5808 } else if (os_strcmp(buf, "SUSPEND") == 0) { 5809 wpas_notify_suspend(global); 5810 } else if (os_strcmp(buf, "RESUME") == 0) { 5811 wpas_notify_resume(global); 5812 } else { 5813 os_memcpy(reply, "UNKNOWN COMMAND\n", 16); 5814 reply_len = 16; 5815 } 5816 5817 if (reply_len < 0) { 5818 os_memcpy(reply, "FAIL\n", 5); 5819 reply_len = 5; 5820 } 5821 5822 *resp_len = reply_len; 5823 return reply; 5824 } 5825