1 /* 2 * WPA Supplicant / Control interface (shared code for all backends) 3 * Copyright (c) 2004-2008, Jouni Malinen <j (at) w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15 #include "includes.h" 16 17 #include "common.h" 18 #include "eloop.h" 19 #include "wpa.h" 20 #include "config.h" 21 #include "eapol_supp/eapol_supp_sm.h" 22 #include "wpa_supplicant_i.h" 23 #include "blacklist.h" 24 #include "ctrl_iface.h" 25 #include "l2_packet/l2_packet.h" 26 #include "preauth.h" 27 #include "pmksa_cache.h" 28 #include "wpa_ctrl.h" 29 #include "eap_peer/eap.h" 30 #include "ieee802_11_defs.h" 31 #include "wps_supplicant.h" 32 #include "wps/wps.h" 33 34 static int wpa_supplicant_global_iface_list(struct wpa_global *global, 35 char *buf, int len); 36 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global, 37 char *buf, int len); 38 39 40 static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s, 41 char *cmd) 42 { 43 char *value; 44 int ret = 0; 45 46 value = os_strchr(cmd, ' '); 47 if (value == NULL) 48 return -1; 49 *value++ = '\0'; 50 51 wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value); 52 if (os_strcasecmp(cmd, "EAPOL::heldPeriod") == 0) { 53 eapol_sm_configure(wpa_s->eapol, 54 atoi(value), -1, -1, -1); 55 } else if (os_strcasecmp(cmd, "EAPOL::authPeriod") == 0) { 56 eapol_sm_configure(wpa_s->eapol, 57 -1, atoi(value), -1, -1); 58 } else if (os_strcasecmp(cmd, "EAPOL::startPeriod") == 0) { 59 eapol_sm_configure(wpa_s->eapol, 60 -1, -1, atoi(value), -1); 61 } else if (os_strcasecmp(cmd, "EAPOL::maxStart") == 0) { 62 eapol_sm_configure(wpa_s->eapol, 63 -1, -1, -1, atoi(value)); 64 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) { 65 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME, 66 atoi(value))) 67 ret = -1; 68 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") == 69 0) { 70 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD, 71 atoi(value))) 72 ret = -1; 73 } else if (os_strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) { 74 if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value))) 75 ret = -1; 76 } else 77 ret = -1; 78 79 return ret; 80 } 81 82 83 #ifdef IEEE8021X_EAPOL 84 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s, 85 char *addr) 86 { 87 u8 bssid[ETH_ALEN]; 88 struct wpa_ssid *ssid = wpa_s->current_ssid; 89 90 if (hwaddr_aton(addr, bssid)) { 91 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address " 92 "'%s'", addr); 93 return -1; 94 } 95 96 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid)); 97 rsn_preauth_deinit(wpa_s->wpa); 98 if (rsn_preauth_init(wpa_s->wpa, bssid, ssid ? &ssid->eap : NULL)) 99 return -1; 100 101 return 0; 102 } 103 #endif /* IEEE8021X_EAPOL */ 104 105 106 #ifdef CONFIG_PEERKEY 107 /* MLME-STKSTART.request(peer) */ 108 static int wpa_supplicant_ctrl_iface_stkstart( 109 struct wpa_supplicant *wpa_s, char *addr) 110 { 111 u8 peer[ETH_ALEN]; 112 113 if (hwaddr_aton(addr, peer)) { 114 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid " 115 "address '%s'", peer); 116 return -1; 117 } 118 119 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART " MACSTR, 120 MAC2STR(peer)); 121 122 return wpa_sm_stkstart(wpa_s->wpa, peer); 123 } 124 #endif /* CONFIG_PEERKEY */ 125 126 127 #ifdef CONFIG_IEEE80211R 128 static int wpa_supplicant_ctrl_iface_ft_ds( 129 struct wpa_supplicant *wpa_s, char *addr) 130 { 131 u8 target_ap[ETH_ALEN]; 132 133 if (hwaddr_aton(addr, target_ap)) { 134 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS: invalid " 135 "address '%s'", target_ap); 136 return -1; 137 } 138 139 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS " MACSTR, MAC2STR(target_ap)); 140 141 return wpa_ft_start_over_ds(wpa_s->wpa, target_ap); 142 } 143 #endif /* CONFIG_IEEE80211R */ 144 145 146 #ifdef CONFIG_WPS 147 static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s, 148 char *cmd) 149 { 150 u8 bssid[ETH_ALEN]; 151 152 if (cmd == NULL || os_strcmp(cmd, "any") == 0) 153 return wpas_wps_start_pbc(wpa_s, NULL); 154 155 if (hwaddr_aton(cmd, bssid)) { 156 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'", 157 cmd); 158 return -1; 159 } 160 161 return wpas_wps_start_pbc(wpa_s, bssid); 162 } 163 164 165 static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s, 166 char *cmd, char *buf, 167 size_t buflen) 168 { 169 u8 bssid[ETH_ALEN], *_bssid = bssid; 170 char *pin; 171 int ret; 172 173 pin = os_strchr(cmd, ' '); 174 if (pin) 175 *pin++ = '\0'; 176 177 if (os_strcmp(cmd, "any") == 0) 178 _bssid = NULL; 179 else if (hwaddr_aton(cmd, bssid)) { 180 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'", 181 cmd); 182 return -1; 183 } 184 185 if (pin) { 186 ret = wpas_wps_start_pin(wpa_s, _bssid, pin); 187 if (ret < 0) 188 return -1; 189 ret = os_snprintf(buf, buflen, "%s", pin); 190 if (ret < 0 || (size_t) ret >= buflen) 191 return -1; 192 return ret; 193 } 194 195 ret = wpas_wps_start_pin(wpa_s, _bssid, NULL); 196 if (ret < 0) 197 return -1; 198 199 /* Return the generated PIN */ 200 ret = os_snprintf(buf, buflen, "%08d", ret); 201 if (ret < 0 || (size_t) ret >= buflen) 202 return -1; 203 return ret; 204 } 205 206 207 static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s, 208 char *cmd) 209 { 210 u8 bssid[ETH_ALEN], *_bssid = bssid; 211 char *pin; 212 213 pin = os_strchr(cmd, ' '); 214 if (pin == NULL) 215 return -1; 216 *pin++ = '\0'; 217 218 if (os_strcmp(cmd, "any") == 0) 219 _bssid = NULL; 220 else if (hwaddr_aton(cmd, bssid)) { 221 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_REG: invalid BSSID '%s'", 222 cmd); 223 return -1; 224 } 225 226 return wpas_wps_start_reg(wpa_s, _bssid, pin); 227 } 228 #endif /* CONFIG_WPS */ 229 230 231 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s, 232 char *rsp) 233 { 234 #ifdef IEEE8021X_EAPOL 235 char *pos, *id_pos; 236 int id; 237 struct wpa_ssid *ssid; 238 struct eap_peer_config *eap; 239 240 pos = os_strchr(rsp, '-'); 241 if (pos == NULL) 242 return -1; 243 *pos++ = '\0'; 244 id_pos = pos; 245 pos = os_strchr(pos, ':'); 246 if (pos == NULL) 247 return -1; 248 *pos++ = '\0'; 249 id = atoi(id_pos); 250 wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id); 251 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value", 252 (u8 *) pos, os_strlen(pos)); 253 254 ssid = wpa_config_get_network(wpa_s->conf, id); 255 if (ssid == NULL) { 256 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 257 "to update", id); 258 return -1; 259 } 260 eap = &ssid->eap; 261 262 if (os_strcmp(rsp, "IDENTITY") == 0) { 263 os_free(eap->identity); 264 eap->identity = (u8 *) os_strdup(pos); 265 eap->identity_len = os_strlen(pos); 266 eap->pending_req_identity = 0; 267 if (ssid == wpa_s->current_ssid) 268 wpa_s->reassociate = 1; 269 } else if (os_strcmp(rsp, "PASSWORD") == 0) { 270 os_free(eap->password); 271 eap->password = (u8 *) os_strdup(pos); 272 eap->password_len = os_strlen(pos); 273 eap->pending_req_password = 0; 274 if (ssid == wpa_s->current_ssid) 275 wpa_s->reassociate = 1; 276 } else if (os_strcmp(rsp, "NEW_PASSWORD") == 0) { 277 os_free(eap->new_password); 278 eap->new_password = (u8 *) os_strdup(pos); 279 eap->new_password_len = os_strlen(pos); 280 eap->pending_req_new_password = 0; 281 if (ssid == wpa_s->current_ssid) 282 wpa_s->reassociate = 1; 283 } else if (os_strcmp(rsp, "PIN") == 0) { 284 os_free(eap->pin); 285 eap->pin = os_strdup(pos); 286 eap->pending_req_pin = 0; 287 if (ssid == wpa_s->current_ssid) 288 wpa_s->reassociate = 1; 289 } else if (os_strcmp(rsp, "OTP") == 0) { 290 os_free(eap->otp); 291 eap->otp = (u8 *) os_strdup(pos); 292 eap->otp_len = os_strlen(pos); 293 os_free(eap->pending_req_otp); 294 eap->pending_req_otp = NULL; 295 eap->pending_req_otp_len = 0; 296 } else if (os_strcmp(rsp, "PASSPHRASE") == 0) { 297 os_free(eap->private_key_passwd); 298 eap->private_key_passwd = (u8 *) os_strdup(pos); 299 eap->pending_req_passphrase = 0; 300 if (ssid == wpa_s->current_ssid) 301 wpa_s->reassociate = 1; 302 } else { 303 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", rsp); 304 return -1; 305 } 306 307 return 0; 308 #else /* IEEE8021X_EAPOL */ 309 wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included"); 310 return -1; 311 #endif /* IEEE8021X_EAPOL */ 312 } 313 314 315 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, 316 const char *params, 317 char *buf, size_t buflen) 318 { 319 char *pos, *end, tmp[30]; 320 int res, verbose, ret; 321 322 verbose = os_strcmp(params, "-VERBOSE") == 0; 323 pos = buf; 324 end = buf + buflen; 325 if (wpa_s->wpa_state >= WPA_ASSOCIATED) { 326 struct wpa_ssid *ssid = wpa_s->current_ssid; 327 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n", 328 MAC2STR(wpa_s->bssid)); 329 if (ret < 0 || ret >= end - pos) 330 return pos - buf; 331 pos += ret; 332 if (ssid) { 333 u8 *_ssid = ssid->ssid; 334 size_t ssid_len = ssid->ssid_len; 335 u8 ssid_buf[MAX_SSID_LEN]; 336 if (ssid_len == 0) { 337 int _res = wpa_drv_get_ssid(wpa_s, ssid_buf); 338 if (_res < 0) 339 ssid_len = 0; 340 else 341 ssid_len = _res; 342 _ssid = ssid_buf; 343 } 344 ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n", 345 wpa_ssid_txt(_ssid, ssid_len), 346 ssid->id); 347 if (ret < 0 || ret >= end - pos) 348 return pos - buf; 349 pos += ret; 350 351 if (ssid->id_str) { 352 ret = os_snprintf(pos, end - pos, 353 "id_str=%s\n", 354 ssid->id_str); 355 if (ret < 0 || ret >= end - pos) 356 return pos - buf; 357 pos += ret; 358 } 359 } 360 361 pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose); 362 } 363 ret = os_snprintf(pos, end - pos, "wpa_state=%s\n", 364 wpa_supplicant_state_txt(wpa_s->wpa_state)); 365 if (ret < 0 || ret >= end - pos) 366 return pos - buf; 367 pos += ret; 368 369 if (wpa_s->l2 && 370 l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) { 371 ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp); 372 if (ret < 0 || ret >= end - pos) 373 return pos - buf; 374 pos += ret; 375 } 376 377 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) || 378 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) { 379 res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos, 380 verbose); 381 if (res >= 0) 382 pos += res; 383 } 384 385 res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose); 386 if (res >= 0) 387 pos += res; 388 389 return pos - buf; 390 } 391 392 393 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s, 394 char *cmd) 395 { 396 char *pos; 397 int id; 398 struct wpa_ssid *ssid; 399 u8 bssid[ETH_ALEN]; 400 401 /* cmd: "<network id> <BSSID>" */ 402 pos = os_strchr(cmd, ' '); 403 if (pos == NULL) 404 return -1; 405 *pos++ = '\0'; 406 id = atoi(cmd); 407 wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos); 408 if (hwaddr_aton(pos, bssid)) { 409 wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos); 410 return -1; 411 } 412 413 ssid = wpa_config_get_network(wpa_s->conf, id); 414 if (ssid == NULL) { 415 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " 416 "to update", id); 417 return -1; 418 } 419 420 os_memcpy(ssid->bssid, bssid, ETH_ALEN); 421 ssid->bssid_set = !is_zero_ether_addr(bssid); 422 423 return 0; 424 } 425 426 #ifdef ANDROID 427 static int wpa_supplicant_ctrl_iface_scan_interval( 428 struct wpa_supplicant *wpa_s, char *cmd) 429 { 430 int scan_int = atoi(cmd); 431 if (scan_int < 0) 432 return -1; 433 wpa_s->scan_interval = scan_int; 434 return 0; 435 } 436 437 438 static int wpa_supplicant_ctrl_iface_blacklist( 439 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) 440 { 441 u8 bssid[ETH_ALEN]; 442 struct wpa_blacklist *e; 443 char *pos, *end; 444 int ret; 445 446 /* cmd: "BLACKLIST [<BSSID>]" */ 447 if (*cmd == '\0') { 448 pos = buf; 449 end = buf + buflen; 450 451 e = wpa_s->blacklist; 452 while (e) { 453 ret = os_snprintf(pos, end-pos, MACSTR"\n", MAC2STR(e->bssid)); 454 if (ret < 0 || ret >= end - pos) 455 return pos - buf; 456 pos += ret; 457 e = e->next; 458 } 459 return pos - buf; 460 } 461 462 ++cmd; 463 if (os_strncmp(cmd, "clear", 5) == 0) { 464 wpa_blacklist_clear(wpa_s); 465 os_memcpy(buf, "OK\n", 3); 466 return 3; 467 } 468 469 wpa_printf(MSG_DEBUG, "CTRL_IFACE: BLACKLIST bssid='%s'", cmd); 470 if (hwaddr_aton(cmd, bssid)) { 471 wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", cmd); 472 return -1; 473 } 474 475 /* 476 * Add the BSSID twice, so its count will be 2, causing it to be 477 * skipped when processing scan results. 478 */ 479 ret = wpa_blacklist_add(wpa_s, bssid); 480 if (ret != 0) 481 return -1; 482 ret = wpa_blacklist_add(wpa_s, bssid); 483 if (ret != 0) 484 return -1; 485 os_memcpy(buf, "OK\n", 3); 486 return 3; 487 } 488 489 490 extern int wpa_debug_level; 491 extern int wpa_debug_timestamp; 492 static int wpa_supplicant_ctrl_iface_log_level( 493 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) 494 { 495 char *pos, *end, *stamp; 496 int ret; 497 498 if (cmd == NULL) { 499 return -1; 500 } 501 502 /* cmd: "LOG_LEVEL [<level>]" */ 503 if (*cmd == '\0') { 504 pos = buf; 505 end = buf + buflen; 506 ret = os_snprintf(pos, end-pos, "Current level: %d\n" 507 "{0-MSGDUMP, 1-DEBUG, 2-INFO, 3-WARNING, 4-ERROR}\n" 508 "Timestamp: %d\n", wpa_debug_level, wpa_debug_timestamp); 509 if (ret < 0 || ret >= end - pos) 510 ret = 0; 511 512 return ret; 513 } 514 515 while (*cmd == ' ') { 516 cmd++; 517 } 518 519 stamp = os_strchr(cmd, ' '); 520 if (stamp) { 521 *stamp++ = '\0'; 522 while (*stamp == ' ') { 523 stamp++; 524 } 525 } 526 527 if (cmd && os_strlen(cmd)) { 528 wpa_debug_level = atoi(cmd); 529 } 530 531 if (stamp && os_strlen(stamp)) { 532 wpa_debug_timestamp = atoi(stamp); 533 } 534 535 os_memcpy(buf, "OK\n", 3); 536 return 3; 537 } 538 #endif 539 540 static int wpa_supplicant_ctrl_iface_list_networks( 541 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 542 { 543 char *pos, *end; 544 struct wpa_ssid *ssid; 545 int ret; 546 547 pos = buf; 548 end = buf + buflen; 549 ret = os_snprintf(pos, end - pos, 550 "network id / ssid / bssid / flags\n"); 551 if (ret < 0 || ret >= end - pos) 552 return pos - buf; 553 pos += ret; 554 555 ssid = wpa_s->conf->ssid; 556 while (ssid) { 557 ret = os_snprintf(pos, end - pos, "%d\t%s", 558 ssid->id, 559 wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 560 if (ret < 0 || ret >= end - pos) 561 return pos - buf; 562 pos += ret; 563 if (ssid->bssid_set) { 564 ret = os_snprintf(pos, end - pos, "\t" MACSTR, 565 MAC2STR(ssid->bssid)); 566 } else { 567 ret = os_snprintf(pos, end - pos, "\tany"); 568 } 569 if (ret < 0 || ret >= end - pos) 570 return pos - buf; 571 pos += ret; 572 ret = os_snprintf(pos, end - pos, "\t%s%s", 573 ssid == wpa_s->current_ssid ? 574 "[CURRENT]" : "", 575 ssid->disabled ? "[DISABLED]" : ""); 576 if (ret < 0 || ret >= end - pos) 577 return pos - buf; 578 pos += ret; 579 ret = os_snprintf(pos, end - pos, "\n"); 580 if (ret < 0 || ret >= end - pos) 581 return pos - buf; 582 pos += ret; 583 584 ssid = ssid->next; 585 } 586 587 return pos - buf; 588 } 589 590 591 static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher) 592 { 593 int first = 1, ret; 594 ret = os_snprintf(pos, end - pos, "-"); 595 if (ret < 0 || ret >= end - pos) 596 return pos; 597 pos += ret; 598 if (cipher & WPA_CIPHER_NONE) { 599 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : "+"); 600 if (ret < 0 || ret >= end - pos) 601 return pos; 602 pos += ret; 603 first = 0; 604 } 605 if (cipher & WPA_CIPHER_WEP40) { 606 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : "+"); 607 if (ret < 0 || ret >= end - pos) 608 return pos; 609 pos += ret; 610 first = 0; 611 } 612 if (cipher & WPA_CIPHER_WEP104) { 613 ret = os_snprintf(pos, end - pos, "%sWEP104", 614 first ? "" : "+"); 615 if (ret < 0 || ret >= end - pos) 616 return pos; 617 pos += ret; 618 first = 0; 619 } 620 if (cipher & WPA_CIPHER_TKIP) { 621 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : "+"); 622 if (ret < 0 || ret >= end - pos) 623 return pos; 624 pos += ret; 625 first = 0; 626 } 627 if (cipher & WPA_CIPHER_CCMP) { 628 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : "+"); 629 if (ret < 0 || ret >= end - pos) 630 return pos; 631 pos += ret; 632 first = 0; 633 } 634 return pos; 635 } 636 637 638 static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto, 639 const u8 *ie, size_t ie_len) 640 { 641 struct wpa_ie_data data; 642 int first, ret; 643 644 ret = os_snprintf(pos, end - pos, "[%s-", proto); 645 if (ret < 0 || ret >= end - pos) 646 return pos; 647 pos += ret; 648 649 if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) { 650 ret = os_snprintf(pos, end - pos, "?]"); 651 if (ret < 0 || ret >= end - pos) 652 return pos; 653 pos += ret; 654 return pos; 655 } 656 657 first = 1; 658 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) { 659 ret = os_snprintf(pos, end - pos, "%sEAP", first ? "" : "+"); 660 if (ret < 0 || ret >= end - pos) 661 return pos; 662 pos += ret; 663 first = 0; 664 } 665 if (data.key_mgmt & WPA_KEY_MGMT_PSK) { 666 ret = os_snprintf(pos, end - pos, "%sPSK", first ? "" : "+"); 667 if (ret < 0 || ret >= end - pos) 668 return pos; 669 pos += ret; 670 first = 0; 671 } 672 if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) { 673 ret = os_snprintf(pos, end - pos, "%sNone", first ? "" : "+"); 674 if (ret < 0 || ret >= end - pos) 675 return pos; 676 pos += ret; 677 first = 0; 678 } 679 #ifdef CONFIG_IEEE80211R 680 if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) { 681 ret = os_snprintf(pos, end - pos, "%sFT/EAP", 682 first ? "" : "+"); 683 if (ret < 0 || ret >= end - pos) 684 return pos; 685 pos += ret; 686 first = 0; 687 } 688 if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) { 689 ret = os_snprintf(pos, end - pos, "%sFT/PSK", 690 first ? "" : "+"); 691 if (ret < 0 || ret >= end - pos) 692 return pos; 693 pos += ret; 694 first = 0; 695 } 696 #endif /* CONFIG_IEEE80211R */ 697 #ifdef CONFIG_IEEE80211W 698 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) { 699 ret = os_snprintf(pos, end - pos, "%sEAP-SHA256", 700 first ? "" : "+"); 701 if (ret < 0 || ret >= end - pos) 702 return pos; 703 pos += ret; 704 first = 0; 705 } 706 if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) { 707 ret = os_snprintf(pos, end - pos, "%sPSK-SHA256", 708 first ? "" : "+"); 709 if (ret < 0 || ret >= end - pos) 710 return pos; 711 pos += ret; 712 first = 0; 713 } 714 #endif /* CONFIG_IEEE80211W */ 715 716 pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher); 717 718 if (data.capabilities & WPA_CAPABILITY_PREAUTH) { 719 ret = os_snprintf(pos, end - pos, "-preauth"); 720 if (ret < 0 || ret >= end - pos) 721 return pos; 722 pos += ret; 723 } 724 725 ret = os_snprintf(pos, end - pos, "]"); 726 if (ret < 0 || ret >= end - pos) 727 return pos; 728 pos += ret; 729 730 return pos; 731 } 732 733 static char * wpa_supplicant_wps_ie_txt(char *pos, char *end, 734 const struct wpa_scan_res *res) 735 { 736 #ifdef CONFIG_WPS 737 struct wpabuf *wps_ie; 738 int ret; 739 const char *txt; 740 741 wps_ie = wpa_scan_get_vendor_ie_multi(res, WPS_IE_VENDOR_TYPE); 742 if (wps_ie == NULL) 743 return pos; 744 745 if (wps_is_selected_pbc_registrar(wps_ie)) 746 txt = "[WPS-PBC]"; 747 else if (wps_is_selected_pin_registrar(wps_ie)) 748 txt = "[WPS-PIN]"; 749 else 750 txt = "[WPS]"; 751 752 ret = os_snprintf(pos, end - pos, "%s", txt); 753 if (ret >= 0 && ret < end - pos) 754 pos += ret; 755 wpabuf_free(wps_ie); 756 #endif /* CONFIG_WPS */ 757 758 return pos; 759 } 760 761 762 /* Format one result on one text line into a buffer. */ 763 static int wpa_supplicant_ctrl_iface_scan_result( 764 const struct wpa_scan_res *res, char *buf, size_t buflen) 765 { 766 char *pos, *end; 767 int ret; 768 const u8 *ie, *ie2; 769 770 pos = buf; 771 end = buf + buflen; 772 773 ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t", 774 MAC2STR(res->bssid), res->freq, res->level); 775 if (ret < 0 || ret >= end - pos) 776 return -1; 777 pos += ret; 778 ie = wpa_scan_get_vendor_ie(res, WPA_IE_VENDOR_TYPE); 779 if (ie) 780 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]); 781 ie2 = wpa_scan_get_ie(res, WLAN_EID_RSN); 782 if (ie2) 783 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]); 784 pos = wpa_supplicant_wps_ie_txt(pos, end, res); 785 if (!ie && !ie2 && res->caps & IEEE80211_CAP_PRIVACY) { 786 ret = os_snprintf(pos, end - pos, "[WEP]"); 787 if (ret < 0 || ret >= end - pos) 788 return -1; 789 pos += ret; 790 } 791 if (res->caps & IEEE80211_CAP_IBSS) { 792 ret = os_snprintf(pos, end - pos, "[IBSS]"); 793 if (ret < 0 || ret >= end - pos) 794 return -1; 795 pos += ret; 796 } 797 /* Just to make the fields line up nicely when printed */ 798 if (!ie && !ie2) { 799 ret = os_snprintf(pos, end - pos, "\t"); 800 if (ret < 0 || ret >= end - pos) 801 return -1; 802 pos += ret; 803 } 804 ie = wpa_scan_get_ie(res, WLAN_EID_SSID); 805 ret = os_snprintf(pos, end - pos, "\t%s", 806 ie ? wpa_ssid_txt(ie + 2, ie[1]) : ""); 807 if (ret < 0 || ret >= end - pos) 808 return -1; 809 pos += ret; 810 811 ret = os_snprintf(pos, end - pos, "\n"); 812 if (ret < 0 || ret >= end - pos) 813 return -1; 814 pos += ret; 815 816 return pos - buf; 817 } 818 819 820 static int wpa_supplicant_ctrl_iface_scan_results( 821 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 822 { 823 char *pos, *end; 824 struct wpa_scan_res *res; 825 int ret; 826 size_t i; 827 828 if (wpa_s->scan_res == NULL && 829 wpa_supplicant_get_scan_results(wpa_s) < 0) 830 return 0; 831 if (wpa_s->scan_res == NULL) 832 return 0; 833 834 pos = buf; 835 end = buf + buflen; 836 ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / " 837 "flags / ssid\n"); 838 if (ret < 0 || ret >= end - pos) 839 return pos - buf; 840 pos += ret; 841 842 for (i = 0; i < wpa_s->scan_res->num; i++) { 843 res = wpa_s->scan_res->res[i]; 844 ret = wpa_supplicant_ctrl_iface_scan_result(res, pos, 845 end - pos); 846 if (ret < 0 || ret >= end - pos) 847 return pos - buf; 848 pos += ret; 849 } 850 851 return pos - buf; 852 } 853 854 855 static int wpa_supplicant_ctrl_iface_select_network( 856 struct wpa_supplicant *wpa_s, char *cmd) 857 { 858 int id; 859 struct wpa_ssid *ssid; 860 861 /* cmd: "<network id>" or "any" */ 862 if (os_strcmp(cmd, "any") == 0) { 863 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any"); 864 ssid = wpa_s->conf->ssid; 865 while (ssid) { 866 ssid->disabled = 0; 867 ssid = ssid->next; 868 } 869 wpa_s->reassociate = 1; 870 wpa_supplicant_req_scan(wpa_s, 0, 0); 871 return 0; 872 } 873 874 id = atoi(cmd); 875 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id); 876 877 ssid = wpa_config_get_network(wpa_s->conf, id); 878 if (ssid == NULL) { 879 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 880 "id=%d", id); 881 return -1; 882 } 883 884 if (ssid != wpa_s->current_ssid && wpa_s->current_ssid) 885 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); 886 887 /* Mark all other networks disabled and trigger reassociation */ 888 ssid = wpa_s->conf->ssid; 889 while (ssid) { 890 ssid->disabled = id != ssid->id; 891 ssid = ssid->next; 892 } 893 wpa_s->reassociate = 1; 894 wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN; 895 wpa_supplicant_req_scan(wpa_s, 0, 0); 896 897 return 0; 898 } 899 900 901 static int wpa_supplicant_ctrl_iface_enable_network( 902 struct wpa_supplicant *wpa_s, char *cmd) 903 { 904 int id; 905 struct wpa_ssid *ssid; 906 907 /* cmd: "<network id>" or "all" */ 908 if (os_strcmp(cmd, "all") == 0) { 909 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all"); 910 ssid = wpa_s->conf->ssid; 911 while (ssid) { 912 if (ssid == wpa_s->current_ssid && ssid->disabled) 913 wpa_s->reassociate = 1; 914 ssid->disabled = 0; 915 ssid = ssid->next; 916 } 917 if (wpa_s->reassociate) 918 #ifdef ANDROID 919 wpa_supplicant_req_scan(wpa_s, 2, 0); 920 #else 921 wpa_supplicant_req_scan(wpa_s, 0, 0); 922 #endif 923 return 0; 924 } 925 926 id = atoi(cmd); 927 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id); 928 929 ssid = wpa_config_get_network(wpa_s->conf, id); 930 if (ssid == NULL) { 931 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 932 "id=%d", id); 933 return -1; 934 } 935 936 if (wpa_s->current_ssid == NULL && ssid->disabled) { 937 /* 938 * Try to reassociate since there is no current configuration 939 * and a new network was made available. */ 940 wpa_s->reassociate = 1; 941 #ifdef ANDROID 942 wpa_supplicant_req_scan(wpa_s, 2, 0); 943 #else 944 wpa_supplicant_req_scan(wpa_s, 0, 0); 945 #endif 946 } 947 ssid->disabled = 0; 948 949 return 0; 950 } 951 952 953 static int wpa_supplicant_ctrl_iface_disable_network( 954 struct wpa_supplicant *wpa_s, char *cmd) 955 { 956 int id; 957 struct wpa_ssid *ssid; 958 959 /* cmd: "<network id>" or "all" */ 960 if (os_strcmp(cmd, "all") == 0) { 961 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all"); 962 ssid = wpa_s->conf->ssid; 963 while (ssid) { 964 ssid->disabled = 1; 965 ssid = ssid->next; 966 } 967 if (wpa_s->current_ssid) 968 wpa_supplicant_disassociate(wpa_s, 969 WLAN_REASON_DEAUTH_LEAVING); 970 return 0; 971 } 972 973 id = atoi(cmd); 974 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id); 975 976 ssid = wpa_config_get_network(wpa_s->conf, id); 977 if (ssid == NULL) { 978 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 979 "id=%d", id); 980 return -1; 981 } 982 983 #ifdef ANDROID 984 if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) { 985 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not disable WPS network " 986 "id=%d", id); 987 return -1; 988 } 989 #endif 990 991 if (ssid == wpa_s->current_ssid) 992 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); 993 ssid->disabled = 1; 994 995 return 0; 996 } 997 998 999 static int wpa_supplicant_ctrl_iface_add_network( 1000 struct wpa_supplicant *wpa_s, char *buf, size_t buflen) 1001 { 1002 struct wpa_ssid *ssid; 1003 int ret; 1004 1005 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK"); 1006 1007 ssid = wpa_config_add_network(wpa_s->conf); 1008 if (ssid == NULL) 1009 return -1; 1010 ssid->disabled = 1; 1011 wpa_config_set_network_defaults(ssid); 1012 1013 ret = os_snprintf(buf, buflen, "%d\n", ssid->id); 1014 if (ret < 0 || (size_t) ret >= buflen) 1015 return -1; 1016 return ret; 1017 } 1018 1019 1020 static int wpa_supplicant_ctrl_iface_remove_network( 1021 struct wpa_supplicant *wpa_s, char *cmd) 1022 { 1023 int id; 1024 struct wpa_ssid *ssid; 1025 1026 /* cmd: "<network id>" or "all" */ 1027 if (os_strcmp(cmd, "all") == 0) { 1028 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all"); 1029 ssid = wpa_s->conf->ssid; 1030 while (ssid) { 1031 id = ssid->id; 1032 ssid = ssid->next; 1033 wpa_config_remove_network(wpa_s->conf, id); 1034 } 1035 if (wpa_s->current_ssid) { 1036 eapol_sm_invalidate_cached_session(wpa_s->eapol); 1037 wpa_supplicant_disassociate(wpa_s, 1038 WLAN_REASON_DEAUTH_LEAVING); 1039 } 1040 return 0; 1041 } 1042 1043 id = atoi(cmd); 1044 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id); 1045 1046 ssid = wpa_config_get_network(wpa_s->conf, id); 1047 if (ssid == NULL || 1048 wpa_config_remove_network(wpa_s->conf, id) < 0) { 1049 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 1050 "id=%d", id); 1051 return -1; 1052 } 1053 1054 if (ssid == wpa_s->current_ssid) { 1055 /* 1056 * Invalidate the EAP session cache if the current network is 1057 * removed. 1058 */ 1059 eapol_sm_invalidate_cached_session(wpa_s->eapol); 1060 1061 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); 1062 } 1063 1064 return 0; 1065 } 1066 1067 1068 static int wpa_supplicant_ctrl_iface_set_network( 1069 struct wpa_supplicant *wpa_s, char *cmd) 1070 { 1071 int id; 1072 struct wpa_ssid *ssid; 1073 char *name, *value; 1074 1075 /* cmd: "<network id> <variable name> <value>" */ 1076 name = os_strchr(cmd, ' '); 1077 if (name == NULL) 1078 return -1; 1079 *name++ = '\0'; 1080 1081 value = os_strchr(name, ' '); 1082 if (value == NULL) 1083 return -1; 1084 *value++ = '\0'; 1085 1086 id = atoi(cmd); 1087 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'", 1088 id, name); 1089 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value", 1090 (u8 *) value, os_strlen(value)); 1091 1092 ssid = wpa_config_get_network(wpa_s->conf, id); 1093 if (ssid == NULL) { 1094 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 1095 "id=%d", id); 1096 return -1; 1097 } 1098 1099 if (wpa_config_set(ssid, name, value, 0) < 0) { 1100 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network " 1101 "variable '%s'", name); 1102 return -1; 1103 } else { 1104 if (os_strcmp(name, "priority") == 0) { 1105 wpa_config_update_prio_list(wpa_s->conf); 1106 } 1107 } 1108 1109 if (wpa_s->current_ssid == ssid) { 1110 /* 1111 * Invalidate the EAP session cache if anything in the current 1112 * configuration changes. 1113 */ 1114 eapol_sm_invalidate_cached_session(wpa_s->eapol); 1115 } 1116 1117 if ((os_strcmp(name, "psk") == 0 && 1118 value[0] == '"' && ssid->ssid_len) || 1119 (os_strcmp(name, "ssid") == 0 && ssid->passphrase)) 1120 wpa_config_update_psk(ssid); 1121 1122 return 0; 1123 } 1124 1125 1126 static int wpa_supplicant_ctrl_iface_get_network( 1127 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) 1128 { 1129 int id; 1130 size_t res; 1131 struct wpa_ssid *ssid; 1132 char *name, *value; 1133 1134 /* cmd: "<network id> <variable name>" */ 1135 name = os_strchr(cmd, ' '); 1136 if (name == NULL || buflen == 0) 1137 return -1; 1138 *name++ = '\0'; 1139 1140 id = atoi(cmd); 1141 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'", 1142 id, name); 1143 1144 ssid = wpa_config_get_network(wpa_s->conf, id); 1145 if (ssid == NULL) { 1146 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " 1147 "id=%d", id); 1148 return -1; 1149 } 1150 1151 value = wpa_config_get_no_key(ssid, name); 1152 if (value == NULL) { 1153 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network " 1154 "variable '%s'", name); 1155 return -1; 1156 } 1157 1158 res = os_strlcpy(buf, value, buflen); 1159 if (res >= buflen) { 1160 os_free(value); 1161 return -1; 1162 } 1163 1164 os_free(value); 1165 1166 return res; 1167 } 1168 1169 1170 #ifndef CONFIG_NO_CONFIG_WRITE 1171 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s) 1172 { 1173 int ret; 1174 1175 if (!wpa_s->conf->update_config) { 1176 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed " 1177 "to update configuration (update_config=0)"); 1178 return -1; 1179 } 1180 1181 ret = wpa_config_write(wpa_s->confname, wpa_s->conf); 1182 if (ret) { 1183 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to " 1184 "update configuration"); 1185 } else { 1186 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration" 1187 " updated"); 1188 } 1189 1190 return ret; 1191 } 1192 #endif /* CONFIG_NO_CONFIG_WRITE */ 1193 1194 1195 static int ctrl_iface_get_capability_pairwise(int res, char *strict, 1196 struct wpa_driver_capa *capa, 1197 char *buf, size_t buflen) 1198 { 1199 int ret, first = 1; 1200 char *pos, *end; 1201 size_t len; 1202 1203 pos = buf; 1204 end = pos + buflen; 1205 1206 if (res < 0) { 1207 if (strict) 1208 return 0; 1209 len = os_strlcpy(buf, "CCMP TKIP NONE", buflen); 1210 if (len >= buflen) 1211 return -1; 1212 return len; 1213 } 1214 1215 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) { 1216 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " "); 1217 if (ret < 0 || ret >= end - pos) 1218 return pos - buf; 1219 pos += ret; 1220 first = 0; 1221 } 1222 1223 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) { 1224 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " "); 1225 if (ret < 0 || ret >= end - pos) 1226 return pos - buf; 1227 pos += ret; 1228 first = 0; 1229 } 1230 1231 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { 1232 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : " "); 1233 if (ret < 0 || ret >= end - pos) 1234 return pos - buf; 1235 pos += ret; 1236 first = 0; 1237 } 1238 1239 return pos - buf; 1240 } 1241 1242 1243 static int ctrl_iface_get_capability_group(int res, char *strict, 1244 struct wpa_driver_capa *capa, 1245 char *buf, size_t buflen) 1246 { 1247 int ret, first = 1; 1248 char *pos, *end; 1249 size_t len; 1250 1251 pos = buf; 1252 end = pos + buflen; 1253 1254 if (res < 0) { 1255 if (strict) 1256 return 0; 1257 len = os_strlcpy(buf, "CCMP TKIP WEP104 WEP40", buflen); 1258 if (len >= buflen) 1259 return -1; 1260 return len; 1261 } 1262 1263 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) { 1264 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " "); 1265 if (ret < 0 || ret >= end - pos) 1266 return pos - buf; 1267 pos += ret; 1268 first = 0; 1269 } 1270 1271 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) { 1272 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " "); 1273 if (ret < 0 || ret >= end - pos) 1274 return pos - buf; 1275 pos += ret; 1276 first = 0; 1277 } 1278 1279 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP104) { 1280 ret = os_snprintf(pos, end - pos, "%sWEP104", 1281 first ? "" : " "); 1282 if (ret < 0 || ret >= end - pos) 1283 return pos - buf; 1284 pos += ret; 1285 first = 0; 1286 } 1287 1288 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP40) { 1289 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : " "); 1290 if (ret < 0 || ret >= end - pos) 1291 return pos - buf; 1292 pos += ret; 1293 first = 0; 1294 } 1295 1296 return pos - buf; 1297 } 1298 1299 1300 static int ctrl_iface_get_capability_key_mgmt(int res, char *strict, 1301 struct wpa_driver_capa *capa, 1302 char *buf, size_t buflen) 1303 { 1304 int ret; 1305 char *pos, *end; 1306 size_t len; 1307 1308 pos = buf; 1309 end = pos + buflen; 1310 1311 if (res < 0) { 1312 if (strict) 1313 return 0; 1314 len = os_strlcpy(buf, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE " 1315 "NONE", buflen); 1316 if (len >= buflen) 1317 return -1; 1318 return len; 1319 } 1320 1321 ret = os_snprintf(pos, end - pos, "NONE IEEE8021X"); 1322 if (ret < 0 || ret >= end - pos) 1323 return pos - buf; 1324 pos += ret; 1325 1326 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | 1327 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) { 1328 ret = os_snprintf(pos, end - pos, " WPA-EAP"); 1329 if (ret < 0 || ret >= end - pos) 1330 return pos - buf; 1331 pos += ret; 1332 } 1333 1334 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | 1335 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { 1336 ret = os_snprintf(pos, end - pos, " WPA-PSK"); 1337 if (ret < 0 || ret >= end - pos) 1338 return pos - buf; 1339 pos += ret; 1340 } 1341 1342 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { 1343 ret = os_snprintf(pos, end - pos, " WPA-NONE"); 1344 if (ret < 0 || ret >= end - pos) 1345 return pos - buf; 1346 pos += ret; 1347 } 1348 1349 return pos - buf; 1350 } 1351 1352 1353 static int ctrl_iface_get_capability_proto(int res, char *strict, 1354 struct wpa_driver_capa *capa, 1355 char *buf, size_t buflen) 1356 { 1357 int ret, first = 1; 1358 char *pos, *end; 1359 size_t len; 1360 1361 pos = buf; 1362 end = pos + buflen; 1363 1364 if (res < 0) { 1365 if (strict) 1366 return 0; 1367 len = os_strlcpy(buf, "RSN WPA", buflen); 1368 if (len >= buflen) 1369 return -1; 1370 return len; 1371 } 1372 1373 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | 1374 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { 1375 ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " "); 1376 if (ret < 0 || ret >= end - pos) 1377 return pos - buf; 1378 pos += ret; 1379 first = 0; 1380 } 1381 1382 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | 1383 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) { 1384 ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " "); 1385 if (ret < 0 || ret >= end - pos) 1386 return pos - buf; 1387 pos += ret; 1388 first = 0; 1389 } 1390 1391 return pos - buf; 1392 } 1393 1394 1395 static int ctrl_iface_get_capability_auth_alg(int res, char *strict, 1396 struct wpa_driver_capa *capa, 1397 char *buf, size_t buflen) 1398 { 1399 int ret, first = 1; 1400 char *pos, *end; 1401 size_t len; 1402 1403 pos = buf; 1404 end = pos + buflen; 1405 1406 if (res < 0) { 1407 if (strict) 1408 return 0; 1409 len = os_strlcpy(buf, "OPEN SHARED LEAP", buflen); 1410 if (len >= buflen) 1411 return -1; 1412 return len; 1413 } 1414 1415 if (capa->auth & (WPA_DRIVER_AUTH_OPEN)) { 1416 ret = os_snprintf(pos, end - pos, "%sOPEN", first ? "" : " "); 1417 if (ret < 0 || ret >= end - pos) 1418 return pos - buf; 1419 pos += ret; 1420 first = 0; 1421 } 1422 1423 if (capa->auth & (WPA_DRIVER_AUTH_SHARED)) { 1424 ret = os_snprintf(pos, end - pos, "%sSHARED", 1425 first ? "" : " "); 1426 if (ret < 0 || ret >= end - pos) 1427 return pos - buf; 1428 pos += ret; 1429 first = 0; 1430 } 1431 1432 if (capa->auth & (WPA_DRIVER_AUTH_LEAP)) { 1433 ret = os_snprintf(pos, end - pos, "%sLEAP", first ? "" : " "); 1434 if (ret < 0 || ret >= end - pos) 1435 return pos - buf; 1436 pos += ret; 1437 first = 0; 1438 } 1439 1440 return pos - buf; 1441 } 1442 1443 1444 static int wpa_supplicant_ctrl_iface_get_capability( 1445 struct wpa_supplicant *wpa_s, const char *_field, char *buf, 1446 size_t buflen) 1447 { 1448 struct wpa_driver_capa capa; 1449 int res; 1450 char *strict; 1451 char field[30]; 1452 size_t len; 1453 1454 /* Determine whether or not strict checking was requested */ 1455 len = os_strlcpy(field, _field, sizeof(field)); 1456 if (len >= sizeof(field)) 1457 return -1; 1458 strict = os_strchr(field, ' '); 1459 if (strict != NULL) { 1460 *strict++ = '\0'; 1461 if (os_strcmp(strict, "strict") != 0) 1462 return -1; 1463 } 1464 1465 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s", 1466 field, strict ? strict : ""); 1467 1468 if (os_strcmp(field, "eap") == 0) { 1469 return eap_get_names(buf, buflen); 1470 } 1471 1472 res = wpa_drv_get_capa(wpa_s, &capa); 1473 1474 if (os_strcmp(field, "pairwise") == 0) 1475 return ctrl_iface_get_capability_pairwise(res, strict, &capa, 1476 buf, buflen); 1477 1478 if (os_strcmp(field, "group") == 0) 1479 return ctrl_iface_get_capability_group(res, strict, &capa, 1480 buf, buflen); 1481 1482 if (os_strcmp(field, "key_mgmt") == 0) 1483 return ctrl_iface_get_capability_key_mgmt(res, strict, &capa, 1484 buf, buflen); 1485 1486 if (os_strcmp(field, "proto") == 0) 1487 return ctrl_iface_get_capability_proto(res, strict, &capa, 1488 buf, buflen); 1489 1490 if (os_strcmp(field, "auth_alg") == 0) 1491 return ctrl_iface_get_capability_auth_alg(res, strict, &capa, 1492 buf, buflen); 1493 1494 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'", 1495 field); 1496 1497 return -1; 1498 } 1499 1500 1501 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s, 1502 const char *cmd, char *buf, 1503 size_t buflen) 1504 { 1505 u8 bssid[ETH_ALEN]; 1506 size_t i; 1507 struct wpa_scan_results *results; 1508 struct wpa_scan_res *bss; 1509 int ret; 1510 char *pos, *end; 1511 const u8 *ie, *ie2; 1512 1513 if (wpa_s->scan_res == NULL && 1514 wpa_supplicant_get_scan_results(wpa_s) < 0) 1515 return 0; 1516 1517 results = wpa_s->scan_res; 1518 if (results == NULL) 1519 return 0; 1520 1521 if (hwaddr_aton(cmd, bssid) == 0) { 1522 for (i = 0; i < results->num; i++) { 1523 if (os_memcmp(bssid, results->res[i]->bssid, ETH_ALEN) 1524 == 0) 1525 break; 1526 } 1527 } else 1528 i = atoi(cmd); 1529 1530 if (i >= results->num || results->res[i] == NULL) 1531 return 0; /* no match found */ 1532 1533 bss = results->res[i]; 1534 pos = buf; 1535 end = buf + buflen; 1536 ret = os_snprintf(pos, end - pos, 1537 "bssid=" MACSTR "\n" 1538 "freq=%d\n" 1539 "beacon_int=%d\n" 1540 "capabilities=0x%04x\n" 1541 "qual=%d\n" 1542 "noise=%d\n" 1543 "level=%d\n" 1544 "tsf=%016llu\n" 1545 "ie=", 1546 MAC2STR(bss->bssid), bss->freq, bss->beacon_int, 1547 bss->caps, bss->qual, bss->noise, bss->level, 1548 (unsigned long long) bss->tsf); 1549 if (ret < 0 || ret >= end - pos) 1550 return pos - buf; 1551 pos += ret; 1552 1553 ie = (const u8 *) (bss + 1); 1554 for (i = 0; i < bss->ie_len; i++) { 1555 ret = os_snprintf(pos, end - pos, "%02x", *ie++); 1556 if (ret < 0 || ret >= end - pos) 1557 return pos - buf; 1558 pos += ret; 1559 } 1560 1561 ret = os_snprintf(pos, end - pos, "\n"); 1562 if (ret < 0 || ret >= end - pos) 1563 return pos - buf; 1564 pos += ret; 1565 1566 ret = os_snprintf(pos, end - pos, "flags="); 1567 if (ret < 0 || ret >= end - pos) 1568 return pos - buf; 1569 pos += ret; 1570 1571 ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); 1572 if (ie) 1573 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]); 1574 ie2 = wpa_scan_get_ie(bss, WLAN_EID_RSN); 1575 if (ie2) 1576 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]); 1577 pos = wpa_supplicant_wps_ie_txt(pos, end, bss); 1578 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) { 1579 ret = os_snprintf(pos, end - pos, "[WEP]"); 1580 if (ret < 0 || ret >= end - pos) 1581 return pos - buf; 1582 pos += ret; 1583 } 1584 if (bss->caps & IEEE80211_CAP_IBSS) { 1585 ret = os_snprintf(pos, end - pos, "[IBSS]"); 1586 if (ret < 0 || ret >= end - pos) 1587 return pos - buf; 1588 pos += ret; 1589 } 1590 1591 ret = os_snprintf(pos, end - pos, "\n"); 1592 if (ret < 0 || ret >= end - pos) 1593 return pos - buf; 1594 pos += ret; 1595 1596 ie = wpa_scan_get_ie(bss, WLAN_EID_SSID); 1597 ret = os_snprintf(pos, end - pos, "ssid=%s\n", 1598 ie ? wpa_ssid_txt(ie + 2, ie[1]) : ""); 1599 if (ret < 0 || ret >= end - pos) 1600 return pos - buf; 1601 pos += ret; 1602 1603 return pos - buf; 1604 } 1605 1606 1607 static int wpa_supplicant_ctrl_iface_ap_scan( 1608 struct wpa_supplicant *wpa_s, char *cmd) 1609 { 1610 int ap_scan = atoi(cmd); 1611 1612 if (ap_scan < 0 || ap_scan > 2) 1613 return -1; 1614 #ifdef ANDROID 1615 if ((ap_scan == 2) && (wpa_s->wpa_state != WPA_COMPLETED)) { 1616 wpa_printf(MSG_DEBUG, "ap_scan = %d", wpa_s->conf->ap_scan); 1617 return 0; 1618 } 1619 wpa_printf(MSG_DEBUG, "ap_scan = %d", ap_scan); 1620 #endif 1621 wpa_s->conf->ap_scan = ap_scan; 1622 return 0; 1623 } 1624 1625 #ifdef ANDROID 1626 static int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s, 1627 char *cmd, char *buf, size_t buflen) 1628 { 1629 int ret; 1630 1631 ret = wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen); 1632 if( ret == 0 ) { 1633 ret = sprintf(buf, "%s\n", "OK"); 1634 } 1635 return( ret ); 1636 } 1637 #endif 1638 1639 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, 1640 char *buf, size_t *resp_len) 1641 { 1642 char *reply; 1643 const int reply_size = 4096; 1644 int ctrl_rsp = 0; 1645 int reply_len; 1646 1647 wpa_printf(MSG_DEBUG, "CMD = %s", buf); 1648 1649 if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 || 1650 os_strncmp(buf, "SET_NETWORK ", 12) == 0) { 1651 wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface", 1652 (const u8 *) buf, os_strlen(buf)); 1653 } else { 1654 if (os_strcmp(buf, "PING") != 0) { 1655 wpa_hexdump_ascii(MSG_DEBUG, "RX ctrl_iface", 1656 (const u8 *) buf, os_strlen(buf)); 1657 } 1658 } 1659 1660 reply = os_malloc(reply_size); 1661 if (reply == NULL) { 1662 *resp_len = 1; 1663 return NULL; 1664 } 1665 1666 os_memcpy(reply, "OK\n", 3); 1667 reply_len = 3; 1668 1669 if (os_strcmp(buf, "PING") == 0) { 1670 os_memcpy(reply, "PONG\n", 5); 1671 reply_len = 5; 1672 } else if (os_strcmp(buf, "MIB") == 0) { 1673 reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); 1674 if (reply_len >= 0) { 1675 int res; 1676 res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len, 1677 reply_size - reply_len); 1678 if (res < 0) 1679 reply_len = -1; 1680 else 1681 reply_len += res; 1682 } 1683 } else if (os_strncmp(buf, "STATUS", 6) == 0) { 1684 reply_len = wpa_supplicant_ctrl_iface_status( 1685 wpa_s, buf + 6, reply, reply_size); 1686 } else if (os_strcmp(buf, "PMKSA") == 0) { 1687 reply_len = pmksa_cache_list(wpa_s->wpa, reply, reply_size); 1688 } else if (os_strncmp(buf, "SET ", 4) == 0) { 1689 if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4)) 1690 reply_len = -1; 1691 } else if (os_strcmp(buf, "LOGON") == 0) { 1692 eapol_sm_notify_logoff(wpa_s->eapol, FALSE); 1693 } else if (os_strcmp(buf, "LOGOFF") == 0) { 1694 eapol_sm_notify_logoff(wpa_s->eapol, TRUE); 1695 } else if (os_strcmp(buf, "REASSOCIATE") == 0) { 1696 wpa_s->disconnected = 0; 1697 wpa_s->reassociate = 1; 1698 wpa_supplicant_req_scan(wpa_s, 0, 0); 1699 } else if (os_strcmp(buf, "RECONNECT") == 0) { 1700 if (wpa_s->disconnected) { 1701 wpa_s->disconnected = 0; 1702 wpa_s->reassociate = 1; 1703 wpa_supplicant_req_scan(wpa_s, 0, 0); 1704 } 1705 #ifdef IEEE8021X_EAPOL 1706 } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) { 1707 if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8)) 1708 reply_len = -1; 1709 #endif /* IEEE8021X_EAPOL */ 1710 #ifdef CONFIG_PEERKEY 1711 } else if (os_strncmp(buf, "STKSTART ", 9) == 0) { 1712 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9)) 1713 reply_len = -1; 1714 #endif /* CONFIG_PEERKEY */ 1715 #ifdef CONFIG_IEEE80211R 1716 } else if (os_strncmp(buf, "FT_DS ", 6) == 0) { 1717 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6)) 1718 reply_len = -1; 1719 #endif /* CONFIG_IEEE80211R */ 1720 #ifdef CONFIG_WPS 1721 } else if (os_strcmp(buf, "WPS_PBC") == 0) { 1722 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, NULL)) 1723 reply_len = -1; 1724 } else if (os_strncmp(buf, "WPS_PBC ", 8) == 0) { 1725 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, buf + 8)) 1726 reply_len = -1; 1727 } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) { 1728 reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8, 1729 reply, 1730 reply_size); 1731 } else if (os_strncmp(buf, "WPS_REG ", 8) == 0) { 1732 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8)) 1733 reply_len = -1; 1734 #endif /* CONFIG_WPS */ 1735 } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0) 1736 { 1737 if (wpa_supplicant_ctrl_iface_ctrl_rsp( 1738 wpa_s, buf + os_strlen(WPA_CTRL_RSP))) 1739 reply_len = -1; 1740 else 1741 ctrl_rsp = 1; 1742 } else if (os_strcmp(buf, "RECONFIGURE") == 0) { 1743 if (wpa_supplicant_reload_configuration(wpa_s)) 1744 reply_len = -1; 1745 } else if (os_strcmp(buf, "TERMINATE") == 0) { 1746 eloop_terminate(); 1747 } else if (os_strncmp(buf, "BSSID ", 6) == 0) { 1748 if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6)) 1749 reply_len = -1; 1750 #ifdef ANDROID 1751 } else if (os_strncmp(buf, "SCAN_INTERVAL ", 14) == 0) { 1752 reply_len = wpa_supplicant_ctrl_iface_scan_interval( 1753 wpa_s, buf + 14); 1754 } else if (os_strncmp(buf, "BLACKLIST", 9) == 0) { 1755 reply_len = wpa_supplicant_ctrl_iface_blacklist( 1756 wpa_s, buf + 9, reply, reply_size); 1757 } else if (os_strncmp(buf, "LOG_LEVEL", 9) == 0) { 1758 reply_len = wpa_supplicant_ctrl_iface_log_level( 1759 wpa_s, buf + 9, reply, reply_size); 1760 #endif 1761 } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) { 1762 reply_len = wpa_supplicant_ctrl_iface_list_networks( 1763 wpa_s, reply, reply_size); 1764 } else if (os_strcmp(buf, "DISCONNECT") == 0) { 1765 wpa_s->reassociate = 0; 1766 wpa_s->disconnected = 1; 1767 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); 1768 } else if (os_strcmp(buf, "SCAN") == 0) { 1769 #ifdef ANDROID 1770 if (!wpa_s->scanning && ((wpa_s->wpa_state <= WPA_SCANNING) || 1771 (wpa_s->wpa_state >= WPA_COMPLETED))) { 1772 #endif 1773 wpa_s->scan_req = 2; 1774 wpa_supplicant_req_scan(wpa_s, 0, 0); 1775 #ifdef ANDROID 1776 } else { 1777 wpa_printf(MSG_ERROR, "Ongoing Scan action..."); 1778 #endif 1779 } 1780 } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) { 1781 reply_len = wpa_supplicant_ctrl_iface_scan_results( 1782 wpa_s, reply, reply_size); 1783 } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) { 1784 if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15)) 1785 reply_len = -1; 1786 } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) { 1787 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15)) 1788 reply_len = -1; 1789 } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) { 1790 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16)) 1791 reply_len = -1; 1792 } else if (os_strcmp(buf, "ADD_NETWORK") == 0) { 1793 reply_len = wpa_supplicant_ctrl_iface_add_network( 1794 wpa_s, reply, reply_size); 1795 } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) { 1796 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15)) 1797 reply_len = -1; 1798 } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) { 1799 if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12)) 1800 reply_len = -1; 1801 } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) { 1802 reply_len = wpa_supplicant_ctrl_iface_get_network( 1803 wpa_s, buf + 12, reply, reply_size); 1804 #ifndef CONFIG_NO_CONFIG_WRITE 1805 } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) { 1806 if (wpa_supplicant_ctrl_iface_save_config(wpa_s)) 1807 reply_len = -1; 1808 #endif /* CONFIG_NO_CONFIG_WRITE */ 1809 } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) { 1810 reply_len = wpa_supplicant_ctrl_iface_get_capability( 1811 wpa_s, buf + 15, reply, reply_size); 1812 } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) { 1813 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8)) 1814 reply_len = -1; 1815 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) { 1816 reply_len = wpa_supplicant_global_iface_list( 1817 wpa_s->global, reply, reply_size); 1818 } else if (os_strcmp(buf, "INTERFACES") == 0) { 1819 reply_len = wpa_supplicant_global_iface_interfaces( 1820 wpa_s->global, reply, reply_size); 1821 } else if (os_strncmp(buf, "BSS ", 4) == 0) { 1822 reply_len = wpa_supplicant_ctrl_iface_bss( 1823 wpa_s, buf + 4, reply, reply_size); 1824 #ifdef ANDROID 1825 } else if (os_strncmp(buf, "DRIVER ", 7) == 0) { 1826 reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply, reply_size); 1827 #endif 1828 } else { 1829 os_memcpy(reply, "UNKNOWN COMMAND\n", 16); 1830 reply_len = 16; 1831 } 1832 1833 if (reply_len < 0) { 1834 os_memcpy(reply, "FAIL\n", 5); 1835 reply_len = 5; 1836 } 1837 1838 if (ctrl_rsp) 1839 eapol_sm_notify_ctrl_response(wpa_s->eapol); 1840 1841 *resp_len = reply_len; 1842 return reply; 1843 } 1844 1845 1846 static int wpa_supplicant_global_iface_add(struct wpa_global *global, 1847 char *cmd) 1848 { 1849 struct wpa_interface iface; 1850 char *pos; 1851 1852 /* 1853 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param> 1854 * TAB<bridge_ifname> 1855 */ 1856 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd); 1857 1858 os_memset(&iface, 0, sizeof(iface)); 1859 1860 do { 1861 iface.ifname = pos = cmd; 1862 pos = os_strchr(pos, '\t'); 1863 if (pos) 1864 *pos++ = '\0'; 1865 if (iface.ifname[0] == '\0') 1866 return -1; 1867 if (pos == NULL) 1868 break; 1869 1870 iface.confname = pos; 1871 pos = os_strchr(pos, '\t'); 1872 if (pos) 1873 *pos++ = '\0'; 1874 if (iface.confname[0] == '\0') 1875 iface.confname = NULL; 1876 if (pos == NULL) 1877 break; 1878 1879 iface.driver = pos; 1880 pos = os_strchr(pos, '\t'); 1881 if (pos) 1882 *pos++ = '\0'; 1883 if (iface.driver[0] == '\0') 1884 iface.driver = NULL; 1885 if (pos == NULL) 1886 break; 1887 1888 iface.ctrl_interface = pos; 1889 pos = os_strchr(pos, '\t'); 1890 if (pos) 1891 *pos++ = '\0'; 1892 if (iface.ctrl_interface[0] == '\0') 1893 iface.ctrl_interface = NULL; 1894 if (pos == NULL) 1895 break; 1896 1897 iface.driver_param = pos; 1898 pos = os_strchr(pos, '\t'); 1899 if (pos) 1900 *pos++ = '\0'; 1901 if (iface.driver_param[0] == '\0') 1902 iface.driver_param = NULL; 1903 if (pos == NULL) 1904 break; 1905 1906 iface.bridge_ifname = pos; 1907 pos = os_strchr(pos, '\t'); 1908 if (pos) 1909 *pos++ = '\0'; 1910 if (iface.bridge_ifname[0] == '\0') 1911 iface.bridge_ifname = NULL; 1912 if (pos == NULL) 1913 break; 1914 } while (0); 1915 1916 if (wpa_supplicant_get_iface(global, iface.ifname)) 1917 return -1; 1918 1919 return wpa_supplicant_add_iface(global, &iface) ? 0 : -1; 1920 } 1921 1922 1923 static int wpa_supplicant_global_iface_remove(struct wpa_global *global, 1924 char *cmd) 1925 { 1926 struct wpa_supplicant *wpa_s; 1927 1928 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd); 1929 1930 wpa_s = wpa_supplicant_get_iface(global, cmd); 1931 if (wpa_s == NULL) 1932 return -1; 1933 return wpa_supplicant_remove_iface(global, wpa_s); 1934 } 1935 1936 1937 static void wpa_free_iface_info(struct wpa_interface_info *iface) 1938 { 1939 struct wpa_interface_info *prev; 1940 1941 while (iface) { 1942 prev = iface; 1943 iface = iface->next; 1944 1945 os_free(prev->ifname); 1946 os_free(prev->desc); 1947 os_free(prev); 1948 } 1949 } 1950 1951 1952 static int wpa_supplicant_global_iface_list(struct wpa_global *global, 1953 char *buf, int len) 1954 { 1955 int i, res; 1956 struct wpa_interface_info *iface = NULL, *last = NULL, *tmp; 1957 char *pos, *end; 1958 1959 for (i = 0; wpa_supplicant_drivers[i]; i++) { 1960 struct wpa_driver_ops *drv = wpa_supplicant_drivers[i]; 1961 if (drv->get_interfaces == NULL) 1962 continue; 1963 tmp = drv->get_interfaces(global->drv_priv); 1964 if (tmp == NULL) 1965 continue; 1966 1967 if (last == NULL) 1968 iface = last = tmp; 1969 else 1970 last->next = tmp; 1971 while (last->next) 1972 last = last->next; 1973 } 1974 1975 pos = buf; 1976 end = buf + len; 1977 for (tmp = iface; tmp; tmp = tmp->next) { 1978 res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n", 1979 tmp->drv_name, tmp->ifname, 1980 tmp->desc ? tmp->desc : ""); 1981 if (res < 0 || res >= end - pos) { 1982 *pos = '\0'; 1983 break; 1984 } 1985 pos += res; 1986 } 1987 1988 wpa_free_iface_info(iface); 1989 1990 return pos - buf; 1991 } 1992 1993 1994 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global, 1995 char *buf, int len) 1996 { 1997 int res; 1998 char *pos, *end; 1999 struct wpa_supplicant *wpa_s; 2000 2001 wpa_s = global->ifaces; 2002 pos = buf; 2003 end = buf + len; 2004 2005 while (wpa_s) { 2006 res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname); 2007 if (res < 0 || res >= end - pos) { 2008 *pos = '\0'; 2009 break; 2010 } 2011 pos += res; 2012 wpa_s = wpa_s->next; 2013 } 2014 return pos - buf; 2015 } 2016 2017 2018 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global, 2019 char *buf, size_t *resp_len) 2020 { 2021 char *reply; 2022 const int reply_size = 4096; 2023 int reply_len; 2024 2025 if (os_strcmp(buf, "PING") != 0) { 2026 wpa_hexdump_ascii(MSG_DEBUG, "RX global ctrl_iface", 2027 (const u8 *) buf, os_strlen(buf)); 2028 } 2029 2030 reply = os_malloc(reply_size); 2031 if (reply == NULL) { 2032 *resp_len = 1; 2033 return NULL; 2034 } 2035 2036 os_memcpy(reply, "OK\n", 3); 2037 reply_len = 3; 2038 2039 if (os_strcmp(buf, "PING") == 0) { 2040 os_memcpy(reply, "PONG\n", 5); 2041 reply_len = 5; 2042 } else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) { 2043 if (wpa_supplicant_global_iface_add(global, buf + 14)) 2044 reply_len = -1; 2045 } else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) { 2046 if (wpa_supplicant_global_iface_remove(global, buf + 17)) 2047 reply_len = -1; 2048 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) { 2049 reply_len = wpa_supplicant_global_iface_list( 2050 global, reply, reply_size); 2051 } else if (os_strcmp(buf, "INTERFACES") == 0) { 2052 reply_len = wpa_supplicant_global_iface_interfaces( 2053 global, reply, reply_size); 2054 } else if (os_strcmp(buf, "TERMINATE") == 0) { 2055 eloop_terminate(); 2056 } else { 2057 os_memcpy(reply, "UNKNOWN COMMAND\n", 16); 2058 reply_len = 16; 2059 } 2060 2061 if (reply_len < 0) { 2062 os_memcpy(reply, "FAIL\n", 5); 2063 reply_len = 5; 2064 } 2065 2066 *resp_len = reply_len; 2067 return reply; 2068 } 2069