Skip to content

Commit a686d23

Browse files
gg-gvaladonguedou
authored andcommitted
Attempt to decode SCTPChunkData data when possible
Removed exception handling around SCTP packet creation.
1 parent ded1d73 commit a686d23

File tree

4 files changed

+51
-4
lines changed

4 files changed

+51
-4
lines changed

scapy/contrib/diameter.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4828,7 +4828,5 @@ def DiamAns(cmd, **fields):
48284828

48294829
bind_layers(TCP, DiamG, dport=3868)
48304830
bind_layers(TCP, DiamG, sport=3868)
4831-
bind_layers(SCTPChunkData, DiamG, dport=3868)
4832-
bind_layers(SCTPChunkData, DiamG, sport=3868)
48334831
bind_layers(SCTPChunkData, DiamG, proto_id=46)
48344832
bind_layers(SCTPChunkData, DiamG, proto_id=47)

scapy/layers/sctp.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
IntEnumField,
2525
IntField,
2626
MultipleTypeField,
27+
PacketLenField,
2728
PacketListField,
2829
PadField,
2930
ShortEnumField,
@@ -624,6 +625,23 @@ class SCTPChunkParamAdaptationLayer(_SCTPChunkParam, Packet):
624625
}
625626

626627

628+
class _SCTPChunkDataField(PacketLenField):
629+
"""PacketLenField that dispatches using bind_layers bindings."""
630+
631+
def m2i(self, pkt, m):
632+
# Only dissect complete messages
633+
if pkt.beginning != 1 or pkt.ending != 1:
634+
return conf.raw_layer(load=m)
635+
# Check bind_layers bindings
636+
for fval, cls in pkt.payload_guess:
637+
if all(
638+
hasattr(pkt, k) and v == pkt.getfieldval(k)
639+
for k, v in fval.items()
640+
):
641+
return cls(m)
642+
return conf.raw_layer(load=m)
643+
644+
627645
class SCTPChunkData(_SCTPChunkGuessPayload, Packet):
628646
# TODO : add a padding function in post build if this layer is used to generate SCTP chunk data # noqa: E501
629647
fields_desc = [ByteEnumField("type", 0, sctpchunktypes),
@@ -637,7 +655,8 @@ class SCTPChunkData(_SCTPChunkGuessPayload, Packet):
637655
XShortField("stream_id", None),
638656
XShortField("stream_seq", None),
639657
IntEnumField("proto_id", None, SCTP_PAYLOAD_PROTOCOL_INDENTIFIERS), # noqa: E501
640-
PadField(StrLenField("data", None, length_from=lambda pkt: pkt.len - 16), # noqa: E501
658+
PadField(_SCTPChunkDataField("data", None, conf.raw_layer,
659+
length_from=lambda pkt: pkt.len - 16), # noqa: E501
641660
4, padwith=b"\x00"),
642661
]
643662

test/contrib/diameter.uts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,3 +253,33 @@ r3b = DiamReq ('Multimedia-Auth', drHbHId=0x5478, drEtEId=0x1234,
253253

254254
raw(r3b) == raw(r3)
255255

256+
257+
#######################################################################
258+
+ Diameter over SCTP
259+
#######################################################################
260+
261+
= Diameter decoded from SCTPChunkData via proto_id binding
262+
263+
from scapy.layers.sctp import SCTP, SCTPChunkData
264+
265+
diam_pkt = DiamAns('Capabilities-Exchange', drHbHId=0x1234, drEtEId=0x5678,
266+
avpList=[AVP('Origin-Host', val='host.example.com'),
267+
AVP('Origin-Realm', val='example.com')])
268+
269+
pkt = SCTP(raw(SCTP() / SCTPChunkData(proto_id=46, beginning=1, ending=1, data=raw(diam_pkt))))
270+
chunk = pkt[SCTPChunkData]
271+
assert isinstance(chunk.data, DiamG)
272+
assert chunk.proto_id == 46
273+
assert chunk.data.drHbHId == 0x1234
274+
assert chunk.data.avpList[0].avpCode == 264
275+
276+
= SCTPChunkData with unknown proto_id keeps raw bytes
277+
278+
pkt = SCTP(raw(SCTP() / SCTPChunkData(proto_id=0, data=b"test")))
279+
assert raw(pkt[SCTPChunkData].data) == b"test"
280+
281+
= SCTPChunkData fragment is not decoded
282+
283+
pkt = SCTP(raw(SCTP() / SCTPChunkData(proto_id=46, beginning=1, ending=0, data=raw(diam_pkt))))
284+
assert not isinstance(pkt[SCTPChunkData].data, DiamG)
285+

test/scapy/layers/sctp.uts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ assert p.tsn == 0
4949
assert p.stream_id == 0
5050
assert p.stream_seq == 0
5151
assert p.len == (len("data") + 16)
52-
assert p.data == b"data"
52+
assert raw(p.data) == b"data"
5353

5454
= basic SCTPChunkIData - Dissection
5555
~ sctp

0 commit comments

Comments
 (0)