checked in.

tx for your submission.

/hannes

Gerrit Renker wrote:
> This introduces support for variable-length checksum in 
> DCCP, as it is specified in section 9 of RFC 4340. 
> 
> Previously tcpdump was only able to validate full-coverage
> checksums, this patch verifies checksums in accordance with
> the CsCov header field (sec. 5.3). 
> 
> The patch has been tested and verified on DCCPv4 and DCCPv6
> connections, checksums were manually validated, and traces
> can be supplied.  
> 
> 
> 
> In addition, the patch also
>       * removes reduplicated code in dccp6_cksum (which 
>           just repeated the code of in_cksum)
>       * fixes a bug in dccp.h -- the fields of CCVAL and
>         CSCOV were swapped (cf. section 5.1 of RFC 4340)
>       * fixes a typo in the display of incorrect checksums
>         (these were printed as `cksum xDEAD (incorrect (->  xBEEF)',
>            it now will print  `cksum xDEAD (incorrect -> xBEEF)'
> 
> I would like to see this merged as a Linux kernel patch already
> exists for DCCP partial checksum coverage support.
> 
> Regards
> Gerrit Renker
> 
> 
>  dccp.h       |    4 ++--
>  print-dccp.c |   34 ++++++++++++++++------------------
>  2 files changed, 18 insertions(+), 20 deletions(-)
> 
> 
> ------------------------------------------------------------------------
> 
> diff --git a/dccp.h b/dccp.h
> index 1afa8c0..8585060 100644
> --- a/dccp.h
> +++ b/dccp.h
> @@ -36,8 +36,8 @@ struct dccp_hdr {
>       }               dccph_xtrs;
>  };
>  
> -#define DCCPH_CCVAL(dh)      (((dh)->dccph_ccval_cscov) & 0x0F)
> -#define DCCPH_CSCOV(dh)      (((dh)->dccph_ccval_cscov >> 4) & 0x0F)
> +#define DCCPH_CCVAL(dh)      (((dh)->dccph_ccval_cscov >> 4) & 0xF)
> +#define DCCPH_CSCOV(dh)      (((dh)->dccph_ccval_cscov) & 0xF)
>  
>  #define DCCPH_X(dh)  ((dh)->dccph_xtrs.dccph_xtr & 1)
>  #define DCCPH_TYPE(dh)       (((dh)->dccph_xtrs.dccph_xtr >> 1) & 0xF)
> diff --git a/print-dccp.c b/print-dccp.c
> index e6bfca6..d19c500 100644
> --- a/print-dccp.c
> +++ b/print-dccp.c
> @@ -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)
> +{
> +     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 *i
>               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_
>       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
>  
> @@ -288,7 +286,7 @@ #ifdef INET6
>                       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));
> +                             (void)printf(" (incorrect -> 0x%04x), 
> ",in_cksum_shouldbe(dccp_sum, sum));
>                       } else
>                               (void)printf(" (correct), ");
>               }                                       
> 
> 
> ------------------------------------------------------------------------
> 
> -
> This is the tcpdump-workers list.
> Visit https://cod.sandelman.ca/ to unsubscribe.
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.

Reply via email to