/src/wireshark/epan/dissectors/packet-yami.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* packet-yami.c |
2 | | * Routines for YAMI dissection |
3 | | * Copyright 2010, Pawel Korbut |
4 | | * Copyright 2012, Jakub Zawadzki <darkjames-ws@darkjames.pl> |
5 | | * |
6 | | * Protocol documentation available at http://www.inspirel.com/yami4/book/B-2.html |
7 | | * |
8 | | * Wireshark - Network traffic analyzer |
9 | | * By Gerald Combs <gerald@wireshark.org> |
10 | | * Copyright 1998 Gerald Combs |
11 | | * |
12 | | * SPDX-License-Identifier: GPL-2.0-or-later |
13 | | */ |
14 | | #include "config.h" |
15 | | |
16 | | #include <epan/packet.h> |
17 | | #include <epan/prefs.h> |
18 | | #include <epan/to_str.h> |
19 | | #include <wsutil/ws_roundup.h> |
20 | | #include "packet-tcp.h" |
21 | | |
22 | | void proto_reg_handoff_yami(void); |
23 | | void proto_register_yami(void); |
24 | | |
25 | | static bool yami_desegment = true; |
26 | | |
27 | | static dissector_handle_t yami_handle; |
28 | | |
29 | 0 | #define YAMI_TYPE_BOOLEAN 1 |
30 | 0 | #define YAMI_TYPE_INTEGER 2 |
31 | 0 | #define YAMI_TYPE_LONGLONG 3 |
32 | 0 | #define YAMI_TYPE_DOUBLE 4 |
33 | 0 | #define YAMI_TYPE_STRING 5 |
34 | 0 | #define YAMI_TYPE_BINARY 6 |
35 | 0 | #define YAMI_TYPE_BOOLEAN_ARRAY 7 |
36 | 0 | #define YAMI_TYPE_INTEGER_ARRAY 8 |
37 | 0 | #define YAMI_TYPE_LONGLONG_ARRAY 9 |
38 | 0 | #define YAMI_TYPE_DOUBLE_ARRAY 10 |
39 | 0 | #define YAMI_TYPE_STRING_ARRAY 11 |
40 | 0 | #define YAMI_TYPE_BINARY_ARRAY 12 |
41 | 0 | #define YAMI_TYPE_NESTED 13 |
42 | | |
43 | | static const value_string yami_param_type_vals[] = { |
44 | | { YAMI_TYPE_BOOLEAN, "boolean" }, |
45 | | { YAMI_TYPE_INTEGER, "integer" }, |
46 | | { YAMI_TYPE_LONGLONG, "long long" }, |
47 | | { YAMI_TYPE_DOUBLE, "double" }, |
48 | | { YAMI_TYPE_STRING, "string" }, |
49 | | { YAMI_TYPE_BINARY, "binary" }, |
50 | | { YAMI_TYPE_BOOLEAN_ARRAY, "boolean array" }, |
51 | | { YAMI_TYPE_INTEGER_ARRAY, "integer array" }, |
52 | | { YAMI_TYPE_LONGLONG_ARRAY, "long long array" }, |
53 | | { YAMI_TYPE_DOUBLE_ARRAY, "double array" }, |
54 | | { YAMI_TYPE_STRING_ARRAY, "string array" }, |
55 | | { YAMI_TYPE_BINARY_ARRAY, "binary array" }, |
56 | | { YAMI_TYPE_NESTED, "nested parameters" }, |
57 | | { 0, NULL } |
58 | | }; |
59 | | |
60 | | static int proto_yami; |
61 | | |
62 | | static int hf_yami_frame_number; |
63 | | static int hf_yami_frame_payload_size; |
64 | | static int hf_yami_items_count; |
65 | | static int hf_yami_message_data; |
66 | | static int hf_yami_message_hdr; |
67 | | static int hf_yami_message_header_size; |
68 | | static int hf_yami_message_id; |
69 | | static int hf_yami_param; |
70 | | static int hf_yami_param_name; |
71 | | static int hf_yami_param_type; |
72 | | static int hf_yami_param_value_bin; |
73 | | static int hf_yami_param_value_bool; |
74 | | static int hf_yami_param_value_double; |
75 | | static int hf_yami_param_value_int; |
76 | | static int hf_yami_param_value_long; |
77 | | static int hf_yami_param_value_str; |
78 | | static int hf_yami_params_count; |
79 | | |
80 | | static int ett_yami; |
81 | | static int ett_yami_msg_hdr; |
82 | | static int ett_yami_msg_data; |
83 | | static int ett_yami_param; |
84 | | |
85 | | static int |
86 | | // NOLINTNEXTLINE(misc-no-recursion) |
87 | | dissect_yami_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_item *par_ti) |
88 | 0 | { |
89 | 0 | const int orig_offset = offset; |
90 | |
|
91 | 0 | proto_tree *yami_param; |
92 | 0 | proto_item *ti; |
93 | |
|
94 | 0 | char *name; |
95 | 0 | int name_offset; |
96 | 0 | uint32_t name_len; |
97 | |
|
98 | 0 | uint32_t type; |
99 | |
|
100 | 0 | ti = proto_tree_add_item(tree, hf_yami_param, tvb, offset, 0, ENC_NA); |
101 | 0 | yami_param = proto_item_add_subtree(ti, ett_yami_param); |
102 | |
|
103 | 0 | name_offset = offset; |
104 | 0 | name_len = tvb_get_letohl(tvb, offset); |
105 | 0 | offset += 4; |
106 | |
|
107 | 0 | name = tvb_get_string_enc(pinfo->pool, tvb, offset, name_len, ENC_ASCII | ENC_NA); |
108 | 0 | proto_item_append_text(ti, ": %s", name); |
109 | 0 | proto_item_append_text(par_ti, "%s, ", name); |
110 | 0 | offset += WS_ROUNDUP_4(name_len); |
111 | 0 | proto_tree_add_string(yami_param, hf_yami_param_name, tvb, name_offset, offset - name_offset, name); |
112 | |
|
113 | 0 | type = tvb_get_letohl(tvb, offset); |
114 | 0 | proto_tree_add_item(yami_param, hf_yami_param_type, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
115 | 0 | offset += 4; |
116 | |
|
117 | 0 | switch (type) { |
118 | 0 | case YAMI_TYPE_BOOLEAN: |
119 | 0 | { |
120 | 0 | uint32_t val = tvb_get_letohl(tvb, offset); |
121 | 0 | proto_item_append_text(ti, ", Type: boolean, Value: %s", val ? "True" : "False"); |
122 | 0 | proto_tree_add_item(yami_param, hf_yami_param_value_bool, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
123 | 0 | offset += 4; |
124 | 0 | break; |
125 | 0 | } |
126 | | |
127 | 0 | case YAMI_TYPE_INTEGER: |
128 | 0 | { |
129 | 0 | int32_t val = tvb_get_letohl(tvb, offset); |
130 | 0 | proto_item_append_text(ti, ", Type: integer, Value: %d", val); |
131 | 0 | proto_tree_add_item(yami_param, hf_yami_param_value_int, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
132 | 0 | offset += 4; |
133 | 0 | break; |
134 | 0 | } |
135 | | |
136 | 0 | case YAMI_TYPE_LONGLONG: |
137 | 0 | { |
138 | 0 | int64_t val = tvb_get_letoh64(tvb, offset); |
139 | 0 | proto_item_append_text(ti, ", Type: long, Value: %" PRId64, val); |
140 | 0 | proto_tree_add_item(yami_param, hf_yami_param_value_long, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
141 | 0 | offset += 8; |
142 | 0 | break; |
143 | 0 | } |
144 | | |
145 | 0 | case YAMI_TYPE_DOUBLE: |
146 | 0 | { |
147 | 0 | double val = tvb_get_letohieee_double(tvb, offset); |
148 | 0 | proto_item_append_text(ti, ", Type: double, Value: %g", val); |
149 | 0 | proto_tree_add_item(yami_param, hf_yami_param_value_double, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
150 | 0 | offset += 8; |
151 | 0 | break; |
152 | 0 | } |
153 | | |
154 | 0 | case YAMI_TYPE_STRING: |
155 | 0 | { |
156 | 0 | const int val_offset = offset; |
157 | 0 | uint32_t val_len; |
158 | 0 | char *val; |
159 | |
|
160 | 0 | val_len = tvb_get_letohl(tvb, offset); |
161 | 0 | offset += 4; |
162 | |
|
163 | 0 | val = tvb_get_string_enc(pinfo->pool, tvb, offset, val_len, ENC_ASCII | ENC_NA); |
164 | |
|
165 | 0 | proto_item_append_text(ti, ", Type: string, Value: \"%s\"", val); |
166 | 0 | offset += WS_ROUNDUP_4(val_len); |
167 | 0 | proto_tree_add_string(yami_param, hf_yami_param_value_str, tvb, val_offset, offset - val_offset, val); |
168 | 0 | break; |
169 | 0 | } |
170 | | |
171 | 0 | case YAMI_TYPE_BINARY: |
172 | 0 | { |
173 | 0 | const int val_offset = offset; |
174 | 0 | uint32_t val_len; |
175 | 0 | const uint8_t *val; |
176 | 0 | char *repr; |
177 | |
|
178 | 0 | val_len = tvb_get_letohl(tvb, offset); |
179 | 0 | offset += 4; |
180 | |
|
181 | 0 | val = tvb_get_ptr(tvb, offset, val_len); |
182 | 0 | repr = bytes_to_str(pinfo->pool, val, val_len); |
183 | |
|
184 | 0 | proto_item_append_text(ti, ", Type: binary, Value: %s", repr); |
185 | 0 | offset += WS_ROUNDUP_4(val_len); |
186 | 0 | proto_tree_add_bytes_format_value(yami_param, hf_yami_param_value_bin, tvb, val_offset, offset - val_offset, val, "%s", repr); |
187 | 0 | break; |
188 | 0 | } |
189 | | |
190 | 0 | case YAMI_TYPE_BOOLEAN_ARRAY: |
191 | 0 | { |
192 | 0 | uint32_t count; |
193 | 0 | unsigned i; |
194 | 0 | int j; |
195 | |
|
196 | 0 | count = tvb_get_letohl(tvb, offset); |
197 | 0 | proto_tree_add_item(yami_param, hf_yami_items_count, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
198 | 0 | offset += 4; |
199 | |
|
200 | 0 | proto_item_append_text(ti, ", Type: boolean[], %u items: {", count); |
201 | |
|
202 | 0 | for (i = 0; i < count/32; i++) { |
203 | 0 | uint32_t val = tvb_get_letohl(tvb, offset); |
204 | |
|
205 | 0 | for (j = 0; j < 32; j++) { |
206 | 0 | int r = !!(val & (1U << j)); |
207 | |
|
208 | 0 | proto_item_append_text(ti, "%s, ", r ? "T" : "F"); |
209 | 0 | proto_tree_add_boolean(yami_param, hf_yami_param_value_bool, tvb, offset+(j/8), 1, r); |
210 | 0 | } |
211 | 0 | offset += 4; |
212 | 0 | } |
213 | |
|
214 | 0 | if (count % 32) { |
215 | 0 | uint32_t val = tvb_get_letohl(tvb, offset); |
216 | 0 | int tmp = count % 32; |
217 | |
|
218 | 0 | for (j = 0; j < tmp; j++) { |
219 | 0 | int r = !!(val & (1 << j)); |
220 | |
|
221 | 0 | proto_item_append_text(ti, "%s, ", r ? "T" : "F"); |
222 | 0 | proto_tree_add_boolean(yami_param, hf_yami_param_value_bool, tvb, offset+(j/8), 1, r); |
223 | 0 | } |
224 | 0 | offset += 4; |
225 | 0 | } |
226 | |
|
227 | 0 | proto_item_append_text(ti, "}"); |
228 | 0 | break; |
229 | 0 | } |
230 | | |
231 | 0 | case YAMI_TYPE_INTEGER_ARRAY: |
232 | 0 | { |
233 | 0 | uint32_t count; |
234 | 0 | unsigned i; |
235 | |
|
236 | 0 | count = tvb_get_letohl(tvb, offset); |
237 | 0 | proto_tree_add_item(yami_param, hf_yami_items_count, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
238 | 0 | offset += 4; |
239 | |
|
240 | 0 | proto_item_append_text(ti, ", Type: integer[], %u items: {", count); |
241 | 0 | for (i = 0; i < count; i++) { |
242 | 0 | int32_t val = tvb_get_letohl(tvb, offset); |
243 | |
|
244 | 0 | proto_item_append_text(ti, "%d, ", val); |
245 | 0 | proto_tree_add_item(yami_param, hf_yami_param_value_int, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
246 | 0 | offset += 4; |
247 | 0 | } |
248 | 0 | proto_item_append_text(ti, "}"); |
249 | 0 | break; |
250 | 0 | } |
251 | | |
252 | 0 | case YAMI_TYPE_LONGLONG_ARRAY: |
253 | 0 | { |
254 | 0 | uint32_t count; |
255 | 0 | unsigned i; |
256 | |
|
257 | 0 | count = tvb_get_letohl(tvb, offset); |
258 | 0 | proto_tree_add_item(yami_param, hf_yami_items_count, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
259 | 0 | offset += 4; |
260 | |
|
261 | 0 | proto_item_append_text(ti, ", Type: long long[], %u items: {", count); |
262 | |
|
263 | 0 | for (i = 0; i < count; i++) { |
264 | 0 | int64_t val = tvb_get_letoh64(tvb, offset); |
265 | |
|
266 | 0 | proto_item_append_text(ti, "%" PRId64 ", ", val); |
267 | 0 | proto_tree_add_item(yami_param, hf_yami_param_value_long, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
268 | 0 | offset += 8; |
269 | 0 | } |
270 | 0 | proto_item_append_text(ti, "}"); |
271 | 0 | break; |
272 | 0 | } |
273 | | |
274 | 0 | case YAMI_TYPE_DOUBLE_ARRAY: |
275 | 0 | { |
276 | 0 | uint32_t count; |
277 | 0 | unsigned i; |
278 | |
|
279 | 0 | count = tvb_get_letohl(tvb, offset); |
280 | 0 | proto_tree_add_item(yami_param, hf_yami_items_count, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
281 | 0 | offset += 4; |
282 | |
|
283 | 0 | proto_item_append_text(ti, ", Type: double[], %u items: {", count); |
284 | |
|
285 | 0 | for (i = 0; i < count; i++) { |
286 | 0 | double val = tvb_get_letohieee_double(tvb, offset); |
287 | |
|
288 | 0 | proto_item_append_text(ti, "%g, ", val); |
289 | 0 | proto_tree_add_item(yami_param, hf_yami_param_value_double, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
290 | 0 | offset += 8; |
291 | 0 | } |
292 | 0 | proto_item_append_text(ti, "}"); |
293 | 0 | break; |
294 | 0 | } |
295 | | |
296 | 0 | case YAMI_TYPE_STRING_ARRAY: |
297 | 0 | { |
298 | 0 | uint32_t count; |
299 | 0 | unsigned i; |
300 | |
|
301 | 0 | count = tvb_get_letohl(tvb, offset); |
302 | 0 | proto_tree_add_item(yami_param, hf_yami_items_count, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
303 | 0 | offset += 4; |
304 | |
|
305 | 0 | proto_item_append_text(ti, ", Type: string[], %u items: {", count); |
306 | |
|
307 | 0 | for (i = 0; i < count; i++) { |
308 | 0 | const int val_offset = offset; |
309 | 0 | uint32_t val_len; |
310 | 0 | char *val; |
311 | |
|
312 | 0 | val_len = tvb_get_letohl(tvb, offset); |
313 | 0 | offset += 4; |
314 | |
|
315 | 0 | val = tvb_get_string_enc(pinfo->pool, tvb, offset, val_len, ENC_ASCII | ENC_NA); |
316 | |
|
317 | 0 | proto_item_append_text(ti, "\"%s\", ", val); |
318 | 0 | proto_tree_add_string(yami_param, hf_yami_param_value_str, tvb, val_offset, offset - val_offset, val); |
319 | 0 | offset += WS_ROUNDUP_4(val_len); |
320 | 0 | } |
321 | 0 | proto_item_append_text(ti, "}"); |
322 | 0 | break; |
323 | 0 | } |
324 | | |
325 | 0 | case YAMI_TYPE_BINARY_ARRAY: |
326 | 0 | { |
327 | 0 | uint32_t count; |
328 | 0 | unsigned i; |
329 | |
|
330 | 0 | count = tvb_get_letohl(tvb, offset); |
331 | 0 | proto_tree_add_item(yami_param, hf_yami_items_count, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
332 | 0 | offset += 4; |
333 | |
|
334 | 0 | proto_item_append_text(ti, ", Type: binary[], %u items: {", count); |
335 | |
|
336 | 0 | for (i = 0; i < count; i++) { |
337 | 0 | const int val_offset = offset; |
338 | 0 | uint32_t val_len; |
339 | 0 | const uint8_t *val; |
340 | 0 | char *repr; |
341 | |
|
342 | 0 | val_len = tvb_get_letohl(tvb, offset); |
343 | 0 | offset += 4; |
344 | |
|
345 | 0 | val = tvb_get_ptr(tvb, offset, val_len); |
346 | 0 | repr = bytes_to_str(pinfo->pool, val, val_len); |
347 | |
|
348 | 0 | proto_item_append_text(ti, "%s, ", repr); |
349 | 0 | offset += WS_ROUNDUP_4(val_len); |
350 | 0 | proto_tree_add_bytes_format_value(yami_param, hf_yami_param_value_bin, tvb, val_offset, offset - val_offset, val, "%s", repr); |
351 | 0 | } |
352 | 0 | proto_item_append_text(ti, "}"); |
353 | 0 | break; |
354 | 0 | } |
355 | | |
356 | 0 | case YAMI_TYPE_NESTED: |
357 | 0 | { |
358 | 0 | uint32_t count; |
359 | 0 | unsigned i; |
360 | |
|
361 | 0 | count = tvb_get_letohl(tvb, offset); |
362 | 0 | proto_tree_add_item(yami_param, hf_yami_params_count, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
363 | 0 | offset += 4; |
364 | |
|
365 | 0 | proto_item_append_text(ti, ", Type: nested, %u parameters: ", count); |
366 | |
|
367 | 0 | for (i = 0; i < count; i++) { |
368 | 0 | increment_dissection_depth(pinfo); |
369 | 0 | offset = dissect_yami_parameter(tvb, pinfo, yami_param, offset, ti); |
370 | 0 | decrement_dissection_depth(pinfo); |
371 | | /* smth went wrong */ |
372 | 0 | if (offset == -1) |
373 | 0 | return -1; |
374 | 0 | } |
375 | 0 | break; |
376 | 0 | } |
377 | | |
378 | 0 | default: |
379 | 0 | proto_item_append_text(ti, ", Type: unknown (%d)!", type); |
380 | 0 | return -1; |
381 | 0 | } |
382 | | |
383 | 0 | proto_item_set_len(ti, offset - orig_offset); |
384 | 0 | return offset; |
385 | 0 | } |
386 | | |
387 | | static int |
388 | | dissect_yami_data(tvbuff_t *tvb, packet_info *pinfo, bool data, proto_tree *tree, int offset) |
389 | 0 | { |
390 | 0 | const int orig_offset = offset; |
391 | |
|
392 | 0 | proto_tree *yami_data_tree; |
393 | 0 | proto_item *ti; |
394 | |
|
395 | 0 | uint32_t count; |
396 | 0 | unsigned i; |
397 | |
|
398 | 0 | ti = proto_tree_add_item(tree, (data) ? hf_yami_message_data : hf_yami_message_hdr, tvb, offset, 0, ENC_NA); |
399 | 0 | yami_data_tree = proto_item_add_subtree(ti, (data) ? ett_yami_msg_data : ett_yami_msg_hdr); |
400 | |
|
401 | 0 | count = tvb_get_letohl(tvb, offset); |
402 | 0 | proto_tree_add_item(yami_data_tree, hf_yami_params_count, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
403 | 0 | offset += 4; |
404 | |
|
405 | 0 | proto_item_append_text(ti, ", %u parameters: ", count); |
406 | |
|
407 | 0 | for (i = 0; i < count; i++) { |
408 | 0 | offset = dissect_yami_parameter(tvb, pinfo, yami_data_tree, offset, ti); |
409 | | /* smth went wrong */ |
410 | 0 | if (offset == -1) |
411 | 0 | return -1; |
412 | 0 | } |
413 | | |
414 | 0 | proto_item_set_len(ti, offset - orig_offset); |
415 | |
|
416 | 0 | return offset; |
417 | 0 | } |
418 | | |
419 | | static int |
420 | | dissect_yami_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
421 | 0 | { |
422 | 0 | proto_tree *yami_tree; |
423 | 0 | proto_item *ti; |
424 | |
|
425 | 0 | int frame_number; |
426 | 0 | int message_header_size; |
427 | 0 | int frame_payload_size; |
428 | 0 | int frame_size; |
429 | 0 | int offset; |
430 | |
|
431 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "YAMI"); |
432 | 0 | col_clear(pinfo->cinfo, COL_INFO); |
433 | |
|
434 | 0 | ti = proto_tree_add_item(tree, proto_yami, tvb, 0, -1, ENC_NA); |
435 | 0 | yami_tree = proto_item_add_subtree(ti, ett_yami); |
436 | |
|
437 | 0 | offset = 0; |
438 | |
|
439 | 0 | proto_tree_add_item(yami_tree, hf_yami_message_id, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
440 | 0 | offset += 4; |
441 | |
|
442 | 0 | frame_number = tvb_get_letohl(tvb, offset); |
443 | 0 | ti = proto_tree_add_item(yami_tree, hf_yami_frame_number, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
444 | 0 | if(frame_number < 0) |
445 | 0 | proto_item_append_text(ti, "%s", " (last frame)"); |
446 | 0 | offset += 4; |
447 | |
|
448 | 0 | message_header_size = tvb_get_letohl(tvb, offset); |
449 | 0 | proto_tree_add_item(yami_tree, hf_yami_message_header_size, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
450 | 0 | if (message_header_size < 4) { |
451 | | /* XXX, expert info */ |
452 | 0 | } |
453 | 0 | offset += 4; |
454 | |
|
455 | 0 | frame_payload_size = tvb_get_letohl(tvb, offset); |
456 | 0 | ti = proto_tree_add_item(yami_tree, hf_yami_frame_payload_size, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
457 | 0 | frame_size = frame_payload_size + 16; |
458 | 0 | proto_item_append_text(ti, ", (YAMI Frame Size: %d)", frame_size); |
459 | 0 | offset += 4; |
460 | |
|
461 | 0 | if (frame_number == 1 || frame_number == -1) { |
462 | 0 | if (message_header_size <= frame_payload_size) { |
463 | 0 | const int orig_offset = offset; |
464 | |
|
465 | 0 | offset = dissect_yami_data(tvb, pinfo, false, yami_tree, offset); |
466 | 0 | if (offset != orig_offset + message_header_size) { |
467 | | /* XXX, expert info */ |
468 | 0 | offset = orig_offset + message_header_size; |
469 | 0 | } |
470 | |
|
471 | 0 | dissect_yami_data(tvb, pinfo, true, yami_tree, offset); |
472 | 0 | } |
473 | 0 | } |
474 | |
|
475 | 0 | return tvb_captured_length(tvb); |
476 | 0 | } |
477 | | |
478 | 0 | #define FRAME_HEADER_LEN 16 |
479 | | |
480 | | static unsigned |
481 | | get_yami_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, |
482 | | int offset, void *data _U_) |
483 | 0 | { |
484 | 0 | uint32_t len = tvb_get_letohl(tvb, offset + 12); |
485 | |
|
486 | 0 | return len + FRAME_HEADER_LEN; |
487 | 0 | } |
488 | | |
489 | | static int |
490 | | dissect_yami(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
491 | 0 | { |
492 | 0 | tcp_dissect_pdus(tvb, pinfo, tree, yami_desegment, FRAME_HEADER_LEN, get_yami_message_len, dissect_yami_pdu, data); |
493 | 0 | return tvb_captured_length(tvb); |
494 | 0 | } |
495 | | |
496 | | void |
497 | | proto_register_yami(void) |
498 | 14 | { |
499 | 14 | static hf_register_info hf[] = { |
500 | 14 | { &hf_yami_message_id, |
501 | 14 | { "Message ID", "yami.message_id", |
502 | 14 | FT_INT32, BASE_DEC, NULL, 0x00, |
503 | 14 | NULL, HFILL } |
504 | 14 | }, |
505 | 14 | { &hf_yami_frame_number, |
506 | 14 | { "Frame Number", "yami.frame_number", |
507 | 14 | FT_INT32, BASE_DEC, NULL, 0x00, |
508 | 14 | NULL, HFILL } |
509 | 14 | }, |
510 | 14 | { &hf_yami_message_header_size, |
511 | 14 | { "Message Header Size", "yami.message_header_size", |
512 | 14 | FT_INT32, BASE_DEC, NULL, 0x00, |
513 | 14 | NULL, HFILL } |
514 | 14 | }, |
515 | 14 | { &hf_yami_frame_payload_size, |
516 | 14 | { "Frame Payload Size", "yami.frame_payload_size", |
517 | 14 | FT_INT32, BASE_DEC, NULL, 0x00, |
518 | 14 | NULL, HFILL } |
519 | 14 | }, |
520 | 14 | { &hf_yami_message_hdr, |
521 | 14 | { "Header message", "yami.msg_hdr", |
522 | 14 | FT_NONE, BASE_NONE, NULL, 0x00, |
523 | 14 | NULL, HFILL } |
524 | 14 | }, |
525 | 14 | { &hf_yami_message_data, |
526 | 14 | { "Data message", "yami.msg_data", |
527 | 14 | FT_NONE, BASE_NONE, NULL, 0x00, |
528 | 14 | NULL, HFILL } |
529 | 14 | }, |
530 | 14 | { &hf_yami_param, |
531 | 14 | { "Parameter", "yami.param", |
532 | 14 | FT_NONE, BASE_NONE, NULL, 0x00, |
533 | 14 | NULL, HFILL } |
534 | 14 | }, |
535 | 14 | { &hf_yami_param_name, |
536 | 14 | { "Name", "yami.param.name", |
537 | 14 | FT_STRING, BASE_NONE, NULL, 0x00, |
538 | 14 | "Parameter name", HFILL } |
539 | 14 | }, |
540 | 14 | { &hf_yami_param_type, |
541 | 14 | { "Type", "yami.param.type", |
542 | 14 | FT_INT32, BASE_DEC, VALS(yami_param_type_vals), 0x00, |
543 | 14 | "Parameter type", HFILL } |
544 | 14 | }, |
545 | 14 | { &hf_yami_param_value_bool, |
546 | 14 | { "Value", "yami.param.value_bool", |
547 | 14 | FT_BOOLEAN, BASE_NONE, NULL, 0x00, |
548 | 14 | "Parameter value (bool)", HFILL } |
549 | 14 | }, |
550 | 14 | { &hf_yami_param_value_int, |
551 | 14 | { "Value", "yami.param.value_int", |
552 | 14 | FT_INT32, BASE_DEC, NULL, 0x00, |
553 | 14 | "Parameter value (int)", HFILL } |
554 | 14 | }, |
555 | 14 | { &hf_yami_param_value_long, |
556 | 14 | { "Value", "yami.param.value_long", |
557 | 14 | FT_INT64, BASE_DEC, NULL, 0x00, |
558 | 14 | "Parameter value (long)", HFILL } |
559 | 14 | }, |
560 | 14 | { &hf_yami_param_value_double, |
561 | 14 | { "Value", "yami.param.value_double", |
562 | 14 | FT_DOUBLE, BASE_NONE, NULL, 0x00, |
563 | 14 | "Parameter value (double)", HFILL } |
564 | 14 | }, |
565 | 14 | { &hf_yami_param_value_str, |
566 | 14 | { "Value", "yami.param.value_str", |
567 | 14 | FT_STRING, BASE_NONE, NULL, 0x00, |
568 | 14 | "Parameter value (string)", HFILL } |
569 | 14 | }, |
570 | 14 | { &hf_yami_param_value_bin, |
571 | 14 | { "Value", "yami.param.value_bin", |
572 | 14 | FT_BYTES, BASE_NONE, NULL, 0x00, |
573 | 14 | "Parameter value (binary)", HFILL } |
574 | 14 | }, |
575 | 14 | { &hf_yami_params_count, |
576 | 14 | { "Parameters count", "yami.params_count", |
577 | 14 | FT_UINT32, BASE_DEC, NULL, 0x00, |
578 | 14 | NULL, HFILL } |
579 | 14 | }, |
580 | 14 | { &hf_yami_items_count, |
581 | 14 | { "Items count", "yami.items_count", |
582 | 14 | FT_UINT32, BASE_DEC, NULL, 0x00, |
583 | 14 | NULL, HFILL } |
584 | 14 | }, |
585 | 14 | }; |
586 | | |
587 | 14 | static int *ett[] = { |
588 | 14 | &ett_yami, |
589 | 14 | &ett_yami_msg_hdr, |
590 | 14 | &ett_yami_msg_data, |
591 | 14 | &ett_yami_param |
592 | 14 | }; |
593 | | |
594 | 14 | module_t *yami_module; |
595 | | |
596 | 14 | proto_yami = proto_register_protocol("YAMI Protocol", "YAMI", "yami"); |
597 | | |
598 | 14 | proto_register_field_array(proto_yami, hf, array_length(hf)); |
599 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
600 | | |
601 | 14 | yami_module = prefs_register_protocol(proto_yami, NULL); |
602 | 14 | prefs_register_bool_preference(yami_module, "desegment", |
603 | 14 | "Reassemble YAMI messages spanning multiple TCP segments", |
604 | 14 | "Whether the YAMI dissector should reassemble messages spanning multiple TCP segments." |
605 | 14 | "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.", |
606 | 14 | &yami_desegment); |
607 | | |
608 | 14 | yami_handle = register_dissector("yami", dissect_yami, proto_yami); |
609 | 14 | } |
610 | | |
611 | | void |
612 | | proto_reg_handoff_yami(void) |
613 | 14 | { |
614 | 14 | dissector_add_for_decode_as_with_preference("tcp.port", yami_handle); |
615 | 14 | dissector_add_for_decode_as_with_preference("udp.port", yami_handle); |
616 | 14 | } |
617 | | |
618 | | /* |
619 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
620 | | * |
621 | | * Local variables: |
622 | | * c-basic-offset: 8 |
623 | | * tab-width: 8 |
624 | | * indent-tabs-mode: t |
625 | | * End: |
626 | | * |
627 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
628 | | * :indentSize=8:tabSize=8:noTabs=false: |
629 | | */ |