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

Reply via email to