summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Mathieson <martin.r.mathieson@googlemail.com>2012-11-12 03:55:46 +0000
committerMartin Mathieson <martin.r.mathieson@googlemail.com>2012-11-12 03:55:46 +0000
commit0aebd579e3be3595a1324bcd3bbe688e60cf5e46 (patch)
tree0dae3163baafaf55feee706b07e15d4812b46741
parent748f35f1e154c7c4bd26758f78e85b7e4b02e6ea (diff)
downloadwireshark-0aebd579e3be3595a1324bcd3bbe688e60cf5e46.tar.gz
Show SACK information in TCP graphs. Also add a generated field for the
number of SACK ranges found in the SACK option. This involved extending the IP options framework to include an extra void* data field, which in the case of TCP is filled in with the tap struct - other users currently pass NULL. I first implemented the graph to sort the SACK ranges and show (in red) the unacknowledged regions between them, but this became confusing where the number of ranges is limited by TCP padding bytes. i.e. you can't tell how many SACKs could have been encoded, so some of the gaps between ranges may already have been received. svn path=/trunk/; revision=46006
-rw-r--r--epan/dissectors/packet-ip.c49
-rw-r--r--epan/dissectors/packet-ppp.c273
-rw-r--r--epan/dissectors/packet-tcp.c57
-rw-r--r--epan/dissectors/packet-tcp.h6
-rw-r--r--epan/ip_opts.h6
-rw-r--r--ui/gtk/tcp_graph.c73
6 files changed, 288 insertions, 176 deletions
diff --git a/epan/dissectors/packet-ip.c b/epan/dissectors/packet-ip.c
index 7146f4bced..d1957d8a35 100644
--- a/epan/dissectors/packet-ip.c
+++ b/epan/dissectors/packet-ip.c
@@ -660,7 +660,7 @@ dissect_ipopt_type(tvbuff_t *tvb, int offset, proto_tree *tree)
static void
dissect_ipopt_eool(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
guint optlen _U_, packet_info *pinfo _U_,
- proto_tree *opt_tree)
+ proto_tree *opt_tree, void * data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -732,7 +732,8 @@ static const int *ip_opt_sec_prot_auth_fields_byte_n[] = {
};
static void
dissect_ipopt_security(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ guint optlen, packet_info *pinfo, proto_tree *opt_tree,
+ void * data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -803,7 +804,8 @@ dissect_ipopt_security(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_ipopt_ext_security(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ guint optlen, packet_info *pinfo, proto_tree *opt_tree,
+ void * data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -842,7 +844,8 @@ dissect_ipopt_ext_security(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
* http://tools.ietf.org/html/draft-ietf-cipso-ipsecurity-01 */
static void
dissect_ipopt_cipso(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ guint optlen, packet_info *pinfo, proto_tree *opt_tree,
+ void * data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -1103,7 +1106,8 @@ dissect_option_route(proto_tree *tree, tvbuff_t *tvb, int offset, int hf,
static void
dissect_ipopt_route(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ guint optlen, packet_info *pinfo, proto_tree *opt_tree,
+ void * data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -1187,7 +1191,7 @@ dissect_ipopt_route(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_ipopt_record_route(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
guint optlen, packet_info *pinfo,
- proto_tree *opt_tree)
+ proto_tree *opt_tree, void * data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -1251,7 +1255,8 @@ dissect_ipopt_record_route(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
/* Stream Identifier */
static void
dissect_ipopt_sid(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ guint optlen, packet_info *pinfo, proto_tree *opt_tree,
+ void * data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -1270,7 +1275,8 @@ dissect_ipopt_sid(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
/* RFC 1063: MTU Probe and MTU Reply */
static void
dissect_ipopt_mtu(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ guint optlen, packet_info *pinfo, proto_tree *opt_tree,
+ void * data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -1289,7 +1295,8 @@ dissect_ipopt_mtu(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
/* RFC 1393: Traceroute */
static void
dissect_ipopt_tr(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ guint optlen, packet_info *pinfo, proto_tree *opt_tree,
+ void * data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -1312,7 +1319,7 @@ dissect_ipopt_tr(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_ipopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
int offset, guint optlen, packet_info *pinfo,
- proto_tree *opt_tree)
+ proto_tree *opt_tree, void * data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -1395,7 +1402,8 @@ static const range_string ra_rvals[] = {
static void
dissect_ipopt_ra(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ guint optlen, packet_info *pinfo, proto_tree *opt_tree,
+ void * data _U_)
{
/* Router-Alert, as defined by RFC2113 */
proto_tree *field_tree;
@@ -1418,7 +1426,8 @@ dissect_ipopt_ra(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
/* RFC 1770: Selective Directed Broadcast */
static void
dissect_ipopt_sdb(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ guint optlen, packet_info *pinfo, proto_tree *opt_tree,
+ void * data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -1467,7 +1476,8 @@ value_string_ext qs_rate_vals_ext = VALUE_STRING_EXT_INIT(qs_rate_vals);
static void
dissect_ipopt_qs(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ guint optlen, packet_info *pinfo, proto_tree *opt_tree,
+ void * data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -1587,8 +1597,8 @@ static const ip_tcp_opt ipopts[] = {
void
dissect_ip_tcp_options(tvbuff_t *tvb, int offset, guint length,
const ip_tcp_opt *opttab, int nopts, int eol,
- packet_info *pinfo, proto_tree *opt_tree,
- proto_item *opt_item)
+ packet_info *pinfo, proto_tree *opt_tree,
+ proto_item *opt_item, void * data)
{
guchar opt;
const ip_tcp_opt *optp;
@@ -1596,7 +1606,8 @@ dissect_ip_tcp_options(tvbuff_t *tvb, int offset, guint length,
unsigned int optlen;
const char *name;
void (*dissect)(const struct ip_tcp_opt *, tvbuff_t *,
- int, guint, packet_info *, proto_tree *);
+ int, guint, packet_info *, proto_tree *,
+ void *);
guint len, nop_count = 0;
while (length > 0) {
@@ -1679,7 +1690,7 @@ dissect_ip_tcp_options(tvbuff_t *tvb, int offset, guint length,
/* Option has a dissector. */
proto_item_append_text(proto_tree_get_parent(opt_tree), ", %s",
optp->name);
- (*dissect)(optp, tvb, offset, len, pinfo, opt_tree);
+ (*dissect)(optp, tvb, offset, len, pinfo, opt_tree, data);
} else {
proto_tree *field_tree;
proto_item *tf;
@@ -1700,7 +1711,7 @@ dissect_ip_tcp_options(tvbuff_t *tvb, int offset, guint length,
if (dissect != NULL) {
proto_item_append_text(proto_tree_get_parent(opt_tree), ", %s",
optp->name);
- (*dissect)(optp, tvb, offset, 1, pinfo, opt_tree);
+ (*dissect)(optp, tvb, offset, 1, pinfo, opt_tree, data);
} else {
proto_tree *field_tree;
proto_item *tf;
@@ -2304,7 +2315,7 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
"Options: (%u bytes)", optlen);
field_tree = proto_item_add_subtree(tf, ett_ip_options);
dissect_ip_tcp_options(tvb, offset + 20, optlen, ipopts, N_IP_OPTS,
- IPOPT_EOOL, pinfo, field_tree, tf);
+ IPOPT_EOOL, pinfo, field_tree, tf, NULL);
}
pinfo->ipproto = iph->ip_p;
diff --git a/epan/dissectors/packet-ppp.c b/epan/dissectors/packet-ppp.c
index 680aa3fb05..8b8082a06e 100644
--- a/epan/dissectors/packet-ppp.c
+++ b/epan/dissectors/packet-ppp.c
@@ -889,59 +889,59 @@ static int hf_lcp_opt_MIBenum = -1;
static int hf_lcp_opt_language_tag = -1;
static void dissect_lcp_vendor_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_lcp_mru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_lcp_async_map_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_lcp_authprot_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_lcp_qualprot_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_lcp_linkqualmon_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_lcp_simple_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp,
tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
- proto_tree *tree);
+ proto_tree *tree, void *data _U_);
static void dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp,
tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
- proto_tree *tree);
+ proto_tree *tree, void *data _U_);
static void dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp,
tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
- proto_tree *tree);
+ proto_tree *tree, void *data _U_);
static void dissect_lcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp,
tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
- proto_tree *tree);
+ proto_tree *tree, void *data _U_);
static void dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp,
tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
- proto_tree *tree);
+ proto_tree *tree, void *data _U_);
static void dissect_lcp_dce_identifier_opt(const ip_tcp_opt *optp,
tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
- proto_tree *tree);
+ proto_tree *tree, void *data _U_);
static void dissect_lcp_multilink_pp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_lcp_bacp_link_discriminator_opt(const ip_tcp_opt *optp,
tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
- proto_tree *tree);
+ proto_tree *tree, void *data _U_);
static void dissect_lcp_auth_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_lcp_cobs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_lcp_prefix_elision_opt(const ip_tcp_opt *optp,
tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
- proto_tree *tree);
+ proto_tree *tree, void *data _U_);
static void dissect_lcp_multilink_hdr_fmt_opt(const ip_tcp_opt *optp,
tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
- proto_tree *tree);
+ proto_tree *tree, void *data _U_);
static void dissect_lcp_internationalization_opt(const ip_tcp_opt *optp,
tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
- proto_tree *tree);
+ proto_tree *tree, void *data _U_);
static void dissect_mp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static const ip_tcp_opt lcp_opts[] = {
@@ -1023,23 +1023,23 @@ static const ip_tcp_opt lcp_opts[] = {
#define CI_APN_AMBR 10
static void dissect_vsncp_pdnid_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static void dissect_vsncp_apname_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static void dissect_vsncp_pdntype_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static void dissect_vsncp_pdnaddress_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static void dissect_vsncp_pco_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static void dissect_vsncp_errorcode_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static void dissect_vsncp_attachtype_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static void dissect_vsncp_ipv4address_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static void dissect_vsncp_addressalloc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static const ip_tcp_opt vsncp_opts[] = {
{CI_PDN_IDENTIFIER, "PDN Identifier", NULL,
@@ -1134,29 +1134,29 @@ static int hf_ipcp_opt_iphc_length = -1;
static int hf_ipcp_opt_iphc_param = -1;
static void dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_ipcp_compress_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_ipcp_rohc_profiles_opt(const ip_tcp_opt *optp,
tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
- proto_tree *tree);
+ proto_tree *tree, void *data _U_);
static void dissect_ipcp_iphc_simple_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_ipcp_iphc_neghdrcomp_opt(const ip_tcp_opt *optp,
tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
- proto_tree *tree);
+ proto_tree *tree, void *data _U_);
static void dissect_ipcp_addr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_ipcp_mobileipv4_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_ipcp_pri_dns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_ipcp_pri_nbns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_ipcp_sec_dns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_ipcp_sec_nbns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static const ip_tcp_opt ipcp_opts[] = {
{CI_ADDRS, "IP Addresses (deprecated)", &ett_ipcp_ipaddrs_opt,
@@ -1251,7 +1251,7 @@ static int hf_osinlcp_opt_alignment = -1;
static void dissect_osinlcp_align_npdu_opt(const ip_tcp_opt *optp,
tvbuff_t *tvb, int offset, guint length, packet_info *pinfo,
- proto_tree *tree);
+ proto_tree *tree, void *data _U_);
static const ip_tcp_opt osinlcp_opts[] = {
{CI_OSINLCP_ALIGN_NPDU, "Align-NPDU", &ett_osinlcp_align_npdu_opt,
@@ -1317,32 +1317,32 @@ static int hf_ccp_opt_dict_size = -1;
static int hf_ccp_opt_history_length = -1;
static void dissect_ccp_oui_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_ccp_other_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
#define dissect_ccp_predict1_opt dissect_ccp_other_opt
#define dissect_ccp_predict2_opt dissect_ccp_other_opt
#define dissect_ccp_puddle_opt dissect_ccp_other_opt
#define dissect_ccp_hpppc_opt dissect_ccp_other_opt
static void dissect_ccp_stac_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_ccp_mppe_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_ccp_gfza_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
#define dissect_ccp_v42bis_opt dissect_ccp_other_opt
static void dissect_ccp_bsdcomp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_ccp_lzsdcp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_ccp_mvrca_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_ccp_dce_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_ccp_deflate_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static void dissect_ccp_v44lzjh_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
static const ip_tcp_opt ccp_opts[] = {
@@ -1395,10 +1395,10 @@ static const ip_tcp_opt ccp_opts[] = {
#define CI_CBCP_CB_ANY 4 /* Callback to any of a list of numbers */
static void dissect_cbcp_no_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static void dissect_cbcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static const ip_tcp_opt cbcp_opts[] = {
{CI_CBCP_NO_CALLBACK, "No callback", NULL,
@@ -1420,7 +1420,7 @@ static const ip_tcp_opt cbcp_opts[] = {
static void dissect_bacp_favored_peer_opt(const ip_tcp_opt *optp,
tvbuff_t *tvb, int offset, guint length, packet_info *pinfo,
- proto_tree *tree);
+ proto_tree *tree, void *data _U_);
static const ip_tcp_opt bacp_opts[] = {
{CI_BACP_FAVORED_PEER, "Favored-Peer", &ett_bacp_favored_peer_opt,
@@ -1440,15 +1440,15 @@ static const ip_tcp_opt bacp_opts[] = {
#define CI_BAP_CALL_STATUS 6 /* Call Status */
static void dissect_bap_link_type_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static void dissect_bap_phone_delta_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static void dissect_bap_link_disc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static void dissect_bap_reason_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static void dissect_bap_call_status_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static const ip_tcp_opt bap_opts[] = {
{CI_BAP_LINK_TYPE, "Link Type", &ett_bap_link_type_opt,
@@ -1506,7 +1506,7 @@ static const value_string pppmuxcp_vals[] = {
#define CI_DEFAULT_PID 1
static void dissect_pppmuxcp_def_pid_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static const ip_tcp_opt pppmuxcp_opts[] = {
@@ -1525,7 +1525,7 @@ static const true_false_string tfs_pppmux_length_field = { "2 bytes", "1 byte" }
#define CI_IPV6CP_COMPRESSTYPE 2 /* Compression Type (RFC 2472) */
static void dissect_ipv6cp_if_id_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo, proto_tree *tree);
+ int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
static const ip_tcp_opt ipv6cp_opts[] = {
{CI_IPV6CP_IF_ID, "Interface Identifier", &ett_ipv6cp_if_id_opt,
@@ -1743,7 +1743,7 @@ dissect_lcp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
static void
dissect_lcp_vendor_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf, *ti;
@@ -1771,7 +1771,7 @@ dissect_lcp_vendor_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_lcp_mru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -1786,7 +1786,7 @@ dissect_lcp_mru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_lcp_async_map_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf, *ti;
@@ -1852,7 +1852,7 @@ dissect_lcp_async_map_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_lcp_authprot_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -1886,7 +1886,7 @@ dissect_lcp_authprot_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_lcp_qualprot_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -1909,7 +1909,7 @@ dissect_lcp_qualprot_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -1924,7 +1924,7 @@ dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_lcp_linkqualmon_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -1953,7 +1953,7 @@ dissect_lcp_linkqualmon_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
*/
static void
dissect_lcp_simple_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -1965,7 +1965,8 @@ dissect_lcp_simple_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree,
+ void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -1987,7 +1988,8 @@ dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
static void
dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree,
+ void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -2006,7 +2008,8 @@ dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
static void
dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree,
+ void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -2048,7 +2051,7 @@ static const value_string callback_op_vals[] = {
static void
dissect_lcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -2071,7 +2074,8 @@ dissect_lcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
/* http://tools.ietf.org/html/rfc1990#section-5.1.1 */
static void
dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree,
+ void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -2102,7 +2106,8 @@ static const value_string multilink_ep_disc_class_vals[] = {
static void
dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree,
+ void *data _U_)
{
proto_tree *field_tree;
proto_tree *magic_tree;
@@ -2187,7 +2192,7 @@ static const value_string dce_id_mode_vals[] = {
static void
dissect_lcp_dce_identifier_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -2204,7 +2209,7 @@ dissect_lcp_dce_identifier_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
static void
dissect_lcp_multilink_pp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -2218,7 +2223,7 @@ dissect_lcp_multilink_pp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_lcp_bacp_link_discriminator_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -2237,7 +2242,7 @@ dissect_lcp_bacp_link_discriminator_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
*/
static void
dissect_lcp_auth_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -2266,7 +2271,7 @@ dissect_lcp_auth_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
*/
static void
dissect_lcp_cobs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -2286,7 +2291,7 @@ dissect_lcp_cobs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_lcp_prefix_elision_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -2323,7 +2328,7 @@ static const value_string ml_hdr_fmt_code_vals[] = {
static void
dissect_lcp_multilink_hdr_fmt_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -2603,7 +2608,7 @@ value_string_ext charset_vals_ext = VALUE_STRING_EXT_INIT(charset_vals);
static void
dissect_lcp_internationalization_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -2632,7 +2637,7 @@ dissect_ipcp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
/* http://tools.ietf.org/html/rfc1172#section-5.1 */
static void
dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -2656,7 +2661,7 @@ static const true_false_string tfs_comp_slot_id = {
/* http://tools.ietf.org/html/rfc1332#section-3.2 */
static void
dissect_ipcp_compress_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -2691,7 +2696,7 @@ dissect_ipcp_compress_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
"Suboptions: (%u byte%s)", length, plurality(length, "", "s"));
subopt_tree = proto_item_add_subtree(tso, *optp->subtree_index);
dissect_ip_tcp_options(tvb, offset, length, ipcp_rohc_subopts,
- N_IPCP_ROHC_SUBOPTS, -1, pinfo, subopt_tree, NULL);
+ N_IPCP_ROHC_SUBOPTS, -1, pinfo, subopt_tree, NULL, NULL);
}
break;
@@ -2730,7 +2735,7 @@ dissect_ipcp_compress_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
"Suboptions: (%u byte%s)", length, plurality(length, "", "s"));
subopt_tree = proto_item_add_subtree(tso, *optp->subtree_index);
dissect_ip_tcp_options(tvb, offset, length, ipcp_iphc_subopts,
- N_IPCP_IPHC_SUBOPTS, -1, pinfo, subopt_tree, NULL);
+ N_IPCP_IPHC_SUBOPTS, -1, pinfo, subopt_tree, NULL, NULL);
}
break;
@@ -2758,7 +2763,7 @@ dissect_ipcp_opt_rohc_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
static void
dissect_ipcp_rohc_profiles_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -2790,7 +2795,7 @@ dissect_ipcp_opt_iphc_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
static void
dissect_ipcp_iphc_simple_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -2802,7 +2807,7 @@ dissect_ipcp_iphc_simple_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
static void
dissect_ipcp_iphc_neghdrcomp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -2816,7 +2821,7 @@ dissect_ipcp_iphc_neghdrcomp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
static void
dissect_ipcp_addr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -2831,7 +2836,7 @@ dissect_ipcp_addr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_ipcp_mobileipv4_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -2846,7 +2851,7 @@ dissect_ipcp_mobileipv4_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_ipcp_pri_dns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -2861,7 +2866,7 @@ dissect_ipcp_pri_dns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_ipcp_pri_nbns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -2876,7 +2881,7 @@ dissect_ipcp_pri_nbns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_ipcp_sec_dns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -2891,7 +2896,7 @@ dissect_ipcp_sec_dns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_ipcp_sec_nbns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -2920,7 +2925,7 @@ dissect_osinlcp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
static void
dissect_osinlcp_align_npdu_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -2935,7 +2940,7 @@ dissect_osinlcp_align_npdu_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
static void
dissect_pppmuxcp_def_pid_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
pppmux_def_prot_id = tvb_get_ntohs(tvb, offset + 2);
proto_tree_add_text(tree, tvb, offset + 2, length - 2, "%s: %s (0x%02x)",
@@ -2959,7 +2964,7 @@ dissect_ccp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
/* http://tools.ietf.org/html/rfc1962 */
static void dissect_ccp_oui_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf, *ti;
@@ -2997,7 +3002,7 @@ static void dissect_ccp_oui_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
* 20) V.42bis compression
*/
static void dissect_ccp_other_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -3015,7 +3020,7 @@ static void dissect_ccp_other_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
/* http://tools.ietf.org/html/rfc1974 */
static void
dissect_ccp_stac_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -3087,7 +3092,7 @@ static const true_false_string ccp_mppe_c_tfs = {
* http://tools.ietf.org/html/rfc3078 */
static void
dissect_ccp_mppe_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -3112,7 +3117,7 @@ dissect_ccp_mppe_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
/* http://tools.ietf.org/html/rfc1993 */
static void dissect_ccp_gfza_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree *field_tree;
proto_item *tf;
@@ -3133,7 +3138,7 @@ static void dissect_ccp_gfza_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
/* http://tools.ietf.org/html/rfc1977 */
static void
dissect_ccp_bsdcomp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -3153,7 +3158,7 @@ dissect_ccp_bsdcomp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
/* http://tools.ietf.org/html/rfc1967 */
static void
dissect_ccp_lzsdcp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -3173,7 +3178,7 @@ dissect_ccp_lzsdcp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
/* http://tools.ietf.org/html/rfc1975 */
static void
dissect_ccp_mvrca_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -3193,7 +3198,7 @@ dissect_ccp_mvrca_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
/* http://tools.ietf.org/html/rfc1976 */
static void
dissect_ccp_dce_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -3219,7 +3224,7 @@ static const value_string deflate_chk_vals[] = {
/* http://tools.ietf.org/html/rfc1979 */
static void
dissect_ccp_deflate_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -3251,7 +3256,7 @@ static const range_string v44lzjh_mode_dict_rvals[] = {
/* http://www.watersprings.org/pub/id/draft-heath-ppp-v44-01.txt */
static void dissect_ccp_v44lzjh_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -3276,14 +3281,14 @@ static void dissect_ccp_v44lzjh_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
static void
dissect_cbcp_no_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
}
static void
dissect_cbcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -3323,7 +3328,7 @@ dissect_cbcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_bacp_favored_peer_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -3337,7 +3342,7 @@ dissect_bacp_favored_peer_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
static void
dissect_bap_link_type_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -3355,7 +3360,7 @@ dissect_bap_link_type_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_bap_phone_delta_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -3445,7 +3450,7 @@ dissect_bap_phone_delta_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_bap_reason_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
if (length > 2) {
proto_tree_add_text(tree, tvb, offset, length, "%s: %s", optp->name,
@@ -3455,7 +3460,7 @@ dissect_bap_reason_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_bap_link_disc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree_add_text(tree, tvb, offset, length, "%s: 0x%04x", optp->name,
tvb_get_ntohs(tvb, offset + 2));
@@ -3463,7 +3468,7 @@ dissect_bap_link_disc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_bap_call_status_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -3485,7 +3490,7 @@ dissect_bap_call_status_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_vsncp_pdnid_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
guint8 PDNID;
@@ -3496,7 +3501,7 @@ dissect_vsncp_pdnid_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_vsncp_attachtype_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
static const value_string attach_vals[] = {
{1, "Initial Attach"},
@@ -3515,7 +3520,7 @@ dissect_vsncp_attachtype_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_vsncp_pdntype_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
static const value_string pdntype_vals[] = {
{1, "IPv4"},
@@ -3535,7 +3540,7 @@ dissect_vsncp_pdntype_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_vsncp_errorcode_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
static const value_string errorcode_vals[] = {
{0, "General Eror"},
@@ -3564,7 +3569,7 @@ dissect_vsncp_errorcode_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_vsncp_pdnaddress_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
guint8 pdnaddtype;
static const value_string pdntype_vals[] = {
@@ -3625,7 +3630,7 @@ dissect_vsncp_pdnaddress_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_vsncp_ipv4address_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree_add_text(tree, tvb, offset, length, "%s: %s", optp->name,
tvb_ip_to_str(tvb, offset + 2));
@@ -3633,7 +3638,7 @@ dissect_vsncp_ipv4address_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
static void
dissect_vsncp_apname_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_item *tf;
proto_tree *field_tree;
@@ -3662,7 +3667,7 @@ dissect_vsncp_apname_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
static void
dissect_vsncp_addressalloc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint length, packet_info *pinfo _U_, proto_tree *tree)
+ int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
static const value_string alloc_vals[] = {
{0, "Null Value (Attach or Handover)"},
@@ -3682,7 +3687,7 @@ dissect_vsncp_addressalloc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
static void
dissect_vsncp_pco_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
static const value_string pco_vals[] = {
{0x8021, "IPCP (DNS Address Request)"},
@@ -3784,7 +3789,7 @@ dissect_cp(tvbuff_t *tvb, int proto_id, int proto_subtree_index,
"Options: (%d byte%s)", length, plurality(length, "", "s"));
field_tree = proto_item_add_subtree(tf, options_subtree_index);
dissect_ip_tcp_options(tvb, offset, length, opts, nopts, -1, pinfo,
- field_tree, NULL);
+ field_tree, NULL, NULL);
}
break;
@@ -3951,7 +3956,7 @@ static void
dissect_lcp_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
dissect_ip_tcp_options(tvb, 0, tvb_reported_length(tvb), lcp_opts,
- N_LCP_OPTS, -1, pinfo, tree, NULL);
+ N_LCP_OPTS, -1, pinfo, tree, NULL, NULL);
}
/*
@@ -4016,7 +4021,7 @@ dissect_vsncp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
plurality(length, "", "s"));
field_tree = proto_item_add_subtree(tf, ett_vsncp_options);
dissect_ip_tcp_options(tvb, offset, length, vsncp_opts,
- N_VSNCP_OPTS, -1, pinfo, field_tree, NULL);
+ N_VSNCP_OPTS, -1, pinfo, field_tree, NULL, NULL);
}
break;
@@ -4281,7 +4286,7 @@ dissect_bap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
"Data (%d byte%s)", length, plurality(length, "", "s"));
field_tree = proto_item_add_subtree(tf, ett_bap_options);
dissect_ip_tcp_options(tvb, offset, length, bap_opts, N_BAP_OPTS,
- -1, pinfo, field_tree, NULL);
+ -1, pinfo, field_tree, NULL, NULL);
}
}
@@ -5368,7 +5373,7 @@ dissect_ipv6cp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static void
dissect_ipv6cp_if_id_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
- guint length, packet_info *pinfo _U_, proto_tree *tree)
+ guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
{
proto_tree_add_text(tree, tvb, offset, length,
"%s: %02x%02x:%02x%02x:%02x%x:%02x%02x", optp->name,
diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c
index 1310fadbb7..a469289fc9 100644
--- a/epan/dissectors/packet-tcp.c
+++ b/epan/dissectors/packet-tcp.c
@@ -164,6 +164,7 @@ static int hf_tcp_option_sack_perm = -1;
static int hf_tcp_option_sack = -1;
static int hf_tcp_option_sack_sle = -1;
static int hf_tcp_option_sack_sre = -1;
+static int hf_tcp_option_sack_range_count = -1;
static int hf_tcp_option_echo = -1;
static int hf_tcp_option_echo_reply = -1;
static int hf_tcp_option_timestamp_tsval = -1;
@@ -2352,7 +2353,7 @@ tcp_info_append_uint(packet_info *pinfo, const char *abbrev, guint32 val)
static void
dissect_tcpopt_exp(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
- int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
{
proto_item *item;
proto_tree *exp_tree;
@@ -2370,7 +2371,7 @@ dissect_tcpopt_exp(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
static void
dissect_tcpopt_sack_perm(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
- int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
{
proto_item *item;
proto_tree *exp_tree;
@@ -2385,7 +2386,7 @@ dissect_tcpopt_sack_perm(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
static void
dissect_tcpopt_mss(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
{
proto_item *item;
proto_tree *exp_tree;
@@ -2404,7 +2405,7 @@ dissect_tcpopt_mss(const ip_tcp_opt *optp, tvbuff_t *tvb,
/* The window scale extension is defined in RFC 1323 */
static void
dissect_tcpopt_wscale(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
- int offset, guint optlen _U_, packet_info *pinfo, proto_tree *opt_tree)
+ int offset, guint optlen _U_, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
{
guint8 val, shift;
proto_item *wscale_pi, *gen_pi;
@@ -2442,14 +2443,16 @@ dissect_tcpopt_wscale(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
static void
dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree, void *data)
{
proto_tree *field_tree = NULL;
proto_item *tf=NULL;
proto_item *hidden_item;
guint32 leftedge, rightedge;
struct tcp_analysis *tcpd=NULL;
+ struct tcpheader *tcph = (struct tcpheader *)data;
guint32 base_ack=0;
+ guint num_sack_ranges = 0;
if(tcp_analyze_seq && tcp_relative_seq) {
/* find(or create if needed) the conversation for this tcp session */
@@ -2467,7 +2470,7 @@ dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
offset + 1, 1, ENC_BIG_ENDIAN);
PROTO_ITEM_SET_HIDDEN(hidden_item);
- tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name);
+ tf = proto_tree_add_text(opt_tree, tvb, offset, optlen, "%s:", optp->name);
offset += 2; /* skip past type and length */
optlen -= 2; /* subtract size of type and length */
while (optlen > 0) {
@@ -2504,14 +2507,28 @@ dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
tcp_relative_seq ? " (relative)" : "");
tcp_info_append_uint(pinfo, "SLE", leftedge);
tcp_info_append_uint(pinfo, "SRE", rightedge);
+ num_sack_ranges++;
+
+ /* Update tap info */
+ if (tcph != NULL && (tcph->num_sack_ranges < MAX_TCP_SACK_RANGES)) {
+ tcph->sack_left_edge[tcph->num_sack_ranges] = leftedge;
+ tcph->sack_right_edge[tcph->num_sack_ranges] = rightedge;
+ tcph->num_sack_ranges++;
+ }
+
proto_item_append_text(field_tree, " %u-%u", leftedge, rightedge);
offset += 8;
}
+
+ /* Show number of SACK ranges in this option as a generated field */
+ tf = proto_tree_add_uint(field_tree, hf_tcp_option_sack_range_count,
+ tvb, 0, 0, num_sack_ranges);
+ PROTO_ITEM_SET_GENERATED(tf);
}
static void
dissect_tcpopt_echo(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
{
proto_item *hidden_item;
guint32 echo;
@@ -2537,7 +2554,7 @@ static gboolean tcp_ignore_timestamps = FALSE;
static void
dissect_tcpopt_timestamp(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
- int offset, guint optlen _U_, packet_info *pinfo, proto_tree *opt_tree)
+ int offset, guint optlen _U_, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
{
proto_item *ti;
proto_tree *ts_tree;
@@ -2579,7 +2596,7 @@ dissect_tcpopt_timestamp(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
*/
static void
dissect_tcpopt_mptcp(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
- int offset, guint optlen, packet_info *pinfo _U_, proto_tree *opt_tree)
+ int offset, guint optlen, packet_info *pinfo _U_, proto_tree *opt_tree, void *data _U_)
{
proto_item *ti;
proto_tree *mptcp_tree;
@@ -2838,7 +2855,7 @@ dissect_tcpopt_mptcp(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
static void
dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
{
proto_item *hidden_item;
guint32 cc;
@@ -2861,7 +2878,7 @@ dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
static void
dissect_tcpopt_qs(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
{
proto_item *hidden_item;
@@ -2889,7 +2906,7 @@ dissect_tcpopt_qs(const ip_tcp_opt *optp, tvbuff_t *tvb,
static void
dissect_tcpopt_scps(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
int offset, guint optlen, packet_info *pinfo,
- proto_tree *opt_tree)
+ proto_tree *opt_tree, void *data _U_)
{
struct tcp_analysis *tcpd;
proto_tree *field_tree = NULL;
@@ -3057,7 +3074,7 @@ dissect_tcpopt_scps(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
static void
dissect_tcpopt_user_to(const ip_tcp_opt *optp, tvbuff_t *tvb,
- int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
{
proto_item *hidden_item, *tf;
proto_tree *field_tree;
@@ -3114,7 +3131,7 @@ verify_scps(packet_info *pinfo, proto_item *tf_syn, struct tcp_analysis *tcpd)
static void
dissect_tcpopt_snack(const ip_tcp_opt *optp, tvbuff_t *tvb,
int offset, guint optlen, packet_info *pinfo,
- proto_tree *opt_tree)
+ proto_tree *opt_tree, void *data _U_)
{
struct tcp_analysis *tcpd=NULL;
guint16 relative_hole_offset;
@@ -3288,7 +3305,8 @@ rvbd_probe_resp_add_info(proto_item *pitem, packet_info *pinfo, guint32 ip, guin
static void
dissect_tcpopt_rvbd_probe(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
- guint optlen, packet_info *pinfo, proto_tree *opt_tree)
+ guint optlen, packet_info *pinfo, proto_tree *opt_tree,
+ void *data _U_)
{
guint8 ver, type;
proto_tree *field_tree;
@@ -3504,7 +3522,7 @@ static const true_false_string trpy_mode_str = {
static void
dissect_tcpopt_rvbd_trpy(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
int offset, guint optlen, packet_info *pinfo,
- proto_tree *opt_tree)
+ proto_tree *opt_tree, void *data _U_)
{
proto_tree *field_tree;
proto_tree *flag_tree;
@@ -4617,6 +4635,7 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
/* Decode TCP options, if any. */
+ tcph->num_sack_ranges = 0;
if (tcph->th_hlen > TCPH_MIN_LEN) {
/* There's more than just the fixed-length header. Decode the
options. */
@@ -4632,7 +4651,7 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
field_tree = NULL;
}
dissect_ip_tcp_options(tvb, offset + 20, optlen,
- tcpopts, N_TCP_OPTS, TCPOPT_EOL, pinfo, field_tree, tf);
+ tcpopts, N_TCP_OPTS, TCPOPT_EOL, pinfo, field_tree, tf, tcph);
}
if(!pinfo->fd->flags.visited) {
@@ -5113,6 +5132,10 @@ proto_register_tcp(void)
{"TCP SACK Right Edge", "tcp.options.sack_re", FT_UINT32,
BASE_DEC, NULL, 0x0, NULL, HFILL}},
+ { &hf_tcp_option_sack_range_count,
+ { "TCP SACK Count", "tcp.options.sack.count", FT_UINT8,
+ BASE_DEC, NULL, 0x0, NULL, HFILL}},
+
{ &hf_tcp_option_echo,
{ "TCP Echo Option", "tcp.options.echo", FT_BOOLEAN,
BASE_NONE, NULL, 0x0, "TCP Sack Echo", HFILL}},
diff --git a/epan/dissectors/packet-tcp.h b/epan/dissectors/packet-tcp.h
index 5e35abaddc..f2e7e92a91 100644
--- a/epan/dissectors/packet-tcp.h
+++ b/epan/dissectors/packet-tcp.h
@@ -62,6 +62,12 @@ typedef struct tcpheader {
guint32 th_stream; /* this stream index field is included to help differentiate when address/port pairs are reused */
address ip_src;
address ip_dst;
+
+ /* This is the absolute maximum we could find in TCP options (RFC2018, section 3) */
+ #define MAX_TCP_SACK_RANGES 4
+ guint8 num_sack_ranges;
+ guint32 sack_left_edge[MAX_TCP_SACK_RANGES];
+ guint32 sack_right_edge[MAX_TCP_SACK_RANGES];
} tcp_info_t;
/*
diff --git a/epan/ip_opts.h b/epan/ip_opts.h
index d6a082c4f5..2553a95f20 100644
--- a/epan/ip_opts.h
+++ b/epan/ip_opts.h
@@ -47,7 +47,8 @@ typedef struct ip_tcp_opt {
int,
guint,
packet_info *,
- proto_tree *); /**< routine to dissect option */
+ proto_tree *,
+ void *); /**< routine to dissect option */
} ip_tcp_opt;
/** Routine to dissect options that work like IPv4 options, where the
@@ -55,7 +56,8 @@ typedef struct ip_tcp_opt {
length bytes. */
extern void dissect_ip_tcp_options(tvbuff_t *, int, guint,
const ip_tcp_opt *, int, int,
- packet_info *, proto_tree *, proto_item *);
+ packet_info *, proto_tree *, proto_item *,
+ void *);
/* Quick-Start option, as defined by RFC4782 */
#define QS_FUNC_MASK 0xf0
diff --git a/ui/gtk/tcp_graph.c b/ui/gtk/tcp_graph.c
index 4ec3285b28..f5cbd4fd52 100644
--- a/ui/gtk/tcp_graph.c
+++ b/ui/gtk/tcp_graph.c
@@ -94,6 +94,10 @@ struct segment {
guint16 th_dport;
address ip_src;
address ip_dst;
+
+ guint8 num_sack_ranges;
+ guint32 sack_left_edge[MAX_TCP_SACK_RANGES];
+ guint32 sack_right_edge[MAX_TCP_SACK_RANGES];
};
struct rect {
@@ -176,6 +180,7 @@ struct axis {
struct style_tseq_tcptrace {
GdkColor seq_color;
GdkColor ack_color[2];
+ GdkColor sack_color[2];
int flags;
};
@@ -416,7 +421,7 @@ static void update_zoom_spins (struct graph * );
static struct tcpheader *select_tcpip_session (capture_file *, struct segment * );
static int compare_headers (address *saddr1, address *daddr1, guint16 sport1, guint16 dport1, address *saddr2, address *daddr2, guint16 sport2, guint16 dport2, int dir);
static int get_num_dsegs (struct graph * );
-static int get_num_acks (struct graph * );
+static int get_num_acks (struct graph *, int * );
static void graph_type_dependent_initialize (struct graph * );
static struct graph *graph_new (void);
static void graph_destroy (struct graph * );
@@ -1840,6 +1845,14 @@ tapall_tcpip_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, cons
segment->th_seglen=tcphdr->th_seglen;
COPY_ADDRESS(&segment->ip_src, &tcphdr->ip_src);
COPY_ADDRESS(&segment->ip_dst, &tcphdr->ip_dst);
+
+ segment->num_sack_ranges = MIN(MAX_TCP_SACK_RANGES, tcphdr->num_sack_ranges);
+ if (segment->num_sack_ranges > 0) {
+ /* Copy entries in the order they happen */
+ memcpy(&segment->sack_left_edge, &tcphdr->sack_left_edge, sizeof(segment->sack_left_edge));
+ memcpy(&segment->sack_right_edge, &tcphdr->sack_right_edge, sizeof(segment->sack_right_edge));
+ }
+
if (ts->g->segments) {
ts->last->next = segment;
} else {
@@ -3750,7 +3763,7 @@ static int get_num_dsegs (struct graph *g)
return count;
}
-static int get_num_acks (struct graph *g)
+static int get_num_acks (struct graph *g, int *num_sack_ranges)
{
int count;
struct segment *tmp;
@@ -3762,6 +3775,7 @@ static int get_num_acks (struct graph *g)
tmp->th_sport, tmp->th_dport,
COMPARE_CURR_DIR)) {
count++;
+ *num_sack_ranges += tmp->num_sack_ranges;
}
}
return count;
@@ -3996,6 +4010,18 @@ static void tseq_tcptrace_read_config (struct graph *g)
g->s.tseq_tcptrace.ack_color[1].green=0xd3d3;
g->s.tseq_tcptrace.ack_color[1].blue=0xd3d3;
+ /* Light blue */
+ g->s.tseq_tcptrace.sack_color[0].pixel=0;
+ g->s.tseq_tcptrace.sack_color[0].red=0x0;
+ g->s.tseq_tcptrace.sack_color[0].green=0x0;
+ g->s.tseq_tcptrace.sack_color[0].blue=0xffff;
+
+ /* Darker blue */
+ g->s.tseq_tcptrace.sack_color[1].pixel=0;
+ g->s.tseq_tcptrace.sack_color[1].red=0x0;
+ g->s.tseq_tcptrace.sack_color[1].green=0x0;
+ g->s.tseq_tcptrace.sack_color[1].blue=0x9888;
+
g->s.tseq_tcptrace.flags = 0;
g->elists->next = (struct element_list * )
@@ -4027,11 +4053,14 @@ static void tseq_tcptrace_make_elmtlist (struct graph *g)
int toggle=0;
guint32 seq_base;
guint32 seq_cur;
+ int num_sack_ranges;
debug(DBS_FENTRY) puts ("tseq_tcptrace_make_elmtlist()");
if (g->elists->elements == NULL) {
- int n = 1 + 4*get_num_acks(g);
+ /* 4 elements per ACK, but only one for each SACK range */
+ int n = 1 + 4*get_num_acks(g, &num_sack_ranges);
+ n += num_sack_ranges;
e0 = elements0 = (struct element * )g_malloc (n*sizeof (struct element));
} else
e0 = elements0 = g->elists->elements;
@@ -4105,6 +4134,8 @@ static void tseq_tcptrace_make_elmtlist (struct graph *g)
/* ack line */
if (ack_seen == TRUE) { /* don't plot the first ack */
+
+ /* Horizonal: time of previous ACK to now (at new ACK) */
e0->type = ELMT_LINE;
e0->parent = tmp;
/* Set the drawing color */
@@ -4114,6 +4145,8 @@ static void tseq_tcptrace_make_elmtlist (struct graph *g)
e0->p.line.dim.x2 = x;
e0->p.line.dim.y2 = p_ackno;
e0++;
+
+ /* Vertical: from previous ACKNO to current one (at current time) */
e0->type = ELMT_LINE;
e0->parent = tmp;
/* Set the drawing color */
@@ -4123,7 +4156,8 @@ static void tseq_tcptrace_make_elmtlist (struct graph *g)
e0->p.line.dim.x2 = x;
e0->p.line.dim.y2 = ackno!=p_ackno || ackno<4 ? ackno : ackno-4;
e0++;
- /* window line */
+
+ /* Horizontal: window line */
e0->type = ELMT_LINE;
e0->parent = tmp;
/* Set the drawing color */
@@ -4133,6 +4167,8 @@ static void tseq_tcptrace_make_elmtlist (struct graph *g)
e0->p.line.dim.x2 = x;
e0->p.line.dim.y2 = p_win + p_ackno;
e0++;
+
+ /* Vertical: old window to new window */
e0->type = ELMT_LINE;
e0->parent = tmp;
/* Set the drawing color */
@@ -4142,12 +4178,41 @@ static void tseq_tcptrace_make_elmtlist (struct graph *g)
e0->p.line.dim.x2 = x;
e0->p.line.dim.y2 = win + ackno;
e0++;
+
+ /* Toggle color to use for ACKs... */
toggle = 1^toggle;
}
ack_seen = TRUE;
p_ackno = ackno;
p_win = win;
p_t = x;
+
+ /* Now any SACK entries */
+ if (tmp->num_sack_ranges) {
+ int n;
+
+ for (n=0; n < tmp->num_sack_ranges; n++) {
+ double left_edge = (tmp->sack_left_edge[n] - seq_base) * g->zoom.y;
+ double right_edge = (tmp->sack_right_edge[n] - seq_base) * g->zoom.y;
+
+ /* Vertical: just show range of SACK.
+ Have experimented with sorting ranges and showing in red regions
+ between SACKs, but when TCP is limited by option bytes and needs to
+ miss out ranges, this can be pretty confusing as we end up apparently
+ NACKing what has been received... */
+ e0->type = ELMT_LINE;
+ e0->parent = tmp;
+ /* Set the drawing color. First range is significant, so use
+ separate colour */
+ e0->elment_color_p = (n==0) ? &g->s.tseq_tcptrace.sack_color[0] :
+ &g->s.tseq_tcptrace.sack_color[1];
+ e0->p.line.dim.x1 = x;
+ e0->p.line.dim.y1 = right_edge;
+ e0->p.line.dim.x2 = x;
+ e0->p.line.dim.y2 = left_edge;
+ e0++;
+ }
+ }
}
}
e0->type = ELMT_NONE;