Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-someip-sd.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-someip-sd.c
2
 * SOME/IP-SD dissector.
3
 * By Dr. Lars Voelker <lars.voelker@technica-engineering.de> / <lars.voelker@bmw.de>
4
 * Copyright 2012-2024 Dr. Lars Voelker
5
 * Copyright 2020      Ayoub Kaanich
6
 * Copyright 2019      Ana Pantar
7
 * Copyright 2019      Guenter Ebermann
8
 *
9
 * Wireshark - Network traffic analyzer
10
 * By Gerald Combs <gerald@wireshark.org>
11
 * Copyright 1998 Gerald Combs
12
 *
13
 * SPDX-License-Identifier: GPL-2.0-or-later
14
 */
15
16
#include <config.h>
17
18
#include <epan/prefs.h>
19
#include <epan/expert.h>
20
#include <epan/to_str.h>
21
#include <epan/stats_tree.h>
22
#include <epan/tfs.h>
23
#include <wsutil/array.h>
24
#include "packet-udp.h"
25
#include "packet-someip.h"
26
27
 /*
28
  * Dissector for SOME/IP Service Discovery (SOME/IP-SD).
29
  *
30
  * See
31
  *     http://www.some-ip.com
32
  */
33
34
14
#define SOMEIP_SD_NAME                          "SOME/IP-SD"
35
14
#define SOMEIP_SD_NAME_LONG                     "SOME/IP Service Discovery Protocol"
36
28
#define SOMEIP_SD_NAME_FILTER                   "someipsd"
37
38
14
#define SOMEIP_SD_MESSAGEID                     0xffff8100
39
0
#define SOMEIP_SD_SERVICE_ID_OTHER_SERVICE      0xfffe
40
41
42
 /* Header */
43
14
#define SOMEIP_SD_REBOOT_FLAG                   0x80
44
14
#define SOMEIP_SD_UNICAST_FLAG                  0x40
45
14
#define SOMEIP_SD_EXPL_INIT_EVENT_REQ_FLAG      0x20
46
0
#define SOMEIP_SD_MIN_LENGTH                    12
47
48
/* Entries */
49
0
#define SD_ENTRY_LENGTH                         16
50
51
0
#define SD_ENTRY_UNKNOWN                        0x00
52
0
#define SD_ENTRY_SERVICE                        0x01
53
0
#define SD_ENTRY_EVENTGROUP                     0x02
54
/* TTL>0 */
55
0
#define SD_ENTRY_FIND_SERVICE                   0x00
56
0
#define SD_ENTRY_OFFER_SERVICE                  0x01
57
0
#define SD_ENTRY_SUBSCRIBE_EVENTGROUP           0x06
58
0
#define SD_ENTRY_SUBSCRIBE_EVENTGROUP_ACK       0x07
59
/* TTL=0 */
60
0
#define SD_ENTRY_STOP_OFFER_SERVICE             0x01
61
0
#define SD_ENTRY_STOP_SUBSCRIBE_EVENTGROUP      0x06
62
0
#define SD_ENTRY_SUBSCRIBE_EVENTGROUP_NACK      0x07
63
64
14
#define SD_EVENTGROUP_ENTRY_COUNTER_MASK        0x0f
65
14
#define SD_EVENTGROUP_ENTRY_RES2_MASK           0x70
66
14
#define SD_ENTRY_INIT_EVENT_REQ_MASK            0x80
67
68
/* Options */
69
0
#define SD_OPTION_MINLENGTH                     3
70
0
#define SD_OPTION_IPV4_LENGTH                   12
71
0
#define SD_OPTION_IPV6_LENGTH                   24
72
73
#define SD_OPTION_UNKNOWN                       0x00
74
0
#define SD_OPTION_CONFIGURATION                 0x01
75
0
#define SD_OPTION_LOADBALANCING                 0x02
76
0
#define SD_OPTION_IPV4_ENDPOINT                 0x04
77
0
#define SD_OPTION_IPV6_ENDPOINT                 0x06
78
0
#define SD_OPTION_IPV4_MULTICAST                0x14
79
0
#define SD_OPTION_IPV6_MULTICAST                0x16
80
0
#define SD_OPTION_IPV4_SD_ENDPOINT              0x24
81
0
#define SD_OPTION_IPV6_SD_ENDPOINT              0x26
82
83
0
#define SD_OPTION_L4PROTO_TCP                   6
84
0
#define SD_OPTION_L4PROTO_UDP                   17
85
86
/* option start 0..255, num 0..15 -> 0..270 */
87
#define SD_MAX_NUM_OPTIONS                      271
88
89
/* ID wireshark identifies the dissector by */
90
static int proto_someip_sd;
91
92
/* header field */
93
static int hf_someip_sd_flags;
94
static int hf_someip_sd_rebootflag;
95
static int hf_someip_sd_unicastflag;
96
static int hf_someip_sd_explicitiniteventflag;
97
static int hf_someip_sd_reserved;
98
99
static int hf_someip_sd_length_entriesarray;
100
static int hf_someip_sd_entries;
101
102
static int hf_someip_sd_entry;
103
static int hf_someip_sd_entry_type;
104
static int hf_someip_sd_entry_type_offerservice;
105
static int hf_someip_sd_entry_type_stopofferservice;
106
static int hf_someip_sd_entry_type_findservice;
107
static int hf_someip_sd_entry_type_subscribeeventgroup;
108
static int hf_someip_sd_entry_type_stopsubscribeeventgroup;
109
static int hf_someip_sd_entry_type_subscribeeventgroupack;
110
static int hf_someip_sd_entry_type_subscribeeventgroupnack;
111
static int hf_someip_sd_entry_index1;
112
static int hf_someip_sd_entry_index2;
113
static int hf_someip_sd_entry_numopt1;
114
static int hf_someip_sd_entry_numopt2;
115
static int hf_someip_sd_entry_opts_referenced;
116
static int hf_someip_sd_entry_serviceid;
117
static int hf_someip_sd_entry_servicename;
118
static int hf_someip_sd_entry_instanceid;
119
static int hf_someip_sd_entry_majorver;
120
static int hf_someip_sd_entry_ttl;
121
static int hf_someip_sd_entry_minorver;
122
static int hf_someip_sd_entry_eventgroupid;
123
static int hf_someip_sd_entry_eventgroupname;
124
static int hf_someip_sd_entry_reserved;
125
static int hf_someip_sd_entry_counter;
126
static int hf_someip_sd_entry_intial_event_flag;
127
static int hf_someip_sd_entry_reserved2;
128
129
static int hf_someip_sd_length_optionsarray;
130
static int hf_someip_sd_options;
131
132
static int hf_someip_sd_option_type;
133
static int hf_someip_sd_option_length;
134
static int hf_someip_sd_option_reserved;
135
static int hf_someip_sd_option_ipv4;
136
static int hf_someip_sd_option_ipv6;
137
static int hf_someip_sd_option_port;
138
static int hf_someip_sd_option_proto;
139
static int hf_someip_sd_option_reserved2;
140
static int hf_someip_sd_option_data;
141
static int hf_someip_sd_option_config_string;
142
static int hf_someip_sd_option_config_string_element;
143
static int hf_someip_sd_option_lb_priority;
144
static int hf_someip_sd_option_lb_weight;
145
146
/* protocol tree items */
147
static int ett_someip_sd;
148
static int ett_someip_sd_flags;
149
static int ett_someip_sd_entries;
150
static int ett_someip_sd_entry;
151
static int ett_someip_sd_options;
152
static int ett_someip_sd_option;
153
static int ett_someip_sd_config_string;
154
155
156
/*** Taps ***/
157
static int tap_someip_sd_entries = -1;
158
159
typedef struct _someip_sd_entries_tap {
160
    uint8_t entry_type;
161
    uint16_t service_id;
162
    uint8_t major_version;
163
    uint32_t minor_version;
164
    uint16_t instance_id;
165
    uint16_t eventgroup_id;
166
    uint32_t ttl;
167
} someip_sd_entries_tap_t;
168
169
170
/*** Stats ***/
171
static const char *st_str_ip_src = "Source Addresses";
172
static const char *st_str_ip_dst = "Destination Addresses";
173
174
static int st_node_ip_src = -1;
175
static int st_node_ip_dst = -1;
176
177
/*** Preferences ***/
178
static range_t *someip_ignore_ports_udp;
179
static range_t *someip_ignore_ports_tcp;
180
181
/* SOME/IP-SD Entry Names for TTL>0 */
182
static const value_string sd_entry_type_positive[] = {
183
    {SD_ENTRY_FIND_SERVICE,                                             "Find Service"},
184
    {SD_ENTRY_OFFER_SERVICE,                                            "Offer Service"},
185
    {SD_ENTRY_SUBSCRIBE_EVENTGROUP,                                     "Subscribe Eventgroup"},
186
    {SD_ENTRY_SUBSCRIBE_EVENTGROUP_ACK,                                 "Subscribe Eventgroup Ack"},
187
    {0, NULL}
188
};
189
190
/* SOME/IP-SD Entry Names for TTL=0 */
191
static const value_string sd_entry_type_negative[] = {
192
    {SD_ENTRY_STOP_OFFER_SERVICE,                                       "Stop Offer Service"},
193
    {SD_ENTRY_STOP_SUBSCRIBE_EVENTGROUP,                                "Stop Subscribe Eventgroup"},
194
    {SD_ENTRY_SUBSCRIBE_EVENTGROUP_NACK,                                "Subscribe Eventgroup Negative Ack"},
195
    {0, NULL}
196
};
197
198
static const value_string sd_serviceid_vs[] = {
199
    {0xFFFF,        "ANY"},
200
    {0, NULL}
201
};
202
203
static const value_string sd_instanceid_vs[] = {
204
    {0xFFFF,        "ANY"},
205
    {0, NULL}
206
};
207
208
static const value_string sd_majorversion_vs[] = {
209
    {0xFF,          "ANY"},
210
    {0, NULL}
211
};
212
213
static const value_string sd_minorversion_vs[] = {
214
    {0xFFFFFFFF,    "ANY"},
215
    {0, NULL}
216
};
217
218
static const value_string sd_eventgroupid_vs[] = {
219
    {0xFFFF,        "ANY"},
220
    {0, NULL}
221
};
222
223
/* SOME/IP-SD Option Names */
224
static const value_string sd_option_type[] = {
225
    {SD_OPTION_UNKNOWN,                                                 "Unknown"},
226
    {SD_OPTION_CONFIGURATION,                                           "Configuration"},
227
    {SD_OPTION_LOADBALANCING,                                           "Load Balancing"},
228
    {SD_OPTION_IPV4_ENDPOINT,                                           "IPv4 Endpoint"},
229
    {SD_OPTION_IPV6_ENDPOINT,                                           "IPv6 Endpoint"},
230
    {SD_OPTION_IPV4_MULTICAST,                                          "IPv4 Multicast"},
231
    {SD_OPTION_IPV6_MULTICAST,                                          "IPv6 Multicast"},
232
    {SD_OPTION_IPV4_SD_ENDPOINT,                                        "IPv4 SD Endpoint"},
233
    {SD_OPTION_IPV6_SD_ENDPOINT,                                        "IPv6 SD Endpoint"},
234
    {0, NULL}
235
};
236
237
/* L4 Protocol Names for SOME/IP-SD Endpoints */
238
static const value_string sd_option_l4protos[] = {
239
    {SD_OPTION_L4PROTO_TCP,                                             "TCP"},
240
    {SD_OPTION_L4PROTO_UDP,                                             "UDP"},
241
    {0, NULL}
242
};
243
244
static const true_false_string sd_reboot_flag = {
245
    "Session ID did not roll over since last reboot",
246
    "Session ID rolled over since last reboot"
247
};
248
249
static const true_false_string sd_unicast_flag = {
250
    "Unicast messages support",
251
    "Unicast messages not supported (deprecated)"
252
};
253
254
static const true_false_string sd_eiec_flag = {
255
    "Explicit Initial Event control supported",
256
    "Explicit Initial Event control not supported"
257
};
258
259
/*** expert info items ***/
260
static expert_field ei_someipsd_message_truncated;
261
static expert_field ei_someipsd_entry_array_malformed;
262
static expert_field ei_someipsd_entry_array_empty;
263
static expert_field ei_someipsd_entry_unknown;
264
static expert_field ei_someipsd_offer_without_endpoint;
265
static expert_field ei_someipsd_entry_stopsubsub;
266
static expert_field ei_someipsd_option_array_truncated;
267
static expert_field ei_someipsd_option_array_bytes_left;
268
static expert_field ei_someipsd_option_unknown;
269
static expert_field ei_someipsd_option_wrong_length;
270
static expert_field ei_someipsd_L4_protocol_unsupported;
271
static expert_field ei_someipsd_config_string_malformed;
272
273
/*** prototypes ***/
274
void proto_register_someip_sd(void);
275
void proto_reg_handoff_someip_sd(void);
276
277
static dissector_handle_t someip_sd_handle;
278
279
/**************************************
280
 ******** SOME/IP-SD Dissector ********
281
 *************************************/
