2 * WPA Supplicant / Control interface (shared code for all backends)
3 * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
15 #include "utils/includes.h"
17 #include "utils/common.h"
18 #include "utils/eloop.h"
19 #include "common/ieee802_11_defs.h"
20 #include "common/wpa_ctrl.h"
21 #include "eap_peer/eap.h"
22 #include "eapol_supp/eapol_supp_sm.h"
23 #include "rsn_supp/wpa.h"
24 #include "rsn_supp/preauth.h"
25 #include "rsn_supp/pmksa_cache.h"
26 #include "l2_packet/l2_packet.h"
29 #include "wpa_supplicant_i.h"
31 #include "wps_supplicant.h"
37 #include "ctrl_iface.h"
39 extern struct wpa_driver_ops *wpa_drivers[];
41 static int wpa_supplicant_global_iface_list(struct wpa_global *global,
43 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
47 static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
53 value = os_strchr(cmd, ' ');
58 wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value);
59 if (os_strcasecmp(cmd, "EAPOL::heldPeriod") == 0) {
60 eapol_sm_configure(wpa_s->eapol,
61 atoi(value), -1, -1, -1);
62 } else if (os_strcasecmp(cmd, "EAPOL::authPeriod") == 0) {
63 eapol_sm_configure(wpa_s->eapol,
64 -1, atoi(value), -1, -1);
65 } else if (os_strcasecmp(cmd, "EAPOL::startPeriod") == 0) {
66 eapol_sm_configure(wpa_s->eapol,
67 -1, -1, atoi(value), -1);
68 } else if (os_strcasecmp(cmd, "EAPOL::maxStart") == 0) {
69 eapol_sm_configure(wpa_s->eapol,
70 -1, -1, -1, atoi(value));
71 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) {
72 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
75 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") ==
77 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
80 } else if (os_strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) {
81 if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value)))
90 #ifdef IEEE8021X_EAPOL
91 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s,
95 struct wpa_ssid *ssid = wpa_s->current_ssid;
97 if (hwaddr_aton(addr, bssid)) {
98 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address "
103 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid));
104 rsn_preauth_deinit(wpa_s->wpa);
105 if (rsn_preauth_init(wpa_s->wpa, bssid, ssid ? &ssid->eap : NULL))
110 #endif /* IEEE8021X_EAPOL */
113 #ifdef CONFIG_PEERKEY
114 /* MLME-STKSTART.request(peer) */
115 static int wpa_supplicant_ctrl_iface_stkstart(
116 struct wpa_supplicant *wpa_s, char *addr)
120 if (hwaddr_aton(addr, peer)) {
121 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid "
122 "address '%s'", addr);
126 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART " MACSTR,
129 return wpa_sm_stkstart(wpa_s->wpa, peer);
131 #endif /* CONFIG_PEERKEY */
134 #ifdef CONFIG_IEEE80211R
135 static int wpa_supplicant_ctrl_iface_ft_ds(
136 struct wpa_supplicant *wpa_s, char *addr)
138 u8 target_ap[ETH_ALEN];
142 if (hwaddr_aton(addr, target_ap)) {
143 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS: invalid "
144 "address '%s'", addr);
148 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS " MACSTR, MAC2STR(target_ap));
150 bss = wpa_bss_get_bssid(wpa_s, target_ap);
152 mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
156 return wpa_ft_start_over_ds(wpa_s->wpa, target_ap, mdie);
158 #endif /* CONFIG_IEEE80211R */
162 static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
165 u8 bssid[ETH_ALEN], *_bssid = bssid;
167 if (cmd == NULL || os_strcmp(cmd, "any") == 0)
169 else if (hwaddr_aton(cmd, bssid)) {
170 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
177 return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid);
178 #endif /* CONFIG_AP */
180 return wpas_wps_start_pbc(wpa_s, _bssid);
184 static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
185 char *cmd, char *buf,
188 u8 bssid[ETH_ALEN], *_bssid = bssid;
192 pin = os_strchr(cmd, ' ');
196 if (os_strcmp(cmd, "any") == 0)
198 else if (hwaddr_aton(cmd, bssid)) {
199 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
206 return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin,
208 #endif /* CONFIG_AP */
211 ret = wpas_wps_start_pin(wpa_s, _bssid, pin);
214 ret = os_snprintf(buf, buflen, "%s", pin);
215 if (ret < 0 || (size_t) ret >= buflen)
220 ret = wpas_wps_start_pin(wpa_s, _bssid, NULL);
224 /* Return the generated PIN */
225 ret = os_snprintf(buf, buflen, "%08d", ret);
226 if (ret < 0 || (size_t) ret >= buflen)
232 #ifdef CONFIG_WPS_OOB
233 static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant *wpa_s,
236 char *path, *method, *name;
238 path = os_strchr(cmd, ' ');
243 method = os_strchr(path, ' ');
248 name = os_strchr(method, ' ');
252 return wpas_wps_start_oob(wpa_s, cmd, path, method, name);
254 #endif /* CONFIG_WPS_OOB */
257 static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s,
260 u8 bssid[ETH_ALEN], *_bssid = bssid;
266 struct wps_new_ap_settings ap;
268 pin = os_strchr(cmd, ' ');
273 if (os_strcmp(cmd, "any") == 0)
275 else if (hwaddr_aton(cmd, bssid)) {
276 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_REG: invalid BSSID '%s'",
281 new_ssid = os_strchr(pin, ' ');
282 if (new_ssid == NULL)
283 return wpas_wps_start_reg(wpa_s, _bssid, pin, NULL);
286 new_auth = os_strchr(new_ssid, ' ');
287 if (new_auth == NULL)
291 new_encr = os_strchr(new_auth, ' ');
292 if (new_encr == NULL)
296 new_key = os_strchr(new_encr, ' ');
301 os_memset(&ap, 0, sizeof(ap));
302 ap.ssid_hex = new_ssid;
305 ap.key_hex = new_key;
306 return wpas_wps_start_reg(wpa_s, _bssid, pin, &ap);
311 static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant *wpa_s,
314 char *uuid = cmd, *pin;
315 pin = os_strchr(uuid, ' ');
319 return wpas_wps_er_add_pin(wpa_s, uuid, pin);
323 static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant *wpa_s,
326 char *uuid = cmd, *pin;
327 pin = os_strchr(uuid, ' ');
331 return wpas_wps_er_learn(wpa_s, uuid, pin);
335 static int wpa_supplicant_ctrl_iface_wps_er_config(
336 struct wpa_supplicant *wpa_s, char *cmd)
343 struct wps_new_ap_settings ap;
345 pin = os_strchr(cmd, ' ');
350 new_ssid = os_strchr(pin, ' ');
351 if (new_ssid == NULL)
355 new_auth = os_strchr(new_ssid, ' ');
356 if (new_auth == NULL)
360 new_encr = os_strchr(new_auth, ' ');
361 if (new_encr == NULL)
365 new_key = os_strchr(new_encr, ' ');
370 os_memset(&ap, 0, sizeof(ap));
371 ap.ssid_hex = new_ssid;
374 ap.key_hex = new_key;
375 return wpas_wps_er_config(wpa_s, cmd, pin, &ap);
377 #endif /* CONFIG_WPS_ER */
379 #endif /* CONFIG_WPS */
382 #ifdef CONFIG_IBSS_RSN
383 static int wpa_supplicant_ctrl_iface_ibss_rsn(
384 struct wpa_supplicant *wpa_s, char *addr)
388 if (hwaddr_aton(addr, peer)) {
389 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN: invalid "
390 "address '%s'", addr);
394 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN " MACSTR,
397 return ibss_rsn_start(wpa_s->ibss_rsn, peer);
399 #endif /* CONFIG_IBSS_RSN */
402 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
405 #ifdef IEEE8021X_EAPOL
408 struct wpa_ssid *ssid;
409 struct eap_peer_config *eap;
411 pos = os_strchr(rsp, '-');
416 pos = os_strchr(pos, ':');
421 wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id);
422 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
423 (u8 *) pos, os_strlen(pos));
425 ssid = wpa_config_get_network(wpa_s->conf, id);
427 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
433 if (os_strcmp(rsp, "IDENTITY") == 0) {
434 os_free(eap->identity);
435 eap->identity = (u8 *) os_strdup(pos);
436 eap->identity_len = os_strlen(pos);
437 eap->pending_req_identity = 0;
438 if (ssid == wpa_s->current_ssid)
439 wpa_s->reassociate = 1;
440 } else if (os_strcmp(rsp, "PASSWORD") == 0) {
441 os_free(eap->password);
442 eap->password = (u8 *) os_strdup(pos);
443 eap->password_len = os_strlen(pos);
444 eap->pending_req_password = 0;
445 if (ssid == wpa_s->current_ssid)
446 wpa_s->reassociate = 1;
447 } else if (os_strcmp(rsp, "NEW_PASSWORD") == 0) {
448 os_free(eap->new_password);
449 eap->new_password = (u8 *) os_strdup(pos);
450 eap->new_password_len = os_strlen(pos);
451 eap->pending_req_new_password = 0;
452 if (ssid == wpa_s->current_ssid)
453 wpa_s->reassociate = 1;
454 } else if (os_strcmp(rsp, "PIN") == 0) {
456 eap->pin = os_strdup(pos);
457 eap->pending_req_pin = 0;
458 if (ssid == wpa_s->current_ssid)
459 wpa_s->reassociate = 1;
460 } else if (os_strcmp(rsp, "OTP") == 0) {
462 eap->otp = (u8 *) os_strdup(pos);
463 eap->otp_len = os_strlen(pos);
464 os_free(eap->pending_req_otp);
465 eap->pending_req_otp = NULL;
466 eap->pending_req_otp_len = 0;
467 } else if (os_strcmp(rsp, "PASSPHRASE") == 0) {
468 os_free(eap->private_key_passwd);
469 eap->private_key_passwd = (u8 *) os_strdup(pos);
470 eap->pending_req_passphrase = 0;
471 if (ssid == wpa_s->current_ssid)
472 wpa_s->reassociate = 1;
474 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", rsp);
479 #else /* IEEE8021X_EAPOL */
480 wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
482 #endif /* IEEE8021X_EAPOL */
486 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
488 char *buf, size_t buflen)
490 char *pos, *end, tmp[30];
491 int res, verbose, ret;
493 verbose = os_strcmp(params, "-VERBOSE") == 0;
496 if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
497 struct wpa_ssid *ssid = wpa_s->current_ssid;
498 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
499 MAC2STR(wpa_s->bssid));
500 if (ret < 0 || ret >= end - pos)
504 u8 *_ssid = ssid->ssid;
505 size_t ssid_len = ssid->ssid_len;
506 u8 ssid_buf[MAX_SSID_LEN];
508 int _res = wpa_drv_get_ssid(wpa_s, ssid_buf);
515 ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n",
516 wpa_ssid_txt(_ssid, ssid_len),
518 if (ret < 0 || ret >= end - pos)
523 ret = os_snprintf(pos, end - pos,
526 if (ret < 0 || ret >= end - pos)
531 switch (ssid->mode) {
532 case WPAS_MODE_INFRA:
533 ret = os_snprintf(pos, end - pos,
537 ret = os_snprintf(pos, end - pos,
541 ret = os_snprintf(pos, end - pos,
548 if (ret < 0 || ret >= end - pos)
554 if (wpa_s->ap_iface) {
555 pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
559 #endif /* CONFIG_AP */
560 pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose);
562 ret = os_snprintf(pos, end - pos, "wpa_state=%s\n",
563 wpa_supplicant_state_txt(wpa_s->wpa_state));
564 if (ret < 0 || ret >= end - pos)
569 l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) {
570 ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp);
571 if (ret < 0 || ret >= end - pos)
576 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
577 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
578 res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos,
584 res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose);
592 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s,
597 struct wpa_ssid *ssid;
600 /* cmd: "<network id> <BSSID>" */
601 pos = os_strchr(cmd, ' ');
606 wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos);
607 if (hwaddr_aton(pos, bssid)) {
608 wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos);
612 ssid = wpa_config_get_network(wpa_s->conf, id);
614 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
619 os_memcpy(ssid->bssid, bssid, ETH_ALEN);
620 ssid->bssid_set = !is_zero_ether_addr(bssid);
626 static int wpa_supplicant_ctrl_iface_list_networks(
627 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
630 struct wpa_ssid *ssid;
635 ret = os_snprintf(pos, end - pos,
636 "network id / ssid / bssid / flags\n");
637 if (ret < 0 || ret >= end - pos)
641 ssid = wpa_s->conf->ssid;
643 ret = os_snprintf(pos, end - pos, "%d\t%s",
645 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
646 if (ret < 0 || ret >= end - pos)
649 if (ssid->bssid_set) {
650 ret = os_snprintf(pos, end - pos, "\t" MACSTR,
651 MAC2STR(ssid->bssid));
653 ret = os_snprintf(pos, end - pos, "\tany");
655 if (ret < 0 || ret >= end - pos)
658 ret = os_snprintf(pos, end - pos, "\t%s%s",
659 ssid == wpa_s->current_ssid ?
661 ssid->disabled ? "[DISABLED]" : "");
662 if (ret < 0 || ret >= end - pos)
665 ret = os_snprintf(pos, end - pos, "\n");
666 if (ret < 0 || ret >= end - pos)
677 static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher)
680 ret = os_snprintf(pos, end - pos, "-");
681 if (ret < 0 || ret >= end - pos)
684 if (cipher & WPA_CIPHER_NONE) {
685 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : "+");
686 if (ret < 0 || ret >= end - pos)
691 if (cipher & WPA_CIPHER_WEP40) {
692 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : "+");
693 if (ret < 0 || ret >= end - pos)
698 if (cipher & WPA_CIPHER_WEP104) {
699 ret = os_snprintf(pos, end - pos, "%sWEP104",
701 if (ret < 0 || ret >= end - pos)
706 if (cipher & WPA_CIPHER_TKIP) {
707 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : "+");
708 if (ret < 0 || ret >= end - pos)
713 if (cipher & WPA_CIPHER_CCMP) {
714 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : "+");
715 if (ret < 0 || ret >= end - pos)
724 static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
725 const u8 *ie, size_t ie_len)
727 struct wpa_ie_data data;
730 ret = os_snprintf(pos, end - pos, "[%s-", proto);
731 if (ret < 0 || ret >= end - pos)
735 if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) {
736 ret = os_snprintf(pos, end - pos, "?]");
737 if (ret < 0 || ret >= end - pos)
744 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
745 ret = os_snprintf(pos, end - pos, "%sEAP", first ? "" : "+");
746 if (ret < 0 || ret >= end - pos)
751 if (data.key_mgmt & WPA_KEY_MGMT_PSK) {
752 ret = os_snprintf(pos, end - pos, "%sPSK", first ? "" : "+");
753 if (ret < 0 || ret >= end - pos)
758 if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
759 ret = os_snprintf(pos, end - pos, "%sNone", first ? "" : "+");
760 if (ret < 0 || ret >= end - pos)
765 #ifdef CONFIG_IEEE80211R
766 if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
767 ret = os_snprintf(pos, end - pos, "%sFT/EAP",
769 if (ret < 0 || ret >= end - pos)
774 if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) {
775 ret = os_snprintf(pos, end - pos, "%sFT/PSK",
777 if (ret < 0 || ret >= end - pos)
782 #endif /* CONFIG_IEEE80211R */
783 #ifdef CONFIG_IEEE80211W
784 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
785 ret = os_snprintf(pos, end - pos, "%sEAP-SHA256",
787 if (ret < 0 || ret >= end - pos)
792 if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
793 ret = os_snprintf(pos, end - pos, "%sPSK-SHA256",
795 if (ret < 0 || ret >= end - pos)
800 #endif /* CONFIG_IEEE80211W */
802 pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher);
804 if (data.capabilities & WPA_CAPABILITY_PREAUTH) {
805 ret = os_snprintf(pos, end - pos, "-preauth");
806 if (ret < 0 || ret >= end - pos)
811 ret = os_snprintf(pos, end - pos, "]");
812 if (ret < 0 || ret >= end - pos)
821 static char * wpa_supplicant_wps_ie_txt_buf(char *pos, char *end,
822 struct wpabuf *wps_ie)
829 if (wps_is_selected_pbc_registrar(wps_ie))
831 else if (wps_is_selected_pin_registrar(wps_ie))
836 ret = os_snprintf(pos, end - pos, "%s", txt);
837 if (ret >= 0 && ret < end - pos)
842 #endif /* CONFIG_WPS */
845 static char * wpa_supplicant_wps_ie_txt(char *pos, char *end,
846 const struct wpa_bss *bss)
849 struct wpabuf *wps_ie;
850 wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
851 return wpa_supplicant_wps_ie_txt_buf(pos, end, wps_ie);
852 #else /* CONFIG_WPS */
854 #endif /* CONFIG_WPS */
858 /* Format one result on one text line into a buffer. */
859 static int wpa_supplicant_ctrl_iface_scan_result(
860 const struct wpa_bss *bss, char *buf, size_t buflen)
869 ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t",
870 MAC2STR(bss->bssid), bss->freq, bss->level);
871 if (ret < 0 || ret >= end - pos)
874 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
876 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
877 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
879 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
880 pos = wpa_supplicant_wps_ie_txt(pos, end, bss);
881 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
882 ret = os_snprintf(pos, end - pos, "[WEP]");
883 if (ret < 0 || ret >= end - pos)
887 if (bss->caps & IEEE80211_CAP_IBSS) {
888 ret = os_snprintf(pos, end - pos, "[IBSS]");
889 if (ret < 0 || ret >= end - pos)
893 if (bss->caps & IEEE80211_CAP_ESS) {
894 ret = os_snprintf(pos, end - pos, "[ESS]");
895 if (ret < 0 || ret >= end - pos)
900 ret = os_snprintf(pos, end - pos, "\t%s",
901 wpa_ssid_txt(bss->ssid, bss->ssid_len));
902 if (ret < 0 || ret >= end - pos)
906 ret = os_snprintf(pos, end - pos, "\n");
907 if (ret < 0 || ret >= end - pos)
915 static int wpa_supplicant_ctrl_iface_scan_results(
916 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
924 ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / "
926 if (ret < 0 || ret >= end - pos)
930 dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
931 ret = wpa_supplicant_ctrl_iface_scan_result(bss, pos,
933 if (ret < 0 || ret >= end - pos)
942 static int wpa_supplicant_ctrl_iface_select_network(
943 struct wpa_supplicant *wpa_s, char *cmd)
946 struct wpa_ssid *ssid;
948 /* cmd: "<network id>" or "any" */
949 if (os_strcmp(cmd, "any") == 0) {
950 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any");
954 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id);
956 ssid = wpa_config_get_network(wpa_s->conf, id);
958 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
959 "network id=%d", id);
964 wpa_supplicant_select_network(wpa_s, ssid);
970 static int wpa_supplicant_ctrl_iface_enable_network(
971 struct wpa_supplicant *wpa_s, char *cmd)
974 struct wpa_ssid *ssid;
976 /* cmd: "<network id>" or "all" */
977 if (os_strcmp(cmd, "all") == 0) {
978 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all");
982 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id);
984 ssid = wpa_config_get_network(wpa_s->conf, id);
986 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
987 "network id=%d", id);
991 wpa_supplicant_enable_network(wpa_s, ssid);
997 static int wpa_supplicant_ctrl_iface_disable_network(
998 struct wpa_supplicant *wpa_s, char *cmd)
1001 struct wpa_ssid *ssid;
1003 /* cmd: "<network id>" or "all" */
1004 if (os_strcmp(cmd, "all") == 0) {
1005 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all");
1009 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id);
1011 ssid = wpa_config_get_network(wpa_s->conf, id);
1013 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
1014 "network id=%d", id);
1018 wpa_supplicant_disable_network(wpa_s, ssid);
1024 static int wpa_supplicant_ctrl_iface_add_network(
1025 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
1027 struct wpa_ssid *ssid;
1030 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK");
1032 ssid = wpa_config_add_network(wpa_s->conf);
1036 wpas_notify_network_added(wpa_s, ssid);
1039 wpa_config_set_network_defaults(ssid);
1041 ret = os_snprintf(buf, buflen, "%d\n", ssid->id);
1042 if (ret < 0 || (size_t) ret >= buflen)
1048 static int wpa_supplicant_ctrl_iface_remove_network(
1049 struct wpa_supplicant *wpa_s, char *cmd)
1052 struct wpa_ssid *ssid;
1054 /* cmd: "<network id>" or "all" */
1055 if (os_strcmp(cmd, "all") == 0) {
1056 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all");
1057 ssid = wpa_s->conf->ssid;
1059 struct wpa_ssid *remove_ssid = ssid;
1062 wpas_notify_network_removed(wpa_s, remove_ssid);
1063 wpa_config_remove_network(wpa_s->conf, id);
1065 if (wpa_s->current_ssid) {
1066 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1067 wpa_supplicant_disassociate(wpa_s,
1068 WLAN_REASON_DEAUTH_LEAVING);
1074 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id);
1076 ssid = wpa_config_get_network(wpa_s->conf, id);
1078 wpa_config_remove_network(wpa_s->conf, id) < 0) {
1079 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1084 if (ssid == wpa_s->current_ssid) {
1086 * Invalidate the EAP session cache if the current network is
1089 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1091 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1098 static int wpa_supplicant_ctrl_iface_set_network(
1099 struct wpa_supplicant *wpa_s, char *cmd)
1102 struct wpa_ssid *ssid;
1105 /* cmd: "<network id> <variable name> <value>" */
1106 name = os_strchr(cmd, ' ');
1111 value = os_strchr(name, ' ');
1117 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
1119 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
1120 (u8 *) value, os_strlen(value));
1122 ssid = wpa_config_get_network(wpa_s->conf, id);
1124 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1129 if (wpa_config_set(ssid, name, value, 0) < 0) {
1130 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network "
1131 "variable '%s'", name);
1135 if (wpa_s->current_ssid == ssid) {
1137 * Invalidate the EAP session cache if anything in the current
1138 * configuration changes.
1140 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1143 if ((os_strcmp(name, "psk") == 0 &&
1144 value[0] == '"' && ssid->ssid_len) ||
1145 (os_strcmp(name, "ssid") == 0 && ssid->passphrase))
1146 wpa_config_update_psk(ssid);
1147 else if (os_strcmp(name, "priority") == 0)
1148 wpa_config_update_prio_list(wpa_s->conf);
1154 static int wpa_supplicant_ctrl_iface_get_network(
1155 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
1159 struct wpa_ssid *ssid;
1162 /* cmd: "<network id> <variable name>" */
1163 name = os_strchr(cmd, ' ');
1164 if (name == NULL || buflen == 0)
1169 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
1172 ssid = wpa_config_get_network(wpa_s->conf, id);
1174 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1179 value = wpa_config_get_no_key(ssid, name);
1180 if (value == NULL) {
1181 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network "
1182 "variable '%s'", name);
1186 res = os_strlcpy(buf, value, buflen);
1187 if (res >= buflen) {
1198 #ifndef CONFIG_NO_CONFIG_WRITE
1199 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s)
1203 if (!wpa_s->conf->update_config) {
1204 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
1205 "to update configuration (update_config=0)");
1209 ret = wpa_config_write(wpa_s->confname, wpa_s->conf);
1211 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to "
1212 "update configuration");
1214 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration"
1220 #endif /* CONFIG_NO_CONFIG_WRITE */
1223 static int ctrl_iface_get_capability_pairwise(int res, char *strict,
1224 struct wpa_driver_capa *capa,
1225 char *buf, size_t buflen)
1237 len = os_strlcpy(buf, "CCMP TKIP NONE", buflen);
1243 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1244 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " ");
1245 if (ret < 0 || ret >= end - pos)
1251 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1252 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " ");
1253 if (ret < 0 || ret >= end - pos)
1259 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1260 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : " ");
1261 if (ret < 0 || ret >= end - pos)
1271 static int ctrl_iface_get_capability_group(int res, char *strict,
1272 struct wpa_driver_capa *capa,
1273 char *buf, size_t buflen)
1285 len = os_strlcpy(buf, "CCMP TKIP WEP104 WEP40", buflen);
1291 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1292 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " ");
1293 if (ret < 0 || ret >= end - pos)
1299 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1300 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " ");
1301 if (ret < 0 || ret >= end - pos)
1307 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP104) {
1308 ret = os_snprintf(pos, end - pos, "%sWEP104",
1310 if (ret < 0 || ret >= end - pos)
1316 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP40) {
1317 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : " ");
1318 if (ret < 0 || ret >= end - pos)
1328 static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
1329 struct wpa_driver_capa *capa,
1330 char *buf, size_t buflen)
1342 len = os_strlcpy(buf, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE "
1349 ret = os_snprintf(pos, end - pos, "NONE IEEE8021X");
1350 if (ret < 0 || ret >= end - pos)
1354 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1355 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
1356 ret = os_snprintf(pos, end - pos, " WPA-EAP");
1357 if (ret < 0 || ret >= end - pos)
1362 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1363 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1364 ret = os_snprintf(pos, end - pos, " WPA-PSK");
1365 if (ret < 0 || ret >= end - pos)
1370 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1371 ret = os_snprintf(pos, end - pos, " WPA-NONE");
1372 if (ret < 0 || ret >= end - pos)
1381 static int ctrl_iface_get_capability_proto(int res, char *strict,
1382 struct wpa_driver_capa *capa,
1383 char *buf, size_t buflen)
1395 len = os_strlcpy(buf, "RSN WPA", buflen);
1401 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1402 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1403 ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " ");
1404 if (ret < 0 || ret >= end - pos)
1410 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1411 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
1412 ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " ");
1413 if (ret < 0 || ret >= end - pos)
1423 static int ctrl_iface_get_capability_auth_alg(int res, char *strict,
1424 struct wpa_driver_capa *capa,
1425 char *buf, size_t buflen)
1437 len = os_strlcpy(buf, "OPEN SHARED LEAP", buflen);
1443 if (capa->auth & (WPA_DRIVER_AUTH_OPEN)) {
1444 ret = os_snprintf(pos, end - pos, "%sOPEN", first ? "" : " ");
1445 if (ret < 0 || ret >= end - pos)
1451 if (capa->auth & (WPA_DRIVER_AUTH_SHARED)) {
1452 ret = os_snprintf(pos, end - pos, "%sSHARED",
1454 if (ret < 0 || ret >= end - pos)
1460 if (capa->auth & (WPA_DRIVER_AUTH_LEAP)) {
1461 ret = os_snprintf(pos, end - pos, "%sLEAP", first ? "" : " ");
1462 if (ret < 0 || ret >= end - pos)
1472 static int wpa_supplicant_ctrl_iface_get_capability(
1473 struct wpa_supplicant *wpa_s, const char *_field, char *buf,
1476 struct wpa_driver_capa capa;
1482 /* Determine whether or not strict checking was requested */
1483 len = os_strlcpy(field, _field, sizeof(field));
1484 if (len >= sizeof(field))
1486 strict = os_strchr(field, ' ');
1487 if (strict != NULL) {
1489 if (os_strcmp(strict, "strict") != 0)
1493 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
1494 field, strict ? strict : "");
1496 if (os_strcmp(field, "eap") == 0) {
1497 return eap_get_names(buf, buflen);
1500 res = wpa_drv_get_capa(wpa_s, &capa);
1502 if (os_strcmp(field, "pairwise") == 0)
1503 return ctrl_iface_get_capability_pairwise(res, strict, &capa,
1506 if (os_strcmp(field, "group") == 0)
1507 return ctrl_iface_get_capability_group(res, strict, &capa,
1510 if (os_strcmp(field, "key_mgmt") == 0)
1511 return ctrl_iface_get_capability_key_mgmt(res, strict, &capa,
1514 if (os_strcmp(field, "proto") == 0)
1515 return ctrl_iface_get_capability_proto(res, strict, &capa,
1518 if (os_strcmp(field, "auth_alg") == 0)
1519 return ctrl_iface_get_capability_auth_alg(res, strict, &capa,
1522 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
1529 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
1530 const char *cmd, char *buf,
1535 struct wpa_bss *bss;
1540 if (os_strcmp(cmd, "FIRST") == 0)
1541 bss = dl_list_first(&wpa_s->bss, struct wpa_bss, list);
1542 else if (os_strncmp(cmd, "ID-", 3) == 0) {
1544 bss = wpa_bss_get_id(wpa_s, i);
1545 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) {
1547 bss = wpa_bss_get_id(wpa_s, i);
1549 struct dl_list *next = bss->list_id.next;
1550 if (next == &wpa_s->bss_id)
1553 bss = dl_list_entry(next, struct wpa_bss,
1556 } else if (hwaddr_aton(cmd, bssid) == 0)
1557 bss = wpa_bss_get_bssid(wpa_s, bssid);
1559 struct wpa_bss *tmp;
1562 dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id)
1576 ret = os_snprintf(pos, end - pos,
1578 "bssid=" MACSTR "\n"
1581 "capabilities=0x%04x\n"
1588 MAC2STR(bss->bssid), bss->freq, bss->beacon_int,
1589 bss->caps, bss->qual, bss->noise, bss->level,
1590 (unsigned long long) bss->tsf);
1591 if (ret < 0 || ret >= end - pos)
1595 ie = (const u8 *) (bss + 1);
1596 for (i = 0; i < bss->ie_len; i++) {
1597 ret = os_snprintf(pos, end - pos, "%02x", *ie++);
1598 if (ret < 0 || ret >= end - pos)
1603 ret = os_snprintf(pos, end - pos, "\n");
1604 if (ret < 0 || ret >= end - pos)
1608 ret = os_snprintf(pos, end - pos, "flags=");
1609 if (ret < 0 || ret >= end - pos)
1613 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
1615 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
1616 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1618 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
1619 pos = wpa_supplicant_wps_ie_txt(pos, end, bss);
1620 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
1621 ret = os_snprintf(pos, end - pos, "[WEP]");
1622 if (ret < 0 || ret >= end - pos)
1626 if (bss->caps & IEEE80211_CAP_IBSS) {
1627 ret = os_snprintf(pos, end - pos, "[IBSS]");
1628 if (ret < 0 || ret >= end - pos)
1632 if (bss->caps & IEEE80211_CAP_ESS) {
1633 ret = os_snprintf(pos, end - pos, "[ESS]");
1634 if (ret < 0 || ret >= end - pos)
1639 ret = os_snprintf(pos, end - pos, "\n");
1640 if (ret < 0 || ret >= end - pos)
1644 ret = os_snprintf(pos, end - pos, "ssid=%s\n",
1645 wpa_ssid_txt(bss->ssid, bss->ssid_len));
1646 if (ret < 0 || ret >= end - pos)
1651 ie = (const u8 *) (bss + 1);
1652 ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end);
1653 if (ret < 0 || ret >= end - pos)
1656 #endif /* CONFIG_WPS */
1662 static int wpa_supplicant_ctrl_iface_ap_scan(
1663 struct wpa_supplicant *wpa_s, char *cmd)
1665 int ap_scan = atoi(cmd);
1666 return wpa_supplicant_set_ap_scan(wpa_s, ap_scan);
1670 static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s)
1672 u8 *bcast = (u8 *) "\xff\xff\xff\xff\xff\xff";
1674 wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication");
1675 /* MLME-DELETEKEYS.request */
1676 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 0, 0, NULL, 0, NULL, 0);
1677 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 1, 0, NULL, 0, NULL, 0);
1678 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 2, 0, NULL, 0, NULL, 0);
1679 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 3, 0, NULL, 0, NULL, 0);
1680 #ifdef CONFIG_IEEE80211W
1681 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 4, 0, NULL, 0, NULL, 0);
1682 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 5, 0, NULL, 0, NULL, 0);
1683 #endif /* CONFIG_IEEE80211W */
1685 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL,
1687 /* MLME-SETPROTECTION.request(None) */
1688 wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid,
1689 MLME_SETPROTECTION_PROTECT_TYPE_NONE,
1690 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
1691 wpa_sm_drop_sa(wpa_s->wpa);
1695 static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s,
1699 struct wpa_bss *bss;
1700 struct wpa_ssid *ssid = wpa_s->current_ssid;
1702 if (hwaddr_aton(addr, bssid)) {
1703 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid "
1704 "address '%s'", addr);
1708 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM " MACSTR, MAC2STR(bssid));
1710 bss = wpa_bss_get_bssid(wpa_s, bssid);
1712 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: Target AP not found "
1718 * TODO: Find best network configuration block from configuration to
1719 * allow roaming to other networks
1723 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: No network "
1724 "configuration known for the target AP");
1728 wpa_s->reassociate = 1;
1729 wpa_supplicant_connect(wpa_s, bss, ssid);
1735 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
1736 char *buf, size_t *resp_len)
1739 const int reply_size = 2048;
1743 if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 ||
1744 os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
1745 wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface",
1746 (const u8 *) buf, os_strlen(buf));
1748 wpa_hexdump_ascii(MSG_DEBUG, "RX ctrl_iface",
1749 (const u8 *) buf, os_strlen(buf));
1752 reply = os_malloc(reply_size);
1753 if (reply == NULL) {
1758 os_memcpy(reply, "OK\n", 3);
1761 if (os_strcmp(buf, "PING") == 0) {
1762 os_memcpy(reply, "PONG\n", 5);
1764 } else if (os_strncmp(buf, "NOTE ", 5) == 0) {
1765 wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
1766 } else if (os_strcmp(buf, "MIB") == 0) {
1767 reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
1768 if (reply_len >= 0) {
1770 res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len,
1771 reply_size - reply_len);
1777 } else if (os_strncmp(buf, "STATUS", 6) == 0) {
1778 reply_len = wpa_supplicant_ctrl_iface_status(
1779 wpa_s, buf + 6, reply, reply_size);
1780 } else if (os_strcmp(buf, "PMKSA") == 0) {
1781 reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, reply,
1783 } else if (os_strncmp(buf, "SET ", 4) == 0) {
1784 if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4))
1786 } else if (os_strcmp(buf, "LOGON") == 0) {
1787 eapol_sm_notify_logoff(wpa_s->eapol, FALSE);
1788 } else if (os_strcmp(buf, "LOGOFF") == 0) {
1789 eapol_sm_notify_logoff(wpa_s->eapol, TRUE);
1790 } else if (os_strcmp(buf, "REASSOCIATE") == 0) {
1791 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
1794 wpa_s->disconnected = 0;
1795 wpa_s->reassociate = 1;
1796 wpa_supplicant_req_scan(wpa_s, 0, 0);
1798 } else if (os_strcmp(buf, "RECONNECT") == 0) {
1799 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
1801 else if (wpa_s->disconnected) {
1802 wpa_s->disconnected = 0;
1803 wpa_s->reassociate = 1;
1804 wpa_supplicant_req_scan(wpa_s, 0, 0);
1806 #ifdef IEEE8021X_EAPOL
1807 } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) {
1808 if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8))
1810 #endif /* IEEE8021X_EAPOL */
1811 #ifdef CONFIG_PEERKEY
1812 } else if (os_strncmp(buf, "STKSTART ", 9) == 0) {
1813 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9))
1815 #endif /* CONFIG_PEERKEY */
1816 #ifdef CONFIG_IEEE80211R
1817 } else if (os_strncmp(buf, "FT_DS ", 6) == 0) {
1818 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6))
1820 #endif /* CONFIG_IEEE80211R */
1822 } else if (os_strcmp(buf, "WPS_PBC") == 0) {
1823 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, NULL))
1825 } else if (os_strncmp(buf, "WPS_PBC ", 8) == 0) {
1826 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, buf + 8))
1828 } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
1829 reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8,
1832 #ifdef CONFIG_WPS_OOB
1833 } else if (os_strncmp(buf, "WPS_OOB ", 8) == 0) {
1834 if (wpa_supplicant_ctrl_iface_wps_oob(wpa_s, buf + 8))
1836 #endif /* CONFIG_WPS_OOB */
1837 } else if (os_strncmp(buf, "WPS_REG ", 8) == 0) {
1838 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8))
1840 #ifdef CONFIG_WPS_ER
1841 } else if (os_strcmp(buf, "WPS_ER_START") == 0) {
1842 if (wpas_wps_er_start(wpa_s, NULL))
1844 } else if (os_strncmp(buf, "WPS_ER_START ", 13) == 0) {
1845 if (wpas_wps_er_start(wpa_s, buf + 13))
1847 } else if (os_strcmp(buf, "WPS_ER_STOP") == 0) {
1848 if (wpas_wps_er_stop(wpa_s))
1850 } else if (os_strncmp(buf, "WPS_ER_PIN ", 11) == 0) {
1851 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s, buf + 11))
1853 } else if (os_strncmp(buf, "WPS_ER_PBC ", 11) == 0) {
1854 if (wpas_wps_er_pbc(wpa_s, buf + 11))
1856 } else if (os_strncmp(buf, "WPS_ER_LEARN ", 13) == 0) {
1857 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s, buf + 13))
1859 } else if (os_strncmp(buf, "WPS_ER_CONFIG ", 14) == 0) {
1860 if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s, buf + 14))
1862 #endif /* CONFIG_WPS_ER */
1863 #endif /* CONFIG_WPS */
1864 #ifdef CONFIG_IBSS_RSN
1865 } else if (os_strncmp(buf, "IBSS_RSN ", 9) == 0) {
1866 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s, buf + 9))
1868 #endif /* CONFIG_IBSS_RSN */
1869 } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0)
1871 if (wpa_supplicant_ctrl_iface_ctrl_rsp(
1872 wpa_s, buf + os_strlen(WPA_CTRL_RSP)))
1876 } else if (os_strcmp(buf, "RECONFIGURE") == 0) {
1877 if (wpa_supplicant_reload_configuration(wpa_s))
1879 } else if (os_strcmp(buf, "TERMINATE") == 0) {
1880 wpa_supplicant_terminate_proc(wpa_s->global);
1881 } else if (os_strncmp(buf, "BSSID ", 6) == 0) {
1882 if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6))
1884 } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) {
1885 reply_len = wpa_supplicant_ctrl_iface_list_networks(
1886 wpa_s, reply, reply_size);
1887 } else if (os_strcmp(buf, "DISCONNECT") == 0) {
1888 wpa_s->reassociate = 0;
1889 wpa_s->disconnected = 1;
1890 wpa_supplicant_deauthenticate(wpa_s,
1891 WLAN_REASON_DEAUTH_LEAVING);
1892 } else if (os_strcmp(buf, "SCAN") == 0) {
1893 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
1896 wpa_s->scan_req = 2;
1897 wpa_supplicant_req_scan(wpa_s, 0, 0);
1899 } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) {
1900 reply_len = wpa_supplicant_ctrl_iface_scan_results(
1901 wpa_s, reply, reply_size);
1902 } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) {
1903 if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15))
1905 } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) {
1906 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15))
1908 } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) {
1909 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16))
1911 } else if (os_strcmp(buf, "ADD_NETWORK") == 0) {
1912 reply_len = wpa_supplicant_ctrl_iface_add_network(
1913 wpa_s, reply, reply_size);
1914 } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) {
1915 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15))
1917 } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
1918 if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12))
1920 } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
1921 reply_len = wpa_supplicant_ctrl_iface_get_network(
1922 wpa_s, buf + 12, reply, reply_size);
1923 #ifndef CONFIG_NO_CONFIG_WRITE
1924 } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
1925 if (wpa_supplicant_ctrl_iface_save_config(wpa_s))
1927 #endif /* CONFIG_NO_CONFIG_WRITE */
1928 } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
1929 reply_len = wpa_supplicant_ctrl_iface_get_capability(
1930 wpa_s, buf + 15, reply, reply_size);
1931 } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) {
1932 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8))
1934 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
1935 reply_len = wpa_supplicant_global_iface_list(
1936 wpa_s->global, reply, reply_size);
1937 } else if (os_strcmp(buf, "INTERFACES") == 0) {
1938 reply_len = wpa_supplicant_global_iface_interfaces(
1939 wpa_s->global, reply, reply_size);
1940 } else if (os_strncmp(buf, "BSS ", 4) == 0) {
1941 reply_len = wpa_supplicant_ctrl_iface_bss(
1942 wpa_s, buf + 4, reply, reply_size);
1944 } else if (os_strcmp(buf, "STA-FIRST") == 0) {
1945 reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
1946 } else if (os_strncmp(buf, "STA ", 4) == 0) {
1947 reply_len = ap_ctrl_iface_sta(wpa_s, buf + 4, reply,
1949 } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
1950 reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
1952 #endif /* CONFIG_AP */
1953 } else if (os_strcmp(buf, "SUSPEND") == 0) {
1954 wpas_notify_suspend(wpa_s->global);
1955 } else if (os_strcmp(buf, "RESUME") == 0) {
1956 wpas_notify_resume(wpa_s->global);
1957 } else if (os_strcmp(buf, "DROP_SA") == 0) {
1958 wpa_supplicant_ctrl_iface_drop_sa(wpa_s);
1959 } else if (os_strncmp(buf, "ROAM ", 5) == 0) {
1960 if (wpa_supplicant_ctrl_iface_roam(wpa_s, buf + 5))
1963 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
1967 if (reply_len < 0) {
1968 os_memcpy(reply, "FAIL\n", 5);
1973 eapol_sm_notify_ctrl_response(wpa_s->eapol);
1975 *resp_len = reply_len;
1980 static int wpa_supplicant_global_iface_add(struct wpa_global *global,
1983 struct wpa_interface iface;
1987 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
1988 * TAB<bridge_ifname>
1990 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd);
1992 os_memset(&iface, 0, sizeof(iface));
1995 iface.ifname = pos = cmd;
1996 pos = os_strchr(pos, '\t');
1999 if (iface.ifname[0] == '\0')
2004 iface.confname = pos;
2005 pos = os_strchr(pos, '\t');
2008 if (iface.confname[0] == '\0')
2009 iface.confname = NULL;
2014 pos = os_strchr(pos, '\t');
2017 if (iface.driver[0] == '\0')
2018 iface.driver = NULL;
2022 iface.ctrl_interface = pos;
2023 pos = os_strchr(pos, '\t');
2026 if (iface.ctrl_interface[0] == '\0')
2027 iface.ctrl_interface = NULL;
2031 iface.driver_param = pos;
2032 pos = os_strchr(pos, '\t');
2035 if (iface.driver_param[0] == '\0')
2036 iface.driver_param = NULL;
2040 iface.bridge_ifname = pos;
2041 pos = os_strchr(pos, '\t');
2044 if (iface.bridge_ifname[0] == '\0')
2045 iface.bridge_ifname = NULL;
2050 if (wpa_supplicant_get_iface(global, iface.ifname))
2053 return wpa_supplicant_add_iface(global, &iface) ? 0 : -1;
2057 static int wpa_supplicant_global_iface_remove(struct wpa_global *global,
2060 struct wpa_supplicant *wpa_s;
2062 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd);
2064 wpa_s = wpa_supplicant_get_iface(global, cmd);
2067 return wpa_supplicant_remove_iface(global, wpa_s);
2071 static void wpa_free_iface_info(struct wpa_interface_info *iface)
2073 struct wpa_interface_info *prev;
2077 iface = iface->next;
2079 os_free(prev->ifname);
2080 os_free(prev->desc);
2086 static int wpa_supplicant_global_iface_list(struct wpa_global *global,
2090 struct wpa_interface_info *iface = NULL, *last = NULL, *tmp;
2093 for (i = 0; wpa_drivers[i]; i++) {
2094 struct wpa_driver_ops *drv = wpa_drivers[i];
2095 if (drv->get_interfaces == NULL)
2097 tmp = drv->get_interfaces(global->drv_priv[i]);
2111 for (tmp = iface; tmp; tmp = tmp->next) {
2112 res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n",
2113 tmp->drv_name, tmp->ifname,
2114 tmp->desc ? tmp->desc : "");
2115 if (res < 0 || res >= end - pos) {
2122 wpa_free_iface_info(iface);
2128 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
2133 struct wpa_supplicant *wpa_s;
2135 wpa_s = global->ifaces;
2140 res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname);
2141 if (res < 0 || res >= end - pos) {
2146 wpa_s = wpa_s->next;
2152 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
2153 char *buf, size_t *resp_len)
2156 const int reply_size = 2048;
2159 wpa_hexdump_ascii(MSG_DEBUG, "RX global ctrl_iface",
2160 (const u8 *) buf, os_strlen(buf));
2162 reply = os_malloc(reply_size);
2163 if (reply == NULL) {
2168 os_memcpy(reply, "OK\n", 3);
2171 if (os_strcmp(buf, "PING") == 0) {
2172 os_memcpy(reply, "PONG\n", 5);
2174 } else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) {
2175 if (wpa_supplicant_global_iface_add(global, buf + 14))
2177 } else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) {
2178 if (wpa_supplicant_global_iface_remove(global, buf + 17))
2180 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
2181 reply_len = wpa_supplicant_global_iface_list(
2182 global, reply, reply_size);
2183 } else if (os_strcmp(buf, "INTERFACES") == 0) {
2184 reply_len = wpa_supplicant_global_iface_interfaces(
2185 global, reply, reply_size);
2186 } else if (os_strcmp(buf, "TERMINATE") == 0) {
2187 wpa_supplicant_terminate_proc(global);
2188 } else if (os_strcmp(buf, "SUSPEND") == 0) {
2189 wpas_notify_suspend(global);
2190 } else if (os_strcmp(buf, "RESUME") == 0) {
2191 wpas_notify_resume(global);
2193 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
2197 if (reply_len < 0) {
2198 os_memcpy(reply, "FAIL\n", 5);
2202 *resp_len = reply_len;