Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-doip.c
Line
Count
Source
1
/* packet-doip.c
2
 * Routines for DoIP (ISO13400) protocol packet disassembly
3
 *
4
 * Wireshark - Network traffic analyzer
5
 * By Gerald Combs <gerald@wireshark.org>
6
 * Copyright 1998 Gerald Combs
7
 *
8
 * SPDX-License-Identifier: GPL-2.0-or-later
9
 */
10
11
#include "config.h"
12
#include <epan/packet.h>
13
#include <epan/uat.h>
14
#include <epan/expert.h>
15
#include <epan/proto_data.h>
16
17
#include "packet-tcp.h"
18
#include "packet-tls.h"
19
#include "packet-doip.h"
20
21
void proto_register_doip(void);
22
void proto_reg_handoff_doip(void);
23
24
25
32
#define DOIP_PORT                                  13400
26
16
#define DOIP_TLS_PORT                               3496
27
28
1
#define DOIP_GENERIC_NACK                          0x0000
29
2
#define DOIP_VEHICLE_IDENTIFICATION_REQ            0x0001
30
0
#define DOIP_VEHICLE_IDENTIFICATION_REQ_EID        0x0002
31
1
#define DOIP_VEHICLE_IDENTIFICATION_REQ_VIN        0x0003
32
0
#define DOIP_VEHICLE_ANNOUNCEMENT_MESSAGE          0x0004
33
0
#define DOIP_ROUTING_ACTIVATION_REQUEST            0x0005
34
0
#define DOIP_ROUTING_ACTIVATION_RESPONSE           0x0006
35
0
#define DOIP_ALIVE_CHECK_REQUEST                   0x0007
36
0
#define DOIP_ALIVE_CHECK_RESPONSE                  0x0008
37
0
#define DOIP_ENTITY_STATUS_REQUEST                 0x4001
38
0
#define DOIP_ENTITY_STATUS_RESPONSE                0x4002
39
0
#define DOIP_POWER_INFORMATION_REQUEST             0x4003
40
0
#define DOIP_POWER_INFORMATION_RESPONSE            0x4004
41
22
#define DOIP_DIAGNOSTIC_MESSAGE                    0x8001
42
0
#define DOIP_DIAGNOSTIC_MESSAGE_ACK                0x8002
43
0
#define DOIP_DIAGNOSTIC_MESSAGE_NACK               0x8003
44
45
46
/* Header */
47
512
#define DOIP_VERSION_OFFSET                        0
48
426
#define DOIP_VERSION_LEN                           1
49
399
#define DOIP_INV_VERSION_OFFSET                    (DOIP_VERSION_OFFSET + DOIP_VERSION_LEN)
50
367
#define DOIP_INV_VERSION_LEN                       1
51
340
#define DOIP_TYPE_OFFSET                           (DOIP_INV_VERSION_OFFSET + DOIP_INV_VERSION_LEN)
52
286
#define DOIP_TYPE_LEN                              2
53
259
#define DOIP_LENGTH_OFFSET                         (DOIP_TYPE_OFFSET + DOIP_TYPE_LEN)
54
232
#define DOIP_LENGTH_LEN                            4
55
206
#define DOIP_HEADER_LEN                            (DOIP_LENGTH_OFFSET + DOIP_LENGTH_LEN)
56
57
#define RESERVED_VER                               0x00
58
54
#define ISO13400_2010                              0x01
59
54
#define ISO13400_2012                              0x02
60
54
#define ISO13400_2019                              0x03
61
54
#define ISO13400_2019_AMD1                         0x04
62
54
#define DEFAULT_VALUE                              0xFF
63
64
65
/* Generic NACK */
66
1
#define DOIP_GENERIC_NACK_OFFSET                   DOIP_HEADER_LEN
67
1
#define DOIP_GENERIC_NACK_LEN                      1
68
69
70
/* Common */
71
0
#define DOIP_COMMON_VIN_LEN                        17
72
0
#define DOIP_COMMON_EID_LEN                        6
73
74
75
/* Vehicle identification request */
76
0
#define DOIP_VEHICLE_IDENTIFICATION_EID_OFFSET     DOIP_HEADER_LEN
77
0
#define DOIP_VEHICLE_IDENTIFICATION_VIN_OFFSET     DOIP_HEADER_LEN
78
79
80
/* Routing activation request */
81
0
#define DOIP_ROUTING_ACTIVATION_REQ_SRC_OFFSET     DOIP_HEADER_LEN
82
0
#define DOIP_ROUTING_ACTIVATION_REQ_SRC_LEN        2
83
0
#define DOIP_ROUTING_ACTIVATION_REQ_TYPE_OFFSET    (DOIP_ROUTING_ACTIVATION_REQ_SRC_OFFSET + DOIP_ROUTING_ACTIVATION_REQ_SRC_LEN)
84
0
#define DOIP_ROUTING_ACTIVATION_REQ_TYPE_LEN_V1    2
85
0
#define DOIP_ROUTING_ACTIVATION_REQ_TYPE_LEN_V2    1
86
0
#define DOIP_ROUTING_ACTIVATION_REQ_ISO_OFFSET_V1  (DOIP_ROUTING_ACTIVATION_REQ_TYPE_OFFSET + DOIP_ROUTING_ACTIVATION_REQ_TYPE_LEN_V1)
87
0
#define DOIP_ROUTING_ACTIVATION_REQ_ISO_OFFSET_V2  (DOIP_ROUTING_ACTIVATION_REQ_TYPE_OFFSET + DOIP_ROUTING_ACTIVATION_REQ_TYPE_LEN_V2)
88
0
#define DOIP_ROUTING_ACTIVATION_REQ_ISO_LEN        4
89
0
#define DOIP_ROUTING_ACTIVATION_REQ_OEM_OFFSET_V1  (DOIP_ROUTING_ACTIVATION_REQ_ISO_OFFSET_V1 + DOIP_ROUTING_ACTIVATION_REQ_ISO_LEN)
90
0
#define DOIP_ROUTING_ACTIVATION_REQ_OEM_OFFSET_V2  (DOIP_ROUTING_ACTIVATION_REQ_ISO_OFFSET_V2 + DOIP_ROUTING_ACTIVATION_REQ_ISO_LEN)
91
0
#define DOIP_ROUTING_ACTIVATION_REQ_OEM_LEN        4
92
93
94
/* Routing activation response */
95
0
#define DOIP_ROUTING_ACTIVATION_RES_TESTER_OFFSET  DOIP_HEADER_LEN
96
0
#define DOIP_ROUTING_ACTIVATION_RES_TESTER_LEN     2
97
0
#define DOIP_ROUTING_ACTIVATION_RES_ENTITY_OFFSET  (DOIP_ROUTING_ACTIVATION_RES_TESTER_OFFSET + DOIP_ROUTING_ACTIVATION_RES_TESTER_LEN)
98
0
#define DOIP_ROUTING_ACTIVATION_RES_ENTITY_LEN     2
99
0
#define DOIP_ROUTING_ACTIVATION_RES_CODE_OFFSET    (DOIP_ROUTING_ACTIVATION_RES_ENTITY_OFFSET + DOIP_ROUTING_ACTIVATION_RES_ENTITY_LEN)
100
0
#define DOIP_ROUTING_ACTIVATION_RES_CODE_LEN       1
101
0
#define DOIP_ROUTING_ACTIVATION_RES_ISO_OFFSET     (DOIP_ROUTING_ACTIVATION_RES_CODE_OFFSET + DOIP_ROUTING_ACTIVATION_RES_CODE_LEN)
102
0
#define DOIP_ROUTING_ACTIVATION_RES_ISO_LEN        4
103
0
#define DOIP_ROUTING_ACTIVATION_RES_OEM_OFFSET     (DOIP_ROUTING_ACTIVATION_RES_ISO_OFFSET + DOIP_ROUTING_ACTIVATION_RES_ISO_LEN)
104
0
#define DOIP_ROUTING_ACTIVATION_RES_OEM_LEN        4
105
106
107
/* Vehicle announcement message */
108
0
#define DOIP_VEHICLE_ANNOUNCEMENT_VIN_OFFSET       DOIP_HEADER_LEN
109
0
#define DOIP_VEHICLE_ANNOUNCEMENT_ADDRESS_OFFSET   (DOIP_VEHICLE_ANNOUNCEMENT_VIN_OFFSET + DOIP_COMMON_VIN_LEN)
110
0
#define DOIP_VEHICLE_ANNOUNCEMENT_ADDRESS_LEN      2
111
0
#define DOIP_VEHICLE_ANNOUNCEMENT_EID_OFFSET       (DOIP_VEHICLE_ANNOUNCEMENT_ADDRESS_OFFSET + DOIP_VEHICLE_ANNOUNCEMENT_ADDRESS_LEN)
112
0
#define DOIP_VEHICLE_ANNOUNCEMENT_GID_OFFSET       (DOIP_VEHICLE_ANNOUNCEMENT_EID_OFFSET + DOIP_COMMON_EID_LEN)
113
0
#define DOIP_VEHICLE_ANNOUNCEMENT_GID_LEN          6
114
0
#define DOIP_VEHICLE_ANNOUNCEMENT_ACTION_OFFSET    (DOIP_VEHICLE_ANNOUNCEMENT_GID_OFFSET + DOIP_VEHICLE_ANNOUNCEMENT_GID_LEN)
115
0
#define DOIP_VEHICLE_ANNOUNCEMENT_ACTION_LEN       1
116
0
#define DOIP_VEHICLE_ANNOUNCEMENT_SYNC_OFFSET      (DOIP_VEHICLE_ANNOUNCEMENT_ACTION_OFFSET + DOIP_VEHICLE_ANNOUNCEMENT_ACTION_LEN)
117
0
#define DOIP_VEHICLE_ANNOUNCEMENT_SYNC_LEN         1
118
119
120
/* Alive check response */
121
0
#define DOIP_ALIVE_CHECK_RESPONSE_SOURCE_OFFSET    DOIP_HEADER_LEN
122
0
#define DOIP_ALIVE_CHECK_RESPONSE_SOURCE_LEN       2
123
124
125
/* Entity status response */
126
0
#define DOIP_ENTITY_STATUS_RESPONSE_NODE_OFFSET    DOIP_HEADER_LEN
127
0
#define DOIP_ENTITY_STATUS_RESPONSE_NODE_LEN       1
128
0
#define DOIP_ENTITY_STATUS_RESPONSE_MCTS_OFFSET    (DOIP_ENTITY_STATUS_RESPONSE_NODE_OFFSET + DOIP_ENTITY_STATUS_RESPONSE_NODE_LEN)
129
0
#define DOIP_ENTITY_STATUS_RESPONSE_MCTS_LEN       1
130
0
#define DOIP_ENTITY_STATUS_RESPONSE_NCTS_OFFSET    (DOIP_ENTITY_STATUS_RESPONSE_MCTS_OFFSET + DOIP_ENTITY_STATUS_RESPONSE_MCTS_LEN)
131
0
#define DOIP_ENTITY_STATUS_RESPONSE_NCTS_LEN       1
132
0
#define DOIP_ENTITY_STATUS_RESPONSE_MDS_OFFSET     (DOIP_ENTITY_STATUS_RESPONSE_NCTS_OFFSET + DOIP_ENTITY_STATUS_RESPONSE_NCTS_LEN)
133
0
#define DOIP_ENTITY_STATUS_RESPONSE_MDS_LEN        4
134
135
136
/* Diagnostic power mode information response */
137
0
#define DOIP_POWER_MODE_OFFSET                     DOIP_HEADER_LEN
138
0
#define DOIP_POWER_MODE_LEN                        1
139
140
141
/* Common */
142
66
#define DOIP_DIAG_COMMON_SOURCE_OFFSET             DOIP_HEADER_LEN
143
66
#define DOIP_DIAG_COMMON_SOURCE_LEN                2
144
44
#define DOIP_DIAG_COMMON_TARGET_OFFSET             (DOIP_DIAG_COMMON_SOURCE_OFFSET + DOIP_DIAG_COMMON_SOURCE_LEN)
145
44
#define DOIP_DIAG_COMMON_TARGET_LEN                2
146
147
148
/* Diagnostic message */
149
22
#define DOIP_DIAG_MESSAGE_DATA_OFFSET              (DOIP_DIAG_COMMON_TARGET_OFFSET + DOIP_DIAG_COMMON_TARGET_LEN)
150
151
152
/* Diagnostic message ACK */
153
0
#define DOIP_DIAG_MESSAGE_ACK_CODE_OFFSET          (DOIP_DIAG_COMMON_TARGET_OFFSET + DOIP_DIAG_COMMON_TARGET_LEN)
154
0
#define DOIP_DIAG_MESSAGE_ACK_CODE_LEN             1
155
0
#define DOIP_DIAG_MESSAGE_ACK_PREVIOUS_OFFSET      (DOIP_DIAG_MESSAGE_ACK_CODE_OFFSET + DOIP_DIAG_MESSAGE_ACK_CODE_LEN)
156
157
158
/* Diagnostic message NACK */
159
0
#define DOIP_DIAG_MESSAGE_NACK_CODE_OFFSET         (DOIP_DIAG_COMMON_TARGET_OFFSET + DOIP_DIAG_COMMON_TARGET_LEN)
160
0
#define DOIP_DIAG_MESSAGE_NACK_CODE_LEN            1
161
0
#define DOIP_DIAG_MESSAGE_NACK_PREVIOUS_OFFSET     (DOIP_DIAG_MESSAGE_NACK_CODE_OFFSET + DOIP_DIAG_MESSAGE_NACK_CODE_LEN)
162
163
164
165
/*
166
 * Enums
167
 */