282
283
static void
284
0
someip_sd_register_ports(uint32_t opt_index, uint32_t opt_num, uint32_t option_count, uint32_t option_ports[]) {
285
0
    unsigned i;
286
287
0
    for (i = opt_index; i < opt_index + opt_num && i < option_count; i++) {
288
0
        uint32_t l4port = 0x0000ffff & option_ports[i];
289
0
        uint32_t l4proto = (0xff000000 & option_ports[i]) >> 24;
290
291
0
        if (l4proto == SD_OPTION_L4PROTO_UDP && !value_is_in_range(someip_ignore_ports_udp, l4port)) {
292
0
            register_someip_port_udp(l4port);
293
0
        }
294
0
        if (l4proto == SD_OPTION_L4PROTO_TCP && !value_is_in_range(someip_ignore_ports_tcp, l4port)) {
295
0
            register_someip_port_tcp(l4port);
296
0
        }
297
298
        /* delete port from list to ensure only registering once per SD message */
299
0
        option_ports[i] = 0;
300
0
    }
301
0
}
302
303
static void
304
0
dissect_someip_sd_pdu_option_configuration(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, uint32_t length, int optionnum) {
305
0
    uint32_t        offset_orig = offset;
306
0
    const uint8_t  *config_string;
307
0
    proto_item     *ti;
308
0
    proto_tree     *subtree;
309
310
0
    tree = proto_tree_add_subtree_format(tree, tvb, offset, length, ett_someip_sd_option, NULL, "%d: Configuration Option", optionnum);
311
312
    /* Add common fields */
313
0
    proto_tree_add_item(tree, hf_someip_sd_option_length, tvb, offset, 2, ENC_BIG_ENDIAN);
314
0
    offset += 2;
315
316
0
    proto_tree_add_item(tree, hf_someip_sd_option_type, tvb, offset, 1, ENC_NA);
317
0
    offset += 1;
318
319
0
    proto_tree_add_item(tree, hf_someip_sd_option_reserved, tvb, offset, 1, ENC_NA);
320
0
    offset += 1;
321
322
0
    int config_string_length = length - offset + offset_orig;
323
0
    ti = proto_tree_add_item_ret_string(tree, hf_someip_sd_option_config_string, tvb, offset, config_string_length, ENC_ASCII | ENC_NA, pinfo->pool, &config_string);
324
0
    subtree = proto_item_add_subtree(ti, ett_someip_sd_config_string);
325
326
0
    uint8_t pos = 0;
327
0
    uint8_t element_length;
328
0
    while (config_string != NULL && config_string_length - pos > 0) {
329
0
        element_length = config_string[pos];
330
0
        pos++;
331
332
0
        if (element_length == 0) {
333
0
            break;
334
0
        }
335
336
0
        if (element_length > config_string_length - pos) {
337
0
            expert_add_info(pinfo, ti, &ei_someipsd_config_string_malformed);
338
0
            break;
339
0
        }
340
341
0
        proto_tree_add_item(subtree, hf_someip_sd_option_config_string_element, tvb, offset + pos, element_length, ENC_ASCII | ENC_NA);
342
0
        pos += element_length;
343
0
    }
344
0
}
345
346
static void
347
0
dissect_someip_sd_pdu_option_loadbalancing(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, uint32_t offset, uint32_t length, int optionnum) {
348
0
    tree = proto_tree_add_subtree_format(tree, tvb, offset, length, ett_someip_sd_option, NULL, "%d: Load Balancing Option", optionnum);
349
350
    /* Add common fields */
351
0
    proto_tree_add_item(tree, hf_someip_sd_option_length, tvb, offset, 2, ENC_BIG_ENDIAN);
352
0
    offset += 2;
353
354
0
    proto_tree_add_item(tree, hf_someip_sd_option_type, tvb, offset, 1, ENC_NA);
355
0
    offset += 1;
356
357
0
    proto_tree_add_item(tree, hf_someip_sd_option_reserved, tvb, offset, 1, ENC_NA);
358
0
    offset += 1;
359
360
0
    proto_tree_add_item(tree, hf_someip_sd_option_lb_priority, tvb, offset, 2, ENC_BIG_ENDIAN);
361
0
    offset += 2;
362
363
0
    proto_tree_add_item(tree, hf_someip_sd_option_lb_weight, tvb, offset, 2, ENC_BIG_ENDIAN);
364
0
}
365
366
static void
367
0
dissect_someip_sd_pdu_option_ipv4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, uint32_t length, int optionnum, uint32_t option_ports[]) {
368
0
    uint8_t             type = 255;
369
0
    const char         *description = NULL;
370
0
    uint32_t            l4port = 0;
371
0
    uint32_t            l4proto = 0;
372
0
    const char         *l4protoname = NULL;
373
0
    const char         *ipstring = NULL;
374
375
0
    proto_item         *ti = NULL;
376
0
    proto_item         *ti_top = NULL;
377
378
0
    type = tvb_get_uint8(tvb, offset + 2);
379
0
    description = val_to_str(type, sd_option_type, "(Unknown Option: %d)");
380
0
    tree = proto_tree_add_subtree_format(tree, tvb, offset, length, ett_someip_sd_option, &ti_top, "%d: %s Option", optionnum, description);
381
382
0
    if (length != SD_OPTION_IPV4_LENGTH) {
383
0
        expert_add_info(pinfo, ti_top, &ei_someipsd_option_wrong_length);
384
0
        return;
385
0
    }
386
387
    /* Add common fields */
388
0
    proto_tree_add_item(tree, hf_someip_sd_option_length, tvb, offset, 2, ENC_BIG_ENDIAN);
389
0
    offset += 2;
390
391
0
    proto_tree_add_item(tree, hf_someip_sd_option_type, tvb, offset, 1, ENC_NA);
392
0
    offset += 1;
393
394
0
    proto_tree_add_item(tree, hf_someip_sd_option_reserved, tvb, offset, 1, ENC_NA);
395
0
    offset += 1;
396
397
0
    proto_tree_add_item(tree, hf_someip_sd_option_ipv4, tvb, offset, 4, ENC_NA);
398
0
    ipstring = tvb_ip_to_str(pinfo->pool, tvb, offset);
399
0
    offset += 4;
400
401
0
    proto_tree_add_item(tree, hf_someip_sd_option_reserved2, tvb, offset, 1, ENC_NA);
402
0
    offset += 1;
403
404
0
    ti = proto_tree_add_item_ret_uint(tree, hf_someip_sd_option_proto, tvb, offset, 1, ENC_NA, &l4proto);
405
0
    l4protoname = val_to_str(l4proto, sd_option_l4protos, "Unknown Transport Protocol: %d");
406
0
    proto_item_append_text(ti, " (%s)", l4protoname);
407
408
0
    if (type != SD_OPTION_IPV4_ENDPOINT && l4proto == SD_OPTION_L4PROTO_TCP) {
409
0
        expert_add_info(pinfo, ti_top, &ei_someipsd_L4_protocol_unsupported);
410
0
    }
411
0
    offset += 1;
412
413
0
    proto_tree_add_item_ret_uint(tree, hf_someip_sd_option_port, tvb, offset, 2, ENC_BIG_ENDIAN, &l4port);
414
415
0
    proto_item_append_text(ti_top, " (%s:%d (%s))", ipstring, l4port, l4protoname);
416
417
0
    option_ports[optionnum] = ((uint32_t)l4proto << 24) + l4port;
418
0
}
419
420
static void
421
0
dissect_someip_sd_pdu_option_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, uint32_t length, int optionnum, uint32_t option_ports[]) {
422
0
    uint8_t             type = 255;
423
0
    const char         *description = NULL;
424
0
    uint32_t            l4port = 0;
425
0
    uint32_t            l4proto = 0;
426
0
    const char         *l4protoname = NULL;
427
0
    const char         *ipstring = NULL;
428
0
    proto_item         *ti = NULL;
429
0
    proto_item         *ti_top = NULL;
430
431
0
    type = tvb_get_uint8(tvb, offset + 2);
432
0
    description = val_to_str(type, sd_option_type, "(Unknown Option: %d)");
433
434
0
    tree = proto_tree_add_subtree_format(tree, tvb, offset, length, ett_someip_sd_option, &ti_top, "%d: %s Option", optionnum, description);
435
436
0
    if (length != SD_OPTION_IPV6_LENGTH) {
437
0
        expert_add_info(pinfo, ti_top, &ei_someipsd_option_wrong_length);
438
0
        return;
439
0
    }
440
441
0
    proto_tree_add_item(tree, hf_someip_sd_option_length, tvb, offset, 2, ENC_BIG_ENDIAN);
442
0
    offset += 2;
443
444
0
    proto_tree_add_item(tree, hf_someip_sd_option_type, tvb, offset, 1, ENC_NA);
445
0
    offset += 1;
446
447
0
    proto_tree_add_item(tree, hf_someip_sd_option_reserved, tvb, offset, 1, ENC_NA);
448
0
    offset += 1;
449
450
0
    proto_tree_add_item(tree, hf_someip_sd_option_ipv6, tvb, offset, 16, ENC_NA);
451
0
    ipstring = tvb_ip6_to_str(pinfo->pool, tvb, offset);
452
0
    offset += 16;
453
454
0
    proto_tree_add_item(tree, hf_someip_sd_option_reserved2, tvb, offset, 1, ENC_NA);
455
0
    offset += 1;
456
457
0
    ti = proto_tree_add_item_ret_uint(tree, hf_someip_sd_option_proto, tvb, offset, 1, ENC_NA, &l4proto);
458
0
    l4protoname = val_to_str(l4proto, sd_option_l4protos, "(Unknown Transport Protocol: %d)");
459
0
    proto_item_append_text(ti, " (%s)", l4protoname);
460
461
0
    if (type != SD_OPTION_IPV6_ENDPOINT && l4proto == SD_OPTION_L4PROTO_TCP) {
462
0
        expert_add_info(pinfo, ti_top, &ei_someipsd_L4_protocol_unsupported);
463
0
    }
464
0
    offset += 1;
465
466
0
    proto_tree_add_item_ret_uint(tree, hf_someip_sd_option_port, tvb, offset, 2, ENC_BIG_ENDIAN, &l4port);
467
468
0
    proto_item_append_text(ti_top, " (%s:%d (%s))", ipstring, l4port, l4protoname);
469
470
0
    option_ports[optionnum] = ((uint32_t)l4proto << 24) + l4port;
471
0
}
472
473
static void
474
0
dissect_someip_sd_pdu_option_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, uint32_t length, int optionnum) {
475
0
    uint32_t            len = 0;
476
0
    proto_item         *ti;
477
478
0
    tree = proto_tree_add_subtree_format(tree, tvb, offset, length, ett_someip_sd_option, &ti, "%d: %s Option", optionnum,
479
0
        val_to_str_const(tvb_get_uint8(tvb, offset + 2), sd_option_type, "Unknown"));
480
481
0
    expert_add_info(pinfo, ti, &ei_someipsd_option_unknown);
482
483
0
    proto_tree_add_item_ret_uint(tree, hf_someip_sd_option_length, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
484
0
    offset += 2;
485
486
0
    proto_tree_add_item(tree, hf_someip_sd_option_type, tvb, offset, 1, ENC_NA);
487
0
    offset += 1;
488
489
0
    if (length > 3) {
490
0
        proto_tree_add_item(tree, hf_someip_sd_option_reserved, tvb, offset, 1, ENC_NA);
491
0
        offset += 1;
492
493
0
        if (length > 4) {
494
0
            proto_tree_add_item(tree, hf_someip_sd_option_data, tvb, offset, length - 4, ENC_NA);
495
0
        }
496
0
    }
497
0
}
498
499
static int
500
0
dissect_someip_sd_pdu_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *ti, uint32_t offset_orig, uint32_t length, uint32_t option_ports[], unsigned *option_count) {
501
0
    uint16_t            real_length = 0;
502
0
    uint8_t             option_type = 0;
503
0
    int                 optionnum = 0;
504
0
    tvbuff_t           *subtvb = NULL;
505
506
0
    uint32_t            offset = offset_orig;
507
508
0
    if (!tvb_bytes_exist(tvb, offset, SD_OPTION_MINLENGTH) || !tvb_bytes_exist(tvb, offset, length)) {
509
0
        expert_add_info(pinfo, ti, &ei_someipsd_option_array_truncated);
510
0
        return offset;
511
0
    }
512
513
0
    while (tvb_bytes_exist(tvb, offset, SD_OPTION_MINLENGTH)) {
514
0
        ws_assert(optionnum >= 0 && optionnum < SD_MAX_NUM_OPTIONS);
515
0
        option_ports[optionnum] = 0;
516
517
0
        real_length = tvb_get_ntohs(tvb, offset) + 3;
518
0
        option_type = tvb_get_uint8(tvb, offset + 2);
519
520
0
        if (!tvb_bytes_exist(tvb, offset, (int)real_length) || offset - offset_orig + real_length > length) {
521
0
            expert_add_info(pinfo, ti, &ei_someipsd_option_array_truncated);
522
0
            return offset;
523
0
        }
524
525
0
        subtvb = tvb_new_subset_length(tvb, offset, (int)real_length);
526
527
0
        switch (option_type) {
528
0
        case SD_OPTION_CONFIGURATION:
529
0
            dissect_someip_sd_pdu_option_configuration(subtvb, pinfo, tree, 0, real_length, optionnum);
530
0
            break;
531
0
        case SD_OPTION_LOADBALANCING:
532
0
            dissect_someip_sd_pdu_option_loadbalancing(subtvb, pinfo, tree, 0, real_length, optionnum);
533
0
            break;
534
0
        case SD_OPTION_IPV4_ENDPOINT:
535
0
        case SD_OPTION_IPV4_MULTICAST:
536
0
        case SD_OPTION_IPV4_SD_ENDPOINT:
537
0
            dissect_someip_sd_pdu_option_ipv4(subtvb, pinfo, tree, 0, real_length, optionnum, option_ports);
538
0
            break;
539
540
0
        case SD_OPTION_IPV6_ENDPOINT:
541
0
        case SD_OPTION_IPV6_MULTICAST:
542
0
        case SD_OPTION_IPV6_SD_ENDPOINT:
543
0
            dissect_someip_sd_pdu_option_ipv6(subtvb, pinfo, tree, 0, real_length, optionnum, option_ports);
544
0
            break;
545
546
0
        default:
547
0
            dissect_someip_sd_pdu_option_unknown(subtvb, pinfo, tree, 0, real_length, optionnum);
548
0
            break;
549
0
        }
550
0
        optionnum++;
551
0
        offset += real_length;
552
0
    }
553
554
0
    *option_count = optionnum;
555
556
0
    return offset;
557
0
}
558
559
static void
560
0
someip_sd_pdu_entry_append_text(proto_item *ti_entry, uint8_t category, uint16_t serviceid, uint16_t instanceid, uint8_t majorver, uint32_t minorver, uint16_t eventgroupid, char *buf_opt_ref) {
561
0
    if (category != SD_ENTRY_SERVICE && category != SD_ENTRY_EVENTGROUP) {
562
0
        return;
563
0
    }
564
565
0
    if (serviceid == 0xffff) {
566
0
        proto_item_append_text(ti_entry, " (Service ID ANY");
567
0
    } else {
568
0
        proto_item_append_text(ti_entry, " (Service ID 0x%04x", serviceid);
569
0
    }
570
571
0
    if (instanceid == 0xffff) {
572
0
        proto_item_append_text(ti_entry, ", Instance ID ANY");
573
0
    } else {
574
0
        proto_item_append_text(ti_entry, ", Instance ID 0x%04x", instanceid);
575
0
    }
576
577
0
    if (majorver == 0xff) {
578
0
        proto_item_append_text(ti_entry, ", Version ANY");
579
0
    } else {
580
0
        proto_item_append_text(ti_entry, ", Version %u", majorver);
581
0
    }
582
583
0
    switch (category) {
584
0
    case SD_ENTRY_SERVICE:
585
0
        if (minorver == 0xffffffff) {
586
0
            proto_item_append_text(ti_entry, ".ANY");
587
0
        } else {
588
0
            proto_item_append_text(ti_entry, ".%u", minorver);
589
0
        }
590
0
        break;
591
592
0
    case SD_ENTRY_EVENTGROUP:
593
0
        if (eventgroupid == 0xffff) {
594
0
            proto_item_append_text(ti_entry, ", Eventgroup ID ANY");
595
0
        } else {
596
0
            proto_item_append_text(ti_entry, ", Eventgroup ID 0x%04x", eventgroupid);
597
0
        }
598
0
        break;
599
0
    }
600
601
0
    proto_item_append_text(ti_entry, ", Options: %s)", buf_opt_ref);
602
0
}
603
604
static void
605
0
dissect_someip_sd_pdu_entry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset_orig, uint32_t length, uint8_t *type, uint32_t *ttl, uint64_t *uniqueid, uint32_t option_ports[], unsigned option_count, proto_item **ti_entry) {
606
0
    uint32_t            serviceid = 0;
607
0
    uint32_t            instanceid = 0;
608
0
    uint32_t            eventgroupid = 0;
609
0
    uint32_t            majorver = 0;
610
0
    uint32_t            minorver = 0;
611
0
    uint32_t            opt_index1;
612
0
    uint32_t            opt_index2;
613
0
    uint32_t            opt_num1;
614
0
    uint32_t            opt_num2;
615
616
0
    uint8_t             category = SD_ENTRY_UNKNOWN;
617
618
0
    const char         *description = NULL;
619
0
    static char         buf_opt_ref[32];
620
621
0
    proto_item         *ti;
622
623
0
    uint32_t            offset = offset_orig;
624
625
0
    *uniqueid = 0;
626
0
    *type = 255;
627
0
    *ttl = 0;
628
629
0
    if (length < SD_ENTRY_LENGTH || !tvb_bytes_exist(tvb, offset, length)) {
630
0
        return;
631
0
    }
632
633
    /* lets look ahead and find out the type and ttl */
634
0
    *type = tvb_get_uint8(tvb, offset);
635
0
    *ttl = tvb_get_ntoh24(tvb, offset + 9);
636
637
0
    if (*type < 4) {
638
0
        category = SD_ENTRY_SERVICE;
639
0
    } else if (*type >= 4 && *type < 8) {
640
0
        category = SD_ENTRY_EVENTGROUP;
641
0
    } else {
642
0
        *ti_entry = proto_tree_add_none_format(tree, hf_someip_sd_entry, tvb, offset, SD_ENTRY_LENGTH, "Unknown Entry (Type: %d)", *type);
643
0
        expert_add_info(pinfo, *ti_entry, &ei_someipsd_entry_unknown);
644
0
        return;
645
0
    }
646
647
0
    description = val_to_str_const(*type,
648
0
                                   (*ttl == 0) ? sd_entry_type_negative : sd_entry_type_positive,
649
0
                                   "Unknown");
650
651
0
    *ti_entry = proto_tree_add_none_format(tree, hf_someip_sd_entry, tvb, offset, SD_ENTRY_LENGTH, "%s Entry", description);
652
0
    tree = proto_item_add_subtree(*ti_entry, ett_someip_sd_entry);
653
654
0
    proto_tree_add_uint_format_value(tree, hf_someip_sd_entry_type, tvb, offset, 1, *type, "0x%02x (%s)", *type, description);
655
0
    offset += 1;
656
657
0
    proto_tree_add_item_ret_uint(tree, hf_someip_sd_entry_index1, tvb, offset, 1, ENC_BIG_ENDIAN, &opt_index1);
658
0
    offset += 1;
659
0
    proto_tree_add_item_ret_uint(tree, hf_someip_sd_entry_index2, tvb, offset, 1, ENC_BIG_ENDIAN, &opt_index2);
660
0
    offset += 1;
661
662
0
    proto_tree_add_item_ret_uint(tree, hf_someip_sd_entry_numopt1, tvb, offset, 1, ENC_NA, &opt_num1);
663
0
    proto_tree_add_item_ret_uint(tree, hf_someip_sd_entry_numopt2, tvb, offset, 1, ENC_NA, &opt_num2);
664
0
    offset += 1;
665
666
0
    if (opt_num1 != 0 && opt_num2 == 0) {
667
0
        snprintf(buf_opt_ref, 32, "%d-%d", opt_index1, opt_index1 + opt_num1 - 1);
668
0
    } else if (opt_num1 == 0 && opt_num2 != 0) {
669
0
        snprintf(buf_opt_ref, 32, "%d-%d", opt_index2, opt_index2 + opt_num2 - 1);
670
0
    } else if (opt_num1 != 0 && opt_num2 != 0) {
671
0
        snprintf(buf_opt_ref, 32, "%d-%d,%d-%d", opt_index1, opt_index1 + opt_num1 - 1, opt_index2, opt_index2 + opt_num2 - 1);
672
0
    } else {
673
0
        snprintf(buf_opt_ref, 32, "None");
674
0
    }
675
676
0
    ti = proto_tree_add_string(tree, hf_someip_sd_entry_opts_referenced, tvb, offset - 3, 3, buf_opt_ref);
677
0
    proto_item_set_generated(ti);
678
679
0
    ti = proto_tree_add_item_ret_uint(tree, hf_someip_sd_entry_serviceid, tvb, offset, 2, ENC_BIG_ENDIAN, &serviceid);
680
0
    description = someip_lookup_service_name((uint16_t)serviceid);
681
0
    if (description != NULL) {
682
0
        proto_item_append_text(ti, " (%s)", description);
683
0
        ti = proto_tree_add_string(tree, hf_someip_sd_entry_servicename, tvb, offset, 2, description);
684
0
        proto_item_set_generated(ti);
685
0
        proto_item_set_hidden(ti);
686
0
    }
687
0
    offset += 2;
688
689
0
    proto_tree_add_item_ret_uint(tree, hf_someip_sd_entry_instanceid, tvb, offset, 2, ENC_BIG_ENDIAN, &instanceid);
690
0
    offset += 2;
691
692
0
    proto_tree_add_item_ret_uint(tree, hf_someip_sd_entry_majorver, tvb, offset, 1, ENC_BIG_ENDIAN, &majorver);
693
0
    offset += 1;
694
695
0
    proto_tree_add_item(tree, hf_someip_sd_entry_ttl, tvb, offset, 3, ENC_BIG_ENDIAN);
696
0
    offset += 3;
697
698
    /* Add specific fields - i.e. the last line */
699
0
    if (category == SD_ENTRY_SERVICE) {
700
0
        proto_tree_add_item_ret_uint(tree, hf_someip_sd_entry_minorver, tvb, offset, 4, ENC_BIG_ENDIAN, &minorver);
701
0
        someip_sd_pdu_entry_append_text(*ti_entry, category, serviceid, instanceid, majorver, minorver, 0, buf_opt_ref);
702
0
    } else if (category == SD_ENTRY_EVENTGROUP) {
703
0
        proto_tree_add_item(tree, hf_someip_sd_entry_reserved, tvb, offset, 1, ENC_NA);
704
0
        offset += 1;
705
706
0
        proto_tree_add_item(tree, hf_someip_sd_entry_intial_event_flag, tvb, offset, 1, ENC_NA);
707
0
        proto_tree_add_item(tree, hf_someip_sd_entry_reserved2, tvb, offset, 1, ENC_NA);
708
0
        proto_tree_add_item(tree, hf_someip_sd_entry_counter, tvb, offset, 1, ENC_NA);
709
0
        offset += 1;
710
711
0
        ti = proto_tree_add_item_ret_uint(tree, hf_someip_sd_entry_eventgroupid, tvb, offset, 2, ENC_BIG_ENDIAN, &eventgroupid);
712
0
        description = someip_lookup_eventgroup_name((uint16_t)serviceid, (uint16_t)eventgroupid);
713
0
        if (description != NULL) {
714
0
            proto_item_append_text(ti, " (%s)", description);
715
0
            ti = proto_tree_add_string(tree, hf_someip_sd_entry_eventgroupname, tvb, offset, 2, description);
716
0
            proto_item_set_generated(ti);
717
0
            proto_item_set_hidden(ti);
718
0
        }
719
720
0
        someip_sd_pdu_entry_append_text(*ti_entry, category, serviceid, instanceid, majorver, 0, eventgroupid, buf_opt_ref);
721
0
    }
722
723
    /* lets add some combined filtering term */
724
0
    *uniqueid = (((uint64_t)serviceid) << 32) | (uint64_t)instanceid << 16 | (uint64_t)eventgroupid;
725
726
0
    ti = NULL;
727
0
    if (*ttl > 0) {
728
0
        switch (*type) {
729
0
        case SD_ENTRY_FIND_SERVICE:
730
0
            ti = proto_tree_add_uint64_format_value(tree, hf_someip_sd_entry_type_findservice, tvb, offset_orig, SD_ENTRY_LENGTH, *uniqueid, "on 0x%012" PRIx64, *uniqueid);
731
0
            break;
732
0
        case SD_ENTRY_OFFER_SERVICE:
733
0
            ti = proto_tree_add_uint64_format_value(tree, hf_someip_sd_entry_type_offerservice, tvb, offset_orig, SD_ENTRY_LENGTH, *uniqueid, "on 0x%012" PRIx64, *uniqueid);
734
0
            break;
735
0
        case SD_ENTRY_SUBSCRIBE_EVENTGROUP:
736
0
            ti = proto_tree_add_uint64_format_value(tree, hf_someip_sd_entry_type_subscribeeventgroup, tvb, offset_orig, SD_ENTRY_LENGTH, *uniqueid, "on 0x%012" PRIx64, *uniqueid);
737
0
            break;
738
0
        case SD_ENTRY_SUBSCRIBE_EVENTGROUP_ACK:
739
0
            ti = proto_tree_add_uint64_format_value(tree, hf_someip_sd_entry_type_subscribeeventgroupack, tvb, offset_orig, SD_ENTRY_LENGTH, *uniqueid, "on 0x%012" PRIx64, *uniqueid);
740
0
            break;
741
0
        }
742
0
    } else {
743
0
        switch (*type) {
744
0
        case SD_ENTRY_STOP_OFFER_SERVICE:
745
0
            ti = proto_tree_add_uint64_format_value(tree, hf_someip_sd_entry_type_stopofferservice, tvb, offset_orig, SD_ENTRY_LENGTH, *uniqueid, "on 0x%012" PRIx64, *uniqueid);
746
0
            break;
747
0
        case SD_ENTRY_STOP_SUBSCRIBE_EVENTGROUP:
748
0
            ti = proto_tree_add_uint64_format_value(tree, hf_someip_sd_entry_type_stopsubscribeeventgroup, tvb, offset_orig, SD_ENTRY_LENGTH, *uniqueid, "on 0x%012" PRIx64, *uniqueid);
749
0
            break;
750
0
        case SD_ENTRY_SUBSCRIBE_EVENTGROUP_NACK:
751
0
            ti = proto_tree_add_uint64_format_value(tree, hf_someip_sd_entry_type_subscribeeventgroupnack, tvb, offset_orig, SD_ENTRY_LENGTH, *uniqueid, "on 0x%012" PRIx64, *uniqueid);
752
0
            break;
753
0
        }
754
0
    }
755
756
0
    proto_item_set_hidden(ti);
757
758
    /* check for Offer Entry without referenced Endpoints */
759
0
    if (opt_num1 == 0 && opt_num2 == 0 && *type == SD_ENTRY_OFFER_SERVICE && *ttl > 0) {
760
0
        expert_add_info(pinfo, *ti_entry, &ei_someipsd_offer_without_endpoint);
761
0
    }
762
763
    /* register ports but we skip 0xfffe because of other-serv */
764
0
    if (serviceid != SOMEIP_SD_SERVICE_ID_OTHER_SERVICE && !PINFO_FD_VISITED(pinfo)) {
765
0
        someip_sd_register_ports(opt_index1, opt_num1, option_count, option_ports);
766
0
        someip_sd_register_ports(opt_index2, opt_num2, option_count, option_ports);
767
0
    }
768
769
    /* TAP */
770
0
    if (have_tap_listener(tap_someip_sd_entries)) {
771
0
        someip_sd_entries_tap_t *data = wmem_alloc(pinfo->pool, sizeof(someip_sd_entries_tap_t));
772
0
        data->entry_type = *type;
773
0
        data->service_id = (uint16_t)serviceid;
774
0
        data->major_version = (uint8_t)majorver;
775
0
        data->minor_version = minorver;
776
0
        data->instance_id = (uint16_t)instanceid;
777
0
        data->eventgroup_id = (uint16_t)eventgroupid;
778
0
        data->ttl = *ttl;
779
780
0
        tap_queue_packet(tap_someip_sd_entries, pinfo, data);
781
0
    }
782
0
}
783
784
static int
785
0
dissect_someip_sd_pdu_entries(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *ti, uint32_t offset, uint32_t length, uint32_t option_ports[], unsigned option_count) {
786
0
    proto_item *ti_entry;
787
788
0
    uint8_t     type;
789
0
    uint32_t    ttl;
790
0
    uint32_t    entry_flags = 0;
791
0
    uint32_t    stop_entry_flags = 0;
792
793
0
    uint64_t    uniqueid;
794
0
    uint64_t    last_uniqueid = 0xffffffffffffffff;
795
796
797
0
    while (length >= SD_ENTRY_LENGTH) {
798
0
        dissect_someip_sd_pdu_entry(tvb, pinfo, tree, offset, SD_ENTRY_LENGTH, &type, &ttl, &uniqueid, option_ports, option_count, &ti_entry);
799
0
        offset += SD_ENTRY_LENGTH;
800
0
        length -= SD_ENTRY_LENGTH;
801
802
        /* mark for attaching to info column */
803
0
        if (type < 32) {
804
0
            if (ttl == 0) {
805
0
                stop_entry_flags = stop_entry_flags | (1 << type);
806
0
            } else {
807
0
                entry_flags = entry_flags | (1 << type);
808
0
            }
809
0
        }
810
811
0
        if (type == SD_ENTRY_SUBSCRIBE_EVENTGROUP && ttl == 0) {
812
0
            last_uniqueid = uniqueid;
813
0
        } else {
814
0
            if ( (type == SD_ENTRY_SUBSCRIBE_EVENTGROUP && ttl > 0) && last_uniqueid == uniqueid ) {
815
0
                expert_add_info(pinfo, ti_entry, &ei_someipsd_entry_stopsubsub);
816
0
            }
817
818
0
            last_uniqueid = 0xffffffffffffffff;
819
0
        }
820
0
    }
821
822
    /* Add entry flags */
823
0
    if (stop_entry_flags != 0 || entry_flags != 0) {
824
0
        col_append_str(pinfo->cinfo, COL_INFO, " ");
825
0
    }
826
827
0
    if (entry_flags & (1 << SD_ENTRY_FIND_SERVICE)) {
828
0
        col_append_str(pinfo->cinfo, COL_INFO, "[Find]");
829
0
    }
830
831
0
    if (stop_entry_flags & (1 << SD_ENTRY_OFFER_SERVICE)) {
832
0
        col_append_str(pinfo->cinfo, COL_INFO, "[StopOffer]");
833
0
    }
834
835
0
    if (entry_flags & (1 << SD_ENTRY_OFFER_SERVICE)) {
836
0
        col_append_str(pinfo->cinfo, COL_INFO, "[Offer]");
837
0
    }
838
839
0
    if (stop_entry_flags & (1 << SD_ENTRY_SUBSCRIBE_EVENTGROUP)) {
840
0
        col_append_str(pinfo->cinfo, COL_INFO, "[StopSubscribe]");
841
0
    }
842
843
0
    if (entry_flags & (1 << SD_ENTRY_SUBSCRIBE_EVENTGROUP)) {
844
0
        col_append_str(pinfo->cinfo, COL_INFO, "[Subscribe]");
845
0
    }
846
847
0
    if (stop_entry_flags & (1 << SD_ENTRY_SUBSCRIBE_EVENTGROUP_ACK)) {
848
0
        col_append_str(pinfo->cinfo, COL_INFO, "[SubscribeNack]");
849
0
    }
850
851
0
    if (entry_flags & (1 << SD_ENTRY_SUBSCRIBE_EVENTGROUP_ACK)) {
852
0
        col_append_str(pinfo->cinfo, COL_INFO, "[SubscribeAck]");
853
0
    }
854
855
0
    if (length != 0) {
856
0
        expert_add_info(pinfo, ti, &ei_someipsd_entry_array_malformed);
857
0
    }
858
859
0
    return length;
860
0
}
861
862
static int
863
0
dissect_someip_sd_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
864
0
    uint32_t        offset = 0;
