aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorJaap Keuter <jaap.keuter@xs4all.nl>2007-09-25 19:42:46 +0000
committerJaap Keuter <jaap.keuter@xs4all.nl>2007-09-25 19:42:46 +0000
commit9b5e0c99a37b7ab187c1f4ffda03f601deb200ef (patch)
treeb691daa39c4702ba789df591430ced9beac7af00 /epan
parent19e901df9ac79c27b136ac18211569c76d445c09 (diff)
From Gerrit Renker:
This is an update for the DCCP dissector and has previously been sent to the DCCP dissector maintainer, Francesco Fondelli, who supplied the Acked-by. I have been using it with profit for several weeks. This patch provides the following extensions: * type-dependent decoding of feature-negotiation options (NN and SP types of options, NN is a 1..6 byte value in network-byte-order, SP is always a list of unsigned char) * decoding for CCID3 Send Loss Event Rate feature * some pretty-printing of options * decoding of CCID3-specific options - Loss Event Rate (receiver report) - Receive Rate (also reported by receiver) * there was a change in the spec - the NDP count at sometime `grew' from 3 to 6 bytes (it was the same in the kernel). I have updated the data type from uint32 to uint64 * utility function to decode from network-byte-order into host byte order with variable length svn path=/trunk/; revision=22961
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-dcp.c262
1 files changed, 126 insertions, 136 deletions
diff --git a/epan/dissectors/packet-dcp.c b/epan/dissectors/packet-dcp.c
index 06bd771c5f..ab9142e234 100644
--- a/epan/dissectors/packet-dcp.c
+++ b/epan/dissectors/packet-dcp.c
@@ -118,6 +118,14 @@ static const value_string dcp_reset_code_vals[] = {
{0, NULL}
};
+static const value_string dcp_feature_options_vals[] = {
+ {0x20, "Change L"},
+ {0x21, "Confirm L"},
+ {0x22, "Change R"},
+ {0x23, "Confirm R"},
+ {0, NULL}
+};
+
static const value_string dcp_feature_numbers_vals[] = {
{0x01, "CCID"},
{0x02, "Allow Short Seqnos"},
@@ -128,6 +136,7 @@ static const value_string dcp_feature_numbers_vals[] = {
{0x07, "Send NDP Count"},
{0x08, "Minimum Checksum Coverage"},
{0x09, "Check Data Checksum"},
+ {0xC0, "Send Loss Event Rate"}, /* CCID3, RFC 4342, 8.5 */
{0, NULL}
};
@@ -263,6 +272,83 @@ decode_dccp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tre
call_dissector(data_handle, next_tvb, pinfo, tree);
}
+/*
+ * Auxiliary functions to dissect DCCP options
+ */
+/* decode a variable-length number of nbytes starting at offset. Based on a concept by Arnaldo de Melo */
+static guint64 tvb_get_ntoh_var(tvbuff_t *tvb, gint offset, guint8 nbytes)
+{
+ const guint8* ptr;
+ guint64 value = 0;
+
+ ptr = tvb_get_ptr(tvb, offset, nbytes);
+ if (nbytes > 5)
+ value += ((guint64)*ptr++) << 40;
+ if (nbytes > 4)
+ value += ((guint64)*ptr++) << 32;
+ if (nbytes > 3)
+ value += ((guint64)*ptr++) << 24;
+ if (nbytes > 2)
+ value += ((guint64)*ptr++) << 16;
+ if (nbytes > 1)
+ value += ((guint64)*ptr++) << 8;
+ if (nbytes > 0)
+ value += *ptr;
+
+ return value;
+}
+
+static void dissect_feature_options(proto_tree *dcp_options_tree, tvbuff_t *tvb, int offset, guint8 option_len,
+ guint8 option_type)
+{
+ guint8 feature_number = tvb_get_guint8(tvb, offset + 2);
+ proto_item *dcp_item;
+ int i;
+
+ proto_tree_add_uint_hidden(dcp_options_tree, hf_dcp_feature_number, tvb, offset + 2, 1, feature_number);
+
+ dcp_item = proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "%s(",
+ val_to_str(option_type, dcp_feature_options_vals, "Unknown Type"));
+
+ /* decode the feature according to whether it is server-priority (list) or NN (single number) */
+ switch (feature_number) {
+ /* Server Priority features (RFC 4340, 6.3.1) */
+ case 1: /* Congestion Control ID (CCID); fall through */
+ case 2: /* Allow Short Seqnos; fall through */
+ case 4: /* ECN Incapable; fall through */
+ case 6: /* Send Ack Vector; fall through */
+ case 7: /* Send NDP Count; fall through */
+ case 8: /* Minimum Checksum Coverage; fall through */
+ case 9: /* Check Data Checksum; fall through */
+ case 192: /* Send Loss Event Rate, RFC 4342, section 8.4 */
+ proto_item_append_text(dcp_item, "%s",
+ val_to_str(feature_number, dcp_feature_numbers_vals, "Unknown Type"));
+ for (i = 0; i < option_len - 3; i++)
+ proto_item_append_text(dcp_item, "%s %d", i? "," : "", tvb_get_guint8(tvb, offset + 3 + i));
+ break;
+ /* Non-negotiable features (RFC 4340, 6.3.2) */
+ case 3: /* Sequence Window; fall through */
+ case 5: /* Ack Ratio */
+ proto_item_append_text(dcp_item, "%s",
+ val_to_str(feature_number, dcp_feature_numbers_vals, "Unknown Type"));
+
+ if (option_len > 3) /* could be empty Confirm */
+ proto_item_append_text(dcp_item, " %" G_GINT64_MODIFIER "u", tvb_get_ntoh_var(tvb, offset + 3, option_len - 3));
+ break;
+ /* Reserved, specific, or unknown features */
+ case 0: /* fall through */
+ case 10 ... 127:
+ proto_item_append_text(dcp_item, "Reserved feature number %d", feature_number);
+ break;
+ case 193 ... 255:
+ proto_item_append_text(dcp_item, "CCID-specific feature number %d", feature_number);
+ break;
+ default:
+ proto_item_append_text(dcp_item, "Unknown feature number %d", feature_number);
+ break;
+ }
+ proto_item_append_text(dcp_item, ")");
+}
/*
* This function dissects DCCP options
@@ -274,9 +360,9 @@ static void dissect_options(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *d
/* if here I'm sure there is at least offset_end - offset_start bytes in tvb and it should be options */
int offset=offset_start;
guint8 option_type = 0;
- guint8 option_len = 0;
- guint8 feature_number = 0;
+ guint8 option_len = 0;
int i;
+ guint32 p;
proto_item *dcp_item = NULL;
while( offset < offset_end ) {
@@ -327,104 +413,8 @@ static void dissect_options(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *d
proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "Slow Receiver");
break;
- case 32:
- feature_number = tvb_get_guint8(tvb, offset + 2);
- proto_tree_add_uint_hidden(dcp_options_tree, hf_dcp_feature_number, tvb, offset + 2, 1, feature_number);
-
- if( (feature_number < 10) && (feature_number!=0) ) {
- dcp_item = proto_tree_add_text(dcp_options_tree, tvb, offset, option_len,
- "Change L(%s",
- val_to_str(feature_number, dcp_feature_numbers_vals, "Unknown Type"));
- for (i = 0; i < option_len - 3; i++) {
- if(i==0)
- proto_item_append_text(dcp_item, "%d", tvb_get_guint8(tvb, offset + 3 + i));
- else
- proto_item_append_text(dcp_item, ", %d", tvb_get_guint8(tvb, offset + 3 + i));
- }
- proto_item_append_text(dcp_item, ")");
- } else {
- if(((feature_number>=10)&&(feature_number<=127))||(feature_number==0))
- proto_tree_add_text(dcp_options_tree, tvb, offset, option_len,
- "Change L(Reserved feature number)");
- else
- proto_tree_add_text(dcp_options_tree, tvb, offset, option_len,
- "Change L(CCID-specific features)");
- }
- break;
-
- case 33:
- feature_number = tvb_get_guint8(tvb, offset + 2);
- proto_tree_add_uint_hidden(dcp_options_tree, hf_dcp_feature_number, tvb, offset + 2, 1, feature_number);
-
- if( (feature_number < 10) && (feature_number!=0) ) {
- dcp_item = proto_tree_add_text(dcp_options_tree, tvb, offset, option_len,
- "Confirm L(%s",
- val_to_str(feature_number, dcp_feature_numbers_vals, "Unknown Type"));
- for (i = 0; i < option_len - 3; i++) {
- if(i==0)
- proto_item_append_text(dcp_item, "%d", tvb_get_guint8(tvb, offset + 3 + i));
- else
- proto_item_append_text(dcp_item, ", %d", tvb_get_guint8(tvb, offset + 3 + i));
- }
- proto_item_append_text(dcp_item, ")");
- } else {
- if(((feature_number>=10)&&(feature_number<=127))||(feature_number==0))
- proto_tree_add_text(dcp_options_tree, tvb, offset, option_len,
- "Confirm L(Reserved feature number)");
- else
- proto_tree_add_text(dcp_options_tree, tvb, offset, option_len,
- "Confirm L(CCID-specific features)");
- }
- break;
-
- case 34:
- feature_number = tvb_get_guint8(tvb, offset + 2);
- proto_tree_add_uint_hidden(dcp_options_tree, hf_dcp_feature_number, tvb, offset + 2, 1, feature_number);
-
- if( (feature_number < 10) && (feature_number!=0) ) {
- dcp_item = proto_tree_add_text(dcp_options_tree, tvb, offset, option_len,
- "Change R(%s",
- val_to_str(feature_number, dcp_feature_numbers_vals, "Unknown Type"));
- for (i = 0; i < option_len - 3; i++) {
- if(i==0)
- proto_item_append_text(dcp_item, "%d", tvb_get_guint8(tvb, offset + 3 + i));
- else
- proto_item_append_text(dcp_item, ", %d", tvb_get_guint8(tvb, offset + 3 + i));
- }
- proto_item_append_text(dcp_item, ")");
- } else {
- if(((feature_number>=10)&&(feature_number<=127))||(feature_number==0))
- proto_tree_add_text(dcp_options_tree, tvb, offset, option_len,
- "Change R(Reserved feature number)");
- else
- proto_tree_add_text(dcp_options_tree, tvb, offset, option_len,
- "Change R(CCID-specific features)");
- }
- break;
-
- case 35:
- feature_number = tvb_get_guint8(tvb, offset + 2);
- proto_tree_add_uint_hidden(dcp_options_tree, hf_dcp_feature_number, tvb, offset + 2, 1, feature_number);
-
- if( (feature_number < 10) && (feature_number!=0) ) {
- dcp_item = proto_tree_add_text(dcp_options_tree, tvb, offset, option_len,
- "Confirm R(%s",
- val_to_str(feature_number, dcp_feature_numbers_vals, "Unknown Type"));
- for (i = 0; i < option_len - 3; i++) {
- if(i==0)
- proto_item_append_text(dcp_item, "%d", tvb_get_guint8(tvb, offset + 3 + i));
- else
- proto_item_append_text(dcp_item, ", %d", tvb_get_guint8(tvb, offset + 3 + i));
- }
- proto_item_append_text(dcp_item, ")");
- } else {
- if(((feature_number>=10)&&(feature_number<=127))||(feature_number==0))
- proto_tree_add_text(dcp_options_tree, tvb, offset, option_len,
- "Confirm R(Reserved feature number)");
- else
- proto_tree_add_text(dcp_options_tree, tvb, offset, option_len,
- "Confirm R(CCID-specific features)");
- }
+ case 32 ... 35:
+ dissect_feature_options(dcp_options_tree, tvb, offset, option_len, option_type);
break;
case 36:
@@ -439,51 +429,30 @@ static void dissect_options(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *d
break;
case 37:
- if(option_len==3)
- proto_tree_add_uint(dcp_options_tree, hf_dcp_ndp_count, tvb, offset + 2, 1,
- tvb_get_guint8(tvb, offset + 2));
- else if (option_len==4)
- proto_tree_add_uint(dcp_options_tree, hf_dcp_ndp_count, tvb, offset + 2, 2,
- tvb_get_ntohs(tvb, offset + 2));
- else if (option_len==5)
- proto_tree_add_uint(dcp_options_tree, hf_dcp_ndp_count, tvb, offset + 2, 3,
- tvb_get_ntoh24(tvb, offset + 2));
+ if (option_len > 8)
+ proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "NDP Count too long (max 6 bytes)");
else
- proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "NDP Count too long (max 3 bytes)");
-
+ proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "NDP Count: %" G_GINT64_MODIFIER "u",
+ tvb_get_ntoh_var(tvb, offset + 2, option_len - 2));
break;
case 38:
- dcp_item = proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "Ack Vector0(");
- for (i = 0; i < option_len - 2; i++) {
- if(i==0)
- proto_item_append_text(dcp_item, "%02x", tvb_get_guint8(tvb, offset + 2 + i));
- else
- proto_item_append_text(dcp_item, " %02x", tvb_get_guint8(tvb, offset + 2 + i));
- }
- proto_item_append_text(dcp_item, ")");
+ dcp_item = proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "Ack Vector [Nonce 0]:");
+ for (i = 0; i < option_len - 2; i++)
+ proto_item_append_text(dcp_item, " %02x", tvb_get_guint8(tvb, offset + 2 + i));
break;
case 39:
- dcp_item = proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "Ack Vector1(");
- for (i = 0; i < option_len - 2; i++) {
- if(i==0)
- proto_item_append_text(dcp_item, "%02x", tvb_get_guint8(tvb, offset + 2 + i));
- else
- proto_item_append_text(dcp_item, " %02x", tvb_get_guint8(tvb, offset + 2 + i));
- }
+ dcp_item = proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "Ack Vector [Nonce 1]:");
+ for (i = 0; i < option_len - 2; i++)
+ proto_item_append_text(dcp_item, " %02x", tvb_get_guint8(tvb, offset + 2 + i));
proto_item_append_text(dcp_item, ")");
break;
case 40:
- dcp_item = proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "Data Dropped(");
- for (i = 0; i < option_len - 2; i++) {
- if(i==0)
- proto_item_append_text(dcp_item, "%02x", tvb_get_guint8(tvb, offset + 2 + i));
- else
- proto_item_append_text(dcp_item, " %02x", tvb_get_guint8(tvb, offset + 2 + i));
- }
- proto_item_append_text(dcp_item, ")");
+ dcp_item = proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "Data Dropped:");
+ for (i = 0; i < option_len - 2; i++)
+ proto_item_append_text(dcp_item, " %02x", tvb_get_guint8(tvb, offset + 2 + i));
break;
case 41:
@@ -533,7 +502,28 @@ static void dissect_options(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *d
} else
proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "Wrong Data checksum length");
break;
-
+ case 192: /* RFC 4342, 8.5 */
+ if(option_len == 6) {
+ p = tvb_get_ntohl(tvb, offset + 2);
+ /* According to the comment in section 8.5 of RFC 4342, 0xffffffff can mean zero */
+ if (p == 0xFFFFFFFF)
+ proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "CCID3 Loss Event Rate: 0 (or max)");
+ else
+ proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "CCID3 Loss Event Rate: %u", p);
+ } else
+ proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "Wrong CCID3 Loss Event Rate length");
+ break;
+ case 193: /* RFC 4342, 8.6 */
+ proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "CCID3 Loss Intervals");
+ /* FIXME: not implemented and apparently not used by any implementation so far */
+ break;
+ case 194: /* RFC 4342, 8.3 */
+ if(option_len == 6)
+ proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "CCID3 Receive Rate: %u bytes/sec",
+ tvb_get_ntohl(tvb, offset + 2));
+ else
+ proto_tree_add_text(dcp_options_tree, tvb, offset, option_len, "Wrong CCID3 Receive Rate length");
+ break;
default :
if(((option_type >= 45) && (option_type <= 127)) ||
((option_type >= 3) && (option_type <= 31))) {
@@ -1082,7 +1072,7 @@ void proto_register_dcp(void)
"", HFILL }},
{ &hf_dcp_ndp_count,
- { "NDP Count", "dcp.ndp_count", FT_UINT32, BASE_DEC, NULL, 0x0,
+ { "NDP Count", "dcp.ndp_count", FT_UINT64, BASE_DEC, NULL, 0x0,
"", HFILL }},
{ &hf_dcp_timestamp,