168
169
/* Header */
170
/* Protocol version */
171
static const value_string doip_versions[] = {
172
    { RESERVED_VER,         "Reserved" },
173
    { ISO13400_2010,        "DoIP ISO/DIS 13400-2:2010" },
174
    { ISO13400_2012,        "DoIP ISO 13400-2:2012" },
175
    { ISO13400_2019,        "DoIP ISO 13400-2:2019" },
176
    { ISO13400_2019_AMD1,   "DoIP ISO 13400-2:2019 Amd1 (experimental)" },
177
    { DEFAULT_VALUE,        "Default value for vehicle identification request messages" },
178
    { 0, NULL }
179
};
180
181
/* Payload type */
182
static const value_string doip_payloads[] = {
183
    { DOIP_GENERIC_NACK,                    "Generic DoIP header NACK" },
184
    { DOIP_VEHICLE_IDENTIFICATION_REQ,      "Vehicle identification request" },
185
    { DOIP_VEHICLE_IDENTIFICATION_REQ_EID,  "Vehicle identification request with EID" },
186
    { DOIP_VEHICLE_IDENTIFICATION_REQ_VIN,  "Vehicle identification request with VIN" },
187
    { DOIP_VEHICLE_ANNOUNCEMENT_MESSAGE,    "Vehicle announcement message/vehicle identification response message" },
188
    { DOIP_ROUTING_ACTIVATION_REQUEST,      "Routing activation request" },
189
    { DOIP_ROUTING_ACTIVATION_RESPONSE,     "Routing activation response" },
190
    { DOIP_ALIVE_CHECK_REQUEST,             "Alive check request" },
191
    { DOIP_ALIVE_CHECK_RESPONSE,            "Alive check response" },
192
    { DOIP_ENTITY_STATUS_REQUEST,           "DoIP entity status request" },
193
    { DOIP_ENTITY_STATUS_RESPONSE,          "DoIP entity status response" },
194
    { DOIP_POWER_INFORMATION_REQUEST,       "Diagnostic power mode information request" },
195
    { DOIP_POWER_INFORMATION_RESPONSE,      "Diagnostic power mode information response" },
196
    { DOIP_DIAGNOSTIC_MESSAGE,              "Diagnostic message" },
197
    { DOIP_DIAGNOSTIC_MESSAGE_ACK,          "Diagnostic message ACK" },
198
    { DOIP_DIAGNOSTIC_MESSAGE_NACK,         "Diagnostic message NACK" },
199
    { 0, NULL }
200
};
201
202
203
/* Generic NACK */
204
static const value_string nack_codes[] = {
205
    { 0x00, "Incorrect pattern format" },
206
    { 0x01, "Unknown payload type" },
207
    { 0x02, "Message too large" },
208
    { 0x03, "Out of memory" },
209
    { 0x04, "Invalid payload length" },
210
    { 0, NULL }
211
};
212
213
214
/* Routing activation request */
215
static const value_string activation_types[] = {
216
    { 0x00, "Default" },
217
    { 0x01, "WWH-OBD" },
218
    { 0xE0, "Central security" },
219
    { 0, NULL }
220
};
221
222
223
/* Routing activation response */
224
static const value_string activation_codes[] = {
225
    { 0x00, "Routing activation denied due to unknown source address." },
226
    { 0x01, "Routing activation denied because all concurrently supported TCP_DATA sockets are registered and active." },
227
    { 0x02, "Routing activation denied because an SA different from the table connection entry was received on the already activated TCP_DATA socket." },
228
    { 0x03, "Routing activation denied because the SA is already registered and active on a different TCP_DATA socket." },
229
    { 0x04, "Routing activation denied due to missing authentication." },
230
    { 0x05, "Routing activation denied due to rejected confirmation." },
231
    { 0x06, "Routing activation denied due to unsupported routing activation type." },
232
    { 0x07, "Routing activation denied due to request for encrypted connection via TLS." },
233
    { 0x08, "Reserved by ISO 13400." },
234
    { 0x09, "Reserved by ISO 13400." },
235
    { 0x0A, "Reserved by ISO 13400." },
236
    { 0x0B, "Reserved by ISO 13400." },
237
    { 0x0C, "Reserved by ISO 13400." },
238
    { 0x0D, "Reserved by ISO 13400." },
239
    { 0x0E, "Reserved by ISO 13400." },
240
    { 0x0F, "Reserved by ISO 13400." },
241
    { 0x10, "Routing successfully activated." },
242
    { 0x11, "Routing will be activated; confirmation required." },
243
    { 0, NULL }
244
};
245
246
247
/* Vehicle announcement message */
248
/* Action code */
249
static const value_string action_codes[] = {
250
    { 0x00, "No further action required" },
251
    { 0x01, "Reserved by ISO 13400" },
252
    { 0x02, "Reserved by ISO 13400" },
253
    { 0x03, "Reserved by ISO 13400" },
254
    { 0x04, "Reserved by ISO 13400" },
255
    { 0x05, "Reserved by ISO 13400" },
256
    { 0x06, "Reserved by ISO 13400" },
257
    { 0x07, "Reserved by ISO 13400" },
258
    { 0x08, "Reserved by ISO 13400" },
259
    { 0x09, "Reserved by ISO 13400" },
260
    { 0x0A, "Reserved by ISO 13400" },
261
    { 0x0B, "Reserved by ISO 13400" },
262
    { 0x0C, "Reserved by ISO 13400" },
263
    { 0x0D, "Reserved by ISO 13400" },
264
    { 0x0E, "Reserved by ISO 13400" },
265
    { 0x0F, "Reserved by ISO 13400" },
266
    { 0x10, "Routing activation required to initiate central security" },
267
    { 0, NULL }
268
};
269
270
/* Sync status */
271
static const value_string sync_status[] = {
272
    { 0x00, "VIN and/or GID are synchronized" },
273
    { 0x01, "Reserved by ISO 13400" },
274
    { 0x02, "Reserved by ISO 13400" },
275
    { 0x03, "Reserved by ISO 13400" },
276
    { 0x04, "Reserved by ISO 13400" },
277
    { 0x05, "Reserved by ISO 13400" },
278
    { 0x06, "Reserved by ISO 13400" },
279
    { 0x07, "Reserved by ISO 13400" },
280
    { 0x08, "Reserved by ISO 13400" },
281
    { 0x09, "Reserved by ISO 13400" },
282
    { 0x0A, "Reserved by ISO 13400" },
283
    { 0x0B, "Reserved by ISO 13400" },
284
    { 0x0C, "Reserved by ISO 13400" },
285
    { 0x0D, "Reserved by ISO 13400" },
286
    { 0x0E, "Reserved by ISO 13400" },
287
    { 0x0F, "Reserved by ISO 13400" },
288
    { 0x10, "Incomplete: VIN and GID are NOT synchronized" },
289
    { 0, NULL }
290
};
291
292
/* Entity status response */
293
/* Node type */
294
static const value_string node_types[] = {
295
    { 0x00, "DoIP gateway" },
296
    { 0x01, "DoIp node" },
297
    { 0, NULL }
298
};
299
300
301
/* Diagnostic power mode information response */
302
/* Power mode */
303
static const value_string power_modes[] = {
304
    { 0x00, "not ready" },
305
    { 0x01, "ready" },
306
    { 0x02, "not supported" },
307
    { 0, NULL }
308
};
309
310
311
/* Diagnostic message ACK */
312
static const value_string diag_ack_codes[] = {
313
    { 0x00, "ACK" },
314
    { 0, NULL }
315
};
316
317
318
/* Diagnostic message NACK */
319
static const value_string diag_nack_codes[] = {
320
    { 0x00, "Reserved by ISO 13400" },
321
    { 0x01, "Reserved by ISO 13400" },
322
    { 0x02, "Invalid source address" },
323
    { 0x03, "Unknown target address" },
324
    { 0x04, "Diagnostic message too large" },
325
    { 0x05, "Out of memory" },
326
    { 0x06, "Target unreachable" },
327
    { 0x07, "Unknown network" },
328
    { 0x08, "Transport protocol error" },
329
    { 0, NULL }
330
};
331
332
333
334
/*
335
 * Config
336
 */
