added TCPPacket implemented by Dennis.
[senf.git] / Packets / 80211Bundle / WLANPacket.hh
index b91df6b..c632aa5 100644 (file)
 
 #include "../../Packets/Packets.hh"
 #include "../DefaultBundle/EthernetPacket.hh"
+#include "../DefaultBundle/LlcSnapPacket.hh"
 
 namespace senf
 {
 
-    /** \brief Management frame parser
-     * <b>Re-ordering of bits due to LSB byte order</b>
+    /** \brief 802.11 Frame parser
+        (see IEEE 802.11-2007 standard - Chapter 7 Frame formats)
+        <b>Re-ordering of bits due to host byte order</b>
 
+        Frame base class.
      */
-    struct WLANPacket_MgtFrameParser : public senf::PacketParserBase
+    struct WLANPacketParser : public senf::PacketParserBase
     {
-    #   include SENF_FIXED_PARSER()
+    #   include SENF_PARSER()
+
+        /*
+         * Frame control field
+         * re-ordering of fields due to the byte order
+         */
+        SENF_PARSER_BITFIELD_RO ( subtype,        4,  unsigned );
+        SENF_PARSER_BITFIELD_RO ( type,           2,  unsigned );
+        SENF_PARSER_BITFIELD    ( version,        2,  unsigned );
+        SENF_PARSER_BITFIELD    ( order,          1,  bool     );
+        SENF_PARSER_BITFIELD    ( protectedFrame, 1,  bool     );
+        SENF_PARSER_BITFIELD    ( moreData,       1,  bool     );
+        SENF_PARSER_BITFIELD    ( pwrMgt,         1,  bool     );
+        SENF_PARSER_BITFIELD    ( retry,          1,  bool     );
+        SENF_PARSER_BITFIELD    ( moreFrag,       1,  bool     );
+        SENF_PARSER_BITFIELD    ( fromDS,         1,  bool     );
+        SENF_PARSER_BITFIELD    ( toDS,           1,  bool     );
+
+        SENF_PARSER_FIELD       ( duration,       UInt16LSBParser );
+
+        SENF_PARSER_FINALIZE(WLANPacketParser);
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    /** \brief Management frame parser
+        <b>Re-ordering of bits due to LSB byte order</b>
+     */
+    struct WLANPacket_MgtFrameParser : public WLANPacketParser
+    {
+    #   include SENF_PARSER()
+
+        SENF_PARSER_INHERIT(WLANPacketParser);
 
-        SENF_PARSER_PRIVATE_BITFIELD ( subtype, 4,  unsigned                ); //<pkgdraw: hide
-       //skip type and version
-        SENF_PARSER_SKIP_BITS        (          4                           ); //<pkgdraw: hide
-        //jump to fist address field
-        SENF_PARSER_SKIP             ( 3                                    ); //<pkgdraw: hide
         SENF_PARSER_FIELD            ( destinationAddress, MACAddressParser );
         SENF_PARSER_FIELD            ( sourceAddress,      MACAddressParser );
         SENF_PARSER_FIELD            ( bssid,              MACAddressParser );
@@ -54,31 +84,56 @@ namespace senf
         SENF_PARSER_BITFIELD         ( fragmentNumber, 4, unsigned );
         SENF_PARSER_PRIVATE_FIELD    ( seqNumber_2,    UInt8Parser );
 
-        SENF_PARSER_FINALIZE(WLANPacket_MgtFrameParser);
+        SENF_PARSER_INIT() { type_() = 0; }
 
-        //this is needed due to the goto in the WLANPacketParser. Don't know exactly why yet.
-        SENF_PARSER_INIT() {}
+        SENF_PARSER_FINALIZE(WLANPacket_MgtFrameParser);
 
         boost::uint16_t sequenceNumber() const {
             return (uint16_t)(seqNumber_2()) << 4 | seqNumber_1();
         };
     };
 
+    /** \brief WLAN Management frame packet
+
+        \par Packet type (typedef):
+            \refWLANPacket_MgtFrame
+
+        \par Fields:
+            \ref WLANPacket_MgtFrameParser
+            \image html WLANPacket_MgtFrame.png
+
+        \ingroup protocolbundle_80211
+     */
+    struct WLANPacket_MgtFrameType
+        : public senf::PacketTypeBase,
+          public senf::PacketTypeMixin<WLANPacket_MgtFrameType>
+    {
+        typedef senf::PacketTypeMixin<WLANPacket_MgtFrameType> mixin;
+        typedef senf::ConcretePacket<WLANPacket_MgtFrameType> packet;
+        typedef WLANPacket_MgtFrameParser parser;
+
+        using mixin::init;
+        using mixin::initSize;
+        using senf::PacketTypeBase::nextPacketRange;
+
+        static void dump(packet p, std::ostream &os);
+    };
+
+    typedef WLANPacket_MgtFrameType::packet WLANPacket_MgtFrame;
+
+    ///////////////////////////////////////////////////////////////////////////
+
     /** \brief Control frame parser
-     * <b>Re-ordering of bits due to LSB byte order</b>
-     *
-     * currently only CTS, RTS and ACK control frames are supported
+        <b>Re-ordering of bits due to LSB byte order</b>
 
+        currently only CTS, RTS and ACK control frames are supported
      */
-    struct WLANPacket_CtrlFrameParser : public senf::PacketParserBase
+    struct WLANPacket_CtrlFrameParser : public WLANPacketParser
     {
     #   include SENF_PARSER()
 
-        SENF_PARSER_PRIVATE_BITFIELD ( subtype,  4,  unsigned            ); //<pkgdraw: hide
-       //skip type and version
-        SENF_PARSER_SKIP_BITS        (           4                       ); //<pkgdraw: hide
-        //jump to fist address field
-        SENF_PARSER_SKIP             ( 3, 3                              ); //<pkgdraw: hide
+        SENF_PARSER_INHERIT(WLANPacketParser);
+
         SENF_PARSER_FIELD            ( receiverAddress, MACAddressParser );
 
         //only RTS frame contains a source address field
@@ -88,28 +143,53 @@ namespace senf
                 ( ids( na,            is_ack, set_ack, key(13, VoidPacketParser)) )
                 ( ids( sourceAddress, is_rts, set_rts, key(11, MACAddressParser)) ) );
 
+        SENF_PARSER_INIT() { type_() = 1; }
+
         SENF_PARSER_FINALIZE(WLANPacket_CtrlFrameParser);
+    };
 
-        //this is needed to due to the goto in the WLANPacketParser. Don't know exactly why yet.
-        SENF_PARSER_INIT() {}
+    /** \brief WLAN Control frame packet
+
+        \par Packet type (typedef):
+            \ref WLANPacket_CtrlFrame
+
+        \par Fields:
+            \ref WLANPacket_CtrlFrameParser
+            \image html WLANPacket_CtrlFrame.png
+
+        \ingroup protocolbundle_80211
+     */
+    struct WLANPacket_CtrlFrameType
+        : public senf::PacketTypeBase,
+          public senf::PacketTypeMixin<WLANPacket_CtrlFrameType>
+    {
+        typedef senf::PacketTypeMixin<WLANPacket_CtrlFrameType> mixin;
+        typedef senf::ConcretePacket<WLANPacket_CtrlFrameType> packet;
+        typedef WLANPacket_CtrlFrameParser parser;
+
+        using mixin::init;
+        using mixin::initSize;
+        using senf::PacketTypeBase::nextPacketRange;
+
+        static void dump(packet p, std::ostream &os);
     };
 
-    /** \brief Data frame parser
-     * <b>Re-ordering of bits due to LSB byte order</b>
+    typedef WLANPacket_CtrlFrameType::packet WLANPacket_CtrlFrame;
 
+    ///////////////////////////////////////////////////////////////////////////
+
+    /** \brief Data frame parser
+        <b>Re-ordering of bits due to LSB byte order</b>
      */
-    struct WLANPacket_DataFrameParser : public senf::PacketParserBase
+    struct WLANPacket_DataFrameParser : public WLANPacketParser
     {
     #   include SENF_PARSER()
-        SENF_PARSER_PRIVATE_BITFIELD ( subtype,  4,  unsigned  ); //<pkgdraw: hide
-        //jump to 'toDS' and 'fromDS' bits
-        //skip type and version
-        SENF_PARSER_SKIP_BITS        ( 4                       ); //<pkgdraw: hide
-        //skip other flags
-        SENF_PARSER_SKIP_BITS        ( 6                       ); //<pkgdraw: hide
-        //needed in data frames due to the variable address fields
+
+        SENF_PARSER_INHERIT(WLANPacketParser);
+
+        SENF_PARSER_GOTO(subtype);
+        SENF_PARSER_SKIP_BITS(14);                                //<pkgdraw: hide
         SENF_PARSER_PRIVATE_BITFIELD ( dsBits,  2,  unsigned   ); //<pkgdraw: hide
-        //skip duration field
         SENF_PARSER_SKIP             ( 2, 2                    ); //<pkgdraw: hide
 
         SENF_PARSER_PRIVATE_FIELD    ( addr1, MACAddressParser );
@@ -122,12 +202,16 @@ namespace senf
         SENF_PARSER_BITFIELD         ( fragmentNumber, 4, unsigned );
         SENF_PARSER_PRIVATE_FIELD    ( seqNumber_2,    UInt8Parser );
 
-        //TODO fourth address field in case of WDS
-//        SENF_PARSER_PRIVATE_VARIANT (wds_, dsBits,
-//                ( novalue ( disable_addr4,               VoidPacketParser                    ))
-//                ( id      ( addr4,  key (3,                   MACAddressParser                     ))) );
+        boost::uint16_t sequenceNumber() const {
+            return (uint16_t)(seqNumber_2()) << 4 | seqNumber_1();
+        };
+
+        // TODO fourth address field in case of WDS
+        // SENF_PARSER_PRIVATE_VARIANT (wds_, dsBits,
+        //     ( novalue ( disable_addr4,               VoidPacketParser ))
+        //     ( id      ( addr4,  key (3,              MACAddressParser ))) );
 
-        //QoS Filed
+        //QoS Field
         SENF_PARSER_VARIANT ( qosField_, subtype,
                 ( ids( na,       na,           set_data,        key(0, VoidPacketParser)) )
                 ( ids( na,       na,           set_nullData,    key(4, VoidPacketParser)) )
@@ -135,104 +219,63 @@ namespace senf
                 //we cannot parse qos Null (data) frames at the moment
                 ( ids( na,       na,           set_qosNullData, key(12, UInt16LSBParser)) ) );
 
-        SENF_PARSER_FINALIZE(WLANPacket_DataFrameParser);
-
-        //this is needed to due to the goto in the WLANPacketParser. Don't know exactly why yet.
-        SENF_PARSER_INIT() {}
+        SENF_PARSER_INIT() { type_() = 2; }
 
-        boost::uint16_t sequenceNumber() const {
-            return (uint16_t)(seqNumber_2()) << 4 | seqNumber_1();
-        };
+        SENF_PARSER_FINALIZE(WLANPacket_DataFrameParser);
 
         MACAddressParser receiverAddress() const    { return addr1(); }; //ra is always addr1
         MACAddressParser transmitterAddress() const { return addr2(); }; //ta is always addr2
         MACAddressParser sourceAddress() const;
         MACAddressParser destinationAddress() const;
         MACAddressParser bssid() const;
-    };
-
-
-    /** \brief 802.11 Frame parser
-     * (see IEEE 802.11-2007 standard - Chapter 7 Frame formats)
-     * <b>Re-ordering of bits due to LSB byte order</b>
-
-     */
-    struct WLANPacketParser : public senf::PacketParserBase
-    {
-    #   include SENF_PARSER()
-
-        /*
-         * Frame control field
-         * re-ordering of fields due to the byte order
-         */
-        SENF_PARSER_BITFIELD_RO ( subtype,        4,  unsigned );
-        SENF_PARSER_BITFIELD_RO ( type,           2,  unsigned );
-        SENF_PARSER_BITFIELD    ( version,        2,  unsigned );
-        SENF_PARSER_BITFIELD    ( order,          1,  bool     );
-        SENF_PARSER_BITFIELD    ( protectedFrame, 1,  bool     );
-        SENF_PARSER_BITFIELD    ( moreData,       1,  bool     );
-        SENF_PARSER_BITFIELD    ( pwrMgt,         1,  bool     );
-        SENF_PARSER_BITFIELD    ( retry,          1,  bool     );
-        SENF_PARSER_BITFIELD    ( moreFrag,       1,  bool     );
-        SENF_PARSER_BITFIELD    ( fromDS,         1,  bool     );
-        SENF_PARSER_BITFIELD    ( toDS,           1,  bool     );
-
-        SENF_PARSER_FIELD       ( duration,       UInt16LSBParser );
-
-        SENF_PARSER_GOTO( subtype ); // subparsers need to know the subtype
-        SENF_PARSER_VARIANT ( frameType_,  type,
-                (     ids( mgtFrame,  is_mgtFrame,  init_mgtFrame,  WLANPacket_MgtFrameParser  ))
-                (     ids( ctrlFrame, is_ctrlFrame, init_ctrlFrame, WLANPacket_CtrlFrameParser ))
-                (     ids( dataFrame, is_dataFrame, init_dataFrame, WLANPacket_DataFrameParser ))
-                ( novalue( reserved,                                WLANPacket_CtrlFrameParser )) );
-
-        SENF_PARSER_CUSTOM_FIELD( fcs, senf::UInt32Parser, fcs_t::fixed_bytes, fcs_t::fixed_bytes) {
-          return parse<UInt32Parser>( data().size()-4 ); }
-
-        SENF_PARSER_FINALIZE(WLANPacketParser);
-
-        SENF_PARSER_INIT() {
-            version() = 0;
-        }
-
-        //Problems can occur with old madwifi and ath5k. Some frames only
-        //contains two byte FCS instead of four.
-//        UInt32Parser fcs() const { return parse<UInt32Parser>( data().size()-4 ); }
 
+        friend class WLANPacket_DataFrameType;
     };
 
-    /** \brief WLAN packet
+    /** \brief WLAN Data frame packet
 
         \par Packet type (typedef):
-            \ref WLANPacket
+            \ref WLANPacket_DataFrame
 
         \par Fields:
-            \ref WLANPacketParser
-           \image html WLANPacket.png
+            \ref WLANPacket_DataFrameParser
+            \image html WLANPacket_DataFrame.png
 
         \ingroup protocolbundle_80211
      */
-    struct WLANPacketType
+    struct WLANPacket_DataFrameType
         : public senf::PacketTypeBase,
-          public senf::PacketTypeMixin<WLANPacketType>
+          public senf::PacketTypeMixin<WLANPacket_DataFrameType>
     {
-        typedef senf::PacketTypeMixin<WLANPacketType> mixin;
-        typedef senf::ConcretePacket<WLANPacketType> packet;
-        typedef WLANPacketParser parser;
-
+        typedef senf::PacketTypeMixin<WLANPacket_DataFrameType> mixin;
+        typedef senf::ConcretePacket<WLANPacket_DataFrameType> packet;
+        typedef WLANPacket_DataFrameParser parser;
 
         using mixin::init;
         using mixin::initSize;
-//        using senf::PacketTypeBase::nextPacketRange;
-        static optional_range nextPacketRange(packet p);
-        static factory_t nextPacketType(packet p);
+        using mixin::nextPacketRange;
+
+        static factory_t nextPacketType(packet p) { 
+            return p->subtype() == 0 || p->subtype() == 8 
+                ? LlcSnapPacket::factory() 
+                : no_factory();
+        }
 
         static void dump(packet p, std::ostream &os);
-//        static PacketParserBase::size_type initSize();
     };
 
-    typedef senf::ConcretePacket<WLANPacketType> WLANPacket;
+    typedef WLANPacket_DataFrameType::packet WLANPacket_DataFrame;
 }
 
-
 #endif /* HH_SENF_Packets_80211Bundle_WLANPacket_ */
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
+// End: