diff options
Diffstat (limited to 'print-dccp.c')
-rw-r--r-- | print-dccp.c | 71 |
1 files changed, 29 insertions, 42 deletions
diff --git a/print-dccp.c b/print-dccp.c index e6bfca6..b7377cf 100644 --- a/print-dccp.c +++ b/print-dccp.c @@ -9,7 +9,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-dccp.c,v 1.1.2.6 2006/02/19 05:08:44 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-dccp.c,v 1.7.2.1 2007-11-09 00:45:16 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -60,9 +60,20 @@ static const char *dccp_feature_nums[] = { "check data checksum", }; +static inline int dccp_csum_coverage(const struct dccp_hdr* dh, u_int len) +{ + u_int cov; + + if (DCCPH_CSCOV(dh) == 0) + return len; + cov = (dh->dccph_doff + DCCPH_CSCOV(dh) - 1) * sizeof(u_int32_t); + return (cov > len)? len : cov; +} + static int dccp_cksum(const struct ip *ip, const struct dccp_hdr *dh, u_int len) { + int cov = dccp_csum_coverage(dh, len); union phu { struct phdr { u_int32_t src; @@ -86,15 +97,15 @@ static int dccp_cksum(const struct ip *ip, phu.ph.dst = ip_finddst(ip); sp = &phu.pa[0]; - return in_cksum((u_short *)dh, len, sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]); + return in_cksum((u_short *)dh, cov, sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]); } #ifdef INET6 static int dccp6_cksum(const struct ip6_hdr *ip6, const struct dccp_hdr *dh, u_int len) { size_t i; - const u_int16_t *sp; - u_int32_t sum; + u_int32_t sum = 0; + int cov = dccp_csum_coverage(dh, len); union { struct { struct in6_addr ph_src; @@ -113,23 +124,10 @@ static int dccp6_cksum(const struct ip6_hdr *ip6, const struct dccp_hdr *dh, u_i phu.ph.ph_len = htonl(len); phu.ph.ph_nxt = IPPROTO_DCCP; - sum = 0; for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++) sum += phu.pa[i]; - sp = (const u_int16_t *)dh; - - for (i = 0; i < (len & ~1); i += 2) - sum += *sp++; - - if (len & 1) - sum += htons((*(const u_int8_t *)sp) << 8); - - while (sum > 0xffff) - sum = (sum & 0xffff) + (sum >> 16); - sum = ~sum & 0xffff; - - return (sum); + return in_cksum((u_short *)dh, cov, sum); } #endif @@ -279,32 +277,21 @@ void dccp_print(const u_char *bp, const u_char *data2, u_int len) } /* checksum calculation */ -#ifdef INET6 - if (ip6) { - if (ip6->ip6_plen && vflag) { - u_int16_t sum, dccp_sum; + if (vflag && TTEST2(bp[0], len)) { + u_int16_t sum = 0, dccp_sum; + dccp_sum = EXTRACT_16BITS(&dh->dccph_checksum); + (void)printf("cksum 0x%04x ", dccp_sum); + if (IP_V(ip) == 4) + sum = dccp_cksum(ip, dh, len); +#ifdef INET6 + else if (IP_V(ip) == 6) sum = dccp6_cksum(ip6, dh, len); - dccp_sum = EXTRACT_16BITS(&dh->dccph_checksum); - printf("cksum 0x%04x", dccp_sum); - if (sum != 0) { - (void)printf(" (incorrect (-> 0x%04x), ",in_cksum_shouldbe(dccp_sum, sum)); - } else - (void)printf(" (correct), "); - } - } else -#endif /* INET6 */ - if (vflag) - { - u_int16_t sum, dccp_sum; - - sum = dccp_cksum(ip, dh, len); - dccp_sum = EXTRACT_16BITS(&dh->dccph_checksum); - printf("cksum 0x%04x", dccp_sum); - if (sum != 0) { - (void)printf(" (incorrect (-> 0x%04x), ",in_cksum_shouldbe(dccp_sum, sum)); - } else - (void)printf(" (correct), "); +#endif + if (sum != 0) + (void)printf("(incorrect -> 0x%04x), ",in_cksum_shouldbe(dccp_sum, sum)); + else + (void)printf("(correct), "); } switch (DCCPH_TYPE(dh)) { |