Packets: Add packet diagram to RadiotapPacket
[senf.git] / Packets / 80211Bundle / RadiotapPacket.hh
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Christian Niephaus <cni@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Radiotap header */
25
26 #ifndef HH_SENF_Packets_80211Bundle_RadiotapPacket_
27 #define HH_SENF_Packets_80211Bundle_RadiotapPacket_ 1
28
29 #include "../../Packets/Packets.hh"
30
31 namespace senf
32 {
33
34     /** \brief Parse Flag field in Radiotap header
35
36         <b>Re-ordering of bits due to LSB byte order</b>
37      */
38     struct RadiotapPacketParser_Flags : public PacketParserBase
39     {
40     #   include SENF_FIXED_PARSER()
41
42         SENF_PARSER_BITFIELD ( shortGI,        1, bool );
43         SENF_PARSER_BITFIELD ( badFCS,         1, bool );
44         SENF_PARSER_BITFIELD ( padding,        1, bool );
45         SENF_PARSER_BITFIELD ( fcsPresent,     1, bool );
46         SENF_PARSER_BITFIELD ( fragmentation,  1, bool );
47         SENF_PARSER_BITFIELD ( wep,            1, bool );
48         SENF_PARSER_BITFIELD ( shortPreamble,  1, bool );
49         SENF_PARSER_BITFIELD ( cfp,            1, bool );
50
51         SENF_PARSER_FINALIZE ( RadiotapPacketParser_Flags );
52     };
53
54     /** \brief Parse in Radiotap Header channel frequency and flag field
55
56         <b>Re-ordering of bits due to LSB byte order</b>
57      */
58     struct RadiotapPacketParser_ChannelOptions : public PacketParserBase
59     {
60     #   include SENF_FIXED_PARSER()
61
62         SENF_PARSER_FIELD     ( freq,          UInt16LSBParser );
63
64         SENF_PARSER_BITFIELD  ( flag2ghz,             1, bool  );
65         SENF_PARSER_BITFIELD  ( ofdm,                 1, bool  );
66         SENF_PARSER_BITFIELD  ( cck,                  1, bool  );
67         SENF_PARSER_BITFIELD  ( turbo,                1, bool  );
68         SENF_PARSER_SKIP_BITS ( 4                              ); //currently unused in radiotap
69         SENF_PARSER_BITFIELD  ( quarterRateChannel,   1, bool  );
70         SENF_PARSER_BITFIELD  ( halfRateChannel,      1, bool  );
71         SENF_PARSER_BITFIELD  ( gsm,                  1, bool  );
72         SENF_PARSER_BITFIELD  ( staticTurbo,          1, bool  );
73         SENF_PARSER_BITFIELD  ( gfsk,                 1, bool  );
74         SENF_PARSER_BITFIELD  ( cckOfdm,              1, bool  );
75         SENF_PARSER_BITFIELD  ( passive,              1, bool  );
76         SENF_PARSER_BITFIELD  ( flag5ghz,             1, bool  );
77
78         SENF_PARSER_FINALIZE ( RadiotapPacketParser_ChannelOptions );
79     };
80
81     /** \brief Parse an Radiotap header
82
83         Parser implementing the Radiotap header
84
85         Radiotap requires that all fields in the radiotap header
86         are aligned to natural boundaries. For radiotap,
87         that means all 8-, 16-, 32-, and 64-bit fields
88         must begin on 8-, 16-, 32-, and 64-bit boundaries, respectively.
89         In this way, generators and parsers can avoid unaligned
90         accesses to radiotap capture fields. Radiotap-compliant
91         generators must insert padding before a capture field
92         to ensure its natural alignment.
93
94         \see <a href="http://www.radiotap.org">Radiotap.org</a>
95
96         \todo extended present field (bit 31 of present field is set)
97     */
98     struct RadiotapPacketParser : public PacketParserBase
99     {
100     #   include SENF_PARSER()
101
102         /*
103          * mandatory fields
104          */
105         SENF_PARSER_FIELD ( version, UInt8Parser     );
106         //padding bits, currently unused, it simply aligns the fields onto natural word boundaries.
107         SENF_PARSER_SKIP  ( 1,1                      );
108         SENF_PARSER_FIELD ( length,  UInt16LSBParser );
109
110         /*
111          * present flags
112          * indicate which data field are contained in the packet
113          */
114         SENF_PARSER_BITFIELD_RO ( lockQualityPresent,      1, bool );
115         SENF_PARSER_BITFIELD_RO ( dbmAntennaNoisePresent,  1, bool );
116         SENF_PARSER_BITFIELD_RO ( dbmAntennaSignalPresent, 1, bool );
117         SENF_PARSER_BITFIELD_RO ( fhssPresent,             1, bool );
118         SENF_PARSER_BITFIELD_RO ( channelOptionsPresent,   1, bool );
119         SENF_PARSER_BITFIELD_RO ( ratePresent,             1, bool );
120         SENF_PARSER_BITFIELD_RO ( flagsPresent,            1, bool );
121         SENF_PARSER_BITFIELD_RO ( tsftPresent,             1, bool );
122         SENF_PARSER_SKIP_BITS   ( 1                                ); //currently unused bits
123         SENF_PARSER_BITFIELD_RO ( fcsPresent,              1, bool );
124         SENF_PARSER_BITFIELD_RO ( dbAntennaNoisePresent,   1, bool );
125         SENF_PARSER_BITFIELD_RO ( dbAntennaSignalPresent,  1, bool );
126         SENF_PARSER_BITFIELD_RO ( antennaPresent,          1, bool );
127         SENF_PARSER_BITFIELD_RO ( dbmTxAttenuationPresent, 1, bool );
128         SENF_PARSER_BITFIELD_RO ( dbTxAttenuationPresent,  1, bool );
129         SENF_PARSER_BITFIELD_RO ( txAttenuationPresent,    1, bool );
130         SENF_PARSER_SKIP_BITS   ( 8                                ); //currently unused bits
131         //if bit is set,another 32 bit present flag is attached (not implemented yet)
132         SENF_PARSER_BITFIELD    ( extendedBitmaskPresent,  1, bool );
133         SENF_PARSER_SKIP_BITS   ( 7                                ); //currently unused bits
134
135         /*
136          * Radiotap data
137          * parsing data according to present flags
138          *
139          * PARSER_SKIP required to skip correct length of padding bits
140          */
141
142         /* macro to create required variant parser */
143         #define OPTIONAL_FIELD(name, parser) SENF_PARSER_VARIANT \
144             ( name##_, name##Present, \
145               ( novalue( disable_##name, VoidPacketParser )) \
146               (      id( name,           parser           )) )
147
148         /* macro to create padding parser */
149         #define SKIP_OPTIONAL_PADDING(cond, parser, size) \
150             SENF_PARSER_SKIP( \
151                     (cond ? (size - (parser##__offset() + \
152                             senf::bytes(parser##_())) % size) % size : 0) , 0  );
153
154         OPTIONAL_FIELD        ( tsft,                     UInt64LSBParser                     );
155         OPTIONAL_FIELD        ( flags,                    RadiotapPacketParser_Flags          ); //<pkgdraw: size=8
156         OPTIONAL_FIELD        ( rate,                     UInt8Parser                         );
157         SKIP_OPTIONAL_PADDING ( channelOptionsPresent(),  rate, 2                             );
158         OPTIONAL_FIELD        ( channelOptions,           RadiotapPacketParser_ChannelOptions ); //<pkgdraw: size=16
159         SKIP_OPTIONAL_PADDING ( fhssPresent(),            channelOptions, 2                   );
160         OPTIONAL_FIELD        ( fhss,                     UInt16LSBParser                     );
161         OPTIONAL_FIELD        ( dbmAntennaSignal,         Int8Parser                          );
162         OPTIONAL_FIELD        ( dbmAntennaNoise,          Int8Parser                          );
163         SKIP_OPTIONAL_PADDING ( lockQualityPresent(),     dbmAntennaNoise, 2                  );
164         OPTIONAL_FIELD        ( lockQuality,              UInt16LSBParser                     );
165         SKIP_OPTIONAL_PADDING ( txAttenuationPresent(),   lockQuality, 2                      );
166         OPTIONAL_FIELD        ( txAttenuation,            UInt16LSBParser                     );
167         SKIP_OPTIONAL_PADDING ( dbTxAttenuationPresent(), txAttenuation, 2                    );
168         OPTIONAL_FIELD        ( dbTxAttenuation,          UInt16LSBParser                     );
169         OPTIONAL_FIELD        ( dbmTxAttenuation,         Int8Parser                          );
170         OPTIONAL_FIELD        ( antenna,                  UInt8Parser                         );
171         OPTIONAL_FIELD        ( dbAntennaSignal,          UInt8Parser                         );
172         OPTIONAL_FIELD        ( dbAntennaNoise,           UInt8Parser                         );
173         SKIP_OPTIONAL_PADDING ( fcsPresent(),             dbAntennaNoise, 4                   );
174         OPTIONAL_FIELD        ( fcs,                      UInt32Parser                        );
175
176         SENF_PARSER_INIT() {
177             version() = 0;
178         }
179
180         SENF_PARSER_FINALIZE( RadiotapPacketParser );
181     };
182
183     /** \brief Radiotap packet
184
185         \par Packet type (typedef):
186             \ref RadiotapPacket
187
188         \par Fields:
189             \ref RadiotapPacketParser
190             \image html RadiotapPacket.png
191         
192         \see http://www.radiotap.org/
193         
194         \ingroup protocolbundle_80211
195      */
196     struct RadiotapPacketType
197         : public PacketTypeBase,
198           public PacketTypeMixin<RadiotapPacketType>
199     {
200         typedef PacketTypeMixin<RadiotapPacketType> mixin;
201         typedef ConcretePacket<RadiotapPacketType> packet;
202         typedef RadiotapPacketParser parser;
203
204         using mixin::nextPacketRange;
205         using mixin::init;
206         using mixin::initSize;
207
208         static void dump(packet p, std::ostream &os);
209         static void finalize(packet p);
210         static factory_t nextPacketType(packet p);
211     };
212
213     typedef ConcretePacket<RadiotapPacketType> RadiotapPacket;
214 }
215
216 #endif