// Custom includes
#include "RadiotapPacket.hh"
+#include "WLANPacket.hh"
#include "../../Packets/Packets.hh"
#include <boost/io/ios_state.hpp>
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_
/** \brief Parse Flag field in Radiotap header
* <b>Re-ordering of bits due to LSB byte order</b>
+ * (see http://www.radiotap.org/)
*/
struct RadiotapPacketParser_Flags : public senf::PacketParserBase
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 <a href="http://www.radiotap.org">Radiotap.org</a>
\todo extended present field (bit 31 of present field is set)
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 );
/*
* 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;
static void dump(packet p, std::ostream &os);
static void finalize(packet p);
+ static factory_t nextPacketType(packet p);
+
};
typedef senf::ConcretePacket<RadiotapPacketType> RadiotapPacket;
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);
+
+
+}
+