shannon (02/02/83)
There is a bug in the checksum routine in the packet driver
used with uucp. This is a portability bug I found when porting
my uucp to the Sun. The problem occurs when converting a variable
of type short to a variable of type unsigned int, where int and
short are not the same. K&R (pg. 41) seems to imply that the
variable will first be sign extended to int and then converted
to unsigned, although I am not sure of that interpretation. The
VAX C compiler seems to convert to unsigned, then to int (movzwl).
Our 68000 C compiler converts to int (extw), then treats the result
as unsigned in the expression below. Anyway, here's the fixed
checksum routine for pk0.c:
chksum(s,n)
register char *s;
register n;
{
register short sum;
register unsigned short t;
register short x;
sum = -1;
x = 0;
do {
if (sum<0) {
sum <<= 1;
sum++;
} else
sum <<= 1;
t = sum;
sum += (unsigned)*s++ & 0377;
x += sum^n;
if ((unsigned short)sum <= t) { /***/
sum ^= x;
}
} while (--n > 0);
return(sum&0xffff); /***/
}
Marked lines are changed. There are probably other changes that
would make it more portable but those are the ones that made it
work.
Bill Shannon
sun!shannon