Overhauled the RMT dissectors. Not sure each needs its own file, but since this involves multiple RFCs, they remain split out by that. More are now a "pure" dissector and not a "decoding function hook".

Some Notes:
1. Converted to "new style" dissectors with data being passed between dissectors
2. Combined header files into one since there wasn't much that should have really been in the header files.  Implemented functionality is in c module of respective dissector.

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

svn path=/trunk/; revision=49555
This commit is contained in:
Michael Mann 2013-05-24 17:06:23 +00:00
parent 7dddfb1784
commit d12fc51afd
12 changed files with 1203 additions and 1886 deletions

View File

@ -1063,7 +1063,6 @@ set(DISSECTOR_SRC
dissectors/packet-rmi.c
dissectors/packet-rmp.c
dissectors/packet-rmt-alc.c
dissectors/packet-rmt-common.c
dissectors/packet-rmt-fec.c
dissectors/packet-rmt-lct.c
dissectors/packet-rmt-norm.c

View File

@ -985,7 +985,6 @@ DISSECTOR_SRC = \
packet-rmi.c \
packet-rmp.c \
packet-rmt-alc.c \
packet-rmt-common.c \
packet-rmt-fec.c \
packet-rmt-lct.c \
packet-rmt-norm.c \
@ -1487,11 +1486,7 @@ DISSECTOR_INCLUDES = \
packet-rlc.h \
packet-rlc-lte.h \
packet-rmi.h \
packet-rmt-alc.h \
packet-rmt-common.h \
packet-rmt-fec.h \
packet-rmt-lct.h \
packet-rmt-norm.h \
packet-rohc.h \
packet-ros.h \
packet-rpc.h \

View File

@ -40,90 +40,51 @@
#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 int proto_rmt_alc = -1;
static struct _alc_hf hf;
static struct _alc_ett ett;
static int hf_version = -1;
static int hf_payload = -1;
static int ett_main = -1;
static struct _alc_prefs preferences;
static dissector_handle_t xml_handle;
static dissector_handle_t rmt_lct_handle;
static dissector_handle_t rmt_fec_handle;
/* Preferences */
/* =========== */
/* 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);
}
/* Save preferences to alc_prefs_old */
static void alc_prefs_save(struct _alc_prefs *p, struct _alc_prefs *p_old)
{
*p_old = *p;
}
static guint g_default_udp_port = 0; /* 4001 */
static gboolean g_codepoint_as_fec_encoding = TRUE;
static gint g_ext_192 = LCT_PREFS_EXT_192_FLUTE;
static gint g_ext_193 = LCT_PREFS_EXT_193_FLUTE;
/* Code to actually dissect the packets */
/* ==================================== */
static void dissect_alc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static int
dissect_alc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
/* Logical packet representation */
struct _alc alc;
guint8 version;
lct_data_exchange_t lct;
fec_data_exchange_t fec;
int len;
/* Offset for subpacket dissection */
guint offset;
guint offset = 0;
/* Set up structures needed to add the protocol subtree and manage it */
proto_item *ti;
proto_tree *alc_tree;
/* Flute or not */
tvbuff_t *new_tvb;
gboolean is_flute = FALSE;
/* Structures and variables initialization */
offset = 0;
memset(&alc, 0, sizeof(struct _alc));
/* Update packet info */
pinfo->current_proto = "ALC";
/* Make entries in Protocol column and Info column on summary display */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ALC");
@ -132,110 +93,96 @@ static void dissect_alc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* ALC header dissection */
/* --------------------- */
alc.version = hi_nibble(tvb_get_guint8(tvb, offset));
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);
/* 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);
/* Fill the ALC subtree */
proto_tree_add_uint(alc_tree, hf.version, tvb, offset, 1, alc.version);
} 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 */
/* ------------------------------------------------ */
if (check_col(pinfo->cinfo, COL_INFO))
{
lct_info_column(&alc.lct, pinfo);
fec_info_column(&alc.fec, pinfo);
}
/* Free g_allocated memory */
lct_dissector_free(&alc.lct);
fec_dissector_free(&alc.fec);
} else {
if (tree)
proto_tree_add_text(alc_tree, tvb, 0, -1, "Sorry, this dissector supports ALC version 1 only");
/* Complete entry in Info column on summary display */
if (check_col(pinfo->cinfo, COL_INFO))
col_add_fstr(pinfo->cinfo, COL_INFO, "Version: %u (not supported)", alc.version);
col_add_fstr(pinfo->cinfo, COL_INFO, "Version: %u (not supported)", version);
return 0;
}
/* 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;
offset += len;
/* FEC header dissection */
/* --------------------- */
/* 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;
new_tvb = tvb_new_subset_remaining(tvb,offset);
len = call_dissector_with_data(rmt_fec_handle, new_tvb, pinfo, alc_tree, &fec);
if (len < 0)
return offset;
offset += len;
}
/* Add the Payload item */
if (tvb_reported_length(tvb) > offset){
if(lct.is_flute){
new_tvb = tvb_new_subset_remaining(tvb,offset);
call_dissector(xml_handle, new_tvb, pinfo, alc_tree);
}else{
proto_tree_add_item(alc_tree, hf_payload, tvb, offset, -1, ENC_NA);
}
}
return tvb_reported_length(tvb);
}
void proto_reg_handoff_alc(void)
{
static dissector_handle_t handle;
static gboolean preferences_initialized = FALSE;
static struct _alc_prefs preferences_old;
static guint old_udp_port = 0;
if (!preferences_initialized)
{
preferences_initialized = TRUE;
handle = create_dissector_handle(dissect_alc, proto);
handle = new_create_dissector_handle(dissect_alc, proto_rmt_alc);
dissector_add_handle("udp.port", handle);
xml_handle = find_dissector("xml");
rmt_lct_handle = find_dissector("rmt-lct");
rmt_fec_handle = find_dissector("rmt-fec");
}
} else {
if (preferences_old.use_default_udp_port)
dissector_delete_uint("udp.port", preferences_old.default_udp_port, handle);
/* Register UDP port for dissection */
if(old_udp_port != 0 && old_udp_port != g_default_udp_port){
dissector_delete_uint("udp.port", old_udp_port, handle);
}
if (preferences.use_default_udp_port)
dissector_add_uint("udp.port", preferences.default_udp_port, handle);
alc_prefs_save(&preferences, &preferences_old);
if(g_default_udp_port != 0 && old_udp_port != g_default_udp_port) {
dissector_add_uint("udp.port", g_default_udp_port, handle);
}
old_udp_port = g_default_udp_port;
}
void proto_register_alc(void)
@ -243,43 +190,71 @@ void proto_register_alc(void)
/* Setup ALC header fields */
static hf_register_info hf_ptr[] = {
{ &hf.version,
{ &hf_version,
{ "Version", "alc.version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
LCT_FIELD_ARRAY(hf.lct, "alc"),
FEC_FIELD_ARRAY(hf.fec, "alc"),
{ &hf.payload,
{ "Payload", "alc.payload", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}
{ &hf_payload,
{ "Payload", "alc.payload", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}
};
/* Setup protocol subtree array */
static gint *ett_ptr[] = {
&ett.main,
LCT_SUBTREE_ARRAY(ett.lct),
FEC_SUBTREE_ARRAY(ett.fec)
&ett_main,
};
module_t *module;
/* Clear hf and ett fields */
memset(&hf, 0xff, sizeof(struct _alc_hf));
memset(&ett, 0xff, sizeof(struct _alc_ett));
/* Register the protocol name and description */
proto = proto_register_protocol("Asynchronous Layered Coding", "ALC", "alc");
proto_rmt_alc = proto_register_protocol("Asynchronous Layered Coding", "ALC", "alc");
new_register_dissector("alc", dissect_alc, proto_rmt_alc);
/* Register the header fields and subtrees used */
proto_register_field_array(proto, hf_ptr, array_length(hf_ptr));
proto_register_field_array(proto_rmt_alc, hf_ptr, array_length(hf_ptr));
proto_register_subtree_array(ett_ptr, array_length(ett_ptr));
/* Reset preferences */
alc_prefs_set_default(&preferences);
/* Register preferences */
module = prefs_register_protocol(proto, proto_reg_handoff_alc);
alc_prefs_register(&preferences, module);
module = prefs_register_protocol(proto_rmt_alc, proto_reg_handoff_alc);
register_dissector("alc", dissect_alc, proto);
prefs_register_obsolete_preference(module, "default.udp_port.enabled");
prefs_register_uint_preference(module,
"default.udp_port",
"UDP destination port",
"Specifies the UDP destination port for automatic dissection of ALC packets",
10, &g_default_udp_port);
prefs_register_bool_preference(module,
"lct.codepoint_as_fec_id",
"LCT Codepoint as FEC Encoding ID",
"Whether the LCT header Codepoint field should be considered the FEC Encoding ID of carried object",
&g_codepoint_as_fec_encoding);
prefs_register_enum_preference(module,
"lct.ext.192",
"LCT header extension 192",
"How to decode LCT header extension 192",
&g_ext_192,
enum_lct_ext_192,
FALSE);
prefs_register_enum_preference(module,
"lct.ext.193",
"LCT header extension 193",
"How to decode LCT header extension 193",
&g_ext_193,
enum_lct_ext_193,
FALSE);
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/

View File

@ -1,81 +0,0 @@
/* packet-rmt-alc.h
* Reliable Multicast Transport (RMT)
* ALC Protocol Instantiation function definitions
* Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __PACKET_RMT_ALC__
#define __PACKET_RMT_ALC__
#include "packet-rmt-common.h"
#include "packet-rmt-lct.h"
#include "packet-rmt-fec.h"
/* Type definitions */
/* ================ */
/* Logical ALC packet representation */
struct _alc
{
guint8 version;
struct _lct lct;
struct _fec fec;
};
/* Wireshark stuff */
/* ============== */
/* ALC header field definitions*/
struct _alc_hf
{
int version;
struct _lct_hf lct;
struct _fec_hf fec;
int payload;
};
/* ALC subtrees */
struct _alc_ett
{
gint main;
struct _lct_ett lct;
struct _fec_ett fec;
};
/* ALC preferences */
struct _alc_prefs
{
gboolean use_default_udp_port;
guint default_udp_port;
struct _lct_prefs lct;
struct _fec_prefs fec;
};
/* Function declarations */
/* ===================== */
#endif

View File

@ -1,114 +0,0 @@
/* packet-rmt-common.c
* Reliable Multicast Transport (RMT)
* Common RMT functions
* Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <string.h>
#include <glib.h>
#include <epan/packet.h>
#include <epan/strutil.h>
#include "packet-rmt-common.h"
/* Common RMT exported functions */
/* ============================= */
/* Scan the tvb and put extensions found in an array */
void rmt_ext_parse(GArray *a, tvbuff_t *tvb, guint *offset, guint offset_max)
{
struct _ext e;
while (*offset < offset_max)
{
/* Clear the temporary extension */
memset(&e, 0, sizeof(struct _ext));
/* Dissect the extension */
e.offset = *offset;
e.het = tvb_get_guint8(tvb, *offset);
if (e.het <= 127) {
/* If HET <= 127, we have a variable-size extension */
e.hel = tvb_get_guint8(tvb, *offset+1);
e.hec_offset = *offset + 2;
e.hec_size = e.hel * 4 - 2;
e.length = e.hel * 4;
} else {
/* If HET > 127, we have a short 32-bit extension */
e.hel = 1; /* even if HEL field is not defined for HET > 127 */
e.hec_offset = *offset + 1;
e.hec_size = 3;
e.length = 4;
}
/* Prevents infinite loops */
if (e.length == 0)
break;
g_array_append_val(a, e);
*offset += e.length;
}
}
/* Add default items to a subtree */
void rmt_ext_decode_default_header(struct _ext *e, tvbuff_t *tvb, proto_tree *tree)
{
if (tree)
{
proto_tree_add_text(tree, tvb, e->offset, 1, "Header Extension Type (HET): %u", e->het);
if (e->het <= 127)
proto_tree_add_text(tree, tvb, e->offset+1, 1, "Header Extension Length (HEL): %u", e->hel);
}
}
/* Add a default subtree to a tree item */
void rmt_ext_decode_default_subtree(struct _ext *e, tvbuff_t *tvb, proto_item *ti, gint ett)
{
proto_tree *ext_tree;
ext_tree = proto_item_add_subtree(ti, ett);
rmt_ext_decode_default_header(e, tvb, ext_tree);
if (ext_tree)
proto_tree_add_text(ext_tree, tvb, e->hec_offset, e->hec_size,
"Header Extension Content (HEC): %s", tvb_bytes_to_str(tvb, e->hec_offset, e->hec_size));
}
/* Add a default subtree for unknown extensions */
void rmt_ext_decode_default(struct _ext *e, tvbuff_t *tvb, proto_tree *tree, gint ett)
{
proto_item *ti;
if (tree)
{
ti = proto_tree_add_text(tree, tvb, e->offset, e->length,
"Unknown extension (%u)", e->het);
rmt_ext_decode_default_subtree(e, tvb, ti, ett);
}
}

View File

@ -27,29 +27,50 @@
#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
{
guint offset;
guint length;
/* inputs */
gint ext_192;
gint ext_193;
guint8 het;
guint8 hel;
/* outputs */
guint8 codepoint;
gboolean is_flute;
} lct_data_exchange_t;
typedef struct fec_data_exchange
{
/* inputs */
guint8 encoding_id;
} 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

View File

@ -44,8 +44,35 @@
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/expert.h>
#include "packet-rmt-common.h"
static int proto_rmt_fec = -1;
static int hf_encoding_id = -1;
static int hf_instance_id = -1;
static int hf_sbn = -1;
static int hf_sbn_with_mask = -1;
static int hf_sbl = -1;
static int hf_esi = -1;
static int hf_esi_with_mask = -1;
static int hf_fti_transfer_length = -1;
static int hf_fti_encoding_symbol_length = -1;
static int hf_fti_max_source_block_length = -1;
static int hf_fti_max_number_encoding_symbols = -1;
static int hf_fti_num_blocks = -1;
static int hf_fti_num_subblocks = -1;
static int hf_fti_alignment = -1;
static int ett_main = -1;
typedef struct fec_packet_data
{
guint8 instance_id;
} fec_packet_data_t;
#include "packet-rmt-fec.h"
/* String tables */
const value_string string_fec_encoding_id[] =
@ -65,145 +92,85 @@ const value_string string_fec_encoding_id[] =
{ 0, NULL }
};
/* FEC exported functions */
/* ====================== */
/* Info */
/* ---- */
void fec_info_column(struct _fec *fec, packet_info *pinfo)
{
if (fec->sbn_present)
col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", fec->sbn);
if (fec->esi_present)
col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", fec->esi);
}
/* Dissection */
/* ---------- */
/* Decode an EXT_FTI extension and fill FEC array */
void fec_decode_ext_fti(struct _ext *e, tvbuff_t *tvb, proto_tree *tree, gint ett, struct _fec_ptr f)
void fec_decode_ext_fti(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int length, guint8 encoding_id)
{
proto_item* ti = NULL, *item = NULL;
proto_tree *ext_tree;
guint64 transfer_length;
fec_packet_data_t* fec_data;
guint8 instance_id = 0;
proto_item* ti;
if (tree)
ti = proto_tree_add_none_format(tree, f.hf->fti_header, tvb, e->offset, e->length,
"EXT_FTI, FEC Object Transmission Information (%u)", e->het);
if (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;
p_add_proto_data(pinfo->fd, proto_rmt_fec, 0, fec_data);
}
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");
}
}
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);
}
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;
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]");
}
}
}
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;
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);
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;
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 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 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;
}
} else
if (tree)
rmt_ext_decode_default_subtree(e, tvb, ti, ett);
case 132:
proto_tree_add_item(tree, hf_fti_encoding_symbol_length, tvb, offset+10, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(tree, hf_fti_max_source_block_length, tvb, offset+12, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(tree, hf_fti_max_number_encoding_symbols, tvb, offset+16, 4, ENC_BIG_ENDIAN);
break;
}
}
/* Dissect a FEC header:
@ -216,142 +183,148 @@ void fec_decode_ext_fti(struct _ext *e, tvbuff_t *tvb, proto_tree *tree, gint et
* tree - tree where to add FEC header subtree
* offset - ptr to offset to use and update
*/
void fec_dissector(struct _fec_ptr f, tvbuff_t *tvb, proto_tree *tree, guint *offset)
static int
dissect_fec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
proto_item *ti;
proto_tree *fec_tree;
guint offset_save = *offset;
guint offset = 0;
fec_data_exchange_t* fec = (fec_data_exchange_t*)data;
guint8 encoding_id = 0;
fec_packet_data_t* packet_data = (fec_packet_data_t*)p_get_proto_data(pinfo->fd, proto_rmt_fec, 0);
if (fec != NULL)
{
encoding_id = fec->encoding_id;
}
/* Create the FEC subtree */
if (tree)
ti = proto_tree_add_item(tree, proto_rmt_fec, tvb, offset, -1, ENC_NA);
fec_tree = proto_item_add_subtree(ti, ett_main);
proto_tree_add_uint(fec_tree, hf_encoding_id, tvb, offset, 0, encoding_id);
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)
{
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
{
ti = NULL;
fec_tree = NULL;
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);
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);
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);
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));
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;
}
/* FEC Encoding ID and FEC Instance ID processing */
if (f.fec->encoding_id_present)
{
if (tree)
{
proto_tree_add_uint(fec_tree, f.hf->encoding_id, tvb, *offset, 0, f.fec->encoding_id);
if (f.fec->encoding_id >= 128 && f.fec->instance_id_present)
proto_tree_add_uint(fec_tree, f.hf->instance_id, tvb, *offset, 0, f.fec->instance_id);
}
switch (f.fec->encoding_id)
{
case 0:
case 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);
}
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);
return offset;
}
void fec_dissector_free(struct _fec *fec _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));
}
/* Preferences */
/* ----------- */
/* Set/Reset preferences to default values */
void fec_prefs_set_default(struct _fec_prefs *fec_prefs _U_)
{
}
/* Register preferences */
void fec_prefs_register(struct _fec_prefs *fec_prefs _U_, module_t *module _U_)
{
}
/*
* 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:
*/

