00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "RadiotapPacket.hh"
00027
00028
00029
00030 #include "WLANPacket.hh"
00031 #include <boost/io/ios_state.hpp>
00032 #include <memory.h>
00033
00034 extern "C" {
00035 # include "radiotap/radiotap_iter.h"
00036 }
00037
00038 #define prefix_
00039
00040
00041
00042
00043
00044 prefix_ senf::RadiotapPacketParser::OffsetTable &
00045 senf::RadiotapPacketParser::offsetTable(boost::uint32_t presentFlags)
00046 {
00047 typedef std::map<boost::uint32_t, OffsetTable> OffsetMap;
00048 static OffsetMap offsetMap;
00049
00050 OffsetMap::iterator i (offsetMap.find(presentFlags));
00051 if (i == offsetMap.end())
00052 i = offsetMap.insert(std::make_pair(presentFlags, OffsetTable())).first;
00053 return i->second;
00054 }
00055
00056 prefix_ void senf::RadiotapPacketParser::parseOffsetTable(boost::uint8_t * data, int maxLength,
00057 OffsetTable & table)
00058 {
00059 struct ieee80211_radiotap_iterator iter;
00060 ieee80211_radiotap_iterator_init(&iter,
00061 (struct ieee80211_radiotap_header *)data,
00062 maxLength,
00063 0);
00064 unsigned size (8u);
00065 while (ieee80211_radiotap_iterator_next(&iter) == 0) {
00066 if (iter.is_radiotap_ns &&
00067 iter.this_arg_index <= int(RadiotapPacketParser::MAX_INDEX))
00068 table[iter.this_arg_index] = iter.this_arg - data;
00069
00070
00071 size = iter.this_arg - data + iter.this_arg_size;
00072 }
00073 table[MAX_INDEX+1] = size;
00074 }
00075
00076 prefix_ void senf::RadiotapPacketParser::buildOffsetTable(boost::uint32_t presentFlags,
00077 OffsetTable & table)
00078 {
00079 SENF_ASSERT(!(presentFlags & ( (1<<IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE) |
00080 (1<<IEEE80211_RADIOTAP_VENDOR_NAMESPACE) |
00081 (1<<IEEE80211_RADIOTAP_EXT) )),
00082 "Extended or vendor fields not supported");
00083
00084 struct ieee80211_radiotap_header header;
00085 memset(&header, 0, sizeof(header));
00086
00087
00088
00089
00090
00091 header.it_len = 0xFFFF;
00092 header.it_present = presentFlags;
00093
00094 parseOffsetTable((boost::uint8_t*)&header, header.it_len, table);
00095 }
00096
00097
00098
00099
00100 unsigned const senf::RadiotapPacketParser_Header::FIELD_SIZE[] = {
00101 8, 1, 1, 4, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1 };
00102
00103 prefix_ senf::UInt32Parser senf::RadiotapPacketParser::init_fcs()
00104 {
00105 if (!has_fcs()) {
00106 protect(), data().insert(data().end(), 4u, 0u);
00107 init_flags().fcsAtEnd_() = true;
00108 }
00109 return fcs();
00110 }
00111
00112 prefix_ void senf::RadiotapPacketParser::disable_fcs()
00113 {
00114 if (has_fcs()) {
00115 validate(RadiotapPacketParser_Header::fixed_bytes+4);
00116 data().erase(data().end()-4, data().end());
00117 flags().fcsAtEnd_() = false;
00118 }
00119 }
00120
00121 prefix_ senf::RadiotapPacketParser::OffsetTable const &
00122 senf::RadiotapPacketParser::getTable(boost::uint32_t presentFlags)
00123 const
00124 {
00125 OffsetTable & table(offsetTable(presentFlags));
00126 if (! table[MAX_INDEX+1])
00127 buildOffsetTable(presentFlags, table);
00128 return table;
00129 }
00130
00131 prefix_ void senf::RadiotapPacketParser::insertRemoveBytes(unsigned from , unsigned to, int bytes)
00132 {
00133 data_iterator b (i() + from);
00134 data_iterator e (i() + to);
00135 if (bytes >= 0) {
00136
00137 std::fill(b, e, 0u);
00138 if (bytes > 0)
00139
00140 protect(), data().insert(e, bytes, 0u);
00141 }
00142 else {
00143
00144
00145 if (b < e + bytes)
00146 std::fill(b, e + bytes, 0u);
00147 data().erase(e + bytes, e);
00148 }
00149 }
00150
00151 prefix_ void senf::RadiotapPacketParser::updatePresentFlags(boost::uint32_t flags)
00152 {
00153 if (flags == presentFlags())
00154 return;
00155 validate(bytes());
00156
00157 OffsetTable const & oldTable (currentTable());
00158 OffsetTable const & newTable (getTable(flags));
00159 unsigned b (RadiotapPacketParser_Header::fixed_bytes);
00160 int cumulativeNewBytes (0);
00161
00162 for (unsigned index (0); index <= MAX_INDEX; ++index) {
00163
00164 for (; index <= MAX_INDEX+1
00165 && ((oldTable[index] == 0 && newTable[index] == 0)
00166 || (oldTable[index]+cumulativeNewBytes == newTable[index])); ++index)
00167 if (newTable[index] != 0)
00168 b = newTable[index] + FIELD_SIZE[index];
00169 if (index > MAX_INDEX+1)
00170 break;
00171
00172
00173
00174 for (; ! (oldTable[index]!=0 && newTable[index]!=0); ++index) ;
00175
00176
00177
00178
00179
00180
00181
00182 int newBytes (newTable[index] - oldTable[index] - cumulativeNewBytes);
00183 insertRemoveBytes(b, oldTable[index] + cumulativeNewBytes, newBytes);
00184 cumulativeNewBytes += newBytes;
00185 b = newTable[index] + FIELD_SIZE[index];
00186 }
00187 length() += cumulativeNewBytes;
00188 presentFlags() = flags;
00189 currentTable_ = &newTable;
00190 }
00191
00192
00193
00194
00195 prefix_ void senf::RadiotapPacketType::dump(packet p, std::ostream & os)
00196 {
00197 boost::io::ios_all_saver ias(os);
00198 os << "Radiotap:\n"
00199 << senf::fieldName("version") << unsigned(p->version()) << '\n'
00200 << senf::fieldName("length") << unsigned(p->length()) << '\n';
00201
00202 # define FIELD(name, sign, desc) \
00203 if (p->name ## Present()) \
00204 os << senf::fieldName(desc) << sign(p->name()) << '\n';
00205
00206 # define ENTER(name) \
00207 if (p->name ## Present()) { \
00208 packet::Parser::name ## _t subparser (p->name());
00209
00210 # define SUBFIELD(name, sign, desc) \
00211 os << senf::fieldName(desc) << sign(subparser.name()) << '\n';
00212
00213 # define LEAVE() \
00214 }
00215
00216 # define START_FLAGS(desc) \
00217 os << senf::fieldName(desc);
00218
00219 # define FLAG(name, desc) \
00220 if (subparser.name()) os << desc " "
00221
00222 # define END_FLAGS() \
00223 os << '\n';
00224
00225 FIELD ( tsft, boost::uint64_t, "MAC timestamp" );
00226 ENTER ( flags );
00227 START_FLAGS ( "flags" );
00228 FLAG ( shortGI, "ShortGI" );
00229 FLAG ( badFCS, "BadFCS" );
00230 FLAG ( fcsAtEnd, "FCSatEnd" );
00231 FLAG ( fragmentation, "Frag" );
00232 FLAG ( wep, "WEP" );
00233 FLAG ( shortPreamble, "ShortPreamble" );
00234 FLAG ( cfp, "CFP" );
00235 END_FLAGS ( );
00236 LEAVE ( );
00237 FIELD ( rate, unsigned, "rate" );
00238 ENTER ( channelOptions );
00239 SUBFIELD ( freq, unsigned, "channel frequency" );
00240 START_FLAGS ( "channel flags" );
00241 FLAG ( flag2ghz, "2GHz" );
00242 FLAG ( ofdm, "OFDM" );
00243 FLAG ( cck, "CCK" );
00244 FLAG ( turbo, "Turbo" );
00245 FLAG ( quarterRateChannel, "Rate/4" );
00246 FLAG ( halfRateChannel, "Rate/2" );
00247 FLAG ( gsm, "GSM" );
00248 FLAG ( staticTurbo, "StaticTurbo" );
00249 FLAG ( gfsk, "GFSK" );
00250 FLAG ( cckOfdm, "CCK+OFDM" );
00251 FLAG ( passive, "Passive" );
00252 FLAG ( flag5ghz, "5GHz" );
00253 END_FLAGS ( );
00254 LEAVE ( );
00255 FIELD ( fhss, unsigned, "FHSS" );
00256 FIELD ( dbmAntennaSignal, signed, "antenna signal (dBm)" );
00257 FIELD ( dbmAntennaNoise, signed, "antenna noise (dBm)" );
00258 FIELD ( lockQuality, unsigned, "lock quality" );
00259 FIELD ( txAttenuation, unsigned, "tx attenuation" );
00260 FIELD ( dbTxAttenuation, unsigned, "tx attenuation (dB)" );
00261 FIELD ( dbmTxAttenuation, signed, "tx attenuation (dBm)" );
00262 FIELD ( antenna, unsigned, "antenna" );
00263 FIELD ( dbAntennaSignal, unsigned, "antenna signal (dB)" );
00264 FIELD ( dbAntennaNoise, unsigned, "antenna noise (dB)" );
00265 ENTER ( rxFlags );
00266 START_FLAGS ( "rx flags" );
00267 FLAG ( badPlcp, "BadPLCP" );
00268 END_FLAGS ( );
00269 LEAVE ( );
00270 ENTER ( txFlags );
00271 START_FLAGS ( "tx flags" );
00272 FLAG ( fail, "Fail" );
00273 FLAG ( txRts, "RTS" );
00274 FLAG ( txCts, "CTS" );
00275 END_FLAGS ( );
00276 LEAVE ( );
00277 FIELD ( rtsRetries, unsigned, "rts retries" );
00278 FIELD ( dataRetries, unsigned, "data retries" );
00279
00280 if (p->flagsPresent() && p->flags().fcsAtEnd())
00281 os << senf::fieldName("fcs") << unsigned(p->fcs()) << '\n';
00282
00283 # undef END_FLAGS
00284 # undef FLAG
00285 # undef START_FLAGS
00286 # undef LEAVE
00287 # undef SUBFIELD
00288 # undef ENTER
00289 # undef FIELD
00290 }
00291
00292 prefix_ void senf::RadiotapPacketType::init(packet p)
00293 {
00294
00295
00296 p->length() << RadiotapPacketParser_Header::fixed_bytes+0;
00297 }
00298
00299 prefix_ senf::PacketInterpreterBase::factory_t senf::RadiotapPacketType::nextPacketType(packet p)
00300 {
00301 static factory_t frameTypeFactory[] = { WLANPacket_MgtFrame::factory(),
00302 WLANPacket_CtrlFrame::factory(),
00303 WLANPacket_DataFrame::factory(),
00304 no_factory() };
00305 return frameTypeFactory[p->frameType()];
00306 }
00307
00308 prefix_ senf::RadiotapPacketType::optional_range
00309 senf::RadiotapPacketType::nextPacketRange(packet p)
00310 {
00311 parser rtParser (p.parser());
00312 size_type h (senf::bytes(rtParser));
00313 size_type t (rtParser.flagsPresent() && rtParser.flags().fcsAtEnd() ? 4 : 0);
00314 return p.size() <= h+t
00315 ? no_range()
00316 : optional_range( range(p.data().begin() + h, p.data().end() - t) );
00317 }
00318
00319
00320 #undef prefix_
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331