diff options
author | Guy Harris <guy@alum.mit.edu> | 2014-08-08 18:09:00 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2014-08-09 01:09:34 +0000 |
commit | ebff85fdbbe9667f469e18686ad945f634be2682 (patch) | |
tree | 325c6cf517f4644339d26bd7f0e57ff2c4097e7b /epan/dissectors/packet-dccp.c | |
parent | fe74e319c0d27fb516577ce521719fba973e8113 (diff) |
Clean up Internet checksum handling.
Add macros to set entries of a vec_t, one for use when you have a
pointer to private data, and one for use when you have data in a tvbuff.
The latter wraps the use of tvb_get_ptr(), so that you're not directly
calling it in a dissector.
Move ip_checksum() to epan/in_cksum.c, and add an ip_checksum_tvb() that
wraps the use of tvb_get_ptr().
In the CARP dissector, give the length variable an unsigned type -
there's no benefit to it being signed, and that requires some casts to
be thrown around.
In the DCCP dissector, check only against the coverage length to see if
we have enough data, combine the "should we check the checksum?" check
with the "*can* we check the checksum?" check in a single if, and throw
a dissector assertion if the source network address type isn't IPv4 or
IPv6.
Get rid of inclues of <epan/in_cksum.h> in dissectors that don't use any
of the Internet checksum routines.
In the HIP dissector, make sure we have the data to calculate the
checksum before doing so.
Change-Id: I2f9674775dbb54c533d33082632809f7d32ec8ae
Reviewed-on: https://code.wireshark.org/review/3517
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan/dissectors/packet-dccp.c')
-rw-r--r-- | epan/dissectors/packet-dccp.c | 98 |
1 files changed, 45 insertions, 53 deletions
diff --git a/epan/dissectors/packet-dccp.c b/epan/dissectors/packet-dccp.c index b8b2af88e5..b1593a1b1b 100644 --- a/epan/dissectors/packet-dccp.c +++ b/epan/dissectors/packet-dccp.c @@ -631,6 +631,7 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ guint offset = 0; guint len = 0; guint reported_len = 0; + guint csum_coverage_len; guint advertised_dccp_header_len = 0; guint options_len = 0; e_dccphdr *dccph; @@ -716,61 +717,52 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ */ reported_len = tvb_reported_length(tvb); len = tvb_length(tvb); + csum_coverage_len = dccp_csum_coverage(dccph, reported_len); + + if (dccp_check_checksum && !pinfo->fragmented && len >= csum_coverage_len) { + /* We're supposed to check the checksum, and the packet isn't part + * of a fragmented datagram and isn't truncated, so we can checksum it. + * XXX - make a bigger scatter-gather list once we do fragment + * reassembly? */ + /* Set up the fields of the pseudo-header. */ + SET_CKSUM_VEC_PTR(cksum_vec[0], (const guint8 *)pinfo->src.data, pinfo->src.len); + SET_CKSUM_VEC_PTR(cksum_vec[1], (const guint8 *)pinfo->dst.data, pinfo->dst.len); + switch (pinfo->src.type) { + case AT_IPv4: + phdr[0] = g_htonl((IP_PROTO_DCCP << 16) + reported_len); + SET_CKSUM_VEC_PTR(cksum_vec[2], (const guint8 *) &phdr, 4); + break; + case AT_IPv6: + phdr[0] = g_htonl(reported_len); + phdr[1] = g_htonl(IP_PROTO_DCCP); + SET_CKSUM_VEC_PTR(cksum_vec[2], (const guint8 *) &phdr, 8); + break; - if (!pinfo->fragmented && len >= reported_len) { - /* The packet isn't part of a fragmented datagram and isn't - * truncated, so we can checksum it. - * XXX - make a bigger scatter-gather list once we do fragment - * reassembly? */ - if (dccp_check_checksum) { - /* Set up the fields of the pseudo-header. */ - cksum_vec[0].ptr = (const guint8 *)pinfo->src.data; - cksum_vec[0].len = pinfo->src.len; - cksum_vec[1].ptr = (const guint8 *)pinfo->dst.data; - cksum_vec[1].len = pinfo->dst.len; - cksum_vec[2].ptr = (const guint8 *) &phdr; - switch (pinfo->src.type) { - case AT_IPv4: - phdr[0] = g_htonl((IP_PROTO_DCCP << 16) + reported_len); - cksum_vec[2].len = 4; - break; - case AT_IPv6: - phdr[0] = g_htonl(reported_len); - phdr[1] = g_htonl(IP_PROTO_DCCP); - cksum_vec[2].len = 8; - break; - - default: - /* DCCP runs only atop IPv4 and IPv6... */ - break; - } - cksum_vec[3].ptr = tvb_get_ptr(tvb, 0, len); - cksum_vec[3].len = dccp_csum_coverage(dccph, reported_len); - computed_cksum = in_cksum(&cksum_vec[0], 4); - if (computed_cksum == 0) { - proto_tree_add_uint_format_value(dccp_tree, - hf_dccp_checksum, tvb, - offset, 2, - dccph->checksum, - "0x%04x [correct]", - dccph->checksum); - } else { - hidden_item = - proto_tree_add_boolean(dccp_tree, hf_dccp_checksum_bad, - tvb, offset, 2, TRUE); - PROTO_ITEM_SET_HIDDEN(hidden_item); - proto_tree_add_uint_format_value( - dccp_tree, hf_dccp_checksum, tvb, offset, 2, - dccph->checksum, - "0x%04x [incorrect, should be 0x%04x]", - dccph->checksum, - in_cksum_shouldbe(dccph->checksum, computed_cksum)); - } + default: + /* DCCP runs only atop IPv4 and IPv6... */ + DISSECTOR_ASSERT_NOT_REACHED(); + break; + } + SET_CKSUM_VEC_TVB(cksum_vec[3], tvb, 0, csum_coverage_len); + computed_cksum = in_cksum(&cksum_vec[0], 4); + if (computed_cksum == 0) { + proto_tree_add_uint_format_value(dccp_tree, + hf_dccp_checksum, tvb, + offset, 2, + dccph->checksum, + "0x%04x [correct]", + dccph->checksum); } else { - proto_tree_add_uint_format_value(dccp_tree, hf_dccp_checksum, - tvb, - offset, 2, dccph->checksum, - "0x%04x", dccph->checksum); + hidden_item = + proto_tree_add_boolean(dccp_tree, hf_dccp_checksum_bad, + tvb, offset, 2, TRUE); + PROTO_ITEM_SET_HIDDEN(hidden_item); + proto_tree_add_uint_format_value( + dccp_tree, hf_dccp_checksum, tvb, offset, 2, + dccph->checksum, + "0x%04x [incorrect, should be 0x%04x]", + dccph->checksum, + in_cksum_shouldbe(dccph->checksum, computed_cksum)); } } else { proto_tree_add_uint_format_value(dccp_tree, hf_dccp_checksum, tvb, |