summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/file-rbm.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
commite4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch)
tree68cb5ef9081156392f1dd62a00c6ccc1451b93df /epan/dissectors/file-rbm.c
parentInitial commit. (diff)
downloadwireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz
wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/file-rbm.c')
-rw-r--r--epan/dissectors/file-rbm.c634
1 files changed, 634 insertions, 0 deletions
diff --git a/epan/dissectors/file-rbm.c b/epan/dissectors/file-rbm.c
new file mode 100644
index 0000000..988b704
--- /dev/null
+++ b/epan/dissectors/file-rbm.c
@@ -0,0 +1,634 @@
+/* file-rbm.c
+ *
+ * Routines for Ruby Marshal Object
+ *
+ * Copyright 2018, Dario Lombardo (lomato@gmail.com)
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/*
+ * Example for creating a Ruby marshal file:
+ * o = <whatever ruby object>
+ * f = File.open("marshal.dat", 'wb')
+ * f.write(Marshal.dump(o))
+ * f.close
+*/
+
+#include "config.h"
+#include <epan/packet.h>
+#include <epan/expert.h>
+#include <file-rbm.h>
+#include <wiretap/ruby_marshal.h>
+
+static int proto_rbm = -1;
+
+static int hf_rbm_version = -1;
+static int hf_rbm_type = -1;
+static int hf_rbm_integer = -1;
+static int hf_rbm_length = -1;
+static int hf_rbm_string = -1;
+static int hf_rbm_link = -1;
+static int hf_rbm_double = -1;
+static int hf_rbm_struct = -1;
+static int hf_rbm_regex_param = -1;
+
+static gint ett_rbm = -1;
+static gint ett_array = -1;
+static gint ett_array_obj = -1;
+static gint ett_hash = -1;
+static gint ett_hash_obj = -1;
+static gint ett_variable = -1;
+
+static expert_field ei_rbm_invalid = EI_INIT;
+static expert_field ei_rbm_version_unsupported = EI_INIT;
+
+/* Marshal types */
+static const value_string rbm_types[] = {
+ { '0', "nil" },
+ { 'T', "true" },
+ { 'F', "false" },
+ { 'i', "Integer" },
+ { ':', "Symbol" },
+ { '"', "String" },
+ { 'I', "Instance variable" },
+ { '[', "Array" },
+ { '{', "Hash" },
+ { 'f', "Double" },
+ { 'c', "Class" },
+ { 'm', "Module" },
+ { 'S', "Struct" },
+ { '/', "Regexp" },
+ { 'o', "Object" },
+ { 'C', "UserClass" },
+ { 'e', "Extended_object" },
+ { ';', "Symbol link" },
+ { '@', "Object link" },
+ { 'u', "DRb::DRbObject" },
+ { ',', "DRb address" },
+ {0, NULL}
+};
+
+void proto_register_rbm(void);
+void proto_reg_handoff_rbm(void);
+
+static dissector_handle_t rbm_file_handle;
+
+#define BETWEEN(v, b1, b2) (((v) >= (b1)) && ((v) <= (b2)))
+
+static void dissect_rbm_object(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, gchar** type, gchar** value);
+
+static void rbm_set_info(packet_info* pinfo, const gchar* str)
+{
+ const gchar* col_str = col_get_text(pinfo->cinfo, COL_INFO);
+ if (!col_str || !strlen(col_str))
+ col_append_fstr(pinfo->cinfo, COL_INFO, "Ruby Marshal Object: %s", str);
+}
+
+void get_rbm_integer(tvbuff_t* tvb, guint offset, gint32* value, gint* len)
+{
+ gint8 c;
+ c = (tvb_get_gint8(tvb, offset) ^ 128) - 128;
+ if (c == 0) {
+ *value = 0;
+ *len = 1;
+ return;
+ }
+ if (c >= 4) {
+ *value = c - 5;
+ *len = 1;
+ return;
+ }
+ if (BETWEEN(c, 1, 3)) {
+ gint i;
+ *value = 0;
+ guint8 byte;
+ for (i = 0; i < c; i++) {
+ byte = tvb_get_guint8(tvb, offset + 1 + i);
+ *value |= (byte << (8 * i));
+ }
+ *len = (c + 1);
+ return;
+ }
+ if (c < -6) {
+ *value = c + 5;
+ *len = 1;
+ return;
+ }
+ if (BETWEEN(c, -5, -1)) {
+ gint i;
+ *value = -1;
+ guint8 byte;
+ gint32 a;
+ gint32 b;
+ for (i = 0; i < -c; i++) {
+ byte = tvb_get_guint8(tvb, offset + 1 + i);
+ a = ~(0xff << (8*i));
+ b = byte << (8*i);
+ *value = ((*value & a) | b);
+ }
+ *len = (-c + 1);
+ return;
+ }
+}
+
+static void dissect_rbm_integer(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, gchar** value_str)
+{
+ gint32 value = 0;
+ gint len = 0;
+ rbm_set_info(pinfo, "integer");
+ get_rbm_integer(tvb, *offset, &value, &len);
+ proto_tree_add_int_format_value(tree, hf_rbm_integer, tvb, *offset, len, value, "%d", value);
+ *offset += len;
+ if (value_str)
+ *value_str = wmem_strdup_printf(pinfo->pool, "%d", value);
+}
+
+static void dissect_rbm_basic(tvbuff_t* tvb _U_, packet_info* pinfo, proto_tree* tree _U_, guint* offset _U_, const guint8 subtype,
+ gchar** type, gchar** value_str)
+{
+ switch (subtype) {
+ case '0':
+ *type = "nil";
+ break;
+ case 'T':
+ *type = "Boolean";
+ *value_str = "true";
+ break;
+ case 'F':
+ *type = "Boolean";
+ *value_str = "false";
+ break;
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ }
+ rbm_set_info(pinfo, *type);
+}
+
+static void dissect_rbm_string_data_trailer(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, const gchar* label,
+ const gchar* prefix, const gchar* trailer, gchar** value_str)
+{
+ gint32 value = 0;
+ gint len = 0;
+ const char* s;
+
+ rbm_set_info(pinfo, label);
+
+ get_rbm_integer(tvb, *offset, &value, &len);
+ proto_tree_add_int_format_value(tree, hf_rbm_length, tvb, *offset, len, value, "%d", value);
+ *offset += len;
+ s = (const char*)tvb_get_string_enc(pinfo->pool, tvb, *offset, value, ENC_NA);
+ proto_tree_add_string_format_value(tree, hf_rbm_string, tvb, *offset, value, s, "%s%s%s", prefix, s, trailer);
+ *offset += value;
+ *value_str = wmem_strdup_printf(pinfo->pool, "%s%s%s", prefix, s, trailer);
+}
+
+static void dissect_rbm_string_data(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, const gchar* label,
+ const gchar* prefix, gchar** value_str)
+{
+ dissect_rbm_string_data_trailer(tvb, pinfo, tree, offset, label, prefix, "", value_str);
+}
+
+static void dissect_rbm_array(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, gchar** value_str)
+{
+ gint32 value;
+ gint len;
+ gint32 i;
+ proto_tree* array_tree = NULL;
+ proto_tree* array_obj_tree = NULL;
+ gint offset_start = *offset;
+
+ rbm_set_info(pinfo, "Array");
+ get_rbm_integer(tvb, *offset, &value, &len);
+ proto_tree_add_int_format_value(tree, hf_rbm_length, tvb, *offset, len, value, "%d", value);
+ array_tree = proto_tree_add_subtree(tree, tvb, *offset, 0, ett_array, NULL, "Array");
+ *offset += len;
+
+ for (i = 0; i < value; i++) {
+ array_obj_tree = proto_tree_add_subtree(array_tree, tvb, *offset, 0, ett_array_obj, NULL, "Object");
+ dissect_rbm_object(tvb, pinfo, array_obj_tree, offset, NULL, NULL);
+ }
+ proto_item_append_text(array_tree, " (%d)", value);
+ proto_item_set_len(array_tree, *offset - offset_start);
+
+ if (value_str)
+ *value_str = wmem_strdup_printf(pinfo->pool, "%d", value);
+}
+
+static void dissect_rbm_hash(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, gchar** value_str)
+{
+ gint32 value;
+ gint len;
+ gint32 i;
+ proto_tree* hash_tree = NULL;
+ proto_tree* hash_obj_tree = NULL;
+ proto_tree* hash_key_tree = NULL;
+ proto_tree* hash_value_tree = NULL;
+ gchar* hkey = NULL;
+ gchar* hval = NULL;
+ gint offset_start = *offset;
+
+ rbm_set_info(pinfo, "Hash");
+ get_rbm_integer(tvb, *offset, &value, &len);
+ proto_tree_add_int_format_value(tree, hf_rbm_length, tvb, *offset, len, value, "%d", value);
+ hash_tree = proto_tree_add_subtree(tree, tvb, *offset, 0, ett_hash, NULL, "Hash");
+ *offset += len;
+
+ for (i = 0; i < value; i++) {
+ hash_obj_tree = proto_tree_add_subtree(hash_tree, tvb, *offset, 0, ett_hash_obj, NULL, "Entry");
+ hash_key_tree = proto_tree_add_subtree(hash_obj_tree, tvb, *offset, 0, ett_hash_obj, NULL, "Key");
+ dissect_rbm_object(tvb, pinfo, hash_key_tree, offset, NULL, &hkey);
+ hash_value_tree = proto_tree_add_subtree(hash_obj_tree, tvb, *offset, 0, ett_hash_obj, NULL, "Value");
+ dissect_rbm_object(tvb, pinfo, hash_value_tree, offset, NULL, &hval);
+ proto_item_append_text(hash_obj_tree, " %s => %s", hkey, hval);
+ }
+ proto_item_append_text(hash_tree, " (%d)", value);
+ proto_item_set_len(hash_tree, *offset - offset_start);
+
+ if (value_str)
+ *value_str = wmem_strdup_printf(pinfo->pool, "%d", value);
+}
+
+static void dissect_rbm_link(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, guint8 subtype,
+ gchar** type, gchar** value_str)
+{
+ gint32 value;
+ gint len;
+ gchar* label;
+
+ switch (subtype) {
+ case ';':
+ label = "Symbol";
+ break;
+ case '@':
+ label = "Object";
+ break;
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ }
+
+ rbm_set_info(pinfo, wmem_strdup_printf(pinfo->pool, "%s Link", label));
+ get_rbm_integer(tvb, *offset, &value, &len);
+ proto_tree_add_int_format_value(tree, hf_rbm_link, tvb, *offset, len, value, "%d", value);
+ *offset += len;
+ if (type)
+ *type = label;
+ if (value_str)
+ *value_str = wmem_strdup_printf(pinfo->pool, "%d", value);
+}
+
+static void dissect_rbm_double(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, gchar** value_str)
+{
+ gint32 value = 0;
+ gdouble valued;
+ gint len = 0;
+ const char* s;
+
+ rbm_set_info(pinfo, "Double");
+
+ get_rbm_integer(tvb, *offset, &value, &len);
+ proto_tree_add_int_format_value(tree, hf_rbm_length, tvb, *offset, len, value, "%d", value);
+ *offset += len;
+ s = (const char*)tvb_get_string_enc(pinfo->pool, tvb, *offset, value, ENC_NA);
+ valued = g_ascii_strtod(s, NULL);
+ proto_tree_add_double(tree, hf_rbm_double, tvb, *offset, value, valued);
+ *offset += value;
+ if (value_str)
+ *value_str = wmem_strdup_printf(pinfo->pool, "%f", valued);
+}
+
+static void dissect_rbm_struct_data(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, gchar** value_str)
+{
+ gint32 value = 0;
+ gint len = 0;
+
+ if (tvb_get_guint8(tvb, *offset) != ':')
+ return;
+ *offset += 1;
+
+ rbm_set_info(pinfo, "Struct");
+ get_rbm_integer(tvb, *offset, &value, &len);
+ proto_tree_add_item(tree, hf_rbm_struct, tvb, *offset + 1, value, ENC_ASCII);
+ *offset += 1 + value;
+ if (value_str)
+ *value_str = wmem_strdup_printf(pinfo->pool, "%d", value);
+}
+
+static void dissect_rbm_string(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, gchar** value)
+{
+ dissect_rbm_string_data(tvb, pinfo, tree, offset, "String", "", value);
+ dissect_rbm_integer(tvb, pinfo, tree, offset, NULL);
+ dissect_rbm_object(tvb, pinfo, tree, offset, NULL, NULL);
+ dissect_rbm_object(tvb, pinfo, tree, offset, NULL, NULL);
+}
+
+static void dissect_rbm_regex(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, gchar** value)
+{
+ dissect_rbm_string_data_trailer(tvb, pinfo, tree, offset, "Regexp", "/", "/", value);
+ proto_tree_add_item(tree, hf_rbm_regex_param, tvb, *offset, 1, ENC_NA);
+ *offset += 1;
+ dissect_rbm_integer(tvb, pinfo, tree, offset, NULL);
+ dissect_rbm_object(tvb, pinfo, tree, offset, NULL, NULL);
+ dissect_rbm_object(tvb, pinfo, tree, offset, NULL, NULL);
+}
+
+static void dissect_rbm_class(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, gchar** value_str)
+{
+ dissect_rbm_string_data(tvb, pinfo, tree, offset, "Class", "", value_str);
+}
+
+static void dissect_rbm_userclass(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, gchar** value)
+{
+ rbm_set_info(pinfo, "UserClass");
+ dissect_rbm_object(tvb, pinfo, tree, offset, NULL, value);
+}
+
+static void dissect_rbm_symbol(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, gchar** value_str)
+{
+ dissect_rbm_string_data(tvb, pinfo, tree, offset, "Symbol", ":", value_str);
+}
+
+static void dissect_rbm_variable(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, gchar** value_str)
+{
+ gint offset_start = *offset;
+ proto_tree* variable_tree = proto_tree_add_subtree(tree, tvb, *offset, 0, ett_variable, NULL, "Variable");
+ dissect_rbm_object(tvb, pinfo, variable_tree, offset, NULL, value_str);
+ proto_item_set_len(variable_tree, *offset - offset_start);
+}
+
+static void dissect_rbm_module(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, gchar** value_str)
+{
+ dissect_rbm_string_data(tvb, pinfo, tree, offset, "Module", "", value_str);
+}
+
+static void dissect_rbm_struct(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, gchar** value)
+{
+ dissect_rbm_struct_data(tvb, pinfo, tree, offset, value);
+ dissect_rbm_hash(tvb, pinfo, tree, offset, NULL);
+}
+
+static void dissect_rbm_drb(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset)
+{
+ gint offset_start = *offset;
+ proto_tree* drb_tree = proto_tree_add_subtree(tree, tvb, *offset, 0, ett_variable, NULL, "Objects");
+ dissect_rbm_object(tvb, pinfo, drb_tree, offset, NULL, NULL);
+ dissect_rbm_object(tvb, pinfo, drb_tree, offset, NULL, NULL);
+ proto_item_set_len(drb_tree, *offset - offset_start);
+}
+
+static void dissect_rbm_rubyobject(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset)
+{
+ gint offset_start = *offset;
+ proto_tree* obj_tree = proto_tree_add_subtree(tree, tvb, *offset, 0, ett_variable, NULL, "Ruby Object");
+
+ rbm_set_info(pinfo, "Ruby Object");
+
+ dissect_rbm_object(tvb, pinfo, obj_tree, offset, NULL, NULL);
+ dissect_rbm_hash(tvb, pinfo, obj_tree, offset, NULL);
+
+ while (tvb_captured_length_remaining(tvb, *offset)) {
+ dissect_rbm_object(tvb, pinfo, obj_tree, offset, NULL, NULL);
+ }
+
+ proto_item_set_len(obj_tree, *offset - offset_start);
+}
+
+static void dissect_rbm_extended(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset)
+{
+ gint offset_start = *offset;
+ proto_tree* ext_tree = proto_tree_add_subtree(tree, tvb, *offset, 0, ett_variable, NULL, "Extended");
+
+ rbm_set_info(pinfo, "Extended");
+ dissect_rbm_object(tvb, pinfo, ext_tree, offset, NULL, NULL);
+ proto_item_set_len(ext_tree, *offset - offset_start);
+}
+
+static void dissect_rbm_object(tvbuff_t* tvb, packet_info* pinfo, proto_tree* ptree, guint* offset, gchar** type, gchar** value)
+{
+ guint8 subtype = tvb_get_guint8(tvb, *offset);
+ proto_tree* tree;
+ gchar* type_local = "Unknown";
+ gchar* value_local = "Unknown";
+ gint offset_start = *offset;
+
+ tree = proto_tree_add_subtree(ptree, tvb, *offset, 0, ett_variable, NULL, "");
+
+ proto_tree_add_item(tree, hf_rbm_type, tvb, *offset, 1, ENC_NA);
+ *offset += 1;
+
+ switch (subtype) {
+ case '0':
+ case 'T':
+ case 'F':
+ dissect_rbm_basic(tvb, pinfo, tree, offset, subtype, &type_local, &value_local);
+ break;
+ case 'i':
+ type_local = "Integer";
+ dissect_rbm_integer(tvb, pinfo, tree, offset, &value_local);
+ break;
+ case ':':
+ type_local = "Symbol";
+ dissect_rbm_symbol(tvb, pinfo, tree, offset, &value_local);
+ break;
+ case '"':
+ type_local = "String";
+ dissect_rbm_string(tvb, pinfo, tree, offset, &value_local);
+ break;
+ case 'I':
+ type_local = "Instance Variable";
+ dissect_rbm_variable(tvb, pinfo, tree, offset, &value_local);
+ break;
+ case '[':
+ type_local = "Array";
+ dissect_rbm_array(tvb, pinfo, tree, offset, &value_local);
+ break;
+ case '{':
+ type_local = "Hash";
+ dissect_rbm_hash(tvb, pinfo, tree, offset, &value_local);
+ break;
+ case ';':
+ case '@':
+ dissect_rbm_link(tvb, pinfo, tree, offset, subtype, &type_local, &value_local);
+ break;
+ case 'f':
+ type_local = "Double";
+ dissect_rbm_double(tvb, pinfo, tree, offset, &value_local);
+ break;
+ case 'c':
+ type_local = "Class";
+ dissect_rbm_class(tvb, pinfo, tree, offset, &value_local);
+ break;
+ case 'm':
+ type_local = "Module";
+ dissect_rbm_module(tvb, pinfo, tree, offset, &value_local);
+ break;
+ case 'S':
+ type_local = "Struct";
+ dissect_rbm_struct(tvb, pinfo, tree, offset, &value_local);
+ break;
+ case '/':
+ type_local = "Regex";
+ dissect_rbm_regex(tvb, pinfo, tree, offset, &value_local);
+ break;
+ case 'u':
+ type_local = "DRb::DRbObject";
+ dissect_rbm_drb(tvb, pinfo, tree, offset);
+ break;
+ case ',':
+ dissect_rbm_inline(tvb, pinfo, tree, offset, &type_local, &value_local);
+ break;
+ case 'o':
+ dissect_rbm_rubyobject(tvb, pinfo, tree, offset);
+ type_local = "Ruby Object";
+ break;
+ case 'C':
+ type_local = "UserClass";
+ dissect_rbm_userclass(tvb, pinfo, tree, offset, &value_local);
+ break;
+ case 'e':
+ type_local = "Extended Object";
+ dissect_rbm_extended(tvb, pinfo, tree, offset);
+ break;
+ default:
+ expert_add_info_format(pinfo, tree, &ei_rbm_invalid,
+ "Object type 0x%x is invalid", subtype);
+ *offset += tvb_reported_length_remaining(tvb, *offset);
+ }
+
+ proto_item_set_len(tree, *offset - offset_start);
+
+ proto_item_append_text(tree, "Type: %s", type_local);
+ if (value_local && strlen(value_local))
+ proto_item_append_text(tree, ", Value: %s", value_local);
+
+ if (type)
+ *type = type_local;
+ if (value)
+ *value = value_local;
+}
+
+static gboolean dissect_rbm_header(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset)
+{
+ guint8 major;
+ guint8 minor;
+ gchar* version;
+
+ major = tvb_get_guint8(tvb, *offset);
+ minor = tvb_get_guint8(tvb, *offset + 1);
+
+ version = wmem_strdup_printf(pinfo->pool, "%u.%u", major, minor);
+ proto_tree_add_string_format(tree, hf_rbm_version, tvb, *offset, 2, version, "Version: %s", version);
+ *offset += 2;
+
+ if (major != RUBY_MARSHAL_MAJOR || minor != RUBY_MARSHAL_MINOR) {
+ expert_add_info_format(pinfo, tree, &ei_rbm_version_unsupported, "Version %u.%u is not supported (only %u.%u)",
+ major, minor, RUBY_MARSHAL_MAJOR, RUBY_MARSHAL_MINOR);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void dissect_rbm_inline(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint* offset, gchar** type, gchar** value)
+{
+ if (!dissect_rbm_header(tvb, pinfo, tree, offset))
+ return;
+ dissect_rbm_object(tvb, pinfo, tree, offset, type, value);
+}
+
+static int dissect_rbm(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
+{
+ guint offset = 0;
+ proto_item* ti;
+ proto_tree* rbm_tree;
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "Rbm");
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ ti = proto_tree_add_item(tree, proto_rbm, tvb, 0, -1, ENC_NA);
+ rbm_tree = proto_item_add_subtree(ti, ett_rbm);
+
+ dissect_rbm_inline(tvb, pinfo, rbm_tree, &offset, NULL, NULL);
+ return offset;
+}
+
+void proto_register_rbm(void)
+{
+ expert_module_t* expert_rbm;
+
+ static hf_register_info hf[] = {
+ { &hf_rbm_version,
+ { "Version", "rbm.version", FT_STRING, BASE_NONE, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_rbm_type,
+ { "Type", "rbm.type", FT_UINT8, BASE_HEX, VALS(rbm_types), 0x00, NULL, HFILL }
+ },
+ { &hf_rbm_integer,
+ { "Integer", "rbm.int", FT_INT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_rbm_length,
+ { "Length", "rbm.length", FT_INT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_rbm_string,
+ { "Value", "rbm.string", FT_STRING, BASE_NONE, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_rbm_link,
+ { "Link to object", "rbm.link", FT_INT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_rbm_double,
+ { "Value", "rbm.double", FT_DOUBLE, BASE_NONE, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_rbm_struct,
+ { "Struct", "rbm.struct", FT_STRING, BASE_NONE, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_rbm_regex_param,
+ { "Regexp parameter", "rbm.regex.param", FT_UINT8, BASE_DEC, NULL, 0x00, NULL, HFILL }
+ }
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_rbm_invalid, { "rbm.invalid", PI_UNDECODED, PI_WARN, "Invalid type", EXPFILL }},
+ { &ei_rbm_version_unsupported, { "rbm.version.unsupported", PI_UNDECODED, PI_WARN, "Unsupported version", EXPFILL }}
+ };
+
+ /* Setup protocol subtree array */
+ static gint* ett[] = {
+ &ett_rbm,
+ &ett_array,
+ &ett_array_obj,
+ &ett_hash,
+ &ett_hash_obj,
+ &ett_variable
+ };
+
+ proto_rbm = proto_register_protocol("Ruby Marshal Object", "Rbm", "rbm");
+
+ expert_rbm = expert_register_protocol(proto_rbm);
+ expert_register_field_array(expert_rbm, ei, array_length(ei));
+
+ proto_register_field_array(proto_rbm, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+ rbm_file_handle = register_dissector("rbm", dissect_rbm, proto_rbm);
+}
+
+void proto_reg_handoff_rbm(void)
+{
+ dissector_add_uint("wtap_encap", WTAP_ENCAP_RUBY_MARSHAL, rbm_file_handle);
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */