/src/wireshark/epan/dissectors/packet-someip.c
Line | Count | Source |
1 | | /* packet-someip.c |
2 | | * SOME/IP dissector. |
3 | | * By Dr. Lars Voelker <lars.voelker@technica-engineering.de> / <lars.voelker@bmw.de> |
4 | | * Copyright 2012-2025 Dr. Lars Völker |
5 | | * Copyright 2019 Ana Pantar |
6 | | * Copyright 2019 Guenter Ebermann |
7 | | * |
8 | | * Wireshark - Network traffic analyzer |
9 | | * By Gerald Combs <gerald@wireshark.org> |
10 | | * Copyright 1998 Gerald Combs |
11 | | * |
12 | | * SPDX-License-Identifier: GPL-2.0-or-later |
13 | | */ |
14 | | |
15 | | #include <config.h> |
16 | | |
17 | | #include <epan/packet.h> |
18 | | #include <epan/prefs.h> |
19 | | #include <epan/expert.h> |
20 | | #include <epan/to_str.h> |
21 | | #include <epan/uat.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> |
27 | | |
28 | | #include "packet-udp.h" |
29 | | #include "packet-dtls.h" |
30 | | #include "packet-someip.h" |
31 | | #include "packet-tls.h" |
32 | | |
33 | | /* |
34 | | * Dissector for SOME/IP, SOME/IP-TP, and SOME/IP Payloads. |
35 | | * |
36 | | * See |
37 | | * http://www.some-ip.com |
38 | | * |
39 | | * |
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. |
48 | | */ |
49 | | |
50 | 90 | #define SOMEIP_NAME_PREFIX "someip.payload.data" |
51 | | |
52 | | #define SOMEIP_NAME_LONG_MULTIPLE "SOME/IP Protocol (Multiple Payloads)" |
53 | | #define SOMEIP_NAME_LONG_BROKEN "SOME/IP: Incomplete headers!" |
54 | | #define SOMEIP_NAME_LONG_TOO_SHORT "SOME/IP: Incomplete SOME/IP payload!" |
55 | | |
56 | | /*** Configuration ***/ |
57 | 15 | #define DATAFILE_SOMEIP_SERVICES "SOMEIP_service_identifiers" |
58 | 15 | #define DATAFILE_SOMEIP_METHODS "SOMEIP_method_event_identifiers" |
59 | 15 | #define DATAFILE_SOMEIP_EVENTGROUPS "SOMEIP_eventgroup_identifiers" |
60 | 15 | #define DATAFILE_SOMEIP_CLIENTS "SOMEIP_client_identifiers" |
61 | | |
62 | 15 | #define DATAFILE_SOMEIP_PARAMETERS "SOMEIP_parameter_list" |
63 | 15 | #define DATAFILE_SOMEIP_BASE_TYPES "SOMEIP_parameter_base_types" |
64 | 15 | #define DATAFILE_SOMEIP_STRINGS "SOMEIP_parameter_strings" |
65 | 15 | #define DATAFILE_SOMEIP_STRUCTS "SOMEIP_parameter_structs" |
66 | 15 | #define DATAFILE_SOMEIP_ARRAYS "SOMEIP_parameter_arrays" |
67 | 15 | #define DATAFILE_SOMEIP_UNIONS "SOMEIP_parameter_unions" |
68 | 15 | #define DATAFILE_SOMEIP_TYPEDEFS "SOMEIP_parameter_typedefs" |
69 | 15 | #define DATAFILE_SOMEIP_ENUMS "SOMEIP_parameter_enums" |
70 | 15 | #define DATAFILE_SOMEIP_BITFIELDS "SOMEIP_parameter_bitfields" |
71 | | |
72 | 0 | #define SOMEIP_PARAMETER_DATA_TYPE_MIN 1 |
73 | 0 | #define SOMEIP_PARAMETER_DATA_TYPE_BASE_TYPE 1 |
74 | 0 | #define SOMEIP_PARAMETER_DATA_TYPE_STRING 2 |
75 | 0 | #define SOMEIP_PARAMETER_DATA_TYPE_ARRAY 3 |
76 | 0 | #define SOMEIP_PARAMETER_DATA_TYPE_STRUCT 4 |
77 | 0 | #define SOMEIP_PARAMETER_DATA_TYPE_UNION 5 |
78 | 0 | #define SOMEIP_PARAMETER_DATA_TYPE_TYPEDEF 6 |
79 | 0 | #define SOMEIP_PARAMETER_DATA_TYPE_ENUM 7 |
80 | 0 | #define SOMEIP_PARAMETER_DATA_TYPE_BITFIELD 8 |
81 | 0 | #define SOMEIP_PARAMETER_DATA_TYPE_MAX 8 |
82 | | |
83 | 0 | #define SOMEIP_PARAMETER_DATA_TYPE_BITFIELD_INT 0xFE |
84 | | |
85 | | /*** SOME/IP ***/ |
86 | 0 | #define SOMEIP_HDR_LEN 16 |
87 | 0 | #define SOMEIP_HDR_PART1_LEN 8 |
88 | | #define SOMEIP_HDR_PART2_LEN_INCL_TP 12 |
89 | 0 | #define SOMEIP_TP_HDR_LEN 4 |
90 | 0 | #define SOMEIP_PROTOCOL_VERSION 1 |
91 | | |
92 | | /* Message Types */ |
93 | | #define SOMEIP_MSGTYPE_REQUEST 0x00 |
94 | | #define SOMEIP_MSGTYPE_REQUEST_NO_RESPONSE 0x01 |
95 | | #define SOMEIP_MSGTYPE_NOTIFICATION 0x02 |
96 | | #define SOMEIP_MSGTYPE_RESPONSE 0x80 |
97 | | #define SOMEIP_MSGTYPE_ERROR 0x81 |
98 | | |
99 | 15 | #define SOMEIP_MSGTYPE_ACK_MASK 0x40 |
100 | 15 | #define SOMEIP_MSGTYPE_TP_MASK 0x20 |
101 | | #define SOMEIP_MSGTYPE_FLAGS_MASK 0x60 |
102 | | #define SOMEIP_MSGTYPE_NO_FLAGS_MASK 0x9f |
103 | 0 | #define SOMEIP_MSGTYPE_TP_STRING "SOME/IP-TP segment" |
104 | | #define SOMEIP_MSGTYPE_ACK_STRING "ACK" |
105 | | |
106 | | /* SOME/IP-TP */ |
107 | 15 | #define SOMEIP_TP_OFFSET_MASK 0xfffffff0 |
108 | 15 | #define SOMEIP_TP_OFFSET_MASK_FLAGS 0x0000000f |
109 | 15 | #define SOMEIP_TP_OFFSET_MASK_RESERVED 0x0000000e |
110 | 15 | #define SOMEIP_TP_OFFSET_MASK_MORE_SEGMENTS 0x00000001 |
111 | | |
112 | | /* Return Codes */ |
113 | | #define SOMEIP_RETCODE_OK 0x00 |
114 | | #define SOMEIP_RETCODE_NOT_OK 0x01 |
115 | | #define SOMEIP_RETCODE_UNKNOWN_SERVICE 0x02 |
116 | | #define SOMEIP_RETCODE_UNKNOWN_METHOD 0x03 |
117 | | #define SOMEIP_RETCODE_NOT_READY 0x04 |
118 | | #define SOMEIP_RETCODE_NOT_REACHABLE 0x05 |
119 | | #define SOMEIP_RETCODE_TIMEOUT 0x06 |
120 | | #define SOMEIP_RETCODE_WRONG_PROTO_VER 0x07 |
121 | | #define SOMEIP_RETCODE_WRONG_INTERFACE_VER 0x08 |
122 | | #define SOMEIP_RETCODE_MALFORMED_MSG 0x09 |
123 | | #define SOMEIP_RETCODE_WRONG_MESSAGE_TYPE 0x0a |
124 | | |
125 | | /* SOME/IP WTLV (experimental "WTLV" extension) */ |
126 | 15 | #define SOMEIP_WTLV_MASK_RES 0x8000 |
127 | 15 | #define SOMEIP_WTLV_MASK_WIRE_TYPE 0x7000 |
128 | 15 | #define SOMEIP_WTLV_MASK_DATA_ID 0x0fff |
129 | | |
130 | | /* ID wireshark identifies the dissector by */ |
131 | | static int proto_someip; |
132 | | static module_t *someip_module; |
133 | | |
134 | | static dissector_handle_t someip_handle_udp; |
135 | | static dissector_handle_t someip_handle_tcp; |
136 | | static dissector_handle_t dtls_handle; |
137 | | |
138 | | /* header field */ |
139 | | static int hf_someip_messageid; |
140 | | static int hf_someip_serviceid; |
141 | | static int hf_someip_servicename; |
142 | | static int hf_someip_methodid; |
143 | | static int hf_someip_methodname; |
144 | | static int hf_someip_length; |
145 | | static int hf_someip_clientid; |
146 | | static int hf_someip_clientname; |
147 | | static int hf_someip_sessionid; |
148 | | static int hf_someip_protover; |
149 | | static int hf_someip_interface_ver; |
150 | | static int hf_someip_messagetype; |
151 | | static int hf_someip_messagetype_ack_flag; |
152 | | static int hf_someip_messagetype_tp_flag; |
153 | | static int hf_someip_returncode; |
154 | | |
155 | | static int hf_someip_tp; |
156 | | static int hf_someip_tp_offset; |
157 | | static int hf_someip_tp_offset_encoded; |
158 | | static int hf_someip_tp_flags; |
159 | | static int hf_someip_tp_reserved; |
160 | | static int hf_someip_tp_more_segments; |
161 | | |
162 | | static int hf_someip_payload; |
163 | | |
164 | | /* protocol tree items */ |
165 | | static int ett_someip; |
166 | | static int ett_someip_msgtype; |
167 | | static int ett_someip_tp; |
168 | | |
169 | | /* dissector handling */ |
170 | | static dissector_table_t someip_dissector_table; |
171 | | |
172 | | /* message reassembly for SOME/IP-TP */ |
173 | | static int hf_someip_tp_fragments; |
174 | | static int hf_someip_tp_fragment; |
175 | | static int hf_someip_tp_fragment_overlap; |
176 | | static int hf_someip_tp_fragment_overlap_conflicts; |
177 | | static int hf_someip_tp_fragment_multiple_tails; |
178 | | static int hf_someip_tp_fragment_too_long_fragment; |
179 | | static int hf_someip_tp_fragment_error; |
180 | | static int hf_someip_tp_fragment_count; |
181 | | static int hf_someip_tp_reassembled_in; |
182 | | static int hf_someip_tp_reassembled_length; |
183 | | static int hf_someip_tp_reassembled_data; |
184 | | |
185 | | static int hf_payload_unparsed; |
186 | | static int hf_payload_length_field_8bit; |
187 | | static int hf_payload_length_field_16bit; |
188 | | static int hf_payload_length_field_32bit; |
189 | | static int hf_payload_type_field_8bit; |
190 | | static int hf_payload_type_field_16bit; |
191 | | static int hf_payload_type_field_32bit; |
192 | | static int hf_payload_str_base; |
193 | | static int hf_payload_str_string; |
194 | | static int hf_payload_str_array; |
195 | | static int hf_payload_str_struct; |
196 | | static int hf_payload_str_union; |
197 | | static int hf_payload_str_bitfield; |
198 | | static int hf_payload_bitfield_item; |
199 | | |
200 | | static int hf_payload_wtlv_tag; |
201 | | static int hf_payload_wtlv_tag_res; |
202 | | static int hf_payload_wtlv_tag_wire_type; |
203 | | static int hf_payload_wtlv_tag_data_id; |
204 | | |
205 | | static hf_register_info *dynamic_hf_param; |
206 | | static unsigned dynamic_hf_param_size; |
207 | | static hf_register_info *dynamic_hf_array; |
208 | | static unsigned dynamic_hf_array_size; |
209 | | static hf_register_info *dynamic_hf_struct; |
210 | | static unsigned dynamic_hf_struct_size; |
211 | | static hf_register_info *dynamic_hf_union; |
212 | | static unsigned dynamic_hf_union_size; |
213 | | static hf_register_info *dynamic_hf_bitfield; |
214 | | static unsigned dynamic_hf_bitfield_size; |
215 | | |
216 | | static int ett_someip_tp_fragment; |
217 | | static int ett_someip_tp_fragments; |
218 | | static int ett_someip_payload; |
219 | | static int ett_someip_string; |
220 | | static int ett_someip_array; |
221 | | static int ett_someip_array_dim; |
222 | | static int ett_someip_struct; |
223 | | static int ett_someip_union; |
224 | | static int ett_someip_bitfield; |
225 | | static int ett_someip_parameter; |
226 | | static int ett_someip_wtlv_tag; |
227 | | |
228 | | static const fragment_items someip_tp_frag_items = { |
229 | | &ett_someip_tp_fragment, |
230 | | &ett_someip_tp_fragments, |
231 | | &hf_someip_tp_fragments, |
232 | | &hf_someip_tp_fragment, |
233 | | &hf_someip_tp_fragment_overlap, |
234 | | &hf_someip_tp_fragment_overlap_conflicts, |
235 | | &hf_someip_tp_fragment_multiple_tails, |
236 | | &hf_someip_tp_fragment_too_long_fragment, |
237 | | &hf_someip_tp_fragment_error, |
238 | | &hf_someip_tp_fragment_count, |
239 | | &hf_someip_tp_reassembled_in, |
240 | | &hf_someip_tp_reassembled_length, |
241 | | &hf_someip_tp_reassembled_data, |
242 | | "SOME/IP-TP Segments" |
243 | | }; |
244 | | |
245 | | static bool someip_tp_reassemble = true; |
246 | | static bool someip_deserializer_activated = true; |
247 | | static bool someip_deserializer_debugging_activated; |
248 | | static bool someip_deserializer_wtlv_default; |
249 | | static bool someip_test_tcp_for_valid_someip = true; |
250 | | static bool someip_detect_dtls; |
251 | | |
252 | | /* SOME/IP Message Types */ |
253 | | static const value_string someip_msg_type[] = { |
254 | | {SOMEIP_MSGTYPE_REQUEST, "Request"}, |
255 | | {SOMEIP_MSGTYPE_REQUEST_NO_RESPONSE, "Request no response"}, |
256 | | {SOMEIP_MSGTYPE_NOTIFICATION, "Notification"}, |
257 | | {SOMEIP_MSGTYPE_RESPONSE, "Response"}, |
258 | | {SOMEIP_MSGTYPE_ERROR, "Error"}, |
259 | | {SOMEIP_MSGTYPE_REQUEST | SOMEIP_MSGTYPE_ACK_MASK, "Request Ack"}, |
260 | | {SOMEIP_MSGTYPE_REQUEST_NO_RESPONSE | SOMEIP_MSGTYPE_ACK_MASK, "Request no response Ack"}, |
261 | | {SOMEIP_MSGTYPE_NOTIFICATION | SOMEIP_MSGTYPE_ACK_MASK, "Notification Ack"}, |
262 | | {SOMEIP_MSGTYPE_RESPONSE | SOMEIP_MSGTYPE_ACK_MASK, "Response Ack"}, |
263 | | {SOMEIP_MSGTYPE_ERROR | SOMEIP_MSGTYPE_ACK_MASK, "Error Ack"}, |
264 | | {0, NULL} |
265 | | }; |
266 | | |
267 | | /* SOME/IP Return Code */ |
268 | | static const value_string someip_return_code[] = { |
269 | | {SOMEIP_RETCODE_OK, "Ok"}, |
270 | | {SOMEIP_RETCODE_NOT_OK, "Not Ok"}, |
271 | | {SOMEIP_RETCODE_UNKNOWN_SERVICE, "Unknown Service"}, |
272 | | {SOMEIP_RETCODE_UNKNOWN_METHOD, "Unknown Method/Event"}, |
273 | | {SOMEIP_RETCODE_NOT_READY, "Not Ready"}, |
274 | | {SOMEIP_RETCODE_NOT_REACHABLE, "Not Reachable (internal)"}, |
275 | | {SOMEIP_RETCODE_TIMEOUT, "Timeout (internal)"}, |
276 | | {SOMEIP_RETCODE_WRONG_PROTO_VER, "Wrong Protocol Version"}, |
277 | | {SOMEIP_RETCODE_WRONG_INTERFACE_VER, "Wrong Interface Version"}, |
278 | | {SOMEIP_RETCODE_MALFORMED_MSG, "Malformed Message"}, |
279 | | {SOMEIP_RETCODE_WRONG_MESSAGE_TYPE, "Wrong Message Type"}, |
280 | | {0, NULL} |
281 | | }; |
282 | | |
283 | | /*** expert info items ***/ |
284 | | static expert_field ei_someip_unknown_version; |
285 | | static expert_field ei_someip_message_truncated; |
286 | | static expert_field ei_someip_incomplete_headers; |
287 | | |
288 | | static expert_field ei_someip_payload_truncated; |
289 | | static expert_field ei_someip_payload_malformed; |
290 | | static expert_field ei_someip_payload_config_error; |
291 | | static expert_field ei_someip_payload_alignment_error; |
292 | | static expert_field ei_someip_payload_static_array_min_not_max; |
293 | | static expert_field ei_someip_payload_dyn_array_not_within_limit; |
294 | | static expert_field ei_someip_payload_disabled; |
295 | | |
296 | | /*** Data Structure for mapping IDs to Names (Services, Methods, ...) ***/ |
297 | | static GHashTable *data_someip_services; |
298 | | static GHashTable *data_someip_methods; |
299 | | static GHashTable *data_someip_eventgroups; |
300 | | static GHashTable *data_someip_clients; |
301 | | |
302 | | static GHashTable *data_someip_parameter_list; |
303 | | static GHashTable *data_someip_parameter_base_type_list; |
304 | | static GHashTable *data_someip_parameter_strings; |
305 | | static GHashTable *data_someip_parameter_arrays; |
306 | | static GHashTable *data_someip_parameter_structs; |
307 | | static GHashTable *data_someip_parameter_unions; |
308 | | static GHashTable *data_someip_parameter_typedefs; |
309 | | static GHashTable *data_someip_parameter_enums; |
310 | | static GHashTable *data_someip_parameter_bitfields; |
311 | | |
312 | | /*** Taps ***/ |
313 | | static int tap_someip_messages = -1; |
314 | | |
315 | | /*** Stats ***/ |
316 | | static const char *st_str_ip_src = "Source Addresses"; |
317 | | static const char *st_str_ip_dst = "Destination Addresses"; |
318 | | |
319 | | static int st_node_ip_src = -1; |
320 | | static int st_node_ip_dst = -1; |
321 | | |
322 | | /*********************************************** |
323 | | ********* Preferences / Configuration ********* |
324 | | ***********************************************/ |
325 | | |
326 | | /*** Parameter List UAT ***/ |
327 | | typedef struct _someip_payload_parameter_item { |
328 | | uint32_t pos; |
329 | | char *name; |
330 | | uint32_t data_type; |
331 | | uint32_t id_ref; |
332 | | int *hf_id; |
333 | | char *filter_string; |
334 | | } someip_parameter_item_t; |
335 | | |
336 | | #define INIT_SOMEIP_PARAMETER_ITEM(NAME) \ |
337 | 0 | (NAME)->pos = 0; \ |
338 | 0 | (NAME)->name = NULL; \ |
339 | 0 | (NAME)->data_type = 0; \ |
340 | 0 | (NAME)->id_ref = 0; \ |
341 | 0 | (NAME)->hf_id = NULL; \ |
342 | 0 | (NAME)->filter_string = NULL; |
343 | | |
344 | | typedef struct _someip_parameter_list { |
345 | | uint32_t service_id; |
346 | | uint32_t method_id; |
347 | | uint32_t version; |
348 | | uint32_t message_type; |
349 | | bool wtlv_encoding; |
350 | | |
351 | | uint32_t num_of_items; |
352 | | |
353 | | someip_parameter_item_t *items; |
354 | | } someip_parameter_list_t; |
355 | | |
356 | | typedef struct _someip_parameter_list_uat { |
357 | | uint32_t service_id; |
358 | | uint32_t method_id; |
359 | | uint32_t version; |
360 | | uint32_t message_type; |
361 | | bool wtlv_encoding; |
362 | | |
363 | | uint32_t num_of_params; |
364 | | |
365 | | uint32_t pos; |
366 | | char *name; |
367 | | uint32_t data_type; |
368 | | uint32_t id_ref; |
369 | | char *filter_string; |
370 | | } someip_parameter_list_uat_t; |
371 | | |
372 | | |
373 | | /*** Parameter Basetypes UAT (ID: 1) ***/ |
374 | | typedef struct _someip_parameter_base_type_list { |
375 | | uint32_t id; |
376 | | char *name; |
377 | | char *data_type; |
378 | | bool big_endian; |
379 | | uint32_t bitlength_base_type; |
380 | | uint32_t bitlength_encoded_type; |
381 | | } someip_parameter_base_type_list_t; |
382 | | |
383 | | #define INIT_COMMON_BASE_TYPE_LIST_ITEM(NAME) \ |
384 | | (NAME)->id = 0; \ |
385 | | (NAME)->name = NULL; \ |
386 | | (NAME)->data_type = NULL ; \ |
387 | | (NAME)->big_endian = true; \ |
388 | | (NAME)->bitlength_base_type = 0; \ |
389 | | (NAME)->bitlength_encoded_type = 0; |
390 | | |
391 | | typedef someip_parameter_base_type_list_t someip_parameter_base_type_list_uat_t; |
392 | | |
393 | | |
394 | | /*** Parameter Strings UAT (ID: 2) ***/ |
395 | | typedef struct _someip_parameter_string { |
396 | | uint32_t id; |
397 | | char *name; |
398 | | char *encoding; |
399 | | bool dynamic_length; |
400 | | uint32_t max_length; |
401 | | uint32_t length_of_length; /* default: 32 */ |
402 | | bool big_endian; |
403 | | uint32_t pad_to; |
404 | | } someip_parameter_string_t; |
405 | | |
406 | | #define INIT_SOMEIP_PARAMETER_STRING(NAME) \ |
407 | | (NAME)->id = 0; \ |
408 | | (NAME)->name = NULL; \ |
409 | | (NAME)->encoding = NULL; \ |
410 | | (NAME)->dynamic_length = false; \ |
411 | | (NAME)->max_length = 0; \ |
412 | | (NAME)->length_of_length = 0; \ |
413 | | (NAME)->big_endian = true; \ |
414 | | (NAME)->pad_to = 0; |
415 | | |
416 | | typedef someip_parameter_string_t someip_parameter_string_uat_t; |
417 | | |
418 | | |
419 | | /*** Parameter Array UAT (ID: 3) ***/ |
420 | | typedef struct _someip_parameter_array_dim { |
421 | | uint32_t num; |
422 | | uint32_t lower_limit; |
423 | | uint32_t upper_limit; |
424 | | uint32_t length_of_length; |
425 | | uint32_t pad_to; |
426 | | } someip_parameter_array_dim_t; |
427 | | |
428 | | typedef struct _someip_parameter_array { |
429 | | uint32_t id; |
430 | | char *name; |
431 | | uint32_t data_type; |
432 | | uint32_t id_ref; |
433 | | uint32_t num_of_dims; |
434 | | int *hf_id; |
435 | | char *filter_string; |
436 | | |
437 | | someip_parameter_array_dim_t *dims; |
438 | | } someip_parameter_array_t; |
439 | | |
440 | | typedef struct _someip_parameter_array_uat { |
441 | | uint32_t id; |
442 | | char *name; |
443 | | uint32_t data_type; |
444 | | uint32_t id_ref; |
445 | | uint32_t num_of_dims; |
446 | | char *filter_string; |
447 | | |
448 | | uint32_t num; |
449 | | uint32_t lower_limit; |
450 | | uint32_t upper_limit; |
451 | | uint32_t length_of_length; |
452 | | uint32_t pad_to; |
453 | | } someip_parameter_array_uat_t; |
454 | | |
455 | | |
456 | | /*** Parameter Struct UAT (ID: 4) ***/ |
457 | | typedef struct _someip_parameter_struct { |
458 | | uint32_t id; |
459 | | char *struct_name; |
460 | | uint32_t length_of_length; /* default: 0 */ |
461 | | uint32_t pad_to; /* default: 0 */ |
462 | | bool wtlv_encoding; |
463 | | uint32_t num_of_items; |
464 | | |
465 | | /* array of items */ |
466 | | someip_parameter_item_t *items; |
467 | | } someip_parameter_struct_t; |
468 | | |
469 | | #define INIT_SOMEIP_PARAMETER_STRUCT(NAME) \ |
470 | 0 | (NAME)->id = 0; \ |
471 | 0 | (NAME)->struct_name = NULL; \ |
472 | 0 | (NAME)->length_of_length = 0; \ |
473 | 0 | (NAME)->pad_to = 0; \ |
474 | 0 | (NAME)->wtlv_encoding = false; \ |
475 | 0 | (NAME)->num_of_items = 0; |
476 | | |
477 | | typedef struct _someip_parameter_struct_uat { |
478 | | uint32_t id; |
479 | | char *struct_name; |
480 | | uint32_t length_of_length; /* default: 0 */ |
481 | | uint32_t pad_to; /* default: 0 */ |
482 | | bool wtlv_encoding; |
483 | | |
484 | | uint32_t num_of_items; |
485 | | |
486 | | uint32_t pos; |
487 | | char *name; |
488 | | uint32_t data_type; |
489 | | uint32_t id_ref; |
490 | | char *filter_string; |
491 | | } someip_parameter_struct_uat_t; |
492 | | |
493 | | |
494 | | /*** Parameter Union UAT (ID: 5) ***/ |
495 | | typedef struct _someip_parameter_union_item { |
496 | | uint32_t id; |
497 | | char *name; |
498 | | uint32_t data_type; |
499 | | uint32_t id_ref; |
500 | | int *hf_id; |
501 | | char *filter_string; |
502 | | } someip_parameter_union_item_t; |
503 | | |
504 | | typedef struct _someip_parameter_union { |
505 | | uint32_t id; |
506 | | char *name; |
507 | | uint32_t length_of_length; /* default: 32 */ |
508 | | uint32_t length_of_type; /* default: 32 */ |
509 | | uint32_t pad_to; /* default: 0 */ |
510 | | uint32_t num_of_items; |
511 | | |
512 | | someip_parameter_union_item_t *items; |
513 | | } someip_parameter_union_t; |
514 | | |
515 | | typedef struct _someip_parameter_union_uat { |
516 | | uint32_t id; |
517 | | char *name; |
518 | | uint32_t length_of_length; |
519 | | uint32_t length_of_type; |
520 | | uint32_t pad_to; |
521 | | uint32_t num_of_items; |
522 | | uint32_t type_id; |
523 | | char *type_name; |
524 | | uint32_t data_type; |
525 | | uint32_t id_ref; |
526 | | char *filter_string; |
527 | | } someip_parameter_union_uat_t; |
528 | | |
529 | | |
530 | | /*** Parameter Typedef UAT (ID: 6) ***/ |
531 | | typedef struct _someip_parameter_typedef { |
532 | | uint32_t id; |
533 | | char *name; |
534 | | uint32_t data_type; |
535 | | uint32_t id_ref; |
536 | | } someip_parameter_typedef_t; |
537 | | |
538 | | #define INIT_SOMEIP_PARAMETER_TYPEDEF(NAME) \ |
539 | | (NAME)->id = 0; \ |
540 | | (NAME)->name = NULL; \ |
541 | | (NAME)->data_type = 0; \ |
542 | | (NAME)->id_ref = 0; |
543 | | |
544 | | typedef someip_parameter_typedef_t someip_parameter_typedef_uat_t; |
545 | | |
546 | | |
547 | | /*** Parameter Enum UAT (ID: 7) ***/ |
548 | | typedef struct _someip_parameter_enum_item { |
549 | | uint64_t value; |
550 | | char *name; |
551 | | } someip_parameter_enum_item_t; |
552 | | |
553 | | #define INIT_SOMEIP_PARAMETER_ENUM_ITEM(NAME) \ |
554 | 0 | (NAME)->value = 0; \ |
555 | 0 | (NAME)->name = NULL; |
556 | | |
557 | | typedef struct _someip_parameter_enum { |
558 | | uint32_t id; |
559 | | char *name; |
560 | | uint32_t data_type; |
561 | | uint32_t id_ref; |
562 | | uint32_t num_of_items; |
563 | | |
564 | | someip_parameter_enum_item_t *items; |
565 | | } someip_parameter_enum_t; |
566 | | |
567 | | #define INIT_SOMEIP_PAYLOAD_PARAMETER_ENUM(NAME) \ |
568 | 0 | (NAME)->id = 0; \ |
569 | 0 | (NAME)->name = NULL; \ |
570 | 0 | (NAME)->data_type = 0; \ |
571 | 0 | (NAME)->id_ref = 0; \ |
572 | 0 | (NAME)->num_of_items = 0; \ |
573 | 0 | (NAME)->items = NULL; |
574 | | |
575 | | typedef struct _someip_parameter_enum_uat { |
576 | | uint32_t id; |
577 | | char *name; |
578 | | uint32_t data_type; |
579 | | uint32_t id_ref; |
580 | | uint32_t num_of_items; |
581 | | uint32_t value; |
582 | | char *value_name; |
583 | | } someip_parameter_enum_uat_t; |
584 | | |
585 | | |
586 | | |
587 | | /*** Parameter Bitfield UAT (ID: 8) ***/ |
588 | | |
589 | | typedef struct _someip_parameter_bitfield_item { |
590 | | uint8_t bit_number; |
591 | | char *bit_name; |
592 | | int *hf_id; |
593 | | char *filter_string; |
594 | | } someip_parameter_bitfield_item_t; |
595 | | |
596 | | #define INIT_SOMEIP_PARAMETER_BITFIELD_ITEM(NAME) \ |
597 | 0 | (NAME)->bit_number = 0; \ |
598 | 0 | (NAME)->bit_name = NULL; \ |
599 | 0 | (NAME)->hf_id = NULL; \ |
600 | 0 | (NAME)->filter_string = NULL; |
601 | | |
602 | | typedef struct _someip_parameter_bitfield { |
603 | | uint32_t id; |
604 | | char *name; |
605 | | uint8_t number_of_bits; |
606 | | uint32_t num_of_items; |
607 | | |
608 | | someip_parameter_bitfield_item_t *items; |
609 | | } someip_parameter_bitfield_t; |
610 | | |
611 | | #define INIT_SOMEIP_PARAMETER_BITFIELD(NAME) \ |
612 | 0 | (NAME)->id = 0; \ |
613 | 0 | (NAME)->name = NULL; \ |
614 | 0 | (NAME)->number_of_bits = 0; \ |
615 | 0 | (NAME)->num_of_items = 0; \ |
616 | 0 | (NAME)->items = NULL; |
617 | | |
618 | | typedef struct _someip_parameter_bitfield_uat { |
619 | | uint32_t id; |
620 | | char *name; |
621 | | uint32_t number_of_bits; |
622 | | uint32_t num_of_items; |
623 | | uint32_t bit_number; |
624 | | char *bit_name; |
625 | | char *filter_string; |
626 | | } someip_parameter_bitfield_uat_t; |
627 | | |
628 | | |
629 | | typedef struct _generic_one_id_string { |
630 | | unsigned id; |
631 | | char *name; |
632 | | } generic_one_id_string_t; |
633 | | |
634 | | typedef struct _generic_two_id_string { |
635 | | unsigned id; |
636 | | unsigned id2; |
637 | | char *name; |
638 | | } generic_two_id_string_t; |
639 | | |
640 | | static generic_one_id_string_t *someip_service_ident; |
641 | | static unsigned someip_service_ident_num; |
642 | | |
643 | | static generic_two_id_string_t *someip_method_ident; |
644 | | static unsigned someip_method_ident_num; |
645 | | |
646 | | static generic_two_id_string_t *someip_eventgroup_ident; |
647 | | static unsigned someip_eventgroup_ident_num; |
648 | | |
649 | | static generic_two_id_string_t *someip_client_ident; |
650 | | static unsigned someip_client_ident_num; |
651 | | |
652 | | static someip_parameter_list_uat_t *someip_parameter_list; |
653 | | static unsigned someip_parameter_list_num; |
654 | | |
655 | | static someip_parameter_base_type_list_uat_t *someip_parameter_base_type_list; |
656 | | static unsigned someip_parameter_base_type_list_num; |
657 | | |
658 | | static someip_parameter_string_uat_t *someip_parameter_strings; |
659 | | static unsigned someip_parameter_strings_num; |
660 | | |
661 | | static someip_parameter_array_uat_t *someip_parameter_arrays; |
662 | | static unsigned someip_parameter_arrays_num; |
663 | | |
664 | | static someip_parameter_struct_uat_t *someip_parameter_structs; |
665 | | static unsigned someip_parameter_structs_num; |
666 | | |
667 | | static someip_parameter_union_uat_t *someip_parameter_unions; |
668 | | static unsigned someip_parameter_unions_num; |
669 | | |
670 | | static someip_parameter_typedef_uat_t *someip_parameter_typedefs; |
671 | | static unsigned someip_parameter_typedefs_num; |
672 | | |
673 | | static someip_parameter_enum_uat_t *someip_parameter_enums; |
674 | | static unsigned someip_parameter_enums_num; |
675 | | |
676 | | static someip_parameter_bitfield_uat_t *someip_parameter_bitfields; |
677 | | static unsigned someip_parameter_bitfields_num; |
678 | | |
679 | | void proto_register_someip(void); |
680 | | void proto_reg_handoff_someip(void); |
681 | | |
682 | | /* Segmentation support |
683 | | * https://gitlab.com/wireshark/wireshark/-/issues/18880 |
684 | | */ |
685 | | typedef struct _someip_segment_key { |
686 | | address src_addr; |
687 | | address dst_addr; |
688 | | uint32_t src_port; |
689 | | uint32_t dst_port; |
690 | | someip_info_t info; |
691 | | } someip_segment_key; |
692 | | |
693 | | static unsigned |
694 | | someip_segment_hash(const void *k) |
695 | 0 | { |
696 | 0 | const someip_segment_key *key = (const someip_segment_key *)k; |
697 | 0 | unsigned hash_val; |
698 | |
|
699 | 0 | hash_val = (key->info.service_id << 16 | key->info.method_id) ^ |
700 | 0 | (key->info.client_id << 16 | key->info.session_id); |
701 | |
|
702 | 0 | return hash_val; |
703 | 0 | } |
704 | | |
705 | | static int |
706 | | someip_segment_equal(const void *k1, const void *k2) |
707 | 0 | { |
708 | 0 | const someip_segment_key *key1 = (someip_segment_key *)k1; |
709 | 0 | const someip_segment_key *key2 = (someip_segment_key *)k2; |
710 | |
|
711 | 0 | return (key1->info.session_id == key2->info.session_id) && |
712 | 0 | (key1->info.service_id == key2->info.service_id) && |
713 | 0 | (key1->info.client_id == key2->info.client_id) && |
714 | 0 | (key1->info.method_id == key2->info.method_id) && |
715 | 0 | (key1->info.message_type == key2->info.message_type) && |
716 | 0 | (key1->info.major_version == key2->info.major_version) && |
717 | 0 | (addresses_equal(&key1->src_addr, &key2->src_addr)) && |
718 | 0 | (addresses_equal(&key1->dst_addr, &key2->dst_addr)) && |
719 | 0 | (key1->src_port == key2->src_port) && |
720 | 0 | (key1->dst_port == key2->dst_port); |
721 | 0 | } |
722 | | |
723 | | /* |
724 | | * Create a fragment key for temporary use; it can point to non- |
725 | | * persistent data, and so must only be used to look up and |
726 | | * delete entries, not to add them. |
727 | | */ |
728 | | static void * |
729 | | someip_segment_temporary_key(const packet_info *pinfo, const uint32_t id _U_, |
730 | | const void *data) |
731 | 0 | { |
732 | 0 | const someip_info_t *info = (const someip_info_t *)data; |
733 | 0 | someip_segment_key *key = g_slice_new(someip_segment_key); |
734 | | |
735 | | /* Do a shallow copy of the addresses. */ |
736 | 0 | copy_address_shallow(&key->src_addr, &pinfo->src); |
737 | 0 | copy_address_shallow(&key->dst_addr, &pinfo->dst); |
738 | 0 | key->src_port = pinfo->srcport; |
739 | 0 | key->dst_port = pinfo->destport; |
740 | 0 | memcpy(&key->info, info, sizeof(someip_info_t)); |
741 | |
|
742 | 0 | return (void *)key; |
743 | 0 | } |
744 | | |
745 | | /* |
746 | | * Create a fragment key for permanent use; it must point to persistent |
747 | | * data, so that it can be used to add entries. |
748 | | */ |
749 | | static void * |
750 | | someip_segment_persistent_key(const packet_info *pinfo, |
751 | | const uint32_t id _U_, const void *data) |
752 | 0 | { |
753 | 0 | const someip_info_t *info = (const someip_info_t *)data; |
754 | 0 | someip_segment_key *key = g_slice_new(someip_segment_key); |
755 | | |
756 | | /* Do a deep copy of the addresses. */ |
757 | 0 | copy_address(&key->src_addr, &pinfo->src); |
758 | 0 | copy_address(&key->dst_addr, &pinfo->dst); |
759 | 0 | key->src_port = pinfo->srcport; |
760 | 0 | key->dst_port = pinfo->destport; |
761 | 0 | memcpy(&key->info, info, sizeof(someip_info_t)); |
762 | |
|
763 | 0 | return (void *)key; |
764 | 0 | } |
765 | | |
766 | | static void |
767 | | someip_segment_free_temporary_key(void *ptr) |
768 | 0 | { |
769 | 0 | someip_segment_key *key = (someip_segment_key *)ptr; |
770 | 0 | if (key) { |
771 | 0 | g_slice_free(someip_segment_key, key); |
772 | 0 | } |
773 | 0 | } |
774 | | static void |
775 | | someip_segment_free_persistent_key(void *ptr) |
776 | 0 | { |
777 | 0 | someip_segment_key *key = (someip_segment_key *)ptr; |
778 | 0 | if (key) { |
779 | | /* Free up the copies of the addresses from the old key. */ |
780 | 0 | free_address(&key->src_addr); |
781 | 0 | free_address(&key->dst_addr); |
782 | |
|
783 | 0 | g_slice_free(someip_segment_key, key); |
784 | 0 | } |
785 | 0 | } |
786 | | |
787 | | static const reassembly_table_functions |
788 | | someip_reassembly_table_functions = { |
789 | | someip_segment_hash, |
790 | | someip_segment_equal, |
791 | | someip_segment_temporary_key, |
792 | | someip_segment_persistent_key, |
793 | | someip_segment_free_temporary_key, |
794 | | someip_segment_free_persistent_key |
795 | | }; |
796 | | |
797 | | static reassembly_table someip_tp_reassembly_table; |
798 | | |
799 | | |
800 | | /* register a UDP SOME/IP port */ |
801 | | void |
802 | 0 | register_someip_port_udp(uint32_t portnumber) { |
803 | 0 | dissector_add_uint("udp.port", portnumber, someip_handle_udp); |
804 | 0 | } |
805 | | |
806 | | /* register a TCP SOME/IP port */ |
807 | | void |
808 | 0 | register_someip_port_tcp(uint32_t portnumber) { |
809 | 0 | dissector_add_uint("tcp.port", portnumber, someip_handle_tcp); |
810 | 0 | } |
811 | | |
812 | | /*** UAT Callbacks and Helpers ***/ |
813 | | |
814 | | static void |
815 | 135 | set_prefs_changed(void) { |
816 | | /* This ensures that proto_reg_handoff_someip is called, even if SOME/IP is not bound to any port yet. */ |
817 | 135 | if (someip_module) { |
818 | 135 | someip_module->prefs_changed_flags |= (PREF_EFFECT_DISSECTION|PREF_EFFECT_FIELDS); |
819 | 135 | } |
820 | 135 | } |
821 | | |
822 | | static char* |
823 | 0 | check_filter_string(char *filter_string, uint32_t id) { |
824 | 0 | char *err = NULL; |
825 | 0 | unsigned char c; |
826 | |
|
827 | 0 | c = proto_check_field_name(filter_string); |
828 | 0 | if (c) { |
829 | 0 | if (c == '.') { |
830 | 0 | err = ws_strdup_printf("Filter String contains illegal chars '.' (ID: %i )", id); |
831 | 0 | } else if (g_ascii_isprint(c)) { |
832 | 0 | err = ws_strdup_printf("Filter String contains illegal chars '%c' (ID: %i)", c, id); |
833 | 0 | } else { |
834 | 0 | err = ws_strdup_printf("Filter String contains invalid byte \\%03o (ID: %i)", c, id); |
835 | 0 | } |
836 | 0 | } |
837 | |
|
838 | 0 | return err; |
839 | 0 | } |
840 | | |
841 | | /* ID -> Name */ |
842 | | static void * |
843 | 0 | copy_generic_one_id_string_cb(void *n, const void *o, size_t size _U_) { |
844 | 0 | generic_one_id_string_t *new_rec = (generic_one_id_string_t *)n; |
845 | 0 | const generic_one_id_string_t *old_rec = (const generic_one_id_string_t *)o; |
846 | |
|
847 | 0 | new_rec->name = g_strdup(old_rec->name); |
848 | 0 | new_rec->id = old_rec->id; |
849 | 0 | return new_rec; |
850 | 0 | } |
851 | | |
852 | | static bool |
853 | 0 | update_serviceid(void *r, char **err) { |
854 | 0 | generic_one_id_string_t *rec = (generic_one_id_string_t *)r; |
855 | |
|
856 | 0 | if (rec->id == 0xffff) { |
857 | 0 | *err = ws_strdup_printf("Service-ID 0xffff is reserved and cannot be used (ID: %i Name: %s)", rec->id, rec->name); |
858 | 0 | return false; |
859 | 0 | } |
860 | | |
861 | 0 | if (rec->id > 0xffff) { |
862 | 0 | *err = ws_strdup_printf("Service-IDs have to be 16bit (ID: %i Name: %s)", rec->id, rec->name); |
863 | 0 | return false; |
864 | 0 | } |
865 | | |
866 | 0 | if (rec->name == NULL || rec->name[0] == 0) { |
867 | 0 | *err = g_strdup("Name cannot be empty"); |
868 | 0 | return false; |
869 | 0 | } |
870 | | |
871 | 0 | return true; |
872 | 0 | } |
873 | | |
874 | | static void |
875 | 0 | free_generic_one_id_string_cb(void *r) { |
876 | 0 | generic_one_id_string_t *rec = (generic_one_id_string_t *)r; |
877 | | |
878 | | /* freeing result of g_strdup */ |
879 | 0 | g_free(rec->name); |
880 | 0 | rec->name = NULL; |
881 | 0 | } |
882 | | |
883 | | /* ID/ID2 -> Name */ |
884 | | |
885 | | static void * |
886 | 0 | copy_generic_two_id_string_cb(void *n, const void *o, size_t size _U_) { |
887 | 0 | generic_two_id_string_t *new_rec = (generic_two_id_string_t *)n; |
888 | 0 | const generic_two_id_string_t *old_rec = (const generic_two_id_string_t *)o; |
889 | |
|
890 | 0 | new_rec->name = g_strdup(old_rec->name); |
891 | 0 | new_rec->id = old_rec->id; |
892 | 0 | new_rec->id2 = old_rec->id2; |
893 | 0 | return new_rec; |
894 | 0 | } |
895 | | |
896 | | static bool |
897 | 0 | update_two_identifier_16bit_check_both(void *r, char **err) { |
898 | 0 | generic_two_id_string_t *rec = (generic_two_id_string_t *)r; |
899 | |
|
900 | 0 | if (rec->id == 0xffff) { |
901 | 0 | *err = ws_strdup_printf("Service-ID 0xffff is reserved and cannot be used (ID: %i Name: %s)", rec->id, rec->name); |
902 | 0 | return false; |
903 | 0 | } |
904 | | |
905 | 0 | if (rec->id > 0xffff) { |
906 | 0 | *err = ws_strdup_printf("Service-IDs have to be 16bit (ID: %i Name: %s)", rec->id, rec->name); |
907 | 0 | return false; |
908 | 0 | } |
909 | | |
910 | 0 | if (rec->id2 == 0xffff) { |
911 | 0 | *err = ws_strdup_printf("0xffff is reserved and cannot be used (ID: %i ID2: %i Name: %s)", rec->id, rec->id2, rec->name); |
912 | 0 | return false; |
913 | 0 | } |
914 | | |
915 | 0 | if (rec->id2 > 0xffff) { |
916 | 0 | *err = ws_strdup_printf("We currently only support 16 bit identifiers (ID: %i ID2: %i Name: %s)", rec->id, rec->id2, rec->name); |
917 | 0 | return false; |
918 | 0 | } |
919 | | |
920 | 0 | if (rec->name == NULL || rec->name[0] == 0) { |
921 | 0 | *err = g_strdup("Name cannot be empty"); |
922 | 0 | return false; |
923 | 0 | } |
924 | | |
925 | 0 | return true; |
926 | 0 | } |
927 | | |
928 | | static bool |
929 | 0 | update_generic_two_identifier_16bit(void *r, char **err) { |
930 | 0 | generic_two_id_string_t *rec = (generic_two_id_string_t *)r; |
931 | |
|
932 | 0 | if (rec->id > 0xffff) { |
933 | 0 | *err = ws_strdup_printf("We currently only support 16 bit identifiers (ID: %i Name: %s)", rec->id, rec->name); |
934 | 0 | return false; |
935 | 0 | } |
936 | | |
937 | 0 | if (rec->id2 > 0xffff) { |
938 | 0 | *err = ws_strdup_printf("We currently only support 16 bit identifiers (ID: %i ID2: %i Name: %s)", rec->id, rec->id2, rec->name); |
939 | 0 | return false; |
940 | 0 | } |
941 | | |
942 | 0 | if (rec->name == NULL || rec->name[0] == 0) { |
943 | 0 | *err = g_strdup("Name cannot be empty"); |
944 | 0 | return false; |
945 | 0 | } |
946 | | |
947 | 0 | return true; |
948 | 0 | } |
949 | | |
950 | | static void |
951 | 0 | free_generic_two_id_string_cb(void *r) { |
952 | 0 | generic_two_id_string_t *rec = (generic_two_id_string_t *)r; |
953 | | |
954 | | /* freeing result of g_strdup */ |
955 | 0 | g_free(rec->name); |
956 | 0 | rec->name = NULL; |
957 | 0 | } |
958 | | |
959 | | char * |
960 | 0 | someip_lookup_service_name(uint16_t serviceid) { |
961 | 0 | if (data_someip_services == NULL) { |
962 | 0 | return NULL; |
963 | 0 | } |
964 | | |
965 | 0 | return g_hash_table_lookup(data_someip_services, GUINT_TO_POINTER(serviceid)); |
966 | 0 | } |
967 | | |
968 | | static char * |
969 | 0 | someip_lookup_method_name(uint16_t serviceid, uint16_t methodid) { |
970 | 0 | if (data_someip_methods == NULL) { |
971 | 0 | return NULL; |
972 | 0 | } |
973 | | |
974 | 0 | return (char *)g_hash_table_lookup(data_someip_methods, GUINT_TO_POINTER(((uint32_t)serviceid << 16) | (uint32_t)methodid)); |
975 | 0 | } |
976 | | |
977 | | char * |
978 | 0 | someip_lookup_eventgroup_name(uint16_t serviceid, uint16_t eventgroupid) { |
979 | 0 | if (data_someip_eventgroups == NULL) { |
980 | 0 | return NULL; |
981 | 0 | } |
982 | | |
983 | 0 | return g_hash_table_lookup(data_someip_eventgroups, GUINT_TO_POINTER(((uint32_t)serviceid << 16) | (uint32_t)eventgroupid)); |
984 | 0 | } |
985 | | |
986 | | static char * |
987 | 0 | someip_lookup_client_name(uint16_t serviceid, uint16_t clientid) { |
988 | 0 | if (data_someip_clients == NULL) { |
989 | 0 | return NULL; |
990 | 0 | } |
991 | | |
992 | 0 | return (char *)g_hash_table_lookup(data_someip_clients, GUINT_TO_POINTER(((uint32_t)serviceid << 16) | (uint32_t)clientid)); |
993 | 0 | } |
994 | | |
995 | | /*** SOME/IP Services ***/ |
996 | 0 | UAT_HEX_CB_DEF (someip_service_ident, id, generic_one_id_string_t) Unexecuted instantiation: packet-someip.c:someip_service_ident_id_set_cb Unexecuted instantiation: packet-someip.c:someip_service_ident_id_tostr_cb |
997 | 0 | UAT_CSTRING_CB_DEF (someip_service_ident, name, generic_one_id_string_t) |
998 | | |
999 | | static void |
1000 | 15 | reset_someip_service_cb(void) { |
1001 | | /* destroy old hash table, if it exists */ |
1002 | 15 | if (data_someip_services) { |
1003 | 0 | g_hash_table_destroy(data_someip_services); |
1004 | 0 | data_someip_services = NULL; |
1005 | 0 | } |
1006 | 15 | } |
1007 | | |
1008 | | static void |
1009 | 15 | post_update_someip_service_cb(void) { |
1010 | 15 | reset_someip_service_cb(); |
1011 | | |
1012 | | /* create new hash table */ |
1013 | 15 | data_someip_services = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); |
1014 | | |
1015 | 15 | for (unsigned i = 0; i < someip_service_ident_num; i++) { |
1016 | 0 | g_hash_table_insert(data_someip_services, GUINT_TO_POINTER(someip_service_ident[i].id), someip_service_ident[i].name); |
1017 | 0 | } |
1018 | 15 | } |
1019 | | |
1020 | | |
1021 | | /*** SOME/IP Methods/Events/Fields ***/ |
1022 | 0 | UAT_HEX_CB_DEF (someip_method_ident, id, generic_two_id_string_t) Unexecuted instantiation: packet-someip.c:someip_method_ident_id_set_cb Unexecuted instantiation: packet-someip.c:someip_method_ident_id_tostr_cb |
1023 | 0 | UAT_HEX_CB_DEF (someip_method_ident, id2, generic_two_id_string_t) Unexecuted instantiation: packet-someip.c:someip_method_ident_id2_set_cb Unexecuted instantiation: packet-someip.c:someip_method_ident_id2_tostr_cb |
1024 | 0 | UAT_CSTRING_CB_DEF (someip_method_ident, name, generic_two_id_string_t) |
1025 | | |
1026 | | static void |
1027 | 15 | reset_someip_method_cb(void) { |
1028 | | /* destroy old hash table, if it exists */ |
1029 | 15 | if (data_someip_methods) { |
1030 | 0 | g_hash_table_destroy(data_someip_methods); |
1031 | 0 | data_someip_methods = NULL; |
1032 | 0 | } |
1033 | 15 | } |
1034 | | |
1035 | | static void |
1036 | 15 | post_update_someip_method_cb(void) { |
1037 | 15 | reset_someip_method_cb(); |
1038 | | |
1039 | | /* create new hash table */ |
1040 | 15 | data_someip_methods = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); |
1041 | | |
1042 | 15 | for (unsigned i = 0; i < someip_method_ident_num; i++) { |
1043 | 0 | uint32_t key = (((uint32_t)someip_method_ident[i].id & 0xffff) << 16) | ((uint32_t)someip_method_ident[i].id2 & 0xffff); |
1044 | 0 | g_hash_table_insert(data_someip_methods, GUINT_TO_POINTER(key), someip_method_ident[i].name); |
1045 | 0 | } |
1046 | 15 | } |
1047 | | |
1048 | | |
1049 | | /*** SOME/IP Eventgroups ***/ |
1050 | 0 | UAT_HEX_CB_DEF (someip_eventgroup_ident, id, generic_two_id_string_t) Unexecuted instantiation: packet-someip.c:someip_eventgroup_ident_id_set_cb Unexecuted instantiation: packet-someip.c:someip_eventgroup_ident_id_tostr_cb |
1051 | 0 | UAT_HEX_CB_DEF (someip_eventgroup_ident, id2, generic_two_id_string_t) Unexecuted instantiation: packet-someip.c:someip_eventgroup_ident_id2_set_cb Unexecuted instantiation: packet-someip.c:someip_eventgroup_ident_id2_tostr_cb |
1052 | 0 | UAT_CSTRING_CB_DEF (someip_eventgroup_ident, name, generic_two_id_string_t) |
1053 | | |
1054 | | static void |
1055 | 15 | reset_someip_eventgroup_cb(void) { |
1056 | | /* destroy old hash table, if it exists */ |
1057 | 15 | if (data_someip_eventgroups) { |
1058 | 0 | g_hash_table_destroy(data_someip_eventgroups); |
1059 | 0 | data_someip_eventgroups = NULL; |
1060 | 0 | } |
1061 | 15 | } |
1062 | | |
1063 | | static void |
1064 | 15 | post_update_someip_eventgroup_cb(void) { |
1065 | 15 | reset_someip_eventgroup_cb(); |
1066 | | |
1067 | | /* create new hash table */ |
1068 | 15 | data_someip_eventgroups = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); |
1069 | | |
1070 | 15 | for (unsigned i = 0; i < someip_eventgroup_ident_num; i++) { |
1071 | 0 | uint32_t key = (((uint32_t)someip_eventgroup_ident[i].id & 0xffff) << 16) | ((uint32_t)someip_eventgroup_ident[i].id2 & 0xffff); |
1072 | 0 | g_hash_table_insert(data_someip_eventgroups, GUINT_TO_POINTER(key), someip_eventgroup_ident[i].name); |
1073 | 0 | } |
1074 | 15 | } |
1075 | | |
1076 | | |
1077 | | /*** SOME/IP Clients ***/ |
1078 | 0 | UAT_HEX_CB_DEF(someip_client_ident, id, generic_two_id_string_t) Unexecuted instantiation: packet-someip.c:someip_client_ident_id_set_cb Unexecuted instantiation: packet-someip.c:someip_client_ident_id_tostr_cb |
1079 | 0 | UAT_HEX_CB_DEF(someip_client_ident, id2, generic_two_id_string_t) Unexecuted instantiation: packet-someip.c:someip_client_ident_id2_set_cb Unexecuted instantiation: packet-someip.c:someip_client_ident_id2_tostr_cb |
1080 | 0 | UAT_CSTRING_CB_DEF(someip_client_ident, name, generic_two_id_string_t) |
1081 | | |
1082 | | static void |
1083 | 15 | reset_someip_client_cb(void) { |
1084 | | /* destroy old hash table, if it exists */ |
1085 | 15 | if (data_someip_clients) { |
1086 | 0 | g_hash_table_destroy(data_someip_clients); |
1087 | 0 | data_someip_clients = NULL; |
1088 | 0 | } |
1089 | 15 | } |
1090 | | |
1091 | | static void |
1092 | 15 | post_update_someip_client_cb(void) { |
1093 | 15 | reset_someip_client_cb(); |
1094 | | |
1095 | | /* create new hash table */ |
1096 | 15 | data_someip_clients = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); |
1097 | | |
1098 | 15 | for (unsigned i = 0; i < someip_client_ident_num; i++) { |
1099 | 0 | uint32_t key = (((uint32_t)someip_client_ident[i].id & 0xffff) << 16) | ((uint32_t)someip_client_ident[i].id2 & 0xffff); |
1100 | 0 | g_hash_table_insert(data_someip_clients, GUINT_TO_POINTER(key), someip_client_ident[i].name); |
1101 | 0 | } |
1102 | 15 | } |
1103 | | |
1104 | | static uint64_t |
1105 | 0 | someip_parameter_key(uint16_t serviceid, uint16_t methodid, uint8_t version, uint8_t msgtype) { |
1106 | | /* key: |
1107 | | Service-ID [16bit] | Method-ID [16bit] | Version [8bit] | Message-Type [8bit] |
1108 | | */ |
1109 | |
|
1110 | 0 | return ((uint64_t)serviceid & 0xffff) | (((uint64_t)methodid & 0xffff) << 16) | (((uint64_t)version & 0xff) << 32) | (((uint64_t)msgtype & 0xff) << 40); |
1111 | 0 | } |
1112 | | |
1113 | | static someip_parameter_list_t* |
1114 | 0 | get_parameter_config(uint16_t serviceid, uint16_t methodid, uint8_t version, uint8_t msgtype) { |
1115 | 0 | if (data_someip_parameter_list == NULL) { |
1116 | 0 | return NULL; |
1117 | 0 | } |
1118 | | |
1119 | 0 | uint64_t key = someip_parameter_key(serviceid, methodid, version, msgtype); |
1120 | 0 | return (someip_parameter_list_t *)g_hash_table_lookup(data_someip_parameter_list, &key); |
1121 | 0 | } |
1122 | | |
1123 | | static void * |
1124 | 0 | get_generic_config(GHashTable *ht, void *id) { |
1125 | 0 | if (ht == NULL) { |
1126 | 0 | return NULL; |
1127 | 0 | } |
1128 | | |
1129 | 0 | return (void *)g_hash_table_lookup(ht, id); |
1130 | 0 | } |
1131 | | |
1132 | | static someip_parameter_base_type_list_t* |
1133 | 0 | get_base_type_config(uint32_t id) { |
1134 | 0 | return (someip_parameter_base_type_list_t *)get_generic_config(data_someip_parameter_base_type_list, GUINT_TO_POINTER(id)); |
1135 | 0 | } |
1136 | | |
1137 | | static someip_parameter_string_t* |
1138 | 0 | get_string_config(uint32_t id) { |
1139 | 0 | return (someip_parameter_string_t *)get_generic_config(data_someip_parameter_strings, GUINT_TO_POINTER(id)); |
1140 | 0 | } |
1141 | | |
1142 | | static someip_parameter_array_t* |
1143 | 0 | get_array_config(uint32_t id) { |
1144 | 0 | return (someip_parameter_array_t *)get_generic_config(data_someip_parameter_arrays, GUINT_TO_POINTER(id)); |
1145 | 0 | } |
1146 | | |
1147 | | static someip_parameter_struct_t* |
1148 | 0 | get_struct_config(uint32_t id) { |
1149 | 0 | return (someip_parameter_struct_t *)get_generic_config(data_someip_parameter_structs, GUINT_TO_POINTER(id)); |
1150 | 0 | } |
1151 | | |
1152 | | static someip_parameter_union_t* |
1153 | 0 | get_union_config(uint32_t id) { |
1154 | 0 | return (someip_parameter_union_t *)get_generic_config(data_someip_parameter_unions, GUINT_TO_POINTER(id)); |
1155 | 0 | } |
1156 | | |
1157 | | static someip_parameter_typedef_t* |
1158 | 0 | get_typedef_config(uint32_t id) { |
1159 | 0 | return (someip_parameter_typedef_t *)get_generic_config(data_someip_parameter_typedefs, GUINT_TO_POINTER(id)); |
1160 | 0 | } |
1161 | | |
1162 | | static someip_parameter_enum_t* |
1163 | 0 | get_enum_config(uint32_t id) { |
1164 | 0 | return (someip_parameter_enum_t *)get_generic_config(data_someip_parameter_enums, GUINT_TO_POINTER(id)); |
1165 | 0 | } |
1166 | | |
1167 | | static someip_parameter_bitfield_t* |
1168 | 0 | get_bitfield_config(uint32_t id) { |
1169 | 0 | return (someip_parameter_bitfield_t *)get_generic_config(data_someip_parameter_bitfields, GUINT_TO_POINTER(id)); |
1170 | 0 | } |
1171 | | |
1172 | | /*** Parameter List ***/ |
1173 | 0 | UAT_HEX_CB_DEF(someip_parameter_list, service_id, someip_parameter_list_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_list_service_id_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_list_service_id_tostr_cb |
1174 | 0 | UAT_HEX_CB_DEF(someip_parameter_list, method_id, someip_parameter_list_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_list_method_id_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_list_method_id_tostr_cb |
1175 | 0 | UAT_DEC_CB_DEF(someip_parameter_list, version, someip_parameter_list_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_list_version_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_list_version_tostr_cb |
1176 | 0 | UAT_HEX_CB_DEF(someip_parameter_list, message_type, someip_parameter_list_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_list_message_type_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_list_message_type_tostr_cb |
1177 | 0 | UAT_BOOL_CB_DEF(someip_parameter_list, wtlv_encoding, someip_parameter_list_uat_t) |
1178 | | |
1179 | 0 | UAT_DEC_CB_DEF(someip_parameter_list, num_of_params, someip_parameter_list_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_list_num_of_params_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_list_num_of_params_tostr_cb |
1180 | | |
1181 | 0 | UAT_DEC_CB_DEF(someip_parameter_list, pos, someip_parameter_list_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_list_pos_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_list_pos_tostr_cb |
1182 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_list, name, someip_parameter_list_uat_t) |
1183 | 0 | UAT_DEC_CB_DEF(someip_parameter_list, data_type, someip_parameter_list_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_list_data_type_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_list_data_type_tostr_cb |
1184 | 0 | UAT_HEX_CB_DEF(someip_parameter_list, id_ref, someip_parameter_list_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_list_id_ref_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_list_id_ref_tostr_cb |
1185 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_list, filter_string, someip_parameter_list_uat_t) |
1186 | | |
1187 | | static void * |
1188 | 0 | copy_someip_parameter_list_cb(void *n, const void *o, size_t size _U_) { |
1189 | 0 | someip_parameter_list_uat_t *new_rec = (someip_parameter_list_uat_t *)n; |
1190 | 0 | const someip_parameter_list_uat_t *old_rec = (const someip_parameter_list_uat_t *)o; |
1191 | |
|
1192 | 0 | if (old_rec->name) { |
1193 | 0 | new_rec->name = g_strdup(old_rec->name); |
1194 | 0 | } else { |
1195 | 0 | new_rec->name = NULL; |
1196 | 0 | } |
1197 | |
|
1198 | 0 | if (old_rec->filter_string) { |
1199 | 0 | new_rec->filter_string = g_strdup(old_rec->filter_string); |
1200 | 0 | } else { |
1201 | 0 | new_rec->filter_string = NULL; |
1202 | 0 | } |
1203 | |
|
1204 | 0 | new_rec->service_id = old_rec->service_id; |
1205 | 0 | new_rec->method_id = old_rec->method_id; |
1206 | 0 | new_rec->version = old_rec->version; |
1207 | 0 | new_rec->message_type = old_rec->message_type; |
1208 | 0 | new_rec->wtlv_encoding = old_rec->wtlv_encoding; |
1209 | 0 | new_rec->num_of_params = old_rec->num_of_params; |
1210 | 0 | new_rec->pos = old_rec->pos; |
1211 | 0 | new_rec->data_type = old_rec->data_type; |
1212 | 0 | new_rec->id_ref = old_rec->id_ref; |
1213 | |
|
1214 | 0 | return new_rec; |
1215 | 0 | } |
1216 | | |
1217 | | static bool |
1218 | 0 | update_someip_parameter_list(void *r, char **err) { |
1219 | 0 | someip_parameter_list_uat_t *rec = (someip_parameter_list_uat_t *)r; |
1220 | 0 | unsigned char c; |
1221 | |
|
1222 | 0 | if (rec->service_id > 0xffff) { |
1223 | 0 | *err = ws_strdup_printf("We currently only support 16 bit Service IDs (Service-ID: %i Name: %s)", rec->service_id, rec->name); |
1224 | 0 | return false; |
1225 | 0 | } |
1226 | | |
1227 | 0 | if (rec->method_id > 0xffff) { |
1228 | 0 | *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); |
1229 | 0 | return false; |
1230 | 0 | } |
1231 | | |
1232 | 0 | if (rec->version > 0xff) { |
1233 | 0 | *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); |
1234 | 0 | return false; |
1235 | 0 | } |
1236 | | |
1237 | 0 | if (rec->message_type > 0xff) { |
1238 | 0 | *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); |
1239 | 0 | return false; |
1240 | 0 | } |
1241 | | |
1242 | 0 | if (rec->name == NULL || rec->name[0] == 0) { |
1243 | 0 | *err = ws_strdup_printf("Name cannot be empty"); |
1244 | 0 | return false; |
1245 | 0 | } |
1246 | | |
1247 | 0 | if (rec->pos >= rec->num_of_params) { |
1248 | 0 | *err = ws_strdup_printf("Position >= Number of Parameters"); |
1249 | 0 | return false; |
1250 | 0 | } |
1251 | | |
1252 | 0 | if (rec->data_type < SOMEIP_PARAMETER_DATA_TYPE_MIN || rec->data_type > SOMEIP_PARAMETER_DATA_TYPE_MAX) { |
1253 | 0 | *err = ws_strdup_printf("Data Type can be only in range %d .. %d!", SOMEIP_PARAMETER_DATA_TYPE_MIN, SOMEIP_PARAMETER_DATA_TYPE_MAX); |
1254 | 0 | return false; |
1255 | 0 | } |
1256 | | |
1257 | 0 | if (rec->filter_string == NULL || rec->filter_string[0] == 0) { |
1258 | 0 | *err = ws_strdup_printf("Name cannot be empty"); |
1259 | 0 | return false; |
1260 | 0 | } |
1261 | | |
1262 | 0 | c = proto_check_field_name(rec->filter_string); |
1263 | 0 | if (c) { |
1264 | 0 | if (c == '.') { |
1265 | 0 | *err = ws_strdup_printf("Filter String contains illegal chars '.' (Service-ID: %i Method-ID: %i)", rec->service_id, rec->method_id); |
1266 | 0 | } else if (g_ascii_isprint(c)) { |
1267 | 0 | *err = ws_strdup_printf("Filter String contains illegal chars '%c' (Service-ID: %i Method-ID: %i)", c, rec->service_id, rec->method_id); |
1268 | 0 | } else { |
1269 | 0 | *err = ws_strdup_printf("Filter String contains invalid byte \\%03o (Service-ID: %i Method-ID: %i)", c, rec->service_id, rec->method_id); |
1270 | 0 | } |
1271 | 0 | return false; |
1272 | 0 | } |
1273 | | |
1274 | 0 | return true; |
1275 | 0 | } |
1276 | | |
1277 | | static void |
1278 | 0 | free_someip_parameter_list_cb(void *r) { |
1279 | 0 | someip_parameter_list_uat_t *rec = (someip_parameter_list_uat_t *)r; |
1280 | |
|
1281 | 0 | if (rec->name) { |
1282 | 0 | g_free(rec->name); |
1283 | 0 | rec->name = NULL; |
1284 | 0 | } |
1285 | |
|
1286 | 0 | if (rec->filter_string) { |
1287 | 0 | g_free(rec->filter_string); |
1288 | 0 | rec->filter_string = NULL; |
1289 | 0 | } |
1290 | 0 | } |
1291 | | |
1292 | | static void |
1293 | 0 | free_someip_parameter_list(void *data) { |
1294 | 0 | someip_parameter_list_t *list = (someip_parameter_list_t *)data; |
1295 | |
|
1296 | 0 | if (list->items != NULL) { |
1297 | 0 | wmem_free(wmem_epan_scope(), (void *)(list->items)); |
1298 | 0 | list->items = NULL; |
1299 | 0 | } |
1300 | |
|
1301 | 0 | wmem_free(wmem_epan_scope(), (void *)data); |
1302 | 0 | } |
1303 | | |
1304 | | static void |
1305 | 60 | post_update_someip_parameter_list_read_in_data(someip_parameter_list_uat_t *data, unsigned data_num, GHashTable *ht) { |
1306 | 60 | if (ht == NULL || data == NULL) { |
1307 | 60 | return; |
1308 | 60 | } |
1309 | | |
1310 | 0 | for (unsigned i = 0; i < data_num; i++) { |
1311 | 0 | uint64_t 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); |
1312 | 0 | someip_parameter_list_t *list = g_hash_table_lookup(ht, &key); |
1313 | 0 | if (list == NULL) { |
1314 | 0 | list = wmem_new(wmem_epan_scope(), someip_parameter_list_t); |
1315 | |
|
1316 | 0 | list->service_id = data[i].service_id; |
1317 | 0 | list->method_id = data[i].method_id; |
1318 | 0 | list->version = data[i].version; |
1319 | 0 | list->message_type = data[i].message_type; |
1320 | 0 | list->wtlv_encoding = data[i].wtlv_encoding; |
1321 | 0 | list->num_of_items = data[i].num_of_params; |
1322 | 0 | list->items = wmem_alloc0_array(wmem_epan_scope(), someip_parameter_item_t, data[i].num_of_params); |
1323 | | |
1324 | | /* create new entry ... */ |
1325 | 0 | uint64_t *new_key = g_new(uint64_t, 1); |
1326 | 0 | *new_key = key; |
1327 | 0 | g_hash_table_insert(ht, new_key, list); |
1328 | 0 | } |
1329 | | |
1330 | | /* and now we add to item array */ |
1331 | 0 | if (data[i].num_of_params == list->num_of_items && data[i].pos < list->num_of_items) { |
1332 | 0 | someip_parameter_item_t *item = &(list->items[data[i].pos]); |
1333 | | |
1334 | | /* we do not care if we overwrite param */ |
1335 | 0 | item->name = data[i].name; |
1336 | 0 | item->id_ref = data[i].id_ref; |
1337 | 0 | item->pos = data[i].pos; |
1338 | 0 | item->data_type = data[i].data_type; |
1339 | 0 | item->filter_string = data[i].filter_string; |
1340 | 0 | } |
1341 | 0 | } |
1342 | 0 | } |
1343 | | |
1344 | | |
1345 | | /*** Parameter Base Types (ID: 1) ***/ |
1346 | 0 | UAT_HEX_CB_DEF(someip_parameter_base_type_list, id, someip_parameter_base_type_list_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_base_type_list_id_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_base_type_list_id_tostr_cb |
1347 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_base_type_list, name, someip_parameter_base_type_list_uat_t) |
1348 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_base_type_list, data_type, someip_parameter_base_type_list_uat_t) |
1349 | 0 | UAT_BOOL_CB_DEF(someip_parameter_base_type_list, big_endian, someip_parameter_base_type_list_uat_t) |
1350 | 0 | UAT_DEC_CB_DEF(someip_parameter_base_type_list, bitlength_base_type, someip_parameter_base_type_list_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_base_type_list_bitlength_base_type_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_base_type_list_bitlength_base_type_tostr_cb |
1351 | 0 | UAT_DEC_CB_DEF(someip_parameter_base_type_list, bitlength_encoded_type, someip_parameter_base_type_list_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_base_type_list_bitlength_encoded_type_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_base_type_list_bitlength_encoded_type_tostr_cb |
1352 | | |
1353 | | static void * |
1354 | 0 | copy_someip_parameter_base_type_list_cb(void *n, const void *o, size_t size _U_) { |
1355 | 0 | someip_parameter_base_type_list_uat_t *new_rec = (someip_parameter_base_type_list_uat_t *)n; |
1356 | 0 | const someip_parameter_base_type_list_uat_t *old_rec = (const someip_parameter_base_type_list_uat_t *)o; |
1357 | |
|
1358 | 0 | if (old_rec->name) { |
1359 | 0 | new_rec->name = g_strdup(old_rec->name); |
1360 | 0 | } else { |
1361 | 0 | new_rec->name = NULL; |
1362 | 0 | } |
1363 | |
|
1364 | 0 | if (old_rec->data_type) { |
1365 | 0 | new_rec->data_type = g_strdup(old_rec->data_type); |
1366 | 0 | } else { |
1367 | 0 | new_rec->data_type = NULL; |
1368 | 0 | } |
1369 | |
|
1370 | 0 | new_rec->id = old_rec->id; |
1371 | 0 | new_rec->big_endian = old_rec->big_endian; |
1372 | 0 | new_rec->bitlength_base_type = old_rec->bitlength_base_type; |
1373 | 0 | new_rec->bitlength_encoded_type = old_rec->bitlength_encoded_type; |
1374 | |
|
1375 | 0 | return new_rec; |
1376 | 0 | } |
1377 | | |
1378 | | static bool |
1379 | 0 | update_someip_parameter_base_type_list(void *r, char **err) { |
1380 | 0 | someip_parameter_base_type_list_uat_t *rec = (someip_parameter_base_type_list_uat_t *)r; |
1381 | |
|
1382 | 0 | if (rec->name == NULL || rec->name[0] == 0) { |
1383 | 0 | *err = ws_strdup_printf("Name cannot be empty (ID: 0x%x)!", rec->id); |
1384 | 0 | return false; |
1385 | 0 | } |
1386 | | |
1387 | 0 | if (rec->data_type == NULL || rec->data_type[0] == 0) { |
1388 | 0 | *err = ws_strdup_printf("Data Type cannot be empty (ID: 0x%x)!", rec->id); |
1389 | 0 | return false; |
1390 | 0 | } |
1391 | | |
1392 | | /* now check data_types and length in detail */ |
1393 | 0 | if (strncmp(rec->data_type, "uint", 4) == 0) { |
1394 | 0 | if (strncmp(rec->data_type, "uint8", 5) == 0) { |
1395 | 0 | if (rec->bitlength_base_type != 8 || rec->bitlength_encoded_type != 8) { |
1396 | 0 | *err = ws_strdup_printf("Data Type uint8 must have length 8 and 8 (ID: 0x%x)!", rec->id); |
1397 | 0 | return false; |
1398 | 0 | } |
1399 | 0 | } else if (strncmp(rec->data_type, "uint16", 6) == 0) { |
1400 | 0 | if (rec->bitlength_base_type != 16 || rec->bitlength_encoded_type != 16) { |
1401 | 0 | *err = ws_strdup_printf("Data Type uint16 must have length 16 and 16 (ID: 0x%x)!", rec->id); |
1402 | 0 | return false; |
1403 | 0 | } |
1404 | 0 | } else if (strncmp(rec->data_type, "uint32", 6) == 0) { |
1405 | 0 | if (rec->bitlength_base_type != 32 || rec->bitlength_encoded_type != 32) { |
1406 | 0 | *err = ws_strdup_printf("Data Type uint32 must have length 32 and 32 (ID: 0x%x)!", rec->id); |
1407 | 0 | return false; |
1408 | 0 | } |
1409 | 0 | } else if (strncmp(rec->data_type, "uint64", 6) == 0) { |
1410 | 0 | if (rec->bitlength_base_type != 64 || rec->bitlength_encoded_type != 64) { |
1411 | 0 | *err = ws_strdup_printf("Data Type uint64 must have length 64 and 64 (ID: 0x%x)!", rec->id); |
1412 | 0 | return false; |
1413 | 0 | } |
1414 | 0 | } else { |
1415 | 0 | *err = ws_strdup_printf("Data Type uint can be 8, 16, 32, or 64 bit (ID: 0x%x)!", rec->id); |
1416 | 0 | return false; |
1417 | 0 | } |
1418 | 0 | } else if (strncmp(rec->data_type, "int", 3) == 0) { |
1419 | 0 | if (strncmp(rec->data_type, "int8", 4) == 0) { |
1420 | 0 | if (rec->bitlength_base_type != 8 || rec->bitlength_encoded_type != 8) { |
1421 | 0 | *err = ws_strdup_printf("Data Type int8 must have length 8 and 8 (ID: 0x%x)!", rec->id); |
1422 | 0 | return false; |
1423 | 0 | } |
1424 | 0 | } else if (strncmp(rec->data_type, "int16", 5) == 0) { |
1425 | 0 | if (rec->bitlength_base_type != 16 || rec->bitlength_encoded_type != 16) { |
1426 | 0 | *err = ws_strdup_printf("Data Type int16 must have length 16 and 16 (ID: 0x%x)!", rec->id); |
1427 | 0 | return false; |
1428 | 0 | } |
1429 | 0 | } else if (strncmp(rec->data_type, "int32", 5) == 0) { |
1430 | 0 | if (rec->bitlength_base_type != 32 || rec->bitlength_encoded_type != 32) { |
1431 | 0 | *err = ws_strdup_printf("Data Type int32 must have length 32 and 32 (ID: 0x%x)!", rec->id); |
1432 | 0 | return false; |
1433 | 0 | } |
1434 | 0 | } else if (strncmp(rec->data_type, "int64", 5) == 0) { |
1435 | 0 | if (rec->bitlength_base_type != 64 || rec->bitlength_encoded_type != 64) { |
1436 | 0 | *err = ws_strdup_printf("Data Type int64 must have length 64 and 64 (ID: 0x%x)!", rec->id); |
1437 | 0 | return false; |
1438 | 0 | } |
1439 | 0 | } else { |
1440 | 0 | *err = ws_strdup_printf("Data Type int can be 8, 16, 32, or 64 bit (ID: 0x%x)!", rec->id); |
1441 | 0 | return false; |
1442 | 0 | } |
1443 | 0 | } else if (strncmp(rec->data_type, "float", 5) == 0) { |
1444 | 0 | if (strncmp(rec->data_type, "float32", 7) == 0) { |
1445 | 0 | if (rec->bitlength_base_type != 32 || rec->bitlength_encoded_type != 32) { |
1446 | 0 | *err = ws_strdup_printf("Data Type float32 must have length 32 and 32 (ID: 0x%x)!", rec->id); |
1447 | 0 | return false; |
1448 | 0 | } |
1449 | 0 | } else if (strncmp(rec->data_type, "float64", 7) == 0) { |
1450 | 0 | if (rec->bitlength_base_type != 64 || rec->bitlength_encoded_type != 64) { |
1451 | 0 | *err = ws_strdup_printf("Data Type float64 must have length 64 and 64 (ID: 0x%x)!", rec->id); |
1452 | 0 | return false; |
1453 | 0 | } |
1454 | 0 | } |
1455 | 0 | } else { |
1456 | 0 | *err = ws_strdup_printf("Data Type only supports uint8/uint16/uin32/uint64, int8/int16/int32/int64, and float32/float64 (ID: 0x%x)!", rec->id); |
1457 | 0 | return false; |
1458 | 0 | } |
1459 | | |
1460 | 0 | if (rec->id > 0xffffffff) { |
1461 | 0 | *err = ws_strdup_printf("We currently only support 32 bit IDs (%i) Name: %s", rec->id, rec->name); |
1462 | 0 | return false; |
1463 | 0 | } |
1464 | | |
1465 | 0 | return true; |
1466 | 0 | } |
1467 | | |
1468 | | static void |
1469 | 0 | free_someip_parameter_base_type_list_cb(void *r) { |
1470 | 0 | someip_parameter_base_type_list_uat_t *rec = (someip_parameter_base_type_list_uat_t *)r; |
1471 | |
|
1472 | 0 | if (rec->name) { |
1473 | 0 | g_free(rec->name); |
1474 | 0 | rec->name = NULL; |
1475 | 0 | } |
1476 | |
|
1477 | 0 | if (rec->data_type) { |
1478 | 0 | g_free(rec->data_type); |
1479 | 0 | rec->data_type = NULL; |
1480 | 0 | } |
1481 | 0 | } |
1482 | | |
1483 | | static void |
1484 | 15 | reset_someip_parameter_base_type_list_cb(void) { |
1485 | | /* destroy old hash table, if it exists */ |
1486 | 15 | if (data_someip_parameter_base_type_list) { |
1487 | 0 | g_hash_table_destroy(data_someip_parameter_base_type_list); |
1488 | 0 | data_someip_parameter_base_type_list = NULL; |
1489 | 0 | } |
1490 | | |
1491 | 15 | set_prefs_changed(); |
1492 | 15 | } |
1493 | | |
1494 | | static void |
1495 | 15 | post_update_someip_parameter_base_type_list_cb(void) { |
1496 | 15 | unsigned i; |
1497 | | |
1498 | 15 | reset_someip_parameter_base_type_list_cb(); |
1499 | | |
1500 | | /* we don't need to free the data as long as we don't alloc it first */ |
1501 | 15 | data_someip_parameter_base_type_list = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); |
1502 | | |
1503 | 15 | for (i = 0; i < someip_parameter_base_type_list_num; i++) { |
1504 | 0 | g_hash_table_insert(data_someip_parameter_base_type_list, GUINT_TO_POINTER(someip_parameter_base_type_list[i].id), &someip_parameter_base_type_list[i]); |
1505 | 0 | } |
1506 | 15 | } |
1507 | | |
1508 | | |
1509 | | /*** Parameter Strings (ID: 2) ***/ |
1510 | 0 | UAT_HEX_CB_DEF(someip_parameter_strings, id, someip_parameter_string_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_strings_id_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_strings_id_tostr_cb |
1511 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_strings, name, someip_parameter_string_uat_t) |
1512 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_strings, encoding, someip_parameter_string_uat_t) |
1513 | 0 | UAT_BOOL_CB_DEF(someip_parameter_strings, dynamic_length, someip_parameter_string_uat_t) |
1514 | 0 | UAT_DEC_CB_DEF(someip_parameter_strings, max_length, someip_parameter_string_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_strings_max_length_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_strings_max_length_tostr_cb |
1515 | 0 | UAT_DEC_CB_DEF(someip_parameter_strings, length_of_length, someip_parameter_string_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_strings_length_of_length_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_strings_length_of_length_tostr_cb |
1516 | 0 | UAT_BOOL_CB_DEF(someip_parameter_strings, big_endian, someip_parameter_string_uat_t) |
1517 | 0 | UAT_DEC_CB_DEF(someip_parameter_strings, pad_to, someip_parameter_string_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_strings_pad_to_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_strings_pad_to_tostr_cb |
1518 | | |
1519 | | static void * |
1520 | 0 | copy_someip_parameter_string_list_cb(void *n, const void *o, size_t size _U_) { |
1521 | 0 | someip_parameter_string_uat_t *new_rec = (someip_parameter_string_uat_t *)n; |
1522 | 0 | const someip_parameter_string_uat_t *old_rec = (const someip_parameter_string_uat_t *)o; |
1523 | |
|
1524 | 0 | if (old_rec->name) { |
1525 | 0 | new_rec->name = g_strdup(old_rec->name); |
1526 | 0 | } else { |
1527 | 0 | new_rec->name = NULL; |
1528 | 0 | } |
1529 | |
|
1530 | 0 | if (old_rec->encoding) { |
1531 | 0 | new_rec->encoding = g_strdup(old_rec->encoding); |
1532 | 0 | } else { |
1533 | 0 | new_rec->encoding = NULL; |
1534 | 0 | } |
1535 | |
|
1536 | 0 | new_rec->id = old_rec->id; |
1537 | 0 | new_rec->dynamic_length = old_rec->dynamic_length; |
1538 | 0 | new_rec->max_length = old_rec->max_length; |
1539 | 0 | new_rec->length_of_length = old_rec->length_of_length; |
1540 | 0 | new_rec->big_endian = old_rec->big_endian; |
1541 | 0 | new_rec->pad_to = old_rec->pad_to; |
1542 | |
|
1543 | 0 | return new_rec; |
1544 | 0 | } |
1545 | | |
1546 | | static bool |
1547 | 0 | update_someip_parameter_string_list(void *r, char **err) { |
1548 | 0 | someip_parameter_string_uat_t *rec = (someip_parameter_string_uat_t *)r; |
1549 | |
|
1550 | 0 | if (rec->name == NULL || rec->name[0] == 0) { |
1551 | 0 | *err = ws_strdup_printf("Name cannot be empty (ID: 0x%x)!", rec->id); |
1552 | 0 | return false; |
1553 | 0 | } |
1554 | | |
1555 | 0 | if (rec->id > 0xffffffff) { |
1556 | 0 | *err = ws_strdup_printf("We currently only support 32 bit IDs (%i) Name: %s", rec->id, rec->name); |
1557 | 0 | return false; |
1558 | 0 | } |
1559 | | |
1560 | 0 | if (rec->max_length > 0xffffffff) { |
1561 | 0 | *err = ws_strdup_printf("We currently only support 32 bit max_length (%i) Name: %s", rec->max_length, rec->name); |
1562 | 0 | return false; |
1563 | 0 | } |
1564 | | |
1565 | 0 | if (rec->length_of_length != 0 && rec->length_of_length != 8 && rec->length_of_length != 16 && rec->length_of_length != 32) { |
1566 | 0 | *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); |
1567 | 0 | return false; |
1568 | 0 | } |
1569 | | |
1570 | 0 | return true; |
1571 | 0 | } |
1572 | | |
1573 | | static void |
1574 | 0 | free_someip_parameter_string_list_cb(void *r) { |
1575 | 0 | someip_parameter_string_uat_t *rec = (someip_parameter_string_uat_t *)r; |
1576 | |
|
1577 | 0 | if (rec->name) { |
1578 | 0 | g_free(rec->name); |
1579 | 0 | rec->name = NULL; |
1580 | 0 | } |
1581 | |
|
1582 | 0 | if (rec->encoding) { |
1583 | 0 | g_free(rec->encoding); |
1584 | 0 | rec->encoding = NULL; |
1585 | 0 | } |
1586 | 0 | } |
1587 | | |
1588 | | static void |
1589 | 15 | reset_someip_parameter_string_list_cb(void) { |
1590 | | /* destroy old hash table, if it exists */ |
1591 | 15 | if (data_someip_parameter_strings) { |
1592 | 0 | g_hash_table_destroy(data_someip_parameter_strings); |
1593 | 0 | data_someip_parameter_strings = NULL; |
1594 | 0 | } |
1595 | | |
1596 | 15 | set_prefs_changed(); |
1597 | 15 | } |
1598 | | |
1599 | | static void |
1600 | 15 | post_update_someip_parameter_string_list_cb(void) { |
1601 | 15 | unsigned i; |
1602 | | |
1603 | 15 | reset_someip_parameter_string_list_cb(); |
1604 | | |
1605 | | /* we don't need to free the data as long as we don't alloc it first */ |
1606 | 15 | data_someip_parameter_strings = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); |
1607 | | |
1608 | 15 | for (i = 0; i < someip_parameter_strings_num; i++) { |
1609 | 0 | g_hash_table_insert(data_someip_parameter_strings, GUINT_TO_POINTER(someip_parameter_strings[i].id), &someip_parameter_strings[i]); |
1610 | 0 | } |
1611 | 15 | } |
1612 | | |
1613 | | |
1614 | | /*** Parameter Arrays (ID: 3) ***/ |
1615 | 0 | UAT_HEX_CB_DEF(someip_parameter_arrays, id, someip_parameter_array_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_id_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_id_tostr_cb |
1616 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_arrays, name, someip_parameter_array_uat_t) |
1617 | 0 | UAT_DEC_CB_DEF(someip_parameter_arrays, data_type, someip_parameter_array_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_data_type_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_data_type_tostr_cb |
1618 | 0 | UAT_HEX_CB_DEF(someip_parameter_arrays, id_ref, someip_parameter_array_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_id_ref_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_id_ref_tostr_cb |
1619 | 0 | UAT_DEC_CB_DEF(someip_parameter_arrays, num_of_dims, someip_parameter_array_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_num_of_dims_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_num_of_dims_tostr_cb |
1620 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_arrays, filter_string, someip_parameter_array_uat_t) |
1621 | | |
1622 | 0 | UAT_DEC_CB_DEF(someip_parameter_arrays, num, someip_parameter_array_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_num_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_num_tostr_cb |
1623 | 0 | UAT_DEC_CB_DEF(someip_parameter_arrays, lower_limit, someip_parameter_array_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_lower_limit_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_lower_limit_tostr_cb |
1624 | 0 | UAT_DEC_CB_DEF(someip_parameter_arrays, upper_limit, someip_parameter_array_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_upper_limit_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_upper_limit_tostr_cb |
1625 | 0 | UAT_DEC_CB_DEF(someip_parameter_arrays, length_of_length, someip_parameter_array_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_length_of_length_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_length_of_length_tostr_cb |
1626 | 0 | UAT_DEC_CB_DEF(someip_parameter_arrays, pad_to, someip_parameter_array_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_pad_to_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_arrays_pad_to_tostr_cb |
1627 | | |
1628 | | static void * |
1629 | 0 | copy_someip_parameter_array_cb(void *n, const void *o, size_t size _U_) { |
1630 | 0 | someip_parameter_array_uat_t *new_rec = (someip_parameter_array_uat_t *)n; |
1631 | 0 | const someip_parameter_array_uat_t *old_rec = (const someip_parameter_array_uat_t *)o; |
1632 | |
|
1633 | 0 | new_rec->id = old_rec->id; |
1634 | 0 | if (old_rec->name) { |
1635 | 0 | new_rec->name = g_strdup(old_rec->name); |
1636 | 0 | } else { |
1637 | 0 | new_rec->name = NULL; |
1638 | 0 | } |
1639 | 0 | new_rec->data_type = old_rec->data_type; |
1640 | 0 | new_rec->id_ref = old_rec->id_ref; |
1641 | 0 | new_rec->num_of_dims = old_rec->num_of_dims; |
1642 | 0 | if (old_rec->filter_string) { |
1643 | 0 | new_rec->filter_string = g_strdup(old_rec->filter_string); |
1644 | 0 | } else { |
1645 | 0 | new_rec->filter_string = NULL; |
1646 | 0 | } |
1647 | |
|
1648 | 0 | new_rec->num = old_rec->num; |
1649 | 0 | new_rec->lower_limit = old_rec->lower_limit; |
1650 | 0 | new_rec->upper_limit = old_rec->upper_limit; |
1651 | 0 | new_rec->length_of_length = old_rec->length_of_length; |
1652 | 0 | new_rec->pad_to = old_rec->pad_to; |
1653 | |
|
1654 | 0 | return new_rec; |
1655 | 0 | } |
1656 | | |
1657 | | static bool |
1658 | 0 | update_someip_parameter_array(void *r, char **err) { |
1659 | 0 | someip_parameter_array_uat_t *rec = (someip_parameter_array_uat_t *)r; |
1660 | 0 | char *tmp; |
1661 | |
|
1662 | 0 | if (rec->name == NULL || rec->name[0] == 0) { |
1663 | 0 | *err = ws_strdup_printf("Name cannot be empty (ID: 0x%x)!", rec->id); |
1664 | 0 | return false; |
1665 | 0 | } |
1666 | | |
1667 | 0 | if (rec->num >= rec->num_of_dims) { |
1668 | 0 | *err = ws_strdup_printf("Dimension >= Number of Dimensions (ID: 0x%x)!", rec->id); |
1669 | 0 | return false; |
1670 | 0 | } |
1671 | | |
1672 | 0 | if (rec->filter_string == NULL || rec->filter_string[0] == 0) { |
1673 | 0 | *err = ws_strdup_printf("Filter String cannot be empty (ID: 0x%x)!", rec->id); |
1674 | 0 | return false; |
1675 | 0 | } |
1676 | | |
1677 | 0 | tmp = check_filter_string(rec->filter_string, rec->id); |
1678 | 0 | if (tmp != NULL) { |
1679 | 0 | *err = tmp; |
1680 | 0 | return false; |
1681 | 0 | } |
1682 | | |
1683 | 0 | if (rec->data_type < SOMEIP_PARAMETER_DATA_TYPE_MIN || rec->data_type > SOMEIP_PARAMETER_DATA_TYPE_MAX) { |
1684 | 0 | *err = ws_strdup_printf("Data Type can be only in range %d .. %d!", SOMEIP_PARAMETER_DATA_TYPE_MIN, SOMEIP_PARAMETER_DATA_TYPE_MAX); |
1685 | 0 | return false; |
1686 | 0 | } |
1687 | | |
1688 | 0 | if (rec->data_type == SOMEIP_PARAMETER_DATA_TYPE_ARRAY && rec->id == rec->id_ref) { |
1689 | 0 | *err = ws_strdup_printf("An array cannot include itself (ID: 0x%x)!", rec->id); |
1690 | 0 | return false; |
1691 | 0 | } |
1692 | | |
1693 | 0 | return true; |
1694 | 0 | } |
1695 | | |
1696 | | static void |
1697 | 0 | free_someip_parameter_array_cb(void *r) { |
1698 | 0 | someip_parameter_array_uat_t *rec = (someip_parameter_array_uat_t *)r; |
1699 | |
|
1700 | 0 | if (rec->name) g_free(rec->name); |
1701 | 0 | rec->name = NULL; |
1702 | |
|
1703 | 0 | if (rec->filter_string) g_free(rec->filter_string); |
1704 | 0 | rec->filter_string = NULL; |
1705 | 0 | } |
1706 | | |
1707 | | static void |
1708 | 0 | free_someip_parameter_array(void *data) { |
1709 | 0 | someip_parameter_array_t *list = (someip_parameter_array_t *)data; |
1710 | |
|
1711 | 0 | if (list->dims != NULL) { |
1712 | 0 | wmem_free(wmem_epan_scope(), (void *)(list->dims)); |
1713 | 0 | list->dims = NULL; |
1714 | 0 | } |
1715 | |
|
1716 | 0 | wmem_free(wmem_epan_scope(), (void *)data); |
1717 | 0 | } |
1718 | | |
1719 | | static void |
1720 | 60 | post_update_someip_parameter_array_read_in_data(someip_parameter_array_uat_t *data, unsigned data_num, GHashTable *ht) { |
1721 | 60 | unsigned i; |
1722 | 60 | someip_parameter_array_t *list; |
1723 | 60 | someip_parameter_array_dim_t *item; |
1724 | | |
1725 | 60 | if (ht == NULL || data == NULL) { |
1726 | 60 | return; |
1727 | 60 | } |
1728 | | |
1729 | 0 | for (i = 0; i < data_num; i++) { |
1730 | 0 | list = g_hash_table_lookup(ht, GUINT_TO_POINTER(data[i].id)); |
1731 | 0 | if (list == NULL) { |
1732 | 0 | list = wmem_new(wmem_epan_scope(), someip_parameter_array_t); |
1733 | |
|
1734 | 0 | list->id = data[i].id; |
1735 | 0 | list->name = data[i].name; |
1736 | 0 | list->data_type = data[i].data_type; |
1737 | 0 | list->id_ref = data[i].id_ref; |
1738 | 0 | list->num_of_dims = data[i].num_of_dims; |
1739 | 0 | list->filter_string = data[i].filter_string; |
1740 | 0 | list->dims = wmem_alloc0_array(wmem_epan_scope(), someip_parameter_array_dim_t, data[i].num_of_dims); |
1741 | | |
1742 | | /* create new entry ... */ |
1743 | 0 | g_hash_table_insert(ht, GUINT_TO_POINTER(data[i].id), list); |
1744 | 0 | } |
1745 | | |
1746 | | /* and now we add to item array */ |
1747 | 0 | if (data[i].num_of_dims == list->num_of_dims && data[i].num < list->num_of_dims) { |
1748 | 0 | item = &(list->dims[data[i].num]); |
1749 | | |
1750 | | /* we do not care if we overwrite param */ |
1751 | 0 | item->num = data[i].num; |
1752 | 0 | item->lower_limit = data[i].lower_limit; |
1753 | 0 | item->upper_limit = data[i].upper_limit; |
1754 | 0 | item->length_of_length = data[i].length_of_length; |
1755 | 0 | item->pad_to = data[i].pad_to; |
1756 | 0 | } |
1757 | 0 | } |
1758 | 0 | } |
1759 | | |
1760 | | |
1761 | | /*** Parameter Structs (ID: 4) ***/ |
1762 | 0 | UAT_HEX_CB_DEF(someip_parameter_structs, id, someip_parameter_struct_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_structs_id_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_structs_id_tostr_cb |
1763 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_structs, struct_name, someip_parameter_struct_uat_t) |
1764 | 0 | UAT_DEC_CB_DEF(someip_parameter_structs, length_of_length, someip_parameter_struct_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_structs_length_of_length_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_structs_length_of_length_tostr_cb |
1765 | 0 | UAT_DEC_CB_DEF(someip_parameter_structs, pad_to, someip_parameter_struct_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_structs_pad_to_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_structs_pad_to_tostr_cb |
1766 | 0 | UAT_BOOL_CB_DEF(someip_parameter_structs, wtlv_encoding, someip_parameter_struct_uat_t) |
1767 | 0 | UAT_DEC_CB_DEF(someip_parameter_structs, num_of_items, someip_parameter_struct_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_structs_num_of_items_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_structs_num_of_items_tostr_cb |
1768 | | |
1769 | 0 | UAT_DEC_CB_DEF(someip_parameter_structs, pos, someip_parameter_struct_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_structs_pos_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_structs_pos_tostr_cb |
1770 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_structs, name, someip_parameter_struct_uat_t) |
1771 | 0 | UAT_DEC_CB_DEF(someip_parameter_structs, data_type, someip_parameter_struct_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_structs_data_type_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_structs_data_type_tostr_cb |
1772 | 0 | UAT_HEX_CB_DEF(someip_parameter_structs, id_ref, someip_parameter_struct_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_structs_id_ref_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_structs_id_ref_tostr_cb |
1773 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_structs, filter_string, someip_parameter_struct_uat_t) |
1774 | | |
1775 | | static void * |
1776 | 0 | copy_someip_parameter_struct_cb(void *n, const void *o, size_t size _U_) { |
1777 | 0 | someip_parameter_struct_uat_t *new_rec = (someip_parameter_struct_uat_t *)n; |
1778 | 0 | const someip_parameter_struct_uat_t *old_rec = (const someip_parameter_struct_uat_t *)o; |
1779 | |
|
1780 | 0 | new_rec->id = old_rec->id; |
1781 | |
|
1782 | 0 | if (old_rec->struct_name) { |
1783 | 0 | new_rec->struct_name = g_strdup(old_rec->struct_name); |
1784 | 0 | } else { |
1785 | 0 | new_rec->struct_name = NULL; |
1786 | 0 | } |
1787 | |
|
1788 | 0 | new_rec->length_of_length = old_rec->length_of_length; |
1789 | 0 | new_rec->pad_to = old_rec->pad_to; |
1790 | 0 | new_rec->wtlv_encoding = old_rec->wtlv_encoding; |
1791 | 0 | new_rec->num_of_items = old_rec->num_of_items; |
1792 | |
|
1793 | 0 | new_rec->pos = old_rec->pos; |
1794 | |
|
1795 | 0 | if (old_rec->name) { |
1796 | 0 | new_rec->name = g_strdup(old_rec->name); |
1797 | 0 | } else { |
1798 | 0 | new_rec->name = NULL; |
1799 | 0 | } |
1800 | |
|
1801 | 0 | new_rec->data_type = old_rec->data_type; |
1802 | 0 | new_rec->id_ref = old_rec->id_ref; |
1803 | |
|
1804 | 0 | if (old_rec->filter_string) { |
1805 | 0 | new_rec->filter_string = g_strdup(old_rec->filter_string); |
1806 | 0 | } else { |
1807 | 0 | new_rec->filter_string = NULL; |
1808 | 0 | } |
1809 | |
|
1810 | 0 | return new_rec; |
1811 | 0 | } |
1812 | | |
1813 | | static bool |
1814 | 0 | update_someip_parameter_struct(void *r, char **err) { |
1815 | 0 | someip_parameter_struct_uat_t *rec = (someip_parameter_struct_uat_t *)r; |
1816 | 0 | char *tmp = NULL; |
1817 | |
|
1818 | 0 | if (rec->struct_name == NULL || rec->struct_name[0] == 0) { |
1819 | 0 | *err = ws_strdup_printf("Struct name cannot be empty (ID: 0x%x)!", rec->id); |
1820 | 0 | return false; |
1821 | 0 | } |
1822 | | |
1823 | 0 | if (rec->filter_string == NULL || rec->filter_string[0] == 0) { |
1824 | 0 | *err = ws_strdup_printf("Struct name cannot be empty (ID: 0x%x)!", rec->id); |
1825 | 0 | return false; |
1826 | 0 | } |
1827 | | |
1828 | 0 | tmp = check_filter_string(rec->filter_string, rec->id); |
1829 | 0 | if (tmp != NULL) { |
1830 | 0 | *err = tmp; |
1831 | 0 | return false; |
1832 | 0 | } |
1833 | | |
1834 | 0 | if (rec->name == NULL || rec->name[0] == 0) { |
1835 | 0 | *err = ws_strdup_printf("Name cannot be empty (ID: 0x%x)!", rec->id); |
1836 | 0 | return false; |
1837 | 0 | } |
1838 | | |
1839 | 0 | if (rec->pos >= rec->num_of_items) { |
1840 | 0 | *err = ws_strdup_printf("Position >= Number of Parameters (ID: 0x%x)!", rec->id); |
1841 | 0 | return false; |
1842 | 0 | } |
1843 | | |
1844 | 0 | if (rec->data_type < SOMEIP_PARAMETER_DATA_TYPE_MIN || rec->data_type > SOMEIP_PARAMETER_DATA_TYPE_MAX) { |
1845 | 0 | *err = ws_strdup_printf("Data Type can be only in range %d .. %d!", SOMEIP_PARAMETER_DATA_TYPE_MIN, SOMEIP_PARAMETER_DATA_TYPE_MAX); |
1846 | 0 | return false; |
1847 | 0 | } |
1848 | | |
1849 | 0 | if (rec->data_type == SOMEIP_PARAMETER_DATA_TYPE_STRUCT && rec->id == rec->id_ref) { |
1850 | 0 | *err = ws_strdup_printf("A struct cannot include itself (ID: 0x%x)!", rec->id); |
1851 | 0 | return false; |
1852 | 0 | } |
1853 | | |
1854 | 0 | return true; |
1855 | 0 | } |
1856 | | |
1857 | | static void |
1858 | 0 | free_someip_parameter_struct_cb(void *r) { |
1859 | 0 | someip_parameter_struct_uat_t *rec = (someip_parameter_struct_uat_t *)r; |
1860 | |
|
1861 | 0 | if (rec->struct_name) g_free(rec->struct_name); |
1862 | 0 | rec->struct_name = NULL; |
1863 | |
|
1864 | 0 | if (rec->name) g_free(rec->name); |
1865 | 0 | rec->name = NULL; |
1866 | |
|
1867 | 0 | if (rec->filter_string) g_free(rec->filter_string); |
1868 | 0 | rec->filter_string = NULL; |
1869 | 0 | } |
1870 | | |
1871 | | static void |
1872 | 0 | free_someip_parameter_struct(void *data) { |
1873 | 0 | someip_parameter_struct_t *list = (someip_parameter_struct_t *)data; |
1874 | |
|
1875 | 0 | if (list->items != NULL) { |
1876 | 0 | wmem_free(wmem_epan_scope(), (void *)(list->items)); |
1877 | 0 | list->items = NULL; |
1878 | 0 | } |
1879 | |
|
1880 | 0 | wmem_free(wmem_epan_scope(), (void *)data); |
1881 | 0 | } |
1882 | | |
1883 | | static void |
1884 | 60 | post_update_someip_parameter_struct_read_in_data(someip_parameter_struct_uat_t *data, unsigned data_num, GHashTable *ht) { |
1885 | 60 | unsigned i; |
1886 | 60 | someip_parameter_struct_t *list; |
1887 | 60 | someip_parameter_item_t *item; |
1888 | | |
1889 | 60 | if (ht == NULL || data == NULL) { |
1890 | 60 | return; |
1891 | 60 | } |
1892 | | |
1893 | 0 | for (i = 0; i < data_num; i++) { |
1894 | 0 | list = g_hash_table_lookup(ht, GUINT_TO_POINTER(data[i].id)); |
1895 | 0 | if (list == NULL) { |
1896 | 0 | list = wmem_new(wmem_epan_scope(), someip_parameter_struct_t); |
1897 | 0 | INIT_SOMEIP_PARAMETER_STRUCT(list) |
1898 | |
|
1899 | 0 | list->id = data[i].id; |
1900 | 0 | list->struct_name = data[i].struct_name; |
1901 | 0 | list->length_of_length = data[i].length_of_length; |
1902 | 0 | list->pad_to = data[i].pad_to; |
1903 | 0 | list->wtlv_encoding = data[i].wtlv_encoding; |
1904 | 0 | list->num_of_items = data[i].num_of_items; |
1905 | 0 | list->items = wmem_alloc0_array(wmem_epan_scope(), someip_parameter_item_t, data[i].num_of_items); |
1906 | | |
1907 | | /* create new entry ... */ |
1908 | 0 | g_hash_table_insert(ht, GUINT_TO_POINTER(data[i].id), list); |
1909 | 0 | } |
1910 | | |
1911 | | /* and now we add to item array */ |
1912 | 0 | if (data[i].num_of_items == list->num_of_items && data[i].pos < list->num_of_items) { |
1913 | 0 | item = &(list->items[data[i].pos]); |
1914 | 0 | INIT_SOMEIP_PARAMETER_ITEM(item) |
1915 | | |
1916 | | /* we do not care if we overwrite param */ |
1917 | 0 | item->name = data[i].name; |
1918 | 0 | item->id_ref = data[i].id_ref; |
1919 | 0 | item->pos = data[i].pos; |
1920 | 0 | item->data_type = data[i].data_type; |
1921 | 0 | item->filter_string = data[i].filter_string; |
1922 | 0 | } |
1923 | 0 | } |
1924 | 0 | } |
1925 | | |
1926 | | |
1927 | | /*** Parameter Unions (ID: 5) ***/ |
1928 | 0 | UAT_HEX_CB_DEF(someip_parameter_unions, id, someip_parameter_union_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_unions_id_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_unions_id_tostr_cb |
1929 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_unions, name, someip_parameter_union_uat_t) |
1930 | 0 | UAT_DEC_CB_DEF(someip_parameter_unions, length_of_length, someip_parameter_union_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_unions_length_of_length_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_unions_length_of_length_tostr_cb |
1931 | 0 | UAT_DEC_CB_DEF(someip_parameter_unions, length_of_type, someip_parameter_union_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_unions_length_of_type_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_unions_length_of_type_tostr_cb |
1932 | 0 | UAT_DEC_CB_DEF(someip_parameter_unions, pad_to, someip_parameter_union_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_unions_pad_to_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_unions_pad_to_tostr_cb |
1933 | | |
1934 | 0 | UAT_DEC_CB_DEF(someip_parameter_unions, num_of_items, someip_parameter_union_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_unions_num_of_items_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_unions_num_of_items_tostr_cb |
1935 | | |
1936 | 0 | UAT_DEC_CB_DEF(someip_parameter_unions, type_id, someip_parameter_union_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_unions_type_id_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_unions_type_id_tostr_cb |
1937 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_unions, type_name, someip_parameter_union_uat_t) |
1938 | 0 | UAT_DEC_CB_DEF(someip_parameter_unions, data_type, someip_parameter_union_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_unions_data_type_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_unions_data_type_tostr_cb |
1939 | 0 | UAT_HEX_CB_DEF(someip_parameter_unions, id_ref, someip_parameter_union_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_unions_id_ref_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_unions_id_ref_tostr_cb |
1940 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_unions, filter_string, someip_parameter_union_uat_t) |
1941 | | |
1942 | | static void * |
1943 | 0 | copy_someip_parameter_union_cb(void *n, const void *o, size_t size _U_) { |
1944 | 0 | someip_parameter_union_uat_t *new_rec = (someip_parameter_union_uat_t *)n; |
1945 | 0 | const someip_parameter_union_uat_t *old_rec = (const someip_parameter_union_uat_t *)o; |
1946 | |
|
1947 | 0 | new_rec->id = old_rec->id; |
1948 | |
|
1949 | 0 | if (old_rec->name) { |
1950 | 0 | new_rec->name = g_strdup(old_rec->name); |
1951 | 0 | } else { |
1952 | 0 | new_rec->name = NULL; |
1953 | 0 | } |
1954 | |
|
1955 | 0 | new_rec->length_of_length = old_rec->length_of_length; |
1956 | 0 | new_rec->length_of_type = old_rec->length_of_type; |
1957 | 0 | new_rec->pad_to = old_rec->pad_to; |
1958 | 0 | new_rec->num_of_items = old_rec->num_of_items; |
1959 | 0 | new_rec->type_id = old_rec->type_id; |
1960 | |
|
1961 | 0 | if (old_rec->type_name) { |
1962 | 0 | new_rec->type_name = g_strdup(old_rec->type_name); |
1963 | 0 | } else { |
1964 | 0 | new_rec->type_name = NULL; |
1965 | 0 | } |
1966 | |
|
1967 | 0 | new_rec->data_type = old_rec->data_type; |
1968 | 0 | new_rec->id_ref = old_rec->id_ref; |
1969 | |
|
1970 | 0 | if (old_rec->filter_string) { |
1971 | 0 | new_rec->filter_string = g_strdup(old_rec->filter_string); |
1972 | 0 | } else { |
1973 | 0 | new_rec->filter_string = NULL; |
1974 | 0 | } |
1975 | |
|
1976 | 0 | return new_rec; |
1977 | 0 | } |
1978 | | |
1979 | | static bool |
1980 | 0 | update_someip_parameter_union(void *r, char **err) { |
1981 | 0 | someip_parameter_union_uat_t *rec = (someip_parameter_union_uat_t *)r; |
1982 | 0 | char *tmp; |
1983 | |
|
1984 | 0 | if (rec->name == NULL || rec->name[0] == 0) { |
1985 | 0 | *err = ws_strdup_printf("Union name cannot be empty (ID: 0x%x)!", rec->id); |
1986 | 0 | return false; |
1987 | 0 | } |
1988 | | |
1989 | 0 | tmp = check_filter_string(rec->filter_string, rec->id); |
1990 | 0 | if (tmp != NULL) { |
1991 | 0 | *err = tmp; |
1992 | 0 | return false; |
1993 | 0 | } |
1994 | | |
1995 | 0 | if (rec->type_name == NULL || rec->type_name[0] == 0) { |
1996 | 0 | *err = ws_strdup_printf("Type Name cannot be empty (ID: 0x%x)!", rec->id); |
1997 | 0 | return false; |
1998 | 0 | } |
1999 | | |
2000 | 0 | if (rec->data_type < SOMEIP_PARAMETER_DATA_TYPE_MIN || rec->data_type > SOMEIP_PARAMETER_DATA_TYPE_MAX) { |
2001 | 0 | *err = ws_strdup_printf("Data Type can be only in range %d .. %d!", SOMEIP_PARAMETER_DATA_TYPE_MIN, SOMEIP_PARAMETER_DATA_TYPE_MAX); |
2002 | 0 | return false; |
2003 | 0 | } |
2004 | | |
2005 | 0 | if (rec->data_type == SOMEIP_PARAMETER_DATA_TYPE_UNION && rec->id == rec->id_ref) { |
2006 | 0 | *err = ws_strdup_printf("A union cannot include itself (ID: 0x%x)!", rec->id); |
2007 | 0 | return false; |
2008 | 0 | } |
2009 | | |
2010 | 0 | return true; |
2011 | 0 | } |
2012 | | |
2013 | | static void |
2014 | 0 | free_someip_parameter_union_cb(void *r) { |
2015 | 0 | someip_parameter_union_uat_t *rec = (someip_parameter_union_uat_t *)r; |
2016 | |
|
2017 | 0 | if (rec->name) { |
2018 | 0 | g_free(rec->name); |
2019 | 0 | rec->name = NULL; |
2020 | 0 | } |
2021 | |
|
2022 | 0 | if (rec->type_name) { |
2023 | 0 | g_free(rec->type_name); |
2024 | 0 | rec->type_name = NULL; |
2025 | 0 | } |
2026 | |
|
2027 | 0 | if (rec->filter_string) { |
2028 | 0 | g_free(rec->filter_string); |
2029 | 0 | rec->filter_string = NULL; |
2030 | 0 | } |
2031 | 0 | } |
2032 | | |
2033 | | static void |
2034 | 0 | free_someip_parameter_union(void *data) { |
2035 | 0 | someip_parameter_union_t *list = (someip_parameter_union_t *)data; |
2036 | |
|
2037 | 0 | if (list->items != NULL) { |
2038 | 0 | wmem_free(wmem_epan_scope(), (void *)(list->items)); |
2039 | 0 | list->items = NULL; |
2040 | 0 | } |
2041 | |
|
2042 | 0 | wmem_free(wmem_epan_scope(), (void *)data); |
2043 | 0 | } |
2044 | | |
2045 | | static void |
2046 | 60 | post_update_someip_parameter_union_read_in_data(someip_parameter_union_uat_t *data, unsigned data_num, GHashTable *ht) { |
2047 | 60 | unsigned i; |
2048 | 60 | unsigned j; |
2049 | 60 | someip_parameter_union_t *list; |
2050 | 60 | someip_parameter_union_item_t *item; |
2051 | | |
2052 | 60 | if (ht == NULL || data == NULL) { |
2053 | 60 | return; |
2054 | 60 | } |
2055 | | |
2056 | 0 | for (i = 0; i < data_num; i++) { |
2057 | 0 | list = g_hash_table_lookup(ht, GUINT_TO_POINTER(data[i].id)); |
2058 | 0 | if (list == NULL) { |
2059 | 0 | list = wmem_new(wmem_epan_scope(), someip_parameter_union_t); |
2060 | |
|
2061 | 0 | list->id = data[i].id; |
2062 | 0 | list->name = data[i].name; |
2063 | 0 | list->length_of_length = data[i].length_of_length; |
2064 | 0 | list->length_of_type = data[i].length_of_type; |
2065 | 0 | list->pad_to = data[i].pad_to; |
2066 | 0 | list->num_of_items = data[i].num_of_items; |
2067 | 0 | list->items = wmem_alloc0_array(wmem_epan_scope(), someip_parameter_union_item_t, list->num_of_items); |
2068 | | |
2069 | | /* create new entry ... */ |
2070 | 0 | g_hash_table_insert(ht, GUINT_TO_POINTER(data[i].id), list); |
2071 | 0 | } |
2072 | | |
2073 | | /* and now we add to item array */ |
2074 | 0 | if (data[i].num_of_items == list->num_of_items) { |
2075 | | |
2076 | | /* find first empty slot */ |
2077 | 0 | for (j = 0; j < list->num_of_items && list->items[j].name != NULL; j++); |
2078 | |
|
2079 | 0 | if (j < list->num_of_items) { |
2080 | 0 | item = &(list->items[j]); |
2081 | | |
2082 | | /* we do not care if we overwrite param */ |
2083 | 0 | item->id = data[i].type_id; |
2084 | 0 | item->name = data[i].type_name; |
2085 | 0 | item->data_type = data[i].data_type; |
2086 | 0 | item->id_ref = data[i].id_ref; |
2087 | 0 | item->filter_string = data[i].filter_string; |
2088 | 0 | } |
2089 | 0 | } |
2090 | 0 | } |
2091 | 0 | } |
2092 | | |
2093 | | |
2094 | | /*** Parameter Typedef (ID: 6) ***/ |
2095 | 0 | UAT_HEX_CB_DEF(someip_parameter_typedefs, id, someip_parameter_typedef_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_typedefs_id_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_typedefs_id_tostr_cb |
2096 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_typedefs, name, someip_parameter_typedef_uat_t) |
2097 | 0 | UAT_DEC_CB_DEF(someip_parameter_typedefs, data_type, someip_parameter_typedef_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_typedefs_data_type_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_typedefs_data_type_tostr_cb |
2098 | 0 | UAT_HEX_CB_DEF(someip_parameter_typedefs, id_ref, someip_parameter_typedef_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_typedefs_id_ref_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_typedefs_id_ref_tostr_cb |
2099 | | |
2100 | | static void * |
2101 | 0 | copy_someip_parameter_typedef_list_cb(void *n, const void *o, size_t size _U_) { |
2102 | 0 | someip_parameter_typedef_uat_t *new_rec = (someip_parameter_typedef_uat_t *)n; |
2103 | 0 | const someip_parameter_typedef_uat_t *old_rec = (const someip_parameter_typedef_uat_t *)o; |
2104 | |
|
2105 | 0 | if (old_rec->name) { |
2106 | 0 | new_rec->name = g_strdup(old_rec->name); |
2107 | 0 | } else { |
2108 | 0 | new_rec->name = NULL; |
2109 | 0 | } |
2110 | |
|
2111 | 0 | new_rec->id = old_rec->id; |
2112 | 0 | new_rec->data_type = old_rec->data_type; |
2113 | 0 | new_rec->id_ref = old_rec->id_ref; |
2114 | |
|
2115 | 0 | return new_rec; |
2116 | 0 | } |
2117 | | |
2118 | | static bool |
2119 | 0 | update_someip_parameter_typedef_list(void *r, char **err) { |
2120 | 0 | someip_parameter_typedef_uat_t *rec = (someip_parameter_typedef_uat_t *)r; |
2121 | |
|
2122 | 0 | if (rec->id > 0xffffffff) { |
2123 | 0 | *err = ws_strdup_printf("We currently only support 32 bit IDs (%i) Name: %s", rec->id, rec->name); |
2124 | 0 | return false; |
2125 | 0 | } |
2126 | | |
2127 | 0 | if (rec->data_type < SOMEIP_PARAMETER_DATA_TYPE_MIN || rec->data_type > SOMEIP_PARAMETER_DATA_TYPE_MAX) { |
2128 | 0 | *err = ws_strdup_printf("Data Type can be only in range %d .. %d!", SOMEIP_PARAMETER_DATA_TYPE_MIN, SOMEIP_PARAMETER_DATA_TYPE_MAX); |
2129 | 0 | return false; |
2130 | 0 | } |
2131 | | |
2132 | 0 | if (rec->data_type == SOMEIP_PARAMETER_DATA_TYPE_TYPEDEF && rec->id == rec->id_ref) { |
2133 | 0 | *err = ws_strdup_printf("A typedef cannot reference itself (ID: 0x%x)!", rec->id); |
2134 | 0 | return false; |
2135 | 0 | } |
2136 | | |
2137 | 0 | return true; |
2138 | 0 | } |
2139 | | |
2140 | | static void |
2141 | 0 | free_someip_parameter_typedef_list_cb(void *r) { |
2142 | 0 | someip_parameter_typedef_uat_t *rec = (someip_parameter_typedef_uat_t *)r; |
2143 | |
|
2144 | 0 | if (rec->name) { |
2145 | 0 | g_free(rec->name); |
2146 | 0 | rec->name = NULL; |
2147 | 0 | } |
2148 | 0 | } |
2149 | | |
2150 | | static void |
2151 | 15 | reset_someip_parameter_typedef_list_cb(void) { |
2152 | | /* destroy old hash table, if it exists */ |
2153 | 15 | if (data_someip_parameter_typedefs) { |
2154 | 0 | g_hash_table_destroy(data_someip_parameter_typedefs); |
2155 | 0 | data_someip_parameter_typedefs = NULL; |
2156 | 0 | } |
2157 | | |
2158 | 15 | set_prefs_changed(); |
2159 | 15 | } |
2160 | | |
2161 | | static void |
2162 | 15 | post_update_someip_parameter_typedef_list_cb(void) { |
2163 | 15 | unsigned i; |
2164 | | |
2165 | 15 | reset_someip_parameter_typedef_list_cb(); |
2166 | | |
2167 | | /* we don't need to free the data as long as we don't alloc it first */ |
2168 | 15 | data_someip_parameter_typedefs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); |
2169 | | |
2170 | 15 | for (i = 0; i < someip_parameter_typedefs_num; i++) { |
2171 | | /* key: ID [32bit] */ |
2172 | 0 | g_hash_table_insert(data_someip_parameter_typedefs, GUINT_TO_POINTER(someip_parameter_typedefs[i].id), &someip_parameter_typedefs[i]); |
2173 | 0 | } |
2174 | 15 | } |
2175 | | |
2176 | | |
2177 | | /*** Parameter Enums (ID: 7) ***/ |
2178 | 0 | UAT_HEX_CB_DEF(someip_parameter_enums, id, someip_parameter_enum_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_enums_id_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_enums_id_tostr_cb |
2179 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_enums, name, someip_parameter_enum_uat_t) |
2180 | 0 | UAT_DEC_CB_DEF(someip_parameter_enums, data_type, someip_parameter_enum_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_enums_data_type_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_enums_data_type_tostr_cb |
2181 | 0 | UAT_HEX_CB_DEF(someip_parameter_enums, id_ref, someip_parameter_enum_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_enums_id_ref_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_enums_id_ref_tostr_cb |
2182 | 0 | UAT_DEC_CB_DEF(someip_parameter_enums, num_of_items, someip_parameter_enum_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_enums_num_of_items_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_enums_num_of_items_tostr_cb |
2183 | | |
2184 | 0 | UAT_HEX_CB_DEF(someip_parameter_enums, value, someip_parameter_enum_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_enums_value_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_enums_value_tostr_cb |
2185 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_enums, value_name, someip_parameter_enum_uat_t) |
2186 | | |
2187 | | static void * |
2188 | 0 | copy_someip_parameter_enum_cb(void *n, const void *o, size_t size _U_) { |
2189 | 0 | someip_parameter_enum_uat_t *new_rec = (someip_parameter_enum_uat_t *)n; |
2190 | 0 | const someip_parameter_enum_uat_t *old_rec = (const someip_parameter_enum_uat_t *)o; |
2191 | |
|
2192 | 0 | new_rec->id = old_rec->id; |
2193 | 0 | if (old_rec->name) { |
2194 | 0 | new_rec->name = g_strdup(old_rec->name); |
2195 | 0 | } else { |
2196 | 0 | new_rec->name = NULL; |
2197 | 0 | } |
2198 | 0 | new_rec->data_type = old_rec->data_type; |
2199 | 0 | new_rec->id_ref = old_rec->id_ref; |
2200 | 0 | new_rec->num_of_items = old_rec->num_of_items; |
2201 | |
|
2202 | 0 | new_rec->value = old_rec->value; |
2203 | 0 | if (old_rec->value_name) { |
2204 | 0 | new_rec->value_name = g_strdup(old_rec->value_name); |
2205 | 0 | } else { |
2206 | 0 | new_rec->value_name = NULL; |
2207 | 0 | } |
2208 | |
|
2209 | 0 | return new_rec; |
2210 | 0 | } |
2211 | | |
2212 | | static bool |
2213 | 0 | update_someip_parameter_enum(void *r, char **err) { |
2214 | 0 | someip_parameter_enum_uat_t *rec = (someip_parameter_enum_uat_t *)r; |
2215 | | |
2216 | | /* enum name is not used in a filter yet. */ |
2217 | |
|
2218 | 0 | if (rec->name == NULL || rec->name[0] == 0) { |
2219 | 0 | *err = ws_strdup_printf("Name cannot be empty (ID: 0x%x)!", rec->id); |
2220 | 0 | return false; |
2221 | 0 | } |
2222 | | |
2223 | 0 | if (rec->value_name == NULL || rec->value_name[0] == 0) { |
2224 | 0 | *err = ws_strdup_printf("Value Name cannot be empty (ID: 0x%x)!", rec->id); |
2225 | 0 | return false; |
2226 | 0 | } |
2227 | | |
2228 | 0 | if (rec->num_of_items == 0) { |
2229 | 0 | *err = ws_strdup_printf("Number_of_Items = 0 (ID: 0x%x)!", rec->id); |
2230 | 0 | return false; |
2231 | 0 | } |
2232 | | |
2233 | 0 | if (rec->data_type < SOMEIP_PARAMETER_DATA_TYPE_MIN || rec->data_type > SOMEIP_PARAMETER_DATA_TYPE_MAX) { |
2234 | 0 | *err = ws_strdup_printf("Data Type can be only in range %d .. %d!", SOMEIP_PARAMETER_DATA_TYPE_MIN, SOMEIP_PARAMETER_DATA_TYPE_MAX); |
2235 | 0 | return false; |
2236 | 0 | } |
2237 | | |
2238 | 0 | if (rec->data_type == SOMEIP_PARAMETER_DATA_TYPE_ENUM) { |
2239 | 0 | *err = ws_strdup_printf("An enum cannot reference an enum (ID: 0x%x)!", rec->id); |
2240 | 0 | return false; |
2241 | 0 | } |
2242 | | |
2243 | 0 | return true; |
2244 | 0 | } |
2245 | | |
2246 | | static void |
2247 | 0 | free_someip_parameter_enum_cb(void *r) { |
2248 | 0 | someip_parameter_enum_uat_t *rec = (someip_parameter_enum_uat_t *)r; |
2249 | 0 | if (rec->name) { |
2250 | 0 | g_free(rec->name); |
2251 | 0 | rec->name = NULL; |
2252 | 0 | } |
2253 | |
|
2254 | 0 | if (rec->value_name) { |
2255 | 0 | g_free(rec->value_name); |
2256 | 0 | rec->value_name = NULL; |
2257 | 0 | } |
2258 | 0 | } |
2259 | | |
2260 | | static void |
2261 | 0 | free_someip_parameter_enum(void *data) { |
2262 | 0 | someip_parameter_enum_t *list = (someip_parameter_enum_t *)data; |
2263 | |
|
2264 | 0 | if (list->items != NULL) { |
2265 | 0 | wmem_free(wmem_epan_scope(), (void *)(list->items)); |
2266 | 0 | list->items = NULL; |
2267 | 0 | } |
2268 | |
|
2269 | 0 | wmem_free(wmem_epan_scope(), (void *)data); |
2270 | 0 | } |
2271 | | |
2272 | | static void |
2273 | 15 | post_update_someip_parameter_enum_read_in_data(someip_parameter_enum_uat_t *data, unsigned data_num, GHashTable *ht) { |
2274 | 15 | unsigned i; |
2275 | 15 | unsigned j; |
2276 | 15 | someip_parameter_enum_t *list; |
2277 | 15 | someip_parameter_enum_item_t *item; |
2278 | | |
2279 | 15 | if (ht == NULL || data == NULL) { |
2280 | 15 | return; |
2281 | 15 | } |
2282 | | |
2283 | 0 | for (i = 0; i < data_num; i++) { |
2284 | 0 | list = g_hash_table_lookup(ht, GUINT_TO_POINTER(data[i].id)); |
2285 | 0 | if (list == NULL) { |
2286 | 0 | list = wmem_new(wmem_epan_scope(), someip_parameter_enum_t); |
2287 | 0 | INIT_SOMEIP_PAYLOAD_PARAMETER_ENUM(list) |
2288 | |
|
2289 | 0 | list->id = data[i].id; |
2290 | 0 | list->name = data[i].name; |
2291 | 0 | list->data_type = data[i].data_type; |
2292 | 0 | list->id_ref = data[i].id_ref; |
2293 | 0 | list->num_of_items = data[i].num_of_items; |
2294 | 0 | list->items = wmem_alloc0_array(wmem_epan_scope(), someip_parameter_enum_item_t, list->num_of_items); |
2295 | | |
2296 | | /* create new entry ... */ |
2297 | 0 | g_hash_table_insert(ht, GUINT_TO_POINTER(data[i].id), list); |
2298 | 0 | } |
2299 | | |
2300 | | /* and now we add to item array */ |
2301 | 0 | if (list->num_of_items > 0 && data[i].num_of_items == list->num_of_items) { |
2302 | | |
2303 | | /* find first empty slot */ |
2304 | 0 | for (j = 0; j < list->num_of_items && list->items[j].name != NULL; j++); |
2305 | |
|
2306 | 0 | if (j < list->num_of_items) { |
2307 | 0 | item = &(list->items[j]); |
2308 | 0 | INIT_SOMEIP_PARAMETER_ENUM_ITEM(item) |
2309 | | |
2310 | | /* we do not care if we overwrite param */ |
2311 | 0 | item->value = data[i].value; |
2312 | 0 | item->name = data[i].value_name; |
2313 | 0 | } |
2314 | 0 | } |
2315 | 0 | } |
2316 | 0 | } |
2317 | | |
2318 | | static void |
2319 | 15 | reset_someip_parameter_enum_cb(void) { |
2320 | | /* destroy old hash table, if it exists */ |
2321 | 15 | if (data_someip_parameter_enums) { |
2322 | 0 | g_hash_table_destroy(data_someip_parameter_enums); |
2323 | 0 | data_someip_parameter_enums = NULL; |
2324 | 0 | } |
2325 | | |
2326 | 15 | set_prefs_changed(); |
2327 | 15 | } |
2328 | | |
2329 | | static void |
2330 | 15 | post_update_someip_parameter_enum_cb(void) { |
2331 | 15 | reset_someip_parameter_enum_cb(); |
2332 | | |
2333 | 15 | data_someip_parameter_enums = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, &free_someip_parameter_enum); |
2334 | 15 | post_update_someip_parameter_enum_read_in_data(someip_parameter_enums, someip_parameter_enums_num, data_someip_parameter_enums); |
2335 | 15 | } |
2336 | | |
2337 | | |
2338 | | /*** Parameter Bitfields (ID: 8) ***/ |
2339 | 0 | UAT_HEX_CB_DEF(someip_parameter_bitfields, id, someip_parameter_bitfield_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_bitfields_id_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_bitfields_id_tostr_cb |
2340 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_bitfields, name, someip_parameter_bitfield_uat_t) |
2341 | 0 | UAT_DEC_CB_DEF(someip_parameter_bitfields, number_of_bits, someip_parameter_bitfield_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_bitfields_number_of_bits_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_bitfields_number_of_bits_tostr_cb |
2342 | 0 | UAT_DEC_CB_DEF(someip_parameter_bitfields, num_of_items, someip_parameter_bitfield_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_bitfields_num_of_items_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_bitfields_num_of_items_tostr_cb |
2343 | | |
2344 | 0 | UAT_DEC_CB_DEF(someip_parameter_bitfields, bit_number, someip_parameter_bitfield_uat_t) Unexecuted instantiation: packet-someip.c:someip_parameter_bitfields_bit_number_set_cb Unexecuted instantiation: packet-someip.c:someip_parameter_bitfields_bit_number_tostr_cb |
2345 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_bitfields, bit_name, someip_parameter_bitfield_uat_t) |
2346 | 0 | UAT_CSTRING_CB_DEF(someip_parameter_bitfields, filter_string, someip_parameter_bitfield_uat_t) |
2347 | | |
2348 | | static void * |
2349 | 0 | copy_someip_parameter_bitfield_cb(void *n, const void *o, size_t size _U_) { |
2350 | 0 | someip_parameter_bitfield_uat_t *new_rec = (someip_parameter_bitfield_uat_t *)n; |
2351 | 0 | const someip_parameter_bitfield_uat_t *old_rec = (const someip_parameter_bitfield_uat_t *)o; |
2352 | |
|
2353 | 0 | new_rec->id = old_rec->id; |
2354 | 0 | if (old_rec->name) { |
2355 | 0 | new_rec->name = g_strdup(old_rec->name); |
2356 | 0 | } else { |
2357 | 0 | new_rec->name = NULL; |
2358 | 0 | } |
2359 | |
|
2360 | 0 | new_rec->number_of_bits = old_rec->number_of_bits; |
2361 | 0 | new_rec->num_of_items = old_rec->num_of_items; |
2362 | 0 | new_rec->bit_number = old_rec->bit_number; |
2363 | 0 | if (old_rec->bit_name) { |
2364 | 0 | new_rec->bit_name = g_strdup(old_rec->bit_name); |
2365 | 0 | } else { |
2366 | 0 | new_rec->bit_name = NULL; |
2367 | 0 | } |
2368 | 0 | if (old_rec->filter_string) { |
2369 | 0 | new_rec->filter_string = g_strdup(old_rec->filter_string); |
2370 | 0 | } else { |
2371 | 0 | new_rec->filter_string = NULL; |
2372 | 0 | } |
2373 | |
|
2374 | 0 | return new_rec; |
2375 | 0 | } |
2376 | | |
2377 | | static bool |
2378 | 0 | update_someip_parameter_bitfield(void *r, char **err) { |
2379 | 0 | someip_parameter_bitfield_uat_t *rec = (someip_parameter_bitfield_uat_t *)r; |
2380 | |
|
2381 | 0 | if (rec->name == NULL || rec->name[0] == 0) { |
2382 | 0 | *err = ws_strdup_printf("Name cannot be empty (ID: 0x%x)!", rec->id); |
2383 | 0 | return false; |
2384 | 0 | } |
2385 | | |
2386 | 0 | if (rec->number_of_bits != 8 && rec->number_of_bits != 16 && rec->number_of_bits != 32 && rec->number_of_bits != 64) { |
2387 | 0 | *err = ws_strdup_printf("Number of Bits must be 8, 16, 32, 64 (ID: 0x%x)!", rec->id); |
2388 | 0 | return false; |
2389 | 0 | } |
2390 | | |
2391 | 0 | if (rec->num_of_items == 0) { |
2392 | 0 | *err = ws_strdup_printf("Number_of_Items = 0 (ID: 0x%x)!", rec->id); |
2393 | 0 | return false; |
2394 | 0 | } |
2395 | | |
2396 | 0 | if (rec->bit_number >= rec->number_of_bits) { |
2397 | 0 | *err = ws_strdup_printf("Bit Number must be < Number of Bits (ID: 0x%x)!", rec->id); |
2398 | 0 | return false; |
2399 | 0 | } |
2400 | | |
2401 | 0 | if (rec->bit_name == NULL || rec->bit_name[0] == 0) { |
2402 | 0 | *err = ws_strdup_printf("Bit Name cannot be empty (ID: 0x%x)!", rec->id); |
2403 | 0 | return false; |
2404 | 0 | } |
2405 | | |
2406 | 0 | return true; |
2407 | 0 | } |
2408 | | |
2409 | | static void |
2410 | 0 | free_someip_parameter_bitfield_cb(void *r) { |
2411 | 0 | someip_parameter_bitfield_uat_t *rec = (someip_parameter_bitfield_uat_t *)r; |
2412 | 0 | if (rec->name) { |
2413 | 0 | g_free(rec->name); |
2414 | 0 | rec->name = NULL; |
2415 | 0 | } |
2416 | |
|
2417 | 0 | if (rec->bit_name) { |
2418 | 0 | g_free(rec->bit_name); |
2419 | 0 | rec->bit_name = NULL; |
2420 | 0 | } |
2421 | |
|
2422 | 0 | if (rec->filter_string) { |
2423 | 0 | g_free(rec->filter_string); |
2424 | 0 | rec->filter_string = NULL; |
2425 | 0 | } |
2426 | 0 | } |
2427 | | |
2428 | | static void |
2429 | 0 | free_someip_parameter_bitfield(void *data) { |
2430 | 0 | someip_parameter_bitfield_t *list = (someip_parameter_bitfield_t *)data; |
2431 | |
|
2432 | 0 | if (list->items != NULL) { |
2433 | 0 | wmem_free(wmem_epan_scope(), (void *)(list->items)); |
2434 | 0 | list->items = NULL; |
2435 | 0 | } |
2436 | |
|
2437 | 0 | wmem_free(wmem_epan_scope(), (void *)data); |
2438 | 0 | } |
2439 | | |
2440 | | static void |
2441 | 75 | post_update_someip_parameter_bitfield_read_in_data(someip_parameter_bitfield_uat_t *data, unsigned data_num, GHashTable *ht) { |
2442 | 75 | if (ht == NULL || data == NULL) { |
2443 | 75 | return; |
2444 | 75 | } |
2445 | | |
2446 | 0 | for (unsigned i = 0; i < data_num; i++) { |
2447 | 0 | someip_parameter_bitfield_t *list = g_hash_table_lookup(ht, GUINT_TO_POINTER(data[i].id)); |
2448 | 0 | if (list == NULL) { |
2449 | 0 | list = wmem_new(wmem_epan_scope(), someip_parameter_bitfield_t); |
2450 | 0 | INIT_SOMEIP_PARAMETER_BITFIELD(list) |
2451 | |
|
2452 | 0 | list->id = data[i].id; |
2453 | 0 | list->name = data[i].name; |
2454 | 0 | list->number_of_bits = data[i].number_of_bits; |
2455 | 0 | list->num_of_items = data[i].num_of_items; |
2456 | 0 | list->items = wmem_alloc0_array(wmem_epan_scope(), someip_parameter_bitfield_item_t, list->num_of_items); |
2457 | | |
2458 | | /* create new entry ... */ |
2459 | 0 | g_hash_table_insert(ht, GUINT_TO_POINTER(data[i].id), list); |
2460 | 0 | } |
2461 | | |
2462 | | /* and now we add to item array */ |
2463 | 0 | if (list->num_of_items > 0 && data[i].num_of_items == list->num_of_items) { |
2464 | | |
2465 | | /* find first empty slot */ |
2466 | 0 | unsigned j; |
2467 | 0 | for (j = 0; j < list->num_of_items && list->items[j].bit_name != NULL; j++); |
2468 | |
|
2469 | 0 | if (j < list->num_of_items) { |
2470 | 0 | someip_parameter_bitfield_item_t *item = &(list->items[j]); |
2471 | 0 | INIT_SOMEIP_PARAMETER_BITFIELD_ITEM(item) |
2472 | | |
2473 | | /* we do not care if we overwrite param */ |
2474 | 0 | item->bit_number = data[i].bit_number; |
2475 | 0 | item->bit_name = data[i].bit_name; |
2476 | 0 | item->filter_string = data[i].filter_string; |
2477 | 0 | } |
2478 | 0 | } |
2479 | 0 | } |
2480 | 0 | } |
2481 | | |
2482 | | static void |
2483 | 15 | reset_someip_parameter_bitfield_cb(void) { |
2484 | | /* destroy old hash table, if it exists */ |
2485 | 15 | if (data_someip_parameter_bitfields) { |
2486 | 15 | g_hash_table_destroy(data_someip_parameter_bitfields); |
2487 | 15 | data_someip_parameter_bitfields = NULL; |
2488 | 15 | } |
2489 | | |
2490 | 15 | set_prefs_changed(); |
2491 | 15 | } |
2492 | | |
2493 | | static void |
2494 | 15 | post_update_someip_parameter_bitfield_cb(void) { |
2495 | 15 | reset_someip_parameter_bitfield_cb(); |
2496 | | |
2497 | 15 | data_someip_parameter_bitfields = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, &free_someip_parameter_bitfield); |
2498 | 15 | post_update_someip_parameter_bitfield_read_in_data(someip_parameter_bitfields, someip_parameter_bitfields_num, data_someip_parameter_bitfields); |
2499 | 15 | } |
2500 | | |
2501 | | |
2502 | | static void |
2503 | 300 | deregister_dynamic_hf_data(hf_register_info **hf_array, unsigned *hf_size) { |
2504 | 300 | if (*hf_array) { |
2505 | 0 | for (unsigned i = 0; i < *hf_size; i++) { |
2506 | 0 | if ((*hf_array)[i].p_id != NULL) { |
2507 | 0 | g_free((*hf_array)[i].p_id); |
2508 | 0 | (*hf_array)[i].p_id = NULL; |
2509 | 0 | } |
2510 | 0 | } |
2511 | 0 | proto_add_deregistered_data(*hf_array); |
2512 | 0 | *hf_array = NULL; |
2513 | 0 | *hf_size = 0; |
2514 | 0 | } |
2515 | 300 | } |
2516 | | |
2517 | | static void |
2518 | 75 | allocate_dynamic_hf_data(hf_register_info **hf_array, unsigned *hf_size, unsigned new_size) { |
2519 | 75 | *hf_array = g_new0(hf_register_info, new_size); |
2520 | 75 | *hf_size = new_size; |
2521 | 75 | } |
2522 | | |
2523 | | static void |
2524 | 60 | reset_someip_dynamic_parameter_cb(void) { |
2525 | 60 | proto_deregister_all_fields_with_prefix(proto_someip, SOMEIP_NAME_PREFIX); |
2526 | | |
2527 | | /* destroy old hash tables, if they exist */ |
2528 | 60 | if (data_someip_parameter_list) { |
2529 | 45 | deregister_dynamic_hf_data(&dynamic_hf_param, &dynamic_hf_param_size); |
2530 | 45 | g_hash_table_destroy(data_someip_parameter_list); |
2531 | 45 | data_someip_parameter_list = NULL; |
2532 | 45 | } |
2533 | 60 | if (data_someip_parameter_arrays) { |
2534 | 45 | deregister_dynamic_hf_data(&dynamic_hf_array, &dynamic_hf_array_size); |
2535 | 45 | g_hash_table_destroy(data_someip_parameter_arrays); |
2536 | 45 | data_someip_parameter_arrays = NULL; |
2537 | 45 | } |
2538 | 60 | if (data_someip_parameter_structs) { |
2539 | 45 | deregister_dynamic_hf_data(&dynamic_hf_struct, &dynamic_hf_struct_size); |
2540 | 45 | g_hash_table_destroy(data_someip_parameter_structs); |
2541 | 45 | data_someip_parameter_structs = NULL; |
2542 | 45 | } |
2543 | 60 | if (data_someip_parameter_unions) { |
2544 | 45 | deregister_dynamic_hf_data(&dynamic_hf_union, &dynamic_hf_union_size); |
2545 | 45 | g_hash_table_destroy(data_someip_parameter_unions); |
2546 | 45 | data_someip_parameter_unions = NULL; |
2547 | 45 | } |
2548 | 60 | if (data_someip_parameter_bitfields) { |
2549 | 45 | deregister_dynamic_hf_data(&dynamic_hf_bitfield, &dynamic_hf_bitfield_size); |
2550 | 45 | g_hash_table_destroy(data_someip_parameter_bitfields); |
2551 | 45 | data_someip_parameter_bitfields = NULL; |
2552 | 45 | } |
2553 | | |
2554 | 60 | set_prefs_changed(); |
2555 | 60 | } |
2556 | | |
2557 | | static void |
2558 | 60 | post_update_someip_dynamic_parameter_cb(void) { |
2559 | 60 | reset_someip_dynamic_parameter_cb(); |
2560 | | |
2561 | 60 | data_someip_parameter_list = g_hash_table_new_full(g_int64_hash, g_int64_equal, g_free, &free_someip_parameter_list); |
2562 | 60 | post_update_someip_parameter_list_read_in_data(someip_parameter_list, someip_parameter_list_num, data_someip_parameter_list); |
2563 | | |
2564 | 60 | data_someip_parameter_arrays = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, &free_someip_parameter_array); |
2565 | 60 | post_update_someip_parameter_array_read_in_data(someip_parameter_arrays, someip_parameter_arrays_num, data_someip_parameter_arrays); |
2566 | | |
2567 | 60 | data_someip_parameter_structs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, &free_someip_parameter_struct); |
2568 | 60 | post_update_someip_parameter_struct_read_in_data(someip_parameter_structs, someip_parameter_structs_num, data_someip_parameter_structs); |
2569 | | |
2570 | 60 | data_someip_parameter_unions = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, &free_someip_parameter_union); |
2571 | 60 | post_update_someip_parameter_union_read_in_data(someip_parameter_unions, someip_parameter_unions_num, data_someip_parameter_unions); |
2572 | | |
2573 | 60 | data_someip_parameter_bitfields = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, &free_someip_parameter_bitfield); |
2574 | 60 | post_update_someip_parameter_bitfield_read_in_data(someip_parameter_bitfields, someip_parameter_bitfields_num, data_someip_parameter_bitfields); |
2575 | 60 | } |
2576 | | |
2577 | | typedef struct _param_return_attibutes_t { |
2578 | | enum ftenum type; |
2579 | | int display_base; |
2580 | | char *base_type_name; |
2581 | | uint64_t bitmask; |
2582 | | uint8_t resolved_data_type; |
2583 | | } param_return_attributes_t; |
2584 | | |
2585 | | static void |
2586 | 0 | get_param_attributes(uint8_t data_type, uint32_t id_ref, unsigned child_pos, param_return_attributes_t *ret) { |
2587 | 0 | int count = 10; |
2588 | |
|
2589 | 0 | ret->type = FT_NONE; |
2590 | 0 | ret->display_base = BASE_NONE; |
2591 | 0 | ret->base_type_name = NULL; |
2592 | 0 | ret->bitmask = 0; |
2593 | 0 | ret->resolved_data_type = SOMEIP_PARAMETER_DATA_TYPE_MAX + 1; |
2594 | | |
2595 | | /* we limit the number of typedef recursion to "count" */ |
2596 | 0 | while (data_type == SOMEIP_PARAMETER_DATA_TYPE_TYPEDEF && count > 0) { |
2597 | 0 | someip_parameter_typedef_t *tmp = get_typedef_config(id_ref); |
2598 | | /* this should not be a typedef since we don't support recursion of typedefs */ |
2599 | 0 | if (tmp != NULL) { |
2600 | 0 | data_type = tmp->data_type; |
2601 | 0 | id_ref = tmp->id_ref; |
2602 | 0 | } |
2603 | 0 | count--; |
2604 | 0 | } |
2605 | |
|
2606 | 0 | if (data_type == SOMEIP_PARAMETER_DATA_TYPE_ENUM) { |
2607 | 0 | someip_parameter_enum_t *tmp = get_enum_config(id_ref); |
2608 | | /* this can only be a base type ... */ |
2609 | 0 | if (tmp != NULL) { |
2610 | 0 | data_type = tmp->data_type; |
2611 | 0 | id_ref = tmp->id_ref; |
2612 | 0 | } |
2613 | 0 | } |
2614 | |
|
2615 | 0 | if (data_type == SOMEIP_PARAMETER_DATA_TYPE_STRING) { |
2616 | 0 | someip_parameter_string_t *tmp = get_string_config(id_ref); |
2617 | 0 | ret->type = FT_STRING; |
2618 | 0 | ret->display_base = BASE_NONE; |
2619 | 0 | if (tmp != NULL) { |
2620 | 0 | ret->base_type_name = tmp->name; |
2621 | 0 | } |
2622 | 0 | ret->resolved_data_type = data_type; |
2623 | 0 | return; |
2624 | 0 | } |
2625 | | |
2626 | 0 | if (data_type == SOMEIP_PARAMETER_DATA_TYPE_BASE_TYPE) { |
2627 | 0 | someip_parameter_base_type_list_t *tmp = get_base_type_config(id_ref); |
2628 | |
|
2629 | 0 | ret->display_base = BASE_DEC; |
2630 | |
|
2631 | 0 | if (tmp != NULL) { |
2632 | 0 | ret->base_type_name = tmp->name; |
2633 | |
|
2634 | 0 | if (g_strcmp0(tmp->data_type, "uint8") == 0) { |
2635 | 0 | ret->type = FT_UINT8; |
2636 | 0 | } else if (g_strcmp0(tmp->data_type, "uint16") == 0) { |
2637 | 0 | ret->type = FT_UINT16; |
2638 | 0 | } else if (g_strcmp0(tmp->data_type, "uint32") == 0) { |
2639 | 0 | ret->type = FT_UINT32; |
2640 | 0 | } else if (g_strcmp0(tmp->data_type, "uint64") == 0) { |
2641 | 0 | ret->type = FT_UINT64; |
2642 | 0 | } else if (g_strcmp0(tmp->data_type, "int8") == 0) { |
2643 | 0 | ret->type = FT_INT8; |
2644 | 0 | } else if (g_strcmp0(tmp->data_type, "int16") == 0) { |
2645 | 0 | ret->type = FT_INT16; |
2646 | 0 | } else if (g_strcmp0(tmp->data_type, "int32") == 0) { |
2647 | 0 | ret->type = FT_INT32; |
2648 | 0 | } else if (g_strcmp0(tmp->data_type, "int64") == 0) { |
2649 | 0 | ret->type = FT_INT64; |
2650 | 0 | } else if (g_strcmp0(tmp->data_type, "float32") == 0) { |
2651 | 0 | ret->type = FT_FLOAT; |
2652 | 0 | ret->display_base = BASE_NONE; |
2653 | 0 | } else if (g_strcmp0(tmp->data_type, "float64") == 0) { |
2654 | 0 | ret->type = FT_DOUBLE; |
2655 | 0 | ret->display_base = BASE_NONE; |
2656 | 0 | } else { |
2657 | 0 | ret->type = FT_NONE; |
2658 | 0 | } |
2659 | 0 | } else { |
2660 | 0 | ret->type = FT_NONE; |
2661 | 0 | } |
2662 | 0 | ret->resolved_data_type = data_type; |
2663 | 0 | } |
2664 | |
|
2665 | 0 | if (data_type == SOMEIP_PARAMETER_DATA_TYPE_BITFIELD) { |
2666 | 0 | someip_parameter_bitfield_t *tmp = get_bitfield_config(id_ref); |
2667 | |
|
2668 | 0 | ret ->display_base = BASE_DEC; |
2669 | |
|
2670 | 0 | if (tmp != NULL) { |
2671 | 0 | ret->base_type_name = tmp->name; |
2672 | |
|
2673 | 0 | switch (tmp->number_of_bits) { |
2674 | 0 | case 8: |
2675 | 0 | ret->type = FT_UINT8; |
2676 | 0 | break; |
2677 | 0 | case 16: |
2678 | 0 | ret->type = FT_UINT16; |
2679 | 0 | break; |
2680 | 0 | case 32: |
2681 | 0 | ret->type = FT_UINT32; |
2682 | 0 | break; |
2683 | 0 | case 64: |
2684 | 0 | ret->type = FT_UINT64; |
2685 | 0 | break; |
2686 | 0 | } |
2687 | 0 | } |
2688 | | |
2689 | 0 | ret->resolved_data_type = data_type; |
2690 | 0 | return; |
2691 | 0 | } |
2692 | | |
2693 | 0 | if (data_type == SOMEIP_PARAMETER_DATA_TYPE_BITFIELD_INT) { |
2694 | 0 | someip_parameter_bitfield_t *tmp = get_bitfield_config(id_ref); |
2695 | |
|
2696 | 0 | if (tmp != NULL) { |
2697 | 0 | ret->display_base = tmp->number_of_bits; |
2698 | |
|
2699 | 0 | someip_parameter_bitfield_item_t *item = &(tmp->items[child_pos]); |
2700 | |
|
2701 | 0 | if (item->bit_number < 64) { |
2702 | 0 | ret->bitmask = (uint64_t)1 << item->bit_number; |
2703 | 0 | } |
2704 | |
|
2705 | 0 | ret->type = FT_BOOLEAN; |
2706 | 0 | } |
2707 | |
|
2708 | 0 | ret->resolved_data_type = data_type; |
2709 | 0 | return; |
2710 | 0 | } |
2711 | | |
2712 | 0 | if (data_type == SOMEIP_PARAMETER_DATA_TYPE_STRUCT) |
2713 | 0 | { |
2714 | 0 | ret->type = FT_NONE; |
2715 | 0 | ret->display_base = BASE_NONE; |
2716 | 0 | ret->resolved_data_type = data_type; |
2717 | 0 | return; |
2718 | 0 | } |
2719 | | |
2720 | 0 | if (data_type == SOMEIP_PARAMETER_DATA_TYPE_UNION) |
2721 | 0 | { |
2722 | 0 | ret->type = FT_NONE; |
2723 | 0 | ret->display_base = BASE_NONE; |
2724 | 0 | ret->resolved_data_type = data_type; |
2725 | 0 | return; |
2726 | 0 | } |
2727 | | |
2728 | 0 | if (data_type == SOMEIP_PARAMETER_DATA_TYPE_ARRAY) |
2729 | 0 | { |
2730 | 0 | ret->type = FT_NONE; |
2731 | 0 | ret->display_base = BASE_NONE; |
2732 | 0 | ret->resolved_data_type = data_type; |
2733 | 0 | return; |
2734 | 0 | } |
2735 | | |
2736 | | /* all other types are handled or don't need a type! */ |
2737 | 0 | ret->resolved_data_type = data_type; |
2738 | 0 | return; |
2739 | 0 | } |
2740 | | |
2741 | | static int* |
2742 | 0 | update_dynamic_hf_entry(hf_register_info *hf_array, int pos, uint32_t data_type, unsigned id_ref, char *param_name, char *filter_string, unsigned child_pos) { |
2743 | 0 | if (filter_string == NULL) { |
2744 | 0 | ws_debug("empty filter string (pos %d)", pos); |
2745 | 0 | return NULL; |
2746 | 0 | } |
2747 | | |
2748 | 0 | param_return_attributes_t attribs; |
2749 | 0 | get_param_attributes(data_type, id_ref, child_pos, &attribs); |
2750 | 0 | bool allow_ft_none = (attribs.resolved_data_type == SOMEIP_PARAMETER_DATA_TYPE_STRUCT || |
2751 | 0 | attribs.resolved_data_type == SOMEIP_PARAMETER_DATA_TYPE_ARRAY || |
2752 | 0 | attribs.resolved_data_type == SOMEIP_PARAMETER_DATA_TYPE_UNION); |
2753 | 0 | bool is_container = allow_ft_none; |
2754 | |
|
2755 | 0 | if (hf_array == NULL || (!allow_ft_none && attribs.type == FT_NONE)) |
2756 | 0 | { |
2757 | 0 | return NULL; |
2758 | 0 | } |
2759 | | |
2760 | 0 | int *hf_id = g_new(int, 1); |
2761 | 0 | *hf_id = 0; |
2762 | 0 | hf_array[pos].p_id = hf_id; |
2763 | |
|
2764 | 0 | hf_array[pos].hfinfo.strings = NULL; |
2765 | 0 | hf_array[pos].hfinfo.bitmask = attribs.bitmask; |
2766 | 0 | hf_array[pos].hfinfo.blurb = NULL; |
2767 | |
|
2768 | 0 | bool same_label = attribs.base_type_name != NULL && g_strcmp0(param_name, attribs.base_type_name) == 0; |
2769 | 0 | if (attribs.base_type_name != NULL && !is_container && !same_label) |
2770 | 0 | { |
2771 | 0 | hf_array[pos].hfinfo.name = ws_strdup_printf("%s [%s]", param_name, attribs.base_type_name); |
2772 | 0 | } |
2773 | 0 | else |
2774 | 0 | { |
2775 | 0 | hf_array[pos].hfinfo.name = g_strdup(param_name); |
2776 | 0 | } |
2777 | |
|
2778 | 0 | hf_array[pos].hfinfo.abbrev = ws_strdup_printf("%s.%s", SOMEIP_NAME_PREFIX, filter_string); |
2779 | 0 | hf_array[pos].hfinfo.type = attribs.type; |
2780 | 0 | hf_array[pos].hfinfo.display = attribs.display_base; |
2781 | |
|
2782 | 0 | HFILL_INIT(hf_array[pos]); |
2783 | |
|
2784 | 0 | return hf_id; |
2785 | 0 | } |
2786 | | |
2787 | | static void |
2788 | 0 | update_dynamic_param_hf_entry(void *key _U_, void *value, void *data) { |
2789 | 0 | uint32_t *pos = (uint32_t *)data; |
2790 | 0 | someip_parameter_list_t *list = (someip_parameter_list_t *)value; |
2791 | 0 | unsigned i = 0; |
2792 | |
|
2793 | 0 | for (i = 0; i < list->num_of_items ; i++) { |
2794 | 0 | if (*pos >= dynamic_hf_param_size) { |
2795 | 0 | ws_critical("out of dynamic hf space for parameters!"); |
2796 | 0 | return; |
2797 | 0 | } |
2798 | | |
2799 | 0 | someip_parameter_item_t *item = &(list->items[i]); |
2800 | |
|
2801 | 0 | item->hf_id = update_dynamic_hf_entry(dynamic_hf_param, *pos, item->data_type, item->id_ref, item->name, item->filter_string, 0); |
2802 | |
|
2803 | 0 | if (item->hf_id != NULL) { |
2804 | 0 | (*pos)++; |
2805 | 0 | } |
2806 | 0 | } |
2807 | 0 | } |
2808 | | |
2809 | | static void |
2810 | 0 | update_dynamic_array_hf_entry(void *key _U_, void *value, void *data) { |
2811 | 0 | uint32_t *pos = (uint32_t *)data; |
2812 | 0 | someip_parameter_array_t *item = (someip_parameter_array_t *)value; |
2813 | |
|
2814 | 0 | if (*pos >= dynamic_hf_array_size) { |
2815 | 0 | ws_critical("out of dynamic hf space for arrays!"); |
2816 | 0 | return; |
2817 | 0 | } |
2818 | | |
2819 | 0 | item->hf_id = update_dynamic_hf_entry(dynamic_hf_array, *pos, item->data_type, item->id_ref, item->name, item->filter_string, 0); |
2820 | |
|
2821 | 0 | if (item->hf_id != NULL) { |
2822 | 0 | (*pos)++; |
2823 | 0 | } |
2824 | 0 | } |
2825 | | |
2826 | | static void |
2827 | 0 | update_dynamic_struct_hf_entry(void *key _U_, void *value, void *data) { |
2828 | 0 | uint32_t *pos = (uint32_t *)data; |
2829 | 0 | someip_parameter_struct_t *list = (someip_parameter_struct_t *)value; |
2830 | 0 | unsigned i = 0; |
2831 | |
|
2832 | 0 | for (i = 0; i < list->num_of_items; i++) { |
2833 | 0 | if (*pos >= dynamic_hf_struct_size) { |
2834 | 0 | ws_critical("out of dynamic hf space for structs!"); |
2835 | 0 | return; |
2836 | 0 | } |
2837 | 0 | someip_parameter_item_t *item = &(list->items[i]); |
2838 | |
|
2839 | 0 | item->hf_id = update_dynamic_hf_entry(dynamic_hf_struct, *pos, item->data_type, item->id_ref, item->name, item->filter_string, 0); |
2840 | |
|
2841 | 0 | if (item->hf_id != NULL) { |
2842 | 0 | (*pos)++; |
2843 | 0 | } |
2844 | 0 | } |
2845 | 0 | } |
2846 | | |
2847 | | static void |
2848 | 0 | update_dynamic_union_hf_entry(void *key _U_, void *value, void *data) { |
2849 | 0 | uint32_t *pos = (uint32_t *)data; |
2850 | 0 | someip_parameter_union_t *list = (someip_parameter_union_t *)value; |
2851 | 0 | unsigned i = 0; |
2852 | |
|
2853 | 0 | for (i = 0; i < list->num_of_items; i++) { |
2854 | 0 | if (*pos >= dynamic_hf_union_size) { |
2855 | 0 | ws_critical("out of dynamic hf space for unions!"); |
2856 | 0 | return; |
2857 | 0 | } |
2858 | | |
2859 | 0 | someip_parameter_union_item_t *item = &(list->items[i]); |
2860 | |
|
2861 | 0 | item->hf_id = update_dynamic_hf_entry(dynamic_hf_union, *pos, item->data_type, item->id_ref, item->name, item->filter_string, 0); |
2862 | |
|
2863 | 0 | if (item->hf_id != NULL) { |
2864 | 0 | (*pos)++; |
2865 | 0 | } |
2866 | 0 | } |
2867 | 0 | } |
2868 | | |
2869 | | static void |
2870 | 0 | update_dynamic_bitfield_hf_entry(void *key _U_, void *value, void *data) { |
2871 | 0 | uint32_t *pos = (uint32_t *)data; |
2872 | 0 | someip_parameter_bitfield_t *list = (someip_parameter_bitfield_t *)value; |
2873 | 0 | unsigned i = 0; |
2874 | |
|
2875 | 0 | for (i = 0; i < list->num_of_items; i++) { |
2876 | 0 | if (*pos >= dynamic_hf_bitfield_size) { |
2877 | 0 | ws_critical("out of dynamic hf space for bitfield bits!"); |
2878 | 0 | return; |
2879 | 0 | } |
2880 | | |
2881 | 0 | someip_parameter_bitfield_item_t *item = &(list->items[i]); |
2882 | |
|
2883 | 0 | item->hf_id = update_dynamic_hf_entry(dynamic_hf_bitfield, *pos, SOMEIP_PARAMETER_DATA_TYPE_BITFIELD_INT, list->id, item->bit_name, item->filter_string, i); |
2884 | |
|
2885 | 0 | if (item->hf_id != NULL) { |
2886 | 0 | (*pos)++; |
2887 | 0 | } |
2888 | 0 | } |
2889 | 0 | } |
2890 | | |
2891 | | static void |
2892 | 30 | update_dynamic_hf_entries_someip_parameter(void) { |
2893 | 30 | proto_deregister_all_fields_with_prefix(proto_someip, SOMEIP_NAME_PREFIX); |
2894 | | |
2895 | 30 | if (data_someip_parameter_list != NULL) { |
2896 | 15 | deregister_dynamic_hf_data(&dynamic_hf_param, &dynamic_hf_param_size); |
2897 | 15 | allocate_dynamic_hf_data(&dynamic_hf_param, &dynamic_hf_param_size, someip_parameter_list_num); |
2898 | 15 | uint32_t pos = 0; |
2899 | 15 | g_hash_table_foreach(data_someip_parameter_list, update_dynamic_param_hf_entry, &pos); |
2900 | 15 | proto_register_field_array(proto_someip, dynamic_hf_param, pos); |
2901 | 15 | } |
2902 | 30 | if (data_someip_parameter_arrays != NULL) { |
2903 | 15 | deregister_dynamic_hf_data(&dynamic_hf_array, &dynamic_hf_array_size); |
2904 | 15 | allocate_dynamic_hf_data(&dynamic_hf_array, &dynamic_hf_array_size, someip_parameter_arrays_num); |
2905 | 15 | uint32_t pos = 0; |
2906 | 15 | g_hash_table_foreach(data_someip_parameter_arrays, update_dynamic_array_hf_entry, &pos); |
2907 | 15 | proto_register_field_array(proto_someip, dynamic_hf_array, pos); |
2908 | 15 | } |
2909 | 30 | if (data_someip_parameter_structs != NULL) { |
2910 | 15 | deregister_dynamic_hf_data(&dynamic_hf_struct, &dynamic_hf_struct_size); |
2911 | 15 | allocate_dynamic_hf_data(&dynamic_hf_struct, &dynamic_hf_struct_size, someip_parameter_structs_num); |
2912 | 15 | uint32_t pos = 0; |
2913 | 15 | g_hash_table_foreach(data_someip_parameter_structs, update_dynamic_struct_hf_entry, &pos); |
2914 | 15 | proto_register_field_array(proto_someip, dynamic_hf_struct, pos); |
2915 | 15 | } |
2916 | 30 | if (data_someip_parameter_unions != NULL) { |
2917 | 15 | deregister_dynamic_hf_data(&dynamic_hf_union, &dynamic_hf_union_size); |
2918 | 15 | allocate_dynamic_hf_data(&dynamic_hf_union, &dynamic_hf_union_size, someip_parameter_unions_num); |
2919 | 15 | uint32_t pos = 0; |
2920 | 15 | g_hash_table_foreach(data_someip_parameter_unions, update_dynamic_union_hf_entry, &pos); |
2921 | 15 | proto_register_field_array(proto_someip, dynamic_hf_union, pos); |
2922 | 15 | } |
2923 | 30 | if (data_someip_parameter_bitfields != NULL) { |
2924 | 15 | deregister_dynamic_hf_data(&dynamic_hf_bitfield, &dynamic_hf_bitfield_size); |
2925 | 15 | allocate_dynamic_hf_data(&dynamic_hf_bitfield, &dynamic_hf_bitfield_size, someip_parameter_bitfields_num); |
2926 | 15 | uint32_t pos = 0; |
2927 | 15 | g_hash_table_foreach(data_someip_parameter_bitfields, update_dynamic_bitfield_hf_entry, &pos); |
2928 | 15 | proto_register_field_array(proto_someip, dynamic_hf_bitfield, pos); |
2929 | 15 | } |
2930 | 30 | } |
2931 | | |
2932 | | static void |
2933 | 0 | expert_someip_payload_truncated(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, int length) { |
2934 | 0 | proto_tree_add_expert(tree, pinfo, &ei_someip_payload_truncated, tvb, offset, length); |
2935 | 0 | col_append_str(pinfo->cinfo, COL_INFO, " [SOME/IP Payload: Truncated payload!]"); |
2936 | 0 | } |
2937 | | |
2938 | | static void |
2939 | 0 | expert_someip_payload_malformed(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, int length) { |
2940 | 0 | proto_tree_add_expert(tree, pinfo, &ei_someip_payload_malformed, tvb, offset, length); |
2941 | 0 | col_append_str(pinfo->cinfo, COL_INFO, " [SOME/IP Payload: Malformed payload!]"); |
2942 | 0 | } |
2943 | | |
2944 | | static void |
2945 | 0 | expert_someip_payload_config_error(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, int length, const char *message) { |
2946 | 0 | proto_tree_add_expert_format(tree, pinfo, &ei_someip_payload_config_error, tvb, offset, length, "SOME/IP Payload: %s", message); |
2947 | 0 | col_append_str(pinfo->cinfo, COL_INFO, " [SOME/IP Payload: Config Error]"); |
2948 | 0 | } |
2949 | | |
2950 | | /******************************************* |
2951 | | **************** Statistics *************** |
2952 | | *******************************************/ |
2953 | | |
2954 | | static void |
2955 | 0 | someip_messages_stats_tree_init(stats_tree *st) { |
2956 | 0 | st_node_ip_src = stats_tree_create_node(st, st_str_ip_src, 0, STAT_DT_INT, true); |
2957 | 0 | stat_node_set_flags(st, st_str_ip_src, 0, false, ST_FLG_SORT_TOP); |
2958 | 0 | st_node_ip_dst = stats_tree_create_node(st, st_str_ip_dst, 0, STAT_DT_INT, true); |
2959 | 0 | } |
2960 | | |
2961 | | static tap_packet_status |
2962 | 0 | someip_messages_stats_tree_packet(stats_tree *st, packet_info *pinfo, epan_dissect_t *edt _U_, const void *p, tap_flags_t flags _U_) { |
2963 | 0 | static char* tmp_srv_str; |
2964 | 0 | static char* tmp_meth_str; |
2965 | 0 | static char* tmp_addr_str; |
2966 | 0 | int tmp; |
2967 | |
|
2968 | 0 | DISSECTOR_ASSERT(p); |
2969 | 0 | const someip_messages_tap_t *data = (const someip_messages_tap_t *)p; |
2970 | |
|
2971 | 0 | tmp_addr_str = wmem_strdup_printf(pinfo->pool, "%s (%s)", address_to_str(pinfo->pool, &pinfo->net_src), address_to_name(&pinfo->net_src)); |
2972 | 0 | tick_stat_node(st, st_str_ip_src, 0, false); |
2973 | 0 | int src_id = tick_stat_node(st, tmp_addr_str, st_node_ip_src, true); |
2974 | |
|
2975 | 0 | tmp_addr_str = wmem_strdup_printf(pinfo->pool, "%s (%s)", address_to_str(pinfo->pool, &pinfo->net_dst), address_to_name(&pinfo->net_dst)); |
2976 | 0 | tick_stat_node(st, st_str_ip_dst, 0, false); |
2977 | 0 | int dst_id = tick_stat_node(st, tmp_addr_str, st_node_ip_dst, true); |
2978 | |
|
2979 | 0 | char *service_name = someip_lookup_service_name(data->service_id); |
2980 | 0 | if (service_name == NULL) { |
2981 | 0 | tmp_srv_str = wmem_strdup_printf(pinfo->pool, "Service 0x%04x", data->service_id); |
2982 | 0 | } else { |
2983 | 0 | tmp_srv_str = wmem_strdup_printf(pinfo->pool, "Service 0x%04x (%s)", data->service_id, service_name); |
2984 | 0 | } |
2985 | |
|
2986 | 0 | char *method_name = someip_lookup_method_name(data->service_id, data->method_id); |
2987 | 0 | if (method_name == NULL) { |
2988 | 0 | tmp_meth_str = wmem_strdup_printf(pinfo->pool, "Method 0x%04x %s", data->method_id, |
2989 | 0 | val_to_str(pinfo->pool, data->message_type, someip_msg_type, "Message-Type: 0x%02x")); |
2990 | 0 | } else { |
2991 | 0 | tmp_meth_str = wmem_strdup_printf(pinfo->pool, "Method 0x%04x (%s) %s", data->method_id, method_name, |
2992 | 0 | val_to_str(pinfo->pool, data->message_type, someip_msg_type, "Message-Type: 0x%02x")); |
2993 | 0 | } |
2994 | |
|
2995 | 0 | tmp = tick_stat_node(st, tmp_srv_str, src_id, true); |
2996 | 0 | tick_stat_node(st, tmp_meth_str, tmp, false); |
2997 | 0 | tmp = tick_stat_node(st, tmp_srv_str, dst_id, true); |
2998 | 0 | tick_stat_node(st, tmp_meth_str, tmp, false); |
2999 | |
|
3000 | 0 | return TAP_PACKET_REDRAW; |
3001 | 0 | } |
3002 | | |
3003 | | /******************************************* |
3004 | | ******** SOME/IP Payload Dissector ******** |
3005 | | *******************************************/ |
3006 | | |
3007 | | static int |
3008 | | 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); |
3009 | | |
3010 | | static int |
3011 | | dissect_someip_payload_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, someip_parameter_item_t *items, uint32_t num_of_items, bool wtlv); |
3012 | | |
3013 | | /* add a flexible size length field, -1 for error*/ |
3014 | | static int64_t |
3015 | 0 | dissect_someip_payload_length_field(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, int offset, int length_of_length_field) { |
3016 | 0 | proto_item *ti; |
3017 | 0 | uint32_t tmp = 0; |
3018 | |
|
3019 | 0 | switch (length_of_length_field) { |
3020 | 0 | case 8: |
3021 | 0 | ti = proto_tree_add_item_ret_uint(subtree, hf_payload_length_field_8bit, tvb, offset, length_of_length_field / 8, ENC_NA, &tmp); |
3022 | 0 | proto_item_set_hidden(ti); |
3023 | 0 | break; |
3024 | 0 | case 16: |
3025 | 0 | ti = proto_tree_add_item_ret_uint(subtree, hf_payload_length_field_16bit, tvb, offset, length_of_length_field / 8, ENC_BIG_ENDIAN, &tmp); |
3026 | 0 | proto_item_set_hidden(ti); |
3027 | 0 | break; |
3028 | 0 | case 32: |
3029 | 0 | ti = proto_tree_add_item_ret_uint(subtree, hf_payload_length_field_32bit, tvb, offset, length_of_length_field / 8, ENC_BIG_ENDIAN, &tmp); |
3030 | 0 | proto_item_set_hidden(ti); |
3031 | 0 | break; |
3032 | 0 | default: |
3033 | 0 | proto_tree_add_expert_format(subtree, pinfo, &ei_someip_payload_config_error, tvb, offset, 0, |
3034 | 0 | "SOME/IP: Payload: length of length field does not make sense: %d bits", length_of_length_field); |
3035 | 0 | col_append_str(pinfo->cinfo, COL_INFO, " [SOME/IP: Payload Config Error]"); |
3036 | 0 | return -1; |
3037 | 0 | } |
3038 | | |
3039 | 0 | return (int64_t)tmp; |
3040 | 0 | } |
3041 | | |
3042 | | /* add a flexible size type field */ |
3043 | | static int64_t |
3044 | 0 | dissect_someip_payload_type_field(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, int offset, int length_of_type_field) { |
3045 | 0 | proto_item *ti; |
3046 | 0 | uint32_t tmp = 0; |
3047 | |
|
3048 | 0 | switch (length_of_type_field) { |
3049 | 0 | case 8: |
3050 | 0 | ti = proto_tree_add_item_ret_uint(subtree, hf_payload_type_field_8bit, tvb, offset, length_of_type_field / 8, ENC_NA, &tmp); |
3051 | 0 | proto_item_set_hidden(ti); |
3052 | 0 | break; |
3053 | 0 | case 16: |
3054 | 0 | ti = proto_tree_add_item_ret_uint(subtree, hf_payload_type_field_16bit, tvb, offset, length_of_type_field / 8, ENC_BIG_ENDIAN, &tmp); |
3055 | 0 | proto_item_set_hidden(ti); |
3056 | 0 | break; |
3057 | 0 | case 32: |
3058 | 0 | ti = proto_tree_add_item_ret_uint(subtree, hf_payload_type_field_32bit, tvb, offset, length_of_type_field / 8, ENC_BIG_ENDIAN, &tmp); |
3059 | 0 | proto_item_set_hidden(ti); |
3060 | 0 | break; |
3061 | 0 | default: |
3062 | 0 | proto_tree_add_expert_format(subtree, pinfo, &ei_someip_payload_config_error, tvb, offset, 0, |
3063 | 0 | "SOME/IP: Payload: length of type field does not make sense: %d bits", length_of_type_field); |
3064 | 0 | col_append_str(pinfo->cinfo, COL_INFO, " [SOME/IP: Payload Config Error]"); |
3065 | 0 | return -1; |
3066 | 0 | } |
3067 | | |
3068 | 0 | return (int64_t)tmp; |
3069 | 0 | } |
3070 | | |
3071 | | static uint32_t |
3072 | 0 | dissect_someip_payload_add_wtlv_if_needed(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_item *ti_root, proto_tree *parent_tree) { |
3073 | 0 | static int * const tag_bitfield[] = { |
3074 | 0 | &hf_payload_wtlv_tag_res, |
3075 | 0 | &hf_payload_wtlv_tag_wire_type, |
3076 | 0 | &hf_payload_wtlv_tag_data_id, |
3077 | 0 | NULL |
3078 | 0 | }; |
3079 | |
|
3080 | 0 | if (offset < 0) { |
3081 | 0 | return 0; |
3082 | 0 | } |
3083 | | |
3084 | 0 | proto_tree *tree = parent_tree; |
3085 | 0 | if (tree == NULL) { |
3086 | 0 | tree = proto_item_add_subtree(ti_root, ett_someip_parameter); |
3087 | 0 | } |
3088 | |
|
3089 | 0 | uint64_t tagdata = 0; |
3090 | 0 | 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); |
3091 | 0 | proto_item_set_hidden(ti); |
3092 | |
|
3093 | 0 | unsigned wiretype = (unsigned)((tagdata & SOMEIP_WTLV_MASK_WIRE_TYPE) >> 12); |
3094 | |
|
3095 | 0 | switch (wiretype) { |
3096 | 0 | case 5: |
3097 | 0 | return 8; |
3098 | 0 | case 6: |
3099 | 0 | return 16; |
3100 | 0 | case 7: |
3101 | 0 | return 32; |
3102 | 0 | default: |
3103 | 0 | return 0; |
3104 | 0 | } |
3105 | 0 | } |
3106 | | |
3107 | | static int |
3108 | 0 | dissect_someip_payload_base_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset, uint8_t data_type, uint32_t id, char *name, int *hf_id_ptr, int wtlv_offset) { |
3109 | 0 | someip_parameter_base_type_list_t *base_type = NULL; |
3110 | 0 | someip_parameter_enum_t *enum_config = NULL; |
3111 | |
|
3112 | 0 | uint32_t basetype_id = 0; |
3113 | 0 | uint32_t enum_id = 0; |
3114 | |
|
3115 | 0 | unsigned param_length = 0; |
3116 | |
|
3117 | 0 | proto_item *ti = NULL; |
3118 | |
|
3119 | 0 | uint64_t value = 0; |
3120 | 0 | uint32_t value32 = 0; |
3121 | 0 | bool value_set = false; |
3122 | |
|
3123 | 0 | uint32_t i = 0; |
3124 | 0 | char *value_name = NULL; |
3125 | |
|
3126 | 0 | bool big_endian = true; |
3127 | |
|
3128 | 0 | int hf_id = 0; |
3129 | |
|
3130 | 0 | if (hf_id_ptr != NULL) { |
3131 | 0 | hf_id = *hf_id_ptr; |
3132 | 0 | } |
3133 | |
|
3134 | 0 | switch (data_type) { |
3135 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_BASE_TYPE: |
3136 | 0 | basetype_id = id; |
3137 | 0 | break; |
3138 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_ENUM: |
3139 | 0 | enum_id = id; |
3140 | 0 | enum_config = get_enum_config(enum_id); |
3141 | 0 | if (enum_config == NULL) { |
3142 | 0 | return 0; |
3143 | 0 | } |
3144 | 0 | basetype_id = enum_config->id_ref; |
3145 | 0 | break; |
3146 | 0 | default: |
3147 | 0 | return 0; |
3148 | 0 | } |
3149 | | |
3150 | 0 | base_type = get_base_type_config(basetype_id); |
3151 | 0 | if (base_type == NULL) { |
3152 | 0 | return 0; |
3153 | 0 | } |
3154 | | |
3155 | 0 | big_endian = base_type->big_endian; |
3156 | 0 | param_length = ((base_type->bitlength_base_type) / 8); |
3157 | |
|
3158 | 0 | if (param_length > tvb_captured_length_remaining(tvb, 0) - offset) { |
3159 | 0 | return 0; |
3160 | 0 | } |
3161 | | |
3162 | 0 | if (hf_id > 0) { |
3163 | 0 | if (strncmp(base_type->data_type, "uint", 4) == 0) { |
3164 | 0 | if (base_type->bitlength_base_type > 32) { |
3165 | 0 | ti = proto_tree_add_item_ret_uint64(tree, hf_id, tvb, offset, param_length, big_endian ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN, &value); |
3166 | 0 | } else { |
3167 | 0 | ti = proto_tree_add_item_ret_uint(tree, hf_id, tvb, offset, param_length, big_endian ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN, &value32); |
3168 | 0 | value = (uint64_t)value32; |
3169 | 0 | } |
3170 | 0 | value_set = true; |
3171 | 0 | } else { |
3172 | 0 | ti = proto_tree_add_item(tree, hf_id, tvb, offset, param_length, big_endian ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN); |
3173 | 0 | } |
3174 | 0 | } else { |
3175 | 0 | if (name == NULL) { |
3176 | 0 | ti = proto_tree_add_string_format(tree, hf_payload_str_base, tvb, offset, param_length, base_type->name, "[%s]", base_type->name); |
3177 | 0 | } else { |
3178 | 0 | ti = proto_tree_add_string_format(tree, hf_payload_str_base, tvb, offset, param_length, base_type->name, "%s [%s]", name, base_type->name); |
3179 | 0 | } |
3180 | 0 | } |
3181 | |
|
3182 | 0 | dissect_someip_payload_add_wtlv_if_needed(tvb, pinfo, wtlv_offset, ti, NULL); |
3183 | |
|
3184 | 0 | if (enum_config != NULL && value_set == true) { |
3185 | 0 | for (i = 0; i < enum_config->num_of_items; i++) { |
3186 | 0 | if (enum_config->items[i].value == value) { |
3187 | 0 | value_name = enum_config->items[i].name; |
3188 | 0 | break; |
3189 | 0 | } |
3190 | 0 | } |
3191 | 0 | if (value_name != NULL) { |
3192 | 0 | proto_item_append_text(ti, " (%s)", value_name); |
3193 | 0 | } |
3194 | 0 | } |
3195 | |
|
3196 | 0 | return param_length; |
3197 | 0 | } |
3198 | | |
3199 | | static int |
3200 | 0 | 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) { |
3201 | 0 | someip_parameter_string_t *config = NULL; |
3202 | |
|
3203 | 0 | uint8_t *buf = NULL; |
3204 | 0 | uint32_t i; |
3205 | |
|
3206 | 0 | proto_item *ti = NULL; |
3207 | 0 | proto_tree *subtree = NULL; |
3208 | 0 | int64_t tmp; |
3209 | 0 | uint32_t length = 0; |
3210 | 0 | int offset_orig = offset; |
3211 | |
|
3212 | 0 | unsigned str_encoding = 0; |
3213 | 0 | int hf_id = hf_payload_str_string; |
3214 | |
|
3215 | 0 | if (hf_id_ptr != NULL) { |
3216 | 0 | hf_id = *hf_id_ptr; |
3217 | 0 | } |
3218 | |
|
3219 | 0 | config = get_string_config(id); |
3220 | |
|
3221 | 0 | if (config == NULL) { |
3222 | 0 | return 0; |
3223 | 0 | } |
3224 | | |
3225 | 0 | if (wtlv_offset >= 0) { |
3226 | 0 | ti = proto_tree_add_string_format(tree, hf_id, tvb, wtlv_offset, 0, name, "%s [%s]", name, config->name); |
3227 | 0 | } else { |
3228 | 0 | ti = proto_tree_add_string_format(tree, hf_id, tvb, offset, 0, name, "%s [%s]", name, config->name); |
3229 | 0 | } |
3230 | 0 | subtree = proto_item_add_subtree(ti, ett_someip_string); |
3231 | |
|
3232 | 0 | uint32_t length_of_length = dissect_someip_payload_add_wtlv_if_needed(tvb, pinfo, wtlv_offset, ti, NULL); |
3233 | | |
3234 | | /* WTLV length overrides configured length */ |
3235 | 0 | if (config->length_of_length == 0 && length_of_length == 0) { |
3236 | 0 | length = config->max_length; |
3237 | 0 | } else { |
3238 | 0 | if (length_of_length == 0) { |
3239 | 0 | length_of_length = config->length_of_length; |
3240 | 0 | } |
3241 | |
|
3242 | 0 | if (tvb_captured_length_remaining(tvb, offset) < (length_of_length >> 3)) { |
3243 | 0 | expert_someip_payload_malformed(tree, pinfo, tvb, offset, 0); |
3244 | 0 | return 0; |
3245 | 0 | } |
3246 | | |
3247 | 0 | tmp = dissect_someip_payload_length_field(tvb, pinfo, subtree, offset, length_of_length); |
3248 | 0 | if (tmp < 0) { |
3249 | | /* error */ |
3250 | 0 | return length_of_length / 8; |
3251 | 0 | } |
3252 | 0 | length = (uint32_t)tmp; |
3253 | 0 | offset += length_of_length / 8; |
3254 | 0 | } |
3255 | | |
3256 | 0 | if ((uint32_t)tvb_captured_length_remaining(tvb, offset) < length) { |
3257 | 0 | expert_someip_payload_malformed(subtree, pinfo, tvb, offset, 0); |
3258 | 0 | return 0; |
3259 | 0 | } |
3260 | | |
3261 | 0 | if (strcmp(config->encoding, "utf-8") == 0) { |
3262 | 0 | str_encoding = ENC_UTF_8 | ENC_NA; |
3263 | 0 | } else if (strcmp(config->encoding, "utf-16") == 0) { |
3264 | 0 | str_encoding = ENC_UTF_16 | (config->big_endian ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN); |
3265 | 0 | } else { |
3266 | 0 | str_encoding = ENC_ASCII | ENC_NA; |
3267 | 0 | } |
3268 | |
|
3269 | 0 | buf = tvb_get_string_enc(pinfo->pool, tvb, offset, length, str_encoding); |
3270 | | |
3271 | | /* sanitizing buffer */ |
3272 | 0 | if ((str_encoding == (ENC_ASCII | ENC_NA)) || (str_encoding & ENC_UTF_8)) { |
3273 | 0 | for (i = 0; i < length; i++) { |
3274 | 0 | if (buf[i] > 0x00 && buf[i] < 0x20) { |
3275 | 0 | buf[i] = 0x20; |
3276 | 0 | } |
3277 | 0 | } |
3278 | 0 | } |
3279 | |
|
3280 | 0 | proto_item_append_text(ti, ": %s", buf); |
3281 | 0 | offset += length; |
3282 | |
|
3283 | 0 | proto_item_set_end(ti, tvb, offset); |
3284 | |
|
3285 | 0 | return offset - offset_orig; |
3286 | 0 | } |
3287 | | |
3288 | | static int |
3289 | | // NOLINTNEXTLINE(misc-no-recursion) |
3290 | 0 | dissect_someip_payload_struct(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset_orig, uint32_t id, char *name, int *hf_id_ptr, int wtlv_offset) { |
3291 | 0 | someip_parameter_struct_t *config = NULL; |
3292 | |
|
3293 | 0 | proto_tree *subtree = NULL; |
3294 | 0 | proto_item *ti = NULL; |
3295 | 0 | tvbuff_t *subtvb = tvb; |
3296 | |
|
3297 | 0 | int64_t length = 0; |
3298 | 0 | int offset = offset_orig; |
3299 | |
|
3300 | 0 | config = get_struct_config(id); |
3301 | |
|
3302 | 0 | if (config == NULL || tree == NULL || tvb == NULL) { |
3303 | 0 | return 0; |
3304 | 0 | } |
3305 | | |
3306 | 0 | int hf_id = 0; |
3307 | 0 | if (hf_id_ptr != NULL) |
3308 | 0 | { |
3309 | 0 | hf_id = *hf_id_ptr; |
3310 | 0 | } |
3311 | |
|
3312 | 0 | const char *display_name = name; |
3313 | 0 | if (display_name == NULL || display_name[0] == '\0') |
3314 | 0 | { |
3315 | 0 | display_name = (config->struct_name != NULL) ? config->struct_name : "struct"; |
3316 | 0 | } |
3317 | |
|
3318 | 0 | if (hf_id > 0) |
3319 | 0 | { |
3320 | 0 | int display_offset = (wtlv_offset >= 0) ? wtlv_offset : offset; |
3321 | 0 | ti = proto_tree_add_item(tree, hf_id, tvb, display_offset, 0, ENC_NA); |
3322 | 0 | } |
3323 | 0 | else if (wtlv_offset >= 0) |
3324 | 0 | { |
3325 | 0 | ti = proto_tree_add_string_format(tree, hf_payload_str_struct, tvb, wtlv_offset, 0, config->struct_name, |
3326 | 0 | "struct %s [%s]", display_name, config->struct_name); |
3327 | 0 | } |
3328 | 0 | else |
3329 | 0 | { |
3330 | 0 | ti = proto_tree_add_string_format(tree, hf_payload_str_struct, tvb, offset, 0, config->struct_name, |
3331 | 0 | "struct %s [%s]", display_name, config->struct_name); |
3332 | 0 | } |
3333 | 0 | subtree = proto_item_add_subtree(ti, ett_someip_struct); |
3334 | |
|
3335 | 0 | if (someip_deserializer_debugging_activated) { |
3336 | 0 | proto_item_append_text(ti, " [Debug: Struct ID 0x%04x]", id); |
3337 | |
|
3338 | 0 | } |
3339 | |
|
3340 | 0 | uint32_t length_of_length = dissect_someip_payload_add_wtlv_if_needed(tvb, pinfo, wtlv_offset, ti, subtree); |
3341 | | |
3342 | | /* WTLV length overrides configured length */ |
3343 | 0 | if (length_of_length == 0) { |
3344 | 0 | length_of_length = config->length_of_length; |
3345 | 0 | } |
3346 | |
|
3347 | 0 | if (tvb_captured_length_remaining(tvb, 0) < (length_of_length >> 3)) { |
3348 | 0 | expert_someip_payload_malformed(tree, pinfo, tvb, offset, 0); |
3349 | 0 | return 0; |
3350 | 0 | }; |
3351 | |
|
3352 | 0 | if (length_of_length != 0) { |
3353 | 0 | length = dissect_someip_payload_length_field(tvb, pinfo, subtree, offset, length_of_length); |
3354 | 0 | if (length < 0) { |
3355 | | /* error */ |
3356 | 0 | return length_of_length / 8; |
3357 | 0 | } |
3358 | 0 | offset += length_of_length / 8; |
3359 | 0 | int endpos = offset_orig + (length_of_length / 8) + (uint32_t)length; |
3360 | 0 | proto_item_set_end(ti, tvb, endpos); |
3361 | 0 | subtvb = tvb_new_subset_length(tvb, 0, endpos); |
3362 | 0 | } |
3363 | | |
3364 | 0 | offset += dissect_someip_payload_parameters(subtvb, pinfo, subtree, offset, config->items, config->num_of_items, config->wtlv_encoding); |
3365 | |
|
3366 | 0 | if (length_of_length == 0) { |
3367 | 0 | proto_item_set_end(ti, tvb, offset); |
3368 | |
|
3369 | 0 | return offset - offset_orig; |
3370 | 0 | } else { |
3371 | 0 | return (length_of_length / 8) + (uint32_t)length; |
3372 | 0 | } |
3373 | 0 | } |
3374 | | |
3375 | | static int |
3376 | | // NOLINTNEXTLINE(misc-no-recursion) |
3377 | 0 | 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) { |
3378 | 0 | someip_parameter_typedef_t *config = NULL; |
3379 | |
|
3380 | 0 | config = get_typedef_config(id); |
3381 | |
|
3382 | 0 | if (config == NULL) { |
3383 | 0 | return 0; |
3384 | 0 | } |
3385 | | |
3386 | | /* we basically skip over the typedef for now */ |
3387 | 0 | return dissect_someip_payload_parameter(tvb, pinfo, tree, offset, (uint8_t)config->data_type, config->id_ref, config->name, hf_id, wtlv_offset); |
3388 | 0 | } |
3389 | | |
3390 | | /* returns bytes parsed, length needs to be int to encode "non-existing" as -1 */ |
3391 | | static int |
3392 | | 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, |
3393 | 0 | someip_parameter_array_t *config, int current_dim, uint32_t length_of_length) { |
3394 | 0 | int offset = offset_orig; |
3395 | 0 | int64_t tmp; |
3396 | |
|
3397 | 0 | *lower_limit = config->dims[current_dim].lower_limit; |
3398 | 0 | *upper_limit = config->dims[current_dim].upper_limit; |
3399 | | |
3400 | | /* length needs to be -1, if we do not have a dynamic length array */ |
3401 | 0 | *length = -1; |
3402 | |
|
3403 | 0 | if (length_of_length == 0) { |
3404 | 0 | length_of_length = config->dims[current_dim].length_of_length; |
3405 | 0 | } |
3406 | 0 | if (length_of_length > 0) { |
3407 | | /* we are filling the length with number of bytes we found in the packet */ |
3408 | 0 | tmp = dissect_someip_payload_length_field(tvb, pinfo, tree, offset, length_of_length); |
3409 | 0 | if (tmp < 0) { |
3410 | | /* leave *length = -1 */ |
3411 | 0 | return length_of_length/8; |
3412 | 0 | } |
3413 | 0 | *length = (int32_t)tmp; |
3414 | 0 | offset += length_of_length/8; |
3415 | 0 | } else { |
3416 | | /* without a length field, the number of elements needs be fixed */ |
3417 | 0 | if (config->dims[current_dim].lower_limit != config->dims[current_dim].upper_limit) { |
3418 | 0 | proto_tree_add_expert_format(tree, pinfo, &ei_someip_payload_static_array_min_not_max, tvb, offset_orig, 0, |
3419 | 0 | "Static array config with Min!=Max (%d, %d)", config->dims[current_dim].lower_limit, config->dims[current_dim].upper_limit); |
3420 | 0 | col_append_str(pinfo->cinfo, COL_INFO, " [SOME/IP Payload: Static array config with Min!=Max!]"); |
3421 | |
|
3422 | 0 | return 0; |
3423 | 0 | } |
3424 | 0 | } |
3425 | | |
3426 | 0 | return offset - offset_orig; |
3427 | 0 | } |
3428 | | |
3429 | | /* returns bytes parsed, length needs to be int to encode "non-existing" as -1 */ |
3430 | | static int |
3431 | | // NOLINTNEXTLINE(misc-no-recursion) |
3432 | | 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, |
3433 | 0 | someip_parameter_array_t *config) { |
3434 | 0 | tvbuff_t *subtvb = NULL; |
3435 | 0 | uint32_t offset = offset_orig; |
3436 | 0 | uint32_t bytes_parsed; |
3437 | 0 | uint32_t ret = 0; |
3438 | 0 | int count = 0; |
3439 | |
|
3440 | 0 | if (length != -1) { |
3441 | 0 | if (length <= (int)tvb_captured_length_remaining(tvb, offset)) { |
3442 | 0 | subtvb = tvb_new_subset_length(tvb, offset, length); |
3443 | | /* created subtvb. so we set offset=0 */ |
3444 | 0 | offset = 0; |
3445 | 0 | } else { |
3446 | 0 | expert_someip_payload_truncated(tree, pinfo, tvb, offset, tvb_captured_length_remaining(tvb, offset)); |
3447 | 0 | return tvb_captured_length_remaining(tvb, offset); |
3448 | 0 | } |
3449 | 0 | } else { |
3450 | 0 | subtvb = tvb; |
3451 | 0 | } |
3452 | | |
3453 | 0 | while ((length == -1 && count < upper_limit) || ((int)offset < length)) { |
3454 | 0 | bytes_parsed = dissect_someip_payload_parameter(subtvb, pinfo, tree, offset, (uint8_t)config->data_type, config->id_ref, config->name, config->hf_id, -1); |
3455 | 0 | if (bytes_parsed == 0) { |
3456 | | /* does this make sense? */ |
3457 | 0 | return 1; |
3458 | 0 | } |
3459 | 0 | offset += bytes_parsed; |
3460 | 0 | count++; |
3461 | 0 | } |
3462 | | |
3463 | 0 | if (count<lower_limit && count>upper_limit) { |
3464 | 0 | proto_tree_add_expert_format(tree, pinfo, &ei_someip_payload_dyn_array_not_within_limit, tvb, offset_orig, length, |
3465 | 0 | "Number of items (%d) outside limit %d-%d", count, lower_limit, upper_limit); |
3466 | 0 | col_append_str(pinfo->cinfo, COL_INFO, " [SOME/IP Payload: Dynamic array does not stay between Min and Max values]"); |
3467 | 0 | } |
3468 | |
|
3469 | 0 | if (length != -1) { |
3470 | | /* we created subtvb first and set offset to 0 */ |
3471 | 0 | ret = offset; |
3472 | 0 | } else { |
3473 | 0 | ret = offset - offset_orig; |
3474 | 0 | } |
3475 | |
|
3476 | 0 | return ret; |
3477 | 0 | } |
3478 | | |
3479 | | static int |
3480 | | // NOLINTNEXTLINE(misc-no-recursion) |
3481 | 0 | dissect_someip_payload_array_dim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset_orig, int length, unsigned lower_limit, unsigned upper_limit, someip_parameter_array_t *config, unsigned current_dim, char *name, uint32_t length_of_length) { |
3482 | 0 | proto_item *ti = NULL; |
3483 | 0 | proto_tree *subtree = NULL; |
3484 | 0 | int sub_length = 0; |
3485 | 0 | int sub_lower_limit = 0; |
3486 | 0 | int sub_upper_limit = 0; |
3487 | 0 | unsigned i; |
3488 | |
|
3489 | 0 | unsigned sub_offset; |
3490 | 0 | unsigned offset = offset_orig; |
3491 | |
|
3492 | 0 | if (config->num_of_dims == current_dim + 1) { |
3493 | | /* only payload left. :) */ |
3494 | 0 | offset += dissect_someip_payload_array_payload(tvb, pinfo, tree, offset, length, lower_limit, upper_limit, config); |
3495 | 0 | } else { |
3496 | 0 | if (length != -1) { |
3497 | 0 | while (offset < offset_orig + length) { |
3498 | 0 | sub_offset = offset; |
3499 | |
|
3500 | 0 | 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); |
3501 | 0 | subtree = proto_item_add_subtree(ti, ett_someip_array_dim); |
3502 | |
|
3503 | 0 | 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); |
3504 | |
|
3505 | 0 | if (tvb_captured_length_remaining(tvb, offset) < (unsigned)sub_length) { |
3506 | 0 | expert_someip_payload_truncated(subtree, pinfo, tvb, offset, (int)tvb_captured_length_remaining(tvb, offset)); |
3507 | 0 | return 0; |
3508 | 0 | } |
3509 | | |
3510 | 0 | 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); |
3511 | |
|
3512 | 0 | proto_item_set_end(ti, tvb, offset); |
3513 | 0 | } |
3514 | 0 | } else { |
3515 | | /* Multi-dim static array */ |
3516 | 0 | sub_lower_limit = config->dims[current_dim].lower_limit; |
3517 | 0 | sub_upper_limit = config->dims[current_dim].upper_limit; |
3518 | |
|
3519 | 0 | for (i = 0; i < upper_limit; i++) { |
3520 | 0 | 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); |
3521 | 0 | } |
3522 | 0 | } |
3523 | 0 | } |
3524 | | |
3525 | 0 | return offset - offset_orig; |
3526 | 0 | } |
3527 | | |
3528 | | static int |
3529 | | // NOLINTNEXTLINE(misc-no-recursion) |
3530 | 0 | dissect_someip_payload_array(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset_orig, uint32_t id, char *name, int *hf_id_ptr, int wtlv_offset) { |
3531 | 0 | someip_parameter_array_t *config = NULL; |
3532 | |
|
3533 | 0 | proto_tree *subtree; |
3534 | 0 | proto_item *ti = NULL; |
3535 | |
|
3536 | 0 | int offset = offset_orig; |
3537 | |
|
3538 | 0 | int length = 0; |
3539 | 0 | int size_of_length = 0; |
3540 | 0 | int lower_limit = 0; |
3541 | 0 | int upper_limit = 0; |
3542 | |
|
3543 | 0 | config = get_array_config(id); |
3544 | |
|
3545 | 0 | if (config == NULL) { |
3546 | 0 | return 0; |
3547 | 0 | } |
3548 | | |
3549 | 0 | if (config->num_of_dims == 0 || config->dims == NULL) { |
3550 | 0 | expert_someip_payload_config_error(tree, pinfo, tvb, offset, 0, "Array config has not enough dimensions for this array!"); |
3551 | 0 | return 0; |
3552 | 0 | } |
3553 | | |
3554 | 0 | int hf_id = 0; |
3555 | 0 | if (hf_id_ptr != NULL) |
3556 | 0 | { |
3557 | 0 | hf_id = *hf_id_ptr; |
3558 | 0 | } |
3559 | |
|
3560 | 0 | if (hf_id > 0) |
3561 | 0 | { |
3562 | 0 | int display_offset = (wtlv_offset >= 0) ? wtlv_offset : offset; |
3563 | 0 | ti = proto_tree_add_item(tree, hf_id, tvb, display_offset, 0, ENC_NA); |
3564 | 0 | proto_item_append_text(ti, " (array %s)", config->name); |
3565 | 0 | } |
3566 | 0 | else |
3567 | 0 | { |
3568 | 0 | ti = proto_tree_add_string_format(tree, hf_payload_str_array, tvb, offset, 0, config->name, "array %s", name); |
3569 | 0 | } |
3570 | 0 | subtree = proto_item_add_subtree(ti, ett_someip_array); |
3571 | |
|
3572 | 0 | uint32_t length_of_length = dissect_someip_payload_add_wtlv_if_needed(tvb, pinfo, wtlv_offset, ti, subtree); |
3573 | |
|
3574 | 0 | offset += dissect_someip_payload_array_dim_length(tvb, pinfo, subtree, offset_orig, &length, &lower_limit, &upper_limit, config, 0, length_of_length); |
3575 | 0 | size_of_length = offset - offset_orig; |
3576 | |
|
3577 | 0 | if (someip_deserializer_debugging_activated) { |
3578 | 0 | proto_item_append_text(ti, " [Debug: Array ID 0x%04x]", id); |
3579 | 0 | } |
3580 | |
|
3581 | 0 | offset += dissect_someip_payload_array_dim(tvb, pinfo, subtree, offset, length, lower_limit, upper_limit, config, 0, name, length_of_length); |
3582 | |
|
3583 | 0 | if (length >= 0) { |
3584 | | /* length field present */ |
3585 | 0 | int total = size_of_length + length; |
3586 | 0 | proto_item_set_end(ti, tvb, offset_orig + total); |
3587 | 0 | return total; |
3588 | 0 | } else { |
3589 | | /* We have no length field, so we return what has been parsed! */ |
3590 | 0 | int total = offset - offset_orig; |
3591 | 0 | proto_item_set_end(ti, tvb, offset_orig + total); |
3592 | 0 | return total; |
3593 | 0 | } |
3594 | 0 | } |
3595 | | |
3596 | | static int |
3597 | | // NOLINTNEXTLINE(misc-no-recursion) |
3598 | 0 | dissect_someip_payload_union(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset_orig, uint32_t id, char *name, int *hf_id_ptr, int wtlv_offset) { |
3599 | 0 | someip_parameter_union_t *config = NULL; |
3600 | 0 | someip_parameter_union_item_t *item = NULL; |
3601 | |
|
3602 | 0 | proto_item *ti = NULL; |
3603 | 0 | proto_tree *subtree = NULL; |
3604 | |
|
3605 | 0 | tvbuff_t *subtvb; |
3606 | 0 | int buf_length = -1; |
3607 | |
|
3608 | 0 | int64_t tmp = 0; |
3609 | 0 | uint32_t length = 0; |
3610 | 0 | uint32_t type = 0; |
3611 | |
|
3612 | 0 | uint32_t i = 0; |
3613 | |
|
3614 | 0 | int offset = offset_orig; |
3615 | |
|
3616 | 0 | config = get_union_config(id); |
3617 | 0 | buf_length = tvb_captured_length_remaining(tvb, 0); |
3618 | |
|
3619 | 0 | if (config == NULL) { |
3620 | 0 | expert_someip_payload_config_error(tree, pinfo, tvb, offset, 0, "Union ID not configured"); |
3621 | 0 | return 0; |
3622 | 0 | } |
3623 | | |
3624 | 0 | int hf_id = 0; |
3625 | 0 | if (hf_id_ptr != NULL) |
3626 | 0 | { |
3627 | 0 | hf_id = *hf_id_ptr; |
3628 | 0 | } |
3629 | |
|
3630 | 0 | const char *display_name = (name != NULL && name[0] != '\0') ? name : config->name; |
3631 | |
|
3632 | 0 | if (hf_id > 0) |
3633 | 0 | { |
3634 | 0 | int display_offset = (wtlv_offset >= 0) ? wtlv_offset : offset_orig; |
3635 | 0 | ti = proto_tree_add_item(tree, hf_id, tvb, display_offset, 0, ENC_NA); |
3636 | 0 | proto_item_append_text(ti, " (union %s)", config->name); |
3637 | 0 | } |
3638 | 0 | else if (wtlv_offset >= 0) |
3639 | 0 | { |
3640 | 0 | ti = proto_tree_add_string_format(tree, hf_payload_str_union, tvb, wtlv_offset, 0, display_name, "union %s [%s]", display_name, config->name); |
3641 | 0 | } |
3642 | 0 | else |
3643 | 0 | { |
3644 | 0 | ti = proto_tree_add_string_format(tree, hf_payload_str_union, tvb, offset_orig, 0, display_name, "union %s [%s]", display_name, config->name); |
3645 | 0 | } |
3646 | 0 | subtree = proto_item_add_subtree(ti, ett_someip_union); |
3647 | |
|
3648 | 0 | if (someip_deserializer_debugging_activated) { |
3649 | 0 | proto_item_append_text(ti, " [Debug: Union ID 0x%04x]", id); |
3650 | 0 | } |
3651 | |
|
3652 | 0 | uint32_t length_of_length = dissect_someip_payload_add_wtlv_if_needed(tvb, pinfo, wtlv_offset, ti, subtree); |
3653 | |
|
3654 | 0 | if (length_of_length == 0) { |
3655 | 0 | length_of_length = config->length_of_length; |
3656 | 0 | } |
3657 | |
|
3658 | 0 | if ((length_of_length + config->length_of_type) / 8 > (unsigned)buf_length - offset) { |
3659 | 0 | expert_someip_payload_truncated(tree, pinfo, tvb, offset, tvb_captured_length_remaining(tvb, offset)); |
3660 | 0 | return 0; |
3661 | 0 | } |
3662 | | |
3663 | 0 | tmp = dissect_someip_payload_length_field(tvb, pinfo, subtree, offset_orig, length_of_length); |
3664 | 0 | if (tmp == -1) { |
3665 | 0 | return offset - offset_orig; |
3666 | 0 | } else { |
3667 | 0 | length = (uint32_t)tmp; |
3668 | 0 | } |
3669 | | |
3670 | 0 | tmp = dissect_someip_payload_type_field(tvb, pinfo, subtree, offset_orig + length_of_length / 8, config->length_of_type); |
3671 | 0 | if (tmp == -1) { |
3672 | 0 | return offset - offset_orig; |
3673 | 0 | } else { |
3674 | 0 | type = (uint32_t)tmp; |
3675 | 0 | } |
3676 | | |
3677 | 0 | offset += (length_of_length + config->length_of_type) / 8; |
3678 | |
|
3679 | 0 | item = NULL; |
3680 | 0 | for (i = 0; i < config->num_of_items; i++) { |
3681 | 0 | if (config->items[i].id == type && config->items[i].name != NULL) { |
3682 | 0 | item = &(config->items[i]); |
3683 | 0 | } |
3684 | 0 | } |
3685 | |
|
3686 | 0 | if (item != NULL) { |
3687 | 0 | subtvb = tvb_new_subset_length(tvb, offset, length); |
3688 | 0 | dissect_someip_payload_parameter(subtvb, pinfo, subtree, 0, (uint8_t)item->data_type, item->id_ref, item->name, item->hf_id, -1); |
3689 | 0 | } else { |
3690 | 0 | expert_someip_payload_config_error(tree, pinfo, tvb, offset, 0, "Union type not configured"); |
3691 | 0 | } |
3692 | |
|
3693 | 0 | int total_len = length + (config->length_of_type + length_of_length) / 8; |
3694 | 0 | proto_item_set_end(ti, tvb, offset_orig + total_len); |
3695 | |
|
3696 | 0 | return total_len; |
3697 | 0 | } |
3698 | | |
3699 | | static int |
3700 | 0 | dissect_someip_payload_bitfield(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset_orig, uint32_t id, char *name, int *hf_id_ptr, int wtlv_offset) { |
3701 | 0 | proto_item *ti = NULL; |
3702 | 0 | proto_tree *subtree = NULL; |
3703 | 0 | int offset = offset_orig; |
3704 | |
|
3705 | 0 | someip_parameter_bitfield_t *config = NULL; |
3706 | 0 | config = get_bitfield_config(id); |
3707 | |
|
3708 | 0 | if (config == NULL) { |
3709 | 0 | expert_someip_payload_config_error(tree, pinfo, tvb, offset, 0, "Bitfield ID not configured"); |
3710 | 0 | return 0; |
3711 | 0 | } |
3712 | | |
3713 | 0 | unsigned number_of_bytes = config->number_of_bits / 8; |
3714 | |
|
3715 | 0 | if (number_of_bytes > (unsigned)tvb_captured_length_remaining(tvb, offset)) { |
3716 | 0 | expert_someip_payload_truncated(tree, pinfo, tvb, offset, tvb_captured_length_remaining(tvb, offset)); |
3717 | 0 | return 0; |
3718 | 0 | } |
3719 | | |
3720 | 0 | if (hf_id_ptr != NULL) { |
3721 | 0 | int hf_id = *hf_id_ptr; |
3722 | 0 | ti = proto_tree_add_item(tree, hf_id, tvb, offset_orig, number_of_bytes, ENC_BIG_ENDIAN); |
3723 | 0 | } else { |
3724 | 0 | ti = proto_tree_add_string_format(tree, hf_payload_str_bitfield, tvb, offset_orig, number_of_bytes, name, "bitfield %s [%s]", name, config->name); |
3725 | 0 | } |
3726 | 0 | dissect_someip_payload_add_wtlv_if_needed(tvb, pinfo, wtlv_offset, ti, NULL); |
3727 | 0 | subtree = proto_item_add_subtree(ti, ett_someip_bitfield); |
3728 | |
|
3729 | 0 | uint64_t value = 0; |
3730 | 0 | switch (config->number_of_bits) { |
3731 | 0 | case 64: |
3732 | 0 | value = tvb_get_uint64(tvb, offset, ENC_BIG_ENDIAN); |
3733 | 0 | break; |
3734 | 0 | case 32: |
3735 | 0 | value = tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN); |
3736 | 0 | break; |
3737 | 0 | case 16: |
3738 | 0 | value = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
3739 | 0 | break; |
3740 | 0 | default: |
3741 | 0 | case 8: |
3742 | 0 | value = tvb_get_uint8(tvb, offset); |
3743 | 0 | break; |
3744 | 0 | } |
3745 | | |
3746 | 0 | if (someip_deserializer_debugging_activated) { |
3747 | 0 | proto_item_append_text(ti, " [Debug: Bitfield ID 0x%04x]", id); |
3748 | 0 | } |
3749 | |
|
3750 | 0 | for (unsigned i = 0; i < config->num_of_items; i++) { |
3751 | 0 | someip_parameter_bitfield_item_t *item = &(config->items[i]); |
3752 | |
|
3753 | 0 | if (item->hf_id != NULL) { |
3754 | 0 | proto_tree_add_item(subtree, *(item->hf_id), tvb, offset_orig, number_of_bytes, ENC_BIG_ENDIAN); |
3755 | 0 | } else { |
3756 | 0 | uint32_t mask = (uint32_t)(1 << (item->bit_number)); |
3757 | 0 | proto_tree_add_boolean_format(subtree, hf_payload_bitfield_item, tvb, offset, number_of_bytes, value, "%s (bit %d): %d", item->bit_name, item->bit_number, (value & mask) != 0); |
3758 | 0 | } |
3759 | 0 | } |
3760 | |
|
3761 | 0 | return number_of_bytes; |
3762 | 0 | } |
3763 | | |
3764 | | static int |
3765 | | // NOLINTNEXTLINE(misc-no-recursion) |
3766 | | 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) |
3767 | 0 | { |
3768 | 0 | int bytes_parsed = 0; |
3769 | |
|
3770 | 0 | increment_dissection_depth(pinfo); |
3771 | 0 | switch (data_type) { |
3772 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_BASE_TYPE: |
3773 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_ENUM: |
3774 | 0 | bytes_parsed = dissect_someip_payload_base_type(tvb, pinfo, tree, offset, data_type, idref, name, hf_id_ptr, wtlv_offset); |
3775 | 0 | break; |
3776 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_STRING: |
3777 | 0 | bytes_parsed = dissect_someip_payload_string(tvb, pinfo, tree, offset, idref, name, hf_id_ptr, wtlv_offset); |
3778 | 0 | break; |
3779 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_ARRAY: |
3780 | 0 | bytes_parsed = dissect_someip_payload_array(tvb, pinfo, tree, offset, idref, name, hf_id_ptr, wtlv_offset); |
3781 | 0 | break; |
3782 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_STRUCT: |
3783 | 0 | bytes_parsed = dissect_someip_payload_struct(tvb, pinfo, tree, offset, idref, name, hf_id_ptr, wtlv_offset); |
3784 | 0 | break; |
3785 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_UNION: |
3786 | 0 | bytes_parsed = dissect_someip_payload_union(tvb, pinfo, tree, offset, idref, name, hf_id_ptr, wtlv_offset); |
3787 | 0 | break; |
3788 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_TYPEDEF: |
3789 | 0 | bytes_parsed = dissect_someip_payload_typedef(tvb, pinfo, tree, offset, idref, name, hf_id_ptr, wtlv_offset); |
3790 | 0 | break; |
3791 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_BITFIELD: |
3792 | 0 | bytes_parsed = dissect_someip_payload_bitfield(tvb, pinfo, tree, offset, idref, name, hf_id_ptr, wtlv_offset); |
3793 | 0 | break; |
3794 | 0 | default: |
3795 | 0 | proto_tree_add_expert_format(tree, pinfo, &ei_someip_payload_config_error, tvb, offset, 0, |
3796 | 0 | "SOME/IP: Payload: item->data_type (0x%x) unknown/not implemented yet! name: %s, id_ref: 0x%x", |
3797 | 0 | data_type, name, idref); |
3798 | 0 | col_append_str(pinfo->cinfo, COL_INFO, " [SOME/IP: Payload Config Error]"); |
3799 | 0 | break; |
3800 | 0 | } |
3801 | 0 | decrement_dissection_depth(pinfo); |
3802 | |
|
3803 | 0 | return bytes_parsed; |
3804 | 0 | } |
3805 | | |
3806 | | /* |
3807 | | * returns <0 for errors |
3808 | | */ |
3809 | 0 | static int dissect_someip_payload_peek_length_of_length(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, int length, someip_parameter_item_t *item) { |
3810 | 0 | if (item == NULL) { |
3811 | 0 | return -1; |
3812 | 0 | } |
3813 | | |
3814 | 0 | uint32_t data_type = item->data_type; |
3815 | 0 | uint32_t id_ref = item->id_ref; |
3816 | | |
3817 | | /* a config error could cause an endless loop, so we limit the number of indirections with loop_limit */ |
3818 | 0 | int loop_limit = 255; |
3819 | 0 | while (data_type == SOMEIP_PARAMETER_DATA_TYPE_TYPEDEF && loop_limit > 0) { |
3820 | 0 | someip_parameter_typedef_t *tmp = get_typedef_config(id_ref); |
3821 | 0 | data_type = tmp->data_type; |
3822 | 0 | id_ref = tmp->id_ref; |
3823 | 0 | loop_limit--; |
3824 | 0 | } |
3825 | |
|
3826 | 0 | someip_parameter_string_t *tmp_string_config; |
3827 | 0 | someip_parameter_array_t *tmp_array_config; |
3828 | 0 | someip_parameter_struct_t *tmp_struct_config; |
3829 | 0 | someip_parameter_union_t *tmp_union_config; |
3830 | |
|
3831 | 0 | switch (data_type) { |
3832 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_STRING: |
3833 | 0 | tmp_string_config = get_string_config(id_ref); |
3834 | 0 | if (tmp_string_config == NULL) { |
3835 | 0 | return -1; |
3836 | 0 | } |
3837 | | |
3838 | 0 | return tmp_string_config->length_of_length; |
3839 | | |
3840 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_ARRAY: |
3841 | 0 | tmp_array_config = get_array_config(id_ref); |
3842 | 0 | if (tmp_array_config == NULL) { |
3843 | 0 | return -1; |
3844 | 0 | } |
3845 | | |
3846 | 0 | if (tmp_array_config->num_of_dims < 1 || tmp_array_config->dims == NULL) { |
3847 | 0 | expert_someip_payload_config_error(tree, pinfo, tvb, offset, length, "array configuration does not support WTLV"); |
3848 | 0 | return -1; |
3849 | 0 | } |
3850 | | |
3851 | 0 | return tmp_array_config->dims[0].length_of_length; |
3852 | | |
3853 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_STRUCT: |
3854 | 0 | tmp_struct_config = get_struct_config(id_ref); |
3855 | 0 | if (tmp_struct_config == NULL) { |
3856 | 0 | return -1; |
3857 | 0 | } |
3858 | | |
3859 | 0 | return tmp_struct_config->length_of_length; |
3860 | | |
3861 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_UNION: |
3862 | 0 | tmp_union_config = get_union_config(id_ref); |
3863 | 0 | if (tmp_union_config == NULL) { |
3864 | 0 | return -1; |
3865 | 0 | } |
3866 | | |
3867 | 0 | return tmp_union_config->length_of_length; |
3868 | | |
3869 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_TYPEDEF: |
3870 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_BASE_TYPE: |
3871 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_ENUM: |
3872 | 0 | case SOMEIP_PARAMETER_DATA_TYPE_BITFIELD: |
3873 | 0 | default: |
3874 | | /* This happens only if configuration or message are buggy. */ |
3875 | 0 | return -2; |
3876 | 0 | } |
3877 | 0 | } |
3878 | | |
3879 | | static int |
3880 | | // NOLINTNEXTLINE(misc-no-recursion) |
3881 | 0 | dissect_someip_payload_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, someip_parameter_item_t *items, uint32_t num_of_items, bool wtlv) { |
3882 | 0 | someip_parameter_item_t *item; |
3883 | |
|
3884 | 0 | int offset_orig = offset; |
3885 | |
|
3886 | 0 | if (items == NULL && !someip_deserializer_wtlv_default) { |
3887 | 0 | return 0; |
3888 | 0 | } |
3889 | | |
3890 | 0 | if (wtlv) { |
3891 | 0 | while (tvb_captured_length_remaining(tvb, offset) >= 2) { |
3892 | 0 | uint64_t tagdata = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
3893 | 0 | unsigned wiretype = (tagdata & SOMEIP_WTLV_MASK_WIRE_TYPE) >> 12; |
3894 | 0 | unsigned param_id = tagdata & SOMEIP_WTLV_MASK_DATA_ID; |
3895 | 0 | offset += 2; |
3896 | |
|
3897 | 0 | if (param_id < num_of_items && items != NULL) { |
3898 | 0 | item = &(items[param_id]); |
3899 | 0 | } else { |
3900 | 0 | item = NULL; |
3901 | 0 | } |
3902 | |
|
3903 | 0 | unsigned param_length = 0; |
3904 | 0 | switch (wiretype) { |
3905 | | |
3906 | | /* fixed length type with just 1, 2, 4, or 8 byte length */ |
3907 | 0 | case 0: |
3908 | 0 | case 1: |
3909 | 0 | case 2: |
3910 | 0 | case 3: |
3911 | 0 | param_length = 1 << wiretype; |
3912 | 0 | break; |
3913 | | |
3914 | | /* var length types like structs, strings, arrays, and unions */ |
3915 | 0 | case 4: |
3916 | | /* this type is deprecated and should not be used*/ |
3917 | |
|
3918 | 0 | switch (dissect_someip_payload_peek_length_of_length(tree, pinfo, tvb, offset - 2, 0, item)) { |
3919 | 0 | case 8: |
3920 | 0 | param_length = 1 + tvb_get_uint8(tvb, offset); |
3921 | 0 | break; |
3922 | 0 | case 16: |
3923 | 0 | param_length = 2 + tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
3924 | 0 | break; |
3925 | 0 | case 32: |
3926 | 0 | param_length = 4 + tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN); |
3927 | 0 | break; |
3928 | 0 | default: |
3929 | 0 | expert_someip_payload_config_error(tree, pinfo, tvb, offset - 2, 2, "WTLV type 4 but datatype has not an appropriate length field configured"); |
3930 | 0 | return 8 * (offset - offset_orig); |
3931 | 0 | } |
3932 | 0 | break; |
3933 | | |
3934 | 0 | case 5: |
3935 | 0 | param_length = 1 + tvb_get_uint8(tvb, offset); |
3936 | 0 | break; |
3937 | 0 | case 6: |
3938 | 0 | param_length = 2 + tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
3939 | 0 | break; |
3940 | 0 | case 7: |
3941 | 0 | param_length = 4 + tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN); |
3942 | 0 | break; |
3943 | | |
3944 | 0 | default: |
3945 | | /* unsupported Wire Type!*/ |
3946 | 0 | expert_someip_payload_malformed(tree, pinfo, tvb, offset - 2, 2); |
3947 | 0 | break; |
3948 | 0 | } |
3949 | | |
3950 | 0 | tvbuff_t *subtvb = tvb_new_subset_length(tvb, offset - 2, param_length + 2); |
3951 | 0 | if (item != NULL) { |
3952 | 0 | dissect_someip_payload_parameter(subtvb, pinfo, tree, 2, (uint8_t)item->data_type, item->id_ref, item->name, item->hf_id, 0); |
3953 | 0 | } else { |
3954 | 0 | proto_item *ti = proto_tree_add_item(tree, hf_payload_unparsed, subtvb, 2, param_length, ENC_NA); |
3955 | 0 | dissect_someip_payload_add_wtlv_if_needed(tvb, pinfo, offset - 2, ti, NULL); |
3956 | 0 | } |
3957 | 0 | offset += param_length; |
3958 | 0 | } |
3959 | 0 | } else { |
3960 | 0 | if (items == NULL) { |
3961 | 0 | return 0; |
3962 | 0 | } |
3963 | 0 | uint32_t i; |
3964 | 0 | for (i = 0; i < num_of_items; i++) { |
3965 | 0 | item = &(items[i]); |
3966 | 0 | offset += dissect_someip_payload_parameter(tvb, pinfo, tree, offset, (uint8_t)item->data_type, item->id_ref, item->name, item->hf_id, -1); |
3967 | 0 | } |
3968 | 0 | } |
3969 | | |
3970 | 0 | return offset - offset_orig; |
3971 | 0 | } |
3972 | | |
3973 | | static void |
3974 | 0 | dissect_someip_payload(tvbuff_t *tvb, packet_info *pinfo, proto_item *ti, uint16_t serviceid, uint16_t methodid, uint8_t version, uint8_t msgtype) { |
3975 | 0 | unsigned length = 0; |
3976 | 0 | unsigned offset = 0; |
3977 | |
|
3978 | 0 | proto_tree *tree = NULL; |
3979 | |
|
3980 | 0 | length = tvb_captured_length_remaining(tvb, 0); |
3981 | 0 | tree = proto_item_add_subtree(ti, ett_someip_payload); |
3982 | 0 | someip_parameter_list_t *paramlist = get_parameter_config(serviceid, methodid, version, msgtype); |
3983 | |
|
3984 | 0 | if (paramlist == NULL) { |
3985 | 0 | if (someip_deserializer_wtlv_default) { |
3986 | 0 | offset += dissect_someip_payload_parameters(tvb, pinfo, tree, offset, NULL, 0, true); |
3987 | 0 | } else { |
3988 | 0 | return; |
3989 | 0 | } |
3990 | 0 | } else { |
3991 | 0 | offset += dissect_someip_payload_parameters(tvb, pinfo, tree, offset, paramlist->items, paramlist->num_of_items, paramlist->wtlv_encoding); |
3992 | 0 | } |
3993 | | |
3994 | 0 | if (length > offset) { |
3995 | 0 | proto_tree_add_item(tree, hf_payload_unparsed, tvb, offset, length - (offset), ENC_NA); |
3996 | 0 | } |
3997 | 0 | } |
3998 | | |
3999 | | /*********************************** |
4000 | | ******** SOME/IP Dissector ******** |
4001 | | ***********************************/ |
4002 | | |
4003 | | static int |
4004 | 0 | dissect_someip_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { |
4005 | 0 | uint32_t offset = 0; |
4006 | 0 | uint32_t someip_messageid = 0; |
4007 | 0 | uint32_t someip_serviceid = 0; |
4008 | 0 | uint32_t someip_methodid = 0; |
4009 | 0 | uint32_t someip_clientid = 0; |
4010 | 0 | uint32_t someip_sessionid = 0; |
4011 | 0 | uint32_t someip_length = 0; |
4012 | 0 | const char *service_description = NULL; |
4013 | 0 | const char *method_description = NULL; |
4014 | 0 | const char *client_description = NULL; |
4015 | 0 | someip_info_t someip_data = SOMEIP_INFO_T_INIT; |
4016 | |
|
4017 | 0 | uint32_t someip_payload_length = 0; |
4018 | 0 | tvbuff_t *subtvb = NULL; |
4019 | |
|
4020 | 0 | proto_item *ti = NULL; |
4021 | 0 | proto_item *ti_someip = NULL; |
4022 | 0 | proto_tree *someip_tree = NULL; |
4023 | 0 | proto_tree *msgtype_tree = NULL; |
4024 | |
|
4025 | 0 | uint32_t protocol_version = 0; |
4026 | 0 | uint32_t version = 0; |
4027 | 0 | uint32_t msgtype = 0; |
4028 | 0 | bool msgtype_ack = false; |
4029 | 0 | bool msgtype_tp = false; |
4030 | 0 | uint32_t retcode = 0; |
4031 | 0 | int tmp; |
4032 | |
|
4033 | 0 | int tvb_length = tvb_captured_length_remaining(tvb, offset); |
4034 | |
|
4035 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "SOME/IP"); |
4036 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "SOME/IP"); |
4037 | 0 | ti_someip = proto_tree_add_item(tree, proto_someip, tvb, offset, -1, ENC_NA); |
4038 | 0 | someip_tree = proto_item_add_subtree(ti_someip, ett_someip); |
4039 | | |
4040 | | /* we should never get called with less than 8 bytes */ |
4041 | 0 | if (tvb_length < 8) { |
4042 | 0 | return tvb_length; |
4043 | 0 | } |
4044 | | |
4045 | | /* Message ID = Service ID + Method ID*/ |
4046 | 0 | someip_messageid = tvb_get_ntohl(tvb, 0); |
4047 | 0 | ti = proto_tree_add_uint_format_value(someip_tree, hf_someip_messageid, tvb, offset, 4, someip_messageid, "0x%08x", someip_messageid); |
4048 | 0 | proto_item_set_hidden(ti); |
4049 | | |
4050 | | /* Service ID */ |
4051 | 0 | ti = proto_tree_add_item_ret_uint(someip_tree, hf_someip_serviceid, tvb, offset, 2, ENC_BIG_ENDIAN, &someip_serviceid); |
4052 | 0 | someip_data.service_id = someip_serviceid; |
4053 | 0 | service_description = someip_lookup_service_name(someip_serviceid); |
4054 | 0 | if (service_description != NULL) { |
4055 | 0 | proto_item_append_text(ti, " (%s)", service_description); |
4056 | 0 | ti = proto_tree_add_string(someip_tree, hf_someip_servicename, tvb, offset, 2, service_description); |
4057 | 0 | proto_item_set_generated(ti); |
4058 | 0 | proto_item_set_hidden(ti); |
4059 | 0 | } |
4060 | 0 | offset += 2; |
4061 | | |
4062 | | /* Method ID */ |
4063 | 0 | ti = proto_tree_add_item_ret_uint(someip_tree, hf_someip_methodid, tvb, offset, 2, ENC_BIG_ENDIAN, &someip_methodid); |
4064 | 0 | someip_data.method_id = someip_methodid; |
4065 | 0 | method_description = someip_lookup_method_name(someip_serviceid, someip_methodid); |
4066 | 0 | if (method_description != NULL) { |
4067 | 0 | proto_item_append_text(ti, " (%s)", method_description); |
4068 | 0 | ti = proto_tree_add_string(someip_tree, hf_someip_methodname , tvb, offset, 2, method_description); |
4069 | 0 | proto_item_set_generated(ti); |
4070 | 0 | proto_item_set_hidden(ti); |
4071 | 0 | } |
4072 | 0 | offset += 2; |
4073 | | |
4074 | | /* Length */ |
4075 | 0 | proto_tree_add_item_ret_uint(someip_tree, hf_someip_length, tvb, offset, 4, ENC_BIG_ENDIAN, &someip_length); |
4076 | 0 | offset += 4; |
4077 | | |
4078 | | /* this checks if value of the header field */ |
4079 | 0 | if (someip_length < 8) { |
4080 | 0 | expert_add_info_format(pinfo, ti_someip, &ei_someip_incomplete_headers, "%s", "SOME/IP length too short (<8 Bytes)!"); |
4081 | 0 | return tvb_length; |
4082 | 0 | } |
4083 | | |
4084 | | /* Add some additional info to the Protocol line and the Info Column*/ |
4085 | 0 | if (service_description == NULL) { |
4086 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " (Service ID: 0x%04x, Method ID: 0x%04x, Length: %i) ", someip_serviceid, someip_methodid, someip_length); |
4087 | 0 | } else if (method_description == NULL) { |
4088 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " (Service ID: 0x%04x (%s), Method ID: 0x%04x, Length: %i) ", someip_serviceid, service_description, someip_methodid, someip_length); |
4089 | 0 | } else { |
4090 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " (Service ID: 0x%04x (%s), Method ID: 0x%04x (%s), Length: %i) ", someip_serviceid, service_description, someip_methodid, method_description, someip_length); |
4091 | 0 | } |
4092 | 0 | proto_item_append_text(ti_someip, " (Service ID: 0x%04x, Method ID: 0x%04x, Length: %i)", someip_serviceid, someip_methodid, someip_length); |
4093 | | |
4094 | | /* check if we have bytes for the rest of the header */ |
4095 | 0 | if ((offset + 8) > (uint32_t)tvb_length) { |
4096 | 0 | expert_add_info_format(pinfo, ti_someip, &ei_someip_incomplete_headers, "%s", "SOME/IP not enough buffer bytes for header!"); |
4097 | 0 | return tvb_length; |
4098 | 0 | } |
4099 | | |
4100 | | /* Client ID */ |
4101 | 0 | ti = proto_tree_add_item_ret_uint(someip_tree, hf_someip_clientid, tvb, offset, 2, ENC_BIG_ENDIAN, &someip_clientid); |
4102 | 0 | someip_data.client_id = someip_clientid; |
4103 | 0 | client_description = someip_lookup_client_name(someip_serviceid, someip_clientid); |
4104 | 0 | if (client_description != NULL) { |
4105 | 0 | proto_item_append_text(ti, " (%s)", client_description); |
4106 | 0 | ti = proto_tree_add_string(someip_tree, hf_someip_clientname, tvb, offset, 2, client_description); |
4107 | 0 | proto_item_set_generated(ti); |
4108 | 0 | proto_item_set_hidden(ti); |
4109 | 0 | } |
4110 | 0 | offset += 2; |
4111 | | |
4112 | | /* Session ID */ |
4113 | 0 | proto_tree_add_item_ret_uint(someip_tree, hf_someip_sessionid, tvb, offset, 2, ENC_BIG_ENDIAN, &someip_sessionid); |
4114 | 0 | someip_data.session_id = someip_sessionid; |
4115 | 0 | offset += 2; |
4116 | | |
4117 | | /* Protocol Version*/ |
4118 | 0 | ti = proto_tree_add_item_ret_uint(someip_tree, hf_someip_protover, tvb, offset, 1, ENC_BIG_ENDIAN, &protocol_version); |
4119 | 0 | if (protocol_version!=SOMEIP_PROTOCOL_VERSION) { |
4120 | 0 | expert_add_info(pinfo, ti, &ei_someip_unknown_version); |
4121 | 0 | } |
4122 | 0 | offset += 1; |
4123 | | |
4124 | | /* Major Version of Service Interface */ |
4125 | 0 | proto_tree_add_item_ret_uint(someip_tree, hf_someip_interface_ver, tvb, offset, 1, ENC_BIG_ENDIAN, &version); |
4126 | 0 | someip_data.major_version = version; |
4127 | 0 | offset += 1; |
4128 | | |
4129 | | /* Message Type */ |
4130 | 0 | ti = proto_tree_add_item_ret_uint(someip_tree, hf_someip_messagetype, tvb, offset, 1, ENC_BIG_ENDIAN, &msgtype); |
4131 | 0 | someip_data.message_type = msgtype; |
4132 | 0 | msgtype_tree = proto_item_add_subtree(ti, ett_someip_msgtype); |
4133 | 0 | proto_tree_add_item_ret_boolean(msgtype_tree, hf_someip_messagetype_ack_flag, tvb, offset, 1, ENC_BIG_ENDIAN, &msgtype_ack); |
4134 | 0 | proto_tree_add_item_ret_boolean(msgtype_tree, hf_someip_messagetype_tp_flag, tvb, offset, 1, ENC_BIG_ENDIAN, &msgtype_tp); |
4135 | |
|
4136 | 0 | proto_item_append_text(ti, " (%s)", val_to_str_const((~SOMEIP_MSGTYPE_TP_MASK)&msgtype, someip_msg_type, "Unknown Message Type")); |
4137 | 0 | if (msgtype_tp) { |
4138 | 0 | proto_item_append_text(ti, " (%s)", SOMEIP_MSGTYPE_TP_STRING); |
4139 | 0 | } |
4140 | 0 | offset += 1; |
4141 | | |
4142 | | /* Return Code */ |
4143 | 0 | ti = proto_tree_add_item_ret_uint(someip_tree, hf_someip_returncode, tvb, offset, 1, ENC_BIG_ENDIAN, &retcode); |
4144 | 0 | proto_item_append_text(ti, " (%s)", val_to_str_const(retcode, someip_return_code, "Unknown Return Code")); |
4145 | 0 | offset += 1; |
4146 | | |
4147 | | /* lets figure out what we have for the rest */ |
4148 | 0 | if (((uint32_t)tvb_length >= (someip_length + 8)) ) { |
4149 | 0 | someip_payload_length = someip_length - SOMEIP_HDR_PART1_LEN; |
4150 | 0 | } else { |
4151 | 0 | someip_payload_length = tvb_length - SOMEIP_HDR_LEN; |
4152 | 0 | expert_add_info(pinfo, ti_someip, &ei_someip_message_truncated); |
4153 | 0 | } |
4154 | | |
4155 | | /* Is this a SOME/IP-TP segment? */ |
4156 | 0 | if (msgtype_tp) { |
4157 | 0 | uint32_t tp_offset = 0; |
4158 | 0 | bool tp_more_segments = false; |
4159 | 0 | bool update_col_info = true; |
4160 | 0 | fragment_head *someip_tp_head = NULL; |
4161 | 0 | proto_tree *tp_tree = NULL; |
4162 | |
|
4163 | 0 | ti = proto_tree_add_item(someip_tree, hf_someip_tp, tvb, offset, someip_payload_length, ENC_NA); |
4164 | 0 | tp_tree = proto_item_add_subtree(ti, ett_someip_tp); |
4165 | | |
4166 | | /* Unfortunately, with a bitmask set the value is always shifted and cannot be set directly. */ |
4167 | 0 | proto_tree_add_item_ret_uint(tp_tree, hf_someip_tp_offset_encoded, tvb, offset, 4, ENC_BIG_ENDIAN, &tp_offset); |
4168 | 0 | tp_offset <<= 4; |
4169 | 0 | proto_tree_add_item(tp_tree, hf_someip_tp_reserved, tvb, offset, 4, ENC_BIG_ENDIAN); |
4170 | 0 | proto_tree_add_item_ret_boolean(tp_tree, hf_someip_tp_more_segments, tvb, offset, 4, ENC_BIG_ENDIAN, &tp_more_segments); |
4171 | 0 | ti = proto_tree_add_uint(tp_tree, hf_someip_tp_offset, tvb, offset, 4, tp_offset); |
4172 | 0 | PROTO_ITEM_SET_GENERATED(ti); |
4173 | 0 | offset += 4; |
4174 | |
|
4175 | 0 | proto_tree_add_item(tp_tree, hf_someip_payload, tvb, offset, someip_payload_length - SOMEIP_TP_HDR_LEN, ENC_NA); |
4176 | |
|
4177 | 0 | if (someip_tp_reassemble && tvb_bytes_exist(tvb, offset, someip_payload_length - SOMEIP_TP_HDR_LEN)) { |
4178 | 0 | someip_tp_head = fragment_add_check(&someip_tp_reassembly_table, tvb, offset, pinfo, 0, |
4179 | 0 | &someip_data, tp_offset, someip_payload_length - SOMEIP_TP_HDR_LEN, tp_more_segments); |
4180 | 0 | subtvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled SOME/IP-TP Segment", |
4181 | 0 | someip_tp_head, &someip_tp_frag_items, &update_col_info, someip_tree); |
4182 | 0 | } |
4183 | 0 | } else { |
4184 | 0 | subtvb = tvb_new_subset_length(tvb, SOMEIP_HDR_LEN, someip_payload_length); |
4185 | 0 | } |
4186 | |
|
4187 | 0 | if (subtvb != NULL) { |
4188 | | /* TAP */ |
4189 | 0 | if (have_tap_listener(tap_someip_messages)) { |
4190 | 0 | someip_messages_tap_t *stats_data = wmem_alloc(pinfo->pool, sizeof(someip_messages_tap_t)); |
4191 | 0 | stats_data->service_id = (uint16_t)someip_serviceid; |
4192 | 0 | stats_data->method_id = (uint16_t)someip_methodid; |
4193 | 0 | stats_data->interface_version = (uint8_t)version; |
4194 | 0 | stats_data->message_type = (uint8_t)(~SOMEIP_MSGTYPE_TP_MASK) & msgtype; |
4195 | |
|
4196 | 0 | tap_queue_packet(tap_someip_messages, pinfo, stats_data); |
4197 | 0 | } |
4198 | |
|
4199 | 0 | tvb_length = tvb_captured_length_remaining(subtvb, 0); |
4200 | 0 | if (tvb_length > 0) { |
4201 | 0 | tmp = dissector_try_uint_with_data(someip_dissector_table, someip_messageid, subtvb, pinfo, tree, false, &someip_data); |
4202 | | |
4203 | | /* if no subdissector was found, the generic payload dissector takes over. */ |
4204 | 0 | if (tmp==0) { |
4205 | 0 | ti = proto_tree_add_item(someip_tree, hf_someip_payload, subtvb, 0, tvb_length, ENC_NA); |
4206 | |
|
4207 | 0 | if (someip_deserializer_activated) { |
4208 | 0 | dissect_someip_payload(subtvb, pinfo, ti, (uint16_t)someip_serviceid, (uint16_t)someip_methodid, (uint8_t)version, (uint8_t)(~SOMEIP_MSGTYPE_TP_MASK)&msgtype); |
4209 | 0 | } else { |
4210 | 0 | expert_add_info(pinfo, ti, &ei_someip_payload_disabled); |
4211 | 0 | } |
4212 | 0 | } |
4213 | 0 | } |
4214 | 0 | } |
4215 | |
|
4216 | 0 | col_set_fence(pinfo->cinfo, COL_INFO); |
4217 | 0 | return SOMEIP_HDR_LEN + someip_payload_length; |
4218 | 0 | } |
4219 | | |
4220 | | static bool |
4221 | 0 | test_someip(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) { |
4222 | 0 | if (tvb_captured_length_remaining(tvb, offset) < SOMEIP_HDR_LEN) { |
4223 | 0 | return false; |
4224 | 0 | } |
4225 | | |
4226 | 0 | if (tvb_get_uint32(tvb, offset + 4, ENC_BIG_ENDIAN) < 8) { |
4227 | 0 | return false; |
4228 | 0 | } |
4229 | | |
4230 | 0 | if ((tvb_get_uint8(tvb, offset + 12)) != SOMEIP_PROTOCOL_VERSION) { |
4231 | 0 | return false; |
4232 | 0 | } |
4233 | | |
4234 | 0 | if (!try_val_to_str((tvb_get_uint8(tvb, offset + 14) & ~SOMEIP_MSGTYPE_TP_MASK), someip_msg_type)) { |
4235 | 0 | return false; |
4236 | 0 | } |
4237 | | |
4238 | 0 | return true; |
4239 | 0 | } |
4240 | | |
4241 | | static unsigned |
4242 | 0 | get_someip_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) { |
4243 | 0 | if (someip_test_tcp_for_valid_someip && !test_someip(pinfo, tvb, offset, data)) { |
4244 | 0 | return tvb_captured_length_remaining(tvb, offset); |
4245 | 0 | } |
4246 | | |
4247 | 0 | return SOMEIP_HDR_PART1_LEN + (unsigned)tvb_get_ntohl(tvb, offset + 4); |
4248 | 0 | } |
4249 | | |
4250 | | static int |
4251 | 0 | dissect_someip_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { |
4252 | 0 | tcp_dissect_pdus(tvb, pinfo, tree, true, SOMEIP_HDR_LEN, get_someip_message_len, dissect_someip_message, data); |
4253 | 0 | return tvb_reported_length(tvb); |
4254 | 0 | } |
4255 | | |
4256 | | static bool |
4257 | 0 | could_this_be_dtls(tvbuff_t *tvb) { |
4258 | | /* Headers compared |
4259 | | * |
4260 | | * Byte | SOME/IP | DTLS |
4261 | | * -------------------------------- |
4262 | | * 00 | Service ID | Content Type |
4263 | | * 01 | Service ID | Version |
4264 | | * 02 | Method ID | Version |
4265 | | * 03 | Method ID | Epoch |
4266 | | * 04 | Length | Epoch |
4267 | | * 05 | Length | Sequence Counter |
4268 | | * 06 | Length | Sequence Counter |
4269 | | * 07 | Length | Sequence Counter |
4270 | | * 08 | Client ID | Sequence Counter |
4271 | | * 09 | Client ID | Sequence Counter |
4272 | | * 10 | Session ID | Sequence Counter |
4273 | | * 11 | Session ID | Length |
4274 | | * 12 | SOME/IP Ver | Length |
4275 | | * 13 | Iface Ver | ... |
4276 | | * 14 | Msg Type | ... |
4277 | | * 15 | Return Code | ... |
4278 | | * 16 | ... | ... |
4279 | | */ |
4280 | 0 | int length = tvb_captured_length_remaining(tvb, 0); |
4281 | | |
4282 | | /* DTLS header is 13 bytes. */ |
4283 | 0 | if (length < 13) { |
4284 | | /* not sure what we have here ... */ |
4285 | 0 | return false; |
4286 | 0 | } |
4287 | | |
4288 | 0 | uint8_t dtls_content_type = tvb_get_uint8(tvb, 0); |
4289 | 0 | uint16_t dtls_version = tvb_get_uint16(tvb, 1, ENC_BIG_ENDIAN); |
4290 | 0 | uint16_t dtls_length = tvb_get_uint16(tvb, 11, ENC_BIG_ENDIAN); |
4291 | |
|
4292 | 0 | bool dtls_possible = (20 <= dtls_content_type) && (dtls_content_type <= 63) && |
4293 | 0 | (0xfefc <= dtls_version) && (dtls_version <= 0xfeff) && |
4294 | 0 | ((uint32_t)length == (uint32_t)dtls_length + 13); |
4295 | |
|
4296 | 0 | if (dtls_possible && length < SOMEIP_HDR_LEN) { |
4297 | 0 | return true; |
4298 | 0 | } |
4299 | | |
4300 | 0 | uint32_t someip_length = tvb_get_uint32(tvb, 4, ENC_BIG_ENDIAN); |
4301 | 0 | uint8_t someip_version = tvb_get_uint8(tvb, 12); |
4302 | | |
4303 | | /* typically this is 1500 bytes or less on UDP but being conservative */ |
4304 | 0 | bool someip_possible = (someip_version == 1) && (8 <= someip_length) && (someip_length <= 65535) && |
4305 | 0 | ((uint32_t)length == someip_length + 8); |
4306 | |
|
4307 | 0 | return dtls_possible && !someip_possible; |
4308 | 0 | } |
4309 | | |
4310 | | static int |
4311 | 0 | dissect_someip_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { |
4312 | 0 | if (someip_detect_dtls && could_this_be_dtls(tvb)) { |
4313 | 0 | if (!PINFO_FD_VISITED(pinfo)) { |
4314 | 0 | dissector_add_uint("dtls.port", (uint16_t)pinfo->destport, someip_handle_udp); |
4315 | 0 | } |
4316 | |
|
4317 | 0 | if (dtls_handle != 0) { |
4318 | 0 | return call_dissector_with_data(dtls_handle, tvb, pinfo, tree, data); |
4319 | 0 | } |
4320 | 0 | } |
4321 | | |
4322 | 0 | return udp_dissect_pdus(tvb, pinfo, tree, SOMEIP_HDR_PART1_LEN, NULL, get_someip_message_len, dissect_someip_message, data); |
4323 | 0 | } |
4324 | | |
4325 | | static bool |
4326 | 0 | dissect_some_ip_heur_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { |
4327 | 0 | if (test_someip(pinfo, tvb, 0, data)) { |
4328 | 0 | tcp_dissect_pdus(tvb, pinfo, tree, true, SOMEIP_HDR_PART1_LEN, get_someip_message_len, dissect_someip_message, data); |
4329 | 0 | return true; |
4330 | 0 | } |
4331 | 0 | return false; |
4332 | 0 | } |
4333 | | |
4334 | | static bool |
4335 | 0 | dissect_some_ip_heur_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { |
4336 | 0 | return (udp_dissect_pdus(tvb, pinfo, tree, SOMEIP_HDR_PART1_LEN, test_someip, get_someip_message_len, dissect_someip_message, data) != 0); |
4337 | 0 | } |
4338 | | |
4339 | | void |
4340 | 15 | proto_register_someip(void) { |
4341 | 15 | expert_module_t *expert_module_someip; |
4342 | | |
4343 | 15 | uat_t *someip_service_uat; |
4344 | 15 | uat_t *someip_method_uat; |
4345 | 15 | uat_t *someip_eventgroup_uat; |
4346 | 15 | uat_t *someip_client_uat; |
4347 | | |
4348 | 15 | uat_t *someip_parameter_list_uat; |
4349 | 15 | uat_t *someip_parameter_base_type_list_uat; |
4350 | 15 | uat_t *someip_parameter_strings_uat; |
4351 | 15 | uat_t *someip_parameter_arrays_uat; |
4352 | 15 | uat_t *someip_parameter_structs_uat; |
4353 | 15 | uat_t *someip_parameter_unions_uat; |
4354 | 15 | uat_t *someip_parameter_typedefs_uat; |
4355 | 15 | uat_t *someip_parameter_enums_uat; |
4356 | 15 | uat_t *someip_parameter_bitfields_uat; |
4357 | | |
4358 | | /* data fields */ |
4359 | 15 | static hf_register_info hf[] = { |
4360 | 15 | { &hf_someip_serviceid, |
4361 | 15 | { "Service ID", "someip.serviceid", |
4362 | 15 | FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
4363 | 15 | { &hf_someip_servicename, |
4364 | 15 | { "Service Name", "someip.servicename", |
4365 | 15 | FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
4366 | 15 | { &hf_someip_methodid, |
4367 | 15 | { "Method ID", "someip.methodid", |
4368 | 15 | FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
4369 | 15 | { &hf_someip_methodname, |
4370 | 15 | { "Method Name", "someip.methodname", |
4371 | 15 | FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
4372 | 15 | { &hf_someip_messageid, |
4373 | 15 | { "Message ID", "someip.messageid", |
4374 | 15 | FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
4375 | 15 | { &hf_someip_length, |
4376 | 15 | { "Length", "someip.length", |
4377 | 15 | FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
4378 | 15 | { &hf_someip_clientid, |
4379 | 15 | { "Client ID", "someip.clientid", |
4380 | 15 | FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
4381 | 15 | { &hf_someip_clientname, |
4382 | 15 | { "Client Name", "someip.clientname", |
4383 | 15 | FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
4384 | 15 | { &hf_someip_sessionid, |
4385 | 15 | { "Session ID", "someip.sessionid", |
4386 | 15 | FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
4387 | 15 | { &hf_someip_protover, |
4388 | 15 | { "SOME/IP Version", "someip.protoversion", |
4389 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
4390 | 15 | { &hf_someip_interface_ver, |
4391 | 15 | { "Interface Version", "someip.interfaceversion", |
4392 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
4393 | 15 | { &hf_someip_messagetype, |
4394 | 15 | { "Message Type", "someip.messagetype", |
4395 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
4396 | 15 | { &hf_someip_messagetype_ack_flag, |
4397 | 15 | { "Message Type Ack Flag", "someip.messagetype.ack", |
4398 | 15 | FT_BOOLEAN, 8, NULL, SOMEIP_MSGTYPE_ACK_MASK, NULL, HFILL }}, |
4399 | 15 | { &hf_someip_messagetype_tp_flag, |
4400 | 15 | { "Message Type TP Flag", "someip.messagetype.tp", |
4401 | 15 | FT_BOOLEAN, 8, NULL, SOMEIP_MSGTYPE_TP_MASK, NULL, HFILL }}, |
4402 | 15 | { &hf_someip_returncode, |
4403 | 15 | { "Return Code", "someip.returncode", |
4404 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
4405 | | |
4406 | 15 | { &hf_someip_payload, |
4407 | 15 | { "Payload", "someip.payload", |
4408 | 15 | FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
4409 | | |
4410 | 15 | { &hf_someip_tp, |
4411 | 15 | { "SOME/IP-TP", "someip.tp", |
4412 | 15 | FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
4413 | 15 | { &hf_someip_tp_offset, |
4414 | 15 | { "Offset", "someip.tp.offset", |
4415 | 15 | FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
4416 | 15 | { &hf_someip_tp_offset_encoded, |
4417 | 15 | { "Encoded Offset", "someip.tp.offset_encoded", |
4418 | 15 | FT_UINT32, BASE_HEX, NULL, SOMEIP_TP_OFFSET_MASK, NULL, HFILL }}, |
4419 | 15 | { &hf_someip_tp_flags, |
4420 | 15 | { "Flags", "someip.tp.flags", |
4421 | 15 | FT_UINT32, BASE_HEX, NULL, SOMEIP_TP_OFFSET_MASK_FLAGS, NULL, HFILL }}, |
4422 | 15 | { &hf_someip_tp_reserved, |
4423 | 15 | { "Reserved", "someip.tp.flags.reserved", |
4424 | 15 | FT_UINT32, BASE_HEX, NULL, SOMEIP_TP_OFFSET_MASK_RESERVED, NULL, HFILL }}, |
4425 | 15 | { &hf_someip_tp_more_segments, |
4426 | 15 | { "More Segments", "someip.tp.flags.more_segments", |
4427 | 15 | FT_BOOLEAN, 32, NULL, SOMEIP_TP_OFFSET_MASK_MORE_SEGMENTS, NULL, HFILL }}, |
4428 | | |
4429 | 15 | {&hf_someip_tp_fragments, |
4430 | 15 | {"SOME/IP-TP segments", "someip.tp.fragments", |
4431 | 15 | FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
4432 | 15 | {&hf_someip_tp_fragment, |
4433 | 15 | {"SOME/IP-TP segment", "someip.tp.fragment", |
4434 | 15 | FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
4435 | 15 | {&hf_someip_tp_fragment_overlap, |
4436 | 15 | {"SOME/IP-TP segment overlap", "someip.tp.fragment.overlap", |
4437 | 15 | FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
4438 | 15 | {&hf_someip_tp_fragment_overlap_conflicts, |
4439 | 15 | {"SOME/IP-TP segment overlapping with conflicting data", "someip.tp.fragment.overlap.conflicts", |
4440 | 15 | FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
4441 | 15 | {&hf_someip_tp_fragment_multiple_tails, |
4442 | 15 | {"SOME/IP-TP Message has multiple tail fragments", "someip.tp.fragment.multiple_tails", |
4443 | 15 | FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
4444 | 15 | {&hf_someip_tp_fragment_too_long_fragment, |
4445 | 15 | {"SOME/IP-TP segment too long", "someip.tp.fragment.too_long_fragment", |
4446 | 15 | FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
4447 | 15 | {&hf_someip_tp_fragment_error, |
4448 | 15 | {"SOME/IP-TP Message defragmentation error", "someip.tp.fragment.error", |
4449 | 15 | FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
4450 | 15 | {&hf_someip_tp_fragment_count, |
4451 | 15 | {"SOME/IP-TP segment count", "someip.tp.fragment.count", |
4452 | 15 | FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }, |
4453 | 15 | {&hf_someip_tp_reassembled_in, |
4454 | 15 | {"Reassembled in", "someip.tp.reassembled.in", |
4455 | 15 | FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
4456 | 15 | {&hf_someip_tp_reassembled_length, |
4457 | 15 | {"Reassembled length", "someip.tp.reassembled.length", |
4458 | 15 | FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }, |
4459 | | |
4460 | 15 | {&hf_someip_tp_reassembled_data, |
4461 | 15 | {"Reassembled data", "someip.tp.reassembled.data", |
4462 | 15 | FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
4463 | | |
4464 | 15 | { &hf_payload_unparsed, |
4465 | 15 | { "Unparsed Payload", "someip.payload.unparsed", |
4466 | 15 | FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
4467 | 15 | { &hf_payload_length_field_8bit, |
4468 | 15 | { "Length", "someip.payload.length", |
4469 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
4470 | 15 | { &hf_payload_length_field_16bit, |
4471 | 15 | { "Length", "someip.payload.length", |
4472 | 15 | FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
4473 | 15 | { &hf_payload_length_field_32bit, |
4474 | 15 | { "Length", "someip.payload.length", |
4475 | 15 | FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
4476 | 15 | { &hf_payload_type_field_8bit, |
4477 | 15 | { "Type", "someip.payload.type", |
4478 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
4479 | 15 | { &hf_payload_type_field_16bit, |
4480 | 15 | { "Type", "someip.payload.type", |
4481 | 15 | FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
4482 | 15 | { &hf_payload_type_field_32bit, |
4483 | 15 | { "Type", "someip.payload.type", |
4484 | 15 | FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
4485 | | |
4486 | | |
4487 | 15 | { &hf_payload_str_base, { |
4488 | 15 | "(base)", "someip.payload.base", |
4489 | 15 | FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
4490 | 15 | { &hf_payload_str_string, { |
4491 | 15 | "(string)", "someip.payload.string", |
4492 | 15 | FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
4493 | 15 | { &hf_payload_str_array, { |
4494 | 15 | "(array)", "someip.payload.array", |
4495 | 15 | FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
4496 | 15 | { &hf_payload_str_struct, { |
4497 | 15 | "(struct)", "someip.payload.struct", |
4498 | 15 | FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
4499 | 15 | { &hf_payload_str_union, { |
4500 | 15 | "(union)", "someip.payload.union", |
4501 | 15 | FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
4502 | 15 | { &hf_payload_str_bitfield, { |
4503 | 15 | "(bitfield)", "someip.payload.bitfield", |
4504 | 15 | FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
4505 | 15 | { &hf_payload_bitfield_item, { |
4506 | 15 | "bit", "someip.payload.bitfield.bit", |
4507 | 15 | FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
4508 | | |
4509 | 15 | { &hf_payload_wtlv_tag, { |
4510 | 15 | "WTLV-TAG", "someip.payload.wtlvtag", |
4511 | 15 | FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } }, |
4512 | 15 | { &hf_payload_wtlv_tag_res, { |
4513 | 15 | "Reserved", "someip.payload.wtlvtag.res", |
4514 | 15 | FT_UINT16, BASE_DEC, NULL, SOMEIP_WTLV_MASK_RES, NULL, HFILL } }, |
4515 | 15 | { &hf_payload_wtlv_tag_wire_type, { |
4516 | 15 | "Wire Type", "someip.payload.wtlvtag.wire_type", |
4517 | 15 | FT_UINT16, BASE_DEC, NULL, SOMEIP_WTLV_MASK_WIRE_TYPE, NULL, HFILL } }, |
4518 | 15 | { &hf_payload_wtlv_tag_data_id, { |
4519 | 15 | "Data ID", "someip.payload.wtlvtag.data_id", |
4520 | 15 | FT_UINT16, BASE_DEC, NULL, SOMEIP_WTLV_MASK_DATA_ID, NULL, HFILL } }, |
4521 | 15 | }; |
4522 | | |
4523 | 15 | static int *ett[] = { |
4524 | 15 | &ett_someip, |
4525 | 15 | &ett_someip_msgtype, |
4526 | 15 | &ett_someip_tp, |
4527 | 15 | &ett_someip_tp_fragment, |
4528 | 15 | &ett_someip_tp_fragments, |
4529 | | |
4530 | 15 | &ett_someip_payload, |
4531 | 15 | &ett_someip_string, |
4532 | 15 | &ett_someip_array, |
4533 | 15 | &ett_someip_array_dim, |
4534 | 15 | &ett_someip_struct, |
4535 | 15 | &ett_someip_union, |
4536 | 15 | &ett_someip_bitfield, |
4537 | | |
4538 | 15 | &ett_someip_parameter, |
4539 | 15 | &ett_someip_wtlv_tag, |
4540 | 15 | }; |
4541 | | |
4542 | | |
4543 | | /* UATs for user_data fields */ |
4544 | 15 | static uat_field_t someip_service_uat_fields[] = { |
4545 | 15 | UAT_FLD_HEX(someip_service_ident, id, "Service ID", "ID of the SOME/IP Service (16bit hex without leading 0x)"), |
4546 | 15 | UAT_FLD_CSTRING(someip_service_ident, name, "Service Name", "Name of the SOME/IP Service (string)"), |
4547 | 15 | UAT_END_FIELDS |
4548 | 15 | }; |
4549 | | |
4550 | 15 | static uat_field_t someip_method_uat_fields[] = { |
4551 | 15 | UAT_FLD_HEX(someip_method_ident, id, "Service ID", "ID of the SOME/IP Service (16bit hex without leading 0x)"), |
4552 | 15 | UAT_FLD_HEX(someip_method_ident, id2, "Methods ID", "ID of the SOME/IP Method/Event/Notifier (16bit hex without leading 0x)"), |
4553 | 15 | UAT_FLD_CSTRING(someip_method_ident, name, "Method Name", "Name of the SOME/IP Method/Event/Notifier (string)"), |
4554 | 15 | UAT_END_FIELDS |
4555 | 15 | }; |
4556 | | |
4557 | 15 | static uat_field_t someip_eventgroup_uat_fields[] = { |
4558 | 15 | UAT_FLD_HEX(someip_eventgroup_ident, id, "Service ID", "ID of the SOME/IP Service (16bit hex without leading 0x)"), |
4559 | 15 | UAT_FLD_HEX(someip_eventgroup_ident, id2, "Eventgroup ID", "ID of the SOME/IP Eventgroup (16bit hex without leading 0x)"), |
4560 | 15 | UAT_FLD_CSTRING(someip_eventgroup_ident, name, "Eventgroup Name", "Name of the SOME/IP Service (string)"), |
4561 | 15 | UAT_END_FIELDS |
4562 | 15 | }; |
4563 | | |
4564 | 15 | static uat_field_t someip_client_uat_fields[] = { |
4565 | 15 | UAT_FLD_HEX(someip_client_ident, id, "Service ID", "ID of the SOME/IP Service (16bit hex without leading 0x)"), |
4566 | 15 | UAT_FLD_HEX(someip_client_ident, id2, "Client ID", "ID of the SOME/IP Client (16bit hex without leading 0x)"), |
4567 | 15 | UAT_FLD_CSTRING(someip_client_ident, name, "Client Name", "Name of the SOME/IP Client (string)"), |
4568 | 15 | UAT_END_FIELDS |
4569 | 15 | }; |
4570 | | |
4571 | 15 | static uat_field_t someip_parameter_list_uat_fields[] = { |
4572 | 15 | UAT_FLD_HEX(someip_parameter_list, service_id, "Service ID", "ID of the SOME/IP Service (16bit hex without leading 0x)"), |
4573 | 15 | UAT_FLD_HEX(someip_parameter_list, method_id, "Method ID", "ID of the SOME/IP Method/Event/Notifier (16bit hex without leading 0x)"), |
4574 | 15 | UAT_FLD_DEC(someip_parameter_list, version, "Version", "Version of the SOME/IP Service (8bit dec)"), |
4575 | 15 | UAT_FLD_HEX(someip_parameter_list, message_type, "Message Type", "Message Type (8bit hex without leading 0x) (0: request, 1: request_no_return, 2: event, 0x80: response, 0x81: exception)"), |
4576 | 15 | 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)"), |
4577 | | |
4578 | 15 | 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"), |
4579 | | |
4580 | 15 | UAT_FLD_DEC(someip_parameter_list, pos, "Parameter Position/ID", "Position or ID of parameter (16bit dec, starting with 0)"), |
4581 | 15 | UAT_FLD_CSTRING(someip_parameter_list, name, "Parameter Name", "Name of parameter (string)"), |
4582 | 15 | 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, 8: bitfield)"), |
4583 | 15 | UAT_FLD_HEX(someip_parameter_list, id_ref, "ID Reference", "ID Reference (32bit hex)"), |
4584 | 15 | UAT_FLD_CSTRING(someip_parameter_list, filter_string, "Filter String", "Unique filter string that will be prepended with someip.payload. (string)"), |
4585 | 15 | UAT_END_FIELDS |
4586 | 15 | }; |
4587 | | |
4588 | 15 | static uat_field_t someip_parameter_base_type_list_uat_fields[] = { |
4589 | 15 | UAT_FLD_HEX(someip_parameter_base_type_list, id, "ID ", "ID (32bit hex)"), |
4590 | 15 | UAT_FLD_CSTRING(someip_parameter_base_type_list, name, "Name", "Name of type (string)"), |
4591 | 15 | UAT_FLD_CSTRING(someip_parameter_base_type_list, data_type, "Data Type", "Data type (string)"), |
4592 | 15 | UAT_FLD_BOOL(someip_parameter_base_type_list, big_endian, "Big Endian", "Encoded Big Endian"), |
4593 | 15 | UAT_FLD_DEC(someip_parameter_base_type_list, bitlength_base_type, "Bitlength base type", "Bitlength base type (uint32 dec)"), |
4594 | 15 | UAT_FLD_DEC(someip_parameter_base_type_list, bitlength_encoded_type, "Bitlength enc. type", "Bitlength encoded type (uint32 dec)"), |
4595 | 15 | UAT_END_FIELDS |
4596 | 15 | }; |
4597 | | |
4598 | 15 | static uat_field_t someip_parameter_string_list_uat_fields[] = { |
4599 | 15 | UAT_FLD_HEX(someip_parameter_strings, id, "ID ", "ID (32bit hex)"), |
4600 | 15 | UAT_FLD_CSTRING(someip_parameter_strings, name, "Name", "Name of string (string)"), |
4601 | 15 | UAT_FLD_CSTRING(someip_parameter_strings, encoding, "Encoding", "String Encoding (ascii, utf-8, utf-16)"), |
4602 | 15 | UAT_FLD_BOOL(someip_parameter_strings, dynamic_length, "Dynamic Length", "Dynamic length of string"), |
4603 | 15 | UAT_FLD_DEC(someip_parameter_strings, max_length, "Max. Length", "Maximum length/Length (uint32 dec)"), |
4604 | 15 | UAT_FLD_DEC(someip_parameter_strings, length_of_length, "Length of Len Field", "Length of the length field in bits (uint8 dec)"), |
4605 | 15 | UAT_FLD_BOOL(someip_parameter_strings, big_endian, "Big Endian", "Encoded Big Endian"), |
4606 | 15 | UAT_FLD_DEC(someip_parameter_strings, pad_to, "Pad to", "Padding pads to reach alignment (8bit dec)"), |
4607 | 15 | UAT_END_FIELDS |
4608 | 15 | }; |
4609 | | |
4610 | 15 | static uat_field_t someip_parameter_array_uat_fields[] = { |
4611 | 15 | UAT_FLD_HEX(someip_parameter_arrays, id, "ID", "ID of SOME/IP array (32bit hex without leading 0x)"), |
4612 | 15 | UAT_FLD_CSTRING(someip_parameter_arrays, name, "Array Name", "Name of array"), |
4613 | 15 | 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, 8: bitfield)"), |
4614 | 15 | UAT_FLD_HEX(someip_parameter_arrays, id_ref, "ID Reference", "ID Reference (32bit hex)"), |
4615 | 15 | UAT_FLD_DEC(someip_parameter_arrays, num_of_dims, "Number of Items", "Number of Dimensions (16bit dec)"), |
4616 | 15 | UAT_FLD_CSTRING(someip_parameter_arrays, filter_string, "Filter String", "Unique filter string that will be prepended with someip.payload. (string)"), |
4617 | | |
4618 | 15 | UAT_FLD_DEC(someip_parameter_arrays, num, "Dimension", "Dimension (16bit dec, starting with 0)"), |
4619 | 15 | UAT_FLD_DEC(someip_parameter_arrays, lower_limit, "Lower Limit", "Dimension (32bit dec)"), |
4620 | 15 | UAT_FLD_DEC(someip_parameter_arrays, upper_limit, "Upper Limit", "Dimension (32bit dec)"), |
4621 | 15 | UAT_FLD_DEC(someip_parameter_arrays, length_of_length, "Length of Length Field", "Length of the arrays length field in bits (8bit dec)"), |
4622 | 15 | UAT_FLD_DEC(someip_parameter_arrays, pad_to, "Pad to", "Padding pads to reach alignment (8bit dec)"), |
4623 | 15 | UAT_END_FIELDS |
4624 | 15 | }; |
4625 | | |
4626 | 15 | static uat_field_t someip_parameter_struct_uat_fields[] = { |
4627 | 15 | UAT_FLD_HEX(someip_parameter_structs, id, "ID", "ID of SOME/IP struct (32bit hex without leading 0x)"), |
4628 | 15 | UAT_FLD_CSTRING(someip_parameter_structs, struct_name, "Struct Name", "Name of struct"), |
4629 | 15 | UAT_FLD_DEC(someip_parameter_structs, length_of_length, "Length of Length Field", "Length of the structs length field in bits (8bit dec)"), |
4630 | 15 | UAT_FLD_DEC(someip_parameter_structs, pad_to, "Pad to", "Padding pads to reach alignment (8bit dec)"), |
4631 | 15 | 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)"), |
4632 | 15 | UAT_FLD_DEC(someip_parameter_structs, num_of_items, "Number of Items", "Number of Items (16bit dec)"), |
4633 | | |
4634 | 15 | UAT_FLD_DEC(someip_parameter_structs, pos, "Parameter Position/ID", "Position or ID of parameter (16bit dec, starting with 0)"), |
4635 | 15 | UAT_FLD_CSTRING(someip_parameter_structs, name, "Parameter Name", "Name of parameter (string)"), |
4636 | 15 | 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, 8: bitfield)"), |
4637 | 15 | UAT_FLD_HEX(someip_parameter_structs, id_ref, "ID Reference", "ID Reference (32bit hex)"), |
4638 | 15 | UAT_FLD_CSTRING(someip_parameter_structs, filter_string, "Filter String", "Unique filter string that will be prepended with someip.payload. (string)"), |
4639 | 15 | UAT_END_FIELDS |
4640 | 15 | }; |
4641 | | |
4642 | 15 | static uat_field_t someip_parameter_union_uat_fields[] = { |
4643 | 15 | UAT_FLD_HEX(someip_parameter_unions, id, "ID", "ID of SOME/IP union (32bit hex without leading 0x)"), |
4644 | 15 | UAT_FLD_CSTRING(someip_parameter_unions, name, "Union Name", "Name of union"), |
4645 | 15 | UAT_FLD_DEC(someip_parameter_unions, length_of_length, "Length of Length Field", "Length of the unions length field in bits (uint8 dec)"), |
4646 | 15 | UAT_FLD_DEC(someip_parameter_unions, length_of_type, "Length of Type Field", "Length of the unions type field in bits (8bit dec)"), |
4647 | 15 | UAT_FLD_DEC(someip_parameter_unions, pad_to, "Pad to", "Padding pads to reach alignment (8bit dec)"), |
4648 | | |
4649 | 15 | UAT_FLD_DEC(someip_parameter_unions, num_of_items, "Number of Items", "Number of Items (32bit dec)"), |
4650 | | |
4651 | 15 | UAT_FLD_DEC(someip_parameter_unions, type_id, "Type ID", "ID of Type (32bit dec, starting with 0)"), |
4652 | 15 | UAT_FLD_CSTRING(someip_parameter_unions, type_name, "Type Name", "Name of Type (string)"), |
4653 | 15 | 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, 8: bitfield)"), |
4654 | 15 | UAT_FLD_HEX(someip_parameter_unions, id_ref, "ID Reference", "ID Reference (32bit hex)"), |
4655 | 15 | UAT_FLD_CSTRING(someip_parameter_unions, filter_string, "Filter String", "Unique filter string that will be prepended with someip.payload. (string)"), |
4656 | 15 | UAT_END_FIELDS |
4657 | 15 | }; |
4658 | | |
4659 | 15 | static uat_field_t someip_parameter_typedef_list_uat_fields[] = { |
4660 | 15 | UAT_FLD_HEX(someip_parameter_typedefs, id, "ID ", "ID (32bit hex)"), |
4661 | 15 | UAT_FLD_CSTRING(someip_parameter_typedefs, name, "Name", "Name of typedef (string)"), |
4662 | 15 | 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)"), |
4663 | 15 | UAT_FLD_HEX(someip_parameter_typedefs, id_ref, "ID Reference", "ID Reference (32bit hex)"), |
4664 | 15 | UAT_END_FIELDS |
4665 | 15 | }; |
4666 | | |
4667 | 15 | static uat_field_t someip_parameter_enum_uat_fields[] = { |
4668 | 15 | UAT_FLD_HEX(someip_parameter_enums, id, "ID", "ID of SOME/IP enum (32bit hex without leading 0x)"), |
4669 | 15 | UAT_FLD_CSTRING(someip_parameter_enums, name, "Name", "Name of Enumeration (string)"), |
4670 | 15 | 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, 8: bitfield)"), |
4671 | 15 | UAT_FLD_HEX(someip_parameter_enums, id_ref, "ID Reference", "ID Reference (32bit hex)"), |
4672 | 15 | UAT_FLD_DEC(someip_parameter_enums, num_of_items, "Number of Items", "Number of Items (32bit dec)"), |
4673 | | |
4674 | 15 | UAT_FLD_HEX(someip_parameter_enums, value, "Value", "Value (64bit uint hex)"), |
4675 | 15 | UAT_FLD_CSTRING(someip_parameter_enums, value_name, "Value Name", "Name (string)"), |
4676 | 15 | UAT_END_FIELDS |
4677 | 15 | }; |
4678 | | |
4679 | 15 | static uat_field_t someip_parameter_bitfield_uat_fields[] = { |
4680 | 15 | UAT_FLD_HEX(someip_parameter_bitfields, id, "ID", "ID of SOME/IP bitfield (32bit hex without leading 0x)"), |
4681 | 15 | UAT_FLD_CSTRING(someip_parameter_bitfields, name, "Name", "Name of Bitfield (string)"), |
4682 | 15 | UAT_FLD_DEC(someip_parameter_bitfields, number_of_bits, "Number of Bits", "Number of Bits (8, 16, 32, 64)"), |
4683 | 15 | UAT_FLD_DEC(someip_parameter_bitfields, num_of_items, "Number of Items", "Number of Items (32bit dec)"), |
4684 | | |
4685 | 15 | UAT_FLD_DEC(someip_parameter_bitfields, bit_number, "Bit Number", "Value (8bit uint dec)"), |
4686 | 15 | UAT_FLD_CSTRING(someip_parameter_bitfields, bit_name, "Bit Name", "Name (string)"), |
4687 | 15 | UAT_FLD_CSTRING(someip_parameter_bitfields, filter_string, "Filter String", "Unique filter string that will be prepended with someip.payload. (string)"), |
4688 | 15 | UAT_END_FIELDS |
4689 | 15 | }; |
4690 | | |
4691 | 15 | static ei_register_info ei[] = { |
4692 | 15 | { &ei_someip_unknown_version,{ "someip.unknown_protocol_version", |
4693 | 15 | PI_PROTOCOL, PI_WARN, "SOME/IP Unknown Protocol Version!", EXPFILL } }, |
4694 | 15 | { &ei_someip_message_truncated,{ "someip.message_truncated", |
4695 | 15 | PI_MALFORMED, PI_ERROR, "SOME/IP Truncated message!", EXPFILL } }, |
4696 | 15 | { &ei_someip_incomplete_headers,{ "someip.incomplete_headers", |
4697 | 15 | PI_MALFORMED, PI_ERROR, "SOME/IP Incomplete headers or some bytes left over!", EXPFILL } }, |
4698 | | |
4699 | 15 | { &ei_someip_payload_truncated, {"someip.payload.expert_truncated", |
4700 | 15 | PI_MALFORMED, PI_ERROR, "SOME/IP Payload: Truncated payload!", EXPFILL} }, |
4701 | 15 | { &ei_someip_payload_malformed, {"someip.payload.expert_malformed", |
4702 | 15 | PI_MALFORMED, PI_ERROR, "SOME/IP Payload: Malformed payload!", EXPFILL} }, |
4703 | 15 | { &ei_someip_payload_config_error, {"someip.payload.expert_config_error", |
4704 | 15 | PI_MALFORMED, PI_ERROR, "SOME/IP Payload: Config Error!", EXPFILL} }, |
4705 | 15 | { &ei_someip_payload_alignment_error, {"someip.payload.expert_alignment_error", |
4706 | 15 | PI_MALFORMED, PI_ERROR, "SOME/IP Payload: SOME/IP datatype must be align to a byte!", EXPFILL} }, |
4707 | 15 | { &ei_someip_payload_static_array_min_not_max, {"someip.payload.expert_static_array_min_max", |
4708 | 15 | PI_MALFORMED, PI_ERROR, "SOME/IP Payload: Static array with min!=max!", EXPFILL} }, |
4709 | 15 | { &ei_someip_payload_dyn_array_not_within_limit, {"someip.payload.expert_dyn_array_not_within_limit", |
4710 | 15 | PI_MALFORMED, PI_WARN, "SOME/IP Payload: Dynamic array does not stay between Min and Max values!", EXPFILL} }, |
4711 | 15 | { &ei_someip_payload_disabled, {"someip.payload.disabled", |
4712 | 15 | PI_PROTOCOL, PI_WARN, "Dissection of payload is disabled. It can be enabled via protocol preferences.", EXPFILL} }, |
4713 | 15 | }; |
4714 | | |
4715 | | /* Register Protocol, Handles, Fields, ETTs, Expert Info, Dissector Table, Taps */ |
4716 | 15 | proto_someip = proto_register_protocol("SOME/IP Protocol", "SOME/IP", "someip"); |
4717 | 15 | someip_handle_udp = register_dissector("someip_udp", dissect_someip_udp, proto_someip); |
4718 | 15 | someip_handle_tcp = register_dissector("someip_tcp", dissect_someip_tcp, proto_someip); |
4719 | 15 | register_dissector("someip", dissect_someip_message, proto_someip); |
4720 | | |
4721 | 15 | proto_register_field_array(proto_someip, hf, array_length(hf)); |
4722 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
4723 | 15 | expert_module_someip = expert_register_protocol(proto_someip); |
4724 | 15 | expert_register_field_array(expert_module_someip, ei, array_length(ei)); |
4725 | | |
4726 | 15 | someip_dissector_table = register_dissector_table("someip.messageid", "SOME/IP Message ID", proto_someip, FT_UINT32, BASE_HEX); |
4727 | | |
4728 | 15 | tap_someip_messages = register_tap("someip_messages"); |
4729 | | |
4730 | | /* init for SOME/IP-TP */ |
4731 | 15 | reassembly_table_init(&someip_tp_reassembly_table, &someip_reassembly_table_functions); |
4732 | | |
4733 | | /* Register preferences */ |
4734 | 15 | someip_module = prefs_register_protocol(proto_someip, &proto_reg_handoff_someip); |
4735 | | |
4736 | | /* UATs */ |
4737 | 15 | someip_service_uat = uat_new("SOME/IP Services", |
4738 | 15 | sizeof(generic_one_id_string_t), /* record size */ |
4739 | 15 | DATAFILE_SOMEIP_SERVICES, /* filename */ |
4740 | 15 | true, /* from profile */ |
4741 | 15 | (void **) &someip_service_ident, /* data_ptr */ |
4742 | 15 | &someip_service_ident_num, /* numitems_ptr */ |
4743 | 15 | UAT_AFFECTS_DISSECTION, /* but not fields */ |
4744 | 15 | NULL, /* help */ |
4745 | 15 | copy_generic_one_id_string_cb, /* copy callback */ |
4746 | 15 | update_serviceid, /* update callback */ |
4747 | 15 | free_generic_one_id_string_cb, /* free callback */ |
4748 | 15 | post_update_someip_service_cb, /* post update callback */ |
4749 | 15 | reset_someip_service_cb, /* reset callback */ |
4750 | 15 | someip_service_uat_fields /* UAT field definitions */ |
4751 | 15 | ); |
4752 | | |
4753 | 15 | prefs_register_uat_preference(someip_module, "services", "SOME/IP Services", |
4754 | 15 | "A table to define names of SOME/IP services", someip_service_uat); |
4755 | | |
4756 | 15 | someip_method_uat = uat_new("SOME/IP Methods/Events/Fields", |
4757 | 15 | sizeof(generic_two_id_string_t), /* record size */ |
4758 | 15 | DATAFILE_SOMEIP_METHODS, /* filename */ |
4759 | 15 | true, /* from profile */ |
4760 | 15 | (void **) &someip_method_ident, /* data_ptr */ |
4761 | 15 | &someip_method_ident_num, /* numitems_ptr */ |
4762 | 15 | UAT_AFFECTS_DISSECTION, /* but not fields */ |
4763 | 15 | NULL, /* help */ |
4764 | 15 | copy_generic_two_id_string_cb, /* copy callback */ |
4765 | 15 | update_two_identifier_16bit_check_both, /* update callback */ |
4766 | 15 | free_generic_two_id_string_cb, /* free callback */ |
4767 | 15 | post_update_someip_method_cb, /* post update callback */ |
4768 | 15 | reset_someip_method_cb, /* reset callback */ |
4769 | 15 | someip_method_uat_fields /* UAT field definitions */ |
4770 | 15 | ); |
4771 | | |
4772 | 15 | prefs_register_uat_preference(someip_module, "methods", "SOME/IP Methods", |
4773 | 15 | "A table to define names of SOME/IP methods", someip_method_uat); |
4774 | | |
4775 | 15 | someip_eventgroup_uat = uat_new("SOME/IP Eventgroups", |
4776 | 15 | sizeof(generic_two_id_string_t), /* record size */ |
4777 | 15 | DATAFILE_SOMEIP_EVENTGROUPS, /* filename */ |
4778 | 15 | true, /* from profile */ |
4779 | 15 | (void **) &someip_eventgroup_ident, /* data_ptr */ |
4780 | 15 | &someip_eventgroup_ident_num, /* numitems_ptr */ |
4781 | 15 | UAT_AFFECTS_DISSECTION, /* but not fields */ |
4782 | 15 | NULL, /* help */ |
4783 | 15 | copy_generic_two_id_string_cb, /* copy callback */ |
4784 | 15 | update_two_identifier_16bit_check_both, /* update callback */ |
4785 | 15 | free_generic_two_id_string_cb, /* free callback */ |
4786 | 15 | post_update_someip_eventgroup_cb, /* post update callback */ |
4787 | 15 | reset_someip_eventgroup_cb, /* reset callback */ |
4788 | 15 | someip_eventgroup_uat_fields /* UAT field definitions */ |
4789 | 15 | ); |
4790 | | |
4791 | 15 | prefs_register_uat_preference(someip_module, "eventgroups", "SOME/IP Eventgroups", |
4792 | 15 | "A table to define names of SOME/IP eventgroups", someip_eventgroup_uat); |
4793 | | |
4794 | 15 | someip_client_uat = uat_new("SOME/IP Clients", |
4795 | 15 | sizeof(generic_two_id_string_t), /* record size */ |
4796 | 15 | DATAFILE_SOMEIP_CLIENTS, /* filename */ |
4797 | 15 | true, /* from profile */ |
4798 | 15 | (void **)&someip_client_ident, /* data_ptr */ |
4799 | 15 | &someip_client_ident_num, /* numitems_ptr */ |
4800 | 15 | UAT_AFFECTS_DISSECTION, /* but not fields */ |
4801 | 15 | NULL, /* help */ |
4802 | 15 | copy_generic_two_id_string_cb, /* copy callback */ |
4803 | 15 | update_generic_two_identifier_16bit, /* update callback */ |
4804 | 15 | free_generic_two_id_string_cb, /* free callback */ |
4805 | 15 | post_update_someip_client_cb, /* post update callback */ |
4806 | 15 | reset_someip_client_cb, /* reset callback */ |
4807 | 15 | someip_client_uat_fields /* UAT field definitions */ |
4808 | 15 | ); |
4809 | | |
4810 | 15 | prefs_register_uat_preference(someip_module, "clients", "SOME/IP Clients", |
4811 | 15 | "A table to define names of SOME/IP clients", someip_client_uat); |
4812 | | |
4813 | 15 | prefs_register_bool_preference(someip_module, "reassemble_tp", "Reassemble SOME/IP-TP", |
4814 | 15 | "Reassemble SOME/IP-TP segments", &someip_tp_reassemble); |
4815 | | |
4816 | 15 | prefs_register_bool_preference(someip_module, "payload_dissector_activated", |
4817 | 15 | "Dissect Payload", |
4818 | 15 | "Should the SOME/IP Dissector use the payload dissector?", |
4819 | 15 | &someip_deserializer_activated); |
4820 | | |
4821 | 15 | prefs_register_bool_preference(someip_module, "payload_dissector_debugging_activated", |
4822 | 15 | "Add Debug Information of Payload Dissector Configuration", |
4823 | 15 | "Should the SOME/IP Dissector add debug information to help debugging dissector configuration?", |
4824 | 15 | &someip_deserializer_debugging_activated); |
4825 | | |
4826 | 15 | prefs_register_bool_preference(someip_module, "detect_dtls_and_hand_off", |
4827 | 15 | "Try to automatically detect DTLS", |
4828 | 15 | "Should the SOME/IP Dissector automatically detect DTLS and hand off to it?", |
4829 | 15 | &someip_detect_dtls); |
4830 | | |
4831 | 15 | prefs_register_bool_preference(someip_module, "payload_dissector_wtlv_default", |
4832 | 15 | "Try WTLV payload dissection for unconfigured messages (not pure SOME/IP)", |
4833 | 15 | "Should the SOME/IP Dissector use the payload dissector with the experimental WTLV encoding for unconfigured messages?", |
4834 | 15 | &someip_deserializer_wtlv_default); |
4835 | | |
4836 | 15 | prefs_register_bool_preference(someip_module, "payload_dissector_test_tcp_for_valid_someip", |
4837 | 15 | "Test TCP segments for valid SOME/IP (improve results with missing TCP segments)", |
4838 | 15 | "Should the SOME/IP Dissector test TCP segments for being correct SOME/IP? This is helpful to resync after missing segments.", |
4839 | 15 | &someip_test_tcp_for_valid_someip); |
4840 | | |
4841 | 15 | someip_parameter_list_uat = uat_new("SOME/IP Parameter List", |
4842 | 15 | sizeof(someip_parameter_list_uat_t), /* record size */ |
4843 | 15 | DATAFILE_SOMEIP_PARAMETERS, /* filename */ |
4844 | 15 | true, /* from profile */ |
4845 | 15 | (void **)&someip_parameter_list, /* data_ptr */ |
4846 | 15 | &someip_parameter_list_num, /* numitems_ptr */ |
4847 | 15 | UAT_AFFECTS_DISSECTION | UAT_AFFECTS_FIELDS, |
4848 | 15 | NULL, /* help */ |
4849 | 15 | copy_someip_parameter_list_cb, /* copy callback */ |
4850 | 15 | update_someip_parameter_list, /* update callback */ |
4851 | 15 | free_someip_parameter_list_cb, /* free callback */ |
4852 | 15 | post_update_someip_dynamic_parameter_cb, /* post update callback */ |
4853 | 15 | reset_someip_dynamic_parameter_cb, /* reset callback */ |
4854 | 15 | someip_parameter_list_uat_fields /* UAT field definitions */ |
4855 | 15 | ); |
4856 | | |
4857 | 15 | prefs_register_uat_preference(someip_module, "_someip_parameter_list", "SOME/IP Parameter List", |
4858 | 15 | "A table to define names of SOME/IP parameters", someip_parameter_list_uat); |
4859 | | |
4860 | 15 | someip_parameter_base_type_list_uat = uat_new("SOME/IP Parameter Base Type List", |
4861 | 15 | sizeof(someip_parameter_base_type_list_uat_t), /* record size */ |
4862 | 15 | DATAFILE_SOMEIP_BASE_TYPES, /* filename */ |
4863 | 15 | true, /* from profile */ |
4864 | 15 | (void **)&someip_parameter_base_type_list, /* data_ptr */ |
4865 | 15 | &someip_parameter_base_type_list_num, /* numitems_ptr */ |
4866 | 15 | UAT_AFFECTS_DISSECTION, /* but not fields */ |
4867 | 15 | NULL, /* help */ |
4868 | 15 | copy_someip_parameter_base_type_list_cb, /* copy callback */ |
4869 | 15 | update_someip_parameter_base_type_list, /* update callback */ |
4870 | 15 | free_someip_parameter_base_type_list_cb, /* free callback */ |
4871 | 15 | post_update_someip_parameter_base_type_list_cb, /* post update callback */ |
4872 | 15 | reset_someip_parameter_base_type_list_cb, /* reset callback */ |
4873 | 15 | someip_parameter_base_type_list_uat_fields /* UAT field definitions */ |
4874 | 15 | ); |
4875 | | |
4876 | 15 | prefs_register_uat_preference(someip_module, "_someip_parameter_base_type_list", "SOME/IP Parameter Base Type List", |
4877 | 15 | "A table to define base types of SOME/IP parameters", someip_parameter_base_type_list_uat); |
4878 | | |
4879 | 15 | someip_parameter_strings_uat = uat_new("SOME/IP Parameter String List", |
4880 | 15 | sizeof(someip_parameter_string_uat_t), /* record size */ |
4881 | 15 | DATAFILE_SOMEIP_STRINGS, /* filename */ |
4882 | 15 | true, /* from profile */ |
4883 | 15 | (void **)&someip_parameter_strings, /* data_ptr */ |
4884 | 15 | &someip_parameter_strings_num, /* numitems_ptr */ |
4885 | 15 | UAT_AFFECTS_DISSECTION, /* but not fields */ |
4886 | 15 | NULL, /* help */ |
4887 | 15 | copy_someip_parameter_string_list_cb, /* copy callback */ |
4888 | 15 | update_someip_parameter_string_list, /* update callback */ |
4889 | 15 | free_someip_parameter_string_list_cb, /* free callback */ |
4890 | 15 | post_update_someip_parameter_string_list_cb, /* post update callback */ |
4891 | 15 | reset_someip_parameter_string_list_cb, /* reset callback */ |
4892 | 15 | someip_parameter_string_list_uat_fields /* UAT field definitions */ |
4893 | 15 | ); |
4894 | | |
4895 | 15 | prefs_register_uat_preference(someip_module, "_someip_parameter_string_list", "SOME/IP Parameter String List", |
4896 | 15 | "A table to define strings parameters", someip_parameter_strings_uat); |
4897 | | |
4898 | 15 | someip_parameter_arrays_uat = uat_new("SOME/IP Parameter Arrays", |
4899 | 15 | sizeof(someip_parameter_array_uat_t), /* record size */ |
4900 | 15 | DATAFILE_SOMEIP_ARRAYS, /* filename */ |
4901 | 15 | true, /* from profile */ |
4902 | 15 | (void **)&someip_parameter_arrays, /* data_ptr */ |
4903 | 15 | &someip_parameter_arrays_num, /* numitems_ptr */ |
4904 | 15 | UAT_AFFECTS_DISSECTION | UAT_AFFECTS_FIELDS, |
4905 | 15 | NULL, /* help */ |
4906 | 15 | copy_someip_parameter_array_cb, /* copy callback */ |
4907 | 15 | update_someip_parameter_array, /* update callback */ |
4908 | 15 | free_someip_parameter_array_cb, /* free callback */ |
4909 | 15 | post_update_someip_dynamic_parameter_cb, /* post update callback */ |
4910 | 15 | reset_someip_dynamic_parameter_cb, /* reset callback */ |
4911 | 15 | someip_parameter_array_uat_fields /* UAT field definitions */ |
4912 | 15 | ); |
4913 | | |
4914 | 15 | prefs_register_uat_preference(someip_module, "_someip_parameter_arrays", "SOME/IP Parameter Arrays", |
4915 | 15 | "A table to define arrays used by SOME/IP", someip_parameter_arrays_uat); |
4916 | | |
4917 | 15 | someip_parameter_structs_uat = uat_new("SOME/IP Parameter Structs", |
4918 | 15 | sizeof(someip_parameter_struct_uat_t), /* record size */ |
4919 | 15 | DATAFILE_SOMEIP_STRUCTS, /* filename */ |
4920 | 15 | true, /* from profile */ |
4921 | 15 | (void **)&someip_parameter_structs, /* data_ptr */ |
4922 | 15 | &someip_parameter_structs_num, /* numitems_ptr */ |
4923 | 15 | UAT_AFFECTS_DISSECTION | UAT_AFFECTS_FIELDS, |
4924 | 15 | NULL, /* help */ |
4925 | 15 | copy_someip_parameter_struct_cb, /* copy callback */ |
4926 | 15 | update_someip_parameter_struct, /* update callback */ |
4927 | 15 | free_someip_parameter_struct_cb, /* free callback */ |
4928 | 15 | post_update_someip_dynamic_parameter_cb, /* post update callback */ |
4929 | 15 | reset_someip_dynamic_parameter_cb, /* reset callback */ |
4930 | 15 | someip_parameter_struct_uat_fields /* UAT field definitions */ |
4931 | 15 | ); |
4932 | | |
4933 | 15 | prefs_register_uat_preference(someip_module, "_someip_parameter_structs", "SOME/IP Parameter Structs", |
4934 | 15 | "A table to define structs used by SOME/IP", someip_parameter_structs_uat); |
4935 | | |
4936 | 15 | someip_parameter_unions_uat = uat_new("SOME/IP Parameter Unions", |
4937 | 15 | sizeof(someip_parameter_union_uat_t), /* record size */ |
4938 | 15 | DATAFILE_SOMEIP_UNIONS, /* filename */ |
4939 | 15 | true, /* from profile */ |
4940 | 15 | (void **)&someip_parameter_unions, /* data_ptr */ |
4941 | 15 | &someip_parameter_unions_num, /* numitems_ptr */ |
4942 | 15 | UAT_AFFECTS_DISSECTION | UAT_AFFECTS_FIELDS, |
4943 | 15 | NULL, /* help */ |
4944 | 15 | copy_someip_parameter_union_cb, /* copy callback */ |
4945 | 15 | update_someip_parameter_union, /* update callback */ |
4946 | 15 | free_someip_parameter_union_cb, /* free callback */ |
4947 | 15 | post_update_someip_dynamic_parameter_cb, /* post update callback */ |
4948 | 15 | reset_someip_dynamic_parameter_cb, /* reset callback */ |
4949 | 15 | someip_parameter_union_uat_fields /* UAT field definitions */ |
4950 | 15 | ); |
4951 | | |
4952 | 15 | prefs_register_uat_preference(someip_module, "_someip_parameter_unions", "SOME/IP Parameter Unions", |
4953 | 15 | "A table to define unions used by SOME/IP", someip_parameter_unions_uat); |
4954 | | |
4955 | 15 | someip_parameter_typedefs_uat = uat_new("SOME/IP Parameter Typedef List", |
4956 | 15 | sizeof(someip_parameter_typedef_uat_t), /* record size */ |
4957 | 15 | DATAFILE_SOMEIP_TYPEDEFS, /* filename */ |
4958 | 15 | true, /* from profile */ |
4959 | 15 | (void **)&someip_parameter_typedefs, /* data_ptr */ |
4960 | 15 | &someip_parameter_typedefs_num, /* numitems_ptr */ |
4961 | 15 | UAT_AFFECTS_DISSECTION, /* but not fields */ |
4962 | 15 | NULL, /* help */ |
4963 | 15 | copy_someip_parameter_typedef_list_cb, /* copy callback */ |
4964 | 15 | update_someip_parameter_typedef_list, /* update callback */ |
4965 | 15 | free_someip_parameter_typedef_list_cb, /* free callback */ |
4966 | 15 | post_update_someip_parameter_typedef_list_cb, /* post update callback */ |
4967 | 15 | reset_someip_parameter_typedef_list_cb, /* reset callback */ |
4968 | 15 | someip_parameter_typedef_list_uat_fields /* UAT field definitions */ |
4969 | 15 | ); |
4970 | | |
4971 | 15 | prefs_register_uat_preference(someip_module, "_someip_parameter_typedef_list", "SOME/IP Parameter Typedef List", |
4972 | 15 | "A table to define typedefs", someip_parameter_typedefs_uat); |
4973 | | |
4974 | 15 | someip_parameter_enums_uat = uat_new("SOME/IP Parameter Enums", |
4975 | 15 | sizeof(someip_parameter_enum_uat_t), /* record size */ |
4976 | 15 | DATAFILE_SOMEIP_ENUMS, /* filename */ |
4977 | 15 | true, /* from profile */ |
4978 | 15 | (void **)&someip_parameter_enums, /* data_ptr */ |
4979 | 15 | &someip_parameter_enums_num, /* numitems_ptr */ |
4980 | 15 | UAT_AFFECTS_DISSECTION, /* but not fields */ |
4981 | 15 | NULL, /* help */ |
4982 | 15 | copy_someip_parameter_enum_cb, /* copy callback */ |
4983 | 15 | update_someip_parameter_enum, /* update callback */ |
4984 | 15 | free_someip_parameter_enum_cb, /* free callback */ |
4985 | 15 | post_update_someip_parameter_enum_cb, /* post update callback */ |
4986 | 15 | reset_someip_parameter_enum_cb, /* reset callback */ |
4987 | 15 | someip_parameter_enum_uat_fields /* UAT field definitions */ |
4988 | 15 | ); |
4989 | | |
4990 | 15 | prefs_register_uat_preference(someip_module, "_someip_parameter_enums", "SOME/IP Parameter Enums", |
4991 | 15 | "A table to define enumerations used by SOME/IP", someip_parameter_enums_uat); |
4992 | | |
4993 | 15 | someip_parameter_bitfields_uat = uat_new("SOME/IP Parameter Bitfields", |
4994 | 15 | sizeof(someip_parameter_bitfield_uat_t), /* record size */ |
4995 | 15 | DATAFILE_SOMEIP_BITFIELDS, /* filename */ |
4996 | 15 | true, /* from profile */ |
4997 | 15 | (void **)&someip_parameter_bitfields, /* data_ptr */ |
4998 | 15 | &someip_parameter_bitfields_num, /* numitems_ptr */ |
4999 | 15 | UAT_AFFECTS_DISSECTION, /* but not fields */ |
5000 | 15 | NULL, /* help */ |
5001 | 15 | copy_someip_parameter_bitfield_cb, /* copy callback */ |
5002 | 15 | update_someip_parameter_bitfield, /* update callback */ |
5003 | 15 | free_someip_parameter_bitfield_cb, /* free callback */ |
5004 | 15 | post_update_someip_parameter_bitfield_cb, /* post update callback */ |
5005 | 15 | reset_someip_parameter_bitfield_cb, /* reset callback */ |
5006 | 15 | someip_parameter_bitfield_uat_fields /* UAT field definitions */ |
5007 | 15 | ); |
5008 | | |
5009 | 15 | prefs_register_uat_preference(someip_module, "_someip_parameter_bitfields", "SOME/IP Parameter Bitfields", |
5010 | 15 | "A table to define bitfields used by SOME/IP", someip_parameter_bitfields_uat); |
5011 | 15 | } |
5012 | | |
5013 | | void |
5014 | 30 | proto_reg_handoff_someip(void) { |
5015 | 30 | static bool initialized = false; |
5016 | | |
5017 | 30 | if (!initialized) { |
5018 | | /* add support for (D)TLS decode as */ |
5019 | 15 | dtls_dissector_add(0, someip_handle_udp); |
5020 | 15 | ssl_dissector_add(0, someip_handle_tcp); |
5021 | | |
5022 | 15 | heur_dissector_add("udp", dissect_some_ip_heur_udp, "SOME/IP over UDP", "someip_udp_heur", proto_someip, HEURISTIC_DISABLE); |
5023 | 15 | heur_dissector_add("tcp", dissect_some_ip_heur_tcp, "SOME/IP over TCP", "someip_tcp_heur", proto_someip, HEURISTIC_DISABLE); |
5024 | | |
5025 | 15 | stats_tree_register("someip_messages", "someip_messages", "SOME/IP Messages", 0, someip_messages_stats_tree_packet, someip_messages_stats_tree_init, NULL); |
5026 | | |
5027 | 15 | dissector_add_uint_range_with_preference("udp.port", "", someip_handle_udp); |
5028 | 15 | dissector_add_uint_range_with_preference("tcp.port", "", someip_handle_tcp); |
5029 | | |
5030 | 15 | dtls_handle = find_dissector("dtls"); |
5031 | | |
5032 | 15 | initialized = true; |
5033 | 15 | } |
5034 | | |
5035 | 30 | update_dynamic_hf_entries_someip_parameter(); |
5036 | 30 | } |
5037 | | |
5038 | | /* |
5039 | | * Editor modelines |
5040 | | * |
5041 | | * Local Variables: |
5042 | | * c-basic-offset: 4 |
5043 | | * tab-width: 8 |
5044 | | * indent-tabs-mode: nil |
5045 | | * End: |
5046 | | * |
5047 | | * ex: set shiftwidth=4 tabstop=8 expandtab: |
5048 | | * :indentSize=4:tabSize=8:noTabs=true: |
5049 | | */ |