20 #include <boost/io/ios_state.hpp> 25 #if !defined(htole32) && !defined(le32toh) 26 # include <byteswap.h> 27 # include <arpa/inet.h> 28 # define htole32(x) (bswap_32(htonl(x))) 29 # define le32toh(x) (ntohl(bswap_32(x))) 36 #define MHZ_TO_KHZ(freq) ((freq) * 1000) 37 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) 48 senf::RadiotapPacketParser::OffsetMap senf::RadiotapPacketParser::offsetMap_;
50 prefix_ void senf::RadiotapPacketParser::parseOffsetTable(boost::uint8_t * data,
int maxLength,
55 &iter, reinterpret_cast<ieee80211_radiotap_header *>(data), maxLength, 0);
57 unsigned extIndex = 0;
75 prefix_ void senf::RadiotapPacketParser::buildOffsetTable(boost::uint32_t
presentFlags, OffsetTable & table)
80 "Extended or vendor fields not supported");
83 memset(&header, 0,
sizeof(header));
93 parseOffsetTable((boost::uint8_t*)&header, header.
it_len, table);
100 8, 1, 1, 4, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 0, 3, 8, 12 };
114 validate(RadiotapPacket_HeaderParser::fixed_bytes+4);
116 flags().fcsAtEnd_() =
false;
120 prefix_ senf::RadiotapPacketParser::OffsetTable
const &
121 senf::RadiotapPacketParser::getTable(boost::uint32_t presentFlags)
124 OffsetTable & table (offsetMap_[boost::hash_value(presentFlags)]);
126 buildOffsetTable(presentFlags, table);
130 prefix_ void senf::RadiotapPacketParser::insertRemoveBytes(
unsigned from,
unsigned to,
int bytes)
145 std::fill(b, e + bytes, 0u);
150 prefix_ void senf::RadiotapPacketParser::updatePresentFlags(boost::uint32_t
flags)
156 OffsetTable
const & oldTable (currentTable());
157 OffsetTable
const & newTable (getTable(flags));
158 unsigned b (RadiotapPacket_HeaderParser::fixed_bytes);
159 int cumulativeNewBytes (0);
161 for (
unsigned index (0); index <=
MAX_INDEX; ++index) {
164 && ((oldTable[index] == 0 && newTable[index] == 0)
165 || (oldTable[index]+cumulativeNewBytes == newTable[index])); ++index)
166 if (newTable[index] != 0)
171 for (; ! (oldTable[index]!=0 && newTable[index]!=0); ++index) ;
183 int newBytes (newTable[index] - oldTable[index] - cumulativeNewBytes);
184 insertRemoveBytes(b, oldTable[index] + cumulativeNewBytes, newBytes);
185 cumulativeNewBytes += newBytes;
186 b = newTable[index] + FIELD_SIZE[index];
188 length() += cumulativeNewBytes;
190 currentTable_ = &newTable;
199 mcs().guardInterval());
201 return rate() * 1000 / 2;
207 unsigned vhtBandwidths[] = {
219 return vhtBandwidths[vht().bandwidth()];
228 boost::io::ios_all_saver ias(os);
233 # define FIELD(name, sign, desc) \ 234 if (p->name ## Present()) \ 235 os << senf::fieldName(desc) << sign(p->name()) << '\n'; 237 # define ENTER(name) \ 238 if (p->name ## Present()) { \ 239 packet::Parser::name ## _t subparser (p->name()); 241 # define SUBFIELD(name, sign, desc) \ 242 os << senf::fieldName(desc) << sign(subparser.name()) << '\n'; 247 # define START_FLAGS(desc) \ 248 os << senf::fieldName(desc); 250 # define FLAG(name, desc) \ 251 if (subparser.name()) os << desc " " 253 # define END_FLAGS() \ 256 static const char * MCSbandwidthDesc[] = {
"20",
"40",
"20L",
"20U" };
257 static const char * MCSguardIntervalDesc[] = {
"long",
"short" };
258 static const char * MCShtFormatDesc[] = {
"mixed",
"greenfield" };
259 static const char * MCSfecTypeDesc[] = {
"BCC",
"LDPC" };
260 static const char * MCSmcsIndexDesc[] = { };
262 # define MCS_FLAG(name, desc, longDesc) \ 263 if (subparser.name ## Known()) { \ 264 os << senf::fieldName(" " desc) << unsigned(subparser.name()); \ 266 os << " (" << MCS ## name ## Desc[subparser.name()] << ")"; \ 270 static const char * VHTpartialAidDesc[] = { };
271 static const char * VHTgroupIdDesc[] = { };
272 static const char * VHTbandwidthDesc[] = { };
273 static const char * VHTbeamformedDesc[] = {
"yes",
"no" };
274 static const char * VHTldpcExtraOfdmSymbolDesc[] = {
"yes",
"no" };
275 static const char * VHTshortGiNsymDisambiguationDesc[] = {
"yes",
"no" };
276 static const char * VHTguardIntervalDesc[] = {
"long",
"short" };
277 static const char * VHTtxOpPsNotAllowedDesc[] = {
"yes",
"no" };
278 static const char * VHTstbcDesc[] = {
"yes",
"no" };
281 # define VHT_FLAG(name, desc, longDesc) \ 282 if (subparser.name ## Known()) { \ 283 os << senf::fieldName(" " desc) << unsigned(subparser.name()); \ 285 os << " (" << VHT ## name ## Desc[subparser.name()] << ")"; \ 290 FIELD ( tsft, boost::uint64_t,
"MAC timestamp" );
293 FLAG ( shortGI,
"ShortGI" );
294 FLAG ( badFCS,
"BadFCS" );
295 FLAG ( fcsAtEnd,
"FCSatEnd" );
296 FLAG ( fragmentation,
"Frag" );
298 FLAG ( shortPreamble,
"ShortPreamble" );
302 FIELD ( rate,
unsigned,
"rate" );
303 ENTER ( channelOptions );
306 FLAG ( flag2ghz,
"2GHz" );
307 FLAG ( ofdm,
"OFDM" );
309 FLAG ( turbo,
"Turbo" );
310 FLAG ( quarterRateChannel,
"Rate/4" );
311 FLAG ( halfRateChannel,
"Rate/2" );
313 FLAG ( staticTurbo,
"StaticTurbo" );
314 FLAG ( gfsk,
"GFSK" );
315 FLAG ( cckOfdm,
"CCK+OFDM" );
316 FLAG ( passive,
"Passive" );
317 FLAG ( flag5ghz,
"5GHz" );
320 FIELD ( fhss,
unsigned,
"FHSS" );
321 FIELD ( dbmAntennaSignal,
signed,
"antenna signal (dBm)" );
322 FIELD ( dbmAntennaNoise,
signed,
"antenna noise (dBm)" );
323 FIELD ( lockQuality,
unsigned,
"lock quality" );
324 FIELD ( txAttenuation,
unsigned,
"tx attenuation" );
325 FIELD ( dbTxAttenuation,
unsigned,
"tx attenuation (dB)" );
326 FIELD ( dbmTxAttenuation,
signed,
"tx attenuation (dBm)" );
327 FIELD ( antenna,
unsigned,
"antenna" );
328 FIELD ( dbAntennaSignal,
unsigned,
"antenna signal (dB)" );
329 FIELD ( dbAntennaNoise,
unsigned,
"antenna noise (dB)" );
332 FLAG ( badPlcp,
"BadPLCP" );
337 FLAG ( fail,
"Fail" );
338 FLAG ( txRts,
"RTS" );
339 FLAG ( txCts,
"CTS" );
342 FIELD ( rtsRetries,
unsigned,
"rts retries" );
343 FIELD ( dataRetries,
unsigned,
"data retries" );
346 FLAG ( bandwidthKnown,
"bandwidth" );
347 FLAG ( mcsIndexKnown,
"MCS index" );
348 FLAG ( guardIntervalKnown,
"guard interval" );
349 FLAG ( htFormatKnown,
"HT format" );
350 FLAG ( fecTypeKnown,
"FEC type" );
352 os <<
" MCS information\n" ;
354 MCS_FLAG ( guardInterval,
"guard interval", 1);
355 MCS_FLAG ( htFormat,
"HT format", 1);
357 MCS_FLAG ( mcsIndex,
"MCS index", 0);
361 FLAG ( partialAidKnown,
"Partial AID" );
362 FLAG ( groupIdKnown,
"Group ID" );
363 FLAG ( bandwidthKnown,
"Bandwidth" );
364 FLAG ( beamformedKnown,
"Beamformed" );
365 FLAG ( ldpcExtraOfdmSymbolKnown,
"LDPC Extra OFDM Symbol");
366 FLAG ( shortGiNsymDisambiguationKnown,
"Short GI NSYM Disambiguation");
367 FLAG ( guardIntervalKnown,
"Guard Interval" );
368 FLAG ( txOpPsNotAllowedKnown,
"TxOp PS Not Allowed");
369 FLAG ( stbcKnown,
"STBC" );
371 os <<
" VHT information\n" ;
372 VHT_FLAG ( partialAid,
"Partial AID" , 0);
375 VHT_FLAG ( beamformed,
"Beamformed", 1);
376 VHT_FLAG ( ldpcExtraOfdmSymbol,
"LDPC Extra OFDM Symbol", 1);
377 VHT_FLAG ( shortGiNsymDisambiguation,
"Short GI NSYM Disambiguation", 1);
378 VHT_FLAG ( guardInterval,
"Guard Interval", 1);
379 VHT_FLAG ( txOpPsNotAllowed,
"TxOp PS Not Allowed", 1);
383 if (p->flagsPresent() && p->flags().fcsAtEnd())
401 p->length() << RadiotapPacket_HeaderParser::fixed_bytes+0;
410 return frameTypeFactory[p->frameType()];
418 size_type t (rtParser.flagsPresent() && rtParser.flags().fcsAtEnd() ? 4 : 0);
419 return p.
size() < h+t
#define START_FLAGS(desc)
static optional_range nextPacketRange(packet const &p)
static unsigned getRate(std::uint8_t mcsIndex, unsigned bandwidth, bool shortGI)
PacketInterpreterBase::optional_range optional_range
static void dump(packet p, std::ostream &os)
int ieee80211_radiotap_iterator_next(struct ieee80211_radiotap_iterator *iterator)
std::string fieldName(std::string const &s)
#define SUBFIELD(name, sign, desc)
iterator begin() const
Return iterator to beginning.
PacketParserBase::size_type bytes(Parser const &p)
Return raw size parsed by the given parser object.
FIELD(tsft, UInt64LSBParser, TSFT_INDEX)
PacketData & data() const
Access the packets raw data container.
iterator end() const
Return iterator to end.
Protocol specific packet handle.
int ieee80211_radiotap_iterator_init(struct ieee80211_radiotap_iterator *iterator, struct ieee80211_radiotap_header *radiotap_header, int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns)
data_iterator i() const
Return beginning of data to parse.
senf::detail::packet::size_type size_type
flags_t flags(unsigned extIndex=0)
PacketInterpreterBase::range range
#define SENF_ASSERT(x, comment)
static void init(packet p)
size_type size() const
Return size of packet in bytes.
PacketData & data() const
Access the packets raw data container.
struct ieee80211_mcs_info mcs
Parse 32bit unsigned byte aligned integer.
void insert(iterator pos, byte v)
PacketInterpreterBase::factory_t factory_t
static factory_t factory()
Return factory for packets of specific type.
void validate(size_type size) const
Validate size of data container.
static factory_t nextPacketType(packet p)
802.11 WLANPacket public header
SENF_PACKET_INSTANTIATE_TEMPLATE(senf::RadiotapPacket)
ParserProtector protect() const
detail::packet::iterator data_iterator
Raw data iterator type.
Factory const * factory_t
Parser parser() const
Access packet field parser directly.