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
);
92 #ifdef IEEE8021X_EAPOL
93 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant
*wpa_s
,
97 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
99 if (hwaddr_aton(addr
, bssid
)) {
100 wpa_printf(MSG_DEBUG
, "CTRL_IFACE PREAUTH: invalid address "
105 wpa_printf(MSG_DEBUG
, "CTRL_IFACE PREAUTH " MACSTR
, MAC2STR(bssid
));
106 rsn_preauth_deinit(wpa_s
->wpa
);
107 if (rsn_preauth_init(wpa_s
->wpa
, bssid
, ssid
? &ssid
->eap
: NULL
))
112 #endif /* IEEE8021X_EAPOL */
115 #ifdef CONFIG_PEERKEY
116 /* MLME-STKSTART.request(peer) */
117 static int wpa_supplicant_ctrl_iface_stkstart(
118 struct wpa_supplicant
*wpa_s
, char *addr
)
122 if (hwaddr_aton(addr
, peer
)) {
123 wpa_printf(MSG_DEBUG
, "CTRL_IFACE STKSTART: invalid "
124 "address '%s'", addr
);
128 wpa_printf(MSG_DEBUG
, "CTRL_IFACE STKSTART " MACSTR
,
131 return wpa_sm_stkstart(wpa_s
->wpa
, peer
);
133 #endif /* CONFIG_PEERKEY */
136 #ifdef CONFIG_IEEE80211R
137 static int wpa_supplicant_ctrl_iface_ft_ds(
138 struct wpa_supplicant
*wpa_s
, char *addr
)
140 u8 target_ap
[ETH_ALEN
];
144 if (hwaddr_aton(addr
, target_ap
)) {
145 wpa_printf(MSG_DEBUG
, "CTRL_IFACE FT_DS: invalid "
146 "address '%s'", addr
);
150 wpa_printf(MSG_DEBUG
, "CTRL_IFACE FT_DS " MACSTR
, MAC2STR(target_ap
));
152 bss
= wpa_bss_get_bssid(wpa_s
, target_ap
);
154 mdie
= wpa_bss_get_ie(bss
, WLAN_EID_MOBILITY_DOMAIN
);
158 return wpa_ft_start_over_ds(wpa_s
->wpa
, target_ap
, mdie
);
160 #endif /* CONFIG_IEEE80211R */
164 static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant
*wpa_s
,
167 u8 bssid
[ETH_ALEN
], *_bssid
= bssid
;
169 if (cmd
== NULL
|| os_strcmp(cmd
, "any") == 0)
171 else if (hwaddr_aton(cmd
, bssid
)) {
172 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
179 return wpa_supplicant_ap_wps_pbc(wpa_s
, _bssid
);
180 #endif /* CONFIG_AP */
182 return wpas_wps_start_pbc(wpa_s
, _bssid
);
186 static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant
*wpa_s
,
187 char *cmd
, char *buf
,
190 u8 bssid
[ETH_ALEN
], *_bssid
= bssid
;
194 pin
= os_strchr(cmd
, ' ');
198 if (os_strcmp(cmd
, "any") == 0)
200 else if (hwaddr_aton(cmd
, bssid
)) {
201 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
208 return wpa_supplicant_ap_wps_pin(wpa_s
, _bssid
, pin
,
210 #endif /* CONFIG_AP */
213 ret
= wpas_wps_start_pin(wpa_s
, _bssid
, pin
);
216 ret
= os_snprintf(buf
, buflen
, "%s", pin
);
217 if (ret
< 0 || (size_t) ret
>= buflen
)
222 ret
= wpas_wps_start_pin(wpa_s
, _bssid
, NULL
);
226 /* Return the generated PIN */
227 ret
= os_snprintf(buf
, buflen
, "%08d", ret
);
228 if (ret
< 0 || (size_t) ret
>= buflen
)
234 #ifdef CONFIG_WPS_OOB
235 static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant
*wpa_s
,
238 char *path
, *method
, *name
;
240 path
= os_strchr(cmd
, ' ');
245 method
= os_strchr(path
, ' ');
250 name
= os_strchr(method
, ' ');
254 return wpas_wps_start_oob(wpa_s
, cmd
, path
, method
, name
);
256 #endif /* CONFIG_WPS_OOB */
259 static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant
*wpa_s
,
262 u8 bssid
[ETH_ALEN
], *_bssid
= bssid
;
268 struct wps_new_ap_settings ap
;
270 pin
= os_strchr(cmd
, ' ');
275 if (os_strcmp(cmd
, "any") == 0)
277 else if (hwaddr_aton(cmd
, bssid
)) {
278 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_REG: invalid BSSID '%s'",
283 new_ssid
= os_strchr(pin
, ' ');
284 if (new_ssid
== NULL
)
285 return wpas_wps_start_reg(wpa_s
, _bssid
, pin
, NULL
);
288 new_auth
= os_strchr(new_ssid
, ' ');
289 if (new_auth
== NULL
)
293 new_encr
= os_strchr(new_auth
, ' ');
294 if (new_encr
== NULL
)
298 new_key
= os_strchr(new_encr
, ' ');
303 os_memset(&ap
, 0, sizeof(ap
));
304 ap
.ssid_hex
= new_ssid
;
307 ap
.key_hex
= new_key
;
308 return wpas_wps_start_reg(wpa_s
, _bssid
, pin
, &ap
);
313 static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant
*wpa_s
,
316 char *uuid
= cmd
, *pin
, *pos
;
317 u8 addr_buf
[ETH_ALEN
], *addr
= NULL
;
318 pin
= os_strchr(uuid
, ' ');
322 pos
= os_strchr(pin
, ' ');
325 if (hwaddr_aton(pos
, addr_buf
) == 0)
328 return wpas_wps_er_add_pin(wpa_s
, addr
, uuid
, pin
);
332 static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant
*wpa_s
,
335 char *uuid
= cmd
, *pin
;
336 pin
= os_strchr(uuid
, ' ');
340 return wpas_wps_er_learn(wpa_s
, uuid
, pin
);
344 static int wpa_supplicant_ctrl_iface_wps_er_config(
345 struct wpa_supplicant
*wpa_s
, char *cmd
)
352 struct wps_new_ap_settings ap
;
354 pin
= os_strchr(cmd
, ' ');
359 new_ssid
= os_strchr(pin
, ' ');
360 if (new_ssid
== NULL
)
364 new_auth
= os_strchr(new_ssid
, ' ');
365 if (new_auth
== NULL
)
369 new_encr
= os_strchr(new_auth
, ' ');
370 if (new_encr
== NULL
)
374 new_key
= os_strchr(new_encr
, ' ');
379 os_memset(&ap
, 0, sizeof(ap
));
380 ap
.ssid_hex
= new_ssid
;
383 ap
.key_hex
= new_key
;
384 return wpas_wps_er_config(wpa_s
, cmd
, pin
, &ap
);
386 #endif /* CONFIG_WPS_ER */
388 #endif /* CONFIG_WPS */
391 #ifdef CONFIG_IBSS_RSN
392 static int wpa_supplicant_ctrl_iface_ibss_rsn(
393 struct wpa_supplicant
*wpa_s
, char *addr
)
397 if (hwaddr_aton(addr
, peer
)) {
398 wpa_printf(MSG_DEBUG
, "CTRL_IFACE IBSS_RSN: invalid "
399 "address '%s'", addr
);
403 wpa_printf(MSG_DEBUG
, "CTRL_IFACE IBSS_RSN " MACSTR
,
406 return ibss_rsn_start(wpa_s
->ibss_rsn
, peer
);
408 #endif /* CONFIG_IBSS_RSN */
411 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant
*wpa_s
,
414 #ifdef IEEE8021X_EAPOL
417 struct wpa_ssid
*ssid
;
418 struct eap_peer_config
*eap
;
420 pos
= os_strchr(rsp
, '-');
425 pos
= os_strchr(pos
, ':');
430 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: field=%s id=%d", rsp
, id
);
431 wpa_hexdump_ascii_key(MSG_DEBUG
, "CTRL_IFACE: value",
432 (u8
*) pos
, os_strlen(pos
));
434 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
436 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
442 if (os_strcmp(rsp
, "IDENTITY") == 0) {
443 os_free(eap
->identity
);
444 eap
->identity
= (u8
*) os_strdup(pos
);
445 eap
->identity_len
= os_strlen(pos
);
446 eap
->pending_req_identity
= 0;
447 if (ssid
== wpa_s
->current_ssid
)
448 wpa_s
->reassociate
= 1;
449 } else if (os_strcmp(rsp
, "PASSWORD") == 0) {
450 os_free(eap
->password
);
451 eap
->password
= (u8
*) os_strdup(pos
);
452 eap
->password_len
= os_strlen(pos
);
453 eap
->pending_req_password
= 0;
454 if (ssid
== wpa_s
->current_ssid
)
455 wpa_s
->reassociate
= 1;
456 } else if (os_strcmp(rsp
, "NEW_PASSWORD") == 0) {
457 os_free(eap
->new_password
);
458 eap
->new_password
= (u8
*) os_strdup(pos
);
459 eap
->new_password_len
= os_strlen(pos
);
460 eap
->pending_req_new_password
= 0;
461 if (ssid
== wpa_s
->current_ssid
)
462 wpa_s
->reassociate
= 1;
463 } else if (os_strcmp(rsp
, "PIN") == 0) {
465 eap
->pin
= os_strdup(pos
);
466 eap
->pending_req_pin
= 0;
467 if (ssid
== wpa_s
->current_ssid
)
468 wpa_s
->reassociate
= 1;
469 } else if (os_strcmp(rsp
, "OTP") == 0) {
471 eap
->otp
= (u8
*) os_strdup(pos
);
472 eap
->otp_len
= os_strlen(pos
);
473 os_free(eap
->pending_req_otp
);
474 eap
->pending_req_otp
= NULL
;
475 eap
->pending_req_otp_len
= 0;
476 } else if (os_strcmp(rsp
, "PASSPHRASE") == 0) {
477 os_free(eap
->private_key_passwd
);
478 eap
->private_key_passwd
= (u8
*) os_strdup(pos
);
479 eap
->pending_req_passphrase
= 0;
480 if (ssid
== wpa_s
->current_ssid
)
481 wpa_s
->reassociate
= 1;
483 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Unknown field '%s'", rsp
);
488 #else /* IEEE8021X_EAPOL */
489 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: 802.1X not included");
491 #endif /* IEEE8021X_EAPOL */
495 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant
*wpa_s
,
497 char *buf
, size_t buflen
)
499 char *pos
, *end
, tmp
[30];
500 int res
, verbose
, ret
;
502 verbose
= os_strcmp(params
, "-VERBOSE") == 0;
505 if (wpa_s
->wpa_state
>= WPA_ASSOCIATED
) {
506 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
507 ret
= os_snprintf(pos
, end
- pos
, "bssid=" MACSTR
"\n",
508 MAC2STR(wpa_s
->bssid
));
509 if (ret
< 0 || ret
>= end
- pos
)
513 u8
*_ssid
= ssid
->ssid
;
514 size_t ssid_len
= ssid
->ssid_len
;
515 u8 ssid_buf
[MAX_SSID_LEN
];
517 int _res
= wpa_drv_get_ssid(wpa_s
, ssid_buf
);
524 ret
= os_snprintf(pos
, end
- pos
, "ssid=%s\nid=%d\n",
525 wpa_ssid_txt(_ssid
, ssid_len
),
527 if (ret
< 0 || ret
>= end
- pos
)
532 ret
= os_snprintf(pos
, end
- pos
,
535 if (ret
< 0 || ret
>= end
- pos
)
540 switch (ssid
->mode
) {
541 case WPAS_MODE_INFRA
:
542 ret
= os_snprintf(pos
, end
- pos
,
546 ret
= os_snprintf(pos
, end
- pos
,
550 ret
= os_snprintf(pos
, end
- pos
,
557 if (ret
< 0 || ret
>= end
- pos
)
563 if (wpa_s
->ap_iface
) {
564 pos
+= ap_ctrl_iface_wpa_get_status(wpa_s
, pos
,
568 #endif /* CONFIG_AP */
569 pos
+= wpa_sm_get_status(wpa_s
->wpa
, pos
, end
- pos
, verbose
);
571 ret
= os_snprintf(pos
, end
- pos
, "wpa_state=%s\n",
572 wpa_supplicant_state_txt(wpa_s
->wpa_state
));
573 if (ret
< 0 || ret
>= end
- pos
)
578 l2_packet_get_ip_addr(wpa_s
->l2
, tmp
, sizeof(tmp
)) >= 0) {
579 ret
= os_snprintf(pos
, end
- pos
, "ip_address=%s\n", tmp
);
580 if (ret
< 0 || ret
>= end
- pos
)
585 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s
->key_mgmt
) ||
586 wpa_s
->key_mgmt
== WPA_KEY_MGMT_IEEE8021X_NO_WPA
) {
587 res
= eapol_sm_get_status(wpa_s
->eapol
, pos
, end
- pos
,
593 res
= rsn_preauth_get_status(wpa_s
->wpa
, pos
, end
- pos
, verbose
);
601 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant
*wpa_s
,
606 struct wpa_ssid
*ssid
;
609 /* cmd: "<network id> <BSSID>" */
610 pos
= os_strchr(cmd
, ' ');
615 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: id=%d bssid='%s'", id
, pos
);
616 if (hwaddr_aton(pos
, bssid
)) {
617 wpa_printf(MSG_DEBUG
,"CTRL_IFACE: invalid BSSID '%s'", pos
);
621 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
623 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
628 os_memcpy(ssid
->bssid
, bssid
, ETH_ALEN
);
629 ssid
->bssid_set
= !is_zero_ether_addr(bssid
);
635 static int wpa_supplicant_ctrl_iface_list_networks(
636 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
639 struct wpa_ssid
*ssid
;
644 ret
= os_snprintf(pos
, end
- pos
,
645 "network id / ssid / bssid / flags\n");
646 if (ret
< 0 || ret
>= end
- pos
)
650 ssid
= wpa_s
->conf
->ssid
;
652 ret
= os_snprintf(pos
, end
- pos
, "%d\t%s",
654 wpa_ssid_txt(ssid
->ssid
, ssid
->ssid_len
));
655 if (ret
< 0 || ret
>= end
- pos
)
658 if (ssid
->bssid_set
) {
659 ret
= os_snprintf(pos
, end
- pos
, "\t" MACSTR
,
660 MAC2STR(ssid
->bssid
));
662 ret
= os_snprintf(pos
, end
- pos
, "\tany");
664 if (ret
< 0 || ret
>= end
- pos
)
667 ret
= os_snprintf(pos
, end
- pos
, "\t%s%s",
668 ssid
== wpa_s
->current_ssid
?
670 ssid
->disabled
? "[DISABLED]" : "");
671 if (ret
< 0 || ret
>= end
- pos
)
674 ret
= os_snprintf(pos
, end
- pos
, "\n");
675 if (ret
< 0 || ret
>= end
- pos
)
686 static char * wpa_supplicant_cipher_txt(char *pos
, char *end
, int cipher
)
689 ret
= os_snprintf(pos
, end
- pos
, "-");
690 if (ret
< 0 || ret
>= end
- pos
)
693 if (cipher
& WPA_CIPHER_NONE
) {
694 ret
= os_snprintf(pos
, end
- pos
, "%sNONE", first
? "" : "+");
695 if (ret
< 0 || ret
>= end
- pos
)
700 if (cipher
& WPA_CIPHER_WEP40
) {
701 ret
= os_snprintf(pos
, end
- pos
, "%sWEP40", first
? "" : "+");
702 if (ret
< 0 || ret
>= end
- pos
)
707 if (cipher
& WPA_CIPHER_WEP104
) {
708 ret
= os_snprintf(pos
, end
- pos
, "%sWEP104",
710 if (ret
< 0 || ret
>= end
- pos
)
715 if (cipher
& WPA_CIPHER_TKIP
) {
716 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : "+");
717 if (ret
< 0 || ret
>= end
- pos
)
722 if (cipher
& WPA_CIPHER_CCMP
) {
723 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : "+");
724 if (ret
< 0 || ret
>= end
- pos
)
733 static char * wpa_supplicant_ie_txt(char *pos
, char *end
, const char *proto
,
734 const u8
*ie
, size_t ie_len
)
736 struct wpa_ie_data data
;
739 ret
= os_snprintf(pos
, end
- pos
, "[%s-", proto
);
740 if (ret
< 0 || ret
>= end
- pos
)
744 if (wpa_parse_wpa_ie(ie
, ie_len
, &data
) < 0) {
745 ret
= os_snprintf(pos
, end
- pos
, "?]");
746 if (ret
< 0 || ret
>= end
- pos
)
753 if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X
) {
754 ret
= os_snprintf(pos
, end
- pos
, "%sEAP", first
? "" : "+");
755 if (ret
< 0 || ret
>= end
- pos
)
760 if (data
.key_mgmt
& WPA_KEY_MGMT_PSK
) {
761 ret
= os_snprintf(pos
, end
- pos
, "%sPSK", first
? "" : "+");
762 if (ret
< 0 || ret
>= end
- pos
)
767 if (data
.key_mgmt
& WPA_KEY_MGMT_WPA_NONE
) {
768 ret
= os_snprintf(pos
, end
- pos
, "%sNone", first
? "" : "+");
769 if (ret
< 0 || ret
>= end
- pos
)
774 #ifdef CONFIG_IEEE80211R
775 if (data
.key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
) {
776 ret
= os_snprintf(pos
, end
- pos
, "%sFT/EAP",
778 if (ret
< 0 || ret
>= end
- pos
)
783 if (data
.key_mgmt
& WPA_KEY_MGMT_FT_PSK
) {
784 ret
= os_snprintf(pos
, end
- pos
, "%sFT/PSK",
786 if (ret
< 0 || ret
>= end
- pos
)
791 #endif /* CONFIG_IEEE80211R */
792 #ifdef CONFIG_IEEE80211W
793 if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
) {
794 ret
= os_snprintf(pos
, end
- pos
, "%sEAP-SHA256",
796 if (ret
< 0 || ret
>= end
- pos
)
801 if (data
.key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
) {
802 ret
= os_snprintf(pos
, end
- pos
, "%sPSK-SHA256",
804 if (ret
< 0 || ret
>= end
- pos
)
809 #endif /* CONFIG_IEEE80211W */
811 pos
= wpa_supplicant_cipher_txt(pos
, end
, data
.pairwise_cipher
);
813 if (data
.capabilities
& WPA_CAPABILITY_PREAUTH
) {
814 ret
= os_snprintf(pos
, end
- pos
, "-preauth");
815 if (ret
< 0 || ret
>= end
- pos
)
820 ret
= os_snprintf(pos
, end
- pos
, "]");
821 if (ret
< 0 || ret
>= end
- pos
)
830 static char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant
*wpa_s
,
831 char *pos
, char *end
,
832 struct wpabuf
*wps_ie
)
839 if (wps_is_selected_pbc_registrar(wps_ie
))
842 else if (wps_is_addr_authorized(wps_ie
, wpa_s
->own_addr
, 0))
844 #endif /* CONFIG_WPS2 */
845 else if (wps_is_selected_pin_registrar(wps_ie
))
850 ret
= os_snprintf(pos
, end
- pos
, "%s", txt
);
851 if (ret
>= 0 && ret
< end
- pos
)
856 #endif /* CONFIG_WPS */
859 static char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant
*wpa_s
,
860 char *pos
, char *end
,
861 const struct wpa_bss
*bss
)
864 struct wpabuf
*wps_ie
;
865 wps_ie
= wpa_bss_get_vendor_ie_multi(bss
, WPS_IE_VENDOR_TYPE
);
866 return wpa_supplicant_wps_ie_txt_buf(wpa_s
, pos
, end
, wps_ie
);
867 #else /* CONFIG_WPS */
869 #endif /* CONFIG_WPS */
873 /* Format one result on one text line into a buffer. */
874 static int wpa_supplicant_ctrl_iface_scan_result(
875 struct wpa_supplicant
*wpa_s
,
876 const struct wpa_bss
*bss
, char *buf
, size_t buflen
)
885 ret
= os_snprintf(pos
, end
- pos
, MACSTR
"\t%d\t%d\t",
886 MAC2STR(bss
->bssid
), bss
->freq
, bss
->level
);
887 if (ret
< 0 || ret
>= end
- pos
)
890 ie
= wpa_bss_get_vendor_ie(bss
, WPA_IE_VENDOR_TYPE
);
892 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA", ie
, 2 + ie
[1]);
893 ie2
= wpa_bss_get_ie(bss
, WLAN_EID_RSN
);
895 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA2", ie2
, 2 + ie2
[1]);
896 pos
= wpa_supplicant_wps_ie_txt(wpa_s
, pos
, end
, bss
);
897 if (!ie
&& !ie2
&& bss
->caps
& IEEE80211_CAP_PRIVACY
) {
898 ret
= os_snprintf(pos
, end
- pos
, "[WEP]");
899 if (ret
< 0 || ret
>= end
- pos
)
903 if (bss
->caps
& IEEE80211_CAP_IBSS
) {
904 ret
= os_snprintf(pos
, end
- pos
, "[IBSS]");
905 if (ret
< 0 || ret
>= end
- pos
)
909 if (bss
->caps
& IEEE80211_CAP_ESS
) {
910 ret
= os_snprintf(pos
, end
- pos
, "[ESS]");
911 if (ret
< 0 || ret
>= end
- pos
)
916 ret
= os_snprintf(pos
, end
- pos
, "\t%s",
917 wpa_ssid_txt(bss
->ssid
, bss
->ssid_len
));
918 if (ret
< 0 || ret
>= end
- pos
)
922 ret
= os_snprintf(pos
, end
- pos
, "\n");
923 if (ret
< 0 || ret
>= end
- pos
)
931 static int wpa_supplicant_ctrl_iface_scan_results(
932 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
940 ret
= os_snprintf(pos
, end
- pos
, "bssid / frequency / signal level / "
942 if (ret
< 0 || ret
>= end
- pos
)
946 dl_list_for_each(bss
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
) {
947 ret
= wpa_supplicant_ctrl_iface_scan_result(wpa_s
, bss
, pos
,
949 if (ret
< 0 || ret
>= end
- pos
)
958 static int wpa_supplicant_ctrl_iface_select_network(
959 struct wpa_supplicant
*wpa_s
, char *cmd
)
962 struct wpa_ssid
*ssid
;
964 /* cmd: "<network id>" or "any" */
965 if (os_strcmp(cmd
, "any") == 0) {
966 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SELECT_NETWORK any");
970 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SELECT_NETWORK id=%d", id
);
972 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
974 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
975 "network id=%d", id
);
980 wpa_supplicant_select_network(wpa_s
, ssid
);
986 static int wpa_supplicant_ctrl_iface_enable_network(
987 struct wpa_supplicant
*wpa_s
, char *cmd
)
990 struct wpa_ssid
*ssid
;
992 /* cmd: "<network id>" or "all" */
993 if (os_strcmp(cmd
, "all") == 0) {
994 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ENABLE_NETWORK all");
998 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ENABLE_NETWORK id=%d", id
);
1000 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1002 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
1003 "network id=%d", id
);
1007 wpa_supplicant_enable_network(wpa_s
, ssid
);
1013 static int wpa_supplicant_ctrl_iface_disable_network(
1014 struct wpa_supplicant
*wpa_s
, char *cmd
)
1017 struct wpa_ssid
*ssid
;
1019 /* cmd: "<network id>" or "all" */
1020 if (os_strcmp(cmd
, "all") == 0) {
1021 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: DISABLE_NETWORK all");
1025 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: DISABLE_NETWORK id=%d", id
);
1027 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1029 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
1030 "network id=%d", id
);
1034 wpa_supplicant_disable_network(wpa_s
, ssid
);
1040 static int wpa_supplicant_ctrl_iface_add_network(
1041 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
1043 struct wpa_ssid
*ssid
;
1046 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ADD_NETWORK");
1048 ssid
= wpa_config_add_network(wpa_s
->conf
);
1052 wpas_notify_network_added(wpa_s
, ssid
);
1055 wpa_config_set_network_defaults(ssid
);
1057 ret
= os_snprintf(buf
, buflen
, "%d\n", ssid
->id
);
1058 if (ret
< 0 || (size_t) ret
>= buflen
)
1064 static int wpa_supplicant_ctrl_iface_remove_network(
1065 struct wpa_supplicant
*wpa_s
, char *cmd
)
1068 struct wpa_ssid
*ssid
;
1070 /* cmd: "<network id>" or "all" */
1071 if (os_strcmp(cmd
, "all") == 0) {
1072 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_NETWORK all");
1073 ssid
= wpa_s
->conf
->ssid
;
1075 struct wpa_ssid
*remove_ssid
= ssid
;
1078 wpas_notify_network_removed(wpa_s
, remove_ssid
);
1079 wpa_config_remove_network(wpa_s
->conf
, id
);
1081 if (wpa_s
->current_ssid
) {
1082 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
1083 wpa_supplicant_disassociate(wpa_s
,
1084 WLAN_REASON_DEAUTH_LEAVING
);
1090 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_NETWORK id=%d", id
);
1092 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1094 wpa_config_remove_network(wpa_s
->conf
, id
) < 0) {
1095 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
1100 if (ssid
== wpa_s
->current_ssid
) {
1102 * Invalidate the EAP session cache if the current network is
1105 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
1107 wpa_supplicant_disassociate(wpa_s
, WLAN_REASON_DEAUTH_LEAVING
);
1114 static int wpa_supplicant_ctrl_iface_set_network(
1115 struct wpa_supplicant
*wpa_s
, char *cmd
)
1118 struct wpa_ssid
*ssid
;
1121 /* cmd: "<network id> <variable name> <value>" */
1122 name
= os_strchr(cmd
, ' ');
1127 value
= os_strchr(name
, ' ');
1133 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
1135 wpa_hexdump_ascii_key(MSG_DEBUG
, "CTRL_IFACE: value",
1136 (u8
*) value
, os_strlen(value
));
1138 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1140 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
1145 if (wpa_config_set(ssid
, name
, value
, 0) < 0) {
1146 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Failed to set network "
1147 "variable '%s'", name
);
1151 if (wpa_s
->current_ssid
== ssid
) {
1153 * Invalidate the EAP session cache if anything in the current
1154 * configuration changes.
1156 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
1159 if ((os_strcmp(name
, "psk") == 0 &&
1160 value
[0] == '"' && ssid
->ssid_len
) ||
1161 (os_strcmp(name
, "ssid") == 0 && ssid
->passphrase
))
1162 wpa_config_update_psk(ssid
);
1163 else if (os_strcmp(name
, "priority") == 0)
1164 wpa_config_update_prio_list(wpa_s
->conf
);
1170 static int wpa_supplicant_ctrl_iface_get_network(
1171 struct wpa_supplicant
*wpa_s
, char *cmd
, char *buf
, size_t buflen
)
1175 struct wpa_ssid
*ssid
;
1178 /* cmd: "<network id> <variable name>" */
1179 name
= os_strchr(cmd
, ' ');
1180 if (name
== NULL
|| buflen
== 0)
1185 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
1188 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1190 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
1195 value
= wpa_config_get_no_key(ssid
, name
);
1196 if (value
== NULL
) {
1197 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Failed to get network "
1198 "variable '%s'", name
);
1202 res
= os_strlcpy(buf
, value
, buflen
);
1203 if (res
>= buflen
) {
1214 #ifndef CONFIG_NO_CONFIG_WRITE
1215 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant
*wpa_s
)
1219 if (!wpa_s
->conf
->update_config
) {
1220 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
1221 "to update configuration (update_config=0)");
1225 ret
= wpa_config_write(wpa_s
->confname
, wpa_s
->conf
);
1227 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Failed to "
1228 "update configuration");
1230 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Configuration"
1236 #endif /* CONFIG_NO_CONFIG_WRITE */
1239 static int ctrl_iface_get_capability_pairwise(int res
, char *strict
,
1240 struct wpa_driver_capa
*capa
,
1241 char *buf
, size_t buflen
)
1253 len
= os_strlcpy(buf
, "CCMP TKIP NONE", buflen
);
1259 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
1260 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : " ");
1261 if (ret
< 0 || ret
>= end
- pos
)
1267 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
1268 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : " ");
1269 if (ret
< 0 || ret
>= end
- pos
)
1275 if (capa
->key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
1276 ret
= os_snprintf(pos
, end
- pos
, "%sNONE", first
? "" : " ");
1277 if (ret
< 0 || ret
>= end
- pos
)
1287 static int ctrl_iface_get_capability_group(int res
, char *strict
,
1288 struct wpa_driver_capa
*capa
,
1289 char *buf
, size_t buflen
)
1301 len
= os_strlcpy(buf
, "CCMP TKIP WEP104 WEP40", buflen
);
1307 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
1308 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : " ");
1309 if (ret
< 0 || ret
>= end
- pos
)
1315 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
1316 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : " ");
1317 if (ret
< 0 || ret
>= end
- pos
)
1323 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_WEP104
) {
1324 ret
= os_snprintf(pos
, end
- pos
, "%sWEP104",
1326 if (ret
< 0 || ret
>= end
- pos
)
1332 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_WEP40
) {
1333 ret
= os_snprintf(pos
, end
- pos
, "%sWEP40", first
? "" : " ");
1334 if (ret
< 0 || ret
>= end
- pos
)
1344 static int ctrl_iface_get_capability_key_mgmt(int res
, char *strict
,
1345 struct wpa_driver_capa
*capa
,
1346 char *buf
, size_t buflen
)
1358 len
= os_strlcpy(buf
, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE "
1365 ret
= os_snprintf(pos
, end
- pos
, "NONE IEEE8021X");
1366 if (ret
< 0 || ret
>= end
- pos
)
1370 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
1371 WPA_DRIVER_CAPA_KEY_MGMT_WPA2
)) {
1372 ret
= os_snprintf(pos
, end
- pos
, " WPA-EAP");
1373 if (ret
< 0 || ret
>= end
- pos
)
1378 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
|
1379 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
1380 ret
= os_snprintf(pos
, end
- pos
, " WPA-PSK");
1381 if (ret
< 0 || ret
>= end
- pos
)
1386 if (capa
->key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
1387 ret
= os_snprintf(pos
, end
- pos
, " WPA-NONE");
1388 if (ret
< 0 || ret
>= end
- pos
)
1397 static int ctrl_iface_get_capability_proto(int res
, char *strict
,
1398 struct wpa_driver_capa
*capa
,
1399 char *buf
, size_t buflen
)
1411 len
= os_strlcpy(buf
, "RSN WPA", buflen
);
1417 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA2
|
1418 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
1419 ret
= os_snprintf(pos
, end
- pos
, "%sRSN", first
? "" : " ");
1420 if (ret
< 0 || ret
>= end
- pos
)
1426 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
1427 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
)) {
1428 ret
= os_snprintf(pos
, end
- pos
, "%sWPA", first
? "" : " ");
1429 if (ret
< 0 || ret
>= end
- pos
)
1439 static int ctrl_iface_get_capability_auth_alg(int res
, char *strict
,
1440 struct wpa_driver_capa
*capa
,
1441 char *buf
, size_t buflen
)
1453 len
= os_strlcpy(buf
, "OPEN SHARED LEAP", buflen
);
1459 if (capa
->auth
& (WPA_DRIVER_AUTH_OPEN
)) {
1460 ret
= os_snprintf(pos
, end
- pos
, "%sOPEN", first
? "" : " ");
1461 if (ret
< 0 || ret
>= end
- pos
)
1467 if (capa
->auth
& (WPA_DRIVER_AUTH_SHARED
)) {
1468 ret
= os_snprintf(pos
, end
- pos
, "%sSHARED",
1470 if (ret
< 0 || ret
>= end
- pos
)
1476 if (capa
->auth
& (WPA_DRIVER_AUTH_LEAP
)) {
1477 ret
= os_snprintf(pos
, end
- pos
, "%sLEAP", first
? "" : " ");
1478 if (ret
< 0 || ret
>= end
- pos
)
1488 static int wpa_supplicant_ctrl_iface_get_capability(
1489 struct wpa_supplicant
*wpa_s
, const char *_field
, char *buf
,
1492 struct wpa_driver_capa capa
;
1498 /* Determine whether or not strict checking was requested */
1499 len
= os_strlcpy(field
, _field
, sizeof(field
));
1500 if (len
>= sizeof(field
))
1502 strict
= os_strchr(field
, ' ');
1503 if (strict
!= NULL
) {
1505 if (os_strcmp(strict
, "strict") != 0)
1509 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
1510 field
, strict
? strict
: "");
1512 if (os_strcmp(field
, "eap") == 0) {
1513 return eap_get_names(buf
, buflen
);
1516 res
= wpa_drv_get_capa(wpa_s
, &capa
);
1518 if (os_strcmp(field
, "pairwise") == 0)
1519 return ctrl_iface_get_capability_pairwise(res
, strict
, &capa
,
1522 if (os_strcmp(field
, "group") == 0)
1523 return ctrl_iface_get_capability_group(res
, strict
, &capa
,
1526 if (os_strcmp(field
, "key_mgmt") == 0)
1527 return ctrl_iface_get_capability_key_mgmt(res
, strict
, &capa
,
1530 if (os_strcmp(field
, "proto") == 0)
1531 return ctrl_iface_get_capability_proto(res
, strict
, &capa
,
1534 if (os_strcmp(field
, "auth_alg") == 0)
1535 return ctrl_iface_get_capability_auth_alg(res
, strict
, &capa
,
1538 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
1545 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant
*wpa_s
,
1546 const char *cmd
, char *buf
,
1551 struct wpa_bss
*bss
;
1556 if (os_strcmp(cmd
, "FIRST") == 0)
1557 bss
= dl_list_first(&wpa_s
->bss
, struct wpa_bss
, list
);
1558 else if (os_strncmp(cmd
, "ID-", 3) == 0) {
1560 bss
= wpa_bss_get_id(wpa_s
, i
);
1561 } else if (os_strncmp(cmd
, "NEXT-", 5) == 0) {
1563 bss
= wpa_bss_get_id(wpa_s
, i
);
1565 struct dl_list
*next
= bss
->list_id
.next
;
1566 if (next
== &wpa_s
->bss_id
)
1569 bss
= dl_list_entry(next
, struct wpa_bss
,
1572 } else if (hwaddr_aton(cmd
, bssid
) == 0)
1573 bss
= wpa_bss_get_bssid(wpa_s
, bssid
);
1575 struct wpa_bss
*tmp
;
1578 dl_list_for_each(tmp
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
)
1592 ret
= os_snprintf(pos
, end
- pos
,
1594 "bssid=" MACSTR
"\n"
1597 "capabilities=0x%04x\n"
1604 MAC2STR(bss
->bssid
), bss
->freq
, bss
->beacon_int
,
1605 bss
->caps
, bss
->qual
, bss
->noise
, bss
->level
,
1606 (unsigned long long) bss
->tsf
);
1607 if (ret
< 0 || ret
>= end
- pos
)
1611 ie
= (const u8
*) (bss
+ 1);
1612 for (i
= 0; i
< bss
->ie_len
; i
++) {
1613 ret
= os_snprintf(pos
, end
- pos
, "%02x", *ie
++);
1614 if (ret
< 0 || ret
>= end
- pos
)
1619 ret
= os_snprintf(pos
, end
- pos
, "\n");
1620 if (ret
< 0 || ret
>= end
- pos
)
1624 ret
= os_snprintf(pos
, end
- pos
, "flags=");
1625 if (ret
< 0 || ret
>= end
- pos
)
1629 ie
= wpa_bss_get_vendor_ie(bss
, WPA_IE_VENDOR_TYPE
);
1631 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA", ie
, 2 + ie
[1]);
1632 ie2
= wpa_bss_get_ie(bss
, WLAN_EID_RSN
);
1634 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA2", ie2
, 2 + ie2
[1]);
1635 pos
= wpa_supplicant_wps_ie_txt(wpa_s
, pos
, end
, bss
);
1636 if (!ie
&& !ie2
&& bss
->caps
& IEEE80211_CAP_PRIVACY
) {
1637 ret
= os_snprintf(pos
, end
- pos
, "[WEP]");
1638 if (ret
< 0 || ret
>= end
- pos
)
1642 if (bss
->caps
& IEEE80211_CAP_IBSS
) {
1643 ret
= os_snprintf(pos
, end
- pos
, "[IBSS]");
1644 if (ret
< 0 || ret
>= end
- pos
)
1648 if (bss
->caps
& IEEE80211_CAP_ESS
) {
1649 ret
= os_snprintf(pos
, end
- pos
, "[ESS]");
1650 if (ret
< 0 || ret
>= end
- pos
)
1655 ret
= os_snprintf(pos
, end
- pos
, "\n");
1656 if (ret
< 0 || ret
>= end
- pos
)
1660 ret
= os_snprintf(pos
, end
- pos
, "ssid=%s\n",
1661 wpa_ssid_txt(bss
->ssid
, bss
->ssid_len
));
1662 if (ret
< 0 || ret
>= end
- pos
)
1667 ie
= (const u8
*) (bss
+ 1);
1668 ret
= wpas_wps_scan_result_text(ie
, bss
->ie_len
, pos
, end
);
1669 if (ret
< 0 || ret
>= end
- pos
)
1672 #endif /* CONFIG_WPS */
1678 static int wpa_supplicant_ctrl_iface_ap_scan(
1679 struct wpa_supplicant
*wpa_s
, char *cmd
)
1681 int ap_scan
= atoi(cmd
);
1682 return wpa_supplicant_set_ap_scan(wpa_s
, ap_scan
);
1686 static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant
*wpa_s
)
1688 u8
*bcast
= (u8
*) "\xff\xff\xff\xff\xff\xff";
1690 wpa_printf(MSG_DEBUG
, "Dropping SA without deauthentication");
1691 /* MLME-DELETEKEYS.request */
1692 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 0, 0, NULL
, 0, NULL
, 0);
1693 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 1, 0, NULL
, 0, NULL
, 0);
1694 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 2, 0, NULL
, 0, NULL
, 0);
1695 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 3, 0, NULL
, 0, NULL
, 0);
1696 #ifdef CONFIG_IEEE80211W
1697 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 4, 0, NULL
, 0, NULL
, 0);
1698 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 5, 0, NULL
, 0, NULL
, 0);
1699 #endif /* CONFIG_IEEE80211W */
1701 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, wpa_s
->bssid
, 0, 0, NULL
, 0, NULL
,
1703 /* MLME-SETPROTECTION.request(None) */
1704 wpa_drv_mlme_setprotection(wpa_s
, wpa_s
->bssid
,
1705 MLME_SETPROTECTION_PROTECT_TYPE_NONE
,
1706 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE
);
1707 wpa_sm_drop_sa(wpa_s
->wpa
);
1711 static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant
*wpa_s
,
1715 struct wpa_bss
*bss
;
1716 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
1718 if (hwaddr_aton(addr
, bssid
)) {
1719 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM: invalid "
1720 "address '%s'", addr
);
1724 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM " MACSTR
, MAC2STR(bssid
));
1726 bss
= wpa_bss_get_bssid(wpa_s
, bssid
);
1728 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM: Target AP not found "
1734 * TODO: Find best network configuration block from configuration to
1735 * allow roaming to other networks
1739 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM: No network "
1740 "configuration known for the target AP");
1744 wpa_s
->reassociate
= 1;
1745 wpa_supplicant_connect(wpa_s
, bss
, ssid
);
1751 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant
*wpa_s
,
1752 char *buf
, size_t *resp_len
)
1755 const int reply_size
= 2048;
1759 if (os_strncmp(buf
, WPA_CTRL_RSP
, os_strlen(WPA_CTRL_RSP
)) == 0 ||
1760 os_strncmp(buf
, "SET_NETWORK ", 12) == 0) {
1761 wpa_hexdump_ascii_key(MSG_DEBUG
, "RX ctrl_iface",
1762 (const u8
*) buf
, os_strlen(buf
));
1764 wpa_hexdump_ascii(MSG_DEBUG
, "RX ctrl_iface",
1765 (const u8
*) buf
, os_strlen(buf
));
1768 reply
= os_malloc(reply_size
);
1769 if (reply
== NULL
) {
1774 os_memcpy(reply
, "OK\n", 3);
1777 if (os_strcmp(buf
, "PING") == 0) {
1778 os_memcpy(reply
, "PONG\n", 5);
1780 } else if (os_strncmp(buf
, "NOTE ", 5) == 0) {
1781 wpa_printf(MSG_INFO
, "NOTE: %s", buf
+ 5);
1782 } else if (os_strcmp(buf
, "MIB") == 0) {
1783 reply_len
= wpa_sm_get_mib(wpa_s
->wpa
, reply
, reply_size
);
1784 if (reply_len
>= 0) {
1786 res
= eapol_sm_get_mib(wpa_s
->eapol
, reply
+ reply_len
,
1787 reply_size
- reply_len
);
1793 } else if (os_strncmp(buf
, "STATUS", 6) == 0) {
1794 reply_len
= wpa_supplicant_ctrl_iface_status(
1795 wpa_s
, buf
+ 6, reply
, reply_size
);
1796 } else if (os_strcmp(buf
, "PMKSA") == 0) {
1797 reply_len
= wpa_sm_pmksa_cache_list(wpa_s
->wpa
, reply
,
1799 } else if (os_strncmp(buf
, "SET ", 4) == 0) {
1800 if (wpa_supplicant_ctrl_iface_set(wpa_s
, buf
+ 4))
1802 } else if (os_strcmp(buf
, "LOGON") == 0) {
1803 eapol_sm_notify_logoff(wpa_s
->eapol
, FALSE
);
1804 } else if (os_strcmp(buf
, "LOGOFF") == 0) {
1805 eapol_sm_notify_logoff(wpa_s
->eapol
, TRUE
);
1806 } else if (os_strcmp(buf
, "REASSOCIATE") == 0) {
1807 if (wpa_s
->wpa_state
== WPA_INTERFACE_DISABLED
)
1810 wpa_s
->disconnected
= 0;
1811 wpa_s
->reassociate
= 1;
1812 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1814 } else if (os_strcmp(buf
, "RECONNECT") == 0) {
1815 if (wpa_s
->wpa_state
== WPA_INTERFACE_DISABLED
)
1817 else if (wpa_s
->disconnected
) {
1818 wpa_s
->disconnected
= 0;
1819 wpa_s
->reassociate
= 1;
1820 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1822 #ifdef IEEE8021X_EAPOL
1823 } else if (os_strncmp(buf
, "PREAUTH ", 8) == 0) {
1824 if (wpa_supplicant_ctrl_iface_preauth(wpa_s
, buf
+ 8))
1826 #endif /* IEEE8021X_EAPOL */
1827 #ifdef CONFIG_PEERKEY
1828 } else if (os_strncmp(buf
, "STKSTART ", 9) == 0) {
1829 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s
, buf
+ 9))
1831 #endif /* CONFIG_PEERKEY */
1832 #ifdef CONFIG_IEEE80211R
1833 } else if (os_strncmp(buf
, "FT_DS ", 6) == 0) {
1834 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s
, buf
+ 6))
1836 #endif /* CONFIG_IEEE80211R */
1838 } else if (os_strcmp(buf
, "WPS_PBC") == 0) {
1839 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s
, NULL
))
1841 } else if (os_strncmp(buf
, "WPS_PBC ", 8) == 0) {
1842 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s
, buf
+ 8))
1844 } else if (os_strncmp(buf
, "WPS_PIN ", 8) == 0) {
1845 reply_len
= wpa_supplicant_ctrl_iface_wps_pin(wpa_s
, buf
+ 8,
1848 #ifdef CONFIG_WPS_OOB
1849 } else if (os_strncmp(buf
, "WPS_OOB ", 8) == 0) {
1850 if (wpa_supplicant_ctrl_iface_wps_oob(wpa_s
, buf
+ 8))
1852 #endif /* CONFIG_WPS_OOB */
1853 } else if (os_strncmp(buf
, "WPS_REG ", 8) == 0) {
1854 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s
, buf
+ 8))
1856 #ifdef CONFIG_WPS_ER
1857 } else if (os_strcmp(buf
, "WPS_ER_START") == 0) {
1858 if (wpas_wps_er_start(wpa_s
, NULL
))
1860 } else if (os_strncmp(buf
, "WPS_ER_START ", 13) == 0) {
1861 if (wpas_wps_er_start(wpa_s
, buf
+ 13))
1863 } else if (os_strcmp(buf
, "WPS_ER_STOP") == 0) {
1864 if (wpas_wps_er_stop(wpa_s
))
1866 } else if (os_strncmp(buf
, "WPS_ER_PIN ", 11) == 0) {
1867 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s
, buf
+ 11))
1869 } else if (os_strncmp(buf
, "WPS_ER_PBC ", 11) == 0) {
1870 if (wpas_wps_er_pbc(wpa_s
, buf
+ 11))
1872 } else if (os_strncmp(buf
, "WPS_ER_LEARN ", 13) == 0) {
1873 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s
, buf
+ 13))
1875 } else if (os_strncmp(buf
, "WPS_ER_CONFIG ", 14) == 0) {
1876 if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s
, buf
+ 14))
1878 #endif /* CONFIG_WPS_ER */
1879 #endif /* CONFIG_WPS */
1880 #ifdef CONFIG_IBSS_RSN
1881 } else if (os_strncmp(buf
, "IBSS_RSN ", 9) == 0) {
1882 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s
, buf
+ 9))
1884 #endif /* CONFIG_IBSS_RSN */
1885 } else if (os_strncmp(buf
, WPA_CTRL_RSP
, os_strlen(WPA_CTRL_RSP
)) == 0)
1887 if (wpa_supplicant_ctrl_iface_ctrl_rsp(
1888 wpa_s
, buf
+ os_strlen(WPA_CTRL_RSP
)))
1892 } else if (os_strcmp(buf
, "RECONFIGURE") == 0) {
1893 if (wpa_supplicant_reload_configuration(wpa_s
))
1895 } else if (os_strcmp(buf
, "TERMINATE") == 0) {
1896 wpa_supplicant_terminate_proc(wpa_s
->global
);
1897 } else if (os_strncmp(buf
, "BSSID ", 6) == 0) {
1898 if (wpa_supplicant_ctrl_iface_bssid(wpa_s
, buf
+ 6))
1900 } else if (os_strcmp(buf
, "LIST_NETWORKS") == 0) {
1901 reply_len
= wpa_supplicant_ctrl_iface_list_networks(
1902 wpa_s
, reply
, reply_size
);
1903 } else if (os_strcmp(buf
, "DISCONNECT") == 0) {
1904 wpa_s
->reassociate
= 0;
1905 wpa_s
->disconnected
= 1;
1906 wpa_supplicant_deauthenticate(wpa_s
,
1907 WLAN_REASON_DEAUTH_LEAVING
);
1908 } else if (os_strcmp(buf
, "SCAN") == 0) {
1909 if (wpa_s
->wpa_state
== WPA_INTERFACE_DISABLED
)
1912 wpa_s
->scan_req
= 2;
1913 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1915 } else if (os_strcmp(buf
, "SCAN_RESULTS") == 0) {
1916 reply_len
= wpa_supplicant_ctrl_iface_scan_results(
1917 wpa_s
, reply
, reply_size
);
1918 } else if (os_strncmp(buf
, "SELECT_NETWORK ", 15) == 0) {
1919 if (wpa_supplicant_ctrl_iface_select_network(wpa_s
, buf
+ 15))
1921 } else if (os_strncmp(buf
, "ENABLE_NETWORK ", 15) == 0) {
1922 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s
, buf
+ 15))
1924 } else if (os_strncmp(buf
, "DISABLE_NETWORK ", 16) == 0) {
1925 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s
, buf
+ 16))
1927 } else if (os_strcmp(buf
, "ADD_NETWORK") == 0) {
1928 reply_len
= wpa_supplicant_ctrl_iface_add_network(
1929 wpa_s
, reply
, reply_size
);
1930 } else if (os_strncmp(buf
, "REMOVE_NETWORK ", 15) == 0) {
1931 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s
, buf
+ 15))
1933 } else if (os_strncmp(buf
, "SET_NETWORK ", 12) == 0) {
1934 if (wpa_supplicant_ctrl_iface_set_network(wpa_s
, buf
+ 12))
1936 } else if (os_strncmp(buf
, "GET_NETWORK ", 12) == 0) {
1937 reply_len
= wpa_supplicant_ctrl_iface_get_network(
1938 wpa_s
, buf
+ 12, reply
, reply_size
);
1939 #ifndef CONFIG_NO_CONFIG_WRITE
1940 } else if (os_strcmp(buf
, "SAVE_CONFIG") == 0) {
1941 if (wpa_supplicant_ctrl_iface_save_config(wpa_s
))
1943 #endif /* CONFIG_NO_CONFIG_WRITE */
1944 } else if (os_strncmp(buf
, "GET_CAPABILITY ", 15) == 0) {
1945 reply_len
= wpa_supplicant_ctrl_iface_get_capability(
1946 wpa_s
, buf
+ 15, reply
, reply_size
);
1947 } else if (os_strncmp(buf
, "AP_SCAN ", 8) == 0) {
1948 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s
, buf
+ 8))
1950 } else if (os_strcmp(buf
, "INTERFACE_LIST") == 0) {
1951 reply_len
= wpa_supplicant_global_iface_list(
1952 wpa_s
->global
, reply
, reply_size
);
1953 } else if (os_strcmp(buf
, "INTERFACES") == 0) {
1954 reply_len
= wpa_supplicant_global_iface_interfaces(
1955 wpa_s
->global
, reply
, reply_size
);
1956 } else if (os_strncmp(buf
, "BSS ", 4) == 0) {
1957 reply_len
= wpa_supplicant_ctrl_iface_bss(
1958 wpa_s
, buf
+ 4, reply
, reply_size
);
1960 } else if (os_strcmp(buf
, "STA-FIRST") == 0) {
1961 reply_len
= ap_ctrl_iface_sta_first(wpa_s
, reply
, reply_size
);
1962 } else if (os_strncmp(buf
, "STA ", 4) == 0) {
1963 reply_len
= ap_ctrl_iface_sta(wpa_s
, buf
+ 4, reply
,
1965 } else if (os_strncmp(buf
, "STA-NEXT ", 9) == 0) {
1966 reply_len
= ap_ctrl_iface_sta_next(wpa_s
, buf
+ 9, reply
,
1968 #endif /* CONFIG_AP */
1969 } else if (os_strcmp(buf
, "SUSPEND") == 0) {
1970 wpas_notify_suspend(wpa_s
->global
);
1971 } else if (os_strcmp(buf
, "RESUME") == 0) {
1972 wpas_notify_resume(wpa_s
->global
);
1973 } else if (os_strcmp(buf
, "DROP_SA") == 0) {
1974 wpa_supplicant_ctrl_iface_drop_sa(wpa_s
);
1975 } else if (os_strncmp(buf
, "ROAM ", 5) == 0) {
1976 if (wpa_supplicant_ctrl_iface_roam(wpa_s
, buf
+ 5))
1979 os_memcpy(reply
, "UNKNOWN COMMAND\n", 16);
1983 if (reply_len
< 0) {
1984 os_memcpy(reply
, "FAIL\n", 5);
1989 eapol_sm_notify_ctrl_response(wpa_s
->eapol
);
1991 *resp_len
= reply_len
;
1996 static int wpa_supplicant_global_iface_add(struct wpa_global
*global
,
1999 struct wpa_interface iface
;
2003 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
2004 * TAB<bridge_ifname>
2006 wpa_printf(MSG_DEBUG
, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd
);
2008 os_memset(&iface
, 0, sizeof(iface
));
2011 iface
.ifname
= pos
= cmd
;
2012 pos
= os_strchr(pos
, '\t');
2015 if (iface
.ifname
[0] == '\0')
2020 iface
.confname
= pos
;
2021 pos
= os_strchr(pos
, '\t');
2024 if (iface
.confname
[0] == '\0')
2025 iface
.confname
= NULL
;
2030 pos
= os_strchr(pos
, '\t');
2033 if (iface
.driver
[0] == '\0')
2034 iface
.driver
= NULL
;
2038 iface
.ctrl_interface
= pos
;
2039 pos
= os_strchr(pos
, '\t');
2042 if (iface
.ctrl_interface
[0] == '\0')
2043 iface
.ctrl_interface
= NULL
;
2047 iface
.driver_param
= pos
;
2048 pos
= os_strchr(pos
, '\t');
2051 if (iface
.driver_param
[0] == '\0')
2052 iface
.driver_param
= NULL
;
2056 iface
.bridge_ifname
= pos
;
2057 pos
= os_strchr(pos
, '\t');
2060 if (iface
.bridge_ifname
[0] == '\0')
2061 iface
.bridge_ifname
= NULL
;
2066 if (wpa_supplicant_get_iface(global
, iface
.ifname
))
2069 return wpa_supplicant_add_iface(global
, &iface
) ? 0 : -1;
2073 static int wpa_supplicant_global_iface_remove(struct wpa_global
*global
,
2076 struct wpa_supplicant
*wpa_s
;
2078 wpa_printf(MSG_DEBUG
, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd
);
2080 wpa_s
= wpa_supplicant_get_iface(global
, cmd
);
2083 return wpa_supplicant_remove_iface(global
, wpa_s
);
2087 static void wpa_free_iface_info(struct wpa_interface_info
*iface
)
2089 struct wpa_interface_info
*prev
;
2093 iface
= iface
->next
;
2095 os_free(prev
->ifname
);
2096 os_free(prev
->desc
);
2102 static int wpa_supplicant_global_iface_list(struct wpa_global
*global
,
2106 struct wpa_interface_info
*iface
= NULL
, *last
= NULL
, *tmp
;
2109 for (i
= 0; wpa_drivers
[i
]; i
++) {
2110 struct wpa_driver_ops
*drv
= wpa_drivers
[i
];
2111 if (drv
->get_interfaces
== NULL
)
2113 tmp
= drv
->get_interfaces(global
->drv_priv
[i
]);
2127 for (tmp
= iface
; tmp
; tmp
= tmp
->next
) {
2128 res
= os_snprintf(pos
, end
- pos
, "%s\t%s\t%s\n",
2129 tmp
->drv_name
, tmp
->ifname
,
2130 tmp
->desc
? tmp
->desc
: "");
2131 if (res
< 0 || res
>= end
- pos
) {
2138 wpa_free_iface_info(iface
);
2144 static int wpa_supplicant_global_iface_interfaces(struct wpa_global
*global
,
2149 struct wpa_supplicant
*wpa_s
;
2151 wpa_s
= global
->ifaces
;
2156 res
= os_snprintf(pos
, end
- pos
, "%s\n", wpa_s
->ifname
);
2157 if (res
< 0 || res
>= end
- pos
) {
2162 wpa_s
= wpa_s
->next
;
2168 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global
*global
,
2169 char *buf
, size_t *resp_len
)
2172 const int reply_size
= 2048;
2175 wpa_hexdump_ascii(MSG_DEBUG
, "RX global ctrl_iface",
2176 (const u8
*) buf
, os_strlen(buf
));
2178 reply
= os_malloc(reply_size
);
2179 if (reply
== NULL
) {
2184 os_memcpy(reply
, "OK\n", 3);
2187 if (os_strcmp(buf
, "PING") == 0) {
2188 os_memcpy(reply
, "PONG\n", 5);
2190 } else if (os_strncmp(buf
, "INTERFACE_ADD ", 14) == 0) {
2191 if (wpa_supplicant_global_iface_add(global
, buf
+ 14))
2193 } else if (os_strncmp(buf
, "INTERFACE_REMOVE ", 17) == 0) {
2194 if (wpa_supplicant_global_iface_remove(global
, buf
+ 17))
2196 } else if (os_strcmp(buf
, "INTERFACE_LIST") == 0) {
2197 reply_len
= wpa_supplicant_global_iface_list(
2198 global
, reply
, reply_size
);
2199 } else if (os_strcmp(buf
, "INTERFACES") == 0) {
2200 reply_len
= wpa_supplicant_global_iface_interfaces(
2201 global
, reply
, reply_size
);
2202 } else if (os_strcmp(buf
, "TERMINATE") == 0) {
2203 wpa_supplicant_terminate_proc(global
);
2204 } else if (os_strcmp(buf
, "SUSPEND") == 0) {
2205 wpas_notify_suspend(global
);
2206 } else if (os_strcmp(buf
, "RESUME") == 0) {
2207 wpas_notify_resume(global
);
2209 os_memcpy(reply
, "UNKNOWN COMMAND\n", 16);
2213 if (reply_len
< 0) {
2214 os_memcpy(reply
, "FAIL\n", 5);
2218 *resp_len
= reply_len
;