[net.bugs.4bsd] BEWARE of TCP port numbers in 4.1c & 4.2BSD

msc@qubix.UUCP (Mark Callow) (01/05/84)

Arrgh!! I've just spent a frustating hour trying to find out why
binding to tcp port number 2048 failed with "permission denied" on a
vax running 4.2 and worked on a Sun running 4.1c.

It seems the port number specified in the 'struct sockaddr_in' must
be in NETWORK order.  This is the same as host order on a sun (68010)
hence the program (which sun supplied) worked fine.  On the vax
it is byte and word swapped from host order so the program bombed
when it tested the port against the reserved port numbers. (ie,
was it < 1024?)

I have not seen this *important* fact documented anywhere.  I looked up
the inet(4f) page and it doesn't say anything about the port address.
It does say that "internet addresses are four byte quantities, stored
in network standard format".  This must be refering to the 'struct
in_addr sin_addr' portion of the 'struct sockaddr_in'

This seems an incredibly strange choice.  Intuitively the user should
be able to deal only with host order and leave it to the kernel to
convert addresses as necessary.  It is incredibly confusing to look up
the constant IPPORT_RESERVED in /usr/include/netinet/in.h and find it
has a value 1024 when a similar constant in your own program must be
declared as 0x0004 or you must use htons(1024).  Whoever wrote the code
in the kernel that checks against IPPORT_RESERVED thought so too.
{Her,His} comment was "GROSS".

I was all set to change the kernel thinking it had to be a bug when I
looked at the source for rlogind and for getservbyname and discovered
that they byte swap port numbers.
-- 
From the Tardis of Mark Callow
msc@qubix.UUCP,  decwrl!qubix!msc@Berkeley.ARPA
...{decvax,ucbvax,ihnp4}!decwrl!qubix!msc, ...{ittvax,amd70}!qubix!msc

jsq@ut-sally.UUCP (John Quarterman) (01/06/84)

x
	From: msc@qubix.UUCP (Mark Callow)
	Message-ID: <747@qubix.UUCP>
	Date: Wed, 4-Jan-84 15:46:36 CST

	...

	It seems the port number specified in the 'struct sockaddr_in' must
	be in NETWORK order.  This is the same as host order on a sun (68010)
	hence the program (which sun supplied) worked fine.  On the vax
	it is byte and word swapped from host order so the program bombed
	when it tested the port against the reserved port numbers. (ie,
	was it < 1024?)

	I have not seen this *important* fact documented anywhere.  I looked up
	the inet(4f) page and it doesn't say anything about the port address.
	It does say that "internet addresses are four byte quantities, stored
	in network standard format".  This must be refering to the 'struct
	in_addr sin_addr' portion of the 'struct sockaddr_in'

From byteorder(3n):

	DESCRIPTION
	     These routines convert 16 and 32 bit quantities between net-
	     work byte order and host byte order.  On machines such as
	     the SUN these routines are defined as null macros in the
	     include file <_n_e_t_i_n_e_t/_i_n._h>.
	
	     These routines are most often used in conjunction with
	     Internet addresses and ports as returned by _g_e_t_h_o_s_t_e_n_t(3N)
	     and _g_e_t_s_e_r_v_e_n_t(3N).
	
	SEE ALSO
	     gethostent(3N), getservent(3N)
	
	BUGS
	     The VAX handles bytes backwards from most everyone else in
	     the world.  This is not expected to be fixed in the near
	     future.

Seems pretty obvious to me from this that any 16 or 32 bit integer that
goes out over the Internet must be byte swapped.  Port numbers are 32 bits.
Of course, the version of byteorder(3N) above came from a VAX, but I'd
guess it's the same on SUN's 4.2.

	This seems an incredibly strange choice.  Intuitively the user should
	be able to deal only with host order and leave it to the kernel to
	convert addresses as necessary.  It is incredibly confusing to look up
	the constant IPPORT_RESERVED in /usr/include/netinet/in.h and find it
	has a value 1024 when a similar constant in your own program must be
	declared as 0x0004 or you must use htons(1024).  Whoever wrote the code
	in the kernel that checks against IPPORT_RESERVED thought so too.
	{Her,His} comment was "GROSS".

And I always thought the GROSS comment referred to the idea of reserving
a range of port numbers that only root could listen on....
-- 
John Quarterman, CS Dept., University of Texas, Austin, Texas
{ihnp4,seismo,ctvax}!ut-sally!jsq, jsq@ut-sally.{ARPA,UUCP}