Package dpkt :: Module ieee80211
[hide private]
[frames] | no frames]

Source Code for Module dpkt.ieee80211

  1  # $Id: 80211.py 53 2008-12-18 01:22:57Z jon.oberheide $ 
  2  # -*- coding: utf-8 -*- 
  3  """IEEE 802.11.""" 
  4  from __future__ import print_function 
  5  from __future__ import absolute_import 
  6   
  7  import socket 
  8  import struct 
  9   
 10  from . import dpkt 
 11  from .decorators import deprecated 
 12   
 13  # Frame Types 
 14  MGMT_TYPE = 0 
 15  CTL_TYPE = 1 
 16  DATA_TYPE = 2 
 17   
 18  # Frame Sub-Types 
 19  M_ASSOC_REQ = 0 
 20  M_ASSOC_RESP = 1 
 21  M_REASSOC_REQ = 2 
 22  M_REASSOC_RESP = 3 
 23  M_PROBE_REQ = 4 
 24  M_PROBE_RESP = 5 
 25  M_BEACON = 8 
 26  M_ATIM = 9 
 27  M_DISASSOC = 10 
 28  M_AUTH = 11 
 29  M_DEAUTH = 12 
 30  M_ACTION = 13 
 31  C_BLOCK_ACK_REQ = 8 
 32  C_BLOCK_ACK = 9 
 33  C_PS_POLL = 10 
 34  C_RTS = 11 
 35  C_CTS = 12 
 36  C_ACK = 13 
 37  C_CF_END = 14 
 38  C_CF_END_ACK = 15 
 39  D_DATA = 0 
 40  D_DATA_CF_ACK = 1 
 41  D_DATA_CF_POLL = 2 
 42  D_DATA_CF_ACK_POLL = 3 
 43  D_NULL = 4 
 44  D_CF_ACK = 5 
 45  D_CF_POLL = 6 
 46  D_CF_ACK_POLL = 7 
 47  D_QOS_DATA = 8 
 48  D_QOS_CF_ACK = 9 
 49  D_QOS_CF_POLL = 10 
 50  D_QOS_CF_ACK_POLL = 11 
 51  D_QOS_NULL = 12 
 52  D_QOS_CF_POLL_EMPTY = 14 
 53   
 54  TO_DS_FLAG = 10 
 55  FROM_DS_FLAG = 1 
 56  INTER_DS_FLAG = 11 
 57   
 58  # Bitshifts for Frame Control 
 59  _VERSION_MASK = 0x0300 
 60  _TYPE_MASK = 0x0c00 
 61  _SUBTYPE_MASK = 0xf000 
 62  _TO_DS_MASK = 0x0001 
 63  _FROM_DS_MASK = 0x0002 
 64  _MORE_FRAG_MASK = 0x0004 
 65  _RETRY_MASK = 0x0008 
 66  _PWR_MGT_MASK = 0x0010 
 67  _MORE_DATA_MASK = 0x0020 
 68  _WEP_MASK = 0x0040 
 69  _ORDER_MASK = 0x0080 
 70  _VERSION_SHIFT = 8 
 71  _TYPE_SHIFT = 10 
 72  _SUBTYPE_SHIFT = 12 
 73  _TO_DS_SHIFT = 0 
 74  _FROM_DS_SHIFT = 1 
 75  _MORE_FRAG_SHIFT = 2 
 76  _RETRY_SHIFT = 3 
 77  _PWR_MGT_SHIFT = 4 
 78  _MORE_DATA_SHIFT = 5 
 79  _WEP_SHIFT = 6 
 80  _ORDER_SHIFT = 7 
 81   
 82  # IEs 
 83  IE_SSID = 0 
 84  IE_RATES = 1 
 85  IE_FH = 2 
 86  IE_DS = 3 
 87  IE_CF = 4 
 88  IE_TIM = 5 
 89  IE_IBSS = 6 
 90  IE_HT_CAPA = 45 
 91  IE_ESR = 50 
 92  IE_HT_INFO = 61 
 93   
 94  FCS_LENGTH = 4 
 95   
 96  FRAMES_WITH_CAPABILITY = [M_BEACON, M_ASSOC_RESP, M_ASSOC_REQ, M_REASSOC_REQ, ] 
 97   
 98  # Block Ack control constants 
 99  _ACK_POLICY_SHIFT = 0 
