Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 93 additions & 3 deletions scapy/layers/dot11.py
Original file line number Diff line number Diff line change
Expand Up @@ -1476,14 +1476,15 @@ class Dot11EltMicrosoftWPA(Dot11EltVendorSpecific):
@classmethod
def dispatch_hook(cls, _pkt=None, *args, **kargs):
if _pkt:
if len(_pkt) < 6:
return Dot11EltVendorSpecific
type_ = orb(_pkt[5])
if type_ == 0x01:
# MS WPA IE
return Dot11EltMicrosoftWPA
elif type_ == 0x02:
# MS WME IE TODO
# return Dot11EltMicrosoftWME
pass
# MS WME IE
return Dot11EltMicrosoftWME
elif type_ == 0x04:
# MS WPS IE TODO
# return Dot11EltWPS
Expand All @@ -1492,6 +1493,95 @@ def dispatch_hook(cls, _pkt=None, *args, **kargs):
return cls


_dot11_wme_subtypes = {
0: "Information",
1: "Parameter",
}


_dot11_wme_ac_aci = {
0: "Best Effort",
1: "Background",
2: "Video",
3: "Voice",
}


def _dot11_wme_remaining_len(pkt):
subtype = getattr(pkt, "subtype", None)
if subtype == 1 and pkt.len >= 24:
consumed = 24
elif subtype == 1 and pkt.len >= 8:
consumed = 8
elif pkt.len >= 5:
consumed = min(pkt.len, 7)
else:
consumed = 4
return max(pkt.len - consumed, 0)


class Dot11WMEACParameter(Packet):
name = "802.11 WME AC Parameter"
fields_desc = [
BitField("reserved", 0, 1, tot_size=-1),
BitEnumField("aci", 0, 2, _dot11_wme_ac_aci),
BitField("acm", 0, 1),
BitField("aifsn", 0, 4, end_tot_size=-1),
BitField("ecw_max", 0, 4, tot_size=-1),
BitField("ecw_min", 0, 4, end_tot_size=-1),
LEShortField("txop_limit", 0),
]

def extract_padding(self, s):
return b"", s


class Dot11EltMicrosoftWME(Dot11EltVendorSpecific):
name = "802.11 Microsoft WMM WME"
match_subclass = True
ID = 221
oui = 0x0050f2
fields_desc = Dot11EltVendorSpecific.fields_desc[:3] + [
XByteField("type", 0x02),
ConditionalField(
ByteEnumField("subtype", 0, _dot11_wme_subtypes),
lambda pkt: pkt.len >= 5
),
ConditionalField(
ByteField("version", 1),
lambda pkt: pkt.len >= 6
),
ConditionalField(
ByteField("qos_info", 0),
lambda pkt: pkt.len >= 7
),
ConditionalField(
ByteField("reserved", 0),
lambda pkt: (
getattr(pkt, "subtype", None) == 1 and
pkt.len >= 8
)
),
ConditionalField(
PacketListField(
"ac_params",
[],
Dot11WMEACParameter,
count_from=lambda pkt: 4
),
lambda pkt: (
getattr(pkt, "subtype", None) == 1 and
pkt.len >= 24
)
),
StrLenField(
"info",
b"",
length_from=_dot11_wme_remaining_len
)
]


# 802.11-2016 9.4.2.19

class Dot11EltCSA(Dot11Elt):
Expand Down
41 changes: 41 additions & 0 deletions test/scapy/layers/dot11.uts
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,47 @@ assert ms_wpa_ie[Dot11EltMicrosoftWPA].nb_akm_suites == 0x01
assert ms_wpa_ie[Dot11EltMicrosoftWPA].akm_suites[0].suite == 0x01
assert Dot11Elt in ms_wpa_ie

= Dot11EltMicrosoftWME
ms_wme_info_ie = Dot11Elt(b'\xdd\x07\x00P\xf2\x02\x00\x01\x80\x00\x04test')
assert Dot11EltMicrosoftWME in ms_wme_info_ie
assert ms_wme_info_ie[Dot11EltMicrosoftWME].type == 0x02
assert ms_wme_info_ie[Dot11EltMicrosoftWME].subtype == 0x00
assert ms_wme_info_ie[Dot11EltMicrosoftWME].version == 0x01
assert ms_wme_info_ie[Dot11EltMicrosoftWME].qos_info == 0x80
assert ms_wme_info_ie[Dot11EltMicrosoftWME].getfieldval("info") == b""
assert Dot11Elt in ms_wme_info_ie
assert raw(ms_wme_info_ie) == b'\xdd\x07\x00P\xf2\x02\x00\x01\x80\x00\x04test'

ms_wme_param_ie = Dot11Elt(
b'\xdd\x18\x00P\xf2\x02\x01\x01\x80\x00'
b'\x03\xa4\x00\x00\x27\xa4\x00\x00\x42\x43\x5e\x00\x62\x32\x2f\x00'
b'\x00\x04test'
)
assert Dot11EltMicrosoftWME in ms_wme_param_ie
assert ms_wme_param_ie[Dot11EltMicrosoftWME].subtype == 0x01
assert ms_wme_param_ie[Dot11EltMicrosoftWME].version == 0x01
assert ms_wme_param_ie[Dot11EltMicrosoftWME].qos_info == 0x80
assert ms_wme_param_ie[Dot11EltMicrosoftWME].reserved == 0
assert len(ms_wme_param_ie[Dot11EltMicrosoftWME].ac_params) == 4
assert ms_wme_param_ie[Dot11EltMicrosoftWME].ac_params[0].aci == 0
assert ms_wme_param_ie[Dot11EltMicrosoftWME].ac_params[0].aifsn == 3
assert ms_wme_param_ie[Dot11EltMicrosoftWME].ac_params[0].ecw_min == 4
assert ms_wme_param_ie[Dot11EltMicrosoftWME].ac_params[0].ecw_max == 10
assert ms_wme_param_ie[Dot11EltMicrosoftWME].ac_params[1].aci == 1
assert ms_wme_param_ie[Dot11EltMicrosoftWME].ac_params[2].aci == 2
assert ms_wme_param_ie[Dot11EltMicrosoftWME].ac_params[3].aci == 3
assert ms_wme_param_ie[Dot11EltMicrosoftWME].getfieldval("info") == b""
assert Dot11Elt in ms_wme_param_ie
assert raw(ms_wme_param_ie) == (
b'\xdd\x18\x00P\xf2\x02\x01\x01\x80\x00'
b'\x03\xa4\x00\x00\x27\xa4\x00\x00\x42\x43\x5e\x00\x62\x32\x2f\x00'
b'\x00\x04test'
)

short_ms_vendor_ie = Dot11Elt(b'\xdd\x03\x00P\xf2')
assert short_ms_vendor_ie.__class__ == Dot11EltVendorSpecific
assert raw(short_ms_vendor_ie) == b'\xdd\x03\x00P\xf2'

= Dot11EltVendorSpecific
assert bytes(Dot11EltVendorSpecific()) == b'\xdd\x03\x00\x00\x00'
vendor_specific_ie = Dot11EltVendorSpecific(b'\xdd\t\x00\x03\x7f\x01\x01\x00\x00\xff\x7f')
Expand Down
Loading