#include "common/ieee802_11_defs.h"
#include "common/ieee802_11_common.h"
#include "common/wpa_ctrl.h"
+#ifdef CONFIG_DPP
+#include "common/dpp.h"
+#endif /* CONFIG_DPP */
#include "crypto/tls.h"
#include "ap/hostapd.h"
#include "eap_peer/eap.h"
#include "offchannel.h"
#include "drivers/driver.h"
#include "mesh.h"
+#include "dpp_supplicant.h"
+#include "sme.h"
static int wpa_supplicant_global_iface_list(struct wpa_global *global,
char *buf, int len);
static int * freq_range_to_channel_list(struct wpa_supplicant *wpa_s,
char *val);
+
static int set_bssid_filter(struct wpa_supplicant *wpa_s, char *val)
{
char *pos;
}
+static int
+wpas_ctrl_set_relative_rssi(struct wpa_supplicant *wpa_s, const char *cmd)
+{
+ int relative_rssi;
+
+ if (os_strcmp(cmd, "disable") == 0) {
+ wpa_s->srp.relative_rssi_set = 0;
+ return 0;
+ }
+
+ relative_rssi = atoi(cmd);
+ if (relative_rssi < 0 || relative_rssi > 100)
+ return -1;
+ wpa_s->srp.relative_rssi = relative_rssi;
+ wpa_s->srp.relative_rssi_set = 1;
+ return 0;
+}
+
+
+static int wpas_ctrl_set_relative_band_adjust(struct wpa_supplicant *wpa_s,
+ const char *cmd)
+{
+ char *pos;
+ int adjust_rssi;
+
+ /* <band>:adjust_value */
+ pos = os_strchr(cmd, ':');
+ if (!pos)
+ return -1;
+ pos++;
+ adjust_rssi = atoi(pos);
+ if (adjust_rssi < -100 || adjust_rssi > 100)
+ return -1;
+
+ if (os_strncmp(cmd, "2G", 2) == 0)
+ wpa_s->srp.relative_adjust_band = WPA_SETBAND_2G;
+ else if (os_strncmp(cmd, "5G", 2) == 0)
+ wpa_s->srp.relative_adjust_band = WPA_SETBAND_5G;
+ else
+ return -1;
+
+ wpa_s->srp.relative_adjust_rssi = adjust_rssi;
+
+ return 0;
+}
+
+
+static int wpas_ctrl_iface_set_ric_ies(struct wpa_supplicant *wpa_s,
+ const char *cmd)
+{
+ struct wpabuf *ric_ies;
+
+ if (*cmd == '\0' || os_strcmp(cmd, "\"\"") == 0) {
+ wpabuf_free(wpa_s->ric_ies);
+ wpa_s->ric_ies = NULL;
+ return 0;
+ }
+
+ ric_ies = wpabuf_parse_bin(cmd);
+ if (!ric_ies)
+ return -1;
+
+ wpabuf_free(wpa_s->ric_ies);
+ wpa_s->ric_ies = ric_ies;
+
+ return 0;
+}
+
+
static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
char *cmd)
{
-1, -1, -1, atoi(value));
} else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) {
if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
- atoi(value)))
+ atoi(value))) {
ret = -1;
+ } else {
+ value[-1] = '=';
+ wpa_config_process_global(wpa_s->conf, cmd, -1);
+ }
} else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") ==
0) {
if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
- atoi(value)))
+ atoi(value))) {
ret = -1;
+ } else {
+ value[-1] = '=';
+ wpa_config_process_global(wpa_s->conf, cmd, -1);
+ }
} else if (os_strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) {
- if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value)))
+ if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
+ atoi(value))) {
ret = -1;
+ } else {
+ value[-1] = '=';
+ wpa_config_process_global(wpa_s->conf, cmd, -1);
+ }
} else if (os_strcasecmp(cmd, "wps_fragment_size") == 0) {
wpa_s->wps_fragment_size = atoi(value);
#ifdef CONFIG_WPS_TESTING
ret = set_disallow_aps(wpa_s, value);
} else if (os_strcasecmp(cmd, "no_keep_alive") == 0) {
wpa_s->no_keep_alive = !!atoi(value);
+#ifdef CONFIG_DPP
+ } else if (os_strcasecmp(cmd, "dpp_configurator_params") == 0) {
+ os_free(wpa_s->dpp_configurator_params);
+ wpa_s->dpp_configurator_params = os_strdup(value);
+ } else if (os_strcasecmp(cmd, "dpp_init_max_tries") == 0) {
+ wpa_s->dpp_init_max_tries = atoi(value);
+ } else if (os_strcasecmp(cmd, "dpp_init_retry_time") == 0) {
+ wpa_s->dpp_init_retry_time = atoi(value);
+ } else if (os_strcasecmp(cmd, "dpp_resp_wait_time") == 0) {
+ wpa_s->dpp_resp_wait_time = atoi(value);
+ } else if (os_strcasecmp(cmd, "dpp_resp_max_tries") == 0) {
+ wpa_s->dpp_resp_max_tries = atoi(value);
+ } else if (os_strcasecmp(cmd, "dpp_resp_retry_time") == 0) {
+ wpa_s->dpp_resp_retry_time = atoi(value);
+#ifdef CONFIG_TESTING_OPTIONS
+ } else if (os_strcasecmp(cmd, "dpp_pkex_own_mac_override") == 0) {
+ if (hwaddr_aton(value, dpp_pkex_own_mac_override))
+ ret = -1;
+ } else if (os_strcasecmp(cmd, "dpp_pkex_peer_mac_override") == 0) {
+ if (hwaddr_aton(value, dpp_pkex_peer_mac_override))
+ ret = -1;
+ } else if (os_strcasecmp(cmd, "dpp_pkex_ephemeral_key_override") == 0) {
+ size_t hex_len = os_strlen(value);
+
+ if (hex_len >
+ 2 * sizeof(dpp_pkex_ephemeral_key_override))
+ ret = -1;
+ else if (hexstr2bin(value, dpp_pkex_ephemeral_key_override,
+ hex_len / 2))
+ ret = -1;
+ else
+ dpp_pkex_ephemeral_key_override_len = hex_len / 2;
+ } else if (os_strcasecmp(cmd, "dpp_protocol_key_override") == 0) {
+ size_t hex_len = os_strlen(value);
+
+ if (hex_len > 2 * sizeof(dpp_protocol_key_override))
+ ret = -1;
+ else if (hexstr2bin(value, dpp_protocol_key_override,
+ hex_len / 2))
+ ret = -1;
+ else
+ dpp_protocol_key_override_len = hex_len / 2;
+ } else if (os_strcasecmp(cmd, "dpp_nonce_override") == 0) {
+ size_t hex_len = os_strlen(value);
+
+ if (hex_len > 2 * sizeof(dpp_nonce_override))
+ ret = -1;
+ else if (hexstr2bin(value, dpp_nonce_override, hex_len / 2))
+ ret = -1;
+ else
+ dpp_nonce_override_len = hex_len / 2;
+#endif /* CONFIG_TESTING_OPTIONS */
+#endif /* CONFIG_DPP */
#ifdef CONFIG_TESTING_OPTIONS
} else if (os_strcasecmp(cmd, "ext_mgmt_frame_handling") == 0) {
wpa_s->ext_mgmt_frame_handling = !!atoi(value);
wpa_s->test_failure = atoi(value);
} else if (os_strcasecmp(cmd, "p2p_go_csa_on_inv") == 0) {
wpa_s->p2p_go_csa_on_inv = !!atoi(value);
+ } else if (os_strcasecmp(cmd, "ignore_auth_resp") == 0) {
+ wpa_s->ignore_auth_resp = !!atoi(value);
+ } else if (os_strcasecmp(cmd, "ignore_assoc_disallow") == 0) {
+ wpa_s->ignore_assoc_disallow = !!atoi(value);
+ wpa_drv_ignore_assoc_disallow(wpa_s,
+ wpa_s->ignore_assoc_disallow);
+ } else if (os_strcasecmp(cmd, "reject_btm_req_reason") == 0) {
+ wpa_s->reject_btm_req_reason = atoi(value);
+ } else if (os_strcasecmp(cmd, "get_pref_freq_list_override") == 0) {
+ os_free(wpa_s->get_pref_freq_list_override);
+ if (!value[0])
+ wpa_s->get_pref_freq_list_override = NULL;
+ else
+ wpa_s->get_pref_freq_list_override = os_strdup(value);
+ } else if (os_strcasecmp(cmd, "sae_commit_override") == 0) {
+ wpabuf_free(wpa_s->sae_commit_override);
+ if (value[0] == '\0')
+ wpa_s->sae_commit_override = NULL;
+ else
+ wpa_s->sae_commit_override = wpabuf_parse_bin(value);
+#ifdef CONFIG_DPP
+ } else if (os_strcasecmp(cmd, "dpp_config_obj_override") == 0) {
+ os_free(wpa_s->dpp_config_obj_override);
+ if (value[0] == '\0')
+ wpa_s->dpp_config_obj_override = NULL;
+ else
+ wpa_s->dpp_config_obj_override = os_strdup(value);
+ } else if (os_strcasecmp(cmd, "dpp_discovery_override") == 0) {
+ os_free(wpa_s->dpp_discovery_override);
+ if (value[0] == '\0')
+ wpa_s->dpp_discovery_override = NULL;
+ else
+ wpa_s->dpp_discovery_override = os_strdup(value);
+ } else if (os_strcasecmp(cmd, "dpp_groups_override") == 0) {
+ os_free(wpa_s->dpp_groups_override);
+ if (value[0] == '\0')
+ wpa_s->dpp_groups_override = NULL;
+ else
+ wpa_s->dpp_groups_override = os_strdup(value);
+ } else if (os_strcasecmp(cmd,
+ "dpp_ignore_netaccesskey_mismatch") == 0) {
+ wpa_s->dpp_ignore_netaccesskey_mismatch = atoi(value);
+ } else if (os_strcasecmp(cmd, "dpp_test") == 0) {
+ dpp_test = atoi(value);
+#endif /* CONFIG_DPP */
#endif /* CONFIG_TESTING_OPTIONS */
+#ifdef CONFIG_FILS
+ } else if (os_strcasecmp(cmd, "disable_fils") == 0) {
+ wpa_s->disable_fils = !!atoi(value);
+ wpa_drv_disable_fils(wpa_s, wpa_s->disable_fils);
+ wpa_supplicant_set_default_scan_ies(wpa_s);
+#endif /* CONFIG_FILS */
#ifndef CONFIG_NO_CONFIG_BLOBS
} else if (os_strcmp(cmd, "blob") == 0) {
ret = wpas_ctrl_set_blob(wpa_s, value);
#ifdef CONFIG_MBO
} else if (os_strcasecmp(cmd, "non_pref_chan") == 0) {
ret = wpas_mbo_update_non_pref_chan(wpa_s, value);
+ if (ret == 0) {
+ value[-1] = '=';
+ wpa_config_process_global(wpa_s->conf, cmd, -1);
+ }
} else if (os_strcasecmp(cmd, "mbo_cell_capa") == 0) {
wpas_mbo_update_cell_capa(wpa_s, atoi(value));
+ } else if (os_strcasecmp(cmd, "oce") == 0) {
+ wpa_s->conf->oce = atoi(value);
+ if (wpa_s->conf->oce) {
+ if ((wpa_s->conf->oce & OCE_STA) &&
+ (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OCE_STA))
+ wpa_s->enable_oce = OCE_STA;
+
+ if ((wpa_s->conf->oce & OCE_STA_CFON) &&
+ (wpa_s->drv_flags &
+ WPA_DRIVER_FLAGS_OCE_STA_CFON)) {
+ /* TODO: Need to add STA-CFON support */
+ wpa_printf(MSG_ERROR,
+ "OCE STA-CFON feature is not yet supported");
+ return -1;
+ }
+ } else {
+ wpa_s->enable_oce = 0;
+ }
+ wpa_supplicant_set_default_scan_ies(wpa_s);
#endif /* CONFIG_MBO */
} else if (os_strcasecmp(cmd, "lci") == 0) {
ret = wpas_ctrl_iface_set_lci(wpa_s, value);
+ } else if (os_strcasecmp(cmd, "tdls_trigger_control") == 0) {
+ ret = wpa_drv_set_tdls_mode(wpa_s, atoi(value));
+ } else if (os_strcasecmp(cmd, "relative_rssi") == 0) {
+ ret = wpas_ctrl_set_relative_rssi(wpa_s, value);
+ } else if (os_strcasecmp(cmd, "relative_band_adjust") == 0) {
+ ret = wpas_ctrl_set_relative_band_adjust(wpa_s, value);
+ } else if (os_strcasecmp(cmd, "ric_ies") == 0) {
+ ret = wpas_ctrl_iface_set_ric_ies(wpa_s, value);
+ } else if (os_strcasecmp(cmd, "roaming") == 0) {
+ ret = wpa_drv_roaming(wpa_s, atoi(value), NULL);
+#ifdef CONFIG_WNM
+ } else if (os_strcasecmp(cmd, "coloc_intf_elems") == 0) {
+ struct wpabuf *elems;
+
+ elems = wpabuf_parse_bin(value);
+ if (!elems)
+ return -1;
+ wnm_set_coloc_intf_elems(wpa_s, elems);
+#endif /* CONFIG_WNM */
} else {
value[-1] = '=';
ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
#endif /* CONFIG_TESTING_GET_GTK */
} else if (os_strcmp(cmd, "tls_library") == 0) {
res = tls_get_library_version(buf, buflen);
+#ifdef CONFIG_TESTING_OPTIONS
+ } else if (os_strcmp(cmd, "anonce") == 0) {
+ return wpa_snprintf_hex(buf, buflen,
+ wpa_sm_get_anonce(wpa_s->wpa),
+ WPA_NONCE_LEN);
+#endif /* CONFIG_TESTING_OPTIONS */
} else {
res = wpa_config_get_value(cmd, wpa_s->conf, buf, buflen);
}
#endif /* IEEE8021X_EAPOL */
-#ifdef CONFIG_PEERKEY
-/* MLME-STKSTART.request(peer) */
-static int wpa_supplicant_ctrl_iface_stkstart(
- struct wpa_supplicant *wpa_s, char *addr)
-{
- u8 peer[ETH_ALEN];
-
- if (hwaddr_aton(addr, peer)) {
- wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid "
- "address '%s'", addr);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART " MACSTR,
- MAC2STR(peer));
-
- return wpa_sm_stkstart(wpa_s->wpa, peer);
-}
-#endif /* CONFIG_PEERKEY */
-
-
#ifdef CONFIG_TDLS
static int wpa_supplicant_ctrl_iface_tdls_discover(
"mode=P2P GO - group "
"formation\n");
break;
+ case WPAS_MODE_MESH:
+ ret = os_snprintf(pos, end - pos,
+ "mode=mesh\n");
+ break;
default:
ret = 0;
break;
#endif /* CONFIG_AP */
pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose);
}
+#ifdef CONFIG_SME
#ifdef CONFIG_SAE
if (wpa_s->wpa_state >= WPA_ASSOCIATED &&
#ifdef CONFIG_AP
pos += ret;
}
#endif /* CONFIG_SAE */
+#endif /* CONFIG_SME */
ret = os_snprintf(pos, end - pos, "wpa_state=%s\n",
wpa_supplicant_state_txt(wpa_s->wpa_state));
if (os_snprintf_error(end - pos, ret))
pos += res;
}
+#ifdef CONFIG_MACSEC
+ res = ieee802_1x_kay_get_status(wpa_s->kay, pos, end - pos);
+ if (res > 0)
+ pos += res;
+#endif /* CONFIG_MACSEC */
+
sess_id = eapol_sm_get_session_id(wpa_s->eapol, &sess_id_len);
if (sess_id) {
char *start = pos;
}
#endif /* CONFIG_WPS */
+ if (wpa_s->ieee80211ac) {
+ ret = os_snprintf(pos, end - pos, "ieee80211ac=1\n");
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+
#ifdef ANDROID
/*
* Allow using the STATUS command with default behavior, say for debug,
}
#endif /* CONFIG_SUITEB192 */
+#ifdef CONFIG_FILS
+ if (data.key_mgmt & WPA_KEY_MGMT_FILS_SHA256) {
+ ret = os_snprintf(pos, end - pos, "%sFILS-SHA256",
+ pos == start ? "" : "+");
+ if (os_snprintf_error(end - pos, ret))
+ return pos;
+ pos += ret;
+ }
+ if (data.key_mgmt & WPA_KEY_MGMT_FILS_SHA384) {
+ ret = os_snprintf(pos, end - pos, "%sFILS-SHA384",
+ pos == start ? "" : "+");
+ if (os_snprintf_error(end - pos, ret))
+ return pos;
+ pos += ret;
+ }
+#ifdef CONFIG_IEEE80211R
+ if (data.key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) {
+ ret = os_snprintf(pos, end - pos, "%sFT-FILS-SHA256",
+ pos == start ? "" : "+");
+ if (os_snprintf_error(end - pos, ret))
+ return pos;
+ pos += ret;
+ }
+ if (data.key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384) {
+ ret = os_snprintf(pos, end - pos, "%sFT-FILS-SHA384",
+ pos == start ? "" : "+");
+ if (os_snprintf_error(end - pos, ret))
+ return pos;
+ pos += ret;
+ }
+#endif /* CONFIG_IEEE80211R */
+#endif /* CONFIG_FILS */
+
+#ifdef CONFIG_OWE
+ if (data.key_mgmt & WPA_KEY_MGMT_OWE) {
+ ret = os_snprintf(pos, end - pos, "%sOWE",
+ pos == start ? "" : "+");
+ if (os_snprintf_error(end - pos, ret))
+ return pos;
+ pos += ret;
+ }
+#endif /* CONFIG_OWE */
+
+#ifdef CONFIG_DPP
+ if (data.key_mgmt & WPA_KEY_MGMT_DPP) {
+ ret = os_snprintf(pos, end - pos, "%sDPP",
+ pos == start ? "" : "+");
+ if (os_snprintf_error(end - pos, ret))
+ return pos;
+ pos += ret;
+ }
+#endif /* CONFIG_DPP */
+
if (data.key_mgmt & WPA_KEY_MGMT_OSEN) {
ret = os_snprintf(pos, end - pos, "%sOSEN",
pos == start ? "" : "+");
{
char *pos, *end;
int ret;
- const u8 *ie, *ie2, *osen_ie, *p2p, *mesh;
+ const u8 *ie, *ie2, *osen_ie, *p2p, *mesh, *owe;
mesh = wpa_bss_get_ie(bss, WLAN_EID_MESH_ID);
p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE);
if (osen_ie)
pos = wpa_supplicant_ie_txt(pos, end, "OSEN",
osen_ie, 2 + osen_ie[1]);
+ owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
+ if (owe) {
+ ret = os_snprintf(pos, end - pos,
+ ie2 ? "[OWE-TRANS]" : "[OWE-TRANS-OPEN]");
+ if (os_snprintf_error(end - pos, ret))
+ return -1;
+ pos += ret;
+ }
pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
if (!ie && !ie2 && !osen_ie && (bss->caps & IEEE80211_CAP_PRIVACY)) {
ret = os_snprintf(pos, end - pos, "[WEP]");
pos += ret;
}
#endif /* CONFIG_HS20 */
+#ifdef CONFIG_FILS
+ if (wpa_bss_get_ie(bss, WLAN_EID_FILS_INDICATION)) {
+ ret = os_snprintf(pos, end - pos, "[FILS]");
+ if (os_snprintf_error(end - pos, ret))
+ return -1;
+ pos += ret;
+ }
+#endif /* CONFIG_FILS */
#ifdef CONFIG_FST
if (wpa_bss_get_ie(bss, WLAN_EID_MULTI_BAND)) {
ret = os_snprintf(pos, end - pos, "[FST]");
if (pos) {
int *freqs = freq_range_to_channel_list(wpa_s, pos + 6);
if (freqs) {
- wpa_s->scan_req = MANUAL_SCAN_REQ;
- os_free(wpa_s->manual_scan_freqs);
- wpa_s->manual_scan_freqs = freqs;
+ os_free(wpa_s->select_network_scan_freqs);
+ wpa_s->select_network_scan_freqs = freqs;
}
}
wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK");
- ssid = wpa_config_add_network(wpa_s->conf);
+ ssid = wpa_supplicant_add_network(wpa_s);
if (ssid == NULL)
return -1;
- wpas_notify_network_added(wpa_s, ssid);
-
- ssid->disabled = 1;
- wpa_config_set_network_defaults(ssid);
-
ret = os_snprintf(buf, buflen, "%d\n", ssid->id);
if (os_snprintf_error(buflen, ret))
return -1;
{
int id;
struct wpa_ssid *ssid;
- int was_disabled;
+ int result;
/* cmd: "<network id>" or "all" */
if (os_strcmp(cmd, "all") == 0) {
id = atoi(cmd);
wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id);
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid)
- wpas_notify_network_removed(wpa_s, ssid);
- if (ssid == NULL) {
+ result = wpa_supplicant_remove_network(wpa_s, id);
+ if (result == -1) {
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
"id=%d", id);
return -1;
}
-
- if (wpa_s->last_ssid == ssid)
- wpa_s->last_ssid = NULL;
-
- if (ssid == wpa_s->current_ssid || wpa_s->current_ssid == NULL) {
-#ifdef CONFIG_SME
- wpa_s->sme.prev_bssid_set = 0;
-#endif /* CONFIG_SME */
- /*
- * Invalidate the EAP session cache if the current or
- * previously used network is removed.
- */
- eapol_sm_invalidate_cached_session(wpa_s->eapol);
- }
-
- if (ssid == wpa_s->current_ssid) {
- wpa_sm_set_config(wpa_s->wpa, NULL);
- eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
-
- if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
- wpa_s->own_disconnect_req = 1;
- wpa_supplicant_deauthenticate(wpa_s,
- WLAN_REASON_DEAUTH_LEAVING);
- }
-
- was_disabled = ssid->disabled;
-
- if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
+ if (result == -2) {
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Not able to remove the "
"network id=%d", id);
return -1;
}
-
- if (!was_disabled && wpa_s->sched_scanning) {
- wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to remove "
- "network from filters");
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_supplicant_req_scan(wpa_s, 0, 0);
- }
-
return 0;
}
return 0; /* No change to the previously configured value */
if (os_strcmp(name, "bssid") != 0 &&
+ os_strcmp(name, "bssid_hint") != 0 &&
os_strcmp(name, "priority") != 0) {
wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
pos += ret;
}
#endif /* CONFIG_SUITEB192 */
+#ifdef CONFIG_OWE
+ if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE) {
+ ret = os_snprintf(pos, end - pos, " OWE");
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+#endif /* CONFIG_OWE */
+#ifdef CONFIG_DPP
+ if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP) {
+ ret = os_snprintf(pos, end - pos, " DPP");
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+#endif /* CONFIG_DPP */
+#ifdef CONFIG_FILS
+ if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256) {
+ ret = os_snprintf(pos, end - pos, " FILS-SHA256");
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+ if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384) {
+ ret = os_snprintf(pos, end - pos, " FILS-SHA384");
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+#ifdef CONFIG_IEEE80211R
+ if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256) {
+ ret = os_snprintf(pos, end - pos, " FT-FILS-SHA256");
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+ if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384) {
+ ret = os_snprintf(pos, end - pos, " FT-FILS-SHA384");
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+#endif /* CONFIG_IEEE80211R */
+#endif /* CONFIG_FILS */
+#ifdef CONFIG_SAE
+ if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE) {
+ ret = os_snprintf(pos, end - pos, " SAE");
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+#endif /* CONFIG_SAE */
return pos - buf;
}
}
#endif /* CONFIG_SAE */
+#ifdef CONFIG_FILS
+ if (wpa_is_fils_supported(wpa_s)) {
+ ret = os_snprintf(pos, end - pos, "%sFILS_SK_WITHOUT_PFS",
+ pos == buf ? "" : " ");
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+
+#ifdef CONFIG_FILS_SK_PFS
+ if (wpa_is_fils_sk_pfs_supported(wpa_s)) {
+ ret = os_snprintf(pos, end - pos, "%sFILS_SK_WITH_PFS",
+ pos == buf ? "" : " ");
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+#endif /* CONFIG_FILS_SK_PFS */
+#endif /* CONFIG_FILS */
+
return pos - buf;
}
}
#endif /* CONFIG_ACS */
+#ifdef CONFIG_FILS
+ if (os_strcmp(field, "fils") == 0) {
+#ifdef CONFIG_FILS_SK_PFS
+ if (wpa_is_fils_supported(wpa_s) &&
+ wpa_is_fils_sk_pfs_supported(wpa_s)) {
+ res = os_snprintf(buf, buflen, "FILS FILS-SK-PFS");
+ if (os_snprintf_error(buflen, res))
+ return -1;
+ return res;
+ }
+#endif /* CONFIG_FILS_SK_PFS */
+
+ if (wpa_is_fils_supported(wpa_s)) {
+ res = os_snprintf(buf, buflen, "FILS");
+ if (os_snprintf_error(buflen, res))
+ return -1;
+ return res;
+ }
+ }
+#endif /* CONFIG_FILS */
+
+ if (os_strcmp(field, "multibss") == 0 && wpa_s->multi_bss_support) {
+ res = os_snprintf(buf, buflen, "MULTIBSS-STA");
+ if (os_snprintf_error(buflen, res))
+ return -1;
+ return res;
+ }
+
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
field);
#endif /* CONFIG_INTERWORKING */
-static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
- unsigned long mask, char *buf, size_t buflen)
+#ifdef CONFIG_FILS
+static int print_fils_indication(struct wpa_bss *bss, char *pos, char *end)
{
- size_t i;
+ char *start = pos;
+ const u8 *ie, *ie_end;
+ u16 info, realms;
int ret;
- char *pos, *end;
- const u8 *ie, *ie2, *osen_ie;
- pos = buf;
- end = buf + buflen;
+ ie = wpa_bss_get_ie(bss, WLAN_EID_FILS_INDICATION);
+ if (!ie)
+ return 0;
+ ie_end = ie + 2 + ie[1];
+ ie += 2;
+ if (ie_end - ie < 2)
+ return -1;
- if (mask & WPA_BSS_MASK_ID) {
- ret = os_snprintf(pos, end - pos, "id=%u\n", bss->id);
+ info = WPA_GET_LE16(ie);
+ ie += 2;
+ ret = os_snprintf(pos, end - pos, "fils_info=%04x\n", info);
+ if (os_snprintf_error(end - pos, ret))
+ return 0;
+ pos += ret;
+
+ if (info & BIT(7)) {
+ /* Cache Identifier Included */
+ if (ie_end - ie < 2)
+ return -1;
+ ret = os_snprintf(pos, end - pos, "fils_cache_id=%02x%02x\n",
+ ie[0], ie[1]);
if (os_snprintf_error(end - pos, ret))
return 0;
pos += ret;
+ ie += 2;
}
- if (mask & WPA_BSS_MASK_BSSID) {
- ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
- MAC2STR(bss->bssid));
+ if (info & BIT(8)) {
+ /* HESSID Included */
+ if (ie_end - ie < ETH_ALEN)
+ return -1;
+ ret = os_snprintf(pos, end - pos, "fils_hessid=" MACSTR "\n",
+ MAC2STR(ie));
if (os_snprintf_error(end - pos, ret))
return 0;
pos += ret;
+ ie += ETH_ALEN;
}
- if (mask & WPA_BSS_MASK_FREQ) {
- ret = os_snprintf(pos, end - pos, "freq=%d\n", bss->freq);
+ realms = (info & (BIT(3) | BIT(4) | BIT(5))) >> 3;
+ if (realms) {
+ if (ie_end - ie < realms * 2)
+ return -1;
+ ret = os_snprintf(pos, end - pos, "fils_realms=");
if (os_snprintf_error(end - pos, ret))
return 0;
pos += ret;
- }
- if (mask & WPA_BSS_MASK_BEACON_INT) {
- ret = os_snprintf(pos, end - pos, "beacon_int=%d\n",
- bss->beacon_int);
- if (os_snprintf_error(end - pos, ret))
+ ret = wpa_snprintf_hex(pos, end - pos, ie, realms * 2);
+ if (ret <= 0)
+ return 0;
+ pos += ret;
+ ie += realms * 2;
+ ret = os_snprintf(pos, end - pos, "\n");
+ if (os_snprintf_error(end - pos, ret))
+ return 0;
+ pos += ret;
+ }
+
+ return pos - start;
+}
+#endif /* CONFIG_FILS */
+
+
+static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
+ unsigned long mask, char *buf, size_t buflen)
+{
+ size_t i;
+ int ret;
+ char *pos, *end;
+ const u8 *ie, *ie2, *osen_ie, *mesh, *owe;
+
+ pos = buf;
+ end = buf + buflen;
+
+ if (mask & WPA_BSS_MASK_ID) {
+ ret = os_snprintf(pos, end - pos, "id=%u\n", bss->id);
+ if (os_snprintf_error(end - pos, ret))
+ return 0;
+ pos += ret;
+ }
+
+ if (mask & WPA_BSS_MASK_BSSID) {
+ ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
+ MAC2STR(bss->bssid));
+ if (os_snprintf_error(end - pos, ret))
+ return 0;
+ pos += ret;
+ }
+
+ if (mask & WPA_BSS_MASK_FREQ) {
+ ret = os_snprintf(pos, end - pos, "freq=%d\n", bss->freq);
+ if (os_snprintf_error(end - pos, ret))
+ return 0;
+ pos += ret;
+ }
+
+ if (mask & WPA_BSS_MASK_BEACON_INT) {
+ ret = os_snprintf(pos, end - pos, "beacon_int=%d\n",
+ bss->beacon_int);
+ if (os_snprintf_error(end - pos, ret))
return 0;
pos += ret;
}
return 0;
pos += ret;
+ mesh = wpa_bss_get_ie(bss, WLAN_EID_MESH_ID);
+
ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
if (ie)
pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie,
2 + ie[1]);
ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
if (ie2)
- pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2,
+ pos = wpa_supplicant_ie_txt(pos, end,
+ mesh ? "RSN" : "WPA2", ie2,
2 + ie2[1]);
osen_ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
if (osen_ie)
pos = wpa_supplicant_ie_txt(pos, end, "OSEN",
osen_ie, 2 + osen_ie[1]);
+ owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
+ if (owe) {
+ ret = os_snprintf(
+ pos, end - pos,
+ ie2 ? "[OWE-TRANS]" : "[OWE-TRANS-OPEN]");
+ if (os_snprintf_error(end - pos, ret))
+ return 0;
+ pos += ret;
+ }
pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
if (!ie && !ie2 && !osen_ie &&
(bss->caps & IEEE80211_CAP_PRIVACY)) {
return 0;
pos += ret;
}
+
+ if (mesh) {
+ ret = os_snprintf(pos, end - pos, "[MESH]");
+ if (os_snprintf_error(end - pos, ret))
+ return 0;
+ pos += ret;
+ }
+
if (bss_is_dmg(bss)) {
const char *s;
ret = os_snprintf(pos, end - pos, "[DMG]");
pos += ret;
}
#endif /* CONFIG_HS20 */
+#ifdef CONFIG_FILS
+ if (wpa_bss_get_ie(bss, WLAN_EID_FILS_INDICATION)) {
+ ret = os_snprintf(pos, end - pos, "[FILS]");
+ if (os_snprintf_error(end - pos, ret))
+ return 0;
+ pos += ret;
+ }
+#endif /* CONFIG_FILS */
ret = os_snprintf(pos, end - pos, "\n");
if (os_snprintf_error(end - pos, ret))
pos = anqp_add_hex(pos, end, "anqp_3gpp", anqp->anqp_3gpp);
pos = anqp_add_hex(pos, end, "anqp_domain_name",
anqp->domain_name);
+ pos = anqp_add_hex(pos, end, "anqp_fils_realm_info",
+ anqp->fils_realm_info);
#ifdef CONFIG_HS20
pos = anqp_add_hex(pos, end, "hs20_capability_list",
anqp->hs20_capability_list);
anqp->hs20_operating_class);
pos = anqp_add_hex(pos, end, "hs20_osu_providers_list",
anqp->hs20_osu_providers_list);
+ pos = anqp_add_hex(pos, end, "hs20_operator_icon_metadata",
+ anqp->hs20_operator_icon_metadata);
+ pos = anqp_add_hex(pos, end, "hs20_osu_providers_nai_list",
+ anqp->hs20_osu_providers_nai_list);
#endif /* CONFIG_HS20 */
dl_list_for_each(elem, &anqp->anqp_elems,
}
#endif /* CONFIG_FST */
+ if (mask & WPA_BSS_MASK_UPDATE_IDX) {
+ ret = os_snprintf(pos, end - pos, "update_idx=%u\n",
+ bss->last_update_idx);
+ if (os_snprintf_error(end - pos, ret))
+ return 0;
+ pos += ret;
+ }
+
+ if ((mask & WPA_BSS_MASK_BEACON_IE) && bss->beacon_ie_len) {
+ ret = os_snprintf(pos, end - pos, "beacon_ie=");
+ if (os_snprintf_error(end - pos, ret))
+ return 0;
+ pos += ret;
+
+ ie = (const u8 *) (bss + 1);
+ ie += bss->ie_len;
+ for (i = 0; i < bss->beacon_ie_len; i++) {
+ ret = os_snprintf(pos, end - pos, "%02x", *ie++);
+ if (os_snprintf_error(end - pos, ret))
+ return 0;
+ pos += ret;
+ }
+
+ ret = os_snprintf(pos, end - pos, "\n");
+ if (os_snprintf_error(end - pos, ret))
+ return 0;
+ pos += ret;
+ }
+
+#ifdef CONFIG_FILS
+ if (mask & WPA_BSS_MASK_FILS_INDICATION) {
+ ret = print_fils_indication(bss, pos, end);
+ if (ret < 0)
+ return 0;
+ pos += ret;
+ }
+#endif /* CONFIG_FILS */
+
if (mask & WPA_BSS_MASK_DELIM) {
ret = os_snprintf(pos, end - pos, "====\n");
if (os_snprintf_error(end - pos, ret))
bss = dl_list_entry(next, struct wpa_bss,
list_id);
}
+ } else if (os_strncmp(cmd, "CURRENT", 7) == 0) {
+ bss = wpa_s->current_bss;
#ifdef CONFIG_P2P
} else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) {
if (hwaddr_aton(cmd + 13, bssid) == 0)
int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
int max_oper_chwidth, chwidth = 0, freq2 = 0;
char *token, *context = NULL;
+#ifdef CONFIG_ACS
+ int acs = 0;
+#endif /* CONFIG_ACS */
while ((token = str_token(cmd, " ", &context))) {
- if (sscanf(token, "freq=%d", &freq) == 1 ||
- sscanf(token, "freq2=%d", &freq2) == 1 ||
+ if (sscanf(token, "freq2=%d", &freq2) == 1 ||
sscanf(token, "persistent=%d", &group_id) == 1 ||
sscanf(token, "max_oper_chwidth=%d", &chwidth) == 1) {
continue;
+#ifdef CONFIG_ACS
+ } else if (os_strcmp(token, "freq=acs") == 0) {
+ acs = 1;
+#endif /* CONFIG_ACS */
+ } else if (sscanf(token, "freq=%d", &freq) == 1) {
+ continue;
} else if (os_strcmp(token, "ht40") == 0) {
ht40 = 1;
} else if (os_strcmp(token, "vht") == 0) {
}
}
+#ifdef CONFIG_ACS
+ if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) &&
+ (acs || freq == 2 || freq == 5)) {
+ if (freq == 2 && wpa_s->best_24_freq <= 0) {
+ wpa_s->p2p_go_acs_band = HOSTAPD_MODE_IEEE80211G;
+ wpa_s->p2p_go_do_acs = 1;
+ freq = 0;
+ } else if (freq == 5 && wpa_s->best_5_freq <= 0) {
+ wpa_s->p2p_go_acs_band = HOSTAPD_MODE_IEEE80211A;
+ wpa_s->p2p_go_do_acs = 1;
+ freq = 0;
+ } else {
+ wpa_s->p2p_go_acs_band = HOSTAPD_MODE_IEEE80211ANY;
+ wpa_s->p2p_go_do_acs = 1;
+ }
+ }
+#endif /* CONFIG_ACS */
+
max_oper_chwidth = parse_freq(chwidth, freq2);
if (max_oper_chwidth < 0)
return -1;
}
+static int wpas_find_p2p_dev_addr_bss(struct wpa_global *global,
+ const u8 *p2p_dev_addr)
+{
+ struct wpa_supplicant *wpa_s;
+
+ for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
+ if (wpa_bss_get_p2p_dev_addr(wpa_s, p2p_dev_addr))
+ return 1;
+ }
+
+ return 0;
+}
+
+
static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
char *buf, size_t buflen)
{
- u8 addr[ETH_ALEN], *addr_ptr;
+ u8 addr[ETH_ALEN], *addr_ptr, group_capab;
int next, res;
const struct p2p_peer_info *info;
char *pos, *end;
info = p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next);
if (info == NULL)
return -1;
+ group_capab = info->group_capab;
+
+ if (group_capab &&
+ !wpas_find_p2p_dev_addr_bss(wpa_s->global, info->p2p_device_addr)) {
+ wpa_printf(MSG_DEBUG,
+ "P2P: Could not find any BSS with p2p_dev_addr "
+ MACSTR ", hence override group_capab from 0x%x to 0",
+ MAC2STR(info->p2p_device_addr), group_capab);
+ group_capab = 0;
+ }
pos = buf;
end = buf + buflen;
info->serial_number,
info->config_methods,
info->dev_capab,
- info->group_capab,
+ group_capab,
info->level);
if (os_snprintf_error(end - pos, res))
return pos - buf;
return 0;
}
+ if (os_strcmp(cmd, "override_pref_op_chan") == 0) {
+ int op_class, chan;
+
+ op_class = atoi(param);
+ param = os_strchr(param, ':');
+ if (!param)
+ return -1;
+ param++;
+ chan = atoi(param);
+ p2p_set_override_pref_op_chan(wpa_s->global->p2p, op_class,
+ chan);
+ return 0;
+ }
+
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
cmd);
{
os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
wpa_s->force_long_sd = 0;
+
+#ifdef CONFIG_TESTING_OPTIONS
+ os_free(wpa_s->get_pref_freq_list_override);
+ wpa_s->get_pref_freq_list_override = NULL;
+#endif /* CONFIG_TESTING_OPTIONS */
+
wpas_p2p_stop_find(wpa_s);
wpa_s->parent->p2ps_method_config_any = 0;
if (wpa_s->global->p2p)
u16 id[MAX_ANQP_INFO_ID];
size_t num_id = 0;
u32 subtypes = 0;
+ u32 mbo_subtypes = 0;
used = hwaddr_aton2(dst, dst_addr);
if (used < 0)
#else /* CONFIG_HS20 */
return -1;
#endif /* CONFIG_HS20 */
+ } else if (os_strncmp(pos, "mbo:", 4) == 0) {
+#ifdef CONFIG_MBO
+ int num = atoi(pos + 4);
+
+ if (num <= 0 || num > MAX_MBO_ANQP_SUBTYPE)
+ return -1;
+ mbo_subtypes |= BIT(num);
+#else /* CONFIG_MBO */
+ return -1;
+#endif /* CONFIG_MBO */
} else {
id[num_id] = atoi(pos);
if (id[num_id])
pos++;
}
- if (num_id == 0)
+ if (num_id == 0 && !subtypes && !mbo_subtypes)
return -1;
- return anqp_send_req(wpa_s, dst_addr, id, num_id, subtypes);
+ return anqp_send_req(wpa_s, dst_addr, id, num_id, subtypes,
+ mbo_subtypes);
}
autoscan_init(wpa_s, 1);
else if (state == WPA_SCANNING)
wpa_supplicant_reinit_autoscan(wpa_s);
+ else
+ wpa_printf(MSG_DEBUG, "No autoscan update in state %s",
+ wpa_supplicant_state_txt(state));
return 0;
}
static int wpas_ctrl_iface_wnm_bss_query(struct wpa_supplicant *wpa_s, char *cmd)
{
int query_reason, list = 0;
+ char *btm_candidates = NULL;
query_reason = atoi(cmd);
cmd = os_strchr(cmd, ' ');
if (cmd) {
- cmd++;
- if (os_strncmp(cmd, "list", 4) == 0) {
+ if (os_strncmp(cmd, " list", 5) == 0)
list = 1;
- } else {
- wpa_printf(MSG_DEBUG, "WNM Query: Invalid option %s",
- cmd);
- return -1;
- }
+ else
+ btm_candidates = cmd;
}
wpa_printf(MSG_DEBUG,
"CTRL_IFACE: WNM_BSS_QUERY query_reason=%d%s",
query_reason, list ? " candidate list" : "");
- return wnm_send_bss_transition_mgmt_query(wpa_s, query_reason, list);
+ return wnm_send_bss_transition_mgmt_query(wpa_s, query_reason,
+ btm_candidates,
+ list);
+}
+
+
+static int wpas_ctrl_iface_coloc_intf_report(struct wpa_supplicant *wpa_s,
+ char *cmd)
+{
+ struct wpabuf *elems;
+ int ret;
+
+ elems = wpabuf_parse_bin(cmd);
+ if (!elems)
+ return -1;
+
+ ret = wnm_send_coloc_intf_report(wpa_s, 0, elems);
+ wpabuf_free(elems);
+ return ret;
}
#endif /* CONFIG_WNM */
pos += ret;
}
- if (si.center_frq1 > 0 && si.center_frq2 > 0) {
- ret = os_snprintf(pos, end - pos,
- "CENTER_FRQ1=%d\nCENTER_FRQ2=%d\n",
- si.center_frq1, si.center_frq2);
+ if (si.center_frq1 > 0) {
+ ret = os_snprintf(pos, end - pos, "CENTER_FRQ1=%d\n",
+ si.center_frq1);
+ if (os_snprintf_error(end - pos, ret))
+ return -1;
+ pos += ret;
+ }
+
+ if (si.center_frq2 > 0) {
+ ret = os_snprintf(pos, end - pos, "CENTER_FRQ2=%d\n",
+ si.center_frq2);
if (os_snprintf_error(end - pos, ret))
return -1;
pos += ret;
}
+#ifdef CONFIG_TESTING_OPTIONS
+int wpas_ctrl_iface_get_pref_freq_list_override(struct wpa_supplicant *wpa_s,
+ enum wpa_driver_if_type if_type,
+ unsigned int *num,
+ unsigned int *freq_list)
+{
+ char *pos = wpa_s->get_pref_freq_list_override;
+ char *end;
+ unsigned int count = 0;
+
+ /* Override string format:
+ * <if_type1>:<freq1>,<freq2>,... <if_type2>:... */
+
+ while (pos) {
+ if (atoi(pos) == (int) if_type)
+ break;
+ pos = os_strchr(pos, ' ');
+ if (pos)
+ pos++;
+ }
+ if (!pos)
+ return -1;
+ pos = os_strchr(pos, ':');
+ if (!pos)
+ return -1;
+ pos++;
+ end = os_strchr(pos, ' ');
+ while (pos && (!end || pos < end) && count < *num) {
+ freq_list[count++] = atoi(pos);
+ pos = os_strchr(pos, ',');
+ if (pos)
+ pos++;
+ }
+
+ *num = count;
+ return 0;
+}
+#endif /* CONFIG_TESTING_OPTIONS */
+
+
static int wpas_ctrl_iface_get_pref_freq_list(
struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
{
}
+static int wpas_ctrl_iface_driver_flags(struct wpa_supplicant *wpa_s,
+ char *buf, size_t buflen)
+{
+ int ret, i;
+ char *pos, *end;
+
+ ret = os_snprintf(buf, buflen, "%016llX:\n",
+ (long long unsigned) wpa_s->drv_flags);
+ if (os_snprintf_error(buflen, ret))
+ return -1;
+
+ pos = buf + ret;
+ end = buf + buflen;
+
+ for (i = 0; i < 64; i++) {
+ if (wpa_s->drv_flags & (1LLU << i)) {
+ ret = os_snprintf(pos, end - pos, "%s\n",
+ driver_flag_to_string(1LLU << i));
+ if (os_snprintf_error(end - pos, ret))
+ return -1;
+ pos += ret;
+ }
+ }
+
+ return pos - buf;
+}
+
+
static int wpa_supplicant_pktcnt_poll(struct wpa_supplicant *wpa_s, char *buf,
size_t buflen)
{
wpa_dbg(wpa_s, MSG_DEBUG, "Flush all wpa_supplicant state");
- wpas_abort_ongoing_scan(wpa_s);
+ if (wpas_abort_ongoing_scan(wpa_s) == 0)
+ wpa_s->ignore_post_flush_scan_res = 1;
if (wpa_s->wpa_state >= WPA_AUTHENTICATING) {
/*
wpa_s->after_wps = 0;
wpa_s->known_wps_freq = 0;
+#ifdef CONFIG_DPP
+ wpas_dpp_deinit(wpa_s);
+ wpa_s->dpp_init_max_tries = 0;
+ wpa_s->dpp_init_retry_time = 0;
+ wpa_s->dpp_resp_wait_time = 0;
+ wpa_s->dpp_resp_max_tries = 0;
+ wpa_s->dpp_resp_retry_time = 0;
+#ifdef CONFIG_TESTING_OPTIONS
+ os_memset(dpp_pkex_own_mac_override, 0, ETH_ALEN);
+ os_memset(dpp_pkex_peer_mac_override, 0, ETH_ALEN);
+ dpp_pkex_ephemeral_key_override_len = 0;
+ dpp_protocol_key_override_len = 0;
+ dpp_nonce_override_len = 0;
+#endif /* CONFIG_TESTING_OPTIONS */
+#endif /* CONFIG_DPP */
+
#ifdef CONFIG_TDLS
#ifdef CONFIG_TDLS_TESTING
tdls_testing = 0;
wpa_s->extra_roc_dur = 0;
wpa_s->test_failure = WPAS_TEST_FAILURE_NONE;
wpa_s->p2p_go_csa_on_inv = 0;
+ wpa_s->ignore_auth_resp = 0;
+ wpa_s->ignore_assoc_disallow = 0;
+ wpa_s->testing_resend_assoc = 0;
+ wpa_s->reject_btm_req_reason = 0;
wpa_sm_set_test_assoc_ie(wpa_s->wpa, NULL);
+ os_free(wpa_s->get_pref_freq_list_override);
+ wpa_s->get_pref_freq_list_override = NULL;
+ wpabuf_free(wpa_s->sae_commit_override);
+ wpa_s->sae_commit_override = NULL;
+#ifdef CONFIG_DPP
+ os_free(wpa_s->dpp_config_obj_override);
+ wpa_s->dpp_config_obj_override = NULL;
+ os_free(wpa_s->dpp_discovery_override);
+ wpa_s->dpp_discovery_override = NULL;
+ os_free(wpa_s->dpp_groups_override);
+ wpa_s->dpp_groups_override = NULL;
+ dpp_test = DPP_TEST_DISABLED;
+#endif /* CONFIG_DPP */
#endif /* CONFIG_TESTING_OPTIONS */
wpa_s->disconnected = 0;
os_free(wpa_s->next_scan_freqs);
wpa_s->next_scan_freqs = NULL;
+ os_free(wpa_s->select_network_scan_freqs);
+ wpa_s->select_network_scan_freqs = NULL;
wpa_bss_flush(wpa_s);
if (!dl_list_empty(&wpa_s->bss)) {
eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
wpa_s->wnmsleep_used = 0;
+
+#ifdef CONFIG_SME
+ wpa_s->sme.last_unprot_disconnect.sec = 0;
+#endif /* CONFIG_SME */
+
+ wpabuf_free(wpa_s->ric_ies);
+ wpa_s->ric_ies = NULL;
+
+ wpa_supplicant_update_channel_list(wpa_s, NULL);
}
goto done;
}
+ pos = os_strstr(params, "bssid=");
+ if (pos) {
+ u8 bssid[ETH_ALEN];
+
+ pos += 6;
+ if (hwaddr_aton(pos, bssid)) {
+ wpa_printf(MSG_ERROR, "Invalid BSSID %s", pos);
+ *reply_len = -1;
+ goto done;
+ }
+ os_memcpy(wpa_s->next_scan_bssid, bssid, ETH_ALEN);
+ }
+
pos = params;
while (pos && *pos != '\0') {
if (os_strncmp(pos, "ssid ", 5) == 0) {
}
+static int wpas_ctrl_iface_driver_scan_res(struct wpa_supplicant *wpa_s,
+ char *param)
+{
+ struct wpa_scan_res *res;
+ struct os_reltime now;
+ char *pos, *end;
+ int ret = -1;
+
+ if (!param)
+ return -1;
+
+ if (os_strcmp(param, "START") == 0) {
+ wpa_bss_update_start(wpa_s);
+ return 0;
+ }
+
+ if (os_strcmp(param, "END") == 0) {
+ wpa_bss_update_end(wpa_s, NULL, 1);
+ return 0;
+ }
+
+ if (os_strncmp(param, "BSS ", 4) != 0)
+ return -1;
+ param += 3;
+
+ res = os_zalloc(sizeof(*res) + os_strlen(param) / 2);
+ if (!res)
+ return -1;
+
+ pos = os_strstr(param, " flags=");
+ if (pos)
+ res->flags = strtol(pos + 7, NULL, 16);
+
+ pos = os_strstr(param, " bssid=");
+ if (pos && hwaddr_aton(pos + 7, res->bssid))
+ goto fail;
+
+ pos = os_strstr(param, " freq=");
+ if (pos)
+ res->freq = atoi(pos + 6);
+
+ pos = os_strstr(param, " beacon_int=");
+ if (pos)
+ res->beacon_int = atoi(pos + 12);
+
+ pos = os_strstr(param, " caps=");
+ if (pos)
+ res->caps = strtol(pos + 6, NULL, 16);
+
+ pos = os_strstr(param, " qual=");
+ if (pos)
+ res->qual = atoi(pos + 6);
+
+ pos = os_strstr(param, " noise=");
+ if (pos)
+ res->noise = atoi(pos + 7);
+
+ pos = os_strstr(param, " level=");
+ if (pos)
+ res->level = atoi(pos + 7);
+
+ pos = os_strstr(param, " tsf=");
+ if (pos)
+ res->tsf = strtoll(pos + 5, NULL, 16);
+
+ pos = os_strstr(param, " age=");
+ if (pos)
+ res->age = atoi(pos + 5);
+
+ pos = os_strstr(param, " est_throughput=");
+ if (pos)
+ res->est_throughput = atoi(pos + 16);
+
+ pos = os_strstr(param, " snr=");
+ if (pos)
+ res->snr = atoi(pos + 5);
+
+ pos = os_strstr(param, " parent_tsf=");
+ if (pos)
+ res->parent_tsf = strtoll(pos + 7, NULL, 16);
+
+ pos = os_strstr(param, " tsf_bssid=");
+ if (pos && hwaddr_aton(pos + 11, res->tsf_bssid))
+ goto fail;
+
+ pos = os_strstr(param, " ie=");
+ if (pos) {
+ pos += 4;
+ end = os_strchr(pos, ' ');
+ if (!end)
+ end = pos + os_strlen(pos);
+ res->ie_len = (end - pos) / 2;
+ if (hexstr2bin(pos, (u8 *) (res + 1), res->ie_len))
+ goto fail;
+ }
+
+ pos = os_strstr(param, " beacon_ie=");
+ if (pos) {
+ pos += 11;
+ end = os_strchr(pos, ' ');
+ if (!end)
+ end = pos + os_strlen(pos);
+ res->beacon_ie_len = (end - pos) / 2;
+ if (hexstr2bin(pos, ((u8 *) (res + 1)) + res->ie_len,
+ res->beacon_ie_len))
+ goto fail;
+ }
+
+ os_get_reltime(&now);
+ wpa_bss_update_scan_res(wpa_s, res, &now);
+ ret = 0;
+fail:
+ os_free(res);
+
+ return ret;
+}
+
+
static int wpas_ctrl_iface_driver_event(struct wpa_supplicant *wpa_s, char *cmd)
{
char *pos, *param;
wpa_supplicant_event(wpa_s, ev, &event);
os_free(event.freq_range.range);
return 0;
+ } else if (os_strcmp(cmd, "SCAN_RES") == 0) {
+ return wpas_ctrl_iface_driver_scan_res(wpa_s, param);
} else {
wpa_dbg(wpa_s, MSG_DEBUG, "Testing - unknown driver event: %s",
cmd);
struct iphdr ip;
const u8 *pos;
unsigned int i;
+ char extra[30];
- if (len != HWSIM_PACKETLEN)
+ if (len < sizeof(*eth) + sizeof(ip) || len > HWSIM_PACKETLEN) {
+ wpa_printf(MSG_DEBUG,
+ "test data: RX - ignore unexpected length %d",
+ (int) len);
return;
+ }
eth = (const struct ether_header *) buf;
os_memcpy(&ip, eth + 1, sizeof(ip));
pos = &buf[sizeof(*eth) + sizeof(ip)];
if (ip.ihl != 5 || ip.version != 4 ||
- ntohs(ip.tot_len) != HWSIM_IP_LEN)
+ ntohs(ip.tot_len) > HWSIM_IP_LEN) {
+ wpa_printf(MSG_DEBUG,
+ "test data: RX - ignore unexpect IP header");
return;
+ }
- for (i = 0; i < HWSIM_IP_LEN - sizeof(ip); i++) {
- if (*pos != (u8) i)
+ for (i = 0; i < ntohs(ip.tot_len) - sizeof(ip); i++) {
+ if (*pos != (u8) i) {
+ wpa_printf(MSG_DEBUG,
+ "test data: RX - ignore mismatching payload");
return;
+ }
pos++;
}
-
- wpa_msg(wpa_s, MSG_INFO, "DATA-TEST-RX " MACSTR " " MACSTR,
- MAC2STR(eth->ether_dhost), MAC2STR(eth->ether_shost));
+ extra[0] = '\0';
+ if (ntohs(ip.tot_len) != HWSIM_IP_LEN)
+ os_snprintf(extra, sizeof(extra), " len=%d", ntohs(ip.tot_len));
+ wpa_msg(wpa_s, MSG_INFO, "DATA-TEST-RX " MACSTR " " MACSTR "%s",
+ MAC2STR(eth->ether_dhost), MAC2STR(eth->ether_shost), extra);
}
static int wpas_ctrl_iface_data_test_tx(struct wpa_supplicant *wpa_s, char *cmd)
{
u8 dst[ETH_ALEN], src[ETH_ALEN];
- char *pos;
+ char *pos, *pos2;
int used;
long int val;
u8 tos;
struct iphdr *ip;
u8 *dpos;
unsigned int i;
+ size_t send_len = HWSIM_IP_LEN;
if (wpa_s->l2_test == NULL)
return -1;
- /* format: <dst> <src> <tos> */
+ /* format: <dst> <src> <tos> [len=<length>] */
pos = cmd;
used = hwaddr_aton2(pos, dst);
return -1;
pos += used;
- val = strtol(pos, NULL, 0);
+ val = strtol(pos, &pos2, 0);
if (val < 0 || val > 0xff)
return -1;
tos = val;
+ pos = os_strstr(pos2, " len=");
+ if (pos) {
+ i = atoi(pos + 5);
+ if (i < sizeof(*ip) || i > HWSIM_IP_LEN)
+ return -1;
+ send_len = i;
+ }
+
eth = (struct ether_header *) &buf[2];
os_memcpy(eth->ether_dhost, dst, ETH_ALEN);
os_memcpy(eth->ether_shost, src, ETH_ALEN);
ip->version = 4;
ip->ttl = 64;
ip->tos = tos;
- ip->tot_len = htons(HWSIM_IP_LEN);
+ ip->tot_len = htons(send_len);
ip->protocol = 1;
ip->saddr = htonl(192U << 24 | 168 << 16 | 1 << 8 | 1);
ip->daddr = htonl(192U << 24 | 168 << 16 | 1 << 8 | 2);
ip->check = ipv4_hdr_checksum(ip, sizeof(*ip));
dpos = (u8 *) (ip + 1);
- for (i = 0; i < HWSIM_IP_LEN - sizeof(*ip); i++)
+ for (i = 0; i < send_len - sizeof(*ip); i++)
*dpos++ = i;
if (l2_packet_send(wpa_s->l2_test, dst, ETHERTYPE_IP, &buf[2],
- HWSIM_PACKETLEN) < 0)
+ sizeof(struct ether_header) + send_len) < 0)
return -1;
wpa_dbg(wpa_s, MSG_DEBUG, "test data: TX dst=" MACSTR " src=" MACSTR
return 0;
}
+
+static int wpas_ctrl_reset_pn(struct wpa_supplicant *wpa_s)
+{
+ u8 zero[WPA_TK_MAX_LEN];
+
+ if (wpa_s->last_tk_alg == WPA_ALG_NONE)
+ return -1;
+
+ wpa_printf(MSG_INFO, "TESTING: Reset PN");
+ os_memset(zero, 0, sizeof(zero));
+
+ /* First, use a zero key to avoid any possible duplicate key avoidance
+ * in the driver. */
+ if (wpa_drv_set_key(wpa_s, wpa_s->last_tk_alg, wpa_s->last_tk_addr,
+ wpa_s->last_tk_key_idx, 1, zero, 6,
+ zero, wpa_s->last_tk_len) < 0)
+ return -1;
+
+ /* Set the previously configured key to reset its TSC/RSC */
+ return wpa_drv_set_key(wpa_s, wpa_s->last_tk_alg, wpa_s->last_tk_addr,
+ wpa_s->last_tk_key_idx, 1, zero, 6,
+ wpa_s->last_tk, wpa_s->last_tk_len);
+}
+
+
+static int wpas_ctrl_key_request(struct wpa_supplicant *wpa_s, const char *cmd)
+{
+ const char *pos = cmd;
+ int error, pairwise;
+
+ error = atoi(pos);
+ pos = os_strchr(pos, ' ');
+ if (!pos)
+ return -1;
+ pairwise = atoi(pos);
+ wpa_sm_key_request(wpa_s->wpa, error, pairwise);
+ return 0;
+}
+
+
+static int wpas_ctrl_resend_assoc(struct wpa_supplicant *wpa_s)
+{
+#ifdef CONFIG_SME
+ struct wpa_driver_associate_params params;
+ int ret;
+
+ os_memset(¶ms, 0, sizeof(params));
+ params.bssid = wpa_s->bssid;
+ params.ssid = wpa_s->sme.ssid;
+ params.ssid_len = wpa_s->sme.ssid_len;
+ params.freq.freq = wpa_s->sme.freq;
+ if (wpa_s->last_assoc_req_wpa_ie) {
+ params.wpa_ie = wpabuf_head(wpa_s->last_assoc_req_wpa_ie);
+ params.wpa_ie_len = wpabuf_len(wpa_s->last_assoc_req_wpa_ie);
+ }
+ params.pairwise_suite = wpa_s->pairwise_cipher;
+ params.group_suite = wpa_s->group_cipher;
+ params.mgmt_group_suite = wpa_s->mgmt_group_cipher;
+ params.key_mgmt_suite = wpa_s->key_mgmt;
+ params.wpa_proto = wpa_s->wpa_proto;
+ params.mgmt_frame_protection = wpa_s->sme.mfp;
+ params.rrm_used = wpa_s->rrm.rrm_used;
+ if (wpa_s->sme.prev_bssid_set)
+ params.prev_bssid = wpa_s->sme.prev_bssid;
+ wpa_printf(MSG_INFO, "TESTING: Resend association request");
+ ret = wpa_drv_associate(wpa_s, ¶ms);
+ wpa_s->testing_resend_assoc = 1;
+ return ret;
+#else /* CONFIG_SME */
+ return -1;
+#endif /* CONFIG_SME */
+}
+
#endif /* CONFIG_TESTING_OPTIONS */
}
} else if (wpa_s->sched_scanning &&
(type & MAC_ADDR_RAND_SCHED_SCAN)) {
- /* simulate timeout to restart the sched scan */
- wpa_s->sched_scan_timed_out = 1;
- wpa_s->prev_sched_ssid = NULL;
- wpa_supplicant_cancel_sched_scan(wpa_s);
+ wpas_scan_restart_sched_scan(wpa_s);
}
return 0;
}
wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_SCHED_SCAN,
addr, mask);
- if (wpa_s->sched_scanning && !wpa_s->pno) {
- /* simulate timeout to restart the sched scan */
- wpa_s->sched_scan_timed_out = 1;
- wpa_s->prev_sched_ssid = NULL;
- wpa_supplicant_cancel_sched_scan(wpa_s);
- }
+ if (wpa_s->sched_scanning && !wpa_s->pno)
+ wpas_scan_restart_sched_scan(wpa_s);
}
if (type & MAC_ADDR_RAND_PNO) {
}
+#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
+
+static int wpas_ctrl_iface_pmksa_get(struct wpa_supplicant *wpa_s,
+ const char *cmd, char *buf, size_t buflen)
+{
+ struct rsn_pmksa_cache_entry *entry;
+ struct wpa_ssid *ssid;
+ char *pos, *pos2, *end;
+ int ret;
+ struct os_reltime now;
+
+ ssid = wpa_config_get_network(wpa_s->conf, atoi(cmd));
+ if (!ssid)
+ return -1;
+
+ pos = buf;
+ end = buf + buflen;
+
+ os_get_reltime(&now);
+
+ /*
+ * Entry format:
+ * <BSSID> <PMKID> <PMK> <reauth_time in seconds>
+ * <expiration in seconds> <akmp> <opportunistic>
+ * [FILS Cache Identifier]
+ */
+
+ for (entry = wpa_sm_pmksa_cache_head(wpa_s->wpa); entry;
+ entry = entry->next) {
+ if (entry->network_ctx != ssid)
+ continue;
+
+ pos2 = pos;
+ ret = os_snprintf(pos2, end - pos2, MACSTR " ",
+ MAC2STR(entry->aa));
+ if (os_snprintf_error(end - pos2, ret))
+ break;
+ pos2 += ret;
+
+ pos2 += wpa_snprintf_hex(pos2, end - pos2, entry->pmkid,
+ PMKID_LEN);
+
+ ret = os_snprintf(pos2, end - pos2, " ");
+ if (os_snprintf_error(end - pos2, ret))
+ break;
+ pos2 += ret;
+
+ pos2 += wpa_snprintf_hex(pos2, end - pos2, entry->pmk,
+ entry->pmk_len);
+
+ ret = os_snprintf(pos2, end - pos2, " %d %d %d %d",
+ (int) (entry->reauth_time - now.sec),
+ (int) (entry->expiration - now.sec),
+ entry->akmp,
+ entry->opportunistic);
+ if (os_snprintf_error(end - pos2, ret))
+ break;
+ pos2 += ret;
+
+ if (entry->fils_cache_id_set) {
+ ret = os_snprintf(pos2, end - pos2, " %02x%02x",
+ entry->fils_cache_id[0],
+ entry->fils_cache_id[1]);
+ if (os_snprintf_error(end - pos2, ret))
+ break;
+ pos2 += ret;
+ }
+
+ ret = os_snprintf(pos2, end - pos2, "\n");
+ if (os_snprintf_error(end - pos2, ret))
+ break;
+ pos2 += ret;
+
+ pos = pos2;
+ }
+
+ return pos - buf;
+}
+
+
+static int wpas_ctrl_iface_pmksa_add(struct wpa_supplicant *wpa_s,
+ char *cmd)
+{
+ struct rsn_pmksa_cache_entry *entry;
+ struct wpa_ssid *ssid;
+ char *pos, *pos2;
+ int ret = -1;
+ struct os_reltime now;
+ int reauth_time = 0, expiration = 0, i;
+
+ /*
+ * Entry format:
+ * <network_id> <BSSID> <PMKID> <PMK> <reauth_time in seconds>
+ * <expiration in seconds> <akmp> <opportunistic>
+ * [FILS Cache Identifier]
+ */
+
+ ssid = wpa_config_get_network(wpa_s->conf, atoi(cmd));
+ if (!ssid)
+ return -1;
+
+ pos = os_strchr(cmd, ' ');
+ if (!pos)
+ return -1;
+ pos++;
+
+ entry = os_zalloc(sizeof(*entry));
+ if (!entry)
+ return -1;
+
+ if (hwaddr_aton(pos, entry->aa))
+ goto fail;
+
+ pos = os_strchr(pos, ' ');
+ if (!pos)
+ goto fail;
+ pos++;
+
+ if (hexstr2bin(pos, entry->pmkid, PMKID_LEN) < 0)
+ goto fail;
+
+ pos = os_strchr(pos, ' ');
+ if (!pos)
+ goto fail;
+ pos++;
+
+ pos2 = os_strchr(pos, ' ');
+ if (!pos2)
+ goto fail;
+ entry->pmk_len = (pos2 - pos) / 2;
+ if (entry->pmk_len < PMK_LEN || entry->pmk_len > PMK_LEN_MAX ||
+ hexstr2bin(pos, entry->pmk, entry->pmk_len) < 0)
+ goto fail;
+
+ pos = os_strchr(pos, ' ');
+ if (!pos)
+ goto fail;
+ pos++;
+
+ if (sscanf(pos, "%d %d %d %d", &reauth_time, &expiration,
+ &entry->akmp, &entry->opportunistic) != 4)
+ goto fail;
+ for (i = 0; i < 4; i++) {
+ pos = os_strchr(pos, ' ');
+ if (!pos) {
+ if (i < 3)
+ goto fail;
+ break;
+ }
+ pos++;
+ }
+ if (pos) {
+ if (hexstr2bin(pos, entry->fils_cache_id,
+ FILS_CACHE_ID_LEN) < 0)
+ goto fail;
+ entry->fils_cache_id_set = 1;
+ }
+ os_get_reltime(&now);
+ entry->expiration = now.sec + expiration;
+ entry->reauth_time = now.sec + reauth_time;
+
+ entry->network_ctx = ssid;
+
+ wpa_sm_pmksa_cache_add_entry(wpa_s->wpa, entry);
+ entry = NULL;
+ ret = 0;
+fail:
+ os_free(entry);
+ return ret;
+}
+
+
+#ifdef CONFIG_MESH
+
+static int wpas_ctrl_iface_mesh_pmksa_get(struct wpa_supplicant *wpa_s,
+ const char *cmd, char *buf,
+ size_t buflen)
+{
+ u8 spa[ETH_ALEN];
+
+ if (!wpa_s->ifmsh)
+ return -1;
+
+ if (os_strcasecmp(cmd, "any") == 0)
+ return wpas_ap_pmksa_cache_list_mesh(wpa_s, NULL, buf, buflen);
+
+ if (hwaddr_aton(cmd, spa))
+ return -1;
+
+ return wpas_ap_pmksa_cache_list_mesh(wpa_s, spa, buf, buflen);
+}
+
+
+static int wpas_ctrl_iface_mesh_pmksa_add(struct wpa_supplicant *wpa_s,
+ char *cmd)
+{
+ /*
+ * We do not check mesh interface existance because PMKSA should be
+ * stored before wpa_s->ifmsh creation to suppress commit message
+ * creation.
+ */
+ return wpas_ap_pmksa_cache_add_external(wpa_s, cmd);
+}
+
+#endif /* CONFIG_MESH */
+#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
+
+
+#ifdef CONFIG_FILS
+static int wpas_ctrl_iface_fils_hlp_req_add(struct wpa_supplicant *wpa_s,
+ const char *cmd)
+{
+ struct fils_hlp_req *req;
+ const char *pos;
+
+ /* format: <dst> <packet starting from ethertype> */
+
+ req = os_zalloc(sizeof(*req));
+ if (!req)
+ return -1;
+
+ if (hwaddr_aton(cmd, req->dst))
+ goto fail;
+
+ pos = os_strchr(cmd, ' ');
+ if (!pos)
+ goto fail;
+ pos++;
+ req->pkt = wpabuf_parse_bin(pos);
+ if (!req->pkt)
+ goto fail;
+
+ dl_list_add_tail(&wpa_s->fils_hlp_req, &req->list);
+ return 0;
+fail:
+ wpabuf_free(req->pkt);
+ os_free(req);
+ return -1;
+}
+#endif /* CONFIG_FILS */
+
+
static int wpas_ctrl_cmd_debug_level(const char *cmd)
{
if (os_strcmp(cmd, "PING") == 0 ||
int reply_len;
if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 ||
- os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
+ os_strncmp(buf, "SET_NETWORK ", 12) == 0 ||
+ os_strncmp(buf, "PMKSA_ADD ", 10) == 0 ||
+ os_strncmp(buf, "MESH_PMKSA_ADD ", 15) == 0) {
if (wpa_debug_show_keys)
wpa_dbg(wpa_s, MSG_DEBUG,
"Control interface command '%s'", buf);
"Control interface command '%s [REMOVED]'",
os_strncmp(buf, WPA_CTRL_RSP,
os_strlen(WPA_CTRL_RSP)) == 0 ?
- WPA_CTRL_RSP : "SET_NETWORK");
+ WPA_CTRL_RSP :
+ (os_strncmp(buf, "SET_NETWORK ", 12) == 0 ?
+ "SET_NETWORK" : "key-add"));
} else if (os_strncmp(buf, "WPS_NFC_TAG_READ", 16) == 0 ||
os_strncmp(buf, "NFC_REPORT_HANDOVER", 19) == 0) {
wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface",
reply_len += eapol_sm_get_mib(wpa_s->eapol,
reply + reply_len,
reply_size - reply_len);
+#ifdef CONFIG_MACSEC
+ reply_len += ieee802_1x_kay_get_mib(
+ wpa_s->kay, reply + reply_len,
+ reply_size - reply_len);
+#endif /* CONFIG_MACSEC */
}
} else if (os_strncmp(buf, "STATUS", 6) == 0) {
reply_len = wpa_supplicant_ctrl_iface_status(
reply_len = wpas_ctrl_iface_pmksa(wpa_s, reply, reply_size);
} else if (os_strcmp(buf, "PMKSA_FLUSH") == 0) {
wpas_ctrl_iface_pmksa_flush(wpa_s);
+#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
+ } else if (os_strncmp(buf, "PMKSA_GET ", 10) == 0) {
+ reply_len = wpas_ctrl_iface_pmksa_get(wpa_s, buf + 10,
+ reply, reply_size);
+ } else if (os_strncmp(buf, "PMKSA_ADD ", 10) == 0) {
+ if (wpas_ctrl_iface_pmksa_add(wpa_s, buf + 10) < 0)
+ reply_len = -1;
+#ifdef CONFIG_MESH
+ } else if (os_strncmp(buf, "MESH_PMKSA_GET ", 15) == 0) {
+ reply_len = wpas_ctrl_iface_mesh_pmksa_get(wpa_s, buf + 15,
+ reply, reply_size);
+ } else if (os_strncmp(buf, "MESH_PMKSA_ADD ", 15) == 0) {
+ if (wpas_ctrl_iface_mesh_pmksa_add(wpa_s, buf + 15) < 0)
+ reply_len = -1;
+#endif /* CONFIG_MESH */
+#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
} else if (os_strncmp(buf, "SET ", 4) == 0) {
if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4))
reply_len = -1;
if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8))
reply_len = -1;
#endif /* IEEE8021X_EAPOL */
-#ifdef CONFIG_PEERKEY
- } else if (os_strncmp(buf, "STKSTART ", 9) == 0) {
- if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9))
- reply_len = -1;
-#endif /* CONFIG_PEERKEY */
#ifdef CONFIG_IEEE80211R
} else if (os_strncmp(buf, "FT_DS ", 6) == 0) {
if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6))
reply_len = wpa_supplicant_ctrl_iface_list_networks(
wpa_s, NULL, reply, reply_size);
} else if (os_strcmp(buf, "DISCONNECT") == 0) {
-#ifdef CONFIG_SME
- wpa_s->sme.prev_bssid_set = 0;
-#endif /* CONFIG_SME */
- wpa_s->reassociate = 0;
- wpa_s->disconnected = 1;
- wpa_supplicant_cancel_sched_scan(wpa_s);
- wpa_supplicant_cancel_scan(wpa_s);
- wpa_supplicant_deauthenticate(wpa_s,
- WLAN_REASON_DEAUTH_LEAVING);
- eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
+ wpas_request_disconnection(wpa_s);
} else if (os_strcmp(buf, "SCAN") == 0) {
wpas_ctrl_scan(wpa_s, NULL, reply, reply_size, &reply_len);
} else if (os_strncmp(buf, "SCAN ", 5) == 0) {
if (wpa_supplicant_ctrl_iface_autoscan(wpa_s, buf + 9))
reply_len = -1;
#endif /* CONFIG_AUTOSCAN */
+ } else if (os_strcmp(buf, "DRIVER_FLAGS") == 0) {
+ reply_len = wpas_ctrl_iface_driver_flags(wpa_s, reply,
+ reply_size);
#ifdef ANDROID
} else if (os_strncmp(buf, "DRIVER ", 7) == 0) {
reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply,
} else if (os_strncmp(buf, "WNM_BSS_QUERY ", 14) == 0) {
if (wpas_ctrl_iface_wnm_bss_query(wpa_s, buf + 14))
reply_len = -1;
+ } else if (os_strncmp(buf, "COLOC_INTF_REPORT ", 18) == 0) {
+ if (wpas_ctrl_iface_coloc_intf_report(wpa_s, buf + 18))
+ reply_len = -1;
#endif /* CONFIG_WNM */
} else if (os_strcmp(buf, "FLUSH") == 0) {
wpa_supplicant_ctrl_iface_flush(wpa_s);
} else if (os_strncmp(buf, "TEST_ASSOC_IE ", 14) == 0) {
if (wpas_ctrl_test_assoc_ie(wpa_s, buf + 14) < 0)
reply_len = -1;
+ } else if (os_strcmp(buf, "RESET_PN") == 0) {
+ if (wpas_ctrl_reset_pn(wpa_s) < 0)
+ reply_len = -1;
+ } else if (os_strncmp(buf, "KEY_REQUEST ", 12) == 0) {
+ if (wpas_ctrl_key_request(wpa_s, buf + 12) < 0)
+ reply_len = -1;
+ } else if (os_strcmp(buf, "RESEND_ASSOC") == 0) {
+ if (wpas_ctrl_resend_assoc(wpa_s) < 0)
+ reply_len = -1;
+ } else if (os_strcmp(buf, "UNPROT_DEAUTH") == 0) {
+ sme_event_unprot_disconnect(
+ wpa_s, wpa_s->bssid, NULL,
+ WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
#endif /* CONFIG_TESTING_OPTIONS */
} else if (os_strncmp(buf, "VENDOR_ELEM_ADD ", 16) == 0) {
if (wpas_ctrl_vendor_elem_add(wpa_s, buf + 16) < 0)
} else if (os_strncmp(buf, "GET_PREF_FREQ_LIST ", 19) == 0) {
reply_len = wpas_ctrl_iface_get_pref_freq_list(
wpa_s, buf + 19, reply, reply_size);
+#ifdef CONFIG_FILS
+ } else if (os_strncmp(buf, "FILS_HLP_REQ_ADD ", 17) == 0) {
+ if (wpas_ctrl_iface_fils_hlp_req_add(wpa_s, buf + 17))
+ reply_len = -1;
+ } else if (os_strcmp(buf, "FILS_HLP_REQ_FLUSH") == 0) {
+ wpas_flush_fils_hlp_req(wpa_s);
+#endif /* CONFIG_FILS */
+#ifdef CONFIG_DPP
+ } else if (os_strncmp(buf, "DPP_QR_CODE ", 12) == 0) {
+ int res;
+
+ res = wpas_dpp_qr_code(wpa_s, buf + 12);
+ if (res < 0) {
+ reply_len = -1;
+ } else {
+ reply_len = os_snprintf(reply, reply_size, "%d", res);
+ if (os_snprintf_error(reply_size, reply_len))
+ reply_len = -1;
+ }
+ } else if (os_strncmp(buf, "DPP_BOOTSTRAP_GEN ", 18) == 0) {
+ int res;
+
+ res = wpas_dpp_bootstrap_gen(wpa_s, buf + 18);
+ if (res < 0) {
+ reply_len = -1;
+ } else {
+ reply_len = os_snprintf(reply, reply_size, "%d", res);
+ if (os_snprintf_error(reply_size, reply_len))
+ reply_len = -1;
+ }
+ } else if (os_strncmp(buf, "DPP_BOOTSTRAP_REMOVE ", 21) == 0) {
+ if (wpas_dpp_bootstrap_remove(wpa_s, buf + 21) < 0)
+ reply_len = -1;
+ } else if (os_strncmp(buf, "DPP_BOOTSTRAP_GET_URI ", 22) == 0) {
+ const char *uri;
+
+ uri = wpas_dpp_bootstrap_get_uri(wpa_s, atoi(buf + 22));
+ if (!uri) {
+ reply_len = -1;
+ } else {
+ reply_len = os_snprintf(reply, reply_size, "%s", uri);
+ if (os_snprintf_error(reply_size, reply_len))
+ reply_len = -1;
+ }
+ } else if (os_strncmp(buf, "DPP_BOOTSTRAP_INFO ", 19) == 0) {
+ reply_len = wpas_dpp_bootstrap_info(wpa_s, atoi(buf + 19),
+ reply, reply_size);
+ } else if (os_strncmp(buf, "DPP_AUTH_INIT ", 14) == 0) {
+ if (wpas_dpp_auth_init(wpa_s, buf + 13) < 0)
+ reply_len = -1;
+ } else if (os_strncmp(buf, "DPP_LISTEN ", 11) == 0) {
+ if (wpas_dpp_listen(wpa_s, buf + 11) < 0)
+ reply_len = -1;
+ } else if (os_strcmp(buf, "DPP_STOP_LISTEN") == 0) {
+ wpas_dpp_stop(wpa_s);
+ wpas_dpp_listen_stop(wpa_s);
+ } else if (os_strncmp(buf, "DPP_CONFIGURATOR_ADD", 20) == 0) {
+ int res;
+
+ res = wpas_dpp_configurator_add(wpa_s, buf + 20);
+ if (res < 0) {
+ reply_len = -1;
+ } else {
+ reply_len = os_snprintf(reply, reply_size, "%d", res);
+ if (os_snprintf_error(reply_size, reply_len))
+ reply_len = -1;
+ }
+ } else if (os_strncmp(buf, "DPP_CONFIGURATOR_REMOVE ", 24) == 0) {
+ if (wpas_dpp_configurator_remove(wpa_s, buf + 24) < 0)
+ reply_len = -1;
+ } else if (os_strncmp(buf, "DPP_CONFIGURATOR_SIGN ", 22) == 0) {
+ if (wpas_dpp_configurator_sign(wpa_s, buf + 21) < 0)
+ reply_len = -1;
+ } else if (os_strncmp(buf, "DPP_CONFIGURATOR_GET_KEY ", 25) == 0) {
+ reply_len = wpas_dpp_configurator_get_key(wpa_s, atoi(buf + 25),
+ reply, reply_size);
+ } else if (os_strncmp(buf, "DPP_PKEX_ADD ", 13) == 0) {
+ int res;
+
+ res = wpas_dpp_pkex_add(wpa_s, buf + 12);
+ if (res < 0) {
+ reply_len = -1;
+ } else {
+ reply_len = os_snprintf(reply, reply_size, "%d", res);
+ if (os_snprintf_error(reply_size, reply_len))
+ reply_len = -1;
+ }
+ } else if (os_strncmp(buf, "DPP_PKEX_REMOVE ", 16) == 0) {
+ if (wpas_dpp_pkex_remove(wpa_s, buf + 16) < 0)
+ reply_len = -1;
+#endif /* CONFIG_DPP */
} else {
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
reply_len = 16;
"P2P_CANCEL",
"P2P_PRESENCE_REQ",
"P2P_EXT_LISTEN",
+#ifdef CONFIG_AP
+ "STA-FIRST",
+#endif /* CONFIG_AP */
NULL
};
static const char * prefix[] = {
#ifdef ANDROID
"DRIVER ",
#endif /* ANDROID */
+ "GET_CAPABILITY ",
"GET_NETWORK ",
"REMOVE_NETWORK ",
"P2P_FIND ",
"NFC_REPORT_HANDOVER ",
"P2P_ASP_PROVISION ",
"P2P_ASP_PROVISION_RESP ",
+#ifdef CONFIG_AP
+ "STA ",
+ "STA-NEXT ",
+#endif /* CONFIG_AP */
NULL
};
int found = 0;