Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-doip.c
blob68867242dfee918d7dbbed7a9f2dd6a610ee3e90
1 /* packet-doip.c
2 * Routines for DoIP (ISO13400) protocol packet disassembly
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
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.
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.
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.
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>
29 #include "packet-tcp.h"
30 #include "packet-tls.h"
31 #include "packet-doip.h"
33 void proto_register_doip(void);
34 void proto_reg_handoff_doip(void);
37 #define DOIP_PORT 13400
38 #define DOIP_TLS_PORT 3496
40 #define DOIP_GENERIC_NACK 0x0000
41 #define DOIP_VEHICLE_IDENTIFICATION_REQ 0x0001
42 #define DOIP_VEHICLE_IDENTIFICATION_REQ_EID 0x0002
43 #define DOIP_VEHICLE_IDENTIFICATION_REQ_VIN 0x0003
44 #define DOIP_VEHICLE_ANNOUNCEMENT_MESSAGE 0x0004
45 #define DOIP_ROUTING_ACTIVATION_REQUEST 0x0005
46 #define DOIP_ROUTING_ACTIVATION_RESPONSE 0x0006
47 #define DOIP_ALIVE_CHECK_REQUEST 0x0007
48 #define DOIP_ALIVE_CHECK_RESPONSE 0x0008
49 #define DOIP_ENTITY_STATUS_REQUEST 0x4001
50 #define DOIP_ENTITY_STATUS_RESPONSE 0x4002
51 #define DOIP_POWER_INFORMATION_REQUEST 0x4003
52 #define DOIP_POWER_INFORMATION_RESPONSE 0x4004
53 #define DOIP_DIAGNOSTIC_MESSAGE 0x8001
54 #define DOIP_DIAGNOSTIC_MESSAGE_ACK 0x8002
55 #define DOIP_DIAGNOSTIC_MESSAGE_NACK 0x8003
58 /* Header */
59 #define DOIP_VERSION_OFFSET 0
60 #define DOIP_VERSION_LEN 1
61 #define DOIP_INV_VERSION_OFFSET (DOIP_VERSION_OFFSET + DOIP_VERSION_LEN)
62 #define DOIP_INV_VERSION_LEN 1
63 #define DOIP_TYPE_OFFSET (DOIP_INV_VERSION_OFFSET + DOIP_INV_VERSION_LEN)
64 #define DOIP_TYPE_LEN 2
65 #define DOIP_LENGTH_OFFSET (DOIP_TYPE_OFFSET + DOIP_TYPE_LEN)
66 #define DOIP_LENGTH_LEN 4
67 #define DOIP_HEADER_LEN (DOIP_LENGTH_OFFSET + DOIP_LENGTH_LEN)
69 #define RESERVED_VER 0x00
70 #define ISO13400_2010 0x01
71 #define ISO13400_2012 0x02
72 #define ISO13400_2019 0x03
73 #define ISO13400_2019_AMD1 0x04
74 #define DEFAULT_VALUE 0xFF
77 /* Generic NACK */
78 #define DOIP_GENERIC_NACK_OFFSET DOIP_HEADER_LEN
79 #define DOIP_GENERIC_NACK_LEN 1
82 /* Common */
83 #define DOIP_COMMON_VIN_LEN 17
84 #define DOIP_COMMON_EID_LEN 6
87 /* Vehicle identification request */
88 #define DOIP_VEHICLE_IDENTIFICATION_EID_OFFSET DOIP_HEADER_LEN
89 #define DOIP_VEHICLE_IDENTIFICATION_VIN_OFFSET DOIP_HEADER_LEN
92 /* Routing activation request */
93 #define DOIP_ROUTING_ACTIVATION_REQ_SRC_OFFSET DOIP_HEADER_LEN
94 #define DOIP_ROUTING_ACTIVATION_REQ_SRC_LEN 2
95 #define DOIP_ROUTING_ACTIVATION_REQ_TYPE_OFFSET (DOIP_ROUTING_ACTIVATION_REQ_SRC_OFFSET + DOIP_ROUTING_ACTIVATION_REQ_SRC_LEN)
96 #define DOIP_ROUTING_ACTIVATION_REQ_TYPE_LEN_V1 2
97 #define DOIP_ROUTING_ACTIVATION_REQ_TYPE_LEN_V2 1
98 #define DOIP_ROUTING_ACTIVATION_REQ_ISO_OFFSET_V1 (DOIP_ROUTING_ACTIVATION_REQ_TYPE_OFFSET + DOIP_ROUTING_ACTIVATION_REQ_TYPE_LEN_V1)
99 #define DOIP_ROUTING_ACTIVATION_REQ_ISO_OFFSET_V2 (DOIP_ROUTING_ACTIVATION_REQ_TYPE_OFFSET + DOIP_ROUTING_ACTIVATION_REQ_TYPE_LEN_V2)
100 #define DOIP_ROUTING_ACTIVATION_REQ_ISO_LEN 4
101 #define DOIP_ROUTING_ACTIVATION_REQ_OEM_OFFSET_V1 (DOIP_ROUTING_ACTIVATION_REQ_ISO_OFFSET_V1 + DOIP_ROUTING_ACTIVATION_REQ_ISO_LEN)
102 #define DOIP_ROUTING_ACTIVATION_REQ_OEM_OFFSET_V2 (DOIP_ROUTING_ACTIVATION_REQ_ISO_OFFSET_V2 + DOIP_ROUTING_ACTIVATION_REQ_ISO_LEN)
103 #define DOIP_ROUTING_ACTIVATION_REQ_OEM_LEN 4
106 /* Routing activation response */
107 #define DOIP_ROUTING_ACTIVATION_RES_TESTER_OFFSET DOIP_HEADER_LEN
108 #define DOIP_ROUTING_ACTIVATION_RES_TESTER_LEN 2
109 #define DOIP_ROUTING_ACTIVATION_RES_ENTITY_OFFSET (DOIP_ROUTING_ACTIVATION_RES_TESTER_OFFSET + DOIP_ROUTING_ACTIVATION_RES_TESTER_LEN)
110 #define DOIP_ROUTING_ACTIVATION_RES_ENTITY_LEN 2
111 #define DOIP_ROUTING_ACTIVATION_RES_CODE_OFFSET (DOIP_ROUTING_ACTIVATION_RES_ENTITY_OFFSET + DOIP_ROUTING_ACTIVATION_RES_ENTITY_LEN)
112 #define DOIP_ROUTING_ACTIVATION_RES_CODE_LEN 1
113 #define DOIP_ROUTING_ACTIVATION_RES_ISO_OFFSET (DOIP_ROUTING_ACTIVATION_RES_CODE_OFFSET + DOIP_ROUTING_ACTIVATION_RES_CODE_LEN)
114 #define DOIP_ROUTING_ACTIVATION_RES_ISO_LEN 4
115 #define DOIP_ROUTING_ACTIVATION_RES_OEM_OFFSET (DOIP_ROUTING_ACTIVATION_RES_ISO_OFFSET + DOIP_ROUTING_ACTIVATION_RES_ISO_LEN)
116 #define DOIP_ROUTING_ACTIVATION_RES_OEM_LEN 4
119 /* Vehicle announcement message */
120 #define DOIP_VEHICLE_ANNOUNCEMENT_VIN_OFFSET DOIP_HEADER_LEN
121 #define DOIP_VEHICLE_ANNOUNCEMENT_ADDRESS_OFFSET (DOIP_VEHICLE_ANNOUNCEMENT_VIN_OFFSET + DOIP_COMMON_VIN_LEN)
122 #define DOIP_VEHICLE_ANNOUNCEMENT_ADDRESS_LEN 2
123 #define DOIP_VEHICLE_ANNOUNCEMENT_EID_OFFSET (DOIP_VEHICLE_ANNOUNCEMENT_ADDRESS_OFFSET + DOIP_VEHICLE_ANNOUNCEMENT_ADDRESS_LEN)
124 #define DOIP_VEHICLE_ANNOUNCEMENT_GID_OFFSET (DOIP_VEHICLE_ANNOUNCEMENT_EID_OFFSET + DOIP_COMMON_EID_LEN)
125 #define DOIP_VEHICLE_ANNOUNCEMENT_GID_LEN 6
126 #define DOIP_VEHICLE_ANNOUNCEMENT_ACTION_OFFSET (DOIP_VEHICLE_ANNOUNCEMENT_GID_OFFSET + DOIP_VEHICLE_ANNOUNCEMENT_GID_LEN)
127 #define DOIP_VEHICLE_ANNOUNCEMENT_ACTION_LEN 1
128 #define DOIP_VEHICLE_ANNOUNCEMENT_SYNC_OFFSET (DOIP_VEHICLE_ANNOUNCEMENT_ACTION_OFFSET + DOIP_VEHICLE_ANNOUNCEMENT_ACTION_LEN)
129 #define DOIP_VEHICLE_ANNOUNCEMENT_SYNC_LEN 1
132 /* Alive check response */
133 #define DOIP_ALIVE_CHECK_RESPONSE_SOURCE_OFFSET DOIP_HEADER_LEN
134 #define DOIP_ALIVE_CHECK_RESPONSE_SOURCE_LEN 2
137 /* Entity status response */
138 #define DOIP_ENTITY_STATUS_RESPONSE_NODE_OFFSET DOIP_HEADER_LEN
139 #define DOIP_ENTITY_STATUS_RESPONSE_NODE_LEN 1
140 #define DOIP_ENTITY_STATUS_RESPONSE_MCTS_OFFSET (DOIP_ENTITY_STATUS_RESPONSE_NODE_OFFSET + DOIP_ENTITY_STATUS_RESPONSE_NODE_LEN)
141 #define DOIP_ENTITY_STATUS_RESPONSE_MCTS_LEN 1
142 #define DOIP_ENTITY_STATUS_RESPONSE_NCTS_OFFSET (DOIP_ENTITY_STATUS_RESPONSE_MCTS_OFFSET + DOIP_ENTITY_STATUS_RESPONSE_MCTS_LEN)
143 #define DOIP_ENTITY_STATUS_RESPONSE_NCTS_LEN 1
144 #define DOIP_ENTITY_STATUS_RESPONSE_MDS_OFFSET (DOIP_ENTITY_STATUS_RESPONSE_NCTS_OFFSET + DOIP_ENTITY_STATUS_RESPONSE_NCTS_LEN)
145 #define DOIP_ENTITY_STATUS_RESPONSE_MDS_LEN 4
148 /* Diagnostic power mode information response */
149 #define DOIP_POWER_MODE_OFFSET DOIP_HEADER_LEN
150 #define DOIP_POWER_MODE_LEN 1
153 /* Common */
154 #define DOIP_DIAG_COMMON_SOURCE_OFFSET DOIP_HEADER_LEN
155 #define DOIP_DIAG_COMMON_SOURCE_LEN 2
156 #define DOIP_DIAG_COMMON_TARGET_OFFSET (DOIP_DIAG_COMMON_SOURCE_OFFSET + DOIP_DIAG_COMMON_SOURCE_LEN)
157 #define DOIP_DIAG_COMMON_TARGET_LEN 2
160 /* Diagnostic message */
161 #define DOIP_DIAG_MESSAGE_DATA_OFFSET (DOIP_DIAG_COMMON_TARGET_OFFSET + DOIP_DIAG_COMMON_TARGET_LEN)
164 /* Diagnostic message ACK */
165 #define DOIP_DIAG_MESSAGE_ACK_CODE_OFFSET (DOIP_DIAG_COMMON_TARGET_OFFSET + DOIP_DIAG_COMMON_TARGET_LEN)
166 #define DOIP_DIAG_MESSAGE_ACK_CODE_LEN 1
167 #define DOIP_DIAG_MESSAGE_ACK_PREVIOUS_OFFSET (DOIP_DIAG_MESSAGE_ACK_CODE_OFFSET + DOIP_DIAG_MESSAGE_ACK_CODE_LEN)
170 /* Diagnostic message NACK */
171 #define DOIP_DIAG_MESSAGE_NACK_CODE_OFFSET (DOIP_DIAG_COMMON_TARGET_OFFSET + DOIP_DIAG_COMMON_TARGET_LEN)
172 #define DOIP_DIAG_MESSAGE_NACK_CODE_LEN 1
173 #define DOIP_DIAG_MESSAGE_NACK_PREVIOUS_OFFSET (DOIP_DIAG_MESSAGE_NACK_CODE_OFFSET + DOIP_DIAG_MESSAGE_NACK_CODE_LEN)
178 * Enums
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
323 /* Diagnostic message ACK */
324 static const value_string diag_ack_codes[] = {
325 { 0x00, "ACK" },
326 { 0, NULL }
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 }
347 * Config
350 static bool doip_hide_address_names = true;
353 * Fields
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;
363 /* Generic NACK */
364 static int hf_generic_nack_code;
367 /* Common */
368 static int hf_reserved_iso;
369 static int hf_reserved_oem;
372 /* Routing activation request */
373 static int hf_activation_type_v1;
374 static int hf_activation_type_v2;
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;
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;
391 /* Diagnostic power mode information response */
392 static int hf_power_mode;
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;
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;
412 /* Diagnostic message */
413 static int hf_data;
416 /* Diagnostic message ACK */
417 static int hf_ack_code;
420 /* Diagnostic message NACK */
421 static int hf_nack_code;
426 * Trees
428 static int ett_doip;
429 static int ett_header;
430 static int ett_address;
433 /* Misc */
434 static dissector_handle_t doip_handle;
435 static dissector_handle_t uds_handle;
436 static int proto_doip;
439 /* expert info items */
440 static expert_field ei_doip_illegal_length_field;
444 * UATs
447 typedef struct _generic_one_id_string {
448 unsigned id;
449 char *name;
450 } generic_one_id_string_t;
452 static void
453 doip_uat_free_key(void *key) {
454 wmem_free(wmem_epan_scope(), key);
457 static void
458 simple_free(void *data) {
459 /* we need to free because of the g_strdup in post_update*/
460 g_free(data);
463 /* ID -> Name */
464 static void *
465 copy_generic_one_id_string_cb(void* n, const void* o, size_t size _U_) {
466 generic_one_id_string_t* new_rec = (generic_one_id_string_t*)n;
467 const generic_one_id_string_t* old_rec = (const generic_one_id_string_t*)o;
469 new_rec->name = g_strdup(old_rec->name);
470 new_rec->id = old_rec->id;
471 return new_rec;
474 static bool
475 update_generic_one_identifier_16bit(void *r, char **err) {
476 generic_one_id_string_t *rec = (generic_one_id_string_t *)r;
478 if (rec->id > 0xffff) {
479 *err = ws_strdup_printf("We currently only support 16 bit identifiers (ID: %i Name: %s)", rec->id, rec->name);
480 return false;
483 if (rec->name == NULL || rec->name[0] == 0) {
484 *err = g_strdup("Name cannot be empty");
485 return false;
488 return true;
491 static void
492 free_generic_one_id_string_cb(void*r) {
493 generic_one_id_string_t* rec = (generic_one_id_string_t*)r;
494 /* freeing result of g_strdup */
495 g_free(rec->name);
496 rec->name = NULL;
499 static void
500 post_update_one_id_string_template_cb(generic_one_id_string_t *data, unsigned data_num, GHashTable *ht) {
501 unsigned i;
502 int *key = NULL;
504 for (i = 0; i < data_num; i++) {
505 key = wmem_new(wmem_epan_scope(), int);
506 *key = data[i].id;
508 g_hash_table_insert(ht, key, g_strdup(data[i].name));
512 static char*
513 ht_lookup_name(GHashTable* ht, unsigned int identifier) {
514 char *tmp = NULL;
515 unsigned int *id = NULL;
517 if (ht == NULL) {
518 return NULL;
521 id = wmem_new(wmem_epan_scope(), unsigned int);
522 *id = (unsigned int)identifier;
523 tmp = (char *)g_hash_table_lookup(ht, id);
524 wmem_free(wmem_epan_scope(), id);
526 return tmp;
530 * UAT DoIP Diagnostic Addresses
532 #define DATAFILE_DOIP_DIAG_ADDRESSES "DoIP_diagnostic_addresses"
534 static GHashTable *data_doip_diag_addresses;
535 static generic_one_id_string_t* doip_diag_addresses;
536 static unsigned doip_diag_address_count;
538 UAT_HEX_CB_DEF(doip_diag_addresses, id, generic_one_id_string_t)
539 UAT_CSTRING_CB_DEF(doip_diag_addresses, name, generic_one_id_string_t)
541 static void
542 post_update_doip_diag_addresses(void) {
543 /* destroy old hash table, if it exists */
544 if (data_doip_diag_addresses) {
545 g_hash_table_destroy(data_doip_diag_addresses);
546 data_doip_diag_addresses = NULL;
549 /* create new hash table */
550 data_doip_diag_addresses = g_hash_table_new_full(g_int_hash, g_int_equal, &doip_uat_free_key, &simple_free);
551 post_update_one_id_string_template_cb(doip_diag_addresses, doip_diag_address_count, data_doip_diag_addresses);
554 static proto_item *
555 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) {
556 unsigned diag_addr_tmp;
557 proto_item *ti;
558 proto_tree *tree;
560 ti = proto_tree_add_item_ret_uint(doip_tree, hfindex, tvb, start, length, encoding, &diag_addr_tmp);
561 const char *name = ht_lookup_name(data_doip_diag_addresses, diag_addr_tmp);
562 if (name != NULL) {
563 proto_item_append_text(ti, " (%s)", name);
564 tree = proto_item_add_subtree(ti, ett_address);
565 ti = proto_tree_add_string(tree, hfindex_name, tvb, start, length, name);
567 if (doip_hide_address_names) {
568 proto_item_set_hidden(ti);
572 if (diag_addr != NULL) {
573 *diag_addr = diag_addr_tmp;
576 return ti;
580 * UAT DoIP Payload Types
582 #define DATAFILE_DOIP_PAYLOAD_TYPES "DoIP_payload_types"
584 static GHashTable *data_doip_payload_types;
585 static generic_one_id_string_t* doip_payload_types;
586 static unsigned doip_payload_type_count;
588 UAT_HEX_CB_DEF(doip_payload_types, id, generic_one_id_string_t)
589 UAT_CSTRING_CB_DEF(doip_payload_types, name, generic_one_id_string_t)
591 static void
592 post_update_doip_payload_types(void) {
593 /* destroy old hash table, if it exists */
594 if (data_doip_payload_types) {
595 g_hash_table_destroy(data_doip_payload_types);
596 data_doip_payload_types = NULL;
599 /* create new hash table */
600 data_doip_payload_types = g_hash_table_new_full(g_int_hash, g_int_equal, &doip_uat_free_key, &simple_free);
601 post_update_one_id_string_template_cb(doip_payload_types, doip_payload_type_count, data_doip_payload_types);
604 static const char*
605 resolve_doip_payload_type(wmem_allocator_t *scope, uint16_t payload_type, bool is_col)
607 const char *tmp = ht_lookup_name(data_doip_payload_types, payload_type);
609 /* lets look at the static values, if nothing is configured */
610 if (tmp == NULL) {
611 tmp = try_val_to_str(payload_type, doip_payloads);
614 /* no configured or standardized name known */
615 if (tmp != NULL) {
616 if (is_col) {
617 return tmp;
618 } else {
619 return wmem_strdup_printf(scope, "%s (0x%04x)", tmp, payload_type);
623 /* just give back unknown */
624 if (is_col) {
625 return wmem_strdup_printf(scope, "0x%04x Unknown Payload", payload_type);
626 } else {
627 return wmem_strdup_printf(scope, "Unknown (0x%04x)", payload_type);
631 static void
632 add_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *doip_tree)
634 uint32_t len;
635 uint32_t payload_type;
637 proto_tree *subtree = proto_tree_add_subtree(doip_tree, tvb, DOIP_VERSION_OFFSET, DOIP_HEADER_LEN, ett_header, NULL, "Header");
638 proto_tree_add_item(subtree, hf_doip_version, tvb, DOIP_VERSION_OFFSET, DOIP_VERSION_LEN, ENC_BIG_ENDIAN);
639 proto_tree_add_item(subtree, hf_doip_inv_version, tvb, DOIP_INV_VERSION_OFFSET, DOIP_INV_VERSION_LEN, ENC_BIG_ENDIAN);
640 payload_type = tvb_get_uint16(tvb, DOIP_TYPE_OFFSET, ENC_BIG_ENDIAN);
641 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));
642 proto_tree_add_item_ret_uint(subtree, hf_doip_length, tvb, DOIP_LENGTH_OFFSET, DOIP_LENGTH_LEN, ENC_BIG_ENDIAN, &len);
644 if (tvb_captured_length(tvb) < len) {
645 proto_tree_add_expert(doip_tree, pinfo, &ei_doip_illegal_length_field, tvb, DOIP_LENGTH_OFFSET, DOIP_LENGTH_LEN);
646 col_append_str(pinfo->cinfo, COL_INFO, " [DoIP Length Field: Illegal Value]");
651 static void
652 add_generic_header_nack_fields(proto_tree *doip_tree, tvbuff_t *tvb)
654 proto_tree_add_item(doip_tree, hf_generic_nack_code, tvb, DOIP_GENERIC_NACK_OFFSET, DOIP_GENERIC_NACK_LEN, ENC_NA);
658 static void
659 add_vehicle_identification_eid_fields(proto_tree *doip_tree, tvbuff_t *tvb)
661 proto_tree_add_item(doip_tree, hf_eid, tvb, DOIP_VEHICLE_IDENTIFICATION_EID_OFFSET, DOIP_COMMON_EID_LEN, ENC_NA);
665 static void
666 add_vehicle_identification_vin_fields(proto_tree *doip_tree, tvbuff_t *tvb)
668 proto_tree_add_item(doip_tree, hf_vin, tvb, DOIP_VEHICLE_IDENTIFICATION_VIN_OFFSET, DOIP_COMMON_VIN_LEN, ENC_ASCII | ENC_NA);
672 static void
673 add_routing_activation_request_fields(proto_tree *doip_tree, tvbuff_t *tvb, uint8_t version)
675 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);
677 if (version == ISO13400_2010) {
678 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);
679 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);
681 if ( tvb_bytes_exist(tvb, DOIP_ROUTING_ACTIVATION_REQ_OEM_OFFSET_V1, DOIP_ROUTING_ACTIVATION_REQ_OEM_LEN) ) {
682 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);
684 } else if ((version == ISO13400_2012) || (version == ISO13400_2019)) {
685 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);
686 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);
688 if ( tvb_bytes_exist(tvb, DOIP_ROUTING_ACTIVATION_REQ_OEM_OFFSET_V2, DOIP_ROUTING_ACTIVATION_REQ_OEM_LEN) ) {
689 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);
695 static void
696 add_routing_activation_response_fields(proto_tree *doip_tree, tvbuff_t *tvb)
698 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);
699 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);
700 proto_tree_add_item(doip_tree, hf_response_code, tvb, DOIP_ROUTING_ACTIVATION_RES_CODE_OFFSET, DOIP_ROUTING_ACTIVATION_RES_CODE_LEN, ENC_NA);
701 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);
703 if ( tvb_bytes_exist(tvb, DOIP_ROUTING_ACTIVATION_RES_OEM_OFFSET, DOIP_ROUTING_ACTIVATION_RES_OEM_LEN) ) {
704 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);
709 static void
710 add_vehicle_announcement_message_fields(proto_tree *doip_tree, tvbuff_t *tvb)
712 proto_tree_add_item(doip_tree, hf_vin, tvb, DOIP_VEHICLE_ANNOUNCEMENT_VIN_OFFSET, DOIP_COMMON_VIN_LEN, ENC_ASCII | ENC_NA);
713 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);
714 proto_tree_add_item(doip_tree, hf_eid, tvb, DOIP_VEHICLE_ANNOUNCEMENT_EID_OFFSET, DOIP_COMMON_EID_LEN, ENC_NA);
715 proto_tree_add_item(doip_tree, hf_gid, tvb, DOIP_VEHICLE_ANNOUNCEMENT_GID_OFFSET, DOIP_VEHICLE_ANNOUNCEMENT_GID_LEN, ENC_NA);
716 proto_tree_add_item(doip_tree, hf_further_action, tvb, DOIP_VEHICLE_ANNOUNCEMENT_ACTION_OFFSET, DOIP_VEHICLE_ANNOUNCEMENT_ACTION_LEN, ENC_BIG_ENDIAN);
718 if ( tvb_bytes_exist(tvb, DOIP_VEHICLE_ANNOUNCEMENT_SYNC_OFFSET, DOIP_VEHICLE_ANNOUNCEMENT_SYNC_LEN) ) {
719 /* Not part of version 1 and optional in version 2. */
720 proto_tree_add_item(doip_tree, hf_sync_status, tvb, DOIP_VEHICLE_ANNOUNCEMENT_SYNC_OFFSET, DOIP_VEHICLE_ANNOUNCEMENT_SYNC_LEN, ENC_BIG_ENDIAN);
725 static void
726 add_alive_check_response_fields(proto_tree *doip_tree, tvbuff_t *tvb)
728 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);
732 static void
733 add_entity_status_response_fields(proto_tree *doip_tree, tvbuff_t *tvb)
735 proto_tree_add_item(doip_tree, hf_node_type, tvb, DOIP_ENTITY_STATUS_RESPONSE_NODE_OFFSET, DOIP_ENTITY_STATUS_RESPONSE_NODE_LEN, ENC_NA);
736 proto_tree_add_item(doip_tree, hf_max_sockets, tvb, DOIP_ENTITY_STATUS_RESPONSE_MCTS_OFFSET, DOIP_ENTITY_STATUS_RESPONSE_MCTS_LEN, ENC_NA);
737 proto_tree_add_item(doip_tree, hf_current_sockets, tvb, DOIP_ENTITY_STATUS_RESPONSE_NCTS_OFFSET, DOIP_ENTITY_STATUS_RESPONSE_NCTS_LEN, ENC_NA);
738 if ( tvb_bytes_exist(tvb, DOIP_ENTITY_STATUS_RESPONSE_MDS_OFFSET, DOIP_ENTITY_STATUS_RESPONSE_MDS_LEN) ) {
739 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);
744 static void
745 add_power_mode_information_response_fields(proto_tree *doip_tree, tvbuff_t *tvb)
747 proto_tree_add_item(doip_tree, hf_power_mode, tvb, DOIP_POWER_MODE_OFFSET, DOIP_POWER_MODE_LEN, ENC_NA);
751 static void
752 add_diagnostic_message_fields(proto_tree *doip_tree, tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
754 doip_info_t doip_info;
755 uint32_t tmp;
757 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);
758 doip_info.source_address = tmp;
759 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);
760 doip_info.target_address = tmp;
762 if (uds_handle != 0) {
763 call_dissector_with_data(uds_handle, tvb_new_subset_length(tvb, DOIP_DIAG_MESSAGE_DATA_OFFSET, -1), pinfo, parent_tree, &doip_info);
764 } else if (tvb_reported_length_remaining(tvb, DOIP_DIAG_MESSAGE_DATA_OFFSET) > 0) {
765 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);
770 static void
771 add_diagnostic_message_ack_fields(proto_tree *doip_tree, tvbuff_t *tvb)
773 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);
774 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);
775 proto_tree_add_item(doip_tree, hf_ack_code, tvb, DOIP_DIAG_MESSAGE_ACK_CODE_OFFSET, DOIP_DIAG_MESSAGE_ACK_CODE_LEN, ENC_NA);
777 if (tvb_captured_length_remaining(tvb, DOIP_DIAG_MESSAGE_ACK_PREVIOUS_OFFSET) > 0) {
778 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);
783 static void
784 add_diagnostic_message_nack_fields(proto_tree *doip_tree, tvbuff_t *tvb)
786 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);
787 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);
788 proto_tree_add_item(doip_tree, hf_nack_code, tvb, DOIP_DIAG_MESSAGE_NACK_CODE_OFFSET, DOIP_DIAG_MESSAGE_NACK_CODE_LEN, ENC_NA);
790 if (tvb_captured_length_remaining(tvb, DOIP_DIAG_MESSAGE_NACK_PREVIOUS_OFFSET) > 0) {
791 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);
796 /* DoIP protocol dissector */
797 static void
798 dissect_doip_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
800 uint8_t version = tvb_get_uint8(tvb, DOIP_VERSION_OFFSET);
801 uint16_t payload_type = tvb_get_ntohs(tvb, DOIP_TYPE_OFFSET);
803 int raw_offset_tvb = tvb_raw_offset(tvb);
804 int *first_offset = (int *)p_get_proto_data(wmem_file_scope(), pinfo, proto_doip, 0);
806 if (!first_offset) {
807 first_offset = wmem_new0(wmem_file_scope(), int);
808 *first_offset = raw_offset_tvb;
809 p_add_proto_data(wmem_file_scope(), pinfo, proto_doip, 0, first_offset);
812 /* Set protocol and clear information columns */
813 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DoIP");
815 if (*first_offset == raw_offset_tvb) {
816 col_clear(pinfo->cinfo, COL_INFO);
817 } else {
818 col_append_str(pinfo->cinfo, COL_INFO, " / ");
821 if (
822 version == ISO13400_2010 ||
823 version == ISO13400_2012 ||
824 version == ISO13400_2019 ||
825 version == ISO13400_2019_AMD1 ||
826 (version == DEFAULT_VALUE && (payload_type >= DOIP_VEHICLE_IDENTIFICATION_REQ && payload_type <= DOIP_VEHICLE_IDENTIFICATION_REQ_VIN))
828 col_append_str(pinfo->cinfo, COL_INFO, resolve_doip_payload_type(pinfo->pool, payload_type, true));
829 } else {
830 col_append_str(pinfo->cinfo, COL_INFO, "Invalid/unsupported DoIP version");
834 if (tree) {
835 proto_item *ti = NULL;
836 proto_tree *doip_tree = NULL;
838 ti = proto_tree_add_item(tree, proto_doip, tvb, 0, -1, ENC_NA);
839 doip_tree = proto_item_add_subtree(ti, ett_doip);
841 add_header(tvb, pinfo, doip_tree);
843 switch (payload_type) {
844 case DOIP_GENERIC_NACK:
845 add_generic_header_nack_fields(doip_tree, tvb);
846 break;
848 case DOIP_VEHICLE_IDENTIFICATION_REQ:
849 break;
851 case DOIP_VEHICLE_IDENTIFICATION_REQ_EID:
852 add_vehicle_identification_eid_fields(doip_tree, tvb);
853 break;
855 case DOIP_VEHICLE_IDENTIFICATION_REQ_VIN:
856 add_vehicle_identification_vin_fields(doip_tree, tvb);
857 break;
859 case DOIP_ROUTING_ACTIVATION_REQUEST:
860 add_routing_activation_request_fields(doip_tree, tvb, version);
861 break;
863 case DOIP_ROUTING_ACTIVATION_RESPONSE:
864 add_routing_activation_response_fields(doip_tree, tvb);
865 break;
867 case DOIP_VEHICLE_ANNOUNCEMENT_MESSAGE:
868 add_vehicle_announcement_message_fields(doip_tree, tvb);
869 break;
871 case DOIP_ALIVE_CHECK_REQUEST:
872 break;
874 case DOIP_ALIVE_CHECK_RESPONSE:
875 add_alive_check_response_fields(doip_tree, tvb);
876 break;
878 case DOIP_ENTITY_STATUS_REQUEST:
879 break;
881 case DOIP_ENTITY_STATUS_RESPONSE:
882 add_entity_status_response_fields(doip_tree, tvb);
883 break;
885 case DOIP_POWER_INFORMATION_REQUEST:
886 break;
888 case DOIP_POWER_INFORMATION_RESPONSE:
889 add_power_mode_information_response_fields(doip_tree, tvb);
890 break;
892 case DOIP_DIAGNOSTIC_MESSAGE:
893 add_diagnostic_message_fields(doip_tree, tvb, pinfo, tree);
894 break;
896 case DOIP_DIAGNOSTIC_MESSAGE_ACK:
897 add_diagnostic_message_ack_fields(doip_tree, tvb);
898 break;
900 case DOIP_DIAGNOSTIC_MESSAGE_NACK:
901 add_diagnostic_message_nack_fields(doip_tree, tvb);
902 break;
904 } else if (payload_type == DOIP_DIAGNOSTIC_MESSAGE) {
905 /* Show UDS details in info column */
906 if (uds_handle != 0) {
907 doip_info_t doip_info;
908 doip_info.source_address = tvb_get_uint16(tvb, DOIP_DIAG_COMMON_SOURCE_OFFSET, ENC_BIG_ENDIAN);
909 doip_info.target_address = tvb_get_uint16(tvb, DOIP_DIAG_COMMON_TARGET_OFFSET, ENC_BIG_ENDIAN);
910 call_dissector_with_data(uds_handle, tvb_new_subset_length(tvb, DOIP_DIAG_MESSAGE_DATA_OFFSET, -1), pinfo, NULL, &doip_info);
916 /* determine PDU length of protocol DoIP */
917 static unsigned
918 get_doip_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *p _U_)
920 uint8_t ver1 = tvb_get_uint8(tvb, DOIP_VERSION_OFFSET);
921 uint8_t ver2 = tvb_get_uint8(tvb, DOIP_INV_VERSION_OFFSET);
923 if (ver1 != ((~ver2) & 0xff)) {
924 /* if ver2 is not the inverse of ver1, we are not at the start of a DoIP message! */
925 /* bounds_error: (0 < return < DOIP_HEADER_LEN) */
926 return 1;
929 /* PDU Length = length field value + header length */
930 uint32_t ret = tvb_get_ntohl(tvb, offset + DOIP_LENGTH_OFFSET) + DOIP_HEADER_LEN;
932 if (ret < DOIP_HEADER_LEN || ret > 0x7fffffff) {
933 /* catch illegal length fields (overflow or too big) */
934 return DOIP_HEADER_LEN;
937 return ret;
941 static int
942 dissect_doip_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
944 dissect_doip_message(tvb, pinfo, tree);
945 return tvb_captured_length(tvb);
949 static int
950 dissect_doip(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, void *data)
952 tcp_dissect_pdus(tvb, pinfo, tree, true, DOIP_HEADER_LEN, get_doip_message_len, dissect_doip_pdu, data);
953 return tvb_captured_length(tvb);
957 /* Register DoIP Protocol */
958 void
959 proto_register_doip(void)
961 module_t *doip_module = NULL;
962 expert_module_t *expert_module_doip = NULL;
963 uat_t *doip_diag_addr_uat = NULL;
964 uat_t *doip_payload_type_uat = NULL;
966 static hf_register_info hf[] = {
967 /* Header */
968 { &hf_doip_version,
969 { "Version", "doip.version",
970 FT_UINT8, BASE_HEX,
971 VALS(doip_versions), 0x0,
972 NULL, HFILL }
974 { &hf_doip_inv_version,
975 { "Inverse version", "doip.inverse",
976 FT_UINT8, BASE_HEX,
977 NULL, 0x0,
978 NULL, HFILL }
980 { &hf_doip_type,
981 { "Type", "doip.type",
982 FT_UINT16, BASE_HEX,
983 VALS(doip_payloads), 0x0,
984 NULL, HFILL }
986 { &hf_doip_length,
987 { "Length", "doip.length",
988 FT_UINT32, BASE_DEC,
989 NULL, 0x0,
990 NULL, HFILL }
992 /* Generic NACK */
994 &hf_generic_nack_code,
996 "DoIP Header NACK code", "doip.nack_code",
997 FT_UINT8, BASE_HEX,
998 VALS(nack_codes), 0x00,
999 NULL, HFILL
1002 /* Vehicle announcement message */
1004 &hf_vin,
1006 "VIN", "doip.vin",
1007 FT_STRING, BASE_NONE,
1008 NULL, 0x00,
1009 NULL, HFILL
1013 &hf_logical_address,
1015 "Logical Address", "doip.logical_address",
1016 FT_UINT16, BASE_HEX,
1017 NULL, 0x00,
1018 NULL, HFILL
1022 &hf_logical_address_name,
1024 "Logical Address Name", "doip.logical_address_name",
1025 FT_STRING, BASE_NONE,
1026 NULL, 0x00,
1027 NULL, HFILL
1031 &hf_eid,
1033 "EID", "doip.eid",
1034 FT_BYTES, BASE_NONE,
1035 NULL, 0x00,
1036 NULL, HFILL
1040 &hf_gid,
1042 "GID", "doip.gid",
1043 FT_BYTES, BASE_NONE,
1044 NULL, 0x00,
1045 NULL, HFILL
1049 &hf_further_action,
1051 "Further action required", "doip.further_action",
1052 FT_UINT8, BASE_HEX,
1053 VALS(action_codes), 0x00,
1054 NULL, HFILL
1058 &hf_sync_status,
1060 "VIN/GID sync. status", "doip.sync_status",
1061 FT_UINT8, BASE_HEX,
1062 VALS(sync_status), 0x00,
1063 NULL, HFILL
1066 /* Diagnostic power mode information response */
1068 &hf_power_mode,
1070 "Diagnostic power mode", "doip.power_mode",
1071 FT_UINT8, BASE_HEX,
1072 VALS(power_modes), 0x00,
1073 NULL, HFILL
1076 /* Entity status response */
1078 &hf_node_type,
1080 "Node type", "doip.node_type",
1081 FT_UINT8, BASE_HEX,
1082 VALS(node_types), 0x00,
1083 NULL, HFILL
1087 &hf_max_sockets,
1089 "Max concurrent sockets", "doip.max_sockets",
1090 FT_UINT8, BASE_DEC,
1091 NULL, 0x00,
1092 NULL, HFILL
1096 &hf_current_sockets,
1098 "Currently open sockets", "doip.sockets",
1099 FT_UINT8, BASE_DEC,
1100 NULL, 0x00,
1101 NULL, HFILL
1105 &hf_max_data_size,
1107 "Max data size", "doip.max_data_size",
1108 FT_UINT32, BASE_DEC,
1109 NULL, 0x00,
1110 NULL, HFILL
1113 /* Common */
1115 &hf_source_address,
1117 "Source Address", "doip.source_address",
1118 FT_UINT16, BASE_HEX,
1119 NULL, 0x00,
1120 NULL, HFILL
1124 &hf_source_address_name,
1126 "Source Address Name", "doip.source_address_name",
1127 FT_STRING, BASE_NONE,
1128 NULL, 0x00,
1129 NULL, HFILL
1133 &hf_target_address,
1135 "Target Address", "doip.target_address",
1136 FT_UINT16, BASE_HEX,
1137 NULL, 0x00,
1138 NULL, HFILL
1142 &hf_target_address_name,
1144 "Target Address Name", "doip.target_address_name",
1145 FT_STRING, BASE_NONE,
1146 NULL, 0x00,
1147 NULL, HFILL
1150 /* Routing activation request */
1152 &hf_activation_type_v1,
1154 "Activation type", "doip.activation_type_v1",
1155 FT_UINT16, BASE_HEX,
1156 NULL, 0x00,
1157 NULL, HFILL
1161 &hf_activation_type_v2,
1163 "Activation type", "doip.activation_type",
1164 FT_UINT8, BASE_HEX,
1165 VALS(activation_types), 0x00,
1166 NULL, HFILL
1169 /* Routing activation response */
1171 &hf_tester_logical_address,
1173 "Logical address of external tester", "doip.tester_logical_address",
1174 FT_UINT16, BASE_HEX,
1175 NULL, 0x00,
1176 NULL, HFILL
1180 &hf_tester_logical_address_name,
1182 "Name of external tester", "doip.tester_logical_address_name",
1183 FT_STRING, BASE_NONE,
1184 NULL, 0x00,
1185 NULL, HFILL
1189 &hf_response_code,
1191 "Routing activation response code", "doip.response_code",
1192 FT_UINT8, BASE_HEX,
1193 VALS(activation_codes), 0x00,
1194 NULL, HFILL
1197 /* Common */
1199 &hf_reserved_iso,
1201 "Reserved by ISO", "doip.reserved_iso",
1202 FT_UINT32, BASE_HEX,
1203 NULL, 0x00,
1204 NULL, HFILL
1208 &hf_reserved_oem,
1210 "Reserved by OEM", "doip.reserved_oem",
1211 FT_UINT32, BASE_HEX,
1212 NULL, 0x00,
1213 NULL, HFILL
1216 /* Diagnostic message */
1218 &hf_data,
1220 "User data", "doip.data",
1221 FT_BYTES, BASE_NONE,
1222 NULL, 0x00,
1223 NULL, HFILL
1226 /* Diagnostic message ACK */
1228 &hf_ack_code,
1230 "ACK code", "doip.diag_ack_code",
1231 FT_UINT8, BASE_HEX,
1232 VALS(diag_ack_codes), 0x00,
1233 NULL, HFILL
1236 /* Diagnostic message NACK */
1238 &hf_nack_code,
1240 "NACK code", "doip.diag_nack_code",
1241 FT_UINT8, BASE_HEX,
1242 VALS(diag_nack_codes), 0x00,
1243 NULL, HFILL
1246 /* Common */
1248 &hf_previous,
1250 "Previous message", "doip.previous",
1251 FT_BYTES, BASE_NONE,
1252 NULL, 0x00,
1253 NULL, HFILL
1258 /* Setup protocol subtree array */
1259 static int *ett[] = {
1260 &ett_doip,
1261 &ett_header,
1262 &ett_address
1265 /* UAT definitions */
1266 static uat_field_t doip_diag_addr_uat_fields[] = {
1267 UAT_FLD_HEX(doip_diag_addresses, id, "Diagnostic Address", "Diagnostic Address (hex uint16 without leading 0x)"),
1268 UAT_FLD_CSTRING(doip_diag_addresses, name, "Name", "Name of the ECU (string)"),
1269 UAT_END_FIELDS
1272 static uat_field_t doip_payload_type_uat_fields[] = {
1273 UAT_FLD_HEX(doip_payload_types, id, "Payload Type", "Payload Type (hex uint16 without leading 0x)"),
1274 UAT_FLD_CSTRING(doip_payload_types, name, "Name", "Name of the Payload Type (string)"),
1275 UAT_END_FIELDS
1278 proto_doip = proto_register_protocol (
1279 "DoIP (ISO13400) Protocol", /* name */
1280 "DoIP", /* short name */
1281 "doip" /* abbrev */
1284 proto_register_field_array(proto_doip, hf, array_length(hf));
1285 proto_register_subtree_array(ett, array_length(ett));
1287 doip_handle = register_dissector("doip", dissect_doip, proto_doip);
1288 doip_module = prefs_register_protocol(proto_doip, NULL);
1290 /* UATs */
1291 doip_diag_addr_uat = uat_new("Diagnostic Addresses",
1292 sizeof(generic_one_id_string_t), /* record size */
1293 DATAFILE_DOIP_DIAG_ADDRESSES, /* filename */
1294 true, /* from profile */
1295 (void**)&doip_diag_addresses, /* data_ptr */
1296 &doip_diag_address_count, /* numitems_ptr */
1297 UAT_AFFECTS_DISSECTION, /* but not fields */
1298 NULL, /* help */
1299 copy_generic_one_id_string_cb, /* copy callback */
1300 update_generic_one_identifier_16bit, /* update callback */
1301 free_generic_one_id_string_cb, /* free callback */
1302 post_update_doip_diag_addresses, /* post update callback */
1303 NULL, /* reset callback */
1304 doip_diag_addr_uat_fields /* UAT field definitions */
1307 prefs_register_uat_preference(doip_module, "_udf_doip_diag_addresses", "Diagnostics Addresses",
1308 "A table to define names of Diagnostics Addresses.", doip_diag_addr_uat);
1310 doip_payload_type_uat = uat_new("Payload Types",
1311 sizeof(generic_one_id_string_t), /* record size */
1312 DATAFILE_DOIP_PAYLOAD_TYPES, /* filename */
1313 true, /* from profile */
1314 (void**)&doip_payload_types, /* data_ptr */
1315 &doip_payload_type_count, /* numitems_ptr */
1316 UAT_AFFECTS_DISSECTION, /* but not fields */
1317 NULL, /* help */
1318 copy_generic_one_id_string_cb, /* copy callback */
1319 update_generic_one_identifier_16bit, /* update callback */
1320 free_generic_one_id_string_cb, /* free callback */
1321 post_update_doip_payload_types, /* post update callback */
1322 NULL, /* reset callback */
1323 doip_payload_type_uat_fields /* UAT field definitions */
1326 prefs_register_uat_preference(doip_module, "_udf_doip_payload_types", "Payload Types",
1327 "A table to define names of Payload Types.", doip_payload_type_uat);
1329 prefs_register_bool_preference(doip_module, "hide_address_name_entries",
1330 "Hide Address Name Entries",
1331 "Should the dissector hide the names for addresses?",
1332 &doip_hide_address_names);
1334 static ei_register_info ei[] = {
1335 { &ei_doip_illegal_length_field, { "doip.illegal_length_field",
1336 PI_MALFORMED, PI_ERROR, "DoIP illegal length field", EXPFILL } },
1339 expert_module_doip = expert_register_protocol(proto_doip);
1340 expert_register_field_array(expert_module_doip, ei, array_length(ei));
1343 void
1344 proto_reg_handoff_doip(void)
1346 dissector_add_uint("udp.port", DOIP_PORT, doip_handle);
1347 dissector_add_uint("tcp.port", DOIP_PORT, doip_handle);
1349 ssl_dissector_add(DOIP_TLS_PORT, doip_handle);
1351 uds_handle = find_dissector("uds_over_doip");
1355 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1357 * Local variables:
1358 * c-basic-offset: 4
1359 * tab-width: 8
1360 * indent-tabs-mode: nil
1361 * End:
1363 * vi: set shiftwidth=4 tabstop=8 expandtab:
1364 * :indentSize=4:tabSize=8:noTabs=true: