aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2005-10-11 05:23:27 +0000
committerAnders Broman <anders.broman@ericsson.com>2005-10-11 05:23:27 +0000
commitb854132495bdfd91fe2975aa1dfff0e9874e01fd (patch)
tree7cfce27e5f299f55b94cb948c07e3cf8ec75de0d
parent24df5c368e69b905137e22a94f941949547d7736 (diff)
From Hannes Gredler:
fixes the AF/SAFI codepoints for BGP Layer-2 VPNs from a Juniper pre-standard implementation to the new "official" IANA assigned codepoints. From Julian Onions packet-rmt-norm.ch Decode more oif the protocol svn path=/trunk/; revision=16183
-rw-r--r--epan/dissectors/packet-bgp.c37
-rw-r--r--epan/dissectors/packet-bgp.h1
-rw-r--r--epan/dissectors/packet-rmt-norm.c663
-rw-r--r--epan/dissectors/packet-rmt-norm.h114
4 files changed, 722 insertions, 93 deletions
diff --git a/epan/dissectors/packet-bgp.c b/epan/dissectors/packet-bgp.c
index 36315b8500..fe7cdcdd6e 100644
--- a/epan/dissectors/packet-bgp.c
+++ b/epan/dissectors/packet-bgp.c
@@ -244,6 +244,7 @@ static const value_string bgpattr_nlri_safi[] = {
{ SAFNUM_UNIMULC, "Unicast+Multicast" },
{ SAFNUM_MPLS_LABEL, "Labeled Unicast"},
{ SAFNUM_TUNNEL, "Tunnel"},
+ { SAFNUM_VPLS, "VPLS"},
{ SAFNUM_LAB_VPNUNICAST, "Labeled VPN Unicast" }, /* draft-rosen-rfc2547bis-03 */
{ SAFNUM_LAB_VPNMULCAST, "Labeled VPN Multicast" },
{ SAFNUM_LAB_VPNUNIMULC, "Labeled VPN Unicast+Multicast" },
@@ -611,10 +612,12 @@ mp_addr_to_str (guint16 afi, guint8 safi, tvbuff_t *tvb, gint offset, char *buf,
}
break;
case AFNUM_L2VPN:
+ case AFNUM_L2VPN_OLD:
switch (safi) {
case SAFNUM_LAB_VPNUNICAST: /* only labeles prefixes do make sense */
case SAFNUM_LAB_VPNMULCAST:
case SAFNUM_LAB_VPNUNIMULC:
+ case SAFNUM_VPLS:
length = 4; /* the next-hop is simply an ipv4 addr */
ip4addr = tvb_get_ipv4(tvb, offset + 0);
strptr += g_snprintf(strptr, buf_len-(strptr-buf), "IPv4=%s",
@@ -1008,11 +1011,13 @@ decode_prefix_MP(proto_tree *tree, int hf_addr4, int hf_addr6,
break;
case AFNUM_L2VPN:
+ case AFNUM_L2VPN_OLD:
switch (safi) {
case SAFNUM_LAB_VPNUNICAST:
case SAFNUM_LAB_VPNMULCAST:
case SAFNUM_LAB_VPNUNIMULC:
+ case SAFNUM_VPLS:
plen = tvb_get_ntohs(tvb,offset);
rd_type=tvb_get_ntohs(tvb,offset+2);
ce_id=tvb_get_ntohs(tvb,offset+10);
@@ -2078,29 +2083,39 @@ dissect_bgp_update(tvbuff_t *tvb, proto_tree *tree)
"Next hop network address (%d %s)",
nexthop_len, plurality(nexthop_len, "byte", "bytes"));
subtree3 = proto_item_add_subtree(ti, ett_bgp_mp_nhna);
- if (af != AFNUM_INET && af != AFNUM_INET6 && af != AFNUM_L2VPN) {
- /*
- * The addresses don't contain lengths, so if we
- * don't understand the address family type, we
- * cannot parse the subsequent addresses as we
- * don't know how long they are.
- */
+
+ /*
+ * The addresses don't contain lengths, so if we
+ * don't understand the address family type, we
+ * cannot parse the subsequent addresses as we
+ * don't know how long they are.
+ */
+ switch (af) {
+ default:
proto_tree_add_text(subtree3, tvb, o + i + aoff + 4,
nexthop_len, "Unknown Address Family");
- } else {
+ break;
+
+ case AFNUM_INET:
+ case AFNUM_INET6:
+ case AFNUM_L2VPN:
+ case AFNUM_L2VPN_OLD:
+
j = 0;
while (j < nexthop_len) {
advance = mp_addr_to_str(af, saf, tvb, o + i + aoff + 4 + j,
- junk_gbuf, MAX_STR_LEN) ;
+ junk_gbuf, MAX_STR_LEN) ;
if (advance == 0) /* catch if this is a unknown AFI type*/
- break;
+ break;
if (j + advance > nexthop_len)
break;
proto_tree_add_text(subtree3, tvb,o + i + aoff + 4 + j,
advance, "Next hop: %s (%u)", junk_gbuf, advance);
j += advance;
}
- }
+ break;
+ }
+
tlen -= nexthop_len + 4;
aoff += nexthop_len + 4 ;
diff --git a/epan/dissectors/packet-bgp.h b/epan/dissectors/packet-bgp.h
index 4c9a037b38..0b59ab5b5c 100644
--- a/epan/dissectors/packet-bgp.h
+++ b/epan/dissectors/packet-bgp.h
@@ -201,6 +201,7 @@ struct bgp_attr {
#define SAFNUM_UNIMULC 3
#define SAFNUM_MPLS_LABEL 4 /* rfc3107 */
#define SAFNUM_TUNNEL 64 /* draft-nalawade-kapoor-tunnel-safi-02.txt */
+#define SAFNUM_VPLS 65
#define SAFNUM_LAB_VPNUNICAST 128 /* Draft-rosen-rfc2547bis-03 */
#define SAFNUM_LAB_VPNMULCAST 129
#define SAFNUM_LAB_VPNUNIMULC 130
diff --git a/epan/dissectors/packet-rmt-norm.c b/epan/dissectors/packet-rmt-norm.c
index 0b09b437b1..33554c8ee6 100644
--- a/epan/dissectors/packet-rmt-norm.c
+++ b/epan/dissectors/packet-rmt-norm.c
@@ -3,6 +3,8 @@
* NORM Protocol Instantiation dissector
* Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
*
+ * Extensive changes to decode more information Julian Onions
+ *
* Negative-acknowledgment (NACK)-Oriented Reliable Multicast (NORM):
* ------------------------------------------------------------------
*
@@ -26,12 +28,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
@@ -49,21 +51,52 @@
#include <epan/packet.h>
#include <epan/prefs.h>
+#include <epan/strutil.h>
#include "packet-rmt-norm.h"
+#include <math.h>
/* String tables */
-const value_string string_norm_type[] =
+static const value_string string_norm_type[] =
+{
+ { NORM_INFO, "INFO" },
+ { NORM_DATA, "DATA" },
+ { NORM_CMD, "CMD" },
+ { NORM_NACK, "NACK" },
+ { NORM_ACK, "ACK" },
+ { NORM_REPORT, "REPORT" },
+ { 0, NULL }
+};
+
+static const value_string string_norm_cmd_type[] =
{
- { 1, "NORM_INFO" },
- { 2, "NORM_DATA" },
- { 3, "NORM_CMD" },
- { 4, "NORM_NACK" },
- { 5, "NORM_ACK" },
- { 6, "NORM_REPORT" },
+ { NORM_CMD_FLUSH, "FLUSH" },
+ { NORM_CMD_EOT, "EOT" },
+ { NORM_CMD_SQUELCH, "SQUELCH" },
+ { NORM_CMD_CC, "CC" },
+ { NORM_CMD_REPAIR_ADV, "REPAIR_ADV" },
+ { NORM_CMD_ACK_REQ, "ACK_REQ" },
+ { NORM_CMD_APPLICATION, "APPLICATION" },
{ 0, NULL }
};
+static const value_string string_norm_ack_type[] =
+{
+ { NORM_ACK_CC, "ACK CC" },
+ { NORM_ACK_FLUSH, "ACK FLUSH" },
+ { 0, NULL }
+};
+
+static const value_string string_norm_nack_form[] =
+{
+ { NORM_NACK_ITEMS, "Items" },
+ { NORM_NACK_RANGES, "Ranges" },
+ { NORM_NACK_ERASURES, "Erasures" },
+ { 0, NULL }
+};
+
+#define hdrlen2bytes(x) ((x)*4U)
+
/* Initialize the protocol and registered fields */
/* ============================================= */
@@ -97,6 +130,393 @@ 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;
+
+static double UnquantizeRtt(unsigned char qrtt)
+{
+ return ((qrtt <= 31) ? (((double)(qrtt+1))*(double)RTT_MIN) :
+ (RTT_MAX/exp(((double)(255-qrtt))/(double)13.0)));
+}
+
+static double UnquantizeGSize(guint8 gsize)
+{
+ guint mant = (gsize & 0x8) ? 5 : 1;
+ guint exponent = gsize & 0x7;
+ exponent ++;
+ 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 gsize;
+ double grtt;
+ proto_tree_add_item(tree, hf.instance_id, tvb, offset, 2, FALSE); offset+=2;
+ grtt = UnquantizeRtt(tvb_get_guint8(tvb, offset));
+ proto_tree_add_double(tree, hf.grtt, tvb, offset, 1, grtt); offset++;
+ backoff = hi_nibble(tvb_get_guint8(tvb, offset));
+ gsize = 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, gsize);
+ offset++;
+ return offset;
+}
+
+/* split out some common FEC handling */
+static guint dissect_feccode(struct _norm *norm, struct _fec_ptr *f, 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->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, FALSE); offset++;
+ if (reserved) {
+ proto_tree_add_item(tree, hf.reserved, tvb, offset, 1, FALSE); offset++;
+ }
+ proto_tree_add_item(tree, hf.object_transport_id, tvb, offset, 2, FALSE); offset+=2;
+
+ if (norm->fec.encoding_id_present && tvb_length(tvb) > offset) {
+ fec_dissector(*f, tvb, tree, &offset);
+ if (check_col(pinfo->cinfo, COL_INFO))
+ fec_info_column(f->fec, pinfo);
+ }
+ 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)
+{
+ guint i;
+ proto_item *ti;
+ /* Allocate an array of _ext elements */
+ GArray *ext;
+ guint offset_old = offset;
+ proto_tree *ext_tree;
+
+ ext = g_array_new(FALSE, TRUE, sizeof(struct _ext));
+
+ rmt_ext_parse(ext, tvb, &offset, hdrlen2bytes(norm->hlen));
+
+ if (ext->len > 0)
+ {
+ 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++)
+ fec_decode_ext_fti(&g_array_index(ext, struct _ext, i),
+ tvb, ext_tree, ett.hdrext, *f);
+ }
+ g_array_free(ext, TRUE);
+ 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)
+{
+ 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, FALSE);
+ 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, FALSE);
+ proto_tree_add_item(flag_tree, hf.flag.explicit, tvb, offset, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf.flag.info, tvb, offset, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf.flag.unreliable, tvb, offset, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf.flag.file, tvb, offset, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf.flag.stream, tvb, offset, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf.flag.msgstart, tvb, offset, 1, FALSE);
+ offset++;
+
+ 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);
+ }
+ 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, FALSE); offset+=2;
+ proto_tree_add_item(flag_tree, hf.payload_len, tvb, offset, 2, FALSE); offset+=2;
+ proto_tree_add_item(flag_tree, hf.payload_offset, tvb, offset, 4, FALSE); offset+=4;
+
+ }
+ if (tvb_length(tvb) > offset)
+ proto_tree_add_none_format(tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_length(tvb) - offset);
+
+}
+
+/* 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)
+{
+ guint8 flags;
+ proto_item *ti;
+ proto_tree *flag_tree;
+
+ offset = dissect_grrtetc(tree, tvb, offset);
+
+ ti = proto_tree_add_item(tree, hf.flags, tvb, offset, 1, FALSE);
+ 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, FALSE);
+ proto_tree_add_item(flag_tree, hf.flag.explicit, tvb, offset, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf.flag.info, tvb, offset, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf.flag.unreliable, tvb, offset, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf.flag.file, tvb, offset, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf.flag.stream, tvb, offset, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf.flag.msgstart, tvb, offset, 1, FALSE);
+ offset++;
+
+ proto_tree_add_item(tree, hf.fec.encoding_id, tvb, offset, 1, FALSE); offset++;
+ proto_tree_add_item(tree, hf.object_transport_id, tvb, offset, 2, FALSE); 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);
+ }
+ if (tvb_length(tvb) > offset)
+ proto_tree_add_none_format(tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_length(tvb) - offset);
+
+}
+/* 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)
+{
+ 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);
+ }
+ 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)
+{
+ proto_tree_add_item(tree, hf.flags, tvb, offset, 1, FALSE); offset ++;
+ proto_tree_add_item(tree, hf.reserved, tvb, offset, 2, FALSE); 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);
+ }
+ 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)
+{
+ proto_tree_add_item(tree, hf.reserved, tvb, offset, 1, FALSE); offset ++;
+ proto_tree_add_item(tree, hf.cc_sequence, tvb, offset, 2, FALSE); offset += 2;
+
+ proto_tree_add_item(tree, hf.cc_sts, tvb, offset, 4, FALSE); offset += 4;
+ proto_tree_add_item(tree, hf.cc_stus, tvb, offset, 4, FALSE); 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);
+ }
+ while (offset + 8 <= tvb_length(tvb)) {
+ 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, FALSE); offset += 4;
+ tif = proto_tree_add_item(cc_tree, hf.cc_flags, tvb, offset, 1, FALSE);
+ flag_tree = proto_item_add_subtree(tif, ett.flags);
+ proto_tree_add_item(flag_tree, hf.cc_flags_clr, tvb, offset, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf.cc_flags_plr, tvb, offset, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf.cc_flags_rtt, tvb, offset, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf.cc_flags_start, tvb, offset, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf.cc_flags_leave, tvb, offset, 1, FALSE);
+ 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;
+ }
+ 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)
+{
+ struct _fec_ptr f;
+ offset = dissect_feccode(norm, &f, tree, tvb, offset, pinfo, 0);
+
+ while (offset + 2 <= tvb_length(tvb)) {
+ proto_tree_add_item(tree, hf.cc_transport_id, tvb, offset, 4, FALSE); offset += 2;
+ }
+ return offset;
+}
+
+/* code to dissect NORM cmd(squelch) packets */
+static guint dissect_norm_cmd_ackreq(struct _norm *norm, proto_tree *tree,
+ tvbuff_t *tvb, guint offset, packet_info *pinfo)
+{
+ proto_tree_add_item(tree, hf.reserved, tvb, offset, 1, FALSE); offset ++;
+ proto_tree_add_item(tree, hf.ack_type, tvb, offset, 1, FALSE); offset += 1;
+ proto_tree_add_item(tree, hf.ack_id, tvb, offset, 1, FALSE); 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)
+{
+ 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, " ",
+ val_to_str(flavor, string_norm_cmd_type, "Unknown Cmd Type (0x%04x)"));
+ proto_tree_add_item(tree, hf.cmd_flavor, tvb, offset, 1, FALSE); offset ++;
+ switch(flavor) {
+ case NORM_CMD_CC:
+ offset = dissect_norm_cmd_cc(norm, tree, tvb, offset, pinfo);
+ break;
+ case NORM_CMD_FLUSH:
+ offset = dissect_norm_cmd_flush(norm, tree, tvb, offset, pinfo);
+ break;
+ case NORM_CMD_SQUELCH:
+ offset = dissect_norm_cmd_squelch(norm, tree, tvb, offset, pinfo);
+ break;
+ case NORM_CMD_REPAIR_ADV:
+ offset = dissect_norm_cmd_repairadv(norm, tree, tvb, offset, pinfo);
+ break;
+ case NORM_CMD_ACK_REQ:
+ offset = dissect_norm_cmd_ackreq(norm, tree, tvb, offset, pinfo);
+ break;
+ }
+ if (tvb_length(tvb) > offset)
+ proto_tree_add_none_format(tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_length(tvb) - offset);
+}
+
+/* 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)
+{
+ guint8 acktype;
+
+ proto_tree_add_item(tree, hf.ack_source, tvb, offset, 4, FALSE); offset += 4;
+ proto_tree_add_item(tree, hf.instance_id, tvb, offset, 2, FALSE); offset += 2;
+ acktype = tvb_get_guint8(tvb, offset);
+ if (check_col(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, FALSE); offset += 1;
+ proto_tree_add_item(tree, hf.ack_id, tvb, offset, 1, FALSE); offset += 1;
+ proto_tree_add_item(tree, hf.ack_grtt_sec, tvb, offset, 4, FALSE); offset += 4;
+ proto_tree_add_item(tree, hf.ack_grtt_usec, tvb, offset, 4, FALSE); 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);
+ }
+
+ if (tvb_length(tvb) > offset)
+ proto_tree_add_none_format(tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_length(tvb) - offset);
+
+}
+
+/* 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)
+{
+ proto_tree_add_item(tree, hf.nack_server, tvb, offset, 4, FALSE); offset += 4;
+ proto_tree_add_item(tree, hf.instance_id, tvb, offset, 2, FALSE); offset += 2;
+ proto_tree_add_item(tree, hf.reserved, tvb, offset, 2, FALSE); offset += 2;
+ proto_tree_add_item(tree, hf.nack_grtt_sec, tvb, offset, 4, FALSE); offset += 4;
+ proto_tree_add_item(tree, hf.nack_grtt_usec, tvb, offset, 4, FALSE); 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);
+ }
+
+ while (offset < tvb_length(tvb)) {
+ proto_item *ti, *tif;
+ proto_tree *nack_tree, *flag_tree;
+ guint orig_offset = offset;
+ guint16 len;
+ ti = proto_tree_add_text(tree, tvb, offset, 8, "NACK Data");
+ nack_tree = proto_item_add_subtree(ti, ett.nackdata);
+ proto_tree_add_item(nack_tree, hf.nack_form, tvb, offset, 1, FALSE); offset += 1;
+
+ tif = proto_tree_add_item(nack_tree, hf.nack_flags, tvb, offset, 1, FALSE);
+ flag_tree = proto_item_add_subtree(tif, ett.flags);
+ proto_tree_add_item(flag_tree, hf.nack_flags_segment, tvb, offset, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf.nack_flags_block, tvb, offset, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf.nack_flags_info, tvb, offset, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf.nack_flags_object, tvb, offset, 1, FALSE);
+ offset += 1;
+ len = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(nack_tree, hf.nack_length, tvb, offset, 2, FALSE); 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);
+ }
+ offset += len;
+ }
+ if (tvb_length(tvb) > offset)
+ proto_tree_add_none_format(tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_length(tvb) - offset);
+
+}
/* Code to actually dissect the packets */
/* ==================================== */
@@ -104,111 +524,103 @@ static void dissect_norm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
/* Logical packet representation */
struct _norm norm;
-
+
/* Offset for subpacket dissection */
guint offset;
-
+
/* Set up structures needed to add the protocol subtree and manage it */
proto_item *ti;
proto_tree *norm_tree;
-
+
/* Structures and variables initialization */
offset = 0;
memset(&norm, 0, sizeof(struct _norm));
-
+
/* Update packet info */
pinfo->current_proto = "NORM";
-
+
/* Make entries in Protocol column and Info column on summary display */
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "NORM");
- if (check_col(pinfo->cinfo, COL_INFO))
+ if (check_col(pinfo->cinfo, COL_INFO))
col_clear(pinfo->cinfo, COL_INFO);
-
+
/* NORM header dissection, part 1 */
/* ------------------------------ */
-
+
norm.version = hi_nibble(tvb_get_guint8(tvb, offset));
-
+
if (tree)
{
/* Create subtree for the NORM protocol */
ti = proto_tree_add_item(tree, proto, tvb, offset, -1, FALSE);
norm_tree = proto_item_add_subtree(ti, ett.main);
-
+
/* Fill the NORM subtree */
proto_tree_add_uint(norm_tree, hf.version, tvb, offset, 1, norm.version);
-
+
} else
norm_tree = NULL;
-
+
/* This dissector supports only NORMv1 packets.
* If norm.version > 1 print only version field and quit.
*/
if (norm.version == 1) {
-
+
/* NORM header dissection, part 2 */
/* ------------------------------ */
-
+
norm.type = lo_nibble(tvb_get_guint8(tvb, offset));
norm.hlen = tvb_get_guint8(tvb, offset+1);
norm.sequence = tvb_get_ntohs(tvb, offset+2);
norm.source_id = tvb_get_ntohl(tvb, offset+4);
-
+
if (tree)
{
proto_tree_add_uint(norm_tree, hf.type, tvb, offset, 1, norm.type);
proto_tree_add_uint(norm_tree, hf.hlen, tvb, offset+1, 1, norm.hlen);
proto_tree_add_uint(norm_tree, hf.sequence, tvb, offset+2, 2, norm.sequence);
- proto_tree_add_uint(norm_tree, hf.source_id, tvb, offset+4, 4, norm.source_id);
+ proto_tree_add_item(norm_tree, hf.source_id, tvb, offset+4, 4, FALSE);
}
-
+
offset += 8;
-
- /* Add the Payload item */
- if (tvb_length(tvb) > offset)
- proto_tree_add_none_format(norm_tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_length(tvb) - offset);
-
+
+
/* Complete entry in Info column on summary display */
/* ------------------------------------------------ */
-
if (check_col(pinfo->cinfo, COL_INFO))
- switch (norm.type)
- {
- case 1:
- col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "INFO");
- break;
-
- case 2:
- col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "DATA");
- break;
-
- case 3:
- col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "CMD");
- break;
-
- case 4:
- col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "NACK");
- break;
-
- case 5:
- col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "ACK");
- break;
-
- case 6:
- col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "REPORT");
- break;
-
- default:
- col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Unknown type");
- break;
- }
+ 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_length(tvb) > offset)
+ proto_tree_add_none_format(norm_tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_length(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);
@@ -221,19 +633,20 @@ void proto_reg_handoff_norm(void)
if (!preferences_initialized)
{
- preferences_initialized = TRUE;
+ preferences_initialized = TRUE;
handle = create_dissector_handle(dissect_norm, proto);
dissector_add_handle("udp.port", handle);
+ //dissector_add("udp.port", 6003, handle);
}
norm_prefs_save(&preferences, &preferences_old);
}
void proto_register_norm(void)
-{
+{
/* Setup NORM header fields */
static hf_register_info hf_ptr[] = {
-
+
{ &hf.version,
{ "Version", "norm.version", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
{ &hf.type,
@@ -243,9 +656,105 @@ void proto_register_norm(void)
{ &hf.sequence,
{ "Sequence", "norm.sequence", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
{ &hf.source_id,
- { "Source ID", "norm.source_id", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
-
- FEC_FIELD_ARRAY(hf.fec, "alc"),
+ { "Source ID", "norm.source_id", FT_IPv4, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf.instance_id,
+ { "Instance", "norm.instance_id", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.grtt,
+ { "grtt", "norm.grtt", FT_DOUBLE, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.backoff,
+ { "Backoff", "norm.backoff", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.gsize,
+ { "Group Size", "norm.gsize", FT_DOUBLE, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.flags,
+ { "Flags", "norm.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL}},
+ { &hf.flag.repair,
+ { "Repair Flag", "norm.flag.repair", FT_BOOLEAN, 8, NULL, NORM_FLAG_REPAIR, "", HFILL }},
+ { &hf.flag.explicit,
+ { "Explicit Flag", "norm.flag.explicit", FT_BOOLEAN, 8, NULL, NORM_FLAG_EXPLICIT, "", HFILL }},
+ { &hf.flag.info,
+ { "Info Flag", "norm.flag.info", FT_BOOLEAN, 8, NULL, NORM_FLAG_INFO, "", HFILL }},
+ { &hf.flag.unreliable,
+ { "Unreliable Flag", "norm.flag.unreliable", FT_BOOLEAN, 8, NULL, NORM_FLAG_UNRELIABLE, "", HFILL }},
+ { &hf.flag.file,
+ { "File Flag", "norm.flag.file", FT_BOOLEAN, 8, NULL, NORM_FLAG_FILE, "", HFILL }},
+ { &hf.flag.stream,
+ { "Stream Flag", "norm.flag.stream", FT_BOOLEAN, 8, NULL, NORM_FLAG_STREAM, "", HFILL }},
+ { &hf.flag.msgstart,
+ { "Msg Start Flag", "norm.flag.msgstart", FT_BOOLEAN, 8, NULL, NORM_FLAG_MSG_START, "", HFILL }},
+ { &hf.object_transport_id,
+ { "Object Transport ID", "norm.object_transport_id", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},
+ { &hf.extension,
+ { "Hdr Extension", "norm.hexext", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.reserved,
+ { "Reserved", "norm.reserved", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL}},
+ { &hf.payload_len,
+ { "Payload Len", "norm.payload.len", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.payload_offset,
+ { "Payload Offset", "norm.payload.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
+
+ { &hf.cmd_flavor,
+ { "Flavor", "norm.flavor", FT_UINT8, BASE_DEC, VALS(string_norm_cmd_type), 0x0, "", HFILL}},
+ { &hf.cc_sequence,
+ { "CC Sequence", "norm.ccsequence", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.cc_sts,
+ { "Send Time secs", "norm.cc_sts", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.cc_stus,
+ { "Send Time usecs", "norm.cc_stus", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.cc_node_id,
+ { "CC Node ID", "norm.cc_node_id", FT_IPv4, BASE_NONE, NULL, 0x0, "", HFILL}},
+ { &hf.cc_flags,
+ { "CC Flags", "norm.cc_flags", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.cc_flags_clr,
+ { "CLR", "norm.cc_flags.clr", FT_BOOLEAN, 8, NULL, NORM_FLAG_CC_CLR, "", HFILL}},
+ { &hf.cc_flags_plr,
+ { "PLR", "norm.cc_flags.plr", FT_BOOLEAN, 8, NULL, NORM_FLAG_CC_PLR, "", HFILL}},
+ { &hf.cc_flags_rtt,
+ { "RTT", "norm.cc_flags.rtt", FT_BOOLEAN, 8, NULL, NORM_FLAG_CC_RTT, "", HFILL}},
+ { &hf.cc_flags_start,
+ { "Start", "norm.cc_flags.start", FT_BOOLEAN, 8, NULL, NORM_FLAG_CC_START, "", HFILL}},
+ { &hf.cc_flags_leave,
+ { "Leave", "norm.cc_flags.leave", FT_BOOLEAN, 8, NULL, NORM_FLAG_CC_LEAVE, "", HFILL}},
+ { &hf.cc_rtt,
+ { "CC RTT", "norm.cc_rtt", FT_DOUBLE, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.cc_rate,
+ { "CC Rate", "norm.cc_rate", FT_DOUBLE, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.cc_transport_id,
+ { "CC Transport ID", "norm.cc_transport_id", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
+
+ { &hf.ack_source,
+ { "Ack Source", "norm.ack.source", FT_IPv4, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.ack_type,
+ { "Ack Type", "norm.ack.type", FT_UINT8, BASE_DEC, VALS(string_norm_ack_type), 0x0, "", HFILL}},
+ { &hf.ack_id,
+ { "Ack ID", "norm.ack.id", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.ack_grtt_sec,
+ { "Ack GRTT Sec", "norm.ack.grtt_sec", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.ack_grtt_usec,
+ { "Ack GRTT usec", "norm.ack.grtt_usec", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
+
+ { &hf.nack_server,
+ { "NAck Server", "norm.nack.server", FT_IPv4, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.nack_grtt_sec,
+ { "NAck GRTT Sec", "norm.nack.grtt_sec", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.nack_grtt_usec,
+ { "NAck GRTT usec", "norm.nack.grtt_usec", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.nack_form,
+ { "NAck FORM", "norm.nack.form", FT_UINT8, BASE_DEC, VALS(string_norm_nack_form), 0x0, "", HFILL}},
+ { &hf.nack_flags,
+ { "NAck Flags", "norm.nack.flags", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL}},
+ { &hf.nack_flags_segment,
+ { "Segment", "norm.nack.flags.segment", FT_BOOLEAN, 8, NULL, NORM_NACK_SEGMENT, "", HFILL}},
+ { &hf.nack_flags_block,
+ { "Block", "norm.nack.flags.block", FT_BOOLEAN, 8, NULL, NORM_NACK_BLOCK, "", HFILL}},
+ { &hf.nack_flags_info,
+ { "Info", "norm.nack.flags.info", FT_BOOLEAN, 8, NULL, NORM_NACK_INFO, "", HFILL}},
+ { &hf.nack_flags_object,
+ { "Object", "norm.nack.flags.object", FT_BOOLEAN, 8, NULL, NORM_NACK_OBJECT, "", HFILL}},
+ { &hf.nack_length,
+ { "NAck Length", "norm.nack.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
+
+
+ FEC_FIELD_ARRAY(hf.fec, "NORM"),
{ &hf.payload,
{ "Payload", "norm.payload", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}
@@ -254,28 +763,32 @@ void proto_register_norm(void)
/* 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)
};
module_t *module;
-
+
/* Clear hf and ett fields */
memset(&hf, 0xff, sizeof(struct _norm_hf));
memset(&ett, 0xff, sizeof(struct _norm_ett));
-
+
/* Register the protocol name and description */
proto = proto_register_protocol("Negative-acknowledgment Oriented Reliable Multicast", "NORM", "norm");
/* Register the header fields and subtrees used */
proto_register_field_array(proto, hf_ptr, array_length(hf_ptr));
proto_register_subtree_array(ett_ptr, array_length(ett_ptr));
-
+
/* Reset preferences */
norm_prefs_set_default(&preferences);
norm_prefs_save(&preferences, &preferences_old);
-
+
/* Register preferences */
module = prefs_register_protocol(proto, proto_reg_handoff_norm);
- norm_prefs_register(&preferences, module);
+ norm_prefs_register(&preferences, module);
}
diff --git a/epan/dissectors/packet-rmt-norm.h b/epan/dissectors/packet-rmt-norm.h
index c353bd9a7a..7144cafd4f 100644
--- a/epan/dissectors/packet-rmt-norm.h
+++ b/epan/dissectors/packet-rmt-norm.h
@@ -9,21 +9,23 @@
* By Gerald Combs <gerald@ethereal.com>
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-
+
#ifndef __PACKET_RMT_NORM__
#define __PACKET_RMT_NORM__
@@ -41,10 +43,57 @@ struct _norm
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,
+
+};
+
+
/* Ethereal stuff */
/* ============== */
@@ -56,9 +105,56 @@ struct _norm_hf
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 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;
};
@@ -66,7 +162,11 @@ struct _norm_hf
struct _norm_ett
{
gint main;
-
+ gint hdrext;
+ gint flags;
+ gint streampayload;
+ gint congestioncontrol;
+ gint nackdata;
struct _fec_ett fec;
};