40f3def2c73f551fb3dd1bd7504e5f0ea74ecbba
[senf.git] / senf / 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 // Custom includes
30 #include <senf/Packets/Packets.hh>
31
32 ///////////////////////////////hh.p////////////////////////////////////////
33 namespace senf {
34
35     /** \brief Parse Flag field in Radiotap header
36
37         <b>Re-ordering of bits due to LSB byte order</b>
38      */
39     struct RadiotapPacketParser_Flags : public PacketParserBase
40     {
41     #   include SENF_FIXED_PARSER()
42
43         SENF_PARSER_BITFIELD ( shortGI,        1, bool );
44         SENF_PARSER_BITFIELD ( badFCS,         1, bool );
45         SENF_PARSER_BITFIELD ( padding,        1, bool );
46         SENF_PARSER_BITFIELD_RO ( fcsAtEnd,    1, bool ); // Cannot change this (change packet size)
47         SENF_PARSER_BITFIELD ( fragmentation,  1, bool );
48         SENF_PARSER_BITFIELD ( wep,            1, bool );
49         SENF_PARSER_BITFIELD ( shortPreamble,  1, bool );
50         SENF_PARSER_BITFIELD ( cfp,            1, bool );
51
52         SENF_PARSER_FINALIZE ( RadiotapPacketParser_Flags );
53     };
54
55     /** \brief Parse in Radiotap Header channel frequency and flag field
56
57         <b>Re-ordering of bits due to LSB byte order</b>
58      */
59     struct RadiotapPacketParser_ChannelOptions : public PacketParserBase
60     {
61     #   include SENF_FIXED_PARSER()
62
63         SENF_PARSER_FIELD     ( freq,          UInt16LSBParser );
64
65         SENF_PARSER_BITFIELD  ( flag2ghz,             1, bool  );
66         SENF_PARSER_BITFIELD  ( ofdm,                 1, bool  );
67         SENF_PARSER_BITFIELD  ( cck,                  1, bool  );
68         SENF_PARSER_BITFIELD  ( turbo,                1, bool  );
69         SENF_PARSER_SKIP_BITS ( 4                              ); //currently unused in radiotap
70         SENF_PARSER_BITFIELD  ( quarterRateChannel,   1, bool  );
71         SENF_PARSER_BITFIELD  ( halfRateChannel,      1, bool  );
72         SENF_PARSER_BITFIELD  ( gsm,                  1, bool  );
73         SENF_PARSER_BITFIELD  ( staticTurbo,          1, bool  );
74         SENF_PARSER_BITFIELD  ( gfsk,                 1, bool  );
75         SENF_PARSER_BITFIELD  ( cckOfdm,              1, bool  );
76         SENF_PARSER_BITFIELD  ( passive,              1, bool  );
77         SENF_PARSER_BITFIELD  ( flag5ghz,             1, bool  );
78
79         SENF_PARSER_FINALIZE ( RadiotapPacketParser_ChannelOptions );
80     };
81
82     /** \brief Parse an Radiotap header
83
84         Parser implementing the Radiotap header
85
86         Radiotap requires that all fields in the radiotap header
87         are aligned to natural boundaries. For radiotap,
88         that means all 8-, 16-, 32-, and 64-bit fields
89         must begin on 8-, 16-, 32-, and 64-bit boundaries, respectively.
90         In this way, generators and parsers can avoid unaligned
91         accesses to radiotap capture fields. Radiotap-compliant
92         generators must insert padding before a capture field
93         to ensure its natural alignment.
94
95         \see <a href="http://www.radiotap.org">Radiotap.org</a>
96
97         \todo extended present field (bit 31 of present field is set)
98     */
99     struct RadiotapPacketParser : public PacketParserBase
100     {
101     #   include SENF_PARSER()
102
103         /*
104          * mandatory fields
105          */
106         SENF_PARSER_FIELD ( version, UInt8Parser     );
107         //padding bits, currently unused, it simply aligns the fields onto natural word boundaries.
108         SENF_PARSER_SKIP  ( 1,1                      );
109         SENF_PARSER_FIELD ( length,  UInt16LSBParser );
110
111         /*
112          * present flags
113          * indicate which data field are contained in the packet
114          */
115         SENF_PARSER_BITFIELD_RO ( lockQualityPresent,      1, bool );
116         SENF_PARSER_BITFIELD_RO ( dbmAntennaNoisePresent,  1, bool );
117         SENF_PARSER_BITFIELD_RO ( dbmAntennaSignalPresent, 1, bool );
118         SENF_PARSER_BITFIELD_RO ( fhssPresent,             1, bool );
119         SENF_PARSER_BITFIELD_RO ( channelOptionsPresent,   1, bool );
120         SENF_PARSER_BITFIELD_RO ( ratePresent,             1, bool );
121         SENF_PARSER_BITFIELD_RO ( flagsPresent,            1, bool );
122         SENF_PARSER_BITFIELD_RO ( tsftPresent,             1, bool );
123         SENF_PARSER_SKIP_BITS   ( 1                                ); //currently unused bits
124         SENF_PARSER_BITFIELD_RO ( headerFcsPresent,        1, bool );
125         SENF_PARSER_BITFIELD_RO ( dbAntennaNoisePresent,   1, bool );
126         SENF_PARSER_BITFIELD_RO ( dbAntennaSignalPresent,  1, bool );
127         SENF_PARSER_BITFIELD_RO ( antennaPresent,          1, bool );
128         SENF_PARSER_BITFIELD_RO ( dbmTxAttenuationPresent, 1, bool );
129         SENF_PARSER_BITFIELD_RO ( dbTxAttenuationPresent,  1, bool );
130         SENF_PARSER_BITFIELD_RO ( txAttenuationPresent,    1, bool );
131         SENF_PARSER_SKIP_BITS   ( 8                                ); //currently unused bits
132         //if bit is set,another 32 bit present flag is attached (not implemented yet)
133         SENF_PARSER_BITFIELD    ( extendedBitmaskPresent,  1, bool );
134         SENF_PARSER_SKIP_BITS   ( 7                                ); //currently unused bits
135
136         SENF_PARSER_LABEL( headerEnd_ );
137
138         /*
139          * Radiotap data
140          * parsing data according to present flags
141          *
142          * PARSER_SKIP required to skip correct length of padding bits
143          */
144
145         /* macro to create required variant parser */
146         #define OPTIONAL_FIELD(name, parser) SENF_PARSER_VARIANT \
147             ( name##_, name##Present, \
148               ( novalue( disable_##name, VoidPacketParser )) \
149               (      id( name,           parser           )) )
150
151         /* macro to create padding parser */
152         #define SKIP_OPTIONAL_PADDING(cond, parser, size) \
153             SENF_PARSER_SKIP( \
154                     (cond ? (size - (parser##__offset() + \
155                             senf::bytes(parser##_())) % size) % size : 0) , 0  );
156
157         OPTIONAL_FIELD        ( tsft,                     UInt64LSBParser                     );
158         OPTIONAL_FIELD        ( flags,                    RadiotapPacketParser_Flags          ); //<pkgdraw: size=8
159         OPTIONAL_FIELD        ( rate,                     UInt8Parser                         );
160         SKIP_OPTIONAL_PADDING ( channelOptionsPresent(),  rate, 2                             );
161         OPTIONAL_FIELD        ( channelOptions,           RadiotapPacketParser_ChannelOptions ); //<pkgdraw: size=32
162         SKIP_OPTIONAL_PADDING ( fhssPresent(),            channelOptions, 2                   );
163         OPTIONAL_FIELD        ( fhss,                     UInt16LSBParser                     );
164         OPTIONAL_FIELD        ( dbmAntennaSignal,         Int8Parser                          );
165         OPTIONAL_FIELD        ( dbmAntennaNoise,          Int8Parser                          );
166         SKIP_OPTIONAL_PADDING ( lockQualityPresent(),     dbmAntennaNoise, 2                  );
167         OPTIONAL_FIELD        ( lockQuality,              UInt16LSBParser                     );
168         SKIP_OPTIONAL_PADDING ( txAttenuationPresent(),   lockQuality, 2                      );
169         OPTIONAL_FIELD        ( txAttenuation,            UInt16LSBParser                     );
170         SKIP_OPTIONAL_PADDING ( dbTxAttenuationPresent(), txAttenuation, 2                    );
171         OPTIONAL_FIELD        ( dbTxAttenuation,          UInt16LSBParser                     );
172         OPTIONAL_FIELD        ( dbmTxAttenuation,         Int8Parser                          );
173         OPTIONAL_FIELD        ( antenna,                  UInt8Parser                         );
174         OPTIONAL_FIELD        ( dbAntennaSignal,          UInt8Parser                         );
175         OPTIONAL_FIELD        ( dbAntennaNoise,           UInt8Parser                         );
176         SKIP_OPTIONAL_PADDING ( headerFcsPresent(),       dbAntennaNoise, 4                   );
177         OPTIONAL_FIELD        ( headerFcs,                UInt32Parser                        );
178
179         SENF_PARSER_LABEL( packetEnd_ );
180
181         size_type calculateSize() { return packetEnd__offset(); }
182
183         // Ouch ... changing the flags().fcsAtEnd() field needs to resize the packet ... !!!
184         // Need to think, if I can do this with a variant parser ...
185         SENF_PARSER_CUSTOM_FIELD( fcs, senf::UInt32Parser, 0, 0 ) {
186             return parse<senf::UInt32Parser>(data().end()-4);
187         }
188
189         SENF_PARSER_INIT() {
190             version() = 0;
191         }
192
193         // The headers length is to be taken from the 'length' value
194         SENF_PARSER_GOTO_OFFSET( length(), headerEnd__init_bytes );
195
196         SENF_PARSER_FINALIZE( RadiotapPacketParser );
197
198         SENF_PARSER_SKIP_BITS( 4 );
199         SENF_PARSER_BITFIELD_RO ( frameType, 2, unsigned );
200         SENF_PARSER_SKIP_BITS( 2 );
201     };
202
203     /** \brief Radiotap packet
204
205         \par Packet type (typedef):
206             \ref RadiotapPacket
207
208         \par Fields:
209             \ref RadiotapPacketParser
210             \image html RadiotapPacket.png
211
212         \see http://www.radiotap.org/
213
214         \ingroup protocolbundle_80211
215      */
216     struct RadiotapPacketType
217         : public PacketTypeBase,
218           public PacketTypeMixin<RadiotapPacketType>
219     {
220         typedef PacketTypeMixin<RadiotapPacketType> mixin;
221         typedef ConcretePacket<RadiotapPacketType> packet;
222         typedef RadiotapPacketParser parser;
223
224         using mixin::init;
225         using mixin::initSize;
226
227         static void dump(packet p, std::ostream &os);
228         static void finalize(packet p);
229         static factory_t nextPacketType(packet p);
230         static optional_range nextPacketRange(packet p);
231     };
232
233     typedef ConcretePacket<RadiotapPacketType> RadiotapPacket;
234 }
235
236 ///////////////////////////////hh.e////////////////////////////////////////
237 //#include "RadiotapPacket.cci"
238 //#include "RadiotapPacket.ct"
239 //#include "RadiotapPacket.cti"
240 #endif
241
242 \f
243 // Local Variables:
244 // mode: c++
245 // fill-column: 100
246 // comment-column: 40
247 // c-file-style: "senf"
248 // indent-tabs-mode: nil
249 // ispell-local-dictionary: "american"
250 // compile-command: "scons -u test"
251 // End: