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 #ifdef IEEE8021X_EAPOL
80 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s,
85 if (hwaddr_aton(addr, bssid)) {
86 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address "
91 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid));
92 rsn_preauth_deinit(wpa_s->wpa);
93 if (rsn_preauth_init(wpa_s->wpa, bssid, wpa_s->current_ssid))
98 #endif /* IEEE8021X_EAPOL */
101 #ifdef CONFIG_PEERKEY
102 /* MLME-STKSTART.request(peer) */
103 static int wpa_supplicant_ctrl_iface_stkstart(
104 struct wpa_supplicant *wpa_s, char *addr)
108 if (hwaddr_aton(addr, peer)) {
109 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid "
110 "address '%s'", peer);
114 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART " MACSTR,
117 return wpa_sm_stkstart(wpa_s->wpa, peer);
119 #endif /* CONFIG_PEERKEY */
122 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
125 #ifdef IEEE8021X_EAPOL
128 struct wpa_ssid *ssid;
130 pos = os_strchr(rsp, '-');
135 pos = os_strchr(pos, ':');
140 wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id);
141 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
142 (u8 *) pos, os_strlen(pos));
144 ssid = wpa_config_get_network(wpa_s->conf, id);
146 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
151 if (os_strcmp(rsp, "IDENTITY") == 0) {
152 os_free(ssid->identity);
153 ssid->identity = (u8 *) os_strdup(pos);
154 ssid->identity_len = os_strlen(pos);
155 ssid->pending_req_identity = 0;
156 if (ssid == wpa_s->current_ssid)
157 wpa_s->reassociate = 1;
158 } else if (os_strcmp(rsp, "PASSWORD") == 0) {
159 os_free(ssid->password);
160 ssid->password = (u8 *) os_strdup(pos);
161 ssid->password_len = os_strlen(pos);
162 ssid->pending_req_password = 0;
163 if (ssid == wpa_s->current_ssid)
164 wpa_s->reassociate = 1;
165 } else if (os_strcmp(rsp, "NEW_PASSWORD") == 0) {
166 os_free(ssid->new_password);
167 ssid->new_password = (u8 *) os_strdup(pos);
168 ssid->new_password_len = os_strlen(pos);
169 ssid->pending_req_new_password = 0;
170 if (ssid == wpa_s->current_ssid)
171 wpa_s->reassociate = 1;
172 } else if (os_strcmp(rsp, "PIN") == 0) {
174 ssid->pin = os_strdup(pos);
175 ssid->pending_req_pin = 0;
176 if (ssid == wpa_s->current_ssid)
177 wpa_s->reassociate = 1;
178 } else if (os_strcmp(rsp, "OTP") == 0) {
180 ssid->otp = (u8 *) os_strdup(pos);
181 ssid->otp_len = os_strlen(pos);
182 os_free(ssid->pending_req_otp);
183 ssid->pending_req_otp = NULL;
184 ssid->pending_req_otp_len = 0;
185 } else if (os_strcmp(rsp, "PASSPHRASE") == 0) {
186 os_free(ssid->private_key_passwd);
187 ssid->private_key_passwd = (u8 *) os_strdup(pos);
188 ssid->pending_req_passphrase = 0;
189 if (ssid == wpa_s->current_ssid)
190 wpa_s->reassociate = 1;
192 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", rsp);
197 #else /* IEEE8021X_EAPOL */
198 wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
200 #endif /* IEEE8021X_EAPOL */
204 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
206 char *buf, size_t buflen)
208 char *pos, *end, tmp[30];
209 int res, verbose, ret;
211 verbose = os_strcmp(params, "-VERBOSE") == 0;
214 if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
215 struct wpa_ssid *ssid = wpa_s->current_ssid;
216 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
217 MAC2STR(wpa_s->bssid));
218 if (ret < 0 || ret >= end - pos)
222 u8 *_ssid = ssid->ssid;
223 size_t ssid_len = ssid->ssid_len;
224 u8 ssid_buf[MAX_SSID_LEN];
226 int _res = wpa_drv_get_ssid(wpa_s, ssid_buf);
233 ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n",
234 wpa_ssid_txt(_ssid, ssid_len),
236 if (ret < 0 || ret >= end - pos)
241 ret = os_snprintf(pos, end - pos,
244 if (ret < 0 || ret >= end - pos)
250 pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose);
252 ret = os_snprintf(pos, end - pos, "wpa_state=%s\n",
253 wpa_supplicant_state_txt(wpa_s->wpa_state));
254 if (ret < 0 || ret >= end - pos)
259 l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) {
260 ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp);
261 if (ret < 0 || ret >= end - pos)
266 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X ||
267 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
268 res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos,
274 res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose);
282 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s,
287 struct wpa_ssid *ssid;
290 /* cmd: "<network id> <BSSID>" */
291 pos = os_strchr(cmd, ' ');
296 wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos);
297 if (hwaddr_aton(pos, bssid)) {
298 wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos);
302 ssid = wpa_config_get_network(wpa_s->conf, id);
304 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
309 os_memcpy(ssid->bssid, bssid, ETH_ALEN);
311 os_memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) != 0;
318 static int wpa_supplicant_ctrl_iface_list_networks(
319 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
322 struct wpa_ssid *ssid;
327 ret = os_snprintf(pos, end - pos,
328 "network id / ssid / bssid / flags\n");
329 if (ret < 0 || ret >= end - pos)
333 ssid = wpa_s->conf->ssid;
335 ret = os_snprintf(pos, end - pos, "%d\t%s",
337 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
338 if (ret < 0 || ret >= end - pos)
341 if (ssid->bssid_set) {
342 ret = os_snprintf(pos, end - pos, "\t" MACSTR,
343 MAC2STR(ssid->bssid));
345 ret = os_snprintf(pos, end - pos, "\tany");
347 if (ret < 0 || ret >= end - pos)
350 ret = os_snprintf(pos, end - pos, "\t%s%s",
351 ssid == wpa_s->current_ssid ?
353 ssid->disabled ? "[DISABLED]" : "");
354 if (ret < 0 || ret >= end - pos)
357 ret = os_snprintf(pos, end - pos, "\n");
358 if (ret < 0 || ret >= end - pos)
369 static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher)
372 ret = os_snprintf(pos, end - pos, "-");
373 if (ret < 0 || ret >= end - pos)
376 if (cipher & WPA_CIPHER_NONE) {
377 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : "+");
378 if (ret < 0 || ret >= end - pos)
383 if (cipher & WPA_CIPHER_WEP40) {
384 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : "+");
385 if (ret < 0 || ret >= end - pos)
390 if (cipher & WPA_CIPHER_WEP104) {
391 ret = os_snprintf(pos, end - pos, "%sWEP104",
393 if (ret < 0 || ret >= end - pos)
398 if (cipher & WPA_CIPHER_TKIP) {
399 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : "+");
400 if (ret < 0 || ret >= end - pos)
405 if (cipher & WPA_CIPHER_CCMP) {
406 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : "+");
407 if (ret < 0 || ret >= end - pos)
416 static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
417 const u8 *ie, size_t ie_len)
419 struct wpa_ie_data data;
422 ret = os_snprintf(pos, end - pos, "[%s-", proto);
423 if (ret < 0 || ret >= end - pos)
427 if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) {
428 ret = os_snprintf(pos, end - pos, "?]");
429 if (ret < 0 || ret >= end - pos)
436 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
437 ret = os_snprintf(pos, end - pos, "%sEAP", first ? "" : "+");
438 if (ret < 0 || ret >= end - pos)
443 if (data.key_mgmt & WPA_KEY_MGMT_PSK) {
444 ret = os_snprintf(pos, end - pos, "%sPSK", first ? "" : "+");
445 if (ret < 0 || ret >= end - pos)
450 if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
451 ret = os_snprintf(pos, end - pos, "%sNone", first ? "" : "+");
452 if (ret < 0 || ret >= end - pos)
458 pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher);
460 if (data.capabilities & WPA_CAPABILITY_PREAUTH) {
461 ret = os_snprintf(pos, end - pos, "-preauth");
462 if (ret < 0 || ret >= end - pos)
467 ret = os_snprintf(pos, end - pos, "]");
468 if (ret < 0 || ret >= end - pos)
476 static int wpa_supplicant_ctrl_iface_scan_results(
477 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
480 struct wpa_scan_result *res;
483 if (wpa_s->scan_results == NULL &&
484 wpa_supplicant_get_scan_results(wpa_s) < 0)
486 if (wpa_s->scan_results == NULL)
491 ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / "
493 if (ret < 0 || ret >= end - pos)
497 for (i = 0; i < wpa_s->num_scan_results; i++) {
498 res = &wpa_s->scan_results[i];
499 ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t",
500 MAC2STR(res->bssid), res->freq, res->level);
501 if (ret < 0 || ret >= end - pos)
504 if (res->wpa_ie_len) {
505 pos = wpa_supplicant_ie_txt(pos, end, "WPA",
509 if (res->rsn_ie_len) {
510 pos = wpa_supplicant_ie_txt(pos, end, "WPA2",
514 if (!res->wpa_ie_len && !res->rsn_ie_len &&
515 res->caps & IEEE80211_CAP_PRIVACY) {
516 ret = os_snprintf(pos, end - pos, "[WEP]");
517 if (ret < 0 || ret >= end - pos)
521 if (res->caps & IEEE80211_CAP_IBSS) {
522 ret = os_snprintf(pos, end - pos, "[IBSS]");
523 if (ret < 0 || ret >= end - pos)
528 ret = os_snprintf(pos, end - pos, "\t%s",
529 wpa_ssid_txt(res->ssid, res->ssid_len));
530 if (ret < 0 || ret >= end - pos)
534 ret = os_snprintf(pos, end - pos, "\n");
535 if (ret < 0 || ret >= end - pos)
544 static int wpa_supplicant_ctrl_iface_select_network(
545 struct wpa_supplicant *wpa_s, char *cmd)
548 struct wpa_ssid *ssid;
550 /* cmd: "<network id>" or "any" */
551 if (os_strcmp(cmd, "any") == 0) {
552 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any");
553 ssid = wpa_s->conf->ssid;
558 wpa_s->reassociate = 1;
559 wpa_supplicant_req_scan(wpa_s, 0, 0);
564 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id);
566 ssid = wpa_config_get_network(wpa_s->conf, id);
568 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
573 if (ssid != wpa_s->current_ssid && wpa_s->current_ssid)
574 wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING);
576 /* Mark all other networks disabled and trigger reassociation */
577 ssid = wpa_s->conf->ssid;
579 ssid->disabled = id != ssid->id;
582 wpa_s->reassociate = 1;
583 wpa_supplicant_req_scan(wpa_s, 0, 0);
589 static int wpa_supplicant_ctrl_iface_enable_network(
590 struct wpa_supplicant *wpa_s, char *cmd)
593 struct wpa_ssid *ssid;
595 /* cmd: "<network id>" */
597 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id);
599 ssid = wpa_config_get_network(wpa_s->conf, id);
601 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
606 if (wpa_s->current_ssid == NULL && ssid->disabled) {
608 * Try to reassociate since there is no current configuration
609 * and a new network was made available. */
610 wpa_s->reassociate = 1;
611 wpa_supplicant_req_scan(wpa_s, 0, 0);
619 static int wpa_supplicant_ctrl_iface_disable_network(
620 struct wpa_supplicant *wpa_s, char *cmd)
623 struct wpa_ssid *ssid;
625 /* cmd: "<network id>" */
627 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id);
629 ssid = wpa_config_get_network(wpa_s->conf, id);
631 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
636 if (ssid == wpa_s->current_ssid)
637 wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING);
644 static int wpa_supplicant_ctrl_iface_add_network(
645 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
647 struct wpa_ssid *ssid;
650 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK");
652 ssid = wpa_config_add_network(wpa_s->conf);
656 wpa_config_set_network_defaults(ssid);
658 ret = os_snprintf(buf, buflen, "%d\n", ssid->id);
659 if (ret < 0 || (size_t) ret >= buflen)
665 static int wpa_supplicant_ctrl_iface_remove_network(
666 struct wpa_supplicant *wpa_s, char *cmd)
669 struct wpa_ssid *ssid;
671 /* cmd: "<network id>" */
673 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id);
675 ssid = wpa_config_get_network(wpa_s->conf, id);
677 wpa_config_remove_network(wpa_s->conf, id) < 0) {
678 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
683 if (ssid == wpa_s->current_ssid) {
685 * Invalidate the EAP session cache if the current network is
688 eapol_sm_invalidate_cached_session(wpa_s->eapol);
690 wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING);
697 static int wpa_supplicant_ctrl_iface_set_network(
698 struct wpa_supplicant *wpa_s, char *cmd)
701 struct wpa_ssid *ssid;
704 /* cmd: "<network id> <variable name> <value>" */
705 name = os_strchr(cmd, ' ');
710 value = os_strchr(name, ' ');
716 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
718 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
719 (u8 *) value, os_strlen(value));
721 ssid = wpa_config_get_network(wpa_s->conf, id);
723 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
728 if (wpa_config_set(ssid, name, value, 0) < 0) {
729 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network "
730 "variable '%s'", name);
734 if (wpa_s->current_ssid == ssid) {
736 * Invalidate the EAP session cache if anything in the current
737 * configuration changes.
739 eapol_sm_invalidate_cached_session(wpa_s->eapol);
742 if ((os_strcmp(name, "psk") == 0 &&
743 value[0] == '"' && ssid->ssid_len) ||
744 (os_strcmp(name, "ssid") == 0 && ssid->passphrase))
745 wpa_config_update_psk(ssid);
751 static int wpa_supplicant_ctrl_iface_get_network(
752 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
755 struct wpa_ssid *ssid;
758 /* cmd: "<network id> <variable name>" */
759 name = os_strchr(cmd, ' ');
760 if (name == NULL || buflen == 0)
765 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
768 ssid = wpa_config_get_network(wpa_s->conf, id);
770 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
775 value = wpa_config_get_no_key(ssid, name);
777 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network "
778 "variable '%s'", name);
782 os_snprintf(buf, buflen, "%s", value);
783 buf[buflen - 1] = '\0';
787 return os_strlen(buf);
791 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s)
795 if (!wpa_s->conf->update_config) {
796 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
797 "to update configuration (update_config=0)");
801 ret = wpa_config_write(wpa_s->confname, wpa_s->conf);
803 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to "
804 "update configuration");
806 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration"
814 static int wpa_supplicant_ctrl_iface_get_capability(
815 struct wpa_supplicant *wpa_s, const char *_field, char *buf,
818 struct wpa_driver_capa capa;
819 int res, first = 1, ret;
820 char *pos, *end, *strict;
823 /* Determine whether or not strict checking was requested */
824 os_snprintf(field, sizeof(field), "%s", _field);
825 field[sizeof(field) - 1] = '\0';
826 strict = os_strchr(field, ' ');
827 if (strict != NULL) {
829 if (os_strcmp(strict, "strict") != 0)
833 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
834 field, strict ? strict : "");
836 if (os_strcmp(field, "eap") == 0) {
837 return eap_get_names(buf, buflen);
840 res = wpa_drv_get_capa(wpa_s, &capa);
845 if (os_strcmp(field, "pairwise") == 0) {
849 ret = os_snprintf(buf, buflen, "CCMP TKIP NONE");
850 if (ret < 0 || (size_t) ret >= buflen)
855 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
856 ret = os_snprintf(pos, end - pos, "%sCCMP",
858 if (ret < 0 || ret >= end - pos)
864 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
865 ret = os_snprintf(pos, end - pos, "%sTKIP",
867 if (ret < 0 || ret >= end - pos)
873 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
874 ret = os_snprintf(pos, end - pos, "%sNONE",
876 if (ret < 0 || ret >= end - pos)
885 if (os_strcmp(field, "group") == 0) {
889 ret = os_snprintf(buf, buflen,
890 "CCMP TKIP WEP104 WEP40");
891 if (ret < 0 || (size_t) ret >= buflen)
896 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
897 ret = os_snprintf(pos, end - pos, "%sCCMP",
899 if (ret < 0 || ret >= end - pos)
905 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
906 ret = os_snprintf(pos, end - pos, "%sTKIP",
908 if (ret < 0 || ret >= end - pos)
914 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) {
915 ret = os_snprintf(pos, end - pos, "%sWEP104",
917 if (ret < 0 || ret >= end - pos)
923 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) {
924 ret = os_snprintf(pos, end - pos, "%sWEP40",
926 if (ret < 0 || ret >= end - pos)
935 if (os_strcmp(field, "key_mgmt") == 0) {
939 ret = os_snprintf(buf, buflen, "WPA-PSK WPA-EAP "
940 "IEEE8021X WPA-NONE NONE");
941 if (ret < 0 || (size_t) ret >= buflen)
946 ret = os_snprintf(pos, end - pos, "NONE IEEE8021X");
947 if (ret < 0 || ret >= end - pos)
951 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
952 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
953 ret = os_snprintf(pos, end - pos, " WPA-EAP");
954 if (ret < 0 || ret >= end - pos)
959 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
960 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
961 ret = os_snprintf(pos, end - pos, " WPA-PSK");
962 if (ret < 0 || ret >= end - pos)
967 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
968 ret = os_snprintf(pos, end - pos, " WPA-NONE");
969 if (ret < 0 || ret >= end - pos)
977 if (os_strcmp(field, "proto") == 0) {
981 ret = os_snprintf(buf, buflen, "RSN WPA");
982 if (ret < 0 || (size_t) ret >= buflen)
987 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
988 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
989 ret = os_snprintf(pos, end - pos, "%sRSN",
991 if (ret < 0 || ret >= end - pos)
997 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
998 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
999 ret = os_snprintf(pos, end - pos, "%sWPA",
1001 if (ret < 0 || ret >= end - pos)
1010 if (os_strcmp(field, "auth_alg") == 0) {
1014 ret = os_snprintf(buf, buflen, "OPEN SHARED LEAP");
1015 if (ret < 0 || (size_t) ret >= buflen)
1020 if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) {
1021 ret = os_snprintf(pos, end - pos, "%sOPEN",
1023 if (ret < 0 || ret >= end - pos)
1029 if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) {
1030 ret = os_snprintf(pos, end - pos, "%sSHARED",
1032 if (ret < 0 || ret >= end - pos)
1038 if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) {
1039 ret = os_snprintf(pos, end - pos, "%sLEAP",
1041 if (ret < 0 || ret >= end - pos)
1050 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
1057 static int wpa_supplicant_ctrl_iface_ap_scan(
1058 struct wpa_supplicant *wpa_s, char *cmd)
1060 int ap_scan = atoi(cmd);
1062 if (ap_scan < 0 || ap_scan > 2)
1064 wpa_s->conf->ap_scan = ap_scan;
1069 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
1070 char *buf, size_t *resp_len)
1073 const int reply_size = 2048;
1077 if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 ||
1078 os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
1079 wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface",
1080 (const u8 *) buf, os_strlen(buf));
1082 wpa_hexdump_ascii(MSG_DEBUG, "RX ctrl_iface",
1083 (const u8 *) buf, os_strlen(buf));
1086 reply = os_malloc(reply_size);
1087 if (reply == NULL) {
1092 os_memcpy(reply, "OK\n", 3);
1095 if (os_strcmp(buf, "PING") == 0) {
1096 os_memcpy(reply, "PONG\n", 5);
1098 } else if (os_strcmp(buf, "MIB") == 0) {
1099 reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
1100 if (reply_len >= 0) {
1102 res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len,
1103 reply_size - reply_len);
1109 } else if (os_strncmp(buf, "STATUS", 6) == 0) {
1110 reply_len = wpa_supplicant_ctrl_iface_status(
1111 wpa_s, buf + 6, reply, reply_size);
1112 } else if (os_strcmp(buf, "PMKSA") == 0) {
1113 reply_len = pmksa_cache_list(wpa_s->wpa, reply, reply_size);
1114 } else if (os_strncmp(buf, "SET ", 4) == 0) {
1115 if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4))
1117 } else if (os_strcmp(buf, "LOGON") == 0) {
1118 eapol_sm_notify_logoff(wpa_s->eapol, FALSE);
1119 } else if (os_strcmp(buf, "LOGOFF") == 0) {
1120 eapol_sm_notify_logoff(wpa_s->eapol, TRUE);
1121 } else if (os_strcmp(buf, "REASSOCIATE") == 0) {
1122 wpa_s->disconnected = 0;
1123 wpa_s->reassociate = 1;
1124 wpa_supplicant_req_scan(wpa_s, 0, 0);
1125 } else if (os_strcmp(buf, "RECONNECT") == 0) {
1126 if (wpa_s->disconnected) {
1127 wpa_s->disconnected = 0;
1128 wpa_s->reassociate = 1;
1129 wpa_supplicant_req_scan(wpa_s, 0, 0);
1131 #ifdef IEEE8021X_EAPOL
1132 } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) {
1133 if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8))
1135 #endif /* IEEE8021X_EAPOL */
1136 #ifdef CONFIG_PEERKEY
1137 } else if (os_strncmp(buf, "STKSTART ", 9) == 0) {
1138 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9))
1140 #endif /* CONFIG_PEERKEY */
1141 } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0)
1143 if (wpa_supplicant_ctrl_iface_ctrl_rsp(
1144 wpa_s, buf + os_strlen(WPA_CTRL_RSP)))
1148 } else if (os_strcmp(buf, "RECONFIGURE") == 0) {
1149 if (wpa_supplicant_reload_configuration(wpa_s))
1151 } else if (os_strcmp(buf, "TERMINATE") == 0) {
1153 } else if (os_strncmp(buf, "BSSID ", 6) == 0) {
1154 if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6))
1156 } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) {
1157 reply_len = wpa_supplicant_ctrl_iface_list_networks(
1158 wpa_s, reply, reply_size);
1159 } else if (os_strcmp(buf, "DISCONNECT") == 0) {
1160 wpa_s->reassociate = 0;
1161 wpa_s->disconnected = 1;
1162 wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING);
1163 } else if (os_strcmp(buf, "SCAN") == 0) {
1164 wpa_s->scan_req = 2;
1165 wpa_supplicant_req_scan(wpa_s, 0, 0);
1166 } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) {
1167 reply_len = wpa_supplicant_ctrl_iface_scan_results(
1168 wpa_s, reply, reply_size);
1169 } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) {
1170 if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15))
1172 } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) {
1173 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15))
1175 } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) {
1176 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16))
1178 } else if (os_strcmp(buf, "ADD_NETWORK") == 0) {
1179 reply_len = wpa_supplicant_ctrl_iface_add_network(
1180 wpa_s, reply, reply_size);
1181 } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) {
1182 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15))
1184 } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
1185 if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12))
1187 } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
1188 reply_len = wpa_supplicant_ctrl_iface_get_network(
1189 wpa_s, buf + 12, reply, reply_size);
1190 } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
1191 if (wpa_supplicant_ctrl_iface_save_config(wpa_s))
1193 } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
1194 reply_len = wpa_supplicant_ctrl_iface_get_capability(
1195 wpa_s, buf + 15, reply, reply_size);
1196 } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) {
1197 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8))
1199 } else if (os_strcmp(buf, "INTERFACES") == 0) {
1200 reply_len = wpa_supplicant_global_iface_interfaces(
1201 wpa_s->global, reply, reply_size);
1203 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
1207 if (reply_len < 0) {
1208 os_memcpy(reply, "FAIL\n", 5);
1213 eapol_sm_notify_ctrl_response(wpa_s->eapol);
1215 *resp_len = reply_len;
1220 static int wpa_supplicant_global_iface_add(struct wpa_global *global,
1223 struct wpa_interface iface;
1227 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
1228 * TAB<bridge_ifname>
1230 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd);
1232 os_memset(&iface, 0, sizeof(iface));
1235 iface.ifname = pos = cmd;
1236 pos = os_strchr(pos, '\t');
1239 if (iface.ifname[0] == '\0')
1244 iface.confname = pos;
1245 pos = os_strchr(pos, '\t');
1248 if (iface.confname[0] == '\0')
1249 iface.confname = NULL;
1254 pos = os_strchr(pos, '\t');
1257 if (iface.driver[0] == '\0')
1258 iface.driver = NULL;
1262 iface.ctrl_interface = pos;
1263 pos = os_strchr(pos, '\t');
1266 if (iface.ctrl_interface[0] == '\0')
1267 iface.ctrl_interface = NULL;
1271 iface.driver_param = pos;
1272 pos = os_strchr(pos, '\t');
1275 if (iface.driver_param[0] == '\0')
1276 iface.driver_param = NULL;
1280 iface.bridge_ifname = pos;
1281 pos = os_strchr(pos, '\t');
1284 if (iface.bridge_ifname[0] == '\0')
1285 iface.bridge_ifname = NULL;
1290 if (wpa_supplicant_get_iface(global, iface.ifname))
1293 return wpa_supplicant_add_iface(global, &iface) ? 0 : -1;
1297 static int wpa_supplicant_global_iface_remove(struct wpa_global *global,
1300 struct wpa_supplicant *wpa_s;
1302 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd);
1304 wpa_s = wpa_supplicant_get_iface(global, cmd);
1307 return wpa_supplicant_remove_iface(global, wpa_s);
1311 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
1316 struct wpa_supplicant *wpa_s;
1318 wpa_s = global->ifaces;
1323 res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname);
1324 if (res < 0 || res >= end - pos) {
1329 wpa_s = wpa_s->next;
1335 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
1336 char *buf, size_t *resp_len)
1339 const int reply_size = 2048;
1342 wpa_hexdump_ascii(MSG_DEBUG, "RX global ctrl_iface",
1343 (const u8 *) buf, os_strlen(buf));
1345 reply = os_malloc(reply_size);
1346 if (reply == NULL) {
1351 os_memcpy(reply, "OK\n", 3);
1354 if (os_strcmp(buf, "PING") == 0) {
1355 os_memcpy(reply, "PONG\n", 5);
1357 } else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) {
1358 if (wpa_supplicant_global_iface_add(global, buf + 14))
1360 } else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) {
1361 if (wpa_supplicant_global_iface_remove(global, buf + 17))
1363 } else if (os_strcmp(buf, "INTERFACES") == 0) {
1364 reply_len = wpa_supplicant_global_iface_interfaces(
1365 global, reply, reply_size);
1366 } else if (os_strcmp(buf, "TERMINATE") == 0) {
1369 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
1373 if (reply_len < 0) {
1374 os_memcpy(reply, "FAIL\n", 5);
1378 *resp_len = reply_len;