2 * WPA Supplicant / Control interface (shared code for all backends)
3 * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "common/version.h"
14 #include "common/ieee802_11_defs.h"
15 #include "common/wpa_ctrl.h"
16 #include "eap_peer/eap.h"
17 #include "eapol_supp/eapol_supp_sm.h"
18 #include "rsn_supp/wpa.h"
19 #include "rsn_supp/preauth.h"
20 #include "rsn_supp/pmksa_cache.h"
21 #include "l2_packet/l2_packet.h"
24 #include "wpa_supplicant_i.h"
26 #include "wps_supplicant.h"
29 #include "p2p_supplicant.h"
34 #include "ctrl_iface.h"
35 #include "interworking.h"
36 #include "blacklist.h"
37 #include "wpas_glue.h"
39 extern struct wpa_driver_ops
*wpa_drivers
[];
41 static int wpa_supplicant_global_iface_list(struct wpa_global
*global
,
43 static int wpa_supplicant_global_iface_interfaces(struct wpa_global
*global
,
47 static int pno_start(struct wpa_supplicant
*wpa_s
)
51 struct wpa_ssid
*ssid
;
52 struct wpa_driver_scan_params params
;
57 os_memset(¶ms
, 0, sizeof(params
));
60 ssid
= wpa_s
->conf
->ssid
;
62 if (!wpas_network_disabled(ssid
))
66 if (num_ssid
> WPAS_MAX_SCAN_SSIDS
) {
67 wpa_printf(MSG_DEBUG
, "PNO: Use only the first %u SSIDs from "
68 "%u", WPAS_MAX_SCAN_SSIDS
, (unsigned int) num_ssid
);
69 num_ssid
= WPAS_MAX_SCAN_SSIDS
;
73 wpa_printf(MSG_DEBUG
, "PNO: No configured SSIDs");
77 params
.filter_ssids
= os_malloc(sizeof(struct wpa_driver_scan_filter
) *
79 if (params
.filter_ssids
== NULL
)
82 ssid
= wpa_s
->conf
->ssid
;
84 if (!wpas_network_disabled(ssid
)) {
85 params
.ssids
[i
].ssid
= ssid
->ssid
;
86 params
.ssids
[i
].ssid_len
= ssid
->ssid_len
;
88 os_memcpy(params
.filter_ssids
[i
].ssid
, ssid
->ssid
,
90 params
.filter_ssids
[i
].ssid_len
= ssid
->ssid_len
;
91 params
.num_filter_ssids
++;
99 ret
= wpa_drv_sched_scan(wpa_s
, ¶ms
, 10 * 1000);
100 os_free(params
.filter_ssids
);
107 static int pno_stop(struct wpa_supplicant
*wpa_s
)
111 return wpa_drv_stop_sched_scan(wpa_s
);
117 static int set_bssid_filter(struct wpa_supplicant
*wpa_s
, char *val
)
120 u8 addr
[ETH_ALEN
], *filter
= NULL
, *n
;
127 if (hwaddr_aton(pos
, addr
)) {
131 n
= os_realloc(filter
, (count
+ 1) * ETH_ALEN
);
137 os_memcpy(filter
+ count
* ETH_ALEN
, addr
, ETH_ALEN
);
140 pos
= os_strchr(pos
, ' ');
145 wpa_hexdump(MSG_DEBUG
, "bssid_filter", filter
, count
* ETH_ALEN
);
146 os_free(wpa_s
->bssid_filter
);
147 wpa_s
->bssid_filter
= filter
;
148 wpa_s
->bssid_filter_count
= count
;
154 static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant
*wpa_s
,
160 value
= os_strchr(cmd
, ' ');
165 wpa_printf(MSG_DEBUG
, "CTRL_IFACE SET '%s'='%s'", cmd
, value
);
166 if (os_strcasecmp(cmd
, "EAPOL::heldPeriod") == 0) {
167 eapol_sm_configure(wpa_s
->eapol
,
168 atoi(value
), -1, -1, -1);
169 } else if (os_strcasecmp(cmd
, "EAPOL::authPeriod") == 0) {
170 eapol_sm_configure(wpa_s
->eapol
,
171 -1, atoi(value
), -1, -1);
172 } else if (os_strcasecmp(cmd
, "EAPOL::startPeriod") == 0) {
173 eapol_sm_configure(wpa_s
->eapol
,
174 -1, -1, atoi(value
), -1);
175 } else if (os_strcasecmp(cmd
, "EAPOL::maxStart") == 0) {
176 eapol_sm_configure(wpa_s
->eapol
,
177 -1, -1, -1, atoi(value
));
178 } else if (os_strcasecmp(cmd
, "dot11RSNAConfigPMKLifetime") == 0) {
179 if (wpa_sm_set_param(wpa_s
->wpa
, RSNA_PMK_LIFETIME
,
182 } else if (os_strcasecmp(cmd
, "dot11RSNAConfigPMKReauthThreshold") ==
184 if (wpa_sm_set_param(wpa_s
->wpa
, RSNA_PMK_REAUTH_THRESHOLD
,
187 } else if (os_strcasecmp(cmd
, "dot11RSNAConfigSATimeout") == 0) {
188 if (wpa_sm_set_param(wpa_s
->wpa
, RSNA_SA_TIMEOUT
, atoi(value
)))
190 } else if (os_strcasecmp(cmd
, "wps_fragment_size") == 0) {
191 wpa_s
->wps_fragment_size
= atoi(value
);
192 #ifdef CONFIG_WPS_TESTING
193 } else if (os_strcasecmp(cmd
, "wps_version_number") == 0) {
195 val
= strtol(value
, NULL
, 0);
196 if (val
< 0 || val
> 0xff) {
198 wpa_printf(MSG_DEBUG
, "WPS: Invalid "
199 "wps_version_number %ld", val
);
201 wps_version_number
= val
;
202 wpa_printf(MSG_DEBUG
, "WPS: Testing - force WPS "
204 (wps_version_number
& 0xf0) >> 4,
205 wps_version_number
& 0x0f);
207 } else if (os_strcasecmp(cmd
, "wps_testing_dummy_cred") == 0) {
208 wps_testing_dummy_cred
= atoi(value
);
209 wpa_printf(MSG_DEBUG
, "WPS: Testing - dummy_cred=%d",
210 wps_testing_dummy_cred
);
211 #endif /* CONFIG_WPS_TESTING */
212 } else if (os_strcasecmp(cmd
, "ampdu") == 0) {
213 if (wpa_drv_ampdu(wpa_s
, atoi(value
)) < 0)
215 #ifdef CONFIG_TDLS_TESTING
216 } else if (os_strcasecmp(cmd
, "tdls_testing") == 0) {
217 extern unsigned int tdls_testing
;
218 tdls_testing
= strtol(value
, NULL
, 0);
219 wpa_printf(MSG_DEBUG
, "TDLS: tdls_testing=0x%x", tdls_testing
);
220 #endif /* CONFIG_TDLS_TESTING */
222 } else if (os_strcasecmp(cmd
, "tdls_disabled") == 0) {
223 int disabled
= atoi(value
);
224 wpa_printf(MSG_DEBUG
, "TDLS: tdls_disabled=%d", disabled
);
226 if (wpa_drv_tdls_oper(wpa_s
, TDLS_DISABLE
, NULL
) < 0)
228 } else if (wpa_drv_tdls_oper(wpa_s
, TDLS_ENABLE
, NULL
) < 0)
230 wpa_tdls_enable(wpa_s
->wpa
, !disabled
);
231 #endif /* CONFIG_TDLS */
232 } else if (os_strcasecmp(cmd
, "pno") == 0) {
234 ret
= pno_start(wpa_s
);
236 ret
= pno_stop(wpa_s
);
237 } else if (os_strcasecmp(cmd
, "radio_disabled") == 0) {
238 int disabled
= atoi(value
);
239 if (wpa_drv_radio_disable(wpa_s
, disabled
) < 0)
242 wpa_supplicant_set_state(wpa_s
, WPA_INACTIVE
);
243 } else if (os_strcasecmp(cmd
, "uapsd") == 0) {
244 if (os_strcmp(value
, "disable") == 0)
245 wpa_s
->set_sta_uapsd
= 0;
249 /* format: BE,BK,VI,VO;max SP Length */
251 pos
= os_strchr(value
, ',');
256 pos
= os_strchr(pos
, ',');
261 pos
= os_strchr(pos
, ',');
266 /* ignore max SP Length for now */
268 wpa_s
->set_sta_uapsd
= 1;
269 wpa_s
->sta_uapsd
= 0;
271 wpa_s
->sta_uapsd
|= BIT(0);
273 wpa_s
->sta_uapsd
|= BIT(1);
275 wpa_s
->sta_uapsd
|= BIT(2);
277 wpa_s
->sta_uapsd
|= BIT(3);
279 } else if (os_strcasecmp(cmd
, "ps") == 0) {
280 ret
= wpa_drv_set_p2p_powersave(wpa_s
, atoi(value
), -1, -1);
281 } else if (os_strcasecmp(cmd
, "bssid_filter") == 0) {
282 ret
= set_bssid_filter(wpa_s
, value
);
285 ret
= wpa_config_process_global(wpa_s
->conf
, cmd
, -1);
287 wpa_supplicant_update_config(wpa_s
);
294 static int wpa_supplicant_ctrl_iface_get(struct wpa_supplicant
*wpa_s
,
295 char *cmd
, char *buf
, size_t buflen
)
299 wpa_printf(MSG_DEBUG
, "CTRL_IFACE GET '%s'", cmd
);
301 if (os_strcmp(cmd
, "version") == 0) {
302 res
= os_snprintf(buf
, buflen
, "%s", VERSION_STR
);
303 } else if (os_strcasecmp(cmd
, "country") == 0) {
304 if (wpa_s
->conf
->country
[0] && wpa_s
->conf
->country
[1])
305 res
= os_snprintf(buf
, buflen
, "%c%c",
306 wpa_s
->conf
->country
[0],
307 wpa_s
->conf
->country
[1]);
310 if (res
< 0 || (unsigned int) res
>= buflen
)
316 #ifdef IEEE8021X_EAPOL
317 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant
*wpa_s
,
321 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
323 if (hwaddr_aton(addr
, bssid
)) {
324 wpa_printf(MSG_DEBUG
, "CTRL_IFACE PREAUTH: invalid address "
329 wpa_printf(MSG_DEBUG
, "CTRL_IFACE PREAUTH " MACSTR
, MAC2STR(bssid
));
330 rsn_preauth_deinit(wpa_s
->wpa
);
331 if (rsn_preauth_init(wpa_s
->wpa
, bssid
, ssid
? &ssid
->eap
: NULL
))
336 #endif /* IEEE8021X_EAPOL */
339 #ifdef CONFIG_PEERKEY
340 /* MLME-STKSTART.request(peer) */
341 static int wpa_supplicant_ctrl_iface_stkstart(
342 struct wpa_supplicant
*wpa_s
, char *addr
)
346 if (hwaddr_aton(addr
, peer
)) {
347 wpa_printf(MSG_DEBUG
, "CTRL_IFACE STKSTART: invalid "
348 "address '%s'", addr
);
352 wpa_printf(MSG_DEBUG
, "CTRL_IFACE STKSTART " MACSTR
,
355 return wpa_sm_stkstart(wpa_s
->wpa
, peer
);
357 #endif /* CONFIG_PEERKEY */
362 static int wpa_supplicant_ctrl_iface_tdls_discover(
363 struct wpa_supplicant
*wpa_s
, char *addr
)
368 if (hwaddr_aton(addr
, peer
)) {
369 wpa_printf(MSG_DEBUG
, "CTRL_IFACE TDLS_DISCOVER: invalid "
370 "address '%s'", addr
);
374 wpa_printf(MSG_DEBUG
, "CTRL_IFACE TDLS_DISCOVER " MACSTR
,
377 if (wpa_tdls_is_external_setup(wpa_s
->wpa
))
378 ret
= wpa_tdls_send_discovery_request(wpa_s
->wpa
, peer
);
380 ret
= wpa_drv_tdls_oper(wpa_s
, TDLS_DISCOVERY_REQ
, peer
);
386 static int wpa_supplicant_ctrl_iface_tdls_setup(
387 struct wpa_supplicant
*wpa_s
, char *addr
)
392 if (hwaddr_aton(addr
, peer
)) {
393 wpa_printf(MSG_DEBUG
, "CTRL_IFACE TDLS_SETUP: invalid "
394 "address '%s'", addr
);
398 wpa_printf(MSG_DEBUG
, "CTRL_IFACE TDLS_SETUP " MACSTR
,
401 ret
= wpa_tdls_reneg(wpa_s
->wpa
, peer
);
403 if (wpa_tdls_is_external_setup(wpa_s
->wpa
))
404 ret
= wpa_tdls_start(wpa_s
->wpa
, peer
);
406 ret
= wpa_drv_tdls_oper(wpa_s
, TDLS_SETUP
, peer
);
413 static int wpa_supplicant_ctrl_iface_tdls_teardown(
414 struct wpa_supplicant
*wpa_s
, char *addr
)
418 if (hwaddr_aton(addr
, peer
)) {
419 wpa_printf(MSG_DEBUG
, "CTRL_IFACE TDLS_TEARDOWN: invalid "
420 "address '%s'", addr
);
424 wpa_printf(MSG_DEBUG
, "CTRL_IFACE TDLS_TEARDOWN " MACSTR
,
427 return wpa_tdls_teardown_link(wpa_s
->wpa
, peer
,
428 WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED
);
431 #endif /* CONFIG_TDLS */
434 #ifdef CONFIG_IEEE80211R
435 static int wpa_supplicant_ctrl_iface_ft_ds(
436 struct wpa_supplicant
*wpa_s
, char *addr
)
438 u8 target_ap
[ETH_ALEN
];
442 if (hwaddr_aton(addr
, target_ap
)) {
443 wpa_printf(MSG_DEBUG
, "CTRL_IFACE FT_DS: invalid "
444 "address '%s'", addr
);
448 wpa_printf(MSG_DEBUG
, "CTRL_IFACE FT_DS " MACSTR
, MAC2STR(target_ap
));
450 bss
= wpa_bss_get_bssid(wpa_s
, target_ap
);
452 mdie
= wpa_bss_get_ie(bss
, WLAN_EID_MOBILITY_DOMAIN
);
456 return wpa_ft_start_over_ds(wpa_s
->wpa
, target_ap
, mdie
);
458 #endif /* CONFIG_IEEE80211R */
462 static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant
*wpa_s
,
465 u8 bssid
[ETH_ALEN
], *_bssid
= bssid
;
467 u8 p2p_dev_addr
[ETH_ALEN
];
468 #endif /* CONFIG_P2P */
470 u8
*_p2p_dev_addr
= NULL
;
471 #endif /* CONFIG_AP */
473 if (cmd
== NULL
|| os_strcmp(cmd
, "any") == 0) {
476 } else if (os_strncmp(cmd
, "p2p_dev_addr=", 13) == 0) {
477 if (hwaddr_aton(cmd
+ 13, p2p_dev_addr
)) {
478 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_PBC: invalid "
479 "P2P Device Address '%s'",
483 _p2p_dev_addr
= p2p_dev_addr
;
484 #endif /* CONFIG_P2P */
485 } else if (hwaddr_aton(cmd
, bssid
)) {
486 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
493 return wpa_supplicant_ap_wps_pbc(wpa_s
, _bssid
, _p2p_dev_addr
);
494 #endif /* CONFIG_AP */
496 return wpas_wps_start_pbc(wpa_s
, _bssid
, 0);
500 static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant
*wpa_s
,
501 char *cmd
, char *buf
,
504 u8 bssid
[ETH_ALEN
], *_bssid
= bssid
;
508 pin
= os_strchr(cmd
, ' ');
512 if (os_strcmp(cmd
, "any") == 0)
514 else if (os_strcmp(cmd
, "get") == 0) {
515 ret
= wps_generate_pin();
517 } else if (hwaddr_aton(cmd
, bssid
)) {
518 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
525 return wpa_supplicant_ap_wps_pin(wpa_s
, _bssid
, pin
,
527 #endif /* CONFIG_AP */
530 ret
= wpas_wps_start_pin(wpa_s
, _bssid
, pin
, 0,
534 ret
= os_snprintf(buf
, buflen
, "%s", pin
);
535 if (ret
< 0 || (size_t) ret
>= buflen
)
540 ret
= wpas_wps_start_pin(wpa_s
, _bssid
, NULL
, 0, DEV_PW_DEFAULT
);
545 /* Return the generated PIN */
546 ret
= os_snprintf(buf
, buflen
, "%08d", ret
);
547 if (ret
< 0 || (size_t) ret
>= buflen
)
553 static int wpa_supplicant_ctrl_iface_wps_check_pin(
554 struct wpa_supplicant
*wpa_s
, char *cmd
, char *buf
, size_t buflen
)
561 wpa_hexdump_ascii_key(MSG_DEBUG
, "WPS_CHECK_PIN",
562 (u8
*) cmd
, os_strlen(cmd
));
563 for (pos
= cmd
, len
= 0; *pos
!= '\0'; pos
++) {
564 if (*pos
< '0' || *pos
> '9')
568 wpa_printf(MSG_DEBUG
, "WPS: Too long PIN");
572 if (len
!= 4 && len
!= 8) {
573 wpa_printf(MSG_DEBUG
, "WPS: Invalid PIN length %d", (int) len
);
579 unsigned int pin_val
;
581 if (!wps_pin_valid(pin_val
)) {
582 wpa_printf(MSG_DEBUG
, "WPS: Invalid checksum digit");
583 ret
= os_snprintf(buf
, buflen
, "FAIL-CHECKSUM\n");
584 if (ret
< 0 || (size_t) ret
>= buflen
)
590 ret
= os_snprintf(buf
, buflen
, "%s", pin
);
591 if (ret
< 0 || (size_t) ret
>= buflen
)
598 #ifdef CONFIG_WPS_OOB
599 static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant
*wpa_s
,
602 char *path
, *method
, *name
;
604 path
= os_strchr(cmd
, ' ');
609 method
= os_strchr(path
, ' ');
614 name
= os_strchr(method
, ' ');
618 return wpas_wps_start_oob(wpa_s
, cmd
, path
, method
, name
);
620 #endif /* CONFIG_WPS_OOB */
623 static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant
*wpa_s
,
632 struct wps_new_ap_settings ap
;
634 pin
= os_strchr(cmd
, ' ');
639 if (hwaddr_aton(cmd
, bssid
)) {
640 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_REG: invalid BSSID '%s'",
645 new_ssid
= os_strchr(pin
, ' ');
646 if (new_ssid
== NULL
)
647 return wpas_wps_start_reg(wpa_s
, bssid
, pin
, NULL
);
650 new_auth
= os_strchr(new_ssid
, ' ');
651 if (new_auth
== NULL
)
655 new_encr
= os_strchr(new_auth
, ' ');
656 if (new_encr
== NULL
)
660 new_key
= os_strchr(new_encr
, ' ');
665 os_memset(&ap
, 0, sizeof(ap
));
666 ap
.ssid_hex
= new_ssid
;
669 ap
.key_hex
= new_key
;
670 return wpas_wps_start_reg(wpa_s
, bssid
, pin
, &ap
);
675 static int wpa_supplicant_ctrl_iface_wps_ap_pin(struct wpa_supplicant
*wpa_s
,
676 char *cmd
, char *buf
,
683 if (!wpa_s
->ap_iface
)
686 pos
= os_strchr(cmd
, ' ');
690 if (os_strcmp(cmd
, "disable") == 0) {
691 wpas_wps_ap_pin_disable(wpa_s
);
692 return os_snprintf(buf
, buflen
, "OK\n");
695 if (os_strcmp(cmd
, "random") == 0) {
698 pin_txt
= wpas_wps_ap_pin_random(wpa_s
, timeout
);
701 return os_snprintf(buf
, buflen
, "%s", pin_txt
);
704 if (os_strcmp(cmd
, "get") == 0) {
705 pin_txt
= wpas_wps_ap_pin_get(wpa_s
);
708 return os_snprintf(buf
, buflen
, "%s", pin_txt
);
711 if (os_strcmp(cmd
, "set") == 0) {
716 pos
= os_strchr(pos
, ' ');
721 if (os_strlen(pin
) > buflen
)
723 if (wpas_wps_ap_pin_set(wpa_s
, pin
, timeout
) < 0)
725 return os_snprintf(buf
, buflen
, "%s", pin
);
730 #endif /* CONFIG_AP */
734 static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant
*wpa_s
,
737 char *uuid
= cmd
, *pin
, *pos
;
738 u8 addr_buf
[ETH_ALEN
], *addr
= NULL
;
739 pin
= os_strchr(uuid
, ' ');
743 pos
= os_strchr(pin
, ' ');
746 if (hwaddr_aton(pos
, addr_buf
) == 0)
749 return wpas_wps_er_add_pin(wpa_s
, addr
, uuid
, pin
);
753 static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant
*wpa_s
,
756 char *uuid
= cmd
, *pin
;
757 pin
= os_strchr(uuid
, ' ');
761 return wpas_wps_er_learn(wpa_s
, uuid
, pin
);
765 static int wpa_supplicant_ctrl_iface_wps_er_set_config(
766 struct wpa_supplicant
*wpa_s
, char *cmd
)
768 char *uuid
= cmd
, *id
;
769 id
= os_strchr(uuid
, ' ');
773 return wpas_wps_er_set_config(wpa_s
, uuid
, atoi(id
));
777 static int wpa_supplicant_ctrl_iface_wps_er_config(
778 struct wpa_supplicant
*wpa_s
, char *cmd
)
785 struct wps_new_ap_settings ap
;
787 pin
= os_strchr(cmd
, ' ');
792 new_ssid
= os_strchr(pin
, ' ');
793 if (new_ssid
== NULL
)
797 new_auth
= os_strchr(new_ssid
, ' ');
798 if (new_auth
== NULL
)
802 new_encr
= os_strchr(new_auth
, ' ');
803 if (new_encr
== NULL
)
807 new_key
= os_strchr(new_encr
, ' ');
812 os_memset(&ap
, 0, sizeof(ap
));
813 ap
.ssid_hex
= new_ssid
;
816 ap
.key_hex
= new_key
;
817 return wpas_wps_er_config(wpa_s
, cmd
, pin
, &ap
);
819 #endif /* CONFIG_WPS_ER */
821 #endif /* CONFIG_WPS */
824 #ifdef CONFIG_IBSS_RSN
825 static int wpa_supplicant_ctrl_iface_ibss_rsn(
826 struct wpa_supplicant
*wpa_s
, char *addr
)
830 if (hwaddr_aton(addr
, peer
)) {
831 wpa_printf(MSG_DEBUG
, "CTRL_IFACE IBSS_RSN: invalid "
832 "address '%s'", addr
);
836 wpa_printf(MSG_DEBUG
, "CTRL_IFACE IBSS_RSN " MACSTR
,
839 return ibss_rsn_start(wpa_s
->ibss_rsn
, peer
);
841 #endif /* CONFIG_IBSS_RSN */
844 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant
*wpa_s
,
847 #ifdef IEEE8021X_EAPOL
850 struct wpa_ssid
*ssid
;
852 pos
= os_strchr(rsp
, '-');
857 pos
= os_strchr(pos
, ':');
862 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: field=%s id=%d", rsp
, id
);
863 wpa_hexdump_ascii_key(MSG_DEBUG
, "CTRL_IFACE: value",
864 (u8
*) pos
, os_strlen(pos
));
866 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
868 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
873 return wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s
, ssid
, rsp
,
875 #else /* IEEE8021X_EAPOL */
876 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: 802.1X not included");
878 #endif /* IEEE8021X_EAPOL */
882 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant
*wpa_s
,
884 char *buf
, size_t buflen
)
886 char *pos
, *end
, tmp
[30];
887 int res
, verbose
, wps
, ret
;
889 verbose
= os_strcmp(params
, "-VERBOSE") == 0;
890 wps
= os_strcmp(params
, "-WPS") == 0;
893 if (wpa_s
->wpa_state
>= WPA_ASSOCIATED
) {
894 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
895 ret
= os_snprintf(pos
, end
- pos
, "bssid=" MACSTR
"\n",
896 MAC2STR(wpa_s
->bssid
));
897 if (ret
< 0 || ret
>= end
- pos
)
901 u8
*_ssid
= ssid
->ssid
;
902 size_t ssid_len
= ssid
->ssid_len
;
903 u8 ssid_buf
[MAX_SSID_LEN
];
905 int _res
= wpa_drv_get_ssid(wpa_s
, ssid_buf
);
912 ret
= os_snprintf(pos
, end
- pos
, "ssid=%s\nid=%d\n",
913 wpa_ssid_txt(_ssid
, ssid_len
),
915 if (ret
< 0 || ret
>= end
- pos
)
919 if (wps
&& ssid
->passphrase
&&
920 wpa_key_mgmt_wpa_psk(ssid
->key_mgmt
) &&
921 (ssid
->mode
== WPAS_MODE_AP
||
922 ssid
->mode
== WPAS_MODE_P2P_GO
)) {
923 ret
= os_snprintf(pos
, end
- pos
,
926 if (ret
< 0 || ret
>= end
- pos
)
931 ret
= os_snprintf(pos
, end
- pos
,
934 if (ret
< 0 || ret
>= end
- pos
)
939 switch (ssid
->mode
) {
940 case WPAS_MODE_INFRA
:
941 ret
= os_snprintf(pos
, end
- pos
,
945 ret
= os_snprintf(pos
, end
- pos
,
949 ret
= os_snprintf(pos
, end
- pos
,
952 case WPAS_MODE_P2P_GO
:
953 ret
= os_snprintf(pos
, end
- pos
,
956 case WPAS_MODE_P2P_GROUP_FORMATION
:
957 ret
= os_snprintf(pos
, end
- pos
,
958 "mode=P2P GO - group "
965 if (ret
< 0 || ret
>= end
- pos
)
971 if (wpa_s
->ap_iface
) {
972 pos
+= ap_ctrl_iface_wpa_get_status(wpa_s
, pos
,
976 #endif /* CONFIG_AP */
977 pos
+= wpa_sm_get_status(wpa_s
->wpa
, pos
, end
- pos
, verbose
);
979 ret
= os_snprintf(pos
, end
- pos
, "wpa_state=%s\n",
980 wpa_supplicant_state_txt(wpa_s
->wpa_state
));
981 if (ret
< 0 || ret
>= end
- pos
)
986 l2_packet_get_ip_addr(wpa_s
->l2
, tmp
, sizeof(tmp
)) >= 0) {
987 ret
= os_snprintf(pos
, end
- pos
, "ip_address=%s\n", tmp
);
988 if (ret
< 0 || ret
>= end
- pos
)
994 if (wpa_s
->global
->p2p
) {
995 ret
= os_snprintf(pos
, end
- pos
, "p2p_device_address=" MACSTR
996 "\n", MAC2STR(wpa_s
->global
->p2p_dev_addr
));
997 if (ret
< 0 || ret
>= end
- pos
)
1001 #endif /* CONFIG_P2P */
1003 ret
= os_snprintf(pos
, end
- pos
, "address=" MACSTR
"\n",
1004 MAC2STR(wpa_s
->own_addr
));
1005 if (ret
< 0 || ret
>= end
- pos
)
1009 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s
->key_mgmt
) ||
1010 wpa_s
->key_mgmt
== WPA_KEY_MGMT_IEEE8021X_NO_WPA
) {
1011 res
= eapol_sm_get_status(wpa_s
->eapol
, pos
, end
- pos
,
1017 res
= rsn_preauth_get_status(wpa_s
->wpa
, pos
, end
- pos
, verbose
);
1025 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant
*wpa_s
,
1030 struct wpa_ssid
*ssid
;
1033 /* cmd: "<network id> <BSSID>" */
1034 pos
= os_strchr(cmd
, ' ');
1039 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: id=%d bssid='%s'", id
, pos
);
1040 if (hwaddr_aton(pos
, bssid
)) {
1041 wpa_printf(MSG_DEBUG
,"CTRL_IFACE: invalid BSSID '%s'", pos
);
1045 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1047 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
1052 os_memcpy(ssid
->bssid
, bssid
, ETH_ALEN
);
1053 ssid
->bssid_set
= !is_zero_ether_addr(bssid
);
1059 static int wpa_supplicant_ctrl_iface_blacklist(struct wpa_supplicant
*wpa_s
,
1060 char *cmd
, char *buf
,
1064 struct wpa_blacklist
*e
;
1068 /* cmd: "BLACKLIST [<BSSID>]" */
1072 e
= wpa_s
->blacklist
;
1074 ret
= os_snprintf(pos
, end
- pos
, MACSTR
"\n",
1076 if (ret
< 0 || ret
>= end
- pos
)
1085 if (os_strncmp(cmd
, "clear", 5) == 0) {
1086 wpa_blacklist_clear(wpa_s
);
1087 os_memcpy(buf
, "OK\n", 3);
1091 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: BLACKLIST bssid='%s'", cmd
);
1092 if (hwaddr_aton(cmd
, bssid
)) {
1093 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: invalid BSSID '%s'", cmd
);
1098 * Add the BSSID twice, so its count will be 2, causing it to be
1099 * skipped when processing scan results.
1101 ret
= wpa_blacklist_add(wpa_s
, bssid
);
1104 ret
= wpa_blacklist_add(wpa_s
, bssid
);
1107 os_memcpy(buf
, "OK\n", 3);
1112 extern int wpa_debug_level
;
1113 extern int wpa_debug_timestamp
;
1115 static const char * debug_level_str(int level
)
1136 static int str_to_debug_level(const char *s
)
1138 if (os_strcasecmp(s
, "EXCESSIVE") == 0)
1139 return MSG_EXCESSIVE
;
1140 if (os_strcasecmp(s
, "MSGDUMP") == 0)
1142 if (os_strcasecmp(s
, "DEBUG") == 0)
1144 if (os_strcasecmp(s
, "INFO") == 0)
1146 if (os_strcasecmp(s
, "WARNING") == 0)
1148 if (os_strcasecmp(s
, "ERROR") == 0)
1154 static int wpa_supplicant_ctrl_iface_log_level(struct wpa_supplicant
*wpa_s
,
1155 char *cmd
, char *buf
,
1158 char *pos
, *end
, *stamp
;
1165 /* cmd: "LOG_LEVEL [<level>]" */
1169 ret
= os_snprintf(pos
, end
- pos
, "Current level: %s\n"
1171 debug_level_str(wpa_debug_level
),
1172 wpa_debug_timestamp
);
1173 if (ret
< 0 || ret
>= end
- pos
)
1182 stamp
= os_strchr(cmd
, ' ');
1185 while (*stamp
== ' ') {
1190 if (cmd
&& os_strlen(cmd
)) {
1191 int level
= str_to_debug_level(cmd
);
1194 wpa_debug_level
= level
;
1197 if (stamp
&& os_strlen(stamp
))
1198 wpa_debug_timestamp
= atoi(stamp
);
1200 os_memcpy(buf
, "OK\n", 3);
1205 static int wpa_supplicant_ctrl_iface_list_networks(
1206 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
1209 struct wpa_ssid
*ssid
;
1214 ret
= os_snprintf(pos
, end
- pos
,
1215 "network id / ssid / bssid / flags\n");
1216 if (ret
< 0 || ret
>= end
- pos
)
1220 ssid
= wpa_s
->conf
->ssid
;
1222 ret
= os_snprintf(pos
, end
- pos
, "%d\t%s",
1224 wpa_ssid_txt(ssid
->ssid
, ssid
->ssid_len
));
1225 if (ret
< 0 || ret
>= end
- pos
)
1228 if (ssid
->bssid_set
) {
1229 ret
= os_snprintf(pos
, end
- pos
, "\t" MACSTR
,
1230 MAC2STR(ssid
->bssid
));
1232 ret
= os_snprintf(pos
, end
- pos
, "\tany");
1234 if (ret
< 0 || ret
>= end
- pos
)
1237 ret
= os_snprintf(pos
, end
- pos
, "\t%s%s%s",
1238 ssid
== wpa_s
->current_ssid
?
1240 ssid
->disabled
? "[DISABLED]" : "",
1241 ssid
->disabled
== 2 ? "[P2P-PERSISTENT]" :
1243 if (ret
< 0 || ret
>= end
- pos
)
1246 ret
= os_snprintf(pos
, end
- pos
, "\n");
1247 if (ret
< 0 || ret
>= end
- pos
)
1258 static char * wpa_supplicant_cipher_txt(char *pos
, char *end
, int cipher
)
1261 ret
= os_snprintf(pos
, end
- pos
, "-");
1262 if (ret
< 0 || ret
>= end
- pos
)
1265 if (cipher
& WPA_CIPHER_NONE
) {
1266 ret
= os_snprintf(pos
, end
- pos
, "%sNONE", first
? "" : "+");
1267 if (ret
< 0 || ret
>= end
- pos
)
1272 if (cipher
& WPA_CIPHER_WEP40
) {
1273 ret
= os_snprintf(pos
, end
- pos
, "%sWEP40", first
? "" : "+");
1274 if (ret
< 0 || ret
>= end
- pos
)
1279 if (cipher
& WPA_CIPHER_WEP104
) {
1280 ret
= os_snprintf(pos
, end
- pos
, "%sWEP104",
1282 if (ret
< 0 || ret
>= end
- pos
)
1287 if (cipher
& WPA_CIPHER_TKIP
) {
1288 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : "+");
1289 if (ret
< 0 || ret
>= end
- pos
)
1294 if (cipher
& WPA_CIPHER_CCMP
) {
1295 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : "+");
1296 if (ret
< 0 || ret
>= end
- pos
)
1305 static char * wpa_supplicant_ie_txt(char *pos
, char *end
, const char *proto
,
1306 const u8
*ie
, size_t ie_len
)
1308 struct wpa_ie_data data
;
1311 ret
= os_snprintf(pos
, end
- pos
, "[%s-", proto
);
1312 if (ret
< 0 || ret
>= end
- pos
)
1316 if (wpa_parse_wpa_ie(ie
, ie_len
, &data
) < 0) {
1317 ret
= os_snprintf(pos
, end
- pos
, "?]");
1318 if (ret
< 0 || ret
>= end
- pos
)
1325 if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X
) {
1326 ret
= os_snprintf(pos
, end
- pos
, "%sEAP", first
? "" : "+");
1327 if (ret
< 0 || ret
>= end
- pos
)
1332 if (data
.key_mgmt
& WPA_KEY_MGMT_PSK
) {
1333 ret
= os_snprintf(pos
, end
- pos
, "%sPSK", first
? "" : "+");
1334 if (ret
< 0 || ret
>= end
- pos
)
1339 if (data
.key_mgmt
& WPA_KEY_MGMT_WPA_NONE
) {
1340 ret
= os_snprintf(pos
, end
- pos
, "%sNone", first
? "" : "+");
1341 if (ret
< 0 || ret
>= end
- pos
)
1346 #ifdef CONFIG_IEEE80211R
1347 if (data
.key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
) {
1348 ret
= os_snprintf(pos
, end
- pos
, "%sFT/EAP",
1350 if (ret
< 0 || ret
>= end
- pos
)
1355 if (data
.key_mgmt
& WPA_KEY_MGMT_FT_PSK
) {
1356 ret
= os_snprintf(pos
, end
- pos
, "%sFT/PSK",
1358 if (ret
< 0 || ret
>= end
- pos
)
1363 #endif /* CONFIG_IEEE80211R */
1364 #ifdef CONFIG_IEEE80211W
1365 if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
) {
1366 ret
= os_snprintf(pos
, end
- pos
, "%sEAP-SHA256",
1368 if (ret
< 0 || ret
>= end
- pos
)
1373 if (data
.key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
) {
1374 ret
= os_snprintf(pos
, end
- pos
, "%sPSK-SHA256",
1376 if (ret
< 0 || ret
>= end
- pos
)
1381 #endif /* CONFIG_IEEE80211W */
1383 pos
= wpa_supplicant_cipher_txt(pos
, end
, data
.pairwise_cipher
);
1385 if (data
.capabilities
& WPA_CAPABILITY_PREAUTH
) {
1386 ret
= os_snprintf(pos
, end
- pos
, "-preauth");
1387 if (ret
< 0 || ret
>= end
- pos
)
1392 ret
= os_snprintf(pos
, end
- pos
, "]");
1393 if (ret
< 0 || ret
>= end
- pos
)
1402 static char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant
*wpa_s
,
1403 char *pos
, char *end
,
1404 struct wpabuf
*wps_ie
)
1411 if (wps_is_selected_pbc_registrar(wps_ie
))
1414 else if (wps_is_addr_authorized(wps_ie
, wpa_s
->own_addr
, 0))
1416 #endif /* CONFIG_WPS2 */
1417 else if (wps_is_selected_pin_registrar(wps_ie
))
1422 ret
= os_snprintf(pos
, end
- pos
, "%s", txt
);
1423 if (ret
>= 0 && ret
< end
- pos
)
1425 wpabuf_free(wps_ie
);
1428 #endif /* CONFIG_WPS */
1431 static char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant
*wpa_s
,
1432 char *pos
, char *end
,
1433 const struct wpa_bss
*bss
)
1436 struct wpabuf
*wps_ie
;
1437 wps_ie
= wpa_bss_get_vendor_ie_multi(bss
, WPS_IE_VENDOR_TYPE
);
1438 return wpa_supplicant_wps_ie_txt_buf(wpa_s
, pos
, end
, wps_ie
);
1439 #else /* CONFIG_WPS */
1441 #endif /* CONFIG_WPS */
1445 /* Format one result on one text line into a buffer. */
1446 static int wpa_supplicant_ctrl_iface_scan_result(
1447 struct wpa_supplicant
*wpa_s
,
1448 const struct wpa_bss
*bss
, char *buf
, size_t buflen
)
1452 const u8
*ie
, *ie2
, *p2p
;
1454 p2p
= wpa_bss_get_vendor_ie(bss
, P2P_IE_VENDOR_TYPE
);
1455 if (p2p
&& bss
->ssid_len
== P2P_WILDCARD_SSID_LEN
&&
1456 os_memcmp(bss
->ssid
, P2P_WILDCARD_SSID
, P2P_WILDCARD_SSID_LEN
) ==
1458 return 0; /* Do not show P2P listen discovery results here */
1463 ret
= os_snprintf(pos
, end
- pos
, MACSTR
"\t%d\t%d\t",
1464 MAC2STR(bss
->bssid
), bss
->freq
, bss
->level
);
1465 if (ret
< 0 || ret
>= end
- pos
)
1468 ie
= wpa_bss_get_vendor_ie(bss
, WPA_IE_VENDOR_TYPE
);
1470 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA", ie
, 2 + ie
[1]);
1471 ie2
= wpa_bss_get_ie(bss
, WLAN_EID_RSN
);
1473 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA2", ie2
, 2 + ie2
[1]);
1474 pos
= wpa_supplicant_wps_ie_txt(wpa_s
, pos
, end
, bss
);
1475 if (!ie
&& !ie2
&& bss
->caps
& IEEE80211_CAP_PRIVACY
) {
1476 ret
= os_snprintf(pos
, end
- pos
, "[WEP]");
1477 if (ret
< 0 || ret
>= end
- pos
)
1481 if (bss
->caps
& IEEE80211_CAP_IBSS
) {
1482 ret
= os_snprintf(pos
, end
- pos
, "[IBSS]");
1483 if (ret
< 0 || ret
>= end
- pos
)
1487 if (bss
->caps
& IEEE80211_CAP_ESS
) {
1488 ret
= os_snprintf(pos
, end
- pos
, "[ESS]");
1489 if (ret
< 0 || ret
>= end
- pos
)
1494 ret
= os_snprintf(pos
, end
- pos
, "[P2P]");
1495 if (ret
< 0 || ret
>= end
- pos
)
1500 ret
= os_snprintf(pos
, end
- pos
, "\t%s",
1501 wpa_ssid_txt(bss
->ssid
, bss
->ssid_len
));
1502 if (ret
< 0 || ret
>= end
- pos
)
1506 ret
= os_snprintf(pos
, end
- pos
, "\n");
1507 if (ret
< 0 || ret
>= end
- pos
)
1515 static int wpa_supplicant_ctrl_iface_scan_results(
1516 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
1519 struct wpa_bss
*bss
;
1524 ret
= os_snprintf(pos
, end
- pos
, "bssid / frequency / signal level / "
1526 if (ret
< 0 || ret
>= end
- pos
)
1530 dl_list_for_each(bss
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
) {
1531 ret
= wpa_supplicant_ctrl_iface_scan_result(wpa_s
, bss
, pos
,
1533 if (ret
< 0 || ret
>= end
- pos
)
1542 static int wpa_supplicant_ctrl_iface_select_network(
1543 struct wpa_supplicant
*wpa_s
, char *cmd
)
1546 struct wpa_ssid
*ssid
;
1548 /* cmd: "<network id>" or "any" */
1549 if (os_strcmp(cmd
, "any") == 0) {
1550 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SELECT_NETWORK any");
1554 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SELECT_NETWORK id=%d", id
);
1556 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1558 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
1559 "network id=%d", id
);
1562 if (ssid
->disabled
== 2) {
1563 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Cannot use "
1564 "SELECT_NETWORK with persistent P2P group");
1569 wpa_supplicant_select_network(wpa_s
, ssid
);
1575 static int wpa_supplicant_ctrl_iface_enable_network(
1576 struct wpa_supplicant
*wpa_s
, char *cmd
)
1579 struct wpa_ssid
*ssid
;
1581 /* cmd: "<network id>" or "all" */
1582 if (os_strcmp(cmd
, "all") == 0) {
1583 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ENABLE_NETWORK all");
1587 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ENABLE_NETWORK id=%d", id
);
1589 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1591 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
1592 "network id=%d", id
);
1595 if (ssid
->disabled
== 2) {
1596 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Cannot use "
1597 "ENABLE_NETWORK with persistent P2P group");
1601 if (os_strstr(cmd
, " no-connect")) {
1606 wpa_supplicant_enable_network(wpa_s
, ssid
);
1612 static int wpa_supplicant_ctrl_iface_disable_network(
1613 struct wpa_supplicant
*wpa_s
, char *cmd
)
1616 struct wpa_ssid
*ssid
;
1618 /* cmd: "<network id>" or "all" */
1619 if (os_strcmp(cmd
, "all") == 0) {
1620 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: DISABLE_NETWORK all");
1624 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: DISABLE_NETWORK id=%d", id
);
1626 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1628 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
1629 "network id=%d", id
);
1632 if (ssid
->disabled
== 2) {
1633 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Cannot use "
1634 "DISABLE_NETWORK with persistent P2P "
1639 wpa_supplicant_disable_network(wpa_s
, ssid
);
1645 static int wpa_supplicant_ctrl_iface_add_network(
1646 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
1648 struct wpa_ssid
*ssid
;
1651 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ADD_NETWORK");
1653 ssid
= wpa_config_add_network(wpa_s
->conf
);
1657 wpas_notify_network_added(wpa_s
, ssid
);
1660 wpa_config_set_network_defaults(ssid
);
1662 ret
= os_snprintf(buf
, buflen
, "%d\n", ssid
->id
);
1663 if (ret
< 0 || (size_t) ret
>= buflen
)
1669 static int wpa_supplicant_ctrl_iface_remove_network(
1670 struct wpa_supplicant
*wpa_s
, char *cmd
)
1673 struct wpa_ssid
*ssid
;
1675 /* cmd: "<network id>" or "all" */
1676 if (os_strcmp(cmd
, "all") == 0) {
1677 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_NETWORK all");
1678 ssid
= wpa_s
->conf
->ssid
;
1680 struct wpa_ssid
*remove_ssid
= ssid
;
1683 wpas_notify_network_removed(wpa_s
, remove_ssid
);
1684 wpa_config_remove_network(wpa_s
->conf
, id
);
1686 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
1687 if (wpa_s
->current_ssid
) {
1689 wpa_s
->sme
.prev_bssid_set
= 0;
1690 #endif /* CONFIG_SME */
1691 wpa_sm_set_config(wpa_s
->wpa
, NULL
);
1692 eapol_sm_notify_config(wpa_s
->eapol
, NULL
, NULL
);
1693 wpa_supplicant_disassociate(wpa_s
,
1694 WLAN_REASON_DEAUTH_LEAVING
);
1700 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_NETWORK id=%d", id
);
1702 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1704 wpas_notify_network_removed(wpa_s
, ssid
);
1706 wpa_config_remove_network(wpa_s
->conf
, id
) < 0) {
1707 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
1712 if (ssid
== wpa_s
->current_ssid
|| wpa_s
->current_ssid
== NULL
) {
1714 wpa_s
->sme
.prev_bssid_set
= 0;
1715 #endif /* CONFIG_SME */
1717 * Invalidate the EAP session cache if the current or
1718 * previously used network is removed.
1720 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
1723 if (ssid
== wpa_s
->current_ssid
) {
1724 wpa_sm_set_config(wpa_s
->wpa
, NULL
);
1725 eapol_sm_notify_config(wpa_s
->eapol
, NULL
, NULL
);
1727 wpa_supplicant_disassociate(wpa_s
, WLAN_REASON_DEAUTH_LEAVING
);
1734 static int wpa_supplicant_ctrl_iface_set_network(
1735 struct wpa_supplicant
*wpa_s
, char *cmd
)
1738 struct wpa_ssid
*ssid
;
1741 /* cmd: "<network id> <variable name> <value>" */
1742 name
= os_strchr(cmd
, ' ');
1747 value
= os_strchr(name
, ' ');
1753 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
1755 wpa_hexdump_ascii_key(MSG_DEBUG
, "CTRL_IFACE: value",
1756 (u8
*) value
, os_strlen(value
));
1758 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1760 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
1765 if (wpa_config_set(ssid
, name
, value
, 0) < 0) {
1766 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Failed to set network "
1767 "variable '%s'", name
);
1771 wpa_sm_pmksa_cache_flush(wpa_s
->wpa
, ssid
);
1773 if (wpa_s
->current_ssid
== ssid
|| wpa_s
->current_ssid
== NULL
) {
1775 * Invalidate the EAP session cache if anything in the current
1776 * or previously used configuration changes.
1778 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
1781 if ((os_strcmp(name
, "psk") == 0 &&
1782 value
[0] == '"' && ssid
->ssid_len
) ||
1783 (os_strcmp(name
, "ssid") == 0 && ssid
->passphrase
))
1784 wpa_config_update_psk(ssid
);
1785 else if (os_strcmp(name
, "priority") == 0)
1786 wpa_config_update_prio_list(wpa_s
->conf
);
1792 static int wpa_supplicant_ctrl_iface_get_network(
1793 struct wpa_supplicant
*wpa_s
, char *cmd
, char *buf
, size_t buflen
)
1797 struct wpa_ssid
*ssid
;
1800 /* cmd: "<network id> <variable name>" */
1801 name
= os_strchr(cmd
, ' ');
1802 if (name
== NULL
|| buflen
== 0)
1807 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
1810 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1812 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
1817 value
= wpa_config_get_no_key(ssid
, name
);
1818 if (value
== NULL
) {
1819 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Failed to get network "
1820 "variable '%s'", name
);
1824 res
= os_strlcpy(buf
, value
, buflen
);
1825 if (res
>= buflen
) {
1836 static int wpa_supplicant_ctrl_iface_list_creds(struct wpa_supplicant
*wpa_s
,
1837 char *buf
, size_t buflen
)
1840 struct wpa_cred
*cred
;
1845 ret
= os_snprintf(pos
, end
- pos
,
1846 "cred id / realm / username / domain / imsi\n");
1847 if (ret
< 0 || ret
>= end
- pos
)
1851 cred
= wpa_s
->conf
->cred
;
1853 ret
= os_snprintf(pos
, end
- pos
, "%d\t%s\t%s\t%s\t%s\n",
1854 cred
->id
, cred
->realm
? cred
->realm
: "",
1855 cred
->username
? cred
->username
: "",
1856 cred
->domain
? cred
->domain
: "",
1857 cred
->imsi
? cred
->imsi
: "");
1858 if (ret
< 0 || ret
>= end
- pos
)
1869 static int wpa_supplicant_ctrl_iface_add_cred(struct wpa_supplicant
*wpa_s
,
1870 char *buf
, size_t buflen
)
1872 struct wpa_cred
*cred
;
1875 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ADD_CRED");
1877 cred
= wpa_config_add_cred(wpa_s
->conf
);
1881 ret
= os_snprintf(buf
, buflen
, "%d\n", cred
->id
);
1882 if (ret
< 0 || (size_t) ret
>= buflen
)
1888 static int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant
*wpa_s
,
1892 struct wpa_cred
*cred
;
1894 /* cmd: "<cred id>" or "all" */
1895 if (os_strcmp(cmd
, "all") == 0) {
1896 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_CRED all");
1897 cred
= wpa_s
->conf
->cred
;
1901 wpa_config_remove_cred(wpa_s
->conf
, id
);
1907 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_CRED id=%d", id
);
1909 cred
= wpa_config_get_cred(wpa_s
->conf
, id
);
1911 wpa_config_remove_cred(wpa_s
->conf
, id
) < 0) {
1912 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find cred id=%d",
1921 static int wpa_supplicant_ctrl_iface_set_cred(struct wpa_supplicant
*wpa_s
,
1925 struct wpa_cred
*cred
;
1928 /* cmd: "<cred id> <variable name> <value>" */
1929 name
= os_strchr(cmd
, ' ');
1934 value
= os_strchr(name
, ' ');
1940 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SET_CRED id=%d name='%s'",
1942 wpa_hexdump_ascii_key(MSG_DEBUG
, "CTRL_IFACE: value",
1943 (u8
*) value
, os_strlen(value
));
1945 cred
= wpa_config_get_cred(wpa_s
->conf
, id
);
1947 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find cred id=%d",
1952 if (wpa_config_set_cred(cred
, name
, value
, 0) < 0) {
1953 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Failed to set cred "
1954 "variable '%s'", name
);
1962 #ifndef CONFIG_NO_CONFIG_WRITE
1963 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant
*wpa_s
)
1967 if (!wpa_s
->conf
->update_config
) {
1968 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
1969 "to update configuration (update_config=0)");
1973 ret
= wpa_config_write(wpa_s
->confname
, wpa_s
->conf
);
1975 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Failed to "
1976 "update configuration");
1978 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Configuration"
1984 #endif /* CONFIG_NO_CONFIG_WRITE */
1987 static int ctrl_iface_get_capability_pairwise(int res
, char *strict
,
1988 struct wpa_driver_capa
*capa
,
1989 char *buf
, size_t buflen
)
2001 len
= os_strlcpy(buf
, "CCMP TKIP NONE", buflen
);
2007 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
2008 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : " ");
2009 if (ret
< 0 || ret
>= end
- pos
)
2015 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
2016 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : " ");
2017 if (ret
< 0 || ret
>= end
- pos
)
2023 if (capa
->key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
2024 ret
= os_snprintf(pos
, end
- pos
, "%sNONE", first
? "" : " ");
2025 if (ret
< 0 || ret
>= end
- pos
)
2035 static int ctrl_iface_get_capability_group(int res
, char *strict
,
2036 struct wpa_driver_capa
*capa
,
2037 char *buf
, size_t buflen
)
2049 len
= os_strlcpy(buf
, "CCMP TKIP WEP104 WEP40", buflen
);
2055 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
2056 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : " ");
2057 if (ret
< 0 || ret
>= end
- pos
)
2063 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
2064 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : " ");
2065 if (ret
< 0 || ret
>= end
- pos
)
2071 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_WEP104
) {
2072 ret
= os_snprintf(pos
, end
- pos
, "%sWEP104",
2074 if (ret
< 0 || ret
>= end
- pos
)
2080 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_WEP40
) {
2081 ret
= os_snprintf(pos
, end
- pos
, "%sWEP40", first
? "" : " ");
2082 if (ret
< 0 || ret
>= end
- pos
)
2092 static int ctrl_iface_get_capability_key_mgmt(int res
, char *strict
,
2093 struct wpa_driver_capa
*capa
,
2094 char *buf
, size_t buflen
)
2106 len
= os_strlcpy(buf
, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE "
2113 ret
= os_snprintf(pos
, end
- pos
, "NONE IEEE8021X");
2114 if (ret
< 0 || ret
>= end
- pos
)
2118 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
2119 WPA_DRIVER_CAPA_KEY_MGMT_WPA2
)) {
2120 ret
= os_snprintf(pos
, end
- pos
, " WPA-EAP");
2121 if (ret
< 0 || ret
>= end
- pos
)
2126 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
|
2127 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
2128 ret
= os_snprintf(pos
, end
- pos
, " WPA-PSK");
2129 if (ret
< 0 || ret
>= end
- pos
)
2134 if (capa
->key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
2135 ret
= os_snprintf(pos
, end
- pos
, " WPA-NONE");
2136 if (ret
< 0 || ret
>= end
- pos
)
2145 static int ctrl_iface_get_capability_proto(int res
, char *strict
,
2146 struct wpa_driver_capa
*capa
,
2147 char *buf
, size_t buflen
)
2159 len
= os_strlcpy(buf
, "RSN WPA", buflen
);
2165 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA2
|
2166 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
2167 ret
= os_snprintf(pos
, end
- pos
, "%sRSN", first
? "" : " ");
2168 if (ret
< 0 || ret
>= end
- pos
)
2174 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
2175 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
)) {
2176 ret
= os_snprintf(pos
, end
- pos
, "%sWPA", first
? "" : " ");
2177 if (ret
< 0 || ret
>= end
- pos
)
2187 static int ctrl_iface_get_capability_auth_alg(int res
, char *strict
,
2188 struct wpa_driver_capa
*capa
,
2189 char *buf
, size_t buflen
)
2201 len
= os_strlcpy(buf
, "OPEN SHARED LEAP", buflen
);
2207 if (capa
->auth
& (WPA_DRIVER_AUTH_OPEN
)) {
2208 ret
= os_snprintf(pos
, end
- pos
, "%sOPEN", first
? "" : " ");
2209 if (ret
< 0 || ret
>= end
- pos
)
2215 if (capa
->auth
& (WPA_DRIVER_AUTH_SHARED
)) {
2216 ret
= os_snprintf(pos
, end
- pos
, "%sSHARED",
2218 if (ret
< 0 || ret
>= end
- pos
)
2224 if (capa
->auth
& (WPA_DRIVER_AUTH_LEAP
)) {
2225 ret
= os_snprintf(pos
, end
- pos
, "%sLEAP", first
? "" : " ");
2226 if (ret
< 0 || ret
>= end
- pos
)
2236 static int wpa_supplicant_ctrl_iface_get_capability(
2237 struct wpa_supplicant
*wpa_s
, const char *_field
, char *buf
,
2240 struct wpa_driver_capa capa
;
2246 /* Determine whether or not strict checking was requested */
2247 len
= os_strlcpy(field
, _field
, sizeof(field
));
2248 if (len
>= sizeof(field
))
2250 strict
= os_strchr(field
, ' ');
2251 if (strict
!= NULL
) {
2253 if (os_strcmp(strict
, "strict") != 0)
2257 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
2258 field
, strict
? strict
: "");
2260 if (os_strcmp(field
, "eap") == 0) {
2261 return eap_get_names(buf
, buflen
);
2264 res
= wpa_drv_get_capa(wpa_s
, &capa
);
2266 if (os_strcmp(field
, "pairwise") == 0)
2267 return ctrl_iface_get_capability_pairwise(res
, strict
, &capa
,
2270 if (os_strcmp(field
, "group") == 0)
2271 return ctrl_iface_get_capability_group(res
, strict
, &capa
,
2274 if (os_strcmp(field
, "key_mgmt") == 0)
2275 return ctrl_iface_get_capability_key_mgmt(res
, strict
, &capa
,
2278 if (os_strcmp(field
, "proto") == 0)
2279 return ctrl_iface_get_capability_proto(res
, strict
, &capa
,
2282 if (os_strcmp(field
, "auth_alg") == 0)
2283 return ctrl_iface_get_capability_auth_alg(res
, strict
, &capa
,
2286 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
2293 #ifdef CONFIG_INTERWORKING
2294 static char * anqp_add_hex(char *pos
, char *end
, const char *title
,
2295 struct wpabuf
*data
)
2305 ret
= os_snprintf(pos
, end
- pos
, "%s=", title
);
2306 if (ret
< 0 || ret
>= end
- pos
)
2310 d
= wpabuf_head_u8(data
);
2311 for (i
= 0; i
< wpabuf_len(data
); i
++) {
2312 ret
= os_snprintf(pos
, end
- pos
, "%02x", *d
++);
2313 if (ret
< 0 || ret
>= end
- pos
)
2318 ret
= os_snprintf(pos
, end
- pos
, "\n");
2319 if (ret
< 0 || ret
>= end
- pos
)
2325 #endif /* CONFIG_INTERWORKING */
2328 static int print_bss_info(struct wpa_supplicant
*wpa_s
, struct wpa_bss
*bss
,
2329 unsigned long mask
, char *buf
, size_t buflen
)
2339 if (mask
& WPA_BSS_MASK_ID
) {
2340 ret
= os_snprintf(pos
, end
- pos
, "id=%u\n", bss
->id
);
2341 if (ret
< 0 || ret
>= end
- pos
)
2346 if (mask
& WPA_BSS_MASK_BSSID
) {
2347 ret
= os_snprintf(pos
, end
- pos
, "bssid=" MACSTR
"\n",
2348 MAC2STR(bss
->bssid
));
2349 if (ret
< 0 || ret
>= end
- pos
)
2354 if (mask
& WPA_BSS_MASK_FREQ
) {
2355 ret
= os_snprintf(pos
, end
- pos
, "freq=%d\n", bss
->freq
);
2356 if (ret
< 0 || ret
>= end
- pos
)
2361 if (mask
& WPA_BSS_MASK_BEACON_INT
) {
2362 ret
= os_snprintf(pos
, end
- pos
, "beacon_int=%d\n",
2364 if (ret
< 0 || ret
>= end
- pos
)
2369 if (mask
& WPA_BSS_MASK_CAPABILITIES
) {
2370 ret
= os_snprintf(pos
, end
- pos
, "capabilities=0x%04x\n",
2372 if (ret
< 0 || ret
>= end
- pos
)
2377 if (mask
& WPA_BSS_MASK_QUAL
) {
2378 ret
= os_snprintf(pos
, end
- pos
, "qual=%d\n", bss
->qual
);
2379 if (ret
< 0 || ret
>= end
- pos
)
2384 if (mask
& WPA_BSS_MASK_NOISE
) {
2385 ret
= os_snprintf(pos
, end
- pos
, "noise=%d\n", bss
->noise
);
2386 if (ret
< 0 || ret
>= end
- pos
)
2391 if (mask
& WPA_BSS_MASK_LEVEL
) {
2392 ret
= os_snprintf(pos
, end
- pos
, "level=%d\n", bss
->level
);
2393 if (ret
< 0 || ret
>= end
- pos
)
2398 if (mask
& WPA_BSS_MASK_TSF
) {
2399 ret
= os_snprintf(pos
, end
- pos
, "tsf=%016llu\n",
2400 (unsigned long long) bss
->tsf
);
2401 if (ret
< 0 || ret
>= end
- pos
)
2406 if (mask
& WPA_BSS_MASK_AGE
) {
2410 ret
= os_snprintf(pos
, end
- pos
, "age=%d\n",
2411 (int) (now
.sec
- bss
->last_update
.sec
));
2412 if (ret
< 0 || ret
>= end
- pos
)
2417 if (mask
& WPA_BSS_MASK_IE
) {
2418 ret
= os_snprintf(pos
, end
- pos
, "ie=");
2419 if (ret
< 0 || ret
>= end
- pos
)
2423 ie
= (const u8
*) (bss
+ 1);
2424 for (i
= 0; i
< bss
->ie_len
; i
++) {
2425 ret
= os_snprintf(pos
, end
- pos
, "%02x", *ie
++);
2426 if (ret
< 0 || ret
>= end
- pos
)
2431 ret
= os_snprintf(pos
, end
- pos
, "\n");
2432 if (ret
< 0 || ret
>= end
- pos
)
2437 if (mask
& WPA_BSS_MASK_FLAGS
) {
2438 ret
= os_snprintf(pos
, end
- pos
, "flags=");
2439 if (ret
< 0 || ret
>= end
- pos
)
2443 ie
= wpa_bss_get_vendor_ie(bss
, WPA_IE_VENDOR_TYPE
);
2445 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA", ie
,
2447 ie2
= wpa_bss_get_ie(bss
, WLAN_EID_RSN
);
2449 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA2", ie2
,
2451 pos
= wpa_supplicant_wps_ie_txt(wpa_s
, pos
, end
, bss
);
2452 if (!ie
&& !ie2
&& bss
->caps
& IEEE80211_CAP_PRIVACY
) {
2453 ret
= os_snprintf(pos
, end
- pos
, "[WEP]");
2454 if (ret
< 0 || ret
>= end
- pos
)
2458 if (bss
->caps
& IEEE80211_CAP_IBSS
) {
2459 ret
= os_snprintf(pos
, end
- pos
, "[IBSS]");
2460 if (ret
< 0 || ret
>= end
- pos
)
2464 if (bss
->caps
& IEEE80211_CAP_ESS
) {
2465 ret
= os_snprintf(pos
, end
- pos
, "[ESS]");
2466 if (ret
< 0 || ret
>= end
- pos
)
2470 if (wpa_bss_get_vendor_ie(bss
, P2P_IE_VENDOR_TYPE
)) {
2471 ret
= os_snprintf(pos
, end
- pos
, "[P2P]");
2472 if (ret
< 0 || ret
>= end
- pos
)
2477 ret
= os_snprintf(pos
, end
- pos
, "\n");
2478 if (ret
< 0 || ret
>= end
- pos
)
2483 if (mask
& WPA_BSS_MASK_SSID
) {
2484 ret
= os_snprintf(pos
, end
- pos
, "ssid=%s\n",
2485 wpa_ssid_txt(bss
->ssid
, bss
->ssid_len
));
2486 if (ret
< 0 || ret
>= end
- pos
)
2492 if (mask
& WPA_BSS_MASK_WPS_SCAN
) {
2493 ie
= (const u8
*) (bss
+ 1);
2494 ret
= wpas_wps_scan_result_text(ie
, bss
->ie_len
, pos
, end
);
2495 if (ret
< 0 || ret
>= end
- pos
)
2499 #endif /* CONFIG_WPS */
2502 if (mask
& WPA_BSS_MASK_P2P_SCAN
) {
2503 ie
= (const u8
*) (bss
+ 1);
2504 ret
= wpas_p2p_scan_result_text(ie
, bss
->ie_len
, pos
, end
);
2505 if (ret
< 0 || ret
>= end
- pos
)
2509 #endif /* CONFIG_P2P */
2511 #ifdef CONFIG_INTERWORKING
2512 if (mask
& WPA_BSS_MASK_INTERNETW
) {
2513 pos
= anqp_add_hex(pos
, end
, "anqp_venue_name",
2514 bss
->anqp_venue_name
);
2515 pos
= anqp_add_hex(pos
, end
, "anqp_network_auth_type",
2516 bss
->anqp_network_auth_type
);
2517 pos
= anqp_add_hex(pos
, end
, "anqp_roaming_consortium",
2518 bss
->anqp_roaming_consortium
);
2519 pos
= anqp_add_hex(pos
, end
, "anqp_ip_addr_type_availability",
2520 bss
->anqp_ip_addr_type_availability
);
2521 pos
= anqp_add_hex(pos
, end
, "anqp_nai_realm",
2522 bss
->anqp_nai_realm
);
2523 pos
= anqp_add_hex(pos
, end
, "anqp_3gpp", bss
->anqp_3gpp
);
2524 pos
= anqp_add_hex(pos
, end
, "anqp_domain_name",
2525 bss
->anqp_domain_name
);
2527 #endif /* CONFIG_INTERWORKING */
2533 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant
*wpa_s
,
2534 const char *cmd
, char *buf
,
2539 struct wpa_bss
*bss
;
2540 struct wpa_bss
*bsslast
= NULL
;
2541 struct dl_list
*next
;
2545 unsigned long mask
= WPA_BSS_MASK_ALL
;
2547 if (os_strncmp(cmd
, "RANGE=", 6) == 0) {
2548 if (os_strncmp(cmd
+ 6, "ALL", 3) == 0) {
2549 bss
= dl_list_first(&wpa_s
->bss_id
, struct wpa_bss
,
2551 bsslast
= dl_list_last(&wpa_s
->bss_id
, struct wpa_bss
,
2553 } else { /* N1-N2 */
2554 unsigned int id1
, id2
;
2556 if ((ctmp
= os_strchr(cmd
+ 6, '-')) == NULL
) {
2557 wpa_printf(MSG_INFO
, "Wrong BSS range "
2562 id1
= atoi(cmd
+ 6);
2563 bss
= wpa_bss_get_id(wpa_s
, id1
);
2564 id2
= atoi(ctmp
+ 1);
2566 bsslast
= dl_list_last(&wpa_s
->bss_id
,
2570 bsslast
= wpa_bss_get_id(wpa_s
, id2
);
2571 if (bsslast
== NULL
&& bss
&& id2
> id1
) {
2572 struct wpa_bss
*tmp
= bss
;
2574 next
= tmp
->list_id
.next
;
2575 if (next
== &wpa_s
->bss_id
)
2577 tmp
= dl_list_entry(
2578 next
, struct wpa_bss
,
2587 } else if (os_strcmp(cmd
, "FIRST") == 0)
2588 bss
= dl_list_first(&wpa_s
->bss_id
, struct wpa_bss
, list_id
);
2589 else if (os_strncmp(cmd
, "ID-", 3) == 0) {
2591 bss
= wpa_bss_get_id(wpa_s
, i
);
2592 } else if (os_strncmp(cmd
, "NEXT-", 5) == 0) {
2594 bss
= wpa_bss_get_id(wpa_s
, i
);
2596 next
= bss
->list_id
.next
;
2597 if (next
== &wpa_s
->bss_id
)
2600 bss
= dl_list_entry(next
, struct wpa_bss
,
2604 } else if (os_strncmp(cmd
, "p2p_dev_addr=", 13) == 0) {
2605 if (hwaddr_aton(cmd
+ 13, bssid
) == 0)
2606 bss
= wpa_bss_get_p2p_dev_addr(wpa_s
, bssid
);
2609 #endif /* CONFIG_P2P */
2610 } else if (hwaddr_aton(cmd
, bssid
) == 0)
2611 bss
= wpa_bss_get_bssid(wpa_s
, bssid
);
2613 struct wpa_bss
*tmp
;
2616 dl_list_for_each(tmp
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
)
2625 if ((ctmp
= os_strstr(cmd
, "MASK=")) != NULL
) {
2626 mask
= strtoul(ctmp
+ 5, NULL
, 0x10);
2628 mask
= WPA_BSS_MASK_ALL
;
2634 if (bsslast
== NULL
)
2637 len
= print_bss_info(wpa_s
, bss
, mask
, buf
, buflen
);
2643 next
= bss
->list_id
.next
;
2644 if (next
== &wpa_s
->bss_id
)
2646 bss
= dl_list_entry(next
, struct wpa_bss
, list_id
);
2647 } while (bss
&& len
);
2653 static int wpa_supplicant_ctrl_iface_ap_scan(
2654 struct wpa_supplicant
*wpa_s
, char *cmd
)
2656 int ap_scan
= atoi(cmd
);
2657 return wpa_supplicant_set_ap_scan(wpa_s
, ap_scan
);
2661 static int wpa_supplicant_ctrl_iface_scan_interval(
2662 struct wpa_supplicant
*wpa_s
, char *cmd
)
2664 int scan_int
= atoi(cmd
);
2665 return wpa_supplicant_set_scan_interval(wpa_s
, scan_int
);
2669 static int wpa_supplicant_ctrl_iface_bss_expire_age(
2670 struct wpa_supplicant
*wpa_s
, char *cmd
)
2672 int expire_age
= atoi(cmd
);
2673 return wpa_supplicant_set_bss_expiration_age(wpa_s
, expire_age
);
2677 static int wpa_supplicant_ctrl_iface_bss_expire_count(
2678 struct wpa_supplicant
*wpa_s
, char *cmd
)
2680 int expire_count
= atoi(cmd
);
2681 return wpa_supplicant_set_bss_expiration_count(wpa_s
, expire_count
);
2685 static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant
*wpa_s
)
2687 wpa_printf(MSG_DEBUG
, "Dropping SA without deauthentication");
2688 /* MLME-DELETEKEYS.request */
2689 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, NULL
, 0, 0, NULL
, 0, NULL
, 0);
2690 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, NULL
, 1, 0, NULL
, 0, NULL
, 0);
2691 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, NULL
, 2, 0, NULL
, 0, NULL
, 0);
2692 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, NULL
, 3, 0, NULL
, 0, NULL
, 0);
2693 #ifdef CONFIG_IEEE80211W
2694 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, NULL
, 4, 0, NULL
, 0, NULL
, 0);
2695 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, NULL
, 5, 0, NULL
, 0, NULL
, 0);
2696 #endif /* CONFIG_IEEE80211W */
2698 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, wpa_s
->bssid
, 0, 0, NULL
, 0, NULL
,
2700 /* MLME-SETPROTECTION.request(None) */
2701 wpa_drv_mlme_setprotection(wpa_s
, wpa_s
->bssid
,
2702 MLME_SETPROTECTION_PROTECT_TYPE_NONE
,
2703 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE
);
2704 wpa_sm_drop_sa(wpa_s
->wpa
);
2708 static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant
*wpa_s
,
2711 #ifdef CONFIG_NO_SCAN_PROCESSING
2713 #else /* CONFIG_NO_SCAN_PROCESSING */
2715 struct wpa_bss
*bss
;
2716 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
2718 if (hwaddr_aton(addr
, bssid
)) {
2719 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM: invalid "
2720 "address '%s'", addr
);
2724 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM " MACSTR
, MAC2STR(bssid
));
2726 bss
= wpa_bss_get_bssid(wpa_s
, bssid
);
2728 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM: Target AP not found "
2734 * TODO: Find best network configuration block from configuration to
2735 * allow roaming to other networks
2739 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM: No network "
2740 "configuration known for the target AP");
2744 wpa_s
->reassociate
= 1;
2745 wpa_supplicant_connect(wpa_s
, bss
, ssid
);
2748 #endif /* CONFIG_NO_SCAN_PROCESSING */
2753 static int p2p_ctrl_find(struct wpa_supplicant
*wpa_s
, char *cmd
)
2755 unsigned int timeout
= atoi(cmd
);
2756 enum p2p_discovery_type type
= P2P_FIND_START_WITH_FULL
;
2757 u8 dev_id
[ETH_ALEN
], *_dev_id
= NULL
;
2760 if (os_strstr(cmd
, "type=social"))
2761 type
= P2P_FIND_ONLY_SOCIAL
;
2762 else if (os_strstr(cmd
, "type=progressive"))
2763 type
= P2P_FIND_PROGRESSIVE
;
2765 pos
= os_strstr(cmd
, "dev_id=");
2768 if (hwaddr_aton(pos
, dev_id
))
2773 return wpas_p2p_find(wpa_s
, timeout
, type
, 0, NULL
, _dev_id
);
2777 static int p2p_ctrl_connect(struct wpa_supplicant
*wpa_s
, char *cmd
,
2778 char *buf
, size_t buflen
)
2783 enum p2p_wps_method wps_method
;
2786 int persistent_group
, persistent_id
= -1;
2793 /* <addr> <"pbc" | "pin" | PIN> [label|display|keypad]
2794 * [persistent|persistent=<network id>]
2795 * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] */
2797 if (hwaddr_aton(cmd
, addr
))
2805 persistent_group
= os_strstr(pos
, " persistent") != NULL
;
2806 pos2
= os_strstr(pos
, " persistent=");
2808 struct wpa_ssid
*ssid
;
2809 persistent_id
= atoi(pos2
+ 12);
2810 ssid
= wpa_config_get_network(wpa_s
->conf
, persistent_id
);
2811 if (ssid
== NULL
|| ssid
->disabled
!= 2 ||
2812 ssid
->mode
!= WPAS_MODE_P2P_GO
) {
2813 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
2814 "SSID id=%d for persistent P2P group (GO)",
2819 join
= os_strstr(pos
, " join") != NULL
;
2820 auth
= os_strstr(pos
, " auth") != NULL
;
2821 automatic
= os_strstr(pos
, " auto") != NULL
;
2823 pos2
= os_strstr(pos
, " go_intent=");
2826 go_intent
= atoi(pos2
);
2827 if (go_intent
< 0 || go_intent
> 15)
2831 pos2
= os_strstr(pos
, " freq=");
2839 if (os_strncmp(pos
, "pin", 3) == 0) {
2840 /* Request random PIN (to be displayed) and enable the PIN */
2841 wps_method
= WPS_PIN_DISPLAY
;
2842 } else if (os_strncmp(pos
, "pbc", 3) == 0) {
2843 wps_method
= WPS_PBC
;
2846 pos
= os_strchr(pin
, ' ');
2847 wps_method
= WPS_PIN_KEYPAD
;
2850 if (os_strncmp(pos
, "display", 7) == 0)
2851 wps_method
= WPS_PIN_DISPLAY
;
2855 new_pin
= wpas_p2p_connect(wpa_s
, addr
, pin
, wps_method
,
2856 persistent_group
, automatic
, join
,
2857 auth
, go_intent
, freq
, persistent_id
);
2858 if (new_pin
== -2) {
2859 os_memcpy(buf
, "FAIL-CHANNEL-UNAVAILABLE\n", 25);
2862 if (new_pin
== -3) {
2863 os_memcpy(buf
, "FAIL-CHANNEL-UNSUPPORTED\n", 25);
2868 if (wps_method
== WPS_PIN_DISPLAY
&& pin
== NULL
) {
2869 ret
= os_snprintf(buf
, buflen
, "%08d", new_pin
);
2870 if (ret
< 0 || (size_t) ret
>= buflen
)
2875 os_memcpy(buf
, "OK\n", 3);
2880 static int p2p_ctrl_listen(struct wpa_supplicant
*wpa_s
, char *cmd
)
2882 unsigned int timeout
= atoi(cmd
);
2883 return wpas_p2p_listen(wpa_s
, timeout
);
2887 static int p2p_ctrl_prov_disc(struct wpa_supplicant
*wpa_s
, char *cmd
)
2891 enum wpas_p2p_prov_disc_use use
= WPAS_P2P_PD_FOR_GO_NEG
;
2893 /* <addr> <config method> [join|auto] */
2895 if (hwaddr_aton(cmd
, addr
))
2903 if (os_strstr(pos
, " join") != NULL
)
2904 use
= WPAS_P2P_PD_FOR_JOIN
;
2905 else if (os_strstr(pos
, " auto") != NULL
)
2906 use
= WPAS_P2P_PD_AUTO
;
2908 return wpas_p2p_prov_disc(wpa_s
, addr
, pos
, use
);
2912 static int p2p_get_passphrase(struct wpa_supplicant
*wpa_s
, char *buf
,
2915 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
2917 if (ssid
== NULL
|| ssid
->mode
!= WPAS_MODE_P2P_GO
||
2918 ssid
->passphrase
== NULL
)
2921 os_strlcpy(buf
, ssid
->passphrase
, buflen
);
2922 return os_strlen(buf
);
2926 static int p2p_ctrl_serv_disc_req(struct wpa_supplicant
*wpa_s
, char *cmd
,
2927 char *buf
, size_t buflen
)
2931 u8 dst_buf
[ETH_ALEN
], *dst
;
2932 struct wpabuf
*tlvs
;
2936 if (hwaddr_aton(cmd
, dst_buf
))
2939 if (dst
[0] == 0 && dst
[1] == 0 && dst
[2] == 0 &&
2940 dst
[3] == 0 && dst
[4] == 0 && dst
[5] == 0)
2947 if (os_strncmp(pos
, "upnp ", 5) == 0) {
2950 if (hexstr2bin(pos
, &version
, 1) < 0)
2956 ref
= wpas_p2p_sd_request_upnp(wpa_s
, dst
, version
, pos
);
2958 len
= os_strlen(pos
);
2962 tlvs
= wpabuf_alloc(len
);
2965 if (hexstr2bin(pos
, wpabuf_put(tlvs
, len
), len
) < 0) {
2970 ref
= wpas_p2p_sd_request(wpa_s
, dst
, tlvs
);
2975 res
= os_snprintf(buf
, buflen
, "%llx", (long long unsigned) ref
);
2976 if (res
< 0 || (unsigned) res
>= buflen
)
2982 static int p2p_ctrl_serv_disc_cancel_req(struct wpa_supplicant
*wpa_s
,
2985 long long unsigned val
;
2987 if (sscanf(cmd
, "%llx", &val
) != 1)
2990 return wpas_p2p_sd_cancel_request(wpa_s
, req
);
2994 static int p2p_ctrl_serv_disc_resp(struct wpa_supplicant
*wpa_s
, char *cmd
)
2999 struct wpabuf
*resp_tlvs
;
3003 pos
= os_strchr(cmd
, ' ');
3011 if (hwaddr_aton(pos
, dst
))
3018 pos2
= os_strchr(pos
, ' ');
3022 dialog_token
= atoi(pos
);
3024 len
= os_strlen(pos2
);
3028 resp_tlvs
= wpabuf_alloc(len
);
3029 if (resp_tlvs
== NULL
)
3031 if (hexstr2bin(pos2
, wpabuf_put(resp_tlvs
, len
), len
) < 0) {
3032 wpabuf_free(resp_tlvs
);
3036 wpas_p2p_sd_response(wpa_s
, freq
, dst
, dialog_token
, resp_tlvs
);
3037 wpabuf_free(resp_tlvs
);
3042 static int p2p_ctrl_serv_disc_external(struct wpa_supplicant
*wpa_s
,
3045 if (os_strcmp(cmd
, "0") && os_strcmp(cmd
, "1"))
3047 wpa_s
->p2p_sd_over_ctrl_iface
= atoi(cmd
);
3052 static int p2p_ctrl_service_add_bonjour(struct wpa_supplicant
*wpa_s
,
3057 struct wpabuf
*query
, *resp
;
3059 pos
= os_strchr(cmd
, ' ');
3064 len
= os_strlen(cmd
);
3068 query
= wpabuf_alloc(len
);
3071 if (hexstr2bin(cmd
, wpabuf_put(query
, len
), len
) < 0) {
3076 len
= os_strlen(pos
);
3082 resp
= wpabuf_alloc(len
);
3087 if (hexstr2bin(pos
, wpabuf_put(resp
, len
), len
) < 0) {
3093 if (wpas_p2p_service_add_bonjour(wpa_s
, query
, resp
) < 0) {
3102 static int p2p_ctrl_service_add_upnp(struct wpa_supplicant
*wpa_s
, char *cmd
)
3107 pos
= os_strchr(cmd
, ' ');
3112 if (hexstr2bin(cmd
, &version
, 1) < 0)
3115 return wpas_p2p_service_add_upnp(wpa_s
, version
, pos
);
3119 static int p2p_ctrl_service_add(struct wpa_supplicant
*wpa_s
, char *cmd
)
3123 pos
= os_strchr(cmd
, ' ');
3128 if (os_strcmp(cmd
, "bonjour") == 0)
3129 return p2p_ctrl_service_add_bonjour(wpa_s
, pos
);
3130 if (os_strcmp(cmd
, "upnp") == 0)
3131 return p2p_ctrl_service_add_upnp(wpa_s
, pos
);
3132 wpa_printf(MSG_DEBUG
, "Unknown service '%s'", cmd
);
3137 static int p2p_ctrl_service_del_bonjour(struct wpa_supplicant
*wpa_s
,
3141 struct wpabuf
*query
;
3144 len
= os_strlen(cmd
);
3148 query
= wpabuf_alloc(len
);
3151 if (hexstr2bin(cmd
, wpabuf_put(query
, len
), len
) < 0) {
3156 ret
= wpas_p2p_service_del_bonjour(wpa_s
, query
);
3162 static int p2p_ctrl_service_del_upnp(struct wpa_supplicant
*wpa_s
, char *cmd
)
3167 pos
= os_strchr(cmd
, ' ');
3172 if (hexstr2bin(cmd
, &version
, 1) < 0)
3175 return wpas_p2p_service_del_upnp(wpa_s
, version
, pos
);
3179 static int p2p_ctrl_service_del(struct wpa_supplicant
*wpa_s
, char *cmd
)
3183 pos
= os_strchr(cmd
, ' ');
3188 if (os_strcmp(cmd
, "bonjour") == 0)
3189 return p2p_ctrl_service_del_bonjour(wpa_s
, pos
);
3190 if (os_strcmp(cmd
, "upnp") == 0)
3191 return p2p_ctrl_service_del_upnp(wpa_s
, pos
);
3192 wpa_printf(MSG_DEBUG
, "Unknown service '%s'", cmd
);
3197 static int p2p_ctrl_reject(struct wpa_supplicant
*wpa_s
, char *cmd
)
3203 if (hwaddr_aton(cmd
, addr
))
3206 return wpas_p2p_reject(wpa_s
, addr
);
3210 static int p2p_ctrl_invite_persistent(struct wpa_supplicant
*wpa_s
, char *cmd
)
3214 struct wpa_ssid
*ssid
;
3218 pos
= os_strstr(cmd
, " peer=");
3221 if (hwaddr_aton(pos
, peer
))
3224 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
3225 if (ssid
== NULL
|| ssid
->disabled
!= 2) {
3226 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
3227 "for persistent P2P group",
3232 return wpas_p2p_invite(wpa_s
, pos
? peer
: NULL
, ssid
, NULL
);
3236 static int p2p_ctrl_invite_group(struct wpa_supplicant
*wpa_s
, char *cmd
)
3239 u8 peer
[ETH_ALEN
], go_dev_addr
[ETH_ALEN
], *go_dev
= NULL
;
3241 pos
= os_strstr(cmd
, " peer=");
3247 if (hwaddr_aton(pos
, peer
)) {
3248 wpa_printf(MSG_DEBUG
, "P2P: Invalid MAC address '%s'", pos
);
3252 pos
= os_strstr(pos
, " go_dev_addr=");
3255 if (hwaddr_aton(pos
, go_dev_addr
)) {
3256 wpa_printf(MSG_DEBUG
, "P2P: Invalid MAC address '%s'",
3260 go_dev
= go_dev_addr
;
3263 return wpas_p2p_invite_group(wpa_s
, cmd
, peer
, go_dev
);
3267 static int p2p_ctrl_invite(struct wpa_supplicant
*wpa_s
, char *cmd
)
3269 if (os_strncmp(cmd
, "persistent=", 11) == 0)
3270 return p2p_ctrl_invite_persistent(wpa_s
, cmd
+ 11);
3271 if (os_strncmp(cmd
, "group=", 6) == 0)
3272 return p2p_ctrl_invite_group(wpa_s
, cmd
+ 6);
3278 static int p2p_ctrl_group_add_persistent(struct wpa_supplicant
*wpa_s
,
3279 char *cmd
, int freq
)
3282 struct wpa_ssid
*ssid
;
3285 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
3286 if (ssid
== NULL
|| ssid
->disabled
!= 2) {
3287 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
3288 "for persistent P2P group",
3293 return wpas_p2p_group_add_persistent(wpa_s
, ssid
, 0, freq
);
3297 static int p2p_ctrl_group_add(struct wpa_supplicant
*wpa_s
, char *cmd
)
3302 pos
= os_strstr(cmd
, "freq=");
3304 freq
= atoi(pos
+ 5);
3306 if (os_strncmp(cmd
, "persistent=", 11) == 0)
3307 return p2p_ctrl_group_add_persistent(wpa_s
, cmd
+ 11, freq
);
3308 if (os_strcmp(cmd
, "persistent") == 0 ||
3309 os_strncmp(cmd
, "persistent ", 11) == 0)
3310 return wpas_p2p_group_add(wpa_s
, 1, freq
);
3311 if (os_strncmp(cmd
, "freq=", 5) == 0)
3312 return wpas_p2p_group_add(wpa_s
, 0, freq
);
3314 wpa_printf(MSG_DEBUG
, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'",
3320 static int p2p_ctrl_peer(struct wpa_supplicant
*wpa_s
, char *cmd
,
3321 char *buf
, size_t buflen
)
3323 u8 addr
[ETH_ALEN
], *addr_ptr
;
3325 const struct p2p_peer_info
*info
;
3327 char devtype
[WPS_DEV_TYPE_BUFSIZE
];
3328 struct wpa_ssid
*ssid
;
3330 if (!wpa_s
->global
->p2p
)
3333 if (os_strcmp(cmd
, "FIRST") == 0) {
3336 } else if (os_strncmp(cmd
, "NEXT-", 5) == 0) {
3337 if (hwaddr_aton(cmd
+ 5, addr
) < 0)
3342 if (hwaddr_aton(cmd
, addr
) < 0)
3348 info
= p2p_get_peer_info(wpa_s
->global
->p2p
, addr_ptr
, next
);
3355 res
= os_snprintf(pos
, end
- pos
, MACSTR
"\n"
3361 "serial_number=%s\n"
3362 "config_methods=0x%x\n"
3364 "group_capab=0x%x\n"
3366 MAC2STR(info
->p2p_device_addr
),
3367 wps_dev_type_bin2str(info
->pri_dev_type
,
3368 devtype
, sizeof(devtype
)),
3373 info
->serial_number
,
3374 info
->config_methods
,
3378 if (res
< 0 || res
>= end
- pos
)
3382 ssid
= wpas_p2p_get_persistent(wpa_s
, info
->p2p_device_addr
, NULL
, 0);
3384 res
= os_snprintf(pos
, end
- pos
, "persistent=%d\n", ssid
->id
);
3385 if (res
< 0 || res
>= end
- pos
)
3390 res
= p2p_get_peer_info_txt(info
, pos
, end
- pos
);
3399 static int p2p_ctrl_disallow_freq(struct wpa_supplicant
*wpa_s
,
3402 struct wpa_freq_range
*freq
= NULL
, *n
;
3403 unsigned int count
= 0, i
;
3404 const char *pos
, *pos2
, *pos3
;
3406 if (wpa_s
->global
->p2p
== NULL
)
3410 * param includes comma separated frequency range.
3411 * For example: 2412-2432,2462,5000-6000
3414 while (pos
&& pos
[0]) {
3415 n
= os_realloc(freq
,
3416 (count
+ 1) * sizeof(struct wpa_freq_range
));
3422 freq
[count
].min
= atoi(pos
);
3423 pos2
= os_strchr(pos
, '-');
3424 pos3
= os_strchr(pos
, ',');
3425 if (pos2
&& (!pos3
|| pos2
< pos3
)) {
3427 freq
[count
].max
= atoi(pos2
);
3429 freq
[count
].max
= freq
[count
].min
;
3436 for (i
= 0; i
< count
; i
++) {
3437 wpa_printf(MSG_DEBUG
, "P2P: Disallowed frequency range %u-%u",
3438 freq
[i
].min
, freq
[i
].max
);
3441 os_free(wpa_s
->global
->p2p_disallow_freq
);
3442 wpa_s
->global
->p2p_disallow_freq
= freq
;
3443 wpa_s
->global
->num_p2p_disallow_freq
= count
;
3444 wpas_p2p_update_channel_list(wpa_s
);
3449 static int p2p_ctrl_set(struct wpa_supplicant
*wpa_s
, char *cmd
)
3453 if (wpa_s
->global
->p2p
== NULL
)
3456 param
= os_strchr(cmd
, ' ');
3461 if (os_strcmp(cmd
, "discoverability") == 0) {
3462 p2p_set_client_discoverability(wpa_s
->global
->p2p
,
3467 if (os_strcmp(cmd
, "managed") == 0) {
3468 p2p_set_managed_oper(wpa_s
->global
->p2p
, atoi(param
));
3472 if (os_strcmp(cmd
, "listen_channel") == 0) {
3473 return p2p_set_listen_channel(wpa_s
->global
->p2p
, 81,
3477 if (os_strcmp(cmd
, "ssid_postfix") == 0) {
3478 return p2p_set_ssid_postfix(wpa_s
->global
->p2p
, (u8
*) param
,
3482 if (os_strcmp(cmd
, "noa") == 0) {
3484 int count
, start
, duration
;
3485 /* GO NoA parameters: count,start_offset(ms),duration(ms) */
3486 count
= atoi(param
);
3487 pos
= os_strchr(param
, ',');
3492 pos
= os_strchr(pos
, ',');
3496 duration
= atoi(pos
);
3497 if (count
< 0 || count
> 255 || start
< 0 || duration
< 0)
3499 if (count
== 0 && duration
> 0)
3501 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: P2P_SET GO NoA: count=%d "
3502 "start=%d duration=%d", count
, start
, duration
);
3503 return wpas_p2p_set_noa(wpa_s
, count
, start
, duration
);
3506 if (os_strcmp(cmd
, "ps") == 0)
3507 return wpa_drv_set_p2p_powersave(wpa_s
, atoi(param
), -1, -1);
3509 if (os_strcmp(cmd
, "oppps") == 0)
3510 return wpa_drv_set_p2p_powersave(wpa_s
, -1, atoi(param
), -1);
3512 if (os_strcmp(cmd
, "ctwindow") == 0)
3513 return wpa_drv_set_p2p_powersave(wpa_s
, -1, -1, atoi(param
));
3515 if (os_strcmp(cmd
, "disabled") == 0) {
3516 wpa_s
->global
->p2p_disabled
= atoi(param
);
3517 wpa_printf(MSG_DEBUG
, "P2P functionality %s",
3518 wpa_s
->global
->p2p_disabled
?
3519 "disabled" : "enabled");
3520 if (wpa_s
->global
->p2p_disabled
) {
3521 wpas_p2p_stop_find(wpa_s
);
3522 os_memset(wpa_s
->p2p_auth_invite
, 0, ETH_ALEN
);
3523 p2p_flush(wpa_s
->global
->p2p
);
3528 if (os_strcmp(cmd
, "force_long_sd") == 0) {
3529 wpa_s
->force_long_sd
= atoi(param
);
3533 if (os_strcmp(cmd
, "peer_filter") == 0) {
3535 if (hwaddr_aton(param
, addr
))
3537 p2p_set_peer_filter(wpa_s
->global
->p2p
, addr
);
3541 if (os_strcmp(cmd
, "cross_connect") == 0)
3542 return wpas_p2p_set_cross_connect(wpa_s
, atoi(param
));
3544 if (os_strcmp(cmd
, "go_apsd") == 0) {
3545 if (os_strcmp(param
, "disable") == 0)
3546 wpa_s
->set_ap_uapsd
= 0;
3548 wpa_s
->set_ap_uapsd
= 1;
3549 wpa_s
->ap_uapsd
= atoi(param
);
3554 if (os_strcmp(cmd
, "client_apsd") == 0) {
3555 if (os_strcmp(param
, "disable") == 0)
3556 wpa_s
->set_sta_uapsd
= 0;
3560 /* format: BE,BK,VI,VO;max SP Length */
3562 pos
= os_strchr(param
, ',');
3567 pos
= os_strchr(pos
, ',');
3572 pos
= os_strchr(pos
, ',');
3577 /* ignore max SP Length for now */
3579 wpa_s
->set_sta_uapsd
= 1;
3580 wpa_s
->sta_uapsd
= 0;
3582 wpa_s
->sta_uapsd
|= BIT(0);
3584 wpa_s
->sta_uapsd
|= BIT(1);
3586 wpa_s
->sta_uapsd
|= BIT(2);
3588 wpa_s
->sta_uapsd
|= BIT(3);
3593 if (os_strcmp(cmd
, "disallow_freq") == 0)
3594 return p2p_ctrl_disallow_freq(wpa_s
, param
);
3596 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
3603 static int p2p_ctrl_presence_req(struct wpa_supplicant
*wpa_s
, char *cmd
)
3606 unsigned int dur1
= 0, int1
= 0, dur2
= 0, int2
= 0;
3609 pos
= os_strchr(cmd
, ' ');
3615 pos2
= os_strchr(pos
, ' ');
3623 pos
= os_strchr(pos2
, ' ');
3631 return wpas_p2p_presence_req(wpa_s
, dur1
, int1
, dur2
, int2
);
3635 static int p2p_ctrl_ext_listen(struct wpa_supplicant
*wpa_s
, char *cmd
)
3638 unsigned int period
= 0, interval
= 0;
3641 pos
= os_strchr(cmd
, ' ');
3646 interval
= atoi(pos
);
3649 return wpas_p2p_ext_listen(wpa_s
, period
, interval
);
3652 #endif /* CONFIG_P2P */
3655 #ifdef CONFIG_INTERWORKING
3656 static int ctrl_interworking_connect(struct wpa_supplicant
*wpa_s
, char *dst
)
3659 struct wpa_bss
*bss
;
3661 if (hwaddr_aton(dst
, bssid
)) {
3662 wpa_printf(MSG_DEBUG
, "Invalid BSSID '%s'", dst
);
3666 bss
= wpa_bss_get_bssid(wpa_s
, bssid
);
3668 wpa_printf(MSG_DEBUG
, "Could not find BSS " MACSTR
,
3673 return interworking_connect(wpa_s
, bss
);
3677 static int get_anqp(struct wpa_supplicant
*wpa_s
, char *dst
)
3679 u8 dst_addr
[ETH_ALEN
];
3682 #define MAX_ANQP_INFO_ID 100
3683 u16 id
[MAX_ANQP_INFO_ID
];
3686 used
= hwaddr_aton2(dst
, dst_addr
);
3690 while (num_id
< MAX_ANQP_INFO_ID
) {
3691 id
[num_id
] = atoi(pos
);
3694 pos
= os_strchr(pos
+ 1, ',');
3703 return anqp_send_req(wpa_s
, dst_addr
, id
, num_id
);
3705 #endif /* CONFIG_INTERWORKING */
3708 static int wpa_supplicant_ctrl_iface_sta_autoconnect(
3709 struct wpa_supplicant
*wpa_s
, char *cmd
)
3711 wpa_s
->auto_reconnect_disabled
= atoi(cmd
) == 0 ? 1 : 0;
3716 static int wpa_supplicant_signal_poll(struct wpa_supplicant
*wpa_s
, char *buf
,
3719 struct wpa_signal_info si
;
3722 ret
= wpa_drv_signal_poll(wpa_s
, &si
);
3726 ret
= os_snprintf(buf
, buflen
, "RSSI=%d\nLINKSPEED=%d\n"
3727 "NOISE=%d\nFREQUENCY=%u\n",
3728 si
.current_signal
, si
.current_txrate
/ 1000,
3729 si
.current_noise
, si
.frequency
);
3730 if (ret
< 0 || (unsigned int) ret
> buflen
)
3736 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant
*wpa_s
,
3737 char *buf
, size_t *resp_len
)
3740 const int reply_size
= 4096;
3744 if (os_strncmp(buf
, WPA_CTRL_RSP
, os_strlen(WPA_CTRL_RSP
)) == 0 ||
3745 os_strncmp(buf
, "SET_NETWORK ", 12) == 0) {
3746 wpa_hexdump_ascii_key(MSG_DEBUG
, "RX ctrl_iface",
3747 (const u8
*) buf
, os_strlen(buf
));
3749 int level
= MSG_DEBUG
;
3750 if (os_strcmp(buf
, "PING") == 0)
3751 level
= MSG_EXCESSIVE
;
3752 wpa_hexdump_ascii(level
, "RX ctrl_iface",
3753 (const u8
*) buf
, os_strlen(buf
));
3756 reply
= os_malloc(reply_size
);
3757 if (reply
== NULL
) {
3762 os_memcpy(reply
, "OK\n", 3);
3765 if (os_strcmp(buf
, "PING") == 0) {
3766 os_memcpy(reply
, "PONG\n", 5);
3768 } else if (os_strncmp(buf
, "RELOG", 5) == 0) {
3769 if (wpa_debug_reopen_file() < 0)
3771 } else if (os_strncmp(buf
, "NOTE ", 5) == 0) {
3772 wpa_printf(MSG_INFO
, "NOTE: %s", buf
+ 5);
3773 } else if (os_strcmp(buf
, "MIB") == 0) {
3774 reply_len
= wpa_sm_get_mib(wpa_s
->wpa
, reply
, reply_size
);
3775 if (reply_len
>= 0) {
3777 res
= eapol_sm_get_mib(wpa_s
->eapol
, reply
+ reply_len
,
3778 reply_size
- reply_len
);
3784 } else if (os_strncmp(buf
, "STATUS", 6) == 0) {
3785 reply_len
= wpa_supplicant_ctrl_iface_status(
3786 wpa_s
, buf
+ 6, reply
, reply_size
);
3787 } else if (os_strcmp(buf
, "PMKSA") == 0) {
3788 reply_len
= wpa_sm_pmksa_cache_list(wpa_s
->wpa
, reply
,
3790 } else if (os_strncmp(buf
, "SET ", 4) == 0) {
3791 if (wpa_supplicant_ctrl_iface_set(wpa_s
, buf
+ 4))
3793 } else if (os_strncmp(buf
, "GET ", 4) == 0) {
3794 reply_len
= wpa_supplicant_ctrl_iface_get(wpa_s
, buf
+ 4,
3796 } else if (os_strcmp(buf
, "LOGON") == 0) {
3797 eapol_sm_notify_logoff(wpa_s
->eapol
, FALSE
);
3798 } else if (os_strcmp(buf
, "LOGOFF") == 0) {
3799 eapol_sm_notify_logoff(wpa_s
->eapol
, TRUE
);
3800 } else if (os_strcmp(buf
, "REASSOCIATE") == 0) {
3801 wpa_s
->normal_scans
= 0;
3802 if (wpa_s
->wpa_state
== WPA_INTERFACE_DISABLED
)
3805 wpa_s
->disconnected
= 0;
3806 wpa_s
->reassociate
= 1;
3807 wpa_supplicant_req_scan(wpa_s
, 0, 0);
3809 } else if (os_strcmp(buf
, "RECONNECT") == 0) {
3810 wpa_s
->normal_scans
= 0;
3811 if (wpa_s
->wpa_state
== WPA_INTERFACE_DISABLED
)
3813 else if (wpa_s
->disconnected
) {
3814 wpa_s
->disconnected
= 0;
3815 wpa_s
->reassociate
= 1;
3816 wpa_supplicant_req_scan(wpa_s
, 0, 0);
3818 #ifdef IEEE8021X_EAPOL
3819 } else if (os_strncmp(buf
, "PREAUTH ", 8) == 0) {
3820 if (wpa_supplicant_ctrl_iface_preauth(wpa_s
, buf
+ 8))
3822 #endif /* IEEE8021X_EAPOL */
3823 #ifdef CONFIG_PEERKEY
3824 } else if (os_strncmp(buf
, "STKSTART ", 9) == 0) {
3825 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s
, buf
+ 9))
3827 #endif /* CONFIG_PEERKEY */
3828 #ifdef CONFIG_IEEE80211R
3829 } else if (os_strncmp(buf
, "FT_DS ", 6) == 0) {
3830 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s
, buf
+ 6))
3832 #endif /* CONFIG_IEEE80211R */
3834 } else if (os_strcmp(buf
, "WPS_PBC") == 0) {
3835 int res
= wpa_supplicant_ctrl_iface_wps_pbc(wpa_s
, NULL
);
3837 os_memcpy(reply
, "FAIL-PBC-OVERLAP\n", 17);
3841 } else if (os_strncmp(buf
, "WPS_PBC ", 8) == 0) {
3842 int res
= wpa_supplicant_ctrl_iface_wps_pbc(wpa_s
, buf
+ 8);
3844 os_memcpy(reply
, "FAIL-PBC-OVERLAP\n", 17);
3848 } else if (os_strncmp(buf
, "WPS_PIN ", 8) == 0) {
3849 reply_len
= wpa_supplicant_ctrl_iface_wps_pin(wpa_s
, buf
+ 8,
3852 } else if (os_strncmp(buf
, "WPS_CHECK_PIN ", 14) == 0) {
3853 reply_len
= wpa_supplicant_ctrl_iface_wps_check_pin(
3854 wpa_s
, buf
+ 14, reply
, reply_size
);
3855 } else if (os_strcmp(buf
, "WPS_CANCEL") == 0) {
3856 if (wpas_wps_cancel(wpa_s
))
3858 #ifdef CONFIG_WPS_OOB
3859 } else if (os_strncmp(buf
, "WPS_OOB ", 8) == 0) {
3860 if (wpa_supplicant_ctrl_iface_wps_oob(wpa_s
, buf
+ 8))
3862 #endif /* CONFIG_WPS_OOB */
3863 } else if (os_strncmp(buf
, "WPS_REG ", 8) == 0) {
3864 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s
, buf
+ 8))
3867 } else if (os_strncmp(buf
, "WPS_AP_PIN ", 11) == 0) {
3868 reply_len
= wpa_supplicant_ctrl_iface_wps_ap_pin(
3869 wpa_s
, buf
+ 11, reply
, reply_size
);
3870 #endif /* CONFIG_AP */
3871 #ifdef CONFIG_WPS_ER
3872 } else if (os_strcmp(buf
, "WPS_ER_START") == 0) {
3873 if (wpas_wps_er_start(wpa_s
, NULL
))
3875 } else if (os_strncmp(buf
, "WPS_ER_START ", 13) == 0) {
3876 if (wpas_wps_er_start(wpa_s
, buf
+ 13))
3878 } else if (os_strcmp(buf
, "WPS_ER_STOP") == 0) {
3879 if (wpas_wps_er_stop(wpa_s
))
3881 } else if (os_strncmp(buf
, "WPS_ER_PIN ", 11) == 0) {
3882 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s
, buf
+ 11))
3884 } else if (os_strncmp(buf
, "WPS_ER_PBC ", 11) == 0) {
3885 int ret
= wpas_wps_er_pbc(wpa_s
, buf
+ 11);
3887 os_memcpy(reply
, "FAIL-PBC-OVERLAP\n", 17);
3889 } else if (ret
== -3) {
3890 os_memcpy(reply
, "FAIL-UNKNOWN-UUID\n", 18);
3892 } else if (ret
== -4) {
3893 os_memcpy(reply
, "FAIL-NO-AP-SETTINGS\n", 20);
3897 } else if (os_strncmp(buf
, "WPS_ER_LEARN ", 13) == 0) {
3898 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s
, buf
+ 13))
3900 } else if (os_strncmp(buf
, "WPS_ER_SET_CONFIG ", 18) == 0) {
3901 if (wpa_supplicant_ctrl_iface_wps_er_set_config(wpa_s
,
3904 } else if (os_strncmp(buf
, "WPS_ER_CONFIG ", 14) == 0) {
3905 if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s
, buf
+ 14))
3907 #endif /* CONFIG_WPS_ER */
3908 #endif /* CONFIG_WPS */
3909 #ifdef CONFIG_IBSS_RSN
3910 } else if (os_strncmp(buf
, "IBSS_RSN ", 9) == 0) {
3911 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s
, buf
+ 9))
3913 #endif /* CONFIG_IBSS_RSN */
3915 } else if (os_strncmp(buf
, "P2P_FIND ", 9) == 0) {
3916 if (p2p_ctrl_find(wpa_s
, buf
+ 9))
3918 } else if (os_strcmp(buf
, "P2P_FIND") == 0) {
3919 if (p2p_ctrl_find(wpa_s
, ""))
3921 } else if (os_strcmp(buf
, "P2P_STOP_FIND") == 0) {
3922 wpas_p2p_stop_find(wpa_s
);
3923 } else if (os_strncmp(buf
, "P2P_CONNECT ", 12) == 0) {
3924 reply_len
= p2p_ctrl_connect(wpa_s
, buf
+ 12, reply
,
3926 } else if (os_strncmp(buf
, "P2P_LISTEN ", 11) == 0) {
3927 if (p2p_ctrl_listen(wpa_s
, buf
+ 11))
3929 } else if (os_strcmp(buf
, "P2P_LISTEN") == 0) {
3930 if (p2p_ctrl_listen(wpa_s
, ""))
3932 } else if (os_strncmp(buf
, "P2P_GROUP_REMOVE ", 17) == 0) {
3933 if (wpas_p2p_group_remove(wpa_s
, buf
+ 17))
3935 } else if (os_strcmp(buf
, "P2P_GROUP_ADD") == 0) {
3936 if (wpas_p2p_group_add(wpa_s
, 0, 0))
3938 } else if (os_strncmp(buf
, "P2P_GROUP_ADD ", 14) == 0) {
3939 if (p2p_ctrl_group_add(wpa_s
, buf
+ 14))
3941 } else if (os_strncmp(buf
, "P2P_PROV_DISC ", 14) == 0) {
3942 if (p2p_ctrl_prov_disc(wpa_s
, buf
+ 14))
3944 } else if (os_strcmp(buf
, "P2P_GET_PASSPHRASE") == 0) {
3945 reply_len
= p2p_get_passphrase(wpa_s
, reply
, reply_size
);
3946 } else if (os_strncmp(buf
, "P2P_SERV_DISC_REQ ", 18) == 0) {
3947 reply_len
= p2p_ctrl_serv_disc_req(wpa_s
, buf
+ 18, reply
,
3949 } else if (os_strncmp(buf
, "P2P_SERV_DISC_CANCEL_REQ ", 25) == 0) {
3950 if (p2p_ctrl_serv_disc_cancel_req(wpa_s
, buf
+ 25) < 0)
3952 } else if (os_strncmp(buf
, "P2P_SERV_DISC_RESP ", 19) == 0) {
3953 if (p2p_ctrl_serv_disc_resp(wpa_s
, buf
+ 19) < 0)
3955 } else if (os_strcmp(buf
, "P2P_SERVICE_UPDATE") == 0) {
3956 wpas_p2p_sd_service_update(wpa_s
);
3957 } else if (os_strncmp(buf
, "P2P_SERV_DISC_EXTERNAL ", 23) == 0) {
3958 if (p2p_ctrl_serv_disc_external(wpa_s
, buf
+ 23) < 0)
3960 } else if (os_strcmp(buf
, "P2P_SERVICE_FLUSH") == 0) {
3961 wpas_p2p_service_flush(wpa_s
);
3962 } else if (os_strncmp(buf
, "P2P_SERVICE_ADD ", 16) == 0) {
3963 if (p2p_ctrl_service_add(wpa_s
, buf
+ 16) < 0)
3965 } else if (os_strncmp(buf
, "P2P_SERVICE_DEL ", 16) == 0) {
3966 if (p2p_ctrl_service_del(wpa_s
, buf
+ 16) < 0)
3968 } else if (os_strncmp(buf
, "P2P_REJECT ", 11) == 0) {
3969 if (p2p_ctrl_reject(wpa_s
, buf
+ 11) < 0)
3971 } else if (os_strncmp(buf
, "P2P_INVITE ", 11) == 0) {
3972 if (p2p_ctrl_invite(wpa_s
, buf
+ 11) < 0)
3974 } else if (os_strncmp(buf
, "P2P_PEER ", 9) == 0) {
3975 reply_len
= p2p_ctrl_peer(wpa_s
, buf
+ 9, reply
,
3977 } else if (os_strncmp(buf
, "P2P_SET ", 8) == 0) {
3978 if (p2p_ctrl_set(wpa_s
, buf
+ 8) < 0)
3980 } else if (os_strcmp(buf
, "P2P_FLUSH") == 0) {
3981 os_memset(wpa_s
->p2p_auth_invite
, 0, ETH_ALEN
);
3982 wpa_s
->force_long_sd
= 0;
3983 if (wpa_s
->global
->p2p
)
3984 p2p_flush(wpa_s
->global
->p2p
);
3985 } else if (os_strncmp(buf
, "P2P_UNAUTHORIZE ", 16) == 0) {
3986 if (wpas_p2p_unauthorize(wpa_s
, buf
+ 16) < 0)
3988 } else if (os_strcmp(buf
, "P2P_CANCEL") == 0) {
3989 if (wpas_p2p_cancel(wpa_s
))
3991 } else if (os_strncmp(buf
, "P2P_PRESENCE_REQ ", 17) == 0) {
3992 if (p2p_ctrl_presence_req(wpa_s
, buf
+ 17) < 0)
3994 } else if (os_strcmp(buf
, "P2P_PRESENCE_REQ") == 0) {
3995 if (p2p_ctrl_presence_req(wpa_s
, "") < 0)
3997 } else if (os_strncmp(buf
, "P2P_EXT_LISTEN ", 15) == 0) {
3998 if (p2p_ctrl_ext_listen(wpa_s
, buf
+ 15) < 0)
4000 } else if (os_strcmp(buf
, "P2P_EXT_LISTEN") == 0) {
4001 if (p2p_ctrl_ext_listen(wpa_s
, "") < 0)
4003 #endif /* CONFIG_P2P */
4004 #ifdef CONFIG_INTERWORKING
4005 } else if (os_strcmp(buf
, "FETCH_ANQP") == 0) {
4006 if (interworking_fetch_anqp(wpa_s
) < 0)
4008 } else if (os_strcmp(buf
, "STOP_FETCH_ANQP") == 0) {
4009 interworking_stop_fetch_anqp(wpa_s
);
4010 } else if (os_strncmp(buf
, "INTERWORKING_SELECT", 19) == 0) {
4011 if (interworking_select(wpa_s
, os_strstr(buf
+ 19, "auto") !=
4014 } else if (os_strncmp(buf
, "INTERWORKING_CONNECT ", 21) == 0) {
4015 if (ctrl_interworking_connect(wpa_s
, buf
+ 21) < 0)
4017 } else if (os_strncmp(buf
, "ANQP_GET ", 9) == 0) {
4018 if (get_anqp(wpa_s
, buf
+ 9) < 0)
4020 #endif /* CONFIG_INTERWORKING */
4021 } else if (os_strncmp(buf
, WPA_CTRL_RSP
, os_strlen(WPA_CTRL_RSP
)) == 0)
4023 if (wpa_supplicant_ctrl_iface_ctrl_rsp(
4024 wpa_s
, buf
+ os_strlen(WPA_CTRL_RSP
)))
4028 } else if (os_strcmp(buf
, "RECONFIGURE") == 0) {
4029 if (wpa_supplicant_reload_configuration(wpa_s
))
4031 } else if (os_strcmp(buf
, "TERMINATE") == 0) {
4032 wpa_supplicant_terminate_proc(wpa_s
->global
);
4033 } else if (os_strncmp(buf
, "BSSID ", 6) == 0) {
4034 if (wpa_supplicant_ctrl_iface_bssid(wpa_s
, buf
+ 6))
4036 } else if (os_strncmp(buf
, "BLACKLIST", 9) == 0) {
4037 reply_len
= wpa_supplicant_ctrl_iface_blacklist(
4038 wpa_s
, buf
+ 9, reply
, reply_size
);
4039 } else if (os_strncmp(buf
, "LOG_LEVEL", 9) == 0) {
4040 reply_len
= wpa_supplicant_ctrl_iface_log_level(
4041 wpa_s
, buf
+ 9, reply
, reply_size
);
4042 } else if (os_strcmp(buf
, "LIST_NETWORKS") == 0) {
4043 reply_len
= wpa_supplicant_ctrl_iface_list_networks(
4044 wpa_s
, reply
, reply_size
);
4045 } else if (os_strcmp(buf
, "DISCONNECT") == 0) {
4047 wpa_s
->sme
.prev_bssid_set
= 0;
4048 #endif /* CONFIG_SME */
4049 wpa_s
->reassociate
= 0;
4050 wpa_s
->disconnected
= 1;
4051 wpa_supplicant_cancel_sched_scan(wpa_s
);
4052 wpa_supplicant_deauthenticate(wpa_s
,
4053 WLAN_REASON_DEAUTH_LEAVING
);
4054 } else if (os_strcmp(buf
, "SCAN") == 0) {
4055 if (wpa_s
->wpa_state
== WPA_INTERFACE_DISABLED
)
4058 if (!wpa_s
->scanning
&&
4059 ((wpa_s
->wpa_state
<= WPA_SCANNING
) ||
4060 (wpa_s
->wpa_state
== WPA_COMPLETED
))) {
4061 wpa_s
->normal_scans
= 0;
4062 wpa_s
->scan_req
= 2;
4063 wpa_supplicant_req_scan(wpa_s
, 0, 0);
4064 } else if (wpa_s
->sched_scanning
) {
4065 wpa_printf(MSG_DEBUG
, "Stop ongoing "
4066 "sched_scan to allow requested "
4067 "full scan to proceed");
4068 wpa_supplicant_cancel_sched_scan(wpa_s
);
4069 wpa_s
->scan_req
= 2;
4070 wpa_supplicant_req_scan(wpa_s
, 0, 0);
4072 wpa_printf(MSG_DEBUG
, "Ongoing scan action - "
4073 "reject new request");
4074 reply_len
= os_snprintf(reply
, reply_size
,
4078 } else if (os_strcmp(buf
, "SCAN_RESULTS") == 0) {
4079 reply_len
= wpa_supplicant_ctrl_iface_scan_results(
4080 wpa_s
, reply
, reply_size
);
4081 } else if (os_strncmp(buf
, "SELECT_NETWORK ", 15) == 0) {
4082 if (wpa_supplicant_ctrl_iface_select_network(wpa_s
, buf
+ 15))
4084 } else if (os_strncmp(buf
, "ENABLE_NETWORK ", 15) == 0) {
4085 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s
, buf
+ 15))
4087 } else if (os_strncmp(buf
, "DISABLE_NETWORK ", 16) == 0) {
4088 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s
, buf
+ 16))
4090 } else if (os_strcmp(buf
, "ADD_NETWORK") == 0) {
4091 reply_len
= wpa_supplicant_ctrl_iface_add_network(
4092 wpa_s
, reply
, reply_size
);
4093 } else if (os_strncmp(buf
, "REMOVE_NETWORK ", 15) == 0) {
4094 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s
, buf
+ 15))
4096 } else if (os_strncmp(buf
, "SET_NETWORK ", 12) == 0) {
4097 if (wpa_supplicant_ctrl_iface_set_network(wpa_s
, buf
+ 12))
4099 } else if (os_strncmp(buf
, "GET_NETWORK ", 12) == 0) {
4100 reply_len
= wpa_supplicant_ctrl_iface_get_network(
4101 wpa_s
, buf
+ 12, reply
, reply_size
);
4102 } else if (os_strcmp(buf
, "LIST_CREDS") == 0) {
4103 reply_len
= wpa_supplicant_ctrl_iface_list_creds(
4104 wpa_s
, reply
, reply_size
);
4105 } else if (os_strcmp(buf
, "ADD_CRED") == 0) {
4106 reply_len
= wpa_supplicant_ctrl_iface_add_cred(
4107 wpa_s
, reply
, reply_size
);
4108 } else if (os_strncmp(buf
, "REMOVE_CRED ", 12) == 0) {
4109 if (wpa_supplicant_ctrl_iface_remove_cred(wpa_s
, buf
+ 12))
4111 } else if (os_strncmp(buf
, "SET_CRED ", 9) == 0) {
4112 if (wpa_supplicant_ctrl_iface_set_cred(wpa_s
, buf
+ 9))
4114 #ifndef CONFIG_NO_CONFIG_WRITE
4115 } else if (os_strcmp(buf
, "SAVE_CONFIG") == 0) {
4116 if (wpa_supplicant_ctrl_iface_save_config(wpa_s
))
4118 #endif /* CONFIG_NO_CONFIG_WRITE */
4119 } else if (os_strncmp(buf
, "GET_CAPABILITY ", 15) == 0) {
4120 reply_len
= wpa_supplicant_ctrl_iface_get_capability(
4121 wpa_s
, buf
+ 15, reply
, reply_size
);
4122 } else if (os_strncmp(buf
, "AP_SCAN ", 8) == 0) {
4123 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s
, buf
+ 8))
4125 } else if (os_strncmp(buf
, "SCAN_INTERVAL ", 14) == 0) {
4126 if (wpa_supplicant_ctrl_iface_scan_interval(wpa_s
, buf
+ 14))
4128 } else if (os_strcmp(buf
, "INTERFACE_LIST") == 0) {
4129 reply_len
= wpa_supplicant_global_iface_list(
4130 wpa_s
->global
, reply
, reply_size
);
4131 } else if (os_strcmp(buf
, "INTERFACES") == 0) {
4132 reply_len
= wpa_supplicant_global_iface_interfaces(
4133 wpa_s
->global
, reply
, reply_size
);
4134 } else if (os_strncmp(buf
, "BSS ", 4) == 0) {
4135 reply_len
= wpa_supplicant_ctrl_iface_bss(
4136 wpa_s
, buf
+ 4, reply
, reply_size
);
4138 } else if (os_strcmp(buf
, "STA-FIRST") == 0) {
4139 reply_len
= ap_ctrl_iface_sta_first(wpa_s
, reply
, reply_size
);
4140 } else if (os_strncmp(buf
, "STA ", 4) == 0) {
4141 reply_len
= ap_ctrl_iface_sta(wpa_s
, buf
+ 4, reply
,
4143 } else if (os_strncmp(buf
, "STA-NEXT ", 9) == 0) {
4144 reply_len
= ap_ctrl_iface_sta_next(wpa_s
, buf
+ 9, reply
,
4146 } else if (os_strncmp(buf
, "DEAUTHENTICATE ", 15) == 0) {
4147 if (ap_ctrl_iface_sta_deauthenticate(wpa_s
, buf
+ 15))
4149 } else if (os_strncmp(buf
, "DISASSOCIATE ", 13) == 0) {
4150 if (ap_ctrl_iface_sta_disassociate(wpa_s
, buf
+ 13))
4152 #endif /* CONFIG_AP */
4153 } else if (os_strcmp(buf
, "SUSPEND") == 0) {
4154 wpas_notify_suspend(wpa_s
->global
);
4155 } else if (os_strcmp(buf
, "RESUME") == 0) {
4156 wpas_notify_resume(wpa_s
->global
);
4157 } else if (os_strcmp(buf
, "DROP_SA") == 0) {
4158 wpa_supplicant_ctrl_iface_drop_sa(wpa_s
);
4159 } else if (os_strncmp(buf
, "ROAM ", 5) == 0) {
4160 if (wpa_supplicant_ctrl_iface_roam(wpa_s
, buf
+ 5))
4162 } else if (os_strncmp(buf
, "STA_AUTOCONNECT ", 16) == 0) {
4163 if (wpa_supplicant_ctrl_iface_sta_autoconnect(wpa_s
, buf
+ 16))
4165 } else if (os_strncmp(buf
, "BSS_EXPIRE_AGE ", 15) == 0) {
4166 if (wpa_supplicant_ctrl_iface_bss_expire_age(wpa_s
, buf
+ 15))
4168 } else if (os_strncmp(buf
, "BSS_EXPIRE_COUNT ", 17) == 0) {
4169 if (wpa_supplicant_ctrl_iface_bss_expire_count(wpa_s
,
4173 } else if (os_strncmp(buf
, "TDLS_DISCOVER ", 14) == 0) {
4174 if (wpa_supplicant_ctrl_iface_tdls_discover(wpa_s
, buf
+ 14))
4176 } else if (os_strncmp(buf
, "TDLS_SETUP ", 11) == 0) {
4177 if (wpa_supplicant_ctrl_iface_tdls_setup(wpa_s
, buf
+ 11))
4179 } else if (os_strncmp(buf
, "TDLS_TEARDOWN ", 14) == 0) {
4180 if (wpa_supplicant_ctrl_iface_tdls_teardown(wpa_s
, buf
+ 14))
4182 #endif /* CONFIG_TDLS */
4183 } else if (os_strncmp(buf
, "SIGNAL_POLL", 11) == 0) {
4184 reply_len
= wpa_supplicant_signal_poll(wpa_s
, reply
,
4186 } else if (os_strcmp(buf
, "REAUTHENTICATE") == 0) {
4187 eapol_sm_request_reauth(wpa_s
->eapol
);
4189 os_memcpy(reply
, "UNKNOWN COMMAND\n", 16);
4193 if (reply_len
< 0) {
4194 os_memcpy(reply
, "FAIL\n", 5);
4199 eapol_sm_notify_ctrl_response(wpa_s
->eapol
);
4201 *resp_len
= reply_len
;
4206 static int wpa_supplicant_global_iface_add(struct wpa_global
*global
,
4209 struct wpa_interface iface
;
4213 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
4214 * TAB<bridge_ifname>
4216 wpa_printf(MSG_DEBUG
, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd
);
4218 os_memset(&iface
, 0, sizeof(iface
));
4221 iface
.ifname
= pos
= cmd
;
4222 pos
= os_strchr(pos
, '\t');
4225 if (iface
.ifname
[0] == '\0')
4230 iface
.confname
= pos
;
4231 pos
= os_strchr(pos
, '\t');
4234 if (iface
.confname
[0] == '\0')
4235 iface
.confname
= NULL
;
4240 pos
= os_strchr(pos
, '\t');
4243 if (iface
.driver
[0] == '\0')
4244 iface
.driver
= NULL
;
4248 iface
.ctrl_interface
= pos
;
4249 pos
= os_strchr(pos
, '\t');
4252 if (iface
.ctrl_interface
[0] == '\0')
4253 iface
.ctrl_interface
= NULL
;
4257 iface
.driver_param
= pos
;
4258 pos
= os_strchr(pos
, '\t');
4261 if (iface
.driver_param
[0] == '\0')
4262 iface
.driver_param
= NULL
;
4266 iface
.bridge_ifname
= pos
;
4267 pos
= os_strchr(pos
, '\t');
4270 if (iface
.bridge_ifname
[0] == '\0')
4271 iface
.bridge_ifname
= NULL
;
4276 if (wpa_supplicant_get_iface(global
, iface
.ifname
))
4279 return wpa_supplicant_add_iface(global
, &iface
) ? 0 : -1;
4283 static int wpa_supplicant_global_iface_remove(struct wpa_global
*global
,
4286 struct wpa_supplicant
*wpa_s
;
4288 wpa_printf(MSG_DEBUG
, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd
);
4290 wpa_s
= wpa_supplicant_get_iface(global
, cmd
);
4293 return wpa_supplicant_remove_iface(global
, wpa_s
, 0);
4297 static void wpa_free_iface_info(struct wpa_interface_info
*iface
)
4299 struct wpa_interface_info
*prev
;
4303 iface
= iface
->next
;
4305 os_free(prev
->ifname
);
4306 os_free(prev
->desc
);
4312 static int wpa_supplicant_global_iface_list(struct wpa_global
*global
,
4316 struct wpa_interface_info
*iface
= NULL
, *last
= NULL
, *tmp
;
4319 for (i
= 0; wpa_drivers
[i
]; i
++) {
4320 struct wpa_driver_ops
*drv
= wpa_drivers
[i
];
4321 if (drv
->get_interfaces
== NULL
)
4323 tmp
= drv
->get_interfaces(global
->drv_priv
[i
]);
4337 for (tmp
= iface
; tmp
; tmp
= tmp
->next
) {
4338 res
= os_snprintf(pos
, end
- pos
, "%s\t%s\t%s\n",
4339 tmp
->drv_name
, tmp
->ifname
,
4340 tmp
->desc
? tmp
->desc
: "");
4341 if (res
< 0 || res
>= end
- pos
) {
4348 wpa_free_iface_info(iface
);
4354 static int wpa_supplicant_global_iface_interfaces(struct wpa_global
*global
,
4359 struct wpa_supplicant
*wpa_s
;
4361 wpa_s
= global
->ifaces
;
4366 res
= os_snprintf(pos
, end
- pos
, "%s\n", wpa_s
->ifname
);
4367 if (res
< 0 || res
>= end
- pos
) {
4372 wpa_s
= wpa_s
->next
;
4378 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global
*global
,
4379 char *buf
, size_t *resp_len
)
4382 const int reply_size
= 2048;
4384 int level
= MSG_DEBUG
;
4386 if (os_strcmp(buf
, "PING") == 0)
4387 level
= MSG_EXCESSIVE
;
4388 wpa_hexdump_ascii(level
, "RX global ctrl_iface",
4389 (const u8
*) buf
, os_strlen(buf
));
4391 reply
= os_malloc(reply_size
);
4392 if (reply
== NULL
) {
4397 os_memcpy(reply
, "OK\n", 3);
4400 if (os_strcmp(buf
, "PING") == 0) {
4401 os_memcpy(reply
, "PONG\n", 5);
4403 } else if (os_strncmp(buf
, "INTERFACE_ADD ", 14) == 0) {
4404 if (wpa_supplicant_global_iface_add(global
, buf
+ 14))
4406 } else if (os_strncmp(buf
, "INTERFACE_REMOVE ", 17) == 0) {
4407 if (wpa_supplicant_global_iface_remove(global
, buf
+ 17))
4409 } else if (os_strcmp(buf
, "INTERFACE_LIST") == 0) {
4410 reply_len
= wpa_supplicant_global_iface_list(
4411 global
, reply
, reply_size
);
4412 } else if (os_strcmp(buf
, "INTERFACES") == 0) {
4413 reply_len
= wpa_supplicant_global_iface_interfaces(
4414 global
, reply
, reply_size
);
4415 } else if (os_strcmp(buf
, "TERMINATE") == 0) {
4416 wpa_supplicant_terminate_proc(global
);
4417 } else if (os_strcmp(buf
, "SUSPEND") == 0) {
4418 wpas_notify_suspend(global
);
4419 } else if (os_strcmp(buf
, "RESUME") == 0) {
4420 wpas_notify_resume(global
);
4422 os_memcpy(reply
, "UNKNOWN COMMAND\n", 16);
4426 if (reply_len
< 0) {
4427 os_memcpy(reply
, "FAIL\n", 5);
4431 *resp_len
= reply_len
;