865
0
    uint32_t        length_entriesarray = 0;
866
0
    uint32_t        length_optionsarray = 0;
867
868
0
    proto_item     *ti = NULL;
869
0
    proto_item     *ti_sd_entries = NULL;
870
871
0
    proto_tree     *someip_sd_entries_tree = NULL;
872
0
    proto_tree     *someip_sd_options_tree = NULL;
873
0
    bool            stop_parsing_after_entries = false;
874
0
    uint32_t        offset_entriesarray;
875
876
    /* format for option_ports entries: 1 byte proto | 1 byte reserved | 2 byte port number*/
877
0
    static uint32_t option_ports[SD_MAX_NUM_OPTIONS];
878
0
    unsigned        option_count = 0;
879
880
0
    static int * const someipsd_flags[] = {
881
0
        &hf_someip_sd_rebootflag,
882
0
        &hf_someip_sd_unicastflag,
883
0
        &hf_someip_sd_explicitiniteventflag,
884
0
        NULL
885
0
    };
886
887
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, SOMEIP_SD_NAME);
888
0
    col_set_str(pinfo->cinfo, COL_INFO, SOMEIP_SD_NAME);
889
890
0
    ti = proto_tree_add_item(tree, proto_someip_sd, tvb, offset, -1, ENC_NA);
