2 * WPA Supplicant / Control interface (shared code for all backends)
3 * Copyright (c) 2004-2012, 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/ieee802_11_common.h"
16 #include "common/wpa_ctrl.h"
17 #include "eap_peer/eap.h"
18 #include "eapol_supp/eapol_supp_sm.h"
19 #include "rsn_supp/wpa.h"
20 #include "rsn_supp/preauth.h"
21 #include "rsn_supp/pmksa_cache.h"
22 #include "l2_packet/l2_packet.h"
25 #include "wpa_supplicant_i.h"
27 #include "wps_supplicant.h"
30 #include "p2p_supplicant.h"
32 #include "hs20_supplicant.h"
33 #include "wifi_display.h"
37 #include "ctrl_iface.h"
38 #include "interworking.h"
39 #include "blacklist.h"
43 extern struct wpa_driver_ops
*wpa_drivers
[];
45 static int wpa_supplicant_global_iface_list(struct wpa_global
*global
,
47 static int wpa_supplicant_global_iface_interfaces(struct wpa_global
*global
,
51 static int pno_start(struct wpa_supplicant
*wpa_s
)
55 struct wpa_ssid
*ssid
;
56 struct wpa_driver_scan_params params
;
61 if (wpa_s
->wpa_state
== WPA_SCANNING
) {
62 wpa_supplicant_cancel_sched_scan(wpa_s
);
63 wpa_supplicant_cancel_scan(wpa_s
);
66 os_memset(¶ms
, 0, sizeof(params
));
69 ssid
= wpa_s
->conf
->ssid
;
71 if (!wpas_network_disabled(wpa_s
, ssid
))
75 if (num_ssid
> WPAS_MAX_SCAN_SSIDS
) {
76 wpa_printf(MSG_DEBUG
, "PNO: Use only the first %u SSIDs from "
77 "%u", WPAS_MAX_SCAN_SSIDS
, (unsigned int) num_ssid
);
78 num_ssid
= WPAS_MAX_SCAN_SSIDS
;
82 wpa_printf(MSG_DEBUG
, "PNO: No configured SSIDs");
86 params
.filter_ssids
= os_malloc(sizeof(struct wpa_driver_scan_filter
) *
88 if (params
.filter_ssids
== NULL
)
91 ssid
= wpa_s
->conf
->ssid
;
93 if (!wpas_network_disabled(wpa_s
, ssid
)) {
94 params
.ssids
[i
].ssid
= ssid
->ssid
;
95 params
.ssids
[i
].ssid_len
= ssid
->ssid_len
;
97 os_memcpy(params
.filter_ssids
[i
].ssid
, ssid
->ssid
,
99 params
.filter_ssids
[i
].ssid_len
= ssid
->ssid_len
;
100 params
.num_filter_ssids
++;
108 if (wpa_s
->conf
->filter_rssi
)
109 params
.filter_rssi
= wpa_s
->conf
->filter_rssi
;
111 ret
= wpa_drv_sched_scan(wpa_s
, ¶ms
, 10 * 1000);
112 os_free(params
.filter_ssids
);
119 static int pno_stop(struct wpa_supplicant
*wpa_s
)
125 ret
= wpa_drv_stop_sched_scan(wpa_s
);
128 if (wpa_s
->wpa_state
== WPA_SCANNING
)
129 wpa_supplicant_req_scan(wpa_s
, 0, 0);
135 static int set_bssid_filter(struct wpa_supplicant
*wpa_s
, char *val
)
138 u8 addr
[ETH_ALEN
], *filter
= NULL
, *n
;
145 if (hwaddr_aton(pos
, addr
)) {
149 n
= os_realloc_array(filter
, count
+ 1, ETH_ALEN
);
155 os_memcpy(filter
+ count
* ETH_ALEN
, addr
, ETH_ALEN
);
158 pos
= os_strchr(pos
, ' ');
163 wpa_hexdump(MSG_DEBUG
, "bssid_filter", filter
, count
* ETH_ALEN
);
164 os_free(wpa_s
->bssid_filter
);
165 wpa_s
->bssid_filter
= filter
;
166 wpa_s
->bssid_filter_count
= count
;
172 static int set_disallow_aps(struct wpa_supplicant
*wpa_s
, char *val
)
175 u8 addr
[ETH_ALEN
], *bssid
= NULL
, *n
;
176 struct wpa_ssid_value
*ssid
= NULL
, *ns
;
177 size_t count
= 0, ssid_count
= 0;
181 * disallow_list ::= <ssid_spec> | <bssid_spec> | <disallow_list> | “”
182 * SSID_SPEC ::= ssid <SSID_HEX>
183 * BSSID_SPEC ::= bssid <BSSID_HEX>
190 if (os_strncmp(pos
, "bssid ", 6) == 0) {
193 res
= hwaddr_aton2(pos
, addr
);
197 wpa_printf(MSG_DEBUG
, "Invalid disallow_aps "
198 "BSSID value '%s'", pos
);
202 n
= os_realloc_array(bssid
, count
+ 1, ETH_ALEN
);
209 os_memcpy(bssid
+ count
* ETH_ALEN
, addr
, ETH_ALEN
);
211 } else if (os_strncmp(pos
, "ssid ", 5) == 0) {
217 if (*end
== '\0' || *end
== ' ')
222 ns
= os_realloc_array(ssid
, ssid_count
+ 1,
223 sizeof(struct wpa_ssid_value
));
231 if ((end
- pos
) & 0x01 || end
- pos
> 2 * 32 ||
232 hexstr2bin(pos
, ssid
[ssid_count
].ssid
,
233 (end
- pos
) / 2) < 0) {
236 wpa_printf(MSG_DEBUG
, "Invalid disallow_aps "
237 "SSID value '%s'", pos
);
240 ssid
[ssid_count
].ssid_len
= (end
- pos
) / 2;
241 wpa_hexdump_ascii(MSG_DEBUG
, "disallow_aps SSID",
242 ssid
[ssid_count
].ssid
,
243 ssid
[ssid_count
].ssid_len
);
247 wpa_printf(MSG_DEBUG
, "Unexpected disallow_aps value "
254 pos
= os_strchr(pos
, ' ');
259 wpa_hexdump(MSG_DEBUG
, "disallow_aps_bssid", bssid
, count
* ETH_ALEN
);
260 os_free(wpa_s
->disallow_aps_bssid
);
261 wpa_s
->disallow_aps_bssid
= bssid
;
262 wpa_s
->disallow_aps_bssid_count
= count
;
264 wpa_printf(MSG_DEBUG
, "disallow_aps_ssid_count %d", (int) ssid_count
);
265 os_free(wpa_s
->disallow_aps_ssid
);
266 wpa_s
->disallow_aps_ssid
= ssid
;
267 wpa_s
->disallow_aps_ssid_count
= ssid_count
;
269 if (!wpa_s
->current_ssid
|| wpa_s
->wpa_state
< WPA_AUTHENTICATING
)
272 c
= wpa_s
->current_ssid
;
273 if (c
->mode
!= WPAS_MODE_INFRA
&& c
->mode
!= WPAS_MODE_IBSS
)
276 if (!disallowed_bssid(wpa_s
, wpa_s
->bssid
) &&
277 !disallowed_ssid(wpa_s
, c
->ssid
, c
->ssid_len
))
280 wpa_printf(MSG_DEBUG
, "Disconnect and try to find another network "
281 "because current AP was marked disallowed");
284 wpa_s
->sme
.prev_bssid_set
= 0;
285 #endif /* CONFIG_SME */
286 wpa_s
->reassociate
= 1;
287 wpa_supplicant_deauthenticate(wpa_s
, WLAN_REASON_DEAUTH_LEAVING
);
288 wpa_supplicant_req_scan(wpa_s
, 0, 0);
294 static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant
*wpa_s
,
300 value
= os_strchr(cmd
, ' ');
305 wpa_printf(MSG_DEBUG
, "CTRL_IFACE SET '%s'='%s'", cmd
, value
);
306 if (os_strcasecmp(cmd
, "EAPOL::heldPeriod") == 0) {
307 eapol_sm_configure(wpa_s
->eapol
,
308 atoi(value
), -1, -1, -1);
309 } else if (os_strcasecmp(cmd
, "EAPOL::authPeriod") == 0) {
310 eapol_sm_configure(wpa_s
->eapol
,
311 -1, atoi(value
), -1, -1);
312 } else if (os_strcasecmp(cmd
, "EAPOL::startPeriod") == 0) {
313 eapol_sm_configure(wpa_s
->eapol
,
314 -1, -1, atoi(value
), -1);
315 } else if (os_strcasecmp(cmd
, "EAPOL::maxStart") == 0) {
316 eapol_sm_configure(wpa_s
->eapol
,
317 -1, -1, -1, atoi(value
));
318 } else if (os_strcasecmp(cmd
, "dot11RSNAConfigPMKLifetime") == 0) {
319 if (wpa_sm_set_param(wpa_s
->wpa
, RSNA_PMK_LIFETIME
,
322 } else if (os_strcasecmp(cmd
, "dot11RSNAConfigPMKReauthThreshold") ==
324 if (wpa_sm_set_param(wpa_s
->wpa
, RSNA_PMK_REAUTH_THRESHOLD
,
327 } else if (os_strcasecmp(cmd
, "dot11RSNAConfigSATimeout") == 0) {
328 if (wpa_sm_set_param(wpa_s
->wpa
, RSNA_SA_TIMEOUT
, atoi(value
)))
330 } else if (os_strcasecmp(cmd
, "wps_fragment_size") == 0) {
331 wpa_s
->wps_fragment_size
= atoi(value
);
332 #ifdef CONFIG_WPS_TESTING
333 } else if (os_strcasecmp(cmd
, "wps_version_number") == 0) {
335 val
= strtol(value
, NULL
, 0);
336 if (val
< 0 || val
> 0xff) {
338 wpa_printf(MSG_DEBUG
, "WPS: Invalid "
339 "wps_version_number %ld", val
);
341 wps_version_number
= val
;
342 wpa_printf(MSG_DEBUG
, "WPS: Testing - force WPS "
344 (wps_version_number
& 0xf0) >> 4,
345 wps_version_number
& 0x0f);
347 } else if (os_strcasecmp(cmd
, "wps_testing_dummy_cred") == 0) {
348 wps_testing_dummy_cred
= atoi(value
);
349 wpa_printf(MSG_DEBUG
, "WPS: Testing - dummy_cred=%d",
350 wps_testing_dummy_cred
);
351 #endif /* CONFIG_WPS_TESTING */
352 } else if (os_strcasecmp(cmd
, "ampdu") == 0) {
353 if (wpa_drv_ampdu(wpa_s
, atoi(value
)) < 0)
355 #ifdef CONFIG_TDLS_TESTING
356 } else if (os_strcasecmp(cmd
, "tdls_testing") == 0) {
357 extern unsigned int tdls_testing
;
358 tdls_testing
= strtol(value
, NULL
, 0);
359 wpa_printf(MSG_DEBUG
, "TDLS: tdls_testing=0x%x", tdls_testing
);
360 #endif /* CONFIG_TDLS_TESTING */
362 } else if (os_strcasecmp(cmd
, "tdls_disabled") == 0) {
363 int disabled
= atoi(value
);
364 wpa_printf(MSG_DEBUG
, "TDLS: tdls_disabled=%d", disabled
);
366 if (wpa_drv_tdls_oper(wpa_s
, TDLS_DISABLE
, NULL
) < 0)
368 } else if (wpa_drv_tdls_oper(wpa_s
, TDLS_ENABLE
, NULL
) < 0)
370 wpa_tdls_enable(wpa_s
->wpa
, !disabled
);
371 #endif /* CONFIG_TDLS */
372 } else if (os_strcasecmp(cmd
, "pno") == 0) {
374 ret
= pno_start(wpa_s
);
376 ret
= pno_stop(wpa_s
);
377 } else if (os_strcasecmp(cmd
, "radio_disabled") == 0) {
378 int disabled
= atoi(value
);
379 if (wpa_drv_radio_disable(wpa_s
, disabled
) < 0)
382 wpa_supplicant_set_state(wpa_s
, WPA_INACTIVE
);
383 } else if (os_strcasecmp(cmd
, "uapsd") == 0) {
384 if (os_strcmp(value
, "disable") == 0)
385 wpa_s
->set_sta_uapsd
= 0;
389 /* format: BE,BK,VI,VO;max SP Length */
391 pos
= os_strchr(value
, ',');
396 pos
= os_strchr(pos
, ',');
401 pos
= os_strchr(pos
, ',');
406 /* ignore max SP Length for now */
408 wpa_s
->set_sta_uapsd
= 1;
409 wpa_s
->sta_uapsd
= 0;
411 wpa_s
->sta_uapsd
|= BIT(0);
413 wpa_s
->sta_uapsd
|= BIT(1);
415 wpa_s
->sta_uapsd
|= BIT(2);
417 wpa_s
->sta_uapsd
|= BIT(3);
419 } else if (os_strcasecmp(cmd
, "ps") == 0) {
420 ret
= wpa_drv_set_p2p_powersave(wpa_s
, atoi(value
), -1, -1);
421 #ifdef CONFIG_WIFI_DISPLAY
422 } else if (os_strcasecmp(cmd
, "wifi_display") == 0) {
423 wifi_display_enable(wpa_s
->global
, !!atoi(value
));
424 #endif /* CONFIG_WIFI_DISPLAY */
425 } else if (os_strcasecmp(cmd
, "bssid_filter") == 0) {
426 ret
= set_bssid_filter(wpa_s
, value
);
427 } else if (os_strcasecmp(cmd
, "disallow_aps") == 0) {
428 ret
= set_disallow_aps(wpa_s
, value
);
429 } else if (os_strcasecmp(cmd
, "no_keep_alive") == 0) {
430 wpa_s
->no_keep_alive
= !!atoi(value
);
433 ret
= wpa_config_process_global(wpa_s
->conf
, cmd
, -1);
435 wpa_supplicant_update_config(wpa_s
);
442 static int wpa_supplicant_ctrl_iface_get(struct wpa_supplicant
*wpa_s
,
443 char *cmd
, char *buf
, size_t buflen
)
447 wpa_printf(MSG_DEBUG
, "CTRL_IFACE GET '%s'", cmd
);
449 if (os_strcmp(cmd
, "version") == 0) {
450 res
= os_snprintf(buf
, buflen
, "%s", VERSION_STR
);
451 } else if (os_strcasecmp(cmd
, "country") == 0) {
452 if (wpa_s
->conf
->country
[0] && wpa_s
->conf
->country
[1])
453 res
= os_snprintf(buf
, buflen
, "%c%c",
454 wpa_s
->conf
->country
[0],
455 wpa_s
->conf
->country
[1]);
456 #ifdef CONFIG_WIFI_DISPLAY
457 } else if (os_strcasecmp(cmd
, "wifi_display") == 0) {
458 res
= os_snprintf(buf
, buflen
, "%d",
459 wpa_s
->global
->wifi_display
);
460 if (res
< 0 || (unsigned int) res
>= buflen
)
463 #endif /* CONFIG_WIFI_DISPLAY */
466 if (res
< 0 || (unsigned int) res
>= buflen
)
472 #ifdef IEEE8021X_EAPOL
473 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant
*wpa_s
,
477 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
479 if (hwaddr_aton(addr
, bssid
)) {
480 wpa_printf(MSG_DEBUG
, "CTRL_IFACE PREAUTH: invalid address "
485 wpa_printf(MSG_DEBUG
, "CTRL_IFACE PREAUTH " MACSTR
, MAC2STR(bssid
));
486 rsn_preauth_deinit(wpa_s
->wpa
);
487 if (rsn_preauth_init(wpa_s
->wpa
, bssid
, ssid
? &ssid
->eap
: NULL
))
492 #endif /* IEEE8021X_EAPOL */
495 #ifdef CONFIG_PEERKEY
496 /* MLME-STKSTART.request(peer) */
497 static int wpa_supplicant_ctrl_iface_stkstart(
498 struct wpa_supplicant
*wpa_s
, char *addr
)
502 if (hwaddr_aton(addr
, peer
)) {
503 wpa_printf(MSG_DEBUG
, "CTRL_IFACE STKSTART: invalid "
504 "address '%s'", addr
);
508 wpa_printf(MSG_DEBUG
, "CTRL_IFACE STKSTART " MACSTR
,
511 return wpa_sm_stkstart(wpa_s
->wpa
, peer
);
513 #endif /* CONFIG_PEERKEY */
518 static int wpa_supplicant_ctrl_iface_tdls_discover(
519 struct wpa_supplicant
*wpa_s
, char *addr
)
524 if (hwaddr_aton(addr
, peer
)) {
525 wpa_printf(MSG_DEBUG
, "CTRL_IFACE TDLS_DISCOVER: invalid "
526 "address '%s'", addr
);
530 wpa_printf(MSG_DEBUG
, "CTRL_IFACE TDLS_DISCOVER " MACSTR
,
533 if (wpa_tdls_is_external_setup(wpa_s
->wpa
))
534 ret
= wpa_tdls_send_discovery_request(wpa_s
->wpa
, peer
);
536 ret
= wpa_drv_tdls_oper(wpa_s
, TDLS_DISCOVERY_REQ
, peer
);
542 static int wpa_supplicant_ctrl_iface_tdls_setup(
543 struct wpa_supplicant
*wpa_s
, char *addr
)
548 if (hwaddr_aton(addr
, peer
)) {
549 wpa_printf(MSG_DEBUG
, "CTRL_IFACE TDLS_SETUP: invalid "
550 "address '%s'", addr
);
554 wpa_printf(MSG_DEBUG
, "CTRL_IFACE TDLS_SETUP " MACSTR
,
557 wpa_tdls_remove(wpa_s
->wpa
, peer
);
559 if (wpa_tdls_is_external_setup(wpa_s
->wpa
))
560 ret
= wpa_tdls_start(wpa_s
->wpa
, peer
);
562 ret
= wpa_drv_tdls_oper(wpa_s
, TDLS_SETUP
, peer
);
568 static int wpa_supplicant_ctrl_iface_tdls_teardown(
569 struct wpa_supplicant
*wpa_s
, char *addr
)
573 if (hwaddr_aton(addr
, peer
)) {
574 wpa_printf(MSG_DEBUG
, "CTRL_IFACE TDLS_TEARDOWN: invalid "
575 "address '%s'", addr
);
579 wpa_printf(MSG_DEBUG
, "CTRL_IFACE TDLS_TEARDOWN " MACSTR
,
582 return wpa_tdls_teardown_link(wpa_s
->wpa
, peer
,
583 WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED
);
586 #endif /* CONFIG_TDLS */
589 #ifdef CONFIG_IEEE80211R
590 static int wpa_supplicant_ctrl_iface_ft_ds(
591 struct wpa_supplicant
*wpa_s
, char *addr
)
593 u8 target_ap
[ETH_ALEN
];
597 if (hwaddr_aton(addr
, target_ap
)) {
598 wpa_printf(MSG_DEBUG
, "CTRL_IFACE FT_DS: invalid "
599 "address '%s'", addr
);
603 wpa_printf(MSG_DEBUG
, "CTRL_IFACE FT_DS " MACSTR
, MAC2STR(target_ap
));
605 bss
= wpa_bss_get_bssid(wpa_s
, target_ap
);
607 mdie
= wpa_bss_get_ie(bss
, WLAN_EID_MOBILITY_DOMAIN
);
611 return wpa_ft_start_over_ds(wpa_s
->wpa
, target_ap
, mdie
);
613 #endif /* CONFIG_IEEE80211R */
617 static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant
*wpa_s
,
620 u8 bssid
[ETH_ALEN
], *_bssid
= bssid
;
622 u8 p2p_dev_addr
[ETH_ALEN
];
623 #endif /* CONFIG_P2P */
625 u8
*_p2p_dev_addr
= NULL
;
626 #endif /* CONFIG_AP */
628 if (cmd
== NULL
|| os_strcmp(cmd
, "any") == 0) {
631 } else if (os_strncmp(cmd
, "p2p_dev_addr=", 13) == 0) {
632 if (hwaddr_aton(cmd
+ 13, p2p_dev_addr
)) {
633 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_PBC: invalid "
634 "P2P Device Address '%s'",
638 _p2p_dev_addr
= p2p_dev_addr
;
639 #endif /* CONFIG_P2P */
640 } else if (hwaddr_aton(cmd
, bssid
)) {
641 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
648 return wpa_supplicant_ap_wps_pbc(wpa_s
, _bssid
, _p2p_dev_addr
);
649 #endif /* CONFIG_AP */
651 return wpas_wps_start_pbc(wpa_s
, _bssid
, 0);
655 static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant
*wpa_s
,
656 char *cmd
, char *buf
,
659 u8 bssid
[ETH_ALEN
], *_bssid
= bssid
;
663 pin
= os_strchr(cmd
, ' ');
667 if (os_strcmp(cmd
, "any") == 0)
669 else if (os_strcmp(cmd
, "get") == 0) {
670 ret
= wps_generate_pin();
672 } else if (hwaddr_aton(cmd
, bssid
)) {
673 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
679 if (wpa_s
->ap_iface
) {
684 pos
= os_strchr(pin
, ' ');
691 return wpa_supplicant_ap_wps_pin(wpa_s
, _bssid
, pin
,
692 buf
, buflen
, timeout
);
694 #endif /* CONFIG_AP */
697 ret
= wpas_wps_start_pin(wpa_s
, _bssid
, pin
, 0,
701 ret
= os_snprintf(buf
, buflen
, "%s", pin
);
702 if (ret
< 0 || (size_t) ret
>= buflen
)
707 ret
= wpas_wps_start_pin(wpa_s
, _bssid
, NULL
, 0, DEV_PW_DEFAULT
);
712 /* Return the generated PIN */
713 ret
= os_snprintf(buf
, buflen
, "%08d", ret
);
714 if (ret
< 0 || (size_t) ret
>= buflen
)
720 static int wpa_supplicant_ctrl_iface_wps_check_pin(
721 struct wpa_supplicant
*wpa_s
, char *cmd
, char *buf
, size_t buflen
)
728 wpa_hexdump_ascii_key(MSG_DEBUG
, "WPS_CHECK_PIN",
729 (u8
*) cmd
, os_strlen(cmd
));
730 for (pos
= cmd
, len
= 0; *pos
!= '\0'; pos
++) {
731 if (*pos
< '0' || *pos
> '9')
735 wpa_printf(MSG_DEBUG
, "WPS: Too long PIN");
739 if (len
!= 4 && len
!= 8) {
740 wpa_printf(MSG_DEBUG
, "WPS: Invalid PIN length %d", (int) len
);
746 unsigned int pin_val
;
748 if (!wps_pin_valid(pin_val
)) {
749 wpa_printf(MSG_DEBUG
, "WPS: Invalid checksum digit");
750 ret
= os_snprintf(buf
, buflen
, "FAIL-CHECKSUM\n");
751 if (ret
< 0 || (size_t) ret
>= buflen
)
757 ret
= os_snprintf(buf
, buflen
, "%s", pin
);
758 if (ret
< 0 || (size_t) ret
>= buflen
)
765 #ifdef CONFIG_WPS_NFC
767 static int wpa_supplicant_ctrl_iface_wps_nfc(struct wpa_supplicant
*wpa_s
,
770 u8 bssid
[ETH_ALEN
], *_bssid
= bssid
;
772 if (cmd
== NULL
|| cmd
[0] == '\0')
774 else if (hwaddr_aton(cmd
, bssid
))
777 return wpas_wps_start_nfc(wpa_s
, _bssid
);
781 static int wpa_supplicant_ctrl_iface_wps_nfc_token(
782 struct wpa_supplicant
*wpa_s
, char *cmd
, char *reply
, size_t max_len
)
788 if (os_strcmp(cmd
, "WPS") == 0)
790 else if (os_strcmp(cmd
, "NDEF") == 0)
795 buf
= wpas_wps_nfc_token(wpa_s
, ndef
);
799 res
= wpa_snprintf_hex_uppercase(reply
, max_len
, wpabuf_head(buf
),
810 static int wpa_supplicant_ctrl_iface_wps_nfc_tag_read(
811 struct wpa_supplicant
*wpa_s
, char *pos
)
817 len
= os_strlen(pos
);
822 buf
= wpabuf_alloc(len
);
825 if (hexstr2bin(pos
, wpabuf_put(buf
, len
), len
) < 0) {
830 ret
= wpas_wps_nfc_tag_read(wpa_s
, buf
);
837 static int wpas_ctrl_nfc_get_handover_req_wps(struct wpa_supplicant
*wpa_s
,
838 char *reply
, size_t max_len
,
844 buf
= wpas_wps_nfc_handover_req(wpa_s
, cr
);
848 res
= wpa_snprintf_hex_uppercase(reply
, max_len
, wpabuf_head(buf
),
859 static int wpas_ctrl_nfc_get_handover_req(struct wpa_supplicant
*wpa_s
,
860 char *cmd
, char *reply
,
865 pos
= os_strchr(cmd
, ' ');
870 if (os_strcmp(cmd
, "NDEF") != 0)
873 if (os_strcmp(pos
, "WPS") == 0 || os_strcmp(pos
, "WPS-CR") == 0) {
874 return wpas_ctrl_nfc_get_handover_req_wps(
875 wpa_s
, reply
, max_len
, os_strcmp(pos
, "WPS-CR") == 0);
882 static int wpas_ctrl_nfc_get_handover_sel_wps(struct wpa_supplicant
*wpa_s
,
883 char *reply
, size_t max_len
)
888 buf
= wpas_wps_nfc_handover_sel(wpa_s
);
892 res
= wpa_snprintf_hex_uppercase(reply
, max_len
, wpabuf_head(buf
),
903 static int wpas_ctrl_nfc_get_handover_sel(struct wpa_supplicant
*wpa_s
,
904 char *cmd
, char *reply
,
909 pos
= os_strchr(cmd
, ' ');
914 if (os_strcmp(cmd
, "NDEF") != 0)
917 if (os_strcmp(pos
, "WPS") == 0) {
918 return wpas_ctrl_nfc_get_handover_sel_wps(wpa_s
, reply
,
926 static int wpas_ctrl_nfc_rx_handover_req(struct wpa_supplicant
*wpa_s
,
927 char *cmd
, char *reply
,
934 len
= os_strlen(cmd
);
939 buf
= wpabuf_alloc(len
);
942 if (hexstr2bin(cmd
, wpabuf_put(buf
, len
), len
) < 0) {
947 ret
= wpas_wps_nfc_rx_handover_req(wpa_s
, buf
);
954 static int wpas_ctrl_nfc_rx_handover_sel(struct wpa_supplicant
*wpa_s
,
961 len
= os_strlen(cmd
);
966 buf
= wpabuf_alloc(len
);
969 if (hexstr2bin(cmd
, wpabuf_put(buf
, len
), len
) < 0) {
974 ret
= wpas_wps_nfc_rx_handover_sel(wpa_s
, buf
);
981 static int wpas_ctrl_nfc_report_handover(struct wpa_supplicant
*wpa_s
,
985 struct wpabuf
*req
, *sel
;
987 char *pos
, *role
, *type
, *pos2
;
990 pos
= os_strchr(role
, ' ');
996 pos
= os_strchr(type
, ' ');
1001 pos2
= os_strchr(pos
, ' ');
1006 len
= os_strlen(pos
);
1011 req
= wpabuf_alloc(len
);
1014 if (hexstr2bin(pos
, wpabuf_put(req
, len
), len
) < 0) {
1019 len
= os_strlen(pos2
);
1026 sel
= wpabuf_alloc(len
);
1031 if (hexstr2bin(pos2
, wpabuf_put(sel
, len
), len
) < 0) {
1037 if (os_strcmp(role
, "INIT") == 0 && os_strcmp(type
, "WPS") == 0) {
1038 ret
= wpas_wps_nfc_report_handover(wpa_s
, req
, sel
);
1040 wpa_printf(MSG_DEBUG
, "NFC: Unsupported connection handover "
1041 "reported: role=%s type=%s", role
, type
);
1050 #endif /* CONFIG_WPS_NFC */
1053 static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant
*wpa_s
,
1062 struct wps_new_ap_settings ap
;
1064 pin
= os_strchr(cmd
, ' ');
1069 if (hwaddr_aton(cmd
, bssid
)) {
1070 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_REG: invalid BSSID '%s'",
1075 new_ssid
= os_strchr(pin
, ' ');
1076 if (new_ssid
== NULL
)
1077 return wpas_wps_start_reg(wpa_s
, bssid
, pin
, NULL
);
1080 new_auth
= os_strchr(new_ssid
, ' ');
1081 if (new_auth
== NULL
)
1085 new_encr
= os_strchr(new_auth
, ' ');
1086 if (new_encr
== NULL
)
1090 new_key
= os_strchr(new_encr
, ' ');
1091 if (new_key
== NULL
)
1095 os_memset(&ap
, 0, sizeof(ap
));
1096 ap
.ssid_hex
= new_ssid
;
1099 ap
.key_hex
= new_key
;
1100 return wpas_wps_start_reg(wpa_s
, bssid
, pin
, &ap
);
1105 static int wpa_supplicant_ctrl_iface_wps_ap_pin(struct wpa_supplicant
*wpa_s
,
1106 char *cmd
, char *buf
,
1111 const char *pin_txt
;
1113 if (!wpa_s
->ap_iface
)
1116 pos
= os_strchr(cmd
, ' ');
1120 if (os_strcmp(cmd
, "disable") == 0) {
1121 wpas_wps_ap_pin_disable(wpa_s
);
1122 return os_snprintf(buf
, buflen
, "OK\n");
1125 if (os_strcmp(cmd
, "random") == 0) {
1127 timeout
= atoi(pos
);
1128 pin_txt
= wpas_wps_ap_pin_random(wpa_s
, timeout
);
1129 if (pin_txt
== NULL
)
1131 return os_snprintf(buf
, buflen
, "%s", pin_txt
);
1134 if (os_strcmp(cmd
, "get") == 0) {
1135 pin_txt
= wpas_wps_ap_pin_get(wpa_s
);
1136 if (pin_txt
== NULL
)
1138 return os_snprintf(buf
, buflen
, "%s", pin_txt
);
1141 if (os_strcmp(cmd
, "set") == 0) {
1146 pos
= os_strchr(pos
, ' ');
1149 timeout
= atoi(pos
);
1151 if (os_strlen(pin
) > buflen
)
1153 if (wpas_wps_ap_pin_set(wpa_s
, pin
, timeout
) < 0)
1155 return os_snprintf(buf
, buflen
, "%s", pin
);
1160 #endif /* CONFIG_AP */
1163 #ifdef CONFIG_WPS_ER
1164 static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant
*wpa_s
,
1167 char *uuid
= cmd
, *pin
, *pos
;
1168 u8 addr_buf
[ETH_ALEN
], *addr
= NULL
;
1169 pin
= os_strchr(uuid
, ' ');
1173 pos
= os_strchr(pin
, ' ');
1176 if (hwaddr_aton(pos
, addr_buf
) == 0)
1179 return wpas_wps_er_add_pin(wpa_s
, addr
, uuid
, pin
);
1183 static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant
*wpa_s
,
1186 char *uuid
= cmd
, *pin
;
1187 pin
= os_strchr(uuid
, ' ');
1191 return wpas_wps_er_learn(wpa_s
, uuid
, pin
);
1195 static int wpa_supplicant_ctrl_iface_wps_er_set_config(
1196 struct wpa_supplicant
*wpa_s
, char *cmd
)
1198 char *uuid
= cmd
, *id
;
1199 id
= os_strchr(uuid
, ' ');
1203 return wpas_wps_er_set_config(wpa_s
, uuid
, atoi(id
));
1207 static int wpa_supplicant_ctrl_iface_wps_er_config(
1208 struct wpa_supplicant
*wpa_s
, char *cmd
)
1215 struct wps_new_ap_settings ap
;
1217 pin
= os_strchr(cmd
, ' ');
1222 new_ssid
= os_strchr(pin
, ' ');
1223 if (new_ssid
== NULL
)
1227 new_auth
= os_strchr(new_ssid
, ' ');
1228 if (new_auth
== NULL
)
1232 new_encr
= os_strchr(new_auth
, ' ');
1233 if (new_encr
== NULL
)
1237 new_key
= os_strchr(new_encr
, ' ');
1238 if (new_key
== NULL
)
1242 os_memset(&ap
, 0, sizeof(ap
));
1243 ap
.ssid_hex
= new_ssid
;
1246 ap
.key_hex
= new_key
;
1247 return wpas_wps_er_config(wpa_s
, cmd
, pin
, &ap
);
1251 #ifdef CONFIG_WPS_NFC
1252 static int wpa_supplicant_ctrl_iface_wps_er_nfc_config_token(
1253 struct wpa_supplicant
*wpa_s
, char *cmd
, char *reply
, size_t max_len
)
1260 uuid
= os_strchr(cmd
, ' ');
1265 if (os_strcmp(cmd
, "WPS") == 0)
1267 else if (os_strcmp(cmd
, "NDEF") == 0)
1272 buf
= wpas_wps_er_nfc_config_token(wpa_s
, ndef
, uuid
);
1276 res
= wpa_snprintf_hex_uppercase(reply
, max_len
, wpabuf_head(buf
),
1278 reply
[res
++] = '\n';
1285 #endif /* CONFIG_WPS_NFC */
1286 #endif /* CONFIG_WPS_ER */
1288 #endif /* CONFIG_WPS */
1291 #ifdef CONFIG_IBSS_RSN
1292 static int wpa_supplicant_ctrl_iface_ibss_rsn(
1293 struct wpa_supplicant
*wpa_s
, char *addr
)
1297 if (hwaddr_aton(addr
, peer
)) {
1298 wpa_printf(MSG_DEBUG
, "CTRL_IFACE IBSS_RSN: invalid "
1299 "address '%s'", addr
);
1303 wpa_printf(MSG_DEBUG
, "CTRL_IFACE IBSS_RSN " MACSTR
,
1306 return ibss_rsn_start(wpa_s
->ibss_rsn
, peer
);
1308 #endif /* CONFIG_IBSS_RSN */
1311 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant
*wpa_s
,
1314 #ifdef IEEE8021X_EAPOL
1317 struct wpa_ssid
*ssid
;
1319 pos
= os_strchr(rsp
, '-');
1324 pos
= os_strchr(pos
, ':');
1329 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: field=%s id=%d", rsp
, id
);
1330 wpa_hexdump_ascii_key(MSG_DEBUG
, "CTRL_IFACE: value",
1331 (u8
*) pos
, os_strlen(pos
));
1333 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1335 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
1340 return wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s
, ssid
, rsp
,
1342 #else /* IEEE8021X_EAPOL */
1343 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: 802.1X not included");
1345 #endif /* IEEE8021X_EAPOL */
1349 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant
*wpa_s
,
1351 char *buf
, size_t buflen
)
1353 char *pos
, *end
, tmp
[30];
1354 int res
, verbose
, wps
, ret
;
1356 verbose
= os_strcmp(params
, "-VERBOSE") == 0;
1357 wps
= os_strcmp(params
, "-WPS") == 0;
1360 if (wpa_s
->wpa_state
>= WPA_ASSOCIATED
) {
1361 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
1362 ret
= os_snprintf(pos
, end
- pos
, "bssid=" MACSTR
"\n",
1363 MAC2STR(wpa_s
->bssid
));
1364 if (ret
< 0 || ret
>= end
- pos
)
1368 u8
*_ssid
= ssid
->ssid
;
1369 size_t ssid_len
= ssid
->ssid_len
;
1370 u8 ssid_buf
[MAX_SSID_LEN
];
1371 if (ssid_len
== 0) {
1372 int _res
= wpa_drv_get_ssid(wpa_s
, ssid_buf
);
1379 ret
= os_snprintf(pos
, end
- pos
, "ssid=%s\nid=%d\n",
1380 wpa_ssid_txt(_ssid
, ssid_len
),
1382 if (ret
< 0 || ret
>= end
- pos
)
1386 if (wps
&& ssid
->passphrase
&&
1387 wpa_key_mgmt_wpa_psk(ssid
->key_mgmt
) &&
1388 (ssid
->mode
== WPAS_MODE_AP
||
1389 ssid
->mode
== WPAS_MODE_P2P_GO
)) {
1390 ret
= os_snprintf(pos
, end
- pos
,
1393 if (ret
< 0 || ret
>= end
- pos
)
1398 ret
= os_snprintf(pos
, end
- pos
,
1401 if (ret
< 0 || ret
>= end
- pos
)
1406 switch (ssid
->mode
) {
1407 case WPAS_MODE_INFRA
:
1408 ret
= os_snprintf(pos
, end
- pos
,
1411 case WPAS_MODE_IBSS
:
1412 ret
= os_snprintf(pos
, end
- pos
,
1416 ret
= os_snprintf(pos
, end
- pos
,
1419 case WPAS_MODE_P2P_GO
:
1420 ret
= os_snprintf(pos
, end
- pos
,
1423 case WPAS_MODE_P2P_GROUP_FORMATION
:
1424 ret
= os_snprintf(pos
, end
- pos
,
1425 "mode=P2P GO - group "
1432 if (ret
< 0 || ret
>= end
- pos
)
1438 if (wpa_s
->ap_iface
) {
1439 pos
+= ap_ctrl_iface_wpa_get_status(wpa_s
, pos
,
1443 #endif /* CONFIG_AP */
1444 pos
+= wpa_sm_get_status(wpa_s
->wpa
, pos
, end
- pos
, verbose
);
1447 if (wpa_s
->wpa_state
>= WPA_ASSOCIATED
&&
1448 wpa_s
->sme
.sae
.state
== SAE_ACCEPTED
&& !wpa_s
->ap_iface
) {
1449 ret
= os_snprintf(pos
, end
- pos
, "sae_group=%d\n",
1450 wpa_s
->sme
.sae
.group
);
1451 if (ret
< 0 || ret
>= end
- pos
)
1455 #endif /* CONFIG_SAE */
1456 ret
= os_snprintf(pos
, end
- pos
, "wpa_state=%s\n",
1457 wpa_supplicant_state_txt(wpa_s
->wpa_state
));
1458 if (ret
< 0 || ret
>= end
- pos
)
1463 l2_packet_get_ip_addr(wpa_s
->l2
, tmp
, sizeof(tmp
)) >= 0) {
1464 ret
= os_snprintf(pos
, end
- pos
, "ip_address=%s\n", tmp
);
1465 if (ret
< 0 || ret
>= end
- pos
)
1471 if (wpa_s
->global
->p2p
) {
1472 ret
= os_snprintf(pos
, end
- pos
, "p2p_device_address=" MACSTR
1473 "\n", MAC2STR(wpa_s
->global
->p2p_dev_addr
));
1474 if (ret
< 0 || ret
>= end
- pos
)
1478 #endif /* CONFIG_P2P */
1480 ret
= os_snprintf(pos
, end
- pos
, "address=" MACSTR
"\n",
1481 MAC2STR(wpa_s
->own_addr
));
1482 if (ret
< 0 || ret
>= end
- pos
)
1487 if (wpa_s
->current_bss
&&
1488 wpa_bss_get_vendor_ie(wpa_s
->current_bss
, HS20_IE_VENDOR_TYPE
) &&
1489 wpa_s
->wpa_proto
== WPA_PROTO_RSN
&&
1490 wpa_key_mgmt_wpa_ieee8021x(wpa_s
->key_mgmt
)) {
1491 ret
= os_snprintf(pos
, end
- pos
, "hs20=1\n");
1492 if (ret
< 0 || ret
>= end
- pos
)
1497 if (wpa_s
->current_ssid
) {
1498 struct wpa_cred
*cred
;
1501 for (cred
= wpa_s
->conf
->cred
; cred
; cred
= cred
->next
) {
1502 if (wpa_s
->current_ssid
->parent_cred
!= cred
)
1507 ret
= os_snprintf(pos
, end
- pos
, "home_sp=%s\n",
1509 if (ret
< 0 || ret
>= end
- pos
)
1513 if (wpa_s
->current_bss
== NULL
||
1514 wpa_s
->current_bss
->anqp
== NULL
)
1517 res
= interworking_home_sp_cred(
1519 wpa_s
->current_bss
->anqp
->domain_name
);
1527 ret
= os_snprintf(pos
, end
- pos
, "sp_type=%s\n", type
);
1528 if (ret
< 0 || ret
>= end
- pos
)
1535 #endif /* CONFIG_HS20 */
1537 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s
->key_mgmt
) ||
1538 wpa_s
->key_mgmt
== WPA_KEY_MGMT_IEEE8021X_NO_WPA
) {
1539 res
= eapol_sm_get_status(wpa_s
->eapol
, pos
, end
- pos
,
1545 res
= rsn_preauth_get_status(wpa_s
->wpa
, pos
, end
- pos
, verbose
);
1553 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant
*wpa_s
,
1558 struct wpa_ssid
*ssid
;
1561 /* cmd: "<network id> <BSSID>" */
1562 pos
= os_strchr(cmd
, ' ');
1567 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: id=%d bssid='%s'", id
, pos
);
1568 if (hwaddr_aton(pos
, bssid
)) {
1569 wpa_printf(MSG_DEBUG
,"CTRL_IFACE: invalid BSSID '%s'", pos
);
1573 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1575 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
1580 os_memcpy(ssid
->bssid
, bssid
, ETH_ALEN
);
1581 ssid
->bssid_set
= !is_zero_ether_addr(bssid
);
1587 static int wpa_supplicant_ctrl_iface_blacklist(struct wpa_supplicant
*wpa_s
,
1588 char *cmd
, char *buf
,
1592 struct wpa_blacklist
*e
;
1596 /* cmd: "BLACKLIST [<BSSID>]" */
1600 e
= wpa_s
->blacklist
;
1602 ret
= os_snprintf(pos
, end
- pos
, MACSTR
"\n",
1604 if (ret
< 0 || ret
>= end
- pos
)
1613 if (os_strncmp(cmd
, "clear", 5) == 0) {
1614 wpa_blacklist_clear(wpa_s
);
1615 os_memcpy(buf
, "OK\n", 3);
1619 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: BLACKLIST bssid='%s'", cmd
);
1620 if (hwaddr_aton(cmd
, bssid
)) {
1621 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: invalid BSSID '%s'", cmd
);
1626 * Add the BSSID twice, so its count will be 2, causing it to be
1627 * skipped when processing scan results.
1629 ret
= wpa_blacklist_add(wpa_s
, bssid
);
1632 ret
= wpa_blacklist_add(wpa_s
, bssid
);
1635 os_memcpy(buf
, "OK\n", 3);
1640 extern int wpa_debug_level
;
1641 extern int wpa_debug_timestamp
;
1643 static const char * debug_level_str(int level
)
1664 static int str_to_debug_level(const char *s
)
1666 if (os_strcasecmp(s
, "EXCESSIVE") == 0)
1667 return MSG_EXCESSIVE
;
1668 if (os_strcasecmp(s
, "MSGDUMP") == 0)
1670 if (os_strcasecmp(s
, "DEBUG") == 0)
1672 if (os_strcasecmp(s
, "INFO") == 0)
1674 if (os_strcasecmp(s
, "WARNING") == 0)
1676 if (os_strcasecmp(s
, "ERROR") == 0)
1682 static int wpa_supplicant_ctrl_iface_log_level(struct wpa_supplicant
*wpa_s
,
1683 char *cmd
, char *buf
,
1686 char *pos
, *end
, *stamp
;
1693 /* cmd: "LOG_LEVEL [<level>]" */
1697 ret
= os_snprintf(pos
, end
- pos
, "Current level: %s\n"
1699 debug_level_str(wpa_debug_level
),
1700 wpa_debug_timestamp
);
1701 if (ret
< 0 || ret
>= end
- pos
)
1710 stamp
= os_strchr(cmd
, ' ');
1713 while (*stamp
== ' ') {
1718 if (cmd
&& os_strlen(cmd
)) {
1719 int level
= str_to_debug_level(cmd
);
1722 wpa_debug_level
= level
;
1725 if (stamp
&& os_strlen(stamp
))
1726 wpa_debug_timestamp
= atoi(stamp
);
1728 os_memcpy(buf
, "OK\n", 3);
1733 static int wpa_supplicant_ctrl_iface_list_networks(
1734 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
1737 struct wpa_ssid
*ssid
;
1742 ret
= os_snprintf(pos
, end
- pos
,
1743 "network id / ssid / bssid / flags\n");
1744 if (ret
< 0 || ret
>= end
- pos
)
1748 ssid
= wpa_s
->conf
->ssid
;
1750 ret
= os_snprintf(pos
, end
- pos
, "%d\t%s",
1752 wpa_ssid_txt(ssid
->ssid
, ssid
->ssid_len
));
1753 if (ret
< 0 || ret
>= end
- pos
)
1756 if (ssid
->bssid_set
) {
1757 ret
= os_snprintf(pos
, end
- pos
, "\t" MACSTR
,
1758 MAC2STR(ssid
->bssid
));
1760 ret
= os_snprintf(pos
, end
- pos
, "\tany");
1762 if (ret
< 0 || ret
>= end
- pos
)
1765 ret
= os_snprintf(pos
, end
- pos
, "\t%s%s%s%s",
1766 ssid
== wpa_s
->current_ssid
?
1768 ssid
->disabled
? "[DISABLED]" : "",
1769 ssid
->disabled_until
.sec
?
1770 "[TEMP-DISABLED]" : "",
1771 ssid
->disabled
== 2 ? "[P2P-PERSISTENT]" :
1773 if (ret
< 0 || ret
>= end
- pos
)
1776 ret
= os_snprintf(pos
, end
- pos
, "\n");
1777 if (ret
< 0 || ret
>= end
- pos
)
1788 static char * wpa_supplicant_cipher_txt(char *pos
, char *end
, int cipher
)
1791 ret
= os_snprintf(pos
, end
- pos
, "-");
1792 if (ret
< 0 || ret
>= end
- pos
)
1795 ret
= wpa_write_ciphers(pos
, end
, cipher
, "+");
1803 static char * wpa_supplicant_ie_txt(char *pos
, char *end
, const char *proto
,
1804 const u8
*ie
, size_t ie_len
)
1806 struct wpa_ie_data data
;
1809 ret
= os_snprintf(pos
, end
- pos
, "[%s-", proto
);
1810 if (ret
< 0 || ret
>= end
- pos
)
1814 if (wpa_parse_wpa_ie(ie
, ie_len
, &data
) < 0) {
1815 ret
= os_snprintf(pos
, end
- pos
, "?]");
1816 if (ret
< 0 || ret
>= end
- pos
)
1823 if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X
) {
1824 ret
= os_snprintf(pos
, end
- pos
, "%sEAP", first
? "" : "+");
1825 if (ret
< 0 || ret
>= end
- pos
)
1830 if (data
.key_mgmt
& WPA_KEY_MGMT_PSK
) {
1831 ret
= os_snprintf(pos
, end
- pos
, "%sPSK", first
? "" : "+");
1832 if (ret
< 0 || ret
>= end
- pos
)
1837 if (data
.key_mgmt
& WPA_KEY_MGMT_WPA_NONE
) {
1838 ret
= os_snprintf(pos
, end
- pos
, "%sNone", first
? "" : "+");
1839 if (ret
< 0 || ret
>= end
- pos
)
1844 #ifdef CONFIG_IEEE80211R
1845 if (data
.key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
) {
1846 ret
= os_snprintf(pos
, end
- pos
, "%sFT/EAP",
1848 if (ret
< 0 || ret
>= end
- pos
)
1853 if (data
.key_mgmt
& WPA_KEY_MGMT_FT_PSK
) {
1854 ret
= os_snprintf(pos
, end
- pos
, "%sFT/PSK",
1856 if (ret
< 0 || ret
>= end
- pos
)
1861 #endif /* CONFIG_IEEE80211R */
1862 #ifdef CONFIG_IEEE80211W
1863 if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
) {
1864 ret
= os_snprintf(pos
, end
- pos
, "%sEAP-SHA256",
1866 if (ret
< 0 || ret
>= end
- pos
)
1871 if (data
.key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
) {
1872 ret
= os_snprintf(pos
, end
- pos
, "%sPSK-SHA256",
1874 if (ret
< 0 || ret
>= end
- pos
)
1879 #endif /* CONFIG_IEEE80211W */
1881 pos
= wpa_supplicant_cipher_txt(pos
, end
, data
.pairwise_cipher
);
1883 if (data
.capabilities
& WPA_CAPABILITY_PREAUTH
) {
1884 ret
= os_snprintf(pos
, end
- pos
, "-preauth");
1885 if (ret
< 0 || ret
>= end
- pos
)
1890 ret
= os_snprintf(pos
, end
- pos
, "]");
1891 if (ret
< 0 || ret
>= end
- pos
)
1900 static char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant
*wpa_s
,
1901 char *pos
, char *end
,
1902 struct wpabuf
*wps_ie
)
1909 if (wps_is_selected_pbc_registrar(wps_ie
))
1912 else if (wps_is_addr_authorized(wps_ie
, wpa_s
->own_addr
, 0))
1914 #endif /* CONFIG_WPS2 */
1915 else if (wps_is_selected_pin_registrar(wps_ie
))
1920 ret
= os_snprintf(pos
, end
- pos
, "%s", txt
);
1921 if (ret
>= 0 && ret
< end
- pos
)
1923 wpabuf_free(wps_ie
);
1926 #endif /* CONFIG_WPS */
1929 static char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant
*wpa_s
,
1930 char *pos
, char *end
,
1931 const struct wpa_bss
*bss
)
1934 struct wpabuf
*wps_ie
;
1935 wps_ie
= wpa_bss_get_vendor_ie_multi(bss
, WPS_IE_VENDOR_TYPE
);
1936 return wpa_supplicant_wps_ie_txt_buf(wpa_s
, pos
, end
, wps_ie
);
1937 #else /* CONFIG_WPS */
1939 #endif /* CONFIG_WPS */
1943 /* Format one result on one text line into a buffer. */
1944 static int wpa_supplicant_ctrl_iface_scan_result(
1945 struct wpa_supplicant
*wpa_s
,
1946 const struct wpa_bss
*bss
, char *buf
, size_t buflen
)
1950 const u8
*ie
, *ie2
, *p2p
;
1952 p2p
= wpa_bss_get_vendor_ie(bss
, P2P_IE_VENDOR_TYPE
);
1953 if (p2p
&& bss
->ssid_len
== P2P_WILDCARD_SSID_LEN
&&
1954 os_memcmp(bss
->ssid
, P2P_WILDCARD_SSID
, P2P_WILDCARD_SSID_LEN
) ==
1956 return 0; /* Do not show P2P listen discovery results here */
1961 ret
= os_snprintf(pos
, end
- pos
, MACSTR
"\t%d\t%d\t",
1962 MAC2STR(bss
->bssid
), bss
->freq
, bss
->level
);
1963 if (ret
< 0 || ret
>= end
- pos
)
1966 ie
= wpa_bss_get_vendor_ie(bss
, WPA_IE_VENDOR_TYPE
);
1968 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA", ie
, 2 + ie
[1]);
1969 ie2
= wpa_bss_get_ie(bss
, WLAN_EID_RSN
);
1971 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA2", ie2
, 2 + ie2
[1]);
1972 pos
= wpa_supplicant_wps_ie_txt(wpa_s
, pos
, end
, bss
);
1973 if (!ie
&& !ie2
&& bss
->caps
& IEEE80211_CAP_PRIVACY
) {
1974 ret
= os_snprintf(pos
, end
- pos
, "[WEP]");
1975 if (ret
< 0 || ret
>= end
- pos
)
1979 if (bss
->caps
& IEEE80211_CAP_IBSS
) {
1980 ret
= os_snprintf(pos
, end
- pos
, "[IBSS]");
1981 if (ret
< 0 || ret
>= end
- pos
)
1985 if (bss
->caps
& IEEE80211_CAP_ESS
) {
1986 ret
= os_snprintf(pos
, end
- pos
, "[ESS]");
1987 if (ret
< 0 || ret
>= end
- pos
)
1992 ret
= os_snprintf(pos
, end
- pos
, "[P2P]");
1993 if (ret
< 0 || ret
>= end
- pos
)
1998 if (wpa_bss_get_vendor_ie(bss
, HS20_IE_VENDOR_TYPE
) && ie2
) {
1999 ret
= os_snprintf(pos
, end
- pos
, "[HS20]");
2000 if (ret
< 0 || ret
>= end
- pos
)
2004 #endif /* CONFIG_HS20 */
2006 ret
= os_snprintf(pos
, end
- pos
, "\t%s",
2007 wpa_ssid_txt(bss
->ssid
, bss
->ssid_len
));
2008 if (ret
< 0 || ret
>= end
- pos
)
2012 ret
= os_snprintf(pos
, end
- pos
, "\n");
2013 if (ret
< 0 || ret
>= end
- pos
)
2021 static int wpa_supplicant_ctrl_iface_scan_results(
2022 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
2025 struct wpa_bss
*bss
;
2030 ret
= os_snprintf(pos
, end
- pos
, "bssid / frequency / signal level / "
2032 if (ret
< 0 || ret
>= end
- pos
)
2036 dl_list_for_each(bss
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
) {
2037 ret
= wpa_supplicant_ctrl_iface_scan_result(wpa_s
, bss
, pos
,
2039 if (ret
< 0 || ret
>= end
- pos
)
2048 static int wpa_supplicant_ctrl_iface_select_network(
2049 struct wpa_supplicant
*wpa_s
, char *cmd
)
2052 struct wpa_ssid
*ssid
;
2054 /* cmd: "<network id>" or "any" */
2055 if (os_strcmp(cmd
, "any") == 0) {
2056 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SELECT_NETWORK any");
2060 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SELECT_NETWORK id=%d", id
);
2062 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
2064 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
2065 "network id=%d", id
);
2068 if (ssid
->disabled
== 2) {
2069 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Cannot use "
2070 "SELECT_NETWORK with persistent P2P group");
2075 wpa_supplicant_select_network(wpa_s
, ssid
);
2081 static int wpa_supplicant_ctrl_iface_enable_network(
2082 struct wpa_supplicant
*wpa_s
, char *cmd
)
2085 struct wpa_ssid
*ssid
;
2087 /* cmd: "<network id>" or "all" */
2088 if (os_strcmp(cmd
, "all") == 0) {
2089 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ENABLE_NETWORK all");
2093 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ENABLE_NETWORK id=%d", id
);
2095 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
2097 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
2098 "network id=%d", id
);
2101 if (ssid
->disabled
== 2) {
2102 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Cannot use "
2103 "ENABLE_NETWORK with persistent P2P group");
2107 if (os_strstr(cmd
, " no-connect")) {
2112 wpa_supplicant_enable_network(wpa_s
, ssid
);
2118 static int wpa_supplicant_ctrl_iface_disable_network(
2119 struct wpa_supplicant
*wpa_s
, char *cmd
)
2122 struct wpa_ssid
*ssid
;
2124 /* cmd: "<network id>" or "all" */
2125 if (os_strcmp(cmd
, "all") == 0) {
2126 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: DISABLE_NETWORK all");
2130 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: DISABLE_NETWORK id=%d", id
);
2132 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
2134 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
2135 "network id=%d", id
);
2138 if (ssid
->disabled
== 2) {
2139 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Cannot use "
2140 "DISABLE_NETWORK with persistent P2P "
2145 wpa_supplicant_disable_network(wpa_s
, ssid
);
2151 static int wpa_supplicant_ctrl_iface_add_network(
2152 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
2154 struct wpa_ssid
*ssid
;
2157 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ADD_NETWORK");
2159 ssid
= wpa_config_add_network(wpa_s
->conf
);
2163 wpas_notify_network_added(wpa_s
, ssid
);
2166 wpa_config_set_network_defaults(ssid
);
2168 ret
= os_snprintf(buf
, buflen
, "%d\n", ssid
->id
);
2169 if (ret
< 0 || (size_t) ret
>= buflen
)
2175 static int wpa_supplicant_ctrl_iface_remove_network(
2176 struct wpa_supplicant
*wpa_s
, char *cmd
)
2179 struct wpa_ssid
*ssid
;
2181 /* cmd: "<network id>" or "all" */
2182 if (os_strcmp(cmd
, "all") == 0) {
2183 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_NETWORK all");
2184 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
2185 if (wpa_s
->current_ssid
) {
2187 wpa_s
->sme
.prev_bssid_set
= 0;
2188 #endif /* CONFIG_SME */
2189 wpa_sm_set_config(wpa_s
->wpa
, NULL
);
2190 eapol_sm_notify_config(wpa_s
->eapol
, NULL
, NULL
);
2191 wpa_supplicant_deauthenticate(
2192 wpa_s
, WLAN_REASON_DEAUTH_LEAVING
);
2194 ssid
= wpa_s
->conf
->ssid
;
2196 struct wpa_ssid
*remove_ssid
= ssid
;
2199 wpas_notify_network_removed(wpa_s
, remove_ssid
);
2200 wpa_config_remove_network(wpa_s
->conf
, id
);
2206 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_NETWORK id=%d", id
);
2208 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
2210 wpas_notify_network_removed(wpa_s
, ssid
);
2212 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
2217 if (ssid
== wpa_s
->current_ssid
|| wpa_s
->current_ssid
== NULL
) {
2219 wpa_s
->sme
.prev_bssid_set
= 0;
2220 #endif /* CONFIG_SME */
2222 * Invalidate the EAP session cache if the current or
2223 * previously used network is removed.
2225 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
2228 if (ssid
== wpa_s
->current_ssid
) {
2229 wpa_sm_set_config(wpa_s
->wpa
, NULL
);
2230 eapol_sm_notify_config(wpa_s
->eapol
, NULL
, NULL
);
2232 wpa_supplicant_deauthenticate(wpa_s
,
2233 WLAN_REASON_DEAUTH_LEAVING
);
2236 if (wpa_config_remove_network(wpa_s
->conf
, id
) < 0) {
2237 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Not able to remove the "
2238 "network id=%d", id
);
2246 static int wpa_supplicant_ctrl_iface_set_network(
2247 struct wpa_supplicant
*wpa_s
, char *cmd
)
2250 struct wpa_ssid
*ssid
;
2253 /* cmd: "<network id> <variable name> <value>" */
2254 name
= os_strchr(cmd
, ' ');
2259 value
= os_strchr(name
, ' ');
2265 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
2267 wpa_hexdump_ascii_key(MSG_DEBUG
, "CTRL_IFACE: value",
2268 (u8
*) value
, os_strlen(value
));
2270 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
2272 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
2277 if (wpa_config_set(ssid
, name
, value
, 0) < 0) {
2278 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Failed to set network "
2279 "variable '%s'", name
);
2283 if (os_strcmp(name
, "bssid") != 0 &&
2284 os_strcmp(name
, "priority") != 0)
2285 wpa_sm_pmksa_cache_flush(wpa_s
->wpa
, ssid
);
2287 if (wpa_s
->current_ssid
== ssid
|| wpa_s
->current_ssid
== NULL
) {
2289 * Invalidate the EAP session cache if anything in the current
2290 * or previously used configuration changes.
2292 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
2295 if ((os_strcmp(name
, "psk") == 0 &&
2296 value
[0] == '"' && ssid
->ssid_len
) ||
2297 (os_strcmp(name
, "ssid") == 0 && ssid
->passphrase
))
2298 wpa_config_update_psk(ssid
);
2299 else if (os_strcmp(name
, "priority") == 0)
2300 wpa_config_update_prio_list(wpa_s
->conf
);
2306 static int wpa_supplicant_ctrl_iface_get_network(
2307 struct wpa_supplicant
*wpa_s
, char *cmd
, char *buf
, size_t buflen
)
2311 struct wpa_ssid
*ssid
;
2314 /* cmd: "<network id> <variable name>" */
2315 name
= os_strchr(cmd
, ' ');
2316 if (name
== NULL
|| buflen
== 0)
2321 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
2324 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
2326 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
2331 value
= wpa_config_get_no_key(ssid
, name
);
2332 if (value
== NULL
) {
2333 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Failed to get network "
2334 "variable '%s'", name
);
2338 res
= os_strlcpy(buf
, value
, buflen
);
2339 if (res
>= buflen
) {
2350 static int wpa_supplicant_ctrl_iface_list_creds(struct wpa_supplicant
*wpa_s
,
2351 char *buf
, size_t buflen
)
2354 struct wpa_cred
*cred
;
2359 ret
= os_snprintf(pos
, end
- pos
,
2360 "cred id / realm / username / domain / imsi\n");
2361 if (ret
< 0 || ret
>= end
- pos
)
2365 cred
= wpa_s
->conf
->cred
;
2367 ret
= os_snprintf(pos
, end
- pos
, "%d\t%s\t%s\t%s\t%s\n",
2368 cred
->id
, cred
->realm
? cred
->realm
: "",
2369 cred
->username
? cred
->username
: "",
2370 cred
->domain
? cred
->domain
: "",
2371 cred
->imsi
? cred
->imsi
: "");
2372 if (ret
< 0 || ret
>= end
- pos
)
2383 static int wpa_supplicant_ctrl_iface_add_cred(struct wpa_supplicant
*wpa_s
,
2384 char *buf
, size_t buflen
)
2386 struct wpa_cred
*cred
;
2389 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ADD_CRED");
2391 cred
= wpa_config_add_cred(wpa_s
->conf
);
2395 ret
= os_snprintf(buf
, buflen
, "%d\n", cred
->id
);
2396 if (ret
< 0 || (size_t) ret
>= buflen
)
2402 static int wpas_ctrl_remove_cred(struct wpa_supplicant
*wpa_s
,
2403 struct wpa_cred
*cred
)
2405 struct wpa_ssid
*ssid
;
2408 if (cred
== NULL
|| wpa_config_remove_cred(wpa_s
->conf
, cred
->id
) < 0) {
2409 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find cred");
2413 /* Remove any network entry created based on the removed credential */
2414 ssid
= wpa_s
->conf
->ssid
;
2416 if (ssid
->parent_cred
== cred
) {
2417 wpa_printf(MSG_DEBUG
, "Remove network id %d since it "
2418 "used the removed credential", ssid
->id
);
2419 os_snprintf(str
, sizeof(str
), "%d", ssid
->id
);
2421 wpa_supplicant_ctrl_iface_remove_network(wpa_s
, str
);
2430 static int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant
*wpa_s
,
2434 struct wpa_cred
*cred
, *prev
;
2436 /* cmd: "<cred id>", "all", or "sp_fqdn=<FQDN>" */
2437 if (os_strcmp(cmd
, "all") == 0) {
2438 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_CRED all");
2439 cred
= wpa_s
->conf
->cred
;
2443 wpas_ctrl_remove_cred(wpa_s
, prev
);
2448 if (os_strncmp(cmd
, "sp_fqdn=", 8) == 0) {
2449 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_CRED SP FQDN '%s'",
2451 cred
= wpa_s
->conf
->cred
;
2456 os_strcmp(prev
->domain
, cmd
+ 8) == 0)
2457 wpas_ctrl_remove_cred(wpa_s
, prev
);
2463 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_CRED id=%d", id
);
2465 cred
= wpa_config_get_cred(wpa_s
->conf
, id
);
2466 return wpas_ctrl_remove_cred(wpa_s
, cred
);
2470 static int wpa_supplicant_ctrl_iface_set_cred(struct wpa_supplicant
*wpa_s
,
2474 struct wpa_cred
*cred
;
2477 /* cmd: "<cred id> <variable name> <value>" */
2478 name
= os_strchr(cmd
, ' ');
2483 value
= os_strchr(name
, ' ');
2489 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SET_CRED id=%d name='%s'",
2491 wpa_hexdump_ascii_key(MSG_DEBUG
, "CTRL_IFACE: value",
2492 (u8
*) value
, os_strlen(value
));
2494 cred
= wpa_config_get_cred(wpa_s
->conf
, id
);
2496 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find cred id=%d",
2501 if (wpa_config_set_cred(cred
, name
, value
, 0) < 0) {
2502 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Failed to set cred "
2503 "variable '%s'", name
);
2511 #ifndef CONFIG_NO_CONFIG_WRITE
2512 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant
*wpa_s
)
2516 if (!wpa_s
->conf
->update_config
) {
2517 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
2518 "to update configuration (update_config=0)");
2522 ret
= wpa_config_write(wpa_s
->confname
, wpa_s
->conf
);
2524 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Failed to "
2525 "update configuration");
2527 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Configuration"
2533 #endif /* CONFIG_NO_CONFIG_WRITE */
2536 static int ctrl_iface_get_capability_pairwise(int res
, char *strict
,
2537 struct wpa_driver_capa
*capa
,
2538 char *buf
, size_t buflen
)
2550 len
= os_strlcpy(buf
, "CCMP TKIP NONE", buflen
);
2556 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
2557 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : " ");
2558 if (ret
< 0 || ret
>= end
- pos
)
2564 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_GCMP
) {
2565 ret
= os_snprintf(pos
, end
- pos
, "%sGCMP", first
? "" : " ");
2566 if (ret
< 0 || ret
>= end
- pos
)
2572 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
2573 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : " ");
2574 if (ret
< 0 || ret
>= end
- pos
)
2580 if (capa
->key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
2581 ret
= os_snprintf(pos
, end
- pos
, "%sNONE", first
? "" : " ");
2582 if (ret
< 0 || ret
>= end
- pos
)
2592 static int ctrl_iface_get_capability_group(int res
, char *strict
,
2593 struct wpa_driver_capa
*capa
,
2594 char *buf
, size_t buflen
)
2606 len
= os_strlcpy(buf
, "CCMP TKIP WEP104 WEP40", buflen
);
2612 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
2613 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : " ");
2614 if (ret
< 0 || ret
>= end
- pos
)
2620 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_GCMP
) {
2621 ret
= os_snprintf(pos
, end
- pos
, "%sGCMP", first
? "" : " ");
2622 if (ret
< 0 || ret
>= end
- pos
)
2628 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
2629 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : " ");
2630 if (ret
< 0 || ret
>= end
- pos
)
2636 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_WEP104
) {
2637 ret
= os_snprintf(pos
, end
- pos
, "%sWEP104",
2639 if (ret
< 0 || ret
>= end
- pos
)
2645 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_WEP40
) {
2646 ret
= os_snprintf(pos
, end
- pos
, "%sWEP40", first
? "" : " ");
2647 if (ret
< 0 || ret
>= end
- pos
)
2657 static int ctrl_iface_get_capability_key_mgmt(int res
, char *strict
,
2658 struct wpa_driver_capa
*capa
,
2659 char *buf
, size_t buflen
)
2671 len
= os_strlcpy(buf
, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE "
2678 ret
= os_snprintf(pos
, end
- pos
, "NONE IEEE8021X");
2679 if (ret
< 0 || ret
>= end
- pos
)
2683 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
2684 WPA_DRIVER_CAPA_KEY_MGMT_WPA2
)) {
2685 ret
= os_snprintf(pos
, end
- pos
, " WPA-EAP");
2686 if (ret
< 0 || ret
>= end
- pos
)
2691 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
|
2692 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
2693 ret
= os_snprintf(pos
, end
- pos
, " WPA-PSK");
2694 if (ret
< 0 || ret
>= end
- pos
)
2699 if (capa
->key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
2700 ret
= os_snprintf(pos
, end
- pos
, " WPA-NONE");
2701 if (ret
< 0 || ret
>= end
- pos
)
2710 static int ctrl_iface_get_capability_proto(int res
, char *strict
,
2711 struct wpa_driver_capa
*capa
,
2712 char *buf
, size_t buflen
)
2724 len
= os_strlcpy(buf
, "RSN WPA", buflen
);
2730 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA2
|
2731 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
2732 ret
= os_snprintf(pos
, end
- pos
, "%sRSN", first
? "" : " ");
2733 if (ret
< 0 || ret
>= end
- pos
)
2739 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
2740 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
)) {
2741 ret
= os_snprintf(pos
, end
- pos
, "%sWPA", first
? "" : " ");
2742 if (ret
< 0 || ret
>= end
- pos
)
2752 static int ctrl_iface_get_capability_auth_alg(int res
, char *strict
,
2753 struct wpa_driver_capa
*capa
,
2754 char *buf
, size_t buflen
)
2766 len
= os_strlcpy(buf
, "OPEN SHARED LEAP", buflen
);
2772 if (capa
->auth
& (WPA_DRIVER_AUTH_OPEN
)) {
2773 ret
= os_snprintf(pos
, end
- pos
, "%sOPEN", first
? "" : " ");
2774 if (ret
< 0 || ret
>= end
- pos
)
2780 if (capa
->auth
& (WPA_DRIVER_AUTH_SHARED
)) {
2781 ret
= os_snprintf(pos
, end
- pos
, "%sSHARED",
2783 if (ret
< 0 || ret
>= end
- pos
)
2789 if (capa
->auth
& (WPA_DRIVER_AUTH_LEAP
)) {
2790 ret
= os_snprintf(pos
, end
- pos
, "%sLEAP", first
? "" : " ");
2791 if (ret
< 0 || ret
>= end
- pos
)
2801 static int ctrl_iface_get_capability_channels(struct wpa_supplicant
*wpa_s
,
2802 char *buf
, size_t buflen
)
2804 struct hostapd_channel_data
*chnl
;
2806 char *pos
, *end
, *hmode
;
2811 for (j
= 0; j
< wpa_s
->hw
.num_modes
; j
++) {
2812 switch (wpa_s
->hw
.modes
[j
].mode
) {
2813 case HOSTAPD_MODE_IEEE80211B
:
2816 case HOSTAPD_MODE_IEEE80211G
:
2819 case HOSTAPD_MODE_IEEE80211A
:
2822 case HOSTAPD_MODE_IEEE80211AD
:
2828 ret
= os_snprintf(pos
, end
- pos
, "Mode[%s] Channels:", hmode
);
2829 if (ret
< 0 || ret
>= end
- pos
)
2832 chnl
= wpa_s
->hw
.modes
[j
].channels
;
2833 for (i
= 0; i
< wpa_s
->hw
.modes
[j
].num_channels
; i
++) {
2834 if (chnl
[i
].flag
& HOSTAPD_CHAN_DISABLED
)
2836 ret
= os_snprintf(pos
, end
- pos
, " %d", chnl
[i
].chan
);
2837 if (ret
< 0 || ret
>= end
- pos
)
2841 ret
= os_snprintf(pos
, end
- pos
, "\n");
2842 if (ret
< 0 || ret
>= end
- pos
)
2851 static int wpa_supplicant_ctrl_iface_get_capability(
2852 struct wpa_supplicant
*wpa_s
, const char *_field
, char *buf
,
2855 struct wpa_driver_capa capa
;
2861 /* Determine whether or not strict checking was requested */
2862 len
= os_strlcpy(field
, _field
, sizeof(field
));
2863 if (len
>= sizeof(field
))
2865 strict
= os_strchr(field
, ' ');
2866 if (strict
!= NULL
) {
2868 if (os_strcmp(strict
, "strict") != 0)
2872 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
2873 field
, strict
? strict
: "");
2875 if (os_strcmp(field
, "eap") == 0) {
2876 return eap_get_names(buf
, buflen
);
2879 res
= wpa_drv_get_capa(wpa_s
, &capa
);
2881 if (os_strcmp(field
, "pairwise") == 0)
2882 return ctrl_iface_get_capability_pairwise(res
, strict
, &capa
,
2885 if (os_strcmp(field
, "group") == 0)
2886 return ctrl_iface_get_capability_group(res
, strict
, &capa
,
2889 if (os_strcmp(field
, "key_mgmt") == 0)
2890 return ctrl_iface_get_capability_key_mgmt(res
, strict
, &capa
,
2893 if (os_strcmp(field
, "proto") == 0)
2894 return ctrl_iface_get_capability_proto(res
, strict
, &capa
,
2897 if (os_strcmp(field
, "auth_alg") == 0)
2898 return ctrl_iface_get_capability_auth_alg(res
, strict
, &capa
,
2901 if (os_strcmp(field
, "channels") == 0)
2902 return ctrl_iface_get_capability_channels(wpa_s
, buf
, buflen
);
2904 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
2911 #ifdef CONFIG_INTERWORKING
2912 static char * anqp_add_hex(char *pos
, char *end
, const char *title
,
2913 struct wpabuf
*data
)
2923 ret
= os_snprintf(pos
, end
- pos
, "%s=", title
);
2924 if (ret
< 0 || ret
>= end
- pos
)
2928 d
= wpabuf_head_u8(data
);
2929 for (i
= 0; i
< wpabuf_len(data
); i
++) {
2930 ret
= os_snprintf(pos
, end
- pos
, "%02x", *d
++);
2931 if (ret
< 0 || ret
>= end
- pos
)
2936 ret
= os_snprintf(pos
, end
- pos
, "\n");
2937 if (ret
< 0 || ret
>= end
- pos
)
2943 #endif /* CONFIG_INTERWORKING */
2946 static int print_bss_info(struct wpa_supplicant
*wpa_s
, struct wpa_bss
*bss
,
2947 unsigned long mask
, char *buf
, size_t buflen
)
2957 if (mask
& WPA_BSS_MASK_ID
) {
2958 ret
= os_snprintf(pos
, end
- pos
, "id=%u\n", bss
->id
);
2959 if (ret
< 0 || ret
>= end
- pos
)
2964 if (mask
& WPA_BSS_MASK_BSSID
) {
2965 ret
= os_snprintf(pos
, end
- pos
, "bssid=" MACSTR
"\n",
2966 MAC2STR(bss
->bssid
));
2967 if (ret
< 0 || ret
>= end
- pos
)
2972 if (mask
& WPA_BSS_MASK_FREQ
) {
2973 ret
= os_snprintf(pos
, end
- pos
, "freq=%d\n", bss
->freq
);
2974 if (ret
< 0 || ret
>= end
- pos
)
2979 if (mask
& WPA_BSS_MASK_BEACON_INT
) {
2980 ret
= os_snprintf(pos
, end
- pos
, "beacon_int=%d\n",
2982 if (ret
< 0 || ret
>= end
- pos
)
2987 if (mask
& WPA_BSS_MASK_CAPABILITIES
) {
2988 ret
= os_snprintf(pos
, end
- pos
, "capabilities=0x%04x\n",
2990 if (ret
< 0 || ret
>= end
- pos
)
2995 if (mask
& WPA_BSS_MASK_QUAL
) {
2996 ret
= os_snprintf(pos
, end
- pos
, "qual=%d\n", bss
->qual
);
2997 if (ret
< 0 || ret
>= end
- pos
)
3002 if (mask
& WPA_BSS_MASK_NOISE
) {
3003 ret
= os_snprintf(pos
, end
- pos
, "noise=%d\n", bss
->noise
);
3004 if (ret
< 0 || ret
>= end
- pos
)
3009 if (mask
& WPA_BSS_MASK_LEVEL
) {
3010 ret
= os_snprintf(pos
, end
- pos
, "level=%d\n", bss
->level
);
3011 if (ret
< 0 || ret
>= end
- pos
)
3016 if (mask
& WPA_BSS_MASK_TSF
) {
3017 ret
= os_snprintf(pos
, end
- pos
, "tsf=%016llu\n",
3018 (unsigned long long) bss
->tsf
);
3019 if (ret
< 0 || ret
>= end
- pos
)
3024 if (mask
& WPA_BSS_MASK_AGE
) {
3028 ret
= os_snprintf(pos
, end
- pos
, "age=%d\n",
3029 (int) (now
.sec
- bss
->last_update
.sec
));
3030 if (ret
< 0 || ret
>= end
- pos
)
3035 if (mask
& WPA_BSS_MASK_IE
) {
3036 ret
= os_snprintf(pos
, end
- pos
, "ie=");
3037 if (ret
< 0 || ret
>= end
- pos
)
3041 ie
= (const u8
*) (bss
+ 1);
3042 for (i
= 0; i
< bss
->ie_len
; i
++) {
3043 ret
= os_snprintf(pos
, end
- pos
, "%02x", *ie
++);
3044 if (ret
< 0 || ret
>= end
- pos
)
3049 ret
= os_snprintf(pos
, end
- pos
, "\n");
3050 if (ret
< 0 || ret
>= end
- pos
)
3055 if (mask
& WPA_BSS_MASK_FLAGS
) {
3056 ret
= os_snprintf(pos
, end
- pos
, "flags=");
3057 if (ret
< 0 || ret
>= end
- pos
)
3061 ie
= wpa_bss_get_vendor_ie(bss
, WPA_IE_VENDOR_TYPE
);
3063 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA", ie
,
3065 ie2
= wpa_bss_get_ie(bss
, WLAN_EID_RSN
);
3067 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA2", ie2
,
3069 pos
= wpa_supplicant_wps_ie_txt(wpa_s
, pos
, end
, bss
);
3070 if (!ie
&& !ie2
&& bss
->caps
& IEEE80211_CAP_PRIVACY
) {
3071 ret
= os_snprintf(pos
, end
- pos
, "[WEP]");
3072 if (ret
< 0 || ret
>= end
- pos
)
3076 if (bss
->caps
& IEEE80211_CAP_IBSS
) {
3077 ret
= os_snprintf(pos
, end
- pos
, "[IBSS]");
3078 if (ret
< 0 || ret
>= end
- pos
)
3082 if (bss
->caps
& IEEE80211_CAP_ESS
) {
3083 ret
= os_snprintf(pos
, end
- pos
, "[ESS]");
3084 if (ret
< 0 || ret
>= end
- pos
)
3088 if (wpa_bss_get_vendor_ie(bss
, P2P_IE_VENDOR_TYPE
)) {
3089 ret
= os_snprintf(pos
, end
- pos
, "[P2P]");
3090 if (ret
< 0 || ret
>= end
- pos
)
3095 if (wpa_bss_get_vendor_ie(bss
, HS20_IE_VENDOR_TYPE
)) {
3096 ret
= os_snprintf(pos
, end
- pos
, "[HS20]");
3097 if (ret
< 0 || ret
>= end
- pos
)
3101 #endif /* CONFIG_HS20 */
3103 ret
= os_snprintf(pos
, end
- pos
, "\n");
3104 if (ret
< 0 || ret
>= end
- pos
)
3109 if (mask
& WPA_BSS_MASK_SSID
) {
3110 ret
= os_snprintf(pos
, end
- pos
, "ssid=%s\n",
3111 wpa_ssid_txt(bss
->ssid
, bss
->ssid_len
));
3112 if (ret
< 0 || ret
>= end
- pos
)
3118 if (mask
& WPA_BSS_MASK_WPS_SCAN
) {
3119 ie
= (const u8
*) (bss
+ 1);
3120 ret
= wpas_wps_scan_result_text(ie
, bss
->ie_len
, pos
, end
);
3121 if (ret
< 0 || ret
>= end
- pos
)
3125 #endif /* CONFIG_WPS */
3128 if (mask
& WPA_BSS_MASK_P2P_SCAN
) {
3129 ie
= (const u8
*) (bss
+ 1);
3130 ret
= wpas_p2p_scan_result_text(ie
, bss
->ie_len
, pos
, end
);
3131 if (ret
< 0 || ret
>= end
- pos
)
3135 #endif /* CONFIG_P2P */
3137 #ifdef CONFIG_WIFI_DISPLAY
3138 if (mask
& WPA_BSS_MASK_WIFI_DISPLAY
) {
3140 ie
= (const u8
*) (bss
+ 1);
3141 wfd
= ieee802_11_vendor_ie_concat(ie
, bss
->ie_len
,
3142 WFD_IE_VENDOR_TYPE
);
3144 ret
= os_snprintf(pos
, end
- pos
, "wfd_subelems=");
3145 if (ret
< 0 || ret
>= end
- pos
)
3149 pos
+= wpa_snprintf_hex(pos
, end
- pos
,
3154 ret
= os_snprintf(pos
, end
- pos
, "\n");
3155 if (ret
< 0 || ret
>= end
- pos
)
3160 #endif /* CONFIG_WIFI_DISPLAY */
3162 #ifdef CONFIG_INTERWORKING
3163 if ((mask
& WPA_BSS_MASK_INTERNETW
) && bss
->anqp
) {
3164 struct wpa_bss_anqp
*anqp
= bss
->anqp
;
3165 pos
= anqp_add_hex(pos
, end
, "anqp_venue_name",
3167 pos
= anqp_add_hex(pos
, end
, "anqp_network_auth_type",
3168 anqp
->network_auth_type
);
3169 pos
= anqp_add_hex(pos
, end
, "anqp_roaming_consortium",
3170 anqp
->roaming_consortium
);
3171 pos
= anqp_add_hex(pos
, end
, "anqp_ip_addr_type_availability",
3172 anqp
->ip_addr_type_availability
);
3173 pos
= anqp_add_hex(pos
, end
, "anqp_nai_realm",
3175 pos
= anqp_add_hex(pos
, end
, "anqp_3gpp", anqp
->anqp_3gpp
);
3176 pos
= anqp_add_hex(pos
, end
, "anqp_domain_name",
3179 pos
= anqp_add_hex(pos
, end
, "hs20_operator_friendly_name",
3180 anqp
->hs20_operator_friendly_name
);
3181 pos
= anqp_add_hex(pos
, end
, "hs20_wan_metrics",
3182 anqp
->hs20_wan_metrics
);
3183 pos
= anqp_add_hex(pos
, end
, "hs20_connection_capability",
3184 anqp
->hs20_connection_capability
);
3185 #endif /* CONFIG_HS20 */
3187 #endif /* CONFIG_INTERWORKING */
3193 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant
*wpa_s
,
3194 const char *cmd
, char *buf
,
3199 struct wpa_bss
*bss
;
3200 struct wpa_bss
*bsslast
= NULL
;
3201 struct dl_list
*next
;
3205 unsigned long mask
= WPA_BSS_MASK_ALL
;
3207 if (os_strncmp(cmd
, "RANGE=", 6) == 0) {
3208 if (os_strncmp(cmd
+ 6, "ALL", 3) == 0) {
3209 bss
= dl_list_first(&wpa_s
->bss_id
, struct wpa_bss
,
3211 bsslast
= dl_list_last(&wpa_s
->bss_id
, struct wpa_bss
,
3213 } else { /* N1-N2 */
3214 unsigned int id1
, id2
;
3216 if ((ctmp
= os_strchr(cmd
+ 6, '-')) == NULL
) {
3217 wpa_printf(MSG_INFO
, "Wrong BSS range "
3222 if (*(cmd
+ 6) == '-')
3225 id1
= atoi(cmd
+ 6);
3227 if (*ctmp
>= '0' && *ctmp
<= '9')
3230 id2
= (unsigned int) -1;
3231 bss
= wpa_bss_get_id_range(wpa_s
, id1
, id2
);
3232 if (id2
== (unsigned int) -1)
3233 bsslast
= dl_list_last(&wpa_s
->bss_id
,
3237 bsslast
= wpa_bss_get_id(wpa_s
, id2
);
3238 if (bsslast
== NULL
&& bss
&& id2
> id1
) {
3239 struct wpa_bss
*tmp
= bss
;
3241 next
= tmp
->list_id
.next
;
3242 if (next
== &wpa_s
->bss_id
)
3244 tmp
= dl_list_entry(
3245 next
, struct wpa_bss
,
3254 } else if (os_strncmp(cmd
, "FIRST", 5) == 0)
3255 bss
= dl_list_first(&wpa_s
->bss_id
, struct wpa_bss
, list_id
);
3256 else if (os_strncmp(cmd
, "LAST", 4) == 0)
3257 bss
= dl_list_last(&wpa_s
->bss_id
, struct wpa_bss
, list_id
);
3258 else if (os_strncmp(cmd
, "ID-", 3) == 0) {
3260 bss
= wpa_bss_get_id(wpa_s
, i
);
3261 } else if (os_strncmp(cmd
, "NEXT-", 5) == 0) {
3263 bss
= wpa_bss_get_id(wpa_s
, i
);
3265 next
= bss
->list_id
.next
;
3266 if (next
== &wpa_s
->bss_id
)
3269 bss
= dl_list_entry(next
, struct wpa_bss
,
3273 } else if (os_strncmp(cmd
, "p2p_dev_addr=", 13) == 0) {
3274 if (hwaddr_aton(cmd
+ 13, bssid
) == 0)
3275 bss
= wpa_bss_get_p2p_dev_addr(wpa_s
, bssid
);
3278 #endif /* CONFIG_P2P */
3279 } else if (hwaddr_aton(cmd
, bssid
) == 0)
3280 bss
= wpa_bss_get_bssid(wpa_s
, bssid
);
3282 struct wpa_bss
*tmp
;
3285 dl_list_for_each(tmp
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
)
3294 if ((ctmp
= os_strstr(cmd
, "MASK=")) != NULL
) {
3295 mask
= strtoul(ctmp
+ 5, NULL
, 0x10);
3297 mask
= WPA_BSS_MASK_ALL
;
3303 if (bsslast
== NULL
)
3306 len
= print_bss_info(wpa_s
, bss
, mask
, buf
, buflen
);
3312 next
= bss
->list_id
.next
;
3313 if (next
== &wpa_s
->bss_id
)
3315 bss
= dl_list_entry(next
, struct wpa_bss
, list_id
);
3316 } while (bss
&& len
);
3322 static int wpa_supplicant_ctrl_iface_ap_scan(
3323 struct wpa_supplicant
*wpa_s
, char *cmd
)
3325 int ap_scan
= atoi(cmd
);
3326 return wpa_supplicant_set_ap_scan(wpa_s
, ap_scan
);
3330 static int wpa_supplicant_ctrl_iface_scan_interval(
3331 struct wpa_supplicant
*wpa_s
, char *cmd
)
3333 int scan_int
= atoi(cmd
);
3334 return wpa_supplicant_set_scan_interval(wpa_s
, scan_int
);
3338 static int wpa_supplicant_ctrl_iface_bss_expire_age(
3339 struct wpa_supplicant
*wpa_s
, char *cmd
)
3341 int expire_age
= atoi(cmd
);
3342 return wpa_supplicant_set_bss_expiration_age(wpa_s
, expire_age
);
3346 static int wpa_supplicant_ctrl_iface_bss_expire_count(
3347 struct wpa_supplicant
*wpa_s
, char *cmd
)
3349 int expire_count
= atoi(cmd
);
3350 return wpa_supplicant_set_bss_expiration_count(wpa_s
, expire_count
);
3354 static int wpa_supplicant_ctrl_iface_bss_flush(
3355 struct wpa_supplicant
*wpa_s
, char *cmd
)
3357 int flush_age
= atoi(cmd
);
3360 wpa_bss_flush(wpa_s
);
3362 wpa_bss_flush_by_age(wpa_s
, flush_age
);
3367 static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant
*wpa_s
)
3369 wpa_printf(MSG_DEBUG
, "Dropping SA without deauthentication");
3370 /* MLME-DELETEKEYS.request */
3371 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, NULL
, 0, 0, NULL
, 0, NULL
, 0);
3372 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, NULL
, 1, 0, NULL
, 0, NULL
, 0);
3373 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, NULL
, 2, 0, NULL
, 0, NULL
, 0);
3374 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, NULL
, 3, 0, NULL
, 0, NULL
, 0);
3375 #ifdef CONFIG_IEEE80211W
3376 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, NULL
, 4, 0, NULL
, 0, NULL
, 0);
3377 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, NULL
, 5, 0, NULL
, 0, NULL
, 0);
3378 #endif /* CONFIG_IEEE80211W */
3380 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, wpa_s
->bssid
, 0, 0, NULL
, 0, NULL
,
3382 /* MLME-SETPROTECTION.request(None) */
3383 wpa_drv_mlme_setprotection(wpa_s
, wpa_s
->bssid
,
3384 MLME_SETPROTECTION_PROTECT_TYPE_NONE
,
3385 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE
);
3386 wpa_sm_drop_sa(wpa_s
->wpa
);
3390 static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant
*wpa_s
,
3393 #ifdef CONFIG_NO_SCAN_PROCESSING
3395 #else /* CONFIG_NO_SCAN_PROCESSING */
3397 struct wpa_bss
*bss
;
3398 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
3400 if (hwaddr_aton(addr
, bssid
)) {
3401 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM: invalid "
3402 "address '%s'", addr
);
3406 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM " MACSTR
, MAC2STR(bssid
));
3408 bss
= wpa_bss_get_bssid(wpa_s
, bssid
);
3410 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM: Target AP not found "
3416 * TODO: Find best network configuration block from configuration to
3417 * allow roaming to other networks
3421 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM: No network "
3422 "configuration known for the target AP");
3426 wpa_s
->reassociate
= 1;
3427 wpa_supplicant_connect(wpa_s
, bss
, ssid
);
3430 #endif /* CONFIG_NO_SCAN_PROCESSING */
3435 static int p2p_ctrl_find(struct wpa_supplicant
*wpa_s
, char *cmd
)
3437 unsigned int timeout
= atoi(cmd
);
3438 enum p2p_discovery_type type
= P2P_FIND_START_WITH_FULL
;
3439 u8 dev_id
[ETH_ALEN
], *_dev_id
= NULL
;
3441 unsigned int search_delay
;
3443 if (os_strstr(cmd
, "type=social"))
3444 type
= P2P_FIND_ONLY_SOCIAL
;
3445 else if (os_strstr(cmd
, "type=progressive"))
3446 type
= P2P_FIND_PROGRESSIVE
;
3448 pos
= os_strstr(cmd
, "dev_id=");
3451 if (hwaddr_aton(pos
, dev_id
))
3456 pos
= os_strstr(cmd
, "delay=");
3459 search_delay
= atoi(pos
);
3461 search_delay
= wpas_p2p_search_delay(wpa_s
);
3463 return wpas_p2p_find(wpa_s
, timeout
, type
, 0, NULL
, _dev_id
,
3468 static int p2p_ctrl_connect(struct wpa_supplicant
*wpa_s
, char *cmd
,
3469 char *buf
, size_t buflen
)
3474 enum p2p_wps_method wps_method
;
3477 int persistent_group
, persistent_id
= -1;
3486 /* <addr> <"pbc" | "pin" | PIN> [label|display|keypad]
3487 * [persistent|persistent=<network id>]
3488 * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] [provdisc]
3491 if (hwaddr_aton(cmd
, addr
))
3499 persistent_group
= os_strstr(pos
, " persistent") != NULL
;
3500 pos2
= os_strstr(pos
, " persistent=");
3502 struct wpa_ssid
*ssid
;
3503 persistent_id
= atoi(pos2
+ 12);
3504 ssid
= wpa_config_get_network(wpa_s
->conf
, persistent_id
);
3505 if (ssid
== NULL
|| ssid
->disabled
!= 2 ||
3506 ssid
->mode
!= WPAS_MODE_P2P_GO
) {
3507 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
3508 "SSID id=%d for persistent P2P group (GO)",
3513 join
= os_strstr(pos
, " join") != NULL
;
3514 auth
= os_strstr(pos
, " auth") != NULL
;
3515 automatic
= os_strstr(pos
, " auto") != NULL
;
3516 pd
= os_strstr(pos
, " provdisc") != NULL
;
3517 ht40
= (os_strstr(cmd
, " ht40") != NULL
) || wpa_s
->conf
->p2p_go_ht40
;
3519 pos2
= os_strstr(pos
, " go_intent=");
3522 go_intent
= atoi(pos2
);
3523 if (go_intent
< 0 || go_intent
> 15)
3527 pos2
= os_strstr(pos
, " freq=");
3535 if (os_strncmp(pos
, "pin", 3) == 0) {
3536 /* Request random PIN (to be displayed) and enable the PIN */
3537 wps_method
= WPS_PIN_DISPLAY
;
3538 } else if (os_strncmp(pos
, "pbc", 3) == 0) {
3539 wps_method
= WPS_PBC
;
3542 pos
= os_strchr(pin
, ' ');
3543 wps_method
= WPS_PIN_KEYPAD
;
3546 if (os_strncmp(pos
, "display", 7) == 0)
3547 wps_method
= WPS_PIN_DISPLAY
;
3549 if (!wps_pin_str_valid(pin
)) {
3550 os_memcpy(buf
, "FAIL-INVALID-PIN\n", 17);
3555 new_pin
= wpas_p2p_connect(wpa_s
, addr
, pin
, wps_method
,
3556 persistent_group
, automatic
, join
,
3557 auth
, go_intent
, freq
, persistent_id
, pd
,
3559 if (new_pin
== -2) {
3560 os_memcpy(buf
, "FAIL-CHANNEL-UNAVAILABLE\n", 25);
3563 if (new_pin
== -3) {
3564 os_memcpy(buf
, "FAIL-CHANNEL-UNSUPPORTED\n", 25);
3569 if (wps_method
== WPS_PIN_DISPLAY
&& pin
== NULL
) {
3570 ret
= os_snprintf(buf
, buflen
, "%08d", new_pin
);
3571 if (ret
< 0 || (size_t) ret
>= buflen
)
3576 os_memcpy(buf
, "OK\n", 3);
3581 static int p2p_ctrl_listen(struct wpa_supplicant
*wpa_s
, char *cmd
)
3583 unsigned int timeout
= atoi(cmd
);
3584 return wpas_p2p_listen(wpa_s
, timeout
);
3588 static int p2p_ctrl_prov_disc(struct wpa_supplicant
*wpa_s
, char *cmd
)
3592 enum wpas_p2p_prov_disc_use use
= WPAS_P2P_PD_FOR_GO_NEG
;
3594 /* <addr> <config method> [join|auto] */
3596 if (hwaddr_aton(cmd
, addr
))
3604 if (os_strstr(pos
, " join") != NULL
)
3605 use
= WPAS_P2P_PD_FOR_JOIN
;
3606 else if (os_strstr(pos
, " auto") != NULL
)
3607 use
= WPAS_P2P_PD_AUTO
;
3609 return wpas_p2p_prov_disc(wpa_s
, addr
, pos
, use
);
3613 static int p2p_get_passphrase(struct wpa_supplicant
*wpa_s
, char *buf
,
3616 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
3618 if (ssid
== NULL
|| ssid
->mode
!= WPAS_MODE_P2P_GO
||
3619 ssid
->passphrase
== NULL
)
3622 os_strlcpy(buf
, ssid
->passphrase
, buflen
);
3623 return os_strlen(buf
);
3627 static int p2p_ctrl_serv_disc_req(struct wpa_supplicant
*wpa_s
, char *cmd
,
3628 char *buf
, size_t buflen
)
3632 u8 dst_buf
[ETH_ALEN
], *dst
;
3633 struct wpabuf
*tlvs
;
3637 if (hwaddr_aton(cmd
, dst_buf
))
3640 if (dst
[0] == 0 && dst
[1] == 0 && dst
[2] == 0 &&
3641 dst
[3] == 0 && dst
[4] == 0 && dst
[5] == 0)
3648 if (os_strncmp(pos
, "upnp ", 5) == 0) {
3651 if (hexstr2bin(pos
, &version
, 1) < 0)
3657 ref
= wpas_p2p_sd_request_upnp(wpa_s
, dst
, version
, pos
);
3658 #ifdef CONFIG_WIFI_DISPLAY
3659 } else if (os_strncmp(pos
, "wifi-display ", 13) == 0) {
3660 ref
= wpas_p2p_sd_request_wifi_display(wpa_s
, dst
, pos
+ 13);
3661 #endif /* CONFIG_WIFI_DISPLAY */
3663 len
= os_strlen(pos
);
3667 tlvs
= wpabuf_alloc(len
);
3670 if (hexstr2bin(pos
, wpabuf_put(tlvs
, len
), len
) < 0) {
3675 ref
= wpas_p2p_sd_request(wpa_s
, dst
, tlvs
);
3680 res
= os_snprintf(buf
, buflen
, "%llx", (long long unsigned) ref
);
3681 if (res
< 0 || (unsigned) res
>= buflen
)
3687 static int p2p_ctrl_serv_disc_cancel_req(struct wpa_supplicant
*wpa_s
,
3690 long long unsigned val
;
3692 if (sscanf(cmd
, "%llx", &val
) != 1)
3695 return wpas_p2p_sd_cancel_request(wpa_s
, req
);
3699 static int p2p_ctrl_serv_disc_resp(struct wpa_supplicant
*wpa_s
, char *cmd
)
3704 struct wpabuf
*resp_tlvs
;
3708 pos
= os_strchr(cmd
, ' ');
3716 if (hwaddr_aton(pos
, dst
))
3723 pos2
= os_strchr(pos
, ' ');
3727 dialog_token
= atoi(pos
);
3729 len
= os_strlen(pos2
);
3733 resp_tlvs
= wpabuf_alloc(len
);
3734 if (resp_tlvs
== NULL
)
3736 if (hexstr2bin(pos2
, wpabuf_put(resp_tlvs
, len
), len
) < 0) {
3737 wpabuf_free(resp_tlvs
);
3741 wpas_p2p_sd_response(wpa_s
, freq
, dst
, dialog_token
, resp_tlvs
);
3742 wpabuf_free(resp_tlvs
);
3747 static int p2p_ctrl_serv_disc_external(struct wpa_supplicant
*wpa_s
,
3750 if (os_strcmp(cmd
, "0") && os_strcmp(cmd
, "1"))
3752 wpa_s
->p2p_sd_over_ctrl_iface
= atoi(cmd
);
3757 static int p2p_ctrl_service_add_bonjour(struct wpa_supplicant
*wpa_s
,
3762 struct wpabuf
*query
, *resp
;
3764 pos
= os_strchr(cmd
, ' ');
3769 len
= os_strlen(cmd
);
3773 query
= wpabuf_alloc(len
);
3776 if (hexstr2bin(cmd
, wpabuf_put(query
, len
), len
) < 0) {
3781 len
= os_strlen(pos
);
3787 resp
= wpabuf_alloc(len
);
3792 if (hexstr2bin(pos
, wpabuf_put(resp
, len
), len
) < 0) {
3798 if (wpas_p2p_service_add_bonjour(wpa_s
, query
, resp
) < 0) {
3807 static int p2p_ctrl_service_add_upnp(struct wpa_supplicant
*wpa_s
, char *cmd
)
3812 pos
= os_strchr(cmd
, ' ');
3817 if (hexstr2bin(cmd
, &version
, 1) < 0)
3820 return wpas_p2p_service_add_upnp(wpa_s
, version
, pos
);
3824 static int p2p_ctrl_service_add(struct wpa_supplicant
*wpa_s
, char *cmd
)
3828 pos
= os_strchr(cmd
, ' ');
3833 if (os_strcmp(cmd
, "bonjour") == 0)
3834 return p2p_ctrl_service_add_bonjour(wpa_s
, pos
);
3835 if (os_strcmp(cmd
, "upnp") == 0)
3836 return p2p_ctrl_service_add_upnp(wpa_s
, pos
);
3837 wpa_printf(MSG_DEBUG
, "Unknown service '%s'", cmd
);
3842 static int p2p_ctrl_service_del_bonjour(struct wpa_supplicant
*wpa_s
,
3846 struct wpabuf
*query
;
3849 len
= os_strlen(cmd
);
3853 query
= wpabuf_alloc(len
);
3856 if (hexstr2bin(cmd
, wpabuf_put(query
, len
), len
) < 0) {
3861 ret
= wpas_p2p_service_del_bonjour(wpa_s
, query
);
3867 static int p2p_ctrl_service_del_upnp(struct wpa_supplicant
*wpa_s
, char *cmd
)
3872 pos
= os_strchr(cmd
, ' ');
3877 if (hexstr2bin(cmd
, &version
, 1) < 0)
3880 return wpas_p2p_service_del_upnp(wpa_s
, version
, pos
);
3884 static int p2p_ctrl_service_del(struct wpa_supplicant
*wpa_s
, char *cmd
)
3888 pos
= os_strchr(cmd
, ' ');
3893 if (os_strcmp(cmd
, "bonjour") == 0)
3894 return p2p_ctrl_service_del_bonjour(wpa_s
, pos
);
3895 if (os_strcmp(cmd
, "upnp") == 0)
3896 return p2p_ctrl_service_del_upnp(wpa_s
, pos
);
3897 wpa_printf(MSG_DEBUG
, "Unknown service '%s'", cmd
);
3902 static int p2p_ctrl_reject(struct wpa_supplicant
*wpa_s
, char *cmd
)
3908 if (hwaddr_aton(cmd
, addr
))
3911 return wpas_p2p_reject(wpa_s
, addr
);
3915 static int p2p_ctrl_invite_persistent(struct wpa_supplicant
*wpa_s
, char *cmd
)
3919 struct wpa_ssid
*ssid
;
3920 u8
*_peer
= NULL
, peer
[ETH_ALEN
];
3925 pos
= os_strstr(cmd
, " peer=");
3928 if (hwaddr_aton(pos
, peer
))
3932 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
3933 if (ssid
== NULL
|| ssid
->disabled
!= 2) {
3934 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
3935 "for persistent P2P group",
3940 pos
= os_strstr(cmd
, " freq=");
3948 ht40
= (os_strstr(cmd
, " ht40") != NULL
) || wpa_s
->conf
->p2p_go_ht40
;
3950 return wpas_p2p_invite(wpa_s
, _peer
, ssid
, NULL
, freq
, ht40
);
3954 static int p2p_ctrl_invite_group(struct wpa_supplicant
*wpa_s
, char *cmd
)
3957 u8 peer
[ETH_ALEN
], go_dev_addr
[ETH_ALEN
], *go_dev
= NULL
;
3959 pos
= os_strstr(cmd
, " peer=");
3965 if (hwaddr_aton(pos
, peer
)) {
3966 wpa_printf(MSG_DEBUG
, "P2P: Invalid MAC address '%s'", pos
);
3970 pos
= os_strstr(pos
, " go_dev_addr=");
3973 if (hwaddr_aton(pos
, go_dev_addr
)) {
3974 wpa_printf(MSG_DEBUG
, "P2P: Invalid MAC address '%s'",
3978 go_dev
= go_dev_addr
;
3981 return wpas_p2p_invite_group(wpa_s
, cmd
, peer
, go_dev
);
3985 static int p2p_ctrl_invite(struct wpa_supplicant
*wpa_s
, char *cmd
)
3987 if (os_strncmp(cmd
, "persistent=", 11) == 0)
3988 return p2p_ctrl_invite_persistent(wpa_s
, cmd
+ 11);
3989 if (os_strncmp(cmd
, "group=", 6) == 0)
3990 return p2p_ctrl_invite_group(wpa_s
, cmd
+ 6);
3996 static int p2p_ctrl_group_add_persistent(struct wpa_supplicant
*wpa_s
,
3997 char *cmd
, int freq
, int ht40
)
4000 struct wpa_ssid
*ssid
;
4003 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
4004 if (ssid
== NULL
|| ssid
->disabled
!= 2) {
4005 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
4006 "for persistent P2P group",
4011 return wpas_p2p_group_add_persistent(wpa_s
, ssid
, 0, freq
, ht40
);
4015 static int p2p_ctrl_group_add(struct wpa_supplicant
*wpa_s
, char *cmd
)
4020 pos
= os_strstr(cmd
, "freq=");
4022 freq
= atoi(pos
+ 5);
4024 ht40
= (os_strstr(cmd
, "ht40") != NULL
) || wpa_s
->conf
->p2p_go_ht40
;
4026 if (os_strncmp(cmd
, "persistent=", 11) == 0)
4027 return p2p_ctrl_group_add_persistent(wpa_s
, cmd
+ 11, freq
,
4029 if (os_strcmp(cmd
, "persistent") == 0 ||
4030 os_strncmp(cmd
, "persistent ", 11) == 0)
4031 return wpas_p2p_group_add(wpa_s
, 1, freq
, ht40
);
4032 if (os_strncmp(cmd
, "freq=", 5) == 0)
4033 return wpas_p2p_group_add(wpa_s
, 0, freq
, ht40
);
4035 return wpas_p2p_group_add(wpa_s
, 0, freq
, ht40
);
4037 wpa_printf(MSG_DEBUG
, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'",
4043 static int p2p_ctrl_peer(struct wpa_supplicant
*wpa_s
, char *cmd
,
4044 char *buf
, size_t buflen
)
4046 u8 addr
[ETH_ALEN
], *addr_ptr
;
4048 const struct p2p_peer_info
*info
;
4050 char devtype
[WPS_DEV_TYPE_BUFSIZE
];
4051 struct wpa_ssid
*ssid
;
4054 if (!wpa_s
->global
->p2p
)
4057 if (os_strcmp(cmd
, "FIRST") == 0) {
4060 } else if (os_strncmp(cmd
, "NEXT-", 5) == 0) {
4061 if (hwaddr_aton(cmd
+ 5, addr
) < 0)
4066 if (hwaddr_aton(cmd
, addr
) < 0)
4072 info
= p2p_get_peer_info(wpa_s
->global
->p2p
, addr_ptr
, next
);
4079 res
= os_snprintf(pos
, end
- pos
, MACSTR
"\n"
4085 "serial_number=%s\n"
4086 "config_methods=0x%x\n"
4088 "group_capab=0x%x\n"
4090 MAC2STR(info
->p2p_device_addr
),
4091 wps_dev_type_bin2str(info
->pri_dev_type
,
4092 devtype
, sizeof(devtype
)),
4097 info
->serial_number
,
4098 info
->config_methods
,
4102 if (res
< 0 || res
>= end
- pos
)
4106 for (i
= 0; i
< info
->wps_sec_dev_type_list_len
/ WPS_DEV_TYPE_LEN
; i
++)
4109 t
= &info
->wps_sec_dev_type_list
[i
* WPS_DEV_TYPE_LEN
];
4110 res
= os_snprintf(pos
, end
- pos
, "sec_dev_type=%s\n",
4111 wps_dev_type_bin2str(t
, devtype
,
4113 if (res
< 0 || res
>= end
- pos
)
4118 ssid
= wpas_p2p_get_persistent(wpa_s
, info
->p2p_device_addr
, NULL
, 0);
4120 res
= os_snprintf(pos
, end
- pos
, "persistent=%d\n", ssid
->id
);
4121 if (res
< 0 || res
>= end
- pos
)
4126 res
= p2p_get_peer_info_txt(info
, pos
, end
- pos
);
4135 static int p2p_ctrl_disallow_freq(struct wpa_supplicant
*wpa_s
,
4138 struct wpa_freq_range
*freq
= NULL
, *n
;
4139 unsigned int count
= 0, i
;
4140 const char *pos
, *pos2
, *pos3
;
4142 if (wpa_s
->global
->p2p
== NULL
)
4146 * param includes comma separated frequency range.
4147 * For example: 2412-2432,2462,5000-6000
4150 while (pos
&& pos
[0]) {
4151 n
= os_realloc_array(freq
, count
+ 1,
4152 sizeof(struct wpa_freq_range
));
4158 freq
[count
].min
= atoi(pos
);
4159 pos2
= os_strchr(pos
, '-');
4160 pos3
= os_strchr(pos
, ',');
4161 if (pos2
&& (!pos3
|| pos2
< pos3
)) {
4163 freq
[count
].max
= atoi(pos2
);
4165 freq
[count
].max
= freq
[count
].min
;
4172 for (i
= 0; i
< count
; i
++) {
4173 wpa_printf(MSG_DEBUG
, "P2P: Disallowed frequency range %u-%u",
4174 freq
[i
].min
, freq
[i
].max
);
4177 os_free(wpa_s
->global
->p2p_disallow_freq
);
4178 wpa_s
->global
->p2p_disallow_freq
= freq
;
4179 wpa_s
->global
->num_p2p_disallow_freq
= count
;
4180 wpas_p2p_update_channel_list(wpa_s
);
4185 static int p2p_ctrl_set(struct wpa_supplicant
*wpa_s
, char *cmd
)
4189 if (wpa_s
->global
->p2p
== NULL
)
4192 param
= os_strchr(cmd
, ' ');
4197 if (os_strcmp(cmd
, "discoverability") == 0) {
4198 p2p_set_client_discoverability(wpa_s
->global
->p2p
,
4203 if (os_strcmp(cmd
, "managed") == 0) {
4204 p2p_set_managed_oper(wpa_s
->global
->p2p
, atoi(param
));
4208 if (os_strcmp(cmd
, "listen_channel") == 0) {
4209 return p2p_set_listen_channel(wpa_s
->global
->p2p
, 81,
4213 if (os_strcmp(cmd
, "ssid_postfix") == 0) {
4214 return p2p_set_ssid_postfix(wpa_s
->global
->p2p
, (u8
*) param
,
4218 if (os_strcmp(cmd
, "noa") == 0) {
4220 int count
, start
, duration
;
4221 /* GO NoA parameters: count,start_offset(ms),duration(ms) */
4222 count
= atoi(param
);
4223 pos
= os_strchr(param
, ',');
4228 pos
= os_strchr(pos
, ',');
4232 duration
= atoi(pos
);
4233 if (count
< 0 || count
> 255 || start
< 0 || duration
< 0)
4235 if (count
== 0 && duration
> 0)
4237 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: P2P_SET GO NoA: count=%d "
4238 "start=%d duration=%d", count
, start
, duration
);
4239 return wpas_p2p_set_noa(wpa_s
, count
, start
, duration
);
4242 if (os_strcmp(cmd
, "ps") == 0)
4243 return wpa_drv_set_p2p_powersave(wpa_s
, atoi(param
), -1, -1);
4245 if (os_strcmp(cmd
, "oppps") == 0)
4246 return wpa_drv_set_p2p_powersave(wpa_s
, -1, atoi(param
), -1);
4248 if (os_strcmp(cmd
, "ctwindow") == 0)
4249 return wpa_drv_set_p2p_powersave(wpa_s
, -1, -1, atoi(param
));
4251 if (os_strcmp(cmd
, "disabled") == 0) {
4252 wpa_s
->global
->p2p_disabled
= atoi(param
);
4253 wpa_printf(MSG_DEBUG
, "P2P functionality %s",
4254 wpa_s
->global
->p2p_disabled
?
4255 "disabled" : "enabled");
4256 if (wpa_s
->global
->p2p_disabled
) {
4257 wpas_p2p_stop_find(wpa_s
);
4258 os_memset(wpa_s
->p2p_auth_invite
, 0, ETH_ALEN
);
4259 p2p_flush(wpa_s
->global
->p2p
);
4264 if (os_strcmp(cmd
, "conc_pref") == 0) {
4265 if (os_strcmp(param
, "sta") == 0)
4266 wpa_s
->global
->conc_pref
= WPA_CONC_PREF_STA
;
4267 else if (os_strcmp(param
, "p2p") == 0)
4268 wpa_s
->global
->conc_pref
= WPA_CONC_PREF_P2P
;
4270 wpa_printf(MSG_INFO
, "Invalid conc_pref value");
4273 wpa_printf(MSG_DEBUG
, "Single channel concurrency preference: "
4278 if (os_strcmp(cmd
, "force_long_sd") == 0) {
4279 wpa_s
->force_long_sd
= atoi(param
);
4283 if (os_strcmp(cmd
, "peer_filter") == 0) {
4285 if (hwaddr_aton(param
, addr
))
4287 p2p_set_peer_filter(wpa_s
->global
->p2p
, addr
);
4291 if (os_strcmp(cmd
, "cross_connect") == 0)
4292 return wpas_p2p_set_cross_connect(wpa_s
, atoi(param
));
4294 if (os_strcmp(cmd
, "go_apsd") == 0) {
4295 if (os_strcmp(param
, "disable") == 0)
4296 wpa_s
->set_ap_uapsd
= 0;
4298 wpa_s
->set_ap_uapsd
= 1;
4299 wpa_s
->ap_uapsd
= atoi(param
);
4304 if (os_strcmp(cmd
, "client_apsd") == 0) {
4305 if (os_strcmp(param
, "disable") == 0)
4306 wpa_s
->set_sta_uapsd
= 0;
4310 /* format: BE,BK,VI,VO;max SP Length */
4312 pos
= os_strchr(param
, ',');
4317 pos
= os_strchr(pos
, ',');
4322 pos
= os_strchr(pos
, ',');
4327 /* ignore max SP Length for now */
4329 wpa_s
->set_sta_uapsd
= 1;
4330 wpa_s
->sta_uapsd
= 0;
4332 wpa_s
->sta_uapsd
|= BIT(0);
4334 wpa_s
->sta_uapsd
|= BIT(1);
4336 wpa_s
->sta_uapsd
|= BIT(2);
4338 wpa_s
->sta_uapsd
|= BIT(3);
4343 if (os_strcmp(cmd
, "disallow_freq") == 0)
4344 return p2p_ctrl_disallow_freq(wpa_s
, param
);
4346 if (os_strcmp(cmd
, "disc_int") == 0) {
4347 int min_disc_int
, max_disc_int
, max_disc_tu
;
4352 min_disc_int
= atoi(pos
);
4353 pos
= os_strchr(pos
, ' ');
4358 max_disc_int
= atoi(pos
);
4359 pos
= os_strchr(pos
, ' ');
4364 max_disc_tu
= atoi(pos
);
4366 return p2p_set_disc_int(wpa_s
->global
->p2p
, min_disc_int
,
4367 max_disc_int
, max_disc_tu
);
4370 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
4377 static int p2p_ctrl_presence_req(struct wpa_supplicant
*wpa_s
, char *cmd
)
4380 unsigned int dur1
= 0, int1
= 0, dur2
= 0, int2
= 0;
4383 pos
= os_strchr(cmd
, ' ');
4389 pos2
= os_strchr(pos
, ' ');
4397 pos
= os_strchr(pos2
, ' ');
4405 return wpas_p2p_presence_req(wpa_s
, dur1
, int1
, dur2
, int2
);
4409 static int p2p_ctrl_ext_listen(struct wpa_supplicant
*wpa_s
, char *cmd
)
4412 unsigned int period
= 0, interval
= 0;
4415 pos
= os_strchr(cmd
, ' ');
4420 interval
= atoi(pos
);
4423 return wpas_p2p_ext_listen(wpa_s
, period
, interval
);
4426 #endif /* CONFIG_P2P */
4429 #ifdef CONFIG_INTERWORKING
4430 static int ctrl_interworking_connect(struct wpa_supplicant
*wpa_s
, char *dst
)
4433 struct wpa_bss
*bss
;
4435 if (hwaddr_aton(dst
, bssid
)) {
4436 wpa_printf(MSG_DEBUG
, "Invalid BSSID '%s'", dst
);
4440 bss
= wpa_bss_get_bssid(wpa_s
, bssid
);
4442 wpa_printf(MSG_DEBUG
, "Could not find BSS " MACSTR
,
4447 return interworking_connect(wpa_s
, bss
);
4451 static int get_anqp(struct wpa_supplicant
*wpa_s
, char *dst
)
4453 u8 dst_addr
[ETH_ALEN
];
4456 #define MAX_ANQP_INFO_ID 100
4457 u16 id
[MAX_ANQP_INFO_ID
];
4460 used
= hwaddr_aton2(dst
, dst_addr
);
4464 while (num_id
< MAX_ANQP_INFO_ID
) {
4465 id
[num_id
] = atoi(pos
);
4468 pos
= os_strchr(pos
+ 1, ',');
4477 return anqp_send_req(wpa_s
, dst_addr
, id
, num_id
);
4481 static int gas_request(struct wpa_supplicant
*wpa_s
, char *cmd
)
4483 u8 dst_addr
[ETH_ALEN
];
4484 struct wpabuf
*advproto
, *query
= NULL
;
4489 used
= hwaddr_aton2(cmd
, dst_addr
);
4497 /* Advertisement Protocol ID */
4498 end
= os_strchr(pos
, ' ');
4502 len
= os_strlen(pos
);
4508 advproto
= wpabuf_alloc(len
);
4509 if (advproto
== NULL
)
4511 if (hexstr2bin(pos
, wpabuf_put(advproto
, len
), len
) < 0)
4515 /* Optional Query Request */
4520 len
= os_strlen(pos
);
4527 query
= wpabuf_alloc(len
);
4530 if (hexstr2bin(pos
, wpabuf_put(query
, len
), len
) < 0)
4535 ret
= gas_send_request(wpa_s
, dst_addr
, advproto
, query
);
4538 wpabuf_free(advproto
);
4545 static int gas_response_get(struct wpa_supplicant
*wpa_s
, char *cmd
, char *buf
,
4552 size_t resp_len
, start
, requested_len
;
4554 if (!wpa_s
->last_gas_resp
)
4557 used
= hwaddr_aton2(cmd
, addr
);
4564 dialog_token
= atoi(pos
);
4566 if (os_memcmp(addr
, wpa_s
->last_gas_addr
, ETH_ALEN
) != 0 ||
4567 dialog_token
!= wpa_s
->last_gas_dialog_token
)
4570 resp_len
= wpabuf_len(wpa_s
->last_gas_resp
);
4572 requested_len
= resp_len
;
4574 pos
= os_strchr(pos
, ' ');
4577 if (start
> resp_len
)
4578 return os_snprintf(buf
, buflen
, "FAIL-Invalid range");
4579 pos
= os_strchr(pos
, ',');
4583 requested_len
= atoi(pos
);
4584 if (start
+ requested_len
> resp_len
)
4585 return os_snprintf(buf
, buflen
, "FAIL-Invalid range");
4588 if (requested_len
* 2 + 1 > buflen
)
4589 return os_snprintf(buf
, buflen
, "FAIL-Too long response");
4591 return wpa_snprintf_hex(buf
, buflen
,
4592 wpabuf_head_u8(wpa_s
->last_gas_resp
) + start
,
4595 #endif /* CONFIG_INTERWORKING */
4600 static int get_hs20_anqp(struct wpa_supplicant
*wpa_s
, char *dst
)
4602 u8 dst_addr
[ETH_ALEN
];
4607 used
= hwaddr_aton2(dst
, dst_addr
);
4612 int num
= atoi(pos
);
4613 if (num
<= 0 || num
> 31)
4615 subtypes
|= BIT(num
);
4616 pos
= os_strchr(pos
+ 1, ',');
4625 return hs20_anqp_send_req(wpa_s
, dst_addr
, subtypes
, NULL
, 0);
4629 static int hs20_nai_home_realm_list(struct wpa_supplicant
*wpa_s
,
4630 const u8
*addr
, const char *realm
)
4636 rlen
= os_strlen(realm
);
4638 buf
= os_malloc(len
);
4641 buf
[0] = 1; /* NAI Home Realm Count */
4642 buf
[1] = 0; /* Formatted in accordance with RFC 4282 */
4644 os_memcpy(buf
+ 3, realm
, rlen
);
4646 ret
= hs20_anqp_send_req(wpa_s
, addr
,
4647 BIT(HS20_STYPE_NAI_HOME_REALM_QUERY
),
4656 static int hs20_get_nai_home_realm_list(struct wpa_supplicant
*wpa_s
,
4659 struct wpa_cred
*cred
= wpa_s
->conf
->cred
;
4660 u8 dst_addr
[ETH_ALEN
];
4666 used
= hwaddr_aton2(dst
, dst_addr
);
4670 while (dst
[used
] == ' ')
4672 if (os_strncmp(dst
+ used
, "realm=", 6) == 0)
4673 return hs20_nai_home_realm_list(wpa_s
, dst_addr
,
4676 len
= os_strlen(dst
+ used
);
4678 if (len
== 0 && cred
&& cred
->realm
)
4679 return hs20_nai_home_realm_list(wpa_s
, dst_addr
, cred
->realm
);
4684 buf
= os_malloc(len
);
4687 if (hexstr2bin(dst
+ used
, buf
, len
) < 0) {
4692 ret
= hs20_anqp_send_req(wpa_s
, dst_addr
,
4693 BIT(HS20_STYPE_NAI_HOME_REALM_QUERY
),
4700 #endif /* CONFIG_HS20 */
4703 static int wpa_supplicant_ctrl_iface_sta_autoconnect(
4704 struct wpa_supplicant
*wpa_s
, char *cmd
)
4706 wpa_s
->auto_reconnect_disabled
= atoi(cmd
) == 0 ? 1 : 0;
4711 #ifdef CONFIG_AUTOSCAN
4713 static int wpa_supplicant_ctrl_iface_autoscan(struct wpa_supplicant
*wpa_s
,
4716 enum wpa_states state
= wpa_s
->wpa_state
;
4717 char *new_params
= NULL
;
4719 if (os_strlen(cmd
) > 0) {
4720 new_params
= os_strdup(cmd
);
4721 if (new_params
== NULL
)
4725 os_free(wpa_s
->conf
->autoscan
);
4726 wpa_s
->conf
->autoscan
= new_params
;
4728 if (wpa_s
->conf
->autoscan
== NULL
)
4729 autoscan_deinit(wpa_s
);
4730 else if (state
== WPA_DISCONNECTED
|| state
== WPA_INACTIVE
)
4731 autoscan_init(wpa_s
, 1);
4732 else if (state
== WPA_SCANNING
)
4733 wpa_supplicant_reinit_autoscan(wpa_s
);
4738 #endif /* CONFIG_AUTOSCAN */
4743 static int wpas_ctrl_iface_wnm_sleep(struct wpa_supplicant
*wpa_s
, char *cmd
)
4749 struct wpabuf
*tfs_req
= NULL
;
4751 if (os_strncmp(cmd
, "enter", 5) == 0)
4753 else if (os_strncmp(cmd
, "exit", 4) == 0)
4758 pos
= os_strstr(cmd
, " interval=");
4760 intval
= atoi(pos
+ 10);
4762 pos
= os_strstr(cmd
, " tfs_req=");
4767 end
= os_strchr(pos
, ' ');
4771 len
= os_strlen(pos
);
4775 tfs_req
= wpabuf_alloc(len
);
4776 if (tfs_req
== NULL
)
4778 if (hexstr2bin(pos
, wpabuf_put(tfs_req
, len
), len
) < 0) {
4779 wpabuf_free(tfs_req
);
4784 ret
= ieee802_11_send_wnmsleep_req(wpa_s
, enter
? WNM_SLEEP_MODE_ENTER
:
4785 WNM_SLEEP_MODE_EXIT
, intval
,
4787 wpabuf_free(tfs_req
);
4792 #endif /* CONFIG_WNM */
4795 static int wpa_supplicant_signal_poll(struct wpa_supplicant
*wpa_s
, char *buf
,
4798 struct wpa_signal_info si
;
4801 ret
= wpa_drv_signal_poll(wpa_s
, &si
);
4805 ret
= os_snprintf(buf
, buflen
, "RSSI=%d\nLINKSPEED=%d\n"
4806 "NOISE=%d\nFREQUENCY=%u\n",
4807 si
.current_signal
, si
.current_txrate
/ 1000,
4808 si
.current_noise
, si
.frequency
);
4809 if (ret
< 0 || (unsigned int) ret
> buflen
)
4815 static int wpa_supplicant_pktcnt_poll(struct wpa_supplicant
*wpa_s
, char *buf
,
4818 struct hostap_sta_driver_data sta
;
4821 ret
= wpa_drv_pktcnt_poll(wpa_s
, &sta
);
4825 ret
= os_snprintf(buf
, buflen
, "TXGOOD=%lu\nTXBAD=%lu\nRXGOOD=%lu\n",
4826 sta
.tx_packets
, sta
.tx_retry_failed
, sta
.rx_packets
);
4827 if (ret
< 0 || (size_t) ret
> buflen
)
4833 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant
*wpa_s
,
4834 char *buf
, size_t *resp_len
)
4837 const int reply_size
= 4096;
4841 if (os_strncmp(buf
, WPA_CTRL_RSP
, os_strlen(WPA_CTRL_RSP
)) == 0 ||
4842 os_strncmp(buf
, "SET_NETWORK ", 12) == 0 ||
4843 os_strncmp(buf
, "WPS_NFC_TAG_READ", 16) == 0 ||
4844 os_strncmp(buf
, "NFC_REPORT_HANDOVER", 19) == 0 ||
4845 os_strncmp(buf
, "NFC_RX_HANDOVER_SEL", 19) == 0) {
4846 wpa_hexdump_ascii_key(MSG_DEBUG
, "RX ctrl_iface",
4847 (const u8
*) buf
, os_strlen(buf
));
4849 int level
= MSG_DEBUG
;
4850 if (os_strcmp(buf
, "PING") == 0)
4851 level
= MSG_EXCESSIVE
;
4852 wpa_hexdump_ascii(level
, "RX ctrl_iface",
4853 (const u8
*) buf
, os_strlen(buf
));
4854 wpa_dbg(wpa_s
, level
, "Control interface command '%s'", buf
);
4857 reply
= os_malloc(reply_size
);
4858 if (reply
== NULL
) {
4863 os_memcpy(reply
, "OK\n", 3);
4866 if (os_strcmp(buf
, "PING") == 0) {
4867 os_memcpy(reply
, "PONG\n", 5);
4869 } else if (os_strcmp(buf
, "IFNAME") == 0) {
4870 reply_len
= os_strlen(wpa_s
->ifname
);
4871 os_memcpy(reply
, wpa_s
->ifname
, reply_len
);
4872 } else if (os_strncmp(buf
, "RELOG", 5) == 0) {
4873 if (wpa_debug_reopen_file() < 0)
4875 } else if (os_strncmp(buf
, "NOTE ", 5) == 0) {
4876 wpa_printf(MSG_INFO
, "NOTE: %s", buf
+ 5);
4877 } else if (os_strcmp(buf
, "MIB") == 0) {
4878 reply_len
= wpa_sm_get_mib(wpa_s
->wpa
, reply
, reply_size
);
4879 if (reply_len
>= 0) {
4881 res
= eapol_sm_get_mib(wpa_s
->eapol
, reply
+ reply_len
,
4882 reply_size
- reply_len
);
4888 } else if (os_strncmp(buf
, "STATUS", 6) == 0) {
4889 reply_len
= wpa_supplicant_ctrl_iface_status(
4890 wpa_s
, buf
+ 6, reply
, reply_size
);
4891 } else if (os_strcmp(buf
, "PMKSA") == 0) {
4892 reply_len
= wpa_sm_pmksa_cache_list(wpa_s
->wpa
, reply
,
4894 } else if (os_strncmp(buf
, "SET ", 4) == 0) {
4895 if (wpa_supplicant_ctrl_iface_set(wpa_s
, buf
+ 4))
4897 } else if (os_strncmp(buf
, "GET ", 4) == 0) {
4898 reply_len
= wpa_supplicant_ctrl_iface_get(wpa_s
, buf
+ 4,
4900 } else if (os_strcmp(buf
, "LOGON") == 0) {
4901 eapol_sm_notify_logoff(wpa_s
->eapol
, FALSE
);
4902 } else if (os_strcmp(buf
, "LOGOFF") == 0) {
4903 eapol_sm_notify_logoff(wpa_s
->eapol
, TRUE
);
4904 } else if (os_strcmp(buf
, "REASSOCIATE") == 0) {
4905 if (wpa_s
->wpa_state
== WPA_INTERFACE_DISABLED
)
4908 wpas_request_connection(wpa_s
);
4909 } else if (os_strcmp(buf
, "RECONNECT") == 0) {
4910 if (wpa_s
->wpa_state
== WPA_INTERFACE_DISABLED
)
4912 else if (wpa_s
->disconnected
)
4913 wpas_request_connection(wpa_s
);
4914 #ifdef IEEE8021X_EAPOL
4915 } else if (os_strncmp(buf
, "PREAUTH ", 8) == 0) {
4916 if (wpa_supplicant_ctrl_iface_preauth(wpa_s
, buf
+ 8))
4918 #endif /* IEEE8021X_EAPOL */
4919 #ifdef CONFIG_PEERKEY
4920 } else if (os_strncmp(buf
, "STKSTART ", 9) == 0) {
4921 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s
, buf
+ 9))
4923 #endif /* CONFIG_PEERKEY */
4924 #ifdef CONFIG_IEEE80211R
4925 } else if (os_strncmp(buf
, "FT_DS ", 6) == 0) {
4926 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s
, buf
+ 6))
4928 #endif /* CONFIG_IEEE80211R */
4930 } else if (os_strcmp(buf
, "WPS_PBC") == 0) {
4931 int res
= wpa_supplicant_ctrl_iface_wps_pbc(wpa_s
, NULL
);
4933 os_memcpy(reply
, "FAIL-PBC-OVERLAP\n", 17);
4937 } else if (os_strncmp(buf
, "WPS_PBC ", 8) == 0) {
4938 int res
= wpa_supplicant_ctrl_iface_wps_pbc(wpa_s
, buf
+ 8);
4940 os_memcpy(reply
, "FAIL-PBC-OVERLAP\n", 17);
4944 } else if (os_strncmp(buf
, "WPS_PIN ", 8) == 0) {
4945 reply_len
= wpa_supplicant_ctrl_iface_wps_pin(wpa_s
, buf
+ 8,
4948 } else if (os_strncmp(buf
, "WPS_CHECK_PIN ", 14) == 0) {
4949 reply_len
= wpa_supplicant_ctrl_iface_wps_check_pin(
4950 wpa_s
, buf
+ 14, reply
, reply_size
);
4951 } else if (os_strcmp(buf
, "WPS_CANCEL") == 0) {
4952 if (wpas_wps_cancel(wpa_s
))
4954 #ifdef CONFIG_WPS_NFC
4955 } else if (os_strcmp(buf
, "WPS_NFC") == 0) {
4956 if (wpa_supplicant_ctrl_iface_wps_nfc(wpa_s
, NULL
))
4958 } else if (os_strncmp(buf
, "WPS_NFC ", 8) == 0) {
4959 if (wpa_supplicant_ctrl_iface_wps_nfc(wpa_s
, buf
+ 8))
4961 } else if (os_strncmp(buf
, "WPS_NFC_TOKEN ", 14) == 0) {
4962 reply_len
= wpa_supplicant_ctrl_iface_wps_nfc_token(
4963 wpa_s
, buf
+ 14, reply
, reply_size
);
4964 } else if (os_strncmp(buf
, "WPS_NFC_TAG_READ ", 17) == 0) {
4965 if (wpa_supplicant_ctrl_iface_wps_nfc_tag_read(wpa_s
,
4968 } else if (os_strncmp(buf
, "NFC_GET_HANDOVER_REQ ", 21) == 0) {
4969 reply_len
= wpas_ctrl_nfc_get_handover_req(
4970 wpa_s
, buf
+ 21, reply
, reply_size
);
4971 } else if (os_strncmp(buf
, "NFC_GET_HANDOVER_SEL ", 21) == 0) {
4972 reply_len
= wpas_ctrl_nfc_get_handover_sel(
4973 wpa_s
, buf
+ 21, reply
, reply_size
);
4974 } else if (os_strncmp(buf
, "NFC_RX_HANDOVER_REQ ", 20) == 0) {
4975 reply_len
= wpas_ctrl_nfc_rx_handover_req(
4976 wpa_s
, buf
+ 20, reply
, reply_size
);
4977 } else if (os_strncmp(buf
, "NFC_RX_HANDOVER_SEL ", 20) == 0) {
4978 if (wpas_ctrl_nfc_rx_handover_sel(wpa_s
, buf
+ 20))
4980 } else if (os_strncmp(buf
, "NFC_REPORT_HANDOVER ", 20) == 0) {
4981 if (wpas_ctrl_nfc_report_handover(wpa_s
, buf
+ 20))
4983 #endif /* CONFIG_WPS_NFC */
4984 } else if (os_strncmp(buf
, "WPS_REG ", 8) == 0) {
4985 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s
, buf
+ 8))
4988 } else if (os_strncmp(buf
, "WPS_AP_PIN ", 11) == 0) {
4989 reply_len
= wpa_supplicant_ctrl_iface_wps_ap_pin(
4990 wpa_s
, buf
+ 11, reply
, reply_size
);
4991 #endif /* CONFIG_AP */
4992 #ifdef CONFIG_WPS_ER
4993 } else if (os_strcmp(buf
, "WPS_ER_START") == 0) {
4994 if (wpas_wps_er_start(wpa_s
, NULL
))
4996 } else if (os_strncmp(buf
, "WPS_ER_START ", 13) == 0) {
4997 if (wpas_wps_er_start(wpa_s
, buf
+ 13))
4999 } else if (os_strcmp(buf
, "WPS_ER_STOP") == 0) {
5000 if (wpas_wps_er_stop(wpa_s
))
5002 } else if (os_strncmp(buf
, "WPS_ER_PIN ", 11) == 0) {
5003 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s
, buf
+ 11))
5005 } else if (os_strncmp(buf
, "WPS_ER_PBC ", 11) == 0) {
5006 int ret
= wpas_wps_er_pbc(wpa_s
, buf
+ 11);
5008 os_memcpy(reply
, "FAIL-PBC-OVERLAP\n", 17);
5010 } else if (ret
== -3) {
5011 os_memcpy(reply
, "FAIL-UNKNOWN-UUID\n", 18);
5013 } else if (ret
== -4) {
5014 os_memcpy(reply
, "FAIL-NO-AP-SETTINGS\n", 20);
5018 } else if (os_strncmp(buf
, "WPS_ER_LEARN ", 13) == 0) {
5019 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s
, buf
+ 13))
5021 } else if (os_strncmp(buf
, "WPS_ER_SET_CONFIG ", 18) == 0) {
5022 if (wpa_supplicant_ctrl_iface_wps_er_set_config(wpa_s
,
5025 } else if (os_strncmp(buf
, "WPS_ER_CONFIG ", 14) == 0) {
5026 if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s
, buf
+ 14))
5028 #ifdef CONFIG_WPS_NFC
5029 } else if (os_strncmp(buf
, "WPS_ER_NFC_CONFIG_TOKEN ", 24) == 0) {
5030 reply_len
= wpa_supplicant_ctrl_iface_wps_er_nfc_config_token(
5031 wpa_s
, buf
+ 24, reply
, reply_size
);
5032 #endif /* CONFIG_WPS_NFC */
5033 #endif /* CONFIG_WPS_ER */
5034 #endif /* CONFIG_WPS */
5035 #ifdef CONFIG_IBSS_RSN
5036 } else if (os_strncmp(buf
, "IBSS_RSN ", 9) == 0) {
5037 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s
, buf
+ 9))
5039 #endif /* CONFIG_IBSS_RSN */
5041 } else if (os_strncmp(buf
, "P2P_FIND ", 9) == 0) {
5042 if (p2p_ctrl_find(wpa_s
, buf
+ 9))
5044 } else if (os_strcmp(buf
, "P2P_FIND") == 0) {
5045 if (p2p_ctrl_find(wpa_s
, ""))
5047 } else if (os_strcmp(buf
, "P2P_STOP_FIND") == 0) {
5048 wpas_p2p_stop_find(wpa_s
);
5049 } else if (os_strncmp(buf
, "P2P_CONNECT ", 12) == 0) {
5050 reply_len
= p2p_ctrl_connect(wpa_s
, buf
+ 12, reply
,
5052 } else if (os_strncmp(buf
, "P2P_LISTEN ", 11) == 0) {
5053 if (p2p_ctrl_listen(wpa_s
, buf
+ 11))
5055 } else if (os_strcmp(buf
, "P2P_LISTEN") == 0) {
5056 if (p2p_ctrl_listen(wpa_s
, ""))
5058 } else if (os_strncmp(buf
, "P2P_GROUP_REMOVE ", 17) == 0) {
5059 if (wpas_p2p_group_remove(wpa_s
, buf
+ 17))
5061 } else if (os_strcmp(buf
, "P2P_GROUP_ADD") == 0) {
5062 if (wpas_p2p_group_add(wpa_s
, 0, 0, 0))
5064 } else if (os_strncmp(buf
, "P2P_GROUP_ADD ", 14) == 0) {
5065 if (p2p_ctrl_group_add(wpa_s
, buf
+ 14))
5067 } else if (os_strncmp(buf
, "P2P_PROV_DISC ", 14) == 0) {
5068 if (p2p_ctrl_prov_disc(wpa_s
, buf
+ 14))
5070 } else if (os_strcmp(buf
, "P2P_GET_PASSPHRASE") == 0) {
5071 reply_len
= p2p_get_passphrase(wpa_s
, reply
, reply_size
);
5072 } else if (os_strncmp(buf
, "P2P_SERV_DISC_REQ ", 18) == 0) {
5073 reply_len
= p2p_ctrl_serv_disc_req(wpa_s
, buf
+ 18, reply
,
5075 } else if (os_strncmp(buf
, "P2P_SERV_DISC_CANCEL_REQ ", 25) == 0) {
5076 if (p2p_ctrl_serv_disc_cancel_req(wpa_s
, buf
+ 25) < 0)
5078 } else if (os_strncmp(buf
, "P2P_SERV_DISC_RESP ", 19) == 0) {
5079 if (p2p_ctrl_serv_disc_resp(wpa_s
, buf
+ 19) < 0)
5081 } else if (os_strcmp(buf
, "P2P_SERVICE_UPDATE") == 0) {
5082 wpas_p2p_sd_service_update(wpa_s
);
5083 } else if (os_strncmp(buf
, "P2P_SERV_DISC_EXTERNAL ", 23) == 0) {
5084 if (p2p_ctrl_serv_disc_external(wpa_s
, buf
+ 23) < 0)
5086 } else if (os_strcmp(buf
, "P2P_SERVICE_FLUSH") == 0) {
5087 wpas_p2p_service_flush(wpa_s
);
5088 } else if (os_strncmp(buf
, "P2P_SERVICE_ADD ", 16) == 0) {
5089 if (p2p_ctrl_service_add(wpa_s
, buf
+ 16) < 0)
5091 } else if (os_strncmp(buf
, "P2P_SERVICE_DEL ", 16) == 0) {
5092 if (p2p_ctrl_service_del(wpa_s
, buf
+ 16) < 0)
5094 } else if (os_strncmp(buf
, "P2P_REJECT ", 11) == 0) {
5095 if (p2p_ctrl_reject(wpa_s
, buf
+ 11) < 0)
5097 } else if (os_strncmp(buf
, "P2P_INVITE ", 11) == 0) {
5098 if (p2p_ctrl_invite(wpa_s
, buf
+ 11) < 0)
5100 } else if (os_strncmp(buf
, "P2P_PEER ", 9) == 0) {
5101 reply_len
= p2p_ctrl_peer(wpa_s
, buf
+ 9, reply
,
5103 } else if (os_strncmp(buf
, "P2P_SET ", 8) == 0) {
5104 if (p2p_ctrl_set(wpa_s
, buf
+ 8) < 0)
5106 } else if (os_strcmp(buf
, "P2P_FLUSH") == 0) {
5107 os_memset(wpa_s
->p2p_auth_invite
, 0, ETH_ALEN
);
5108 wpa_s
->force_long_sd
= 0;
5109 if (wpa_s
->global
->p2p
)
5110 p2p_flush(wpa_s
->global
->p2p
);
5111 } else if (os_strncmp(buf
, "P2P_UNAUTHORIZE ", 16) == 0) {
5112 if (wpas_p2p_unauthorize(wpa_s
, buf
+ 16) < 0)
5114 } else if (os_strcmp(buf
, "P2P_CANCEL") == 0) {
5115 if (wpas_p2p_cancel(wpa_s
))
5117 } else if (os_strncmp(buf
, "P2P_PRESENCE_REQ ", 17) == 0) {
5118 if (p2p_ctrl_presence_req(wpa_s
, buf
+ 17) < 0)
5120 } else if (os_strcmp(buf
, "P2P_PRESENCE_REQ") == 0) {
5121 if (p2p_ctrl_presence_req(wpa_s
, "") < 0)
5123 } else if (os_strncmp(buf
, "P2P_EXT_LISTEN ", 15) == 0) {
5124 if (p2p_ctrl_ext_listen(wpa_s
, buf
+ 15) < 0)
5126 } else if (os_strcmp(buf
, "P2P_EXT_LISTEN") == 0) {
5127 if (p2p_ctrl_ext_listen(wpa_s
, "") < 0)
5129 #endif /* CONFIG_P2P */
5130 #ifdef CONFIG_WIFI_DISPLAY
5131 } else if (os_strncmp(buf
, "WFD_SUBELEM_SET ", 16) == 0) {
5132 if (wifi_display_subelem_set(wpa_s
->global
, buf
+ 16) < 0)
5134 } else if (os_strncmp(buf
, "WFD_SUBELEM_GET ", 16) == 0) {
5135 reply_len
= wifi_display_subelem_get(wpa_s
->global
, buf
+ 16,
5137 #endif /* CONFIG_WIFI_DISPLAY */
5138 #ifdef CONFIG_INTERWORKING
5139 } else if (os_strcmp(buf
, "FETCH_ANQP") == 0) {
5140 if (interworking_fetch_anqp(wpa_s
) < 0)
5142 } else if (os_strcmp(buf
, "STOP_FETCH_ANQP") == 0) {
5143 interworking_stop_fetch_anqp(wpa_s
);
5144 } else if (os_strncmp(buf
, "INTERWORKING_SELECT", 19) == 0) {
5145 if (interworking_select(wpa_s
, os_strstr(buf
+ 19, "auto") !=
5148 } else if (os_strncmp(buf
, "INTERWORKING_CONNECT ", 21) == 0) {
5149 if (ctrl_interworking_connect(wpa_s
, buf
+ 21) < 0)
5151 } else if (os_strncmp(buf
, "ANQP_GET ", 9) == 0) {
5152 if (get_anqp(wpa_s
, buf
+ 9) < 0)
5154 } else if (os_strncmp(buf
, "GAS_REQUEST ", 12) == 0) {
5155 if (gas_request(wpa_s
, buf
+ 12) < 0)
5157 } else if (os_strncmp(buf
, "GAS_RESPONSE_GET ", 17) == 0) {
5158 reply_len
= gas_response_get(wpa_s
, buf
+ 17, reply
,
5160 #endif /* CONFIG_INTERWORKING */
5162 } else if (os_strncmp(buf
, "HS20_ANQP_GET ", 14) == 0) {
5163 if (get_hs20_anqp(wpa_s
, buf
+ 14) < 0)
5165 } else if (os_strncmp(buf
, "HS20_GET_NAI_HOME_REALM_LIST ", 29) == 0) {
5166 if (hs20_get_nai_home_realm_list(wpa_s
, buf
+ 29) < 0)
5168 #endif /* CONFIG_HS20 */
5169 } else if (os_strncmp(buf
, WPA_CTRL_RSP
, os_strlen(WPA_CTRL_RSP
)) == 0)
5171 if (wpa_supplicant_ctrl_iface_ctrl_rsp(
5172 wpa_s
, buf
+ os_strlen(WPA_CTRL_RSP
)))
5176 } else if (os_strcmp(buf
, "RECONFIGURE") == 0) {
5177 if (wpa_supplicant_reload_configuration(wpa_s
))
5179 } else if (os_strcmp(buf
, "TERMINATE") == 0) {
5180 wpa_supplicant_terminate_proc(wpa_s
->global
);
5181 } else if (os_strncmp(buf
, "BSSID ", 6) == 0) {
5182 if (wpa_supplicant_ctrl_iface_bssid(wpa_s
, buf
+ 6))
5184 } else if (os_strncmp(buf
, "BLACKLIST", 9) == 0) {
5185 reply_len
= wpa_supplicant_ctrl_iface_blacklist(
5186 wpa_s
, buf
+ 9, reply
, reply_size
);
5187 } else if (os_strncmp(buf
, "LOG_LEVEL", 9) == 0) {
5188 reply_len
= wpa_supplicant_ctrl_iface_log_level(
5189 wpa_s
, buf
+ 9, reply
, reply_size
);
5190 } else if (os_strcmp(buf
, "LIST_NETWORKS") == 0) {
5191 reply_len
= wpa_supplicant_ctrl_iface_list_networks(
5192 wpa_s
, reply
, reply_size
);
5193 } else if (os_strcmp(buf
, "DISCONNECT") == 0) {
5195 wpa_s
->sme
.prev_bssid_set
= 0;
5196 #endif /* CONFIG_SME */
5197 wpa_s
->reassociate
= 0;
5198 wpa_s
->disconnected
= 1;
5199 wpa_supplicant_cancel_sched_scan(wpa_s
);
5200 wpa_supplicant_cancel_scan(wpa_s
);
5201 wpa_supplicant_deauthenticate(wpa_s
,
5202 WLAN_REASON_DEAUTH_LEAVING
);
5203 } else if (os_strcmp(buf
, "SCAN") == 0 ||
5204 os_strncmp(buf
, "SCAN ", 5) == 0) {
5205 if (wpa_s
->wpa_state
== WPA_INTERFACE_DISABLED
)
5208 if (os_strlen(buf
) > 4 &&
5209 os_strncasecmp(buf
+ 5, "TYPE=ONLY", 9) == 0)
5210 wpa_s
->scan_res_handler
= scan_only_handler
;
5211 if (!wpa_s
->sched_scanning
&& !wpa_s
->scanning
&&
5212 ((wpa_s
->wpa_state
<= WPA_SCANNING
) ||
5213 (wpa_s
->wpa_state
== WPA_COMPLETED
))) {
5214 wpa_s
->normal_scans
= 0;
5215 wpa_s
->scan_req
= MANUAL_SCAN_REQ
;
5216 wpa_supplicant_req_scan(wpa_s
, 0, 0);
5217 } else if (wpa_s
->sched_scanning
) {
5218 wpa_printf(MSG_DEBUG
, "Stop ongoing "
5219 "sched_scan to allow requested "
5220 "full scan to proceed");
5221 wpa_supplicant_cancel_sched_scan(wpa_s
);
5222 wpa_s
->scan_req
= MANUAL_SCAN_REQ
;
5223 wpa_supplicant_req_scan(wpa_s
, 0, 0);
5225 wpa_printf(MSG_DEBUG
, "Ongoing scan action - "
5226 "reject new request");
5227 reply_len
= os_snprintf(reply
, reply_size
,
5231 } else if (os_strcmp(buf
, "SCAN_RESULTS") == 0) {
5232 reply_len
= wpa_supplicant_ctrl_iface_scan_results(
5233 wpa_s
, reply
, reply_size
);
5234 } else if (os_strncmp(buf
, "SELECT_NETWORK ", 15) == 0) {
5235 if (wpa_supplicant_ctrl_iface_select_network(wpa_s
, buf
+ 15))
5237 } else if (os_strncmp(buf
, "ENABLE_NETWORK ", 15) == 0) {
5238 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s
, buf
+ 15))
5240 } else if (os_strncmp(buf
, "DISABLE_NETWORK ", 16) == 0) {
5241 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s
, buf
+ 16))
5243 } else if (os_strcmp(buf
, "ADD_NETWORK") == 0) {
5244 reply_len
= wpa_supplicant_ctrl_iface_add_network(
5245 wpa_s
, reply
, reply_size
);
5246 } else if (os_strncmp(buf
, "REMOVE_NETWORK ", 15) == 0) {
5247 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s
, buf
+ 15))
5249 } else if (os_strncmp(buf
, "SET_NETWORK ", 12) == 0) {
5250 if (wpa_supplicant_ctrl_iface_set_network(wpa_s
, buf
+ 12))
5252 } else if (os_strncmp(buf
, "GET_NETWORK ", 12) == 0) {
5253 reply_len
= wpa_supplicant_ctrl_iface_get_network(
5254 wpa_s
, buf
+ 12, reply
, reply_size
);
5255 } else if (os_strcmp(buf
, "LIST_CREDS") == 0) {
5256 reply_len
= wpa_supplicant_ctrl_iface_list_creds(
5257 wpa_s
, reply
, reply_size
);
5258 } else if (os_strcmp(buf
, "ADD_CRED") == 0) {
5259 reply_len
= wpa_supplicant_ctrl_iface_add_cred(
5260 wpa_s
, reply
, reply_size
);
5261 } else if (os_strncmp(buf
, "REMOVE_CRED ", 12) == 0) {
5262 if (wpa_supplicant_ctrl_iface_remove_cred(wpa_s
, buf
+ 12))
5264 } else if (os_strncmp(buf
, "SET_CRED ", 9) == 0) {
5265 if (wpa_supplicant_ctrl_iface_set_cred(wpa_s
, buf
+ 9))
5267 #ifndef CONFIG_NO_CONFIG_WRITE
5268 } else if (os_strcmp(buf
, "SAVE_CONFIG") == 0) {
5269 if (wpa_supplicant_ctrl_iface_save_config(wpa_s
))
5271 #endif /* CONFIG_NO_CONFIG_WRITE */
5272 } else if (os_strncmp(buf
, "GET_CAPABILITY ", 15) == 0) {
5273 reply_len
= wpa_supplicant_ctrl_iface_get_capability(
5274 wpa_s
, buf
+ 15, reply
, reply_size
);
5275 } else if (os_strncmp(buf
, "AP_SCAN ", 8) == 0) {
5276 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s
, buf
+ 8))
5278 } else if (os_strncmp(buf
, "SCAN_INTERVAL ", 14) == 0) {
5279 if (wpa_supplicant_ctrl_iface_scan_interval(wpa_s
, buf
+ 14))
5281 } else if (os_strcmp(buf
, "INTERFACE_LIST") == 0) {
5282 reply_len
= wpa_supplicant_global_iface_list(
5283 wpa_s
->global
, reply
, reply_size
);
5284 } else if (os_strcmp(buf
, "INTERFACES") == 0) {
5285 reply_len
= wpa_supplicant_global_iface_interfaces(
5286 wpa_s
->global
, reply
, reply_size
);
5287 } else if (os_strncmp(buf
, "BSS ", 4) == 0) {
5288 reply_len
= wpa_supplicant_ctrl_iface_bss(
5289 wpa_s
, buf
+ 4, reply
, reply_size
);
5291 } else if (os_strcmp(buf
, "STA-FIRST") == 0) {
5292 reply_len
= ap_ctrl_iface_sta_first(wpa_s
, reply
, reply_size
);
5293 } else if (os_strncmp(buf
, "STA ", 4) == 0) {
5294 reply_len
= ap_ctrl_iface_sta(wpa_s
, buf
+ 4, reply
,
5296 } else if (os_strncmp(buf
, "STA-NEXT ", 9) == 0) {
5297 reply_len
= ap_ctrl_iface_sta_next(wpa_s
, buf
+ 9, reply
,
5299 } else if (os_strncmp(buf
, "DEAUTHENTICATE ", 15) == 0) {
5300 if (ap_ctrl_iface_sta_deauthenticate(wpa_s
, buf
+ 15))
5302 } else if (os_strncmp(buf
, "DISASSOCIATE ", 13) == 0) {
5303 if (ap_ctrl_iface_sta_disassociate(wpa_s
, buf
+ 13))
5305 #endif /* CONFIG_AP */
5306 } else if (os_strcmp(buf
, "SUSPEND") == 0) {
5307 wpas_notify_suspend(wpa_s
->global
);
5308 } else if (os_strcmp(buf
, "RESUME") == 0) {
5309 wpas_notify_resume(wpa_s
->global
);
5310 } else if (os_strcmp(buf
, "DROP_SA") == 0) {
5311 wpa_supplicant_ctrl_iface_drop_sa(wpa_s
);
5312 } else if (os_strncmp(buf
, "ROAM ", 5) == 0) {
5313 if (wpa_supplicant_ctrl_iface_roam(wpa_s
, buf
+ 5))
5315 } else if (os_strncmp(buf
, "STA_AUTOCONNECT ", 16) == 0) {
5316 if (wpa_supplicant_ctrl_iface_sta_autoconnect(wpa_s
, buf
+ 16))
5318 } else if (os_strncmp(buf
, "BSS_EXPIRE_AGE ", 15) == 0) {
5319 if (wpa_supplicant_ctrl_iface_bss_expire_age(wpa_s
, buf
+ 15))
5321 } else if (os_strncmp(buf
, "BSS_EXPIRE_COUNT ", 17) == 0) {
5322 if (wpa_supplicant_ctrl_iface_bss_expire_count(wpa_s
,
5325 } else if (os_strncmp(buf
, "BSS_FLUSH ", 10) == 0) {
5326 if (wpa_supplicant_ctrl_iface_bss_flush(wpa_s
, buf
+ 10))
5329 } else if (os_strncmp(buf
, "TDLS_DISCOVER ", 14) == 0) {
5330 if (wpa_supplicant_ctrl_iface_tdls_discover(wpa_s
, buf
+ 14))
5332 } else if (os_strncmp(buf
, "TDLS_SETUP ", 11) == 0) {
5333 if (wpa_supplicant_ctrl_iface_tdls_setup(wpa_s
, buf
+ 11))
5335 } else if (os_strncmp(buf
, "TDLS_TEARDOWN ", 14) == 0) {
5336 if (wpa_supplicant_ctrl_iface_tdls_teardown(wpa_s
, buf
+ 14))
5338 #endif /* CONFIG_TDLS */
5339 } else if (os_strncmp(buf
, "SIGNAL_POLL", 11) == 0) {
5340 reply_len
= wpa_supplicant_signal_poll(wpa_s
, reply
,
5342 } else if (os_strncmp(buf
, "PKTCNT_POLL", 11) == 0) {
5343 reply_len
= wpa_supplicant_pktcnt_poll(wpa_s
, reply
,
5345 #ifdef CONFIG_AUTOSCAN
5346 } else if (os_strncmp(buf
, "AUTOSCAN ", 9) == 0) {
5347 if (wpa_supplicant_ctrl_iface_autoscan(wpa_s
, buf
+ 9))
5349 #endif /* CONFIG_AUTOSCAN */
5350 } else if (os_strcmp(buf
, "REAUTHENTICATE") == 0) {
5351 pmksa_cache_clear_current(wpa_s
->wpa
);
5352 eapol_sm_request_reauth(wpa_s
->eapol
);
5354 } else if (os_strncmp(buf
, "WNM_SLEEP ", 10) == 0) {
5355 if (wpas_ctrl_iface_wnm_sleep(wpa_s
, buf
+ 10))
5357 #endif /* CONFIG_WNM */
5359 os_memcpy(reply
, "UNKNOWN COMMAND\n", 16);
5363 if (reply_len
< 0) {
5364 os_memcpy(reply
, "FAIL\n", 5);
5369 eapol_sm_notify_ctrl_response(wpa_s
->eapol
);
5371 *resp_len
= reply_len
;
5376 static int wpa_supplicant_global_iface_add(struct wpa_global
*global
,
5379 struct wpa_interface iface
;
5383 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
5384 * TAB<bridge_ifname>
5386 wpa_printf(MSG_DEBUG
, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd
);
5388 os_memset(&iface
, 0, sizeof(iface
));
5391 iface
.ifname
= pos
= cmd
;
5392 pos
= os_strchr(pos
, '\t');
5395 if (iface
.ifname
[0] == '\0')
5400 iface
.confname
= pos
;
5401 pos
= os_strchr(pos
, '\t');
5404 if (iface
.confname
[0] == '\0')
5405 iface
.confname
= NULL
;
5410 pos
= os_strchr(pos
, '\t');
5413 if (iface
.driver
[0] == '\0')
5414 iface
.driver
= NULL
;
5418 iface
.ctrl_interface
= pos
;
5419 pos
= os_strchr(pos
, '\t');
5422 if (iface
.ctrl_interface
[0] == '\0')
5423 iface
.ctrl_interface
= NULL
;
5427 iface
.driver_param
= pos
;
5428 pos
= os_strchr(pos
, '\t');
5431 if (iface
.driver_param
[0] == '\0')
5432 iface
.driver_param
= NULL
;
5436 iface
.bridge_ifname
= pos
;
5437 pos
= os_strchr(pos
, '\t');
5440 if (iface
.bridge_ifname
[0] == '\0')
5441 iface
.bridge_ifname
= NULL
;
5446 if (wpa_supplicant_get_iface(global
, iface
.ifname
))
5449 return wpa_supplicant_add_iface(global
, &iface
) ? 0 : -1;
5453 static int wpa_supplicant_global_iface_remove(struct wpa_global
*global
,
5456 struct wpa_supplicant
*wpa_s
;
5458 wpa_printf(MSG_DEBUG
, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd
);
5460 wpa_s
= wpa_supplicant_get_iface(global
, cmd
);
5463 return wpa_supplicant_remove_iface(global
, wpa_s
, 0);
5467 static void wpa_free_iface_info(struct wpa_interface_info
*iface
)
5469 struct wpa_interface_info
*prev
;
5473 iface
= iface
->next
;
5475 os_free(prev
->ifname
);
5476 os_free(prev
->desc
);
5482 static int wpa_supplicant_global_iface_list(struct wpa_global
*global
,
5486 struct wpa_interface_info
*iface
= NULL
, *last
= NULL
, *tmp
;
5489 for (i
= 0; wpa_drivers
[i
]; i
++) {
5490 struct wpa_driver_ops
*drv
= wpa_drivers
[i
];
5491 if (drv
->get_interfaces
== NULL
)
5493 tmp
= drv
->get_interfaces(global
->drv_priv
[i
]);
5507 for (tmp
= iface
; tmp
; tmp
= tmp
->next
) {
5508 res
= os_snprintf(pos
, end
- pos
, "%s\t%s\t%s\n",
5509 tmp
->drv_name
, tmp
->ifname
,
5510 tmp
->desc
? tmp
->desc
: "");
5511 if (res
< 0 || res
>= end
- pos
) {
5518 wpa_free_iface_info(iface
);
5524 static int wpa_supplicant_global_iface_interfaces(struct wpa_global
*global
,
5529 struct wpa_supplicant
*wpa_s
;
5531 wpa_s
= global
->ifaces
;
5536 res
= os_snprintf(pos
, end
- pos
, "%s\n", wpa_s
->ifname
);
5537 if (res
< 0 || res
>= end
- pos
) {
5542 wpa_s
= wpa_s
->next
;
5548 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global
*global
,
5549 char *buf
, size_t *resp_len
)
5552 const int reply_size
= 2048;
5554 int level
= MSG_DEBUG
;
5556 if (os_strcmp(buf
, "PING") == 0)
5557 level
= MSG_EXCESSIVE
;
5558 wpa_hexdump_ascii(level
, "RX global ctrl_iface",
5559 (const u8
*) buf
, os_strlen(buf
));
5561 reply
= os_malloc(reply_size
);
5562 if (reply
== NULL
) {
5567 os_memcpy(reply
, "OK\n", 3);
5570 if (os_strcmp(buf
, "PING") == 0) {
5571 os_memcpy(reply
, "PONG\n", 5);
5573 } else if (os_strncmp(buf
, "INTERFACE_ADD ", 14) == 0) {
5574 if (wpa_supplicant_global_iface_add(global
, buf
+ 14))
5576 } else if (os_strncmp(buf
, "INTERFACE_REMOVE ", 17) == 0) {
5577 if (wpa_supplicant_global_iface_remove(global
, buf
+ 17))
5579 } else if (os_strcmp(buf
, "INTERFACE_LIST") == 0) {
5580 reply_len
= wpa_supplicant_global_iface_list(
5581 global
, reply
, reply_size
);
5582 } else if (os_strcmp(buf
, "INTERFACES") == 0) {
5583 reply_len
= wpa_supplicant_global_iface_interfaces(
5584 global
, reply
, reply_size
);
5585 } else if (os_strcmp(buf
, "TERMINATE") == 0) {
5586 wpa_supplicant_terminate_proc(global
);
5587 } else if (os_strcmp(buf
, "SUSPEND") == 0) {
5588 wpas_notify_suspend(global
);
5589 } else if (os_strcmp(buf
, "RESUME") == 0) {
5590 wpas_notify_resume(global
);
5592 os_memcpy(reply
, "UNKNOWN COMMAND\n", 16);
5596 if (reply_len
< 0) {
5597 os_memcpy(reply
, "FAIL\n", 5);
5601 *resp_len
= reply_len
;