2019-09-10 18:24:32 +00:00
/* packet-someip.c
* SOME / IP dissector .
2020-04-10 15:28:05 +00:00
* By Dr . Lars Voelker < lars . voelker @ technica - engineering . de > / < lars . voelker @ bmw . de >
* Copyright 2012 - 2020 Dr . Lars Voelker
2019-09-10 18:24:32 +00:00
* Copyright 2019 Ana Pantar
* Copyright 2019 Guenter Ebermann
*
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
* Copyright 1998 Gerald Combs
*
* SPDX - License - Identifier : GPL - 2.0 - or - later
*/
# include <config.h>
2020-04-22 13:36:25 +00:00
# include <epan/packet.h>
2019-09-10 18:24:32 +00:00
# include <epan/prefs.h>
# include <epan/expert.h>
# include <epan/to_str.h>
# include <epan/uat.h>
# include <epan/dissectors/packet-tcp.h>
# include <epan/reassemble.h>
# include "packet-udp.h"
# include "packet-someip.h"
/*
* Dissector for SOME / IP , SOME / IP - TP , and SOME / IP Payloads .
*
* See
* http : //www.some-ip.com
*/
# define SOMEIP_NAME "SOME / IP"
# define SOMEIP_NAME_LONG "SOME / IP Protocol"
# define SOMEIP_NAME_FILTER "someip"
# define SOMEIP_NAME_LONG_MULTIPLE "SOME / IP Protocol (Multiple Payloads)"
# define SOMEIP_NAME_LONG_BROKEN "SOME / IP: Incomplete headers!"
# define SOMEIP_NAME_LONG_TOO_SHORT "SOME / IP: Incomplete SOME / IP payload!"
/*** Configuration ***/
# define DATAFILE_SOMEIP_SERVICES "SOMEIP_service_identifiers"
# define DATAFILE_SOMEIP_METHODS "SOMEIP_method_event_identifiers"
# define DATAFILE_SOMEIP_EVENTGROUPS "SOMEIP_eventgroup_identifiers"
# define DATAFILE_SOMEIP_PARAMETERS "SOMEIP_parameter_list"
# define DATAFILE_SOMEIP_BASE_TYPES "SOMEIP_parameter_base_types"
# define DATAFILE_SOMEIP_ARRAYS "SOMEIP_parameter_arrays"
# define DATAFILE_SOMEIP_STRINGS "SOMEIP_parameter_strings"
# define DATAFILE_SOMEIP_TYPEDEFS "SOMEIP_parameter_typedefs"
# define DATAFILE_SOMEIP_STRUCTS "SOMEIP_parameter_structs"
# define DATAFILE_SOMEIP_UNIONS "SOMEIP_parameter_unions"
# define DATAFILE_SOMEIP_ENUMS "SOMEIP_parameter_enums"
# define SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_UNKNOWN 0
# define SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_BASE_TYPE 1
# define SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_STRING 2
# define SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ARRAY 3
# define SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_STRUCT 4
# define SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_UNION 5
# define SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_TYPEDEF 6
# define SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ENUM 7
/*** SOME/IP ***/
# define SOMEIP_HDR_LEN 16
# define SOMEIP_HDR_PART1_LEN 8
# define SOMEIP_HDR_PART2_LEN_INCL_TP 12
# define SOMEIP_TP_HDR_LEN 4
# define SOMEIP_PROTOCOL_VERSION 1
/* Message Types */
# define SOMEIP_MSGTYPE_REQUEST 0x00
# define SOMEIP_MSGTYPE_REQUEST_NO_RESPONSE 0x01
# define SOMEIP_MSGTYPE_NOTIFICATION 0x02
# define SOMEIP_MSGTYPE_RESPONSE 0x80
# define SOMEIP_MSGTYPE_ERROR 0x81
# define SOMEIP_MSGTYPE_ACK_MASK 0x40
# define SOMEIP_MSGTYPE_TP_MASK 0x20
# define SOMEIP_MSGTYPE_FLAGS_MASK 0x60
# define SOMEIP_MSGTYPE_NO_FLAGS_MASK 0x9f
# define SOMEIP_MSGTYPE_TP_STRING "SOME / IP-TP segment"
# define SOMEIP_MSGTYPE_ACK_STRING "ACK"
/* SOME/IP-TP */
# define SOMEIP_TP_OFFSET_MASK 0xfffffff0
# define SOMEIP_TP_OFFSET_MASK_FLAGS 0x0000000f
# define SOMEIP_TP_OFFSET_MASK_RESERVED 0x0000000e
# define SOMEIP_TP_OFFSET_MASK_MORE_SEGMENTS 0x00000001
/* Return Codes */
# define SOMEIP_RETCODE_OK 0x00
# define SOMEIP_RETCODE_NOT_OK 0x01
# define SOMEIP_RETCODE_UNKNOWN_SERVICE 0x02
# define SOMEIP_RETCODE_UNKNOWN_METHOD 0x03
# define SOMEIP_RETCODE_NOT_READY 0x04
# define SOMEIP_RETCODE_NOT_REACHABLE 0x05
# define SOMEIP_RETCODE_TIMEOUT 0x06
# define SOMEIP_RETCODE_WRONG_PROTO_VER 0x07
# define SOMEIP_RETCODE_WRONG_INTERFACE_VER 0x08
# define SOMEIP_RETCODE_MALFORMED_MSG 0x09
# define SOMEIP_RETCODE_WRONG_MESSAGE_TYPE 0x0a
/* ID wireshark identifies the dissector by */
static int proto_someip = - 1 ;
static dissector_handle_t someip_handle_udp = NULL ;
static dissector_handle_t someip_handle_tcp = NULL ;
/* header field */
static int hf_someip_messageid = - 1 ;
static int hf_someip_serviceid = - 1 ;
static int hf_someip_methodid = - 1 ;
static int hf_someip_length = - 1 ;
static int hf_someip_clientid = - 1 ;
static int hf_someip_sessionid = - 1 ;
static int hf_someip_protover = - 1 ;
static int hf_someip_interface_ver = - 1 ;
static int hf_someip_messagetype = - 1 ;
static int hf_someip_messagetype_ack_flag = - 1 ;
static int hf_someip_messagetype_tp_flag = - 1 ;
static int hf_someip_returncode = - 1 ;
static int hf_someip_tp = - 1 ;
static int hf_someip_tp_offset = - 1 ;
static int hf_someip_tp_flags = - 1 ;
static int hf_someip_tp_reserved = - 1 ;
static int hf_someip_tp_more_segments = - 1 ;
static int hf_someip_payload = - 1 ;
/* protocol tree items */
static gint ett_someip = - 1 ;
static gint ett_someip_msgtype = - 1 ;
static gint ett_someip_tp = - 1 ;
static gint ett_someip_tp_flags = - 1 ;
/* dissector handling */
static dissector_table_t someip_dissector_table = NULL ;
/* message reassembly for SOME/IP-TP */
static int hf_someip_tp_fragments = - 1 ;
static int hf_someip_tp_fragment = - 1 ;
static int hf_someip_tp_fragment_overlap = - 1 ;
static int hf_someip_tp_fragment_overlap_conflicts = - 1 ;
static int hf_someip_tp_fragment_multiple_tails = - 1 ;
static int hf_someip_tp_fragment_too_long_fragment = - 1 ;
static int hf_someip_tp_fragment_error = - 1 ;
static int hf_someip_tp_fragment_count = - 1 ;
static int hf_someip_tp_reassembled_in = - 1 ;
static int hf_someip_tp_reassembled_length = - 1 ;
static int hf_someip_tp_reassembled_data = - 1 ;
static int hf_payload_unparsed = - 1 ;
static int hf_payload_length_field_8bit = - 1 ;
static int hf_payload_length_field_16bit = - 1 ;
static int hf_payload_length_field_32bit = - 1 ;
static int hf_payload_type_field_8bit = - 1 ;
static int hf_payload_type_field_16bit = - 1 ;
static int hf_payload_type_field_32bit = - 1 ;
static int hf_payload_str_base = - 1 ;
static int hf_payload_str_string = - 1 ;
static int hf_payload_str_struct = - 1 ;
static gint ett_someip_tp_fragment = - 1 ;
static gint ett_someip_tp_fragments = - 1 ;
static gint ett_someip_payload = - 1 ;
static gint ett_someip_string = - 1 ;
static gint ett_someip_array = - 1 ;
static gint ett_someip_array_dim = - 1 ;
static gint ett_someip_struct = - 1 ;
static gint ett_someip_union = - 1 ;
static const fragment_items someip_tp_frag_items = {
& ett_someip_tp_fragment ,
& ett_someip_tp_fragments ,
& hf_someip_tp_fragments ,
& hf_someip_tp_fragment ,
& hf_someip_tp_fragment_overlap ,
& hf_someip_tp_fragment_overlap_conflicts ,
& hf_someip_tp_fragment_multiple_tails ,
& hf_someip_tp_fragment_too_long_fragment ,
& hf_someip_tp_fragment_error ,
& hf_someip_tp_fragment_count ,
& hf_someip_tp_reassembled_in ,
& hf_someip_tp_reassembled_length ,
& hf_someip_tp_reassembled_data ,
" SOME/IP-TP Segments "
} ;
static reassembly_table someip_tp_reassembly_table ;
static range_t * someip_ports_udp = NULL ;
static range_t * someip_ports_tcp = NULL ;
static gboolean someip_tp_reassemble = TRUE ;
static gboolean someip_derserializer_activated = FALSE ;
/* SOME/IP Message Types */
static const value_string someip_msg_type [ ] = {
{ SOMEIP_MSGTYPE_REQUEST , " Request " } ,
{ SOMEIP_MSGTYPE_REQUEST_NO_RESPONSE , " Request no response " } ,
{ SOMEIP_MSGTYPE_NOTIFICATION , " Notification " } ,
{ SOMEIP_MSGTYPE_RESPONSE , " Response " } ,
{ SOMEIP_MSGTYPE_ERROR , " Error " } ,
{ SOMEIP_MSGTYPE_REQUEST | SOMEIP_MSGTYPE_ACK_MASK , " Request Ack " } ,
{ SOMEIP_MSGTYPE_REQUEST_NO_RESPONSE | SOMEIP_MSGTYPE_ACK_MASK , " Request no response Ack " } ,
{ SOMEIP_MSGTYPE_NOTIFICATION | SOMEIP_MSGTYPE_ACK_MASK , " Notification Ack " } ,
{ SOMEIP_MSGTYPE_RESPONSE | SOMEIP_MSGTYPE_ACK_MASK , " Response Ack " } ,
{ SOMEIP_MSGTYPE_ERROR | SOMEIP_MSGTYPE_ACK_MASK , " Error Ack " } ,
{ 0 , NULL }
} ;
/* SOME/IP Return Code */
static const value_string someip_return_code [ ] = {
{ SOMEIP_RETCODE_OK , " Ok " } ,
{ SOMEIP_RETCODE_NOT_OK , " Not Ok " } ,
{ SOMEIP_RETCODE_UNKNOWN_SERVICE , " Unknown Service " } ,
{ SOMEIP_RETCODE_UNKNOWN_METHOD , " Unknown Method/Event " } ,
{ SOMEIP_RETCODE_NOT_READY , " Not Ready " } ,
{ SOMEIP_RETCODE_NOT_REACHABLE , " Not Reachable (internal) " } ,
{ SOMEIP_RETCODE_TIMEOUT , " Timeout (internal) " } ,
{ SOMEIP_RETCODE_WRONG_PROTO_VER , " Wrong Protocol Version " } ,
{ SOMEIP_RETCODE_WRONG_INTERFACE_VER , " Wrong Interface Version " } ,
{ SOMEIP_RETCODE_MALFORMED_MSG , " Malformed Message " } ,
{ SOMEIP_RETCODE_WRONG_MESSAGE_TYPE , " Wrong Message Type " } ,
{ 0 , NULL }
} ;
/*** expert info items ***/
static expert_field ef_someip_unknown_version = EI_INIT ;
static expert_field ef_someip_message_truncated = EI_INIT ;
static expert_field ef_someip_incomplete_headers = EI_INIT ;
static expert_field ef_someip_payload_truncated = EI_INIT ;
2020-04-10 15:28:05 +00:00
static expert_field ef_someip_payload_malformed = EI_INIT ;
2019-09-10 18:24:32 +00:00
static expert_field ef_someip_payload_config_error = EI_INIT ;
static expert_field ef_someip_payload_alignment_error = EI_INIT ;
static expert_field ef_someip_payload_static_array_min_not_max = EI_INIT ;
static expert_field ef_someip_payload_dyn_array_not_within_limit = EI_INIT ;
/*** Data Structure for mapping IDs to Names (Services, Methods, ...) ***/
static GHashTable * data_someip_services = NULL ;
static GHashTable * data_someip_methods = NULL ;
static GHashTable * data_someip_eventgroups = NULL ;
static GHashTable * data_someip_parameter_list = NULL ;
static GHashTable * data_someip_parameter_base_type_list = NULL ;
static GHashTable * data_someip_parameter_strings = NULL ;
static GHashTable * data_someip_parameter_typedefs = NULL ;
static GHashTable * data_someip_parameter_arrays = NULL ;
static GHashTable * data_someip_parameter_structs = NULL ;
static GHashTable * data_someip_parameter_unions = NULL ;
static GHashTable * data_someip_parameter_enums = NULL ;
/***********************************************
* * * * * * * * * Preferences / Configuration * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
typedef struct _someip_payload_parameter_item {
guint32 pos ;
gchar * name ;
guint32 data_type ;
guint32 id_ref ;
} someip_payload_parameter_item_t ;
# define INIT_SOMEIP_PAYLOAD_PARAMETER_ITEM(NAME) \
( NAME ) - > pos = 0 ; \
( NAME ) - > name = NULL ; \
( NAME ) - > data_type = 0 ; \
( NAME ) - > id_ref = 0 ;
typedef struct _someip_payload_parameter_base_type_list {
guint32 id ;
gchar * name ;
gchar * data_type ;
gboolean big_endian ;
guint32 bitlength_base_type ;
guint32 bitlength_encoded_type ;
} someip_payload_parameter_base_type_list_t ;
# define INIT_COMMON_BASE_TYPE_LIST_ITEM(NAME) \
( NAME ) - > id = 0 ; \
( NAME ) - > name = NULL ; \
( NAME ) - > data_type = NULL ; \
( NAME ) - > big_endian = TRUE ; \
( NAME ) - > bitlength_base_type = 0 ; \
( NAME ) - > bitlength_encoded_type = 0 ;
typedef struct _someip_payload_parameter_string {
guint32 id ;
gchar * name ;
gchar * encoding ;
gboolean dynamic_length ;
guint32 max_length ;
guint32 length_of_length ; /* default: 32 */
gboolean big_endian ;
guint32 pad_to ;
} someip_payload_parameter_string_t ;
# define INIT_SOMEIP_PAYLOAD_PARAMETER_STRING(NAME) \
( NAME ) - > id = 0 ; \
( NAME ) - > name = NULL ; \
( NAME ) - > encoding = NULL ; \
( NAME ) - > dynamic_length = FALSE ; \
( NAME ) - > max_length = 0 ; \
( NAME ) - > length_of_length = 0 ; \
( NAME ) - > big_endian = TRUE ; \
( NAME ) - > pad_to = 0 ;
typedef struct _someip_payload_parameter_typedef {
guint32 id ;
gchar * name ;
guint32 data_type ;
guint32 id_ref ;
} someip_payload_parameter_typedef_t ;
# define INIT_SOMEIP_PAYLOAD_PARAMETER_TYPEDEF(NAME) \
( NAME ) - > id = 0 ; \
( NAME ) - > name = NULL ; \
( NAME ) - > data_type = 0 ; \
( NAME ) - > id_ref = 0 ;
typedef struct _someip_payload_parameter_struct {
guint32 id ;
gchar * struct_name ;
guint32 length_of_length ; /* default: 0 */
guint32 pad_to ; /* default: 0 */
guint32 num_of_items ;
/* array of items */
someip_payload_parameter_item_t * items ;
} someip_payload_parameter_struct_t ;
# define INIT_SOMEIP_PAYLOAD_PARAMETER_STRUCT(NAME) \
( NAME ) - > id = 0 ; \
( NAME ) - > struct_name = NULL ; \
( NAME ) - > length_of_length = 0 ; \
( NAME ) - > pad_to = 0 ; \
( NAME ) - > num_of_items = 0 ;
typedef struct _someip_payload_parameter_enum_item {
guint64 value ;
gchar * name ;
} someip_payload_parameter_enum_item_t ;
# define INIT_SOMEIP_PAYLOAD_PARAMETER_ENUM_ITEM(NAME) \
( NAME ) - > value = 0 ; \
( NAME ) - > name = NULL ;
typedef struct _someip_payload_parameter_enum {
guint32 id ;
gchar * name ;
guint32 data_type ;
guint32 id_ref ;
guint32 num_of_items ;
someip_payload_parameter_enum_item_t * items ;
} someip_payload_parameter_enum_t ;
# define INIT_SOMEIP_PAYLOAD_PARAMETER_ENUM(NAME) \
( NAME ) - > id = 0 ; \
( NAME ) - > name = NULL ; \
( NAME ) - > data_type = 0 ; \
( NAME ) - > id_ref = 0 ; \
( NAME ) - > num_of_items = 0 ; \
( NAME ) - > items = NULL ;
typedef struct _someip_parameter_union_item {
guint32 id ;
gchar * name ;
guint32 data_type ;
guint32 id_ref ;
} someip_parameter_union_item_t ;
typedef struct _someip_parameter_union {
guint32 id ;
gchar * name ;
guint32 length_of_length ; /* default: 32 */
guint32 length_of_type ; /* default: 32 */
guint32 pad_to ; /* default: 0 */
guint32 num_of_items ;
someip_parameter_union_item_t * items ;
} someip_parameter_union_t ;
typedef struct _someip_parameter_union_uat {
guint32 id ;
gchar * name ;
guint32 length_of_length ;
guint32 length_of_type ;
guint32 pad_to ;
guint32 num_of_items ;
guint32 type_id ;
gchar * type_name ;
guint32 data_type ;
guint32 id_ref ;
} someip_parameter_union_uat_t ;
typedef struct _someip_parameter_enum_uat {
guint32 id ;
gchar * name ;
guint32 data_type ;
guint32 id_ref ;
guint32 num_of_items ;
guint32 value ;
gchar * value_name ;
} someip_parameter_enum_uat_t ;
typedef struct _someip_parameter_array_dim {
guint32 num ;
guint32 lower_limit ;
guint32 upper_limit ;
guint32 length_of_length ;
guint32 pad_to ;
} someip_parameter_array_dim_t ;
typedef struct _someip_parameter_array {
guint32 id ;
gchar * name ;
guint32 data_type ;
guint32 id_ref ;
guint32 num_of_dims ;
someip_parameter_array_dim_t * dims ;
} someip_parameter_array_t ;
typedef struct _someip_parameter_array_uat {
guint32 id ;
gchar * name ;
guint32 data_type ;
guint32 id_ref ;
guint32 num_of_dims ;
guint32 num ;
guint32 lower_limit ;
guint32 upper_limit ;
guint32 length_of_length ;
guint32 pad_to ;
} someip_parameter_array_uat_t ;
typedef struct _someip_parameter_list {
guint32 service_id ;
guint32 method_id ;
guint32 version ;
guint32 message_type ;
guint32 num_of_items ;
someip_payload_parameter_item_t * items ;
} someip_parameter_list_t ;
typedef struct _someip_parameter_list_uat {
guint32 service_id ;
guint32 method_id ;
guint32 version ;
guint32 message_type ;
guint32 num_of_params ;
guint32 pos ;
gchar * name ;
guint32 data_type ;
guint32 id_ref ;
} someip_parameter_list_uat_t ;
typedef struct _someip_parameter_struct_uat {
guint32 id ;
gchar * struct_name ;
guint32 length_of_length ; /* default: 0 */
guint32 pad_to ; /* default: 0 */
guint32 num_of_items ;
guint32 pos ;
gchar * name ;
guint32 data_type ;
guint32 id_ref ;
} someip_parameter_struct_uat_t ;
typedef someip_payload_parameter_base_type_list_t someip_parameter_base_type_list_uat_t ;
typedef someip_payload_parameter_string_t someip_parameter_string_uat_t ;
typedef someip_payload_parameter_typedef_t someip_parameter_typedef_uat_t ;
typedef struct _generic_one_id_string {
guint id ;
gchar * name ;
} generic_one_id_string_t ;
typedef struct _generic_two_id_string {
guint id ;
guint id2 ;
gchar * name ;
} generic_two_id_string_t ;
static generic_one_id_string_t * someip_service_ident = NULL ;
static guint someip_service_ident_num = 0 ;
static generic_two_id_string_t * someip_method_ident = NULL ;
static guint someip_method_ident_num = 0 ;
static generic_two_id_string_t * someip_eventgroup_ident = NULL ;
static guint someip_eventgroup_ident_num = 0 ;
static someip_parameter_list_uat_t * someip_parameter_list = NULL ;
static guint someip_parameter_list_num = 0 ;
static someip_parameter_string_uat_t * someip_parameter_strings = NULL ;
static guint someip_parameter_strings_num = 0 ;
static someip_parameter_typedef_uat_t * someip_parameter_typedefs = NULL ;
static guint someip_parameter_typedefs_num = 0 ;
static someip_parameter_array_uat_t * someip_parameter_arrays = NULL ;
static guint someip_parameter_arrays_num = 0 ;
static someip_parameter_struct_uat_t * someip_parameter_structs = NULL ;
static guint someip_parameter_structs_num = 0 ;
static someip_parameter_union_uat_t * someip_parameter_unions = NULL ;
static guint someip_parameter_unions_num = 0 ;
static someip_parameter_enum_uat_t * someip_parameter_enums = NULL ;
static guint someip_parameter_enums_num = 0 ;
static someip_parameter_base_type_list_uat_t * someip_parameter_base_type_list = NULL ;
static guint someip_parameter_base_type_list_num = 0 ;
void proto_register_someip ( void ) ;
void proto_reg_handoff_someip ( void ) ;
/* register a UDP SOME/IP port */
void
register_someip_port_udp ( guint32 portnumber ) {
dissector_add_uint ( " udp.port " , portnumber , someip_handle_udp ) ;
}
/* register a TCP SOME/IP port */
void
register_someip_port_tcp ( guint32 portnumber ) {
dissector_add_uint ( " tcp.port " , portnumber , someip_handle_tcp ) ;
}
/*** UAT Callbacks and Helpers ***/
static void
someip_free_key ( gpointer key ) {
wmem_free ( wmem_epan_scope ( ) , key ) ;
}
static void
simple_free ( gpointer data _U_ ) {
/* we need to free because of the g_strdup in post_update*/
g_free ( data ) ;
}
/* ID -> Name */
static void *
copy_generic_one_id_string_cb ( void * n , const void * o , size_t size _U_ ) {
generic_one_id_string_t * new_rec = ( generic_one_id_string_t * ) n ;
const generic_one_id_string_t * old_rec = ( const generic_one_id_string_t * ) o ;
new_rec - > name = g_strdup ( old_rec - > name ) ;
new_rec - > id = old_rec - > id ;
return new_rec ;
}
static gboolean
update_generic_one_identifier_16bit ( void * r , char * * err ) {
generic_one_id_string_t * rec = ( generic_one_id_string_t * ) r ;
if ( rec - > id > 0xffff ) {
* err = g_strdup_printf ( " We currently only support 16 bit identifiers (ID: %i Name: %s) " , rec - > id , rec - > name ) ;
return FALSE ;
}
if ( rec - > name = = NULL | | rec - > name [ 0 ] = = 0 ) {
* err = g_strdup ( " Name cannot be empty " ) ;
return FALSE ;
}
return TRUE ;
}
static void
free_generic_one_id_string_cb ( void * r ) {
generic_one_id_string_t * rec = ( generic_one_id_string_t * ) r ;
/* freeing result of g_strdup */
g_free ( rec - > name ) ;
rec - > name = NULL ;
}
static void
post_update_one_id_string_template_cb ( generic_one_id_string_t * data , guint data_num , GHashTable * ht ) {
guint i ;
int * key = NULL ;
for ( i = 0 ; i < data_num ; i + + ) {
key = wmem_new ( wmem_epan_scope ( ) , int ) ;
* key = data [ i ] . id ;
g_hash_table_insert ( ht , key , g_strdup ( data [ i ] . name ) ) ;
}
}
/* ID/ID2 -> Name */
static void *
copy_generic_two_id_string_cb ( void * n , const void * o , size_t size _U_ ) {
generic_two_id_string_t * new_rec = ( generic_two_id_string_t * ) n ;
const generic_two_id_string_t * old_rec = ( const generic_two_id_string_t * ) o ;
new_rec - > name = g_strdup ( old_rec - > name ) ;
new_rec - > id = old_rec - > id ;
new_rec - > id2 = old_rec - > id2 ;
return new_rec ;
}
static gboolean
update_generic_two_identifier_16bit ( void * r , char * * err ) {
generic_two_id_string_t * rec = ( generic_two_id_string_t * ) r ;
if ( rec - > id > 0xffff ) {
* err = g_strdup_printf ( " We currently only support 16 bit identifiers (ID: %i Name: %s) " , rec - > id , rec - > name ) ;
return FALSE ;
}
if ( rec - > id2 > 0xffff ) {
* err = g_strdup_printf ( " We currently only support 16 bit identifiers (ID: %i ID2: %i Name: %s) " , rec - > id , rec - > id2 , rec - > name ) ;
return FALSE ;
}
if ( rec - > name = = NULL | | rec - > name [ 0 ] = = 0 ) {
* err = g_strdup ( " Name cannot be empty " ) ;
return FALSE ;
}
return TRUE ;
}
static void
free_generic_two_id_string_cb ( void * r ) {
generic_two_id_string_t * rec = ( generic_two_id_string_t * ) r ;
/* freeing result of g_strdup */
g_free ( rec - > name ) ;
rec - > name = NULL ;
}
static void
post_update_generic_two_id_string_template_cb ( generic_two_id_string_t * data , guint data_num , GHashTable * ht ) {
guint i ;
int * key = NULL ;
guint tmp ;
guint tmp2 ;
for ( i = 0 ; i < data_num ; i + + ) {
key = wmem_new ( wmem_epan_scope ( ) , int ) ;
tmp = ( data [ i ] . id & 0xffff ) < < 16 ;
tmp2 = ( data [ i ] . id2 & 0xffff ) ;
/* the hash table does not know about uint32, so we use int32 */
* key = ( int ) ( tmp + tmp2 ) ;
g_hash_table_insert ( ht , key , g_strdup ( data [ i ] . name ) ) ;
}
}
char *
someip_lookup_service_name ( guint16 serviceid ) {
guint32 tmp = ( guint32 ) serviceid ;
if ( data_someip_services = = NULL ) {
return NULL ;
}
return ( char * ) g_hash_table_lookup ( data_someip_services , & tmp ) ;
}
static char *
someip_lookup_method_name ( guint16 serviceid , guint16 methodid ) {
guint32 tmp = ( serviceid < < 16 ) + methodid ;
if ( data_someip_methods = = NULL ) {
return NULL ;
}
return ( char * ) g_hash_table_lookup ( data_someip_methods , & tmp ) ;
}
char *
someip_lookup_eventgroup_name ( guint16 serviceid , guint16 eventgroupid ) {
guint32 tmp = ( serviceid < < 16 ) + eventgroupid ;
if ( data_someip_eventgroups = = NULL ) {
return NULL ;
}
return ( char * ) g_hash_table_lookup ( data_someip_eventgroups , & tmp ) ;
}
/*** SOME/IP Services ***/
UAT_HEX_CB_DEF ( someip_service_ident , id , generic_one_id_string_t )
UAT_CSTRING_CB_DEF ( someip_service_ident , name , generic_one_id_string_t )
static void
post_update_someip_service_cb ( void ) {
/* destroy old hash table, if it exists */
if ( data_someip_services ) {
g_hash_table_destroy ( data_someip_services ) ;
data_someip_services = NULL ;
}
/* create new hash table */
data_someip_services = g_hash_table_new_full ( g_int_hash , g_int_equal , & someip_free_key , & simple_free ) ;
post_update_one_id_string_template_cb ( someip_service_ident , someip_service_ident_num , data_someip_services ) ;
}
/*** SOME/IP Methods/Events/Fields ***/
UAT_HEX_CB_DEF ( someip_method_ident , id , generic_two_id_string_t )
UAT_HEX_CB_DEF ( someip_method_ident , id2 , generic_two_id_string_t )
UAT_CSTRING_CB_DEF ( someip_method_ident , name , generic_two_id_string_t )
static void
post_update_someip_method_cb ( void ) {
/* destroy old hash table, if it exists */
if ( data_someip_methods ) {
g_hash_table_destroy ( data_someip_methods ) ;
data_someip_methods = NULL ;
}
/* create new hash table */
data_someip_methods = g_hash_table_new_full ( g_int_hash , g_int_equal , & someip_free_key , & simple_free ) ;
post_update_generic_two_id_string_template_cb ( someip_method_ident , someip_method_ident_num , data_someip_methods ) ;
}
/*** SOME/IP Eventgroups ***/
UAT_HEX_CB_DEF ( someip_eventgroup_ident , id , generic_two_id_string_t )
UAT_HEX_CB_DEF ( someip_eventgroup_ident , id2 , generic_two_id_string_t )
UAT_CSTRING_CB_DEF ( someip_eventgroup_ident , name , generic_two_id_string_t )
static void
post_update_someip_eventgroup_cb ( void ) {
/* destroy old hash table, if it exists */
if ( data_someip_eventgroups ) {
g_hash_table_destroy ( data_someip_eventgroups ) ;
data_someip_eventgroups = NULL ;
}
/* create new hash table */
data_someip_eventgroups = g_hash_table_new_full ( g_int_hash , g_int_equal , & someip_free_key , & simple_free ) ;
post_update_generic_two_id_string_template_cb ( someip_eventgroup_ident , someip_eventgroup_ident_num , data_someip_eventgroups ) ;
}
static void
someip_payload_free_key ( gpointer key ) {
wmem_free ( wmem_epan_scope ( ) , key ) ;
}
static void
someip_payload_free_generic_data ( gpointer data ) {
wmem_free ( wmem_epan_scope ( ) , ( void * ) data ) ;
}
static gint64
someip_parameter_key ( guint16 serviceid , guint16 methodid , guint8 version , guint8 msgtype ) {
gint64 tmp1 ;
gint64 tmp2 ;
gint64 tmp3 ;
gint64 tmp4 ;
/* key:
Service - ID [ 16 bit ] | Method - ID [ 16 bit ] | Version [ 8 bit ] | Message - Type [ 8 bit ]
*/
tmp1 = ( gint64 ) ( serviceid & 0xffff ) ;
tmp2 = ( gint64 ) ( methodid & 0xffff ) < < 16 ;
tmp3 = ( gint64 ) ( version & 0xff ) < < 32 ;
tmp4 = ( gint64 ) ( msgtype & 0xff ) < < 40 ;
return ( gint64 ) ( tmp1 + tmp2 + tmp3 + tmp4 ) ;
}
static someip_parameter_list_t *
get_parameter_config ( guint16 serviceid , guint16 methodid , guint8 version , guint8 msgtype ) {
gint64 * key = NULL ;
someip_parameter_list_t * tmp = NULL ;
if ( data_someip_parameter_list = = NULL ) {
return NULL ;
}
key = wmem_new ( wmem_epan_scope ( ) , gint64 ) ;
* key = someip_parameter_key ( serviceid , methodid , version , msgtype ) ;
tmp = ( someip_parameter_list_t * ) g_hash_table_lookup ( data_someip_parameter_list , key ) ;
wmem_free ( wmem_epan_scope ( ) , key ) ;
return tmp ;
}
static gpointer
get_generic_config ( GHashTable * ht , gint64 id ) {
if ( ht = = NULL ) {
return NULL ;
}
return ( gpointer ) g_hash_table_lookup ( ht , & id ) ;
}
static someip_payload_parameter_base_type_list_t *
get_base_type_config ( guint32 id ) {
return ( someip_payload_parameter_base_type_list_t * ) get_generic_config ( data_someip_parameter_base_type_list , ( gint64 ) id ) ;
}
static someip_payload_parameter_string_t *
get_string_config ( guint32 id ) {
return ( someip_payload_parameter_string_t * ) get_generic_config ( data_someip_parameter_strings , ( gint64 ) id ) ;
}
static someip_payload_parameter_typedef_t *
get_typedef_config ( guint32 id ) {
return ( someip_payload_parameter_typedef_t * ) get_generic_config ( data_someip_parameter_typedefs , ( gint64 ) id ) ;
}
static someip_parameter_array_t *
get_array_config ( guint32 id ) {
return ( someip_parameter_array_t * ) get_generic_config ( data_someip_parameter_arrays , ( gint64 ) id ) ;
}
static someip_payload_parameter_struct_t *
get_struct_config ( guint32 id ) {
return ( someip_payload_parameter_struct_t * ) get_generic_config ( data_someip_parameter_structs , ( gint64 ) id ) ;
}
static someip_parameter_union_t *
get_union_config ( guint32 id ) {
return ( someip_parameter_union_t * ) get_generic_config ( data_someip_parameter_unions , ( gint64 ) id ) ;
}
static someip_payload_parameter_enum_t *
get_enum_config ( guint32 id ) {
return ( someip_payload_parameter_enum_t * ) get_generic_config ( data_someip_parameter_enums , ( gint64 ) id ) ;
}
UAT_HEX_CB_DEF ( someip_parameter_list , service_id , someip_parameter_list_uat_t )
UAT_HEX_CB_DEF ( someip_parameter_list , method_id , someip_parameter_list_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_list , version , someip_parameter_list_uat_t )
UAT_HEX_CB_DEF ( someip_parameter_list , message_type , someip_parameter_list_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_list , num_of_params , someip_parameter_list_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_list , pos , someip_parameter_list_uat_t )
UAT_CSTRING_CB_DEF ( someip_parameter_list , name , someip_parameter_list_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_list , data_type , someip_parameter_list_uat_t )
UAT_HEX_CB_DEF ( someip_parameter_list , id_ref , someip_parameter_list_uat_t )
static void *
copy_someip_parameter_list_cb ( void * n , const void * o , size_t size _U_ ) {
someip_parameter_list_uat_t * new_rec = ( someip_parameter_list_uat_t * ) n ;
const someip_parameter_list_uat_t * old_rec = ( const someip_parameter_list_uat_t * ) o ;
if ( old_rec - > name ) {
new_rec - > name = g_strdup ( old_rec - > name ) ;
} else {
new_rec - > name = NULL ;
}
new_rec - > service_id = old_rec - > service_id ;
new_rec - > method_id = old_rec - > method_id ;
new_rec - > version = old_rec - > version ;
new_rec - > message_type = old_rec - > message_type ;
new_rec - > num_of_params = old_rec - > num_of_params ;
new_rec - > pos = old_rec - > pos ;
new_rec - > data_type = old_rec - > data_type ;
new_rec - > id_ref = old_rec - > id_ref ;
return new_rec ;
}
static gboolean
update_someip_parameter_list ( void * r , char * * err ) {
someip_parameter_list_uat_t * rec = ( someip_parameter_list_uat_t * ) r ;
if ( rec - > service_id > 0xffff ) {
* err = g_strdup_printf ( " We currently only support 16 bit Service IDs (Service-ID: %i Name: %s) " , rec - > service_id , rec - > name ) ;
return FALSE ;
}
if ( rec - > method_id > 0xffff ) {
* err = g_strdup_printf ( " We currently only support 16 bit Method IDs (Service-ID: %i Method-ID: %i Name: %s) " , rec - > service_id , rec - > method_id , rec - > name ) ;
return FALSE ;
}
if ( rec - > version > 0xff ) {
* err = g_strdup_printf ( " We currently only support 8 bit Version (Service-ID: %i Method-ID: %i Version: %d Name: %s) " , rec - > service_id , rec - > method_id , rec - > version , rec - > name ) ;
return FALSE ;
}
if ( rec - > message_type > 0xff ) {
* err = g_strdup_printf ( " We currently only support 8 bit Message Type (Service-ID: %i Method-ID: %i Version: %d Message Type: %x Name: %s) " , rec - > service_id , rec - > method_id , rec - > version , rec - > message_type , rec - > name ) ;
return FALSE ;
}
if ( rec - > name = = NULL | | rec - > name [ 0 ] = = 0 ) {
* err = g_strdup_printf ( " Name cannot be empty " ) ;
return FALSE ;
}
if ( rec - > pos > = rec - > num_of_params ) {
* err = g_strdup_printf ( " Position >= Number of Parameters " ) ;
return FALSE ;
}
return TRUE ;
}
static void
free_someip_parameter_list_cb ( void * r ) {
someip_parameter_list_uat_t * rec = ( someip_parameter_list_uat_t * ) r ;
if ( rec - > name ) g_free ( rec - > name ) ;
}
static void
post_update_someip_parameter_list_read_in_data ( someip_parameter_list_uat_t * data , guint data_num , GHashTable * ht ) {
guint i = 0 ;
gint64 * key = NULL ;
someip_parameter_list_t * list = NULL ;
someip_payload_parameter_item_t * item = NULL ;
someip_payload_parameter_item_t * items = NULL ;
if ( ht = = NULL | | data = = NULL | | data_num = = 0 ) {
return ;
}
for ( i = 0 ; i < data_num ; i + + ) {
/* the hash table does not know about uint64, so we use int64*/
key = wmem_new ( wmem_epan_scope ( ) , gint64 ) ;
* key = someip_parameter_key ( ( guint16 ) data [ i ] . service_id , ( guint16 ) data [ i ] . method_id , ( guint8 ) data [ i ] . version , ( guint8 ) data [ i ] . message_type ) ;
list = ( someip_parameter_list_t * ) g_hash_table_lookup ( ht , key ) ;
if ( list = = NULL ) {
list = wmem_new ( wmem_epan_scope ( ) , someip_parameter_list_t ) ;
list - > service_id = data [ i ] . service_id ;
list - > method_id = data [ i ] . method_id ;
list - > version = data [ i ] . version ;
list - > message_type = data [ i ] . message_type ;
list - > num_of_items = data [ i ] . num_of_params ;
items = ( someip_payload_parameter_item_t * ) wmem_alloc_array ( wmem_epan_scope ( ) , someip_payload_parameter_item_t , data [ i ] . num_of_params ) ;
memset ( items , 0 , sizeof ( someip_payload_parameter_item_t ) * data [ i ] . num_of_params ) ;
list - > items = items ;
/* create new entry ... */
g_hash_table_insert ( ht , key , list ) ;
} else {
/* already present, deleting key */
wmem_free ( wmem_epan_scope ( ) , key ) ;
}
/* and now we add to item array */
if ( data [ i ] . num_of_params = = list - > num_of_items & & data [ i ] . pos < list - > num_of_items ) {
item = & ( list - > items [ data [ i ] . pos ] ) ;
/* we do not care if we overwrite param */
item - > name = data [ i ] . name ;
item - > id_ref = data [ i ] . id_ref ;
item - > pos = data [ i ] . pos ;
item - > data_type = data [ i ] . data_type ;
}
}
}
static void
post_update_someip_parameter_list_cb ( void ) {
/* destroy old hash table, if it exists */
if ( data_someip_parameter_list ) {
g_hash_table_destroy ( data_someip_parameter_list ) ;
data_someip_parameter_list = NULL ;
}
data_someip_parameter_list = g_hash_table_new_full ( g_int64_hash , g_int64_equal , & someip_payload_free_key , & someip_payload_free_generic_data ) ;
post_update_someip_parameter_list_read_in_data ( someip_parameter_list , someip_parameter_list_num , data_someip_parameter_list ) ;
}
UAT_HEX_CB_DEF ( someip_parameter_enums , id , someip_parameter_enum_uat_t )
UAT_CSTRING_CB_DEF ( someip_parameter_enums , name , someip_parameter_enum_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_enums , data_type , someip_parameter_enum_uat_t )
UAT_HEX_CB_DEF ( someip_parameter_enums , id_ref , someip_parameter_enum_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_enums , num_of_items , someip_parameter_enum_uat_t )
UAT_HEX_CB_DEF ( someip_parameter_enums , value , someip_parameter_enum_uat_t )
UAT_CSTRING_CB_DEF ( someip_parameter_enums , value_name , someip_parameter_enum_uat_t )
static void *
copy_someip_parameter_enum_cb ( void * n , const void * o , size_t size _U_ ) {
someip_parameter_enum_uat_t * new_rec = ( someip_parameter_enum_uat_t * ) n ;
const someip_parameter_enum_uat_t * old_rec = ( const someip_parameter_enum_uat_t * ) o ;
new_rec - > id = old_rec - > id ;
if ( old_rec - > name ) {
new_rec - > name = g_strdup ( old_rec - > name ) ;
} else {
new_rec - > name = NULL ;
}
new_rec - > data_type = old_rec - > data_type ;
new_rec - > id_ref = old_rec - > id_ref ;
new_rec - > num_of_items = old_rec - > num_of_items ;
new_rec - > value = old_rec - > value ;
if ( old_rec - > value_name ) {
new_rec - > value_name = g_strdup ( old_rec - > value_name ) ;
} else {
new_rec - > value_name = NULL ;
}
return new_rec ;
}
static gboolean
update_someip_parameter_enum ( void * r , char * * err ) {
someip_parameter_enum_uat_t * rec = ( someip_parameter_enum_uat_t * ) r ;
if ( rec - > name = = NULL | | rec - > name [ 0 ] = = 0 ) {
* err = g_strdup_printf ( " Name cannot be empty " ) ;
return FALSE ;
}
if ( rec - > value_name = = NULL | | rec - > value_name [ 0 ] = = 0 ) {
* err = g_strdup_printf ( " Value Name cannot be empty " ) ;
return FALSE ;
}
if ( rec - > num_of_items = = 0 ) {
* err = g_strdup_printf ( " Number_of_Items = 0 " ) ;
return FALSE ;
}
return TRUE ;
}
static void
free_someip_parameter_enum_cb ( void * r ) {
someip_parameter_enum_uat_t * rec = ( someip_parameter_enum_uat_t * ) r ;
if ( rec - > name ) g_free ( rec - > name ) ;
if ( rec - > value_name ) g_free ( rec - > value_name ) ;
}
static void
post_update_someip_parameter_enum_read_in_data ( someip_parameter_enum_uat_t * data , guint data_num , GHashTable * ht ) {
guint i = 0 ;
guint j = 0 ;
gint64 * key = NULL ;
someip_payload_parameter_enum_t * list = NULL ;
someip_payload_parameter_enum_item_t * item = NULL ;
if ( ht = = NULL | | data = = NULL | | data_num = = 0 ) {
return ;
}
for ( i = 0 ; i < data_num ; i + + ) {
key = wmem_new ( wmem_epan_scope ( ) , gint64 ) ;
* key = data [ i ] . id ;
list = ( someip_payload_parameter_enum_t * ) g_hash_table_lookup ( ht , key ) ;
if ( list = = NULL ) {
list = wmem_new ( wmem_epan_scope ( ) , someip_payload_parameter_enum_t ) ;
INIT_SOMEIP_PAYLOAD_PARAMETER_ENUM ( list )
list - > id = data [ i ] . id ;
list - > name = data [ i ] . name ;
list - > data_type = data [ i ] . data_type ;
list - > id_ref = data [ i ] . id_ref ;
list - > num_of_items = data [ i ] . num_of_items ;
list - > items = ( someip_payload_parameter_enum_item_t * ) wmem_alloc_array ( wmem_epan_scope ( ) , someip_payload_parameter_enum_item_t , list - > num_of_items ) ;
memset ( list - > items , 0 , sizeof ( someip_payload_parameter_enum_item_t ) * list - > num_of_items ) ;
/* create new entry ... */
g_hash_table_insert ( ht , key , list ) ;
} else {
/* dont need it anymore */
wmem_free ( wmem_epan_scope ( ) , key ) ;
}
/* and now we add to item array */
if ( list - > num_of_items > 0 & & data [ i ] . num_of_items = = list - > num_of_items ) {
/* find first empty slot */
for ( j = 0 ; j < list - > num_of_items & & list - > items [ j ] . name ! = NULL ; j + + ) ;
if ( j < list - > num_of_items ) {
item = & ( list - > items [ j ] ) ;
INIT_SOMEIP_PAYLOAD_PARAMETER_ENUM_ITEM ( item )
/* we do not care if we overwrite param */
item - > value = data [ i ] . value ;
item - > name = data [ i ] . value_name ;
}
}
}
}
static void
post_update_someip_parameter_enum_cb ( void ) {
/* destroy old hash table, if it exists */
if ( data_someip_parameter_enums ) {
g_hash_table_destroy ( data_someip_parameter_enums ) ;
data_someip_parameter_enums = NULL ;
}
data_someip_parameter_enums = g_hash_table_new_full ( g_int64_hash , g_int64_equal , & someip_payload_free_key , & someip_payload_free_generic_data ) ;
post_update_someip_parameter_enum_read_in_data ( someip_parameter_enums , someip_parameter_enums_num , data_someip_parameter_enums ) ;
}
UAT_HEX_CB_DEF ( someip_parameter_arrays , id , someip_parameter_array_uat_t )
UAT_CSTRING_CB_DEF ( someip_parameter_arrays , name , someip_parameter_array_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_arrays , data_type , someip_parameter_array_uat_t )
UAT_HEX_CB_DEF ( someip_parameter_arrays , id_ref , someip_parameter_array_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_arrays , num_of_dims , someip_parameter_array_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_arrays , num , someip_parameter_array_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_arrays , lower_limit , someip_parameter_array_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_arrays , upper_limit , someip_parameter_array_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_arrays , length_of_length , someip_parameter_array_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_arrays , pad_to , someip_parameter_array_uat_t )
static void *
copy_someip_parameter_array_cb ( void * n , const void * o , size_t size _U_ ) {
someip_parameter_array_uat_t * new_rec = ( someip_parameter_array_uat_t * ) n ;
const someip_parameter_array_uat_t * old_rec = ( const someip_parameter_array_uat_t * ) o ;
new_rec - > id = old_rec - > id ;
if ( old_rec - > name ) {
new_rec - > name = g_strdup ( old_rec - > name ) ;
} else {
new_rec - > name = NULL ;
}
new_rec - > data_type = old_rec - > data_type ;
new_rec - > id_ref = old_rec - > id_ref ;
new_rec - > num_of_dims = old_rec - > num_of_dims ;
new_rec - > num = old_rec - > num ;
new_rec - > lower_limit = old_rec - > lower_limit ;
new_rec - > upper_limit = old_rec - > upper_limit ;
new_rec - > length_of_length = old_rec - > length_of_length ;
new_rec - > pad_to = old_rec - > pad_to ;
return new_rec ;
}
static gboolean
update_someip_parameter_array ( void * r , char * * err ) {
someip_parameter_array_uat_t * rec = ( someip_parameter_array_uat_t * ) r ;
if ( rec - > name = = NULL | | rec - > name [ 0 ] = = 0 ) {
* err = g_strdup_printf ( " Name cannot be empty " ) ;
return FALSE ;
}
if ( rec - > num > = rec - > num_of_dims ) {
* err = g_strdup_printf ( " Dimension >= Number of Dimensions " ) ;
return FALSE ;
}
return TRUE ;
}
static void
free_someip_parameter_array_cb ( void * r ) {
someip_parameter_array_uat_t * rec = ( someip_parameter_array_uat_t * ) r ;
if ( rec - > name ) g_free ( rec - > name ) ;
}
static void
post_update_someip_parameter_array_read_in_data ( someip_parameter_array_uat_t * data , guint data_num , GHashTable * ht ) {
guint i = 0 ;
gint64 * key = NULL ;
someip_parameter_array_t * list = NULL ;
someip_parameter_array_dim_t * item = NULL ;
someip_parameter_array_dim_t * items = NULL ;
if ( ht = = NULL | | data = = NULL | | data_num = = 0 ) {
return ;
}
for ( i = 0 ; i < data_num ; i + + ) {
key = wmem_new ( wmem_epan_scope ( ) , gint64 ) ;
* key = data [ i ] . id ;
list = ( someip_parameter_array_t * ) g_hash_table_lookup ( ht , key ) ;
if ( list = = NULL ) {
list = wmem_new ( wmem_epan_scope ( ) , someip_parameter_array_t ) ;
list - > id = data [ i ] . id ;
list - > name = data [ i ] . name ;
list - > data_type = data [ i ] . data_type ;
list - > id_ref = data [ i ] . id_ref ;
list - > num_of_dims = data [ i ] . num_of_dims ;
items = ( someip_parameter_array_dim_t * ) wmem_alloc_array ( wmem_epan_scope ( ) , someip_parameter_array_dim_t , data [ i ] . num_of_dims ) ;
memset ( items , 0 , sizeof ( someip_parameter_array_dim_t ) * data [ i ] . num_of_dims ) ;
list - > dims = items ;
/* create new entry ... */
g_hash_table_insert ( ht , key , list ) ;
}
/* and now we add to item array */
if ( data [ i ] . num_of_dims = = list - > num_of_dims & & data [ i ] . num < list - > num_of_dims ) {
item = & ( list - > dims [ data [ i ] . num ] ) ;
/* we do not care if we overwrite param */
item - > num = data [ i ] . num ;
item - > lower_limit = data [ i ] . lower_limit ;
item - > upper_limit = data [ i ] . upper_limit ;
item - > length_of_length = data [ i ] . length_of_length ;
item - > pad_to = data [ i ] . pad_to ;
}
}
}
static void
post_update_someip_parameter_array_cb ( void ) {
/* destroy old hash table, if it exists */
if ( data_someip_parameter_arrays ) {
g_hash_table_destroy ( data_someip_parameter_arrays ) ;
data_someip_parameter_arrays = NULL ;
}
data_someip_parameter_arrays = g_hash_table_new_full ( g_int64_hash , g_int64_equal , & someip_payload_free_key , & someip_payload_free_generic_data ) ;
post_update_someip_parameter_array_read_in_data ( someip_parameter_arrays , someip_parameter_arrays_num , data_someip_parameter_arrays ) ;
}
UAT_HEX_CB_DEF ( someip_parameter_structs , id , someip_parameter_struct_uat_t )
UAT_CSTRING_CB_DEF ( someip_parameter_structs , struct_name , someip_parameter_struct_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_structs , length_of_length , someip_parameter_struct_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_structs , pad_to , someip_parameter_struct_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_structs , num_of_items , someip_parameter_struct_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_structs , pos , someip_parameter_struct_uat_t )
UAT_CSTRING_CB_DEF ( someip_parameter_structs , name , someip_parameter_struct_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_structs , data_type , someip_parameter_struct_uat_t )
UAT_HEX_CB_DEF ( someip_parameter_structs , id_ref , someip_parameter_struct_uat_t )
static void *
copy_someip_parameter_struct_cb ( void * n , const void * o , size_t size _U_ ) {
someip_parameter_struct_uat_t * new_rec = ( someip_parameter_struct_uat_t * ) n ;
const someip_parameter_struct_uat_t * old_rec = ( const someip_parameter_struct_uat_t * ) o ;
new_rec - > id = old_rec - > id ;
if ( old_rec - > struct_name ) {
new_rec - > struct_name = g_strdup ( old_rec - > struct_name ) ;
} else {
new_rec - > struct_name = NULL ;
}
new_rec - > length_of_length = old_rec - > length_of_length ;
new_rec - > pad_to = old_rec - > pad_to ;
new_rec - > num_of_items = old_rec - > num_of_items ;
new_rec - > pos = old_rec - > pos ;
if ( old_rec - > name ) {
new_rec - > name = g_strdup ( old_rec - > name ) ;
} else {
new_rec - > name = NULL ;
}
new_rec - > data_type = old_rec - > data_type ;
new_rec - > id_ref = old_rec - > id_ref ;
return new_rec ;
}
static gboolean
update_someip_parameter_struct ( void * r , char * * err ) {
someip_parameter_struct_uat_t * rec = ( someip_parameter_struct_uat_t * ) r ;
if ( rec - > struct_name = = NULL | | rec - > struct_name [ 0 ] = = 0 ) {
* err = g_strdup_printf ( " Struct name cannot be empty " ) ;
return FALSE ;
}
if ( rec - > name = = NULL | | rec - > name [ 0 ] = = 0 ) {
* err = g_strdup_printf ( " Name cannot be empty " ) ;
return FALSE ;
}
if ( rec - > pos > = rec - > num_of_items ) {
* err = g_strdup_printf ( " Position >= Number of Parameters " ) ;
return FALSE ;
}
return TRUE ;
}
static void
free_someip_parameter_struct_cb ( void * r ) {
someip_parameter_struct_uat_t * rec = ( someip_parameter_struct_uat_t * ) r ;
if ( rec - > struct_name ) g_free ( rec - > struct_name ) ;
if ( rec - > name ) g_free ( rec - > name ) ;
}
static void
post_update_someip_parameter_struct_read_in_data ( someip_parameter_struct_uat_t * data , guint data_num , GHashTable * ht ) {
guint i = 0 ;
gint64 * key = NULL ;
someip_payload_parameter_struct_t * list = NULL ;
someip_payload_parameter_item_t * item = NULL ;
someip_payload_parameter_item_t * items = NULL ;
if ( ht = = NULL | | data = = NULL | | data_num = = 0 ) {
return ;
}
for ( i = 0 ; i < data_num ; i + + ) {
key = wmem_new ( wmem_epan_scope ( ) , gint64 ) ;
* key = data [ i ] . id ;
list = ( someip_payload_parameter_struct_t * ) g_hash_table_lookup ( ht , key ) ;
if ( list = = NULL ) {
list = wmem_new ( wmem_epan_scope ( ) , someip_payload_parameter_struct_t ) ;
INIT_SOMEIP_PAYLOAD_PARAMETER_STRUCT ( list )
list - > id = data [ i ] . id ;
list - > struct_name = data [ i ] . struct_name ;
list - > length_of_length = data [ i ] . length_of_length ;
list - > pad_to = data [ i ] . pad_to ;
list - > num_of_items = data [ i ] . num_of_items ;
items = ( someip_payload_parameter_item_t * ) wmem_alloc_array ( wmem_epan_scope ( ) , someip_payload_parameter_item_t , data [ i ] . num_of_items ) ;
memset ( items , 0 , sizeof ( someip_payload_parameter_item_t ) * data [ i ] . num_of_items ) ;
list - > items = items ;
/* create new entry ... */
g_hash_table_insert ( ht , key , list ) ;
}
/* and now we add to item array */
if ( data [ i ] . num_of_items = = list - > num_of_items & & data [ i ] . pos < list - > num_of_items ) {
item = & ( list - > items [ data [ i ] . pos ] ) ;
INIT_SOMEIP_PAYLOAD_PARAMETER_ITEM ( item )
/* we do not care if we overwrite param */
item - > name = data [ i ] . name ;
item - > id_ref = data [ i ] . id_ref ;
item - > pos = data [ i ] . pos ;
item - > data_type = data [ i ] . data_type ;
}
}
}
static void
post_update_someip_parameter_struct_cb ( void ) {
/* destroy old hash table, if it exists */
if ( data_someip_parameter_structs ) {
g_hash_table_destroy ( data_someip_parameter_structs ) ;
data_someip_parameter_structs = NULL ;
}
data_someip_parameter_structs = g_hash_table_new_full ( g_int64_hash , g_int64_equal , & someip_payload_free_key , & someip_payload_free_generic_data ) ;
post_update_someip_parameter_struct_read_in_data ( someip_parameter_structs , someip_parameter_structs_num , data_someip_parameter_structs ) ;
}
UAT_HEX_CB_DEF ( someip_parameter_unions , id , someip_parameter_union_uat_t )
UAT_CSTRING_CB_DEF ( someip_parameter_unions , name , someip_parameter_union_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_unions , length_of_length , someip_parameter_union_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_unions , length_of_type , someip_parameter_union_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_unions , pad_to , someip_parameter_union_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_unions , num_of_items , someip_parameter_union_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_unions , type_id , someip_parameter_union_uat_t )
UAT_CSTRING_CB_DEF ( someip_parameter_unions , type_name , someip_parameter_union_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_unions , data_type , someip_parameter_union_uat_t )
UAT_HEX_CB_DEF ( someip_parameter_unions , id_ref , someip_parameter_union_uat_t )
static void *
copy_someip_parameter_union_cb ( void * n , const void * o , size_t size _U_ ) {
someip_parameter_union_uat_t * new_rec = ( someip_parameter_union_uat_t * ) n ;
const someip_parameter_union_uat_t * old_rec = ( const someip_parameter_union_uat_t * ) o ;
new_rec - > id = old_rec - > id ;
if ( old_rec - > name ) {
new_rec - > name = g_strdup ( old_rec - > name ) ;
} else {
new_rec - > name = NULL ;
}
new_rec - > length_of_length = old_rec - > length_of_length ;
new_rec - > length_of_type = old_rec - > length_of_type ;
new_rec - > pad_to = old_rec - > pad_to ;
new_rec - > num_of_items = old_rec - > num_of_items ;
new_rec - > type_id = old_rec - > type_id ;
if ( old_rec - > type_name ) {
new_rec - > type_name = g_strdup ( old_rec - > type_name ) ;
} else {
new_rec - > type_name = NULL ;
}
new_rec - > data_type = old_rec - > data_type ;
new_rec - > id_ref = old_rec - > id_ref ;
return new_rec ;
}
static gboolean
update_someip_parameter_union ( void * r , char * * err ) {
someip_parameter_union_uat_t * rec = ( someip_parameter_union_uat_t * ) r ;
if ( rec - > name = = NULL | | rec - > name [ 0 ] = = 0 ) {
* err = g_strdup_printf ( " Union name cannot be empty " ) ;
return FALSE ;
}
if ( rec - > type_name = = NULL | | rec - > type_name [ 0 ] = = 0 ) {
* err = g_strdup_printf ( " Type Name cannot be empty " ) ;
return FALSE ;
}
return TRUE ;
}
static void
free_someip_parameter_union_cb ( void * r ) {
someip_parameter_union_uat_t * rec = ( someip_parameter_union_uat_t * ) r ;
if ( rec - > name ) g_free ( rec - > name ) ;
if ( rec - > type_name ) g_free ( rec - > type_name ) ;
}
static void
post_update_someip_parameter_union_read_in_data ( someip_parameter_union_uat_t * data , guint data_num , GHashTable * ht ) {
guint i = 0 ;
guint j = 0 ;
gint64 * key = NULL ;
someip_parameter_union_t * list = NULL ;
someip_parameter_union_item_t * item = NULL ;
if ( ht = = NULL | | data = = NULL | | data_num = = 0 ) {
return ;
}
for ( i = 0 ; i < data_num ; i + + ) {
key = wmem_new ( wmem_epan_scope ( ) , gint64 ) ;
* key = data [ i ] . id ;
list = ( someip_parameter_union_t * ) g_hash_table_lookup ( ht , key ) ;
if ( list = = NULL ) {
list = wmem_new ( wmem_epan_scope ( ) , someip_parameter_union_t ) ;
list - > id = data [ i ] . id ;
list - > name = data [ i ] . name ;
list - > length_of_length = data [ i ] . length_of_length ;
list - > length_of_type = data [ i ] . length_of_type ;
list - > pad_to = data [ i ] . pad_to ;
list - > num_of_items = data [ i ] . num_of_items ;
list - > items = ( someip_parameter_union_item_t * ) wmem_alloc_array ( wmem_epan_scope ( ) , someip_parameter_union_item_t , list - > num_of_items ) ;
memset ( list - > items , 0 , sizeof ( someip_parameter_union_item_t ) * list - > num_of_items ) ;
/* create new entry ... */
g_hash_table_insert ( ht , key , list ) ;
} else {
/* dont need it anymore */
wmem_free ( wmem_epan_scope ( ) , key ) ;
}
/* and now we add to item array */
if ( data [ i ] . num_of_items = = list - > num_of_items ) {
/* find first empty slot */
for ( j = 0 ; j < list - > num_of_items & & list - > items [ j ] . name ! = NULL ; j + + ) ;
if ( j < list - > num_of_items ) {
item = & ( list - > items [ j ] ) ;
/* we do not care if we overwrite param */
item - > id = data [ i ] . type_id ;
item - > name = data [ i ] . type_name ;
item - > data_type = data [ i ] . data_type ;
item - > id_ref = data [ i ] . id_ref ;
}
}
}
}
static void
post_update_someip_parameter_union_cb ( void ) {
/* destroy old hash table, if it exists */
if ( data_someip_parameter_unions ) {
g_hash_table_destroy ( data_someip_parameter_unions ) ;
data_someip_parameter_unions = NULL ;
}
data_someip_parameter_unions = g_hash_table_new_full ( g_int64_hash , g_int64_equal , & someip_payload_free_key , & someip_payload_free_generic_data ) ;
post_update_someip_parameter_union_read_in_data ( someip_parameter_unions , someip_parameter_unions_num , data_someip_parameter_unions ) ;
}
UAT_HEX_CB_DEF ( someip_parameter_base_type_list , id , someip_parameter_base_type_list_uat_t )
UAT_CSTRING_CB_DEF ( someip_parameter_base_type_list , name , someip_parameter_base_type_list_uat_t )
UAT_CSTRING_CB_DEF ( someip_parameter_base_type_list , data_type , someip_parameter_base_type_list_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_base_type_list , big_endian , someip_parameter_base_type_list_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_base_type_list , bitlength_base_type , someip_parameter_base_type_list_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_base_type_list , bitlength_encoded_type , someip_parameter_base_type_list_uat_t )
static void *
copy_someip_parameter_base_type_list_cb ( void * n , const void * o , size_t size _U_ ) {
someip_parameter_base_type_list_uat_t * new_rec = ( someip_parameter_base_type_list_uat_t * ) n ;
const someip_parameter_base_type_list_uat_t * old_rec = ( const someip_parameter_base_type_list_uat_t * ) o ;
if ( old_rec - > name ) {
new_rec - > name = g_strdup ( old_rec - > name ) ;
} else {
new_rec - > name = NULL ;
}
if ( old_rec - > data_type ) {
new_rec - > data_type = g_strdup ( old_rec - > data_type ) ;
} else {
new_rec - > data_type = NULL ;
}
new_rec - > id = old_rec - > id ;
new_rec - > big_endian = old_rec - > big_endian ;
new_rec - > bitlength_base_type = old_rec - > bitlength_base_type ;
new_rec - > bitlength_encoded_type = old_rec - > bitlength_encoded_type ;
return new_rec ;
}
static gboolean
update_someip_parameter_base_type_list ( void * r , char * * err ) {
someip_parameter_base_type_list_uat_t * rec = ( someip_parameter_base_type_list_uat_t * ) r ;
if ( rec - > id > 0xffffffff ) {
* err = g_strdup_printf ( " We currently only support 32 bit IDs (%i) Name: %s " , rec - > id , rec - > name ) ;
return FALSE ;
}
if ( rec - > big_endian ! = 0 & & rec - > big_endian ! = 1 ) {
* err = g_strdup_printf ( " Big Endian can be only 0 or 1 but not %d (IDs: %i Name: %s) " , rec - > big_endian , rec - > id , rec - > name ) ;
return FALSE ;
}
return TRUE ;
}
static void
free_someip_parameter_base_type_list_cb ( void * r ) {
someip_parameter_base_type_list_uat_t * rec = ( someip_parameter_base_type_list_uat_t * ) r ;
if ( rec - > name ) g_free ( rec - > name ) ;
if ( rec - > data_type ) g_free ( rec - > data_type ) ;
}
static void
post_update_someip_parameter_base_type_list_cb ( void ) {
guint i ;
gint64 * key = NULL ;
/* destroy old hash table, if it exists */
if ( data_someip_parameter_base_type_list ) {
g_hash_table_destroy ( data_someip_parameter_base_type_list ) ;
data_someip_parameter_base_type_list = NULL ;
}
/* we dont need to free the data as long as we don't alloc it first */
data_someip_parameter_base_type_list = g_hash_table_new_full ( g_int64_hash , g_int64_equal , & someip_payload_free_key , NULL ) ;
if ( data_someip_parameter_base_type_list = = NULL | | someip_parameter_base_type_list = = NULL | | someip_parameter_base_type_list_num = = 0 ) {
return ;
}
if ( someip_parameter_base_type_list_num > 0 ) {
for ( i = 0 ; i < someip_parameter_base_type_list_num ; i + + ) {
key = wmem_new ( wmem_epan_scope ( ) , gint64 ) ;
* key = someip_parameter_base_type_list [ i ] . id ;
g_hash_table_insert ( data_someip_parameter_base_type_list , key , & someip_parameter_base_type_list [ i ] ) ;
}
}
}
UAT_HEX_CB_DEF ( someip_parameter_strings , id , someip_parameter_string_uat_t )
UAT_CSTRING_CB_DEF ( someip_parameter_strings , name , someip_parameter_string_uat_t )
UAT_CSTRING_CB_DEF ( someip_parameter_strings , encoding , someip_parameter_string_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_strings , dynamic_length , someip_parameter_string_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_strings , max_length , someip_parameter_string_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_strings , length_of_length , someip_parameter_string_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_strings , big_endian , someip_parameter_string_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_strings , pad_to , someip_parameter_string_uat_t )
static void *
copy_someip_parameter_string_list_cb ( void * n , const void * o , size_t size _U_ ) {
someip_parameter_string_uat_t * new_rec = ( someip_parameter_string_uat_t * ) n ;
const someip_parameter_string_uat_t * old_rec = ( const someip_parameter_string_uat_t * ) o ;
if ( old_rec - > name ) {
new_rec - > name = g_strdup ( old_rec - > name ) ;
} else {
new_rec - > name = NULL ;
}
if ( old_rec - > encoding ) {
new_rec - > encoding = g_strdup ( old_rec - > encoding ) ;
} else {
new_rec - > encoding = NULL ;
}
new_rec - > id = old_rec - > id ;
new_rec - > dynamic_length = old_rec - > dynamic_length ;
new_rec - > max_length = old_rec - > max_length ;
new_rec - > length_of_length = old_rec - > length_of_length ;
new_rec - > big_endian = old_rec - > big_endian ;
new_rec - > pad_to = old_rec - > pad_to ;
return new_rec ;
}
static gboolean
update_someip_parameter_string_list ( void * r , char * * err ) {
someip_parameter_string_uat_t * rec = ( someip_parameter_string_uat_t * ) r ;
if ( rec - > id > 0xffffffff ) {
* err = g_strdup_printf ( " We currently only support 32 bit IDs (%i) Name: %s " , rec - > id , rec - > name ) ;
return FALSE ;
}
if ( rec - > dynamic_length ! = 0 & & rec - > dynamic_length ! = 1 ) {
* err = g_strdup_printf ( " Dynamic Length can be only 0 or 1 but not %d (IDs: %i Name: %s) " , rec - > dynamic_length , rec - > id , rec - > name ) ;
return FALSE ;
}
if ( rec - > big_endian ! = 0 & & rec - > big_endian ! = 1 ) {
* err = g_strdup_printf ( " Big Endian can be only 0 or 1 but not %d (IDs: %i Name: %s) " , rec - > big_endian , rec - > id , rec - > name ) ;
return FALSE ;
}
if ( rec - > max_length > 0xffffffff ) {
* err = g_strdup_printf ( " We currently only support 32 bit max_length (%i) Name: %s " , rec - > max_length , rec - > name ) ;
return FALSE ;
}
if ( rec - > length_of_length ! = 0 & & rec - > length_of_length ! = 8 & & rec - > length_of_length ! = 16 & & rec - > length_of_length ! = 32 ) {
* err = g_strdup_printf ( " length_of_length can be only 0, 8, 16, or 32 but not %d (IDs: %i Name: %s) " , rec - > length_of_length , rec - > id , rec - > name ) ;
return FALSE ;
}
return TRUE ;
}
static void
free_someip_parameter_string_list_cb ( void * r ) {
someip_parameter_string_uat_t * rec = ( someip_parameter_string_uat_t * ) r ;
if ( rec - > name ) g_free ( rec - > name ) ;
if ( rec - > encoding ) g_free ( rec - > encoding ) ;
}
static void
post_update_someip_parameter_string_list_cb ( void ) {
guint i ;
gint64 * key = NULL ;
/* destroy old hash table, if it exists */
if ( data_someip_parameter_strings ) {
g_hash_table_destroy ( data_someip_parameter_strings ) ;
data_someip_parameter_strings = NULL ;
}
/* we dont need to free the data as long as we don't alloc it first */
data_someip_parameter_strings = g_hash_table_new_full ( g_int64_hash , g_int64_equal , & someip_payload_free_key , NULL ) ;
if ( data_someip_parameter_strings = = NULL | | someip_parameter_strings = = NULL | | someip_parameter_strings_num = = 0 ) {
return ;
}
if ( someip_parameter_strings_num > 0 ) {
for ( i = 0 ; i < someip_parameter_strings_num ; i + + ) {
key = wmem_new ( wmem_epan_scope ( ) , gint64 ) ;
* key = someip_parameter_strings [ i ] . id ;
g_hash_table_insert ( data_someip_parameter_strings , key , & someip_parameter_strings [ i ] ) ;
}
}
}
UAT_HEX_CB_DEF ( someip_parameter_typedefs , id , someip_parameter_typedef_uat_t )
UAT_CSTRING_CB_DEF ( someip_parameter_typedefs , name , someip_parameter_typedef_uat_t )
UAT_DEC_CB_DEF ( someip_parameter_typedefs , data_type , someip_parameter_typedef_uat_t )
UAT_HEX_CB_DEF ( someip_parameter_typedefs , id_ref , someip_parameter_typedef_uat_t )
static void *
copy_someip_parameter_typedef_list_cb ( void * n , const void * o , size_t size _U_ ) {
someip_parameter_typedef_uat_t * new_rec = ( someip_parameter_typedef_uat_t * ) n ;
const someip_parameter_typedef_uat_t * old_rec = ( const someip_parameter_typedef_uat_t * ) o ;
if ( old_rec - > name ) {
new_rec - > name = g_strdup ( old_rec - > name ) ;
} else {
new_rec - > name = NULL ;
}
new_rec - > id = old_rec - > id ;
new_rec - > data_type = old_rec - > data_type ;
new_rec - > id_ref = old_rec - > id_ref ;
return new_rec ;
}
static gboolean
update_someip_parameter_typedef_list ( void * r , char * * err ) {
someip_parameter_typedef_uat_t * rec = ( someip_parameter_typedef_uat_t * ) r ;
if ( rec - > id > 0xffffffff ) {
* err = g_strdup_printf ( " We currently only support 32 bit IDs (%i) Name: %s " , rec - > id , rec - > name ) ;
return FALSE ;
}
return TRUE ;
}
static void
free_someip_parameter_typedef_list_cb ( void * r ) {
someip_parameter_typedef_uat_t * rec = ( someip_parameter_typedef_uat_t * ) r ;
if ( rec - > name ) g_free ( rec - > name ) ;
}
static void
post_update_someip_parameter_typedef_list_cb ( void ) {
guint i ;
gint64 * key = NULL ;
/* destroy old hash table, if it exists */
if ( data_someip_parameter_typedefs ) {
g_hash_table_destroy ( data_someip_parameter_typedefs ) ;
data_someip_parameter_typedefs = NULL ;
}
/* we dont need to free the data as long as we don't alloc it first */
data_someip_parameter_typedefs = g_hash_table_new_full ( g_int64_hash , g_int64_equal , & someip_payload_free_key , NULL ) ;
if ( data_someip_parameter_typedefs = = NULL | | someip_parameter_typedefs = = NULL | | someip_parameter_typedefs_num = = 0 ) {
return ;
}
if ( someip_parameter_typedefs_num > 0 ) {
for ( i = 0 ; i < someip_parameter_typedefs_num ; i + + ) {
/* key: ID [32bit] */
key = wmem_new ( wmem_epan_scope ( ) , gint64 ) ;
* key = someip_parameter_typedefs [ i ] . id ;
g_hash_table_insert ( data_someip_parameter_typedefs , key , & someip_parameter_typedefs [ i ] ) ;
}
}
}
static void
expert_someip_payload_truncated ( proto_tree * tree , packet_info * pinfo , tvbuff_t * tvb , gint offset , gint length ) {
proto_tree_add_expert ( tree , pinfo , & ef_someip_payload_truncated , tvb , offset , length ) ;
col_append_str ( pinfo - > cinfo , COL_INFO , " [SOME/IP Payload: Truncated payload!] " ) ;
}
2020-04-10 15:28:05 +00:00
static void
expert_someip_payload_malformed ( proto_tree * tree , packet_info * pinfo , tvbuff_t * tvb , gint offset , gint length ) {
proto_tree_add_expert ( tree , pinfo , & ef_someip_payload_malformed , tvb , offset , length ) ;
col_append_str ( pinfo - > cinfo , COL_INFO , " [SOME/IP Payload: Malformed payload!] " ) ;
}
2019-09-10 18:24:32 +00:00
static void
expert_someip_payload_config_error ( proto_tree * tree , packet_info * pinfo , tvbuff_t * tvb , gint offset , gint length , const char * message ) {
proto_tree_add_expert_format ( tree , pinfo , & ef_someip_payload_config_error , tvb , offset , length , " SOME/IP Payload: %s " , message ) ;
col_append_str ( pinfo - > cinfo , COL_INFO , " [SOME/IP Payload: Config Error] " ) ;
}
static void
expert_someip_payload_alignment_error ( proto_tree * tree , packet_info * pinfo , tvbuff_t * tvb , gint offset , gint length ) {
proto_tree_add_expert ( tree , pinfo , & ef_someip_payload_alignment_error , tvb , offset , length ) ;
col_append_str ( pinfo - > cinfo , COL_INFO , " [SOME/IP Payload: Alignment problem] " ) ;
}
/*******************************************
* * * * * * * * SOME / IP Payload Dissector * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int
dissect_someip_payload_parameter ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , gint offset , gint offset_bits , guint8 data_type , guint32 idref , gchar * name ) ;
/* add a flexible size length field, -1 for error*/
static gint64
dissect_someip_payload_length_field ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * subtree , gint offset , gint length_of_length_field ) {
guint32 tmp = 0 ;
switch ( length_of_length_field ) {
case 8 :
proto_tree_add_item_ret_uint ( subtree , hf_payload_length_field_8bit , tvb , offset , length_of_length_field / 8 , ENC_NA , & tmp ) ;
break ;
case 16 :
proto_tree_add_item_ret_uint ( subtree , hf_payload_length_field_16bit , tvb , offset , length_of_length_field / 8 , ENC_BIG_ENDIAN , & tmp ) ;
break ;
case 32 :
proto_tree_add_item_ret_uint ( subtree , hf_payload_length_field_32bit , tvb , offset , length_of_length_field / 8 , ENC_BIG_ENDIAN , & tmp ) ;
break ;
default :
proto_tree_add_expert_format ( subtree , pinfo , & ef_someip_payload_config_error , tvb , offset , 0 ,
" SOME/IP: Payload: length of length field does not make sense: %d bits " , length_of_length_field ) ;
col_append_str ( pinfo - > cinfo , COL_INFO , " [SOME/IP: Payload Config Error] " ) ;
return - 1 ;
}
return ( gint64 ) tmp ;
}
/* add a flexible size type field */
static gint64
dissect_someip_payload_type_field ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * subtree , gint offset , gint length_of_type_field ) {
guint32 tmp = 0 ;
switch ( length_of_type_field ) {
case 8 :
proto_tree_add_item_ret_uint ( subtree , hf_payload_type_field_8bit , tvb , offset , length_of_type_field / 8 , ENC_NA , & tmp ) ;
break ;
case 16 :
proto_tree_add_item_ret_uint ( subtree , hf_payload_type_field_16bit , tvb , offset , length_of_type_field / 8 , ENC_BIG_ENDIAN , & tmp ) ;
break ;
case 32 :
proto_tree_add_item_ret_uint ( subtree , hf_payload_type_field_32bit , tvb , offset , length_of_type_field / 8 , ENC_BIG_ENDIAN , & tmp ) ;
break ;
default :
proto_tree_add_expert_format ( subtree , pinfo , & ef_someip_payload_config_error , tvb , offset , 0 ,
" SOME/IP: Payload: length of type field does not make sense: %d bits " , length_of_type_field ) ;
col_append_str ( pinfo - > cinfo , COL_INFO , " [SOME/IP: Payload Config Error] " ) ;
return - 1 ;
}
return ( gint64 ) tmp ;
}
static gint
dissect_someip_payload_base_type ( tvbuff_t * tvb , packet_info * pinfo _U_ , proto_tree * tree , gint offset , gint offset_bits , guint8 data_type , guint32 id , gchar * name ) {
someip_payload_parameter_base_type_list_t * base_type = NULL ;
someip_payload_parameter_enum_t * enum_config = NULL ;
guint32 basetype_id = 0 ;
guint32 enum_id = 0 ;
gint buf_length = - 1 ;
gint param_length = - 1 ;
guint32 bit_length = 0 ;
proto_item * ti = NULL ;
guint64 value = 0 ;
guint8 tmp = 0 ;
gint tmp_bit_count = 8 ;
gboolean value_set = FALSE ;
gint32 i = 0 ;
guint32 j = 0 ;
gchar * value_name = NULL ;
gint offset_end = 0 ;
gint offset_end_bits = 0 ;
gboolean big_endian = TRUE ;
if ( offset_bits < 0 ) {
return 0 ;
}
switch ( data_type ) {
case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_BASE_TYPE :
basetype_id = id ;
break ;
case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ENUM :
enum_id = id ;
enum_config = get_enum_config ( enum_id ) ;
if ( enum_config = = NULL ) {
return 0 ;
}
basetype_id = enum_config - > id_ref ;
break ;
default :
return 0 ;
}
base_type = get_base_type_config ( basetype_id ) ;
if ( base_type = = NULL ) {
return 0 ;
}
big_endian = base_type - > big_endian ;
buf_length = tvb_captured_length_remaining ( tvb , 0 ) ;
bit_length = base_type - > bitlength_encoded_type ;
/* +7 to round up, if more than 0 bits */
param_length = ( gint ) ( ( offset_bits + bit_length + 7 ) / 8 ) ;
if ( param_length < = buf_length - offset ) {
if ( name = = NULL ) {
ti = proto_tree_add_string_format ( tree , hf_payload_str_base , tvb , offset , param_length , base_type - > name , " [%s] " , base_type - > name ) ;
} else {
ti = proto_tree_add_string_format ( tree , hf_payload_str_base , tvb , offset , param_length , base_type - > name , " %s [%s] " , name , base_type - > name ) ;
}
/* Regular (non-shortened!) SOME/IP types! */
if ( offset_bits = = 0 & & base_type - > bitlength_base_type = = bit_length & & bit_length % 8 = = 0 ) {
if ( strcmp ( base_type - > data_type , " uint8 " ) = = 0 & & base_type - > bitlength_base_type = = 8 ) {
value = tvb_get_guint8 ( tvb , offset ) ;
value_set = TRUE ;
proto_item_append_text ( ti , " : %u " , ( guint8 ) value ) ;
} else if ( strcmp ( base_type - > data_type , " uint16 " ) = = 0 & & base_type - > bitlength_base_type = = 16 ) {
if ( big_endian ) {
value = tvb_get_ntohs ( tvb , offset ) ;
} else {
value = tvb_get_letohs ( tvb , offset ) ;
}
value_set = TRUE ;
proto_item_append_text ( ti , " : %u " , ( guint16 ) value ) ;
} else if ( strcmp ( base_type - > data_type , " uint32 " ) = = 0 & & base_type - > bitlength_base_type = = 32 ) {
if ( big_endian ) {
value = tvb_get_ntohl ( tvb , offset ) ;
} else {
value = tvb_get_letohl ( tvb , offset ) ;
}
value_set = TRUE ;
proto_item_append_text ( ti , " : %u " , ( guint32 ) value ) ;
} else if ( strcmp ( base_type - > data_type , " uint64 " ) = = 0 & & base_type - > bitlength_base_type = = 64 ) {
if ( big_endian ) {
value = tvb_get_ntoh64 ( tvb , offset ) ;
} else {
value = tvb_get_letoh64 ( tvb , offset ) ;
}
value_set = TRUE ;
proto_item_append_text ( ti , " : % " G_GUINT64_FORMAT , value ) ;
} else if ( strcmp ( base_type - > data_type , " int8 " ) = = 0 & & base_type - > bitlength_base_type = = 8 ) {
proto_item_append_text ( ti , " : %d " , ( gint8 ) tvb_get_guint8 ( tvb , offset ) ) ;
} else if ( strcmp ( base_type - > data_type , " int16 " ) = = 0 & & base_type - > bitlength_base_type = = 16 ) {
if ( big_endian ) {
proto_item_append_text ( ti , " : %d " , ( gint16 ) tvb_get_ntohs ( tvb , offset ) ) ;
} else {
proto_item_append_text ( ti , " : %d " , ( gint16 ) tvb_get_letohs ( tvb , offset ) ) ;
}
} else if ( strcmp ( base_type - > data_type , " int32 " ) = = 0 & & base_type - > bitlength_base_type = = 32 ) {
if ( big_endian ) {
proto_item_append_text ( ti , " : %d " , ( gint32 ) tvb_get_ntohl ( tvb , offset ) ) ;
} else {
proto_item_append_text ( ti , " : %d " , ( gint32 ) tvb_get_letohl ( tvb , offset ) ) ;
}
} else if ( strcmp ( base_type - > data_type , " int64 " ) = = 0 & & base_type - > bitlength_base_type = = 64 ) {
if ( big_endian ) {
proto_item_append_text ( ti , " : % " G_GINT64_FORMAT , ( gint64 ) tvb_get_ntoh64 ( tvb , offset ) ) ;
} else {
proto_item_append_text ( ti , " : % " G_GINT64_FORMAT , ( gint64 ) tvb_get_letoh64 ( tvb , offset ) ) ;
}
} else if ( strcmp ( base_type - > data_type , " float32 " ) = = 0 & & base_type - > bitlength_base_type = = 32 ) {
if ( big_endian ) {
proto_item_append_text ( ti , " : %f " , ( float ) tvb_get_ntohieee_float ( tvb , offset ) ) ;
} else {
proto_item_append_text ( ti , " : %f " , ( float ) tvb_get_letohieee_float ( tvb , offset ) ) ;
}
} else if ( strcmp ( base_type - > data_type , " float64 " ) = = 0 & & base_type - > bitlength_base_type = = 64 ) {
if ( big_endian ) {
proto_item_append_text ( ti , " : %f " , ( double ) tvb_get_ntohieee_double ( tvb , offset ) ) ;
} else {
proto_item_append_text ( ti , " : %f " , ( double ) tvb_get_letohieee_double ( tvb , offset ) ) ;
}
}
} else {
/* Shortened datatypes (e.g.CAN over SOME/IP) */
offset_end = ( gint ) ( ( 8 * offset + offset_bits + bit_length ) / 8 ) ;
offset_end_bits = ( gint ) ( ( 8 * offset + offset_bits + bit_length ) % 8 ) ;
if ( ! big_endian ) {
/* offset and offset_end need to be included */
for ( i = offset_end ; i > = offset ; i - - ) {
if ( i ! = offset_end | | offset_end_bits ! = 0 ) {
tmp = tvb_get_guint8 ( tvb , i ) ;
tmp_bit_count = 8 ;
if ( i = = offset_end ) {
tmp = tmp & ( 0xff > > ( 8 - offset_end_bits ) ) ;
/* don't need to shift value, in the first round */
tmp_bit_count = 0 ;
}
if ( i = = offset ) {
tmp > > = offset_bits ;
tmp_bit_count = 8 - offset_bits ;
}
value < < = ( guint ) tmp_bit_count ;
value | = tmp ;
}
}
} else {
/* offset_end needs to be included. */
for ( i = offset ; i < = offset_end ; i + + ) {
/* Do not read the last byte, if you do not need any bit of it. Else we read behind buffer! */
if ( i ! = offset_end | | offset_end_bits ! = 0 ) {
tmp = tvb_get_guint8 ( tvb , i ) ;
tmp_bit_count = 8 ;
if ( i = = offset ) {
tmp = tmp & ( 0xff > > offset_bits ) ;
/* don't need to shift value, in the first round */
tmp_bit_count = 0 ;
}
if ( i = = offset_end ) {
tmp > > = 8 - offset_end_bits ;
tmp_bit_count = offset_end_bits ;
}
value < < = ( guint ) tmp_bit_count ;
value | = tmp ;
}
}
}
value_set = TRUE ;
2020-01-22 07:25:39 +00:00
proto_item_append_text ( ti , " : % " G_GUINT64_FORMAT " (0x% " G_GINT64_MODIFIER " x) " , value , value ) ;
2019-09-10 18:24:32 +00:00
}
} else {
return 0 ;
}
if ( enum_config ! = NULL & & value_set = = TRUE ) {
for ( j = 0 ; j < enum_config - > num_of_items ; j + + ) {
if ( enum_config - > items [ j ] . value = = value ) {
value_name = enum_config - > items [ j ] . name ;
break ;
}
}
if ( value_name ! = NULL ) {
proto_item_append_text ( ti , " (%s) " , value_name ) ;
}
}
return ( gint ) bit_length ;
}
static int
dissect_someip_payload_string ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , gint offset , gint offset_bits , guint32 id , gchar * name ) {
someip_payload_parameter_string_t * config = NULL ;
guint8 * buf = NULL ;
guint32 i = 0 ;
guint32 ret = 0 ;
proto_item * ti = NULL ;
proto_tree * subtree = NULL ;
gint64 tmp = 0 ;
guint32 length = 0 ;
gint offset_orig = offset ;
gint offset_bits_orig = offset_bits ;
guint str_encoding = 0 ;
config = get_string_config ( id ) ;
if ( config = = NULL | | offset_bits ! = 0 ) {
return 0 ;
}
if ( tvb_captured_length_remaining ( tvb , 0 ) < ( gint ) ( config - > length_of_length > > 3 ) ) {
2020-04-10 15:28:05 +00:00
expert_someip_payload_malformed ( tree , pinfo , tvb , offset , 0 ) ;
2019-09-10 18:24:32 +00:00
return 0 ;
} ;
if ( config - > length_of_length = = 0 ) {
length = config - > max_length ;
} else {
tmp = dissect_someip_payload_length_field ( tvb , pinfo , tree , offset , config - > length_of_length ) ;
if ( tmp < 0 ) {
/* error */
return config - > length_of_length / 8 ;
}
length = ( guint32 ) tmp ;
offset + = config - > length_of_length / 8 ;
}
if ( ( guint32 ) tvb_captured_length_remaining ( tvb , offset ) < length ) {
2020-04-10 15:28:05 +00:00
expert_someip_payload_malformed ( tree , pinfo , tvb , offset , 0 ) ;
2019-09-10 18:24:32 +00:00
return 0 ;
}
if ( strcmp ( config - > encoding , " utf-8 " ) = = 0 ) {
str_encoding = ENC_UTF_8 ;
} else if ( strcmp ( config - > encoding , " utf-16 " ) = = 0 ) {
str_encoding = ENC_UTF_16 ;
} else {
str_encoding = ENC_ASCII ;
}
buf = tvb_get_string_enc ( wmem_packet_scope ( ) , tvb , offset , length , str_encoding ) ;
/* sanitizing buffer */
if ( str_encoding = = ENC_ASCII | | str_encoding = = ENC_UTF_8 ) {
for ( i = 0 ; i < length ; i + + ) {
if ( buf [ i ] > 0x00 & & buf [ i ] < 0x20 ) {
buf [ i ] = 0x20 ;
}
}
}
ti = proto_tree_add_string_format ( tree , hf_payload_str_string , tvb , offset_orig , length + ( offset - offset_orig ) , buf , " %s [%s]: %s " , name , config - > name , buf ) ;
subtree = proto_item_add_subtree ( ti , ett_someip_string ) ;
proto_tree_add_string_format ( subtree , hf_payload_str_string , tvb , offset_orig , offset - offset_orig , buf , " string length: %d " , length ) ;
offset + = length ;
ret = 8 * ( offset - offset_orig ) + ( offset_bits - offset_bits_orig ) ;
return ret ;
}
static int
dissect_someip_payload_struct ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , gint offset_orig , gint offset_bits_orig , guint32 id , gchar * name ) {
someip_payload_parameter_item_t * item = NULL ;
someip_payload_parameter_struct_t * config = NULL ;
proto_tree * subtree = NULL ;
proto_item * ti = NULL ;
2020-04-10 15:28:05 +00:00
gint64 length = 0 ;
2019-09-10 18:24:32 +00:00
gint offset = offset_orig ;
gint offset_bits = offset_bits_orig ;
gint bits_parsed = 0 ;
guint i = 0 ;
config = get_struct_config ( id ) ;
if ( config = = NULL | | tree = = NULL | | tvb = = NULL ) {
return 0 ;
}
ti = proto_tree_add_string_format ( tree , hf_payload_str_struct , tvb , offset , 0 , config - > struct_name , " struct %s [%s] " , name , config - > struct_name ) ;
subtree = proto_item_add_subtree ( ti , ett_someip_struct ) ;
2020-04-10 15:28:05 +00:00
if ( tvb_captured_length_remaining ( tvb , 0 ) < ( gint ) ( config - > length_of_length > > 3 ) ) {
expert_someip_payload_malformed ( tree , pinfo , tvb , offset , 0 ) ;
return 0 ;
} ;
if ( config - > length_of_length ! = 0 ) {
length = dissect_someip_payload_length_field ( tvb , pinfo , subtree , offset , config - > length_of_length ) ;
if ( length < 0 ) {
/* error */
return config - > length_of_length / 8 ;
}
offset + = config - > length_of_length / 8 ;
proto_item_set_end ( ti , tvb , offset_orig + ( config - > length_of_length / 8 ) + ( guint32 ) length ) ;
}
2019-09-10 18:24:32 +00:00
for ( i = 0 ; i < config - > num_of_items ; i + + ) {
item = & ( config - > items [ i ] ) ;
bits_parsed = dissect_someip_payload_parameter ( tvb , pinfo , subtree , offset , offset_bits , ( guint8 ) item - > data_type , item - > id_ref , item - > name ) ;
offset = ( 8 * offset + offset_bits + bits_parsed ) / 8 ;
offset_bits = ( 8 * offset + offset_bits + bits_parsed ) % 8 ;
}
2020-04-10 15:28:05 +00:00
if ( config - > length_of_length = = 0 ) {
if ( offset_bits = = 0 ) {
proto_item_set_end ( ti , tvb , offset ) ;
} else {
proto_item_set_end ( ti , tvb , offset + 1 ) ;
}
return 8 * ( offset - offset_orig ) + ( offset_bits - offset_bits_orig ) ;
2019-09-10 18:24:32 +00:00
} else {
2020-04-10 15:28:05 +00:00
return 8 * ( ( config - > length_of_length / 8 ) + ( guint32 ) length ) ;
2019-09-10 18:24:32 +00:00
}
}
static int
dissect_someip_payload_typedef ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , gint offset , gint offset_bits , guint32 id , gchar * name _U_ ) {
gint bits_parsed = 0 ;
someip_payload_parameter_typedef_t * config = NULL ;
config = get_typedef_config ( id ) ;
if ( config = = NULL ) {
return 0 ;
}
/* we basically skip over the typedef for now */
bits_parsed = dissect_someip_payload_parameter ( tvb , pinfo , tree , offset , offset_bits , ( guint8 ) config - > data_type , config - > id_ref , config - > name ) ;
return bits_parsed ;
}
/* returns bytes parsed, length needs to be gint to encode "non-existing" as -1 */
static int
dissect_someip_payload_array_dim_length ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , gint offset_orig , gint * length , gint * lower_limit , gint * upper_limit ,
someip_parameter_array_t * config , gint current_dim ) {
gint offset = offset_orig ;
gint64 tmp = 0 ;
* lower_limit = config - > dims [ current_dim ] . lower_limit ;
* upper_limit = config - > dims [ current_dim ] . upper_limit ;
/* length needs to be -1, if we do not have a dynamic length array */
* length = - 1 ;
if ( config - > dims [ current_dim ] . length_of_length > 0 ) {
/* we are filling the length with number of bytes we found in the packet */
tmp = dissect_someip_payload_length_field ( tvb , pinfo , tree , offset , config - > dims [ current_dim ] . length_of_length ) ;
if ( tmp < 0 ) {
/* leave *length = -1 */
return config - > dims [ current_dim ] . length_of_length / 8 ;
}
* length = ( gint32 ) tmp ;
offset + = config - > dims [ current_dim ] . length_of_length / 8 ;
} else {
/* without a length field, the number of elements needs be fixed */
if ( config - > dims [ current_dim ] . lower_limit ! = config - > dims [ current_dim ] . upper_limit ) {
proto_tree_add_expert_format ( tree , pinfo , & ef_someip_payload_static_array_min_not_max , tvb , offset_orig , 0 ,
" Static array config with Min!=Max (%d, %d) " , config - > dims [ current_dim ] . lower_limit , config - > dims [ current_dim ] . upper_limit ) ;
col_append_str ( pinfo - > cinfo , COL_INFO , " [SOME/IP Payload: Static array config with Min!=Max!] " ) ;
return 0 ;
}
}
return offset - offset_orig ;
}
/* returns bits parsed, length needs to be gint to encode "non-existing" as -1 */
static gint
dissect_someip_payload_array_payload ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , gint offset_orig , gint length , gint lower_limit , gint upper_limit ,
someip_parameter_array_t * config ) {
tvbuff_t * subtvb = NULL ;
guint32 offset = offset_orig ;
guint32 offset_bits = 0 ;
guint32 bits_parsed = 0 ;
guint32 ret = 0 ;
gint count = 0 ;
if ( length ! = - 1 ) {
if ( length < = tvb_captured_length_remaining ( tvb , offset ) ) {
subtvb = tvb_new_subset_length_caplen ( tvb , offset , length , length ) ;
} else {
expert_someip_payload_truncated ( tree , pinfo , tvb , offset , tvb_captured_length_remaining ( tvb , offset ) ) ;
return tvb_captured_length_remaining ( tvb , offset ) ;
}
} else {
subtvb = tvb ;
}
/* created subtvb. so we set offset=0 */
offset = 0 ;
while ( ( length = = - 1 & & count < upper_limit ) | | ( ( gint ) ( 8 * offset + offset_bits ) < 8 * length ) ) {
bits_parsed = dissect_someip_payload_parameter ( subtvb , pinfo , tree , offset , offset_bits , ( guint8 ) config - > data_type , config - > id_ref , config - > name ) ;
if ( bits_parsed = = 0 ) {
return 1 ;
}
offset = ( 8 * offset + bits_parsed ) / 8 ;
offset_bits = ( 8 * offset + bits_parsed ) % 8 ;
count + + ;
}
if ( count < lower_limit & & count > upper_limit ) {
proto_tree_add_expert_format ( tree , pinfo , & ef_someip_payload_dyn_array_not_within_limit , tvb , offset_orig , length ,
" Number of items (%d) outside limit %d-%d " , count , lower_limit , upper_limit ) ;
col_append_str ( pinfo - > cinfo , COL_INFO , " [SOME/IP Payload: Dynamic array does not stay between Min and Max values] " ) ;
}
ret = 8 * offset + offset_bits ;
return ret ;
}
/* returns bits parsed */
static gint
dissect_someip_payload_array_dim ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , gint offset_orig , gint length , gint lower_limit , gint upper_limit , someip_parameter_array_t * config , guint current_dim , gchar * name ) {
proto_tree * subtree = NULL ;
gint sub_length = 0 ;
gint sub_lower_limit = 0 ;
gint sub_upper_limit = 0 ;
gint i = 0 ;
gint sub_offset = 0 ;
gint offset = offset_orig ;
gint offset_bits = 0 ;
gint ret = 0 ;
gint len_of_len = 0 ;
if ( config - > num_of_dims = = current_dim + 1 ) {
/* only payload left. :) */
offset_bits + = dissect_someip_payload_array_payload ( tvb , pinfo , tree , offset , length , lower_limit , upper_limit , config ) ;
} else {
if ( length ! = - 1 ) {
while ( offset < offset_orig + ( gint ) length ) {
sub_offset = offset ;
offset + = dissect_someip_payload_array_dim_length ( tvb , pinfo , tree , offset , & sub_length , & sub_lower_limit , & sub_upper_limit , config , current_dim + 1 ) ;
len_of_len = offset - sub_offset ;
if ( tvb_captured_length_remaining ( tvb , offset ) < ( gint ) sub_length ) {
expert_someip_payload_truncated ( tree , pinfo , tvb , offset , tvb_captured_length_remaining ( tvb , offset ) ) ;
return 0 ;
}
subtree = proto_tree_add_subtree_format ( tree , tvb , sub_offset , sub_length + len_of_len , ett_someip_array_dim , NULL , " subarray (dim: %d, limit %d-%d) " , current_dim + 1 , sub_lower_limit , sub_upper_limit ) ;
offset_bits + = dissect_someip_payload_array_dim ( tvb , pinfo , subtree , offset , sub_length , sub_lower_limit , sub_upper_limit , config , current_dim + 1 , name ) ;
offset = ( 8 * offset + offset_bits ) / 8 ;
offset_bits = ( 8 * offset + offset_bits ) % 8 ;
}
} else {
/* Multi-dim static array */
sub_lower_limit = config - > dims [ current_dim ] . lower_limit ;
sub_upper_limit = config - > dims [ current_dim ] . upper_limit ;
for ( i = 0 ; i < upper_limit ; i + + ) {
offset + = dissect_someip_payload_array_dim ( tvb , pinfo , tree , offset , - 1 , sub_lower_limit , sub_upper_limit , config , current_dim + 1 , name ) ;
}
}
}
ret = 8 * ( offset - offset_orig ) + ( offset_bits - 0 ) ;
return ret ;
}
static int
dissect_someip_payload_array ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , gint offset_orig , gint offset_bits_orig , guint32 id , gchar * name ) {
someip_parameter_array_t * config = NULL ;
proto_tree * subtree ;
gint offset = offset_orig ;
gint offset_bits = offset_bits_orig ;
gint length = 0 ;
gint lower_limit = 0 ;
gint upper_limit = 0 ;
config = get_array_config ( id ) ;
if ( config = = NULL ) {
return 0 ;
}
if ( config - > num_of_dims = = 0 | | config - > dims = = NULL ) {
expert_someip_payload_config_error ( tree , pinfo , tvb , offset , 0 , " Array config has not enough dimensions for this array! " ) ;
return 0 ;
}
if ( offset_bits_orig ! = 0 ) {
expert_someip_payload_alignment_error ( tree , pinfo , tvb , offset , 0 ) ;
return 0 ;
}
offset + = dissect_someip_payload_array_dim_length ( tvb , pinfo , tree , offset_orig , & length , & lower_limit , & upper_limit , config , 0 ) ;
if ( length ! = - 1 ) {
subtree = proto_tree_add_subtree_format ( tree , tvb , offset_orig , length + ( offset - offset_orig ) , ett_someip_array , NULL , " array %s (elements limit: %d-%d) " , name , lower_limit , upper_limit ) ;
} else {
subtree = proto_tree_add_subtree_format ( tree , tvb , offset_orig , length + ( offset - offset_orig ) , ett_someip_array , NULL , " array %s (elements limit: %d) " , name , upper_limit ) ;
}
offset_bits + = dissect_someip_payload_array_dim ( tvb , pinfo , subtree , offset , length , lower_limit , upper_limit , config , 0 , name ) ;
return 8 * ( length + ( offset - offset_orig ) ) + ( offset_bits - offset_bits_orig ) ;
}
static int
dissect_someip_payload_union ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , gint offset_orig , gint offset_bits_orig , guint32 id , gchar * name ) {
someip_parameter_union_t * config = NULL ;
someip_parameter_union_item_t * item = NULL ;
proto_tree * subtree = NULL ;
tvbuff_t * subtvb ;
gint buf_length = - 1 ;
gint64 tmp = 0 ;
guint32 length = 0 ;
guint32 type = 0 ;
guint32 i = 0 ;
gint offset = offset_orig ;
gint offset_bits = offset_bits_orig ;
config = get_union_config ( id ) ;
buf_length = tvb_captured_length_remaining ( tvb , 0 ) ;
if ( config = = NULL ) {
expert_someip_payload_config_error ( tree , pinfo , tvb , offset , 0 , " Union ID not configured " ) ;
return 0 ;
}
if ( offset_bits_orig ! = 0 ) {
expert_someip_payload_alignment_error ( tree , pinfo , tvb , offset_orig , 0 ) ;
return 0 ;
}
if ( ( config - > length_of_length + config - > length_of_type ) / 8 > ( guint ) buf_length - offset ) {
expert_someip_payload_truncated ( tree , pinfo , tvb , offset , tvb_captured_length_remaining ( tvb , offset ) ) ;
return 0 ;
}
subtree = proto_tree_add_subtree_format ( tree , tvb , offset_orig , offset - offset_orig + length , ett_someip_union , NULL , " union %s [%s] " , name , config - > name ) ;
tmp = dissect_someip_payload_length_field ( tvb , pinfo , subtree , offset_orig , config - > length_of_length ) ;
if ( tmp = = - 1 ) {
return 8 * ( offset - offset_orig ) + ( offset_bits - 0 ) ;
} else {
length = ( guint32 ) tmp ;
}
tmp = dissect_someip_payload_type_field ( tvb , pinfo , subtree , offset_orig + config - > length_of_length / 8 , config - > length_of_type ) ;
if ( tmp = = - 1 ) {
return 8 * ( offset - offset_orig ) + ( offset_bits - 0 ) ;
} else {
type = ( guint32 ) tmp ;
}
offset + = ( config - > length_of_length + config - > length_of_type ) / 8 ;
item = NULL ;
for ( i = 0 ; i < config - > num_of_items ; i + + ) {
if ( config - > items [ i ] . id = = type & & config - > items [ i ] . name ! = NULL ) {
item = & ( config - > items [ i ] ) ;
}
}
if ( item ! = NULL ) {
subtvb = tvb_new_subset_length_caplen ( tvb , offset , length , length ) ;
dissect_someip_payload_parameter ( subtvb , pinfo , subtree , 0 , 0 , ( guint8 ) item - > data_type , item - > id_ref , item - > name ) ;
} else {
expert_someip_payload_config_error ( tree , pinfo , tvb , offset , 0 , " Union type not configured " ) ;
}
/* there might be some padding present, if 8*length != bits_parsed */
return 8 * length + config - > length_of_type + config - > length_of_length ;
}
static int
dissect_someip_payload_parameter ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , gint offset , gint offset_bits , guint8 data_type , guint32 idref , gchar * name ) {
gint bits_parsed = 0 ;
switch ( data_type ) {
case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_TYPEDEF :
bits_parsed = dissect_someip_payload_typedef ( tvb , pinfo , tree , offset , offset_bits , idref , name ) ;
break ;
case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_BASE_TYPE :
case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ENUM :
bits_parsed = dissect_someip_payload_base_type ( tvb , pinfo , tree , offset , offset_bits , data_type , idref , name ) ;
break ;
case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_STRING :
bits_parsed = dissect_someip_payload_string ( tvb , pinfo , tree , offset , offset_bits , idref , name ) ;
break ;
case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ARRAY :
bits_parsed = dissect_someip_payload_array ( tvb , pinfo , tree , offset , offset_bits , idref , name ) ;
break ;
case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_STRUCT :
bits_parsed = dissect_someip_payload_struct ( tvb , pinfo , tree , offset , offset_bits , idref , name ) ;
break ;
case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_UNION :
bits_parsed = dissect_someip_payload_union ( tvb , pinfo , tree , offset , offset_bits , idref , name ) ;
break ;
default :
proto_tree_add_expert_format ( tree , pinfo , & ef_someip_payload_config_error , tvb , offset , 0 ,
" SOME/IP: Payload: item->data_type (0x%x) unknown/not implemented yet! name: %s, id_ref: 0x%x " ,
data_type , name , idref ) ;
col_append_str ( pinfo - > cinfo , COL_INFO , " [SOME/IP: Payload Config Error] " ) ;
break ;
}
return bits_parsed ;
}
static void
dissect_someip_payload ( tvbuff_t * tvb , packet_info * pinfo , proto_item * ti , guint16 serviceid , guint16 methodid , guint8 version , guint8 msgtype ) {
someip_parameter_list_t * paramlist = NULL ;
someip_payload_parameter_item_t * item = NULL ;
gint length = - 1 ;
gint offset = 0 ;
gint offset_bits = 0 ;
gint bits_parsed = 0 ;
proto_tree * tree = NULL ;
guint i = 0 ;
length = tvb_captured_length_remaining ( tvb , 0 ) ;
tree = proto_item_add_subtree ( ti , ett_someip_payload ) ;
paramlist = get_parameter_config ( serviceid , methodid , version , msgtype ) ;
if ( paramlist = = NULL ) {
return ;
}
for ( i = 0 ; i < paramlist - > num_of_items ; i + + ) {
item = & ( paramlist - > items [ i ] ) ;
bits_parsed = dissect_someip_payload_parameter ( tvb , pinfo , tree , offset , offset_bits , ( guint8 ) item - > data_type , item - > id_ref , item - > name ) ;
offset = ( 8 * offset + offset_bits + bits_parsed ) / 8 ;
offset_bits = ( 8 * offset + offset_bits + bits_parsed ) % 8 ;
}
if ( length > offset + 1 ) {
proto_tree_add_item ( tree , hf_payload_unparsed , tvb , offset + 1 , length - ( offset + 1 ) , ENC_NA ) ;
}
}
/***********************************
* * * * * * * * SOME / IP Dissector * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int
dissect_someip_message ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data _U_ ) {
guint32 offset = 0 ;
guint32 someip_messageid = 0 ;
guint32 someip_serviceid = 0 ;
guint32 someip_methodid = 0 ;
guint32 someip_sessionid = 0 ;
guint32 someip_length = 0 ;
const gchar * service_description = NULL ;
const gchar * method_description = NULL ;
guint32 someip_payload_length = 0 ;
tvbuff_t * subtvb = NULL ;
proto_item * ti = NULL ;
proto_item * ti_someip = NULL ;
proto_tree * someip_tree = NULL ;
proto_tree * msgtype_tree = NULL ;
guint32 protocol_version = 0 ;
guint32 version = 0 ;
guint32 msgtype = 0 ;
gboolean msgtype_ack = FALSE ;
gboolean msgtype_tp = FALSE ;
guint32 retcode = 0 ;
int tmp = 0 ;
gint tvb_length = tvb_captured_length_remaining ( tvb , offset ) ;
2020-06-19 01:14:46 +00:00
static int * const someip_tp_flags [ ] = {
2019-09-10 18:24:32 +00:00
& hf_someip_tp_reserved ,
& hf_someip_tp_more_segments ,
NULL
} ;
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , SOMEIP_NAME ) ;
col_set_str ( pinfo - > cinfo , COL_INFO , SOMEIP_NAME_LONG ) ;
ti_someip = proto_tree_add_item ( tree , proto_someip , tvb , offset , - 1 , ENC_NA ) ;
someip_tree = proto_item_add_subtree ( ti_someip , ett_someip ) ;
/* we should never get called with less than 8 bytes */
if ( tvb_length < 8 ) {
return tvb_length ;
}
/* Message ID = Service ID + Method ID*/
someip_messageid = tvb_get_ntohl ( tvb , 0 ) ;
ti = proto_tree_add_uint_format_value ( someip_tree , hf_someip_messageid , tvb , offset , 4 , someip_messageid , " 0x%08x " , someip_messageid ) ;
PROTO_ITEM_SET_HIDDEN ( ti ) ;
/* Service ID */
ti = proto_tree_add_item_ret_uint ( someip_tree , hf_someip_serviceid , tvb , offset , 2 , ENC_BIG_ENDIAN , & someip_serviceid ) ;
service_description = someip_lookup_service_name ( someip_serviceid ) ;
if ( service_description ! = NULL ) {
proto_item_append_text ( ti , " (%s) " , service_description ) ;
}
offset + = 2 ;
/* Method ID */
ti = proto_tree_add_item_ret_uint ( someip_tree , hf_someip_methodid , tvb , offset , 2 , ENC_BIG_ENDIAN , & someip_methodid ) ;
method_description = someip_lookup_method_name ( someip_serviceid , someip_methodid ) ;
if ( method_description ! = NULL ) {
proto_item_append_text ( ti , " (%s) " , method_description ) ;
}
offset + = 2 ;
/* Length */
proto_tree_add_item_ret_uint ( someip_tree , hf_someip_length , tvb , offset , 4 , ENC_BIG_ENDIAN , & someip_length ) ;
offset + = 4 ;
/* this checks if value of the header field */
if ( someip_length < 8 ) {
expert_add_info_format ( pinfo , ti_someip , & ef_someip_incomplete_headers , " %s " , " SOME/IP length too short (<8 Bytes)! " ) ;
return tvb_length ;
}
/* Add some additional info to the Protocol line and the Info Column*/
if ( service_description = = NULL ) {
col_add_fstr ( pinfo - > cinfo , COL_INFO , " %s (Service ID: 0x%04x, Method ID: 0x%04x, Length: %i) " ,
SOMEIP_NAME_LONG , someip_serviceid , someip_methodid , someip_length ) ;
} else if ( method_description = = NULL ) {
col_add_fstr ( pinfo - > cinfo , COL_INFO , " %s (Service ID: 0x%04x (%s), Method ID: 0x%04x, Length: %i) " ,
SOMEIP_NAME_LONG , someip_serviceid , service_description , someip_methodid , someip_length ) ;
} else {
col_add_fstr ( pinfo - > cinfo , COL_INFO , " %s (Service ID: 0x%04x (%s), Method ID: 0x%04x (%s), Length: %i) " ,
SOMEIP_NAME_LONG , someip_serviceid , service_description , someip_methodid , method_description , someip_length ) ;
}
proto_item_append_text ( ti_someip , " (Service ID: 0x%04x, Method ID: 0x%04x, Length: %i) " , someip_serviceid , someip_methodid , someip_length ) ;
/* check if we have bytes for the rest of the header */
if ( tvb_length < 0 | | offset + 8 > ( guint32 ) tvb_length ) {
expert_add_info_format ( pinfo , ti_someip , & ef_someip_incomplete_headers , " %s " , " SOME/IP not enough buffer bytes for header! " ) ;
return tvb_length ;
}
/* Client ID */
proto_tree_add_item ( someip_tree , hf_someip_clientid , tvb , offset , 2 , ENC_BIG_ENDIAN ) ;
offset + = 2 ;
/* Session ID */
proto_tree_add_item_ret_uint ( someip_tree , hf_someip_sessionid , tvb , offset , 2 , ENC_BIG_ENDIAN , & someip_sessionid ) ;
offset + = 2 ;
/* Protocol Version*/
ti = proto_tree_add_item_ret_uint ( someip_tree , hf_someip_protover , tvb , offset , 1 , ENC_BIG_ENDIAN , & protocol_version ) ;
if ( protocol_version ! = SOMEIP_PROTOCOL_VERSION ) {
expert_add_info ( pinfo , ti , & ef_someip_unknown_version ) ;
}
offset + = 1 ;
/* Major Version of Service Interface */
proto_tree_add_item_ret_uint ( someip_tree , hf_someip_interface_ver , tvb , offset , 1 , ENC_BIG_ENDIAN , & version ) ;
offset + = 1 ;
/* Message Type */
ti = proto_tree_add_item_ret_uint ( someip_tree , hf_someip_messagetype , tvb , offset , 1 , ENC_BIG_ENDIAN , & msgtype ) ;
msgtype_tree = proto_item_add_subtree ( ti , ett_someip_msgtype ) ;
proto_tree_add_item_ret_boolean ( msgtype_tree , hf_someip_messagetype_ack_flag , tvb , offset , 1 , ENC_BIG_ENDIAN , & msgtype_ack ) ;
proto_tree_add_item_ret_boolean ( msgtype_tree , hf_someip_messagetype_tp_flag , tvb , offset , 1 , ENC_BIG_ENDIAN , & msgtype_tp ) ;
proto_item_append_text ( ti , " (%s) " , val_to_str ( ( ~ SOMEIP_MSGTYPE_TP_MASK ) & msgtype , someip_msg_type , " Unknown Message Type " ) ) ;
if ( msgtype_tp ) {
proto_item_append_text ( ti , " (%s) " , SOMEIP_MSGTYPE_TP_STRING ) ;
}
offset + = 1 ;
/* Return Code */
ti = proto_tree_add_item_ret_uint ( someip_tree , hf_someip_returncode , tvb , offset , 1 , ENC_BIG_ENDIAN , & retcode ) ;
proto_item_append_text ( ti , " (%s) " , val_to_str ( retcode , someip_return_code , " Unknown Return Code " ) ) ;
offset + = 1 ;
/* lets figure out what we have for the rest */
if ( ( ( guint32 ) tvb_length > = ( someip_length + 8 ) ) ) {
someip_payload_length = someip_length - SOMEIP_HDR_PART1_LEN ;
} else {
someip_payload_length = tvb_length - SOMEIP_HDR_LEN ;
expert_add_info ( pinfo , ti_someip , & ef_someip_message_truncated ) ;
}
/* Is this a SOME/IP-TP segment? */
if ( msgtype_tp ) {
guint32 tp_offset = 0 ;
gboolean tp_more_segments = FALSE ;
gboolean update_col_info = TRUE ;
guint32 segment_key ;
fragment_item * someip_tp_head = NULL ;
proto_tree * tp_tree = NULL ;
ti = proto_tree_add_item ( someip_tree , hf_someip_tp , tvb , offset , someip_payload_length , ENC_NA ) ;
tp_tree = proto_item_add_subtree ( ti , ett_someip_tp ) ;
tp_offset = ( tvb_get_ntohl ( tvb , offset ) & SOMEIP_TP_OFFSET_MASK ) ;
tp_more_segments = ( ( tvb_get_ntohl ( tvb , offset ) & SOMEIP_TP_OFFSET_MASK_MORE_SEGMENTS ) ! = 0 ) ;
/* Why can I not mask an FT_UINT32 without it being shifted. :( . */
proto_tree_add_uint ( tp_tree , hf_someip_tp_offset , tvb , offset , 4 , tp_offset ) ;
proto_tree_add_bitmask_with_flags ( tp_tree , tvb , offset + 3 , hf_someip_tp_flags , ett_someip_tp_flags , someip_tp_flags , ENC_BIG_ENDIAN , BMT_NO_TFS | BMT_NO_INT ) ;
offset + = 4 ;
proto_tree_add_item ( tp_tree , hf_someip_payload , tvb , offset , someip_payload_length - SOMEIP_TP_HDR_LEN , ENC_NA ) ;
if ( someip_tp_reassemble & & tvb_bytes_exist ( tvb , offset , someip_payload_length - SOMEIP_TP_HDR_LEN ) ) {
segment_key = someip_messageid ^ ( version < < 24 ) ^ ( msgtype < < 16 ) ^ someip_sessionid ;
someip_tp_head = fragment_add_check ( & someip_tp_reassembly_table , tvb , offset , pinfo , segment_key ,
NULL , tp_offset , someip_payload_length - SOMEIP_TP_HDR_LEN , tp_more_segments ) ;
subtvb = process_reassembled_data ( tvb , offset , pinfo , " Reassembled SOME/IP-TP Segment " ,
someip_tp_head , & someip_tp_frag_items , & update_col_info , someip_tree ) ;
}
} else {
subtvb = tvb_new_subset_length_caplen ( tvb , SOMEIP_HDR_LEN , someip_payload_length , someip_payload_length ) ;
}
if ( subtvb ! = NULL ) {
tvb_length = tvb_captured_length_remaining ( subtvb , 0 ) ;
if ( tvb_length > 0 ) {
tmp = dissector_try_uint ( someip_dissector_table , someip_messageid , subtvb , pinfo , tree ) ;
/* if no subdissector was found, the generic payload dissector takes over. */
if ( tmp = = 0 ) {
ti = proto_tree_add_item ( someip_tree , hf_someip_payload , subtvb , 0 , tvb_length , ENC_NA ) ;
if ( someip_derserializer_activated ) {
dissect_someip_payload ( subtvb , pinfo , ti , ( guint16 ) someip_serviceid , ( guint16 ) someip_methodid , ( guint8 ) version , ( guint8 ) ( ~ SOMEIP_MSGTYPE_TP_MASK ) & msgtype ) ;
}
}
}
}
return SOMEIP_HDR_LEN + someip_payload_length ;
}
static guint
get_someip_message_len ( packet_info * pinfo _U_ , tvbuff_t * tvb , int offset , void * data _U_ ) {
return SOMEIP_HDR_PART1_LEN + ( guint ) tvb_get_ntohl ( tvb , offset + 4 ) ;
}
static int
dissect_someip_tcp ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data ) {
tcp_dissect_pdus ( tvb , pinfo , tree , TRUE , SOMEIP_HDR_PART1_LEN , get_someip_message_len , dissect_someip_message , data ) ;
return tvb_reported_length ( tvb ) ;
}
static int
dissect_someip_udp ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data ) {
return udp_dissect_pdus ( tvb , pinfo , tree , SOMEIP_HDR_PART1_LEN , NULL , get_someip_message_len , dissect_someip_message , data ) ;
}
static gboolean
test_someip ( packet_info * pinfo _U_ , tvbuff_t * tvb , int offset _U_ , void * data _U_ )
{
if ( tvb_captured_length ( tvb ) < SOMEIP_HDR_LEN ) {
return FALSE ;
}
if ( tvb_get_guint32 ( tvb , 4 , ENC_BIG_ENDIAN ) < 8 ) {
return FALSE ;
}
if ( ( tvb_get_guint8 ( tvb , 12 ) ) ! = SOMEIP_PROTOCOL_VERSION ) {
return FALSE ;
}
if ( ! try_val_to_str ( ( tvb_get_guint8 ( tvb , 14 ) & ~ SOMEIP_MSGTYPE_TP_MASK ) , someip_msg_type ) ) {
return FALSE ;
}
return TRUE ;
}
static gboolean
dissect_some_ip_heur_tcp ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data )
{
if ( test_someip ( pinfo , tvb , 0 , data ) ) {
tcp_dissect_pdus ( tvb , pinfo , tree , TRUE , SOMEIP_HDR_PART1_LEN , get_someip_message_len , dissect_someip_message , data ) ;
return TRUE ;
}
return FALSE ;
}
static gboolean
dissect_some_ip_heur_udp ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data )
{
udp_dissect_pdus ( tvb , pinfo , tree , SOMEIP_HDR_PART1_LEN , test_someip , get_someip_message_len , dissect_someip_message , data ) ;
return TRUE ;
}
void
proto_register_someip ( void ) {
module_t * someip_module ;
expert_module_t * expert_module_someip ;
uat_t * someip_service_uat ;
uat_t * someip_method_uat ;
uat_t * someip_eventgroup_uat ;
uat_t * someip_parameter_base_type_list_uat ;
uat_t * someip_parameter_strings_uat ;
uat_t * someip_parameter_typedefs_uat ;
uat_t * someip_parameter_list_uat ;
uat_t * someip_parameter_arrays_uat ;
uat_t * someip_parameter_structs_uat ;
uat_t * someip_parameter_unions_uat ;
uat_t * someip_parameter_enums_uat ;
/* data fields */
static hf_register_info hf [ ] = {
{ & hf_someip_serviceid ,
{ " Service ID " , " someip.serviceid " ,
FT_UINT16 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_someip_methodid ,
{ " Method ID " , " someip.methodid " ,
FT_UINT16 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_someip_messageid ,
{ " Message ID " , " someip.messageid " ,
FT_UINT32 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_someip_length ,
{ " Length " , " someip.length " ,
FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_someip_clientid ,
{ " Client ID " , " someip.clientid " ,
FT_UINT16 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_someip_sessionid ,
{ " Session ID " , " someip.sessionid " ,
FT_UINT16 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_someip_protover ,
{ " SOME/IP Version " , " someip.protoversion " ,
FT_UINT8 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_someip_interface_ver ,
{ " Interface Version " , " someip.interfaceversion " ,
FT_UINT8 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_someip_messagetype ,
{ " Message Type " , " someip.messagetype " ,
FT_UINT8 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_someip_messagetype_ack_flag ,
{ " Message Type Ack Flag " , " someip.messagetype.ack " ,
FT_BOOLEAN , 8 , NULL , SOMEIP_MSGTYPE_ACK_MASK , NULL , HFILL } } ,
{ & hf_someip_messagetype_tp_flag ,
{ " Message Type TP Flag " , " someip.messagetype.tp " ,
FT_BOOLEAN , 8 , NULL , SOMEIP_MSGTYPE_TP_MASK , NULL , HFILL } } ,
{ & hf_someip_returncode ,
{ " Return Code " , " someip.returncode " ,
FT_UINT8 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_someip_payload ,
{ " Payload " , " someip.payload " ,
FT_BYTES , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_someip_tp ,
{ " SOME/IP-TP " , " someip.tp " ,
FT_BYTES , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_someip_tp_offset ,
{ " Offset " , " someip.tp.offset " ,
FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_someip_tp_flags ,
{ " Flags " , " someip.tp.flags " ,
FT_UINT8 , BASE_HEX , NULL , SOMEIP_TP_OFFSET_MASK_FLAGS , NULL , HFILL } } ,
{ & hf_someip_tp_reserved ,
{ " Reserved " , " someip.tp.flags.reserved " ,
FT_UINT8 , BASE_HEX , NULL , SOMEIP_TP_OFFSET_MASK_RESERVED , NULL , HFILL } } ,
{ & hf_someip_tp_more_segments ,
{ " More Segments " , " someip.tp.flags.more_segments " ,
FT_BOOLEAN , 8 , NULL , SOMEIP_TP_OFFSET_MASK_MORE_SEGMENTS , NULL , HFILL } } ,
{ & hf_someip_tp_fragments ,
{ " SOME/IP-TP segments " , " someip.tp.fragments " ,
FT_NONE , BASE_NONE , NULL , 0x00 , NULL , HFILL } } ,
{ & hf_someip_tp_fragment ,
{ " SOME/IP-TP segment " , " someip.tp.fragment " ,
FT_FRAMENUM , BASE_NONE , NULL , 0x00 , NULL , HFILL } } ,
{ & hf_someip_tp_fragment_overlap ,
{ " SOME/IP-TP segment overlap " , " someip.tp.fragment.overlap " ,
FT_BOOLEAN , 0 , NULL , 0x00 , NULL , HFILL } } ,
{ & hf_someip_tp_fragment_overlap_conflicts ,
{ " SOME/IP-TP segment overlapping with conflicting data " , " someip.tp.fragment.overlap.conflicts " ,
FT_BOOLEAN , 0 , NULL , 0x00 , NULL , HFILL } } ,
{ & hf_someip_tp_fragment_multiple_tails ,
{ " SOME/IP-TP Message has multiple tail fragments " , " someip.tp.fragment.multiple_tails " ,
FT_BOOLEAN , 0 , NULL , 0x00 , NULL , HFILL } } ,
{ & hf_someip_tp_fragment_too_long_fragment ,
{ " SOME/IP-TP segment too long " , " someip.tp.fragment.too_long_fragment " ,
FT_BOOLEAN , 0 , NULL , 0x00 , NULL , HFILL } } ,
{ & hf_someip_tp_fragment_error ,
{ " SOME/IP-TP Message defragmentation error " , " someip.tp.fragment.error " ,
FT_FRAMENUM , BASE_NONE , NULL , 0x00 , NULL , HFILL } } ,
{ & hf_someip_tp_fragment_count ,
{ " SOME/IP-TP segment count " , " someip.tp.fragment.count " ,
FT_UINT32 , BASE_DEC , NULL , 0x00 , NULL , HFILL } } ,
{ & hf_someip_tp_reassembled_in ,
{ " Reassembled in " , " someip.tp.reassembled.in " ,
FT_FRAMENUM , BASE_NONE , NULL , 0x00 , NULL , HFILL } } ,
{ & hf_someip_tp_reassembled_length ,
{ " Reassembled length " , " someip.tp.reassembled.length " ,
FT_UINT32 , BASE_DEC , NULL , 0x00 , NULL , HFILL } } ,
{ & hf_someip_tp_reassembled_data ,
{ " Reassembled data " , " someip.tp.reassembled.data " ,
FT_BYTES , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_payload_unparsed ,
{ " Unparsed Payload " , " someip.payload.unparsed " ,
FT_BYTES , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_payload_length_field_8bit ,
{ " Length " , " someip.payload.length " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_payload_length_field_16bit ,
{ " Length " , " someip.payload.length " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_payload_length_field_32bit ,
{ " Length " , " someip.payload.length " ,
FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_payload_type_field_8bit ,
{ " Type " , " someip.payload.type " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_payload_type_field_16bit ,
{ " Type " , " someip.payload.type " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_payload_type_field_32bit ,
{ " Type " , " someip.payload.type " ,
FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_payload_str_base , {
" (base) " , " someip.payload.base " ,
FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_payload_str_string , {
" (string) " , " someip.payload.string " ,
FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_payload_str_struct , {
" (struct) " , " someip.payload.struct " ,
FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
} ;
static gint * ett [ ] = {
& ett_someip ,
& ett_someip_msgtype ,
& ett_someip_tp ,
& ett_someip_tp_flags ,
& ett_someip_tp_fragment ,
& ett_someip_tp_fragments ,
& ett_someip_payload ,
& ett_someip_string ,
& ett_someip_array ,
& ett_someip_array_dim ,
& ett_someip_struct ,
& ett_someip_union ,
} ;
/* UATs for user_data fields */
static uat_field_t someip_service_uat_fields [ ] = {
UAT_FLD_HEX ( someip_service_ident , id , " Service ID " , " ID of the SOME/IP Service (16bit hex without leading 0x) " ) ,
UAT_FLD_CSTRING ( someip_service_ident , name , " Service Name " , " Name of the SOME/IP Service (string) " ) ,
UAT_END_FIELDS
} ;
static uat_field_t someip_method_uat_fields [ ] = {
UAT_FLD_HEX ( someip_method_ident , id , " Service ID " , " ID of the SOME/IP Service (16bit hex without leading 0x) " ) ,
UAT_FLD_HEX ( someip_method_ident , id2 , " Methods ID " , " ID of the SOME/IP Method/Event/Notifier (16bit hex without leading 0x) " ) ,
UAT_FLD_CSTRING ( someip_method_ident , name , " Method Name " , " Name of the SOME/IP Method/Event/Notifier (string) " ) ,
UAT_END_FIELDS
} ;
static uat_field_t someip_eventgroup_uat_fields [ ] = {
UAT_FLD_HEX ( someip_eventgroup_ident , id , " Service ID " , " ID of the SOME/IP Service (16bit hex without leading 0x) " ) ,
UAT_FLD_HEX ( someip_eventgroup_ident , id2 , " Eventgroup ID " , " ID of the SOME/IP Eventgroup (16bit hex without leading 0x) " ) ,
UAT_FLD_CSTRING ( someip_eventgroup_ident , name , " Eventgroup Name " , " Name of the SOME/IP Service (string) " ) ,
UAT_END_FIELDS
} ;
static uat_field_t someip_parameter_list_uat_fields [ ] = {
UAT_FLD_HEX ( someip_parameter_list , service_id , " Service ID " , " ID of the SOME/IP Service (16bit hex without leading 0x) " ) ,
UAT_FLD_HEX ( someip_parameter_list , method_id , " Method ID " , " ID of the SOME/IP Method/Event/Notifier (16bit hex without leading 0x) " ) ,
UAT_FLD_DEC ( someip_parameter_list , version , " Version " , " Version of the SOME/IP Service (8bit dec) " ) ,
UAT_FLD_HEX ( someip_parameter_list , message_type , " Message Type " , " Message Type (8bit hex without leading 0x) " ) ,
UAT_FLD_DEC ( someip_parameter_list , num_of_params , " Number of Parameter " , " Number of Parameters (16bit dec) " ) ,
UAT_FLD_DEC ( someip_parameter_list , pos , " Parameter Position " , " Position of parameter (16bit dec, starting with 0) " ) ,
UAT_FLD_CSTRING ( someip_parameter_list , name , " Parameter Name " , " Name of parameter (string) " ) ,
UAT_FLD_DEC ( someip_parameter_list , data_type , " Parameter Type " , " Type of parameter (1: base, 2: string, 3: array, 4: struct, 5: union, 6: typedef, 7: enum) " ) ,
UAT_FLD_HEX ( someip_parameter_list , id_ref , " ID Reference " , " ID Reference (32bit hex) " ) ,
UAT_END_FIELDS
} ;
static uat_field_t someip_parameter_array_uat_fields [ ] = {
UAT_FLD_HEX ( someip_parameter_arrays , id , " ID " , " ID of SOME/IP array (32bit hex without leading 0x) " ) ,
UAT_FLD_CSTRING ( someip_parameter_arrays , name , " Array Name " , " Name of array " ) ,
UAT_FLD_DEC ( someip_parameter_arrays , data_type , " Parameter Type " , " Type of parameter (1: base, 2: string, 3: array, 4: struct, 5: union, 6: typedef, 7: enum) " ) ,
UAT_FLD_HEX ( someip_parameter_arrays , id_ref , " ID Reference " , " ID Reference (32bit hex) " ) ,
UAT_FLD_DEC ( someip_parameter_arrays , num_of_dims , " Number of Items " , " Number of Dimensions (16bit dec) " ) ,
UAT_FLD_DEC ( someip_parameter_arrays , num , " Dimension " , " Dimension (16bit dec, starting with 0) " ) ,
UAT_FLD_DEC ( someip_parameter_arrays , lower_limit , " Lower Limit " , " Dimension (32bit dec) " ) ,
UAT_FLD_DEC ( someip_parameter_arrays , upper_limit , " Upper Limit " , " Dimension (32bit dec) " ) ,
UAT_FLD_DEC ( someip_parameter_arrays , length_of_length , " Length of Length Field " , " Version of the SOME/IP Service (8bit dec) " ) ,
2020-08-31 17:37:12 +00:00
UAT_FLD_DEC ( someip_parameter_arrays , pad_to , " Pad to " , " Padding pads to reach alignment (8bit dec) " ) ,
2019-09-10 18:24:32 +00:00
UAT_END_FIELDS
} ;
static uat_field_t someip_parameter_struct_uat_fields [ ] = {
UAT_FLD_HEX ( someip_parameter_structs , id , " ID " , " ID of SOME/IP struct (32bit hex without leading 0x) " ) ,
UAT_FLD_CSTRING ( someip_parameter_structs , struct_name , " Struct Name " , " Name of struct " ) ,
UAT_FLD_DEC ( someip_parameter_structs , length_of_length , " Length of Length Field " , " Length of the strcuts length field (8bit dec) " ) ,
2020-08-31 17:37:12 +00:00
UAT_FLD_DEC ( someip_parameter_structs , pad_to , " Pad to " , " Padding pads to reach alignment (8bit dec) " ) ,
2019-09-10 18:24:32 +00:00
UAT_FLD_DEC ( someip_parameter_structs , num_of_items , " Number of Items " , " Number of Items (16bit dec) " ) ,
UAT_FLD_DEC ( someip_parameter_structs , pos , " Parameter Position " , " Position of parameter (16bit dec, starting with 0) " ) ,
UAT_FLD_CSTRING ( someip_parameter_structs , name , " Parameter Name " , " Name of parameter (string) " ) ,
UAT_FLD_DEC ( someip_parameter_structs , data_type , " Parameter Type " , " Type of parameter (1: base, 2: string, 3: array, 4: struct, 5: union, 6: typedef, 7: enum) " ) ,
UAT_FLD_HEX ( someip_parameter_structs , id_ref , " ID Reference " , " ID Reference (32bit hex) " ) ,
UAT_END_FIELDS
} ;
static uat_field_t someip_parameter_union_uat_fields [ ] = {
UAT_FLD_HEX ( someip_parameter_unions , id , " ID " , " ID of SOME/IP union (32bit hex without leading 0x) " ) ,
UAT_FLD_CSTRING ( someip_parameter_unions , name , " Union Name " , " Name of union " ) ,
UAT_FLD_DEC ( someip_parameter_unions , length_of_length , " Length of Length Field " , " Length of the unions length field (uint8 dec) " ) ,
UAT_FLD_DEC ( someip_parameter_unions , length_of_type , " Length of Type Field " , " Length of the unions type field (8bit dec) " ) ,
2020-08-31 17:37:12 +00:00
UAT_FLD_DEC ( someip_parameter_unions , pad_to , " Pad to " , " Padding pads to reach alignment (8bit dec) " ) ,
2019-09-10 18:24:32 +00:00
UAT_FLD_DEC ( someip_parameter_unions , num_of_items , " Number of Items " , " Number of Items (32bit dec) " ) ,
UAT_FLD_DEC ( someip_parameter_unions , type_id , " Type ID " , " ID of Type (32bit dec, starting with 0) " ) ,
UAT_FLD_CSTRING ( someip_parameter_unions , type_name , " Type Name " , " Name of Type (string) " ) ,
UAT_FLD_DEC ( someip_parameter_unions , data_type , " Data Type " , " Type of payload (1: base, 2: string, 3: array, 4: struct, 5: union, 6: typedef, 7: enum) " ) ,
UAT_FLD_HEX ( someip_parameter_unions , id_ref , " ID Reference " , " ID Reference (32bit hex) " ) ,
UAT_END_FIELDS
} ;
static uat_field_t someip_parameter_enum_uat_fields [ ] = {
UAT_FLD_HEX ( someip_parameter_enums , id , " ID " , " ID of SOME/IP enum (32bit hex without leading 0x) " ) ,
UAT_FLD_CSTRING ( someip_parameter_enums , name , " Name " , " Name of Enumeration (string) " ) ,
UAT_FLD_DEC ( someip_parameter_enums , data_type , " Parameter Type " , " Type of parameter (dec) " ) ,
UAT_FLD_HEX ( someip_parameter_enums , id_ref , " ID Reference " , " ID Reference (32bit hex) " ) ,
UAT_FLD_DEC ( someip_parameter_enums , num_of_items , " Number of Items " , " Number of Items (32bit dec) " ) ,
UAT_FLD_HEX ( someip_parameter_enums , value , " Value " , " Value (64bit uint hex) " ) ,
UAT_FLD_CSTRING ( someip_parameter_enums , value_name , " Value Name " , " Name (string) " ) ,
UAT_END_FIELDS
} ;
static uat_field_t someip_parameter_base_type_list_uat_fields [ ] = {
UAT_FLD_HEX ( someip_parameter_base_type_list , id , " ID " , " ID (32bit hex) " ) ,
UAT_FLD_CSTRING ( someip_parameter_base_type_list , name , " Name " , " Name of type (string) " ) ,
UAT_FLD_CSTRING ( someip_parameter_base_type_list , data_type , " Data Type " , " Data type (string) " ) ,
UAT_FLD_DEC ( someip_parameter_base_type_list , big_endian , " Big Endian " , " Encoded Big Endian 0=no 1=yes " ) ,
UAT_FLD_DEC ( someip_parameter_base_type_list , bitlength_base_type , " Bitlength base type " , " Bitlength base type (uint32 dec) " ) ,
UAT_FLD_DEC ( someip_parameter_base_type_list , bitlength_encoded_type , " Bitlength enc. type " , " Bitlength encoded type (uint32 dec) " ) ,
UAT_END_FIELDS
} ;
static uat_field_t someip_parameter_string_list_uat_fields [ ] = {
UAT_FLD_HEX ( someip_parameter_strings , id , " ID " , " ID (32bit hex) " ) ,
UAT_FLD_CSTRING ( someip_parameter_strings , name , " Name " , " Name of string (string) " ) ,
UAT_FLD_CSTRING ( someip_parameter_strings , encoding , " Encoding " , " String Encoding (ascii, utf-8, utf-16) " ) ,
UAT_FLD_DEC ( someip_parameter_strings , dynamic_length , " Dynamic Length " , " Dynamic length of string 0=no 1=yes " ) ,
UAT_FLD_DEC ( someip_parameter_strings , max_length , " Max. Length " , " Maximum length/Length (uint32 dec) " ) ,
UAT_FLD_DEC ( someip_parameter_strings , length_of_length , " Length of Len Field " , " Length of the length field (uint8 dec) " ) ,
UAT_FLD_DEC ( someip_parameter_strings , big_endian , " Big Endian " , " Encoded Big Endian 0=no 1=yes " ) ,
2020-08-31 17:37:12 +00:00
UAT_FLD_DEC ( someip_parameter_strings , pad_to , " Pad to " , " Padding pads to reach alignment (8bit dec) " ) ,
2019-09-10 18:24:32 +00:00
UAT_END_FIELDS
} ;
static uat_field_t someip_parameter_typedef_list_uat_fields [ ] = {
UAT_FLD_HEX ( someip_parameter_typedefs , id , " ID " , " ID (32bit hex) " ) ,
UAT_FLD_CSTRING ( someip_parameter_typedefs , name , " Name " , " Name of typedef (string) " ) ,
UAT_FLD_DEC ( someip_parameter_typedefs , data_type , " Data Type " , " Type referenced item (1: base, 2: string, 3: array, 4: struct, 5: union, 6: typedef, 7: enum) " ) ,
UAT_FLD_HEX ( someip_parameter_typedefs , id_ref , " ID Reference " , " ID Reference (32bit hex) " ) ,
UAT_END_FIELDS
} ;
static ei_register_info ei [ ] = {
{ & ef_someip_unknown_version , { " someip.unknown_protocol_version " ,
PI_PROTOCOL , PI_WARN , " SOME/IP Unknown Protocol Version! " , EXPFILL } } ,
{ & ef_someip_message_truncated , { " someip.message_truncated " ,
PI_MALFORMED , PI_ERROR , " SOME/IP Truncated message! " , EXPFILL } } ,
{ & ef_someip_incomplete_headers , { " someip.incomplete_headers " ,
PI_MALFORMED , PI_ERROR , " SOME/IP Incomplete headers or some bytes left over! " , EXPFILL } } ,
{ & ef_someip_payload_truncated , { " someip.payload.expert_truncated " ,
PI_MALFORMED , PI_ERROR , " SOME/IP Payload: Truncated payload! " , EXPFILL } } ,
2020-04-10 15:28:05 +00:00
{ & ef_someip_payload_malformed , { " someip.payload.expert_malformed " ,
PI_MALFORMED , PI_ERROR , " SOME/IP Payload: Malformed payload! " , EXPFILL } } ,
2019-09-10 18:24:32 +00:00
{ & ef_someip_payload_config_error , { " someip.payload.expert_config_error " ,
PI_MALFORMED , PI_ERROR , " SOME/IP Payload: Config Error! " , EXPFILL } } ,
{ & ef_someip_payload_alignment_error , { " someip.payload.expert_alignment_error " ,
PI_MALFORMED , PI_ERROR , " SOME/IP Payload: SOME/IP datatype must be align to a byte! " , EXPFILL } } ,
{ & ef_someip_payload_static_array_min_not_max , { " someip.payload.expert_static_array_min_max " ,
PI_MALFORMED , PI_ERROR , " SOME/IP Payload: Static array with min!=max! " , EXPFILL } } ,
{ & ef_someip_payload_dyn_array_not_within_limit , { " someip.payload.expert_dyn_array_not_within_limit " ,
PI_MALFORMED , PI_WARN , " SOME/IP Payload: Dynamic array does not stay between Min and Max values! " , EXPFILL } } ,
} ;
/* Register ETTs */
proto_someip = proto_register_protocol ( SOMEIP_NAME_LONG , SOMEIP_NAME , SOMEIP_NAME_FILTER ) ;
proto_register_field_array ( proto_someip , hf , array_length ( hf ) ) ;
proto_register_subtree_array ( ett , array_length ( ett ) ) ;
expert_module_someip = expert_register_protocol ( proto_someip ) ;
expert_register_field_array ( expert_module_someip , ei , array_length ( ei ) ) ;
someip_dissector_table = register_dissector_table ( " someip.messageid " , " SOME/IP Message ID " , proto_someip , FT_UINT32 , BASE_HEX ) ;
/* init for SOME/IP-TP */
reassembly_table_init ( & someip_tp_reassembly_table , & addresses_ports_reassembly_table_functions ) ;
/* Register preferences */
someip_module = prefs_register_protocol ( proto_someip , & proto_reg_handoff_someip ) ;
range_convert_str ( wmem_epan_scope ( ) , & someip_ports_udp , " " , 65535 ) ;
prefs_register_range_preference ( someip_module , " ports.udp " , " UDP Ports " ,
" SOME/IP Port Ranges UDP. " ,
& someip_ports_udp , 65535 ) ;
range_convert_str ( wmem_epan_scope ( ) , & someip_ports_tcp , " " , 65535 ) ;
prefs_register_range_preference ( someip_module , " ports.tcp " , " TCP Ports " ,
" SOME/IP Port Ranges TCP. " ,
& someip_ports_tcp , 65535 ) ;
/* UATs */
someip_service_uat = uat_new ( " SOME/IP Services " ,
sizeof ( generic_one_id_string_t ) , /* record size */
DATAFILE_SOMEIP_SERVICES , /* filename */
TRUE , /* from profile */
( void * * ) & someip_service_ident , /* data_ptr */
& someip_service_ident_num , /* numitems_ptr */
UAT_AFFECTS_DISSECTION , /* but not fields */
NULL , /* help */
copy_generic_one_id_string_cb , /* copy callback */
update_generic_one_identifier_16bit , /* update callback */
free_generic_one_id_string_cb , /* free callback */
post_update_someip_service_cb , /* post update callback */
NULL , /* reset callback */
someip_service_uat_fields /* UAT field definitions */
) ;
prefs_register_uat_preference ( someip_module , " services " , " SOME/IP Services " ,
" A table to define names of SOME/IP services " , someip_service_uat ) ;
someip_method_uat = uat_new ( " SOME/IP Methods/Events/Fields " ,
sizeof ( generic_two_id_string_t ) , /* record size */
DATAFILE_SOMEIP_METHODS , /* record size */
TRUE , /* from profile */
( void * * ) & someip_method_ident , /* data_ptr */
& someip_method_ident_num , /* numitems_ptr */
UAT_AFFECTS_DISSECTION , /* but not fields */
NULL , /* help */
copy_generic_two_id_string_cb , /* copy callback */
update_generic_two_identifier_16bit , /* update callback */
free_generic_two_id_string_cb , /* free callback */
post_update_someip_method_cb , /* post update callback */
NULL , /* reset callback */
someip_method_uat_fields /* UAT field definitions */
) ;
prefs_register_uat_preference ( someip_module , " methods " , " SOME/IP Methods " ,
" A table to define names of SOME/IP methods " , someip_method_uat ) ;
someip_eventgroup_uat = uat_new ( " SOME/IP Eventgroups " ,
sizeof ( generic_two_id_string_t ) , /* record size */
DATAFILE_SOMEIP_EVENTGROUPS , /* record size */
TRUE , /* from profile */
( void * * ) & someip_eventgroup_ident , /* data_ptr */
& someip_eventgroup_ident_num , /* numitems_ptr */
UAT_AFFECTS_DISSECTION , /* but not fields */
NULL , /* help */
copy_generic_two_id_string_cb , /* copy callback */
update_generic_two_identifier_16bit , /* update callback */
free_generic_two_id_string_cb , /* free callback */
post_update_someip_eventgroup_cb , /* post update callback */
NULL , /* reset callback */
someip_eventgroup_uat_fields /* UAT field definitions */
) ;
prefs_register_uat_preference ( someip_module , " eventgroups " , " SOME/IP Eventgroups " ,
" A table to define names of SOME/IP eventgroups " , someip_eventgroup_uat ) ;
someip_parameter_list_uat = uat_new ( " SOME/IP Parameter List " ,
sizeof ( someip_parameter_list_uat_t ) , DATAFILE_SOMEIP_PARAMETERS , TRUE ,
( void * * ) & someip_parameter_list ,
& someip_parameter_list_num ,
UAT_AFFECTS_DISSECTION ,
NULL , /* help */
copy_someip_parameter_list_cb ,
update_someip_parameter_list ,
free_someip_parameter_list_cb ,
post_update_someip_parameter_list_cb ,
NULL , /* reset */
someip_parameter_list_uat_fields
) ;
prefs_register_bool_preference ( someip_module , " reassemble_tp " , " Reassemble SOME/IP-TP " ,
" Reassemble SOME/IP-TP segments " , & someip_tp_reassemble ) ;
prefs_register_bool_preference ( someip_module , " payload_dissector_activated " ,
" Dissect Payload " ,
" Should the SOME/IP Dissector use the payload dissector? " ,
& someip_derserializer_activated ) ;
prefs_register_uat_preference ( someip_module , " _someip_parameter_list " , " SOME/IP Parameter List " ,
" A table to define names of SOME/IP parameters " , someip_parameter_list_uat ) ;
someip_parameter_arrays_uat = uat_new ( " SOME/IP Parameter Arrays " ,
sizeof ( someip_parameter_array_uat_t ) , DATAFILE_SOMEIP_ARRAYS , TRUE ,
( void * * ) & someip_parameter_arrays ,
& someip_parameter_arrays_num ,
UAT_AFFECTS_DISSECTION ,
NULL , /* help */
copy_someip_parameter_array_cb ,
update_someip_parameter_array ,
free_someip_parameter_array_cb ,
post_update_someip_parameter_array_cb ,
NULL , /* reset */
someip_parameter_array_uat_fields
) ;
prefs_register_uat_preference ( someip_module , " _someip_parameter_arrays " , " SOME/IP Parameter Arrays " ,
" A table to define arrays used by SOME/IP " , someip_parameter_arrays_uat ) ;
someip_parameter_structs_uat = uat_new ( " SOME/IP Parameter Structs " ,
sizeof ( someip_parameter_struct_uat_t ) , DATAFILE_SOMEIP_STRUCTS , TRUE ,
( void * * ) & someip_parameter_structs ,
& someip_parameter_structs_num ,
UAT_AFFECTS_DISSECTION ,
NULL , /* help */
copy_someip_parameter_struct_cb ,
update_someip_parameter_struct ,
free_someip_parameter_struct_cb ,
post_update_someip_parameter_struct_cb ,
NULL , /* reset */
someip_parameter_struct_uat_fields
) ;
prefs_register_uat_preference ( someip_module , " _someip_parameter_structs " , " SOME/IP Parameter Structs " ,
" A table to define structs used by SOME/IP " , someip_parameter_structs_uat ) ;
someip_parameter_unions_uat = uat_new ( " SOME/IP Parameter Unions " ,
sizeof ( someip_parameter_union_uat_t ) , DATAFILE_SOMEIP_UNIONS , TRUE ,
( void * * ) & someip_parameter_unions ,
& someip_parameter_unions_num ,
UAT_AFFECTS_DISSECTION ,
NULL , /* help */
copy_someip_parameter_union_cb ,
update_someip_parameter_union ,
free_someip_parameter_union_cb ,
post_update_someip_parameter_union_cb ,
NULL , /* reset */
someip_parameter_union_uat_fields
) ;
prefs_register_uat_preference ( someip_module , " _someip_parameter_unions " , " SOME/IP Parameter Unions " ,
" A table to define unions used by SOME/IP " , someip_parameter_unions_uat ) ;
someip_parameter_enums_uat = uat_new ( " SOME/IP Parameter Enums " ,
sizeof ( someip_parameter_enum_uat_t ) , DATAFILE_SOMEIP_ENUMS , TRUE ,
( void * * ) & someip_parameter_enums ,
& someip_parameter_enums_num ,
UAT_AFFECTS_DISSECTION ,
NULL , /* help */
copy_someip_parameter_enum_cb ,
update_someip_parameter_enum ,
free_someip_parameter_enum_cb ,
post_update_someip_parameter_enum_cb ,
NULL , /* reset */
someip_parameter_enum_uat_fields
) ;
prefs_register_uat_preference ( someip_module , " _someip_parameter_enums " , " SOME/IP Parameter Enums " ,
" A table to define enumerations used by SOME/IP " , someip_parameter_enums_uat ) ;
someip_parameter_base_type_list_uat = uat_new ( " SOME/IP Parameter Base Type List " ,
sizeof ( someip_parameter_base_type_list_uat_t ) , DATAFILE_SOMEIP_BASE_TYPES , TRUE ,
( void * * ) & someip_parameter_base_type_list ,
& someip_parameter_base_type_list_num ,
UAT_AFFECTS_DISSECTION ,
NULL , /* help */
copy_someip_parameter_base_type_list_cb ,
update_someip_parameter_base_type_list ,
free_someip_parameter_base_type_list_cb ,
post_update_someip_parameter_base_type_list_cb ,
NULL , /* reset */
someip_parameter_base_type_list_uat_fields
) ;
prefs_register_uat_preference ( someip_module , " _someip_parameter_base_type_list " , " SOME/IP Parameter Base Type List " ,
" A table to define base types of SOME/IP parameters " , someip_parameter_base_type_list_uat ) ;
someip_parameter_strings_uat = uat_new ( " SOME/IP Parameter String List " ,
sizeof ( someip_parameter_string_uat_t ) , DATAFILE_SOMEIP_STRINGS , TRUE ,
( void * * ) & someip_parameter_strings ,
& someip_parameter_strings_num ,
UAT_AFFECTS_DISSECTION ,
NULL , /* help */
copy_someip_parameter_string_list_cb ,
update_someip_parameter_string_list ,
free_someip_parameter_string_list_cb ,
post_update_someip_parameter_string_list_cb ,
NULL , /* reset */
someip_parameter_string_list_uat_fields
) ;
prefs_register_uat_preference ( someip_module , " _someip_parameter_string_list " , " SOME/IP Parameter String List " ,
" A table to define strings parameters " , someip_parameter_strings_uat ) ;
someip_parameter_typedefs_uat = uat_new ( " SOME/IP Parameter Typedef List " ,
sizeof ( someip_parameter_typedef_uat_t ) , DATAFILE_SOMEIP_TYPEDEFS , TRUE ,
( void * * ) & someip_parameter_typedefs ,
& someip_parameter_typedefs_num ,
UAT_AFFECTS_DISSECTION ,
NULL , /* help */
copy_someip_parameter_typedef_list_cb ,
update_someip_parameter_typedef_list ,
free_someip_parameter_typedef_list_cb ,
post_update_someip_parameter_typedef_list_cb ,
NULL , /* reset */
someip_parameter_typedef_list_uat_fields
) ;
prefs_register_uat_preference ( someip_module , " _someip_parameter_typedef_list " , " SOME/IP Parameter Typedef List " ,
" A table to define typedefs " , someip_parameter_typedefs_uat ) ;
}
void
proto_reg_handoff_someip ( void ) {
static gboolean initialized = FALSE ;
if ( ! initialized ) {
someip_handle_udp = create_dissector_handle ( dissect_someip_udp , proto_someip ) ;
someip_handle_tcp = create_dissector_handle ( dissect_someip_tcp , proto_someip ) ;
2019-12-01 03:01:41 +00:00
heur_dissector_add ( " udp " , dissect_some_ip_heur_udp , " SOME/IP_UDP_Heuristic " , " someip_udp_heur " , proto_someip , HEURISTIC_DISABLE ) ;
heur_dissector_add ( " tcp " , dissect_some_ip_heur_tcp , " SOME/IP_TCP_Heuristic " , " someip_tcp_heur " , proto_someip , HEURISTIC_DISABLE ) ;
2019-09-10 18:24:32 +00:00
initialized = TRUE ;
} else {
/* delete all my ports even the dynamically registered ones */
dissector_delete_all ( " udp.port " , someip_handle_tcp ) ;
dissector_delete_all ( " tcp.port " , someip_handle_tcp ) ;
}
dissector_add_uint_range ( " udp.port " , someip_ports_udp , someip_handle_udp ) ;
dissector_add_uint_range ( " tcp.port " , someip_ports_tcp , someip_handle_tcp ) ;
}
/*
* Editor modelines
*
* Local Variables :
* c - basic - offset : 4
* tab - width : 8
* indent - tabs - mode : nil
* End :
*
* ex : set shiftwidth = 4 tabstop = 8 expandtab :
* : indentSize = 4 : tabSize = 8 : noTabs = true :
*/