X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=senf%2FPackets%2F80211Bundle%2FRadiotapPacket.hh;h=c1e9a91a00b6ef3183f4896ca9d2508fc997656a;hb=ddb2132be4265f8a0d7d4c954c7c9401e59d027c;hp=40f3def2c73f551fb3dd1bd7504e5f0ea74ecbba;hpb=9cb871b939efe93e35dd96808d25089399acfc46;p=senf.git diff --git a/senf/Packets/80211Bundle/RadiotapPacket.hh b/senf/Packets/80211Bundle/RadiotapPacket.hh index 40f3def..c1e9a91 100644 --- a/senf/Packets/80211Bundle/RadiotapPacket.hh +++ b/senf/Packets/80211Bundle/RadiotapPacket.hh @@ -2,23 +2,29 @@ // // Copyright (C) 2008 // Fraunhofer Institute for Open Communication Systems (FOKUS) -// Competence Center NETwork research (NET), St. Augustin, GERMANY -// Christian Niephaus // -// 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 -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. +// The contents of this file are subject to the Fraunhofer FOKUS Public License +// Version 1.0 (the "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// http://senf.berlios.de/license.html // -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// The Fraunhofer FOKUS Public License Version 1.0 is based on, +// but modifies the Mozilla Public License Version 1.1. +// See the full license text for the amendments. // -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// Software distributed under the License is distributed on an "AS IS" basis, +// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +// for the specific language governing rights and limitations under the License. +// +// The Original Code is Fraunhofer FOKUS code. +// +// The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. +// (registered association), Hansastraße 27 c, 80686 Munich, Germany. +// All Rights Reserved. +// +// Contributor(s): +// Stefan Bund +// Christian Niephaus /** \file \brief Radiotap header */ @@ -28,8 +34,9 @@ // Custom includes #include +#include -///////////////////////////////hh.p//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// namespace senf { /** \brief Parse Flag field in Radiotap header @@ -38,7 +45,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 ); @@ -50,6 +57,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 @@ -58,7 +67,7 @@ namespace senf { */ struct RadiotapPacketParser_ChannelOptions : public PacketParserBase { - # include SENF_FIXED_PARSER() +# include SENF_FIXED_PARSER() SENF_PARSER_FIELD ( freq, UInt16LSBParser ); @@ -66,7 +75,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 ); @@ -79,6 +88,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 @@ -96,108 +128,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<(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_; - /* 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 ); + friend class RadiotapPacketType; }; /** \brief Radiotap packet @@ -221,11 +322,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,10 +333,10 @@ namespace senf { typedef ConcretePacket RadiotapPacket; } -///////////////////////////////hh.e//////////////////////////////////////// -//#include "RadiotapPacket.cci" +//-///////////////////////////////////////////////////////////////////////////////////////////////// +#include "RadiotapPacket.cci" //#include "RadiotapPacket.ct" -//#include "RadiotapPacket.cti" +#include "RadiotapPacket.cti" #endif