/src/wireshark/epan/dissectors/packet-lbmpdm.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* packet-lbmpdm.c |
2 | | * Routines for LBM PDM Packet dissection |
3 | | * |
4 | | * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved. |
5 | | * |
6 | | * Wireshark - Network traffic analyzer |
7 | | * By Gerald Combs <gerald@wireshark.org> |
8 | | * Copyright 1998 Gerald Combs |
9 | | * |
10 | | * SPDX-License-Identifier: GPL-2.0-or-later |
11 | | */ |
12 | | |
13 | | #include "config.h" |
14 | | #include <epan/packet.h> |
15 | | #include <epan/exceptions.h> |
16 | | #include "packet-lbm.h" |
17 | | |
18 | | /* Magic number for message header to check if data is big-endian or little-endian. */ |
19 | 1.15k | #define PDM_MSG_HDR_BE_MAGIC_BYTE_1 0xA7 |
20 | 1 | #define PDM_MSG_HDR_BE_MAGIC_BYTE_2 0x1C |
21 | 0 | #define PDM_MSG_HDR_BE_MAGIC_BYTE_3 0xCA |
22 | 0 | #define PDM_MSG_HDR_BE_MAGIC_BYTE_4 0xFE |
23 | 1.15k | #define PDM_MSG_HDR_LE_MAGIC_BYTE_1 0xFE |
24 | 7 | #define PDM_MSG_HDR_LE_MAGIC_BYTE_2 0xCA |
25 | 0 | #define PDM_MSG_HDR_LE_MAGIC_BYTE_3 0x1C |
26 | 0 | #define PDM_MSG_HDR_LE_MAGIC_BYTE_4 0xA7 |
27 | | |
28 | | void proto_register_lbmpdm(void); |
29 | | |
30 | | /*------------*/ |
31 | | /* PDM header */ |
32 | | /*------------*/ |
33 | | typedef struct lbmpdm_msg_hdr_stct_t |
34 | | { |
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 | 0 | #define O_LBMPDM_MSG_HDR_T_MAGIC OFFSETOF(lbmpdm_msg_hdr_t, magic) |
44 | 0 | #define L_LBMPDM_MSG_HDR_T_MAGIC SIZEOF(lbmpdm_msg_hdr_t, magic) |
45 | 0 | #define O_LBMPDM_MSG_HDR_T_VER_TYPE OFFSETOF(lbmpdm_msg_hdr_t, ver_type) |
46 | 0 | #define L_LBMPDM_MSG_HDR_T_VER_TYPE SIZEOF(lbmpdm_msg_hdr_t, ver_type) |
47 | 0 | #define O_LBMPDM_MSG_HDR_T_NEXT_HDR OFFSETOF(lbmpdm_msg_hdr_t, next_hdr) |
48 | 0 | #define L_LBMPDM_MSG_HDR_T_NEXT_HDR SIZEOF(lbmpdm_msg_hdr_t, next_hdr) |
49 | 0 | #define O_LBMPDM_MSG_HDR_T_DEF_MAJOR_VER OFFSETOF(lbmpdm_msg_hdr_t, def_major_ver) |
50 | 0 | #define L_LBMPDM_MSG_HDR_T_DEF_MAJOR_VER SIZEOF(lbmpdm_msg_hdr_t, def_major_ver) |
51 | 0 | #define O_LBMPDM_MSG_HDR_T_DEF_MINOR_VER OFFSETOF(lbmpdm_msg_hdr_t, def_minor_ver) |
52 | 0 | #define L_LBMPDM_MSG_HDR_T_DEF_MINOR_VER SIZEOF(lbmpdm_msg_hdr_t, def_minor_ver) |
53 | 0 | #define O_LBMPDM_MSG_HDR_T_DEF_ID OFFSETOF(lbmpdm_msg_hdr_t, def_id) |
54 | 0 | #define L_LBMPDM_MSG_HDR_T_DEF_ID SIZEOF(lbmpdm_msg_hdr_t, def_id) |
55 | 0 | #define O_LBMPDM_MSG_HDR_T_LEN OFFSETOF(lbmpdm_msg_hdr_t, len) |
56 | 0 | #define L_LBMPDM_MSG_HDR_T_LEN SIZEOF(lbmpdm_msg_hdr_t, len) |
57 | 1.51k | #define L_LBMPDM_MSG_HDR_T (int) sizeof(lbmpdm_msg_hdr_t) |
58 | | |
59 | | /*---------------------*/ |
60 | | /* PDM segment header. */ |
61 | | /*---------------------*/ |
62 | | typedef struct lbmpdm_seg_hdr_stct_t |
63 | | { |
64 | | uint8_t next_hdr; |
65 | | uint8_t flags; |
66 | | uint16_t res; |
67 | | uint32_t len; |
68 | | } lbmpdm_seg_hdr_t; |
69 | 0 | #define O_LBMPDM_SEG_HDR_T_NEXT_HDR OFFSETOF(lbmpdm_seg_hdr_t, next_hdr) |
70 | 0 | #define L_LBMPDM_SEG_HDR_T_NEXT_HDR SIZEOF(lbmpdm_seg_hdr_t, next_hdr) |
71 | 0 | #define O_LBMPDM_SEG_HDR_T_FLAGS OFFSETOF(lbmpdm_seg_hdr_t, flags) |
72 | 0 | #define L_LBMPDM_SEG_HDR_T_FLAGS SIZEOF(lbmpdm_seg_hdr_t, flags) |
73 | 0 | #define O_LBMPDM_SEG_HDR_T_RES OFFSETOF(lbmpdm_seg_hdr_t, res) |
74 | 0 | #define L_LBMPDM_SEG_HDR_T_RES SIZEOF(lbmpdm_seg_hdr_t, res) |
75 | 0 | #define O_LBMPDM_SEG_HDR_T_LEN OFFSETOF(lbmpdm_seg_hdr_t, len) |
76 | 0 | #define L_LBMPDM_SEG_HDR_T_LEN SIZEOF(lbmpdm_seg_hdr_t, len) |
77 | 0 | #define L_LBMPDM_SEG_HDR_T (int) sizeof(lbmpdm_seg_hdr_t) |
78 | | |
79 | | /*--------------------------------*/ |
80 | | /* PDM definition segment header. */ |
81 | | /*--------------------------------*/ |
82 | | typedef struct lbmpdm_defn_stct_t |
83 | | { |
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 | 0 | #define O_LBMPDM_DEFN_T_ID OFFSETOF(lbmpdm_defn_t, id) |
94 | 0 | #define L_LBMPDM_DEFN_T_ID SIZEOF(lbmpdm_defn_t, id) |
95 | 0 | #define O_LBMPDM_DEFN_T_NUM_FIELDS OFFSETOF(lbmpdm_defn_t, num_fields) |
96 | 0 | #define L_LBMPDM_DEFN_T_NUM_FIELDS SIZEOF(lbmpdm_defn_t, num_fields) |
97 | 0 | #define O_LBMPDM_DEFN_T_FIELD_NAMES_TYPE OFFSETOF(lbmpdm_defn_t, field_names_type) |
98 | 0 | #define L_LBMPDM_DEFN_T_FIELD_NAMES_TYPE SIZEOF(lbmpdm_defn_t, field_names_type) |
99 | 0 | #define O_LBMPDM_DEFN_T_FINALIZED OFFSETOF(lbmpdm_defn_t, finalized) |
100 | 0 | #define L_LBMPDM_DEFN_T_FINALIZED SIZEOF(lbmpdm_defn_t, finalized) |
101 | 0 | #define O_LBMPDM_DEFN_T_MSG_VERS_MAJOR OFFSETOF(lbmpdm_defn_t, msg_vers_major) |
102 | 0 | #define L_LBMPDM_DEFN_T_MSG_VERS_MAJOR SIZEOF(lbmpdm_defn_t, msg_vers_major) |
103 | 0 | #define O_LBMPDM_DEFN_T_MSG_VERS_MINOR OFFSETOF(lbmpdm_defn_t, msg_vers_minor) |
104 | 0 | #define L_LBMPDM_DEFN_T_MSG_VERS_MINOR SIZEOF(lbmpdm_defn_t, msg_vers_minor) |
105 | 0 | #define O_LBMPDM_DEFN_T_FIXED_REQ_SECTION_LEN OFFSETOF(lbmpdm_defn_t, fixed_req_section_len) |
106 | 0 | #define L_LBMPDM_DEFN_T_FIXED_REQ_SECTION_LEN SIZEOF(lbmpdm_defn_t, fixed_req_section_len) |
107 | 0 | #define O_LBMPDM_DEFN_T_FIELD_INFO_LEN OFFSETOF(lbmpdm_defn_t, field_info_len) |
108 | 0 | #define L_LBMPDM_DEFN_T_FIELD_INFO_LEN SIZEOF(lbmpdm_defn_t, field_info_len) |
109 | 0 | #define L_LBMPDM_DEFN_T (int) sizeof(lbmpdm_defn_t) |
110 | | |
111 | | /*----------------------------*/ |
112 | | /* PDM definition field info. */ |
113 | | /*----------------------------*/ |
114 | | typedef struct lbmpdm_field_info_stct_t |
115 | | { |
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 | 0 | #define O_LBMPDM_FIELD_INFO_T_ID OFFSETOF(lbmpdm_field_info_t, id) |
128 | 0 | #define L_LBMPDM_FIELD_INFO_T_ID SIZEOF(lbmpdm_field_info_t, id) |
129 | 0 | #define O_LBMPDM_FIELD_INFO_T_LEN OFFSETOF(lbmpdm_field_info_t, len) |
130 | 0 | #define L_LBMPDM_FIELD_INFO_T_LEN SIZEOF(lbmpdm_field_info_t, len) |
131 | 0 | #define O_LBMPDM_FIELD_INFO_T_FIXED_STR_LEN OFFSETOF(lbmpdm_field_info_t, fixed_str_len) |
132 | 0 | #define L_LBMPDM_FIELD_INFO_T_FIXED_STR_LEN SIZEOF(lbmpdm_field_info_t, fixed_str_len) |
133 | 0 | #define O_LBMPDM_FIELD_INFO_T_NUM_ARR_ELEM OFFSETOF(lbmpdm_field_info_t, num_arr_elem) |
134 | 0 | #define L_LBMPDM_FIELD_INFO_T_NUM_ARR_ELEM SIZEOF(lbmpdm_field_info_t, num_arr_elem) |
135 | 0 | #define O_LBMPDM_FIELD_INFO_T_REQ OFFSETOF(lbmpdm_field_info_t, req) |
136 | 0 | #define L_LBMPDM_FIELD_INFO_T_REQ SIZEOF(lbmpdm_field_info_t, req) |
137 | 0 | #define O_LBMPDM_FIELD_INFO_T_FIXED OFFSETOF(lbmpdm_field_info_t, fixed) |
138 | 0 | #define L_LBMPDM_FIELD_INFO_T_FIXED SIZEOF(lbmpdm_field_info_t, fixed) |
139 | 0 | #define O_LBMPDM_FIELD_INFO_T_FLD_INT_NAME (O_LBMPDM_FIELD_INFO_T_FIXED + L_LBMPDM_FIELD_INFO_T_FIXED) |
140 | 0 | #define L_LBMPDM_FIELD_INFO_T_FLD_INT_NAME 4 |
141 | 0 | #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 | 0 | #define L_LBMPDM_FIELD_INFO_T_STR_NAME_LEN 4 |
143 | 0 | #define L_LBMPDM_FIELD_INFO_T (O_LBMPDM_FIELD_INFO_T_STR_NAME_LEN + L_LBMPDM_FIELD_INFO_T_STR_NAME_LEN) |
144 | 0 | #define L_LBMPDM_FIELD_INFO_T_INT_NAME (int) (L_LBMPDM_FIELD_INFO_T + 2) |
145 | | |
146 | | /*---------------------------------*/ |
147 | | /* PDM offset table segment entry. */ |
148 | | /*---------------------------------*/ |
149 | | typedef struct |
150 | | { |
151 | | uint32_t id; |
152 | | uint32_t offset; |
153 | | } lbmpdm_offset_entry_t; |
154 | 0 | #define O_LBMPDM_OFFSET_ENTRY_T_ID OFFSETOF(lbmpdm_offset_entry_t, id) |
155 | 0 | #define L_LBMPDM_OFFSET_ENTRY_T_ID SIZEOF(lbmpdm_offset_entry_t, id) |
156 | 0 | #define O_LBMPDM_OFFSET_ENTRY_T_OFFSET OFFSETOF(lbmpdm_offset_entry_t, offset) |
157 | 0 | #define L_LBMPDM_OFFSET_ENTRY_T_OFFSET SIZEOF(lbmpdm_offset_entry_t, offset) |
158 | 0 | #define L_LBMPDM_OFFSET_ENTRY_T (int) sizeof(lbmpdm_offset_entry_t) |
159 | | |
160 | | /*-----------------------------------*/ |
161 | | /* Header types (value of next_hdr). */ |
162 | | /*-----------------------------------*/ |
163 | 0 | #define PDM_HDR_TYPE_DATA 0 |
164 | 0 | #define PDM_HDR_TYPE_OFSTTBLE 1 |
165 | 0 | #define PDM_HDR_TYPE_DEFN 2 |
166 | 0 | #define PDM_HDR_TYPE_EOM 0xFF |
167 | | |
168 | | |
169 | | /* PDM protocol version number. |
170 | | */ |
171 | | #define PDM_VERS 1 |
172 | | |
173 | | /*------------------*/ |
174 | | /* PDM field types. */ |
175 | | /*------------------*/ |
176 | 0 | #define PDM_TYPE_BOOLEAN 0 |
177 | 0 | #define PDM_TYPE_INT8 1 |
178 | 0 | #define PDM_TYPE_UINT8 2 |
179 | 0 | #define PDM_TYPE_INT16 3 |
180 | 0 | #define PDM_TYPE_UINT16 4 |
181 | 0 | #define PDM_TYPE_INT32 5 |
182 | 0 | #define PDM_TYPE_UINT32 6 |
183 | 0 | #define PDM_TYPE_INT64 7 |
184 | 0 | #define PDM_TYPE_UINT64 8 |
185 | 0 | #define PDM_TYPE_FLOAT 9 |
186 | 0 | #define PDM_TYPE_DOUBLE 10 |
187 | 0 | #define PDM_TYPE_DECIMAL 11 |
188 | 0 | #define PDM_TYPE_TIMESTAMP 12 |
189 | 0 | #define PDM_TYPE_FIX_STRING 13 |
190 | 0 | #define PDM_TYPE_STRING 14 |
191 | 0 | #define PDM_TYPE_FIX_UNICODE 15 |
192 | 0 | #define PDM_TYPE_UNICODE 16 |
193 | 0 | #define PDM_TYPE_BLOB 17 |
194 | 0 | #define PDM_TYPE_MESSAGE 18 |
195 | 0 | #define PDM_TYPE_BOOLEAN_ARR 19 |
196 | 0 | #define PDM_TYPE_INT8_ARR 20 |
197 | 0 | #define PDM_TYPE_UINT8_ARR 21 |
198 | 0 | #define PDM_TYPE_INT16_ARR 22 |
199 | 0 | #define PDM_TYPE_UINT16_ARR 23 |
200 | 0 | #define PDM_TYPE_INT32_ARR 24 |
201 | 0 | #define PDM_TYPE_UINT32_ARR 25 |
202 | 0 | #define PDM_TYPE_INT64_ARR 26 |
203 | 0 | #define PDM_TYPE_UINT64_ARR 27 |
204 | 0 | #define PDM_TYPE_FLOAT_ARR 28 |
205 | 0 | #define PDM_TYPE_DOUBLE_ARR 29 |
206 | 0 | #define PDM_TYPE_DECIMAL_ARR 30 |
207 | 0 | #define PDM_TYPE_TIMESTAMP_ARR 31 |
208 | 0 | #define PDM_TYPE_FIX_STRING_ARR 32 |
209 | 0 | #define PDM_TYPE_STRING_ARR 33 |
210 | 0 | #define PDM_TYPE_FIX_UNICODE_ARR 34 |
211 | 0 | #define PDM_TYPE_UNICODE_ARR 35 |
212 | 0 | #define PDM_TYPE_BLOB_ARR 36 |
213 | 0 | #define PDM_TYPE_MESSAGE_ARR 37 |
214 | | |
215 | | /* Macros for protocol version number and pdm message type. |
216 | | */ |
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 | 14 | #define PDM_HDR_VER_TYPE_VER_MASK 0xf0 |
221 | 14 | #define PDM_HDR_VER_TYPE_TYPE_MASK 0x0f |
222 | | |
223 | | #define PDM_IGNORE_FLAG 0x80 |
224 | | |
225 | 0 | #define PDM_DEFN_STR_FIELD_NAMES 0 |
226 | | #define PDM_DEFN_INT_FIELD_NAMES 1 |
227 | | |
228 | | #define PDM_DEFN_OPTIONAL_FIELD 0 |
229 | 0 | #define PDM_DEFN_REQUIRED_FIELD 1 |
230 | | |
231 | 0 | #define PDM_DEFN_VARIABLE_LENGTH_FIELD 0 |
232 | 0 | #define PDM_DEFN_FIXED_LENGTH_FIELD 1 |
233 | | |
234 | | typedef struct |
235 | | { |
236 | | uint32_t num_flds; |
237 | | int32_t * min_set_offset; |
238 | | int32_t * offset_list; |
239 | | } lbmpdm_offset_table_t; |
240 | | |
241 | | struct lbmpdm_definition_field_t_stct; |
242 | | typedef struct lbmpdm_definition_field_t_stct lbmpdm_definition_field_t; |
243 | | |
244 | | struct lbmpdm_definition_t_stct; |
245 | | typedef struct lbmpdm_definition_t_stct lbmpdm_definition_t; |
246 | | |
247 | | struct lbmpdm_definition_field_t_stct |
248 | | { |
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; |
263 | | }; |
264 | | |
265 | | struct lbmpdm_definition_t_stct |
266 | | { |
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; |
278 | | }; |
279 | | |
280 | | typedef struct |
281 | | { |
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; |
288 | | |
289 | 0 | #define LBMPDM_DEFINITION_KEY_ELEMENT_COUNT 5 |
290 | 0 | #define LBMPDM_DEFINITION_KEY_ELEMENT_CHANNEL_HIGH 0 |
291 | 0 | #define LBMPDM_DEFINITION_KEY_ELEMENT_CHANNEL_LOW 1 |
292 | 0 | #define LBMPDM_DEFINITION_KEY_ELEMENT_ID 2 |
293 | 0 | #define LBMPDM_DEFINITION_KEY_ELEMENT_VERS_MAJOR 3 |
294 | 0 | #define LBMPDM_DEFINITION_KEY_ELEMENT_VERS_MINOR 4 |
295 | | |
296 | | static wmem_tree_t * lbmpdm_definition_table; |
297 | | |
298 | | /*----------------------------------------------------------------------------*/ |
299 | | /* Handles of all types. */ |
300 | | /*----------------------------------------------------------------------------*/ |
301 | | |
302 | | /* Protocol handle */ |
303 | | static int proto_lbmpdm; |
304 | | |
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; |
371 | | |
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; |
379 | | |
380 | | /*----------------------------------------------------------------------------*/ |
381 | | /* Value translation tables. */ |
382 | | /*----------------------------------------------------------------------------*/ |
383 | | |
384 | | /* Value tables */ |
385 | | static const value_string lbmpdm_field_type[] = |
386 | | { |
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 } |
426 | | }; |
427 | | |
428 | | static const value_string lbmpdm_next_header[] = |
429 | | { |
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 } |
435 | | }; |
436 | | |
437 | | static const value_string lbmpdm_field_name_type[] = |
438 | | { |
439 | | { PDM_DEFN_STR_FIELD_NAMES, "String" }, |
440 | | { PDM_DEFN_INT_FIELD_NAMES, "Integer" }, |
441 | | { 0x0, NULL } |
442 | | }; |
443 | | |
444 | | static const value_string lbmpdm_field_required[] = |
445 | | { |
446 | | { PDM_DEFN_OPTIONAL_FIELD, "Field is optional" }, |
447 | | { PDM_DEFN_REQUIRED_FIELD, "Field is required" }, |
448 | | { 0x0, NULL } |
449 | | }; |
450 | | |
451 | | static const value_string lbmpdm_field_fixed_length[] = |
452 | | { |
453 | | { PDM_DEFN_VARIABLE_LENGTH_FIELD, "Field is variable-length" }, |
454 | | { PDM_DEFN_FIXED_LENGTH_FIELD, "Field is fixed-length" }, |
455 | | { 0x0, NULL } |
456 | | }; |
457 | | |
458 | | static int lbmpdm_get_segment_length(tvbuff_t * tvb, int offset, int encoding, int * data_length) |
459 | 0 | { |
460 | 0 | uint32_t datalen = 0; |
461 | 0 | int seglen = 0; |
462 | |
|
463 | 0 | datalen = tvb_get_uint32(tvb, offset + O_LBMPDM_SEG_HDR_T_LEN, encoding); |
464 | 0 | seglen = ((int)datalen) + L_LBMPDM_SEG_HDR_T; |
465 | 0 | *data_length = (int) datalen; |
466 | 0 | return (seglen); |
467 | 0 | } |
468 | | |
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) |
470 | 0 | { |
471 | 0 | key_value[LBMPDM_DEFINITION_KEY_ELEMENT_CHANNEL_HIGH] = (uint32_t) ((channel >> 32) & 0xffffffff); |
472 | 0 | key_value[LBMPDM_DEFINITION_KEY_ELEMENT_CHANNEL_LOW] = (uint32_t) (channel & 0xffffffff); |
473 | 0 | key_value[LBMPDM_DEFINITION_KEY_ELEMENT_ID] = id; |
474 | 0 | key_value[LBMPDM_DEFINITION_KEY_ELEMENT_VERS_MAJOR] = version_major; |
475 | 0 | key_value[LBMPDM_DEFINITION_KEY_ELEMENT_VERS_MINOR] = version_minor; |
476 | 0 | key[0].length = LBMPDM_DEFINITION_KEY_ELEMENT_COUNT; |
477 | 0 | key[0].key = key_value; |
478 | 0 | key[1].length = 0; |
479 | 0 | key[1].key = NULL; |
480 | 0 | } |
481 | | |
482 | | static lbmpdm_definition_t * lbmpdm_definition_find(uint64_t channel, uint32_t ID, uint8_t version_major, uint8_t version_minor) |
483 | 0 | { |
484 | 0 | lbmpdm_definition_t * entry = NULL; |
485 | 0 | uint32_t keyval[LBMPDM_DEFINITION_KEY_ELEMENT_COUNT]; |
486 | 0 | wmem_tree_key_t tkey[2]; |
487 | |
|
488 | 0 | lbmpdm_definition_build_key(keyval, tkey, channel, ID, version_major, version_minor); |
489 | 0 | entry = (lbmpdm_definition_t *) wmem_tree_lookup32_array(lbmpdm_definition_table, tkey); |
490 | 0 | return (entry); |
491 | 0 | } |
492 | | |
493 | | static lbmpdm_definition_t * lbmpdm_definition_add(uint64_t channel, uint32_t id, uint8_t version_major, uint8_t version_minor) |
494 | 0 | { |
495 | 0 | lbmpdm_definition_t * entry = NULL; |
496 | 0 | uint32_t keyval[LBMPDM_DEFINITION_KEY_ELEMENT_COUNT]; |
497 | 0 | wmem_tree_key_t tkey[2]; |
498 | |
|
499 | 0 | entry = lbmpdm_definition_find(channel, id, version_major, version_minor); |
500 | 0 | if (entry != NULL) |
501 | 0 | { |
502 | 0 | return (entry); |
503 | 0 | } |
504 | 0 | entry = wmem_new(wmem_file_scope(), lbmpdm_definition_t); |
505 | 0 | entry->channel = channel; |
506 | 0 | entry->id = id; |
507 | 0 | entry->vers_major = version_major; |
508 | 0 | entry->vers_minor = version_minor; |
509 | 0 | entry->field_list = wmem_tree_new(wmem_file_scope()); |
510 | 0 | lbmpdm_definition_build_key(keyval, tkey, channel, id, version_major, version_minor); |
511 | 0 | wmem_tree_insert32_array(lbmpdm_definition_table, tkey, (void *) entry); |
512 | 0 | return (entry); |
513 | 0 | } |
514 | | |
515 | | static lbmpdm_definition_field_t * lbmpdm_definition_field_find(lbmpdm_definition_t * definition, uint32_t id) |
516 | 0 | { |
517 | 0 | lbmpdm_definition_field_t * entry = NULL; |
518 | |
|
519 | 0 | entry = (lbmpdm_definition_field_t *) wmem_tree_lookup32(definition->field_list, id); |
520 | 0 | return (entry); |
521 | 0 | } |
522 | | |
523 | | static lbmpdm_definition_field_t * lbmpdm_definition_field_add(lbmpdm_definition_t * definition, uint32_t id) |
524 | 0 | { |
525 | 0 | lbmpdm_definition_field_t * entry = NULL; |
526 | |
|
527 | 0 | entry = lbmpdm_definition_field_find(definition, id); |
528 | 0 | if (entry != NULL) |
529 | 0 | { |
530 | 0 | return (entry); |
531 | 0 | } |
532 | 0 | entry = wmem_new0(wmem_file_scope(), lbmpdm_definition_field_t); |
533 | 0 | entry->id = id; |
534 | 0 | entry->definition = definition; |
535 | 0 | wmem_tree_insert32(definition->field_list, id, (void *) entry); |
536 | 0 | return (entry); |
537 | 0 | } |
538 | | |
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) |
543 | 0 | { |
544 | 0 | switch (field_type) |
545 | 0 | { |
546 | 0 | case PDM_TYPE_BOOLEAN: |
547 | 0 | proto_tree_add_item(tree, hf_lbmpdm_field_value_boolean, tvb, offset, field_length, encoding); |
548 | 0 | break; |
549 | 0 | case PDM_TYPE_INT8: |
550 | 0 | proto_tree_add_item(tree, hf_lbmpdm_field_value_int8, tvb, offset, field_length, encoding); |
551 | 0 | break; |
552 | 0 | case PDM_TYPE_UINT8: |
553 | 0 | proto_tree_add_item(tree, hf_lbmpdm_field_value_uint8, tvb, offset, field_length, encoding); |
554 | 0 | break; |
555 | 0 | case PDM_TYPE_INT16: |
556 | 0 | proto_tree_add_item(tree, hf_lbmpdm_field_value_int16, tvb, offset, field_length, encoding); |
557 | 0 | break; |
558 | 0 | case PDM_TYPE_UINT16: |
559 | 0 | proto_tree_add_item(tree, hf_lbmpdm_field_value_uint16, tvb, offset, field_length, encoding); |
560 | 0 | break; |
561 | 0 | case PDM_TYPE_INT32: |
562 | 0 | proto_tree_add_item(tree, hf_lbmpdm_field_value_int32, tvb, offset, field_length, encoding); |
563 | 0 | break; |
564 | 0 | case PDM_TYPE_UINT32: |
565 | 0 | proto_tree_add_item(tree, hf_lbmpdm_field_value_uint32, tvb, offset, field_length, encoding); |
566 | 0 | break; |
567 | 0 | case PDM_TYPE_INT64: |
568 | 0 | proto_tree_add_item(tree, hf_lbmpdm_field_value_int64, tvb, offset, field_length, encoding); |
569 | 0 | break; |
570 | 0 | case PDM_TYPE_UINT64: |
571 | 0 | proto_tree_add_item(tree, hf_lbmpdm_field_value_uint64, tvb, offset, field_length, encoding); |
572 | 0 | break; |
573 | 0 | case PDM_TYPE_FLOAT: |
574 | 0 | proto_tree_add_item(tree, hf_lbmpdm_field_value_float, tvb, offset, field_length, encoding); |
575 | 0 | break; |
576 | 0 | case PDM_TYPE_DOUBLE: |
577 | 0 | proto_tree_add_item(tree, hf_lbmpdm_field_value_double, tvb, offset, field_length, encoding); |
578 | 0 | break; |
579 | 0 | case PDM_TYPE_DECIMAL: |
580 | 0 | { |
581 | 0 | int64_t mantissa; |
582 | 0 | int8_t exponent; |
583 | 0 | int64_t whole = 0; |
584 | 0 | uint64_t fraction = 0; |
585 | 0 | int8_t shift_count; |
586 | |
|
587 | 0 | exponent = tvb_get_int8(tvb, offset); |
588 | 0 | mantissa = tvb_get_int64(tvb, offset + 1, encoding); |
589 | 0 | if (exponent >= 0) |
590 | 0 | { |
591 | 0 | whole = mantissa; |
592 | 0 | shift_count = exponent; |
593 | 0 | while (shift_count > 0) |
594 | 0 | { |
595 | 0 | whole *= 10; |
596 | 0 | shift_count--; |
597 | 0 | } |
598 | 0 | proto_tree_add_none_format(tree, hf_lbmpdm_field_value_decimal, tvb, offset, field_length, |
599 | 0 | "DECIMAL Value: %" PRId64 " (%" PRId64 "e%d)", whole, mantissa, exponent); |
600 | 0 | } |
601 | 0 | else |
602 | 0 | { |
603 | 0 | uint64_t divisor = 1; |
604 | 0 | int decimal_digits = -exponent; |
605 | 0 | shift_count = decimal_digits; |
606 | 0 | while (shift_count > 0) |
607 | 0 | { |
608 | 0 | divisor *= 10; |
609 | 0 | shift_count--; |
610 | 0 | } |
611 | 0 | if (mantissa < 0) |
612 | 0 | { |
613 | 0 | whole = -mantissa; |
614 | 0 | } |
615 | 0 | else |
616 | 0 | { |
617 | 0 | whole = mantissa; |
618 | 0 | } |
619 | 0 | fraction = whole % divisor; |
620 | 0 | whole /= divisor; |
621 | 0 | if (mantissa < 0) |
622 | 0 | { |
623 | 0 | whole *= -1; |
624 | 0 | } |
625 | 0 | proto_tree_add_none_format(tree, hf_lbmpdm_field_value_decimal, tvb, offset, field_length, |
626 | 0 | "DECIMAL Value: %" PRId64 ".%0*" PRIu64 " (%" PRId64 "e%d)", |
627 | 0 | whole, decimal_digits, fraction, mantissa, exponent); |
628 | 0 | } |
629 | 0 | } |
630 | 0 | break; |
631 | 0 | case PDM_TYPE_TIMESTAMP: |
632 | 0 | { |
633 | 0 | nstime_t timestamp; |
634 | |
|
635 | 0 | timestamp.secs = (time_t)tvb_get_uint32(tvb, offset, encoding); |
636 | 0 | timestamp.nsecs = (int)(tvb_get_uint32(tvb, offset + 4, encoding) * 1000); |
637 | 0 | proto_tree_add_time(tree, hf_lbmpdm_field_value_timestamp, tvb, offset, field_length, ×tamp); |
638 | 0 | } |
639 | 0 | break; |
640 | 0 | case PDM_TYPE_FIX_STRING: |
641 | 0 | proto_tree_add_item(tree, hf_lbmpdm_field_value_fixed_string, tvb, offset, field_length, encoding); |
642 | 0 | break; |
643 | 0 | case PDM_TYPE_STRING: |
644 | 0 | proto_tree_add_item(tree, hf_lbmpdm_field_value_string, tvb, offset, field_length, encoding); |
645 | 0 | break; |
646 | 0 | case PDM_TYPE_FIX_UNICODE: |
647 | 0 | proto_tree_add_item(tree, hf_lbmpdm_field_value_fixed_unicode, tvb, offset, field_length, encoding); |
648 | 0 | break; |
649 | 0 | case PDM_TYPE_UNICODE: |
650 | 0 | proto_tree_add_item(tree, hf_lbmpdm_field_value_unicode, tvb, offset, field_length, encoding); |
651 | 0 | break; |
652 | 0 | case PDM_TYPE_BLOB: |
653 | 0 | proto_tree_add_item(tree, hf_lbmpdm_field_value_blob, tvb, offset, field_length, encoding); |
654 | 0 | break; |
655 | 0 | case PDM_TYPE_MESSAGE: |
656 | 0 | proto_tree_add_item(tree, hf_lbmpdm_field_value_message, tvb, offset, field_length, encoding); |
657 | 0 | break; |
658 | 0 | default: |
659 | 0 | break; |
660 | 0 | } |
661 | 0 | } |
662 | | |
663 | | static int dissect_field(tvbuff_t * tvb, int offset, proto_tree * tree, lbmpdm_definition_field_t * field, bool string_field_names, int encoding) |
664 | 0 | { |
665 | 0 | proto_item * field_item = NULL; |
666 | 0 | proto_tree * field_tree = NULL; |
667 | 0 | proto_item * ti = NULL; |
668 | 0 | int ofs = offset; |
669 | 0 | uint32_t element_count = 0; |
670 | 0 | uint32_t idx; |
671 | 0 | int len_dissected = 0; |
672 | |
|
673 | 0 | field_item = proto_tree_add_item(tree, hf_lbmpdm_field, tvb, offset, field->len, ENC_NA); |
674 | 0 | field_tree = proto_item_add_subtree(field_item, ett_lbmpdm_field); |
675 | 0 | ti = proto_tree_add_uint(field_tree, hf_lbmpdm_field_id, tvb, 0, 0, field->id); |
676 | 0 | proto_item_set_generated(ti); |
677 | 0 | if (string_field_names) |
678 | 0 | { |
679 | 0 | ti = proto_tree_add_string(field_tree, hf_lbmpdm_field_string_name, tvb, 0, 0, field->field_string_name); |
680 | 0 | } |
681 | 0 | else |
682 | 0 | { |
683 | 0 | ti = proto_tree_add_uint(field_tree, hf_lbmpdm_field_int_name, tvb, 0, 0, field->field_int_name); |
684 | 0 | } |
685 | 0 | proto_item_set_generated(ti); |
686 | 0 | ti = proto_tree_add_uint(field_tree, hf_lbmpdm_field_type, tvb, 0, 0, field->field_type); |
687 | 0 | proto_item_set_generated(ti); |
688 | 0 | if (field->num_array_elem == 0) |
689 | 0 | { |
690 | 0 | element_count = 1; |
691 | 0 | } |
692 | 0 | else |
693 | 0 | { |
694 | 0 | element_count = field->num_array_elem; |
695 | 0 | if (field->fixed == PDM_DEFN_VARIABLE_LENGTH_FIELD) |
696 | 0 | { |
697 | 0 | proto_tree_add_item(field_tree, hf_lbmpdm_field_total_length, tvb, ofs, 4, encoding); |
698 | 0 | len_dissected += 4; |
699 | 0 | ofs += 4; |
700 | 0 | } |
701 | 0 | } |
702 | 0 | for (idx = 0; idx < element_count; ++idx) |
703 | 0 | { |
704 | | /* field_len is length of the entire entry, including any length prefix. */ |
705 | 0 | uint32_t field_len = field->len / element_count; |
706 | | /* value_len is the length of the data only. */ |
707 | 0 | uint32_t value_len = field_len; |
708 | | /* value_offset is the offset of the actual value. */ |
709 | 0 | int value_offset = ofs; |
710 | |
|
711 | 0 | if (field->fixed == PDM_DEFN_VARIABLE_LENGTH_FIELD) |
712 | 0 | { |
713 | 0 | proto_tree_add_item(field_tree, hf_lbmpdm_field_length, tvb, ofs, 4, encoding); |
714 | 0 | value_len = tvb_get_uint32(tvb, ofs, encoding); |
715 | 0 | field_len = value_len + 4; |
716 | 0 | value_offset += 4; |
717 | 0 | } |
718 | 0 | else if (field->fixed_string_len > 0) |
719 | 0 | { |
720 | 0 | value_len = field->fixed_string_len; |
721 | 0 | } |
722 | 0 | dissect_field_value(tvb, value_offset, field_tree, field->base_type, value_len, encoding); |
723 | 0 | ofs += (int)field_len; |
724 | 0 | len_dissected += (int)field_len; |
725 | 0 | } |
726 | 0 | return (len_dissected); |
727 | 0 | } |
728 | | |
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) |
730 | 0 | { |
731 | 0 | proto_item * subtree_item = NULL; |
732 | 0 | proto_tree * subtree = NULL; |
733 | 0 | int datalen = 0; |
734 | 0 | int seglen = 0; |
735 | 0 | lbmpdm_definition_t * def = NULL; |
736 | |
|
737 | 0 | seglen = lbmpdm_get_segment_length(tvb, offset, encoding, &datalen); |
738 | 0 | subtree_item = proto_tree_add_none_format(tree, hf_lbmpdm_segment, tvb, offset, seglen, "Data Segment"); |
739 | 0 | subtree = proto_item_add_subtree(subtree_item, ett_lbmpdm_segment); |
740 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | if ((id != NULL) && (id->offset_table != NULL)) |
745 | 0 | { |
746 | 0 | def = lbmpdm_definition_find(id->channel, id->msg_def_id, id->ver_major, id->ver_minor); |
747 | 0 | } |
748 | 0 | if (def == NULL) |
749 | 0 | { |
750 | 0 | proto_tree_add_item(subtree, hf_lbmpdm_segment_data, tvb, offset + L_LBMPDM_SEG_HDR_T, datalen, ENC_NA); |
751 | 0 | } |
752 | 0 | else |
753 | 0 | { |
754 | 0 | int fld_offset = offset + L_LBMPDM_SEG_HDR_T; |
755 | 0 | lbmpdm_definition_field_t * field = NULL; |
756 | 0 | bool string_field_names = false; |
757 | 0 | uint32_t idx; |
758 | |
|
759 | 0 | if (def->field_names_type == PDM_DEFN_STR_FIELD_NAMES) |
760 | 0 | { |
761 | 0 | string_field_names = true; |
762 | 0 | } |
763 | 0 | else |
764 | 0 | { |
765 | 0 | string_field_names = false; |
766 | 0 | } |
767 | | |
768 | | /* Handle any fixed required fields first. */ |
769 | 0 | for (field = def->first_fixed_required; field != NULL; field = field->next_fixed_required) |
770 | 0 | { |
771 | 0 | fld_offset += dissect_field(tvb, fld_offset, subtree, field, string_field_names, encoding); |
772 | 0 | } |
773 | | /* Step through the offset table. */ |
774 | 0 | for (idx = 0; idx < id->offset_table->num_flds; ++idx) |
775 | 0 | { |
776 | 0 | int32_t ofs = id->offset_table->offset_list[idx]; |
777 | 0 | if (ofs != -1) |
778 | 0 | { |
779 | 0 | field = lbmpdm_definition_field_find(def, idx); |
780 | 0 | if (field != NULL) |
781 | 0 | { |
782 | 0 | (void)dissect_field(tvb, offset + L_LBMPDM_SEG_HDR_T + ofs, subtree, field, string_field_names, encoding); |
783 | 0 | } |
784 | 0 | } |
785 | 0 | } |
786 | 0 | } |
787 | 0 | return (seglen); |
788 | 0 | } |
789 | | |
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) |
791 | 0 | { |
792 | 0 | proto_item * subtree_item = NULL; |
793 | 0 | proto_tree * subtree = NULL; |
794 | 0 | int datalen = 0; |
795 | 0 | int seglen = 0; |
796 | 0 | int ofs = 0; |
797 | 0 | int field_count = 0; |
798 | 0 | int idx; |
799 | 0 | int32_t * id_list = NULL; |
800 | 0 | int32_t * ofs_list = NULL; |
801 | 0 | int32_t max_index = -1; |
802 | 0 | int32_t min_offset = INT32_MAX; |
803 | 0 | lbmpdm_offset_table_t * ofs_table = NULL; |
804 | |
|
805 | 0 | seglen = lbmpdm_get_segment_length(tvb, offset, encoding, &datalen); |
806 | 0 | subtree_item = proto_tree_add_none_format(tree, hf_lbmpdm_segment, tvb, offset, seglen, "Offset Table Segment"); |
807 | 0 | subtree = proto_item_add_subtree(subtree_item, ett_lbmpdm_segment); |
808 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | field_count = datalen / L_LBMPDM_OFFSET_ENTRY_T; |
813 | 0 | id_list = wmem_alloc_array(pinfo->pool, int32_t, field_count); |
814 | 0 | ofs_list = wmem_alloc_array(pinfo->pool, int32_t, field_count); |
815 | 0 | for (idx = 0; idx < field_count; ++idx) |
816 | 0 | { |
817 | 0 | id_list[idx] = -1; |
818 | 0 | ofs_list[idx] = -1; |
819 | 0 | } |
820 | 0 | ofs = offset + L_LBMPDM_SEG_HDR_T; |
821 | 0 | for (idx = 0; idx < field_count; idx++, ofs += L_LBMPDM_OFFSET_ENTRY_T) |
822 | 0 | { |
823 | 0 | proto_item * offset_item = NULL; |
824 | 0 | proto_tree * offset_tree = NULL; |
825 | |
|
826 | 0 | offset_item = proto_tree_add_item(subtree, hf_lbmpdm_offset_entry, tvb, ofs, L_LBMPDM_OFFSET_ENTRY_T, ENC_NA); |
827 | 0 | offset_tree = proto_item_add_subtree(offset_item, ett_lbmpdm_offset_entry); |
828 | 0 | 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 | 0 | id_list[idx] = (int32_t)tvb_get_uint32(tvb, ofs + O_LBMPDM_OFFSET_ENTRY_T_ID, encoding); |
830 | 0 | 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 | 0 | ofs_list[idx] = (int32_t)tvb_get_uint32(tvb, ofs + O_LBMPDM_OFFSET_ENTRY_T_OFFSET, encoding); |
832 | 0 | if (id_list[idx] < 0 || ofs_list[idx] < 0) { |
833 | 0 | THROW(ReportedBoundsError); |
834 | 0 | } |
835 | 0 | if (id_list[idx] > max_index) |
836 | 0 | { |
837 | 0 | max_index = id_list[idx]; |
838 | 0 | } |
839 | 0 | if (ofs_list[idx] < min_offset) |
840 | 0 | { |
841 | 0 | min_offset = ofs_list[idx]; |
842 | 0 | } |
843 | 0 | } |
844 | 0 | ofs_table = wmem_new(pinfo->pool, lbmpdm_offset_table_t); |
845 | 0 | ofs_table->num_flds = max_index + 1; |
846 | 0 | ofs_table->min_set_offset = NULL; |
847 | 0 | ofs_table->offset_list = wmem_alloc_array(pinfo->pool, int32_t, ofs_table->num_flds); |
848 | 0 | for (idx = 0; idx < (int)ofs_table->num_flds; ++idx) |
849 | 0 | { |
850 | 0 | ofs_table->offset_list[idx] = -1; |
851 | 0 | } |
852 | 0 | for (idx = 0; idx < field_count; ++idx) |
853 | 0 | { |
854 | 0 | ofs_table->offset_list[id_list[idx]] = ofs_list[idx]; |
855 | 0 | if (ofs_list[idx] == min_offset) |
856 | 0 | { |
857 | 0 | ofs_table->min_set_offset = &(ofs_table->offset_list[id_list[idx]]); |
858 | 0 | } |
859 | 0 | } |
860 | 0 | if (offset_table != NULL) |
861 | 0 | { |
862 | 0 | *offset_table = ofs_table; |
863 | 0 | } |
864 | 0 | return (seglen); |
865 | 0 | } |
866 | | |
867 | | static int dissect_segment_defn(tvbuff_t * tvb, int offset, packet_info * pinfo, proto_tree * tree, uint64_t channel, int encoding) |
868 | 0 | { |
869 | 0 | proto_item * subtree_item = NULL; |
870 | 0 | proto_tree * subtree = NULL; |
871 | 0 | int seglen = 0; |
872 | 0 | int ofs = 0; |
873 | 0 | bool string_field_name = false; |
874 | 0 | int remaining_datalen = 0; |
875 | 0 | uint32_t num_fields = 0; |
876 | 0 | lbmpdm_definition_t * def = NULL; |
877 | 0 | bool add_definition = false; |
878 | 0 | uint32_t def_id = 0; |
879 | 0 | uint8_t vers_major = 0; |
880 | 0 | uint8_t vers_minor = 0; |
881 | 0 | lbmpdm_definition_field_t * last_fixed_required_field = NULL; |
882 | |
|
883 | 0 | seglen = lbmpdm_get_segment_length(tvb, offset, encoding, &remaining_datalen); |
884 | 0 | if (pinfo->fd->visited == 0) |
885 | 0 | { |
886 | 0 | add_definition = true; |
887 | 0 | } |
888 | 0 | subtree_item = proto_tree_add_none_format(tree, hf_lbmpdm_segment, tvb, offset, seglen, "Definition Segment"); |
889 | 0 | subtree = proto_item_add_subtree(subtree_item, ett_lbmpdm_segment); |
890 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | ofs = offset + L_LBMPDM_SEG_HDR_T; |
895 | 0 | proto_tree_add_item(subtree, hf_lbmpdm_segment_def_id, tvb, ofs + O_LBMPDM_DEFN_T_ID, L_LBMPDM_DEFN_T_ID, encoding); |
896 | 0 | def_id = tvb_get_uint32(tvb, ofs + O_LBMPDM_DEFN_T_ID, encoding); |
897 | 0 | 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 | 0 | 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 | 0 | proto_tree_add_item(subtree, hf_lbmpdm_segment_def_finalized, tvb, ofs + O_LBMPDM_DEFN_T_FINALIZED, L_LBMPDM_DEFN_T_FINALIZED, encoding); |
900 | 0 | 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 | 0 | vers_major = tvb_get_uint8(tvb, ofs + O_LBMPDM_DEFN_T_MSG_VERS_MAJOR); |
902 | 0 | 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 | 0 | vers_minor = tvb_get_uint8(tvb, ofs + O_LBMPDM_DEFN_T_MSG_VERS_MINOR); |
904 | 0 | 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 | 0 | 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 | 0 | if (tvb_get_uint8(tvb, ofs + O_LBMPDM_DEFN_T_FIELD_NAMES_TYPE) == PDM_DEFN_STR_FIELD_NAMES) |
907 | 0 | { |
908 | 0 | string_field_name = true; |
909 | 0 | } |
910 | 0 | num_fields = tvb_get_uint32(tvb, ofs + O_LBMPDM_DEFN_T_NUM_FIELDS, encoding); |
911 | 0 | if (add_definition) |
912 | 0 | { |
913 | 0 | def = lbmpdm_definition_find(channel, def_id, vers_major, vers_minor); |
914 | 0 | if (def == NULL) |
915 | 0 | { |
916 | 0 | def = lbmpdm_definition_add(channel, def_id, vers_major, vers_minor); |
917 | 0 | def->num_fields = num_fields; |
918 | 0 | def->field_names_type = tvb_get_uint8(tvb, ofs + O_LBMPDM_DEFN_T_FIELD_NAMES_TYPE); |
919 | 0 | def->fixed_req_section_len = tvb_get_uint32(tvb, ofs + O_LBMPDM_DEFN_T_FIXED_REQ_SECTION_LEN, encoding); |
920 | 0 | def->first_fixed_required = NULL; |
921 | 0 | def->fixed_required_count = 0; |
922 | 0 | } |
923 | 0 | } |
924 | 0 | ofs += L_LBMPDM_DEFN_T; |
925 | 0 | remaining_datalen = seglen - L_LBMPDM_SEG_HDR_T - L_LBMPDM_DEFN_T; |
926 | 0 | while ((remaining_datalen > 0) && (num_fields > 0)) |
927 | 0 | { |
928 | 0 | proto_item * field_item = NULL; |
929 | 0 | proto_tree * field_tree = NULL; |
930 | 0 | uint32_t def_len = L_LBMPDM_FIELD_INFO_T_INT_NAME; |
931 | 0 | int def_ofs = 0; |
932 | 0 | int type_ofs = L_LBMPDM_FIELD_INFO_T; |
933 | 0 | uint32_t string_name_len = 0; |
934 | 0 | int string_name_ofs = -1; |
935 | |
|
936 | 0 | if (string_field_name) |
937 | 0 | { |
938 | 0 | def_len = tvb_get_uint32(tvb, ofs, encoding) + 4; |
939 | 0 | } |
940 | 0 | field_item = proto_tree_add_item(subtree, hf_lbmpdm_segment_def_field, tvb, ofs, def_len, ENC_NA); |
941 | 0 | field_tree = proto_item_add_subtree(field_item, ett_lbmpdm_segment_def_field); |
942 | 0 | if (string_field_name) |
943 | 0 | { |
944 | 0 | proto_tree_add_item(field_tree, hf_lbmpdm_segment_def_field_def_len, tvb, ofs, 4, encoding); |
945 | 0 | def_ofs = 4; |
946 | 0 | type_ofs += def_ofs; |
947 | 0 | } |
948 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | if (string_field_name) |
957 | 0 | { |
958 | 0 | string_name_len = tvb_get_uint32(tvb, ofs + def_ofs + O_LBMPDM_FIELD_INFO_T_STR_NAME_LEN, encoding); |
959 | 0 | if (string_name_len > 0) |
960 | 0 | { |
961 | 0 | string_name_ofs = ofs + def_ofs + L_LBMPDM_FIELD_INFO_T; |
962 | 0 | proto_tree_add_item(field_tree, hf_lbmpdm_segment_def_field_str_name, tvb, string_name_ofs, (int)string_name_len, ENC_ASCII); |
963 | 0 | type_ofs += string_name_len; |
964 | 0 | } |
965 | 0 | } |
966 | 0 | proto_tree_add_item(field_tree, hf_lbmpdm_segment_def_field_fld_type, tvb, ofs + type_ofs, 2, encoding); |
967 | 0 | if (add_definition && (def != NULL)) |
968 | 0 | { |
969 | 0 | lbmpdm_definition_field_t * field = NULL; |
970 | 0 | uint32_t field_id; |
971 | |
|
972 | 0 | field_id = tvb_get_uint32(tvb, ofs + def_ofs + O_LBMPDM_FIELD_INFO_T_ID, encoding); |
973 | 0 | field = lbmpdm_definition_field_find(def, field_id); |
974 | 0 | if (field == NULL) |
975 | 0 | { |
976 | 0 | field = lbmpdm_definition_field_add(def, field_id); |
977 | 0 | if (field != NULL) |
978 | 0 | { |
979 | 0 | field->len = tvb_get_uint32(tvb, ofs + def_ofs + O_LBMPDM_FIELD_INFO_T_LEN, encoding); |
980 | 0 | field->fixed_string_len = tvb_get_uint32(tvb, ofs + def_ofs + O_LBMPDM_FIELD_INFO_T_FIXED_STR_LEN, encoding); |
981 | 0 | field->num_array_elem = tvb_get_uint32(tvb, ofs + def_ofs + O_LBMPDM_FIELD_INFO_T_NUM_ARR_ELEM, encoding); |
982 | 0 | field->required = tvb_get_uint8(tvb, ofs + def_ofs + O_LBMPDM_FIELD_INFO_T_REQ); |
983 | 0 | field->fixed = tvb_get_uint8(tvb, ofs + def_ofs + O_LBMPDM_FIELD_INFO_T_FIXED); |
984 | 0 | field->field_int_name = tvb_get_uint32(tvb, ofs + def_ofs + O_LBMPDM_FIELD_INFO_T_FLD_INT_NAME, encoding); |
985 | 0 | if (string_field_name && (string_name_len > 0)) |
986 | 0 | { |
987 | 0 | field->field_string_name_len = string_name_len; |
988 | 0 | field->field_string_name = tvb_get_string_enc(wmem_file_scope(), tvb, string_name_ofs, string_name_len, ENC_ASCII); |
989 | 0 | } |
990 | 0 | else |
991 | 0 | { |
992 | 0 | field->field_string_name_len = 0; |
993 | 0 | field->field_string_name = NULL; |
994 | 0 | } |
995 | 0 | field->field_type = tvb_get_uint16(tvb, ofs + type_ofs, encoding); |
996 | 0 | switch (field->field_type) |
997 | 0 | { |
998 | 0 | case PDM_TYPE_BOOLEAN: |
999 | 0 | case PDM_TYPE_BOOLEAN_ARR: |
1000 | 0 | field->base_type = PDM_TYPE_BOOLEAN; |
1001 | 0 | break; |
1002 | 0 | case PDM_TYPE_INT8: |
1003 | 0 | case PDM_TYPE_INT8_ARR: |
1004 | 0 | field->base_type = PDM_TYPE_INT8; |
1005 | 0 | break; |
1006 | 0 | case PDM_TYPE_UINT8: |
1007 | 0 | case PDM_TYPE_UINT8_ARR: |
1008 | 0 | field->base_type = PDM_TYPE_UINT8; |
1009 | 0 | break; |
1010 | 0 | case PDM_TYPE_INT16: |
1011 | 0 | case PDM_TYPE_INT16_ARR: |
1012 | 0 | field->base_type = PDM_TYPE_INT16; |
1013 | 0 | break; |
1014 | 0 | case PDM_TYPE_UINT16: |
1015 | 0 | case PDM_TYPE_UINT16_ARR: |
1016 | 0 | field->base_type = PDM_TYPE_UINT16; |
1017 | 0 | break; |
1018 | 0 | case PDM_TYPE_INT32: |
1019 | 0 | case PDM_TYPE_INT32_ARR: |
1020 | 0 | field->base_type = PDM_TYPE_INT32; |
1021 | 0 | break; |
1022 | 0 | case PDM_TYPE_UINT32: |
1023 | 0 | case PDM_TYPE_UINT32_ARR: |
1024 | 0 | field->base_type = PDM_TYPE_UINT32; |
1025 | 0 | break; |
1026 | 0 | case PDM_TYPE_INT64: |
1027 | 0 | case PDM_TYPE_INT64_ARR: |
1028 | 0 | field->base_type = PDM_TYPE_INT64; |
1029 | 0 | break; |
1030 | 0 | case PDM_TYPE_UINT64: |
1031 | 0 | case PDM_TYPE_UINT64_ARR: |
1032 | 0 | field->base_type = PDM_TYPE_UINT64; |
1033 | 0 | break; |
1034 | 0 | case PDM_TYPE_FLOAT: |
1035 | 0 | case PDM_TYPE_FLOAT_ARR: |
1036 | 0 | field->base_type = PDM_TYPE_FLOAT; |
1037 | 0 | break; |
1038 | 0 | case PDM_TYPE_DOUBLE: |
1039 | 0 | case PDM_TYPE_DOUBLE_ARR: |
1040 | 0 | field->base_type = PDM_TYPE_DOUBLE; |
1041 | 0 | break; |
1042 | 0 | case PDM_TYPE_DECIMAL: |
1043 | 0 | case PDM_TYPE_DECIMAL_ARR: |
1044 | 0 | field->base_type = PDM_TYPE_DECIMAL; |
1045 | 0 | break; |
1046 | 0 | case PDM_TYPE_TIMESTAMP: |
1047 | 0 | case PDM_TYPE_TIMESTAMP_ARR: |
1048 | 0 | field->base_type = PDM_TYPE_TIMESTAMP; |
1049 | 0 | break; |
1050 | 0 | case PDM_TYPE_FIX_STRING: |
1051 | 0 | case PDM_TYPE_FIX_STRING_ARR: |
1052 | 0 | field->base_type = PDM_TYPE_FIX_STRING; |
1053 | 0 | break; |
1054 | 0 | case PDM_TYPE_STRING: |
1055 | 0 | case PDM_TYPE_STRING_ARR: |
1056 | 0 | field->base_type = PDM_TYPE_STRING; |
1057 | 0 | break; |
1058 | 0 | case PDM_TYPE_FIX_UNICODE: |
1059 | 0 | case PDM_TYPE_FIX_UNICODE_ARR: |
1060 | 0 | field->base_type = PDM_TYPE_FIX_UNICODE; |
1061 | 0 | break; |
1062 | 0 | case PDM_TYPE_UNICODE: |
1063 | 0 | case PDM_TYPE_UNICODE_ARR: |
1064 | 0 | field->base_type = PDM_TYPE_UNICODE; |
1065 | 0 | break; |
1066 | 0 | case PDM_TYPE_BLOB: |
1067 | 0 | case PDM_TYPE_BLOB_ARR: |
1068 | 0 | default: |
1069 | 0 | field->base_type = PDM_TYPE_BLOB; |
1070 | 0 | break; |
1071 | 0 | case PDM_TYPE_MESSAGE: |
1072 | 0 | case PDM_TYPE_MESSAGE_ARR: |
1073 | 0 | field->base_type = PDM_TYPE_MESSAGE; |
1074 | 0 | break; |
1075 | 0 | } |
1076 | 0 | if ((field->fixed == PDM_DEFN_FIXED_LENGTH_FIELD) && (field->required == PDM_DEFN_REQUIRED_FIELD)) |
1077 | 0 | { |
1078 | 0 | if (last_fixed_required_field == NULL) |
1079 | 0 | { |
1080 | 0 | def->first_fixed_required = field; |
1081 | 0 | field->fixed_required_offset = 0; |
1082 | 0 | } |
1083 | 0 | else |
1084 | 0 | { |
1085 | 0 | last_fixed_required_field->next_fixed_required = field; |
1086 | 0 | field->fixed_required_offset = last_fixed_required_field->fixed_required_offset + last_fixed_required_field->len; |
1087 | 0 | } |
1088 | 0 | last_fixed_required_field = field; |
1089 | 0 | def->fixed_required_count++; |
1090 | 0 | } |
1091 | 0 | } |
1092 | 0 | } |
1093 | 0 | } |
1094 | 0 | ofs += def_len; |
1095 | 0 | remaining_datalen -= def_len; |
1096 | 0 | num_fields--; |
1097 | 0 | } |
1098 | 0 | return (seglen); |
1099 | 0 | } |
1100 | | |
1101 | | static int dissect_segment_unknown(tvbuff_t * tvb, int offset, packet_info * pinfo _U_, proto_tree * tree, int encoding) |
1102 | 0 | { |
1103 | 0 | proto_item * subtree_item = NULL; |
1104 | 0 | proto_tree * subtree = NULL; |
1105 | 0 | int datalen = 0; |
1106 | 0 | int seglen = 0; |
1107 | |
|
1108 | 0 | seglen = lbmpdm_get_segment_length(tvb, offset, encoding, &datalen); |
1109 | 0 | subtree_item = proto_tree_add_none_format(tree, hf_lbmpdm_segment, tvb, offset, seglen, "Unknown Segment"); |
1110 | 0 | subtree = proto_item_add_subtree(subtree_item, ett_lbmpdm_segment); |
1111 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | proto_tree_add_item(subtree, hf_lbmpdm_segment_data, tvb, offset + L_LBMPDM_SEG_HDR_T, datalen, ENC_NA); |
1116 | 0 | return (seglen); |
1117 | 0 | } |
1118 | | |
1119 | | static bool check_lbmpdm_encoding(tvbuff_t * tvb, int offset, int * encoding) |
1120 | 1.15k | { |
1121 | 1.15k | uint8_t magic_byte_1; |
1122 | 1.15k | uint8_t magic_byte_2; |
1123 | 1.15k | uint8_t magic_byte_3; |
1124 | 1.15k | uint8_t magic_byte_4; |
1125 | 1.15k | bool result = true; |
1126 | | |
1127 | 1.15k | magic_byte_1 = tvb_get_uint8(tvb, offset); |
1128 | 1.15k | magic_byte_2 = tvb_get_uint8(tvb, offset + 1); |
1129 | 1.15k | magic_byte_3 = tvb_get_uint8(tvb, offset + 2); |
1130 | 1.15k | magic_byte_4 = tvb_get_uint8(tvb, offset + 3); |
1131 | 1.15k | if ((magic_byte_1 == PDM_MSG_HDR_BE_MAGIC_BYTE_1) && (magic_byte_2 == PDM_MSG_HDR_BE_MAGIC_BYTE_2) |
1132 | 1.15k | && (magic_byte_3 == PDM_MSG_HDR_BE_MAGIC_BYTE_3) && (magic_byte_4 == PDM_MSG_HDR_BE_MAGIC_BYTE_4)) |
1133 | 0 | { |
1134 | 0 | *encoding = ENC_BIG_ENDIAN; |
1135 | 0 | } |
1136 | 1.15k | else if ((magic_byte_1 == PDM_MSG_HDR_LE_MAGIC_BYTE_1) && (magic_byte_2 == PDM_MSG_HDR_LE_MAGIC_BYTE_2) |
1137 | 1.15k | && (magic_byte_3 == PDM_MSG_HDR_LE_MAGIC_BYTE_3) && (magic_byte_4 == PDM_MSG_HDR_LE_MAGIC_BYTE_4)) |
1138 | 0 | { |
1139 | 0 | *encoding = ENC_LITTLE_ENDIAN; |
1140 | 0 | } |
1141 | 1.15k | else |
1142 | 1.15k | { |
1143 | 1.15k | result = false; |
1144 | 1.15k | } |
1145 | 1.15k | return (result); |
1146 | 1.15k | } |
1147 | | |
1148 | | bool lbmpdm_verify_payload(tvbuff_t * tvb, int offset, int * encoding, int * length) |
1149 | 1.51k | { |
1150 | 1.51k | uint8_t next_header; |
1151 | 1.51k | uint32_t len = 0; |
1152 | | |
1153 | 1.51k | if (!tvb_bytes_exist(tvb, offset, L_LBMPDM_MSG_HDR_T)) |
1154 | 361 | { |
1155 | 361 | return false; |
1156 | 361 | } |
1157 | 1.15k | if (!check_lbmpdm_encoding(tvb, offset, encoding)) |
1158 | 1.15k | { |
1159 | 1.15k | return false; |
1160 | 1.15k | } |
1161 | 0 | next_header = tvb_get_uint8(tvb, offset + O_LBMPDM_MSG_HDR_T_NEXT_HDR); |
1162 | 0 | switch (next_header) |
1163 | 0 | { |
1164 | 0 | case PDM_HDR_TYPE_DATA: |
1165 | 0 | case PDM_HDR_TYPE_OFSTTBLE: |
1166 | 0 | case PDM_HDR_TYPE_DEFN: |
1167 | 0 | case PDM_HDR_TYPE_EOM: |
1168 | 0 | break; |
1169 | 0 | default: |
1170 | 0 | return false; |
1171 | 0 | } |
1172 | 0 | len = tvb_get_uint32(tvb, offset + O_LBMPDM_MSG_HDR_T_LEN, *encoding); |
1173 | 0 | if (len > INT_MAX) |
1174 | 0 | { |
1175 | 0 | return false; |
1176 | 0 | } |
1177 | 0 | *length = (int)len; |
1178 | 0 | return true; |
1179 | 0 | } |
1180 | | |
1181 | | int lbmpdm_dissect_lbmpdm_payload(tvbuff_t * tvb, int offset, packet_info * pinfo, proto_tree * tree, uint64_t channel) |
1182 | 0 | { |
1183 | 0 | proto_item * subtree_item = NULL; |
1184 | 0 | proto_tree * subtree = NULL; |
1185 | 0 | proto_item * segments_item = NULL; |
1186 | 0 | proto_tree * segments_tree = NULL; |
1187 | 0 | proto_item * pi = NULL; |
1188 | 0 | uint8_t next_hdr; |
1189 | 0 | int dissected_len = 0; |
1190 | 0 | int encoding; |
1191 | 0 | int msglen = 0; |
1192 | 0 | int len_remaining = 0; |
1193 | 0 | int ofs = 0; |
1194 | 0 | int segment_len = 0; |
1195 | 0 | int datalen = 0; |
1196 | 0 | uint32_t raw_msglen = 0; |
1197 | 0 | lbmpdm_msg_definition_id_t msgid; |
1198 | |
|
1199 | 0 | if (!lbmpdm_verify_payload(tvb, offset, &encoding, &raw_msglen)) |
1200 | 0 | { |
1201 | 0 | return 0; |
1202 | 0 | } |
1203 | 0 | msglen = (int)raw_msglen; |
1204 | |
|
1205 | 0 | msgid.channel = channel; |
1206 | 0 | msgid.offset_table = NULL; |
1207 | 0 | subtree_item = proto_tree_add_protocol_format(tree, proto_lbmpdm, tvb, offset, msglen, "LBMPDM Protocol"); |
1208 | 0 | subtree = proto_item_add_subtree(subtree_item, ett_lbmpdm); |
1209 | 0 | proto_tree_add_item(subtree, hf_lbmpdm_magic, tvb, offset + O_LBMPDM_MSG_HDR_T_MAGIC, L_LBMPDM_MSG_HDR_T_MAGIC, encoding); |
1210 | 0 | pi = proto_tree_add_string(subtree, hf_lbmpdm_encoding, tvb, offset + O_LBMPDM_MSG_HDR_T_MAGIC, L_LBMPDM_MSG_HDR_T_MAGIC, |
1211 | 0 | ((encoding == ENC_BIG_ENDIAN) ? "Big-Endian" : "Little-Endian")); |
1212 | 0 | proto_item_set_generated(pi); |
1213 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | msgid.ver_major = tvb_get_uint8(tvb, offset + O_LBMPDM_MSG_HDR_T_DEF_MAJOR_VER); |
1218 | 0 | 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 | 0 | msgid.ver_minor = tvb_get_uint8(tvb, offset + O_LBMPDM_MSG_HDR_T_DEF_MINOR_VER); |
1220 | 0 | 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 | 0 | msgid.msg_def_id = tvb_get_uint32(tvb, offset + O_LBMPDM_MSG_HDR_T_DEF_ID, encoding); |
1222 | 0 | proto_tree_add_item(subtree, hf_lbmpdm_len, tvb, offset + O_LBMPDM_MSG_HDR_T_LEN, L_LBMPDM_MSG_HDR_T_LEN, encoding); |
1223 | |
|
1224 | 0 | next_hdr = tvb_get_uint8(tvb, offset + O_LBMPDM_MSG_HDR_T_NEXT_HDR); |
1225 | 0 | len_remaining = msglen - L_LBMPDM_MSG_HDR_T; |
1226 | 0 | ofs = offset + L_LBMPDM_MSG_HDR_T; |
1227 | 0 | dissected_len = L_LBMPDM_MSG_HDR_T; |
1228 | 0 | datalen = msglen - L_LBMPDM_MSG_HDR_T; |
1229 | 0 | if (len_remaining > 0) |
1230 | 0 | { |
1231 | 0 | uint8_t this_hdr = next_hdr; |
1232 | |
|
1233 | 0 | segments_item = proto_tree_add_item(subtree, hf_lbmpdm_segments, tvb, ofs, datalen, encoding); |
1234 | 0 | segments_tree = proto_item_add_subtree(segments_item, ett_lbmpdm_segments); |
1235 | 0 | while ((this_hdr != PDM_HDR_TYPE_EOM) && (len_remaining >= L_LBMPDM_SEG_HDR_T)) |
1236 | 0 | { |
1237 | 0 | next_hdr = tvb_get_uint8(tvb, ofs + O_LBMPDM_SEG_HDR_T_NEXT_HDR); |
1238 | 0 | switch (this_hdr) |
1239 | 0 | { |
1240 | 0 | case PDM_HDR_TYPE_DATA: |
1241 | 0 | segment_len = dissect_segment_data(tvb, ofs, pinfo, segments_tree, &msgid, encoding); |
1242 | 0 | break; |
1243 | 0 | case PDM_HDR_TYPE_OFSTTBLE: |
1244 | 0 | segment_len = dissect_segment_ofstable(tvb, ofs, pinfo, segments_tree, &(msgid.offset_table), encoding); |
1245 | 0 | break; |
1246 | 0 | case PDM_HDR_TYPE_DEFN: |
1247 | 0 | segment_len = dissect_segment_defn(tvb, ofs, pinfo, segments_tree, channel, encoding); |
1248 | 0 | break; |
1249 | 0 | default: |
1250 | 0 | segment_len = dissect_segment_unknown(tvb, ofs, pinfo, segments_tree, encoding); |
1251 | 0 | break; |
1252 | 0 | } |
1253 | 0 | this_hdr = next_hdr; |
1254 | 0 | dissected_len += segment_len; |
1255 | 0 | len_remaining -= segment_len; |
1256 | 0 | ofs += segment_len; |
1257 | 0 | } |
1258 | 0 | } |
1259 | 0 | return (dissected_len); |
1260 | 0 | } |
1261 | | |
1262 | | int lbmpdm_get_minimum_length(void) |
1263 | 0 | { |
1264 | 0 | return (L_LBMPDM_MSG_HDR_T); |
1265 | 0 | } |
1266 | | |
1267 | | /* Register all the bits needed with the filtering engine */ |
1268 | | void proto_register_lbmpdm(void) |
1269 | 14 | { |
1270 | 14 | static hf_register_info hf[] = |
1271 | 14 | { |
1272 | 14 | { &hf_lbmpdm_magic, |
1273 | 14 | { "Magic", "lbmpdm.magic", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, |
1274 | 14 | { &hf_lbmpdm_encoding, |
1275 | 14 | { "Encoding", "lbmpdm.encoding", FT_STRING, BASE_NONE, NULL, 0x0, "encoding as determined by magic number", HFILL } }, |
1276 | 14 | { &hf_lbmpdm_ver, |
1277 | 14 | { "Version", "lbmpdm.ver", FT_UINT8, BASE_DEC, NULL, PDM_HDR_VER_TYPE_VER_MASK, NULL, HFILL } }, |
1278 | 14 | { &hf_lbmpdm_type, |
1279 | 14 | { "Type", "lbmpdm.type", FT_UINT8, BASE_DEC, NULL, PDM_HDR_VER_TYPE_TYPE_MASK, NULL, HFILL } }, |
1280 | 14 | { &hf_lbmpdm_next_hdr, |
1281 | 14 | { "Next Header", "lbmpdm.next_hdr", FT_UINT8, BASE_DEC_HEX, VALS(lbmpdm_next_header), 0x0, NULL, HFILL } }, |
1282 | 14 | { &hf_lbmpdm_def_major_ver, |
1283 | 14 | { "Definition Major Version", "lbmpdm.def_major_ver", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1284 | 14 | { &hf_lbmpdm_def_minor_ver, |
1285 | 14 | { "Definition Minor Version", "lbmpdm.def_minor_ver", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1286 | 14 | { &hf_lbmpdm_def_id, |
1287 | 14 | { "Definition ID", "lbmpdm.def_id", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1288 | 14 | { &hf_lbmpdm_len, |
1289 | 14 | { "Length", "lbmpdm.len", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1290 | 14 | { &hf_lbmpdm_segments, |
1291 | 14 | { "Segments", "lbmpdm.segments", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1292 | 14 | { &hf_lbmpdm_segment, |
1293 | 14 | { "Segment", "lbmpdm.segment", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1294 | 14 | { &hf_lbmpdm_segment_next_hdr, |
1295 | 14 | { "Next Header", "lbmpdm.segment.next_hdr", FT_UINT8, BASE_DEC_HEX, VALS(lbmpdm_next_header), 0x0, NULL, HFILL } }, |
1296 | 14 | { &hf_lbmpdm_segment_flags, |
1297 | 14 | { "Flags", "lbmpdm.segment.flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } }, |
1298 | 14 | { &hf_lbmpdm_segment_res, |
1299 | 14 | { "Reserved", "lbmpdm.segment.res", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } }, |
1300 | 14 | { &hf_lbmpdm_segment_len, |
1301 | 14 | { "Length", "lbmpdm.segment.len", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1302 | 14 | { &hf_lbmpdm_segment_def_id, |
1303 | 14 | { "Definition ID", "lbmpdm.segment_def.id", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1304 | 14 | { &hf_lbmpdm_segment_def_num_fields, |
1305 | 14 | { "Number Of Fields", "lbmpdm.segment_def.num_fields", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1306 | 14 | { &hf_lbmpdm_segment_def_field_names_type, |
1307 | 14 | { "Field Names Type", "lbmpdm.segment_def.field_names_type", FT_UINT8, BASE_HEX, VALS(lbmpdm_field_name_type), 0x0, NULL, HFILL } }, |
1308 | 14 | { &hf_lbmpdm_segment_def_finalized, |
1309 | 14 | { "Finalized", "lbmpdm.segment_def.finalized", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } }, |
1310 | 14 | { &hf_lbmpdm_segment_def_msg_vers_major, |
1311 | 14 | { "Definition Major Version", "lbmpdm.segment_def.msg_vers_major", FT_UINT8, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1312 | 14 | { &hf_lbmpdm_segment_def_msg_vers_minor, |
1313 | 14 | { "Definition Minor Version", "lbmpdm.segment_def.msg_vers_minor", FT_UINT8, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1314 | 14 | { &hf_lbmpdm_segment_def_fixed_req_section_len, |
1315 | 14 | { "Fixed Required Section Length", "lbmpdm.segment_def.fixed_req_section_len", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1316 | 14 | { &hf_lbmpdm_segment_def_field_info_len, |
1317 | 14 | { "Field Information Length", "lbmpdm.segment_def.field_info_len", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1318 | 14 | { &hf_lbmpdm_segment_def_field, |
1319 | 14 | { "Field Definition", "lbmpdm.segment_def.field", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1320 | 14 | { &hf_lbmpdm_segment_def_field_def_len, |
1321 | 14 | { "Definition Length", "lbmpdm.segment_def.field.def_len", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1322 | 14 | { &hf_lbmpdm_segment_def_field_id, |
1323 | 14 | { "ID", "lbmpdm.segment_def.field.id", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1324 | 14 | { &hf_lbmpdm_segment_def_field_len, |
1325 | 14 | { "Length", "lbmpdm.segment_def.field.len", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1326 | 14 | { &hf_lbmpdm_segment_def_field_fixed_str_len, |
1327 | 14 | { "Fixed String Length", "lbmpdm.segment_def.field.fixed_str_len", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1328 | 14 | { &hf_lbmpdm_segment_def_field_num_arr_elem, |
1329 | 14 | { "Number Of Array Elements", "lbmpdm.segment_def.field.num_arr_elem", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1330 | 14 | { &hf_lbmpdm_segment_def_field_req, |
1331 | 14 | { "Required", "lbmpdm.segment_def.field.req", FT_UINT8, BASE_HEX, VALS(lbmpdm_field_required), 0x0, NULL, HFILL } }, |
1332 | 14 | { &hf_lbmpdm_segment_def_field_fixed, |
1333 | 14 | { "Fixed Length Field", "lbmpdm.segment_def.field.fixed", FT_UINT8, BASE_HEX, VALS(lbmpdm_field_fixed_length), 0x0, NULL, HFILL } }, |
1334 | 14 | { &hf_lbmpdm_segment_def_field_fld_int_name, |
1335 | 14 | { "Field Integer Name", "lbmpdm.segment_def.field.fld_int_name", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1336 | 14 | { &hf_lbmpdm_segment_def_field_str_name_len, |
1337 | 14 | { "String Name Length", "lbmpdm.segment_def.field.str_name_len", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1338 | 14 | { &hf_lbmpdm_segment_def_field_str_name, |
1339 | 14 | { "String Name", "lbmpdm.segment_def.field.str_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1340 | 14 | { &hf_lbmpdm_segment_def_field_fld_type, |
1341 | 14 | { "Field Type", "lbmpdm.segment_def.field.fld_type", FT_UINT16, BASE_DEC_HEX, VALS(lbmpdm_field_type), 0x0, NULL, HFILL } }, |
1342 | 14 | { &hf_lbmpdm_offset_entry, |
1343 | 14 | { "Offset Entry", "lbmpdm.segment_ofs.entry", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1344 | 14 | { &hf_lbmpdm_offset_entry_id, |
1345 | 14 | { "ID", "lbmpdm.segment_ofs.entry.id", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1346 | 14 | { &hf_lbmpdm_offset_entry_offset, |
1347 | 14 | { "Offset", "lbmpdm.segment_ofs.entry.offset", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1348 | 14 | { &hf_lbmpdm_segment_data, |
1349 | 14 | { "Data", "lbmpdm.segment.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1350 | 14 | { &hf_lbmpdm_field, |
1351 | 14 | { "Field", "lbmpdm.field", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1352 | 14 | { &hf_lbmpdm_field_id, |
1353 | 14 | { "ID", "lbmpdm.field.id", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1354 | 14 | { &hf_lbmpdm_field_string_name, |
1355 | 14 | { "String Name", "lbmpdm.field.string_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1356 | 14 | { &hf_lbmpdm_field_int_name, |
1357 | 14 | { "Integer Name", "lbmpdm.field.int_name", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1358 | 14 | { &hf_lbmpdm_field_type, |
1359 | 14 | { "Type", "lbmpdm.field.type", FT_UINT16, BASE_DEC_HEX, VALS(lbmpdm_field_type), 0x0, NULL, HFILL } }, |
1360 | 14 | { &hf_lbmpdm_field_total_length, |
1361 | 14 | { "Total Length", "lbmpdm.field.total_length", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1362 | 14 | { &hf_lbmpdm_field_length, |
1363 | 14 | { "Length", "lbmpdm.field.length", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, NULL, HFILL } }, |
1364 | 14 | { &hf_lbmpdm_field_value_boolean, |
1365 | 14 | { "Boolean Value", "lbmpdm.field.value_boolean", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1366 | 14 | { &hf_lbmpdm_field_value_int8, |
1367 | 14 | { "INT8 Value", "lbmpdm.field.value_int8", FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1368 | 14 | { &hf_lbmpdm_field_value_uint8, |
1369 | 14 | { "UINT8 Value", "lbmpdm.field.value_uint8", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1370 | 14 | { &hf_lbmpdm_field_value_int16, |
1371 | 14 | { "INT16 Value", "lbmpdm.field.value_int16", FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1372 | 14 | { &hf_lbmpdm_field_value_uint16, |
1373 | 14 | { "UINT16 Value", "lbmpdm.field.value_uint16", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1374 | 14 | { &hf_lbmpdm_field_value_int32, |
1375 | 14 | { "INT32 Value", "lbmpdm.field.value_int32", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1376 | 14 | { &hf_lbmpdm_field_value_uint32, |
1377 | 14 | { "UINT32 Value", "lbmpdm.field.value_uint32", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1378 | 14 | { &hf_lbmpdm_field_value_int64, |
1379 | 14 | { "INT64 Value", "lbmpdm.field.value_int64", FT_INT64, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1380 | 14 | { &hf_lbmpdm_field_value_uint64, |
1381 | 14 | { "UINT64 Value", "lbmpdm.field.value_uint64", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } }, |
1382 | 14 | { &hf_lbmpdm_field_value_float, |
1383 | 14 | { "FLOAT Value", "lbmpdm.field.value_float", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1384 | 14 | { &hf_lbmpdm_field_value_double, |
1385 | 14 | { "DOUBLE Value", "lbmpdm.field.value_double", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1386 | 14 | { &hf_lbmpdm_field_value_decimal, |
1387 | 14 | { "DECIMAL Value", "lbmpdm.field.value_decimal", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1388 | 14 | { &hf_lbmpdm_field_value_timestamp, |
1389 | 14 | { "TIMESTAMP Value", "lbmpdm.field.value_timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL } }, |
1390 | 14 | { &hf_lbmpdm_field_value_fixed_string, |
1391 | 14 | { "FIXED STRING Value", "lbmpdm.field.value_fixed_string", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1392 | 14 | { &hf_lbmpdm_field_value_string, |
1393 | 14 | { "STRING Value", "lbmpdm.field.value_string", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1394 | 14 | { &hf_lbmpdm_field_value_fixed_unicode, |
1395 | 14 | { "FIXED UNICODE Value", "lbmpdm.field.value_fixed_unicode", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1396 | 14 | { &hf_lbmpdm_field_value_unicode, |
1397 | 14 | { "UNICODE Value", "lbmpdm.field.value_unicode", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1398 | 14 | { &hf_lbmpdm_field_value_blob, |
1399 | 14 | { "BLOB Value", "lbmpdm.field.value_blob", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |
1400 | 14 | { &hf_lbmpdm_field_value_message, |
1401 | 14 | { "MESSAGE Value", "lbmpdm.field.value_message", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } } |
1402 | 14 | }; |
1403 | 14 | static int * ett[] = |
1404 | 14 | { |
1405 | 14 | &ett_lbmpdm, |
1406 | 14 | &ett_lbmpdm_segments, |
1407 | 14 | &ett_lbmpdm_segment, |
1408 | 14 | &ett_lbmpdm_offset_entry, |
1409 | 14 | &ett_lbmpdm_segment_def_field, |
1410 | 14 | &ett_lbmpdm_field |
1411 | 14 | }; |
1412 | | |
1413 | 14 | proto_lbmpdm = proto_register_protocol("LBMPDM Protocol", "LBMPDM", "lbmpdm"); |
1414 | | |
1415 | 14 | proto_register_field_array(proto_lbmpdm, hf, array_length(hf)); |
1416 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
1417 | 14 | lbmpdm_definition_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); |
1418 | 14 | } |
1419 | | |
1420 | | /* |
1421 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
1422 | | * |
1423 | | * Local variables: |
1424 | | * c-basic-offset: 4 |
1425 | | * tab-width: 8 |
1426 | | * indent-tabs-mode: nil |
1427 | | * End: |
1428 | | * |
1429 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
1430 | | * :indentSize=4:tabSize=8:noTabs=true: |
1431 | | */ |