2 * WPA Supplicant / Control interface (shared code for all backends)
3 * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "common/version.h"
14 #include "common/ieee802_11_defs.h"
15 #include "common/wpa_ctrl.h"
16 #include "eap_peer/eap.h"
17 #include "eapol_supp/eapol_supp_sm.h"
18 #include "rsn_supp/wpa.h"
19 #include "rsn_supp/preauth.h"
20 #include "rsn_supp/pmksa_cache.h"
21 #include "l2_packet/l2_packet.h"
24 #include "wpa_supplicant_i.h"
26 #include "wps_supplicant.h"
29 #include "p2p_supplicant.h"
34 #include "ctrl_iface.h"
35 #include "interworking.h"
36 #include "blacklist.h"
37 #include "wpas_glue.h"
39 extern struct wpa_driver_ops *wpa_drivers[];
41 static int wpa_supplicant_global_iface_list(struct wpa_global *global,
43 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
47 static int pno_start(struct wpa_supplicant *wpa_s)
51 struct wpa_ssid *ssid;
52 struct wpa_driver_scan_params params;
57 os_memset(¶ms, 0, sizeof(params));
60 ssid = wpa_s->conf->ssid;
66 if (num_ssid > WPAS_MAX_SCAN_SSIDS) {
67 wpa_printf(MSG_DEBUG, "PNO: Use only the first %u SSIDs from "
68 "%u", WPAS_MAX_SCAN_SSIDS, (unsigned int) num_ssid);
69 num_ssid = WPAS_MAX_SCAN_SSIDS;
73 wpa_printf(MSG_DEBUG, "PNO: No configured SSIDs");
77 params.filter_ssids = os_malloc(sizeof(struct wpa_driver_scan_filter) *
79 if (params.filter_ssids == NULL)
82 ssid = wpa_s->conf->ssid;
84 if (!ssid->disabled) {
85 params.ssids[i].ssid = ssid->ssid;
86 params.ssids[i].ssid_len = ssid->ssid_len;
88 os_memcpy(params.filter_ssids[i].ssid, ssid->ssid,
90 params.filter_ssids[i].ssid_len = ssid->ssid_len;
91 params.num_filter_ssids++;
99 ret = wpa_drv_sched_scan(wpa_s, ¶ms, 10 * 1000);
100 os_free(params.filter_ssids);
107 static int pno_stop(struct wpa_supplicant *wpa_s)
111 return wpa_drv_stop_sched_scan(wpa_s);
117 static int set_bssid_filter(struct wpa_supplicant *wpa_s, char *val)
120 u8 addr[ETH_ALEN], *filter = NULL, *n;
127 if (hwaddr_aton(pos, addr))
129 n = os_realloc(filter, (count + 1) * ETH_ALEN);
135 os_memcpy(filter + count * ETH_ALEN, addr, ETH_ALEN);
138 pos = os_strchr(pos, ' ');
143 wpa_hexdump(MSG_DEBUG, "bssid_filter", filter, count * ETH_ALEN);
144 os_free(wpa_s->bssid_filter);
145 wpa_s->bssid_filter = filter;
146 wpa_s->bssid_filter_count = count;
152 static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
158 value = os_strchr(cmd, ' ');
163 wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value);
164 if (os_strcasecmp(cmd, "EAPOL::heldPeriod") == 0) {
165 eapol_sm_configure(wpa_s->eapol,
166 atoi(value), -1, -1, -1);
167 } else if (os_strcasecmp(cmd, "EAPOL::authPeriod") == 0) {
168 eapol_sm_configure(wpa_s->eapol,
169 -1, atoi(value), -1, -1);
170 } else if (os_strcasecmp(cmd, "EAPOL::startPeriod") == 0) {
171 eapol_sm_configure(wpa_s->eapol,
172 -1, -1, atoi(value), -1);
173 } else if (os_strcasecmp(cmd, "EAPOL::maxStart") == 0) {
174 eapol_sm_configure(wpa_s->eapol,
175 -1, -1, -1, atoi(value));
176 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) {
177 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
180 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") ==
182 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
185 } else if (os_strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) {
186 if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value)))
188 } else if (os_strcasecmp(cmd, "wps_fragment_size") == 0) {
189 wpa_s->wps_fragment_size = atoi(value);
190 #ifdef CONFIG_WPS_TESTING
191 } else if (os_strcasecmp(cmd, "wps_version_number") == 0) {
193 val = strtol(value, NULL, 0);
194 if (val < 0 || val > 0xff) {
196 wpa_printf(MSG_DEBUG, "WPS: Invalid "
197 "wps_version_number %ld", val);
199 wps_version_number = val;
200 wpa_printf(MSG_DEBUG, "WPS: Testing - force WPS "
202 (wps_version_number & 0xf0) >> 4,
203 wps_version_number & 0x0f);
205 } else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) {
206 wps_testing_dummy_cred = atoi(value);
207 wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d",
208 wps_testing_dummy_cred);
209 #endif /* CONFIG_WPS_TESTING */
210 } else if (os_strcasecmp(cmd, "ampdu") == 0) {
211 if (wpa_drv_ampdu(wpa_s, atoi(value)) < 0)
213 #ifdef CONFIG_TDLS_TESTING
214 } else if (os_strcasecmp(cmd, "tdls_testing") == 0) {
215 extern unsigned int tdls_testing;
216 tdls_testing = strtol(value, NULL, 0);
217 wpa_printf(MSG_DEBUG, "TDLS: tdls_testing=0x%x", tdls_testing);
218 #endif /* CONFIG_TDLS_TESTING */
220 } else if (os_strcasecmp(cmd, "tdls_disabled") == 0) {
221 int disabled = atoi(value);
222 wpa_printf(MSG_DEBUG, "TDLS: tdls_disabled=%d", disabled);
224 if (wpa_drv_tdls_oper(wpa_s, TDLS_DISABLE, NULL) < 0)
226 } else if (wpa_drv_tdls_oper(wpa_s, TDLS_ENABLE, NULL) < 0)
228 wpa_tdls_enable(wpa_s->wpa, !disabled);
229 #endif /* CONFIG_TDLS */
230 } else if (os_strcasecmp(cmd, "pno") == 0) {
232 ret = pno_start(wpa_s);
234 ret = pno_stop(wpa_s);
235 } else if (os_strcasecmp(cmd, "radio_disabled") == 0) {
236 int disabled = atoi(value);
237 if (wpa_drv_radio_disable(wpa_s, disabled) < 0)
240 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
241 } else if (os_strcasecmp(cmd, "uapsd") == 0) {
242 if (os_strcmp(value, "disable") == 0)
243 wpa_s->set_sta_uapsd = 0;
247 /* format: BE,BK,VI,VO;max SP Length */
249 pos = os_strchr(value, ',');
254 pos = os_strchr(pos, ',');
259 pos = os_strchr(pos, ',');
264 /* ignore max SP Length for now */
266 wpa_s->set_sta_uapsd = 1;
267 wpa_s->sta_uapsd = 0;
269 wpa_s->sta_uapsd |= BIT(0);
271 wpa_s->sta_uapsd |= BIT(1);
273 wpa_s->sta_uapsd |= BIT(2);
275 wpa_s->sta_uapsd |= BIT(3);
277 } else if (os_strcasecmp(cmd, "ps") == 0) {
278 ret = wpa_drv_set_p2p_powersave(wpa_s, atoi(value), -1, -1);
279 } else if (os_strcasecmp(cmd, "bssid_filter") == 0) {
280 ret = set_bssid_filter(wpa_s, value);
283 ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
285 wpa_supplicant_update_config(wpa_s);
292 static int wpa_supplicant_ctrl_iface_get(struct wpa_supplicant *wpa_s,
293 char *cmd, char *buf, size_t buflen)
297 wpa_printf(MSG_DEBUG, "CTRL_IFACE GET '%s'", cmd);
299 if (os_strcmp(cmd, "version") == 0) {
300 res = os_snprintf(buf, buflen, "%s", VERSION_STR);
301 } else if (os_strcasecmp(cmd, "country") == 0) {
302 if (wpa_s->conf->country[0] && wpa_s->conf->country[1])
303 res = os_snprintf(buf, buflen, "%c%c",
304 wpa_s->conf->country[0],
305 wpa_s->conf->country[1]);
308 if (res < 0 || (unsigned int) res >= buflen)
314 #ifdef IEEE8021X_EAPOL
315 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s,
319 struct wpa_ssid *ssid = wpa_s->current_ssid;
321 if (hwaddr_aton(addr, bssid)) {
322 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address "
327 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid));
328 rsn_preauth_deinit(wpa_s->wpa);
329 if (rsn_preauth_init(wpa_s->wpa, bssid, ssid ? &ssid->eap : NULL))
334 #endif /* IEEE8021X_EAPOL */
337 #ifdef CONFIG_PEERKEY
338 /* MLME-STKSTART.request(peer) */
339 static int wpa_supplicant_ctrl_iface_stkstart(
340 struct wpa_supplicant *wpa_s, char *addr)
344 if (hwaddr_aton(addr, peer)) {
345 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid "
346 "address '%s'", addr);
350 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART " MACSTR,
353 return wpa_sm_stkstart(wpa_s->wpa, peer);
355 #endif /* CONFIG_PEERKEY */
360 static int wpa_supplicant_ctrl_iface_tdls_discover(
361 struct wpa_supplicant *wpa_s, char *addr)
366 if (hwaddr_aton(addr, peer)) {
367 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER: invalid "
368 "address '%s'", addr);
372 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER " MACSTR,
375 if (wpa_tdls_is_external_setup(wpa_s->wpa))
376 ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
378 ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
384 static int wpa_supplicant_ctrl_iface_tdls_setup(
385 struct wpa_supplicant *wpa_s, char *addr)
390 if (hwaddr_aton(addr, peer)) {
391 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP: invalid "
392 "address '%s'", addr);
396 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP " MACSTR,
399 ret = wpa_tdls_reneg(wpa_s->wpa, peer);
401 if (wpa_tdls_is_external_setup(wpa_s->wpa))
402 ret = wpa_tdls_start(wpa_s->wpa, peer);
404 ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
411 static int wpa_supplicant_ctrl_iface_tdls_teardown(
412 struct wpa_supplicant *wpa_s, char *addr)
416 if (hwaddr_aton(addr, peer)) {
417 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN: invalid "
418 "address '%s'", addr);
422 wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN " MACSTR,
425 return wpa_tdls_teardown_link(wpa_s->wpa, peer,
426 WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
429 #endif /* CONFIG_TDLS */
432 #ifdef CONFIG_IEEE80211R
433 static int wpa_supplicant_ctrl_iface_ft_ds(
434 struct wpa_supplicant *wpa_s, char *addr)
436 u8 target_ap[ETH_ALEN];
440 if (hwaddr_aton(addr, target_ap)) {
441 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS: invalid "
442 "address '%s'", addr);
446 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS " MACSTR, MAC2STR(target_ap));
448 bss = wpa_bss_get_bssid(wpa_s, target_ap);
450 mdie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
454 return wpa_ft_start_over_ds(wpa_s->wpa, target_ap, mdie);
456 #endif /* CONFIG_IEEE80211R */
460 static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
463 u8 bssid[ETH_ALEN], *_bssid = bssid;
465 u8 p2p_dev_addr[ETH_ALEN];
466 #endif /* CONFIG_P2P */
468 u8 *_p2p_dev_addr = NULL;
469 #endif /* CONFIG_AP */
471 if (cmd == NULL || os_strcmp(cmd, "any") == 0) {
474 } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) {
475 if (hwaddr_aton(cmd + 13, p2p_dev_addr)) {
476 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid "
477 "P2P Device Address '%s'",
481 _p2p_dev_addr = p2p_dev_addr;
482 #endif /* CONFIG_P2P */
483 } else if (hwaddr_aton(cmd, bssid)) {
484 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
491 return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr);
492 #endif /* CONFIG_AP */
494 return wpas_wps_start_pbc(wpa_s, _bssid, 0);
498 static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
499 char *cmd, char *buf,
502 u8 bssid[ETH_ALEN], *_bssid = bssid;
506 pin = os_strchr(cmd, ' ');
510 if (os_strcmp(cmd, "any") == 0)
512 else if (os_strcmp(cmd, "get") == 0) {
513 ret = wps_generate_pin();
515 } else if (hwaddr_aton(cmd, bssid)) {
516 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
523 return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin,
525 #endif /* CONFIG_AP */
528 ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0,
532 ret = os_snprintf(buf, buflen, "%s", pin);
533 if (ret < 0 || (size_t) ret >= buflen)
538 ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0, DEV_PW_DEFAULT);
543 /* Return the generated PIN */
544 ret = os_snprintf(buf, buflen, "%08d", ret);
545 if (ret < 0 || (size_t) ret >= buflen)
551 static int wpa_supplicant_ctrl_iface_wps_check_pin(
552 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
559 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS_CHECK_PIN",
560 (u8 *) cmd, os_strlen(cmd));
561 for (pos = cmd, len = 0; *pos != '\0'; pos++) {
562 if (*pos < '0' || *pos > '9')
566 wpa_printf(MSG_DEBUG, "WPS: Too long PIN");
570 if (len != 4 && len != 8) {
571 wpa_printf(MSG_DEBUG, "WPS: Invalid PIN length %d", (int) len);
577 unsigned int pin_val;
579 if (!wps_pin_valid(pin_val)) {
580 wpa_printf(MSG_DEBUG, "WPS: Invalid checksum digit");
581 ret = os_snprintf(buf, buflen, "FAIL-CHECKSUM\n");
582 if (ret < 0 || (size_t) ret >= buflen)
588 ret = os_snprintf(buf, buflen, "%s", pin);
589 if (ret < 0 || (size_t) ret >= buflen)
596 #ifdef CONFIG_WPS_OOB
597 static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant *wpa_s,
600 char *path, *method, *name;
602 path = os_strchr(cmd, ' ');
607 method = os_strchr(path, ' ');
612 name = os_strchr(method, ' ');
616 return wpas_wps_start_oob(wpa_s, cmd, path, method, name);
618 #endif /* CONFIG_WPS_OOB */
621 static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s,
630 struct wps_new_ap_settings ap;
632 pin = os_strchr(cmd, ' ');
637 if (hwaddr_aton(cmd, bssid)) {
638 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_REG: invalid BSSID '%s'",
643 new_ssid = os_strchr(pin, ' ');
644 if (new_ssid == NULL)
645 return wpas_wps_start_reg(wpa_s, bssid, pin, NULL);
648 new_auth = os_strchr(new_ssid, ' ');
649 if (new_auth == NULL)
653 new_encr = os_strchr(new_auth, ' ');
654 if (new_encr == NULL)
658 new_key = os_strchr(new_encr, ' ');
663 os_memset(&ap, 0, sizeof(ap));
664 ap.ssid_hex = new_ssid;
667 ap.key_hex = new_key;
668 return wpas_wps_start_reg(wpa_s, bssid, pin, &ap);
673 static int wpa_supplicant_ctrl_iface_wps_ap_pin(struct wpa_supplicant *wpa_s,
674 char *cmd, char *buf,
681 if (!wpa_s->ap_iface)
684 pos = os_strchr(cmd, ' ');
688 if (os_strcmp(cmd, "disable") == 0) {
689 wpas_wps_ap_pin_disable(wpa_s);
690 return os_snprintf(buf, buflen, "OK\n");
693 if (os_strcmp(cmd, "random") == 0) {
696 pin_txt = wpas_wps_ap_pin_random(wpa_s, timeout);
699 return os_snprintf(buf, buflen, "%s", pin_txt);
702 if (os_strcmp(cmd, "get") == 0) {
703 pin_txt = wpas_wps_ap_pin_get(wpa_s);
706 return os_snprintf(buf, buflen, "%s", pin_txt);
709 if (os_strcmp(cmd, "set") == 0) {
714 pos = os_strchr(pos, ' ');
719 if (os_strlen(pin) > buflen)
721 if (wpas_wps_ap_pin_set(wpa_s, pin, timeout) < 0)
723 return os_snprintf(buf, buflen, "%s", pin);
728 #endif /* CONFIG_AP */
732 static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant *wpa_s,
735 char *uuid = cmd, *pin, *pos;
736 u8 addr_buf[ETH_ALEN], *addr = NULL;
737 pin = os_strchr(uuid, ' ');
741 pos = os_strchr(pin, ' ');
744 if (hwaddr_aton(pos, addr_buf) == 0)
747 return wpas_wps_er_add_pin(wpa_s, addr, uuid, pin);
751 static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant *wpa_s,
754 char *uuid = cmd, *pin;
755 pin = os_strchr(uuid, ' ');
759 return wpas_wps_er_learn(wpa_s, uuid, pin);
763 static int wpa_supplicant_ctrl_iface_wps_er_set_config(
764 struct wpa_supplicant *wpa_s, char *cmd)
766 char *uuid = cmd, *id;
767 id = os_strchr(uuid, ' ');
771 return wpas_wps_er_set_config(wpa_s, uuid, atoi(id));
775 static int wpa_supplicant_ctrl_iface_wps_er_config(
776 struct wpa_supplicant *wpa_s, char *cmd)
783 struct wps_new_ap_settings ap;
785 pin = os_strchr(cmd, ' ');
790 new_ssid = os_strchr(pin, ' ');
791 if (new_ssid == NULL)
795 new_auth = os_strchr(new_ssid, ' ');
796 if (new_auth == NULL)
800 new_encr = os_strchr(new_auth, ' ');
801 if (new_encr == NULL)
805 new_key = os_strchr(new_encr, ' ');
810 os_memset(&ap, 0, sizeof(ap));
811 ap.ssid_hex = new_ssid;
814 ap.key_hex = new_key;
815 return wpas_wps_er_config(wpa_s, cmd, pin, &ap);
817 #endif /* CONFIG_WPS_ER */
819 #endif /* CONFIG_WPS */
822 #ifdef CONFIG_IBSS_RSN
823 static int wpa_supplicant_ctrl_iface_ibss_rsn(
824 struct wpa_supplicant *wpa_s, char *addr)
828 if (hwaddr_aton(addr, peer)) {
829 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN: invalid "
830 "address '%s'", addr);
834 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN " MACSTR,
837 return ibss_rsn_start(wpa_s->ibss_rsn, peer);
839 #endif /* CONFIG_IBSS_RSN */
842 int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
843 struct wpa_ssid *ssid,
847 #ifdef IEEE8021X_EAPOL
848 struct eap_peer_config *eap = &ssid->eap;
850 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
851 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
852 (const u8 *) value, os_strlen(value));
854 switch (wpa_supplicant_ctrl_req_from_string(field)) {
855 case WPA_CTRL_REQ_EAP_IDENTITY:
856 os_free(eap->identity);
857 eap->identity = (u8 *) os_strdup(value);
858 eap->identity_len = os_strlen(value);
859 eap->pending_req_identity = 0;
860 if (ssid == wpa_s->current_ssid)
861 wpa_s->reassociate = 1;
863 case WPA_CTRL_REQ_EAP_PASSWORD:
864 os_free(eap->password);
865 eap->password = (u8 *) os_strdup(value);
866 eap->password_len = os_strlen(value);
867 eap->pending_req_password = 0;
868 if (ssid == wpa_s->current_ssid)
869 wpa_s->reassociate = 1;
871 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
872 os_free(eap->new_password);
873 eap->new_password = (u8 *) os_strdup(value);
874 eap->new_password_len = os_strlen(value);
875 eap->pending_req_new_password = 0;
876 if (ssid == wpa_s->current_ssid)
877 wpa_s->reassociate = 1;
879 case WPA_CTRL_REQ_EAP_PIN:
881 eap->pin = os_strdup(value);
882 eap->pending_req_pin = 0;
883 if (ssid == wpa_s->current_ssid)
884 wpa_s->reassociate = 1;
886 case WPA_CTRL_REQ_EAP_OTP:
888 eap->otp = (u8 *) os_strdup(value);
889 eap->otp_len = os_strlen(value);
890 os_free(eap->pending_req_otp);
891 eap->pending_req_otp = NULL;
892 eap->pending_req_otp_len = 0;
894 case WPA_CTRL_REQ_EAP_PASSPHRASE:
895 os_free(eap->private_key_passwd);
896 eap->private_key_passwd = (u8 *) os_strdup(value);
897 eap->pending_req_passphrase = 0;
898 if (ssid == wpa_s->current_ssid)
899 wpa_s->reassociate = 1;
902 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
907 #else /* IEEE8021X_EAPOL */
908 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
910 #endif /* IEEE8021X_EAPOL */
914 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
917 #ifdef IEEE8021X_EAPOL
920 struct wpa_ssid *ssid;
922 pos = os_strchr(rsp, '-');
927 pos = os_strchr(pos, ':');
932 wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id);
933 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
934 (u8 *) pos, os_strlen(pos));
936 ssid = wpa_config_get_network(wpa_s->conf, id);
938 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
943 return wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s, ssid, rsp,
945 #else /* IEEE8021X_EAPOL */
946 wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
948 #endif /* IEEE8021X_EAPOL */
952 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
954 char *buf, size_t buflen)
956 char *pos, *end, tmp[30];
957 int res, verbose, wps, ret;
959 verbose = os_strcmp(params, "-VERBOSE") == 0;
960 wps = os_strcmp(params, "-WPS") == 0;
963 if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
964 struct wpa_ssid *ssid = wpa_s->current_ssid;
965 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
966 MAC2STR(wpa_s->bssid));
967 if (ret < 0 || ret >= end - pos)
971 u8 *_ssid = ssid->ssid;
972 size_t ssid_len = ssid->ssid_len;
973 u8 ssid_buf[MAX_SSID_LEN];
975 int _res = wpa_drv_get_ssid(wpa_s, ssid_buf);
982 ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n",
983 wpa_ssid_txt(_ssid, ssid_len),
985 if (ret < 0 || ret >= end - pos)
989 if (wps && ssid->passphrase &&
990 wpa_key_mgmt_wpa_psk(ssid->key_mgmt) &&
991 (ssid->mode == WPAS_MODE_AP ||
992 ssid->mode == WPAS_MODE_P2P_GO)) {
993 ret = os_snprintf(pos, end - pos,
996 if (ret < 0 || ret >= end - pos)
1001 ret = os_snprintf(pos, end - pos,
1004 if (ret < 0 || ret >= end - pos)
1009 switch (ssid->mode) {
1010 case WPAS_MODE_INFRA:
1011 ret = os_snprintf(pos, end - pos,
1014 case WPAS_MODE_IBSS:
1015 ret = os_snprintf(pos, end - pos,
1019 ret = os_snprintf(pos, end - pos,
1022 case WPAS_MODE_P2P_GO:
1023 ret = os_snprintf(pos, end - pos,
1026 case WPAS_MODE_P2P_GROUP_FORMATION:
1027 ret = os_snprintf(pos, end - pos,
1028 "mode=P2P GO - group "
1035 if (ret < 0 || ret >= end - pos)
1041 if (wpa_s->ap_iface) {
1042 pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
1046 #endif /* CONFIG_AP */
1047 pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose);
1049 ret = os_snprintf(pos, end - pos, "wpa_state=%s\n",
1050 wpa_supplicant_state_txt(wpa_s->wpa_state));
1051 if (ret < 0 || ret >= end - pos)
1056 l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) {
1057 ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp);
1058 if (ret < 0 || ret >= end - pos)
1064 if (wpa_s->global->p2p) {
1065 ret = os_snprintf(pos, end - pos, "p2p_device_address=" MACSTR
1066 "\n", MAC2STR(wpa_s->global->p2p_dev_addr));
1067 if (ret < 0 || ret >= end - pos)
1071 #endif /* CONFIG_P2P */
1073 ret = os_snprintf(pos, end - pos, "address=" MACSTR "\n",
1074 MAC2STR(wpa_s->own_addr));
1075 if (ret < 0 || ret >= end - pos)
1079 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
1080 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1081 res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos,
1087 res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose);
1095 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s,
1100 struct wpa_ssid *ssid;
1103 /* cmd: "<network id> <BSSID>" */
1104 pos = os_strchr(cmd, ' ');
1109 wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos);
1110 if (hwaddr_aton(pos, bssid)) {
1111 wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos);
1115 ssid = wpa_config_get_network(wpa_s->conf, id);
1117 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
1122 os_memcpy(ssid->bssid, bssid, ETH_ALEN);
1123 ssid->bssid_set = !is_zero_ether_addr(bssid);
1129 static int wpa_supplicant_ctrl_iface_blacklist(struct wpa_supplicant *wpa_s,
1130 char *cmd, char *buf,
1134 struct wpa_blacklist *e;
1138 /* cmd: "BLACKLIST [<BSSID>]" */
1142 e = wpa_s->blacklist;
1144 ret = os_snprintf(pos, end - pos, MACSTR "\n",
1146 if (ret < 0 || ret >= end - pos)
1155 if (os_strncmp(cmd, "clear", 5) == 0) {
1156 wpa_blacklist_clear(wpa_s);
1157 os_memcpy(buf, "OK\n", 3);
1161 wpa_printf(MSG_DEBUG, "CTRL_IFACE: BLACKLIST bssid='%s'", cmd);
1162 if (hwaddr_aton(cmd, bssid)) {
1163 wpa_printf(MSG_DEBUG, "CTRL_IFACE: invalid BSSID '%s'", cmd);
1168 * Add the BSSID twice, so its count will be 2, causing it to be
1169 * skipped when processing scan results.
1171 ret = wpa_blacklist_add(wpa_s, bssid);
1174 ret = wpa_blacklist_add(wpa_s, bssid);
1177 os_memcpy(buf, "OK\n", 3);
1182 extern int wpa_debug_level;
1183 extern int wpa_debug_timestamp;
1185 static const char * debug_level_str(int level)
1206 static int str_to_debug_level(const char *s)
1208 if (os_strcasecmp(s, "EXCESSIVE") == 0)
1209 return MSG_EXCESSIVE;
1210 if (os_strcasecmp(s, "MSGDUMP") == 0)
1212 if (os_strcasecmp(s, "DEBUG") == 0)
1214 if (os_strcasecmp(s, "INFO") == 0)
1216 if (os_strcasecmp(s, "WARNING") == 0)
1218 if (os_strcasecmp(s, "ERROR") == 0)
1224 static int wpa_supplicant_ctrl_iface_log_level(struct wpa_supplicant *wpa_s,
1225 char *cmd, char *buf,
1228 char *pos, *end, *stamp;
1235 /* cmd: "LOG_LEVEL [<level>]" */
1239 ret = os_snprintf(pos, end - pos, "Current level: %s\n"
1241 debug_level_str(wpa_debug_level),
1242 wpa_debug_timestamp);
1243 if (ret < 0 || ret >= end - pos)
1252 stamp = os_strchr(cmd, ' ');
1255 while (*stamp == ' ') {
1260 if (cmd && os_strlen(cmd)) {
1261 int level = str_to_debug_level(cmd);
1264 wpa_debug_level = level;
1267 if (stamp && os_strlen(stamp))
1268 wpa_debug_timestamp = atoi(stamp);
1270 os_memcpy(buf, "OK\n", 3);
1275 static int wpa_supplicant_ctrl_iface_list_networks(
1276 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
1279 struct wpa_ssid *ssid;
1284 ret = os_snprintf(pos, end - pos,
1285 "network id / ssid / bssid / flags\n");
1286 if (ret < 0 || ret >= end - pos)
1290 ssid = wpa_s->conf->ssid;
1292 ret = os_snprintf(pos, end - pos, "%d\t%s",
1294 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1295 if (ret < 0 || ret >= end - pos)
1298 if (ssid->bssid_set) {
1299 ret = os_snprintf(pos, end - pos, "\t" MACSTR,
1300 MAC2STR(ssid->bssid));
1302 ret = os_snprintf(pos, end - pos, "\tany");
1304 if (ret < 0 || ret >= end - pos)
1307 ret = os_snprintf(pos, end - pos, "\t%s%s%s",
1308 ssid == wpa_s->current_ssid ?
1310 ssid->disabled ? "[DISABLED]" : "",
1311 ssid->disabled == 2 ? "[P2P-PERSISTENT]" :
1313 if (ret < 0 || ret >= end - pos)
1316 ret = os_snprintf(pos, end - pos, "\n");
1317 if (ret < 0 || ret >= end - pos)
1328 static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher)
1331 ret = os_snprintf(pos, end - pos, "-");
1332 if (ret < 0 || ret >= end - pos)
1335 if (cipher & WPA_CIPHER_NONE) {
1336 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : "+");
1337 if (ret < 0 || ret >= end - pos)
1342 if (cipher & WPA_CIPHER_WEP40) {
1343 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : "+");
1344 if (ret < 0 || ret >= end - pos)
1349 if (cipher & WPA_CIPHER_WEP104) {
1350 ret = os_snprintf(pos, end - pos, "%sWEP104",
1352 if (ret < 0 || ret >= end - pos)
1357 if (cipher & WPA_CIPHER_TKIP) {
1358 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : "+");
1359 if (ret < 0 || ret >= end - pos)
1364 if (cipher & WPA_CIPHER_CCMP) {
1365 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : "+");
1366 if (ret < 0 || ret >= end - pos)
1375 static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
1376 const u8 *ie, size_t ie_len)
1378 struct wpa_ie_data data;
1381 ret = os_snprintf(pos, end - pos, "[%s-", proto);
1382 if (ret < 0 || ret >= end - pos)
1386 if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) {
1387 ret = os_snprintf(pos, end - pos, "?]");
1388 if (ret < 0 || ret >= end - pos)
1395 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
1396 ret = os_snprintf(pos, end - pos, "%sEAP", first ? "" : "+");
1397 if (ret < 0 || ret >= end - pos)
1402 if (data.key_mgmt & WPA_KEY_MGMT_PSK) {
1403 ret = os_snprintf(pos, end - pos, "%sPSK", first ? "" : "+");
1404 if (ret < 0 || ret >= end - pos)
1409 if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
1410 ret = os_snprintf(pos, end - pos, "%sNone", first ? "" : "+");
1411 if (ret < 0 || ret >= end - pos)
1416 #ifdef CONFIG_IEEE80211R
1417 if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
1418 ret = os_snprintf(pos, end - pos, "%sFT/EAP",
1420 if (ret < 0 || ret >= end - pos)
1425 if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) {
1426 ret = os_snprintf(pos, end - pos, "%sFT/PSK",
1428 if (ret < 0 || ret >= end - pos)
1433 #endif /* CONFIG_IEEE80211R */
1434 #ifdef CONFIG_IEEE80211W
1435 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
1436 ret = os_snprintf(pos, end - pos, "%sEAP-SHA256",
1438 if (ret < 0 || ret >= end - pos)
1443 if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
1444 ret = os_snprintf(pos, end - pos, "%sPSK-SHA256",
1446 if (ret < 0 || ret >= end - pos)
1451 #endif /* CONFIG_IEEE80211W */
1453 pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher);
1455 if (data.capabilities & WPA_CAPABILITY_PREAUTH) {
1456 ret = os_snprintf(pos, end - pos, "-preauth");
1457 if (ret < 0 || ret >= end - pos)
1462 ret = os_snprintf(pos, end - pos, "]");
1463 if (ret < 0 || ret >= end - pos)
1472 static char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant *wpa_s,
1473 char *pos, char *end,
1474 struct wpabuf *wps_ie)
1481 if (wps_is_selected_pbc_registrar(wps_ie))
1484 else if (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 0))
1486 #endif /* CONFIG_WPS2 */
1487 else if (wps_is_selected_pin_registrar(wps_ie))
1492 ret = os_snprintf(pos, end - pos, "%s", txt);
1493 if (ret >= 0 && ret < end - pos)
1495 wpabuf_free(wps_ie);
1498 #endif /* CONFIG_WPS */
1501 static char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant *wpa_s,
1502 char *pos, char *end,
1503 const struct wpa_bss *bss)
1506 struct wpabuf *wps_ie;
1507 wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
1508 return wpa_supplicant_wps_ie_txt_buf(wpa_s, pos, end, wps_ie);
1509 #else /* CONFIG_WPS */
1511 #endif /* CONFIG_WPS */
1515 /* Format one result on one text line into a buffer. */
1516 static int wpa_supplicant_ctrl_iface_scan_result(
1517 struct wpa_supplicant *wpa_s,
1518 const struct wpa_bss *bss, char *buf, size_t buflen)
1522 const u8 *ie, *ie2, *p2p;
1524 p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE);
1525 if (p2p && bss->ssid_len == P2P_WILDCARD_SSID_LEN &&
1526 os_memcmp(bss->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) ==
1528 return 0; /* Do not show P2P listen discovery results here */
1533 ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t",
1534 MAC2STR(bss->bssid), bss->freq, bss->level);
1535 if (ret < 0 || ret >= end - pos)
1538 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
1540 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
1541 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1543 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
1544 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
1545 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
1546 ret = os_snprintf(pos, end - pos, "[WEP]");
1547 if (ret < 0 || ret >= end - pos)
1551 if (bss->caps & IEEE80211_CAP_IBSS) {
1552 ret = os_snprintf(pos, end - pos, "[IBSS]");
1553 if (ret < 0 || ret >= end - pos)
1557 if (bss->caps & IEEE80211_CAP_ESS) {
1558 ret = os_snprintf(pos, end - pos, "[ESS]");
1559 if (ret < 0 || ret >= end - pos)
1564 ret = os_snprintf(pos, end - pos, "[P2P]");
1565 if (ret < 0 || ret >= end - pos)
1570 ret = os_snprintf(pos, end - pos, "\t%s",
1571 wpa_ssid_txt(bss->ssid, bss->ssid_len));
1572 if (ret < 0 || ret >= end - pos)
1576 ret = os_snprintf(pos, end - pos, "\n");
1577 if (ret < 0 || ret >= end - pos)
1585 static int wpa_supplicant_ctrl_iface_scan_results(
1586 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
1589 struct wpa_bss *bss;
1594 ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / "
1596 if (ret < 0 || ret >= end - pos)
1600 dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
1601 ret = wpa_supplicant_ctrl_iface_scan_result(wpa_s, bss, pos,
1603 if (ret < 0 || ret >= end - pos)
1612 static int wpa_supplicant_ctrl_iface_select_network(
1613 struct wpa_supplicant *wpa_s, char *cmd)
1616 struct wpa_ssid *ssid;
1618 /* cmd: "<network id>" or "any" */
1619 if (os_strcmp(cmd, "any") == 0) {
1620 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any");
1624 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id);
1626 ssid = wpa_config_get_network(wpa_s->conf, id);
1628 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
1629 "network id=%d", id);
1632 if (ssid->disabled == 2) {
1633 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
1634 "SELECT_NETWORK with persistent P2P group");
1639 wpa_supplicant_select_network(wpa_s, ssid);
1645 static int wpa_supplicant_ctrl_iface_enable_network(
1646 struct wpa_supplicant *wpa_s, char *cmd)
1649 struct wpa_ssid *ssid;
1651 /* cmd: "<network id>" or "all" */
1652 if (os_strcmp(cmd, "all") == 0) {
1653 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all");
1657 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id);
1659 ssid = wpa_config_get_network(wpa_s->conf, id);
1661 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
1662 "network id=%d", id);
1665 if (ssid->disabled == 2) {
1666 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
1667 "ENABLE_NETWORK with persistent P2P group");
1671 if (os_strstr(cmd, " no-connect")) {
1676 wpa_supplicant_enable_network(wpa_s, ssid);
1682 static int wpa_supplicant_ctrl_iface_disable_network(
1683 struct wpa_supplicant *wpa_s, char *cmd)
1686 struct wpa_ssid *ssid;
1688 /* cmd: "<network id>" or "all" */
1689 if (os_strcmp(cmd, "all") == 0) {
1690 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all");
1694 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id);
1696 ssid = wpa_config_get_network(wpa_s->conf, id);
1698 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
1699 "network id=%d", id);
1702 if (ssid->disabled == 2) {
1703 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Cannot use "
1704 "DISABLE_NETWORK with persistent P2P "
1709 wpa_supplicant_disable_network(wpa_s, ssid);
1715 static int wpa_supplicant_ctrl_iface_add_network(
1716 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
1718 struct wpa_ssid *ssid;
1721 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK");
1723 ssid = wpa_config_add_network(wpa_s->conf);
1727 wpas_notify_network_added(wpa_s, ssid);
1730 wpa_config_set_network_defaults(ssid);
1732 ret = os_snprintf(buf, buflen, "%d\n", ssid->id);
1733 if (ret < 0 || (size_t) ret >= buflen)
1739 static int wpa_supplicant_ctrl_iface_remove_network(
1740 struct wpa_supplicant *wpa_s, char *cmd)
1743 struct wpa_ssid *ssid;
1745 /* cmd: "<network id>" or "all" */
1746 if (os_strcmp(cmd, "all") == 0) {
1747 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all");
1748 ssid = wpa_s->conf->ssid;
1750 struct wpa_ssid *remove_ssid = ssid;
1753 wpas_notify_network_removed(wpa_s, remove_ssid);
1754 wpa_config_remove_network(wpa_s->conf, id);
1756 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1757 if (wpa_s->current_ssid) {
1758 wpa_sm_set_config(wpa_s->wpa, NULL);
1759 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
1760 wpa_supplicant_disassociate(wpa_s,
1761 WLAN_REASON_DEAUTH_LEAVING);
1767 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id);
1769 ssid = wpa_config_get_network(wpa_s->conf, id);
1771 wpas_notify_network_removed(wpa_s, ssid);
1773 wpa_config_remove_network(wpa_s->conf, id) < 0) {
1774 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1779 if (ssid == wpa_s->current_ssid || wpa_s->current_ssid == NULL) {
1781 * Invalidate the EAP session cache if the current or
1782 * previously used network is removed.
1784 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1787 if (ssid == wpa_s->current_ssid) {
1788 wpa_sm_set_config(wpa_s->wpa, NULL);
1789 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
1791 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1798 static int wpa_supplicant_ctrl_iface_set_network(
1799 struct wpa_supplicant *wpa_s, char *cmd)
1802 struct wpa_ssid *ssid;
1805 /* cmd: "<network id> <variable name> <value>" */
1806 name = os_strchr(cmd, ' ');
1811 value = os_strchr(name, ' ');
1817 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
1819 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
1820 (u8 *) value, os_strlen(value));
1822 ssid = wpa_config_get_network(wpa_s->conf, id);
1824 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1829 if (wpa_config_set(ssid, name, value, 0) < 0) {
1830 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network "
1831 "variable '%s'", name);
1835 wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
1837 if (wpa_s->current_ssid == ssid || wpa_s->current_ssid == NULL) {
1839 * Invalidate the EAP session cache if anything in the current
1840 * or previously used configuration changes.
1842 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1845 if ((os_strcmp(name, "psk") == 0 &&
1846 value[0] == '"' && ssid->ssid_len) ||
1847 (os_strcmp(name, "ssid") == 0 && ssid->passphrase))
1848 wpa_config_update_psk(ssid);
1849 else if (os_strcmp(name, "priority") == 0)
1850 wpa_config_update_prio_list(wpa_s->conf);
1856 static int wpa_supplicant_ctrl_iface_get_network(
1857 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
1861 struct wpa_ssid *ssid;
1864 /* cmd: "<network id> <variable name>" */
1865 name = os_strchr(cmd, ' ');
1866 if (name == NULL || buflen == 0)
1871 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
1874 ssid = wpa_config_get_network(wpa_s->conf, id);
1876 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1881 value = wpa_config_get_no_key(ssid, name);
1882 if (value == NULL) {
1883 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network "
1884 "variable '%s'", name);
1888 res = os_strlcpy(buf, value, buflen);
1889 if (res >= buflen) {
1900 #ifndef CONFIG_NO_CONFIG_WRITE
1901 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s)
1905 if (!wpa_s->conf->update_config) {
1906 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
1907 "to update configuration (update_config=0)");
1911 ret = wpa_config_write(wpa_s->confname, wpa_s->conf);
1913 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to "
1914 "update configuration");
1916 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration"
1922 #endif /* CONFIG_NO_CONFIG_WRITE */
1925 static int ctrl_iface_get_capability_pairwise(int res, char *strict,
1926 struct wpa_driver_capa *capa,
1927 char *buf, size_t buflen)
1939 len = os_strlcpy(buf, "CCMP TKIP NONE", buflen);
1945 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1946 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " ");
1947 if (ret < 0 || ret >= end - pos)
1953 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1954 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " ");
1955 if (ret < 0 || ret >= end - pos)
1961 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1962 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : " ");
1963 if (ret < 0 || ret >= end - pos)
1973 static int ctrl_iface_get_capability_group(int res, char *strict,
1974 struct wpa_driver_capa *capa,
1975 char *buf, size_t buflen)
1987 len = os_strlcpy(buf, "CCMP TKIP WEP104 WEP40", buflen);
1993 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1994 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " ");
1995 if (ret < 0 || ret >= end - pos)
2001 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) {
2002 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " ");
2003 if (ret < 0 || ret >= end - pos)
2009 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP104) {
2010 ret = os_snprintf(pos, end - pos, "%sWEP104",
2012 if (ret < 0 || ret >= end - pos)
2018 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP40) {
2019 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : " ");
2020 if (ret < 0 || ret >= end - pos)
2030 static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
2031 struct wpa_driver_capa *capa,
2032 char *buf, size_t buflen)
2044 len = os_strlcpy(buf, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE "
2051 ret = os_snprintf(pos, end - pos, "NONE IEEE8021X");
2052 if (ret < 0 || ret >= end - pos)
2056 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
2057 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
2058 ret = os_snprintf(pos, end - pos, " WPA-EAP");
2059 if (ret < 0 || ret >= end - pos)
2064 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
2065 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
2066 ret = os_snprintf(pos, end - pos, " WPA-PSK");
2067 if (ret < 0 || ret >= end - pos)
2072 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
2073 ret = os_snprintf(pos, end - pos, " WPA-NONE");
2074 if (ret < 0 || ret >= end - pos)
2083 static int ctrl_iface_get_capability_proto(int res, char *strict,
2084 struct wpa_driver_capa *capa,
2085 char *buf, size_t buflen)
2097 len = os_strlcpy(buf, "RSN WPA", buflen);
2103 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
2104 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
2105 ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " ");
2106 if (ret < 0 || ret >= end - pos)
2112 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
2113 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
2114 ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " ");
2115 if (ret < 0 || ret >= end - pos)
2125 static int ctrl_iface_get_capability_auth_alg(int res, char *strict,
2126 struct wpa_driver_capa *capa,
2127 char *buf, size_t buflen)
2139 len = os_strlcpy(buf, "OPEN SHARED LEAP", buflen);
2145 if (capa->auth & (WPA_DRIVER_AUTH_OPEN)) {
2146 ret = os_snprintf(pos, end - pos, "%sOPEN", first ? "" : " ");
2147 if (ret < 0 || ret >= end - pos)
2153 if (capa->auth & (WPA_DRIVER_AUTH_SHARED)) {
2154 ret = os_snprintf(pos, end - pos, "%sSHARED",
2156 if (ret < 0 || ret >= end - pos)
2162 if (capa->auth & (WPA_DRIVER_AUTH_LEAP)) {
2163 ret = os_snprintf(pos, end - pos, "%sLEAP", first ? "" : " ");
2164 if (ret < 0 || ret >= end - pos)
2174 static int wpa_supplicant_ctrl_iface_get_capability(
2175 struct wpa_supplicant *wpa_s, const char *_field, char *buf,
2178 struct wpa_driver_capa capa;
2184 /* Determine whether or not strict checking was requested */
2185 len = os_strlcpy(field, _field, sizeof(field));
2186 if (len >= sizeof(field))
2188 strict = os_strchr(field, ' ');
2189 if (strict != NULL) {
2191 if (os_strcmp(strict, "strict") != 0)
2195 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
2196 field, strict ? strict : "");
2198 if (os_strcmp(field, "eap") == 0) {
2199 return eap_get_names(buf, buflen);
2202 res = wpa_drv_get_capa(wpa_s, &capa);
2204 if (os_strcmp(field, "pairwise") == 0)
2205 return ctrl_iface_get_capability_pairwise(res, strict, &capa,
2208 if (os_strcmp(field, "group") == 0)
2209 return ctrl_iface_get_capability_group(res, strict, &capa,
2212 if (os_strcmp(field, "key_mgmt") == 0)
2213 return ctrl_iface_get_capability_key_mgmt(res, strict, &capa,
2216 if (os_strcmp(field, "proto") == 0)
2217 return ctrl_iface_get_capability_proto(res, strict, &capa,
2220 if (os_strcmp(field, "auth_alg") == 0)
2221 return ctrl_iface_get_capability_auth_alg(res, strict, &capa,
2224 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
2231 #ifdef CONFIG_INTERWORKING
2232 static char * anqp_add_hex(char *pos, char *end, const char *title,
2233 struct wpabuf *data)
2243 ret = os_snprintf(pos, end - pos, "%s=", title);
2244 if (ret < 0 || ret >= end - pos)
2248 d = wpabuf_head_u8(data);
2249 for (i = 0; i < wpabuf_len(data); i++) {
2250 ret = os_snprintf(pos, end - pos, "%02x", *d++);
2251 if (ret < 0 || ret >= end - pos)
2256 ret = os_snprintf(pos, end - pos, "\n");
2257 if (ret < 0 || ret >= end - pos)
2263 #endif /* CONFIG_INTERWORKING */
2266 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
2267 const char *cmd, char *buf,
2272 struct wpa_bss *bss;
2278 if (os_strcmp(cmd, "FIRST") == 0)
2279 bss = dl_list_first(&wpa_s->bss, struct wpa_bss, list);
2280 else if (os_strncmp(cmd, "ID-", 3) == 0) {
2282 bss = wpa_bss_get_id(wpa_s, i);
2283 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) {
2285 bss = wpa_bss_get_id(wpa_s, i);
2287 struct dl_list *next = bss->list_id.next;
2288 if (next == &wpa_s->bss_id)
2291 bss = dl_list_entry(next, struct wpa_bss,
2295 } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) {
2296 if (hwaddr_aton(cmd + 13, bssid) == 0)
2297 bss = wpa_bss_get_p2p_dev_addr(wpa_s, bssid);
2300 #endif /* CONFIG_P2P */
2301 } else if (hwaddr_aton(cmd, bssid) == 0)
2302 bss = wpa_bss_get_bssid(wpa_s, bssid);
2304 struct wpa_bss *tmp;
2307 dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id)
2322 ret = os_snprintf(pos, end - pos,
2324 "bssid=" MACSTR "\n"
2327 "capabilities=0x%04x\n"
2335 MAC2STR(bss->bssid), bss->freq, bss->beacon_int,
2336 bss->caps, bss->qual, bss->noise, bss->level,
2337 (unsigned long long) bss->tsf,
2338 (int) (now.sec - bss->last_update.sec));
2339 if (ret < 0 || ret >= end - pos)
2343 ie = (const u8 *) (bss + 1);
2344 for (i = 0; i < bss->ie_len; i++) {
2345 ret = os_snprintf(pos, end - pos, "%02x", *ie++);
2346 if (ret < 0 || ret >= end - pos)
2351 ret = os_snprintf(pos, end - pos, "\n");
2352 if (ret < 0 || ret >= end - pos)
2356 ret = os_snprintf(pos, end - pos, "flags=");
2357 if (ret < 0 || ret >= end - pos)
2361 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
2363 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
2364 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
2366 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
2367 pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
2368 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
2369 ret = os_snprintf(pos, end - pos, "[WEP]");
2370 if (ret < 0 || ret >= end - pos)
2374 if (bss->caps & IEEE80211_CAP_IBSS) {
2375 ret = os_snprintf(pos, end - pos, "[IBSS]");
2376 if (ret < 0 || ret >= end - pos)
2380 if (bss->caps & IEEE80211_CAP_ESS) {
2381 ret = os_snprintf(pos, end - pos, "[ESS]");
2382 if (ret < 0 || ret >= end - pos)
2386 if (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE)) {
2387 ret = os_snprintf(pos, end - pos, "[P2P]");
2388 if (ret < 0 || ret >= end - pos)
2393 ret = os_snprintf(pos, end - pos, "\n");
2394 if (ret < 0 || ret >= end - pos)
2398 ret = os_snprintf(pos, end - pos, "ssid=%s\n",
2399 wpa_ssid_txt(bss->ssid, bss->ssid_len));
2400 if (ret < 0 || ret >= end - pos)
2405 ie = (const u8 *) (bss + 1);
2406 ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end);
2407 if (ret < 0 || ret >= end - pos)
2410 #endif /* CONFIG_WPS */
2413 ie = (const u8 *) (bss + 1);
2414 ret = wpas_p2p_scan_result_text(ie, bss->ie_len, pos, end);
2415 if (ret < 0 || ret >= end - pos)
2418 #endif /* CONFIG_P2P */
2420 #ifdef CONFIG_INTERWORKING
2421 pos = anqp_add_hex(pos, end, "anqp_venue_name", bss->anqp_venue_name);
2422 pos = anqp_add_hex(pos, end, "anqp_network_auth_type",
2423 bss->anqp_network_auth_type);
2424 pos = anqp_add_hex(pos, end, "anqp_roaming_consortium",
2425 bss->anqp_roaming_consortium);
2426 pos = anqp_add_hex(pos, end, "anqp_ip_addr_type_availability",
2427 bss->anqp_ip_addr_type_availability);
2428 pos = anqp_add_hex(pos, end, "anqp_nai_realm", bss->anqp_nai_realm);
2429 pos = anqp_add_hex(pos, end, "anqp_3gpp", bss->anqp_3gpp);
2430 pos = anqp_add_hex(pos, end, "anqp_domain_name",
2431 bss->anqp_domain_name);
2432 #endif /* CONFIG_INTERWORKING */
2438 static int wpa_supplicant_ctrl_iface_ap_scan(
2439 struct wpa_supplicant *wpa_s, char *cmd)
2441 int ap_scan = atoi(cmd);
2442 return wpa_supplicant_set_ap_scan(wpa_s, ap_scan);
2446 static int wpa_supplicant_ctrl_iface_scan_interval(
2447 struct wpa_supplicant *wpa_s, char *cmd)
2449 int scan_int = atoi(cmd);
2452 wpa_s->scan_interval = scan_int;
2457 static int wpa_supplicant_ctrl_iface_bss_expire_age(
2458 struct wpa_supplicant *wpa_s, char *cmd)
2460 int expire_age = atoi(cmd);
2461 return wpa_supplicant_set_bss_expiration_age(wpa_s, expire_age);
2465 static int wpa_supplicant_ctrl_iface_bss_expire_count(
2466 struct wpa_supplicant *wpa_s, char *cmd)
2468 int expire_count = atoi(cmd);
2469 return wpa_supplicant_set_bss_expiration_count(wpa_s, expire_count);
2473 static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s)
2475 wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication");
2476 /* MLME-DELETEKEYS.request */
2477 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0);
2478 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0);
2479 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0);
2480 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0);
2481 #ifdef CONFIG_IEEE80211W
2482 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0);
2483 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0);
2484 #endif /* CONFIG_IEEE80211W */
2486 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, wpa_s->bssid, 0, 0, NULL, 0, NULL,
2488 /* MLME-SETPROTECTION.request(None) */
2489 wpa_drv_mlme_setprotection(wpa_s, wpa_s->bssid,
2490 MLME_SETPROTECTION_PROTECT_TYPE_NONE,
2491 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
2492 wpa_sm_drop_sa(wpa_s->wpa);
2496 static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s,
2499 #ifdef CONFIG_NO_SCAN_PROCESSING
2501 #else /* CONFIG_NO_SCAN_PROCESSING */
2503 struct wpa_bss *bss;
2504 struct wpa_ssid *ssid = wpa_s->current_ssid;
2506 if (hwaddr_aton(addr, bssid)) {
2507 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid "
2508 "address '%s'", addr);
2512 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM " MACSTR, MAC2STR(bssid));
2514 bss = wpa_bss_get_bssid(wpa_s, bssid);
2516 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: Target AP not found "
2522 * TODO: Find best network configuration block from configuration to
2523 * allow roaming to other networks
2527 wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: No network "
2528 "configuration known for the target AP");
2532 wpa_s->reassociate = 1;
2533 wpa_supplicant_connect(wpa_s, bss, ssid);
2536 #endif /* CONFIG_NO_SCAN_PROCESSING */
2541 static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
2543 unsigned int timeout = atoi(cmd);
2544 enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL;
2545 u8 dev_id[ETH_ALEN], *_dev_id = NULL;
2548 if (os_strstr(cmd, "type=social"))
2549 type = P2P_FIND_ONLY_SOCIAL;
2550 else if (os_strstr(cmd, "type=progressive"))
2551 type = P2P_FIND_PROGRESSIVE;
2553 pos = os_strstr(cmd, "dev_id=");
2556 if (hwaddr_aton(pos, dev_id))
2561 return wpas_p2p_find(wpa_s, timeout, type, 0, NULL, _dev_id);
2565 static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
2566 char *buf, size_t buflen)
2571 enum p2p_wps_method wps_method;
2574 int persistent_group;
2580 /* <addr> <"pbc" | "pin" | PIN> [label|display|keypad] [persistent]
2581 * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] */
2583 if (hwaddr_aton(cmd, addr))
2591 persistent_group = os_strstr(pos, " persistent") != NULL;
2592 join = os_strstr(pos, " join") != NULL;
2593 auth = os_strstr(pos, " auth") != NULL;
2595 pos2 = os_strstr(pos, " go_intent=");
2598 go_intent = atoi(pos2);
2599 if (go_intent < 0 || go_intent > 15)
2603 pos2 = os_strstr(pos, " freq=");
2611 if (os_strncmp(pos, "pin", 3) == 0) {
2612 /* Request random PIN (to be displayed) and enable the PIN */
2613 wps_method = WPS_PIN_DISPLAY;
2614 } else if (os_strncmp(pos, "pbc", 3) == 0) {
2615 wps_method = WPS_PBC;
2618 pos = os_strchr(pin, ' ');
2619 wps_method = WPS_PIN_KEYPAD;
2622 if (os_strncmp(pos, "display", 7) == 0)
2623 wps_method = WPS_PIN_DISPLAY;
2627 new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
2628 persistent_group, join, auth, go_intent,
2630 if (new_pin == -2) {
2631 os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25);
2634 if (new_pin == -3) {
2635 os_memcpy(buf, "FAIL-CHANNEL-UNSUPPORTED\n", 25);
2640 if (wps_method == WPS_PIN_DISPLAY && pin == NULL) {
2641 ret = os_snprintf(buf, buflen, "%08d", new_pin);
2642 if (ret < 0 || (size_t) ret >= buflen)
2647 os_memcpy(buf, "OK\n", 3);
2652 static int p2p_ctrl_listen(struct wpa_supplicant *wpa_s, char *cmd)
2654 unsigned int timeout = atoi(cmd);
2655 return wpas_p2p_listen(wpa_s, timeout);
2659 static int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd)
2664 /* <addr> <config method> [join] */
2666 if (hwaddr_aton(cmd, addr))
2674 return wpas_p2p_prov_disc(wpa_s, addr, pos,
2675 os_strstr(pos, "join") != NULL);
2679 static int p2p_get_passphrase(struct wpa_supplicant *wpa_s, char *buf,
2682 struct wpa_ssid *ssid = wpa_s->current_ssid;
2684 if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
2685 ssid->passphrase == NULL)
2688 os_strlcpy(buf, ssid->passphrase, buflen);
2689 return os_strlen(buf);
2693 static int p2p_ctrl_serv_disc_req(struct wpa_supplicant *wpa_s, char *cmd,
2694 char *buf, size_t buflen)
2698 u8 dst_buf[ETH_ALEN], *dst;
2699 struct wpabuf *tlvs;
2703 if (hwaddr_aton(cmd, dst_buf))
2706 if (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 &&
2707 dst[3] == 0 && dst[4] == 0 && dst[5] == 0)
2714 if (os_strncmp(pos, "upnp ", 5) == 0) {
2717 if (hexstr2bin(pos, &version, 1) < 0)
2723 ref = wpas_p2p_sd_request_upnp(wpa_s, dst, version, pos);
2725 len = os_strlen(pos);
2729 tlvs = wpabuf_alloc(len);
2732 if (hexstr2bin(pos, wpabuf_put(tlvs, len), len) < 0) {
2737 ref = wpas_p2p_sd_request(wpa_s, dst, tlvs);
2742 res = os_snprintf(buf, buflen, "%llx", (long long unsigned) ref);
2743 if (res < 0 || (unsigned) res >= buflen)
2749 static int p2p_ctrl_serv_disc_cancel_req(struct wpa_supplicant *wpa_s,
2752 long long unsigned val;
2754 if (sscanf(cmd, "%llx", &val) != 1)
2757 return wpas_p2p_sd_cancel_request(wpa_s, req);
2761 static int p2p_ctrl_serv_disc_resp(struct wpa_supplicant *wpa_s, char *cmd)
2766 struct wpabuf *resp_tlvs;
2770 pos = os_strchr(cmd, ' ');
2778 if (hwaddr_aton(pos, dst))
2785 pos2 = os_strchr(pos, ' ');
2789 dialog_token = atoi(pos);
2791 len = os_strlen(pos2);
2795 resp_tlvs = wpabuf_alloc(len);
2796 if (resp_tlvs == NULL)
2798 if (hexstr2bin(pos2, wpabuf_put(resp_tlvs, len), len) < 0) {
2799 wpabuf_free(resp_tlvs);
2803 wpas_p2p_sd_response(wpa_s, freq, dst, dialog_token, resp_tlvs);
2804 wpabuf_free(resp_tlvs);
2809 static int p2p_ctrl_serv_disc_external(struct wpa_supplicant *wpa_s,
2812 wpa_s->p2p_sd_over_ctrl_iface = atoi(cmd);
2817 static int p2p_ctrl_service_add_bonjour(struct wpa_supplicant *wpa_s,
2822 struct wpabuf *query, *resp;
2824 pos = os_strchr(cmd, ' ');
2829 len = os_strlen(cmd);
2833 query = wpabuf_alloc(len);
2836 if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) {
2841 len = os_strlen(pos);
2847 resp = wpabuf_alloc(len);
2852 if (hexstr2bin(pos, wpabuf_put(resp, len), len) < 0) {
2858 if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0) {
2867 static int p2p_ctrl_service_add_upnp(struct wpa_supplicant *wpa_s, char *cmd)
2872 pos = os_strchr(cmd, ' ');
2877 if (hexstr2bin(cmd, &version, 1) < 0)
2880 return wpas_p2p_service_add_upnp(wpa_s, version, pos);
2884 static int p2p_ctrl_service_add(struct wpa_supplicant *wpa_s, char *cmd)
2888 pos = os_strchr(cmd, ' ');
2893 if (os_strcmp(cmd, "bonjour") == 0)
2894 return p2p_ctrl_service_add_bonjour(wpa_s, pos);
2895 if (os_strcmp(cmd, "upnp") == 0)
2896 return p2p_ctrl_service_add_upnp(wpa_s, pos);
2897 wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd);
2902 static int p2p_ctrl_service_del_bonjour(struct wpa_supplicant *wpa_s,
2906 struct wpabuf *query;
2909 len = os_strlen(cmd);
2913 query = wpabuf_alloc(len);
2916 if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) {
2921 ret = wpas_p2p_service_del_bonjour(wpa_s, query);
2927 static int p2p_ctrl_service_del_upnp(struct wpa_supplicant *wpa_s, char *cmd)
2932 pos = os_strchr(cmd, ' ');
2937 if (hexstr2bin(cmd, &version, 1) < 0)
2940 return wpas_p2p_service_del_upnp(wpa_s, version, pos);
2944 static int p2p_ctrl_service_del(struct wpa_supplicant *wpa_s, char *cmd)
2948 pos = os_strchr(cmd, ' ');
2953 if (os_strcmp(cmd, "bonjour") == 0)
2954 return p2p_ctrl_service_del_bonjour(wpa_s, pos);
2955 if (os_strcmp(cmd, "upnp") == 0)
2956 return p2p_ctrl_service_del_upnp(wpa_s, pos);
2957 wpa_printf(MSG_DEBUG, "Unknown service '%s'", cmd);
2962 static int p2p_ctrl_reject(struct wpa_supplicant *wpa_s, char *cmd)
2968 if (hwaddr_aton(cmd, addr))
2971 return wpas_p2p_reject(wpa_s, addr);
2975 static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
2979 struct wpa_ssid *ssid;
2983 pos = os_strstr(cmd, " peer=");
2986 if (hwaddr_aton(pos, peer))
2989 ssid = wpa_config_get_network(wpa_s->conf, id);
2990 if (ssid == NULL || ssid->disabled != 2) {
2991 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
2992 "for persistent P2P group",
2997 return wpas_p2p_invite(wpa_s, pos ? peer : NULL, ssid, NULL);
3001 static int p2p_ctrl_invite_group(struct wpa_supplicant *wpa_s, char *cmd)
3004 u8 peer[ETH_ALEN], go_dev_addr[ETH_ALEN], *go_dev = NULL;
3006 pos = os_strstr(cmd, " peer=");
3012 if (hwaddr_aton(pos, peer)) {
3013 wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'", pos);
3017 pos = os_strstr(pos, " go_dev_addr=");
3020 if (hwaddr_aton(pos, go_dev_addr)) {
3021 wpa_printf(MSG_DEBUG, "P2P: Invalid MAC address '%s'",
3025 go_dev = go_dev_addr;
3028 return wpas_p2p_invite_group(wpa_s, cmd, peer, go_dev);
3032 static int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd)
3034 if (os_strncmp(cmd, "persistent=", 11) == 0)
3035 return p2p_ctrl_invite_persistent(wpa_s, cmd + 11);
3036 if (os_strncmp(cmd, "group=", 6) == 0)
3037 return p2p_ctrl_invite_group(wpa_s, cmd + 6);
3043 static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
3044 char *cmd, int freq)
3047 struct wpa_ssid *ssid;
3050 ssid = wpa_config_get_network(wpa_s->conf, id);
3051 if (ssid == NULL || ssid->disabled != 2) {
3052 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
3053 "for persistent P2P group",
3058 return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq);
3062 static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
3067 pos = os_strstr(cmd, "freq=");
3069 freq = atoi(pos + 5);
3071 if (os_strncmp(cmd, "persistent=", 11) == 0)
3072 return p2p_ctrl_group_add_persistent(wpa_s, cmd + 11, freq);
3073 if (os_strcmp(cmd, "persistent") == 0 ||
3074 os_strncmp(cmd, "persistent ", 11) == 0)
3075 return wpas_p2p_group_add(wpa_s, 1, freq);
3076 if (os_strncmp(cmd, "freq=", 5) == 0)
3077 return wpas_p2p_group_add(wpa_s, 0, freq);
3079 wpa_printf(MSG_DEBUG, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'",
3085 static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
3086 char *buf, size_t buflen)
3088 u8 addr[ETH_ALEN], *addr_ptr;
3090 const struct p2p_peer_info *info;
3092 char devtype[WPS_DEV_TYPE_BUFSIZE];
3093 struct wpa_ssid *ssid;
3095 if (!wpa_s->global->p2p)
3098 if (os_strcmp(cmd, "FIRST") == 0) {
3101 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) {
3102 if (hwaddr_aton(cmd + 5, addr) < 0)
3107 if (hwaddr_aton(cmd, addr) < 0)
3113 info = p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next);
3120 res = os_snprintf(pos, end - pos, MACSTR "\n"
3126 "serial_number=%s\n"
3127 "config_methods=0x%x\n"
3129 "group_capab=0x%x\n"
3131 MAC2STR(info->p2p_device_addr),
3132 wps_dev_type_bin2str(info->pri_dev_type,
3133 devtype, sizeof(devtype)),
3138 info->serial_number,
3139 info->config_methods,
3143 if (res < 0 || res >= end - pos)
3147 ssid = wpas_p2p_get_persistent(wpa_s, info->p2p_device_addr, NULL, 0);
3149 res = os_snprintf(pos, end - pos, "persistent=%d\n", ssid->id);
3150 if (res < 0 || res >= end - pos)
3155 res = p2p_get_peer_info_txt(info, pos, end - pos);
3164 static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
3168 if (wpa_s->global->p2p == NULL)
3171 param = os_strchr(cmd, ' ');
3176 if (os_strcmp(cmd, "discoverability") == 0) {
3177 p2p_set_client_discoverability(wpa_s->global->p2p,
3182 if (os_strcmp(cmd, "managed") == 0) {
3183 p2p_set_managed_oper(wpa_s->global->p2p, atoi(param));
3187 if (os_strcmp(cmd, "listen_channel") == 0) {
3188 return p2p_set_listen_channel(wpa_s->global->p2p, 81,
3192 if (os_strcmp(cmd, "ssid_postfix") == 0) {
3193 return p2p_set_ssid_postfix(wpa_s->global->p2p, (u8 *) param,
3197 if (os_strcmp(cmd, "noa") == 0) {
3199 int count, start, duration;
3200 /* GO NoA parameters: count,start_offset(ms),duration(ms) */
3201 count = atoi(param);
3202 pos = os_strchr(param, ',');
3207 pos = os_strchr(pos, ',');
3211 duration = atoi(pos);
3212 if (count < 0 || count > 255 || start < 0 || duration < 0)
3214 if (count == 0 && duration > 0)
3216 wpa_printf(MSG_DEBUG, "CTRL_IFACE: P2P_SET GO NoA: count=%d "
3217 "start=%d duration=%d", count, start, duration);
3218 return wpas_p2p_set_noa(wpa_s, count, start, duration);
3221 if (os_strcmp(cmd, "ps") == 0)
3222 return wpa_drv_set_p2p_powersave(wpa_s, atoi(param), -1, -1);
3224 if (os_strcmp(cmd, "oppps") == 0)
3225 return wpa_drv_set_p2p_powersave(wpa_s, -1, atoi(param), -1);
3227 if (os_strcmp(cmd, "ctwindow") == 0)
3228 return wpa_drv_set_p2p_powersave(wpa_s, -1, -1, atoi(param));
3230 if (os_strcmp(cmd, "disabled") == 0) {
3231 wpa_s->global->p2p_disabled = atoi(param);
3232 wpa_printf(MSG_DEBUG, "P2P functionality %s",
3233 wpa_s->global->p2p_disabled ?
3234 "disabled" : "enabled");
3235 if (wpa_s->global->p2p_disabled) {
3236 wpas_p2p_stop_find(wpa_s);
3237 os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
3238 p2p_flush(wpa_s->global->p2p);
3243 if (os_strcmp(cmd, "force_long_sd") == 0) {
3244 wpa_s->force_long_sd = atoi(param);
3248 if (os_strcmp(cmd, "peer_filter") == 0) {
3250 if (hwaddr_aton(param, addr))
3252 p2p_set_peer_filter(wpa_s->global->p2p, addr);
3256 if (os_strcmp(cmd, "cross_connect") == 0)
3257 return wpas_p2p_set_cross_connect(wpa_s, atoi(param));
3259 if (os_strcmp(cmd, "go_apsd") == 0) {
3260 if (os_strcmp(param, "disable") == 0)
3261 wpa_s->set_ap_uapsd = 0;
3263 wpa_s->set_ap_uapsd = 1;
3264 wpa_s->ap_uapsd = atoi(param);
3269 if (os_strcmp(cmd, "client_apsd") == 0) {
3270 if (os_strcmp(param, "disable") == 0)
3271 wpa_s->set_sta_uapsd = 0;
3275 /* format: BE,BK,VI,VO;max SP Length */
3277 pos = os_strchr(param, ',');
3282 pos = os_strchr(pos, ',');
3287 pos = os_strchr(pos, ',');
3292 /* ignore max SP Length for now */
3294 wpa_s->set_sta_uapsd = 1;
3295 wpa_s->sta_uapsd = 0;
3297 wpa_s->sta_uapsd |= BIT(0);
3299 wpa_s->sta_uapsd |= BIT(1);
3301 wpa_s->sta_uapsd |= BIT(2);
3303 wpa_s->sta_uapsd |= BIT(3);
3308 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
3315 static int p2p_ctrl_presence_req(struct wpa_supplicant *wpa_s, char *cmd)
3318 unsigned int dur1 = 0, int1 = 0, dur2 = 0, int2 = 0;
3321 pos = os_strchr(cmd, ' ');
3327 pos2 = os_strchr(pos, ' ');
3335 pos = os_strchr(pos2, ' ');
3343 return wpas_p2p_presence_req(wpa_s, dur1, int1, dur2, int2);
3347 static int p2p_ctrl_ext_listen(struct wpa_supplicant *wpa_s, char *cmd)
3350 unsigned int period = 0, interval = 0;
3353 pos = os_strchr(cmd, ' ');
3358 interval = atoi(pos);
3361 return wpas_p2p_ext_listen(wpa_s, period, interval);
3364 #endif /* CONFIG_P2P */
3367 #ifdef CONFIG_INTERWORKING
3368 static int ctrl_interworking_connect(struct wpa_supplicant *wpa_s, char *dst)
3371 struct wpa_bss *bss;
3373 if (hwaddr_aton(dst, bssid)) {
3374 wpa_printf(MSG_DEBUG, "Invalid BSSID '%s'", dst);
3378 bss = wpa_bss_get_bssid(wpa_s, bssid);
3380 wpa_printf(MSG_DEBUG, "Could not find BSS " MACSTR,
3385 return interworking_connect(wpa_s, bss);
3389 static int get_anqp(struct wpa_supplicant *wpa_s, char *dst)
3391 u8 dst_addr[ETH_ALEN];
3394 #define MAX_ANQP_INFO_ID 100
3395 u16 id[MAX_ANQP_INFO_ID];
3398 used = hwaddr_aton2(dst, dst_addr);
3402 while (num_id < MAX_ANQP_INFO_ID) {
3403 id[num_id] = atoi(pos);
3406 pos = os_strchr(pos + 1, ',');
3415 return anqp_send_req(wpa_s, dst_addr, id, num_id);
3417 #endif /* CONFIG_INTERWORKING */
3420 static int wpa_supplicant_ctrl_iface_sta_autoconnect(
3421 struct wpa_supplicant *wpa_s, char *cmd)
3423 wpa_s->auto_reconnect_disabled = atoi(cmd) == 0 ? 1 : 0;
3428 static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf,
3431 struct wpa_signal_info si;
3434 ret = wpa_drv_signal_poll(wpa_s, &si);
3438 ret = os_snprintf(buf, buflen, "RSSI=%d\nLINKSPEED=%d\n"
3439 "NOISE=%d\nFREQUENCY=%u\n",
3440 si.current_signal, si.current_txrate / 1000,
3441 si.current_noise, si.frequency);
3442 if (ret < 0 || (unsigned int) ret > buflen)
3448 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
3449 char *buf, size_t *resp_len)
3452 const int reply_size = 4096;
3456 if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 ||
3457 os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
3458 wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface",
3459 (const u8 *) buf, os_strlen(buf));
3461 int level = MSG_DEBUG;
3462 if (os_strcmp(buf, "PING") == 0)
3463 level = MSG_EXCESSIVE;
3464 wpa_hexdump_ascii(level, "RX ctrl_iface",
3465 (const u8 *) buf, os_strlen(buf));
3468 reply = os_malloc(reply_size);
3469 if (reply == NULL) {
3474 os_memcpy(reply, "OK\n", 3);
3477 if (os_strcmp(buf, "PING") == 0) {
3478 os_memcpy(reply, "PONG\n", 5);
3480 } else if (os_strncmp(buf, "RELOG", 5) == 0) {
3481 if (wpa_debug_reopen_file() < 0)
3483 } else if (os_strncmp(buf, "NOTE ", 5) == 0) {
3484 wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
3485 } else if (os_strcmp(buf, "MIB") == 0) {
3486 reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
3487 if (reply_len >= 0) {
3489 res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len,
3490 reply_size - reply_len);
3496 } else if (os_strncmp(buf, "STATUS", 6) == 0) {
3497 reply_len = wpa_supplicant_ctrl_iface_status(
3498 wpa_s, buf + 6, reply, reply_size);
3499 } else if (os_strcmp(buf, "PMKSA") == 0) {
3500 reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, reply,
3502 } else if (os_strncmp(buf, "SET ", 4) == 0) {
3503 if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4))
3505 } else if (os_strncmp(buf, "GET ", 4) == 0) {
3506 reply_len = wpa_supplicant_ctrl_iface_get(wpa_s, buf + 4,
3508 } else if (os_strcmp(buf, "LOGON") == 0) {
3509 eapol_sm_notify_logoff(wpa_s->eapol, FALSE);
3510 } else if (os_strcmp(buf, "LOGOFF") == 0) {
3511 eapol_sm_notify_logoff(wpa_s->eapol, TRUE);
3512 } else if (os_strcmp(buf, "REASSOCIATE") == 0) {
3513 wpa_s->normal_scans = 0;
3514 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
3517 wpa_s->disconnected = 0;
3518 wpa_s->reassociate = 1;
3519 wpa_supplicant_req_scan(wpa_s, 0, 0);
3521 } else if (os_strcmp(buf, "RECONNECT") == 0) {
3522 wpa_s->normal_scans = 0;
3523 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
3525 else if (wpa_s->disconnected) {
3526 wpa_s->disconnected = 0;
3527 wpa_s->reassociate = 1;
3528 wpa_supplicant_req_scan(wpa_s, 0, 0);
3530 #ifdef IEEE8021X_EAPOL
3531 } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) {
3532 if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8))
3534 #endif /* IEEE8021X_EAPOL */
3535 #ifdef CONFIG_PEERKEY
3536 } else if (os_strncmp(buf, "STKSTART ", 9) == 0) {
3537 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9))
3539 #endif /* CONFIG_PEERKEY */
3540 #ifdef CONFIG_IEEE80211R
3541 } else if (os_strncmp(buf, "FT_DS ", 6) == 0) {
3542 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6))
3544 #endif /* CONFIG_IEEE80211R */
3546 } else if (os_strcmp(buf, "WPS_PBC") == 0) {
3547 int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, NULL);
3549 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17);
3553 } else if (os_strncmp(buf, "WPS_PBC ", 8) == 0) {
3554 int res = wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, buf + 8);
3556 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17);
3560 } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
3561 reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8,
3564 } else if (os_strncmp(buf, "WPS_CHECK_PIN ", 14) == 0) {
3565 reply_len = wpa_supplicant_ctrl_iface_wps_check_pin(
3566 wpa_s, buf + 14, reply, reply_size);
3567 } else if (os_strcmp(buf, "WPS_CANCEL") == 0) {
3568 if (wpas_wps_cancel(wpa_s))
3570 #ifdef CONFIG_WPS_OOB
3571 } else if (os_strncmp(buf, "WPS_OOB ", 8) == 0) {
3572 if (wpa_supplicant_ctrl_iface_wps_oob(wpa_s, buf + 8))
3574 #endif /* CONFIG_WPS_OOB */
3575 } else if (os_strncmp(buf, "WPS_REG ", 8) == 0) {
3576 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8))
3579 } else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) {
3580 reply_len = wpa_supplicant_ctrl_iface_wps_ap_pin(
3581 wpa_s, buf + 11, reply, reply_size);
3582 #endif /* CONFIG_AP */
3583 #ifdef CONFIG_WPS_ER
3584 } else if (os_strcmp(buf, "WPS_ER_START") == 0) {
3585 if (wpas_wps_er_start(wpa_s, NULL))
3587 } else if (os_strncmp(buf, "WPS_ER_START ", 13) == 0) {
3588 if (wpas_wps_er_start(wpa_s, buf + 13))
3590 } else if (os_strcmp(buf, "WPS_ER_STOP") == 0) {
3591 if (wpas_wps_er_stop(wpa_s))
3593 } else if (os_strncmp(buf, "WPS_ER_PIN ", 11) == 0) {
3594 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s, buf + 11))
3596 } else if (os_strncmp(buf, "WPS_ER_PBC ", 11) == 0) {
3597 int ret = wpas_wps_er_pbc(wpa_s, buf + 11);
3599 os_memcpy(reply, "FAIL-PBC-OVERLAP\n", 17);
3601 } else if (ret == -3) {
3602 os_memcpy(reply, "FAIL-UNKNOWN-UUID\n", 18);
3604 } else if (ret == -4) {
3605 os_memcpy(reply, "FAIL-NO-AP-SETTINGS\n", 20);
3609 } else if (os_strncmp(buf, "WPS_ER_LEARN ", 13) == 0) {
3610 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s, buf + 13))
3612 } else if (os_strncmp(buf, "WPS_ER_SET_CONFIG ", 18) == 0) {
3613 if (wpa_supplicant_ctrl_iface_wps_er_set_config(wpa_s,
3616 } else if (os_strncmp(buf, "WPS_ER_CONFIG ", 14) == 0) {
3617 if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s, buf + 14))
3619 #endif /* CONFIG_WPS_ER */
3620 #endif /* CONFIG_WPS */
3621 #ifdef CONFIG_IBSS_RSN
3622 } else if (os_strncmp(buf, "IBSS_RSN ", 9) == 0) {
3623 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s, buf + 9))
3625 #endif /* CONFIG_IBSS_RSN */
3627 } else if (os_strncmp(buf, "P2P_FIND ", 9) == 0) {
3628 if (p2p_ctrl_find(wpa_s, buf + 9))
3630 } else if (os_strcmp(buf, "P2P_FIND") == 0) {
3631 if (p2p_ctrl_find(wpa_s, ""))
3633 } else if (os_strcmp(buf, "P2P_STOP_FIND") == 0) {
3634 wpas_p2p_stop_find(wpa_s);
3635 } else if (os_strncmp(buf, "P2P_CONNECT ", 12) == 0) {
3636 reply_len = p2p_ctrl_connect(wpa_s, buf + 12, reply,
3638 } else if (os_strncmp(buf, "P2P_LISTEN ", 11) == 0) {
3639 if (p2p_ctrl_listen(wpa_s, buf + 11))
3641 } else if (os_strcmp(buf, "P2P_LISTEN") == 0) {
3642 if (p2p_ctrl_listen(wpa_s, ""))
3644 } else if (os_strncmp(buf, "P2P_GROUP_REMOVE ", 17) == 0) {
3645 if (wpas_p2p_group_remove(wpa_s, buf + 17))
3647 } else if (os_strcmp(buf, "P2P_GROUP_ADD") == 0) {
3648 if (wpas_p2p_group_add(wpa_s, 0, 0))
3650 } else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) {
3651 if (p2p_ctrl_group_add(wpa_s, buf + 14))
3653 } else if (os_strncmp(buf, "P2P_PROV_DISC ", 14) == 0) {
3654 if (p2p_ctrl_prov_disc(wpa_s, buf + 14))
3656 } else if (os_strcmp(buf, "P2P_GET_PASSPHRASE") == 0) {
3657 reply_len = p2p_get_passphrase(wpa_s, reply, reply_size);
3658 } else if (os_strncmp(buf, "P2P_SERV_DISC_REQ ", 18) == 0) {
3659 reply_len = p2p_ctrl_serv_disc_req(wpa_s, buf + 18, reply,
3661 } else if (os_strncmp(buf, "P2P_SERV_DISC_CANCEL_REQ ", 25) == 0) {
3662 if (p2p_ctrl_serv_disc_cancel_req(wpa_s, buf + 25) < 0)
3664 } else if (os_strncmp(buf, "P2P_SERV_DISC_RESP ", 19) == 0) {
3665 if (p2p_ctrl_serv_disc_resp(wpa_s, buf + 19) < 0)
3667 } else if (os_strcmp(buf, "P2P_SERVICE_UPDATE") == 0) {
3668 wpas_p2p_sd_service_update(wpa_s);
3669 } else if (os_strncmp(buf, "P2P_SERV_DISC_EXTERNAL ", 23) == 0) {
3670 if (p2p_ctrl_serv_disc_external(wpa_s, buf + 23) < 0)
3672 } else if (os_strcmp(buf, "P2P_SERVICE_FLUSH") == 0) {
3673 wpas_p2p_service_flush(wpa_s);
3674 } else if (os_strncmp(buf, "P2P_SERVICE_ADD ", 16) == 0) {
3675 if (p2p_ctrl_service_add(wpa_s, buf + 16) < 0)
3677 } else if (os_strncmp(buf, "P2P_SERVICE_DEL ", 16) == 0) {
3678 if (p2p_ctrl_service_del(wpa_s, buf + 16) < 0)
3680 } else if (os_strncmp(buf, "P2P_REJECT ", 11) == 0) {
3681 if (p2p_ctrl_reject(wpa_s, buf + 11) < 0)
3683 } else if (os_strncmp(buf, "P2P_INVITE ", 11) == 0) {
3684 if (p2p_ctrl_invite(wpa_s, buf + 11) < 0)
3686 } else if (os_strncmp(buf, "P2P_PEER ", 9) == 0) {
3687 reply_len = p2p_ctrl_peer(wpa_s, buf + 9, reply,
3689 } else if (os_strncmp(buf, "P2P_SET ", 8) == 0) {
3690 if (p2p_ctrl_set(wpa_s, buf + 8) < 0)
3692 } else if (os_strcmp(buf, "P2P_FLUSH") == 0) {
3693 os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
3694 wpa_s->force_long_sd = 0;
3695 if (wpa_s->global->p2p)
3696 p2p_flush(wpa_s->global->p2p);
3697 } else if (os_strncmp(buf, "P2P_UNAUTHORIZE ", 16) == 0) {
3698 if (wpas_p2p_unauthorize(wpa_s, buf + 16) < 0)
3700 } else if (os_strcmp(buf, "P2P_CANCEL") == 0) {
3701 if (wpas_p2p_cancel(wpa_s))
3703 } else if (os_strncmp(buf, "P2P_PRESENCE_REQ ", 17) == 0) {
3704 if (p2p_ctrl_presence_req(wpa_s, buf + 17) < 0)
3706 } else if (os_strcmp(buf, "P2P_PRESENCE_REQ") == 0) {
3707 if (p2p_ctrl_presence_req(wpa_s, "") < 0)
3709 } else if (os_strncmp(buf, "P2P_EXT_LISTEN ", 15) == 0) {
3710 if (p2p_ctrl_ext_listen(wpa_s, buf + 15) < 0)
3712 } else if (os_strcmp(buf, "P2P_EXT_LISTEN") == 0) {
3713 if (p2p_ctrl_ext_listen(wpa_s, "") < 0)
3715 #endif /* CONFIG_P2P */
3716 #ifdef CONFIG_INTERWORKING
3717 } else if (os_strcmp(buf, "FETCH_ANQP") == 0) {
3718 if (interworking_fetch_anqp(wpa_s) < 0)
3720 } else if (os_strcmp(buf, "STOP_FETCH_ANQP") == 0) {
3721 interworking_stop_fetch_anqp(wpa_s);
3722 } else if (os_strncmp(buf, "INTERWORKING_SELECT", 19) == 0) {
3723 if (interworking_select(wpa_s, os_strstr(buf + 19, "auto") !=
3726 } else if (os_strncmp(buf, "INTERWORKING_CONNECT ", 21) == 0) {
3727 if (ctrl_interworking_connect(wpa_s, buf + 21) < 0)
3729 } else if (os_strncmp(buf, "ANQP_GET ", 9) == 0) {
3730 if (get_anqp(wpa_s, buf + 9) < 0)
3732 #endif /* CONFIG_INTERWORKING */
3733 } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0)
3735 if (wpa_supplicant_ctrl_iface_ctrl_rsp(
3736 wpa_s, buf + os_strlen(WPA_CTRL_RSP)))
3740 } else if (os_strcmp(buf, "RECONFIGURE") == 0) {
3741 if (wpa_supplicant_reload_configuration(wpa_s))
3743 } else if (os_strcmp(buf, "TERMINATE") == 0) {
3744 wpa_supplicant_terminate_proc(wpa_s->global);
3745 } else if (os_strncmp(buf, "BSSID ", 6) == 0) {
3746 if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6))
3748 } else if (os_strncmp(buf, "BLACKLIST", 9) == 0) {
3749 reply_len = wpa_supplicant_ctrl_iface_blacklist(
3750 wpa_s, buf + 9, reply, reply_size);
3751 } else if (os_strncmp(buf, "LOG_LEVEL", 9) == 0) {
3752 reply_len = wpa_supplicant_ctrl_iface_log_level(
3753 wpa_s, buf + 9, reply, reply_size);
3754 } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) {
3755 reply_len = wpa_supplicant_ctrl_iface_list_networks(
3756 wpa_s, reply, reply_size);
3757 } else if (os_strcmp(buf, "DISCONNECT") == 0) {
3758 wpa_s->reassociate = 0;
3759 wpa_s->disconnected = 1;
3760 wpa_supplicant_cancel_sched_scan(wpa_s);
3761 wpa_supplicant_deauthenticate(wpa_s,
3762 WLAN_REASON_DEAUTH_LEAVING);
3763 } else if (os_strcmp(buf, "SCAN") == 0) {
3764 wpa_s->normal_scans = 0;
3765 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
3768 if (!wpa_s->scanning &&
3769 ((wpa_s->wpa_state <= WPA_SCANNING) ||
3770 (wpa_s->wpa_state == WPA_COMPLETED))) {
3771 wpa_s->scan_req = 2;
3772 wpa_supplicant_req_scan(wpa_s, 0, 0);
3774 wpa_printf(MSG_DEBUG, "Ongoing scan action - "
3775 "reject new request");
3776 reply_len = os_snprintf(reply, reply_size,
3780 } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) {
3781 reply_len = wpa_supplicant_ctrl_iface_scan_results(
3782 wpa_s, reply, reply_size);
3783 } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) {
3784 if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15))
3786 } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) {
3787 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15))
3789 } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) {
3790 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16))
3792 } else if (os_strcmp(buf, "ADD_NETWORK") == 0) {
3793 reply_len = wpa_supplicant_ctrl_iface_add_network(
3794 wpa_s, reply, reply_size);
3795 } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) {
3796 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15))
3798 } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
3799 if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12))
3801 } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
3802 reply_len = wpa_supplicant_ctrl_iface_get_network(
3803 wpa_s, buf + 12, reply, reply_size);
3804 #ifndef CONFIG_NO_CONFIG_WRITE
3805 } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
3806 if (wpa_supplicant_ctrl_iface_save_config(wpa_s))
3808 #endif /* CONFIG_NO_CONFIG_WRITE */
3809 } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
3810 reply_len = wpa_supplicant_ctrl_iface_get_capability(
3811 wpa_s, buf + 15, reply, reply_size);
3812 } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) {
3813 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8))
3815 } else if (os_strncmp(buf, "SCAN_INTERVAL ", 14) == 0) {
3816 if (wpa_supplicant_ctrl_iface_scan_interval(wpa_s, buf + 14))
3818 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
3819 reply_len = wpa_supplicant_global_iface_list(
3820 wpa_s->global, reply, reply_size);
3821 } else if (os_strcmp(buf, "INTERFACES") == 0) {
3822 reply_len = wpa_supplicant_global_iface_interfaces(
3823 wpa_s->global, reply, reply_size);
3824 } else if (os_strncmp(buf, "BSS ", 4) == 0) {
3825 reply_len = wpa_supplicant_ctrl_iface_bss(
3826 wpa_s, buf + 4, reply, reply_size);
3828 } else if (os_strcmp(buf, "STA-FIRST") == 0) {
3829 reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
3830 } else if (os_strncmp(buf, "STA ", 4) == 0) {
3831 reply_len = ap_ctrl_iface_sta(wpa_s, buf + 4, reply,
3833 } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
3834 reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
3836 #endif /* CONFIG_AP */
3837 } else if (os_strcmp(buf, "SUSPEND") == 0) {
3838 wpas_notify_suspend(wpa_s->global);
3839 } else if (os_strcmp(buf, "RESUME") == 0) {
3840 wpas_notify_resume(wpa_s->global);
3841 } else if (os_strcmp(buf, "DROP_SA") == 0) {
3842 wpa_supplicant_ctrl_iface_drop_sa(wpa_s);
3843 } else if (os_strncmp(buf, "ROAM ", 5) == 0) {
3844 if (wpa_supplicant_ctrl_iface_roam(wpa_s, buf + 5))
3846 } else if (os_strncmp(buf, "STA_AUTOCONNECT ", 16) == 0) {
3847 if (wpa_supplicant_ctrl_iface_sta_autoconnect(wpa_s, buf + 16))
3849 } else if (os_strncmp(buf, "BSS_EXPIRE_AGE ", 15) == 0) {
3850 if (wpa_supplicant_ctrl_iface_bss_expire_age(wpa_s, buf + 15))
3852 } else if (os_strncmp(buf, "BSS_EXPIRE_COUNT ", 17) == 0) {
3853 if (wpa_supplicant_ctrl_iface_bss_expire_count(wpa_s,
3857 } else if (os_strncmp(buf, "TDLS_DISCOVER ", 14) == 0) {
3858 if (wpa_supplicant_ctrl_iface_tdls_discover(wpa_s, buf + 14))
3860 } else if (os_strncmp(buf, "TDLS_SETUP ", 11) == 0) {
3861 if (wpa_supplicant_ctrl_iface_tdls_setup(wpa_s, buf + 11))
3863 } else if (os_strncmp(buf, "TDLS_TEARDOWN ", 14) == 0) {
3864 if (wpa_supplicant_ctrl_iface_tdls_teardown(wpa_s, buf + 14))
3866 #endif /* CONFIG_TDLS */
3867 } else if (os_strncmp(buf, "SIGNAL_POLL", 11) == 0) {
3868 reply_len = wpa_supplicant_signal_poll(wpa_s, reply,
3870 } else if (os_strcmp(buf, "REAUTHENTICATE") == 0) {
3871 eapol_sm_request_reauth(wpa_s->eapol);
3873 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
3877 if (reply_len < 0) {
3878 os_memcpy(reply, "FAIL\n", 5);
3883 eapol_sm_notify_ctrl_response(wpa_s->eapol);
3885 *resp_len = reply_len;
3890 static int wpa_supplicant_global_iface_add(struct wpa_global *global,
3893 struct wpa_interface iface;
3897 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
3898 * TAB<bridge_ifname>
3900 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd);
3902 os_memset(&iface, 0, sizeof(iface));
3905 iface.ifname = pos = cmd;
3906 pos = os_strchr(pos, '\t');
3909 if (iface.ifname[0] == '\0')
3914 iface.confname = pos;
3915 pos = os_strchr(pos, '\t');
3918 if (iface.confname[0] == '\0')
3919 iface.confname = NULL;
3924 pos = os_strchr(pos, '\t');
3927 if (iface.driver[0] == '\0')
3928 iface.driver = NULL;
3932 iface.ctrl_interface = pos;
3933 pos = os_strchr(pos, '\t');
3936 if (iface.ctrl_interface[0] == '\0')
3937 iface.ctrl_interface = NULL;
3941 iface.driver_param = pos;
3942 pos = os_strchr(pos, '\t');
3945 if (iface.driver_param[0] == '\0')
3946 iface.driver_param = NULL;
3950 iface.bridge_ifname = pos;
3951 pos = os_strchr(pos, '\t');
3954 if (iface.bridge_ifname[0] == '\0')
3955 iface.bridge_ifname = NULL;
3960 if (wpa_supplicant_get_iface(global, iface.ifname))
3963 return wpa_supplicant_add_iface(global, &iface) ? 0 : -1;
3967 static int wpa_supplicant_global_iface_remove(struct wpa_global *global,
3970 struct wpa_supplicant *wpa_s;
3972 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd);
3974 wpa_s = wpa_supplicant_get_iface(global, cmd);
3977 return wpa_supplicant_remove_iface(global, wpa_s, 0);
3981 static void wpa_free_iface_info(struct wpa_interface_info *iface)
3983 struct wpa_interface_info *prev;
3987 iface = iface->next;
3989 os_free(prev->ifname);
3990 os_free(prev->desc);
3996 static int wpa_supplicant_global_iface_list(struct wpa_global *global,
4000 struct wpa_interface_info *iface = NULL, *last = NULL, *tmp;
4003 for (i = 0; wpa_drivers[i]; i++) {
4004 struct wpa_driver_ops *drv = wpa_drivers[i];
4005 if (drv->get_interfaces == NULL)
4007 tmp = drv->get_interfaces(global->drv_priv[i]);
4021 for (tmp = iface; tmp; tmp = tmp->next) {
4022 res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n",
4023 tmp->drv_name, tmp->ifname,
4024 tmp->desc ? tmp->desc : "");
4025 if (res < 0 || res >= end - pos) {
4032 wpa_free_iface_info(iface);
4038 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
4043 struct wpa_supplicant *wpa_s;
4045 wpa_s = global->ifaces;
4050 res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname);
4051 if (res < 0 || res >= end - pos) {
4056 wpa_s = wpa_s->next;
4062 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
4063 char *buf, size_t *resp_len)
4066 const int reply_size = 2048;
4068 int level = MSG_DEBUG;
4070 if (os_strcmp(buf, "PING") == 0)
4071 level = MSG_EXCESSIVE;
4072 wpa_hexdump_ascii(level, "RX global ctrl_iface",
4073 (const u8 *) buf, os_strlen(buf));
4075 reply = os_malloc(reply_size);
4076 if (reply == NULL) {
4081 os_memcpy(reply, "OK\n", 3);
4084 if (os_strcmp(buf, "PING") == 0) {
4085 os_memcpy(reply, "PONG\n", 5);
4087 } else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) {
4088 if (wpa_supplicant_global_iface_add(global, buf + 14))
4090 } else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) {
4091 if (wpa_supplicant_global_iface_remove(global, buf + 17))
4093 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
4094 reply_len = wpa_supplicant_global_iface_list(
4095 global, reply, reply_size);
4096 } else if (os_strcmp(buf, "INTERFACES") == 0) {
4097 reply_len = wpa_supplicant_global_iface_interfaces(
4098 global, reply, reply_size);
4099 } else if (os_strcmp(buf, "TERMINATE") == 0) {
4100 wpa_supplicant_terminate_proc(global);
4101 } else if (os_strcmp(buf, "SUSPEND") == 0) {
4102 wpas_notify_suspend(global);
4103 } else if (os_strcmp(buf, "RESUME") == 0) {
4104 wpas_notify_resume(global);
4106 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
4110 if (reply_len < 0) {
4111 os_memcpy(reply, "FAIL\n", 5);
4115 *resp_len = reply_len;