Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-lbmpdm.c
blob8bafd686ca0279427d42e52f0133a44a24714bef
1 /* packet-lbmpdm.c
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
13 #include "config.h"
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);
30 /*------------*/
31 /* PDM header */
32 /*------------*/
33 typedef struct lbmpdm_msg_hdr_stct_t
35 uint32_t magic;
36 uint8_t ver_type;
37 uint8_t next_hdr;
38 uint8_t def_major_ver;
39 uint8_t def_minor_ver;
40 uint32_t def_id;
41 uint32_t len;
42 } lbmpdm_msg_hdr_t;
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
64 uint8_t next_hdr;
65 uint8_t flags;
66 uint16_t res;
67 uint32_t len;
68 } lbmpdm_seg_hdr_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
84 int32_t id;
85 int32_t num_fields;
86 uint8_t field_names_type;
87 uint8_t finalized;
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;
92 } lbmpdm_defn_t;
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
116 uint32_t id;
117 uint32_t len;
118 uint32_t fixed_str_len;
119 uint32_t num_arr_elem;
120 uint8_t req;
121 uint8_t fixed;
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 /*---------------------------------*/
149 typedef struct
151 uint32_t id;
152 uint32_t offset;
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.
171 #define PDM_VERS 1
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
234 typedef struct
236 uint32_t num_flds;
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
249 uint32_t id;
250 uint32_t len;
251 uint32_t fixed_string_len;
252 uint32_t num_array_elem;
253 uint8_t required;
254 uint8_t fixed;
255 uint16_t field_type;
256 uint16_t base_type;
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
267 uint64_t channel;
268 uint32_t id;
269 uint8_t vers_major;
270 uint8_t vers_minor;
271 int32_t num_fields;
272 uint8_t field_names_type;
273 uint8_t finalized;
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;
280 typedef struct
282 uint64_t channel;
283 uint32_t msg_def_id;
284 uint8_t ver_major;
285 uint8_t ver_minor;
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;
372 /* Protocol trees */
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 /*----------------------------------------------------------------------------*/
384 /* Value tables */
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" },
425 { 0x0, NULL }
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" },
434 { 0x0, NULL }
437 static const value_string lbmpdm_field_name_type[] =
439 { PDM_DEFN_STR_FIELD_NAMES, "String" },
440 { PDM_DEFN_INT_FIELD_NAMES, "Integer" },
441 { 0x0, NULL }
444 static const value_string lbmpdm_field_required[] =
446 { PDM_DEFN_OPTIONAL_FIELD, "Field is optional" },
447 { PDM_DEFN_REQUIRED_FIELD, "Field is required" },
448 { 0x0, NULL }
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" },
455 { 0x0, NULL }
458 static int lbmpdm_get_segment_length(tvbuff_t * tvb, int offset, int encoding, int * data_length)
460 uint32_t datalen = 0;
461 int seglen = 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;
466 return (seglen);
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;
478 key[1].length = 0;
479 key[1].key = NULL;
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);
490 return (entry);
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);
500 if (entry != NULL)
502 return (entry);
504 entry = wmem_new(wmem_file_scope(), lbmpdm_definition_t);
505 entry->channel = channel;
506 entry->id = id;
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);
512 return (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);
520 return (entry);
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);
528 if (entry != NULL)
530 return (entry);
532 entry = wmem_new0(wmem_file_scope(), lbmpdm_definition_field_t);
533 entry->id = id;
534 entry->definition = definition;
535 wmem_tree_insert32(definition->field_list, id, (void *) entry);
536 return (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)
544 switch (field_type)
546 case PDM_TYPE_BOOLEAN:
547 proto_tree_add_item(tree, hf_lbmpdm_field_value_boolean, tvb, offset, field_length, encoding);
548 break;
549 case PDM_TYPE_INT8:
550 proto_tree_add_item(tree, hf_lbmpdm_field_value_int8, tvb, offset, field_length, encoding);
551 break;
552 case PDM_TYPE_UINT8:
553 proto_tree_add_item(tree, hf_lbmpdm_field_value_uint8, tvb, offset, field_length, encoding);
554 break;
555 case PDM_TYPE_INT16:
556 proto_tree_add_item(tree, hf_lbmpdm_field_value_int16, tvb, offset, field_length, encoding);
557 break;
558 case PDM_TYPE_UINT16:
559 proto_tree_add_item(tree, hf_lbmpdm_field_value_uint16, tvb, offset, field_length, encoding);
560 break;
561 case PDM_TYPE_INT32:
562 proto_tree_add_item(tree, hf_lbmpdm_field_value_int32, tvb, offset, field_length, encoding);
563 break;
564 case PDM_TYPE_UINT32:
565 proto_tree_add_item(tree, hf_lbmpdm_field_value_uint32, tvb, offset, field_length, encoding);
566 break;
567 case PDM_TYPE_INT64:
568 proto_tree_add_item(tree, hf_lbmpdm_field_value_int64, tvb, offset, field_length, encoding);
569 break;
570 case PDM_TYPE_UINT64:
571 proto_tree_add_item(tree, hf_lbmpdm_field_value_uint64, tvb, offset, field_length, encoding);
572 break;
573 case PDM_TYPE_FLOAT:
574 proto_tree_add_item(tree, hf_lbmpdm_field_value_float, tvb, offset, field_length, encoding);
575 break;
576 case PDM_TYPE_DOUBLE:
577 proto_tree_add_item(tree, hf_lbmpdm_field_value_double, tvb, offset, field_length, encoding);
578 break;
579 case PDM_TYPE_DECIMAL:
581 int64_t mantissa;
582 int8_t exponent;
583 int64_t whole = 0;
584 uint64_t fraction = 0;
585 int8_t shift_count;
587 exponent = tvb_get_int8(tvb, offset);
588 mantissa = tvb_get_int64(tvb, offset + 1, encoding);
589 if (exponent >= 0)
591 whole = mantissa;
592 shift_count = exponent;
593 while (shift_count > 0)
595 whole *= 10;
596 shift_count--;
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);
601 else
603 uint64_t divisor = 1;
604 int decimal_digits = -exponent;
605 shift_count = decimal_digits;
606 while (shift_count > 0)
608 divisor *= 10;
609 shift_count--;
611 if (mantissa < 0)
613 whole = -mantissa;
615 else
617 whole = mantissa;
619 fraction = whole % divisor;
620 whole /= divisor;
621 if (mantissa < 0)
623 whole *= -1;
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);
630 break;
631 case PDM_TYPE_TIMESTAMP:
633 nstime_t 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, &timestamp);
639 break;
640 case PDM_TYPE_FIX_STRING:
641 proto_tree_add_item(tree, hf_lbmpdm_field_value_fixed_string, tvb, offset, field_length, encoding);
642 break;
643 case PDM_TYPE_STRING:
644 proto_tree_add_item(tree, hf_lbmpdm_field_value_string, tvb, offset, field_length, encoding);
645 break;
646 case PDM_TYPE_FIX_UNICODE:
647 proto_tree_add_item(tree, hf_lbmpdm_field_value_fixed_unicode, tvb, offset, field_length, encoding);
648 break;
649 case PDM_TYPE_UNICODE:
650 proto_tree_add_item(tree, hf_lbmpdm_field_value_unicode, tvb, offset, field_length, encoding);
651 break;
652 case PDM_TYPE_BLOB:
653 proto_tree_add_item(tree, hf_lbmpdm_field_value_blob, tvb, offset, field_length, encoding);
654 break;
655 case PDM_TYPE_MESSAGE:
656 proto_tree_add_item(tree, hf_lbmpdm_field_value_message, tvb, offset, field_length, encoding);
657 break;
658 default:
659 break;
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;
668 int ofs = offset;
669 uint32_t element_count = 0;
670 uint32_t idx;
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);
681 else
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)
690 element_count = 1;
692 else
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);
698 len_dissected += 4;
699 ofs += 4;
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;
716 value_offset += 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;
733 int datalen = 0;
734 int seglen = 0;
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);
748 if (def == NULL)
750 proto_tree_add_item(subtree, hf_lbmpdm_segment_data, tvb, offset + L_LBMPDM_SEG_HDR_T, datalen, ENC_NA);
752 else
754 int fld_offset = offset + L_LBMPDM_SEG_HDR_T;
755 lbmpdm_definition_field_t * field = NULL;
756 bool string_field_names = false;
757 uint32_t idx;
759 if (def->field_names_type == PDM_DEFN_STR_FIELD_NAMES)
761 string_field_names = true;
763 else
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];
777 if (ofs != -1)
779 field = lbmpdm_definition_field_find(def, idx);
780 if (field != NULL)
782 (void)dissect_field(tvb, offset + L_LBMPDM_SEG_HDR_T + ofs, subtree, field, string_field_names, encoding);
787 return (seglen);
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;
794 int datalen = 0;
795 int seglen = 0;
796 int ofs = 0;
797 int field_count = 0;
798 int idx;
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)
817 id_list[idx] = -1;
818 ofs_list[idx] = -1;
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;
864 return (seglen);
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;
871 int seglen = 0;
872 int ofs = 0;
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;
878 uint32_t def_id = 0;
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);
911 if (add_definition)
913 def = lbmpdm_definition_find(channel, def_id, vers_major, vers_minor);
914 if (def == NULL)
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;
931 int def_ofs = 0;
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);
945 def_ofs = 4;
946 type_ofs += def_ofs;
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;
970 uint32_t field_id;
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);
974 if (field == NULL)
976 field = lbmpdm_definition_field_add(def, field_id);
977 if (field != NULL)
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);
990 else
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;
1001 break;
1002 case PDM_TYPE_INT8:
1003 case PDM_TYPE_INT8_ARR:
1004 field->base_type = PDM_TYPE_INT8;
1005 break;
1006 case PDM_TYPE_UINT8:
1007 case PDM_TYPE_UINT8_ARR:
1008 field->base_type = PDM_TYPE_UINT8;
1009 break;
1010 case PDM_TYPE_INT16:
1011 case PDM_TYPE_INT16_ARR:
1012 field->base_type = PDM_TYPE_INT16;
1013 break;
1014 case PDM_TYPE_UINT16:
1015 case PDM_TYPE_UINT16_ARR:
1016 field->base_type = PDM_TYPE_UINT16;
1017 break;
1018 case PDM_TYPE_INT32:
1019 case PDM_TYPE_INT32_ARR:
1020 field->base_type = PDM_TYPE_INT32;
1021 break;
1022 case PDM_TYPE_UINT32:
1023 case PDM_TYPE_UINT32_ARR:
1024 field->base_type = PDM_TYPE_UINT32;
1025 break;
1026 case PDM_TYPE_INT64:
1027 case PDM_TYPE_INT64_ARR:
1028 field->base_type = PDM_TYPE_INT64;
1029 break;
1030 case PDM_TYPE_UINT64:
1031 case PDM_TYPE_UINT64_ARR:
1032 field->base_type = PDM_TYPE_UINT64;
1033 break;
1034 case PDM_TYPE_FLOAT:
1035 case PDM_TYPE_FLOAT_ARR:
1036 field->base_type = PDM_TYPE_FLOAT;
1037 break;
1038 case PDM_TYPE_DOUBLE:
1039 case PDM_TYPE_DOUBLE_ARR:
1040 field->base_type = PDM_TYPE_DOUBLE;
1041 break;
1042 case PDM_TYPE_DECIMAL:
1043 case PDM_TYPE_DECIMAL_ARR:
1044 field->base_type = PDM_TYPE_DECIMAL;
1045 break;
1046 case PDM_TYPE_TIMESTAMP:
1047 case PDM_TYPE_TIMESTAMP_ARR:
1048 field->base_type = PDM_TYPE_TIMESTAMP;
1049 break;
1050 case PDM_TYPE_FIX_STRING:
1051 case PDM_TYPE_FIX_STRING_ARR:
1052 field->base_type = PDM_TYPE_FIX_STRING;
1053 break;
1054 case PDM_TYPE_STRING:
1055 case PDM_TYPE_STRING_ARR:
1056 field->base_type = PDM_TYPE_STRING;
1057 break;
1058 case PDM_TYPE_FIX_UNICODE:
1059 case PDM_TYPE_FIX_UNICODE_ARR:
1060 field->base_type = PDM_TYPE_FIX_UNICODE;
1061 break;
1062 case PDM_TYPE_UNICODE:
1063 case PDM_TYPE_UNICODE_ARR:
1064 field->base_type = PDM_TYPE_UNICODE;
1065 break;
1066 case PDM_TYPE_BLOB:
1067 case PDM_TYPE_BLOB_ARR:
1068 default:
1069 field->base_type = PDM_TYPE_BLOB;
1070 break;
1071 case PDM_TYPE_MESSAGE:
1072 case PDM_TYPE_MESSAGE_ARR:
1073 field->base_type = PDM_TYPE_MESSAGE;
1074 break;
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;
1083 else
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++;
1094 ofs += def_len;
1095 remaining_datalen -= def_len;
1096 num_fields--;
1098 return (seglen);
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;
1105 int datalen = 0;
1106 int seglen = 0;
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);
1116 return (seglen);
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;
1125 bool result = true;
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;
1141 else
1143 result = false;
1145 return (result);
1148 bool lbmpdm_verify_payload(tvbuff_t * tvb, int offset, int * encoding, int * length)
1150 uint8_t next_header;
1151 uint32_t len = 0;
1153 if (!tvb_bytes_exist(tvb, offset, L_LBMPDM_MSG_HDR_T))
1155 return false;
1157 if (!check_lbmpdm_encoding(tvb, offset, encoding))
1159 return false;
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:
1168 break;
1169 default:
1170 return false;
1172 len = tvb_get_uint32(tvb, offset + O_LBMPDM_MSG_HDR_T_LEN, *encoding);
1173 if (len > INT_MAX)
1175 return false;
1177 *length = (int)len;
1178 return true;
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;
1188 uint8_t next_hdr;
1189 int dissected_len = 0;
1190 int encoding;
1191 int msglen = 0;
1192 int len_remaining = 0;
1193 int ofs = 0;
1194 int segment_len = 0;
1195 int datalen = 0;
1196 uint32_t raw_msglen = 0;
1197 lbmpdm_msg_definition_id_t msgid;
1199 if (!lbmpdm_verify_payload(tvb, offset, &encoding, &raw_msglen))
1201 return 0;
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);
1238 switch (this_hdr)
1240 case PDM_HDR_TYPE_DATA:
1241 segment_len = dissect_segment_data(tvb, ofs, pinfo, segments_tree, &msgid, encoding);
1242 break;
1243 case PDM_HDR_TYPE_OFSTTBLE:
1244 segment_len = dissect_segment_ofstable(tvb, ofs, pinfo, segments_tree, &(msgid.offset_table), encoding);
1245 break;
1246 case PDM_HDR_TYPE_DEFN:
1247 segment_len = dissect_segment_defn(tvb, ofs, pinfo, segments_tree, channel, encoding);
1248 break;
1249 default:
1250 segment_len = dissect_segment_unknown(tvb, ofs, pinfo, segments_tree, encoding);
1251 break;
1253 this_hdr = next_hdr;
1254 dissected_len += segment_len;
1255 len_remaining -= segment_len;
1256 ofs += 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[] =
1272 { &hf_lbmpdm_magic,
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 } },
1276 { &hf_lbmpdm_ver,
1277 { "Version", "lbmpdm.ver", FT_UINT8, BASE_DEC, NULL, PDM_HDR_VER_TYPE_VER_MASK, NULL, HFILL } },
1278 { &hf_lbmpdm_type,
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 } },
1288 { &hf_lbmpdm_len,
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 } },
1350 { &hf_lbmpdm_field,
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[] =
1405 &ett_lbmpdm,
1406 &ett_lbmpdm_segments,
1407 &ett_lbmpdm_segment,
1408 &ett_lbmpdm_offset_entry,
1409 &ett_lbmpdm_segment_def_field,
1410 &ett_lbmpdm_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
1423 * Local variables:
1424 * c-basic-offset: 4
1425 * tab-width: 8
1426 * indent-tabs-mode: nil
1427 * End:
1429 * vi: set shiftwidth=4 tabstop=8 expandtab:
1430 * :indentSize=4:tabSize=8:noTabs=true: