Overhauled the RMT dissectors. Not sure each needs its own file, but since this...
authorMichael Mann <mmann78@netscape.net>
Fri, 24 May 2013 17:06:23 +0000 (17:06 -0000)
committerMichael Mann <mmann78@netscape.net>
Fri, 24 May 2013 17:06:23 +0000 (17:06 -0000)
Some Notes:
1. Converted to "new style" dissectors with data being passed between dissectors
2. Combined header files into one since there wasn't much that should have really been in the header files.  Implemented functionality is in c module of respective dissector.

Not sure if LCT preferences should just be in the LCT dissector and not the RMT-ALC "parent", but kept for backwards compatibility.

svn path=/trunk/; revision=49555

12 files changed:
epan/CMakeLists.txt
epan/dissectors/Makefile.common
epan/dissectors/packet-rmt-alc.c
epan/dissectors/packet-rmt-alc.h [deleted file]
epan/dissectors/packet-rmt-common.c [deleted file]
epan/dissectors/packet-rmt-common.h
epan/dissectors/packet-rmt-fec.c
epan/dissectors/packet-rmt-fec.h [deleted file]
epan/dissectors/packet-rmt-lct.c
epan/dissectors/packet-rmt-lct.h [deleted file]
epan/dissectors/packet-rmt-norm.c
epan/dissectors/packet-rmt-norm.h [deleted file]

index ae87d886663e0e33356db8f89d298da81fee0d69..b82fbc336b3f6e531f700121c8c81484fbc2fa6c 100644 (file)
@@ -1063,7 +1063,6 @@ set(DISSECTOR_SRC
        dissectors/packet-rmi.c
        dissectors/packet-rmp.c
        dissectors/packet-rmt-alc.c
-       dissectors/packet-rmt-common.c
        dissectors/packet-rmt-fec.c
        dissectors/packet-rmt-lct.c
        dissectors/packet-rmt-norm.c
index e432ec630e2d59c599c246d48661454bbc4ba870..8e0022961c44c33e3a95b266923c1003f6731a63 100644 (file)
@@ -985,7 +985,6 @@ DISSECTOR_SRC = \
        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       \
@@ -1487,11 +1486,7 @@ DISSECTOR_INCLUDES =     \
        packet-rlc.h    \
        packet-rlc-lte.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-rohc.h   \
        packet-ros.h    \
        packet-rpc.h    \
index 1913a0d904cc719c89edcdfe294d84528e5f666b..298db469aaf3e2e65044c7d17d253403b7ed69c8 100644 (file)
 
 #include "config.h"
 
-#include <string.h>
-
 #include <glib.h>
 
 #include <epan/packet.h>
 #include <epan/prefs.h>
+#include <epan/expert.h>
 
-#include "packet-rmt-alc.h"
+#include "packet-rmt-common.h"
 
 /* Initialize the protocol and registered fields */
 /* ============================================= */
 
-static int proto = -1;
-
-static struct _alc_hf hf;
-static struct _alc_ett ett;
-
-static struct _alc_prefs preferences;
-static dissector_handle_t xml_handle;
+static int proto_rmt_alc = -1;
 
+static int hf_version = -1;
+static int hf_payload = -1;
 
-/* Preferences */
-/* =========== */
+static int ett_main = -1;
 
-/* Set/Reset preferences to default values */
-static void alc_prefs_set_default(struct _alc_prefs *alc_prefs)
-{
-       alc_prefs->use_default_udp_port = FALSE;
-       alc_prefs->default_udp_port = 4001;
-
-       lct_prefs_set_default(&alc_prefs->lct);
-       fec_prefs_set_default(&alc_prefs->fec);
-}
-
-/* Register preferences */
-static void alc_prefs_register(struct _alc_prefs *alc_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",
-                &alc_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, &alc_prefs->default_udp_port);
-
-       lct_prefs_register(&alc_prefs->lct, module);
-       fec_prefs_register(&alc_prefs->fec, module);
-}
+static dissector_handle_t xml_handle;
+static dissector_handle_t rmt_lct_handle;
+static dissector_handle_t rmt_fec_handle;
 
-/* Save preferences to alc_prefs_old */
-static void alc_prefs_save(struct _alc_prefs *p, struct _alc_prefs *p_old)
-{
-       *p_old = *p;
-}
+static guint g_default_udp_port = 0; /* 4001 */
+static gboolean g_codepoint_as_fec_encoding = TRUE;
+static gint g_ext_192 = LCT_PREFS_EXT_192_FLUTE;
+static gint g_ext_193 = LCT_PREFS_EXT_193_FLUTE;
 
 /* Code to actually dissect the packets */
 /* ==================================== */
-
-static void dissect_alc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+static int
+dissect_alc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
 {
-       /* Logical packet representation */
-       struct _alc alc;
+       guint8 version;
+       lct_data_exchange_t lct;
+       fec_data_exchange_t fec;
+       int len;
 
        /* Offset for subpacket dissection */
-       guint offset;
+       guint offset = 0;
 
        /* Set up structures needed to add the protocol subtree and manage it */
        proto_item *ti;
        proto_tree *alc_tree;
 
-       /* Flute or not */
        tvbuff_t *new_tvb;
-       gboolean is_flute = FALSE;
-
-       /* 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 */
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "ALC");
@@ -132,110 +93,96 @@ static void dissect_alc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        /* 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, ENC_NA);
-               alc_tree = proto_item_add_subtree(ti, ett.main);
+       version = hi_nibble(tvb_get_guint8(tvb, offset));
 
-               /* Fill the ALC subtree */
-               proto_tree_add_uint(alc_tree, hf.version, tvb, offset, 1, alc.version);
+       /* Create subtree for the ALC protocol */
+       ti = proto_tree_add_item(tree, proto_rmt_alc, tvb, offset, -1, ENC_NA);
+       alc_tree = proto_item_add_subtree(ti, ett_main);
 
-       } else
-               alc_tree = NULL;
+       /* Fill the ALC subtree */
+       ti = proto_tree_add_uint(alc_tree, hf_version, tvb, offset, 1, version);
 
        /* This dissector supports only ALCv1 packets.
-        * If alc.version > 1 print only version field and quit.
+        * If 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 */
-               /* --------------------- */
-
-               is_flute = 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){
-                       if(is_flute){
-                               new_tvb = tvb_new_subset_remaining(tvb,offset);
-                               call_dissector(xml_handle, new_tvb, pinfo, alc_tree);
-                       }else{
-                               proto_tree_add_none_format(alc_tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_length(tvb) - offset);
-                       }
-               }
+       if (version != 1) {
+               expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN, "Sorry, this dissector supports ALC version 1 only");
 
                /* Complete entry in Info column on summary display */
-               /* ------------------------------------------------ */
+               col_add_fstr(pinfo->cinfo, COL_INFO, "Version: %u (not supported)", version);
+               return 0;
+       }
 
-               if (check_col(pinfo->cinfo, COL_INFO))
-               {
-                       lct_info_column(&alc.lct, pinfo);
-                       fec_info_column(&alc.fec, pinfo);
-               }
+       /* LCT header dissection */
+       /* --------------------- */
+       new_tvb = tvb_new_subset_remaining(tvb,offset);
+
+       lct.ext_192 = g_ext_192;
+       lct.ext_193 = g_ext_193;
+       lct.codepoint = 0;
+       lct.is_flute = FALSE;
+       len = call_dissector_with_data(rmt_lct_handle, new_tvb, pinfo, alc_tree, &lct);
+       if (len < 0)
+               return offset;
 
-               /* Free g_allocated memory */
-               lct_dissector_free(&alc.lct);
-               fec_dissector_free(&alc.fec);
+       offset += len;
 
-       } else {
+       /* FEC header dissection */
+       /* --------------------- */
 
-               if (tree)
-                       proto_tree_add_text(alc_tree, tvb, 0, -1, "Sorry, this dissector supports ALC version 1 only");
+       /* Only if LCT dissector has determined FEC Encoding ID */
+       /* FEC dissector needs to be called with encoding_id filled */
+       if (g_codepoint_as_fec_encoding && tvb_reported_length(tvb) > offset)
+       {
+               fec.encoding_id = lct.codepoint;
 
-               /* 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);
+               new_tvb = tvb_new_subset_remaining(tvb,offset);
+               len = call_dissector_with_data(rmt_fec_handle, new_tvb, pinfo, alc_tree, &fec);
+               if (len < 0)
+                       return offset;
+
+               offset += len;
+       }
+
+       /* Add the Payload item */
+       if (tvb_reported_length(tvb) > offset){
+               if(lct.is_flute){
+                       new_tvb = tvb_new_subset_remaining(tvb,offset);
+                       call_dissector(xml_handle, new_tvb, pinfo, alc_tree);
+               }else{
+                       proto_tree_add_item(alc_tree, hf_payload, tvb, offset, -1, ENC_NA);
+               }
        }
+
+       return tvb_reported_length(tvb);
 }
 
 void proto_reg_handoff_alc(void)
 {
        static dissector_handle_t handle;
        static gboolean preferences_initialized = FALSE;
-       static struct _alc_prefs preferences_old;
+       static guint old_udp_port = 0;
 
        if (!preferences_initialized)
        {
                preferences_initialized = TRUE;
-               handle = create_dissector_handle(dissect_alc, proto);
+               handle = new_create_dissector_handle(dissect_alc, proto_rmt_alc);
                dissector_add_handle("udp.port", handle);
                xml_handle = find_dissector("xml");
+               rmt_lct_handle = find_dissector("rmt-lct");
+               rmt_fec_handle = find_dissector("rmt-fec");
+       } 
 
-       } else {
-
-               if (preferences_old.use_default_udp_port)
-                       dissector_delete_uint("udp.port", preferences_old.default_udp_port, handle);
+       /* Register UDP port for dissection */
+       if(old_udp_port != 0 && old_udp_port != g_default_udp_port){
+               dissector_delete_uint("udp.port", old_udp_port, handle);
        }
 
-       if (preferences.use_default_udp_port)
-               dissector_add_uint("udp.port", preferences.default_udp_port, handle);
-
-       alc_prefs_save(&preferences, &preferences_old);
+       if(g_default_udp_port != 0 && old_udp_port != g_default_udp_port) {
+               dissector_add_uint("udp.port", g_default_udp_port, handle);
+       }
 
+       old_udp_port = g_default_udp_port;
 }
 
 void proto_register_alc(void)
@@ -243,43 +190,71 @@ void proto_register_alc(void)
        /* Setup ALC header fields */
        static hf_register_info hf_ptr[] = {
 
-               { &hf.version,
+               { &hf_version,
                        { "Version", "alc.version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
 
-               LCT_FIELD_ARRAY(hf.lct, "alc"),
-               FEC_FIELD_ARRAY(hf.fec, "alc"),
-
-               { &hf.payload,
-                       { "Payload", "alc.payload", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}
+               { &hf_payload,
+                       { "Payload", "alc.payload", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}
        };
 
        /* Setup protocol subtree array */
        static gint *ett_ptr[] = {
-               &ett.main,
-
-               LCT_SUBTREE_ARRAY(ett.lct),
-               FEC_SUBTREE_ARRAY(ett.fec)
+               &ett_main,
        };
 
        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");
+       proto_rmt_alc = proto_register_protocol("Asynchronous Layered Coding", "ALC", "alc");
+       new_register_dissector("alc", dissect_alc, proto_rmt_alc);
 
        /* Register the header fields and subtrees used */
-       proto_register_field_array(proto, hf_ptr, array_length(hf_ptr));
+       proto_register_field_array(proto_rmt_alc, hf_ptr, array_length(hf_ptr));
        proto_register_subtree_array(ett_ptr, array_length(ett_ptr));
 
-       /* Reset preferences */
-       alc_prefs_set_default(&preferences);
-
        /* Register preferences */
-       module = prefs_register_protocol(proto, proto_reg_handoff_alc);
-       alc_prefs_register(&preferences, module);
+       module = prefs_register_protocol(proto_rmt_alc, proto_reg_handoff_alc);
 
-       register_dissector("alc", dissect_alc, proto);
+       prefs_register_obsolete_preference(module, "default.udp_port.enabled");
+
+       prefs_register_uint_preference(module,
+               "default.udp_port",
+               "UDP destination port",
+               "Specifies the UDP destination port for automatic dissection of ALC packets",
+                10, &g_default_udp_port);
+
+       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",
+                &g_codepoint_as_fec_encoding);
+
+       prefs_register_enum_preference(module,
+               "lct.ext.192",
+               "LCT header extension 192",
+               "How to decode LCT header extension 192",
+               &g_ext_192,
+               enum_lct_ext_192,
+               FALSE);
+
+       prefs_register_enum_preference(module,
+               "lct.ext.193",
+               "LCT header extension 193",
+               "How to decode LCT header extension 193",
+               &g_ext_193,
+               enum_lct_ext_193,
+               FALSE);
 }
+
+/*
+* Editor modelines - http://www.wireshark.org/tools/modelines.html
+*
+* Local variables:
+* c-basic-offset: 4
+* tab-width: 8
+* indent-tabs-mode: nil
+* End:
+*
+* ex: set shiftwidth=4 tabstop=8 expandtab:
+* :indentSize=4:tabSize=8:noTabs=true:
+*/
diff --git a/epan/dissectors/packet-rmt-alc.h b/epan/dissectors/packet-rmt-alc.h
deleted file mode 100644 (file)
index 2f633eb..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/* packet-rmt-alc.h
- * Reliable Multicast Transport (RMT)
- * ALC Protocol Instantiation function definitions
- * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
- *
- * $Id$
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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;
-};
-
-/* Wireshark 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
deleted file mode 100644 (file)
index d02ba65..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/* packet-rmt-common.c
- * Reliable Multicast Transport (RMT)
- * Common RMT functions
- * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
- *
- * $Id$
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-
-#include <glib.h>
-
-#include <epan/packet.h>
-#include <epan/strutil.h>
-
-#include "packet-rmt-common.h"
-
-/* 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 extension */
-                       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 extension */
-                       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);
-       }
-}
index 65e055129f25c99c4c31da665879601cd5ed0a11..0aa7620e97df84604bfc941c499e5f12bc9abcdc 100644 (file)
 #ifndef __PACKET_RMT_COMMON__
 #define __PACKET_RMT_COMMON__
 
-/* Type definitions */
-/* ================ */
+/* LCT preferences */
 
-/* Logical header extension representation */
-struct _ext
+#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
+
+
+extern const enum_val_t enum_lct_ext_192[];
+extern const enum_val_t enum_lct_ext_193[];
+
+/* String tables external references */
+extern const value_string string_fec_encoding_id[];
+
+
+/* Structures to exchange data between RMT dissectors */
+/* ============================= */
+typedef struct lct_data_exchange
+{
+       /* inputs */
+       gint ext_192;
+       gint ext_193;
+
+       /* outputs */
+       guint8 codepoint;
+       gboolean is_flute;
+
+} lct_data_exchange_t;
+
+typedef struct fec_data_exchange
 {
-       guint offset;
-       guint length;
+       /* inputs */
+       guint8 encoding_id;
 
-       guint8 het;
-       guint8 hel;
+} fec_data_exchange_t;
 
-       guint hec_offset;
-       guint8 hec_size;
-};
 
 /* Common RMT exported functions */
 /* ============================= */
+extern int lct_ext_decode(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, guint offset, guint offset_max, lct_data_exchange_t *data_exchange,
+                   int hfext, int ettext);
+extern void fec_decode_ext_fti(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int length, guint8 encoding_id);
 
-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);
+extern double rmt_decode_send_rate(guint16 send_rate );
 
 #endif
index f1e1a42d8bf4848a9388230e5442204b67c48a81..bb2125922bb0e4fd980b8d695ea2d3c0560d5630 100644 (file)
 
 #include <epan/packet.h>
 #include <epan/prefs.h>