View File

@ -1,150 +0,0 @@
/* packet-rmt-fec.h
* Reliable Multicast Transport (RMT)
* FEC Building Block function definitions
* Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __PACKET_RMT_FEC__
#define __PACKET_RMT_FEC__
#include "packet-rmt-common.h"
/* String tables external references */
extern const value_string string_fec_encoding_id[];
/* Type definitions */
/* ================ */
struct _fec
{
gboolean encoding_id_present;
gboolean instance_id_present;
guint8 encoding_id;
guint8 instance_id;
guint64 transfer_length;
guint32 encoding_symbol_length;
guint32 max_source_block_length;
guint32 max_number_encoding_symbols;
guint16 num_blocks;
guint16 num_subblocks;
guint8 alignment;
gboolean sbn_present;
gboolean sbl_present;
gboolean esi_present;
guint32 sbn;
guint32 sbl;
guint32 esi;
};
/* Wireshark stuff */
/* ============== */
/* FEC header field definitions */
struct _fec_hf
{
int header;
int encoding_id;
int instance_id;
int sbn;
int sbl;
int esi;
int fti_header;
int fti_transfer_length;
int fti_encoding_symbol_length;
int fti_max_source_block_length;
int fti_max_number_encoding_symbols;
int fti_num_blocks;
int fti_num_subblocks;
int fti_alignment;
};
/* FEC subtrees */
struct _fec_ett
{
gint main;
};
/* FEC preferences */
struct _fec_prefs
{
gboolean dummy;
};
/* FEC pointers */
struct _fec_ptr
{
struct _fec *fec;
struct _fec_hf *hf;
struct _fec_ett *ett;
struct _fec_prefs *prefs;
};
/* Macros to generate static arrays */
#define FEC_FIELD_ARRAY(base_structure, base_protocol) \
{ &base_structure.header, \
{ "Forward Error Correction (FEC) header", base_protocol ".fec", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.encoding_id, \
{ "FEC Encoding ID", base_protocol ".fec.encoding_id", FT_UINT8, BASE_DEC, VALS(string_fec_encoding_id), 0x0, NULL, HFILL }}, \
{ &base_structure.instance_id, \
{ "FEC Instance ID", base_protocol ".fec.instance_id", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.sbn, \
{ "Source Block Number", base_protocol ".fec.sbn", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.sbl, \
{ "Source Block Length", base_protocol ".fec.sbl", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.esi, \
{ "Encoding Symbol ID", base_protocol ".fec.esi", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.fti_header, \
{ "FEC Object Transmission Information", base_protocol ".fec.fti", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.fti_transfer_length, \
{ "Transfer Length", base_protocol ".fec.fti.transfer_length", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.fti_encoding_symbol_length, \
{ "Encoding Symbol Length", base_protocol ".fec.fti.encoding_symbol_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.fti_max_source_block_length, \
{ "Maximum Source Block Length", base_protocol ".fec.fti.max_source_block_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.fti_max_number_encoding_symbols, \
{ "Maximum Number of Encoding Symbols", base_protocol ".fec.fti.max_number_encoding_symbols", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.fti_num_blocks, \
{ "Number of Source Blocks", base_protocol ".fec.fti.num_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.fti_num_subblocks, \
{ "Number of Sub-Blocks", base_protocol ".fec.fti.num_subblocks", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.fti_alignment, \
{ "Symbol Alignment", base_protocol ".fec.fti.alignment", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}
#define FEC_SUBTREE_ARRAY(base_structure) \
&base_structure.main
/* FEC exported functions */
/* ====================== */
void fec_info_column(struct _fec *fec, packet_info *pinfo);
void fec_dissector(struct _fec_ptr f, tvbuff_t *tvb, proto_tree *tree, guint *offset);
void fec_dissector_free(struct _fec *fec);
void fec_decode_ext_fti(struct _ext *e, tvbuff_t *tvb, proto_tree *tree, gint ett, struct _fec_ptr f);
void fec_prefs_set_default(struct _fec_prefs *prefs);
void fec_prefs_register(struct _fec_prefs *prefs, module_t *module);
#endif

View File

@ -45,27 +45,85 @@
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/strutil.h>
#include <epan/garrayfix.h>
#include <math.h>
#include "packet-rmt-lct.h"
#include "packet-rmt-common.h"
#define LCT_SCT_FLAG 0x0008
#define LCT_ERT_FLAG 0x0004
#define LCT_CLOSE_SESSION_FLAG 0x0002
#define LCT_CLOSE_OBJECT_FLAG 0x0001
static int proto_rmt_lct = -1;
static int hf_version = -1;
static int hf_fsize_header = -1;
static int hf_fsize_cci = -1;
static int hf_fsize_tsi = -1;
static int hf_fsize_toi = -1;
static int hf_flags_header = -1;
static int hf_flags_sct_present = -1;
static int hf_flags_ert_present = -1;
static int hf_flags_close_session = -1;
static int hf_flags_close_object = -1;
static int hf_hlen = -1;
static int hf_codepoint = -1;
static int hf_cci = -1;
static int hf_tsi = -1;
static int hf_tsi16 = -1;
static int hf_tsi32 = -1;
static int hf_tsi48 = -1;
static int hf_toi = -1;
static int hf_toi16 = -1;
static int hf_toi32 = -1;
static int hf_toi48 = -1;
static int hf_toi64 = -1;
static int hf_toi_extended = -1;
static int hf_sct = -1;
static int hf_ert = -1;
static int hf_ext = -1;
static int hf_hec_type = -1;
static int hf_hec_len = -1;
static int hf_hec_data = -1;
static int hf_send_rate = -1;
static int hf_cenc = -1;
static int hf_flute_version = -1;
static int hf_fdt_instance_id = -1;
static int ett_main = -1;
static int ett_fsize = -1;
static int ett_flags = -1;
static int ett_ext = -1;
static int ett_ext_ext = -1;
/* Enumerated data types for LCT preferences */
static const enum_val_t enum_lct_ext_192[] =
const enum_val_t enum_lct_ext_192[] =
{
{ "none", "Don't decode", LCT_PREFS_EXT_192_NONE },
{ "flute", "Decode as FLUTE extension (EXT_FDT)", LCT_PREFS_EXT_192_FLUTE },
{ NULL, NULL, 0 }
};
static const enum_val_t enum_lct_ext_193[] =
const enum_val_t enum_lct_ext_193[] =
{
{ "none", "Don't decode", LCT_PREFS_EXT_193_NONE },
{ "flute", "Decode as FLUTE extension (EXT_CENC)", LCT_PREFS_EXT_193_FLUTE },
{ NULL, NULL, 0 }
};
static const value_string hec_type_vals[] = {
{ 0, "EXT_NOP, No-Operation" },
{ 1, "EXT_AUTH, Packet authentication" },
{ 2, "EXT_CC, Congestion Control Feedback" },
{ 64, "EXT_FTI, FEC Object Transmission Information" },
{ 128, "EXT_RATE, Send Rate" },
{ 192, "EXT_FDT, FDT Instance Header" },
{ 193, "EXT_CENC, FDT Instance Content Encoding" },
{ 0, NULL }
};
/* LCT helper functions */
/* ==================== */
@ -75,169 +133,131 @@ static void lct_timestamp_parse(guint32 t, nstime_t* s)
s->nsecs = (t % 1000) * 1000000;
}
gboolean lct_ext_decode(struct _ext *e, struct _lct_prefs *lct_prefs, tvbuff_t *tvb, proto_tree *tree, gint ett, struct _fec_ptr f)
double rmt_decode_send_rate(guint16 send_rate )
{
guint32 buffer32;
proto_item *ti;
proto_tree *ext_tree;
gboolean is_flute = FALSE;
double value;
switch (e->het)
value = (send_rate >> 4) * 10.0 / 4096.0 * pow(10.0, (send_rate & 0xf));
return value;
}
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)
{
/* EXT_NOP */
case 0:
if (tree)
het = tvb_get_guint8(tvb, tmp_offset);
if (het <= 127)
{
ti = proto_tree_add_text(tree, tvb, e->offset, e->length,
"EXT_NOP, No-Operation (0)");
rmt_ext_decode_default_subtree(e, tvb, ti, ett);
length = tvb_get_guint8(tvb, tmp_offset+1)*4;
}
break;
/* EXT_AUTH */
case 1:
if (tree)
else
{
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);
length = 4;
}
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));
}
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);
}
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)");
ext_tree = proto_item_add_subtree(ti, ett);
buffer32 = tvb_get_ntohl(tvb, e->offset);
rmt_ext_decode_default_header(e, tvb, ext_tree);
proto_tree_add_text(ext_tree, tvb, e->offset+1, 1,
"FLUTE version (V): %u", (buffer32 & 0x00F00000) >> 20);
proto_tree_add_text(ext_tree, tvb, e->offset+1, 3,
"FDT Instance ID: %u", buffer32 & 0x000FFFFF);
}
is_flute = TRUE;
break;
}
break;
/* EXT_CENC */
case 193:
switch (lct_prefs->ext_193)
{
case LCT_PREFS_EXT_193_NONE:
rmt_ext_decode_default(e, tvb, tree, ett);
break;
case LCT_PREFS_EXT_193_FLUTE:
if (tree)
{
ti = proto_tree_add_text(tree, tvb, e->offset, e->length,
"EXT_CENC, FDT Instance Content Encoding (193)");
ext_tree = proto_item_add_subtree(ti, ett);
buffer32 = tvb_get_ntohl(tvb, e->offset);
rmt_ext_decode_default_header(e, tvb, ext_tree);
proto_tree_add_text(ext_tree, tvb, e->offset+1, 1,
"Content Encoding Algorithm (CENC): %u", (buffer32 & 0x00FF0000) >> 16);
}
break;
}
break;
default:
rmt_ext_decode_default(e, tvb, tree, ett);
tmp_offset += length;
count++;
}
return is_flute;
if (count == 0)
return 0;
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;
}
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);
if (het <= 127)
{
proto_tree_add_item(ext_tree, hf_hec_len, tvb, offset+1, 1, ENC_BIG_ENDIAN);
}
switch (het)
{
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 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;
case 64: /* EXT_FTI */
fec_decode_ext_fti(tvb, pinfo, ext_tree, offset, length,
(data_exchange == NULL) ? 0 : data_exchange->codepoint);
break;
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;
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;
}
offset += length;
}
return offset-start_offset;
}
/* LCT exported functions */
/* ====================== */
/* Info */
/* ---- */
void lct_info_column(struct _lct *lct, packet_info *pinfo)
{
if (lct->tsi_present)
col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "TSI: %" G_GINT64_MODIFIER "u", lct->tsi);
if (lct->toi_present)
{
if (lct->toi_size <= 8)
col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "TOI: %" G_GINT64_MODIFIER "u", lct->toi);
else
col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "TOI: 0x%s", bytes_to_str(lct->toi_extended, lct->toi_size));
}
if (lct->close_session)
col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Close session");
if (lct->close_object)
col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Close object");
}
/* Dissection */
/* ---------- */
@ -249,268 +269,297 @@ void lct_info_column(struct _lct *lct, packet_info *pinfo)
* tree - tree where to add LCT header subtree
* offset - ptr to offset to use and update
*/
gboolean lct_dissector(struct _lct_ptr l, struct _fec_ptr f, tvbuff_t *tvb, proto_tree *tree, guint *offset)
static int
dissect_lct(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
guint i;
guint offset_old;
guint offset_start;
int offset = 0;
guint16 buffer16;
gboolean is_flute_tmp =FALSE;
gboolean is_flute =FALSE;
guint8 *tmp;
lct_data_exchange_t *data_exchange = (lct_data_exchange_t*)data;
guint8 cci_size;
guint8 tsi_size;
guint8 toi_size;
guint64 tsi;
guint64 toi;
guint16 hlen;
nstime_t time;
/* Set up structures needed to add the protocol subtree and manage it */
proto_item *ti;
proto_tree *lct_tree;
proto_tree *lct_fsize_tree;
proto_tree *lct_flags_tree;
proto_tree *lct_ext_tree;
proto_tree *lct_tree = tree, *lct_fsize_tree, *lct_flags_tree;
/* LCT fixed-size fields dissection */
/* -------------------------------- */
buffer16 = tvb_get_ntohs(tvb, offset);
offset_start = *offset;
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;
buffer16 = tvb_get_ntohs(tvb, *offset);
hlen = tvb_get_guint8(tvb, offset+2) * 4;
l.lct->version = ((buffer16 & 0xF000) >> 12);
l.lct->cci_size = ((buffer16 & 0x0C00) >> 10) * 4 + 4;
l.lct->tsi_size = ((buffer16 & 0x0080) >> 7) * 4 + ((buffer16 & 0x0010) >> 4) * 2;
l.lct->toi_size = ((buffer16 & 0x0060) >> 5) * 4 + ((buffer16 & 0x0010) >> 4) * 2;
l.lct->tsi_present = (l.lct->tsi_size > 0);
l.lct->toi_present = (l.lct->toi_size > 0);
l.lct->sct_present = (buffer16 & 0x0008) != 0;
l.lct->ert_present = (buffer16 & 0x0004) != 0;
l.lct->close_session = (buffer16 & 0x0002) != 0;
l.lct->close_object = (buffer16 & 0x0001) != 0;
l.lct->hlen = tvb_get_guint8(tvb, *offset+2) * 4;
l.lct->codepoint = tvb_get_guint8(tvb, *offset+3);
if (l.prefs->codepoint_as_fec_encoding)
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);
proto_tree_add_item(lct_tree, hf_version, tvb, offset, 2, ENC_BIG_ENDIAN);
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);
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);
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);
} else {
lct_tree = NULL;
lct_fsize_tree = NULL;
lct_flags_tree = NULL;
}
*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);
proto_tree_add_item(lct_tree, l.hf->toi_extended, tvb, *offset, l.lct->toi_size, ENC_NA);
}
*offset += l.lct->toi_size;
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;
}
if (buffer16 & LCT_CLOSE_SESSION_FLAG)
col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Close session");
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;
return hlen;
}
void lct_dissector_free(struct _lct *lct)
void
proto_register_rmt_lct(void)
{
g_array_free(lct->ext, TRUE);
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));
}
/* Preferences */
/* ----------- */
/* Set/Reset preferences to default values */
void lct_prefs_set_default(struct _lct_prefs *lct_prefs)
{
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;
}
/* 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:
*/

