secdev / scapy

Scapy: the Python-based interactive packet manipulation program & library.
https://scapy.net
GNU General Public License v2.0
10.74k stars 2.03k forks source link

SOME/IP-SD Entry-Array is broken by building it from RAW #2348

Closed ddisaster closed 4 years ago

ddisaster commented 4 years ago

Environment

How to reproduce

from scapy.all import *
load_contrib("automotive.someip_sd")

ea1 = SDEntry_Service()
ea1.type = 1
ea1.srv_id = 0x1234
ea1.inst_id = 0x5678
ea1.ttl = 3

ea2 = SDEntry_Service()
ea2.type = 0
ea2.srv_id = 0x8765
ea2.inst_id = 0x4321
ea2.ttl = 2

sd1 = SD()
sd1.set_entryArray([ea1])

sd2 = SD()
sd2.set_entryArray([ea2,ea1])

print("Expected:")
sd1.show()

print("From RAW:")
SD(sd1.build()).show()

print("_SDEntry type gets the type of the first Entry. All entrys get type 0")
print("---------------------------------------------------------------------")
print("Expected:")
sd2.show()
print("From RAW:")
SD(sd2.build()).show()

print("Other order of Entrys:")
print("Expected:")
sd2.set_entryArray([ea1,ea2])
sd2.show()
print("From RAW:")
SD(sd2.build()).show()

Result

Expected:
###[ SD ]### 
  flags     = 0
  res       = 0x0
  len_entry_array= None
  \entry_array\
   |###[ Service Entry ]### 
   |  type      = 1
   |  index_1   = 0
   |  index_2   = 0
   |  n_opt_1   = 0
   |  n_opt_2   = 0
   |  srv_id    = 4660
   |  inst_id   = 22136
   |  major_ver = 0
   |  ttl       = 0x3
   |  minor_ver = 0
  len_option_array= None
  \option_array\

From RAW:
###[ SD ]### 
  flags     = 0
  res       = 0x0
  len_entry_array= 16
  \entry_array\
   |###[ _SDEntry ]### 
   |  type      = 1
   |  index_1   = 0
   |  index_2   = 0
   |  n_opt_1   = 0
   |  n_opt_2   = 0
   |  srv_id    = 4660
   |  inst_id   = 22136
   |  major_ver = 0
   |  ttl       = 0x3
   |###[ Service Entry ]### 
   |     type      = 0
   |     index_1   = 0
   |     index_2   = 0
   |     n_opt_1   = 0
   |     n_opt_2   = 0
   |     srv_id    = 0
   |     inst_id   = 0
   |     major_ver = 0
   |     ttl       = 0x0
   |     minor_ver = 0
  len_option_array= 0
  \option_array\

_SDEntry type gets the type of the first Entry. All entrys get type 0
---------------------------------------------------------------------
Expected:
###[ SD ]### 
  flags     = 0
  res       = 0x0
  len_entry_array= None
  \entry_array\
   |###[ Service Entry ]### 
   |  type      = 0
   |  index_1   = 0
   |  index_2   = 0
   |  n_opt_1   = 0
   |  n_opt_2   = 0
   |  srv_id    = 34661
   |  inst_id   = 17185
   |  major_ver = 0
   |  ttl       = 0x2
   |  minor_ver = 0
   |###[ Service Entry ]### 
   |  type      = 1
   |  index_1   = 0
   |  index_2   = 0
   |  n_opt_1   = 0
   |  n_opt_2   = 0
   |  srv_id    = 4660
   |  inst_id   = 22136
   |  major_ver = 0
   |  ttl       = 0x3
   |  minor_ver = 0
  len_option_array= None
  \option_array\

