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.
24 #include <epan/packet.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
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
78 #define DOIP_GENERIC_NACK_OFFSET DOIP_HEADER_LEN
79 #define DOIP_GENERIC_NACK_LEN 1
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
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)
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" },
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" },
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" },
226 /* Routing activation request */
227 static const value_string activation_types
[] = {
230 { 0xE0, "Central security" },
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." },
259 /* Vehicle announcement message */
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" },
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" },
304 /* Entity status response */
306 static const value_string node_types
[] = {
307 { 0x00, "DoIP gateway" },
308 { 0x01, "DoIp node" },
313 /* Diagnostic power mode information response */
315 static const value_string power_modes
[] = {
316 { 0x00, "not ready" },
318 { 0x02, "not supported" },
323 /* Diagnostic message ACK */
324 static const value_string diag_ack_codes
[] = {
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" },
350 static bool doip_hide_address_names
= true;
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
;
364 static int hf_generic_nack_code
;
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
;
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
;
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 */
416 /* Diagnostic message ACK */
417 static int hf_ack_code
;
420 /* Diagnostic message NACK */
421 static int hf_nack_code
;
429 static int ett_header
;
430 static int ett_address
;
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
;
447 typedef struct _generic_one_id_string
{
450 } generic_one_id_string_t
;
453 doip_uat_free_key(void *key
) {
454 wmem_free(wmem_epan_scope(), key
);
458 simple_free(void *data
) {
459 /* we need to free because of the g_strdup in post_update*/
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
;
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
);
483 if (rec
->name
== NULL
|| rec
->name
[0] == 0) {
484 *err
= g_strdup("Name cannot be empty");
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 */
500 post_update_one_id_string_template_cb(generic_one_id_string_t
*data
, unsigned data_num
, GHashTable
*ht
) {
504 for (i
= 0; i
< data_num
; i
++) {
505 key
= wmem_new(wmem_epan_scope(), int);
508 g_hash_table_insert(ht
, key
, g_strdup(data
[i
].name
));
513 ht_lookup_name(GHashTable
* ht
, unsigned int identifier
) {
515 unsigned int *id
= 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
);
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
)
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
);
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
;
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
);
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
;
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
)
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
);
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 */
611 tmp
= try_val_to_str(payload_type
, doip_payloads
);
614 /* no configured or standardized name known */
619 return wmem_strdup_printf(scope
, "%s (0x%04x)", tmp
, payload_type
);
623 /* just give back unknown */
625 return wmem_strdup_printf(scope
, "0x%04x Unknown Payload", payload_type
);
627 return wmem_strdup_printf(scope
, "Unknown (0x%04x)", payload_type
);
632 add_header(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*doip_tree
)
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]");
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
;
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
);
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
);
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 */
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);
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
);
818 col_append_str(pinfo
->cinfo
, COL_INFO
, " / ");
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));
830 col_append_str(pinfo
->cinfo
, COL_INFO
, "Invalid/unsupported DoIP version");
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
);
848 case DOIP_VEHICLE_IDENTIFICATION_REQ
:
851 case DOIP_VEHICLE_IDENTIFICATION_REQ_EID
:
852 add_vehicle_identification_eid_fields(doip_tree
, tvb
);
855 case DOIP_VEHICLE_IDENTIFICATION_REQ_VIN
:
856 add_vehicle_identification_vin_fields(doip_tree
, tvb
);
859 case DOIP_ROUTING_ACTIVATION_REQUEST
:
860 add_routing_activation_request_fields(doip_tree
, tvb
, version
);
863 case DOIP_ROUTING_ACTIVATION_RESPONSE
:
864 add_routing_activation_response_fields(doip_tree
, tvb
);
867 case DOIP_VEHICLE_ANNOUNCEMENT_MESSAGE
:
868 add_vehicle_announcement_message_fields(doip_tree
, tvb
);
871 case DOIP_ALIVE_CHECK_REQUEST
:
874 case DOIP_ALIVE_CHECK_RESPONSE
:
875 add_alive_check_response_fields(doip_tree
, tvb
);
878 case DOIP_ENTITY_STATUS_REQUEST
:
881 case DOIP_ENTITY_STATUS_RESPONSE
:
882 add_entity_status_response_fields(doip_tree
, tvb
);
885 case DOIP_POWER_INFORMATION_REQUEST
:
888 case DOIP_POWER_INFORMATION_RESPONSE
:
889 add_power_mode_information_response_fields(doip_tree
, tvb
);
892 case DOIP_DIAGNOSTIC_MESSAGE
:
893 add_diagnostic_message_fields(doip_tree
, tvb
, pinfo
, tree
);
896 case DOIP_DIAGNOSTIC_MESSAGE_ACK
:
897 add_diagnostic_message_ack_fields(doip_tree
, tvb
);
900 case DOIP_DIAGNOSTIC_MESSAGE_NACK
:
901 add_diagnostic_message_nack_fields(doip_tree
, tvb
);
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 */
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) */
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
;
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
);
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 */
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
[] = {
969 { "Version", "doip.version",
971 VALS(doip_versions
), 0x0,
974 { &hf_doip_inv_version
,
975 { "Inverse version", "doip.inverse",
981 { "Type", "doip.type",
983 VALS(doip_payloads
), 0x0,
987 { "Length", "doip.length",
994 &hf_generic_nack_code
,
996 "DoIP Header NACK code", "doip.nack_code",
998 VALS(nack_codes
), 0x00,
1002 /* Vehicle announcement message */
1007 FT_STRING
, BASE_NONE
,
1013 &hf_logical_address
,
1015 "Logical Address", "doip.logical_address",
1016 FT_UINT16
, BASE_HEX
,
1022 &hf_logical_address_name
,
1024 "Logical Address Name", "doip.logical_address_name",
1025 FT_STRING
, BASE_NONE
,
1034 FT_BYTES
, BASE_NONE
,
1043 FT_BYTES
, BASE_NONE
,
1051 "Further action required", "doip.further_action",
1053 VALS(action_codes
), 0x00,
1060 "VIN/GID sync. status", "doip.sync_status",
1062 VALS(sync_status
), 0x00,
1066 /* Diagnostic power mode information response */
1070 "Diagnostic power mode", "doip.power_mode",
1072 VALS(power_modes
), 0x00,
1076 /* Entity status response */
1080 "Node type", "doip.node_type",
1082 VALS(node_types
), 0x00,
1089 "Max concurrent sockets", "doip.max_sockets",
1096 &hf_current_sockets
,
1098 "Currently open sockets", "doip.sockets",
1107 "Max data size", "doip.max_data_size",
1108 FT_UINT32
, BASE_DEC
,
1117 "Source Address", "doip.source_address",
1118 FT_UINT16
, BASE_HEX
,
1124 &hf_source_address_name
,
1126 "Source Address Name", "doip.source_address_name",
1127 FT_STRING
, BASE_NONE
,
1135 "Target Address", "doip.target_address",
1136 FT_UINT16
, BASE_HEX
,
1142 &hf_target_address_name
,
1144 "Target Address Name", "doip.target_address_name",
1145 FT_STRING
, BASE_NONE
,
1150 /* Routing activation request */
1152 &hf_activation_type_v1
,
1154 "Activation type", "doip.activation_type_v1",
1155 FT_UINT16
, BASE_HEX
,
1161 &hf_activation_type_v2
,
1163 "Activation type", "doip.activation_type",
1165 VALS(activation_types
), 0x00,
1169 /* Routing activation response */
1171 &hf_tester_logical_address
,
1173 "Logical address of external tester", "doip.tester_logical_address",
1174 FT_UINT16
, BASE_HEX
,
1180 &hf_tester_logical_address_name
,
1182 "Name of external tester", "doip.tester_logical_address_name",
1183 FT_STRING
, BASE_NONE
,
1191 "Routing activation response code", "doip.response_code",
1193 VALS(activation_codes
), 0x00,
1201 "Reserved by ISO", "doip.reserved_iso",
1202 FT_UINT32
, BASE_HEX
,
1210 "Reserved by OEM", "doip.reserved_oem",
1211 FT_UINT32
, BASE_HEX
,
1216 /* Diagnostic message */
1220 "User data", "doip.data",
1221 FT_BYTES
, BASE_NONE
,
1226 /* Diagnostic message ACK */
1230 "ACK code", "doip.diag_ack_code",
1232 VALS(diag_ack_codes
), 0x00,
1236 /* Diagnostic message NACK */
1240 "NACK code", "doip.diag_nack_code",
1242 VALS(diag_nack_codes
), 0x00,
1250 "Previous message", "doip.previous",
1251 FT_BYTES
, BASE_NONE
,
1258 /* Setup protocol subtree array */
1259 static int *ett
[] = {
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)"),
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)"),
1278 proto_doip
= proto_register_protocol (
1279 "DoIP (ISO13400) Protocol", /* name */
1280 "DoIP", /* short name */
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
);
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 */
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 */
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
));
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
1360 * indent-tabs-mode: nil
1363 * vi: set shiftwidth=4 tabstop=8 expandtab:
1364 * :indentSize=4:tabSize=8:noTabs=true: