# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.
#
# This software is provided under under a slightly modified version
# of the Apache Software License. See the accompanying LICENSE file
# for more information.
#
# Description:
# IEEE 802.11 Network packet codecs.
#
# Author:
# Gustavo Moreira
import struct
from binascii import crc32
from impacket.ImpactPacket import ProtocolPacket
from impacket.Dot11Crypto import RC4
frequency = {
2412: 1, 2417: 2, 2422: 3, 2427: 4, 2432: 5, 2437: 6, 2442: 7, 2447: 8, 2452: 9,
2457: 10, 2462: 11, 2467: 12, 2472: 13, 2484: 14, 5170: 34, 5180: 36, 5190: 38, 5200: 40,
5210: 42, 5220: 44, 5230: 46, 5240: 48, 5260: 52, 5280: 56, 5300: 60, 5320: 64, 5500: 100,
5510: 102, 5520: 104, 5530: 106, 5540: 108, 5550: 110, 5560: 112, 5570: 114, 5580: 116, 5590: 118,
5600: 120, 5610: 122, 5620: 124, 5630: 126, 5640: 128, 5650: 130, 5660: 132, 5670: 134, 5680: 136,
5690: 138, 5700: 140, 5745: 149, 5765: 153, 5785: 157, 5805: 161, 5825: 165, 5855: 170, 5860: 172,
5865: 173, 5870: 174, 5875: 175, 5880: 176, 5885: 177, 5890: 178, 5895: 179, 5900: 180, 5905: 181,
5910: 182, 5915: 183, 5920: 184,
}
class Dot11ManagementCapabilities():
#
# Capability Information
# 0 1 2 3 4 5 6 7 8 9 A B C D E F
# +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
# | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
# +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
# | | | | | | | | | | | | | | | |
# | | | | | | | | | | | | | | |---+-- Reserved
# | | | | | | | | | | | | | |
# | | | | | | | | | | | | | |---------- DSSS-OFDM
# | | | | | | | | | | | | |
# | | | | | | | | | | | |---+-------------- Reserved
# | | | | | | | | | | |
# | | | | | | | | | | |---------------------- Short slot time
# | | | | | | | | | |
# | | | | | | | | |---+-------------------------- Reserved
# | | | | | | | |
# | | | | | | | |---------------------------------- Channel agility (802.11b)
# | | | | | | |
# | | | | | | |-------------------------------------- PBCC (802.11b)
# | | | | | |
# | | | | | |------------------------------------------ Short preamble (802.11b)
# | | | | |
# | | | | |---------------------------------------------- Privacy
# | | | |
# | | | |-------------------------------------------------- CF-Poll request
# | | |
# | | |------------------------------------------------------ CF-Pollable
# | |
# | |---------------------------------------------------------- IBSS
# |
# |-------------------------------------------------------------- ESS
#
CAPABILITY_RESERVED_1 = int("1000000000000000", 2)
CAPABILITY_RESERVED_2 = int("0100000000000000", 2)
CAPABILITY_DSSS_OFDM = int("0010000000000000", 2)
CAPABILITY_RESERVED_3 = int("0001000000000000", 2)
CAPABILITY_RESERVED_4 = int("0000100000000000", 2)
CAPABILITY_SHORT_SLOT_TIME = int("0000010000000000", 2)
CAPABILITY_RESERVED_5 = int("0000001000000000", 2)
CAPABILITY_RESERVED_6 = int("0000000100000000", 2)
CAPABILITY_CH_AGILITY = int("0000000010000000", 2)
CAPABILITY_PBCC = int("0000000001000000", 2)
CAPABILITY_SHORT_PREAMBLE = int("0000000000100000", 2)
CAPABILITY_PRIVACY = int("0000000000010000", 2)
CAPABILITY_CF_POLL_REQ = int("0000000000001000", 2)
CAPABILITY_CF_POLLABLE = int("0000000000000100", 2)
CAPABILITY_IBSS = int("0000000000000010", 2)
CAPABILITY_ESS = int("0000000000000001", 2)
class Dot11Types():
# Management Types/SubTypes
DOT11_TYPE_MANAGEMENT = int("00",2)
DOT11_SUBTYPE_MANAGEMENT_ASSOCIATION_REQUEST = int("0000",2)
DOT11_SUBTYPE_MANAGEMENT_ASSOCIATION_RESPONSE = int("0001",2)
DOT11_SUBTYPE_MANAGEMENT_REASSOCIATION_REQUEST = int("0010",2)
DOT11_SUBTYPE_MANAGEMENT_REASSOCIATION_RESPONSE = int("0011",2)
DOT11_SUBTYPE_MANAGEMENT_PROBE_REQUEST = int("0100",2)
DOT11_SUBTYPE_MANAGEMENT_PROBE_RESPONSE = int("0101",2)
DOT11_SUBTYPE_MANAGEMENT_RESERVED1 = int("0110",2)
DOT11_SUBTYPE_MANAGEMENT_RESERVED2 = int("0111",2)
DOT11_SUBTYPE_MANAGEMENT_BEACON = int("1000",2)
DOT11_SUBTYPE_MANAGEMENT_ATIM = int("1001",2)
DOT11_SUBTYPE_MANAGEMENT_DISASSOCIATION = int("1010",2)
DOT11_SUBTYPE_MANAGEMENT_AUTHENTICATION = int("1011",2)
DOT11_SUBTYPE_MANAGEMENT_DEAUTHENTICATION = int("1100",2)
DOT11_SUBTYPE_MANAGEMENT_ACTION = int("1101",2)
DOT11_SUBTYPE_MANAGEMENT_RESERVED3 = int("1110",2)
DOT11_SUBTYPE_MANAGEMENT_RESERVED4 = int("1111",2)
DOT11_TYPE_MANAGEMENT_SUBTYPE_ASSOCIATION_REQUEST = \
DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_ASSOCIATION_REQUEST<<2
DOT11_TYPE_MANAGEMENT_SUBTYPE_ASSOCIATION_RESPONSE = \
DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_ASSOCIATION_RESPONSE<<2
DOT11_TYPE_MANAGEMENT_SUBTYPE_REASSOCIATION_REQUEST = \
DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_REASSOCIATION_REQUEST<<2
DOT11_TYPE_MANAGEMENT_SUBTYPE_REASSOCIATION_RESPONSE = \
DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_REASSOCIATION_RESPONSE<<2
DOT11_TYPE_MANAGEMENT_SUBTYPE_PROBE_REQUEST = \
DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_PROBE_REQUEST<<2
DOT11_TYPE_MANAGEMENT_SUBTYPE_PROBE_RESPONSE = \
DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_PROBE_RESPONSE<<2
DOT11_TYPE_MANAGEMENT_SUBTYPE_RESERVED1 = \
DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_RESERVED1<<2
DOT11_TYPE_MANAGEMENT_SUBTYPE_RESERVED2 = \
DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_RESERVED2<<2
DOT11_TYPE_MANAGEMENT_SUBTYPE_BEACON = \
DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_BEACON<<2
DOT11_TYPE_MANAGEMENT_SUBTYPE_ATIM = \
DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_ATIM<<2
DOT11_TYPE_MANAGEMENT_SUBTYPE_DISASSOCIATION = \
DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_DISASSOCIATION<<2
DOT11_TYPE_MANAGEMENT_SUBTYPE_AUTHENTICATION = \
DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_AUTHENTICATION<<2
DOT11_TYPE_MANAGEMENT_SUBTYPE_DEAUTHENTICATION = \
DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_DEAUTHENTICATION<<2
DOT11_TYPE_MANAGEMENT_SUBTYPE_ACTION = \
DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_ACTION<<2
DOT11_TYPE_MANAGEMENT_SUBTYPE_RESERVED3 = \
DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_RESERVED3<<2
DOT11_TYPE_MANAGEMENT_SUBTYPE_RESERVED4 = \
DOT11_TYPE_MANAGEMENT|DOT11_SUBTYPE_MANAGEMENT_RESERVED4<<2
# Control Types/SubTypes
DOT11_TYPE_CONTROL = int("01",2)
DOT11_SUBTYPE_CONTROL_RESERVED1 = int("0000",2)
DOT11_SUBTYPE_CONTROL_RESERVED2 = int("0001",2)
DOT11_SUBTYPE_CONTROL_RESERVED3 = int("0010",2)
DOT11_SUBTYPE_CONTROL_RESERVED4 = int("0011",2)
DOT11_SUBTYPE_CONTROL_RESERVED5 = int("0100",2)
DOT11_SUBTYPE_CONTROL_RESERVED6 = int("0101",2)
DOT11_SUBTYPE_CONTROL_RESERVED7 = int("0110",2)
DOT11_SUBTYPE_CONTROL_RESERVED8 = int("0111",2)
DOT11_SUBTYPE_CONTROL_BLOCK_ACK_REQUEST = int("1000",2)
DOT11_SUBTYPE_CONTROL_BLOCK_ACK = int("1001",2)
DOT11_SUBTYPE_CONTROL_POWERSAVE_POLL = int("1010",2)
DOT11_SUBTYPE_CONTROL_REQUEST_TO_SEND = int("1011",2)
DOT11_SUBTYPE_CONTROL_CLEAR_TO_SEND = int("1100",2)
DOT11_SUBTYPE_CONTROL_ACKNOWLEDGMENT = int("1101",2)
DOT11_SUBTYPE_CONTROL_CF_END = int("1110",2)
DOT11_SUBTYPE_CONTROL_CF_END_CF_ACK = int("1111",2)
DOT11_TYPE_CONTROL_SUBTYPE_RESERVED1 = \
DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_RESERVED1<<2
DOT11_TYPE_CONTROL_SUBTYPE_RESERVED2 = \
DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_RESERVED2<<2
DOT11_TYPE_CONTROL_SUBTYPE_RESERVED3 = \
DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_RESERVED3<<2
DOT11_TYPE_CONTROL_SUBTYPE_RESERVED4 = \
DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_RESERVED4<<2
DOT11_TYPE_CONTROL_SUBTYPE_RESERVED5 = \
DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_RESERVED5<<2
DOT11_TYPE_CONTROL_SUBTYPE_RESERVED6 = \
DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_RESERVED6<<2
DOT11_TYPE_CONTROL_SUBTYPE_RESERVED7 = \
DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_RESERVED7<<2
DOT11_TYPE_CONTROL_SUBTYPE_BLOCK_ACK_REQUEST = \
DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_BLOCK_ACK_REQUEST<<2
DOT11_TYPE_CONTROL_SUBTYPE_BLOCK_ACK = \
DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_BLOCK_ACK<<2
DOT11_TYPE_CONTROL_SUBTYPE_POWERSAVE_POLL = \
DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_POWERSAVE_POLL<<2
DOT11_TYPE_CONTROL_SUBTYPE_REQUEST_TO_SEND = \
DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_REQUEST_TO_SEND<<2
DOT11_TYPE_CONTROL_SUBTYPE_CLEAR_TO_SEND = \
DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_CLEAR_TO_SEND<<2
DOT11_TYPE_CONTROL_SUBTYPE_ACKNOWLEDGMENT = \
DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_ACKNOWLEDGMENT<<2
DOT11_TYPE_CONTROL_SUBTYPE_CF_END = \
DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_CF_END<<2
DOT11_TYPE_CONTROL_SUBTYPE_CF_END_CF_ACK = \
DOT11_TYPE_CONTROL|DOT11_SUBTYPE_CONTROL_CF_END_CF_ACK<<2
# Data Types/SubTypes
DOT11_TYPE_DATA = int("10",2)
DOT11_SUBTYPE_DATA = int("0000",2)
DOT11_SUBTYPE_DATA_CF_ACK = int("0001",2)
DOT11_SUBTYPE_DATA_CF_POLL = int("0010",2)
DOT11_SUBTYPE_DATA_CF_ACK_CF_POLL = int("0011",2)
DOT11_SUBTYPE_DATA_NULL_NO_DATA = int("0100",2)
DOT11_SUBTYPE_DATA_CF_ACK_NO_DATA = int("0101",2)
DOT11_SUBTYPE_DATA_CF_POLL_NO_DATA = int("0110",2)
DOT11_SUBTYPE_DATA_CF_ACK_CF_POLL_NO_DATA = int("0111",2)
DOT11_SUBTYPE_DATA_QOS_DATA = int("1000",2)
DOT11_SUBTYPE_DATA_QOS_DATA_CF_ACK = int("1001",2)
DOT11_SUBTYPE_DATA_QOS_DATA_CF_POLL = int("1010",2)
DOT11_SUBTYPE_DATA_QOS_DATA_CF_ACK_CF_POLL = int("1011",2)
DOT11_SUBTYPE_DATA_QOS_NULL_NO_DATA = int("1100",2)
DOT11_SUBTYPE_DATA_RESERVED1 = int("1101",2)
DOT11_SUBTYPE_DATA_QOS_CF_POLL_NO_DATA = int("1110",2)
DOT11_SUBTYPE_DATA_QOS_CF_ACK_CF_POLL_NO_DATA = int("1111",2)
DOT11_TYPE_DATA_SUBTYPE_DATA = \
DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA<<2
DOT11_TYPE_DATA_SUBTYPE_CF_ACK = \
DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_CF_ACK<<2
DOT11_TYPE_DATA_SUBTYPE_CF_POLL = \
DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_CF_POLL<<2
DOT11_TYPE_DATA_SUBTYPE_CF_ACK_CF_POLL = \
DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_CF_ACK_CF_POLL<<2
DOT11_TYPE_DATA_SUBTYPE_NULL_NO_DATA = \
DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_NULL_NO_DATA<<2
DOT11_TYPE_DATA_SUBTYPE_CF_ACK_NO_DATA = \
DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_CF_POLL_NO_DATA<<2
DOT11_TYPE_DATA_SUBTYPE_CF_ACK_CF_POLL_NO_DATA = \
DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_CF_ACK_CF_POLL_NO_DATA<<2
DOT11_TYPE_DATA_SUBTYPE_QOS_DATA = \
DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_QOS_DATA<<2
DOT11_TYPE_DATA_SUBTYPE_QOS_DATA_CF_ACK = \
DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_QOS_DATA_CF_ACK<<2
DOT11_TYPE_DATA_SUBTYPE_QOS_DATA_CF_POLL = \
DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_QOS_DATA_CF_POLL<<2
DOT11_TYPE_DATA_SUBTYPE_QOS_DATA_CF_ACK_CF_POLL = \
DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_QOS_DATA_CF_ACK_CF_POLL<<2
DOT11_TYPE_DATA_SUBTYPE_QOS_NULL_NO_DATA = \
DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_QOS_NULL_NO_DATA<<2
DOT11_TYPE_DATA_SUBTYPE_RESERVED1 = \
DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_RESERVED1<<2
DOT11_TYPE_DATA_SUBTYPE_QOS_CF_POLL_NO_DATA = \
DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_QOS_CF_POLL_NO_DATA<<2
DOT11_TYPE_DATA_SUBTYPE_QOS_CF_ACK_CF_POLL_NO_DATA = \
DOT11_TYPE_DATA|DOT11_SUBTYPE_DATA_QOS_CF_ACK_CF_POLL_NO_DATA<<2
# Reserved Types/SubTypes
DOT11_TYPE_RESERVED = int("11",2)
DOT11_SUBTYPE_RESERVED_RESERVED1 = int("0000",2)
DOT11_SUBTYPE_RESERVED_RESERVED2 = int("0001",2)
DOT11_SUBTYPE_RESERVED_RESERVED3 = int("0010",2)
DOT11_SUBTYPE_RESERVED_RESERVED4 = int("0011",2)
DOT11_SUBTYPE_RESERVED_RESERVED5 = int("0100",2)
DOT11_SUBTYPE_RESERVED_RESERVED6 = int("0101",2)
DOT11_SUBTYPE_RESERVED_RESERVED7 = int("0110",2)
DOT11_SUBTYPE_RESERVED_RESERVED8 = int("0111",2)
DOT11_SUBTYPE_RESERVED_RESERVED9 = int("1000",2)
DOT11_SUBTYPE_RESERVED_RESERVED10 = int("1001",2)
DOT11_SUBTYPE_RESERVED_RESERVED11 = int("1010",2)
DOT11_SUBTYPE_RESERVED_RESERVED12 = int("1011",2)
DOT11_SUBTYPE_RESERVED_RESERVED13 = int("1100",2)
DOT11_SUBTYPE_RESERVED_RESERVED14 = int("1101",2)
DOT11_SUBTYPE_RESERVED_RESERVED15 = int("1110",2)
DOT11_SUBTYPE_RESERVED_RESERVED16 = int("1111",2)
DOT11_TYPE_RESERVED_SUBTYPE_RESERVED1 = \
DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED1<<2
DOT11_TYPE_RESERVED_SUBTYPE_RESERVED2 = \
DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED2<<2
DOT11_TYPE_RESERVED_SUBTYPE_RESERVED3 = \
DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED3<<2
DOT11_TYPE_RESERVED_SUBTYPE_RESERVED4 = \
DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED4<<2
DOT11_TYPE_RESERVED_SUBTYPE_RESERVED5 = \
DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED5<<2
DOT11_TYPE_RESERVED_SUBTYPE_RESERVED6 = \
DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED6<<2
DOT11_TYPE_RESERVED_SUBTYPE_RESERVED7 = \
DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED7<<2
DOT11_TYPE_RESERVED_SUBTYPE_RESERVED8 = \
DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED8<<2
DOT11_TYPE_RESERVED_SUBTYPE_RESERVED9 = \
DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED9<<2
DOT11_TYPE_RESERVED_SUBTYPE_RESERVED10 = \
DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED10<<2
DOT11_TYPE_RESERVED_SUBTYPE_RESERVED11 = \
DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED11<<2
DOT11_TYPE_RESERVED_SUBTYPE_RESERVED12 = \
DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED12<<2
DOT11_TYPE_RESERVED_SUBTYPE_RESERVED13 = \
DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED13<<2
DOT11_TYPE_RESERVED_SUBTYPE_RESERVED14 = \
DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED14<<2
DOT11_TYPE_RESERVED_SUBTYPE_RESERVED15 = \
DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED15<<2
DOT11_TYPE_RESERVED_SUBTYPE_RESERVED16 = \
DOT11_TYPE_RESERVED|DOT11_SUBTYPE_RESERVED_RESERVED16<<2
class Dot11(ProtocolPacket):
def __init__(self, aBuffer = None, FCS_at_end = True):
header_size = 2
self.__FCS_at_end=not not FCS_at_end # Is Boolean
if self.__FCS_at_end:
tail_size = 4
else:
tail_size = 0
ProtocolPacket.__init__(self, header_size,tail_size)
if(aBuffer):
self.load_packet(aBuffer)
def get_order(self):
"Return 802.11 frame 'Order' field"
b = self.header.get_byte(1)
return ((b >> 7) & 0x01)
def set_order(self, value):
"Set 802.11 frame 'Order' field"
# clear the bits
mask = (~0x80) & 0xFF
masked = self.header.get_byte(1) & mask
# set the bits
nb = masked | ((value & 0x01) << 7)
self.header.set_byte(1, nb)
def get_protectedFrame(self):
"Return 802.11 frame 'Protected' field"
b = self.header.get_byte(1)
return ((b >> 6) & 0x01)
def set_protectedFrame(self, value):
"Set 802.11 frame 'Protected Frame' field"
# clear the bits
mask = (~0x40) & 0xFF
masked = self.header.get_byte(1) & mask
# set the bits
nb = masked | ((value & 0x01) << 6)
self.header.set_byte(1, nb)
def get_moreData(self):
"Return 802.11 frame 'More Data' field"
b = self.header.get_byte(1)
return ((b >> 5) & 0x01)
def set_moreData(self, value):
"Set 802.11 frame 'More Data' field"
# clear the bits
mask = (~0x20) & 0xFF
masked = self.header.get_byte(1) & mask
# set the bits
nb = masked | ((value & 0x01) << 5)
self.header.set_byte(1, nb)
def get_powerManagement(self):
"Return 802.11 frame 'Power Management' field"
b = self.header.get_byte(1)
return ((b >> 4) & 0x01)
def set_powerManagement(self, value):
"Set 802.11 frame 'Power Management' field"
# clear the bits
mask = (~0x10) & 0xFF
masked = self.header.get_byte(1) & mask
# set the bits
nb = masked | ((value & 0x01) << 4)
self.header.set_byte(1, nb)
def get_retry(self):
"Return 802.11 frame 'Retry' field"
b = self.header.get_byte(1)
return ((b >> 3) & 0x01)
def set_retry(self, value):
"Set 802.11 frame 'Retry' field"
# clear the bits
mask = (~0x08) & 0xFF
masked = self.header.get_byte(1) & mask
# set the bits
nb = masked | ((value & 0x01) << 3)
self.header.set_byte(1, nb)
def get_moreFrag(self):
"Return 802.11 frame 'More Fragments' field"
b = self.header.get_byte(1)
return ((b >> 2) & 0x01)
def set_moreFrag(self, value):
"Set 802.11 frame 'More Fragments' field"
# clear the bits
mask = (~0x04) & 0xFF
masked = self.header.get_byte(1) & mask
# set the bits
nb = masked | ((value & 0x01) << 2)
self.header.set_byte(1, nb)
def get_fromDS(self):
"Return 802.11 frame 'from DS' field"
b = self.header.get_byte(1)
return ((b >> 1) & 0x01)
def set_fromDS(self, value):
"Set 802.11 frame 'from DS' field"
# clear the bits
mask = (~0x02) & 0xFF
masked = self.header.get_byte(1) & mask
# set the bits
nb = masked | ((value & 0x01) << 1)
self.header.set_byte(1, nb)
def get_toDS(self):
"Return 802.11 frame 'to DS' field"
b = self.header.get_byte(1)
return (b & 0x01)
def set_toDS(self, value):
"Set 802.11 frame 'to DS' field"
# clear the bits
mask = (~0x01) & 0xFF
masked = self.header.get_byte(1) & mask
# set the bits
nb = masked | (value & 0x01)
self.header.set_byte(1, nb)
def get_subtype(self):
"Return 802.11 frame 'subtype' field"
b = self.header.get_byte(0)
return ((b >> 4) & 0x0F)
def set_subtype(self, value):
"Set 802.11 frame 'subtype' field"
# clear the bits
mask = (~0xF0)&0xFF
masked = self.header.get_byte(0) & mask
# set the bits
nb = masked | ((value << 4) & 0xF0)
self.header.set_byte(0, nb)
def get_type(self):
"Return 802.11 frame 'type' field"
b = self.header.get_byte(0)
return ((b >> 2) & 0x03)
def set_type(self, value):
"Set 802.11 frame 'type' field"
# clear the bits
mask = (~0x0C)&0xFF
masked = self.header.get_byte(0) & mask
# set the bits
nb = masked | ((value << 2) & 0x0C)
self.header.set_byte(0, nb)
def get_type_n_subtype(self):
"Return 802.11 frame 'Type and Subtype' field"
b = self.header.get_byte(0)
return ((b >> 2) & 0x3F)
def set_type_n_subtype(self, value):
"Set 802.11 frame 'Type and Subtype' field"
# clear the bits
mask = (~0xFC)&0xFF
masked = self.header.get_byte(0) & mask
# set the bits
nb = masked | ((value << 2) & 0xFC)
self.header.set_byte(0, nb)
def get_version(self):
"Return 802.11 frame control 'Protocol version' field"
b = self.header.get_byte(0)
return (b & 0x03)
def set_version(self, value):
"Set the 802.11 frame control 'Protocol version' field"
# clear the bits
mask = (~0x03)&0xFF
masked = self.header.get_byte(0) & mask
# set the bits
nb = masked | (value & 0x03)
self.header.set_byte(0, nb)
def compute_checksum(self,bytes):
crcle=crc32(bytes)&0xffffffff
# ggrr this crc32 is in little endian, convert it to big endian
crc=struct.pack('<L', crcle)
# Convert to long
(crc_long,) = struct.unpack('!L', crc)
return crc_long
def is_QoS_frame(self):
"Return 'True' if is an QoS data frame type"
b = self.header.get_byte(0)
return (b & 0x80) and True
def is_no_framebody_frame(self):
"Return 'True' if it frame contain no Frame Body"
b = self.header.get_byte(0)
return (b & 0x40) and True
def is_cf_poll_frame(self):
"Return 'True' if it frame is a CF_POLL frame"
b = self.header.get_byte(0)
return (b & 0x20) and True
def is_cf_ack_frame(self):
"Return 'True' if it frame is a CF_ACK frame"
b = self.header.get_byte(0)
return (b & 0x10) and True
def get_fcs(self):
"Return 802.11 'FCS' field"
if not self.__FCS_at_end:
return None
b = self.tail.get_long(-4, ">")
return b
def set_fcs(self, value = None):
"Set the 802.11 CTS control frame 'FCS' field. If value is None, is auto_checksum"
if not self.__FCS_at_end:
return
# calculate the FCS
if value is None:
payload = self.get_body_as_string()
crc32=self.compute_checksum(payload)
value=crc32
# set the bits
nb = value & 0xFFFFFFFF
self.tail.set_long(-4, nb)
class Dot11ControlFrameCTS(ProtocolPacket):
"802.11 Clear-To-Send Control Frame"
def __init__(self, aBuffer = None):
header_size = 8
tail_size = 0
ProtocolPacket.__init__(self, header_size, tail_size)
532 ↛ exitline 532 didn't return from function '__init__', because the condition on line 532 was never false if(aBuffer):
self.load_packet(aBuffer)
def get_duration(self):
"Return 802.11 CTS control frame 'Duration' field"
b = self.header.get_word(0, "<")
return b
def set_duration(self, value):
"Set the 802.11 CTS control frame 'Duration' field"
# set the bits
nb = value & 0xFFFF
self.header.set_word(0, nb, "<")
def get_ra(self):
"Return 802.11 CTS control frame 48 bit 'Receiver Address' field as a 6 bytes array"
return self.header.get_bytes()[2:8]
def set_ra(self, value):
"Set 802.11 CTS control frame 48 bit 'Receiver Address' field as a 6 bytes array"
for i in range(0, 6):
self.header.set_byte(2+i, value[i])
class Dot11ControlFrameACK(ProtocolPacket):
"802.11 Acknowledgement Control Frame"
def __init__(self, aBuffer = None):
header_size = 8
tail_size = 0
ProtocolPacket.__init__(self, header_size, tail_size)
563 ↛ exitline 563 didn't return from function '__init__', because the condition on line 563 was never false if(aBuffer):
self.load_packet(aBuffer)
def get_duration(self):
"Return 802.11 ACK control frame 'Duration' field"
b = self.header.get_word(0, "<")
return b
def set_duration(self, value):
"Set the 802.11 ACK control frame 'Duration' field"
# set the bits
nb = value & 0xFFFF
self.header.set_word(0, nb, "<")
def get_ra(self):
"Return 802.11 ACK control frame 48 bit 'Receiver Address' field as a 6 bytes array"
return self.header.get_bytes()[2:8]
def set_ra(self, value):
"Set 802.11 ACK control frame 48 bit 'Receiver Address' field as a 6 bytes array"
for i in range(0, 6):
self.header.set_byte(2+i, value[i])
class Dot11ControlFrameRTS(ProtocolPacket):
"802.11 Request-To-Send Control Frame"
def __init__(self, aBuffer = None):
header_size = 14
tail_size = 0
ProtocolPacket.__init__(self, header_size, tail_size)
594 ↛ exitline 594 didn't return from function '__init__', because the condition on line 594 was never false if(aBuffer):
self.load_packet(aBuffer)
def get_duration(self):
"Return 802.11 RTS control frame 'Duration' field"
b = self.header.get_word(0, "<")
return b
def set_duration(self, value):
"Set the 802.11 RTS control frame 'Duration' field"
# set the bits
nb = value & 0xFFFF
self.header.set_word(0, nb, "<")
def get_ra(self):
"Return 802.11 RTS control frame 48 bit 'Receiver Address' field as a 6 bytes array"
return self.header.get_bytes()[2:8]
def set_ra(self, value):
"Set 802.11 RTS control frame 48 bit 'Receiver Address' field as a 6 bytes array"
for i in range(0, 6):
self.header.set_byte(2+i, value[i])
def get_ta(self):
"Return 802.11 RTS control frame 48 bit 'Transmitter Address' field as a 6 bytes array"
return self.header.get_bytes()[8:14]
def set_ta(self, value):
"Set 802.11 RTS control frame 48 bit 'Transmitter Address' field as a 6 bytes array"
for i in range(0, 6):
self.header.set_byte(8+i, value[i])
class Dot11ControlFramePSPoll(ProtocolPacket):
"802.11 Power-Save Poll Control Frame"
def __init__(self, aBuffer = None):
header_size = 14
tail_size = 0
ProtocolPacket.__init__(self, header_size, tail_size)
634 ↛ exitline 634 didn't return from function '__init__', because the condition on line 634 was never false if(aBuffer):
self.load_packet(aBuffer)
def get_aid(self):
"Return 802.11 PSPoll control frame 'AID' field"
# the spec says "The AID value always has its two MSBs each set to 1."
# TODO: Should we do check/modify it? Wireshark shows the only MSB to 0
b = self.header.get_word(0, "<")
return b
def set_aid(self, value):
"Set the 802.11 PSPoll control frame 'AID' field"
# set the bits
nb = value & 0xFFFF
# the spec says "The AID value always has its two MSBs each set to 1."
# TODO: Should we do check/modify it? Wireshark shows the only MSB to 0
self.header.set_word(0, nb, "<")
def get_bssid(self):
"Return 802.11 PSPoll control frame 48 bit 'BSS ID' field as a 6 bytes array"
return self.header.get_bytes()[2:8]
def set_bssid(self, value):
"Set 802.11 PSPoll control frame 48 bit 'BSS ID' field as a 6 bytes array"
for i in range(0, 6):
self.header.set_byte(2+i, value[i])
def get_ta(self):
"Return 802.11 PSPoll control frame 48 bit 'Transmitter Address' field as a 6 bytes array"
return self.header.get_bytes()[8:14]
def set_ta(self, value):
"Set 802.11 PSPoll control frame 48 bit 'Transmitter Address' field as a 6 bytes array"
for i in range(0, 6):
self.header.set_byte(8+i, value[i])
class Dot11ControlFrameCFEnd(ProtocolPacket):
"802.11 'Contention Free End' Control Frame"
def __init__(self, aBuffer = None):
header_size = 14
tail_size = 0
ProtocolPacket.__init__(self, header_size, tail_size)
678 ↛ exitline 678 didn't return from function '__init__', because the condition on line 678 was never false if(aBuffer):
self.load_packet(aBuffer)
def get_duration(self):
"Return 802.11 CF-End control frame 'Duration' field"
b = self.header.get_word(0, "<")
return b
def set_duration(self, value):
"Set the 802.11 CF-End control frame 'Duration' field"
# set the bits
nb = value & 0xFFFF
self.header.set_word(0, nb, "<")
def get_ra(self):
"Return 802.11 CF-End control frame 48 bit 'Receiver Address' field as a 6 bytes array"
return self.header.get_bytes()[2:8]
def set_ra(self, value):
"Set 802.11 CF-End control frame 48 bit 'Receiver Address' field as a 6 bytes array"
for i in range(0, 6):
self.header.set_byte(2+i, value[i])
def get_bssid(self):
"Return 802.11 CF-End control frame 48 bit 'BSS ID' field as a 6 bytes array"
return self.header.get_bytes()[8:14]
def set_bssid(self, value):
"Set 802.11 CF-End control frame 48 bit 'BSS ID' field as a 6 bytes array"
for i in range(0, 6):
self.header.set_byte(8+i, value[i])
class Dot11ControlFrameCFEndCFACK(ProtocolPacket):
'802.11 \'CF-End + CF-ACK\' Control Frame'
def __init__(self, aBuffer = None):
header_size = 14
tail_size = 0
ProtocolPacket.__init__(self, header_size, tail_size)
718 ↛ exitline 718 didn't return from function '__init__', because the condition on line 718 was never false if(aBuffer):
self.load_packet(aBuffer)
def get_duration(self):
'Return 802.11 \'CF-End+CF-ACK\' control frame \'Duration\' field'
b = self.header.get_word(0, "<")
return b
def set_duration(self, value):
'Set the 802.11 \'CF-End+CF-ACK\' control frame \'Duration\' field'
# set the bits
nb = value & 0xFFFF
self.header.set_word(0, nb, "<")
def get_ra(self):
'Return 802.11 \'CF-End+CF-ACK\' control frame 48 bit \'Receiver Address\' field as a 6 bytes array'
return self.header.get_bytes()[2:8]
def set_ra(self, value):
'Set 802.11 \'CF-End+CF-ACK\' control frame 48 bit \'Receiver Address\' field as a 6 bytes array'
for i in range(0, 6):
self.header.set_byte(2+i, value[i])
def get_bssid(self):
'Return 802.11 \'CF-End+CF-ACK\' control frame 48 bit \'BSS ID\' field as a 6 bytes array'
return self.header.get_bytes()[8:16]
def set_bssid(self, value):
'Set 802.11 \'CF-End+CF-ACK\' control frame 48 bit \'BSS ID\' field as a 6 bytes array'
for i in range(0, 6):
self.header.set_byte(8+i, value[i])
class Dot11DataFrame(ProtocolPacket):
'802.11 Data Frame'
def __init__(self, aBuffer = None):
header_size = 22
tail_size = 0
ProtocolPacket.__init__(self, header_size, tail_size)
if(aBuffer):
self.load_packet(aBuffer)
def get_duration(self):
'Return 802.11 \'Data\' data frame \'Duration\' field'
b = self.header.get_word(0, "<")
return b
def set_duration(self, value):
'Set the 802.11 \'Data\' data frame \'Duration\' field'
# set the bits
nb = value & 0xFFFF
self.header.set_word(0, nb, "<")
def get_address1(self):
'Return 802.11 \'Data\' data frame 48 bit \'Address1\' field as a 6 bytes array'
return self.header.get_bytes()[2:8]
def set_address1(self, value):
'Set 802.11 \'Data\' data frame 48 bit \'Address1\' field as a 6 bytes array'
for i in range(0, 6):
self.header.set_byte(2+i, value[i])
def get_address2(self):
'Return 802.11 \'Data\' data frame 48 bit \'Address2\' field as a 6 bytes array'
return self.header.get_bytes()[8:14]
def set_address2(self, value):
'Set 802.11 \'Data\' data frame 48 bit \'Address2\' field as a 6 bytes array'
for i in range(0, 6):
self.header.set_byte(8+i, value[i])
def get_address3(self):
'Return 802.11 \'Data\' data frame 48 bit \'Address3\' field as a 6 bytes array'
return self.header.get_bytes()[14: 20]
def set_address3(self, value):
'Set 802.11 \'Data\' data frame 48 bit \'Address3\' field as a 6 bytes array'
for i in range(0, 6):
self.header.set_byte(14+i, value[i])
def get_sequence_control(self):
'Return 802.11 \'Data\' data frame \'Sequence Control\' field'
b = self.header.get_word(20, "<")
return b
def set_sequence_control(self, value):
'Set the 802.11 \'Data\' data frame \'Sequence Control\' field'
# set the bits
nb = value & 0xFFFF
self.header.set_word(20, nb, "<")
def get_fragment_number(self):
'Return 802.11 \'Data\' data frame \'Fragment Number\' subfield'
b = self.header.get_word(20, "<")
return (b&0x000F)
def set_fragment_number(self, value):
'Set the 802.11 \'Data\' data frame \'Fragment Number\' subfield'
# clear the bits
mask = (~0x000F) & 0xFFFF
masked = self.header.get_word(20, "<") & mask
# set the bits
nb = masked | (value & 0x000F)
self.header.set_word(20, nb, "<")
def get_sequence_number(self):
'Return 802.11 \'Data\' data frame \'Sequence Number\' subfield'
b = self.header.get_word(20, "<")
return ((b>>4) & 0xFFF)
def set_sequence_number(self, value):
'Set the 802.11 \'Data\' data frame \'Sequence Number\' subfield'
# clear the bits
mask = (~0xFFF0) & 0xFFFF
masked = self.header.get_word(20, "<") & mask
# set the bits
nb = masked | ((value & 0x0FFF ) << 4 )
self.header.set_word(20, nb, "<")
def get_frame_body(self):
'Return 802.11 \'Data\' data frame \'Frame Body\' field'
return self.get_body_as_string()
def set_frame_body(self, data):
'Set 802.11 \'Data\' data frame \'Frame Body\' field'
self.load_body(data)
class Dot11DataQoSFrame(Dot11DataFrame):
'802.11 Data QoS Frame'
def __init__(self, aBuffer = None):
header_size = 24
tail_size = 0
ProtocolPacket.__init__(self, header_size, tail_size)
if(aBuffer):
self.load_packet(aBuffer)
def get_QoS(self):
'Return 802.11 \'Data\' data frame \'QoS\' field'
b = self.header.get_word(22, "<")
return b
def set_QoS(self, value):
'Set the 802.11 \'Data\' data frame \'QoS\' field'
# set the bits
nb = value & 0xFFFF
self.header.set_word(22, nb, "<")
class Dot11DataAddr4Frame(Dot11DataFrame):
'802.11 Data With ToDS From DS Flags (With Addr 4) Frame'
def __init__(self, aBuffer = None):
header_size = 28
tail_size = 0
ProtocolPacket.__init__(self, header_size, tail_size)
if(aBuffer):
self.load_packet(aBuffer)
def get_address4(self):
'Return 802.11 \'Data\' data frame 48 bit \'Address4\' field as a 6 bytes array'
return self.header.get_bytes()[22:28]
def set_address4(self, value):
'Set 802.11 \'Data\' data frame 48 bit \'Address4\' field as a 6 bytes array'
for i in range(0, 6):
self.header.set_byte(22+i, value[i])
class Dot11DataAddr4QoSFrame(Dot11DataAddr4Frame):
'802.11 Data With ToDS From DS Flags (With Addr 4) and QoS Frame'
def __init__(self, aBuffer = None):
header_size = 30
tail_size = 0
ProtocolPacket.__init__(self, header_size, tail_size)
if(aBuffer):
self.load_packet(aBuffer)
def get_QoS(self):
'Return 802.11 \'Data\' data frame \'QoS\' field'
b = self.header.get_word(28, "<")
return b
def set_QoS(self, value):
'Set the 802.11 \'Data\' data frame \'QoS\' field'
# set the bits
nb = value & 0xFFFF
self.header.set_word(28, nb, "<")
class SAPTypes():
NULL = 0x00
LLC_SLMGMT = 0x02
SNA_PATHCTRL = 0x04
IP = 0x06
SNA1 = 0x08
SNA2 = 0x0C
PROWAY_NM_INIT = 0x0E
NETWARE1 = 0x10
OSINL1 = 0x14
TI = 0x18
OSINL2 = 0x20
OSINL3 = 0x34
SNA3 = 0x40
BPDU = 0x42
RS511 = 0x4E
OSINL4 = 0x54
X25 = 0x7E
XNS = 0x80
BACNET = 0x82
NESTAR = 0x86
PROWAY_ASLM = 0x8E
ARP = 0x98
SNAP = 0xAA
HPJD = 0xB4
VINES1 = 0xBA
VINES2 = 0xBC
NETWARE2 = 0xE0
NETBIOS = 0xF0
IBMNM = 0xF4
HPEXT = 0xF8
UB = 0xFA
RPL = 0xFC
OSINL5 = 0xFE
GLOBAL = 0xFF
class LLC(ProtocolPacket):
'802.2 Logical Link Control (LLC) Frame'
DLC_UNNUMBERED_FRAMES = 0x03
def __init__(self, aBuffer = None):
header_size = 3
tail_size = 0
ProtocolPacket.__init__(self, header_size, tail_size)
if(aBuffer):
self.load_packet(aBuffer)
def get_DSAP(self):
"Get the Destination Service Access Point (SAP) from LLC frame"
return self.header.get_byte(0)
def set_DSAP(self, value):
"Set the Destination Service Access Point (SAP) of LLC frame"
self.header.set_byte(0, value)
def get_SSAP(self):
"Get the Source Service Access Point (SAP) from LLC frame"
return self.header.get_byte(1)
def set_SSAP(self, value):
"Set the Source Service Access Point (SAP) of LLC frame"
self.header.set_byte(1, value)
def get_control(self):
"Get the Control field from LLC frame"
return self.header.get_byte(2)
def set_control(self, value):
"Set the Control field of LLC frame"
self.header.set_byte(2, value)
class SNAP(ProtocolPacket):
'802.2 SubNetwork Access Protocol (SNAP) Frame'
def __init__(self, aBuffer = None):
header_size = 5
tail_size = 0
ProtocolPacket.__init__(self, header_size, tail_size)
if(aBuffer):
self.load_packet(aBuffer)
def get_OUI(self):
"Get the three-octet Organizationally Unique Identifier (OUI) SNAP frame"
b=self.header.get_bytes()[0:3].tostring()
#unpack requires a string argument of length 4 and b is 3 bytes long
(oui,)=struct.unpack('!L', b'\x00'+b)
return oui
def set_OUI(self, value):
"Set the three-octet Organizationally Unique Identifier (OUI) SNAP frame"
# clear the bits
mask = ((~0xFFFFFF00) & 0xFF)
masked = self.header.get_long(0, ">") & mask
# set the bits
nb = masked | ((value & 0x00FFFFFF) << 8)
self.header.set_long(0, nb)
def get_protoID(self):
"Get the two-octet Protocol Identifier (PID) SNAP field"
return self.header.get_word(3, ">")
def set_protoID(self, value):
"Set the two-octet Protocol Identifier (PID) SNAP field"
self.header.set_word(3, value, ">")
class Dot11WEP(ProtocolPacket):
'802.11 WEP'
def __init__(self, aBuffer = None):
header_size = 4
tail_size = 0
ProtocolPacket.__init__(self, header_size, tail_size)
if(aBuffer):
self.load_packet(aBuffer)
def is_WEP(self):
'Return True if it\'s a WEP'
# We already know that it's private.
# Now we must differentiate between WEP and WPA/WPA2
# WPA/WPA2 have the ExtIV (Bit 5) enaled and WEP disabled
b = self.header.get_byte(3)
return not (b & 0x20)
def get_iv(self):
'Return the \'WEP IV\' field'
b=self.header.get_bytes()[0:3].tostring()
#unpack requires a string argument of length 4 and b is 3 bytes long
(iv,)=struct.unpack('!L', b'\x00'+b)
return iv
def set_iv(self, value):
'Set the \'WEP IV\' field.'
# clear the bits
mask = ((~0xFFFFFF00) & 0xFF)
masked = self.header.get_long(0, ">") & mask
# set the bits
nb = masked | ((value & 0x00FFFFFF) << 8)
self.header.set_long(0, nb)
def get_keyid(self):
'Return the \'WEP KEY ID\' field'
b = self.header.get_byte(3)
return ((b>>6) & 0x03)
def set_keyid(self, value):
'Set the \'WEP KEY ID\' field'
# clear the bits
mask = (~0xC0) & 0xFF
masked = self.header.get_byte(3) & mask
# set the bits
nb = masked | ((value & 0x03) << 6)
self.header.set_byte(3, nb)
def get_decrypted_data(self, key_string):
'Return \'WEP Data\' field decrypted'
# Needs to be at least 8 bytes of payload
1075 ↛ 1076line 1075 didn't jump to line 1076, because the condition on line 1075 was never true if len(self.body_string)<8:
return self.body_string
# initialize the first bytes of the key from the IV
# and copy rest of the WEP key (the secret part)
# Convert IV to 3 bytes long string
iv=struct.pack('>L',self.get_iv())[-3:]
key=iv+key_string
rc4=RC4(key)
decrypted_data=rc4.decrypt(self.body_string)
return decrypted_data
def get_encrypted_data(self, key_string):
# RC4 is symmetric
return self.get_decrypted_data(key_string)
def encrypt_frame(self, key_string):
enc = self.get_encrypted_data(key_string)
self.load_body(enc)
class Dot11WEPData(ProtocolPacket):
'802.11 WEP Data Part'
def __init__(self, aBuffer = None):
header_size = 0
tail_size = 4
ProtocolPacket.__init__(self, header_size, tail_size)
if(aBuffer):
self.load_packet(aBuffer)
def get_icv(self):
"Return 'WEP ICV' field"
b = self.tail.get_long(-4, ">")
return b
def set_icv(self, value = None):
"Set 'WEP ICV' field"
# Compute the WEP ICV
1118 ↛ 1119line 1118 didn't jump to line 1119, because the condition on line 1118 was never true if value is None:
value=self.get_computed_icv()
# set the bits
nb = value & 0xFFFFFFFF
self.tail.set_long(-4, nb)
def get_computed_icv(self):
crcle=crc32(self.body_string)&0xffffffff
# This crc32 is in little endian, convert it to big endian
crc=struct.pack('<L', crcle)
# Convert to long
(crc_long,) = struct.unpack('!L', crc)
return crc_long
def check_icv(self):
computed_icv=self.get_computed_icv()
current_icv=self.get_icv()
1136 ↛ 1139line 1136 didn't jump to line 1139, because the condition on line 1136 was never false if computed_icv==current_icv:
return True
else:
return False
class Dot11WPA(ProtocolPacket):
'802.11 WPA'
def __init__(self, aBuffer = None):
header_size = 8
tail_size = 0
ProtocolPacket.__init__(self, header_size, tail_size)
1149 ↛ exitline 1149 didn't return from function '__init__', because the condition on line 1149 was never false if(aBuffer):
self.load_packet(aBuffer)
def is_WPA(self):
'Return True if it\'s a WPA'
# Now we must differentiate between WPA and WPA2
# In WPA WEPSeed is set to (TSC1 | 0x20) & 0x7f.
b = self.get_WEPSeed() == ((self.get_TSC1() | 0x20 ) & 0x7f)
return (b and self.get_extIV())
def get_keyid(self):
'Return the \'WPA KEY ID\' field'
b = self.header.get_byte(3)
return ((b>>6) & 0x03)
def set_keyid(self, value):
'Set the \'WPA KEY ID\' field'
# clear the bits
mask = (~0xC0) & 0xFF
masked = self.header.get_byte(3) & mask
# set the bits
nb = masked | ((value & 0x03) << 6)
self.header.set_byte(3, nb)
def get_decrypted_data(self):
'Return \'WPA Data\' field decrypted'
# TODO: Replace it with the decoded string
return self.body_string
def get_TSC1(self):
'Return the \'WPA TSC1\' field'
b = self.header.get_byte(0)
return (b & 0xFF)
def set_TSC1(self, value):
'Set the \'WPA TSC1\' field'
# set the bits
nb = (value & 0xFF)
self.header.set_byte(0, nb)
def get_WEPSeed(self):
'Return the \'WPA WEPSeed\' field'
b = self.header.get_byte(1)
return (b & 0xFF)
def set_WEPSeed(self, value):
'Set the \'WPA WEPSeed\' field'
# set the bits
nb = (value & 0xFF)
self.header.set_byte(1, nb)
def get_TSC0(self):
'Return the \'WPA TSC0\' field'
b = self.header.get_byte(2)
return (b & 0xFF)
def set_TSC0(self, value):
'Set the \'WPA TSC0\' field'
# set the bits
nb = (value & 0xFF)
self.header.set_byte(2, nb)
def get_extIV(self):
'Return the \'WPA extID\' field'
b = self.header.get_byte(3)
return ((b>>5) & 0x1)
def set_extIV(self, value):
'Set the \'WPA extID\' field'
# clear the bits
mask = (~0x20) & 0xFF
masked = self.header.get_byte(3) & mask
# set the bits
nb = masked | ((value & 0x01) << 5)
self.header.set_byte(3, nb)
def get_TSC2(self):
'Return the \'WPA TSC2\' field'
b = self.header.get_byte(4)
return (b & 0xFF)
def set_TSC2(self, value):
'Set the \'WPA TSC2\' field'
# set the bits
nb = (value & 0xFF)
self.header.set_byte(4, nb)
def get_TSC3(self):
'Return the \'WPA TSC3\' field'
b = self.header.get_byte(5)
return (b & 0xFF)
def set_TSC3(self, value):
'Set the \'WPA TSC3\' field'
# set the bits
nb = (value & 0xFF)
self.header.set_byte(5, nb)
def get_TSC4(self):
'Return the \'WPA TSC4\' field'
b = self.header.get_byte(6)
return (b & 0xFF)
def set_TSC4(self, value):
'Set the \'WPA TSC4\' field'
# set the bits
nb = (value & 0xFF)
self.header.set_byte(6, nb)
def get_TSC5(self):
'Return the \'WPA TSC5\' field'
b = self.header.get_byte(7)
return (b & 0xFF)
def set_TSC5(self, value):
'Set the \'WPA TSC5\' field'
# set the bits
nb = (value & 0xFF)
self.header.set_byte(7, nb)
class Dot11WPAData(ProtocolPacket):
'802.11 WPA Data Part'
def __init__(self, aBuffer = None):
header_size = 0
tail_size = 12
ProtocolPacket.__init__(self, header_size, tail_size)
1277 ↛ exitline 1277 didn't return from function '__init__', because the condition on line 1277 was never false if(aBuffer):
self.load_packet(aBuffer)
def get_icv(self):
"Return 'WPA ICV' field"
b = self.tail.get_long(-4, ">")
return b
def set_icv(self, value = None):
"Set 'WPA ICV' field"
# calculate the FCS
if value is None:
value=self.compute_checksum(self.body_string)
# set the bits
nb = value & 0xFFFFFFFF
self.tail.set_long(-4, nb)
def get_MIC(self):
'Return the \'WPA2Data MIC\' field'
return self.get_tail_as_string()[:8]
def set_MIC(self, value):
'Set the \'WPA2Data MIC\' field'
#Padding to 8 bytes with 0x00's
value.ljust(8,b'\x00')
#Stripping to 8 bytes
value=value[:8]
icv=self.tail.get_buffer_as_string()[-4:]
self.tail.set_bytes_from_string(value+icv)
class Dot11WPA2(ProtocolPacket):
'802.11 WPA2'
def __init__(self, aBuffer = None):
header_size = 8
tail_size = 0
ProtocolPacket.__init__(self, header_size, tail_size)
1318 ↛ exitline 1318 didn't return from function '__init__', because the condition on line 1318 was never false if(aBuffer):
self.load_packet(aBuffer)
def is_WPA2(self):
'Return True if it\'s a WPA2'
# Now we must differentiate between WPA and WPA2
# In WPA WEPSeed is set to (TSC1 | 0x20) & 0x7f.
# In WPA2 WEPSeed=PN1 and TSC1=PN0
b = self.get_PN1() == ((self.get_PN0() | 0x20 ) & 0x7f)
return (not b and self.get_extIV())
def get_extIV(self):
'Return the \'WPA2 extID\' field'
b = self.header.get_byte(3)
return ((b>>5) & 0x1)
def set_extIV(self, value):
'Set the \'WPA2 extID\' field'
# clear the bits
mask = (~0x20) & 0xFF
masked = self.header.get_byte(3) & mask
# set the bits
nb = masked | ((value & 0x01) << 5)
self.header.set_byte(3, nb)
def get_keyid(self):
'Return the \'WPA2 KEY ID\' field'
b = self.header.get_byte(3)
return ((b>>6) & 0x03)
def set_keyid(self, value):
'Set the \'WPA2 KEY ID\' field'
# clear the bits
mask = (~0xC0) & 0xFF
masked = self.header.get_byte(3) & mask
# set the bits
nb = masked | ((value & 0x03) << 6)
self.header.set_byte(3, nb)
def get_decrypted_data(self):
'Return \'WPA2 Data\' field decrypted'
# TODO: Replace it with the decoded string
return self.body_string
def get_PN0(self):
'Return the \'WPA2 PN0\' field'
b = self.header.get_byte(0)
return (b & 0xFF)
def set_PN0(self, value):
'Set the \'WPA2 PN0\' field'
# set the bits
nb = (value & 0xFF)
self.header.set_byte(0, nb)
def get_PN1(self):
'Return the \'WPA2 PN1\' field'
b = self.header.get_byte(1)
return (b & 0xFF)
def set_PN1(self, value):
'Set the \'WPA2 PN1\' field'
# set the bits
nb = (value & 0xFF)
self.header.set_byte(1, nb)
def get_PN2(self):
'Return the \'WPA2 PN2\' field'
b = self.header.get_byte(4)
return (b & 0xFF)
def set_PN2(self, value):
'Set the \'WPA2 PN2\' field'
# set the bits
nb = (value & 0xFF)
self.header.set_byte(4, nb)
def get_PN3(self):
'Return the \'WPA2 PN3\' field'
b = self.header.get_byte(5)
return (b & 0xFF)
def set_PN3(self, value):
'Set the \'WPA2 PN3\' field'
# set the bits
nb = (value & 0xFF)
self.header.set_byte(5, nb)
def get_PN4(self):
'Return the \'WPA2 PN4\' field'
b = self.header.get_byte(6)
return (b & 0xFF)
def set_PN4(self, value):
'Set the \'WPA2 PN4\' field'
# set the bits
nb = (value & 0xFF)
self.header.set_byte(6, nb)
def get_PN5(self):
'Return the \'WPA2 PN5\' field'
b = self.header.get_byte(7)
return (b & 0xFF)
def set_PN5(self, value):
'Set the \'WPA2 PN5\' field'
# set the bits
nb = (value & 0xFF)
self.header.set_byte(7, nb)
class Dot11WPA2Data(ProtocolPacket):
'802.11 WPA2 Data Part'
def __init__(self, aBuffer = None):
header_size = 0
tail_size = 8
ProtocolPacket.__init__(self, header_size, tail_size)
1436 ↛ exitline 1436 didn't return from function '__init__', because the condition on line 1436 was never false if(aBuffer):
self.load_packet(aBuffer)
def get_MIC(self):
'Return the \'WPA2Data MIC\' field'
return self.get_tail_as_string()
def set_MIC(self, value):
'Set the \'WPA2Data MIC\' field'
#Padding to 8 bytes with 0x00's
value.ljust(8,b'\x00')
#Stripping to 8 bytes
value=value[:8]
self.tail.set_bytes_from_string(value)
class RadioTap(ProtocolPacket):
__HEADER_BASE_SIZE = 8 # minimal header size
_PRESENT_FLAGS_SIZE = 4
_BASE_PRESENT_FLAGS_OFFSET = 4
class __RadioTapField(object):
ALIGNMENT = 1
def __str__( self ):
return str( self.__class__.__name__ )
class RTF_TSFT(__RadioTapField):
BIT_NUMBER = 0
STRUCTURE = "<Q"
ALIGNMENT = 8
class RTF_FLAGS(__RadioTapField):
BIT_NUMBER = 1
STRUCTURE = "<B"
# https://web.archive.org/web/20160423125307/www.radiotap.org/defined-fields/Flags
PROPERTY_CFP = 0x01 #sent/received during CFP
PROPERTY_SHORTPREAMBLE = 0x02 #sent/received with short preamble
PROPERTY_WEP = 0x04 #sent/received with WEP encryption
PROPERTY_FRAGMENTATION = 0x08 #sent/received with fragmentation
PROPERTY_FCS_AT_END = 0x10 #frame includes FCS
PROPERTY_PAYLOAD_PADDING= 0x20 #frame has padding between 802.11 header and payload (to 32-bit boundary)
PROPERTY_BAD_FCS = 0x40 #does not pass FCS check
PROPERTY_SHORT_GI = 0x80 #frame used short guard interval (HT). Unspecified but used:
class RTF_RATE(__RadioTapField):
BIT_NUMBER = 2
STRUCTURE = "<B"
class RTF_CHANNEL(__RadioTapField):
BIT_NUMBER = 3
STRUCTURE = "<HH"
ALIGNMENT = 2
class RTF_FHSS(__RadioTapField):
BIT_NUMBER = 4
STRUCTURE = "<BB"
class RTF_DBM_ANTSIGNAL(__RadioTapField):
BIT_NUMBER = 5
STRUCTURE = "<B"
class RTF_DBM_ANTNOISE(__RadioTapField):
BIT_NUMBER = 6
STRUCTURE = "<B"
class RTF_LOCK_QUALITY(__RadioTapField):
BIT_NUMBER = 7
STRUCTURE = "<H"
ALIGNMENT = 2
class RTF_TX_ATTENUATION(__RadioTapField):
BIT_NUMBER = 8
STRUCTURE = "<H"
ALIGNMENT = 2
class RTF_DB_TX_ATTENUATION(__RadioTapField):
BIT_NUMBER = 9
STRUCTURE = "<H"
ALIGNMENT = 2
class RTF_DBM_TX_POWER(__RadioTapField):
BIT_NUMBER = 10
STRUCTURE = "<b"
ALIGNMENT = 2
class RTF_ANTENNA(__RadioTapField):
BIT_NUMBER = 11
STRUCTURE = "<B"
class RTF_DB_ANTSIGNAL(__RadioTapField):
BIT_NUMBER = 12
STRUCTURE = "<B"
class RTF_DB_ANTNOISE(__RadioTapField):
BIT_NUMBER = 13
STRUCTURE = "<B"
## # official assignment, clashes with RTF_FCS_IN_HEADER
## class RTF_RX_FLAGS(__RadioTapField):
## BIT_NUMBER = 14
## STRUCTURE = "<H"
## ALIGNMENT = 2
# clashes with RTF_RX_FLAGS
class RTF_FCS_IN_HEADER(__RadioTapField):
BIT_NUMBER = 14
STRUCTURE = "<L"
ALIGNMENT = 4
# clashes with HARDWARE_QUEUE
class RTF_TX_FLAGS(__RadioTapField):
BIT_NUMBER = 15
STRUCTURE = "<H"
ALIGNMENT = 2
## # clashes with TX_FLAGS
## class RTF_HARDWARE_QUEUE(__RadioTapField):
## BIT_NUMBER = 15
## STRUCTURE = "<B"
## ALIGNMENT = 1
# clashes with RSSI
class RTF_RTS_RETRIES(__RadioTapField):
BIT_NUMBER = 16
STRUCTURE = "<B"
## # clashes with RTS_RETRIES
## class RTF_RSSI(__RadioTapField):
## BIT_NUMBER = 16
## STRUCTURE = "<H"
## ALIGNMENT = 1
class RTF_DATA_RETRIES(__RadioTapField):
BIT_NUMBER = 17
STRUCTURE = "<B"
class RTF_XCHANNEL(__RadioTapField):
BIT_NUMBER = 18
STRUCTURE = "<LHBB"
ALIGNMENT = 4
class RTF_EXT(__RadioTapField):
BIT_NUMBER = 31
STRUCTURE = []
# Sort the list so the 'for' statement walk the list in the right order
radiotap_fields = __RadioTapField.__subclasses__()
radiotap_fields.sort(key= lambda x: x.BIT_NUMBER)
def __init__(self, aBuffer = None):
header_size = self.__HEADER_BASE_SIZE
tail_size = 0
if aBuffer:
length = struct.unpack('<H', aBuffer[2:4])[0]
header_size=length
ProtocolPacket.__init__(self, header_size, tail_size)
self.load_packet(aBuffer)
else:
ProtocolPacket.__init__(self, header_size, tail_size)
self.set_version(0)
self.__set_present(0x00000000)
def get_header_length(self):
'Return the RadioTap header \'length\' field'
self.__update_header_length()
return self.header.get_word(2, "<")
def get_version(self):
'Return the \'version\' field'
b = self.header.get_byte(0)
return b
def set_version(self, value):
'Set the \'version\' field'
nb = (value & 0xFF)
self.header.set_byte(0, nb)
nb = (value & 0xFF)
def get_present(self, offset=_BASE_PRESENT_FLAGS_OFFSET):
"Return RadioTap present bitmap field"
present = self.header.get_long(offset, "<")
return present
def __set_present(self, value):
"Set RadioTap present field bit"
self.header.set_long(4, value)
def get_present_bit(self, field, offset=4):
'Get a \'present\' field bit'
present=self.get_present(offset)
return not not (2**field.BIT_NUMBER & present)
def __set_present_bit(self, field):
'Set a \'present\' field bit'
npresent=2**field.BIT_NUMBER | self.get_present()
self.header.set_long(4, npresent,'<')
def __unset_present_bit(self, field):
'Unset a \'present\' field bit'
npresent=~(2**field.BIT_NUMBER) & self.get_present()
self.header.set_long(4, npresent,'<')
def __align(self, val, align):
return ( (((val) + ((align) - 1)) & ~((align) - 1)) - val )
def __get_field_position(self, field):
offset = RadioTap._BASE_PRESENT_FLAGS_OFFSET
extra_present_flags_count = 0
while self.get_present_bit(RadioTap.RTF_EXT, offset):
offset += RadioTap._PRESENT_FLAGS_SIZE
extra_present_flags_count += 1
field_position = self.__HEADER_BASE_SIZE + (RadioTap._BASE_PRESENT_FLAGS_OFFSET * extra_present_flags_count)
1655 ↛ 1664line 1655 didn't jump to line 1664, because the loop on line 1655 didn't complete for f in self.radiotap_fields:
field_position += self.__align(field_position, f.ALIGNMENT)
if f == field:
return field_position
if self.get_present_bit(f):
total_length = struct.calcsize(f.STRUCTURE)
field_position += total_length
return None
def unset_field( self, field):
is_present=self.get_present_bit(field)
1668 ↛ 1669line 1668 didn't jump to line 1669, because the condition on line 1668 was never true if is_present is False:
return False
byte_pos=self.__get_field_position(field)
1672 ↛ 1673line 1672 didn't jump to line 1673, because the condition on line 1672 was never true if not byte_pos:
return False
self.__unset_present_bit(field)
header=self.get_header_as_string()
total_length = struct.calcsize(field.STRUCTURE)
header=header[:byte_pos]+header[byte_pos+total_length:]
self.load_header(header)
def __get_field_values( self, field ):
is_present=self.get_present_bit(field)
if is_present is False:
return None
byte_pos=self.__get_field_position(field)
header=self.get_header_as_string()
total_length=struct.calcsize(field.STRUCTURE)
v=header[ byte_pos:byte_pos+total_length ]
field_values = struct.unpack(field.STRUCTURE, v)
return field_values
def __set_field_values( self, field, values ):
1698 ↛ 1699line 1698 didn't jump to line 1699, because the condition on line 1698 was never true if not hasattr(values,'__iter__'):
raise Exception("arg 'values' is not iterable")
# It's for to known the qty of argument of a structure
num_fields=len(''.join(c for c in field.STRUCTURE if c not in '=@!<>'))
1704 ↛ 1705line 1704 didn't jump to line 1705, because the condition on line 1704 was never true if len(values)!=num_fields:
raise Exception("Field %s has exactly %d items"%(str(field),struct.calcsize(field.STRUCTURE)))
is_present=self.get_present_bit(field)
if is_present is False:
self.__set_present_bit(field)
byte_pos=self.__get_field_position(field)
header=self.get_header_as_string()
total_length=struct.calcsize(field.STRUCTURE)
new_str = struct.pack(field.STRUCTURE, *values)
if is_present is True:
header=header[:byte_pos]+new_str+header[byte_pos+total_length:]
else:
header=header[:byte_pos]+new_str+header[byte_pos:]
self.load_header(header)
def set_tsft( self, nvalue ):
"Set the Value in microseconds of the MAC's 64-bit 802.11 "\
"Time Synchronization Function timer when the first bit of "\
"the MPDU arrived at the MAC"
self.__set_field_values(RadioTap.RTF_TSFT, [nvalue])
def get_tsft( self ):
"Get the Value in microseconds of the MAC's 64-bit 802.11 "\
"Time Synchronization Function timer when the first bit of "\
"the MPDU arrived at the MAC"
values=self.__get_field_values(RadioTap.RTF_TSFT)
if not values:
return None
return values[0]
def set_flags( self, nvalue ):
"Set the properties of transmitted and received frames."
self.__set_field_values(self.RTF_FLAGS, [nvalue])
def get_flags( self ):
"Get the properties of transmitted and received frames."
values=self.__get_field_values(self.RTF_FLAGS)
1747 ↛ 1748line 1747 didn't jump to line 1748, because the condition on line 1747 was never true if not values:
return None
return values[0]
def set_rate( self, nvalue ):
"Set the TX/RX data rate in 500 Kbps units"
self.__set_field_values(self.RTF_RATE, [nvalue])
def get_rate( self ):
"Get the TX/RX data rate in 500 Kbps units"
values=self.__get_field_values(self.RTF_RATE)
1760 ↛ 1761line 1760 didn't jump to line 1761, because the condition on line 1760 was never true if not values:
return None
return values[0]
def set_channel( self, freq, flags ):
"Set the channel Tx/Rx frequency in MHz and the channel flags"
self.__set_field_values(self.RTF_CHANNEL, [freq, flags])
def get_channel( self ):
"Get the TX/RX data rate in 500 Kbps units"
values=self.__get_field_values(self.RTF_CHANNEL)
return values
def set_FHSS( self, hop_set, hop_pattern ):
"Set the hop set and pattern for frequency-hopping radios"
self.__set_field_values(self.RTF_FHSS, [hop_set, hop_pattern])
def get_FHSS( self ):
"Get the hop set and pattern for frequency-hopping radios"
values=self.__get_field_values(self.RTF_FHSS)
return values
def set_dBm_ant_signal( self, signal ):
"Set the RF signal power at the antenna, decibel difference from an "\
"arbitrary, fixed reference."
self.__set_field_values(self.RTF_DBM_ANTSIGNAL, [signal])
def get_dBm_ant_signal( self ):
"Get the RF signal power at the antenna, decibel difference from an "\
"arbitrary, fixed reference."
values=self.__get_field_values(self.RTF_DBM_ANTSIGNAL)
if not values:
return None
return values[0]
def set_dBm_ant_noise( self, signal ):
"Set the RF noise power at the antenna, decibel difference from an "\
"arbitrary, fixed reference."
self.__set_field_values(self.RTF_DBM_ANTNOISE, [signal])
def get_dBm_ant_noise( self ):
"Get the RF noise power at the antenna, decibel difference from an "\
"arbitrary, fixed reference."
values=self.__get_field_values(self.RTF_DBM_ANTNOISE)
if not values:
return None
return values[0]
def set_lock_quality( self, quality ):
"Set the quality of Barker code lock. "\
"Called 'Signal Quality' in datasheets. "
self.__set_field_values(self.RTF_LOCK_QUALITY, [quality])
def get_lock_quality( self ):
"Get the quality of Barker code lock. "\
"Called 'Signal Quality' in datasheets. "
values=self.__get_field_values(self.RTF_LOCK_QUALITY)
if not values:
return None
return values[0]
def set_tx_attenuation( self, power ):
"Set the transmit power expressed as unitless distance from max power "\
"set at factory calibration. 0 is max power."
self.__set_field_values(self.RTF_TX_ATTENUATION, [power])
def get_tx_attenuation( self ):
"Set the transmit power expressed as unitless distance from max power "\
"set at factory calibration. 0 is max power."
values=self.__get_field_values(self.RTF_TX_ATTENUATION)
if not values:
return None
return values[0]
def set_dB_tx_attenuation( self, power ):
"Set the transmit power expressed as decibel distance from max power "\
"set at factory calibration. 0 is max power. "
self.__set_field_values(self.RTF_DB_TX_ATTENUATION, [power])
def get_dB_tx_attenuation( self ):
"Set the transmit power expressed as decibel distance from max power "\
"set at factory calibration. 0 is max power. "
values=self.__get_field_values(self.RTF_DB_TX_ATTENUATION)
if not values:
return None
return values[0]
def set_dBm_tx_power( self, power ):
"Set the transmit power expressed as dBm (decibels from a 1 milliwatt"\
" reference). This is the absolute power level measured at the "\
"antenna port."
self.__set_field_values(self.RTF_DBM_TX_POWER, [power])
def get_dBm_tx_power( self ):
"Get the transmit power expressed as dBm (decibels from a 1 milliwatt"\
" reference). This is the absolute power level measured at the "\
"antenna port."
values=self.__get_field_values(self.RTF_DBM_TX_POWER)
if not values:
return None
return values[0]
def set_antenna( self, antenna_index ):
"Set Rx/Tx antenna index for this packet. "\
"The first antenna is antenna 0. "\
self.__set_field_values(self.RTF_ANTENNA, [antenna_index])
def get_antenna( self ):
"Set Rx/Tx antenna index for this packet. "\
"The first antenna is antenna 0. "\
values=self.__get_field_values(self.RTF_ANTENNA)
1891 ↛ 1892line 1891 didn't jump to line 1892, because the condition on line 1891 was never true if not values:
return None
return values[0]
def set_dB_ant_signal( self, signal ):
"Set the RF signal power at the antenna, decibel difference from an "\
"arbitrary, fixed reference."
self.__set_field_values(self.RTF_DB_ANTSIGNAL, [signal])
def get_dB_ant_signal( self ):
"Get the RF signal power at the antenna, decibel difference from an "\
"arbitrary, fixed reference."
values=self.__get_field_values(self.RTF_DB_ANTSIGNAL)
if not values:
return None
return values[0]
def set_dB_ant_noise( self, signal ):
"Set the RF noise power at the antenna, decibel difference from an "\
"arbitrary, fixed reference."
self.__set_field_values(self.RTF_DB_ANTNOISE, [signal])
def get_dB_ant_noise( self ):
"Get the RF noise power at the antenna, decibel difference from an "\
"arbitrary, fixed reference."
values=self.__get_field_values(self.RTF_DB_ANTNOISE)
if not values:
return None
return values[0]
## def set_rx_flags( self, flags ):
## "Set the properties of received frames."
##
## self.__set_field_values(self.RTF_RX_FLAGS, [flags])
##
## def get_rx_flags( self ):
## "Get the properties of received frames."
##
## values=self.__get_field_values(self.RTF_RX_FLAGS)
## if not values:
## return None
## return values[0]
def set_FCS_in_header( self, fcs ):
"Set the Field containing the FCS of the frame (instead of it being "\
"appended to the frame as it would appear on the air.) "
self.__set_field_values(self.RTF_FCS_IN_HEADER, [fcs])
def get_FCS_in_header( self ):
"Get the Field containing the FCS of the frame (instead of it being "\
"appended to the frame as it would appear on the air.) "
values=self.__get_field_values(self.RTF_FCS_IN_HEADER)
if not values:
return None
return values[0]
## def set_RSSI( self, rssi, max_rssi ):
## "Set the received signal strength and the maximum for the hardware."
##
## self.__set_field_values(self.RTF_RSSI, [rssi, max_rssi])
##
## def get_RSSI( self ):
## "Get the received signal strength and the maximum for the hardware."
##
## values=self.__get_field_values(self.RTF_RSSI)
##
## return values
def set_RTS_retries( self, retries):
"Set the number of RTS retries a transmitted frame used."
self.__set_field_values(self.RTF_RTS_RETRIES, [retries])
def get_RTS_retries( self ):
"Get the number of RTS retries a transmitted frame used."
values=self.__get_field_values(self.RTF_RTS_RETRIES)
if not values:
return None
return values[0]
def set_tx_flags( self, flags ):
"Set the properties of transmitted frames."
self.__set_field_values(self.RTF_TX_FLAGS, [flags])
def get_tx_flags( self ):
"Get the properties of transmitted frames."
values=self.__get_field_values(self.RTF_TX_FLAGS)
if not values:
return None
return values[0]
def set_xchannel( self, flags, freq, channel, maxpower ):
"Set extended channel information: flags, freq, channel and maxpower"
self.__set_field_values(self.RTF_XCHANNEL, [flags, freq, channel, maxpower] )
def get_xchannel( self ):
"Get extended channel information: flags, freq, channel and maxpower"
values=self.__get_field_values(field=self.RTF_XCHANNEL)
return values
def set_data_retries( self, retries ):
"Set the number of data retries a transmitted frame used."
self.__set_field_values(self.RTF_DATA_RETRIES, [retries])
def get_data_retries( self ):
"Get the number of data retries a transmitted frame used."
values=self.__get_field_values(self.RTF_DATA_RETRIES)
if not values:
return None
return values[0]
def set_hardware_queue( self, queue ):
"Set the hardware queue to send the frame on."
self.__set_field_values(self.RTF_HARDWARE_QUEUE, [queue])
## def get_hardware_queue( self ):
## "Get the hardware queue to send the frame on."
##
## values=self.__get_field_values(self.RTF_HARDWARE_QUEUE)
## if not values:
## return None
## return values[0]
def __update_header_length(self):
'Update the RadioTap header length field with the real size'
self.header.set_word(2, self.get_header_size(), "<")
def get_packet(self):
self.__update_header_length()
return ProtocolPacket.get_packet(self)
class Dot11ManagementFrame(ProtocolPacket):
'802.11 Management Frame'
def __init__(self, aBuffer = None):
header_size = 22
tail_size = 0
ProtocolPacket.__init__(self, header_size, tail_size)
2045 ↛ exitline 2045 didn't return from function '__init__', because the condition on line 2045 was never false if(aBuffer):
self.load_packet(aBuffer)
def get_duration(self):
'Return 802.11 Management frame \'Duration\' field'
b = self.header.get_word(0, "<")
return b
def set_duration(self, value):
'Set the 802.11 Management frame \'Duration\' field'
# set the bits
nb = value & 0xFFFF
self.header.set_word(0, nb, "<")
def get_destination_address(self):
'Return 802.11 Management frame \'Destination Address\' field as a 6 bytes array'
return self.header.get_bytes()[2:8]
def set_destination_address(self, value):
'Set 802.11 Management frame \'Destination Address\' field as a 6 bytes array'
for i in range(0, 6):
self.header.set_byte(2+i, value[i])
def get_source_address(self):
'Return 802.11 Management frame \'Source Address\' field as a 6 bytes array'
return self.header.get_bytes()[8:14]
def set_source_address(self, value):
'Set 802.11 Management frame \'Source Address\' field as a 6 bytes array'
for i in range(0, 6):
self.header.set_byte(8+i, value[i])
def get_bssid(self):
'Return 802.11 Management frame \'BSSID\' field as a 6 bytes array'
return self.header.get_bytes()[14: 20]
def set_bssid(self, value):
'Set 802.11 Management frame \'BSSID\' field as a 6 bytes array'
for i in range(0, 6):
self.header.set_byte(14+i, value[i])
def get_sequence_control(self):
'Return 802.11 Management frame \'Sequence Control\' field'
b = self.header.get_word(20, "<")
return b
def set_sequence_control(self, value):
'Set the 802.11 Management frame \'Sequence Control\' field'
# set the bits
nb = value & 0xFFFF
self.header.set_word(20, nb, "<")
def get_fragment_number(self):
'Return 802.11 Management frame \'Fragment Number\' subfield'
b = self.get_sequence_control()
return (b&0x000F)
def set_fragment_number(self, value):
'Set the 802.11 Management frame \'Fragment Number\' subfield'
# clear the bits
mask = (~0x000F) & 0xFFFF
masked = self.header.get_word(20, "<") & mask
# set the bits
nb = masked | (value & 0x000F)
self.header.set_word(20, nb, "<")
def get_sequence_number(self):
'Return 802.11 Management frame \'Sequence Number\' subfield'
b = self.get_sequence_control()
return ((b>>4) & 0xFFF)
def set_sequence_number(self, value):
'Set the 802.11 Management frame \'Sequence Number\' subfield'
# clear the bits
mask = (~0xFFF0) & 0xFFFF
masked = self.header.get_word(20, "<") & mask
# set the bits
nb = masked | ((value & 0x0FFF ) << 4 )
self.header.set_word(20, nb, "<")
def get_frame_body(self):
'Return 802.11 Management frame \'Frame Body\' field'
return self.get_body_as_string()
def set_frame_body(self, data):
'Set 802.11 Management frame \'Frame Body\' field'
self.load_body(data)
class DOT11_MANAGEMENT_ELEMENTS():
SSID = 0
SUPPORTED_RATES = 1
FH_PARAMETER_SET = 2
DS_PARAMETER_SET = 3
CF_PARAMETER_SET = 4
TIM = 5
IBSS_PARAMETER_SET = 6
COUNTRY = 7
HOPPING_PARAMETER = 8
HOPPING_TABLE = 9
REQUEST = 10
BSS_LOAD = 11
EDCA_PARAMETER_SET = 12
TSPEC = 13
TCLAS = 14
SCHEDULE = 15
CHALLENGE_TEXT = 16
# RESERVED 17-31
POWER_CONSTRAINT = 32
POWER_CAPABILITY = 33
TPC_REQUEST = 34
TPC_REPORT = 35
SUPPORTED_CHANNELS = 36
CHANNEL_SWITCH_ANN = 37
MEASURE_REQ = 38
MEASURE_REP = 39
QUIET = 40
IBSS_DFS = 41
ERP_INFO = 42
TS_DELAY = 43
TCLAS_PROCESSING = 44
#RESERVED 45 # See: IEEE 802.11n
QOS_CAPABILITY = 46
#RESERVED 47 # See: IEEE 802.11g
RSN = 48
#RESERVED 49
EXT_SUPPORTED_RATES = 50
#RESERVED 51-126
EXTENDED_CAPABILITIES = 127
#RESERVED 128-220
VENDOR_SPECIFIC = 221
#RESERVED 222-255
class Dot11ManagementHelper(ProtocolPacket):
def __init__(self, header_size, tail_size, aBuffer = None):
self.__HEADER_BASE_SIZE=header_size
2186 ↛ 2193line 2186 didn't jump to line 2193, because the condition on line 2186 was never false if aBuffer:
elements_length=self.__calculate_elements_length(aBuffer[self.__HEADER_BASE_SIZE:])
header_size+=elements_length
ProtocolPacket.__init__(self, header_size, tail_size)
self.load_packet(aBuffer)
else:
ProtocolPacket.__init__(self, header_size, tail_size)
def _find_element(self, elements, element_id ):
remaining=len(elements)
offset=0
while remaining > 0:
(id,length)=struct.unpack("!BB",elements[offset:offset+2])
if element_id is None:
pass # through the whole list returning the length
elif id==element_id:
yield (0,offset,length+2) # ==
length+=2 #id+length
offset+=length
2207 ↛ 2209line 2207 didn't jump to line 2209, because the condition on line 2207 was never true if length>remaining:
# Error!!
length = remaining
remaining-=length
# < Not found
yield (-1, offset, None)
def __calculate_elements_length(self, elements):
gen_tp=self._find_element(elements, None )
(match,offset,length)=next(gen_tp)
2217 ↛ 2219line 2217 didn't jump to line 2219, because the condition on line 2217 was never true if match != -1:
# element_id is None, then __find_tagged_parameter must return -1
raise Exception("Internal Error %s"%match)
return offset
def _get_elements_generator(self, element_id):
elements=self.get_header_as_string()[self.__HEADER_BASE_SIZE:]
gen_tp=self._find_element(elements, element_id )
while True:
(match,offset,length)=next(gen_tp)
if match != 0:
return
value_offset=offset+2
value_end=offset+length
value=elements[value_offset:value_end]
yield value
def _get_element(self, element_id):
gen_get_element=self._get_elements_generator(element_id)
try:
s=next(gen_get_element)
2239 ↛ 2240line 2239 didn't jump to line 2240, because the condition on line 2239 was never true if s is None:
raise Exception("gen_get_element salio con None in _get_element!!!")
return s
except StopIteration:
pass
return None
def delete_element(self, element_id, multiple = False):
header=self.get_header_as_string()
elements=header[self.__HEADER_BASE_SIZE:]
gen_tp=self._find_element(elements, element_id )
found=False
while True:
(match,offset,length)=next(gen_tp)
if match != 0:
break
start=self.__HEADER_BASE_SIZE+offset
header=header[:start]+header[start+length:]
found=True
if multiple is False:
break
if not found:
return False
self.load_header(header)
return True
def _set_element(self, element_id, value, replace = True):
parameter=struct.pack('BB%ds'%len(value),element_id,len(value),value)
header=self.get_header_as_string()
elements=header[self.__HEADER_BASE_SIZE:]
gen_tp=self._find_element(elements, element_id )
found=False
while True:
(match,offset,length)=next(gen_tp)
start=self.__HEADER_BASE_SIZE+offset
if match == 0 and replace:
# Replace
header=header[:start]+parameter+header[start+length:]
found=True
break
2284 ↛ 2286line 2284 didn't jump to line 2286, because the condition on line 2284 was never true elif match > 0:
# Add
header=header[:start]+parameter+header[start:]
found=True
break
else:
break
if not found:
# Append (found<0 Not found)
header=header+parameter
self.load_header(header)
class Dot11ManagementBeacon(Dot11ManagementHelper):
'802.11 Management Beacon Frame'
__HEADER_BASE_SIZE = 12 # minimal header size
def __init__(self, aBuffer = None):
header_size = self.__HEADER_BASE_SIZE
tail_size = 0
Dot11ManagementHelper.__init__(self, header_size, tail_size, aBuffer)
def get_timestamp(self):
'Return the 802.11 Management Beacon frame \'Timestamp\' field'
b = self.header.get_long_long(0, "<")
return b
def set_timestamp(self, value):
'Set the 802.11 Management Beacon frame \'Timestamp\' field'
# set the bits
nb = value & 0xFFFFFFFFFFFFFFFF
self.header.set_long_long(0, nb, "<")
def get_beacon_interval(self):
'Return the 802.11 Management Beacon frame \'Beacon Interval\' field' \
'To convert it to seconds => secs = Beacon_Interval*1024/1000000'
b = self.header.get_word(8, "<")
return b
def set_beacon_interval(self, value):
'Set the 802.11 Management Beacon frame \'Beacon Interval\' field'
# set the bits
nb = value & 0xFFFF
self.header.set_word(8, nb, "<")
def get_capabilities(self):
'Return the 802.11 Management Beacon frame \'Capability information\' field. '
b = self.header.get_word(10, "<")
return b
def set_capabilities(self, value):
'Set the 802.11 Management Beacon frame \'Capability Information\' field'
# set the bits
nb = value & 0xFFFF
self.header.set_word(10, nb, "<")
def get_ssid(self):
"Get the 802.11 Management SSID element. "\
"The SSID element indicates the identity of an ESS or IBSS."
return self._get_element(DOT11_MANAGEMENT_ELEMENTS.SSID)
def set_ssid(self, ssid):
self._set_element(DOT11_MANAGEMENT_ELEMENTS.SSID,ssid)
def get_supported_rates(self, human_readable=False):
"Get the 802.11 Management Supported Rates element. "\
"Specifies up to eight rates, then an Extended Supported Rate element "\
"shall be generated to specify the remaining supported rates."\
"If human_readable is True, the rates are returned in Mbit/sec"
s=self._get_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES)
2356 ↛ 2357line 2356 didn't jump to line 2357, because the condition on line 2356 was never true if s is None:
return None
rates=struct.unpack('%dB'%len(s),s)
if not human_readable:
return rates
rates_Mbs=tuple([(x&0x7F)*0.5 for x in rates])
return rates_Mbs
def set_supported_rates(self, rates):
"Set the 802.11 Management Supported Rates element. "\
"Specifies a tuple or list with up to eight rates, then an "\
"Extended Supported Rate element shall be generated to specify "\
"the remaining supported rates."
qty_rates=len(rates)
2372 ↛ 2373line 2372 didn't jump to line 2373, because the condition on line 2372 was never true if qty_rates>8:
raise Exception("requires up to eight rates")
rates_string=struct.pack('B'*qty_rates,*rates)
self._set_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES,rates_string)
def get_ds_parameter_set(self):
"Get the 802.11 Management DS Parameter set element. "\
"Contains information to allow channel number identification for "\
"STAs using a DSSS PHY."
s=self._get_element(DOT11_MANAGEMENT_ELEMENTS.DS_PARAMETER_SET)
2382 ↛ 2383line 2382 didn't jump to line 2383, because the condition on line 2382 was never true if s is None:
return None
(ch,)=struct.unpack('B',s)
return ch
def set_ds_parameter_set(self, channel):
"Set the 802.11 Management DS Parameter set element. "\
"Contains information to allow channel number identification for "\
"STAs using a DSSS PHY."
channel_string=struct.pack('B',channel)
self._set_element(DOT11_MANAGEMENT_ELEMENTS.DS_PARAMETER_SET,channel_string)
def get_rsn(self):
"Get the 802.11 Management Robust Security Network element."
s = self._get_element(DOT11_MANAGEMENT_ELEMENTS.RSN)
if s is None:
return None
return s
def set_rsn(self, data):
"Set the 802.11 Management Robust Security Network element."
self._set_element(DOT11_MANAGEMENT_ELEMENTS.RSN, data)
def get_erp(self):
"Get the 802.11 Management ERP (extended rate PHY) Information element."
s = self._get_element(DOT11_MANAGEMENT_ELEMENTS.ERP_INFO)
if s is None:
return None
(erp,) = struct.unpack('B',s)
return erp
def set_erp(self, erp):
"Set the 802.11 Management ERP (extended rate PHY) Inforamation "\
"element."
erp_string = struct.pack('B',erp)
self._set_element(DOT11_MANAGEMENT_ELEMENTS.ERP_INFO, erp_string)
def get_country(self):
"Get the 802.11 Management Country element." \
"Returns a tuple containing Country code, first channel number, "\
"number of channels and maximum transmit power level"
s = self._get_element(DOT11_MANAGEMENT_ELEMENTS.COUNTRY)
if s is None:
return None
code, first, num, max = struct.unpack('3sBBB',s)
code = code.strip(' ')
return code, first, num, max
def set_country(self, code, first_channel, number_of_channels, max_power):
"Set the 802.11 Management Country element."
if len(code) > 3:
raise Exception("Country code must be up to 3 bytes long")
#Padding the country code
code += ' ' * (3-len(code))
country_string = struct.pack('3sBBB', code, first_channel,
number_of_channels, max_power)
self._set_element(DOT11_MANAGEMENT_ELEMENTS.COUNTRY, country_string)
def get_vendor_specific(self):
"Get the 802.11 Management Vendor Specific elements "\
"as a list of tuples."
"The Vendor Specific information element is used to carry "\
"information not defined in the standard within a single "\
"defined format"
vs=[]
gen_get_element=self._get_elements_generator(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC)
try:
while 1:
s=next(gen_get_element)
2460 ↛ 2461line 2460 didn't jump to line 2461, because the condition on line 2460 was never true if s is None:
raise Exception("gen_get_element salio con None!!!")
# OUI is 3 bytes
oui=s[:3]
data=s[3:]
vs.append((oui,data))
except StopIteration:
pass
return vs
def add_vendor_specific(self, oui, data):
"Set the 802.11 Management Vendor Specific element. "\
"The Vendor Specific information element is used to carry "\
"information not defined in the standard within a single "\
"defined format"
# 3 is the OUI length
max_data_len=255-3
data_len=len(data)
2482 ↛ 2483line 2482 didn't jump to line 2483, because the condition on line 2482 was never true if data_len>max_data_len:
raise Exception("data allow up to %d bytes long" % max_data_len)
2484 ↛ 2485line 2484 didn't jump to line 2485, because the condition on line 2484 was never true if len(oui) > 3:
raise Exception("oui is three bytes long")
self._set_element(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC,oui+data, replace=False)
class Dot11ManagementProbeRequest(Dot11ManagementHelper):
'802.11 Management Probe Request Frame'
def __init__(self, aBuffer = None):
header_size = 0
tail_size = 0
Dot11ManagementHelper.__init__(self, header_size, tail_size, aBuffer)
def get_ssid(self):
"Get the 802.11 Management SSID element. "\
"The SSID element indicates the identity of an ESS or IBSS."
return self._get_element(DOT11_MANAGEMENT_ELEMENTS.SSID)
def set_ssid(self, ssid):
self._set_element(DOT11_MANAGEMENT_ELEMENTS.SSID,ssid)
def get_supported_rates(self, human_readable=False):
"Get the 802.11 Management Supported Rates element. "\
"Specifies up to eight rates, then an Extended Supported Rate element "\
"shall be generated to specify the remaining supported rates."\
"If human_readable is True, the rates are returned in Mbit/sec"
s=self._get_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES)
2511 ↛ 2512line 2511 didn't jump to line 2512, because the condition on line 2511 was never true if s is None:
return None
rates=struct.unpack('%dB'%len(s),s)
if not human_readable:
return rates
rates_Mbs=tuple([(x&0x7F)*0.5 for x in rates])
return rates_Mbs
def set_supported_rates(self, rates):
"Set the 802.11 Management Supported Rates element. "\
"Specifies a tuple or list with up to eight rates, then an "\
"Extended Supported Rate element shall be generated to specify "\
"the remaining supported rates."
qty_rates=len(rates)
2527 ↛ 2528line 2527 didn't jump to line 2528, because the condition on line 2527 was never true if qty_rates>8:
raise Exception("requires up to eight rates")
rates_string=struct.pack('B'*qty_rates,*rates)
self._set_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES,rates_string)
class Dot11ManagementProbeResponse(Dot11ManagementBeacon):
'802.11 Management Probe Response Frame'
def __init__(self, aBuffer = None):
Dot11ManagementBeacon.__init__(self, aBuffer)
class DOT11_REASON_CODES():
# RESERVED = 0
UNSPECIFIED_REASON = 1
PREV_AUTH_NO_LONGER_VALID = 2
DEAUTH_STA_IS_LEAVING = 3
DISASS_DUE_TO_INACTIVITY = 4
DISASS_AP_UNABLE_HANDLE_ALL_STA = 5
C2_FRAME_FROM_NONAUTHENTICATED_STA = 6
C3_FRAME_FROM_NONASSOCIATED_STA = 7
DISSASS_STA_IS_LEAVING = 8
STA_REQ_NOT_AUTH_STA = 9
DISASS_POWER_CAP_IE_UNNACCEPTABLE = 10
DISASS_SUP_CH_IE_UNNACCEPTABLE = 11
# RESERVED = 12
INVALID_IE = 13
MIC_FAILURE = 14
FOUR_WAY_HANDSHAKE_TIMEOUT = 15
GROUP_KEY_HANDSHAKE_TIMEOUT = 16
IE_FOUR_WAY_HANDSHAKE_DIFFERENT = 17
INVALID_GROUP_CIPHER = 18
INVALID_PAIRWISE_CIPHER = 19
INVALID_AKMP = 20
UNSUPPORTED_RSN_IE_VERSION = 21
INVALID_RSN_IE_CAP = 22
X_AUTH_FAILED = 23
CIPHER_SUITE_REJECTED_SECURITY_POLICY = 24
# RESERVED = 25 - 31
DISASS_QOS_RELATED_REASON = 32
DISASS_QOS_UNSUFFICIENT_BANDWIDTH = 33
DISASS_EXCESSIVE_FRAMES_WITHOUT_ACK = 34
DISASS_STA_TX_OUTSIDE_TXOPS = 35
REQ_STA_LEAVING = 36
REQ_STA_NOT_WANT_MECHANISM = 37
REQ_STA_RECV_FRAMES_WHICH_SETUP_REQ = 38
REQ_STA_DUE_TIMEOUT = 39
STA_NOT_SUPPORT_CIPHER_SUITE = 45
# RESERVED = 46 - 65 535
class Dot11ManagementDeauthentication(ProtocolPacket):
'802.11 Management Deauthentication Frame'
def __init__(self, aBuffer = None):
header_size = 2
tail_size = 0
2582 ↛ 2586line 2582 didn't jump to line 2586, because the condition on line 2582 was never false if aBuffer:
ProtocolPacket.__init__(self, header_size, tail_size)
self.load_packet(aBuffer)
else:
ProtocolPacket.__init__(self, header_size, tail_size)
def get_reason_code(self):
"Get the 802.11 Management Deauthentication or Disassociation Code."
return self.header.get_word(0, "<")
def set_reason_code(self, rc):
self.header.set_word(0, rc, "<")
class DOT11_AUTH_ALGORITHMS():
OPEN = 0
SHARED_KEY = 1
class DOT11_AUTH_STATUS_CODES():
SUCCESSFUL = 0
UNSPECIFIED_FAILURE = 1
# RESERVED = 2 - 9
CAP_REQ_UNSUPPORTED = 10
REASS_DENIED_CANNOT_CONFIRM_ASS_EXISTS = 11
ASS_DENIED_REASON_OUTSIDE_SCOPE_STANDARD = 12
STA_NOT_SUPPORT_AUTH_ALGORITHM = 13
AUTH_SEQ_OUT_OF_EXPECTED = 14
AUTH_REJECTED_CHALLENGE_FAILURE = 15
AUTH_REJECTED_TIMEOUT = 16
ASS_DENIED_AP_UNABLE_HANDLE_MORE_STA = 17
ASS_DENIED_STA_NOT_SUPPORTING_DATA_RATES = 18
ASS_DENIED_STA_NOT_SUPPORTING_SHORT_PREAMBLE = 19
ASS_DENIED_STA_NOT_SUPPORTING_PBCC_MODULATION = 20
ASS_DENIED_STA_NOT_SUPPORTING_CHANNEL_AGILITY = 21
ASS_REQUEST_REJECTED_SPACTRUM_MGT_CAP = 22
ASS_REQUEST_REJECTED_POWER_CAP_IE_UNNACCEPTABLE = 23
ASS_REQUEST_REJECTED_SUP_CH_IE_UNNACCEPTABLE = 24
ASS_DENIED_STA_NOT_SUPPORTING_SHORT_SLOT_TIME = 25
ASS_DENIED_STA_NOT_SUPPORTING_DSSS_OFDM = 26
# RESERVED = 27 - 31
UNSPECIFIED_QOS = 32
ASS_DENIED_QOS_UNSUFFICIENT_BANDWIDTH = 33
ASS_DENIED_EXCESSIVE_FRAME_LOST = 34
ASS_DENIED_STA_NOT_SUPPORT_QOS = 35
# RESERVED = 36
REQ_HAS_BEEN_DECLINED = 37
REQ_NOT_SUCCESSFUL_PARAM_INVALID_VALUE = 38
TSPEC = 39
INVALID_IE = 40
INVALID_GROUP_CIPHER = 41
INVALID_PAIRWISE_CIPHER = 42
INVALID_AKMP = 43
UNSUPPORTED_RSN_IE_VERSION = 44
INVALID_RSN_IE_CAP = 45
CIPHER_SUITE_REJECTED_SECURITY_POLICY = 46
TS_NOT_CREATED = 47
DIRECT_LINK_NOT_ALLOWED_BSS_POLICY = 48
DST_STA_NOT_PRESENT_IN_BSS = 49
DST_STA_NOT_QOS_STA = 50
ASS_DENIED_LISTEN_INTERVAL_TOO_LARGE = 51
# RESERVED = 52 - 65 535
class Dot11ManagementAuthentication(Dot11ManagementHelper):
'802.11 Management Authentication Frame'
__HEADER_BASE_SIZE = 6 # minimal header size
def __init__(self, aBuffer = None):
header_size = self.__HEADER_BASE_SIZE
tail_size = 0
Dot11ManagementHelper.__init__(self, header_size, tail_size, aBuffer)
def get_authentication_algorithm(self):
"Get the 802.11 Management Authentication Algorithm."
return self.header.get_word(0, "<")
def set_authentication_algorithm(self, algorithm):
"Set the 802.11 Management Authentication Algorithm."
self.header.set_word(0, algorithm, "<")
def get_authentication_sequence(self):
"Get the 802.11 Management Authentication Sequence."
return self.header.get_word(2, "<")
def set_authentication_sequence(self, seq):
"Set the 802.11 Management Authentication Sequence."
self.header.set_word(2, seq, "<")
def get_authentication_status(self):
"Get the 802.11 Management Authentication Status."
return self.header.get_word(4, "<")
def set_authentication_status(self, status):
"Set the 802.11 Management Authentication Status."
self.header.set_word(4, status, "<")
def get_challenge_text(self):
return self._get_element(DOT11_MANAGEMENT_ELEMENTS.CHALLENGE_TEXT)
def set_challenge_text(self, challenge):
self._set_element(DOT11_MANAGEMENT_ELEMENTS.CHALLENGE_TEXT, challenge)
def get_vendor_specific(self):
"Get the 802.11 Management Vendor Specific elements "\
"as a list of tuples."
"The Vendor Specific information element is used to carry "\
"information not defined in the standard within a single "\
"defined format"
vs=[]
gen_get_element=self._get_elements_generator(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC)
try:
while 1:
s=next(gen_get_element)
2696 ↛ 2697line 2696 didn't jump to line 2697, because the condition on line 2696 was never true if s is None:
raise Exception("gen_get_element salio con None!!!")
# OUI is 3 bytes
oui=s[:3]
data=s[3:]
vs.append((oui,data))
except StopIteration:
pass
return vs
def add_vendor_specific(self, oui, data):
"Set the 802.11 Management Vendor Specific element. "\
"The Vendor Specific information element is used to carry "\
"information not defined in the standard within a single "\
"defined format"
# 3 is the OUI length
max_data_len=255-3
data_len=len(data)
2718 ↛ 2719line 2718 didn't jump to line 2719, because the condition on line 2718 was never true if data_len>max_data_len:
raise Exception("data allow up to %d bytes long" % max_data_len)
2720 ↛ 2721line 2720 didn't jump to line 2721, because the condition on line 2720 was never true if len(oui) > 3:
raise Exception("oui is three bytes long")
self._set_element(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC,oui+data, replace=False)
class Dot11ManagementDisassociation(Dot11ManagementDeauthentication):
'802.11 Management Disassociation Frame'
def __init__(self, aBuffer = None):
Dot11ManagementDeauthentication.__init__(self, aBuffer)
class Dot11ManagementAssociationRequest(Dot11ManagementHelper):
'802.11 Management Association Request Frame'
__HEADER_BASE_SIZE = 4 # minimal header size
def __init__(self, aBuffer = None):
header_size = self.__HEADER_BASE_SIZE
tail_size = 0
Dot11ManagementHelper.__init__(self, header_size, tail_size, aBuffer)
def get_capabilities(self):
'Return the 802.11 Management Association Request Frame \'Capability information\' field. '
b = self.header.get_word(0, "<")
return b
def set_capabilities(self, value):
'Set the 802.11 Management Association Request Frame \'Capability Information\' field'
# set the bits
nb = value & 0xFFFF
self.header.set_word(0, nb, "<")
def get_listen_interval(self):
'Return the 802.11 Management Association Request Frame \'Listen Interval\' field. '
b = self.header.get_word(2, "<")
return b
def set_listen_interval(self, value):
'Set the 802.11 Management Association Request Frame \'Listen Interval\' field'
self.header.set_word(2, value, "<")
def get_ssid(self):
"Get the 802.11 Management SSID element. "\
"The SSID element indicates the identity of an ESS or IBSS."
return self._get_element(DOT11_MANAGEMENT_ELEMENTS.SSID)
def set_ssid(self, ssid):
self._set_element(DOT11_MANAGEMENT_ELEMENTS.SSID,ssid)
def get_supported_rates(self, human_readable=False):
"Get the 802.11 Management Supported Rates element. "\
"Specifies up to eight rates, then an Extended Supported Rate element "\
"shall be generated to specify the remaining supported rates."\
"If human_readable is True, the rates are returned in Mbit/sec"
s=self._get_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES)
2775 ↛ 2776line 2775 didn't jump to line 2776, because the condition on line 2775 was never true if s is None:
return None
rates=struct.unpack('%dB'%len(s),s)
if not human_readable:
return rates
rates_Mbs=tuple([(x&0x7F)*0.5 for x in rates])
return rates_Mbs
def set_supported_rates(self, rates):
"Set the 802.11 Management Supported Rates element. "\
"Specifies a tuple or list with up to eight rates, then an "\
"Extended Supported Rate element shall be generated to specify "\
"the remaining supported rates."
qty_rates=len(rates)
2791 ↛ 2792line 2791 didn't jump to line 2792, because the condition on line 2791 was never true if qty_rates>8:
raise Exception("requires up to eight rates")
rates_string=struct.pack('B'*qty_rates,*rates)
self._set_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES,rates_string)
def get_rsn(self):
"Get the 802.11 Management Robust Security Network element."
s = self._get_element(DOT11_MANAGEMENT_ELEMENTS.RSN)
2799 ↛ 2800line 2799 didn't jump to line 2800, because the condition on line 2799 was never true if s is None:
return None
return s
def set_rsn(self, data):
"Set the 802.11 Management Robust Security Network element."
self._set_element(DOT11_MANAGEMENT_ELEMENTS.RSN, data)
def get_vendor_specific(self):
"Get the 802.11 Management Vendor Specific elements "\
"as a list of tuples."
"The Vendor Specific information element is used to carry "\
"information not defined in the standard within a single "\
"defined format"
vs=[]
gen_get_element=self._get_elements_generator(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC)
try:
while 1:
s=next(gen_get_element)
2820 ↛ 2821line 2820 didn't jump to line 2821, because the condition on line 2820 was never true if s is None:
raise Exception("gen_get_element salio con None!!!")
# OUI is 3 bytes
oui=s[:3]
data=s[3:]
vs.append((oui,data))
except StopIteration:
pass
return vs
def add_vendor_specific(self, oui, data):
"Set the 802.11 Management Vendor Specific element. "\
"The Vendor Specific information element is used to carry "\
"information not defined in the standard within a single "\
"defined format"
# 3 is the OUI length
max_data_len=255-3
data_len=len(data)
2842 ↛ 2843line 2842 didn't jump to line 2843, because the condition on line 2842 was never true if data_len>max_data_len:
raise Exception("data allow up to %d bytes long" % max_data_len)
2844 ↛ 2845line 2844 didn't jump to line 2845, because the condition on line 2844 was never true if len(oui) > 3:
raise Exception("oui is three bytes long")
self._set_element(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC,oui+data, replace=False)
class Dot11ManagementAssociationResponse(Dot11ManagementHelper):
'802.11 Management Association Response Frame'
__HEADER_BASE_SIZE = 6 # minimal header size
def __init__(self, aBuffer = None):
header_size = self.__HEADER_BASE_SIZE
tail_size = 0
Dot11ManagementHelper.__init__(self, header_size, tail_size, aBuffer)
def get_capabilities(self):
'Return the 802.11 Management Association Response Frame \'Capability information\' field. '
b = self.header.get_word(0, "<")
return b
def set_capabilities(self, value):
'Set the 802.11 Management Association Response Frame \'Capability Information\' field'
# set the bits
nb = value & 0xFFFF
self.header.set_word(0, nb, "<")
def get_status_code(self):
'Return the 802.11 Management Association Response Frame \'Status Code\' field. '
b = self.header.get_word(2, "<")
return b
def set_status_code(self, value):
'Set the 802.11 Management Association Response Frame \'Status Code\' field'
self.header.set_word(2, value, "<")
def get_association_id(self):
'Return the 802.11 Management Association Response Frame \'Association Id\' field. '
b = self.header.get_word(4, "<")
return b
def set_association_id(self, value):
'Set the 802.11 Management Association Response Frame \'Association Id\' field'
self.header.set_word(4, value, "<")
def get_supported_rates(self, human_readable=False):
"Get the 802.11 Management Supported Rates element. "\
"Specifies up to eight rates, then an Extended Supported Rate element "\
"shall be generated to specify the remaining supported rates."\
"If human_readable is True, the rates are returned in Mbit/sec"
s=self._get_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES)
2894 ↛ 2895line 2894 didn't jump to line 2895, because the condition on line 2894 was never true if s is None:
return None
rates=struct.unpack('%dB'%len(s),s)
if not human_readable:
return rates
rates_Mbs=tuple([(x&0x7F)*0.5 for x in rates])
return rates_Mbs
def set_supported_rates(self, rates):
"Set the 802.11 Management Supported Rates element. "\
"Specifies a tuple or list with up to eight rates, then an "\
"Extended Supported Rate element shall be generated to specify "\
"the remaining supported rates."
qty_rates=len(rates)
2910 ↛ 2911line 2910 didn't jump to line 2911, because the condition on line 2910 was never true if qty_rates>8:
raise Exception("requires up to eight rates")
rates_string=struct.pack('B'*qty_rates,*rates)
self._set_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES,rates_string)
def get_vendor_specific(self):
"Get the 802.11 Management Vendor Specific elements "\
"as a list of tuples."
"The Vendor Specific information element is used to carry "\
"information not defined in the standard within a single "\
"defined format"
vs=[]
gen_get_element=self._get_elements_generator(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC)
try:
while 1:
s=next(gen_get_element)
2928 ↛ 2929line 2928 didn't jump to line 2929, because the condition on line 2928 was never true if s is None:
raise Exception("gen_get_element salio con None!!!")
# OUI is 3 bytes
oui=s[:3]
data=s[3:]
vs.append((oui,data))
except StopIteration:
pass
return vs
def add_vendor_specific(self, oui, data):
"Set the 802.11 Management Vendor Specific element. "\
"The Vendor Specific information element is used to carry "\
"information not defined in the standard within a single "\
"defined format"
# 3 is the OUI length
max_data_len=255-3
data_len=len(data)
2949 ↛ 2950line 2949 didn't jump to line 2950, because the condition on line 2949 was never true if data_len>max_data_len:
raise Exception("data allow up to %d bytes long" % max_data_len)
2951 ↛ 2952line 2951 didn't jump to line 2952, because the condition on line 2951 was never true if len(oui) > 3:
raise Exception("oui is three bytes long")
self._set_element(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC,oui+data, replace=False)
class Dot11ManagementReassociationRequest(Dot11ManagementHelper):
'802.11 Management Reassociation Request Frame'
__HEADER_BASE_SIZE = 10 # minimal header size
def __init__(self, aBuffer = None):
header_size = self.__HEADER_BASE_SIZE
tail_size = 0
Dot11ManagementHelper.__init__(self, header_size, tail_size, aBuffer)
def get_capabilities(self):
'Return the 802.11 Management Reassociation Request Frame \'Capability information\' field. '
b = self.header.get_word(0, "<")
return b
def set_capabilities(self, value):
'Set the 802.11 Management Reassociation Request Frame \'Capability Information\' field'
# set the bits
nb = value & 0xFFFF
self.header.set_word(0, nb, "<")
def get_listen_interval(self):
'Return the 802.11 Management Reassociation Request Frame \'Listen Interval\' field. '
b = self.header.get_word(2, "<")
return b
def set_listen_interval(self, value):
'Set the 802.11 Management Reassociation Request Frame \'Listen Interval\' field'
self.header.set_word(2, value, "<")
def get_current_ap(self):
'Return the 802.11 Management Reassociation Request Frame \'Current AP\' field.'
return self.header.get_bytes()[4:10]
def set_current_ap(self, value):
'Set the 802.11 Management Reassociation Request Frame \'Current AP\' field'
for i in range(0, 6):
self.header.set_byte(4+i, value[i])
def get_ssid(self):
"Get the 802.11 Management SSID element. "\
"The SSID element indicates the identity of an ESS or IBSS."
return self._get_element(DOT11_MANAGEMENT_ELEMENTS.SSID)
def set_ssid(self, ssid):
self._set_element(DOT11_MANAGEMENT_ELEMENTS.SSID,ssid)
def get_supported_rates(self, human_readable=False):
"Get the 802.11 Management Supported Rates element. "\
"Specifies up to eight rates, then an Extended Supported Rate element "\
"shall be generated to specify the remaining supported rates."\
"If human_readable is True, the rates are returned in Mbit/sec"
s=self._get_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES)
3009 ↛ 3010line 3009 didn't jump to line 3010, because the condition on line 3009 was never true if s is None:
return None
rates=struct.unpack('%dB'%len(s),s)
if not human_readable:
return rates
rates_Mbs=tuple([(x&0x7F)*0.5 for x in rates])
return rates_Mbs
def set_supported_rates(self, rates):
"Set the 802.11 Management Supported Rates element. "\
"Specifies a tuple or list with up to eight rates, then an "\
"Extended Supported Rate element shall be generated to specify "\
"the remaining supported rates."
qty_rates=len(rates)
3025 ↛ 3026line 3025 didn't jump to line 3026, because the condition on line 3025 was never true if qty_rates>8:
raise Exception("requires up to eight rates")
rates_string=struct.pack('B'*qty_rates,*rates)
self._set_element(DOT11_MANAGEMENT_ELEMENTS.SUPPORTED_RATES,rates_string)
def get_rsn(self):
"Get the 802.11 Management Robust Security Network element."
s = self._get_element(DOT11_MANAGEMENT_ELEMENTS.RSN)
3033 ↛ 3034line 3033 didn't jump to line 3034, because the condition on line 3033 was never true if s is None:
return None
return s
def set_rsn(self, data):
"Set the 802.11 Management Robust Security Network element."
self._set_element(DOT11_MANAGEMENT_ELEMENTS.RSN, data)
def get_vendor_specific(self):
"Get the 802.11 Management Vendor Specific elements "\
"as a list of tuples."
"The Vendor Specific information element is used to carry "\
"information not defined in the standard within a single "\
"defined format"
vs=[]
gen_get_element=self._get_elements_generator(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC)
try:
while 1:
s=next(gen_get_element)
3054 ↛ 3055line 3054 didn't jump to line 3055, because the condition on line 3054 was never true if s is None:
raise Exception("gen_get_element salio con None!!!")
# OUI is 3 bytes
oui=s[:3]
data=s[3:]
vs.append((oui,data))
except StopIteration:
pass
return vs
def add_vendor_specific(self, oui, data):
"Set the 802.11 Management Vendor Specific element. "\
"The Vendor Specific information element is used to carry "\
"information not defined in the standard within a single "\
"defined format"
# 3 is the OUI length
max_data_len=255-3
data_len=len(data)
3076 ↛ 3077line 3076 didn't jump to line 3077, because the condition on line 3076 was never true if data_len>max_data_len:
raise Exception("data allow up to %d bytes long" % max_data_len)
3078 ↛ 3079line 3078 didn't jump to line 3079, because the condition on line 3078 was never true if len(oui) > 3:
raise Exception("oui is three bytes long")
self._set_element(DOT11_MANAGEMENT_ELEMENTS.VENDOR_SPECIFIC,oui+data, replace=False)
class Dot11ManagementReassociationResponse(Dot11ManagementAssociationResponse):
'802.11 Management Reassociation Response Frame'
def __init__(self, aBuffer = None):
Dot11ManagementAssociationResponse.__init__(self, aBuffer)
|