2 * WPA Supplicant / Control interface (shared code for all backends)
3 * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
15 #include "utils/includes.h"
17 #include "utils/common.h"
18 #include "utils/eloop.h"
19 #include "common/ieee802_11_defs.h"
20 #include "common/wpa_ctrl.h"
21 #include "eap_peer/eap.h"
22 #include "eapol_supp/eapol_supp_sm.h"
23 #include "rsn_supp/wpa.h"
24 #include "rsn_supp/preauth.h"
25 #include "rsn_supp/pmksa_cache.h"
26 #include "l2_packet/l2_packet.h"
29 #include "wpa_supplicant_i.h"
31 #include "wps_supplicant.h"
34 #include "p2p_supplicant.h"
39 #include "ctrl_iface.h"
41 extern struct wpa_driver_ops
*wpa_drivers
[];
43 static int wpa_supplicant_global_iface_list(struct wpa_global
*global
,
45 static int wpa_supplicant_global_iface_interfaces(struct wpa_global
*global
,
49 static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant
*wpa_s
,
55 value
= os_strchr(cmd
, ' ');
60 wpa_printf(MSG_DEBUG
, "CTRL_IFACE SET '%s'='%s'", cmd
, value
);
61 if (os_strcasecmp(cmd
, "EAPOL::heldPeriod") == 0) {
62 eapol_sm_configure(wpa_s
->eapol
,
63 atoi(value
), -1, -1, -1);
64 } else if (os_strcasecmp(cmd
, "EAPOL::authPeriod") == 0) {
65 eapol_sm_configure(wpa_s
->eapol
,
66 -1, atoi(value
), -1, -1);
67 } else if (os_strcasecmp(cmd
, "EAPOL::startPeriod") == 0) {
68 eapol_sm_configure(wpa_s
->eapol
,
69 -1, -1, atoi(value
), -1);
70 } else if (os_strcasecmp(cmd
, "EAPOL::maxStart") == 0) {
71 eapol_sm_configure(wpa_s
->eapol
,
72 -1, -1, -1, atoi(value
));
73 } else if (os_strcasecmp(cmd
, "dot11RSNAConfigPMKLifetime") == 0) {
74 if (wpa_sm_set_param(wpa_s
->wpa
, RSNA_PMK_LIFETIME
,
77 } else if (os_strcasecmp(cmd
, "dot11RSNAConfigPMKReauthThreshold") ==
79 if (wpa_sm_set_param(wpa_s
->wpa
, RSNA_PMK_REAUTH_THRESHOLD
,
82 } else if (os_strcasecmp(cmd
, "dot11RSNAConfigSATimeout") == 0) {
83 if (wpa_sm_set_param(wpa_s
->wpa
, RSNA_SA_TIMEOUT
, atoi(value
)))
85 } else if (os_strcasecmp(cmd
, "wps_fragment_size") == 0) {
86 wpa_s
->wps_fragment_size
= atoi(value
);
89 ret
= wpa_config_process_global(wpa_s
->conf
, cmd
, -1);
91 wpa_supplicant_update_config(wpa_s
);
98 #ifdef IEEE8021X_EAPOL
99 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant
*wpa_s
,
103 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
105 if (hwaddr_aton(addr
, bssid
)) {
106 wpa_printf(MSG_DEBUG
, "CTRL_IFACE PREAUTH: invalid address "
111 wpa_printf(MSG_DEBUG
, "CTRL_IFACE PREAUTH " MACSTR
, MAC2STR(bssid
));
112 rsn_preauth_deinit(wpa_s
->wpa
);
113 if (rsn_preauth_init(wpa_s
->wpa
, bssid
, ssid
? &ssid
->eap
: NULL
))
118 #endif /* IEEE8021X_EAPOL */
121 #ifdef CONFIG_PEERKEY
122 /* MLME-STKSTART.request(peer) */
123 static int wpa_supplicant_ctrl_iface_stkstart(
124 struct wpa_supplicant
*wpa_s
, char *addr
)
128 if (hwaddr_aton(addr
, peer
)) {
129 wpa_printf(MSG_DEBUG
, "CTRL_IFACE STKSTART: invalid "
130 "address '%s'", addr
);
134 wpa_printf(MSG_DEBUG
, "CTRL_IFACE STKSTART " MACSTR
,
137 return wpa_sm_stkstart(wpa_s
->wpa
, peer
);
139 #endif /* CONFIG_PEERKEY */
142 #ifdef CONFIG_IEEE80211R
143 static int wpa_supplicant_ctrl_iface_ft_ds(
144 struct wpa_supplicant
*wpa_s
, char *addr
)
146 u8 target_ap
[ETH_ALEN
];
150 if (hwaddr_aton(addr
, target_ap
)) {
151 wpa_printf(MSG_DEBUG
, "CTRL_IFACE FT_DS: invalid "
152 "address '%s'", addr
);
156 wpa_printf(MSG_DEBUG
, "CTRL_IFACE FT_DS " MACSTR
, MAC2STR(target_ap
));
158 bss
= wpa_bss_get_bssid(wpa_s
, target_ap
);
160 mdie
= wpa_bss_get_ie(bss
, WLAN_EID_MOBILITY_DOMAIN
);
164 return wpa_ft_start_over_ds(wpa_s
->wpa
, target_ap
, mdie
);
166 #endif /* CONFIG_IEEE80211R */
170 static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant
*wpa_s
,
173 u8 bssid
[ETH_ALEN
], *_bssid
= bssid
;
175 if (cmd
== NULL
|| os_strcmp(cmd
, "any") == 0)
177 else if (hwaddr_aton(cmd
, bssid
)) {
178 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
185 return wpa_supplicant_ap_wps_pbc(wpa_s
, _bssid
);
186 #endif /* CONFIG_AP */
188 return wpas_wps_start_pbc(wpa_s
, _bssid
, 0);
192 static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant
*wpa_s
,
193 char *cmd
, char *buf
,
196 u8 bssid
[ETH_ALEN
], *_bssid
= bssid
;
200 pin
= os_strchr(cmd
, ' ');
204 if (os_strcmp(cmd
, "any") == 0)
206 else if (hwaddr_aton(cmd
, bssid
)) {
207 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
214 return wpa_supplicant_ap_wps_pin(wpa_s
, _bssid
, pin
,
216 #endif /* CONFIG_AP */
219 ret
= wpas_wps_start_pin(wpa_s
, _bssid
, pin
, 0,
223 ret
= os_snprintf(buf
, buflen
, "%s", pin
);
224 if (ret
< 0 || (size_t) ret
>= buflen
)
229 ret
= wpas_wps_start_pin(wpa_s
, _bssid
, NULL
, 0, DEV_PW_DEFAULT
);
233 /* Return the generated PIN */
234 ret
= os_snprintf(buf
, buflen
, "%08d", ret
);
235 if (ret
< 0 || (size_t) ret
>= buflen
)
241 #ifdef CONFIG_WPS_OOB
242 static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant
*wpa_s
,
245 char *path
, *method
, *name
;
247 path
= os_strchr(cmd
, ' ');
252 method
= os_strchr(path
, ' ');
257 name
= os_strchr(method
, ' ');
261 return wpas_wps_start_oob(wpa_s
, cmd
, path
, method
, name
);
263 #endif /* CONFIG_WPS_OOB */
266 static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant
*wpa_s
,
269 u8 bssid
[ETH_ALEN
], *_bssid
= bssid
;
275 struct wps_new_ap_settings ap
;
277 pin
= os_strchr(cmd
, ' ');
282 if (os_strcmp(cmd
, "any") == 0)
284 else if (hwaddr_aton(cmd
, bssid
)) {
285 wpa_printf(MSG_DEBUG
, "CTRL_IFACE WPS_REG: invalid BSSID '%s'",
290 new_ssid
= os_strchr(pin
, ' ');
291 if (new_ssid
== NULL
)
292 return wpas_wps_start_reg(wpa_s
, _bssid
, pin
, NULL
);
295 new_auth
= os_strchr(new_ssid
, ' ');
296 if (new_auth
== NULL
)
300 new_encr
= os_strchr(new_auth
, ' ');
301 if (new_encr
== NULL
)
305 new_key
= os_strchr(new_encr
, ' ');
310 os_memset(&ap
, 0, sizeof(ap
));
311 ap
.ssid_hex
= new_ssid
;
314 ap
.key_hex
= new_key
;
315 return wpas_wps_start_reg(wpa_s
, _bssid
, pin
, &ap
);
320 static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant
*wpa_s
,
323 char *uuid
= cmd
, *pin
, *pos
;
324 u8 addr_buf
[ETH_ALEN
], *addr
= NULL
;
325 pin
= os_strchr(uuid
, ' ');
329 pos
= os_strchr(pin
, ' ');
332 if (hwaddr_aton(pos
, addr_buf
) == 0)
335 return wpas_wps_er_add_pin(wpa_s
, addr
, uuid
, pin
);
339 static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant
*wpa_s
,
342 char *uuid
= cmd
, *pin
;
343 pin
= os_strchr(uuid
, ' ');
347 return wpas_wps_er_learn(wpa_s
, uuid
, pin
);
351 static int wpa_supplicant_ctrl_iface_wps_er_config(
352 struct wpa_supplicant
*wpa_s
, char *cmd
)
359 struct wps_new_ap_settings ap
;
361 pin
= os_strchr(cmd
, ' ');
366 new_ssid
= os_strchr(pin
, ' ');
367 if (new_ssid
== NULL
)
371 new_auth
= os_strchr(new_ssid
, ' ');
372 if (new_auth
== NULL
)
376 new_encr
= os_strchr(new_auth
, ' ');
377 if (new_encr
== NULL
)
381 new_key
= os_strchr(new_encr
, ' ');
386 os_memset(&ap
, 0, sizeof(ap
));
387 ap
.ssid_hex
= new_ssid
;
390 ap
.key_hex
= new_key
;
391 return wpas_wps_er_config(wpa_s
, cmd
, pin
, &ap
);
393 #endif /* CONFIG_WPS_ER */
395 #endif /* CONFIG_WPS */
398 #ifdef CONFIG_IBSS_RSN
399 static int wpa_supplicant_ctrl_iface_ibss_rsn(
400 struct wpa_supplicant
*wpa_s
, char *addr
)
404 if (hwaddr_aton(addr
, peer
)) {
405 wpa_printf(MSG_DEBUG
, "CTRL_IFACE IBSS_RSN: invalid "
406 "address '%s'", addr
);
410 wpa_printf(MSG_DEBUG
, "CTRL_IFACE IBSS_RSN " MACSTR
,
413 return ibss_rsn_start(wpa_s
->ibss_rsn
, peer
);
415 #endif /* CONFIG_IBSS_RSN */
418 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant
*wpa_s
,
421 #ifdef IEEE8021X_EAPOL
424 struct wpa_ssid
*ssid
;
425 struct eap_peer_config
*eap
;
427 pos
= os_strchr(rsp
, '-');
432 pos
= os_strchr(pos
, ':');
437 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: field=%s id=%d", rsp
, id
);
438 wpa_hexdump_ascii_key(MSG_DEBUG
, "CTRL_IFACE: value",
439 (u8
*) pos
, os_strlen(pos
));
441 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
443 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
449 if (os_strcmp(rsp
, "IDENTITY") == 0) {
450 os_free(eap
->identity
);
451 eap
->identity
= (u8
*) os_strdup(pos
);
452 eap
->identity_len
= os_strlen(pos
);
453 eap
->pending_req_identity
= 0;
454 if (ssid
== wpa_s
->current_ssid
)
455 wpa_s
->reassociate
= 1;
456 } else if (os_strcmp(rsp
, "PASSWORD") == 0) {
457 os_free(eap
->password
);
458 eap
->password
= (u8
*) os_strdup(pos
);
459 eap
->password_len
= os_strlen(pos
);
460 eap
->pending_req_password
= 0;
461 if (ssid
== wpa_s
->current_ssid
)
462 wpa_s
->reassociate
= 1;
463 } else if (os_strcmp(rsp
, "NEW_PASSWORD") == 0) {
464 os_free(eap
->new_password
);
465 eap
->new_password
= (u8
*) os_strdup(pos
);
466 eap
->new_password_len
= os_strlen(pos
);
467 eap
->pending_req_new_password
= 0;
468 if (ssid
== wpa_s
->current_ssid
)
469 wpa_s
->reassociate
= 1;
470 } else if (os_strcmp(rsp
, "PIN") == 0) {
472 eap
->pin
= os_strdup(pos
);
473 eap
->pending_req_pin
= 0;
474 if (ssid
== wpa_s
->current_ssid
)
475 wpa_s
->reassociate
= 1;
476 } else if (os_strcmp(rsp
, "OTP") == 0) {
478 eap
->otp
= (u8
*) os_strdup(pos
);
479 eap
->otp_len
= os_strlen(pos
);
480 os_free(eap
->pending_req_otp
);
481 eap
->pending_req_otp
= NULL
;
482 eap
->pending_req_otp_len
= 0;
483 } else if (os_strcmp(rsp
, "PASSPHRASE") == 0) {
484 os_free(eap
->private_key_passwd
);
485 eap
->private_key_passwd
= (u8
*) os_strdup(pos
);
486 eap
->pending_req_passphrase
= 0;
487 if (ssid
== wpa_s
->current_ssid
)
488 wpa_s
->reassociate
= 1;
490 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Unknown field '%s'", rsp
);
495 #else /* IEEE8021X_EAPOL */
496 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: 802.1X not included");
498 #endif /* IEEE8021X_EAPOL */
502 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant
*wpa_s
,
504 char *buf
, size_t buflen
)
506 char *pos
, *end
, tmp
[30];
507 int res
, verbose
, ret
;
509 verbose
= os_strcmp(params
, "-VERBOSE") == 0;
512 if (wpa_s
->wpa_state
>= WPA_ASSOCIATED
) {
513 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
514 ret
= os_snprintf(pos
, end
- pos
, "bssid=" MACSTR
"\n",
515 MAC2STR(wpa_s
->bssid
));
516 if (ret
< 0 || ret
>= end
- pos
)
520 u8
*_ssid
= ssid
->ssid
;
521 size_t ssid_len
= ssid
->ssid_len
;
522 u8 ssid_buf
[MAX_SSID_LEN
];
524 int _res
= wpa_drv_get_ssid(wpa_s
, ssid_buf
);
531 ret
= os_snprintf(pos
, end
- pos
, "ssid=%s\nid=%d\n",
532 wpa_ssid_txt(_ssid
, ssid_len
),
534 if (ret
< 0 || ret
>= end
- pos
)
539 ret
= os_snprintf(pos
, end
- pos
,
542 if (ret
< 0 || ret
>= end
- pos
)
547 switch (ssid
->mode
) {
548 case WPAS_MODE_INFRA
:
549 ret
= os_snprintf(pos
, end
- pos
,
553 ret
= os_snprintf(pos
, end
- pos
,
557 ret
= os_snprintf(pos
, end
- pos
,
560 case WPAS_MODE_P2P_GO
:
561 ret
= os_snprintf(pos
, end
- pos
,
564 case WPAS_MODE_P2P_GROUP_FORMATION
:
565 ret
= os_snprintf(pos
, end
- pos
,
566 "mode=P2P GO - group "
573 if (ret
< 0 || ret
>= end
- pos
)
579 if (wpa_s
->ap_iface
) {
580 pos
+= ap_ctrl_iface_wpa_get_status(wpa_s
, pos
,
584 #endif /* CONFIG_AP */
585 pos
+= wpa_sm_get_status(wpa_s
->wpa
, pos
, end
- pos
, verbose
);
587 ret
= os_snprintf(pos
, end
- pos
, "wpa_state=%s\n",
588 wpa_supplicant_state_txt(wpa_s
->wpa_state
));
589 if (ret
< 0 || ret
>= end
- pos
)
594 l2_packet_get_ip_addr(wpa_s
->l2
, tmp
, sizeof(tmp
)) >= 0) {
595 ret
= os_snprintf(pos
, end
- pos
, "ip_address=%s\n", tmp
);
596 if (ret
< 0 || ret
>= end
- pos
)
602 if (wpa_s
->global
->p2p
) {
603 ret
= os_snprintf(pos
, end
- pos
, "p2p_device_address=" MACSTR
604 "\n", MAC2STR(wpa_s
->global
->p2p_dev_addr
));
605 if (ret
< 0 || ret
>= end
- pos
)
610 ret
= os_snprintf(pos
, end
- pos
, "address=" MACSTR
"\n",
611 MAC2STR(wpa_s
->own_addr
));
612 if (ret
< 0 || ret
>= end
- pos
)
615 #endif /* CONFIG_P2P */
617 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s
->key_mgmt
) ||
618 wpa_s
->key_mgmt
== WPA_KEY_MGMT_IEEE8021X_NO_WPA
) {
619 res
= eapol_sm_get_status(wpa_s
->eapol
, pos
, end
- pos
,
625 res
= rsn_preauth_get_status(wpa_s
->wpa
, pos
, end
- pos
, verbose
);
633 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant
*wpa_s
,
638 struct wpa_ssid
*ssid
;
641 /* cmd: "<network id> <BSSID>" */
642 pos
= os_strchr(cmd
, ' ');
647 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: id=%d bssid='%s'", id
, pos
);
648 if (hwaddr_aton(pos
, bssid
)) {
649 wpa_printf(MSG_DEBUG
,"CTRL_IFACE: invalid BSSID '%s'", pos
);
653 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
655 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
660 os_memcpy(ssid
->bssid
, bssid
, ETH_ALEN
);
661 ssid
->bssid_set
= !is_zero_ether_addr(bssid
);
667 static int wpa_supplicant_ctrl_iface_list_networks(
668 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
671 struct wpa_ssid
*ssid
;
676 ret
= os_snprintf(pos
, end
- pos
,
677 "network id / ssid / bssid / flags\n");
678 if (ret
< 0 || ret
>= end
- pos
)
682 ssid
= wpa_s
->conf
->ssid
;
684 ret
= os_snprintf(pos
, end
- pos
, "%d\t%s",
686 wpa_ssid_txt(ssid
->ssid
, ssid
->ssid_len
));
687 if (ret
< 0 || ret
>= end
- pos
)
690 if (ssid
->bssid_set
) {
691 ret
= os_snprintf(pos
, end
- pos
, "\t" MACSTR
,
692 MAC2STR(ssid
->bssid
));
694 ret
= os_snprintf(pos
, end
- pos
, "\tany");
696 if (ret
< 0 || ret
>= end
- pos
)
699 ret
= os_snprintf(pos
, end
- pos
, "\t%s%s%s",
700 ssid
== wpa_s
->current_ssid
?
702 ssid
->disabled
? "[DISABLED]" : "",
703 ssid
->disabled
== 2 ? "[P2P-PERSISTENT]" :
705 if (ret
< 0 || ret
>= end
- pos
)
708 ret
= os_snprintf(pos
, end
- pos
, "\n");
709 if (ret
< 0 || ret
>= end
- pos
)
720 static char * wpa_supplicant_cipher_txt(char *pos
, char *end
, int cipher
)
723 ret
= os_snprintf(pos
, end
- pos
, "-");
724 if (ret
< 0 || ret
>= end
- pos
)
727 if (cipher
& WPA_CIPHER_NONE
) {
728 ret
= os_snprintf(pos
, end
- pos
, "%sNONE", first
? "" : "+");
729 if (ret
< 0 || ret
>= end
- pos
)
734 if (cipher
& WPA_CIPHER_WEP40
) {
735 ret
= os_snprintf(pos
, end
- pos
, "%sWEP40", first
? "" : "+");
736 if (ret
< 0 || ret
>= end
- pos
)
741 if (cipher
& WPA_CIPHER_WEP104
) {
742 ret
= os_snprintf(pos
, end
- pos
, "%sWEP104",
744 if (ret
< 0 || ret
>= end
- pos
)
749 if (cipher
& WPA_CIPHER_TKIP
) {
750 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : "+");
751 if (ret
< 0 || ret
>= end
- pos
)
756 if (cipher
& WPA_CIPHER_CCMP
) {
757 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : "+");
758 if (ret
< 0 || ret
>= end
- pos
)
767 static char * wpa_supplicant_ie_txt(char *pos
, char *end
, const char *proto
,
768 const u8
*ie
, size_t ie_len
)
770 struct wpa_ie_data data
;
773 ret
= os_snprintf(pos
, end
- pos
, "[%s-", proto
);
774 if (ret
< 0 || ret
>= end
- pos
)
778 if (wpa_parse_wpa_ie(ie
, ie_len
, &data
) < 0) {
779 ret
= os_snprintf(pos
, end
- pos
, "?]");
780 if (ret
< 0 || ret
>= end
- pos
)
787 if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X
) {
788 ret
= os_snprintf(pos
, end
- pos
, "%sEAP", first
? "" : "+");
789 if (ret
< 0 || ret
>= end
- pos
)
794 if (data
.key_mgmt
& WPA_KEY_MGMT_PSK
) {
795 ret
= os_snprintf(pos
, end
- pos
, "%sPSK", first
? "" : "+");
796 if (ret
< 0 || ret
>= end
- pos
)
801 if (data
.key_mgmt
& WPA_KEY_MGMT_WPA_NONE
) {
802 ret
= os_snprintf(pos
, end
- pos
, "%sNone", first
? "" : "+");
803 if (ret
< 0 || ret
>= end
- pos
)
808 #ifdef CONFIG_IEEE80211R
809 if (data
.key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
) {
810 ret
= os_snprintf(pos
, end
- pos
, "%sFT/EAP",
812 if (ret
< 0 || ret
>= end
- pos
)
817 if (data
.key_mgmt
& WPA_KEY_MGMT_FT_PSK
) {
818 ret
= os_snprintf(pos
, end
- pos
, "%sFT/PSK",
820 if (ret
< 0 || ret
>= end
- pos
)
825 #endif /* CONFIG_IEEE80211R */
826 #ifdef CONFIG_IEEE80211W
827 if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
) {
828 ret
= os_snprintf(pos
, end
- pos
, "%sEAP-SHA256",
830 if (ret
< 0 || ret
>= end
- pos
)
835 if (data
.key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
) {
836 ret
= os_snprintf(pos
, end
- pos
, "%sPSK-SHA256",
838 if (ret
< 0 || ret
>= end
- pos
)
843 #endif /* CONFIG_IEEE80211W */
845 pos
= wpa_supplicant_cipher_txt(pos
, end
, data
.pairwise_cipher
);
847 if (data
.capabilities
& WPA_CAPABILITY_PREAUTH
) {
848 ret
= os_snprintf(pos
, end
- pos
, "-preauth");
849 if (ret
< 0 || ret
>= end
- pos
)
854 ret
= os_snprintf(pos
, end
- pos
, "]");
855 if (ret
< 0 || ret
>= end
- pos
)
864 static char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant
*wpa_s
,
865 char *pos
, char *end
,
866 struct wpabuf
*wps_ie
)
873 if (wps_is_selected_pbc_registrar(wps_ie
))
876 else if (wps_is_addr_authorized(wps_ie
, wpa_s
->own_addr
, 0))
878 #endif /* CONFIG_WPS2 */
879 else if (wps_is_selected_pin_registrar(wps_ie
))
884 ret
= os_snprintf(pos
, end
- pos
, "%s", txt
);
885 if (ret
>= 0 && ret
< end
- pos
)
890 #endif /* CONFIG_WPS */
893 static char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant
*wpa_s
,
894 char *pos
, char *end
,
895 const struct wpa_bss
*bss
)
898 struct wpabuf
*wps_ie
;
899 wps_ie
= wpa_bss_get_vendor_ie_multi(bss
, WPS_IE_VENDOR_TYPE
);
900 return wpa_supplicant_wps_ie_txt_buf(wpa_s
, pos
, end
, wps_ie
);
901 #else /* CONFIG_WPS */
903 #endif /* CONFIG_WPS */
907 /* Format one result on one text line into a buffer. */
908 static int wpa_supplicant_ctrl_iface_scan_result(
909 struct wpa_supplicant
*wpa_s
,
910 const struct wpa_bss
*bss
, char *buf
, size_t buflen
)
914 const u8
*ie
, *ie2
, *p2p
;
916 p2p
= wpa_bss_get_vendor_ie(bss
, P2P_IE_VENDOR_TYPE
);
917 if (p2p
&& bss
->ssid_len
== P2P_WILDCARD_SSID_LEN
&&
918 os_memcmp(bss
->ssid
, P2P_WILDCARD_SSID
, P2P_WILDCARD_SSID_LEN
) ==
920 return 0; /* Do not show P2P listen discovery results here */
925 ret
= os_snprintf(pos
, end
- pos
, MACSTR
"\t%d\t%d\t",
926 MAC2STR(bss
->bssid
), bss
->freq
, bss
->level
);
927 if (ret
< 0 || ret
>= end
- pos
)
930 ie
= wpa_bss_get_vendor_ie(bss
, WPA_IE_VENDOR_TYPE
);
932 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA", ie
, 2 + ie
[1]);
933 ie2
= wpa_bss_get_ie(bss
, WLAN_EID_RSN
);
935 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA2", ie2
, 2 + ie2
[1]);
936 pos
= wpa_supplicant_wps_ie_txt(wpa_s
, pos
, end
, bss
);
937 if (!ie
&& !ie2
&& bss
->caps
& IEEE80211_CAP_PRIVACY
) {
938 ret
= os_snprintf(pos
, end
- pos
, "[WEP]");
939 if (ret
< 0 || ret
>= end
- pos
)
943 if (bss
->caps
& IEEE80211_CAP_IBSS
) {
944 ret
= os_snprintf(pos
, end
- pos
, "[IBSS]");
945 if (ret
< 0 || ret
>= end
- pos
)
949 if (bss
->caps
& IEEE80211_CAP_ESS
) {
950 ret
= os_snprintf(pos
, end
- pos
, "[ESS]");
951 if (ret
< 0 || ret
>= end
- pos
)
956 ret
= os_snprintf(pos
, end
- pos
, "[P2P]");
957 if (ret
< 0 || ret
>= end
- pos
)
962 ret
= os_snprintf(pos
, end
- pos
, "\t%s",
963 wpa_ssid_txt(bss
->ssid
, bss
->ssid_len
));
964 if (ret
< 0 || ret
>= end
- pos
)
968 ret
= os_snprintf(pos
, end
- pos
, "\n");
969 if (ret
< 0 || ret
>= end
- pos
)
977 static int wpa_supplicant_ctrl_iface_scan_results(
978 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
986 ret
= os_snprintf(pos
, end
- pos
, "bssid / frequency / signal level / "
988 if (ret
< 0 || ret
>= end
- pos
)
992 dl_list_for_each(bss
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
) {
993 ret
= wpa_supplicant_ctrl_iface_scan_result(wpa_s
, bss
, pos
,
995 if (ret
< 0 || ret
>= end
- pos
)
1004 static int wpa_supplicant_ctrl_iface_select_network(
1005 struct wpa_supplicant
*wpa_s
, char *cmd
)
1008 struct wpa_ssid
*ssid
;
1010 /* cmd: "<network id>" or "any" */
1011 if (os_strcmp(cmd
, "any") == 0) {
1012 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SELECT_NETWORK any");
1016 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SELECT_NETWORK id=%d", id
);
1018 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1020 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
1021 "network id=%d", id
);
1024 if (ssid
->disabled
== 2) {
1025 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Cannot use "
1026 "SELECT_NETWORK with persistent P2P group");
1031 wpa_supplicant_select_network(wpa_s
, ssid
);
1037 static int wpa_supplicant_ctrl_iface_enable_network(
1038 struct wpa_supplicant
*wpa_s
, char *cmd
)
1041 struct wpa_ssid
*ssid
;
1043 /* cmd: "<network id>" or "all" */
1044 if (os_strcmp(cmd
, "all") == 0) {
1045 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ENABLE_NETWORK all");
1049 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ENABLE_NETWORK id=%d", id
);
1051 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1053 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
1054 "network id=%d", id
);
1057 if (ssid
->disabled
== 2) {
1058 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Cannot use "
1059 "ENABLE_NETWORK with persistent P2P group");
1063 wpa_supplicant_enable_network(wpa_s
, ssid
);
1069 static int wpa_supplicant_ctrl_iface_disable_network(
1070 struct wpa_supplicant
*wpa_s
, char *cmd
)
1073 struct wpa_ssid
*ssid
;
1075 /* cmd: "<network id>" or "all" */
1076 if (os_strcmp(cmd
, "all") == 0) {
1077 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: DISABLE_NETWORK all");
1081 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: DISABLE_NETWORK id=%d", id
);
1083 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1085 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find "
1086 "network id=%d", id
);
1089 if (ssid
->disabled
== 2) {
1090 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Cannot use "
1091 "DISABLE_NETWORK with persistent P2P "
1096 wpa_supplicant_disable_network(wpa_s
, ssid
);
1102 static int wpa_supplicant_ctrl_iface_add_network(
1103 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
1105 struct wpa_ssid
*ssid
;
1108 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ADD_NETWORK");
1110 ssid
= wpa_config_add_network(wpa_s
->conf
);
1114 wpas_notify_network_added(wpa_s
, ssid
);
1117 wpa_config_set_network_defaults(ssid
);
1119 ret
= os_snprintf(buf
, buflen
, "%d\n", ssid
->id
);
1120 if (ret
< 0 || (size_t) ret
>= buflen
)
1126 static int wpa_supplicant_ctrl_iface_remove_network(
1127 struct wpa_supplicant
*wpa_s
, char *cmd
)
1130 struct wpa_ssid
*ssid
;
1132 /* cmd: "<network id>" or "all" */
1133 if (os_strcmp(cmd
, "all") == 0) {
1134 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_NETWORK all");
1135 ssid
= wpa_s
->conf
->ssid
;
1137 struct wpa_ssid
*remove_ssid
= ssid
;
1140 wpas_notify_network_removed(wpa_s
, remove_ssid
);
1141 wpa_config_remove_network(wpa_s
->conf
, id
);
1143 if (wpa_s
->current_ssid
) {
1144 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
1145 wpa_supplicant_disassociate(wpa_s
,
1146 WLAN_REASON_DEAUTH_LEAVING
);
1152 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_NETWORK id=%d", id
);
1154 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1156 wpa_config_remove_network(wpa_s
->conf
, id
) < 0) {
1157 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
1162 if (ssid
== wpa_s
->current_ssid
) {
1164 * Invalidate the EAP session cache if the current network is
1167 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
1169 wpa_supplicant_disassociate(wpa_s
, WLAN_REASON_DEAUTH_LEAVING
);
1176 static int wpa_supplicant_ctrl_iface_set_network(
1177 struct wpa_supplicant
*wpa_s
, char *cmd
)
1180 struct wpa_ssid
*ssid
;
1183 /* cmd: "<network id> <variable name> <value>" */
1184 name
= os_strchr(cmd
, ' ');
1189 value
= os_strchr(name
, ' ');
1195 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
1197 wpa_hexdump_ascii_key(MSG_DEBUG
, "CTRL_IFACE: value",
1198 (u8
*) value
, os_strlen(value
));
1200 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1202 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
1207 if (wpa_config_set(ssid
, name
, value
, 0) < 0) {
1208 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Failed to set network "
1209 "variable '%s'", name
);
1213 if (wpa_s
->current_ssid
== ssid
) {
1215 * Invalidate the EAP session cache if anything in the current
1216 * configuration changes.
1218 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
1221 if ((os_strcmp(name
, "psk") == 0 &&
1222 value
[0] == '"' && ssid
->ssid_len
) ||
1223 (os_strcmp(name
, "ssid") == 0 && ssid
->passphrase
))
1224 wpa_config_update_psk(ssid
);
1225 else if (os_strcmp(name
, "priority") == 0)
1226 wpa_config_update_prio_list(wpa_s
->conf
);
1232 static int wpa_supplicant_ctrl_iface_get_network(
1233 struct wpa_supplicant
*wpa_s
, char *cmd
, char *buf
, size_t buflen
)
1237 struct wpa_ssid
*ssid
;
1240 /* cmd: "<network id> <variable name>" */
1241 name
= os_strchr(cmd
, ' ');
1242 if (name
== NULL
|| buflen
== 0)
1247 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
1250 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1252 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
1257 value
= wpa_config_get_no_key(ssid
, name
);
1258 if (value
== NULL
) {
1259 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Failed to get network "
1260 "variable '%s'", name
);
1264 res
= os_strlcpy(buf
, value
, buflen
);
1265 if (res
>= buflen
) {
1276 #ifndef CONFIG_NO_CONFIG_WRITE
1277 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant
*wpa_s
)
1281 if (!wpa_s
->conf
->update_config
) {
1282 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
1283 "to update configuration (update_config=0)");
1287 ret
= wpa_config_write(wpa_s
->confname
, wpa_s
->conf
);
1289 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Failed to "
1290 "update configuration");
1292 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Configuration"
1298 #endif /* CONFIG_NO_CONFIG_WRITE */
1301 static int ctrl_iface_get_capability_pairwise(int res
, char *strict
,
1302 struct wpa_driver_capa
*capa
,
1303 char *buf
, size_t buflen
)
1315 len
= os_strlcpy(buf
, "CCMP TKIP NONE", buflen
);
1321 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
1322 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : " ");
1323 if (ret
< 0 || ret
>= end
- pos
)
1329 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
1330 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : " ");
1331 if (ret
< 0 || ret
>= end
- pos
)
1337 if (capa
->key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
1338 ret
= os_snprintf(pos
, end
- pos
, "%sNONE", first
? "" : " ");
1339 if (ret
< 0 || ret
>= end
- pos
)
1349 static int ctrl_iface_get_capability_group(int res
, char *strict
,
1350 struct wpa_driver_capa
*capa
,
1351 char *buf
, size_t buflen
)
1363 len
= os_strlcpy(buf
, "CCMP TKIP WEP104 WEP40", buflen
);
1369 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
1370 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : " ");
1371 if (ret
< 0 || ret
>= end
- pos
)
1377 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
1378 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : " ");
1379 if (ret
< 0 || ret
>= end
- pos
)
1385 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_WEP104
) {
1386 ret
= os_snprintf(pos
, end
- pos
, "%sWEP104",
1388 if (ret
< 0 || ret
>= end
- pos
)
1394 if (capa
->enc
& WPA_DRIVER_CAPA_ENC_WEP40
) {
1395 ret
= os_snprintf(pos
, end
- pos
, "%sWEP40", first
? "" : " ");
1396 if (ret
< 0 || ret
>= end
- pos
)
1406 static int ctrl_iface_get_capability_key_mgmt(int res
, char *strict
,
1407 struct wpa_driver_capa
*capa
,
1408 char *buf
, size_t buflen
)
1420 len
= os_strlcpy(buf
, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE "
1427 ret
= os_snprintf(pos
, end
- pos
, "NONE IEEE8021X");
1428 if (ret
< 0 || ret
>= end
- pos
)
1432 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
1433 WPA_DRIVER_CAPA_KEY_MGMT_WPA2
)) {
1434 ret
= os_snprintf(pos
, end
- pos
, " WPA-EAP");
1435 if (ret
< 0 || ret
>= end
- pos
)
1440 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
|
1441 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
1442 ret
= os_snprintf(pos
, end
- pos
, " WPA-PSK");
1443 if (ret
< 0 || ret
>= end
- pos
)
1448 if (capa
->key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
1449 ret
= os_snprintf(pos
, end
- pos
, " WPA-NONE");
1450 if (ret
< 0 || ret
>= end
- pos
)
1459 static int ctrl_iface_get_capability_proto(int res
, char *strict
,
1460 struct wpa_driver_capa
*capa
,
1461 char *buf
, size_t buflen
)
1473 len
= os_strlcpy(buf
, "RSN WPA", buflen
);
1479 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA2
|
1480 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
1481 ret
= os_snprintf(pos
, end
- pos
, "%sRSN", first
? "" : " ");
1482 if (ret
< 0 || ret
>= end
- pos
)
1488 if (capa
->key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
1489 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
)) {
1490 ret
= os_snprintf(pos
, end
- pos
, "%sWPA", first
? "" : " ");
1491 if (ret
< 0 || ret
>= end
- pos
)
1501 static int ctrl_iface_get_capability_auth_alg(int res
, char *strict
,
1502 struct wpa_driver_capa
*capa
,
1503 char *buf
, size_t buflen
)
1515 len
= os_strlcpy(buf
, "OPEN SHARED LEAP", buflen
);
1521 if (capa
->auth
& (WPA_DRIVER_AUTH_OPEN
)) {
1522 ret
= os_snprintf(pos
, end
- pos
, "%sOPEN", first
? "" : " ");
1523 if (ret
< 0 || ret
>= end
- pos
)
1529 if (capa
->auth
& (WPA_DRIVER_AUTH_SHARED
)) {
1530 ret
= os_snprintf(pos
, end
- pos
, "%sSHARED",
1532 if (ret
< 0 || ret
>= end
- pos
)
1538 if (capa
->auth
& (WPA_DRIVER_AUTH_LEAP
)) {
1539 ret
= os_snprintf(pos
, end
- pos
, "%sLEAP", first
? "" : " ");
1540 if (ret
< 0 || ret
>= end
- pos
)
1550 static int wpa_supplicant_ctrl_iface_get_capability(
1551 struct wpa_supplicant
*wpa_s
, const char *_field
, char *buf
,
1554 struct wpa_driver_capa capa
;
1560 /* Determine whether or not strict checking was requested */
1561 len
= os_strlcpy(field
, _field
, sizeof(field
));
1562 if (len
>= sizeof(field
))
1564 strict
= os_strchr(field
, ' ');
1565 if (strict
!= NULL
) {
1567 if (os_strcmp(strict
, "strict") != 0)
1571 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
1572 field
, strict
? strict
: "");
1574 if (os_strcmp(field
, "eap") == 0) {
1575 return eap_get_names(buf
, buflen
);
1578 res
= wpa_drv_get_capa(wpa_s
, &capa
);
1580 if (os_strcmp(field
, "pairwise") == 0)
1581 return ctrl_iface_get_capability_pairwise(res
, strict
, &capa
,
1584 if (os_strcmp(field
, "group") == 0)
1585 return ctrl_iface_get_capability_group(res
, strict
, &capa
,
1588 if (os_strcmp(field
, "key_mgmt") == 0)
1589 return ctrl_iface_get_capability_key_mgmt(res
, strict
, &capa
,
1592 if (os_strcmp(field
, "proto") == 0)
1593 return ctrl_iface_get_capability_proto(res
, strict
, &capa
,
1596 if (os_strcmp(field
, "auth_alg") == 0)
1597 return ctrl_iface_get_capability_auth_alg(res
, strict
, &capa
,
1600 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
1607 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant
*wpa_s
,
1608 const char *cmd
, char *buf
,
1613 struct wpa_bss
*bss
;
1618 if (os_strcmp(cmd
, "FIRST") == 0)
1619 bss
= dl_list_first(&wpa_s
->bss
, struct wpa_bss
, list
);
1620 else if (os_strncmp(cmd
, "ID-", 3) == 0) {
1622 bss
= wpa_bss_get_id(wpa_s
, i
);
1623 } else if (os_strncmp(cmd
, "NEXT-", 5) == 0) {
1625 bss
= wpa_bss_get_id(wpa_s
, i
);
1627 struct dl_list
*next
= bss
->list_id
.next
;
1628 if (next
== &wpa_s
->bss_id
)
1631 bss
= dl_list_entry(next
, struct wpa_bss
,
1634 } else if (hwaddr_aton(cmd
, bssid
) == 0)
1635 bss
= wpa_bss_get_bssid(wpa_s
, bssid
);
1637 struct wpa_bss
*tmp
;
1640 dl_list_for_each(tmp
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
)
1654 ret
= os_snprintf(pos
, end
- pos
,
1656 "bssid=" MACSTR
"\n"
1659 "capabilities=0x%04x\n"
1666 MAC2STR(bss
->bssid
), bss
->freq
, bss
->beacon_int
,
1667 bss
->caps
, bss
->qual
, bss
->noise
, bss
->level
,
1668 (unsigned long long) bss
->tsf
);
1669 if (ret
< 0 || ret
>= end
- pos
)
1673 ie
= (const u8
*) (bss
+ 1);
1674 for (i
= 0; i
< bss
->ie_len
; i
++) {
1675 ret
= os_snprintf(pos
, end
- pos
, "%02x", *ie
++);
1676 if (ret
< 0 || ret
>= end
- pos
)
1680 if (wpa_bss_get_vendor_ie(bss
, P2P_IE_VENDOR_TYPE
)) {
1681 ret
= os_snprintf(pos
, end
- pos
, "[P2P]");
1682 if (ret
< 0 || ret
>= end
- pos
)
1687 ret
= os_snprintf(pos
, end
- pos
, "\n");
1688 if (ret
< 0 || ret
>= end
- pos
)
1692 ret
= os_snprintf(pos
, end
- pos
, "flags=");
1693 if (ret
< 0 || ret
>= end
- pos
)
1697 ie
= wpa_bss_get_vendor_ie(bss
, WPA_IE_VENDOR_TYPE
);
1699 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA", ie
, 2 + ie
[1]);
1700 ie2
= wpa_bss_get_ie(bss
, WLAN_EID_RSN
);
1702 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA2", ie2
, 2 + ie2
[1]);
1703 pos
= wpa_supplicant_wps_ie_txt(wpa_s
, pos
, end
, bss
);
1704 if (!ie
&& !ie2
&& bss
->caps
& IEEE80211_CAP_PRIVACY
) {
1705 ret
= os_snprintf(pos
, end
- pos
, "[WEP]");
1706 if (ret
< 0 || ret
>= end
- pos
)
1710 if (bss
->caps
& IEEE80211_CAP_IBSS
) {
1711 ret
= os_snprintf(pos
, end
- pos
, "[IBSS]");
1712 if (ret
< 0 || ret
>= end
- pos
)
1716 if (bss
->caps
& IEEE80211_CAP_ESS
) {
1717 ret
= os_snprintf(pos
, end
- pos
, "[ESS]");
1718 if (ret
< 0 || ret
>= end
- pos
)
1723 ret
= os_snprintf(pos
, end
- pos
, "\n");
1724 if (ret
< 0 || ret
>= end
- pos
)
1728 ret
= os_snprintf(pos
, end
- pos
, "ssid=%s\n",
1729 wpa_ssid_txt(bss
->ssid
, bss
->ssid_len
));
1730 if (ret
< 0 || ret
>= end
- pos
)
1735 ie
= (const u8
*) (bss
+ 1);
1736 ret
= wpas_wps_scan_result_text(ie
, bss
->ie_len
, pos
, end
);
1737 if (ret
< 0 || ret
>= end
- pos
)
1740 #endif /* CONFIG_WPS */
1743 ie
= (const u8
*) (bss
+ 1);
1744 ret
= wpas_p2p_scan_result_text(ie
, bss
->ie_len
, pos
, end
);
1745 if (ret
< 0 || ret
>= end
- pos
)
1748 #endif /* CONFIG_P2P */
1754 static int wpa_supplicant_ctrl_iface_ap_scan(
1755 struct wpa_supplicant
*wpa_s
, char *cmd
)
1757 int ap_scan
= atoi(cmd
);
1758 return wpa_supplicant_set_ap_scan(wpa_s
, ap_scan
);
1762 static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant
*wpa_s
)
1764 u8
*bcast
= (u8
*) "\xff\xff\xff\xff\xff\xff";
1766 wpa_printf(MSG_DEBUG
, "Dropping SA without deauthentication");
1767 /* MLME-DELETEKEYS.request */
1768 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 0, 0, NULL
, 0, NULL
, 0);
1769 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 1, 0, NULL
, 0, NULL
, 0);
1770 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 2, 0, NULL
, 0, NULL
, 0);
1771 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 3, 0, NULL
, 0, NULL
, 0);
1772 #ifdef CONFIG_IEEE80211W
1773 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 4, 0, NULL
, 0, NULL
, 0);
1774 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, bcast
, 5, 0, NULL
, 0, NULL
, 0);
1775 #endif /* CONFIG_IEEE80211W */
1777 wpa_drv_set_key(wpa_s
, WPA_ALG_NONE
, wpa_s
->bssid
, 0, 0, NULL
, 0, NULL
,
1779 /* MLME-SETPROTECTION.request(None) */
1780 wpa_drv_mlme_setprotection(wpa_s
, wpa_s
->bssid
,
1781 MLME_SETPROTECTION_PROTECT_TYPE_NONE
,
1782 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE
);
1783 wpa_sm_drop_sa(wpa_s
->wpa
);
1787 static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant
*wpa_s
,
1791 struct wpa_bss
*bss
;
1792 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
1794 if (hwaddr_aton(addr
, bssid
)) {
1795 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM: invalid "
1796 "address '%s'", addr
);
1800 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM " MACSTR
, MAC2STR(bssid
));
1802 bss
= wpa_bss_get_bssid(wpa_s
, bssid
);
1804 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM: Target AP not found "
1810 * TODO: Find best network configuration block from configuration to
1811 * allow roaming to other networks
1815 wpa_printf(MSG_DEBUG
, "CTRL_IFACE ROAM: No network "
1816 "configuration known for the target AP");
1820 wpa_s
->reassociate
= 1;
1821 wpa_supplicant_connect(wpa_s
, bss
, ssid
);
1828 static int p2p_ctrl_find(struct wpa_supplicant
*wpa_s
, char *cmd
)
1830 unsigned int timeout
= atoi(cmd
);
1831 enum p2p_discovery_type type
= P2P_FIND_START_WITH_FULL
;
1833 if (os_strstr(cmd
, "type=social"))
1834 type
= P2P_FIND_ONLY_SOCIAL
;
1835 else if (os_strstr(cmd
, "type=progressive"))
1836 type
= P2P_FIND_PROGRESSIVE
;
1838 wpas_p2p_find(wpa_s
, timeout
, type
);
1843 static int p2p_ctrl_connect(struct wpa_supplicant
*wpa_s
, char *cmd
,
1844 char *buf
, size_t buflen
)
1849 enum p2p_wps_method wps_method
;
1852 int persistent_group
;
1858 /* <addr> <"pbc" | "pin" | PIN> [label|display|keypad] [persistent]
1859 * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] */
1861 if (hwaddr_aton(cmd
, addr
))
1869 persistent_group
= os_strstr(pos
, " persistent") != NULL
;
1870 join
= os_strstr(pos
, " join") != NULL
;
1871 auth
= os_strstr(pos
, " auth") != NULL
;
1873 pos2
= os_strstr(pos
, " go_intent=");
1876 go_intent
= atoi(pos2
);
1877 if (go_intent
< 0 || go_intent
> 15)
1881 pos2
= os_strstr(pos
, " freq=");
1889 if (os_strncmp(pos
, "pin", 3) == 0) {
1890 /* Request random PIN (to be displayed) and enable the PIN */
1891 wps_method
= WPS_PIN_DISPLAY
;
1892 } else if (os_strncmp(pos
, "pbc", 3) == 0) {
1893 wps_method
= WPS_PBC
;
1896 pos
= os_strchr(pin
, ' ');
1897 wps_method
= WPS_PIN_KEYPAD
;
1900 if (os_strncmp(pos
, "label", 5) == 0)
1901 wps_method
= WPS_PIN_LABEL
;
1902 else if (os_strncmp(pos
, "display", 7) == 0)
1903 wps_method
= WPS_PIN_DISPLAY
;
1907 new_pin
= wpas_p2p_connect(wpa_s
, addr
, pin
, wps_method
,
1908 persistent_group
, join
, auth
, go_intent
,
1912 if (wps_method
== WPS_PIN_DISPLAY
&& pin
== NULL
) {
1913 ret
= os_snprintf(buf
, buflen
, "%08d", new_pin
);
1914 if (ret
< 0 || (size_t) ret
>= buflen
)
1919 os_memcpy(buf
, "OK\n", 3);
1924 static int p2p_ctrl_listen(struct wpa_supplicant
*wpa_s
, char *cmd
)
1926 unsigned int timeout
= atoi(cmd
);
1927 return wpas_p2p_listen(wpa_s
, timeout
);
1931 static int p2p_ctrl_prov_disc(struct wpa_supplicant
*wpa_s
, char *cmd
)
1936 /* <addr> <config method> */
1938 if (hwaddr_aton(cmd
, addr
))
1946 return wpas_p2p_prov_disc(wpa_s
, addr
, pos
);
1950 static int p2p_get_passphrase(struct wpa_supplicant
*wpa_s
, char *buf
,
1953 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
1955 if (ssid
== NULL
|| ssid
->mode
!= WPAS_MODE_P2P_GO
||
1956 ssid
->passphrase
== NULL
)
1959 os_strlcpy(buf
, ssid
->passphrase
, buflen
);
1960 return os_strlen(buf
);
1964 static int p2p_ctrl_serv_disc_req(struct wpa_supplicant
*wpa_s
, char *cmd
,
1965 char *buf
, size_t buflen
)
1969 u8 dst_buf
[ETH_ALEN
], *dst
;
1970 struct wpabuf
*tlvs
;
1974 if (hwaddr_aton(cmd
, dst_buf
))
1977 if (dst
[0] == 0 && dst
[1] == 0 && dst
[2] == 0 &&
1978 dst
[3] == 0 && dst
[4] == 0 && dst
[5] == 0)
1985 if (os_strncmp(pos
, "upnp ", 5) == 0) {
1988 if (hexstr2bin(pos
, &version
, 1) < 0)
1994 ref
= (u64
) wpas_p2p_sd_request_upnp(wpa_s
, dst
, version
, pos
);
1996 len
= os_strlen(pos
);
2000 tlvs
= wpabuf_alloc(len
);
2003 if (hexstr2bin(pos
, wpabuf_put(tlvs
, len
), len
) < 0) {
2008 ref
= (u64
) wpas_p2p_sd_request(wpa_s
, dst
, tlvs
);
2011 res
= os_snprintf(buf
, buflen
, "%llx", (long long unsigned) ref
);
2012 if (res
< 0 || (unsigned) res
>= buflen
)
2018 static int p2p_ctrl_serv_disc_cancel_req(struct wpa_supplicant
*wpa_s
,
2021 long long unsigned val
;
2023 if (sscanf(cmd
, "%llx", &val
) != 1)
2026 return wpas_p2p_sd_cancel_request(wpa_s
, (void *) req
);
2030 static int p2p_ctrl_serv_disc_resp(struct wpa_supplicant
*wpa_s
, char *cmd
)
2033 u8 dst_buf
[ETH_ALEN
], *dst
;
2035 struct wpabuf
*resp_tlvs
;
2039 pos
= os_strchr(cmd
, ' ');
2047 if (hwaddr_aton(pos
, dst_buf
))
2050 if (dst
[0] == 0 && dst
[1] == 0 && dst
[2] == 0 &&
2051 dst
[3] == 0 && dst
[4] == 0 && dst
[5] == 0)
2058 pos2
= os_strchr(pos
, ' ');
2062 dialog_token
= atoi(pos
);
2064 len
= os_strlen(pos2
);
2068 resp_tlvs
= wpabuf_alloc(len
);
2069 if (resp_tlvs
== NULL
)
2071 if (hexstr2bin(pos2
, wpabuf_put(resp_tlvs
, len
), len
) < 0) {
2072 wpabuf_free(resp_tlvs
);
2076 wpas_p2p_sd_response(wpa_s
, freq
, dst
, dialog_token
, resp_tlvs
);
2077 wpabuf_free(resp_tlvs
);
2082 static int p2p_ctrl_serv_disc_external(struct wpa_supplicant
*wpa_s
,
2085 wpa_s
->p2p_sd_over_ctrl_iface
= atoi(cmd
);
2090 static int p2p_ctrl_service_add_bonjour(struct wpa_supplicant
*wpa_s
,
2095 struct wpabuf
*query
, *resp
;
2097 pos
= os_strchr(cmd
, ' ');
2102 len
= os_strlen(cmd
);
2106 query
= wpabuf_alloc(len
);
2109 if (hexstr2bin(cmd
, wpabuf_put(query
, len
), len
) < 0) {
2114 len
= os_strlen(pos
);
2120 resp
= wpabuf_alloc(len
);
2125 if (hexstr2bin(pos
, wpabuf_put(resp
, len
), len
) < 0) {
2131 if (wpas_p2p_service_add_bonjour(wpa_s
, query
, resp
) < 0) {
2140 static int p2p_ctrl_service_add_upnp(struct wpa_supplicant
*wpa_s
, char *cmd
)
2145 pos
= os_strchr(cmd
, ' ');
2150 if (hexstr2bin(cmd
, &version
, 1) < 0)
2153 return wpas_p2p_service_add_upnp(wpa_s
, version
, pos
);
2157 static int p2p_ctrl_service_add(struct wpa_supplicant
*wpa_s
, char *cmd
)
2161 pos
= os_strchr(cmd
, ' ');
2166 if (os_strcmp(cmd
, "bonjour") == 0)
2167 return p2p_ctrl_service_add_bonjour(wpa_s
, pos
);
2168 if (os_strcmp(cmd
, "upnp") == 0)
2169 return p2p_ctrl_service_add_upnp(wpa_s
, pos
);
2170 wpa_printf(MSG_DEBUG
, "Unknown service '%s'", cmd
);
2175 static int p2p_ctrl_service_del_bonjour(struct wpa_supplicant
*wpa_s
,
2179 struct wpabuf
*query
;
2182 len
= os_strlen(cmd
);
2186 query
= wpabuf_alloc(len
);
2189 if (hexstr2bin(cmd
, wpabuf_put(query
, len
), len
) < 0) {
2194 ret
= wpas_p2p_service_del_bonjour(wpa_s
, query
);
2200 static int p2p_ctrl_service_del_upnp(struct wpa_supplicant
*wpa_s
, char *cmd
)
2205 pos
= os_strchr(cmd
, ' ');
2210 if (hexstr2bin(cmd
, &version
, 1) < 0)
2213 return wpas_p2p_service_del_upnp(wpa_s
, version
, pos
);
2217 static int p2p_ctrl_service_del(struct wpa_supplicant
*wpa_s
, char *cmd
)
2221 pos
= os_strchr(cmd
, ' ');
2226 if (os_strcmp(cmd
, "bonjour") == 0)
2227 return p2p_ctrl_service_del_bonjour(wpa_s
, pos
);
2228 if (os_strcmp(cmd
, "upnp") == 0)
2229 return p2p_ctrl_service_del_upnp(wpa_s
, pos
);
2230 wpa_printf(MSG_DEBUG
, "Unknown service '%s'", cmd
);
2235 static int p2p_ctrl_reject(struct wpa_supplicant
*wpa_s
, char *cmd
)
2241 if (hwaddr_aton(cmd
, addr
))
2244 return wpas_p2p_reject(wpa_s
, addr
);
2248 static int p2p_ctrl_invite_persistent(struct wpa_supplicant
*wpa_s
, char *cmd
)
2252 struct wpa_ssid
*ssid
;
2256 pos
= os_strstr(cmd
, " peer=");
2259 if (hwaddr_aton(pos
, peer
))
2262 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
2263 if (ssid
== NULL
|| ssid
->disabled
!= 2) {
2264 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
2265 "for persistent P2P group",
2270 return wpas_p2p_invite(wpa_s
, pos
? peer
: NULL
, ssid
, NULL
);
2274 static int p2p_ctrl_invite_group(struct wpa_supplicant
*wpa_s
, char *cmd
)
2277 u8 peer
[ETH_ALEN
], go_dev_addr
[ETH_ALEN
], *go_dev
= NULL
;
2279 pos
= os_strstr(cmd
, " peer=");
2285 if (hwaddr_aton(pos
, peer
)) {
2286 wpa_printf(MSG_DEBUG
, "P2P: Invalid MAC address '%s'", pos
);
2290 pos
= os_strstr(pos
, " go_dev_addr=");
2293 if (hwaddr_aton(pos
, go_dev_addr
)) {
2294 wpa_printf(MSG_DEBUG
, "P2P: Invalid MAC address '%s'",
2298 go_dev
= go_dev_addr
;
2301 return wpas_p2p_invite_group(wpa_s
, cmd
, peer
, go_dev
);
2305 static int p2p_ctrl_invite(struct wpa_supplicant
*wpa_s
, char *cmd
)
2307 if (os_strncmp(cmd
, "persistent=", 11) == 0)
2308 return p2p_ctrl_invite_persistent(wpa_s
, cmd
+ 11);
2309 if (os_strncmp(cmd
, "group=", 6) == 0)
2310 return p2p_ctrl_invite_group(wpa_s
, cmd
+ 6);
2316 static int p2p_ctrl_group_add_persistent(struct wpa_supplicant
*wpa_s
,
2317 char *cmd
, int freq
)
2320 struct wpa_ssid
*ssid
;
2323 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
2324 if (ssid
== NULL
|| ssid
->disabled
!= 2) {
2325 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
2326 "for persistent P2P group",
2331 return wpas_p2p_group_add_persistent(wpa_s
, ssid
, 0, freq
);
2335 static int p2p_ctrl_group_add(struct wpa_supplicant
*wpa_s
, char *cmd
)
2340 pos
= os_strstr(cmd
, "freq=");
2342 freq
= atoi(pos
+ 5);
2344 if (os_strncmp(cmd
, "persistent=", 11) == 0)
2345 return p2p_ctrl_group_add_persistent(wpa_s
, cmd
+ 11, freq
);
2346 if (os_strcmp(cmd
, "persistent") == 0 ||
2347 os_strncmp(cmd
, "persistent ", 11) == 0)
2348 return wpas_p2p_group_add(wpa_s
, 1, freq
);
2349 if (os_strncmp(cmd
, "freq=", 5) == 0)
2350 return wpas_p2p_group_add(wpa_s
, 0, freq
);
2352 wpa_printf(MSG_DEBUG
, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'",
2358 static int p2p_ctrl_peer(struct wpa_supplicant
*wpa_s
, char *cmd
,
2359 char *buf
, size_t buflen
)
2361 u8 addr
[ETH_ALEN
], *addr_ptr
;
2364 if (!wpa_s
->global
->p2p
)
2367 if (os_strcmp(cmd
, "FIRST") == 0) {
2370 } else if (os_strncmp(cmd
, "NEXT-", 5) == 0) {
2371 if (hwaddr_aton(cmd
+ 5, addr
) < 0)
2376 if (hwaddr_aton(cmd
, addr
) < 0)
2382 return p2p_get_peer_info(wpa_s
->global
->p2p
, addr_ptr
, next
,
2387 static int p2p_ctrl_set(struct wpa_supplicant
*wpa_s
, char *cmd
)
2391 if (wpa_s
->global
->p2p
== NULL
)
2394 param
= os_strchr(cmd
, ' ');
2399 if (os_strcmp(cmd
, "discoverability") == 0) {
2400 p2p_set_client_discoverability(wpa_s
->global
->p2p
,
2405 if (os_strcmp(cmd
, "managed") == 0) {
2406 p2p_set_managed_oper(wpa_s
->global
->p2p
, atoi(param
));
2410 if (os_strcmp(cmd
, "listen_channel") == 0) {
2411 return p2p_set_listen_channel(wpa_s
->global
->p2p
, 81,
2415 if (os_strcmp(cmd
, "ssid_postfix") == 0) {
2416 return p2p_set_ssid_postfix(wpa_s
->global
->p2p
, (u8
*) param
,
2420 if (os_strcmp(cmd
, "noa") == 0) {
2422 int count
, start
, duration
;
2423 /* GO NoA parameters: count,start_offset(ms),duration(ms) */
2424 count
= atoi(param
);
2425 pos
= os_strchr(param
, ',');
2430 pos
= os_strchr(pos
, ',');
2434 duration
= atoi(pos
);
2435 if (count
< 0 || count
> 255 || start
< 0 || duration
< 0)
2437 if (count
== 0 && duration
> 0)
2439 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: P2P_SET GO NoA: count=%d "
2440 "start=%d duration=%d", count
, start
, duration
);
2441 return wpas_p2p_set_noa(wpa_s
, count
, start
, duration
);
2444 if (os_strcmp(cmd
, "ps") == 0)
2445 return wpa_drv_set_p2p_powersave(wpa_s
, atoi(param
), -1, -1);
2447 if (os_strcmp(cmd
, "oppps") == 0)
2448 return wpa_drv_set_p2p_powersave(wpa_s
, -1, atoi(param
), -1);
2450 if (os_strcmp(cmd
, "ctwindow") == 0)
2451 return wpa_drv_set_p2p_powersave(wpa_s
, -1, -1, atoi(param
));
2453 if (os_strcmp(cmd
, "disabled") == 0) {
2454 wpa_s
->global
->p2p_disabled
= atoi(param
);
2455 wpa_printf(MSG_DEBUG
, "P2P functionality %s",
2456 wpa_s
->global
->p2p_disabled
?
2457 "disabled" : "enabled");
2458 if (wpa_s
->global
->p2p_disabled
) {
2459 wpas_p2p_stop_find(wpa_s
);
2460 os_memset(wpa_s
->p2p_auth_invite
, 0, ETH_ALEN
);
2461 p2p_flush(wpa_s
->global
->p2p
);
2466 if (os_strcmp(cmd
, "force_long_sd") == 0) {
2467 wpa_s
->force_long_sd
= atoi(param
);
2471 if (os_strcmp(cmd
, "peer_filter") == 0) {
2473 if (hwaddr_aton(param
, addr
))
2475 p2p_set_peer_filter(wpa_s
->global
->p2p
, addr
);
2479 if (os_strcmp(cmd
, "cross_connect") == 0)
2480 return wpas_p2p_set_cross_connect(wpa_s
, atoi(param
));
2482 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
2489 static int p2p_ctrl_presence_req(struct wpa_supplicant
*wpa_s
, char *cmd
)
2492 unsigned int dur1
= 0, int1
= 0, dur2
= 0, int2
= 0;
2495 pos
= os_strchr(cmd
, ' ');
2501 pos2
= os_strchr(pos
, ' ');
2509 pos
= os_strchr(pos2
, ' ');
2517 return wpas_p2p_presence_req(wpa_s
, dur1
, int1
, dur2
, int2
);
2521 static int p2p_ctrl_ext_listen(struct wpa_supplicant
*wpa_s
, char *cmd
)
2524 unsigned int period
= 0, interval
= 0;
2527 pos
= os_strchr(cmd
, ' ');
2532 interval
= atoi(pos
);
2535 return wpas_p2p_ext_listen(wpa_s
, period
, interval
);
2538 #endif /* CONFIG_P2P */
2541 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant
*wpa_s
,
2542 char *buf
, size_t *resp_len
)
2545 const int reply_size
= 4096;
2549 if (os_strncmp(buf
, WPA_CTRL_RSP
, os_strlen(WPA_CTRL_RSP
)) == 0 ||
2550 os_strncmp(buf
, "SET_NETWORK ", 12) == 0) {
2551 wpa_hexdump_ascii_key(MSG_DEBUG
, "RX ctrl_iface",
2552 (const u8
*) buf
, os_strlen(buf
));
2554 wpa_hexdump_ascii(MSG_DEBUG
, "RX ctrl_iface",
2555 (const u8
*) buf
, os_strlen(buf
));
2558 reply
= os_malloc(reply_size
);
2559 if (reply
== NULL
) {
2564 os_memcpy(reply
, "OK\n", 3);
2567 if (os_strcmp(buf
, "PING") == 0) {
2568 os_memcpy(reply
, "PONG\n", 5);
2570 } else if (os_strncmp(buf
, "NOTE ", 5) == 0) {
2571 wpa_printf(MSG_INFO
, "NOTE: %s", buf
+ 5);
2572 } else if (os_strcmp(buf
, "MIB") == 0) {
2573 reply_len
= wpa_sm_get_mib(wpa_s
->wpa
, reply
, reply_size
);
2574 if (reply_len
>= 0) {
2576 res
= eapol_sm_get_mib(wpa_s
->eapol
, reply
+ reply_len
,
2577 reply_size
- reply_len
);
2583 } else if (os_strncmp(buf
, "STATUS", 6) == 0) {
2584 reply_len
= wpa_supplicant_ctrl_iface_status(
2585 wpa_s
, buf
+ 6, reply
, reply_size
);
2586 } else if (os_strcmp(buf
, "PMKSA") == 0) {
2587 reply_len
= wpa_sm_pmksa_cache_list(wpa_s
->wpa
, reply
,
2589 } else if (os_strncmp(buf
, "SET ", 4) == 0) {
2590 if (wpa_supplicant_ctrl_iface_set(wpa_s
, buf
+ 4))
2592 } else if (os_strcmp(buf
, "LOGON") == 0) {
2593 eapol_sm_notify_logoff(wpa_s
->eapol
, FALSE
);
2594 } else if (os_strcmp(buf
, "LOGOFF") == 0) {
2595 eapol_sm_notify_logoff(wpa_s
->eapol
, TRUE
);
2596 } else if (os_strcmp(buf
, "REASSOCIATE") == 0) {
2597 if (wpa_s
->wpa_state
== WPA_INTERFACE_DISABLED
)
2600 wpa_s
->disconnected
= 0;
2601 wpa_s
->reassociate
= 1;
2602 wpa_supplicant_req_scan(wpa_s
, 0, 0);
2604 } else if (os_strcmp(buf
, "RECONNECT") == 0) {
2605 if (wpa_s
->wpa_state
== WPA_INTERFACE_DISABLED
)
2607 else if (wpa_s
->disconnected
) {
2608 wpa_s
->disconnected
= 0;
2609 wpa_s
->reassociate
= 1;
2610 wpa_supplicant_req_scan(wpa_s
, 0, 0);
2612 #ifdef IEEE8021X_EAPOL
2613 } else if (os_strncmp(buf
, "PREAUTH ", 8) == 0) {
2614 if (wpa_supplicant_ctrl_iface_preauth(wpa_s
, buf
+ 8))
2616 #endif /* IEEE8021X_EAPOL */
2617 #ifdef CONFIG_PEERKEY
2618 } else if (os_strncmp(buf
, "STKSTART ", 9) == 0) {
2619 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s
, buf
+ 9))
2621 #endif /* CONFIG_PEERKEY */
2622 #ifdef CONFIG_IEEE80211R
2623 } else if (os_strncmp(buf
, "FT_DS ", 6) == 0) {
2624 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s
, buf
+ 6))
2626 #endif /* CONFIG_IEEE80211R */
2628 } else if (os_strcmp(buf
, "WPS_PBC") == 0) {
2629 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s
, NULL
))
2631 } else if (os_strncmp(buf
, "WPS_PBC ", 8) == 0) {
2632 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s
, buf
+ 8))
2634 } else if (os_strncmp(buf
, "WPS_PIN ", 8) == 0) {
2635 reply_len
= wpa_supplicant_ctrl_iface_wps_pin(wpa_s
, buf
+ 8,
2638 #ifdef CONFIG_WPS_OOB
2639 } else if (os_strncmp(buf
, "WPS_OOB ", 8) == 0) {
2640 if (wpa_supplicant_ctrl_iface_wps_oob(wpa_s
, buf
+ 8))
2642 #endif /* CONFIG_WPS_OOB */
2643 } else if (os_strncmp(buf
, "WPS_REG ", 8) == 0) {
2644 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s
, buf
+ 8))
2646 #ifdef CONFIG_WPS_ER
2647 } else if (os_strcmp(buf
, "WPS_ER_START") == 0) {
2648 if (wpas_wps_er_start(wpa_s
, NULL
))
2650 } else if (os_strncmp(buf
, "WPS_ER_START ", 13) == 0) {
2651 if (wpas_wps_er_start(wpa_s
, buf
+ 13))
2653 } else if (os_strcmp(buf
, "WPS_ER_STOP") == 0) {
2654 if (wpas_wps_er_stop(wpa_s
))
2656 } else if (os_strncmp(buf
, "WPS_ER_PIN ", 11) == 0) {
2657 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s
, buf
+ 11))
2659 } else if (os_strncmp(buf
, "WPS_ER_PBC ", 11) == 0) {
2660 if (wpas_wps_er_pbc(wpa_s
, buf
+ 11))
2662 } else if (os_strncmp(buf
, "WPS_ER_LEARN ", 13) == 0) {
2663 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s
, buf
+ 13))
2665 } else if (os_strncmp(buf
, "WPS_ER_CONFIG ", 14) == 0) {
2666 if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s
, buf
+ 14))
2668 #endif /* CONFIG_WPS_ER */
2669 #endif /* CONFIG_WPS */
2670 #ifdef CONFIG_IBSS_RSN
2671 } else if (os_strncmp(buf
, "IBSS_RSN ", 9) == 0) {
2672 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s
, buf
+ 9))
2674 #endif /* CONFIG_IBSS_RSN */
2676 } else if (os_strncmp(buf
, "P2P_FIND ", 9) == 0) {
2677 if (p2p_ctrl_find(wpa_s
, buf
+ 9))
2679 } else if (os_strcmp(buf
, "P2P_FIND") == 0) {
2680 if (p2p_ctrl_find(wpa_s
, ""))
2682 } else if (os_strcmp(buf
, "P2P_STOP_FIND") == 0) {
2683 wpas_p2p_stop_find(wpa_s
);
2684 } else if (os_strncmp(buf
, "P2P_CONNECT ", 12) == 0) {
2685 reply_len
= p2p_ctrl_connect(wpa_s
, buf
+ 12, reply
,
2687 } else if (os_strncmp(buf
, "P2P_LISTEN ", 11) == 0) {
2688 if (p2p_ctrl_listen(wpa_s
, buf
+ 11))
2690 } else if (os_strcmp(buf
, "P2P_LISTEN") == 0) {
2691 if (p2p_ctrl_listen(wpa_s
, ""))
2693 } else if (os_strncmp(buf
, "P2P_GROUP_REMOVE ", 17) == 0) {
2694 if (wpas_p2p_group_remove(wpa_s
, buf
+ 17))
2696 } else if (os_strcmp(buf
, "P2P_GROUP_ADD") == 0) {
2697 if (wpas_p2p_group_add(wpa_s
, 0, 0))
2699 } else if (os_strncmp(buf
, "P2P_GROUP_ADD ", 14) == 0) {
2700 if (p2p_ctrl_group_add(wpa_s
, buf
+ 14))
2702 } else if (os_strncmp(buf
, "P2P_PROV_DISC ", 14) == 0) {
2703 if (p2p_ctrl_prov_disc(wpa_s
, buf
+ 14))
2705 } else if (os_strcmp(buf
, "P2P_GET_PASSPHRASE") == 0) {
2706 reply_len
= p2p_get_passphrase(wpa_s
, reply
, reply_size
);
2707 } else if (os_strncmp(buf
, "P2P_SERV_DISC_REQ ", 18) == 0) {
2708 reply_len
= p2p_ctrl_serv_disc_req(wpa_s
, buf
+ 18, reply
,
2710 } else if (os_strncmp(buf
, "P2P_SERV_DISC_CANCEL_REQ ", 25) == 0) {
2711 if (p2p_ctrl_serv_disc_cancel_req(wpa_s
, buf
+ 25) < 0)
2713 } else if (os_strncmp(buf
, "P2P_SERV_DISC_RESP ", 19) == 0) {
2714 if (p2p_ctrl_serv_disc_resp(wpa_s
, buf
+ 19) < 0)
2716 } else if (os_strcmp(buf
, "P2P_SERVICE_UPDATE") == 0) {
2717 wpas_p2p_sd_service_update(wpa_s
);
2718 } else if (os_strncmp(buf
, "P2P_SERV_DISC_EXTERNAL ", 23) == 0) {
2719 if (p2p_ctrl_serv_disc_external(wpa_s
, buf
+ 23) < 0)
2721 } else if (os_strcmp(buf
, "P2P_SERVICE_FLUSH") == 0) {
2722 wpas_p2p_service_flush(wpa_s
);
2723 } else if (os_strncmp(buf
, "P2P_SERVICE_ADD ", 16) == 0) {
2724 if (p2p_ctrl_service_add(wpa_s
, buf
+ 16) < 0)
2726 } else if (os_strncmp(buf
, "P2P_SERVICE_DEL ", 16) == 0) {
2727 if (p2p_ctrl_service_del(wpa_s
, buf
+ 16) < 0)
2729 } else if (os_strncmp(buf
, "P2P_REJECT ", 11) == 0) {
2730 if (p2p_ctrl_reject(wpa_s
, buf
+ 11) < 0)
2732 } else if (os_strncmp(buf
, "P2P_INVITE ", 11) == 0) {
2733 if (p2p_ctrl_invite(wpa_s
, buf
+ 11) < 0)
2735 } else if (os_strncmp(buf
, "P2P_PEER ", 9) == 0) {
2736 reply_len
= p2p_ctrl_peer(wpa_s
, buf
+ 9, reply
,
2738 } else if (os_strncmp(buf
, "P2P_SET ", 8) == 0) {
2739 if (p2p_ctrl_set(wpa_s
, buf
+ 8) < 0)
2741 } else if (os_strcmp(buf
, "P2P_FLUSH") == 0) {
2742 os_memset(wpa_s
->p2p_auth_invite
, 0, ETH_ALEN
);
2743 wpa_s
->force_long_sd
= 0;
2744 p2p_flush(wpa_s
->global
->p2p
);
2745 } else if (os_strncmp(buf
, "P2P_PRESENCE_REQ ", 17) == 0) {
2746 if (p2p_ctrl_presence_req(wpa_s
, buf
+ 17) < 0)
2748 } else if (os_strcmp(buf
, "P2P_PRESENCE_REQ") == 0) {
2749 if (p2p_ctrl_presence_req(wpa_s
, "") < 0)
2751 } else if (os_strncmp(buf
, "P2P_EXT_LISTEN ", 15) == 0) {
2752 if (p2p_ctrl_ext_listen(wpa_s
, buf
+ 15) < 0)
2754 } else if (os_strcmp(buf
, "P2P_EXT_LISTEN") == 0) {
2755 if (p2p_ctrl_ext_listen(wpa_s
, "") < 0)
2757 #endif /* CONFIG_P2P */
2758 } else if (os_strncmp(buf
, WPA_CTRL_RSP
, os_strlen(WPA_CTRL_RSP
)) == 0)
2760 if (wpa_supplicant_ctrl_iface_ctrl_rsp(
2761 wpa_s
, buf
+ os_strlen(WPA_CTRL_RSP
)))
2765 } else if (os_strcmp(buf
, "RECONFIGURE") == 0) {
2766 if (wpa_supplicant_reload_configuration(wpa_s
))
2768 } else if (os_strcmp(buf
, "TERMINATE") == 0) {
2769 wpa_supplicant_terminate_proc(wpa_s
->global
);
2770 } else if (os_strncmp(buf
, "BSSID ", 6) == 0) {
2771 if (wpa_supplicant_ctrl_iface_bssid(wpa_s
, buf
+ 6))
2773 } else if (os_strcmp(buf
, "LIST_NETWORKS") == 0) {
2774 reply_len
= wpa_supplicant_ctrl_iface_list_networks(
2775 wpa_s
, reply
, reply_size
);
2776 } else if (os_strcmp(buf
, "DISCONNECT") == 0) {
2777 wpa_s
->reassociate
= 0;
2778 wpa_s
->disconnected
= 1;
2779 wpa_supplicant_deauthenticate(wpa_s
,
2780 WLAN_REASON_DEAUTH_LEAVING
);
2781 } else if (os_strcmp(buf
, "SCAN") == 0) {
2782 if (wpa_s
->wpa_state
== WPA_INTERFACE_DISABLED
)
2785 wpa_s
->scan_req
= 2;
2786 wpa_supplicant_req_scan(wpa_s
, 0, 0);
2788 } else if (os_strcmp(buf
, "SCAN_RESULTS") == 0) {
2789 reply_len
= wpa_supplicant_ctrl_iface_scan_results(
2790 wpa_s
, reply
, reply_size
);
2791 } else if (os_strncmp(buf
, "SELECT_NETWORK ", 15) == 0) {
2792 if (wpa_supplicant_ctrl_iface_select_network(wpa_s
, buf
+ 15))
2794 } else if (os_strncmp(buf
, "ENABLE_NETWORK ", 15) == 0) {
2795 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s
, buf
+ 15))
2797 } else if (os_strncmp(buf
, "DISABLE_NETWORK ", 16) == 0) {
2798 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s
, buf
+ 16))
2800 } else if (os_strcmp(buf
, "ADD_NETWORK") == 0) {
2801 reply_len
= wpa_supplicant_ctrl_iface_add_network(
2802 wpa_s
, reply
, reply_size
);
2803 } else if (os_strncmp(buf
, "REMOVE_NETWORK ", 15) == 0) {
2804 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s
, buf
+ 15))
2806 } else if (os_strncmp(buf
, "SET_NETWORK ", 12) == 0) {
2807 if (wpa_supplicant_ctrl_iface_set_network(wpa_s
, buf
+ 12))
2809 } else if (os_strncmp(buf
, "GET_NETWORK ", 12) == 0) {
2810 reply_len
= wpa_supplicant_ctrl_iface_get_network(
2811 wpa_s
, buf
+ 12, reply
, reply_size
);
2812 #ifndef CONFIG_NO_CONFIG_WRITE
2813 } else if (os_strcmp(buf
, "SAVE_CONFIG") == 0) {
2814 if (wpa_supplicant_ctrl_iface_save_config(wpa_s
))
2816 #endif /* CONFIG_NO_CONFIG_WRITE */
2817 } else if (os_strncmp(buf
, "GET_CAPABILITY ", 15) == 0) {
2818 reply_len
= wpa_supplicant_ctrl_iface_get_capability(
2819 wpa_s
, buf
+ 15, reply
, reply_size
);
2820 } else if (os_strncmp(buf
, "AP_SCAN ", 8) == 0) {
2821 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s
, buf
+ 8))
2823 } else if (os_strcmp(buf
, "INTERFACE_LIST") == 0) {
2824 reply_len
= wpa_supplicant_global_iface_list(
2825 wpa_s
->global
, reply
, reply_size
);
2826 } else if (os_strcmp(buf
, "INTERFACES") == 0) {
2827 reply_len
= wpa_supplicant_global_iface_interfaces(
2828 wpa_s
->global
, reply
, reply_size
);
2829 } else if (os_strncmp(buf
, "BSS ", 4) == 0) {
2830 reply_len
= wpa_supplicant_ctrl_iface_bss(
2831 wpa_s
, buf
+ 4, reply
, reply_size
);
2833 } else if (os_strcmp(buf
, "STA-FIRST") == 0) {
2834 reply_len
= ap_ctrl_iface_sta_first(wpa_s
, reply
, reply_size
);
2835 } else if (os_strncmp(buf
, "STA ", 4) == 0) {
2836 reply_len
= ap_ctrl_iface_sta(wpa_s
, buf
+ 4, reply
,
2838 } else if (os_strncmp(buf
, "STA-NEXT ", 9) == 0) {
2839 reply_len
= ap_ctrl_iface_sta_next(wpa_s
, buf
+ 9, reply
,
2841 #endif /* CONFIG_AP */
2842 } else if (os_strcmp(buf
, "SUSPEND") == 0) {
2843 wpas_notify_suspend(wpa_s
->global
);
2844 } else if (os_strcmp(buf
, "RESUME") == 0) {
2845 wpas_notify_resume(wpa_s
->global
);
2846 } else if (os_strcmp(buf
, "DROP_SA") == 0) {
2847 wpa_supplicant_ctrl_iface_drop_sa(wpa_s
);
2848 } else if (os_strncmp(buf
, "ROAM ", 5) == 0) {
2849 if (wpa_supplicant_ctrl_iface_roam(wpa_s
, buf
+ 5))
2852 os_memcpy(reply
, "UNKNOWN COMMAND\n", 16);
2856 if (reply_len
< 0) {
2857 os_memcpy(reply
, "FAIL\n", 5);
2862 eapol_sm_notify_ctrl_response(wpa_s
->eapol
);
2864 *resp_len
= reply_len
;
2869 static int wpa_supplicant_global_iface_add(struct wpa_global
*global
,
2872 struct wpa_interface iface
;
2876 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
2877 * TAB<bridge_ifname>
2879 wpa_printf(MSG_DEBUG
, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd
);
2881 os_memset(&iface
, 0, sizeof(iface
));
2884 iface
.ifname
= pos
= cmd
;
2885 pos
= os_strchr(pos
, '\t');
2888 if (iface
.ifname
[0] == '\0')
2893 iface
.confname
= pos
;
2894 pos
= os_strchr(pos
, '\t');
2897 if (iface
.confname
[0] == '\0')
2898 iface
.confname
= NULL
;
2903 pos
= os_strchr(pos
, '\t');
2906 if (iface
.driver
[0] == '\0')
2907 iface
.driver
= NULL
;
2911 iface
.ctrl_interface
= pos
;
2912 pos
= os_strchr(pos
, '\t');
2915 if (iface
.ctrl_interface
[0] == '\0')
2916 iface
.ctrl_interface
= NULL
;
2920 iface
.driver_param
= pos
;
2921 pos
= os_strchr(pos
, '\t');
2924 if (iface
.driver_param
[0] == '\0')
2925 iface
.driver_param
= NULL
;
2929 iface
.bridge_ifname
= pos
;
2930 pos
= os_strchr(pos
, '\t');
2933 if (iface
.bridge_ifname
[0] == '\0')
2934 iface
.bridge_ifname
= NULL
;
2939 if (wpa_supplicant_get_iface(global
, iface
.ifname
))
2942 return wpa_supplicant_add_iface(global
, &iface
) ? 0 : -1;
2946 static int wpa_supplicant_global_iface_remove(struct wpa_global
*global
,
2949 struct wpa_supplicant
*wpa_s
;
2951 wpa_printf(MSG_DEBUG
, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd
);
2953 wpa_s
= wpa_supplicant_get_iface(global
, cmd
);
2956 return wpa_supplicant_remove_iface(global
, wpa_s
);
2960 static void wpa_free_iface_info(struct wpa_interface_info
*iface
)
2962 struct wpa_interface_info
*prev
;
2966 iface
= iface
->next
;
2968 os_free(prev
->ifname
);
2969 os_free(prev
->desc
);
2975 static int wpa_supplicant_global_iface_list(struct wpa_global
*global
,
2979 struct wpa_interface_info
*iface
= NULL
, *last
= NULL
, *tmp
;
2982 for (i
= 0; wpa_drivers
[i
]; i
++) {
2983 struct wpa_driver_ops
*drv
= wpa_drivers
[i
];
2984 if (drv
->get_interfaces
== NULL
)
2986 tmp
= drv
->get_interfaces(global
->drv_priv
[i
]);
3000 for (tmp
= iface
; tmp
; tmp
= tmp
->next
) {
3001 res
= os_snprintf(pos
, end
- pos
, "%s\t%s\t%s\n",
3002 tmp
->drv_name
, tmp
->ifname
,
3003 tmp
->desc
? tmp
->desc
: "");
3004 if (res
< 0 || res
>= end
- pos
) {
3011 wpa_free_iface_info(iface
);
3017 static int wpa_supplicant_global_iface_interfaces(struct wpa_global
*global
,
3022 struct wpa_supplicant
*wpa_s
;
3024 wpa_s
= global
->ifaces
;
3029 res
= os_snprintf(pos
, end
- pos
, "%s\n", wpa_s
->ifname
);
3030 if (res
< 0 || res
>= end
- pos
) {
3035 wpa_s
= wpa_s
->next
;
3041 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global
*global
,
3042 char *buf
, size_t *resp_len
)
3045 const int reply_size
= 2048;
3048 wpa_hexdump_ascii(MSG_DEBUG
, "RX global ctrl_iface",
3049 (const u8
*) buf
, os_strlen(buf
));
3051 reply
= os_malloc(reply_size
);
3052 if (reply
== NULL
) {
3057 os_memcpy(reply
, "OK\n", 3);
3060 if (os_strcmp(buf
, "PING") == 0) {
3061 os_memcpy(reply
, "PONG\n", 5);
3063 } else if (os_strncmp(buf
, "INTERFACE_ADD ", 14) == 0) {
3064 if (wpa_supplicant_global_iface_add(global
, buf
+ 14))
3066 } else if (os_strncmp(buf
, "INTERFACE_REMOVE ", 17) == 0) {
3067 if (wpa_supplicant_global_iface_remove(global
, buf
+ 17))
3069 } else if (os_strcmp(buf
, "INTERFACE_LIST") == 0) {
3070 reply_len
= wpa_supplicant_global_iface_list(
3071 global
, reply
, reply_size
);
3072 } else if (os_strcmp(buf
, "INTERFACES") == 0) {
3073 reply_len
= wpa_supplicant_global_iface_interfaces(
3074 global
, reply
, reply_size
);
3075 } else if (os_strcmp(buf
, "TERMINATE") == 0) {
3076 wpa_supplicant_terminate_proc(global
);
3077 } else if (os_strcmp(buf
, "SUSPEND") == 0) {
3078 wpas_notify_suspend(global
);
3079 } else if (os_strcmp(buf
, "RESUME") == 0) {
3080 wpas_notify_resume(global
);
3082 os_memcpy(reply
, "UNKNOWN COMMAND\n", 16);
3086 if (reply_len
< 0) {
3087 os_memcpy(reply
, "FAIL\n", 5);
3091 *resp_len
= reply_len
;