ieee80211.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. """IEEE 802.11"""
  2. from pypacker import pypacker
  3. from pypacker import triggerlist
  4. import struct
  5. import logging
  6. logger = logging.getLogger("pypacker")
  7. # Frame Types
  8. MGMT_TYPE = 0
  9. CTL_TYPE = 1
  10. DATA_TYPE = 2
  11. # Frame Sub-Types
  12. M_ASSOC_REQ = 0
  13. M_ASSOC_RESP = 1
  14. M_REASSOC_REQ = 2
  15. M_REASSOC_RESP = 3
  16. M_PROBE_REQ = 4
  17. M_PROBE_RESP = 5
  18. M_DISASSOC = 10
  19. M_AUTH = 11
  20. M_DEAUTH = 12
  21. M_ACTION = 13
  22. M_BEACON = 8
  23. M_ATIM = 9
  24. C_BLOCK_ACK_REQ = 8
  25. C_BLOCK_ACK = 9
  26. C_PS_POLL = 10
  27. C_RTS = 11
  28. C_CTS = 12
  29. C_ACK = 13
  30. C_CF_END = 14
  31. C_CF_END_ACK = 15
  32. D_NORMAL = 0
  33. D_DATA_CF_ACK = 1
  34. D_DATA_CF_POLL = 2
  35. D_DATA_CF_ACK_POLL = 3
  36. D_NULL = 4
  37. D_CF_ACK = 5
  38. D_CF_POLL = 6
  39. D_CF_ACK_POLL = 7
  40. D_QOS_DATA = 8
  41. D_QOS_CF_ACK = 9
  42. D_QOS_CF_POLL = 10
  43. D_QOS_CF_ACK_POLL = 11
  44. D_QOS_NULL = 12
  45. D_QOS_CF_POLL_EMPTY = 14
  46. TO_DS_FLAG = 10
  47. FROM_DS_FLAG = 1
  48. INTER_DS_FLAG = 11
  49. # Bitshifts for Frame Control
  50. _VERSION_MASK = 0x0300
  51. _TYPE_MASK = 0x0c00
  52. _SUBTYPE_MASK = 0xf000
  53. _TO_DS_MASK = 0x0001
  54. _FROM_DS_MASK = 0x0002
  55. _MORE_FRAG_MASK = 0x0004
  56. _RETRY_MASK = 0x0008
  57. _PWR_MGT_MASK = 0x0010
  58. _MORE_DATA_MASK = 0x0020
  59. _PROTECTED_MASK = 0x0040
  60. _ORDER_MASK = 0x0080
  61. _VERSION_SHIFT = 8
  62. _TYPE_SHIFT = 10
  63. _SUBTYPE_SHIFT = 12
  64. _TO_DS_SHIFT = 0
  65. _FROM_DS_SHIFT = 1
  66. _MORE_FRAG_SHIFT = 2
  67. _RETRY_SHIFT = 3
  68. _PWR_MGT_SHIFT = 4
  69. _MORE_DATA_SHIFT = 5
  70. _PROTECTED_SHIFT = 6
  71. _ORDER_SHIFT = 7
  72. # needed to distinguish subtypes via types
  73. TYPE_FACTORS = [16, 32, 64]
  74. TYPE_FACTOR_PROTECTED = 128
  75. class IEEE80211(pypacker.Packet):
  76. __hdr__ = (
  77. # AAAABBCC | 00000000
  78. # AAAA = subtype BB = type CC = version
  79. ("framectl", "H", 0),
  80. ("duration", "H", 0)
  81. )
  82. def _get_version(self):
  83. return (self.framectl & _VERSION_MASK) >> _VERSION_SHIFT
  84. def _set_version(self, val):
  85. self.framectl = (val << _VERSION_SHIFT) | (self.framectl & ~_VERSION_MASK)
  86. def _get_type(self):
  87. return (self.framectl & _TYPE_MASK) >> _TYPE_SHIFT
  88. def _set_type(self, val):
  89. self.framectl = (val << _TYPE_SHIFT) | (self.framectl & ~_TYPE_MASK)
  90. def _get_subtype(self):
  91. return (self.framectl & _SUBTYPE_MASK) >> _SUBTYPE_SHIFT
  92. def _set_subtype(self, val):
  93. self.framectl = (val << _SUBTYPE_SHIFT) | (self.framectl & ~_SUBTYPE_MASK)
  94. def _get_to_ds(self):
  95. return (self.framectl & _TO_DS_MASK) >> _TO_DS_SHIFT
  96. def _set_to_ds(self, val):
  97. self.framectl = (val << _TO_DS_SHIFT) | (self.framectl & ~_TO_DS_MASK)
  98. def _get_from_ds(self):
  99. return (self.framectl & _FROM_DS_MASK) >> _FROM_DS_SHIFT
  100. def _set_from_ds(self, val):
  101. self.framectl = (val << _FROM_DS_SHIFT) | (self.framectl & ~_FROM_DS_MASK)
  102. def _get_from_to_ds(self):
  103. return (self.framectl & (_TO_DS_MASK | _FROM_DS_MASK))
  104. def _get_more_frag(self):
  105. return (self.framectl & _MORE_FRAG_MASK) >> _MORE_FRAG_SHIFT
  106. def _set_more_frag(self, val):
  107. self.framectl = (val << _MORE_FRAG_SHIFT) | (self.framectl & ~_MORE_FRAG_MASK)
  108. def _get_retry(self):
  109. return (self.framectl & _RETRY_MASK) >> _RETRY_SHIFT
  110. def _set_retry(self, val):
  111. self.framectl = (val << _RETRY_SHIFT) | (self.framectl & ~_RETRY_MASK)
  112. def _get_pwr_mgt(self):
  113. return (self.framectl & _PWR_MGT_MASK) >> _PWR_MGT_SHIFT
  114. def _set_pwr_mgt(self, val):
  115. self.framectl = (val << _PWR_MGT_SHIFT) | (self.framectl & ~_PWR_MGT_MASK)
  116. def _get_more_data(self):
  117. return (self.framectl & _MORE_DATA_MASK) >> _MORE_DATA_SHIFT
  118. def _set_more_data(self, val):
  119. self.framectl = (val << _MORE_DATA_SHIFT) | (self.framectl & ~_MORE_DATA_MASK)
  120. def _get_protected(self):
  121. return (self.framectl & _PROTECTED_MASK) >> _PROTECTED_SHIFT
  122. def _set_protected(self, val):
  123. self.framectl = (val << _PROTECTED_SHIFT) | (self.framectl & ~_PROTECTED_MASK)
  124. def _get_order(self):
  125. return (self.framectl & _ORDER_MASK) >> _ORDER_SHIFT
  126. def _set_order(self, val):
  127. self.framectl = (val << _ORDER_SHIFT) | (self.framectl & ~_ORDER_MASK)
  128. version = property(_get_version, _set_version)
  129. type = property(_get_type, _set_type)
  130. subtype = property(_get_subtype, _set_subtype)
  131. to_ds = property(_get_to_ds, _set_to_ds)
  132. from_ds = property(_get_from_ds, _set_from_ds)
  133. more_frag = property(_get_more_frag, _set_more_frag)
  134. retry = property(_get_retry, _set_retry)
  135. pwr_mgt = property(_get_pwr_mgt, _set_pwr_mgt)
  136. more_data = property(_get_more_data, _set_more_data)
  137. protected = property(_get_protected, _set_protected)
  138. order = property(_get_order, _set_order)
  139. from_to_ds = property(_get_from_to_ds)
  140. def _dissect(self, buf):
  141. self.framectl = struct.unpack(">H", buf[0:2])[0]
  142. # logger.debug("got protected packet, type/sub/prot: %d/%d/%d" %
  143. # (TYPE_FACTORS[self.type], self.subtype, protected_factor))
  144. # logger.debug("ieee80211 type/subtype is: %d/%d" % (self.type, self.subtype))
  145. self._init_handler(TYPE_FACTORS[self.type] + self.subtype, buf[4:])
  146. return 4
  147. #
  148. # mgmt frames
  149. #
  150. class Beacon(pypacker.Packet):
  151. __hdr__ = (
  152. ("dst", "6s", b"\x00" * 6),
  153. ("bssid", "6s", b"\x00" * 6),
  154. ("src", "6s", b"\x00" * 6),
  155. # 12 Bits: 0->4095 | 4 Bits
  156. # SF SS (LE)
  157. ("seq_frag", "H", 0),
  158. # _ts (integer) is saved as LE
  159. ("_ts", "Q", 0),
  160. ("interval", "H", 0x6400),
  161. ("capa", "H", 0x0100),
  162. ("params", None, triggerlist.TriggerList)
  163. )
  164. def _get_seq(self):
  165. return (self.seq_frag & 0xFF) << 4 | (self.seq_frag >> 12)
  166. def _set_seq(self, val):
  167. self.seq_frag = (val & 0xF) << 12 | (val & 0xFF0) >> 4 | (self.seq_frag & 0x0F00)
  168. def _get_ts(self):
  169. # LE->BE: dirty but simple
  170. return struct.unpack("<Q", struct.pack(">Q", self._ts))[0]
  171. def _set_ts(self, val):
  172. self._ts = struct.unpack("<Q", struct.pack(">Q", val))[0]
  173. seq = property(_get_seq, _set_seq)
  174. ts = property(_get_ts, _set_ts)
  175. dst_s = pypacker.get_property_mac("dst")
  176. bssid_s = pypacker.get_property_mac("bssid")
  177. src_s = pypacker.get_property_mac("src")
  178. def _dissect(self, buf):
  179. self._init_triggerlist("params", buf[32:], IEEE80211._unpack_ies)
  180. return len(buf)
  181. def reverse_address(self):
  182. self.dst, self.src = self.src, self.dst
  183. class Action(pypacker.Packet):
  184. __hdr__ = (
  185. ("dst", "6s", b"\x00" * 6),
  186. ("src", "6s", b"\x00" * 6),
  187. ("bssid", "6s", b"\x00" * 6),
  188. ("seq_frag", "H", 0),
  189. ("category", "B", 0),
  190. ("code", "B", 0)
  191. )
  192. class BlockAckRequest(pypacker.Packet):
  193. __hdr__ = (
  194. ("dialog", "B", 0),
  195. ("parameters", "H", 0),
  196. ("timeout", "H", 0),
  197. ("starting_seq", "H", 0),
  198. )
  199. class BlockAckResponse(pypacker.Packet):
  200. __hdr__ = (
  201. ("dialog", "B", 0),
  202. ("status_code", "H", 0),
  203. ("parameters", "H", 0),
  204. ("timeout", "H", 0),
  205. )
  206. CATEGORY_BLOCK_ACK = 3
  207. CODE_BLOCK_ACK_REQUEST = 0
  208. CODE_BLOCK_ACK_RESPONSE = 1
  209. dst_s = pypacker.get_property_mac("dst")
  210. src_s = pypacker.get_property_mac("src")
  211. bssid_s = pypacker.get_property_mac("bssid")
  212. def _dissect(self, buf):
  213. # logger.debug(">>>>>>>> ACTION!!!")
  214. # category: block ack, code: request or response
  215. self._init_handler(buf[20] * 4 + buf[21], buf[22:])
  216. return 22
  217. def reverse_address(self):
  218. self.dst, self.src = self.src, self.dst
  219. class ProbeReq(pypacker.Packet):
  220. __hdr__ = (
  221. ("dst", "6s", b"\x00" * 6),
  222. ("bssid", "6s", b"\x00" * 6),
  223. ("src", "6s", b"\x00" * 6),
  224. ("seq_frag", "H", 0),
  225. ("params", None, triggerlist.TriggerList)
  226. )
  227. dst_s = pypacker.get_property_mac("dst")
  228. bssid_s = pypacker.get_property_mac("bssid")
  229. src_s = pypacker.get_property_mac("src")
  230. def _dissect(self, buf):
  231. self._init_triggerlist("params", buf[20:], IEEE80211._unpack_ies)
  232. return len(buf)
  233. def reverse_address(self):
  234. self.dst, self.src = self.src, self.dst
  235. class ProbeResp(Beacon):
  236. pass
  237. class AssocReq(pypacker.Packet):
  238. __hdr__ = (
  239. ("dst", "6s", b"\x00" * 6),
  240. ("bssid", "6s", b"\x00" * 6),
  241. ("src", "6s", b"\x00" * 6),
  242. ("seq_frag", "H", 0),
  243. ("capa", "H", 0),
  244. ("interval", "H", 0),
  245. ("params", None, triggerlist.TriggerList)
  246. )
  247. dst_s = pypacker.get_property_mac("dst")
  248. bssid_s = pypacker.get_property_mac("bssid")
  249. src_s = pypacker.get_property_mac("src")
  250. def _dissect(self, buf):
  251. self._init_triggerlist("params", buf[24:], IEEE80211._unpack_ies)
  252. return len(buf)
  253. def reverse_address(self):
  254. self.dst, self.src = self.src, self.dst
  255. class AssocResp(pypacker.Packet):
  256. __hdr__ = (
  257. ("dst", "6s", b"\x00" * 6),
  258. ("bssid", "6s", b"\x00" * 6),
  259. ("src", "6s", b"\x00" * 6),
  260. ("seq_frag", "H", 0),
  261. ("capa", "H", 0),
  262. ("status", "H", 0),
  263. ("aid", "H", 0),
  264. ("params", None, triggerlist.TriggerList)
  265. )
  266. dst_s = pypacker.get_property_mac("dst")
  267. bssid_s = pypacker.get_property_mac("bssid")
  268. src_s = pypacker.get_property_mac("src")
  269. def _dissect(self, buf):
  270. self._init_triggerlist("params", buf[26:], IEEE80211._unpack_ies)
  271. return len(buf)
  272. def reverse_address(self):
  273. self.dst, self.src = self.src, self.dst
  274. class Disassoc(pypacker.Packet):
  275. __hdr__ = (
  276. ("dst", "6s", b"\x00" * 6),
  277. ("bssid", "6s", b"\x00" * 6),
  278. ("src", "6s", b"\x00" * 6),
  279. ("seq_frag", "H", 0),
  280. ("reason", "H", 0),
  281. )
  282. dst_s = pypacker.get_property_mac("dst")
  283. bssid_s = pypacker.get_property_mac("bssid")
  284. src_s = pypacker.get_property_mac("src")
  285. def reverse_address(self):
  286. self.dst, self.src = self.src, self.dst
  287. class ReassocReq(pypacker.Packet):
  288. __hdr__ = (
  289. ("dst", "6s", b"\x00" * 6),
  290. ("bssid", "6s", b"\x00" * 6),
  291. ("src", "6s", b"\x00" * 6),
  292. ("seq_frag", "H", 0),
  293. ("capa", "H", 0),
  294. ("interval", "H", 0),
  295. ("current_ap", "6s", b"\x00" * 6)
  296. )
  297. dst_s = pypacker.get_property_mac("dst")
  298. bssid_s = pypacker.get_property_mac("bssid")
  299. src_s = pypacker.get_property_mac("src")
  300. def reverse_address(self):
  301. self.dst, self.src = self.src, self.dst
  302. class Auth(pypacker.Packet):
  303. """Authentication request."""
  304. __hdr__ = (
  305. ("dst", "6s", b"\x00" * 6),
  306. ("src", "6s", b"\x00" * 6),
  307. ("bssid", "6s", b"\x00" * 6),
  308. ("seq_frag", "H", 0),
  309. ("algo", "H", 0),
  310. ("seq", "H", 0x0100),
  311. ("status", "H", 0)
  312. )
  313. dst_s = pypacker.get_property_mac("dst")
  314. bssid_s = pypacker.get_property_mac("bssid")
  315. src_s = pypacker.get_property_mac("src")
  316. def reverse_address(self):
  317. self.dst, self.src = self.src, self.dst
  318. class Deauth(pypacker.Packet):
  319. __hdr__ = (
  320. ("dst", "6s", b"\x00" * 6),
  321. ("bssid", "6s", b"\x00" * 6),
  322. ("src", "6s", b"\x00" * 6),
  323. ("seq_frag", "H", 0),
  324. ("reason", "H", 0)
  325. )
  326. dst_s = pypacker.get_property_mac("dst")
  327. bssid_s = pypacker.get_property_mac("bssid")
  328. src_s = pypacker.get_property_mac("src")
  329. def reverse_address(self):
  330. self.dst, self.src = self.src, self.dst
  331. m_decoder = {
  332. M_BEACON : Beacon,
  333. M_ACTION : Action,
  334. M_ASSOC_REQ : AssocReq,
  335. M_ASSOC_RESP : AssocResp,
  336. M_DISASSOC : Disassoc,
  337. M_REASSOC_REQ : ReassocReq,
  338. M_REASSOC_RESP : AssocResp,
  339. M_AUTH : Auth,
  340. M_PROBE_REQ : ProbeReq,
  341. M_PROBE_RESP : ProbeResp,
  342. M_DEAUTH : Deauth
  343. }
  344. #
  345. # Control frames: no need for extra layer: 802.11 Base data is enough
  346. #
  347. class RTS(pypacker.Packet):
  348. __hdr__ = (
  349. ("dst", "6s", b"\x00" * 6),
  350. ("src", "6s", b"\x00" * 6)
  351. )
  352. dst_s = pypacker.get_property_mac("dst")
  353. src_s = pypacker.get_property_mac("src")
  354. def reverse_address(self):
  355. self.dst, self.src = self.src, self.dst
  356. class CTS(pypacker.Packet):
  357. __hdr__ = (
  358. ("dst", "6s", b"\x00" * 6),
  359. )
  360. dst_s = pypacker.get_property_mac("dst")
  361. class ACK(pypacker.Packet):
  362. __hdr__ = (
  363. ("dst", "6s", b"\x00" * 6),
  364. )
  365. dst_s = pypacker.get_property_mac("dst")
  366. class BlockAckReq(pypacker.Packet):
  367. __hdr__ = (
  368. ("dst", "6s", b"\x00" * 6),
  369. ("src", "6s", b"\x00" * 6),
  370. ("reqctrl", "H", 0),
  371. ("seq", "H", 0)
  372. )
  373. dst_s = pypacker.get_property_mac("dst")
  374. src_s = pypacker.get_property_mac("src")
  375. def reverse_address(self):
  376. self.dst, self.src = self.src, self.dst
  377. class BlockAck(pypacker.Packet):
  378. __hdr__ = (
  379. ("dst", "6s", b"\x00" * 6),
  380. ("src", "6s", b"\x00" * 6),
  381. ("reqctrl", "H", 0),
  382. ("seq", "H", 0),
  383. ("bitmap", "Q", 0)
  384. )
  385. dst_s = pypacker.get_property_mac("dst")
  386. src_s = pypacker.get_property_mac("src")
  387. def reverse_address(self):
  388. self.dst, self.src = self.src, self.dst
  389. class CFEnd(pypacker.Packet):
  390. __hdr__ = (
  391. ("dst", "6s", b"\x00" * 6),
  392. ("src", "6s", b"\x00" * 6),
  393. )
  394. dst_s = pypacker.get_property_mac("dst")
  395. src_s = pypacker.get_property_mac("src")
  396. def reverse_address(self):
  397. self.dst, self.src = self.src, self.dst
  398. c_decoder = {
  399. C_RTS : RTS,
  400. C_CTS : CTS,
  401. C_ACK : ACK,
  402. C_BLOCK_ACK_REQ : BlockAckReq,
  403. C_BLOCK_ACK : BlockAck,
  404. C_CF_END : CFEnd
  405. }
  406. #
  407. # data frames
  408. #
  409. class Dataframe(pypacker.Packet):
  410. """
  411. DataFrames need special care: there are too many types of field combinations to create classes
  412. for every one. Solution: initiate giving lower type "subType" via constructor.
  413. In order to use "src/dst/bssid" instead of addrX set from_to_ds of "subType" to one of the following values:
  414. [Bit 0: from DS][Bit 1: to DS] = [order of fields]
  415. 00 = 0 = dst, src, bssid
  416. 01 = 1 = bssid, src, dst
  417. 10 = 2 = dst, bssid, src
  418. 11 = 3 = RA, TA, DA, SA
  419. """
  420. def __init__(self, *arg, **kwargs):
  421. if len(arg) > 1:
  422. # logger.debug("extracting lower layer type: %r" % arg[1])
  423. self.dtype = arg[1]
  424. else:
  425. self.dtype = self
  426. super().__init__(*arg, **kwargs)
  427. __hdr__ = (
  428. ("addr1", "6s", b"\x00" * 6),
  429. ("addr2", "6s", b"\x00" * 6),
  430. ("addr3", "6s", b"\x00" * 6),
  431. ("seq_frag", "H", 0),
  432. ("addr4", "6s", None), # to/from-DS = 1
  433. ("qos_ctrl", "H", 0), # QoS
  434. ("sec_param", "Q", 0) # protected
  435. )
  436. def reverse_address(self):
  437. if self.dtype.from_to_ds == 0:
  438. self.addr1, self.addr2 = self.addr2, self.addr1
  439. elif self.dtype.from_to_ds == 1:
  440. self.addr2, self.addr3 = self.addr3, self.addr2
  441. elif self.dtype.from_to_ds == 2:
  442. self.addr1, self.addr3 = self.addr3, self.addr1
  443. # FromDs, ToDS
  444. # 00 = dst, src, bssid
  445. # 01 = bssid, src, dst
  446. # 10 = dst, bssid, src
  447. # 11 = RA, TA, DA, SA
  448. def __get_src(self):
  449. return self.addr2 if self.dtype.from_to_ds in [0, 1] else self.addr3
  450. def __set_src(self, src):
  451. if self.dtype.from_to_ds in [0, 1]:
  452. self.addr2 = src
  453. else:
  454. self.addr3 = src
  455. def __get_dst(self):
  456. return self.addr1 if self.dtype.from_to_ds in [0, 2] else self.addr3
  457. def __set_dst(self, dst):
  458. if self.dtype.from_to_ds in [0, 2]:
  459. self.addr1 = dst
  460. else:
  461. self.addr3 = dst
  462. def __get_bssid(self):
  463. dstype = self.dtype.from_to_ds
  464. if dstype == 0:
  465. return self.addr3
  466. elif dstype == 1:
  467. return self.addr1
  468. elif dstype == 2:
  469. return self.addr2
  470. def __set_bssid(self, bssid):
  471. dstype = self.dtype.from_to_ds
  472. if dstype == 0:
  473. self.addr3 = bssid
  474. elif dstype == 1:
  475. self.addr1 = bssid
  476. elif dstype == 2:
  477. self.addr2 = bssid
  478. src = property(__get_src, __set_src)
  479. src_s = pypacker.get_property_mac("src")
  480. dst = property(__get_dst, __set_dst)
  481. dst_s = pypacker.get_property_mac("dst")
  482. bssid = property(__get_bssid, __set_bssid)
  483. bssid_s = pypacker.get_property_mac("bssid")
  484. __QOS_SUBTYPES = set([8, 9, 10, 11, 12, 14, 15])
  485. def _dissect(self, buf):
  486. # logger.debug("starting dissecting, buflen: %r" % str(buf))
  487. header_len = 30
  488. try:
  489. is_qos = True if self.dtype.subtype in IEEE80211.Dataframe.__QOS_SUBTYPES else False
  490. is_protected = self.dtype.protected == 1
  491. is_bridge = True if self.dtype.from_ds == 1 and self.dtype.to_ds == 1 else False
  492. except Exception:
  493. # logger.debug(e)
  494. # default is fromds
  495. is_qos = False
  496. is_protected = False
  497. is_bridge = False
  498. # logger.debug("switching fields1")
  499. if not is_qos:
  500. self.qos_ctrl = None
  501. header_len -= 2
  502. # logger.debug("switching fields2")
  503. if not is_protected:
  504. self.sec_param = None
  505. header_len -= 8
  506. # logger.debug("switching fields3")
  507. if is_bridge:
  508. self.addr4 = b"\x00" * 6
  509. header_len += 6
  510. # logger.debug("format/length/len(bin): %s/%d/%d" % (self._hdr_fmtstr, self.hdr_len, len(self.bin())))
  511. # logger.debug("%r" % self)
  512. return header_len
  513. d_decoder = {
  514. D_NORMAL : Dataframe,
  515. D_DATA_CF_ACK : Dataframe,
  516. D_DATA_CF_POLL : Dataframe,
  517. D_DATA_CF_ACK_POLL : Dataframe,
  518. D_NULL : Dataframe,
  519. D_CF_ACK : Dataframe,
  520. D_CF_POLL : Dataframe,
  521. D_CF_ACK_POLL : Dataframe,
  522. D_QOS_DATA : Dataframe,
  523. D_QOS_CF_ACK : Dataframe,
  524. D_QOS_CF_POLL : Dataframe,
  525. D_QOS_CF_ACK_POLL : Dataframe,
  526. D_QOS_NULL : Dataframe,
  527. D_QOS_CF_POLL_EMPTY : Dataframe
  528. }
  529. #
  530. # IEs for Mgmt-Frames
  531. #
  532. @staticmethod
  533. def _unpack_ies(buf):
  534. """Parse IEs and return them as Triggerlist."""
  535. # each IE starts with an ID and a length
  536. ies = []
  537. off = 0
  538. buflen = len(buf)
  539. # logger.debug("lazy dissecting: %s" % buf)
  540. while off < buflen:
  541. ie_id = buf[off]
  542. try:
  543. parser = IEEE80211.ie_decoder[ie_id]
  544. except KeyError:
  545. # some unknown tag, use standard format
  546. parser = IEEE80211.IE
  547. dlen = buf[off + 1]
  548. # logger.debug("IE parser is: %d = %s = %s" % (ie_id, parser, buf[off: off+2+dlen]))
  549. ie = parser(buf[off: off + 2 + dlen])
  550. ies.append(ie)
  551. off += 2 + dlen
  552. return ies
  553. class IE(pypacker.Packet):
  554. __hdr__ = (
  555. ("id", "B", 0),
  556. ("len", "B", 0)
  557. )
  558. class FH(pypacker.Packet):
  559. __hdr__ = (
  560. ("id", "B", 0),
  561. ("len", "B", 0),
  562. ("tu", "H", 0),
  563. ("hopset", "B", 0),
  564. ("hoppattern", "B", 0),
  565. ("hopindex", "B", 0)
  566. )
  567. class DS(pypacker.Packet):
  568. __hdr__ = (
  569. ("id", "B", 0),
  570. ("len", "B", 0),
  571. ("ch", "B", 0)
  572. )
  573. class CF(pypacker.Packet):
  574. __hdr__ = (
  575. ("id", "B", 0),
  576. ("len", "B", 0),
  577. ("count", "B", 0),
  578. ("period", "B", 0),
  579. ("max", "H", 0),
  580. ("dur", "H", 0)
  581. )
  582. class TIM(pypacker.Packet):
  583. __hdr__ = (
  584. ("id", "B", 0),
  585. ("len", "B", 0),
  586. ("count", "B", 0),
  587. ("period", "B", 0),
  588. ("ctrl", "H", 0)
  589. )
  590. class IBSS(pypacker.Packet):
  591. __hdr__ = (
  592. ("id", "B", 0),
  593. ("len", "B", 0),
  594. ("atim", "H", 0)
  595. )
  596. # IEs
  597. IE_SSID = 0
  598. IE_RATES = 1
  599. IE_FH = 2
  600. IE_DS = 3
  601. IE_CF = 4
  602. IE_TIM = 5
  603. IE_IBSS = 6
  604. IE_HT_CAPA = 45
  605. IE_ESR = 50
  606. IE_HT_INFO = 61
  607. ie_decoder = {
  608. IE_SSID : IE,
  609. IE_RATES : IE,
  610. IE_FH : FH,
  611. IE_DS : DS,
  612. IE_CF : CF,
  613. IE_TIM : TIM,
  614. IE_IBSS : IBSS,
  615. IE_HT_CAPA : IE,
  616. IE_ESR : IE,
  617. IE_HT_INFO : IE
  618. }
  619. # handler for IEEE80211
  620. # position in list = type-ID
  621. dicts = [IEEE80211.m_decoder, IEEE80211.c_decoder, IEEE80211.d_decoder]
  622. decoder_dict_complete = {}
  623. for pos, decoder_dict in enumerate(dicts):
  624. for key, val in decoder_dict.items():
  625. # same subtype-ID for different typ-IDs, distinguish via "type_factor + subtype)"
  626. decoder_dict_complete[TYPE_FACTORS[pos] + key] = val
  627. pypacker.Packet.load_handler(IEEE80211, decoder_dict_complete)
  628. # handler for Action
  629. CATEGORY_BLOCK_ACK_FACTOR = IEEE80211.Action.CATEGORY_BLOCK_ACK * 4
  630. pypacker.Packet.load_handler(IEEE80211.Action,
  631. {
  632. CATEGORY_BLOCK_ACK_FACTOR + IEEE80211.Action.CODE_BLOCK_ACK_REQUEST: IEEE80211.Action.BlockAckRequest,
  633. CATEGORY_BLOCK_ACK_FACTOR + IEEE80211.Action.CODE_BLOCK_ACK_RESPONSE: IEEE80211.Action.BlockAckResponse
  634. }
  635. )