Coverage for /root/GitHubProjects/impacket/impacket/dot11.py : 88%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Impacket - Collection of Python classes for working with network protocols.
2#
3# SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved.
4#
5# This software is provided under a slightly modified version
6# of the Apache Software License. See the accompanying LICENSE file
7# for more information.
8#
9# Description:
10# IEEE 802.11 Network packet codecs.
11#
12# Author:
13# Gustavo Moreira
14#
16import struct
17from binascii import crc32
19from impacket.ImpactPacket import ProtocolPacket, array_tobytes
20from impacket.Dot11Crypto import RC4
21frequency = {
22 2412: 1, 2417: 2, 2422: 3, 2427: 4, 2432: 5, 2437: 6, 2442: 7, 2447: 8, 2452: 9,
23 2457: 10, 2462: 11, 2467: 12, 2472: 13, 2484: 14, 5170: 34, 5180: 36, 5190: 38, 5200: 40,
24 5210: 42, 5220: 44, 5230: 46, 5240: 48, 5260: 52, 5280: 56, 5300: 60, 5320: 64, 5500: 100,
25 5510: 102, 5520: 104, 5530: 106, 5540: 108, 5550: 110, 5560: 112, 5570: 114, 5580: 116, 5590: 118,
26 5600: 120, 5610: 122, 5620: 124, 5630: 126, 5640: 128, 5650: 130, 5660: 132, 5670: 134, 5680: 136,
27 5690: 138, 5700: 140, 5745: 149, 5765: 153, 5785: 157, 5805: 161, 5825: 165, 5855: 170, 5860: 172,
28 5865: 173, 5870: 174, 5875: 175, 5880: 176, 5885: 177, 5890: 178, 5895: 179, 5900: 180, 5905: 181,
29 5910: 182, 5915: 183, 5920: 184,
30}
33class Dot11ManagementCapabilities():
34 #
35 # Capability Information
36 # 0 1 2 3 4 5 6 7 8 9 A B C D E F
37 # +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
38 # | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
39 # +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
40 # | | | | | | | | | | | | | | | |
41 # | | | | | | | | | | | | | | |---+-- Reserved
42 # | | | | | | | | | | | | | |
43 # | | | | | | | | | | | | | |---------- DSSS-OFDM
44 # | | | | | | | | | | | | |
45 # | | | | | | | | | | | |---+-------------- Reserved
46 # | | | | | | | | | | |
47 # | | | | | | | | | | |---------------------- Short slot time
48 # | | | | | | | | | |
49 # | | | | | | | | |---+-------------------------- Reserved
50 # | | | | | | | |
51 # | | | | | | | |---------------------------------- Channel agility (802.11b)
52 # | | | | | | |
53 # | | | | | | |-------------------------------------- PBCC (802.11b)
54 # | | | | | |
55 # | | | | | |------------------------------------------ Short preamble (802.11b)
56 # | | | | |
57 # | | | | |---------------------------------------------- Privacy
58 # | | | |
59 # | | | |-------------------------------------------------- CF-Poll request
60 # | | |
61 # | | |------------------------------------------------------ CF-Pollable
62 # | |
63 # | |---------------------------------------------------------- IBSS
64 # |
65 # |-------------------------------------------------------------- ESS
66 #
67 CAPABILITY_RESERVED_1 = int("1000000000000000", 2)
68 CAPABILITY_RESERVED_2 = int("0100000000000000", 2)
69 CAPABILITY_DSSS_OFDM = int("0010000000000000", 2)
70 CAPABILITY_RESERVED_3 = int("0001000000000000", 2)
71 CAPABILITY_RESERVED_4 = int("0000100000000000", 2)
72 CAPABILITY_SHORT_SLOT_TIME = int("0000010000000000", 2)
73 CAPABILITY_RESERVED_5 = int("0000001000000000", 2)
74 CAPABILITY_RESERVED_6 = int("0000000100000000", 2)
75 CAPABILITY_CH_AGILITY = int("0000000010000000", 2)
76 CAPABILITY_PBCC = int("0000000001000000", 2)
77 CAPABILITY_SHORT_PREAMBLE = int("0000000000100000", 2)
78 CAPABILITY_PRIVACY = int("0000000000010000", 2)
79 CAPABILITY_CF_POLL_REQ = int("0000000000001000", 2)
80 CAPABILITY_CF_POLLABLE = int("0000000000000100", 2)
81 CAPABILITY_IBSS = int("0000000000000010", 2)
82 CAPABILITY_ESS = int("0000000000000001", 2)
84class Dot11Types():
85 # Management Types/SubTypes
86 DOT11_TYPE_MANAGEMENT = int("00",2)
87 DOT11_SUBTYPE_MANAGEMENT_ASSOCIATION_REQUEST = int("0000",2)
88 DOT11_SUBTYPE_MANAGEMENT_ASSOCIATION_RESPONSE = int("0001",2)
89 DOT11_SUBTYPE_MANAGEMENT_REASSOCIATION_REQUEST = int("0010",2)
90 DOT11_SUBTYPE_MANAGEMENT_REASSOCIATION_RESPONSE = int("0011",2)
91 DOT11_SUBTYPE_MANAGEMENT_PROBE_REQUEST = int("0100",2)
92 DOT11_SUBTYPE_MANAGEMENT_PROBE_RESPONSE = int("0101",2)
93 DOT11_SUBTYPE_MANAGEMENT_RESERVED1 = int("0110",2)
94 DOT11_SUBTYPE_MANAGEMENT_RESERVED2 = int("0111",2)
95 DOT11_SUBTYPE_MANAGEMENT_BEACON = int("1000",2)
96 DOT11_SUBTYPE_MANAGEMENT_ATIM = int("1001",2)
97 DOT11_SUBTYPE_MANAGEMENT_DISASSOCIATION = int("1010",2)
98 DOT11_SUBTYPE_MANAGEMENT_AUTHENTICATION = int("1011",2)
99 DOT11_SUBTYPE_MANAGEMENT_DEAUTHENTICATION = int("1100",2)
100 DOT11_SUBTYPE_MANAGEMENT_ACTION = int("1101",2)
101 DOT11_SUBTYPE_MANAGEMENT_RESERVED3 = int("1110",2)
102 DOT11_SUBTYPE_MANAGEMENT_RESERVED4 = int("1111",2)
104 DOT11_TYPE_MANAGEMENT_SUBTYPE_ASSOCIATION_REQUEST = \
105 DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_ASSOCIATION_REQUEST<<2
106 DOT11_TYPE_MANAGEMENT_SUBTYPE_ASSOCIATION_RESPONSE = \
107 DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_ASSOCIATION_RESPONSE<<2
108 DOT11_TYPE_MANAGEMENT_SUBTYPE_REASSOCIATION_REQUEST = \
109 DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_REASSOCIATION_REQUEST<<2
110 DOT11_TYPE_MANAGEMENT_SUBTYPE_REASSOCIATION_RESPONSE = \
111 DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_REASSOCIATION_RESPONSE<<2
112 DOT11_TYPE_MANAGEMENT_SUBTYPE_PROBE_REQUEST = \
113 DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_PROBE_REQUEST<<2
114 DOT11_TYPE_MANAGEMENT_SUBTYPE_PROBE_RESPONSE = \
115 DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_PROBE_RESPONSE<<2
116 DOT11_TYPE_MANAGEMENT_SUBTYPE_RESERVED1 = \
117 DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_RESERVED1<<2
118 DOT11_TYPE_MANAGEMENT_SUBTYPE_RESERVED2 = \
119 DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_RESERVED2<<2
120 DOT11_TYPE_MANAGEMENT_SUBTYPE_BEACON = \
121 DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_BEACON<<2
122 DOT11_TYPE_MANAGEMENT_SUBTYPE_ATIM = \
123 DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_ATIM<<2
124 DOT11_TYPE_MANAGEMENT_SUBTYPE_DISASSOCIATION = \
125 DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_DISASSOCIATION<<2
126 DOT11_TYPE_MANAGEMENT_SUBTYPE_AUTHENTICATION = \
127 DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_AUTHENTICATION<<2
128 DOT11_TYPE_MANAGEMENT_SUBTYPE_DEAUTHENTICATION = \
129 DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_DEAUTHENTICATION<<2
130 DOT11_TYPE_MANAGEMENT_SUBTYPE_ACTION = \
131 DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_ACTION<<2
132 DOT11_TYPE_MANAGEMENT_SUBTYPE_RESERVED3 = \
133 DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_RESERVED3<<2
134 DOT11_TYPE_MANAGEMENT_SUBTYPE_RESERVED4 = \
135 DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_RESERVED4<<2
137 # Control Types/SubTypes
138 DOT11_TYPE_CONTROL = int("01",2)
139 DOT11_SUBTYPE_CONTROL_RESERVED1 = int("0000",2)
140 DOT11_SUBTYPE_CONTROL_RESERVED2 = int("0001",2)
141 DOT11_SUBTYPE_CONTROL_RESERVED3 = int("0010",2)
142 DOT11_SUBTYPE_CONTROL_RESERVED4 = int("0011",2)
143 DOT11_SUBTYPE_CONTROL_RESERVED5 = int("0100",2)
144 DOT11_SUBTYPE_CONTROL_RESERVED6 = int("0101",2)
145 DOT11_SUBTYPE_CONTROL_RESERVED7 = int("0110",2)
146 DOT11_SUBTYPE_CONTROL_RESERVED8 = int("0111",2)
147 DOT11_SUBTYPE_CONTROL_BLOCK_ACK_REQUEST = int("1000",2)
148 DOT11_SUBTYPE_CONTROL_BLOCK_ACK = int("1001",2)
149 DOT11_SUBTYPE_CONTROL_POWERSAVE_POLL = int("1010",2)
150 DOT11_SUBTYPE_CONTROL_REQUEST_TO_SEND = int("1011",2)
151 DOT11_SUBTYPE_CONTROL_CLEAR_TO_SEND = int("1100",2)
152 DOT11_SUBTYPE_CONTROL_ACKNOWLEDGMENT = int("1101",2)
153 DOT11_SUBTYPE_CONTROL_CF_END = int("1110",2)
154 DOT11_SUBTYPE_CONTROL_CF_END_CF_ACK = int("1111",2)
156 DOT11_TYPE_CONTROL_SUBTYPE_RESERVED1 = \
157 DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_RESERVED1<<2
158 DOT11_TYPE_CONTROL_SUBTYPE_RESERVED2 = \
159 DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_RESERVED2<<2
160 DOT11_TYPE_CONTROL_SUBTYPE_RESERVED3 = \
161 DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_RESERVED3<<2
162 DOT11_TYPE_CONTROL_SUBTYPE_RESERVED4 = \
163 DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_RESERVED4<<2
164 DOT11_TYPE_CONTROL_SUBTYPE_RESERVED5 = \
165 DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_RESERVED5<<2
166 DOT11_TYPE_CONTROL_SUBTYPE_RESERVED6 = \
167 DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_RESERVED6<<2
168 DOT11_TYPE_CONTROL_SUBTYPE_RESERVED7 = \
169 DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_RESERVED7<<2
170 DOT11_TYPE_CONTROL_SUBTYPE_BLOCK_ACK_REQUEST = \
171 DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_BLOCK_ACK_REQUEST<<2
172 DOT11_TYPE_CONTROL_SUBTYPE_BLOCK_ACK = \
173 DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_BLOCK_ACK<<2
174 DOT11_TYPE_CONTROL_SUBTYPE_POWERSAVE_POLL = \
175 DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_POWERSAVE_POLL<<2
176 DOT11_TYPE_CONTROL_SUBTYPE_REQUEST_TO_SEND = \
177 DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_REQUEST_TO_SEND<<2
178 DOT11_TYPE_CONTROL_SUBTYPE_CLEAR_TO_SEND = \
179 DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_CLEAR_TO_SEND<<2
180 DOT11_TYPE_CONTROL_SUBTYPE_ACKNOWLEDGMENT = \
181 DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_ACKNOWLEDGMENT<<2
182 DOT11_TYPE_CONTROL_SUBTYPE_CF_END = \
183 DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_CF_END<<2
184 DOT11_TYPE_CONTROL_SUBTYPE_CF_END_CF_ACK = \
185 DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_CF_END_CF_ACK<<2
187 # Data Types/SubTypes
188 DOT11_TYPE_DATA = int("10",2)
189 DOT11_SUBTYPE_DATA = int("0000",2)
190 DOT11_SUBTYPE_DATA_CF_ACK = int("0001",2)
191 DOT11_SUBTYPE_DATA_CF_POLL = int("0010",2)
192 DOT11_SUBTYPE_DATA_CF_ACK_CF_POLL = int("0011",2)
193 DOT11_SUBTYPE_DATA_NULL_NO_DATA = int("0100",2)
194 DOT11_SUBTYPE_DATA_CF_ACK_NO_DATA = int("0101",2)
195 DOT11_SUBTYPE_DATA_CF_POLL_NO_DATA = int("0110",2)
196 DOT11_SUBTYPE_DATA_CF_ACK_CF_POLL_NO_DATA = int("0111",2)
197 DOT11_SUBTYPE_DATA_QOS_DATA = int("1000",2)
198 DOT11_SUBTYPE_DATA_QOS_DATA_CF_ACK = int("1001",2)
199 DOT11_SUBTYPE_DATA_QOS_DATA_CF_POLL = int("1010",2)
200 DOT11_SUBTYPE_DATA_QOS_DATA_CF_ACK_CF_POLL = int("1011",2)
201 DOT11_SUBTYPE_DATA_QOS_NULL_NO_DATA = int("1100",2)
202 DOT11_SUBTYPE_DATA_RESERVED1 = int("1101",2)
203 DOT11_SUBTYPE_DATA_QOS_CF_POLL_NO_DATA = int("1110",2)
204 DOT11_SUBTYPE_DATA_QOS_CF_ACK_CF_POLL_NO_DATA = int("1111",2)
206 DOT11_TYPE_DATA_SUBTYPE_DATA = \
207 DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA<<2
208 DOT11_TYPE_DATA_SUBTYPE_CF_ACK = \
209 DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_CF_ACK<<2
210 DOT11_TYPE_DATA_SUBTYPE_CF_POLL = \
211 DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_CF_POLL<<2
212 DOT11_TYPE_DATA_SUBTYPE_CF_ACK_CF_POLL = \
213 DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_CF_ACK_CF_POLL<<2
214 DOT11_TYPE_DATA_SUBTYPE_NULL_NO_DATA = \
215 DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_NULL_NO_DATA<<2
216 DOT11_TYPE_DATA_SUBTYPE_CF_ACK_NO_DATA = \
217 DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_CF_POLL_NO_DATA<<2
218 DOT11_TYPE_DATA_SUBTYPE_CF_ACK_CF_POLL_NO_DATA = \
219 DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_CF_ACK_CF_POLL_NO_DATA<<2
220 DOT11_TYPE_DATA_SUBTYPE_QOS_DATA = \
221 DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_QOS_DATA<<2
222 DOT11_TYPE_DATA_SUBTYPE_QOS_DATA_CF_ACK = \
223 DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_QOS_DATA_CF_ACK<<2
224 DOT11_TYPE_DATA_SUBTYPE_QOS_DATA_CF_POLL = \
225 DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_QOS_DATA_CF_POLL<<2
226 DOT11_TYPE_DATA_SUBTYPE_QOS_DATA_CF_ACK_CF_POLL = \
227 DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_QOS_DATA_CF_ACK_CF_POLL<<2
228 DOT11_TYPE_DATA_SUBTYPE_QOS_NULL_NO_DATA = \
229 DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_QOS_NULL_NO_DATA<<2
230 DOT11_TYPE_DATA_SUBTYPE_RESERVED1 = \
231 DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_RESERVED1<<2
232 DOT11_TYPE_DATA_SUBTYPE_QOS_CF_POLL_NO_DATA = \
233 DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_QOS_CF_POLL_NO_DATA<<2
234 DOT11_TYPE_DATA_SUBTYPE_QOS_CF_ACK_CF_POLL_NO_DATA = \
235 DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_QOS_CF_ACK_CF_POLL_NO_DATA<<2
237 # Reserved Types/SubTypes
238 DOT11_TYPE_RESERVED = int("11",2)
239 DOT11_SUBTYPE_RESERVED_RESERVED1 = int("0000",2)
240 DOT11_SUBTYPE_RESERVED_RESERVED2 = int("0001",2)
241 DOT11_SUBTYPE_RESERVED_RESERVED3 = int("0010",2)
242 DOT11_SUBTYPE_RESERVED_RESERVED4 = int("0011",2)
243 DOT11_SUBTYPE_RESERVED_RESERVED5 = int("0100",2)
244 DOT11_SUBTYPE_RESERVED_RESERVED6 = int("0101",2)
245 DOT11_SUBTYPE_RESERVED_RESERVED7 = int("0110",2)
246 DOT11_SUBTYPE_RESERVED_RESERVED8 = int("0111",2)
247 DOT11_SUBTYPE_RESERVED_RESERVED9 = int("1000",2)
248 DOT11_SUBTYPE_RESERVED_RESERVED10 = int("1001",2)
249 DOT11_SUBTYPE_RESERVED_RESERVED11 = int("1010",2)
250 DOT11_SUBTYPE_RESERVED_RESERVED12 = int("1011",2)
251 DOT11_SUBTYPE_RESERVED_RESERVED13 = int("1100",2)
252 DOT11_SUBTYPE_RESERVED_RESERVED14 = int("1101",2)
253 DOT11_SUBTYPE_RESERVED_RESERVED15 = int("1110",2)
254 DOT11_SUBTYPE_RESERVED_RESERVED16 = int("1111",2)
256 DOT11_TYPE_RESERVED_SUBTYPE_RESERVED1 = \
257 DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED1<<2
258 DOT11_TYPE_RESERVED_SUBTYPE_RESERVED2 = \
259 DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED2<<2
260 DOT11_TYPE_RESERVED_SUBTYPE_RESERVED3 = \
261 DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED3<<2
262 DOT11_TYPE_RESERVED_SUBTYPE_RESERVED4 = \
263 DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED4<<2
264 DOT11_TYPE_RESERVED_SUBTYPE_RESERVED5 = \
265 DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED5<<2
266 DOT11_TYPE_RESERVED_SUBTYPE_RESERVED6 = \
267 DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED6<<2
268 DOT11_TYPE_RESERVED_SUBTYPE_RESERVED7 = \
269 DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED7<<2
270 DOT11_TYPE_RESERVED_SUBTYPE_RESERVED8 = \
271 DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED8<<2
272 DOT11_TYPE_RESERVED_SUBTYPE_RESERVED9 = \
273 DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED9<<2
274 DOT11_TYPE_RESERVED_SUBTYPE_RESERVED10 = \
275 DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED10<<2
276 DOT11_TYPE_RESERVED_SUBTYPE_RESERVED11 = \
277 DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED11<<2
278 DOT11_TYPE_RESERVED_SUBTYPE_RESERVED12 = \
279 DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED12<<2
280 DOT11_TYPE_RESERVED_SUBTYPE_RESERVED13 = \
281 DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED13<<2
282 DOT11_TYPE_RESERVED_SUBTYPE_RESERVED14 = \
283 DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED14<<2
284 DOT11_TYPE_RESERVED_SUBTYPE_RESERVED15 = \
285 DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED15<<2
286 DOT11_TYPE_RESERVED_SUBTYPE_RESERVED16 = \
287 DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED16<<2
289class Dot11(ProtocolPacket):
290 def __init__(self, aBuffer = None, FCS_at_end = True):
291 header_size = 2
292 self.__FCS_at_end=not not FCS_at_end # Is Boolean
293 if self.__FCS_at_end:
294 tail_size = 4
295 else:
296 tail_size = 0
298 ProtocolPacket.__init__(self, header_size,tail_size)
299 if(aBuffer):
300 self.load_packet(aBuffer)
302 def get_order(self):
303 "Return 802.11 frame 'Order' field"
304 b = self.header.get_byte(1)
305 return ((b >> 7) & 0x01)
307 def set_order(self, value):
308 "Set 802.11 frame 'Order' field"
309 # clear the bits
310 mask = (~0x80) & 0xFF
311 masked = self.header.get_byte(1) & mask
312 # set the bits
313 nb = masked | ((value & 0x01) << 7)
314 self.header.set_byte(1, nb)
316 def get_protectedFrame(self):
317 "Return 802.11 frame 'Protected' field"
318 b = self.header.get_byte(1)
319 return ((b >> 6) & 0x01)
321 def set_protectedFrame(self, value):
322 "Set 802.11 frame 'Protected Frame' field"
323 # clear the bits
324 mask = (~0x40) & 0xFF
325 masked = self.header.get_byte(1) & mask
326 # set the bits
327 nb = masked | ((value & 0x01) << 6)
328 self.header.set_byte(1, nb)
330 def get_moreData(self):
331 "Return 802.11 frame 'More Data' field"
332 b = self.header.get_byte(1)
333 return ((b >> 5) & 0x01)
335 def set_moreData(self, value):
336 "Set 802.11 frame 'More Data' field"
337 # clear the bits
338 mask = (~0x20) & 0xFF
339 masked = self.header.get_byte(1) & mask
340 # set the bits
341 nb = masked | ((value & 0x01) << 5)
342 self.header.set_byte(1, nb)
344 def get_powerManagement(self):
345 "Return 802.11 frame 'Power Management' field"
346 b = self.header.get_byte(1)
347 return ((b >> 4) & 0x01)
349 def set_powerManagement(self, value):
350 "Set 802.11 frame 'Power Management' field"
351 # clear the bits
352 mask = (~0x10) & 0xFF
353 masked = self.header.get_byte(1) & mask
354 # set the bits
355 nb = masked | ((value & 0x01) << 4)
356 self.header.set_byte(1, nb)
358 def get_retry(self):
359 "Return 802.11 frame 'Retry' field"
360 b = self.header.get_byte(1)
361 return ((b >> 3) & 0x01)
363 def set_retry(self, value):
364 "Set 802.11 frame 'Retry' field"
365 # clear the bits
366 mask = (~0x08) & 0xFF
367 masked = self.header.get_byte(1) & mask
368 # set the bits
369 nb = masked | ((value & 0x01) << 3)
370 self.header.set_byte(1, nb)
372 def get_moreFrag(self):
373 "Return 802.11 frame 'More Fragments' field"
374 b = self.header.get_byte(1)
375 return ((b >> 2) & 0x01)
377 def set_moreFrag(self, value):
378 "Set 802.11 frame 'More Fragments' field"
379 # clear the bits
380 mask = (~0x04) & 0xFF
381 masked = self.header.get_byte(1) & mask
382 # set the bits
383 nb = masked | ((value & 0x01) << 2)
384 self.header.set_byte(1, nb)
386 def get_fromDS(self):
387 "Return 802.11 frame 'from DS' field"
388 b = self.header.get_byte(1)
389 return ((b >> 1) & 0x01)
391 def set_fromDS(self, value):
392 "Set 802.11 frame 'from DS' field"
393 # clear the bits
394 mask = (~0x02) & 0xFF
395 masked = self.header.get_byte(1) & mask
396 # set the bits
397 nb = masked | ((value & 0x01) << 1)
398 self.header.set_byte(1, nb)
400 def get_toDS(self):
401 "Return 802.11 frame 'to DS' field"
402 b = self.header.get_byte(1)
403 return (b & 0x01)
405 def set_toDS(self, value):
406 "Set 802.11 frame 'to DS' field"
407 # clear the bits
408 mask = (~0x01) & 0xFF
409 masked = self.header.get_byte(1) & mask
410 # set the bits
411 nb = masked | (value & 0x01)
412 self.header.set_byte(1, nb)
414 def get_subtype(self):
415 "Return 802.11 frame 'subtype' field"
416 b = self.header.get_byte(0)
417 return ((b >> 4) & 0x0F)
419 def set_subtype(self, value):
420 "Set 802.11 frame 'subtype' field"
421 # clear the bits
422 mask = (~0xF0)&0xFF
423 masked = self.header.get_byte(0) & mask
424 # set the bits
425 nb = masked | ((value << 4) & 0xF0)
426 self.header.set_byte(0, nb)
428 def get_type(self):
429 "Return 802.11 frame 'type' field"
430 b = self.header.get_byte(0)
431 return ((b >> 2) & 0x03)
433 def set_type(self, value):
434 "Set 802.11 frame 'type' field"
435 # clear the bits
436 mask = (~0x0C)&0xFF
437 masked = self.header.get_byte(0) & mask
438 # set the bits
439 nb = masked | ((value << 2) & 0x0C)
440 self.header.set_byte(0, nb)
442 def get_type_n_subtype(self):
443 "Return 802.11 frame 'Type and Subtype' field"
444 b = self.header.get_byte(0)
445 return ((b >> 2) & 0x3F)
447 def set_type_n_subtype(self, value):
448 "Set 802.11 frame 'Type and Subtype' field"
449 # clear the bits
450 mask = (~0xFC)&0xFF
451 masked = self.header.get_byte(0) & mask
452 # set the bits
453 nb = masked | ((value << 2) & 0xFC)
454 self.header.set_byte(0, nb)
456 def get_version(self):
457 "Return 802.11 frame control 'Protocol version' field"
458 b = self.header.get_byte(0)
459 return (b & 0x03)
461 def set_version(self, value):
462 "Set the 802.11 frame control 'Protocol version' field"
463 # clear the bits
464 mask = (~0x03)&0xFF
465 masked = self.header.get_byte(0) & mask
466 # set the bits
467 nb = masked | (value & 0x03)
468 self.header.set_byte(0, nb)
470 def compute_checksum(self,bytes):
471 crcle=crc32(bytes)&0xffffffff
472 # ggrr this crc32 is in little endian, convert it to big endian
473 crc=struct.pack('<L', crcle)
474 # Convert to long
475 (crc_long,) = struct.unpack('!L', crc)
476 return crc_long
478 def is_QoS_frame(self):
479 "Return 'True' if is an QoS data frame type"
481 b = self.header.get_byte(0)
482 return (b & 0x80) and True
484 def is_no_framebody_frame(self):
485 "Return 'True' if it frame contain no Frame Body"
487 b = self.header.get_byte(0)
488 return (b & 0x40) and True
490 def is_cf_poll_frame(self):
491 "Return 'True' if it frame is a CF_POLL frame"
493 b = self.header.get_byte(0)
494 return (b & 0x20) and True
496 def is_cf_ack_frame(self):
497 "Return 'True' if it frame is a CF_ACK frame"
499 b = self.header.get_byte(0)
500 return (b & 0x10) and True
502 def get_fcs(self):
503 "Return 802.11 'FCS' field"
505 if not self.__FCS_at_end:
506 return None
508 b = self.tail.get_long(-4, ">")
509 return b
511 def set_fcs(self, value = None):
512 "Set the 802.11 CTS control frame 'FCS' field. If value is None, is auto_checksum"
514 if not self.__FCS_at_end:
515 return
517 # calculate the FCS
518 if value is None:
519 payload = self.get_body_as_string()
520 crc32=self.compute_checksum(payload)
521 value=crc32
523 # set the bits
524 nb = value & 0xFFFFFFFF
525 self.tail.set_long(-4, nb)
527class Dot11ControlFrameCTS(ProtocolPacket):
528 "802.11 Clear-To-Send Control Frame"
530 def __init__(self, aBuffer = None):
531 header_size = 8
532 tail_size = 0
534 ProtocolPacket.__init__(self, header_size, tail_size)
535 if(aBuffer): 535 ↛ exitline 535 didn't return from function '__init__', because the condition on line 535 was never false
536 self.load_packet(aBuffer)
538 def get_duration(self):
539 "Return 802.11 CTS control frame 'Duration' field"
540 b = self.header.get_word(0, "<")
541 return b
543 def set_duration(self, value):
544 "Set the 802.11 CTS control frame 'Duration' field"
545 # set the bits
546 nb = value & 0xFFFF
547 self.header.set_word(0, nb, "<")
549 def get_ra(self):
550 "Return 802.11 CTS control frame 48 bit 'Receiver Address' field as a 6 bytes array"
551 return self.header.get_bytes()[2:8]
553 def set_ra(self, value):
554 "Set 802.11 CTS control frame 48 bit 'Receiver Address' field as a 6 bytes array"
555 for i in range(0, 6):
556 self.header.set_byte(2+i, value[i])
558class Dot11ControlFrameACK(ProtocolPacket):
559 "802.11 Acknowledgement Control Frame"
561 def __init__(self, aBuffer = None):
562 header_size = 8
563 tail_size = 0
565 ProtocolPacket.__init__(self, header_size, tail_size)
566 if(aBuffer): 566 ↛ exitline 566 didn't return from function '__init__', because the condition on line 566 was never false
567 self.load_packet(aBuffer)
569 def get_duration(self):
570 "Return 802.11 ACK control frame 'Duration' field"
571 b = self.header.get_word(0, "<")
572 return b
574 def set_duration(self, value):
575 "Set the 802.11 ACK control frame 'Duration' field"
576 # set the bits
577 nb = value & 0xFFFF
578 self.header.set_word(0, nb, "<")
580 def get_ra(self):
581 "Return 802.11 ACK control frame 48 bit 'Receiver Address' field as a 6 bytes array"
582 return self.header.get_bytes()[2:8]
584 def set_ra(self, value):
585 "Set 802.11 ACK control frame 48 bit 'Receiver Address' field as a 6 bytes array"
586 for i in range(0, 6):
587 self.header.set_byte(2+i, value[i])
589class Dot11ControlFrameRTS(ProtocolPacket):
590 "802.11 Request-To-Send Control Frame"
592 def __init__(self, aBuffer = None):
593 header_size = 14
594 tail_size = 0
596 ProtocolPacket.__init__(self, header_size, tail_size)
597 if(aBuffer): 597 ↛ exitline 597 didn't return from function '__init__', because the condition on line 597 was never false
598 self.load_packet(aBuffer)
600 def get_duration(self):
601 "Return 802.11 RTS control frame 'Duration' field"
602 b = self.header.get_word(0, "<")
603 return b
605 def set_duration(self, value):
606 "Set the 802.11 RTS control frame 'Duration' field"
607 # set the bits
608 nb = value & 0xFFFF
609 self.header.set_word(0, nb, "<")
611 def get_ra(self):
612 "Return 802.11 RTS control frame 48 bit 'Receiver Address' field as a 6 bytes array"
613 return self.header.get_bytes()[2:8]
615 def set_ra(self, value):
616 "Set 802.11 RTS control frame 48 bit 'Receiver Address' field as a 6 bytes array"
617 for i in range(0, 6):
618 self.header.set_byte(2+i, value[i])
620 def get_ta(self):
621 "Return 802.11 RTS control frame 48 bit 'Transmitter Address' field as a 6 bytes array"
622 return self.header.get_bytes()[8:14]
624 def set_ta(self, value):
625 "Set 802.11 RTS control frame 48 bit 'Transmitter Address' field as a 6 bytes array"
626 for i in range(0, 6):
627 self.header.set_byte(8+i, value[i])
629class Dot11ControlFramePSPoll(ProtocolPacket):
630 "802.11 Power-Save Poll Control Frame"
632 def __init__(self, aBuffer = None):
633 header_size = 14
634 tail_size = 0
636 ProtocolPacket.__init__(self, header_size, tail_size)
637 if(aBuffer): 637 ↛ exitline 637 didn't return from function '__init__', because the condition on line 637 was never false
638 self.load_packet(aBuffer)
640 def get_aid(self):
641 "Return 802.11 PSPoll control frame 'AID' field"
642 # the spec says "The AID value always has its two MSBs each set to 1."
643 # TODO: Should we do check/modify it? Wireshark shows the only MSB to 0
644 b = self.header.get_word(0, "<")
645 return b
647 def set_aid(self, value):
648 "Set the 802.11 PSPoll control frame 'AID' field"
649 # set the bits
650 nb = value & 0xFFFF
651 # the spec says "The AID value always has its two MSBs each set to 1."
652 # TODO: Should we do check/modify it? Wireshark shows the only MSB to 0
653 self.header.set_word(0, nb, "<")
655 def get_bssid(self):
656 "Return 802.11 PSPoll control frame 48 bit 'BSS ID' field as a 6 bytes array"
657 return self.header.get_bytes()[2:8]
659 def set_bssid(self, value):
660 "Set 802.11 PSPoll control frame 48 bit 'BSS ID' field as a 6 bytes array"
661 for i in range(0, 6):
662 self.header.set_byte(2+i, value[i])
664 def get_ta(self):
665 "Return 802.11 PSPoll control frame 48 bit 'Transmitter Address' field as a 6 bytes array"
666 return self.header.get_bytes()[8:14]
668 def set_ta(self, value):
669 "Set 802.11 PSPoll control frame 48 bit 'Transmitter Address' field as a 6 bytes array"
670 for i in range(0, 6):
671 self.header.set_byte(8+i, value[i])
673class Dot11ControlFrameCFEnd(ProtocolPacket):
674 "802.11 'Contention Free End' Control Frame"
676 def __init__(self, aBuffer = None):
677 header_size = 14
678 tail_size = 0
680 ProtocolPacket.__init__(self, header_size, tail_size)
681 if(aBuffer): 681 ↛ exitline 681 didn't return from function '__init__', because the condition on line 681 was never false
682 self.load_packet(aBuffer)
684 def get_duration(self):
685 "Return 802.11 CF-End control frame 'Duration' field"
686 b = self.header.get_word(0, "<")
687 return b
689 def set_duration(self, value):
690 "Set the 802.11 CF-End control frame 'Duration' field"
691 # set the bits
692 nb = value & 0xFFFF
693 self.header.set_word(0, nb, "<")
695 def get_ra(self):
696 "Return 802.11 CF-End control frame 48 bit 'Receiver Address' field as a 6 bytes array"
697 return self.header.get_bytes()[2:8]
699 def set_ra(self, value):
700 "Set 802.11 CF-End control frame 48 bit 'Receiver Address' field as a 6 bytes array"
701 for i in range(0, 6):
702 self.header.set_byte(2+i, value[i])
704 def get_bssid(self):
705 "Return 802.11 CF-End control frame 48 bit 'BSS ID' field as a 6 bytes array"
706 return self.header.get_bytes()[8:14]
708 def set_bssid(self, value):
709 "Set 802.11 CF-End control frame 48 bit 'BSS ID' field as a 6 bytes array"
710 for i in range(0, 6):
711 self.header.set_byte(8+i, value[i])
713class Dot11ControlFrameCFEndCFACK(ProtocolPacket):
714 '802.11 \'CF-End + CF-ACK\' Control Frame'
716 def __init__(self, aBuffer = None):
717 header_size = 14
718 tail_size = 0
720 ProtocolPacket.__init__(self, header_size, tail_size)
721 if(aBuffer): 721 ↛ exitline 721 didn't return from function '__init__', because the condition on line 721 was never false
722 self.load_packet(aBuffer)
724 def get_duration(self):
725 'Return 802.11 \'CF-End+CF-ACK\' control frame \'Duration\' field'
726 b = self.header.get_word(0, "<")
727 return b
729 def set_duration(self, value):
730 'Set the 802.11 \'CF-End+CF-ACK\' control frame \'Duration\' field'
731 # set the bits
732 nb = value & 0xFFFF
733 self.header.set_word(0, nb, "<")
735 def get_ra(self):
736 'Return 802.11 \'CF-End+CF-ACK\' control frame 48 bit \'Receiver Address\' field as a 6 bytes array'
737 return self.header.get_bytes()[2:8]
739 def set_ra(self, value):
740 'Set 802.11 \'CF-End+CF-ACK\' control frame 48 bit \'Receiver Address\' field as a 6 bytes array'
741 for i in range(0, 6):
742 self.header.set_byte(2+i, value[i])
744 def get_bssid(self):
745 'Return 802.11 \'CF-End+CF-ACK\' control frame 48 bit \'BSS ID\' field as a 6 bytes array'
746 return self.header.get_bytes()[8:16]
748 def set_bssid(self, value):
749 'Set 802.11 \'CF-End+CF-ACK\' control frame 48 bit \'BSS ID\' field as a 6 bytes array'
750 for i in range(0, 6):
751 self.header.set_byte(8+i, value[i])
753class Dot11DataFrame(ProtocolPacket):
754 '802.11 Data Frame'
756 def __init__(self, aBuffer = None):
757 header_size = 22
758 tail_size = 0
760 ProtocolPacket.__init__(self, header_size, tail_size)
761 if(aBuffer):
762 self.load_packet(aBuffer)
764 def get_duration(self):
765 'Return 802.11 \'Data\' data frame \'Duration\' field'
766 b = self.header.get_word(0, "<")
767 return b
769 def set_duration(self, value):
770 'Set the 802.11 \'Data\' data frame \'Duration\' field'
771 # set the bits
772 nb = value & 0xFFFF
773 self.header.set_word(0, nb, "<")
775 def get_address1(self):
776 'Return 802.11 \'Data\' data frame 48 bit \'Address1\' field as a 6 bytes array'
777 return self.header.get_bytes()[2:8]
779 def set_address1(self, value):
780 'Set 802.11 \'Data\' data frame 48 bit \'Address1\' field as a 6 bytes array'
781 for i in range(0, 6):
782 self.header.set_byte(2+i, value[i])
784 def get_address2(self):
785 'Return 802.11 \'Data\' data frame 48 bit \'Address2\' field as a 6 bytes array'
786 return self.header.get_bytes()[8:14]
788 def set_address2(self, value):
789 'Set 802.11 \'Data\' data frame 48 bit \'Address2\' field as a 6 bytes array'
790 for i in range(0, 6):
791 self.header.set_byte(8+i, value[i])
793 def get_address3(self):
794 'Return 802.11 \'Data\' data frame 48 bit \'Address3\' field as a 6 bytes array'
795 return self.header.get_bytes()[14: 20]
797 def set_address3(self, value):
798 'Set 802.11 \'Data\' data frame 48 bit \'Address3\' field as a 6 bytes array'
799 for i in range(0, 6):
800 self.header.set_byte(14+i, value[i])
802 def get_sequence_control(self):
803 'Return 802.11 \'Data\' data frame \'Sequence Control\' field'
804 b = self.header.get_word(20, "<")
805 return b
807 def set_sequence_control(self, value):
808 'Set the 802.11 \'Data\' data frame \'Sequence Control\' field'
809 # set the bits
810 nb = value & 0xFFFF
811 self.header.set_word(20, nb, "<")
813 def get_fragment_number(self):
814 'Return 802.11 \'Data\' data frame \'Fragment Number\' subfield'
816 b = self.header.get_word(20, "<")
817 return (b&0x000F)
819 def set_fragment_number(self, value):
820 'Set the 802.11 \'Data\' data frame \'Fragment Number\' subfield'
821 # clear the bits
822 mask = (~0x000F) & 0xFFFF
823 masked = self.header.get_word(20, "<") & mask
824 # set the bits
825 nb = masked | (value & 0x000F)
826 self.header.set_word(20, nb, "<")
828 def get_sequence_number(self):
829 'Return 802.11 \'Data\' data frame \'Sequence Number\' subfield'
831 b = self.header.get_word(20, "<")
832 return ((b>>4) & 0xFFF)
834 def set_sequence_number(self, value):
835 'Set the 802.11 \'Data\' data frame \'Sequence Number\' subfield'
836 # clear the bits
837 mask = (~0xFFF0) & 0xFFFF
838 masked = self.header.get_word(20, "<") & mask
839 # set the bits
840 nb = masked | ((value & 0x0FFF ) << 4 )
841 self.header.set_word(20, nb, "<")
843 def get_frame_body(self):
844 'Return 802.11 \'Data\' data frame \'Frame Body\' field'
846 return self.get_body_as_string()
848 def set_frame_body(self, data):
849 'Set 802.11 \'Data\' data frame \'Frame Body\' field'
851 self.load_body(data)
853class Dot11DataQoSFrame(Dot11DataFrame):
854 '802.11 Data QoS Frame'
856 def __init__(self, aBuffer = None):
857 header_size = 24
858 tail_size = 0
860 ProtocolPacket.__init__(self, header_size, tail_size)
861 if(aBuffer):
862 self.load_packet(aBuffer)
864 def get_QoS(self):
865 'Return 802.11 \'Data\' data frame \'QoS\' field'
866 b = self.header.get_word(22, "<")
867 return b
869 def set_QoS(self, value):
870 'Set the 802.11 \'Data\' data frame \'QoS\' field'
871 # set the bits
872 nb = value & 0xFFFF
873 self.header.set_word(22, nb, "<")
875class Dot11DataAddr4Frame(Dot11DataFrame):
876 '802.11 Data With ToDS From DS Flags (With Addr 4) Frame'
878 def __init__(self, aBuffer = None):
879 header_size = 28
880 tail_size = 0
882 ProtocolPacket.__init__(self, header_size, tail_size)
883 if(aBuffer):
884 self.load_packet(aBuffer)
886 def get_address4(self):
887 'Return 802.11 \'Data\' data frame 48 bit \'Address4\' field as a 6 bytes array'
888 return self.header.get_bytes()[22:28]
890 def set_address4(self, value):
891 'Set 802.11 \'Data\' data frame 48 bit \'Address4\' field as a 6 bytes array'
892 for i in range(0, 6):
893 self.header.set_byte(22+i, value[i])
895class Dot11DataAddr4QoSFrame(Dot11DataAddr4Frame):
896 '802.11 Data With ToDS From DS Flags (With Addr 4) and QoS Frame'
898 def __init__(self, aBuffer = None):
899 header_size = 30
900 tail_size = 0
902 ProtocolPacket.__init__(self, header_size, tail_size)
903 if(aBuffer):
904 self.load_packet(aBuffer)
906 def get_QoS(self):
907 'Return 802.11 \'Data\' data frame \'QoS\' field'
908 b = self.header.get_word(28, "<")
909 return b
911 def set_QoS(self, value):
912 'Set the 802.11 \'Data\' data frame \'QoS\' field'
913 # set the bits
914 nb = value & 0xFFFF
915 self.header.set_word(28, nb, "<")
917class SAPTypes():
918 NULL = 0x00
919 LLC_SLMGMT = 0x02
920 SNA_PATHCTRL = 0x04
921 IP = 0x06
922 SNA1 = 0x08
923 SNA2 = 0x0C
924 PROWAY_NM_INIT = 0x0E
925 NETWARE1 = 0x10
926 OSINL1 = 0x14
927 TI = 0x18
928 OSINL2 = 0x20
929 OSINL3 = 0x34
930 SNA3 = 0x40
931 BPDU = 0x42
932 RS511 = 0x4E
933 OSINL4 = 0x54
934 X25 = 0x7E
935 XNS = 0x80
936 BACNET = 0x82
937 NESTAR = 0x86
938 PROWAY_ASLM = 0x8E
939 ARP = 0x98
940 SNAP = 0xAA
941 HPJD = 0xB4
942 VINES1 = 0xBA
943 VINES2 = 0xBC
944 NETWARE2 = 0xE0
945 NETBIOS = 0xF0
946 IBMNM = 0xF4
947 HPEXT = 0xF8
948 UB = 0xFA
949 RPL = 0xFC
950 OSINL5 = 0xFE
951 GLOBAL = 0xFF
953class LLC(ProtocolPacket):
954 '802.2 Logical Link Control (LLC) Frame'
956 DLC_UNNUMBERED_FRAMES = 0x03
958 def __init__(self, aBuffer = None):
959 header_size = 3
960 tail_size = 0
962 ProtocolPacket.__init__(self, header_size, tail_size)
963 if(aBuffer):
964 self.load_packet(aBuffer)
966 def get_DSAP(self):
967 "Get the Destination Service Access Point (SAP) from LLC frame"
968 return self.header.get_byte(0)
970 def set_DSAP(self, value):
971 "Set the Destination Service Access Point (SAP) of LLC frame"
972 self.header.set_byte(0, value)
974 def get_SSAP(self):
975 "Get the Source Service Access Point (SAP) from LLC frame"
976 return self.header.get_byte(1)
978 def set_SSAP(self, value):
979 "Set the Source Service Access Point (SAP) of LLC frame"
980 self.header.set_byte(1, value)
982 def get_control(self):
983 "Get the Control field from LLC frame"
984 return self.header.get_byte(2)
986 def set_control(self, value):
987 "Set the Control field of LLC frame"
988 self.header.set_byte(2, value)
990class SNAP(ProtocolPacket):
991 '802.2 SubNetwork Access Protocol (SNAP) Frame'
993 def __init__(self, aBuffer = None):
994 header_size = 5
995 tail_size = 0
997 ProtocolPacket.__init__(self, header_size, tail_size)
998 if(aBuffer):
999 self.load_packet(aBuffer)
1001 def get_OUI(self):
1002 "Get the three-octet Organizationally Unique Identifier (OUI) SNAP frame"
1003 b = array_tobytes(self.header.get_bytes()[0:3])
1004 #unpack requires a string argument of length 4 and b is 3 bytes long
1005 (oui,) = struct.unpack('!L', b'\x00'+b)
1006 return oui
1008 def set_OUI(self, value):
1009 "Set the three-octet Organizationally Unique Identifier (OUI) SNAP frame"
1010 # clear the bits
1011 mask = ((~0xFFFFFF00) & 0xFF)
1012 masked = self.header.get_long(0, ">") & mask
1013 # set the bits
1014 nb = masked | ((value & 0x00FFFFFF) << 8)
1015 self.header.set_long(0, nb)
1017 def get_protoID(self):
1018 "Get the two-octet Protocol Identifier (PID) SNAP field"
1019 return self.header.get_word(3, ">")
1021 def set_protoID(self, value):
1022 "Set the two-octet Protocol Identifier (PID) SNAP field"
1023 self.header.set_word(3, value, ">")
1025class Dot11WEP(ProtocolPacket):
1026 '802.11 WEP'
1028 def __init__(self, aBuffer = None):
1029 header_size = 4
1030 tail_size = 0
1032 ProtocolPacket.__init__(self, header_size, tail_size)
1033 if(aBuffer):
1034 self.load_packet(aBuffer)
1036 def is_WEP(self):
1037 'Return True if it\'s a WEP'
1038 # We already know that it's private.
1039 # Now we must differentiate between WEP and WPA/WPA2
1040 # WPA/WPA2 have the ExtIV (Bit 5) enaled and WEP disabled
1041 b = self.header.get_byte(3)
1042 return not (b & 0x20)
1044 def get_iv(self):
1045 'Return the \'WEP IV\' field'
1046 b = array_tobytes(self.header.get_bytes()[0:3])
1047 #unpack requires a string argument of length 4 and b is 3 bytes long
1048 (iv,) = struct.unpack('!L', b'\x00'+b)
1049 return iv
1051 def set_iv(self, value):
1052 'Set the \'WEP IV\' field.'
1053 # clear the bits
1054 mask = ((~0xFFFFFF00) & 0xFF)
1055 masked = self.header.get_long(0, ">") & mask
1056 # set the bits
1057 nb = masked | ((value & 0x00FFFFFF) << 8)
1058 self.header.set_long(0, nb)
1060 def get_keyid(self):
1061 'Return the \'WEP KEY ID\' field'
1062 b = self.header.get_byte(3)
1063 return ((b>>6) & 0x03)
1065 def set_keyid(self, value):
1066 'Set the \'WEP KEY ID\' field'
1067 # clear the bits
1068 mask = (~0xC0) & 0xFF
1069 masked = self.header.get_byte(3) & mask
1070 # set the bits
1071 nb = masked | ((value & 0x03) << 6)
1072 self.header.set_byte(3, nb)
1074 def get_decrypted_data(self, key_string):
1075 'Return \'WEP Data\' field decrypted'
1077 # Needs to be at least 8 bytes of payload
1078 if len(self.body_string)<8: 1078 ↛ 1079line 1078 didn't jump to line 1079, because the condition on line 1078 was never true
1079 return self.body_string
1081 # initialize the first bytes of the key from the IV
1082 # and copy rest of the WEP key (the secret part)
1084 # Convert IV to 3 bytes long string
1085 iv=struct.pack('>L',self.get_iv())[-3:]
1086 key=iv+key_string
1087 rc4=RC4(key)
1088 decrypted_data=rc4.decrypt(self.body_string)
1090 return decrypted_data
1092 def get_encrypted_data(self, key_string):
1093 # RC4 is symmetric
1094 return self.get_decrypted_data(key_string)
1096 def encrypt_frame(self, key_string):
1097 enc = self.get_encrypted_data(key_string)
1098 self.load_body(enc)
1100class Dot11WEPData(ProtocolPacket):
1101 '802.11 WEP Data Part'
1103 def __init__(self, aBuffer = None):
1104 header_size = 0
1105 tail_size = 4
1107 ProtocolPacket.__init__(self, header_size, tail_size)
1108 if(aBuffer):
1109 self.load_packet(aBuffer)
1111 def get_icv(self):
1112 "Return 'WEP ICV' field"
1114 b = self.tail.get_long(-4, ">")
1115 return b
1117 def set_icv(self, value = None):
1118 "Set 'WEP ICV' field"
1120 # Compute the WEP ICV
1121 if value is None: 1121 ↛ 1122line 1121 didn't jump to line 1122, because the condition on line 1121 was never true
1122 value=self.get_computed_icv()
1124 # set the bits
1125 nb = value & 0xFFFFFFFF
1126 self.tail.set_long(-4, nb)
1128 def get_computed_icv(self):
1129 crcle=crc32(self.body_string)&0xffffffff
1130 # This crc32 is in little endian, convert it to big endian
1131 crc=struct.pack('<L', crcle)
1132 # Convert to long
1133 (crc_long,) = struct.unpack('!L', crc)
1134 return crc_long
1136 def check_icv(self):
1137 computed_icv=self.get_computed_icv()
1138 current_icv=self.get_icv()
1139 if computed_icv==current_icv: 1139 ↛ 1142line 1139 didn't jump to line 1142, because the condition on line 1139 was never false
1140 return True
1141 else:
1142 return False
1144class Dot11WPA(ProtocolPacket):
1145 '802.11 WPA'
1147 def __init__(self, aBuffer = None):
1148 header_size = 8
1149 tail_size = 0
1151 ProtocolPacket.__init__(self, header_size, tail_size)
1152 if(aBuffer): 1152 ↛ exitline 1152 didn't return from function '__init__', because the condition on line 1152 was never false
1153 self.load_packet(aBuffer)
1155 def is_WPA(self):
1156 'Return True if it\'s a WPA'
1157 # Now we must differentiate between WPA and WPA2
1158 # In WPA WEPSeed is set to (TSC1 | 0x20) & 0x7f.
1159 b = self.get_WEPSeed() == ((self.get_TSC1() | 0x20 ) & 0x7f)
1160 return (b and self.get_extIV())
1162 def get_keyid(self):
1163 'Return the \'WPA KEY ID\' field'
1164 b = self.header.get_byte(3)
1165 return ((b>>6) & 0x03)
1167 def set_keyid(self, value):
1168 'Set the \'WPA KEY ID\' field'
1169 # clear the bits
1170 mask = (~0xC0) & 0xFF
1171 masked = self.header.get_byte(3) & mask
1172 # set the bits
1173 nb = masked | ((value & 0x03) << 6)
1174 self.header.set_byte(3, nb)
1176 def get_decrypted_data(self):
1177 'Return \'WPA Data\' field decrypted'
1178 # TODO: Replace it with the decoded string
1179 return self.body_string
1181 def get_TSC1(self):
1182 'Return the \'WPA TSC1\' field'
1183 b = self.header.get_byte(0)
1184 return (b & 0xFF)
1186 def set_TSC1(self, value):
1187 'Set the \'WPA TSC1\' field'
1188 # set the bits
1189 nb = (value & 0xFF)
1190 self.header.set_byte(0, nb)
1192 def get_WEPSeed(self):
1193 'Return the \'WPA WEPSeed\' field'
1194 b = self.header.get_byte(1)
1195 return (b & 0xFF)
1197 def set_WEPSeed(self, value):
1198 'Set the \'WPA WEPSeed\' field'
1199 # set the bits
1200 nb = (value & 0xFF)
1201 self.header.set_byte(1, nb)
1203 def get_TSC0(self):
1204 'Return the \'WPA TSC0\' field'
1205 b = self.header.get_byte(2)
1206 return (b & 0xFF)
1208 def set_TSC0(self, value):
1209 'Set the \'WPA TSC0\' field'
1210 # set the bits
1211 nb = (value & 0xFF)
1212 self.header.set_byte(2, nb)
1214 def get_extIV(self):
1215 'Return the \'WPA extID\' field'
1216 b = self.header.get_byte(3)
1217 return ((b>>5) & 0x1)
1219 def set_extIV(self, value):
1220 'Set the \'WPA extID\' field'
1221 # clear the bits
1222 mask = (~0x20) & 0xFF
1223 masked = self.header.get_byte(3) & mask
1224 # set the bits
1225 nb = masked | ((value & 0x01) << 5)
1226 self.header.set_byte(3, nb)
1228 def get_TSC2(self):
1229 'Return the \'WPA TSC2\' field'
1230 b = self.header.get_byte(4)
1231 return (b & 0xFF)
1233 def set_TSC2(self, value):
1234 'Set the \'WPA TSC2\' field'
1235 # set the bits
1236 nb = (value & 0xFF)
1237 self.header.set_byte(4, nb)
1239 def get_TSC3(self):
1240 'Return the \'WPA TSC3\' field'
1241 b = self.header.get_byte(5)
1242 return (b & 0xFF)
1244 def set_TSC3(self, value):
1245 'Set the \'WPA TSC3\' field'
1246 # set the bits
1247 nb = (value & 0xFF)
1248 self.header.set_byte(5, nb)
1250 def get_TSC4(self):
1251 'Return the \'WPA TSC4\' field'
1252 b = self.header.get_byte(6)
1253 return (b & 0xFF)
1255 def set_TSC4(self, value):
1256 'Set the \'WPA TSC4\' field'
1257 # set the bits
1258 nb = (value & 0xFF)
1259 self.header.set_byte(6, nb)
1261 def get_TSC5(self):
1262 'Return the \'WPA TSC5\' field'
1263 b = self.header.get_byte(7)
1264 return (b & 0xFF)
1266 def set_TSC5(self, value):
1267 'Set the \'WPA TSC5\' field'
1268 # set the bits
1269 nb = (value & 0xFF)
1270 self.header.set_byte(7, nb)
1272class Dot11WPAData(ProtocolPacket):
1273 '802.11 WPA Data Part'
1275 def __init__(self, aBuffer = None):
1276 header_size = 0
1277 tail_size = 12
1279 ProtocolPacket.__init__(self, header_size, tail_size)
1280 if(aBuffer): 1280 ↛ exitline 1280 didn't return from function '__init__', because the condition on line 1280 was never false
1281 self.load_packet(aBuffer)
1283 def get_icv(self):
1284 "Return 'WPA ICV' field"
1286 b = self.tail.get_long(-4, ">")
1287 return b
1289 def set_icv(self, value = None):
1290 "Set 'WPA ICV' field"
1292 # calculate the FCS
1293 if value is None:
1294 value=self.compute_checksum(self.body_string)
1296 # set the bits
1297 nb = value & 0xFFFFFFFF
1298 self.tail.set_long(-4, nb)
1300 def get_MIC(self):
1301 'Return the \'WPA2Data MIC\' field'
1302 return self.get_tail_as_string()[:8]
1304 def set_MIC(self, value):
1305 'Set the \'WPA2Data MIC\' field'
1306 #Padding to 8 bytes with 0x00's
1307 value.ljust(8,b'\x00')
1308 #Stripping to 8 bytes
1309 value=value[:8]
1310 icv=self.tail.get_buffer_as_string()[-4:]
1311 self.tail.set_bytes_from_string(value+icv)
1313class Dot11WPA2(ProtocolPacket):
1314 '802.11 WPA2'
1316 def __init__(self, aBuffer = None):
1317 header_size = 8
1318 tail_size = 0
1320 ProtocolPacket.__init__(self, header_size, tail_size)
1321 if(aBuffer): 1321 ↛ exitline 1321 didn't return from function '__init__', because the condition on line 1321 was never false
1322 self.load_packet(aBuffer)
1324 def is_WPA2(self):
1325 'Return True if it\'s a WPA2'
1326 # Now we must differentiate between WPA and WPA2
1327 # In WPA WEPSeed is set to (TSC1 | 0x20) & 0x7f.
1328 # In WPA2 WEPSeed=PN1 and TSC1=PN0
1329 b = self.get_PN1() == ((self.get_PN0() | 0x20 ) & 0x7f)
1330 return (not b and self.get_extIV())
1332 def get_extIV(self):
1333 'Return the \'WPA2 extID\' field'
1334 b = self.header.get_byte(3)
1335 return ((b>>5) & 0x1)
1337 def set_extIV(self, value):
1338 'Set the \'WPA2 extID\' field'
1339 # clear the bits
1340 mask = (~0x20) & 0xFF
1341 masked = self.header.get_byte(3) & mask
1342 # set the bits
1343 nb = masked | ((value & 0x01) << 5)
1344 self.header.set_byte(3, nb)
1346 def get_keyid(self):
1347 'Return the \'WPA2 KEY ID\' field'
1348 b = self.header.get_byte(3)
1349 return ((b>>6) & 0x03)
1351 def set_keyid(self, value):
1352 'Set the \'WPA2 KEY ID\' field'
1353 # clear the bits
1354 mask = (~0xC0) & 0xFF
1355 masked = self.header.get_byte(3) & mask
1356 # set the bits
1357 nb = masked | ((value & 0x03) << 6)
1358 self.header.set_byte(3, nb)
1360 def get_decrypted_data(self):
1361 'Return \'WPA2 Data\' field decrypted'
1362 # TODO: Replace it with the decoded string
1363 return self.body_string
1365 def get_PN0(self):
1366 'Return the \'WPA2 PN0\' field'
1367 b = self.header.get_byte(0)
1368 return (b & 0xFF)
1370 def set_PN0(self, value):
1371 'Set the \'WPA2 PN0\' field'
1372 # set the bits
1373 nb = (value & 0xFF)
1374 self.header.set_byte(0, nb)
1376 def get_PN1(self):
1377 'Return the \'WPA2 PN1\' field'
1378 b = self.header.get_byte(1)
1379 return (b & 0xFF)
1381 def set_PN1(self, value):
1382 'Set the \'WPA2 PN1\' field'
1383 # set the bits
1384 nb = (value & 0xFF)
1385 self.header.set_byte(1, nb)
1387 def get_PN2(self):
1388 'Return the \'WPA2 PN2\' field'
1389 b = self.header.get_byte(4)
1390 return (b & 0xFF)
1392 def set_PN2(self, value):
1393 'Set the \'WPA2 PN2\' field'
1394 # set the bits
1395 nb = (value & 0xFF)
1396 self.header.set_byte(4, nb)
1398 def get_PN3(self):
1399 'Return the \'WPA2 PN3\' field'
1400 b = self.header.get_byte(5)
1401 return (b & 0xFF)
1403 def set_PN3(self, value):
1404 'Set the \'WPA2 PN3\' field'
1405 # set the bits
1406 nb = (value & 0xFF)
1407 self.header.set_byte(5, nb)
1409 def get_PN4(self):
1410 'Return the \'WPA2 PN4\' field'
1411 b = self.header.get_byte(6)
1412 return (b & 0xFF)
1414 def set_PN4(self, value):
1415 'Set the \'WPA2 PN4\' field'
1416 # set the bits
1417 nb = (value & 0xFF)
1418 self.header.set_byte(6, nb)
1420 def get_PN5(self):
1421 'Return the \'WPA2 PN5\' field'
1422 b = self.header.get_byte(7)
1423 return (b & 0xFF)
1425 def set_PN5(self, value):
1426 'Set the \'WPA2 PN5\' field'
1427 # set the bits
1428 nb = (value & 0xFF)
1429 self.header.set_byte(7, nb)
1431class Dot11WPA2Data(ProtocolPacket):
1432 '802.11 WPA2 Data Part'
1434 def __init__(self, aBuffer = None):
1435 header_size = 0
1436 tail_size = 8
1438 ProtocolPacket.__init__(self, header_size, tail_size)
1439 if(aBuffer): 1439 ↛ exitline 1439 didn't return from function '__init__', because the condition on line 1439 was never false
1440 self.load_packet(aBuffer)
1442 def get_MIC(self):
1443 'Return the \'WPA2Data MIC\' field'
1444 return self.get_tail_as_string()
1446 def set_MIC(self, value):
1447 'Set the \'WPA2Data MIC\' field'
1448 #Padding to 8 bytes with 0x00's
1449 value.ljust(8,b'\x00')
1450 #Stripping to 8 bytes
1451 value=value[:8]
1452 self.tail.set_bytes_from_string(value)
1454class RadioTap(ProtocolPacket):
1455 __HEADER_BASE_SIZE = 8 # minimal header size
1456 _PRESENT_FLAGS_SIZE = 4
1457 _BASE_PRESENT_FLAGS_OFFSET = 4
1459 class __RadioTapField(object):
1460 ALIGNMENT = 1
1462 def __str__( self ):
1463 return str( self.__class__.__name__ )
1465 class RTF_TSFT(__RadioTapField):
1466 BIT_NUMBER = 0
1467 STRUCTURE = "<Q"
1468 ALIGNMENT = 8
1470 class RTF_FLAGS(__RadioTapField):
1471 BIT_NUMBER = 1
1472 STRUCTURE = "<B"
1474 # https://web.archive.org/web/20160423125307/www.radiotap.org/defined-fields/Flags
1475 PROPERTY_CFP = 0x01 #sent/received during CFP
1476 PROPERTY_SHORTPREAMBLE = 0x02 #sent/received with short preamble
1477 PROPERTY_WEP = 0x04 #sent/received with WEP encryption
1478 PROPERTY_FRAGMENTATION = 0x08 #sent/received with fragmentation
1479 PROPERTY_FCS_AT_END = 0x10 #frame includes FCS
1480 PROPERTY_PAYLOAD_PADDING= 0x20 #frame has padding between 802.11 header and payload (to 32-bit boundary)
1481 PROPERTY_BAD_FCS = 0x40 #does not pass FCS check
1482 PROPERTY_SHORT_GI = 0x80 #frame used short guard interval (HT). Unspecified but used:
1484 class RTF_RATE(__RadioTapField):
1485 BIT_NUMBER = 2
1486 STRUCTURE = "<B"
1488 class RTF_CHANNEL(__RadioTapField):
1489 BIT_NUMBER = 3
1490 STRUCTURE = "<HH"
1491 ALIGNMENT = 2
1493 class RTF_FHSS(__RadioTapField):
1494 BIT_NUMBER = 4
1495 STRUCTURE = "<BB"
1497 class RTF_DBM_ANTSIGNAL(__RadioTapField):
1498 BIT_NUMBER = 5
1499 STRUCTURE = "<B"
1501 class RTF_DBM_ANTNOISE(__RadioTapField):
1502 BIT_NUMBER = 6
1503 STRUCTURE = "<B"
1505 class RTF_LOCK_QUALITY(__RadioTapField):
1506 BIT_NUMBER = 7
1507 STRUCTURE = "<H"
1508 ALIGNMENT = 2
1510 class RTF_TX_ATTENUATION(__RadioTapField):
1511 BIT_NUMBER = 8
1512 STRUCTURE = "<H"
1513 ALIGNMENT = 2
1515 class RTF_DB_TX_ATTENUATION(__RadioTapField):
1516 BIT_NUMBER = 9
1517 STRUCTURE = "<H"
1518 ALIGNMENT = 2
1520 class RTF_DBM_TX_POWER(__RadioTapField):
1521 BIT_NUMBER = 10
1522 STRUCTURE = "<b"
1523 ALIGNMENT = 2
1525 class RTF_ANTENNA(__RadioTapField):
1526 BIT_NUMBER = 11
1527 STRUCTURE = "<B"
1529 class RTF_DB_ANTSIGNAL(__RadioTapField):
1530 BIT_NUMBER = 12
1531 STRUCTURE = "<B"
1533 class RTF_DB_ANTNOISE(__RadioTapField):
1534 BIT_NUMBER = 13
1535 STRUCTURE = "<B"
1537## # official assignment, clashes with RTF_FCS_IN_HEADER
1538## class RTF_RX_FLAGS(__RadioTapField):
1539## BIT_NUMBER = 14
1540## STRUCTURE = "<H"
1541## ALIGNMENT = 2
1543 # clashes with RTF_RX_FLAGS
1544 class RTF_FCS_IN_HEADER(__RadioTapField):
1545 BIT_NUMBER = 14
1546 STRUCTURE = "<L"
1547 ALIGNMENT = 4
1549 # clashes with HARDWARE_QUEUE
1550 class RTF_TX_FLAGS(__RadioTapField):
1551 BIT_NUMBER = 15
1552 STRUCTURE = "<H"
1553 ALIGNMENT = 2
1555## # clashes with TX_FLAGS
1556## class RTF_HARDWARE_QUEUE(__RadioTapField):
1557## BIT_NUMBER = 15
1558## STRUCTURE = "<B"
1559## ALIGNMENT = 1
1561 # clashes with RSSI
1562 class RTF_RTS_RETRIES(__RadioTapField):
1563 BIT_NUMBER = 16
1564 STRUCTURE = "<B"
1566## # clashes with RTS_RETRIES
1567## class RTF_RSSI(__RadioTapField):
1568## BIT_NUMBER = 16
1569## STRUCTURE = "<H"
1570## ALIGNMENT = 1
1572 class RTF_DATA_RETRIES(__RadioTapField):
1573 BIT_NUMBER = 17
1574 STRUCTURE = "<B"
1576 class RTF_XCHANNEL(__RadioTapField):
1577 BIT_NUMBER = 18
1578 STRUCTURE = "<LHBB"
1579 ALIGNMENT = 4
1581 class RTF_EXT(__RadioTapField):
1582 BIT_NUMBER = 31
1583 STRUCTURE = []
1585 # Sort the list so the 'for' statement walk the list in the right order
1586 radiotap_fields = __RadioTapField.__subclasses__()
1587 radiotap_fields.sort(key= lambda x: x.BIT_NUMBER)
1589 def __init__(self, aBuffer = None):
1590 header_size = self.__HEADER_BASE_SIZE
1591 tail_size = 0
1593 if aBuffer:
1594 length = struct.unpack('<H', aBuffer[2:4])[0]
1595 header_size=length
1597 ProtocolPacket.__init__(self, header_size, tail_size)
1598 self.load_packet(aBuffer)
1599 else:
1600 ProtocolPacket.__init__(self, header_size, tail_size)
1601 self.set_version(0)
1602 self.__set_present(0x00000000)
1604 def get_header_length(self):
1605 'Return the RadioTap header \'length\' field'
1606 self.__update_header_length()
1607 return self.header.get_word(2, "<")
1609 def get_version(self):
1610 'Return the \'version\' field'
1611 b = self.header.get_byte(0)
1612 return b
1614 def set_version(self, value):
1615 'Set the \'version\' field'
1616 nb = (value & 0xFF)
1617 self.header.set_byte(0, nb)
1619 nb = (value & 0xFF)
1621 def get_present(self, offset=_BASE_PRESENT_FLAGS_OFFSET):
1622 "Return RadioTap present bitmap field"
1623 present = self.header.get_long(offset, "<")
1624 return present
1626 def __set_present(self, value):
1627 "Set RadioTap present field bit"
1628 self.header.set_long(4, value)
1630 def get_present_bit(self, field, offset=4):
1631 'Get a \'present\' field bit'
1632 present=self.get_present(offset)
1633 return not not (2**field.BIT_NUMBER & present)
1635 def __set_present_bit(self, field):
1636 'Set a \'present\' field bit'
1637 npresent=2**field.BIT_NUMBER | self.get_present()
1638 self.header.set_long(4, npresent,'<')
1640 def __unset_present_bit(self, field):
1641 'Unset a \'present\' field bit'
1642 npresent=~(2**field.BIT_NUMBER) & self.get_present()
1643 self.header.set_long(4, npresent,'<')
1645 def __align(self, val, align):
1646 return ( (((val) + ((align) - 1)) & ~((align) - 1)) - val )
1648 def __get_field_position(self, field):
1650 offset = RadioTap._BASE_PRESENT_FLAGS_OFFSET
1651 extra_present_flags_count = 0
1652 while self.get_present_bit(RadioTap.RTF_EXT, offset):
1653 offset += RadioTap._PRESENT_FLAGS_SIZE
1654 extra_present_flags_count += 1
1656 field_position = self.__HEADER_BASE_SIZE + (RadioTap._BASE_PRESENT_FLAGS_OFFSET * extra_present_flags_count)
1658 for f in self.radiotap_fields: 1658 ↛ 1667line 1658 didn't jump to line 1667, because the loop on line 1658 didn't complete
1659 field_position += self.__align(field_position, f.ALIGNMENT)
1660 if f == field:
1661 return field_position
1663 if self.get_present_bit(f):
1664 total_length = struct.calcsize(f.STRUCTURE)
1665 field_position += total_length
1667 return None
1669 def unset_field( self, field):
1670 is_present=self.get_present_bit(field)
1671 if is_present is False: 1671 ↛ 1672line 1671 didn't jump to line 1672, because the condition on line 1671 was never true
1672 return False
1674 byte_pos=self.__get_field_position(field)
1675 if not byte_pos: 1675 ↛ 1676line 1675 didn't jump to line 1676, because the condition on line 1675 was never true
1676 return False
1678 self.__unset_present_bit(field)
1680 header=self.get_header_as_string()
1681 total_length = struct.calcsize(field.STRUCTURE)
1682 header=header[:byte_pos]+header[byte_pos+total_length:]
1684 self.load_header(header)
1686 def __get_field_values( self, field ):
1687 is_present=self.get_present_bit(field)
1688 if is_present is False:
1689 return None
1691 byte_pos=self.__get_field_position(field)
1692 header=self.get_header_as_string()
1693 total_length=struct.calcsize(field.STRUCTURE)
1694 v=header[ byte_pos:byte_pos+total_length ]
1696 field_values = struct.unpack(field.STRUCTURE, v)
1698 return field_values
1700 def __set_field_values( self, field, values ):
1701 if not hasattr(values,'__iter__'): 1701 ↛ 1702line 1701 didn't jump to line 1702, because the condition on line 1701 was never true
1702 raise Exception("arg 'values' is not iterable")
1704 # It's for to known the qty of argument of a structure
1705 num_fields=len(''.join(c for c in field.STRUCTURE if c not in '=@!<>'))
1707 if len(values)!=num_fields: 1707 ↛ 1708line 1707 didn't jump to line 1708, because the condition on line 1707 was never true
1708 raise Exception("Field %s has exactly %d items"%(str(field),struct.calcsize(field.STRUCTURE)))
1710 is_present=self.get_present_bit(field)
1711 if is_present is False:
1712 self.__set_present_bit(field)
1714 byte_pos=self.__get_field_position(field)
1715 header=self.get_header_as_string()
1716 total_length=struct.calcsize(field.STRUCTURE)
1718 new_str = struct.pack(field.STRUCTURE, *values)
1720 if is_present is True:
1721 header=header[:byte_pos]+new_str+header[byte_pos+total_length:]
1722 else:
1723 header=header[:byte_pos]+new_str+header[byte_pos:]
1724 self.load_header(header)
1727 def set_tsft( self, nvalue ):
1728 "Set the Value in microseconds of the MAC's 64-bit 802.11 "\
1729 "Time Synchronization Function timer when the first bit of "\
1730 "the MPDU arrived at the MAC"
1731 self.__set_field_values(RadioTap.RTF_TSFT, [nvalue])
1733 def get_tsft( self ):
1734 "Get the Value in microseconds of the MAC's 64-bit 802.11 "\
1735 "Time Synchronization Function timer when the first bit of "\
1736 "the MPDU arrived at the MAC"
1738 values=self.__get_field_values(RadioTap.RTF_TSFT)
1739 if not values:
1740 return None
1741 return values[0]
1743 def set_flags( self, nvalue ):
1744 "Set the properties of transmitted and received frames."
1745 self.__set_field_values(self.RTF_FLAGS, [nvalue])
1747 def get_flags( self ):
1748 "Get the properties of transmitted and received frames."
1749 values=self.__get_field_values(self.RTF_FLAGS)
1750 if not values: 1750 ↛ 1751line 1750 didn't jump to line 1751, because the condition on line 1750 was never true
1751 return None
1752 return values[0]
1754 def set_rate( self, nvalue ):
1755 "Set the TX/RX data rate in 500 Kbps units"
1757 self.__set_field_values(self.RTF_RATE, [nvalue])
1759 def get_rate( self ):
1760 "Get the TX/RX data rate in 500 Kbps units"
1762 values=self.__get_field_values(self.RTF_RATE)
1763 if not values: 1763 ↛ 1764line 1763 didn't jump to line 1764, because the condition on line 1763 was never true
1764 return None
1765 return values[0]
1767 def set_channel( self, freq, flags ):
1768 "Set the channel Tx/Rx frequency in MHz and the channel flags"
1770 self.__set_field_values(self.RTF_CHANNEL, [freq, flags])
1772 def get_channel( self ):
1773 "Get the TX/RX data rate in 500 Kbps units"
1775 values=self.__get_field_values(self.RTF_CHANNEL)
1777 return values
1779 def set_FHSS( self, hop_set, hop_pattern ):
1780 "Set the hop set and pattern for frequency-hopping radios"
1782 self.__set_field_values(self.RTF_FHSS, [hop_set, hop_pattern])
1784 def get_FHSS( self ):
1785 "Get the hop set and pattern for frequency-hopping radios"
1787 values=self.__get_field_values(self.RTF_FHSS)
1789 return values
1791 def set_dBm_ant_signal( self, signal ):
1792 "Set the RF signal power at the antenna, decibel difference from an "\
1793 "arbitrary, fixed reference."
1795 self.__set_field_values(self.RTF_DBM_ANTSIGNAL, [signal])
1797 def get_dBm_ant_signal( self ):
1798 "Get the RF signal power at the antenna, decibel difference from an "\
1799 "arbitrary, fixed reference."
1801 values=self.__get_field_values(self.RTF_DBM_ANTSIGNAL)
1802 if not values:
1803 return None
1804 return values[0]
1806 def set_dBm_ant_noise( self, signal ):
1807 "Set the RF noise power at the antenna, decibel difference from an "\
1808 "arbitrary, fixed reference."
1810 self.__set_field_values(self.RTF_DBM_ANTNOISE, [signal])
1812 def get_dBm_ant_noise( self ):
1813 "Get the RF noise power at the antenna, decibel difference from an "\
1814 "arbitrary, fixed reference."
1816 values=self.__get_field_values(self.RTF_DBM_ANTNOISE)
1817 if not values:
1818 return None
1819 return values[0]
1821 def set_lock_quality( self, quality ):
1822 "Set the quality of Barker code lock. "\
1823 "Called 'Signal Quality' in datasheets. "
1825 self.__set_field_values(self.RTF_LOCK_QUALITY, [quality])
1827 def get_lock_quality( self ):
1828 "Get the quality of Barker code lock. "\
1829 "Called 'Signal Quality' in datasheets. "
1831 values=self.__get_field_values(self.RTF_LOCK_QUALITY)
1832 if not values:
1833 return None
1834 return values[0]
1836 def set_tx_attenuation( self, power ):
1837 "Set the transmit power expressed as unitless distance from max power "\
1838 "set at factory calibration. 0 is max power."
1840 self.__set_field_values(self.RTF_TX_ATTENUATION, [power])
1842 def get_tx_attenuation( self ):
1843 "Set the transmit power expressed as unitless distance from max power "\
1844 "set at factory calibration. 0 is max power."
1846 values=self.__get_field_values(self.RTF_TX_ATTENUATION)
1847 if not values:
1848 return None
1849 return values[0]
1851 def set_dB_tx_attenuation( self, power ):
1852 "Set the transmit power expressed as decibel distance from max power "\
1853 "set at factory calibration. 0 is max power. "
1855 self.__set_field_values(self.RTF_DB_TX_ATTENUATION, [power])
1857 def get_dB_tx_attenuation( self ):
1858 "Set the transmit power expressed as decibel distance from max power "\
1859 "set at factory calibration. 0 is max power. "
1861 values=self.__get_field_values(self.RTF_DB_TX_ATTENUATION)
1862 if not values:
1863 return None
1864 return values[0]
1866 def set_dBm_tx_power( self, power ):
1867 "Set the transmit power expressed as dBm (decibels from a 1 milliwatt"\
1868 " reference). This is the absolute power level measured at the "\
1869 "antenna port."
1871 self.__set_field_values(self.RTF_DBM_TX_POWER, [power])
1873 def get_dBm_tx_power( self ):
1874 "Get the transmit power expressed as dBm (decibels from a 1 milliwatt"\
1875 " reference). This is the absolute power level measured at the "\
1876 "antenna port."
1878 values=self.__get_field_values(self.RTF_DBM_TX_POWER)
1879 if not values:
1880 return None
1881 return values[0]
1883 def set_antenna( self, antenna_index ):
1884 "Set Rx/Tx antenna index for this packet. "\
1885 "The first antenna is antenna 0. "\
1887 self.__set_field_values(self.RTF_ANTENNA, [antenna_index])
1889 def get_antenna( self ):
1890 "Set Rx/Tx antenna index for this packet. "\
1891 "The first antenna is antenna 0. "\
1893 values=self.__get_field_values(self.RTF_ANTENNA)
1894 if not values: 1894 ↛ 1895line 1894 didn't jump to line 1895, because the condition on line 1894 was never true
1895 return None
1896 return values[0]
1898 def set_dB_ant_signal( self, signal ):
1899 "Set the RF signal power at the antenna, decibel difference from an "\
1900 "arbitrary, fixed reference."
1902 self.__set_field_values(self.RTF_DB_ANTSIGNAL, [signal])
1904 def get_dB_ant_signal( self ):
1905 "Get the RF signal power at the antenna, decibel difference from an "\
1906 "arbitrary, fixed reference."
1908 values=self.__get_field_values(self.RTF_DB_ANTSIGNAL)
1909 if not values:
1910 return None
1911 return values[0]
1913 def set_dB_ant_noise( self, signal ):
1914 "Set the RF noise power at the antenna, decibel difference from an "\
1915 "arbitrary, fixed reference."
1917 self.__set_field_values(self.RTF_DB_ANTNOISE, [signal])
1919 def get_dB_ant_noise( self ):
1920 "Get the RF noise power at the antenna, decibel difference from an "\
1921 "arbitrary, fixed reference."
1923 values=self.__get_field_values(self.RTF_DB_ANTNOISE)
1924 if not values:
1925 return None
1926 return values[0]
1928## def set_rx_flags( self, flags ):
1929## "Set the properties of received frames."
1930##
1931## self.__set_field_values(self.RTF_RX_FLAGS, [flags])
1932##
1933## def get_rx_flags( self ):
1934## "Get the properties of received frames."
1935##
1936## values=self.__get_field_values(self.RTF_RX_FLAGS)
1937## if not values:
1938## return None
1939## return values[0]
1941 def set_FCS_in_header( self, fcs ):
1942 "Set the Field containing the FCS of the frame (instead of it being "\
1943 "appended to the frame as it would appear on the air.) "
1945 self.__set_field_values(self.RTF_FCS_IN_HEADER, [fcs])
1947 def get_FCS_in_header( self ):
1948 "Get the Field containing the FCS of the frame (instead of it being "\
1949 "appended to the frame as it would appear on the air.) "
1951 values=self.__get_field_values(self.RTF_FCS_IN_HEADER)
1952 if not values:
1953 return None
1954 return values[0]
1956## def set_RSSI( self, rssi, max_rssi ):
1957## "Set the received signal strength and the maximum for the hardware."
1958##
1959## self.__set_field_values(self.RTF_RSSI, [rssi, max_rssi])
1960##
1961## def get_RSSI( self ):
1962## "Get the received signal strength and the maximum for the hardware."
1963##
1964## values=self.__get_field_values(self.RTF_RSSI)
1965##
1966## return values
1968 def set_RTS_retries( self, retries):
1969 "Set the number of RTS retries a transmitted frame used."
1971 self.__set_field_values(self.RTF_RTS_RETRIES, [retries])
1973 def get_RTS_retries( self ):
1974 "Get the number of RTS retries a transmitted frame used."
1976 values=self.__get_field_values(self.RTF_RTS_RETRIES)
1977 if not values:
1978 return None
1979 return values[0]
1981 def set_tx_flags( self, flags ):
1982 "Set the properties of transmitted frames."
1984 self.__set_field_values(self.RTF_TX_FLAGS, [flags])
1986 def get_tx_flags( self ):
1987 "Get the properties of transmitted frames."
1989 values=self.__get_field_values(self.RTF_TX_FLAGS)
1990 if not values:
1991 return None
1992 return values[0]
1994 def set_xchannel( self, flags, freq, channel, maxpower ):
1995 "Set extended channel information: flags, freq, channel and maxpower"
1997 self.__set_field_values(self.RTF_XCHANNEL, [flags, freq, channel, maxpower] )
1999 def get_xchannel( self ):
2000 "Get extended channel information: flags, freq, channel and maxpower"
2002 values=self.__get_field_values(field=self.RTF_XCHANNEL)
2004 return values
2006 def set_data_retries( self, retries ):
2007 "Set the number of data retries a transmitted frame used."
2009 self.__set_field_values(self.RTF_DATA_RETRIES, [retries])
2011 def get_data_retries( self ):
2012 "Get the number of data retries a transmitted frame used."
2014 values=self.__get_field_values(self.RTF_DATA_RETRIES)
2015 if not values:
2016 return None
2017 return values[0]
2019 def set_hardware_queue( self, queue ):
2020 "Set the hardware queue to send the frame on."
2022 self.__set_field_values(self.RTF_HARDWARE_QUEUE, [queue])
2024## def get_hardware_queue( self ):
2025## "Get the hardware queue to send the frame on."
2026##
2027## values=self.__get_field_values(self.RTF_HARDWARE_QUEUE)
2028## if not values:
2029## return None
2030## return values[0]
2032 def __update_header_length(self):
2033 'Update the RadioTap header length field with the real size'
2034 self.header.set_word(2, self.get_header_size(), "<")
2036 def get_packet(self):
2037 self.__update_header_length()
2038 return ProtocolPacket.get_packet(self)
2040class Dot11ManagementFrame(ProtocolPacket):
2041 '802.11 Management Frame'
2043 def __init__(self, aBuffer = None):
2044 header_size = 22
2045 tail_size = 0
2047 ProtocolPacket.__init__(self, header_size, tail_size)
2048 if(aBuffer): 2048 ↛ exitline 2048 didn't return from function '__init__', because the condition on line 2048 was never false
2049 self.load_packet(aBuffer)
2051 def get_duration(self):
2052 'Return 802.11 Management frame \'Duration\' field'
2053 b = self.header.get_word(0, "<")
2054 return b
2056 def set_duration(self, value):
2057 'Set the 802.11 Management frame \'Duration\' field'
2058 # set the bits
2059 nb = value & 0xFFFF
2060 self.header.set_word(0, nb, "<")
2062 def get_destination_address(self):
2063 'Return 802.11 Management frame \'Destination Address\' field as a 6 bytes array'
2064 return self.header.get_bytes()[2:8]
2066 def set_destination_address(self, value):
2067 'Set 802.11 Management frame \'Destination Address\' field as a 6 bytes array'
2068 for i in range(0, 6):
2069 self.header.set_byte(2+i, value[i])
2071 def get_source_address(self):
2072 'Return 802.11 Management frame \'Source Address\' field as a 6 bytes array'
2073 return self.header.get_bytes()[8:14]
2075 def set_source_address(self, value):
2076 'Set 802.11 Management frame \'Source Address\' field as a 6 bytes array'
2077 for i in range(0, 6):
2078 self.header.set_byte(8+i, value[i])
2080 def get_bssid(self):
2081 'Return 802.11 Management frame \'BSSID\' field as a 6 bytes array'
2082 return self.header.get_bytes()[14: 20]
2084 def set_bssid(self, value):
2085 'Set 802.11 Management frame \'BSSID\' field as a 6 bytes array'
2086 for i in range(0, 6):
2087 self.header.set_byte(14+i, value[i])
2089 def get_sequence_control(self):
2090 'Return 802.11 Management frame \'Sequence Control\' field'
2091 b = self.header.get_word(20, "<")
2092 return b
2094 def set_sequence_control(self, value):
2095 'Set the 802.11 Management frame \'Sequence Control\' field'
2096 # set the bits
2097 nb = value & 0xFFFF
2098 self.header.set_word(20, nb, "<")
2100 def get_fragment_number(self):
2101 'Return 802.11 Management frame \'Fragment Number\' subfield'
2103 b = self.get_sequence_control()
2104 return (b&0x000F)
2106 def set_fragment_number(self, value):
2107 'Set the 802.11 Management frame \'Fragment Number\' subfield'
2108 # clear the bits
2109 mask = (~0x000F) & 0xFFFF
2110 masked = self.header.get_word(20, "<") & mask
2111 # set the bits
2112 nb = masked | (value & 0x000F)
2113 self.header.set_word(20, nb, "<")
2115 def get_sequence_number(self):
2116 'Return 802.11 Management frame \'Sequence Number\' subfield'
2118 b = self.get_sequence_control()
2119 return ((b>>4) & 0xFFF)
2121 def set_sequence_number(self, value):
2122 'Set the 802.11 Management frame \'Sequence Number\' subfield'
2123 # clear the bits
2124 mask = (~0xFFF0) & 0xFFFF
2125 masked = self.header.get_word(20, "<") & mask
2126 # set the bits
2127 nb = masked | ((value & 0x0FFF ) << 4 )
2128 self.header.set_word(20, nb, "<")
2130 def get_frame_body(self):
2131 'Return 802.11 Management frame \'Frame Body\' field'
2133 return self.get_body_as_string()
2135 def set_frame_body(self, data):
2136 'Set 802.11 Management frame \'Frame Body\' field'
2138 self.load_body(data)
2140class DOT11_MANAGEMENT_ELEMENTS():
2141 SSID = 0
2142 SUPPORTED_RATES = 1
2143 FH_PARAMETER_SET = 2
2144 DS_PARAMETER_SET = 3
2145 CF_PARAMETER_SET = 4
2146 TIM = 5
2147 IBSS_PARAMETER_SET = 6
2148 COUNTRY = 7
2149 HOPPING_PARAMETER = 8
2150 HOPPING_TABLE = 9
2151 REQUEST = 10
2152 BSS_LOAD = 11
2153 EDCA_PARAMETER_SET = 12
2154 TSPEC = 13
2155 TCLAS = 14
2156 SCHEDULE = 15
2157 CHALLENGE_TEXT = 16
2158 # RESERVED 17-31
2159 POWER_CONSTRAINT = 32
2160 POWER_CAPABILITY = 33
2161 TPC_REQUEST = 34
2162 TPC_REPORT = 35
2163 SUPPORTED_CHANNELS = 36
2164 CHANNEL_SWITCH_ANN = 37
2165 MEASURE_REQ = 38
2166 MEASURE_REP = 39
2167 QUIET = 40
2168 IBSS_DFS = 41
2169 ERP_INFO = 42
2170 TS_DELAY = 43
2171 TCLAS_PROCESSING = 44
2172 #RESERVED 45 # See: IEEE 802.11n
2173 QOS_CAPABILITY = 46
2174 #RESERVED 47 # See: IEEE 802.11g
2175 RSN = 48
2176 #RESERVED 49
2177 EXT_SUPPORTED_RATES = 50
2178 #RESERVED 51-126
2179 EXTENDED_CAPABILITIES = 127
2180 #RESERVED 128-220
2181 VENDOR_SPECIFIC = 221
2182 #RESERVED 222-255
2184class Dot11ManagementHelper(ProtocolPacket):
2186 def __init__(self, header_size, tail_size, aBuffer = None):
2187 self.__HEADER_BASE_SIZE=header_size
2189 if aBuffer: 2189 ↛ 2196line 2189 didn't jump to line 2196, because the condition on line 2189 was never false
2190 elements_length=self.__calculate_elements_length(aBuffer[self.__HEADER_BASE_SIZE:])
2191 header_size+=elements_length
2193 ProtocolPacket.__init__(self, header_size, tail_size)
2194 self.load_packet(aBuffer)
2195 else:
2196 ProtocolPacket.__init__(self, header_size, tail_size)
2198 def _find_element(self, elements, element_id ):
2199 remaining=len(elements)
2201 offset=0
2202 while remaining > 0:
2203 (id,length)=struct.unpack("!BB",elements[offset:offset+2])
2204 if element_id is None:
2205 pass # through the whole list returning the length
2206 elif id==element_id:
2207 yield (0,offset,length+2) # ==
2208 length+=2 #id+length
2209 offset+=length
2210 if length>remaining: 2210 ↛ 2212line 2210 didn't jump to line 2212, because the condition on line 2210 was never true
2211 # Error!!
2212 length = remaining
2213 remaining-=length
2214 # < Not found
2215 yield (-1, offset, None)
2217 def __calculate_elements_length(self, elements):
2218 gen_tp=self._find_element(elements, None )
2219 (match,offset,length)=next(gen_tp)
2220 if match != -1: 2220 ↛ 2222line 2220 didn't jump to line 2222, because the condition on line 2220 was never true
2221 # element_id is None, then __find_tagged_parameter must return -1
2222 raise Exception("Internal Error %s"%match)
2223 return offset
2225 def _get_elements_generator(self, element_id):
2226 elements=self.get_header_as_string()[self.__HEADER_BASE_SIZE:]
2227 gen_tp=self._find_element(elements, element_id )
2228 while True:
2229 (match,offset,length)=next(gen_tp)
2230 if match != 0:
2231 return
2232 value_offset=offset+2
2233 value_end=offset+length
2234 value=elements[value_offset:value_end]
2235 yield value
2237 def _get_element(self, element_id):
2238 gen_get_element=self._get_elements_generator(element_id)
2239 try:
2240 s=next(gen_get_element)
2242 if s is None: 2242 ↛ 2243line 2242 didn't jump to line 2243, because the condition on line 2242 was never true
2243 raise Exception("gen_get_element salio con None in _get_element!!!")
2245 return s
2246 except StopIteration:
2247 pass
2249 return None
2251 def delete_element(self, element_id, multiple = False):
2252 header=self.get_header_as_string()
2253 elements=header[self.__HEADER_BASE_SIZE:]
2254 gen_tp=self._find_element(elements, element_id )
2255 found=False
2256 while True:
2257 (match,offset,length)=next(gen_tp)
2258 if match != 0:
2259 break
2260 start=self.__HEADER_BASE_SIZE+offset
2261 header=header[:start]+header[start+length:]
2262 found=True
2263 if multiple is False:
2264 break
2266 if not found:
2267 return False
2269 self.load_header(header)
2270 return True
2272 def _set_element(self, element_id, value, replace = True):
2273 parameter=struct.pack('BB%ds'%len(value),element_id,len(value),value)
2275 header=self.get_header_as_string()
2276 elements=header[self.__HEADER_BASE_SIZE:]
2277 gen_tp=self._find_element(elements, element_id )
2278 found=False
2279 while True:
2280 (match,offset,length)=next(gen_tp)
2281 start=self.__HEADER_BASE_SIZE+offset
2282 if match == 0 and replace:
2283 # Replace
2284 header=header[:start]+parameter+header[start+length:]
2285 found=True
2286 break
2287 elif match > 0: 2287 ↛ 2289line 2287 didn't jump to line 2289, because the condition on line 2287 was never true
2288 # Add
2289 header=header[:start]+parameter+header[start:]
2290 found=True
2291 break
2292 else:
2293 break
2294 if not found:
2295 # Append (found<0 Not found)
2296 header=header+parameter
2297 self.load_header(header)
2299class Dot11ManagementBeacon(Dot11ManagementHelper):
2300 '802.11 Management Beacon Frame'
2302 __HEADER_BASE_SIZE = 12 # minimal header size
2304 def __init__(self, aBuffer = None):
2305 header_size = self.__HEADER_BASE_SIZE
2306 tail_size = 0
2307 Dot11ManagementHelper.__init__(self, header_size, tail_size, aBuffer)
2309 def get_timestamp(self):
2310 'Return the 802.11 Management Beacon frame \'Timestamp\' field'
2311 b = self.header.get_long_long(0, "<")
2312 return b
2314 def set_timestamp(self, value):
2315 'Set the 802.11 Management Beacon frame \'Timestamp\' field'
2316 # set the bits
2317 nb = value & 0xFFFFFFFFFFFFFFFF
2318 self.header.set_long_long(0, nb, "<")
2320 def get_beacon_interval(self):
2321 'Return the 802.11 Management Beacon frame \'Beacon Interval\' field' \
2322 'To convert it to seconds => secs = Beacon_Interval*1024/1000000'
2324 b = self.header.get_word(8, "<")
2325 return b
2327 def set_beacon_interval(self, value):
2328 'Set the 802.11 Management Beacon frame \'Beacon Interval\' field'
2329 # set the bits
2330 nb = value & 0xFFFF
2331 self.header.set_word(8, nb, "<")
2333 def get_capabilities(self):
2334 'Return the 802.11 Management Beacon frame \'Capability information\' field. '
2336 b = self.header.get_word(10, "<")
2337 return b
2339 def set_capabilities(self, value):
2340 'Set the 802.11 Management Beacon frame \'Capability Information\' field'
2341 # set the bits
2342 nb = value & 0xFFFF
2343 self.header.set_word(10, nb, "<")
2345 def get_ssid(self):
2346 "Get the 802.11 Management SSID element. "\
2347 "The SSID element indicates the identity of an ESS or IBSS."
2348 return self._get_element(DOT11_MANAGEMENT_ELEMENTS.SSID)
2350 def set_ssid(self, ssid):
2351 self._set_element(DOT11_MANAGEMENT_ELEMENTS.SSID,ssid)
2353 def get_supported_rates(self, human_readable=False):
2354 "Get the 802.11 Management Supported Rates element. "\
2355 "Specifies up to eight rates, then an Extended Supported Rate element "\
2356 "shall be generated to specify the remaining supported rates."\
2357 "If human_readable is True, the rates are returned in Mbit/sec"
2358 s=self._get_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES)
2359 if s is None: 2359 ↛ 2360line 2359 didn't jump to line 2360, because the condition on line 2359 was never true
2360 return None
2362 rates=struct.unpack('%dB'%len(s),s)
2363 if not human_readable:
2364 return rates
2366 rates_Mbs=tuple([(x&0x7F)*0.5 for x in rates])
2367 return rates_Mbs
2369 def set_supported_rates(self, rates):
2370 "Set the 802.11 Management Supported Rates element. "\
2371 "Specifies a tuple or list with up to eight rates, then an "\
2372 "Extended Supported Rate element shall be generated to specify "\
2373 "the remaining supported rates."
2374 qty_rates=len(rates)
2375 if qty_rates>8: 2375 ↛ 2376line 2375 didn't jump to line 2376, because the condition on line 2375 was never true
2376 raise Exception("requires up to eight rates")
2377 rates_string=struct.pack('B'*qty_rates,*rates)
2378 self._set_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES,rates_string)
2380 def get_ds_parameter_set(self):
2381 "Get the 802.11 Management DS Parameter set element. "\
2382 "Contains information to allow channel number identification for "\
2383 "STAs using a DSSS PHY."
2384 s=self._get_element(DOT11_MANAGEMENT_ELEMENTS.DS_PARAMETER_SET)
2385 if s is None: 2385 ↛ 2386line 2385 didn't jump to line 2386, because the condition on line 2385 was never true
2386 return None
2388 (ch,)=struct.unpack('B',s)
2390 return ch
2392 def set_ds_parameter_set(self, channel):
2393 "Set the 802.11 Management DS Parameter set element. "\
2394 "Contains information to allow channel number identification for "\
2395 "STAs using a DSSS PHY."
2396 channel_string=struct.pack('B',channel)
2397 self._set_element(DOT11_MANAGEMENT_ELEMENTS.DS_PARAMETER_SET,channel_string)
2399 def get_rsn(self):
2400 "Get the 802.11 Management Robust Security Network element."
2401 s = self._get_element(DOT11_MANAGEMENT_ELEMENTS.RSN)
2402 if s is None:
2403 return None
2404 return s
2406 def set_rsn(self, data):
2407 "Set the 802.11 Management Robust Security Network element."
2408 self._set_element(DOT11_MANAGEMENT_ELEMENTS.RSN, data)
2410 def get_erp(self):
2411 "Get the 802.11 Management ERP (extended rate PHY) Information element."
2412 s = self._get_element(DOT11_MANAGEMENT_ELEMENTS.ERP_INFO)
2413 if s is None:
2414 return None
2416 (erp,) = struct.unpack('B',s)
2418 return erp
2420 def set_erp(self, erp):
2421 "Set the 802.11 Management ERP (extended rate PHY) Inforamation "\
2422 "element."
2423 erp_string = struct.pack('B',erp)
2424 self._set_element(DOT11_MANAGEMENT_ELEMENTS.ERP_INFO, erp_string)
2426 def get_country(self):
2427 "Get the 802.11 Management Country element." \
2428 "Returns a tuple containing Country code, first channel number, "\
2429 "number of channels and maximum transmit power level"
2430 s = self._get_element(DOT11_MANAGEMENT_ELEMENTS.COUNTRY)
2431 if s is None:
2432 return None
2434 code, first, num, max = struct.unpack('3sBBB',s)
2435 code = code.strip(' ')
2436 return code, first, num, max
2438 def set_country(self, code, first_channel, number_of_channels, max_power):
2439 "Set the 802.11 Management Country element."
2440 if len(code) > 3:
2441 raise Exception("Country code must be up to 3 bytes long")
2443 #Padding the country code
2444 code += ' ' * (3-len(code))
2446 country_string = struct.pack('3sBBB', code, first_channel,
2447 number_of_channels, max_power)
2448 self._set_element(DOT11_MANAGEMENT_ELEMENTS.COUNTRY, country_string)
2450 def get_vendor_specific(self):
2451 "Get the 802.11 Management Vendor Specific elements "\
2452 "as a list of tuples."
2453 "The Vendor Specific information element is used to carry "\
2454 "information not defined in the standard within a single "\
2455 "defined format"
2457 vs=[]
2458 gen_get_element=self._get_elements_generator(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC)
2459 try:
2460 while 1:
2461 s=next(gen_get_element)
2463 if s is None: 2463 ↛ 2464line 2463 didn't jump to line 2464, because the condition on line 2463 was never true
2464 raise Exception("gen_get_element salio con None!!!")
2466 # OUI is 3 bytes
2467 oui=s[:3]
2468 data=s[3:]
2469 vs.append((oui,data))
2470 except StopIteration:
2471 pass
2473 return vs
2475 def add_vendor_specific(self, oui, data):
2476 "Set the 802.11 Management Vendor Specific element. "\
2477 "The Vendor Specific information element is used to carry "\
2478 "information not defined in the standard within a single "\
2479 "defined format"
2481 # 3 is the OUI length
2482 max_data_len=255-3
2483 data_len=len(data)
2485 if data_len>max_data_len: 2485 ↛ 2486line 2485 didn't jump to line 2486, because the condition on line 2485 was never true
2486 raise Exception("data allow up to %d bytes long" % max_data_len)
2487 if len(oui) > 3: 2487 ↛ 2488line 2487 didn't jump to line 2488, because the condition on line 2487 was never true
2488 raise Exception("oui is three bytes long")
2490 self._set_element(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC,oui+data, replace=False)
2492class Dot11ManagementProbeRequest(Dot11ManagementHelper):
2493 '802.11 Management Probe Request Frame'
2495 def __init__(self, aBuffer = None):
2496 header_size = 0
2497 tail_size = 0
2498 Dot11ManagementHelper.__init__(self, header_size, tail_size, aBuffer)
2500 def get_ssid(self):
2501 "Get the 802.11 Management SSID element. "\
2502 "The SSID element indicates the identity of an ESS or IBSS."
2503 return self._get_element(DOT11_MANAGEMENT_ELEMENTS.SSID)
2505 def set_ssid(self, ssid):
2506 self._set_element(DOT11_MANAGEMENT_ELEMENTS.SSID,ssid)
2508 def get_supported_rates(self, human_readable=False):
2509 "Get the 802.11 Management Supported Rates element. "\
2510 "Specifies up to eight rates, then an Extended Supported Rate element "\
2511 "shall be generated to specify the remaining supported rates."\
2512 "If human_readable is True, the rates are returned in Mbit/sec"
2513 s=self._get_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES)
2514 if s is None: 2514 ↛ 2515line 2514 didn't jump to line 2515, because the condition on line 2514 was never true
2515 return None
2517 rates=struct.unpack('%dB'%len(s),s)
2518 if not human_readable:
2519 return rates
2521 rates_Mbs=tuple([(x&0x7F)*0.5 for x in rates])
2522 return rates_Mbs
2524 def set_supported_rates(self, rates):
2525 "Set the 802.11 Management Supported Rates element. "\
2526 "Specifies a tuple or list with up to eight rates, then an "\
2527 "Extended Supported Rate element shall be generated to specify "\
2528 "the remaining supported rates."
2529 qty_rates=len(rates)
2530 if qty_rates>8: 2530 ↛ 2531line 2530 didn't jump to line 2531, because the condition on line 2530 was never true
2531 raise Exception("requires up to eight rates")
2532 rates_string=struct.pack('B'*qty_rates,*rates)
2533 self._set_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES,rates_string)
2535class Dot11ManagementProbeResponse(Dot11ManagementBeacon):
2536 '802.11 Management Probe Response Frame'
2538 def __init__(self, aBuffer = None):
2539 Dot11ManagementBeacon.__init__(self, aBuffer)
2541class DOT11_REASON_CODES():
2542 # RESERVED = 0
2543 UNSPECIFIED_REASON = 1
2544 PREV_AUTH_NO_LONGER_VALID = 2
2545 DEAUTH_STA_IS_LEAVING = 3
2546 DISASS_DUE_TO_INACTIVITY = 4
2547 DISASS_AP_UNABLE_HANDLE_ALL_STA = 5
2548 C2_FRAME_FROM_NONAUTHENTICATED_STA = 6
2549 C3_FRAME_FROM_NONASSOCIATED_STA = 7
2550 DISSASS_STA_IS_LEAVING = 8
2551 STA_REQ_NOT_AUTH_STA = 9
2552 DISASS_POWER_CAP_IE_UNNACCEPTABLE = 10
2553 DISASS_SUP_CH_IE_UNNACCEPTABLE = 11
2554 # RESERVED = 12
2555 INVALID_IE = 13
2556 MIC_FAILURE = 14
2557 FOUR_WAY_HANDSHAKE_TIMEOUT = 15
2558 GROUP_KEY_HANDSHAKE_TIMEOUT = 16
2559 IE_FOUR_WAY_HANDSHAKE_DIFFERENT = 17
2560 INVALID_GROUP_CIPHER = 18
2561 INVALID_PAIRWISE_CIPHER = 19
2562 INVALID_AKMP = 20
2563 UNSUPPORTED_RSN_IE_VERSION = 21
2564 INVALID_RSN_IE_CAP = 22
2565 X_AUTH_FAILED = 23
2566 CIPHER_SUITE_REJECTED_SECURITY_POLICY = 24
2567 # RESERVED = 25 - 31
2568 DISASS_QOS_RELATED_REASON = 32
2569 DISASS_QOS_UNSUFFICIENT_BANDWIDTH = 33
2570 DISASS_EXCESSIVE_FRAMES_WITHOUT_ACK = 34
2571 DISASS_STA_TX_OUTSIDE_TXOPS = 35
2572 REQ_STA_LEAVING = 36
2573 REQ_STA_NOT_WANT_MECHANISM = 37
2574 REQ_STA_RECV_FRAMES_WHICH_SETUP_REQ = 38
2575 REQ_STA_DUE_TIMEOUT = 39
2576 STA_NOT_SUPPORT_CIPHER_SUITE = 45
2577 # RESERVED = 46 - 65 535
2579class Dot11ManagementDeauthentication(ProtocolPacket):
2580 '802.11 Management Deauthentication Frame'
2582 def __init__(self, aBuffer = None):
2583 header_size = 2
2584 tail_size = 0
2585 if aBuffer: 2585 ↛ 2589line 2585 didn't jump to line 2589, because the condition on line 2585 was never false
2586 ProtocolPacket.__init__(self, header_size, tail_size)
2587 self.load_packet(aBuffer)
2588 else:
2589 ProtocolPacket.__init__(self, header_size, tail_size)
2591 def get_reason_code(self):
2592 "Get the 802.11 Management Deauthentication or Disassociation Code."
2593 return self.header.get_word(0, "<")
2595 def set_reason_code(self, rc):
2596 self.header.set_word(0, rc, "<")
2598class DOT11_AUTH_ALGORITHMS():
2599 OPEN = 0
2600 SHARED_KEY = 1
2602class DOT11_AUTH_STATUS_CODES():
2603 SUCCESSFUL = 0
2604 UNSPECIFIED_FAILURE = 1
2605 # RESERVED = 2 - 9
2606 CAP_REQ_UNSUPPORTED = 10
2607 REASS_DENIED_CANNOT_CONFIRM_ASS_EXISTS = 11
2608 ASS_DENIED_REASON_OUTSIDE_SCOPE_STANDARD = 12
2609 STA_NOT_SUPPORT_AUTH_ALGORITHM = 13
2610 AUTH_SEQ_OUT_OF_EXPECTED = 14
2611 AUTH_REJECTED_CHALLENGE_FAILURE = 15
2612 AUTH_REJECTED_TIMEOUT = 16
2613 ASS_DENIED_AP_UNABLE_HANDLE_MORE_STA = 17
2614 ASS_DENIED_STA_NOT_SUPPORTING_DATA_RATES = 18
2615 ASS_DENIED_STA_NOT_SUPPORTING_SHORT_PREAMBLE = 19
2616 ASS_DENIED_STA_NOT_SUPPORTING_PBCC_MODULATION = 20
2617 ASS_DENIED_STA_NOT_SUPPORTING_CHANNEL_AGILITY = 21
2618 ASS_REQUEST_REJECTED_SPACTRUM_MGT_CAP = 22
2619 ASS_REQUEST_REJECTED_POWER_CAP_IE_UNNACCEPTABLE = 23
2620 ASS_REQUEST_REJECTED_SUP_CH_IE_UNNACCEPTABLE = 24
2621 ASS_DENIED_STA_NOT_SUPPORTING_SHORT_SLOT_TIME = 25
2622 ASS_DENIED_STA_NOT_SUPPORTING_DSSS_OFDM = 26
2623 # RESERVED = 27 - 31
2624 UNSPECIFIED_QOS = 32
2625 ASS_DENIED_QOS_UNSUFFICIENT_BANDWIDTH = 33
2626 ASS_DENIED_EXCESSIVE_FRAME_LOST = 34
2627 ASS_DENIED_STA_NOT_SUPPORT_QOS = 35
2628 # RESERVED = 36
2629 REQ_HAS_BEEN_DECLINED = 37
2630 REQ_NOT_SUCCESSFUL_PARAM_INVALID_VALUE = 38
2631 TSPEC = 39
2632 INVALID_IE = 40
2633 INVALID_GROUP_CIPHER = 41
2634 INVALID_PAIRWISE_CIPHER = 42
2635 INVALID_AKMP = 43
2636 UNSUPPORTED_RSN_IE_VERSION = 44
2637 INVALID_RSN_IE_CAP = 45
2638 CIPHER_SUITE_REJECTED_SECURITY_POLICY = 46
2639 TS_NOT_CREATED = 47
2640 DIRECT_LINK_NOT_ALLOWED_BSS_POLICY = 48
2641 DST_STA_NOT_PRESENT_IN_BSS = 49
2642 DST_STA_NOT_QOS_STA = 50
2643 ASS_DENIED_LISTEN_INTERVAL_TOO_LARGE = 51
2644 # RESERVED = 52 - 65 535
2646class Dot11ManagementAuthentication(Dot11ManagementHelper):
2647 '802.11 Management Authentication Frame'
2649 __HEADER_BASE_SIZE = 6 # minimal header size
2651 def __init__(self, aBuffer = None):
2652 header_size = self.__HEADER_BASE_SIZE
2653 tail_size = 0
2654 Dot11ManagementHelper.__init__(self, header_size, tail_size, aBuffer)
2656 def get_authentication_algorithm(self):
2657 "Get the 802.11 Management Authentication Algorithm."
2658 return self.header.get_word(0, "<")
2660 def set_authentication_algorithm(self, algorithm):
2661 "Set the 802.11 Management Authentication Algorithm."
2662 self.header.set_word(0, algorithm, "<")
2664 def get_authentication_sequence(self):
2665 "Get the 802.11 Management Authentication Sequence."
2666 return self.header.get_word(2, "<")
2668 def set_authentication_sequence(self, seq):
2669 "Set the 802.11 Management Authentication Sequence."
2670 self.header.set_word(2, seq, "<")
2672 def get_authentication_status(self):
2673 "Get the 802.11 Management Authentication Status."
2674 return self.header.get_word(4, "<")
2676 def set_authentication_status(self, status):
2677 "Set the 802.11 Management Authentication Status."
2678 self.header.set_word(4, status, "<")
2680 def get_challenge_text(self):
2681 return self._get_element(DOT11_MANAGEMENT_ELEMENTS.CHALLENGE_TEXT)
2683 def set_challenge_text(self, challenge):
2684 self._set_element(DOT11_MANAGEMENT_ELEMENTS.CHALLENGE_TEXT, challenge)
2686 def get_vendor_specific(self):
2687 "Get the 802.11 Management Vendor Specific elements "\
2688 "as a list of tuples."
2689 "The Vendor Specific information element is used to carry "\
2690 "information not defined in the standard within a single "\
2691 "defined format"
2693 vs=[]
2694 gen_get_element=self._get_elements_generator(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC)
2695 try:
2696 while 1:
2697 s=next(gen_get_element)
2699 if s is None: 2699 ↛ 2700line 2699 didn't jump to line 2700, because the condition on line 2699 was never true
2700 raise Exception("gen_get_element salio con None!!!")
2702 # OUI is 3 bytes
2703 oui=s[:3]
2704 data=s[3:]
2705 vs.append((oui,data))
2706 except StopIteration:
2707 pass
2709 return vs
2711 def add_vendor_specific(self, oui, data):
2712 "Set the 802.11 Management Vendor Specific element. "\
2713 "The Vendor Specific information element is used to carry "\
2714 "information not defined in the standard within a single "\
2715 "defined format"
2717 # 3 is the OUI length
2718 max_data_len=255-3
2719 data_len=len(data)
2721 if data_len>max_data_len: 2721 ↛ 2722line 2721 didn't jump to line 2722, because the condition on line 2721 was never true
2722 raise Exception("data allow up to %d bytes long" % max_data_len)
2723 if len(oui) > 3: 2723 ↛ 2724line 2723 didn't jump to line 2724, because the condition on line 2723 was never true
2724 raise Exception("oui is three bytes long")
2726 self._set_element(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC,oui+data, replace=False)
2728class Dot11ManagementDisassociation(Dot11ManagementDeauthentication):
2729 '802.11 Management Disassociation Frame'
2731 def __init__(self, aBuffer = None):
2732 Dot11ManagementDeauthentication.__init__(self, aBuffer)
2734class Dot11ManagementAssociationRequest(Dot11ManagementHelper):
2735 '802.11 Management Association Request Frame'
2737 __HEADER_BASE_SIZE = 4 # minimal header size
2739 def __init__(self, aBuffer = None):
2740 header_size = self.__HEADER_BASE_SIZE
2741 tail_size = 0
2742 Dot11ManagementHelper.__init__(self, header_size, tail_size, aBuffer)
2744 def get_capabilities(self):
2745 'Return the 802.11 Management Association Request Frame \'Capability information\' field. '
2746 b = self.header.get_word(0, "<")
2747 return b
2749 def set_capabilities(self, value):
2750 'Set the 802.11 Management Association Request Frame \'Capability Information\' field'
2751 # set the bits
2752 nb = value & 0xFFFF
2753 self.header.set_word(0, nb, "<")
2755 def get_listen_interval(self):
2756 'Return the 802.11 Management Association Request Frame \'Listen Interval\' field. '
2757 b = self.header.get_word(2, "<")
2758 return b
2760 def set_listen_interval(self, value):
2761 'Set the 802.11 Management Association Request Frame \'Listen Interval\' field'
2762 self.header.set_word(2, value, "<")
2764 def get_ssid(self):
2765 "Get the 802.11 Management SSID element. "\
2766 "The SSID element indicates the identity of an ESS or IBSS."
2767 return self._get_element(DOT11_MANAGEMENT_ELEMENTS.SSID)
2769 def set_ssid(self, ssid):
2770 self._set_element(DOT11_MANAGEMENT_ELEMENTS.SSID,ssid)
2772 def get_supported_rates(self, human_readable=False):
2773 "Get the 802.11 Management Supported Rates element. "\
2774 "Specifies up to eight rates, then an Extended Supported Rate element "\
2775 "shall be generated to specify the remaining supported rates."\
2776 "If human_readable is True, the rates are returned in Mbit/sec"
2777 s=self._get_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES)
2778 if s is None: 2778 ↛ 2779line 2778 didn't jump to line 2779, because the condition on line 2778 was never true
2779 return None
2781 rates=struct.unpack('%dB'%len(s),s)
2782 if not human_readable:
2783 return rates
2785 rates_Mbs=tuple([(x&0x7F)*0.5 for x in rates])
2786 return rates_Mbs
2788 def set_supported_rates(self, rates):
2789 "Set the 802.11 Management Supported Rates element. "\
2790 "Specifies a tuple or list with up to eight rates, then an "\
2791 "Extended Supported Rate element shall be generated to specify "\
2792 "the remaining supported rates."
2793 qty_rates=len(rates)
2794 if qty_rates>8: 2794 ↛ 2795line 2794 didn't jump to line 2795, because the condition on line 2794 was never true
2795 raise Exception("requires up to eight rates")
2796 rates_string=struct.pack('B'*qty_rates,*rates)
2797 self._set_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES,rates_string)
2799 def get_rsn(self):
2800 "Get the 802.11 Management Robust Security Network element."
2801 s = self._get_element(DOT11_MANAGEMENT_ELEMENTS.RSN)
2802 if s is None: 2802 ↛ 2803line 2802 didn't jump to line 2803, because the condition on line 2802 was never true
2803 return None
2804 return s
2806 def set_rsn(self, data):
2807 "Set the 802.11 Management Robust Security Network element."
2808 self._set_element(DOT11_MANAGEMENT_ELEMENTS.RSN, data)
2810 def get_vendor_specific(self):
2811 "Get the 802.11 Management Vendor Specific elements "\
2812 "as a list of tuples."
2813 "The Vendor Specific information element is used to carry "\
2814 "information not defined in the standard within a single "\
2815 "defined format"
2817 vs=[]
2818 gen_get_element=self._get_elements_generator(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC)
2819 try:
2820 while 1:
2821 s=next(gen_get_element)
2823 if s is None: 2823 ↛ 2824line 2823 didn't jump to line 2824, because the condition on line 2823 was never true
2824 raise Exception("gen_get_element salio con None!!!")
2826 # OUI is 3 bytes
2827 oui=s[:3]
2828 data=s[3:]
2829 vs.append((oui,data))
2830 except StopIteration:
2831 pass
2833 return vs
2835 def add_vendor_specific(self, oui, data):
2836 "Set the 802.11 Management Vendor Specific element. "\
2837 "The Vendor Specific information element is used to carry "\
2838 "information not defined in the standard within a single "\
2839 "defined format"
2841 # 3 is the OUI length
2842 max_data_len=255-3
2843 data_len=len(data)
2845 if data_len>max_data_len: 2845 ↛ 2846line 2845 didn't jump to line 2846, because the condition on line 2845 was never true
2846 raise Exception("data allow up to %d bytes long" % max_data_len)
2847 if len(oui) > 3: 2847 ↛ 2848line 2847 didn't jump to line 2848, because the condition on line 2847 was never true
2848 raise Exception("oui is three bytes long")
2850 self._set_element(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC,oui+data, replace=False)
2852class Dot11ManagementAssociationResponse(Dot11ManagementHelper):
2853 '802.11 Management Association Response Frame'
2855 __HEADER_BASE_SIZE = 6 # minimal header size
2857 def __init__(self, aBuffer = None):
2858 header_size = self.__HEADER_BASE_SIZE
2859 tail_size = 0
2860 Dot11ManagementHelper.__init__(self, header_size, tail_size, aBuffer)
2862 def get_capabilities(self):
2863 'Return the 802.11 Management Association Response Frame \'Capability information\' field. '
2864 b = self.header.get_word(0, "<")
2865 return b
2867 def set_capabilities(self, value):
2868 'Set the 802.11 Management Association Response Frame \'Capability Information\' field'
2869 # set the bits
2870 nb = value & 0xFFFF
2871 self.header.set_word(0, nb, "<")
2873 def get_status_code(self):
2874 'Return the 802.11 Management Association Response Frame \'Status Code\' field. '
2875 b = self.header.get_word(2, "<")
2876 return b
2878 def set_status_code(self, value):
2879 'Set the 802.11 Management Association Response Frame \'Status Code\' field'
2880 self.header.set_word(2, value, "<")
2882 def get_association_id(self):
2883 'Return the 802.11 Management Association Response Frame \'Association Id\' field. '
2884 b = self.header.get_word(4, "<")
2885 return b
2887 def set_association_id(self, value):
2888 'Set the 802.11 Management Association Response Frame \'Association Id\' field'
2889 self.header.set_word(4, value, "<")
2891 def get_supported_rates(self, human_readable=False):
2892 "Get the 802.11 Management Supported Rates element. "\
2893 "Specifies up to eight rates, then an Extended Supported Rate element "\
2894 "shall be generated to specify the remaining supported rates."\
2895 "If human_readable is True, the rates are returned in Mbit/sec"
2896 s=self._get_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES)
2897 if s is None: 2897 ↛ 2898line 2897 didn't jump to line 2898, because the condition on line 2897 was never true
2898 return None
2900 rates=struct.unpack('%dB'%len(s),s)
2901 if not human_readable:
2902 return rates
2904 rates_Mbs=tuple([(x&0x7F)*0.5 for x in rates])
2905 return rates_Mbs
2907 def set_supported_rates(self, rates):
2908 "Set the 802.11 Management Supported Rates element. "\
2909 "Specifies a tuple or list with up to eight rates, then an "\
2910 "Extended Supported Rate element shall be generated to specify "\
2911 "the remaining supported rates."
2912 qty_rates=len(rates)
2913 if qty_rates>8: 2913 ↛ 2914line 2913 didn't jump to line 2914, because the condition on line 2913 was never true
2914 raise Exception("requires up to eight rates")
2915 rates_string=struct.pack('B'*qty_rates,*rates)
2916 self._set_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES,rates_string)
2918 def get_vendor_specific(self):
2919 "Get the 802.11 Management Vendor Specific elements "\
2920 "as a list of tuples."
2921 "The Vendor Specific information element is used to carry "\
2922 "information not defined in the standard within a single "\
2923 "defined format"
2925 vs=[]
2926 gen_get_element=self._get_elements_generator(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC)
2927 try:
2928 while 1:
2929 s=next(gen_get_element)
2931 if s is None: 2931 ↛ 2932line 2931 didn't jump to line 2932, because the condition on line 2931 was never true
2932 raise Exception("gen_get_element salio con None!!!")
2934 # OUI is 3 bytes
2935 oui=s[:3]
2936 data=s[3:]
2937 vs.append((oui,data))
2938 except StopIteration:
2939 pass
2941 return vs
2943 def add_vendor_specific(self, oui, data):
2944 "Set the 802.11 Management Vendor Specific element. "\
2945 "The Vendor Specific information element is used to carry "\
2946 "information not defined in the standard within a single "\
2947 "defined format"
2949 # 3 is the OUI length
2950 max_data_len=255-3
2951 data_len=len(data)
2952 if data_len>max_data_len: 2952 ↛ 2953line 2952 didn't jump to line 2953, because the condition on line 2952 was never true
2953 raise Exception("data allow up to %d bytes long" % max_data_len)
2954 if len(oui) > 3: 2954 ↛ 2955line 2954 didn't jump to line 2955, because the condition on line 2954 was never true
2955 raise Exception("oui is three bytes long")
2957 self._set_element(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC,oui+data, replace=False)
2959class Dot11ManagementReassociationRequest(Dot11ManagementHelper):
2960 '802.11 Management Reassociation Request Frame'
2962 __HEADER_BASE_SIZE = 10 # minimal header size
2964 def __init__(self, aBuffer = None):
2965 header_size = self.__HEADER_BASE_SIZE
2966 tail_size = 0
2967 Dot11ManagementHelper.__init__(self, header_size, tail_size, aBuffer)
2969 def get_capabilities(self):
2970 'Return the 802.11 Management Reassociation Request Frame \'Capability information\' field. '
2971 b = self.header.get_word(0, "<")
2972 return b
2974 def set_capabilities(self, value):
2975 'Set the 802.11 Management Reassociation Request Frame \'Capability Information\' field'
2976 # set the bits
2977 nb = value & 0xFFFF
2978 self.header.set_word(0, nb, "<")
2980 def get_listen_interval(self):
2981 'Return the 802.11 Management Reassociation Request Frame \'Listen Interval\' field. '
2982 b = self.header.get_word(2, "<")
2983 return b
2985 def set_listen_interval(self, value):
2986 'Set the 802.11 Management Reassociation Request Frame \'Listen Interval\' field'
2987 self.header.set_word(2, value, "<")
2989 def get_current_ap(self):
2990 'Return the 802.11 Management Reassociation Request Frame \'Current AP\' field.'
2991 return self.header.get_bytes()[4:10]
2993 def set_current_ap(self, value):
2994 'Set the 802.11 Management Reassociation Request Frame \'Current AP\' field'
2995 for i in range(0, 6):
2996 self.header.set_byte(4+i, value[i])
2998 def get_ssid(self):
2999 "Get the 802.11 Management SSID element. "\
3000 "The SSID element indicates the identity of an ESS or IBSS."
3001 return self._get_element(DOT11_MANAGEMENT_ELEMENTS.SSID)
3003 def set_ssid(self, ssid):
3004 self._set_element(DOT11_MANAGEMENT_ELEMENTS.SSID,ssid)
3006 def get_supported_rates(self, human_readable=False):
3007 "Get the 802.11 Management Supported Rates element. "\
3008 "Specifies up to eight rates, then an Extended Supported Rate element "\
3009 "shall be generated to specify the remaining supported rates."\
3010 "If human_readable is True, the rates are returned in Mbit/sec"
3011 s=self._get_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES)
3012 if s is None: 3012 ↛ 3013line 3012 didn't jump to line 3013, because the condition on line 3012 was never true
3013 return None
3015 rates=struct.unpack('%dB'%len(s),s)
3016 if not human_readable:
3017 return rates
3019 rates_Mbs=tuple([(x&0x7F)*0.5 for x in rates])
3020 return rates_Mbs
3022 def set_supported_rates(self, rates):
3023 "Set the 802.11 Management Supported Rates element. "\
3024 "Specifies a tuple or list with up to eight rates, then an "\
3025 "Extended Supported Rate element shall be generated to specify "\
3026 "the remaining supported rates."
3027 qty_rates=len(rates)
3028 if qty_rates>8: 3028 ↛ 3029line 3028 didn't jump to line 3029, because the condition on line 3028 was never true
3029 raise Exception("requires up to eight rates")
3030 rates_string=struct.pack('B'*qty_rates,*rates)
3031 self._set_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES,rates_string)
3033 def get_rsn(self):
3034 "Get the 802.11 Management Robust Security Network element."
3035 s = self._get_element(DOT11_MANAGEMENT_ELEMENTS.RSN)
3036 if s is None: 3036 ↛ 3037line 3036 didn't jump to line 3037, because the condition on line 3036 was never true
3037 return None
3038 return s
3040 def set_rsn(self, data):
3041 "Set the 802.11 Management Robust Security Network element."
3042 self._set_element(DOT11_MANAGEMENT_ELEMENTS.RSN, data)
3044 def get_vendor_specific(self):
3045 "Get the 802.11 Management Vendor Specific elements "\
3046 "as a list of tuples."
3047 "The Vendor Specific information element is used to carry "\
3048 "information not defined in the standard within a single "\
3049 "defined format"
3051 vs=[]
3052 gen_get_element=self._get_elements_generator(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC)
3053 try:
3054 while 1:
3055 s=next(gen_get_element)
3057 if s is None: 3057 ↛ 3058line 3057 didn't jump to line 3058, because the condition on line 3057 was never true
3058 raise Exception("gen_get_element salio con None!!!")
3060 # OUI is 3 bytes
3061 oui=s[:3]
3062 data=s[3:]
3063 vs.append((oui,data))
3064 except StopIteration:
3065 pass
3067 return vs
3069 def add_vendor_specific(self, oui, data):
3070 "Set the 802.11 Management Vendor Specific element. "\
3071 "The Vendor Specific information element is used to carry "\
3072 "information not defined in the standard within a single "\
3073 "defined format"
3075 # 3 is the OUI length
3076 max_data_len=255-3
3077 data_len=len(data)
3079 if data_len>max_data_len: 3079 ↛ 3080line 3079 didn't jump to line 3080, because the condition on line 3079 was never true
3080 raise Exception("data allow up to %d bytes long" % max_data_len)
3081 if len(oui) > 3: 3081 ↛ 3082line 3081 didn't jump to line 3082, because the condition on line 3081 was never true
3082 raise Exception("oui is three bytes long")
3084 self._set_element(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC,oui+data, replace=False)
3086class Dot11ManagementReassociationResponse(Dot11ManagementAssociationResponse):
3087 '802.11 Management Reassociation Response Frame'
3089 def __init__(self, aBuffer = None):
3090 Dot11ManagementAssociationResponse.__init__(self, aBuffer)