4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Stefan Bund <g0dil@berlios.de>
27 // Christian Niephaus <cni@berlios.de>
30 \brief Radiotap header */
32 #ifndef HH_SENF_Packets_80211Bundle_RadiotapPacket_
33 #define HH_SENF_Packets_80211Bundle_RadiotapPacket_ 1
36 #include <senf/Packets/Packets.hh>
37 #include <boost/array.hpp>
39 //-/////////////////////////////////////////////////////////////////////////////////////////////////
42 /** \brief Parse Flag field in Radiotap header
44 <b>Re-ordering of bits due to LSB byte order</b>
46 struct RadiotapPacketParser_Flags : public PacketParserBase
48 # include SENF_FIXED_PARSER()
50 SENF_PARSER_BITFIELD ( shortGI, 1, bool );
51 SENF_PARSER_BITFIELD ( badFCS, 1, bool );
52 SENF_PARSER_BITFIELD ( padding, 1, bool );
53 SENF_PARSER_BITFIELD_RO ( fcsAtEnd, 1, bool ); // Cannot change this (change packet size)
54 SENF_PARSER_BITFIELD ( fragmentation, 1, bool );
55 SENF_PARSER_BITFIELD ( wep, 1, bool );
56 SENF_PARSER_BITFIELD ( shortPreamble, 1, bool );
57 SENF_PARSER_BITFIELD ( cfp, 1, bool );
59 SENF_PARSER_FINALIZE ( RadiotapPacketParser_Flags );
61 friend struct RadiotapPacketParser;
64 /** \brief Parse in Radiotap Header channel frequency and flag field
66 <b>Re-ordering of bits due to LSB byte order</b>
68 struct RadiotapPacketParser_ChannelOptions : public PacketParserBase
70 # include SENF_FIXED_PARSER()
72 SENF_PARSER_FIELD ( freq, UInt16LSBParser );
74 SENF_PARSER_BITFIELD ( flag2ghz, 1, bool );
75 SENF_PARSER_BITFIELD ( ofdm, 1, bool );
76 SENF_PARSER_BITFIELD ( cck, 1, bool );
77 SENF_PARSER_BITFIELD ( turbo, 1, bool );
78 SENF_PARSER_SKIP_BITS ( 4 );
79 SENF_PARSER_BITFIELD ( quarterRateChannel, 1, bool );
80 SENF_PARSER_BITFIELD ( halfRateChannel, 1, bool );
81 SENF_PARSER_BITFIELD ( gsm, 1, bool );
82 SENF_PARSER_BITFIELD ( staticTurbo, 1, bool );
83 SENF_PARSER_BITFIELD ( gfsk, 1, bool );
84 SENF_PARSER_BITFIELD ( cckOfdm, 1, bool );
85 SENF_PARSER_BITFIELD ( passive, 1, bool );
86 SENF_PARSER_BITFIELD ( flag5ghz, 1, bool );
88 SENF_PARSER_FINALIZE ( RadiotapPacketParser_ChannelOptions );
91 struct RadiotapPacketParser_RxFlags : public PacketParserBase
93 # include SENF_FIXED_PARSER()
95 SENF_PARSER_SKIP_BITS ( 6 );
96 SENF_PARSER_BITFIELD ( badPlcp, 1, bool );
97 SENF_PARSER_SKIP_BITS ( 1 );
99 SENF_PARSER_FINALIZE( RadiotapPacketParser_RxFlags );
102 struct RadiotapPacketParser_TxFlags : public PacketParserBase
104 # include SENF_FIXED_PARSER()
106 SENF_PARSER_SKIP_BITS ( 5 );
107 SENF_PARSER_BITFIELD ( txRts, 1, bool );
108 SENF_PARSER_BITFIELD ( txCts, 1, bool );
109 SENF_PARSER_BITFIELD ( fail, 1, bool );
111 SENF_PARSER_FINALIZE( RadiotapPacketParser_TxFlags );
114 /** \brief Parse an Radiotap header
116 Parser implementing the Radiotap header
118 Radiotap requires that all fields in the radiotap header
119 are aligned to natural boundaries. For radiotap,
120 that means all 8-, 16-, 32-, and 64-bit fields
121 must begin on 8-, 16-, 32-, and 64-bit boundaries, respectively.
122 In this way, generators and parsers can avoid unaligned
123 accesses to radiotap capture fields. Radiotap-compliant
124 generators must insert padding before a capture field
125 to ensure its natural alignment.
127 \see <a href="http://www.radiotap.org">Radiotap.org</a>
129 \todo extended present field (bit 31 of present field is set)
131 struct RadiotapPacketParser_Header : public PacketParserBase
133 # include SENF_FIXED_PARSER()
138 SENF_PARSER_FIELD ( version, UInt8Parser );
139 //padding bits, currently unused, it simply aligns the fields onto natural word boundaries.
140 SENF_PARSER_SKIP ( 1 );
141 SENF_PARSER_FIELD ( length, UInt16LSBParser );
143 SENF_PARSER_PRIVATE_FIELD ( presentFlags, UInt32LSBParser );
145 SENF_PARSER_FINALIZE ( RadiotapPacketParser_Header );
148 // Could use the the entries from radiotap.h but I don't know,
149 // if I want to pollute the global and macro namespace even more ...
155 DBM_ANTSIGNAL_INDEX = 5,
156 DBM_ANTNOISE_INDEX = 6,
157 LOCK_QUALITY_INDEX = 7,
158 TX_ATTENUATION_INDEX = 8,
159 DB_TX_ATTENUATION_INDEX = 9,
160 DBM_TX_POWER_INDEX = 10,
162 DB_ANTSIGNAL_INDEX = 12,
163 DB_ANTNOISE_INDEX = 13,
166 RTS_RETRIES_INDEX = 16,
167 DATA_RETRIES_INDEX = 17,
171 RADIOTOP_NS_INDEX = 29,
172 VENDOR_NS_INDEX = 30,
173 EXTENDED_BITMASK_INDEX = 31
177 TSFT_FLAG = (1<<TSFT_INDEX),
178 FLAGS_FLAG = (1<<FLAGS_INDEX),
179 RATE_FLAG = (1<<RATE_INDEX),
180 CHANNEL_FLAG = (1<<CHANNEL_INDEX),
181 FHSS_FLAG = (1<<FHSS_INDEX),
182 DBM_ANTSIGNAL_FLAG = (1<<DBM_ANTSIGNAL_INDEX),
183 DBM_ANTNOISE_FLAG = (1<<DBM_ANTNOISE_INDEX),
184 LOCK_QUALITY_FLAG = (1<<LOCK_QUALITY_INDEX),
185 TX_ATTENUATION_FLAG = (1<<TX_ATTENUATION_INDEX),
186 DB_TX_ATTENUATION_FLAG = (1<<DB_TX_ATTENUATION_INDEX),
187 DBM_TX_POWER_FLAG = (1<<DBM_TX_POWER_INDEX),
188 ANTENNA_FLAG = (1<<ANTENNA_INDEX),
189 DB_ANTSIGNAL_FLAG = (1<<DB_ANTSIGNAL_INDEX),
190 DB_ANTNOISE_FLAG = (1<<DB_ANTNOISE_INDEX),
191 RX_FLAGS_FLAG = (1<<RX_FLAGS_INDEX),
192 TX_FLAGS_FLAG = (1<<TX_FLAGS_INDEX),
193 RTS_RETRIES_FLAG = (1<<RTS_RETRIES_INDEX),
194 DATA_RETRIES_FLAG = (1<<DATA_RETRIES_INDEX),
196 RADIOTOP_NS_FLAG = (1<<RADIOTOP_NS_INDEX),
197 VENDOR_NS_FLAG = (1<<VENDOR_NS_INDEX),
198 EXTENDED_BITMASK_FLAG = (1<<EXTENDED_BITMASK_INDEX)
201 static unsigned const FIELD_SIZE[MAX_INDEX+2];
204 struct RadiotapPacketParser_FrameType : public PacketParserBase
206 # include SENF_FIXED_PARSER()
208 SENF_PARSER_SKIP_BITS(4);
209 SENF_PARSER_BITFIELD_RO( frameType, 2, unsigned );
210 SENF_PARSER_SKIP_BITS(2);
212 SENF_PARSER_FINALIZE(RadiotapPacketParser_FrameType);
215 struct RadiotapPacketParser : public RadiotapPacketParser_Header
217 RadiotapPacketParser(data_iterator i, state_type s);
219 static const size_type init_bytes = RadiotapPacketParser_Header::fixed_bytes;
221 size_type bytes() const;
223 //-////////////////////////////////////////////////////////////////////////
225 # define FIELD(name,type,index) \
226 typedef type name ## _t; \
227 type name() { return parseField<type>(index); } \
228 bool has_ ## name() { return currentTable()[index]; } \
229 bool name ## Present() { return has_ ## name(); } \
230 type init_ ## name() { initField(index); return name(); } \
231 void disable_ ## name() { disableField(index); }
233 FIELD( tsft, UInt64LSBParser, TSFT_INDEX );
235 // flags is special: disabling 'flags' must also disable the 'fcs' field
236 typedef RadiotapPacketParser_Flags flags_t;
237 flags_t flags() { return parseField<flags_t>(FLAGS_INDEX); }
238 bool has_flags() { return currentTable()[FLAGS_INDEX]; }
239 bool flagsPresent() { return has_flags(); }
240 flags_t init_flags() { initField(FLAGS_INDEX); return flags(); }
241 void disable_flags() { disable_fcs(); disableField(FLAGS_INDEX); }
243 FIELD( rate, UInt8Parser, RATE_INDEX );
244 FIELD( channelOptions, RadiotapPacketParser_ChannelOptions, CHANNEL_INDEX );
245 FIELD( fhss, UInt16LSBParser, FHSS_INDEX );
246 FIELD( dbmAntennaSignal, Int8Parser, DBM_ANTSIGNAL_INDEX );
247 FIELD( dbmAntennaNoise, Int8Parser, DBM_ANTNOISE_INDEX );
248 FIELD( lockQuality, UInt16LSBParser, LOCK_QUALITY_INDEX );
249 FIELD( txAttenuation, UInt16LSBParser, TX_ATTENUATION_INDEX );
250 FIELD( dbTxAttenuation, UInt16LSBParser, DB_TX_ATTENUATION_INDEX );
251 FIELD( dbmTxAttenuation, Int8Parser, DBM_TX_POWER_INDEX );
252 FIELD( antenna, UInt8Parser, ANTENNA_INDEX );
253 FIELD( dbAntennaSignal, UInt8Parser, DB_ANTSIGNAL_INDEX );
254 FIELD( dbAntennaNoise, UInt8Parser, DB_ANTNOISE_INDEX );
255 FIELD( rxFlags, RadiotapPacketParser_RxFlags, RX_FLAGS_INDEX );
256 FIELD( txFlags, RadiotapPacketParser_TxFlags, TX_FLAGS_INDEX );
257 FIELD( rtsRetries, UInt8Parser, RTS_RETRIES_INDEX );
258 FIELD( dataRetries, UInt8Parser, DATA_RETRIES_INDEX );
262 typedef UInt32Parser fcs_t;
265 UInt32Parser init_fcs();
268 unsigned frameType();
271 static const size_type fixed_bytes = 0; // hide this member, just in case
273 typedef boost::array<size_type,MAX_INDEX+2> OffsetTable;
274 typedef std::map<boost::uint32_t, OffsetTable> OffsetMap;
276 //-////////////////////////////////////////////////////////////////////////
277 // Offset table handling
279 static OffsetTable & offsetTable(boost::uint32_t presentFlags);
280 // Fills the offset table based on a packet
281 static void parseOffsetTable(boost::uint8_t * data, int maxLength, OffsetTable & table);
282 // Generate an offset table just from the present flags
283 static void buildOffsetTable(boost::uint32_t presentFlags, OffsetTable & table);
285 //-////////////////////////////////////////////////////////////////////////
287 OffsetTable const & currentTable() const;
288 OffsetTable const & getTable(boost::uint32_t presentFlags) const;
290 template <class Parser>
291 Parser parseField(unsigned index);
292 void initField(unsigned index);
293 void disableField(unsigned index);
295 size_type calculateSize() const;
297 void updatePresentFlags(boost::uint32_t flags);
298 void insertRemoveBytes(unsigned from, unsigned to, int bytes);
300 static OffsetMap offsetMap_;
301 OffsetTable const * currentTable_;
303 friend struct RadiotapPacketType;
306 /** \brief Radiotap packet
308 \par Packet type (typedef):
312 \ref RadiotapPacketParser
313 \image html RadiotapPacket.png
315 \see http://www.radiotap.org/
317 \ingroup protocolbundle_80211
319 struct RadiotapPacketType
320 : public PacketTypeBase,
321 public PacketTypeMixin<RadiotapPacketType>
323 typedef PacketTypeMixin<RadiotapPacketType> mixin;
324 typedef ConcretePacket<RadiotapPacketType> packet;
325 typedef RadiotapPacketParser parser;
327 using mixin::initSize;
329 static void init(packet p);
330 static void dump(packet p, std::ostream & os);
331 static factory_t nextPacketType(packet p);
332 static optional_range nextPacketRange(packet const & p);
335 typedef ConcretePacket<RadiotapPacketType> RadiotapPacket;
338 //-/////////////////////////////////////////////////////////////////////////////////////////////////
339 #include "RadiotapPacket.cci"
340 //#include "RadiotapPacket.ct"
341 #include "RadiotapPacket.cti"
348 // comment-column: 40
349 // c-file-style: "senf"
350 // indent-tabs-mode: nil
351 // ispell-local-dictionary: "american"
352 // compile-command: "scons -u test"