From 222eaa14fb2bd1dde2c93cb0ac79aa29defc8c76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deronne?= Date: Tue, 3 Jun 2025 20:09:31 +0200 Subject: [PATCH] network, wifi: The size of the ieee80211_radiotap_header should be set first for correct alignment calculations --- src/network/utils/radiotap-header.cc | 30 +++++++++++++++++----------- src/network/utils/radiotap-header.h | 12 ++++++++++- src/wifi/helper/wifi-helper.cc | 4 +++- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/network/utils/radiotap-header.cc b/src/network/utils/radiotap-header.cc index 52e98c225..0cd2597f2 100644 --- a/src/network/utils/radiotap-header.cc +++ b/src/network/utils/radiotap-header.cc @@ -568,6 +568,20 @@ RadiotapHeader::Print(std::ostream& os) const } } +void +RadiotapHeader::SetWifiHeader(bool extended) +{ + NS_LOG_FUNCTION(this << extended); + NS_ASSERT_MSG(m_length == MIN_HEADER_SIZE, + "RadiotapHeader::SetWifiHeader() should be called before any other Set* method"); + if (extended) + { + m_present |= RADIOTAP_EXT; + m_presentExt = 0; + m_length += sizeof(RadiotapExtFlags); + } +} + void RadiotapHeader::SetTsft(uint64_t value) { @@ -1028,12 +1042,8 @@ void RadiotapHeader::SetUsigFields(const UsigFields& usigFields) { NS_LOG_FUNCTION(this << usigFields.common << usigFields.mask << usigFields.value); - if (!m_presentExt) - { - m_present |= RADIOTAP_TLV | RADIOTAP_EXT; - m_presentExt = 0; - m_length += sizeof(RadiotapExtFlags); - } + NS_ASSERT_MSG(m_presentExt, "Number of it_present words is incorrect"); + m_present |= RADIOTAP_TLV; NS_ASSERT_MSG(!(*m_presentExt & RADIOTAP_USIG), "U-SIG radiotap field already present"); *m_presentExt |= RADIOTAP_USIG; @@ -1094,12 +1104,8 @@ void RadiotapHeader::SetEhtFields(const EhtFields& ehtFields) { NS_LOG_FUNCTION(this << ehtFields.known); - if (!m_presentExt) - { - m_present |= RADIOTAP_TLV | RADIOTAP_EXT; - m_presentExt = 0; - m_length += sizeof(RadiotapExtFlags); - } + NS_ASSERT_MSG(m_presentExt, "Number of it_present words is incorrect"); + m_present |= RADIOTAP_TLV; NS_ASSERT_MSG(!(*m_presentExt & RADIOTAP_EHT_SIG), "EHT radiotap field already present"); *m_presentExt |= RADIOTAP_EHT_SIG; diff --git a/src/network/utils/radiotap-header.h b/src/network/utils/radiotap-header.h index 501b81130..e8a36ea08 100644 --- a/src/network/utils/radiotap-header.h +++ b/src/network/utils/radiotap-header.h @@ -82,6 +82,14 @@ class RadiotapHeader : public Header */ void Print(std::ostream& os) const override; + /** + * @brief Set the ieee80211_radiotap_header. This method must be called + * before any other Set* method. + * + * @param extended If true, one more it_present word follows the it_present bitmask. + */ + void SetWifiHeader(bool extended); + /** * @brief Set the Time Synchronization Function Timer (TSFT) value. Valid for * received frames only. @@ -773,6 +781,8 @@ class RadiotapHeader : public Header void SetEhtFields(const EhtFields& ehtFields); private: + static constexpr int MIN_HEADER_SIZE{8}; //!< the minimum size of the radiotap header + /** * Serialize the TSFT radiotap header. * @@ -1048,7 +1058,7 @@ class RadiotapHeader : public Header RADIOTAP_EHT_SIG = 0x00000004 }; - uint16_t m_length{8}; //!< entire length of radiotap data + header + uint16_t m_length{MIN_HEADER_SIZE}; //!< entire length of radiotap data + header uint32_t m_present{0}; //!< bits describing which fields follow header std::optional m_presentExt{}; //!< optional extended present bitmask diff --git a/src/wifi/helper/wifi-helper.cc b/src/wifi/helper/wifi-helper.cc index ab1942a42..c5b6148d4 100644 --- a/src/wifi/helper/wifi-helper.cc +++ b/src/wifi/helper/wifi-helper.cc @@ -346,9 +346,9 @@ WifiPhyHelper::GetRadiotapHeader(RadiotapHeader& header, uint16_t staId, SignalNoiseDbm signalNoise) { + GetRadiotapHeader(header, packet, channelFreqMhz, p20Index, txVector, aMpdu, staId); header.SetAntennaSignalPower(signalNoise.signal); header.SetAntennaNoisePower(signalNoise.noise); - GetRadiotapHeader(header, packet, channelFreqMhz, p20Index, txVector, aMpdu, staId); } void @@ -365,6 +365,8 @@ WifiPhyHelper::GetRadiotapHeader(RadiotapHeader& header, const auto channelWidth = txVector.GetChannelWidth(); const auto gi = txVector.GetGuardInterval(); + header.SetWifiHeader(IsEht(preamble)); + header.SetTsft(Simulator::Now().GetMicroSeconds()); uint8_t frameFlags = RadiotapHeader::FRAME_FLAG_NONE;