| | 6272 | class RadioTapByteField(ByteField): |
|---|
| | 6273 | def __init__(self, name, default, bitset): |
|---|
| | 6274 | ByteField.__init__(self, name, default) |
|---|
| | 6275 | self.bitset = bitset |
|---|
| | 6276 | |
|---|
| | 6277 | def getfield(self, pkt, s): |
|---|
| | 6278 | if pkt[RadioTap].bitmap & (1 << self.bitset): |
|---|
| | 6279 | pkt.l += 1 |
|---|
| | 6280 | return ByteField.getfield(self, pkt, s) |
|---|
| | 6281 | else: |
|---|
| | 6282 | return s,None |
|---|
| | 6283 | |
|---|
| | 6284 | class RadioTapShortField(LEShortField): |
|---|
| | 6285 | def __init__(self, name, default, bitset): |
|---|
| | 6286 | LEShortField.__init__(self, name, default) |
|---|
| | 6287 | self.bitset = bitset |
|---|
| | 6288 | |
|---|
| | 6289 | def getfield(self, pkt, s): |
|---|
| | 6290 | if (pkt.l+1) % 2: |
|---|
| | 6291 | delta=(pkt.l+2)/2*2 - pkt.l - 1 # alignement |
|---|
| | 6292 | pkt.l += delta |
|---|
| | 6293 | s = s[delta:] |
|---|
| | 6294 | if pkt[RadioTap].bitmap & (1 << self.bitset): |
|---|
| | 6295 | pkt.l += 2 |
|---|
| | 6296 | return LEShortField.getfield(self, pkt, s) |
|---|
| | 6297 | else: |
|---|
| | 6298 | return s,None |
|---|
| | 6299 | |
|---|
| | 6300 | _radiotap_channel_type = { |
|---|
| | 6301 | 0x4001: "802.11a", |
|---|
| | 6302 | 0xa000: "802.11b", |
|---|
| | 6303 | 0xc000: "802.11g (pure)", |
|---|
| | 6304 | 0x5001: "802.11a (turbo)", |
|---|
| | 6305 | 0xd000: "802.11g (pure, turbo)", |
|---|
| | 6306 | 0x9004: "802.11g (turbo)", |
|---|
| | 6307 | 0x8008: "FHSS" |
|---|
| | 6308 | } |
|---|
| | 6309 | |
|---|
| | 6310 | class RadioTapChannelField(RadioTapShortField): |
|---|
| | 6311 | def i2repr(self, pkt, val): |
|---|
| | 6312 | if val == 0: |
|---|
| | 6313 | return 'N/A' |
|---|
| | 6314 | else: |
|---|
| | 6315 | return '%d / %0.3f GHz' % ((val-2407)/5.0, val/1000.0) |
|---|
| | 6316 | |
|---|
| | 6317 | class RadioTapChannelTypeField(BitEnumField): |
|---|
| | 6318 | length=16 |
|---|
| | 6319 | def __init__(self, name, default, bitset): |
|---|
| | 6320 | BitEnumField.__init__(self, name, default, self.length, _radiotap_channel_type) |
|---|
| | 6321 | self.bitset = bitset |
|---|
| | 6322 | |
|---|
| | 6323 | def getfield(self, pkt, s): |
|---|
| | 6324 | if pkt[RadioTap].bitmap & (1 << self.bitset): |
|---|
| | 6325 | pkt.l += self.length/8 |
|---|
| | 6326 | return BitEnumField.getfield(self, pkt, s) |
|---|
| | 6327 | else: |
|---|
| | 6328 | return s,None |
|---|
| | 6329 | |
|---|
| | 6330 | class RadioTapIntField(XIntField): |
|---|
| | 6331 | def __init__(self, name, default, bitset): |
|---|
| | 6332 | XIntField.__init__(self, name, default) |
|---|
| | 6333 | self.bitset = bitset |
|---|
| | 6334 | |
|---|
| | 6335 | def getfield(self, pkt, s): |
|---|
| | 6336 | if (pkt.l+1) % 4: |
|---|
| | 6337 | delta=(pkt.l+4)/4*4 - pkt.l - 1 # alignement |
|---|
| | 6338 | pkt.l += delta |
|---|
| | 6339 | s = s[delta:] |
|---|
| | 6340 | if pkt[RadioTap].bitmap & (1 << self.bitset): |
|---|
| | 6341 | pkt.l += 4 |
|---|
| | 6342 | return XIntField.getfield(self, pkt, s) |
|---|
| | 6343 | else: |
|---|
| | 6344 | return s,None |
|---|
| | 6345 | |
|---|
| | 6346 | class RadioTapLongField(XLongField): |
|---|
| | 6347 | def __init__(self, name, default, bitset): |
|---|
| | 6348 | XLongField.__init__(self, name, default) |
|---|
| | 6349 | self.bitset = bitset |
|---|
| | 6350 | |
|---|
| | 6351 | def getfield(self, pkt, s): |
|---|
| | 6352 | if pkt[RadioTap].bitmap & (1 << self.bitset): |
|---|
| | 6353 | pkt.l += 8 |
|---|
| | 6354 | return XLongField.getfield(self, pkt, s) |
|---|
| | 6355 | else: |
|---|
| | 6356 | return s,None |
|---|
| | 6357 | |
|---|
| | 6358 | _radiotap_flags = { |
|---|
| | 6359 | 0x1: "CFP", |
|---|
| | 6360 | 0x2: "Preamble", |
|---|
| | 6361 | 0x3: "WEP", |
|---|
| | 6362 | 0x4: "Frag", |
|---|
| | 6363 | 0x5: "FCS", |
|---|
| | 6364 | 0x6: "pad" |
|---|
| | 6365 | } |
|---|
| | 6366 | |
|---|
| | 6367 | class RadioTapFlagsField(BitEnumField): |
|---|
| | 6368 | def __init__(self, name, default, bitset): |
|---|
| | 6369 | BitEnumField.__init__(self, name, default, 8, _radiotap_flags) |
|---|
| | 6370 | self.bitset = bitset |
|---|
| | 6371 | |
|---|
| | 6372 | def getfield(self, pkt, s): |
|---|
| | 6373 | if pkt[RadioTap].bitmap & (1 << self.bitset): |
|---|
| | 6374 | return BitEnumField.getfield(self, pkt, s) |
|---|
| | 6375 | else: |
|---|
| | 6376 | return s,None |
|---|
| | 6377 | |
|---|
| | 6378 | class RadioTapRateField(RadioTapByteField): |
|---|
| | 6379 | def i2repr(self, pkt, x): |
|---|
| | 6380 | if x is None: |
|---|
| | 6381 | return '0' |
|---|
| | 6382 | return '%d Mb/s' % (x*0.512) |
|---|
| | 6383 | |
|---|
| | 6384 | _radiotap_msg = { |
|---|
| | 6385 | 0x00: "TSFT", |
|---|
| | 6386 | 0x01: "Flags", |
|---|
| | 6387 | 0x02: "Rate", |
|---|
| | 6388 | 0x03: "Channel", |
|---|
| | 6389 | 0x04: "FrequencyHop", |
|---|
| | 6390 | 0x05: "SignalPower", |
|---|
| | 6391 | 0x06: "NoisePower", |
|---|
| | 6392 | 0x07: "Quality", |
|---|
| | 6393 | 0x08: "Transmit", |
|---|
| | 6394 | 0x09: "TransmitDB", |
|---|
| | 6395 | 0x0a: "TransmitDBM", |
|---|
| | 6396 | 0x0b: "AntennaId", |
|---|
| | 6397 | 0x0c: "PowerAntennaDB", |
|---|
| | 6398 | 0x0d: "NoisePowerDB", |
|---|
| | 6399 | 0x0e: "FCS", |
|---|
| | 6400 | 0x1f: "Extension", |
|---|
| | 6401 | } |
|---|
| | 6402 | |
|---|
| | 6403 | class RadioTapBitmapField(LEIntField): |
|---|
| | 6404 | def __init__(self, name, d): |
|---|
| | 6405 | LEIntField.__init__(self, name, 0) |
|---|
| | 6406 | self.d=d |
|---|
| | 6407 | |
|---|
| | 6408 | def i2repr(self, pkt, x): |
|---|
| | 6409 | n=0 |
|---|
| | 6410 | s=[] |
|---|
| | 6411 | while n < 32: |
|---|
| | 6412 | if x & (1 << n) and _radiotap_msg.has_key(n): |
|---|
| | 6413 | s.append(_radiotap_msg[n]) |
|---|
| | 6414 | n += 1 |
|---|
| | 6415 | return '+'.join(s) |
|---|
| | 6416 | |
|---|
| | 6417 | class RadioTapLenPadding(StrLenField): |
|---|
| | 6418 | def getfield(self, pkt, x): |
|---|
| | 6419 | pkt.l = pkt[RadioTap].len - pkt.l - 8 - 1 # 8 is the header's length |
|---|
| | 6420 | return StrLenField.getfield(self, pkt, x) |
|---|
| | 6421 | |
|---|
| | 6422 | ## /usr/src/linux/include/net/ieee80211_radiotap.h |
|---|
| | 6423 | ## http://madwifi.org/wiki/DevDocs/RadiotapHeader |
|---|
| | 6424 | class RadioTap(Packet): |
|---|
| | 6425 | name = "RadioTap" |
|---|
| | 6426 | l=0 # this will represent the length used by fields |
|---|
| | 6427 | fields_desc = [ ByteField('version', 0), |
|---|
| | 6428 | ByteField('padding', 0), |
|---|
| | 6429 | LenField('len', None, '@H'), |
|---|
| | 6430 | ## variable headers |
|---|
| | 6431 | RadioTapBitmapField('bitmap', _radiotap_msg), |
|---|
| | 6432 | RadioTapLongField('timestamp', 0, 0), |
|---|
| | 6433 | RadioTapFlagsField('flags', 0, 1), |
|---|
| | 6434 | RadioTapRateField('rate', 0, 2), |
|---|
| | 6435 | RadioTapChannelField('channel', 11, 3), |
|---|
| | 6436 | RadioTapChannelTypeField('chantype', 11, 3), |
|---|
| | 6437 | RadioTapShortField('hop', 0, 4), |
|---|
| | 6438 | RadioTapByteField('signal', 0, 5), |
|---|
| | 6439 | RadioTapByteField('noise', 0, 6), |
|---|
| | 6440 | RadioTapShortField('quality', 0, 7), |
|---|
| | 6441 | RadioTapShortField('tx', 0, 8), |
|---|
| | 6442 | RadioTapShortField('txDB', 0, 9), |
|---|
| | 6443 | RadioTapByteField('txDBM', 0, 10), |
|---|
| | 6444 | RadioTapByteField('antennaID', 0, 11), |
|---|
| | 6445 | RadioTapByteField('powerAntennaDB', 0, 12), |
|---|
| | 6446 | RadioTapByteField('noisepowerDB', 0, 13), |
|---|
| | 6447 | RadioTapIntField('fcs', 0, 14), |
|---|
| | 6448 | RadioTapLenPadding('padding', '', 'l') ] |
|---|
| | 6449 | |
|---|