@@ -2282,6 +2282,8 @@ void wpa_config_free(struct wpa_config *config)
os_free(config->ext_password_backend);
os_free(config->sae_groups);
wpabuf_free(config->ap_vendor_elements);
+ wpabuf_free(config->probe_req_ie);
+ wpabuf_free(config->assoc_req_ie);
os_free(config->osu_dir);
os_free(config->bgscan);
os_free(config->wowlan_triggers);
@@ -4094,17 +4096,18 @@ static int wpa_config_process_sae_groups(
}
-static int wpa_config_process_ap_vendor_elements(
+static int wpa_config_process_ie_helper(
const struct global_parse_data *data,
- struct wpa_config *config, int line, const char *pos)
+ int line, const char *pos,
+ const char* id, struct wpabuf **buf)
{
struct wpabuf *tmp;
int len = os_strlen(pos) / 2;
u8 *p;
if (!len) {
- wpa_printf(MSG_ERROR, "Line %d: invalid ap_vendor_elements",
- line);
+ wpa_printf(MSG_ERROR, "Line %d: invalid %s",
+ line, id);
return -1;
}
@@ -4113,23 +4116,47 @@ static int wpa_config_process_ap_vendor_elements(
p = wpabuf_put(tmp, len);
if (hexstr2bin(pos, p, len)) {
- wpa_printf(MSG_ERROR, "Line %d: invalid "
- "ap_vendor_elements", line);
+ wpa_printf(MSG_ERROR, "Line %d: invalid %s",
+ line, id);
wpabuf_free(tmp);
return -1;
}
- wpabuf_free(config->ap_vendor_elements);
- config->ap_vendor_elements = tmp;
+ wpabuf_free(*buf);
+ *buf = tmp;
} else {
- wpa_printf(MSG_ERROR, "Cannot allocate memory for "
- "ap_vendor_elements");
+ wpa_printf(MSG_ERROR, "Cannot allocate memory for %s",
+ id);
return -1;
}
return 0;
}
+static int wpa_config_process_ap_vendor_elements(
+ const struct global_parse_data *data,
+ struct wpa_config *config, int line, const char *pos)
+{
+ return wpa_config_process_ie_helper(data, line, pos, "ap_vendor_elements",
+ &config->ap_vendor_elements);
+}
+
+static int wpa_config_process_probe_req_ie(
+ const struct global_parse_data *data,
+ struct wpa_config *config, int line, const char *pos)
+{
+ return wpa_config_process_ie_helper(data, line, pos, "probe_req_ie",
+ &config->probe_req_ie);
+}
+
+static int wpa_config_process_assoc_req_ie(
+ const struct global_parse_data *data,
+ struct wpa_config *config, int line, const char *pos)
+{
+ return wpa_config_process_ie_helper(data, line, pos, "assoc_req_ie",
+ &config->assoc_req_ie);
+}
+
#ifdef CONFIG_CTRL_IFACE
static int wpa_config_process_no_ctrl_interface(
@@ -4332,6 +4359,8 @@ static const struct global_parse_data global_fields[] = {
{ INT(dtim_period), 0 },
{ INT(beacon_int), 0 },
{ FUNC(ap_vendor_elements), 0 },
+ { FUNC(probe_req_ie), 0 },
+ { FUNC(assoc_req_ie), 0 },
{ INT_RANGE(ignore_old_scan_res, 0, 1), 0 },
{ FUNC(freq_list), 0 },
{ INT(scan_cur_freq), 0 },
@@ -1115,6 +1115,26 @@ struct wpa_config {
struct wpabuf *ap_vendor_elements;
/**
+ * probe_req_ie: Vendor specific elements for Probe-Req
+ *
+ * This parameter can be used to define additional vendor specific
+ * elements for Probe Requests.
+ * format for these element(s) is a hexdump of the raw information
+ * elements (id+len+payload for one or more elements).
+ */
+ struct wpabuf *probe_req_ie;
+
+ /**
+ * assoc_req_ie: Vendor specific elements for Assoc-Req
+ *
+ * This parameter can be used to define additional vendor specific
+ * elements for Association Requests.
+ * format for these element(s) is a hexdump of the raw information
+ * elements (id+len+payload for one or more elements).
+ */
+ struct wpabuf *assoc_req_ie;
+
+ /**
* ignore_old_scan_res - Ignore scan results older than request
*
* The driver may have a cache of scan results that makes it return
@@ -1242,6 +1242,28 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
}
}
+ if (config->probe_req_ie) {
+ int i, len = wpabuf_len(config->probe_req_ie);
+ const u8 *p = wpabuf_head_u8(config->probe_req_ie);
+ if (len > 0) {
+ fprintf(f, "probe_req_ie=");
+ for (i = 0; i < len; i++)
+ fprintf(f, "%02x", *p++);
+ fprintf(f, "\n");
+ }
+ }
+
+ if (config->assoc_req_ie) {
+ int i, len = wpabuf_len(config->assoc_req_ie);
+ const u8 *p = wpabuf_head_u8(config->assoc_req_ie);
+ if (len > 0) {
+ fprintf(f, "assoc_req_ie=");
+ for (i = 0; i < len; i++)
+ fprintf(f, "%02x", *p++);
+ fprintf(f, "\n");
+ }
+ }
+
if (config->ignore_old_scan_res)
fprintf(f, "ignore_old_scan_res=%d\n",
config->ignore_old_scan_res);
@@ -512,6 +512,14 @@ static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
wpas_mbo_scan_ie(wpa_s, extra_ie);
#endif /* CONFIG_MBO */
+ /* Add user-specified IE */
+ if (wpa_s->conf->probe_req_ie) {
+ int ln = wpabuf_len(wpa_s->conf->probe_req_ie);
+ if (wpabuf_resize(&extra_ie, ln) == 0) {
+ wpabuf_put_buf(extra_ie, wpa_s->conf->probe_req_ie);
+ }
+ }
+
return extra_ie;
}
@@ -464,6 +464,20 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
os_memcpy(pos, ext_capab, ext_capab_len);
}
+ /* Add user-specified IE */
+ if (wpa_s->conf->assoc_req_ie) {
+ int v_ies_len = wpabuf_len(wpa_s->conf->assoc_req_ie);
+
+ if (wpa_s->sme.assoc_req_ie_len + v_ies_len <= sizeof(wpa_s->sme.assoc_req_ie)) {
+ os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
+ wpabuf_head(wpa_s->conf->assoc_req_ie), v_ies_len);
+ wpa_s->sme.assoc_req_ie_len += v_ies_len;
+ wpa_msg(wpa_s, MSG_INFO, "SME: added user-specified vendor elements, len: %d",
+ v_ies_len);
+ }
+ }
+
+
#ifdef CONFIG_HS20
if (is_hs20_network(wpa_s, ssid, bss)) {
struct wpabuf *hs20;
@@ -678,7 +678,8 @@ static char ** wpa_cli_complete_set(const char *str, int pos)
"wps_nfc_dh_privkey", "wps_nfc_dev_pw", "ext_password_backend",
"p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
"sae_groups", "dtim_period", "beacon_int",
- "ap_vendor_elements", "ignore_old_scan_res", "freq_list",
+ "ap_vendor_elements", "probe_req_ie", "assoc_req_ie",
+ "ignore_old_scan_res", "freq_list",
"scan_cur_freq", "sched_scan_interval",
"tdls_external_control", "osu_dir", "wowlan_triggers",
"p2p_search_delay", "mac_addr", "rand_addr_lifetime",
@@ -2434,6 +2434,19 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
}
#endif /* CONFIG_MBO */
+ /* Add user-specified IE */
+ if (wpa_s->conf->assoc_req_ie) {
+ int v_ies_len = wpabuf_len(wpa_s->conf->assoc_req_ie);
+
+ if (wpa_ie_len + v_ies_len <= sizeof(wpa_ie)) {
+ os_memcpy(wpa_ie + wpa_ie_len,
+ wpabuf_head(wpa_s->conf->assoc_req_ie), v_ies_len);
+ wpa_ie_len += v_ies_len;
+ wpa_msg(wpa_s, MSG_INFO, "start-assoc-cb, added user-specified vendor elements, len: %d",
+ v_ies_len);
+ }
+ }
+
wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
use_crypt = 1;
cipher_pairwise = wpa_s->pairwise_cipher;
@@ -392,6 +392,20 @@ fast_reauth=1
# one or more elements). This is used in AP and P2P GO modes.
#ap_vendor_elements=dd0411223301
+# Additional vendor specific elements for Probe Request frames
+# This parameter can be used to add additional vendor specific element(s) into
+# the end of the Probe Request frames. The format for these
+# element(s) is a hexdump of the raw information elements (id+len+payload for
+# one or more elements). This is used in Station mode.
+#probe_req_ie=dd0411223301
+
+# Additional vendor specific elements for Assoc Request frames
+# This parameter can be used to add additional vendor specific element(s) into
+# the end of the Assoc Request frames. The format for these
+# element(s) is a hexdump of the raw information elements (id+len+payload for
+# one or more elements). This is used in Station mode.
+#assoc_req_ie=dd0411223301
+
# Ignore scan results older than request
#
# The driver may have a cache of scan results that makes it return