100  _MULTI_TID_SHIFT = 1 
101  _COMPRESSED_SHIFT = 2 
102  _TID_SHIFT = 12 
103   
104  _ACK_POLICY_MASK = 0x0001 
105  _MULTI_TID_MASK = 0x0002 
106  _COMPRESSED_MASK = 0x0004 
107  _TID_MASK = 0xf000 
108   
109  _COMPRESSED_BMP_LENGTH = 8 
110  _BMP_LENGTH = 128 
111   
112  # Action frame categories 
113  BLOCK_ACK = 3 
114   
115  # Block ack category action codes 
116  BLOCK_ACK_CODE_REQUEST = 0 
117  BLOCK_ACK_CODE_RESPONSE = 1 
118 119 120 -class IEEE80211(dpkt.Packet):
121 """IEEE 802.11. 122 123 TODO: Longer class information.... 124 125 Attributes: 126 __hdr__: Header fields of IEEE802.11. 127 TODO. 128 """ 129 130 __hdr__ = ( 131 ('framectl', 'H', 0), 132 ('duration', 'H', 0) 133 ) 134 135 @property
136 - def version(self):
137 return (self.framectl & _VERSION_MASK) >> _VERSION_SHIFT
138 139 @version.setter
140 - def version(self, val):
141 self.framectl = (val << _VERSION_SHIFT) | (self.framectl & ~_VERSION_MASK)
142 143 @property
144 - def type(self):
145 return (self.framectl & _TYPE_MASK) >> _TYPE_SHIFT
146 147 @type.setter
148 - def type(self, val):
149 self.framectl = (val << _TYPE_SHIFT) | (self.framectl & ~_TYPE_MASK)
150 151 @property
152 - def subtype(self):
153 return (self.framectl & _SUBTYPE_MASK) >> _SUBTYPE_SHIFT
154 155 @subtype.setter
156 - def subtype(self, val):
157 self.framectl = (val << _SUBTYPE_SHIFT) | (self.framectl & ~_SUBTYPE_MASK)
158 159 @property
160 - def to_ds(self):
161 return (self.framectl & _TO_DS_MASK) >> _TO_DS_SHIFT
162 163 @to_ds.setter
164 - def to_ds(self, val):
165 self.framectl = (val << _TO_DS_SHIFT) | (self.framectl & ~_TO_DS_MASK)
166 167 @property
168 - def from_ds(self):
169 return (self.framectl & _FROM_DS_MASK) >> _FROM_DS_SHIFT
170 171 @from_ds.setter
172 - def from_ds(self, val):
173 self.framectl = (val << _FROM_DS_SHIFT) | (self.framectl & ~_FROM_DS_MASK)
174 175 @property
176 - def more_frag(self):
177 return (self.framectl & _MORE_FRAG_MASK) >> _MORE_FRAG_SHIFT
178 179 @more_frag.setter
180 - def more_frag(self, val):
182 183 @property
184 - def retry(self):
185 return (self.framectl & _RETRY_MASK) >> _RETRY_SHIFT
186 187 @retry.setter
188 - def retry(self, val):
189 self.framectl = (val << _RETRY_SHIFT) | (self.framectl & ~_RETRY_MASK)
190 191 @property
192 - def pwr_mgt(self):
193 return (self.framectl & _PWR_MGT_MASK) >> _PWR_MGT_SHIFT
194 195 @pwr_mgt.setter
196 - def pwr_mgt(self, val):
197 self.framectl = (val << _PWR_MGT_SHIFT) | (self.framectl & ~_PWR_MGT_MASK)
198 199 @property
200 - def more_data(self):
201 return (self.framectl & _MORE_DATA_MASK) >> _MORE_DATA_SHIFT
202 203 @more_data.setter
204 - def more_data(self, val):
206 207 @property
208 - def wep(self):
209 return (self.framectl & _WEP_MASK) >> _WEP_SHIFT
210 211 @wep.setter
212 - def wep(self, val):
213 self.framectl = (val << _WEP_SHIFT) | (self.framectl & ~_WEP_MASK)
214 215 @property
216 - def order(self):
217 return (self.framectl & _ORDER_MASK) >> _ORDER_SHIFT
218 219 @order.setter
220 - def order(self, val):
221 self.framectl = (val << _ORDER_SHIFT) | (self.framectl & ~_ORDER_MASK)
222
223 - def unpack_ies(self, buf):
224 self.ies = [] 225 226 ie_decoder = { 227 IE_SSID: ('ssid', self.IE), 228 IE_RATES: ('rate', self.IE), 229 IE_FH: ('fh', self.FH), 230 IE_DS: ('ds', self.DS), 231 IE_CF: ('cf', self.CF), 232 IE_TIM: ('tim', self.TIM), 233 IE_IBSS: ('ibss', self.IBSS), 234 IE_HT_CAPA: ('ht_capa', self.IE), 235 IE_ESR: ('esr', self.IE), 236 IE_HT_INFO: ('ht_info', self.IE) 237 } 238 239 # each IE starts with an ID and a length 240 while len(buf) > FCS_LENGTH: 241 ie_id = struct.unpack('B', buf[:1])[0] 242 try: 243 parser = ie_decoder[ie_id][1] 244 name = ie_decoder[ie_id][0] 245 except KeyError: 246 parser = self.IE 247 name = 'ie_' + str(ie_id) 248 ie = parser(buf) 249 250 ie.data = buf[2:2 + ie.len] 251 setattr(self, name, ie) 252 self.ies.append(ie) 253 buf = buf[2 + ie.len:]
254
255 - class Capability(object):
256 - def __init__(self, field):
257 self.ess = field & 1 258 self.ibss = (field >> 1) & 1 259 self.cf_poll = (field >> 2) & 1 260 self.cf_poll_req = (field >> 3) & 1 261 self.privacy = (field >> 4) & 1 262 self.short_preamble = (field >> 5) & 1 263 self.pbcc = (field >> 6) & 1 264 self.hopping = (field >> 7) & 1 265 self.spec_mgmt = (field >> 8) & 1 266 self.qos = (field >> 9) & 1 267 self.short_slot = (field >> 10) & 1 268 self.apsd = (field >> 11) & 1 269 self.dsss = (field >> 13) & 1 270 self.delayed_blk_ack = (field >> 14) & 1 271 self.imm_blk_ack = (field >> 15) & 1
272
273 - def __init__(self, *args, **kwargs):
274 if kwargs and 'fcs' in kwargs: 275 self.fcs_present = kwargs.pop('fcs') 276 else: 277 self.fcs_present = False 278 279 super(IEEE80211, self).__init__(*args, **kwargs)
280
281 - def unpack(self, buf):
282 dpkt.Packet.unpack(self, buf) 283 self.data = buf[self.__hdr_len__:] 284 285 m_decoder = { 286 M_BEACON: ('beacon', self.Beacon), 287 M_ASSOC_REQ: ('assoc_req', self.Assoc_Req), 288 M_ASSOC_RESP: ('assoc_resp', self.Assoc_Resp), 289 M_DISASSOC: ('diassoc', self.Disassoc), 290 M_REASSOC_REQ: ('reassoc_req', self.Reassoc_Req), 291 M_REASSOC_RESP: ('reassoc_resp', self.Assoc_Resp), 292 M_AUTH: ('auth', self.Auth), 293 M_PROBE_RESP: ('probe_resp', self.Beacon), 294 M_DEAUTH: ('deauth', self.Deauth), 295 M_ACTION: ('action', self.Action) 296 } 297 298 c_decoder = { 299 C_RTS: ('rts', self.RTS), 300 C_CTS: ('cts', self.CTS), 301 C_ACK: ('ack', self.ACK), 302 C_BLOCK_ACK_REQ: ('bar', self.BlockAckReq), 303 C_BLOCK_ACK: ('back', self.BlockAck), 304 C_CF_END: ('cf_end', self.CFEnd), 305 } 306 307 d_dsData = { 308 0: self.Data, 309 FROM_DS_FLAG: self.DataFromDS, 310 TO_DS_FLAG: self.DataToDS, 311 INTER_DS_FLAG: self.DataInterDS 312 } 313 314 # For now decode everything with DATA. Haven't checked about other QoS 315 # additions 316 d_decoder = { 317 # modified the decoder to consider the ToDS and FromDS flags 318 # Omitting the 11 case for now 319 D_DATA: ('data_frame', d_dsData), 320 D_NULL: ('data_frame', d_dsData), 321 D_QOS_DATA: ('data_frame', d_dsData), 322 D_QOS_NULL: ('data_frame', d_dsData) 323 } 324 325 decoder = { 326 MGMT_TYPE: m_decoder, 327 CTL_TYPE: c_decoder, 328 DATA_TYPE: d_decoder 329 } 330 331 # Strip off the FCS field 332 if self.fcs_present: 333 self.fcs = struct.unpack('I', self.data[-1 * FCS_LENGTH:])[0] 334 self.data = self.data[0: -1 * FCS_LENGTH] 335 336 if self.type == MGMT_TYPE: 337 self.mgmt = self.MGMT_Frame(self.data) 338 self.data = self.mgmt.data 339 if self.subtype == M_PROBE_REQ: 340 self.unpack_ies(self.data) 341 return 342 if self.subtype == M_ATIM: 343 return 344 345 try: 346 parser = decoder[self.type][self.subtype][1] 347 name = decoder[self.type][self.subtype][0] 348 except KeyError: 349 raise dpkt.UnpackError("KeyError: type=%s subtype=%s" % (self.type, self.subtype)) 350 351 if self.type == DATA_TYPE: 352 # need to grab the ToDS/FromDS info 353 parser = parser[self.to_ds * 10 + self.from_ds] 354 355 if self.type == MGMT_TYPE: 356 field = parser(self.mgmt.data) 357 else: 358 field = parser(self.data) 359 self.data = field 360 361 setattr(self, name, field) 362 363 if self.type == MGMT_TYPE: 364 self.unpack_ies(field.data) 365 if self.subtype in FRAMES_WITH_CAPABILITY: 366 self.capability = self.Capability(socket.ntohs(field.capability)) 367 368 if self.type == DATA_TYPE and self.subtype == D_QOS_DATA: 369 self.qos_data = self.QoS_Data(field.data) 370 field.data = self.qos_data.data 371 372 self.data = field.data
373
374 - class BlockAckReq(dpkt.Packet):
375 __hdr__ = ( 376 ('dst', '6s', '\x00' * 6), 377 ('src', '6s', '\x00' * 6), 378 ('ctl', 'H', 0), 379 ('seq', 'H', 0), 380 )
381
382 - class BlockAck(dpkt.Packet):
383 __hdr__ = ( 384 ('dst', '6s', '\x00' * 6), 385 ('src', '6s', '\x00' * 6), 386 ('ctl', 'H', 0), 387 ('seq', 'H', 0), 388 ) 389 390 @property
391 - def compressed(self):
392 return (self.ctl & _COMPRESSED_MASK) >> _COMPRESSED_SHIFT
393 394 @compressed.setter
395 - def compressed(self, val):
396 self.ctl = (val << _COMPRESSED_SHIFT) | (self.ctl & ~_COMPRESSED_MASK)
397 398 @property
399 - def ack_policy(self):
400 return (self.ctl & _ACK_POLICY_MASK) >> _ACK_POLICY_SHIFT
401 402 @ack_policy.setter
403 - def ack_policy(self, val):
404 self.ctl = (val << _ACK_POLICY_SHIFT) | (self.ctl & ~_ACK_POLICY_MASK)
405 406 @property
407 - def multi_tid(self):
408 return (self.ctl & _MULTI_TID_MASK) >> _MULTI_TID_SHIFT
409 410 @multi_tid.setter
411 - def multi_tid(self, val):
412 self.ctl = (val << _MULTI_TID_SHIFT) | (self.ctl & ~_MULTI_TID_MASK)
413 414 @property
415 - def tid(self):
416 return (self.ctl & _TID_MASK) >> _TID_SHIFT
417 418 @tid.setter
419 - def tid(self, val):
420 self.ctl = (val << _TID_SHIFT) | (self.ctl & ~_TID_MASK)
421
422 - def unpack(self, buf):
423 dpkt.Packet.unpack(self, buf) 424 self.data = buf[self.__hdr_len__:] 425 self.ctl = socket.ntohs(self.ctl) 426 427 if self.compressed: 428 self.bmp = struct.unpack('8s', self.data[0:_COMPRESSED_BMP_LENGTH])[0] 429 else: 430 self.bmp = struct.unpack('128s', self.data[0:_BMP_LENGTH])[0] 431 self.data = self.data[len(self.__hdr__) + len(self.bmp):]
432
433 - class RTS(dpkt.Packet):
434 __hdr__ = ( 435 ('dst', '6s', '\x00' * 6), 436 ('src', '6s', '\x00' * 6) 437 )
438
439 - class CTS(dpkt.Packet):
440 __hdr__ = ( 441 ('dst', '6s', '\x00' * 6), 442 )
443
444 - class ACK(dpkt.Packet):
445 __hdr__ = ( 446 ('dst', '6s', '\x00' * 6), 447 )
448
449 - class CFEnd(dpkt.Packet):
450 __hdr__ = ( 451 ('dst', '6s', '\x00' * 6), 452 ('src', '6s', '\x00' * 6), 453 )
454
455 - class MGMT_Frame(dpkt.Packet):
456 __hdr__ = ( 457 ('dst', '6s', '\x00' * 6), 458 ('src', '6s', '\x00' * 6), 459 ('bssid', '6s', '\x00' * 6), 460 ('frag_seq', 'H', 0) 461 )
462
463 - class Beacon(dpkt.Packet):
464 __hdr__ = ( 465 ('timestamp', 'Q', 0), 466 ('interval', 'H', 0), 467 ('capability', 'H', 0) 468 )
469
470 - class Disassoc(dpkt.Packet):
471 __hdr__ = ( 472 ('reason', 'H', 0), 473 )
474
475 - class Assoc_Req(dpkt.Packet):
476 __hdr__ = ( 477 ('capability', 'H', 0), 478 ('interval', 'H', 0) 479 )
480
481 - class Assoc_Resp(dpkt.Packet):
482 __hdr__ = ( 483 ('capability', 'H', 0), 484 ('status', 'H', 0), 485 ('aid', 'H', 0) 486 )
487
488 - class Reassoc_Req(dpkt.Packet):
489 __hdr__ = ( 490 ('capability', 'H', 0), 491 ('interval', 'H', 0), 492 ('current_ap', '6s', '\x00' * 6) 493 )
494 495 # This obviously doesn't support any of AUTH frames that use encryption
496 - class Auth(dpkt.Packet):
497 __hdr__ = ( 498 ('algorithm', 'H', 0), 499 ('auth_seq', 'H', 0), 500 )
501
502 - class Deauth(dpkt.Packet):
503 __hdr__ = ( 504 ('reason', 'H', 0), 505 )
506
507 - class Action(dpkt.Packet):
508 __hdr__ = ( 509 ('category', 'B', 0), 510 ('code', 'B', 0), 511 ) 512
513 - def unpack(self, buf):
514 dpkt.Packet.unpack(self, buf) 515 516 action_parser = { 517 BLOCK_ACK: { 518 BLOCK_ACK_CODE_REQUEST: ('block_ack_request', IEEE80211.BlockAckActionRequest), 519 BLOCK_ACK_CODE_RESPONSE: ('block_ack_response', IEEE80211.BlockAckActionResponse), 520 }, 521 } 522 523 try: 524 decoder = action_parser[self.category][self.code][1] 525 field_name = action_parser[self.category][self.code][0] 526 except KeyError: 527 raise dpkt.UnpackError("KeyError: category=%s code=%s" % (self.category, self.code)) 528 529 field = decoder(self.data) 530 setattr(self, field_name, field) 531 self.data = field.data
532
533 - class BlockAckActionRequest(dpkt.Packet):
534 __hdr__ = ( 535 ('dialog', 'B', 0), 536 ('parameters', 'H', 0), 537 ('timeout', 'H', 0), 538 ('starting_seq', 'H', 0), 539 )
540
541 - class BlockAckActionResponse(dpkt.Packet):
542 __hdr__ = ( 543 ('dialog', 'B', 0), 544 ('status_code', 'H', 0), 545 ('parameters', 'H', 0), 546 ('timeout', 'H', 0), 547 )
548
549 - class Data(dpkt.Packet):
550 __hdr__ = ( 551 ('dst', '6s', '\x00' * 6), 552 ('src', '6s', '\x00' * 6), 553 ('bssid', '6s', '\x00' * 6), 554 ('frag_seq', 'H', 0) 555 )
556
557 - class DataFromDS(dpkt.Packet):
558 __hdr__ = ( 559 ('dst', '6s', '\x00' * 6), 560 ('bssid', '6s', '\x00' * 6), 561 ('src', '6s', '\x00' * 6), 562 ('frag_seq', 'H', 0) 563 )
564
565 - class DataToDS(dpkt.Packet):
566 __hdr__ = ( 567 ('bssid', '6s', '\x00' * 6), 568 ('src', '6s', '\x00' * 6), 569 ('dst', '6s', '\x00' * 6), 570 ('frag_seq', 'H', 0) 571 )
572
573 - class DataInterDS(dpkt.Packet):
574 __hdr__ = ( 575 ('dst', '6s', '\x00' * 6), 576 ('src', '6s', '\x00' * 6), 577 ('da', '6s', '\x00' * 6), 578 ('frag_seq', 'H', 0), 579 ('sa', '6s', '\x00' * 6) 580 )
581
582 - class QoS_Data(dpkt.Packet):
583 __hdr__ = ( 584 ('control', 'H', 0), 585 )
586
587 - class IE(dpkt.Packet):
588 __hdr__ = ( 589 ('id', 'B', 0), 590 ('len', 'B', 0) 591 ) 592
593 - def unpack(self, buf):
594 dpkt.Packet.unpack(self, buf) 595 self.info = buf[2:self.len + 2]
596
597 - class FH(dpkt.Packet):
598 __hdr__ = ( 599 ('id', 'B', 0), 600 ('len', 'B', 0), 601 ('tu', 'H', 0), 602 ('hopset', 'B', 0), 603 ('hoppattern', 'B', 0), 604 ('hopindex', 'B', 0) 605 )
606
607 - class DS(dpkt.Packet):
608 __hdr__ = ( 609 ('id', 'B', 0), 610 ('len', 'B', 0), 611 ('ch', 'B', 0) 612 )
613
614 - class CF(dpkt.Packet):
615 __hdr__ = ( 616 ('id', 'B', 0), 617 ('len', 'B', 0), 618 ('count', 'B', 0), 619 ('period', 'B', 0), 620 ('max', 'H', 0), 621 ('dur', 'H', 0) 622 )
623
624 - class TIM(dpkt.Packet):
625 __hdr__ = ( 626 ('id', 'B', 0), 627 ('len', 'B', 0), 628 ('count', 'B', 0), 629 ('period', 'B', 0), 630 ('ctrl', 'H', 0) 631 ) 632
633 - def unpack(self, buf):
634 dpkt.Packet.unpack(self, buf) 635 self.bitmap = buf[5:self.len + 2]
636
637 - class IBSS(dpkt.Packet):
638 __hdr__ = ( 639 ('id', 'B', 0), 640 ('len', 'B', 0), 641 ('atim', 'H', 0) 642 )
643
644 645 -def test_802211_ack():
646 s = b'\xd4\x00\x00\x00\x00\x12\xf0\xb6\x1c\xa4\xff\xff\xff\xff' 647 ieee = IEEE80211(s, fcs=True) 648 assert ieee.version == 0 649 assert ieee.type == CTL_TYPE 650 assert ieee.subtype == C_ACK 651 assert ieee.to_ds == 0 652 assert ieee.from_ds == 0 653 assert ieee.pwr_mgt == 0 654 assert ieee.more_data == 0 655 assert ieee.wep == 0 656 assert ieee.order == 0 657 assert ieee.ack.dst == b'\x00\x12\xf0\xb6\x1c\xa4' 658 fcs = struct.unpack('I', s[-4:])[0] 659 assert ieee.fcs == fcs
660
661 -def test_80211_beacon():
662 s = b'\x80\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x26\xcb\x18\x6a\x30\x00\x26\xcb\x18\x6a\x30\xa0\xd0\x77\x09\x32\x03\x8f\x00\x00\x00\x66\x00\x31\x04\x00\x04\x43\x41\x45\x4e\x01\x08\x82\x84\x8b\x0c\x12\x96\x18\x24\x03\x01\x01\x05\x04\x00\x01\x00\x00\x07\x06\x55\x53\x20\x01\x0b\x1a\x0b\x05\x00\x00\x6e\x00\x00\x2a\x01\x02\x2d\x1a\x6e\x18\x1b\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x14\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x28\x00\x32\x04\x30\x48\x60\x6c\x36\x03\x51\x63\x03\x3d\x16\x01\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x1e\x05\x00\x8f\x00\x0f\x00\xff\x03\x59\x00\x63\x73\x65\x2d\x33\x39\x31\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x36\x96\x06\x00\x40\x96\x00\x14\x00\xdd\x18\x00\x50\xf2\x02\x01\x01\x80\x00\x03\xa4\x00\x00\x27\xa4\x00\x00\x42\x43\x5e\x00\x62\x32\x2f\x00\xdd\x06\x00\x40\x96\x01\x01\x04\xdd\x05\x00\x40\x96\x03\x05\xdd\x05\x00\x40\x96\x0b\x09\xdd\x08\x00\x40\x96\x13\x01\x00\x34\x01\xdd\x05\x00\x40\x96\x14\x05' 663 ieee = IEEE80211(s, fcs=True) 664 assert ieee.version == 0 665 assert ieee.type == MGMT_TYPE 666 assert ieee.subtype == M_BEACON 667 assert ieee.to_ds == 0 668 assert ieee.from_ds == 0 669 assert ieee.pwr_mgt == 0 670 assert ieee.more_data == 0 671 assert ieee.wep == 0 672 assert ieee.order == 0 673 assert ieee.mgmt.dst == b'\xff\xff\xff\xff\xff\xff' 674 assert ieee.mgmt.src == b'\x00\x26\xcb\x18\x6a\x30' 675 assert ieee.beacon.capability == 0x3104 676 assert ieee.capability.privacy == 1 677 assert ieee.ssid.data == b'CAEN' 678 assert ieee.rate.data == b'\x82\x84\x8b\x0c\x12\x96\x18\x24' 679 assert ieee.ds.data == b'\x01' 680 assert ieee.tim.data == b'\x00\x01\x00\x00' 681 fcs = struct.unpack('I', s[-4:])[0] 682 assert ieee.fcs == fcs
683
684 -def test_80211_data():
685 s = b'\x08\x09\x20\x00\x00\x26\xcb\x17\x3d\x91\x00\x16\x44\xb0\xae\xc6\x00\x02\xb3\xd6\x26\x3c\x80\x7e\xaa\xaa\x03\x00\x00\x00\x08\x00\x45\x00\x00\x28\x07\x27\x40\x00\x80\x06\x1d\x39\x8d\xd4\x37\x3d\x3f\xf5\xd1\x69\xc0\x5f\x01\xbb\xb2\xd6\xef\x23\x38\x2b\x4f\x08\x50\x10\x42\x04\xac\x17\x00\x00' 686 ieee = IEEE80211(s, fcs=True) 687 assert ieee.type == DATA_TYPE 688 assert ieee.subtype == D_DATA 689 assert ieee.data_frame.dst == b'\x00\x02\xb3\xd6\x26\x3c' 690 assert ieee.data_frame.src == b'\x00\x16\x44\xb0\xae\xc6' 691 assert ieee.data_frame.frag_seq == 0x807e 692 assert ieee.data == b'\xaa\xaa\x03\x00\x00\x00\x08\x00\x45\x00\x00\x28\x07\x27\x40\x00\x80\x06\x1d\x39\x8d\xd4\x37\x3d\x3f\xf5\xd1\x69\xc0\x5f\x01\xbb\xb2\xd6\xef\x23\x38\x2b\x4f\x08\x50\x10\x42\x04' 693 assert ieee.fcs == struct.unpack('I', b'\xac\x17\x00\x00')[0] 694 695 from . import llc 696 llc_pkt = llc.LLC(ieee.data_frame.data) 697 ip_pkt = llc_pkt.data 698 assert ip_pkt.dst == b'\x3f\xf5\xd1\x69'
699
700 -def test_80211_data_qos():
701 s = b'\x88\x01\x3a\x01\x00\x26\xcb\x17\x44\xf0\x00\x23\xdf\xc9\xc0\x93\x00\x26\xcb\x17\x44\xf0\x20\x7b\x00\x00\xaa\xaa\x03\x00\x00\x00\x88\x8e\x01\x00\x00\x74\x02\x02\x00\x74\x19\x80\x00\x00\x00\x6a\x16\x03\x01\x00\x65\x01\x00\x00\x61\x03\x01\x4b\x4c\xa7\x7e\x27\x61\x6f\x02\x7b\x3c\x72\x39\xe3\x7b\xd7\x43\x59\x91\x7f\xaa\x22\x47\x51\xb6\x88\x9f\x85\x90\x87\x5a\xd1\x13\x20\xe0\x07\x00\x00\x68\xbd\xa4\x13\xb0\xd5\x82\x7e\xc7\xfb\xe7\xcc\xab\x6e\x5d\x5a\x51\x50\xd4\x45\xc5\xa1\x65\x53\xad\xb5\x88\x5b\x00\x1a\x00\x2f\x00\x05\x00\x04\x00\x35\x00\x0a\x00\x09\x00\x03\x00\x08\x00\x33\x00\x39\x00\x16\x00\x15\x00\x14\x01\x00\xff\xff\xff\xff' 702 ieee = IEEE80211(s, fcs=True) 703 assert ieee.type == DATA_TYPE 704 assert ieee.subtype == D_QOS_DATA 705 assert ieee.data_frame.dst == b'\x00\x26\xcb\x17\x44\xf0' 706 assert ieee.data_frame.src == b'\x00\x23\xdf\xc9\xc0\x93' 707 assert ieee.data_frame.frag_seq == 0x207b 708 assert ieee.data == b'\xaa\xaa\x03\x00\x00\x00\x88\x8e\x01\x00\x00\x74\x02\x02\x00\x74\x19\x80\x00\x00\x00\x6a\x16\x03\x01\x00\x65\x01\x00\x00\x61\x03\x01\x4b\x4c\xa7\x7e\x27\x61\x6f\x02\x7b\x3c\x72\x39\xe3\x7b\xd7\x43\x59\x91\x7f\xaa\x22\x47\x51\xb6\x88\x9f\x85\x90\x87\x5a\xd1\x13\x20\xe0\x07\x00\x00\x68\xbd\xa4\x13\xb0\xd5\x82\x7e\xc7\xfb\xe7\xcc\xab\x6e\x5d\x5a\x51\x50\xd4\x45\xc5\xa1\x65\x53\xad\xb5\x88\x5b\x00\x1a\x00\x2f\x00\x05\x00\x04\x00\x35\x00\x0a\x00\x09\x00\x03\x00\x08\x00\x33\x00\x39\x00\x16\x00\x15\x00\x14\x01\x00' 709 assert ieee.qos_data.control == 0x0 710 assert ieee.fcs == struct.unpack('I', b'\xff\xff\xff\xff')[0]
711
712 -def test_bug():
713 s = b'\x88\x41\x2c\x00\x00\x26\xcb\x17\x44\xf0\x00\x1e\x52\x97\x14\x11\x00\x1f\x6d\xe8\x18\x00\xd0\x07\x00\x00\x6f\x00\x00\x20\x00\x00\x00\x00' 714 ieee = IEEE80211(s) 715 assert ieee.wep == 1
716
717 -def test_data_ds():
718 # verifying the ToDS and FromDS fields and that we're getting the 719 # correct values 720 721 s = b'\x08\x03\x00\x00\x01\x0b\x85\x00\x00\x00\x00\x26\xcb\x18\x73\x50\x01\x0b\x85\x00\x00\x00\x00\x89\x00\x26\xcb\x18\x73\x50' 722 ieee = IEEE80211(s) 723 assert ieee.type == DATA_TYPE 724 assert ieee.to_ds == 1 725 assert ieee.from_ds == 1 726 assert ieee.data_frame.sa == b'\x00\x26\xcb\x18\x73\x50' 727 assert ieee.data_frame.src == b'\x00\x26\xcb\x18\x73\x50' 728 assert ieee.data_frame.dst == b'\x01\x0b\x85\x00\x00\x00' 729 assert ieee.data_frame.da == b'\x01\x0b\x85\x00\x00\x00' 730 731 s = b'\x88\x41\x50\x01\x00\x26\xcb\x17\x48\xc1\x00\x24\x2c\xe7\xfe\x8a\xff\xff\xff\xff\xff\xff\x80\xa0\x00\x00\x09\x1a\x00\x20\x00\x00\x00\x00' 732 ieee = IEEE80211(s) 733 assert ieee.type == DATA_TYPE 734 assert ieee.to_ds == 1 735 assert ieee.from_ds == 0 736 assert ieee.data_frame.bssid == b'\x00\x26\xcb\x17\x48\xc1' 737 assert ieee.data_frame.src == b'\x00\x24\x2c\xe7\xfe\x8a' 738 assert ieee.data_frame.dst == b'\xff\xff\xff\xff\xff\xff' 739 740 s = b'\x08\x02\x02\x01\x00\x02\x44\xac\x27\x70\x00\x1f\x33\x39\x75\x44\x00\x1f\x33\x39\x75\x44\x90\xa4' 741 ieee = IEEE80211(s) 742 assert ieee.type == DATA_TYPE 743 assert ieee.to_ds == 0 744 assert ieee.from_ds == 1 745 assert ieee.data_frame.bssid == b'\x00\x1f\x33\x39\x75\x44' 746 assert ieee.data_frame.src == b'\x00\x1f\x33\x39\x75\x44' 747 assert ieee.data_frame.dst == b'\x00\x02\x44\xac\x27\x70'
748
749 -def test_compressed_block_ack():
750 s = b'\x94\x00\x00\x00\x34\xc0\x59\xd6\x3f\x62\xb4\x75\x0e\x46\x83\xc1\x05\x50\x80\xee\x03\x00\x00\x00\x00\x00\x00\x00\xa2\xe4\x98\x45' 751 ieee = IEEE80211(s, fcs=True) 752 assert ieee.type == CTL_TYPE 753 assert ieee.subtype == C_BLOCK_ACK 754 assert ieee.back.dst == b'\x34\xc0\x59\xd6\x3f\x62' 755 assert ieee.back.src == b'\xb4\x75\x0e\x46\x83\xc1' 756 assert ieee.back.compressed == 1 757 assert len(ieee.back.bmp) == 8 758 assert ieee.back.ack_policy == 1 759 assert ieee.back.tid == 5
760
761 -def test_action_block_ack_request():
762 s = b'\xd0\x00\x3a\x01\x00\x23\x14\x36\x52\x30\xb4\x75\x0e\x46\x83\xc1\xb4\x75\x0e\x46\x83\xc1\x70\x14\x03\x00\x0d\x02\x10\x00\x00\x40\x29\x06\x50\x33\x9e' 763 ieee = IEEE80211(s, fcs=True) 764 assert ieee.type == MGMT_TYPE 765 assert ieee.subtype == M_ACTION 766 assert ieee.action.category == BLOCK_ACK 767 assert ieee.action.code == BLOCK_ACK_CODE_REQUEST 768 assert ieee.action.block_ack_request.timeout == 0 769 parameters = struct.unpack('H', b'\x10\x02')[0] 770 assert ieee.action.block_ack_request.parameters == parameters
771
772 -def test_action_block_ack_response():
773 s = b'\xd0\x00\x3c\x00\xb4\x75\x0e\x46\x83\xc1\x00\x23\x14\x36\x52\x30\xb4\x75\x0e\x46\x83\xc1\xd0\x68\x03\x01\x0d\x00\x00\x02\x10\x88\x13\x9f\xc0\x0b\x75' 774 ieee = IEEE80211(s, fcs=True) 775 assert ieee.type == MGMT_TYPE 776 assert ieee.subtype == M_ACTION 777 assert ieee.action.category == BLOCK_ACK 778 assert ieee.action.code == BLOCK_ACK_CODE_RESPONSE 779 timeout = struct.unpack('H', b'\x13\x88')[0] 780 assert ieee.action.block_ack_response.timeout == timeout 781 parameters = struct.unpack('H', b'\x10\x02')[0] 782 assert ieee.action.block_ack_response.parameters == parameters
783 784 if __name__ == '__main__': 785 # Runs all the test associated with this class/file 786 test_802211_ack() 787 test_80211_beacon() 788 test_80211_data() 789 test_80211_data_qos() 790 test_bug() 791 test_data_ds() 792 test_compressed_block_ack() 793 test_action_block_ack_request() 794 test_action_block_ack_response() 795 print('Tests Successful...') 796