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