diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 2347df3f7..e05c81366 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -2332,6 +2332,22 @@ fail: #endif /* CONFIG_DPP2 */ +static int get_hex_config(u8 *buf, size_t max_len, int line, + const char *field, const char *val) +{ + size_t hlen = os_strlen(val), len = hlen / 2; + u8 tmp[EXT_CAPA_MAX_LEN]; + + os_memset(tmp, 0, EXT_CAPA_MAX_LEN); + if (hlen & 1 || len > EXT_CAPA_MAX_LEN || hexstr2bin(val, tmp, len)) { + wpa_printf(MSG_ERROR, "Line %d: Invalid %s", line, field); + return -1; + } + os_memcpy(buf, tmp, EXT_CAPA_MAX_LEN); + return 0; +} + + static int hostapd_config_fill(struct hostapd_config *conf, struct hostapd_bss_config *bss, const char *buf, char *pos, int line) @@ -4679,6 +4695,14 @@ static int hostapd_config_fill(struct hostapd_config *conf, } else if (os_strcmp(buf, "pasn_comeback_after") == 0) { bss->pasn_comeback_after = atoi(pos); #endif /* CONFIG_PASN */ + } else if (os_strcmp(buf, "ext_capa_mask") == 0) { + if (get_hex_config(bss->ext_capa_mask, EXT_CAPA_MAX_LEN, + line, "ext_capa_mask", pos)) + return 1; + } else if (os_strcmp(buf, "ext_capa") == 0) { + if (get_hex_config(bss->ext_capa, EXT_CAPA_MAX_LEN, + line, "ext_capa", pos)) + return 1; } else { wpa_printf(MSG_ERROR, "Line %d: unknown configuration item '%s'", diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index f86cf26ca..95bd79873 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -267,6 +267,8 @@ struct airtime_sta_weight { u8 addr[ETH_ALEN]; }; +#define EXT_CAPA_MAX_LEN 15 + /** * struct hostapd_bss_config - Per-BSS configuration */ @@ -889,6 +891,9 @@ struct hostapd_bss_config { #endif /* CONFIG_PASN */ unsigned int unsol_bcast_probe_resp_interval; + + u8 ext_capa_mask[EXT_CAPA_MAX_LEN]; + u8 ext_capa[EXT_CAPA_MAX_LEN]; }; /** diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c index 727de75d7..4bff9e591 100644 --- a/src/ap/ieee802_11_shared.c +++ b/src/ap/ieee802_11_shared.c @@ -451,7 +451,7 @@ static void hostapd_ext_capab_byte(struct hostapd_data *hapd, u8 *pos, int idx) u8 * hostapd_eid_ext_capab(struct hostapd_data *hapd, u8 *eid) { u8 *pos = eid; - u8 len = 12, i; + u8 len = EXT_CAPA_MAX_LEN, i; if (len < hapd->iface->extended_capa_len) len = hapd->iface->extended_capa_len; @@ -465,6 +465,11 @@ u8 * hostapd_eid_ext_capab(struct hostapd_data *hapd, u8 *eid) *pos &= ~hapd->iface->extended_capa_mask[i]; *pos |= hapd->iface->extended_capa[i]; } + + if (i < EXT_CAPA_MAX_LEN) { + *pos &= ~hapd->conf->ext_capa_mask[i]; + *pos |= hapd->conf->ext_capa[i]; + } } while (len > 0 && eid[1 + len] == 0) {