From: cni Date: Tue, 9 Dec 2008 16:28:24 +0000 (+0000) Subject: Packets/80211Bundle: fix problems with dynamic padding due to byte alignment in Radio... X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=c1a83da548df3b5cb63e201465f1b9cd79e320ed;p=senf.git Packets/80211Bundle: fix problems with dynamic padding due to byte alignment in Radiotap, add a further unittest for radiotap git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1009 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Packets/80211Bundle/RadiotapPacket.cc b/Packets/80211Bundle/RadiotapPacket.cc index 22cd2a9..a67514c 100644 --- a/Packets/80211Bundle/RadiotapPacket.cc +++ b/Packets/80211Bundle/RadiotapPacket.cc @@ -24,6 +24,7 @@ // Custom includes #include "RadiotapPacket.hh" +#include "WLANPacket.hh" #include "../../Packets/Packets.hh" #include @@ -33,15 +34,30 @@ prefix_ void senf::RadiotapPacketType::dump(packet p, std::ostream &os) { boost::io::ios_all_saver ias(os); - os << "Radiotap:\n" - << " Version : " << p->version() << "\n" - << " Length : " << p->length() << "\n"; + os << "Radiotap:\n" + << " Version : " << unsigned (p->version()) << "\n" + << " Length : " << unsigned (p->length()) << "\n"; + if (p->has_dbmAntennaSignal()) + os << " Signal : " << signed (p-> dbmAntennaSignal()) << "\n"; + if (p->has_tsft()) + os << " MAC timestamp : " << unsigned (p->tsft()) << "\n"; + if (p->has_dbmAntennaNoise()) + os << " Noise : " << signed (p-> dbmAntennaNoise()) << "\n"; + + + } prefix_ void senf::RadiotapPacketType::finalize(packet p) { + //TODO p->length() << p.size(); } +prefix_ senf::PacketInterpreterBase::factory_t senf::RadiotapPacketType::nextPacketType(packet p) +{ + return WLANPacket::factory(); +} + #undef prefix_ diff --git a/Packets/80211Bundle/RadiotapPacket.hh b/Packets/80211Bundle/RadiotapPacket.hh index 48d020b..ea6eee4 100644 --- a/Packets/80211Bundle/RadiotapPacket.hh +++ b/Packets/80211Bundle/RadiotapPacket.hh @@ -35,6 +35,7 @@ namespace senf /** \brief Parse Flag field in Radiotap header * Re-ordering of bits due to LSB byte order + * (see http://www.radiotap.org/) */ struct RadiotapPacketParser_Flags : public senf::PacketParserBase @@ -84,6 +85,15 @@ namespace senf Parser implementing the Radiotap header + Radiotap requires that all fields in the radiotap header + are aligned to natural boundaries. For radiotap, + that means all 8-, 16-, 32-, and 64-bit fields + must begin on 8-, 16-, 32-, and 64-bit boundaries, respectively. + In this way, generators and parsers can avoid unaligned + accesses to radiotap capture fields. Radiotap-compliant + generators must insert padding before a capture field + to ensure its natural alignment. + \see Radiotap.org \todo extended present field (bit 31 of present field is set) @@ -112,7 +122,8 @@ namespace senf 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 ( 2 ); //currently unused bits + SENF_PARSER_SKIP_BITS ( 1 ); //currently unused bits + SENF_PARSER_BITFIELD_RO ( fcsPresent, 1, bool ); SENF_PARSER_BITFIELD_RO ( dbAntennaNoisePresent, 1, bool ); SENF_PARSER_BITFIELD_RO ( dbAntennaSignalPresent, 1, bool ); SENF_PARSER_BITFIELD_RO ( antennaPresent, 1, bool ); @@ -127,24 +138,43 @@ namespace senf /* * Radiotap data * parsing data according to present flags + * + * PARSER_SKIP required to skip correct length of padding bits */ + + /* macro to create required variant parser */ #define OPTIONAL_FIELD(name, parser) SENF_PARSER_VARIANT \ ( name##_, name##Present, \ ( novalue( disable_##name, VoidPacketParser )) \ ( id( name, 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 ); OPTIONAL_FIELD ( rate, UInt8Parser ); - OPTIONAL_FIELD ( channelOptions, RadiotapPacketParser_ChannelOptions ); + SKIP_OPTIONAL_PADDING(channelOptionsPresent(), rate, 2); + OPTIONAL_FIELD ( channelOptions, RadiotapPacketParser_ChannelOptions ) ; + SKIP_OPTIONAL_PADDING(fhssPresent(), channelOptions, 2); OPTIONAL_FIELD ( fhss, UInt16LSBParser ); OPTIONAL_FIELD ( dbmAntennaSignal, Int8Parser ); OPTIONAL_FIELD ( dbmAntennaNoise, Int8Parser ); + SKIP_OPTIONAL_PADDING(lockQualityPresent(), dbmAntennaNoise, 2); + OPTIONAL_FIELD ( lockQuality, UInt16LSBParser ); + SKIP_OPTIONAL_PADDING(txAttenuationPresent(), lockQuality, 2); OPTIONAL_FIELD ( txAttenuation, UInt16LSBParser ); + SKIP_OPTIONAL_PADDING(dbTxAttenuationPresent(), txAttenuation, 2); OPTIONAL_FIELD ( dbTxAttenuation, UInt16LSBParser ); + OPTIONAL_FIELD ( dbmTxAttenuation, Int8Parser ); OPTIONAL_FIELD ( antenna, UInt8Parser ); OPTIONAL_FIELD ( dbAntennaSignal, UInt8Parser ); OPTIONAL_FIELD ( dbAntennaNoise, UInt8Parser ); + SKIP_OPTIONAL_PADDING(fcsPresent(), dbAntennaNoise, 4) + OPTIONAL_FIELD ( fcs, UInt32Parser ); SENF_PARSER_INIT() { version() = 0; @@ -177,6 +207,8 @@ namespace senf static void dump(packet p, std::ostream &os); static void finalize(packet p); + static factory_t nextPacketType(packet p); + }; typedef senf::ConcretePacket RadiotapPacket; diff --git a/Packets/80211Bundle/RadiotapPacket.test.cc b/Packets/80211Bundle/RadiotapPacket.test.cc index f304f02..b94efc4 100644 --- a/Packets/80211Bundle/RadiotapPacket.test.cc +++ b/Packets/80211Bundle/RadiotapPacket.test.cc @@ -148,3 +148,25 @@ BOOST_AUTO_UNIT_TEST(RadiotapPacket_create) BOOST_CHECK_EQUAL( p->length(), 26u ); BOOST_CHECK( equal( p.data().begin(), p.data().end(), data )); } + +BOOST_AUTO_UNIT_TEST(RadiotapPacket_packet_ath9k) +{ + /* radiotap packet from ath9k with atheros card*/ + unsigned char data[] = { + 0x00, 0x00, 0x20, 0x00, 0x6f, 0x48, 0x00, 0x00, 0x87, 0xbb, 0x91, 0x7c, 0x3b, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x85, 0x09, 0x80, 0x04, 0xb2, 0xa1, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x1a, 0xf7, 0x94 + }; + senf::RadiotapPacket p (senf::RadiotapPacket::create(data)); + + /* mandatory fields*/ + BOOST_CHECK_EQUAL( p->version(), 0u); + BOOST_CHECK_EQUAL( p->length(), 32u); + + BOOST_CHECK_EQUAL( p->dbmAntennaSignal(), -78); + BOOST_CHECK_EQUAL( p->dbmAntennaNoise(), -95); + BOOST_CHECK_EQUAL( p->fcs(), 0xd51af794); + BOOST_CHECK_EQUAL( p->antenna(), 0u); + + +} +