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
packet-rmi.c \
packet-rmp.c \
packet-rmt-alc.c \
- packet-rmt-common.c \
packet-rmt-fec.c \
packet-rmt-lct.c \
packet-rmt-norm.c \
packet-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 \
#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");
/* 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)
/* 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:
+*/
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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);
- }
-}
#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
#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[] =
{ 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:
* 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:
+*/
+++ /dev/null
-/* 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
#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 */
/* ==================== */
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 */
/* ---------- */
* 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:
+*/
+++ /dev/null
-/* 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
#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" },
{ 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" },
{ 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" },
{ 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" },
{ 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;
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;
/* 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);
/* 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 */
}
{
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:
+*/
+++ /dev/null
-/* 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