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/dissectors/packet-ipv6.c | |
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/dissectors/packet-ipv6.c')
-rw-r--r-- | epan/dissectors/packet-ipv6.c | 79 |
1 files changed, 41 insertions, 38 deletions
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) { |