Skip to content

Commit

Permalink
Fix #4651: Improve SOMEIP.fragment()
Browse files Browse the repository at this point in the history
  • Loading branch information
polybassa committed Feb 5, 2025
1 parent 3e00f42 commit c3dcc43
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 7 deletions.
28 changes: 22 additions & 6 deletions scapy/contrib/automotive/someip.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
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, NoPayload)
from scapy.fields import (XShortField, ConditionalField,
BitField, XBitField, XByteField, ByteEnumField,
ShortField, X3BytesField, StrLenField, IPField,
Expand Down Expand Up @@ -178,21 +179,35 @@ def fragment(self, fragsize=1392):
fnb += 1
fl = fl.underlayer

has_payload = len(self.data) == 0 or sum(len(p) for p in self.data) == 0

for p in fl:
s = raw(p[fnb].payload)
if has_payload:
s = raw(p[fnb].payload)
else:
s = raw(p[fnb].data[0])
nb = (len(s) + fragsize) // fragsize
for i in range(nb):
q = p.copy()
del q[fnb].payload
if has_payload:
del q[fnb].payload
else:
del q[fnb].data[0]
q[fnb].len = SOMEIP.LEN_OFFSET_TP + \
len(s[i * fragsize:(i + 1) * fragsize])
q[fnb].more_seg = 1
if i == nb - 1:
q[fnb].more_seg = 0
q[fnb].offset += i * fragsize // 16
q[fnb].offset += i * fragsize
r = conf.raw_layer(load=s[i * fragsize:(i + 1) * fragsize])
r.overload_fields = p[fnb].payload.overload_fields.copy()
q.add_payload(r)
if has_payload:
r.overload_fields = p[fnb].payload.overload_fields.copy()
else:
r.overload_fields = p[fnb].data[0].overload_fields.copy()
if has_payload:
q.add_payload(r)
else:
q.data.append(r)
lst.append(q)

return lst
Expand All @@ -209,6 +224,7 @@ def _bind_someip_layers():


_bind_someip_layers()
bind_layers(SOMEIP, SOMEIP)


class _SDPacketBase(Packet):
Expand Down
30 changes: 29 additions & 1 deletion test/contrib/automotive/someip.uts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pstr = bytes(p)
binstr = b"\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x01\x01\x00\x00"
assert pstr == binstr

= Build TP fragmented
= Build TP fragmented payload
p = SOMEIP()
p.msg_type = 0x20
p.add_payload(Raw("A"*1400))
Expand All @@ -127,6 +127,20 @@ assert f[1].payload == Raw("A"*8)
assert f[0].more_seg == 1
assert f[1].more_seg == 0

= Build TP fragmented data
p = SOMEIP()
p.msg_type = 0x20
p.data = [Raw("A"*1400)]

f = p.fragment()

assert f[0].len == 1404
assert f[1].len == 20
assert f[0].data[0] == Raw("A"*1392)
assert f[1].data[0] == Raw("A"*8)
assert f[0].more_seg == 1
assert f[1].more_seg == 0

+ SD Entry Service

= Check packet length on empty build
Expand Down Expand Up @@ -727,3 +741,17 @@ _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"

= test fragment

msg = bytes.fromhex("aabbccdd0003aabbccdd20608100a5dc0800450005a050ad400040117ee9c0a87262c0a872037725e107058c6b54402f801e0000057c0000000e0101220000000001123456789abcdef0fedcba9876543210123456789abcdef0fedcba9876543210123456789abcdef0fedcba9876543210123456789abcdef0fedcba9876543210123456789abcdef0fedcba9876543210123456789abcdef0fedcba9876543210123456789abcdef0fedcba9876543210123456789abcdef0fedcba9876543210123456789abcdef0fedcba9876543210123456789abcdef0fedcba9876543210123456789abcdef0fedcba9876543210123456789abcdef0fedcba9876543210123456789abcdef0fedcba9876543210123456789abcdef0fedcba9876543210123456789abcdef0fedcba9876543210fedcba9876543210a1b2c3d4e5f678901234567890abcdef0f1e2d3c4b5a697889abcdef01234567f0e1d2c3b4a59687111122223333444455556666777788889999aaaabbbbccccdeadbeafbaddcafecafebabedeafbeef1122334455667788a1b2c3d4e5f6f7f823456789abcdef0199887766554433221a2b3c4d5e6f7a8beaf1234567890deffedcba987654321001f23e45d6789abce1f2d3c4b5a6d7e8c9a1b2f3e4d5a6b7d8e1f0a2b3c4d5e623a1b2c3d4e5f678f23456789abcdef09876543210abcdefabcdef012345678987654321f0e1d2c312f34d56a78b9c019a8b7c6d5e4f3a2b56789abcdef0123423456789abcdef01a1b2c3d4e5f678909876543210abcdefabcdef0123456789f23456789abcdef099887766554433221a2b3c4d5e6f7a8bf0e1d2c3b4a59687abcdef9876543210234567890abcdef19999aaaabbbbccccdeadbeafbaddcafecafebabedeafbeef111122223333444455556666777788889999aaaabbbbccccdeadbeafbaddcafecafebabedeafbeef1122334455667788a1b2c3d4e5f6f7f823456789abcdef0199887766554433221a2b3c4d5e6f7a8beaf1234567890deffedcba987654321001f23e45d6789abce1f2d3c4b5a6d7e8c9a1b2f3e4d5a6b7d8e1f0a2b3c4d5e623a1b2c3d4e5f678f23456789abcdef09876543210abcdefabcdef012345678987654321f0e1d2c312f34d56a78b9c019a8b7c6d5e4f3a2b56789abcdef0123423456789abcdef01a1b2c3d4e5f678909876543210abcdefabcdef0123456789f23456789abcdef099887766554433221a2b3c4d5e6f7a8bf0e1d2c3b4a59687abcdef9876543210234567890abcdef19999aaaabbbbccccdeadbeafbaddcafecafebabedeafbeef111122223333444455556666777788889999aaaabbbbccccdeadbeafbaddcafecafebabedeafbeef1122334455667788a1b2c3d4e5f6f7f823456789abcdef0199887766554433221a2b3c4d5e6f7a8beaf1234567890deffedcba987654321001f23e45d6789abce1f2d3c4b5a6d7e8c9a1b2f3e4d5a6b7d8e1f0a2b3c4d5e623a1b2c3d4e5f678f23456789abcdef09876543210abcdefabcdef0123456789123456789abcdef01a2b3c4d5e6f70819a8b7c6d5e4f3a21d1c2b3a4f5e60798a9b8c7d6e5f4f3d2123456789abcdef01f2e3d4c5b6a7980a4b3c2d1e0f1f8a9456789abcdef0123f1e2d3c4b5a60789d6c5b4a3f2e1f0a91e2d3c4b5a6078f09c8b7a6d5e4f3b212b1a3c4d5e6f7081a7b8c9d6e5f4f0d2f5e4d3c2b1a0798a8123456789abcdef1f2e3d4c5b6a7981a3b2c1d0f1e607929081726354abcdef0f1e2d3c4b5a60788b7a6c5d4e3f2109d4c3b2a1f0e6078a4f5e6d7c8b9a1234e9d8c7b6a5f4e308a1b2c3d4e5f678909c8b7a6d5e4f32103b2a1c0d5e6f7098a0b1c2d3e4f5e6176d5e4f3c2b1a7890d7c8b9a0f1e2f390f1e2d3c4b5a607899b8a7c6d5e4f3211d3c2b1a0f1e6078b8f9e6d7c5b4a3210b2c1a3d4e5f6f8090e1d2c3b4a5f6789c9b8a7d6e5f4e3087d6c5b4a3f2e10989a8b7c6d5e4f32106e5d4c3b2a1f70980a9b8c7d6e5f4d023e1f2d4c5b6a70988f9e7d6c5b4a3102")
pkt = Ether(msg)[SOMEIP]

x = pkt.fragment(fragsize=100)
for i, p in enumerate(x):
if i == len(x) -1:
assert p.more_seg == 0
assert len(p.data[0]) < 100
else:
assert p.more_seg == 1
assert len(p.data[0]) == 100

0 comments on commit c3dcc43

Please sign in to comment.