diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index 720ff7b70..8a996f900 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -305,6 +305,11 @@ no_wps: bss->disassoc_low_ack = wpa_s->conf->disassoc_low_ack; + if (wpa_s->conf->ap_vendor_elements) { + bss->vendor_elements = + wpabuf_dup(wpa_s->conf->ap_vendor_elements); + } + return 0; } diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 1ffe05eb9..1b71ca71a 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -1833,6 +1833,7 @@ void wpa_config_free(struct wpa_config *config) wpabuf_free(config->wps_nfc_dev_pw); os_free(config->ext_password_backend); os_free(config->sae_groups); + wpabuf_free(config->ap_vendor_elements); os_free(config); } @@ -2953,6 +2954,43 @@ static int wpa_config_process_sae_groups( } +static int wpa_config_process_ap_vendor_elements( + const struct global_parse_data *data, + struct wpa_config *config, int line, const char *pos) +{ + struct wpabuf *tmp; + int len = os_strlen(pos) / 2; + u8 *p; + + if (!len) { + wpa_printf(MSG_ERROR, "Line %d: invalid ap_vendor_elements", + line); + return -1; + } + + tmp = wpabuf_alloc(len); + if (tmp) { + p = wpabuf_put(tmp, len); + + if (hexstr2bin(pos, p, len)) { + wpa_printf(MSG_ERROR, "Line %d: invalid " + "ap_vendor_elements", line); + wpabuf_free(tmp); + return -1; + } + + wpabuf_free(config->ap_vendor_elements); + config->ap_vendor_elements = tmp; + } else { + wpa_printf(MSG_ERROR, "Cannot allocate memory for " + "ap_vendor_elements"); + return -1; + } + + return 0; +} + + #ifdef OFFSET #undef OFFSET #endif /* OFFSET */ @@ -3050,6 +3088,7 @@ static const struct global_parse_data global_fields[] = { { FUNC(sae_groups), 0 }, { INT(dtim_period), 0 }, { INT(beacon_int), 0 }, + { FUNC(ap_vendor_elements), 0 }, }; #undef FUNC diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 03fe6fc70..00990cb40 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -834,6 +834,16 @@ struct wpa_config { * blocks that do not specify beacon_int. */ int beacon_int; + + /** + * ap_vendor_elements: Vendor specific elements for Beacon/ProbeResp + * + * This parameter can be used to define additional vendor specific + * elements for Beacon and Probe Response frames in AP/P2P GO mode. The + * format for these element(s) is a hexdump of the raw information + * elements (id+len+payload for one or more elements). + */ + struct wpabuf *ap_vendor_elements; }; diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index ff99cd7b7..6bb51bad2 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -990,6 +990,17 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) } fprintf(f, "\n"); } + + if (config->ap_vendor_elements) { + int i, len = wpabuf_len(config->ap_vendor_elements); + const u8 *p = wpabuf_head_u8(config->ap_vendor_elements); + if (len > 0) { + fprintf(f, "ap_vendor_elements="); + for (i = 0; i < len; i++) + fprintf(f, "%02x", *p++); + fprintf(f, "\n"); + } + } } #endif /* CONFIG_NO_CONFIG_WRITE */ diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index 1ded4e12a..b40706076 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -295,6 +295,13 @@ fast_reauth=1 # Default value for Beacon interval (if not overridden in network block) #beacon_int=100 +# Additional vendor specific elements for Beacon and Probe Response frames +# This parameter can be used to add additional vendor specific element(s) into +# the end of the Beacon and Probe Response 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 AP and P2P GO modes. +#ap_vendor_elements=dd0411223301 + # Interworking (IEEE 802.11u) # Enable Interworking