337
338
static bool doip_hide_address_names = true;
339
340
 /*
341
 * Fields
342
 */
343
344
/* DoIP header */
345
static int hf_doip_version;
346
static int hf_doip_inv_version;
347
static int hf_doip_type;
348
static int hf_doip_length;
349
350
351
/* Generic NACK */
352
static int hf_generic_nack_code;
353
354
355
/* Common */
356
static int hf_reserved_iso;
357
static int hf_reserved_oem;
358
359
360
/* Routing activation request */
361
static int hf_activation_type_v1;
362
static int hf_activation_type_v2;
363
364
365
/* Routing activation response */
366
static int hf_tester_logical_address;
367
static int hf_tester_logical_address_name;
368
static int hf_response_code;
369
370
371
/* Vehicle announcement message */
372
static int hf_logical_address;
373
static int hf_logical_address_name;
374
static int hf_gid;
375
static int hf_further_action;
376
static int hf_sync_status;
377
378
379
/* Diagnostic power mode information response */
380
static int hf_power_mode;
381
382
383
/* Entity status response */
384
static int hf_node_type;
385
static int hf_max_sockets;
386
static int hf_current_sockets;
387
static int hf_max_data_size;
388
389
390
/* Common */
391
static int hf_vin;
392
static int hf_eid;
393
static int hf_source_address;
394
static int hf_source_address_name;
395
static int hf_target_address;
396
static int hf_target_address_name;
397
static int hf_previous;
398
399
400
/* Diagnostic message */
401
static int hf_data;
402
403
404
/* Diagnostic message ACK */
405
static int hf_ack_code;
406
407
408
/* Diagnostic message NACK */
409
static int hf_nack_code;
410
411
412
413
/*
414
 * Trees
415
 */
416
static int ett_doip;
417
static int ett_header;
418
static int ett_address;
419
420
421
/* Misc */
422
static dissector_handle_t doip_handle;
423
static dissector_handle_t uds_handle;
424
static int proto_doip;
425
426
427
/* expert info items */
428
static expert_field ei_doip_illegal_length_field;
429
430
431
/*
432
 * UATs
433
 */
434
435
typedef struct _generic_one_id_string {
436
    unsigned   id;
437
    char   *name;
438
} generic_one_id_string_t;
439
440
/* ID -> Name */
441
static void *
442
0
copy_generic_one_id_string_cb(void* n, const void* o, size_t size _U_) {
443
0
    generic_one_id_string_t* new_rec = (generic_one_id_string_t*)n;
444
0
    const generic_one_id_string_t* old_rec = (const generic_one_id_string_t*)o;
445
446
0
    new_rec->name = g_strdup(old_rec->name);
447
0
    new_rec->id = old_rec->id;
448
0
    return new_rec;
449
0
}
450
451
static bool
452
0
update_generic_one_identifier_16bit(void *r, char **err) {
453
0
    generic_one_id_string_t *rec = (generic_one_id_string_t *)r;
454
455
0
    if (rec->id > 0xffff) {
456
0
        *err = ws_strdup_printf("We currently only support 16 bit identifiers (ID: %i  Name: %s)", rec->id, rec->name);
457
0
        return false;
458
0
    }
459
460
0
    if (rec->name == NULL || rec->name[0] == 0) {
461
0
        *err = g_strdup("Name cannot be empty");
462
0
        return false;
463
0
    }
464
465
0
    return true;
466
0
}
467
468
static void
469
0
free_generic_one_id_string_cb(void*r) {
470
0
    generic_one_id_string_t* rec = (generic_one_id_string_t*)r;
471
    /* freeing result of g_strdup */
472
0
    g_free(rec->name);
473
0
    rec->name = NULL;
474
0
}
475
476
/*
477
 * UAT DoIP Diagnostic Addresses
478
 */
