Skip to content

Commit dff9ca1

Browse files
committed
Revert part of 2629 / FlagsField & SMB2 fixes
1 parent c68ee2b commit dff9ca1

4 files changed

Lines changed: 100 additions & 78 deletions

File tree

scapy/fields.py

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2152,27 +2152,54 @@ class FlagsField(BitField):
21522152
21532153
Make sure all your flags have a label
21542154
2155-
Example:
2155+
Example (list):
21562156
>>> from scapy.packet import Packet
21572157
>>> class FlagsTest(Packet):
21582158
fields_desc = [FlagsField("flags", 0, 8, ["f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7"])] # noqa: E501
21592159
>>> FlagsTest(flags=9).show2()
21602160
###[ FlagsTest ]###
21612161
flags = f0+f3
2162-
>>> FlagsTest(flags=0).show2().strip()
2162+
2163+
Example (str):
2164+
>>> from scapy.packet import Packet
2165+
>>> class TCPTest(Packet):
2166+
fields_desc = [
2167+
BitField("reserved", 0, 7),
2168+
FlagsField("flags", 0x2, 9, "FSRPAUECN")
2169+
]
2170+
>>> TCPTest(flags=3).show2()
21632171
###[ FlagsTest ]###
2164-
flags =
2172+
reserved = 0
2173+
flags = FS
2174+
2175+
Example (dict):
2176+
>>> from scapy.packet import Packet
2177+
>>> class FlagsTest2(Packet):
2178+
fields_desc = [
2179+
FlagsField("flags", 0x2, 16, {
2180+
1: "1", # 1st bit
2181+
8: "2" # 8th bit
2182+
})
2183+
]
21652184
21662185
:param name: field's name
21672186
:param default: default value for the field
21682187
:param size: number of bits in the field (in bits)
2169-
:param names: (list or dict) label for each flag, Least Significant Bit tag's name is written first # noqa: E501
2188+
:param names: (list or str or dict) label for each flag
2189+
If it's a str or a list, the least Significant Bit tag's name
2190+
is written first.
21702191
"""
21712192
ismutable = True
2172-
__slots__ = ["multi", "names"]
2193+
__slots__ = ["names"]
21732194

21742195
def __init__(self, name, default, size, names):
2175-
self.multi = isinstance(names, list)
2196+
# Convert the dict to a list
2197+
if isinstance(names, dict):
2198+
tmp = ["bit_%d" % i for i in range(size)]
2199+
for i, v in six.viewitems(names):
2200+
tmp[i] = v
2201+
names = tmp
2202+
# Store the names as str or list
21762203
self.names = names
21772204
BitField.__init__(self, name, default, size)
21782205

scapy/layers/smb2.py

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,30 @@
99

1010
from scapy.config import conf
1111
from scapy.packet import Packet, bind_layers
12-
from scapy.fields import StrFixedLenField, LEIntField, LEShortEnumField, \
13-
ShortEnumField, XLEIntField, LEShortField, FlagsField, LELongField, \
14-
XLELongField, XNBytesField, FieldLenField, IntField, FieldListField, \
15-
XStrLenField, ShortField, IntEnumField, StrFieldUtf16, XLEShortField, \
16-
UUIDField, XLongField, PacketListField, PadField
12+
from scapy.fields import (
13+
FieldLenField,
14+
FieldListField,
15+
FlagsField,
16+
IntEnumField,
17+
IntField,
18+
LEIntField,
19+
LELongField,
20+
LEShortEnumField,
21+
LEShortField,
22+
PacketListField,
23+
PadField,
24+
ShortEnumField,
25+
ShortField,
26+
StrFieldUtf16,
27+
StrFixedLenField,
28+
UUIDField,
29+
XLEIntField,
30+
XLELongField,
31+
XLEShortField,
32+
XLongField,
33+
XNBytesField,
34+
XStrLenField,
35+
)
1736

1837

1938
# EnumField
@@ -35,13 +54,13 @@
3554

3655
# FlagField
3756
SMB2_CAPABILITIES = {
38-
30: "CapabilitiesEncryption",
39-
29: "CapabilitiesDirectoryLeasing",
40-
28: "CapabilitiesPersistentHandles",
41-
27: "CapabilitiesMultiChannel",
42-
26: "CapabilitiesLargeMTU",
43-
25: "CapabilitiesLeasing",
44-
24: "CapabilitiesDFS",
57+
30: "Encryption",
58+
29: "DirectoryLeasing",
59+
28: "PersistentHandles",
60+
27: "MultiChannel",
61+
26: "LargeMTU",
62+
25: "Leasing",
63+
24: "DFS",
4564
}
4665

4766
# EnumField
@@ -76,6 +95,13 @@ class SMB2_Header(Packet):
7695
XNBytesField("Signature", 0, 16),
7796
]
7897

98+
def guess_payload_class(self, payload):
99+
if self.Command == 0x0000:
100+
if self.Flags.SMB2_FLAGS_SERVER_TO_REDIR:
101+
return SMB2_Negociate_Protocol_Response_Header
102+
return SMB2_Negociate_Protocol_Request_Header
103+
return super(SMB2_Header, self).guess_payload_class(payload)
104+
79105

80106
class SMB2_Compression_Transform_Header(Packet):
81107
name = "SMB2 Compression Transform Header"
@@ -270,18 +296,6 @@ class SMB2_Negociate_Protocol_Response_Header(Packet):
270296
bind_layers(SMB2_Encryption_Capabilities, conf.padding_layer)
271297
bind_layers(SMB2_Compression_Capabilities, conf.padding_layer)
272298
bind_layers(SMB2_Netname_Negociate_Context_ID, conf.padding_layer)
273-
bind_layers(
274-
SMB2_Header,
275-
SMB2_Negociate_Protocol_Request_Header,
276-
Command=0x0000,
277-
Flags=lambda f: (f >> 24) & 1 == 0
278-
)
279-
bind_layers(
280-
SMB2_Header,
281-
SMB2_Negociate_Protocol_Response_Header,
282-
Command=0x0000,
283-
Flags=lambda f: (f >> 24) & 1 == 1
284-
)
285299
bind_layers(
286300
SMB2_Negociate_Context,
287301
SMB2_Preauth_Integrity_Capabilities,

test/fields.uts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,6 +1487,35 @@ assert "f2" in flags
14871487
assert "f4" in flags
14881488
assert "f0" in flags
14891489

1490+
= FlagsField with str
1491+
1492+
class TCPTest(Packet):
1493+
fields_desc = [
1494+
BitField("reserved", 0, 7),
1495+
FlagsField("flags", 0x2, 9, "FSRPAUECN")
1496+
]
1497+
1498+
a = TCPTest(flags=3)
1499+
assert a.flags.F
1500+
assert a.flags.S
1501+
assert a.sprintf("%flags%") == "FS"
1502+
1503+
= FlagsField with dict
1504+
1505+
class FlagsTest2(Packet):
1506+
fields_desc = [
1507+
FlagsField("flags", 0x2, 16, {
1508+
0: "A", # 0 bit
1509+
7: "B" # 7 bit
1510+
})
1511+
]
1512+
1513+
a = FlagsTest2(flags=255)
1514+
a.sprintf("%flags%")
1515+
assert a.flags.A
1516+
assert a.flags.B
1517+
assert a.sprintf("%flags%") == "A+bit_1+bit_2+bit_3+bit_4+bit_5+bit_6+B"
1518+
14901519

14911520
########
14921521
########

test/smb2.uts

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
############
2-
############
3-
~ SMB2
4-
51
+ SMB2 Header
62

73
= SMB2 Header dissecting
@@ -59,15 +55,6 @@ assert pkt[NBTSession].TYPE == 0x00 # session message
5955
smb2 = pkt[SMB2_Header]
6056
assert smb2.Start == b'\xfeSMB'
6157

62-
63-
64-
65-
66-
67-
68-
69-
70-
7158
+ SMB2 Negociate Procotol Request Header dissecting
7259

7360
= Common fields in header
@@ -146,28 +133,6 @@ assert netname.DataLength == 28
146133
assert netname.NetName == '192.168.178.21'
147134

148135

149-
150-
151-
152-
153-
154-
155-
156-
157-
+ test SMB2 Negociate Protocol Request Header - assembling
158-
159-
pkt = IP() / TCP() / NBTSession() / SMB2_Header() / SMB2_Negociate_Protocol_Request_Header()
160-
assert SMB2_Negociate_Protocol_Request_Header in pkt
161-
162-
163-
164-
165-
166-
167-
168-
169-
170-
171136
+ SMB2 Negociate Protocol Response Header dissecting
172137

173138
= Common fields in header
@@ -229,16 +194,3 @@ assert comp.CompressionAlgorithmCount == 1
229194
assert len(comp.CompressionAlgorithms) == 1
230195
assert comp.CompressionAlgorithms[0] == 1
231196

232-
233-
234-
235-
236-
237-
238-
239-
240-
241-
+ SMB2 Negociate Protocol Response Header assembling
242-
243-
pkt = IP() / TCP() / NBTSession() / SMB2_Header() / SMB2_Negociate_Protocol_Response_Header()
244-
assert SMB2_Negociate_Protocol_Response_Header in pkt

0 commit comments

Comments
 (0)