891
0
    tree = proto_item_add_subtree(ti, ett_someip_sd);
892
893
0
    if (!tvb_bytes_exist(tvb, offset, SOMEIP_SD_MIN_LENGTH)) {
894
0
        expert_add_info(pinfo, ti, &ei_someipsd_message_truncated);
895
0
        return tvb_reported_length(tvb);
896
0
    }
897
898
    /* add flags */
899
0
    proto_tree_add_bitmask(tree, tvb, offset, hf_someip_sd_flags, ett_someip_sd_flags, someipsd_flags, ENC_BIG_ENDIAN);
900
0
    offset += 1;
901
902
    /* add reserved */
903
0
    proto_tree_add_item(tree, hf_someip_sd_reserved, tvb, offset, 3, ENC_BIG_ENDIAN);
904
0
    offset += 3;
905
906
    /* add length of entries */
907
0
    proto_tree_add_item_ret_uint(tree, hf_someip_sd_length_entriesarray, tvb, offset, 4, ENC_BIG_ENDIAN, &length_entriesarray);
908
0
    offset += 4;
909
910
0
    if (!tvb_bytes_exist(tvb, offset, length_entriesarray)) {
911
0
        expert_add_info(pinfo, ti   , &ei_someipsd_message_truncated);
912
0
        return tvb_reported_length(tvb);
913
0
    }
