Skip to content

Commit 5cf0c10

Browse files
committed
Fixing #4608
1 parent c424205 commit 5cf0c10

File tree

2 files changed

+50
-6
lines changed

2 files changed

+50
-6
lines changed

scapy/contrib/automotive/someip.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
# scapy.contrib.status = loads
99

1010
import struct
11+
from typing import Type
1112

1213
from scapy.layers.inet import TCP, UDP
1314
from scapy.layers.inet6 import IP6Field
@@ -19,7 +20,8 @@
1920
ShortField, X3BytesField, StrLenField, IPField,
2021
FieldLenField, PacketListField, XIntField,
2122
MultipleTypeField, FlagsField, IntField,
22-
XByteEnumField, BitScalingField)
23+
XByteEnumField, BitScalingField, LenField)
24+
from scapy.utils import hexdump
2325

2426

2527
class SOMEIP(Packet):
@@ -73,7 +75,7 @@ class SOMEIP(Packet):
7375
],
7476
XShortField("sub_id", 0),
7577
),
76-
IntField("len", None),
78+
LenField("len", None, fmt=">I", adjust=lambda x: x+8),
7779
XShortField("client_id", 0),
7880
XShortField("session_id", 0),
7981
XByteField("proto_ver", PROTOCOL_VERSION),
@@ -117,12 +119,10 @@ class SOMEIP(Packet):
117119
ConditionalField(
118120
BitField("more_seg", 0, 1),
119121
lambda pkt: SOMEIP._is_tp(pkt)), # noqa: E501
120-
ConditionalField(PacketListField(
122+
PacketListField(
121123
"data", [Raw()], Raw,
122124
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
123-
next_cls_cb=lambda pkt, lst, cur, remain:
124-
SOMEIP.get_payload_cls_by_srv_id(pkt, lst, cur, remain)),
125-
lambda pkt: SOMEIP._is_tp(pkt)) # noqa: E501
125+
next_cls_cb=lambda pkt, lst, cur, remain: SOMEIP.get_payload_cls_by_srv_id(pkt, lst, cur, remain)) # noqa: E501
126126
]
127127

128128
payload_cls_by_srv_id = dict() # To be customized
@@ -131,6 +131,10 @@ class SOMEIP(Packet):
131131
def get_payload_cls_by_srv_id(pkt, lst, cur, remain):
132132
return SOMEIP.payload_cls_by_srv_id.get(pkt.srv_id, Raw)
133133

134+
def default_payload_class(self, payload):
135+
# type: (bytes) -> Type[Packet]
136+
return SOMEIP
137+
134138
def post_build(self, pkt, pay):
135139
length = self.len
136140
if length is None:

test/contrib/automotive/someip.uts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,3 +727,43 @@ _opts_check(opts + opts[::-1])
727727
p = SOMEIP(srv_id=1234, sub_id=4321, msg_type=0xff, retcode=0xff, offset=4294967040, data=[Raw(b"deadbeef")])
728728

729729
assert p.data[0].load == b"deadbeef"
730+
731+
= SOMEIP multiple frames in one TCP/UDP
732+
733+
payload_3 = bytes.fromhex("deadbeef")
734+
someip_3 = SOMEIP(srv_id=0xabcd, sub_id=0x8001, len=8 + len(payload_3))
735+
someip_3.payload = Raw(load=payload_3)
736+
737+
payload_2 = bytes.fromhex("ff")
738+
someip_23 = SOMEIP(srv_id=0x5678, sub_id=0x8002, len=8 + len(payload_2))
739+
someip_23.payload = Raw(load=payload_2 + bytes(someip_3))
740+
741+
payload_1 = bytes.fromhex("0000")
742+
someip_123 = SOMEIP(srv_id=0x1234, sub_id=0x8001, len=8 + len(payload_1))
743+
someip_123.payload = Raw(load=payload_1 + bytes(someip_23))
744+
745+
eth_frame = (
746+
Ether(src="00:11:22:33:44:55", dst="AA:BB:CC:DD:EE:FF")
747+
/ IP(src="192.168.0.10", dst="192.168.0.20")
748+
/ UDP(sport=30501, dport=30491)
749+
/ someip_123
750+
)
751+
752+
pkt = Ether(bytes(eth_frame))
753+
754+
755+
pkt.show()
756+
layers = pkt.layers()
757+
assert len(layers) == 6
758+
assert layers[-1] == SOMEIP
759+
assert layers[-2] == SOMEIP
760+
assert layers[-3] == SOMEIP
761+
762+
763+
someip_123_x = pkt[SOMEIP]
764+
765+
assert someip_123_x.data[0].load == payload_1
766+
someip_23_x = someip_123_x.payload
767+
assert someip_23_x.data[0].load == payload_2
768+
someip_3_x = someip_23_x.payload
769+
assert someip_3_x.data[0].load == payload_3

0 commit comments

Comments
 (0)