Plamen Alexandrov wrote... > Depending on the endian of the system, the macros le64toh(), > be64toh(), htole64(), htobe64(), etc. could not return a 64-bit type. > This can lead to issues ranging from compilation errors to runtime > crashes.
Yepp, ran into crashes. The same problem exists for the ntoh*/hton* functions in <in.h>. On big- endian architectures, the input value is passed unchanged; on litte endian it's capped to the respective size by __bswap_* Reproducer: ====================================================================== #include <netinet/in.h> #include <stdio.h> int main (int argc, char **argv) { long l1 = 0x12345678; long l2 = ntohs (l1); printf ("Got: %08lx\n", l2); long long ll1 = 0x123456789abcdef; long long ll2 = ntohl (ll1); printf ("Got: %016llx\n", ll2); } ====================================================================== Enable optimizations (-O2 -Wall) when building. Result on amd64: | Got: 00007856 | Got: 00000000efcdab89 Result on powerpc and ppc64: | Got: 12345678 | Got: 0123456789abcdef ... which is out the domain for uint16_t and uint32_t resp. My suggested fix is to mask the according bits: @@ -393,10 +393,10 @@ # if __BYTE_ORDER == __BIG_ENDIAN /* The host byte order is the same as network byte order, so these functions are all just identity. */ -# define ntohl(x) (x) -# define ntohs(x) (x) -# define htonl(x) (x) -# define htons(x) (x) +# define ntohl(x) ((x)&0xffffffff) +# define ntohs(x) ((x)&0xffff) +# define htonl(x) ((x)&0xffffffff) +# define htons(x) ((x)&0xffff) # else # if __BYTE_ORDER == __LITTLE_ENDIAN # define ntohl(x) __bswap_32 (x) This results in a consistent output: | Got: 00005678 | Got: 0000000089abcdef The worse part is gcc doesn't even raise warnings from this. Christoph
signature.asc
Description: Digital signature