2 * WPA Supplicant / Control interface (shared code for all backends)
3 * Copyright (c) 2004-2006, 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.
20 #include "wpa_supplicant.h"
23 #include "wpa_supplicant_i.h"
24 #include "ctrl_iface.h"
25 #include "l2_packet.h"
27 #include "pmksa_cache.h"
32 static int wpa_supplicant_global_iface_interfaces(struct wpa_global
*global
,
36 static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant
*wpa_s
,
42 value
= os_strchr(cmd
, ' ');
47 wpa_printf(MSG_DEBUG
, "CTRL_IFACE SET '%s'='%s'", cmd
, value
);
48 if (os_strcasecmp(cmd
, "EAPOL::heldPeriod") == 0) {
49 eapol_sm_configure(wpa_s
->eapol
,
50 atoi(value
), -1, -1, -1);
51 } else if (os_strcasecmp(cmd
, "EAPOL::authPeriod") == 0) {
52 eapol_sm_configure(wpa_s
->eapol
,
53 -1, atoi(value
), -1, -1);
54 } else if (os_strcasecmp(cmd
, "EAPOL::startPeriod") == 0) {
55 eapol_sm_configure(wpa_s
->eapol
,
56 -1, -1, atoi(value
), -1);
57 } else if (os_strcasecmp(cmd
, "EAPOL::maxStart") == 0) {
58 eapol_sm_configure(wpa_s
->eapol
,
59 -1, -1, -1, atoi(value
));
60 } else if (os_strcasecmp(cmd
, "dot11RSNAConfigPMKLifetime") == 0) {
61 if (wpa_sm_set_param(wpa_s
->wpa
, RSNA_PMK_LIFETIME
,
64 } else if (os_strcasecmp(cmd
, "dot11RSNAConfigPMKReauthThreshold") ==
66 if (wpa_sm_set_param(wpa_s
->wpa
, RSNA_PMK_REAUTH_THRESHOLD
,
69 } else if (os_strcasecmp(cmd
, "dot11RSNAConfigSATimeout") == 0) {
70 if (wpa_sm_set_param(wpa_s
->wpa
, RSNA_SA_TIMEOUT
, atoi(value
)))
79 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant
*wpa_s
,
84 if (hwaddr_aton(addr
, bssid
)) {
85 wpa_printf(MSG_DEBUG
, "CTRL_IFACE PREAUTH: invalid address "
90 wpa_printf(MSG_DEBUG
, "CTRL_IFACE PREAUTH " MACSTR
, MAC2STR(bssid
));
91 rsn_preauth_deinit(wpa_s
->wpa
);
92 if (rsn_preauth_init(wpa_s
->wpa
, bssid
, wpa_s
->current_ssid
))
100 /* MLME-STKSTART.request(peer) */
101 static int wpa_supplicant_ctrl_iface_stkstart(
102 struct wpa_supplicant
*wpa_s
, char *addr
)
106 if (hwaddr_aton(addr
, peer
)) {
107 wpa_printf(MSG_DEBUG
, "CTRL_IFACE STKSTART: invalid "
108 "address '%s'", peer
);
112 wpa_printf(MSG_DEBUG
, "CTRL_IFACE STKSTART " MACSTR
,
115 return wpa_sm_stkstart(wpa_s
->wpa
, peer
);
117 #endif /* CONFIG_PEERKEY */
120 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant
*wpa_s
,
123 #ifdef IEEE8021X_EAPOL
126 struct wpa_ssid
*ssid
;
128 pos
= os_strchr(rsp
, '-');
133 pos
= os_strchr(pos
, ':');
138 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: field=%s id=%d", rsp
, id
);
139 wpa_hexdump_ascii_key(MSG_DEBUG
, "CTRL_IFACE: value",
140 (u8
*) pos
, os_strlen(pos
));
142 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
144 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
149 if (os_strcmp(rsp
, "IDENTITY") == 0) {
150 os_free(ssid
->identity
);
151 ssid
->identity
= (u8
*) os_strdup(pos
);
152 ssid
->identity_len
= os_strlen(pos
);
153 ssid
->pending_req_identity
= 0;
154 if (ssid
== wpa_s
->current_ssid
)
155 wpa_s
->reassociate
= 1;
156 } else if (os_strcmp(rsp
, "PASSWORD") == 0) {
157 os_free(ssid
->password
);
158 ssid
->password
= (u8
*) os_strdup(pos
);
159 ssid
->password_len
= os_strlen(pos
);
160 ssid
->pending_req_password
= 0;
161 if (ssid
== wpa_s
->current_ssid
)
162 wpa_s
->reassociate
= 1;
163 } else if (os_strcmp(rsp
, "NEW_PASSWORD") == 0) {
164 os_free(ssid
->new_password
);
165 ssid
->new_password
= (u8
*) os_strdup(pos
);
166 ssid
->new_password_len
= os_strlen(pos
);
167 ssid
->pending_req_new_password
= 0;
168 if (ssid
== wpa_s
->current_ssid
)
169 wpa_s
->reassociate
= 1;
170 } else if (os_strcmp(rsp
, "PIN") == 0) {
172 ssid
->pin
= os_strdup(pos
);
173 ssid
->pending_req_pin
= 0;
174 if (ssid
== wpa_s
->current_ssid
)
175 wpa_s
->reassociate
= 1;
176 } else if (os_strcmp(rsp
, "OTP") == 0) {
178 ssid
->otp
= (u8
*) os_strdup(pos
);
179 ssid
->otp_len
= os_strlen(pos
);
180 os_free(ssid
->pending_req_otp
);
181 ssid
->pending_req_otp
= NULL
;
182 ssid
->pending_req_otp_len
= 0;
183 } else if (os_strcmp(rsp
, "PASSPHRASE") == 0) {
184 os_free(ssid
->private_key_passwd
);
185 ssid
->private_key_passwd
= (u8
*) os_strdup(pos
);
186 ssid
->pending_req_passphrase
= 0;
187 if (ssid
== wpa_s
->current_ssid
)
188 wpa_s
->reassociate
= 1;
190 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Unknown field '%s'", rsp
);
195 #else /* IEEE8021X_EAPOL */
196 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: 802.1X not included");
198 #endif /* IEEE8021X_EAPOL */
202 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant
*wpa_s
,
204 char *buf
, size_t buflen
)
206 char *pos
, *end
, tmp
[30];
207 int res
, verbose
, ret
;
209 verbose
= os_strcmp(params
, "-VERBOSE") == 0;
212 if (wpa_s
->wpa_state
>= WPA_ASSOCIATED
) {
213 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
214 ret
= os_snprintf(pos
, end
- pos
, "bssid=" MACSTR
"\n",
215 MAC2STR(wpa_s
->bssid
));
216 if (ret
< 0 || ret
>= end
- pos
)
220 u8
*_ssid
= ssid
->ssid
;
221 size_t ssid_len
= ssid
->ssid_len
;
222 u8 ssid_buf
[MAX_SSID_LEN
];
224 int _res
= wpa_drv_get_ssid(wpa_s
, ssid_buf
);
231 ret
= os_snprintf(pos
, end
- pos
, "ssid=%s\nid=%d\n",
232 wpa_ssid_txt(_ssid
, ssid_len
),
234 if (ret
< 0 || ret
>= end
- pos
)
239 ret
= os_snprintf(pos
, end
- pos
,
242 if (ret
< 0 || ret
>= end
- pos
)
248 pos
+= wpa_sm_get_status(wpa_s
->wpa
, pos
, end
- pos
, verbose
);
250 ret
= os_snprintf(pos
, end
- pos
, "wpa_state=%s\n",
251 wpa_supplicant_state_txt(wpa_s
->wpa_state
));
252 if (ret
< 0 || ret
>= end
- pos
)
257 l2_packet_get_ip_addr(wpa_s
->l2
, tmp
, sizeof(tmp
)) >= 0) {
258 ret
= os_snprintf(pos
, end
- pos
, "ip_address=%s\n", tmp
);
259 if (ret
< 0 || ret
>= end
- pos
)
264 if (wpa_s
->key_mgmt
== WPA_KEY_MGMT_IEEE8021X
||
265 wpa_s
->key_mgmt
== WPA_KEY_MGMT_IEEE8021X_NO_WPA
) {
266 res
= eapol_sm_get_status(wpa_s
->eapol
, pos
, end
- pos
,
272 res
= rsn_preauth_get_status(wpa_s
->wpa
, pos
, end
- pos
, verbose
);
280 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant
*wpa_s
,
285 struct wpa_ssid
*ssid
;
288 /* cmd: "<network id> <BSSID>" */
289 pos
= os_strchr(cmd
, ' ');
294 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: id=%d bssid='%s'", id
, pos
);
295 if (hwaddr_aton(pos
, bssid
)) {
296 wpa_printf(MSG_DEBUG
,"CTRL_IFACE: invalid BSSID '%s'", pos
);
300 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
302 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find SSID id=%d "
307 os_memcpy(ssid
->bssid
, bssid
, ETH_ALEN
);
309 os_memcmp(bssid
, "\x00\x00\x00\x00\x00\x00", ETH_ALEN
) != 0;
316 static int wpa_supplicant_ctrl_iface_list_networks(
317 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
320 struct wpa_ssid
*ssid
;
325 ret
= os_snprintf(pos
, end
- pos
,
326 "network id / ssid / bssid / flags\n");
327 if (ret
< 0 || ret
>= end
- pos
)
331 ssid
= wpa_s
->conf
->ssid
;
333 ret
= os_snprintf(pos
, end
- pos
, "%d\t%s",
335 wpa_ssid_txt(ssid
->ssid
, ssid
->ssid_len
));
336 if (ret
< 0 || ret
>= end
- pos
)
339 if (ssid
->bssid_set
) {
340 ret
= os_snprintf(pos
, end
- pos
, "\t" MACSTR
,
341 MAC2STR(ssid
->bssid
));
343 ret
= os_snprintf(pos
, end
- pos
, "\tany");
345 if (ret
< 0 || ret
>= end
- pos
)
348 ret
= os_snprintf(pos
, end
- pos
, "\t%s%s",
349 ssid
== wpa_s
->current_ssid
?
351 ssid
->disabled
? "[DISABLED]" : "");
352 if (ret
< 0 || ret
>= end
- pos
)
355 ret
= os_snprintf(pos
, end
- pos
, "\n");
356 if (ret
< 0 || ret
>= end
- pos
)
367 static char * wpa_supplicant_cipher_txt(char *pos
, char *end
, int cipher
)
370 ret
= os_snprintf(pos
, end
- pos
, "-");
371 if (ret
< 0 || ret
>= end
- pos
)
374 if (cipher
& WPA_CIPHER_NONE
) {
375 ret
= os_snprintf(pos
, end
- pos
, "%sNONE", first
? "" : "+");
376 if (ret
< 0 || ret
>= end
- pos
)
381 if (cipher
& WPA_CIPHER_WEP40
) {
382 ret
= os_snprintf(pos
, end
- pos
, "%sWEP40", first
? "" : "+");
383 if (ret
< 0 || ret
>= end
- pos
)
388 if (cipher
& WPA_CIPHER_WEP104
) {
389 ret
= os_snprintf(pos
, end
- pos
, "%sWEP104",
391 if (ret
< 0 || ret
>= end
- pos
)
396 if (cipher
& WPA_CIPHER_TKIP
) {
397 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP", first
? "" : "+");
398 if (ret
< 0 || ret
>= end
- pos
)
403 if (cipher
& WPA_CIPHER_CCMP
) {
404 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP", first
? "" : "+");
405 if (ret
< 0 || ret
>= end
- pos
)
414 static char * wpa_supplicant_ie_txt(char *pos
, char *end
, const char *proto
,
415 const u8
*ie
, size_t ie_len
)
417 struct wpa_ie_data data
;
420 ret
= os_snprintf(pos
, end
- pos
, "[%s-", proto
);
421 if (ret
< 0 || ret
>= end
- pos
)
425 if (wpa_parse_wpa_ie(ie
, ie_len
, &data
) < 0) {
426 ret
= os_snprintf(pos
, end
- pos
, "?]");
427 if (ret
< 0 || ret
>= end
- pos
)
434 if (data
.key_mgmt
& WPA_KEY_MGMT_IEEE8021X
) {
435 ret
= os_snprintf(pos
, end
- pos
, "%sEAP", first
? "" : "+");
436 if (ret
< 0 || ret
>= end
- pos
)
441 if (data
.key_mgmt
& WPA_KEY_MGMT_PSK
) {
442 ret
= os_snprintf(pos
, end
- pos
, "%sPSK", first
? "" : "+");
443 if (ret
< 0 || ret
>= end
- pos
)
448 if (data
.key_mgmt
& WPA_KEY_MGMT_WPA_NONE
) {
449 ret
= os_snprintf(pos
, end
- pos
, "%sNone", first
? "" : "+");
450 if (ret
< 0 || ret
>= end
- pos
)
456 pos
= wpa_supplicant_cipher_txt(pos
, end
, data
.pairwise_cipher
);
458 if (data
.capabilities
& WPA_CAPABILITY_PREAUTH
) {
459 ret
= os_snprintf(pos
, end
- pos
, "-preauth");
460 if (ret
< 0 || ret
>= end
- pos
)
465 ret
= os_snprintf(pos
, end
- pos
, "]");
466 if (ret
< 0 || ret
>= end
- pos
)
474 static int wpa_supplicant_ctrl_iface_scan_results(
475 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
478 struct wpa_scan_result
*res
;
481 if (wpa_s
->scan_results
== NULL
&&
482 wpa_supplicant_get_scan_results(wpa_s
) < 0)
484 if (wpa_s
->scan_results
== NULL
)
489 ret
= os_snprintf(pos
, end
- pos
, "bssid / frequency / signal level / "
491 if (ret
< 0 || ret
>= end
- pos
)
495 for (i
= 0; i
< wpa_s
->num_scan_results
; i
++) {
496 res
= &wpa_s
->scan_results
[i
];
497 ret
= os_snprintf(pos
, end
- pos
, MACSTR
"\t%d\t%d\t",
498 MAC2STR(res
->bssid
), res
->freq
, res
->level
);
499 if (ret
< 0 || ret
>= end
- pos
)
502 if (res
->wpa_ie_len
) {
503 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA",
507 if (res
->rsn_ie_len
) {
508 pos
= wpa_supplicant_ie_txt(pos
, end
, "WPA2",
512 if (!res
->wpa_ie_len
&& !res
->rsn_ie_len
&&
513 res
->caps
& IEEE80211_CAP_PRIVACY
) {
514 ret
= os_snprintf(pos
, end
- pos
, "[WEP]");
515 if (ret
< 0 || ret
>= end
- pos
)
519 if (res
->caps
& IEEE80211_CAP_IBSS
) {
520 ret
= os_snprintf(pos
, end
- pos
, "[IBSS]");
521 if (ret
< 0 || ret
>= end
- pos
)
526 ret
= os_snprintf(pos
, end
- pos
, "\t%s",
527 wpa_ssid_txt(res
->ssid
, res
->ssid_len
));
528 if (ret
< 0 || ret
>= end
- pos
)
532 ret
= os_snprintf(pos
, end
- pos
, "\n");
533 if (ret
< 0 || ret
>= end
- pos
)
542 static int wpa_supplicant_ctrl_iface_select_network(
543 struct wpa_supplicant
*wpa_s
, char *cmd
)
546 struct wpa_ssid
*ssid
;
548 /* cmd: "<network id>" or "any" */
549 if (os_strcmp(cmd
, "any") == 0) {
550 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SELECT_NETWORK any");
551 ssid
= wpa_s
->conf
->ssid
;
556 wpa_s
->reassociate
= 1;
557 wpa_supplicant_req_scan(wpa_s
, 0, 0);
562 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SELECT_NETWORK id=%d", id
);
564 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
566 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
571 if (ssid
!= wpa_s
->current_ssid
&& wpa_s
->current_ssid
)
572 wpa_supplicant_disassociate(wpa_s
, REASON_DEAUTH_LEAVING
);
574 /* Mark all other networks disabled and trigger reassociation */
575 ssid
= wpa_s
->conf
->ssid
;
577 ssid
->disabled
= id
!= ssid
->id
;
580 wpa_s
->reassociate
= 1;
581 wpa_supplicant_req_scan(wpa_s
, 0, 0);
587 static int wpa_supplicant_ctrl_iface_enable_network(
588 struct wpa_supplicant
*wpa_s
, char *cmd
)
591 struct wpa_ssid
*ssid
;
593 /* cmd: "<network id>" */
595 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ENABLE_NETWORK id=%d", id
);
597 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
599 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
604 if (wpa_s
->current_ssid
== NULL
&& ssid
->disabled
) {
606 * Try to reassociate since there is no current configuration
607 * and a new network was made available. */
608 wpa_s
->reassociate
= 1;
609 wpa_supplicant_req_scan(wpa_s
, 0, 0);
617 static int wpa_supplicant_ctrl_iface_disable_network(
618 struct wpa_supplicant
*wpa_s
, char *cmd
)
621 struct wpa_ssid
*ssid
;
623 /* cmd: "<network id>" */
625 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: DISABLE_NETWORK id=%d", id
);
627 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
629 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
634 if (ssid
== wpa_s
->current_ssid
)
635 wpa_supplicant_disassociate(wpa_s
, REASON_DEAUTH_LEAVING
);
642 static int wpa_supplicant_ctrl_iface_add_network(
643 struct wpa_supplicant
*wpa_s
, char *buf
, size_t buflen
)
645 struct wpa_ssid
*ssid
;
648 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: ADD_NETWORK");
650 ssid
= wpa_config_add_network(wpa_s
->conf
);
654 wpa_config_set_network_defaults(ssid
);
656 ret
= os_snprintf(buf
, buflen
, "%d\n", ssid
->id
);
657 if (ret
< 0 || (size_t) ret
>= buflen
)
663 static int wpa_supplicant_ctrl_iface_remove_network(
664 struct wpa_supplicant
*wpa_s
, char *cmd
)
667 struct wpa_ssid
*ssid
;
669 /* cmd: "<network id>" */
671 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: REMOVE_NETWORK id=%d", id
);
673 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
675 wpa_config_remove_network(wpa_s
->conf
, id
) < 0) {
676 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
681 if (ssid
== wpa_s
->current_ssid
) {
683 * Invalidate the EAP session cache if the current network is
686 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
688 wpa_supplicant_disassociate(wpa_s
, REASON_DEAUTH_LEAVING
);
695 static int wpa_supplicant_ctrl_iface_set_network(
696 struct wpa_supplicant
*wpa_s
, char *cmd
)
699 struct wpa_ssid
*ssid
;
702 /* cmd: "<network id> <variable name> <value>" */
703 name
= os_strchr(cmd
, ' ');
708 value
= os_strchr(name
, ' ');
714 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
716 wpa_hexdump_ascii_key(MSG_DEBUG
, "CTRL_IFACE: value",
717 (u8
*) value
, os_strlen(value
));
719 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
721 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
726 if (wpa_config_set(ssid
, name
, value
, 0) < 0) {
727 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Failed to set network "
728 "variable '%s'", name
);
732 if (wpa_s
->current_ssid
== ssid
) {
734 * Invalidate the EAP session cache if anything in the current
735 * configuration changes.
737 eapol_sm_invalidate_cached_session(wpa_s
->eapol
);
740 if ((os_strcmp(name
, "psk") == 0 &&
741 value
[0] == '"' && ssid
->ssid_len
) ||
742 (os_strcmp(name
, "ssid") == 0 && ssid
->passphrase
))
743 wpa_config_update_psk(ssid
);
749 static int wpa_supplicant_ctrl_iface_get_network(
750 struct wpa_supplicant
*wpa_s
, char *cmd
, char *buf
, size_t buflen
)
753 struct wpa_ssid
*ssid
;
756 /* cmd: "<network id> <variable name>" */
757 name
= os_strchr(cmd
, ' ');
758 if (name
== NULL
|| buflen
== 0)
763 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
766 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
768 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Could not find network "
773 value
= wpa_config_get_no_key(ssid
, name
);
775 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Failed to get network "
776 "variable '%s'", name
);
780 os_snprintf(buf
, buflen
, "%s", value
);
781 buf
[buflen
- 1] = '\0';
785 return os_strlen(buf
);
789 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant
*wpa_s
)
793 if (!wpa_s
->conf
->update_config
) {
794 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
795 "to update configuration (update_config=0)");
799 ret
= wpa_config_write(wpa_s
->confname
, wpa_s
->conf
);
801 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Failed to "
802 "update configuration");
804 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: SAVE_CONFIG - Configuration"
812 static int wpa_supplicant_ctrl_iface_get_capability(
813 struct wpa_supplicant
*wpa_s
, const char *_field
, char *buf
,
816 struct wpa_driver_capa capa
;
817 int res
, first
= 1, ret
;
818 char *pos
, *end
, *strict
;
821 /* Determine whether or not strict checking was requested */
822 os_snprintf(field
, sizeof(field
), "%s", _field
);
823 field
[sizeof(field
) - 1] = '\0';
824 strict
= os_strchr(field
, ' ');
825 if (strict
!= NULL
) {
827 if (os_strcmp(strict
, "strict") != 0)
831 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
832 field
, strict
? strict
: "");
834 if (os_strcmp(field
, "eap") == 0) {
835 return eap_get_names(buf
, buflen
);
838 res
= wpa_drv_get_capa(wpa_s
, &capa
);
843 if (os_strcmp(field
, "pairwise") == 0) {
847 ret
= os_snprintf(buf
, buflen
, "CCMP TKIP NONE");
848 if (ret
< 0 || (size_t) ret
>= buflen
)
853 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
854 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP",
856 if (ret
< 0 || ret
>= end
- pos
)
862 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
863 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP",
865 if (ret
< 0 || ret
>= end
- pos
)
871 if (capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
872 ret
= os_snprintf(pos
, end
- pos
, "%sNONE",
874 if (ret
< 0 || ret
>= end
- pos
)
883 if (os_strcmp(field
, "group") == 0) {
887 ret
= os_snprintf(buf
, buflen
,
888 "CCMP TKIP WEP104 WEP40");
889 if (ret
< 0 || (size_t) ret
>= buflen
)
894 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
895 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP",
897 if (ret
< 0 || ret
>= end
- pos
)
903 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
904 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP",
906 if (ret
< 0 || ret
>= end
- pos
)
912 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_WEP104
) {
913 ret
= os_snprintf(pos
, end
- pos
, "%sWEP104",
915 if (ret
< 0 || ret
>= end
- pos
)
921 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_WEP40
) {
922 ret
= os_snprintf(pos
, end
- pos
, "%sWEP40",
924 if (ret
< 0 || ret
>= end
- pos
)
933 if (os_strcmp(field
, "key_mgmt") == 0) {
937 ret
= os_snprintf(buf
, buflen
, "WPA-PSK WPA-EAP "
938 "IEEE8021X WPA-NONE NONE");
939 if (ret
< 0 || (size_t) ret
>= buflen
)
944 ret
= os_snprintf(pos
, end
- pos
, "NONE IEEE8021X");
945 if (ret
< 0 || ret
>= end
- pos
)
949 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
950 WPA_DRIVER_CAPA_KEY_MGMT_WPA2
)) {
951 ret
= os_snprintf(pos
, end
- pos
, " WPA-EAP");
952 if (ret
< 0 || ret
>= end
- pos
)
957 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
|
958 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
959 ret
= os_snprintf(pos
, end
- pos
, " WPA-PSK");
960 if (ret
< 0 || ret
>= end
- pos
)
965 if (capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
966 ret
= os_snprintf(pos
, end
- pos
, " WPA-NONE");
967 if (ret
< 0 || ret
>= end
- pos
)
975 if (os_strcmp(field
, "proto") == 0) {
979 ret
= os_snprintf(buf
, buflen
, "RSN WPA");
980 if (ret
< 0 || (size_t) ret
>= buflen
)
985 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA2
|
986 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
987 ret
= os_snprintf(pos
, end
- pos
, "%sRSN",
989 if (ret
< 0 || ret
>= end
- pos
)
995 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
996 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
)) {
997 ret
= os_snprintf(pos
, end
- pos
, "%sWPA",
999 if (ret
< 0 || ret
>= end
- pos
)
1008 if (os_strcmp(field
, "auth_alg") == 0) {
1012 ret
= os_snprintf(buf
, buflen
, "OPEN SHARED LEAP");
1013 if (ret
< 0 || (size_t) ret
>= buflen
)
1018 if (capa
.auth
& (WPA_DRIVER_AUTH_OPEN
)) {
1019 ret
= os_snprintf(pos
, end
- pos
, "%sOPEN",
1021 if (ret
< 0 || ret
>= end
- pos
)
1027 if (capa
.auth
& (WPA_DRIVER_AUTH_SHARED
)) {
1028 ret
= os_snprintf(pos
, end
- pos
, "%sSHARED",
1030 if (ret
< 0 || ret
>= end
- pos
)
1036 if (capa
.auth
& (WPA_DRIVER_AUTH_LEAP
)) {
1037 ret
= os_snprintf(pos
, end
- pos
, "%sLEAP",
1039 if (ret
< 0 || ret
>= end
- pos
)
1048 wpa_printf(MSG_DEBUG
, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
1055 static int wpa_supplicant_ctrl_iface_ap_scan(
1056 struct wpa_supplicant
*wpa_s
, char *cmd
)
1058 int ap_scan
= atoi(cmd
);
1060 if (ap_scan
< 0 || ap_scan
> 2)
1062 wpa_s
->conf
->ap_scan
= ap_scan
;
1067 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant
*wpa_s
,
1068 char *buf
, size_t *resp_len
)
1071 const int reply_size
= 2048;
1075 if (os_strncmp(buf
, WPA_CTRL_RSP
, os_strlen(WPA_CTRL_RSP
)) == 0 ||
1076 os_strncmp(buf
, "SET_NETWORK ", 12) == 0) {
1077 wpa_hexdump_ascii_key(MSG_DEBUG
, "RX ctrl_iface",
1078 (const u8
*) buf
, os_strlen(buf
));
1080 wpa_hexdump_ascii(MSG_DEBUG
, "RX ctrl_iface",
1081 (const u8
*) buf
, os_strlen(buf
));
1084 reply
= os_malloc(reply_size
);
1085 if (reply
== NULL
) {
1090 os_memcpy(reply
, "OK\n", 3);
1093 if (os_strcmp(buf
, "PING") == 0) {
1094 os_memcpy(reply
, "PONG\n", 5);
1096 } else if (os_strcmp(buf
, "MIB") == 0) {
1097 reply_len
= wpa_sm_get_mib(wpa_s
->wpa
, reply
, reply_size
);
1098 if (reply_len
>= 0) {
1100 res
= eapol_sm_get_mib(wpa_s
->eapol
, reply
+ reply_len
,
1101 reply_size
- reply_len
);
1107 } else if (os_strncmp(buf
, "STATUS", 6) == 0) {
1108 reply_len
= wpa_supplicant_ctrl_iface_status(
1109 wpa_s
, buf
+ 6, reply
, reply_size
);
1110 } else if (os_strcmp(buf
, "PMKSA") == 0) {
1111 reply_len
= pmksa_cache_list(wpa_s
->wpa
, reply
, reply_size
);
1112 } else if (os_strncmp(buf
, "SET ", 4) == 0) {
1113 if (wpa_supplicant_ctrl_iface_set(wpa_s
, buf
+ 4))
1115 } else if (os_strcmp(buf
, "LOGON") == 0) {
1116 eapol_sm_notify_logoff(wpa_s
->eapol
, FALSE
);
1117 } else if (os_strcmp(buf
, "LOGOFF") == 0) {
1118 eapol_sm_notify_logoff(wpa_s
->eapol
, TRUE
);
1119 } else if (os_strcmp(buf
, "REASSOCIATE") == 0) {
1120 wpa_s
->disconnected
= 0;
1121 wpa_s
->reassociate
= 1;
1122 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1123 } else if (os_strncmp(buf
, "PREAUTH ", 8) == 0) {
1124 if (wpa_supplicant_ctrl_iface_preauth(wpa_s
, buf
+ 8))
1126 #ifdef CONFIG_PEERKEY
1127 } else if (os_strncmp(buf
, "STKSTART ", 9) == 0) {
1128 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s
, buf
+ 9))
1130 #endif /* CONFIG_PEERKEY */
1131 } else if (os_strncmp(buf
, WPA_CTRL_RSP
, os_strlen(WPA_CTRL_RSP
)) == 0)
1133 if (wpa_supplicant_ctrl_iface_ctrl_rsp(
1134 wpa_s
, buf
+ os_strlen(WPA_CTRL_RSP
)))
1138 } else if (os_strcmp(buf
, "RECONFIGURE") == 0) {
1139 if (wpa_supplicant_reload_configuration(wpa_s
))
1141 } else if (os_strcmp(buf
, "TERMINATE") == 0) {
1143 } else if (os_strncmp(buf
, "BSSID ", 6) == 0) {
1144 if (wpa_supplicant_ctrl_iface_bssid(wpa_s
, buf
+ 6))
1146 } else if (os_strcmp(buf
, "LIST_NETWORKS") == 0) {
1147 reply_len
= wpa_supplicant_ctrl_iface_list_networks(
1148 wpa_s
, reply
, reply_size
);
1149 } else if (os_strcmp(buf
, "DISCONNECT") == 0) {
1150 wpa_s
->disconnected
= 1;
1151 wpa_supplicant_disassociate(wpa_s
, REASON_DEAUTH_LEAVING
);
1152 } else if (os_strcmp(buf
, "SCAN") == 0) {
1153 wpa_s
->scan_req
= 2;
1154 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1155 } else if (os_strcmp(buf
, "SCAN_RESULTS") == 0) {
1156 reply_len
= wpa_supplicant_ctrl_iface_scan_results(
1157 wpa_s
, reply
, reply_size
);
1158 } else if (os_strncmp(buf
, "SELECT_NETWORK ", 15) == 0) {
1159 if (wpa_supplicant_ctrl_iface_select_network(wpa_s
, buf
+ 15))
1161 } else if (os_strncmp(buf
, "ENABLE_NETWORK ", 15) == 0) {
1162 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s
, buf
+ 15))
1164 } else if (os_strncmp(buf
, "DISABLE_NETWORK ", 16) == 0) {
1165 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s
, buf
+ 16))
1167 } else if (os_strcmp(buf
, "ADD_NETWORK") == 0) {
1168 reply_len
= wpa_supplicant_ctrl_iface_add_network(
1169 wpa_s
, reply
, reply_size
);
1170 } else if (os_strncmp(buf
, "REMOVE_NETWORK ", 15) == 0) {
1171 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s
, buf
+ 15))
1173 } else if (os_strncmp(buf
, "SET_NETWORK ", 12) == 0) {
1174 if (wpa_supplicant_ctrl_iface_set_network(wpa_s
, buf
+ 12))
1176 } else if (os_strncmp(buf
, "GET_NETWORK ", 12) == 0) {
1177 reply_len
= wpa_supplicant_ctrl_iface_get_network(
1178 wpa_s
, buf
+ 12, reply
, reply_size
);
1179 } else if (os_strcmp(buf
, "SAVE_CONFIG") == 0) {
1180 if (wpa_supplicant_ctrl_iface_save_config(wpa_s
))
1182 } else if (os_strncmp(buf
, "GET_CAPABILITY ", 15) == 0) {
1183 reply_len
= wpa_supplicant_ctrl_iface_get_capability(
1184 wpa_s
, buf
+ 15, reply
, reply_size
);
1185 } else if (os_strncmp(buf
, "AP_SCAN ", 8) == 0) {
1186 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s
, buf
+ 8))
1188 } else if (os_strcmp(buf
, "INTERFACES") == 0) {
1189 reply_len
= wpa_supplicant_global_iface_interfaces(
1190 wpa_s
->global
, reply
, reply_size
);
1192 os_memcpy(reply
, "UNKNOWN COMMAND\n", 16);
1196 if (reply_len
< 0) {
1197 os_memcpy(reply
, "FAIL\n", 5);
1202 eapol_sm_notify_ctrl_response(wpa_s
->eapol
);
1204 *resp_len
= reply_len
;
1209 static int wpa_supplicant_global_iface_add(struct wpa_global
*global
,
1212 struct wpa_interface iface
;
1216 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
1217 * TAB<bridge_ifname>
1219 wpa_printf(MSG_DEBUG
, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd
);
1221 os_memset(&iface
, 0, sizeof(iface
));
1224 iface
.ifname
= pos
= cmd
;
1225 pos
= os_strchr(pos
, '\t');
1228 if (iface
.ifname
[0] == '\0')
1233 iface
.confname
= pos
;
1234 pos
= os_strchr(pos
, '\t');
1237 if (iface
.confname
[0] == '\0')
1238 iface
.confname
= NULL
;
1243 pos
= os_strchr(pos
, '\t');
1246 if (iface
.driver
[0] == '\0')
1247 iface
.driver
= NULL
;
1251 iface
.ctrl_interface
= pos
;
1252 pos
= os_strchr(pos
, '\t');
1255 if (iface
.ctrl_interface
[0] == '\0')
1256 iface
.ctrl_interface
= NULL
;
1260 iface
.driver_param
= pos
;
1261 pos
= os_strchr(pos
, '\t');
1264 if (iface
.driver_param
[0] == '\0')
1265 iface
.driver_param
= NULL
;
1269 iface
.bridge_ifname
= pos
;
1270 pos
= os_strchr(pos
, '\t');
1273 if (iface
.bridge_ifname
[0] == '\0')
1274 iface
.bridge_ifname
= NULL
;
1279 if (wpa_supplicant_get_iface(global
, iface
.ifname
))
1282 return wpa_supplicant_add_iface(global
, &iface
) ? 0 : -1;
1286 static int wpa_supplicant_global_iface_remove(struct wpa_global
*global
,
1289 struct wpa_supplicant
*wpa_s
;
1291 wpa_printf(MSG_DEBUG
, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd
);
1293 wpa_s
= wpa_supplicant_get_iface(global
, cmd
);
1296 return wpa_supplicant_remove_iface(global
, wpa_s
);
1300 static int wpa_supplicant_global_iface_interfaces(struct wpa_global
*global
,
1305 struct wpa_supplicant
*wpa_s
;
1307 wpa_s
= global
->ifaces
;
1312 res
= os_snprintf(pos
, end
- pos
, "%s\n", wpa_s
->ifname
);
1313 if (res
< 0 || res
>= end
- pos
) {
1318 wpa_s
= wpa_s
->next
;
1324 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global
*global
,
1325 char *buf
, size_t *resp_len
)
1328 const int reply_size
= 2048;
1331 wpa_hexdump_ascii(MSG_DEBUG
, "RX global ctrl_iface",
1332 (const u8
*) buf
, os_strlen(buf
));
1334 reply
= os_malloc(reply_size
);
1335 if (reply
== NULL
) {
1340 os_memcpy(reply
, "OK\n", 3);
1343 if (os_strcmp(buf
, "PING") == 0) {
1344 os_memcpy(reply
, "PONG\n", 5);
1346 } else if (os_strncmp(buf
, "INTERFACE_ADD ", 14) == 0) {
1347 if (wpa_supplicant_global_iface_add(global
, buf
+ 14))
1349 } else if (os_strncmp(buf
, "INTERFACE_REMOVE ", 17) == 0) {
1350 if (wpa_supplicant_global_iface_remove(global
, buf
+ 17))
1352 } else if (os_strcmp(buf
, "INTERFACES") == 0) {
1353 reply_len
= wpa_supplicant_global_iface_interfaces(
1354 global
, reply
, reply_size
);
1355 } else if (os_strcmp(buf
, "TERMINATE") == 0) {
1358 os_memcpy(reply
, "UNKNOWN COMMAND\n", 16);
1362 if (reply_len
< 0) {
1363 os_memcpy(reply
, "FAIL\n", 5);
1367 *resp_len
= reply_len
;