X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=senf%2FPackets%2F80211Bundle%2FRadiotapPacket.hh;h=966f2b750c775ef8154d14f09790f06d637b1d27;hb=0d88f940c093ff9c34099c9ab5c43e340f60a1f0;hp=40f3def2c73f551fb3dd1bd7504e5f0ea74ecbba;hpb=1c149cd73c2b9dc5b112958e1f247097cd18db6e;p=senf.git diff --git a/senf/Packets/80211Bundle/RadiotapPacket.hh b/senf/Packets/80211Bundle/RadiotapPacket.hh index 40f3def..966f2b7 100644 --- a/senf/Packets/80211Bundle/RadiotapPacket.hh +++ b/senf/Packets/80211Bundle/RadiotapPacket.hh @@ -28,6 +28,7 @@ // Custom includes #include +#include ///////////////////////////////hh.p//////////////////////////////////////// namespace senf { @@ -38,7 +39,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 ); @@ -58,7 +59,7 @@ namespace senf { */ struct RadiotapPacketParser_ChannelOptions : public PacketParserBase { - # include SENF_FIXED_PARSER() +# include SENF_FIXED_PARSER() SENF_PARSER_FIELD ( freq, UInt16LSBParser ); @@ -96,18 +97,21 @@ 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 ); + SENF_PARSER_PRIVATE_FIELD ( presentFlags, UInt32LSBParser ); + SENF_PARSER_GOTO( presentFlags ); + /* * present flags * indicate which data field are contained in the packet @@ -130,74 +134,87 @@ namespace senf { 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_BITFIELD_RO ( extendedBitmaskPresent, 1, bool ); SENF_PARSER_SKIP_BITS ( 7 ); //currently unused bits - SENF_PARSER_LABEL( headerEnd_ ); + SENF_PARSER_FINALIZE ( RadiotapPacketParser_Header ); + }; - /* - * Radiotap data - * parsing data according to present flags - * - * PARSER_SKIP required to skip correct length of padding bits - */ + struct RadiotapPacketParser_FrameType : public PacketParserBase + { +# include SENF_FIXED_PARSER() - /* macro to create required variant parser */ - #define OPTIONAL_FIELD(name, parser) SENF_PARSER_VARIANT \ - ( name##_, name##Present, \ - ( novalue( disable_##name, VoidPacketParser )) \ - ( id( name, parser )) ) - - /* macro to create padding parser */ - #define SKIP_OPTIONAL_PADDING(cond, parser, size) \ - SENF_PARSER_SKIP( \ - (cond ? (size - (parser##__offset() + \ - senf::bytes(parser##_())) % size) % size : 0) , 0 ); - - OPTIONAL_FIELD ( tsft, UInt64LSBParser ); - OPTIONAL_FIELD ( flags, RadiotapPacketParser_Flags ); //(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 ); + SENF_PARSER_SKIP_BITS(4); + SENF_PARSER_BITFIELD_RO( frameType, 2, unsigned ); + SENF_PARSER_SKIP_BITS(2); + + SENF_PARSER_FINALIZE(RadiotapPacketParser_FrameType); + }; + + struct RadiotapPacketParser : public RadiotapPacketParser_Header + { + RadiotapPacketParser(data_iterator i, state_type s) : RadiotapPacketParser_Header(i,s) {} + + static const size_type init_bytes = RadiotapPacketParser_Header::fixed_bytes; + + size_type bytes() const { return length(); } + + // //////////////////////////////////////////////////////////////////////// + + UInt64LSBParser tsft() + { return parseField (0); } + RadiotapPacketParser_Flags flags() + { return parseField (1); } + UInt8Parser rate() + { return parseField (2); } + RadiotapPacketParser_ChannelOptions channelOptions() + { return parseField(3); } + UInt16LSBParser fhss() + { return parseField (4); } + Int8Parser dbmAntennaSignal() + { return parseField (5); } + Int8Parser dbmAntennaNoise() + { return parseField (6); } + UInt16LSBParser lockQuality() + { return parseField (7); } + UInt16LSBParser txAttenuation() + { return parseField (8); } + UInt16LSBParser dbTxAttenuation() + { return parseField (9); } + Int8Parser dbmTxAttenuation() + { return parseField (10); } + UInt8Parser antenna() + { return parseField (11); } + UInt8Parser dbAntennaSignal() + { return parseField (12); } + UInt8Parser dbAntennaNoise() + { return parseField (13); } + UInt32Parser headerFcs() + { return parseField (14); } + + unsigned frameType() + { return parse(length()).frameType(); } + + UInt32Parser fcs() + { return parse(data().end()-4); } + + private: + static const size_type fixed_bytes = 0; // 'remove' this member ... + static const unsigned MAX_INDEX = 14; + + typedef boost::array OffsetTable; + + OffsetTable const & offsetTable(boost::uint32_t presentFlags); + static void fillOffsetTable(boost::uint8_t * data, int maxLength, OffsetTable & table); + + template + Parser parseField(unsigned index) + { return parse(offsetTable(presentFlags())[index]); } + + size_type calculateSize() + { return offsetTable(presentFlags())[MAX_INDEX+1]; } + + friend class RadiotapPacketType; }; /** \brief Radiotap packet