From e6f9eab90ebc80170b2fb2af61217d5eb0421564 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 25 Apr 2019 23:57:47 +0300 Subject: [PATCH] HE: Fix HE Operation element byte order on bigendian CPUs The first four octets of the element were used as a host byte order u32. That is not correct on bigendian CPUs, so handle byte swapping needs properly. Mark the he_oper_params field as le32 to explicitly indicate the byte order and swap the generated params content based on CPU byte order. Signed-off-by: Jouni Malinen --- src/ap/ieee802_11_he.c | 20 ++++++++++---------- src/common/ieee802_11_defs.h | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c index 8798ada32..0dbfc7019 100644 --- a/src/ap/ieee802_11_he.c +++ b/src/ap/ieee802_11_he.c @@ -62,6 +62,7 @@ u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid) struct ieee80211_he_operation *oper; u8 *pos = eid; int oper_size = 6; + u32 params = 0; if (!hapd->iface->current_mode) return eid; @@ -74,25 +75,24 @@ u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid) os_memset(oper, 0, sizeof(*oper)); if (hapd->iface->conf->he_op.he_default_pe_duration) - oper->he_oper_params |= - (hapd->iface->conf->he_op.he_default_pe_duration << - HE_OPERATION_DFLT_PE_DURATION_OFFSET); + params |= (hapd->iface->conf->he_op.he_default_pe_duration << + HE_OPERATION_DFLT_PE_DURATION_OFFSET); if (hapd->iface->conf->he_op.he_twt_required) - oper->he_oper_params |= HE_OPERATION_TWT_REQUIRED; + params |= HE_OPERATION_TWT_REQUIRED; if (hapd->iface->conf->he_op.he_rts_threshold) - oper->he_oper_params |= - (hapd->iface->conf->he_op.he_rts_threshold << - HE_OPERATION_RTS_THRESHOLD_OFFSET); + params |= (hapd->iface->conf->he_op.he_rts_threshold << + HE_OPERATION_RTS_THRESHOLD_OFFSET); if (hapd->iface->conf->he_op.he_bss_color) - oper->he_oper_params |= - (hapd->iface->conf->he_op.he_bss_color << - HE_OPERATION_BSS_COLOR_OFFSET); + params |= (hapd->iface->conf->he_op.he_bss_color << + HE_OPERATION_BSS_COLOR_OFFSET); /* TODO: conditional MaxBSSID Indicator subfield */ + oper->he_oper_params = host_to_le32(params); + pos += oper_size; return pos; diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 90615ece6..7eadc7710 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -2110,8 +2110,8 @@ struct ieee80211_he_capabilities { } STRUCT_PACKED; struct ieee80211_he_operation { - u32 he_oper_params; /* HE Operation Parameters[3] and - * BSS Color Information[1] */ + le32 he_oper_params; /* HE Operation Parameters[3] and + * BSS Color Information[1] */ u8 he_mcs_nss_set[2]; u8 vht_op_info_chwidth; u8 vht_op_info_chan_center_freq_seg0_idx;