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? 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);