Re: [OFFTOPIC?] Re: 2.2.x kernels missend odd-sized ICMP pa

Horst von Brand (vonbrand@sleipnir.valparaiso.cl)
Sun, 11 Apr 1999 21:51:35 -0400


(This is an excerpt from ping.c:in_cksum in netkit-0.10, sent to me by Petr
Vandrovec):

register u_short *w = addr;
register int sum = 0;
u_short answer = 0;
....
*(u_char*)(&answer) = *(u_char*)w;
sum += answer;

This is a dumb way to write this.

egcs-19990405 generates code that gets the right value, others (including
egcs-1.0.3 used to build RedHat-5.2, AFAIKS) break, as they don't respect
the initialization and put a random byte in the higher half.

A better way to write the above is just:

sum += *(u_char*)w;

I can see no endianess issues here. This works with the compilers I have
here (gcc-2.7.2.3, egcs-1.1.1 and 1.1.2, egcs-19990405). A patch follows:

--- ping.c.old Fri Apr 9 09:14:26 1999
+++ ping.c Sun Apr 11 21:34:30 1999
@@ -886,7 +886,6 @@
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
- u_short answer = 0;

/*
* Our algorithm is simple, using a 32 bit accumulator (sum), we add
@@ -899,16 +898,13 @@
}

/* mop up an odd byte, if necessary */
- if (nleft == 1) {
- *(u_char *)(&answer) = *(u_char *)w ;
- sum += answer;
- }
+ if (nleft == 1)
+ sum += *(u_char *)w;

/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
- answer = ~sum; /* truncate to 16 bits */
- return(answer);
+ return (u_short) ~sum; /* Truncate to 16 bits */
}

/*

BTW, Comer's "Internetworking with TPC/IP, vol 1" tells me that the
checksum is computed by ones' complement sum of 16bit quantities in network
byte order and stored in network byte order (i.e., big endian), the
computation in ping.c:in_cksum is clearly in host format (little endian
around here). What gives?

-- 
Horst von Brand                             vonbrand@sleipnir.valparaiso.cl
Casilla 9G, Viņa del Mar, Chile                               +56 32 672616

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/