479
16
#define DATAFILE_DOIP_DIAG_ADDRESSES "DoIP_diagnostic_addresses"
480
481
static GHashTable *data_doip_diag_addresses;
482
static generic_one_id_string_t* doip_diag_addresses;
483
static unsigned doip_diag_address_count;
484
485
0
UAT_HEX_CB_DEF(doip_diag_addresses, id, generic_one_id_string_t)
Unexecuted instantiation: packet-doip.c:doip_diag_addresses_id_set_cb
Unexecuted instantiation: packet-doip.c:doip_diag_addresses_id_tostr_cb
486
0
UAT_CSTRING_CB_DEF(doip_diag_addresses, name, generic_one_id_string_t)
487
488
static void
489
16
post_update_doip_diag_addresses(void) {
490
    /* destroy old hash table, if it exists */
491
16
    if (data_doip_diag_addresses) {
492
0
        g_hash_table_destroy(data_doip_diag_addresses);
493
0
    }
494
495
    /* create new hash table */
496
16
    data_doip_diag_addresses = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
497
498
16
    for (unsigned i = 0; i < doip_diag_address_count; i++) {
499
0
        g_hash_table_insert(data_doip_diag_addresses, GUINT_TO_POINTER(doip_diag_addresses[i].id), doip_diag_addresses[i].name);
500
0
    }
501
16
}
502
503
static void
504
0
reset_doip_diag_addresses_cb(void) {
505
    /* destroy hash table, if it exists */
506
0
    if (data_doip_diag_addresses) {
507
0
        g_hash_table_destroy(data_doip_diag_addresses);
508
0
        data_doip_diag_addresses = NULL;
509
0
    }
510
0
}
511
512
static proto_item *
513
44
doip_prototree_add_with_resolv(proto_tree* doip_tree, int hfindex, int hfindex_name, tvbuff_t* tvb, const int start, int length, const unsigned encoding, unsigned *diag_addr) {
514
44
    unsigned diag_addr_tmp;
515
44
    proto_item *ti;
516
44
    proto_tree *tree;
517
518
44
    ti = proto_tree_add_item_ret_uint(doip_tree, hfindex, tvb, start, length, encoding, &diag_addr_tmp);
519
44
    const char *name = NULL;
520
521
44
    if (data_doip_diag_addresses != NULL) {
522
44
        name = g_hash_table_lookup(data_doip_diag_addresses, GUINT_TO_POINTER(diag_addr_tmp));
523
44
    }
524
525
44
    if (name != NULL) {
526
0
        proto_item_append_text(ti, " (%s)", name);
527
0
        tree = proto_item_add_subtree(ti, ett_address);
528
0
        ti = proto_tree_add_string(tree, hfindex_name, tvb, start, length, name);
529
530
0
        if (doip_hide_address_names) {
531
0
            proto_item_set_hidden(ti);
532
0
        }
533
0
    }
534
535
44
    if (diag_addr != NULL) {
536
44
        *diag_addr = diag_addr_tmp;
537
44
    }
538
539
44
    return ti;
540
44
}
541
542
/*
543
 * UAT DoIP Payload Types
544
 */
