diff --git a/scapy/contrib/automotive/someip.py b/scapy/contrib/automotive/someip.py index 09e9c891dc5..a10cd24dc72 100644 --- a/scapy/contrib/automotive/someip.py +++ b/scapy/contrib/automotive/someip.py @@ -13,13 +13,13 @@ from scapy.layers.inet6 import IP6Field from scapy.compat import raw, orb from scapy.config import conf -from scapy.packet import Packet, Raw, bind_top_down, bind_bottom_up +from scapy.packet import Packet, Raw, bind_top_down, bind_bottom_up, bind_layers from scapy.fields import (XShortField, ConditionalField, BitField, XBitField, XByteField, ByteEnumField, ShortField, X3BytesField, StrLenField, IPField, FieldLenField, PacketListField, XIntField, - MultipleTypeField, FlagsField, IntField, - XByteEnumField, BitScalingField) + MultipleTypeField, FlagsField, + XByteEnumField, BitScalingField, LenField) class SOMEIP(Packet): @@ -73,7 +73,7 @@ class SOMEIP(Packet): ], XShortField("sub_id", 0), ), - IntField("len", None), + LenField("len", None, fmt=">I", adjust=lambda x: x + 8), XShortField("client_id", 0), XShortField("session_id", 0), XByteField("proto_ver", PROTOCOL_VERSION), @@ -117,12 +117,10 @@ class SOMEIP(Packet): ConditionalField( BitField("more_seg", 0, 1), lambda pkt: SOMEIP._is_tp(pkt)), # noqa: E501 - ConditionalField(PacketListField( + PacketListField( "data", [Raw()], Raw, length_from=lambda pkt: pkt.len - (SOMEIP.LEN_OFFSET_TP if (SOMEIP._is_tp(pkt) and (pkt.len is None or pkt.len >= SOMEIP.LEN_OFFSET_TP)) else SOMEIP.LEN_OFFSET), # noqa: E501 - next_cls_cb=lambda pkt, lst, cur, remain: - SOMEIP.get_payload_cls_by_srv_id(pkt, lst, cur, remain)), - lambda pkt: SOMEIP._is_tp(pkt)) # noqa: E501 + next_cls_cb=lambda pkt, lst, cur, remain: SOMEIP.get_payload_cls_by_srv_id(pkt, lst, cur, remain)) # noqa: E501 ] payload_cls_by_srv_id = dict() # To be customized @@ -209,6 +207,7 @@ def _bind_someip_layers(): _bind_someip_layers() +bind_layers(SOMEIP, SOMEIP) class _SDPacketBase(Packet): diff --git a/test/contrib/automotive/someip.uts b/test/contrib/automotive/someip.uts index f3e33283547..5508b3ec6ae 100644 --- a/test/contrib/automotive/someip.uts +++ b/test/contrib/automotive/someip.uts @@ -727,3 +727,43 @@ _opts_check(opts + opts[::-1]) p = SOMEIP(srv_id=1234, sub_id=4321, msg_type=0xff, retcode=0xff, offset=4294967040, data=[Raw(b"deadbeef")]) assert p.data[0].load == b"deadbeef" + += SOMEIP multiple frames in one TCP/UDP + +payload_3 = bytes.fromhex("deadbeef") +someip_3 = SOMEIP(srv_id=0xabcd, sub_id=0x8001, len=8 + len(payload_3)) +someip_3.payload = Raw(load=payload_3) + +payload_2 = bytes.fromhex("ff") +someip_23 = SOMEIP(srv_id=0x5678, sub_id=0x8002, len=8 + len(payload_2)) +someip_23.payload = Raw(load=payload_2 + bytes(someip_3)) + +payload_1 = bytes.fromhex("0000") +someip_123 = SOMEIP(srv_id=0x1234, sub_id=0x8001, len=8 + len(payload_1)) +someip_123.payload = Raw(load=payload_1 + bytes(someip_23)) + +eth_frame = ( + Ether(src="00:11:22:33:44:55", dst="AA:BB:CC:DD:EE:FF") + / IP(src="192.168.0.10", dst="192.168.0.20") + / UDP(sport=30501, dport=30491) + / someip_123 +) + +pkt = Ether(bytes(eth_frame)) + + +pkt.show() +layers = pkt.layers() +assert len(layers) == 6 +assert layers[-1] == SOMEIP +assert layers[-2] == SOMEIP +assert layers[-3] == SOMEIP + + +someip_123_x = pkt[SOMEIP] + +assert someip_123_x.data[0].load == payload_1 +someip_23_x = someip_123_x.payload +assert someip_23_x.data[0].load == payload_2 +someip_3_x = someip_23_x.payload +assert someip_3_x.data[0].load == payload_3