TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags
[wireshark-sm.git] / epan / dissectors / packet-dlt.c
blob4cc2de12b29fb29bd5b3f0498f482bd397c03dc2
1 /* packet-dlt.c
2 * DLT Dissector
3 * By Dr. Lars Voelker <lars.voelker@technica-engineering.de>
4 * Copyright 2013-2019 Dr. Lars Voelker, BMW
5 * Copyright 2020-2023 Dr. Lars Voelker, Technica Engineering GmbH
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
15 * For further information about the "Diagnostic Log and Trace" (DLT) protocol see:
16 * - GENIVI Alliance (https://covesa.global/ and https://github.com/GENIVI/)
17 * - AUTOSAR (https://www.autosar.org) -> AUTOSAR_SWS_DiagnosticLogAndTrace.pdf
20 /* This dissector currently only supports Version 1 of DLT. */
22 #include <config.h>
24 #include <epan/packet.h>
25 #include "packet-tcp.h"
26 #include "packet-udp.h"
27 #include <epan/exceptions.h>
28 #include <epan/expert.h>
29 #include <epan/show_exception.h>
30 #include <epan/etypes.h>
31 #include <epan/tvbuff.h>
33 #include <epan/to_str.h>
34 #include <epan/uat.h>
35 #include <wiretap/wtap.h>
37 #include "packet-dlt.h"
39 void proto_register_dlt(void);
40 void proto_reg_handoff_dlt(void);
42 void proto_register_dlt_storage_header(void);
43 void proto_reg_handoff_dlt_storage_header(void);
45 #define PNAME "DLT"
46 #define PSNAME "Diagnostic Log and Trace (DLT)"
47 #define PFNAME "dlt"
49 #define DLT_STORAGE_HEADER_NAME "DLT Storage Header (short)"
50 #define DLT_STORAGE_HEADER_NAME_LONG "Shortened Diagnostic Log and Trace (DLT) Storage Header"
51 #define DLT_STORAGE_HEADER_NAME_FILTER "dlt.storage"
53 #define DLT_MIN_SIZE_FOR_PARSING 4
55 #define DLT_HDR_TYPE_EXT_HEADER 0x01
56 #define DLT_HDR_TYPE_MSB_FIRST 0x02
57 #define DLT_HDR_TYPE_WITH_ECU_ID 0x04
58 #define DLT_HDR_TYPE_WITH_SESSION_ID 0x08
59 #define DLT_HDR_TYPE_WITH_TIMESTAMP 0x10
60 #define DLT_HDR_TYPE_VERSION 0xe0
61 #define DLT_MSG_INFO_VERBOSE 0x01
62 #define DLT_MSG_INFO_MSG_TYPE 0x0e
63 #define DLT_MSG_INFO_MSG_TYPE_INFO 0xf0
64 #define DLT_MSG_INFO_MSG_TYPE_INFO_COMB 0xfe
66 #define DLT_MSG_VERB_PARAM_LENGTH 0x0000000f
67 #define DLT_MSG_VERB_PARAM_BOOL 0x00000010
68 #define DLT_MSG_VERB_PARAM_SINT 0x00000020
69 #define DLT_MSG_VERB_PARAM_UINT 0x00000040
70 #define DLT_MSG_VERB_PARAM_FLOA 0x00000080
72 #define DLT_MSG_VERB_PARAM_ARAY 0x00000100
73 #define DLT_MSG_VERB_PARAM_STRG 0x00000200
74 #define DLT_MSG_VERB_PARAM_RAWD 0x00000400
75 #define DLT_MSG_VERB_PARAM_VARI 0x00000800
76 #define DLT_MSG_VERB_PARAM_FIXP 0x00001000
77 #define DLT_MSG_VERB_PARAM_TRAI 0x00002000
78 #define DLT_MSG_VERB_PARAM_STRU 0x00004000
80 #define DLT_MSG_VERB_PARAM_SCOD 0x00038000
81 #define DLT_MSG_VERB_PARAM_SCOD_ASCII 0x00000000
82 #define DLT_MSG_VERB_PARAM_SCOD_UTF8 0x00008000
83 #define DLT_MSG_VERB_PARAM_SCOD_SHIFT 15
85 #define DLT_MSG_VERB_PARAM_RES 0xfffc0000
87 #define DLT_SERVICE_ID_SET_LOG_LEVEL 0x01
88 #define DLT_SERVICE_ID_SET_TRACE_STATUS 0x02
89 #define DLT_SERVICE_ID_GET_LOG_INFO 0x03
90 #define DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL 0x04
91 #define DLT_SERVICE_ID_STORE_CONFIGURATION 0x05
92 #define DLT_SERVICE_ID_RESTORE_TO_FACTORY_DEFAULT 0x06
93 #define DLT_SERVICE_ID_SET_COM_INTERFACE_STATUS 0x07
94 #define DLT_SERVICE_ID_SET_COM_INTERFACE_MAX_BANDWIDTH 0x08
95 #define DLT_SERVICE_ID_SET_VERBOSE_MODE 0x09
96 #define DLT_SERVICE_ID_SET_MESSAGE_FILTERING 0x0a
97 #define DLT_SERVICE_ID_SET_TIMING_PACKETS 0x0b
98 #define DLT_SERVICE_ID_GET_LOCAL_TIME 0x0c
99 #define DLT_SERVICE_ID_USE_ECU_ID 0x0d
100 #define DLT_SERVICE_ID_USE_SESSION_ID 0x0e
101 #define DLT_SERVICE_ID_USE_TIMESTAMP 0x0f
102 #define DLT_SERVICE_ID_USE_EXTENDED_HEADER 0x10
103 #define DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL 0x11
104 #define DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS 0x12
105 #define DLT_SERVICE_ID_GET_SOFTWARE_VERSION 0x13
106 #define DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW 0x14
107 #define DLT_SERVICE_ID_GET_DEFAULT_TRACE_STATUS 0x15
108 #define DLT_SERVICE_ID_GET_COM_INTERFACE_STATUS 0x16
109 #define DLT_SERVICE_ID_GET_LOG_CHANNEL_NAMES 0x17
110 #define DLT_SERVICE_ID_GET_COM_INTERFACE_MAX_BANDWIDTH 0x18
111 #define DLT_SERVICE_ID_GET_VERBOSE_MODE_STATUS 0x19
112 #define DLT_SERVICE_ID_GET_MESSAGE_FILTERING_STATUS 0x1a
113 #define DLT_SERVICE_ID_GET_USE_ECUID 0x1b
114 #define DLT_SERVICE_ID_GET_USE_SESSION_ID 0x1c
115 #define DLT_SERVICE_ID_GET_USE_TIMESTAMP 0x1d
116 #define DLT_SERVICE_ID_GET_USE_EXTENDED_HEADER 0x1e
117 #define DLT_SERVICE_ID_GET_TRACE_STATUS 0x1f
118 #define DLT_SERVICE_ID_SET_LOG_CHANNEL_ASSIGNMENT 0x20
119 #define DLT_SERVICE_ID_SET_LOG_CHANNEL_THRESHOLD 0x21
120 #define DLT_SERVICE_ID_GET_LOG_CHANNEL_THRESHOLD 0x22
121 #define DLT_SERVICE_ID_BUFFER_OVERFLOW_NOTIFICATION 0x23
122 /* not found in specification but in github code */
123 #define DLT_USER_SERVICE_ID 0xf00
124 #define DLT_SERVICE_ID_UNREGISTER_CONTEXT 0xf01
125 #define DLT_SERVICE_ID_CONNECTION_INFO 0xf02
126 #define DLT_SERVICE_ID_TIMEZONE 0xf03
127 #define DLT_SERVICE_ID_MARKER 0xf04
128 #define DLT_SERVICE_ID_OFFLINE_LOGSTORAGE 0xF05
129 #define DLT_SERVICE_ID_PASSIVE_NODE_CONNECT 0xF06
130 #define DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS 0xF07
131 #define DLT_SERVICE_ID_SET_ALL_LOG_LEVEL 0xF08
132 #define DLT_SERVICE_ID_SET_ALL_TRACE_STATUS 0xF09
134 #define DLT_SERVICE_LOG_LEVEL_DEFAULT -1
135 #define DLT_SERVICE_LOG_LEVEL_NONE 0
136 #define DLT_SERVICE_LOG_LEVEL_FATAL 1
137 #define DLT_SERVICE_LOG_LEVEL_ERROR 2
138 #define DLT_SERVICE_LOG_LEVEL_WARN 3
139 #define DLT_SERVICE_LOG_LEVEL_INFO 4
140 #define DLT_SERVICE_LOG_LEVEL_DEBUG 5
141 #define DLT_SERVICE_LOG_LEVEL_VERBOSE 6
143 #define DLT_SERVICE_TRACE_STATUS_DEFAULT -1
144 #define DLT_SERVICE_TRACE_STATUS_OFF 0
145 #define DLT_SERVICE_TRACE_STATUS_ON 1
147 #define DLT_SERVICE_NEW_STATUS_OFF 0
148 #define DLT_SERVICE_NEW_STATUS_ON 1
150 #define DLT_SERVICE_STATUS_OK 0x00
151 #define DLT_SERVICE_STATUS_NOT_SUPPORTED 0x01
152 #define DLT_SERVICE_STATUS_ERROR 0x02
154 #define DLT_SERVICE_STATUS_LOG_LEVEL_NOT_SUPPORTED 1
155 #define DLT_SERVICE_STATUS_LOG_LEVEL_DLT_ERROR 2
156 #define DLT_SERVICE_STATUS_LOG_LEVEL_DLT_LOG_TRACE 6
157 #define DLT_SERVICE_STATUS_LOG_LEVEL_DLT_LOG_TRACE_TEXT 7
158 #define DLT_SERVICE_STATUS_LOG_LEVEL_DLT_NO_MATCH_CTX 8
159 #define DLT_SERVICE_STATUS_LOG_LEVEL_DLT_RESP_OVERFLOW 9
161 #define DLT_SERVICE_OPTIONS_WITH_LOG_TRACE 6
162 #define DLT_SERVICE_OPTIONS_WITH_LOG_TRACE_TEXT 7
164 static int proto_dlt;
165 static int proto_dlt_storage_header;
167 static dissector_handle_t dlt_handle_udp;
168 static dissector_handle_t dlt_handle_tcp;
169 static dissector_handle_t dlt_handle_storage;
171 /* Subdissectors */
172 static heur_dissector_list_t heur_subdissector_list;
173 static heur_dtbl_entry_t *heur_dtbl_entry;
175 /* header fields */
176 static int hf_dlt_header_type;
177 static int hf_dlt_ht_ext_header;
178 static int hf_dlt_ht_msb_first;
179 static int hf_dlt_ht_with_ecuid;
180 static int hf_dlt_ht_with_sessionid;
181 static int hf_dlt_ht_with_timestamp;
182 static int hf_dlt_ht_version;
184 static int hf_dlt_msg_ctr;
185 static int hf_dlt_length;
187 static int hf_dlt_ecu_id;
188 static int hf_dlt_session_id;
189 static int hf_dlt_timestamp;
191 static int hf_dlt_ext_hdr;
192 static int hf_dlt_msg_info;
193 static int hf_dlt_mi_verbose;
194 static int hf_dlt_mi_msg_type;
195 static int hf_dlt_mi_msg_type_info;
196 static int hf_dlt_num_of_args;
197 static int hf_dlt_app_id;
198 static int hf_dlt_ctx_id;
200 static int hf_dlt_payload;
201 static int hf_dlt_message_id;
202 static int hf_dlt_payload_data;
204 static int hf_dlt_data_bool;
205 static int hf_dlt_uint8;
206 static int hf_dlt_uint16;
207 static int hf_dlt_uint32;
208 static int hf_dlt_uint64;
209 static int hf_dlt_int8;
210 static int hf_dlt_int16;
211 static int hf_dlt_int32;
212 static int hf_dlt_int64;
213 static int hf_dlt_float;
214 static int hf_dlt_double;
215 static int hf_dlt_rawd;
216 static int hf_dlt_string;
218 static int hf_dlt_service_options;
219 static int hf_dlt_service_application_id;
220 static int hf_dlt_service_context_id;
221 static int hf_dlt_service_log_level;
222 static int hf_dlt_service_new_log_level;
223 static int hf_dlt_service_trace_status;
224 static int hf_dlt_service_new_trace_status;
225 static int hf_dlt_service_new_status;
226 static int hf_dlt_service_reserved;
227 static int hf_dlt_service_status;
228 static int hf_dlt_service_length;
229 static int hf_dlt_service_swVersion;
230 static int hf_dlt_service_status_log_info;
231 static int hf_dlt_service_log_levels;
232 static int hf_dlt_service_count;
233 static int hf_dlt_service_app_desc;
234 static int hf_dlt_service_ctx_desc;
236 static int hf_dlt_storage_tstamp_s;
237 static int hf_dlt_storage_tstamp_us;
238 static int hf_dlt_storage_ecu_name;
239 static int hf_dlt_storage_reserved;
241 /* subtrees */
242 static int ett_dlt;
243 static int ett_dlt_hdr_type;
244 static int ett_dlt_ext_hdr;
245 static int ett_dlt_msg_info;
246 static int ett_dlt_payload;
247 static int ett_dlt_service_app_ids;
248 static int ett_dlt_service_app_id;
249 static int ett_dlt_service_ctx_id;
251 static int ett_dlt_storage;
253 /***************************
254 ****** String Tables ******
255 ***************************/
257 /* DLT Message Types */
258 static const value_string dlt_msg_type[] = {
259 {DLT_MSG_TYPE_LOG_MSG, "DLT Log Message"},
260 {DLT_MSG_TYPE_TRACE_MSG, "DLT Trace Message"},
261 {DLT_MSG_TYPE_NETWORK_MSG, "DLT Network Message"},
262 {DLT_MSG_TYPE_CTRL_MSG, "DLT Control Message"},
263 {0, NULL}
266 /* DLT Message Types Infos - this is not context free and uses bits of dlt_msg_type too! */
267 static const value_string dlt_msg_type_info[] = {
268 {DLT_MSG_TYPE_INFO_LOG_FATAL, "Fatal"},
269 {DLT_MSG_TYPE_INFO_LOG_ERROR, "Error"},
270 {DLT_MSG_TYPE_INFO_LOG_WARN, "Warn"},
271 {DLT_MSG_TYPE_INFO_LOG_INFO, "Info"},
272 {DLT_MSG_TYPE_INFO_LOG_DEBUG, "Debug"},
273 {DLT_MSG_TYPE_INFO_LOG_VERBOSE, "Verbose"},
274 {DLT_MSG_TYPE_INFO_TRACE_VAR, "Variable"},
275 {DLT_MSG_TYPE_INFO_TRACE_FUNC_IN, "Function In"},
276 {DLT_MSG_TYPE_INFO_TRACE_FUNC_OUT, "Function Out"},
277 {DLT_MSG_TYPE_INFO_TRACE_STATE, "State"},
278 {DLT_MSG_TYPE_INFO_TRACE_VFB, "VFB"},
279 {DLT_MSG_TYPE_INFO_NET_IPC, "IPC"},
280 {DLT_MSG_TYPE_INFO_NET_CAN, "CAN"},
281 {DLT_MSG_TYPE_INFO_NET_FLEXRAY, "FlexRay"},
282 {DLT_MSG_TYPE_INFO_NET_MOST, "MOST"},
283 {DLT_MSG_TYPE_INFO_CTRL_REQ, "Request"},
284 {DLT_MSG_TYPE_INFO_CTRL_RES, "Response"},
285 {DLT_MSG_TYPE_INFO_CTRL_TIME, "Time"},
286 {0, NULL}
289 static const value_string dlt_service[] = {
290 {DLT_SERVICE_ID_SET_LOG_LEVEL, "Set Log Level"},
291 {DLT_SERVICE_ID_SET_TRACE_STATUS, "Set Trace Status"},
292 {DLT_SERVICE_ID_GET_LOG_INFO, "Get Log Info"},
293 {DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL, "Get Default Log Level"},
294 {DLT_SERVICE_ID_STORE_CONFIGURATION, "Store Configuration"},
295 {DLT_SERVICE_ID_RESTORE_TO_FACTORY_DEFAULT, "Restore Factory Default"},
296 {DLT_SERVICE_ID_SET_COM_INTERFACE_STATUS, "Set Com Interface Status (Deprecated!)"},
297 {DLT_SERVICE_ID_SET_COM_INTERFACE_MAX_BANDWIDTH, "Set Com Interface Max Bandwidth (Deprecated!)"},
298 {DLT_SERVICE_ID_SET_VERBOSE_MODE, "Set Verbose Mode (Deprecated!)"},
299 {DLT_SERVICE_ID_SET_MESSAGE_FILTERING, "Set Message Filtering"},
300 {DLT_SERVICE_ID_SET_TIMING_PACKETS, "Set Timing Packets (Deprecated!)"},
301 {DLT_SERVICE_ID_GET_LOCAL_TIME, "Get Local Time (Deprecated!)"},
302 {DLT_SERVICE_ID_USE_ECU_ID, "Use ECU ID (Deprecated!)"},
303 {DLT_SERVICE_ID_USE_SESSION_ID, "Use Session ID (Deprecated!)"},
304 {DLT_SERVICE_ID_USE_TIMESTAMP, "Use Timestamp (Deprecated!)"},
305 {DLT_SERVICE_ID_USE_EXTENDED_HEADER, "Use Extended Header (Deprecated!)"},
306 {DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL, "Set Default Log Level"},
307 {DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS, "Set Default Trace Status"},
308 {DLT_SERVICE_ID_GET_SOFTWARE_VERSION, "Get Software Version"},
309 {DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW, "Message Buffer Overflow (Deprecated!)"},
310 {DLT_SERVICE_ID_GET_DEFAULT_TRACE_STATUS, "Get Default trace Status"},
311 {DLT_SERVICE_ID_GET_COM_INTERFACE_STATUS, "Get Com Interface Status (Deprecated!)"},
312 {DLT_SERVICE_ID_GET_LOG_CHANNEL_NAMES, "Get Log Channel Names"},
313 {DLT_SERVICE_ID_GET_COM_INTERFACE_MAX_BANDWIDTH, "Get Com Interface Max Bandwidth (Deprecated!)"},
314 {DLT_SERVICE_ID_GET_VERBOSE_MODE_STATUS, "Get Verbose Mode Status (Deprecated!)"},
315 {DLT_SERVICE_ID_GET_MESSAGE_FILTERING_STATUS, "Get Message Filtering Status (Deprecated!)"},
316 {DLT_SERVICE_ID_GET_USE_ECUID, "Get Use ECUID (Deprecated!)"},
317 {DLT_SERVICE_ID_GET_USE_SESSION_ID, "Get Use Session ID (Deprecated!)"},
318 {DLT_SERVICE_ID_GET_USE_TIMESTAMP, "Get Use Timestamp (Deprecated!)"},
319 {DLT_SERVICE_ID_GET_USE_EXTENDED_HEADER, "Get Use Extended Header (Deprecated!)"},
320 {DLT_SERVICE_ID_GET_TRACE_STATUS, "Get Trace Status"},
321 {DLT_SERVICE_ID_SET_LOG_CHANNEL_ASSIGNMENT, "Set Log Channel Assignment"},
322 {DLT_SERVICE_ID_SET_LOG_CHANNEL_THRESHOLD, "Set Log Channel Threshold"},
323 {DLT_SERVICE_ID_GET_LOG_CHANNEL_THRESHOLD, "Get log Channel Threshold"},
324 {DLT_SERVICE_ID_BUFFER_OVERFLOW_NOTIFICATION, "Buffer Overflow Notification"},
325 {DLT_USER_SERVICE_ID, "User Service"},
326 {DLT_SERVICE_ID_UNREGISTER_CONTEXT, "Unregister Context (undefined)"},
327 {DLT_SERVICE_ID_CONNECTION_INFO, "Connection Info (undefined)"},
328 {DLT_SERVICE_ID_TIMEZONE, "Timezone (undefined)"},
329 {DLT_SERVICE_ID_MARKER, "Marker (undefined)"},
330 {DLT_SERVICE_ID_OFFLINE_LOGSTORAGE, "Offline Log Storage (undefined)"},
331 {DLT_SERVICE_ID_PASSIVE_NODE_CONNECT, "Passive Mode Connect (undefined)"},
332 {DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS, "Passive Mode Connection Status (undefined)"},
333 {DLT_SERVICE_ID_SET_ALL_LOG_LEVEL, "Set All Log Level (undefined)"},
334 {DLT_SERVICE_ID_SET_ALL_TRACE_STATUS, "Set All Trace Status (undefined)"},
335 {0, NULL}
338 static const value_string dlt_service_log_level[] = {
339 {DLT_SERVICE_LOG_LEVEL_DEFAULT, "Default Log Level"},
340 {DLT_SERVICE_LOG_LEVEL_NONE, "No Messages"},
341 {DLT_SERVICE_LOG_LEVEL_FATAL, "Fatal"},
342 {DLT_SERVICE_LOG_LEVEL_ERROR, "Error"},
343 {DLT_SERVICE_LOG_LEVEL_WARN, "Warn"},
344 {DLT_SERVICE_LOG_LEVEL_INFO, "Info"},
345 {DLT_SERVICE_LOG_LEVEL_DEBUG, "Debug"},
346 {DLT_SERVICE_LOG_LEVEL_VERBOSE, "Verbose"},
347 {0, NULL}
350 static const value_string dlt_service_trace_status[] = {
351 {DLT_SERVICE_TRACE_STATUS_DEFAULT, "Default Trace Status"},
352 {DLT_SERVICE_TRACE_STATUS_OFF, "Off"},
353 {DLT_SERVICE_TRACE_STATUS_ON, "On"},
354 {0, NULL}
357 static const value_string dlt_service_new_status[] = {
358 {DLT_SERVICE_NEW_STATUS_OFF, "Off"},
359 {DLT_SERVICE_NEW_STATUS_ON, "On"},
360 {0, NULL}
363 static const value_string dlt_service_status[] = {
364 {DLT_SERVICE_STATUS_OK, "OK"},
365 {DLT_SERVICE_STATUS_NOT_SUPPORTED, "Not supported"},
366 {DLT_SERVICE_STATUS_ERROR, "Error"},
367 {0, NULL}
370 static const value_string dlt_service_options[] = {
371 {DLT_SERVICE_OPTIONS_WITH_LOG_TRACE, "Loglevel and Trace status"},
372 {DLT_SERVICE_OPTIONS_WITH_LOG_TRACE_TEXT, "Loglevel, Trace status, and Textual"},
373 {0, NULL}
376 #define DLT_SERVICE_OPTIONS_WITH_LOG_TRACE 6
377 #define DLT_SERVICE_OPTIONS_WITH_LOG_TRACE_TEXT 7
379 /*************************
380 ****** Expert Info ******
381 *************************/
383 static expert_field ei_dlt_unsupported_datatype;
384 static expert_field ei_dlt_unsupported_length_datatype;
385 static expert_field ei_dlt_unsupported_string_coding;
386 static expert_field ei_dlt_unsupported_non_verbose_msg_type;
387 static expert_field ei_dlt_buffer_too_short;
388 static expert_field ei_dlt_parsing_error;
390 static void
391 expert_dlt_unsupported_parameter(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, int length) {
392 if (tvb!=NULL) {
393 proto_tree_add_expert(tree, pinfo, &ei_dlt_unsupported_datatype, tvb, offset, length);
395 col_append_str(pinfo->cinfo, COL_INFO, " [DLT: Unsupported Data Type!]");
398 static void
399 expert_dlt_unsupported_length_datatype(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, int length) {
400 if (tvb != NULL) {
401 proto_tree_add_expert(tree, pinfo, &ei_dlt_unsupported_length_datatype, tvb, offset, length);
403 col_append_str(pinfo->cinfo, COL_INFO, " [DLT: Unsupported Length of Datatype!]");
406 static void
407 expert_dlt_unsupported_string_coding(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, int length) {
408 if (tvb != NULL) {
409 proto_tree_add_expert(tree, pinfo, &ei_dlt_unsupported_string_coding, tvb, offset, length);
411 col_append_str(pinfo->cinfo, COL_INFO, " [DLT: Unsupported String Coding!]");
414 static void
415 expert_dlt_unsupported_non_verbose_msg_type(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, int length) {
416 if (tvb != NULL) {
417 proto_tree_add_expert(tree, pinfo, &ei_dlt_unsupported_non_verbose_msg_type, tvb, offset, length);
419 col_append_str(pinfo->cinfo, COL_INFO, " [DLT: Unsupported Non-Verbose Message Type!]");
422 static void
423 expert_dlt_buffer_too_short(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, int length) {
424 if (tvb != NULL) {
425 proto_tree_add_expert(tree, pinfo, &ei_dlt_buffer_too_short, tvb, offset, length);
427 col_append_str(pinfo->cinfo, COL_INFO, " [DLT: Buffer too short!]");
430 static void
431 expert_dlt_parsing_error(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, int length) {
432 if (tvb != NULL) {
433 proto_tree_add_expert(tree, pinfo, &ei_dlt_parsing_error, tvb, offset, length);
435 col_append_str(pinfo->cinfo, COL_INFO, " [DLT: Parsing Error!]");
439 /*****************************
440 ****** Helper routines ******
441 *****************************/
443 int32_t
444 dlt_ecu_id_to_int32(const char *ecu_id) {
445 if (ecu_id == NULL) {
446 return 0;
449 int32_t ret = 0;
450 int i;
451 unsigned shift = 32;
453 /* DLT allows only up to 4 ASCII chars! Unused is 0x00 */
454 for (i = 0; i < (int)strlen(ecu_id) && i < 4; i++) {
455 shift -= 8;
456 ret |= (int32_t)ecu_id[i] << shift;
459 return ret;
462 /**********************************
463 ****** The dissector itself ******
464 **********************************/
466 static void
467 sanitize_buffer(uint8_t *buf, int length, uint32_t encoding) {
468 int i = 0;
470 for (i=0; i<length; i++) {
471 /* UTF-8 uses the ASCII chars. So between 0x00 and 0x7f, we can treat it as ASCII. :) */
472 if ((encoding==DLT_MSG_VERB_PARAM_SCOD_UTF8 || encoding==DLT_MSG_VERB_PARAM_SCOD_ASCII) && buf[i]!=0x00 && buf[i]<0x20) {
473 /* write space for special chars */
474 buf[i]=0x20;
479 static uint32_t
480 dissect_dlt_verbose_parameter_bool(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, bool payload_le _U_, uint32_t type_info _U_, int length) {
481 uint8_t value = 0;
483 if (length != 1 || tvb_captured_length_remaining(tvb, offset) < length) {
484 expert_dlt_buffer_too_short(tree, pinfo, tvb, offset, 0);
485 return 0;
488 value = tvb_get_uint8(tvb, offset);
489 proto_tree_add_item(tree, hf_dlt_data_bool, tvb, offset, 1, ENC_NA);
491 if (value==0x00) {
492 col_append_str(pinfo->cinfo, COL_INFO, " false");
493 } else if (value==0x01) {
494 col_append_str(pinfo->cinfo, COL_INFO, " true");
495 } else {
496 col_append_str(pinfo->cinfo, COL_INFO, " undefined");
499 return length;
502 static uint32_t
503 dissect_dlt_verbose_parameter_int(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, bool payload_le, uint32_t type_info _U_, int length) {
504 int64_t value = 0;
506 if (tvb_captured_length_remaining(tvb, offset) < length) {
507 return 0;
510 if (payload_le) {
511 switch (length) {
512 case 1:
513 proto_tree_add_item(tree, hf_dlt_int8, tvb, offset, 1, ENC_LITTLE_ENDIAN);
514 value = (int8_t)tvb_get_uint8(tvb, offset);
515 break;
516 case 2:
517 proto_tree_add_item(tree, hf_dlt_int16, tvb, offset, 2, ENC_LITTLE_ENDIAN);
518 value = (int16_t)tvb_get_letohs(tvb, offset);
519 break;
520 case 4:
521 proto_tree_add_item(tree, hf_dlt_int32, tvb, offset, 4, ENC_LITTLE_ENDIAN);
522 value = (int32_t)tvb_get_letohl(tvb, offset);
523 break;
524 case 8:
525 proto_tree_add_item(tree, hf_dlt_int64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
526 value = (int64_t)tvb_get_letoh64(tvb, offset);
527 break;
528 case 16:
529 default:
530 expert_dlt_unsupported_length_datatype(tree, pinfo, tvb, offset, length);
532 } else {
533 switch (length) {
534 case 1:
535 proto_tree_add_item(tree, hf_dlt_int8, tvb, offset, 1, ENC_BIG_ENDIAN);
536 value = (int8_t)tvb_get_uint8(tvb, offset);
537 break;
538 case 2:
539 proto_tree_add_item(tree, hf_dlt_int16, tvb, offset, 2, ENC_BIG_ENDIAN);
540 value = (int16_t)tvb_get_ntohs(tvb, offset);
541 break;
542 case 4:
543 proto_tree_add_item(tree, hf_dlt_int32, tvb, offset, 4, ENC_BIG_ENDIAN);
544 value = (int32_t)tvb_get_ntohl(tvb, offset);
545 break;
546 case 8:
547 proto_tree_add_item(tree, hf_dlt_int64, tvb, offset, 8, ENC_BIG_ENDIAN);
548 value = (int64_t)tvb_get_ntoh64(tvb, offset);
549 break;
550 case 16:
551 default:
552 expert_dlt_unsupported_length_datatype(tree, pinfo, tvb, offset, length);
556 col_append_fstr(pinfo->cinfo, COL_INFO, " %" PRId64, value);
557 return length;
560 static uint32_t
561 dissect_dlt_verbose_parameter_uint(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, bool payload_le, uint32_t type_info _U_, int length) {
562 uint64_t value = 0;
564 if (tvb_captured_length_remaining(tvb, offset) < length) {
565 expert_dlt_buffer_too_short(tree, pinfo, tvb, offset, 0);
566 return 0;
569 if (payload_le) {
570 switch (length) {
571 case 1:
572 proto_tree_add_item(tree, hf_dlt_uint8, tvb, offset, 1, ENC_LITTLE_ENDIAN);
573 value = tvb_get_uint8(tvb, offset);
574 break;
575 case 2:
576 proto_tree_add_item(tree, hf_dlt_uint16, tvb, offset, 2, ENC_LITTLE_ENDIAN);
577 value = tvb_get_letohs(tvb, offset);
578 break;
579 case 4:
580 proto_tree_add_item(tree, hf_dlt_uint32, tvb, offset, 4, ENC_LITTLE_ENDIAN);
581 value = tvb_get_letohl(tvb, offset);
582 break;
583 case 8:
584 proto_tree_add_item(tree, hf_dlt_uint64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
585 value = tvb_get_letoh64(tvb, offset);
586 break;
587 case 16:
588 default:
589 expert_dlt_unsupported_length_datatype(tree, pinfo, tvb, offset, length);
591 } else {
592 switch (length) {
593 case 1:
594 proto_tree_add_item(tree, hf_dlt_uint8, tvb, offset, 1, ENC_BIG_ENDIAN);
595 value = tvb_get_uint8(tvb, offset);
596 break;
597 case 2:
598 proto_tree_add_item(tree, hf_dlt_uint16, tvb, offset, 2, ENC_BIG_ENDIAN);
599 value = tvb_get_ntohs(tvb, offset);
600 break;
601 case 4:
602 proto_tree_add_item(tree, hf_dlt_uint32, tvb, offset, 4, ENC_BIG_ENDIAN);
603 value = tvb_get_ntohl(tvb, offset);
604 break;
605 case 8:
606 proto_tree_add_item(tree, hf_dlt_uint64, tvb, offset, 8, ENC_BIG_ENDIAN);
607 value = tvb_get_ntoh64(tvb, offset);
608 break;
609 case 16:
610 default:
611 expert_dlt_unsupported_length_datatype(tree, pinfo, tvb, offset, length);
615 col_append_fstr(pinfo->cinfo, COL_INFO, " %" PRIu64, value);
616 return length;
619 static uint32_t
620 dissect_dlt_verbose_parameter_float(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, bool payload_le, uint32_t type_info _U_, int length) {
621 double value = 0.0;
623 if (tvb_captured_length_remaining(tvb, offset) < length) {
624 expert_dlt_buffer_too_short(tree, pinfo, tvb, offset, 0);
625 return 0;
628 if (payload_le) {
629 switch (length) {
630 case 4:
631 proto_tree_add_item(tree, hf_dlt_float, tvb, offset, 4, ENC_LITTLE_ENDIAN);
632 value = (double)tvb_get_letohieee_float(tvb, offset);
633 break;
634 case 8:
635 proto_tree_add_item(tree, hf_dlt_double, tvb, offset, 8, ENC_LITTLE_ENDIAN);
636 value = tvb_get_letohieee_double(tvb, offset);
637 break;
638 case 2:
639 case 16:
640 default:
641 expert_dlt_unsupported_length_datatype(tree, pinfo, tvb, offset, length);
643 } else {
644 switch (length) {
645 case 4:
646 proto_tree_add_item(tree, hf_dlt_float, tvb, offset, 4, ENC_BIG_ENDIAN);
647 value = (double)tvb_get_ntohieee_float(tvb, offset);
648 break;
649 case 8:
650 proto_tree_add_item(tree, hf_dlt_double, tvb, offset, 8, ENC_BIG_ENDIAN);
651 value = tvb_get_ntohieee_double(tvb, offset);
652 break;
653 case 2:
654 case 16:
655 default:
656 expert_dlt_unsupported_length_datatype(tree, pinfo, tvb, offset, length);
660 col_append_fstr(pinfo->cinfo, COL_INFO, " %f", value);
661 return length;
664 static uint32_t
665 dissect_dlt_verbose_parameter_raw_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, bool payload_le, uint32_t type_info _U_, int length _U_) {
666 uint16_t len = 0;
667 uint8_t *buf = NULL;
668 uint32_t i = 0;
669 uint32_t offset_orig = offset;
671 if (tvb_captured_length_remaining(tvb, offset) < 2) {
672 expert_dlt_buffer_too_short(tree, pinfo, tvb, offset, 0);
673 return offset - offset_orig;
676 if (payload_le) {
677 len = tvb_get_letohs(tvb, offset);
678 } else {
679 len = tvb_get_ntohs(tvb, offset);
681 offset += 2;
683 if (tvb_captured_length_remaining(tvb, offset) < len) {
684 expert_dlt_buffer_too_short(tree, pinfo, tvb, offset, 0);
685 return offset - offset_orig;
688 proto_tree_add_item(tree, hf_dlt_rawd, tvb, offset, len, ENC_NA);
690 buf = (uint8_t *) tvb_memdup(pinfo->pool, tvb, offset, len);
691 offset += len;
693 for (i=0; i<len; i++) {
694 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "%02x", buf[i]);
697 return offset - offset_orig;
700 static uint32_t
701 dissect_dlt_verbose_parameter_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, bool payload_le, uint32_t type_info _U_, int length _U_) {
702 uint16_t str_len = 0;
703 uint32_t encoding = 0;
704 uint8_t *buf = NULL;
705 uint32_t offset_orig = offset;
706 int tmp_length = 0;
707 tvbuff_t *subtvb = NULL;
709 if (tvb_captured_length_remaining(tvb, offset) < 2) {
710 expert_dlt_buffer_too_short(tree, pinfo, tvb, offset, 0);
711 return offset - offset_orig;
714 if (payload_le) {
715 str_len = tvb_get_letohs(tvb, offset);
716 } else {
717 str_len = tvb_get_ntohs(tvb, offset);
719 offset += 2;
721 if (tvb_captured_length_remaining(tvb, offset) < str_len) {
722 expert_dlt_buffer_too_short(tree, pinfo, tvb, offset, 0);
723 return offset - offset_orig;
726 encoding = (type_info & DLT_MSG_VERB_PARAM_SCOD);
728 if (encoding!=DLT_MSG_VERB_PARAM_SCOD_ASCII && encoding!=DLT_MSG_VERB_PARAM_SCOD_UTF8) {
729 expert_dlt_unsupported_string_coding(tree, pinfo, tvb, offset, str_len);
730 return -1;
733 subtvb = tvb_new_subset_length(tvb, offset, str_len);
735 if (encoding == DLT_MSG_VERB_PARAM_SCOD_ASCII) {
736 buf = tvb_get_stringz_enc(pinfo->pool, subtvb, 0, &tmp_length, ENC_ASCII);
738 else {
739 buf = tvb_get_stringz_enc(pinfo->pool, subtvb, 0, &tmp_length, ENC_UTF_8);
742 if ( buf != NULL && tmp_length > 0) {
743 sanitize_buffer(buf, tmp_length, encoding);
744 proto_tree_add_item(tree, hf_dlt_string, tvb, offset, str_len, ENC_ASCII | ENC_NA);
745 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", buf);
746 } else {
747 expert_dlt_parsing_error(tree, pinfo, tvb, offset, str_len);
750 offset += str_len;
751 return offset - offset_orig;
754 static uint32_t
755 dissect_dlt_verbose_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, bool payload_le) {
756 uint32_t type_info = 0;
757 uint8_t length_field = 0;
758 int length = 0;
759 uint32_t offset_orig = offset;
761 /* we need at least the uint32 type info to decide on how much more bytes we need */
762 if (tvb_captured_length_remaining(tvb, offset) < 4) {
763 expert_dlt_parsing_error(tree, pinfo, tvb, offset, tvb_captured_length_remaining(tvb, offset));
764 return -1;
767 if (payload_le) {
768 type_info = tvb_get_letohl(tvb, offset);
769 } else {
770 type_info = tvb_get_ntohl(tvb, offset);
772 offset +=4;
774 length_field = type_info & DLT_MSG_VERB_PARAM_LENGTH;
776 length=0;
777 switch (length_field) {
778 case 0x01:
779 length=1;
780 break;
781 case 0x02:
782 length=2;
783 break;
784 case 0x03:
785 length=4;
786 break;
787 case 0x04:
788 length=8;
789 break;
790 case 0x05:
791 length=16;
792 break;
795 if (length > 0 && tvb_captured_length_remaining(tvb, offset) < length) {
796 return -1;
799 switch (type_info & (~ (DLT_MSG_VERB_PARAM_LENGTH | DLT_MSG_VERB_PARAM_SCOD))) {
800 case DLT_MSG_VERB_PARAM_BOOL:
801 offset += dissect_dlt_verbose_parameter_bool(tvb, pinfo, tree, offset, payload_le, type_info, length);
802 break;
803 case DLT_MSG_VERB_PARAM_SINT:
804 offset += dissect_dlt_verbose_parameter_int(tvb, pinfo, tree, offset, payload_le, type_info, length);
805 break;
806 case DLT_MSG_VERB_PARAM_UINT:
807 offset += dissect_dlt_verbose_parameter_uint(tvb, pinfo, tree, offset, payload_le, type_info, length);
808 break;
809 case DLT_MSG_VERB_PARAM_FLOA:
810 offset += dissect_dlt_verbose_parameter_float(tvb, pinfo, tree, offset, payload_le, type_info, length);
811 break;
812 case DLT_MSG_VERB_PARAM_STRG:
813 offset += dissect_dlt_verbose_parameter_string(tvb, pinfo, tree, offset, payload_le, type_info, length);
814 break;
815 case DLT_MSG_VERB_PARAM_RAWD:
816 offset += dissect_dlt_verbose_parameter_raw_data(tvb, pinfo, tree, offset, payload_le, type_info, length);
817 break;
818 default:
819 expert_dlt_unsupported_parameter(tree, pinfo, tvb, offset, 0);
822 if ( (offset-offset_orig) <= 4) {
823 return 0;
824 } else {
825 return offset - offset_orig;
829 static uint32_t
830 dissect_dlt_verbose_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, bool payload_le, uint8_t num_of_args) {
831 uint32_t i = 0;
832 uint32_t offset_orig = offset;
833 uint32_t len_parsed = 5;
835 while (len_parsed>4 && i<num_of_args) {
836 len_parsed = dissect_dlt_verbose_parameter(tvb, pinfo, tree, offset, payload_le);
837 offset += len_parsed;
838 i++;
841 return offset - offset_orig;
844 static int
845 dissect_dlt_non_verbose_payload_message(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, uint32_t offset, bool payload_le, uint8_t msg_type _U_,
846 uint8_t msg_type_info_comb, uint32_t message_id) {
847 proto_item *ti = NULL;
848 proto_tree *subtree;
849 proto_tree *subtree2;
850 proto_tree *subtree3;
851 int ret = 0;
852 int len;
853 uint32_t offset_orig;
854 unsigned tmp_length = 0;
855 unsigned encoding = ENC_BIG_ENDIAN;
856 unsigned status;
857 unsigned appid_count;
858 unsigned ctxid_count;
859 unsigned i;
860 unsigned j;
862 offset_orig = offset;
864 if (payload_le) {
865 encoding = ENC_LITTLE_ENDIAN;
868 len = tvb_captured_length_remaining(tvb, offset);
869 if (len == 0) {
870 return 0;
873 if (msg_type_info_comb == DLT_MSG_TYPE_INFO_CTRL_REQ) {
874 switch (message_id) {
875 case DLT_SERVICE_ID_SET_LOG_LEVEL:
876 proto_tree_add_item(tree, hf_dlt_service_application_id, tvb, offset, 4, ENC_ASCII | ENC_NA);
877 proto_tree_add_item(tree, hf_dlt_service_context_id, tvb, offset + 4, 4, ENC_ASCII | ENC_NA );
878 proto_tree_add_item(tree, hf_dlt_service_new_log_level, tvb, offset + 8, 1, ENC_NA);
879 proto_tree_add_item(tree, hf_dlt_service_reserved, tvb, offset + 9, 4, ENC_NA);
880 ret = 13;
881 break;
882 case DLT_SERVICE_ID_SET_TRACE_STATUS:
883 proto_tree_add_item(tree, hf_dlt_service_application_id, tvb, offset, 4, ENC_ASCII | ENC_NA);
884 proto_tree_add_item(tree, hf_dlt_service_context_id, tvb, offset + 4, 4, ENC_ASCII | ENC_NA);
885 proto_tree_add_item(tree, hf_dlt_service_new_trace_status, tvb, offset + 8, 1, ENC_NA);
886 proto_tree_add_item(tree, hf_dlt_service_reserved, tvb, offset + 9, 4, ENC_NA);
887 ret = 13;
888 break;
889 case DLT_SERVICE_ID_GET_LOG_INFO:
890 proto_tree_add_item(tree, hf_dlt_service_options, tvb, offset, 1, ENC_NA);
891 proto_tree_add_item(tree, hf_dlt_service_application_id, tvb, offset + 1, 4, ENC_ASCII | ENC_NA);
892 proto_tree_add_item(tree, hf_dlt_service_context_id, tvb, offset + 5, 4, ENC_ASCII | ENC_NA);
893 proto_tree_add_item(tree, hf_dlt_service_reserved, tvb, offset + 9, 4, ENC_NA);
894 break;
895 case DLT_SERVICE_ID_SET_MESSAGE_FILTERING:
896 proto_tree_add_item(tree, hf_dlt_service_new_status, tvb, offset, 1, ENC_NA);
897 ret = 1;
898 break;
899 case DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL:
900 proto_tree_add_item(tree, hf_dlt_service_new_log_level, tvb, offset, 1, ENC_NA);
901 proto_tree_add_item(tree, hf_dlt_service_reserved, tvb, offset + 1, 4, ENC_NA);
902 ret = 5;
903 break;
904 case DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS:
905 proto_tree_add_item(tree, hf_dlt_service_new_trace_status, tvb, offset, 1, ENC_NA);
906 proto_tree_add_item(tree, hf_dlt_service_reserved, tvb, offset + 1, 4, ENC_NA);
907 ret = 5;
908 break;
910 } else if (msg_type_info_comb == DLT_MSG_TYPE_INFO_CTRL_RES) {
911 switch (message_id) {
912 case DLT_SERVICE_ID_SET_LOG_LEVEL:
913 case DLT_SERVICE_ID_SET_TRACE_STATUS:
914 case DLT_SERVICE_ID_STORE_CONFIGURATION:
915 case DLT_SERVICE_ID_RESTORE_TO_FACTORY_DEFAULT:
916 case DLT_SERVICE_ID_SET_VERBOSE_MODE:
917 case DLT_SERVICE_ID_SET_MESSAGE_FILTERING:
918 case DLT_SERVICE_ID_SET_TIMING_PACKETS:
919 case DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL:
920 case DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS:
921 case DLT_SERVICE_ID_SET_LOG_CHANNEL_ASSIGNMENT:
922 proto_tree_add_item(tree, hf_dlt_service_status, tvb, offset, 1, ENC_NA);
923 ret = 1;
924 break;
925 case DLT_SERVICE_ID_GET_LOG_INFO:
926 proto_tree_add_item_ret_uint(tree, hf_dlt_service_status_log_info, tvb, offset, 1, ENC_NA, &status);
927 offset += 1;
928 ti = proto_tree_add_item(tree, hf_dlt_service_log_levels, tvb, offset, len - 4, ENC_NA);
929 subtree = proto_item_add_subtree(ti, ett_dlt_service_app_ids);
931 proto_tree_add_item_ret_uint(subtree, hf_dlt_service_count, tvb, offset, 2, encoding, &appid_count);
932 offset += 2;
933 /* loop over all app id entries */
934 for (i=0; i<appid_count; i++) {
935 ti = proto_tree_add_item(subtree, hf_dlt_service_application_id, tvb, offset, 4, ENC_ASCII | ENC_NA);
936 offset += 4;
937 subtree2 = proto_item_add_subtree(ti, ett_dlt_service_app_id);
939 proto_tree_add_item_ret_uint(subtree2, hf_dlt_service_count, tvb, offset, 2, encoding, &ctxid_count);
940 offset += 2;
941 /* loop over all ctx id entries */
942 for (j = 0; j < ctxid_count; j++) {
943 ti = proto_tree_add_item(subtree2, hf_dlt_service_context_id, tvb, offset, 4, ENC_ASCII | ENC_NA);
944 subtree3 = proto_item_add_subtree(ti, ett_dlt_service_ctx_id);
945 offset += 4;
947 proto_tree_add_item(subtree3, hf_dlt_service_log_level, tvb, offset, 1, encoding);
948 offset += 1;
949 proto_tree_add_item(subtree3, hf_dlt_service_trace_status, tvb, offset, 1, encoding);
950 offset += 1;
952 if (status == DLT_SERVICE_STATUS_LOG_LEVEL_DLT_LOG_TRACE_TEXT) {
953 proto_tree_add_item_ret_uint(subtree2, hf_dlt_service_count, tvb, offset, 2, encoding, &tmp_length);
954 offset += 2;
955 proto_tree_add_item(subtree2, hf_dlt_service_ctx_desc, tvb, offset, tmp_length, ENC_ASCII | ENC_NA);
956 offset += tmp_length;
959 if (status == DLT_SERVICE_STATUS_LOG_LEVEL_DLT_LOG_TRACE_TEXT) {
960 proto_tree_add_item_ret_uint(subtree, hf_dlt_service_count, tvb, offset, 2, encoding, &tmp_length);
961 offset += 2;
962 proto_tree_add_item(subtree, hf_dlt_service_app_desc, tvb, offset, tmp_length, ENC_ASCII | ENC_NA);
963 offset += tmp_length;
967 proto_tree_add_item(tree, hf_dlt_service_reserved, tvb, offset_orig + len - 4, 4, ENC_NA);
968 ret = len;
969 break;
970 case DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL:
971 proto_tree_add_item(tree, hf_dlt_service_status, tvb, offset, 1, ENC_NA);
972 proto_tree_add_item(tree, hf_dlt_service_log_level, tvb, offset+1, 1, ENC_NA);
973 ret = 2;
974 break;
975 case DLT_SERVICE_ID_GET_SOFTWARE_VERSION:
976 proto_tree_add_item(tree, hf_dlt_service_status, tvb, offset, 1, ENC_NA);
977 proto_tree_add_item_ret_uint(tree, hf_dlt_service_length, tvb, offset + 1, 4, encoding, &tmp_length);
978 if ((unsigned)len >= 5 + tmp_length) {
979 proto_tree_add_item(tree, hf_dlt_service_swVersion, tvb, offset + 5, tmp_length, ENC_ASCII | ENC_NA);
980 } else {
981 expert_dlt_buffer_too_short(tree, pinfo, tvb, offset, len);
983 ret = 5 + tmp_length;
984 break;
987 if (ret==0 && len>0) {
988 proto_tree_add_item(tree, hf_dlt_payload_data, tvb, offset, len, encoding);
989 ret = len;
991 return ret;
994 static bool
995 dissect_dlt_non_verbose_payload_message_handoff(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, bool payload_le,
996 uint8_t msg_type, uint8_t msg_type_info_comb, uint32_t message_id, const uint8_t *ecu_id) {
998 dlt_info_t dlt_info;
1000 dlt_info.message_id = message_id;
1001 dlt_info.little_endian = payload_le;
1002 dlt_info.message_type = msg_type;
1003 dlt_info.message_type_info_comb = msg_type_info_comb;
1004 dlt_info.ecu_id = (const char *)ecu_id;
1006 return dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree, &heur_dtbl_entry, &dlt_info);
1009 static int
1010 dissect_dlt_non_verbose_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *root_tree, proto_tree *tree, uint32_t offset, bool payload_le,
1011 uint8_t msg_type, uint8_t msg_type_info_comb, const uint8_t *ecu_id) {
1012 uint32_t message_id = 0;
1013 tvbuff_t *subtvb = NULL;
1014 uint32_t offset_orig = offset;
1015 const char *message_id_name = NULL;
1016 proto_item *ti;
1018 if (payload_le) {
1019 ti = proto_tree_add_item(tree, hf_dlt_message_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1020 message_id = tvb_get_letohl(tvb, offset);
1021 } else {
1022 ti = proto_tree_add_item(tree, hf_dlt_message_id, tvb, offset, 4, ENC_BIG_ENDIAN);
1023 message_id = tvb_get_ntohl(tvb, offset);
1025 offset += 4;
1027 if (msg_type==DLT_MSG_TYPE_CTRL_MSG && (msg_type_info_comb==DLT_MSG_TYPE_INFO_CTRL_REQ || msg_type_info_comb==DLT_MSG_TYPE_INFO_CTRL_RES)) {
1028 if (tvb_captured_length_remaining(tvb, offset) == 0) {
1029 return offset - offset_orig;
1032 message_id_name = try_val_to_str(message_id, dlt_service);
1034 if (message_id_name == NULL) {
1035 col_append_fstr(pinfo->cinfo, COL_INFO, " Unknown Non-Verbose Message (ID: 0x%02x)", message_id);
1036 } else {
1037 col_append_fstr(pinfo->cinfo, COL_INFO, " %s (ID: 0x%02x)", message_id_name, message_id);
1038 proto_item_append_text(ti, " (%s)", message_id_name);
1041 subtvb = tvb_new_subset_remaining(tvb, offset);
1042 dissect_dlt_non_verbose_payload_message(subtvb, pinfo, tree, 0, payload_le, msg_type, msg_type_info_comb, message_id);
1043 } else if(msg_type == DLT_MSG_TYPE_LOG_MSG) {
1044 subtvb = tvb_new_subset_remaining(tvb, offset);
1045 if (!dissect_dlt_non_verbose_payload_message_handoff(subtvb, pinfo, root_tree, payload_le, msg_type, msg_type_info_comb, message_id, ecu_id)) {
1046 proto_tree_add_item(tree, hf_dlt_payload_data, tvb, offset, tvb_captured_length_remaining(tvb, offset), payload_le);
1048 } else {
1049 expert_dlt_unsupported_non_verbose_msg_type(tree, pinfo, tvb, offset, 0);
1052 return offset - offset_orig;
1055 static int
1056 dissect_dlt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_, uint32_t offset_orig) {
1057 proto_item *ti;
1058 proto_tree *dlt_tree = NULL;
1059 proto_tree *ext_hdr_tree = NULL;
1060 proto_tree *subtree = NULL;
1061 uint32_t offset = offset_orig;
1063 uint8_t header_type = 0;
1064 bool ext_header = false;
1065 bool payload_le = false;
1066 uint16_t length = 0;
1068 uint8_t msg_info = 0;
1069 bool verbose = false;
1070 uint8_t msg_type = 0;
1071 uint8_t msg_type_info = 0;
1072 uint8_t msg_type_info_comb = 0;
1074 uint8_t num_of_args = 0;
1075 double timestamp = 0.0;
1077 int captured_length = tvb_captured_length_remaining(tvb, offset);
1079 const uint8_t *ecu_id = NULL;
1081 col_set_str(pinfo->cinfo, COL_PROTOCOL, PNAME);
1082 col_clear(pinfo->cinfo, COL_INFO);
1083 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "%s", PNAME);
1085 if (captured_length < DLT_MIN_SIZE_FOR_PARSING) {
1086 expert_dlt_buffer_too_short(tree, pinfo, tvb, offset, captured_length);
1087 return captured_length;
1090 header_type = tvb_get_uint8(tvb, offset);
1091 ext_header = ((header_type & DLT_HDR_TYPE_EXT_HEADER) == DLT_HDR_TYPE_EXT_HEADER);
1092 payload_le = ((header_type & DLT_HDR_TYPE_MSB_FIRST) != DLT_HDR_TYPE_MSB_FIRST);
1094 ti = proto_tree_add_item(tree, proto_dlt, tvb, offset, -1, ENC_NA);
1095 dlt_tree = proto_item_add_subtree(ti, ett_dlt);
1097 ti = proto_tree_add_item(dlt_tree, hf_dlt_header_type, tvb, offset, 1, ENC_NA);
1098 subtree = proto_item_add_subtree(ti, ett_dlt_hdr_type);
1100 proto_tree_add_item(subtree, hf_dlt_ht_ext_header, tvb, offset, 1, ENC_NA);
1101 proto_tree_add_item(subtree, hf_dlt_ht_msb_first, tvb, offset, 1, ENC_NA);
1102 proto_tree_add_item(subtree, hf_dlt_ht_with_ecuid, tvb, offset, 1, ENC_NA);
1103 proto_tree_add_item(subtree, hf_dlt_ht_with_sessionid, tvb, offset, 1, ENC_NA);
1104 proto_tree_add_item(subtree, hf_dlt_ht_with_timestamp, tvb, offset, 1, ENC_NA);
1105 proto_tree_add_item(subtree, hf_dlt_ht_version, tvb, offset, 1, ENC_NA);
1106 offset += 1;
1108 proto_tree_add_item(dlt_tree, hf_dlt_msg_ctr, tvb, offset, 1, ENC_NA);
1109 offset += 1;
1111 length = tvb_get_ntohs(tvb, offset);
1112 proto_tree_add_item(dlt_tree, hf_dlt_length, tvb, offset, 2, ENC_NA);
1113 offset += 2;
1115 if ((header_type & DLT_HDR_TYPE_WITH_ECU_ID) == DLT_HDR_TYPE_WITH_ECU_ID) {
1116 proto_tree_add_item_ret_string(dlt_tree, hf_dlt_ecu_id, tvb, offset, 4, ENC_ASCII | ENC_NA, pinfo->pool, &ecu_id);
1117 offset += 4;
1120 if ((header_type & DLT_HDR_TYPE_WITH_SESSION_ID) == DLT_HDR_TYPE_WITH_SESSION_ID) {
1121 proto_tree_add_item(dlt_tree, hf_dlt_session_id, tvb, offset, 4, ENC_NA);
1122 offset += 4;
1125 if ((header_type & DLT_HDR_TYPE_WITH_TIMESTAMP) == DLT_HDR_TYPE_WITH_TIMESTAMP) {
1126 timestamp = (tvb_get_ntohl(tvb, offset)/10000.0);
1127 proto_tree_add_double_format_value(dlt_tree, hf_dlt_timestamp, tvb, offset, 4, timestamp, "%.4f s", timestamp);
1128 offset += 4;
1131 if ((header_type & DLT_HDR_TYPE_EXT_HEADER) == DLT_HDR_TYPE_EXT_HEADER) {
1132 ti = proto_tree_add_item(dlt_tree, hf_dlt_ext_hdr, tvb, offset, 10, ENC_NA);
1133 ext_hdr_tree = proto_item_add_subtree(ti, ett_dlt_ext_hdr);
1135 ti = proto_tree_add_item(ext_hdr_tree, hf_dlt_msg_info, tvb, offset, 1, ENC_NA);
1136 subtree = proto_item_add_subtree(ti, ett_dlt_msg_info);
1138 proto_tree_add_item(subtree, hf_dlt_mi_verbose, tvb, offset, 1, ENC_NA);
1140 msg_info = tvb_get_uint8(tvb, offset);
1141 verbose = (msg_info & DLT_MSG_INFO_VERBOSE) == DLT_MSG_INFO_VERBOSE;
1142 msg_type_info_comb = msg_info & DLT_MSG_INFO_MSG_TYPE_INFO_COMB;
1143 msg_type = (msg_type_info_comb & DLT_MSG_INFO_MSG_TYPE) >> 1;
1144 msg_type_info = (msg_type_info_comb & DLT_MSG_INFO_MSG_TYPE_INFO) >> 4;
1146 proto_tree_add_item(subtree, hf_dlt_mi_msg_type, tvb, offset, 1, ENC_NA);
1147 proto_tree_add_uint_format_value(subtree, hf_dlt_mi_msg_type_info, tvb, offset, 1, msg_info, "%s (%d)",
1148 val_to_str_const(msg_type_info_comb, dlt_msg_type_info, "Unknown Message Type Info"), msg_type_info);
1149 offset += 1;
1151 num_of_args = tvb_get_uint8(tvb, offset);
1152 proto_tree_add_item(ext_hdr_tree, hf_dlt_num_of_args, tvb, offset, 1, ENC_NA);
1153 offset += 1;
1155 proto_tree_add_item(ext_hdr_tree, hf_dlt_app_id, tvb, offset, 4, ENC_ASCII | ENC_NA);
1156 offset += 4;
1158 proto_tree_add_item(ext_hdr_tree, hf_dlt_ctx_id, tvb, offset, 4, ENC_ASCII | ENC_NA);
1159 offset += 4;
1162 ti = proto_tree_add_item(dlt_tree, hf_dlt_payload, tvb, offset, length - offset, ENC_NA);
1163 subtree = proto_item_add_subtree(ti, ett_dlt_payload);
1165 col_append_str(pinfo->cinfo, COL_INFO, ":");
1167 if (!ext_header || !verbose) {
1168 offset += dissect_dlt_non_verbose_payload(tvb, pinfo, tree, subtree, offset, payload_le, msg_type, msg_type_info_comb, ecu_id);
1169 } else {
1170 offset += dissect_dlt_verbose_payload(tvb, pinfo, subtree, offset, payload_le, num_of_args);
1173 col_set_fence(pinfo->cinfo, COL_INFO);
1174 return offset - offset_orig;
1177 static int
1178 dissect_dlt_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
1179 return dissect_dlt(tvb, pinfo, tree, data, 0);
1182 static unsigned
1183 get_dlt_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void* data _U_) {
1184 return tvb_get_ntohs(tvb, offset + 2);
1187 static int
1188 dissect_dlt_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
1189 tcp_dissect_pdus(tvb, pinfo, tree, true, DLT_MIN_SIZE_FOR_PARSING, get_dlt_message_len, dissect_dlt_msg, data);
1190 return tvb_reported_length(tvb);
1193 static int
1194 dissect_dlt_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
1195 return udp_dissect_pdus(tvb, pinfo, tree, DLT_MIN_SIZE_FOR_PARSING, NULL, get_dlt_message_len, dissect_dlt_msg, data);
1198 static int
1199 dissect_dlt_storage_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
1200 proto_tree *dlt_storage_tree;
1201 proto_item *ti;
1203 uint32_t offset = 0;
1205 ti = proto_tree_add_item(tree, proto_dlt_storage_header, tvb, offset, 16, ENC_NA);
1206 dlt_storage_tree = proto_item_add_subtree(ti, ett_dlt_storage);
1208 proto_tree_add_item(dlt_storage_tree, hf_dlt_storage_tstamp_s, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1209 offset += 4;
1211 proto_tree_add_item(dlt_storage_tree, hf_dlt_storage_tstamp_us, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1212 offset += 4;
1214 /* setting source to ECU Name of the encapsulation header */
1215 set_address_tvb(&(pinfo->src), AT_STRINGZ, 4, tvb, offset);
1216 proto_tree_add_item(dlt_storage_tree, hf_dlt_storage_ecu_name, tvb, offset, 5, ENC_ASCII);
1217 offset += 5;
1219 proto_tree_add_item(dlt_storage_tree, hf_dlt_storage_reserved, tvb, offset, 3, ENC_NA);
1220 return 16 + dissect_dlt(tvb, pinfo, tree, data, 16);
1223 void proto_register_dlt(void) {
1224 expert_module_t *expert_module_DLT;
1226 static hf_register_info hf_dlt[] = {
1227 { &hf_dlt_header_type, {
1228 "Header Type", "dlt.header_type",
1229 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1231 { &hf_dlt_ht_ext_header, {
1232 "Extended Header", "dlt.header_type.ext_header",
1233 FT_BOOLEAN, 8, NULL, DLT_HDR_TYPE_EXT_HEADER, NULL, HFILL }},
1234 { &hf_dlt_ht_msb_first, {
1235 "MSB First", "dlt.header_type.msb_first",
1236 FT_BOOLEAN, 8, NULL, DLT_HDR_TYPE_MSB_FIRST, NULL, HFILL }},
1237 { &hf_dlt_ht_with_ecuid, {
1238 "With ECU ID", "dlt.header_type.with_ecu_id",
1239 FT_BOOLEAN, 8, NULL, DLT_HDR_TYPE_WITH_ECU_ID, NULL, HFILL }},
1240 { &hf_dlt_ht_with_sessionid, {
1241 "With Session ID", "dlt.header_type.with_session_id",
1242 FT_BOOLEAN, 8, NULL, DLT_HDR_TYPE_WITH_SESSION_ID, NULL, HFILL }},
1243 { &hf_dlt_ht_with_timestamp, {
1244 "With Timestamp", "dlt.header_type.with_timestamp",
1245 FT_BOOLEAN, 8, NULL, DLT_HDR_TYPE_WITH_TIMESTAMP, NULL, HFILL }},
1246 { &hf_dlt_ht_version, {
1247 "Version", "dlt.header_type.version",
1248 FT_UINT8, BASE_DEC, NULL, DLT_HDR_TYPE_VERSION, NULL, HFILL }},
1250 { &hf_dlt_msg_ctr, {
1251 "Message Counter", "dlt.msg_counter",
1252 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1253 { &hf_dlt_length, {
1254 "Length", "dlt.length",
1255 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1256 { &hf_dlt_ecu_id, {
1257 "ECU ID", "dlt.ecu_id",
1258 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1259 { &hf_dlt_session_id, {
1260 "Session ID", "dlt.session_id",
1261 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1262 { &hf_dlt_timestamp, {
1263 "Timestamp", "dlt.timestamp",
1264 FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1266 { &hf_dlt_ext_hdr, {
1267 "Extended Header", "dlt.ext_header",
1268 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1269 { &hf_dlt_msg_info, {
1270 "Message Info", "dlt.msg_info",
1271 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1272 { &hf_dlt_mi_verbose, {
1273 "Verbose", "dlt.msg_info.verbose",
1274 FT_BOOLEAN, 8, NULL, DLT_MSG_INFO_VERBOSE, NULL, HFILL }},
1275 { &hf_dlt_mi_msg_type, {
1276 "Message Type", "dlt.msg_info.msg_type",
1277 FT_UINT8, BASE_DEC, VALS(dlt_msg_type), DLT_MSG_INFO_MSG_TYPE, NULL, HFILL }},
1278 { &hf_dlt_mi_msg_type_info, {
1279 "Message Type Info", "dlt.msg_info.msg_type_info",
1280 FT_UINT8, BASE_DEC, NULL, DLT_MSG_INFO_MSG_TYPE_INFO, NULL, HFILL }},
1281 { &hf_dlt_num_of_args, {
1282 "Number of Arguments", "dlt.num_of_args",
1283 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1284 { &hf_dlt_app_id, {
1285 "Application ID", "dlt.application_id",
1286 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1287 { &hf_dlt_ctx_id, {
1288 "Context ID", "dlt.context_id",
1289 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1291 { &hf_dlt_payload, {
1292 "Payload", "dlt.payload",
1293 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1294 { &hf_dlt_message_id, {
1295 "Message ID", "dlt.message_id",
1296 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1297 { &hf_dlt_payload_data, {
1298 "Payload Data", "dlt.payload.data",
1299 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1301 { &hf_dlt_data_bool, {
1302 "(bool)", "dlt.data.bool",
1303 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1304 { &hf_dlt_uint8, {
1305 "(uint8)", "dlt.data.uint8",
1306 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1307 { &hf_dlt_uint16, {
1308 "(uint16)", "dlt.data.uint16",
1309 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1310 { &hf_dlt_uint32, {
1311 "(uint32)", "dlt.data.uint32",
1312 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1313 { &hf_dlt_uint64, {
1314 "(uint64)", "dlt.data.uint64",
1315 FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1316 { &hf_dlt_int8, {
1317 "(int8)", "dlt.data.int8",
1318 FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1319 { &hf_dlt_int16, {
1320 "(int16)", "dlt.data.int16",
1321 FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1322 { &hf_dlt_int32, {
1323 "(int32)", "dlt.data.int32",
1324 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1325 { &hf_dlt_int64, {
1326 "(int64)", "dlt.data.int64",
1327 FT_INT64, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1328 { &hf_dlt_float, {
1329 "(float)", "dlt.data.float",
1330 FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1331 { &hf_dlt_double, {
1332 "(double)", "dlt.data.double",
1333 FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1334 { &hf_dlt_rawd, {
1335 "(rawd)", "dlt.data.rawd",
1336 FT_BYTES, BASE_NONE, NULL, 0x00, NULL, HFILL } },
1337 { &hf_dlt_string, {
1338 "(string)", "dlt.data.string",
1339 FT_STRING, BASE_NONE, NULL, 0x00, NULL, HFILL } },
1341 { &hf_dlt_service_options, {
1342 "Options", "dlt.service.options",
1343 FT_UINT8, BASE_DEC, VALS(dlt_service_options), 0x0, NULL, HFILL } },
1344 { &hf_dlt_service_application_id, {
1345 "Application ID", "dlt.service.application_id",
1346 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1347 { &hf_dlt_service_context_id, {
1348 "Context ID", "dlt.service.context_id",
1349 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1350 { &hf_dlt_service_log_level, {
1351 "Log Level", "dlt.service.log_level",
1352 FT_INT8, BASE_DEC, VALS(dlt_service_log_level), 0x0, NULL, HFILL } },
1353 { &hf_dlt_service_new_log_level, {
1354 "New Log Level", "dlt.service.new_log_level",
1355 FT_INT8, BASE_DEC, VALS(dlt_service_log_level), 0x0, NULL, HFILL } },
1356 { &hf_dlt_service_trace_status, {
1357 "Trace Status", "dlt.service.trace_status",
1358 FT_INT8, BASE_DEC, VALS(dlt_service_trace_status), 0x0, NULL, HFILL } },
1359 { &hf_dlt_service_new_trace_status, {
1360 "New Trace Status", "dlt.service.new_trace_status",
1361 FT_INT8, BASE_DEC, VALS(dlt_service_trace_status), 0x0, NULL, HFILL } },
1362 { &hf_dlt_service_new_status, {
1363 "New Status", "dlt.service.new_status",
1364 FT_INT8, BASE_DEC, VALS(dlt_service_new_status), 0x0, NULL, HFILL } },
1365 { &hf_dlt_service_reserved, {
1366 "Reserved", "dlt.service.res",
1367 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1368 { &hf_dlt_service_status, {
1369 "Status", "dlt.service.status",
1370 FT_UINT8, BASE_DEC, VALS(dlt_service_status), 0x0, NULL, HFILL } },
1371 { &hf_dlt_service_length, {
1372 "Length", "dlt.service.length",
1373 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1374 { &hf_dlt_service_swVersion, {
1375 "SW-Version", "dlt.service.sw_version",
1376 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1377 { &hf_dlt_service_status_log_info, {
1378 "Status", "dlt.service.status",
1379 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1380 { &hf_dlt_service_log_levels, {
1381 "Log Levels", "dlt.service.appid_log_levels",
1382 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1383 { &hf_dlt_service_count, {
1384 "Count", "dlt.service.count",
1385 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
1386 { &hf_dlt_service_app_desc, {
1387 "Application Description", "dlt.service.app_description",
1388 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1389 { &hf_dlt_service_ctx_desc, {
1390 "Context Description", "dlt.service.ctx_description",
1391 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
1394 static int *ett[] = {
1395 &ett_dlt,
1396 &ett_dlt_hdr_type,
1397 &ett_dlt_ext_hdr,
1398 &ett_dlt_msg_info,
1399 &ett_dlt_payload,
1400 &ett_dlt_service_app_ids,
1401 &ett_dlt_service_app_id,
1402 &ett_dlt_service_ctx_id,
1405 static ei_register_info ei[] = {
1406 { &ei_dlt_unsupported_datatype, {
1407 "dlt.unsupported_datatype", PI_MALFORMED, PI_ERROR,
1408 "DLT: Unsupported Data Type!", EXPFILL } },
1409 { &ei_dlt_unsupported_length_datatype, {
1410 "dlt.unsupported_length_datatype", PI_MALFORMED, PI_ERROR,
1411 "DLT: Unsupported Length of Datatype!", EXPFILL } },
1412 { &ei_dlt_unsupported_string_coding, {
1413 "dlt.unsupported_string_coding", PI_MALFORMED, PI_ERROR,
1414 "DLT: Unsupported String Coding!", EXPFILL } },
1415 { &ei_dlt_unsupported_non_verbose_msg_type, {
1416 "dlt.unsupported_non_verbose_message_type", PI_MALFORMED, PI_ERROR,
1417 "DLT: Unsupported Non-Verbose Message Type!", EXPFILL } },
1418 { &ei_dlt_buffer_too_short, {
1419 "dlt.buffer_too_short", PI_MALFORMED, PI_ERROR,
1420 "DLT: Buffer too short!", EXPFILL } },
1421 { &ei_dlt_parsing_error, {
1422 "dlt.parsing_error", PI_MALFORMED, PI_ERROR,
1423 "DLT: Parsing Error!", EXPFILL } },
1426 /* Register the protocol name and description */
1427 proto_dlt = proto_register_protocol(PSNAME, PNAME, PFNAME);
1428 dlt_handle_tcp = register_dissector("dlt_tcp", dissect_dlt_tcp, proto_dlt);
1429 dlt_handle_udp = register_dissector("dlt_udp", dissect_dlt_udp, proto_dlt);
1430 dlt_handle_storage = register_dissector("dlt_storage", dissect_dlt_storage_header, proto_dlt_storage_header);
1431 proto_register_subtree_array(ett, array_length(ett));
1432 proto_register_field_array(proto_dlt, hf_dlt, array_length(hf_dlt));
1434 /* Register Expert Info */
1435 expert_module_DLT = expert_register_protocol(proto_dlt);
1436 expert_register_field_array(expert_module_DLT, ei, array_length(ei));
1438 heur_subdissector_list = register_heur_dissector_list_with_description("dlt", "DLT Log Message payload", proto_dlt);
1441 void proto_reg_handoff_dlt(void) {
1442 dissector_add_uint_with_preference("udp.port", 0, dlt_handle_udp);
1443 dissector_add_uint_with_preference("tcp.port", 0, dlt_handle_tcp);
1446 void proto_register_dlt_storage_header(void) {
1447 static hf_register_info hfs[] = {
1448 { &hf_dlt_storage_tstamp_s, {
1449 "Timestamp s", "dlt.storage.timestamp_s",
1450 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1451 { &hf_dlt_storage_tstamp_us, {
1452 "Timestamp us", "dlt.storage.timestamp_us",
1453 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1454 { &hf_dlt_storage_ecu_name, {
1455 "ECU Name", "dlt.storage.ecu_name",
1456 FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1457 { &hf_dlt_storage_reserved, {
1458 "Reserved", "dlt.storage.reserved",
1459 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1463 static int *ett[] = {
1464 &ett_dlt_storage,
1467 /* Register the protocol name and description */
1468 proto_dlt_storage_header = proto_register_protocol(DLT_STORAGE_HEADER_NAME_LONG, DLT_STORAGE_HEADER_NAME, DLT_STORAGE_HEADER_NAME_FILTER);
1469 proto_register_subtree_array(ett, array_length(ett));
1470 proto_register_field_array(proto_dlt, hfs, array_length(hfs));
1473 void proto_reg_handoff_dlt_storage_header(void) {
1474 dissector_add_uint("wtap_encap", WTAP_ENCAP_AUTOSAR_DLT, dlt_handle_storage);
1477 * Editor modelines
1479 * Local Variables:
1480 * c-basic-offset: 4
1481 * tab-width: 8
1482 * indent-tabs-mode: nil
1483 * End:
1485 * ex: set shiftwidth=4 tabstop=8 expandtab:
1486 * :indentSize=4:tabSize=8:noTabs=true: