2 * Routines for LBM PDM Packet dissection
4 * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
15 #include <epan/exceptions.h>
16 #include "packet-lbm.h"
18 /* Magic number for message header to check if data is big-endian or little-endian. */
19 #define PDM_MSG_HDR_BE_MAGIC_BYTE_1 0xA7
20 #define PDM_MSG_HDR_BE_MAGIC_BYTE_2 0x1C
21 #define PDM_MSG_HDR_BE_MAGIC_BYTE_3 0xCA
22 #define PDM_MSG_HDR_BE_MAGIC_BYTE_4 0xFE
23 #define PDM_MSG_HDR_LE_MAGIC_BYTE_1 0xFE
24 #define PDM_MSG_HDR_LE_MAGIC_BYTE_2 0xCA
25 #define PDM_MSG_HDR_LE_MAGIC_BYTE_3 0x1C
26 #define PDM_MSG_HDR_LE_MAGIC_BYTE_4 0xA7
28 void proto_register_lbmpdm(void);
33 typedef struct lbmpdm_msg_hdr_stct_t
38 uint8_t def_major_ver
;
39 uint8_t def_minor_ver
;
43 #define O_LBMPDM_MSG_HDR_T_MAGIC OFFSETOF(lbmpdm_msg_hdr_t, magic)
44 #define L_LBMPDM_MSG_HDR_T_MAGIC SIZEOF(lbmpdm_msg_hdr_t, magic)
45 #define O_LBMPDM_MSG_HDR_T_VER_TYPE OFFSETOF(lbmpdm_msg_hdr_t, ver_type)
46 #define L_LBMPDM_MSG_HDR_T_VER_TYPE SIZEOF(lbmpdm_msg_hdr_t, ver_type)
47 #define O_LBMPDM_MSG_HDR_T_NEXT_HDR OFFSETOF(lbmpdm_msg_hdr_t, next_hdr)
48 #define L_LBMPDM_MSG_HDR_T_NEXT_HDR SIZEOF(lbmpdm_msg_hdr_t, next_hdr)
49 #define O_LBMPDM_MSG_HDR_T_DEF_MAJOR_VER OFFSETOF(lbmpdm_msg_hdr_t, def_major_ver)
50 #define L_LBMPDM_MSG_HDR_T_DEF_MAJOR_VER SIZEOF(lbmpdm_msg_hdr_t, def_major_ver)
51 #define O_LBMPDM_MSG_HDR_T_DEF_MINOR_VER OFFSETOF(lbmpdm_msg_hdr_t, def_minor_ver)
52 #define L_LBMPDM_MSG_HDR_T_DEF_MINOR_VER SIZEOF(lbmpdm_msg_hdr_t, def_minor_ver)
53 #define O_LBMPDM_MSG_HDR_T_DEF_ID OFFSETOF(lbmpdm_msg_hdr_t, def_id)
54 #define L_LBMPDM_MSG_HDR_T_DEF_ID SIZEOF(lbmpdm_msg_hdr_t, def_id)
55 #define O_LBMPDM_MSG_HDR_T_LEN OFFSETOF(lbmpdm_msg_hdr_t, len)
56 #define L_LBMPDM_MSG_HDR_T_LEN SIZEOF(lbmpdm_msg_hdr_t, len)
57 #define L_LBMPDM_MSG_HDR_T (int) sizeof(lbmpdm_msg_hdr_t)
59 /*---------------------*/
60 /* PDM segment header. */
61 /*---------------------*/
62 typedef struct lbmpdm_seg_hdr_stct_t
69 #define O_LBMPDM_SEG_HDR_T_NEXT_HDR OFFSETOF(lbmpdm_seg_hdr_t, next_hdr)
70 #define L_LBMPDM_SEG_HDR_T_NEXT_HDR SIZEOF(lbmpdm_seg_hdr_t, next_hdr)
71 #define O_LBMPDM_SEG_HDR_T_FLAGS OFFSETOF(lbmpdm_seg_hdr_t, flags)
72 #define L_LBMPDM_SEG_HDR_T_FLAGS SIZEOF(lbmpdm_seg_hdr_t, flags)
73 #define O_LBMPDM_SEG_HDR_T_RES OFFSETOF(lbmpdm_seg_hdr_t, res)
74 #define L_LBMPDM_SEG_HDR_T_RES SIZEOF(lbmpdm_seg_hdr_t, res)
75 #define O_LBMPDM_SEG_HDR_T_LEN OFFSETOF(lbmpdm_seg_hdr_t, len)
76 #define L_LBMPDM_SEG_HDR_T_LEN SIZEOF(lbmpdm_seg_hdr_t, len)
77 #define L_LBMPDM_SEG_HDR_T (int) sizeof(lbmpdm_seg_hdr_t)
79 /*--------------------------------*/
80 /* PDM definition segment header. */
81 /*--------------------------------*/
82 typedef struct lbmpdm_defn_stct_t
86 uint8_t field_names_type
;
88 uint8_t msg_vers_major
;
89 uint8_t msg_vers_minor
;
90 uint32_t fixed_req_section_len
;
91 uint32_t field_info_len
;
93 #define O_LBMPDM_DEFN_T_ID OFFSETOF(lbmpdm_defn_t, id)
94 #define L_LBMPDM_DEFN_T_ID SIZEOF(lbmpdm_defn_t, id)
95 #define O_LBMPDM_DEFN_T_NUM_FIELDS OFFSETOF(lbmpdm_defn_t, num_fields)
96 #define L_LBMPDM_DEFN_T_NUM_FIELDS SIZEOF(lbmpdm_defn_t, num_fields)
97 #define O_LBMPDM_DEFN_T_FIELD_NAMES_TYPE OFFSETOF(lbmpdm_defn_t, field_names_type)
98 #define L_LBMPDM_DEFN_T_FIELD_NAMES_TYPE SIZEOF(lbmpdm_defn_t, field_names_type)
99 #define O_LBMPDM_DEFN_T_FINALIZED OFFSETOF(lbmpdm_defn_t, finalized)
100 #define L_LBMPDM_DEFN_T_FINALIZED SIZEOF(lbmpdm_defn_t, finalized)
101 #define O_LBMPDM_DEFN_T_MSG_VERS_MAJOR OFFSETOF(lbmpdm_defn_t, msg_vers_major)
102 #define L_LBMPDM_DEFN_T_MSG_VERS_MAJOR SIZEOF(lbmpdm_defn_t, msg_vers_major)
103 #define O_LBMPDM_DEFN_T_MSG_VERS_MINOR OFFSETOF(lbmpdm_defn_t, msg_vers_minor)
104 #define L_LBMPDM_DEFN_T_MSG_VERS_MINOR SIZEOF(lbmpdm_defn_t, msg_vers_minor)
105 #define O_LBMPDM_DEFN_T_FIXED_REQ_SECTION_LEN OFFSETOF(lbmpdm_defn_t, fixed_req_section_len)
106 #define L_LBMPDM_DEFN_T_FIXED_REQ_SECTION_LEN SIZEOF(lbmpdm_defn_t, fixed_req_section_len)
107 #define O_LBMPDM_DEFN_T_FIELD_INFO_LEN OFFSETOF(lbmpdm_defn_t, field_info_len)
108 #define L_LBMPDM_DEFN_T_FIELD_INFO_LEN SIZEOF(lbmpdm_defn_t, field_info_len)
109 #define L_LBMPDM_DEFN_T (int) sizeof(lbmpdm_defn_t)
111 /*----------------------------*/
112 /* PDM definition field info. */
113 /*----------------------------*/
114 typedef struct lbmpdm_field_info_stct_t
118 uint32_t fixed_str_len
;
119 uint32_t num_arr_elem
;
122 int32_t fld_int_name
;
123 int32_t str_name_len
;
124 /* NUL-terminated field name, if str_name_len != 0 */
125 /* int16_t fld_type */
126 } lbmpdm_field_info_t
;
127 #define O_LBMPDM_FIELD_INFO_T_ID OFFSETOF(lbmpdm_field_info_t, id)
128 #define L_LBMPDM_FIELD_INFO_T_ID SIZEOF(lbmpdm_field_info_t, id)
129 #define O_LBMPDM_FIELD_INFO_T_LEN OFFSETOF(lbmpdm_field_info_t, len)
130 #define L_LBMPDM_FIELD_INFO_T_LEN SIZEOF(lbmpdm_field_info_t, len)
131 #define O_LBMPDM_FIELD_INFO_T_FIXED_STR_LEN OFFSETOF(lbmpdm_field_info_t, fixed_str_len)
132 #define L_LBMPDM_FIELD_INFO_T_FIXED_STR_LEN SIZEOF(lbmpdm_field_info_t, fixed_str_len)
133 #define O_LBMPDM_FIELD_INFO_T_NUM_ARR_ELEM OFFSETOF(lbmpdm_field_info_t, num_arr_elem)
134 #define L_LBMPDM_FIELD_INFO_T_NUM_ARR_ELEM SIZEOF(lbmpdm_field_info_t, num_arr_elem)
135 #define O_LBMPDM_FIELD_INFO_T_REQ OFFSETOF(lbmpdm_field_info_t, req)
136 #define L_LBMPDM_FIELD_INFO_T_REQ SIZEOF(lbmpdm_field_info_t, req)
137 #define O_LBMPDM_FIELD_INFO_T_FIXED OFFSETOF(lbmpdm_field_info_t, fixed)
138 #define L_LBMPDM_FIELD_INFO_T_FIXED SIZEOF(lbmpdm_field_info_t, fixed)
139 #define O_LBMPDM_FIELD_INFO_T_FLD_INT_NAME (O_LBMPDM_FIELD_INFO_T_FIXED + L_LBMPDM_FIELD_INFO_T_FIXED)
140 #define L_LBMPDM_FIELD_INFO_T_FLD_INT_NAME 4
141 #define O_LBMPDM_FIELD_INFO_T_STR_NAME_LEN (O_LBMPDM_FIELD_INFO_T_FLD_INT_NAME + L_LBMPDM_FIELD_INFO_T_FLD_INT_NAME)
142 #define L_LBMPDM_FIELD_INFO_T_STR_NAME_LEN 4
143 #define L_LBMPDM_FIELD_INFO_T (O_LBMPDM_FIELD_INFO_T_STR_NAME_LEN + L_LBMPDM_FIELD_INFO_T_STR_NAME_LEN)
144 #define L_LBMPDM_FIELD_INFO_T_INT_NAME (int) (L_LBMPDM_FIELD_INFO_T + 2)
146 /*---------------------------------*/
147 /* PDM offset table segment entry. */
148 /*---------------------------------*/
153 } lbmpdm_offset_entry_t
;
154 #define O_LBMPDM_OFFSET_ENTRY_T_ID OFFSETOF(lbmpdm_offset_entry_t, id)
155 #define L_LBMPDM_OFFSET_ENTRY_T_ID SIZEOF(lbmpdm_offset_entry_t, id)
156 #define O_LBMPDM_OFFSET_ENTRY_T_OFFSET OFFSETOF(lbmpdm_offset_entry_t, offset)
157 #define L_LBMPDM_OFFSET_ENTRY_T_OFFSET SIZEOF(lbmpdm_offset_entry_t, offset)
158 #define L_LBMPDM_OFFSET_ENTRY_T (int) sizeof(lbmpdm_offset_entry_t)
160 /*-----------------------------------*/
161 /* Header types (value of next_hdr). */
162 /*-----------------------------------*/
163 #define PDM_HDR_TYPE_DATA 0
164 #define PDM_HDR_TYPE_OFSTTBLE 1
165 #define PDM_HDR_TYPE_DEFN 2
166 #define PDM_HDR_TYPE_EOM 0xFF
169 /* PDM protocol version number.
173 /*------------------*/
174 /* PDM field types. */
175 /*------------------*/
176 #define PDM_TYPE_BOOLEAN 0
177 #define PDM_TYPE_INT8 1
178 #define PDM_TYPE_UINT8 2
179 #define PDM_TYPE_INT16 3
180 #define PDM_TYPE_UINT16 4
181 #define PDM_TYPE_INT32 5
182 #define PDM_TYPE_UINT32 6
183 #define PDM_TYPE_INT64 7
184 #define PDM_TYPE_UINT64 8
185 #define PDM_TYPE_FLOAT 9
186 #define PDM_TYPE_DOUBLE 10
187 #define PDM_TYPE_DECIMAL 11
188 #define PDM_TYPE_TIMESTAMP 12
189 #define PDM_TYPE_FIX_STRING 13
190 #define PDM_TYPE_STRING 14
191 #define PDM_TYPE_FIX_UNICODE 15
192 #define PDM_TYPE_UNICODE 16
193 #define PDM_TYPE_BLOB 17
194 #define PDM_TYPE_MESSAGE 18
195 #define PDM_TYPE_BOOLEAN_ARR 19
196 #define PDM_TYPE_INT8_ARR 20
197 #define PDM_TYPE_UINT8_ARR 21
198 #define PDM_TYPE_INT16_ARR 22
199 #define PDM_TYPE_UINT16_ARR 23
200 #define PDM_TYPE_INT32_ARR 24
201 #define PDM_TYPE_UINT32_ARR 25
202 #define PDM_TYPE_INT64_ARR 26
203 #define PDM_TYPE_UINT64_ARR 27
204 #define PDM_TYPE_FLOAT_ARR 28
205 #define PDM_TYPE_DOUBLE_ARR 29
206 #define PDM_TYPE_DECIMAL_ARR 30
207 #define PDM_TYPE_TIMESTAMP_ARR 31
208 #define PDM_TYPE_FIX_STRING_ARR 32
209 #define PDM_TYPE_STRING_ARR 33
210 #define PDM_TYPE_FIX_UNICODE_ARR 34
211 #define PDM_TYPE_UNICODE_ARR 35
212 #define PDM_TYPE_BLOB_ARR 36
213 #define PDM_TYPE_MESSAGE_ARR 37
215 /* Macros for protocol version number and pdm message type.
217 #define PDM_HDR_VER(x) (x >> 4)
218 #define PDM_HDR_TYPE(x) (x & 0xF)
219 #define PDM_HDR_VER_TYPE(v,t) ((v << 4)|(t & 0xF))
220 #define PDM_HDR_VER_TYPE_VER_MASK 0xf0
221 #define PDM_HDR_VER_TYPE_TYPE_MASK 0x0f
223 #define PDM_IGNORE_FLAG 0x80
225 #define PDM_DEFN_STR_FIELD_NAMES 0
226 #define PDM_DEFN_INT_FIELD_NAMES 1
228 #define PDM_DEFN_OPTIONAL_FIELD 0
229 #define PDM_DEFN_REQUIRED_FIELD 1
231 #define PDM_DEFN_VARIABLE_LENGTH_FIELD 0
232 #define PDM_DEFN_FIXED_LENGTH_FIELD 1
237 int32_t * min_set_offset
;
238 int32_t * offset_list
;
239 } lbmpdm_offset_table_t
;
241 struct lbmpdm_definition_field_t_stct
;
242 typedef struct lbmpdm_definition_field_t_stct lbmpdm_definition_field_t
;
244 struct lbmpdm_definition_t_stct
;
245 typedef struct lbmpdm_definition_t_stct lbmpdm_definition_t
;
247 struct lbmpdm_definition_field_t_stct
251 uint32_t fixed_string_len
;
252 uint32_t num_array_elem
;
257 int32_t field_int_name
;
258 uint32_t field_string_name_len
;
259 char * field_string_name
;
260 int fixed_required_offset
;
261 lbmpdm_definition_field_t
* next_fixed_required
;
262 lbmpdm_definition_t
* definition
;
265 struct lbmpdm_definition_t_stct
272 uint8_t field_names_type
;
274 uint32_t fixed_req_section_len
;
275 uint32_t fixed_required_count
;
276 lbmpdm_definition_field_t
* first_fixed_required
;
277 wmem_tree_t
* field_list
;
286 lbmpdm_offset_table_t
* offset_table
;
287 } lbmpdm_msg_definition_id_t
;
289 #define LBMPDM_DEFINITION_KEY_ELEMENT_COUNT 5
290 #define LBMPDM_DEFINITION_KEY_ELEMENT_CHANNEL_HIGH 0
291 #define LBMPDM_DEFINITION_KEY_ELEMENT_CHANNEL_LOW 1
292 #define LBMPDM_DEFINITION_KEY_ELEMENT_ID 2
293 #define LBMPDM_DEFINITION_KEY_ELEMENT_VERS_MAJOR 3
294 #define LBMPDM_DEFINITION_KEY_ELEMENT_VERS_MINOR 4
296 static wmem_tree_t
* lbmpdm_definition_table
;
298 /*----------------------------------------------------------------------------*/
299 /* Handles of all types. */
300 /*----------------------------------------------------------------------------*/
302 /* Protocol handle */
303 static int proto_lbmpdm
;
305 /* Protocol fields */
306 static int hf_lbmpdm_magic
;
307 static int hf_lbmpdm_encoding
;
308 static int hf_lbmpdm_ver
;
309 static int hf_lbmpdm_type
;
310 static int hf_lbmpdm_next_hdr
;
311 static int hf_lbmpdm_def_major_ver
;
312 static int hf_lbmpdm_def_minor_ver
;
313 static int hf_lbmpdm_def_id
;
314 static int hf_lbmpdm_len
;
315 static int hf_lbmpdm_segments
;
316 static int hf_lbmpdm_segment
;
317 static int hf_lbmpdm_segment_next_hdr
;
318 static int hf_lbmpdm_segment_flags
;
319 static int hf_lbmpdm_segment_res
;
320 static int hf_lbmpdm_segment_len
;
321 static int hf_lbmpdm_segment_def_id
;
322 static int hf_lbmpdm_segment_def_num_fields
;
323 static int hf_lbmpdm_segment_def_field_names_type
;
324 static int hf_lbmpdm_segment_def_finalized
;
325 static int hf_lbmpdm_segment_def_msg_vers_major
;
326 static int hf_lbmpdm_segment_def_msg_vers_minor
;
327 static int hf_lbmpdm_segment_def_fixed_req_section_len
;
328 static int hf_lbmpdm_segment_def_field_info_len
;
329 static int hf_lbmpdm_segment_def_field
;
330 static int hf_lbmpdm_segment_def_field_def_len
;
331 static int hf_lbmpdm_segment_def_field_id
;
332 static int hf_lbmpdm_segment_def_field_len
;
333 static int hf_lbmpdm_segment_def_field_fixed_str_len
;
334 static int hf_lbmpdm_segment_def_field_num_arr_elem
;
335 static int hf_lbmpdm_segment_def_field_req
;
336 static int hf_lbmpdm_segment_def_field_fixed
;
337 static int hf_lbmpdm_segment_def_field_fld_int_name
;
338 static int hf_lbmpdm_segment_def_field_str_name_len
;
339 static int hf_lbmpdm_segment_def_field_str_name
;
340 static int hf_lbmpdm_segment_def_field_fld_type
;
341 static int hf_lbmpdm_offset_entry
;
342 static int hf_lbmpdm_offset_entry_id
;
343 static int hf_lbmpdm_offset_entry_offset
;
344 static int hf_lbmpdm_segment_data
;
345 static int hf_lbmpdm_field
;
346 static int hf_lbmpdm_field_id
;
347 static int hf_lbmpdm_field_string_name
;
348 static int hf_lbmpdm_field_int_name
;
349 static int hf_lbmpdm_field_type
;
350 static int hf_lbmpdm_field_total_length
;
351 static int hf_lbmpdm_field_length
;
352 static int hf_lbmpdm_field_value_boolean
;
353 static int hf_lbmpdm_field_value_int8
;
354 static int hf_lbmpdm_field_value_uint8
;
355 static int hf_lbmpdm_field_value_int16
;
356 static int hf_lbmpdm_field_value_uint16
;
357 static int hf_lbmpdm_field_value_int32
;
358 static int hf_lbmpdm_field_value_uint32
;
359 static int hf_lbmpdm_field_value_int64
;
360 static int hf_lbmpdm_field_value_uint64
;
361 static int hf_lbmpdm_field_value_float
;
362 static int hf_lbmpdm_field_value_double
;
363 static int hf_lbmpdm_field_value_decimal
;
364 static int hf_lbmpdm_field_value_timestamp
;
365 static int hf_lbmpdm_field_value_fixed_string
;
366 static int hf_lbmpdm_field_value_string
;
367 static int hf_lbmpdm_field_value_fixed_unicode
;
368 static int hf_lbmpdm_field_value_unicode
;
369 static int hf_lbmpdm_field_value_blob
;
370 static int hf_lbmpdm_field_value_message
;
373 static int ett_lbmpdm
;
374 static int ett_lbmpdm_segments
;
375 static int ett_lbmpdm_segment
;
376 static int ett_lbmpdm_offset_entry
;
377 static int ett_lbmpdm_segment_def_field
;
378 static int ett_lbmpdm_field
;
380 /*----------------------------------------------------------------------------*/
381 /* Value translation tables. */
382 /*----------------------------------------------------------------------------*/
385 static const value_string lbmpdm_field_type
[] =
387 { PDM_TYPE_BOOLEAN
, "Boolean" },
388 { PDM_TYPE_INT8
, "8-bit integer" },
389 { PDM_TYPE_UINT8
, "8-bit unsigned integer" },
390 { PDM_TYPE_INT16
, "16-bit integer" },
391 { PDM_TYPE_UINT16
, "16-bit unsigned integer" },
392 { PDM_TYPE_INT32
, "32-bit integer" },
393 { PDM_TYPE_UINT32
, "32-bit unsigned integer" },
394 { PDM_TYPE_INT64
, "64-bit integer" },
395 { PDM_TYPE_UINT64
, "64-bit unsigned integer" },
396 { PDM_TYPE_FLOAT
, "Float" },
397 { PDM_TYPE_DOUBLE
, "Double" },
398 { PDM_TYPE_DECIMAL
, "Decimal" },
399 { PDM_TYPE_TIMESTAMP
, "Timestamp" },
400 { PDM_TYPE_FIX_STRING
, "Fixed-length string" },
401 { PDM_TYPE_STRING
, "String" },
402 { PDM_TYPE_FIX_UNICODE
, "Fixed-length unicode string" },
403 { PDM_TYPE_UNICODE
, "Unicode string" },
404 { PDM_TYPE_BLOB
, "Binary Large OBject" },
405 { PDM_TYPE_MESSAGE
, "Message" },
406 { PDM_TYPE_BOOLEAN_ARR
, "Array of booleans" },
407 { PDM_TYPE_INT8_ARR
, "Array of 8-bit integers" },
408 { PDM_TYPE_UINT8_ARR
, "Array of 8-bit unsigned integers" },
409 { PDM_TYPE_INT16_ARR
, "Array of 16-bit integers" },
410 { PDM_TYPE_UINT16_ARR
, "Array of 16-bit unsigned integers" },
411 { PDM_TYPE_INT32_ARR
, "Array of 32-bit integers" },
412 { PDM_TYPE_UINT32_ARR
, "Array of 32-bit unsigned integers" },
413 { PDM_TYPE_INT64_ARR
, "Array of 64-bit integers" },
414 { PDM_TYPE_UINT64_ARR
, "Array of 64-bit unsigned integers" },
415 { PDM_TYPE_FLOAT_ARR
, "Array of floats" },
416 { PDM_TYPE_DOUBLE_ARR
, "Array of doubles" },
417 { PDM_TYPE_DECIMAL_ARR
, "Array of decimals" },
418 { PDM_TYPE_TIMESTAMP_ARR
, "Array of timestamps" },
419 { PDM_TYPE_FIX_STRING_ARR
, "Array of fixed-length strings" },
420 { PDM_TYPE_STRING_ARR
, "Array of strings" },
421 { PDM_TYPE_FIX_UNICODE_ARR
, "Array of fixed-length unicode strings" },
422 { PDM_TYPE_UNICODE_ARR
, "Array of unicode strings" },
423 { PDM_TYPE_BLOB_ARR
, "Array of Binary Large OBjects" },
424 { PDM_TYPE_MESSAGE_ARR
, "Array of messages" },
428 static const value_string lbmpdm_next_header
[] =
430 { PDM_HDR_TYPE_DATA
, "Data" },
431 { PDM_HDR_TYPE_OFSTTBLE
, "Offset table" },
432 { PDM_HDR_TYPE_DEFN
, "Definition" },
433 { PDM_HDR_TYPE_EOM
, "End of message" },
437 static const value_string lbmpdm_field_name_type
[] =
439 { PDM_DEFN_STR_FIELD_NAMES
, "String" },
440 { PDM_DEFN_INT_FIELD_NAMES
, "Integer" },
444 static const value_string lbmpdm_field_required
[] =
446 { PDM_DEFN_OPTIONAL_FIELD
, "Field is optional" },
447 { PDM_DEFN_REQUIRED_FIELD
, "Field is required" },
451 static const value_string lbmpdm_field_fixed_length
[] =
453 { PDM_DEFN_VARIABLE_LENGTH_FIELD
, "Field is variable-length" },
454 { PDM_DEFN_FIXED_LENGTH_FIELD
, "Field is fixed-length" },
458 static int lbmpdm_get_segment_length(tvbuff_t
* tvb
, int offset
, int encoding
, int * data_length
)
460 uint32_t datalen
= 0;
463 datalen
= tvb_get_uint32(tvb
, offset
+ O_LBMPDM_SEG_HDR_T_LEN
, encoding
);
464 seglen
= ((int)datalen
) + L_LBMPDM_SEG_HDR_T
;
465 *data_length
= (int) datalen
;
469 static void lbmpdm_definition_build_key(uint32_t * key_value
, wmem_tree_key_t
* key
, uint64_t channel
, uint32_t id
, uint8_t version_major
, uint8_t version_minor
)
471 key_value
[LBMPDM_DEFINITION_KEY_ELEMENT_CHANNEL_HIGH
] = (uint32_t) ((channel
>> 32) & 0xffffffff);
472 key_value
[LBMPDM_DEFINITION_KEY_ELEMENT_CHANNEL_LOW
] = (uint32_t) (channel
& 0xffffffff);
473 key_value
[LBMPDM_DEFINITION_KEY_ELEMENT_ID
] = id
;
474 key_value
[LBMPDM_DEFINITION_KEY_ELEMENT_VERS_MAJOR
] = version_major
;
475 key_value
[LBMPDM_DEFINITION_KEY_ELEMENT_VERS_MINOR
] = version_minor
;
476 key
[0].length
= LBMPDM_DEFINITION_KEY_ELEMENT_COUNT
;
477 key
[0].key
= key_value
;
482 static lbmpdm_definition_t
* lbmpdm_definition_find(uint64_t channel
, uint32_t ID
, uint8_t version_major
, uint8_t version_minor
)
484 lbmpdm_definition_t
* entry
= NULL
;
485 uint32_t keyval
[LBMPDM_DEFINITION_KEY_ELEMENT_COUNT
];
486 wmem_tree_key_t tkey
[2];
488 lbmpdm_definition_build_key(keyval
, tkey
, channel
, ID
, version_major
, version_minor
);
489 entry
= (lbmpdm_definition_t
*) wmem_tree_lookup32_array(lbmpdm_definition_table
, tkey
);
493 static lbmpdm_definition_t
* lbmpdm_definition_add(uint64_t channel
, uint32_t id
, uint8_t version_major
, uint8_t version_minor
)
495 lbmpdm_definition_t
* entry
= NULL
;
496 uint32_t keyval
[LBMPDM_DEFINITION_KEY_ELEMENT_COUNT
];
497 wmem_tree_key_t tkey
[2];
499 entry
= lbmpdm_definition_find(channel
, id
, version_major
, version_minor
);
504 entry
= wmem_new(wmem_file_scope(), lbmpdm_definition_t
);
505 entry
->channel
= channel
;
507 entry
->vers_major
= version_major
;
508 entry
->vers_minor
= version_minor
;
509 entry
->field_list
= wmem_tree_new(wmem_file_scope());
510 lbmpdm_definition_build_key(keyval
, tkey
, channel
, id
, version_major
, version_minor
);
511 wmem_tree_insert32_array(lbmpdm_definition_table
, tkey
, (void *) entry
);
515 static lbmpdm_definition_field_t
* lbmpdm_definition_field_find(lbmpdm_definition_t
* definition
, uint32_t id
)
517 lbmpdm_definition_field_t
* entry
= NULL
;
519 entry
= (lbmpdm_definition_field_t
*) wmem_tree_lookup32(definition
->field_list
, id
);
523 static lbmpdm_definition_field_t
* lbmpdm_definition_field_add(lbmpdm_definition_t
* definition
, uint32_t id
)
525 lbmpdm_definition_field_t
* entry
= NULL
;
527 entry
= lbmpdm_definition_field_find(definition
, id
);
532 entry
= wmem_new0(wmem_file_scope(), lbmpdm_definition_field_t
);
534 entry
->definition
= definition
;
535 wmem_tree_insert32(definition
->field_list
, id
, (void *) entry
);
539 /*----------------------------------------------------------------------------*/
540 /* Dissection functions. */
541 /*----------------------------------------------------------------------------*/
542 static void dissect_field_value(tvbuff_t
* tvb
, int offset
, proto_tree
* tree
, uint16_t field_type
, int field_length
, int encoding
)
546 case PDM_TYPE_BOOLEAN
:
547 proto_tree_add_item(tree
, hf_lbmpdm_field_value_boolean
, tvb
, offset
, field_length
, encoding
);
550 proto_tree_add_item(tree
, hf_lbmpdm_field_value_int8
, tvb
, offset
, field_length
, encoding
);
553 proto_tree_add_item(tree
, hf_lbmpdm_field_value_uint8
, tvb
, offset
, field_length
, encoding
);
556 proto_tree_add_item(tree
, hf_lbmpdm_field_value_int16
, tvb
, offset
, field_length
, encoding
);
558 case PDM_TYPE_UINT16
:
559 proto_tree_add_item(tree
, hf_lbmpdm_field_value_uint16
, tvb
, offset
, field_length
, encoding
);
562 proto_tree_add_item(tree
, hf_lbmpdm_field_value_int32
, tvb
, offset
, field_length
, encoding
);
564 case PDM_TYPE_UINT32
:
565 proto_tree_add_item(tree
, hf_lbmpdm_field_value_uint32
, tvb
, offset
, field_length
, encoding
);
568 proto_tree_add_item(tree
, hf_lbmpdm_field_value_int64
, tvb
, offset
, field_length
, encoding
);
570 case PDM_TYPE_UINT64
:
571 proto_tree_add_item(tree
, hf_lbmpdm_field_value_uint64
, tvb
, offset
, field_length
, encoding
);
574 proto_tree_add_item(tree
, hf_lbmpdm_field_value_float
, tvb
, offset
, field_length
, encoding
);
576 case PDM_TYPE_DOUBLE
:
577 proto_tree_add_item(tree
, hf_lbmpdm_field_value_double
, tvb
, offset
, field_length
, encoding
);
579 case PDM_TYPE_DECIMAL
:
584 uint64_t fraction
= 0;
587 exponent
= tvb_get_int8(tvb
, offset
);
588 mantissa
= tvb_get_int64(tvb
, offset
+ 1, encoding
);
592 shift_count
= exponent
;
593 while (shift_count
> 0)
598 proto_tree_add_none_format(tree
, hf_lbmpdm_field_value_decimal
, tvb
, offset
, field_length
,
599 "DECIMAL Value: %" PRId64
" (%" PRId64
"e%d)", whole
, mantissa
, exponent
);
603 uint64_t divisor
= 1;
604 int decimal_digits
= -exponent
;
605 shift_count
= decimal_digits
;
606 while (shift_count
> 0)
619 fraction
= whole
% divisor
;
625 proto_tree_add_none_format(tree
, hf_lbmpdm_field_value_decimal
, tvb
, offset
, field_length
,
626 "DECIMAL Value: %" PRId64
".%0*" PRIu64
" (%" PRId64
"e%d)",
627 whole
, decimal_digits
, fraction
, mantissa
, exponent
);
631 case PDM_TYPE_TIMESTAMP
:
635 timestamp
.secs
= (time_t)tvb_get_uint32(tvb
, offset
, encoding
);
636 timestamp
.nsecs
= (int)(tvb_get_uint32(tvb
, offset
+ 4, encoding
) * 1000);
637 proto_tree_add_time(tree
, hf_lbmpdm_field_value_timestamp
, tvb
, offset
, field_length
, ×tamp
);
640 case PDM_TYPE_FIX_STRING
:
641 proto_tree_add_item(tree
, hf_lbmpdm_field_value_fixed_string
, tvb
, offset
, field_length
, encoding
);
643 case PDM_TYPE_STRING
:
644 proto_tree_add_item(tree
, hf_lbmpdm_field_value_string
, tvb
, offset
, field_length
, encoding
);
646 case PDM_TYPE_FIX_UNICODE
:
647 proto_tree_add_item(tree
, hf_lbmpdm_field_value_fixed_unicode
, tvb
, offset
, field_length
, encoding
);
649 case PDM_TYPE_UNICODE
:
650 proto_tree_add_item(tree
, hf_lbmpdm_field_value_unicode
, tvb
, offset
, field_length
, encoding
);
653 proto_tree_add_item(tree
, hf_lbmpdm_field_value_blob
, tvb
, offset
, field_length
, encoding
);
655 case PDM_TYPE_MESSAGE
:
656 proto_tree_add_item(tree
, hf_lbmpdm_field_value_message
, tvb
, offset
, field_length
, encoding
);
663 static int dissect_field(tvbuff_t
* tvb
, int offset
, proto_tree
* tree
, lbmpdm_definition_field_t
* field
, bool string_field_names
, int encoding
)
665 proto_item
* field_item
= NULL
;
666 proto_tree
* field_tree
= NULL
;
667 proto_item
* ti
= NULL
;
669 uint32_t element_count
= 0;
671 int len_dissected
= 0;
673 field_item
= proto_tree_add_item(tree
, hf_lbmpdm_field
, tvb
, offset
, field
->len
, ENC_NA
);
674 field_tree
= proto_item_add_subtree(field_item
, ett_lbmpdm_field
);
675 ti
= proto_tree_add_uint(field_tree
, hf_lbmpdm_field_id
, tvb
, 0, 0, field
->id
);
676 proto_item_set_generated(ti
);
677 if (string_field_names
)
679 ti
= proto_tree_add_string(field_tree
, hf_lbmpdm_field_string_name
, tvb
, 0, 0, field
->field_string_name
);
683 ti
= proto_tree_add_uint(field_tree
, hf_lbmpdm_field_int_name
, tvb
, 0, 0, field
->field_int_name
);
685 proto_item_set_generated(ti
);
686 ti
= proto_tree_add_uint(field_tree
, hf_lbmpdm_field_type
, tvb
, 0, 0, field
->field_type
);
687 proto_item_set_generated(ti
);
688 if (field
->num_array_elem
== 0)
694 element_count
= field
->num_array_elem
;
695 if (field
->fixed
== PDM_DEFN_VARIABLE_LENGTH_FIELD
)
697 proto_tree_add_item(field_tree
, hf_lbmpdm_field_total_length
, tvb
, ofs
, 4, encoding
);
702 for (idx
= 0; idx
< element_count
; ++idx
)
704 /* field_len is length of the entire entry, including any length prefix. */
705 uint32_t field_len
= field
->len
/ element_count
;
706 /* value_len is the length of the data only. */
707 uint32_t value_len
= field_len
;
708 /* value_offset is the offset of the actual value. */
709 int value_offset
= ofs
;
711 if (field
->fixed
== PDM_DEFN_VARIABLE_LENGTH_FIELD
)
713 proto_tree_add_item(field_tree
, hf_lbmpdm_field_length
, tvb
, ofs
, 4, encoding
);
714 value_len
= tvb_get_uint32(tvb
, ofs
, encoding
);
715 field_len
= value_len
+ 4;
718 else if (field
->fixed_string_len
> 0)
720 value_len
= field
->fixed_string_len
;
722 dissect_field_value(tvb
, value_offset
, field_tree
, field
->base_type
, value_len
, encoding
);
723 ofs
+= (int)field_len
;
724 len_dissected
+= (int)field_len
;
726 return (len_dissected
);
729 static int dissect_segment_data(tvbuff_t
* tvb
, int offset
, packet_info
* pinfo _U_
, proto_tree
* tree
, lbmpdm_msg_definition_id_t
* id
, int encoding
)
731 proto_item
* subtree_item
= NULL
;
732 proto_tree
* subtree
= NULL
;
735 lbmpdm_definition_t
* def
= NULL
;
737 seglen
= lbmpdm_get_segment_length(tvb
, offset
, encoding
, &datalen
);
738 subtree_item
= proto_tree_add_none_format(tree
, hf_lbmpdm_segment
, tvb
, offset
, seglen
, "Data Segment");
739 subtree
= proto_item_add_subtree(subtree_item
, ett_lbmpdm_segment
);
740 proto_tree_add_item(subtree
, hf_lbmpdm_segment_next_hdr
, tvb
, offset
+ O_LBMPDM_SEG_HDR_T_NEXT_HDR
, L_LBMPDM_SEG_HDR_T_NEXT_HDR
, encoding
);
741 proto_tree_add_item(subtree
, hf_lbmpdm_segment_flags
, tvb
, offset
+ O_LBMPDM_SEG_HDR_T_FLAGS
, L_LBMPDM_SEG_HDR_T_FLAGS
, encoding
);
742 proto_tree_add_item(subtree
, hf_lbmpdm_segment_res
, tvb
, offset
+ O_LBMPDM_SEG_HDR_T_RES
, L_LBMPDM_SEG_HDR_T_RES
, encoding
);
743 proto_tree_add_item(subtree
, hf_lbmpdm_segment_len
, tvb
, offset
+ O_LBMPDM_SEG_HDR_T_LEN
, L_LBMPDM_SEG_HDR_T_LEN
, encoding
);
744 if ((id
!= NULL
) && (id
->offset_table
!= NULL
))
746 def
= lbmpdm_definition_find(id
->channel
, id
->msg_def_id
, id
->ver_major
, id
->ver_minor
);
750 proto_tree_add_item(subtree
, hf_lbmpdm_segment_data
, tvb
, offset
+ L_LBMPDM_SEG_HDR_T
, datalen
, ENC_NA
);
754 int fld_offset
= offset
+ L_LBMPDM_SEG_HDR_T
;
755 lbmpdm_definition_field_t
* field
= NULL
;
756 bool string_field_names
= false;
759 if (def
->field_names_type
== PDM_DEFN_STR_FIELD_NAMES
)
761 string_field_names
= true;
765 string_field_names
= false;
768 /* Handle any fixed required fields first. */
769 for (field
= def
->first_fixed_required
; field
!= NULL
; field
= field
->next_fixed_required
)
771 fld_offset
+= dissect_field(tvb
, fld_offset
, subtree
, field
, string_field_names
, encoding
);
773 /* Step through the offset table. */
774 for (idx
= 0; idx
< id
->offset_table
->num_flds
; ++idx
)
776 int32_t ofs
= id
->offset_table
->offset_list
[idx
];
779 field
= lbmpdm_definition_field_find(def
, idx
);
782 (void)dissect_field(tvb
, offset
+ L_LBMPDM_SEG_HDR_T
+ ofs
, subtree
, field
, string_field_names
, encoding
);
790 static int dissect_segment_ofstable(tvbuff_t
* tvb
, int offset
, packet_info
* pinfo _U_
, proto_tree
* tree
, lbmpdm_offset_table_t
* * offset_table
, int encoding
)
792 proto_item
* subtree_item
= NULL
;
793 proto_tree
* subtree
= NULL
;
799 int32_t * id_list
= NULL
;
800 int32_t * ofs_list
= NULL
;
801 int32_t max_index
= -1;
802 int32_t min_offset
= INT32_MAX
;
803 lbmpdm_offset_table_t
* ofs_table
= NULL
;
805 seglen
= lbmpdm_get_segment_length(tvb
, offset
, encoding
, &datalen
);
806 subtree_item
= proto_tree_add_none_format(tree
, hf_lbmpdm_segment
, tvb
, offset
, seglen
, "Offset Table Segment");
807 subtree
= proto_item_add_subtree(subtree_item
, ett_lbmpdm_segment
);
808 proto_tree_add_item(subtree
, hf_lbmpdm_segment_next_hdr
, tvb
, offset
+ O_LBMPDM_SEG_HDR_T_NEXT_HDR
, L_LBMPDM_SEG_HDR_T_NEXT_HDR
, encoding
);
809 proto_tree_add_item(subtree
, hf_lbmpdm_segment_flags
, tvb
, offset
+ O_LBMPDM_SEG_HDR_T_FLAGS
, L_LBMPDM_SEG_HDR_T_FLAGS
, encoding
);
810 proto_tree_add_item(subtree
, hf_lbmpdm_segment_res
, tvb
, offset
+ O_LBMPDM_SEG_HDR_T_RES
, L_LBMPDM_SEG_HDR_T_RES
, encoding
);
811 proto_tree_add_item(subtree
, hf_lbmpdm_segment_len
, tvb
, offset
+ O_LBMPDM_SEG_HDR_T_LEN
, L_LBMPDM_SEG_HDR_T_LEN
, encoding
);
812 field_count
= datalen
/ L_LBMPDM_OFFSET_ENTRY_T
;
813 id_list
= wmem_alloc_array(pinfo
->pool
, int32_t, field_count
);
814 ofs_list
= wmem_alloc_array(pinfo
->pool
, int32_t, field_count
);
815 for (idx
= 0; idx
< field_count
; ++idx
)
820 ofs
= offset
+ L_LBMPDM_SEG_HDR_T
;
821 for (idx
= 0; idx
< field_count
; idx
++, ofs
+= L_LBMPDM_OFFSET_ENTRY_T
)
823 proto_item
* offset_item
= NULL
;
824 proto_tree
* offset_tree
= NULL
;
826 offset_item
= proto_tree_add_item(subtree
, hf_lbmpdm_offset_entry
, tvb
, ofs
, L_LBMPDM_OFFSET_ENTRY_T
, ENC_NA
);
827 offset_tree
= proto_item_add_subtree(offset_item
, ett_lbmpdm_offset_entry
);
828 proto_tree_add_item(offset_tree
, hf_lbmpdm_offset_entry_id
, tvb
, ofs
+ O_LBMPDM_OFFSET_ENTRY_T_ID
, L_LBMPDM_OFFSET_ENTRY_T_ID
, encoding
);
829 id_list
[idx
] = (int32_t)tvb_get_uint32(tvb
, ofs
+ O_LBMPDM_OFFSET_ENTRY_T_ID
, encoding
);
830 proto_tree_add_item(offset_tree
, hf_lbmpdm_offset_entry_offset
, tvb
, ofs
+ O_LBMPDM_OFFSET_ENTRY_T_OFFSET
, L_LBMPDM_OFFSET_ENTRY_T_OFFSET
, encoding
);
831 ofs_list
[idx
] = (int32_t)tvb_get_uint32(tvb
, ofs
+ O_LBMPDM_OFFSET_ENTRY_T_OFFSET
, encoding
);
832 if (id_list
[idx
] < 0 || ofs_list
[idx
] < 0) {
833 THROW(ReportedBoundsError
);
835 if (id_list
[idx
] > max_index
)
837 max_index
= id_list
[idx
];
839 if (ofs_list
[idx
] < min_offset
)
841 min_offset
= ofs_list
[idx
];
844 ofs_table
= wmem_new(pinfo
->pool
, lbmpdm_offset_table_t
);
845 ofs_table
->num_flds
= max_index
+ 1;
846 ofs_table
->min_set_offset
= NULL
;
847 ofs_table
->offset_list
= wmem_alloc_array(pinfo
->pool
, int32_t, ofs_table
->num_flds
);
848 for (idx
= 0; idx
< (int)ofs_table
->num_flds
; ++idx
)
850 ofs_table
->offset_list
[idx
] = -1;
852 for (idx
= 0; idx
< field_count
; ++idx
)
854 ofs_table
->offset_list
[id_list
[idx
]] = ofs_list
[idx
];
855 if (ofs_list
[idx
] == min_offset
)
857 ofs_table
->min_set_offset
= &(ofs_table
->offset_list
[id_list
[idx
]]);
860 if (offset_table
!= NULL
)
862 *offset_table
= ofs_table
;
867 static int dissect_segment_defn(tvbuff_t
* tvb
, int offset
, packet_info
* pinfo
, proto_tree
* tree
, uint64_t channel
, int encoding
)
869 proto_item
* subtree_item
= NULL
;
870 proto_tree
* subtree
= NULL
;
873 bool string_field_name
= false;
874 int remaining_datalen
= 0;
875 uint32_t num_fields
= 0;
876 lbmpdm_definition_t
* def
= NULL
;
877 bool add_definition
= false;
879 uint8_t vers_major
= 0;
880 uint8_t vers_minor
= 0;
881 lbmpdm_definition_field_t
* last_fixed_required_field
= NULL
;
883 seglen
= lbmpdm_get_segment_length(tvb
, offset
, encoding
, &remaining_datalen
);
884 if (pinfo
->fd
->visited
== 0)
886 add_definition
= true;
888 subtree_item
= proto_tree_add_none_format(tree
, hf_lbmpdm_segment
, tvb
, offset
, seglen
, "Definition Segment");
889 subtree
= proto_item_add_subtree(subtree_item
, ett_lbmpdm_segment
);
890 proto_tree_add_item(subtree
, hf_lbmpdm_segment_next_hdr
, tvb
, offset
+ O_LBMPDM_SEG_HDR_T_NEXT_HDR
, L_LBMPDM_SEG_HDR_T_NEXT_HDR
, encoding
);
891 proto_tree_add_item(subtree
, hf_lbmpdm_segment_flags
, tvb
, offset
+ O_LBMPDM_SEG_HDR_T_FLAGS
, L_LBMPDM_SEG_HDR_T_FLAGS
, encoding
);
892 proto_tree_add_item(subtree
, hf_lbmpdm_segment_res
, tvb
, offset
+ O_LBMPDM_SEG_HDR_T_RES
, L_LBMPDM_SEG_HDR_T_RES
, encoding
);
893 proto_tree_add_item(subtree
, hf_lbmpdm_segment_len
, tvb
, offset
+ O_LBMPDM_SEG_HDR_T_LEN
, L_LBMPDM_SEG_HDR_T_LEN
, encoding
);
894 ofs
= offset
+ L_LBMPDM_SEG_HDR_T
;
895 proto_tree_add_item(subtree
, hf_lbmpdm_segment_def_id
, tvb
, ofs
+ O_LBMPDM_DEFN_T_ID
, L_LBMPDM_DEFN_T_ID
, encoding
);
896 def_id
= tvb_get_uint32(tvb
, ofs
+ O_LBMPDM_DEFN_T_ID
, encoding
);
897 proto_tree_add_item(subtree
, hf_lbmpdm_segment_def_num_fields
, tvb
, ofs
+ O_LBMPDM_DEFN_T_NUM_FIELDS
, L_LBMPDM_DEFN_T_NUM_FIELDS
, encoding
);
898 proto_tree_add_item(subtree
, hf_lbmpdm_segment_def_field_names_type
, tvb
, ofs
+ O_LBMPDM_DEFN_T_FIELD_NAMES_TYPE
, L_LBMPDM_DEFN_T_FIELD_NAMES_TYPE
, encoding
);
899 proto_tree_add_item(subtree
, hf_lbmpdm_segment_def_finalized
, tvb
, ofs
+ O_LBMPDM_DEFN_T_FINALIZED
, L_LBMPDM_DEFN_T_FINALIZED
, encoding
);
900 proto_tree_add_item(subtree
, hf_lbmpdm_segment_def_msg_vers_major
, tvb
, ofs
+ O_LBMPDM_DEFN_T_MSG_VERS_MAJOR
, L_LBMPDM_DEFN_T_MSG_VERS_MAJOR
, encoding
);
901 vers_major
= tvb_get_uint8(tvb
, ofs
+ O_LBMPDM_DEFN_T_MSG_VERS_MAJOR
);
902 proto_tree_add_item(subtree
, hf_lbmpdm_segment_def_msg_vers_minor
, tvb
, ofs
+ O_LBMPDM_DEFN_T_MSG_VERS_MINOR
, L_LBMPDM_DEFN_T_MSG_VERS_MINOR
, encoding
);
903 vers_minor
= tvb_get_uint8(tvb
, ofs
+ O_LBMPDM_DEFN_T_MSG_VERS_MINOR
);
904 proto_tree_add_item(subtree
, hf_lbmpdm_segment_def_fixed_req_section_len
, tvb
, ofs
+ O_LBMPDM_DEFN_T_FIXED_REQ_SECTION_LEN
, L_LBMPDM_DEFN_T_FIXED_REQ_SECTION_LEN
, encoding
);
905 proto_tree_add_item(subtree
, hf_lbmpdm_segment_def_field_info_len
, tvb
, ofs
+ O_LBMPDM_DEFN_T_FIELD_INFO_LEN
, L_LBMPDM_DEFN_T_FIELD_INFO_LEN
, encoding
);
906 if (tvb_get_uint8(tvb
, ofs
+ O_LBMPDM_DEFN_T_FIELD_NAMES_TYPE
) == PDM_DEFN_STR_FIELD_NAMES
)
908 string_field_name
= true;
910 num_fields
= tvb_get_uint32(tvb
, ofs
+ O_LBMPDM_DEFN_T_NUM_FIELDS
, encoding
);
913 def
= lbmpdm_definition_find(channel
, def_id
, vers_major
, vers_minor
);
916 def
= lbmpdm_definition_add(channel
, def_id
, vers_major
, vers_minor
);
917 def
->num_fields
= num_fields
;
918 def
->field_names_type
= tvb_get_uint8(tvb
, ofs
+ O_LBMPDM_DEFN_T_FIELD_NAMES_TYPE
);
919 def
->fixed_req_section_len
= tvb_get_uint32(tvb
, ofs
+ O_LBMPDM_DEFN_T_FIXED_REQ_SECTION_LEN
, encoding
);
920 def
->first_fixed_required
= NULL
;
921 def
->fixed_required_count
= 0;
924 ofs
+= L_LBMPDM_DEFN_T
;
925 remaining_datalen
= seglen
- L_LBMPDM_SEG_HDR_T
- L_LBMPDM_DEFN_T
;
926 while ((remaining_datalen
> 0) && (num_fields
> 0))
928 proto_item
* field_item
= NULL
;
929 proto_tree
* field_tree
= NULL
;
930 uint32_t def_len
= L_LBMPDM_FIELD_INFO_T_INT_NAME
;
932 int type_ofs
= L_LBMPDM_FIELD_INFO_T
;
933 uint32_t string_name_len
= 0;
934 int string_name_ofs
= -1;
936 if (string_field_name
)
938 def_len
= tvb_get_uint32(tvb
, ofs
, encoding
) + 4;
940 field_item
= proto_tree_add_item(subtree
, hf_lbmpdm_segment_def_field
, tvb
, ofs
, def_len
, ENC_NA
);
941 field_tree
= proto_item_add_subtree(field_item
, ett_lbmpdm_segment_def_field
);
942 if (string_field_name
)
944 proto_tree_add_item(field_tree
, hf_lbmpdm_segment_def_field_def_len
, tvb
, ofs
, 4, encoding
);
948 proto_tree_add_item(field_tree
, hf_lbmpdm_segment_def_field_id
, tvb
, ofs
+ def_ofs
+ O_LBMPDM_FIELD_INFO_T_ID
, L_LBMPDM_FIELD_INFO_T_ID
, encoding
);
949 proto_tree_add_item(field_tree
, hf_lbmpdm_segment_def_field_len
, tvb
, ofs
+ def_ofs
+ O_LBMPDM_FIELD_INFO_T_LEN
, L_LBMPDM_FIELD_INFO_T_LEN
, encoding
);
950 proto_tree_add_item(field_tree
, hf_lbmpdm_segment_def_field_fixed_str_len
, tvb
, ofs
+ def_ofs
+ O_LBMPDM_FIELD_INFO_T_FIXED_STR_LEN
, L_LBMPDM_FIELD_INFO_T_FIXED_STR_LEN
, encoding
);
951 proto_tree_add_item(field_tree
, hf_lbmpdm_segment_def_field_num_arr_elem
, tvb
, ofs
+ def_ofs
+ O_LBMPDM_FIELD_INFO_T_NUM_ARR_ELEM
, L_LBMPDM_FIELD_INFO_T_NUM_ARR_ELEM
, encoding
);
952 proto_tree_add_item(field_tree
, hf_lbmpdm_segment_def_field_req
, tvb
, ofs
+ def_ofs
+ O_LBMPDM_FIELD_INFO_T_REQ
, L_LBMPDM_FIELD_INFO_T_REQ
, encoding
);
953 proto_tree_add_item(field_tree
, hf_lbmpdm_segment_def_field_fixed
, tvb
, ofs
+ def_ofs
+ O_LBMPDM_FIELD_INFO_T_FIXED
, L_LBMPDM_FIELD_INFO_T_FIXED
, encoding
);
954 proto_tree_add_item(field_tree
, hf_lbmpdm_segment_def_field_fld_int_name
, tvb
, ofs
+ def_ofs
+ O_LBMPDM_FIELD_INFO_T_FLD_INT_NAME
, L_LBMPDM_FIELD_INFO_T_FLD_INT_NAME
, encoding
);
955 proto_tree_add_item(field_tree
, hf_lbmpdm_segment_def_field_str_name_len
, tvb
, ofs
+ def_ofs
+ O_LBMPDM_FIELD_INFO_T_STR_NAME_LEN
, L_LBMPDM_FIELD_INFO_T_STR_NAME_LEN
, encoding
);
956 if (string_field_name
)
958 string_name_len
= tvb_get_uint32(tvb
, ofs
+ def_ofs
+ O_LBMPDM_FIELD_INFO_T_STR_NAME_LEN
, encoding
);
959 if (string_name_len
> 0)
961 string_name_ofs
= ofs
+ def_ofs
+ L_LBMPDM_FIELD_INFO_T
;
962 proto_tree_add_item(field_tree
, hf_lbmpdm_segment_def_field_str_name
, tvb
, string_name_ofs
, (int)string_name_len
, ENC_ASCII
);
963 type_ofs
+= string_name_len
;
966 proto_tree_add_item(field_tree
, hf_lbmpdm_segment_def_field_fld_type
, tvb
, ofs
+ type_ofs
, 2, encoding
);
967 if (add_definition
&& (def
!= NULL
))
969 lbmpdm_definition_field_t
* field
= NULL
;
972 field_id
= tvb_get_uint32(tvb
, ofs
+ def_ofs
+ O_LBMPDM_FIELD_INFO_T_ID
, encoding
);
973 field
= lbmpdm_definition_field_find(def
, field_id
);
976 field
= lbmpdm_definition_field_add(def
, field_id
);
979 field
->len
= tvb_get_uint32(tvb
, ofs
+ def_ofs
+ O_LBMPDM_FIELD_INFO_T_LEN
, encoding
);
980 field
->fixed_string_len
= tvb_get_uint32(tvb
, ofs
+ def_ofs
+ O_LBMPDM_FIELD_INFO_T_FIXED_STR_LEN
, encoding
);
981 field
->num_array_elem
= tvb_get_uint32(tvb
, ofs
+ def_ofs
+ O_LBMPDM_FIELD_INFO_T_NUM_ARR_ELEM
, encoding
);
982 field
->required
= tvb_get_uint8(tvb
, ofs
+ def_ofs
+ O_LBMPDM_FIELD_INFO_T_REQ
);
983 field
->fixed
= tvb_get_uint8(tvb
, ofs
+ def_ofs
+ O_LBMPDM_FIELD_INFO_T_FIXED
);
984 field
->field_int_name
= tvb_get_uint32(tvb
, ofs
+ def_ofs
+ O_LBMPDM_FIELD_INFO_T_FLD_INT_NAME
, encoding
);
985 if (string_field_name
&& (string_name_len
> 0))
987 field
->field_string_name_len
= string_name_len
;
988 field
->field_string_name
= tvb_get_string_enc(wmem_file_scope(), tvb
, string_name_ofs
, string_name_len
, ENC_ASCII
);
992 field
->field_string_name_len
= 0;
993 field
->field_string_name
= NULL
;
995 field
->field_type
= tvb_get_uint16(tvb
, ofs
+ type_ofs
, encoding
);
996 switch (field
->field_type
)
998 case PDM_TYPE_BOOLEAN
:
999 case PDM_TYPE_BOOLEAN_ARR
:
1000 field
->base_type
= PDM_TYPE_BOOLEAN
;
1003 case PDM_TYPE_INT8_ARR
:
1004 field
->base_type
= PDM_TYPE_INT8
;
1006 case PDM_TYPE_UINT8
:
1007 case PDM_TYPE_UINT8_ARR
:
1008 field
->base_type
= PDM_TYPE_UINT8
;
1010 case PDM_TYPE_INT16
:
1011 case PDM_TYPE_INT16_ARR
:
1012 field
->base_type
= PDM_TYPE_INT16
;
1014 case PDM_TYPE_UINT16
:
1015 case PDM_TYPE_UINT16_ARR
:
1016 field
->base_type
= PDM_TYPE_UINT16
;
1018 case PDM_TYPE_INT32
:
1019 case PDM_TYPE_INT32_ARR
:
1020 field
->base_type
= PDM_TYPE_INT32
;
1022 case PDM_TYPE_UINT32
:
1023 case PDM_TYPE_UINT32_ARR
:
1024 field
->base_type
= PDM_TYPE_UINT32
;
1026 case PDM_TYPE_INT64
:
1027 case PDM_TYPE_INT64_ARR
:
1028 field
->base_type
= PDM_TYPE_INT64
;
1030 case PDM_TYPE_UINT64
:
1031 case PDM_TYPE_UINT64_ARR
:
1032 field
->base_type
= PDM_TYPE_UINT64
;
1034 case PDM_TYPE_FLOAT
:
1035 case PDM_TYPE_FLOAT_ARR
:
1036 field
->base_type
= PDM_TYPE_FLOAT
;
1038 case PDM_TYPE_DOUBLE
:
1039 case PDM_TYPE_DOUBLE_ARR
:
1040 field
->base_type
= PDM_TYPE_DOUBLE
;
1042 case PDM_TYPE_DECIMAL
:
1043 case PDM_TYPE_DECIMAL_ARR
:
1044 field
->base_type
= PDM_TYPE_DECIMAL
;
1046 case PDM_TYPE_TIMESTAMP
:
1047 case PDM_TYPE_TIMESTAMP_ARR
:
1048 field
->base_type
= PDM_TYPE_TIMESTAMP
;
1050 case PDM_TYPE_FIX_STRING
:
1051 case PDM_TYPE_FIX_STRING_ARR
:
1052 field
->base_type
= PDM_TYPE_FIX_STRING
;
1054 case PDM_TYPE_STRING
:
1055 case PDM_TYPE_STRING_ARR
:
1056 field
->base_type
= PDM_TYPE_STRING
;
1058 case PDM_TYPE_FIX_UNICODE
:
1059 case PDM_TYPE_FIX_UNICODE_ARR
:
1060 field
->base_type
= PDM_TYPE_FIX_UNICODE
;
1062 case PDM_TYPE_UNICODE
:
1063 case PDM_TYPE_UNICODE_ARR
:
1064 field
->base_type
= PDM_TYPE_UNICODE
;
1067 case PDM_TYPE_BLOB_ARR
:
1069 field
->base_type
= PDM_TYPE_BLOB
;
1071 case PDM_TYPE_MESSAGE
:
1072 case PDM_TYPE_MESSAGE_ARR
:
1073 field
->base_type
= PDM_TYPE_MESSAGE
;
1076 if ((field
->fixed
== PDM_DEFN_FIXED_LENGTH_FIELD
) && (field
->required
== PDM_DEFN_REQUIRED_FIELD
))
1078 if (last_fixed_required_field
== NULL
)
1080 def
->first_fixed_required
= field
;
1081 field
->fixed_required_offset
= 0;
1085 last_fixed_required_field
->next_fixed_required
= field
;
1086 field
->fixed_required_offset
= last_fixed_required_field
->fixed_required_offset
+ last_fixed_required_field
->len
;
1088 last_fixed_required_field
= field
;
1089 def
->fixed_required_count
++;
1095 remaining_datalen
-= def_len
;
1101 static int dissect_segment_unknown(tvbuff_t
* tvb
, int offset
, packet_info
* pinfo _U_
, proto_tree
* tree
, int encoding
)
1103 proto_item
* subtree_item
= NULL
;
1104 proto_tree
* subtree
= NULL
;
1108 seglen
= lbmpdm_get_segment_length(tvb
, offset
, encoding
, &datalen
);
1109 subtree_item
= proto_tree_add_none_format(tree
, hf_lbmpdm_segment
, tvb
, offset
, seglen
, "Unknown Segment");
1110 subtree
= proto_item_add_subtree(subtree_item
, ett_lbmpdm_segment
);
1111 proto_tree_add_item(subtree
, hf_lbmpdm_segment_next_hdr
, tvb
, offset
+ O_LBMPDM_SEG_HDR_T_NEXT_HDR
, L_LBMPDM_SEG_HDR_T_NEXT_HDR
, encoding
);
1112 proto_tree_add_item(subtree
, hf_lbmpdm_segment_flags
, tvb
, offset
+ O_LBMPDM_SEG_HDR_T_FLAGS
, L_LBMPDM_SEG_HDR_T_FLAGS
, encoding
);
1113 proto_tree_add_item(subtree
, hf_lbmpdm_segment_res
, tvb
, offset
+ O_LBMPDM_SEG_HDR_T_RES
, L_LBMPDM_SEG_HDR_T_RES
, encoding
);
1114 proto_tree_add_item(subtree
, hf_lbmpdm_segment_len
, tvb
, offset
+ O_LBMPDM_SEG_HDR_T_LEN
, L_LBMPDM_SEG_HDR_T_LEN
, encoding
);
1115 proto_tree_add_item(subtree
, hf_lbmpdm_segment_data
, tvb
, offset
+ L_LBMPDM_SEG_HDR_T
, datalen
, ENC_NA
);
1119 static bool check_lbmpdm_encoding(tvbuff_t
* tvb
, int offset
, int * encoding
)
1121 uint8_t magic_byte_1
;
1122 uint8_t magic_byte_2
;
1123 uint8_t magic_byte_3
;
1124 uint8_t magic_byte_4
;
1127 magic_byte_1
= tvb_get_uint8(tvb
, offset
);
1128 magic_byte_2
= tvb_get_uint8(tvb
, offset
+ 1);
1129 magic_byte_3
= tvb_get_uint8(tvb
, offset
+ 2);
1130 magic_byte_4
= tvb_get_uint8(tvb
, offset
+ 3);
1131 if ((magic_byte_1
== PDM_MSG_HDR_BE_MAGIC_BYTE_1
) && (magic_byte_2
== PDM_MSG_HDR_BE_MAGIC_BYTE_2
)
1132 && (magic_byte_3
== PDM_MSG_HDR_BE_MAGIC_BYTE_3
) && (magic_byte_4
== PDM_MSG_HDR_BE_MAGIC_BYTE_4
))
1134 *encoding
= ENC_BIG_ENDIAN
;
1136 else if ((magic_byte_1
== PDM_MSG_HDR_LE_MAGIC_BYTE_1
) && (magic_byte_2
== PDM_MSG_HDR_LE_MAGIC_BYTE_2
)
1137 && (magic_byte_3
== PDM_MSG_HDR_LE_MAGIC_BYTE_3
) && (magic_byte_4
== PDM_MSG_HDR_LE_MAGIC_BYTE_4
))
1139 *encoding
= ENC_LITTLE_ENDIAN
;
1148 bool lbmpdm_verify_payload(tvbuff_t
* tvb
, int offset
, int * encoding
, int * length
)
1150 uint8_t next_header
;
1153 if (!tvb_bytes_exist(tvb
, offset
, L_LBMPDM_MSG_HDR_T
))
1157 if (!check_lbmpdm_encoding(tvb
, offset
, encoding
))
1161 next_header
= tvb_get_uint8(tvb
, offset
+ O_LBMPDM_MSG_HDR_T_NEXT_HDR
);
1162 switch (next_header
)
1164 case PDM_HDR_TYPE_DATA
:
1165 case PDM_HDR_TYPE_OFSTTBLE
:
1166 case PDM_HDR_TYPE_DEFN
:
1167 case PDM_HDR_TYPE_EOM
:
1172 len
= tvb_get_uint32(tvb
, offset
+ O_LBMPDM_MSG_HDR_T_LEN
, *encoding
);
1181 int lbmpdm_dissect_lbmpdm_payload(tvbuff_t
* tvb
, int offset
, packet_info
* pinfo
, proto_tree
* tree
, uint64_t channel
)
1183 proto_item
* subtree_item
= NULL
;
1184 proto_tree
* subtree
= NULL
;
1185 proto_item
* segments_item
= NULL
;
1186 proto_tree
* segments_tree
= NULL
;
1187 proto_item
* pi
= NULL
;
1189 int dissected_len
= 0;
1192 int len_remaining
= 0;
1194 int segment_len
= 0;
1196 uint32_t raw_msglen
= 0;
1197 lbmpdm_msg_definition_id_t msgid
;
1199 if (!lbmpdm_verify_payload(tvb
, offset
, &encoding
, &raw_msglen
))
1203 msglen
= (int)raw_msglen
;
1205 msgid
.channel
= channel
;
1206 msgid
.offset_table
= NULL
;
1207 subtree_item
= proto_tree_add_protocol_format(tree
, proto_lbmpdm
, tvb
, offset
, msglen
, "LBMPDM Protocol");
1208 subtree
= proto_item_add_subtree(subtree_item
, ett_lbmpdm
);
1209 proto_tree_add_item(subtree
, hf_lbmpdm_magic
, tvb
, offset
+ O_LBMPDM_MSG_HDR_T_MAGIC
, L_LBMPDM_MSG_HDR_T_MAGIC
, encoding
);
1210 pi
= proto_tree_add_string(subtree
, hf_lbmpdm_encoding
, tvb
, offset
+ O_LBMPDM_MSG_HDR_T_MAGIC
, L_LBMPDM_MSG_HDR_T_MAGIC
,
1211 ((encoding
== ENC_BIG_ENDIAN
) ? "Big-Endian" : "Little-Endian"));
1212 proto_item_set_generated(pi
);
1213 proto_tree_add_item(subtree
, hf_lbmpdm_ver
, tvb
, offset
+ O_LBMPDM_MSG_HDR_T_VER_TYPE
, L_LBMPDM_MSG_HDR_T_VER_TYPE
, encoding
);
1214 proto_tree_add_item(subtree
, hf_lbmpdm_type
, tvb
, offset
+ O_LBMPDM_MSG_HDR_T_VER_TYPE
, L_LBMPDM_MSG_HDR_T_VER_TYPE
, encoding
);
1215 proto_tree_add_item(subtree
, hf_lbmpdm_next_hdr
, tvb
, offset
+ O_LBMPDM_MSG_HDR_T_NEXT_HDR
, L_LBMPDM_MSG_HDR_T_NEXT_HDR
, encoding
);
1216 proto_tree_add_item(subtree
, hf_lbmpdm_def_major_ver
, tvb
, offset
+ O_LBMPDM_MSG_HDR_T_DEF_MAJOR_VER
, L_LBMPDM_MSG_HDR_T_DEF_MAJOR_VER
, encoding
);
1217 msgid
.ver_major
= tvb_get_uint8(tvb
, offset
+ O_LBMPDM_MSG_HDR_T_DEF_MAJOR_VER
);
1218 proto_tree_add_item(subtree
, hf_lbmpdm_def_minor_ver
, tvb
, offset
+ O_LBMPDM_MSG_HDR_T_DEF_MINOR_VER
, L_LBMPDM_MSG_HDR_T_DEF_MINOR_VER
, encoding
);
1219 msgid
.ver_minor
= tvb_get_uint8(tvb
, offset
+ O_LBMPDM_MSG_HDR_T_DEF_MINOR_VER
);
1220 proto_tree_add_item(subtree
, hf_lbmpdm_def_id
, tvb
, offset
+ O_LBMPDM_MSG_HDR_T_DEF_ID
, L_LBMPDM_MSG_HDR_T_DEF_ID
, encoding
);
1221 msgid
.msg_def_id
= tvb_get_uint32(tvb
, offset
+ O_LBMPDM_MSG_HDR_T_DEF_ID
, encoding
);
1222 proto_tree_add_item(subtree
, hf_lbmpdm_len
, tvb
, offset
+ O_LBMPDM_MSG_HDR_T_LEN
, L_LBMPDM_MSG_HDR_T_LEN
, encoding
);
1224 next_hdr
= tvb_get_uint8(tvb
, offset
+ O_LBMPDM_MSG_HDR_T_NEXT_HDR
);
1225 len_remaining
= msglen
- L_LBMPDM_MSG_HDR_T
;
1226 ofs
= offset
+ L_LBMPDM_MSG_HDR_T
;
1227 dissected_len
= L_LBMPDM_MSG_HDR_T
;
1228 datalen
= msglen
- L_LBMPDM_MSG_HDR_T
;
1229 if (len_remaining
> 0)
1231 uint8_t this_hdr
= next_hdr
;
1233 segments_item
= proto_tree_add_item(subtree
, hf_lbmpdm_segments
, tvb
, ofs
, datalen
, encoding
);
1234 segments_tree
= proto_item_add_subtree(segments_item
, ett_lbmpdm_segments
);
1235 while ((this_hdr
!= PDM_HDR_TYPE_EOM
) && (len_remaining
>= L_LBMPDM_SEG_HDR_T
))
1237 next_hdr
= tvb_get_uint8(tvb
, ofs
+ O_LBMPDM_SEG_HDR_T_NEXT_HDR
);
1240 case PDM_HDR_TYPE_DATA
:
1241 segment_len
= dissect_segment_data(tvb
, ofs
, pinfo
, segments_tree
, &msgid
, encoding
);
1243 case PDM_HDR_TYPE_OFSTTBLE
:
1244 segment_len
= dissect_segment_ofstable(tvb
, ofs
, pinfo
, segments_tree
, &(msgid
.offset_table
), encoding
);
1246 case PDM_HDR_TYPE_DEFN
:
1247 segment_len
= dissect_segment_defn(tvb
, ofs
, pinfo
, segments_tree
, channel
, encoding
);
1250 segment_len
= dissect_segment_unknown(tvb
, ofs
, pinfo
, segments_tree
, encoding
);
1253 this_hdr
= next_hdr
;
1254 dissected_len
+= segment_len
;
1255 len_remaining
-= segment_len
;
1259 return (dissected_len
);
1262 int lbmpdm_get_minimum_length(void)
1264 return (L_LBMPDM_MSG_HDR_T
);
1267 /* Register all the bits needed with the filtering engine */
1268 void proto_register_lbmpdm(void)
1270 static hf_register_info hf
[] =
1273 { "Magic", "lbmpdm.magic", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1274 { &hf_lbmpdm_encoding
,
1275 { "Encoding", "lbmpdm.encoding", FT_STRING
, BASE_NONE
, NULL
, 0x0, "encoding as determined by magic number", HFILL
} },
1277 { "Version", "lbmpdm.ver", FT_UINT8
, BASE_DEC
, NULL
, PDM_HDR_VER_TYPE_VER_MASK
, NULL
, HFILL
} },
1279 { "Type", "lbmpdm.type", FT_UINT8
, BASE_DEC
, NULL
, PDM_HDR_VER_TYPE_TYPE_MASK
, NULL
, HFILL
} },
1280 { &hf_lbmpdm_next_hdr
,
1281 { "Next Header", "lbmpdm.next_hdr", FT_UINT8
, BASE_DEC_HEX
, VALS(lbmpdm_next_header
), 0x0, NULL
, HFILL
} },
1282 { &hf_lbmpdm_def_major_ver
,
1283 { "Definition Major Version", "lbmpdm.def_major_ver", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1284 { &hf_lbmpdm_def_minor_ver
,
1285 { "Definition Minor Version", "lbmpdm.def_minor_ver", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1286 { &hf_lbmpdm_def_id
,
1287 { "Definition ID", "lbmpdm.def_id", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1289 { "Length", "lbmpdm.len", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1290 { &hf_lbmpdm_segments
,
1291 { "Segments", "lbmpdm.segments", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1292 { &hf_lbmpdm_segment
,
1293 { "Segment", "lbmpdm.segment", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1294 { &hf_lbmpdm_segment_next_hdr
,
1295 { "Next Header", "lbmpdm.segment.next_hdr", FT_UINT8
, BASE_DEC_HEX
, VALS(lbmpdm_next_header
), 0x0, NULL
, HFILL
} },
1296 { &hf_lbmpdm_segment_flags
,
1297 { "Flags", "lbmpdm.segment.flags", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1298 { &hf_lbmpdm_segment_res
,
1299 { "Reserved", "lbmpdm.segment.res", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1300 { &hf_lbmpdm_segment_len
,
1301 { "Length", "lbmpdm.segment.len", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1302 { &hf_lbmpdm_segment_def_id
,
1303 { "Definition ID", "lbmpdm.segment_def.id", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1304 { &hf_lbmpdm_segment_def_num_fields
,
1305 { "Number Of Fields", "lbmpdm.segment_def.num_fields", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1306 { &hf_lbmpdm_segment_def_field_names_type
,
1307 { "Field Names Type", "lbmpdm.segment_def.field_names_type", FT_UINT8
, BASE_HEX
, VALS(lbmpdm_field_name_type
), 0x0, NULL
, HFILL
} },
1308 { &hf_lbmpdm_segment_def_finalized
,
1309 { "Finalized", "lbmpdm.segment_def.finalized", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1310 { &hf_lbmpdm_segment_def_msg_vers_major
,
1311 { "Definition Major Version", "lbmpdm.segment_def.msg_vers_major", FT_UINT8
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1312 { &hf_lbmpdm_segment_def_msg_vers_minor
,
1313 { "Definition Minor Version", "lbmpdm.segment_def.msg_vers_minor", FT_UINT8
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1314 { &hf_lbmpdm_segment_def_fixed_req_section_len
,
1315 { "Fixed Required Section Length", "lbmpdm.segment_def.fixed_req_section_len", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1316 { &hf_lbmpdm_segment_def_field_info_len
,
1317 { "Field Information Length", "lbmpdm.segment_def.field_info_len", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1318 { &hf_lbmpdm_segment_def_field
,
1319 { "Field Definition", "lbmpdm.segment_def.field", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1320 { &hf_lbmpdm_segment_def_field_def_len
,
1321 { "Definition Length", "lbmpdm.segment_def.field.def_len", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1322 { &hf_lbmpdm_segment_def_field_id
,
1323 { "ID", "lbmpdm.segment_def.field.id", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1324 { &hf_lbmpdm_segment_def_field_len
,
1325 { "Length", "lbmpdm.segment_def.field.len", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1326 { &hf_lbmpdm_segment_def_field_fixed_str_len
,
1327 { "Fixed String Length", "lbmpdm.segment_def.field.fixed_str_len", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1328 { &hf_lbmpdm_segment_def_field_num_arr_elem
,
1329 { "Number Of Array Elements", "lbmpdm.segment_def.field.num_arr_elem", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1330 { &hf_lbmpdm_segment_def_field_req
,
1331 { "Required", "lbmpdm.segment_def.field.req", FT_UINT8
, BASE_HEX
, VALS(lbmpdm_field_required
), 0x0, NULL
, HFILL
} },
1332 { &hf_lbmpdm_segment_def_field_fixed
,
1333 { "Fixed Length Field", "lbmpdm.segment_def.field.fixed", FT_UINT8
, BASE_HEX
, VALS(lbmpdm_field_fixed_length
), 0x0, NULL
, HFILL
} },
1334 { &hf_lbmpdm_segment_def_field_fld_int_name
,
1335 { "Field Integer Name", "lbmpdm.segment_def.field.fld_int_name", FT_INT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1336 { &hf_lbmpdm_segment_def_field_str_name_len
,
1337 { "String Name Length", "lbmpdm.segment_def.field.str_name_len", FT_INT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1338 { &hf_lbmpdm_segment_def_field_str_name
,
1339 { "String Name", "lbmpdm.segment_def.field.str_name", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1340 { &hf_lbmpdm_segment_def_field_fld_type
,
1341 { "Field Type", "lbmpdm.segment_def.field.fld_type", FT_UINT16
, BASE_DEC_HEX
, VALS(lbmpdm_field_type
), 0x0, NULL
, HFILL
} },
1342 { &hf_lbmpdm_offset_entry
,
1343 { "Offset Entry", "lbmpdm.segment_ofs.entry", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1344 { &hf_lbmpdm_offset_entry_id
,
1345 { "ID", "lbmpdm.segment_ofs.entry.id", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1346 { &hf_lbmpdm_offset_entry_offset
,
1347 { "Offset", "lbmpdm.segment_ofs.entry.offset", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1348 { &hf_lbmpdm_segment_data
,
1349 { "Data", "lbmpdm.segment.data", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1351 { "Field", "lbmpdm.field", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1352 { &hf_lbmpdm_field_id
,
1353 { "ID", "lbmpdm.field.id", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1354 { &hf_lbmpdm_field_string_name
,
1355 { "String Name", "lbmpdm.field.string_name", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1356 { &hf_lbmpdm_field_int_name
,
1357 { "Integer Name", "lbmpdm.field.int_name", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1358 { &hf_lbmpdm_field_type
,
1359 { "Type", "lbmpdm.field.type", FT_UINT16
, BASE_DEC_HEX
, VALS(lbmpdm_field_type
), 0x0, NULL
, HFILL
} },
1360 { &hf_lbmpdm_field_total_length
,
1361 { "Total Length", "lbmpdm.field.total_length", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1362 { &hf_lbmpdm_field_length
,
1363 { "Length", "lbmpdm.field.length", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1364 { &hf_lbmpdm_field_value_boolean
,
1365 { "Boolean Value", "lbmpdm.field.value_boolean", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1366 { &hf_lbmpdm_field_value_int8
,
1367 { "INT8 Value", "lbmpdm.field.value_int8", FT_INT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1368 { &hf_lbmpdm_field_value_uint8
,
1369 { "UINT8 Value", "lbmpdm.field.value_uint8", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1370 { &hf_lbmpdm_field_value_int16
,
1371 { "INT16 Value", "lbmpdm.field.value_int16", FT_INT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1372 { &hf_lbmpdm_field_value_uint16
,
1373 { "UINT16 Value", "lbmpdm.field.value_uint16", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1374 { &hf_lbmpdm_field_value_int32
,
1375 { "INT32 Value", "lbmpdm.field.value_int32", FT_INT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1376 { &hf_lbmpdm_field_value_uint32
,
1377 { "UINT32 Value", "lbmpdm.field.value_uint32", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1378 { &hf_lbmpdm_field_value_int64
,
1379 { "INT64 Value", "lbmpdm.field.value_int64", FT_INT64
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1380 { &hf_lbmpdm_field_value_uint64
,
1381 { "UINT64 Value", "lbmpdm.field.value_uint64", FT_UINT64
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1382 { &hf_lbmpdm_field_value_float
,
1383 { "FLOAT Value", "lbmpdm.field.value_float", FT_FLOAT
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1384 { &hf_lbmpdm_field_value_double
,
1385 { "DOUBLE Value", "lbmpdm.field.value_double", FT_DOUBLE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1386 { &hf_lbmpdm_field_value_decimal
,
1387 { "DECIMAL Value", "lbmpdm.field.value_decimal", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1388 { &hf_lbmpdm_field_value_timestamp
,
1389 { "TIMESTAMP Value", "lbmpdm.field.value_timestamp", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0, NULL
, HFILL
} },
1390 { &hf_lbmpdm_field_value_fixed_string
,
1391 { "FIXED STRING Value", "lbmpdm.field.value_fixed_string", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1392 { &hf_lbmpdm_field_value_string
,
1393 { "STRING Value", "lbmpdm.field.value_string", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1394 { &hf_lbmpdm_field_value_fixed_unicode
,
1395 { "FIXED UNICODE Value", "lbmpdm.field.value_fixed_unicode", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1396 { &hf_lbmpdm_field_value_unicode
,
1397 { "UNICODE Value", "lbmpdm.field.value_unicode", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1398 { &hf_lbmpdm_field_value_blob
,
1399 { "BLOB Value", "lbmpdm.field.value_blob", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1400 { &hf_lbmpdm_field_value_message
,
1401 { "MESSAGE Value", "lbmpdm.field.value_message", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} }
1403 static int * ett
[] =
1406 &ett_lbmpdm_segments
,
1407 &ett_lbmpdm_segment
,
1408 &ett_lbmpdm_offset_entry
,
1409 &ett_lbmpdm_segment_def_field
,
1413 proto_lbmpdm
= proto_register_protocol("LBMPDM Protocol", "LBMPDM", "lbmpdm");
1415 proto_register_field_array(proto_lbmpdm
, hf
, array_length(hf
));
1416 proto_register_subtree_array(ett
, array_length(ett
));
1417 lbmpdm_definition_table
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
1421 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1426 * indent-tabs-mode: nil
1429 * vi: set shiftwidth=4 tabstop=8 expandtab:
1430 * :indentSize=4:tabSize=8:noTabs=true: