Coverage Report

Created: 2025-02-15 06:25

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