From RAW:
###[ SD ]### 
  flags     = 0
  res       = 0x0
  len_entry_array= 32
  \entry_array\
   |###[ _SDEntry ]### 
   |  type      = 0
   |  index_1   = 0
   |  index_2   = 0
   |  n_opt_1   = 0
   |  n_opt_2   = 0
   |  srv_id    = 34661
   |  inst_id   = 17185
   |  major_ver = 0
   |  ttl       = 0x2
   |###[ Service Entry ]### 
   |     type      = 0
   |     index_1   = 0
   |     index_2   = 0
   |     n_opt_1   = 0
   |     n_opt_2   = 0
   |     srv_id    = 256
   |     inst_id   = 0
   |     major_ver = 18
   |     ttl       = 0x345678
   |     minor_ver = 3
   |###[ Service Entry ]### 
   |        type      = 0
   |        index_1   = 0
   |        index_2   = 0
   |        n_opt_1   = 0
   |        n_opt_2   = 0
   |        srv_id    = 0
   |        inst_id   = 0
   |        major_ver = 0
   |        ttl       = 0x0
   |        minor_ver = 0
  len_option_array= 0
  \option_array\

Other order of Entrys:
Expected:
###[ SD ]### 
  flags     = 0
  res       = 0x0
  len_entry_array= None
  \entry_array\
   |###[ Service Entry ]### 
   |  type      = 1
   |  index_1   = 0
   |  index_2   = 0
   |  n_opt_1   = 0
   |  n_opt_2   = 0
   |  srv_id    = 4660
   |  inst_id   = 22136
   |  major_ver = 0
   |  ttl       = 0x3
   |  minor_ver = 0
   |###[ Service Entry ]### 
   |  type      = 0
   |  index_1   = 0
   |  index_2   = 0
   |  n_opt_1   = 0
   |  n_opt_2   = 0
   |  srv_id    = 34661
   |  inst_id   = 17185
   |  major_ver = 0
   |  ttl       = 0x2
   |  minor_ver = 0
  len_option_array= None
  \option_array\

From RAW:
###[ SD ]### 
  flags     = 0
  res       = 0x0
  len_entry_array= 32
  \entry_array\
   |###[ _SDEntry ]### 
   |  type      = 1
   |  index_1   = 0
   |  index_2   = 0
   |  n_opt_1   = 0
   |  n_opt_2   = 0
   |  srv_id    = 4660
   |  inst_id   = 22136
   |  major_ver = 0
   |  ttl       = 0x3
   |###[ Service Entry ]### 
   |     type      = 0
   |     index_1   = 0
   |     index_2   = 0
   |     n_opt_1   = 0
   |     n_opt_2   = 0
   |     srv_id    = 0
   |     inst_id   = 0
   |     major_ver = 135
   |     ttl       = 0x654321
   |     minor_ver = 2
   |###[ Service Entry ]### 
   |        type      = 0
   |        index_1   = 0
   |        index_2   = 0
   |        n_opt_1   = 0
   |        n_opt_2   = 0
   |        srv_id    = 0
   |        inst_id   = 0
   |        major_ver = 0
   |        ttl       = 0x0
   |        minor_ver = 0
  len_option_array= 0
  \option_array\

Description

The first two outputs show the _SDEntry layer is added to the package. The others show that the type of each entry is always set to 0, while _SDEntry takes the type of the first entry.

Related resources

AUTOSAR_PRS_SOMEIPServiceDiscoveryProtocol.pdf - 4.1.2.3 Entry Format

@baarse @polybassa

polybassa commented 4 years ago

Thanks for this issue. We will look into it. Do you have a PR to fix this?

ddisaster commented 4 years ago

Not yet. Works for me for now by using this patch. But EventGroups no longer Works.

diff -u someip_sd_orig.py someip_sd.py 
--- someip_sd_orig.py   2019-11-27 18:54:34.541247352 +0100
+++ someip_sd.py    2019-11-27 18:54:42.565233818 +0100
@@ -300,7 +300,7 @@
         X3BytesField("res", 0),
         FieldLenField("len_entry_array", None,
                       length_of="entry_array", fmt="!I"),
-        PacketListField("entry_array", None, cls=_SDEntry,
+        PacketListField("entry_array", None, cls=SDEntry_Service,
                         length_from=lambda pkt: pkt.len_entry_array),
         FieldLenField("len_option_array", None,
                       length_of="option_array", fmt="!I"),