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/version.h"
20 #include "common/ieee802_11_defs.h"
21 #include "common/wpa_ctrl.h"
22 #include "eap_peer/eap.h"
23 #include "eapol_supp/eapol_supp_sm.h"
24 #include "rsn_supp/wpa.h"
25 #include "rsn_supp/preauth.h"
26 #include "rsn_supp/pmksa_cache.h"
27 #include "l2_packet/l2_packet.h"
30 #include "wpa_supplicant_i.h"
32 #include "wps_supplicant.h"
35 #include "p2p_supplicant.h"
40 #include "ctrl_iface.h"
42 extern struct wpa_driver_ops *wpa_drivers[];
44 static int wpa_supplicant_global_iface_list(struct wpa_global *global,
46 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
50 static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
56 value = os_strchr(cmd, ' ');
61 wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value);
62 if (os_strcasecmp(cmd, "EAPOL::heldPeriod") == 0) {
63 eapol_sm_configure(wpa_s->eapol,
64 atoi(value), -1, -1, -1);
65 } else if (os_strcasecmp(cmd, "EAPOL::authPeriod") == 0) {
66 eapol_sm_configure(wpa_s->eapol,
67 -1, atoi(value), -1, -1);
68 } else if (os_strcasecmp(cmd, "EAPOL::startPeriod") == 0) {
69 eapol_sm_configure(wpa_s->eapol,
70 -1, -1, atoi(value), -1);
71 } else if (os_strcasecmp(cmd, "EAPOL::maxStart") == 0) {
72 eapol_sm_configure(wpa_s->eapol,
73 -1, -1, -1, atoi(value));
74 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) {
75 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
78 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") ==
80 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
83 } else if (os_strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) {
84 if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value)))
86 } else if (os_strcasecmp(cmd, "wps_fragment_size") == 0) {
87 wpa_s->wps_fragment_size = atoi(value);
88 #ifdef CONFIG_WPS_TESTING
89 } else if (os_strcasecmp(cmd, "wps_version_number") == 0) {
91 val = strtol(value, NULL, 0);
92 if (val < 0 || val > 0xff) {
94 wpa_printf(MSG_DEBUG, "WPS: Invalid "
95 "wps_version_number %ld", val);
97 wps_version_number = val;
98 wpa_printf(MSG_DEBUG, "WPS: Testing - force WPS "
100 (wps_version_number & 0xf0) >> 4,
101 wps_version_number & 0x0f);
103 } else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) {
104 wps_testing_dummy_cred = atoi(value);
105 wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d",
106 wps_testing_dummy_cred);
107 #endif /* CONFIG_WPS_TESTING */
108 } else if (os_strcasecmp(cmd, "ampdu") == 0) {
109 if (wpa_drv_ampdu(wpa_s, atoi(value)) < 0)
113 ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
115 wpa_supplicant_update_config(wpa_s);
122 static int wpa_supplicant_ctrl_iface_get(struct wpa_supplicant *wpa_s,
123 char *cmd, char *buf, size_t buflen)
127 wpa_printf(MSG_DEBUG, "CTRL_IFACE GET '%s'", cmd);
129 if (os_strcmp(cmd, "version") == 0) {
130 res = os_snprintf(buf, buflen, "%s", VERSION_STR);
131 if (res < 0 || (unsigned int) res >= buflen)
140 #ifdef IEEE8021X_EAPOL
141 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s,
145 struct wpa_ssid *ssid = wpa_s->current_ssid;
147 if (hwaddr_aton(addr, bssid)) {
148 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address "
153 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid));
154 rsn_preauth_deinit(wpa_s->wpa);
155 if (rsn_preauth_init(wpa_s->wpa, bssid, ssid ? &ssid->eap : NULL))
160 #endif /* IEEE8021X_EAPOL */
163 #ifdef CONFIG_PEERKEY
164 /* MLME-STKSTART.request(peer) */
165 static int wpa_supplicant_ctrl_iface_stkstart(
166 struct wpa_supplicant *wpa_s, char *addr)
170 if (hwaddr_aton(addr, peer)) {
171 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid "
172 "address '%s'", addr);
176 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART " MACSTR,
179 return wpa_sm_stkstart(wpa_s->wpa, peer);
181 #endif /* CONFIG_PEERKEY */
184 #ifdef CONFIG_IEEE80211R
185 static int wpa_supplicant_ctrl_iface_ft_ds(
186 struct wpa_supplicant *wpa_s, char *addr)
188 u8 target_ap[ETH_ALEN];
192 if (hwaddr_aton(addr, target_ap)) {
193 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS: invalid "
194 "address '%s'", addr);
198 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS " MACSTR, MAC2STR(target_ap));
200 bss = wpa_bss_get_bssid(wpa_s, target_ap);
202 mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
206 return wpa_ft_start_over_ds(wpa_s->wpa, target_ap, mdie);
208 #endif /* CONFIG_IEEE80211R */
212 static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
215 u8 bssid[ETH_ALEN], *_bssid = bssid;
216 u8 p2p_dev_addr[ETH_ALEN], *_p2p_dev_addr = NULL;
218 if (cmd == NULL || os_strcmp(cmd, "any") == 0) {
221 } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) {
222 if (hwaddr_aton(cmd + 13, p2p_dev_addr)) {
223 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid "
224 "P2P Device Address '%s'",
228 _p2p_dev_addr = p2p_dev_addr;
229 #endif /* CONFIG_P2P */
230 } else if (hwaddr_aton(cmd, bssid)) {
231 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
238 return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr);
239 #endif /* CONFIG_AP */
241 return wpas_wps_start_pbc(wpa_s, _bssid, 0);
245 static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
246 char *cmd, char *buf,
249 u8 bssid[ETH_ALEN], *_bssid = bssid;
253 pin = os_strchr(cmd, ' ');
257 if (os_strcmp(cmd, "any") == 0)
259 else if (hwaddr_aton(cmd, bssid)) {
260 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
267 return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin,
269 #endif /* CONFIG_AP */
272 ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0,
276 ret = os_snprintf(buf, buflen, "%s", pin);
277 if (ret < 0 || (size_t) ret >= buflen)
282 ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0, DEV_PW_DEFAULT);
286 /* Return the generated PIN */
287 ret = os_snprintf(buf, buflen, "%08d", ret);
288 if (ret < 0 || (size_t) ret >= buflen)
294 static int wpa_supplicant_ctrl_iface_wps_check_pin(
295 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
302 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS_CHECK_PIN",
303 (u8 *) cmd, os_strlen(cmd));
304 for (pos = cmd, len = 0; *pos != '\0'; pos++) {
305 if (*pos < '0' || *pos > '9')
309 wpa_printf(MSG_DEBUG, "WPS: Too long PIN");
313 if (len != 4 && len != 8) {
314 wpa_printf(MSG_DEBUG, "WPS: Invalid PIN length %d", (int) len);
320 unsigned int pin_val;
322 if (!wps_pin_valid(pin_val)) {
323 wpa_printf(MSG_DEBUG, "WPS: Invalid checksum digit");
324 ret = os_snprintf(buf, buflen, "FAIL-CHECKSUM\n");
325 if (ret < 0 || (size_t) ret >= buflen)
331 ret = os_snprintf(buf, buflen, "%s", pin);
332 if (ret < 0 || (size_t) ret >= buflen)
339 #ifdef CONFIG_WPS_OOB
340 static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant *wpa_s,
343 char *path, *method, *name;
345 path = os_strchr(cmd, ' ');
350 method = os_strchr(path, ' ');
355 name = os_strchr(method, ' ');
359 return wpas_wps_start_oob(wpa_s, cmd, path, method, name);
361 #endif /* CONFIG_WPS_OOB */
364 static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s,
373 struct wps_new_ap_settings ap;
375 pin = os_strchr(cmd, ' ');
380 if (hwaddr_aton(cmd, bssid)) {
381 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_REG: invalid BSSID '%s'",
386 new_ssid = os_strchr(pin, ' ');
387 if (new_ssid == NULL)
388 return wpas_wps_start_reg(wpa_s, bssid, pin, NULL);
391 new_auth = os_strchr(new_ssid, ' ');
392 if (new_auth == NULL)
396 new_encr = os_strchr(new_auth, ' ');
397 if (new_encr == NULL)
401 new_key = os_strchr(new_encr, ' ');
406 os_memset(&ap, 0, sizeof(ap));
407 ap.ssid_hex = new_ssid;
410 ap.key_hex = new_key;
411 return wpas_wps_start_reg(wpa_s, bssid, pin, &ap);
416 static int wpa_supplicant_ctrl_iface_wps_ap_pin(struct wpa_supplicant *wpa_s,
417 char *cmd, char *buf,
424 if (!wpa_s->ap_iface)
427 pos = os_strchr(cmd, ' ');
431 if (os_strcmp(cmd, "disable") == 0) {
432 wpas_wps_ap_pin_disable(wpa_s);
433 return os_snprintf(buf, buflen, "OK\n");
436 if (os_strcmp(cmd, "random") == 0) {
439 pin_txt = wpas_wps_ap_pin_random(wpa_s, timeout);
442 return os_snprintf(buf, buflen, "%s", pin_txt);
445 if (os_strcmp(cmd, "get") == 0) {
446 pin_txt = wpas_wps_ap_pin_get(wpa_s);
449 return os_snprintf(buf, buflen, "%s", pin_txt);
452 if (os_strcmp(cmd, "set") == 0) {
457 pos = os_strchr(pos, ' ');
462 if (os_strlen(pin) > buflen)
464 if (wpas_wps_ap_pin_set(wpa_s, pin, timeout) < 0)
466 return os_snprintf(buf, buflen, "%s", pin);
471 #endif /* CONFIG_AP */
475 static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant *wpa_s,
478 char *uuid = cmd, *pin, *pos;
479 u8 addr_buf[ETH_ALEN], *addr = NULL;
480 pin = os_strchr(uuid, ' ');
484 pos = os_strchr(pin, ' ');
487 if (hwaddr_aton(pos, addr_buf) == 0)
490 return wpas_wps_er_add_pin(wpa_s, addr, uuid, pin);
494 static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant *wpa_s,
497 char *uuid = cmd, *pin;
498 pin = os_strchr(uuid, ' ');
502 return wpas_wps_er_learn(wpa_s, uuid, pin);
506 static int wpa_supplicant_ctrl_iface_wps_er_set_config(
507 struct wpa_supplicant *wpa_s, char *cmd)
509 char *uuid = cmd, *id;
510 id = os_strchr(uuid, ' ');
514 return wpas_wps_er_set_config(wpa_s, uuid, atoi(id));
518 static int wpa_supplicant_ctrl_iface_wps_er_config(
519 struct wpa_supplicant *wpa_s, char *cmd)
526 struct wps_new_ap_settings ap;
528 pin = os_strchr(cmd, ' ');
533 new_ssid = os_strchr(pin, ' ');
534 if (new_ssid == NULL)
538 new_auth = os_strchr(new_ssid, ' ');
539 if (new_auth == NULL)
543 new_encr = os_strchr(new_auth, ' ');
544 if (new_encr == NULL)
548 new_key = os_strchr(new_encr, ' ');
553 os_memset(&ap, 0, sizeof(ap));
554 ap.ssid_hex = new_ssid;
557 ap.key_hex = new_key;
558 return wpas_wps_er_config(wpa_s, cmd, pin, &ap);
560 #endif /* CONFIG_WPS_ER */
562 #endif /* CONFIG_WPS */
565 #ifdef CONFIG_IBSS_RSN
566 static int wpa_supplicant_ctrl_iface_ibss_rsn(
567 struct wpa_supplicant *wpa_s, char *addr)
571 if (hwaddr_aton(addr, peer)) {
572 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN: invalid "
573 "address '%s'", addr);
577 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN " MACSTR,
580 return ibss_rsn_start(wpa_s->ibss_rsn, peer);
582 #endif /* CONFIG_IBSS_RSN */
585 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
588 #ifdef IEEE8021X_EAPOL
591 struct wpa_ssid *ssid;
592 struct eap_peer_config *eap;
594 pos = os_strchr(rsp, '-');
599 pos = os_strchr(pos, ':');
604 wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id);
605 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
606 (u8 *) pos, os_strlen(pos));
608 ssid = wpa_config_get_network(wpa_s->conf, id);
610 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
616 if (os_strcmp(rsp, "IDENTITY") == 0) {
617 os_free(eap->identity);
618 eap->identity = (u8 *) os_strdup(pos);
619 eap->identity_len = os_strlen(pos);
620 eap->pending_req_identity = 0;
621 if (ssid == wpa_s->current_ssid)
622 wpa_s->reassociate = 1;
623 } else if (os_strcmp(rsp, "PASSWORD") == 0) {
624 os_free(eap->password);
625 eap->password = (u8 *) os_strdup(pos);
626 eap->password_len = os_strlen(pos);
627 eap->pending_req_password = 0;
628 if (ssid == wpa_s->current_ssid)
629 wpa_s->reassociate = 1;
630 } else if (os_strcmp(rsp, "NEW_PASSWORD") == 0) {
631 os_free(eap->new_password);
632 eap->new_password = (u8 *) os_strdup(pos);
633 eap->new_password_len = os_strlen(pos);
634 eap->pending_req_new_password = 0;
635 if (ssid == wpa_s->current_ssid)
636 wpa_s->reassociate = 1;
637 } else if (os_strcmp(rsp, "PIN") == 0) {
639 eap->pin = os_strdup(pos);
640 eap->pending_req_pin = 0;
641 if (ssid == wpa_s->current_ssid)
642 wpa_s->reassociate = 1;
643 } else if (os_strcmp(rsp, "OTP") == 0) {
645 eap->otp = (u8 *) os_strdup(pos);
646 eap->otp_len = os_strlen(pos);
647 os_free(eap->pending_req_otp);
648 eap->pending_req_otp = NULL;
649 eap->pending_req_otp_len = 0;
650 } else if (os_strcmp(rsp, "PASSPHRASE") == 0) {
651 os_free(eap->private_key_passwd);
652 eap->private_key_passwd = (u8 *) os_strdup(pos);
653 eap->pending_req_passphrase = 0;
654 if (ssid == wpa_s->current_ssid)
655 wpa_s->reassociate = 1;
657 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", rsp);
662 #else /* IEEE8021X_EAPOL */
663 wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
665 #endif /* IEEE8021X_EAPOL */
669 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
671 char *buf, size_t buflen)
673 char *pos, *end, tmp[30];
674 int res, verbose, ret;
676 verbose = os_strcmp(params, "-VERBOSE") == 0;
679 if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
680 struct wpa_ssid *ssid = wpa_s->current_ssid;
681 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
682 MAC2STR(wpa_s->bssid));
683 if (ret < 0 || ret >= end - pos)
687 u8 *_ssid = ssid->ssid;
688 size_t ssid_len = ssid->ssid_len;
689 u8 ssid_buf[MAX_SSID_LEN];
691 int _res = wpa_drv_get_ssid(wpa_s, ssid_buf);
698 ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n",
699 wpa_ssid_txt(_ssid, ssid_len),
701 if (ret < 0 || ret >= end - pos)
706 ret = os_snprintf(pos, end - pos,
709 if (ret < 0 || ret >= end - pos)
714 switch (ssid->mode) {
715 case WPAS_MODE_INFRA:
716 ret = os_snprintf(pos, end - pos,
720 ret = os_snprintf(pos, end - pos,
724 ret = os_snprintf(pos, end - pos,
727 case WPAS_MODE_P2P_GO:
728 ret = os_snprintf(pos, end - pos,
731 case WPAS_MODE_P2P_GROUP_FORMATION:
732 ret = os_snprintf(pos, end - pos,
733 "mode=P2P GO - group "
740 if (ret < 0 || ret >= end - pos)
746 if (wpa_s->ap_iface) {
747 pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
751 #endif /* CONFIG_AP */
752 pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose);
754 ret = os_snprintf(pos, end - pos, "wpa_state=%s\n",
755 wpa_supplicant_state_txt(wpa_s->wpa_state));
756 if (ret < 0 || ret >= end - pos)
761 l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) {
762 ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp);
763 if (ret < 0 || ret >= end - pos)
769 if (wpa_s->global->p2p) {
770 ret = os_snprintf(pos, end - pos, "p2p_device_address=" MACSTR
771 "\n", MAC2STR(wpa_s->global->p2p_dev_addr));
772 if (ret < 0 || ret >= end - pos)
776 #endif /* CONFIG_P2P */
778 ret = os_snprintf(pos, end - pos, "address=" MACSTR "\n",
779 MAC2STR(wpa_s->own_addr));
780 if (ret < 0 || ret >= end - pos)
784 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
785 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
786 res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos,
792 res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose);
800 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s,
805 struct wpa_ssid *ssid;
808 /* cmd: "<network id> <BSSID>" */
809 pos = os_strchr(cmd, ' ');
814 wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos);
815 if (hwaddr_aton(pos, bssid)) {
816 wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos);
820 ssid = wpa_config_get_network(wpa_s->conf, id);
822 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
827 os_memcpy(ssid->bssid, bssid, ETH_ALEN);
828 ssid->bssid_set = !is_zero_ether_addr(bssid);
834 static int wpa_supplicant_ctrl_iface_list_networks(
835 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
838 struct wpa_ssid *ssid;
843 ret = os_snprintf(pos, end - pos,
844 "network id / ssid / bssid / flags\n");
845 if (ret < 0 || ret >= end - pos)
849 ssid = wpa_s->conf->ssid;
851 ret = os_snprintf(pos, end - pos, "%d\t%s",
853 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
854 if (ret < 0 || ret >= end - pos)
857 if (ssid->bssid_set) {
858 ret = os_snprintf(pos, end - pos, "\t" MACSTR,
859 MAC2STR(ssid->bssid));
861 ret = os_snprintf(pos, end - pos, "\tany");
863 if (ret < 0 || ret >= end - pos)
866 ret = os_snprintf(pos, end - pos, "\t%s%s%s",
867 ssid == wpa_s->current_ssid ?
869 ssid->disabled ? "[DISABLED]" : "",
870 ssid->disabled == 2 ? "[P2P-PERSISTENT]" :
872 if (ret < 0 || ret >= end - pos)
875 ret = os_snprintf(pos, end - pos, "\n");
876 if (ret < 0 || ret >= end - pos)
887 static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher)
890 ret = os_snprintf(pos, end - pos, "-");
891 if (ret < 0 || ret >= end - pos)
894 if (cipher & WPA_CIPHER_NONE) {
895 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : "+");
896 if (ret < 0 || ret >= end - pos)
901 if (cipher & WPA_CIPHER_WEP40) {
902 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : "+");
903 if (ret < 0 || ret >= end - pos)
908 if (cipher & WPA_CIPHER_WEP104) {
909 ret = os_snprintf(pos, end - pos, "%sWEP104",
911 if (ret < 0 || ret >= end - pos)
916 if (cipher & WPA_CIPHER_TKIP) {
917 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : "+");
918 if (ret < 0 || ret >= end - pos)
923 if (cipher & WPA_CIPHER_CCMP) {
924 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : "+");
925 if (ret < 0 || ret >= end - pos)
934 static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
935 const u8 *ie, size_t ie_len)
937 struct wpa_ie_data data;
940 ret = os_snprintf(pos, end - pos, "[%s-", proto);
941 if (ret < 0 || ret >= end - pos)
945 if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) {
946 ret = os_snprintf(pos, end - pos, "?]");
947 if (ret < 0 || ret >= end - pos)
954 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
955 ret = os_snprintf(pos, end - pos, "%sEAP", first ? "" : "+");
956 if (ret < 0 || ret >= end - pos)
961 if (data.key_mgmt & WPA_KEY_MGMT_PSK) {
962 ret = os_snprintf(pos, end - pos, "%sPSK", first ? "" : "+");
963 if (ret < 0 || ret >= end - pos)
968 if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
969 ret = os_snprintf(pos, end - pos, "%sNone", first ? "" : "+");
970 if (ret < 0 || ret >= end - pos)
975 #ifdef CONFIG_IEEE80211R
976 if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
977 ret = os_snprintf(pos, end - pos, "%sFT/EAP",
979 if (ret < 0 || ret >= end - pos)
984 if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) {
985 ret = os_snprintf(pos, end - pos, "%sFT/PSK",
987 if (ret < 0 || ret >= end - pos)
992 #endif /* CONFIG_IEEE80211R */
993 #ifdef CONFIG_IEEE80211W
994 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
995 ret = os_snprintf(pos, end - pos, "%sEAP-SHA256",
997 if (ret < 0 || ret >= end - pos)
1002 if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
1003 ret = os_snprintf(pos, end - pos, "%sPSK-SHA256",
1005 if (ret < 0 || ret >= end - pos)
1010 #endif /* CONFIG_IEEE80211W */
1012 pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher);
1014 if (data.capabilities & WPA_CAPABILITY_PREAUTH) {
1015 ret = os_snprintf(pos, end - pos, "-preauth");
1016 if (ret < 0 || ret >= end - pos)
1021 ret = os_snprintf(pos, end - pos, "]");
1022 if (ret < 0 || ret >= end - pos)
1031 static char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant *wpa_s,
1032 char *pos, char *end,
1033 struct wpabuf *wps_ie)
1040 if (wps_is_selected_pbc_registrar(wps_ie))
1043 else if (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 0))
1045 #endif /* CONFIG_WPS2 */
1046 else if (wps_is_selected_pin_registrar(wps_ie))
1051 ret = os_snprintf(pos, end - pos, "%s", txt);
1052 if (ret >= 0 && ret < end - pos)
1054 wpabuf_free(wps_ie);
1057 #endif /* CONFIG_WPS */
1060 static char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant *wpa_s,
1061 char *pos, char *end,
1062 const struct wpa_bss *bss)
1065 struct wpabuf *wps_ie;
1066 wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
1067 return wpa_supplicant_wps_ie_txt_buf(wpa_s, pos, end, wps_ie);
1068 #else /* CONFIG_WPS */
1070 #endif /* CONFIG_WPS */
1074 /* Format one result on one text line into a buffer. */
1075 static int wpa_supplicant_ctrl_iface_scan_result(
1076 struct wpa_supplicant *wpa_s,
1077 const struct wpa_bss *bss, char *buf, size_t buflen)
1081 const u8 *ie, *ie2, *p2p;
1083 p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE);
1084 if (p2p && bss->ssid_len == P2P_WILDCARD_SSID_LEN &&
1085 os_memcmp(bss->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) ==
1087 return 0; /* Do not show P2P listen discovery results here */
1092 ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t",
1093 MAC2STR(bss->bssid), bss->freq, bss->level);
1094 if (ret < 0 || ret >= end - pos)
1097 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
1099 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
1100 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1102 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
1103 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
1104 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
1105 ret = os_snprintf(pos, end - pos, "[WEP]");
1106 if (ret < 0 || ret >= end - pos)
1110 if (bss->caps & IEEE80211_CAP_IBSS) {
1111 ret = os_snprintf(pos, end - pos, "[IBSS]");
1112 if (ret < 0 || ret >= end - pos)
1116 if (bss->caps & IEEE80211_CAP_ESS) {
1117 ret = os_snprintf(pos, end - pos, "[ESS]");
1118 if (ret < 0 || ret >= end - pos)
1123 ret = os_snprintf(pos, end - pos, "[P2P]");
1124 if (ret < 0 || ret >= end - pos)
1129 ret = os_snprintf(pos, end - pos, "\t%s",
1130 wpa_ssid_txt(bss->ssid, bss->ssid_len));
1131 if (ret < 0 || ret >= end - pos)
1135 ret = os_snprintf(pos, end - pos, "\n");
1136 if (ret < 0 || ret >= end - pos)
1144 static int wpa_supplicant_ctrl_iface_scan_results(
1145 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
1148 struct wpa_bss *bss;
1153 ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / "
1155 if (ret < 0 || ret >= end - pos)
1159 dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
1160 ret = wpa_supplicant_ctrl_iface_scan_result(wpa_s, bss, pos,
1162 if (ret < 0 || ret >= end - pos)
1171 static int wpa_supplicant_ctrl_iface_select_network(
1172 struct wpa_supplicant *wpa_s, char *cmd)
1175 struct wpa_ssid *ssid;
1177 /* cmd: "<network id>" or "any" */
1178 if (os_strcmp(cmd, "any") == 0) {
1179 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any");
1183 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id);
1185 ssid = wpa_config_get_network(wpa_s->conf, id);
1187 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
1188 "network id=%d", id);
1191 if (ssid->disabled == 2) {
1192 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
1193 "SELECT_NETWORK with persistent P2P group");
1198 wpa_supplicant_select_network(wpa_s, ssid);
1204 static int wpa_supplicant_ctrl_iface_enable_network(
1205 struct wpa_supplicant *wpa_s, char *cmd)
1208 struct wpa_ssid *ssid;
1210 /* cmd: "<network id>" or "all" */
1211 if (os_strcmp(cmd, "all") == 0) {
1212 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all");
1216 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id);
1218 ssid = wpa_config_get_network(wpa_s->conf, id);
1220 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
1221 "network id=%d", id);
1224 if (ssid->disabled == 2) {
1225 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
1226 "ENABLE_NETWORK with persistent P2P group");
1230 wpa_supplicant_enable_network(wpa_s, ssid);
1236 static int wpa_supplicant_ctrl_iface_disable_network(
1237 struct wpa_supplicant *wpa_s, char *cmd)
1240 struct wpa_ssid *ssid;
1242 /* cmd: "<network id>" or "all" */
1243 if (os_strcmp(cmd, "all") == 0) {
1244 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all");
1248 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id);
1250 ssid = wpa_config_get_network(wpa_s->conf, id);
1252 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
1253 "network id=%d", id);
1256 if (ssid->disabled == 2) {
1257 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
1258 "DISABLE_NETWORK with persistent P2P "
1263 wpa_supplicant_disable_network(wpa_s, ssid);
1269 static int wpa_supplicant_ctrl_iface_add_network(
1270 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
1272 struct wpa_ssid *ssid;
1275 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK");
1277 ssid = wpa_config_add_network(wpa_s->conf);
1281 wpas_notify_network_added(wpa_s, ssid);
1284 wpa_config_set_network_defaults(ssid);
1286 ret = os_snprintf(buf, buflen, "%d\n", ssid->id);
1287 if (ret < 0 || (size_t) ret >= buflen)
1293 static int wpa_supplicant_ctrl_iface_remove_network(
1294 struct wpa_supplicant *wpa_s, char *cmd)
1297 struct wpa_ssid *ssid;
1299 /* cmd: "<network id>" or "all" */
1300 if (os_strcmp(cmd, "all") == 0) {
1301 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all");
1302 ssid = wpa_s->conf->ssid;
1304 struct wpa_ssid *remove_ssid = ssid;
1307 wpas_notify_network_removed(wpa_s, remove_ssid);
1308 wpa_config_remove_network(wpa_s->conf, id);
1310 if (wpa_s->current_ssid) {
1311 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1312 wpa_supplicant_disassociate(wpa_s,
1313 WLAN_REASON_DEAUTH_LEAVING);
1319 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id);
1321 ssid = wpa_config_get_network(wpa_s->conf, id);
1323 wpa_config_remove_network(wpa_s->conf, id) < 0) {
1324 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1329 if (ssid == wpa_s->current_ssid) {
1331 * Invalidate the EAP session cache if the current network is
1334 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1336 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1343 static int wpa_supplicant_ctrl_iface_set_network(
1344 struct wpa_supplicant *wpa_s, char *cmd)
1347 struct wpa_ssid *ssid;
1350 /* cmd: "<network id> <variable name> <value>" */
1351 name = os_strchr(cmd, ' ');
1356 value = os_strchr(name, ' ');
1362 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
1364 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
1365 (u8 *) value, os_strlen(value));
1367 ssid = wpa_config_get_network(wpa_s->conf, id);
1369 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1374 if (wpa_config_set(ssid, name, value, 0) < 0) {
1375 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network "
1376 "variable '%s'", name);
1380 if (wpa_s->current_ssid == ssid) {
1382 * Invalidate the EAP session cache if anything in the current
1383 * configuration changes.
1385 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1388 if ((os_strcmp(name, "psk") == 0 &&
1389 value[0] == '"' && ssid->ssid_len) ||
1390 (os_strcmp(name, "ssid") == 0 && ssid->passphrase))
1391 wpa_config_update_psk(ssid);
1392 else if (os_strcmp(name, "priority") == 0)
1393 wpa_config_update_prio_list(wpa_s->conf);
1399 static int wpa_supplicant_ctrl_iface_get_network(
1400 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
1404 struct wpa_ssid *ssid;
1407 /* cmd: "<network id> <variable name>" */
1408 name = os_strchr(cmd, ' ');
1409 if (name == NULL || buflen == 0)
1414 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
1417 ssid = wpa_config_get_network(wpa_s->conf, id);
1419 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1424 value = wpa_config_get_no_key(ssid, name);
1425 if (value == NULL) {
1426 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network "
1427 "variable '%s'", name);
1431 res = os_strlcpy(buf, value, buflen);
1432 if (res >= buflen) {
1443 #ifndef CONFIG_NO_CONFIG_WRITE
1444 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s)
1448 if (!wpa_s->conf->update_config) {
1449 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
1450 "to update configuration (update_config=0)");
1454 ret = wpa_config_write(wpa_s->confname, wpa_s->conf);
1456 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to "
1457 "update configuration");
1459 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration"
1465 #endif /* CONFIG_NO_CONFIG_WRITE */
1468 static int ctrl_iface_get_capability_pairwise(int res, char *strict,
1469 struct wpa_driver_capa *capa,
1470 char *buf, size_t buflen)
1482 len = os_strlcpy(buf, "CCMP TKIP NONE", buflen);
1488 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1489 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " ");
1490 if (ret < 0 || ret >= end - pos)
1496 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1497 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " ");
1498 if (ret < 0 || ret >= end - pos)
1504 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1505 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : " ");
1506 if (ret < 0 || ret >= end - pos)
1516 static int ctrl_iface_get_capability_group(int res, char *strict,
1517 struct wpa_driver_capa *capa,
1518 char *buf, size_t buflen)
1530 len = os_strlcpy(buf, "CCMP TKIP WEP104 WEP40", buflen);
1536 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1537 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " ");
1538 if (ret < 0 || ret >= end - pos)
1544 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1545 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " ");
1546 if (ret < 0 || ret >= end - pos)
1552 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP104) {
1553 ret = os_snprintf(pos, end - pos, "%sWEP104",
1555 if (ret < 0 || ret >= end - pos)
1561 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP40) {
1562 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : " ");
1563 if (ret < 0 || ret >= end - pos)
1573 static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
1574 struct wpa_driver_capa *capa,
1575 char *buf, size_t buflen)
1587 len = os_strlcpy(buf, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE "
1594 ret = os_snprintf(pos, end - pos, "NONE IEEE8021X");
1595 if (ret < 0 || ret >= end - pos)
1599 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1600 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
1601 ret = os_snprintf(pos, end - pos, " WPA-EAP");
1602 if (ret < 0 || ret >= end - pos)
1607 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1608 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1609 ret = os_snprintf(pos, end - pos, " WPA-PSK");
1610 if (ret < 0 || ret >= end - pos)
1615 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1616 ret = os_snprintf(pos, end - pos, " WPA-NONE");
1617 if (ret < 0 || ret >= end - pos)
1626 static int ctrl_iface_get_capability_proto(int res, char *strict,
1627 struct wpa_driver_capa *capa,
1628 char *buf, size_t buflen)
1640 len = os_strlcpy(buf, "RSN WPA", buflen);
1646 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1647 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1648 ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " ");
1649 if (ret < 0 || ret >= end - pos)
1655 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1656 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
1657 ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " ");
1658 if (ret < 0 || ret >= end - pos)
1668 static int ctrl_iface_get_capability_auth_alg(int res, char *strict,
1669 struct wpa_driver_capa *capa,
1670 char *buf, size_t buflen)
1682 len = os_strlcpy(buf, "OPEN SHARED LEAP", buflen);
1688 if (capa->auth & (WPA_DRIVER_AUTH_OPEN)) {
1689 ret = os_snprintf(pos, end - pos, "%sOPEN", first ? "" : " ");
1690 if (ret < 0 || ret >= end - pos)
1696 if (capa->auth & (WPA_DRIVER_AUTH_SHARED)) {
1697 ret = os_snprintf(pos, end - pos, "%sSHARED",
1699 if (ret < 0 || ret >= end - pos)
1705 if (capa->auth & (WPA_DRIVER_AUTH_LEAP)) {
1706 ret = os_snprintf(pos, end - pos, "%sLEAP", first ? "" : " ");
1707 if (ret < 0 || ret >= end - pos)
1717 static int wpa_supplicant_ctrl_iface_get_capability(
1718 struct wpa_supplicant *wpa_s, const char *_field, char *buf,
1721 struct wpa_driver_capa capa;
1727 /* Determine whether or not strict checking was requested */
1728 len = os_strlcpy(field, _field, sizeof(field));
1729 if (len >= sizeof(field))
1731 strict = os_strchr(field, ' ');
1732 if (strict != NULL) {
1734 if (os_strcmp(strict, "strict") != 0)
1738 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
1739 field, strict ? strict : "");
1741 if (os_strcmp(field, "eap") == 0) {
1742 return eap_get_names(buf, buflen);
1745 res = wpa_drv_get_capa(wpa_s, &capa);
1747 if (os_strcmp(field, "pairwise") == 0)
1748 return ctrl_iface_get_capability_pairwise(res, strict, &capa,
1751 if (os_strcmp(field, "group") == 0)
1752 return ctrl_iface_get_capability_group(res, strict, &capa,
1755 if (os_strcmp(field, "key_mgmt") == 0)
1756 return ctrl_iface_get_capability_key_mgmt(res, strict, &capa,
1759 if (os_strcmp(field, "proto") == 0)
1760 return ctrl_iface_get_capability_proto(res, strict, &capa,
1763 if (os_strcmp(field, "auth_alg") == 0)
1764 return ctrl_iface_get_capability_auth_alg(res, strict, &capa,
1767 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
1774 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
1775 const char *cmd, char *buf,
1780 struct wpa_bss *bss;
1785 if (os_strcmp(cmd, "FIRST") == 0)
1786 bss = dl_list_first(&wpa_s->bss, struct wpa_bss, list);
1787 else if (os_strncmp(cmd, "ID-", 3) == 0) {
1789 bss = wpa_bss_get_id(wpa_s, i);
1790 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) {
1792 bss = wpa_bss_get_id(wpa_s, i);
1794 struct dl_list *next = bss->list_id.next;
1795 if (next == &wpa_s->bss_id)
1798 bss = dl_list_entry(next, struct wpa_bss,
1801 } else if (hwaddr_aton(cmd, bssid) == 0)
1802 bss = wpa_bss_get_bssid(wpa_s, bssid);
1804 struct wpa_bss *tmp;
1807 dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id)
1821 ret = os_snprintf(pos, end - pos,
1823 "bssid=" MACSTR "\n"
1826 "capabilities=0x%04x\n"
1833 MAC2STR(bss->bssid), bss->freq, bss->beacon_int,
1834 bss->caps, bss->qual, bss->noise, bss->level,
1835 (unsigned long long) bss->tsf);
1836 if (ret < 0 || ret >= end - pos)
1840 ie = (const u8 *) (bss + 1);
1841 for (i = 0; i < bss->ie_len; i++) {
1842 ret = os_snprintf(pos, end - pos, "%02x", *ie++);
1843 if (ret < 0 || ret >= end - pos)
1847 if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE)) {
1848 ret = os_snprintf(pos, end - pos, "[P2P]");
1849 if (ret < 0 || ret >= end - pos)
1854 ret = os_snprintf(pos, end - pos, "\n");
1855 if (ret < 0 || ret >= end - pos)
1859 ret = os_snprintf(pos, end - pos, "flags=");
1860 if (ret < 0 || ret >= end - pos)
1864 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
1866 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
1867 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1869 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
1870 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
1871 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
1872 ret = os_snprintf(pos, end - pos, "[WEP]");
1873 if (ret < 0 || ret >= end - pos)
1877 if (bss->caps & IEEE80211_CAP_IBSS) {
1878 ret = os_snprintf(pos, end - pos, "[IBSS]");
1879 if (ret < 0 || ret >= end - pos)
1883 if (bss->caps & IEEE80211_CAP_ESS) {
1884 ret = os_snprintf(pos, end - pos, "[ESS]");
1885 if (ret < 0 || ret >= end - pos)
1890 ret = os_snprintf(pos, end - pos, "\n");
1891 if (ret < 0 || ret >= end - pos)
1895 ret = os_snprintf(pos, end - pos, "ssid=%s\n",
1896 wpa_ssid_txt(bss->ssid, bss->ssid_len));
1897 if (ret < 0 || ret >= end - pos)
1902 ie = (const u8 *) (bss + 1);
1903 ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end);
1904 if (ret < 0 || ret >= end - pos)
1907 #endif /* CONFIG_WPS */
1910 ie = (const u8 *) (bss + 1);
1911 ret = wpas_p2p_scan_result_text(ie, bss->ie_len, pos, end);
1912 if (ret < 0 || ret >= end - pos)
1915 #endif /* CONFIG_P2P */
1921 static int wpa_supplicant_ctrl_iface_ap_scan(
1922 struct wpa_supplicant *wpa_s, char *cmd)
1924 int ap_scan = atoi(cmd);
1925 return wpa_supplicant_set_ap_scan(wpa_s, ap_scan);
1929 static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s)
1931 wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication");
1932 /* MLME-DELETEKEYS.request */
1933 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0);
1934 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0);
1935 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0);
1936 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0);
1937 #ifdef CONFIG_IEEE80211W
1938 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0);
1939 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0);
1940 #endif /* CONFIG_IEEE80211W */
1942 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL,
1944 /* MLME-SETPROTECTION.request(None) */
1945 wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid,
1946 MLME_SETPROTECTION_PROTECT_TYPE_NONE,
1947 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
1948 wpa_sm_drop_sa(wpa_s->wpa);
1952 static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s,
1956 struct wpa_bss *bss;
1957 struct wpa_ssid *ssid = wpa_s->current_ssid;
1959 if (hwaddr_aton(addr, bssid)) {
1960 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid "
1961 "address '%s'", addr);
1965 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM " MACSTR, MAC2STR(bssid));
1967 bss = wpa_bss_get_bssid(wpa_s, bssid);
1969 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: Target AP not found "
1975 * TODO: Find best network configuration block from configuration to
1976 * allow roaming to other networks
1980 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: No network "
1981 "configuration known for the target AP");
1985 wpa_s->reassociate = 1;
1986 wpa_supplicant_connect(wpa_s, bss, ssid);
1993 static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
1995 unsigned int timeout = atoi(cmd);
1996 enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL;
1998 if (os_strstr(cmd, "type=social"))
1999 type = P2P_FIND_ONLY_SOCIAL;
2000 else if (os_strstr(cmd, "type=progressive"))
2001 type = P2P_FIND_PROGRESSIVE;
2003 return wpas_p2p_find(wpa_s, timeout, type);
2007 static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
2008 char *buf, size_t buflen)
2013 enum p2p_wps_method wps_method;
2016 int persistent_group;
2022 /* <addr> <"pbc" | "pin" | PIN> [label|display|keypad] [persistent]
2023 * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] */
2025 if (hwaddr_aton(cmd, addr))
2033 persistent_group = os_strstr(pos, " persistent") != NULL;
2034 join = os_strstr(pos, " join") != NULL;
2035 auth = os_strstr(pos, " auth") != NULL;
2037 pos2 = os_strstr(pos, " go_intent=");
2040 go_intent = atoi(pos2);
2041 if (go_intent < 0 || go_intent > 15)
2045 pos2 = os_strstr(pos, " freq=");
2053 if (os_strncmp(pos, "pin", 3) == 0) {
2054 /* Request random PIN (to be displayed) and enable the PIN */
2055 wps_method = WPS_PIN_DISPLAY;
2056 } else if (os_strncmp(pos, "pbc", 3) == 0) {
2057 wps_method = WPS_PBC;
2060 pos = os_strchr(pin, ' ');
2061 wps_method = WPS_PIN_KEYPAD;
2064 if (os_strncmp(pos, "label", 5) == 0)
2065 wps_method = WPS_PIN_LABEL;
2066 else if (os_strncmp(pos, "display", 7) == 0)
2067 wps_method = WPS_PIN_DISPLAY;
2071 new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
2072 persistent_group, join, auth, go_intent,
2074 if (new_pin == -2) {
2075 os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25);
2078 if (new_pin == -3) {
2079 os_memcpy(buf, "FAIL-CHANNEL-UNSUPPORTED\n", 25);
2084 if (wps_method == WPS_PIN_DISPLAY && pin == NULL) {
2085 ret = os_snprintf(buf, buflen, "%08d", new_pin);
2086 if (ret < 0 || (size_t) ret >= buflen)
2091 os_memcpy(buf, "OK\n", 3);
2096 static int p2p_ctrl_listen(struct wpa_supplicant *wpa_s, char *cmd)
2098 unsigned int timeout = atoi(cmd);
2099 return wpas_p2p_listen(wpa_s, timeout);
2103 static int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd)
2108 /* <addr> <config method> */
2110 if (hwaddr_aton(cmd, addr))
2118 return wpas_p2p_prov_disc(wpa_s, addr, pos);
2122 static int p2p_get_passphrase(struct wpa_supplicant *wpa_s, char *buf,
2125 struct wpa_ssid *ssid = wpa_s->current_ssid;
2127 if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
2128 ssid->passphrase == NULL)
2131 os_strlcpy(buf, ssid->passphrase, buflen);
2132 return os_strlen(buf);
2136 static int p2p_ctrl_serv_disc_req(struct wpa_supplicant *wpa_s, char *cmd,
2137 char *buf, size_t buflen)
2141 u8 dst_buf[ETH_ALEN], *dst;
2142 struct wpabuf *tlvs;
2146 if (hwaddr_aton(cmd, dst_buf))
2149 if (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 &&
2150 dst[3] == 0 && dst[4] == 0 && dst[5] == 0)
2157 if (os_strncmp(pos, "upnp ", 5) == 0) {
2160 if (hexstr2bin(pos, &version, 1) < 0)
2166 ref = (unsigned long) wpas_p2p_sd_request_upnp(wpa_s, dst,
2169 len = os_strlen(pos);
2173 tlvs = wpabuf_alloc(len);
2176 if (hexstr2bin(pos, wpabuf_put(tlvs, len), len) < 0) {
2181 ref = (unsigned long) wpas_p2p_sd_request(wpa_s, dst, tlvs);
2184 res = os_snprintf(buf, buflen, "%llx", (long long unsigned) ref);
2185 if (res < 0 || (unsigned) res >= buflen)
2191 static int p2p_ctrl_serv_disc_cancel_req(struct wpa_supplicant *wpa_s,
2194 long long unsigned val;
2196 if (sscanf(cmd, "%llx", &val) != 1)
2199 return wpas_p2p_sd_cancel_request(wpa_s, (void *) (unsigned long) req);
2203 static int p2p_ctrl_serv_disc_resp(struct wpa_supplicant *wpa_s, char *cmd)
2208 struct wpabuf *resp_tlvs;
2212 pos = os_strchr(cmd, ' ');
2220 if (hwaddr_aton(pos, dst))
2227 pos2 = os_strchr(pos, ' ');
2231 dialog_token = atoi(pos);
2233 len = os_strlen(pos2);
2237 resp_tlvs = wpabuf_alloc(len);
2238 if (resp_tlvs == NULL)
2240 if (hexstr2bin(pos2, wpabuf_put(resp_tlvs, len), len) < 0) {
2241 wpabuf_free(resp_tlvs);
2245 wpas_p2p_sd_response(wpa_s, freq, dst, dialog_token, resp_tlvs);
2246 wpabuf_free(resp_tlvs);
2251 static int p2p_ctrl_serv_disc_external(struct wpa_supplicant *wpa_s,
2254 wpa_s->p2p_sd_over_ctrl_iface = atoi(cmd);
2259 static int p2p_ctrl_service_add_bonjour(struct wpa_supplicant *wpa_s,
2264 struct wpabuf *query, *resp;
2266 pos = os_strchr(cmd, ' ');
2271 len = os_strlen(cmd);
2275 query = wpabuf_alloc(len);
2278 if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) {
2283 len = os_strlen(pos);
2289 resp = wpabuf_alloc(len);
2294 if (hexstr2bin(pos, wpabuf_put(resp, len), len) < 0) {
2300 if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0) {
2309 static int p2p_ctrl_service_add_upnp(struct wpa_supplicant *wpa_s, char *cmd)
2314 pos = os_strchr(cmd, ' ');
2319 if (hexstr2bin(cmd, &version, 1) < 0)
2322 return wpas_p2p_service_add_upnp(wpa_s, version, pos);
2326 static int p2p_ctrl_service_add(struct wpa_supplicant *wpa_s, char *cmd)
2330 pos = os_strchr(cmd, ' ');
2335 if (os_strcmp(cmd, "bonjour") == 0)
2336 return p2p_ctrl_service_add_bonjour(wpa_s, pos);
2337 if (os_strcmp(cmd, "upnp") == 0)
2338 return p2p_ctrl_service_add_upnp(wpa_s, pos);
2339 wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd);
2344 static int p2p_ctrl_service_del_bonjour(struct wpa_supplicant *wpa_s,
2348 struct wpabuf *query;
2351 len = os_strlen(cmd);
2355 query = wpabuf_alloc(len);
2358 if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) {
2363 ret = wpas_p2p_service_del_bonjour(wpa_s, query);
2369 static int p2p_ctrl_service_del_upnp(struct wpa_supplicant *wpa_s, char *cmd)
2374 pos = os_strchr(cmd, ' ');
2379 if (hexstr2bin(cmd, &version, 1) < 0)
2382 return wpas_p2p_service_del_upnp(wpa_s, version, pos);
2386 static int p2p_ctrl_service_del(struct wpa_supplicant *wpa_s, char *cmd)
2390 pos = os_strchr(cmd, ' ');
2395 if (os_strcmp(cmd, "bonjour") == 0)
2396 return p2p_ctrl_service_del_bonjour(wpa_s, pos);
2397 if (os_strcmp(cmd, "upnp") == 0)
2398 return p2p_ctrl_service_del_upnp(wpa_s, pos);
2399 wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd);
2404 static int p2p_ctrl_reject(struct wpa_supplicant *wpa_s, char *cmd)
2410 if (hwaddr_aton(cmd, addr))
2413 return wpas_p2p_reject(wpa_s, addr);
2417 static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
2421 struct wpa_ssid *ssid;
2425 pos = os_strstr(cmd, " peer=");
2428 if (hwaddr_aton(pos, peer))
2431 ssid = wpa_config_get_network(wpa_s->conf, id);
2432 if (ssid == NULL || ssid->disabled != 2) {
2433 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
2434 "for persistent P2P group",
2439 return wpas_p2p_invite(wpa_s, pos ? peer : NULL, ssid, NULL);
2443 static int p2p_ctrl_invite_group(struct wpa_supplicant *wpa_s, char *cmd)
2446 u8 peer[ETH_ALEN], go_dev_addr[ETH_ALEN], *go_dev = NULL;
2448 pos = os_strstr(cmd, " peer=");
2454 if (hwaddr_aton(pos, peer)) {
2455 wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'", pos);
2459 pos = os_strstr(pos, " go_dev_addr=");
2462 if (hwaddr_aton(pos, go_dev_addr)) {
2463 wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'",
2467 go_dev = go_dev_addr;
2470 return wpas_p2p_invite_group(wpa_s, cmd, peer, go_dev);
2474 static int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd)
2476 if (os_strncmp(cmd, "persistent=", 11) == 0)
2477 return p2p_ctrl_invite_persistent(wpa_s, cmd + 11);
2478 if (os_strncmp(cmd, "group=", 6) == 0)
2479 return p2p_ctrl_invite_group(wpa_s, cmd + 6);
2485 static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
2486 char *cmd, int freq)
2489 struct wpa_ssid *ssid;
2492 ssid = wpa_config_get_network(wpa_s->conf, id);
2493 if (ssid == NULL || ssid->disabled != 2) {
2494 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
2495 "for persistent P2P group",
2500 return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq);
2504 static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
2509 pos = os_strstr(cmd, "freq=");
2511 freq = atoi(pos + 5);
2513 if (os_strncmp(cmd, "persistent=", 11) == 0)
2514 return p2p_ctrl_group_add_persistent(wpa_s, cmd + 11, freq);
2515 if (os_strcmp(cmd, "persistent") == 0 ||
2516 os_strncmp(cmd, "persistent ", 11) == 0)
2517 return wpas_p2p_group_add(wpa_s, 1, freq);
2518 if (os_strncmp(cmd, "freq=", 5) == 0)
2519 return wpas_p2p_group_add(wpa_s, 0, freq);
2521 wpa_printf(MSG_DEBUG, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'",
2527 static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
2528 char *buf, size_t buflen)
2530 u8 addr[ETH_ALEN], *addr_ptr;
2533 if (!wpa_s->global->p2p)
2536 if (os_strcmp(cmd, "FIRST") == 0) {
2539 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) {
2540 if (hwaddr_aton(cmd + 5, addr) < 0)
2545 if (hwaddr_aton(cmd, addr) < 0)
2551 return p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next,
2556 static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
2560 if (wpa_s->global->p2p == NULL)
2563 param = os_strchr(cmd, ' ');
2568 if (os_strcmp(cmd, "discoverability") == 0) {
2569 p2p_set_client_discoverability(wpa_s->global->p2p,
2574 if (os_strcmp(cmd, "managed") == 0) {
2575 p2p_set_managed_oper(wpa_s->global->p2p, atoi(param));
2579 if (os_strcmp(cmd, "listen_channel") == 0) {
2580 return p2p_set_listen_channel(wpa_s->global->p2p, 81,
2584 if (os_strcmp(cmd, "ssid_postfix") == 0) {
2585 return p2p_set_ssid_postfix(wpa_s->global->p2p, (u8 *) param,
2589 if (os_strcmp(cmd, "noa") == 0) {
2591 int count, start, duration;
2592 /* GO NoA parameters: count,start_offset(ms),duration(ms) */
2593 count = atoi(param);
2594 pos = os_strchr(param, ',');
2599 pos = os_strchr(pos, ',');
2603 duration = atoi(pos);
2604 if (count < 0 || count > 255 || start < 0 || duration < 0)
2606 if (count == 0 && duration > 0)
2608 wpa_printf(MSG_DEBUG, "CTRL_IFACE: P2P_SET GO NoA: count=%d "
2609 "start=%d duration=%d", count, start, duration);
2610 return wpas_p2p_set_noa(wpa_s, count, start, duration);
2613 if (os_strcmp(cmd, "ps") == 0)
2614 return wpa_drv_set_p2p_powersave(wpa_s, atoi(param), -1, -1);
2616 if (os_strcmp(cmd, "oppps") == 0)
2617 return wpa_drv_set_p2p_powersave(wpa_s, -1, atoi(param), -1);
2619 if (os_strcmp(cmd, "ctwindow") == 0)
2620 return wpa_drv_set_p2p_powersave(wpa_s, -1, -1, atoi(param));
2622 if (os_strcmp(cmd, "disabled") == 0) {
2623 wpa_s->global->p2p_disabled = atoi(param);
2624 wpa_printf(MSG_DEBUG, "P2P functionality %s",
2625 wpa_s->global->p2p_disabled ?
2626 "disabled" : "enabled");
2627 if (wpa_s->global->p2p_disabled) {
2628 wpas_p2p_stop_find(wpa_s);
2629 os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
2630 p2p_flush(wpa_s->global->p2p);
2635 if (os_strcmp(cmd, "force_long_sd") == 0) {
2636 wpa_s->force_long_sd = atoi(param);
2640 if (os_strcmp(cmd, "peer_filter") == 0) {
2642 if (hwaddr_aton(param, addr))
2644 p2p_set_peer_filter(wpa_s->global->p2p, addr);
2648 if (os_strcmp(cmd, "cross_connect") == 0)
2649 return wpas_p2p_set_cross_connect(wpa_s, atoi(param));
2651 if (os_strcmp(cmd, "go_apsd") == 0) {
2652 if (os_strcmp(param, "disable") == 0)
2653 wpa_s->set_ap_uapsd = 0;
2655 wpa_s->set_ap_uapsd = 1;
2656 wpa_s->ap_uapsd = atoi(param);
2661 if (os_strcmp(cmd, "client_apsd") == 0) {
2662 if (os_strcmp(param, "disable") == 0)
2663 wpa_s->set_sta_uapsd = 0;
2667 /* format: BE,BK,VI,VO;max SP Length */
2669 pos = os_strchr(param, ',');
2674 pos = os_strchr(pos, ',');
2679 pos = os_strchr(pos, ',');
2684 /* ignore max SP Length for now */
2686 wpa_s->set_sta_uapsd = 1;
2687 wpa_s->sta_uapsd = 0;
2689 wpa_s->sta_uapsd |= BIT(0);
2691 wpa_s->sta_uapsd |= BIT(1);
2693 wpa_s->sta_uapsd |= BIT(2);
2695 wpa_s->sta_uapsd |= BIT(3);
2700 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
2707 static int p2p_ctrl_presence_req(struct wpa_supplicant *wpa_s, char *cmd)
2710 unsigned int dur1 = 0, int1 = 0, dur2 = 0, int2 = 0;
2713 pos = os_strchr(cmd, ' ');
2719 pos2 = os_strchr(pos, ' ');
2727 pos = os_strchr(pos2, ' ');
2735 return wpas_p2p_presence_req(wpa_s, dur1, int1, dur2, int2);
2739 static int p2p_ctrl_ext_listen(struct wpa_supplicant *wpa_s, char *cmd)
2742 unsigned int period = 0, interval = 0;
2745 pos = os_strchr(cmd, ' ');
2750 interval = atoi(pos);
2753 return wpas_p2p_ext_listen(wpa_s, period, interval);
2756 #endif /* CONFIG_P2P */
2759 static int wpa_supplicant_ctrl_iface_sta_autoconnect(
2760 struct wpa_supplicant *wpa_s, char *cmd)
2762 wpa_s->auto_reconnect_disabled = atoi(cmd) == 0 ? 1 : 0;
2767 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
2768 char *buf, size_t *resp_len)
2771 const int reply_size = 4096;
2775 if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 ||
2776 os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
2777 wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface",
2778 (const u8 *) buf, os_strlen(buf));
2780 int level = MSG_DEBUG;
2781 if (os_strcmp(buf, "PING") == 0)
2782 level = MSG_EXCESSIVE;
2783 wpa_hexdump_ascii(level, "RX ctrl_iface",
2784 (const u8 *) buf, os_strlen(buf));
2787 reply = os_malloc(reply_size);
2788 if (reply == NULL) {
2793 os_memcpy(reply, "OK\n", 3);
2796 if (os_strcmp(buf, "PING") == 0) {
2797 os_memcpy(reply, "PONG\n", 5);
2799 } else if (os_strncmp(buf, "RELOG", 5) == 0) {
2800 if (wpa_debug_reopen_file() < 0)
2802 } else if (os_strncmp(buf, "NOTE ", 5) == 0) {
2803 wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
2804 } else if (os_strcmp(buf, "MIB") == 0) {
2805 reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
2806 if (reply_len >= 0) {
2808 res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len,
2809 reply_size - reply_len);
2815 } else if (os_strncmp(buf, "STATUS", 6) == 0) {
2816 reply_len = wpa_supplicant_ctrl_iface_status(
2817 wpa_s, buf + 6, reply, reply_size);
2818 } else if (os_strcmp(buf, "PMKSA") == 0) {
2819 reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, reply,
2821 } else if (os_strncmp(buf, "SET ", 4) == 0) {
2822 if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4))
2824 } else if (os_strncmp(buf, "GET ", 4) == 0) {
2825 reply_len = wpa_supplicant_ctrl_iface_get(wpa_s, buf + 4,
2827 } else if (os_strcmp(buf, "LOGON") == 0) {
2828 eapol_sm_notify_logoff(wpa_s->eapol, FALSE);
2829 } else if (os_strcmp(buf, "LOGOFF") == 0) {
2830 eapol_sm_notify_logoff(wpa_s->eapol, TRUE);
2831 } else if (os_strcmp(buf, "REASSOCIATE") == 0) {
2832 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
2835 wpa_s->disconnected = 0;
2836 wpa_s->reassociate = 1;
2837 wpa_supplicant_req_scan(wpa_s, 0, 0);
2839 } else if (os_strcmp(buf, "RECONNECT") == 0) {
2840 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
2842 else if (wpa_s->disconnected) {
2843 wpa_s->disconnected = 0;
2844 wpa_s->reassociate = 1;
2845 wpa_supplicant_req_scan(wpa_s, 0, 0);
2847 #ifdef IEEE8021X_EAPOL
2848 } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) {
2849 if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8))
2851 #endif /* IEEE8021X_EAPOL */
2852 #ifdef CONFIG_PEERKEY
2853 } else if (os_strncmp(buf, "STKSTART ", 9) == 0) {
2854 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9))
2856 #endif /* CONFIG_PEERKEY */
2857 #ifdef CONFIG_IEEE80211R
2858 } else if (os_strncmp(buf, "FT_DS ", 6) == 0) {
2859 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6))
2861 #endif /* CONFIG_IEEE80211R */
2863 } else if (os_strcmp(buf, "WPS_PBC") == 0) {
2864 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, NULL))
2866 } else if (os_strncmp(buf, "WPS_PBC ", 8) == 0) {
2867 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, buf + 8))
2869 } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
2870 reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8,
2873 } else if (os_strncmp(buf, "WPS_CHECK_PIN ", 14) == 0) {
2874 reply_len = wpa_supplicant_ctrl_iface_wps_check_pin(
2875 wpa_s, buf + 14, reply, reply_size);
2876 } else if (os_strcmp(buf, "WPS_CANCEL") == 0) {
2877 if (wpas_wps_cancel(wpa_s))
2879 #ifdef CONFIG_WPS_OOB
2880 } else if (os_strncmp(buf, "WPS_OOB ", 8) == 0) {
2881 if (wpa_supplicant_ctrl_iface_wps_oob(wpa_s, buf + 8))
2883 #endif /* CONFIG_WPS_OOB */
2884 } else if (os_strncmp(buf, "WPS_REG ", 8) == 0) {
2885 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8))
2888 } else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) {
2889 reply_len = wpa_supplicant_ctrl_iface_wps_ap_pin(
2890 wpa_s, buf + 11, reply, reply_size);
2891 #endif /* CONFIG_AP */
2892 #ifdef CONFIG_WPS_ER
2893 } else if (os_strcmp(buf, "WPS_ER_START") == 0) {
2894 if (wpas_wps_er_start(wpa_s, NULL))
2896 } else if (os_strncmp(buf, "WPS_ER_START ", 13) == 0) {
2897 if (wpas_wps_er_start(wpa_s, buf + 13))
2899 } else if (os_strcmp(buf, "WPS_ER_STOP") == 0) {
2900 if (wpas_wps_er_stop(wpa_s))
2902 } else if (os_strncmp(buf, "WPS_ER_PIN ", 11) == 0) {
2903 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s, buf + 11))
2905 } else if (os_strncmp(buf, "WPS_ER_PBC ", 11) == 0) {
2906 int ret = wpas_wps_er_pbc(wpa_s, buf + 11);
2908 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17);
2910 } else if (ret == -3) {
2911 os_memcpy(reply, "FAIL-UNKNOWN-UUID\n", 18);
2913 } else if (ret == -4) {
2914 os_memcpy(reply, "FAIL-NO-AP-SETTINGS\n", 20);
2918 } else if (os_strncmp(buf, "WPS_ER_LEARN ", 13) == 0) {
2919 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s, buf + 13))
2921 } else if (os_strncmp(buf, "WPS_ER_SET_CONFIG ", 18) == 0) {
2922 if (wpa_supplicant_ctrl_iface_wps_er_set_config(wpa_s,
2925 } else if (os_strncmp(buf, "WPS_ER_CONFIG ", 14) == 0) {
2926 if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s, buf + 14))
2928 #endif /* CONFIG_WPS_ER */
2929 #endif /* CONFIG_WPS */
2930 #ifdef CONFIG_IBSS_RSN
2931 } else if (os_strncmp(buf, "IBSS_RSN ", 9) == 0) {
2932 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s, buf + 9))
2934 #endif /* CONFIG_IBSS_RSN */
2936 } else if (os_strncmp(buf, "P2P_FIND ", 9) == 0) {
2937 if (p2p_ctrl_find(wpa_s, buf + 9))
2939 } else if (os_strcmp(buf, "P2P_FIND") == 0) {
2940 if (p2p_ctrl_find(wpa_s, ""))
2942 } else if (os_strcmp(buf, "P2P_STOP_FIND") == 0) {
2943 wpas_p2p_stop_find(wpa_s);
2944 } else if (os_strncmp(buf, "P2P_CONNECT ", 12) == 0) {
2945 reply_len = p2p_ctrl_connect(wpa_s, buf + 12, reply,
2947 } else if (os_strncmp(buf, "P2P_LISTEN ", 11) == 0) {
2948 if (p2p_ctrl_listen(wpa_s, buf + 11))
2950 } else if (os_strcmp(buf, "P2P_LISTEN") == 0) {
2951 if (p2p_ctrl_listen(wpa_s, ""))
2953 } else if (os_strncmp(buf, "P2P_GROUP_REMOVE ", 17) == 0) {
2954 if (wpas_p2p_group_remove(wpa_s, buf + 17))
2956 } else if (os_strcmp(buf, "P2P_GROUP_ADD") == 0) {
2957 if (wpas_p2p_group_add(wpa_s, 0, 0))
2959 } else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) {
2960 if (p2p_ctrl_group_add(wpa_s, buf + 14))
2962 } else if (os_strncmp(buf, "P2P_PROV_DISC ", 14) == 0) {
2963 if (p2p_ctrl_prov_disc(wpa_s, buf + 14))
2965 } else if (os_strcmp(buf, "P2P_GET_PASSPHRASE") == 0) {
2966 reply_len = p2p_get_passphrase(wpa_s, reply, reply_size);
2967 } else if (os_strncmp(buf, "P2P_SERV_DISC_REQ ", 18) == 0) {
2968 reply_len = p2p_ctrl_serv_disc_req(wpa_s, buf + 18, reply,
2970 } else if (os_strncmp(buf, "P2P_SERV_DISC_CANCEL_REQ ", 25) == 0) {
2971 if (p2p_ctrl_serv_disc_cancel_req(wpa_s, buf + 25) < 0)
2973 } else if (os_strncmp(buf, "P2P_SERV_DISC_RESP ", 19) == 0) {
2974 if (p2p_ctrl_serv_disc_resp(wpa_s, buf + 19) < 0)
2976 } else if (os_strcmp(buf, "P2P_SERVICE_UPDATE") == 0) {
2977 wpas_p2p_sd_service_update(wpa_s);
2978 } else if (os_strncmp(buf, "P2P_SERV_DISC_EXTERNAL ", 23) == 0) {
2979 if (p2p_ctrl_serv_disc_external(wpa_s, buf + 23) < 0)
2981 } else if (os_strcmp(buf, "P2P_SERVICE_FLUSH") == 0) {
2982 wpas_p2p_service_flush(wpa_s);
2983 } else if (os_strncmp(buf, "P2P_SERVICE_ADD ", 16) == 0) {
2984 if (p2p_ctrl_service_add(wpa_s, buf + 16) < 0)
2986 } else if (os_strncmp(buf, "P2P_SERVICE_DEL ", 16) == 0) {
2987 if (p2p_ctrl_service_del(wpa_s, buf + 16) < 0)
2989 } else if (os_strncmp(buf, "P2P_REJECT ", 11) == 0) {
2990 if (p2p_ctrl_reject(wpa_s, buf + 11) < 0)
2992 } else if (os_strncmp(buf, "P2P_INVITE ", 11) == 0) {
2993 if (p2p_ctrl_invite(wpa_s, buf + 11) < 0)
2995 } else if (os_strncmp(buf, "P2P_PEER ", 9) == 0) {
2996 reply_len = p2p_ctrl_peer(wpa_s, buf + 9, reply,
2998 } else if (os_strncmp(buf, "P2P_SET ", 8) == 0) {
2999 if (p2p_ctrl_set(wpa_s, buf + 8) < 0)
3001 } else if (os_strcmp(buf, "P2P_FLUSH") == 0) {
3002 os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
3003 wpa_s->force_long_sd = 0;
3004 if (wpa_s->global->p2p)
3005 p2p_flush(wpa_s->global->p2p);
3006 } else if (os_strncmp(buf, "P2P_UNAUTHORIZE ", 16) == 0) {
3007 if (wpas_p2p_unauthorize(wpa_s, buf + 16) < 0)
3009 } else if (os_strcmp(buf, "P2P_CANCEL") == 0) {
3010 if (wpas_p2p_cancel(wpa_s))
3012 } else if (os_strncmp(buf, "P2P_PRESENCE_REQ ", 17) == 0) {
3013 if (p2p_ctrl_presence_req(wpa_s, buf + 17) < 0)
3015 } else if (os_strcmp(buf, "P2P_PRESENCE_REQ") == 0) {
3016 if (p2p_ctrl_presence_req(wpa_s, "") < 0)
3018 } else if (os_strncmp(buf, "P2P_EXT_LISTEN ", 15) == 0) {
3019 if (p2p_ctrl_ext_listen(wpa_s, buf + 15) < 0)
3021 } else if (os_strcmp(buf, "P2P_EXT_LISTEN") == 0) {
3022 if (p2p_ctrl_ext_listen(wpa_s, "") < 0)
3024 #endif /* CONFIG_P2P */
3025 } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0)
3027 if (wpa_supplicant_ctrl_iface_ctrl_rsp(
3028 wpa_s, buf + os_strlen(WPA_CTRL_RSP)))
3032 } else if (os_strcmp(buf, "RECONFIGURE") == 0) {
3033 if (wpa_supplicant_reload_configuration(wpa_s))
3035 } else if (os_strcmp(buf, "TERMINATE") == 0) {
3036 wpa_supplicant_terminate_proc(wpa_s->global);
3037 } else if (os_strncmp(buf, "BSSID ", 6) == 0) {
3038 if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6))
3040 } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) {
3041 reply_len = wpa_supplicant_ctrl_iface_list_networks(
3042 wpa_s, reply, reply_size);
3043 } else if (os_strcmp(buf, "DISCONNECT") == 0) {
3044 wpa_s->reassociate = 0;
3045 wpa_s->disconnected = 1;
3046 wpa_supplicant_deauthenticate(wpa_s,
3047 WLAN_REASON_DEAUTH_LEAVING);
3048 } else if (os_strcmp(buf, "SCAN") == 0) {
3049 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
3052 wpa_s->scan_req = 2;
3053 wpa_supplicant_req_scan(wpa_s, 0, 0);
3055 } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) {
3056 reply_len = wpa_supplicant_ctrl_iface_scan_results(
3057 wpa_s, reply, reply_size);
3058 } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) {
3059 if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15))
3061 } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) {
3062 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15))
3064 } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) {
3065 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16))
3067 } else if (os_strcmp(buf, "ADD_NETWORK") == 0) {
3068 reply_len = wpa_supplicant_ctrl_iface_add_network(
3069 wpa_s, reply, reply_size);
3070 } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) {
3071 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15))
3073 } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
3074 if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12))
3076 } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
3077 reply_len = wpa_supplicant_ctrl_iface_get_network(
3078 wpa_s, buf + 12, reply, reply_size);
3079 #ifndef CONFIG_NO_CONFIG_WRITE
3080 } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
3081 if (wpa_supplicant_ctrl_iface_save_config(wpa_s))
3083 #endif /* CONFIG_NO_CONFIG_WRITE */
3084 } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
3085 reply_len = wpa_supplicant_ctrl_iface_get_capability(
3086 wpa_s, buf + 15, reply, reply_size);
3087 } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) {
3088 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8))
3090 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
3091 reply_len = wpa_supplicant_global_iface_list(
3092 wpa_s->global, reply, reply_size);
3093 } else if (os_strcmp(buf, "INTERFACES") == 0) {
3094 reply_len = wpa_supplicant_global_iface_interfaces(
3095 wpa_s->global, reply, reply_size);
3096 } else if (os_strncmp(buf, "BSS ", 4) == 0) {
3097 reply_len = wpa_supplicant_ctrl_iface_bss(
3098 wpa_s, buf + 4, reply, reply_size);
3100 } else if (os_strcmp(buf, "STA-FIRST") == 0) {
3101 reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
3102 } else if (os_strncmp(buf, "STA ", 4) == 0) {
3103 reply_len = ap_ctrl_iface_sta(wpa_s, buf + 4, reply,
3105 } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
3106 reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
3108 #endif /* CONFIG_AP */
3109 } else if (os_strcmp(buf, "SUSPEND") == 0) {
3110 wpas_notify_suspend(wpa_s->global);
3111 } else if (os_strcmp(buf, "RESUME") == 0) {
3112 wpas_notify_resume(wpa_s->global);
3113 } else if (os_strcmp(buf, "DROP_SA") == 0) {
3114 wpa_supplicant_ctrl_iface_drop_sa(wpa_s);
3115 } else if (os_strncmp(buf, "ROAM ", 5) == 0) {
3116 if (wpa_supplicant_ctrl_iface_roam(wpa_s, buf + 5))
3118 } else if (os_strncmp(buf, "STA_AUTOCONNECT ", 16) == 0) {
3119 if (wpa_supplicant_ctrl_iface_sta_autoconnect(wpa_s, buf + 16))
3122 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
3126 if (reply_len < 0) {
3127 os_memcpy(reply, "FAIL\n", 5);
3132 eapol_sm_notify_ctrl_response(wpa_s->eapol);
3134 *resp_len = reply_len;
3139 static int wpa_supplicant_global_iface_add(struct wpa_global *global,
3142 struct wpa_interface iface;
3146 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
3147 * TAB<bridge_ifname>
3149 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd);
3151 os_memset(&iface, 0, sizeof(iface));
3154 iface.ifname = pos = cmd;
3155 pos = os_strchr(pos, '\t');
3158 if (iface.ifname[0] == '\0')
3163 iface.confname = pos;
3164 pos = os_strchr(pos, '\t');
3167 if (iface.confname[0] == '\0')
3168 iface.confname = NULL;
3173 pos = os_strchr(pos, '\t');
3176 if (iface.driver[0] == '\0')
3177 iface.driver = NULL;
3181 iface.ctrl_interface = pos;
3182 pos = os_strchr(pos, '\t');
3185 if (iface.ctrl_interface[0] == '\0')
3186 iface.ctrl_interface = NULL;
3190 iface.driver_param = pos;
3191 pos = os_strchr(pos, '\t');
3194 if (iface.driver_param[0] == '\0')
3195 iface.driver_param = NULL;
3199 iface.bridge_ifname = pos;
3200 pos = os_strchr(pos, '\t');
3203 if (iface.bridge_ifname[0] == '\0')
3204 iface.bridge_ifname = NULL;
3209 if (wpa_supplicant_get_iface(global, iface.ifname))
3212 return wpa_supplicant_add_iface(global, &iface) ? 0 : -1;
3216 static int wpa_supplicant_global_iface_remove(struct wpa_global *global,
3219 struct wpa_supplicant *wpa_s;
3221 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd);
3223 wpa_s = wpa_supplicant_get_iface(global, cmd);
3226 return wpa_supplicant_remove_iface(global, wpa_s);
3230 static void wpa_free_iface_info(struct wpa_interface_info *iface)
3232 struct wpa_interface_info *prev;
3236 iface = iface->next;
3238 os_free(prev->ifname);
3239 os_free(prev->desc);
3245 static int wpa_supplicant_global_iface_list(struct wpa_global *global,
3249 struct wpa_interface_info *iface = NULL, *last = NULL, *tmp;
3252 for (i = 0; wpa_drivers[i]; i++) {
3253 struct wpa_driver_ops *drv = wpa_drivers[i];
3254 if (drv->get_interfaces == NULL)
3256 tmp = drv->get_interfaces(global->drv_priv[i]);
3270 for (tmp = iface; tmp; tmp = tmp->next) {
3271 res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n",
3272 tmp->drv_name, tmp->ifname,
3273 tmp->desc ? tmp->desc : "");
3274 if (res < 0 || res >= end - pos) {
3281 wpa_free_iface_info(iface);
3287 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
3292 struct wpa_supplicant *wpa_s;
3294 wpa_s = global->ifaces;
3299 res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname);
3300 if (res < 0 || res >= end - pos) {
3305 wpa_s = wpa_s->next;
3311 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
3312 char *buf, size_t *resp_len)
3315 const int reply_size = 2048;
3318 wpa_hexdump_ascii(MSG_DEBUG, "RX global ctrl_iface",
3319 (const u8 *) buf, os_strlen(buf));
3321 reply = os_malloc(reply_size);
3322 if (reply == NULL) {
3327 os_memcpy(reply, "OK\n", 3);
3330 if (os_strcmp(buf, "PING") == 0) {
3331 os_memcpy(reply, "PONG\n", 5);
3333 } else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) {
3334 if (wpa_supplicant_global_iface_add(global, buf + 14))
3336 } else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) {
3337 if (wpa_supplicant_global_iface_remove(global, buf + 17))
3339 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
3340 reply_len = wpa_supplicant_global_iface_list(
3341 global, reply, reply_size);
3342 } else if (os_strcmp(buf, "INTERFACES") == 0) {
3343 reply_len = wpa_supplicant_global_iface_interfaces(
3344 global, reply, reply_size);
3345 } else if (os_strcmp(buf, "TERMINATE") == 0) {
3346 wpa_supplicant_terminate_proc(global);
3347 } else if (os_strcmp(buf, "SUSPEND") == 0) {
3348 wpas_notify_suspend(global);
3349 } else if (os_strcmp(buf, "RESUME") == 0) {
3350 wpas_notify_resume(global);
3352 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
3356 if (reply_len < 0) {
3357 os_memcpy(reply, "FAIL\n", 5);
3361 *resp_len = reply_len;