diff options
author | peter <peter@FreeBSD.org> | 1996-02-22 21:32:23 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1996-02-22 21:32:23 +0000 |
commit | fe35eac01c2144b50535ae23a00660c11524fd22 (patch) | |
tree | 00ca04534534b22254d22056ecd77387d0c0ec90 /sys/netinet/ip_output.c | |
parent | f7cfae926eb054cccf8e9a58065b4e8a2874d530 (diff) | |
download | FreeBSD-src-fe35eac01c2144b50535ae23a00660c11524fd22.zip FreeBSD-src-fe35eac01c2144b50535ae23a00660c11524fd22.tar.gz |
Make the default behavior of local port assignment match traditional
systems (my last change did not mix well with some firewall
configurations). As much as I dislike firewalls, this is one thing I
I was not prepared to break by default.. :-)
Allow the user to nominate one of three ranges of port numbers as
candidates for selecting a local address to replace a zero port number.
The ranges are selected via a setsockopt(s, IPPROTO_IP, IP_PORTRANGE, &arg)
call. The three ranges are: default, high (to bypass firewalls) and
low (to get a port below 1024).
The default and high port ranges are sysctl settable under sysctl
net.inet.ip.portrange.*
This code also fixes a potential deadlock if the system accidently ran out
of local port addresses. It'd drop into an infinite while loop.
The secure port selection (for root) should reduce overheads and increase
reliability of rlogin/rlogind/rsh/rshd if they are modified to take
advantage of it.
Partly suggested by: pst
Reviewed by: wollman
Diffstat (limited to 'sys/netinet/ip_output.c')
-rw-r--r-- | sys/netinet/ip_output.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 2a463c2..58220b8 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)ip_output.c 8.3 (Berkeley) 1/21/94 - * $Id: ip_output.c,v 1.26 1995/12/05 17:46:15 wollman Exp $ + * $Id: ip_output.c,v 1.27 1995/12/19 21:24:19 wollman Exp $ */ #include <sys/param.h> @@ -635,6 +635,35 @@ ip_ctloutput(op, so, level, optname, mp) error = ip_setmoptions(optname, &inp->inp_moptions, m); break; + case IP_PORTRANGE: + if (m == 0 || m->m_len != sizeof(int)) + error = EINVAL; + else { + optval = *mtod(m, int *); + + switch (optval) { + + case IP_PORTRANGE_DEFAULT: + inp->inp_flags &= ~(INP_LOWPORT); + inp->inp_flags &= ~(INP_HIGHPORT); + break; + + case IP_PORTRANGE_HIGH: + inp->inp_flags &= ~(INP_LOWPORT); + inp->inp_flags |= INP_HIGHPORT; + break; + + case IP_PORTRANGE_LOW: + inp->inp_flags &= ~(INP_HIGHPORT); + inp->inp_flags |= INP_LOWPORT; + break; + + default: + error = EINVAL; + break; + } + } + default: error = ENOPROTOOPT; break; @@ -699,6 +728,20 @@ ip_ctloutput(op, so, level, optname, mp) error = ip_getmoptions(optname, inp->inp_moptions, mp); break; + case IP_PORTRANGE: + *mp = m = m_get(M_WAIT, MT_SOOPTS); + m->m_len = sizeof(int); + + if (inp->inp_flags & INP_HIGHPORT) + optval = IP_PORTRANGE_HIGH; + else if (inp->inp_flags & INP_LOWPORT) + optval = IP_PORTRANGE_LOW; + else + optval = 0; + + *mtod(m, int *) = optval; + break; + default: error = ENOPROTOOPT; break; |