Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / file-rbm.c
blobd881ab4403aa0a723709458cb5a0deba7c70f50b
1 /* file-rbm.c
3 * Routines for Ruby Marshal Object
5 * Copyright 2018, Dario Lombardo (lomato@gmail.com)
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
15 * Example for creating a Ruby marshal file:
16 * o = <whatever ruby object>
17 * f = File.open("marshal.dat", 'wb')
18 * f.write(Marshal.dump(o))
19 * f.close
22 #include "config.h"
24 #include <epan/expert.h>
25 #include <epan/packet.h>
26 #include <wsutil/array.h>
27 #include <file-rbm.h>
28 #include <wiretap/ruby_marshal.h>
30 static int proto_rbm;
32 static int hf_rbm_version;
33 static int hf_rbm_type;
34 static int hf_rbm_integer;
35 static int hf_rbm_length;
36 static int hf_rbm_string;
37 static int hf_rbm_link;
38 static int hf_rbm_double;
39 static int hf_rbm_struct;
40 static int hf_rbm_regex_param;
42 static int ett_rbm;
43 static int ett_array;
44 static int ett_array_obj;
45 static int ett_hash;
46 static int ett_hash_obj;
47 static int ett_variable;
49 static expert_field ei_rbm_invalid;
50 static expert_field ei_rbm_version_unsupported;
52 /* Marshal types */
53 static const value_string rbm_types[] = {
54 { '0', "nil" },
55 { 'T', "true" },
56 { 'F', "false" },
57 { 'i', "Integer" },
58 { ':', "Symbol" },
59 { '"', "String" },
60 { 'I', "Instance variable" },
61 { '[', "Array" },
62 { '{', "Hash" },
63 { 'f', "Double" },
64 { 'c', "Class" },
65 { 'm', "Module" },
66 { 'S', "Struct" },
67 { '/', "Regexp" },
68 { 'o', "Object" },
69 { 'C', "UserClass" },
70 { 'e', "Extended_object" },
71 { ';', "Symbol link" },
72 { '@', "Object link" },
73 { 'u', "DRb::DRbObject" },
74 { ',', "DRb address" },
75 {0, NULL}
78 void proto_register_rbm(void);
79 void proto_reg_handoff_rbm(void);
81 static dissector_handle_t rbm_file_handle;
83 #define BETWEEN(v, b1, b2) (((v) >= (b1)) && ((v) <= (b2)))
85 static void dissect_rbm_object(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, char** type, char** value);
87 static void rbm_set_info(packet_info* pinfo, const char* str)
89 const char* col_str = col_get_text(pinfo->cinfo, COL_INFO);
90 if (!col_str || !strlen(col_str))
91 col_append_fstr(pinfo->cinfo, COL_INFO, "Ruby Marshal Object: %s", str);
94 void get_rbm_integer(tvbuff_t* tvb, unsigned offset, int32_t* value, int* len)
96 int8_t c;
97 c = (tvb_get_int8(tvb, offset) ^ 128) - 128;
98 if (c == 0) {
99 *value = 0;
100 *len = 1;
101 return;
103 if (c >= 4) {
104 *value = c - 5;
105 *len = 1;
106 return;
108 if (BETWEEN(c, 1, 3)) {
109 int i;
110 *value = 0;
111 uint8_t byte;
112 for (i = 0; i < c; i++) {
113 byte = tvb_get_uint8(tvb, offset + 1 + i);
114 *value |= (byte << (8 * i));
116 *len = (c + 1);
117 return;
119 if (c < -6) {
120 *value = c + 5;
121 *len = 1;
122 return;
124 if (BETWEEN(c, -5, -1)) {
125 int i;
126 *value = -1;
127 uint8_t byte;
128 int32_t a;
129 int32_t b;
130 for (i = 0; i < -c; i++) {
131 byte = tvb_get_uint8(tvb, offset + 1 + i);
132 a = ~(0xff << (8*i));
133 b = byte << (8*i);
134 *value = ((*value & a) | b);
136 *len = (-c + 1);
137 return;
141 static void dissect_rbm_integer(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, char** value_str)
143 int32_t value = 0;
144 int len = 0;
145 rbm_set_info(pinfo, "integer");
146 get_rbm_integer(tvb, *offset, &value, &len);
147 proto_tree_add_int_format_value(tree, hf_rbm_integer, tvb, *offset, len, value, "%d", value);
148 *offset += len;
149 if (value_str)
150 *value_str = wmem_strdup_printf(pinfo->pool, "%d", value);
153 static void dissect_rbm_basic(tvbuff_t* tvb _U_, packet_info* pinfo, proto_tree* tree _U_, unsigned* offset _U_, const uint8_t subtype,
154 char** type, char** value_str)
156 switch (subtype) {
157 case '0':
158 *type = "nil";
159 break;
160 case 'T':
161 *type = "Boolean";
162 *value_str = "true";
163 break;
164 case 'F':
165 *type = "Boolean";
166 *value_str = "false";
167 break;
168 default:
169 DISSECTOR_ASSERT_NOT_REACHED();
171 rbm_set_info(pinfo, *type);
174 static void dissect_rbm_string_data_trailer(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, const char* label,
175 const char* prefix, const char* trailer, char** value_str)
177 int32_t value = 0;
178 int len = 0;
179 const char* s;
181 rbm_set_info(pinfo, label);
183 get_rbm_integer(tvb, *offset, &value, &len);
184 proto_tree_add_int_format_value(tree, hf_rbm_length, tvb, *offset, len, value, "%d", value);
185 *offset += len;
186 s = (const char*)tvb_get_string_enc(pinfo->pool, tvb, *offset, value, ENC_NA);
187 proto_tree_add_string_format_value(tree, hf_rbm_string, tvb, *offset, value, s, "%s%s%s", prefix, s, trailer);
188 *offset += value;
189 *value_str = wmem_strdup_printf(pinfo->pool, "%s%s%s", prefix, s, trailer);
192 static void dissect_rbm_string_data(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, const char* label,
193 const char* prefix, char** value_str)
195 dissect_rbm_string_data_trailer(tvb, pinfo, tree, offset, label, prefix, "", value_str);
198 // NOLINTNEXTLINE(misc-no-recursion)
199 static void dissect_rbm_array(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, char** value_str)
201 int32_t value;
202 int len;
203 int32_t i;
204 proto_tree* array_tree = NULL;
205 proto_tree* array_obj_tree = NULL;
206 int offset_start = *offset;
208 rbm_set_info(pinfo, "Array");
209 get_rbm_integer(tvb, *offset, &value, &len);
210 proto_tree_add_int_format_value(tree, hf_rbm_length, tvb, *offset, len, value, "%d", value);
211 array_tree = proto_tree_add_subtree(tree, tvb, *offset, 0, ett_array, NULL, "Array");
212 *offset += len;
214 for (i = 0; i < value; i++) {
215 array_obj_tree = proto_tree_add_subtree(array_tree, tvb, *offset, 0, ett_array_obj, NULL, "Object");
216 dissect_rbm_object(tvb, pinfo, array_obj_tree, offset, NULL, NULL);
218 proto_item_append_text(array_tree, " (%d)", value);
219 proto_item_set_len(array_tree, *offset - offset_start);
221 if (value_str)
222 *value_str = wmem_strdup_printf(pinfo->pool, "%d", value);
225 // NOLINTNEXTLINE(misc-no-recursion)
226 static void dissect_rbm_hash(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, char** value_str)
228 int32_t value;
229 int len;
230 int32_t i;
231 proto_tree* hash_tree = NULL;
232 proto_tree* hash_obj_tree = NULL;
233 proto_tree* hash_key_tree = NULL;
234 proto_tree* hash_value_tree = NULL;
235 char* hkey = NULL;
236 char* hval = NULL;
237 int offset_start = *offset;
239 rbm_set_info(pinfo, "Hash");
240 get_rbm_integer(tvb, *offset, &value, &len);
241 proto_tree_add_int_format_value(tree, hf_rbm_length, tvb, *offset, len, value, "%d", value);
242 hash_tree = proto_tree_add_subtree(tree, tvb, *offset, 0, ett_hash, NULL, "Hash");
243 *offset += len;
245 for (i = 0; i < value; i++) {
246 hash_obj_tree = proto_tree_add_subtree(hash_tree, tvb, *offset, 0, ett_hash_obj, NULL, "Entry");
247 hash_key_tree = proto_tree_add_subtree(hash_obj_tree, tvb, *offset, 0, ett_hash_obj, NULL, "Key");
248 dissect_rbm_object(tvb, pinfo, hash_key_tree, offset, NULL, &hkey);
249 hash_value_tree = proto_tree_add_subtree(hash_obj_tree, tvb, *offset, 0, ett_hash_obj, NULL, "Value");
250 dissect_rbm_object(tvb, pinfo, hash_value_tree, offset, NULL, &hval);
251 proto_item_append_text(hash_obj_tree, " %s => %s", hkey, hval);
253 proto_item_append_text(hash_tree, " (%d)", value);
254 proto_item_set_len(hash_tree, *offset - offset_start);
256 if (value_str)
257 *value_str = wmem_strdup_printf(pinfo->pool, "%d", value);
260 static void dissect_rbm_link(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, uint8_t subtype,
261 char** type, char** value_str)
263 int32_t value;
264 int len;
265 char* label;
267 switch (subtype) {
268 case ';':
269 label = "Symbol";
270 break;
271 case '@':
272 label = "Object";
273 break;
274 default:
275 DISSECTOR_ASSERT_NOT_REACHED();
278 rbm_set_info(pinfo, wmem_strdup_printf(pinfo->pool, "%s Link", label));
279 get_rbm_integer(tvb, *offset, &value, &len);
280 proto_tree_add_int_format_value(tree, hf_rbm_link, tvb, *offset, len, value, "%d", value);
281 *offset += len;
282 if (type)
283 *type = label;
284 if (value_str)
285 *value_str = wmem_strdup_printf(pinfo->pool, "%d", value);
288 static void dissect_rbm_double(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, char** value_str)
290 int32_t value = 0;
291 double valued;
292 int len = 0;
293 const char* s;
295 rbm_set_info(pinfo, "Double");
297 get_rbm_integer(tvb, *offset, &value, &len);
298 proto_tree_add_int_format_value(tree, hf_rbm_length, tvb, *offset, len, value, "%d", value);
299 *offset += len;
300 s = (const char*)tvb_get_string_enc(pinfo->pool, tvb, *offset, value, ENC_NA);
301 valued = g_ascii_strtod(s, NULL);
302 proto_tree_add_double(tree, hf_rbm_double, tvb, *offset, value, valued);
303 *offset += value;
304 if (value_str)
305 *value_str = wmem_strdup_printf(pinfo->pool, "%f", valued);
308 static void dissect_rbm_struct_data(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, char** value_str)
310 int32_t value = 0;
311 int len = 0;
313 if (tvb_get_uint8(tvb, *offset) != ':')
314 return;
315 *offset += 1;
317 rbm_set_info(pinfo, "Struct");
318 get_rbm_integer(tvb, *offset, &value, &len);
319 proto_tree_add_item(tree, hf_rbm_struct, tvb, *offset + 1, value, ENC_ASCII);
320 *offset += 1 + value;
321 if (value_str)
322 *value_str = wmem_strdup_printf(pinfo->pool, "%d", value);
325 // NOLINTNEXTLINE(misc-no-recursion)
326 static void dissect_rbm_string(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, char** value)
328 dissect_rbm_string_data(tvb, pinfo, tree, offset, "String", "", value);
329 dissect_rbm_integer(tvb, pinfo, tree, offset, NULL);
330 dissect_rbm_object(tvb, pinfo, tree, offset, NULL, NULL);
331 dissect_rbm_object(tvb, pinfo, tree, offset, NULL, NULL);
334 // NOLINTNEXTLINE(misc-no-recursion)
335 static void dissect_rbm_regex(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, char** value)
337 dissect_rbm_string_data_trailer(tvb, pinfo, tree, offset, "Regexp", "/", "/", value);
338 proto_tree_add_item(tree, hf_rbm_regex_param, tvb, *offset, 1, ENC_NA);
339 *offset += 1;
340 dissect_rbm_integer(tvb, pinfo, tree, offset, NULL);
341 dissect_rbm_object(tvb, pinfo, tree, offset, NULL, NULL);
342 dissect_rbm_object(tvb, pinfo, tree, offset, NULL, NULL);
345 static void dissect_rbm_class(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, char** value_str)
347 dissect_rbm_string_data(tvb, pinfo, tree, offset, "Class", "", value_str);
350 // NOLINTNEXTLINE(misc-no-recursion)
351 static void dissect_rbm_userclass(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, char** value)
353 rbm_set_info(pinfo, "UserClass");
354 dissect_rbm_object(tvb, pinfo, tree, offset, NULL, value);
357 static void dissect_rbm_symbol(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, char** value_str)
359 dissect_rbm_string_data(tvb, pinfo, tree, offset, "Symbol", ":", value_str);
362 // NOLINTNEXTLINE(misc-no-recursion)
363 static void dissect_rbm_variable(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, char** value_str)
365 int offset_start = *offset;
366 proto_tree* variable_tree = proto_tree_add_subtree(tree, tvb, *offset, 0, ett_variable, NULL, "Variable");
367 dissect_rbm_object(tvb, pinfo, variable_tree, offset, NULL, value_str);
368 proto_item_set_len(variable_tree, *offset - offset_start);
371 static void dissect_rbm_module(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, char** value_str)
373 dissect_rbm_string_data(tvb, pinfo, tree, offset, "Module", "", value_str);
376 // NOLINTNEXTLINE(misc-no-recursion)
377 static void dissect_rbm_struct(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, char** value)
379 dissect_rbm_struct_data(tvb, pinfo, tree, offset, value);
380 dissect_rbm_hash(tvb, pinfo, tree, offset, NULL);
383 // NOLINTNEXTLINE(misc-no-recursion)
384 static void dissect_rbm_drb(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset)
386 int offset_start = *offset;
387 proto_tree* drb_tree = proto_tree_add_subtree(tree, tvb, *offset, 0, ett_variable, NULL, "Objects");
388 dissect_rbm_object(tvb, pinfo, drb_tree, offset, NULL, NULL);
389 dissect_rbm_object(tvb, pinfo, drb_tree, offset, NULL, NULL);
390 proto_item_set_len(drb_tree, *offset - offset_start);
393 // NOLINTNEXTLINE(misc-no-recursion)
394 static void dissect_rbm_rubyobject(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset)
396 int offset_start = *offset;
397 proto_tree* obj_tree = proto_tree_add_subtree(tree, tvb, *offset, 0, ett_variable, NULL, "Ruby Object");
399 rbm_set_info(pinfo, "Ruby Object");
401 dissect_rbm_object(tvb, pinfo, obj_tree, offset, NULL, NULL);
402 dissect_rbm_hash(tvb, pinfo, obj_tree, offset, NULL);
404 while (tvb_captured_length_remaining(tvb, *offset)) {
405 dissect_rbm_object(tvb, pinfo, obj_tree, offset, NULL, NULL);
408 proto_item_set_len(obj_tree, *offset - offset_start);
411 // NOLINTNEXTLINE(misc-no-recursion)
412 static void dissect_rbm_extended(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset)
414 int offset_start = *offset;
415 proto_tree* ext_tree = proto_tree_add_subtree(tree, tvb, *offset, 0, ett_variable, NULL, "Extended");
417 rbm_set_info(pinfo, "Extended");
418 dissect_rbm_object(tvb, pinfo, ext_tree, offset, NULL, NULL);
419 proto_item_set_len(ext_tree, *offset - offset_start);
422 // NOLINTNEXTLINE(misc-no-recursion)
423 static void dissect_rbm_object(tvbuff_t* tvb, packet_info* pinfo, proto_tree* ptree, unsigned* offset, char** type, char** value)
425 uint8_t subtype = tvb_get_uint8(tvb, *offset);
426 proto_tree* tree;
427 char* type_local = "Unknown";
428 char* value_local = "Unknown";
429 int offset_start = *offset;
431 tree = proto_tree_add_subtree(ptree, tvb, *offset, 0, ett_variable, NULL, "");
433 proto_tree_add_item(tree, hf_rbm_type, tvb, *offset, 1, ENC_NA);
434 *offset += 1;
436 increment_dissection_depth(pinfo);
438 switch (subtype) {
439 case '0':
440 case 'T':
441 case 'F':
442 dissect_rbm_basic(tvb, pinfo, tree, offset, subtype, &type_local, &value_local);
443 break;
444 case 'i':
445 type_local = "Integer";
446 dissect_rbm_integer(tvb, pinfo, tree, offset, &value_local);
447 break;
448 case ':':
449 type_local = "Symbol";
450 dissect_rbm_symbol(tvb, pinfo, tree, offset, &value_local);
451 break;
452 case '"':
453 type_local = "String";
454 dissect_rbm_string(tvb, pinfo, tree, offset, &value_local);
455 break;
456 case 'I':
457 type_local = "Instance Variable";
458 dissect_rbm_variable(tvb, pinfo, tree, offset, &value_local);
459 break;
460 case '[':
461 type_local = "Array";
462 dissect_rbm_array(tvb, pinfo, tree, offset, &value_local);
463 break;
464 case '{':
465 type_local = "Hash";
466 dissect_rbm_hash(tvb, pinfo, tree, offset, &value_local);
467 break;
468 case ';':
469 case '@':
470 dissect_rbm_link(tvb, pinfo, tree, offset, subtype, &type_local, &value_local);
471 break;
472 case 'f':
473 type_local = "Double";
474 dissect_rbm_double(tvb, pinfo, tree, offset, &value_local);
475 break;
476 case 'c':
477 type_local = "Class";
478 dissect_rbm_class(tvb, pinfo, tree, offset, &value_local);
479 break;
480 case 'm':
481 type_local = "Module";
482 dissect_rbm_module(tvb, pinfo, tree, offset, &value_local);
483 break;
484 case 'S':
485 type_local = "Struct";
486 dissect_rbm_struct(tvb, pinfo, tree, offset, &value_local);
487 break;
488 case '/':
489 type_local = "Regex";
490 dissect_rbm_regex(tvb, pinfo, tree, offset, &value_local);
491 break;
492 case 'u':
493 type_local = "DRb::DRbObject";
494 dissect_rbm_drb(tvb, pinfo, tree, offset);
495 break;
496 case ',':
497 dissect_rbm_inline(tvb, pinfo, tree, offset, &type_local, &value_local);
498 break;
499 case 'o':
500 dissect_rbm_rubyobject(tvb, pinfo, tree, offset);
501 type_local = "Ruby Object";
502 break;
503 case 'C':
504 type_local = "UserClass";
505 dissect_rbm_userclass(tvb, pinfo, tree, offset, &value_local);
506 break;
507 case 'e':
508 type_local = "Extended Object";
509 dissect_rbm_extended(tvb, pinfo, tree, offset);
510 break;
511 default:
512 expert_add_info_format(pinfo, tree, &ei_rbm_invalid,
513 "Object type 0x%x is invalid", subtype);
514 *offset += tvb_reported_length_remaining(tvb, *offset);
517 proto_item_set_len(tree, *offset - offset_start);
519 proto_item_append_text(tree, "Type: %s", type_local);
520 if (value_local && strlen(value_local))
521 proto_item_append_text(tree, ", Value: %s", value_local);
523 if (type)
524 *type = type_local;
525 if (value)
526 *value = value_local;
528 decrement_dissection_depth(pinfo);
531 static bool dissect_rbm_header(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset)
533 uint8_t major;
534 uint8_t minor;
535 char* version;
537 major = tvb_get_uint8(tvb, *offset);
538 minor = tvb_get_uint8(tvb, *offset + 1);
540 version = wmem_strdup_printf(pinfo->pool, "%u.%u", major, minor);
541 proto_tree_add_string_format(tree, hf_rbm_version, tvb, *offset, 2, version, "Version: %s", version);
542 *offset += 2;
544 if (major != RUBY_MARSHAL_MAJOR || minor != RUBY_MARSHAL_MINOR) {
545 expert_add_info_format(pinfo, tree, &ei_rbm_version_unsupported, "Version %u.%u is not supported (only %u.%u)",
546 major, minor, RUBY_MARSHAL_MAJOR, RUBY_MARSHAL_MINOR);
547 return false;
549 return true;
552 // NOLINTNEXTLINE(misc-no-recursion)
553 void dissect_rbm_inline(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned* offset, char** type, char** value)
555 if (!dissect_rbm_header(tvb, pinfo, tree, offset))
556 return;
557 dissect_rbm_object(tvb, pinfo, tree, offset, type, value);
560 static int dissect_rbm(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
562 unsigned offset = 0;
563 proto_item* ti;
564 proto_tree* rbm_tree;
566 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Rbm");
567 col_clear(pinfo->cinfo, COL_INFO);
569 ti = proto_tree_add_item(tree, proto_rbm, tvb, 0, -1, ENC_NA);
570 rbm_tree = proto_item_add_subtree(ti, ett_rbm);
572 dissect_rbm_inline(tvb, pinfo, rbm_tree, &offset, NULL, NULL);
573 return offset;
576 void proto_register_rbm(void)
578 expert_module_t* expert_rbm;
580 static hf_register_info hf[] = {
581 { &hf_rbm_version,
582 { "Version", "rbm.version", FT_STRING, BASE_NONE, NULL, 0x00, NULL, HFILL }
584 { &hf_rbm_type,
585 { "Type", "rbm.type", FT_UINT8, BASE_HEX, VALS(rbm_types), 0x00, NULL, HFILL }
587 { &hf_rbm_integer,
588 { "Integer", "rbm.int", FT_INT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
590 { &hf_rbm_length,
591 { "Length", "rbm.length", FT_INT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
593 { &hf_rbm_string,
594 { "Value", "rbm.string", FT_STRING, BASE_NONE, NULL, 0x00, NULL, HFILL }
596 { &hf_rbm_link,
597 { "Link to object", "rbm.link", FT_INT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
599 { &hf_rbm_double,
600 { "Value", "rbm.double", FT_DOUBLE, BASE_NONE, NULL, 0x00, NULL, HFILL }
602 { &hf_rbm_struct,
603 { "Struct", "rbm.struct", FT_STRING, BASE_NONE, NULL, 0x00, NULL, HFILL }
605 { &hf_rbm_regex_param,
606 { "Regexp parameter", "rbm.regex.param", FT_UINT8, BASE_DEC, NULL, 0x00, NULL, HFILL }
610 static ei_register_info ei[] = {
611 { &ei_rbm_invalid, { "rbm.invalid", PI_UNDECODED, PI_WARN, "Invalid type", EXPFILL }},
612 { &ei_rbm_version_unsupported, { "rbm.version.unsupported", PI_UNDECODED, PI_WARN, "Unsupported version", EXPFILL }}
615 /* Setup protocol subtree array */
616 static int* ett[] = {
617 &ett_rbm,
618 &ett_array,
619 &ett_array_obj,
620 &ett_hash,
621 &ett_hash_obj,
622 &ett_variable
625 proto_rbm = proto_register_protocol("Ruby Marshal Object", "Rbm", "rbm");
627 expert_rbm = expert_register_protocol(proto_rbm);
628 expert_register_field_array(expert_rbm, ei, array_length(ei));
630 proto_register_field_array(proto_rbm, hf, array_length(hf));
631 proto_register_subtree_array(ett, array_length(ett));
633 rbm_file_handle = register_dissector("rbm", dissect_rbm, proto_rbm);
636 void proto_reg_handoff_rbm(void)
638 dissector_add_uint("wtap_encap", WTAP_ENCAP_RUBY_MARSHAL, rbm_file_handle);
642 * Editor modelines - https://www.wireshark.org/tools/modelines.html
644 * Local variables:
645 * c-basic-offset: 8
646 * tab-width: 8
647 * indent-tabs-mode: t
648 * End:
650 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
651 * :indentSize=8:tabSize=8:noTabs=false: