General cleanup including:

1. Convert proto_tree_add_text to proto_tree_add_item/expert info
2. Change to "new style" dissector
3. Use standard malformed packet interface

Reviewed by Francesco Fondelli

svn path=/trunk/; revision=48009
This commit is contained in:
Michael Mann 2013-03-02 16:00:43 +00:00
parent 9991973c37
commit f473d9a3d7
1 changed files with 182 additions and 243 deletions

View File

@ -57,6 +57,7 @@
#include <epan/ipproto.h>
#include <epan/in_cksum.h>
#include <epan/prefs.h>
#include <epan/expert.h>
#include <epan/emem.h>
#include "packet-ip.h"
#include <epan/conversation.h>
@ -175,8 +176,6 @@ static int hf_dccp_timestamp_echo = -1;
static int hf_dccp_elapsed_time = -1;
static int hf_dccp_data_checksum = -1;
static int hf_dccp_malformed = -1;
static gint ett_dccp = -1;
static gint ett_dccp_options = -1;
@ -388,43 +387,37 @@ dissect_options(tvbuff_t *tvb, packet_info *pinfo _U_,
int i;
guint32 p;
proto_item *dccp_item = NULL;
proto_item *hidden_item;
proto_item *option_item;
while (offset < offset_end) {
/* first byte is the option type */
option_type = tvb_get_guint8(tvb, offset);
hidden_item =
option_item =
proto_tree_add_uint(dccp_options_tree, hf_dccp_option_type, tvb,
offset,
1,
option_type);
PROTO_ITEM_SET_HIDDEN(hidden_item);
PROTO_ITEM_SET_HIDDEN(option_item);
if (option_type >= 32) { /* variable length options */
if (!tvb_bytes_exist(tvb, offset, 1)) {
hidden_item =
proto_tree_add_boolean(dccp_options_tree, hf_dccp_malformed,
tvb, offset, 0, TRUE);
PROTO_ITEM_SET_HIDDEN(hidden_item);
THROW(ReportedBoundsError);
expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR,
"Option length incorrect");
return;
}
option_len = tvb_get_guint8(tvb, offset + 1);
if (option_len < 2) {
hidden_item =
proto_tree_add_boolean(dccp_options_tree, hf_dccp_malformed,
tvb, offset, 0, TRUE);
PROTO_ITEM_SET_HIDDEN(hidden_item);
THROW(ReportedBoundsError);
expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR,
"Option length incorrect");
return;
}
if (!tvb_bytes_exist(tvb, offset, option_len)) {
hidden_item =
proto_tree_add_boolean(dccp_options_tree, hf_dccp_malformed,
tvb, offset, 0, TRUE);
PROTO_ITEM_SET_HIDDEN(hidden_item);
THROW(ReportedBoundsError);
expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR,
"Option length incorrect");
return;
}
} else { /* 1byte options */
option_len = 1;
@ -466,7 +459,7 @@ dissect_options(tvbuff_t *tvb, packet_info *pinfo _U_,
break;
case 37:
if (option_len > 8)
proto_tree_add_text(dccp_options_tree, tvb, offset, option_len,
expert_add_info_format(pinfo, option_item, PI_PROTOCOL, PI_WARN,
"NDP Count too long (max 6 bytes)");
else
proto_tree_add_text(dccp_options_tree, tvb, offset, option_len,
@ -505,7 +498,7 @@ dissect_options(tvbuff_t *tvb, packet_info *pinfo _U_,
offset + 2, 4,
tvb_get_ntohl(tvb, offset + 2));
else
proto_tree_add_text(dccp_options_tree, tvb, offset, option_len,
expert_add_info_format(pinfo, option_item, PI_PROTOCOL, PI_WARN,
"Timestamp too long [%u != 6]", option_len);
break;
case 42:
@ -528,7 +521,7 @@ dissect_options(tvbuff_t *tvb, packet_info *pinfo _U_,
tvb, offset + 6, 4,
tvb_get_ntohl(tvb, offset + 6));
} else
proto_tree_add_text(dccp_options_tree, tvb, offset, option_len,
expert_add_info_format(pinfo, option_item, PI_PROTOCOL, PI_WARN,
"Wrong Timestamp Echo length");
break;
case 43:
@ -541,7 +534,7 @@ dissect_options(tvbuff_t *tvb, packet_info *pinfo _U_,
tvb, offset + 2, 4,
tvb_get_ntohl(tvb, offset + 2));
else
proto_tree_add_text(dccp_options_tree, tvb, offset, option_len,
expert_add_info_format(pinfo, option_item, PI_PROTOCOL, PI_WARN,
"Wrong Elapsed Time length");
break;
case 44:
@ -550,7 +543,7 @@ dissect_options(tvbuff_t *tvb, packet_info *pinfo _U_,
tvb, offset + 2, 4,
tvb_get_ntohl(tvb, offset + 2));
} else
proto_tree_add_text(dccp_options_tree, tvb, offset, option_len,
expert_add_info_format(pinfo, option_item, PI_PROTOCOL, PI_WARN,
"Wrong Data checksum length");
break;
case 192: /* RFC 4342, 8.5 */
@ -569,7 +562,7 @@ dissect_options(tvbuff_t *tvb, packet_info *pinfo _U_,
option_len, "CCID3 Loss Event Rate: %u",
p);
} else
proto_tree_add_text(dccp_options_tree, tvb, offset, option_len,
expert_add_info_format(pinfo, option_item, PI_PROTOCOL, PI_WARN,
"Wrong CCID3 Loss Event Rate length");
break;
case 193: /* RFC 4342, 8.6 */
@ -586,7 +579,7 @@ dissect_options(tvbuff_t *tvb, packet_info *pinfo _U_,
"CCID3 Receive Rate: %u bytes/sec",
tvb_get_ntohl(tvb, offset + 2));
else
proto_tree_add_text(dccp_options_tree, tvb, offset, option_len,
expert_add_info_format(pinfo, option_item, PI_PROTOCOL, PI_WARN,
"Wrong CCID3 Receive Rate length");
break;
default:
@ -628,13 +621,13 @@ dccp_csum_coverage(const e_dccphdr *dccph, guint len)
return (cov > len) ? len : cov;
}
static void
dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static int
dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
proto_tree *dccp_tree = NULL;
proto_tree *dccp_tree;
proto_tree *dccp_options_tree = NULL;
proto_item *dccp_item = NULL;
proto_item *hidden_item;
proto_item *hidden_item, *offset_item;
vec_t cksum_vec[4];
guint32 phdr[2];
@ -647,16 +640,8 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
e_dccphdr *dccph;
/* get at least a full message header */
if (tvb_length(tvb) < DCCP_HDR_LEN_MIN) {
if (tree) {
hidden_item =
proto_tree_add_boolean(dccp_tree, hf_dccp_malformed, tvb,
offset, 0, TRUE);
PROTO_ITEM_SET_HIDDEN(hidden_item);
}
col_set_str(pinfo->cinfo, COL_INFO, "Packet too short");
THROW(ReportedBoundsError);
}
if (tvb_length(tvb) < DCCP_HDR_LEN_MIN)
return 0;
dccph = ep_alloc0(sizeof (e_dccphdr));
@ -693,11 +678,8 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (dccph->x) {
if (tvb_length(tvb) < DCCP_HDR_LEN) { /* at least 16 bytes */
hidden_item =
proto_tree_add_boolean(dccp_tree, hf_dccp_malformed, tvb,
offset, 0, TRUE);
PROTO_ITEM_SET_HIDDEN(hidden_item);
THROW(ReportedBoundsError);
expert_add_info_format(pinfo, dccp_item, PI_MALFORMED, PI_ERROR, "DCCP Header length too short");
return tvb_length(tvb);
}
dccph->reserved2 = tvb_get_guint8(tvb, offset + 9);
@ -717,7 +699,6 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
val_to_str_const(dccph->type, dccp_packet_type_vals, "Unknown Type"),
dccph->seq);
if (tree) {
if (dccp_summary_in_tree) {
dccp_item =
proto_tree_add_protocol_format(
@ -756,7 +737,7 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
dccph->dport);
PROTO_ITEM_SET_HIDDEN(hidden_item);
proto_tree_add_uint(dccp_tree, hf_dccp_data_offset, tvb, offset + 4, 1,
offset_item = proto_tree_add_uint(dccp_tree, hf_dccp_data_offset, tvb, offset + 4, 1,
dccph->data_offset);
proto_tree_add_uint(dccp_tree, hf_dccp_ccval, tvb, offset + 5, 1,
dccph->ccval);
@ -850,7 +831,6 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_uint64(dccp_tree, hf_dccp_seq, tvb, offset + 9, 3,
dccph->seq);
}
}
if (dccph->x)
offset += 16; /* move offset past the extended Generic header */
@ -862,10 +842,8 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
case 0x0: /* DCCP-Request */
case 0xA: /* DCCP-Listen */
if (!tvb_bytes_exist(tvb, offset, 4)) { /* at least 4 byte */
if (tree)
proto_tree_add_text(dccp_tree, tvb, offset, -1,
"too short packet");
return;
expert_add_info_format(pinfo, dccp_item, PI_MALFORMED, PI_ERROR, "too short packet");
return tvb_length(tvb);
}
dccph->service_code = tvb_get_ntohl(tvb, offset);
if (tree)
@ -877,10 +855,8 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
break;
case 0x1: /* DCCP-Response */
if (!tvb_bytes_exist(tvb, offset, 8)) { /* at least 8 byte */
if (tree)
proto_tree_add_text(dccp_tree, tvb, offset, -1,
"too short packet");
return;
expert_add_info_format(pinfo, dccp_item, PI_MALFORMED, PI_ERROR, "too short packet");
return tvb_length(tvb);
}
dccph->ack_reserved = tvb_get_ntohs(tvb, offset);
if (tree) {
@ -902,10 +878,8 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
offset += 8; /* move offset past the Acknowledgement Number Subheader */
if (!tvb_bytes_exist(tvb, offset, 4)) { /* at least 4 byte */
if (tree)
proto_tree_add_text(dccp_tree, tvb, offset, -1,
"too short packet");
return;
expert_add_info_format(pinfo, dccp_item, PI_MALFORMED, PI_ERROR, "too short packet");
return tvb_length(tvb);
}
dccph->service_code = tvb_get_ntohl(tvb, offset);
if (tree)
@ -923,10 +897,8 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
case 0x4: /* DCCP-DataAck */
if (dccph->x) {
if (!tvb_bytes_exist(tvb, offset, 8)) { /* at least 8 byte */
if (tree)
proto_tree_add_text(dccp_tree, tvb, offset, -1,
"too short packet");
return;
expert_add_info_format(pinfo, dccp_item, PI_MALFORMED, PI_ERROR, "too short packet");
return tvb_length(tvb);
}
dccph->ack_reserved = tvb_get_ntohs(tvb, offset);
if (tree) {
@ -947,10 +919,8 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
offset += 8; /* move offset past the Ack Number Subheader */
} else {
if (!tvb_bytes_exist(tvb, offset, 4)) { /* at least 4 byte */
if (tree)
proto_tree_add_text(dccp_tree, tvb, offset, -1,
"too short packet");
return;
expert_add_info_format(pinfo, dccp_item, PI_MALFORMED, PI_ERROR, "too short packet");
return tvb_length(tvb);
}
dccph->ack_reserved = tvb_get_guint8(tvb, offset);
if (tree) {
@ -972,10 +942,8 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
break;
case 0x7: /* DCCP-Reset */
if (!tvb_bytes_exist(tvb, offset, 8)) { /* at least 8 byte */
if (tree)
proto_tree_add_text(dccp_tree, tvb, offset, -1,
"too short packet");
return;
expert_add_info_format(pinfo, dccp_item, PI_MALFORMED, PI_ERROR, "too short packet");
return tvb_length(tvb);
}
dccph->ack_reserved = tvb_get_ntohs(tvb, offset);
@ -1024,10 +992,8 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
case 0x8: /* DCCP-Sync */
case 0x9: /* DCCP-SyncAck */
if (!tvb_bytes_exist(tvb, offset, 8)) { /* at least 8 byte */
if (tree)
proto_tree_add_text(dccp_tree, tvb, offset, -1,
"too short packet");
return;
expert_add_info_format(pinfo, dccp_item, PI_MALFORMED, PI_ERROR, "too short packet");
return tvb_length(tvb);
}
dccph->ack_reserved = tvb_get_ntohs(tvb, offset);
if (tree) {
@ -1047,11 +1013,9 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
offset += 8; /* move offset past the Ack. Number Subheader */
break;
default:
if (tree)
proto_tree_add_text(
dccp_tree, tvb, offset, -1,
expert_add_info_format(pinfo, dccp_item, PI_PROTOCOL, PI_WARN,
"Reserved packet type: unable to dissect further");
return;
return tvb_length(tvb);
}
/*
@ -1064,33 +1028,22 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
options_len = advertised_dccp_header_len - offset;
if (advertised_dccp_header_len > DCCP_HDR_LEN_MAX) {
if (tree)
proto_tree_add_text(
dccp_tree, tvb, 4, 2,
"bogus data offset, advertised header length (%d) is "
"larger than max (%d)",
expert_add_info_format(pinfo, offset_item, PI_MALFORMED, PI_ERROR,
"bogus data offset, advertised header length (%d) is larger than max (%d)",
advertised_dccp_header_len, DCCP_HDR_LEN_MAX);
return;
return tvb_length(tvb);
}
if (tvb_length(tvb) < advertised_dccp_header_len) {
if (tree)
proto_tree_add_text(
dccp_tree, tvb, offset, -1,
expert_add_info_format(pinfo, offset_item, PI_MALFORMED, PI_ERROR,
"too short packet: missing %d bytes of DCCP header",
advertised_dccp_header_len -
tvb_reported_length_remaining(tvb, offset));
return;
advertised_dccp_header_len - tvb_reported_length_remaining(tvb, offset));
return tvb_length(tvb);
}
if (options_len > DCCP_OPT_LEN_MAX) {
if (tree) {
hidden_item =
proto_tree_add_boolean(dccp_tree, hf_dccp_malformed, tvb,
offset, 0, TRUE);
PROTO_ITEM_SET_HIDDEN(hidden_item);
}
THROW(ReportedBoundsError);
expert_add_info_format(pinfo, dccp_item, PI_MALFORMED, PI_ERROR, "DCCP Option length too large");
return tvb_length(tvb);
}
/*
@ -1100,18 +1053,10 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (advertised_dccp_header_len == offset) {
; /* ok no options, no need to move the offset forward */
} else if (advertised_dccp_header_len < offset) {
if (tree) {
proto_tree_add_text(
dccp_tree, tvb, 4, 2,
"bogus data offset, advertised header length (%d) is "
"shorter than expected",
expert_add_info_format(pinfo, offset_item, PI_MALFORMED, PI_ERROR,
"bogus data offset, advertised header length (%d) is shorter than expected",
advertised_dccp_header_len);
hidden_item =
proto_tree_add_boolean(dccp_tree, hf_dccp_malformed, tvb,
offset, 0, TRUE);
PROTO_ITEM_SET_HIDDEN(hidden_item);
}
THROW(ReportedBoundsError);
return tvb_length(tvb);
} else {
if (dccp_tree) {
dccp_item =
@ -1134,6 +1079,8 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* call sub-dissectors */
if (!pinfo->flags.in_error_pkt || tvb_length_remaining(tvb, offset) > 0)
decode_dccp_ports(tvb, offset, pinfo, tree, dccph->sport, dccph->dport);
return tvb_length(tvb);
}
void
@ -1360,14 +1307,6 @@ proto_register_dccp(void)
NULL, HFILL
}
},
{
&hf_dccp_malformed,
{
"Malformed", "dccp.malformed",
FT_BOOLEAN, BASE_NONE, NULL, 0x0,
NULL, HFILL
}
},
{
&hf_dccp_options,
{
@ -1423,7 +1362,7 @@ proto_reg_handoff_dccp(void)
{
dissector_handle_t dccp_handle;
dccp_handle = create_dissector_handle(dissect_dccp, proto_dccp);
dccp_handle = new_create_dissector_handle(dissect_dccp, proto_dccp);
dissector_add_uint("ip.proto", IP_PROTO_DCCP, dccp_handle);
data_handle = find_dissector("data");
dccp_tap = register_tap("dccp");