4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Christian Niephaus <cni@berlios.de>
7 // Stefan Bund <g0dil@berlios.de>
9 // This program is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the
21 // Free Software Foundation, Inc.,
22 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 \brief Radiotap header */
27 #ifndef HH_SENF_Packets_80211Bundle_RadiotapPacket_
28 #define HH_SENF_Packets_80211Bundle_RadiotapPacket_ 1
31 #include <senf/Packets/Packets.hh>
32 #include <boost/array.hpp>
34 //-/////////////////////////////////////////////////////////////////////////////////////////////////
37 /** \brief Parse Flag field in Radiotap header
39 <b>Re-ordering of bits due to LSB byte order</b>
41 struct RadiotapPacketParser_Flags : public PacketParserBase
43 # include SENF_FIXED_PARSER()
45 SENF_PARSER_BITFIELD ( shortGI, 1, bool );
46 SENF_PARSER_BITFIELD ( badFCS, 1, bool );
47 SENF_PARSER_BITFIELD ( padding, 1, bool );
48 SENF_PARSER_BITFIELD_RO ( fcsAtEnd, 1, bool ); // Cannot change this (change packet size)
49 SENF_PARSER_BITFIELD ( fragmentation, 1, bool );
50 SENF_PARSER_BITFIELD ( wep, 1, bool );
51 SENF_PARSER_BITFIELD ( shortPreamble, 1, bool );
52 SENF_PARSER_BITFIELD ( cfp, 1, bool );
54 SENF_PARSER_FINALIZE ( RadiotapPacketParser_Flags );
56 friend class RadiotapPacketParser;
59 /** \brief Parse in Radiotap Header channel frequency and flag field
61 <b>Re-ordering of bits due to LSB byte order</b>
63 struct RadiotapPacketParser_ChannelOptions : public PacketParserBase
65 # include SENF_FIXED_PARSER()
67 SENF_PARSER_FIELD ( freq, UInt16LSBParser );
69 SENF_PARSER_BITFIELD ( flag2ghz, 1, bool );
70 SENF_PARSER_BITFIELD ( ofdm, 1, bool );
71 SENF_PARSER_BITFIELD ( cck, 1, bool );
72 SENF_PARSER_BITFIELD ( turbo, 1, bool );
73 SENF_PARSER_SKIP_BITS ( 4 );
74 SENF_PARSER_BITFIELD ( quarterRateChannel, 1, bool );
75 SENF_PARSER_BITFIELD ( halfRateChannel, 1, bool );
76 SENF_PARSER_BITFIELD ( gsm, 1, bool );
77 SENF_PARSER_BITFIELD ( staticTurbo, 1, bool );
78 SENF_PARSER_BITFIELD ( gfsk, 1, bool );
79 SENF_PARSER_BITFIELD ( cckOfdm, 1, bool );
80 SENF_PARSER_BITFIELD ( passive, 1, bool );
81 SENF_PARSER_BITFIELD ( flag5ghz, 1, bool );
83 SENF_PARSER_FINALIZE ( RadiotapPacketParser_ChannelOptions );
86 struct RadiotapPacketParser_RxFlags : public PacketParserBase
88 # include SENF_FIXED_PARSER()
90 SENF_PARSER_SKIP_BITS ( 6 );
91 SENF_PARSER_BITFIELD ( badPlcp, 1, bool );
92 SENF_PARSER_SKIP_BITS ( 1 );
94 SENF_PARSER_FINALIZE( RadiotapPacketParser_RxFlags );
97 struct RadiotapPacketParser_TxFlags : public PacketParserBase
99 # include SENF_FIXED_PARSER()
101 SENF_PARSER_SKIP_BITS ( 5 );
102 SENF_PARSER_BITFIELD ( txRts, 1, bool );
103 SENF_PARSER_BITFIELD ( txCts, 1, bool );
104 SENF_PARSER_BITFIELD ( fail, 1, bool );
106 SENF_PARSER_FINALIZE( RadiotapPacketParser_TxFlags );
109 /** \brief Parse an Radiotap header
111 Parser implementing the Radiotap header
113 Radiotap requires that all fields in the radiotap header
114 are aligned to natural boundaries. For radiotap,
115 that means all 8-, 16-, 32-, and 64-bit fields
116 must begin on 8-, 16-, 32-, and 64-bit boundaries, respectively.
117 In this way, generators and parsers can avoid unaligned
118 accesses to radiotap capture fields. Radiotap-compliant
119 generators must insert padding before a capture field
120 to ensure its natural alignment.
122 \see <a href="http://www.radiotap.org">Radiotap.org</a>
124 \todo extended present field (bit 31 of present field is set)
126 struct RadiotapPacketParser_Header : public PacketParserBase
128 # include SENF_FIXED_PARSER()
133 SENF_PARSER_FIELD ( version, UInt8Parser );
134 //padding bits, currently unused, it simply aligns the fields onto natural word boundaries.
135 SENF_PARSER_SKIP ( 1 );
136 SENF_PARSER_FIELD ( length, UInt16LSBParser );
138 SENF_PARSER_PRIVATE_FIELD ( presentFlags, UInt32LSBParser );
140 SENF_PARSER_FINALIZE ( RadiotapPacketParser_Header );
143 // Could use the the entries from radiotap.h but I don't know,
144 // if I want to pollute the global and macro namespace even more ...
150 DBM_ANTSIGNAL_INDEX = 5,
151 DBM_ANTNOISE_INDEX = 6,
152 LOCK_QUALITY_INDEX = 7,
153 TX_ATTENUATION_INDEX = 8,
154 DB_TX_ATTENUATION_INDEX = 9,
155 DBM_TX_POWER_INDEX = 10,
157 DB_ANTSIGNAL_INDEX = 12,
158 DB_ANTNOISE_INDEX = 13,
161 RTS_RETRIES_INDEX = 16,
162 DATA_RETRIES_INDEX = 17,
166 RADIOTOP_NS_INDEX = 29,
167 VENDOR_NS_INDEX = 30,
168 EXTENDED_BITMASK_INDEX = 31
172 TSFT_FLAG = (1<<TSFT_INDEX),
173 FLAGS_FLAG = (1<<FLAGS_INDEX),
174 RATE_FLAG = (1<<RATE_INDEX),
175 CHANNEL_FLAG = (1<<CHANNEL_INDEX),
176 FHSS_FLAG = (1<<FHSS_INDEX),
177 DBM_ANTSIGNAL_FLAG = (1<<DBM_ANTSIGNAL_INDEX),
178 DBM_ANTNOISE_FLAG = (1<<DBM_ANTNOISE_INDEX),
179 LOCK_QUALITY_FLAG = (1<<LOCK_QUALITY_INDEX),
180 TX_ATTENUATION_FLAG = (1<<TX_ATTENUATION_INDEX),
181 DB_TX_ATTENUATION_FLAG = (1<<DB_TX_ATTENUATION_INDEX),
182 DBM_TX_POWER_FLAG = (1<<DBM_TX_POWER_INDEX),
183 ANTENNA_FLAG = (1<<ANTENNA_INDEX),
184 DB_ANTSIGNAL_FLAG = (1<<DB_ANTSIGNAL_INDEX),
185 DB_ANTNOISE_FLAG = (1<<DB_ANTNOISE_INDEX),
186 RX_FLAGS_FLAG = (1<<RX_FLAGS_INDEX),
187 TX_FLAGS_FLAG = (1<<TX_FLAGS_INDEX),
188 RTS_RETRIES_FLAG = (1<<RTS_RETRIES_INDEX),
189 DATA_RETRIES_FLAG = (1<<DATA_RETRIES_INDEX),
191 RADIOTOP_NS_FLAG = (1<<RADIOTOP_NS_INDEX),
192 VENDOR_NS_FLAG = (1<<VENDOR_NS_INDEX),
193 EXTENDED_BITMASK_FLAG = (1<<EXTENDED_BITMASK_INDEX)
196 static unsigned const FIELD_SIZE[MAX_INDEX+2];
199 struct RadiotapPacketParser_FrameType : public PacketParserBase
201 # include SENF_FIXED_PARSER()
203 SENF_PARSER_SKIP_BITS(4);
204 SENF_PARSER_BITFIELD_RO( frameType, 2, unsigned );
205 SENF_PARSER_SKIP_BITS(2);
207 SENF_PARSER_FINALIZE(RadiotapPacketParser_FrameType);
210 struct RadiotapPacketParser : public RadiotapPacketParser_Header
212 RadiotapPacketParser(data_iterator i, state_type s);
214 static const size_type init_bytes = RadiotapPacketParser_Header::fixed_bytes;
216 size_type bytes() const;
218 //-////////////////////////////////////////////////////////////////////////
220 # define FIELD(name,type,index) \
221 typedef type name ## _t; \
222 type name() { return parseField<type>(index); } \
223 bool has_ ## name() { return currentTable()[index]; } \
224 bool name ## Present() { return has_ ## name(); } \
225 type init_ ## name() { initField(index); return name(); } \
226 void disable_ ## name() { disableField(index); }
228 FIELD( tsft, UInt64LSBParser, TSFT_INDEX );
230 // flags is special: disabling 'flags' must also disable the 'fcs' field
231 typedef RadiotapPacketParser_Flags flags_t;
232 flags_t flags() { return parseField<flags_t>(FLAGS_INDEX); }
233 bool has_flags() { return currentTable()[FLAGS_INDEX]; }
234 bool flagsPresent() { return has_flags(); }
235 flags_t init_flags() { initField(FLAGS_INDEX); return flags(); }
236 void disable_flags() { disable_fcs(); disableField(FLAGS_INDEX); }
238 FIELD( rate, UInt8Parser, RATE_INDEX );
239 FIELD( channelOptions, RadiotapPacketParser_ChannelOptions, CHANNEL_INDEX );
240 FIELD( fhss, UInt16LSBParser, FHSS_INDEX );
241 FIELD( dbmAntennaSignal, Int8Parser, DBM_ANTSIGNAL_INDEX );
242 FIELD( dbmAntennaNoise, Int8Parser, DBM_ANTNOISE_INDEX );
243 FIELD( lockQuality, UInt16LSBParser, LOCK_QUALITY_INDEX );
244 FIELD( txAttenuation, UInt16LSBParser, TX_ATTENUATION_INDEX );
245 FIELD( dbTxAttenuation, UInt16LSBParser, DB_TX_ATTENUATION_INDEX );
246 FIELD( dbmTxAttenuation, Int8Parser, DBM_TX_POWER_INDEX );
247 FIELD( antenna, UInt8Parser, ANTENNA_INDEX );
248 FIELD( dbAntennaSignal, UInt8Parser, DB_ANTSIGNAL_INDEX );
249 FIELD( dbAntennaNoise, UInt8Parser, DB_ANTNOISE_INDEX );
250 FIELD( rxFlags, RadiotapPacketParser_RxFlags, RX_FLAGS_INDEX );
251 FIELD( txFlags, RadiotapPacketParser_TxFlags, TX_FLAGS_INDEX );
252 FIELD( rtsRetries, UInt8Parser, RTS_RETRIES_INDEX );
253 FIELD( dataRetries, UInt8Parser, DATA_RETRIES_INDEX );
257 typedef UInt32Parser fcs_t;
260 UInt32Parser init_fcs();
263 unsigned frameType();
266 static const size_type fixed_bytes = 0; // hide this member, just in case
268 typedef boost::array<size_type,MAX_INDEX+2> OffsetTable;
270 //-////////////////////////////////////////////////////////////////////////
271 // Offset table handling
273 static OffsetTable & offsetTable(boost::uint32_t presentFlags);
274 // Fills the offset table based on a packet
275 static void parseOffsetTable(boost::uint8_t * data, int maxLength, OffsetTable & table);
276 // Generate an offset table just from the present flags
277 static void buildOffsetTable(boost::uint32_t presentFlags, OffsetTable & table);
279 //-////////////////////////////////////////////////////////////////////////
281 OffsetTable const & currentTable() const;
282 OffsetTable const & getTable(boost::uint32_t presentFlags) const;
284 template <class Parser>
285 Parser parseField(unsigned index);
286 void initField(unsigned index);
287 void disableField(unsigned index);
289 size_type calculateSize() const;
291 void updatePresentFlags(boost::uint32_t flags);
292 void insertRemoveBytes(unsigned from, unsigned to, int bytes);
294 OffsetTable const * currentTable_;
296 friend class RadiotapPacketType;
299 /** \brief Radiotap packet
301 \par Packet type (typedef):
305 \ref RadiotapPacketParser
306 \image html RadiotapPacket.png
308 \see http://www.radiotap.org/
310 \ingroup protocolbundle_80211
312 struct RadiotapPacketType
313 : public PacketTypeBase,
314 public PacketTypeMixin<RadiotapPacketType>
316 typedef PacketTypeMixin<RadiotapPacketType> mixin;
317 typedef ConcretePacket<RadiotapPacketType> packet;
318 typedef RadiotapPacketParser parser;
320 using mixin::initSize;
322 static void init(packet p);
323 static void dump(packet p, std::ostream &os);
324 static factory_t nextPacketType(packet p);
325 static optional_range nextPacketRange(packet p);
328 typedef ConcretePacket<RadiotapPacketType> RadiotapPacket;
331 //-/////////////////////////////////////////////////////////////////////////////////////////////////
332 #include "RadiotapPacket.cci"
333 //#include "RadiotapPacket.ct"
334 #include "RadiotapPacket.cti"
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"