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"
34 #include "p2p_supplicant.h"
39 #include "ctrl_iface.h"
41 extern struct wpa_driver_ops *wpa_drivers[];
43 static int wpa_supplicant_global_iface_list(struct wpa_global *global,
45 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
49 static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
55 value = os_strchr(cmd, ' ');
60 wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value);
61 if (os_strcasecmp(cmd, "EAPOL::heldPeriod") == 0) {
62 eapol_sm_configure(wpa_s->eapol,
63 atoi(value), -1, -1, -1);
64 } else if (os_strcasecmp(cmd, "EAPOL::authPeriod") == 0) {
65 eapol_sm_configure(wpa_s->eapol,
66 -1, atoi(value), -1, -1);
67 } else if (os_strcasecmp(cmd, "EAPOL::startPeriod") == 0) {
68 eapol_sm_configure(wpa_s->eapol,
69 -1, -1, atoi(value), -1);
70 } else if (os_strcasecmp(cmd, "EAPOL::maxStart") == 0) {
71 eapol_sm_configure(wpa_s->eapol,
72 -1, -1, -1, atoi(value));
73 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) {
74 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
77 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") ==
79 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
82 } else if (os_strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) {
83 if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value)))
85 } else if (os_strcasecmp(cmd, "wps_fragment_size") == 0) {
86 wpa_s->wps_fragment_size = atoi(value);
87 #ifdef CONFIG_WPS_TESTING
88 } else if (os_strcasecmp(cmd, "wps_version_number") == 0) {
90 val = strtol(value, NULL, 0);
91 if (val < 0 || val > 0xff) {
93 wpa_printf(MSG_DEBUG, "WPS: Invalid "
94 "wps_version_number %ld", val);
96 wps_version_number = val;
97 wpa_printf(MSG_DEBUG, "WPS: Testing - force WPS "
99 (wps_version_number & 0xf0) >> 4,
100 wps_version_number & 0x0f);
102 } else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) {
103 wps_testing_dummy_cred = atoi(value);
104 wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d",
105 wps_testing_dummy_cred);
106 #endif /* CONFIG_WPS_TESTING */
107 } else if (os_strcasecmp(cmd, "ampdu") == 0) {
108 if (wpa_drv_ampdu(wpa_s, atoi(value)) < 0)
112 ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
114 wpa_supplicant_update_config(wpa_s);
121 #ifdef IEEE8021X_EAPOL
122 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s,
126 struct wpa_ssid *ssid = wpa_s->current_ssid;
128 if (hwaddr_aton(addr, bssid)) {
129 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address "
134 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid));
135 rsn_preauth_deinit(wpa_s->wpa);
136 if (rsn_preauth_init(wpa_s->wpa, bssid, ssid ? &ssid->eap : NULL))
141 #endif /* IEEE8021X_EAPOL */
144 #ifdef CONFIG_PEERKEY
145 /* MLME-STKSTART.request(peer) */
146 static int wpa_supplicant_ctrl_iface_stkstart(
147 struct wpa_supplicant *wpa_s, char *addr)
151 if (hwaddr_aton(addr, peer)) {
152 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid "
153 "address '%s'", addr);
157 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART " MACSTR,
160 return wpa_sm_stkstart(wpa_s->wpa, peer);
162 #endif /* CONFIG_PEERKEY */
165 #ifdef CONFIG_IEEE80211R
166 static int wpa_supplicant_ctrl_iface_ft_ds(
167 struct wpa_supplicant *wpa_s, char *addr)
169 u8 target_ap[ETH_ALEN];
173 if (hwaddr_aton(addr, target_ap)) {
174 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS: invalid "
175 "address '%s'", addr);
179 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS " MACSTR, MAC2STR(target_ap));
181 bss = wpa_bss_get_bssid(wpa_s, target_ap);
183 mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
187 return wpa_ft_start_over_ds(wpa_s->wpa, target_ap, mdie);
189 #endif /* CONFIG_IEEE80211R */
193 static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
196 u8 bssid[ETH_ALEN], *_bssid = bssid;
198 if (cmd == NULL || os_strcmp(cmd, "any") == 0)
200 else if (hwaddr_aton(cmd, bssid)) {
201 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
208 return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid);
209 #endif /* CONFIG_AP */
211 return wpas_wps_start_pbc(wpa_s, _bssid, 0);
215 static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
216 char *cmd, char *buf,
219 u8 bssid[ETH_ALEN], *_bssid = bssid;
223 pin = os_strchr(cmd, ' ');
227 if (os_strcmp(cmd, "any") == 0)
229 else if (hwaddr_aton(cmd, bssid)) {
230 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
237 return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin,
239 #endif /* CONFIG_AP */
242 ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0,
246 ret = os_snprintf(buf, buflen, "%s", pin);
247 if (ret < 0 || (size_t) ret >= buflen)
252 ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0, DEV_PW_DEFAULT);
256 /* Return the generated PIN */
257 ret = os_snprintf(buf, buflen, "%08d", ret);
258 if (ret < 0 || (size_t) ret >= buflen)
264 static int wpa_supplicant_ctrl_iface_wps_check_pin(
265 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
272 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS_CHECK_PIN",
273 (u8 *) cmd, os_strlen(cmd));
274 for (pos = cmd, len = 0; *pos != '\0'; pos++) {
275 if (*pos < '0' || *pos > '9')
279 wpa_printf(MSG_DEBUG, "WPS: Too long PIN");
283 if (len != 4 && len != 8) {
284 wpa_printf(MSG_DEBUG, "WPS: Invalid PIN length %d", (int) len);
290 unsigned int pin_val;
292 if (!wps_pin_valid(pin_val)) {
293 wpa_printf(MSG_DEBUG, "WPS: Invalid checksum digit");
294 ret = os_snprintf(buf, buflen, "FAIL-CHECKSUM\n");
295 if (ret < 0 || (size_t) ret >= buflen)
301 ret = os_snprintf(buf, buflen, "%s", pin);
302 if (ret < 0 || (size_t) ret >= buflen)
309 #ifdef CONFIG_WPS_OOB
310 static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant *wpa_s,
313 char *path, *method, *name;
315 path = os_strchr(cmd, ' ');
320 method = os_strchr(path, ' ');
325 name = os_strchr(method, ' ');
329 return wpas_wps_start_oob(wpa_s, cmd, path, method, name);
331 #endif /* CONFIG_WPS_OOB */
334 static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s,
343 struct wps_new_ap_settings ap;
345 pin = os_strchr(cmd, ' ');
350 if (hwaddr_aton(cmd, bssid)) {
351 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_REG: invalid BSSID '%s'",
356 new_ssid = os_strchr(pin, ' ');
357 if (new_ssid == NULL)
358 return wpas_wps_start_reg(wpa_s, bssid, pin, NULL);
361 new_auth = os_strchr(new_ssid, ' ');
362 if (new_auth == NULL)
366 new_encr = os_strchr(new_auth, ' ');
367 if (new_encr == NULL)
371 new_key = os_strchr(new_encr, ' ');
376 os_memset(&ap, 0, sizeof(ap));
377 ap.ssid_hex = new_ssid;
380 ap.key_hex = new_key;
381 return wpas_wps_start_reg(wpa_s, bssid, pin, &ap);
386 static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant *wpa_s,
389 char *uuid = cmd, *pin, *pos;
390 u8 addr_buf[ETH_ALEN], *addr = NULL;
391 pin = os_strchr(uuid, ' ');
395 pos = os_strchr(pin, ' ');
398 if (hwaddr_aton(pos, addr_buf) == 0)
401 return wpas_wps_er_add_pin(wpa_s, addr, uuid, pin);
405 static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant *wpa_s,
408 char *uuid = cmd, *pin;
409 pin = os_strchr(uuid, ' ');
413 return wpas_wps_er_learn(wpa_s, uuid, pin);
417 static int wpa_supplicant_ctrl_iface_wps_er_set_config(
418 struct wpa_supplicant *wpa_s, char *cmd)
420 char *uuid = cmd, *id;
421 id = os_strchr(uuid, ' ');
425 return wpas_wps_er_set_config(wpa_s, uuid, atoi(id));
429 static int wpa_supplicant_ctrl_iface_wps_er_config(
430 struct wpa_supplicant *wpa_s, char *cmd)
437 struct wps_new_ap_settings ap;
439 pin = os_strchr(cmd, ' ');
444 new_ssid = os_strchr(pin, ' ');
445 if (new_ssid == NULL)
449 new_auth = os_strchr(new_ssid, ' ');
450 if (new_auth == NULL)
454 new_encr = os_strchr(new_auth, ' ');
455 if (new_encr == NULL)
459 new_key = os_strchr(new_encr, ' ');
464 os_memset(&ap, 0, sizeof(ap));
465 ap.ssid_hex = new_ssid;
468 ap.key_hex = new_key;
469 return wpas_wps_er_config(wpa_s, cmd, pin, &ap);
471 #endif /* CONFIG_WPS_ER */
473 #endif /* CONFIG_WPS */
476 #ifdef CONFIG_IBSS_RSN
477 static int wpa_supplicant_ctrl_iface_ibss_rsn(
478 struct wpa_supplicant *wpa_s, char *addr)
482 if (hwaddr_aton(addr, peer)) {
483 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN: invalid "
484 "address '%s'", addr);
488 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN " MACSTR,
491 return ibss_rsn_start(wpa_s->ibss_rsn, peer);
493 #endif /* CONFIG_IBSS_RSN */
496 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
499 #ifdef IEEE8021X_EAPOL
502 struct wpa_ssid *ssid;
503 struct eap_peer_config *eap;
505 pos = os_strchr(rsp, '-');
510 pos = os_strchr(pos, ':');
515 wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id);
516 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
517 (u8 *) pos, os_strlen(pos));
519 ssid = wpa_config_get_network(wpa_s->conf, id);
521 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
527 if (os_strcmp(rsp, "IDENTITY") == 0) {
528 os_free(eap->identity);
529 eap->identity = (u8 *) os_strdup(pos);
530 eap->identity_len = os_strlen(pos);
531 eap->pending_req_identity = 0;
532 if (ssid == wpa_s->current_ssid)
533 wpa_s->reassociate = 1;
534 } else if (os_strcmp(rsp, "PASSWORD") == 0) {
535 os_free(eap->password);
536 eap->password = (u8 *) os_strdup(pos);
537 eap->password_len = os_strlen(pos);
538 eap->pending_req_password = 0;
539 if (ssid == wpa_s->current_ssid)
540 wpa_s->reassociate = 1;
541 } else if (os_strcmp(rsp, "NEW_PASSWORD") == 0) {
542 os_free(eap->new_password);
543 eap->new_password = (u8 *) os_strdup(pos);
544 eap->new_password_len = os_strlen(pos);
545 eap->pending_req_new_password = 0;
546 if (ssid == wpa_s->current_ssid)
547 wpa_s->reassociate = 1;
548 } else if (os_strcmp(rsp, "PIN") == 0) {
550 eap->pin = os_strdup(pos);
551 eap->pending_req_pin = 0;
552 if (ssid == wpa_s->current_ssid)
553 wpa_s->reassociate = 1;
554 } else if (os_strcmp(rsp, "OTP") == 0) {
556 eap->otp = (u8 *) os_strdup(pos);
557 eap->otp_len = os_strlen(pos);
558 os_free(eap->pending_req_otp);
559 eap->pending_req_otp = NULL;
560 eap->pending_req_otp_len = 0;
561 } else if (os_strcmp(rsp, "PASSPHRASE") == 0) {
562 os_free(eap->private_key_passwd);
563 eap->private_key_passwd = (u8 *) os_strdup(pos);
564 eap->pending_req_passphrase = 0;
565 if (ssid == wpa_s->current_ssid)
566 wpa_s->reassociate = 1;
568 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", rsp);
573 #else /* IEEE8021X_EAPOL */
574 wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
576 #endif /* IEEE8021X_EAPOL */
580 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
582 char *buf, size_t buflen)
584 char *pos, *end, tmp[30];
585 int res, verbose, ret;
587 verbose = os_strcmp(params, "-VERBOSE") == 0;
590 if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
591 struct wpa_ssid *ssid = wpa_s->current_ssid;
592 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
593 MAC2STR(wpa_s->bssid));
594 if (ret < 0 || ret >= end - pos)
598 u8 *_ssid = ssid->ssid;
599 size_t ssid_len = ssid->ssid_len;
600 u8 ssid_buf[MAX_SSID_LEN];
602 int _res = wpa_drv_get_ssid(wpa_s, ssid_buf);
609 ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n",
610 wpa_ssid_txt(_ssid, ssid_len),
612 if (ret < 0 || ret >= end - pos)
617 ret = os_snprintf(pos, end - pos,
620 if (ret < 0 || ret >= end - pos)
625 switch (ssid->mode) {
626 case WPAS_MODE_INFRA:
627 ret = os_snprintf(pos, end - pos,
631 ret = os_snprintf(pos, end - pos,
635 ret = os_snprintf(pos, end - pos,
638 case WPAS_MODE_P2P_GO:
639 ret = os_snprintf(pos, end - pos,
642 case WPAS_MODE_P2P_GROUP_FORMATION:
643 ret = os_snprintf(pos, end - pos,
644 "mode=P2P GO - group "
651 if (ret < 0 || ret >= end - pos)
657 if (wpa_s->ap_iface) {
658 pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
662 #endif /* CONFIG_AP */
663 pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose);
665 ret = os_snprintf(pos, end - pos, "wpa_state=%s\n",
666 wpa_supplicant_state_txt(wpa_s->wpa_state));
667 if (ret < 0 || ret >= end - pos)
672 l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) {
673 ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp);
674 if (ret < 0 || ret >= end - pos)
680 if (wpa_s->global->p2p) {
681 ret = os_snprintf(pos, end - pos, "p2p_device_address=" MACSTR
682 "\n", MAC2STR(wpa_s->global->p2p_dev_addr));
683 if (ret < 0 || ret >= end - pos)
688 ret = os_snprintf(pos, end - pos, "address=" MACSTR "\n",
689 MAC2STR(wpa_s->own_addr));
690 if (ret < 0 || ret >= end - pos)
693 #endif /* CONFIG_P2P */
695 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
696 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
697 res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos,
703 res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose);
711 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s,
716 struct wpa_ssid *ssid;
719 /* cmd: "<network id> <BSSID>" */
720 pos = os_strchr(cmd, ' ');
725 wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos);
726 if (hwaddr_aton(pos, bssid)) {
727 wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos);
731 ssid = wpa_config_get_network(wpa_s->conf, id);
733 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
738 os_memcpy(ssid->bssid, bssid, ETH_ALEN);
739 ssid->bssid_set = !is_zero_ether_addr(bssid);
745 static int wpa_supplicant_ctrl_iface_list_networks(
746 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
749 struct wpa_ssid *ssid;
754 ret = os_snprintf(pos, end - pos,
755 "network id / ssid / bssid / flags\n");
756 if (ret < 0 || ret >= end - pos)
760 ssid = wpa_s->conf->ssid;
762 ret = os_snprintf(pos, end - pos, "%d\t%s",
764 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
765 if (ret < 0 || ret >= end - pos)
768 if (ssid->bssid_set) {
769 ret = os_snprintf(pos, end - pos, "\t" MACSTR,
770 MAC2STR(ssid->bssid));
772 ret = os_snprintf(pos, end - pos, "\tany");
774 if (ret < 0 || ret >= end - pos)
777 ret = os_snprintf(pos, end - pos, "\t%s%s%s",
778 ssid == wpa_s->current_ssid ?
780 ssid->disabled ? "[DISABLED]" : "",
781 ssid->disabled == 2 ? "[P2P-PERSISTENT]" :
783 if (ret < 0 || ret >= end - pos)
786 ret = os_snprintf(pos, end - pos, "\n");
787 if (ret < 0 || ret >= end - pos)
798 static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher)
801 ret = os_snprintf(pos, end - pos, "-");
802 if (ret < 0 || ret >= end - pos)
805 if (cipher & WPA_CIPHER_NONE) {
806 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : "+");
807 if (ret < 0 || ret >= end - pos)
812 if (cipher & WPA_CIPHER_WEP40) {
813 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : "+");
814 if (ret < 0 || ret >= end - pos)
819 if (cipher & WPA_CIPHER_WEP104) {
820 ret = os_snprintf(pos, end - pos, "%sWEP104",
822 if (ret < 0 || ret >= end - pos)
827 if (cipher & WPA_CIPHER_TKIP) {
828 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : "+");
829 if (ret < 0 || ret >= end - pos)
834 if (cipher & WPA_CIPHER_CCMP) {
835 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : "+");
836 if (ret < 0 || ret >= end - pos)
845 static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
846 const u8 *ie, size_t ie_len)
848 struct wpa_ie_data data;
851 ret = os_snprintf(pos, end - pos, "[%s-", proto);
852 if (ret < 0 || ret >= end - pos)
856 if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) {
857 ret = os_snprintf(pos, end - pos, "?]");
858 if (ret < 0 || ret >= end - pos)
865 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
866 ret = os_snprintf(pos, end - pos, "%sEAP", first ? "" : "+");
867 if (ret < 0 || ret >= end - pos)
872 if (data.key_mgmt & WPA_KEY_MGMT_PSK) {
873 ret = os_snprintf(pos, end - pos, "%sPSK", first ? "" : "+");
874 if (ret < 0 || ret >= end - pos)
879 if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
880 ret = os_snprintf(pos, end - pos, "%sNone", first ? "" : "+");
881 if (ret < 0 || ret >= end - pos)
886 #ifdef CONFIG_IEEE80211R
887 if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
888 ret = os_snprintf(pos, end - pos, "%sFT/EAP",
890 if (ret < 0 || ret >= end - pos)
895 if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) {
896 ret = os_snprintf(pos, end - pos, "%sFT/PSK",
898 if (ret < 0 || ret >= end - pos)
903 #endif /* CONFIG_IEEE80211R */
904 #ifdef CONFIG_IEEE80211W
905 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
906 ret = os_snprintf(pos, end - pos, "%sEAP-SHA256",
908 if (ret < 0 || ret >= end - pos)
913 if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
914 ret = os_snprintf(pos, end - pos, "%sPSK-SHA256",
916 if (ret < 0 || ret >= end - pos)
921 #endif /* CONFIG_IEEE80211W */
923 pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher);
925 if (data.capabilities & WPA_CAPABILITY_PREAUTH) {
926 ret = os_snprintf(pos, end - pos, "-preauth");
927 if (ret < 0 || ret >= end - pos)
932 ret = os_snprintf(pos, end - pos, "]");
933 if (ret < 0 || ret >= end - pos)
942 static char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant *wpa_s,
943 char *pos, char *end,
944 struct wpabuf *wps_ie)
951 if (wps_is_selected_pbc_registrar(wps_ie))
954 else if (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 0))
956 #endif /* CONFIG_WPS2 */
957 else if (wps_is_selected_pin_registrar(wps_ie))
962 ret = os_snprintf(pos, end - pos, "%s", txt);
963 if (ret >= 0 && ret < end - pos)
968 #endif /* CONFIG_WPS */
971 static char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant *wpa_s,
972 char *pos, char *end,
973 const struct wpa_bss *bss)
976 struct wpabuf *wps_ie;
977 wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
978 return wpa_supplicant_wps_ie_txt_buf(wpa_s, pos, end, wps_ie);
979 #else /* CONFIG_WPS */
981 #endif /* CONFIG_WPS */
985 /* Format one result on one text line into a buffer. */
986 static int wpa_supplicant_ctrl_iface_scan_result(
987 struct wpa_supplicant *wpa_s,
988 const struct wpa_bss *bss, char *buf, size_t buflen)
992 const u8 *ie, *ie2, *p2p;
994 p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE);
995 if (p2p && bss->ssid_len == P2P_WILDCARD_SSID_LEN &&
996 os_memcmp(bss->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) ==
998 return 0; /* Do not show P2P listen discovery results here */
1003 ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t",
1004 MAC2STR(bss->bssid), bss->freq, bss->level);
1005 if (ret < 0 || ret >= end - pos)
1008 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
1010 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
1011 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1013 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
1014 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
1015 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
1016 ret = os_snprintf(pos, end - pos, "[WEP]");
1017 if (ret < 0 || ret >= end - pos)
1021 if (bss->caps & IEEE80211_CAP_IBSS) {
1022 ret = os_snprintf(pos, end - pos, "[IBSS]");
1023 if (ret < 0 || ret >= end - pos)
1027 if (bss->caps & IEEE80211_CAP_ESS) {
1028 ret = os_snprintf(pos, end - pos, "[ESS]");
1029 if (ret < 0 || ret >= end - pos)
1034 ret = os_snprintf(pos, end - pos, "[P2P]");
1035 if (ret < 0 || ret >= end - pos)
1040 ret = os_snprintf(pos, end - pos, "\t%s",
1041 wpa_ssid_txt(bss->ssid, bss->ssid_len));
1042 if (ret < 0 || ret >= end - pos)
1046 ret = os_snprintf(pos, end - pos, "\n");
1047 if (ret < 0 || ret >= end - pos)
1055 static int wpa_supplicant_ctrl_iface_scan_results(
1056 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
1059 struct wpa_bss *bss;
1064 ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / "
1066 if (ret < 0 || ret >= end - pos)
1070 dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
1071 ret = wpa_supplicant_ctrl_iface_scan_result(wpa_s, bss, pos,
1073 if (ret < 0 || ret >= end - pos)
1082 static int wpa_supplicant_ctrl_iface_select_network(
1083 struct wpa_supplicant *wpa_s, char *cmd)
1086 struct wpa_ssid *ssid;
1088 /* cmd: "<network id>" or "any" */
1089 if (os_strcmp(cmd, "any") == 0) {
1090 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any");
1094 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id);
1096 ssid = wpa_config_get_network(wpa_s->conf, id);
1098 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
1099 "network id=%d", id);
1102 if (ssid->disabled == 2) {
1103 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
1104 "SELECT_NETWORK with persistent P2P group");
1109 wpa_supplicant_select_network(wpa_s, ssid);
1115 static int wpa_supplicant_ctrl_iface_enable_network(
1116 struct wpa_supplicant *wpa_s, char *cmd)
1119 struct wpa_ssid *ssid;
1121 /* cmd: "<network id>" or "all" */
1122 if (os_strcmp(cmd, "all") == 0) {
1123 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all");
1127 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id);
1129 ssid = wpa_config_get_network(wpa_s->conf, id);
1131 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
1132 "network id=%d", id);
1135 if (ssid->disabled == 2) {
1136 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
1137 "ENABLE_NETWORK with persistent P2P group");
1141 wpa_supplicant_enable_network(wpa_s, ssid);
1147 static int wpa_supplicant_ctrl_iface_disable_network(
1148 struct wpa_supplicant *wpa_s, char *cmd)
1151 struct wpa_ssid *ssid;
1153 /* cmd: "<network id>" or "all" */
1154 if (os_strcmp(cmd, "all") == 0) {
1155 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all");
1159 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id);
1161 ssid = wpa_config_get_network(wpa_s->conf, id);
1163 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
1164 "network id=%d", id);
1167 if (ssid->disabled == 2) {
1168 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
1169 "DISABLE_NETWORK with persistent P2P "
1174 wpa_supplicant_disable_network(wpa_s, ssid);
1180 static int wpa_supplicant_ctrl_iface_add_network(
1181 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
1183 struct wpa_ssid *ssid;
1186 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK");
1188 ssid = wpa_config_add_network(wpa_s->conf);
1192 wpas_notify_network_added(wpa_s, ssid);
1195 wpa_config_set_network_defaults(ssid);
1197 ret = os_snprintf(buf, buflen, "%d\n", ssid->id);
1198 if (ret < 0 || (size_t) ret >= buflen)
1204 static int wpa_supplicant_ctrl_iface_remove_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: REMOVE_NETWORK all");
1213 ssid = wpa_s->conf->ssid;
1215 struct wpa_ssid *remove_ssid = ssid;
1218 wpas_notify_network_removed(wpa_s, remove_ssid);
1219 wpa_config_remove_network(wpa_s->conf, id);
1221 if (wpa_s->current_ssid) {
1222 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1223 wpa_supplicant_disassociate(wpa_s,
1224 WLAN_REASON_DEAUTH_LEAVING);
1230 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id);
1232 ssid = wpa_config_get_network(wpa_s->conf, id);
1234 wpa_config_remove_network(wpa_s->conf, id) < 0) {
1235 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1240 if (ssid == wpa_s->current_ssid) {
1242 * Invalidate the EAP session cache if the current network is
1245 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1247 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1254 static int wpa_supplicant_ctrl_iface_set_network(
1255 struct wpa_supplicant *wpa_s, char *cmd)
1258 struct wpa_ssid *ssid;
1261 /* cmd: "<network id> <variable name> <value>" */
1262 name = os_strchr(cmd, ' ');
1267 value = os_strchr(name, ' ');
1273 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
1275 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
1276 (u8 *) value, os_strlen(value));
1278 ssid = wpa_config_get_network(wpa_s->conf, id);
1280 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1285 if (wpa_config_set(ssid, name, value, 0) < 0) {
1286 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network "
1287 "variable '%s'", name);
1291 if (wpa_s->current_ssid == ssid) {
1293 * Invalidate the EAP session cache if anything in the current
1294 * configuration changes.
1296 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1299 if ((os_strcmp(name, "psk") == 0 &&
1300 value[0] == '"' && ssid->ssid_len) ||
1301 (os_strcmp(name, "ssid") == 0 && ssid->passphrase))
1302 wpa_config_update_psk(ssid);
1303 else if (os_strcmp(name, "priority") == 0)
1304 wpa_config_update_prio_list(wpa_s->conf);
1310 static int wpa_supplicant_ctrl_iface_get_network(
1311 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
1315 struct wpa_ssid *ssid;
1318 /* cmd: "<network id> <variable name>" */
1319 name = os_strchr(cmd, ' ');
1320 if (name == NULL || buflen == 0)
1325 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
1328 ssid = wpa_config_get_network(wpa_s->conf, id);
1330 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1335 value = wpa_config_get_no_key(ssid, name);
1336 if (value == NULL) {
1337 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network "
1338 "variable '%s'", name);
1342 res = os_strlcpy(buf, value, buflen);
1343 if (res >= buflen) {
1354 #ifndef CONFIG_NO_CONFIG_WRITE
1355 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s)
1359 if (!wpa_s->conf->update_config) {
1360 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
1361 "to update configuration (update_config=0)");
1365 ret = wpa_config_write(wpa_s->confname, wpa_s->conf);
1367 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to "
1368 "update configuration");
1370 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration"
1376 #endif /* CONFIG_NO_CONFIG_WRITE */
1379 static int ctrl_iface_get_capability_pairwise(int res, char *strict,
1380 struct wpa_driver_capa *capa,
1381 char *buf, size_t buflen)
1393 len = os_strlcpy(buf, "CCMP TKIP NONE", buflen);
1399 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1400 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " ");
1401 if (ret < 0 || ret >= end - pos)
1407 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1408 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " ");
1409 if (ret < 0 || ret >= end - pos)
1415 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1416 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : " ");
1417 if (ret < 0 || ret >= end - pos)
1427 static int ctrl_iface_get_capability_group(int res, char *strict,
1428 struct wpa_driver_capa *capa,
1429 char *buf, size_t buflen)
1441 len = os_strlcpy(buf, "CCMP TKIP WEP104 WEP40", buflen);
1447 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1448 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " ");
1449 if (ret < 0 || ret >= end - pos)
1455 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1456 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " ");
1457 if (ret < 0 || ret >= end - pos)
1463 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP104) {
1464 ret = os_snprintf(pos, end - pos, "%sWEP104",
1466 if (ret < 0 || ret >= end - pos)
1472 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP40) {
1473 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : " ");
1474 if (ret < 0 || ret >= end - pos)
1484 static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
1485 struct wpa_driver_capa *capa,
1486 char *buf, size_t buflen)
1498 len = os_strlcpy(buf, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE "
1505 ret = os_snprintf(pos, end - pos, "NONE IEEE8021X");
1506 if (ret < 0 || ret >= end - pos)
1510 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1511 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
1512 ret = os_snprintf(pos, end - pos, " WPA-EAP");
1513 if (ret < 0 || ret >= end - pos)
1518 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1519 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1520 ret = os_snprintf(pos, end - pos, " WPA-PSK");
1521 if (ret < 0 || ret >= end - pos)
1526 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1527 ret = os_snprintf(pos, end - pos, " WPA-NONE");
1528 if (ret < 0 || ret >= end - pos)
1537 static int ctrl_iface_get_capability_proto(int res, char *strict,
1538 struct wpa_driver_capa *capa,
1539 char *buf, size_t buflen)
1551 len = os_strlcpy(buf, "RSN WPA", buflen);
1557 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1558 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1559 ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " ");
1560 if (ret < 0 || ret >= end - pos)
1566 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1567 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
1568 ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " ");
1569 if (ret < 0 || ret >= end - pos)
1579 static int ctrl_iface_get_capability_auth_alg(int res, char *strict,
1580 struct wpa_driver_capa *capa,
1581 char *buf, size_t buflen)
1593 len = os_strlcpy(buf, "OPEN SHARED LEAP", buflen);
1599 if (capa->auth & (WPA_DRIVER_AUTH_OPEN)) {
1600 ret = os_snprintf(pos, end - pos, "%sOPEN", first ? "" : " ");
1601 if (ret < 0 || ret >= end - pos)
1607 if (capa->auth & (WPA_DRIVER_AUTH_SHARED)) {
1608 ret = os_snprintf(pos, end - pos, "%sSHARED",
1610 if (ret < 0 || ret >= end - pos)
1616 if (capa->auth & (WPA_DRIVER_AUTH_LEAP)) {
1617 ret = os_snprintf(pos, end - pos, "%sLEAP", first ? "" : " ");
1618 if (ret < 0 || ret >= end - pos)
1628 static int wpa_supplicant_ctrl_iface_get_capability(
1629 struct wpa_supplicant *wpa_s, const char *_field, char *buf,
1632 struct wpa_driver_capa capa;
1638 /* Determine whether or not strict checking was requested */
1639 len = os_strlcpy(field, _field, sizeof(field));
1640 if (len >= sizeof(field))
1642 strict = os_strchr(field, ' ');
1643 if (strict != NULL) {
1645 if (os_strcmp(strict, "strict") != 0)
1649 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
1650 field, strict ? strict : "");
1652 if (os_strcmp(field, "eap") == 0) {
1653 return eap_get_names(buf, buflen);
1656 res = wpa_drv_get_capa(wpa_s, &capa);
1658 if (os_strcmp(field, "pairwise") == 0)
1659 return ctrl_iface_get_capability_pairwise(res, strict, &capa,
1662 if (os_strcmp(field, "group") == 0)
1663 return ctrl_iface_get_capability_group(res, strict, &capa,
1666 if (os_strcmp(field, "key_mgmt") == 0)
1667 return ctrl_iface_get_capability_key_mgmt(res, strict, &capa,
1670 if (os_strcmp(field, "proto") == 0)
1671 return ctrl_iface_get_capability_proto(res, strict, &capa,
1674 if (os_strcmp(field, "auth_alg") == 0)
1675 return ctrl_iface_get_capability_auth_alg(res, strict, &capa,
1678 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
1685 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
1686 const char *cmd, char *buf,
1691 struct wpa_bss *bss;
1696 if (os_strcmp(cmd, "FIRST") == 0)
1697 bss = dl_list_first(&wpa_s->bss, struct wpa_bss, list);
1698 else if (os_strncmp(cmd, "ID-", 3) == 0) {
1700 bss = wpa_bss_get_id(wpa_s, i);
1701 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) {
1703 bss = wpa_bss_get_id(wpa_s, i);
1705 struct dl_list *next = bss->list_id.next;
1706 if (next == &wpa_s->bss_id)
1709 bss = dl_list_entry(next, struct wpa_bss,
1712 } else if (hwaddr_aton(cmd, bssid) == 0)
1713 bss = wpa_bss_get_bssid(wpa_s, bssid);
1715 struct wpa_bss *tmp;
1718 dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id)
1732 ret = os_snprintf(pos, end - pos,
1734 "bssid=" MACSTR "\n"
1737 "capabilities=0x%04x\n"
1744 MAC2STR(bss->bssid), bss->freq, bss->beacon_int,
1745 bss->caps, bss->qual, bss->noise, bss->level,
1746 (unsigned long long) bss->tsf);
1747 if (ret < 0 || ret >= end - pos)
1751 ie = (const u8 *) (bss + 1);
1752 for (i = 0; i < bss->ie_len; i++) {
1753 ret = os_snprintf(pos, end - pos, "%02x", *ie++);
1754 if (ret < 0 || ret >= end - pos)
1758 if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE)) {
1759 ret = os_snprintf(pos, end - pos, "[P2P]");
1760 if (ret < 0 || ret >= end - pos)
1765 ret = os_snprintf(pos, end - pos, "\n");
1766 if (ret < 0 || ret >= end - pos)
1770 ret = os_snprintf(pos, end - pos, "flags=");
1771 if (ret < 0 || ret >= end - pos)
1775 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
1777 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
1778 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1780 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
1781 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
1782 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
1783 ret = os_snprintf(pos, end - pos, "[WEP]");
1784 if (ret < 0 || ret >= end - pos)
1788 if (bss->caps & IEEE80211_CAP_IBSS) {
1789 ret = os_snprintf(pos, end - pos, "[IBSS]");
1790 if (ret < 0 || ret >= end - pos)
1794 if (bss->caps & IEEE80211_CAP_ESS) {
1795 ret = os_snprintf(pos, end - pos, "[ESS]");
1796 if (ret < 0 || ret >= end - pos)
1801 ret = os_snprintf(pos, end - pos, "\n");
1802 if (ret < 0 || ret >= end - pos)
1806 ret = os_snprintf(pos, end - pos, "ssid=%s\n",
1807 wpa_ssid_txt(bss->ssid, bss->ssid_len));
1808 if (ret < 0 || ret >= end - pos)
1813 ie = (const u8 *) (bss + 1);
1814 ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end);
1815 if (ret < 0 || ret >= end - pos)
1818 #endif /* CONFIG_WPS */
1821 ie = (const u8 *) (bss + 1);
1822 ret = wpas_p2p_scan_result_text(ie, bss->ie_len, pos, end);
1823 if (ret < 0 || ret >= end - pos)
1826 #endif /* CONFIG_P2P */
1832 static int wpa_supplicant_ctrl_iface_ap_scan(
1833 struct wpa_supplicant *wpa_s, char *cmd)
1835 int ap_scan = atoi(cmd);
1836 return wpa_supplicant_set_ap_scan(wpa_s, ap_scan);
1840 static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s)
1842 u8 *bcast = (u8 *) "\xff\xff\xff\xff\xff\xff";
1844 wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication");
1845 /* MLME-DELETEKEYS.request */
1846 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 0, 0, NULL, 0, NULL, 0);
1847 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 1, 0, NULL, 0, NULL, 0);
1848 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 2, 0, NULL, 0, NULL, 0);
1849 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 3, 0, NULL, 0, NULL, 0);
1850 #ifdef CONFIG_IEEE80211W
1851 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 4, 0, NULL, 0, NULL, 0);
1852 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 5, 0, NULL, 0, NULL, 0);
1853 #endif /* CONFIG_IEEE80211W */
1855 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL,
1857 /* MLME-SETPROTECTION.request(None) */
1858 wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid,
1859 MLME_SETPROTECTION_PROTECT_TYPE_NONE,
1860 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
1861 wpa_sm_drop_sa(wpa_s->wpa);
1865 static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s,
1869 struct wpa_bss *bss;
1870 struct wpa_ssid *ssid = wpa_s->current_ssid;
1872 if (hwaddr_aton(addr, bssid)) {
1873 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid "
1874 "address '%s'", addr);
1878 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM " MACSTR, MAC2STR(bssid));
1880 bss = wpa_bss_get_bssid(wpa_s, bssid);
1882 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: Target AP not found "
1888 * TODO: Find best network configuration block from configuration to
1889 * allow roaming to other networks
1893 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: No network "
1894 "configuration known for the target AP");
1898 wpa_s->reassociate = 1;
1899 wpa_supplicant_connect(wpa_s, bss, ssid);
1906 static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
1908 unsigned int timeout = atoi(cmd);
1909 enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL;
1911 if (os_strstr(cmd, "type=social"))
1912 type = P2P_FIND_ONLY_SOCIAL;
1913 else if (os_strstr(cmd, "type=progressive"))
1914 type = P2P_FIND_PROGRESSIVE;
1916 wpas_p2p_find(wpa_s, timeout, type);
1921 static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
1922 char *buf, size_t buflen)
1927 enum p2p_wps_method wps_method;
1930 int persistent_group;
1936 /* <addr> <"pbc" | "pin" | PIN> [label|display|keypad] [persistent]
1937 * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] */
1939 if (hwaddr_aton(cmd, addr))
1947 persistent_group = os_strstr(pos, " persistent") != NULL;
1948 join = os_strstr(pos, " join") != NULL;
1949 auth = os_strstr(pos, " auth") != NULL;
1951 pos2 = os_strstr(pos, " go_intent=");
1954 go_intent = atoi(pos2);
1955 if (go_intent < 0 || go_intent > 15)
1959 pos2 = os_strstr(pos, " freq=");
1967 if (os_strncmp(pos, "pin", 3) == 0) {
1968 /* Request random PIN (to be displayed) and enable the PIN */
1969 wps_method = WPS_PIN_DISPLAY;
1970 } else if (os_strncmp(pos, "pbc", 3) == 0) {
1971 wps_method = WPS_PBC;
1974 pos = os_strchr(pin, ' ');
1975 wps_method = WPS_PIN_KEYPAD;
1978 if (os_strncmp(pos, "label", 5) == 0)
1979 wps_method = WPS_PIN_LABEL;
1980 else if (os_strncmp(pos, "display", 7) == 0)
1981 wps_method = WPS_PIN_DISPLAY;
1985 new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
1986 persistent_group, join, auth, go_intent,
1988 if (new_pin == -2) {
1989 os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25);
1992 if (new_pin == -3) {
1993 os_memcpy(buf, "FAIL-CHANNEL-UNSUPPORTED\n", 25);
1998 if (wps_method == WPS_PIN_DISPLAY && pin == NULL) {
1999 ret = os_snprintf(buf, buflen, "%08d", new_pin);
2000 if (ret < 0 || (size_t) ret >= buflen)
2005 os_memcpy(buf, "OK\n", 3);
2010 static int p2p_ctrl_listen(struct wpa_supplicant *wpa_s, char *cmd)
2012 unsigned int timeout = atoi(cmd);
2013 return wpas_p2p_listen(wpa_s, timeout);
2017 static int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd)
2022 /* <addr> <config method> */
2024 if (hwaddr_aton(cmd, addr))
2032 return wpas_p2p_prov_disc(wpa_s, addr, pos);
2036 static int p2p_get_passphrase(struct wpa_supplicant *wpa_s, char *buf,
2039 struct wpa_ssid *ssid = wpa_s->current_ssid;
2041 if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
2042 ssid->passphrase == NULL)
2045 os_strlcpy(buf, ssid->passphrase, buflen);
2046 return os_strlen(buf);
2050 static int p2p_ctrl_serv_disc_req(struct wpa_supplicant *wpa_s, char *cmd,
2051 char *buf, size_t buflen)
2055 u8 dst_buf[ETH_ALEN], *dst;
2056 struct wpabuf *tlvs;
2060 if (hwaddr_aton(cmd, dst_buf))
2063 if (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 &&
2064 dst[3] == 0 && dst[4] == 0 && dst[5] == 0)
2071 if (os_strncmp(pos, "upnp ", 5) == 0) {
2074 if (hexstr2bin(pos, &version, 1) < 0)
2080 ref = (u64) wpas_p2p_sd_request_upnp(wpa_s, dst, version, pos);
2082 len = os_strlen(pos);
2086 tlvs = wpabuf_alloc(len);
2089 if (hexstr2bin(pos, wpabuf_put(tlvs, len), len) < 0) {
2094 ref = (u64) wpas_p2p_sd_request(wpa_s, dst, tlvs);
2097 res = os_snprintf(buf, buflen, "%llx", (long long unsigned) ref);
2098 if (res < 0 || (unsigned) res >= buflen)
2104 static int p2p_ctrl_serv_disc_cancel_req(struct wpa_supplicant *wpa_s,
2107 long long unsigned val;
2109 if (sscanf(cmd, "%llx", &val) != 1)
2112 return wpas_p2p_sd_cancel_request(wpa_s, (void *) req);
2116 static int p2p_ctrl_serv_disc_resp(struct wpa_supplicant *wpa_s, char *cmd)
2119 u8 dst_buf[ETH_ALEN], *dst;
2121 struct wpabuf *resp_tlvs;
2125 pos = os_strchr(cmd, ' ');
2133 if (hwaddr_aton(pos, dst_buf))
2136 if (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 &&
2137 dst[3] == 0 && dst[4] == 0 && dst[5] == 0)
2144 pos2 = os_strchr(pos, ' ');
2148 dialog_token = atoi(pos);
2150 len = os_strlen(pos2);
2154 resp_tlvs = wpabuf_alloc(len);
2155 if (resp_tlvs == NULL)
2157 if (hexstr2bin(pos2, wpabuf_put(resp_tlvs, len), len) < 0) {
2158 wpabuf_free(resp_tlvs);
2162 wpas_p2p_sd_response(wpa_s, freq, dst, dialog_token, resp_tlvs);
2163 wpabuf_free(resp_tlvs);
2168 static int p2p_ctrl_serv_disc_external(struct wpa_supplicant *wpa_s,
2171 wpa_s->p2p_sd_over_ctrl_iface = atoi(cmd);
2176 static int p2p_ctrl_service_add_bonjour(struct wpa_supplicant *wpa_s,
2181 struct wpabuf *query, *resp;
2183 pos = os_strchr(cmd, ' ');
2188 len = os_strlen(cmd);
2192 query = wpabuf_alloc(len);
2195 if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) {
2200 len = os_strlen(pos);
2206 resp = wpabuf_alloc(len);
2211 if (hexstr2bin(pos, wpabuf_put(resp, len), len) < 0) {
2217 if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0) {
2226 static int p2p_ctrl_service_add_upnp(struct wpa_supplicant *wpa_s, char *cmd)
2231 pos = os_strchr(cmd, ' ');
2236 if (hexstr2bin(cmd, &version, 1) < 0)
2239 return wpas_p2p_service_add_upnp(wpa_s, version, pos);
2243 static int p2p_ctrl_service_add(struct wpa_supplicant *wpa_s, char *cmd)
2247 pos = os_strchr(cmd, ' ');
2252 if (os_strcmp(cmd, "bonjour") == 0)
2253 return p2p_ctrl_service_add_bonjour(wpa_s, pos);
2254 if (os_strcmp(cmd, "upnp") == 0)
2255 return p2p_ctrl_service_add_upnp(wpa_s, pos);
2256 wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd);
2261 static int p2p_ctrl_service_del_bonjour(struct wpa_supplicant *wpa_s,
2265 struct wpabuf *query;
2268 len = os_strlen(cmd);
2272 query = wpabuf_alloc(len);
2275 if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) {
2280 ret = wpas_p2p_service_del_bonjour(wpa_s, query);
2286 static int p2p_ctrl_service_del_upnp(struct wpa_supplicant *wpa_s, char *cmd)
2291 pos = os_strchr(cmd, ' ');
2296 if (hexstr2bin(cmd, &version, 1) < 0)
2299 return wpas_p2p_service_del_upnp(wpa_s, version, pos);
2303 static int p2p_ctrl_service_del(struct wpa_supplicant *wpa_s, char *cmd)
2307 pos = os_strchr(cmd, ' ');
2312 if (os_strcmp(cmd, "bonjour") == 0)
2313 return p2p_ctrl_service_del_bonjour(wpa_s, pos);
2314 if (os_strcmp(cmd, "upnp") == 0)
2315 return p2p_ctrl_service_del_upnp(wpa_s, pos);
2316 wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd);
2321 static int p2p_ctrl_reject(struct wpa_supplicant *wpa_s, char *cmd)
2327 if (hwaddr_aton(cmd, addr))
2330 return wpas_p2p_reject(wpa_s, addr);
2334 static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
2338 struct wpa_ssid *ssid;
2342 pos = os_strstr(cmd, " peer=");
2345 if (hwaddr_aton(pos, peer))
2348 ssid = wpa_config_get_network(wpa_s->conf, id);
2349 if (ssid == NULL || ssid->disabled != 2) {
2350 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
2351 "for persistent P2P group",
2356 return wpas_p2p_invite(wpa_s, pos ? peer : NULL, ssid, NULL);
2360 static int p2p_ctrl_invite_group(struct wpa_supplicant *wpa_s, char *cmd)
2363 u8 peer[ETH_ALEN], go_dev_addr[ETH_ALEN], *go_dev = NULL;
2365 pos = os_strstr(cmd, " peer=");
2371 if (hwaddr_aton(pos, peer)) {
2372 wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'", pos);
2376 pos = os_strstr(pos, " go_dev_addr=");
2379 if (hwaddr_aton(pos, go_dev_addr)) {
2380 wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'",
2384 go_dev = go_dev_addr;
2387 return wpas_p2p_invite_group(wpa_s, cmd, peer, go_dev);
2391 static int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd)
2393 if (os_strncmp(cmd, "persistent=", 11) == 0)
2394 return p2p_ctrl_invite_persistent(wpa_s, cmd + 11);
2395 if (os_strncmp(cmd, "group=", 6) == 0)
2396 return p2p_ctrl_invite_group(wpa_s, cmd + 6);
2402 static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
2403 char *cmd, int freq)
2406 struct wpa_ssid *ssid;
2409 ssid = wpa_config_get_network(wpa_s->conf, id);
2410 if (ssid == NULL || ssid->disabled != 2) {
2411 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
2412 "for persistent P2P group",
2417 return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq);
2421 static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
2426 pos = os_strstr(cmd, "freq=");
2428 freq = atoi(pos + 5);
2430 if (os_strncmp(cmd, "persistent=", 11) == 0)
2431 return p2p_ctrl_group_add_persistent(wpa_s, cmd + 11, freq);
2432 if (os_strcmp(cmd, "persistent") == 0 ||
2433 os_strncmp(cmd, "persistent ", 11) == 0)
2434 return wpas_p2p_group_add(wpa_s, 1, freq);
2435 if (os_strncmp(cmd, "freq=", 5) == 0)
2436 return wpas_p2p_group_add(wpa_s, 0, freq);
2438 wpa_printf(MSG_DEBUG, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'",
2444 static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
2445 char *buf, size_t buflen)
2447 u8 addr[ETH_ALEN], *addr_ptr;
2450 if (!wpa_s->global->p2p)
2453 if (os_strcmp(cmd, "FIRST") == 0) {
2456 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) {
2457 if (hwaddr_aton(cmd + 5, addr) < 0)
2462 if (hwaddr_aton(cmd, addr) < 0)
2468 return p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next,
2473 static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
2477 if (wpa_s->global->p2p == NULL)
2480 param = os_strchr(cmd, ' ');
2485 if (os_strcmp(cmd, "discoverability") == 0) {
2486 p2p_set_client_discoverability(wpa_s->global->p2p,
2491 if (os_strcmp(cmd, "managed") == 0) {
2492 p2p_set_managed_oper(wpa_s->global->p2p, atoi(param));
2496 if (os_strcmp(cmd, "listen_channel") == 0) {
2497 return p2p_set_listen_channel(wpa_s->global->p2p, 81,
2501 if (os_strcmp(cmd, "ssid_postfix") == 0) {
2502 return p2p_set_ssid_postfix(wpa_s->global->p2p, (u8 *) param,
2506 if (os_strcmp(cmd, "noa") == 0) {
2508 int count, start, duration;
2509 /* GO NoA parameters: count,start_offset(ms),duration(ms) */
2510 count = atoi(param);
2511 pos = os_strchr(param, ',');
2516 pos = os_strchr(pos, ',');
2520 duration = atoi(pos);
2521 if (count < 0 || count > 255 || start < 0 || duration < 0)
2523 if (count == 0 && duration > 0)
2525 wpa_printf(MSG_DEBUG, "CTRL_IFACE: P2P_SET GO NoA: count=%d "
2526 "start=%d duration=%d", count, start, duration);
2527 return wpas_p2p_set_noa(wpa_s, count, start, duration);
2530 if (os_strcmp(cmd, "ps") == 0)
2531 return wpa_drv_set_p2p_powersave(wpa_s, atoi(param), -1, -1);
2533 if (os_strcmp(cmd, "oppps") == 0)
2534 return wpa_drv_set_p2p_powersave(wpa_s, -1, atoi(param), -1);
2536 if (os_strcmp(cmd, "ctwindow") == 0)
2537 return wpa_drv_set_p2p_powersave(wpa_s, -1, -1, atoi(param));
2539 if (os_strcmp(cmd, "disabled") == 0) {
2540 wpa_s->global->p2p_disabled = atoi(param);
2541 wpa_printf(MSG_DEBUG, "P2P functionality %s",
2542 wpa_s->global->p2p_disabled ?
2543 "disabled" : "enabled");
2544 if (wpa_s->global->p2p_disabled) {
2545 wpas_p2p_stop_find(wpa_s);
2546 os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
2547 p2p_flush(wpa_s->global->p2p);
2552 if (os_strcmp(cmd, "force_long_sd") == 0) {
2553 wpa_s->force_long_sd = atoi(param);
2557 if (os_strcmp(cmd, "peer_filter") == 0) {
2559 if (hwaddr_aton(param, addr))
2561 p2p_set_peer_filter(wpa_s->global->p2p, addr);
2565 if (os_strcmp(cmd, "cross_connect") == 0)
2566 return wpas_p2p_set_cross_connect(wpa_s, atoi(param));
2568 if (os_strcmp(cmd, "go_apsd") == 0) {
2569 if (os_strcmp(param, "disable") == 0)
2570 wpa_s->set_ap_uapsd = 0;
2572 wpa_s->set_ap_uapsd = 1;
2573 wpa_s->ap_uapsd = atoi(param);
2578 if (os_strcmp(cmd, "client_apsd") == 0) {
2579 if (os_strcmp(param, "disable") == 0)
2580 wpa_s->set_sta_uapsd = 0;
2584 /* format: BE,BK,VI,VO;max SP Length */
2586 pos = os_strchr(param, ',');
2591 pos = os_strchr(pos, ',');
2596 pos = os_strchr(pos, ',');
2601 /* ignore max SP Length for now */
2603 wpa_s->set_sta_uapsd = 1;
2604 wpa_s->sta_uapsd = 0;
2606 wpa_s->sta_uapsd |= BIT(0);
2608 wpa_s->sta_uapsd |= BIT(1);
2610 wpa_s->sta_uapsd |= BIT(2);
2612 wpa_s->sta_uapsd |= BIT(3);
2617 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
2624 static int p2p_ctrl_presence_req(struct wpa_supplicant *wpa_s, char *cmd)
2627 unsigned int dur1 = 0, int1 = 0, dur2 = 0, int2 = 0;
2630 pos = os_strchr(cmd, ' ');
2636 pos2 = os_strchr(pos, ' ');
2644 pos = os_strchr(pos2, ' ');
2652 return wpas_p2p_presence_req(wpa_s, dur1, int1, dur2, int2);
2656 static int p2p_ctrl_ext_listen(struct wpa_supplicant *wpa_s, char *cmd)
2659 unsigned int period = 0, interval = 0;
2662 pos = os_strchr(cmd, ' ');
2667 interval = atoi(pos);
2670 return wpas_p2p_ext_listen(wpa_s, period, interval);
2673 #endif /* CONFIG_P2P */
2676 static int wpa_supplicant_ctrl_iface_sta_autoconnect(
2677 struct wpa_supplicant *wpa_s, char *cmd)
2679 wpa_s->auto_reconnect_disabled = atoi(cmd) == 0 ? 1 : 0;
2684 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
2685 char *buf, size_t *resp_len)
2688 const int reply_size = 4096;
2692 if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 ||
2693 os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
2694 wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface",
2695 (const u8 *) buf, os_strlen(buf));
2697 int level = MSG_DEBUG;
2698 if (os_strcmp(buf, "PING") == 0)
2699 level = MSG_EXCESSIVE;
2700 wpa_hexdump_ascii(level, "RX ctrl_iface",
2701 (const u8 *) buf, os_strlen(buf));
2704 reply = os_malloc(reply_size);
2705 if (reply == NULL) {
2710 os_memcpy(reply, "OK\n", 3);
2713 if (os_strcmp(buf, "PING") == 0) {
2714 os_memcpy(reply, "PONG\n", 5);
2716 } else if (os_strncmp(buf, "NOTE ", 5) == 0) {
2717 wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
2718 } else if (os_strcmp(buf, "MIB") == 0) {
2719 reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
2720 if (reply_len >= 0) {
2722 res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len,
2723 reply_size - reply_len);
2729 } else if (os_strncmp(buf, "STATUS", 6) == 0) {
2730 reply_len = wpa_supplicant_ctrl_iface_status(
2731 wpa_s, buf + 6, reply, reply_size);
2732 } else if (os_strcmp(buf, "PMKSA") == 0) {
2733 reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, reply,
2735 } else if (os_strncmp(buf, "SET ", 4) == 0) {
2736 if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4))
2738 } else if (os_strcmp(buf, "LOGON") == 0) {
2739 eapol_sm_notify_logoff(wpa_s->eapol, FALSE);
2740 } else if (os_strcmp(buf, "LOGOFF") == 0) {
2741 eapol_sm_notify_logoff(wpa_s->eapol, TRUE);
2742 } else if (os_strcmp(buf, "REASSOCIATE") == 0) {
2743 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
2746 wpa_s->disconnected = 0;
2747 wpa_s->reassociate = 1;
2748 wpa_supplicant_req_scan(wpa_s, 0, 0);
2750 } else if (os_strcmp(buf, "RECONNECT") == 0) {
2751 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
2753 else if (wpa_s->disconnected) {
2754 wpa_s->disconnected = 0;
2755 wpa_s->reassociate = 1;
2756 wpa_supplicant_req_scan(wpa_s, 0, 0);
2758 #ifdef IEEE8021X_EAPOL
2759 } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) {
2760 if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8))
2762 #endif /* IEEE8021X_EAPOL */
2763 #ifdef CONFIG_PEERKEY
2764 } else if (os_strncmp(buf, "STKSTART ", 9) == 0) {
2765 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9))
2767 #endif /* CONFIG_PEERKEY */
2768 #ifdef CONFIG_IEEE80211R
2769 } else if (os_strncmp(buf, "FT_DS ", 6) == 0) {
2770 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6))
2772 #endif /* CONFIG_IEEE80211R */
2774 } else if (os_strcmp(buf, "WPS_PBC") == 0) {
2775 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, NULL))
2777 } else if (os_strncmp(buf, "WPS_PBC ", 8) == 0) {
2778 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, buf + 8))
2780 } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
2781 reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8,
2784 } else if (os_strncmp(buf, "WPS_CHECK_PIN ", 14) == 0) {
2785 reply_len = wpa_supplicant_ctrl_iface_wps_check_pin(
2786 wpa_s, buf + 14, reply, reply_size);
2787 } else if (os_strcmp(buf, "WPS_CANCEL") == 0) {
2788 if (wpas_wps_cancel(wpa_s))
2790 #ifdef CONFIG_WPS_OOB
2791 } else if (os_strncmp(buf, "WPS_OOB ", 8) == 0) {
2792 if (wpa_supplicant_ctrl_iface_wps_oob(wpa_s, buf + 8))
2794 #endif /* CONFIG_WPS_OOB */
2795 } else if (os_strncmp(buf, "WPS_REG ", 8) == 0) {
2796 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8))
2798 #ifdef CONFIG_WPS_ER
2799 } else if (os_strcmp(buf, "WPS_ER_START") == 0) {
2800 if (wpas_wps_er_start(wpa_s, NULL))
2802 } else if (os_strncmp(buf, "WPS_ER_START ", 13) == 0) {
2803 if (wpas_wps_er_start(wpa_s, buf + 13))
2805 } else if (os_strcmp(buf, "WPS_ER_STOP") == 0) {
2806 if (wpas_wps_er_stop(wpa_s))
2808 } else if (os_strncmp(buf, "WPS_ER_PIN ", 11) == 0) {
2809 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s, buf + 11))
2811 } else if (os_strncmp(buf, "WPS_ER_PBC ", 11) == 0) {
2812 int ret = wpas_wps_er_pbc(wpa_s, buf + 11);
2814 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17);
2816 } else if (ret == -3) {
2817 os_memcpy(reply, "FAIL-UNKNOWN-UUID\n", 18);
2819 } else if (ret == -4) {
2820 os_memcpy(reply, "FAIL-NO-AP-SETTINGS\n", 20);
2824 } else if (os_strncmp(buf, "WPS_ER_LEARN ", 13) == 0) {
2825 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s, buf + 13))
2827 } else if (os_strncmp(buf, "WPS_ER_SET_CONFIG ", 18) == 0) {
2828 if (wpa_supplicant_ctrl_iface_wps_er_set_config(wpa_s,
2831 } else if (os_strncmp(buf, "WPS_ER_CONFIG ", 14) == 0) {
2832 if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s, buf + 14))
2834 #endif /* CONFIG_WPS_ER */
2835 #endif /* CONFIG_WPS */
2836 #ifdef CONFIG_IBSS_RSN
2837 } else if (os_strncmp(buf, "IBSS_RSN ", 9) == 0) {
2838 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s, buf + 9))
2840 #endif /* CONFIG_IBSS_RSN */
2842 } else if (os_strncmp(buf, "P2P_FIND ", 9) == 0) {
2843 if (p2p_ctrl_find(wpa_s, buf + 9))
2845 } else if (os_strcmp(buf, "P2P_FIND") == 0) {
2846 if (p2p_ctrl_find(wpa_s, ""))
2848 } else if (os_strcmp(buf, "P2P_STOP_FIND") == 0) {
2849 wpas_p2p_stop_find(wpa_s);
2850 } else if (os_strncmp(buf, "P2P_CONNECT ", 12) == 0) {
2851 reply_len = p2p_ctrl_connect(wpa_s, buf + 12, reply,
2853 } else if (os_strncmp(buf, "P2P_LISTEN ", 11) == 0) {
2854 if (p2p_ctrl_listen(wpa_s, buf + 11))
2856 } else if (os_strcmp(buf, "P2P_LISTEN") == 0) {
2857 if (p2p_ctrl_listen(wpa_s, ""))
2859 } else if (os_strncmp(buf, "P2P_GROUP_REMOVE ", 17) == 0) {
2860 if (wpas_p2p_group_remove(wpa_s, buf + 17))
2862 } else if (os_strcmp(buf, "P2P_GROUP_ADD") == 0) {
2863 if (wpas_p2p_group_add(wpa_s, 0, 0))
2865 } else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) {
2866 if (p2p_ctrl_group_add(wpa_s, buf + 14))
2868 } else if (os_strncmp(buf, "P2P_PROV_DISC ", 14) == 0) {
2869 if (p2p_ctrl_prov_disc(wpa_s, buf + 14))
2871 } else if (os_strcmp(buf, "P2P_GET_PASSPHRASE") == 0) {
2872 reply_len = p2p_get_passphrase(wpa_s, reply, reply_size);
2873 } else if (os_strncmp(buf, "P2P_SERV_DISC_REQ ", 18) == 0) {
2874 reply_len = p2p_ctrl_serv_disc_req(wpa_s, buf + 18, reply,
2876 } else if (os_strncmp(buf, "P2P_SERV_DISC_CANCEL_REQ ", 25) == 0) {
2877 if (p2p_ctrl_serv_disc_cancel_req(wpa_s, buf + 25) < 0)
2879 } else if (os_strncmp(buf, "P2P_SERV_DISC_RESP ", 19) == 0) {
2880 if (p2p_ctrl_serv_disc_resp(wpa_s, buf + 19) < 0)
2882 } else if (os_strcmp(buf, "P2P_SERVICE_UPDATE") == 0) {
2883 wpas_p2p_sd_service_update(wpa_s);
2884 } else if (os_strncmp(buf, "P2P_SERV_DISC_EXTERNAL ", 23) == 0) {
2885 if (p2p_ctrl_serv_disc_external(wpa_s, buf + 23) < 0)
2887 } else if (os_strcmp(buf, "P2P_SERVICE_FLUSH") == 0) {
2888 wpas_p2p_service_flush(wpa_s);
2889 } else if (os_strncmp(buf, "P2P_SERVICE_ADD ", 16) == 0) {
2890 if (p2p_ctrl_service_add(wpa_s, buf + 16) < 0)
2892 } else if (os_strncmp(buf, "P2P_SERVICE_DEL ", 16) == 0) {
2893 if (p2p_ctrl_service_del(wpa_s, buf + 16) < 0)
2895 } else if (os_strncmp(buf, "P2P_REJECT ", 11) == 0) {
2896 if (p2p_ctrl_reject(wpa_s, buf + 11) < 0)
2898 } else if (os_strncmp(buf, "P2P_INVITE ", 11) == 0) {
2899 if (p2p_ctrl_invite(wpa_s, buf + 11) < 0)
2901 } else if (os_strncmp(buf, "P2P_PEER ", 9) == 0) {
2902 reply_len = p2p_ctrl_peer(wpa_s, buf + 9, reply,
2904 } else if (os_strncmp(buf, "P2P_SET ", 8) == 0) {
2905 if (p2p_ctrl_set(wpa_s, buf + 8) < 0)
2907 } else if (os_strcmp(buf, "P2P_FLUSH") == 0) {
2908 os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
2909 wpa_s->force_long_sd = 0;
2910 p2p_flush(wpa_s->global->p2p);
2911 } else if (os_strcmp(buf, "P2P_CANCEL") == 0) {
2912 if (wpas_p2p_cancel(wpa_s))
2914 } else if (os_strncmp(buf, "P2P_PRESENCE_REQ ", 17) == 0) {
2915 if (p2p_ctrl_presence_req(wpa_s, buf + 17) < 0)
2917 } else if (os_strcmp(buf, "P2P_PRESENCE_REQ") == 0) {
2918 if (p2p_ctrl_presence_req(wpa_s, "") < 0)
2920 } else if (os_strncmp(buf, "P2P_EXT_LISTEN ", 15) == 0) {
2921 if (p2p_ctrl_ext_listen(wpa_s, buf + 15) < 0)
2923 } else if (os_strcmp(buf, "P2P_EXT_LISTEN") == 0) {
2924 if (p2p_ctrl_ext_listen(wpa_s, "") < 0)
2926 #endif /* CONFIG_P2P */
2927 } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0)
2929 if (wpa_supplicant_ctrl_iface_ctrl_rsp(
2930 wpa_s, buf + os_strlen(WPA_CTRL_RSP)))
2934 } else if (os_strcmp(buf, "RECONFIGURE") == 0) {
2935 if (wpa_supplicant_reload_configuration(wpa_s))
2937 } else if (os_strcmp(buf, "TERMINATE") == 0) {
2938 wpa_supplicant_terminate_proc(wpa_s->global);
2939 } else if (os_strncmp(buf, "BSSID ", 6) == 0) {
2940 if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6))
2942 } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) {
2943 reply_len = wpa_supplicant_ctrl_iface_list_networks(
2944 wpa_s, reply, reply_size);
2945 } else if (os_strcmp(buf, "DISCONNECT") == 0) {
2946 wpa_s->reassociate = 0;
2947 wpa_s->disconnected = 1;
2948 wpa_supplicant_deauthenticate(wpa_s,
2949 WLAN_REASON_DEAUTH_LEAVING);
2950 } else if (os_strcmp(buf, "SCAN") == 0) {
2951 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
2954 wpa_s->scan_req = 2;
2955 wpa_supplicant_req_scan(wpa_s, 0, 0);
2957 } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) {
2958 reply_len = wpa_supplicant_ctrl_iface_scan_results(
2959 wpa_s, reply, reply_size);
2960 } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) {
2961 if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15))
2963 } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) {
2964 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15))
2966 } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) {
2967 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16))
2969 } else if (os_strcmp(buf, "ADD_NETWORK") == 0) {
2970 reply_len = wpa_supplicant_ctrl_iface_add_network(
2971 wpa_s, reply, reply_size);
2972 } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) {
2973 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15))
2975 } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
2976 if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12))
2978 } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
2979 reply_len = wpa_supplicant_ctrl_iface_get_network(
2980 wpa_s, buf + 12, reply, reply_size);
2981 #ifndef CONFIG_NO_CONFIG_WRITE
2982 } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
2983 if (wpa_supplicant_ctrl_iface_save_config(wpa_s))
2985 #endif /* CONFIG_NO_CONFIG_WRITE */
2986 } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
2987 reply_len = wpa_supplicant_ctrl_iface_get_capability(
2988 wpa_s, buf + 15, reply, reply_size);
2989 } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) {
2990 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8))
2992 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
2993 reply_len = wpa_supplicant_global_iface_list(
2994 wpa_s->global, reply, reply_size);
2995 } else if (os_strcmp(buf, "INTERFACES") == 0) {
2996 reply_len = wpa_supplicant_global_iface_interfaces(
2997 wpa_s->global, reply, reply_size);
2998 } else if (os_strncmp(buf, "BSS ", 4) == 0) {
2999 reply_len = wpa_supplicant_ctrl_iface_bss(
3000 wpa_s, buf + 4, reply, reply_size);
3002 } else if (os_strcmp(buf, "STA-FIRST") == 0) {
3003 reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
3004 } else if (os_strncmp(buf, "STA ", 4) == 0) {
3005 reply_len = ap_ctrl_iface_sta(wpa_s, buf + 4, reply,
3007 } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
3008 reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
3010 #endif /* CONFIG_AP */
3011 } else if (os_strcmp(buf, "SUSPEND") == 0) {
3012 wpas_notify_suspend(wpa_s->global);
3013 } else if (os_strcmp(buf, "RESUME") == 0) {
3014 wpas_notify_resume(wpa_s->global);
3015 } else if (os_strcmp(buf, "DROP_SA") == 0) {
3016 wpa_supplicant_ctrl_iface_drop_sa(wpa_s);
3017 } else if (os_strncmp(buf, "ROAM ", 5) == 0) {
3018 if (wpa_supplicant_ctrl_iface_roam(wpa_s, buf + 5))
3020 } else if (os_strncmp(buf, "STA_AUTOCONNECT ", 16) == 0) {
3021 if (wpa_supplicant_ctrl_iface_sta_autoconnect(wpa_s, buf + 16))
3024 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
3028 if (reply_len < 0) {
3029 os_memcpy(reply, "FAIL\n", 5);
3034 eapol_sm_notify_ctrl_response(wpa_s->eapol);
3036 *resp_len = reply_len;
3041 static int wpa_supplicant_global_iface_add(struct wpa_global *global,
3044 struct wpa_interface iface;
3048 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
3049 * TAB<bridge_ifname>
3051 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd);
3053 os_memset(&iface, 0, sizeof(iface));
3056 iface.ifname = pos = cmd;
3057 pos = os_strchr(pos, '\t');
3060 if (iface.ifname[0] == '\0')
3065 iface.confname = pos;
3066 pos = os_strchr(pos, '\t');
3069 if (iface.confname[0] == '\0')
3070 iface.confname = NULL;
3075 pos = os_strchr(pos, '\t');
3078 if (iface.driver[0] == '\0')
3079 iface.driver = NULL;
3083 iface.ctrl_interface = pos;
3084 pos = os_strchr(pos, '\t');
3087 if (iface.ctrl_interface[0] == '\0')
3088 iface.ctrl_interface = NULL;
3092 iface.driver_param = pos;
3093 pos = os_strchr(pos, '\t');
3096 if (iface.driver_param[0] == '\0')
3097 iface.driver_param = NULL;
3101 iface.bridge_ifname = pos;
3102 pos = os_strchr(pos, '\t');
3105 if (iface.bridge_ifname[0] == '\0')
3106 iface.bridge_ifname = NULL;
3111 if (wpa_supplicant_get_iface(global, iface.ifname))
3114 return wpa_supplicant_add_iface(global, &iface) ? 0 : -1;
3118 static int wpa_supplicant_global_iface_remove(struct wpa_global *global,
3121 struct wpa_supplicant *wpa_s;
3123 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd);
3125 wpa_s = wpa_supplicant_get_iface(global, cmd);
3128 return wpa_supplicant_remove_iface(global, wpa_s);
3132 static void wpa_free_iface_info(struct wpa_interface_info *iface)
3134 struct wpa_interface_info *prev;
3138 iface = iface->next;
3140 os_free(prev->ifname);
3141 os_free(prev->desc);
3147 static int wpa_supplicant_global_iface_list(struct wpa_global *global,
3151 struct wpa_interface_info *iface = NULL, *last = NULL, *tmp;
3154 for (i = 0; wpa_drivers[i]; i++) {
3155 struct wpa_driver_ops *drv = wpa_drivers[i];
3156 if (drv->get_interfaces == NULL)
3158 tmp = drv->get_interfaces(global->drv_priv[i]);
3172 for (tmp = iface; tmp; tmp = tmp->next) {
3173 res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n",
3174 tmp->drv_name, tmp->ifname,
3175 tmp->desc ? tmp->desc : "");
3176 if (res < 0 || res >= end - pos) {
3183 wpa_free_iface_info(iface);
3189 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
3194 struct wpa_supplicant *wpa_s;
3196 wpa_s = global->ifaces;
3201 res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname);
3202 if (res < 0 || res >= end - pos) {
3207 wpa_s = wpa_s->next;
3213 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
3214 char *buf, size_t *resp_len)
3217 const int reply_size = 2048;
3220 wpa_hexdump_ascii(MSG_DEBUG, "RX global ctrl_iface",
3221 (const u8 *) buf, os_strlen(buf));
3223 reply = os_malloc(reply_size);
3224 if (reply == NULL) {
3229 os_memcpy(reply, "OK\n", 3);
3232 if (os_strcmp(buf, "PING") == 0) {
3233 os_memcpy(reply, "PONG\n", 5);
3235 } else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) {
3236 if (wpa_supplicant_global_iface_add(global, buf + 14))
3238 } else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) {
3239 if (wpa_supplicant_global_iface_remove(global, buf + 17))
3241 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
3242 reply_len = wpa_supplicant_global_iface_list(
3243 global, reply, reply_size);
3244 } else if (os_strcmp(buf, "INTERFACES") == 0) {
3245 reply_len = wpa_supplicant_global_iface_interfaces(
3246 global, reply, reply_size);
3247 } else if (os_strcmp(buf, "TERMINATE") == 0) {
3248 wpa_supplicant_terminate_proc(global);
3249 } else if (os_strcmp(buf, "SUSPEND") == 0) {
3250 wpas_notify_suspend(global);
3251 } else if (os_strcmp(buf, "RESUME") == 0) {
3252 wpas_notify_resume(global);
3254 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
3258 if (reply_len < 0) {
3259 os_memcpy(reply, "FAIL\n", 5);
3263 *resp_len = reply_len;