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 );
139 SENF_PARSER_FINALIZE ( RadiotapPacketParser_Header );
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 ...
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,
156 DB_ANTSIGNAL_INDEX = 12,
157 DB_ANTNOISE_INDEX = 13,
160 RTS_RETRIES_INDEX = 16,
161 DATA_RETRIES_INDEX = 17,
165 RADIOTOP_NS_INDEX = 29,
166 VENDOR_NS_INDEX = 30,
167 EXTENDED_BITMASK_INDEX = 31
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),
190 RADIOTOP_NS_FLAG = (1<<RADIOTOP_NS_INDEX),
191 VENDOR_NS_FLAG = (1<<VENDOR_NS_INDEX),
192 EXTENDED_BITMASK_FLAG = (1<<EXTENDED_BITMASK_INDEX)
195 static unsigned const FIELD_SIZE[MAX_INDEX+2];
198 struct RadiotapPacketParser_FrameType : public PacketParserBase
200 # include SENF_FIXED_PARSER()
202 SENF_PARSER_SKIP_BITS(4);
203 SENF_PARSER_BITFIELD_RO( frameType, 2, unsigned );
204 SENF_PARSER_SKIP_BITS(2);
206 SENF_PARSER_FINALIZE(RadiotapPacketParser_FrameType);
209 struct RadiotapPacketParser : public RadiotapPacketParser_Header
211 RadiotapPacketParser(data_iterator i, state_type s);
213 static const size_type init_bytes = RadiotapPacketParser_Header::fixed_bytes;
215 size_type bytes() const;
217 // ////////////////////////////////////////////////////////////////////////
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); }
227 FIELD( tsft, UInt64LSBParser, TSFT_INDEX );
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); }
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 );
256 typedef UInt32Parser fcs_t;
259 UInt32Parser init_fcs();
262 unsigned frameType();
265 static const size_type fixed_bytes = 0; // hide this member, just in case
267 typedef boost::array<size_type,MAX_INDEX+2> OffsetTable;
269 ///////////////////////////////////////////////////////////////////////////
270 // Offset table handling
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);
278 ///////////////////////////////////////////////////////////////////////////
280 OffsetTable const & currentTable() const;
281 OffsetTable const & getTable(boost::uint32_t presentFlags) const;
283 template <class Parser>
284 Parser parseField(unsigned index);
285 void initField(unsigned index);
286 void disableField(unsigned index);
288 size_type calculateSize() const;
290 void updatePresentFlags(boost::uint32_t flags);
291 void insertRemoveBytes(unsigned from, unsigned to, int bytes);
293 OffsetTable const * currentTable_;
295 friend class RadiotapPacketType;
298 /** \brief Radiotap packet
300 \par Packet type (typedef):
304 \ref RadiotapPacketParser
305 \image html RadiotapPacket.png
307 \see http://www.radiotap.org/
309 \ingroup protocolbundle_80211
311 struct RadiotapPacketType
312 : public PacketTypeBase,
313 public PacketTypeMixin<RadiotapPacketType>
315 typedef PacketTypeMixin<RadiotapPacketType> mixin;
316 typedef ConcretePacket<RadiotapPacketType> packet;
317 typedef RadiotapPacketParser parser;
320 using mixin::initSize;
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);
328 typedef ConcretePacket<RadiotapPacketType> RadiotapPacket;
331 ///////////////////////////////hh.e////////////////////////////////////////
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"