diff --git a/scapy/layers/dot11.py b/scapy/layers/dot11.py index 3e0dced1d58..26f5bfdf811 100644 --- a/scapy/layers/dot11.py +++ b/scapy/layers/dot11.py @@ -683,7 +683,7 @@ def i2repr(self, pkt, val): return s -# 802.11-2016 9.2.4.1.1 +# 802.11-2020 9.2.4.1.1 class Dot11(Packet): name = "802.11" fields_desc = [ @@ -702,17 +702,31 @@ class Dot11(Packet): FlagsField("FCfield", 0, 4, ["pw-mgt", "MD", "protected", "order"]), lambda pkt: (pkt.type, pkt.subtype) == (1, 6) + ), + ( + FlagsField("FCfield", 0, 2, + ["security", "AP_PM"]), + lambda pkt: (pkt.type, pkt.subtype) == (3, 1) ) ], FlagsField("FCfield", 0, 8, ["to-DS", "from-DS", "MF", "retry", "pw-mgt", "MD", "protected", "order"]) ), + ConditionalField( + BitField("FCfield_bw", 0, 3), + lambda pkt: (pkt.type, pkt.subtype) == (3, 1) + ), + ConditionalField( + FlagsField("FCfield2", 0, 3, + ["next_tbtt", "comp_ssid", "ano"]), + lambda pkt: (pkt.type, pkt.subtype) == (3, 1) + ), ShortField("ID", 0), _Dot11MacField("addr1", ETHER_ANY, 1), ConditionalField( _Dot11MacField("addr2", ETHER_ANY, 2), - lambda pkt: (pkt.type != 1 or + lambda pkt: (pkt.type not in {1, 3} or pkt.subtype in [0x4, 0x5, 0x6, 0x8, 0x9, 0xa, 0xb, 0xe, 0xf]), ), ConditionalField( @@ -720,7 +734,7 @@ class Dot11(Packet): lambda pkt: (pkt.type in [0, 2] or ((pkt.type, pkt.subtype) == (1, 6) and pkt.cfe == 6)), ), - ConditionalField(LEShortField("SC", 0), lambda pkt: pkt.type != 1), + ConditionalField(LEShortField("SC", 0), lambda pkt: pkt.type not in {1, 3}), ConditionalField( _Dot11MacField("addr4", ETHER_ANY, 4), lambda pkt: (pkt.type == 2 and @@ -736,7 +750,7 @@ def guess_payload_class(self, payload): if self.type == 0x02 and ( 0x08 <= self.subtype <= 0xF and self.subtype != 0xD): return Dot11QoS - elif self.FCfield.protected: + elif hasattr(self.FCfield, "protected") and self.FCfield.protected: # When a frame is handled by encryption, the Protected Frame bit # (previously called WEP bit) is set to 1, and the Frame Body # begins with the appropriate cryptographic header. @@ -1832,6 +1846,12 @@ class Dot11CSA(Packet): ] +class Dot11S1GBeacon(_Dot11EltUtils): + name = "802.11 S1G Beacon" + fields_desc = [LEIntField("timestamp", 0), + ByteField("change_seq", 0)] + + ################### # 802.11 Security # ################### @@ -1981,6 +2001,7 @@ class Dot11CCMP(Dot11Encrypted): bind_layers(Dot11, Dot11ProbeReq, subtype=4, type=0) bind_layers(Dot11, Dot11ProbeResp, subtype=5, type=0) bind_layers(Dot11, Dot11Beacon, subtype=8, type=0) +bind_layers(Dot11, Dot11S1GBeacon, subtype=1, type=3) bind_layers(Dot11, Dot11ATIM, subtype=9, type=0) bind_layers(Dot11, Dot11Disas, subtype=10, type=0) bind_layers(Dot11, Dot11Auth, subtype=11, type=0) @@ -1988,6 +2009,7 @@ class Dot11CCMP(Dot11Encrypted): bind_layers(Dot11, Dot11Action, subtype=13, type=0) bind_layers(Dot11, Dot11Ack, subtype=13, type=1) bind_layers(Dot11Beacon, Dot11Elt,) +bind_layers(Dot11S1GBeacon, Dot11Elt,) bind_layers(Dot11AssoReq, Dot11Elt,) bind_layers(Dot11AssoResp, Dot11Elt,) bind_layers(Dot11ReassoReq, Dot11Elt,) diff --git a/test/scapy/layers/dot11.uts b/test/scapy/layers/dot11.uts index 06a45e01a29..b1c81931724 100644 --- a/test/scapy/layers/dot11.uts +++ b/test/scapy/layers/dot11.uts @@ -778,3 +778,21 @@ assert pkt[Dot11Elt::{"ID": 74}].len == 14 pkt = Dot11EltCSA(b'%\x03\x01\x0b\x05') assert pkt[Dot11Elt::{"ID": 37}].len == 3 + += Dot11S1GBeacon + +pkt=Dot11(b"\x1c\x18\x00\x00,/u\x1c\x103hq\xf8\x00\x00\xd5\x08\x01\x00d\x00\x00\x00\x00\x00\x05\x02\x00\x01\xd9\x0f\x9e\x00@\x18\x80\x0c\x00\x02@\x00\xfe\x00\xfc\x01\x00\xe8\x06\x06\x18&(\xc4\xcc\xd6\x02d\x00\x00\nWiFiDiving\xdd\x18\x00P\xf2\x02\x01\x01\x01\x00\x03\xa4\xd5\x01'\xa4\xd5\x01BC\xd5\x01b2\xd5\x01") +assert pkt[Dot11].type == 3 +assert pkt[Dot11].subtype == 1 +assert pkt[Dot11].addr1 == '2c:2f:75:1c:10:33' +assert pkt[Dot11S1GBeacon].timestamp == 16281960 +assert pkt[Dot11Elt::{"ID": 0}].info == b"WiFiDiving" +assert pkt[Dot11Elt::{"ID": 214}].len == 2 +assert pkt[Dot11Elt::{"ID": 217}].len == 15 +assert pkt[Dot11Elt::{"ID": 232}].len == 6 +assert pkt[Dot11].FCfield_bw == 3 +assert pkt[Dot11].FCfield2.next_tbtt == False +assert pkt[Dot11].FCfield2.comp_ssid == False +assert pkt[Dot11].FCfield2.ano == False +assert pkt[Dot11].FCfield.security == False +assert pkt[Dot11].FCfield.AP_PM == False