On Mon, May 18, 2020 at 03:50:05PM +0200, Patrick Wildt wrote:
> Hi,
> 
> I was trying to tftpboot and had an issue with files of odd-length.
> As it turns out, I think the in_cksum() that's called for UDP payload
> cannot handle a payload length that's not aligned to 16 bytes.
> 
> I don't know how in_cksum() is supposed to work exactly, but it looks
> like the first step is summing up all bytes.  The code is using 16-
> byte blocks, apart from some oddbyte magic.
> 
> First of all, why is there a while loop around code that already
> consumes the whole length?  That can be done in a single step
> without the loop.  Why does it continue of there's an "oddbyte"?
> 
> If I simplify that whole construct, consuming in 16-bytes step
> until there's only one left, then summing that one, in_cksum()
> works for me.
> 
> Can someone please help me have a look?

There are other versions of in_cksum in our tree.
Like: ./usr.sbin/ospfd/in_cksum.c

I'm surprised that the libsa code does no htons / ntohs conversions.
Also after looking at the ospfd/in_cksum.c code I wonder if the htons /
ntohs are actually reversed in that that code...
 
> Patrick
> 
> diff --git a/sys/lib/libsa/in_cksum.c b/sys/lib/libsa/in_cksum.c
> index d3f2e6ac978..57ded38a7b7 100644
> --- a/sys/lib/libsa/in_cksum.c
> +++ b/sys/lib/libsa/in_cksum.c
> @@ -59,31 +59,24 @@
>  int
>  in_cksum(const void *p, int len)
>  {
> -     int sum = 0, oddbyte = 0, v = 0;
>       const u_char *cp = p;
> +     int sum = 0;
>  
>       /* we assume < 2^16 bytes being summed */
> -     while (len > 0) {
> -             if (oddbyte) {
> -                     sum += v + *cp++;
> -                     len--;
> -             }
> +     while (len > 1) {
>               if (((long)cp & 1) == 0) {
> -                     while ((len -= 2) >= 0) {
> -                             sum += *(const u_short *)cp;
> -                             cp += 2;
> -                     }
> +                     sum += *(const u_short *)cp;
> +                     cp += 2;
>               } else {
> -                     while ((len -= 2) >= 0) {
> -                             sum += *cp++ << 8;
> -                             sum += *cp++;
> -                     }
> +                     sum += *cp++ << 8;
> +                     sum += *cp++;
>               }
> -             if ((oddbyte = len & 1) != 0)
> -                     v = *cp << 8;
> +             len -= 2;
> +     }
> +     if (len > 0) {
> +             sum += *cp++;
> +             len--;
>       }
> -     if (oddbyte)
> -             sum += v;
>       sum = (sum >> 16) + (sum & 0xffff); /* add in accumulated carries */
>       sum += sum >> 16;               /* add potential last carry */
>       return (0xffff & ~sum);
> 

-- 
:wq Claudio

Reply via email to