X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=senf%2FPackets%2F80211Bundle%2FRadiotapPacket.hh;h=c375a56509adf0294a1894d7eaa8007bc79d4a7c;hb=e3179a2123ad51d0d9eb63834a581145c4f77c92;hp=c6fe53cf9c4fc2cc8cc3f08d27cf1869af0c2c28;hpb=601d1f509f5bb24df167a4dd5a20da67a0af9af8;p=senf.git diff --git a/senf/Packets/80211Bundle/RadiotapPacket.hh b/senf/Packets/80211Bundle/RadiotapPacket.hh index c6fe53c..c375a56 100644 --- a/senf/Packets/80211Bundle/RadiotapPacket.hh +++ b/senf/Packets/80211Bundle/RadiotapPacket.hh @@ -4,6 +4,7 @@ // Fraunhofer Institute for Open Communication Systems (FOKUS) // Competence Center NETwork research (NET), St. Augustin, GERMANY // Christian Niephaus +// Stefan Bund // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -26,10 +27,12 @@ #ifndef HH_SENF_Packets_80211Bundle_RadiotapPacket_ #define HH_SENF_Packets_80211Bundle_RadiotapPacket_ 1 -#include "../../Packets/Packets.hh" +// Custom includes +#include +#include -namespace senf -{ +//-///////////////////////////////////////////////////////////////////////////////////////////////// +namespace senf { /** \brief Parse Flag field in Radiotap header @@ -37,7 +40,7 @@ namespace senf */ struct RadiotapPacketParser_Flags : public PacketParserBase { - # include SENF_FIXED_PARSER() +# include SENF_FIXED_PARSER() SENF_PARSER_BITFIELD ( shortGI, 1, bool ); SENF_PARSER_BITFIELD ( badFCS, 1, bool ); @@ -49,6 +52,8 @@ namespace senf SENF_PARSER_BITFIELD ( cfp, 1, bool ); SENF_PARSER_FINALIZE ( RadiotapPacketParser_Flags ); + + friend class RadiotapPacketParser; }; /** \brief Parse in Radiotap Header channel frequency and flag field @@ -57,7 +62,7 @@ namespace senf */ struct RadiotapPacketParser_ChannelOptions : public PacketParserBase { - # include SENF_FIXED_PARSER() +# include SENF_FIXED_PARSER() SENF_PARSER_FIELD ( freq, UInt16LSBParser ); @@ -65,7 +70,7 @@ namespace senf SENF_PARSER_BITFIELD ( ofdm, 1, bool ); SENF_PARSER_BITFIELD ( cck, 1, bool ); SENF_PARSER_BITFIELD ( turbo, 1, bool ); - SENF_PARSER_SKIP_BITS ( 4 ); //currently unused in radiotap + SENF_PARSER_SKIP_BITS ( 4 ); SENF_PARSER_BITFIELD ( quarterRateChannel, 1, bool ); SENF_PARSER_BITFIELD ( halfRateChannel, 1, bool ); SENF_PARSER_BITFIELD ( gsm, 1, bool ); @@ -78,6 +83,29 @@ namespace senf SENF_PARSER_FINALIZE ( RadiotapPacketParser_ChannelOptions ); }; + struct RadiotapPacketParser_RxFlags : public PacketParserBase + { +# include SENF_FIXED_PARSER() + + SENF_PARSER_SKIP_BITS ( 6 ); + SENF_PARSER_BITFIELD ( badPlcp, 1, bool ); + SENF_PARSER_SKIP_BITS ( 1 ); + + SENF_PARSER_FINALIZE( RadiotapPacketParser_RxFlags ); + }; + + struct RadiotapPacketParser_TxFlags : public PacketParserBase + { +# include SENF_FIXED_PARSER() + + SENF_PARSER_SKIP_BITS ( 5 ); + SENF_PARSER_BITFIELD ( txRts, 1, bool ); + SENF_PARSER_BITFIELD ( txCts, 1, bool ); + SENF_PARSER_BITFIELD ( fail, 1, bool ); + + SENF_PARSER_FINALIZE( RadiotapPacketParser_TxFlags ); + }; + /** \brief Parse an Radiotap header Parser implementing the Radiotap header @@ -95,109 +123,177 @@ namespace senf \todo extended present field (bit 31 of present field is set) */ - struct RadiotapPacketParser : public PacketParserBase + struct RadiotapPacketParser_Header : public PacketParserBase { - # include SENF_PARSER() +# include SENF_FIXED_PARSER() /* * mandatory fields */ SENF_PARSER_FIELD ( version, UInt8Parser ); //padding bits, currently unused, it simply aligns the fields onto natural word boundaries. - SENF_PARSER_SKIP ( 1,1 ); + SENF_PARSER_SKIP ( 1 ); SENF_PARSER_FIELD ( length, UInt16LSBParser ); - /* - * present flags - * indicate which data field are contained in the packet - */ - SENF_PARSER_BITFIELD_RO ( lockQualityPresent, 1, bool ); - SENF_PARSER_BITFIELD_RO ( dbmAntennaNoisePresent, 1, bool ); - SENF_PARSER_BITFIELD_RO ( dbmAntennaSignalPresent, 1, bool ); - SENF_PARSER_BITFIELD_RO ( fhssPresent, 1, bool ); - SENF_PARSER_BITFIELD_RO ( channelOptionsPresent, 1, bool ); - SENF_PARSER_BITFIELD_RO ( ratePresent, 1, bool ); - SENF_PARSER_BITFIELD_RO ( flagsPresent, 1, bool ); - SENF_PARSER_BITFIELD_RO ( tsftPresent, 1, bool ); - SENF_PARSER_SKIP_BITS ( 1 ); //currently unused bits - SENF_PARSER_BITFIELD_RO ( headerFcsPresent, 1, bool ); - SENF_PARSER_BITFIELD_RO ( dbAntennaNoisePresent, 1, bool ); - SENF_PARSER_BITFIELD_RO ( dbAntennaSignalPresent, 1, bool ); - SENF_PARSER_BITFIELD_RO ( antennaPresent, 1, bool ); - SENF_PARSER_BITFIELD_RO ( dbmTxAttenuationPresent, 1, bool ); - SENF_PARSER_BITFIELD_RO ( dbTxAttenuationPresent, 1, bool ); - SENF_PARSER_BITFIELD_RO ( txAttenuationPresent, 1, bool ); - SENF_PARSER_SKIP_BITS ( 8 ); //currently unused bits - //if bit is set,another 32 bit present flag is attached (not implemented yet) - SENF_PARSER_BITFIELD ( extendedBitmaskPresent, 1, bool ); - SENF_PARSER_SKIP_BITS ( 7 ); //currently unused bits - - SENF_PARSER_LABEL( headerEnd_ ); + SENF_PARSER_PRIVATE_FIELD ( presentFlags, UInt32LSBParser ); + + SENF_PARSER_FINALIZE ( RadiotapPacketParser_Header ); + + enum PresentIndex { + // Could use the the entries from radiotap.h but I don't know, + // if I want to pollute the global and macro namespace even more ... + TSFT_INDEX = 0, + FLAGS_INDEX = 1, + RATE_INDEX = 2, + CHANNEL_INDEX = 3, + FHSS_INDEX = 4, + DBM_ANTSIGNAL_INDEX = 5, + DBM_ANTNOISE_INDEX = 6, + LOCK_QUALITY_INDEX = 7, + TX_ATTENUATION_INDEX = 8, + DB_TX_ATTENUATION_INDEX = 9, + DBM_TX_POWER_INDEX = 10, + ANTENNA_INDEX = 11, + DB_ANTSIGNAL_INDEX = 12, + DB_ANTNOISE_INDEX = 13, + RX_FLAGS_INDEX = 14, + TX_FLAGS_INDEX = 15, + RTS_RETRIES_INDEX = 16, + DATA_RETRIES_INDEX = 17, + + MAX_INDEX = 17, + + RADIOTOP_NS_INDEX = 29, + VENDOR_NS_INDEX = 30, + EXTENDED_BITMASK_INDEX = 31 + }; + + enum PresentFlag { + TSFT_FLAG = (1<(data().end()-4); - } - - SENF_PARSER_INIT() { - version() = 0; - } - - // The headers length is to be taken from the 'length' value - SENF_PARSER_GOTO_OFFSET( length(), headerEnd__init_bytes ); - - SENF_PARSER_FINALIZE( RadiotapPacketParser ); - - SENF_PARSER_SKIP_BITS( 4 ); - SENF_PARSER_BITFIELD_RO ( frameType, 2, unsigned ); - SENF_PARSER_SKIP_BITS( 2 ); - + static const size_type init_bytes = RadiotapPacketParser_Header::fixed_bytes; + + size_type bytes() const; + + //-//////////////////////////////////////////////////////////////////////// + +# define FIELD(name,type,index) \ + typedef type name ## _t; \ + type name() { return parseField(index); } \ + bool has_ ## name() { return currentTable()[index]; } \ + bool name ## Present() { return has_ ## name(); } \ + type init_ ## name() { initField(index); return name(); } \ + void disable_ ## name() { disableField(index); } + + FIELD( tsft, UInt64LSBParser, TSFT_INDEX ); + + // flags is special: disabling 'flags' must also disable the 'fcs' field + typedef RadiotapPacketParser_Flags flags_t; + flags_t flags() { return parseField(FLAGS_INDEX); } + bool has_flags() { return currentTable()[FLAGS_INDEX]; } + bool flagsPresent() { return has_flags(); } + flags_t init_flags() { initField(FLAGS_INDEX); return flags(); } + void disable_flags() { disable_fcs(); disableField(FLAGS_INDEX); } + + FIELD( rate, UInt8Parser, RATE_INDEX ); + FIELD( channelOptions, RadiotapPacketParser_ChannelOptions, CHANNEL_INDEX ); + FIELD( fhss, UInt16LSBParser, FHSS_INDEX ); + FIELD( dbmAntennaSignal, Int8Parser, DBM_ANTSIGNAL_INDEX ); + FIELD( dbmAntennaNoise, Int8Parser, DBM_ANTNOISE_INDEX ); + FIELD( lockQuality, UInt16LSBParser, LOCK_QUALITY_INDEX ); + FIELD( txAttenuation, UInt16LSBParser, TX_ATTENUATION_INDEX ); + FIELD( dbTxAttenuation, UInt16LSBParser, DB_TX_ATTENUATION_INDEX ); + FIELD( dbmTxAttenuation, Int8Parser, DBM_TX_POWER_INDEX ); + FIELD( antenna, UInt8Parser, ANTENNA_INDEX ); + FIELD( dbAntennaSignal, UInt8Parser, DB_ANTSIGNAL_INDEX ); + FIELD( dbAntennaNoise, UInt8Parser, DB_ANTNOISE_INDEX ); + FIELD( rxFlags, RadiotapPacketParser_RxFlags, RX_FLAGS_INDEX ); + FIELD( txFlags, RadiotapPacketParser_TxFlags, TX_FLAGS_INDEX ); + FIELD( rtsRetries, UInt8Parser, RTS_RETRIES_INDEX ); + FIELD( dataRetries, UInt8Parser, DATA_RETRIES_INDEX ); + +# undef FIELD + + typedef UInt32Parser fcs_t; + UInt32Parser fcs(); + bool has_fcs(); + UInt32Parser init_fcs(); + void disable_fcs(); + + unsigned frameType(); + + private: + static const size_type fixed_bytes = 0; // hide this member, just in case + + typedef boost::array OffsetTable; + + //-//////////////////////////////////////////////////////////////////////// + // Offset table handling + + static OffsetTable & offsetTable(boost::uint32_t presentFlags); + // Fills the offset table based on a packet + static void parseOffsetTable(boost::uint8_t * data, int maxLength, OffsetTable & table); + // Generate an offset table just from the present flags + static void buildOffsetTable(boost::uint32_t presentFlags, OffsetTable & table); + + //-//////////////////////////////////////////////////////////////////////// + + OffsetTable const & currentTable() const; + OffsetTable const & getTable(boost::uint32_t presentFlags) const; + + template + Parser parseField(unsigned index); + void initField(unsigned index); + void disableField(unsigned index); + + size_type calculateSize() const; + + void updatePresentFlags(boost::uint32_t flags); + void insertRemoveBytes(unsigned from, unsigned to, int bytes); + + OffsetTable const * currentTable_; + + friend class RadiotapPacketType; }; /** \brief Radiotap packet @@ -208,9 +304,9 @@ namespace senf \par Fields: \ref RadiotapPacketParser \image html RadiotapPacket.png - + \see http://www.radiotap.org/ - + \ingroup protocolbundle_80211 */ struct RadiotapPacketType @@ -221,11 +317,10 @@ namespace senf typedef ConcretePacket packet; typedef RadiotapPacketParser parser; - using mixin::init; using mixin::initSize; - static void dump(packet p, std::ostream &os); - static void finalize(packet p); + static void init(packet p); + static void dump(packet p, std::ostream & os); static factory_t nextPacketType(packet p); static optional_range nextPacketRange(packet p); }; @@ -233,6 +328,10 @@ namespace senf typedef ConcretePacket RadiotapPacket; } +//-///////////////////////////////////////////////////////////////////////////////////////////////// +#include "RadiotapPacket.cci" +//#include "RadiotapPacket.ct" +#include "RadiotapPacket.cti" #endif