+#include <epan/expert.h>
+
+#include "packet-rmt-common.h"
+
+static int proto_rmt_fec = -1;
+
+static int hf_encoding_id = -1;
+static int hf_instance_id = -1;
+static int hf_sbn = -1;
+static int hf_sbn_with_mask = -1;
+static int hf_sbl = -1;
+static int hf_esi = -1;
+static int hf_esi_with_mask = -1;
+static int hf_fti_transfer_length = -1;
+static int hf_fti_encoding_symbol_length = -1;
+static int hf_fti_max_source_block_length = -1;
+static int hf_fti_max_number_encoding_symbols = -1;
+static int hf_fti_num_blocks = -1;
+static int hf_fti_num_subblocks = -1;
+static int hf_fti_alignment = -1;
+
+static int ett_main = -1;
+
+typedef struct fec_packet_data
+{
+       guint8 instance_id;
+
+} fec_packet_data_t;
 
-#include "packet-rmt-fec.h"
 
 /* String tables */
 const value_string string_fec_encoding_id[] =
@@ -65,145 +92,85 @@ const value_string string_fec_encoding_id[] =
        { 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)
+void fec_decode_ext_fti(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int length, guint8 encoding_id)
 {
-       proto_item* ti = NULL, *item = 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);
+       guint64 transfer_length;
+       fec_packet_data_t* fec_data;
+       guint8 instance_id = 0;
+       proto_item* ti;
+
+       if (encoding_id == 6){
+               /* Raptor Q uses 40-bit transfer length */
+               transfer_length = tvb_get_ntoh40(tvb, offset+2);
+       }
+       else {
+               /* Decode 48-bit length field */
+               transfer_length = tvb_get_ntoh48(tvb, offset+2);
+       }
 
-       if (f.fec->encoding_id_present)
+       if (encoding_id >= 128)
        {
-               ext_tree = proto_item_add_subtree(ti, ett);
-               rmt_ext_decode_default_header(e, tvb, ext_tree);
+               instance_id = (guint8) tvb_get_ntohs(tvb, offset+8);
 
-               if (f.fec->encoding_id == 6){
-                       /* Raptor Q uses 40-bit transfer length */
-                       f.fec->transfer_length = tvb_get_ntoh40(tvb, e->offset+2);
-               }
-               else {
-                       /* Decode 48-bit length field */
-                       f.fec->transfer_length = tvb_get_ntoh48(tvb, e->offset+2);
-               }
+               /* Decode FEC Instance ID */
+               fec_data = se_new0(fec_packet_data_t);
+               fec_data->instance_id = instance_id;
 
-               if (f.fec->encoding_id >= 128)
-               {
-                       /* Decode FEC Instance ID */
-                       f.fec->instance_id_present = TRUE;
-                       f.fec->instance_id = (guint8) tvb_get_ntohs(tvb, e->offset+8);
-               }
-
-               if (tree) {
-                       if (f.fec->encoding_id == 6){
-                               /* Raptor Q uses 40-bit transfer length */
-                               proto_tree_add_uint64(ext_tree, f.hf->fti_transfer_length, tvb, e->offset+2, 5, f.fec->transfer_length);
-                       }
-                       else {
-                               proto_tree_add_uint64(ext_tree, f.hf->fti_transfer_length, tvb, e->offset+2, 6, f.fec->transfer_length);
-                               item = proto_tree_add_item(ext_tree, f.hf->instance_id, tvb,  e->offset+8, 2, ENC_BIG_ENDIAN);
-                               if(f.fec->instance_id_present == FALSE){
-                                       proto_item_append_text(item," - [FEC Encoding ID < 128, should be zero]");
-                               }
-                       }
-               }
+               p_add_proto_data(pinfo->fd, proto_rmt_fec, 0, fec_data);
+       }
 
-               switch (f.fec->encoding_id)
-               {
-               case 1:
-                       f.fec->encoding_symbol_length = tvb_get_ntohs(tvb, e->offset+10);
-                       f.fec->num_blocks = tvb_get_ntohs(tvb, e->offset+12);
-                       f.fec->num_subblocks = tvb_get_guint8(tvb, e->offset+14);
-                       f.fec->alignment = tvb_get_guint8(tvb, e->offset+15);
-
-                       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_num_blocks, tvb, e->offset+12, 2, f.fec->num_blocks);
-                               proto_tree_add_uint(ext_tree, f.hf->fti_num_subblocks, tvb, e->offset+14, 1, f.fec->num_subblocks);
-                               proto_tree_add_uint(ext_tree, f.hf->fti_alignment, tvb, e->offset+15, 1, f.fec->alignment);
-                       }
-                       break;
-
-               case 6:
-                       f.fec->encoding_symbol_length = tvb_get_ntohs(tvb, e->offset+8);
-                       f.fec->num_blocks = tvb_get_guint8(tvb, e->offset+10);
-                       f.fec->num_subblocks = tvb_get_ntohs(tvb, e->offset+11);
-                       f.fec->alignment = tvb_get_guint8(tvb, e->offset+13);
-
-                       if (tree)
-                       {
-                               proto_tree_add_uint(ext_tree, f.hf->fti_encoding_symbol_length, tvb, e->offset+8, 2, f.fec->encoding_symbol_length);
-                               proto_tree_add_uint(ext_tree, f.hf->fti_num_blocks, tvb, e->offset+10, 1, f.fec->num_blocks);
-                               proto_tree_add_uint(ext_tree, f.hf->fti_num_subblocks, tvb, e->offset+11, 2, f.fec->num_subblocks);
-                               proto_tree_add_uint(ext_tree, f.hf->fti_alignment, tvb, e->offset+13, 1, f.fec->alignment);
-                       }
-                       break;
-
-               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;
+       if (encoding_id == 6){
+               /* Raptor Q uses 40-bit transfer length */
+               proto_tree_add_uint64(tree, hf_fti_transfer_length, tvb, offset+2, 5, transfer_length);
+       }
+       else {
+               proto_tree_add_uint64(tree, hf_fti_transfer_length, tvb, offset+2, 6, transfer_length);
+               ti = proto_tree_add_item(tree, hf_instance_id, tvb,  offset+8, 2, ENC_BIG_ENDIAN);
+               if ((encoding_id < 128) && (instance_id != 0)) {
+                       expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN, "FEC Encoding ID < 128, should be zero");
                }
+       }
 
-       } else
-               if (tree)
-                       rmt_ext_decode_default_subtree(e, tvb, ti, ett);
+       switch (encoding_id)
+       {
+       case 1:
+               proto_tree_add_item(tree, hf_fti_encoding_symbol_length, tvb, offset+10, 2, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_fti_num_blocks, tvb, offset+12, 2, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_fti_num_subblocks, tvb, offset+14, 1, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_fti_alignment, tvb, offset+15, 1, ENC_BIG_ENDIAN);
+               break;
+
+       case 6:
+               proto_tree_add_item(tree, hf_fti_encoding_symbol_length, tvb, offset+8, 2, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_fti_num_blocks, tvb, offset+10, 1, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_fti_num_subblocks, tvb, offset+11, 2, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_fti_alignment, tvb, offset+13, 1, ENC_BIG_ENDIAN);
+               break;
+
+       case 0:
+       case 2:
+       case 128:
+       case 130:
+               proto_tree_add_item(tree, hf_fti_encoding_symbol_length, tvb, offset+10, 2, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_fti_max_source_block_length, tvb, offset+12, 4, ENC_BIG_ENDIAN);
+               break;
+
+       case 129:
+               proto_tree_add_item(tree, hf_fti_encoding_symbol_length, tvb, offset+10, 2, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_fti_max_source_block_length, tvb, offset+12, 2, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_fti_max_number_encoding_symbols, tvb, offset+14, 2, ENC_BIG_ENDIAN);
+               break;
+
+       case 132:
+               proto_tree_add_item(tree, hf_fti_encoding_symbol_length, tvb, offset+10, 2, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_fti_max_source_block_length, tvb, offset+12, 4, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_fti_max_number_encoding_symbols, tvb, offset+16, 4, ENC_BIG_ENDIAN);
+               break;
+       }
 }
 
 /* Dissect a FEC header:
@@ -216,142 +183,148 @@ void fec_decode_ext_fti(struct _ext *e, tvbuff_t *tvb, proto_tree *tree, gint et
  * 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)
+static int
+dissect_fec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
 {
        proto_item *ti;
        proto_tree *fec_tree;
-       guint offset_save = *offset;
+       guint offset = 0;
+       fec_data_exchange_t* fec = (fec_data_exchange_t*)data;
+       guint8 encoding_id = 0;
+       fec_packet_data_t* packet_data = (fec_packet_data_t*)p_get_proto_data(pinfo->fd, proto_rmt_fec, 0);
 
-       /* Create the FEC subtree */
-       if (tree)
-       {
-               ti = proto_tree_add_item(tree, f.hf->header, tvb, *offset, -1, ENC_NA);
-               fec_tree = proto_item_add_subtree(ti, f.ett->main);
-       } else
+       if (fec != NULL)
        {
-               ti = NULL;
-               fec_tree = NULL;
+               encoding_id = fec->encoding_id;
        }
 
-       /* 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);
+       /* Create the FEC subtree */
+       ti = proto_tree_add_item(tree, proto_rmt_fec, tvb, offset, -1, ENC_NA);
+       fec_tree = proto_item_add_subtree(ti, ett_main);
 
-                       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);
-               }
+       proto_tree_add_uint(fec_tree, hf_encoding_id, tvb, offset, 0, encoding_id);
 
-               switch (f.fec->encoding_id)
-               {
-               case 0:
-               case 1:
-               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 3:
-               case 4:
-                       f.fec->sbn = tvb_get_ntohl(tvb, *offset);
-                       f.fec->sbn = f.fec->sbn >> 20;
-                       f.fec->esi = tvb_get_ntohl(tvb, *offset);
-                       f.fec->esi &= 0xfffff;
-                       
-                       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, f.fec->esi);
-                       }
+       if (encoding_id >= 128 && (packet_data != NULL))
+               proto_tree_add_uint(fec_tree, hf_instance_id, tvb, offset, 0, packet_data->instance_id);
+
+       switch (encoding_id)
+       {
+       case 0:
+       case 1:
+       case 130:
+               proto_tree_add_item(fec_tree, hf_sbn, tvb, offset, 2, ENC_BIG_ENDIAN);
+               proto_tree_add_item(fec_tree, hf_esi, tvb, offset+2, 2, ENC_BIG_ENDIAN);
+
+               col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", tvb_get_ntohs(tvb, offset));
+               col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", tvb_get_ntohs(tvb, offset+2));
+
+               offset += 4;
+               break;
+
+       case 2:
+       case 128:
+       case 132:
+               proto_tree_add_item(fec_tree, hf_sbn, tvb, offset, 4, ENC_BIG_ENDIAN);
+               proto_tree_add_item(fec_tree, hf_esi, tvb, offset+4, 4, ENC_BIG_ENDIAN);
+
+               col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", tvb_get_ntohl(tvb, offset));
+               col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", tvb_get_ntohl(tvb, offset+4));
+
+               offset += 8;
+               break;
+
+       case 3:
+       case 4:
+               proto_tree_add_item(fec_tree, hf_sbn_with_mask, tvb, offset, 4, ENC_BIG_ENDIAN);
+               proto_tree_add_item(fec_tree, hf_esi_with_mask, tvb, offset, 4, ENC_BIG_ENDIAN);
                        
-                       f.fec->sbn_present = TRUE;
-                       f.fec->esi_present = TRUE;
-                       *offset += 4;
-                       break;
-
-               case 6:
-                       f.fec->sbn = tvb_get_guint8(tvb, *offset);
-                       f.fec->esi = tvb_get_ntoh24(tvb, *offset+1);
-
-                       if (tree)
-                       {
-                               proto_tree_add_uint(fec_tree, f.hf->sbn, tvb, *offset, 1, f.fec->sbn);
-                               proto_tree_add_uint(fec_tree, f.hf->esi, tvb, *offset+1, 3, f.fec->esi);
-                       }
-
-                       f.fec->sbn_present = TRUE;
-                       f.fec->esi_present = TRUE;
-                       *offset += 4;
-                       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;
-               }
-       }
-       if (tree)
-               proto_item_set_len(ti, *offset - offset_save);
-}
+               col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", tvb_get_ntohl(tvb, offset) >> 20);
+               col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", tvb_get_ntohl(tvb, offset) & 0xfffff);
 
-void fec_dissector_free(struct _fec *fec _U_)
-{
+               offset += 4;
+               break;
 
-}
+       case 6:
+               proto_tree_add_item(fec_tree, hf_sbn, tvb, offset, 1, ENC_BIG_ENDIAN);
+               proto_tree_add_item(fec_tree, hf_esi, tvb, offset+1, 3, ENC_BIG_ENDIAN);
 
-/* Preferences */
-/* ----------- */
+               col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", tvb_get_guint8(tvb, offset));
+               col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", tvb_get_ntoh24(tvb, offset+1));
 
-/* Set/Reset preferences to default values */
-void fec_prefs_set_default(struct _fec_prefs *fec_prefs _U_)
-{
+               offset += 4;
+               break;
+
+       case 129:
+               proto_tree_add_item(fec_tree, hf_sbn, tvb, offset, 4, ENC_BIG_ENDIAN);
+               proto_tree_add_item(fec_tree, hf_sbl, tvb, offset+4, 2, ENC_BIG_ENDIAN);
+               proto_tree_add_item(fec_tree, hf_esi, tvb, offset+6, 2, ENC_BIG_ENDIAN);
 
+               col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", tvb_get_ntohl(tvb, offset));
+               col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", tvb_get_ntohs(tvb, offset+6));
+
+               offset += 8;
+               break;
+       }
+
+       return offset;
 }
 
