/src/wireshark/epan/dissectors/packet-msgpack.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* packet-msgpack.c |
2 | | * |
3 | | * Routines for MsgPack dissection |
4 | | * References: |
5 | | * https://github.com/msgpack/msgpack/ |
6 | | * |
7 | | * Copyright 2018, Dario Lombardo <lomato@gmail.com> |
8 | | * |
9 | | * Wireshark - Network traffic analyzer |
10 | | * By Gerald Combs <gerald@wireshark.org> |
11 | | * Copyright 1998 Gerald Combs |
12 | | * |
13 | | * SPDX-License-Identifier: GPL-2.0-or-later |
14 | | */ |
15 | | |
16 | | #include "config.h" |
17 | | |
18 | | #include <wsutil/array.h> |
19 | | #include <epan/packet.h> |
20 | | #include <epan/expert.h> |
21 | | #include <epan/to_str.h> |
22 | | |
23 | | |
24 | | |
25 | | void proto_register_msgpack(void); |
26 | | void proto_reg_handoff_msgpack(void); |
27 | | |
28 | | dissector_handle_t msgpack_handle; |
29 | | |
30 | | static int proto_msgpack; |
31 | | |
32 | | static int hf_msgpack_string; |
33 | | static int hf_msgpack_type; |
34 | | static int hf_msgpack_string_len; |
35 | | static int hf_msgpack_uint_8; |
36 | | static int hf_msgpack_uint_16; |
37 | | static int hf_msgpack_uint_32; |
38 | | static int hf_msgpack_uint_64; |
39 | | static int hf_msgpack_int_8; |
40 | | static int hf_msgpack_int_16; |
41 | | static int hf_msgpack_int_32; |
42 | | static int hf_msgpack_int_64; |
43 | | static int hf_msgpack_bool; |
44 | | static int hf_msgpack_float; |
45 | | static int hf_msgpack_ext_fixext; |
46 | | static int hf_msgpack_ext_type; |
47 | | static int hf_msgpack_ext_bytes; |
48 | | |
49 | | static int ett_msgpack; |
50 | | static int ett_msgpack_string; |
51 | | static int ett_msgpack_array; |
52 | | static int ett_msgpack_map; |
53 | | static int ett_msgpack_map_elem; |
54 | | static int ett_msgpack_ext; |
55 | | |
56 | | static expert_field ei_msgpack_unsupported; |
57 | | |
58 | | static const value_string msgpack_ext_fixtexts[] = { |
59 | | { 0xd4, "fixext 1" }, |
60 | | { 0xd5, "fixext 2" }, |
61 | | { 0xd6, "fixext 4" }, |
62 | | { 0xd7, "fixext 8" }, |
63 | | { 0xd8, "fixext 16" }, |
64 | | { 0, NULL } |
65 | | }; |
66 | | |
67 | | static void dissect_msgpack_object(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data, int* offset, char** value); |
68 | | |
69 | | static void dissect_msgpack_integer(tvbuff_t* tvb, packet_info *pinfo, proto_tree* tree, uint8_t type, void* data, int* offset, char** value) |
70 | 0 | { |
71 | 0 | uint8_t uint8; |
72 | 0 | uint16_t uint16; |
73 | 0 | uint32_t uint32; |
74 | 0 | uint64_t uint64; |
75 | 0 | int8_t int8; |
76 | 0 | int16_t int16; |
77 | 0 | int32_t int32; |
78 | 0 | int64_t int64; |
79 | 0 | char* label; |
80 | |
|
81 | 0 | label = (data ? (char*)data : "MsgPack Integer"); |
82 | |
|
83 | 0 | if (type >> 7 == 0) { |
84 | 0 | proto_tree_add_uint_format(tree, hf_msgpack_uint_8, tvb, *offset, 1, type, "%s: %u", label, type); |
85 | 0 | if (value) |
86 | 0 | *value = wmem_strdup_printf(pinfo->pool, "%u", type); |
87 | 0 | *offset += 1; |
88 | 0 | return; |
89 | 0 | } |
90 | | |
91 | 0 | if (type >> 5 == 7) { |
92 | 0 | proto_tree_add_int_format(tree, hf_msgpack_int_8, tvb, *offset, 1, type, "%s: %u", label, type); |
93 | 0 | if (value) |
94 | 0 | *value = wmem_strdup_printf(pinfo->pool, "%d", type); |
95 | 0 | *offset += 1; |
96 | 0 | return; |
97 | 0 | } |
98 | | |
99 | 0 | switch (type) { |
100 | 0 | case 0xcc: |
101 | 0 | uint8 = tvb_get_uint8(tvb, *offset + 1); |
102 | 0 | proto_tree_add_uint_format(tree, hf_msgpack_uint_8, tvb, *offset, 2, uint8, "%s: %u", label, uint8); |
103 | 0 | if (value) |
104 | 0 | *value = wmem_strdup_printf(pinfo->pool, "%u", uint8); |
105 | 0 | *offset += 2; |
106 | 0 | break; |
107 | 0 | case 0xcd: |
108 | 0 | uint16 = tvb_get_ntohs(tvb, *offset + 1); |
109 | 0 | proto_tree_add_uint(tree, hf_msgpack_uint_16, tvb, *offset, 3, uint16); |
110 | 0 | if (value) |
111 | 0 | *value = wmem_strdup_printf(pinfo->pool, "%u", uint16); |
112 | 0 | *offset += 3; |
113 | 0 | break; |
114 | 0 | case 0xce: |
115 | 0 | uint32 = tvb_get_ntohl(tvb, *offset + 1); |
116 | 0 | proto_tree_add_uint(tree, hf_msgpack_uint_32, tvb, *offset, 5, uint32); |
117 | 0 | if (value) |
118 | 0 | *value = wmem_strdup_printf(pinfo->pool, "%u", uint32); |
119 | 0 | *offset += 5; |
120 | 0 | break; |
121 | 0 | case 0xcf: |
122 | 0 | uint64 = tvb_get_ntoh64(tvb, *offset + 1); |
123 | 0 | proto_tree_add_uint64(tree, hf_msgpack_uint_64, tvb, *offset, 9, uint64); |
124 | 0 | if (value) |
125 | 0 | *value = wmem_strdup_printf(pinfo->pool, "%" PRIu64, uint64); |
126 | 0 | *offset += 9; |
127 | 0 | break; |
128 | 0 | case 0xd0: |
129 | 0 | int8 = tvb_get_int8(tvb, *offset + 1); |
130 | 0 | proto_tree_add_int(tree, hf_msgpack_int_8, tvb, *offset, 2, int8); |
131 | 0 | if (value) |
132 | 0 | *value = wmem_strdup_printf(pinfo->pool, "%d", int8); |
133 | 0 | *offset += 2; |
134 | 0 | break; |
135 | 0 | case 0xd1: |
136 | 0 | int16 = tvb_get_ntohs(tvb, *offset + 1); |
137 | 0 | proto_tree_add_int(tree, hf_msgpack_int_16, tvb, *offset, 3, int16); |
138 | 0 | if (value) |
139 | 0 | *value = wmem_strdup_printf(pinfo->pool, "%d", int16); |
140 | 0 | *offset += 3; |
141 | 0 | break; |
142 | 0 | case 0xd2: |
143 | 0 | int32 = tvb_get_ntohl(tvb, *offset + 1); |
144 | 0 | proto_tree_add_int(tree, hf_msgpack_int_32, tvb, *offset, 5, int32); |
145 | 0 | if (value) |
146 | 0 | *value = wmem_strdup_printf(pinfo->pool, "%d", int32); |
147 | 0 | *offset += 5; |
148 | 0 | break; |
149 | 0 | case 0xd3: |
150 | 0 | int64 = tvb_get_ntoh64(tvb, *offset + 1); |
151 | 0 | proto_tree_add_int64(tree, hf_msgpack_int_64, tvb, *offset, 9, int64); |
152 | 0 | if (value) |
153 | 0 | *value = wmem_strdup_printf(pinfo->pool, "%" PRId64, int64); |
154 | 0 | *offset += 9; |
155 | 0 | break; |
156 | 0 | default: |
157 | 0 | DISSECTOR_ASSERT_NOT_REACHED(); |
158 | 0 | } |
159 | 0 | } |
160 | | |
161 | | // NOLINTNEXTLINE(misc-no-recursion) |
162 | | static void dissect_msgpack_map(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, uint8_t type, void* data, int* offset, char** value) |
163 | 0 | { |
164 | 0 | proto_tree* subtree; |
165 | 0 | proto_tree* map_subtree; |
166 | 0 | proto_item* ti; |
167 | 0 | uint8_t len; |
168 | 0 | char* label; |
169 | 0 | unsigned i; |
170 | |
|
171 | 0 | len = type & 0x0F; |
172 | |
|
173 | 0 | label = wmem_strdup_printf(pinfo->pool, "%s: %u element%s", data ? (char*)data : "MsgPack Map", len, len > 1 ? "s" : ""); |
174 | |
|
175 | 0 | ti = proto_tree_add_string_format(tree, hf_msgpack_string, tvb, *offset, 1 + len, NULL, "%s", label); |
176 | 0 | subtree = proto_item_add_subtree(ti, ett_msgpack_map); |
177 | 0 | *offset += 1; |
178 | 0 | for (i = 0; i < len; i++) { |
179 | 0 | map_subtree = proto_tree_add_subtree(subtree, tvb, *offset, 0, ett_msgpack_map_elem, NULL, ""); |
180 | 0 | dissect_msgpack_object(tvb, pinfo, map_subtree, "Key", offset, value); |
181 | 0 | if (value) |
182 | 0 | proto_item_append_text(map_subtree, " %s:", *value); |
183 | | // We recurse here, but we'll run out of packet before we run out of stack. |
184 | 0 | dissect_msgpack_object(tvb, pinfo, map_subtree, "Value", offset, value); |
185 | 0 | if (value) |
186 | 0 | proto_item_append_text(map_subtree, " %s", *value); |
187 | 0 | } |
188 | |
|
189 | 0 | if (value) |
190 | 0 | *value = label; |
191 | 0 | } |
192 | | |
193 | | // NOLINTNEXTLINE(misc-no-recursion) |
194 | | static void dissect_msgpack_array(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, uint8_t type, void* data, int* offset, char** value) |
195 | 0 | { |
196 | 0 | proto_tree* subtree; |
197 | 0 | proto_item* ti; |
198 | 0 | uint32_t len; |
199 | 0 | uint32_t lensize = UINT32_MAX; |
200 | 0 | char* label; |
201 | 0 | unsigned i; |
202 | |
|
203 | 0 | if (type >> 4 == 0x9) { |
204 | 0 | len = type & 0x0F; |
205 | 0 | lensize = 0; |
206 | 0 | } |
207 | 0 | if (type == 0xdc) { |
208 | 0 | len = tvb_get_ntohs(tvb, *offset + 1); |
209 | 0 | lensize = 2; |
210 | 0 | } |
211 | 0 | if (type == 0xdd) { |
212 | 0 | len = tvb_get_ntohl(tvb, *offset + 1); |
213 | 0 | lensize = 4; |
214 | 0 | } |
215 | |
|
216 | 0 | DISSECTOR_ASSERT(lensize != UINT32_MAX); |
217 | |
|
218 | 0 | label = wmem_strdup_printf(pinfo->pool, "%s %u element%s", data ? (char*)data : "MsgPack Array", len, len > 1 ? "s" : ""); |
219 | |
|
220 | 0 | ti = proto_tree_add_string_format(tree, hf_msgpack_string, tvb, *offset, 1 + len, NULL, "%s", label); |
221 | 0 | subtree = proto_item_add_subtree(ti, ett_msgpack_array); |
222 | 0 | *offset += lensize + 1; |
223 | 0 | for (i = 0; i < len; i++) { |
224 | | // We recurse here, but we'll run out of packet before we run out of stack. |
225 | 0 | dissect_msgpack_object(tvb, pinfo, subtree, data, offset, value); |
226 | 0 | } |
227 | |
|
228 | 0 | if (value) |
229 | 0 | *value = label; |
230 | 0 | } |
231 | | |
232 | | static void dissect_msgpack_string(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int type, void* data, int* offset, char** value) |
233 | 0 | { |
234 | 0 | uint32_t len = 0; |
235 | 0 | uint32_t lensize = 0; |
236 | 0 | char* label; |
237 | 0 | proto_item* ti; |
238 | 0 | proto_tree* subtree; |
239 | 0 | char* lvalue; |
240 | |
|
241 | 0 | if (type >> 5 == 0x5) { |
242 | 0 | len = type & 0x1F; |
243 | 0 | lensize = 0; |
244 | 0 | } |
245 | 0 | if (type == 0xd9) { |
246 | 0 | len = tvb_get_uint8(tvb, *offset + 1); |
247 | 0 | lensize = 1; |
248 | 0 | } |
249 | 0 | if (type == 0xda) { |
250 | 0 | len = tvb_get_ntohs(tvb, *offset + 1); |
251 | 0 | lensize = 2; |
252 | 0 | } |
253 | 0 | if (type == 0xdb) { |
254 | 0 | len = tvb_get_ntohl(tvb, *offset + 1); |
255 | 0 | lensize = 4; |
256 | 0 | } |
257 | |
|
258 | 0 | lvalue = (char*)tvb_get_string_enc(pinfo->pool, tvb, *offset + 1 + lensize, len, ENC_NA); |
259 | 0 | label = (data ? (char*)data : "MsgPack String"); |
260 | |
|
261 | 0 | ti = proto_tree_add_string_format(tree, hf_msgpack_string, tvb, *offset, 1 + lensize + len, lvalue, "%s: %s", label, lvalue); |
262 | |
|
263 | 0 | subtree = proto_item_add_subtree(ti, ett_msgpack_string); |
264 | 0 | if (lensize == 0) { |
265 | 0 | proto_tree_add_uint_format(subtree, hf_msgpack_type, tvb, *offset, 1, type, "Type: String"); |
266 | 0 | proto_tree_add_uint_format(subtree, hf_msgpack_string_len, tvb, *offset, 1, lensize, "Length: 1"); |
267 | 0 | proto_tree_add_item(subtree, hf_msgpack_string, tvb, *offset + 1 + lensize, len, ENC_ASCII); |
268 | 0 | } else { |
269 | 0 | proto_tree_add_item(subtree, hf_msgpack_type, tvb, *offset, 1, ENC_NA); |
270 | 0 | proto_tree_add_item(subtree, hf_msgpack_string_len, tvb, *offset + 1, lensize, ENC_BIG_ENDIAN); |
271 | 0 | proto_tree_add_item(subtree, hf_msgpack_string, tvb, *offset + 1 + lensize, len, ENC_ASCII); |
272 | 0 | } |
273 | 0 | *offset += 1 + lensize + len; |
274 | |
|
275 | 0 | if (value) |
276 | 0 | *value = lvalue; |
277 | 0 | } |
278 | | |
279 | | static void dissect_msgpack_float(tvbuff_t* tvb, packet_info *pinfo, proto_tree* tree, int type, void* data, int* offset, char** value) |
280 | 0 | { |
281 | 0 | char* label; |
282 | 0 | char* lvalue; |
283 | |
|
284 | 0 | label = (data ? (char*)data : "Float"); |
285 | |
|
286 | 0 | *offset += 1; |
287 | |
|
288 | 0 | if (type == 0xca) { |
289 | 0 | float f = tvb_get_ntohieee_float(tvb, *offset); |
290 | 0 | lvalue = wmem_strdup_printf(pinfo->pool, "%f", f); |
291 | 0 | proto_tree_add_string_format(tree, hf_msgpack_float, tvb, *offset, 4, lvalue, "%s: %f", label, f); |
292 | 0 | if (value) |
293 | 0 | *value = lvalue; |
294 | 0 | *offset += 4; |
295 | 0 | } else { |
296 | 0 | double d = tvb_get_ntohieee_double(tvb, *offset); |
297 | 0 | lvalue = wmem_strdup_printf(pinfo->pool, "%f", d); |
298 | 0 | proto_tree_add_string_format(tree, hf_msgpack_float, tvb, *offset, 8, lvalue, "%s: %f", label, d); |
299 | 0 | if (value) |
300 | 0 | *value = lvalue; |
301 | 0 | *offset += 8; |
302 | 0 | } |
303 | 0 | } |
304 | | |
305 | | static void dissect_msgpack_ext(tvbuff_t* tvb, proto_tree* tree, int type, void* data, int* offset, char** value) |
306 | 0 | { |
307 | 0 | char* label; |
308 | 0 | int bytes; |
309 | 0 | const uint8_t* start; |
310 | 0 | proto_tree* ext_tree; |
311 | 0 | unsigned offset_start = *offset; |
312 | |
|
313 | 0 | label = (data ? (char*)data : "Ext"); |
314 | |
|
315 | 0 | ext_tree = proto_tree_add_subtree(tree, tvb, *offset, 0, ett_msgpack_ext, NULL, label); |
316 | |
|
317 | 0 | proto_tree_add_item(ext_tree, hf_msgpack_ext_fixext, tvb, *offset, 1, ENC_NA); |
318 | 0 | *offset += 1; |
319 | |
|
320 | 0 | if (type >= 0xd4 && type <= 0xd8) { |
321 | 0 | proto_tree_add_item(ext_tree, hf_msgpack_ext_type, tvb, *offset, 1, ENC_NA); |
322 | 0 | *offset += 1; |
323 | 0 | bytes = 1 << (type - 0xd4); |
324 | 0 | start = (const uint8_t*)tvb_get_ptr(tvb, *offset, bytes); |
325 | 0 | proto_tree_add_bytes(ext_tree, hf_msgpack_ext_bytes, tvb, *offset, bytes, start); |
326 | 0 | if (value) |
327 | 0 | *value = bytes_to_hexstr(*value, start, bytes); |
328 | 0 | *offset += bytes; |
329 | 0 | } |
330 | |
|
331 | 0 | proto_item_set_len(ext_tree, *offset - offset_start); |
332 | 0 | } |
333 | | |
334 | | // NOLINTNEXTLINE(misc-no-recursion) |
335 | | static void dissect_msgpack_object(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data, int* offset, char** value) |
336 | 0 | { |
337 | 0 | uint8_t type; |
338 | |
|
339 | 0 | type = tvb_get_uint8(tvb, *offset); |
340 | | |
341 | | // Nil |
342 | 0 | if (type == 0xc0) { |
343 | 0 | proto_tree_add_string_format(tree, hf_msgpack_string, tvb, *offset, 1, "nil", "nil"); |
344 | 0 | if (value) |
345 | 0 | *value = "nil"; |
346 | 0 | *offset += 1; |
347 | 0 | return; |
348 | 0 | } |
349 | | |
350 | | // True/False |
351 | 0 | if (type == 0xc2 || type == 0xc3) { |
352 | 0 | proto_tree_add_boolean(tree, hf_msgpack_bool, tvb, *offset, 1, type - 0xc2); |
353 | 0 | if (value) |
354 | 0 | *value = (type - 0xc2) ? "True" : "False"; |
355 | 0 | *offset += 1; |
356 | 0 | return; |
357 | 0 | } |
358 | | |
359 | | // Integer |
360 | 0 | if (type >= 0xe0 || type <= 0x7f || (type >= 0xcc && type <= 0xd3)) { |
361 | 0 | dissect_msgpack_integer(tvb, pinfo, tree, type, data, offset, value); |
362 | 0 | return; |
363 | 0 | } |
364 | | |
365 | | // Float |
366 | 0 | if (type == 0xca || type == 0xcb) { |
367 | 0 | dissect_msgpack_float(tvb, pinfo, tree, type, data, offset, value); |
368 | 0 | return; |
369 | 0 | } |
370 | | |
371 | | // String |
372 | 0 | if (type >> 5 == 0x5 || type == 0xd9 || type == 0xda || type == 0xdb) { |
373 | 0 | dissect_msgpack_string(tvb, pinfo, tree, type, data, offset, value); |
374 | 0 | return; |
375 | 0 | } |
376 | | |
377 | | // Array |
378 | 0 | if (type >> 4 == 0x9 || type == 0xdc || type == 0xdd) { |
379 | | // We recurse here, but we'll run out of packet before we run out of stack. |
380 | 0 | dissect_msgpack_array(tvb, pinfo, tree, type, data, offset, value); |
381 | 0 | return; |
382 | 0 | } |
383 | | |
384 | | // Map |
385 | 0 | if (type >> 4 == 0x8) { |
386 | | // We recurse here, but we'll run out of packet before we run out of stack. |
387 | 0 | dissect_msgpack_map(tvb, pinfo, tree, type, data, offset, value); |
388 | 0 | return; |
389 | 0 | } |
390 | | |
391 | | // Ext |
392 | 0 | if ((type >= 0xd4 && type <= 0xd8) || (type >= 0xc7 && type <= 0xc9)) { |
393 | 0 | dissect_msgpack_ext(tvb, tree, type, data, offset, value); |
394 | 0 | return; |
395 | 0 | } |
396 | | |
397 | 0 | if (*offset == 0) { |
398 | 0 | expert_add_info_format(pinfo, tree, &ei_msgpack_unsupported, "Type 0x%x is unsupported", type); |
399 | 0 | } |
400 | 0 | } |
401 | | |
402 | | static int dissect_msgpack(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data) |
403 | 0 | { |
404 | 0 | int offset = 0; |
405 | 0 | dissect_msgpack_object(tvb, pinfo, tree, data, &offset, NULL); |
406 | 0 | return offset; |
407 | 0 | } |
408 | | |
409 | | void proto_register_msgpack(void) |
410 | 14 | { |
411 | 14 | expert_module_t* expert_msgpack; |
412 | | |
413 | 14 | static hf_register_info hf[] = { |
414 | 14 | { &hf_msgpack_string, |
415 | 14 | { "String", "msgpack.string", FT_STRING, BASE_NONE, NULL, 0x00, NULL, HFILL } |
416 | 14 | }, |
417 | 14 | { &hf_msgpack_type, |
418 | 14 | { "Type", "msgpack.type", FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL } |
419 | 14 | }, |
420 | 14 | { &hf_msgpack_string_len, |
421 | 14 | { "Length", "msgpack.string.len", FT_UINT16, BASE_DEC, NULL, 0x00, NULL, HFILL } |
422 | 14 | }, |
423 | 14 | { &hf_msgpack_uint_8, |
424 | 14 | { "Integer", "msgpack.integer.u8", FT_UINT8, BASE_DEC, NULL, 0x00, NULL, HFILL } |
425 | 14 | }, |
426 | 14 | { &hf_msgpack_uint_16, |
427 | 14 | { "Integer", "msgpack.integer.u16", FT_UINT16, BASE_DEC, NULL, 0x00, NULL, HFILL } |
428 | 14 | }, |
429 | 14 | { &hf_msgpack_uint_32, |
430 | 14 | { "Integer", "msgpack.integer.u32", FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } |
431 | 14 | }, |
432 | 14 | { &hf_msgpack_uint_64, |
433 | 14 | { "Integer", "msgpack.integer.u64", FT_UINT64, BASE_DEC, NULL, 0x00, NULL, HFILL } |
434 | 14 | }, |
435 | 14 | { &hf_msgpack_int_8, |
436 | 14 | { "Integer", "msgpack.integer.8", FT_INT8, BASE_DEC, NULL, 0x00, NULL, HFILL } |
437 | 14 | }, |
438 | 14 | { &hf_msgpack_int_16, |
439 | 14 | { "Integer", "msgpack.integer.16", FT_INT16, BASE_DEC, NULL, 0x00, NULL, HFILL } |
440 | 14 | }, |
441 | 14 | { &hf_msgpack_int_32, |
442 | 14 | { "Integer", "msgpack.integer.32", FT_INT32, BASE_DEC, NULL, 0x00, NULL, HFILL } |
443 | 14 | }, |
444 | 14 | { &hf_msgpack_int_64, |
445 | 14 | { "Integer", "msgpack.integer.64", FT_INT64, BASE_DEC, NULL, 0x00, NULL, HFILL } |
446 | 14 | }, |
447 | 14 | { &hf_msgpack_bool, |
448 | 14 | { "Boolean", "msgpack.boolean", FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } |
449 | 14 | }, |
450 | 14 | { &hf_msgpack_float, |
451 | 14 | { "Float", "msgpack.float", FT_STRING, BASE_NONE, NULL, 0x00, NULL, HFILL } |
452 | 14 | }, |
453 | 14 | { &hf_msgpack_ext_fixext, |
454 | 14 | { "Ext fix text", "msgpack.ext.fixtext", FT_UINT8, BASE_HEX, VALS(msgpack_ext_fixtexts), 0x00, NULL, HFILL } |
455 | 14 | }, |
456 | 14 | { &hf_msgpack_ext_type, |
457 | 14 | { "Ext type", "msgpack.ext.type", FT_INT8, BASE_DEC, NULL, 0x00, NULL, HFILL } |
458 | 14 | }, |
459 | 14 | { &hf_msgpack_ext_bytes, |
460 | 14 | { "Ext", "msgpack.ext", FT_BYTES, BASE_NONE, NULL, 0x00, NULL, HFILL } |
461 | 14 | } |
462 | 14 | }; |
463 | | |
464 | 14 | static int* ett[] = { |
465 | 14 | &ett_msgpack, |
466 | 14 | &ett_msgpack_string, |
467 | 14 | &ett_msgpack_array, |
468 | 14 | &ett_msgpack_map, |
469 | 14 | &ett_msgpack_map_elem, |
470 | 14 | &ett_msgpack_ext |
471 | 14 | }; |
472 | | |
473 | 14 | static ei_register_info ei[] = { |
474 | 14 | { &ei_msgpack_unsupported, { "msgpack.unsupported", PI_UNDECODED, PI_WARN, "Unsupported type", EXPFILL }} |
475 | 14 | }; |
476 | | |
477 | 14 | proto_msgpack = proto_register_protocol("Message Pack", "MsgPack", "msgpack"); |
478 | 14 | msgpack_handle = register_dissector("msgpack", dissect_msgpack, proto_msgpack); |
479 | | |
480 | 14 | expert_msgpack = expert_register_protocol(proto_msgpack); |
481 | 14 | expert_register_field_array(expert_msgpack, ei, array_length(ei)); |
482 | | |
483 | 14 | proto_register_field_array(proto_msgpack, hf, array_length(hf)); |
484 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
485 | 14 | } |
486 | | |
487 | | void proto_reg_handoff_msgpack(void) |
488 | 14 | { |
489 | | // If this is ever streamed (transported over TCP) we need to add recursion checks |
490 | 14 | dissector_add_for_decode_as("udp.port", msgpack_handle); |
491 | 14 | } |
492 | | |
493 | | /* |
494 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
495 | | * |
496 | | * Local variables: |
497 | | * c-basic-offset: 8 |
498 | | * tab-width: 8 |
499 | | * indent-tabs-mode: t |
500 | | * End: |
501 | | * |
502 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
503 | | * :indentSize=8:tabSize=8:noTabs=false: |
504 | | */ |