Subject: kern/4440: kernel uses obsolete range for ephemeral ports
To: None <gnats-bugs@gnats.netbsd.org>
From: Luke Mewburn <lukem@karybdis.cs.rmit.edu.au>
List: netbsd-bugs
Date: 11/07/1997 00:05:23
>Number:         4440
>Category:       kern
>Synopsis:       kernel uses 1024-5000 instead of 49152-65535 for ephemeral ports
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   lm
>Arrival-Date:   Thu Nov  6 05:20:08 1997
>Last-Modified:
>Originator:     Luke Mewburn
>Organization:
NetBSD code grunts
>Release:        NetBSD-current-971025
>Environment:
System: NetBSD karybdis 1.3A NetBSD 1.3A (LUKEM) #3: Sun Oct 26 01:13:48 EST 1997 lukem@karybdis:/z/src/current/src/sys/arch/i386/compile/LUKEM i386

>Description:
	according to the latest IANA assigned port numbers document, which
	is found at:
		ftp://ftp.isi.edu/in-notes/iana/assignments/port-numbers
	the ephemeral port numbers are in the range 49152-65535.

	to quote:
		``The Dynamic and/or Private Ports are those from 49152
		  through 65535''

	other literature seems to indicate that the original choice of
	1024-5000 in 4.3BSD was actually a mistake (it should have been
	1024-50000), but the current philosophy appears to be that
	49152-65535 makes more sense (probably due to the lack of
	assigned ports in that range.)

>How-To-Repeat:
	make a connection where the local end is an ephemeral port.
	notice that it starts at 1025.
	
>Fix:
	apply this simplistic patch. i've had it running on one of
	my workstations for a few days. i didn't get a chance to
	`wrap' the ports, so i may have a fencepost error at the
	IPPORT_USERHIGH boundary (although i don't think so).

	maybe a more generic solution is required, allowing these
	to be controlled with sysctl: solaris allows these figures
	to be tuned separately for tcp and udp, but i'm not sure if
	there's great benefit in providing that.  on the other hand,
	the IANA document specifies what the port range is, so i'm
	not sure if there's that great a benefit in allowing it to be
	(easily) modified by the user...

	if this patch is applied, [kern/4226] would need to be
	reworked, although it shouldn't be hard. in the long term,
	maybe part of the problem highlighted in [kern/4226] would
	be solved by using random port allocation anyway...


Index: in.h
===================================================================
RCS file: /cvsroot/src/sys/netinet/in.h,v
retrieving revision 1.28
diff -c -r1.28 in.h
*** in.h	1997/10/18 21:18:29	1.28
--- in.h	1997/11/06 12:46:50
***************
*** 68,80 ****
  
  /*
   * Local port number conventions:
!  * Ports < IPPORT_RESERVED are reserved for
!  * privileged processes (e.g. root).
!  * Ports > IPPORT_USERRESERVED are reserved
!  * for servers, not necessarily privileged.
   */
  #define	IPPORT_RESERVED		1024
! #define	IPPORT_USERRESERVED	5000
  
  /*
   * Internet address (a structure for historical reasons)
--- 68,79 ----
  
  /*
   * Local port number conventions:
!  * Ports < IPPORT_RESERVED are reserved for privileged processes (e.g. root).
!  * IPPORT_USERLOW <= Ports <= IPPORT_USERHIGH are for dynamic connections.
   */
  #define	IPPORT_RESERVED		1024
! #define	IPPORT_USERLOW		49152
! #define	IPPORT_USERHIGH		65535
  
  /*
   * Internet address (a structure for historical reasons)
Index: in_pcb.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/in_pcb.c,v
retrieving revision 1.39
diff -c -r1.39 in_pcb.c
*** in_pcb.c	1997/10/14 00:52:49	1.39
--- in_pcb.c	1997/11/06 12:46:58
***************
*** 82,88 ****
  	    hashinit(bindhashsize, M_PCB, &table->inpt_bindhash);
  	table->inpt_connecthashtbl =
  	    hashinit(connecthashsize, M_PCB, &table->inpt_connecthash);
! 	table->inpt_lastport = IPPORT_RESERVED;
  }
  
  int
--- 82,88 ----
  	    hashinit(bindhashsize, M_PCB, &table->inpt_bindhash);
  	table->inpt_connecthashtbl =
  	    hashinit(connecthashsize, M_PCB, &table->inpt_connecthash);
! 	table->inpt_lastport = IPPORT_USERLOW;
  }
  
  int
***************
*** 176,186 ****
  noname:
  	if (lport == 0) {
  		for (lport = table->inpt_lastport + 1;
! 		    lport < IPPORT_USERRESERVED; lport++)
  			if (!in_pcblookup_port(table, inp->inp_laddr,
  			    htons(lport), wild))
  				goto found;
! 		for (lport = IPPORT_RESERVED;
  		    lport <= table->inpt_lastport; lport++)
  			if (!in_pcblookup_port(table, inp->inp_laddr,
  			    htons(lport), wild))
--- 176,186 ----
  noname:
  	if (lport == 0) {
  		for (lport = table->inpt_lastport + 1;
! 		    lport <= IPPORT_USERHIGH; lport++)
  			if (!in_pcblookup_port(table, inp->inp_laddr,
  			    htons(lport), wild))
  				goto found;
! 		for (lport = IPPORT_USERLOW;
  		    lport <= table->inpt_lastport; lport++)
  			if (!in_pcblookup_port(table, inp->inp_laddr,
  			    htons(lport), wild))
	don't 
>Audit-Trail:
>Unformatted: