aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-hip.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2014-08-08 18:09:00 -0700
committerGuy Harris <guy@alum.mit.edu>2014-08-09 01:09:34 +0000
commitebff85fdbbe9667f469e18686ad945f634be2682 (patch)
tree325c6cf517f4644339d26bd7f0e57ff2c4097e7b /epan/dissectors/packet-hip.c
parentfe74e319c0d27fb516577ce521719fba973e8113 (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-hip.c')
-rw-r--r--epan/dissectors/packet-hip.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/epan/dissectors/packet-hip.c b/epan/dissectors/packet-hip.c
index b7501c0cde..6dd263fd11 100644
--- a/epan/dissectors/packet-hip.c
+++ b/epan/dissectors/packet-hip.c
@@ -416,6 +416,8 @@ dissect_hip_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean
int length, offset = 0, newoffset = 0;
guint16 control_h, checksum_h, computed_checksum;
guint16 tlv_type_h, tlv_length_h; /* For storing in host order */
+ guint len;
+ guint reported_len;
vec_t cksum_vec[4];
guint32 phdr[2];
@@ -482,29 +484,26 @@ dissect_hip_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean
((hiph_shim6_fixed_bit_s) ? "HIP" : "SHIM6"));
/* Checksum - this is the same algorithm from UDP, ICMPv6 */
- if (!pinfo->fragmented) {
+ reported_len = tvb_reported_length(tvb);
+ len = tvb_captured_length(tvb);
+ if (!pinfo->fragmented && len >= reported_len) {
/* IPv4 or IPv6 addresses */
- 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;
+ 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);
/* the rest of the pseudo-header */
if (pinfo->src.type == AT_IPv6) {
- cksum_vec[2].ptr = (const guint8 *)&phdr;
- phdr[0] = tvb_reported_length(tvb);
+ phdr[0] = reported_len;
phdr[0] = g_htonl(phdr[0]); /* Note: g_htonl() macro may eval arg multiple times */
phdr[1] = g_htonl(IP_PROTO_HIP);
- cksum_vec[2].len = 8;
+ SET_CKSUM_VEC_PTR(cksum_vec[2], (const guint8 *)&phdr, 8);
} else {
- cksum_vec[2].ptr = (const guint8 *)&phdr;
- phdr[0] = (IP_PROTO_HIP<<16)+tvb_reported_length(tvb);
+ phdr[0] = (IP_PROTO_HIP<<16)+reported_len;
phdr[0] = g_htonl(phdr[0]); /* Note: g_htonl() macro may eval arg multiple times */
- cksum_vec[2].len = 4;
+ SET_CKSUM_VEC_PTR(cksum_vec[2], (const guint8 *)&phdr, 4);
}
/* pointer to the HIP header (packet data) */
- cksum_vec[3].len = tvb_reported_length(tvb);
- cksum_vec[3].ptr = tvb_get_ptr(tvb, 0, cksum_vec[3].len);
+ SET_CKSUM_VEC_TVB(cksum_vec[3], tvb, 0, reported_len);
computed_checksum = in_cksum(cksum_vec, 4);
if (computed_checksum == 0) {
proto_tree_add_uint_format_value(hip_tree, hf_hip_checksum, tvb,