aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-icmp.c11
-rw-r--r--epan/dissectors/packet-icmpv6.c6
-rw-r--r--epan/dissectors/packet-ip.c33
-rw-r--r--epan/dissectors/packet-ipv6.c79
-rw-r--r--epan/packet_info.h1
5 files changed, 66 insertions, 64 deletions
diff --git a/epan/dissectors/packet-icmp.c b/epan/dissectors/packet-icmp.c
index c7a05002c5..d5a73dd6fa 100644
--- a/epan/dissectors/packet-icmp.c
+++ b/epan/dissectors/packet-icmp.c
@@ -1239,8 +1239,8 @@ get_best_guess_mstimeofday(tvbuff_t * tvb, gint offset, guint32 comp_ts)
* RFC 1256 for router discovery messages.
* RFC 2002 and 3012 for Mobile IP stuff.
*/
-static void
-dissect_icmp(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
+static int
+dissect_icmp(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* data)
{
proto_tree *icmp_tree = NULL;
proto_item *ti;
@@ -1259,6 +1259,7 @@ dissect_icmp(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
guint32 conv_key[2];
icmp_transaction_t *trans = NULL;
nstime_t ts, time_relative;
+ ws_ip *iph = (ws_ip*)data;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ICMP");
col_clear(pinfo->cinfo, COL_INFO);
@@ -1404,7 +1405,7 @@ dissect_icmp(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
" id=0x%04x, seq=%u/%u, ttl=%u",
tvb_get_ntohs(tvb, 4), tvb_get_ntohs(tvb,
6),
- tvb_get_letohs(tvb, 6), pinfo->ip_ttl);
+ tvb_get_letohs(tvb, 6), (iph != NULL) ? iph->ip_ttl : 0);
break;
case ICMP_UNREACH:
@@ -1694,6 +1695,8 @@ dissect_icmp(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
if (trans) {
tap_queue_packet(icmp_tap, pinfo, trans);
}
+
+ return tvb_length(tvb);
}
void proto_register_icmp(void)
@@ -2010,7 +2013,7 @@ void proto_register_icmp(void)
"Whether the 128th and following bytes of the ICMP payload should be decoded as MPLS extensions or as a portion of the original packet",
&favor_icmp_mpls_ext);
- register_dissector("icmp", dissect_icmp, proto_icmp);
+ new_register_dissector("icmp", dissect_icmp, proto_icmp);
icmp_tap = register_tap("icmp");
}
diff --git a/epan/dissectors/packet-icmpv6.c b/epan/dissectors/packet-icmpv6.c
index 30c9ea5065..007e19ec0b 100644
--- a/epan/dissectors/packet-icmpv6.c
+++ b/epan/dissectors/packet-icmpv6.c
@@ -55,6 +55,7 @@
#include "packet-icmp.h" /* same transaction_t used both both v4 and v6 */
#include "packet-ieee802154.h"
#include "packet-6lowpan.h"
+#include "packet-ip.h"
/*
* The information used comes from:
@@ -3176,7 +3177,7 @@ dissect_mldrv2( tvbuff_t *tvb, guint32 offset, packet_info *pinfo _U_, proto_tre
static int
-dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
proto_tree *icmp6_tree = NULL, *flag_tree = NULL;
proto_item *ti = NULL, *hidden_item, *checksum_item = NULL, *code_item = NULL, *ti_flag = NULL;
@@ -3189,6 +3190,7 @@ dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _
tvbuff_t *next_tvb;
guint8 icmp6_type, icmp6_code;
icmp_transaction_t *trans = NULL;
+ ws_ip *iph = (ws_ip*)data;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ICMPv6");
col_clear(pinfo->cinfo, COL_INFO);
@@ -3307,7 +3309,7 @@ dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _
offset += 2;
col_append_fstr(pinfo->cinfo, COL_INFO, " id=0x%04x, seq=%u, hop limit=%u",
- identifier, sequence, pinfo->ip_ttl);
+ identifier, sequence, (iph != NULL) ? iph->ip_ttl : 0);
if (pinfo->destport == 3544 && icmp6_type == ICMP6_ECHO_REQUEST) {
/* RFC 4380
diff --git a/epan/dissectors/packet-ip.c b/epan/dissectors/packet-ip.c
index a2a69664d4..b03339506c 100644
--- a/epan/dissectors/packet-ip.c
+++ b/epan/dissectors/packet-ip.c
@@ -1486,11 +1486,12 @@ 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,
- void * data _U_)
+ void * data)
{
proto_tree *field_tree;
proto_item *tf;
proto_item *ti;
+ ws_ip *iph = (ws_ip*)data;
guint8 command = tvb_get_guint8(tvb, offset + 2);
guint8 function = command >> 4;
@@ -1512,7 +1513,7 @@ dissect_ipopt_qs(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
if (function == QS_RATE_REQUEST) {
proto_tree_add_item(field_tree, hf_ip_opt_qs_rate, tvb, offset + 2, 1, ENC_NA);
proto_tree_add_item(field_tree, hf_ip_opt_qs_ttl, tvb, offset + 3, 1, ENC_NA);
- ttl_diff = (pinfo->ip_ttl - tvb_get_guint8(tvb, offset + 3) % 256);
+ ttl_diff = (iph->ip_ttl - tvb_get_guint8(tvb, offset + 3) % 256);
ti = proto_tree_add_uint_format_value(field_tree, hf_ip_opt_qs_ttl_diff,
tvb, offset + 3, 1, ttl_diff,
"%u", ttl_diff);
@@ -1931,8 +1932,8 @@ ip_checksum(const guint8 *ptr, int len)
static void
dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
- proto_tree *ip_tree = NULL, *field_tree = NULL;
- proto_item *ti = NULL, *tf;
+ proto_tree *ip_tree, *field_tree = NULL;
+ proto_item *ti, *tf;
guint32 addr;
int offset = 0, dst_off;
guint hlen, optlen;
@@ -1965,13 +1966,11 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
hlen = lo_nibble(iph->ip_v_hl) * 4; /* IP header length, in bytes */
- if (tree) {
- ti = proto_tree_add_item(tree, proto_ip, tvb, offset, hlen, ENC_NA);
- ip_tree = proto_item_add_subtree(ti, ett_ip);
+ ti = proto_tree_add_item(tree, proto_ip, tvb, offset, hlen, ENC_NA);
+ ip_tree = proto_item_add_subtree(ti, ett_ip);
- proto_tree_add_uint(ip_tree, hf_ip_version, tvb, offset, 1,
+ proto_tree_add_uint(ip_tree, hf_ip_version, tvb, offset, 1,
hi_nibble(iph->ip_v_hl));
- }
/* if IP is not referenced from any filters we don't need to worry about
generating any tree items. We must do this after we created the actual
@@ -1988,17 +1987,14 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
col_add_fstr(pinfo->cinfo, COL_INFO,
"Bogus IP header length (%u, must be at least %u)",
hlen, IPH_MIN_LEN);
- if (tree) {
- proto_tree_add_uint_format_value(ip_tree, hf_ip_hdr_len, tvb, offset, 1, hlen,
+
+ proto_tree_add_uint_format_value(ip_tree, hf_ip_hdr_len, tvb, offset, 1, hlen,
"%u bytes (bogus, must be at least %u)", hlen, IPH_MIN_LEN);
- }
return;
}
- if (tree) {
- proto_tree_add_uint_format_value(ip_tree, hf_ip_hdr_len, tvb, offset, 1, hlen,
+ proto_tree_add_uint_format_value(ip_tree, hf_ip_hdr_len, tvb, offset, 1, hlen,
"%u bytes", hlen);
- }
iph->ip_tos = tvb_get_guint8(tvb, offset + 1);
if (g_ip_dscp_actif) {
@@ -2119,7 +2115,6 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
}
iph->ip_ttl = tvb_get_guint8(tvb, offset + 8);
- pinfo->ip_ttl = iph->ip_ttl;
if (tree) {
ttl_item = proto_tree_add_item(ip_tree, hf_ip_ttl, tvb, offset + 8, 1, ENC_BIG_ENDIAN);
} else {
@@ -2322,7 +2317,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, &IP_OPT_TYPES, &ei_ip_opt_len_invalid, pinfo, field_tree, tf, NULL);
+ IPOPT_EOOL, &IP_OPT_TYPES, &ei_ip_opt_len_invalid, pinfo, field_tree, tf, iph);
}
pinfo->ipproto = iph->ip_p;
@@ -2403,8 +2398,8 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
type in question. */
if ((try_heuristic_first) && (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree, iph))) {
/* We're good */
- } else if (!dissector_try_uint(ip_dissector_table, nxt, next_tvb, pinfo,
- parent_tree)) {
+ } else if (!dissector_try_uint_new(ip_dissector_table, nxt, next_tvb, pinfo,
+ parent_tree, TRUE, iph)) {
if ((!try_heuristic_first) && (!dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree, iph))) {
/* Unknown protocol */
if (update_col_info) {
diff --git a/epan/dissectors/packet-ipv6.c b/epan/dissectors/packet-ipv6.c
index 764ae0e0f3..1e3245b2e9 100644
--- a/epan/dissectors/packet-ipv6.c
+++ b/epan/dissectors/packet-ipv6.c
@@ -950,7 +950,7 @@ dissect_unknown_option(tvbuff_t *tvb, int offset, proto_tree *tree)
}
static int
-dissect_opts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo, const int hf_option_item)
+dissect_opts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo, const int hf_option_item, ws_ip* iph)
{
int len;
int offset_end;
@@ -1091,7 +1091,7 @@ dissect_opts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo, c
proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_rate, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_ttl, tvb, offset, 1, ENC_NA);
- ttl_diff = (pinfo->ip_ttl - tvb_get_guint8(tvb, offset) % 256);
+ ttl_diff = (iph->ip_ttl - tvb_get_guint8(tvb, offset) % 256);
offset += 1;
ti = proto_tree_add_uint_format_value(opt_tree, hf_ipv6_opt_qs_ttl_diff,
tvb, offset, 1, ttl_diff,
@@ -1167,15 +1167,15 @@ dissect_opts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo, c
}
static int
-dissect_hopopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
+dissect_hopopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo, ws_ip* iph)
{
- return dissect_opts(tvb, offset, tree, pinfo, hf_ipv6_hop_opt);
+ return dissect_opts(tvb, offset, tree, pinfo, hf_ipv6_hop_opt, iph);
}
static int
-dissect_dstopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
+dissect_dstopts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo, ws_ip* iph)
{
- return dissect_opts(tvb, offset, tree, pinfo, hf_ipv6_dst_opt);
+ return dissect_opts(tvb, offset, tree, pinfo, hf_ipv6_dst_opt, iph);
}
/* START SHIM6 PART */
@@ -1731,8 +1731,8 @@ dissect_shim6(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo)
static void
dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- proto_tree *ipv6_tree = NULL;
- proto_item *ipv6_item = NULL, *ti;
+ proto_tree *ipv6_tree, *ipv6_tc_tree, *pt;
+ proto_item *ipv6_item, *ipv6_tc, *ti, *pi;
guint8 nxt;
guint8 stype=0;
int advance;
@@ -1747,6 +1747,11 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
gboolean save_fragmented = FALSE;
const char *sep = "IPv6 ";
guint8 *mac_addr;
+ const char *name;
+
+ /* Provide as much IPv4 header information as possible as some dissectors
+ in the ip.proto dissector table may need it */
+ ws_ip iph;
struct ip6_hdr ipv6;
@@ -1754,6 +1759,7 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
col_clear(pinfo->cinfo, COL_INFO);
offset = 0;
+ memset(&iph, 0, sizeof(iph));
tvb_memcpy(tvb, (guint8 *)&ipv6, offset, sizeof(ipv6));
/* Get extension header and payload length */
@@ -1767,16 +1773,10 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
TVB_SET_ADDRESS(&pinfo->net_dst, AT_IPv6, tvb, offset + IP6H_DST, 16);
TVB_SET_ADDRESS(&pinfo->dst, AT_IPv6, tvb, offset + IP6H_DST, 16);
- if (tree) {
- proto_tree* pt;
- proto_item* pi;
- proto_tree *ipv6_tc_tree;
- proto_item *ipv6_tc;
- const char *name;
-
- ipv6_item = proto_tree_add_item(tree, proto_ipv6, tvb, offset, -1, ENC_NA);
- ipv6_tree = proto_item_add_subtree(ipv6_item, ett_ipv6);
+ ipv6_item = proto_tree_add_item(tree, proto_ipv6, tvb, offset, -1, ENC_NA);
+ ipv6_tree = proto_item_add_subtree(ipv6_item, ett_ipv6);
+ if (tree) {
/* !!! warning: (4-bit) version, (6-bit) DSCP, (1-bit) ECN-ECT, (1-bit) ECN-CE and (20-bit) Flow */
pi = proto_tree_add_item(ipv6_tree, hf_ipv6_version, tvb,
offset + (int)offsetof(struct ip6_hdr, ip6_vfc), 1, ENC_BIG_ENDIAN);
@@ -1812,8 +1812,6 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_item(ipv6_tree, hf_ipv6_hlim, tvb,
offset + (int)offsetof(struct ip6_hdr, ip6_hlim), 1, ENC_BIG_ENDIAN);
- /* Yes, there is not TTL in IPv6 Header... but it is the same of Hop Limit...*/
- pinfo->ip_ttl = tvb_get_guint8(tvb, offset + (int)offsetof(struct ip6_hdr, ip6_hlim));
/* Add the different items for the source address */
proto_tree_add_item(ipv6_tree, hf_ipv6_src, tvb,
@@ -1995,6 +1993,12 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
add_geoip_info(ipv6_tree, tvb, offset, &ipv6.ip6_src, &ipv6.ip6_dst);
}
#endif
+ /* Fill in IPv4 fields for potential subdissectors */
+ iph.ip_v_hl = (tvb_get_guint8(tvb, offset + (int)offsetof(struct ip6_hdr, ip6_vfc)) >> 4) & 0x0F;
+ iph.ip_tos = (guint8)((tvb_get_ntohl(tvb, offset + (int)offsetof(struct ip6_hdr, ip6_flow)) >> 20) & 0xFF);
+ iph.ip_len = tvb_get_ntohs(tvb, offset + (int)offsetof(struct ip6_hdr, ip6_plen));
+ /* Yes, there is not TTL in IPv6 Header... but it is the same of Hop Limit...*/
+ iph.ip_ttl = tvb_get_guint8(tvb, offset + (int)offsetof(struct ip6_hdr, ip6_hlim));
/* start of the new header (could be a extension header) */
nxt = tvb_get_guint8(tvb, offset + 6);
@@ -2015,7 +2019,7 @@ again:
case IP_PROTO_HOPOPTS:
hopopts = TRUE;
- advance = dissect_hopopts(tvb, offset, ipv6_tree, pinfo);
+ advance = dissect_hopopts(tvb, offset, ipv6_tree, pinfo, &iph);
nxt = tvb_get_guint8(tvb, offset);
offset += advance;
plen -= advance;
@@ -2077,7 +2081,7 @@ again:
case IP_PROTO_DSTOPTS:
dstopts = TRUE;
- advance = dissect_dstopts(tvb, offset, ipv6_tree, pinfo);
+ advance = dissect_dstopts(tvb, offset, ipv6_tree, pinfo, &iph);
nxt = tvb_get_guint8(tvb, offset);
offset += advance;
plen -= advance;
@@ -2112,25 +2116,24 @@ again:
/* COL_INFO was filled in by "dissect_frag6()" */
call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
return;
- } else {
- /* First fragment, not fragmented, or already reassembled. Dissect what we have here. */
-
- /* Get a tvbuff for the payload. */
- next_tvb = tvb_new_subset_remaining(tvb, offset);
-
- /*
- * If this is the first fragment, but not the only fragment,
- * tell the next protocol that.
- */
- if (offlg & IP6F_MORE_FRAG)
- pinfo->fragmented = TRUE;
- else
- pinfo->fragmented = FALSE;
- }
-
+ }
+
+ /* First fragment, not fragmented, or already reassembled. Dissect what we have here. */
+
+ /* Get a tvbuff for the payload. */
+ next_tvb = tvb_new_subset_remaining(tvb, offset);
+
+ /*
+ * If this is the first fragment, but not the only fragment,
+ * tell the next protocol that.
+ */
+ if (offlg & IP6F_MORE_FRAG)
+ pinfo->fragmented = TRUE;
+ else
+ pinfo->fragmented = FALSE;
/* do lookup with the subdissector table */
- if (!dissector_try_uint(ip_dissector_table, nxt, next_tvb, pinfo, tree)) {
+ if (!dissector_try_uint_new(ip_dissector_table, nxt, next_tvb, pinfo, tree, TRUE, &iph)) {
/* Unknown protocol.
Handle "no next header" specially. */
if (nxt == IP_PROTO_NONE) {
diff --git a/epan/packet_info.h b/epan/packet_info.h
index 57be0fe35f..73bbc4ba57 100644
--- a/epan/packet_info.h
+++ b/epan/packet_info.h
@@ -133,7 +133,6 @@ typedef struct _packet_info {
*/
guint32 bytes_until_next_pdu;
- guint8 ip_ttl; /**< IP time to live */
int p2p_dir; /**< Packet was captured as an
outbound (P2P_DIR_SENT)
inbound (P2P_DIR_RECV)