Coverage Report

Created: 2026-07-12 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
 */