ISC dhcp server on NetBSD

dhcp.50.CHRIS94561 at spamgourmet.com dhcp.50.CHRIS94561 at spamgourmet.com
Sun Apr 25 13:39:44 UTC 2004


  From: dhcp.50.CHRIS94561 at spamgourmet.com

  > I'd say that it is reasonable for ntohl to be unsigned, since a 32-bit
  > quantity in non-native byte order shouldn't be treated as signed
  > (which implies native byte order).  time_t might become 64 bits in the
  > future, too.

  Problem is that time_t is a signed, not unsigned.

The code is converting between on-the-wire types, which are of course
a size fixed by the protocol, into host types.  So a variable which is
the right type for the wire format (uint32_t, I'd argue) should be
used to hold the bits in wire format, and the assignment to a time_t
variable only done after the ntohl, and that probably should have an
explicit cast.

    While that all may be true. Part of the question I'm asking is: Why does
  the same code compile on Linux and not NetBSD? In both cases ntohl is
  unsigned and time_t is signed. So why the discrepancy in the compiler
  behavior?

On NetBSD/i386 1.6.2 (which I am guessing you are using), ntohl
expands to an inline function, which therefore does type checking:

  static __inline u_int32_t
  __byte_swap_long_variable(u_int32_t x)
  {
	  __asm __volatile (
  #if defined(_KERNEL) && !defined(_LKM) && !defined(I386_CPU)
	      "bswap %1"
  #else
	      "rorw $8, %w1\n\trorl $16, %1\n\trorw $8, %w1"
  #endif
	      : "=r" (x) : "0" (x));
	  return (x);
  }

There is also a macro for doing this, used if __OPTIMIZE__ is not
defined or for constants, which won't do much type checking (but might
warn if the provided type is too small to hold 0xff000000):

  #define	__byte_swap_long_constant(x) \
	  ((((x) & 0xff000000) >> 24) | \
	   (((x) & 0x00ff0000) >>  8) | \
	   (((x) & 0x0000ff00) <<  8) | \
	   (((x) & 0x000000ff) << 24))


More information about the dhcp-hackers mailing list