2 * WPA Supplicant / Control interface (shared code for all backends)
3 * Copyright (c) 2004-2009, 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"
36 #include "ctrl_iface.h"
38 extern struct wpa_driver_ops
*wpa_drivers
[];
40 static int wpa_supplicant_global_iface_list(struct wpa_global
*global
,
42 static int wpa_supplicant_global_iface_interfaces(struct wpa_global
*global
,
46 static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant
*wpa_s
,
52 value
= os_strchr(cmd
, ' ');
57 wpa_printf(MSG_DEBUG
, "CTRL_IFACE SET '%s'='%s'", cmd
, value
);
58 if (os_strcasecmp(cmd
, "EAPOL::heldPeriod") == 0) {
59 eapol_sm_configure(wpa_s
->eapol
,
60 atoi(value
), -1, -1, -1);
61 } else if (os_strcasecmp(cmd
, "EAPOL::authPeriod") == 0) {
62 eapol_sm_configure(wpa_s
->eapol
,
63 -1, atoi(value
), -1, -1);
64 } else if (os_strcasecmp(cmd
, "EAPOL::startPeriod") == 0) {
65 eapol_sm_configure(wpa_s
->eapol
,
66 -1, -1, atoi(value
), -1);
67 } else if (os_strcasecmp(cmd
, "EAPOL::maxStart") == 0) {
68 eapol_sm_configure(wpa_s
->eapol
,
69 -1, -1, -1, atoi(value
));
70 } else if (os_strcasecmp(cmd
, "dot11RSNAConfigPMKLifetime") == 0) {
71 if (wpa_sm_set_param(wpa_s
->wpa
, RSNA_PMK_LIFETIME
,
74 } else if (os_strcasecmp(cmd
, "dot11RSNAConfigPMKReauthThreshold") ==
76 if (wpa_sm_set_param(wpa_s
->wpa
, RSNA_PMK_REAUTH_THRESHOLD
,
79 } else if (os_strcasecmp(cmd
, "dot11RSNAConfigSATimeout") == 0) {
80 if (wpa_sm_set_param(wpa_s
->wpa
, RSNA_SA_TIMEOUT
, atoi(value
)))
89 #ifdef IEEE8021X_EAPOL
90 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant
*wpa_s
,
94 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
96 if (hwaddr_aton(addr
, bssid
)) {
97 wpa_printf(MSG_DEBUG
, "CTRL_IFACE PREAUTH: invalid address "
102 wpa_printf(MSG_DEBUG
, "CTRL_IFACE PREAUTH " MACSTR
, MAC2STR(bssid
));
103 rsn_preauth_deinit(wpa_s
->wpa
);
104 if (rsn_preauth_init(wpa_s
->wpa
, bssid
, ssid
? &ssid
->eap
: NULL
))
109 #endif /* IEEE8021X_EAPOL */
112 #ifdef CONFIG_PEERKEY
113 /* MLME-STKSTART.request(peer) */
114 static int wpa_supplicant_ctrl_iface_stkstart(
115 struct wpa_supplicant
*wpa_s
, char *addr
)
119 if (hwaddr_aton(addr
, peer
)) {
120 wpa_printf(MSG_DEBUG
, "CTRL_IFACE STKSTART: invalid "
121 "address '%s'", peer
);
125 wpa_printf(MSG_DEBUG
, "CTRL_IFACE STKSTART " MACSTR
,
128 return wpa_sm_stkstart(wpa_s
->wpa
, peer
);
130 #endif /* CONFIG_PEERKEY */
133 #ifdef CONFIG_IEEE80211R
134 static int wpa_supplicant_ctrl_iface_ft_ds(
135 struct wpa_supplicant
*wpa_s
, char *addr
)
137 u8 target_ap
[ETH_ALEN
];
139 if (hwaddr_aton(addr
, target_ap
)) {
140 wpa_printf(MSG_DEBUG
, "CTRL_IFACE FT_DS: invalid "
141 "address '%s'", target_ap
);
145 wpa_printf(MSG_DEBUG
, "CTRL_IFACE FT_DS " MACSTR
, MAC2STR(target_ap
));
147 return wpa_ft_start_over_ds(wpa_s
->wpa
, target_ap
);
149 #endif /* CONFIG_IEEE80211R */
153 static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant
*wpa_s
,
156 u8 bssid
[ETH_ALEN
], *_bssid
= bssid
;
158 if (cmd
== NULL
|| os_strcmp(cmd
, "any") == 0)
160 else if (hwaddr_aton(cmd
, bssid
)) {
161 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
168 return wpa_supplicant_ap_wps_pbc(wpa_s
, _bssid
);
169 #endif /* CONFIG_AP */
171 return wpas_wps_start_pbc(wpa_s
, _bssid
);
175 static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant
*wpa_s
,
176 char *cmd
, char *buf
,
179 u8 bssid
[ETH_ALEN
], *_bssid
= bssid
;
183 pin
= os_strchr(cmd
, ' ');
187 if (os_strcmp(cmd
, "any") == 0)
189 else if (hwaddr_aton(cmd
, bssid
)) {
190 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
197 return wpa_supplicant_ap_wps_pin(wpa_s
, _bssid
, pin
,
199 #endif /* CONFIG_AP */
202 ret
= wpas_wps_start_pin(wpa_s
, _bssid
, pin
);
205 ret
= os_snprintf(buf
, buflen
, "%s", pin
);
206 if (ret
< 0 || (size_t) ret
>= buflen
)
211 ret
= wpas_wps_start_pin(wpa_s
, _bssid
, NULL
);
215 /* Return the generated PIN */
216 ret
= os_snprintf(buf
, buflen
, "%08d", ret
);
217 if (ret
< 0 || (size_t) ret
>= buflen
)
223 #ifdef CONFIG_WPS_OOB
224 static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant
*wpa_s
,
227 char *path
, *method
, *name
;
229 path
= os_strchr(cmd
, ' ');
234 method
= os_strchr(path
, ' ');
239 name
= os_strchr(method
, ' ');
243 return wpas_wps_start_oob(wpa_s
, cmd
, path
, method
, name
);
245 #endif /* CONFIG_WPS_OOB */
248 static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant
*wpa_s
,
251 u8 bssid
[ETH_ALEN
], *_bssid
= bssid
;
257 struct wps_new_ap_settings ap
;
259 pin
= os_strchr(cmd
, ' ');
264 if (os_strcmp(cmd
, "any") == 0)
266 else if (hwaddr_aton(cmd
, bssid
)) {
267 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_REG: invalid BSSID '%s'",
272 new_ssid
= os_strchr(pin
, ' ');
273 if (new_ssid
== NULL
)
274 return wpas_wps_start_reg(wpa_s
, _bssid
, pin
, NULL
);
277 new_auth
= os_strchr(new_ssid
, ' ');
278 if (new_auth
== NULL
)
282 new_encr
= os_strchr(new_auth
, ' ');
283 if (new_encr
== NULL
)
287 new_key
= os_strchr(new_encr
, ' ');
292 os_memset(&ap
, 0, sizeof(ap
));
293 ap
.ssid_hex
= new_ssid
;
296 ap
.key_hex
= new_key
;
297 return wpas_wps_start_reg(wpa_s
, _bssid
, pin
, &ap
);
302 static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant
*wpa_s
,
305 char *uuid
= cmd
, *pin
;
306 pin
= os_strchr(uuid
, ' ');
310 return wpas_wps_er_add_pin(wpa_s
, uuid
, pin
);
314 static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant
*wpa_s
,
317 char *uuid
= cmd
, *pin
;
318 pin
= os_strchr(uuid
, ' ');
322 return wpas_wps_er_learn(wpa_s
, uuid
, pin
);
324 #endif /* CONFIG_WPS_ER */
326 #endif /* CONFIG_WPS */
329 #ifdef CONFIG_IBSS_RSN
330 static int wpa_supplicant_ctrl_iface_ibss_rsn(
331 struct wpa_supplicant
*wpa_s
, char *addr
)
335 if (hwaddr_aton(addr
, peer
)) {
336 wpa_printf(MSG_DEBUG
, "CTRL_IFACE IBSS_RSN: invalid "
337 "address '%s'", peer
);
341 wpa_printf(MSG_DEBUG
, "CTRL_IFACE IBSS_RSN " MACSTR
,
344 return ibss_rsn_start(wpa_s
->ibss_rsn
, peer
);
346 #endif /* CONFIG_IBSS_RSN */
349 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant
*wpa_s
,
352 #ifdef IEEE8021X_EAPOL
355 struct wpa_ssid
*ssid
;
356 struct eap_peer_config
*eap
;
358 pos
= os_strchr(rsp
, '-');
363 pos
= os_strchr(pos
, ':');
368 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: field=%s id=%d", rsp
, id
);
369 wpa_hexdump_ascii_key(MSG_DEBUG
, "CTRL_IFACE: value",
370 (u8
*) pos
, os_strlen(pos
));
372 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
374 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
380 if (os_strcmp(rsp
, "IDENTITY") == 0) {
381 os_free(eap
->identity
);
382 eap
->identity
= (u8
*) os_strdup(pos
);
383 eap
->identity_len
= os_strlen(pos
);
384 eap
->pending_req_identity
= 0;
385 if (ssid
== wpa_s
->current_ssid
)
386 wpa_s
->reassociate
= 1;
387 } else if (os_strcmp(rsp
, "PASSWORD") == 0) {
388 os_free(eap
->password
);
389 eap
->password
= (u8
*) os_strdup(pos
);
390 eap
->password_len
= os_strlen(pos
);
391 eap
->pending_req_password
= 0;
392 if (ssid
== wpa_s
->current_ssid
)
393 wpa_s
->reassociate
= 1;
394 } else if (os_strcmp(rsp
, "NEW_PASSWORD") == 0) {
395 os_free(eap
->new_password
);
396 eap
->new_password
= (u8
*) os_strdup(pos
);
397 eap
->new_password_len
= os_strlen(pos
);
398 eap
->pending_req_new_password
= 0;
399 if (ssid
== wpa_s
->current_ssid
)
400 wpa_s
->reassociate
= 1;
401 } else if (os_strcmp(rsp
, "PIN") == 0) {
403 eap
->pin
= os_strdup(pos
);
404 eap
->pending_req_pin
= 0;
405 if (ssid
== wpa_s
->current_ssid
)
406 wpa_s
->reassociate
= 1;
407 } else if (os_strcmp(rsp
, "OTP") == 0) {
409 eap
->otp
= (u8
*) os_strdup(pos
);
410 eap
->otp_len
= os_strlen(pos
);
411 os_free(eap
->pending_req_otp
);
412 eap
->pending_req_otp
= NULL
;
413 eap
->pending_req_otp_len
= 0;
414 } else if (os_strcmp(rsp
, "PASSPHRASE") == 0) {
415 os_free(eap
->private_key_passwd
);
416 eap
->private_key_passwd
= (u8
*) os_strdup(pos
);
417 eap
->pending_req_passphrase
= 0;
418 if (ssid
== wpa_s
->current_ssid
)
419 wpa_s
->reassociate
= 1;
421 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Unknown field '%s'", rsp
);
426 #else /* IEEE8021X_EAPOL */
427 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: 802.1X not included");
429 #endif /* IEEE8021X_EAPOL */
433 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant
*wpa_s
,
435 char *buf
, size_t buflen
)
437 char *pos
, *end
, tmp
[30];
438 int res
, verbose
, ret
;
440 verbose
= os_strcmp(params
, "-VERBOSE") == 0;
443 if (wpa_s
->wpa_state
>= WPA_ASSOCIATED
) {
444 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
445 ret
= os_snprintf(pos
, end
- pos
, "bssid=" MACSTR
"\n",
446 MAC2STR(wpa_s
->bssid
));
447 if (ret
< 0 || ret
>= end
- pos
)
451 u8
*_ssid
= ssid
->ssid
;
452 size_t ssid_len
= ssid
->ssid_len
;
453 u8 ssid_buf
[MAX_SSID_LEN
];
455 int _res
= wpa_drv_get_ssid(wpa_s
, ssid_buf
);
462 ret
= os_snprintf(pos
, end
- pos
, "ssid=%s\nid=%d\n",
463 wpa_ssid_txt(_ssid
, ssid_len
),
465 if (ret
< 0 || ret
>= end
- pos
)
470 ret
= os_snprintf(pos
, end
- pos
,
473 if (ret
< 0 || ret
>= end
- pos
)
478 switch (ssid
->mode
) {
479 case WPAS_MODE_INFRA
:
480 ret
= os_snprintf(pos
, end
- pos
,
484 ret
= os_snprintf(pos
, end
- pos
,
488 ret
= os_snprintf(pos
, end
- pos
,
495 if (ret
< 0 || ret
>= end
- pos
)
501 if (wpa_s
->ap_iface
) {
502 pos
+= ap_ctrl_iface_wpa_get_status(wpa_s
, pos
,
506 #endif /* CONFIG_AP */
507 pos
+= wpa_sm_get_status(wpa_s
->wpa
, pos
, end
- pos
, verbose
);
509 ret
= os_snprintf(pos
, end
- pos
, "wpa_state=%s\n",
510 wpa_supplicant_state_txt(wpa_s
->wpa_state
));
511 if (ret
< 0 || ret
>= end
- pos
)
516 l2_packet_get_ip_addr(wpa_s
->l2
, tmp
, sizeof(tmp
)) >= 0) {
517 ret
= os_snprintf(pos
, end
- pos
, "ip_address=%s\n", tmp
);
518 if (ret
< 0 || ret
>= end
- pos
)
523 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s
->key_mgmt
) ||
524 wpa_s
->key_mgmt
== WPA_KEY_MGMT_IEEE8021X_NO_WPA
) {
525 res
= eapol_sm_get_status(wpa_s
->eapol
, pos
, end
- pos
,
531 res
= rsn_preauth_get_status(wpa_s
->wpa
, pos
, end
- pos
, verbose
);
539 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant
*wpa_s
,
544 struct wpa_ssid
*ssid
;
547 /* cmd: "<network id> <BSSID>" */
548 pos
= os_strchr(cmd
, ' ');
553 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: id=%d bssid='%s'", id
, pos
);
554 if (hwaddr_aton(pos
, bssid
)) {
555 wpa_printf(MSG_DEBUG
,"CTRL_IFACE: invalid BSSID '%s'", pos
);
559 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
561 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
566 os_memcpy(ssid
->bssid
, bssid
, ETH_ALEN
);
567 ssid
->bssid_set
= !is_zero_ether_addr(bssid
);
573 static int wpa_supplicant_ctrl_iface_list_networks(
574 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
577 struct wpa_ssid
*ssid
;
582 ret
= os_snprintf(pos
, end
- pos
,
583 "network id / ssid / bssid / flags\n");
584 if (ret
< 0 || ret
>= end
- pos
)
588 ssid
= wpa_s
->conf
->ssid
;
590 ret
= os_snprintf(pos
, end
- pos
, "%d\t%s",
592 wpa_ssid_txt(ssid
->ssid
, ssid
->ssid_len
));
593 if (ret
< 0 || ret
>= end
- pos
)
596 if (ssid
->bssid_set
) {
597 ret
= os_snprintf(pos
, end
- pos
, "\t" MACSTR
,
598 MAC2STR(ssid
->bssid
));
600 ret
= os_snprintf(pos
, end
- pos
, "\tany");
602 if (ret
< 0 || ret
>= end
- pos
)
605 ret
= os_snprintf(pos
, end
- pos
, "\t%s%s",
606 ssid
== wpa_s
->current_ssid
?
608 ssid
->disabled
? "[DISABLED]" : "");
609 if (ret
< 0 || ret
>= end
- pos
)
612 ret
= os_snprintf(pos
, end
- pos
, "\n");
613 if (ret
< 0 || ret
>= end
- pos
)
624 static char * wpa_supplicant_cipher_txt(char *pos
, char *end
, int cipher
)
627 ret
= os_snprintf(pos
, end
- pos
, "-");
628 if (ret
< 0 || ret
>= end
- pos
)
631 if (cipher
& WPA_CIPHER_NONE
) {
632 ret
= os_snprintf(pos
, end
- pos
, "%sNONE", first
? "" : "+");
633 if (ret
< 0 || ret
>= end
- pos
)
638 if (cipher
& WPA_CIPHER_WEP40
) {
639 ret
= os_snprintf(pos
, end
- pos
, "%sWEP40", first
? "" : "+");
640 if (ret
< 0 || ret
>= end
- pos
)
645 if (cipher
& WPA_CIPHER_WEP104
) {
646 ret
= os_snprintf(pos
, end
- pos
, "%sWEP104",
648 if (ret
< 0 || ret
>= end
- pos
)
653 if (cipher
& WPA_CIPHER_TKIP
) {
654 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : "+");
655 if (ret
< 0 || ret
>= end
- pos
)
660 if (cipher
& WPA_CIPHER_CCMP
) {
661 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : "+");
662 if (ret
< 0 || ret
>= end
- pos
)
671 static char * wpa_supplicant_ie_txt(char *pos
, char *end
, const char *proto
,
672 const u8
*ie
, size_t ie_len
)
674 struct wpa_ie_data data
;
677 ret
= os_snprintf(pos
, end
- pos
, "[%s-", proto
);
678 if (ret
< 0 || ret
>= end
- pos
)
682 if (wpa_parse_wpa_ie(ie
, ie_len
, &data
) < 0) {
683 ret
= os_snprintf(pos
, end
- pos
, "?]");
684 if (ret
< 0 || ret
>= end
- pos
)
691 if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X
) {
692 ret
= os_snprintf(pos
, end
- pos
, "%sEAP", first
? "" : "+");
693 if (ret
< 0 || ret
>= end
- pos
)
698 if (data
.key_mgmt
& WPA_KEY_MGMT_PSK
) {
699 ret
= os_snprintf(pos
, end
- pos
, "%sPSK", first
? "" : "+");
700 if (ret
< 0 || ret
>= end
- pos
)
705 if (data
.key_mgmt
& WPA_KEY_MGMT_WPA_NONE
) {
706 ret
= os_snprintf(pos
, end
- pos
, "%sNone", first
? "" : "+");
707 if (ret
< 0 || ret
>= end
- pos
)
712 #ifdef CONFIG_IEEE80211R
713 if (data
.key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
) {
714 ret
= os_snprintf(pos
, end
- pos
, "%sFT/EAP",
716 if (ret
< 0 || ret
>= end
- pos
)
721 if (data
.key_mgmt
& WPA_KEY_MGMT_FT_PSK
) {
722 ret
= os_snprintf(pos
, end
- pos
, "%sFT/PSK",
724 if (ret
< 0 || ret
>= end
- pos
)
729 #endif /* CONFIG_IEEE80211R */
730 #ifdef CONFIG_IEEE80211W
731 if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
) {
732 ret
= os_snprintf(pos
, end
- pos
, "%sEAP-SHA256",
734 if (ret
< 0 || ret
>= end
- pos
)
739 if (data
.key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
) {
740 ret
= os_snprintf(pos
, end
- pos
, "%sPSK-SHA256",
742 if (ret
< 0 || ret
>= end
- pos
)
747 #endif /* CONFIG_IEEE80211W */
749 pos
= wpa_supplicant_cipher_txt(pos
, end
, data
.pairwise_cipher
);
751 if (data
.capabilities
& WPA_CAPABILITY_PREAUTH
) {
752 ret
= os_snprintf(pos
, end
- pos
, "-preauth");
753 if (ret
< 0 || ret
>= end
- pos
)
758 ret
= os_snprintf(pos
, end
- pos
, "]");
759 if (ret
< 0 || ret
>= end
- pos
)
768 static char * wpa_supplicant_wps_ie_txt_buf(char *pos
, char *end
,
769 struct wpabuf
*wps_ie
)
776 if (wps_is_selected_pbc_registrar(wps_ie
))
778 else if (wps_is_selected_pin_registrar(wps_ie
))
783 ret
= os_snprintf(pos
, end
- pos
, "%s", txt
);
784 if (ret
>= 0 && ret
< end
- pos
)
789 #endif /* CONFIG_WPS */
792 static char * wpa_supplicant_wps_ie_txt(char *pos
, char *end
,
793 const struct wpa_scan_res
*res
)
796 struct wpabuf
*wps_ie
;
797 wps_ie
= wpa_scan_get_vendor_ie_multi(res
, WPS_IE_VENDOR_TYPE
);
798 return wpa_supplicant_wps_ie_txt_buf(pos
, end
, wps_ie
);
799 #else /* CONFIG_WPS */
801 #endif /* CONFIG_WPS */
805 static char * wpa_supplicant_wps_ie_txt_bss(char *pos
, char *end
,
806 const struct wpa_bss
*bss
)
809 struct wpabuf
*wps_ie
;
810 wps_ie
= wpa_bss_get_vendor_ie_multi(bss
, WPS_IE_VENDOR_TYPE
);
811 return wpa_supplicant_wps_ie_txt_buf(pos
, end
, wps_ie
);
812 #else /* CONFIG_WPS */
814 #endif /* CONFIG_WPS */
818 /* Format one result on one text line into a buffer. */
819 static int wpa_supplicant_ctrl_iface_scan_result(
820 const struct wpa_scan_res
*res
, char *buf
, size_t buflen
)
829 ret
= os_snprintf(pos
, end
- pos
, MACSTR
"\t%d\t%d\t",
830 MAC2STR(res
->bssid
), res
->freq
, res
->level
);
831 if (ret
< 0 || ret
>= end
- pos
)
834 ie
= wpa_scan_get_vendor_ie(res
, WPA_IE_VENDOR_TYPE
);
836 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA", ie
, 2 + ie
[1]);
837 ie2
= wpa_scan_get_ie(res
, WLAN_EID_RSN
);
839 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA2", ie2
, 2 + ie2
[1]);
840 pos
= wpa_supplicant_wps_ie_txt(pos
, end
, res
);
841 if (!ie
&& !ie2
&& res
->caps
& IEEE80211_CAP_PRIVACY
) {
842 ret
= os_snprintf(pos
, end
- pos
, "[WEP]");
843 if (ret
< 0 || ret
>= end
- pos
)
847 if (res
->caps
& IEEE80211_CAP_IBSS
) {
848 ret
= os_snprintf(pos
, end
- pos
, "[IBSS]");
849 if (ret
< 0 || ret
>= end
- pos
)
853 if (res
->caps
& IEEE80211_CAP_ESS
) {
854 ret
= os_snprintf(pos
, end
- pos
, "[ESS]");
855 if (ret
< 0 || ret
>= end
- pos
)
860 ie
= wpa_scan_get_ie(res
, WLAN_EID_SSID
);
861 ret
= os_snprintf(pos
, end
- pos
, "\t%s",
862 ie
? wpa_ssid_txt(ie
+ 2, ie
[1]) : "");
863 if (ret
< 0 || ret
>= end
- pos
)
867 ret
= os_snprintf(pos
, end
- pos
, "\n");
868 if (ret
< 0 || ret
>= end
- pos
)
876 static int wpa_supplicant_ctrl_iface_scan_results(
877 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
880 struct wpa_scan_res
*res
;
884 if (wpa_s
->scan_res
== NULL
&&
885 wpa_supplicant_get_scan_results(wpa_s
) < 0)
890 ret
= os_snprintf(pos
, end
- pos
, "bssid / frequency / signal level / "
892 if (ret
< 0 || ret
>= end
- pos
)
896 for (i
= 0; i
< wpa_s
->scan_res
->num
; i
++) {
897 res
= wpa_s
->scan_res
->res
[i
];
898 ret
= wpa_supplicant_ctrl_iface_scan_result(res
, pos
,
900 if (ret
< 0 || ret
>= end
- pos
)
909 static int wpa_supplicant_ctrl_iface_select_network(
910 struct wpa_supplicant
*wpa_s
, char *cmd
)
913 struct wpa_ssid
*ssid
;
915 /* cmd: "<network id>" or "any" */
916 if (os_strcmp(cmd
, "any") == 0) {
917 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SELECT_NETWORK any");
921 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SELECT_NETWORK id=%d", id
);
923 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
925 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
926 "network id=%d", id
);
931 wpa_supplicant_select_network(wpa_s
, ssid
);
937 static int wpa_supplicant_ctrl_iface_enable_network(
938 struct wpa_supplicant
*wpa_s
, char *cmd
)
941 struct wpa_ssid
*ssid
;
943 /* cmd: "<network id>" or "all" */
944 if (os_strcmp(cmd
, "all") == 0) {
945 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ENABLE_NETWORK all");
949 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ENABLE_NETWORK id=%d", id
);
951 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
953 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
954 "network id=%d", id
);
958 wpa_supplicant_enable_network(wpa_s
, ssid
);
964 static int wpa_supplicant_ctrl_iface_disable_network(
965 struct wpa_supplicant
*wpa_s
, char *cmd
)
968 struct wpa_ssid
*ssid
;
970 /* cmd: "<network id>" or "all" */
971 if (os_strcmp(cmd
, "all") == 0) {
972 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: DISABLE_NETWORK all");
976 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: DISABLE_NETWORK id=%d", id
);
978 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
980 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
981 "network id=%d", id
);
985 wpa_supplicant_disable_network(wpa_s
, ssid
);
991 static int wpa_supplicant_ctrl_iface_add_network(
992 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
994 struct wpa_ssid
*ssid
;
997 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ADD_NETWORK");
999 ssid
= wpa_config_add_network(wpa_s
->conf
);
1003 wpas_notify_network_added(wpa_s
, ssid
);
1006 wpa_config_set_network_defaults(ssid
);
1008 ret
= os_snprintf(buf
, buflen
, "%d\n", ssid
->id
);
1009 if (ret
< 0 || (size_t) ret
>= buflen
)
1015 static int wpa_supplicant_ctrl_iface_remove_network(
1016 struct wpa_supplicant
*wpa_s
, char *cmd
)
1019 struct wpa_ssid
*ssid
;
1021 /* cmd: "<network id>" or "all" */
1022 if (os_strcmp(cmd
, "all") == 0) {
1023 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_NETWORK all");
1024 ssid
= wpa_s
->conf
->ssid
;
1026 struct wpa_ssid
*remove_ssid
= ssid
;
1029 wpas_notify_network_removed(wpa_s
, remove_ssid
);
1030 wpa_config_remove_network(wpa_s
->conf
, id
);
1032 if (wpa_s
->current_ssid
) {
1033 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
1034 wpa_supplicant_disassociate(wpa_s
,
1035 WLAN_REASON_DEAUTH_LEAVING
);
1041 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_NETWORK id=%d", id
);
1043 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1045 wpa_config_remove_network(wpa_s
->conf
, id
) < 0) {
1046 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
1051 if (ssid
== wpa_s
->current_ssid
) {
1053 * Invalidate the EAP session cache if the current network is
1056 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
1058 wpa_supplicant_disassociate(wpa_s
, WLAN_REASON_DEAUTH_LEAVING
);
1065 static int wpa_supplicant_ctrl_iface_set_network(
1066 struct wpa_supplicant
*wpa_s
, char *cmd
)
1069 struct wpa_ssid
*ssid
;
1072 /* cmd: "<network id> <variable name> <value>" */
1073 name
= os_strchr(cmd
, ' ');
1078 value
= os_strchr(name
, ' ');
1084 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
1086 wpa_hexdump_ascii_key(MSG_DEBUG
, "CTRL_IFACE: value",
1087 (u8
*) value
, os_strlen(value
));
1089 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1091 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
1096 if (wpa_config_set(ssid
, name
, value
, 0) < 0) {
1097 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Failed to set network "
1098 "variable '%s'", name
);
1102 if (wpa_s
->current_ssid
== ssid
) {
1104 * Invalidate the EAP session cache if anything in the current
1105 * configuration changes.
1107 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
1110 if ((os_strcmp(name
, "psk") == 0 &&
1111 value
[0] == '"' && ssid
->ssid_len
) ||
1112 (os_strcmp(name
, "ssid") == 0 && ssid
->passphrase
))
1113 wpa_config_update_psk(ssid
);
1119 static int wpa_supplicant_ctrl_iface_get_network(
1120 struct wpa_supplicant
*wpa_s
, char *cmd
, char *buf
, size_t buflen
)
1124 struct wpa_ssid
*ssid
;
1127 /* cmd: "<network id> <variable name>" */
1128 name
= os_strchr(cmd
, ' ');
1129 if (name
== NULL
|| buflen
== 0)
1134 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
1137 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1139 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
1144 value
= wpa_config_get_no_key(ssid
, name
);
1145 if (value
== NULL
) {
1146 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Failed to get network "
1147 "variable '%s'", name
);
1151 res
= os_strlcpy(buf
, value
, buflen
);
1152 if (res
>= buflen
) {
1163 #ifndef CONFIG_NO_CONFIG_WRITE
1164 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant
*wpa_s
)
1168 if (!wpa_s
->conf
->update_config
) {
1169 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
1170 "to update configuration (update_config=0)");
1174 ret
= wpa_config_write(wpa_s
->confname
, wpa_s
->conf
);
1176 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Failed to "
1177 "update configuration");
1179 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Configuration"
1185 #endif /* CONFIG_NO_CONFIG_WRITE */
1188 static int ctrl_iface_get_capability_pairwise(int res
, char *strict
,
1189 struct wpa_driver_capa
*capa
,
1190 char *buf
, size_t buflen
)
1202 len
= os_strlcpy(buf
, "CCMP TKIP NONE", buflen
);
1208 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
1209 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : " ");
1210 if (ret
< 0 || ret
>= end
- pos
)
1216 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
1217 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : " ");
1218 if (ret
< 0 || ret
>= end
- pos
)
1224 if (capa
->key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
1225 ret
= os_snprintf(pos
, end
- pos
, "%sNONE", first
? "" : " ");
1226 if (ret
< 0 || ret
>= end
- pos
)
1236 static int ctrl_iface_get_capability_group(int res
, char *strict
,
1237 struct wpa_driver_capa
*capa
,
1238 char *buf
, size_t buflen
)
1250 len
= os_strlcpy(buf
, "CCMP TKIP WEP104 WEP40", buflen
);
1256 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
1257 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : " ");
1258 if (ret
< 0 || ret
>= end
- pos
)
1264 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
1265 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : " ");
1266 if (ret
< 0 || ret
>= end
- pos
)
1272 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_WEP104
) {
1273 ret
= os_snprintf(pos
, end
- pos
, "%sWEP104",
1275 if (ret
< 0 || ret
>= end
- pos
)
1281 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_WEP40
) {
1282 ret
= os_snprintf(pos
, end
- pos
, "%sWEP40", first
? "" : " ");
1283 if (ret
< 0 || ret
>= end
- pos
)
1293 static int ctrl_iface_get_capability_key_mgmt(int res
, char *strict
,
1294 struct wpa_driver_capa
*capa
,
1295 char *buf
, size_t buflen
)
1307 len
= os_strlcpy(buf
, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE "
1314 ret
= os_snprintf(pos
, end
- pos
, "NONE IEEE8021X");
1315 if (ret
< 0 || ret
>= end
- pos
)
1319 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
1320 WPA_DRIVER_CAPA_KEY_MGMT_WPA2
)) {
1321 ret
= os_snprintf(pos
, end
- pos
, " WPA-EAP");
1322 if (ret
< 0 || ret
>= end
- pos
)
1327 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
|
1328 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
1329 ret
= os_snprintf(pos
, end
- pos
, " WPA-PSK");
1330 if (ret
< 0 || ret
>= end
- pos
)
1335 if (capa
->key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
1336 ret
= os_snprintf(pos
, end
- pos
, " WPA-NONE");
1337 if (ret
< 0 || ret
>= end
- pos
)
1346 static int ctrl_iface_get_capability_proto(int res
, char *strict
,
1347 struct wpa_driver_capa
*capa
,
1348 char *buf
, size_t buflen
)
1360 len
= os_strlcpy(buf
, "RSN WPA", buflen
);
1366 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA2
|
1367 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
1368 ret
= os_snprintf(pos
, end
- pos
, "%sRSN", first
? "" : " ");
1369 if (ret
< 0 || ret
>= end
- pos
)
1375 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
1376 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
)) {
1377 ret
= os_snprintf(pos
, end
- pos
, "%sWPA", first
? "" : " ");
1378 if (ret
< 0 || ret
>= end
- pos
)
1388 static int ctrl_iface_get_capability_auth_alg(int res
, char *strict
,
1389 struct wpa_driver_capa
*capa
,
1390 char *buf
, size_t buflen
)
1402 len
= os_strlcpy(buf
, "OPEN SHARED LEAP", buflen
);
1408 if (capa
->auth
& (WPA_DRIVER_AUTH_OPEN
)) {
1409 ret
= os_snprintf(pos
, end
- pos
, "%sOPEN", first
? "" : " ");
1410 if (ret
< 0 || ret
>= end
- pos
)
1416 if (capa
->auth
& (WPA_DRIVER_AUTH_SHARED
)) {
1417 ret
= os_snprintf(pos
, end
- pos
, "%sSHARED",
1419 if (ret
< 0 || ret
>= end
- pos
)
1425 if (capa
->auth
& (WPA_DRIVER_AUTH_LEAP
)) {
1426 ret
= os_snprintf(pos
, end
- pos
, "%sLEAP", first
? "" : " ");
1427 if (ret
< 0 || ret
>= end
- pos
)
1437 static int wpa_supplicant_ctrl_iface_get_capability(
1438 struct wpa_supplicant
*wpa_s
, const char *_field
, char *buf
,
1441 struct wpa_driver_capa capa
;
1447 /* Determine whether or not strict checking was requested */
1448 len
= os_strlcpy(field
, _field
, sizeof(field
));
1449 if (len
>= sizeof(field
))
1451 strict
= os_strchr(field
, ' ');
1452 if (strict
!= NULL
) {
1454 if (os_strcmp(strict
, "strict") != 0)
1458 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
1459 field
, strict
? strict
: "");
1461 if (os_strcmp(field
, "eap") == 0) {
1462 return eap_get_names(buf
, buflen
);
1465 res
= wpa_drv_get_capa(wpa_s
, &capa
);
1467 if (os_strcmp(field
, "pairwise") == 0)
1468 return ctrl_iface_get_capability_pairwise(res
, strict
, &capa
,
1471 if (os_strcmp(field
, "group") == 0)
1472 return ctrl_iface_get_capability_group(res
, strict
, &capa
,
1475 if (os_strcmp(field
, "key_mgmt") == 0)
1476 return ctrl_iface_get_capability_key_mgmt(res
, strict
, &capa
,
1479 if (os_strcmp(field
, "proto") == 0)
1480 return ctrl_iface_get_capability_proto(res
, strict
, &capa
,
1483 if (os_strcmp(field
, "auth_alg") == 0)
1484 return ctrl_iface_get_capability_auth_alg(res
, strict
, &capa
,
1487 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
1494 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant
*wpa_s
,
1495 const char *cmd
, char *buf
,
1500 struct wpa_bss
*bss
;
1505 if (os_strcmp(cmd
, "FIRST") == 0)
1506 bss
= dl_list_first(&wpa_s
->bss
, struct wpa_bss
, list
);
1507 else if (os_strncmp(cmd
, "ID-", 3) == 0) {
1509 bss
= wpa_bss_get_id(wpa_s
, i
);
1510 } else if (os_strncmp(cmd
, "NEXT-", 5) == 0) {
1512 bss
= wpa_bss_get_id(wpa_s
, i
);
1514 struct dl_list
*next
= bss
->list_id
.next
;
1515 if (next
== &wpa_s
->bss_id
)
1518 bss
= dl_list_entry(next
, struct wpa_bss
,
1521 } else if (hwaddr_aton(cmd
, bssid
) == 0)
1522 bss
= wpa_bss_get_bssid(wpa_s
, bssid
);
1524 struct wpa_bss
*tmp
;
1527 dl_list_for_each(tmp
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
)
1541 ret
= os_snprintf(pos
, end
- pos
,
1543 "bssid=" MACSTR
"\n"
1546 "capabilities=0x%04x\n"
1553 MAC2STR(bss
->bssid
), bss
->freq
, bss
->beacon_int
,
1554 bss
->caps
, bss
->qual
, bss
->noise
, bss
->level
,
1555 (unsigned long long) bss
->tsf
);
1556 if (ret
< 0 || ret
>= end
- pos
)
1560 ie
= (const u8
*) (bss
+ 1);
1561 for (i
= 0; i
< bss
->ie_len
; i
++) {
1562 ret
= os_snprintf(pos
, end
- pos
, "%02x", *ie
++);
1563 if (ret
< 0 || ret
>= end
- pos
)
1568 ret
= os_snprintf(pos
, end
- pos
, "\n");
1569 if (ret
< 0 || ret
>= end
- pos
)
1573 ret
= os_snprintf(pos
, end
- pos
, "flags=");
1574 if (ret
< 0 || ret
>= end
- pos
)
1578 ie
= wpa_bss_get_vendor_ie(bss
, WPA_IE_VENDOR_TYPE
);
1580 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA", ie
, 2 + ie
[1]);
1581 ie2
= wpa_bss_get_ie(bss
, WLAN_EID_RSN
);
1583 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA2", ie2
, 2 + ie2
[1]);
1584 pos
= wpa_supplicant_wps_ie_txt_bss(pos
, end
, bss
);
1585 if (!ie
&& !ie2
&& bss
->caps
& IEEE80211_CAP_PRIVACY
) {
1586 ret
= os_snprintf(pos
, end
- pos
, "[WEP]");
1587 if (ret
< 0 || ret
>= end
- pos
)
1591 if (bss
->caps
& IEEE80211_CAP_IBSS
) {
1592 ret
= os_snprintf(pos
, end
- pos
, "[IBSS]");
1593 if (ret
< 0 || ret
>= end
- pos
)
1597 if (bss
->caps
& IEEE80211_CAP_ESS
) {
1598 ret
= os_snprintf(pos
, end
- pos
, "[ESS]");
1599 if (ret
< 0 || ret
>= end
- pos
)
1604 ret
= os_snprintf(pos
, end
- pos
, "\n");
1605 if (ret
< 0 || ret
>= end
- pos
)
1609 ret
= os_snprintf(pos
, end
- pos
, "ssid=%s\n",
1610 wpa_ssid_txt(bss
->ssid
, bss
->ssid_len
));
1611 if (ret
< 0 || ret
>= end
- pos
)
1616 ie
= (const u8
*) (bss
+ 1);
1617 ret
= wpas_wps_scan_result_text(ie
, bss
->ie_len
, pos
, end
);
1618 if (ret
< 0 || ret
>= end
- pos
)
1621 #endif /* CONFIG_WPS */
1627 static int wpa_supplicant_ctrl_iface_ap_scan(
1628 struct wpa_supplicant
*wpa_s
, char *cmd
)
1630 int ap_scan
= atoi(cmd
);
1631 return wpa_supplicant_set_ap_scan(wpa_s
, ap_scan
);
1635 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant
*wpa_s
,
1636 char *buf
, size_t *resp_len
)
1639 const int reply_size
= 2048;
1643 if (os_strncmp(buf
, WPA_CTRL_RSP
, os_strlen(WPA_CTRL_RSP
)) == 0 ||
1644 os_strncmp(buf
, "SET_NETWORK ", 12) == 0) {
1645 wpa_hexdump_ascii_key(MSG_DEBUG
, "RX ctrl_iface",
1646 (const u8
*) buf
, os_strlen(buf
));
1648 wpa_hexdump_ascii(MSG_DEBUG
, "RX ctrl_iface",
1649 (const u8
*) buf
, os_strlen(buf
));
1652 reply
= os_malloc(reply_size
);
1653 if (reply
== NULL
) {
1658 os_memcpy(reply
, "OK\n", 3);
1661 if (os_strcmp(buf
, "PING") == 0) {
1662 os_memcpy(reply
, "PONG\n", 5);
1664 } else if (os_strcmp(buf
, "MIB") == 0) {
1665 reply_len
= wpa_sm_get_mib(wpa_s
->wpa
, reply
, reply_size
);
1666 if (reply_len
>= 0) {
1668 res
= eapol_sm_get_mib(wpa_s
->eapol
, reply
+ reply_len
,
1669 reply_size
- reply_len
);
1675 } else if (os_strncmp(buf
, "STATUS", 6) == 0) {
1676 reply_len
= wpa_supplicant_ctrl_iface_status(
1677 wpa_s
, buf
+ 6, reply
, reply_size
);
1678 } else if (os_strcmp(buf
, "PMKSA") == 0) {
1679 reply_len
= wpa_sm_pmksa_cache_list(wpa_s
->wpa
, reply
,
1681 } else if (os_strncmp(buf
, "SET ", 4) == 0) {
1682 if (wpa_supplicant_ctrl_iface_set(wpa_s
, buf
+ 4))
1684 } else if (os_strcmp(buf
, "LOGON") == 0) {
1685 eapol_sm_notify_logoff(wpa_s
->eapol
, FALSE
);
1686 } else if (os_strcmp(buf
, "LOGOFF") == 0) {
1687 eapol_sm_notify_logoff(wpa_s
->eapol
, TRUE
);
1688 } else if (os_strcmp(buf
, "REASSOCIATE") == 0) {
1689 wpa_s
->disconnected
= 0;
1690 wpa_s
->reassociate
= 1;
1691 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1692 } else if (os_strcmp(buf
, "RECONNECT") == 0) {
1693 if (wpa_s
->disconnected
) {
1694 wpa_s
->disconnected
= 0;
1695 wpa_s
->reassociate
= 1;
1696 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1698 #ifdef IEEE8021X_EAPOL
1699 } else if (os_strncmp(buf
, "PREAUTH ", 8) == 0) {
1700 if (wpa_supplicant_ctrl_iface_preauth(wpa_s
, buf
+ 8))
1702 #endif /* IEEE8021X_EAPOL */
1703 #ifdef CONFIG_PEERKEY
1704 } else if (os_strncmp(buf
, "STKSTART ", 9) == 0) {
1705 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s
, buf
+ 9))
1707 #endif /* CONFIG_PEERKEY */
1708 #ifdef CONFIG_IEEE80211R
1709 } else if (os_strncmp(buf
, "FT_DS ", 6) == 0) {
1710 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s
, buf
+ 6))
1712 #endif /* CONFIG_IEEE80211R */
1714 } else if (os_strcmp(buf
, "WPS_PBC") == 0) {
1715 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s
, NULL
))
1717 } else if (os_strncmp(buf
, "WPS_PBC ", 8) == 0) {
1718 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s
, buf
+ 8))
1720 } else if (os_strncmp(buf
, "WPS_PIN ", 8) == 0) {
1721 reply_len
= wpa_supplicant_ctrl_iface_wps_pin(wpa_s
, buf
+ 8,
1724 #ifdef CONFIG_WPS_OOB
1725 } else if (os_strncmp(buf
, "WPS_OOB ", 8) == 0) {
1726 if (wpa_supplicant_ctrl_iface_wps_oob(wpa_s
, buf
+ 8))
1728 #endif /* CONFIG_WPS_OOB */
1729 } else if (os_strncmp(buf
, "WPS_REG ", 8) == 0) {
1730 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s
, buf
+ 8))
1732 #ifdef CONFIG_WPS_ER
1733 } else if (os_strcmp(buf
, "WPS_ER_START") == 0) {
1734 if (wpas_wps_er_start(wpa_s
))
1736 } else if (os_strcmp(buf
, "WPS_ER_STOP") == 0) {
1737 if (wpas_wps_er_stop(wpa_s
))
1739 } else if (os_strncmp(buf
, "WPS_ER_PIN ", 11) == 0) {
1740 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s
, buf
+ 11))
1742 } else if (os_strncmp(buf
, "WPS_ER_PBC ", 11) == 0) {
1743 if (wpas_wps_er_pbc(wpa_s
, buf
+ 11))
1745 } else if (os_strncmp(buf
, "WPS_ER_LEARN ", 13) == 0) {
1746 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s
, buf
+ 13))
1748 #endif /* CONFIG_WPS_ER */
1749 #endif /* CONFIG_WPS */
1750 #ifdef CONFIG_IBSS_RSN
1751 } else if (os_strncmp(buf
, "IBSS_RSN ", 9) == 0) {
1752 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s
, buf
+ 9))
1754 #endif /* CONFIG_IBSS_RSN */
1755 } else if (os_strncmp(buf
, WPA_CTRL_RSP
, os_strlen(WPA_CTRL_RSP
)) == 0)
1757 if (wpa_supplicant_ctrl_iface_ctrl_rsp(
1758 wpa_s
, buf
+ os_strlen(WPA_CTRL_RSP
)))
1762 } else if (os_strcmp(buf
, "RECONFIGURE") == 0) {
1763 if (wpa_supplicant_reload_configuration(wpa_s
))
1765 } else if (os_strcmp(buf
, "TERMINATE") == 0) {
1766 wpa_supplicant_terminate_proc(wpa_s
->global
);
1767 } else if (os_strncmp(buf
, "BSSID ", 6) == 0) {
1768 if (wpa_supplicant_ctrl_iface_bssid(wpa_s
, buf
+ 6))
1770 } else if (os_strcmp(buf
, "LIST_NETWORKS") == 0) {
1771 reply_len
= wpa_supplicant_ctrl_iface_list_networks(
1772 wpa_s
, reply
, reply_size
);
1773 } else if (os_strcmp(buf
, "DISCONNECT") == 0) {
1774 wpa_s
->reassociate
= 0;
1775 wpa_s
->disconnected
= 1;
1776 wpa_supplicant_disassociate(wpa_s
, WLAN_REASON_DEAUTH_LEAVING
);
1777 } else if (os_strcmp(buf
, "SCAN") == 0) {
1778 wpa_s
->scan_req
= 2;
1779 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1780 } else if (os_strcmp(buf
, "SCAN_RESULTS") == 0) {
1781 reply_len
= wpa_supplicant_ctrl_iface_scan_results(
1782 wpa_s
, reply
, reply_size
);
1783 } else if (os_strncmp(buf
, "SELECT_NETWORK ", 15) == 0) {
1784 if (wpa_supplicant_ctrl_iface_select_network(wpa_s
, buf
+ 15))
1786 } else if (os_strncmp(buf
, "ENABLE_NETWORK ", 15) == 0) {
1787 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s
, buf
+ 15))
1789 } else if (os_strncmp(buf
, "DISABLE_NETWORK ", 16) == 0) {
1790 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s
, buf
+ 16))
1792 } else if (os_strcmp(buf
, "ADD_NETWORK") == 0) {
1793 reply_len
= wpa_supplicant_ctrl_iface_add_network(
1794 wpa_s
, reply
, reply_size
);
1795 } else if (os_strncmp(buf
, "REMOVE_NETWORK ", 15) == 0) {
1796 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s
, buf
+ 15))
1798 } else if (os_strncmp(buf
, "SET_NETWORK ", 12) == 0) {
1799 if (wpa_supplicant_ctrl_iface_set_network(wpa_s
, buf
+ 12))
1801 } else if (os_strncmp(buf
, "GET_NETWORK ", 12) == 0) {
1802 reply_len
= wpa_supplicant_ctrl_iface_get_network(
1803 wpa_s
, buf
+ 12, reply
, reply_size
);
1804 #ifndef CONFIG_NO_CONFIG_WRITE
1805 } else if (os_strcmp(buf
, "SAVE_CONFIG") == 0) {
1806 if (wpa_supplicant_ctrl_iface_save_config(wpa_s
))
1808 #endif /* CONFIG_NO_CONFIG_WRITE */
1809 } else if (os_strncmp(buf
, "GET_CAPABILITY ", 15) == 0) {
1810 reply_len
= wpa_supplicant_ctrl_iface_get_capability(
1811 wpa_s
, buf
+ 15, reply
, reply_size
);
1812 } else if (os_strncmp(buf
, "AP_SCAN ", 8) == 0) {
1813 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s
, buf
+ 8))
1815 } else if (os_strcmp(buf
, "INTERFACE_LIST") == 0) {
1816 reply_len
= wpa_supplicant_global_iface_list(
1817 wpa_s
->global
, reply
, reply_size
);
1818 } else if (os_strcmp(buf
, "INTERFACES") == 0) {
1819 reply_len
= wpa_supplicant_global_iface_interfaces(
1820 wpa_s
->global
, reply
, reply_size
);
1821 } else if (os_strncmp(buf
, "BSS ", 4) == 0) {
1822 reply_len
= wpa_supplicant_ctrl_iface_bss(
1823 wpa_s
, buf
+ 4, reply
, reply_size
);
1825 } else if (os_strcmp(buf
, "STA-FIRST") == 0) {
1826 reply_len
= ap_ctrl_iface_sta_first(wpa_s
, reply
, reply_size
);
1827 } else if (os_strncmp(buf
, "STA ", 4) == 0) {
1828 reply_len
= ap_ctrl_iface_sta(wpa_s
, buf
+ 4, reply
,
1830 } else if (os_strncmp(buf
, "STA-NEXT ", 9) == 0) {
1831 reply_len
= ap_ctrl_iface_sta_next(wpa_s
, buf
+ 9, reply
,
1833 #endif /* CONFIG_AP */
1835 os_memcpy(reply
, "UNKNOWN COMMAND\n", 16);
1839 if (reply_len
< 0) {
1840 os_memcpy(reply
, "FAIL\n", 5);
1845 eapol_sm_notify_ctrl_response(wpa_s
->eapol
);
1847 *resp_len
= reply_len
;
1852 static int wpa_supplicant_global_iface_add(struct wpa_global
*global
,
1855 struct wpa_interface iface
;
1859 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
1860 * TAB<bridge_ifname>
1862 wpa_printf(MSG_DEBUG
, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd
);
1864 os_memset(&iface
, 0, sizeof(iface
));
1867 iface
.ifname
= pos
= cmd
;
1868 pos
= os_strchr(pos
, '\t');
1871 if (iface
.ifname
[0] == '\0')
1876 iface
.confname
= pos
;
1877 pos
= os_strchr(pos
, '\t');
1880 if (iface
.confname
[0] == '\0')
1881 iface
.confname
= NULL
;
1886 pos
= os_strchr(pos
, '\t');
1889 if (iface
.driver
[0] == '\0')
1890 iface
.driver
= NULL
;
1894 iface
.ctrl_interface
= pos
;
1895 pos
= os_strchr(pos
, '\t');
1898 if (iface
.ctrl_interface
[0] == '\0')
1899 iface
.ctrl_interface
= NULL
;
1903 iface
.driver_param
= pos
;
1904 pos
= os_strchr(pos
, '\t');
1907 if (iface
.driver_param
[0] == '\0')
1908 iface
.driver_param
= NULL
;
1912 iface
.bridge_ifname
= pos
;
1913 pos
= os_strchr(pos
, '\t');
1916 if (iface
.bridge_ifname
[0] == '\0')
1917 iface
.bridge_ifname
= NULL
;
1922 if (wpa_supplicant_get_iface(global
, iface
.ifname
))
1925 return wpa_supplicant_add_iface(global
, &iface
) ? 0 : -1;
1929 static int wpa_supplicant_global_iface_remove(struct wpa_global
*global
,
1932 struct wpa_supplicant
*wpa_s
;
1934 wpa_printf(MSG_DEBUG
, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd
);
1936 wpa_s
= wpa_supplicant_get_iface(global
, cmd
);
1939 return wpa_supplicant_remove_iface(global
, wpa_s
);
1943 static void wpa_free_iface_info(struct wpa_interface_info
*iface
)
1945 struct wpa_interface_info
*prev
;
1949 iface
= iface
->next
;
1951 os_free(prev
->ifname
);
1952 os_free(prev
->desc
);
1958 static int wpa_supplicant_global_iface_list(struct wpa_global
*global
,
1962 struct wpa_interface_info
*iface
= NULL
, *last
= NULL
, *tmp
;
1965 for (i
= 0; wpa_drivers
[i
]; i
++) {
1966 struct wpa_driver_ops
*drv
= wpa_drivers
[i
];
1967 if (drv
->get_interfaces
== NULL
)
1969 tmp
= drv
->get_interfaces(global
->drv_priv
);
1983 for (tmp
= iface
; tmp
; tmp
= tmp
->next
) {
1984 res
= os_snprintf(pos
, end
- pos
, "%s\t%s\t%s\n",
1985 tmp
->drv_name
, tmp
->ifname
,
1986 tmp
->desc
? tmp
->desc
: "");
1987 if (res
< 0 || res
>= end
- pos
) {
1994 wpa_free_iface_info(iface
);
2000 static int wpa_supplicant_global_iface_interfaces(struct wpa_global
*global
,
2005 struct wpa_supplicant
*wpa_s
;
2007 wpa_s
= global
->ifaces
;
2012 res
= os_snprintf(pos
, end
- pos
, "%s\n", wpa_s
->ifname
);
2013 if (res
< 0 || res
>= end
- pos
) {
2018 wpa_s
= wpa_s
->next
;
2024 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global
*global
,
2025 char *buf
, size_t *resp_len
)
2028 const int reply_size
= 2048;
2031 wpa_hexdump_ascii(MSG_DEBUG
, "RX global ctrl_iface",
2032 (const u8
*) buf
, os_strlen(buf
));
2034 reply
= os_malloc(reply_size
);
2035 if (reply
== NULL
) {
2040 os_memcpy(reply
, "OK\n", 3);
2043 if (os_strcmp(buf
, "PING") == 0) {
2044 os_memcpy(reply
, "PONG\n", 5);
2046 } else if (os_strncmp(buf
, "INTERFACE_ADD ", 14) == 0) {
2047 if (wpa_supplicant_global_iface_add(global
, buf
+ 14))
2049 } else if (os_strncmp(buf
, "INTERFACE_REMOVE ", 17) == 0) {
2050 if (wpa_supplicant_global_iface_remove(global
, buf
+ 17))
2052 } else if (os_strcmp(buf
, "INTERFACE_LIST") == 0) {
2053 reply_len
= wpa_supplicant_global_iface_list(
2054 global
, reply
, reply_size
);
2055 } else if (os_strcmp(buf
, "INTERFACES") == 0) {
2056 reply_len
= wpa_supplicant_global_iface_interfaces(
2057 global
, reply
, reply_size
);
2058 } else if (os_strcmp(buf
, "TERMINATE") == 0) {
2059 wpa_supplicant_terminate_proc(global
);
2061 os_memcpy(reply
, "UNKNOWN COMMAND\n", 16);
2065 if (reply_len
< 0) {
2066 os_memcpy(reply
, "FAIL\n", 5);
2070 *resp_len
= reply_len
;