3 * By Dr. Lars Voelker <lars.voelker@technica-engineering.de> / <lars.voelker@bmw.de>
4 * Copyright 2012-2024 Dr. Lars Voelker
5 * Copyright 2019 Ana Pantar
6 * Copyright 2019 Guenter Ebermann
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
17 #include <epan/packet.h>
18 #include <epan/prefs.h>
19 #include <epan/expert.h>
20 #include <epan/to_str.h>
22 #include "packet-tcp.h"
23 #include <epan/reassemble.h>
24 #include <epan/addr_resolv.h>
25 #include <epan/stats_tree.h>
26 #include <epan/prefs-int.h>
28 #include "packet-udp.h"
29 #include "packet-dtls.h"
30 #include "packet-someip.h"
31 #include "packet-tls.h"
34 * Dissector for SOME/IP, SOME/IP-TP, and SOME/IP Payloads.
37 * http://www.some-ip.com
40 * This dissector also supports the experimental WTLV or TLV extension,
41 * which is not part of the original SOME/IP.
42 * This add-on feature uses a so-called WireType, which is basically
43 * a type of a length field and an ID to each parameter. Since the
44 * WireType is not really a type, we should avoid TLV as name for this.
45 * Only use this, if you know what you are doing since this changes the
46 * serialization methodology of SOME/IP in a incompatible way and might
47 * break the dissection of your messages.
50 #define SOMEIP_NAME "SOME/IP"
51 #define SOMEIP_NAME_LONG "SOME/IP Protocol"
52 #define SOMEIP_NAME_FILTER "someip"
53 #define SOMEIP_NAME_PREFIX "someip.payload"
55 #define SOMEIP_NAME_LONG_MULTIPLE "SOME/IP Protocol (Multiple Payloads)"
56 #define SOMEIP_NAME_LONG_BROKEN "SOME/IP: Incomplete headers!"
57 #define SOMEIP_NAME_LONG_TOO_SHORT "SOME/IP: Incomplete SOME/IP payload!"
59 /*** Configuration ***/
60 #define DATAFILE_SOMEIP_SERVICES "SOMEIP_service_identifiers"
61 #define DATAFILE_SOMEIP_METHODS "SOMEIP_method_event_identifiers"
62 #define DATAFILE_SOMEIP_EVENTGROUPS "SOMEIP_eventgroup_identifiers"
63 #define DATAFILE_SOMEIP_CLIENTS "SOMEIP_client_identifiers"
65 #define DATAFILE_SOMEIP_PARAMETERS "SOMEIP_parameter_list"
66 #define DATAFILE_SOMEIP_BASE_TYPES "SOMEIP_parameter_base_types"
67 #define DATAFILE_SOMEIP_ARRAYS "SOMEIP_parameter_arrays"
68 #define DATAFILE_SOMEIP_STRINGS "SOMEIP_parameter_strings"
69 #define DATAFILE_SOMEIP_TYPEDEFS "SOMEIP_parameter_typedefs"
70 #define DATAFILE_SOMEIP_STRUCTS "SOMEIP_parameter_structs"
71 #define DATAFILE_SOMEIP_UNIONS "SOMEIP_parameter_unions"
72 #define DATAFILE_SOMEIP_ENUMS "SOMEIP_parameter_enums"
74 #define SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_UNKNOWN 0
75 #define SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_BASE_TYPE 1
76 #define SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_STRING 2
77 #define SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ARRAY 3
78 #define SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_STRUCT 4
79 #define SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_UNION 5
80 #define SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_TYPEDEF 6
81 #define SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ENUM 7
84 #define SOMEIP_HDR_LEN 16
85 #define SOMEIP_HDR_PART1_LEN 8
86 #define SOMEIP_HDR_PART2_LEN_INCL_TP 12
87 #define SOMEIP_TP_HDR_LEN 4
88 #define SOMEIP_PROTOCOL_VERSION 1
91 #define SOMEIP_MSGTYPE_REQUEST 0x00
92 #define SOMEIP_MSGTYPE_REQUEST_NO_RESPONSE 0x01
93 #define SOMEIP_MSGTYPE_NOTIFICATION 0x02
94 #define SOMEIP_MSGTYPE_RESPONSE 0x80
95 #define SOMEIP_MSGTYPE_ERROR 0x81
97 #define SOMEIP_MSGTYPE_ACK_MASK 0x40
98 #define SOMEIP_MSGTYPE_TP_MASK 0x20
99 #define SOMEIP_MSGTYPE_FLAGS_MASK 0x60
100 #define SOMEIP_MSGTYPE_NO_FLAGS_MASK 0x9f
101 #define SOMEIP_MSGTYPE_TP_STRING "SOME/IP-TP segment"
102 #define SOMEIP_MSGTYPE_ACK_STRING "ACK"
105 #define SOMEIP_TP_OFFSET_MASK 0xfffffff0
106 #define SOMEIP_TP_OFFSET_MASK_FLAGS 0x0000000f
107 #define SOMEIP_TP_OFFSET_MASK_RESERVED 0x0000000e
108 #define SOMEIP_TP_OFFSET_MASK_MORE_SEGMENTS 0x00000001
111 #define SOMEIP_RETCODE_OK 0x00
112 #define SOMEIP_RETCODE_NOT_OK 0x01
113 #define SOMEIP_RETCODE_UNKNOWN_SERVICE 0x02
114 #define SOMEIP_RETCODE_UNKNOWN_METHOD 0x03
115 #define SOMEIP_RETCODE_NOT_READY 0x04
116 #define SOMEIP_RETCODE_NOT_REACHABLE 0x05
117 #define SOMEIP_RETCODE_TIMEOUT 0x06
118 #define SOMEIP_RETCODE_WRONG_PROTO_VER 0x07
119 #define SOMEIP_RETCODE_WRONG_INTERFACE_VER 0x08
120 #define SOMEIP_RETCODE_MALFORMED_MSG 0x09
121 #define SOMEIP_RETCODE_WRONG_MESSAGE_TYPE 0x0a
123 /* SOME/IP WTLV (experimental "WTLV" extension) */
124 #define SOMEIP_WTLV_MASK_RES 0x8000
125 #define SOMEIP_WTLV_MASK_WIRE_TYPE 0x7000
126 #define SOMEIP_WTLV_MASK_DATA_ID 0x0fff
128 /* ID wireshark identifies the dissector by */
129 static int proto_someip
;
130 static module_t
*someip_module
;
132 static dissector_handle_t someip_handle_udp
;
133 static dissector_handle_t someip_handle_tcp
;
134 static dissector_handle_t dtls_handle
;
137 static int hf_someip_messageid
;
138 static int hf_someip_serviceid
;
139 static int hf_someip_servicename
;
140 static int hf_someip_methodid
;
141 static int hf_someip_methodname
;
142 static int hf_someip_length
;
143 static int hf_someip_clientid
;
144 static int hf_someip_clientname
;
145 static int hf_someip_sessionid
;
146 static int hf_someip_protover
;
147 static int hf_someip_interface_ver
;
148 static int hf_someip_messagetype
;
149 static int hf_someip_messagetype_ack_flag
;
150 static int hf_someip_messagetype_tp_flag
;
151 static int hf_someip_returncode
;
153 static int hf_someip_tp
;
154 static int hf_someip_tp_offset
;
155 static int hf_someip_tp_offset_encoded
;
156 static int hf_someip_tp_flags
;
157 static int hf_someip_tp_reserved
;
158 static int hf_someip_tp_more_segments
;
160 static int hf_someip_payload
;
162 /* protocol tree items */
163 static int ett_someip
;
164 static int ett_someip_msgtype
;
165 static int ett_someip_tp
;
167 /* dissector handling */
168 static dissector_table_t someip_dissector_table
;
170 /* message reassembly for SOME/IP-TP */
171 static int hf_someip_tp_fragments
;
172 static int hf_someip_tp_fragment
;
173 static int hf_someip_tp_fragment_overlap
;
174 static int hf_someip_tp_fragment_overlap_conflicts
;
175 static int hf_someip_tp_fragment_multiple_tails
;
176 static int hf_someip_tp_fragment_too_long_fragment
;
177 static int hf_someip_tp_fragment_error
;
178 static int hf_someip_tp_fragment_count
;
179 static int hf_someip_tp_reassembled_in
;
180 static int hf_someip_tp_reassembled_length
;
181 static int hf_someip_tp_reassembled_data
;
183 static int hf_payload_unparsed
;
184 static int hf_payload_length_field_8bit
;
185 static int hf_payload_length_field_16bit
;
186 static int hf_payload_length_field_32bit
;
187 static int hf_payload_type_field_8bit
;
188 static int hf_payload_type_field_16bit
;
189 static int hf_payload_type_field_32bit
;
190 static int hf_payload_str_base
;
191 static int hf_payload_str_string
;
192 static int hf_payload_str_struct
;
193 static int hf_payload_str_array
;
194 static int hf_payload_str_union
;
196 static int hf_payload_wtlv_tag
;
197 static int hf_payload_wtlv_tag_res
;
198 static int hf_payload_wtlv_tag_wire_type
;
199 static int hf_payload_wtlv_tag_data_id
;
201 static hf_register_info
* dynamic_hf_param
;
202 static unsigned dynamic_hf_param_size
;
203 static hf_register_info
* dynamic_hf_array
;
204 static unsigned dynamic_hf_array_size
;
205 static hf_register_info
* dynamic_hf_struct
;
206 static unsigned dynamic_hf_struct_size
;
207 static hf_register_info
* dynamic_hf_union
;
208 static unsigned dynamic_hf_union_size
;
210 static int ett_someip_tp_fragment
;
211 static int ett_someip_tp_fragments
;
212 static int ett_someip_payload
;
213 static int ett_someip_string
;
214 static int ett_someip_array
;
215 static int ett_someip_array_dim
;
216 static int ett_someip_struct
;
217 static int ett_someip_union
;
218 static int ett_someip_parameter
;
219 static int ett_someip_wtlv_tag
;
221 static const fragment_items someip_tp_frag_items
= {
222 &ett_someip_tp_fragment
,
223 &ett_someip_tp_fragments
,
224 &hf_someip_tp_fragments
,
225 &hf_someip_tp_fragment
,
226 &hf_someip_tp_fragment_overlap
,
227 &hf_someip_tp_fragment_overlap_conflicts
,
228 &hf_someip_tp_fragment_multiple_tails
,
229 &hf_someip_tp_fragment_too_long_fragment
,
230 &hf_someip_tp_fragment_error
,
231 &hf_someip_tp_fragment_count
,
232 &hf_someip_tp_reassembled_in
,
233 &hf_someip_tp_reassembled_length
,
234 &hf_someip_tp_reassembled_data
,
235 "SOME/IP-TP Segments"
238 static bool someip_tp_reassemble
= true;
239 static bool someip_deserializer_activated
= true;
240 static bool someip_deserializer_wtlv_default
;
241 static bool someip_detect_dtls
;
243 /* SOME/IP Message Types */
244 static const value_string someip_msg_type
[] = {
245 {SOMEIP_MSGTYPE_REQUEST
, "Request"},
246 {SOMEIP_MSGTYPE_REQUEST_NO_RESPONSE
, "Request no response"},
247 {SOMEIP_MSGTYPE_NOTIFICATION
, "Notification"},
248 {SOMEIP_MSGTYPE_RESPONSE
, "Response"},
249 {SOMEIP_MSGTYPE_ERROR
, "Error"},
250 {SOMEIP_MSGTYPE_REQUEST
| SOMEIP_MSGTYPE_ACK_MASK
, "Request Ack"},
251 {SOMEIP_MSGTYPE_REQUEST_NO_RESPONSE
| SOMEIP_MSGTYPE_ACK_MASK
, "Request no response Ack"},
252 {SOMEIP_MSGTYPE_NOTIFICATION
| SOMEIP_MSGTYPE_ACK_MASK
, "Notification Ack"},
253 {SOMEIP_MSGTYPE_RESPONSE
| SOMEIP_MSGTYPE_ACK_MASK
, "Response Ack"},
254 {SOMEIP_MSGTYPE_ERROR
| SOMEIP_MSGTYPE_ACK_MASK
, "Error Ack"},
258 /* SOME/IP Return Code */
259 static const value_string someip_return_code
[] = {
260 {SOMEIP_RETCODE_OK
, "Ok"},
261 {SOMEIP_RETCODE_NOT_OK
, "Not Ok"},
262 {SOMEIP_RETCODE_UNKNOWN_SERVICE
, "Unknown Service"},
263 {SOMEIP_RETCODE_UNKNOWN_METHOD
, "Unknown Method/Event"},
264 {SOMEIP_RETCODE_NOT_READY
, "Not Ready"},
265 {SOMEIP_RETCODE_NOT_REACHABLE
, "Not Reachable (internal)"},
266 {SOMEIP_RETCODE_TIMEOUT
, "Timeout (internal)"},
267 {SOMEIP_RETCODE_WRONG_PROTO_VER
, "Wrong Protocol Version"},
268 {SOMEIP_RETCODE_WRONG_INTERFACE_VER
, "Wrong Interface Version"},
269 {SOMEIP_RETCODE_MALFORMED_MSG
, "Malformed Message"},
270 {SOMEIP_RETCODE_WRONG_MESSAGE_TYPE
, "Wrong Message Type"},
274 /*** expert info items ***/
275 static expert_field ei_someip_unknown_version
;
276 static expert_field ei_someip_message_truncated
;
277 static expert_field ei_someip_incomplete_headers
;
279 static expert_field ei_someip_payload_truncated
;
280 static expert_field ei_someip_payload_malformed
;
281 static expert_field ei_someip_payload_config_error
;
282 static expert_field ei_someip_payload_alignment_error
;
283 static expert_field ei_someip_payload_static_array_min_not_max
;
284 static expert_field ei_someip_payload_dyn_array_not_within_limit
;
286 /*** Data Structure for mapping IDs to Names (Services, Methods, ...) ***/
287 static GHashTable
*data_someip_services
;
288 static GHashTable
*data_someip_methods
;
289 static GHashTable
*data_someip_eventgroups
;
290 static GHashTable
*data_someip_clients
;
292 static GHashTable
*data_someip_parameter_list
;
293 static GHashTable
*data_someip_parameter_base_type_list
;
294 static GHashTable
*data_someip_parameter_strings
;
295 static GHashTable
*data_someip_parameter_typedefs
;
296 static GHashTable
*data_someip_parameter_arrays
;
297 static GHashTable
*data_someip_parameter_structs
;
298 static GHashTable
*data_someip_parameter_unions
;
299 static GHashTable
*data_someip_parameter_enums
;
302 static int tap_someip_messages
= -1;
305 static const char *st_str_ip_src
= "Source Addresses";
306 static const char *st_str_ip_dst
= "Destination Addresses";
308 static int st_node_ip_src
= -1;
309 static int st_node_ip_dst
= -1;
311 /***********************************************
312 ********* Preferences / Configuration *********
313 ***********************************************/
315 typedef struct _someip_payload_parameter_item
{
322 } someip_payload_parameter_item_t
;
324 #define INIT_SOMEIP_PAYLOAD_PARAMETER_ITEM(NAME) \
326 (NAME)->name = NULL; \
327 (NAME)->data_type = 0; \
328 (NAME)->id_ref = 0; \
329 (NAME)->hf_id = NULL; \
330 (NAME)->filter_string = NULL;
333 typedef struct _someip_payload_parameter_base_type_list
{
338 uint32_t bitlength_base_type
;
339 uint32_t bitlength_encoded_type
;
340 } someip_payload_parameter_base_type_list_t
;
342 #define INIT_COMMON_BASE_TYPE_LIST_ITEM(NAME) \
344 (NAME)->name = NULL; \
345 (NAME)->data_type = NULL ; \
346 (NAME)->big_endian = true; \
347 (NAME)->bitlength_base_type = 0; \
348 (NAME)->bitlength_encoded_type = 0;
351 typedef struct _someip_payload_parameter_string
{
357 uint32_t length_of_length
; /* default: 32 */
360 } someip_payload_parameter_string_t
;
362 #define INIT_SOMEIP_PAYLOAD_PARAMETER_STRING(NAME) \
364 (NAME)->name = NULL; \
365 (NAME)->encoding = NULL; \
366 (NAME)->dynamic_length = false; \
367 (NAME)->max_length = 0; \
368 (NAME)->length_of_length = 0; \
369 (NAME)->big_endian = true; \
373 typedef struct _someip_payload_parameter_typedef
{
378 } someip_payload_parameter_typedef_t
;
380 #define INIT_SOMEIP_PAYLOAD_PARAMETER_TYPEDEF(NAME) \
382 (NAME)->name = NULL; \
383 (NAME)->data_type = 0; \
387 typedef struct _someip_payload_parameter_struct
{
390 uint32_t length_of_length
; /* default: 0 */
391 uint32_t pad_to
; /* default: 0 */
393 uint32_t num_of_items
;
396 someip_payload_parameter_item_t
*items
;
397 } someip_payload_parameter_struct_t
;
399 #define INIT_SOMEIP_PAYLOAD_PARAMETER_STRUCT(NAME) \
401 (NAME)->struct_name = NULL; \
402 (NAME)->length_of_length = 0; \
403 (NAME)->pad_to = 0; \
404 (NAME)->wtlv_encoding = false; \
405 (NAME)->num_of_items = 0;
408 typedef struct _someip_payload_parameter_enum_item
{
411 } someip_payload_parameter_enum_item_t
;
413 #define INIT_SOMEIP_PAYLOAD_PARAMETER_ENUM_ITEM(NAME) \
418 typedef struct _someip_payload_parameter_enum
{
423 uint32_t num_of_items
;
425 someip_payload_parameter_enum_item_t
*items
;
426 } someip_payload_parameter_enum_t
;
428 #define INIT_SOMEIP_PAYLOAD_PARAMETER_ENUM(NAME) \
430 (NAME)->name = NULL; \
431 (NAME)->data_type = 0; \
432 (NAME)->id_ref = 0; \
433 (NAME)->num_of_items = 0; \
434 (NAME)->items = NULL;
436 typedef struct _someip_parameter_union_item
{
443 } someip_parameter_union_item_t
;
445 typedef struct _someip_parameter_union
{
448 uint32_t length_of_length
; /* default: 32 */
449 uint32_t length_of_type
; /* default: 32 */
450 uint32_t pad_to
; /* default: 0 */
451 uint32_t num_of_items
;
453 someip_parameter_union_item_t
*items
;
454 } someip_parameter_union_t
;
456 typedef struct _someip_parameter_union_uat
{
459 uint32_t length_of_length
;
460 uint32_t length_of_type
;
462 uint32_t num_of_items
;
468 } someip_parameter_union_uat_t
;
470 typedef struct _someip_parameter_enum_uat
{
475 uint32_t num_of_items
;
478 } someip_parameter_enum_uat_t
;
480 typedef struct _someip_parameter_array_dim
{
482 uint32_t lower_limit
;
483 uint32_t upper_limit
;
484 uint32_t length_of_length
;
486 } someip_parameter_array_dim_t
;
488 typedef struct _someip_parameter_array
{
493 uint32_t num_of_dims
;
497 someip_parameter_array_dim_t
*dims
;
498 } someip_parameter_array_t
;
500 typedef struct _someip_parameter_array_uat
{
505 uint32_t num_of_dims
;
509 uint32_t lower_limit
;
510 uint32_t upper_limit
;
511 uint32_t length_of_length
;
513 } someip_parameter_array_uat_t
;
515 typedef struct _someip_parameter_list
{
519 uint32_t message_type
;
522 uint32_t num_of_items
;
524 someip_payload_parameter_item_t
*items
;
525 } someip_parameter_list_t
;
527 typedef struct _someip_parameter_list_uat
{
531 uint32_t message_type
;
534 uint32_t num_of_params
;
541 } someip_parameter_list_uat_t
;
543 typedef struct _someip_parameter_struct_uat
{
546 uint32_t length_of_length
; /* default: 0 */
547 uint32_t pad_to
; /* default: 0 */
550 uint32_t num_of_items
;
557 } someip_parameter_struct_uat_t
;
559 typedef someip_payload_parameter_base_type_list_t someip_parameter_base_type_list_uat_t
;
560 typedef someip_payload_parameter_string_t someip_parameter_string_uat_t
;
561 typedef someip_payload_parameter_typedef_t someip_parameter_typedef_uat_t
;
563 typedef struct _generic_one_id_string
{
566 } generic_one_id_string_t
;
568 typedef struct _generic_two_id_string
{
572 } generic_two_id_string_t
;
574 static generic_one_id_string_t
*someip_service_ident
;
575 static unsigned someip_service_ident_num
;
577 static generic_two_id_string_t
*someip_method_ident
;
578 static unsigned someip_method_ident_num
;
580 static generic_two_id_string_t
*someip_eventgroup_ident
;
581 static unsigned someip_eventgroup_ident_num
;
583 static generic_two_id_string_t
*someip_client_ident
;
584 static unsigned someip_client_ident_num
;
586 static someip_parameter_list_uat_t
*someip_parameter_list
;
587 static unsigned someip_parameter_list_num
;
589 static someip_parameter_string_uat_t
*someip_parameter_strings
;
590 static unsigned someip_parameter_strings_num
;
592 static someip_parameter_typedef_uat_t
*someip_parameter_typedefs
;
593 static unsigned someip_parameter_typedefs_num
;
595 static someip_parameter_array_uat_t
*someip_parameter_arrays
;
596 static unsigned someip_parameter_arrays_num
;
598 static someip_parameter_struct_uat_t
*someip_parameter_structs
;
599 static unsigned someip_parameter_structs_num
;
601 static someip_parameter_union_uat_t
*someip_parameter_unions
;
602 static unsigned someip_parameter_unions_num
;
604 static someip_parameter_enum_uat_t
*someip_parameter_enums
;
605 static unsigned someip_parameter_enums_num
;
607 static someip_parameter_base_type_list_uat_t
*someip_parameter_base_type_list
;
608 static unsigned someip_parameter_base_type_list_num
;
610 void proto_register_someip(void);
611 void proto_reg_handoff_someip(void);
613 static void deregister_dynamic_hf_data(hf_register_info
**hf_array
, unsigned *hf_size
);
614 static void update_dynamic_hf_entries_someip_parameter_list(void);
615 static void update_dynamic_hf_entries_someip_parameter_arrays(void);
616 static void update_dynamic_hf_entries_someip_parameter_structs(void);
617 static void update_dynamic_hf_entries_someip_parameter_unions(void);
619 /* Segmentation support
620 * https://gitlab.com/wireshark/wireshark/-/issues/18880
622 typedef struct _someip_segment_key
{
628 } someip_segment_key
;
631 someip_segment_hash(const void *k
)
633 const someip_segment_key
*key
= (const someip_segment_key
*)k
;
636 hash_val
= (key
->info
.service_id
<< 16 | key
->info
.method_id
) ^
637 (key
->info
.client_id
<< 16 | key
->info
.session_id
);
643 someip_segment_equal(const void *k1
, const void *k2
)
645 const someip_segment_key
*key1
= (someip_segment_key
*)k1
;
646 const someip_segment_key
*key2
= (someip_segment_key
*)k2
;
648 return (key1
->info
.session_id
== key2
->info
.session_id
) &&
649 (key1
->info
.service_id
== key2
->info
.service_id
) &&
650 (key1
->info
.client_id
== key2
->info
.client_id
) &&
651 (key1
->info
.method_id
== key2
->info
.method_id
) &&
652 (key1
->info
.message_type
== key2
->info
.message_type
) &&
653 (key1
->info
.major_version
== key2
->info
.major_version
) &&
654 (addresses_equal(&key1
->src_addr
, &key2
->src_addr
)) &&
655 (addresses_equal(&key1
->dst_addr
, &key2
->dst_addr
)) &&
656 (key1
->src_port
== key2
->src_port
) &&
657 (key1
->dst_port
== key2
->dst_port
);
661 * Create a fragment key for temporary use; it can point to non-
662 * persistent data, and so must only be used to look up and
663 * delete entries, not to add them.
666 someip_segment_temporary_key(const packet_info
*pinfo
, const uint32_t id _U_
,
669 const someip_info_t
*info
= (const someip_info_t
*)data
;
670 someip_segment_key
*key
= g_slice_new(someip_segment_key
);
672 /* Do a shallow copy of the addresses. */
673 copy_address_shallow(&key
->src_addr
, &pinfo
->src
);
674 copy_address_shallow(&key
->dst_addr
, &pinfo
->dst
);
675 key
->src_port
= pinfo
->srcport
;
676 key
->dst_port
= pinfo
->destport
;
677 memcpy(&key
->info
, info
, sizeof(someip_info_t
));
683 * Create a fragment key for permanent use; it must point to persistent
684 * data, so that it can be used to add entries.
687 someip_segment_persistent_key(const packet_info
*pinfo
,
688 const uint32_t id _U_
, const void *data
)
690 const someip_info_t
*info
= (const someip_info_t
*)data
;
691 someip_segment_key
*key
= g_slice_new(someip_segment_key
);
693 /* Do a deep copy of the addresses. */
694 copy_address(&key
->src_addr
, &pinfo
->src
);
695 copy_address(&key
->dst_addr
, &pinfo
->dst
);
696 key
->src_port
= pinfo
->srcport
;
697 key
->dst_port
= pinfo
->destport
;
698 memcpy(&key
->info
, info
, sizeof(someip_info_t
));
704 someip_segment_free_temporary_key(void *ptr
)
706 someip_segment_key
*key
= (someip_segment_key
*)ptr
;
708 g_slice_free(someip_segment_key
, key
);
712 someip_segment_free_persistent_key(void *ptr
)
714 someip_segment_key
*key
= (someip_segment_key
*)ptr
;
716 /* Free up the copies of the addresses from the old key. */
717 free_address(&key
->src_addr
);
718 free_address(&key
->dst_addr
);
720 g_slice_free(someip_segment_key
, key
);
724 static const reassembly_table_functions
725 someip_reassembly_table_functions
= {
727 someip_segment_equal
,
728 someip_segment_temporary_key
,
729 someip_segment_persistent_key
,
730 someip_segment_free_temporary_key
,
731 someip_segment_free_persistent_key
734 static reassembly_table someip_tp_reassembly_table
;
737 /* register a UDP SOME/IP port */
739 register_someip_port_udp(uint32_t portnumber
) {
740 dissector_add_uint("udp.port", portnumber
, someip_handle_udp
);
743 /* register a TCP SOME/IP port */
745 register_someip_port_tcp(uint32_t portnumber
) {
746 dissector_add_uint("tcp.port", portnumber
, someip_handle_tcp
);
749 /*** UAT Callbacks and Helpers ***/
752 set_prefs_changed(void) {
753 /* This ensures that proto_reg_handoff_someip is called, even if SOME/IP is not bound to any port yet. */
755 someip_module
->prefs_changed_flags
|= (PREF_EFFECT_DISSECTION
|PREF_EFFECT_FIELDS
);
760 check_filter_string(char *filter_string
, uint32_t id
) {
764 c
= proto_check_field_name(filter_string
);
767 err
= ws_strdup_printf("Filter String contains illegal chars '.' (ID: %i )", id
);
768 } else if (g_ascii_isprint(c
)) {
769 err
= ws_strdup_printf("Filter String contains illegal chars '%c' (ID: %i)", c
, id
);
771 err
= ws_strdup_printf("Filter String contains invalid byte \\%03o (ID: %i)", c
, id
);
779 someip_free_key(void *key
) {
780 wmem_free(wmem_epan_scope(), key
);
784 simple_free(void *data _U_
) {
785 /* we need to free because of the g_strdup in post_update*/
791 copy_generic_one_id_string_cb(void *n
, const void *o
, size_t size _U_
) {
792 generic_one_id_string_t
*new_rec
= (generic_one_id_string_t
*)n
;
793 const generic_one_id_string_t
*old_rec
= (const generic_one_id_string_t
*)o
;
795 new_rec
->name
= g_strdup(old_rec
->name
);
796 new_rec
->id
= old_rec
->id
;
801 update_serviceid(void *r
, char **err
) {
802 generic_one_id_string_t
*rec
= (generic_one_id_string_t
*)r
;
804 if (rec
->id
== 0xffff) {
805 *err
= ws_strdup_printf("Service-ID 0xffff is reserved and cannot be used (ID: %i Name: %s)", rec
->id
, rec
->name
);
809 if (rec
->id
> 0xffff) {
810 *err
= ws_strdup_printf("Service-IDs have to be 16bit (ID: %i Name: %s)", rec
->id
, rec
->name
);
814 if (rec
->name
== NULL
|| rec
->name
[0] == 0) {
815 *err
= g_strdup("Name cannot be empty");
823 free_generic_one_id_string_cb(void *r
) {
824 generic_one_id_string_t
*rec
= (generic_one_id_string_t
*)r
;
826 /* freeing result of g_strdup */
832 post_update_one_id_string_template_cb(generic_one_id_string_t
*data
, unsigned data_num
, GHashTable
*ht
) {
836 for (i
= 0; i
< data_num
; i
++) {
837 key
= wmem_new(wmem_epan_scope(), int);
840 g_hash_table_insert(ht
, key
, g_strdup(data
[i
].name
));
847 copy_generic_two_id_string_cb(void *n
, const void *o
, size_t size _U_
) {
848 generic_two_id_string_t
*new_rec
= (generic_two_id_string_t
*)n
;
849 const generic_two_id_string_t
*old_rec
= (const generic_two_id_string_t
*)o
;
851 new_rec
->name
= g_strdup(old_rec
->name
);
852 new_rec
->id
= old_rec
->id
;
853 new_rec
->id2
= old_rec
->id2
;
858 update_two_identifier_16bit_check_both(void *r
, char **err
) {
859 generic_two_id_string_t
*rec
= (generic_two_id_string_t
*)r
;
861 if (rec
->id
== 0xffff) {
862 *err
= ws_strdup_printf("Service-ID 0xffff is reserved and cannot be used (ID: %i Name: %s)", rec
->id
, rec
->name
);
866 if (rec
->id
> 0xffff) {
867 *err
= ws_strdup_printf("Service-IDs have to be 16bit (ID: %i Name: %s)", rec
->id
, rec
->name
);
871 if (rec
->id2
== 0xffff) {
872 *err
= ws_strdup_printf("0xffff is reserved and cannot be used (ID: %i ID2: %i Name: %s)", rec
->id
, rec
->id2
, rec
->name
);
876 if (rec
->id2
> 0xffff) {
877 *err
= ws_strdup_printf("We currently only support 16 bit identifiers (ID: %i ID2: %i Name: %s)", rec
->id
, rec
->id2
, rec
->name
);
881 if (rec
->name
== NULL
|| rec
->name
[0] == 0) {
882 *err
= g_strdup("Name cannot be empty");
890 update_generic_two_identifier_16bit(void *r
, char **err
) {
891 generic_two_id_string_t
*rec
= (generic_two_id_string_t
*)r
;
893 if (rec
->id
> 0xffff) {
894 *err
= ws_strdup_printf("We currently only support 16 bit identifiers (ID: %i Name: %s)", rec
->id
, rec
->name
);
898 if (rec
->id2
> 0xffff) {
899 *err
= ws_strdup_printf("We currently only support 16 bit identifiers (ID: %i ID2: %i Name: %s)", rec
->id
, rec
->id2
, rec
->name
);
903 if (rec
->name
== NULL
|| rec
->name
[0] == 0) {
904 *err
= g_strdup("Name cannot be empty");
912 free_generic_two_id_string_cb(void *r
) {
913 generic_two_id_string_t
*rec
= (generic_two_id_string_t
*)r
;
915 /* freeing result of g_strdup */
921 post_update_generic_two_id_string_template_cb(generic_two_id_string_t
*data
, unsigned data_num
, GHashTable
*ht
) {
927 for (i
= 0; i
< data_num
; i
++) {
928 key
= wmem_new(wmem_epan_scope(), int);
929 tmp
= (data
[i
].id
& 0xffff) << 16;
930 tmp2
= (data
[i
].id2
& 0xffff);
932 /* the hash table does not know about uint32, so we use int32 */
933 *key
= (int)(tmp
+ tmp2
);
935 g_hash_table_insert(ht
, key
, g_strdup(data
[i
].name
));
940 someip_lookup_service_name(uint16_t serviceid
) {
941 uint32_t tmp
= (uint32_t)serviceid
;
943 if (data_someip_services
== NULL
) {
947 return (char *)g_hash_table_lookup(data_someip_services
, &tmp
);
951 someip_lookup_method_name(uint16_t serviceid
, uint16_t methodid
) {
952 uint32_t tmp
= (serviceid
<< 16) + methodid
;
954 if (data_someip_methods
== NULL
) {
958 return (char *)g_hash_table_lookup(data_someip_methods
, &tmp
);
962 someip_lookup_eventgroup_name(uint16_t serviceid
, uint16_t eventgroupid
) {
963 uint32_t tmp
= (serviceid
<< 16) + eventgroupid
;
965 if (data_someip_eventgroups
== NULL
) {
969 return (char *)g_hash_table_lookup(data_someip_eventgroups
, &tmp
);
973 someip_lookup_client_name(uint16_t serviceid
, uint16_t clientid
) {
974 uint32_t tmp
= (serviceid
<< 16) + clientid
;
976 if (data_someip_clients
== NULL
) {
980 return (char *)g_hash_table_lookup(data_someip_clients
, &tmp
);
984 /*** SOME/IP Services ***/
985 UAT_HEX_CB_DEF (someip_service_ident
, id
, generic_one_id_string_t
)
986 UAT_CSTRING_CB_DEF (someip_service_ident
, name
, generic_one_id_string_t
)
989 reset_someip_service_cb(void) {
990 /* destroy old hash table, if it exists */
991 if (data_someip_services
) {
992 g_hash_table_destroy(data_someip_services
);
993 data_someip_services
= NULL
;
998 post_update_someip_service_cb(void) {
999 reset_someip_service_cb();
1001 /* create new hash table */
1002 data_someip_services
= g_hash_table_new_full(g_int_hash
, g_int_equal
, &someip_free_key
, &simple_free
);
1003 post_update_one_id_string_template_cb(someip_service_ident
, someip_service_ident_num
, data_someip_services
);
1007 /*** SOME/IP Methods/Events/Fields ***/
1008 UAT_HEX_CB_DEF (someip_method_ident
, id
, generic_two_id_string_t
)
1009 UAT_HEX_CB_DEF (someip_method_ident
, id2
, generic_two_id_string_t
)
1010 UAT_CSTRING_CB_DEF (someip_method_ident
, name
, generic_two_id_string_t
)
1013 reset_someip_method_cb(void) {
1014 /* destroy old hash table, if it exists */
1015 if (data_someip_methods
) {
1016 g_hash_table_destroy(data_someip_methods
);
1017 data_someip_methods
= NULL
;
1022 post_update_someip_method_cb(void) {
1023 reset_someip_method_cb();
1025 /* create new hash table */
1026 data_someip_methods
= g_hash_table_new_full(g_int_hash
, g_int_equal
, &someip_free_key
, &simple_free
);
1027 post_update_generic_two_id_string_template_cb(someip_method_ident
, someip_method_ident_num
, data_someip_methods
);
1031 /*** SOME/IP Eventgroups ***/
1032 UAT_HEX_CB_DEF (someip_eventgroup_ident
, id
, generic_two_id_string_t
)
1033 UAT_HEX_CB_DEF (someip_eventgroup_ident
, id2
, generic_two_id_string_t
)
1034 UAT_CSTRING_CB_DEF (someip_eventgroup_ident
, name
, generic_two_id_string_t
)
1037 reset_someip_eventgroup_cb(void) {
1038 /* destroy old hash table, if it exists */
1039 if (data_someip_eventgroups
) {
1040 g_hash_table_destroy(data_someip_eventgroups
);
1041 data_someip_eventgroups
= NULL
;
1046 post_update_someip_eventgroup_cb(void) {
1047 reset_someip_eventgroup_cb();
1049 /* create new hash table */
1050 data_someip_eventgroups
= g_hash_table_new_full(g_int_hash
, g_int_equal
, &someip_free_key
, &simple_free
);
1051 post_update_generic_two_id_string_template_cb(someip_eventgroup_ident
, someip_eventgroup_ident_num
, data_someip_eventgroups
);
1055 /*** SOME/IP Clients ***/
1056 UAT_HEX_CB_DEF(someip_client_ident
, id
, generic_two_id_string_t
)
1057 UAT_HEX_CB_DEF(someip_client_ident
, id2
, generic_two_id_string_t
)
1058 UAT_CSTRING_CB_DEF(someip_client_ident
, name
, generic_two_id_string_t
)
1061 reset_someip_client_cb(void) {
1062 /* destroy old hash table, if it exists */
1063 if (data_someip_clients
) {
1064 g_hash_table_destroy(data_someip_clients
);
1065 data_someip_clients
= NULL
;
1070 post_update_someip_client_cb(void) {
1071 reset_someip_client_cb();
1073 /* create new hash table */
1074 data_someip_clients
= g_hash_table_new_full(g_int_hash
, g_int_equal
, &someip_free_key
, &simple_free
);
1075 post_update_generic_two_id_string_template_cb(someip_client_ident
, someip_client_ident_num
, data_someip_clients
);
1079 someip_payload_free_key(void *key
) {
1080 wmem_free(wmem_epan_scope(), key
);
1084 someip_parameter_key(uint16_t serviceid
, uint16_t methodid
, uint8_t version
, uint8_t msgtype
) {
1091 Service-ID [16bit] | Method-ID [16bit] | Version [8bit] | Message-Type [8bit]
1094 tmp1
= (int64_t)(serviceid
& 0xffff);
1095 tmp2
= (int64_t)(methodid
& 0xffff) << 16;
1096 tmp3
= (int64_t)(version
& 0xff) << 32;
1097 tmp4
= (int64_t)(msgtype
& 0xff) << 40;
1099 return (int64_t)(tmp1
+ tmp2
+ tmp3
+ tmp4
);
1102 static someip_parameter_list_t
*
1103 get_parameter_config(uint16_t serviceid
, uint16_t methodid
, uint8_t version
, uint8_t msgtype
) {
1104 int64_t *key
= NULL
;
1105 someip_parameter_list_t
*tmp
= NULL
;
1107 if (data_someip_parameter_list
== NULL
) {
1111 key
= wmem_new(wmem_epan_scope(), int64_t);
1112 *key
= someip_parameter_key(serviceid
, methodid
, version
, msgtype
);
1113 tmp
= (someip_parameter_list_t
*)g_hash_table_lookup(data_someip_parameter_list
, key
);
1114 wmem_free(wmem_epan_scope(), key
);
1120 get_generic_config(GHashTable
*ht
, int64_t id
) {
1125 return (void *)g_hash_table_lookup(ht
, &id
);
1128 static someip_payload_parameter_base_type_list_t
*
1129 get_base_type_config(uint32_t id
) {
1130 return (someip_payload_parameter_base_type_list_t
*)get_generic_config(data_someip_parameter_base_type_list
, (int64_t)id
);
1133 static someip_payload_parameter_string_t
*
1134 get_string_config(uint32_t id
) {
1135 return (someip_payload_parameter_string_t
*)get_generic_config(data_someip_parameter_strings
, (int64_t)id
);
1138 static someip_payload_parameter_typedef_t
*
1139 get_typedef_config(uint32_t id
) {
1140 return (someip_payload_parameter_typedef_t
*)get_generic_config(data_someip_parameter_typedefs
, (int64_t)id
);
1143 static someip_parameter_array_t
*
1144 get_array_config(uint32_t id
) {
1145 return (someip_parameter_array_t
*)get_generic_config(data_someip_parameter_arrays
, (int64_t)id
);
1148 static someip_payload_parameter_struct_t
*
1149 get_struct_config(uint32_t id
) {
1150 return (someip_payload_parameter_struct_t
*)get_generic_config(data_someip_parameter_structs
, (int64_t)id
);
1153 static someip_parameter_union_t
*
1154 get_union_config(uint32_t id
) {
1155 return (someip_parameter_union_t
*)get_generic_config(data_someip_parameter_unions
, (int64_t)id
);
1158 static someip_payload_parameter_enum_t
*
1159 get_enum_config(uint32_t id
) {
1160 return (someip_payload_parameter_enum_t
*)get_generic_config(data_someip_parameter_enums
, (int64_t)id
);
1163 UAT_HEX_CB_DEF(someip_parameter_list
, service_id
, someip_parameter_list_uat_t
)
1164 UAT_HEX_CB_DEF(someip_parameter_list
, method_id
, someip_parameter_list_uat_t
)
1165 UAT_DEC_CB_DEF(someip_parameter_list
, version
, someip_parameter_list_uat_t
)
1166 UAT_HEX_CB_DEF(someip_parameter_list
, message_type
, someip_parameter_list_uat_t
)
1167 UAT_BOOL_CB_DEF(someip_parameter_list
, wtlv_encoding
, someip_parameter_list_uat_t
)
1169 UAT_DEC_CB_DEF(someip_parameter_list
, num_of_params
, someip_parameter_list_uat_t
)
1171 UAT_DEC_CB_DEF(someip_parameter_list
, pos
, someip_parameter_list_uat_t
)
1172 UAT_CSTRING_CB_DEF(someip_parameter_list
, name
, someip_parameter_list_uat_t
)
1173 UAT_DEC_CB_DEF(someip_parameter_list
, data_type
, someip_parameter_list_uat_t
)
1174 UAT_HEX_CB_DEF(someip_parameter_list
, id_ref
, someip_parameter_list_uat_t
)
1175 UAT_CSTRING_CB_DEF(someip_parameter_list
, filter_string
, someip_parameter_list_uat_t
)
1178 copy_someip_parameter_list_cb(void *n
, const void *o
, size_t size _U_
) {
1179 someip_parameter_list_uat_t
*new_rec
= (someip_parameter_list_uat_t
*)n
;
1180 const someip_parameter_list_uat_t
*old_rec
= (const someip_parameter_list_uat_t
*)o
;
1182 if (old_rec
->name
) {
1183 new_rec
->name
= g_strdup(old_rec
->name
);
1185 new_rec
->name
= NULL
;
1188 if (old_rec
->filter_string
) {
1189 new_rec
->filter_string
= g_strdup(old_rec
->filter_string
);
1191 new_rec
->filter_string
= NULL
;
1194 new_rec
->service_id
= old_rec
->service_id
;
1195 new_rec
->method_id
= old_rec
->method_id
;
1196 new_rec
->version
= old_rec
->version
;
1197 new_rec
->message_type
= old_rec
->message_type
;
1198 new_rec
->wtlv_encoding
= old_rec
->wtlv_encoding
;
1199 new_rec
->num_of_params
= old_rec
->num_of_params
;
1200 new_rec
->pos
= old_rec
->pos
;
1201 new_rec
->data_type
= old_rec
->data_type
;
1202 new_rec
->id_ref
= old_rec
->id_ref
;
1208 update_someip_parameter_list(void *r
, char **err
) {
1209 someip_parameter_list_uat_t
*rec
= (someip_parameter_list_uat_t
*)r
;
1212 if (rec
->service_id
> 0xffff) {
1213 *err
= ws_strdup_printf("We currently only support 16 bit Service IDs (Service-ID: %i Name: %s)", rec
->service_id
, rec
->name
);
1217 if (rec
->method_id
> 0xffff) {
1218 *err
= ws_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
);
1222 if (rec
->version
> 0xff) {
1223 *err
= ws_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
);
1227 if (rec
->message_type
> 0xff) {
1228 *err
= ws_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
);
1232 if (rec
->name
== NULL
|| rec
->name
[0] == 0) {
1233 *err
= ws_strdup_printf("Name cannot be empty");
1237 if (rec
->pos
>= rec
->num_of_params
) {
1238 *err
= ws_strdup_printf("Position >= Number of Parameters");
1242 if (rec
->filter_string
== NULL
|| rec
->filter_string
[0] == 0) {
1243 *err
= ws_strdup_printf("Name cannot be empty");
1247 c
= proto_check_field_name(rec
->filter_string
);
1250 *err
= ws_strdup_printf("Filter String contains illegal chars '.' (Service-ID: %i Method-ID: %i)", rec
->service_id
, rec
->method_id
);
1251 } else if (g_ascii_isprint(c
)) {
1252 *err
= ws_strdup_printf("Filter String contains illegal chars '%c' (Service-ID: %i Method-ID: %i)", c
, rec
->service_id
, rec
->method_id
);
1254 *err
= ws_strdup_printf("Filter String contains invalid byte \\%03o (Service-ID: %i Method-ID: %i)", c
, rec
->service_id
, rec
->method_id
);
1263 free_someip_parameter_list_cb(void *r
) {
1264 someip_parameter_list_uat_t
*rec
= (someip_parameter_list_uat_t
*)r
;
1271 if (rec
->filter_string
) {
1272 g_free(rec
->filter_string
);
1273 rec
->filter_string
= NULL
;
1278 free_someip_parameter_list(void *data
) {
1279 someip_parameter_list_t
*list
= (someip_parameter_list_t
*)data
;
1281 if (list
->items
!= NULL
) {
1282 wmem_free(wmem_epan_scope(), (void *)(list
->items
));
1286 wmem_free(wmem_epan_scope(), (void *)data
);
1290 post_update_someip_parameter_list_read_in_data(someip_parameter_list_uat_t
*data
, unsigned data_num
, GHashTable
*ht
) {
1292 int64_t *key
= NULL
;
1293 someip_parameter_list_t
*list
= NULL
;
1294 someip_payload_parameter_item_t
*item
= NULL
;
1295 someip_payload_parameter_item_t
*items
= NULL
;
1297 if (ht
== NULL
|| data
== NULL
|| data_num
== 0) {
1301 for (i
= 0; i
< data_num
; i
++) {
1302 /* the hash table does not know about uint64, so we use int64*/
1303 key
= wmem_new(wmem_epan_scope(), int64_t);
1304 *key
= someip_parameter_key((uint16_t)data
[i
].service_id
, (uint16_t)data
[i
].method_id
, (uint8_t)data
[i
].version
, (uint8_t)data
[i
].message_type
);
1306 list
= (someip_parameter_list_t
*)g_hash_table_lookup(ht
, key
);
1309 list
= wmem_new(wmem_epan_scope(), someip_parameter_list_t
);
1311 list
->service_id
= data
[i
].service_id
;
1312 list
->method_id
= data
[i
].method_id
;
1313 list
->version
= data
[i
].version
;
1314 list
->message_type
= data
[i
].message_type
;
1315 list
->wtlv_encoding
= data
[i
].wtlv_encoding
;
1316 list
->num_of_items
= data
[i
].num_of_params
;
1318 items
= (someip_payload_parameter_item_t
*)wmem_alloc0_array(wmem_epan_scope(), someip_payload_parameter_item_t
, data
[i
].num_of_params
);
1319 list
->items
= items
;
1321 /* create new entry ... */
1322 g_hash_table_insert(ht
, key
, list
);
1324 /* already present, deleting key */
1325 wmem_free(wmem_epan_scope(), key
);
1328 /* and now we add to item array */
1329 if (data
[i
].num_of_params
== list
->num_of_items
&& data
[i
].pos
< list
->num_of_items
) {
1330 item
= &(list
->items
[data
[i
].pos
]);
1332 /* we do not care if we overwrite param */
1333 item
->name
= data
[i
].name
;
1334 item
->id_ref
= data
[i
].id_ref
;
1335 item
->pos
= data
[i
].pos
;
1336 item
->data_type
= data
[i
].data_type
;
1337 item
->filter_string
= data
[i
].filter_string
;
1343 reset_someip_parameter_list_cb(void) {
1344 /* destroy old hash table, if it exists */
1345 if (data_someip_parameter_list
) {
1346 deregister_dynamic_hf_data(&dynamic_hf_param
, &dynamic_hf_param_size
);
1347 g_hash_table_destroy(data_someip_parameter_list
);
1348 data_someip_parameter_list
= NULL
;
1351 set_prefs_changed();
1355 post_update_someip_parameter_list_cb(void) {
1356 reset_someip_parameter_list_cb();
1358 data_someip_parameter_list
= g_hash_table_new_full(g_int64_hash
, g_int64_equal
, &someip_payload_free_key
, &free_someip_parameter_list
);
1359 post_update_someip_parameter_list_read_in_data(someip_parameter_list
, someip_parameter_list_num
, data_someip_parameter_list
);
1362 UAT_HEX_CB_DEF(someip_parameter_enums
, id
, someip_parameter_enum_uat_t
)
1363 UAT_CSTRING_CB_DEF(someip_parameter_enums
, name
, someip_parameter_enum_uat_t
)
1364 UAT_DEC_CB_DEF(someip_parameter_enums
, data_type
, someip_parameter_enum_uat_t
)
1365 UAT_HEX_CB_DEF(someip_parameter_enums
, id_ref
, someip_parameter_enum_uat_t
)
1366 UAT_DEC_CB_DEF(someip_parameter_enums
, num_of_items
, someip_parameter_enum_uat_t
)
1368 UAT_HEX_CB_DEF(someip_parameter_enums
, value
, someip_parameter_enum_uat_t
)
1369 UAT_CSTRING_CB_DEF(someip_parameter_enums
, value_name
, someip_parameter_enum_uat_t
)
1372 copy_someip_parameter_enum_cb(void *n
, const void *o
, size_t size _U_
) {
1373 someip_parameter_enum_uat_t
*new_rec
= (someip_parameter_enum_uat_t
*)n
;
1374 const someip_parameter_enum_uat_t
*old_rec
= (const someip_parameter_enum_uat_t
*)o
;
1376 new_rec
->id
= old_rec
->id
;
1377 if (old_rec
->name
) {
1378 new_rec
->name
= g_strdup(old_rec
->name
);
1380 new_rec
->name
= NULL
;
1382 new_rec
->data_type
= old_rec
->data_type
;
1383 new_rec
->id_ref
= old_rec
->id_ref
;
1384 new_rec
->num_of_items
= old_rec
->num_of_items
;
1386 new_rec
->value
= old_rec
->value
;
1387 if (old_rec
->value_name
) {
1388 new_rec
->value_name
= g_strdup(old_rec
->value_name
);
1390 new_rec
->value_name
= NULL
;
1397 update_someip_parameter_enum(void *r
, char **err
) {
1398 someip_parameter_enum_uat_t
*rec
= (someip_parameter_enum_uat_t
*)r
;
1400 /* enum name is not used in a filter yet. */
1402 if (rec
->name
== NULL
|| rec
->name
[0] == 0) {
1403 *err
= ws_strdup_printf("Name cannot be empty (ID: 0x%x)!", rec
->id
);
1407 if (rec
->value_name
== NULL
|| rec
->value_name
[0] == 0) {
1408 *err
= ws_strdup_printf("Value Name cannot be empty (ID: 0x%x)!", rec
->id
);
1412 if (rec
->num_of_items
== 0) {
1413 *err
= ws_strdup_printf("Number_of_Items = 0 (ID: 0x%x)!", rec
->id
);
1417 if (rec
->data_type
== SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ENUM
) {
1418 *err
= ws_strdup_printf("An enum cannot reference an enum (ID: 0x%x)!", rec
->id
);
1426 free_someip_parameter_enum_cb(void *r
) {
1427 someip_parameter_enum_uat_t
*rec
= (someip_parameter_enum_uat_t
*)r
;
1433 if (rec
->value_name
) {
1434 g_free(rec
->value_name
);
1435 rec
->value_name
= NULL
;
1440 free_someip_parameter_enum(void *data
) {
1441 someip_payload_parameter_enum_t
*list
= (someip_payload_parameter_enum_t
*)data
;
1443 if (list
->items
!= NULL
) {
1444 wmem_free(wmem_epan_scope(), (void *)(list
->items
));
1448 wmem_free(wmem_epan_scope(), (void *)data
);
1452 post_update_someip_parameter_enum_read_in_data(someip_parameter_enum_uat_t
*data
, unsigned data_num
, GHashTable
*ht
) {
1455 int64_t *key
= NULL
;
1456 someip_payload_parameter_enum_t
*list
= NULL
;
1457 someip_payload_parameter_enum_item_t
*item
= NULL
;
1459 if (ht
== NULL
|| data
== NULL
|| data_num
== 0) {
1463 for (i
= 0; i
< data_num
; i
++) {
1464 key
= wmem_new(wmem_epan_scope(), int64_t);
1467 list
= (someip_payload_parameter_enum_t
*)g_hash_table_lookup(ht
, key
);
1470 list
= wmem_new(wmem_epan_scope(), someip_payload_parameter_enum_t
);
1471 INIT_SOMEIP_PAYLOAD_PARAMETER_ENUM(list
)
1473 list
->id
= data
[i
].id
;
1474 list
->name
= data
[i
].name
;
1475 list
->data_type
= data
[i
].data_type
;
1476 list
->id_ref
= data
[i
].id_ref
;
1477 list
->num_of_items
= data
[i
].num_of_items
;
1479 list
->items
= (someip_payload_parameter_enum_item_t
*)wmem_alloc0_array(wmem_epan_scope(), someip_payload_parameter_enum_item_t
, list
->num_of_items
);
1481 /* create new entry ... */
1482 g_hash_table_insert(ht
, key
, list
);
1484 /* don't need it anymore */
1485 wmem_free(wmem_epan_scope(), key
);
1488 /* and now we add to item array */
1489 if (list
->num_of_items
> 0 && data
[i
].num_of_items
== list
->num_of_items
) {
1491 /* find first empty slot */
1492 for (j
= 0; j
< list
->num_of_items
&& list
->items
[j
].name
!= NULL
; j
++);
1494 if (j
< list
->num_of_items
) {
1495 item
= &(list
->items
[j
]);
1496 INIT_SOMEIP_PAYLOAD_PARAMETER_ENUM_ITEM(item
)
1498 /* we do not care if we overwrite param */
1499 item
->value
= data
[i
].value
;
1500 item
->name
= data
[i
].value_name
;
1507 reset_someip_parameter_enum_cb(void) {
1508 /* destroy old hash table, if it exists */
1509 if (data_someip_parameter_enums
) {
1510 g_hash_table_destroy(data_someip_parameter_enums
);
1511 data_someip_parameter_enums
= NULL
;
1514 set_prefs_changed();
1518 post_update_someip_parameter_enum_cb(void) {
1519 reset_someip_parameter_enum_cb();
1521 data_someip_parameter_enums
= g_hash_table_new_full(g_int64_hash
, g_int64_equal
, &someip_payload_free_key
, &free_someip_parameter_enum
);
1522 post_update_someip_parameter_enum_read_in_data(someip_parameter_enums
, someip_parameter_enums_num
, data_someip_parameter_enums
);
1525 UAT_HEX_CB_DEF(someip_parameter_arrays
, id
, someip_parameter_array_uat_t
)
1526 UAT_CSTRING_CB_DEF(someip_parameter_arrays
, name
, someip_parameter_array_uat_t
)
1527 UAT_DEC_CB_DEF(someip_parameter_arrays
, data_type
, someip_parameter_array_uat_t
)
1528 UAT_HEX_CB_DEF(someip_parameter_arrays
, id_ref
, someip_parameter_array_uat_t
)
1529 UAT_DEC_CB_DEF(someip_parameter_arrays
, num_of_dims
, someip_parameter_array_uat_t
)
1530 UAT_CSTRING_CB_DEF(someip_parameter_arrays
, filter_string
, someip_parameter_array_uat_t
)
1532 UAT_DEC_CB_DEF(someip_parameter_arrays
, num
, someip_parameter_array_uat_t
)
1533 UAT_DEC_CB_DEF(someip_parameter_arrays
, lower_limit
, someip_parameter_array_uat_t
)
1534 UAT_DEC_CB_DEF(someip_parameter_arrays
, upper_limit
, someip_parameter_array_uat_t
)
1535 UAT_DEC_CB_DEF(someip_parameter_arrays
, length_of_length
, someip_parameter_array_uat_t
)
1536 UAT_DEC_CB_DEF(someip_parameter_arrays
, pad_to
, someip_parameter_array_uat_t
)
1539 copy_someip_parameter_array_cb(void *n
, const void *o
, size_t size _U_
) {
1540 someip_parameter_array_uat_t
*new_rec
= (someip_parameter_array_uat_t
*)n
;
1541 const someip_parameter_array_uat_t
*old_rec
= (const someip_parameter_array_uat_t
*)o
;
1543 new_rec
->id
= old_rec
->id
;
1544 if (old_rec
->name
) {
1545 new_rec
->name
= g_strdup(old_rec
->name
);
1547 new_rec
->name
= NULL
;
1549 new_rec
->data_type
= old_rec
->data_type
;
1550 new_rec
->id_ref
= old_rec
->id_ref
;
1551 new_rec
->num_of_dims
= old_rec
->num_of_dims
;
1552 if (old_rec
->filter_string
) {
1553 new_rec
->filter_string
= g_strdup(old_rec
->filter_string
);
1555 new_rec
->filter_string
= NULL
;
1558 new_rec
->num
= old_rec
->num
;
1559 new_rec
->lower_limit
= old_rec
->lower_limit
;
1560 new_rec
->upper_limit
= old_rec
->upper_limit
;
1561 new_rec
->length_of_length
= old_rec
->length_of_length
;
1562 new_rec
->pad_to
= old_rec
->pad_to
;
1568 update_someip_parameter_array(void *r
, char **err
) {
1569 someip_parameter_array_uat_t
*rec
= (someip_parameter_array_uat_t
*)r
;
1572 if (rec
->name
== NULL
|| rec
->name
[0] == 0) {
1573 *err
= ws_strdup_printf("Name cannot be empty (ID: 0x%x)!", rec
->id
);
1577 if (rec
->num
>= rec
->num_of_dims
) {
1578 *err
= ws_strdup_printf("Dimension >= Number of Dimensions (ID: 0x%x)!", rec
->id
);
1582 if (rec
->filter_string
== NULL
|| rec
->filter_string
[0] == 0) {
1583 *err
= ws_strdup_printf("Filter String cannot be empty (ID: 0x%x)!", rec
->id
);
1587 tmp
= check_filter_string(rec
->filter_string
, rec
->id
);
1593 if (rec
->data_type
== SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ARRAY
&& rec
->id
== rec
->id_ref
) {
1594 *err
= ws_strdup_printf("An array cannot include itself (ID: 0x%x)!", rec
->id
);
1602 free_someip_parameter_array_cb(void *r
) {
1603 someip_parameter_array_uat_t
*rec
= (someip_parameter_array_uat_t
*)r
;
1605 if (rec
->name
) g_free(rec
->name
);
1608 if (rec
->filter_string
) g_free(rec
->filter_string
);
1609 rec
->filter_string
= NULL
;
1613 free_someip_parameter_array(void *data
) {
1614 someip_parameter_array_t
*list
= (someip_parameter_array_t
*)data
;
1616 if (list
->dims
!= NULL
) {
1617 wmem_free(wmem_epan_scope(), (void *)(list
->dims
));
1621 wmem_free(wmem_epan_scope(), (void *)data
);
1625 post_update_someip_parameter_array_read_in_data(someip_parameter_array_uat_t
*data
, unsigned data_num
, GHashTable
*ht
) {
1627 int64_t *key
= NULL
;
1628 someip_parameter_array_t
*list
= NULL
;
1629 someip_parameter_array_dim_t
*item
= NULL
;
1630 someip_parameter_array_dim_t
*items
= NULL
;
1632 if (ht
== NULL
|| data
== NULL
|| data_num
== 0) {
1636 for (i
= 0; i
< data_num
; i
++) {
1637 key
= wmem_new(wmem_epan_scope(), int64_t);
1640 list
= (someip_parameter_array_t
*)g_hash_table_lookup(ht
, key
);
1643 list
= wmem_new(wmem_epan_scope(), someip_parameter_array_t
);
1645 list
->id
= data
[i
].id
;
1646 list
->name
= data
[i
].name
;
1647 list
->data_type
= data
[i
].data_type
;
1648 list
->id_ref
= data
[i
].id_ref
;
1649 list
->num_of_dims
= data
[i
].num_of_dims
;
1650 list
->filter_string
= data
[i
].filter_string
;
1652 items
= (someip_parameter_array_dim_t
*)wmem_alloc0_array(wmem_epan_scope(), someip_parameter_array_dim_t
, data
[i
].num_of_dims
);
1655 /* create new entry ... */
1656 g_hash_table_insert(ht
, key
, list
);
1659 /* and now we add to item array */
1660 if (data
[i
].num_of_dims
== list
->num_of_dims
&& data
[i
].num
< list
->num_of_dims
) {
1661 item
= &(list
->dims
[data
[i
].num
]);
1663 /* we do not care if we overwrite param */
1664 item
->num
= data
[i
].num
;
1665 item
->lower_limit
= data
[i
].lower_limit
;
1666 item
->upper_limit
= data
[i
].upper_limit
;
1667 item
->length_of_length
= data
[i
].length_of_length
;
1668 item
->pad_to
= data
[i
].pad_to
;
1674 reset_someip_parameter_array_cb(void) {
1675 /* destroy old hash table, if it exists */
1676 if (data_someip_parameter_arrays
) {
1677 deregister_dynamic_hf_data(&dynamic_hf_array
, &dynamic_hf_array_size
);
1678 g_hash_table_destroy(data_someip_parameter_arrays
);
1679 data_someip_parameter_arrays
= NULL
;
1682 set_prefs_changed();
1686 post_update_someip_parameter_array_cb(void) {
1687 reset_someip_parameter_array_cb();
1689 data_someip_parameter_arrays
= g_hash_table_new_full(g_int64_hash
, g_int64_equal
, &someip_payload_free_key
, &free_someip_parameter_array
);
1690 post_update_someip_parameter_array_read_in_data(someip_parameter_arrays
, someip_parameter_arrays_num
, data_someip_parameter_arrays
);
1693 UAT_HEX_CB_DEF(someip_parameter_structs
, id
, someip_parameter_struct_uat_t
)
1694 UAT_CSTRING_CB_DEF(someip_parameter_structs
, struct_name
, someip_parameter_struct_uat_t
)
1695 UAT_DEC_CB_DEF(someip_parameter_structs
, length_of_length
, someip_parameter_struct_uat_t
)
1696 UAT_DEC_CB_DEF(someip_parameter_structs
, pad_to
, someip_parameter_struct_uat_t
)
1697 UAT_BOOL_CB_DEF(someip_parameter_structs
, wtlv_encoding
, someip_parameter_struct_uat_t
)
1698 UAT_DEC_CB_DEF(someip_parameter_structs
, num_of_items
, someip_parameter_struct_uat_t
)
1700 UAT_DEC_CB_DEF(someip_parameter_structs
, pos
, someip_parameter_struct_uat_t
)
1701 UAT_CSTRING_CB_DEF(someip_parameter_structs
, name
, someip_parameter_struct_uat_t
)
1702 UAT_DEC_CB_DEF(someip_parameter_structs
, data_type
, someip_parameter_struct_uat_t
)
1703 UAT_HEX_CB_DEF(someip_parameter_structs
, id_ref
, someip_parameter_struct_uat_t
)
1704 UAT_CSTRING_CB_DEF(someip_parameter_structs
, filter_string
, someip_parameter_struct_uat_t
)
1707 copy_someip_parameter_struct_cb(void *n
, const void *o
, size_t size _U_
) {
1708 someip_parameter_struct_uat_t
*new_rec
= (someip_parameter_struct_uat_t
*)n
;
1709 const someip_parameter_struct_uat_t
*old_rec
= (const someip_parameter_struct_uat_t
*)o
;
1711 new_rec
->id
= old_rec
->id
;
1713 if (old_rec
->struct_name
) {
1714 new_rec
->struct_name
= g_strdup(old_rec
->struct_name
);
1716 new_rec
->struct_name
= NULL
;
1719 new_rec
->length_of_length
= old_rec
->length_of_length
;
1720 new_rec
->pad_to
= old_rec
->pad_to
;
1721 new_rec
->wtlv_encoding
= old_rec
->wtlv_encoding
;
1722 new_rec
->num_of_items
= old_rec
->num_of_items
;
1724 new_rec
->pos
= old_rec
->pos
;
1726 if (old_rec
->name
) {
1727 new_rec
->name
= g_strdup(old_rec
->name
);
1729 new_rec
->name
= NULL
;
1732 new_rec
->data_type
= old_rec
->data_type
;
1733 new_rec
->id_ref
= old_rec
->id_ref
;
1735 if (old_rec
->filter_string
) {
1736 new_rec
->filter_string
= g_strdup(old_rec
->filter_string
);
1738 new_rec
->filter_string
= NULL
;
1745 update_someip_parameter_struct(void *r
, char **err
) {
1746 someip_parameter_struct_uat_t
*rec
= (someip_parameter_struct_uat_t
*)r
;
1749 if (rec
->struct_name
== NULL
|| rec
->struct_name
[0] == 0) {
1750 *err
= ws_strdup_printf("Struct name cannot be empty (ID: 0x%x)!", rec
->id
);
1754 if (rec
->filter_string
== NULL
|| rec
->filter_string
[0] == 0) {
1755 *err
= ws_strdup_printf("Struct name cannot be empty (ID: 0x%x)!", rec
->id
);
1759 tmp
= check_filter_string(rec
->filter_string
, rec
->id
);
1765 if (rec
->name
== NULL
|| rec
->name
[0] == 0) {
1766 *err
= ws_strdup_printf("Name cannot be empty (ID: 0x%x)!", rec
->id
);
1770 if (rec
->pos
>= rec
->num_of_items
) {
1771 *err
= ws_strdup_printf("Position >= Number of Parameters (ID: 0x%x)!", rec
->id
);
1775 if (rec
->data_type
== SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_STRUCT
&& rec
->id
== rec
->id_ref
) {
1776 *err
= ws_strdup_printf("A struct cannot include itself (ID: 0x%x)!", rec
->id
);
1784 free_someip_parameter_struct_cb(void *r
) {
1785 someip_parameter_struct_uat_t
*rec
= (someip_parameter_struct_uat_t
*)r
;
1787 if (rec
->struct_name
) g_free(rec
->struct_name
);
1788 rec
->struct_name
= NULL
;
1790 if (rec
->name
) g_free(rec
->name
);
1793 if (rec
->filter_string
) g_free(rec
->filter_string
);
1794 rec
->filter_string
= NULL
;
1798 free_someip_parameter_struct(void *data
) {
1799 someip_payload_parameter_struct_t
*list
= (someip_payload_parameter_struct_t
*)data
;
1801 if (list
->items
!= NULL
) {
1802 wmem_free(wmem_epan_scope(), (void *)(list
->items
));
1806 wmem_free(wmem_epan_scope(), (void *)data
);
1810 post_update_someip_parameter_struct_read_in_data(someip_parameter_struct_uat_t
*data
, unsigned data_num
, GHashTable
*ht
) {
1812 int64_t *key
= NULL
;
1813 someip_payload_parameter_struct_t
*list
= NULL
;
1814 someip_payload_parameter_item_t
*item
= NULL
;
1815 someip_payload_parameter_item_t
*items
= NULL
;
1817 if (ht
== NULL
|| data
== NULL
|| data_num
== 0) {
1821 for (i
= 0; i
< data_num
; i
++) {
1822 key
= wmem_new(wmem_epan_scope(), int64_t);
1825 list
= (someip_payload_parameter_struct_t
*)g_hash_table_lookup(ht
, key
);
1827 list
= wmem_new(wmem_epan_scope(), someip_payload_parameter_struct_t
);
1828 INIT_SOMEIP_PAYLOAD_PARAMETER_STRUCT(list
)
1830 list
->id
= data
[i
].id
;
1831 list
->struct_name
= data
[i
].struct_name
;
1832 list
->length_of_length
= data
[i
].length_of_length
;
1833 list
->pad_to
= data
[i
].pad_to
;
1834 list
->wtlv_encoding
= data
[i
].wtlv_encoding
;
1835 list
->num_of_items
= data
[i
].num_of_items
;
1837 items
= (someip_payload_parameter_item_t
*)wmem_alloc0_array(wmem_epan_scope(), someip_payload_parameter_item_t
, data
[i
].num_of_items
);
1838 list
->items
= items
;
1840 /* create new entry ... */
1841 g_hash_table_insert(ht
, key
, list
);
1844 /* and now we add to item array */
1845 if (data
[i
].num_of_items
== list
->num_of_items
&& data
[i
].pos
< list
->num_of_items
) {
1846 item
= &(list
->items
[data
[i
].pos
]);
1847 INIT_SOMEIP_PAYLOAD_PARAMETER_ITEM(item
)
1849 /* we do not care if we overwrite param */
1850 item
->name
= data
[i
].name
;
1851 item
->id_ref
= data
[i
].id_ref
;
1852 item
->pos
= data
[i
].pos
;
1853 item
->data_type
= data
[i
].data_type
;
1854 item
->filter_string
= data
[i
].filter_string
;
1860 reset_someip_parameter_struct_cb(void) {
1861 /* destroy old hash table, if it exists */
1862 if (data_someip_parameter_structs
) {
1863 deregister_dynamic_hf_data(&dynamic_hf_struct
, &dynamic_hf_struct_size
);
1864 g_hash_table_destroy(data_someip_parameter_structs
);
1865 data_someip_parameter_structs
= NULL
;
1868 set_prefs_changed();
1872 post_update_someip_parameter_struct_cb(void) {
1873 reset_someip_parameter_struct_cb();
1875 data_someip_parameter_structs
= g_hash_table_new_full(g_int64_hash
, g_int64_equal
, &someip_payload_free_key
, &free_someip_parameter_struct
);
1876 post_update_someip_parameter_struct_read_in_data(someip_parameter_structs
, someip_parameter_structs_num
, data_someip_parameter_structs
);
1879 UAT_HEX_CB_DEF(someip_parameter_unions
, id
, someip_parameter_union_uat_t
)
1880 UAT_CSTRING_CB_DEF(someip_parameter_unions
, name
, someip_parameter_union_uat_t
)
1881 UAT_DEC_CB_DEF(someip_parameter_unions
, length_of_length
, someip_parameter_union_uat_t
)
1882 UAT_DEC_CB_DEF(someip_parameter_unions
, length_of_type
, someip_parameter_union_uat_t
)
1883 UAT_DEC_CB_DEF(someip_parameter_unions
, pad_to
, someip_parameter_union_uat_t
)
1885 UAT_DEC_CB_DEF(someip_parameter_unions
, num_of_items
, someip_parameter_union_uat_t
)
1887 UAT_DEC_CB_DEF(someip_parameter_unions
, type_id
, someip_parameter_union_uat_t
)
1888 UAT_CSTRING_CB_DEF(someip_parameter_unions
, type_name
, someip_parameter_union_uat_t
)
1889 UAT_DEC_CB_DEF(someip_parameter_unions
, data_type
, someip_parameter_union_uat_t
)
1890 UAT_HEX_CB_DEF(someip_parameter_unions
, id_ref
, someip_parameter_union_uat_t
)
1891 UAT_CSTRING_CB_DEF(someip_parameter_unions
, filter_string
, someip_parameter_union_uat_t
)
1894 copy_someip_parameter_union_cb(void *n
, const void *o
, size_t size _U_
) {
1895 someip_parameter_union_uat_t
*new_rec
= (someip_parameter_union_uat_t
*)n
;
1896 const someip_parameter_union_uat_t
*old_rec
= (const someip_parameter_union_uat_t
*)o
;
1898 new_rec
->id
= old_rec
->id
;
1900 if (old_rec
->name
) {
1901 new_rec
->name
= g_strdup(old_rec
->name
);
1903 new_rec
->name
= NULL
;
1906 new_rec
->length_of_length
= old_rec
->length_of_length
;
1907 new_rec
->length_of_type
= old_rec
->length_of_type
;
1908 new_rec
->pad_to
= old_rec
->pad_to
;
1909 new_rec
->num_of_items
= old_rec
->num_of_items
;
1910 new_rec
->type_id
= old_rec
->type_id
;
1912 if (old_rec
->type_name
) {
1913 new_rec
->type_name
= g_strdup(old_rec
->type_name
);
1915 new_rec
->type_name
= NULL
;
1918 new_rec
->data_type
= old_rec
->data_type
;
1919 new_rec
->id_ref
= old_rec
->id_ref
;
1921 if (old_rec
->filter_string
) {
1922 new_rec
->filter_string
= g_strdup(old_rec
->filter_string
);
1924 new_rec
->filter_string
= NULL
;
1931 update_someip_parameter_union(void *r
, char **err
) {
1932 someip_parameter_union_uat_t
*rec
= (someip_parameter_union_uat_t
*)r
;
1935 if (rec
->name
== NULL
|| rec
->name
[0] == 0) {
1936 *err
= ws_strdup_printf("Union name cannot be empty (ID: 0x%x)!", rec
->id
);
1940 tmp
= check_filter_string(rec
->filter_string
, rec
->id
);
1946 if (rec
->type_name
== NULL
|| rec
->type_name
[0] == 0) {
1947 *err
= ws_strdup_printf("Type Name cannot be empty (ID: 0x%x)!", rec
->id
);
1951 if (rec
->data_type
== SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_UNION
&& rec
->id
== rec
->id_ref
) {
1952 *err
= ws_strdup_printf("A union cannot include itself (ID: 0x%x)!", rec
->id
);
1960 free_someip_parameter_union_cb(void *r
) {
1961 someip_parameter_union_uat_t
*rec
= (someip_parameter_union_uat_t
*)r
;
1968 if (rec
->type_name
) {
1969 g_free(rec
->type_name
);
1970 rec
->type_name
= NULL
;
1973 if (rec
->filter_string
) {
1974 g_free(rec
->filter_string
);
1975 rec
->filter_string
= NULL
;
1980 free_someip_parameter_union(void *data
) {
1981 someip_parameter_union_t
*list
= (someip_parameter_union_t
*)data
;
1983 if (list
->items
!= NULL
) {
1984 wmem_free(wmem_epan_scope(), (void *)(list
->items
));
1988 wmem_free(wmem_epan_scope(), (void *)data
);
1992 post_update_someip_parameter_union_read_in_data(someip_parameter_union_uat_t
*data
, unsigned data_num
, GHashTable
*ht
) {
1995 int64_t *key
= NULL
;
1996 someip_parameter_union_t
*list
= NULL
;
1997 someip_parameter_union_item_t
*item
= NULL
;
1999 if (ht
== NULL
|| data
== NULL
|| data_num
== 0) {
2003 for (i
= 0; i
< data_num
; i
++) {
2004 key
= wmem_new(wmem_epan_scope(), int64_t);
2007 list
= (someip_parameter_union_t
*)g_hash_table_lookup(ht
, key
);
2010 list
= wmem_new(wmem_epan_scope(), someip_parameter_union_t
);
2012 list
->id
= data
[i
].id
;
2013 list
->name
= data
[i
].name
;
2014 list
->length_of_length
= data
[i
].length_of_length
;
2015 list
->length_of_type
= data
[i
].length_of_type
;
2016 list
->pad_to
= data
[i
].pad_to
;
2017 list
->num_of_items
= data
[i
].num_of_items
;
2019 list
->items
= (someip_parameter_union_item_t
*)wmem_alloc0_array(wmem_epan_scope(), someip_parameter_union_item_t
, list
->num_of_items
);
2021 /* create new entry ... */
2022 g_hash_table_insert(ht
, key
, list
);
2024 /* don't need it anymore */
2025 wmem_free(wmem_epan_scope(), key
);
2028 /* and now we add to item array */
2029 if (data
[i
].num_of_items
== list
->num_of_items
) {
2031 /* find first empty slot */
2032 for (j
= 0; j
< list
->num_of_items
&& list
->items
[j
].name
!= NULL
; j
++);
2034 if (j
< list
->num_of_items
) {
2035 item
= &(list
->items
[j
]);
2037 /* we do not care if we overwrite param */
2038 item
->id
= data
[i
].type_id
;
2039 item
->name
= data
[i
].type_name
;
2040 item
->data_type
= data
[i
].data_type
;
2041 item
->id_ref
= data
[i
].id_ref
;
2042 item
->filter_string
= data
[i
].filter_string
;
2049 reset_someip_parameter_union_cb(void) {
2050 /* destroy old hash table, if it exists */
2051 if (data_someip_parameter_unions
) {
2052 deregister_dynamic_hf_data(&dynamic_hf_union
, &dynamic_hf_union_size
);
2053 g_hash_table_destroy(data_someip_parameter_unions
);
2054 data_someip_parameter_unions
= NULL
;
2057 set_prefs_changed();
2061 post_update_someip_parameter_union_cb(void) {
2062 reset_someip_parameter_union_cb();
2064 data_someip_parameter_unions
= g_hash_table_new_full(g_int64_hash
, g_int64_equal
, &someip_payload_free_key
, &free_someip_parameter_union
);
2065 post_update_someip_parameter_union_read_in_data(someip_parameter_unions
, someip_parameter_unions_num
, data_someip_parameter_unions
);
2068 UAT_HEX_CB_DEF(someip_parameter_base_type_list
, id
, someip_parameter_base_type_list_uat_t
)
2069 UAT_CSTRING_CB_DEF(someip_parameter_base_type_list
, name
, someip_parameter_base_type_list_uat_t
)
2070 UAT_CSTRING_CB_DEF(someip_parameter_base_type_list
, data_type
, someip_parameter_base_type_list_uat_t
)
2071 UAT_BOOL_CB_DEF(someip_parameter_base_type_list
, big_endian
, someip_parameter_base_type_list_uat_t
)
2072 UAT_DEC_CB_DEF(someip_parameter_base_type_list
, bitlength_base_type
, someip_parameter_base_type_list_uat_t
)
2073 UAT_DEC_CB_DEF(someip_parameter_base_type_list
, bitlength_encoded_type
, someip_parameter_base_type_list_uat_t
)
2076 copy_someip_parameter_base_type_list_cb(void *n
, const void *o
, size_t size _U_
) {
2077 someip_parameter_base_type_list_uat_t
*new_rec
= (someip_parameter_base_type_list_uat_t
*)n
;
2078 const someip_parameter_base_type_list_uat_t
*old_rec
= (const someip_parameter_base_type_list_uat_t
*)o
;
2080 if (old_rec
->name
) {
2081 new_rec
->name
= g_strdup(old_rec
->name
);
2083 new_rec
->name
= NULL
;
2086 if (old_rec
->data_type
) {
2087 new_rec
->data_type
= g_strdup(old_rec
->data_type
);
2089 new_rec
->data_type
= NULL
;
2092 new_rec
->id
= old_rec
->id
;
2093 new_rec
->big_endian
= old_rec
->big_endian
;
2094 new_rec
->bitlength_base_type
= old_rec
->bitlength_base_type
;
2095 new_rec
->bitlength_encoded_type
= old_rec
->bitlength_encoded_type
;
2101 update_someip_parameter_base_type_list(void *r
, char **err
) {
2102 someip_parameter_base_type_list_uat_t
*rec
= (someip_parameter_base_type_list_uat_t
*)r
;
2104 if (rec
->name
== NULL
|| rec
->name
[0] == 0) {
2105 *err
= ws_strdup_printf("Name cannot be empty (ID: 0x%x)!", rec
->id
);
2109 if (rec
->id
> 0xffffffff) {
2110 *err
= ws_strdup_printf("We currently only support 32 bit IDs (%i) Name: %s", rec
->id
, rec
->name
);
2114 if (rec
->bitlength_base_type
!= 8 && rec
->bitlength_base_type
!= 16 && rec
->bitlength_base_type
!= 32 && rec
->bitlength_base_type
!= 64) {
2115 *err
= ws_strdup_printf("Bit length of base type may only be 8, 16, 32, or 64. Affected item: ID (%i) Name (%s).", rec
->id
, rec
->name
);
2119 /* As long as we check that rec->bitlength_base_type equals rec->bitlength_encoded_type, we do not have to check that bitlength_encoded_type is 8, 16, 32, or 64. */
2121 if (rec
->bitlength_base_type
!= rec
->bitlength_encoded_type
) {
2122 *err
= ws_strdup_printf("Bit length of encoded type must be equal to bit length of base type. Affected item: ID (%i) Name (%s). Shortened types supported by Signal-PDU dissector.", rec
->id
, rec
->name
);
2130 free_someip_parameter_base_type_list_cb(void *r
) {
2131 someip_parameter_base_type_list_uat_t
*rec
= (someip_parameter_base_type_list_uat_t
*)r
;
2138 if (rec
->data_type
) {
2139 g_free(rec
->data_type
);
2140 rec
->data_type
= NULL
;
2145 reset_someip_parameter_base_type_list_cb(void) {
2146 /* destroy old hash table, if it exists */
2147 if (data_someip_parameter_base_type_list
) {
2148 g_hash_table_destroy(data_someip_parameter_base_type_list
);
2149 data_someip_parameter_base_type_list
= NULL
;
2152 set_prefs_changed();
2156 post_update_someip_parameter_base_type_list_cb(void) {
2158 int64_t *key
= NULL
;
2160 reset_someip_parameter_base_type_list_cb();
2162 /* we don't need to free the data as long as we don't alloc it first */
2163 data_someip_parameter_base_type_list
= g_hash_table_new_full(g_int64_hash
, g_int64_equal
, &someip_payload_free_key
, NULL
);
2165 if (data_someip_parameter_base_type_list
== NULL
|| someip_parameter_base_type_list
== NULL
|| someip_parameter_base_type_list_num
== 0) {
2169 if (someip_parameter_base_type_list_num
> 0) {
2170 for (i
= 0; i
< someip_parameter_base_type_list_num
; i
++) {
2171 key
= wmem_new(wmem_epan_scope(), int64_t);
2172 *key
= someip_parameter_base_type_list
[i
].id
;
2174 g_hash_table_insert(data_someip_parameter_base_type_list
, key
, &someip_parameter_base_type_list
[i
]);
2179 UAT_HEX_CB_DEF(someip_parameter_strings
, id
, someip_parameter_string_uat_t
)
2180 UAT_CSTRING_CB_DEF(someip_parameter_strings
, name
, someip_parameter_string_uat_t
)
2181 UAT_CSTRING_CB_DEF(someip_parameter_strings
, encoding
, someip_parameter_string_uat_t
)
2182 UAT_BOOL_CB_DEF(someip_parameter_strings
, dynamic_length
, someip_parameter_string_uat_t
)
2183 UAT_DEC_CB_DEF(someip_parameter_strings
, max_length
, someip_parameter_string_uat_t
)
2184 UAT_DEC_CB_DEF(someip_parameter_strings
, length_of_length
, someip_parameter_string_uat_t
)
2185 UAT_BOOL_CB_DEF(someip_parameter_strings
, big_endian
, someip_parameter_string_uat_t
)
2186 UAT_DEC_CB_DEF(someip_parameter_strings
, pad_to
, someip_parameter_string_uat_t
)
2189 copy_someip_parameter_string_list_cb(void *n
, const void *o
, size_t size _U_
) {
2190 someip_parameter_string_uat_t
*new_rec
= (someip_parameter_string_uat_t
*)n
;
2191 const someip_parameter_string_uat_t
*old_rec
= (const someip_parameter_string_uat_t
*)o
;
2193 if (old_rec
->name
) {
2194 new_rec
->name
= g_strdup(old_rec
->name
);
2196 new_rec
->name
= NULL
;
2199 if (old_rec
->encoding
) {
2200 new_rec
->encoding
= g_strdup(old_rec
->encoding
);
2202 new_rec
->encoding
= NULL
;
2205 new_rec
->id
= old_rec
->id
;
2206 new_rec
->dynamic_length
= old_rec
->dynamic_length
;
2207 new_rec
->max_length
= old_rec
->max_length
;
2208 new_rec
->length_of_length
= old_rec
->length_of_length
;
2209 new_rec
->big_endian
= old_rec
->big_endian
;
2210 new_rec
->pad_to
= old_rec
->pad_to
;
2216 update_someip_parameter_string_list(void *r
, char **err
) {
2217 someip_parameter_string_uat_t
*rec
= (someip_parameter_string_uat_t
*)r
;
2219 if (rec
->name
== NULL
|| rec
->name
[0] == 0) {
2220 *err
= ws_strdup_printf("Name cannot be empty (ID: 0x%x)!", rec
->id
);
2224 if (rec
->id
> 0xffffffff) {
2225 *err
= ws_strdup_printf("We currently only support 32 bit IDs (%i) Name: %s", rec
->id
, rec
->name
);
2229 if (rec
->max_length
> 0xffffffff) {
2230 *err
= ws_strdup_printf("We currently only support 32 bit max_length (%i) Name: %s", rec
->max_length
, rec
->name
);
2234 if (rec
->length_of_length
!= 0 && rec
->length_of_length
!= 8 && rec
->length_of_length
!= 16 && rec
->length_of_length
!= 32) {
2235 *err
= ws_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
);
2243 free_someip_parameter_string_list_cb(void *r
) {
2244 someip_parameter_string_uat_t
*rec
= (someip_parameter_string_uat_t
*)r
;
2251 if (rec
->encoding
) {
2252 g_free(rec
->encoding
);
2253 rec
->encoding
= NULL
;
2258 reset_someip_parameter_string_list_cb(void) {
2259 /* destroy old hash table, if it exists */
2260 if (data_someip_parameter_strings
) {
2261 g_hash_table_destroy(data_someip_parameter_strings
);
2262 data_someip_parameter_strings
= NULL
;
2265 set_prefs_changed();
2269 post_update_someip_parameter_string_list_cb(void) {
2271 int64_t *key
= NULL
;
2273 reset_someip_parameter_string_list_cb();
2275 /* we don't need to free the data as long as we don't alloc it first */
2276 data_someip_parameter_strings
= g_hash_table_new_full(g_int64_hash
, g_int64_equal
, &someip_payload_free_key
, NULL
);
2278 if (data_someip_parameter_strings
== NULL
|| someip_parameter_strings
== NULL
|| someip_parameter_strings_num
== 0) {
2282 if (someip_parameter_strings_num
> 0) {
2283 for (i
= 0; i
< someip_parameter_strings_num
; i
++) {
2284 key
= wmem_new(wmem_epan_scope(), int64_t);
2285 *key
= someip_parameter_strings
[i
].id
;
2287 g_hash_table_insert(data_someip_parameter_strings
, key
, &someip_parameter_strings
[i
]);
2292 UAT_HEX_CB_DEF(someip_parameter_typedefs
, id
, someip_parameter_typedef_uat_t
)
2293 UAT_CSTRING_CB_DEF(someip_parameter_typedefs
, name
, someip_parameter_typedef_uat_t
)
2294 UAT_DEC_CB_DEF(someip_parameter_typedefs
, data_type
, someip_parameter_typedef_uat_t
)
2295 UAT_HEX_CB_DEF(someip_parameter_typedefs
, id_ref
, someip_parameter_typedef_uat_t
)
2298 copy_someip_parameter_typedef_list_cb(void *n
, const void *o
, size_t size _U_
) {
2299 someip_parameter_typedef_uat_t
*new_rec
= (someip_parameter_typedef_uat_t
*)n
;
2300 const someip_parameter_typedef_uat_t
*old_rec
= (const someip_parameter_typedef_uat_t
*)o
;
2302 if (old_rec
->name
) {
2303 new_rec
->name
= g_strdup(old_rec
->name
);
2305 new_rec
->name
= NULL
;
2308 new_rec
->id
= old_rec
->id
;
2309 new_rec
->data_type
= old_rec
->data_type
;
2310 new_rec
->id_ref
= old_rec
->id_ref
;
2316 update_someip_parameter_typedef_list(void *r
, char **err
) {
2317 someip_parameter_typedef_uat_t
*rec
= (someip_parameter_typedef_uat_t
*)r
;
2319 if (rec
->id
> 0xffffffff) {
2320 *err
= ws_strdup_printf("We currently only support 32 bit IDs (%i) Name: %s", rec
->id
, rec
->name
);
2324 if (rec
->data_type
== SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_TYPEDEF
&& rec
->id
== rec
->id_ref
) {
2325 *err
= ws_strdup_printf("A typedef cannot reference itself (ID: 0x%x)!", rec
->id
);
2333 free_someip_parameter_typedef_list_cb(void *r
) {
2334 someip_parameter_typedef_uat_t
*rec
= (someip_parameter_typedef_uat_t
*)r
;
2343 reset_someip_parameter_typedef_list_cb(void) {
2344 /* destroy old hash table, if it exists */
2345 if (data_someip_parameter_typedefs
) {
2346 g_hash_table_destroy(data_someip_parameter_typedefs
);
2347 data_someip_parameter_typedefs
= NULL
;
2350 set_prefs_changed();
2354 post_update_someip_parameter_typedef_list_cb(void) {
2356 int64_t *key
= NULL
;
2358 reset_someip_parameter_typedef_list_cb();
2360 /* we don't need to free the data as long as we don't alloc it first */
2361 data_someip_parameter_typedefs
= g_hash_table_new_full(g_int64_hash
, g_int64_equal
, &someip_payload_free_key
, NULL
);
2363 if (data_someip_parameter_typedefs
== NULL
|| someip_parameter_typedefs
== NULL
|| someip_parameter_typedefs_num
== 0) {
2367 if (someip_parameter_typedefs_num
> 0) {
2368 for (i
= 0; i
< someip_parameter_typedefs_num
; i
++) {
2369 /* key: ID [32bit] */
2370 key
= wmem_new(wmem_epan_scope(), int64_t);
2371 *key
= someip_parameter_typedefs
[i
].id
;
2372 g_hash_table_insert(data_someip_parameter_typedefs
, key
, &someip_parameter_typedefs
[i
]);
2379 deregister_dynamic_hf_data(hf_register_info
**hf_array
, unsigned *hf_size
) {
2381 /* Unregister all fields used before */
2382 for (unsigned i
= 0; i
< *hf_size
; i
++) {
2383 if ((*hf_array
)[i
].p_id
!= NULL
) {
2384 proto_deregister_field(proto_someip
, *((*hf_array
)[i
].p_id
));
2385 g_free((*hf_array
)[i
].p_id
);
2386 (*hf_array
)[i
].p_id
= NULL
;
2389 proto_add_deregistered_data(*hf_array
);
2396 allocate_dynamic_hf_data(hf_register_info
**hf_array
, unsigned *hf_size
, unsigned new_size
) {
2397 *hf_array
= g_new0(hf_register_info
, new_size
);
2398 *hf_size
= new_size
;
2401 typedef struct _param_return_attibutes_t
{
2404 char *base_type_name
;
2405 } param_return_attributes_t
;
2407 static param_return_attributes_t
2408 get_param_attributes(uint8_t data_type
, uint32_t id_ref
) {
2411 param_return_attributes_t ret
;
2413 ret
.display_base
= BASE_NONE
;
2414 ret
.base_type_name
= NULL
;
2416 /* we limit the number of typedef recursion to "count" */
2417 while (data_type
== SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_TYPEDEF
&& count
> 0) {
2418 someip_payload_parameter_typedef_t
*tmp
= get_typedef_config(id_ref
);
2419 /* this should not be a typedef since we don't support recursion of typedefs */
2421 data_type
= tmp
->data_type
;
2422 id_ref
= tmp
->id_ref
;
2427 if (data_type
== SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ENUM
) {
2428 someip_payload_parameter_enum_t
*tmp
= get_enum_config(id_ref
);
2429 /* this can only be a base type ... */
2431 data_type
= tmp
->data_type
;
2432 id_ref
= tmp
->id_ref
;
2436 if (data_type
== SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_STRING
) {
2437 someip_payload_parameter_string_t
*tmp
= get_string_config(id_ref
);
2438 ret
.type
= FT_STRING
;
2439 ret
.display_base
= BASE_NONE
;
2441 ret
.base_type_name
= tmp
->name
;
2446 if (data_type
== SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_BASE_TYPE
) {
2447 someip_payload_parameter_base_type_list_t
*tmp
= get_base_type_config(id_ref
);
2449 ret
.display_base
= BASE_DEC
;
2452 ret
.base_type_name
= tmp
->name
;
2454 if (g_strcmp0(tmp
->data_type
, "uint8") == 0) {
2455 ret
.type
= FT_UINT8
;
2456 } else if (g_strcmp0(tmp
->data_type
, "uint16") == 0) {
2457 ret
.type
= FT_UINT16
;
2458 } else if (g_strcmp0(tmp
->data_type
, "uint24") == 0) {
2459 ret
.type
= FT_UINT24
;
2460 } else if (g_strcmp0(tmp
->data_type
, "uint32") == 0) {
2461 ret
.type
= FT_UINT32
;
2462 } else if (g_strcmp0(tmp
->data_type
, "uint40") == 0) {
2463 ret
.type
= FT_UINT40
;
2464 } else if (g_strcmp0(tmp
->data_type
, "uint48") == 0) {
2465 ret
.type
= FT_UINT48
;
2466 } else if (g_strcmp0(tmp
->data_type
, "uint56") == 0) {
2467 ret
.type
= FT_UINT56
;
2468 } else if (g_strcmp0(tmp
->data_type
, "uint64") == 0) {
2469 ret
.type
= FT_UINT64
;
2470 } else if (g_strcmp0(tmp
->data_type
, "int8") == 0) {
2472 } else if (g_strcmp0(tmp
->data_type
, "int16") == 0) {
2473 ret
.type
= FT_INT16
;
2474 } else if (g_strcmp0(tmp
->data_type
, "int24") == 0) {
2475 ret
.type
= FT_INT24
;
2476 } else if (g_strcmp0(tmp
->data_type
, "int32") == 0) {
2477 ret
.type
= FT_INT32
;
2478 } else if (g_strcmp0(tmp
->data_type
, "int40") == 0) {
2479 ret
.type
= FT_INT40
;
2480 } else if (g_strcmp0(tmp
->data_type
, "int48") == 0) {
2481 ret
.type
= FT_INT48
;
2482 } else if (g_strcmp0(tmp
->data_type
, "int56") == 0) {
2483 ret
.type
= FT_INT56
;
2484 } else if (g_strcmp0(tmp
->data_type
, "int64") == 0) {
2485 ret
.type
= FT_INT64
;
2486 } else if (g_strcmp0(tmp
->data_type
, "float32") == 0) {
2487 ret
.type
= FT_FLOAT
;
2488 ret
.display_base
= BASE_NONE
;
2489 } else if (g_strcmp0(tmp
->data_type
, "float64") == 0) {
2490 ret
.type
= FT_DOUBLE
;
2491 ret
.display_base
= BASE_NONE
;
2500 /* all other types are handled or don't need a type! */
2505 update_dynamic_hf_entry(hf_register_info
*hf_array
, int pos
, uint32_t data_type
, unsigned id_ref
, char *param_name
, char *filter_string
) {
2506 param_return_attributes_t attribs
;
2509 attribs
= get_param_attributes(data_type
, id_ref
);
2510 if (hf_array
== NULL
|| attribs
.type
== FT_NONE
) {
2514 hf_id
= g_new(int, 1);
2516 hf_array
[pos
].p_id
= hf_id
;
2518 hf_array
[pos
].hfinfo
.strings
= NULL
;
2519 hf_array
[pos
].hfinfo
.bitmask
= 0;
2520 hf_array
[pos
].hfinfo
.blurb
= NULL
;
2522 if (attribs
.base_type_name
== NULL
) {
2523 hf_array
[pos
].hfinfo
.name
= g_strdup(param_name
);
2525 hf_array
[pos
].hfinfo
.name
= ws_strdup_printf("%s [%s]", param_name
, attribs
.base_type_name
);
2528 hf_array
[pos
].hfinfo
.abbrev
= ws_strdup_printf("%s.%s", SOMEIP_NAME_PREFIX
, filter_string
);
2529 hf_array
[pos
].hfinfo
.type
= attribs
.type
;
2530 hf_array
[pos
].hfinfo
.display
= attribs
.display_base
;
2532 HFILL_INIT(hf_array
[pos
]);
2538 update_dynamic_param_hf_entry(void *key _U_
, void *value
, void *data
) {
2539 uint32_t *pos
= (uint32_t *)data
;
2540 someip_parameter_list_t
*list
= (someip_parameter_list_t
*)value
;
2543 for (i
= 0; i
< list
->num_of_items
; i
++) {
2544 if (*pos
>= dynamic_hf_param_size
) {
2548 someip_payload_parameter_item_t
*item
= &(list
->items
[i
]);
2550 item
->hf_id
= update_dynamic_hf_entry(dynamic_hf_param
, *pos
, item
->data_type
, item
->id_ref
, item
->name
, item
->filter_string
);
2552 if (item
->hf_id
!= NULL
) {
2559 update_dynamic_array_hf_entry(void *key _U_
, void *value
, void *data
) {
2560 uint32_t *pos
= (uint32_t *)data
;
2561 someip_parameter_array_t
*item
= (someip_parameter_array_t
*)value
;
2563 if (*pos
>= dynamic_hf_array_size
) {
2567 item
->hf_id
= update_dynamic_hf_entry(dynamic_hf_array
, *pos
, item
->data_type
, item
->id_ref
, item
->name
, item
->filter_string
);
2569 if (item
->hf_id
!= NULL
) {
2575 update_dynamic_struct_hf_entry(void *key _U_
, void *value
, void *data
) {
2576 uint32_t *pos
= (uint32_t *)data
;
2577 someip_payload_parameter_struct_t
*list
= (someip_payload_parameter_struct_t
*)value
;
2580 for (i
= 0; i
< list
->num_of_items
; i
++) {
2581 if (*pos
>= dynamic_hf_struct_size
) {
2584 someip_payload_parameter_item_t
*item
= &(list
->items
[i
]);
2586 item
->hf_id
= update_dynamic_hf_entry(dynamic_hf_struct
, *pos
, item
->data_type
, item
->id_ref
, item
->name
, item
->filter_string
);
2588 if (item
->hf_id
!= NULL
) {
2595 update_dynamic_union_hf_entry(void *key _U_
, void *value
, void *data
) {
2596 uint32_t *pos
= (uint32_t *)data
;
2597 someip_parameter_union_t
*list
= (someip_parameter_union_t
*)value
;
2600 for (i
= 0; i
< list
->num_of_items
; i
++) {
2601 if (*pos
>= dynamic_hf_union_size
) {
2605 someip_parameter_union_item_t
*item
= &(list
->items
[i
]);
2607 item
->hf_id
= update_dynamic_hf_entry(dynamic_hf_union
, *pos
, item
->data_type
, item
->id_ref
, item
->name
, item
->filter_string
);
2609 if (item
->hf_id
!= NULL
) {
2616 update_dynamic_hf_entries_someip_parameter_list(void) {
2617 if (data_someip_parameter_list
!= NULL
) {
2618 deregister_dynamic_hf_data(&dynamic_hf_param
, &dynamic_hf_param_size
);
2619 allocate_dynamic_hf_data(&dynamic_hf_param
, &dynamic_hf_param_size
, someip_parameter_list_num
);
2621 g_hash_table_foreach(data_someip_parameter_list
, update_dynamic_param_hf_entry
, &pos
);
2622 proto_register_field_array(proto_someip
, dynamic_hf_param
, pos
);
2627 update_dynamic_hf_entries_someip_parameter_arrays(void) {
2628 if (data_someip_parameter_arrays
!= NULL
) {
2629 deregister_dynamic_hf_data(&dynamic_hf_array
, &dynamic_hf_array_size
);
2630 allocate_dynamic_hf_data(&dynamic_hf_array
, &dynamic_hf_array_size
, someip_parameter_arrays_num
);
2632 g_hash_table_foreach(data_someip_parameter_arrays
, update_dynamic_array_hf_entry
, &pos
);
2633 proto_register_field_array(proto_someip
, dynamic_hf_array
, pos
);
2638 update_dynamic_hf_entries_someip_parameter_structs(void) {
2639 if (data_someip_parameter_structs
!= NULL
) {
2640 deregister_dynamic_hf_data(&dynamic_hf_struct
, &dynamic_hf_struct_size
);
2641 allocate_dynamic_hf_data(&dynamic_hf_struct
, &dynamic_hf_struct_size
, someip_parameter_structs_num
);
2643 g_hash_table_foreach(data_someip_parameter_structs
, update_dynamic_struct_hf_entry
, &pos
);
2644 proto_register_field_array(proto_someip
, dynamic_hf_struct
, pos
);
2649 update_dynamic_hf_entries_someip_parameter_unions(void) {
2650 if (data_someip_parameter_unions
!= NULL
) {
2651 deregister_dynamic_hf_data(&dynamic_hf_union
, &dynamic_hf_union_size
);
2652 allocate_dynamic_hf_data(&dynamic_hf_union
, &dynamic_hf_union_size
, someip_parameter_unions_num
);
2654 g_hash_table_foreach(data_someip_parameter_unions
, update_dynamic_union_hf_entry
, &pos
);
2655 proto_register_field_array(proto_someip
, dynamic_hf_union
, pos
);
2660 expert_someip_payload_truncated(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, int length
) {
2661 proto_tree_add_expert(tree
, pinfo
, &ei_someip_payload_truncated
, tvb
, offset
, length
);
2662 col_append_str(pinfo
->cinfo
, COL_INFO
, " [SOME/IP Payload: Truncated payload!]");
2666 expert_someip_payload_malformed(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, int length
) {
2667 proto_tree_add_expert(tree
, pinfo
, &ei_someip_payload_malformed
, tvb
, offset
, length
);
2668 col_append_str(pinfo
->cinfo
, COL_INFO
, " [SOME/IP Payload: Malformed payload!]");
2672 expert_someip_payload_config_error(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, int length
, const char *message
) {
2673 proto_tree_add_expert_format(tree
, pinfo
, &ei_someip_payload_config_error
, tvb
, offset
, length
, "SOME/IP Payload: %s", message
);
2674 col_append_str(pinfo
->cinfo
, COL_INFO
, " [SOME/IP Payload: Config Error]");
2677 /*******************************************
2678 **************** Statistics ***************
2679 *******************************************/
2682 someip_messages_stats_tree_init(stats_tree
*st
) {
2683 st_node_ip_src
= stats_tree_create_node(st
, st_str_ip_src
, 0, STAT_DT_INT
, true);
2684 stat_node_set_flags(st
, st_str_ip_src
, 0, false, ST_FLG_SORT_TOP
);
2685 st_node_ip_dst
= stats_tree_create_node(st
, st_str_ip_dst
, 0, STAT_DT_INT
, true);
2688 static tap_packet_status
2689 someip_messages_stats_tree_packet(stats_tree
*st
, packet_info
*pinfo
, epan_dissect_t
*edt _U_
, const void *p
, tap_flags_t flags _U_
) {
2690 static char tmp_srv_str
[128];
2691 static char tmp_meth_str
[128];
2692 static char tmp_addr_str
[128];
2695 DISSECTOR_ASSERT(p
);
2696 const someip_messages_tap_t
*data
= (const someip_messages_tap_t
*)p
;
2698 snprintf(tmp_addr_str
, sizeof(tmp_addr_str
) - 1, "%s (%s)", address_to_str(pinfo
->pool
, &pinfo
->net_src
), address_to_name(&pinfo
->net_src
));
2699 tick_stat_node(st
, st_str_ip_src
, 0, false);
2700 int src_id
= tick_stat_node(st
, tmp_addr_str
, st_node_ip_src
, true);
2702 snprintf(tmp_addr_str
, sizeof(tmp_addr_str
) - 1, "%s (%s)", address_to_str(pinfo
->pool
, &pinfo
->net_dst
), address_to_name(&pinfo
->net_dst
));
2703 tick_stat_node(st
, st_str_ip_dst
, 0, false);
2704 int dst_id
= tick_stat_node(st
, tmp_addr_str
, st_node_ip_dst
, true);
2706 char *service_name
= someip_lookup_service_name(data
->service_id
);
2707 if (service_name
== NULL
) {
2708 snprintf(tmp_srv_str
, sizeof(tmp_srv_str
) - 1, "Service 0x%04x", data
->service_id
);
2710 snprintf(tmp_srv_str
, sizeof(tmp_srv_str
) - 1, "Service 0x%04x (%s)", data
->service_id
, service_name
);
2713 char *method_name
= someip_lookup_method_name(data
->service_id
, data
->method_id
);
2714 if (method_name
== NULL
) {
2715 snprintf(tmp_meth_str
, sizeof(tmp_meth_str
) - 1, "Method 0x%04x %s", data
->method_id
,
2716 val_to_str(data
->message_type
, someip_msg_type
, "Message-Type: 0x%02x"));
2718 snprintf(tmp_meth_str
, sizeof(tmp_meth_str
) - 1, "Method 0x%04x (%s) %s", data
->method_id
, method_name
,
2719 val_to_str(data
->message_type
, someip_msg_type
, "Message-Type: 0x%02x"));
2722 tmp
= tick_stat_node(st
, tmp_srv_str
, src_id
, true);
2723 tick_stat_node(st
, tmp_meth_str
, tmp
, false);
2724 tmp
= tick_stat_node(st
, tmp_srv_str
, dst_id
, true);
2725 tick_stat_node(st
, tmp_meth_str
, tmp
, false);
2727 return TAP_PACKET_REDRAW
;
2730 /*******************************************
2731 ******** SOME/IP Payload Dissector ********
2732 *******************************************/
2735 dissect_someip_payload_parameter(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
, uint8_t data_type
, uint32_t idref
, char *name
, int *hf_id_ptr
, int wtlv_offset
);
2738 dissect_someip_payload_parameters(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
, someip_payload_parameter_item_t
*items
, uint32_t num_of_items
, bool wtlv
);
2740 /* add a flexible size length field, -1 for error*/
2742 dissect_someip_payload_length_field(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*subtree
, int offset
, int length_of_length_field
) {
2746 switch (length_of_length_field
) {
2748 ti
= proto_tree_add_item_ret_uint(subtree
, hf_payload_length_field_8bit
, tvb
, offset
, length_of_length_field
/ 8, ENC_NA
, &tmp
);
2749 proto_item_set_hidden(ti
);
2752 ti
= proto_tree_add_item_ret_uint(subtree
, hf_payload_length_field_16bit
, tvb
, offset
, length_of_length_field
/ 8, ENC_BIG_ENDIAN
, &tmp
);
2753 proto_item_set_hidden(ti
);
2756 ti
= proto_tree_add_item_ret_uint(subtree
, hf_payload_length_field_32bit
, tvb
, offset
, length_of_length_field
/ 8, ENC_BIG_ENDIAN
, &tmp
);
2757 proto_item_set_hidden(ti
);
2760 proto_tree_add_expert_format(subtree
, pinfo
, &ei_someip_payload_config_error
, tvb
, offset
, 0,
2761 "SOME/IP: Payload: length of length field does not make sense: %d bits", length_of_length_field
);
2762 col_append_str(pinfo
->cinfo
, COL_INFO
, " [SOME/IP: Payload Config Error]");
2766 return (int64_t)tmp
;
2769 /* add a flexible size type field */
2771 dissect_someip_payload_type_field(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*subtree
, int offset
, int length_of_type_field
) {
2775 switch (length_of_type_field
) {
2777 ti
= proto_tree_add_item_ret_uint(subtree
, hf_payload_type_field_8bit
, tvb
, offset
, length_of_type_field
/ 8, ENC_NA
, &tmp
);
2778 proto_item_set_hidden(ti
);
2781 ti
= proto_tree_add_item_ret_uint(subtree
, hf_payload_type_field_16bit
, tvb
, offset
, length_of_type_field
/ 8, ENC_BIG_ENDIAN
, &tmp
);
2782 proto_item_set_hidden(ti
);
2785 ti
= proto_tree_add_item_ret_uint(subtree
, hf_payload_type_field_32bit
, tvb
, offset
, length_of_type_field
/ 8, ENC_BIG_ENDIAN
, &tmp
);
2786 proto_item_set_hidden(ti
);
2789 proto_tree_add_expert_format(subtree
, pinfo
, &ei_someip_payload_config_error
, tvb
, offset
, 0,
2790 "SOME/IP: Payload: length of type field does not make sense: %d bits", length_of_type_field
);
2791 col_append_str(pinfo
->cinfo
, COL_INFO
, " [SOME/IP: Payload Config Error]");
2795 return (int64_t)tmp
;
2799 dissect_someip_payload_add_wtlv_if_needed(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, int offset
, proto_item
*ti_root
, proto_tree
*parent_tree
) {
2800 static int * const tag_bitfield
[] = {
2801 &hf_payload_wtlv_tag_res
,
2802 &hf_payload_wtlv_tag_wire_type
,
2803 &hf_payload_wtlv_tag_data_id
,
2811 proto_tree
*tree
= parent_tree
;
2813 tree
= proto_item_add_subtree(ti_root
, ett_someip_parameter
);
2816 uint64_t tagdata
= 0;
2817 proto_item
*ti
= proto_tree_add_bitmask_ret_uint64(tree
, tvb
, offset
, hf_payload_wtlv_tag
, ett_someip_wtlv_tag
, tag_bitfield
, ENC_BIG_ENDIAN
, &tagdata
);
2818 proto_item_set_hidden(ti
);
2820 unsigned wiretype
= (unsigned)((tagdata
& SOMEIP_WTLV_MASK_WIRE_TYPE
) >> 12);
2835 dissect_someip_payload_base_type(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
, uint8_t data_type
, uint32_t id
, char *name
, int *hf_id_ptr
, int wtlv_offset
) {
2836 someip_payload_parameter_base_type_list_t
*base_type
= NULL
;
2837 someip_payload_parameter_enum_t
*enum_config
= NULL
;
2839 uint32_t basetype_id
= 0;
2840 uint32_t enum_id
= 0;
2842 int param_length
= -1;
2844 proto_item
*ti
= NULL
;
2847 uint32_t value32
= 0;
2848 bool value_set
= false;
2851 char *value_name
= NULL
;
2853 bool big_endian
= true;
2857 if (hf_id_ptr
!= NULL
) {
2861 switch (data_type
) {
2862 case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_BASE_TYPE
:
2865 case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ENUM
:
2867 enum_config
= get_enum_config(enum_id
);
2868 if (enum_config
== NULL
) {
2871 basetype_id
= enum_config
->id_ref
;
2877 base_type
= get_base_type_config(basetype_id
);
2878 if (base_type
== NULL
) {
2882 big_endian
= base_type
->big_endian
;
2883 param_length
= (int)((base_type
->bitlength_base_type
) / 8);
2885 if (param_length
> tvb_captured_length_remaining(tvb
, 0) - offset
) {
2890 if (strncmp(base_type
->data_type
, "uint", 4) == 0) {
2891 if (base_type
->bitlength_base_type
> 32) {
2892 ti
= proto_tree_add_item_ret_uint64(tree
, hf_id
, tvb
, offset
, param_length
, big_endian
? ENC_BIG_ENDIAN
: ENC_LITTLE_ENDIAN
, &value
);
2894 ti
= proto_tree_add_item_ret_uint(tree
, hf_id
, tvb
, offset
, param_length
, big_endian
? ENC_BIG_ENDIAN
: ENC_LITTLE_ENDIAN
, &value32
);
2895 value
= (uint64_t)value32
;
2899 ti
= proto_tree_add_item(tree
, hf_id
, tvb
, offset
, param_length
, big_endian
? ENC_BIG_ENDIAN
: ENC_LITTLE_ENDIAN
);
2903 ti
= proto_tree_add_string_format(tree
, hf_payload_str_base
, tvb
, offset
, param_length
, base_type
->name
, "[%s]", base_type
->name
);
2905 ti
= proto_tree_add_string_format(tree
, hf_payload_str_base
, tvb
, offset
, param_length
, base_type
->name
, "%s [%s]", name
, base_type
->name
);
2909 dissect_someip_payload_add_wtlv_if_needed(tvb
, pinfo
, wtlv_offset
, ti
, NULL
);
2911 if (enum_config
!= NULL
&& value_set
== true) {
2912 for (i
= 0; i
< enum_config
->num_of_items
; i
++) {
2913 if (enum_config
->items
[i
].value
== value
) {
2914 value_name
= enum_config
->items
[i
].name
;
2918 if (value_name
!= NULL
) {
2919 proto_item_append_text(ti
, " (%s)", value_name
);
2923 return param_length
;
2927 dissect_someip_payload_string(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
, uint32_t id
, char *name
, int *hf_id_ptr
, int wtlv_offset
) {
2928 someip_payload_parameter_string_t
*config
= NULL
;
2930 uint8_t *buf
= NULL
;
2933 proto_item
*ti
= NULL
;
2934 proto_tree
*subtree
= NULL
;
2936 uint32_t length
= 0;
2937 int offset_orig
= offset
;
2939 unsigned str_encoding
= 0;
2940 int hf_id
= hf_payload_str_string
;
2942 if (hf_id_ptr
!= NULL
) {
2946 config
= get_string_config(id
);
2948 if (config
== NULL
) {
2952 if (wtlv_offset
>= 0) {
2953 ti
= proto_tree_add_string_format(tree
, hf_id
, tvb
, wtlv_offset
, 0, name
, "%s [%s]", name
, config
->name
);
2955 ti
= proto_tree_add_string_format(tree
, hf_id
, tvb
, offset
, 0, name
, "%s [%s]", name
, config
->name
);
2958 subtree
= proto_item_add_subtree(ti
, ett_someip_string
);
2959 uint32_t length_of_length
= dissect_someip_payload_add_wtlv_if_needed(tvb
, pinfo
, wtlv_offset
, ti
, NULL
);
2961 /* WTLV length overrides configured length */
2962 if (config
->length_of_length
== 0 && length_of_length
== 0) {
2963 length
= config
->max_length
;
2965 if (length_of_length
== 0) {
2966 length_of_length
= config
->length_of_length
;
2969 if (tvb_captured_length_remaining(tvb
, offset
) < (int)(length_of_length
>> 3)) {
2970 expert_someip_payload_malformed(tree
, pinfo
, tvb
, offset
, 0);
2974 tmp
= dissect_someip_payload_length_field(tvb
, pinfo
, subtree
, offset
, length_of_length
);
2977 return length_of_length
/ 8;
2979 length
= (uint32_t)tmp
;
2980 offset
+= length_of_length
/ 8;
2983 if ((uint32_t)tvb_captured_length_remaining(tvb
, offset
) < length
) {
2984 expert_someip_payload_malformed(subtree
, pinfo
, tvb
, offset
, 0);
2988 if (strcmp(config
->encoding
, "utf-8") == 0) {
2989 str_encoding
= ENC_UTF_8
| ENC_NA
;
2990 } else if (strcmp(config
->encoding
, "utf-16") == 0) {
2991 str_encoding
= ENC_UTF_16
| (config
->big_endian
? ENC_BIG_ENDIAN
: ENC_LITTLE_ENDIAN
);
2993 str_encoding
= ENC_ASCII
| ENC_NA
;
2996 buf
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, length
, str_encoding
);
2998 /* sanitizing buffer */
2999 if ((str_encoding
== (ENC_ASCII
| ENC_NA
)) || (str_encoding
& ENC_UTF_8
)) {
3000 for (i
= 0; i
< length
; i
++) {
3001 if (buf
[i
] > 0x00 && buf
[i
] < 0x20) {
3007 proto_item_append_text(ti
, ": %s", buf
);
3010 proto_item_set_end(ti
, tvb
, offset
);
3012 return offset
- offset_orig
;
3016 // NOLINTNEXTLINE(misc-no-recursion)
3017 dissect_someip_payload_struct(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset_orig
, uint32_t id
, char *name
, int wtlv_offset
) {
3018 someip_payload_parameter_struct_t
*config
= NULL
;
3020 proto_tree
*subtree
= NULL
;
3021 proto_item
*ti
= NULL
;
3022 tvbuff_t
*subtvb
= tvb
;
3025 int offset
= offset_orig
;
3027 config
= get_struct_config(id
);
3029 if (config
== NULL
|| tree
== NULL
|| tvb
== NULL
) {
3033 if (wtlv_offset
>= 0) {
3034 ti
= proto_tree_add_string_format(tree
, hf_payload_str_struct
, tvb
, wtlv_offset
, 0, config
->struct_name
, "struct %s [%s]", name
, config
->struct_name
);
3036 ti
= proto_tree_add_string_format(tree
, hf_payload_str_struct
, tvb
, offset
, 0, config
->struct_name
, "struct %s [%s]", name
, config
->struct_name
);
3039 subtree
= proto_item_add_subtree(ti
, ett_someip_struct
);
3040 uint32_t length_of_length
= dissect_someip_payload_add_wtlv_if_needed(tvb
, pinfo
, wtlv_offset
, ti
, subtree
);
3042 /* WTLV length overrides configured length */
3043 if (length_of_length
== 0) {
3044 length_of_length
= config
->length_of_length
;
3047 if (tvb_captured_length_remaining(tvb
, 0) < (int)(length_of_length
>> 3)) {
3048 expert_someip_payload_malformed(tree
, pinfo
, tvb
, offset
, 0);
3052 if (length_of_length
!= 0) {
3053 length
= dissect_someip_payload_length_field(tvb
, pinfo
, subtree
, offset
, length_of_length
);
3056 return length_of_length
/ 8;
3058 offset
+= length_of_length
/ 8;
3059 int endpos
= offset_orig
+ (length_of_length
/ 8) + (uint32_t)length
;
3060 proto_item_set_end(ti
, tvb
, endpos
);
3061 subtvb
= tvb_new_subset_length(tvb
, 0, endpos
);
3064 offset
+= dissect_someip_payload_parameters(subtvb
, pinfo
, subtree
, offset
, config
->items
, config
->num_of_items
, config
->wtlv_encoding
);
3066 if (length_of_length
== 0) {
3067 proto_item_set_end(ti
, tvb
, offset
);
3069 return offset
- offset_orig
;
3071 return (length_of_length
/ 8) + (uint32_t)length
;
3076 // NOLINTNEXTLINE(misc-no-recursion)
3077 dissect_someip_payload_typedef(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
, uint32_t id
, char *name _U_
, int *hf_id
, int wtlv_offset
) {
3078 someip_payload_parameter_typedef_t
*config
= NULL
;
3080 config
= get_typedef_config(id
);
3082 if (config
== NULL
) {
3086 /* we basically skip over the typedef for now */
3087 return dissect_someip_payload_parameter(tvb
, pinfo
, tree
, offset
, (uint8_t)config
->data_type
, config
->id_ref
, config
->name
, hf_id
, wtlv_offset
);
3090 /* returns bytes parsed, length needs to be int to encode "non-existing" as -1 */
3092 dissect_someip_payload_array_dim_length(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset_orig
, int *length
, int *lower_limit
, int *upper_limit
,
3093 someip_parameter_array_t
*config
, int current_dim
, uint32_t length_of_length
) {
3094 int offset
= offset_orig
;
3097 *lower_limit
= config
->dims
[current_dim
].lower_limit
;
3098 *upper_limit
= config
->dims
[current_dim
].upper_limit
;
3100 /* length needs to be -1, if we do not have a dynamic length array */
3103 if (length_of_length
== 0) {
3104 length_of_length
= config
->dims
[current_dim
].length_of_length
;
3106 if (length_of_length
> 0) {
3107 /* we are filling the length with number of bytes we found in the packet */
3108 tmp
= dissect_someip_payload_length_field(tvb
, pinfo
, tree
, offset
, length_of_length
);
3110 /* leave *length = -1 */
3111 return length_of_length
/8;
3113 *length
= (int32_t)tmp
;
3114 offset
+= length_of_length
/8;
3116 /* without a length field, the number of elements needs be fixed */
3117 if (config
->dims
[current_dim
].lower_limit
!= config
->dims
[current_dim
].upper_limit
) {
3118 proto_tree_add_expert_format(tree
, pinfo
, &ei_someip_payload_static_array_min_not_max
, tvb
, offset_orig
, 0,
3119 "Static array config with Min!=Max (%d, %d)", config
->dims
[current_dim
].lower_limit
, config
->dims
[current_dim
].upper_limit
);
3120 col_append_str(pinfo
->cinfo
, COL_INFO
, " [SOME/IP Payload: Static array config with Min!=Max!]");
3126 return offset
- offset_orig
;
3129 /* returns bytes parsed, length needs to be int to encode "non-existing" as -1 */
3131 // NOLINTNEXTLINE(misc-no-recursion)
3132 dissect_someip_payload_array_payload(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset_orig
, int length
, int lower_limit
, int upper_limit
,
3133 someip_parameter_array_t
*config
) {
3134 tvbuff_t
*subtvb
= NULL
;
3135 uint32_t offset
= offset_orig
;
3136 uint32_t bytes_parsed
= 0;
3141 if (length
<= tvb_captured_length_remaining(tvb
, offset
)) {
3142 subtvb
= tvb_new_subset_length(tvb
, offset
, length
);
3143 /* created subtvb. so we set offset=0 */
3146 expert_someip_payload_truncated(tree
, pinfo
, tvb
, offset
, tvb_captured_length_remaining(tvb
, offset
));
3147 return tvb_captured_length_remaining(tvb
, offset
);
3153 while ((length
== -1 && count
< upper_limit
) || ((int)offset
< length
)) {
3154 bytes_parsed
= dissect_someip_payload_parameter(subtvb
, pinfo
, tree
, offset
, (uint8_t)config
->data_type
, config
->id_ref
, config
->name
, config
->hf_id
, -1);
3155 if (bytes_parsed
== 0) {
3156 /* does this make sense? */
3159 offset
+= bytes_parsed
;
3163 if (count
<lower_limit
&& count
>upper_limit
) {
3164 proto_tree_add_expert_format(tree
, pinfo
, &ei_someip_payload_dyn_array_not_within_limit
, tvb
, offset_orig
, length
,
3165 "Number of items (%d) outside limit %d-%d", count
, lower_limit
, upper_limit
);
3166 col_append_str(pinfo
->cinfo
, COL_INFO
, " [SOME/IP Payload: Dynamic array does not stay between Min and Max values]");
3170 /* we created subtvb first and set offset to 0 */
3173 ret
= offset
- offset_orig
;
3180 // NOLINTNEXTLINE(misc-no-recursion)
3181 dissect_someip_payload_array_dim(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset_orig
, int length
, int lower_limit
, int upper_limit
, someip_parameter_array_t
*config
, unsigned current_dim
, char *name
, uint32_t length_of_length
) {
3182 proto_item
*ti
= NULL
;
3183 proto_tree
*subtree
= NULL
;
3185 int sub_lower_limit
= 0;
3186 int sub_upper_limit
= 0;
3190 int offset
= offset_orig
;
3192 if (config
->num_of_dims
== current_dim
+ 1) {
3193 /* only payload left. :) */
3194 offset
+= dissect_someip_payload_array_payload(tvb
, pinfo
, tree
, offset
, length
, lower_limit
, upper_limit
, config
);
3197 while (offset
< offset_orig
+ (int)length
) {
3198 sub_offset
= offset
;
3200 ti
= proto_tree_add_string_format(tree
, hf_payload_str_array
, tvb
, sub_offset
, 0, name
, "subarray (dim: %d, limit %d-%d)", current_dim
+ 1, sub_lower_limit
, sub_upper_limit
);
3201 subtree
= proto_item_add_subtree(ti
, ett_someip_array_dim
);
3203 offset
+= dissect_someip_payload_array_dim_length(tvb
, pinfo
, subtree
, offset
, &sub_length
, &sub_lower_limit
, &sub_upper_limit
, config
, current_dim
+ 1, length_of_length
);
3205 if (tvb_captured_length_remaining(tvb
, offset
) < (int)sub_length
) {
3206 expert_someip_payload_truncated(subtree
, pinfo
, tvb
, offset
, tvb_captured_length_remaining(tvb
, offset
));
3210 offset
+= dissect_someip_payload_array_dim(tvb
, pinfo
, subtree
, offset
, sub_length
, sub_lower_limit
, sub_upper_limit
, config
, current_dim
+ 1, name
, length_of_length
);
3212 proto_item_set_end(ti
, tvb
, offset
);
3215 /* Multi-dim static array */
3216 sub_lower_limit
= config
->dims
[current_dim
].lower_limit
;
3217 sub_upper_limit
= config
->dims
[current_dim
].upper_limit
;
3219 for (i
= 0; i
< upper_limit
; i
++) {
3220 offset
+= dissect_someip_payload_array_dim(tvb
, pinfo
, tree
, offset
, -1, sub_lower_limit
, sub_upper_limit
, config
, current_dim
+ 1, name
, length_of_length
);
3225 return offset
- offset_orig
;
3229 // NOLINTNEXTLINE(misc-no-recursion)
3230 dissect_someip_payload_array(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset_orig
, uint32_t id
, char *name
, int wtlv_offset
) {
3231 someip_parameter_array_t
*config
= NULL
;
3233 proto_tree
*subtree
;
3234 proto_item
*ti
= NULL
;
3236 int offset
= offset_orig
;
3239 int size_of_length
= 0;
3240 int lower_limit
= 0;
3241 int upper_limit
= 0;
3243 config
= get_array_config(id
);
3245 if (config
== NULL
) {
3249 if (config
->num_of_dims
== 0 || config
->dims
== NULL
) {
3250 expert_someip_payload_config_error(tree
, pinfo
, tvb
, offset
, 0, "Array config has not enough dimensions for this array!");
3254 ti
= proto_tree_add_string_format(tree
, hf_payload_str_array
, tvb
, offset
, 0, config
->name
, "array %s", name
);
3255 subtree
= proto_item_add_subtree(ti
, ett_someip_array
);
3256 uint32_t length_of_length
= dissect_someip_payload_add_wtlv_if_needed(tvb
, pinfo
, wtlv_offset
, ti
, subtree
);
3258 offset
+= dissect_someip_payload_array_dim_length(tvb
, pinfo
, subtree
, offset_orig
, &length
, &lower_limit
, &upper_limit
, config
, 0, length_of_length
);
3259 size_of_length
= offset
- offset_orig
;
3262 proto_item_append_text(ti
, " (elements limit: %d-%d)", lower_limit
, upper_limit
);
3264 proto_item_append_text(ti
, " (elements limit: %d)", upper_limit
);
3267 offset
+= dissect_someip_payload_array_dim(tvb
, pinfo
, subtree
, offset
, length
, lower_limit
, upper_limit
, config
, 0, name
, length_of_length
);
3269 proto_item_set_end(ti
, tvb
, offset
);
3272 /* length field present */
3273 return size_of_length
+ length
;
3275 /* We have no length field, so we return what has been parsed! */
3276 return offset
- offset_orig
;
3281 // NOLINTNEXTLINE(misc-no-recursion)
3282 dissect_someip_payload_union(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset_orig
, uint32_t id
, char *name
, int wtlv_offset
) {
3283 someip_parameter_union_t
*config
= NULL
;
3284 someip_parameter_union_item_t
*item
= NULL
;
3286 proto_item
*ti
= NULL
;
3287 proto_tree
*subtree
= NULL
;
3290 int buf_length
= -1;
3293 uint32_t length
= 0;
3298 int offset
= offset_orig
;
3300 config
= get_union_config(id
);
3301 buf_length
= tvb_captured_length_remaining(tvb
, 0);
3303 if (config
== NULL
) {
3304 expert_someip_payload_config_error(tree
, pinfo
, tvb
, offset
, 0, "Union ID not configured");
3308 if (wtlv_offset
>= 0) {
3309 ti
= proto_tree_add_string_format(tree
, hf_payload_str_union
, tvb
, wtlv_offset
, 0, name
, "union %s [%s]", name
, config
->name
);
3311 ti
= proto_tree_add_string_format(tree
, hf_payload_str_union
, tvb
, offset_orig
, 0, name
, "union %s [%s]", name
, config
->name
);
3314 subtree
= proto_item_add_subtree(ti
, ett_someip_union
);
3315 uint32_t length_of_length
= dissect_someip_payload_add_wtlv_if_needed(tvb
, pinfo
, wtlv_offset
, ti
, subtree
);
3317 if (length_of_length
== 0) {
3318 length_of_length
= config
->length_of_length
;
3321 if ((length_of_length
+ config
->length_of_type
) / 8 > (unsigned)buf_length
- offset
) {
3322 expert_someip_payload_truncated(tree
, pinfo
, tvb
, offset
, tvb_captured_length_remaining(tvb
, offset
));
3326 tmp
= dissect_someip_payload_length_field(tvb
, pinfo
, subtree
, offset_orig
, length_of_length
);
3328 return offset
- offset_orig
;
3330 length
= (uint32_t)tmp
;
3333 tmp
= dissect_someip_payload_type_field(tvb
, pinfo
, subtree
, offset_orig
+ length_of_length
/ 8, config
->length_of_type
);
3335 return offset
- offset_orig
;
3337 type
= (uint32_t)tmp
;
3340 offset
+= (length_of_length
+ config
->length_of_type
) / 8;
3341 proto_item_set_end(ti
, tvb
, offset
+ length
);
3344 for (i
= 0; i
< config
->num_of_items
; i
++) {
3345 if (config
->items
[i
].id
== type
&& config
->items
[i
].name
!= NULL
) {
3346 item
= &(config
->items
[i
]);
3351 subtvb
= tvb_new_subset_length(tvb
, offset
, length
);
3352 dissect_someip_payload_parameter(subtvb
, pinfo
, subtree
, 0, (uint8_t)item
->data_type
, item
->id_ref
, item
->name
, item
->hf_id
, -1);
3354 expert_someip_payload_config_error(tree
, pinfo
, tvb
, offset
, 0, "Union type not configured");
3357 return length
+ (config
->length_of_type
+ length_of_length
) / 8;
3361 // NOLINTNEXTLINE(misc-no-recursion)
3362 dissect_someip_payload_parameter(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
, uint8_t data_type
, uint32_t idref
, char *name
, int *hf_id_ptr
, int wtlv_offset
) {
3363 int bytes_parsed
= 0;
3365 increment_dissection_depth(pinfo
);
3366 switch (data_type
) {
3367 case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_TYPEDEF
:
3368 bytes_parsed
= dissect_someip_payload_typedef(tvb
, pinfo
, tree
, offset
, idref
, name
, hf_id_ptr
, wtlv_offset
);
3370 case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_BASE_TYPE
:
3371 case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ENUM
:
3372 bytes_parsed
= dissect_someip_payload_base_type(tvb
, pinfo
, tree
, offset
, data_type
, idref
, name
, hf_id_ptr
, wtlv_offset
);
3374 case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_STRING
:
3375 bytes_parsed
= dissect_someip_payload_string(tvb
, pinfo
, tree
, offset
, idref
, name
, hf_id_ptr
, wtlv_offset
);
3377 case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ARRAY
:
3378 bytes_parsed
= dissect_someip_payload_array(tvb
, pinfo
, tree
, offset
, idref
, name
, wtlv_offset
);
3380 case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_STRUCT
:
3381 bytes_parsed
= dissect_someip_payload_struct(tvb
, pinfo
, tree
, offset
, idref
, name
, wtlv_offset
);
3383 case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_UNION
:
3384 bytes_parsed
= dissect_someip_payload_union(tvb
, pinfo
, tree
, offset
, idref
, name
, wtlv_offset
);
3387 proto_tree_add_expert_format(tree
, pinfo
, &ei_someip_payload_config_error
, tvb
, offset
, 0,
3388 "SOME/IP: Payload: item->data_type (0x%x) unknown/not implemented yet! name: %s, id_ref: 0x%x",
3389 data_type
, name
, idref
);
3390 col_append_str(pinfo
->cinfo
, COL_INFO
, " [SOME/IP: Payload Config Error]");
3393 decrement_dissection_depth(pinfo
);
3395 return bytes_parsed
;
3399 * returns <0 for errors
3401 static int dissect_someip_payload_peek_length_of_length(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, int length
, someip_payload_parameter_item_t
*item
) {
3406 uint32_t data_type
= item
->data_type
;
3407 uint32_t id_ref
= item
->id_ref
;
3409 /* a config error could cause an endless loop, so we limit the number of indirections with loop_limit */
3410 int loop_limit
= 255;
3411 while (data_type
== SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_TYPEDEF
&& loop_limit
> 0) {
3412 someip_payload_parameter_typedef_t
*tmp
= get_typedef_config(id_ref
);
3413 data_type
= tmp
->data_type
;
3414 id_ref
= tmp
->id_ref
;
3418 someip_payload_parameter_string_t
*tmp_string_config
;
3419 someip_parameter_array_t
*tmp_array_config
;
3420 someip_payload_parameter_struct_t
*tmp_struct_config
;
3421 someip_parameter_union_t
*tmp_union_config
;
3423 switch (data_type
) {
3424 case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_STRING
:
3425 tmp_string_config
= get_string_config(id_ref
);
3426 if (tmp_string_config
== NULL
) {
3430 return tmp_string_config
->length_of_length
;
3432 case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ARRAY
:
3433 tmp_array_config
= get_array_config(id_ref
);
3434 if (tmp_array_config
== NULL
) {
3438 if (tmp_array_config
->num_of_dims
< 1 || tmp_array_config
->dims
== NULL
) {
3439 expert_someip_payload_config_error(tree
, pinfo
, tvb
, offset
, length
, "array configuration does not support WTLV");
3443 return tmp_array_config
->dims
[0].length_of_length
;
3445 case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_STRUCT
:
3446 tmp_struct_config
= get_struct_config(id_ref
);
3447 if (tmp_struct_config
== NULL
) {
3451 return tmp_struct_config
->length_of_length
;
3453 case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_UNION
:
3454 tmp_union_config
= get_union_config(id_ref
);
3455 if (tmp_union_config
== NULL
) {
3459 return tmp_union_config
->length_of_length
;
3461 case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_TYPEDEF
:
3462 case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_BASE_TYPE
:
3463 case SOMEIP_PAYLOAD_PARAMETER_DATA_TYPE_ENUM
:
3465 /* This happens only if configuration or message are buggy. */
3471 // NOLINTNEXTLINE(misc-no-recursion)
3472 dissect_someip_payload_parameters(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
, someip_payload_parameter_item_t
*items
, uint32_t num_of_items
, bool wtlv
) {
3473 someip_payload_parameter_item_t
*item
;
3475 int offset_orig
= offset
;
3477 if (items
== NULL
&& !someip_deserializer_wtlv_default
) {
3482 while (tvb_captured_length_remaining(tvb
, offset
) >= 2) {
3483 uint64_t tagdata
= tvb_get_uint16(tvb
, offset
, ENC_BIG_ENDIAN
);
3484 unsigned wiretype
= (tagdata
& SOMEIP_WTLV_MASK_WIRE_TYPE
) >> 12;
3485 unsigned param_id
= tagdata
& SOMEIP_WTLV_MASK_DATA_ID
;
3488 if (param_id
< num_of_items
&& items
!= NULL
) {
3489 item
= &(items
[param_id
]);
3494 unsigned param_length
= 0;
3497 /* fixed length type with just 1, 2, 4, or 8 byte length */
3502 param_length
= 1 << wiretype
;
3505 /* var length types like structs, strings, arrays, and unions */
3507 /* this type is deprecated and should not be used*/
3509 switch (dissect_someip_payload_peek_length_of_length(tree
, pinfo
, tvb
, offset
- 2, 0, item
)) {
3511 param_length
= 1 + tvb_get_uint8(tvb
, offset
);
3514 param_length
= 2 + tvb_get_uint16(tvb
, offset
, ENC_BIG_ENDIAN
);
3517 param_length
= 4 + tvb_get_uint32(tvb
, offset
, ENC_BIG_ENDIAN
);
3520 expert_someip_payload_config_error(tree
, pinfo
, tvb
, offset
- 2, 2, "WTLV type 4 but datatype has not an appropriate length field configured");
3521 return 8 * (offset
- offset_orig
);
3526 param_length
= 1 + tvb_get_uint8(tvb
, offset
);
3529 param_length
= 2 + tvb_get_uint16(tvb
, offset
, ENC_BIG_ENDIAN
);
3532 param_length
= 4 + tvb_get_uint32(tvb
, offset
, ENC_BIG_ENDIAN
);
3536 /* unsupported Wire Type!*/
3537 expert_someip_payload_malformed(tree
, pinfo
, tvb
, offset
- 2, 2);
3541 tvbuff_t
*subtvb
= tvb_new_subset_length(tvb
, offset
- 2, param_length
+ 2);
3543 dissect_someip_payload_parameter(subtvb
, pinfo
, tree
, 2, (uint8_t)item
->data_type
, item
->id_ref
, item
->name
, item
->hf_id
, 0);
3545 proto_item
*ti
= proto_tree_add_item(tree
, hf_payload_unparsed
, subtvb
, 2, param_length
, ENC_NA
);
3546 dissect_someip_payload_add_wtlv_if_needed(tvb
, pinfo
, offset
- 2, ti
, NULL
);
3548 offset
+= param_length
;
3551 if (items
== NULL
) {
3555 for (i
= 0; i
< num_of_items
; i
++) {
3557 offset
+= dissect_someip_payload_parameter(tvb
, pinfo
, tree
, offset
, (uint8_t)item
->data_type
, item
->id_ref
, item
->name
, item
->hf_id
, -1);
3561 return offset
- offset_orig
;
3565 dissect_someip_payload(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_item
*ti
, uint16_t serviceid
, uint16_t methodid
, uint8_t version
, uint8_t msgtype
) {
3566 someip_parameter_list_t
* paramlist
= NULL
;
3571 proto_tree
*tree
= NULL
;
3573 length
= tvb_captured_length_remaining(tvb
, 0);
3574 tree
= proto_item_add_subtree(ti
, ett_someip_payload
);
3575 paramlist
= get_parameter_config(serviceid
, methodid
, version
, msgtype
);
3577 if (paramlist
== NULL
) {
3578 if (someip_deserializer_wtlv_default
) {
3579 offset
+= dissect_someip_payload_parameters(tvb
, pinfo
, tree
, offset
, NULL
, 0, true);
3584 offset
+= dissect_someip_payload_parameters(tvb
, pinfo
, tree
, offset
, paramlist
->items
, paramlist
->num_of_items
, paramlist
->wtlv_encoding
);
3587 if (length
> offset
) {
3588 proto_tree_add_item(tree
, hf_payload_unparsed
, tvb
, offset
, length
- (offset
), ENC_NA
);
3592 /***********************************
3593 ******** SOME/IP Dissector ********
3594 ***********************************/
3597 dissect_someip_message(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
) {
3598 uint32_t offset
= 0;
3599 uint32_t someip_messageid
= 0;
3600 uint32_t someip_serviceid
= 0;
3601 uint32_t someip_methodid
= 0;
3602 uint32_t someip_clientid
= 0;
3603 uint32_t someip_sessionid
= 0;
3604 uint32_t someip_length
= 0;
3605 const char *service_description
= NULL
;
3606 const char *method_description
= NULL
;
3607 const char *client_description
= NULL
;
3608 someip_info_t someip_data
= SOMEIP_INFO_T_INIT
;
3610 uint32_t someip_payload_length
= 0;
3611 tvbuff_t
*subtvb
= NULL
;
3613 proto_item
*ti
= NULL
;
3614 proto_item
*ti_someip
= NULL
;
3615 proto_tree
*someip_tree
= NULL
;
3616 proto_tree
*msgtype_tree
= NULL
;
3618 uint32_t protocol_version
= 0;
3619 uint32_t version
= 0;
3620 uint32_t msgtype
= 0;
3621 bool msgtype_ack
= false;
3622 bool msgtype_tp
= false;
3623 uint32_t retcode
= 0;
3626 int tvb_length
= tvb_captured_length_remaining(tvb
, offset
);
3628 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, SOMEIP_NAME
);
3629 col_set_str(pinfo
->cinfo
, COL_INFO
, SOMEIP_NAME_LONG
);
3630 ti_someip
= proto_tree_add_item(tree
, proto_someip
, tvb
, offset
, -1, ENC_NA
);
3631 someip_tree
= proto_item_add_subtree(ti_someip
, ett_someip
);
3633 /* we should never get called with less than 8 bytes */
3634 if (tvb_length
< 8) {
3638 /* Message ID = Service ID + Method ID*/
3639 someip_messageid
= tvb_get_ntohl(tvb
, 0);
3640 ti
= proto_tree_add_uint_format_value(someip_tree
, hf_someip_messageid
, tvb
, offset
, 4, someip_messageid
, "0x%08x", someip_messageid
);
3641 proto_item_set_hidden(ti
);
3644 ti
= proto_tree_add_item_ret_uint(someip_tree
, hf_someip_serviceid
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &someip_serviceid
);
3645 someip_data
.service_id
= someip_serviceid
;
3646 service_description
= someip_lookup_service_name(someip_serviceid
);
3647 if (service_description
!= NULL
) {
3648 proto_item_append_text(ti
, " (%s)", service_description
);
3649 ti
= proto_tree_add_string(someip_tree
, hf_someip_servicename
, tvb
, offset
, 2, service_description
);
3650 proto_item_set_generated(ti
);
3651 proto_item_set_hidden(ti
);
3656 ti
= proto_tree_add_item_ret_uint(someip_tree
, hf_someip_methodid
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &someip_methodid
);
3657 someip_data
.method_id
= someip_methodid
;
3658 method_description
= someip_lookup_method_name(someip_serviceid
, someip_methodid
);
3659 if (method_description
!= NULL
) {
3660 proto_item_append_text(ti
, " (%s)", method_description
);
3661 ti
= proto_tree_add_string(someip_tree
, hf_someip_methodname
, tvb
, offset
, 2, method_description
);
3662 proto_item_set_generated(ti
);
3663 proto_item_set_hidden(ti
);
3668 proto_tree_add_item_ret_uint(someip_tree
, hf_someip_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &someip_length
);
3671 /* this checks if value of the header field */
3672 if (someip_length
< 8) {
3673 expert_add_info_format(pinfo
, ti_someip
, &ei_someip_incomplete_headers
, "%s", "SOME/IP length too short (<8 Bytes)!");
3677 /* Add some additional info to the Protocol line and the Info Column*/
3678 if (service_description
== NULL
) {
3679 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s (Service ID: 0x%04x, Method ID: 0x%04x, Length: %i)",
3680 SOMEIP_NAME_LONG
, someip_serviceid
, someip_methodid
, someip_length
);
3681 } else if (method_description
== NULL
) {
3682 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s (Service ID: 0x%04x (%s), Method ID: 0x%04x, Length: %i)",
3683 SOMEIP_NAME_LONG
, someip_serviceid
, service_description
, someip_methodid
, someip_length
);
3685 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s (Service ID: 0x%04x (%s), Method ID: 0x%04x (%s), Length: %i)",
3686 SOMEIP_NAME_LONG
, someip_serviceid
, service_description
, someip_methodid
, method_description
, someip_length
);
3688 proto_item_append_text(ti_someip
, " (Service ID: 0x%04x, Method ID: 0x%04x, Length: %i)", someip_serviceid
, someip_methodid
, someip_length
);
3690 /* check if we have bytes for the rest of the header */
3691 if (tvb_length
< 0 || offset
+ 8 > (uint32_t)tvb_length
) {
3692 expert_add_info_format(pinfo
, ti_someip
, &ei_someip_incomplete_headers
, "%s", "SOME/IP not enough buffer bytes for header!");
3697 ti
= proto_tree_add_item_ret_uint(someip_tree
, hf_someip_clientid
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &someip_clientid
);
3698 someip_data
.client_id
= someip_clientid
;
3699 client_description
= someip_lookup_client_name(someip_serviceid
, someip_clientid
);
3700 if (client_description
!= NULL
) {
3701 proto_item_append_text(ti
, " (%s)", client_description
);
3702 ti
= proto_tree_add_string(someip_tree
, hf_someip_clientname
, tvb
, offset
, 2, client_description
);
3703 proto_item_set_generated(ti
);
3704 proto_item_set_hidden(ti
);
3709 proto_tree_add_item_ret_uint(someip_tree
, hf_someip_sessionid
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &someip_sessionid
);
3710 someip_data
.session_id
= someip_sessionid
;
3713 /* Protocol Version*/
3714 ti
= proto_tree_add_item_ret_uint(someip_tree
, hf_someip_protover
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &protocol_version
);
3715 if (protocol_version
!=SOMEIP_PROTOCOL_VERSION
) {
3716 expert_add_info(pinfo
, ti
, &ei_someip_unknown_version
);
3720 /* Major Version of Service Interface */
3721 proto_tree_add_item_ret_uint(someip_tree
, hf_someip_interface_ver
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &version
);
3722 someip_data
.major_version
= version
;
3726 ti
= proto_tree_add_item_ret_uint(someip_tree
, hf_someip_messagetype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &msgtype
);
3727 someip_data
.message_type
= msgtype
;
3728 msgtype_tree
= proto_item_add_subtree(ti
, ett_someip_msgtype
);
3729 proto_tree_add_item_ret_boolean(msgtype_tree
, hf_someip_messagetype_ack_flag
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &msgtype_ack
);
3730 proto_tree_add_item_ret_boolean(msgtype_tree
, hf_someip_messagetype_tp_flag
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &msgtype_tp
);
3732 proto_item_append_text(ti
, " (%s)", val_to_str_const((~SOMEIP_MSGTYPE_TP_MASK
)&msgtype
, someip_msg_type
, "Unknown Message Type"));
3734 proto_item_append_text(ti
, " (%s)", SOMEIP_MSGTYPE_TP_STRING
);
3739 ti
= proto_tree_add_item_ret_uint(someip_tree
, hf_someip_returncode
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &retcode
);
3740 proto_item_append_text(ti
, " (%s)", val_to_str_const(retcode
, someip_return_code
, "Unknown Return Code"));
3743 /* lets figure out what we have for the rest */
3744 if (((uint32_t)tvb_length
>= (someip_length
+ 8)) ) {
3745 someip_payload_length
= someip_length
- SOMEIP_HDR_PART1_LEN
;
3747 someip_payload_length
= tvb_length
- SOMEIP_HDR_LEN
;
3748 expert_add_info(pinfo
, ti_someip
, &ei_someip_message_truncated
);
3751 /* Is this a SOME/IP-TP segment? */
3753 uint32_t tp_offset
= 0;
3754 bool tp_more_segments
= false;
3755 bool update_col_info
= true;
3756 fragment_head
*someip_tp_head
= NULL
;
3757 proto_tree
*tp_tree
= NULL
;
3759 ti
= proto_tree_add_item(someip_tree
, hf_someip_tp
, tvb
, offset
, someip_payload_length
, ENC_NA
);
3760 tp_tree
= proto_item_add_subtree(ti
, ett_someip_tp
);
3762 /* Unfortunately, with a bitmask set the value is always shifted and cannot be set directly. */
3763 proto_tree_add_item_ret_uint(tp_tree
, hf_someip_tp_offset_encoded
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &tp_offset
);
3765 proto_tree_add_item(tp_tree
, hf_someip_tp_reserved
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3766 proto_tree_add_item_ret_boolean(tp_tree
, hf_someip_tp_more_segments
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &tp_more_segments
);
3767 ti
= proto_tree_add_uint(tp_tree
, hf_someip_tp_offset
, tvb
, offset
, 4, tp_offset
);
3768 PROTO_ITEM_SET_GENERATED(ti
);
3771 proto_tree_add_item(tp_tree
, hf_someip_payload
, tvb
, offset
, someip_payload_length
- SOMEIP_TP_HDR_LEN
, ENC_NA
);
3773 if (someip_tp_reassemble
&& tvb_bytes_exist(tvb
, offset
, someip_payload_length
- SOMEIP_TP_HDR_LEN
)) {
3774 someip_tp_head
= fragment_add_check(&someip_tp_reassembly_table
, tvb
, offset
, pinfo
, 0,
3775 &someip_data
, tp_offset
, someip_payload_length
- SOMEIP_TP_HDR_LEN
, tp_more_segments
);
3776 subtvb
= process_reassembled_data(tvb
, offset
, pinfo
, "Reassembled SOME/IP-TP Segment",
3777 someip_tp_head
, &someip_tp_frag_items
, &update_col_info
, someip_tree
);
3780 subtvb
= tvb_new_subset_length(tvb
, SOMEIP_HDR_LEN
, someip_payload_length
);
3783 if (subtvb
!= NULL
) {
3785 if (have_tap_listener(tap_someip_messages
)) {
3786 someip_messages_tap_t
*stats_data
= wmem_alloc(pinfo
->pool
, sizeof(someip_messages_tap_t
));
3787 stats_data
->service_id
= (uint16_t)someip_serviceid
;
3788 stats_data
->method_id
= (uint16_t)someip_methodid
;
3789 stats_data
->interface_version
= (uint8_t)version
;
3790 stats_data
->message_type
= (uint8_t)(~SOMEIP_MSGTYPE_TP_MASK
) & msgtype
;
3792 tap_queue_packet(tap_someip_messages
, pinfo
, stats_data
);
3795 tvb_length
= tvb_captured_length_remaining(subtvb
, 0);
3796 if (tvb_length
> 0) {
3797 tmp
= dissector_try_uint_new(someip_dissector_table
, someip_messageid
, subtvb
, pinfo
, tree
, false, &someip_data
);
3799 /* if no subdissector was found, the generic payload dissector takes over. */
3801 ti
= proto_tree_add_item(someip_tree
, hf_someip_payload
, subtvb
, 0, tvb_length
, ENC_NA
);
3803 if (someip_deserializer_activated
) {
3804 dissect_someip_payload(subtvb
, pinfo
, ti
, (uint16_t)someip_serviceid
, (uint16_t)someip_methodid
, (uint8_t)version
, (uint8_t)(~SOMEIP_MSGTYPE_TP_MASK
)&msgtype
);
3806 proto_tree
* payload_dissection_disabled_info_sub_tree
= proto_item_add_subtree(ti
, ett_someip_payload
);
3807 proto_tree_add_text_internal(payload_dissection_disabled_info_sub_tree
, subtvb
, 0, tvb_length
, "Dissection of payload is disabled. It can be enabled via protocol preferences.");
3813 return SOMEIP_HDR_LEN
+ someip_payload_length
;
3817 get_someip_message_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
, void *data _U_
) {
3818 return SOMEIP_HDR_PART1_LEN
+ (unsigned)tvb_get_ntohl(tvb
, offset
+ 4);
3822 dissect_someip_tcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
) {
3823 tcp_dissect_pdus(tvb
, pinfo
, tree
, true, SOMEIP_HDR_PART1_LEN
, get_someip_message_len
, dissect_someip_message
, data
);
3824 return tvb_reported_length(tvb
);
3828 could_this_be_dtls(tvbuff_t
*tvb
) {
3831 * Byte | SOME/IP | DTLS
3832 * --------------------------------
3833 * 00 | Service ID | Content Type
3834 * 01 | Service ID | Version
3835 * 02 | Method ID | Version
3836 * 03 | Method ID | Epoch
3837 * 04 | Length | Epoch
3838 * 05 | Length | Sequence Counter
3839 * 06 | Length | Sequence Counter
3840 * 07 | Length | Sequence Counter
3841 * 08 | Client ID | Sequence Counter
3842 * 09 | Client ID | Sequence Counter
3843 * 10 | Session ID | Sequence Counter
3844 * 11 | Session ID | Length
3845 * 12 | SOME/IP Ver | Length
3846 * 13 | Iface Ver | ...
3847 * 14 | Msg Type | ...
3848 * 15 | Return Code | ...
3851 int length
= tvb_captured_length_remaining(tvb
, 0);
3853 /* DTLS header is 13 bytes. */
3855 /* not sure what we have here ... */
3859 uint8_t dtls_content_type
= tvb_get_uint8(tvb
, 0);
3860 uint16_t dtls_version
= tvb_get_uint16(tvb
, 1, ENC_BIG_ENDIAN
);
3861 uint16_t dtls_length
= tvb_get_uint16(tvb
, 11, ENC_BIG_ENDIAN
);
3863 bool dtls_possible
= (20 <= dtls_content_type
) && (dtls_content_type
<= 63) &&
3864 (0xfefc <= dtls_version
) && (dtls_version
<= 0xfeff) &&
3865 ((uint32_t)length
== (uint32_t)dtls_length
+ 13);
3867 if (dtls_possible
&& length
< SOMEIP_HDR_LEN
) {
3871 uint32_t someip_length
= tvb_get_uint32(tvb
, 4, ENC_BIG_ENDIAN
);
3872 uint8_t someip_version
= tvb_get_uint8(tvb
, 12);
3874 /* typically this is 1500 bytes or less on UDP but being conservative */
3875 bool someip_possible
= (someip_version
== 1) && (8 <= someip_length
) && (someip_length
<= 65535) &&
3876 ((uint32_t)length
== someip_length
+ 8);
3878 return dtls_possible
&& !someip_possible
;
3882 dissect_someip_udp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
) {
3883 if (someip_detect_dtls
&& could_this_be_dtls(tvb
)) {
3884 if (!PINFO_FD_VISITED(pinfo
)) {
3885 dissector_add_uint("dtls.port", (uint16_t)pinfo
->destport
, someip_handle_udp
);
3888 if (dtls_handle
!= 0) {
3889 return call_dissector_with_data(dtls_handle
, tvb
, pinfo
, tree
, data
);
3893 return udp_dissect_pdus(tvb
, pinfo
, tree
, SOMEIP_HDR_PART1_LEN
, NULL
, get_someip_message_len
, dissect_someip_message
, data
);
3897 test_someip(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset _U_
, void *data _U_
) {
3898 if (tvb_captured_length(tvb
) < SOMEIP_HDR_LEN
) {
3902 if (tvb_get_uint32(tvb
, 4, ENC_BIG_ENDIAN
) < 8) {
3906 if ((tvb_get_uint8(tvb
, 12)) != SOMEIP_PROTOCOL_VERSION
) {
3910 if (!try_val_to_str((tvb_get_uint8(tvb
, 14) & ~SOMEIP_MSGTYPE_TP_MASK
), someip_msg_type
)) {
3918 dissect_some_ip_heur_tcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
) {
3919 if (test_someip(pinfo
, tvb
, 0, data
)) {
3920 tcp_dissect_pdus(tvb
, pinfo
, tree
, true, SOMEIP_HDR_PART1_LEN
, get_someip_message_len
, dissect_someip_message
, data
);
3927 dissect_some_ip_heur_udp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
) {
3928 return (udp_dissect_pdus(tvb
, pinfo
, tree
, SOMEIP_HDR_PART1_LEN
, test_someip
, get_someip_message_len
, dissect_someip_message
, data
) != 0);
3932 proto_register_someip(void) {
3933 expert_module_t
*expert_module_someip
;
3935 uat_t
*someip_service_uat
;
3936 uat_t
*someip_method_uat
;
3937 uat_t
*someip_eventgroup_uat
;
3938 uat_t
*someip_client_uat
;
3940 uat_t
*someip_parameter_base_type_list_uat
;
3941 uat_t
*someip_parameter_strings_uat
;
3942 uat_t
*someip_parameter_typedefs_uat
;
3943 uat_t
*someip_parameter_list_uat
;
3944 uat_t
*someip_parameter_arrays_uat
;
3945 uat_t
*someip_parameter_structs_uat
;
3946 uat_t
*someip_parameter_unions_uat
;
3947 uat_t
*someip_parameter_enums_uat
;
3950 static hf_register_info hf
[] = {
3951 { &hf_someip_serviceid
,
3952 { "Service ID", "someip.serviceid",
3953 FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
3954 { &hf_someip_servicename
,
3955 { "Service Name", "someip.servicename",
3956 FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
3957 { &hf_someip_methodid
,
3958 { "Method ID", "someip.methodid",
3959 FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
3960 { &hf_someip_methodname
,
3961 { "Method Name", "someip.methodname",
3962 FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
3963 { &hf_someip_messageid
,
3964 { "Message ID", "someip.messageid",
3965 FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
3966 { &hf_someip_length
,
3967 { "Length", "someip.length",
3968 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
3969 { &hf_someip_clientid
,
3970 { "Client ID", "someip.clientid",
3971 FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
3972 { &hf_someip_clientname
,
3973 { "Client Name", "someip.clientname",
3974 FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
3975 { &hf_someip_sessionid
,
3976 { "Session ID", "someip.sessionid",
3977 FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
3978 { &hf_someip_protover
,
3979 { "SOME/IP Version", "someip.protoversion",
3980 FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
3981 { &hf_someip_interface_ver
,
3982 { "Interface Version", "someip.interfaceversion",
3983 FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
3984 { &hf_someip_messagetype
,
3985 { "Message Type", "someip.messagetype",
3986 FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
3987 { &hf_someip_messagetype_ack_flag
,
3988 { "Message Type Ack Flag", "someip.messagetype.ack",
3989 FT_BOOLEAN
, 8, NULL
, SOMEIP_MSGTYPE_ACK_MASK
, NULL
, HFILL
}},
3990 { &hf_someip_messagetype_tp_flag
,
3991 { "Message Type TP Flag", "someip.messagetype.tp",
3992 FT_BOOLEAN
, 8, NULL
, SOMEIP_MSGTYPE_TP_MASK
, NULL
, HFILL
}},
3993 { &hf_someip_returncode
,
3994 { "Return Code", "someip.returncode",
3995 FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
3997 { &hf_someip_payload
,
3998 { "Payload", "someip.payload",
3999 FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
4002 { "SOME/IP-TP", "someip.tp",
4003 FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
4004 { &hf_someip_tp_offset
,
4005 { "Offset", "someip.tp.offset",
4006 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
4007 { &hf_someip_tp_offset_encoded
,
4008 { "Encoded Offset", "someip.tp.offset_encoded",
4009 FT_UINT32
, BASE_HEX
, NULL
, SOMEIP_TP_OFFSET_MASK
, NULL
, HFILL
}},
4010 { &hf_someip_tp_flags
,
4011 { "Flags", "someip.tp.flags",
4012 FT_UINT32
, BASE_HEX
, NULL
, SOMEIP_TP_OFFSET_MASK_FLAGS
, NULL
, HFILL
}},
4013 { &hf_someip_tp_reserved
,
4014 { "Reserved", "someip.tp.flags.reserved",
4015 FT_UINT32
, BASE_HEX
, NULL
, SOMEIP_TP_OFFSET_MASK_RESERVED
, NULL
, HFILL
}},
4016 { &hf_someip_tp_more_segments
,
4017 { "More Segments", "someip.tp.flags.more_segments",
4018 FT_BOOLEAN
, 32, NULL
, SOMEIP_TP_OFFSET_MASK_MORE_SEGMENTS
, NULL
, HFILL
}},
4020 {&hf_someip_tp_fragments
,
4021 {"SOME/IP-TP segments", "someip.tp.fragments",
4022 FT_NONE
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
} },
4023 {&hf_someip_tp_fragment
,
4024 {"SOME/IP-TP segment", "someip.tp.fragment",
4025 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
} },
4026 {&hf_someip_tp_fragment_overlap
,
4027 {"SOME/IP-TP segment overlap", "someip.tp.fragment.overlap",
4028 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
} },
4029 {&hf_someip_tp_fragment_overlap_conflicts
,
4030 {"SOME/IP-TP segment overlapping with conflicting data", "someip.tp.fragment.overlap.conflicts",
4031 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
} },
4032 {&hf_someip_tp_fragment_multiple_tails
,
4033 {"SOME/IP-TP Message has multiple tail fragments", "someip.tp.fragment.multiple_tails",
4034 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
} },
4035 {&hf_someip_tp_fragment_too_long_fragment
,
4036 {"SOME/IP-TP segment too long", "someip.tp.fragment.too_long_fragment",
4037 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
} },
4038 {&hf_someip_tp_fragment_error
,
4039 {"SOME/IP-TP Message defragmentation error", "someip.tp.fragment.error",
4040 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
} },
4041 {&hf_someip_tp_fragment_count
,
4042 {"SOME/IP-TP segment count", "someip.tp.fragment.count",
4043 FT_UINT32
, BASE_DEC
, NULL
, 0x00, NULL
, HFILL
} },
4044 {&hf_someip_tp_reassembled_in
,
4045 {"Reassembled in", "someip.tp.reassembled.in",
4046 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
} },
4047 {&hf_someip_tp_reassembled_length
,
4048 {"Reassembled length", "someip.tp.reassembled.length",
4049 FT_UINT32
, BASE_DEC
, NULL
, 0x00, NULL
, HFILL
} },
4051 {&hf_someip_tp_reassembled_data
,
4052 {"Reassembled data", "someip.tp.reassembled.data",
4053 FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
4055 { &hf_payload_unparsed
,
4056 { "Unparsed Payload", "someip.payload.unparsed",
4057 FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
4058 { &hf_payload_length_field_8bit
,
4059 { "Length", "someip.payload.length",
4060 FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
4061 { &hf_payload_length_field_16bit
,
4062 { "Length", "someip.payload.length",
4063 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
4064 { &hf_payload_length_field_32bit
,
4065 { "Length", "someip.payload.length",
4066 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
4067 { &hf_payload_type_field_8bit
,
4068 { "Type", "someip.payload.type",
4069 FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
4070 { &hf_payload_type_field_16bit
,
4071 { "Type", "someip.payload.type",
4072 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
4073 { &hf_payload_type_field_32bit
,
4074 { "Type", "someip.payload.type",
4075 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
4077 { &hf_payload_str_base
, {
4078 "(base)", "someip.payload.base",
4079 FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
4080 { &hf_payload_str_string
, {
4081 "(string)", "someip.payload.string",
4082 FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
4083 { &hf_payload_str_struct
, {
4084 "(struct)", "someip.payload.struct",
4085 FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
4086 { &hf_payload_str_array
, {
4087 "(array)", "someip.payload.array",
4088 FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
4089 { &hf_payload_str_union
, {
4090 "(array)", "someip.payload.union",
4091 FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
4093 { &hf_payload_wtlv_tag
, {
4094 "WTLV-TAG", "someip.payload.wtlvtag",
4095 FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
4096 { &hf_payload_wtlv_tag_res
, {
4097 "Reserved", "someip.payload.wtlvtag.res",
4098 FT_UINT16
, BASE_DEC
, NULL
, SOMEIP_WTLV_MASK_RES
, NULL
, HFILL
} },
4099 { &hf_payload_wtlv_tag_wire_type
, {
4100 "Wire Type", "someip.payload.wtlvtag.wire_type",
4101 FT_UINT16
, BASE_DEC
, NULL
, SOMEIP_WTLV_MASK_WIRE_TYPE
, NULL
, HFILL
} },
4102 { &hf_payload_wtlv_tag_data_id
, {
4103 "Data ID", "someip.payload.wtlvtag.data_id",
4104 FT_UINT16
, BASE_DEC
, NULL
, SOMEIP_WTLV_MASK_DATA_ID
, NULL
, HFILL
} },
4107 static int *ett
[] = {
4109 &ett_someip_msgtype
,
4111 &ett_someip_tp_fragment
,
4112 &ett_someip_tp_fragments
,
4114 &ett_someip_payload
,
4117 &ett_someip_array_dim
,
4121 &ett_someip_parameter
,
4122 &ett_someip_wtlv_tag
,
4126 /* UATs for user_data fields */
4127 static uat_field_t someip_service_uat_fields
[] = {
4128 UAT_FLD_HEX(someip_service_ident
, id
, "Service ID", "ID of the SOME/IP Service (16bit hex without leading 0x)"),
4129 UAT_FLD_CSTRING(someip_service_ident
, name
, "Service Name", "Name of the SOME/IP Service (string)"),
4133 static uat_field_t someip_method_uat_fields
[] = {
4134 UAT_FLD_HEX(someip_method_ident
, id
, "Service ID", "ID of the SOME/IP Service (16bit hex without leading 0x)"),
4135 UAT_FLD_HEX(someip_method_ident
, id2
, "Methods ID", "ID of the SOME/IP Method/Event/Notifier (16bit hex without leading 0x)"),
4136 UAT_FLD_CSTRING(someip_method_ident
, name
, "Method Name", "Name of the SOME/IP Method/Event/Notifier (string)"),
4140 static uat_field_t someip_eventgroup_uat_fields
[] = {
4141 UAT_FLD_HEX(someip_eventgroup_ident
, id
, "Service ID", "ID of the SOME/IP Service (16bit hex without leading 0x)"),
4142 UAT_FLD_HEX(someip_eventgroup_ident
, id2
, "Eventgroup ID", "ID of the SOME/IP Eventgroup (16bit hex without leading 0x)"),
4143 UAT_FLD_CSTRING(someip_eventgroup_ident
, name
, "Eventgroup Name", "Name of the SOME/IP Service (string)"),
4147 static uat_field_t someip_client_uat_fields
[] = {
4148 UAT_FLD_HEX(someip_client_ident
, id
, "Service ID", "ID of the SOME/IP Service (16bit hex without leading 0x)"),
4149 UAT_FLD_HEX(someip_client_ident
, id2
, "Client ID", "ID of the SOME/IP Client (16bit hex without leading 0x)"),
4150 UAT_FLD_CSTRING(someip_client_ident
, name
, "Client Name", "Name of the SOME/IP Client (string)"),
4154 static uat_field_t someip_parameter_list_uat_fields
[] = {
4155 UAT_FLD_HEX(someip_parameter_list
, service_id
, "Service ID", "ID of the SOME/IP Service (16bit hex without leading 0x)"),
4156 UAT_FLD_HEX(someip_parameter_list
, method_id
, "Method ID", "ID of the SOME/IP Method/Event/Notifier (16bit hex without leading 0x)"),
4157 UAT_FLD_DEC(someip_parameter_list
, version
, "Version", "Version of the SOME/IP Service (8bit dec)"),
4158 UAT_FLD_HEX(someip_parameter_list
, message_type
, "Message Type", "Message Type (8bit hex without leading 0x)"),
4159 UAT_FLD_BOOL(someip_parameter_list
, wtlv_encoding
, "WTLV Extension?", "SOME/IP is extended by Wiretag-Length-Value encoding for this parameter list (not pure SOME/IP)"),
4161 UAT_FLD_DEC(someip_parameter_list
, num_of_params
, "Number of Parameters", "Number of Parameters (16bit dec), needs to be larger than greatest Parameter Position/ID"),
4163 UAT_FLD_DEC(someip_parameter_list
, pos
, "Parameter Position/ID", "Position or ID of parameter (16bit dec, starting with 0)"),
4164 UAT_FLD_CSTRING(someip_parameter_list
, name
, "Parameter Name", "Name of parameter (string)"),
4165 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)"),
4166 UAT_FLD_HEX(someip_parameter_list
, id_ref
, "ID Reference", "ID Reference (32bit hex)"),
4167 UAT_FLD_CSTRING(someip_parameter_list
, filter_string
, "Filter String", "Unique filter string that will be prepended with someip.payload. (string)"),
4171 static uat_field_t someip_parameter_array_uat_fields
[] = {
4172 UAT_FLD_HEX(someip_parameter_arrays
, id
, "ID", "ID of SOME/IP array (32bit hex without leading 0x)"),
4173 UAT_FLD_CSTRING(someip_parameter_arrays
, name
, "Array Name", "Name of array"),
4174 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)"),
4175 UAT_FLD_HEX(someip_parameter_arrays
, id_ref
, "ID Reference", "ID Reference (32bit hex)"),
4176 UAT_FLD_DEC(someip_parameter_arrays
, num_of_dims
, "Number of Items", "Number of Dimensions (16bit dec)"),
4177 UAT_FLD_CSTRING(someip_parameter_arrays
, filter_string
, "Filter String", "Unique filter string that will be prepended with someip.payload. (string)"),
4179 UAT_FLD_DEC(someip_parameter_arrays
, num
, "Dimension", "Dimension (16bit dec, starting with 0)"),
4180 UAT_FLD_DEC(someip_parameter_arrays
, lower_limit
, "Lower Limit", "Dimension (32bit dec)"),
4181 UAT_FLD_DEC(someip_parameter_arrays
, upper_limit
, "Upper Limit", "Dimension (32bit dec)"),
4182 UAT_FLD_DEC(someip_parameter_arrays
, length_of_length
, "Length of Length Field", "Length of the arrays length field in bits (8bit dec)"),
4183 UAT_FLD_DEC(someip_parameter_arrays
, pad_to
, "Pad to", "Padding pads to reach alignment (8bit dec)"),
4187 static uat_field_t someip_parameter_struct_uat_fields
[] = {
4188 UAT_FLD_HEX(someip_parameter_structs
, id
, "ID", "ID of SOME/IP struct (32bit hex without leading 0x)"),
4189 UAT_FLD_CSTRING(someip_parameter_structs
, struct_name
, "Struct Name", "Name of struct"),
4190 UAT_FLD_DEC(someip_parameter_structs
, length_of_length
, "Length of Length Field", "Length of the structs length field in bits (8bit dec)"),
4191 UAT_FLD_DEC(someip_parameter_structs
, pad_to
, "Pad to", "Padding pads to reach alignment (8bit dec)"),
4192 UAT_FLD_BOOL(someip_parameter_structs
, wtlv_encoding
, "WTLV Extension?", "SOME/IP is extended by Wiretag-Length-Value encoding for this struct (not pure SOME/IP)"),
4193 UAT_FLD_DEC(someip_parameter_structs
, num_of_items
, "Number of Items", "Number of Items (16bit dec)"),
4195 UAT_FLD_DEC(someip_parameter_structs
, pos
, "Parameter Position/ID", "Position or ID of parameter (16bit dec, starting with 0)"),
4196 UAT_FLD_CSTRING(someip_parameter_structs
, name
, "Parameter Name", "Name of parameter (string)"),
4197 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)"),
4198 UAT_FLD_HEX(someip_parameter_structs
, id_ref
, "ID Reference", "ID Reference (32bit hex)"),
4199 UAT_FLD_CSTRING(someip_parameter_structs
, filter_string
, "Filter String", "Unique filter string that will be prepended with someip.payload. (string)"),
4203 static uat_field_t someip_parameter_union_uat_fields
[] = {
4204 UAT_FLD_HEX(someip_parameter_unions
, id
, "ID", "ID of SOME/IP union (32bit hex without leading 0x)"),
4205 UAT_FLD_CSTRING(someip_parameter_unions
, name
, "Union Name", "Name of union"),
4206 UAT_FLD_DEC(someip_parameter_unions
, length_of_length
, "Length of Length Field", "Length of the unions length field in bits (uint8 dec)"),
4207 UAT_FLD_DEC(someip_parameter_unions
, length_of_type
, "Length of Type Field", "Length of the unions type field in bits (8bit dec)"),
4208 UAT_FLD_DEC(someip_parameter_unions
, pad_to
, "Pad to", "Padding pads to reach alignment (8bit dec)"),
4210 UAT_FLD_DEC(someip_parameter_unions
, num_of_items
, "Number of Items", "Number of Items (32bit dec)"),
4212 UAT_FLD_DEC(someip_parameter_unions
, type_id
, "Type ID", "ID of Type (32bit dec, starting with 0)"),
4213 UAT_FLD_CSTRING(someip_parameter_unions
, type_name
, "Type Name", "Name of Type (string)"),
4214 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)"),
4215 UAT_FLD_HEX(someip_parameter_unions
, id_ref
, "ID Reference", "ID Reference (32bit hex)"),
4216 UAT_FLD_CSTRING(someip_parameter_unions
, filter_string
, "Filter String", "Unique filter string that will be prepended with someip.payload. (string)"),
4220 static uat_field_t someip_parameter_enum_uat_fields
[] = {
4221 UAT_FLD_HEX(someip_parameter_enums
, id
, "ID", "ID of SOME/IP enum (32bit hex without leading 0x)"),
4222 UAT_FLD_CSTRING(someip_parameter_enums
, name
, "Name", "Name of Enumeration (string)"),
4223 UAT_FLD_DEC(someip_parameter_enums
, data_type
, "Parameter Type", "Type of parameter (1: base, 2: string, 3: array, 4: struct, 5: union, 6: typedef, 7: enum)"),
4224 UAT_FLD_HEX(someip_parameter_enums
, id_ref
, "ID Reference", "ID Reference (32bit hex)"),
4225 UAT_FLD_DEC(someip_parameter_enums
, num_of_items
, "Number of Items", "Number of Items (32bit dec)"),
4227 UAT_FLD_HEX(someip_parameter_enums
, value
, "Value", "Value (64bit uint hex)"),
4228 UAT_FLD_CSTRING(someip_parameter_enums
, value_name
, "Value Name", "Name (string)"),
4232 static uat_field_t someip_parameter_base_type_list_uat_fields
[] = {
4233 UAT_FLD_HEX(someip_parameter_base_type_list
, id
, "ID ", "ID (32bit hex)"),
4234 UAT_FLD_CSTRING(someip_parameter_base_type_list
, name
, "Name", "Name of type (string)"),
4235 UAT_FLD_CSTRING(someip_parameter_base_type_list
, data_type
, "Data Type", "Data type (string)"),
4236 UAT_FLD_BOOL(someip_parameter_base_type_list
, big_endian
, "Big Endian", "Encoded Big Endian"),
4237 UAT_FLD_DEC(someip_parameter_base_type_list
, bitlength_base_type
, "Bitlength base type", "Bitlength base type (uint32 dec)"),
4238 UAT_FLD_DEC(someip_parameter_base_type_list
, bitlength_encoded_type
, "Bitlength enc. type", "Bitlength encoded type (uint32 dec)"),
4242 static uat_field_t someip_parameter_string_list_uat_fields
[] = {
4243 UAT_FLD_HEX(someip_parameter_strings
, id
, "ID ", "ID (32bit hex)"),
4244 UAT_FLD_CSTRING(someip_parameter_strings
, name
, "Name", "Name of string (string)"),
4245 UAT_FLD_CSTRING(someip_parameter_strings
, encoding
, "Encoding", "String Encoding (ascii, utf-8, utf-16)"),
4246 UAT_FLD_BOOL(someip_parameter_strings
, dynamic_length
, "Dynamic Length", "Dynamic length of string"),
4247 UAT_FLD_DEC(someip_parameter_strings
, max_length
, "Max. Length", "Maximum length/Length (uint32 dec)"),
4248 UAT_FLD_DEC(someip_parameter_strings
, length_of_length
, "Length of Len Field", "Length of the length field in bits (uint8 dec)"),
4249 UAT_FLD_BOOL(someip_parameter_strings
, big_endian
, "Big Endian", "Encoded Big Endian"),
4250 UAT_FLD_DEC(someip_parameter_strings
, pad_to
, "Pad to", "Padding pads to reach alignment (8bit dec)"),
4254 static uat_field_t someip_parameter_typedef_list_uat_fields
[] = {
4255 UAT_FLD_HEX(someip_parameter_typedefs
, id
, "ID ", "ID (32bit hex)"),
4256 UAT_FLD_CSTRING(someip_parameter_typedefs
, name
, "Name", "Name of typedef (string)"),
4257 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)"),
4258 UAT_FLD_HEX(someip_parameter_typedefs
, id_ref
, "ID Reference", "ID Reference (32bit hex)"),
4262 static ei_register_info ei
[] = {
4263 { &ei_someip_unknown_version
,{ "someip.unknown_protocol_version",
4264 PI_PROTOCOL
, PI_WARN
, "SOME/IP Unknown Protocol Version!", EXPFILL
} },
4265 { &ei_someip_message_truncated
,{ "someip.message_truncated",
4266 PI_MALFORMED
, PI_ERROR
, "SOME/IP Truncated message!", EXPFILL
} },
4267 { &ei_someip_incomplete_headers
,{ "someip.incomplete_headers",
4268 PI_MALFORMED
, PI_ERROR
, "SOME/IP Incomplete headers or some bytes left over!", EXPFILL
} },
4270 { &ei_someip_payload_truncated
, {"someip.payload.expert_truncated",
4271 PI_MALFORMED
, PI_ERROR
, "SOME/IP Payload: Truncated payload!", EXPFILL
} },
4272 { &ei_someip_payload_malformed
, {"someip.payload.expert_malformed",
4273 PI_MALFORMED
, PI_ERROR
, "SOME/IP Payload: Malformed payload!", EXPFILL
} },
4274 { &ei_someip_payload_config_error
, {"someip.payload.expert_config_error",
4275 PI_MALFORMED
, PI_ERROR
, "SOME/IP Payload: Config Error!", EXPFILL
} },
4276 { &ei_someip_payload_alignment_error
, {"someip.payload.expert_alignment_error",
4277 PI_MALFORMED
, PI_ERROR
, "SOME/IP Payload: SOME/IP datatype must be align to a byte!", EXPFILL
} },
4278 { &ei_someip_payload_static_array_min_not_max
, {"someip.payload.expert_static_array_min_max",
4279 PI_MALFORMED
, PI_ERROR
, "SOME/IP Payload: Static array with min!=max!", EXPFILL
} },
4280 { &ei_someip_payload_dyn_array_not_within_limit
, {"someip.payload.expert_dyn_array_not_within_limit",
4281 PI_MALFORMED
, PI_WARN
, "SOME/IP Payload: Dynamic array does not stay between Min and Max values!", EXPFILL
} },
4284 /* Register Protocol, Handles, Fields, ETTs, Expert Info, Dissector Table, Taps */
4285 proto_someip
= proto_register_protocol(SOMEIP_NAME_LONG
, SOMEIP_NAME
, SOMEIP_NAME_FILTER
);
4286 someip_handle_udp
= register_dissector("someip_udp", dissect_someip_udp
, proto_someip
);
4287 someip_handle_tcp
= register_dissector("someip_tcp", dissect_someip_tcp
, proto_someip
);
4289 proto_register_field_array(proto_someip
, hf
, array_length(hf
));
4290 proto_register_subtree_array(ett
, array_length(ett
));
4291 expert_module_someip
= expert_register_protocol(proto_someip
);
4292 expert_register_field_array(expert_module_someip
, ei
, array_length(ei
));
4294 someip_dissector_table
= register_dissector_table("someip.messageid", "SOME/IP Message ID", proto_someip
, FT_UINT32
, BASE_HEX
);
4296 tap_someip_messages
= register_tap("someip_messages");
4298 /* init for SOME/IP-TP */
4299 reassembly_table_init(&someip_tp_reassembly_table
, &someip_reassembly_table_functions
);
4301 /* Register preferences */
4302 someip_module
= prefs_register_protocol(proto_someip
, &proto_reg_handoff_someip
);
4305 someip_service_uat
= uat_new("SOME/IP Services",
4306 sizeof(generic_one_id_string_t
), /* record size */
4307 DATAFILE_SOMEIP_SERVICES
, /* filename */
4308 true, /* from profile */
4309 (void **) &someip_service_ident
, /* data_ptr */
4310 &someip_service_ident_num
, /* numitems_ptr */
4311 UAT_AFFECTS_DISSECTION
, /* but not fields */
4313 copy_generic_one_id_string_cb
, /* copy callback */
4314 update_serviceid
, /* update callback */
4315 free_generic_one_id_string_cb
, /* free callback */
4316 post_update_someip_service_cb
, /* post update callback */
4317 reset_someip_service_cb
, /* reset callback */
4318 someip_service_uat_fields
/* UAT field definitions */
4321 prefs_register_uat_preference(someip_module
, "services", "SOME/IP Services",
4322 "A table to define names of SOME/IP services", someip_service_uat
);
4324 someip_method_uat
= uat_new("SOME/IP Methods/Events/Fields",
4325 sizeof(generic_two_id_string_t
), /* record size */
4326 DATAFILE_SOMEIP_METHODS
, /* filename */
4327 true, /* from profile */
4328 (void **) &someip_method_ident
, /* data_ptr */
4329 &someip_method_ident_num
, /* numitems_ptr */
4330 UAT_AFFECTS_DISSECTION
, /* but not fields */
4332 copy_generic_two_id_string_cb
, /* copy callback */
4333 update_two_identifier_16bit_check_both
, /* update callback */
4334 free_generic_two_id_string_cb
, /* free callback */
4335 post_update_someip_method_cb
, /* post update callback */
4336 reset_someip_method_cb
, /* reset callback */
4337 someip_method_uat_fields
/* UAT field definitions */
4340 prefs_register_uat_preference(someip_module
, "methods", "SOME/IP Methods",
4341 "A table to define names of SOME/IP methods", someip_method_uat
);
4343 someip_eventgroup_uat
= uat_new("SOME/IP Eventgroups",
4344 sizeof(generic_two_id_string_t
), /* record size */
4345 DATAFILE_SOMEIP_EVENTGROUPS
, /* filename */
4346 true, /* from profile */
4347 (void **) &someip_eventgroup_ident
, /* data_ptr */
4348 &someip_eventgroup_ident_num
, /* numitems_ptr */
4349 UAT_AFFECTS_DISSECTION
, /* but not fields */
4351 copy_generic_two_id_string_cb
, /* copy callback */
4352 update_two_identifier_16bit_check_both
, /* update callback */
4353 free_generic_two_id_string_cb
, /* free callback */
4354 post_update_someip_eventgroup_cb
, /* post update callback */
4355 reset_someip_eventgroup_cb
, /* reset callback */
4356 someip_eventgroup_uat_fields
/* UAT field definitions */
4359 prefs_register_uat_preference(someip_module
, "eventgroups", "SOME/IP Eventgroups",
4360 "A table to define names of SOME/IP eventgroups", someip_eventgroup_uat
);
4362 someip_client_uat
= uat_new("SOME/IP Clients",
4363 sizeof(generic_two_id_string_t
), /* record size */
4364 DATAFILE_SOMEIP_CLIENTS
, /* filename */
4365 true, /* from profile */
4366 (void **)&someip_client_ident
, /* data_ptr */
4367 &someip_client_ident_num
, /* numitems_ptr */
4368 UAT_AFFECTS_DISSECTION
, /* but not fields */
4370 copy_generic_two_id_string_cb
, /* copy callback */
4371 update_generic_two_identifier_16bit
, /* update callback */
4372 free_generic_two_id_string_cb
, /* free callback */
4373 post_update_someip_client_cb
, /* post update callback */
4374 reset_someip_client_cb
, /* reset callback */
4375 someip_client_uat_fields
/* UAT field definitions */
4378 prefs_register_uat_preference(someip_module
, "clients", "SOME/IP Clients",
4379 "A table to define names of SOME/IP clients", someip_client_uat
);
4381 someip_parameter_list_uat
= uat_new("SOME/IP Parameter List",
4382 sizeof(someip_parameter_list_uat_t
), /* record size */
4383 DATAFILE_SOMEIP_PARAMETERS
, /* filename */
4384 true, /* from profile */
4385 (void **)&someip_parameter_list
, /* data_ptr */
4386 &someip_parameter_list_num
, /* numitems_ptr */
4387 UAT_AFFECTS_DISSECTION
| UAT_AFFECTS_FIELDS
,
4389 copy_someip_parameter_list_cb
, /* copy callback */
4390 update_someip_parameter_list
, /* update callback */
4391 free_someip_parameter_list_cb
, /* free callback */
4392 post_update_someip_parameter_list_cb
, /* post update callback */
4393 reset_someip_parameter_list_cb
, /* reset callback */
4394 someip_parameter_list_uat_fields
/* UAT field definitions */
4397 prefs_register_bool_preference(someip_module
, "reassemble_tp", "Reassemble SOME/IP-TP",
4398 "Reassemble SOME/IP-TP segments", &someip_tp_reassemble
);
4400 prefs_register_bool_preference(someip_module
, "payload_dissector_activated",
4402 "Should the SOME/IP Dissector use the payload dissector?",
4403 &someip_deserializer_activated
);
4405 prefs_register_bool_preference(someip_module
, "detect_dtls_and_hand_off",
4406 "Try to automatically detect DTLS",
4407 "Should the SOME/IP Dissector automatically detect DTLS and hand off to it?",
4408 &someip_detect_dtls
);
4410 prefs_register_bool_preference(someip_module
, "payload_dissector_wtlv_default",
4411 "Try WTLV payload dissection for unconfigured messages (not pure SOME/IP)",
4412 "Should the SOME/IP Dissector use the payload dissector with the experimental WTLV encoding for unconfigured messages?",
4413 &someip_deserializer_wtlv_default
);
4415 prefs_register_uat_preference(someip_module
, "_someip_parameter_list", "SOME/IP Parameter List",
4416 "A table to define names of SOME/IP parameters", someip_parameter_list_uat
);
4418 someip_parameter_arrays_uat
= uat_new("SOME/IP Parameter Arrays",
4419 sizeof(someip_parameter_array_uat_t
), /* record size */
4420 DATAFILE_SOMEIP_ARRAYS
, /* filename */
4421 true, /* from profile */
4422 (void **)&someip_parameter_arrays
, /* data_ptr */
4423 &someip_parameter_arrays_num
, /* numitems_ptr */
4424 UAT_AFFECTS_DISSECTION
| UAT_AFFECTS_FIELDS
,
4426 copy_someip_parameter_array_cb
, /* copy callback */
4427 update_someip_parameter_array
, /* update callback */
4428 free_someip_parameter_array_cb
, /* free callback */
4429 post_update_someip_parameter_array_cb
, /* post update callback */
4430 reset_someip_parameter_array_cb
, /* reset callback */
4431 someip_parameter_array_uat_fields
/* UAT field definitions */
4434 prefs_register_uat_preference(someip_module
, "_someip_parameter_arrays", "SOME/IP Parameter Arrays",
4435 "A table to define arrays used by SOME/IP", someip_parameter_arrays_uat
);
4437 someip_parameter_structs_uat
= uat_new("SOME/IP Parameter Structs",
4438 sizeof(someip_parameter_struct_uat_t
), /* record size */
4439 DATAFILE_SOMEIP_STRUCTS
, /* filename */
4440 true, /* from profile */
4441 (void **)&someip_parameter_structs
, /* data_ptr */
4442 &someip_parameter_structs_num
, /* numitems_ptr */
4443 UAT_AFFECTS_DISSECTION
| UAT_AFFECTS_FIELDS
,
4445 copy_someip_parameter_struct_cb
, /* copy callback */
4446 update_someip_parameter_struct
, /* update callback */
4447 free_someip_parameter_struct_cb
, /* free callback */
4448 post_update_someip_parameter_struct_cb
, /* post update callback */
4449 reset_someip_parameter_struct_cb
, /* reset callback */
4450 someip_parameter_struct_uat_fields
/* UAT field definitions */
4453 prefs_register_uat_preference(someip_module
, "_someip_parameter_structs", "SOME/IP Parameter Structs",
4454 "A table to define structs used by SOME/IP", someip_parameter_structs_uat
);
4456 someip_parameter_unions_uat
= uat_new("SOME/IP Parameter Unions",
4457 sizeof(someip_parameter_union_uat_t
), /* record size */
4458 DATAFILE_SOMEIP_UNIONS
, /* filename */
4459 true, /* from profile */
4460 (void **)&someip_parameter_unions
, /* data_ptr */
4461 &someip_parameter_unions_num
, /* numitems_ptr */
4462 UAT_AFFECTS_DISSECTION
| UAT_AFFECTS_FIELDS
,
4464 copy_someip_parameter_union_cb
, /* copy callback */
4465 update_someip_parameter_union
, /* update callback */
4466 free_someip_parameter_union_cb
, /* free callback */
4467 post_update_someip_parameter_union_cb
, /* post update callback */
4468 reset_someip_parameter_union_cb
, /* reset callback */
4469 someip_parameter_union_uat_fields
/* UAT field definitions */
4472 prefs_register_uat_preference(someip_module
, "_someip_parameter_unions", "SOME/IP Parameter Unions",
4473 "A table to define unions used by SOME/IP", someip_parameter_unions_uat
);
4475 someip_parameter_enums_uat
= uat_new("SOME/IP Parameter Enums",
4476 sizeof(someip_parameter_enum_uat_t
), /* record size */
4477 DATAFILE_SOMEIP_ENUMS
, /* filename */
4478 true, /* from profile */
4479 (void **)&someip_parameter_enums
, /* data_ptr */
4480 &someip_parameter_enums_num
, /* numitems_ptr */
4481 UAT_AFFECTS_DISSECTION
, /* but not fields */
4483 copy_someip_parameter_enum_cb
, /* copy callback */
4484 update_someip_parameter_enum
, /* update callback */
4485 free_someip_parameter_enum_cb
, /* free callback */
4486 post_update_someip_parameter_enum_cb
, /* post update callback */
4487 reset_someip_parameter_enum_cb
, /* reset callback */
4488 someip_parameter_enum_uat_fields
/* UAT field definitions */
4491 prefs_register_uat_preference(someip_module
, "_someip_parameter_enums", "SOME/IP Parameter Enums",
4492 "A table to define enumerations used by SOME/IP", someip_parameter_enums_uat
);
4494 someip_parameter_base_type_list_uat
= uat_new("SOME/IP Parameter Base Type List",
4495 sizeof(someip_parameter_base_type_list_uat_t
), /* record size */
4496 DATAFILE_SOMEIP_BASE_TYPES
, /* filename */
4497 true, /* from profile */
4498 (void **)&someip_parameter_base_type_list
, /* data_ptr */
4499 &someip_parameter_base_type_list_num
, /* numitems_ptr */
4500 UAT_AFFECTS_DISSECTION
, /* but not fields */
4502 copy_someip_parameter_base_type_list_cb
, /* copy callback */
4503 update_someip_parameter_base_type_list
, /* update callback */
4504 free_someip_parameter_base_type_list_cb
, /* free callback */
4505 post_update_someip_parameter_base_type_list_cb
, /* post update callback */
4506 reset_someip_parameter_base_type_list_cb
, /* reset callback */
4507 someip_parameter_base_type_list_uat_fields
/* UAT field definitions */
4510 prefs_register_uat_preference(someip_module
, "_someip_parameter_base_type_list", "SOME/IP Parameter Base Type List",
4511 "A table to define base types of SOME/IP parameters", someip_parameter_base_type_list_uat
);
4513 someip_parameter_strings_uat
= uat_new("SOME/IP Parameter String List",
4514 sizeof(someip_parameter_string_uat_t
), /* record size */
4515 DATAFILE_SOMEIP_STRINGS
, /* filename */
4516 true, /* from profile */
4517 (void **)&someip_parameter_strings
, /* data_ptr */
4518 &someip_parameter_strings_num
, /* numitems_ptr */
4519 UAT_AFFECTS_DISSECTION
, /* but not fields */
4521 copy_someip_parameter_string_list_cb
, /* copy callback */
4522 update_someip_parameter_string_list
, /* update callback */
4523 free_someip_parameter_string_list_cb
, /* free callback */
4524 post_update_someip_parameter_string_list_cb
, /* post update callback */
4525 reset_someip_parameter_string_list_cb
, /* reset callback */
4526 someip_parameter_string_list_uat_fields
/* UAT field definitions */
4529 prefs_register_uat_preference(someip_module
, "_someip_parameter_string_list", "SOME/IP Parameter String List",
4530 "A table to define strings parameters", someip_parameter_strings_uat
);
4532 someip_parameter_typedefs_uat
= uat_new("SOME/IP Parameter Typedef List",
4533 sizeof(someip_parameter_typedef_uat_t
), /* record size */
4534 DATAFILE_SOMEIP_TYPEDEFS
, /* filename */
4535 true, /* from profile */
4536 (void **)&someip_parameter_typedefs
, /* data_ptr */
4537 &someip_parameter_typedefs_num
, /* numitems_ptr */
4538 UAT_AFFECTS_DISSECTION
, /* but not fields */
4540 copy_someip_parameter_typedef_list_cb
, /* copy callback */
4541 update_someip_parameter_typedef_list
, /* update callback */
4542 free_someip_parameter_typedef_list_cb
, /* free callback */
4543 post_update_someip_parameter_typedef_list_cb
, /* post update callback */
4544 reset_someip_parameter_typedef_list_cb
, /* reset callback */
4545 someip_parameter_typedef_list_uat_fields
/* UAT field definitions */
4548 prefs_register_uat_preference(someip_module
, "_someip_parameter_typedef_list", "SOME/IP Parameter Typedef List",
4549 "A table to define typedefs", someip_parameter_typedefs_uat
);
4553 clean_all_hashtables_with_empty_uat(void) {
4554 /* On config change, we delete all hashtables which should have 0 entries! */
4555 /* Usually this is already done in the post update cb of the uat.*/
4556 /* Unfortunately, Wireshark does not call the post_update_cb on config errors. :( */
4557 if (data_someip_services
&& someip_service_ident_num
==0) {
4558 g_hash_table_destroy(data_someip_services
);
4559 data_someip_services
= NULL
;
4561 if (data_someip_methods
&& someip_method_ident_num
==0) {
4562 g_hash_table_destroy(data_someip_methods
);
4563 data_someip_methods
= NULL
;
4565 if (data_someip_eventgroups
&& someip_eventgroup_ident_num
==0) {
4566 g_hash_table_destroy(data_someip_eventgroups
);
4567 data_someip_eventgroups
= NULL
;
4569 if (data_someip_clients
&& someip_client_ident_num
== 0) {
4570 g_hash_table_destroy(data_someip_clients
);
4571 data_someip_clients
= NULL
;
4573 if (data_someip_parameter_list
&& someip_parameter_list_num
==0) {
4574 g_hash_table_destroy(data_someip_parameter_list
);
4575 data_someip_parameter_list
= NULL
;
4577 if (data_someip_parameter_arrays
&& someip_parameter_arrays_num
==0) {
4578 g_hash_table_destroy(data_someip_parameter_arrays
);
4579 data_someip_parameter_arrays
= NULL
;
4581 if (data_someip_parameter_structs
&& someip_parameter_structs_num
==0) {
4582 g_hash_table_destroy(data_someip_parameter_structs
);
4583 data_someip_parameter_structs
= NULL
;
4585 if (data_someip_parameter_unions
&& someip_parameter_unions_num
==0) {
4586 g_hash_table_destroy(data_someip_parameter_unions
);
4587 data_someip_parameter_unions
= NULL
;
4589 if (data_someip_parameter_enums
&& someip_parameter_enums_num
== 0) {
4590 g_hash_table_destroy(data_someip_parameter_enums
);
4591 data_someip_parameter_enums
= NULL
;
4593 if (data_someip_parameter_base_type_list
&& someip_parameter_base_type_list_num
==0) {
4594 g_hash_table_destroy(data_someip_parameter_base_type_list
);
4595 data_someip_parameter_base_type_list
= NULL
;
4597 if (data_someip_parameter_strings
&& someip_parameter_strings_num
==0) {
4598 g_hash_table_destroy(data_someip_parameter_strings
);
4599 data_someip_parameter_strings
= NULL
;
4601 if (data_someip_parameter_typedefs
&& someip_parameter_typedefs_num
==0) {
4602 g_hash_table_destroy(data_someip_parameter_typedefs
);
4603 data_someip_parameter_typedefs
= NULL
;
4608 proto_reg_handoff_someip(void) {
4609 static bool initialized
= false;
4612 /* add support for (D)TLS decode as */
4613 dtls_dissector_add(0, someip_handle_udp
);
4614 ssl_dissector_add(0, someip_handle_tcp
);
4616 heur_dissector_add("udp", dissect_some_ip_heur_udp
, "SOME/IP over UDP", "someip_udp_heur", proto_someip
, HEURISTIC_DISABLE
);
4617 heur_dissector_add("tcp", dissect_some_ip_heur_tcp
, "SOME/IP over TCP", "someip_tcp_heur", proto_someip
, HEURISTIC_DISABLE
);
4619 stats_tree_register("someip_messages", "someip_messages", "SOME/IP Messages", 0, someip_messages_stats_tree_packet
, someip_messages_stats_tree_init
, NULL
);
4621 dissector_add_uint_range_with_preference("udp.port", "", someip_handle_udp
);
4622 dissector_add_uint_range_with_preference("tcp.port", "", someip_handle_tcp
);
4624 dtls_handle
= find_dissector("dtls");
4628 clean_all_hashtables_with_empty_uat();
4631 update_dynamic_hf_entries_someip_parameter_list();
4632 update_dynamic_hf_entries_someip_parameter_arrays();
4633 update_dynamic_hf_entries_someip_parameter_structs();
4634 update_dynamic_hf_entries_someip_parameter_unions();
4643 * indent-tabs-mode: nil
4646 * ex: set shiftwidth=4 tabstop=8 expandtab:
4647 * :indentSize=4:tabSize=8:noTabs=true: