From 2ec8bcc1ddd830b0df4722347da918596b2dc923 Mon Sep 17 00:00:00 2001 From: Lucas Pascal <lpascal@quarkslab.com> Date: Wed, 9 Nov 2016 16:58:08 +0100 Subject: [PATCH] [add] RFC 4895 & 5061 - new params and chunks for SCTP --- scapy/layers/sctp.py | 178 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 168 insertions(+), 10 deletions(-) diff --git a/scapy/layers/sctp.py b/scapy/layers/sctp.py index 886321f9..d1961447 100644 --- a/scapy/layers/sctp.py +++ b/scapy/layers/sctp.py @@ -8,6 +8,7 @@ SCTP (Stream Control Transmission Protocol). """ +import os import struct from scapy.config import conf @@ -114,6 +115,13 @@ def sctp_checksum(buf): return update_adler32(1, buf) """ +hmactypes = { + 0 : "Reserved1", + 1 : "SHA-1", + 2 : "Reserved2", + 3 : "SHA-256", + } + sctpchunktypescls = { 0 : "SCTPChunkData", 1 : "SCTPChunkInit", @@ -128,6 +136,9 @@ sctpchunktypescls = { 10 : "SCTPChunkCookieEcho", 11 : "SCTPChunkCookieAck", 14 : "SCTPChunkShutdownComplete", + 15 : "SCTPChunkAuthentication", + 0x80 : "SCTPChunkAddressConfAck", + 0xc1 : "SCTPChunkAddressConf", } sctpchunktypes = { @@ -144,6 +155,9 @@ sctpchunktypes = { 10 : "cookie-echo", 11 : "cookie-ack", 14 : "shutdown-complete", + 15 : "authentication", + 0x80 : "address-configuration-ack", + 0xc1 : "address-configuration", } sctpchunkparamtypescls = { @@ -155,9 +169,18 @@ sctpchunkparamtypescls = { 9 : "SCTPChunkParamCookiePreservative", 11 : "SCTPChunkParamHostname", 12 : "SCTPChunkParamSupportedAddrTypes", - 32768 : "SCTPChunkParamECNCapable", - 49152 : "SCTPChunkParamFwdTSN", - 49158 : "SCTPChunkParamAdaptationLayer", + 0x8000 : "SCTPChunkParamECNCapable", + 0x8002 : "SCTPChunkParamRandom", + 0x8003 : "SCTPChunkParamChunkList", + 0x8004 : "SCTPChunkParamRequestedHMACFunctions", + 0x8008 : "SCTPChunkParamSupportedExtensions", + 0xc000 : "SCTPChunkParamFwdTSN", + 0xc001 : "SCTPChunkParamAddIPAddr", + 0xc002 : "SCTPChunkParamDelIPAddr", + 0xc003 : "SCTPChunkParamErrorIndication", + 0xc004 : "SCTPChunkParamSetPrimaryAddr", + 0xc005 : "SCTPChunkParamSuccessIndication", + 0xc006 : "SCTPChunkParamAdaptationLayer", } sctpchunkparamtypes = { @@ -169,9 +192,18 @@ sctpchunkparamtypes = { 9 : "cookie-preservative", 11 : "hostname", 12 : "addrtypes", - 32768 : "ecn-capable", - 49152 : "fwd-tsn-supported", - 49158 : "adaptation-layer", + 0x8000 : "ecn-capable", + 0x8002 : "random", + 0x8003 : "chunk-list", + 0x8004 : "requested-HMAC-functions", + 0x8008 : "supported-extensions", + 0xc000 : "fwd-tsn-supported", + 0xc001 : "add-IP", + 0xc002 : "del-IP", + 0xc003 : "error-indication", + 0xc004 : "set-primary-addr", + 0xc005 : "success-indication", + 0xc006 : "adaptation-layer", } ############## SCTP header @@ -280,15 +312,113 @@ class SCTPChunkParamSupportedAddrTypes(_SCTPChunkParam, Packet): 4, padwith=b"\x00"), ] class SCTPChunkParamECNCapable(_SCTPChunkParam, Packet): - fields_desc = [ ShortEnumField("type", 32768, sctpchunkparamtypes), + fields_desc = [ ShortEnumField("type", 0x8000, sctpchunkparamtypes), ShortField("len", 4), ] +class SCTPChunkParamRandom(_SCTPChunkParam, Packet): + fields_desc = [ ShortEnumField("type", 0x8002, sctpchunkparamtypes), + FieldLenField("len", None, length_of="random", + adjust = lambda pkt,x:x+4), + PadField(StrLenField("random", os.urandom(32), + length_from=lambda pkt: pkt.len-4), + 4, padwith="\x00"),] + +class SCTPChunkParamChunkList(_SCTPChunkParam, Packet): + fields_desc = [ ShortEnumField("type", 0x8003, sctpchunkparamtypes), + FieldLenField("len", None, length_of="chunk_list", + adjust = lambda pkt,x:x+4), + PadField(FieldListField("chunk_list", None, + ByteEnumField("chunk", None, sctpchunktypes), + length_from=lambda pkt: pkt.len-4), + 4, padwith="\x00"),] + +class SCTPChunkParamRequestedHMACFunctions(_SCTPChunkParam, Packet): + fields_desc = [ ShortEnumField("type", 0x8004, sctpchunkparamtypes), + FieldLenField("len", None, length_of="HMAC_functions_list", + adjust = lambda pkt,x:x+4), + PadField(FieldListField("HMAC_functions_list", [ "SHA-1" ], + ShortEnumField("HMAC_function", 1, hmactypes), + length_from=lambda pkt: pkt.len-4), + 4, padwith="\x00"),] + +class SCTPChunkParamSupportedExtensions(_SCTPChunkParam, Packet): + fields_desc = [ ShortEnumField("type", 0x8008, sctpchunkparamtypes), + FieldLenField("len", None, length_of="supported_extensions", + adjust = lambda pkt,x:x+4), + PadField(FieldListField("supported_extensions", + [ "authentication", + "address-configuration", + "address-configuration-ack" ], + ByteEnumField("supported_extensions", + None, sctpchunktypes), + length_from=lambda pkt: pkt.len-4), + 4, padwith="\x00"),] + class SCTPChunkParamFwdTSN(_SCTPChunkParam, Packet): - fields_desc = [ ShortEnumField("type", 49152, sctpchunkparamtypes), + fields_desc = [ ShortEnumField("type", 0xc000, sctpchunkparamtypes), ShortField("len", 4), ] +class SCTPChunkParamAddIPAddr(_SCTPChunkParam, Packet): + fields_desc = [ ShortEnumField("type", 0xc001, sctpchunkparamtypes), + FieldLenField("len", None, length_of="addr", + adjust = lambda pkt,x:x+12), + XIntField("correlation_id", None), + ShortEnumField("addr_type", 5, sctpchunkparamtypes), + FieldLenField("addr_len", None, length_of="addr", + adjust = lambda pkt,x:x+4), + ConditionalField( + IPField("addr", "127.0.0.1"), + lambda p: p.addr_type == 5), + ConditionalField( + IP6Field("addr", "::1"), + lambda p: p.addr_type == 6),] + +class SCTPChunkParamDelIPAddr(_SCTPChunkParam, Packet): + fields_desc = [ ShortEnumField("type", 0xc002, sctpchunkparamtypes), + FieldLenField("len", None, length_of="addr", + adjust = lambda pkt,x:x+12), + XIntField("correlation_id", None), + ShortEnumField("addr_type", 5, sctpchunkparamtypes), + FieldLenField("addr_len", None, length_of="addr", + adjust = lambda pkt,x:x+4), + ConditionalField( + IPField("addr", "127.0.0.1"), + lambda p: p.addr_type == 5), + ConditionalField( + IP6Field("addr", "::1"), + lambda p: p.addr_type == 6),] + +class SCTPChunkParamErrorIndication(_SCTPChunkParam, Packet): + fields_desc = [ ShortEnumField("type", 0xc003, sctpchunkparamtypes), + FieldLenField("len", None, length_of="error_causes", + adjust = lambda pkt,x:x+8), + XIntField("correlation_id", None), + PadField(StrLenField("error_causes", "", + length_from=lambda pkt: pkt.len-4), + 4, padwith="\x00"),] + +class SCTPChunkParamSetPrimaryAddr(_SCTPChunkParam, Packet): + fields_desc = [ ShortEnumField("type", 0xc004, sctpchunkparamtypes), + FieldLenField("len", None, length_of="addr", + adjust = lambda pkt,x:x+12), + XIntField("correlation_id", None), + ShortEnumField("addr_type", 5, sctpchunkparamtypes), + FieldLenField("addr_len", None, length_of="addr", + adjust = lambda pkt,x:x+4), + ConditionalField( + IPField("addr", "127.0.0.1"), + lambda p: p.addr_type == 5), + ConditionalField( + IP6Field("addr", "::1"), + lambda p: p.addr_type == 6),] + +class SCTPChunkParamSuccessIndication(_SCTPChunkParam, Packet): + fields_desc = [ ShortEnumField("type", 0xc005, sctpchunkparamtypes), + ShortField("len", 8), + XIntField("correlation_id", None), ] + class SCTPChunkParamAdaptationLayer(_SCTPChunkParam, Packet): - fields_desc = [ ShortEnumField("type", 49158, sctpchunkparamtypes), + fields_desc = [ ShortEnumField("type", 0xc006, sctpchunkparamtypes), ShortField("len", 8), XIntField("indication", None), ] @@ -433,6 +563,34 @@ class SCTPChunkShutdownComplete(_SCTPChunkGuessPayload, Packet): ShortField("len", 4), ] +class SCTPChunkAuthentication(_SCTPChunkGuessPayload, Packet): + fields_desc = [ ByteEnumField("type", 15, sctpchunktypes), + XByteField("flags", None), + FieldLenField("len", None, length_of="HMAC", + adjust = lambda pkt,x:x+8), + ShortField("shared_key_id", None), + ShortField("HMAC_function", None), + PadField(StrLenField("HMAC", "", length_from=lambda pkt: pkt.len-8), + 4, padwith="\x00"), + ] + +class SCTPChunkAddressConf(_SCTPChunkGuessPayload, Packet): + fields_desc = [ ByteEnumField("type", 0xc1, sctpchunktypes), + XByteField("flags", None), + FieldLenField("len", None, length_of="params", + adjust=lambda pkt,x:x+8), + IntField("seq", 0), + ChunkParamField("params", None, length_from=lambda pkt:pkt.len-8), + ] + +class SCTPChunkAddressConfAck(_SCTPChunkGuessPayload, Packet): + fields_desc = [ ByteEnumField("type",0x80, sctpchunktypes), + XByteField("flags", None), + FieldLenField("len", None, length_of="params", + adjust=lambda pkt,x:x+8), + IntField("seq", 0), + ChunkParamField("params", None, length_from=lambda pkt:pkt.len-8), + ] + bind_layers( IP, SCTP, proto=IPPROTO_SCTP) bind_layers( IPv6, SCTP, nh=IPPROTO_SCTP) - -- GitLab