diff options
author | Michael Mann <mmann78@netscape.net> | 2013-11-23 19:16:05 +0000 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2013-11-23 19:16:05 +0000 |
commit | 55c6869980d76369255442d7e32d35965ae29625 (patch) | |
tree | a535aac635bc9b356bebaa7e0f042dffe6fd08b9 /epan | |
parent | 9150571bf3f68f3a1d5fcbfd1b05b55160dabd6a (diff) |
Remove ip_ttl from packet_info structure.
Part of the fix includes having the IPv6 dissector populate as much of a ws_ip structure as possible to pass to subdissectors of the "ip.proto" table, so the ttl value can be picked up.
svn path=/trunk/; revision=53522
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-icmp.c | 11 | ||||
-rw-r--r-- | epan/dissectors/packet-icmpv6.c | 6 | ||||
-rw-r--r-- | epan/dissectors/packet-ip.c | 33 | ||||
-rw-r--r-- | epan/dissectors/packet-ipv6.c | 79 | ||||
-rw-r--r-- | epan/packet_info.h | 1 |
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) |