diff --git a/scapy/layers/dot11.py b/scapy/layers/dot11.py index 9c2722196ff..0d6d0d69687 100644 --- a/scapy/layers/dot11.py +++ b/scapy/layers/dot11.py @@ -1685,6 +1685,42 @@ class Dot11EltHEOperation(Dot11EltExtension): Dot11EltHEOperation.register_variant(36) +# 802.11n-2009 7.3.2.57, Figure 7-95o24, Table 7-43p + +class Dot11EltHTOperation(Dot11Elt): + name = "802.11 HT Operation" + match_subclass = True + fields_desc = [ + ByteEnumField("ID", 61, _dot11_id_enum), + ByteField("len", 22), + ByteField("primary_channel", 0), + + # HT Operation Information: 1B + BitField("reserved_1", 0, 4, tot_size=-1), + BitField("rifs_mode", 0, 1), + BitField("channel_width", 0, 1), + BitField("secondary_channel_offset", 0, 2, end_tot_size=-1), + + # HT Operation Information: 2B + BitField("reserved_3", 0, 11, tot_size=-2), + BitField("obss_non_ht_stas_present", 0, 1), + BitField("reserved_2", 0, 1), + BitField("nongreenfield_ht_stas_present", 0, 1), + BitField("ht_protection", 0, 2, end_tot_size=-2), + + # HT Operation Information: 2B + BitField("reserved_4", 0, 10, tot_size=-2), + BitField("pco_phase", 0, 1), + BitField("pco_active", 0, 1), + BitField("lsig_txop_protection_full_support", 0, 1), + BitField("stbc_beacon", 0, 1), + BitField("dual_cts_protection", 0, 1), + BitField("dual_beacon", 0, 1, end_tot_size=-2), + + StrFixedLenField("basic_mcs_set", b"\x00" * 16, 16), + ] + + ###################### # 802.11 Frame types # ###################### diff --git a/test/scapy/layers/dot11.uts b/test/scapy/layers/dot11.uts index 9444eec4265..eaf84b17064 100644 --- a/test/scapy/layers/dot11.uts +++ b/test/scapy/layers/dot11.uts @@ -779,6 +779,30 @@ assert pkt[Dot11EltVHTOperation].VHT_Operation_Info.channel_center1 == 50 pkt = Dot11EltVHTOperation(b'\xc0\x05\x01*2\x00\x00') assert pkt[Dot11Elt::{"ID": 192}].len == 5 += Dot11EltHTOperation in isolation + +data = b'\x3d\x16\x24\x0d\x17\x00\x3f\x00' + b'\xff' + b'\x00' * 15 +pkt = Dot11Elt(data) +assert Dot11EltHTOperation in pkt +assert pkt[Dot11EltHTOperation].ID == 61 +assert pkt[Dot11EltHTOperation].len == 22 +assert pkt[Dot11EltHTOperation].primary_channel == 36 +assert pkt[Dot11EltHTOperation].secondary_channel_offset == 1 +assert pkt[Dot11EltHTOperation].channel_width == 1 +assert pkt[Dot11EltHTOperation].rifs_mode == 1 +assert pkt[Dot11EltHTOperation].reserved_1 == 0 +assert pkt[Dot11EltHTOperation].ht_protection == 3 +assert pkt[Dot11EltHTOperation].nongreenfield_ht_stas_present == 1 +assert pkt[Dot11EltHTOperation].obss_non_ht_stas_present == 1 +assert pkt[Dot11EltHTOperation].dual_beacon == 1 +assert pkt[Dot11EltHTOperation].dual_cts_protection == 1 +assert pkt[Dot11EltHTOperation].stbc_beacon == 1 +assert pkt[Dot11EltHTOperation].lsig_txop_protection_full_support == 1 +assert pkt[Dot11EltHTOperation].pco_active == 1 +assert pkt[Dot11EltHTOperation].pco_phase == 1 +assert pkt[Dot11EltHTOperation].basic_mcs_set == b'\xff' + b'\x00' * 15 +assert raw(pkt) == data + = Dot11EltExtension generic in isolation data = b'\xff\x03\x30\x01\x02'