diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1999-12-16 21:30:36 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1999-12-16 21:30:36 +0000 |
commit | 6d482af2eab04b3d3aef695c895761acfafa18e0 (patch) | |
tree | 988a0d2394ca3693e23c18db00b406ca3a231ac5 /lib/libc/rpc | |
parent | 1fa54c44ce388765511dd93bab101711fb09cbb5 (diff) |
rresvport_af() and bindresvport_af()
Diffstat (limited to 'lib/libc/rpc')
-rw-r--r-- | lib/libc/rpc/Makefile.inc | 5 | ||||
-rw-r--r-- | lib/libc/rpc/bindresvport.3 | 20 | ||||
-rw-r--r-- | lib/libc/rpc/bindresvport.c | 75 |
3 files changed, 71 insertions, 29 deletions
diff --git a/lib/libc/rpc/Makefile.inc b/lib/libc/rpc/Makefile.inc index d4ea29b4c91..4df12abfb9d 100644 --- a/lib/libc/rpc/Makefile.inc +++ b/lib/libc/rpc/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.8 1998/11/20 11:18:47 d Exp $ +# $OpenBSD: Makefile.inc,v 1.9 1999/12/16 21:30:35 deraadt Exp $ # librpc sources .PATH: ${LIBCSRCDIR}/arch/${MACHINE}/rpc ${LIBCSRCDIR}/rpc @@ -13,7 +13,8 @@ SRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c \ xdr_rec.c xdr_reference.c xdr_stdio.c MAN+= bindresvport.3 getrpcent.3 getrpcport.3 rpc.3 xdr.3 rpcauth.3 -MLINKS+= getrpcent.3 getrpcbyname.3 \ +MLINKS+= bindresvport.3 bindresvport_af.3 \ + getrpcent.3 getrpcbyname.3 \ getrpcent.3 getrpcbynumber.3 \ getrpcent.3 endrpcent.3 \ getrpcent.3 setrpcent.3 \ diff --git a/lib/libc/rpc/bindresvport.3 b/lib/libc/rpc/bindresvport.3 index 4960277753f..39e23eb911a 100644 --- a/lib/libc/rpc/bindresvport.3 +++ b/lib/libc/rpc/bindresvport.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bindresvport.3,v 1.11 1999/07/09 13:35:22 aaron Exp $ +.\" $OpenBSD: bindresvport.3,v 1.12 1999/12/16 21:30:35 deraadt Exp $ .\" .Dd August 9, 1997 .Dt BINDRESVPORT 3 @@ -11,9 +11,13 @@ .Fd #include <netinet/in.h> .Ft int .Fn bindresvport "int sd" "struct sockaddr_in *sin" +.Ft int +.Fn bindresvport_af "int sd" "struct sockaddr *sa" "int af" .Sh DESCRIPTION .Fn bindresvport -is used to bind a socket descriptor to a privileged +and +.Fn bindresvport_af +are used to bind a socket descriptor to a privileged .Tn IP port, that is, a port number in the range 0-1023. .Fa sd @@ -23,10 +27,17 @@ is a socket descriptor that was returned by a call to Only root can bind to a privileged port; this call will fail for any other users. .Pp -If the value of sin->sin_port is non-zero, +If the value of +.Va sin->sin_port +is non-zero, .Fn bindresvport attempts to use the specified port. If that fails, it chooses another privileged port number automatically. +.Pp +.Fn bindresvport_af +acts in a similar way, but supports other protocols as well, such +as +.Va AF_INET6 . .Sh RETURN VALUES .Fn bindresvport returns 0 if it is successful, otherwise \-1 is returned and @@ -67,4 +78,5 @@ system or no implementation for it exists. .Sh SEE ALSO .Xr bind 2 , .Xr socket 2 , -.Xr rresvport 3 +.Xr rresvport 3 , +.Xr rresvport_af 3 diff --git a/lib/libc/rpc/bindresvport.c b/lib/libc/rpc/bindresvport.c index 003de2778cf..fe5ab3b1210 100644 --- a/lib/libc/rpc/bindresvport.c +++ b/lib/libc/rpc/bindresvport.c @@ -28,7 +28,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: bindresvport.c,v 1.9 1996/09/15 09:31:30 tholo Exp $"; +static char *rcsid = "$OpenBSD: bindresvport.c,v 1.10 1999/12/16 21:30:35 deraadt Exp $"; #endif /* LIBC_SCCS and not lint */ /* @@ -51,50 +51,79 @@ bindresvport(sd, sin) int sd; struct sockaddr_in *sin; { - int on, old, error; - struct sockaddr_in myaddr; - int sinlen = sizeof(struct sockaddr_in); + return bindresvport_af(sd, (struct sockaddr *)sin, AF_INET); +} + +/* + * Bind a socket to a privileged IP port + */ +int +bindresvport_af(sd, sa, af) + int sd; + struct sockaddr *sa; + int af; +{ + int old, error; + struct sockaddr_storage myaddr; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + int proto, portrange, portlow; + u_int16_t *portp; + int salen; - if (sin == (struct sockaddr_in *)0) { - sin = &myaddr; - memset(sin, 0, sinlen); - sin->sin_len = sinlen; - sin->sin_family = AF_INET; - } else if (sin->sin_family != AF_INET) { + if (sa == NULL) { + memset(&myaddr, 0, sizeof(myaddr)); + sa = (struct sockaddr *)&myaddr; + } + + if (af == AF_INET) { + proto = IPPROTO_IP; + portrange = IP_PORTRANGE; + portlow = IP_PORTRANGE_LOW; + sin = (struct sockaddr_in *)sa; + salen = sizeof(struct sockaddr_in); + portp = &sin->sin_port; + } else if (af == AF_INET6) { + proto = IPPROTO_IPV6; + portrange = IPV6_PORTRANGE; + portlow = IPV6_PORTRANGE_LOW; + sin6 = (struct sockaddr_in6 *)sa; + salen = sizeof(struct sockaddr_in6); + portp = &sin6->sin6_port; + } else { errno = EPFNOSUPPORT; return (-1); } + sa->sa_family = af; - if (sin->sin_port == 0) { + if (*portp == 0) { int oldlen = sizeof(old); - error = getsockopt(sd, IPPROTO_IP, IP_PORTRANGE, - &old, &oldlen); + + error = getsockopt(sd, proto, portrange, &old, &oldlen); if (error < 0) return(error); - on = IP_PORTRANGE_LOW; - error = setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, - &on, sizeof(on)); + error = setsockopt(sd, proto, portrange, &portlow, + sizeof(portlow)); if (error < 0) return(error); } - error = bind(sd, (struct sockaddr *)sin, sinlen); + error = bind(sd, sa, salen); - if (sin->sin_port == 0) { + if (*portp == 0) { int saved_errno = errno; if (error) { - if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, - &old, sizeof(old)) < 0) + if (setsockopt(sd, proto, portrange, &old, + sizeof(old)) < 0) errno = saved_errno; return (error); } - if (sin != &myaddr) { + if (sa != (struct sockaddr *)&myaddr) { /* Hmm, what did the kernel assign... */ - if (getsockname(sd, (struct sockaddr *)sin, - &sinlen) < 0) + if (getsockname(sd, sa, &salen) < 0) errno = saved_errno; return (error); } |