summaryrefslogtreecommitdiff
path: root/lib/libc/rpc
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1999-12-16 21:30:36 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1999-12-16 21:30:36 +0000
commit6d482af2eab04b3d3aef695c895761acfafa18e0 (patch)
tree988a0d2394ca3693e23c18db00b406ca3a231ac5 /lib/libc/rpc
parent1fa54c44ce388765511dd93bab101711fb09cbb5 (diff)
rresvport_af() and bindresvport_af()
Diffstat (limited to 'lib/libc/rpc')
-rw-r--r--lib/libc/rpc/Makefile.inc5
-rw-r--r--lib/libc/rpc/bindresvport.320
-rw-r--r--lib/libc/rpc/bindresvport.c75
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);
}