/src/wireshark/epan/dissectors/packet-yami.c
Line | Count | Source |
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 | | /* coverity[sanitize] */ |
105 | 0 | name_len = tvb_get_letohl(tvb, offset); |
106 | 0 | offset += 4; |
107 | |
|
108 | 0 | name = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, name_len, ENC_ASCII | ENC_NA); |
109 | 0 | proto_item_append_text(ti, ": %s", name); |
110 | 0 | proto_item_append_text(par_ti, "%s, ", name); |
111 | 0 | offset += WS_ROUNDUP_4(name_len); |
112 | 0 | proto_tree_add_string(yami_param, hf_yami_param_name, tvb, name_offset, offset - name_offset, name); |
113 | |
|
114 | 0 | proto_tree_add_item_ret_uint(yami_param, hf_yami_param_type, tvb, offset, 4, ENC_LITTLE_ENDIAN, &type); |
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 | | /* coverity[sanitize] */ |
161 | 0 | val_len = tvb_get_letohl(tvb, offset); |
162 | 0 | offset += 4; |
163 | |
|
164 | 0 | val = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, val_len, ENC_ASCII | ENC_NA); |
165 | |
|
166 | 0 | proto_item_append_text(ti, ", Type: string, Value: \"%s\"", val); |
167 | 0 | offset += WS_ROUNDUP_4(val_len); |
168 | 0 | proto_tree_add_string(yami_param, hf_yami_param_value_str, tvb, val_offset, offset - val_offset, val); |
169 | 0 | break; |
170 | 0 | } |
171 | | |
172 | 0 | case YAMI_TYPE_BINARY: |
173 | 0 | { |
174 | 0 | const int val_offset = offset; |
175 | 0 | uint32_t val_len; |
176 | 0 | const uint8_t *val; |
177 | 0 | char *repr; |
178 | |
|
179 | 0 | val_len = tvb_get_letohl(tvb, offset); |
180 | 0 | offset += 4; |
181 | |
|
182 | 0 | val = tvb_get_ptr(tvb, offset, val_len); |
183 | 0 | repr = bytes_to_str(pinfo->pool, val, val_len); |
184 | |
|
185 | 0 | proto_item_append_text(ti, ", Type: binary, Value: %s", repr); |
186 | 0 | offset += WS_ROUNDUP_4(val_len); |
187 | 0 | proto_tree_add_bytes_format_value(yami_param, hf_yami_param_value_bin, tvb, val_offset, offset - val_offset, val, "%s", repr); |
188 | 0 | break; |
189 | 0 | } |
190 | | |
191 | 0 | case YAMI_TYPE_BOOLEAN_ARRAY: |
192 | 0 | { |
193 | 0 | uint32_t count; |
194 | 0 | unsigned i; |
195 | 0 | int j; |
196 | |
|
197 | 0 | proto_tree_add_item_ret_uint(yami_param, hf_yami_items_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &count); |
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 | proto_tree_add_item_ret_uint(yami_param, hf_yami_items_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &count); |
237 | 0 | offset += 4; |
238 | |
|
239 | 0 | proto_item_append_text(ti, ", Type: integer[], %u items: {", count); |
240 | 0 | for (i = 0; i < count; i++) { |
241 | 0 | int32_t val = tvb_get_letohl(tvb, offset); |
242 | |
|
243 | 0 | proto_item_append_text(ti, "%d, ", val); |
244 | 0 | proto_tree_add_item(yami_param, hf_yami_param_value_int, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
245 | 0 | offset += 4; |
246 | 0 | } |
247 | 0 | proto_item_append_text(ti, "}"); |
248 | 0 | break; |
249 | 0 | } |
250 | | |
251 | 0 | case YAMI_TYPE_LONGLONG_ARRAY: |
252 | 0 | { |
253 | 0 | uint32_t count; |
254 | 0 | unsigned i; |
255 | |
|
256 | 0 | proto_tree_add_item_ret_uint(yami_param, hf_yami_items_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &count); |
257 | 0 | offset += 4; |
258 | |
|
259 | 0 | proto_item_append_text(ti, ", Type: long long[], %u items: {", count); |
260 | |
|
261 | 0 | for (i = 0; i < count; i++) { |
262 | 0 | int64_t val = tvb_get_letoh64(tvb, offset); |
263 | |
|
264 | 0 | proto_item_append_text(ti, "%" PRId64 ", ", val); |
265 | 0 | proto_tree_add_item(yami_param, hf_yami_param_value_long, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
266 | 0 | offset += 8; |
267 | 0 | } |
268 | 0 | proto_item_append_text(ti, "}"); |
269 | 0 | break; |
270 | 0 | } |
271 | | |
272 | 0 | case YAMI_TYPE_DOUBLE_ARRAY: |
273 | 0 | { |
274 | 0 | uint32_t count; |
275 | 0 | unsigned i; |
276 | |
|
277 | 0 | proto_tree_add_item_ret_uint(yami_param, hf_yami_items_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &count); |
278 | 0 | offset += 4; |
279 | |
|
280 | 0 | proto_item_append_text(ti, ", Type: double[], %u items: {", count); |
281 | |
|
282 | 0 | for (i = 0; i < count; i++) { |
283 | 0 | double val = tvb_get_letohieee_double(tvb, offset); |
284 | |
|
285 | 0 | proto_item_append_text(ti, "%g, ", val); |
286 | 0 | proto_tree_add_item(yami_param, hf_yami_param_value_double, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
287 | 0 | offset += 8; |
288 | 0 | } |
289 | 0 | proto_item_append_text(ti, "}"); |
290 | 0 | break; |
291 | 0 | } |
292 | | |
293 | 0 | case YAMI_TYPE_STRING_ARRAY: |
294 | 0 | { |
295 | 0 | uint32_t count; |
296 | 0 | unsigned i; |
297 | |
|
298 | 0 | proto_tree_add_item_ret_uint(yami_param, hf_yami_items_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &count); |
299 | 0 | offset += 4; |
300 | |
|
301 | 0 | proto_item_append_text(ti, ", Type: string[], %u items: {", count); |
302 | |
|
303 | 0 | for (i = 0; i < count; i++) { |
304 | 0 | const int val_offset = offset; |
305 | 0 | uint32_t val_len; |
306 | 0 | char *val; |
307 | | |
308 | | /* coverity[sanitize] */ |
309 | 0 | val_len = tvb_get_letohl(tvb, offset); |
310 | 0 | offset += 4; |
311 | |
|
312 | 0 | val = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, val_len, ENC_ASCII | ENC_NA); |
313 | |
|
314 | 0 | proto_item_append_text(ti, "\"%s\", ", val); |
315 | 0 | proto_tree_add_string(yami_param, hf_yami_param_value_str, tvb, val_offset, offset - val_offset, val); |
316 | 0 | offset += WS_ROUNDUP_4(val_len); |
317 | 0 | } |
318 | 0 | proto_item_append_text(ti, "}"); |
319 | 0 | break; |
320 | 0 | } |
321 | | |
322 | 0 | case YAMI_TYPE_BINARY_ARRAY: |
323 | 0 | { |
324 | 0 | uint32_t count; |
325 | 0 | unsigned i; |
326 | |
|
327 | 0 | proto_tree_add_item_ret_uint(yami_param, hf_yami_items_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &count); |
328 | 0 | offset += 4; |
329 | |
|
330 | 0 | proto_item_append_text(ti, ", Type: binary[], %u items: {", count); |
331 | |
|
332 | 0 | for (i = 0; i < count; i++) { |
333 | 0 | const int val_offset = offset; |
334 | 0 | uint32_t val_len; |
335 | 0 | const uint8_t *val; |
336 | 0 | char *repr; |
337 | |
|
338 | 0 | val_len = tvb_get_letohl(tvb, offset); |
339 | 0 | offset += 4; |
340 | |
|
341 | 0 | val = tvb_get_ptr(tvb, offset, val_len); |
342 | 0 | repr = bytes_to_str(pinfo->pool, val, val_len); |
343 | |
|
344 | 0 | proto_item_append_text(ti, "%s, ", repr); |
345 | 0 | offset += WS_ROUNDUP_4(val_len); |
346 | 0 | proto_tree_add_bytes_format_value(yami_param, hf_yami_param_value_bin, tvb, val_offset, offset - val_offset, val, "%s", repr); |
347 | 0 | } |
348 | 0 | proto_item_append_text(ti, "}"); |
349 | 0 | break; |
350 | 0 | } |
351 | | |
352 | 0 | case YAMI_TYPE_NESTED: |
353 | 0 | { |
354 | 0 | uint32_t count; |
355 | 0 | unsigned i; |
356 | |
|
357 | 0 | proto_tree_add_item_ret_uint(yami_param, hf_yami_params_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &count); |
358 | 0 | offset += 4; |
359 | |
|
360 | 0 | proto_item_append_text(ti, ", Type: nested, %u parameters: ", count); |
361 | |
|
362 | 0 | for (i = 0; i < count; i++) { |
363 | 0 | increment_dissection_depth(pinfo); |
364 | 0 | offset = dissect_yami_parameter(tvb, pinfo, yami_param, offset, ti); |
365 | 0 | decrement_dissection_depth(pinfo); |
366 | | /* smth went wrong */ |
367 | 0 | if (offset == -1) |
368 | 0 | return -1; |
369 | 0 | } |
370 | 0 | break; |
371 | 0 | } |
372 | | |
373 | 0 | default: |
374 | 0 | proto_item_append_text(ti, ", Type: unknown (%d)!", type); |
375 | 0 | return -1; |
376 | 0 | } |
377 | | |
378 | 0 | proto_item_set_len(ti, offset - orig_offset); |
379 | 0 | return offset; |
380 | 0 | } |
381 | | |
382 | | static int |
383 | | dissect_yami_data(tvbuff_t *tvb, packet_info *pinfo, bool data, proto_tree *tree, int offset) |
384 | 0 | { |
385 | 0 | const int orig_offset = offset; |
386 | |
|
387 | 0 | proto_tree *yami_data_tree; |
388 | 0 | proto_item *ti; |
389 | |
|
390 | 0 | uint32_t count; |
391 | 0 | unsigned i; |
392 | |
|
393 | 0 | ti = proto_tree_add_item(tree, (data) ? hf_yami_message_data : hf_yami_message_hdr, tvb, offset, 0, ENC_NA); |
394 | 0 | yami_data_tree = proto_item_add_subtree(ti, (data) ? ett_yami_msg_data : ett_yami_msg_hdr); |
395 | |
|
396 | 0 | proto_tree_add_item_ret_uint(yami_data_tree, hf_yami_params_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &count); |
397 | 0 | offset += 4; |
398 | |
|
399 | 0 | proto_item_append_text(ti, ", %u parameters: ", count); |
400 | |
|
401 | 0 | for (i = 0; i < count; i++) { |
402 | 0 | offset = dissect_yami_parameter(tvb, pinfo, yami_data_tree, offset, ti); |
403 | | /* smth went wrong */ |
404 | 0 | if (offset == -1) |
405 | 0 | return -1; |
406 | 0 | } |
407 | | |
408 | 0 | proto_item_set_len(ti, offset - orig_offset); |
409 | |
|
410 | 0 | return offset; |
411 | 0 | } |
412 | | |
413 | | static int |
414 | | dissect_yami_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
415 | 0 | { |
416 | 0 | proto_tree *yami_tree; |
417 | 0 | proto_item *ti; |
418 | |
|
419 | 0 | int frame_number; |
420 | 0 | int message_header_size; |
421 | 0 | int frame_payload_size; |
422 | 0 | int frame_size; |
423 | 0 | int offset; |
424 | |
|
425 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "YAMI"); |
426 | 0 | col_clear(pinfo->cinfo, COL_INFO); |
427 | |
|
428 | 0 | ti = proto_tree_add_item(tree, proto_yami, tvb, 0, -1, ENC_NA); |
429 | 0 | yami_tree = proto_item_add_subtree(ti, ett_yami); |
430 | |
|
431 | 0 | offset = 0; |
432 | |
|
433 | 0 | proto_tree_add_item(yami_tree, hf_yami_message_id, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
434 | 0 | offset += 4; |
435 | |
|
436 | 0 | ti = proto_tree_add_item_ret_int(yami_tree, hf_yami_frame_number, tvb, offset, 4, ENC_LITTLE_ENDIAN, &frame_number); |
437 | 0 | if(frame_number < 0) |
438 | 0 | proto_item_append_text(ti, "%s", " (last frame)"); |
439 | 0 | offset += 4; |
440 | |
|
441 | 0 | proto_tree_add_item_ret_int(yami_tree, hf_yami_message_header_size, tvb, offset, 4, ENC_LITTLE_ENDIAN, &message_header_size); |
442 | 0 | if (message_header_size < 4) { |
443 | | /* XXX, expert info */ |
444 | 0 | } |
445 | 0 | offset += 4; |
446 | |
|
447 | 0 | ti = proto_tree_add_item_ret_int(yami_tree, hf_yami_frame_payload_size, tvb, offset, 4, ENC_LITTLE_ENDIAN, &frame_payload_size); |
448 | 0 | frame_size = frame_payload_size + 16; |
449 | 0 | proto_item_append_text(ti, ", (YAMI Frame Size: %d)", frame_size); |
450 | 0 | offset += 4; |
451 | |
|
452 | 0 | if (frame_number == 1 || frame_number == -1) { |
453 | 0 | if (message_header_size <= frame_payload_size) { |
454 | 0 | const int orig_offset = offset; |
455 | |
|
456 | 0 | offset = dissect_yami_data(tvb, pinfo, false, yami_tree, offset); |
457 | 0 | if (offset != orig_offset + message_header_size) { |
458 | | /* XXX, expert info */ |
459 | 0 | offset = orig_offset + message_header_size; |
460 | 0 | } |
461 | |
|
462 | 0 | dissect_yami_data(tvb, pinfo, true, yami_tree, offset); |
463 | 0 | } |
464 | 0 | } |
465 | |
|
466 | 0 | return tvb_captured_length(tvb); |
467 | 0 | } |
468 | | |
469 | 0 | #define FRAME_HEADER_LEN 16 |
470 | | |
471 | | static unsigned |
472 | | get_yami_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, |
473 | | int offset, void *data _U_) |
474 | 0 | { |
475 | 0 | uint32_t len = tvb_get_letohl(tvb, offset + 12); |
476 | |
|
477 | 0 | return len + FRAME_HEADER_LEN; |
478 | 0 | } |
479 | | |
480 | | static int |
481 | | dissect_yami(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
482 | 0 | { |
483 | 0 | tcp_dissect_pdus(tvb, pinfo, tree, yami_desegment, FRAME_HEADER_LEN, get_yami_message_len, dissect_yami_pdu, data); |
484 | 0 | return tvb_captured_length(tvb); |
485 | 0 | } |
486 | | |
487 | | void |
488 | | proto_register_yami(void) |
489 | 15 | { |
490 | 15 | static hf_register_info hf[] = { |
491 | 15 | { &hf_yami_message_id, |
492 | 15 | { "Message ID", "yami.message_id", |
493 | 15 | FT_INT32, BASE_DEC, NULL, 0x00, |
494 | 15 | NULL, HFILL } |
495 | 15 | }, |
496 | 15 | { &hf_yami_frame_number, |
497 | 15 | { "Frame Number", "yami.frame_number", |
498 | 15 | FT_INT32, BASE_DEC, NULL, 0x00, |
499 | 15 | NULL, HFILL } |
500 | 15 | }, |
501 | 15 | { &hf_yami_message_header_size, |
502 | 15 | { "Message Header Size", "yami.message_header_size", |
503 | 15 | FT_INT32, BASE_DEC, NULL, 0x00, |
504 | 15 | NULL, HFILL } |
505 | 15 | }, |
506 | 15 | { &hf_yami_frame_payload_size, |
507 | 15 | { "Frame Payload Size", "yami.frame_payload_size", |
508 | 15 | FT_INT32, BASE_DEC, NULL, 0x00, |
509 | 15 | NULL, HFILL } |
510 | 15 | }, |
511 | 15 | { &hf_yami_message_hdr, |
512 | 15 | { "Header message", "yami.msg_hdr", |
513 | 15 | FT_NONE, BASE_NONE, NULL, 0x00, |
514 | 15 | NULL, HFILL } |
515 | 15 | }, |
516 | 15 | { &hf_yami_message_data, |
517 | 15 | { "Data message", "yami.msg_data", |
518 | 15 | FT_NONE, BASE_NONE, NULL, 0x00, |
519 | 15 | NULL, HFILL } |
520 | 15 | }, |
521 | 15 | { &hf_yami_param, |
522 | 15 | { "Parameter", "yami.param", |
523 | 15 | FT_NONE, BASE_NONE, NULL, 0x00, |
524 | 15 | NULL, HFILL } |
525 | 15 | }, |
526 | 15 | { &hf_yami_param_name, |
527 | 15 | { "Name", "yami.param.name", |
528 | 15 | FT_STRING, BASE_NONE, NULL, 0x00, |
529 | 15 | "Parameter name", HFILL } |
530 | 15 | }, |
531 | 15 | { &hf_yami_param_type, |
532 | 15 | { "Type", "yami.param.type", |
533 | 15 | FT_UINT32, BASE_DEC, VALS(yami_param_type_vals), 0x00, |
534 | 15 | "Parameter type", HFILL } |
535 | 15 | }, |
536 | 15 | { &hf_yami_param_value_bool, |
537 | 15 | { "Value", "yami.param.value_bool", |
538 | 15 | FT_BOOLEAN, BASE_NONE, NULL, 0x00, |
539 | 15 | "Parameter value (bool)", HFILL } |
540 | 15 | }, |
541 | 15 | { &hf_yami_param_value_int, |
542 | 15 | { "Value", "yami.param.value_int", |
543 | 15 | FT_INT32, BASE_DEC, NULL, 0x00, |
544 | 15 | "Parameter value (int)", HFILL } |
545 | 15 | }, |
546 | 15 | { &hf_yami_param_value_long, |
547 | 15 | { "Value", "yami.param.value_long", |
548 | 15 | FT_INT64, BASE_DEC, NULL, 0x00, |
549 | 15 | "Parameter value (long)", HFILL } |
550 | 15 | }, |
551 | 15 | { &hf_yami_param_value_double, |
552 | 15 | { "Value", "yami.param.value_double", |
553 | 15 | FT_DOUBLE, BASE_NONE, NULL, 0x00, |
554 | 15 | "Parameter value (double)", HFILL } |
555 | 15 | }, |
556 | 15 | { &hf_yami_param_value_str, |
557 | 15 | { "Value", "yami.param.value_str", |
558 | 15 | FT_STRING, BASE_NONE, NULL, 0x00, |
559 | 15 | "Parameter value (string)", HFILL } |
560 | 15 | }, |
561 | 15 | { &hf_yami_param_value_bin, |
562 | 15 | { "Value", "yami.param.value_bin", |
563 | 15 | FT_BYTES, BASE_NONE, NULL, 0x00, |
564 | 15 | "Parameter value (binary)", HFILL } |
565 | 15 | }, |
566 | 15 | { &hf_yami_params_count, |
567 | 15 | { "Parameters count", "yami.params_count", |
568 | 15 | FT_UINT32, BASE_DEC, NULL, 0x00, |
569 | 15 | NULL, HFILL } |
570 | 15 | }, |
571 | 15 | { &hf_yami_items_count, |
572 | 15 | { "Items count", "yami.items_count", |
573 | 15 | FT_UINT32, BASE_DEC, NULL, 0x00, |
574 | 15 | NULL, HFILL } |
575 | 15 | }, |
576 | 15 | }; |
577 | | |
578 | 15 | static int *ett[] = { |
579 | 15 | &ett_yami, |
580 | 15 | &ett_yami_msg_hdr, |
581 | 15 | &ett_yami_msg_data, |
582 | 15 | &ett_yami_param |
583 | 15 | }; |
584 | | |
585 | 15 | module_t *yami_module; |
586 | | |
587 | 15 | proto_yami = proto_register_protocol("YAMI Protocol", "YAMI", "yami"); |
588 | | |
589 | 15 | proto_register_field_array(proto_yami, hf, array_length(hf)); |
590 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
591 | | |
592 | 15 | yami_module = prefs_register_protocol(proto_yami, NULL); |
593 | 15 | prefs_register_bool_preference(yami_module, "desegment", |
594 | 15 | "Reassemble YAMI messages spanning multiple TCP segments", |
595 | 15 | "Whether the YAMI dissector should reassemble messages spanning multiple TCP segments." |
596 | 15 | "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.", |
597 | 15 | &yami_desegment); |
598 | | |
599 | 15 | yami_handle = register_dissector("yami", dissect_yami, proto_yami); |
600 | 15 | } |
601 | | |
602 | | void |
603 | | proto_reg_handoff_yami(void) |
604 | 15 | { |
605 | 15 | dissector_add_for_decode_as_with_preference("tcp.port", yami_handle); |
606 | 15 | dissector_add_for_decode_as_with_preference("udp.port", yami_handle); |
607 | 15 | } |
608 | | |
609 | | /* |
610 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
611 | | * |
612 | | * Local variables: |
613 | | * c-basic-offset: 8 |
614 | | * tab-width: 8 |
615 | | * indent-tabs-mode: t |
616 | | * End: |
617 | | * |
618 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
619 | | * :indentSize=8:tabSize=8:noTabs=false: |
620 | | */ |