aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>2005-01-14 11:17:35 +0000
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>2005-01-14 11:17:35 +0000
commit2eda8ba6de40577173d720c77d174f7278231154 (patch)
treea79c77ef3f2e52eba3b13c62b701e3299b5a1fbd /epan/dissectors
parentb33d73dd31473aa6ced347cad53a2f3ee12474f9 (diff)
From Stefano Pettini: RMT support for ALC and NORM.
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@13029 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/Makefile.common10
-rw-r--r--epan/dissectors/packet-rmt-alc.c276
-rw-r--r--epan/dissectors/packet-rmt-alc.h81
-rw-r--r--epan/dissectors/packet-rmt-common.c122
-rw-r--r--epan/dissectors/packet-rmt-common.h59
-rw-r--r--epan/dissectors/packet-rmt-fec.c270
-rw-r--r--epan/dissectors/packet-rmt-fec.h138
-rw-r--r--epan/dissectors/packet-rmt-lct.c469
-rw-r--r--epan/dissectors/packet-rmt-lct.h185
-rw-r--r--epan/dissectors/packet-rmt-norm.c281
-rw-r--r--epan/dissectors/packet-rmt-norm.h82
11 files changed, 1973 insertions, 0 deletions
diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common
index 610cf1504b..15b63ee73d 100644
--- a/epan/dissectors/Makefile.common
+++ b/epan/dissectors/Makefile.common
@@ -438,6 +438,11 @@ DISSECTOR_SRC = \
packet-rmcp.c \
packet-rmi.c \
packet-rmp.c \
+ packet-rmt-alc.c \
+ packet-rmt-common.c \
+ packet-rmt-fec.c \
+ packet-rmt-lct.c \
+ packet-rmt-norm.c \
packet-rpc.c \
packet-rpl.c \
packet-rquota.c \
@@ -716,6 +721,11 @@ DISSECTOR_INCLUDES = \
packet-raw.h \
packet-ripng.h \
packet-rmi.h \
+ packet-rmt-alc.h \
+ packet-rmt-common.h \
+ packet-rmt-fec.h \
+ packet-rmt-lct.h \
+ packet-rmt-norm.h \
packet-rpc.h \
packet-rquota.h \
packet-rsvp.h \
diff --git a/epan/dissectors/packet-rmt-alc.c b/epan/dissectors/packet-rmt-alc.c
new file mode 100644
index 0000000000..c882bd2a02
--- /dev/null
+++ b/epan/dissectors/packet-rmt-alc.c
@@ -0,0 +1,276 @@
+/* packet-rmt-alc.c
+ * Reliable Multicast Transport (RMT)
+ * ALC Protocol Instantiation dissector
+ * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
+ *
+ * Asynchronous Layered Coding (ALC):
+ * ----------------------------------
+ *
+ * A massively scalable reliable content delivery protocol.
+ * Asynchronous Layered Coding combines the Layered Coding Transport
+ * (LCT) building block, a multiple rate congestion control building
+ * block and the Forward Error Correction (FEC) building block to
+ * provide congestion controlled reliable asynchronous delivery of
+ * content to an unlimited number of concurrent receivers from a single
+ * sender.
+ *
+ * References:
+ * RFC 3450, Asynchronous Layered Coding protocol instantiation
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/prefs.h>
+
+#include "packet-rmt-alc.h"
+
+/* Initialize the protocol and registered fields */
+/* ============================================= */
+
+static int proto = -1;
+
+static struct _alc_hf hf;
+static struct _alc_ett ett;
+
+static gboolean preferences_initialized = FALSE;
+static struct _alc_prefs preferences;
+static struct _alc_prefs preferences_old;
+
+/* Preferences */
+/* =========== */
+
+/* Set/Reset preferences to default values */
+static void alc_prefs_set_default(struct _alc_prefs *prefs)
+{
+ prefs->use_default_udp_port = FALSE;
+ prefs->default_udp_port = 4001;
+
+ lct_prefs_set_default(&prefs->lct);
+ fec_prefs_set_default(&prefs->fec);
+}
+
+/* Register preferences */
+static void alc_prefs_register(struct _alc_prefs *prefs, module_t *module)
+{
+ prefs_register_bool_preference(module,
+ "default.udp_port.enabled",
+ "Use default UDP port",
+ "Whether that payload of UDP packets with a specific destination port should be automatically dissected as ALC packets",
+ &prefs->use_default_udp_port);
+
+ prefs_register_uint_preference(module,
+ "default.udp_port",
+ "Default UDP destination port",
+ "Specifies the UDP destination port for automatic dissection of ALC packets",
+ 10, &prefs->default_udp_port);
+
+ lct_prefs_register(&prefs->lct, module);
+ fec_prefs_register(&prefs->fec, module);
+}
+
+/* Save preferences to alc_prefs_old */
+static void alc_prefs_save(struct _alc_prefs *p, struct _alc_prefs *p_old)
+{
+ *p_old = *p;
+}
+
+/* Code to actually dissect the packets */
+/* ==================================== */
+
+static void dissect_alc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ /* Logical packet representation */
+ struct _alc alc;
+
+ /* Offset for subpacket dissection */
+ guint offset;
+
+ /* Set up structures needed to add the protocol subtree and manage it */
+ proto_item *ti;
+ proto_tree *alc_tree;
+
+ /* Structures and variables initialization */
+ offset = 0;
+ memset(&alc, 0, sizeof(struct _alc));
+
+ /* Update packet info */
+ pinfo->current_proto = "ALC";
+
+ /* Make entries in Protocol column and Info column on summary display */
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "ALC");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ /* ALC header dissection */
+ /* --------------------- */
+
+ alc.version = hi_nibble(tvb_get_guint8(tvb, offset));
+
+ if (tree)
+ {
+ /* Create subtree for the ALC protocol */
+ ti = proto_tree_add_item(tree, proto, tvb, offset, -1, FALSE);
+ alc_tree = proto_item_add_subtree(ti, ett.main);
+
+ /* Fill the ALC subtree */
+ proto_tree_add_uint(alc_tree, hf.version, tvb, offset, 1, alc.version);
+
+ } else
+ alc_tree = NULL;
+
+ /* This dissector supports only ALCv1 packets.
+ * If alc.version > 1 print only version field and quit.
+ */
+ if (alc.version == 1) {
+
+ struct _lct_ptr l;
+ struct _fec_ptr f;
+
+ l.lct = &alc.lct;
+ l.hf = &hf.lct;
+ l.ett = &ett.lct;
+ l.prefs = &preferences.lct;
+
+ f.fec = &alc.fec;
+ f.hf = &hf.fec;
+ f.ett = &ett.fec;
+ f.prefs = &preferences.fec;
+
+ /* LCT header dissection */
+ /* --------------------- */
+
+ lct_dissector(l, f, tvb, alc_tree, &offset);
+
+ /* FEC header dissection */
+ /* --------------------- */
+
+ /* Only if it's present and if LCT dissector has determined FEC Encoding ID
+ * FEC dissector should be called with fec->encoding_id* and fec->instance_id* filled
+ */
+ if (alc.fec.encoding_id_present && tvb_length(tvb) > offset)
+ fec_dissector(f, tvb, alc_tree, &offset);
+
+ /* Add the Payload item */
+ if (tvb_length(tvb) > offset)
+ proto_tree_add_none_format(alc_tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_length(tvb) - offset);
+
+ /* Complete entry in Info column on summary display */
+ /* ------------------------------------------------ */
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ {
+ lct_info_column(&alc.lct, pinfo);
+ fec_info_column(&alc.fec, pinfo);
+ }
+
+ /* Free g_allocated memory */
+ lct_dissector_free(&alc.lct);
+ fec_dissector_free(&alc.fec);
+
+ } else {
+
+ if (tree)
+ proto_tree_add_text(alc_tree, tvb, 0, -1, "Sorry, this dissector supports ALC version 1 only");
+
+ /* Complete entry in Info column on summary display */
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Version: %u (not supported)", alc.version);
+ }
+}
+
+void proto_reg_handoff_alc(void)
+{
+ static dissector_handle_t handle;
+
+ if (!preferences_initialized)
+ {
+ preferences_initialized = TRUE;
+ handle = create_dissector_handle(dissect_alc, proto);
+ dissector_add_handle("udp.port", handle);
+
+ } else {
+
+ if (preferences_old.use_default_udp_port)
+ dissector_delete("udp.port", preferences_old.default_udp_port, handle);
+ }
+
+ if (preferences.use_default_udp_port)
+ dissector_add("udp.port", preferences.default_udp_port, handle);
+
+ alc_prefs_save(&preferences, &preferences_old);
+}
+
+void proto_register_alc(void)
+{
+ /* Setup ALC header fields */
+ static hf_register_info hf_ptr[] = {
+
+ { &hf.version,
+ { "Version", "alc.version", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
+
+ LCT_FIELD_ARRAY(hf.lct, "alc"),
+ FEC_FIELD_ARRAY(hf.fec, "alc"),
+
+ { &hf.payload,
+ { "Payload", "alc.payload", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}
+ };
+
+ /* Setup protocol subtree array */
+ static gint *ett_ptr[] = {
+ &ett.main,
+
+ LCT_SUBTREE_ARRAY(ett.lct),
+ FEC_SUBTREE_ARRAY(ett.fec)
+ };
+
+ module_t *module;
+
+ /* Clear hf and ett fields */
+ memset(&hf, 0xff, sizeof(struct _alc_hf));
+ memset(&ett, 0xff, sizeof(struct _alc_ett));
+
+ /* Register the protocol name and description */
+ proto = proto_register_protocol("Asynchronous Layered Coding", "ALC", "alc");
+
+ /* Register the header fields and subtrees used */
+ proto_register_field_array(proto, hf_ptr, array_length(hf_ptr));
+ proto_register_subtree_array(ett_ptr, array_length(ett_ptr));
+
+ /* Reset preferences */
+ alc_prefs_set_default(&preferences);
+ alc_prefs_save(&preferences, &preferences_old);
+
+ /* Register preferences */
+ module = prefs_register_protocol(proto, proto_reg_handoff_alc);
+ alc_prefs_register(&preferences, module);
+}
diff --git a/epan/dissectors/packet-rmt-alc.h b/epan/dissectors/packet-rmt-alc.h
new file mode 100644
index 0000000000..a60e0cfdd4
--- /dev/null
+++ b/epan/dissectors/packet-rmt-alc.h
@@ -0,0 +1,81 @@
+/* packet-rmt-alc.h
+ * Reliable Multicast Transport (RMT)
+ * ALC Protocol Instantiation function definitions
+ * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PACKET_RMT_ALC__
+#define __PACKET_RMT_ALC__
+
+#include "packet-rmt-common.h"
+#include "packet-rmt-lct.h"
+#include "packet-rmt-fec.h"
+
+/* Type definitions */
+/* ================ */
+
+/* Logical ALC packet representation */
+struct _alc
+{
+ guint8 version;
+ struct _lct lct;
+ struct _fec fec;
+};
+
+/* Ethereal stuff */
+/* ============== */
+
+/* ALC header field definitions*/
+struct _alc_hf
+{
+ int version;
+
+ struct _lct_hf lct;
+ struct _fec_hf fec;
+
+ int payload;
+};
+
+/* ALC subtrees */
+struct _alc_ett
+{
+ gint main;
+
+ struct _lct_ett lct;
+ struct _fec_ett fec;
+};
+
+/* ALC preferences */
+struct _alc_prefs
+{
+ gboolean use_default_udp_port;
+ guint default_udp_port;
+
+ struct _lct_prefs lct;
+ struct _fec_prefs fec;
+};
+
+/* Function declarations */
+/* ===================== */
+
+#endif
diff --git a/epan/dissectors/packet-rmt-common.c b/epan/dissectors/packet-rmt-common.c
new file mode 100644
index 0000000000..7826d45e0f
--- /dev/null
+++ b/epan/dissectors/packet-rmt-common.c
@@ -0,0 +1,122 @@
+/* packet-rmt-common.c
+ * Reliable Multicast Transport (RMT)
+ * Common RMT functions
+ * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/strutil.h>
+
+#include "packet-rmt-common.h"
+
+/* Boolean string tables */
+const true_false_string boolean_set_notset = { "Set", "Not set" };
+const true_false_string boolean_yes_no = { "Yes", "No" };
+
+/* Common RMT exported functions */
+/* ============================= */
+
+/* Scan the tvb and put extensions found in an array */
+void rmt_ext_parse(GArray *a, tvbuff_t *tvb, guint *offset, guint offset_max)
+{
+ struct _ext e;
+
+ while (*offset < offset_max)
+ {
+ /* Clear the temporary extension */
+ memset(&e, 0, sizeof(struct _ext));
+
+ /* Dissect the extension */
+ e.offset = *offset;
+ e.het = tvb_get_guint8(tvb, *offset);
+
+ if (e.het <= 127) {
+ /* If HET <= 127, we have a variable-size extention */
+ e.hel = tvb_get_guint8(tvb, *offset+1);
+ e.hec_offset = *offset + 2;
+ e.hec_size = e.hel * 4 - 2;
+ e.length = e.hel * 4;
+ } else {
+ /* If HET > 127, we have a short 32-bit extention */
+ e.hel = 1; /* even if HEL field is not defined for HET > 127 */
+ e.hec_offset = *offset + 1;
+ e.hec_size = 3;
+ e.length = 4;
+ }
+
+ /* Prevents infinite loops */
+ if (e.length == 0)
+ break;
+
+ g_array_append_val(a, e);
+ *offset += e.length;
+ }
+}
+
+/* Add default items to a subtree */
+void rmt_ext_decode_default_header(struct _ext *e, tvbuff_t *tvb, proto_tree *tree)
+{
+ if (tree)
+ {
+ proto_tree_add_text(tree, tvb, e->offset, 1, "Header Extension Type (HET): %u", e->het);
+ if (e->het <= 127)
+ proto_tree_add_text(tree, tvb, e->offset+1, 1, "Header Extension Length (HEL): %u", e->hel);
+ }
+}
+
+/* Add a default subtree to a tree item */
+void rmt_ext_decode_default_subtree(struct _ext *e, tvbuff_t *tvb, proto_item *ti, gint ett)
+{
+ proto_tree *ext_tree;
+
+ ext_tree = proto_item_add_subtree(ti, ett);
+ rmt_ext_decode_default_header(e, tvb, ext_tree);
+
+ if (ext_tree)
+ proto_tree_add_text(ext_tree, tvb, e->hec_offset, e->hec_size,
+ "Header Extension Content (HEC): %s", tvb_bytes_to_str(tvb, e->hec_offset, e->hec_size));
+}
+
+/* Add a default subtree for unknown extensions */
+void rmt_ext_decode_default(struct _ext *e, tvbuff_t *tvb, proto_tree *tree, gint ett)
+{
+ proto_item *ti;
+
+ if (tree)
+ {
+ ti = proto_tree_add_text(tree, tvb, e->offset, e->length,
+ "Unknown extension (%u)", e->het);
+
+ rmt_ext_decode_default_subtree(e, tvb, ti, ett);
+ }
+}
diff --git a/epan/dissectors/packet-rmt-common.h b/epan/dissectors/packet-rmt-common.h
new file mode 100644
index 0000000000..b5dfb0c0c6
--- /dev/null
+++ b/epan/dissectors/packet-rmt-common.h
@@ -0,0 +1,59 @@
+/* packet-rmt-common.h
+ * Reliable Multicast Transport (RMT)
+ * Common RMT function definitions
+ * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PACKET_RMT_COMMON__
+#define __PACKET_RMT_COMMON__
+
+/* Boolean string tables external references */
+extern const true_false_string boolean_set_notset;
+extern const true_false_string boolean_yes_no;
+
+/* Type definitions */
+/* ================ */
+
+/* Logical header extension representation */
+struct _ext
+{
+ guint offset;
+ guint length;
+
+ guint8 het;
+ guint8 hel;
+
+ guint hec_offset;
+ guint8 hec_size;
+};
+
+/* Common RMT exported functions */
+/* ============================= */
+
+void rmt_ext_parse(GArray *a, tvbuff_t *tvb, guint *offset, guint offset_max);
+
+void rmt_ext_decode_default(struct _ext *e, tvbuff_t *tvb, proto_tree *tree, gint ett);
+void rmt_ext_decode_default_subtree(struct _ext *e, tvbuff_t *tvb, proto_tree *tree, gint ett);
+void rmt_ext_decode_default_header(struct _ext *e, tvbuff_t *tvb, proto_tree *tree);
+
+#endif
diff --git a/epan/dissectors/packet-rmt-fec.c b/epan/dissectors/packet-rmt-fec.c
new file mode 100644
index 0000000000..6c263c1b8f
--- /dev/null
+++ b/epan/dissectors/packet-rmt-fec.c
@@ -0,0 +1,270 @@
+/* packet-rmt-fec.c
+ * Reliable Multicast Transport (RMT)
+ * FEC Building Block dissector
+ * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
+ *
+ * Forward Error Correction (ALC):
+ * -------------------------------
+ *
+ * The goal of the FEC building block is to describe functionality
+ * directly related to FEC codes that is common to all reliable content
+ * delivery IP multicast protocols, and to leave out any additional
+ * functionality that is specific to particular protocols.
+ *
+ * References:
+ * RFC 3452, Forward Error Correction Building Block
+ * RFC 3695, Compact Forward Error Correction (FEC) Schemes
+ * Simple XOR, Reed-Solomon, and Parity Check Matrix-based FEC Schemes draft-peltotalo-rmt-bb-fec-supp-xor-pcm-rs-00
+ * IANA RMT FEC parameters (http://www.iana.org/assignments/rmt-fec-parameters)
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/prefs.h>
+
+#include "packet-rmt-fec.h"
+
+/* String tables */
+const value_string string_fec_encoding_id[] =
+{
+ { 0, "Compact No-Code" },
+ { 2, "Simple XOR, Reed-Solomon, and Parity Check Matrix-based FEC Codes" },
+ { 128, "Small Block, Large Block and Expandable FEC Codes" },
+ { 129, "Small Block Systematic FEC Codes" },
+ { 130, "Compact FEC Codes" },
+ { 132, "Simple XOR, Reed-Solomon, and Parity Check Matrix-based FEC Codes" },
+ { 0, NULL }
+};
+
+/* FEC exported functions */
+/* ====================== */
+
+/* Info */
+/* ---- */
+
+void fec_info_column(struct _fec *fec, packet_info *pinfo)
+{
+ if (fec->sbn_present)
+ col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", fec->sbn);
+
+ if (fec->esi_present)
+ col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", fec->esi);
+}
+
+/* Dissection */
+/* ---------- */
+
+/* Decode an EXT_FTI extension and fill FEC array */
+void fec_decode_ext_fti(struct _ext *e, tvbuff_t *tvb, proto_tree *tree, gint ett, struct _fec_ptr f)
+{
+ proto_item* ti = NULL;
+ proto_tree *ext_tree;
+
+ if (tree)
+ ti = proto_tree_add_none_format(tree, f.hf->fti_header, tvb, e->offset, e->length,
+ "EXT_FTI, FEC Object Transmission Information (%u)", e->het);
+
+ if (f.fec->encoding_id_present)
+ {
+ ext_tree = proto_item_add_subtree(ti, ett);
+ rmt_ext_decode_default_header(e, tvb, ext_tree);
+
+ /* Decode 48-bit length field */
+ f.fec->transfer_length = tvb_get_ntoh64(tvb, e->offset) & G_GINT64_CONSTANT(0xFFFFFFFFFFFFU);
+
+ if (f.fec->encoding_id >= 128)
+ {
+ /* Decode FEC Instance ID */
+ f.fec->instance_id_present = TRUE;
+ f.fec->instance_id = tvb_get_ntohs(tvb, e->offset+8);
+ }
+
+ if (tree)
+ proto_tree_add_uint64(ext_tree, f.hf->fti_transfer_length, tvb, e->offset+2, 6, f.fec->transfer_length);
+
+ switch (f.fec->encoding_id)
+ {
+ case 0:
+ case 2:
+ case 128:
+ case 130:
+ f.fec->encoding_symbol_length = tvb_get_ntohs(tvb, e->offset+10);
+ f.fec->max_source_block_length = tvb_get_ntohl(tvb, e->offset+12);
+
+ if (tree)
+ {
+ proto_tree_add_uint(ext_tree, f.hf->fti_encoding_symbol_length, tvb, e->offset+10, 2, f.fec->encoding_symbol_length);
+ proto_tree_add_uint(ext_tree, f.hf->fti_max_source_block_length, tvb, e->offset+12, 4, f.fec->max_source_block_length);
+ }
+ break;
+
+ case 129:
+ f.fec->encoding_symbol_length = tvb_get_ntohs(tvb, e->offset+10);
+ f.fec->max_source_block_length = tvb_get_ntohs(tvb, e->offset+12);
+ f.fec->max_number_encoding_symbols = tvb_get_ntohs(tvb, e->offset+14);
+
+ if (tree)
+ {
+ proto_tree_add_uint(ext_tree, f.hf->fti_encoding_symbol_length, tvb, e->offset+10, 2, f.fec->encoding_symbol_length);
+ proto_tree_add_uint(ext_tree, f.hf->fti_max_source_block_length, tvb, e->offset+12, 2, f.fec->max_source_block_length);
+ proto_tree_add_uint(ext_tree, f.hf->fti_max_number_encoding_symbols, tvb, e->offset+14, 2, f.fec->max_number_encoding_symbols);
+ }
+ break;
+
+ case 132:
+ f.fec->encoding_symbol_length = tvb_get_ntohs(tvb, e->offset+10);
+ f.fec->max_source_block_length = tvb_get_ntohl(tvb, e->offset+12);
+ f.fec->max_number_encoding_symbols = tvb_get_ntohl(tvb, e->offset+16);
+
+ if (tree)
+ {
+ proto_tree_add_uint(ext_tree, f.hf->fti_encoding_symbol_length, tvb, e->offset+10, 2, f.fec->encoding_symbol_length);
+ proto_tree_add_uint(ext_tree, f.hf->fti_max_source_block_length, tvb, e->offset+12, 4, f.fec->max_source_block_length);
+ proto_tree_add_uint(ext_tree, f.hf->fti_max_number_encoding_symbols, tvb, e->offset+16, 4, f.fec->max_number_encoding_symbols);
+ }
+ break;
+ }
+
+ } else
+ if (tree)
+ rmt_ext_decode_default_subtree(e, tvb, ti, ett);
+}
+
+/* Dissect a FEC header:
+ * fec - ptr to the logical FEC packet representation to fill
+ * hf - ptr to header fields array
+ * ett - ptr to ett array
+ * prefs - ptr to FEC prefs array
+ * tvb - buffer
+ * pinfo - packet info
+ * tree - tree where to add FEC header subtree
+ * offset - ptr to offset to use and update
+ */
+void fec_dissector(struct _fec_ptr f, tvbuff_t *tvb, proto_tree *tree, guint *offset)
+{
+ proto_item *ti;
+ proto_tree *fec_tree;
+
+ /* Create the FEC subtree */
+ if (tree)
+ {
+ ti = proto_tree_add_item(tree, f.hf->header, tvb, *offset, -1, FALSE);
+ fec_tree = proto_item_add_subtree(ti, f.ett->main);
+ } else
+ fec_tree = NULL;
+
+ /* FEC Encoding ID and FEC Instance ID processing */
+ if (f.fec->encoding_id_present)
+ {
+ if (tree)
+ {
+ proto_tree_add_uint(fec_tree, f.hf->encoding_id, tvb, *offset, 0, f.fec->encoding_id);
+
+ if (f.fec->encoding_id >= 128 && f.fec->instance_id_present)
+ proto_tree_add_uint(fec_tree, f.hf->instance_id, tvb, *offset, 0, f.fec->instance_id);
+ }
+
+ switch (f.fec->encoding_id)
+ {
+ case 0:
+ case 130:
+ f.fec->sbn = tvb_get_ntohs(tvb, *offset);
+ f.fec->esi = tvb_get_ntohs(tvb, *offset+2);
+
+ if (tree)
+ {
+ proto_tree_add_uint(fec_tree, f.hf->sbn, tvb, *offset, 2, f.fec->sbn);
+ proto_tree_add_uint(fec_tree, f.hf->esi, tvb, *offset+2, 2, f.fec->esi);
+ }
+
+ f.fec->sbn_present = TRUE;
+ f.fec->esi_present = TRUE;
+ *offset += 4;
+ break;
+
+ case 2:
+ case 128:
+ case 132:
+ f.fec->sbn = tvb_get_ntohl(tvb, *offset);
+ f.fec->esi = tvb_get_ntohl(tvb, *offset+4);
+
+ if (tree)
+ {
+ proto_tree_add_uint(fec_tree, f.hf->sbn, tvb, *offset, 4, f.fec->sbn);
+ proto_tree_add_uint(fec_tree, f.hf->esi, tvb, *offset+4, 4, f.fec->esi);
+ }
+
+ f.fec->sbn_present = TRUE;
+ f.fec->esi_present = TRUE;
+ *offset += 8;
+ break;
+
+ case 129:
+ f.fec->sbn = tvb_get_ntohl(tvb, *offset);
+ f.fec->sbl = tvb_get_ntohs(tvb, *offset+4);
+ f.fec->esi = tvb_get_ntohs(tvb, *offset+6);
+
+ if (tree)
+ {
+ proto_tree_add_uint(fec_tree, f.hf->sbn, tvb, *offset, 4, f.fec->sbn);
+ proto_tree_add_uint(fec_tree, f.hf->sbl, tvb, *offset+4, 2, f.fec->sbl);
+ proto_tree_add_uint(fec_tree, f.hf->esi, tvb, *offset+6, 2, f.fec->esi);
+ }
+
+ f.fec->sbn_present = TRUE;
+ f.fec->sbl_present = TRUE;
+ f.fec->esi_present = TRUE;
+ *offset += 8;
+ break;
+ }
+ }
+}
+
+void fec_dissector_free(struct _fec *fec)
+{
+
+}
+
+/* Preferences */
+/* ----------- */
+
+/* Set/Reset preferences to default values */
+void fec_prefs_set_default(struct _fec_prefs *prefs)
+{
+
+}
+
+/* Register preferences */
+void fec_prefs_register(struct _fec_prefs *prefs, module_t *module)
+{
+
+}
diff --git a/epan/dissectors/packet-rmt-fec.h b/epan/dissectors/packet-rmt-fec.h
new file mode 100644
index 0000000000..ca2eb9ac21
--- /dev/null
+++ b/epan/dissectors/packet-rmt-fec.h
@@ -0,0 +1,138 @@
+/* packet-rmt-fec.h
+ * Reliable Multicast Transport (RMT)
+ * FEC Building Block function definitions
+ * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PACKET_RMT_FEC__
+#define __PACKET_RMT_FEC__
+
+#include "packet-rmt-common.h"
+
+/* String tables external references */
+extern const value_string string_fec_encoding_id[];
+
+/* Type definitions */
+/* ================ */
+
+struct _fec
+{
+ gboolean encoding_id_present;
+ gboolean instance_id_present;
+ guint8 encoding_id;
+ guint8 instance_id;
+ guint64 transfer_length;
+ guint32 encoding_symbol_length;
+ guint32 max_source_block_length;
+ guint32 max_number_encoding_symbols;
+ gboolean sbn_present;
+ gboolean sbl_present;
+ gboolean esi_present;
+ guint32 sbn;
+ guint32 sbl;
+ guint32 esi;
+};
+
+/* Ethereal stuff */
+/* ============== */
+
+/* FEC header field definitions */
+struct _fec_hf
+{
+ int header;
+ int encoding_id;
+ int instance_id;
+ int sbn;
+ int sbl;
+ int esi;
+ int fti_header;
+ int fti_transfer_length;
+ int fti_encoding_symbol_length;
+ int fti_max_source_block_length;
+ int fti_max_number_encoding_symbols;
+};
+
+/* FEC subtrees */
+struct _fec_ett
+{
+ gint main;
+};
+
+/* FEC preferences */
+struct _fec_prefs
+{
+ gboolean dummy;
+};
+
+/* FEC pointers */
+struct _fec_ptr
+{
+ struct _fec *fec;
+ struct _fec_hf *hf;
+ struct _fec_ett *ett;
+ struct _fec_prefs *prefs;
+};
+
+/* Macros to generate static arrays */
+
+#define FEC_FIELD_ARRAY(base_structure, base_protocol) \
+ { &base_structure.header, \
+ { "Forward Error Correction (FEC) header", base_protocol ".fec", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.encoding_id, \
+ { "FEC Encoding ID", base_protocol ".fec.encoding_id", FT_UINT8, BASE_DEC, VALS(string_fec_encoding_id), 0x0, "", HFILL }}, \
+ { &base_structure.instance_id, \
+ { "FEC Instance ID", base_protocol ".fec.instance_id", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.sbn, \
+ { "Source Block Number", base_protocol ".fec.sbn", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.sbl, \
+ { "Source Block Length", base_protocol ".fec.sbl", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.esi, \
+ { "Encoding Symbol ID", base_protocol ".fec.esi", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.fti_header, \
+ { "FEC Object Transmission Information", base_protocol ".fec.fti", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.fti_transfer_length, \
+ { "Transfer Length", base_protocol ".fec.fti.transfer_length", FT_UINT64, BASE_DEC, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.fti_encoding_symbol_length, \
+ { "Encoding Symbol Length", base_protocol ".fec.fti.encoding_symbol_length", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.fti_max_source_block_length, \
+ { "Maximum Source Block Length", base_protocol ".fec.fti.max_source_block_length", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.fti_max_number_encoding_symbols, \
+ { "Maximum Number of Encoding Symbols", base_protocol ".fec.fti.max_number_encoding_symbols", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}
+
+#define FEC_SUBTREE_ARRAY(base_structure) \
+ &base_structure.main
+
+/* FEC exported functions */
+/* ====================== */
+
+void fec_info_column(struct _fec *fec, packet_info *pinfo);
+
+void fec_dissector(struct _fec_ptr f, tvbuff_t *tvb, proto_tree *tree, guint *offset);
+void fec_dissector_free(struct _fec *fec);
+
+void fec_decode_ext_fti(struct _ext *e, tvbuff_t *tvb, proto_tree *tree, gint ett, struct _fec_ptr f);
+
+void fec_prefs_set_default(struct _fec_prefs *prefs);
+void fec_prefs_register(struct _fec_prefs *prefs, module_t *module);
+
+#endif
diff --git a/epan/dissectors/packet-rmt-lct.c b/epan/dissectors/packet-rmt-lct.c
new file mode 100644
index 0000000000..7dce3c9716
--- /dev/null
+++ b/epan/dissectors/packet-rmt-lct.c
@@ -0,0 +1,469 @@
+/* packet-rmt-lct.c
+ * Reliable Multicast Transport (RMT)
+ * LCT Building Block dissector
+ * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
+ *
+ * Layered Coding Transport (LCT):
+ * -------------------------------
+ *
+ * Provides transport level support for reliable content delivery
+ * and stream delivery protocols. LCT is specifically designed to
+ * support protocols using IP multicast, but also provides support
+ * to protocols that use unicast. LCT is compatible with congestion
+ * control that provides multiple rate delivery to receivers and
+ * is also compatible with coding techniques that provide
+ * reliable delivery of content.
+ *
+ * References:
+ * RFC 3451, Layered Coding Transport (LCT) Building Block
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/prefs.h>
+#include <epan/strutil.h>
+
+#include "packet-rmt-lct.h"
+
+/* Enumerated data types for LCT preferences */
+static const enum_val_t enum_lct_ext_192[] =
+{
+ { "none", "Don't decode", LCT_PREFS_EXT_192_NONE },
+ { "flute", "Decode as FLUTE extension (EXT_FDT)", LCT_PREFS_EXT_192_FLUTE },
+ { NULL, NULL, 0 }
+};
+
+static const enum_val_t enum_lct_ext_193[] =
+{
+ { "none", "Don't decode", LCT_PREFS_EXT_193_NONE },
+ { "flute", "Decode as FLUTE extension (EXT_CENC)", LCT_PREFS_EXT_193_FLUTE },
+ { NULL, NULL, 0 }
+};
+
+/* LCT helper functions */
+/* ==================== */
+
+static void lct_timestamp_parse(guint32 t, nstime_t* s)
+{
+ s->secs = t / 1000;
+ s->nsecs = (t % 1000) * 1000000;
+}
+
+static void lct_ext_decode(struct _ext *e, struct _lct_prefs *prefs, tvbuff_t *tvb, proto_tree *tree, gint ett, struct _fec_ptr f)
+{
+ guint32 buffer32;
+ proto_item *ti;
+ proto_tree *ext_tree;
+
+ switch (e->het)
+ {
+
+ /* EXT_NOP */
+ case 0:
+ if (tree)
+ {
+ ti = proto_tree_add_text(tree, tvb, e->offset, e->length,
+ "EXT_NOP, No-Operation (0)");
+
+ rmt_ext_decode_default_subtree(e, tvb, ti, ett);
+ }
+ break;
+
+ /* EXT_AUTH */
+ case 1:
+ if (tree)
+ {
+ ti = proto_tree_add_text(tree, tvb, e->offset, e->length,
+ "EXT_AUTH, Packet authentication (1)");
+
+ rmt_ext_decode_default_subtree(e, tvb, ti, ett);
+ }
+ break;
+
+ /* EXT_FTI */
+ case 64:
+ fec_decode_ext_fti(e, tvb, tree, ett, f);
+ break;
+
+ /* EXT_FDT */
+ case 192:
+ switch (prefs->ext_192)
+ {
+ case LCT_PREFS_EXT_192_NONE:
+ rmt_ext_decode_default(e, tvb, tree, ett);
+ break;
+
+ case LCT_PREFS_EXT_192_FLUTE:
+ if (tree)
+ {
+ ti = proto_tree_add_text(tree, tvb, e->offset, e->length,
+ "EXT_FDT, FDT Instance Header (192)");
+
+ ext_tree = proto_item_add_subtree(ti, ett);
+ buffer32 = tvb_get_ntohl(tvb, e->offset);
+
+ rmt_ext_decode_default_header(e, tvb, ext_tree);
+
+ proto_tree_add_text(ext_tree, tvb, e->offset+1, 1,
+ "FLUTE version (V): %u", (buffer32 & 0x00F00000) >> 20);
+
+ proto_tree_add_text(ext_tree, tvb, e->offset+1, 3,
+ "FDT Instance ID: %u", buffer32 & 0x000FFFFF);
+ }
+ break;
+ }
+ break;
+
+ /* EXT_CENC */
+ case 193:
+ switch (prefs->ext_193)
+ {
+ case LCT_PREFS_EXT_193_NONE:
+ rmt_ext_decode_default(e, tvb, tree, ett);
+ break;
+
+ case LCT_PREFS_EXT_193_FLUTE:
+ if (tree)
+ {
+ ti = proto_tree_add_text(tree, tvb, e->offset, e->length,
+ "EXT_CENC, FDT Instance Content Encoding (193)");
+
+ ext_tree = proto_item_add_subtree(ti, ett);
+ buffer32 = tvb_get_ntohl(tvb, e->offset);
+
+ rmt_ext_decode_default_header(e, tvb, ext_tree);
+
+ proto_tree_add_text(ext_tree, tvb, e->offset+1, 1,
+ "Content Encoding Algorithm (CENC): %u", (buffer32 & 0x00FF0000) >> 16);
+ }
+ break;
+ }
+ break;
+
+ default:
+ rmt_ext_decode_default(e, tvb, tree, ett);
+ }
+}
+
+/* LCT exported functions */
+/* ====================== */
+
+/* Info */
+/* ---- */
+
+void lct_info_column(struct _lct *lct, packet_info *pinfo)
+{
+ if (lct->tsi_present)
+ col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "TSI: %" PRIu64, lct->tsi);
+
+ if (lct->toi_present)
+ {
+ if (lct->toi_size <= 8)
+ col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "TOI: %" PRIu64, lct->toi);
+ else
+ col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "TOI: 0x%s", bytes_to_str(lct->toi_extended, lct->toi_size));
+ }
+
+ if (lct->close_session)
+ col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Close session");
+
+ if (lct->close_object)
+ col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Close object");
+}
+
+/* Dissection */
+/* ---------- */
+
+/* Dissect an LCT header:
+ * l - ptr to the logical LCT packet representation to fill, and related ethereal stuffs
+ * f - ptr to the FEC infos to fill (EXT_FTI), and related ethereal stuffs
+ * tvb - buffer
+ * pinfo - packet info
+ * tree - tree where to add LCT header subtree
+ * offset - ptr to offset to use and update
+ */
+void lct_dissector(struct _lct_ptr l, struct _fec_ptr f, tvbuff_t *tvb, proto_tree *tree, guint *offset)
+{
+ guint i;
+ guint offset_old;
+ guint offset_start;
+ guint16 buffer16;
+
+ /* Set up structures needed to add the protocol subtree and manage it */
+ proto_item *ti;
+ proto_tree *lct_tree;
+ proto_tree *lct_fsize_tree;
+ proto_tree *lct_flags_tree;
+ proto_tree *lct_ext_tree;
+
+ /* LCT fixed-size fields dissection */
+ /* -------------------------------- */
+
+ offset_start = *offset;
+
+ buffer16 = tvb_get_ntohs(tvb, *offset);
+
+ l.lct->version = ((buffer16 & 0xF000) >> 12);
+
+ l.lct->cci_size = ((buffer16 & 0x0C00) >> 10) * 4 + 4;
+ l.lct->tsi_size = ((buffer16 & 0x0080) >> 7) * 4 + ((buffer16 & 0x0010) >> 4) * 2;
+ l.lct->toi_size = ((buffer16 & 0x0060) >> 5) * 4 + ((buffer16 & 0x0010) >> 4) * 2;
+
+ l.lct->tsi_present = (l.lct->tsi_size > 0);
+ l.lct->toi_present = (l.lct->toi_size > 0);
+ l.lct->sct_present = (buffer16 & 0x0008) != 0;
+ l.lct->ert_present = (buffer16 & 0x0004) != 0;
+ l.lct->close_session = (buffer16 & 0x0002) != 0;
+ l.lct->close_object = (buffer16 & 0x0001) != 0;
+
+ l.lct->hlen = tvb_get_guint8(tvb, *offset+2) * 4;
+ l.lct->codepoint = tvb_get_guint8(tvb, *offset+3);
+
+ if (l.prefs->codepoint_as_fec_encoding)
+ {
+ f.fec->encoding_id_present = TRUE;
+ f.fec->encoding_id = l.lct->codepoint;
+ }
+
+ if (tree)
+ {
+ /* Create the LCT subtree */
+ ti = proto_tree_add_item(tree, l.hf->header, tvb, *offset, l.lct->hlen, FALSE);
+ lct_tree = proto_item_add_subtree(ti, l.ett->main);
+
+ /* Fill the LCT subtree */
+ proto_tree_add_uint(lct_tree, l.hf->version, tvb, *offset, 1, l.lct->version);
+
+ ti = proto_tree_add_item(lct_tree, l.hf->fsize_header, tvb, *offset, 2, FALSE);
+ lct_fsize_tree = proto_item_add_subtree(ti, l.ett->fsize);
+
+ ti = proto_tree_add_item(lct_tree, l.hf->flags_header, tvb, *offset, 2, FALSE);
+ lct_flags_tree = proto_item_add_subtree(ti, l.ett->flags);
+
+ proto_tree_add_uint(lct_tree, l.hf->hlen, tvb, *offset+2, 1, l.lct->hlen);
+ proto_tree_add_uint(lct_tree, l.hf->codepoint, tvb, *offset+3, 1, l.lct->codepoint);
+
+ /* Fill the LCT fsize subtree */
+ proto_tree_add_uint(lct_fsize_tree, l.hf->fsize_cci, tvb, *offset, 1, l.lct->cci_size);
+ proto_tree_add_uint(lct_fsize_tree, l.hf->fsize_tsi, tvb, *offset+1, 1, l.lct->tsi_size);
+ proto_tree_add_uint(lct_fsize_tree, l.hf->fsize_toi, tvb, *offset+1, 1, l.lct->toi_size);
+
+ /* Fill the LCT flags subtree */
+ proto_tree_add_boolean(lct_flags_tree, l.hf->flags_sct_present, tvb, *offset+1, 1, l.lct->sct_present);
+ proto_tree_add_boolean(lct_flags_tree, l.hf->flags_ert_present, tvb, *offset+1, 1, l.lct->ert_present);
+ proto_tree_add_boolean(lct_flags_tree, l.hf->flags_close_session, tvb, *offset+1, 1, l.lct->close_session);
+ proto_tree_add_boolean(lct_flags_tree, l.hf->flags_close_object, tvb, *offset+1, 1, l.lct->close_object);
+
+ } else {
+ lct_tree = NULL;
+ lct_fsize_tree = NULL;
+ lct_flags_tree = NULL;
+ }
+
+ *offset += 4;
+
+ /* LCT variable-size and optional fields dissection */
+ /* ------------------------------------------------ */
+
+ /* Congestion Control Information (CCI) */
+ if (l.lct->cci_size > 0) {
+ l.lct->cci = (guint8*) tvb_get_ptr(tvb, *offset, l.lct->cci_size);
+ if (tree)
+ proto_tree_add_bytes(lct_tree, l.hf->cci, tvb, *offset, l.lct->cci_size, l.lct->cci);
+ *offset += l.lct->cci_size;
+ }
+
+ /* Transmission Session Identifier (TSI) */
+ if (l.lct->tsi_present) {
+
+ switch (l.lct->tsi_size)
+ {
+ case 0:
+ l.lct->tsi = 0;
+ break;
+
+ case 2:
+ l.lct->tsi = tvb_get_ntohs(tvb, *offset);
+ break;
+
+ case 4:
+ l.lct->tsi = tvb_get_ntohl(tvb, *offset);
+ break;
+
+ case 6:
+ l.lct->tsi = tvb_get_ntoh64(tvb, *offset-2) & G_GINT64_CONSTANT(0x0000FFFFFFFFFFFFU);
+ break;
+ }
+
+ if (tree)
+ proto_tree_add_uint64(lct_tree, l.hf->tsi, tvb, *offset, l.lct->tsi_size, l.lct->tsi);
+ *offset += l.lct->tsi_size;
+ }
+
+ /* Transmission Object Identifier (TOI) */
+ if (l.lct->toi_present) {
+
+ switch (l.lct->toi_size)
+ {
+ case 0:
+ l.lct->toi = 0;
+ break;
+
+ case 2:
+ l.lct->toi = tvb_get_ntohs(tvb, *offset);
+ break;
+
+ case 4:
+ l.lct->toi = tvb_get_ntohl(tvb, *offset);
+ break;
+
+ case 6:
+ l.lct->toi = tvb_get_ntoh64(tvb, *offset-2) & G_GINT64_CONSTANT(0x0000FFFFFFFFFFFFU);
+ break;
+
+ case 8:
+ l.lct->toi = tvb_get_ntoh64(tvb, *offset);
+ break;
+
+ case 10:
+ l.lct->toi = tvb_get_ntoh64(tvb, *offset+2);
+ break;
+
+ case 12:
+ l.lct->toi = tvb_get_ntoh64(tvb, *offset+4);
+ break;
+
+ case 14:
+ l.lct->toi = tvb_get_ntoh64(tvb, *offset)+6;
+ break;
+ }
+
+ l.lct->toi_extended = (guint8*) tvb_get_ptr(tvb, *offset, l.lct->toi_size);
+
+ if (tree)
+ {
+ if (l.lct->toi_size > 8)
+ proto_tree_add_uint64(lct_tree, l.hf->toi, tvb, *offset+(l.lct->toi_size-8), 8, l.lct->toi);
+ else
+ proto_tree_add_uint64(lct_tree, l.hf->toi, tvb, *offset, l.lct->toi_size, l.lct->toi);
+
+ proto_tree_add_bytes(lct_tree, l.hf->toi_extended, tvb, *offset, l.lct->toi_size, l.lct->toi_extended);
+ }
+
+ *offset += l.lct->toi_size;
+ }
+
+ /* Sender Current Time (SCT) */
+ if (l.lct->sct_present) {
+ lct_timestamp_parse(tvb_get_ntohl(tvb, *offset), &l.lct->sct);
+ if (tree)
+ proto_tree_add_time(lct_tree, l.hf->sct, tvb, *offset, 4, &l.lct->sct);
+ *offset += 4;
+ }
+
+ /* Expected Residual Time (ERT) */
+ if (l.lct->sct_present) {
+ lct_timestamp_parse(tvb_get_ntohl(tvb, *offset), &l.lct->ert);
+ if (tree)
+ proto_tree_add_time(lct_tree, l.hf->ert, tvb, *offset, 4, &l.lct->ert);
+ *offset += 4;
+ }
+
+ /* LCT header extensions, if applicable */
+ /* ------------------------------------ */
+
+ /* Allocate an array of _ext elements */
+ l.lct->ext = g_array_new(FALSE, TRUE, sizeof(struct _ext));
+
+ offset_old = *offset;
+ rmt_ext_parse(l.lct->ext, tvb, offset, offset_start + l.lct->hlen);
+
+ /* Resync the offset with the end of LCT header */
+ *offset = offset_start + l.lct->hlen;
+
+ if (l.lct->ext->len > 0)
+ {
+ if (tree)
+ {
+ /* Add the extensions subtree */
+ ti = proto_tree_add_uint(lct_tree, l.hf->ext, tvb, offset_old, *offset - offset_old, l.lct->ext->len);
+ lct_ext_tree = proto_item_add_subtree(ti, l.ett->ext);
+ } else
+ lct_ext_tree = NULL;
+
+ /* Add the extensions to the subtree */
+ for (i = 0; i < l.lct->ext->len; i++)
+ lct_ext_decode(&g_array_index(l.lct->ext, struct _ext, i), l.prefs, tvb, lct_ext_tree, l.ett->ext_ext, f);
+ }
+}
+
+void lct_dissector_free(struct _lct *lct)
+{
+ g_array_free(lct->ext, TRUE);
+}
+
+/* Preferences */
+/* ----------- */
+
+/* Set/Reset preferences to default values */
+void lct_prefs_set_default(struct _lct_prefs *prefs)
+{
+ prefs->codepoint_as_fec_encoding = TRUE;
+ prefs->ext_192 = LCT_PREFS_EXT_192_FLUTE;
+ prefs->ext_193 = LCT_PREFS_EXT_193_FLUTE;
+}
+
+/* Register preferences */
+void lct_prefs_register(struct _lct_prefs *prefs, module_t *module)
+{
+ prefs_register_bool_preference(module,
+ "lct.codepoint_as_fec_id",
+ "LCT Codepoint as FEC Encoding ID",
+ "Whether the LCT header Codepoint field should be considered the FEC Encoding ID of carried object",
+ &prefs->codepoint_as_fec_encoding);
+
+ prefs_register_enum_preference(module,
+ "lct.ext.192",
+ "LCT header extention 192",
+ "How to decode LCT header extention 192",
+ &prefs->ext_192,
+ enum_lct_ext_192,
+ FALSE);
+
+ prefs_register_enum_preference(module,
+ "lct.ext.193",
+ "LCT header extention 193",
+ "How to decode LCT header extention 193",
+ &prefs->ext_193,
+ enum_lct_ext_193,
+ FALSE);
+}
diff --git a/epan/dissectors/packet-rmt-lct.h b/epan/dissectors/packet-rmt-lct.h
new file mode 100644
index 0000000000..9cf79448c3
--- /dev/null
+++ b/epan/dissectors/packet-rmt-lct.h
@@ -0,0 +1,185 @@
+/* packet-rmt-lct.h
+ * Reliable Multicast Transport (RMT)
+ * LCT Building Block function definitions
+ * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PACKET_RMT_LCT__
+#define __PACKET_RMT_LCT__
+
+#include "packet-rmt-common.h"
+#include "packet-rmt-fec.h"
+
+/* Type definitions */
+/* ================ */
+
+/* Logical LCT header representation */
+struct _lct
+{
+ guint8 version;
+ guint8 cci_size;
+ guint8 tsi_size;
+ guint8 toi_size;
+ gboolean tsi_present;
+ gboolean toi_present;
+ gboolean sct_present;
+ gboolean ert_present;
+ gboolean close_session;
+ gboolean close_object;
+ guint16 hlen;
+ guint8 codepoint;
+ guint8 *cci;
+ guint64 tsi;
+ guint64 toi;
+ guint8 *toi_extended;
+ nstime_t sct;
+ nstime_t ert;
+ GArray *ext;
+};
+
+/* Ethereal stuff */
+/* ============== */
+
+/* LCT header field definitions */
+struct _lct_hf
+{
+ int header;
+ int version;
+ int fsize_header;
+ int fsize_cci;
+ int fsize_tsi;
+ int fsize_toi;
+ int flags_header;
+ int flags_sct_present;
+ int flags_ert_present;
+ int flags_close_session;
+ int flags_close_object;
+ int hlen;
+ int codepoint;
+ int cci;
+ int tsi;
+ int toi;
+ int toi_extended;
+ int sct;
+ int ert;
+ int ext;
+};
+
+/* LCT subtrees */
+struct _lct_ett
+{
+ gint main;
+
+ gint fsize;
+ gint flags;
+ gint ext;
+ gint ext_ext;
+};
+
+/* LCT preferences */
+
+#define LCT_PREFS_EXT_192_NONE 0
+#define LCT_PREFS_EXT_192_FLUTE 1
+
+#define LCT_PREFS_EXT_193_NONE 0
+#define LCT_PREFS_EXT_193_FLUTE 1
+
+struct _lct_prefs
+{
+ gboolean codepoint_as_fec_encoding;
+ gint ext_192;
+ gint ext_193;
+};
+
+/* LCT pointers */
+struct _lct_ptr
+{
+ struct _lct *lct;
+ struct _lct_hf *hf;
+ struct _lct_ett *ett;
+ struct _lct_prefs *prefs;
+};
+
+/* Macros to generate static arrays */
+
+#define LCT_FIELD_ARRAY(base_structure, base_protocol) \
+ { &base_structure.header, \
+ { "Layered Coding Transport (LCT) header", base_protocol ".lct", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.version, \
+ { "Version", base_protocol ".lct.version", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.fsize_header, \
+ { "Field sizes (bytes)", base_protocol ".lct.fsize", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.fsize_cci, \
+ { "Congestion Control Information field size", base_protocol ".lct.fsize.cci", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.fsize_tsi, \
+ { "Transport Session Identifier field size", base_protocol ".lct.fsize.tsi", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.fsize_toi, \
+ { "Transport Object Identifier field size", base_protocol ".lct.fsize.toi", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.flags_header, \
+ { "Flags", base_protocol ".lct.flags", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.flags_sct_present, \
+ { "Sender Current Time present flag", base_protocol ".lct.flags.sct_present", FT_BOOLEAN, BASE_NONE, TFS(&boolean_set_notset), 0x0, "", HFILL }}, \
+ { &base_structure.flags_ert_present, \
+ { "Expected Residual Time present flag", base_protocol ".lct.flags.ert_present", FT_BOOLEAN, BASE_NONE, TFS(&boolean_set_notset), 0x0, "", HFILL }}, \
+ { &base_structure.flags_close_session, \
+ { "Close Session flag", base_protocol ".lct.flags.close_session", FT_BOOLEAN, BASE_NONE, TFS(&boolean_set_notset), 0x0, "", HFILL }}, \
+ { &base_structure.flags_close_object, \
+ { "Close Object flag", base_protocol ".lct.flags.close_object", FT_BOOLEAN, BASE_NONE, TFS(&boolean_set_notset), 0x0, "", HFILL }}, \
+ { &base_structure.hlen, \
+ { "Header length", base_protocol ".lct.hlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.codepoint, \
+ { "Codepoint", base_protocol ".lct.codepoint", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.cci, \
+ { "Congestion Control Information", base_protocol ".lct.cci", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.tsi, \
+ { "Transport Session Identifier", base_protocol ".lct.tsi", FT_UINT64, BASE_DEC, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.toi, \
+ { "Transport Object Identifier (up to 64 bites)", base_protocol ".lct.toi", FT_UINT64, BASE_DEC, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.toi_extended, \
+ { "Transport Object Identifier (up to 112 bits)", base_protocol ".lct.toi_extended", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.sct, \
+ { "Sender Current Time", base_protocol ".lct.sct", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.ert, \
+ { "Expected Residual Time", base_protocol ".lct.ert", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0, "", HFILL }}, \
+ { &base_structure.ext, \
+ { "Extension count", base_protocol ".lct.ext", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}
+
+#define LCT_SUBTREE_ARRAY(base_structure) \
+ &base_structure.main, \
+ &base_structure.fsize, \
+ &base_structure.flags, \
+ &base_structure.ext, \
+ &base_structure.ext_ext
+
+/* LCT exported functions */
+/* ====================== */
+
+void lct_info_column(struct _lct *lct, packet_info *pinfo);
+
+void lct_dissector(struct _lct_ptr l, struct _fec_ptr f, tvbuff_t *tvb, proto_tree *tree, guint *offset);
+void lct_dissector_free(struct _lct *lct);
+
+void lct_prefs_set_default(struct _lct_prefs *prefs);
+void lct_prefs_register(struct _lct_prefs *prefs, module_t *module);
+
+#endif
diff --git a/epan/dissectors/packet-rmt-norm.c b/epan/dissectors/packet-rmt-norm.c
new file mode 100644
index 0000000000..0b09b437b1
--- /dev/null
+++ b/epan/dissectors/packet-rmt-norm.c
@@ -0,0 +1,281 @@
+/* packet-rmt-norm.c
+ * Reliable Multicast Transport (RMT)
+ * NORM Protocol Instantiation dissector
+ * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
+ *
+ * Negative-acknowledgment (NACK)-Oriented Reliable Multicast (NORM):
+ * ------------------------------------------------------------------
+ *
+ * This protocol is designed to provide end-to-end reliable transport of
+ * bulk data objects or streams over generic IP multicast routing and
+ * forwarding services. NORM uses a selective, negative acknowledgment
+ * mechanism for transport reliability and offers additional protocol
+ * mechanisms to allow for operation with minimal "a priori"
+ * coordination among senders and receivers.
+ *
+ * References:
+ * RFC 3490, Negative-acknowledgment (NACK)-Oriented Reliable Multicast (NORM) Protocol
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/prefs.h>
+
+#include "packet-rmt-norm.h"
+
+/* String tables */
+const value_string string_norm_type[] =
+{
+ { 1, "NORM_INFO" },
+ { 2, "NORM_DATA" },
+ { 3, "NORM_CMD" },
+ { 4, "NORM_NACK" },
+ { 5, "NORM_ACK" },
+ { 6, "NORM_REPORT" },
+ { 0, NULL }
+};
+
+/* Initialize the protocol and registered fields */
+/* ============================================= */
+
+static int proto = -1;
+
+static struct _norm_hf hf;
+static struct _norm_ett ett;
+
+static gboolean preferences_initialized = FALSE;
+static struct _norm_prefs preferences;
+static struct _norm_prefs preferences_old;
+
+/* Preferences */
+/* =========== */
+
+/* Set/Reset preferences to default values */
+static void norm_prefs_set_default(struct _norm_prefs *prefs)
+{
+ fec_prefs_set_default(&prefs->fec);
+}
+
+/* Register preferences */
+static void norm_prefs_register(struct _norm_prefs *prefs, module_t *module)
+{
+ fec_prefs_register(&prefs->fec, module);
+}
+
+/* Save preferences to alc_prefs_old */
+static void norm_prefs_save(struct _norm_prefs *p, struct _norm_prefs *p_old)
+{
+ *p_old = *p;
+}
+
+/* Code to actually dissect the packets */
+/* ==================================== */
+
+static void dissect_norm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ /* Logical packet representation */
+ struct _norm norm;
+
+ /* Offset for subpacket dissection */
+ guint offset;
+
+ /* Set up structures needed to add the protocol subtree and manage it */
+ proto_item *ti;
+ proto_tree *norm_tree;
+
+ /* Structures and variables initialization */
+ offset = 0;
+ memset(&norm, 0, sizeof(struct _norm));
+
+ /* Update packet info */
+ pinfo->current_proto = "NORM";
+
+ /* Make entries in Protocol column and Info column on summary display */
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "NORM");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ /* NORM header dissection, part 1 */
+ /* ------------------------------ */
+
+ norm.version = hi_nibble(tvb_get_guint8(tvb, offset));
+
+ if (tree)
+ {
+ /* Create subtree for the NORM protocol */
+ ti = proto_tree_add_item(tree, proto, tvb, offset, -1, FALSE);
+ norm_tree = proto_item_add_subtree(ti, ett.main);
+
+ /* Fill the NORM subtree */
+ proto_tree_add_uint(norm_tree, hf.version, tvb, offset, 1, norm.version);
+
+ } else
+ norm_tree = NULL;
+
+ /* This dissector supports only NORMv1 packets.
+ * If norm.version > 1 print only version field and quit.
+ */
+ if (norm.version == 1) {
+
+ /* NORM header dissection, part 2 */
+ /* ------------------------------ */
+
+ norm.type = lo_nibble(tvb_get_guint8(tvb, offset));
+ norm.hlen = tvb_get_guint8(tvb, offset+1);
+ norm.sequence = tvb_get_ntohs(tvb, offset+2);
+ norm.source_id = tvb_get_ntohl(tvb, offset+4);
+
+ if (tree)
+ {
+ proto_tree_add_uint(norm_tree, hf.type, tvb, offset, 1, norm.type);
+ proto_tree_add_uint(norm_tree, hf.hlen, tvb, offset+1, 1, norm.hlen);
+ proto_tree_add_uint(norm_tree, hf.sequence, tvb, offset+2, 2, norm.sequence);
+ proto_tree_add_uint(norm_tree, hf.source_id, tvb, offset+4, 4, norm.source_id);
+ }
+
+ offset += 8;
+
+ /* Add the Payload item */
+ if (tvb_length(tvb) > offset)
+ proto_tree_add_none_format(norm_tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_length(tvb) - offset);
+
+ /* Complete entry in Info column on summary display */
+ /* ------------------------------------------------ */
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ switch (norm.type)
+ {
+ case 1:
+ col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "INFO");
+ break;
+
+ case 2:
+ col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "DATA");
+ break;
+
+ case 3:
+ col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "CMD");
+ break;
+
+ case 4:
+ col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "NACK");
+ break;
+
+ case 5:
+ col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "ACK");
+ break;
+
+ case 6:
+ col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "REPORT");
+ break;
+
+ default:
+ col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Unknown type");
+ break;
+ }
+
+ } else {
+
+ if (tree)
+ proto_tree_add_text(norm_tree, tvb, 0, -1, "Sorry, this dissector supports NORM version 1 only");
+
+ /* Complete entry in Info column on summary display */
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Version: %u (not supported)", norm.version);
+ }
+}
+
+void proto_reg_handoff_norm(void)
+{
+ static dissector_handle_t handle;
+
+ if (!preferences_initialized)
+ {
+ preferences_initialized = TRUE;
+ handle = create_dissector_handle(dissect_norm, proto);
+ dissector_add_handle("udp.port", handle);
+ }
+
+ norm_prefs_save(&preferences, &preferences_old);
+}
+
+void proto_register_norm(void)
+{
+ /* Setup NORM header fields */
+ static hf_register_info hf_ptr[] = {
+
+ { &hf.version,
+ { "Version", "norm.version", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf.type,
+ { "Message Type", "norm.type", FT_UINT8, BASE_DEC, VALS(string_norm_type), 0x0, "", HFILL }},
+ { &hf.hlen,
+ { "Header length", "norm.hlen", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf.sequence,
+ { "Sequence", "norm.sequence", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf.source_id,
+ { "Source ID", "norm.source_id", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+
+ FEC_FIELD_ARRAY(hf.fec, "alc"),
+
+ { &hf.payload,
+ { "Payload", "norm.payload", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}
+ };
+
+ /* Setup protocol subtree array */
+ static gint *ett_ptr[] = {
+ &ett.main,
+
+ FEC_SUBTREE_ARRAY(ett.fec)
+ };
+
+ module_t *module;
+
+ /* Clear hf and ett fields */
+ memset(&hf, 0xff, sizeof(struct _norm_hf));
+ memset(&ett, 0xff, sizeof(struct _norm_ett));
+
+ /* Register the protocol name and description */
+ proto = proto_register_protocol("Negative-acknowledgment Oriented Reliable Multicast", "NORM", "norm");
+
+ /* Register the header fields and subtrees used */
+ proto_register_field_array(proto, hf_ptr, array_length(hf_ptr));
+ proto_register_subtree_array(ett_ptr, array_length(ett_ptr));
+
+ /* Reset preferences */
+ norm_prefs_set_default(&preferences);
+ norm_prefs_save(&preferences, &preferences_old);
+
+ /* Register preferences */
+ module = prefs_register_protocol(proto, proto_reg_handoff_norm);
+ norm_prefs_register(&preferences, module);
+}
diff --git a/epan/dissectors/packet-rmt-norm.h b/epan/dissectors/packet-rmt-norm.h
new file mode 100644
index 0000000000..c353bd9a7a
--- /dev/null
+++ b/epan/dissectors/packet-rmt-norm.h
@@ -0,0 +1,82 @@
+/* packet-rmt-norm.h
+ * Reliable Multicast Transport (RMT)
+ * NORM Protocol Instantiation function definitions
+ * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PACKET_RMT_NORM__
+#define __PACKET_RMT_NORM__
+
+#include "packet-rmt-common.h"
+#include "packet-rmt-fec.h"
+
+/* Type definitions */
+/* ================ */
+
+/* Logical NORM packet representation */
+struct _norm
+{
+ guint8 version;
+ guint8 type;
+ guint8 hlen;
+ guint16 sequence;
+ guint32 source_id;
+
+ struct _fec fec;
+};
+
+/* Ethereal stuff */
+/* ============== */
+
+/* NORM header field definitions*/
+struct _norm_hf
+{
+ int version;
+ int type;
+ int hlen;
+ int sequence;
+ int source_id;
+
+ struct _fec_hf fec;
+
+ int payload;
+};
+
+/* NORM subtrees */
+struct _norm_ett
+{
+ gint main;
+
+ struct _fec_ett fec;
+};
+
+/* NORM preferences */
+struct _norm_prefs
+{
+ struct _fec_prefs fec;
+};
+
+/* Function declarations */
+/* ===================== */
+
+#endif