From 7c4065938478d81fa235ec6bdae4d60e3726023c Mon Sep 17 00:00:00 2001 From: Nils Weiss Date: Wed, 5 Feb 2025 08:45:50 +0100 Subject: [PATCH 1/4] Fix #4651: Improve SOMEIP.fragment() --- scapy/contrib/automotive/someip.py | 27 ++++++++++++++++++++------ test/contrib/automotive/someip.uts | 31 +++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/scapy/contrib/automotive/someip.py b/scapy/contrib/automotive/someip.py index a10cd24dc72..87f2fc31ca9 100644 --- a/scapy/contrib/automotive/someip.py +++ b/scapy/contrib/automotive/someip.py @@ -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, bind_layers +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, @@ -176,21 +177,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 diff --git a/test/contrib/automotive/someip.uts b/test/contrib/automotive/someip.uts index 5508b3ec6ae..ec1a38f780d 100644 --- a/test/contrib/automotive/someip.uts +++ b/test/contrib/automotive/someip.uts @@ -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)) @@ -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 @@ -728,6 +742,20 @@ p = SOMEIP(srv_id=1234, sub_id=4321, msg_type=0xff, retcode=0xff, offset=4294967 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 + = SOMEIP multiple frames in one TCP/UDP payload_3 = bytes.fromhex("deadbeef") @@ -767,3 +795,4 @@ 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 + From 775d58e863c811379e3d64fe3cf9ff14ea98343b Mon Sep 17 00:00:00 2001 From: Nils Weiss Date: Wed, 5 Feb 2025 08:48:44 +0100 Subject: [PATCH 2/4] fix flake --- scapy/contrib/automotive/someip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scapy/contrib/automotive/someip.py b/scapy/contrib/automotive/someip.py index 87f2fc31ca9..40d43a09fd4 100644 --- a/scapy/contrib/automotive/someip.py +++ b/scapy/contrib/automotive/someip.py @@ -14,7 +14,7 @@ from scapy.compat import raw, orb from scapy.config import conf from scapy.packet import (Packet, Raw, bind_top_down, bind_bottom_up, - bind_layers, NoPayload) + bind_layers) from scapy.fields import (XShortField, ConditionalField, BitField, XBitField, XByteField, ByteEnumField, ShortField, X3BytesField, StrLenField, IPField, From 36143e26080cdf7b328470d1f2a1ae2e79b0bf71 Mon Sep 17 00:00:00 2001 From: Nils Weiss Date: Tue, 25 Feb 2025 09:16:56 +0100 Subject: [PATCH 3/4] Update scapy/contrib/automotive/someip.py Co-authored-by: gpotter2 <10530980+gpotter2@users.noreply.github.com> --- scapy/contrib/automotive/someip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scapy/contrib/automotive/someip.py b/scapy/contrib/automotive/someip.py index 40d43a09fd4..48fff6c1662 100644 --- a/scapy/contrib/automotive/someip.py +++ b/scapy/contrib/automotive/someip.py @@ -177,7 +177,7 @@ 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 + has_payload = not any(self.data) for p in fl: if has_payload: From 8f0978d8958da175d8f9f2bbee63b96bd889ab05 Mon Sep 17 00:00:00 2001 From: Nils Weiss Date: Tue, 25 Feb 2025 09:37:27 +0100 Subject: [PATCH 4/4] Update someip.py Revert suggested change --- scapy/contrib/automotive/someip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scapy/contrib/automotive/someip.py b/scapy/contrib/automotive/someip.py index 48fff6c1662..40d43a09fd4 100644 --- a/scapy/contrib/automotive/someip.py +++ b/scapy/contrib/automotive/someip.py @@ -177,7 +177,7 @@ def fragment(self, fragsize=1392): fnb += 1 fl = fl.underlayer - has_payload = not any(self.data) + has_payload = len(self.data) == 0 or sum(len(p) for p in self.data) == 0 for p in fl: if has_payload: