4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Christian Niephaus <cni@berlios.de>
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.
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.
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.
24 \brief Radiotap header */
26 #ifndef HH_SENF_Packets_80211Bundle_RadiotapPacket_
27 #define HH_SENF_Packets_80211Bundle_RadiotapPacket_ 1
30 #include <senf/Packets/Packets.hh>
31 #include <boost/array.hpp>
33 ///////////////////////////////hh.p////////////////////////////////////////
36 /** \brief Parse Flag field in Radiotap header
38 <b>Re-ordering of bits due to LSB byte order</b>
40 struct RadiotapPacketParser_Flags : public PacketParserBase
42 # include SENF_FIXED_PARSER()
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 );
53 SENF_PARSER_FINALIZE ( RadiotapPacketParser_Flags );
55 friend class RadiotapPacketParser;
58 /** \brief Parse in Radiotap Header channel frequency and flag field
60 <b>Re-ordering of bits due to LSB byte order</b>
62 struct RadiotapPacketParser_ChannelOptions : public PacketParserBase
64 # include SENF_FIXED_PARSER()
66 SENF_PARSER_FIELD ( freq, UInt16LSBParser );
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 );
82 SENF_PARSER_FINALIZE ( RadiotapPacketParser_ChannelOptions );
85 struct RadiotapPacketParser_RxFlags : public PacketParserBase
87 # include SENF_FIXED_PARSER()
89 SENF_PARSER_SKIP_BITS ( 6 );
90 SENF_PARSER_BITFIELD ( badPlcp, 1, bool );
91 SENF_PARSER_SKIP_BITS ( 1 );
93 SENF_PARSER_FINALIZE( RadiotapPacketParser_RxFlags );
96 struct RadiotapPacketParser_TxFlags : public PacketParserBase
98 # include SENF_FIXED_PARSER()
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 );
105 SENF_PARSER_FINALIZE( RadiotapPacketParser_TxFlags );
108 /** \brief Parse an Radiotap header
110 Parser implementing the Radiotap header
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.
121 \see <a href="http://www.radiotap.org">Radiotap.org</a>
123 \todo extended present field (bit 31 of present field is set)
125 struct RadiotapPacketParser_Header : public PacketParserBase
127 # include SENF_FIXED_PARSER()
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 );
137 SENF_PARSER_PRIVATE_FIELD ( presentFlags, UInt32LSBParser );
138 SENF_PARSER_GOTO( presentFlags );
140 // present flags indicate which data fields are contained in the packet
141 // BEWARE: LSB-first bit-order !!
144 SENF_PARSER_BITFIELD_RO ( lockQualityPresent, 1, bool );
145 SENF_PARSER_BITFIELD_RO ( dbmAntennaNoisePresent, 1, bool );
146 SENF_PARSER_BITFIELD_RO ( dbmAntennaSignalPresent, 1, bool );
147 SENF_PARSER_BITFIELD_RO ( fhssPresent, 1, bool );
148 SENF_PARSER_BITFIELD_RO ( channelOptionsPresent, 1, bool );
149 SENF_PARSER_BITFIELD_RO ( ratePresent, 1, bool );
150 SENF_PARSER_BITFIELD_RO ( flagsPresent, 1, bool );
151 SENF_PARSER_BITFIELD_RO ( tsftPresent, 1, bool );
154 SENF_PARSER_BITFIELD_RO ( txFlagsPresent, 1, bool );
155 SENF_PARSER_BITFIELD_RO ( rxFlagsPresent, 1, bool );
156 SENF_PARSER_BITFIELD_RO ( dbAntennaNoisePresent, 1, bool );
157 SENF_PARSER_BITFIELD_RO ( dbAntennaSignalPresent, 1, bool );
158 SENF_PARSER_BITFIELD_RO ( antennaPresent, 1, bool );
159 SENF_PARSER_BITFIELD_RO ( dbmTxAttenuationPresent, 1, bool );
160 SENF_PARSER_BITFIELD_RO ( dbTxAttenuationPresent, 1, bool );
161 SENF_PARSER_BITFIELD_RO ( txAttenuationPresent, 1, bool );
164 SENF_PARSER_SKIP_BITS ( 6 );
165 SENF_PARSER_BITFIELD_RO ( dataRetriesPresent, 1, bool );
166 SENF_PARSER_BITFIELD_RO ( rtsRetriesPresent, 1, bool );
169 SENF_PARSER_BITFIELD_RO ( extendedBitmaskPresent, 1, bool );
170 SENF_PARSER_BITFIELD_RO ( vendorNamespacePresent, 1, bool );
171 SENF_PARSER_BITFIELD_RO ( resetRadiotapNamespace, 1, bool )
172 SENF_PARSER_SKIP_BITS ( 5 );
174 SENF_PARSER_FINALIZE ( RadiotapPacketParser_Header );
177 // Could use the the entries from radiotap.h but I don't know,
178 // if I want to pollute the global and macro namespace even more ...
184 DBM_ANTSIGNAL_INDEX = 5,
185 DBM_ANTNOISE_INDEX = 6,
186 LOCK_QUALITY_INDEX = 7,
187 TX_ATTENUATION_INDEX = 8,
188 DB_TX_ATTENUATION_INDEX = 9,
189 DBM_TX_POWER_INDEX = 10,
191 DB_ANTSIGNAL_INDEX = 12,
192 DB_ANTNOISE_INDEX = 13,
195 RTS_RETRIES_INDEX = 16,
196 DATA_RETRIES_INDEX = 17,
202 TSFT_FLAG = (1<<TSFT_INDEX),
203 FLAGS_FLAG = (1<<FLAGS_INDEX),
204 RATE_FLAG = (1<<RATE_INDEX),
205 CHANNEL_FLAG = (1<<CHANNEL_INDEX),
206 FHSS_FLAG = (1<<FHSS_INDEX),
207 DBM_ANTSIGNAL_FLAG = (1<<DBM_ANTSIGNAL_INDEX),
208 DBM_ANTNOISE_FLAG = (1<<DBM_ANTNOISE_INDEX),
209 LOCK_QUALITY_FLAG = (1<<LOCK_QUALITY_INDEX),
210 TX_ATTENUATION_FLAG = (1<<TX_ATTENUATION_INDEX),
211 DB_TX_ATTENUATION_FLAG = (1<<DB_TX_ATTENUATION_INDEX),
212 DBM_TX_POWER_FLAG = (1<<DBM_TX_POWER_INDEX),
213 ANTENNA_FLAG = (1<<ANTENNA_INDEX),
214 DB_ANTSIGNAL_FLAG = (1<<DB_ANTSIGNAL_INDEX),
215 DB_ANTNOISE_FLAG = (1<<DB_ANTNOISE_INDEX),
216 RX_FLAGS_FLAG = (1<<RX_FLAGS_INDEX),
217 TX_FLAGS_FLAG = (1<<TX_FLAGS_INDEX),
218 RTS_RETRIES_FLAG = (1<<RTS_RETRIES_INDEX),
219 DATA_RETRIES_FLAG = (1<<DATA_RETRIES_INDEX)
222 static unsigned const FIELD_SIZE[MAX_INDEX+2];
225 struct RadiotapPacketParser_FrameType : public PacketParserBase
227 # include SENF_FIXED_PARSER()
229 SENF_PARSER_SKIP_BITS(4);
230 SENF_PARSER_BITFIELD_RO( frameType, 2, unsigned );
231 SENF_PARSER_SKIP_BITS(2);
233 SENF_PARSER_FINALIZE(RadiotapPacketParser_FrameType);
236 struct RadiotapPacketParser : public RadiotapPacketParser_Header
238 RadiotapPacketParser(data_iterator i, state_type s);
240 static const size_type init_bytes = RadiotapPacketParser_Header::fixed_bytes;
242 size_type bytes() const;
244 // ////////////////////////////////////////////////////////////////////////
246 # define FIELD(name,type,index) \
247 typedef type name ## _t; \
248 type name() { return parseField<type>(index); } \
249 bool has_ ## name() { return name ## Present(); } \
250 type init_ ## name() { initField(index); return name(); } \
251 void disable_ ## name() { disableField(index); }
253 FIELD( tsft, UInt64LSBParser, TSFT_INDEX );
255 // flags is special: disabling 'flags' must also disable the 'fcs' field
256 typedef RadiotapPacketParser_Flags flags_t;
257 flags_t flags() { return parseField<flags_t>(FLAGS_INDEX); }
258 bool has_flags() { return flagsPresent(); }
259 flags_t init_flags() { initField(FLAGS_INDEX); return flags(); }
260 void disable_flags() { disable_fcs(); disableField(FLAGS_INDEX); }
262 FIELD( rate, UInt8Parser, RATE_INDEX );
263 FIELD( channelOptions, RadiotapPacketParser_ChannelOptions, CHANNEL_INDEX );
264 FIELD( fhss, UInt16LSBParser, FHSS_INDEX );
265 FIELD( dbmAntennaSignal, Int8Parser, DBM_ANTSIGNAL_INDEX );
266 FIELD( dbmAntennaNoise, Int8Parser, DBM_ANTNOISE_INDEX );
267 FIELD( lockQuality, UInt16LSBParser, LOCK_QUALITY_INDEX );
268 FIELD( txAttenuation, UInt16LSBParser, TX_ATTENUATION_INDEX );
269 FIELD( dbTxAttenuation, UInt16LSBParser, DB_TX_ATTENUATION_INDEX );
270 FIELD( dbmTxAttenuation, Int8Parser, DBM_TX_POWER_INDEX );
271 FIELD( antenna, UInt8Parser, ANTENNA_INDEX );
272 FIELD( dbAntennaSignal, UInt8Parser, DB_ANTSIGNAL_INDEX );
273 FIELD( dbAntennaNoise, UInt8Parser, DB_ANTNOISE_INDEX );
274 FIELD( rxFlags, RadiotapPacketParser_RxFlags, RX_FLAGS_INDEX );
275 FIELD( txFlags, RadiotapPacketParser_TxFlags, TX_FLAGS_INDEX );
276 FIELD( rtsRetries, UInt8Parser, RTS_RETRIES_INDEX );
277 FIELD( dataRetries, UInt8Parser, DATA_RETRIES_INDEX );
281 typedef UInt32Parser fcs_t;
284 UInt32Parser init_fcs();
287 unsigned frameType();
290 static const size_type fixed_bytes = 0; // hide this member, just in case
292 typedef boost::array<size_type,MAX_INDEX+2> OffsetTable;
294 ///////////////////////////////////////////////////////////////////////////
295 // Offset table handling
297 static OffsetTable & offsetTable(boost::uint32_t presentFlags);
298 // Fills the offset table based on a packet
299 static void parseOffsetTable(boost::uint8_t * data, int maxLength, OffsetTable & table);
300 // Generate an offset table just from the present flags
301 static void buildOffsetTable(boost::uint32_t presentFlags, OffsetTable & table);
303 ///////////////////////////////////////////////////////////////////////////
305 OffsetTable const & currentTable() const;
306 OffsetTable const & getTable(boost::uint32_t presentFlags) const;
308 template <class Parser>
309 Parser parseField(unsigned index);
310 void initField(unsigned index);
311 void disableField(unsigned index);
313 size_type calculateSize() const;
315 void updatePresentFlags(boost::uint32_t flags);
316 void insertRemoveBytes(unsigned from, unsigned to, int bytes);
318 friend class RadiotapPacketType;
321 /** \brief Radiotap packet
323 \par Packet type (typedef):
327 \ref RadiotapPacketParser
328 \image html RadiotapPacket.png
330 \see http://www.radiotap.org/
332 \ingroup protocolbundle_80211
334 struct RadiotapPacketType
335 : public PacketTypeBase,
336 public PacketTypeMixin<RadiotapPacketType>
338 typedef PacketTypeMixin<RadiotapPacketType> mixin;
339 typedef ConcretePacket<RadiotapPacketType> packet;
340 typedef RadiotapPacketParser parser;
343 using mixin::initSize;
345 static void dump(packet p, std::ostream &os);
346 static void finalize(packet p);
347 static factory_t nextPacketType(packet p);
348 static optional_range nextPacketRange(packet p);
351 typedef ConcretePacket<RadiotapPacketType> RadiotapPacket;
354 ///////////////////////////////hh.e////////////////////////////////////////
355 #include "RadiotapPacket.cci"
356 //#include "RadiotapPacket.ct"
357 #include "RadiotapPacket.cti"
364 // comment-column: 40
365 // c-file-style: "senf"
366 // indent-tabs-mode: nil
367 // ispell-local-dictionary: "american"
368 // compile-command: "scons -u test"