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
)))
90 #ifdef IEEE8021X_EAPOL
91 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant
*wpa_s
,
95 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
97 if (hwaddr_aton(addr
, bssid
)) {
98 wpa_printf(MSG_DEBUG
, "CTRL_IFACE PREAUTH: invalid address "
103 wpa_printf(MSG_DEBUG
, "CTRL_IFACE PREAUTH " MACSTR
, MAC2STR(bssid
));
104 rsn_preauth_deinit(wpa_s
->wpa
);
105 if (rsn_preauth_init(wpa_s
->wpa
, bssid
, ssid
? &ssid
->eap
: NULL
))
110 #endif /* IEEE8021X_EAPOL */
113 #ifdef CONFIG_PEERKEY
114 /* MLME-STKSTART.request(peer) */
115 static int wpa_supplicant_ctrl_iface_stkstart(
116 struct wpa_supplicant
*wpa_s
, char *addr
)
120 if (hwaddr_aton(addr
, peer
)) {
121 wpa_printf(MSG_DEBUG
, "CTRL_IFACE STKSTART: invalid "
122 "address '%s'", addr
);
126 wpa_printf(MSG_DEBUG
, "CTRL_IFACE STKSTART " MACSTR
,
129 return wpa_sm_stkstart(wpa_s
->wpa
, peer
);
131 #endif /* CONFIG_PEERKEY */
134 #ifdef CONFIG_IEEE80211R
135 static int wpa_supplicant_ctrl_iface_ft_ds(
136 struct wpa_supplicant
*wpa_s
, char *addr
)
138 u8 target_ap
[ETH_ALEN
];
142 if (hwaddr_aton(addr
, target_ap
)) {
143 wpa_printf(MSG_DEBUG
, "CTRL_IFACE FT_DS: invalid "
144 "address '%s'", addr
);
148 wpa_printf(MSG_DEBUG
, "CTRL_IFACE FT_DS " MACSTR
, MAC2STR(target_ap
));
150 bss
= wpa_bss_get_bssid(wpa_s
, target_ap
);
152 mdie
= wpa_bss_get_ie(bss
, WLAN_EID_MOBILITY_DOMAIN
);
156 return wpa_ft_start_over_ds(wpa_s
->wpa
, target_ap
, mdie
);
158 #endif /* CONFIG_IEEE80211R */
162 static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant
*wpa_s
,
165 u8 bssid
[ETH_ALEN
], *_bssid
= bssid
;
167 if (cmd
== NULL
|| os_strcmp(cmd
, "any") == 0)
169 else if (hwaddr_aton(cmd
, bssid
)) {
170 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
177 return wpa_supplicant_ap_wps_pbc(wpa_s
, _bssid
);
178 #endif /* CONFIG_AP */
180 return wpas_wps_start_pbc(wpa_s
, _bssid
);
184 static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant
*wpa_s
,
185 char *cmd
, char *buf
,
188 u8 bssid
[ETH_ALEN
], *_bssid
= bssid
;
192 pin
= os_strchr(cmd
, ' ');
196 if (os_strcmp(cmd
, "any") == 0)
198 else if (hwaddr_aton(cmd
, bssid
)) {
199 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
206 return wpa_supplicant_ap_wps_pin(wpa_s
, _bssid
, pin
,
208 #endif /* CONFIG_AP */
211 ret
= wpas_wps_start_pin(wpa_s
, _bssid
, pin
);
214 ret
= os_snprintf(buf
, buflen
, "%s", pin
);
215 if (ret
< 0 || (size_t) ret
>= buflen
)
220 ret
= wpas_wps_start_pin(wpa_s
, _bssid
, NULL
);
224 /* Return the generated PIN */
225 ret
= os_snprintf(buf
, buflen
, "%08d", ret
);
226 if (ret
< 0 || (size_t) ret
>= buflen
)
232 #ifdef CONFIG_WPS_OOB
233 static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant
*wpa_s
,
236 char *path
, *method
, *name
;
238 path
= os_strchr(cmd
, ' ');
243 method
= os_strchr(path
, ' ');
248 name
= os_strchr(method
, ' ');
252 return wpas_wps_start_oob(wpa_s
, cmd
, path
, method
, name
);
254 #endif /* CONFIG_WPS_OOB */
257 static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant
*wpa_s
,
260 u8 bssid
[ETH_ALEN
], *_bssid
= bssid
;
266 struct wps_new_ap_settings ap
;
268 pin
= os_strchr(cmd
, ' ');
273 if (os_strcmp(cmd
, "any") == 0)
275 else if (hwaddr_aton(cmd
, bssid
)) {
276 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_REG: invalid BSSID '%s'",
281 new_ssid
= os_strchr(pin
, ' ');
282 if (new_ssid
== NULL
)
283 return wpas_wps_start_reg(wpa_s
, _bssid
, pin
, NULL
);
286 new_auth
= os_strchr(new_ssid
, ' ');
287 if (new_auth
== NULL
)
291 new_encr
= os_strchr(new_auth
, ' ');
292 if (new_encr
== NULL
)
296 new_key
= os_strchr(new_encr
, ' ');
301 os_memset(&ap
, 0, sizeof(ap
));
302 ap
.ssid_hex
= new_ssid
;
305 ap
.key_hex
= new_key
;
306 return wpas_wps_start_reg(wpa_s
, _bssid
, pin
, &ap
);
311 static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant
*wpa_s
,
314 char *uuid
= cmd
, *pin
;
315 pin
= os_strchr(uuid
, ' ');
319 return wpas_wps_er_add_pin(wpa_s
, uuid
, pin
);
323 static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant
*wpa_s
,
326 char *uuid
= cmd
, *pin
;
327 pin
= os_strchr(uuid
, ' ');
331 return wpas_wps_er_learn(wpa_s
, uuid
, pin
);
333 #endif /* CONFIG_WPS_ER */
335 #endif /* CONFIG_WPS */
338 #ifdef CONFIG_IBSS_RSN
339 static int wpa_supplicant_ctrl_iface_ibss_rsn(
340 struct wpa_supplicant
*wpa_s
, char *addr
)
344 if (hwaddr_aton(addr
, peer
)) {
345 wpa_printf(MSG_DEBUG
, "CTRL_IFACE IBSS_RSN: invalid "
346 "address '%s'", addr
);
350 wpa_printf(MSG_DEBUG
, "CTRL_IFACE IBSS_RSN " MACSTR
,
353 return ibss_rsn_start(wpa_s
->ibss_rsn
, peer
);
355 #endif /* CONFIG_IBSS_RSN */
358 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant
*wpa_s
,
361 #ifdef IEEE8021X_EAPOL
364 struct wpa_ssid
*ssid
;
365 struct eap_peer_config
*eap
;
367 pos
= os_strchr(rsp
, '-');
372 pos
= os_strchr(pos
, ':');
377 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: field=%s id=%d", rsp
, id
);
378 wpa_hexdump_ascii_key(MSG_DEBUG
, "CTRL_IFACE: value",
379 (u8
*) pos
, os_strlen(pos
));
381 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
383 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
389 if (os_strcmp(rsp
, "IDENTITY") == 0) {
390 os_free(eap
->identity
);
391 eap
->identity
= (u8
*) os_strdup(pos
);
392 eap
->identity_len
= os_strlen(pos
);
393 eap
->pending_req_identity
= 0;
394 if (ssid
== wpa_s
->current_ssid
)
395 wpa_s
->reassociate
= 1;
396 } else if (os_strcmp(rsp
, "PASSWORD") == 0) {
397 os_free(eap
->password
);
398 eap
->password
= (u8
*) os_strdup(pos
);
399 eap
->password_len
= os_strlen(pos
);
400 eap
->pending_req_password
= 0;
401 if (ssid
== wpa_s
->current_ssid
)
402 wpa_s
->reassociate
= 1;
403 } else if (os_strcmp(rsp
, "NEW_PASSWORD") == 0) {
404 os_free(eap
->new_password
);
405 eap
->new_password
= (u8
*) os_strdup(pos
);
406 eap
->new_password_len
= os_strlen(pos
);
407 eap
->pending_req_new_password
= 0;
408 if (ssid
== wpa_s
->current_ssid
)
409 wpa_s
->reassociate
= 1;
410 } else if (os_strcmp(rsp
, "PIN") == 0) {
412 eap
->pin
= os_strdup(pos
);
413 eap
->pending_req_pin
= 0;
414 if (ssid
== wpa_s
->current_ssid
)
415 wpa_s
->reassociate
= 1;
416 } else if (os_strcmp(rsp
, "OTP") == 0) {
418 eap
->otp
= (u8
*) os_strdup(pos
);
419 eap
->otp_len
= os_strlen(pos
);
420 os_free(eap
->pending_req_otp
);
421 eap
->pending_req_otp
= NULL
;
422 eap
->pending_req_otp_len
= 0;
423 } else if (os_strcmp(rsp
, "PASSPHRASE") == 0) {
424 os_free(eap
->private_key_passwd
);
425 eap
->private_key_passwd
= (u8
*) os_strdup(pos
);
426 eap
->pending_req_passphrase
= 0;
427 if (ssid
== wpa_s
->current_ssid
)
428 wpa_s
->reassociate
= 1;
430 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Unknown field '%s'", rsp
);
435 #else /* IEEE8021X_EAPOL */
436 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: 802.1X not included");
438 #endif /* IEEE8021X_EAPOL */
442 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant
*wpa_s
,
444 char *buf
, size_t buflen
)
446 char *pos
, *end
, tmp
[30];
447 int res
, verbose
, ret
;
449 verbose
= os_strcmp(params
, "-VERBOSE") == 0;
452 if (wpa_s
->wpa_state
>= WPA_ASSOCIATED
) {
453 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
454 ret
= os_snprintf(pos
, end
- pos
, "bssid=" MACSTR
"\n",
455 MAC2STR(wpa_s
->bssid
));
456 if (ret
< 0 || ret
>= end
- pos
)
460 u8
*_ssid
= ssid
->ssid
;
461 size_t ssid_len
= ssid
->ssid_len
;
462 u8 ssid_buf
[MAX_SSID_LEN
];
464 int _res
= wpa_drv_get_ssid(wpa_s
, ssid_buf
);
471 ret
= os_snprintf(pos
, end
- pos
, "ssid=%s\nid=%d\n",
472 wpa_ssid_txt(_ssid
, ssid_len
),
474 if (ret
< 0 || ret
>= end
- pos
)
479 ret
= os_snprintf(pos
, end
- pos
,
482 if (ret
< 0 || ret
>= end
- pos
)
487 switch (ssid
->mode
) {
488 case WPAS_MODE_INFRA
:
489 ret
= os_snprintf(pos
, end
- pos
,
493 ret
= os_snprintf(pos
, end
- pos
,
497 ret
= os_snprintf(pos
, end
- pos
,
504 if (ret
< 0 || ret
>= end
- pos
)
510 if (wpa_s
->ap_iface
) {
511 pos
+= ap_ctrl_iface_wpa_get_status(wpa_s
, pos
,
515 #endif /* CONFIG_AP */
516 pos
+= wpa_sm_get_status(wpa_s
->wpa
, pos
, end
- pos
, verbose
);
518 ret
= os_snprintf(pos
, end
- pos
, "wpa_state=%s\n",
519 wpa_supplicant_state_txt(wpa_s
->wpa_state
));
520 if (ret
< 0 || ret
>= end
- pos
)
525 l2_packet_get_ip_addr(wpa_s
->l2
, tmp
, sizeof(tmp
)) >= 0) {
526 ret
= os_snprintf(pos
, end
- pos
, "ip_address=%s\n", tmp
);
527 if (ret
< 0 || ret
>= end
- pos
)
532 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s
->key_mgmt
) ||
533 wpa_s
->key_mgmt
== WPA_KEY_MGMT_IEEE8021X_NO_WPA
) {
534 res
= eapol_sm_get_status(wpa_s
->eapol
, pos
, end
- pos
,
540 res
= rsn_preauth_get_status(wpa_s
->wpa
, pos
, end
- pos
, verbose
);
548 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant
*wpa_s
,
553 struct wpa_ssid
*ssid
;
556 /* cmd: "<network id> <BSSID>" */
557 pos
= os_strchr(cmd
, ' ');
562 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: id=%d bssid='%s'", id
, pos
);
563 if (hwaddr_aton(pos
, bssid
)) {
564 wpa_printf(MSG_DEBUG
,"CTRL_IFACE: invalid BSSID '%s'", pos
);
568 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
570 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
575 os_memcpy(ssid
->bssid
, bssid
, ETH_ALEN
);
576 ssid
->bssid_set
= !is_zero_ether_addr(bssid
);
582 static int wpa_supplicant_ctrl_iface_list_networks(
583 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
586 struct wpa_ssid
*ssid
;
591 ret
= os_snprintf(pos
, end
- pos
,
592 "network id / ssid / bssid / flags\n");
593 if (ret
< 0 || ret
>= end
- pos
)
597 ssid
= wpa_s
->conf
->ssid
;
599 ret
= os_snprintf(pos
, end
- pos
, "%d\t%s",
601 wpa_ssid_txt(ssid
->ssid
, ssid
->ssid_len
));
602 if (ret
< 0 || ret
>= end
- pos
)
605 if (ssid
->bssid_set
) {
606 ret
= os_snprintf(pos
, end
- pos
, "\t" MACSTR
,
607 MAC2STR(ssid
->bssid
));
609 ret
= os_snprintf(pos
, end
- pos
, "\tany");
611 if (ret
< 0 || ret
>= end
- pos
)
614 ret
= os_snprintf(pos
, end
- pos
, "\t%s%s",
615 ssid
== wpa_s
->current_ssid
?
617 ssid
->disabled
? "[DISABLED]" : "");
618 if (ret
< 0 || ret
>= end
- pos
)
621 ret
= os_snprintf(pos
, end
- pos
, "\n");
622 if (ret
< 0 || ret
>= end
- pos
)
633 static char * wpa_supplicant_cipher_txt(char *pos
, char *end
, int cipher
)
636 ret
= os_snprintf(pos
, end
- pos
, "-");
637 if (ret
< 0 || ret
>= end
- pos
)
640 if (cipher
& WPA_CIPHER_NONE
) {
641 ret
= os_snprintf(pos
, end
- pos
, "%sNONE", first
? "" : "+");
642 if (ret
< 0 || ret
>= end
- pos
)
647 if (cipher
& WPA_CIPHER_WEP40
) {
648 ret
= os_snprintf(pos
, end
- pos
, "%sWEP40", first
? "" : "+");
649 if (ret
< 0 || ret
>= end
- pos
)
654 if (cipher
& WPA_CIPHER_WEP104
) {
655 ret
= os_snprintf(pos
, end
- pos
, "%sWEP104",
657 if (ret
< 0 || ret
>= end
- pos
)
662 if (cipher
& WPA_CIPHER_TKIP
) {
663 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : "+");
664 if (ret
< 0 || ret
>= end
- pos
)
669 if (cipher
& WPA_CIPHER_CCMP
) {
670 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : "+");
671 if (ret
< 0 || ret
>= end
- pos
)
680 static char * wpa_supplicant_ie_txt(char *pos
, char *end
, const char *proto
,
681 const u8
*ie
, size_t ie_len
)
683 struct wpa_ie_data data
;
686 ret
= os_snprintf(pos
, end
- pos
, "[%s-", proto
);
687 if (ret
< 0 || ret
>= end
- pos
)
691 if (wpa_parse_wpa_ie(ie
, ie_len
, &data
) < 0) {
692 ret
= os_snprintf(pos
, end
- pos
, "?]");
693 if (ret
< 0 || ret
>= end
- pos
)
700 if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X
) {
701 ret
= os_snprintf(pos
, end
- pos
, "%sEAP", first
? "" : "+");
702 if (ret
< 0 || ret
>= end
- pos
)
707 if (data
.key_mgmt
& WPA_KEY_MGMT_PSK
) {
708 ret
= os_snprintf(pos
, end
- pos
, "%sPSK", first
? "" : "+");
709 if (ret
< 0 || ret
>= end
- pos
)
714 if (data
.key_mgmt
& WPA_KEY_MGMT_WPA_NONE
) {
715 ret
= os_snprintf(pos
, end
- pos
, "%sNone", first
? "" : "+");
716 if (ret
< 0 || ret
>= end
- pos
)
721 #ifdef CONFIG_IEEE80211R
722 if (data
.key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
) {
723 ret
= os_snprintf(pos
, end
- pos
, "%sFT/EAP",
725 if (ret
< 0 || ret
>= end
- pos
)
730 if (data
.key_mgmt
& WPA_KEY_MGMT_FT_PSK
) {
731 ret
= os_snprintf(pos
, end
- pos
, "%sFT/PSK",
733 if (ret
< 0 || ret
>= end
- pos
)
738 #endif /* CONFIG_IEEE80211R */
739 #ifdef CONFIG_IEEE80211W
740 if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
) {
741 ret
= os_snprintf(pos
, end
- pos
, "%sEAP-SHA256",
743 if (ret
< 0 || ret
>= end
- pos
)
748 if (data
.key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
) {
749 ret
= os_snprintf(pos
, end
- pos
, "%sPSK-SHA256",
751 if (ret
< 0 || ret
>= end
- pos
)
756 #endif /* CONFIG_IEEE80211W */
758 pos
= wpa_supplicant_cipher_txt(pos
, end
, data
.pairwise_cipher
);
760 if (data
.capabilities
& WPA_CAPABILITY_PREAUTH
) {
761 ret
= os_snprintf(pos
, end
- pos
, "-preauth");
762 if (ret
< 0 || ret
>= end
- pos
)
767 ret
= os_snprintf(pos
, end
- pos
, "]");
768 if (ret
< 0 || ret
>= end
- pos
)
777 static char * wpa_supplicant_wps_ie_txt_buf(char *pos
, char *end
,
778 struct wpabuf
*wps_ie
)
785 if (wps_is_selected_pbc_registrar(wps_ie
))
787 else if (wps_is_selected_pin_registrar(wps_ie
))
792 ret
= os_snprintf(pos
, end
- pos
, "%s", txt
);
793 if (ret
>= 0 && ret
< end
- pos
)
798 #endif /* CONFIG_WPS */
801 static char * wpa_supplicant_wps_ie_txt(char *pos
, char *end
,
802 const struct wpa_bss
*bss
)
805 struct wpabuf
*wps_ie
;
806 wps_ie
= wpa_bss_get_vendor_ie_multi(bss
, WPS_IE_VENDOR_TYPE
);
807 return wpa_supplicant_wps_ie_txt_buf(pos
, end
, wps_ie
);
808 #else /* CONFIG_WPS */
810 #endif /* CONFIG_WPS */
814 /* Format one result on one text line into a buffer. */
815 static int wpa_supplicant_ctrl_iface_scan_result(
816 const struct wpa_bss
*bss
, char *buf
, size_t buflen
)
825 ret
= os_snprintf(pos
, end
- pos
, MACSTR
"\t%d\t%d\t",
826 MAC2STR(bss
->bssid
), bss
->freq
, bss
->level
);
827 if (ret
< 0 || ret
>= end
- pos
)
830 ie
= wpa_bss_get_vendor_ie(bss
, WPA_IE_VENDOR_TYPE
);
832 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA", ie
, 2 + ie
[1]);
833 ie2
= wpa_bss_get_ie(bss
, WLAN_EID_RSN
);
835 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA2", ie2
, 2 + ie2
[1]);
836 pos
= wpa_supplicant_wps_ie_txt(pos
, end
, bss
);
837 if (!ie
&& !ie2
&& bss
->caps
& IEEE80211_CAP_PRIVACY
) {
838 ret
= os_snprintf(pos
, end
- pos
, "[WEP]");
839 if (ret
< 0 || ret
>= end
- pos
)
843 if (bss
->caps
& IEEE80211_CAP_IBSS
) {
844 ret
= os_snprintf(pos
, end
- pos
, "[IBSS]");
845 if (ret
< 0 || ret
>= end
- pos
)
849 if (bss
->caps
& IEEE80211_CAP_ESS
) {
850 ret
= os_snprintf(pos
, end
- pos
, "[ESS]");
851 if (ret
< 0 || ret
>= end
- pos
)
856 ret
= os_snprintf(pos
, end
- pos
, "\t%s",
857 wpa_ssid_txt(bss
->ssid
, bss
->ssid_len
));
858 if (ret
< 0 || ret
>= end
- pos
)
862 ret
= os_snprintf(pos
, end
- pos
, "\n");
863 if (ret
< 0 || ret
>= end
- pos
)
871 static int wpa_supplicant_ctrl_iface_scan_results(
872 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
880 ret
= os_snprintf(pos
, end
- pos
, "bssid / frequency / signal level / "
882 if (ret
< 0 || ret
>= end
- pos
)
886 dl_list_for_each(bss
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
) {
887 ret
= wpa_supplicant_ctrl_iface_scan_result(bss
, pos
,
889 if (ret
< 0 || ret
>= end
- pos
)
898 static int wpa_supplicant_ctrl_iface_select_network(
899 struct wpa_supplicant
*wpa_s
, char *cmd
)
902 struct wpa_ssid
*ssid
;
904 /* cmd: "<network id>" or "any" */
905 if (os_strcmp(cmd
, "any") == 0) {
906 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SELECT_NETWORK any");
910 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SELECT_NETWORK id=%d", id
);
912 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
914 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
915 "network id=%d", id
);
920 wpa_supplicant_select_network(wpa_s
, ssid
);
926 static int wpa_supplicant_ctrl_iface_enable_network(
927 struct wpa_supplicant
*wpa_s
, char *cmd
)
930 struct wpa_ssid
*ssid
;
932 /* cmd: "<network id>" or "all" */
933 if (os_strcmp(cmd
, "all") == 0) {
934 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ENABLE_NETWORK all");
938 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ENABLE_NETWORK id=%d", id
);
940 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
942 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
943 "network id=%d", id
);
947 wpa_supplicant_enable_network(wpa_s
, ssid
);
953 static int wpa_supplicant_ctrl_iface_disable_network(
954 struct wpa_supplicant
*wpa_s
, char *cmd
)
957 struct wpa_ssid
*ssid
;
959 /* cmd: "<network id>" or "all" */
960 if (os_strcmp(cmd
, "all") == 0) {
961 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: DISABLE_NETWORK all");
965 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: DISABLE_NETWORK id=%d", id
);
967 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
969 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
970 "network id=%d", id
);
974 wpa_supplicant_disable_network(wpa_s
, ssid
);
980 static int wpa_supplicant_ctrl_iface_add_network(
981 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
983 struct wpa_ssid
*ssid
;
986 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ADD_NETWORK");
988 ssid
= wpa_config_add_network(wpa_s
->conf
);
992 wpas_notify_network_added(wpa_s
, ssid
);
995 wpa_config_set_network_defaults(ssid
);
997 ret
= os_snprintf(buf
, buflen
, "%d\n", ssid
->id
);
998 if (ret
< 0 || (size_t) ret
>= buflen
)
1004 static int wpa_supplicant_ctrl_iface_remove_network(
1005 struct wpa_supplicant
*wpa_s
, char *cmd
)
1008 struct wpa_ssid
*ssid
;
1010 /* cmd: "<network id>" or "all" */
1011 if (os_strcmp(cmd
, "all") == 0) {
1012 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_NETWORK all");
1013 ssid
= wpa_s
->conf
->ssid
;
1015 struct wpa_ssid
*remove_ssid
= ssid
;
1018 wpas_notify_network_removed(wpa_s
, remove_ssid
);
1019 wpa_config_remove_network(wpa_s
->conf
, id
);
1021 if (wpa_s
->current_ssid
) {
1022 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
1023 wpa_supplicant_disassociate(wpa_s
,
1024 WLAN_REASON_DEAUTH_LEAVING
);
1030 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_NETWORK id=%d", id
);
1032 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1034 wpa_config_remove_network(wpa_s
->conf
, id
) < 0) {
1035 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
1040 if (ssid
== wpa_s
->current_ssid
) {
1042 * Invalidate the EAP session cache if the current network is
1045 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
1047 wpa_supplicant_disassociate(wpa_s
, WLAN_REASON_DEAUTH_LEAVING
);
1054 static int wpa_supplicant_ctrl_iface_set_network(
1055 struct wpa_supplicant
*wpa_s
, char *cmd
)
1058 struct wpa_ssid
*ssid
;
1061 /* cmd: "<network id> <variable name> <value>" */
1062 name
= os_strchr(cmd
, ' ');
1067 value
= os_strchr(name
, ' ');
1073 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
1075 wpa_hexdump_ascii_key(MSG_DEBUG
, "CTRL_IFACE: value",
1076 (u8
*) value
, os_strlen(value
));
1078 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1080 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
1085 if (wpa_config_set(ssid
, name
, value
, 0) < 0) {
1086 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Failed to set network "
1087 "variable '%s'", name
);
1091 if (wpa_s
->current_ssid
== ssid
) {
1093 * Invalidate the EAP session cache if anything in the current
1094 * configuration changes.
1096 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
1099 if ((os_strcmp(name
, "psk") == 0 &&
1100 value
[0] == '"' && ssid
->ssid_len
) ||
1101 (os_strcmp(name
, "ssid") == 0 && ssid
->passphrase
))
1102 wpa_config_update_psk(ssid
);
1103 else if (os_strcmp(name
, "priority") == 0)
1104 wpa_config_update_prio_list(wpa_s
->conf
);
1110 static int wpa_supplicant_ctrl_iface_get_network(
1111 struct wpa_supplicant
*wpa_s
, char *cmd
, char *buf
, size_t buflen
)
1115 struct wpa_ssid
*ssid
;
1118 /* cmd: "<network id> <variable name>" */
1119 name
= os_strchr(cmd
, ' ');
1120 if (name
== NULL
|| buflen
== 0)
1125 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
1128 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1130 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
1135 value
= wpa_config_get_no_key(ssid
, name
);
1136 if (value
== NULL
) {
1137 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Failed to get network "
1138 "variable '%s'", name
);
1142 res
= os_strlcpy(buf
, value
, buflen
);
1143 if (res
>= buflen
) {
1154 #ifndef CONFIG_NO_CONFIG_WRITE
1155 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant
*wpa_s
)
1159 if (!wpa_s
->conf
->update_config
) {
1160 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
1161 "to update configuration (update_config=0)");
1165 ret
= wpa_config_write(wpa_s
->confname
, wpa_s
->conf
);
1167 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Failed to "
1168 "update configuration");
1170 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Configuration"
1176 #endif /* CONFIG_NO_CONFIG_WRITE */
1179 static int ctrl_iface_get_capability_pairwise(int res
, char *strict
,
1180 struct wpa_driver_capa
*capa
,
1181 char *buf
, size_t buflen
)
1193 len
= os_strlcpy(buf
, "CCMP TKIP NONE", buflen
);
1199 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
1200 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : " ");
1201 if (ret
< 0 || ret
>= end
- pos
)
1207 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
1208 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : " ");
1209 if (ret
< 0 || ret
>= end
- pos
)
1215 if (capa
->key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
1216 ret
= os_snprintf(pos
, end
- pos
, "%sNONE", first
? "" : " ");
1217 if (ret
< 0 || ret
>= end
- pos
)
1227 static int ctrl_iface_get_capability_group(int res
, char *strict
,
1228 struct wpa_driver_capa
*capa
,
1229 char *buf
, size_t buflen
)
1241 len
= os_strlcpy(buf
, "CCMP TKIP WEP104 WEP40", buflen
);
1247 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
1248 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : " ");
1249 if (ret
< 0 || ret
>= end
- pos
)
1255 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
1256 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : " ");
1257 if (ret
< 0 || ret
>= end
- pos
)
1263 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_WEP104
) {
1264 ret
= os_snprintf(pos
, end
- pos
, "%sWEP104",
1266 if (ret
< 0 || ret
>= end
- pos
)
1272 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_WEP40
) {
1273 ret
= os_snprintf(pos
, end
- pos
, "%sWEP40", first
? "" : " ");
1274 if (ret
< 0 || ret
>= end
- pos
)
1284 static int ctrl_iface_get_capability_key_mgmt(int res
, char *strict
,
1285 struct wpa_driver_capa
*capa
,
1286 char *buf
, size_t buflen
)
1298 len
= os_strlcpy(buf
, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE "
1305 ret
= os_snprintf(pos
, end
- pos
, "NONE IEEE8021X");
1306 if (ret
< 0 || ret
>= end
- pos
)
1310 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
1311 WPA_DRIVER_CAPA_KEY_MGMT_WPA2
)) {
1312 ret
= os_snprintf(pos
, end
- pos
, " WPA-EAP");
1313 if (ret
< 0 || ret
>= end
- pos
)
1318 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
|
1319 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
1320 ret
= os_snprintf(pos
, end
- pos
, " WPA-PSK");
1321 if (ret
< 0 || ret
>= end
- pos
)
1326 if (capa
->key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
1327 ret
= os_snprintf(pos
, end
- pos
, " WPA-NONE");
1328 if (ret
< 0 || ret
>= end
- pos
)
1337 static int ctrl_iface_get_capability_proto(int res
, char *strict
,
1338 struct wpa_driver_capa
*capa
,
1339 char *buf
, size_t buflen
)
1351 len
= os_strlcpy(buf
, "RSN WPA", buflen
);
1357 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA2
|
1358 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
1359 ret
= os_snprintf(pos
, end
- pos
, "%sRSN", first
? "" : " ");
1360 if (ret
< 0 || ret
>= end
- pos
)
1366 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
1367 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
)) {
1368 ret
= os_snprintf(pos
, end
- pos
, "%sWPA", first
? "" : " ");
1369 if (ret
< 0 || ret
>= end
- pos
)
1379 static int ctrl_iface_get_capability_auth_alg(int res
, char *strict
,
1380 struct wpa_driver_capa
*capa
,
1381 char *buf
, size_t buflen
)
1393 len
= os_strlcpy(buf
, "OPEN SHARED LEAP", buflen
);
1399 if (capa
->auth
& (WPA_DRIVER_AUTH_OPEN
)) {
1400 ret
= os_snprintf(pos
, end
- pos
, "%sOPEN", first
? "" : " ");
1401 if (ret
< 0 || ret
>= end
- pos
)
1407 if (capa
->auth
& (WPA_DRIVER_AUTH_SHARED
)) {
1408 ret
= os_snprintf(pos
, end
- pos
, "%sSHARED",
1410 if (ret
< 0 || ret
>= end
- pos
)
1416 if (capa
->auth
& (WPA_DRIVER_AUTH_LEAP
)) {
1417 ret
= os_snprintf(pos
, end
- pos
, "%sLEAP", first
? "" : " ");
1418 if (ret
< 0 || ret
>= end
- pos
)
1428 static int wpa_supplicant_ctrl_iface_get_capability(
1429 struct wpa_supplicant
*wpa_s
, const char *_field
, char *buf
,
1432 struct wpa_driver_capa capa
;
1438 /* Determine whether or not strict checking was requested */
1439 len
= os_strlcpy(field
, _field
, sizeof(field
));
1440 if (len
>= sizeof(field
))
1442 strict
= os_strchr(field
, ' ');
1443 if (strict
!= NULL
) {
1445 if (os_strcmp(strict
, "strict") != 0)
1449 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
1450 field
, strict
? strict
: "");
1452 if (os_strcmp(field
, "eap") == 0) {
1453 return eap_get_names(buf
, buflen
);
1456 res
= wpa_drv_get_capa(wpa_s
, &capa
);
1458 if (os_strcmp(field
, "pairwise") == 0)
1459 return ctrl_iface_get_capability_pairwise(res
, strict
, &capa
,
1462 if (os_strcmp(field
, "group") == 0)
1463 return ctrl_iface_get_capability_group(res
, strict
, &capa
,
1466 if (os_strcmp(field
, "key_mgmt") == 0)
1467 return ctrl_iface_get_capability_key_mgmt(res
, strict
, &capa
,
1470 if (os_strcmp(field
, "proto") == 0)
1471 return ctrl_iface_get_capability_proto(res
, strict
, &capa
,
1474 if (os_strcmp(field
, "auth_alg") == 0)
1475 return ctrl_iface_get_capability_auth_alg(res
, strict
, &capa
,
1478 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
1485 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant
*wpa_s
,
1486 const char *cmd
, char *buf
,
1491 struct wpa_bss
*bss
;
1496 if (os_strcmp(cmd
, "FIRST") == 0)
1497 bss
= dl_list_first(&wpa_s
->bss
, struct wpa_bss
, list
);
1498 else if (os_strncmp(cmd
, "ID-", 3) == 0) {
1500 bss
= wpa_bss_get_id(wpa_s
, i
);
1501 } else if (os_strncmp(cmd
, "NEXT-", 5) == 0) {
1503 bss
= wpa_bss_get_id(wpa_s
, i
);
1505 struct dl_list
*next
= bss
->list_id
.next
;
1506 if (next
== &wpa_s
->bss_id
)
1509 bss
= dl_list_entry(next
, struct wpa_bss
,
1512 } else if (hwaddr_aton(cmd
, bssid
) == 0)
1513 bss
= wpa_bss_get_bssid(wpa_s
, bssid
);
1515 struct wpa_bss
*tmp
;
1518 dl_list_for_each(tmp
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
)
1532 ret
= os_snprintf(pos
, end
- pos
,
1534 "bssid=" MACSTR
"\n"
1537 "capabilities=0x%04x\n"
1544 MAC2STR(bss
->bssid
), bss
->freq
, bss
->beacon_int
,
1545 bss
->caps
, bss
->qual
, bss
->noise
, bss
->level
,
1546 (unsigned long long) bss
->tsf
);
1547 if (ret
< 0 || ret
>= end
- pos
)
1551 ie
= (const u8
*) (bss
+ 1);
1552 for (i
= 0; i
< bss
->ie_len
; i
++) {
1553 ret
= os_snprintf(pos
, end
- pos
, "%02x", *ie
++);
1554 if (ret
< 0 || ret
>= end
- pos
)
1559 ret
= os_snprintf(pos
, end
- pos
, "\n");
1560 if (ret
< 0 || ret
>= end
- pos
)
1564 ret
= os_snprintf(pos
, end
- pos
, "flags=");
1565 if (ret
< 0 || ret
>= end
- pos
)
1569 ie
= wpa_bss_get_vendor_ie(bss
, WPA_IE_VENDOR_TYPE
);
1571 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA", ie
, 2 + ie
[1]);
1572 ie2
= wpa_bss_get_ie(bss
, WLAN_EID_RSN
);
1574 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA2", ie2
, 2 + ie2
[1]);
1575 pos
= wpa_supplicant_wps_ie_txt(pos
, end
, bss
);
1576 if (!ie
&& !ie2
&& bss
->caps
& IEEE80211_CAP_PRIVACY
) {
1577 ret
= os_snprintf(pos
, end
- pos
, "[WEP]");
1578 if (ret
< 0 || ret
>= end
- pos
)
1582 if (bss
->caps
& IEEE80211_CAP_IBSS
) {
1583 ret
= os_snprintf(pos
, end
- pos
, "[IBSS]");
1584 if (ret
< 0 || ret
>= end
- pos
)
1588 if (bss
->caps
& IEEE80211_CAP_ESS
) {
1589 ret
= os_snprintf(pos
, end
- pos
, "[ESS]");
1590 if (ret
< 0 || ret
>= end
- pos
)
1595 ret
= os_snprintf(pos
, end
- pos
, "\n");
1596 if (ret
< 0 || ret
>= end
- pos
)
1600 ret
= os_snprintf(pos
, end
- pos
, "ssid=%s\n",
1601 wpa_ssid_txt(bss
->ssid
, bss
->ssid_len
));
1602 if (ret
< 0 || ret
>= end
- pos
)
1607 ie
= (const u8
*) (bss
+ 1);
1608 ret
= wpas_wps_scan_result_text(ie
, bss
->ie_len
, pos
, end
);
1609 if (ret
< 0 || ret
>= end
- pos
)
1612 #endif /* CONFIG_WPS */
1618 static int wpa_supplicant_ctrl_iface_ap_scan(
1619 struct wpa_supplicant
*wpa_s
, char *cmd
)
1621 int ap_scan
= atoi(cmd
);
1622 return wpa_supplicant_set_ap_scan(wpa_s
, ap_scan
);
1626 static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant
*wpa_s
)
1628 u8
*bcast
= (u8
*) "\xff\xff\xff\xff\xff\xff";
1630 wpa_printf(MSG_DEBUG
, "Dropping SA without deauthentication");
1631 /* MLME-DELETEKEYS.request */
1632 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 0, 0, NULL
, 0, NULL
, 0);
1633 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 1, 0, NULL
, 0, NULL
, 0);
1634 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 2, 0, NULL
, 0, NULL
, 0);
1635 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 3, 0, NULL
, 0, NULL
, 0);
1636 #ifdef CONFIG_IEEE80211W
1637 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 4, 0, NULL
, 0, NULL
, 0);
1638 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 5, 0, NULL
, 0, NULL
, 0);
1639 #endif /* CONFIG_IEEE80211W */
1641 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, wpa_s
->bssid
, 0, 0, NULL
, 0, NULL
,
1643 /* MLME-SETPROTECTION.request(None) */
1644 wpa_drv_mlme_setprotection(wpa_s
, wpa_s
->bssid
,
1645 MLME_SETPROTECTION_PROTECT_TYPE_NONE
,
1646 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE
);
1647 wpa_sm_drop_sa(wpa_s
->wpa
);
1651 static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant
*wpa_s
,
1655 struct wpa_bss
*bss
;
1656 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
1658 if (hwaddr_aton(addr
, bssid
)) {
1659 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM: invalid "
1660 "address '%s'", addr
);
1664 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM " MACSTR
, MAC2STR(bssid
));
1666 bss
= wpa_bss_get_bssid(wpa_s
, bssid
);
1668 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM: Target AP not found "
1674 * TODO: Find best network configuration block from configuration to
1675 * allow roaming to other networks
1679 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM: No network "
1680 "configuration known for the target AP");
1684 wpa_s
->reassociate
= 1;
1685 wpa_supplicant_connect(wpa_s
, bss
, ssid
);
1691 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant
*wpa_s
,
1692 char *buf
, size_t *resp_len
)
1695 const int reply_size
= 2048;
1699 if (os_strncmp(buf
, WPA_CTRL_RSP
, os_strlen(WPA_CTRL_RSP
)) == 0 ||
1700 os_strncmp(buf
, "SET_NETWORK ", 12) == 0) {
1701 wpa_hexdump_ascii_key(MSG_DEBUG
, "RX ctrl_iface",
1702 (const u8
*) buf
, os_strlen(buf
));
1704 wpa_hexdump_ascii(MSG_DEBUG
, "RX ctrl_iface",
1705 (const u8
*) buf
, os_strlen(buf
));
1708 reply
= os_malloc(reply_size
);
1709 if (reply
== NULL
) {
1714 os_memcpy(reply
, "OK\n", 3);
1717 if (os_strcmp(buf
, "PING") == 0) {
1718 os_memcpy(reply
, "PONG\n", 5);
1720 } else if (os_strcmp(buf
, "MIB") == 0) {
1721 reply_len
= wpa_sm_get_mib(wpa_s
->wpa
, reply
, reply_size
);
1722 if (reply_len
>= 0) {
1724 res
= eapol_sm_get_mib(wpa_s
->eapol
, reply
+ reply_len
,
1725 reply_size
- reply_len
);
1731 } else if (os_strncmp(buf
, "STATUS", 6) == 0) {
1732 reply_len
= wpa_supplicant_ctrl_iface_status(
1733 wpa_s
, buf
+ 6, reply
, reply_size
);
1734 } else if (os_strcmp(buf
, "PMKSA") == 0) {
1735 reply_len
= wpa_sm_pmksa_cache_list(wpa_s
->wpa
, reply
,
1737 } else if (os_strncmp(buf
, "SET ", 4) == 0) {
1738 if (wpa_supplicant_ctrl_iface_set(wpa_s
, buf
+ 4))
1740 } else if (os_strcmp(buf
, "LOGON") == 0) {
1741 eapol_sm_notify_logoff(wpa_s
->eapol
, FALSE
);
1742 } else if (os_strcmp(buf
, "LOGOFF") == 0) {
1743 eapol_sm_notify_logoff(wpa_s
->eapol
, TRUE
);
1744 } else if (os_strcmp(buf
, "REASSOCIATE") == 0) {
1745 wpa_s
->disconnected
= 0;
1746 wpa_s
->reassociate
= 1;
1747 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1748 } else if (os_strcmp(buf
, "RECONNECT") == 0) {
1749 if (wpa_s
->disconnected
) {
1750 wpa_s
->disconnected
= 0;
1751 wpa_s
->reassociate
= 1;
1752 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1754 #ifdef IEEE8021X_EAPOL
1755 } else if (os_strncmp(buf
, "PREAUTH ", 8) == 0) {
1756 if (wpa_supplicant_ctrl_iface_preauth(wpa_s
, buf
+ 8))
1758 #endif /* IEEE8021X_EAPOL */
1759 #ifdef CONFIG_PEERKEY
1760 } else if (os_strncmp(buf
, "STKSTART ", 9) == 0) {
1761 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s
, buf
+ 9))
1763 #endif /* CONFIG_PEERKEY */
1764 #ifdef CONFIG_IEEE80211R
1765 } else if (os_strncmp(buf
, "FT_DS ", 6) == 0) {
1766 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s
, buf
+ 6))
1768 #endif /* CONFIG_IEEE80211R */
1770 } else if (os_strcmp(buf
, "WPS_PBC") == 0) {
1771 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s
, NULL
))
1773 } else if (os_strncmp(buf
, "WPS_PBC ", 8) == 0) {
1774 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s
, buf
+ 8))
1776 } else if (os_strncmp(buf
, "WPS_PIN ", 8) == 0) {
1777 reply_len
= wpa_supplicant_ctrl_iface_wps_pin(wpa_s
, buf
+ 8,
1780 #ifdef CONFIG_WPS_OOB
1781 } else if (os_strncmp(buf
, "WPS_OOB ", 8) == 0) {
1782 if (wpa_supplicant_ctrl_iface_wps_oob(wpa_s
, buf
+ 8))
1784 #endif /* CONFIG_WPS_OOB */
1785 } else if (os_strncmp(buf
, "WPS_REG ", 8) == 0) {
1786 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s
, buf
+ 8))
1788 #ifdef CONFIG_WPS_ER
1789 } else if (os_strcmp(buf
, "WPS_ER_START") == 0) {
1790 if (wpas_wps_er_start(wpa_s
))
1792 } else if (os_strcmp(buf
, "WPS_ER_STOP") == 0) {
1793 if (wpas_wps_er_stop(wpa_s
))
1795 } else if (os_strncmp(buf
, "WPS_ER_PIN ", 11) == 0) {
1796 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s
, buf
+ 11))
1798 } else if (os_strncmp(buf
, "WPS_ER_PBC ", 11) == 0) {
1799 if (wpas_wps_er_pbc(wpa_s
, buf
+ 11))
1801 } else if (os_strncmp(buf
, "WPS_ER_LEARN ", 13) == 0) {
1802 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s
, buf
+ 13))
1804 #endif /* CONFIG_WPS_ER */
1805 #endif /* CONFIG_WPS */
1806 #ifdef CONFIG_IBSS_RSN
1807 } else if (os_strncmp(buf
, "IBSS_RSN ", 9) == 0) {
1808 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s
, buf
+ 9))
1810 #endif /* CONFIG_IBSS_RSN */
1811 } else if (os_strncmp(buf
, WPA_CTRL_RSP
, os_strlen(WPA_CTRL_RSP
)) == 0)
1813 if (wpa_supplicant_ctrl_iface_ctrl_rsp(
1814 wpa_s
, buf
+ os_strlen(WPA_CTRL_RSP
)))
1818 } else if (os_strcmp(buf
, "RECONFIGURE") == 0) {
1819 if (wpa_supplicant_reload_configuration(wpa_s
))
1821 } else if (os_strcmp(buf
, "TERMINATE") == 0) {
1822 wpa_supplicant_terminate_proc(wpa_s
->global
);
1823 } else if (os_strncmp(buf
, "BSSID ", 6) == 0) {
1824 if (wpa_supplicant_ctrl_iface_bssid(wpa_s
, buf
+ 6))
1826 } else if (os_strcmp(buf
, "LIST_NETWORKS") == 0) {
1827 reply_len
= wpa_supplicant_ctrl_iface_list_networks(
1828 wpa_s
, reply
, reply_size
);
1829 } else if (os_strcmp(buf
, "DISCONNECT") == 0) {
1830 wpa_s
->reassociate
= 0;
1831 wpa_s
->disconnected
= 1;
1832 wpa_supplicant_deauthenticate(wpa_s
,
1833 WLAN_REASON_DEAUTH_LEAVING
);
1834 } else if (os_strcmp(buf
, "SCAN") == 0) {
1835 wpa_s
->scan_req
= 2;
1836 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1837 } else if (os_strcmp(buf
, "SCAN_RESULTS") == 0) {
1838 reply_len
= wpa_supplicant_ctrl_iface_scan_results(
1839 wpa_s
, reply
, reply_size
);
1840 } else if (os_strncmp(buf
, "SELECT_NETWORK ", 15) == 0) {
1841 if (wpa_supplicant_ctrl_iface_select_network(wpa_s
, buf
+ 15))
1843 } else if (os_strncmp(buf
, "ENABLE_NETWORK ", 15) == 0) {
1844 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s
, buf
+ 15))
1846 } else if (os_strncmp(buf
, "DISABLE_NETWORK ", 16) == 0) {
1847 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s
, buf
+ 16))
1849 } else if (os_strcmp(buf
, "ADD_NETWORK") == 0) {
1850 reply_len
= wpa_supplicant_ctrl_iface_add_network(
1851 wpa_s
, reply
, reply_size
);
1852 } else if (os_strncmp(buf
, "REMOVE_NETWORK ", 15) == 0) {
1853 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s
, buf
+ 15))
1855 } else if (os_strncmp(buf
, "SET_NETWORK ", 12) == 0) {
1856 if (wpa_supplicant_ctrl_iface_set_network(wpa_s
, buf
+ 12))
1858 } else if (os_strncmp(buf
, "GET_NETWORK ", 12) == 0) {
1859 reply_len
= wpa_supplicant_ctrl_iface_get_network(
1860 wpa_s
, buf
+ 12, reply
, reply_size
);
1861 #ifndef CONFIG_NO_CONFIG_WRITE
1862 } else if (os_strcmp(buf
, "SAVE_CONFIG") == 0) {
1863 if (wpa_supplicant_ctrl_iface_save_config(wpa_s
))
1865 #endif /* CONFIG_NO_CONFIG_WRITE */
1866 } else if (os_strncmp(buf
, "GET_CAPABILITY ", 15) == 0) {
1867 reply_len
= wpa_supplicant_ctrl_iface_get_capability(
1868 wpa_s
, buf
+ 15, reply
, reply_size
);
1869 } else if (os_strncmp(buf
, "AP_SCAN ", 8) == 0) {
1870 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s
, buf
+ 8))
1872 } else if (os_strcmp(buf
, "INTERFACE_LIST") == 0) {
1873 reply_len
= wpa_supplicant_global_iface_list(
1874 wpa_s
->global
, reply
, reply_size
);
1875 } else if (os_strcmp(buf
, "INTERFACES") == 0) {
1876 reply_len
= wpa_supplicant_global_iface_interfaces(
1877 wpa_s
->global
, reply
, reply_size
);
1878 } else if (os_strncmp(buf
, "BSS ", 4) == 0) {
1879 reply_len
= wpa_supplicant_ctrl_iface_bss(
1880 wpa_s
, buf
+ 4, reply
, reply_size
);
1882 } else if (os_strcmp(buf
, "STA-FIRST") == 0) {
1883 reply_len
= ap_ctrl_iface_sta_first(wpa_s
, reply
, reply_size
);
1884 } else if (os_strncmp(buf
, "STA ", 4) == 0) {
1885 reply_len
= ap_ctrl_iface_sta(wpa_s
, buf
+ 4, reply
,
1887 } else if (os_strncmp(buf
, "STA-NEXT ", 9) == 0) {
1888 reply_len
= ap_ctrl_iface_sta_next(wpa_s
, buf
+ 9, reply
,
1890 #endif /* CONFIG_AP */
1891 } else if (os_strcmp(buf
, "SUSPEND") == 0) {
1892 wpas_notify_suspend(wpa_s
->global
);
1893 } else if (os_strcmp(buf
, "RESUME") == 0) {
1894 wpas_notify_resume(wpa_s
->global
);
1895 } else if (os_strcmp(buf
, "DROP_SA") == 0) {
1896 wpa_supplicant_ctrl_iface_drop_sa(wpa_s
);
1897 } else if (os_strncmp(buf
, "ROAM ", 5) == 0) {
1898 if (wpa_supplicant_ctrl_iface_roam(wpa_s
, buf
+ 5))
1901 os_memcpy(reply
, "UNKNOWN COMMAND\n", 16);
1905 if (reply_len
< 0) {
1906 os_memcpy(reply
, "FAIL\n", 5);
1911 eapol_sm_notify_ctrl_response(wpa_s
->eapol
);
1913 *resp_len
= reply_len
;
1918 static int wpa_supplicant_global_iface_add(struct wpa_global
*global
,
1921 struct wpa_interface iface
;
1925 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
1926 * TAB<bridge_ifname>
1928 wpa_printf(MSG_DEBUG
, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd
);
1930 os_memset(&iface
, 0, sizeof(iface
));
1933 iface
.ifname
= pos
= cmd
;
1934 pos
= os_strchr(pos
, '\t');
1937 if (iface
.ifname
[0] == '\0')
1942 iface
.confname
= pos
;
1943 pos
= os_strchr(pos
, '\t');
1946 if (iface
.confname
[0] == '\0')
1947 iface
.confname
= NULL
;
1952 pos
= os_strchr(pos
, '\t');
1955 if (iface
.driver
[0] == '\0')
1956 iface
.driver
= NULL
;
1960 iface
.ctrl_interface
= pos
;
1961 pos
= os_strchr(pos
, '\t');
1964 if (iface
.ctrl_interface
[0] == '\0')
1965 iface
.ctrl_interface
= NULL
;
1969 iface
.driver_param
= pos
;
1970 pos
= os_strchr(pos
, '\t');
1973 if (iface
.driver_param
[0] == '\0')
1974 iface
.driver_param
= NULL
;
1978 iface
.bridge_ifname
= pos
;
1979 pos
= os_strchr(pos
, '\t');
1982 if (iface
.bridge_ifname
[0] == '\0')
1983 iface
.bridge_ifname
= NULL
;
1988 if (wpa_supplicant_get_iface(global
, iface
.ifname
))
1991 return wpa_supplicant_add_iface(global
, &iface
) ? 0 : -1;
1995 static int wpa_supplicant_global_iface_remove(struct wpa_global
*global
,
1998 struct wpa_supplicant
*wpa_s
;
2000 wpa_printf(MSG_DEBUG
, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd
);
2002 wpa_s
= wpa_supplicant_get_iface(global
, cmd
);
2005 return wpa_supplicant_remove_iface(global
, wpa_s
);
2009 static void wpa_free_iface_info(struct wpa_interface_info
*iface
)
2011 struct wpa_interface_info
*prev
;
2015 iface
= iface
->next
;
2017 os_free(prev
->ifname
);
2018 os_free(prev
->desc
);
2024 static int wpa_supplicant_global_iface_list(struct wpa_global
*global
,
2028 struct wpa_interface_info
*iface
= NULL
, *last
= NULL
, *tmp
;
2031 for (i
= 0; wpa_drivers
[i
]; i
++) {
2032 struct wpa_driver_ops
*drv
= wpa_drivers
[i
];
2033 if (drv
->get_interfaces
== NULL
)
2035 tmp
= drv
->get_interfaces(global
->drv_priv
[i
]);
2049 for (tmp
= iface
; tmp
; tmp
= tmp
->next
) {
2050 res
= os_snprintf(pos
, end
- pos
, "%s\t%s\t%s\n",
2051 tmp
->drv_name
, tmp
->ifname
,
2052 tmp
->desc
? tmp
->desc
: "");
2053 if (res
< 0 || res
>= end
- pos
) {
2060 wpa_free_iface_info(iface
);
2066 static int wpa_supplicant_global_iface_interfaces(struct wpa_global
*global
,
2071 struct wpa_supplicant
*wpa_s
;
2073 wpa_s
= global
->ifaces
;
2078 res
= os_snprintf(pos
, end
- pos
, "%s\n", wpa_s
->ifname
);
2079 if (res
< 0 || res
>= end
- pos
) {
2084 wpa_s
= wpa_s
->next
;
2090 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global
*global
,
2091 char *buf
, size_t *resp_len
)
2094 const int reply_size
= 2048;
2097 wpa_hexdump_ascii(MSG_DEBUG
, "RX global ctrl_iface",
2098 (const u8
*) buf
, os_strlen(buf
));
2100 reply
= os_malloc(reply_size
);
2101 if (reply
== NULL
) {
2106 os_memcpy(reply
, "OK\n", 3);
2109 if (os_strcmp(buf
, "PING") == 0) {
2110 os_memcpy(reply
, "PONG\n", 5);
2112 } else if (os_strncmp(buf
, "INTERFACE_ADD ", 14) == 0) {
2113 if (wpa_supplicant_global_iface_add(global
, buf
+ 14))
2115 } else if (os_strncmp(buf
, "INTERFACE_REMOVE ", 17) == 0) {
2116 if (wpa_supplicant_global_iface_remove(global
, buf
+ 17))
2118 } else if (os_strcmp(buf
, "INTERFACE_LIST") == 0) {
2119 reply_len
= wpa_supplicant_global_iface_list(
2120 global
, reply
, reply_size
);
2121 } else if (os_strcmp(buf
, "INTERFACES") == 0) {
2122 reply_len
= wpa_supplicant_global_iface_interfaces(
2123 global
, reply
, reply_size
);
2124 } else if (os_strcmp(buf
, "TERMINATE") == 0) {
2125 wpa_supplicant_terminate_proc(global
);
2126 } else if (os_strcmp(buf
, "SUSPEND") == 0) {
2127 wpas_notify_suspend(global
);
2128 } else if (os_strcmp(buf
, "RESUME") == 0) {
2129 wpas_notify_resume(global
);
2131 os_memcpy(reply
, "UNKNOWN COMMAND\n", 16);
2135 if (reply_len
< 0) {
2136 os_memcpy(reply
, "FAIL\n", 5);
2140 *resp_len
= reply_len
;