545
16
#define DATAFILE_DOIP_PAYLOAD_TYPES "DoIP_payload_types"
546
547
static GHashTable *data_doip_payload_types;
548
static generic_one_id_string_t* doip_payload_types;
549
static unsigned doip_payload_type_count;
550
551
0
UAT_HEX_CB_DEF(doip_payload_types, id, generic_one_id_string_t)
Unexecuted instantiation: packet-doip.c:doip_payload_types_id_set_cb
Unexecuted instantiation: packet-doip.c:doip_payload_types_id_tostr_cb
552
0
UAT_CSTRING_CB_DEF(doip_payload_types, name, generic_one_id_string_t)
553
554
static void
555
16
post_update_doip_payload_types(void) {
556
    /* destroy old hash table, if it exists */
557
16
    if (data_doip_payload_types) {
558
0
        g_hash_table_destroy(data_doip_payload_types);
559
0
    }
560
561
    /* create new hash table */
562
16
    data_doip_payload_types = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
563
564
16
    for (unsigned i = 0; i < doip_payload_type_count; i++) {
565
0
        g_hash_table_insert(data_doip_payload_types, GUINT_TO_POINTER(doip_payload_types[i].id), doip_payload_types[i].name);
566
0
    }
567
16
}
568
569
static void
570
0
reset_doip_payload_type_cb(void) {
571
    /* destroy hash table, if it exists */
572
0
    if (data_doip_payload_types) {
573
0
        g_hash_table_destroy(data_doip_payload_types);
574
0
        data_doip_payload_types = NULL;
575
0
    }
576
0
}
577
578
static const char*
579
27
resolve_doip_payload_type(wmem_allocator_t *scope, uint16_t payload_type, bool is_col) {
580
27
    const char *tmp = NULL;
581
582
27
    if (data_doip_payload_types != NULL) {
583
27
        tmp = g_hash_table_lookup(data_doip_payload_types, GUINT_TO_POINTER(payload_type));
584
27
    }
585
586
    /* lets look at the static values, if nothing is configured */
587
27
    if (tmp == NULL) {
588
27
        tmp = try_val_to_str(payload_type, doip_payloads);
589
27
    }
590
591
    /* no configured or standardized name known */
592
27
    if (tmp != NULL) {
593
23
        if (is_col) {
594
0
            return tmp;
595
23
        } else {
596
23
            return wmem_strdup_printf(scope, "%s (0x%04x)", tmp, payload_type);
597
23
        }
598
23
    }
599
600
    /* just give back unknown */
601
4
    if (is_col) {
602
0
        return wmem_strdup_printf(scope, "0x%04x Unknown Payload", payload_type);
603
4
    } else {
604
4
        return wmem_strdup_printf(scope, "Unknown (0x%04x)", payload_type);
605
4
    }
606
4
}
607
608
static void
609
add_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *doip_tree)
610
27
{
611
27
    uint32_t len;
612
27
    uint32_t payload_type;
613
614
27
    proto_tree *subtree = proto_tree_add_subtree(doip_tree, tvb, DOIP_VERSION_OFFSET, DOIP_HEADER_LEN, ett_header, NULL, "Header");
615
27
    proto_tree_add_item(subtree, hf_doip_version, tvb, DOIP_VERSION_OFFSET, DOIP_VERSION_LEN, ENC_BIG_ENDIAN);
616
27
    proto_tree_add_item(subtree, hf_doip_inv_version, tvb, DOIP_INV_VERSION_OFFSET, DOIP_INV_VERSION_LEN, ENC_BIG_ENDIAN);
617
27
    payload_type = tvb_get_uint16(tvb, DOIP_TYPE_OFFSET, ENC_BIG_ENDIAN);
618
27
    proto_tree_add_uint_format(subtree, hf_doip_type, tvb, DOIP_TYPE_OFFSET, DOIP_TYPE_LEN, payload_type, "Type: %s", resolve_doip_payload_type(pinfo->pool, payload_type, false));
619
27
    proto_tree_add_item_ret_uint(subtree, hf_doip_length, tvb, DOIP_LENGTH_OFFSET, DOIP_LENGTH_LEN, ENC_BIG_ENDIAN, &len);
620
621
27
    if (tvb_captured_length(tvb) < len) {
622
26
        proto_tree_add_expert(doip_tree, pinfo, &ei_doip_illegal_length_field, tvb, DOIP_LENGTH_OFFSET, DOIP_LENGTH_LEN);
623
26
        col_append_str(pinfo->cinfo, COL_INFO, " [DoIP Length Field: Illegal Value]");
624
26
    }
625
27
}
626
627
628
static void
629
add_generic_header_nack_fields(proto_tree *doip_tree, tvbuff_t *tvb)
630
1
{
631
1
    proto_tree_add_item(doip_tree, hf_generic_nack_code, tvb, DOIP_GENERIC_NACK_OFFSET, DOIP_GENERIC_NACK_LEN, ENC_NA);
632
1
}
633
634
635
static void
636
add_vehicle_identification_eid_fields(proto_tree *doip_tree, tvbuff_t *tvb)
637
0
{
638
0
    proto_tree_add_item(doip_tree, hf_eid, tvb, DOIP_VEHICLE_IDENTIFICATION_EID_OFFSET, DOIP_COMMON_EID_LEN, ENC_NA);
639
0
}
640
641
642
static void
643
add_vehicle_identification_vin_fields(proto_tree *doip_tree, tvbuff_t *tvb)
644
0
{
645
0
    proto_tree_add_item(doip_tree, hf_vin, tvb, DOIP_VEHICLE_IDENTIFICATION_VIN_OFFSET, DOIP_COMMON_VIN_LEN, ENC_ASCII);
646
0
}
647
648
649
static void
650
add_routing_activation_request_fields(proto_tree *doip_tree, tvbuff_t *tvb, uint8_t version)
651
0
{
652
0
    doip_prototree_add_with_resolv(doip_tree, hf_source_address, hf_source_address_name, tvb, DOIP_ROUTING_ACTIVATION_REQ_SRC_OFFSET, DOIP_ROUTING_ACTIVATION_REQ_SRC_LEN, ENC_BIG_ENDIAN, NULL);
653
654
0
    if (version == ISO13400_2010) {
655
0
        proto_tree_add_item(doip_tree, hf_activation_type_v1, tvb, DOIP_ROUTING_ACTIVATION_REQ_TYPE_OFFSET, DOIP_ROUTING_ACTIVATION_REQ_TYPE_LEN_V1, ENC_BIG_ENDIAN);
656
0
        proto_tree_add_item(doip_tree, hf_reserved_iso, tvb, DOIP_ROUTING_ACTIVATION_REQ_ISO_OFFSET_V1, DOIP_ROUTING_ACTIVATION_REQ_ISO_LEN, ENC_BIG_ENDIAN);
657
658
0
        if ( tvb_bytes_exist(tvb, DOIP_ROUTING_ACTIVATION_REQ_OEM_OFFSET_V1, DOIP_ROUTING_ACTIVATION_REQ_OEM_LEN) ) {
659
0
            proto_tree_add_item(doip_tree, hf_reserved_oem, tvb, DOIP_ROUTING_ACTIVATION_REQ_OEM_OFFSET_V1, DOIP_ROUTING_ACTIVATION_REQ_OEM_LEN, ENC_BIG_ENDIAN);
660
0
        }
661
0
    } else if ((version == ISO13400_2012) || (version == ISO13400_2019)) {
662
0
        proto_tree_add_item(doip_tree, hf_activation_type_v2, tvb, DOIP_ROUTING_ACTIVATION_REQ_TYPE_OFFSET, DOIP_ROUTING_ACTIVATION_REQ_TYPE_LEN_V2, ENC_NA);
663
0
        proto_tree_add_item(doip_tree, hf_reserved_iso, tvb, DOIP_ROUTING_ACTIVATION_REQ_ISO_OFFSET_V2, DOIP_ROUTING_ACTIVATION_REQ_ISO_LEN, ENC_BIG_ENDIAN);
664
665
0
        if ( tvb_bytes_exist(tvb, DOIP_ROUTING_ACTIVATION_REQ_OEM_OFFSET_V2, DOIP_ROUTING_ACTIVATION_REQ_OEM_LEN) ) {
666
0
            proto_tree_add_item(doip_tree, hf_reserved_oem, tvb, DOIP_ROUTING_ACTIVATION_REQ_OEM_OFFSET_V2, DOIP_ROUTING_ACTIVATION_REQ_OEM_LEN, ENC_BIG_ENDIAN);
667
0
        }
668
0
    }
669
0
}
670
671
672
static void
673
add_routing_activation_response_fields(proto_tree *doip_tree, tvbuff_t *tvb)
674
0
{
675
0
    doip_prototree_add_with_resolv(doip_tree, hf_tester_logical_address, hf_tester_logical_address_name, tvb, DOIP_ROUTING_ACTIVATION_RES_TESTER_OFFSET, DOIP_ROUTING_ACTIVATION_RES_TESTER_LEN, ENC_BIG_ENDIAN, NULL);
676
0
    doip_prototree_add_with_resolv(doip_tree, hf_source_address, hf_source_address_name, tvb, DOIP_ROUTING_ACTIVATION_RES_ENTITY_OFFSET, DOIP_ROUTING_ACTIVATION_RES_ENTITY_LEN, ENC_BIG_ENDIAN, NULL);
677
0
    proto_tree_add_item(doip_tree, hf_response_code, tvb, DOIP_ROUTING_ACTIVATION_RES_CODE_OFFSET, DOIP_ROUTING_ACTIVATION_RES_CODE_LEN, ENC_NA);
678
0
    proto_tree_add_item(doip_tree, hf_reserved_iso, tvb, DOIP_ROUTING_ACTIVATION_RES_ISO_OFFSET, DOIP_ROUTING_ACTIVATION_RES_ISO_LEN, ENC_BIG_ENDIAN);
679
680
0
    if ( tvb_bytes_exist(tvb, DOIP_ROUTING_ACTIVATION_RES_OEM_OFFSET, DOIP_ROUTING_ACTIVATION_RES_OEM_LEN) ) {
681
0
        proto_tree_add_item(doip_tree, hf_reserved_oem, tvb, DOIP_ROUTING_ACTIVATION_RES_OEM_OFFSET, DOIP_ROUTING_ACTIVATION_RES_OEM_LEN, ENC_BIG_ENDIAN);
682
0
    }
683
0
}
684
685
686
static void
687
add_vehicle_announcement_message_fields(proto_tree *doip_tree, tvbuff_t *tvb)
688
0
{
689
0
    proto_tree_add_item(doip_tree, hf_vin, tvb, DOIP_VEHICLE_ANNOUNCEMENT_VIN_OFFSET, DOIP_COMMON_VIN_LEN, ENC_ASCII);
690
0
    doip_prototree_add_with_resolv(doip_tree, hf_logical_address, hf_logical_address_name, tvb, DOIP_VEHICLE_ANNOUNCEMENT_ADDRESS_OFFSET, DOIP_VEHICLE_ANNOUNCEMENT_ADDRESS_LEN, ENC_BIG_ENDIAN, NULL);
691
0
    proto_tree_add_item(doip_tree, hf_eid, tvb, DOIP_VEHICLE_ANNOUNCEMENT_EID_OFFSET, DOIP_COMMON_EID_LEN, ENC_NA);
692
0
    proto_tree_add_item(doip_tree, hf_gid, tvb, DOIP_VEHICLE_ANNOUNCEMENT_GID_OFFSET, DOIP_VEHICLE_ANNOUNCEMENT_GID_LEN, ENC_NA);
693
0
    proto_tree_add_item(doip_tree, hf_further_action, tvb, DOIP_VEHICLE_ANNOUNCEMENT_ACTION_OFFSET, DOIP_VEHICLE_ANNOUNCEMENT_ACTION_LEN, ENC_BIG_ENDIAN);
694
695
0
    if ( tvb_bytes_exist(tvb, DOIP_VEHICLE_ANNOUNCEMENT_SYNC_OFFSET, DOIP_VEHICLE_ANNOUNCEMENT_SYNC_LEN) ) {
696
        /* Not part of version 1 and optional in version 2. */
697
0
        proto_tree_add_item(doip_tree, hf_sync_status, tvb, DOIP_VEHICLE_ANNOUNCEMENT_SYNC_OFFSET, DOIP_VEHICLE_ANNOUNCEMENT_SYNC_LEN, ENC_BIG_ENDIAN);
698
0
    }
699
0
}
700
701
702
static void
703
add_alive_check_response_fields(proto_tree *doip_tree, tvbuff_t *tvb)
704
0
{
705
0
    doip_prototree_add_with_resolv(doip_tree, hf_source_address, hf_source_address_name, tvb, DOIP_ALIVE_CHECK_RESPONSE_SOURCE_OFFSET, DOIP_ALIVE_CHECK_RESPONSE_SOURCE_LEN, ENC_BIG_ENDIAN, NULL);
706
0
}
707
708
709
static void
710
add_entity_status_response_fields(proto_tree *doip_tree, tvbuff_t *tvb)
711
0
{
712
0
    proto_tree_add_item(doip_tree, hf_node_type, tvb, DOIP_ENTITY_STATUS_RESPONSE_NODE_OFFSET, DOIP_ENTITY_STATUS_RESPONSE_NODE_LEN, ENC_NA);
713
0
    proto_tree_add_item(doip_tree, hf_max_sockets, tvb, DOIP_ENTITY_STATUS_RESPONSE_MCTS_OFFSET, DOIP_ENTITY_STATUS_RESPONSE_MCTS_LEN, ENC_NA);
714
0
    proto_tree_add_item(doip_tree, hf_current_sockets, tvb, DOIP_ENTITY_STATUS_RESPONSE_NCTS_OFFSET, DOIP_ENTITY_STATUS_RESPONSE_NCTS_LEN, ENC_NA);
715
0
    if ( tvb_bytes_exist(tvb, DOIP_ENTITY_STATUS_RESPONSE_MDS_OFFSET, DOIP_ENTITY_STATUS_RESPONSE_MDS_LEN) ) {
716
0
        proto_tree_add_item(doip_tree, hf_max_data_size, tvb, DOIP_ENTITY_STATUS_RESPONSE_MDS_OFFSET, DOIP_ENTITY_STATUS_RESPONSE_MDS_LEN, ENC_BIG_ENDIAN);
717
0
    }
718
0
}
719
720
721
static void
722
add_power_mode_information_response_fields(proto_tree *doip_tree, tvbuff_t *tvb)
723
0
{
724
0
    proto_tree_add_item(doip_tree, hf_power_mode, tvb, DOIP_POWER_MODE_OFFSET, DOIP_POWER_MODE_LEN, ENC_NA);
725
0
}
726
727
728
static void
729
add_diagnostic_message_fields(proto_tree *doip_tree, tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
730
22
{
731
22
    doip_info_t doip_info;
732
22
    uint32_t tmp;
733
734
22
    doip_prototree_add_with_resolv(doip_tree, hf_source_address, hf_source_address_name, tvb, DOIP_DIAG_COMMON_SOURCE_OFFSET, DOIP_DIAG_COMMON_SOURCE_LEN, ENC_BIG_ENDIAN, &tmp);
735
22
    doip_info.source_address = tmp;
736
22
    doip_prototree_add_with_resolv(doip_tree, hf_target_address, hf_target_address_name, tvb, DOIP_DIAG_COMMON_TARGET_OFFSET, DOIP_DIAG_COMMON_TARGET_LEN, ENC_BIG_ENDIAN, &tmp);
737
22
    doip_info.target_address = tmp;
738
739
22
    if (uds_handle != 0) {
740
22
        call_dissector_with_data(uds_handle, tvb_new_subset_remaining(tvb, DOIP_DIAG_MESSAGE_DATA_OFFSET), pinfo, parent_tree, &doip_info);
741
22
    } else if (tvb_reported_length_remaining(tvb, DOIP_DIAG_MESSAGE_DATA_OFFSET) > 0) {
742
0
        proto_tree_add_item(doip_tree, hf_data, tvb, DOIP_DIAG_MESSAGE_DATA_OFFSET, tvb_reported_length_remaining(tvb, DOIP_DIAG_MESSAGE_DATA_OFFSET), ENC_NA);
743
0
    }
744
22
}
745
746
747
static void
748
add_diagnostic_message_ack_fields(proto_tree *doip_tree, tvbuff_t *tvb)
749
0
{
750
0
    doip_prototree_add_with_resolv(doip_tree, hf_source_address, hf_source_address_name, tvb, DOIP_DIAG_COMMON_SOURCE_OFFSET, DOIP_DIAG_COMMON_SOURCE_LEN, ENC_BIG_ENDIAN, NULL);
751
0
    doip_prototree_add_with_resolv(doip_tree, hf_target_address, hf_target_address_name, tvb, DOIP_DIAG_COMMON_TARGET_OFFSET, DOIP_DIAG_COMMON_TARGET_LEN, ENC_BIG_ENDIAN, NULL);
752
0
    proto_tree_add_item(doip_tree, hf_ack_code, tvb, DOIP_DIAG_MESSAGE_ACK_CODE_OFFSET, DOIP_DIAG_MESSAGE_ACK_CODE_LEN, ENC_NA);
753
754
0
    if (tvb_captured_length_remaining(tvb, DOIP_DIAG_MESSAGE_ACK_PREVIOUS_OFFSET) > 0) {
755
0
        proto_tree_add_item(doip_tree, hf_previous, tvb, DOIP_DIAG_MESSAGE_ACK_PREVIOUS_OFFSET, tvb_captured_length_remaining(tvb, DOIP_DIAG_MESSAGE_ACK_PREVIOUS_OFFSET), ENC_NA);
756
0
    }
757
0
}
758
759
760
static void
761
add_diagnostic_message_nack_fields(proto_tree *doip_tree, tvbuff_t *tvb)
762
0
{
763
0
    doip_prototree_add_with_resolv(doip_tree, hf_source_address, hf_source_address_name, tvb, DOIP_DIAG_COMMON_SOURCE_OFFSET, DOIP_DIAG_COMMON_SOURCE_LEN, ENC_BIG_ENDIAN, NULL);
764
0
    doip_prototree_add_with_resolv(doip_tree, hf_target_address, hf_target_address_name, tvb, DOIP_DIAG_COMMON_TARGET_OFFSET, DOIP_DIAG_COMMON_TARGET_LEN, ENC_BIG_ENDIAN, NULL);
765
0
    proto_tree_add_item(doip_tree, hf_nack_code, tvb, DOIP_DIAG_MESSAGE_NACK_CODE_OFFSET, DOIP_DIAG_MESSAGE_NACK_CODE_LEN, ENC_NA);
766
767
0
    if (tvb_captured_length_remaining(tvb, DOIP_DIAG_MESSAGE_NACK_PREVIOUS_OFFSET) > 0) {
768
0
        proto_tree_add_item(doip_tree, hf_previous, tvb, DOIP_DIAG_MESSAGE_NACK_PREVIOUS_OFFSET, tvb_captured_length_remaining(tvb, DOIP_DIAG_MESSAGE_NACK_PREVIOUS_OFFSET), ENC_NA);
769
0
    }
770
0
}
771
772
773
/* DoIP protocol dissector */
774
static void
775
dissect_doip_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
776
27
{
777
27
    uint8_t version = tvb_get_uint8(tvb, DOIP_VERSION_OFFSET);
778
27
    uint16_t payload_type = tvb_get_ntohs(tvb, DOIP_TYPE_OFFSET);
779
780
27
    int raw_offset_tvb = tvb_raw_offset(tvb);
781
27
    int *first_offset  = (int *)p_get_proto_data(wmem_file_scope(), pinfo, proto_doip, 0);
782
783
27
    if (!first_offset) {
784
27
        first_offset = wmem_new0(wmem_file_scope(), int);
785
27
        *first_offset = raw_offset_tvb;
786
27
        p_add_proto_data(wmem_file_scope(), pinfo, proto_doip, 0, first_offset);
787
27
    }
788
789
    /* Set protocol and clear information columns */
790
27
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "DoIP");
791
792
27
    if (*first_offset == raw_offset_tvb) {
793
27
        col_clear(pinfo->cinfo, COL_INFO);
794
27
    } else {
795
0
        col_append_str(pinfo->cinfo, COL_INFO, " / ");
796
0
    }
797
798
27
    if (
799
27
        version == ISO13400_2010 ||
800
27
        version == ISO13400_2012 ||
801
27
        version == ISO13400_2019 ||
802
27
        version == ISO13400_2019_AMD1 ||
803
27
        (version == DEFAULT_VALUE && (payload_type >= DOIP_VEHICLE_IDENTIFICATION_REQ && payload_type <= DOIP_VEHICLE_IDENTIFICATION_REQ_VIN))
804
27
        ) {
805
0
        col_append_str(pinfo->cinfo, COL_INFO, resolve_doip_payload_type(pinfo->pool, payload_type, true));
806
27
    } else {
807
27
        col_append_str(pinfo->cinfo, COL_INFO, "Invalid/unsupported DoIP version");
808
27
    }
809
810
811
27
    if (tree) {
812
27
        proto_item *ti = NULL;
813
27
        proto_tree *doip_tree = NULL;
814
815
27
        ti = proto_tree_add_item(tree, proto_doip, tvb, 0, -1, ENC_NA);
816
27
        doip_tree = proto_item_add_subtree(ti, ett_doip);
817
818
27
        add_header(tvb, pinfo, doip_tree);
819
820
27
        switch (payload_type) {
821
1
        case DOIP_GENERIC_NACK:
822
1
            add_generic_header_nack_fields(doip_tree, tvb);
823
1
            break;
824
825
0
        case DOIP_VEHICLE_IDENTIFICATION_REQ:
826
0
            break;
827
828
0
        case DOIP_VEHICLE_IDENTIFICATION_REQ_EID:
829
0
            add_vehicle_identification_eid_fields(doip_tree, tvb);
830
0
            break;
831
832
0
        case DOIP_VEHICLE_IDENTIFICATION_REQ_VIN:
833
0
            add_vehicle_identification_vin_fields(doip_tree, tvb);
834
0
            break;
835
836
0
        case DOIP_ROUTING_ACTIVATION_REQUEST:
837
0
            add_routing_activation_request_fields(doip_tree, tvb, version);
838
0
            break;
839
840
0
        case DOIP_ROUTING_ACTIVATION_RESPONSE:
841
0
            add_routing_activation_response_fields(doip_tree, tvb);
842
0
            break;
843
844
0
        case DOIP_VEHICLE_ANNOUNCEMENT_MESSAGE:
845
0
            add_vehicle_announcement_message_fields(doip_tree, tvb);
846
0
            break;
847
848
0
        case DOIP_ALIVE_CHECK_REQUEST:
849
0
            break;
850
851
0
        case DOIP_ALIVE_CHECK_RESPONSE:
852
0
            add_alive_check_response_fields(doip_tree, tvb);
853
0
            break;
854
855
0
        case DOIP_ENTITY_STATUS_REQUEST:
856
0
            break;
857
858
0
        case DOIP_ENTITY_STATUS_RESPONSE:
859
0
            add_entity_status_response_fields(doip_tree, tvb);
860
0
            break;
861
862
0
        case DOIP_POWER_INFORMATION_REQUEST:
863
0
            break;
864
865
0
        case DOIP_POWER_INFORMATION_RESPONSE:
866
0
            add_power_mode_information_response_fields(doip_tree, tvb);
867
0
            break;
868
869
22
        case DOIP_DIAGNOSTIC_MESSAGE:
870
22
            add_diagnostic_message_fields(doip_tree, tvb, pinfo, tree);
871
22
            break;
872
873
0
        case DOIP_DIAGNOSTIC_MESSAGE_ACK:
874
0
            add_diagnostic_message_ack_fields(doip_tree, tvb);
875
0
            break;
876
877
0
        case DOIP_DIAGNOSTIC_MESSAGE_NACK:
878
0
            add_diagnostic_message_nack_fields(doip_tree, tvb);
879
0
            break;
880
27
        }
881
27
    } else if (payload_type == DOIP_DIAGNOSTIC_MESSAGE) {
882
        /* Show UDS details in info column */
883
0
        if (uds_handle != 0) {
884
0
            doip_info_t doip_info;
885
0
            doip_info.source_address = tvb_get_uint16(tvb, DOIP_DIAG_COMMON_SOURCE_OFFSET, ENC_BIG_ENDIAN);
886
0
            doip_info.target_address = tvb_get_uint16(tvb, DOIP_DIAG_COMMON_TARGET_OFFSET, ENC_BIG_ENDIAN);
887
0
            call_dissector_with_data(uds_handle, tvb_new_subset_remaining(tvb, DOIP_DIAG_MESSAGE_DATA_OFFSET), pinfo, NULL, &doip_info);
888
0
        }
889
0
    }
890
27
}
891
892
893
/* determine PDU length of protocol DoIP */
894
static unsigned
895
get_doip_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *p _U_)
896
32
{
897
32
    uint8_t ver1 = tvb_get_uint8(tvb, offset + DOIP_VERSION_OFFSET);
898
32
    uint8_t ver2 = tvb_get_uint8(tvb, offset + DOIP_INV_VERSION_OFFSET);
899
900
32
    if (ver1 != ((~ver2) & 0xff)) {
901
        /* if ver2 is not the inverse of ver1, we are not at the start of a DoIP message! */
902
        /* bounds_error: (0 < return < DOIP_HEADER_LEN) */
903
5
        return 1;
904
5
    }
905
906
    /* PDU Length = length field value + header length */
907
27
    uint32_t ret = tvb_get_ntohl(tvb, offset + DOIP_LENGTH_OFFSET) + DOIP_HEADER_LEN;
908
909
27
    if (ret < DOIP_HEADER_LEN || ret > 0x7fffffff) {
910
        /* catch illegal length fields (overflow or too big) */
911
3
        return DOIP_HEADER_LEN;
912
3
    }
913
914
24
    return ret;
915
27
}
916
917
918
static int
919
dissect_doip_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
920
27
{
921
27
    dissect_doip_message(tvb, pinfo, tree);
922
27
    return tvb_captured_length(tvb);
923
27
}
924
925
926
static int
927
dissect_doip(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, void *data)
928
28
{
929
28
    tcp_dissect_pdus(tvb, pinfo, tree, true, DOIP_HEADER_LEN, get_doip_message_len, dissect_doip_pdu, data);
930
28
    return tvb_captured_length(tvb);
931
28
}
932
933
934
/* Register DoIP Protocol */
935
void
936
proto_register_doip(void)
937
16
{
938
16
    module_t        *doip_module = NULL;
939
16
    expert_module_t *expert_module_doip = NULL;
940
16
    uat_t           *doip_diag_addr_uat = NULL;
941
16
    uat_t           *doip_payload_type_uat = NULL;
942
943
16
    static hf_register_info hf[] = {
944
        /* Header */
945
16
        { &hf_doip_version,
946
16
          { "Version", "doip.version",
947
16
            FT_UINT8, BASE_HEX,
948
16
            VALS(doip_versions), 0x0,
949
16
            NULL, HFILL }
950
16
        },
951
16
        { &hf_doip_inv_version,
952
16
          { "Inverse version", "doip.inverse",
953
16
            FT_UINT8, BASE_HEX,
954
16
            NULL, 0x0,
955
16
            NULL, HFILL }
956
16
        },
957
16
        { &hf_doip_type,
958
16
          { "Type", "doip.type",
959
16
            FT_UINT16, BASE_HEX,
960
16
            VALS(doip_payloads), 0x0,
961
16
            NULL, HFILL }
962
16
        },
963
16
        { &hf_doip_length,
964
16
          { "Length", "doip.length",
965
16
            FT_UINT32, BASE_DEC,
966
16
            NULL, 0x0,
967
16
            NULL, HFILL }
968
16
        },
969
        /* Generic NACK */
970
16
        {
971
16
            &hf_generic_nack_code,
972
16
            {
973
16
                "DoIP Header NACK code", "doip.nack_code",
974
16
                FT_UINT8, BASE_HEX,
975
16
                VALS(nack_codes), 0x00,
976
16
                NULL, HFILL
977
16
            }
978
16
        },
979
        /* Vehicle announcement message */
980
16
        {
981
16
            &hf_vin,
982
16
            {
983
16
                "VIN", "doip.vin",
984
16
                FT_STRING, BASE_NONE,
985
16
                NULL, 0x00,
986
16
                NULL, HFILL
987
16
            }
988
16
        },
989
16
        {
990
16
            &hf_logical_address,
991
16
            {
992
16
                "Logical Address", "doip.logical_address",
993
16
                FT_UINT16, BASE_HEX,
994
16
                NULL, 0x00,
995
16
                NULL, HFILL
996
16
            }
997
16
        },
998
16
        {
999
16
            &hf_logical_address_name,
1000
16
            {
1001
16
                "Logical Address Name", "doip.logical_address_name",
1002
16
                FT_STRING, BASE_NONE,
1003
16
                NULL, 0x00,
1004
16
                NULL, HFILL
1005
16
            }
1006
16
        },
1007
16
        {
1008
16
            &hf_eid,
1009
16
            {
1010
16
                "EID", "doip.eid",
1011
16
                FT_BYTES, BASE_NONE,
1012
16
                NULL, 0x00,
1013
16
                NULL, HFILL
1014
16
            }
1015
16
        },
1016
16
        {
1017
16
            &hf_gid,
1018
16
            {
1019
16
                "GID", "doip.gid",
1020
16
                FT_BYTES, BASE_NONE,
1021
16
                NULL, 0x00,
1022
16
                NULL, HFILL
1023
16
            }
1024
16
        },
1025
16
        {
1026
16
            &hf_further_action,
1027
16
            {
1028
16
                "Further action required", "doip.further_action",
1029
16
                FT_UINT8, BASE_HEX,
1030
16
                VALS(action_codes), 0x00,
1031
16
                NULL, HFILL
1032
16
            }
1033
16
        },
1034
16
        {
1035
16
            &hf_sync_status,
1036
16
            {
1037
16
                "VIN/GID sync. status", "doip.sync_status",
1038
16
                FT_UINT8, BASE_HEX,
1039
16
                VALS(sync_status), 0x00,
1040
16
                NULL, HFILL
1041
16
            }
1042
16
        },
1043
        /* Diagnostic power mode information response */
1044
16
        {
1045
16
            &hf_power_mode,
1046
16
            {
1047
16
                "Diagnostic power mode", "doip.power_mode",
1048
16
                FT_UINT8, BASE_HEX,
1049
16
                VALS(power_modes), 0x00,
1050
16
                NULL, HFILL
1051
16
            }
1052
16
        },
1053
        /* Entity status response */
1054
16
        {
1055
16
            &hf_node_type,
1056
16
            {
1057
16
                "Node type", "doip.node_type",
1058
16
                FT_UINT8, BASE_HEX,
1059
16
                VALS(node_types), 0x00,
1060
16
                NULL, HFILL
1061
16
            }
1062
16
        },
1063
16
        {
1064
16
            &hf_max_sockets,
1065
16
            {
1066
16
                "Max concurrent sockets", "doip.max_sockets",
1067
16
                FT_UINT8, BASE_DEC,
1068
16
                NULL, 0x00,
1069
16
                NULL, HFILL
1070
16
            }
1071
16
        },
1072
16
        {
1073
16
            &hf_current_sockets,
1074
16
            {
1075
16
                "Currently open sockets", "doip.sockets",
1076
16
                FT_UINT8, BASE_DEC,
1077
16
                NULL, 0x00,
1078
16
                NULL, HFILL
1079
16
            }
1080
16
        },
1081
16
        {
1082
16
            &hf_max_data_size,
1083
16
            {
1084
16
                "Max data size", "doip.max_data_size",
1085
16
                FT_UINT32, BASE_DEC,
1086
16
                NULL, 0x00,
1087
16
                NULL, HFILL
1088
16
            }
1089
16
        },
1090
        /* Common */
1091
16
        {
1092
16
            &hf_source_address,
1093
16
            {
1094
16
                "Source Address", "doip.source_address",
1095
16
                FT_UINT16, BASE_HEX,
1096
16
                NULL, 0x00,
1097
16
                NULL, HFILL
1098
16
            }
1099
16
        },
1100
16
        {
1101
16
            &hf_source_address_name,
1102
16
            {
1103
16
                "Source Address Name", "doip.source_address_name",
1104
16
                FT_STRING, BASE_NONE,
1105
16
                NULL, 0x00,
1106
16
                NULL, HFILL
1107
16
            }
1108
16
        },
1109
16
        {
1110
16
            &hf_target_address,
1111
16
            {
1112
16
                "Target Address", "doip.target_address",
1113
16
                FT_UINT16, BASE_HEX,
1114
16
                NULL, 0x00,
1115
16
                NULL, HFILL
1116
16
            }
1117
16
        },
1118
16
        {
1119
16
            &hf_target_address_name,
1120
16
            {
1121
16
                "Target Address Name", "doip.target_address_name",
1122
16
                FT_STRING, BASE_NONE,
1123
16
                NULL, 0x00,
1124
16
                NULL, HFILL
1125
16
            }
1126
16
        },
1127
        /* Routing activation request */
1128
16
        {
1129
16
            &hf_activation_type_v1,
1130
16
            {
1131
16
                "Activation type", "doip.activation_type_v1",
1132
16
                FT_UINT16, BASE_HEX,
1133
16
                NULL, 0x00,
1134
16
                NULL, HFILL
1135
16
            }
1136
16
        },
1137
16
        {
1138
16
            &hf_activation_type_v2,
1139
16
            {
1140
16
                "Activation type", "doip.activation_type",
1141
16
                FT_UINT8, BASE_HEX,
1142
16
                VALS(activation_types), 0x00,
1143
16
                NULL, HFILL
1144
16
            }
1145
16
        },
1146
        /* Routing activation response */
1147
16
        {
1148
16
            &hf_tester_logical_address,
1149
16
            {
1150
16
                "Logical address of external tester", "doip.tester_logical_address",
1151
16
                FT_UINT16, BASE_HEX,
1152
16
                NULL, 0x00,
1153
16
                NULL, HFILL
1154
16
            }
1155
16
        },
1156
16
        {
1157
16
            &hf_tester_logical_address_name,
1158
16
            {
1159
16
                "Name of external tester", "doip.tester_logical_address_name",
1160
16
                FT_STRING, BASE_NONE,
1161
16
                NULL, 0x00,
1162
16
                NULL, HFILL
1163
16
            }
1164
16
        },
1165
16
        {
1166
16
            &hf_response_code,
1167
16
            {
1168
16
                "Routing activation response code", "doip.response_code",
1169
16
                FT_UINT8, BASE_HEX,
1170
16
                VALS(activation_codes), 0x00,
1171
16
                NULL, HFILL
1172
16
            }
1173
16
        },
1174
        /* Common */
1175
16
        {
1176
16
            &hf_reserved_iso,
1177
16
            {
1178
16
                "Reserved by ISO", "doip.reserved_iso",
1179
16
                FT_UINT32, BASE_HEX,
1180
16
                NULL, 0x00,
1181
16
                NULL, HFILL
1182
16
            }
1183
16
        },
1184
16
        {
1185
16
            &hf_reserved_oem,
1186
16
            {
1187
16
                "Reserved by OEM", "doip.reserved_oem",
1188
16
                FT_UINT32, BASE_HEX,
1189
16
                NULL, 0x00,
1190
16
                NULL, HFILL
1191
16
            }
1192
16
        },
1193
        /* Diagnostic message */
1194
16
        {
1195
16
            &hf_data,
1196
16
            {
1197
16
                "User data", "doip.data",
1198
16
                FT_BYTES, BASE_NONE,
1199
16
                NULL, 0x00,
1200
16
                NULL, HFILL
1201
16
            }
1202
16
        },
1203
        /* Diagnostic message ACK */
1204
16
        {
1205
16
            &hf_ack_code,
1206
16
            {
1207
16
                "ACK code", "doip.diag_ack_code",
1208
16
                FT_UINT8, BASE_HEX,
1209
16
                VALS(diag_ack_codes), 0x00,
1210
16
                NULL, HFILL
1211
16
            }
1212
16
        },
1213
        /* Diagnostic message NACK */
1214
16
        {
1215
16
            &hf_nack_code,
1216
16
            {
1217
16
                "NACK code", "doip.diag_nack_code",
1218
16
                FT_UINT8, BASE_HEX,
1219
16
                VALS(diag_nack_codes), 0x00,
1220
16
                NULL, HFILL
1221
16
            }
1222
16
        },
1223
        /* Common */
1224
16
        {
1225
16
            &hf_previous,
1226
16
            {
1227
16
                "Previous message", "doip.previous",
1228
16
                FT_BYTES, BASE_NONE,
1229
16
                NULL, 0x00,
1230
16
                NULL, HFILL
1231
16
            }
1232
16
        }
1233
16
    };
1234
1235
    /* Setup protocol subtree array */
1236
16
    static int *ett[] = {
1237
16
        &ett_doip,
1238
16
        &ett_header,
1239
16
        &ett_address
1240
16
    };
1241
1242
    /* UAT definitions */
1243
16
    static uat_field_t doip_diag_addr_uat_fields[] = {
1244
16
        UAT_FLD_HEX(doip_diag_addresses, id, "Diagnostic Address", "Diagnostic Address (hex uint16 without leading 0x)"),
1245
16
        UAT_FLD_CSTRING(doip_diag_addresses, name, "Name", "Name of the ECU (string)"),
1246
16
        UAT_END_FIELDS
1247
16
    };
1248
1249
16
    static uat_field_t doip_payload_type_uat_fields[] = {
1250
16
        UAT_FLD_HEX(doip_payload_types, id, "Payload Type", "Payload Type (hex uint16 without leading 0x)"),
1251
16
        UAT_FLD_CSTRING(doip_payload_types, name, "Name", "Name of the Payload Type (string)"),
1252
16
        UAT_END_FIELDS
1253
16
    };
1254
1255
16
    proto_doip = proto_register_protocol ("DoIP (ISO13400) Protocol", "DoIP", "doip");
1256
1257
16
    proto_register_field_array(proto_doip, hf, array_length(hf));
1258
16
    proto_register_subtree_array(ett, array_length(ett));
1259
1260
16
    doip_handle = register_dissector("doip", dissect_doip, proto_doip);
1261
16
    doip_module = prefs_register_protocol(proto_doip, NULL);
1262
1263
    /* UATs */
1264
16
    doip_diag_addr_uat = uat_new("Diagnostic Addresses",
1265
16
        sizeof(generic_one_id_string_t),        /* record size           */
1266
16
        DATAFILE_DOIP_DIAG_ADDRESSES,           /* filename              */
1267
16
        true,                                   /* from profile          */
1268
16
        (void**)&doip_diag_addresses,           /* data_ptr              */
1269
16
        &doip_diag_address_count,               /* numitems_ptr          */
1270
16
        UAT_AFFECTS_DISSECTION,                 /* but not fields        */
1271
16
        NULL,                                   /* help                  */
1272
16
        copy_generic_one_id_string_cb,          /* copy callback         */
1273
16
        update_generic_one_identifier_16bit,    /* update callback       */
1274
16
        free_generic_one_id_string_cb,          /* free callback         */
1275
16
        post_update_doip_diag_addresses,        /* post update callback  */
1276
16
        reset_doip_diag_addresses_cb,           /* reset callback        */
1277
16
        doip_diag_addr_uat_fields               /* UAT field definitions */
1278
16
    );
1279
1280
16
    prefs_register_uat_preference(doip_module, "_udf_doip_diag_addresses", "Diagnostics Addresses",
1281
16
        "A table to define names of Diagnostics Addresses.", doip_diag_addr_uat);
1282
1283
16
    doip_payload_type_uat = uat_new("Payload Types",
1284
16
        sizeof(generic_one_id_string_t),        /* record size           */
1285
16
        DATAFILE_DOIP_PAYLOAD_TYPES,            /* filename              */
1286
16
        true,                                   /* from profile          */
1287
16
        (void**)&doip_payload_types,            /* data_ptr              */
1288
16
        &doip_payload_type_count,               /* numitems_ptr          */
1289
16
        UAT_AFFECTS_DISSECTION,                 /* but not fields        */
1290
16
        NULL,                                   /* help                  */
1291
16
        copy_generic_one_id_string_cb,          /* copy callback         */
1292
16
        update_generic_one_identifier_16bit,    /* update callback       */
1293
16
        free_generic_one_id_string_cb,          /* free callback         */
1294
16
        post_update_doip_payload_types,         /* post update callback  */
1295
16
        reset_doip_payload_type_cb,             /* reset callback        */
1296
16
        doip_payload_type_uat_fields            /* UAT field definitions */
1297
16
    );
1298
1299
16
    prefs_register_uat_preference(doip_module, "_udf_doip_payload_types", "Payload Types",
1300
16
        "A table to define names of Payload Types.", doip_payload_type_uat);
1301
1302
16
    prefs_register_bool_preference(doip_module, "hide_address_name_entries",
1303
16
        "Hide Address Name Entries",
1304
16
        "Should the dissector hide the names for addresses?",
1305
16
        &doip_hide_address_names);
1306
1307
16
    static ei_register_info ei[] = {
1308
16
     { &ei_doip_illegal_length_field, { "doip.illegal_length_field",
1309
16
       PI_MALFORMED, PI_ERROR, "DoIP illegal length field", EXPFILL } },
1310
16
    };
1311
1312
16
    expert_module_doip = expert_register_protocol(proto_doip);
1313
16
    expert_register_field_array(expert_module_doip, ei, array_length(ei));
1314
16
}
1315
1316
void
1317
proto_reg_handoff_doip(void)
1318
16
{
1319
16
    dissector_add_uint("udp.port", DOIP_PORT, doip_handle);
1320
16
    dissector_add_uint("tcp.port", DOIP_PORT, doip_handle);
1321
1322
16
    ssl_dissector_add(DOIP_TLS_PORT, doip_handle);
1323
1324
16
    uds_handle = find_dissector("uds_over_doip");
1325
16
}
1326
1327
/*
1328
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1329
 *
1330
 * Local variables:
1331
 * c-basic-offset: 4
1332
 * tab-width: 8
1333
 * indent-tabs-mode: nil
1334
 * End:
1335
 *
1336
 * vi: set shiftwidth=4 tabstop=8 expandtab:
1337
 * :indentSize=4:tabSize=8:noTabs=true:
1338
 */