914
915
0
    if (!tvb_bytes_exist(tvb, offset, length_entriesarray)) {
916
        /* truncated SD message - need to shorten buffer */
917
0
        length_entriesarray = tvb_captured_length_remaining(tvb, offset);
918
0
        expert_add_info(pinfo, ti, &ei_someipsd_message_truncated);
919
0
        stop_parsing_after_entries = true;
920
0
    }
921
922
    /* preparing entries array but not parsing it yet */
923
0
    ti_sd_entries = proto_tree_add_item(tree, hf_someip_sd_entries, tvb, offset, length_entriesarray, ENC_NA);
924
0
    someip_sd_entries_tree = proto_item_add_subtree(ti_sd_entries, ett_someip_sd_entries);
925
    /* save offset to parse entries later since we need to parse options first */
926
0
    offset_entriesarray = offset;
927
0
    offset += length_entriesarray;
928
929
0
    if (!stop_parsing_after_entries) {
930
        /* make sure we have a length field */
931
0
        if (tvb_bytes_exist(tvb, offset, 4)) {
932
933
            /* add options length */
934
0
            proto_tree_add_item_ret_uint(tree, hf_someip_sd_length_optionsarray, tvb, offset, 4, ENC_BIG_ENDIAN, &length_optionsarray);
935
0
            offset += 4;
936
937
0
            if (length_optionsarray > 0) {
938
0
                if (tvb_bytes_exist(tvb, offset, 1)) {
939
0
                    ti = proto_tree_add_item(tree, hf_someip_sd_options, tvb, offset, -1, ENC_NA);
940
0
                    someip_sd_options_tree = proto_item_add_subtree(ti, ett_someip_sd_options);
941
942
                    /* check, if enough bytes are left for optionsarray */
943
0
                    if (!tvb_bytes_exist(tvb, offset, length_optionsarray)) {
944
0
                        length_optionsarray = tvb_captured_length_remaining(tvb, offset);
945
0
                        expert_add_info(pinfo, ti, &ei_someipsd_message_truncated);
946
0
                        proto_item_append_text(ti, " (truncated!)");
947
0
                    }
948
949
                    /* updating to length we will work with */
950
0
                    if (length_optionsarray > 0) {
951
0
                        proto_item_set_len(ti, length_optionsarray);
952
0
                    }
953
954
0
                    dissect_someip_sd_pdu_options(tvb, pinfo, someip_sd_options_tree, ti, offset, length_optionsarray, option_ports, &option_count);
955
0
                    offset += length_optionsarray;
956
0
                } else {
957
0
                    expert_add_info(pinfo, ti, &ei_someipsd_message_truncated);
958
0
                }
959
0
            }
960
0
        }
961
0
    }
