Packets/80211Bundle: Read-only radiotap reimplementation
g0dil [Fri, 20 Aug 2010 06:40:15 +0000 (06:40 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1691 270642c3-0616-0410-b53a-bc976706d245

13 files changed:
senf/Packets/80211Bundle/RadiotapPacket.cc
senf/Packets/80211Bundle/RadiotapPacket.hh
senf/Packets/80211Bundle/RadiotapPacket.test.cc
senf/Packets/80211Bundle/SConscript
senf/Packets/80211Bundle/radiotap/SConscript [new file with mode: 0644]
senf/Packets/80211Bundle/radiotap/platform.h [new file with mode: 0644]
senf/Packets/80211Bundle/radiotap/radiotap.c [new file with mode: 0644]
senf/Packets/80211Bundle/radiotap/radiotap.h [new file with mode: 0644]
senf/Packets/80211Bundle/radiotap/radiotap_iter.h [new file with mode: 0644]
senf/Packets/PacketParser.ct
senf/Packets/PacketParser.cti
senf/Packets/PacketParser.ih
site_scons/SENFSCons.py

index 474f4b0..ceff474 100644 (file)
 #include "WLANPacket.hh"
 #include <boost/io/ios_state.hpp>
 
+extern "C" {
+#   include "radiotap/radiotap_iter.h"
+}
+
 #define prefix_
 ///////////////////////////////cc.p//////////////////////////////////////
 
-namespace {
-    #define DUMP_OPTIONAL_FIELD(name, sign, desc)           \
-        if (p->has_##name())                                \
-            os << senf::fieldName(desc) << sign( p->name()) \
-               << std::endl;
+prefix_ void senf::RadiotapPacketParser::fillOffsetTable(boost::uint8_t * data, int maxLength,
+                                                         OffsetTable & table)
+{
+    struct ieee80211_radiotap_iterator iter;
+    ieee80211_radiotap_iterator_init(&iter,
+                                     (struct ieee80211_radiotap_header *)data,
+                                     maxLength,
+                                     0);
+    while (ieee80211_radiotap_iterator_next(&iter)==0) {
+        if (iter.is_radiotap_ns &&
+            iter.this_arg_index <= int(senf::RadiotapPacketParser::MAX_INDEX)) {
+            table[iter.this_arg_index] = iter.this_arg - data;
+            std::cerr << ">> " << iter.this_arg_index << " " << table[iter.this_arg_index] << "\n";
+        }
+    }
+    table[MAX_INDEX+1] = iter.this_arg - data + iter.this_arg_size;
+    std::cerr << ">> size " << table[MAX_INDEX+1] << "\n";
+}
+
+prefix_ senf::RadiotapPacketParser::OffsetTable const &
+senf::RadiotapPacketParser::offsetTable(boost::uint32_t presentFlags)
+{
+    typedef std::map<boost::uint32_t, OffsetTable> OffsetMap;
+    static OffsetMap offsetMap;
+
+    OffsetMap::iterator i (offsetMap.find(presentFlags));
+    if (i == offsetMap.end()) {
+        OffsetTable table;
+        fillOffsetTable(&(*data().begin()), data().size(), table);
+        i = offsetMap.insert(std::make_pair(presentFlags, table)).first;
+    }
+    return i->second;
 }
 
+
+#define DUMP_OPTIONAL_FIELD(name, sign, desc)                           \
+    if (p->name ## Present())                                           \
+        os << senf::fieldName(desc) << sign(p->name())                  \
+           << std::endl;
+
 prefix_ void senf::RadiotapPacketType::dump(packet p, std::ostream &os)
 {
     boost::io::ios_all_saver ias(os);
     os << "Radiotap:\n"
-       << senf::fieldName("version") << unsigned( p->version()) << "\n"
-       << senf::fieldName("length")  << unsigned( p->length()) << "\n";
+       << senf::fieldName("version") << unsigned(p->version()) << "\n"
+       << senf::fieldName("length")  << unsigned(p->length()) << "\n";
     // TODO: flags, channelOptions
     DUMP_OPTIONAL_FIELD( tsft,              unsigned, "MAC timestamp"        );
     DUMP_OPTIONAL_FIELD( rate,              unsigned, "rate"                 );
@@ -58,10 +95,13 @@ prefix_ void senf::RadiotapPacketType::dump(packet p, std::ostream &os)
     DUMP_OPTIONAL_FIELD( antenna,           unsigned, "antenna"              );
     DUMP_OPTIONAL_FIELD( dbAntennaSignal,   unsigned, "antenna signal (dB)"  );
     DUMP_OPTIONAL_FIELD( dbAntennaNoise,    unsigned, "antenna noise (dB)"   );
-    if (p->has_headerFcs())
-        os << senf::fieldName("FCS")     << unsigned( p->fcs()) << "\n";
+    DUMP_OPTIONAL_FIELD( headerFcs,         unsigned, "FCS (in header)"      );
+    if (p->flagsPresent() && p->flags().fcsAtEnd())
+        os << senf::fieldName("FCS (at end)") << unsigned(p->fcs()) << "\n";
 }
 
+#undef DUMP_OPTIONAL_FIELD
+
 prefix_ void senf::RadiotapPacketType::finalize(packet p)
 {
     p->length() << p->calculateSize();
index 40f3def..966f2b7 100644 (file)
@@ -28,6 +28,7 @@
 
 // Custom includes
 #include <senf/Packets/Packets.hh>
+#include <boost/array.hpp>
 
 ///////////////////////////////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          ); //<pkgdraw: size=8
-        OPTIONAL_FIELD        ( rate,                     UInt8Parser                         );
-        SKIP_OPTIONAL_PADDING ( channelOptionsPresent(),  rate, 2                             );
-        OPTIONAL_FIELD        ( channelOptions,           RadiotapPacketParser_ChannelOptions ); //<pkgdraw: size=32
-        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 ( headerFcsPresent(),       dbAntennaNoise, 4                   );
-        OPTIONAL_FIELD        ( headerFcs,                UInt32Parser                        );
-
-        SENF_PARSER_LABEL( packetEnd_ );
-
-        size_type calculateSize() { return packetEnd__offset(); }
-
-        // Ouch ... changing the flags().fcsAtEnd() field needs to resize the packet ... !!!
-        // Need to think, if I can do this with a variant parser ...
-        SENF_PARSER_CUSTOM_FIELD( fcs, senf::UInt32Parser, 0, 0 ) {
-            return parse<senf::UInt32Parser>(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<UInt64LSBParser>             (0); }
+        RadiotapPacketParser_Flags flags()
+            { return parseField<RadiotapPacketParser_Flags>  (1); }
+        UInt8Parser                rate()
+            { return parseField<UInt8Parser>                 (2); }
+        RadiotapPacketParser_ChannelOptions channelOptions()
+            { return parseField<RadiotapPacketParser_ChannelOptions>(3); }
+        UInt16LSBParser            fhss()
+            { return parseField<UInt16LSBParser>             (4); }
+        Int8Parser                 dbmAntennaSignal()
+            { return parseField<Int8Parser>                  (5); }
+        Int8Parser                 dbmAntennaNoise()
+            { return parseField<Int8Parser>                  (6); }
+        UInt16LSBParser            lockQuality()
+            { return parseField<UInt16LSBParser>             (7); }
+        UInt16LSBParser            txAttenuation()
+            { return parseField<UInt16LSBParser>             (8); }
+        UInt16LSBParser            dbTxAttenuation()
+            { return parseField<UInt16LSBParser>             (9); }
+        Int8Parser                 dbmTxAttenuation()
+            { return parseField<Int8Parser>                 (10); }
+        UInt8Parser                antenna()
+            { return parseField<UInt8Parser>                (11); }
+        UInt8Parser                dbAntennaSignal()
+            { return parseField<UInt8Parser>                (12); }
+        UInt8Parser                dbAntennaNoise()
+            { return parseField<UInt8Parser>                (13); }
+        UInt32Parser               headerFcs()
+            { return parseField<UInt32Parser>               (14); }
+
+        unsigned frameType()
+            { return parse<RadiotapPacketParser_FrameType>(length()).frameType(); }
+
+        UInt32Parser fcs()
+            { return parse<senf::UInt32Parser>(data().end()-4); }
+
+    private:
+        static const size_type fixed_bytes = 0; // 'remove' this member ...
+        static const unsigned MAX_INDEX = 14;
+
+        typedef boost::array<size_type,MAX_INDEX+2> OffsetTable;
+
+        OffsetTable const & offsetTable(boost::uint32_t presentFlags);
+        static void fillOffsetTable(boost::uint8_t * data, int maxLength, OffsetTable & table);
+
+        template <class Parser>
+        Parser parseField(unsigned index)
+            { return parse<Parser>(offsetTable(presentFlags())[index]); }
+
+        size_type calculateSize()
+            { return offsetTable(presentFlags())[MAX_INDEX+1]; }
+
+        friend class RadiotapPacketType;
     };
 
     /** \brief Radiotap packet
index bd20348..91c1e80 100644 (file)
@@ -99,6 +99,7 @@ SENF_AUTO_UNIT_TEST(RadiotapPacket_packet)
     SENF_CHECK_NO_THROW( p.dump( oss));
 }
 
+#if 0
 SENF_AUTO_UNIT_TEST(RadiotapPacket_create)
 {
     unsigned char data[] = {
@@ -154,6 +155,7 @@ SENF_AUTO_UNIT_TEST(RadiotapPacket_create)
     BOOST_CHECK_EQUAL_COLLECTIONS( p.data().begin(), p.data().end(),
                                    data, data+sizeof(data)/sizeof(data[0]) );
 }
+#endif
 
 SENF_AUTO_UNIT_TEST(RadiotapPacket_packet_ath9k)
 {
@@ -173,7 +175,12 @@ SENF_AUTO_UNIT_TEST(RadiotapPacket_packet_ath9k)
 
     BOOST_CHECK_EQUAL( p->dbmAntennaSignal(), -78);
     BOOST_CHECK_EQUAL( p->dbmAntennaNoise(), -95);
+#if 0
+    // The standard defines this field as RXFlags / TXFLags, so using the
+    // 'official' radiotap parser, this test fails ...
+    // Why is this field parsed using MSB byteorder ??
     BOOST_CHECK_EQUAL( p->headerFcs(), 0xd51af794);
+#endif
     BOOST_CHECK_EQUAL( p->antenna(), 0u);
 }
 
index 9f77b74..6c532af 100644 (file)
@@ -5,4 +5,6 @@ import SENFSCons
 
 ###########################################################################
 
-SENFSCons.AutoPacketBundle(env, '80211Bundle')
+SConscript(env.Glob("*/SConscript"))
+
+SENFSCons.AutoPacketBundle(env, '80211Bundle', subdirs=['radiotap'])
diff --git a/senf/Packets/80211Bundle/radiotap/SConscript b/senf/Packets/80211Bundle/radiotap/SConscript
new file mode 100644 (file)
index 0000000..0b12252
--- /dev/null
@@ -0,0 +1,20 @@
+# -*- python -*-
+
+Import('env')
+import SENFSCons
+
+env.SetDefault(
+    RADIOTAP_FILES = env.Glob("*.h") + env.Glob("*.c"),
+    RADIOTAP_URL = 'http://git.sipsolutions.net/radiotap.git',
+    )
+
+env.PhonyTarget(
+    'update-radiotap', [],
+    [ Delete('$GITDIR'),
+      'git clone $RADIOTAP_URL $GITDIR',
+      'cp $_RADIOTAP_FILES $HERE',
+      Delete('$GITDIR') ],
+    HERE            = env.Dir('.'),
+    GITDIR          = env.Dir('radiotap.git'),
+    _RADIOTAP_FILES = [ env.Dir('radiotap.git').File(f)
+                        for f in env.Flatten(env.subst_list('$RADIOTAP_FILES')) ])
diff --git a/senf/Packets/80211Bundle/radiotap/platform.h b/senf/Packets/80211Bundle/radiotap/platform.h
new file mode 100644 (file)
index 0000000..9ab734b
--- /dev/null
@@ -0,0 +1,19 @@
+#include <stddef.h>
+#include <errno.h>
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+#include <endian.h>
+
+#define le16_to_cpu            le16toh
+#define le32_to_cpu            le32toh
+#define get_unaligned(p)                                       \
+({                                                             \
+       struct packed_dummy_struct {                            \
+               typeof(*(p)) __val;                             \
+       } __attribute__((packed)) *__ptr = (void *) (p);        \
+                                                               \
+       __ptr->__val;                                           \
+})
+#define get_unaligned_le16(p)  le16_to_cpu(get_unaligned((uint16_t *)(p)))
+#define get_unaligned_le32(p)  le32_to_cpu(get_unaligned((uint32_t *)(p)))
diff --git a/senf/Packets/80211Bundle/radiotap/radiotap.c b/senf/Packets/80211Bundle/radiotap/radiotap.c
new file mode 100644 (file)
index 0000000..6683d6a
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * Radiotap parser
+ *
+ * Copyright 2007              Andy Green <andy@warmcat.com>
+ * Copyright 2009              Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See COPYING for more details.
+ */
+#include "radiotap_iter.h"
+#include "platform.h"
+
+/* function prototypes and related defs are in radiotap_iter.h */
+
+static const struct radiotap_align_size rtap_namespace_sizes[] = {
+       [IEEE80211_RADIOTAP_TSFT] = { .align = 8, .size = 8, },
+       [IEEE80211_RADIOTAP_FLAGS] = { .align = 1, .size = 1, },
+       [IEEE80211_RADIOTAP_RATE] = { .align = 1, .size = 1, },
+       [IEEE80211_RADIOTAP_CHANNEL] = { .align = 2, .size = 4, },
+       [IEEE80211_RADIOTAP_FHSS] = { .align = 2, .size = 2, },
+       [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = { .align = 1, .size = 1, },
+       [IEEE80211_RADIOTAP_DBM_ANTNOISE] = { .align = 1, .size = 1, },
+       [IEEE80211_RADIOTAP_LOCK_QUALITY] = { .align = 2, .size = 2, },
+       [IEEE80211_RADIOTAP_TX_ATTENUATION] = { .align = 2, .size = 2, },
+       [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = { .align = 2, .size = 2, },
+       [IEEE80211_RADIOTAP_DBM_TX_POWER] = { .align = 1, .size = 1, },
+       [IEEE80211_RADIOTAP_ANTENNA] = { .align = 1, .size = 1, },
+       [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = { .align = 1, .size = 1, },
+       [IEEE80211_RADIOTAP_DB_ANTNOISE] = { .align = 1, .size = 1, },
+       [IEEE80211_RADIOTAP_RX_FLAGS] = { .align = 2, .size = 2, },
+       [IEEE80211_RADIOTAP_TX_FLAGS] = { .align = 2, .size = 2, },
+       [IEEE80211_RADIOTAP_RTS_RETRIES] = { .align = 1, .size = 1, },
+       [IEEE80211_RADIOTAP_DATA_RETRIES] = { .align = 1, .size = 1, },
+       /*
+        * add more here as they are defined in radiotap.h
+        */
+};
+
+static const struct ieee80211_radiotap_namespace radiotap_ns = {
+       .n_bits = sizeof(rtap_namespace_sizes) / sizeof(rtap_namespace_sizes[0]),
+       .align_size = rtap_namespace_sizes,
+};
+
+/**
+ * ieee80211_radiotap_iterator_init - radiotap parser iterator initialization
+ * @iterator: radiotap_iterator to initialize
+ * @radiotap_header: radiotap header to parse
+ * @max_length: total length we can parse into (eg, whole packet length)
+ *
+ * Returns: 0 or a negative error code if there is a problem.
+ *
+ * This function initializes an opaque iterator struct which can then
+ * be passed to ieee80211_radiotap_iterator_next() to visit every radiotap
+ * argument which is present in the header.  It knows about extended
+ * present headers and handles them.
+ *
+ * How to use:
+ * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator
+ * struct ieee80211_radiotap_iterator (no need to init the struct beforehand)
+ * checking for a good 0 return code.  Then loop calling
+ * __ieee80211_radiotap_iterator_next()... it returns either 0,
+ * -ENOENT if there are no more args to parse, or -EINVAL if there is a problem.
+ * The iterator's @this_arg member points to the start of the argument
+ * associated with the current argument index that is present, which can be
+ * found in the iterator's @this_arg_index member.  This arg index corresponds
+ * to the IEEE80211_RADIOTAP_... defines.
+ *
+ * Radiotap header length:
+ * You can find the CPU-endian total radiotap header length in
+ * iterator->max_length after executing ieee80211_radiotap_iterator_init()
+ * successfully.
+ *
+ * Alignment Gotcha:
+ * You must take care when dereferencing iterator.this_arg
+ * for multibyte types... the pointer is not aligned.  Use
+ * get_unaligned((type *)iterator.this_arg) to dereference
+ * iterator.this_arg for type "type" safely on all arches.
+ *
+ * Example code: parse.c
+ */
+
+int ieee80211_radiotap_iterator_init(
+       struct ieee80211_radiotap_iterator *iterator,
+       struct ieee80211_radiotap_header *radiotap_header,
+       int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns)
+{
+       /* Linux only supports version 0 radiotap format */
+       if (radiotap_header->it_version)
+               return -EINVAL;
+
+       /* sanity check for allowed length and radiotap length field */
+       if (max_length < get_unaligned_le16(&radiotap_header->it_len))
+               return -EINVAL;
+
+       iterator->_rtheader = radiotap_header;
+       iterator->_max_length = get_unaligned_le16(&radiotap_header->it_len);
+       iterator->_arg_index = 0;
+       iterator->_bitmap_shifter = get_unaligned_le32(&radiotap_header->it_present);
+       iterator->_arg = (uint8_t *)radiotap_header + sizeof(*radiotap_header);
+       iterator->_reset_on_ext = 0;
+       iterator->_next_bitmap = &radiotap_header->it_present;
+       iterator->_next_bitmap++;
+       iterator->_vns = vns;
+       iterator->current_namespace = &radiotap_ns;
+       iterator->is_radiotap_ns = 1;
+#ifdef RADIOTAP_SUPPORT_OVERRIDES
+       iterator->n_overrides = 0;
+       iterator->overrides = NULL;
+#endif
+
+       /* find payload start allowing for extended bitmap(s) */
+
+       if (iterator->_bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT)) {
+               while (get_unaligned_le32(iterator->_arg) &
+                                       (1 << IEEE80211_RADIOTAP_EXT)) {
+                       iterator->_arg += sizeof(uint32_t);
+
+                       /*
+                        * check for insanity where the present bitmaps
+                        * keep claiming to extend up to or even beyond the
+                        * stated radiotap header length
+                        */
+
+                       if ((unsigned long)iterator->_arg -
+                           (unsigned long)iterator->_rtheader >
+                           (unsigned long)iterator->_max_length)
+                               return -EINVAL;
+               }
+
+               iterator->_arg += sizeof(uint32_t);
+
+               /*
+                * no need to check again for blowing past stated radiotap
+                * header length, because ieee80211_radiotap_iterator_next
+                * checks it before it is dereferenced
+                */
+       }
+
+       iterator->this_arg = iterator->_arg;
+
+       /* we are all initialized happily */
+
+       return 0;
+}
+
+static void find_ns(struct ieee80211_radiotap_iterator *iterator,
+                   uint32_t oui, uint8_t subns)
+{
+       int i;
+
+       iterator->current_namespace = NULL;
+
+       if (!iterator->_vns)
+               return;
+
+       for (i = 0; i < iterator->_vns->n_ns; i++) {
+               if (iterator->_vns->ns[i].oui != oui)
+                       continue;
+               if (iterator->_vns->ns[i].subns != subns)
+                       continue;
+
+               iterator->current_namespace = &iterator->_vns->ns[i];
+               break;
+       }
+}
+
+#ifdef RADIOTAP_SUPPORT_OVERRIDES
+static int find_override(struct ieee80211_radiotap_iterator *iterator,
+                        int *align, int *size)
+{
+       int i;
+
+       if (!iterator->overrides)
+               return 0;
+
+       for (i = 0; i < iterator->n_overrides; i++) {
+               if (iterator->_arg_index == iterator->overrides[i].field) {
+                       *align = iterator->overrides[i].align;
+                       *size = iterator->overrides[i].size;
+                       if (!*align) /* erroneous override */
+                               return 0;
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+#endif
+
+
+/**
+ * ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg
+ * @iterator: radiotap_iterator to move to next arg (if any)
+ *
+ * Returns: 0 if there is an argument to handle,
+ * -ENOENT if there are no more args or -EINVAL
+ * if there is something else wrong.
+ *
+ * This function provides the next radiotap arg index (IEEE80211_RADIOTAP_*)
+ * in @this_arg_index and sets @this_arg to point to the
+ * payload for the field.  It takes care of alignment handling and extended
+ * present fields.  @this_arg can be changed by the caller (eg,
+ * incremented to move inside a compound argument like
+ * IEEE80211_RADIOTAP_CHANNEL).  The args pointed to are in
+ * little-endian format whatever the endianess of your CPU.
+ *
+ * Alignment Gotcha:
+ * You must take care when dereferencing iterator.this_arg
+ * for multibyte types... the pointer is not aligned.  Use
+ * get_unaligned((type *)iterator.this_arg) to dereference
+ * iterator.this_arg for type "type" safely on all arches.
+ */
+
+int ieee80211_radiotap_iterator_next(
+       struct ieee80211_radiotap_iterator *iterator)
+{
+       while (1) {
+               int hit = 0;
+               int pad, align, size, subns, vnslen;
+               uint32_t oui;
+
+               /* if no more EXT bits, that's it */
+               if ((iterator->_arg_index % 32) == IEEE80211_RADIOTAP_EXT &&
+                   !(iterator->_bitmap_shifter & 1))
+                       return -ENOENT;
+
+               if (!(iterator->_bitmap_shifter & 1))
+                       goto next_entry; /* arg not present */
+
+               /* get alignment/size of data */
+               switch (iterator->_arg_index % 32) {
+               case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
+               case IEEE80211_RADIOTAP_EXT:
+                       align = 1;
+                       size = 0;
+                       break;
+               case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
+                       align = 2;
+                       size = 6;
+                       break;
+               default:
+#ifdef RADIOTAP_SUPPORT_OVERRIDES
+                       if (find_override(iterator, &align, &size)) {
+                               /* all set */
+                       } else
+#endif
+                       if (!iterator->current_namespace ||
+                           iterator->_arg_index >= iterator->current_namespace->n_bits) {
+                               if (iterator->current_namespace == &radiotap_ns)
+                                       return -ENOENT;
+                               align = 0;
+                       } else {
+                               align = iterator->current_namespace->align_size[iterator->_arg_index].align;
+                               size = iterator->current_namespace->align_size[iterator->_arg_index].size;
+                       }
+                       if (!align) {
+                               /* skip all subsequent data */
+                               iterator->_arg = iterator->_next_ns_data;
+                               /* give up on this namespace */
+                               iterator->current_namespace = NULL;
+                               goto next_entry;
+                       }
+                       break;
+               }
+
+               /*
+                * arg is present, account for alignment padding
+                *
+                * Note that these alignments are relative to the start
+                * of the radiotap header.  There is no guarantee
+                * that the radiotap header itself is aligned on any
+                * kind of boundary.
+                *
+                * The above is why get_unaligned() is used to dereference
+                * multibyte elements from the radiotap area.
+                */
+
+               pad = ((unsigned long)iterator->_arg -
+                      (unsigned long)iterator->_rtheader) & (align - 1);
+
+               if (pad)
+                       iterator->_arg += align - pad;
+
+               /*
+                * this is what we will return to user, but we need to
+                * move on first so next call has something fresh to test
+                */
+               iterator->this_arg_index = iterator->_arg_index;
+               iterator->this_arg = iterator->_arg;
+               iterator->this_arg_size = size;
+
+               /* internally move on the size of this arg */
+               iterator->_arg += size;
+
+               /*
+                * check for insanity where we are given a bitmap that
+                * claims to have more arg content than the length of the
+                * radiotap section.  We will normally end up equalling this
+                * max_length on the last arg, never exceeding it.
+                */
+
+               if ((unsigned long)iterator->_arg -
+                   (unsigned long)iterator->_rtheader >
+                   (unsigned long)iterator->_max_length)
+                       return -EINVAL;
+
+               /* these special ones are valid in each bitmap word */
+               switch (iterator->_arg_index % 32) {
+               case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
+                       iterator->_bitmap_shifter >>= 1;
+                       iterator->_arg_index++;
+
+                       iterator->_reset_on_ext = 1;
+
+                       vnslen = get_unaligned_le16(iterator->this_arg + 4);
+                       iterator->_next_ns_data = iterator->_arg + vnslen;
+                       oui = (*iterator->this_arg << 16) |
+                               (*(iterator->this_arg + 1) << 8) |
+                               *(iterator->this_arg + 2);
+                       subns = *(iterator->this_arg + 3);
+
+                       find_ns(iterator, oui, subns);
+
+                       iterator->is_radiotap_ns = 0;
+                       /* allow parsers to show this information */
+                       iterator->this_arg_index =
+                               IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
+                       iterator->this_arg_size += vnslen;
+                       if ((unsigned long)iterator->this_arg +
+                           iterator->this_arg_size -
+                           (unsigned long)iterator->_rtheader >
+                           (unsigned long)(unsigned long)iterator->_max_length)
+                               return -EINVAL;
+                       hit = 1;
+                       break;
+               case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
+                       iterator->_bitmap_shifter >>= 1;
+                       iterator->_arg_index++;
+
+                       iterator->_reset_on_ext = 1;
+                       iterator->current_namespace = &radiotap_ns;
+                       iterator->is_radiotap_ns = 1;
+                       break;
+               case IEEE80211_RADIOTAP_EXT:
+                       /*
+                        * bit 31 was set, there is more
+                        * -- move to next u32 bitmap
+                        */
+                       iterator->_bitmap_shifter =
+                               get_unaligned_le32(iterator->_next_bitmap);
+                       iterator->_next_bitmap++;
+                       if (iterator->_reset_on_ext)
+                               iterator->_arg_index = 0;
+                       else
+                               iterator->_arg_index++;
+                       iterator->_reset_on_ext = 0;
+                       break;
+               default:
+                       /* we've got a hit! */
+                       hit = 1;
+ next_entry:
+                       iterator->_bitmap_shifter >>= 1;
+                       iterator->_arg_index++;
+               }
+
+               /* if we found a valid arg earlier, return it now */
+               if (hit)
+                       return 0;
+       }
+}
diff --git a/senf/Packets/80211Bundle/radiotap/radiotap.h b/senf/Packets/80211Bundle/radiotap/radiotap.h
new file mode 100644 (file)
index 0000000..09b1ee0
--- /dev/null
@@ -0,0 +1,245 @@
+/*-
+ * Copyright (c) 2003, 2004 David Young.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of David Young may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DAVID
+ * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+/*
+ * Modifications to fit into the linux IEEE 802.11 stack,
+ * Mike Kershaw (dragorn@kismetwireless.net)
+ */
+
+#ifndef IEEE80211RADIOTAP_H
+#define IEEE80211RADIOTAP_H
+
+#include <stdint.h>
+
+/* Base version of the radiotap packet header data */
+#define PKTHDR_RADIOTAP_VERSION                0
+
+/* A generic radio capture format is desirable. There is one for
+ * Linux, but it is neither rigidly defined (there were not even
+ * units given for some fields) nor easily extensible.
+ *
+ * I suggest the following extensible radio capture format. It is
+ * based on a bitmap indicating which fields are present.
+ *
+ * I am trying to describe precisely what the application programmer
+ * should expect in the following, and for that reason I tell the
+ * units and origin of each measurement (where it applies), or else I
+ * use sufficiently weaselly language ("is a monotonically nondecreasing
+ * function of...") that I cannot set false expectations for lawyerly
+ * readers.
+ */
+
+/* The radio capture header precedes the 802.11 header.
+ * All data in the header is little endian on all platforms.
+ */
+struct ieee80211_radiotap_header {
+       uint8_t it_version;     /* Version 0. Only increases
+                                * for drastic changes,
+                                * introduction of compatible
+                                * new fields does not count.
+                                */
+       uint8_t it_pad;
+       uint16_t it_len;        /* length of the whole
+                                * header in bytes, including
+                                * it_version, it_pad,
+                                * it_len, and data fields.
+                                */
+       uint32_t it_present;    /* A bitmap telling which
+                                * fields are present. Set bit 31
+                                * (0x80000000) to extend the
+                                * bitmap by another 32 bits.
+                                * Additional extensions are made
+                                * by setting bit 31.
+                                */
+};
+
+/* Name                                 Data type    Units
+ * ----                                 ---------    -----
+ *
+ * IEEE80211_RADIOTAP_TSFT              __le64       microseconds
+ *
+ *      Value in microseconds of the MAC's 64-bit 802.11 Time
+ *      Synchronization Function timer when the first bit of the
+ *      MPDU arrived at the MAC. For received frames, only.
+ *
+ * IEEE80211_RADIOTAP_CHANNEL           2 x uint16_t   MHz, bitmap
+ *
+ *      Tx/Rx frequency in MHz, followed by flags (see below).
+ *
+ * IEEE80211_RADIOTAP_FHSS              uint16_t       see below
+ *
+ *      For frequency-hopping radios, the hop set (first byte)
+ *      and pattern (second byte).
+ *
+ * IEEE80211_RADIOTAP_RATE              u8           500kb/s
+ *
+ *      Tx/Rx data rate
+ *
+ * IEEE80211_RADIOTAP_DBM_ANTSIGNAL     s8           decibels from
+ *                                                   one milliwatt (dBm)
+ *
+ *      RF signal power at the antenna, decibel difference from
+ *      one milliwatt.
+ *
+ * IEEE80211_RADIOTAP_DBM_ANTNOISE      s8           decibels from
+ *                                                   one milliwatt (dBm)
+ *
+ *      RF noise power at the antenna, decibel difference from one
+ *      milliwatt.
+ *
+ * IEEE80211_RADIOTAP_DB_ANTSIGNAL      u8           decibel (dB)
+ *
+ *      RF signal power at the antenna, decibel difference from an
+ *      arbitrary, fixed reference.
+ *
+ * IEEE80211_RADIOTAP_DB_ANTNOISE       u8           decibel (dB)
+ *
+ *      RF noise power at the antenna, decibel difference from an
+ *      arbitrary, fixed reference point.
+ *
+ * IEEE80211_RADIOTAP_LOCK_QUALITY      uint16_t       unitless
+ *
+ *      Quality of Barker code lock. Unitless. Monotonically
+ *      nondecreasing with "better" lock strength. Called "Signal
+ *      Quality" in datasheets.  (Is there a standard way to measure
+ *      this?)
+ *
+ * IEEE80211_RADIOTAP_TX_ATTENUATION    uint16_t       unitless
+ *
+ *      Transmit power expressed as unitless distance from max
+ *      power set at factory calibration.  0 is max power.
+ *      Monotonically nondecreasing with lower power levels.
+ *
+ * IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t       decibels (dB)
+ *
+ *      Transmit power expressed as decibel distance from max power
+ *      set at factory calibration.  0 is max power.  Monotonically
+ *      nondecreasing with lower power levels.
+ *
+ * IEEE80211_RADIOTAP_DBM_TX_POWER      s8           decibels from
+ *                                                   one milliwatt (dBm)
+ *
+ *      Transmit power expressed as dBm (decibels from a 1 milliwatt
+ *      reference). This is the absolute power level measured at
+ *      the antenna port.
+ *
+ * IEEE80211_RADIOTAP_FLAGS             u8           bitmap
+ *
+ *      Properties of transmitted and received frames. See flags
+ *      defined below.
+ *
+ * IEEE80211_RADIOTAP_ANTENNA           u8           antenna index
+ *
+ *      Unitless indication of the Rx/Tx antenna for this packet.
+ *      The first antenna is antenna 0.
+ *
+ * IEEE80211_RADIOTAP_RX_FLAGS          uint16_t       bitmap
+ *
+ *     Properties of received frames. See flags defined below.
+ *
+ * IEEE80211_RADIOTAP_TX_FLAGS          uint16_t       bitmap
+ *
+ *     Properties of transmitted frames. See flags defined below.
+ *
+ * IEEE80211_RADIOTAP_RTS_RETRIES       u8           data
+ *
+ *     Number of rts retries a transmitted frame used.
+ *
+ * IEEE80211_RADIOTAP_DATA_RETRIES      u8           data
+ *
+ *     Number of unicast retries a transmitted frame used.
+ *
+ */
+enum ieee80211_radiotap_type {
+       IEEE80211_RADIOTAP_TSFT = 0,
+       IEEE80211_RADIOTAP_FLAGS = 1,
+       IEEE80211_RADIOTAP_RATE = 2,
+       IEEE80211_RADIOTAP_CHANNEL = 3,
+       IEEE80211_RADIOTAP_FHSS = 4,
+       IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
+       IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
+       IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
+       IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
+       IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
+       IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
+       IEEE80211_RADIOTAP_ANTENNA = 11,
+       IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
+       IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
+       IEEE80211_RADIOTAP_RX_FLAGS = 14,
+       IEEE80211_RADIOTAP_TX_FLAGS = 15,
+       IEEE80211_RADIOTAP_RTS_RETRIES = 16,
+       IEEE80211_RADIOTAP_DATA_RETRIES = 17,
+
+       /* valid in every it_present bitmap, even vendor namespaces */
+       IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
+       IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
+       IEEE80211_RADIOTAP_EXT = 31
+};
+
+/* Channel flags. */
+#define        IEEE80211_CHAN_TURBO    0x0010  /* Turbo channel */
+#define        IEEE80211_CHAN_CCK      0x0020  /* CCK channel */
+#define        IEEE80211_CHAN_OFDM     0x0040  /* OFDM channel */
+#define        IEEE80211_CHAN_2GHZ     0x0080  /* 2 GHz spectrum channel. */
+#define        IEEE80211_CHAN_5GHZ     0x0100  /* 5 GHz spectrum channel */
+#define        IEEE80211_CHAN_PASSIVE  0x0200  /* Only passive scan allowed */
+#define        IEEE80211_CHAN_DYN      0x0400  /* Dynamic CCK-OFDM channel */
+#define        IEEE80211_CHAN_GFSK     0x0800  /* GFSK channel (FHSS PHY) */
+
+/* For IEEE80211_RADIOTAP_FLAGS */
+#define        IEEE80211_RADIOTAP_F_CFP        0x01    /* sent/received
+                                                * during CFP
+                                                */
+#define        IEEE80211_RADIOTAP_F_SHORTPRE   0x02    /* sent/received
+                                                * with short
+                                                * preamble
+                                                */
+#define        IEEE80211_RADIOTAP_F_WEP        0x04    /* sent/received
+                                                * with WEP encryption
+                                                */
+#define        IEEE80211_RADIOTAP_F_FRAG       0x08    /* sent/received
+                                                * with fragmentation
+                                                */
+#define        IEEE80211_RADIOTAP_F_FCS        0x10    /* frame includes FCS */
+#define        IEEE80211_RADIOTAP_F_DATAPAD    0x20    /* frame has padding between
+                                                * 802.11 header and payload
+                                                * (to 32-bit boundary)
+                                                */
+#define IEEE80211_RADIOTAP_F_BADFCS    0x40    /* frame failed FCS check */
+
+/* For IEEE80211_RADIOTAP_RX_FLAGS */
+#define IEEE80211_RADIOTAP_F_RX_BADPLCP        0x0002 /* bad PLCP */
+
+/* For IEEE80211_RADIOTAP_TX_FLAGS */
+#define IEEE80211_RADIOTAP_F_TX_FAIL   0x0001  /* failed due to excessive
+                                                * retries */
+#define IEEE80211_RADIOTAP_F_TX_CTS    0x0002  /* used cts 'protection' */
+#define IEEE80211_RADIOTAP_F_TX_RTS    0x0004  /* used rts/cts handshake */
+
+#endif                         /* IEEE80211_RADIOTAP_H */
diff --git a/senf/Packets/80211Bundle/radiotap/radiotap_iter.h b/senf/Packets/80211Bundle/radiotap/radiotap_iter.h
new file mode 100644 (file)
index 0000000..b768c85
--- /dev/null
@@ -0,0 +1,96 @@
+#ifndef __RADIOTAP_ITER_H
+#define __RADIOTAP_ITER_H
+
+#include <stdint.h>
+#include "radiotap.h"
+
+/* Radiotap header iteration
+ *   implemented in radiotap.c
+ */
+
+struct radiotap_override {
+       uint8_t field;
+       uint8_t align:4, size:4;
+};
+
+struct radiotap_align_size {
+       uint8_t align:4, size:4;
+};
+
+struct ieee80211_radiotap_namespace {
+       const struct radiotap_align_size *align_size;
+       int n_bits;
+       uint32_t oui;
+       uint8_t subns;
+};
+
+struct ieee80211_radiotap_vendor_namespaces {
+       const struct ieee80211_radiotap_namespace *ns;
+       int n_ns;
+};
+
+/**
+ * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args
+ * @this_arg_index: index of current arg, valid after each successful call
+ *     to ieee80211_radiotap_iterator_next()
+ * @this_arg: pointer to current radiotap arg; it is valid after each
+ *     call to ieee80211_radiotap_iterator_next() but also after
+ *     ieee80211_radiotap_iterator_init() where it will point to
+ *     the beginning of the actual data portion
+ * @this_arg_size: length of the current arg, for convenience
+ * @current_namespace: pointer to the current namespace definition
+ *     (or internally %NULL if the current namespace is unknown)
+ * @is_radiotap_ns: indicates whether the current namespace is the default
+ *     radiotap namespace or not
+ *
+ * @overrides: override standard radiotap fields
+ * @n_overrides: number of overrides
+ *
+ * @_rtheader: pointer to the radiotap header we are walking through
+ * @_max_length: length of radiotap header in cpu byte ordering
+ * @_arg_index: next argument index
+ * @_arg: next argument pointer
+ * @_next_bitmap: internal pointer to next present u32
+ * @_bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present
+ * @_vns: vendor namespace definitions
+ * @_next_ns_data: beginning of the next namespace's data
+ * @_reset_on_ext: internal; reset the arg index to 0 when going to the
+ *     next bitmap word
+ *
+ * Describes the radiotap parser state. Fields prefixed with an underscore
+ * must not be used by users of the parser, only by the parser internally.
+ */
+
+struct ieee80211_radiotap_iterator {
+       struct ieee80211_radiotap_header *_rtheader;
+       const struct ieee80211_radiotap_vendor_namespaces *_vns;
+       const struct ieee80211_radiotap_namespace *current_namespace;
+
+       unsigned char *_arg, *_next_ns_data;
+       uint32_t *_next_bitmap;
+
+       unsigned char *this_arg;
+#ifdef RADIOTAP_SUPPORT_OVERRIDES
+       const struct radiotap_override *overrides;
+       int n_overrides;
+#endif
+       int this_arg_index;
+       int this_arg_size;
+
+       int is_radiotap_ns;
+
+       int _max_length;
+       int _arg_index;
+       uint32_t _bitmap_shifter;
+       int _reset_on_ext;
+};
+
+extern int ieee80211_radiotap_iterator_init(
+       struct ieee80211_radiotap_iterator *iterator,
+       struct ieee80211_radiotap_header *radiotap_header,
+       int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns);
+
+extern int ieee80211_radiotap_iterator_next(
+       struct ieee80211_radiotap_iterator *iterator);
+
+#endif /* __RADIOTAP_ITER_H */
index 01569dd..5934762 100644 (file)
@@ -59,7 +59,7 @@ prefix_ Parser senf::operator<<(Parser target, Parser source)
 template <class Parser>
 prefix_ senf::PacketParserBase::size_type senf::detail::packetParserSize(Parser p, ...)
 {
-    return p.bytes();
+    return Parser::fixed_bytes;
 }
 
 ///////////////////////////////ct.e////////////////////////////////////////
index ca2a4c4..48f2334 100644 (file)
@@ -108,9 +108,9 @@ prefix_ Parser senf::operator<<(Parser target, Value const & value)
 
 template <class Parser>
 prefix_ senf::PacketParserBase::size_type
-senf::detail::packetParserSize(Parser p, int, senf::mpl::take_uint<Parser::fixed_bytes> *)
+senf::detail::packetParserSize(Parser p, int, senf::mpl::take_uint<Parser::init_bytes> *)
 {
-    return Parser::fixed_bytes;
+    return p.bytes();
 }
 
 
index 2eb95af..c55be7e 100644 (file)
@@ -38,12 +38,12 @@ namespace detail {
 
 #   ifndef DOXYGEN
 
-    // Use SFINAE to check, if Parser has an integer-valued fixed_bytes member. If not,
-    // 'Parser_TakeNum<Parser::fixed_bytes>' fails and the overload is removed from the overload
+    // Use SFINAE to check, if Parser has an integer-valued init_bytes member. If not,
+    // 'Parser_TakeNum<Parser::init_bytes>' fails and the overload is removed from the overload
     // set.
     template <class Parser>
     PacketParserBase::size_type packetParserSize(
-        Parser p, int, senf::mpl::take_uint<Parser::fixed_bytes> * = 0);
+        Parser p, int, senf::mpl::take_uint<Parser::init_bytes> * = 0);
 
     // An ellipsis is always the worst match. A call 'packetParserSize(p,0) will prefer above
     // overload if that is not disabled by SFINAE.
index 09e4c4d..e64e844 100644 (file)
@@ -6,12 +6,14 @@ from SCons.Script import *
 def Glob(env, exclude=[], subdirs=[]):
     testSources = env.Glob("*.test.cc",strings=True)
     sources = [ x
-                for x in env.Glob("*.cc",strings=True)
+                for x in env.Glob("*.cc",strings=True) \
+                    + env.Glob("*.c",strings=True)
                 if x not in testSources and x not in exclude ]
     for subdir in subdirs:
         testSources += env.Glob(os.path.join(subdir,"*.test.cc"),strings=True)
         sources += [ x
-                     for x in env.Glob(os.path.join(subdir,"*.cc"),strings=True)
+                     for x in env.Glob(os.path.join(subdir,"*.cc"),strings=True) \
+                         + env.Glob(os.path.join(subdir,"*.c"),strings=True)
                      if x not in testSources and x not in exclude ]
     includes = []
     for d in [ '' ] + [ x+'/' for x in subdirs ]: