Skip to content

Add support for S1G beacon to the dot11 layer. (#2) #4458

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Dec 28, 2024
30 changes: 26 additions & 4 deletions scapy/layers/dot11.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
Expand All @@ -702,25 +702,39 @@ 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(
_Dot11MacField("addr3", ETHER_ANY, 3),
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
Expand All @@ -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.
Expand Down Expand Up @@ -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 #
###################
Expand Down Expand Up @@ -1981,13 +2001,15 @@ 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)
bind_layers(Dot11, Dot11Deauth, subtype=12, type=0)
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,)
Expand Down
18 changes: 18 additions & 0 deletions test/scapy/layers/dot11.uts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading