aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2018-04-18 19:33:34 -0700
committerGuy Harris <guy@alum.mit.edu>2018-04-19 02:34:11 +0000
commit735cfc8502e6dac8edfeb729e8c912ed897cb08b (patch)
treeb17a3be9a373335b6f0feff6f79265e4600ce050
parentd5c4c6972ed019e1cf52d268baecd41726760b90 (diff)
Clean up option handling.
If the option length is >= 2, so that it's long enough to include the code and length, always put it into the protocol tree, even if the length is invalid. If the length is invalid, attach an expert info item to the length field, rather than putting it into a top-level item of its own. Use a length of -1 for the top-level item for an option, rather than what the length is supposed to be; that way, we don't throw an exception if the option is too short - we just attach the aforementioned expert info item to the length. Change-Id: If2d987fa10739a7da28ca2c39515bfdf50da6ef9 Reviewed-on: https://code.wireshark.org/review/27018 Reviewed-by: Guy Harris <guy@alum.mit.edu>
-rw-r--r--epan/dissectors/packet-tcp.c259
1 files changed, 132 insertions, 127 deletions
diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c
index 03f6185a10..de73fdaf0d 100644
--- a/epan/dissectors/packet-tcp.c
+++ b/epan/dissectors/packet-tcp.c
@@ -330,6 +330,7 @@ static gint ett_tcp_option_wscale = -1;
static gint ett_tcp_option_sack = -1;
static gint ett_tcp_option_snack = -1;
static gint ett_tcp_option_scps = -1;
+static gint ett_tcp_scpsoption_flags = -1;
static gint ett_tcp_option_scps_extended = -1;
static gint ett_tcp_option_user_to = -1;
static gint ett_tcp_option_exp = -1;
@@ -3646,14 +3647,12 @@ tcp_info_append_uint(packet_info *pinfo, const char *abbrev, guint32 val)
}
static gboolean
-tcp_option_len_check(proto_tree* tree, packet_info *pinfo, tvbuff_t *tvb, int proto, guint len, guint optlen)
+tcp_option_len_check(proto_item* length_item, packet_info *pinfo, guint len, guint optlen)
{
if (len != optlen) {
/* Bogus - option length isn't what it's supposed to be for this option. */
- proto_tree_add_expert_format(tree, pinfo, &ei_tcp_opt_len_invalid, tvb, 0, len,
- "%s (with option length = %u byte%s; should be %u)",
- proto_get_protocol_short_name(find_protocol_by_id(proto)),
- len, plurality(len, "", "s"), optlen);
+ expert_add_info_format(pinfo, length_item, &ei_tcp_opt_len_invalid,
+ "option length should be %u", optlen);
return FALSE;
}
@@ -3665,16 +3664,17 @@ dissect_tcpopt_default_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
{
proto_item *item;
proto_tree *exp_tree;
+ proto_item *length_item;
int offset = 0;
- if (!tcp_option_len_check(tree, pinfo, tvb, proto, tvb_reported_length(tvb), 2))
- return tvb_captured_length(tvb);
-
- item = proto_tree_add_item(tree, proto, tvb, offset, 2, ENC_NA);
+ item = proto_tree_add_item(tree, proto, tvb, offset, -1, ENC_NA);
exp_tree = proto_item_add_subtree(item, ett);
proto_tree_add_item(exp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(exp_tree, hf_tcp_option_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
+ length_item = proto_tree_add_item(exp_tree, hf_tcp_option_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
+
+ if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), 2))
+ return tvb_captured_length(tvb);
return tvb_captured_length(tvb);
}
@@ -3721,14 +3721,14 @@ dissect_tcpopt_tfo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* da
{
proto_item *item;
proto_tree *exp_tree;
- int offset = 0, optlen = tvb_reported_length(tvb);
+ int offset = 0;
- item = proto_tree_add_item(tree, proto_tcp_option_tfo, tvb, offset, optlen, ENC_NA);
+ item = proto_tree_add_item(tree, proto_tcp_option_tfo, tvb, offset, -1, ENC_NA);
exp_tree = proto_item_add_subtree(item, ett_tcp_option_exp);
proto_tree_add_item(exp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(exp_tree, hf_tcp_option_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
- dissect_tcpopt_tfo_payload(tvb, offset, optlen, pinfo, exp_tree, data);
+ dissect_tcpopt_tfo_payload(tvb, offset, tvb_reported_length(tvb), pinfo, exp_tree, data);
return tvb_captured_length(tvb);
}
@@ -3740,7 +3740,7 @@ dissect_tcpopt_exp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* da
guint16 magic;
int offset = 0, optlen = tvb_reported_length(tvb);
- item = proto_tree_add_item(tree, proto_tcp_option_exp, tvb, offset, optlen, ENC_NA);
+ item = proto_tree_add_item(tree, proto_tcp_option_exp, tvb, offset, -1, ENC_NA);
exp_tree = proto_item_add_subtree(item, ett_tcp_option_exp);
proto_tree_add_item(exp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
@@ -3770,18 +3770,20 @@ dissect_tcpopt_sack_perm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, vo
{
proto_item *item;
proto_tree *exp_tree;
+ proto_item *length_item;
int offset = 0;
- if (!tcp_option_len_check(tree, pinfo, tvb, proto_tcp_option_sack_perm, tvb_reported_length(tvb), TCPOLEN_SACK_PERM))
- return tvb_captured_length(tvb);
-
- item = proto_tree_add_item(tree, proto_tcp_option_sack_perm, tvb, offset, TCPOLEN_SACK_PERM, ENC_NA);
+ item = proto_tree_add_item(tree, proto_tcp_option_sack_perm, tvb, offset, -1, ENC_NA);
exp_tree = proto_item_add_subtree(item, ett_tcp_option_sack_perm);
proto_tree_add_item(exp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(exp_tree, hf_tcp_option_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
+ length_item = proto_tree_add_item(exp_tree, hf_tcp_option_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
tcp_info_append_uint(pinfo, "SACK_PERM", TRUE);
+
+ if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), TCPOLEN_SACK_PERM))
+ return tvb_captured_length(tvb);
+
return tvb_captured_length(tvb);
}
@@ -3789,18 +3791,20 @@ static int
dissect_tcpopt_mss(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
proto_item *item;
- int offset = 0;
proto_tree *exp_tree;
+ proto_item *length_item;
+ int offset = 0;
guint32 mss;
- if (!tcp_option_len_check(tree, pinfo, tvb, proto_tcp_option_mss, tvb_reported_length(tvb), TCPOLEN_MSS))
- return tvb_captured_length(tvb);
-
- item = proto_tree_add_item(tree, proto_tcp_option_mss, tvb, offset, TCPOLEN_MSS, ENC_NA);
+ item = proto_tree_add_item(tree, proto_tcp_option_mss, tvb, offset, -1, ENC_NA);
exp_tree = proto_item_add_subtree(item, ett_tcp_option_mss);
proto_tree_add_item(exp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(exp_tree, hf_tcp_option_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
+ length_item = proto_tree_add_item(exp_tree, hf_tcp_option_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
+
+ if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), TCPOLEN_MSS))
+ return tvb_captured_length(tvb);
+
proto_tree_add_item_ret_uint(exp_tree, hf_tcp_option_mss_val, tvb, offset + 2, 2, ENC_BIG_ENDIAN, &mss);
proto_item_append_text(item, ": %u bytes", mss);
tcp_info_append_uint(pinfo, "MSS", mss);
@@ -3816,23 +3820,24 @@ dissect_tcpopt_wscale(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
guint32 shift;
proto_item *wscale_pi, *shift_pi, *gen_pi;
proto_tree *wscale_tree;
+ proto_item *length_item;
int offset = 0;
struct tcp_analysis *tcpd;
- if (!tcp_option_len_check(tree, pinfo, tvb, proto_tcp_option_wscale, tvb_reported_length(tvb), TCPOLEN_WINDOW))
- return tvb_captured_length(tvb);
-
tcpd=get_tcp_conversation_data(NULL,pinfo);
- wscale_pi = proto_tree_add_item(tree, proto_tcp_option_wscale, tvb, offset, TCPOLEN_WINDOW, ENC_NA);
+ wscale_pi = proto_tree_add_item(tree, proto_tcp_option_wscale, tvb, offset, -1, ENC_NA);
wscale_tree = proto_item_add_subtree(wscale_pi, ett_tcp_option_wscale);
proto_tree_add_item(wscale_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
- proto_tree_add_item(wscale_tree, hf_tcp_option_len, tvb, offset, 1, ENC_BIG_ENDIAN);
+ length_item = proto_tree_add_item(wscale_tree, hf_tcp_option_len, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
+ if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), TCPOLEN_WINDOW))
+ return tvb_captured_length(tvb);
+
shift_pi = proto_tree_add_item_ret_uint(wscale_tree, hf_tcp_option_wscale_shift, tvb, offset, 1, ENC_BIG_ENDIAN, &shift);
if (shift > 14) {
/* RFC 1323: "If a Window Scale option is received with a shift.cnt
@@ -3880,7 +3885,7 @@ dissect_tcpopt_sack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* d
}
}
- ti = proto_tree_add_item(tree, proto_tcp_option_sack, tvb, offset, optlen, ENC_NA);
+ ti = proto_tree_add_item(tree, proto_tcp_option_sack, tvb, offset, -1, ENC_NA);
field_tree = proto_item_add_subtree(ti, ett_tcp_option_sack);
proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
@@ -3942,19 +3947,21 @@ dissect_tcpopt_echo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* d
{
proto_tree *field_tree;
proto_item *item;
+ proto_item *length_item;
guint32 echo;
int offset = 0;
- if (!tcp_option_len_check(tree, pinfo, tvb, proto_tcp_option_echo, tvb_reported_length(tvb), TCPOLEN_ECHO))
- return tvb_captured_length(tvb);
-
- item = proto_tree_add_item(tree, proto_tcp_option_echo, tvb, offset, TCPOLEN_ECHO, ENC_NA);
+ item = proto_tree_add_item(tree, proto_tcp_option_echo, tvb, offset, -1, ENC_NA);
field_tree = proto_item_add_subtree(item, ett_tcp_opt_echo);
proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
+ length_item = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
offset + 1, 1, ENC_BIG_ENDIAN);
+
+ if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), TCPOLEN_ECHO))
+ return tvb_captured_length(tvb);
+
proto_tree_add_item_ret_uint(field_tree, hf_tcp_option_echo, tvb,
offset + 2, 4, ENC_BIG_ENDIAN, &echo);
@@ -3972,22 +3979,23 @@ dissect_tcpopt_timestamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, vo
{
proto_item *ti;
proto_tree *ts_tree;
+ proto_item *length_item;
int offset = 0;
guint32 ts_val, ts_ecr;
int len = tvb_reported_length(tvb);
- if (!tcp_option_len_check(tree, pinfo, tvb, proto_tcp_option_timestamp, len, TCPOLEN_TIMESTAMP))
- return tvb_captured_length(tvb);
-
- ti = proto_tree_add_item(tree, proto_tcp_option_timestamp, tvb, offset, TCPOLEN_TIMESTAMP, ENC_NA);
+ ti = proto_tree_add_item(tree, proto_tcp_option_timestamp, tvb, offset, -1, ENC_NA);
ts_tree = proto_item_add_subtree(ti, ett_tcp_option_timestamp);
proto_tree_add_item(ts_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
- proto_tree_add_item(ts_tree, hf_tcp_option_len, tvb, offset, 1, ENC_BIG_ENDIAN);
+ length_item = proto_tree_add_item(ts_tree, hf_tcp_option_len, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
+ if (!tcp_option_len_check(length_item, pinfo, len, TCPOLEN_TIMESTAMP))
+ return tvb_captured_length(tvb);
+
proto_tree_add_item_ret_uint(ts_tree, hf_tcp_option_timestamp_tsval, tvb, offset,
4, ENC_BIG_ENDIAN, &ts_val);
offset += 4;
@@ -4171,7 +4179,7 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
}
col_set_str(pinfo->cinfo, COL_PROTOCOL, "MPTCP");
- main_item = proto_tree_add_item(tree, proto_mptcp, tvb, offset, optlen, ENC_NA);
+ main_item = proto_tree_add_item(tree, proto_mptcp, tvb, offset, -1, ENC_NA);
mptcp_tree = proto_item_add_subtree(main_item, ett_tcp_option_mptcp);
proto_tree_add_item(mptcp_tree, hf_tcp_option_kind, tvb, offset, 1, ENC_BIG_ENDIAN);
@@ -4560,19 +4568,21 @@ dissect_tcpopt_cc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
{
proto_tree *field_tree;
proto_item *item;
+ proto_item *length_item;
int offset = 0;
guint32 cc;
- if (!tcp_option_len_check(tree, pinfo, tvb, proto_tcp_option_cc, tvb_reported_length(tvb), TCPOLEN_CC))
- return tvb_captured_length(tvb);
-
- item = proto_tree_add_item(tree, proto_tcp_option_cc, tvb, offset, TCPOLEN_CC, ENC_NA);
+ item = proto_tree_add_item(tree, proto_tcp_option_cc, tvb, offset, -1, ENC_NA);
field_tree = proto_item_add_subtree(item, ett_tcp_opt_cc);
proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
+ length_item = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
offset + 1, 1, ENC_BIG_ENDIAN);
+
+ if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), TCPOLEN_CC))
+ return tvb_captured_length(tvb);
+
proto_tree_add_item_ret_uint(field_tree, hf_tcp_option_cc, tvb,
offset + 2, 4, ENC_BIG_ENDIAN, &cc);
@@ -4585,19 +4595,21 @@ dissect_tcpopt_md5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* da
{
proto_tree *field_tree;
proto_item *item;
+ proto_item *length_item;
int offset = 0, optlen = tvb_reported_length(tvb);
- if (!tcp_option_len_check(tree, pinfo, tvb, proto_tcp_option_md5, optlen, TCPOLEN_MD5))
- return tvb_captured_length(tvb);
-
- item = proto_tree_add_item(tree, proto_tcp_option_md5, tvb, offset, TCPOLEN_MD5, ENC_NA);
+ item = proto_tree_add_item(tree, proto_tcp_option_md5, tvb, offset, -1, ENC_NA);
field_tree = proto_item_add_subtree(item, ett_tcp_opt_md5);
col_append_lstr(pinfo->cinfo, COL_INFO, " MD5", COL_ADD_LSTR_TERMINATOR);
proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
- offset + 1, 1, ENC_BIG_ENDIAN);
+ length_item = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
+ offset + 1, 1, ENC_BIG_ENDIAN);
+
+ if (!tcp_option_len_check(length_item, pinfo, optlen, TCPOLEN_MD5))
+ return tvb_captured_length(tvb);
+
proto_tree_add_item(field_tree, hf_tcp_option_md5_digest, tvb,
offset + 2, optlen - 2, ENC_NA);
@@ -4609,19 +4621,20 @@ dissect_tcpopt_qs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
{
proto_tree *field_tree;
proto_item *item;
+ proto_item *length_item;
guint8 rate;
int offset = 0;
- if (!tcp_option_len_check(tree, pinfo, tvb, proto_tcp_option_qs, tvb_reported_length(tvb), TCPOLEN_QS))
- return tvb_captured_length(tvb);
-
- item = proto_tree_add_item(tree, proto_tcp_option_qs, tvb, offset, TCPOLEN_QS, ENC_NA);
+ item = proto_tree_add_item(tree, proto_tcp_option_qs, tvb, offset, -1, ENC_NA);
field_tree = proto_item_add_subtree(item, ett_tcp_opt_qs);
proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
- offset + 1, 1, ENC_BIG_ENDIAN);
+ length_item = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
+ offset + 1, 1, ENC_BIG_ENDIAN);
+
+ if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), TCPOLEN_QS))
+ return tvb_captured_length(tvb);
rate = tvb_get_guint8(tvb, offset + 2) & 0x0f;
col_append_lstr(pinfo->cinfo, COL_INFO,
@@ -4643,6 +4656,7 @@ dissect_tcpopt_scps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* d
tcp_flow_t *flow;
int direction;
proto_item *tf = NULL, *item;
+ proto_tree *flags_tree = NULL;
guint8 capvector;
guint8 connid;
int offset = 0, optlen = tvb_reported_length(tvb);
@@ -4662,37 +4676,36 @@ dissect_tcpopt_scps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* d
else
flow =&(tcpd->flow2);
+ item = proto_tree_add_item(tree, proto_tcp_option_scps,
+ tvb, offset, -1, ENC_NA);
+ field_tree = proto_item_add_subtree(item, ett_tcp_option_scps);
+
+ proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
+ offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
+ offset + 1, 1, ENC_BIG_ENDIAN);
+
/* If the option length == 4, this is a real SCPS capability option
* See "CCSDS 714.0-B-2 (CCSDS Recommended Standard for SCPS Transport Protocol
* (SCPS-TP)" Section 3.2.3 for definition.
*/
if (optlen == 4) {
- item = proto_tree_add_item(tree, proto_tcp_option_scps,
- tvb, offset, optlen, ENC_NA);
- PROTO_ITEM_SET_HIDDEN(item);
-
- capvector = tvb_get_guint8(tvb, offset + 2);
- connid = tvb_get_guint8(tvb, offset + 3);
-
- tf = proto_tree_add_item(tree, hf_tcp_option_scps_vector, tvb,
+ tf = proto_tree_add_item(field_tree, hf_tcp_option_scps_vector, tvb,
offset + 2, 1, ENC_BIG_ENDIAN);
- field_tree = proto_item_add_subtree(tf, ett_tcp_option_scps);
- proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
- offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
- offset + 1, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(field_tree, hf_tcp_scpsoption_flags_bets, tvb,
+ flags_tree = proto_item_add_subtree(tf, ett_tcp_scpsoption_flags);
+ proto_tree_add_item(flags_tree, hf_tcp_scpsoption_flags_bets, tvb,
offset + 2, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(field_tree, hf_tcp_scpsoption_flags_snack1, tvb,
+ proto_tree_add_item(flags_tree, hf_tcp_scpsoption_flags_snack1, tvb,
offset + 2, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(field_tree, hf_tcp_scpsoption_flags_snack2, tvb,
+ proto_tree_add_item(flags_tree, hf_tcp_scpsoption_flags_snack2, tvb,
offset + 2, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(field_tree, hf_tcp_scpsoption_flags_compress, tvb,
+ proto_tree_add_item(flags_tree, hf_tcp_scpsoption_flags_compress, tvb,
offset + 2, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(field_tree, hf_tcp_scpsoption_flags_nlts, tvb,
+ proto_tree_add_item(flags_tree, hf_tcp_scpsoption_flags_nlts, tvb,
offset + 2, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(field_tree, hf_tcp_scpsoption_flags_reserved, tvb,
+ proto_tree_add_item(flags_tree, hf_tcp_scpsoption_flags_reserved, tvb,
offset + 2, 1, ENC_BIG_ENDIAN);
+ capvector = tvb_get_guint8(tvb, offset + 2);
if (capvector) {
struct capvec
@@ -4728,6 +4741,7 @@ dissect_tcpopt_scps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* d
proto_tree_add_item(field_tree, hf_tcp_scpsoption_connection_id, tvb,
offset + 3, 1, ENC_BIG_ENDIAN);
+ connid = tvb_get_guint8(tvb, offset + 3);
flow->scps_capable = 1;
if (connid)
@@ -4747,25 +4761,13 @@ dissect_tcpopt_scps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* d
if (flow->scps_capable != 1) {
/* There was no SCPS capabilities option preceding this */
- tf = proto_tree_add_uint_format(tree, hf_tcp_option_scps_vector,
- tvb, offset, optlen, 0,
- "Illegal SCPS Extended Capabilities (%d bytes)",
- optlen);
- field_tree=proto_item_add_subtree(tf, ett_tcp_option_scps_extended);
- proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
- offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
- offset + 1, 1, ENC_BIG_ENDIAN);
+ proto_item_set_text(item,
+ "Illegal SCPS Extended Capabilities (%u bytes)",
+ optlen);
} else {
- tf = proto_tree_add_uint_format(tree, hf_tcp_option_scps_vector,
- tvb, offset, optlen, 0,
- "SCPS Extended Capabilities (%d bytes)",
- optlen);
- field_tree=proto_item_add_subtree(tf, ett_tcp_option_scps_extended);
- proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
- offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
- offset + 1, 1, ENC_BIG_ENDIAN);
+ proto_item_set_text(item,
+ "SCPS Extended Capabilities (%u bytes)",
+ optlen);
/* There may be multiple binding spaces included in a single option,
* so we will semi-parse each of the stacked binding spaces - skipping
@@ -4815,19 +4817,20 @@ dissect_tcpopt_user_to(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
{
proto_item *tf;
proto_tree *field_tree;
+ proto_item *length_item;
guint16 to;
int offset = 0;
- if (!tcp_option_len_check(tree, pinfo, tvb, proto_tcp_option_user_to, tvb_reported_length(tvb), TCPOLEN_USER_TO))
- return tvb_captured_length(tvb);
-
- tf = proto_tree_add_item(tree, proto_tcp_option_user_to, tvb, offset, TCPOLEN_USER_TO, ENC_NA);
+ tf = proto_tree_add_item(tree, proto_tcp_option_user_to, tvb, offset, -1, ENC_NA);
field_tree = proto_item_add_subtree(tf, ett_tcp_option_user_to);
proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
- offset + 1, 1, ENC_BIG_ENDIAN);
+ length_item = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
+ offset + 1, 1, ENC_BIG_ENDIAN);
+
+ if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), TCPOLEN_USER_TO))
+ return tvb_captured_length(tvb);
proto_tree_add_item(field_tree, hf_tcp_option_user_to_granularity, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
to = tvb_get_ntohs(tvb, offset + 2) & 0x7FFF;
@@ -4874,17 +4877,18 @@ dissect_tcpopt_snack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
int offset = 0;
proto_item *hidden_item, *tf;
proto_tree *field_tree;
+ proto_item *length_item;
- if (!tcp_option_len_check(tree, pinfo, tvb, proto_tcp_option_snack, tvb_reported_length(tvb), TCPOLEN_SNACK))
- return tvb_captured_length(tvb);
-
- tf = proto_tree_add_item(tree, proto_tcp_option_snack, tvb, offset, TCPOLEN_SNACK, ENC_NA);
+ tf = proto_tree_add_item(tree, proto_tcp_option_snack, tvb, offset, -1, ENC_NA);
field_tree = proto_item_add_subtree(tf, ett_tcp_option_snack);
proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
- offset + 1, 1, ENC_BIG_ENDIAN);
+ length_item = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
+ offset + 1, 1, ENC_BIG_ENDIAN);
+
+ if (!tcp_option_len_check(length_item, pinfo, tvb_reported_length(tvb), TCPOLEN_SNACK))
+ return tvb_captured_length(tvb);
tcpd = get_tcp_conversation_data(NULL,pinfo);
@@ -5035,23 +5039,28 @@ dissect_tcpopt_rvbd_probe(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, v
guint8 ver, type;
proto_tree *field_tree;
proto_item *pitem;
+ proto_item *length_item;
int offset = 0,
optlen = tvb_reported_length(tvb);
struct tcpheader *tcph = (struct tcpheader*)data;
+ pitem = proto_tree_add_item(tree, proto_tcp_option_rvbd_probe, tvb, offset, -1, ENC_NA);
+ field_tree = proto_item_add_subtree(pitem, ett_tcp_opt_rvbd_probe);
+
+ proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
+ offset, 1, ENC_BIG_ENDIAN);
+ length_item = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
+ offset + 1, 1, ENC_BIG_ENDIAN);
+
if (optlen < TCPOLEN_RVBD_PROBE_MIN) {
/* Bogus - option length is less than what it's supposed to be for
this option. */
- proto_tree_add_expert_format(tree, pinfo, &ei_tcp_opt_len_invalid, tvb, offset, optlen,
- "%s (with option length = %u bytes; should be >= %u)",
- proto_get_protocol_short_name(find_protocol_by_id(proto_tcp_option_rvbd_probe)),
- optlen, TCPOLEN_RVBD_PROBE_MIN);
+ expert_add_info_format(pinfo, length_item, &ei_tcp_opt_len_invalid,
+ "option length should be >= %u)",
+ TCPOLEN_RVBD_PROBE_MIN);
return tvb_captured_length(tvb);
}
- pitem = proto_tree_add_item(tree, proto_tcp_option_rvbd_probe, tvb, offset, optlen, ENC_NA);
- field_tree = proto_item_add_subtree(pitem, ett_tcp_opt_rvbd_probe);
-
rvbd_probe_decode_version_type(
tvb_get_guint8(tvb, offset + PROBE_VERSION_TYPE_OFFSET),
&ver, &type);
@@ -5061,12 +5070,6 @@ dissect_tcpopt_rvbd_probe(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, v
if (type >= PROBE_TYPE_MAX)
return tvb_captured_length(tvb);
- /* optlen, type, ver are common for all probes */
- proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
- offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
- offset + PROBE_OPTLEN_OFFSET, 1, ENC_BIG_ENDIAN);
-
if (ver == PROBE_VERSION_1) {
guint16 port;
@@ -5268,6 +5271,7 @@ dissect_tcpopt_rvbd_trpy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, vo
{
proto_tree *field_tree;
proto_item *pitem;
+ proto_item *length_item;
guint16 sport, dport, flags;
int offset = 0,
optlen = tvb_reported_length(tvb);
@@ -5281,18 +5285,18 @@ dissect_tcpopt_rvbd_trpy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, vo
NULL
};
- if (!tcp_option_len_check(tree, pinfo, tvb, proto_tcp_option_rvbd_trpy, optlen, TCPOLEN_RVBD_TRPY_MIN))
- return tvb_captured_length(tvb);
-
col_prepend_fstr(pinfo->cinfo, COL_INFO, "TRPY, ");
- pitem = proto_tree_add_item(tree, proto_tcp_option_rvbd_trpy, tvb, offset, TCPOLEN_RVBD_TRPY_MIN, ENC_NA);
+ pitem = proto_tree_add_item(tree, proto_tcp_option_rvbd_trpy, tvb, offset, -1, ENC_NA);
field_tree = proto_item_add_subtree(pitem, ett_tcp_opt_rvbd_trpy);
proto_tree_add_item(field_tree, hf_tcp_option_kind, tvb,
offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
- offset + PROBE_OPTLEN_OFFSET, 1, ENC_BIG_ENDIAN);
+ length_item = proto_tree_add_item(field_tree, hf_tcp_option_len, tvb,
+ offset + 1, 1, ENC_BIG_ENDIAN);
+
+ if (!tcp_option_len_check(length_item, pinfo, optlen, TCPOLEN_RVBD_TRPY_MIN))
+ return tvb_captured_length(tvb);
flags = tvb_get_ntohs(tvb, offset + TRPY_OPTIONS_OFFSET);
proto_tree_add_bitmask_with_flags(field_tree, tvb, offset + TRPY_OPTIONS_OFFSET, hf_tcp_option_rvbd_trpy_flags,
@@ -7256,6 +7260,7 @@ proto_register_tcp(void)
&ett_tcp_option_sack,
&ett_tcp_option_snack,
&ett_tcp_option_scps,
+ &ett_tcp_scpsoption_flags,
&ett_tcp_option_scps_extended,
&ett_tcp_option_user_to,
&ett_tcp_option_exp,