-/* Register preferences */
-void fec_prefs_register(struct _fec_prefs *fec_prefs _U_, module_t *module _U_)
+void proto_register_rmt_fec(void)
 {
-
+       static hf_register_info hf[] = {
+               { &hf_encoding_id,
+                       { "FEC Encoding ID", "rmt-fec.encoding_id", FT_UINT8, BASE_DEC, VALS(string_fec_encoding_id), 0x0, NULL, HFILL }},
+               { &hf_instance_id,
+                       { "FEC Instance ID", "rmt-fec.instance_id", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_sbn,
+                       { "Source Block Number", "rmt-fec.sbn", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_sbn_with_mask,
+                       { "Source Block Number", "rmt-fec.sbn", FT_UINT32, BASE_DEC, NULL, 0xFFF00000, NULL, HFILL }},
+               { &hf_sbl,
+                       { "Source Block Length", "rmt-fec.sbl", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_esi,
+                       { "Encoding Symbol ID", "rmt-fec.esi", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+               { &hf_esi_with_mask,
+                       { "Encoding Symbol ID", "rmt-fec.esi", FT_UINT32, BASE_HEX, NULL, 0x000FFFFF, NULL, HFILL }},
+               { &hf_fti_transfer_length,
+                       { "Transfer Length", "rmt-fec.fti.transfer_length", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_fti_encoding_symbol_length,
+                       { "Encoding Symbol Length", "rmt-fec.fti.encoding_symbol_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_fti_max_source_block_length,
+                       { "Maximum Source Block Length", "rmt-fec.fti.max_source_block_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_fti_max_number_encoding_symbols,
+                       { "Maximum Number of Encoding Symbols", "rmt-fec.fti.max_number_encoding_symbols", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_fti_num_blocks,
+                       { "Number of Source Blocks", "rmt-fec.fti.num_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_fti_num_subblocks,
+                       { "Number of Sub-Blocks", "rmt-fec.fti.num_subblocks", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_fti_alignment,
+                       { "Symbol Alignment", "rmt-fec.fti.alignment", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}
+       };
+
+       /* Setup protocol subtree array */
+       static gint *ett[] = {
+               &ett_main,
+       };
+
+       /* Register the protocol name and description */
+       proto_rmt_fec = proto_register_protocol("Forward Error Correction (FEC)", "RMT-FEC", "rmt-fec");
+       new_register_dissector("rmt-fec", dissect_fec, proto_rmt_fec);
+
+       /* Required function calls to register the header fields and subtrees used */
+       proto_register_field_array(proto_rmt_fec, hf, array_length(hf));
+       proto_register_subtree_array(ett, array_length(ett));
 }
+
+/*
+* Editor modelines - http://www.wireshark.org/tools/modelines.html
+*
+* Local variables:
+* c-basic-offset: 4
+* tab-width: 8
+* indent-tabs-mode: nil
+* End:
+*
+* ex: set shiftwidth=4 tabstop=8 expandtab:
+* :indentSize=4:tabSize=8:noTabs=true:
+*/
diff --git a/epan/dissectors/packet-rmt-fec.h b/epan/dissectors/packet-rmt-fec.h
deleted file mode 100644 (file)
index 9176881..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/* packet-rmt-fec.h
- * Reliable Multicast Transport (RMT)
- * FEC Building Block function definitions
- * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
- *
- * $Id$
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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;
-       guint16 num_blocks;
-       guint16 num_subblocks;
-       guint8 alignment;
-       gboolean sbn_present;
-       gboolean sbl_present;
-       gboolean esi_present;
-       guint32 sbn;
-       guint32 sbl;
-       guint32 esi;
-};
-
-/* Wireshark 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;
-       int fti_num_blocks;
-       int fti_num_subblocks;
-       int fti_alignment;
-};
-
-/* 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, NULL, HFILL }}, \
-       { &base_structure.encoding_id,  \
-               { "FEC Encoding ID", base_protocol ".fec.encoding_id", FT_UINT8, BASE_DEC, VALS(string_fec_encoding_id), 0x0, NULL, HFILL }},   \
-       { &base_structure.instance_id,  \
-               { "FEC Instance ID", base_protocol ".fec.instance_id", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},   \
-       { &base_structure.sbn,  \
-               { "Source Block Number", base_protocol ".fec.sbn", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},      \
-       { &base_structure.sbl,  \
-               { "Source Block Length", base_protocol ".fec.sbl", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},      \
-       { &base_structure.esi,  \
-               { "Encoding Symbol ID", base_protocol ".fec.esi", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},       \
-       { &base_structure.fti_header,   \
-               { "FEC Object Transmission Information", base_protocol ".fec.fti", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},       \
-       { &base_structure.fti_transfer_length,  \
-               { "Transfer Length", base_protocol ".fec.fti.transfer_length", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},  \
-       { &base_structure.fti_encoding_symbol_length,   \
-               { "Encoding Symbol Length", base_protocol ".fec.fti.encoding_symbol_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, 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, NULL, 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, NULL, HFILL }},   \
-       { &base_structure.fti_num_blocks,       \
-               { "Number of Source Blocks", base_protocol ".fec.fti.num_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},       \
-       { &base_structure.fti_num_subblocks,    \
-               { "Number of Sub-Blocks", base_protocol ".fec.fti.num_subblocks", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},       \
-       { &base_structure.fti_alignment,        \
-               { "Symbol Alignment", base_protocol ".fec.fti.alignment", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, 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
index b036d7e98e49b18a8472bb11572d92a8ea653c30..c851834f3d96d97bdbdc58bfa8a1e05114c3df22 100644 (file)
 #include <epan/packet.h>
 #include <epan/prefs.h>
 #include <epan/strutil.h>
-#include <epan/garrayfix.h>
 
 #include <math.h>
 
-#include "packet-rmt-lct.h"
+#include "packet-rmt-common.h"
+
+#define LCT_SCT_FLAG 0x0008
+#define LCT_ERT_FLAG 0x0004
+#define LCT_CLOSE_SESSION_FLAG 0x0002
+#define LCT_CLOSE_OBJECT_FLAG 0x0001
+
+static int proto_rmt_lct = -1;
+
+static int hf_version = -1;
+static int hf_fsize_header = -1;
+static int hf_fsize_cci = -1;
+static int hf_fsize_tsi = -1;
+static int hf_fsize_toi = -1;
+static int hf_flags_header = -1;
+static int hf_flags_sct_present = -1;
+static int hf_flags_ert_present = -1;
+static int hf_flags_close_session = -1;
+static int hf_flags_close_object = -1;
+static int hf_hlen = -1;
+static int hf_codepoint = -1;
+static int hf_cci = -1;
+static int hf_tsi = -1;
+static int hf_tsi16 = -1;
+static int hf_tsi32 = -1;
+static int hf_tsi48 = -1;
+static int hf_toi = -1;
+static int hf_toi16 = -1;
+static int hf_toi32 = -1;
+static int hf_toi48 = -1;
+static int hf_toi64 = -1;
+static int hf_toi_extended = -1;
+static int hf_sct = -1;
+static int hf_ert = -1;
+static int hf_ext = -1;
+static int hf_hec_type = -1;
+static int hf_hec_len = -1;
+static int hf_hec_data = -1;
+static int hf_send_rate = -1;
+static int hf_cenc = -1;
+static int hf_flute_version = -1;
+static int hf_fdt_instance_id = -1;
+
+static int ett_main = -1;
+static int ett_fsize = -1;
+static int ett_flags = -1;
+static int ett_ext = -1;
+static int ett_ext_ext = -1;
 
 /* Enumerated data types for LCT preferences */
-static const enum_val_t enum_lct_ext_192[] =
+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[] =
+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 }
 };
 
+static const value_string hec_type_vals[] = {
+       { 0,   "EXT_NOP, No-Operation" },
+       { 1,   "EXT_AUTH, Packet authentication" },
+       { 2,   "EXT_CC, Congestion Control Feedback" },
+       { 64,  "EXT_FTI, FEC Object Transmission Information" },
+       { 128,  "EXT_RATE, Send Rate" },
+       { 192,  "EXT_FDT, FDT Instance Header" },
+       { 193,  "EXT_CENC, FDT Instance Content Encoding" },
+
+       { 0,  NULL }
+};
+
 /* LCT helper functions */
 /* ==================== */
 
@@ -75,169 +133,131 @@ static void lct_timestamp_parse(guint32 t, nstime_t* s)
        s->nsecs = (t % 1000) * 1000000;
 }
 
-gboolean lct_ext_decode(struct _ext *e, struct _lct_prefs *lct_prefs, tvbuff_t *tvb, proto_tree *tree, gint ett, struct _fec_ptr f)
+double rmt_decode_send_rate(guint16 send_rate )
 {
-       guint32 buffer32;
-       proto_item *ti;
-       proto_tree *ext_tree;
-       gboolean is_flute = FALSE;
-
-       switch (e->het)
-       {
+       double value;
 
-       /* EXT_NOP */
-       case 0:
-               if (tree)
-               {
-                       ti = proto_tree_add_text(tree, tvb, e->offset, e->length,
-                               "EXT_NOP, No-Operation (0)");
+       value = (send_rate >> 4) * 10.0 / 4096.0 * pow(10.0, (send_rate & 0xf));
+       return value;
+}
 
-                       rmt_ext_decode_default_subtree(e, tvb, ti, ett);
-               }
-               break;
 
-       /* EXT_AUTH */
-       case 1:
-               if (tree)
+int lct_ext_decode(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, guint offset, guint offset_max, lct_data_exchange_t *data_exchange,
+                   int hfext, int ettext)
+{
+       guint8 het;
+       guint i, count = 0;
+       guint length, 
+                 tmp_offset = offset,
+                 start_offset = offset;
+       proto_item* ti;
+       proto_tree *hec_tree, *ext_tree;
+
+       /* Figure out the extention count */
+       while (tmp_offset < offset_max)
+       {
+               het = tvb_get_guint8(tvb, tmp_offset);
+               if (het <= 127)
                {
-                       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_CC RATE */
-    case 3:
-        if (tree) {
-                       ti = proto_tree_add_text(tree, tvb, e->offset, e->length,
-                               "EXT_CC, Congestion Control Feedback (%u)", e->het);
-
-                       ext_tree = proto_item_add_subtree(ti, ett);
-                       rmt_ext_decode_default_header(e, tvb, ext_tree);
-                       proto_tree_add_text(ext_tree, tvb, e->offset+2, 2,
-                                       "CC Sequence: %u", tvb_get_ntohs(tvb, e->offset+2));
-                       proto_tree_add_text(ext_tree, tvb, e->offset+4, 1,
-                                       "CC Flags: 0x%x", tvb_get_guint8(tvb, e->offset+4));
-                       proto_tree_add_text(ext_tree, tvb, e->offset+5, 1,
-                                       "CC RTT: %u", tvb_get_guint8(tvb, e->offset+5));
-                       proto_tree_add_text(ext_tree, tvb, e->offset+6, 2,
-                                       "CC Loss: %g", tvb_get_ntohs(tvb, e->offset+6)/65535.0);
-                       proto_tree_add_text(ext_tree, tvb, e->offset+8, 2,
-                                       "CC Rate: %u", tvb_get_ntohs(tvb, e->offset+8));
-
+                       length = tvb_get_guint8(tvb, tmp_offset+1)*4;
                }
-               break;
-       /* EXT_FTI */
-       case 64:
-               fec_decode_ext_fti(e, tvb, tree, ett, f);
-               break;
-
-       /* EXT_RATE */
-    case 128:
-        if (tree) {
-                       guint16 send_rate;
-                       double value;
-                       ti = proto_tree_add_text(tree, tvb, e->offset, e->length,
-                               "EXT_RATE, Send Rate (%u)", e->het);
-
-                       ext_tree = proto_item_add_subtree(ti, ett);
-                       rmt_ext_decode_default_header(e, tvb, ext_tree);
-                       send_rate = tvb_get_ntohs(tvb, e->offset+2);
-                       value = (send_rate >> 4) * 10.0 / 4096.0 * pow(10.0, (send_rate & 0xf));
-                       proto_tree_add_text(ext_tree, tvb, e->offset+2, 2,
-                                       "Send Rate: %g", value);
+               else
+               {
+                       length = 4;
                }
-               break;
 
-       /* EXT_FDT */
-       case 192:
-               switch (lct_prefs->ext_192)
-               {
-               case LCT_PREFS_EXT_192_NONE:
-                       rmt_ext_decode_default(e, tvb, tree, ett);
+               /* Prevents infinite loops */
+               if (length == 0)
                        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)");
+               tmp_offset += length;
+               count++;
+       }
 
-                               ext_tree = proto_item_add_subtree(ti, ett);
-                               buffer32 = tvb_get_ntohl(tvb, e->offset);
+       if (count == 0)
+               return 0;
 
-                               rmt_ext_decode_default_header(e, tvb, ext_tree);
+       ti = proto_tree_add_uint(tree, hfext, tvb, offset, tmp_offset - offset, count);
+       hec_tree = proto_item_add_subtree(ti, ettext);
+
+       for (i = 0; i < count; i++)
+       {
+               het = tvb_get_guint8(tvb, offset);
+               if (het <= 127)
+               {
+                       length = tvb_get_guint8(tvb, offset+1)*4;
+               }
+               else
+               {
+                       length = 4;
+               }
 
-                               proto_tree_add_text(ext_tree, tvb, e->offset+1, 1,
-                                       "FLUTE version (V): %u", (buffer32 & 0x00F00000) >> 20);
+               ti = proto_tree_add_item(hec_tree, hf_hec_type, tvb, offset, 1, ENC_BIG_ENDIAN);
+               ext_tree = proto_item_add_subtree(ti, ett_ext_ext);
+               proto_item_set_len(ti, length);
 
-                               proto_tree_add_text(ext_tree, tvb, e->offset+1, 3,
-                                       "FDT Instance ID: %u", buffer32 & 0x000FFFFF);
-                       }
-                       is_flute = TRUE;
-                       break;
+               if (het <= 127)
+               {
+                       proto_tree_add_item(ext_tree, hf_hec_len, tvb, offset+1, 1, ENC_BIG_ENDIAN);
                }
-               break;
 
-       /* EXT_CENC */
-       case 193:
-               switch (lct_prefs->ext_193)
+               switch (het)
                {
-               case LCT_PREFS_EXT_193_NONE:
-                       rmt_ext_decode_default(e, tvb, tree, ett);
+               case 0: /* EXT_NOP */
+               case 1: /* EXT_AUTH */
+               default:
+                       proto_tree_add_item(ext_tree, hf_hec_data, tvb, offset+2, length-2, ENC_NA);
                        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)");
+               case 3: /* EXT_CC RATE */
+                       proto_tree_add_text(ext_tree, tvb, offset+2, 2,
+                                       "CC Sequence: %u", tvb_get_ntohs(tvb, offset+2));
+                       proto_tree_add_text(ext_tree, tvb, offset+4, 1,
+                                       "CC Flags: 0x%x", tvb_get_guint8(tvb, offset+4));
+                       proto_tree_add_text(ext_tree, tvb, offset+5, 1,
+                                       "CC RTT: %u", tvb_get_guint8(tvb, offset+5));
+                       proto_tree_add_text(ext_tree, tvb, offset+6, 2,
+                                       "CC Loss: %g", tvb_get_ntohs(tvb, offset+6)/65535.0);
+                       proto_tree_add_text(ext_tree, tvb, offset+8, 2,
+                                       "CC Rate: %u", tvb_get_ntohs(tvb, offset+8));
+                       break;
 
-                               ext_tree = proto_item_add_subtree(ti, ett);
-                               buffer32 = tvb_get_ntohl(tvb, e->offset);
+               case 64: /* EXT_FTI */
+                       fec_decode_ext_fti(tvb, pinfo, ext_tree, offset, length, 
+                               (data_exchange == NULL) ? 0 : data_exchange->codepoint);
+                       break;
 
-                               rmt_ext_decode_default_header(e, tvb, ext_tree);
+               case 128: /* EXT_RATE */
+                       proto_tree_add_double(ext_tree, hf_send_rate, tvb, offset+2, 2, 
+                                       rmt_decode_send_rate(tvb_get_ntohs(tvb, offset+2)));
+                       break;
+               
+               case 192: /* EXT_FDT */
+                       if ((data_exchange != NULL) && (data_exchange->ext_192 == LCT_PREFS_EXT_192_FLUTE))
+                       {
+                               proto_tree_add_item(ext_tree, hf_flute_version, tvb, offset, 4, ENC_BIG_ENDIAN);
+                               proto_tree_add_item(ext_tree, hf_fdt_instance_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+                               data_exchange->is_flute = TRUE;
+                       }
+                       break;
 
-                               proto_tree_add_text(ext_tree, tvb, e->offset+1, 1,
-                                       "Content Encoding Algorithm (CENC): %u", (buffer32 & 0x00FF0000) >> 16);
+               case 193: /* EXT_CENC */
+                       if ((data_exchange != NULL) && (data_exchange->ext_193 == LCT_PREFS_EXT_193_FLUTE))
+                       {
+                               proto_tree_add_item(ext_tree, hf_cenc, tvb, offset+3, 1, ENC_BIG_ENDIAN);
                        }
                        break;
                }
-               break;
 
-       default:
-               rmt_ext_decode_default(e, tvb, tree, ett);
+               offset += length;
        }
-       return is_flute;
+
+       return offset-start_offset;
 }
 
 /* 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: %" G_GINT64_MODIFIER "u", lct->tsi);
-
-       if (lct->toi_present)
-       {
-               if (lct->toi_size <= 8)
-                       col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "TOI: %" G_GINT64_MODIFIER "u", 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 */
 /* ---------- */
 
@@ -249,268 +269,297 @@ void lct_info_column(struct _lct *lct, packet_info *pinfo)
  * tree - tree where to add LCT header subtree
  * offset - ptr to offset to use and update
  */
-gboolean lct_dissector(struct _lct_ptr l, struct _fec_ptr f, tvbuff_t *tvb, proto_tree *tree, guint *offset)
+static int
+dissect_lct(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
 {
-       guint i;
-       guint offset_old;
-       guint offset_start;
+       int offset = 0;
        guint16 buffer16;
-       gboolean is_flute_tmp =FALSE;
-       gboolean is_flute =FALSE;
-       guint8 *tmp;
+       lct_data_exchange_t *data_exchange = (lct_data_exchange_t*)data;
+
+       guint8 cci_size;
+       guint8 tsi_size;
+       guint8 toi_size;
+       guint64 tsi;
+       guint64 toi;
+       guint16 hlen;
+       nstime_t time;
 
        /* 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;
+       proto_tree *lct_tree = tree, *lct_fsize_tree, *lct_flags_tree;
 
        /* LCT fixed-size fields dissection */
        /* -------------------------------- */
+       buffer16 = tvb_get_ntohs(tvb, offset);
 
-       offset_start = *offset;
-
-       buffer16 = tvb_get_ntohs(tvb, *offset);
-
-       l.lct->version = ((buffer16 & 0xF000) >> 12);
+       cci_size = ((buffer16 & 0x0C00) >> 10) * 4 + 4;
+       tsi_size = ((buffer16 & 0x0080) >> 7) * 4 + ((buffer16 & 0x0010) >> 4) * 2;
+       toi_size = ((buffer16 & 0x0060) >> 5) * 4 + ((buffer16 & 0x0010) >> 4) * 2;
 
-       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;
+       hlen = tvb_get_guint8(tvb, offset+2) * 4;
 
-       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)
+       if (data_exchange != NULL)
        {
-               f.fec->encoding_id_present = TRUE;
-               f.fec->encoding_id = l.lct->codepoint;
+               data_exchange->codepoint = tvb_get_guint8(tvb, offset+3);
+               data_exchange->is_flute = FALSE;
        }
 
        if (tree)
        {
                /* Create the LCT subtree */
-               ti = proto_tree_add_item(tree, l.hf->header, tvb, *offset, l.lct->hlen, ENC_NA);
-               lct_tree = proto_item_add_subtree(ti, l.ett->main);
+               ti = proto_tree_add_item(tree, proto_rmt_lct, tvb, offset, hlen, ENC_NA);
+               lct_tree = proto_item_add_subtree(ti, 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, ENC_NA);
-               lct_fsize_tree = proto_item_add_subtree(ti, l.ett->fsize);
+               proto_tree_add_item(lct_tree, hf_version, tvb, offset, 2, ENC_BIG_ENDIAN);
 
-               ti = proto_tree_add_item(lct_tree, l.hf->flags_header, tvb, *offset, 2, ENC_NA);
-               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);
+               ti = proto_tree_add_item(lct_tree, hf_fsize_header, tvb, offset, 1, ENC_BIG_ENDIAN);
+               lct_fsize_tree = proto_item_add_subtree(ti, ett_fsize);
 
                /* 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);
+               proto_tree_add_uint(lct_fsize_tree, hf_fsize_cci, tvb, offset, 2, cci_size);
+               proto_tree_add_uint(lct_fsize_tree, hf_fsize_tsi, tvb, offset, 2, tsi_size);
+               proto_tree_add_uint(lct_fsize_tree, hf_fsize_toi, tvb, offset, 2, toi_size);
+
+               ti = proto_tree_add_item(lct_tree, hf_flags_header, tvb, offset, 2, ENC_BIG_ENDIAN);
+               lct_flags_tree = proto_item_add_subtree(ti, ett_flags);
 
                /* 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;
+               proto_tree_add_item(lct_flags_tree, hf_flags_sct_present, tvb, offset, 2, ENC_BIG_ENDIAN);
+               proto_tree_add_item(lct_flags_tree, hf_flags_ert_present, tvb, offset, 2, ENC_BIG_ENDIAN);
+               proto_tree_add_item(lct_flags_tree, hf_flags_close_session, tvb, offset, 2, ENC_BIG_ENDIAN);
+               proto_tree_add_item(lct_flags_tree, hf_flags_close_object, tvb, offset, 2, ENC_BIG_ENDIAN);
+
+               proto_tree_add_uint(lct_tree, hf_hlen, tvb, offset+2, 1, hlen);
+               proto_tree_add_item(lct_tree, hf_codepoint, tvb, offset+3, 1, ENC_BIG_ENDIAN);
+
        }
 
-       *offset += 4;
+       offset += 4;
 
        /* LCT variable-size and optional fields dissection */
        /* ------------------------------------------------ */
 
        /* Congestion Control Information (CCI) */
-       if (l.lct->cci_size > 0) {
-               if (tree)
-                       proto_tree_add_item(lct_tree, l.hf->cci, tvb, *offset, l.lct->cci_size, ENC_NA);
-               *offset += l.lct->cci_size;
+       if (cci_size > 0) {
+               proto_tree_add_item(lct_tree, hf_cci, tvb, offset, cci_size, ENC_NA);
+               offset += cci_size;
        }
 
        /* Transmission Session Identifier (TSI) */
-       if (l.lct->tsi_present) {
+       if (tsi_size > 0) {
 
-               switch (l.lct->tsi_size)
+               switch (tsi_size)
                {
                        case 0:
-                               l.lct->tsi = 0;
+                               proto_tree_add_uint(lct_tree, hf_tsi, tvb, offset, tsi_size, 0);
+                               tsi = 0;
                                break;
 
                        case 2:
-                               l.lct->tsi = tvb_get_ntohs(tvb, *offset);
+                               proto_tree_add_item(lct_tree, hf_tsi16, tvb, offset, tsi_size, ENC_BIG_ENDIAN);
+                               tsi = tvb_get_ntohs(tvb, offset);
                                break;
 
                        case 4:
-                               l.lct->tsi = tvb_get_ntohl(tvb, *offset);
+                               proto_tree_add_item(lct_tree, hf_tsi32, tvb, offset, tsi_size, ENC_BIG_ENDIAN);
+                               tsi = tvb_get_ntohl(tvb, offset);
                                break;
 
                        case 6:
-                               l.lct->tsi = tvb_get_ntoh64(tvb, *offset-2) & G_GINT64_CONSTANT(0x0000FFFFFFFFFFFFU);
+                               proto_tree_add_item(lct_tree, hf_tsi48, tvb, offset, tsi_size, ENC_BIG_ENDIAN);
+                               tsi = tvb_get_ntoh64(tvb, offset) & G_GINT64_CONSTANT(0x0000FFFFFFFFFFFFU);
+                               break;
+                       default:
+                               tsi = 0;
                                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;
+               col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "TSI: %" G_GINT64_MODIFIER "u", tsi);
+               offset += tsi_size;
        }
 
        /* Transmission Object Identifier (TOI) */
-       if (l.lct->toi_present) {
+       if (toi_size > 0) {
 
-               switch (l.lct->toi_size)
+               switch (toi_size)
                {
                        case 0:
-                               l.lct->toi = 0;
+                               proto_tree_add_uint(lct_tree, hf_toi, tvb, offset, toi_size, 0);
+                               toi = 0;
                                break;
 
                        case 2:
-                               l.lct->toi = tvb_get_ntohs(tvb, *offset);
+                               proto_tree_add_item(lct_tree, hf_toi16, tvb, offset, toi_size, ENC_BIG_ENDIAN);
+                               toi = tvb_get_ntohs(tvb, offset);
                                break;
 
                        case 4:
-                               l.lct->toi = tvb_get_ntohl(tvb, *offset);
+                               proto_tree_add_item(lct_tree, hf_toi32, tvb, offset, toi_size, ENC_BIG_ENDIAN);
+                               toi = tvb_get_ntohl(tvb, offset);
                                break;
 
                        case 6:
-                               l.lct->toi = tvb_get_ntoh64(tvb, *offset-2) & G_GINT64_CONSTANT(0x0000FFFFFFFFFFFFU);
+                               proto_tree_add_item(lct_tree, hf_toi48, tvb, offset, toi_size, ENC_BIG_ENDIAN);
+                               toi = tvb_get_ntoh64(tvb, offset) & G_GINT64_CONSTANT(0x0000FFFFFFFFFFFFU);
                                break;
 
                        case 8:
-                               l.lct->toi = tvb_get_ntoh64(tvb, *offset);
+                               proto_tree_add_item(lct_tree, hf_toi64, tvb, offset, toi_size, ENC_BIG_ENDIAN);
+                               toi = tvb_get_ntoh64(tvb, offset);
                                break;
 
                        case 10:
-                               l.lct->toi = tvb_get_ntoh64(tvb, *offset+2);
+                               proto_tree_add_item(lct_tree, hf_toi64, tvb, offset+2, 8, ENC_BIG_ENDIAN);
+                               proto_tree_add_item(lct_tree, hf_toi_extended, tvb, offset, 2, ENC_BIG_ENDIAN);
                                break;
 
                        case 12:
-                               l.lct->toi = tvb_get_ntoh64(tvb, *offset+4);
+                               proto_tree_add_item(lct_tree, hf_toi64, tvb, offset+4, 8, ENC_BIG_ENDIAN);
+                               proto_tree_add_item(lct_tree, hf_toi_extended, tvb, offset, 4, ENC_BIG_ENDIAN);
                                break;
 
                        case 14:
-                               l.lct->toi = tvb_get_ntoh64(tvb, *offset)+6;
+                               proto_tree_add_item(lct_tree, hf_toi64, tvb, offset+6, 8, ENC_BIG_ENDIAN);
+                               proto_tree_add_item(lct_tree, hf_toi_extended, tvb, offset, 6, ENC_BIG_ENDIAN);
+                               break;
+                       default:
                                break;
                }
 
-               tmp = (guint8 *)ep_alloc(l.lct->toi_size);
-               tvb_memcpy(tvb, tmp, *offset, l.lct->toi_size);
-               l.lct->toi_extended = tmp;
-
-               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);
+               if (toi_size <= 8)
+                       col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "TOI: %" G_GINT64_MODIFIER "u", toi);
+               else
+                       col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "TOI: 0x%s", tvb_bytes_to_str(tvb, offset, toi_size));
+               offset += toi_size;
+       }
 
-                       proto_tree_add_item(lct_tree, l.hf->toi_extended, tvb, *offset, l.lct->toi_size, ENC_NA);
-               }
+       if (buffer16 & LCT_CLOSE_SESSION_FLAG)
+               col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Close session");
 
-               *offset += l.lct->toi_size;
-       }
+       if (buffer16 & LCT_CLOSE_OBJECT_FLAG)
+               col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Close object");
 
        /* 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;
+       if (buffer16 & LCT_SCT_FLAG) {
+               lct_timestamp_parse(tvb_get_ntohl(tvb, offset), &time);
+               proto_tree_add_time(lct_tree, hf_sct, tvb, offset, 4, &time);
+               offset += 4;
        }
 
        /* Expected Residual Time (ERT) */
-       if (l.lct->ert_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;
+       if (buffer16 & LCT_ERT_FLAG) {
+               lct_timestamp_parse(tvb_get_ntohl(tvb, offset), &time);
+               proto_tree_add_time(lct_tree, hf_ert, tvb, offset, 4, &time);
+               offset += 4;
        }
 
        /* LCT header extensions, if applicable */
        /* ------------------------------------ */
+       lct_ext_decode(lct_tree, tvb, pinfo, offset, hlen, data_exchange, hf_ext, ett_ext);
 
-       /* 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++){
-                       is_flute_tmp = lct_ext_decode(&g_array_index(l.lct->ext, struct _ext, i), l.prefs, tvb, lct_ext_tree, l.ett->ext_ext, f);
-                       if (is_flute_tmp == TRUE )
-                               is_flute = TRUE;
-               }
-       }
-
-       return is_flute;
-}
-
-void lct_dissector_free(struct _lct *lct)
-{
-       g_array_free(lct->ext, TRUE);
+       return hlen;
 }
 
-/* Preferences */
-/* ----------- */
-
-/* Set/Reset preferences to default values */
-void lct_prefs_set_default(struct _lct_prefs *lct_prefs)
+void
+proto_register_rmt_lct(void)
 {
-       lct_prefs->codepoint_as_fec_encoding = TRUE;
-       lct_prefs->ext_192 = LCT_PREFS_EXT_192_FLUTE;
-       lct_prefs->ext_193 = LCT_PREFS_EXT_193_FLUTE;
+    static hf_register_info hf[] = {
+               { &hf_version,
+                       { "Version", "rmt-lct.version", FT_UINT16, BASE_DEC, NULL, 0xF000, NULL, HFILL }},
+               { &hf_fsize_header,
+                       { "Field size flags", "rmt-lct.fsize", FT_UINT16, BASE_HEX, NULL, 0x0FD0, NULL, HFILL }},
+               { &hf_fsize_cci,
+                       { "Congestion Control Information field size", "rmt-lct.fsize.cci", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_fsize_tsi,
+                       { "Transport Session Identifier field size", "rmt-lct.fsize.tsi", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_fsize_toi,
+                       { "Transport Object Identifier field size", "rmt-lct.fsize.toi", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_flags_header,
+                       { "Flags", "rmt-lct.flags", FT_UINT16, BASE_HEX, NULL, 0x001F, NULL, HFILL }},
+               { &hf_flags_sct_present,
+                       { "Sender Current Time present flag", "rmt-lct.flags.sct_present", FT_BOOLEAN, 16, TFS(&tfs_set_notset), LCT_SCT_FLAG, NULL, HFILL }},
+               { &hf_flags_ert_present,
+                       { "Expected Residual Time present flag", "rmt-lct.flags.ert_present", FT_BOOLEAN, 16, TFS(&tfs_set_notset), LCT_ERT_FLAG, NULL, HFILL }},
+               { &hf_flags_close_session,
+                       { "Close Session flag", "rmt-lct.flags.close_session", FT_BOOLEAN, 16, TFS(&tfs_set_notset), LCT_CLOSE_SESSION_FLAG, NULL, HFILL }},
+               { &hf_flags_close_object,
+                       { "Close Object flag", "rmt-lct.flags.close_object", FT_BOOLEAN, 16, TFS(&tfs_set_notset), LCT_CLOSE_OBJECT_FLAG, NULL, HFILL }},
+               { &hf_hlen,
+                       { "Header length", "rmt-lct.hlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_codepoint,
+                       { "Codepoint", "rmt-lct.codepoint", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_cci,
+                       { "Congestion Control Information", "rmt-lct.cci", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_tsi,
+                       { "Transport Session Identifier", "rmt-lct.tsi", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_tsi16,
+                       { "Transport Session Identifier", "rmt-lct.tsi", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_tsi32,
+                       { "Transport Session Identifier", "rmt-lct.tsi", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_tsi48,
+                       { "Transport Session Identifier", "rmt-lct.tsi", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_toi,
+                       { "Transport Object Identifier", "rmt-lct.toi", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_toi16,
+                       { "Transport Object Identifier", "rmt-lct.toi", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_toi32,
+                       { "Transport Object Identifier", "rmt-lct.toi", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_toi48,
+                       { "Transport Object Identifier", "rmt-lct.toi", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_toi64,
+                       { "Transport Object Identifier (up to 64 bits)", "rmt-lct.toi", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_toi_extended,
+                       { "Transport Object Identifier (bits 64-112)", "rmt-lct.toi_extended", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_sct,
+                       { "Sender Current Time", "rmt-lct.sct", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_ert,
+                       { "Expected Residual Time", "rmt-lct.ert", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_ext,
+                       { "Extension count", "rmt-lct.ext", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_hec_type,
+                       { "Header Extension Type (HET)", "rmt-lct.hec.type", FT_UINT8, BASE_DEC, VALS(hec_type_vals), 0x0, NULL, HFILL }},
+               { &hf_hec_len,
+                       { "Header Extension Length (HEL)", "rmt-lct.hec.len", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_hec_data,
+                       { "Header Extension Data", "rmt-lct.hec.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_send_rate,
+                       { "Send Rate", "rmt-lct.send_rate", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_cenc,
+                       { "Content Encoding Algorithm (CENC)", "rmt-lct.cenc", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_flute_version,
+                       { "FLUTE version (V)", "rmt-lct.flute_version", FT_UINT32, BASE_DEC, NULL, 0x00F00000, NULL, HFILL }},
+               { &hf_fdt_instance_id,
+                       { "FDT Instance ID", "rmt-lct.fdt_instance_id", FT_UINT32, BASE_DEC, NULL, 0x000FFFFF, NULL, HFILL }},
+    };
+
+    /* Setup protocol subtree array */
+    static gint *ett[] = {
+           &ett_main,
+           &ett_fsize,
+           &ett_flags,
+           &ett_ext,
+           &ett_ext_ext
+    };
+
+       /* Register the protocol name and description */
+       proto_rmt_lct = proto_register_protocol("Layered Coding Transport", "RMT-LCT", "rmt-lct");
+       new_register_dissector("rmt-lct", dissect_lct, proto_rmt_lct);
+
+       /* Required function calls to register the header fields and subtrees used */
+       proto_register_field_array(proto_rmt_lct, hf, array_length(hf));
+       proto_register_subtree_array(ett, array_length(ett));
 }
 
-/* Register preferences */
-void lct_prefs_register(struct _lct_prefs *lct_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",
-                &lct_prefs->codepoint_as_fec_encoding);
-
-       prefs_register_enum_preference(module,
-               "lct.ext.192",
-               "LCT header extension 192",
-               "How to decode LCT header extension 192",
-               &lct_prefs->ext_192,
-               enum_lct_ext_192,
-               FALSE);
-
-       prefs_register_enum_preference(module,
-               "lct.ext.193",
-               "LCT header extension 193",
-               "How to decode LCT header extension 193",
-               &lct_prefs->ext_193,
-               enum_lct_ext_193,
-               FALSE);
-}
+/*
+* Editor modelines - http://www.wireshark.org/tools/modelines.html
+*
+* Local variables:
+* c-basic-offset: 4
+* tab-width: 8
+* indent-tabs-mode: nil
+* End:
+*
+* ex: set shiftwidth=4 tabstop=8 expandtab:
+* :indentSize=4:tabSize=8:noTabs=true:
+*/
diff --git a/epan/dissectors/packet-rmt-lct.h b/epan/dissectors/packet-rmt-lct.h
deleted file mode 100644 (file)
index 4dd2cda..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/* packet-rmt-lct.h
- * Reliable Multicast Transport (RMT)
- * LCT Building Block function definitions
- * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
- *
- * $Id$
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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;
-       guint64 tsi;
-       guint64 toi;
-       const guint8 *toi_extended;
-       nstime_t sct;
-       nstime_t ert;
-       GArray *ext;
-};
-
-/* Wireshark 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, NULL, HFILL }}, \
-               { &base_structure.version,      \
-                       { "Version", base_protocol ".lct.version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},       \
-               { &base_structure.fsize_header, \
-                       { "Field sizes (bytes)", base_protocol ".lct.fsize", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},     \
-               { &base_structure.fsize_cci,    \
-                       { "Congestion Control Information field size", base_protocol ".lct.fsize.cci", FT_UINT8,        BASE_DEC, NULL, 0x0, NULL, HFILL }},    \
-               { &base_structure.fsize_tsi,    \
-                       { "Transport Session Identifier field size", base_protocol ".lct.fsize.tsi", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},     \
-               { &base_structure.fsize_toi,    \
-                       { "Transport Object Identifier field size", base_protocol ".lct.fsize.toi", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},      \
-               { &base_structure.flags_header, \
-                       { "Flags", base_protocol ".lct.flags", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},   \
-               { &base_structure.flags_sct_present,    \
-                       { "Sender Current Time present flag", base_protocol ".lct.flags.sct_present", FT_BOOLEAN, BASE_NONE, TFS(&tfs_set_notset), 0x0, NULL, HFILL }}, \
-               { &base_structure.flags_ert_present,    \
-                       { "Expected Residual Time present flag", base_protocol ".lct.flags.ert_present", FT_BOOLEAN, BASE_NONE, TFS(&tfs_set_notset), 0x0, NULL, HFILL }},      \
-               { &base_structure.flags_close_session,  \
-                       { "Close Session flag", base_protocol ".lct.flags.close_session", FT_BOOLEAN, BASE_NONE, TFS(&tfs_set_notset), 0x0, NULL, HFILL }},     \
-               { &base_structure.flags_close_object,   \
-                       { "Close Object flag", base_protocol ".lct.flags.close_object", FT_BOOLEAN, BASE_NONE, TFS(&tfs_set_notset), 0x0, NULL, HFILL }},       \
-               { &base_structure.hlen, \
-                       { "Header length", base_protocol ".lct.hlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},   \
-               { &base_structure.codepoint,    \
-                       { "Codepoint", base_protocol ".lct.codepoint", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},   \
-               { &base_structure.cci,  \
-                       { "Congestion Control Information", base_protocol ".lct.cci", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},   \
-               { &base_structure.tsi,  \
-                       { "Transport Session Identifier", base_protocol ".lct.tsi", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},     \
-               { &base_structure.toi,  \
-                       { "Transport Object Identifier (up to 64 bits)", base_protocol ".lct.toi", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},      \
-               { &base_structure.toi_extended, \
-                       { "Transport Object Identifier (up to 112 bits)", base_protocol ".lct.toi_extended", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},    \
-               { &base_structure.sct,  \
-                       { "Sender Current Time", base_protocol ".lct.sct", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0, NULL, HFILL }},      \
-               { &base_structure.ert,  \
-                       { "Expected Residual Time", base_protocol ".lct.ert", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0, NULL, HFILL }},   \
-               { &base_structure.ext,  \
-                       { "Extension count", base_protocol ".lct.ext", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, 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);
-
-gboolean 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);
-gboolean lct_ext_decode(struct _ext *e, struct _lct_prefs *prefs, tvbuff_t *tvb, proto_tree *tree, gint ett, struct _fec_ptr f);
-
-#endif
index 28440a820c4efb8413d2c7e4055bb0e3606d484b..7d6640a18af88dbeefa39e7e428351ed72d8d6e1 100644 (file)
 
 #include "config.h"
 
-#include <string.h>
-
 #include <glib.h>
+#include <math.h>
 
 #include <epan/packet.h>
 #include <epan/prefs.h>
-#include <epan/strutil.h>
-#include <epan/garrayfix.h>
+#include <epan/expert.h>
 
-#include "packet-rmt-norm.h"
-#include <math.h>
+#include "packet-rmt-common.h"
 
 /* String tables */
+
+#define NORM_INFO       1
+#define NORM_DATA       2
+#define NORM_CMD        3
+#define NORM_NACK       4
+#define NORM_ACK        5
+#define NORM_REPORT     6
+
 static const value_string string_norm_type[] =
 {
        { NORM_INFO,   "INFO" },
@@ -65,6 +70,14 @@ static const value_string string_norm_type[] =
        { 0, NULL }
 };
 
+#define NORM_CMD_FLUSH          1
+#define NORM_CMD_EOT            2
+#define NORM_CMD_SQUELCH        3
+#define NORM_CMD_CC             4
+#define NORM_CMD_REPAIR_ADV     5
+#define NORM_CMD_ACK_REQ        6
+#define NORM_CMD_APPLICATION    7
+
 static const value_string string_norm_cmd_type[] =
 {
        { NORM_CMD_FLUSH,       "FLUSH" },
@@ -77,6 +90,9 @@ static const value_string string_norm_cmd_type[] =
        { 0, NULL }
 };
 
+#define NORM_ACK_CC         1
+#define NORM_ACK_FLUSH      2
+
 static const value_string string_norm_ack_type[] =
 {
        { NORM_ACK_CC,    "ACK CC" },
@@ -84,6 +100,10 @@ static const value_string string_norm_ack_type[] =
        { 0, NULL }
 };
 
+#define NORM_NACK_ITEMS         1
+#define NORM_NACK_RANGES        2
+#define NORM_NACK_ERASURES      3
+
 static const value_string string_norm_nack_form[] =
 {
        { NORM_NACK_ITEMS,    "Items" },
@@ -92,39 +112,101 @@ static const value_string string_norm_nack_form[] =
        { 0, NULL }
 };
 
-#define hdrlen2bytes(x) ((x)*4U)
+#define NORM_FLAG_REPAIR        0x01
+#define NORM_FLAG_EXPLICIT      0x02
+#define NORM_FLAG_INFO          0x04
+#define NORM_FLAG_UNRELIABLE    0x08
+#define NORM_FLAG_FILE          0x10
+#define NORM_FLAG_STREAM        0x20
+#define NORM_FLAG_MSG_START     0x40
+
+#define NORM_NACK_SEGMENT       0x01
+#define NORM_NACK_BLOCK         0x02
+#define NORM_NACK_INFO          0x04
+#define NORM_NACK_OBJECT        0x08
+
+#define NORM_FLAG_CC_CLR        0x01
+#define NORM_FLAG_CC_PLR        0x02
+#define NORM_FLAG_CC_RTT        0x04
+#define NORM_FLAG_CC_START      0x08
+#define NORM_FLAG_CC_LEAVE      0x10
 
-/* Initialize the protocol and registered fields */
-/* ============================================= */
+#define hdrlen2bytes(x) ((x)*4U)
 
-static int proto = -1;
 static gboolean global_norm_heur = FALSE;
 
-static struct _norm_hf hf;
-static struct _norm_ett ett;
-
-static struct _norm_prefs preferences;
-
-/* Preferences */
-/* =========== */
-
-/* Set/Reset preferences to default values */
-static void norm_prefs_set_default(struct _norm_prefs *norm_prefs)
+typedef struct norm_packet_data
 {
-       fec_prefs_set_default(&norm_prefs->fec);
-}
+       guint8 encoding_id;
+} norm_packet_data_t;
 
-/* Register preferences */
-static void norm_prefs_register(struct _norm_prefs *norm_prefs, module_t *module)
-{
-       fec_prefs_register(&norm_prefs->fec, module);
-}
+/* Initialize the protocol and registered fields */
+/* ============================================= */
+static dissector_handle_t rmt_fec_handle;
+
+static int proto_rmt_norm = -1;
+
+static int hf_version = -1;
+static int hf_type = -1;
+static int hf_hlen = -1;
+static int hf_sequence = -1;
+static int hf_source_id = -1;
+static int hf_instance_id = -1;
+static int hf_grtt = -1;
+static int hf_backoff = -1;
+static int hf_gsize = -1;
+static int hf_flags = -1;
+static int hf_flag_repair = -1;
+static int hf_flag_norm_explicit = -1;
+static int hf_flag_info = -1;
+static int hf_flag_unreliable = -1;
+static int hf_flag_file = -1;
+static int hf_flag_stream = -1;
+static int hf_flag_msgstart = -1;
+static int hf_object_transport_id = -1;
+static int hf_extension = -1;
+static int hf_reserved = -1;
+static int hf_payload_len = -1;
+static int hf_payload_offset = -1;
+static int hf_cmd_flavor = -1;
+static int hf_cc_sequence = -1;
+static int hf_cc_sts = -1;
+static int hf_cc_stus = -1;
+static int hf_cc_node_id = -1;
+static int hf_cc_flags = -1;
+static int hf_cc_flags_clr = -1;
+static int hf_cc_flags_plr = -1;
+static int hf_cc_flags_rtt = -1;
+static int hf_cc_flags_start = -1;
+static int hf_cc_flags_leave = -1;
+static int hf_cc_rtt = -1;
+static int hf_cc_rate = -1;
+static int hf_cc_transport_id = -1;
+static int hf_ack_source = -1;
+static int hf_ack_type = -1;
+static int hf_ack_id = -1;
+static int hf_ack_grtt_sec = -1;
+static int hf_ack_grtt_usec = -1;
+static int hf_nack_server = -1;
+static int hf_nack_grtt_sec = -1;
+static int hf_nack_grtt_usec = -1;
+static int hf_nack_form = -1;
+static int hf_nack_flags = -1;
+static int hf_nack_flags_segment = -1;
+static int hf_nack_flags_block = -1;
+static int hf_nack_flags_info = -1;
+static int hf_nack_flags_object = -1;
+static int hf_nack_length = -1;
+static int hf_payload = -1;
+static int hf_fec_encoding_id = -1;
+
+static int ett_main = -1;
+static int ett_hdrext = -1;
+static int ett_flags = -1;
+static int ett_streampayload = -1;
+static int ett_congestioncontrol = -1;
+static int ett_nackdata = -1;
 
-/* Save preferences to alc_prefs_old */
-static void norm_prefs_save(struct _norm_prefs *p, struct _norm_prefs *p_old)
-{
-       *p_old = *p;
-}
 
 static const double RTT_MIN = 1.0e-06;
 static const double RTT_MAX = 1000;
@@ -143,118 +225,97 @@ static double UnquantizeGSize(guint8 gsizex)
        return mant * pow(10, exponent);
 }
 
-static double UnquantizeSendRate(guint16 send_rate)
-{
-       return (send_rate >> 4) * 10.0 / 4096.0 * pow(10.0, (send_rate & 0x000f));
-}
-
 /* code to dissect fairly common sequence in NORM packets */
 static guint dissect_grrtetc(proto_tree *tree, tvbuff_t *tvb, guint offset)
 {
        guint8 backoff;
        double gsizex;
        double grtt;
-       proto_tree_add_item(tree, hf.instance_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
+       proto_tree_add_item(tree, hf_instance_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
        grtt = UnquantizeRtt(tvb_get_guint8(tvb, offset));
-       proto_tree_add_double(tree, hf.grtt, tvb, offset, 1, grtt); offset++;
+       proto_tree_add_double(tree, hf_grtt, tvb, offset, 1, grtt); offset++;
        backoff = hi_nibble(tvb_get_guint8(tvb, offset));
        gsizex = UnquantizeGSize((guint8)lo_nibble(tvb_get_guint8(tvb, offset)));
-       proto_tree_add_uint(tree, hf.backoff, tvb, offset, 1, backoff);
-       proto_tree_add_double(tree, hf.gsize, tvb, offset, 1, gsizex);
+       proto_tree_add_uint(tree, hf_backoff, tvb, offset, 1, backoff);
+       proto_tree_add_double(tree, hf_gsize, tvb, offset, 1, gsizex);
        offset++;
        return offset;
 }
 
 /* split out some common FEC handling */
-static guint dissect_feccode(struct _norm *norm, struct _fec_ptr *f, proto_tree *tree,
+static guint dissect_feccode(proto_tree *tree,
                                                         tvbuff_t *tvb, guint offset, packet_info *pinfo, gint reserved)
 {
-       f->fec = &norm->fec;
-       f->hf = &hf.fec;
-       f->ett = &ett.fec;
-       f->prefs = &preferences.fec;
+       norm_packet_data_t* norm_data;
+       guint8 encoding_id = tvb_get_guint8(tvb, offset);
 
+       /* Save encoding ID */
+       norm_data = se_new0(norm_packet_data_t);
+       norm_data->encoding_id = encoding_id;
 
-       norm->fec.encoding_id = tvb_get_guint8(tvb, offset);
-       norm->fec.encoding_id_present = 1;
-       proto_tree_add_item(tree, hf.fec.encoding_id, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
+       p_add_proto_data(pinfo->fd, proto_rmt_norm, 0, norm_data);
+
+       proto_tree_add_item(tree, hf_fec_encoding_id, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
        if (reserved) {
-               proto_tree_add_item(tree, hf.reserved, tvb, offset, 1, ENC_NA); offset++;
+               proto_tree_add_item(tree, hf_reserved, tvb, offset, 1, ENC_NA); offset++;
        }
-       proto_tree_add_item(tree, hf.object_transport_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
+       proto_tree_add_item(tree, hf_object_transport_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
+
+       if (tvb_reported_length_remaining(tvb, offset) > 0) {
+               fec_data_exchange_t fec;
+               tvbuff_t *new_tvb;
+               int len;
 
-       if (norm->fec.encoding_id_present &&
-           tvb_reported_length_remaining(tvb, offset) > 0) {
-               fec_dissector(*f, tvb, tree, &offset);
-               if (check_col(pinfo->cinfo, COL_INFO))
-                       fec_info_column(f->fec, pinfo);
+               new_tvb = tvb_new_subset_remaining(tvb, offset);
+
+               fec.encoding_id = encoding_id;
+               len = call_dissector_with_data(rmt_fec_handle, new_tvb, pinfo, tree, &fec);
+               if (len > 0)
+                       offset += len;
        }
+
        return offset;
 }
 
-static guint dissect_norm_hdrext(struct _norm *norm, struct _fec_ptr *f, proto_tree *tree,
-                                                        tvbuff_t *tvb, guint offset, packet_info *pinfo _U_)
+static guint dissect_norm_hdrext(proto_tree *tree, packet_info *pinfo,
+                                                        tvbuff_t *tvb, guint offset, guint8 hlen)
 {
-       guint i;
-       proto_item *ti;
-       /* Allocate an array of _ext elements */
-       GArray *ext;
-       guint offset_old = offset;
-       proto_tree *ext_tree;
+       lct_data_exchange_t data_exchange;
+       norm_packet_data_t* packet_data = (norm_packet_data_t*)p_get_proto_data(pinfo->fd, proto_rmt_norm, 0);
 
-       ext = g_array_new(FALSE, TRUE, sizeof(struct _ext));
+       memset(&data_exchange, 0, sizeof(data_exchange));
 
-       rmt_ext_parse(ext, tvb, &offset, hdrlen2bytes(norm->hlen));
+       if (packet_data != NULL)
+               data_exchange.codepoint = packet_data->encoding_id;
+
+       offset += lct_ext_decode(tree, tvb, pinfo, offset, hdrlen2bytes(hlen), &data_exchange,
+                               hf_extension, ett_hdrext);
 
-       if (ext->len > 0)
-       {
-               struct _lct_prefs lctp;
-               memset(&lctp, 0, sizeof(lctp));
-               if (tree)
-               {
-                       /* Add the extensions subtree */
-                       ti = proto_tree_add_uint(tree, hf.extension,
-                               tvb, offset_old,
-                               offset - offset_old, ext->len);
-                       ext_tree = proto_item_add_subtree(ti, ett.hdrext);
-               } else
-                       ext_tree = NULL;
-
-               /* Add the extensions to the subtree */
-               for (i = 0; i < ext->len; i++) {
-                       struct _ext *e = &g_array_index(ext, struct _ext, i);
-
-                       lct_ext_decode(e, &lctp, tvb, ext_tree, ett.hdrext, *f);
-                       /* fec_decode_ext_fti(e, tvb, ext_tree, ett.hdrext, *f); */
-               }
-       }
-       g_array_free(ext, TRUE);
        return offset;
 }
 
-static guint dissect_nack_data(struct _norm *norm, proto_tree *tree,
+static guint dissect_nack_data(proto_tree *tree,
                                                         tvbuff_t *tvb, guint offset, packet_info *pinfo)
 {
        proto_item *ti, *tif;
        proto_tree *nack_tree, *flag_tree;
        guint16 len;
        ti = proto_tree_add_text(tree, tvb, offset, -1, "NACK Data");
-       nack_tree = proto_item_add_subtree(ti, ett.nackdata);
-       proto_tree_add_item(nack_tree, hf.nack_form, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1;
-
-       tif = proto_tree_add_item(nack_tree, hf.nack_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
-       flag_tree = proto_item_add_subtree(tif, ett.flags);
-       proto_tree_add_item(flag_tree, hf.nack_flags_segment, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(flag_tree, hf.nack_flags_block, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(flag_tree, hf.nack_flags_info, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(flag_tree, hf.nack_flags_object, tvb, offset, 1, ENC_BIG_ENDIAN);
+       nack_tree = proto_item_add_subtree(ti, ett_nackdata);
+       proto_tree_add_item(nack_tree, hf_nack_form, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1;
+
+       tif = proto_tree_add_item(nack_tree, hf_nack_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
+       flag_tree = proto_item_add_subtree(tif, ett_flags);
+       proto_tree_add_item(flag_tree, hf_nack_flags_segment, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(flag_tree, hf_nack_flags_block, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(flag_tree, hf_nack_flags_info, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(flag_tree, hf_nack_flags_object, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;
        len = tvb_get_ntohs(tvb, offset);
-       proto_tree_add_item(nack_tree, hf.nack_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
+       proto_tree_add_item(nack_tree, hf_nack_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
        proto_item_set_len(ti, 4+len);
        if (len > 4) {
-               struct _fec_ptr f;
-               dissect_feccode(norm, &f, nack_tree, tvb, offset, pinfo, 1);
+               dissect_feccode(nack_tree, tvb, offset, pinfo, 1);
        }
        offset += len;
        return offset;
@@ -262,297 +323,263 @@ static guint dissect_nack_data(struct _norm *norm, proto_tree *tree,
 
 
 /* code to dissect NORM data packets */
-static void dissect_norm_data(struct _norm *norm, proto_tree *tree,
-       tvbuff_t *tvb, guint offset, packet_info *pinfo)
+static void dissect_norm_data(proto_tree *tree, packet_info *pinfo,
+       tvbuff_t *tvb, guint offset, guint8 hlen)
 {
        guint8 flags;
        proto_item *ti;
        proto_tree *flag_tree;
-       struct _fec_ptr f;
 
        offset = dissect_grrtetc(tree, tvb, offset);
 
 
-       ti = proto_tree_add_item(tree, hf.flags, tvb, offset, 1, ENC_BIG_ENDIAN);
+       ti = proto_tree_add_item(tree, hf_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
        flags = tvb_get_guint8(tvb, offset);
-       flag_tree = proto_item_add_subtree(ti, ett.flags);
-       proto_tree_add_item(flag_tree, hf.flag.repair, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(flag_tree, hf.flag.norm_explicit, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(flag_tree, hf.flag.info, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(flag_tree, hf.flag.unreliable, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(flag_tree, hf.flag.file, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(flag_tree, hf.flag.stream, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(flag_tree, hf.flag.msgstart, tvb, offset, 1, ENC_BIG_ENDIAN);
+       flag_tree = proto_item_add_subtree(ti, ett_flags);
+       proto_tree_add_item(flag_tree, hf_flag_repair, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(flag_tree, hf_flag_norm_explicit, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(flag_tree, hf_flag_info, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(flag_tree, hf_flag_unreliable, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(flag_tree, hf_flag_file, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(flag_tree, hf_flag_stream, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(flag_tree, hf_flag_msgstart, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;
 
-       offset = dissect_feccode(norm, &f, tree, tvb, offset, pinfo, 0);
+       offset = dissect_feccode(tree, tvb, offset, pinfo, 0);
 
-       if (offset < hdrlen2bytes(norm->hlen)) {
-               offset = dissect_norm_hdrext(norm, &f, tree, tvb, offset, pinfo);
+       if (offset < hdrlen2bytes(hlen)) {
+               offset = dissect_norm_hdrext(tree, pinfo, tvb, offset, hlen);
        }
        if (flags & NORM_FLAG_STREAM) {
                ti = proto_tree_add_text(tree, tvb, offset, 8, "Stream Data");
-               flag_tree = proto_item_add_subtree(ti, ett.streampayload);
-               proto_tree_add_item(flag_tree, hf.reserved, tvb, offset, 2, ENC_NA); offset+=2;
-               proto_tree_add_item(flag_tree, hf.payload_len, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
-               proto_tree_add_item(flag_tree, hf.payload_offset, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4;
+               flag_tree = proto_item_add_subtree(ti, ett_streampayload);
+               proto_tree_add_item(flag_tree, hf_reserved, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
+               proto_tree_add_item(flag_tree, hf_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
+               proto_tree_add_item(flag_tree, hf_payload_offset, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4;
 
        }
        if (tvb_reported_length_remaining(tvb, offset) > 0)
-               proto_tree_add_none_format(tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_reported_length_remaining(tvb, offset));
+               proto_tree_add_item(tree, hf_payload, tvb, offset, -1, ENC_NA);
 
 }
 
 /* code to dissect NORM info packets */
-static void dissect_norm_info(struct _norm *norm, proto_tree *tree,
-       tvbuff_t *tvb, guint offset, packet_info *pinfo _U_)
+static void dissect_norm_info(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, guint offset, guint8 hlen)
 {
        proto_item *ti;
        proto_tree *flag_tree;
+       norm_packet_data_t* norm_data;
 
        offset = dissect_grrtetc(tree, tvb, offset);
 
-       ti = proto_tree_add_item(tree, hf.flags, tvb, offset, 1, ENC_BIG_ENDIAN);
-       flag_tree = proto_item_add_subtree(ti, ett.flags);
-       proto_tree_add_item(flag_tree, hf.flag.repair, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(flag_tree, hf.flag.norm_explicit, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(flag_tree, hf.flag.info, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(flag_tree, hf.flag.unreliable, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(flag_tree, hf.flag.file, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(flag_tree, hf.flag.stream, tvb, offset, 1, ENC_BIG_ENDIAN);
-       proto_tree_add_item(flag_tree, hf.flag.msgstart, tvb, offset, 1, ENC_BIG_ENDIAN);
+       ti = proto_tree_add_item(tree, hf_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
+       flag_tree = proto_item_add_subtree(ti, ett_flags);
+       proto_tree_add_item(flag_tree, hf_flag_repair, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(flag_tree, hf_flag_norm_explicit, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(flag_tree, hf_flag_info, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(flag_tree, hf_flag_unreliable, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(flag_tree, hf_flag_file, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(flag_tree, hf_flag_stream, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(flag_tree, hf_flag_msgstart, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;
 
-       norm->fec.encoding_id = tvb_get_guint8(tvb, offset);
-       norm->fec.encoding_id_present = 1;
-       proto_tree_add_item(tree, hf.fec.encoding_id, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
-       proto_tree_add_item(tree, hf.object_transport_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
-
-       if (offset < hdrlen2bytes(norm->hlen)) {
-               struct _fec_ptr f;
-               memset(&f, 0, sizeof f);
-               f.fec = &norm->fec;
-               f.hf = &hf.fec;
-               f.ett = &ett.fec;
-               f.prefs = &preferences.fec;
-               offset = dissect_norm_hdrext(norm, &f, tree, tvb, offset, pinfo);
+       /* Save encoding ID */
+       norm_data = se_new0(norm_packet_data_t);
+       norm_data->encoding_id = tvb_get_guint8(tvb, offset);
+
+       p_add_proto_data(pinfo->fd, proto_rmt_norm, 0, norm_data);
+
+       proto_tree_add_item(tree, hf_fec_encoding_id, tvb, offset, 1, ENC_BIG_ENDIAN); offset++;
+       proto_tree_add_item(tree, hf_object_transport_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2;
+
+       if (offset < hdrlen2bytes(hlen)) {
+               offset = dissect_norm_hdrext(tree, pinfo, tvb, offset, hlen);
        }
        if (tvb_reported_length_remaining(tvb, offset) > 0)
-               proto_tree_add_none_format(tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_reported_length_remaining(tvb, offset));
+               proto_tree_add_item(tree, hf_payload, tvb, offset, -1, ENC_NA);
 
 }
 /* code to dissect NORM cmd(flush) packets */
-static guint dissect_norm_cmd_flush(struct _norm *norm, proto_tree *tree,
-       tvbuff_t *tvb, guint offset, packet_info *pinfo)
+static guint dissect_norm_cmd_flush(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, 
+                                    guint offset, guint8 hlen)
 {
-       struct _fec_ptr f;
-       offset = dissect_feccode(norm, &f, tree, tvb, offset, pinfo, 0);
-       if (offset < hdrlen2bytes(norm->hlen)) {
-               offset = dissect_norm_hdrext(norm, &f, tree, tvb, offset, pinfo);
+       offset = dissect_feccode(tree, tvb, offset, pinfo, 0);
+       if (offset < hdrlen2bytes(hlen)) {
+               offset = dissect_norm_hdrext(tree, pinfo, tvb, offset, hlen);
        }
        return offset;
 }
 
 /* code to dissect NORM cmd(flush) packets */
-static guint dissect_norm_cmd_repairadv(struct _norm *norm, proto_tree *tree,
-       tvbuff_t *tvb, guint offset, packet_info *pinfo)
+static guint dissect_norm_cmd_repairadv(proto_tree *tree, packet_info *pinfo,
+       tvbuff_t *tvb, guint offset, guint8 hlen)
 {
-       proto_tree_add_item(tree, hf.flags, tvb, offset, 1, ENC_BIG_ENDIAN); offset ++;
-       proto_tree_add_item(tree, hf.reserved, tvb, offset, 2, ENC_NA); offset +=2;
-
-       if (offset < hdrlen2bytes(norm->hlen)) {
-               struct _fec_ptr f;
-               memset(&f, 0, sizeof f);
-               f.fec = &norm->fec;
-               f.hf = &hf.fec;
-               f.ett = &ett.fec;
-               f.prefs = &preferences.fec;
-               offset = dissect_norm_hdrext(norm, &f, tree, tvb, offset, pinfo);
+       proto_tree_add_item(tree, hf_flags, tvb, offset, 1, ENC_BIG_ENDIAN); offset ++;
+       proto_tree_add_item(tree, hf_reserved, tvb, offset, 2, ENC_BIG_ENDIAN); offset +=2;
+
+       if (offset < hdrlen2bytes(hlen)) {
+               offset = dissect_norm_hdrext(tree, pinfo, tvb, offset, hlen);
        }
        while (tvb_reported_length_remaining(tvb, offset) > 0) {
-               offset = dissect_nack_data(norm, tree, tvb, offset, pinfo);
+               offset = dissect_nack_data(tree, tvb, offset, pinfo);
        }
        return offset;
 }
 
 /* code to dissect NORM cmd(cc) packets */
-static guint dissect_norm_cmd_cc(struct _norm *norm, proto_tree *tree,
-       tvbuff_t *tvb, guint offset, packet_info *pinfo _U_)
+static guint dissect_norm_cmd_cc(proto_tree *tree, packet_info *pinfo,
+       tvbuff_t *tvb, guint offset, guint8 hlen)
 {
-       proto_tree_add_item(tree, hf.reserved, tvb, offset, 1, ENC_NA); offset ++;
-       proto_tree_add_item(tree, hf.cc_sequence, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
-
-       proto_tree_add_item(tree, hf.cc_sts, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
-       proto_tree_add_item(tree, hf.cc_stus, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
-       if (offset < hdrlen2bytes(norm->hlen)) {
-               struct _fec_ptr f;
-               memset(&f, 0, sizeof f);
-               f.fec = &norm->fec;
-               f.hf = &hf.fec;
-               f.ett = &ett.fec;
-               f.prefs = &preferences.fec;
-               offset = dissect_norm_hdrext(norm, &f, tree, tvb, offset, pinfo);
+       proto_tree_add_item(tree, hf_reserved, tvb, offset, 1, ENC_NA); offset ++;
+       proto_tree_add_item(tree, hf_cc_sequence, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
+
+       proto_tree_add_item(tree, hf_cc_sts, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
+       proto_tree_add_item(tree, hf_cc_stus, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
+       if (offset < hdrlen2bytes(hlen)) {
+               offset = dissect_norm_hdrext(tree, pinfo, tvb, offset, hlen);
        }
        while (tvb_reported_length_remaining(tvb, offset) > 0) {
                proto_item *ti, *tif;
                proto_tree *cc_tree, *flag_tree;
                double grtt;
                ti = proto_tree_add_text(tree, tvb, offset, 8, "Congestion Control");
-               cc_tree = proto_item_add_subtree(ti, ett.congestioncontrol);
-               proto_tree_add_item(cc_tree, hf.cc_node_id, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
-               tif = proto_tree_add_item(cc_tree, hf.cc_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
-               flag_tree = proto_item_add_subtree(tif, ett.flags);
-               proto_tree_add_item(flag_tree, hf.cc_flags_clr, tvb, offset, 1, ENC_BIG_ENDIAN);
-               proto_tree_add_item(flag_tree, hf.cc_flags_plr, tvb, offset, 1, ENC_BIG_ENDIAN);
-               proto_tree_add_item(flag_tree, hf.cc_flags_rtt, tvb, offset, 1, ENC_BIG_ENDIAN);
-               proto_tree_add_item(flag_tree, hf.cc_flags_start, tvb, offset, 1, ENC_BIG_ENDIAN);
-               proto_tree_add_item(flag_tree, hf.cc_flags_leave, tvb, offset, 1, ENC_BIG_ENDIAN);
+               cc_tree = proto_item_add_subtree(ti, ett_congestioncontrol);
+               proto_tree_add_item(cc_tree, hf_cc_node_id, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
+               tif = proto_tree_add_item(cc_tree, hf_cc_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
+               flag_tree = proto_item_add_subtree(tif, ett_flags);
+               proto_tree_add_item(flag_tree, hf_cc_flags_clr, tvb, offset, 1, ENC_BIG_ENDIAN);
+               proto_tree_add_item(flag_tree, hf_cc_flags_plr, tvb, offset, 1, ENC_BIG_ENDIAN);
+               proto_tree_add_item(flag_tree, hf_cc_flags_rtt, tvb, offset, 1, ENC_BIG_ENDIAN);
+               proto_tree_add_item(flag_tree, hf_cc_flags_start, tvb, offset, 1, ENC_BIG_ENDIAN);
+               proto_tree_add_item(flag_tree, hf_cc_flags_leave, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                grtt = UnquantizeRtt(tvb_get_guint8(tvb, offset));
-               proto_tree_add_double(cc_tree, hf.cc_rtt, tvb, offset, 1, grtt); offset += 1;
-               grtt = UnquantizeSendRate(tvb_get_ntohs(tvb, offset));
-               proto_tree_add_double(cc_tree, hf.cc_rate, tvb, offset, 2, grtt); offset += 2;
+               proto_tree_add_double(cc_tree, hf_cc_rtt, tvb, offset, 1, grtt); offset += 1;
+               grtt = rmt_decode_send_rate(tvb_get_ntohs(tvb, offset));
+               proto_tree_add_double(cc_tree, hf_cc_rate, tvb, offset, 2, grtt); offset += 2;
        }
        return offset;
 }
 
 /* code to dissect NORM cmd(squelch) packets */
-static guint dissect_norm_cmd_squelch(struct _norm *norm, proto_tree *tree,
-       tvbuff_t *tvb, guint offset, packet_info *pinfo)
+static guint dissect_norm_cmd_squelch(proto_tree *tree, packet_info *pinfo,
+       tvbuff_t *tvb, guint offset)
 {
-       struct _fec_ptr f;
-       offset = dissect_feccode(norm, &f, tree, tvb, offset, pinfo, 0);
+       offset = dissect_feccode(tree, tvb, offset, pinfo, 0);
 
        while (tvb_reported_length_remaining(tvb, offset) > 0) {
-               proto_tree_add_item(tree, hf.cc_transport_id, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 2;
+               proto_tree_add_item(tree, hf_cc_transport_id, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 2;
        }
        return offset;
 }
 
 /* code to dissect NORM cmd(squelch) packets */
-static guint dissect_norm_cmd_ackreq(struct _norm *norm _U_, proto_tree *tree,
-       tvbuff_t *tvb, guint offset, packet_info *pinfo _U_)
+static guint dissect_norm_cmd_ackreq(proto_tree *tree, packet_info *pinfo _U_,
+       tvbuff_t *tvb, guint offset)
 {
-       proto_tree_add_item(tree, hf.reserved, tvb, offset, 1, ENC_NA); offset ++;
-       proto_tree_add_item(tree, hf.ack_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1;
-       proto_tree_add_item(tree, hf.ack_id, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1;
+       proto_tree_add_item(tree, hf_reserved, tvb, offset, 1, ENC_NA); offset ++;
+       proto_tree_add_item(tree, hf_ack_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1;
+       proto_tree_add_item(tree, hf_ack_id, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1;
        return offset;
 }
 
 /* code to dissect NORM cmd packets */
-static void dissect_norm_cmd(struct _norm *norm, proto_tree *tree,
-       tvbuff_t *tvb, guint offset, packet_info *pinfo)
+static void dissect_norm_cmd(proto_tree *tree, packet_info *pinfo,
+       tvbuff_t *tvb, guint offset, guint8 hlen)
 {
        guint8 flavor;
 
        offset = dissect_grrtetc(tree, tvb, offset);
        flavor = tvb_get_guint8(tvb, offset);
-       if (check_col(pinfo->cinfo, COL_INFO))
-               col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
+
+       col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
                val_to_str(flavor, string_norm_cmd_type, "Unknown Cmd Type (0x%04x)"));
-       proto_tree_add_item(tree, hf.cmd_flavor, tvb, offset, 1, ENC_BIG_ENDIAN); offset ++;
+       proto_tree_add_item(tree, hf_cmd_flavor, tvb, offset, 1, ENC_BIG_ENDIAN); offset ++;
        switch(flavor) {
        case NORM_CMD_CC:
-               offset = dissect_norm_cmd_cc(norm, tree, tvb, offset, pinfo);
+               offset = dissect_norm_cmd_cc(tree, pinfo, tvb, offset, hlen);
                break;
        case NORM_CMD_FLUSH:
-               offset = dissect_norm_cmd_flush(norm, tree, tvb, offset, pinfo);
+               offset = dissect_norm_cmd_flush(tree, pinfo, tvb, offset, hlen);
                break;
        case NORM_CMD_SQUELCH:
-               offset = dissect_norm_cmd_squelch(norm, tree, tvb, offset, pinfo);
+               offset = dissect_norm_cmd_squelch(tree, pinfo, tvb, offset);
                break;
        case NORM_CMD_REPAIR_ADV:
-               offset = dissect_norm_cmd_repairadv(norm, tree, tvb, offset, pinfo);
+               offset = dissect_norm_cmd_repairadv(tree, pinfo, tvb, offset, hlen);
                break;
        case NORM_CMD_ACK_REQ:
-               offset = dissect_norm_cmd_ackreq(norm, tree, tvb, offset, pinfo);
+               offset = dissect_norm_cmd_ackreq(tree, pinfo, tvb, offset);
                break;
        }
        if (tvb_reported_length_remaining(tvb, offset) > 0)
-               proto_tree_add_none_format(tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_reported_length_remaining(tvb, offset));
+               proto_tree_add_item(tree, hf_payload, tvb, offset, -1, ENC_NA);
 }
 
 /* code to dissect NORM ack packets */
-static void dissect_norm_ack(struct _norm *norm, proto_tree *tree,
-       tvbuff_t *tvb, guint offset, packet_info *pinfo)
+static void dissect_norm_ack(proto_tree *tree, packet_info *pinfo,
+       tvbuff_t *tvb, guint offset, guint8 hlen)
 {
        guint8 acktype;
 
-       proto_tree_add_item(tree, hf.ack_source, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
-       proto_tree_add_item(tree, hf.instance_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
+       proto_tree_add_item(tree, hf_ack_source, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
+       proto_tree_add_item(tree, hf_instance_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
        acktype = tvb_get_guint8(tvb, offset);
-       if (check_col(pinfo->cinfo, COL_INFO))
-               col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
+
+       col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
                val_to_str(acktype, string_norm_ack_type, "Unknown Ack Type (0x%04x)"));
-       proto_tree_add_item(tree, hf.ack_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1;
-       proto_tree_add_item(tree, hf.ack_id, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1;
-       proto_tree_add_item(tree, hf.ack_grtt_sec, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
-       proto_tree_add_item(tree, hf.ack_grtt_usec, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
-       if (offset < hdrlen2bytes(norm->hlen)) {
-               struct _fec_ptr f;
-               memset(&f, 0, sizeof f);
-               f.fec = &norm->fec;
-               f.hf = &hf.fec;
-               f.ett = &ett.fec;
-               f.prefs = &preferences.fec;
-               offset = dissect_norm_hdrext(norm, &f, tree, tvb, offset, pinfo);
+       proto_tree_add_item(tree, hf_ack_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1;
+       proto_tree_add_item(tree, hf_ack_id, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1;
+       proto_tree_add_item(tree, hf_ack_grtt_sec, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
+       proto_tree_add_item(tree, hf_ack_grtt_usec, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
+       if (offset < hdrlen2bytes(hlen)) {
+               offset = dissect_norm_hdrext(tree, pinfo, tvb, offset, hlen);
        }
 
        if (tvb_reported_length_remaining(tvb, offset) > 0)
-               proto_tree_add_none_format(tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_reported_length_remaining(tvb, offset));
+               proto_tree_add_item(tree, hf_payload, tvb, offset, -1, ENC_NA);
 
 }
 
 
 
 /* code to dissect NORM nack packets */
-static void dissect_norm_nack(struct _norm *norm, proto_tree *tree,
-       tvbuff_t *tvb, guint offset, packet_info *pinfo)
+static void dissect_norm_nack(proto_tree *tree, packet_info *pinfo,
+       tvbuff_t *tvb, guint offset, guint8 hlen)
 {
-       proto_tree_add_item(tree, hf.nack_server, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
-       proto_tree_add_item(tree, hf.instance_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
-       proto_tree_add_item(tree, hf.reserved, tvb, offset, 2, ENC_NA); offset += 2;
-       proto_tree_add_item(tree, hf.nack_grtt_sec, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
-       proto_tree_add_item(tree, hf.nack_grtt_usec, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
-       if (offset < hdrlen2bytes(norm->hlen)) {
-               struct _fec_ptr f;
-               memset(&f, 0, sizeof f);
-               f.fec = &norm->fec;
-               f.hf = &hf.fec;
-               f.ett = &ett.fec;
-               f.prefs = &preferences.fec;
-               offset = dissect_norm_hdrext(norm, &f, tree, tvb, offset, pinfo);
+       proto_tree_add_item(tree, hf_nack_server, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
+       proto_tree_add_item(tree, hf_instance_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
+       proto_tree_add_item(tree, hf_reserved, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
+       proto_tree_add_item(tree, hf_nack_grtt_sec, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
+       proto_tree_add_item(tree, hf_nack_grtt_usec, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;
+       if (offset < hdrlen2bytes(hlen)) {
+               offset = dissect_norm_hdrext(tree, pinfo, tvb, offset, hlen);
        }
 
        while (tvb_reported_length_remaining(tvb, offset) > 0) {
-               offset = dissect_nack_data(norm, tree, tvb, offset, pinfo);
+               offset = dissect_nack_data(tree, tvb, offset, pinfo);
        }
        if (tvb_reported_length_remaining(tvb, offset) > 0)
-               proto_tree_add_none_format(tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_reported_length_remaining(tvb, offset));
+               proto_tree_add_item(tree, hf_payload, tvb, offset, -1, ENC_NA);
 
 }
 /* Code to actually dissect the packets */
 /* ==================================== */
-
-static void dissect_norm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+static int
+dissect_norm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
 {
        /* Logical packet representation */
-       struct _norm norm;
+       guint8 version;
+       guint8 type;
+       guint8 hlen;
 
        /* Offset for subpacket dissection */
-       guint offset;
+       guint offset = 0;
 
        /* 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 */
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "NORM");
        col_clear(pinfo->cinfo, COL_INFO);
@@ -560,101 +587,90 @@ static void dissect_norm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        /* 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, ENC_NA);
-               norm_tree = proto_item_add_subtree(ti, ett.main);
+       version = hi_nibble(tvb_get_guint8(tvb, offset));
 
-               /* Fill the NORM subtree */
-               proto_tree_add_uint(norm_tree, hf.version, tvb, offset, 1, norm.version);
+       /* Create subtree for the NORM protocol */
+       ti = proto_tree_add_item(tree, proto_rmt_norm, tvb, offset, -1, ENC_NA);
+       norm_tree = proto_item_add_subtree(ti, ett_main);
 
-       } else
-               norm_tree = NULL;
+       /* Fill the NORM subtree */
+       proto_tree_add_uint(norm_tree, hf_version, tvb, offset, 1, version);
 
        /* This dissector supports only NORMv1 packets.
-        * If norm.version > 1 print only version field and quit.
+        * If version > 1 print only version field and quit.
         */
-       if (norm.version == 1) {
+       if (version != 1) {
+               expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN, "Sorry, this dissector supports ALC version 1 only");
 
-               /* NORM header dissection, part 2 */
-               /* ------------------------------ */
+               /* Complete entry in Info column on summary display */
+               col_add_fstr(pinfo->cinfo, COL_INFO, "Version: %u (not supported)", version);
+               return 0;
+       }
 
-               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);
+       /* NORM header dissection, part 2 */
+       /* ------------------------------ */
 
-               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_item(norm_tree, hf.source_id, tvb, offset+4, 4, ENC_BIG_ENDIAN);
-               }
+       type = lo_nibble(tvb_get_guint8(tvb, offset));
+       hlen = tvb_get_guint8(tvb, offset+1);
 
-               offset += 8;
+       if (tree)
+       {
+               proto_tree_add_uint(norm_tree, hf_type, tvb, offset, 1, type);
+               proto_tree_add_item(norm_tree, hf_hlen, tvb, offset+1, 1, ENC_BIG_ENDIAN);
+               proto_tree_add_item(norm_tree, hf_sequence, tvb, offset+2, 2, ENC_BIG_ENDIAN);
+               proto_tree_add_item(norm_tree, hf_source_id, tvb, offset+4, 4, ENC_BIG_ENDIAN);
+       }
 
+       offset += 8;
 
-               /* Complete entry in Info column on summary display */
-               /* ------------------------------------------------ */
-               if (check_col(pinfo->cinfo, COL_INFO))
-                               col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
-                               val_to_str(norm.type, string_norm_type, "Unknown Type (0x%04x)"));
-
-
-               switch(norm.type) {
-               case NORM_INFO:
-                       dissect_norm_info(&norm, norm_tree, tvb, offset, pinfo);
-                       break;
-               case NORM_DATA:
-                       dissect_norm_data(&norm, norm_tree, tvb, offset, pinfo);
-                       break;
-               case NORM_CMD:
-                       dissect_norm_cmd(&norm, norm_tree, tvb, offset, pinfo);
-                       break;
-               case NORM_ACK:
-                       dissect_norm_ack(&norm, norm_tree, tvb, offset, pinfo);
-                       break;
-               case NORM_NACK:
-                       dissect_norm_nack(&norm, norm_tree, tvb, offset, pinfo);
-                       break;
-               default:
-                       /* Add the Payload item */
-                       if (tvb_reported_length_remaining(tvb, offset) > 0)
-                               proto_tree_add_none_format(norm_tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_reported_length_remaining(tvb, offset));
-                       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);
+       /* Complete entry in Info column on summary display */
+       /* ------------------------------------------------ */
+       col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
+                       val_to_str(type, string_norm_type, "Unknown Type (0x%04x)"));
+
+
+       switch(type) {
+       case NORM_INFO:
+               dissect_norm_info(norm_tree, pinfo, tvb, offset, hlen);
+               break;
+       case NORM_DATA:
+               dissect_norm_data(norm_tree, pinfo, tvb, offset, hlen);
+               break;
+       case NORM_CMD:
+               dissect_norm_cmd(norm_tree, pinfo, tvb, offset, hlen);
+               break;
+       case NORM_ACK:
+               dissect_norm_ack(norm_tree, pinfo, tvb, offset, hlen);
+               break;
+       case NORM_NACK:
+               dissect_norm_nack(norm_tree, pinfo, tvb, offset, hlen);
+               break;
+       default:
+               /* Add the Payload item */
+               if (tvb_reported_length_remaining(tvb, offset) > 0)
+                       proto_tree_add_item(norm_tree, hf_payload, tvb, offset, -1, ENC_NA);
+               break;
        }
+
+       return tvb_reported_length(tvb);
 }
 
 static gboolean
-dissect_norm_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+dissect_norm_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
 {
        guint8 byte1;
        if (!global_norm_heur)
                return FALSE;
-       if (tvb_length(tvb) < 2)
+       if (tvb_reported_length(tvb) < 12)
                return FALSE;   /* not enough to check */
        byte1 = tvb_get_guint8(tvb, 0);
 
        if (hi_nibble(byte1) != 1) return FALSE;
        if (lo_nibble(byte1) < 1 || lo_nibble(byte1) > 6) return FALSE;
        if (tvb_get_guint8(tvb, 1) > 20) return FALSE;
-       if (tvb_length(tvb) < 12)
-               return FALSE;
-       dissect_norm(tvb, pinfo, tree);
+
+       dissect_norm(tvb, pinfo, tree, data);
        return TRUE; /* appears to be a NORM packet */
 }
 
@@ -662,170 +678,172 @@ void proto_reg_handoff_norm(void)
 {
        static gboolean preferences_initialized = FALSE;
        static dissector_handle_t handle;
-        static struct _norm_prefs preferences_old;
 
        if (!preferences_initialized)
        {
                preferences_initialized = TRUE;
-               handle = create_dissector_handle(dissect_norm, proto);
+               handle = new_create_dissector_handle(dissect_norm, proto_rmt_norm);
                dissector_add_handle("udp.port", handle);
-               heur_dissector_add("udp", dissect_norm_heur, proto);
-       }
+               heur_dissector_add("udp", dissect_norm_heur, proto_rmt_norm);
 
-       norm_prefs_save(&preferences, &preferences_old);
+               rmt_fec_handle = find_dissector("rmt-fec");
+       }
 }
 
 void proto_register_norm(void)
 {
        /* Setup NORM header fields */
-       static hf_register_info hf_ptr[] = {
+       static hf_register_info hf[] = {
 
-               { &hf.version,
+               { &hf_version,
                        { "Version", "norm.version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
-               { &hf.type,
+               { &hf_type,
                        { "Message Type", "norm.type", FT_UINT8, BASE_DEC, VALS(string_norm_type), 0x0, NULL, HFILL }},
-               { &hf.hlen,
+               { &hf_hlen,
                        { "Header length", "norm.hlen", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
-               { &hf.sequence,
+               { &hf_sequence,
                        { "Sequence", "norm.sequence", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
-               { &hf.source_id,
+               { &hf_source_id,
                        { "Source ID", "norm.source_id", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
-               { &hf.instance_id,
+               { &hf_instance_id,
                        { "Instance", "norm.instance_id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
-               { &hf.grtt,
+               { &hf_grtt,
                        { "grtt", "norm.grtt", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
-               { &hf.backoff,
+               { &hf_backoff,
                        { "Backoff", "norm.backoff", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
-               { &hf.gsize,
+               { &hf_gsize,
                        { "Group Size", "norm.gsize", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
-               { &hf.flags,
+               { &hf_flags,
                        { "Flags", "norm.flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
-               { &hf.flag.repair,
+               { &hf_flag_repair,
                        { "Repair Flag", "norm.flag.repair", FT_BOOLEAN, 8, NULL, NORM_FLAG_REPAIR, NULL, HFILL }},
-               { &hf.flag.norm_explicit,
+               { &hf_flag_norm_explicit,
                        { "Explicit Flag", "norm.flag.explicit", FT_BOOLEAN, 8, NULL, NORM_FLAG_EXPLICIT, NULL, HFILL }},
-               { &hf.flag.info,
+               { &hf_flag_info,
                        { "Info Flag", "norm.flag.info", FT_BOOLEAN, 8, NULL, NORM_FLAG_INFO, NULL, HFILL }},
-               { &hf.flag.unreliable,
+               { &hf_flag_unreliable,
                        { "Unreliable Flag", "norm.flag.unreliable", FT_BOOLEAN, 8, NULL, NORM_FLAG_UNRELIABLE, NULL, HFILL }},
-               { &hf.flag.file,
+               { &hf_flag_file,
                        { "File Flag", "norm.flag.file", FT_BOOLEAN, 8, NULL, NORM_FLAG_FILE, NULL, HFILL }},
-               { &hf.flag.stream,
+               { &hf_flag_stream,
                        { "Stream Flag", "norm.flag.stream", FT_BOOLEAN, 8, NULL, NORM_FLAG_STREAM, NULL, HFILL }},
-               { &hf.flag.msgstart,
+               { &hf_flag_msgstart,
                        { "Msg Start Flag", "norm.flag.msgstart", FT_BOOLEAN, 8, NULL, NORM_FLAG_MSG_START, NULL, HFILL }},
-               { &hf.object_transport_id,
+               { &hf_object_transport_id,
                        { "Object Transport ID", "norm.object_transport_id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
-               { &hf.extension,
+               { &hf_extension,
                        { "Hdr Extension", "norm.hexext", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
-               { &hf.reserved,
-                       { "Reserved", "norm.reserved", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
-               { &hf.payload_len,
+               { &hf_reserved,
+                       { "Reserved", "norm.reserved", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
+               { &hf_payload_len,
                        { "Payload Len", "norm.payload.len", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
-               { &hf.payload_offset,
+               { &hf_payload_offset,
                        { "Payload Offset", "norm.payload.offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
 
-               { &hf.cmd_flavor,
+               { &hf_cmd_flavor,
                        { "Flavor", "norm.flavor", FT_UINT8, BASE_DEC, VALS(string_norm_cmd_type), 0x0, NULL, HFILL}},
-               { &hf.cc_sequence,
+               { &hf_cc_sequence,
                        { "CC Sequence", "norm.ccsequence", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
-               { &hf.cc_sts,
+               { &hf_cc_sts,
                        { "Send Time secs", "norm.cc_sts", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
-               { &hf.cc_stus,
+               { &hf_cc_stus,
                        { "Send Time usecs", "norm.cc_stus", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
-               { &hf.cc_node_id,
+               { &hf_cc_node_id,
                        { "CC Node ID", "norm.cc_node_id", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL}},
-               { &hf.cc_flags,
+               { &hf_cc_flags,
                        { "CC Flags", "norm.cc_flags", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
-               { &hf.cc_flags_clr,
+               { &hf_cc_flags_clr,
                        { "CLR", "norm.cc_flags.clr", FT_BOOLEAN, 8, NULL, NORM_FLAG_CC_CLR, NULL, HFILL}},
-               { &hf.cc_flags_plr,
+               { &hf_cc_flags_plr,
                        { "PLR", "norm.cc_flags.plr", FT_BOOLEAN, 8, NULL, NORM_FLAG_CC_PLR, NULL, HFILL}},
-               { &hf.cc_flags_rtt,
+               { &hf_cc_flags_rtt,
                        { "RTT", "norm.cc_flags.rtt", FT_BOOLEAN, 8, NULL, NORM_FLAG_CC_RTT, NULL, HFILL}},
-               { &hf.cc_flags_start,
+               { &hf_cc_flags_start,
                        { "Start", "norm.cc_flags.start", FT_BOOLEAN, 8, NULL, NORM_FLAG_CC_START, NULL, HFILL}},
-               { &hf.cc_flags_leave,
+               { &hf_cc_flags_leave,
                        { "Leave", "norm.cc_flags.leave", FT_BOOLEAN, 8, NULL, NORM_FLAG_CC_LEAVE, NULL, HFILL}},
-               { &hf.cc_rtt,
+               { &hf_cc_rtt,
                        { "CC RTT", "norm.cc_rtt", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
-               { &hf.cc_rate,
+               { &hf_cc_rate,
                        { "CC Rate", "norm.cc_rate", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
-               { &hf.cc_transport_id,
+               { &hf_cc_transport_id,
                        { "CC Transport ID", "norm.cc_transport_id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
 
-               { &hf.ack_source,
+               { &hf_ack_source,
                        { "Ack Source", "norm.ack.source", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL}},
-               { &hf.ack_type,
+               { &hf_ack_type,
                        { "Ack Type", "norm.ack.type", FT_UINT8, BASE_DEC, VALS(string_norm_ack_type), 0x0, NULL, HFILL}},
-               { &hf.ack_id,
+               { &hf_ack_id,
                        { "Ack ID", "norm.ack.id", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
-               { &hf.ack_grtt_sec,
+               { &hf_ack_grtt_sec,
                        { "Ack GRTT Sec", "norm.ack.grtt_sec", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
-               { &hf.ack_grtt_usec,
+               { &hf_ack_grtt_usec,
                        { "Ack GRTT usec", "norm.ack.grtt_usec", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
 
-               { &hf.nack_server,
+               { &hf_nack_server,
                        { "NAck Server", "norm.nack.server", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL}},
-               { &hf.nack_grtt_sec,
+               { &hf_nack_grtt_sec,
                        { "NAck GRTT Sec", "norm.nack.grtt_sec", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
-               { &hf.nack_grtt_usec,
+               { &hf_nack_grtt_usec,
                        { "NAck GRTT usec", "norm.nack.grtt_usec", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
-               { &hf.nack_form,
+               { &hf_nack_form,
                        { "NAck FORM", "norm.nack.form", FT_UINT8, BASE_DEC, VALS(string_norm_nack_form), 0x0, NULL, HFILL}},
-               { &hf.nack_flags,
+               { &hf_nack_flags,
                        { "NAck Flags", "norm.nack.flags", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
-               { &hf.nack_flags_segment,
+               { &hf_nack_flags_segment,
                        { "Segment", "norm.nack.flags.segment", FT_BOOLEAN, 8, NULL, NORM_NACK_SEGMENT, NULL, HFILL}},
-               { &hf.nack_flags_block,
+               { &hf_nack_flags_block,
                        { "Block", "norm.nack.flags.block", FT_BOOLEAN, 8, NULL, NORM_NACK_BLOCK, NULL, HFILL}},
-               { &hf.nack_flags_info,
+               { &hf_nack_flags_info,
                        { "Info", "norm.nack.flags.info", FT_BOOLEAN, 8, NULL, NORM_NACK_INFO, NULL, HFILL}},
-               { &hf.nack_flags_object,
+               { &hf_nack_flags_object,
                        { "Object", "norm.nack.flags.object", FT_BOOLEAN, 8, NULL, NORM_NACK_OBJECT, NULL, HFILL}},
-               { &hf.nack_length,
+               { &hf_nack_length,
                        { "NAck Length", "norm.nack.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
-
-
-               FEC_FIELD_ARRAY(hf.fec, "NORM"),
-
-               { &hf.payload,
-                       { "Payload", "norm.payload", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}
+               { &hf_payload,
+                       { "Payload", "norm.payload", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_fec_encoding_id,
+                       { "FEC Encoding ID", "norm.fec_encoding_id", FT_UINT8, BASE_DEC, VALS(string_fec_encoding_id), 0x0, NULL, HFILL}},
        };
 
        /* Setup protocol subtree array */
-       static gint *ett_ptr[] = {
-               &ett.main,
-               &ett.hdrext,
-               &ett.flags,
-               &ett.streampayload,
-               &ett.congestioncontrol,
-               &ett.nackdata,
-               FEC_SUBTREE_ARRAY(ett.fec)
+       static gint *ett[] = {
+               &ett_main,
+               &ett_hdrext,
+               &ett_flags,
+               &ett_streampayload,
+               &ett_congestioncontrol,
+               &ett_nackdata,
        };
 
        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");
+       proto_rmt_norm = 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));
+       proto_register_field_array(proto_rmt_norm, hf, array_length(hf));
+       proto_register_subtree_array(ett, array_length(ett));
 
-       /* Reset preferences */
-       norm_prefs_set_default(&preferences);
 
        /* Register preferences */
-       module = prefs_register_protocol(proto, proto_reg_handoff_norm);
-       norm_prefs_register(&preferences, module);
+       module = prefs_register_protocol(proto_rmt_norm, proto_reg_handoff_norm);
        prefs_register_bool_preference(module, "heuristic_norm",
-                       "Try to decode UDP packets as NORM packets",
-                       "Check this to decode NORM traffic between clients",
-                       &global_norm_heur);
+                                       "Try to decode UDP packets as NORM packets",
+                                       "Check this to decode NORM traffic between clients",
+                                       &global_norm_heur);
 
 }
+
+/*
+* Editor modelines - http://www.wireshark.org/tools/modelines.html
+*
+* Local variables:
+* c-basic-offset: 4
+* tab-width: 8
+* indent-tabs-mode: nil
+* End:
+*
+* ex: set shiftwidth=4 tabstop=8 expandtab:
+* :indentSize=4:tabSize=8:noTabs=true:
+*/
diff --git a/epan/dissectors/packet-rmt-norm.h b/epan/dissectors/packet-rmt-norm.h
deleted file mode 100644 (file)
index 8726edb..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/* packet-rmt-norm.h
- * Reliable Multicast Transport (RMT)
- * NORM Protocol Instantiation function definitions
- * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
- *
- * $Id$
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * Copyright 1998 Gerald Combs
- *
- * Extensive changes to decode more information Julian Onions
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef __PACKET_RMT_NORM__
-#define __PACKET_RMT_NORM__
-
-#include "packet-rmt-common.h"
-#include "packet-rmt-fec.h"
-#include "packet-rmt-lct.h"
-
-/* Type definitions */
-/* ================ */
-
-/* Logical NORM packet representation */
-struct _norm
-{
-       guint8 version;
-       guint8 type;
-       guint8 hlen;
-       guint16 sequence;
-       guint32 source_id;
-
-       struct _fec fec;
-};
-
-enum {
-       NORM_INFO = 1,
-       NORM_DATA = 2,
-       NORM_CMD = 3,
-       NORM_NACK = 4,
-       NORM_ACK = 5,
-       NORM_REPORT = 6,
-
-       NORM_CMD_FLUSH = 1,
-       NORM_CMD_EOT = 2,
-       NORM_CMD_SQUELCH = 3,
-       NORM_CMD_CC = 4,
-       NORM_CMD_REPAIR_ADV = 5,
-       NORM_CMD_ACK_REQ = 6,
-       NORM_CMD_APPLICATION = 7,
-
-
-       NORM_FLAG_REPAIR = 0x01,
-       NORM_FLAG_EXPLICIT = 0x02,
-       NORM_FLAG_INFO = 0x04,
-       NORM_FLAG_UNRELIABLE = 0x08,
-       NORM_FLAG_FILE = 0x10,
-       NORM_FLAG_STREAM = 0x20,
-       NORM_FLAG_MSG_START = 0x40,
-
-       NORM_ACK_CC = 1,
-       NORM_ACK_FLUSH = 2,
-
-       NORM_NACK_ITEMS = 1,
-       NORM_NACK_RANGES = 2,
-       NORM_NACK_ERASURES = 3,
-
-       NORM_NACK_SEGMENT = 0x01,
-       NORM_NACK_BLOCK = 0x02,
-       NORM_NACK_INFO = 0x04,
-       NORM_NACK_OBJECT = 0x08,
-
-
-       NORM_FLAG_CC_CLR = 0x01,
-       NORM_FLAG_CC_PLR = 0x02,
-       NORM_FLAG_CC_RTT = 0x04,
-       NORM_FLAG_CC_START = 0x08,
-       NORM_FLAG_CC_LEAVE = 0x10
-
-};
-
-
-/* Wireshark stuff */
-/* ============== */
-
-/* NORM header field definitions*/
-struct _norm_hf
-{
-       int version;
-       int type;
-       int hlen;
-       int sequence;
-       int source_id;
-       int instance_id;
-       int grtt;
-       int backoff;
-       int gsize;
-       int flags;
-       int cmd_flavor;
-       int reserved;
-       int cc_sequence;
-       int cc_sts;
-       int cc_stus;
-       int cc_node_id;
-       int cc_flags;
-       int cc_flags_clr;
-       int cc_flags_plr;
-       int cc_flags_rtt;
-       int cc_flags_start;
-       int cc_flags_leave;
-       int cc_rtt;
-       int cc_rate;
-       int cc_transport_id;
-       int ack_source;
-       int ack_type;
-       int ack_id;
-       int ack_grtt_sec;
-       int ack_grtt_usec;
-       int nack_server;
-       int nack_grtt_sec;
-       int nack_grtt_usec;
-       int nack_form;
-       int nack_length;
-       int nack_flags;
-       int nack_flags_segment;
-       int nack_flags_block;
-       int nack_flags_info;
-       int nack_flags_object;
-       struct flaglist {
-               int repair;
-               int norm_explicit;
-               int info;
-               int unreliable;
-               int file;
-               int stream;
-               int msgstart;
-       } flag;
-       int object_transport_id;
-       int extension;
-       int payload_len;
-       int payload_offset;
-       struct _fec_hf fec;
-
-       int payload;
-};
-
-/* NORM subtrees */
-struct _norm_ett
-{
-       gint main;
-       gint hdrext;
-       gint flags;
-       gint streampayload;
-       gint congestioncontrol;
-       gint nackdata;
-       struct _fec_ett fec;
-};
-
-/* NORM preferences */
-struct _norm_prefs
-{
-       struct _fec_prefs fec;
-};
-
-/* Function declarations */
-/* ===================== */
-
-#endif