View File

@ -1,185 +0,0 @@
/* packet-rmt-lct.h
* Reliable Multicast Transport (RMT)
* LCT Building Block function definitions
* Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __PACKET_RMT_LCT__
#define __PACKET_RMT_LCT__
#include "packet-rmt-common.h"
#include "packet-rmt-fec.h"
/* Type definitions */
/* ================ */
/* Logical LCT header representation */
struct _lct
{
guint8 version;
guint8 cci_size;
guint8 tsi_size;
guint8 toi_size;
gboolean tsi_present;
gboolean toi_present;
gboolean sct_present;
gboolean ert_present;
gboolean close_session;
gboolean close_object;
guint16 hlen;
guint8 codepoint;
guint64 tsi;
guint64 toi;
const guint8 *toi_extended;
nstime_t sct;
nstime_t ert;
GArray *ext;
};
/* Wireshark stuff */
/* ============== */
/* LCT header field definitions */
struct _lct_hf
{
int header;
int version;
int fsize_header;
int fsize_cci;
int fsize_tsi;
int fsize_toi;
int flags_header;
int flags_sct_present;
int flags_ert_present;
int flags_close_session;
int flags_close_object;
int hlen;
int codepoint;
int cci;
int tsi;
int toi;
int toi_extended;
int sct;
int ert;
int ext;
};
/* LCT subtrees */
struct _lct_ett
{
gint main;
gint fsize;
gint flags;
gint ext;
gint ext_ext;
};
/* LCT preferences */
#define LCT_PREFS_EXT_192_NONE 0
#define LCT_PREFS_EXT_192_FLUTE 1
#define LCT_PREFS_EXT_193_NONE 0
#define LCT_PREFS_EXT_193_FLUTE 1
struct _lct_prefs
{
gboolean codepoint_as_fec_encoding;
gint ext_192;
gint ext_193;
};
/* LCT pointers */
struct _lct_ptr
{
struct _lct *lct;
struct _lct_hf *hf;
struct _lct_ett *ett;
struct _lct_prefs *prefs;
};
/* Macros to generate static arrays */
#define LCT_FIELD_ARRAY(base_structure, base_protocol) \
{ &base_structure.header, \
{ "Layered Coding Transport (LCT) header", base_protocol ".lct", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.version, \
{ "Version", base_protocol ".lct.version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.fsize_header, \
{ "Field sizes (bytes)", base_protocol ".lct.fsize", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.fsize_cci, \
{ "Congestion Control Information field size", base_protocol ".lct.fsize.cci", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.fsize_tsi, \
{ "Transport Session Identifier field size", base_protocol ".lct.fsize.tsi", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.fsize_toi, \
{ "Transport Object Identifier field size", base_protocol ".lct.fsize.toi", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.flags_header, \
{ "Flags", base_protocol ".lct.flags", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.flags_sct_present, \
{ "Sender Current Time present flag", base_protocol ".lct.flags.sct_present", FT_BOOLEAN, BASE_NONE, TFS(&tfs_set_notset), 0x0, NULL, HFILL }}, \
{ &base_structure.flags_ert_present, \
{ "Expected Residual Time present flag", base_protocol ".lct.flags.ert_present", FT_BOOLEAN, BASE_NONE, TFS(&tfs_set_notset), 0x0, NULL, HFILL }}, \
{ &base_structure.flags_close_session, \
{ "Close Session flag", base_protocol ".lct.flags.close_session", FT_BOOLEAN, BASE_NONE, TFS(&tfs_set_notset), 0x0, NULL, HFILL }}, \
{ &base_structure.flags_close_object, \
{ "Close Object flag", base_protocol ".lct.flags.close_object", FT_BOOLEAN, BASE_NONE, TFS(&tfs_set_notset), 0x0, NULL, HFILL }}, \
{ &base_structure.hlen, \
{ "Header length", base_protocol ".lct.hlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.codepoint, \
{ "Codepoint", base_protocol ".lct.codepoint", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.cci, \
{ "Congestion Control Information", base_protocol ".lct.cci", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.tsi, \
{ "Transport Session Identifier", base_protocol ".lct.tsi", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.toi, \
{ "Transport Object Identifier (up to 64 bits)", base_protocol ".lct.toi", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.toi_extended, \
{ "Transport Object Identifier (up to 112 bits)", base_protocol ".lct.toi_extended", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.sct, \
{ "Sender Current Time", base_protocol ".lct.sct", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.ert, \
{ "Expected Residual Time", base_protocol ".lct.ert", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0, NULL, HFILL }}, \
{ &base_structure.ext, \
{ "Extension count", base_protocol ".lct.ext", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}
#define LCT_SUBTREE_ARRAY(base_structure) \
&base_structure.main, \
&base_structure.fsize, \
&base_structure.flags, \
&base_structure.ext, \
&base_structure.ext_ext
/* LCT exported functions */
/* ====================== */
void lct_info_column(struct _lct *lct, packet_info *pinfo);
gboolean lct_dissector(struct _lct_ptr l, struct _fec_ptr f, tvbuff_t *tvb, proto_tree *tree, guint *offset);
void lct_dissector_free(struct _lct *lct);
void lct_prefs_set_default(struct _lct_prefs *prefs);
void lct_prefs_register(struct _lct_prefs *prefs, module_t *module);
gboolean lct_ext_decode(struct _ext *e, struct _lct_prefs *prefs, tvbuff_t *tvb, proto_tree *tree, gint ett, struct _fec_ptr f);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,183 +0,0 @@
/* packet-rmt-norm.h
* Reliable Multicast Transport (RMT)
* NORM Protocol Instantiation function definitions
* Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* Extensive changes to decode more information Julian Onions
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __PACKET_RMT_NORM__
#define __PACKET_RMT_NORM__
#include "packet-rmt-common.h"
#include "packet-rmt-fec.h"
#include "packet-rmt-lct.h"
/* Type definitions */
/* ================ */
/* Logical NORM packet representation */
struct _norm
{
guint8 version;
guint8 type;
guint8 hlen;
guint16 sequence;
guint32 source_id;
struct _fec fec;
};
enum {
NORM_INFO = 1,
NORM_DATA = 2,
NORM_CMD = 3,
NORM_NACK = 4,
NORM_ACK = 5,
NORM_REPORT = 6,
NORM_CMD_FLUSH = 1,
NORM_CMD_EOT = 2,
NORM_CMD_SQUELCH = 3,
NORM_CMD_CC = 4,
NORM_CMD_REPAIR_ADV = 5,
NORM_CMD_ACK_REQ = 6,
NORM_CMD_APPLICATION = 7,
NORM_FLAG_REPAIR = 0x01,
NORM_FLAG_EXPLICIT = 0x02,
NORM_FLAG_INFO = 0x04,
NORM_FLAG_UNRELIABLE = 0x08,
NORM_FLAG_FILE = 0x10,
NORM_FLAG_STREAM = 0x20,
NORM_FLAG_MSG_START = 0x40,
NORM_ACK_CC = 1,
NORM_ACK_FLUSH = 2,
NORM_NACK_ITEMS = 1,
NORM_NACK_RANGES = 2,
NORM_NACK_ERASURES = 3,
NORM_NACK_SEGMENT = 0x01,
NORM_NACK_BLOCK = 0x02,
NORM_NACK_INFO = 0x04,
NORM_NACK_OBJECT = 0x08,
NORM_FLAG_CC_CLR = 0x01,
NORM_FLAG_CC_PLR = 0x02,
NORM_FLAG_CC_RTT = 0x04,
NORM_FLAG_CC_START = 0x08,
NORM_FLAG_CC_LEAVE = 0x10
};
/* Wireshark stuff */
/* ============== */
/* NORM header field definitions*/
struct _norm_hf
{
int version;
int type;
int hlen;
int sequence;
int source_id;
int instance_id;
int grtt;
int backoff;
int gsize;
int flags;
int cmd_flavor;
int reserved;
int cc_sequence;
int cc_sts;
int cc_stus;
int cc_node_id;
int cc_flags;
int cc_flags_clr;
int cc_flags_plr;
int cc_flags_rtt;
int cc_flags_start;
int cc_flags_leave;
int cc_rtt;
int cc_rate;
int cc_transport_id;
int ack_source;
int ack_type;
int ack_id;
int ack_grtt_sec;
int ack_grtt_usec;
int nack_server;
int nack_grtt_sec;
int nack_grtt_usec;
int nack_form;
int nack_length;
int nack_flags;
int nack_flags_segment;
int nack_flags_block;
int nack_flags_info;
int nack_flags_object;
struct flaglist {
int repair;
int norm_explicit;
int info;
int unreliable;
int file;
int stream;
int msgstart;
} flag;
int object_transport_id;
int extension;
int payload_len;
int payload_offset;
struct _fec_hf fec;
int payload;
};
/* NORM subtrees */
struct _norm_ett
{
gint main;
gint hdrext;
gint flags;
gint streampayload;
gint congestioncontrol;
gint nackdata;
struct _fec_ett fec;
};
/* NORM preferences */
struct _norm_prefs
{
struct _fec_prefs fec;
};
/* Function declarations */
/* ===================== */
#endif