Fix location of MDE and RSNXE in Beacon and Probe Response frames
Split the IEs from WPA authenticator state machine into separately added IEs so that the exact location between these and other elements can be controlled. This fixes the location of MDE and RSNXE in Beacon and Probe Response frames. In addition, this swaps the order of BSS Load and RM Enabled Capabilities elements in Beacon frames to get them into the correct order (which was already used for Probe Response frames). Furthermore, this fixes the buffer end checks for couple of elements to make the implementation more consistent (though, in practice, there is no impact from this since the old size limit was smaller than needed, but still sufficiently large to have room for these). Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
f65da0ca4b
commit
640d59942b
1 changed files with 102 additions and 38 deletions
140
src/ap/beacon.c
140
src/ap/beacon.c
|
@ -266,17 +266,95 @@ static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static u8 * hostapd_eid_wpa(struct hostapd_data *hapd, u8 *eid, size_t len)
|
static const u8 * hostapd_wpa_ie(struct hostapd_data *hapd, u8 eid)
|
||||||
|
{
|
||||||
|
const u8 *ies;
|
||||||
|
size_t ies_len;
|
||||||
|
|
||||||
|
ies = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ies_len);
|
||||||
|
if (!ies)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return get_ie(ies, ies_len, eid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const u8 * hostapd_vendor_wpa_ie(struct hostapd_data *hapd,
|
||||||
|
u32 vendor_type)
|
||||||
|
{
|
||||||
|
const u8 *ies;
|
||||||
|
size_t ies_len;
|
||||||
|
|
||||||
|
ies = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ies_len);
|
||||||
|
if (!ies)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return get_vendor_ie(ies, ies_len, vendor_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * hostapd_get_rsne(struct hostapd_data *hapd, u8 *pos, size_t len)
|
||||||
{
|
{
|
||||||
const u8 *ie;
|
const u8 *ie;
|
||||||
size_t ielen;
|
|
||||||
|
|
||||||
ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ielen);
|
ie = hostapd_wpa_ie(hapd, WLAN_EID_RSN);
|
||||||
if (ie == NULL || ielen > len)
|
if (!ie || 2U + ie[1] > len)
|
||||||
return eid;
|
return pos;
|
||||||
|
|
||||||
os_memcpy(eid, ie, ielen);
|
os_memcpy(pos, ie, 2 + ie[1]);
|
||||||
return eid + ielen;
|
return pos + 2 + ie[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * hostapd_get_mde(struct hostapd_data *hapd, u8 *pos, size_t len)
|
||||||
|
{
|
||||||
|
const u8 *ie;
|
||||||
|
|
||||||
|
ie = hostapd_wpa_ie(hapd, WLAN_EID_MOBILITY_DOMAIN);
|
||||||
|
if (!ie || 2U + ie[1] > len)
|
||||||
|
return pos;
|
||||||
|
|
||||||
|
os_memcpy(pos, ie, 2 + ie[1]);
|
||||||
|
return pos + 2 + ie[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * hostapd_get_rsnxe(struct hostapd_data *hapd, u8 *pos, size_t len)
|
||||||
|
{
|
||||||
|
const u8 *ie;
|
||||||
|
|
||||||
|
ie = hostapd_wpa_ie(hapd, WLAN_EID_RSNX);
|
||||||
|
if (!ie || 2U + ie[1] > len)
|
||||||
|
return pos;
|
||||||
|
|
||||||
|
os_memcpy(pos, ie, 2 + ie[1]);
|
||||||
|
return pos + 2 + ie[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * hostapd_get_wpa_ie(struct hostapd_data *hapd, u8 *pos, size_t len)
|
||||||
|
{
|
||||||
|
const u8 *ie;
|
||||||
|
|
||||||
|
ie = hostapd_vendor_wpa_ie(hapd, WPA_IE_VENDOR_TYPE);
|
||||||
|
if (!ie || 2U + ie[1] > len)
|
||||||
|
return pos;
|
||||||
|
|
||||||
|
os_memcpy(pos, ie, 2 + ie[1]);
|
||||||
|
return pos + 2 + ie[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * hostapd_get_osen_ie(struct hostapd_data *hapd, u8 *pos, size_t len)
|
||||||
|
{
|
||||||
|
const u8 *ie;
|
||||||
|
|
||||||
|
ie = hostapd_vendor_wpa_ie(hapd, OSEN_IE_VENDOR_TYPE);
|
||||||
|
if (!ie || 2U + ie[1] > len)
|
||||||
|
return pos;
|
||||||
|
|
||||||
|
os_memcpy(pos, ie, 2 + ie[1]);
|
||||||
|
return pos + 2 + ie[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -434,14 +512,10 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
|
||||||
/* Extended supported rates */
|
/* Extended supported rates */
|
||||||
pos = hostapd_eid_ext_supp_rates(hapd, pos);
|
pos = hostapd_eid_ext_supp_rates(hapd, pos);
|
||||||
|
|
||||||
/* RSN, MDIE */
|
pos = hostapd_get_rsne(hapd, pos, epos - pos);
|
||||||
if (!(hapd->conf->wpa == WPA_PROTO_WPA ||
|
|
||||||
(hapd->conf->osen && !hapd->conf->wpa)))
|
|
||||||
pos = hostapd_eid_wpa(hapd, pos, epos - pos);
|
|
||||||
|
|
||||||
pos = hostapd_eid_bss_load(hapd, pos, epos - pos);
|
pos = hostapd_eid_bss_load(hapd, pos, epos - pos);
|
||||||
|
|
||||||
pos = hostapd_eid_rm_enabled_capab(hapd, pos, epos - pos);
|
pos = hostapd_eid_rm_enabled_capab(hapd, pos, epos - pos);
|
||||||
|
pos = hostapd_get_mde(hapd, pos, epos - pos);
|
||||||
|
|
||||||
/* eCSA IE */
|
/* eCSA IE */
|
||||||
csa_pos = hostapd_eid_ecsa(hapd, pos);
|
csa_pos = hostapd_eid_ecsa(hapd, pos);
|
||||||
|
@ -488,6 +562,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
|
||||||
#endif /* CONFIG_IEEE80211AC */
|
#endif /* CONFIG_IEEE80211AC */
|
||||||
|
|
||||||
pos = hostapd_eid_fils_indic(hapd, pos, 0);
|
pos = hostapd_eid_fils_indic(hapd, pos, 0);
|
||||||
|
pos = hostapd_get_rsnxe(hapd, pos, epos - pos);
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211AX
|
#ifdef CONFIG_IEEE80211AX
|
||||||
if (hapd->iconf->ieee80211ax) {
|
if (hapd->iconf->ieee80211ax) {
|
||||||
|
@ -503,10 +578,9 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
|
||||||
pos = hostapd_eid_vendor_vht(hapd, pos);
|
pos = hostapd_eid_vendor_vht(hapd, pos);
|
||||||
#endif /* CONFIG_IEEE80211AC */
|
#endif /* CONFIG_IEEE80211AC */
|
||||||
|
|
||||||
/* WPA */
|
/* WPA / OSEN */
|
||||||
if (hapd->conf->wpa == WPA_PROTO_WPA ||
|
pos = hostapd_get_wpa_ie(hapd, pos, epos - pos);
|
||||||
(hapd->conf->osen && !hapd->conf->wpa))
|
pos = hostapd_get_osen_ie(hapd, pos, epos - pos);
|
||||||
pos = hostapd_eid_wpa(hapd, pos, epos - pos);
|
|
||||||
|
|
||||||
/* Wi-Fi Alliance WMM */
|
/* Wi-Fi Alliance WMM */
|
||||||
pos = hostapd_eid_wmm(hapd, pos);
|
pos = hostapd_eid_wmm(hapd, pos);
|
||||||
|
@ -1052,7 +1126,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
|
||||||
size_t resp_len = 0;
|
size_t resp_len = 0;
|
||||||
#ifdef NEED_AP_MLME
|
#ifdef NEED_AP_MLME
|
||||||
u16 capab_info;
|
u16 capab_info;
|
||||||
u8 *pos, *tailpos, *csa_pos;
|
u8 *pos, *tailpos, *tailend, *csa_pos;
|
||||||
|
|
||||||
#define BEACON_HEAD_BUF_SIZE 256
|
#define BEACON_HEAD_BUF_SIZE 256
|
||||||
#define BEACON_TAIL_BUF_SIZE 512
|
#define BEACON_TAIL_BUF_SIZE 512
|
||||||
|
@ -1099,6 +1173,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
|
||||||
os_free(tail);
|
os_free(tail);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
tailend = tail + tail_len;
|
||||||
|
|
||||||
head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
|
head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
|
||||||
WLAN_FC_STYPE_BEACON);
|
WLAN_FC_STYPE_BEACON);
|
||||||
|
@ -1139,8 +1214,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
|
||||||
|
|
||||||
head_len = pos - (u8 *) head;
|
head_len = pos - (u8 *) head;
|
||||||
|
|
||||||
tailpos = hostapd_eid_country(hapd, tailpos,
|
tailpos = hostapd_eid_country(hapd, tailpos, tailend - tailpos);
|
||||||
tail + BEACON_TAIL_BUF_SIZE - tailpos);
|
|
||||||
|
|
||||||
/* Power Constraint element */
|
/* Power Constraint element */
|
||||||
tailpos = hostapd_eid_pwr_constraint(hapd, tailpos);
|
tailpos = hostapd_eid_pwr_constraint(hapd, tailpos);
|
||||||
|
@ -1157,19 +1231,11 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
|
||||||
/* Extended supported rates */
|
/* Extended supported rates */
|
||||||
tailpos = hostapd_eid_ext_supp_rates(hapd, tailpos);
|
tailpos = hostapd_eid_ext_supp_rates(hapd, tailpos);
|
||||||
|
|
||||||
/* RSN, MDIE */
|
tailpos = hostapd_get_rsne(hapd, tailpos, tailend - tailpos);
|
||||||
if (!(hapd->conf->wpa == WPA_PROTO_WPA ||
|
tailpos = hostapd_eid_bss_load(hapd, tailpos, tailend - tailpos);
|
||||||
(hapd->conf->osen && !hapd->conf->wpa)))
|
|
||||||
tailpos = hostapd_eid_wpa(hapd, tailpos,
|
|
||||||
tail + BEACON_TAIL_BUF_SIZE -
|
|
||||||
tailpos);
|
|
||||||
|
|
||||||
tailpos = hostapd_eid_rm_enabled_capab(hapd, tailpos,
|
tailpos = hostapd_eid_rm_enabled_capab(hapd, tailpos,
|
||||||
tail + BEACON_TAIL_BUF_SIZE -
|
tailend - tailpos);
|
||||||
tailpos);
|
tailpos = hostapd_get_mde(hapd, tailpos, tailend - tailpos);
|
||||||
|
|
||||||
tailpos = hostapd_eid_bss_load(hapd, tailpos,
|
|
||||||
tail + BEACON_TAIL_BUF_SIZE - tailpos);
|
|
||||||
|
|
||||||
/* eCSA IE */
|
/* eCSA IE */
|
||||||
csa_pos = hostapd_eid_ecsa(hapd, tailpos);
|
csa_pos = hostapd_eid_ecsa(hapd, tailpos);
|
||||||
|
@ -1218,6 +1284,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
|
||||||
#endif /* CONFIG_IEEE80211AC */
|
#endif /* CONFIG_IEEE80211AC */
|
||||||
|
|
||||||
tailpos = hostapd_eid_fils_indic(hapd, tailpos, 0);
|
tailpos = hostapd_eid_fils_indic(hapd, tailpos, 0);
|
||||||
|
tailpos = hostapd_get_rsnxe(hapd, tailpos, tailend - tailpos);
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211AX
|
#ifdef CONFIG_IEEE80211AX
|
||||||
if (hapd->iconf->ieee80211ax) {
|
if (hapd->iconf->ieee80211ax) {
|
||||||
|
@ -1234,12 +1301,9 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
|
||||||
tailpos = hostapd_eid_vendor_vht(hapd, tailpos);
|
tailpos = hostapd_eid_vendor_vht(hapd, tailpos);
|
||||||
#endif /* CONFIG_IEEE80211AC */
|
#endif /* CONFIG_IEEE80211AC */
|
||||||
|
|
||||||
/* WPA */
|
/* WPA / OSEN */
|
||||||
if (hapd->conf->wpa == WPA_PROTO_WPA ||
|
tailpos = hostapd_get_wpa_ie(hapd, tailpos, tailend - tailpos);
|
||||||
(hapd->conf->osen && !hapd->conf->wpa))
|
tailpos = hostapd_get_osen_ie(hapd, tailpos, tailend - tailpos);
|
||||||
tailpos = hostapd_eid_wpa(hapd, tailpos,
|
|
||||||
tail + BEACON_TAIL_BUF_SIZE -
|
|
||||||
tailpos);
|
|
||||||
|
|
||||||
/* Wi-Fi Alliance WMM */
|
/* Wi-Fi Alliance WMM */
|
||||||
tailpos = hostapd_eid_wmm(hapd, tailpos);
|
tailpos = hostapd_eid_wmm(hapd, tailpos);
|
||||||
|
|
Loading…
Reference in a new issue