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)))
83 } else if (os_strcasecmp(cmd, "wps_fragment_size") == 0) {
84 wpa_s->wps_fragment_size = atoi(value);
87 ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
89 wpa_supplicant_update_config(wpa_s);
96 #ifdef IEEE8021X_EAPOL
97 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s,
101 struct wpa_ssid *ssid = wpa_s->current_ssid;
103 if (hwaddr_aton(addr, bssid)) {
104 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address "
109 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid));
110 rsn_preauth_deinit(wpa_s->wpa);
111 if (rsn_preauth_init(wpa_s->wpa, bssid, ssid ? &ssid->eap : NULL))
116 #endif /* IEEE8021X_EAPOL */
119 #ifdef CONFIG_PEERKEY
120 /* MLME-STKSTART.request(peer) */
121 static int wpa_supplicant_ctrl_iface_stkstart(
122 struct wpa_supplicant *wpa_s, char *addr)
126 if (hwaddr_aton(addr, peer)) {
127 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid "
128 "address '%s'", addr);
132 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART " MACSTR,
135 return wpa_sm_stkstart(wpa_s->wpa, peer);
137 #endif /* CONFIG_PEERKEY */
140 #ifdef CONFIG_IEEE80211R
141 static int wpa_supplicant_ctrl_iface_ft_ds(
142 struct wpa_supplicant *wpa_s, char *addr)
144 u8 target_ap[ETH_ALEN];
148 if (hwaddr_aton(addr, target_ap)) {
149 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS: invalid "
150 "address '%s'", addr);
154 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS " MACSTR, MAC2STR(target_ap));
156 bss = wpa_bss_get_bssid(wpa_s, target_ap);
158 mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
162 return wpa_ft_start_over_ds(wpa_s->wpa, target_ap, mdie);
164 #endif /* CONFIG_IEEE80211R */
168 static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
171 u8 bssid[ETH_ALEN], *_bssid = bssid;
173 if (cmd == NULL || os_strcmp(cmd, "any") == 0)
175 else if (hwaddr_aton(cmd, bssid)) {
176 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
183 return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid);
184 #endif /* CONFIG_AP */
186 return wpas_wps_start_pbc(wpa_s, _bssid);
190 static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
191 char *cmd, char *buf,
194 u8 bssid[ETH_ALEN], *_bssid = bssid;
198 pin = os_strchr(cmd, ' ');
202 if (os_strcmp(cmd, "any") == 0)
204 else if (hwaddr_aton(cmd, bssid)) {
205 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
212 return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin,
214 #endif /* CONFIG_AP */
217 ret = wpas_wps_start_pin(wpa_s, _bssid, pin);
220 ret = os_snprintf(buf, buflen, "%s", pin);
221 if (ret < 0 || (size_t) ret >= buflen)
226 ret = wpas_wps_start_pin(wpa_s, _bssid, NULL);
230 /* Return the generated PIN */
231 ret = os_snprintf(buf, buflen, "%08d", ret);
232 if (ret < 0 || (size_t) ret >= buflen)
238 #ifdef CONFIG_WPS_OOB
239 static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant *wpa_s,
242 char *path, *method, *name;
244 path = os_strchr(cmd, ' ');
249 method = os_strchr(path, ' ');
254 name = os_strchr(method, ' ');
258 return wpas_wps_start_oob(wpa_s, cmd, path, method, name);
260 #endif /* CONFIG_WPS_OOB */
263 static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s,
266 u8 bssid[ETH_ALEN], *_bssid = bssid;
272 struct wps_new_ap_settings ap;
274 pin = os_strchr(cmd, ' ');
279 if (os_strcmp(cmd, "any") == 0)
281 else if (hwaddr_aton(cmd, bssid)) {
282 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_REG: invalid BSSID '%s'",
287 new_ssid = os_strchr(pin, ' ');
288 if (new_ssid == NULL)
289 return wpas_wps_start_reg(wpa_s, _bssid, pin, NULL);
292 new_auth = os_strchr(new_ssid, ' ');
293 if (new_auth == NULL)
297 new_encr = os_strchr(new_auth, ' ');
298 if (new_encr == NULL)
302 new_key = os_strchr(new_encr, ' ');
307 os_memset(&ap, 0, sizeof(ap));
308 ap.ssid_hex = new_ssid;
311 ap.key_hex = new_key;
312 return wpas_wps_start_reg(wpa_s, _bssid, pin, &ap);
317 static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant *wpa_s,
320 char *uuid = cmd, *pin, *pos;
321 u8 addr_buf[ETH_ALEN], *addr = NULL;
322 pin = os_strchr(uuid, ' ');
326 pos = os_strchr(pin, ' ');
329 if (hwaddr_aton(pos, addr_buf) == 0)
332 return wpas_wps_er_add_pin(wpa_s, addr, uuid, pin);
336 static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant *wpa_s,
339 char *uuid = cmd, *pin;
340 pin = os_strchr(uuid, ' ');
344 return wpas_wps_er_learn(wpa_s, uuid, pin);
348 static int wpa_supplicant_ctrl_iface_wps_er_config(
349 struct wpa_supplicant *wpa_s, char *cmd)
356 struct wps_new_ap_settings ap;
358 pin = os_strchr(cmd, ' ');
363 new_ssid = os_strchr(pin, ' ');
364 if (new_ssid == NULL)
368 new_auth = os_strchr(new_ssid, ' ');
369 if (new_auth == NULL)
373 new_encr = os_strchr(new_auth, ' ');
374 if (new_encr == NULL)
378 new_key = os_strchr(new_encr, ' ');
383 os_memset(&ap, 0, sizeof(ap));
384 ap.ssid_hex = new_ssid;
387 ap.key_hex = new_key;
388 return wpas_wps_er_config(wpa_s, cmd, pin, &ap);
390 #endif /* CONFIG_WPS_ER */
392 #endif /* CONFIG_WPS */
395 #ifdef CONFIG_IBSS_RSN
396 static int wpa_supplicant_ctrl_iface_ibss_rsn(
397 struct wpa_supplicant *wpa_s, char *addr)
401 if (hwaddr_aton(addr, peer)) {
402 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN: invalid "
403 "address '%s'", addr);
407 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN " MACSTR,
410 return ibss_rsn_start(wpa_s->ibss_rsn, peer);
412 #endif /* CONFIG_IBSS_RSN */
415 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
418 #ifdef IEEE8021X_EAPOL
421 struct wpa_ssid *ssid;
422 struct eap_peer_config *eap;
424 pos = os_strchr(rsp, '-');
429 pos = os_strchr(pos, ':');
434 wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id);
435 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
436 (u8 *) pos, os_strlen(pos));
438 ssid = wpa_config_get_network(wpa_s->conf, id);
440 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
446 if (os_strcmp(rsp, "IDENTITY") == 0) {
447 os_free(eap->identity);
448 eap->identity = (u8 *) os_strdup(pos);
449 eap->identity_len = os_strlen(pos);
450 eap->pending_req_identity = 0;
451 if (ssid == wpa_s->current_ssid)
452 wpa_s->reassociate = 1;
453 } else if (os_strcmp(rsp, "PASSWORD") == 0) {
454 os_free(eap->password);
455 eap->password = (u8 *) os_strdup(pos);
456 eap->password_len = os_strlen(pos);
457 eap->pending_req_password = 0;
458 if (ssid == wpa_s->current_ssid)
459 wpa_s->reassociate = 1;
460 } else if (os_strcmp(rsp, "NEW_PASSWORD") == 0) {
461 os_free(eap->new_password);
462 eap->new_password = (u8 *) os_strdup(pos);
463 eap->new_password_len = os_strlen(pos);
464 eap->pending_req_new_password = 0;
465 if (ssid == wpa_s->current_ssid)
466 wpa_s->reassociate = 1;
467 } else if (os_strcmp(rsp, "PIN") == 0) {
469 eap->pin = os_strdup(pos);
470 eap->pending_req_pin = 0;
471 if (ssid == wpa_s->current_ssid)
472 wpa_s->reassociate = 1;
473 } else if (os_strcmp(rsp, "OTP") == 0) {
475 eap->otp = (u8 *) os_strdup(pos);
476 eap->otp_len = os_strlen(pos);
477 os_free(eap->pending_req_otp);
478 eap->pending_req_otp = NULL;
479 eap->pending_req_otp_len = 0;
480 } else if (os_strcmp(rsp, "PASSPHRASE") == 0) {
481 os_free(eap->private_key_passwd);
482 eap->private_key_passwd = (u8 *) os_strdup(pos);
483 eap->pending_req_passphrase = 0;
484 if (ssid == wpa_s->current_ssid)
485 wpa_s->reassociate = 1;
487 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", rsp);
492 #else /* IEEE8021X_EAPOL */
493 wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
495 #endif /* IEEE8021X_EAPOL */
499 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
501 char *buf, size_t buflen)
503 char *pos, *end, tmp[30];
504 int res, verbose, ret;
506 verbose = os_strcmp(params, "-VERBOSE") == 0;
509 if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
510 struct wpa_ssid *ssid = wpa_s->current_ssid;
511 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
512 MAC2STR(wpa_s->bssid));
513 if (ret < 0 || ret >= end - pos)
517 u8 *_ssid = ssid->ssid;
518 size_t ssid_len = ssid->ssid_len;
519 u8 ssid_buf[MAX_SSID_LEN];
521 int _res = wpa_drv_get_ssid(wpa_s, ssid_buf);
528 ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n",
529 wpa_ssid_txt(_ssid, ssid_len),
531 if (ret < 0 || ret >= end - pos)
536 ret = os_snprintf(pos, end - pos,
539 if (ret < 0 || ret >= end - pos)
544 switch (ssid->mode) {
545 case WPAS_MODE_INFRA:
546 ret = os_snprintf(pos, end - pos,
550 ret = os_snprintf(pos, end - pos,
554 ret = os_snprintf(pos, end - pos,
557 case WPAS_MODE_P2P_GO:
558 ret = os_snprintf(pos, end - pos,
561 case WPAS_MODE_P2P_GROUP_FORMATION:
562 ret = os_snprintf(pos, end - pos,
563 "mode=P2P GO - group "
570 if (ret < 0 || ret >= end - pos)
576 if (wpa_s->ap_iface) {
577 pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
581 #endif /* CONFIG_AP */
582 pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose);
584 ret = os_snprintf(pos, end - pos, "wpa_state=%s\n",
585 wpa_supplicant_state_txt(wpa_s->wpa_state));
586 if (ret < 0 || ret >= end - pos)
591 l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) {
592 ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp);
593 if (ret < 0 || ret >= end - pos)
598 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
599 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
600 res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos,
606 res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose);
614 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s,
619 struct wpa_ssid *ssid;
622 /* cmd: "<network id> <BSSID>" */
623 pos = os_strchr(cmd, ' ');
628 wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos);
629 if (hwaddr_aton(pos, bssid)) {
630 wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos);
634 ssid = wpa_config_get_network(wpa_s->conf, id);
636 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
641 os_memcpy(ssid->bssid, bssid, ETH_ALEN);
642 ssid->bssid_set = !is_zero_ether_addr(bssid);
648 static int wpa_supplicant_ctrl_iface_list_networks(
649 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
652 struct wpa_ssid *ssid;
657 ret = os_snprintf(pos, end - pos,
658 "network id / ssid / bssid / flags\n");
659 if (ret < 0 || ret >= end - pos)
663 ssid = wpa_s->conf->ssid;
665 ret = os_snprintf(pos, end - pos, "%d\t%s",
667 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
668 if (ret < 0 || ret >= end - pos)
671 if (ssid->bssid_set) {
672 ret = os_snprintf(pos, end - pos, "\t" MACSTR,
673 MAC2STR(ssid->bssid));
675 ret = os_snprintf(pos, end - pos, "\tany");
677 if (ret < 0 || ret >= end - pos)
680 ret = os_snprintf(pos, end - pos, "\t%s%s",
681 ssid == wpa_s->current_ssid ?
683 ssid->disabled ? "[DISABLED]" : "");
684 if (ret < 0 || ret >= end - pos)
687 ret = os_snprintf(pos, end - pos, "\n");
688 if (ret < 0 || ret >= end - pos)
699 static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher)
702 ret = os_snprintf(pos, end - pos, "-");
703 if (ret < 0 || ret >= end - pos)
706 if (cipher & WPA_CIPHER_NONE) {
707 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : "+");
708 if (ret < 0 || ret >= end - pos)
713 if (cipher & WPA_CIPHER_WEP40) {
714 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : "+");
715 if (ret < 0 || ret >= end - pos)
720 if (cipher & WPA_CIPHER_WEP104) {
721 ret = os_snprintf(pos, end - pos, "%sWEP104",
723 if (ret < 0 || ret >= end - pos)
728 if (cipher & WPA_CIPHER_TKIP) {
729 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : "+");
730 if (ret < 0 || ret >= end - pos)
735 if (cipher & WPA_CIPHER_CCMP) {
736 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : "+");
737 if (ret < 0 || ret >= end - pos)
746 static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
747 const u8 *ie, size_t ie_len)
749 struct wpa_ie_data data;
752 ret = os_snprintf(pos, end - pos, "[%s-", proto);
753 if (ret < 0 || ret >= end - pos)
757 if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) {
758 ret = os_snprintf(pos, end - pos, "?]");
759 if (ret < 0 || ret >= end - pos)
766 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
767 ret = os_snprintf(pos, end - pos, "%sEAP", first ? "" : "+");
768 if (ret < 0 || ret >= end - pos)
773 if (data.key_mgmt & WPA_KEY_MGMT_PSK) {
774 ret = os_snprintf(pos, end - pos, "%sPSK", first ? "" : "+");
775 if (ret < 0 || ret >= end - pos)
780 if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
781 ret = os_snprintf(pos, end - pos, "%sNone", first ? "" : "+");
782 if (ret < 0 || ret >= end - pos)
787 #ifdef CONFIG_IEEE80211R
788 if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
789 ret = os_snprintf(pos, end - pos, "%sFT/EAP",
791 if (ret < 0 || ret >= end - pos)
796 if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) {
797 ret = os_snprintf(pos, end - pos, "%sFT/PSK",
799 if (ret < 0 || ret >= end - pos)
804 #endif /* CONFIG_IEEE80211R */
805 #ifdef CONFIG_IEEE80211W
806 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
807 ret = os_snprintf(pos, end - pos, "%sEAP-SHA256",
809 if (ret < 0 || ret >= end - pos)
814 if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
815 ret = os_snprintf(pos, end - pos, "%sPSK-SHA256",
817 if (ret < 0 || ret >= end - pos)
822 #endif /* CONFIG_IEEE80211W */
824 pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher);
826 if (data.capabilities & WPA_CAPABILITY_PREAUTH) {
827 ret = os_snprintf(pos, end - pos, "-preauth");
828 if (ret < 0 || ret >= end - pos)
833 ret = os_snprintf(pos, end - pos, "]");
834 if (ret < 0 || ret >= end - pos)
843 static char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant *wpa_s,
844 char *pos, char *end,
845 struct wpabuf *wps_ie)
852 if (wps_is_selected_pbc_registrar(wps_ie))
855 else if (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 0))
857 #endif /* CONFIG_WPS2 */
858 else if (wps_is_selected_pin_registrar(wps_ie))
863 ret = os_snprintf(pos, end - pos, "%s", txt);
864 if (ret >= 0 && ret < end - pos)
869 #endif /* CONFIG_WPS */
872 static char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant *wpa_s,
873 char *pos, char *end,
874 const struct wpa_bss *bss)
877 struct wpabuf *wps_ie;
878 wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
879 return wpa_supplicant_wps_ie_txt_buf(wpa_s, pos, end, wps_ie);
880 #else /* CONFIG_WPS */
882 #endif /* CONFIG_WPS */
886 /* Format one result on one text line into a buffer. */
887 static int wpa_supplicant_ctrl_iface_scan_result(
888 struct wpa_supplicant *wpa_s,
889 const struct wpa_bss *bss, char *buf, size_t buflen)
898 ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t",
899 MAC2STR(bss->bssid), bss->freq, bss->level);
900 if (ret < 0 || ret >= end - pos)
903 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
905 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
906 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
908 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
909 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
910 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
911 ret = os_snprintf(pos, end - pos, "[WEP]");
912 if (ret < 0 || ret >= end - pos)
916 if (bss->caps & IEEE80211_CAP_IBSS) {
917 ret = os_snprintf(pos, end - pos, "[IBSS]");
918 if (ret < 0 || ret >= end - pos)
922 if (bss->caps & IEEE80211_CAP_ESS) {
923 ret = os_snprintf(pos, end - pos, "[ESS]");
924 if (ret < 0 || ret >= end - pos)
929 ret = os_snprintf(pos, end - pos, "\t%s",
930 wpa_ssid_txt(bss->ssid, bss->ssid_len));
931 if (ret < 0 || ret >= end - pos)
935 ret = os_snprintf(pos, end - pos, "\n");
936 if (ret < 0 || ret >= end - pos)
944 static int wpa_supplicant_ctrl_iface_scan_results(
945 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
953 ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / "
955 if (ret < 0 || ret >= end - pos)
959 dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
960 ret = wpa_supplicant_ctrl_iface_scan_result(wpa_s, bss, pos,
962 if (ret < 0 || ret >= end - pos)
971 static int wpa_supplicant_ctrl_iface_select_network(
972 struct wpa_supplicant *wpa_s, char *cmd)
975 struct wpa_ssid *ssid;
977 /* cmd: "<network id>" or "any" */
978 if (os_strcmp(cmd, "any") == 0) {
979 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any");
983 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id);
985 ssid = wpa_config_get_network(wpa_s->conf, id);
987 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
988 "network id=%d", id);
993 wpa_supplicant_select_network(wpa_s, ssid);
999 static int wpa_supplicant_ctrl_iface_enable_network(
1000 struct wpa_supplicant *wpa_s, char *cmd)
1003 struct wpa_ssid *ssid;
1005 /* cmd: "<network id>" or "all" */
1006 if (os_strcmp(cmd, "all") == 0) {
1007 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all");
1011 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id);
1013 ssid = wpa_config_get_network(wpa_s->conf, id);
1015 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
1016 "network id=%d", id);
1020 wpa_supplicant_enable_network(wpa_s, ssid);
1026 static int wpa_supplicant_ctrl_iface_disable_network(
1027 struct wpa_supplicant *wpa_s, char *cmd)
1030 struct wpa_ssid *ssid;
1032 /* cmd: "<network id>" or "all" */
1033 if (os_strcmp(cmd, "all") == 0) {
1034 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all");
1038 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id);
1040 ssid = wpa_config_get_network(wpa_s->conf, id);
1042 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
1043 "network id=%d", id);
1047 wpa_supplicant_disable_network(wpa_s, ssid);
1053 static int wpa_supplicant_ctrl_iface_add_network(
1054 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
1056 struct wpa_ssid *ssid;
1059 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK");
1061 ssid = wpa_config_add_network(wpa_s->conf);
1065 wpas_notify_network_added(wpa_s, ssid);
1068 wpa_config_set_network_defaults(ssid);
1070 ret = os_snprintf(buf, buflen, "%d\n", ssid->id);
1071 if (ret < 0 || (size_t) ret >= buflen)
1077 static int wpa_supplicant_ctrl_iface_remove_network(
1078 struct wpa_supplicant *wpa_s, char *cmd)
1081 struct wpa_ssid *ssid;
1083 /* cmd: "<network id>" or "all" */
1084 if (os_strcmp(cmd, "all") == 0) {
1085 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all");
1086 ssid = wpa_s->conf->ssid;
1088 struct wpa_ssid *remove_ssid = ssid;
1091 wpas_notify_network_removed(wpa_s, remove_ssid);
1092 wpa_config_remove_network(wpa_s->conf, id);
1094 if (wpa_s->current_ssid) {
1095 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1096 wpa_supplicant_disassociate(wpa_s,
1097 WLAN_REASON_DEAUTH_LEAVING);
1103 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id);
1105 ssid = wpa_config_get_network(wpa_s->conf, id);
1107 wpa_config_remove_network(wpa_s->conf, id) < 0) {
1108 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1113 if (ssid == wpa_s->current_ssid) {
1115 * Invalidate the EAP session cache if the current network is
1118 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1120 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1127 static int wpa_supplicant_ctrl_iface_set_network(
1128 struct wpa_supplicant *wpa_s, char *cmd)
1131 struct wpa_ssid *ssid;
1134 /* cmd: "<network id> <variable name> <value>" */
1135 name = os_strchr(cmd, ' ');
1140 value = os_strchr(name, ' ');
1146 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
1148 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
1149 (u8 *) value, os_strlen(value));
1151 ssid = wpa_config_get_network(wpa_s->conf, id);
1153 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1158 if (wpa_config_set(ssid, name, value, 0) < 0) {
1159 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network "
1160 "variable '%s'", name);
1164 if (wpa_s->current_ssid == ssid) {
1166 * Invalidate the EAP session cache if anything in the current
1167 * configuration changes.
1169 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1172 if ((os_strcmp(name, "psk") == 0 &&
1173 value[0] == '"' && ssid->ssid_len) ||
1174 (os_strcmp(name, "ssid") == 0 && ssid->passphrase))
1175 wpa_config_update_psk(ssid);
1176 else if (os_strcmp(name, "priority") == 0)
1177 wpa_config_update_prio_list(wpa_s->conf);
1183 static int wpa_supplicant_ctrl_iface_get_network(
1184 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
1188 struct wpa_ssid *ssid;
1191 /* cmd: "<network id> <variable name>" */
1192 name = os_strchr(cmd, ' ');
1193 if (name == NULL || buflen == 0)
1198 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
1201 ssid = wpa_config_get_network(wpa_s->conf, id);
1203 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1208 value = wpa_config_get_no_key(ssid, name);
1209 if (value == NULL) {
1210 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network "
1211 "variable '%s'", name);
1215 res = os_strlcpy(buf, value, buflen);
1216 if (res >= buflen) {
1227 #ifndef CONFIG_NO_CONFIG_WRITE
1228 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s)
1232 if (!wpa_s->conf->update_config) {
1233 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
1234 "to update configuration (update_config=0)");
1238 ret = wpa_config_write(wpa_s->confname, wpa_s->conf);
1240 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to "
1241 "update configuration");
1243 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration"
1249 #endif /* CONFIG_NO_CONFIG_WRITE */
1252 static int ctrl_iface_get_capability_pairwise(int res, char *strict,
1253 struct wpa_driver_capa *capa,
1254 char *buf, size_t buflen)
1266 len = os_strlcpy(buf, "CCMP TKIP NONE", buflen);
1272 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1273 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " ");
1274 if (ret < 0 || ret >= end - pos)
1280 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1281 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " ");
1282 if (ret < 0 || ret >= end - pos)
1288 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1289 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : " ");
1290 if (ret < 0 || ret >= end - pos)
1300 static int ctrl_iface_get_capability_group(int res, char *strict,
1301 struct wpa_driver_capa *capa,
1302 char *buf, size_t buflen)
1314 len = os_strlcpy(buf, "CCMP TKIP WEP104 WEP40", buflen);
1320 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1321 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " ");
1322 if (ret < 0 || ret >= end - pos)
1328 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1329 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " ");
1330 if (ret < 0 || ret >= end - pos)
1336 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP104) {
1337 ret = os_snprintf(pos, end - pos, "%sWEP104",
1339 if (ret < 0 || ret >= end - pos)
1345 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP40) {
1346 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : " ");
1347 if (ret < 0 || ret >= end - pos)
1357 static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
1358 struct wpa_driver_capa *capa,
1359 char *buf, size_t buflen)
1371 len = os_strlcpy(buf, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE "
1378 ret = os_snprintf(pos, end - pos, "NONE IEEE8021X");
1379 if (ret < 0 || ret >= end - pos)
1383 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1384 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
1385 ret = os_snprintf(pos, end - pos, " WPA-EAP");
1386 if (ret < 0 || ret >= end - pos)
1391 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1392 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1393 ret = os_snprintf(pos, end - pos, " WPA-PSK");
1394 if (ret < 0 || ret >= end - pos)
1399 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1400 ret = os_snprintf(pos, end - pos, " WPA-NONE");
1401 if (ret < 0 || ret >= end - pos)
1410 static int ctrl_iface_get_capability_proto(int res, char *strict,
1411 struct wpa_driver_capa *capa,
1412 char *buf, size_t buflen)
1424 len = os_strlcpy(buf, "RSN WPA", buflen);
1430 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1431 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1432 ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " ");
1433 if (ret < 0 || ret >= end - pos)
1439 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1440 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
1441 ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " ");
1442 if (ret < 0 || ret >= end - pos)
1452 static int ctrl_iface_get_capability_auth_alg(int res, char *strict,
1453 struct wpa_driver_capa *capa,
1454 char *buf, size_t buflen)
1466 len = os_strlcpy(buf, "OPEN SHARED LEAP", buflen);
1472 if (capa->auth & (WPA_DRIVER_AUTH_OPEN)) {
1473 ret = os_snprintf(pos, end - pos, "%sOPEN", first ? "" : " ");
1474 if (ret < 0 || ret >= end - pos)
1480 if (capa->auth & (WPA_DRIVER_AUTH_SHARED)) {
1481 ret = os_snprintf(pos, end - pos, "%sSHARED",
1483 if (ret < 0 || ret >= end - pos)
1489 if (capa->auth & (WPA_DRIVER_AUTH_LEAP)) {
1490 ret = os_snprintf(pos, end - pos, "%sLEAP", first ? "" : " ");
1491 if (ret < 0 || ret >= end - pos)
1501 static int wpa_supplicant_ctrl_iface_get_capability(
1502 struct wpa_supplicant *wpa_s, const char *_field, char *buf,
1505 struct wpa_driver_capa capa;
1511 /* Determine whether or not strict checking was requested */
1512 len = os_strlcpy(field, _field, sizeof(field));
1513 if (len >= sizeof(field))
1515 strict = os_strchr(field, ' ');
1516 if (strict != NULL) {
1518 if (os_strcmp(strict, "strict") != 0)
1522 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
1523 field, strict ? strict : "");
1525 if (os_strcmp(field, "eap") == 0) {
1526 return eap_get_names(buf, buflen);
1529 res = wpa_drv_get_capa(wpa_s, &capa);
1531 if (os_strcmp(field, "pairwise") == 0)
1532 return ctrl_iface_get_capability_pairwise(res, strict, &capa,
1535 if (os_strcmp(field, "group") == 0)
1536 return ctrl_iface_get_capability_group(res, strict, &capa,
1539 if (os_strcmp(field, "key_mgmt") == 0)
1540 return ctrl_iface_get_capability_key_mgmt(res, strict, &capa,
1543 if (os_strcmp(field, "proto") == 0)
1544 return ctrl_iface_get_capability_proto(res, strict, &capa,
1547 if (os_strcmp(field, "auth_alg") == 0)
1548 return ctrl_iface_get_capability_auth_alg(res, strict, &capa,
1551 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
1558 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
1559 const char *cmd, char *buf,
1564 struct wpa_bss *bss;
1569 if (os_strcmp(cmd, "FIRST") == 0)
1570 bss = dl_list_first(&wpa_s->bss, struct wpa_bss, list);
1571 else if (os_strncmp(cmd, "ID-", 3) == 0) {
1573 bss = wpa_bss_get_id(wpa_s, i);
1574 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) {
1576 bss = wpa_bss_get_id(wpa_s, i);
1578 struct dl_list *next = bss->list_id.next;
1579 if (next == &wpa_s->bss_id)
1582 bss = dl_list_entry(next, struct wpa_bss,
1585 } else if (hwaddr_aton(cmd, bssid) == 0)
1586 bss = wpa_bss_get_bssid(wpa_s, bssid);
1588 struct wpa_bss *tmp;
1591 dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id)
1605 ret = os_snprintf(pos, end - pos,
1607 "bssid=" MACSTR "\n"
1610 "capabilities=0x%04x\n"
1617 MAC2STR(bss->bssid), bss->freq, bss->beacon_int,
1618 bss->caps, bss->qual, bss->noise, bss->level,
1619 (unsigned long long) bss->tsf);
1620 if (ret < 0 || ret >= end - pos)
1624 ie = (const u8 *) (bss + 1);
1625 for (i = 0; i < bss->ie_len; i++) {
1626 ret = os_snprintf(pos, end - pos, "%02x", *ie++);
1627 if (ret < 0 || ret >= end - pos)
1632 ret = os_snprintf(pos, end - pos, "\n");
1633 if (ret < 0 || ret >= end - pos)
1637 ret = os_snprintf(pos, end - pos, "flags=");
1638 if (ret < 0 || ret >= end - pos)
1642 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
1644 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
1645 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1647 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
1648 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
1649 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
1650 ret = os_snprintf(pos, end - pos, "[WEP]");
1651 if (ret < 0 || ret >= end - pos)
1655 if (bss->caps & IEEE80211_CAP_IBSS) {
1656 ret = os_snprintf(pos, end - pos, "[IBSS]");
1657 if (ret < 0 || ret >= end - pos)
1661 if (bss->caps & IEEE80211_CAP_ESS) {
1662 ret = os_snprintf(pos, end - pos, "[ESS]");
1663 if (ret < 0 || ret >= end - pos)
1668 ret = os_snprintf(pos, end - pos, "\n");
1669 if (ret < 0 || ret >= end - pos)
1673 ret = os_snprintf(pos, end - pos, "ssid=%s\n",
1674 wpa_ssid_txt(bss->ssid, bss->ssid_len));
1675 if (ret < 0 || ret >= end - pos)
1680 ie = (const u8 *) (bss + 1);
1681 ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end);
1682 if (ret < 0 || ret >= end - pos)
1685 #endif /* CONFIG_WPS */
1691 static int wpa_supplicant_ctrl_iface_ap_scan(
1692 struct wpa_supplicant *wpa_s, char *cmd)
1694 int ap_scan = atoi(cmd);
1695 return wpa_supplicant_set_ap_scan(wpa_s, ap_scan);
1699 static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s)
1701 u8 *bcast = (u8 *) "\xff\xff\xff\xff\xff\xff";
1703 wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication");
1704 /* MLME-DELETEKEYS.request */
1705 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 0, 0, NULL, 0, NULL, 0);
1706 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 1, 0, NULL, 0, NULL, 0);
1707 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 2, 0, NULL, 0, NULL, 0);
1708 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 3, 0, NULL, 0, NULL, 0);
1709 #ifdef CONFIG_IEEE80211W
1710 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 4, 0, NULL, 0, NULL, 0);
1711 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 5, 0, NULL, 0, NULL, 0);
1712 #endif /* CONFIG_IEEE80211W */
1714 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL,
1716 /* MLME-SETPROTECTION.request(None) */
1717 wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid,
1718 MLME_SETPROTECTION_PROTECT_TYPE_NONE,
1719 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
1720 wpa_sm_drop_sa(wpa_s->wpa);
1724 static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s,
1728 struct wpa_bss *bss;
1729 struct wpa_ssid *ssid = wpa_s->current_ssid;
1731 if (hwaddr_aton(addr, bssid)) {
1732 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid "
1733 "address '%s'", addr);
1737 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM " MACSTR, MAC2STR(bssid));
1739 bss = wpa_bss_get_bssid(wpa_s, bssid);
1741 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: Target AP not found "
1747 * TODO: Find best network configuration block from configuration to
1748 * allow roaming to other networks
1752 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: No network "
1753 "configuration known for the target AP");
1757 wpa_s->reassociate = 1;
1758 wpa_supplicant_connect(wpa_s, bss, ssid);
1764 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
1765 char *buf, size_t *resp_len)
1768 const int reply_size = 2048;
1772 if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 ||
1773 os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
1774 wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface",
1775 (const u8 *) buf, os_strlen(buf));
1777 wpa_hexdump_ascii(MSG_DEBUG, "RX ctrl_iface",
1778 (const u8 *) buf, os_strlen(buf));
1781 reply = os_malloc(reply_size);
1782 if (reply == NULL) {
1787 os_memcpy(reply, "OK\n", 3);
1790 if (os_strcmp(buf, "PING") == 0) {
1791 os_memcpy(reply, "PONG\n", 5);
1793 } else if (os_strncmp(buf, "NOTE ", 5) == 0) {
1794 wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
1795 } else if (os_strcmp(buf, "MIB") == 0) {
1796 reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
1797 if (reply_len >= 0) {
1799 res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len,
1800 reply_size - reply_len);
1806 } else if (os_strncmp(buf, "STATUS", 6) == 0) {
1807 reply_len = wpa_supplicant_ctrl_iface_status(
1808 wpa_s, buf + 6, reply, reply_size);
1809 } else if (os_strcmp(buf, "PMKSA") == 0) {
1810 reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, reply,
1812 } else if (os_strncmp(buf, "SET ", 4) == 0) {
1813 if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4))
1815 } else if (os_strcmp(buf, "LOGON") == 0) {
1816 eapol_sm_notify_logoff(wpa_s->eapol, FALSE);
1817 } else if (os_strcmp(buf, "LOGOFF") == 0) {
1818 eapol_sm_notify_logoff(wpa_s->eapol, TRUE);
1819 } else if (os_strcmp(buf, "REASSOCIATE") == 0) {
1820 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
1823 wpa_s->disconnected = 0;
1824 wpa_s->reassociate = 1;
1825 wpa_supplicant_req_scan(wpa_s, 0, 0);
1827 } else if (os_strcmp(buf, "RECONNECT") == 0) {
1828 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
1830 else if (wpa_s->disconnected) {
1831 wpa_s->disconnected = 0;
1832 wpa_s->reassociate = 1;
1833 wpa_supplicant_req_scan(wpa_s, 0, 0);
1835 #ifdef IEEE8021X_EAPOL
1836 } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) {
1837 if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8))
1839 #endif /* IEEE8021X_EAPOL */
1840 #ifdef CONFIG_PEERKEY
1841 } else if (os_strncmp(buf, "STKSTART ", 9) == 0) {
1842 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9))
1844 #endif /* CONFIG_PEERKEY */
1845 #ifdef CONFIG_IEEE80211R
1846 } else if (os_strncmp(buf, "FT_DS ", 6) == 0) {
1847 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6))
1849 #endif /* CONFIG_IEEE80211R */
1851 } else if (os_strcmp(buf, "WPS_PBC") == 0) {
1852 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, NULL))
1854 } else if (os_strncmp(buf, "WPS_PBC ", 8) == 0) {
1855 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, buf + 8))
1857 } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
1858 reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8,
1861 #ifdef CONFIG_WPS_OOB
1862 } else if (os_strncmp(buf, "WPS_OOB ", 8) == 0) {
1863 if (wpa_supplicant_ctrl_iface_wps_oob(wpa_s, buf + 8))
1865 #endif /* CONFIG_WPS_OOB */
1866 } else if (os_strncmp(buf, "WPS_REG ", 8) == 0) {
1867 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8))
1869 #ifdef CONFIG_WPS_ER
1870 } else if (os_strcmp(buf, "WPS_ER_START") == 0) {
1871 if (wpas_wps_er_start(wpa_s, NULL))
1873 } else if (os_strncmp(buf, "WPS_ER_START ", 13) == 0) {
1874 if (wpas_wps_er_start(wpa_s, buf + 13))
1876 } else if (os_strcmp(buf, "WPS_ER_STOP") == 0) {
1877 if (wpas_wps_er_stop(wpa_s))
1879 } else if (os_strncmp(buf, "WPS_ER_PIN ", 11) == 0) {
1880 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s, buf + 11))
1882 } else if (os_strncmp(buf, "WPS_ER_PBC ", 11) == 0) {
1883 if (wpas_wps_er_pbc(wpa_s, buf + 11))
1885 } else if (os_strncmp(buf, "WPS_ER_LEARN ", 13) == 0) {
1886 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s, buf + 13))
1888 } else if (os_strncmp(buf, "WPS_ER_CONFIG ", 14) == 0) {
1889 if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s, buf + 14))
1891 #endif /* CONFIG_WPS_ER */
1892 #endif /* CONFIG_WPS */
1893 #ifdef CONFIG_IBSS_RSN
1894 } else if (os_strncmp(buf, "IBSS_RSN ", 9) == 0) {
1895 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s, buf + 9))
1897 #endif /* CONFIG_IBSS_RSN */
1898 } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0)
1900 if (wpa_supplicant_ctrl_iface_ctrl_rsp(
1901 wpa_s, buf + os_strlen(WPA_CTRL_RSP)))
1905 } else if (os_strcmp(buf, "RECONFIGURE") == 0) {
1906 if (wpa_supplicant_reload_configuration(wpa_s))
1908 } else if (os_strcmp(buf, "TERMINATE") == 0) {
1909 wpa_supplicant_terminate_proc(wpa_s->global);
1910 } else if (os_strncmp(buf, "BSSID ", 6) == 0) {
1911 if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6))
1913 } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) {
1914 reply_len = wpa_supplicant_ctrl_iface_list_networks(
1915 wpa_s, reply, reply_size);
1916 } else if (os_strcmp(buf, "DISCONNECT") == 0) {
1917 wpa_s->reassociate = 0;
1918 wpa_s->disconnected = 1;
1919 wpa_supplicant_deauthenticate(wpa_s,
1920 WLAN_REASON_DEAUTH_LEAVING);
1921 } else if (os_strcmp(buf, "SCAN") == 0) {
1922 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
1925 wpa_s->scan_req = 2;
1926 wpa_supplicant_req_scan(wpa_s, 0, 0);
1928 } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) {
1929 reply_len = wpa_supplicant_ctrl_iface_scan_results(
1930 wpa_s, reply, reply_size);
1931 } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) {
1932 if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15))
1934 } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) {
1935 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15))
1937 } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) {
1938 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16))
1940 } else if (os_strcmp(buf, "ADD_NETWORK") == 0) {
1941 reply_len = wpa_supplicant_ctrl_iface_add_network(
1942 wpa_s, reply, reply_size);
1943 } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) {
1944 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15))
1946 } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
1947 if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12))
1949 } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
1950 reply_len = wpa_supplicant_ctrl_iface_get_network(
1951 wpa_s, buf + 12, reply, reply_size);
1952 #ifndef CONFIG_NO_CONFIG_WRITE
1953 } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
1954 if (wpa_supplicant_ctrl_iface_save_config(wpa_s))
1956 #endif /* CONFIG_NO_CONFIG_WRITE */
1957 } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
1958 reply_len = wpa_supplicant_ctrl_iface_get_capability(
1959 wpa_s, buf + 15, reply, reply_size);
1960 } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) {
1961 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8))
1963 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
1964 reply_len = wpa_supplicant_global_iface_list(
1965 wpa_s->global, reply, reply_size);
1966 } else if (os_strcmp(buf, "INTERFACES") == 0) {
1967 reply_len = wpa_supplicant_global_iface_interfaces(
1968 wpa_s->global, reply, reply_size);
1969 } else if (os_strncmp(buf, "BSS ", 4) == 0) {
1970 reply_len = wpa_supplicant_ctrl_iface_bss(
1971 wpa_s, buf + 4, reply, reply_size);
1973 } else if (os_strcmp(buf, "STA-FIRST") == 0) {
1974 reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
1975 } else if (os_strncmp(buf, "STA ", 4) == 0) {
1976 reply_len = ap_ctrl_iface_sta(wpa_s, buf + 4, reply,
1978 } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
1979 reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
1981 #endif /* CONFIG_AP */
1982 } else if (os_strcmp(buf, "SUSPEND") == 0) {
1983 wpas_notify_suspend(wpa_s->global);
1984 } else if (os_strcmp(buf, "RESUME") == 0) {
1985 wpas_notify_resume(wpa_s->global);
1986 } else if (os_strcmp(buf, "DROP_SA") == 0) {
1987 wpa_supplicant_ctrl_iface_drop_sa(wpa_s);
1988 } else if (os_strncmp(buf, "ROAM ", 5) == 0) {
1989 if (wpa_supplicant_ctrl_iface_roam(wpa_s, buf + 5))
1992 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
1996 if (reply_len < 0) {
1997 os_memcpy(reply, "FAIL\n", 5);
2002 eapol_sm_notify_ctrl_response(wpa_s->eapol);
2004 *resp_len = reply_len;
2009 static int wpa_supplicant_global_iface_add(struct wpa_global *global,
2012 struct wpa_interface iface;
2016 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
2017 * TAB<bridge_ifname>
2019 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd);
2021 os_memset(&iface, 0, sizeof(iface));
2024 iface.ifname = pos = cmd;
2025 pos = os_strchr(pos, '\t');
2028 if (iface.ifname[0] == '\0')
2033 iface.confname = pos;
2034 pos = os_strchr(pos, '\t');
2037 if (iface.confname[0] == '\0')
2038 iface.confname = NULL;
2043 pos = os_strchr(pos, '\t');
2046 if (iface.driver[0] == '\0')
2047 iface.driver = NULL;
2051 iface.ctrl_interface = pos;
2052 pos = os_strchr(pos, '\t');
2055 if (iface.ctrl_interface[0] == '\0')
2056 iface.ctrl_interface = NULL;
2060 iface.driver_param = pos;
2061 pos = os_strchr(pos, '\t');
2064 if (iface.driver_param[0] == '\0')
2065 iface.driver_param = NULL;
2069 iface.bridge_ifname = pos;
2070 pos = os_strchr(pos, '\t');
2073 if (iface.bridge_ifname[0] == '\0')
2074 iface.bridge_ifname = NULL;
2079 if (wpa_supplicant_get_iface(global, iface.ifname))
2082 return wpa_supplicant_add_iface(global, &iface) ? 0 : -1;
2086 static int wpa_supplicant_global_iface_remove(struct wpa_global *global,
2089 struct wpa_supplicant *wpa_s;
2091 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd);
2093 wpa_s = wpa_supplicant_get_iface(global, cmd);
2096 return wpa_supplicant_remove_iface(global, wpa_s);
2100 static void wpa_free_iface_info(struct wpa_interface_info *iface)
2102 struct wpa_interface_info *prev;
2106 iface = iface->next;
2108 os_free(prev->ifname);
2109 os_free(prev->desc);
2115 static int wpa_supplicant_global_iface_list(struct wpa_global *global,
2119 struct wpa_interface_info *iface = NULL, *last = NULL, *tmp;
2122 for (i = 0; wpa_drivers[i]; i++) {
2123 struct wpa_driver_ops *drv = wpa_drivers[i];
2124 if (drv->get_interfaces == NULL)
2126 tmp = drv->get_interfaces(global->drv_priv[i]);
2140 for (tmp = iface; tmp; tmp = tmp->next) {
2141 res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n",
2142 tmp->drv_name, tmp->ifname,
2143 tmp->desc ? tmp->desc : "");
2144 if (res < 0 || res >= end - pos) {
2151 wpa_free_iface_info(iface);
2157 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
2162 struct wpa_supplicant *wpa_s;
2164 wpa_s = global->ifaces;
2169 res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname);
2170 if (res < 0 || res >= end - pos) {
2175 wpa_s = wpa_s->next;
2181 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
2182 char *buf, size_t *resp_len)
2185 const int reply_size = 2048;
2188 wpa_hexdump_ascii(MSG_DEBUG, "RX global ctrl_iface",
2189 (const u8 *) buf, os_strlen(buf));
2191 reply = os_malloc(reply_size);
2192 if (reply == NULL) {
2197 os_memcpy(reply, "OK\n", 3);
2200 if (os_strcmp(buf, "PING") == 0) {
2201 os_memcpy(reply, "PONG\n", 5);
2203 } else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) {
2204 if (wpa_supplicant_global_iface_add(global, buf + 14))
2206 } else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) {
2207 if (wpa_supplicant_global_iface_remove(global, buf + 17))
2209 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
2210 reply_len = wpa_supplicant_global_iface_list(
2211 global, reply, reply_size);
2212 } else if (os_strcmp(buf, "INTERFACES") == 0) {
2213 reply_len = wpa_supplicant_global_iface_interfaces(
2214 global, reply, reply_size);
2215 } else if (os_strcmp(buf, "TERMINATE") == 0) {
2216 wpa_supplicant_terminate_proc(global);
2217 } else if (os_strcmp(buf, "SUSPEND") == 0) {
2218 wpas_notify_suspend(global);
2219 } else if (os_strcmp(buf, "RESUME") == 0) {
2220 wpas_notify_resume(global);
2222 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
2226 if (reply_len < 0) {
2227 os_memcpy(reply, "FAIL\n", 5);
2231 *resp_len = reply_len;