962
963
0
    if (length_entriesarray >= SD_ENTRY_LENGTH) {
964
0
        offset += dissect_someip_sd_pdu_entries(tvb, pinfo, someip_sd_entries_tree, ti_sd_entries, offset_entriesarray, length_entriesarray, option_ports, option_count);
965
0
    } else {
966
0
        expert_add_info(pinfo, ti_sd_entries, &ei_someipsd_entry_array_empty);
967
0
    }
968
0
    return offset;
969
0
}
970
971
/*******************************************
972
 **************** Statistics ***************
973
 *******************************************/
974
975
static void
976
0
someipsd_entries_stats_tree_init(stats_tree *st) {
977
0
    st_node_ip_src = stats_tree_create_node(st, st_str_ip_src, 0, STAT_DT_INT, true);
978
0
    stat_node_set_flags(st, st_str_ip_src, 0, false, ST_FLG_SORT_TOP);
979
0
    st_node_ip_dst = stats_tree_create_node(st, st_str_ip_dst, 0, STAT_DT_INT, true);
980
0
}
981
982
static void
983
0
stat_number_to_string_with_any(uint32_t value, unsigned max, char *format_string, char *ret, size_t size_limit) {
984
0
    if (value == max) {
985
0
        snprintf(ret, size_limit, "%s", "MAX");
986
0
    } else {
987
0
        snprintf(ret, size_limit, format_string, value);
988
0
    }
989
0
}
990
991
static void
992
0
stat_create_entry_summary_string(const someip_sd_entries_tap_t *data, char *ret, size_t size_limit) {
993
0
    char service_str[128];
994
0
    char instance_str[128];
995
0
    char majorver_str[128];
996
0
    char minorver_str[128];
997
0
    char eventgrp_str[128];
998
0
    char tmp[128];
999
1000
0
    char *service_name  = someip_lookup_service_name(data->service_id);
1001
0
    char *eventgrp_name = someip_lookup_eventgroup_name(data->service_id, data->eventgroup_id);
1002
1003
0
    stat_number_to_string_with_any(data->service_id, UINT32_MAX, "0x%04x", service_str, sizeof(service_str) - 1);
1004
0
    stat_number_to_string_with_any(data->instance_id, UINT32_MAX, "0x%04x", instance_str, sizeof(instance_str) - 1);
1005
0
    stat_number_to_string_with_any(data->major_version, UINT8_MAX, "%d", majorver_str, sizeof(majorver_str) - 1);
1006
1007
0
    switch (data->entry_type) {
1008
0
    case SD_ENTRY_FIND_SERVICE:
1009
0
    case SD_ENTRY_OFFER_SERVICE:
1010
0
        stat_number_to_string_with_any(data->minor_version, UINT32_MAX, "%d", minorver_str, sizeof(minorver_str) - 1);
1011
0
        if (service_name != NULL) {
1012
0
            snprintf(ret, size_limit, "Service %s (%s) Version %s.%s Instance %s", service_str, service_name, majorver_str, minorver_str, instance_str);
1013
0
        } else {
1014
0
            snprintf(ret, size_limit, "Service %s Version %s.%s Instance %s", service_str, majorver_str, minorver_str, instance_str);
1015
0
        }
1016
0
        break;
1017
1018
0
    case SD_ENTRY_SUBSCRIBE_EVENTGROUP:
1019
0
    case SD_ENTRY_SUBSCRIBE_EVENTGROUP_ACK:
1020
0
        stat_number_to_string_with_any(data->eventgroup_id, UINT32_MAX, "0x%04x", eventgrp_str, sizeof(eventgrp_str) - 1);
1021
0
        if (service_name != NULL) {
1022
0
            snprintf(tmp, sizeof(tmp) - 1, "Service %s (%s) Version %s Instance %s Eventgroup %s", service_str, service_name, majorver_str, instance_str, eventgrp_str);
1023
0
        } else {
1024
0
            snprintf(tmp, sizeof(tmp) - 1, "Service %s Version %s Instance %s Eventgroup %s", service_str, majorver_str, instance_str, eventgrp_str);
1025
0
        }
1026
0
        if (eventgrp_name != NULL) {
1027
0
            snprintf(ret, size_limit, "%s (%s)", tmp, eventgrp_name);
1028
0
        }
1029
0
        break;
1030
0
    }
1031
0
}
1032
1033
static tap_packet_status
1034
0
someipsd_entries_stats_tree_packet(stats_tree *st, packet_info *pinfo, epan_dissect_t *edt _U_, const void *p, tap_flags_t flags _U_) {
1035
0
    DISSECTOR_ASSERT(p);
1036
0
    const someip_sd_entries_tap_t *data = (const someip_sd_entries_tap_t *)p;
1037
0
    static char tmp_addr_str[256];
1038
1039
0
    snprintf(tmp_addr_str, sizeof(tmp_addr_str) - 1, "%s (%s)", address_to_str(pinfo->pool, &pinfo->net_src), address_to_name(&pinfo->net_src));
1040
0
    tick_stat_node(st, st_str_ip_src, 0, false);
1041
0
    int src_id = tick_stat_node(st, tmp_addr_str, st_node_ip_src, true);
1042
1043
0
    snprintf(tmp_addr_str, sizeof(tmp_addr_str) - 1, "%s (%s)", address_to_str(pinfo->pool, &pinfo->net_dst), address_to_name(&pinfo->net_dst));
1044
0
    tick_stat_node(st, st_str_ip_dst, 0, false);
1045
0
    int dst_id = tick_stat_node(st, tmp_addr_str, st_node_ip_dst, true);
1046
1047
0
    int tmp_id;
1048
0
    static char tmp_str[128];
1049
1050
0
    if (data->ttl == 0) {
1051
0
        switch (data->entry_type) {
1052
0
        case SD_ENTRY_STOP_OFFER_SERVICE:
1053
0
            stat_create_entry_summary_string(data, tmp_str, sizeof(tmp_str) - 1);
1054
0
            tmp_id = tick_stat_node(st, "Stop Offer Service", src_id, true);
1055
0
            tick_stat_node(st, tmp_str, tmp_id, false);
1056
0
            tmp_id = tick_stat_node(st, "Stop Offer Service", dst_id, true);
1057
0
            tick_stat_node(st, tmp_str, tmp_id, false);
1058
0
            break;
1059
0
        case SD_ENTRY_STOP_SUBSCRIBE_EVENTGROUP:
1060
0
            stat_create_entry_summary_string(data, tmp_str, sizeof(tmp_str) - 1);
1061
0
            tmp_id = tick_stat_node(st, "Stop Subscribe Eventgroup", src_id, true);
1062
0
            tick_stat_node(st, tmp_str, tmp_id, false);
1063
0
            tmp_id = tick_stat_node(st, "Stop Subscribe Eventgroup", dst_id, true);
1064
0
            tick_stat_node(st, tmp_str, tmp_id, false);
1065
0
            break;
1066
0
        case SD_ENTRY_SUBSCRIBE_EVENTGROUP_NACK:
1067
0
            stat_create_entry_summary_string(data, tmp_str, sizeof(tmp_str) - 1);
1068
0
            tmp_id = tick_stat_node(st, "Subscribe Eventgroup Nack", src_id, true);
1069
0
            tick_stat_node(st, tmp_str, tmp_id, false);
1070
0
            tmp_id = tick_stat_node(st, "Subscribe Eventgroup Nack", dst_id, true);
1071
0
            tick_stat_node(st, tmp_str, tmp_id, false);
1072
0
            break;
1073
0
        }
1074
0
    } else {
1075
0
        switch (data->entry_type) {
1076
0
        case SD_ENTRY_FIND_SERVICE:
1077
0
            stat_create_entry_summary_string(data, tmp_str, sizeof(tmp_str) - 1);
1078
0
            tmp_id = tick_stat_node(st, "Find Service", src_id, true);
1079
0
            tick_stat_node(st, tmp_str, tmp_id, false);
1080
0
            tmp_id = tick_stat_node(st, "Find Service", dst_id, true);
1081
0
            tick_stat_node(st, tmp_str, tmp_id, false);
1082
0
            break;
1083
0
        case SD_ENTRY_OFFER_SERVICE:
1084
0
            stat_create_entry_summary_string(data, tmp_str, sizeof(tmp_str) - 1);
1085
0
            tmp_id = tick_stat_node(st, "Offer Service", src_id, true);
1086
0
            tick_stat_node(st, tmp_str, tmp_id, false);
1087
0
            tmp_id = tick_stat_node(st, "Offer Service", dst_id, true);
1088
0
            tick_stat_node(st, tmp_str, tmp_id, false);
1089
0
            break;
1090
0
        case SD_ENTRY_SUBSCRIBE_EVENTGROUP:
1091
0
            stat_create_entry_summary_string(data, tmp_str, sizeof(tmp_str) - 1);
1092
0
            tmp_id = tick_stat_node(st, "Subscribe Eventgroup", src_id, true);
1093
0
            tick_stat_node(st, tmp_str, tmp_id, false);
1094
0
            tmp_id = tick_stat_node(st, "Subscribe Eventgroup", dst_id, true);
1095
0
            tick_stat_node(st, tmp_str, tmp_id, false);
1096
0
            break;
1097
0
        case SD_ENTRY_SUBSCRIBE_EVENTGROUP_ACK:
1098
0
            stat_create_entry_summary_string(data, tmp_str, sizeof(tmp_str) - 1);
1099
0
            tmp_id = tick_stat_node(st, "Subscribe Eventgroup Ack", src_id, true);
1100
0
            tick_stat_node(st, tmp_str, tmp_id, false);
1101
0
            tmp_id = tick_stat_node(st, "Subscribe Eventgroup Ack", dst_id, true);
1102
0
            tick_stat_node(st, tmp_str, tmp_id, false);
1103
0
            break;
1104
0
        }
1105
0
    }
1106
1107
0
    return TAP_PACKET_REDRAW;
1108
0
}
1109
1110
void
1111
14
proto_register_someip_sd(void) {
1112
14
    module_t *someipsd_module;
1113
1114
14
    expert_module_t *expert_module_someip_sd;
1115
1116
    /* data fields */
1117
14
    static hf_register_info hf_sd[] = {
1118
14
        { &hf_someip_sd_flags,
1119
14
            { "Flags", "someipsd.flags",
1120
14
            FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1121
14
        { &hf_someip_sd_rebootflag,
1122
14
            { "Reboot Flag", "someipsd.flags.reboot",
1123
14
            FT_BOOLEAN, 8, TFS(&sd_reboot_flag), SOMEIP_SD_REBOOT_FLAG, NULL, HFILL }},
1124
14
        { &hf_someip_sd_unicastflag,
1125
14
            { "Unicast Flag", "someipsd.flags.unicast",
1126
14
            FT_BOOLEAN, 8, TFS(&sd_unicast_flag), SOMEIP_SD_UNICAST_FLAG, NULL, HFILL }},
1127
14
        { &hf_someip_sd_explicitiniteventflag,
1128
14
            { "Explicit Initial Events Flag", "someipsd.flags.exp_init_events",
1129
14
            FT_BOOLEAN, 8, TFS(&sd_eiec_flag), SOMEIP_SD_EXPL_INIT_EVENT_REQ_FLAG, NULL, HFILL }},
1130
14
        { &hf_someip_sd_reserved,
1131
14
            { "Reserved", "someipsd.reserved",
1132
14
            FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1133
1134
14
        { &hf_someip_sd_length_entriesarray,
1135
14
            { "Length of Entries Array", "someipsd.length_entriesarray",
1136
14
            FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1137
14
        { &hf_someip_sd_entries,
1138
14
            { "Entries Array", "someipsd.entries",
1139
14
            FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1140
14
        { &hf_someip_sd_entry,
1141
14
            { "Entry", "someipsd.entry",
1142
14
            FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1143
14
        { &hf_someip_sd_entry_type,
1144
14
            { "Type", "someipsd.entry.type",
1145
14
            FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1146
14
        { &hf_someip_sd_entry_index1,
1147
14
            { "Index 1", "someipsd.entry.index1",
1148
14
            FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1149
14
        { &hf_someip_sd_entry_index2,
1150
14
            { "Index 2", "someipsd.entry.index2",
1151
14
            FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1152
14
        { &hf_someip_sd_entry_numopt1,
1153
14
            { "Number of Opts 1", "someipsd.entry.numopt1",
1154
14
            FT_UINT8, BASE_HEX, NULL, 0xf0, NULL, HFILL }},
1155
14
        { &hf_someip_sd_entry_numopt2,
1156
14
            { "Number of Opts 2", "someipsd.entry.numopt2",
1157
14
            FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }},
1158
14
        { &hf_someip_sd_entry_opts_referenced,
1159
14
            { "Options referenced", "someipsd.entry.optionsreferenced",
1160
14
            FT_STRING, BASE_NONE, NULL, 0x00, NULL, HFILL }},
1161
1162
14
        { &hf_someip_sd_entry_serviceid,
1163
14
            { "Service ID", "someipsd.entry.serviceid",
1164
14
            FT_UINT16, BASE_HEX | BASE_SPECIAL_VALS, VALS(sd_serviceid_vs), 0x0, NULL, HFILL }},
1165
14
        { &hf_someip_sd_entry_servicename,
1166
14
            { "Service Name", "someipsd.entry.servicename",
1167
14
            FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1168
14
        { &hf_someip_sd_entry_instanceid,
1169
14
            { "Instance ID", "someipsd.entry.instanceid",
1170
14
            FT_UINT16, BASE_HEX | BASE_SPECIAL_VALS, VALS(sd_instanceid_vs), 0x0, NULL, HFILL }},
1171
14
        { &hf_someip_sd_entry_majorver,
1172
14
            { "Major Version", "someipsd.entry.majorver",
1173
14
            FT_UINT8, BASE_DEC | BASE_SPECIAL_VALS, VALS(sd_majorversion_vs), 0x0, NULL, HFILL }},
1174
14
        { &hf_someip_sd_entry_ttl,
1175
14
            { "TTL", "someipsd.entry.ttl",
1176
14
            FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1177
14
        { &hf_someip_sd_entry_minorver,
1178
14
            { "Minor Version", "someipsd.entry.minorver",
1179
14
            FT_UINT32, BASE_DEC | BASE_SPECIAL_VALS, VALS(sd_minorversion_vs), 0x0, NULL, HFILL }},
1180
14
        { &hf_someip_sd_entry_eventgroupid,
1181
14
            { "Eventgroup ID", "someipsd.entry.eventgroupid",
1182
14
            FT_UINT16, BASE_HEX | BASE_SPECIAL_VALS, VALS(sd_eventgroupid_vs), 0x0, NULL, HFILL }},
1183
14
        { &hf_someip_sd_entry_eventgroupname,
1184
14
            { "Eventgroup Name", "someipsd.entry.eventgroupname",
1185
14
            FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1186
14
        { &hf_someip_sd_entry_reserved,
1187
14
            { "Reserved", "someipsd.entry.reserved",
1188
14
            FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
1189
14
        { &hf_someip_sd_entry_counter,
1190
14
            { "Counter", "someipsd.entry.counter",
1191
14
            FT_UINT8, BASE_HEX, NULL, SD_EVENTGROUP_ENTRY_COUNTER_MASK, NULL, HFILL } },
1192
14
        { &hf_someip_sd_entry_reserved2,
1193
14
            { "Reserved", "someipsd.entry.reserved2",
1194
14
            FT_UINT8, BASE_HEX, NULL, SD_EVENTGROUP_ENTRY_RES2_MASK, NULL, HFILL } },
1195
14
        { &hf_someip_sd_entry_intial_event_flag,
1196
14
            { "Initial Event Request", "someipsd.entry.initialevents",
1197
14
            FT_BOOLEAN, 8, NULL, SD_ENTRY_INIT_EVENT_REQ_MASK, NULL, HFILL } },
1198
1199
14
        { &hf_someip_sd_length_optionsarray,
1200
14
            { "Length of Options Array", "someipsd.length_optionsarray",
1201
14
            FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1202
14
        { &hf_someip_sd_options,
1203
14
            { "Options Array", "someipsd.options",
1204
14
            FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1205
1206
14
        { &hf_someip_sd_option_type,
1207
14
            { "Type", "someipsd.option.type",
1208
14
            FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1209
14
        { &hf_someip_sd_option_length,
1210
14
            { "Length", "someipsd.option.length",
1211
14
            FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1212
14
        { &hf_someip_sd_option_reserved,
1213
14
            { "Reserved", "someipsd.option.reserved",
1214
14
            FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1215
14
        { &hf_someip_sd_option_ipv4,
1216
14
            { "IPv4 Address", "someipsd.option.ipv4address",
1217
14
            FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1218
14
        { &hf_someip_sd_option_ipv6,
1219
14
            { "IPv6 Address", "someipsd.option.ipv6address",
1220
14
            FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1221
14
        { &hf_someip_sd_option_port,
1222
14
            { "Port", "someipsd.option.port",
1223
14
            FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1224
14
        { &hf_someip_sd_option_proto,
1225
14
            { "Protocol", "someipsd.option.proto",
1226
14
            FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1227
14
        { &hf_someip_sd_option_reserved2,
1228
14
            { "Reserved 2", "someipsd.option.reserved2",
1229
14
            FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1230
14
        { &hf_someip_sd_option_data,
1231
14
            { "Unknown Data", "someipsd.option.unknown_data",
1232
14
            FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1233
14
        { &hf_someip_sd_option_config_string,
1234
14
            { "Configuration String", "someipsd.option.config_string",
1235
14
            FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1236
14
        { &hf_someip_sd_option_config_string_element,
1237
14
            { "Configuration String Element", "someipsd.option.config_string_element",
1238
14
            FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1239
14
        { &hf_someip_sd_option_lb_priority,
1240
14
            { "Priority", "someipsd.option.priority",
1241
14
            FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1242
14
        { &hf_someip_sd_option_lb_weight,
1243
14
            { "Weight", "someipsd.option.weight",
1244
14
            FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1245
14
        { &hf_someip_sd_entry_type_offerservice,
1246
14
            { "Offer Service", "someipsd.entry.offerservice",
1247
14
            FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1248
14
        { &hf_someip_sd_entry_type_stopofferservice,
1249
14
            { "Stop Offer Service", "someipsd.entry.stopofferservice",
1250
14
            FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1251
14
        { &hf_someip_sd_entry_type_findservice,
1252
14
            { "Find Service", "someipsd.entry.findservice",
1253
14
            FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1254
1255
14
        { &hf_someip_sd_entry_type_subscribeeventgroup,
1256
14
            { "Subscribe Eventgroup", "someipsd.entry.subscribeeventgroup",
1257
14
            FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1258
14
        { &hf_someip_sd_entry_type_stopsubscribeeventgroup,
1259
14
            { "Stop Subscribe Eventgroup", "someipsd.entry.stopsubscribeeventgroup",
1260
14
            FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1261
1262
14
        { &hf_someip_sd_entry_type_subscribeeventgroupack,
1263
14
            { "Subscribe Eventgroup ACK", "someipsd.entry.subscribeeventgroupack",
1264
14
            FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1265
14
        { &hf_someip_sd_entry_type_subscribeeventgroupnack,
1266
14
            { "Subscribe Eventgroup NACK", "someipsd.entry.subscribeeventgroupnack",
1267
14
            FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1268
14
    };
1269
1270
14
    static int *ett_sd[] = {
1271
14
        &ett_someip_sd,
1272
14
        &ett_someip_sd_flags,
1273
14
        &ett_someip_sd_entries,
1274
14
        &ett_someip_sd_entry,
1275
14
        &ett_someip_sd_options,
1276
14
        &ett_someip_sd_option,
1277
14
        &ett_someip_sd_config_string,
1278
14
    };
1279
1280
14
    static ei_register_info ei_sd[] = {
1281
14
        { &ei_someipsd_message_truncated,{ "someipsd.message_truncated", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Truncated message!", EXPFILL } },
1282
14
        { &ei_someipsd_entry_array_malformed,{ "someipsd.entry_array_malformed", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Entry Array length not multiple of 16 bytes!", EXPFILL } },
1283
14
        { &ei_someipsd_entry_array_empty,{ "someipsd.entry_array_empty", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Empty Entry Array!", EXPFILL } },
1284
14
        { &ei_someipsd_entry_unknown,{ "someipsd.entry_unknown", PI_MALFORMED, PI_WARN, "SOME/IP-SD Unknown Entry!", EXPFILL } },
1285
14
        { &ei_someipsd_offer_without_endpoint,{ "someipsd.offer_no_endpoints", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Offer Service references no endpoints!", EXPFILL } },
1286
14
        { &ei_someipsd_entry_stopsubsub,{ "someipsd.stopsub_sub", PI_PROTOCOL, PI_WARN, "SOME/IP-SD Subscribe after Stop Subscribe!", EXPFILL } },
1287
14
        { &ei_someipsd_option_array_truncated,{ "someipsd.option_array_truncated", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Option Array truncated!", EXPFILL } },
1288
14
        { &ei_someipsd_option_array_bytes_left,{ "someipsd.option_array_bytes_left", PI_MALFORMED, PI_WARN, "SOME/IP-SD Option Array bytes left after parsing options!", EXPFILL } },
1289
14
        { &ei_someipsd_option_unknown,{ "someipsd.option_unknown", PI_MALFORMED, PI_WARN, "SOME/IP-SD Unknown Option!", EXPFILL } },
1290
14
        { &ei_someipsd_option_wrong_length,{ "someipsd.option_wrong_length", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Option length is incorrect!", EXPFILL } },
1291
14
        { &ei_someipsd_L4_protocol_unsupported,{ "someipsd.L4_protocol_unsupported", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Unsupported Layer 4 Protocol!", EXPFILL } },
1292
14
        { &ei_someipsd_config_string_malformed,{ "someipsd.config_string_malformed", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Configuration String malformed!", EXPFILL } },
1293
14
    };
1294
1295
    /* Register Protocol, Fields, ETTs, Expert Info, Taps, Dissector */
1296
14
    proto_someip_sd = proto_register_protocol(SOMEIP_SD_NAME_LONG, SOMEIP_SD_NAME, SOMEIP_SD_NAME_FILTER);
1297
14
    proto_register_field_array(proto_someip_sd, hf_sd, array_length(hf_sd));
1298
14
    proto_register_subtree_array(ett_sd, array_length(ett_sd));
1299
14
    expert_module_someip_sd = expert_register_protocol(proto_someip_sd);
1300
14
    expert_register_field_array(expert_module_someip_sd, ei_sd, array_length(ei_sd));
1301
14
    tap_someip_sd_entries = register_tap("someipsd_entries");
1302
14
    someip_sd_handle = register_dissector(SOMEIP_SD_NAME_FILTER, dissect_someip_sd_pdu, proto_someip_sd);
1303
1304
    /* Register preferences */
1305
14
    someipsd_module = prefs_register_protocol(proto_someip_sd, NULL);
1306
1307
14
    range_convert_str(wmem_epan_scope(), &someip_ignore_ports_udp, "", 65535);
1308
14
    prefs_register_range_preference(someipsd_module, "ports.udp.ignore", "UDP Ports ignored",
1309
14
        "SOME/IP Ignore Port Ranges UDP. These ports are not automatically added by the SOME/IP-SD.",
1310
14
        &someip_ignore_ports_udp, 65535);
1311
1312
14
    range_convert_str(wmem_epan_scope(), &someip_ignore_ports_tcp, "", 65535);
1313
14
    prefs_register_range_preference(someipsd_module, "ports.tcp.ignore", "TCP Ports ignored",
1314
14
        "SOME/IP Ignore Port Ranges TCP. These ports are not automatically added by the SOME/IP-SD.",
1315
14
        &someip_ignore_ports_tcp, 65535);
1316
14
 }
1317
1318
void
1319
14
proto_reg_handoff_someip_sd(void) {
1320
14
    dissector_add_uint("someip.messageid", SOMEIP_SD_MESSAGEID, someip_sd_handle);
1321
14
    stats_tree_register("someipsd_entries", "someipsd_entries", "SOME/IP-SD Entries", 0, someipsd_entries_stats_tree_packet, someipsd_entries_stats_tree_init, NULL);
1322
14
}
1323
1324
/*
1325
 * Editor modelines
1326
 *
1327
 * Local Variables:
1328
 * c-basic-offset: 4
1329
 * tab-width: 8
1330
 * indent-tabs-mode: nil
1331
 * End:
1332
 *
1333
 * ex: set shiftwidth=4 tabstop=8 expandtab:
1334
 * :indentSize=4:tabSize=8:noTabs=true:
1335
 */