bd932ca45ea8577628b347c22462b338ff77b389
[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 #include <boost/array.hpp>
32
33 ///////////////////////////////hh.p////////////////////////////////////////
34 namespace senf {
35
36     /** \brief Parse Flag field in Radiotap header
37
38         <b>Re-ordering of bits due to LSB byte order</b>
39      */
40     struct RadiotapPacketParser_Flags : public PacketParserBase
41     {
42 #       include SENF_FIXED_PARSER()
43
44         SENF_PARSER_BITFIELD ( shortGI,        1, bool );
45         SENF_PARSER_BITFIELD ( badFCS,         1, bool );
46         SENF_PARSER_BITFIELD ( padding,        1, bool );
47         SENF_PARSER_BITFIELD_RO ( fcsAtEnd,    1, bool ); // Cannot change this (change packet size)
48         SENF_PARSER_BITFIELD ( fragmentation,  1, bool );
49         SENF_PARSER_BITFIELD ( wep,            1, bool );
50         SENF_PARSER_BITFIELD ( shortPreamble,  1, bool );
51         SENF_PARSER_BITFIELD ( cfp,            1, bool );
52
53         SENF_PARSER_FINALIZE ( RadiotapPacketParser_Flags );
54
55         friend class RadiotapPacketParser;
56     };
57
58     /** \brief Parse in Radiotap Header channel frequency and flag field
59
60         <b>Re-ordering of bits due to LSB byte order</b>
61      */
62     struct RadiotapPacketParser_ChannelOptions : public PacketParserBase
63     {
64 #       include SENF_FIXED_PARSER()
65
66         SENF_PARSER_FIELD     ( freq,          UInt16LSBParser );
67
68         SENF_PARSER_BITFIELD  ( flag2ghz,             1, bool  );
69         SENF_PARSER_BITFIELD  ( ofdm,                 1, bool  );
70         SENF_PARSER_BITFIELD  ( cck,                  1, bool  );
71         SENF_PARSER_BITFIELD  ( turbo,                1, bool  );
72         SENF_PARSER_SKIP_BITS ( 4                              );
73         SENF_PARSER_BITFIELD  ( quarterRateChannel,   1, bool  );
74         SENF_PARSER_BITFIELD  ( halfRateChannel,      1, bool  );
75         SENF_PARSER_BITFIELD  ( gsm,                  1, bool  );
76         SENF_PARSER_BITFIELD  ( staticTurbo,          1, bool  );
77         SENF_PARSER_BITFIELD  ( gfsk,                 1, bool  );
78         SENF_PARSER_BITFIELD  ( cckOfdm,              1, bool  );
79         SENF_PARSER_BITFIELD  ( passive,              1, bool  );
80         SENF_PARSER_BITFIELD  ( flag5ghz,             1, bool  );
81
82         SENF_PARSER_FINALIZE ( RadiotapPacketParser_ChannelOptions );
83     };
84
85     struct RadiotapPacketParser_RxFlags : public PacketParserBase
86     {
87 #       include SENF_FIXED_PARSER()
88
89         SENF_PARSER_SKIP_BITS ( 6                              );
90         SENF_PARSER_BITFIELD  ( badPlcp,              1, bool  );
91         SENF_PARSER_SKIP_BITS ( 1                              );
92
93         SENF_PARSER_FINALIZE( RadiotapPacketParser_RxFlags );
94     };
95
96     struct RadiotapPacketParser_TxFlags : public PacketParserBase
97     {
98 #       include SENF_FIXED_PARSER()
99
100         SENF_PARSER_SKIP_BITS ( 5                              );
101         SENF_PARSER_BITFIELD  ( txRts,                1, bool  );
102         SENF_PARSER_BITFIELD  ( txCts,                1, bool  );
103         SENF_PARSER_BITFIELD  ( fail,                 1, bool  );
104
105         SENF_PARSER_FINALIZE( RadiotapPacketParser_TxFlags );
106     };
107
108     /** \brief Parse an Radiotap header
109
110         Parser implementing the Radiotap header
111
112         Radiotap requires that all fields in the radiotap header
113         are aligned to natural boundaries. For radiotap,
114         that means all 8-, 16-, 32-, and 64-bit fields
115         must begin on 8-, 16-, 32-, and 64-bit boundaries, respectively.
116         In this way, generators and parsers can avoid unaligned
117         accesses to radiotap capture fields. Radiotap-compliant
118         generators must insert padding before a capture field
119         to ensure its natural alignment.
120
121         \see <a href="http://www.radiotap.org">Radiotap.org</a>
122
123         \todo extended present field (bit 31 of present field is set)
124     */
125     struct RadiotapPacketParser_Header : public PacketParserBase
126     {
127 #       include SENF_FIXED_PARSER()
128
129         /*
130          * mandatory fields
131          */
132         SENF_PARSER_FIELD ( version, UInt8Parser     );
133         //padding bits, currently unused, it simply aligns the fields onto natural word boundaries.
134         SENF_PARSER_SKIP  ( 1                        );
135         SENF_PARSER_FIELD ( length,  UInt16LSBParser );
136
137         SENF_PARSER_PRIVATE_FIELD ( presentFlags, UInt32LSBParser );
138
139         SENF_PARSER_FINALIZE ( RadiotapPacketParser_Header );
140
141         enum PresentIndex {
142             // Could use the the entries from radiotap.h but I don't know,
143             // if I want to pollute the global and macro namespace even more ...
144             TSFT_INDEX              =  0,
145             FLAGS_INDEX             =  1,
146             RATE_INDEX              =  2,
147             CHANNEL_INDEX           =  3,
148             FHSS_INDEX              =  4,
149             DBM_ANTSIGNAL_INDEX     =  5,
150             DBM_ANTNOISE_INDEX      =  6,
151             LOCK_QUALITY_INDEX      =  7,
152             TX_ATTENUATION_INDEX    =  8,
153             DB_TX_ATTENUATION_INDEX =  9,
154             DBM_TX_POWER_INDEX      = 10,
155             ANTENNA_INDEX           = 11,
156             DB_ANTSIGNAL_INDEX      = 12,
157             DB_ANTNOISE_INDEX       = 13,
158             RX_FLAGS_INDEX          = 14,
159             TX_FLAGS_INDEX          = 15,
160             RTS_RETRIES_INDEX       = 16,
161             DATA_RETRIES_INDEX      = 17,
162
163             MAX_INDEX               = 17,
164
165             RADIOTOP_NS_INDEX       = 29,
166             VENDOR_NS_INDEX         = 30,
167             EXTENDED_BITMASK_INDEX  = 31
168         };
169
170         enum PresentFlag {
171             TSFT_FLAG               = (1<<TSFT_INDEX),
172             FLAGS_FLAG              = (1<<FLAGS_INDEX),
173             RATE_FLAG               = (1<<RATE_INDEX),
174             CHANNEL_FLAG            = (1<<CHANNEL_INDEX),
175             FHSS_FLAG               = (1<<FHSS_INDEX),
176             DBM_ANTSIGNAL_FLAG      = (1<<DBM_ANTSIGNAL_INDEX),
177             DBM_ANTNOISE_FLAG       = (1<<DBM_ANTNOISE_INDEX),
178             LOCK_QUALITY_FLAG       = (1<<LOCK_QUALITY_INDEX),
179             TX_ATTENUATION_FLAG     = (1<<TX_ATTENUATION_INDEX),
180             DB_TX_ATTENUATION_FLAG  = (1<<DB_TX_ATTENUATION_INDEX),
181             DBM_TX_POWER_FLAG       = (1<<DBM_TX_POWER_INDEX),
182             ANTENNA_FLAG            = (1<<ANTENNA_INDEX),
183             DB_ANTSIGNAL_FLAG       = (1<<DB_ANTSIGNAL_INDEX),
184             DB_ANTNOISE_FLAG        = (1<<DB_ANTNOISE_INDEX),
185             RX_FLAGS_FLAG           = (1<<RX_FLAGS_INDEX),
186             TX_FLAGS_FLAG           = (1<<TX_FLAGS_INDEX),
187             RTS_RETRIES_FLAG        = (1<<RTS_RETRIES_INDEX),
188             DATA_RETRIES_FLAG       = (1<<DATA_RETRIES_INDEX),
189
190             RADIOTOP_NS_FLAG        = (1<<RADIOTOP_NS_INDEX),
191             VENDOR_NS_FLAG          = (1<<VENDOR_NS_INDEX),
192             EXTENDED_BITMASK_FLAG   = (1<<EXTENDED_BITMASK_INDEX)
193         };
194
195         static unsigned const FIELD_SIZE[MAX_INDEX+2];
196     };
197
198     struct RadiotapPacketParser_FrameType : public PacketParserBase
199     {
200 #       include SENF_FIXED_PARSER()
201
202         SENF_PARSER_SKIP_BITS(4);
203         SENF_PARSER_BITFIELD_RO( frameType, 2, unsigned );
204         SENF_PARSER_SKIP_BITS(2);
205
206         SENF_PARSER_FINALIZE(RadiotapPacketParser_FrameType);
207     };
208
209     struct RadiotapPacketParser : public RadiotapPacketParser_Header
210     {
211         RadiotapPacketParser(data_iterator i, state_type s);
212
213         static const size_type init_bytes = RadiotapPacketParser_Header::fixed_bytes;
214
215         size_type bytes() const;
216
217         // ////////////////////////////////////////////////////////////////////////
218
219 #       define FIELD(name,type,index)                                   \
220             typedef type name ## _t;                                    \
221             type name() { return parseField<type>(index); }             \
222             bool has_ ## name() { return currentTable()[index]; }       \
223             bool name ## Present() { return has_ ## name(); }           \
224             type init_ ## name() { initField(index); return name(); }   \
225             void disable_ ## name() { disableField(index); }
226
227         FIELD( tsft,              UInt64LSBParser,                      TSFT_INDEX              );
228
229         // flags is special: disabling 'flags' must also disable the 'fcs' field
230         typedef RadiotapPacketParser_Flags flags_t;
231         flags_t flags() { return parseField<flags_t>(FLAGS_INDEX); }
232         bool has_flags() { return currentTable()[FLAGS_INDEX]; }
233         bool flagsPresent() { return has_flags(); }
234         flags_t init_flags() { initField(FLAGS_INDEX); return flags(); }
235         void disable_flags() { disable_fcs(); disableField(FLAGS_INDEX); }
236
237         FIELD( rate,              UInt8Parser,                          RATE_INDEX              );
238         FIELD( channelOptions,    RadiotapPacketParser_ChannelOptions,  CHANNEL_INDEX           );
239         FIELD( fhss,              UInt16LSBParser,                      FHSS_INDEX              );
240         FIELD( dbmAntennaSignal,  Int8Parser,                           DBM_ANTSIGNAL_INDEX     );
241         FIELD( dbmAntennaNoise,   Int8Parser,                           DBM_ANTNOISE_INDEX      );
242         FIELD( lockQuality,       UInt16LSBParser,                      LOCK_QUALITY_INDEX      );
243         FIELD( txAttenuation,     UInt16LSBParser,                      TX_ATTENUATION_INDEX    );
244         FIELD( dbTxAttenuation,   UInt16LSBParser,                      DB_TX_ATTENUATION_INDEX );
245         FIELD( dbmTxAttenuation,  Int8Parser,                           DBM_TX_POWER_INDEX      );
246         FIELD( antenna,           UInt8Parser,                          ANTENNA_INDEX           );
247         FIELD( dbAntennaSignal,   UInt8Parser,                          DB_ANTSIGNAL_INDEX      );
248         FIELD( dbAntennaNoise,    UInt8Parser,                          DB_ANTNOISE_INDEX       );
249         FIELD( rxFlags,           RadiotapPacketParser_RxFlags,         RX_FLAGS_INDEX          );
250         FIELD( txFlags,           RadiotapPacketParser_TxFlags,         TX_FLAGS_INDEX          );
251         FIELD( rtsRetries,        UInt8Parser,                          RTS_RETRIES_INDEX       );
252         FIELD( dataRetries,       UInt8Parser,                          DATA_RETRIES_INDEX      );
253
254 #       undef FIELD
255
256         typedef UInt32Parser fcs_t;
257         UInt32Parser fcs();
258         bool has_fcs();
259         UInt32Parser init_fcs();
260         void disable_fcs();
261
262         unsigned frameType();
263
264     private:
265         static const size_type fixed_bytes = 0; // hide this member, just in case
266
267         typedef boost::array<size_type,MAX_INDEX+2> OffsetTable;
268
269         ///////////////////////////////////////////////////////////////////////////
270         // Offset table handling
271
272         static OffsetTable & offsetTable(boost::uint32_t presentFlags);
273         // Fills the offset table based on a packet
274         static void parseOffsetTable(boost::uint8_t * data, int maxLength, OffsetTable & table);
275         // Generate an offset table just from the present flags
276         static void buildOffsetTable(boost::uint32_t presentFlags, OffsetTable & table);
277
278         ///////////////////////////////////////////////////////////////////////////
279
280         OffsetTable const & currentTable() const;
281         OffsetTable const & getTable(boost::uint32_t presentFlags) const;
282
283         template <class Parser>
284         Parser parseField(unsigned index);
285         void initField(unsigned index);
286         void disableField(unsigned index);
287
288         size_type calculateSize() const;
289
290         void updatePresentFlags(boost::uint32_t flags);
291         void insertRemoveBytes(unsigned from, unsigned to, int bytes);
292
293         OffsetTable const * currentTable_;
294
295         friend class RadiotapPacketType;
296     };
297
298     /** \brief Radiotap packet
299
300         \par Packet type (typedef):
301             \ref RadiotapPacket
302
303         \par Fields:
304             \ref RadiotapPacketParser
305             \image html RadiotapPacket.png
306
307         \see http://www.radiotap.org/
308
309         \ingroup protocolbundle_80211
310      */
311     struct RadiotapPacketType
312         : public PacketTypeBase,
313           public PacketTypeMixin<RadiotapPacketType>
314     {
315         typedef PacketTypeMixin<RadiotapPacketType> mixin;
316         typedef ConcretePacket<RadiotapPacketType> packet;
317         typedef RadiotapPacketParser parser;
318
319         using mixin::init;
320         using mixin::initSize;
321
322         static void dump(packet p, std::ostream &os);
323         static void finalize(packet p);
324         static factory_t nextPacketType(packet p);
325         static optional_range nextPacketRange(packet p);
326     };
327
328     typedef ConcretePacket<RadiotapPacketType> RadiotapPacket;
329 }
330
331 ///////////////////////////////hh.e////////////////////////////////////////
332 #include "RadiotapPacket.cci"
333 //#include "RadiotapPacket.ct"
334 #include "RadiotapPacket.cti"
335 #endif
336
337 \f
338 // Local Variables:
339 // mode: c++
340 // fill-column: 100
341 // comment-column: 40
342 // c-file-style: "senf"
343 // indent-tabs-mode: nil
344 // ispell-local-dictionary: "american"
345 // compile-command: "scons -u test"
346 // End: