Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src implement bindresvport_sa(), which is necessary for IPv6 sup...
details: https://anonhg.NetBSD.org/src/rev/2c9f5cd80cfc
branches: trunk
changeset: 481342:2c9f5cd80cfc
user: itojun <itojun%NetBSD.org@localhost>
date: Wed Jan 26 13:20:24 2000 +0000
description:
implement bindresvport_sa(), which is necessary for IPv6 support in certain
programs (like rshd or rlogind).
bindresvport() and bindresvport_sa() exhibits exactly the same functionality,
with different function prototype (sockaddr_in * and sockaddr *).
The behavior and prototype was discussed and agreed among shin%kame.net@localhost
(who is doing freebsd-current kame merge), deraadt%openbsd.org@localhost, and
Jean-Luc.Richier%imag.fr@localhost (INRIA IPv6/IPv6 RPC support). so it will be
portable across *bsd.
diffstat:
distrib/sets/lists/comp/mi | 3 +-
include/rpc/rpc.h | 5 +-
lib/libc/rpc/Makefile.inc | 5 +-
lib/libc/rpc/bindresvport.3 | 41 ++++++++++++----
lib/libc/rpc/bindresvport.c | 107 +++++++++++++++++++++++++++++++------------
5 files changed, 115 insertions(+), 46 deletions(-)
diffs (290 lines):
diff -r 8ca92d5bbf02 -r 2c9f5cd80cfc distrib/sets/lists/comp/mi
--- a/distrib/sets/lists/comp/mi Wed Jan 26 12:48:44 2000 +0000
+++ b/distrib/sets/lists/comp/mi Wed Jan 26 13:20:24 2000 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.186 2000/01/24 18:53:53 augustss Exp $
+# $NetBSD: mi,v 1.187 2000/01/26 13:20:26 itojun Exp $
./sys
./usr/bin/ar
./usr/bin/as
@@ -1512,6 +1512,7 @@
./usr/share/man/cat3/bcmp.0
./usr/share/man/cat3/bcopy.0
./usr/share/man/cat3/bindresvport.0
+./usr/share/man/cat3/bindresvport_sa.0
./usr/share/man/cat3/bitstring.0
./usr/share/man/cat3/bm.0
./usr/share/man/cat3/bm_comp.0
diff -r 8ca92d5bbf02 -r 2c9f5cd80cfc include/rpc/rpc.h
--- a/include/rpc/rpc.h Wed Jan 26 12:48:44 2000 +0000
+++ b/include/rpc/rpc.h Wed Jan 26 13:20:24 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rpc.h,v 1.11 1998/02/11 23:01:25 lukem Exp $ */
+/* $NetBSD: rpc.h,v 1.12 2000/01/26 13:20:26 itojun Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
@@ -98,6 +98,9 @@
extern int callrpc __P((char *, int, int, int, xdrproc_t, char *,
xdrproc_t , char *));
extern int getrpcport __P((char *, int, int, int));
+
+struct sockaddr;
+extern int bindresvport_sa __P((int, struct sockaddr *));
__END_DECLS
#endif /* !_RPC_RPC_H_ */
diff -r 8ca92d5bbf02 -r 2c9f5cd80cfc lib/libc/rpc/Makefile.inc
--- a/lib/libc/rpc/Makefile.inc Wed Jan 26 12:48:44 2000 +0000
+++ b/lib/libc/rpc/Makefile.inc Wed Jan 26 13:20:24 2000 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.inc,v 1.10 1998/03/18 01:37:39 jtc Exp $
+# $NetBSD: Makefile.inc,v 1.11 2000/01/26 13:20:24 itojun Exp $
# librpc sources
.PATH: ${.CURDIR}/arch/${MACHINE}/rpc ${.CURDIR}/rpc
@@ -13,7 +13,8 @@
xdr_rec.c xdr_reference.c xdr_stdio.c
MAN+= bindresvport.3 getrpcent.3 getrpcport.3 rpc.3 xdr.3
-MLINKS+= getrpcent.3 getrpcbyname.3 \
+MLINKS+= bindresvport.3 bindresvport_sa.3 \
+ getrpcent.3 getrpcbyname.3 \
getrpcent.3 getrpcbynumber.3 \
getrpcent.3 endrpcent.3 \
getrpcent.3 setrpcent.3 \
diff -r 8ca92d5bbf02 -r 2c9f5cd80cfc lib/libc/rpc/bindresvport.3
--- a/lib/libc/rpc/bindresvport.3 Wed Jan 26 12:48:44 2000 +0000
+++ b/lib/libc/rpc/bindresvport.3 Wed Jan 26 13:20:24 2000 +0000
@@ -1,11 +1,12 @@
.\" @(#)bindresvport.3n 2.2 88/08/02 4.0 RPCSRC; from 1.7 88/03/14 SMI
-.\" $NetBSD: bindresvport.3,v 1.6 2000/01/26 07:06:03 itojun Exp $
+.\" $NetBSD: bindresvport.3,v 1.7 2000/01/26 13:20:25 itojun Exp $
.\"
.Dd November 22, 1987
.Dt BINDRESVPORT 3
.Os
.Sh NAME
-.Nm bindresvport
+.Nm bindresvport ,
+.Nm bindresvport_sa
.Nd bind a socket to a privileged IP port
.Sh LIBRARY
.Lb libc
@@ -14,9 +15,13 @@
.Fd #include <rpc/rpc.h>
.Ft int
.Fn bindresvport "int sd" "struct sockaddr_in *sin"
+.Ft int
+.Fn bindresvport_sa "int sd" "struct sockaddr *sa"
.Sh DESCRIPTION
.Fn bindresvport
-is used to bind a socket descriptor to a privileged
+and
+.Fn bindresvport_sa
+are used to bind a socket descriptor to a privileged
.Tn IP
port, that is, a
port number in the range 0-1023.
@@ -30,15 +35,19 @@
is a pointer to a
.Ft "struct sockaddr_in"
then the appropriate fields in the structure should be defined.
+Note that
+.Fa sin->sin_family
+must be initialized to the address family of the socket, passed by
+.Fa sd .
If
-.Fa sin.sin_port
+.Fa sin->sin_port
is
.Sq 0
then an anonymous port (in the range 600-1023) will be
chosen, and if
.Xr bind 2
is successful, the
-.Fa sin.sin_port
+.Fa sin->sin_port
will be updated to contain the allocated port.
.Pp
If
@@ -53,6 +62,20 @@
.Pp
Only root can bind to a privileged port; this call will fail for any
other users.
+.Pp
+Function prototype of
+.Fn bindresvport
+is biased to
+.Dv AF_INET
+socket.
+.Fn bindresvport_sa
+acts exactly the same, with more neutral function prototype.
+Note that both functions behave exactly the same, and
+both support
+.Dv AF_INET6
+sockets as well as
+.Dv AF_INET
+sockets.
.Sh RETURN VALUES
If the bind is successful, a 0 value is returned.
A return value of -1 indicates an error, which is
@@ -61,12 +84,8 @@
.Sh ERRORS
.Bl -tag -width Er
.It Bq Er EPFNOSUPPORT
-If
-.Fa sin
-was supplied, and
-.Fa sin.sin_family
-isn't
-.Dv AF_INET .
+If second argument was supplied,
+and address family did not match between arguments.
.El
.Pp
.Fn bindresvport
diff -r 8ca92d5bbf02 -r 2c9f5cd80cfc lib/libc/rpc/bindresvport.c
--- a/lib/libc/rpc/bindresvport.c Wed Jan 26 12:48:44 2000 +0000
+++ b/lib/libc/rpc/bindresvport.c Wed Jan 26 13:20:24 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bindresvport.c,v 1.16 2000/01/22 22:19:17 mycroft Exp $ */
+/* $NetBSD: bindresvport.c,v 1.17 2000/01/26 13:20:25 itojun Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
@@ -35,7 +35,7 @@
static char *sccsid = "@(#)bindresvport.c 1.8 88/02/08 SMI";
static char *sccsid = "@(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC";
#else
-__RCSID("$NetBSD: bindresvport.c,v 1.16 2000/01/22 22:19:17 mycroft Exp $");
+__RCSID("$NetBSD: bindresvport.c,v 1.17 2000/01/26 13:20:25 itojun Exp $");
#endif
#endif
@@ -68,51 +68,96 @@
int sd;
struct sockaddr_in *sin;
{
- int res, old;
- struct sockaddr_in myaddr;
- socklen_t sinlen = sizeof(struct sockaddr_in);
+ return bindresvport_sa(sd, (struct sockaddr *)sin);
+}
+
+/*
+ * Bind a socket to a privileged IP port
+ */
+int
+bindresvport_sa(sd, sa)
+ int sd;
+ struct sockaddr *sa;
+{
+ int error, old;
+ struct sockaddr_storage myaddr;
+ struct sockaddr_in *sin;
+#ifdef INET6
+ struct sockaddr_in6 *sin6;
+#endif
+ int proto, portrange, portlow;
+ u_int16_t *portp;
+ socklen_t salen;
+ int af;
+
+ if (sa == NULL) {
+ salen = sizeof(myaddr);
+ sa = (struct sockaddr *)&myaddr;
- if (sin == NULL) {
- sin = &myaddr;
- memset(sin, 0, (size_t)sinlen);
- sin->sin_len = sinlen;
- sin->sin_family = AF_INET;
- } else if (sin->sin_family != AF_INET) {
+ if (getsockname(sd, sa, &salen) == -1)
+ return -1; /* errno is correctly set */
+
+ af = sa->sa_family;
+ memset(sa, 0, salen);
+ } else
+ af = sa->sa_family;
+
+ switch (af) {
+ case 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;
+ break;
+#ifdef INET6
+ case 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;
+ break;
+#endif
+ default:
errno = EPFNOSUPPORT;
return (-1);
}
+ sa->sa_family = af;
+ sa->sa_len = salen;
- if (sin->sin_port == 0) {
- int on;
+ if (*portp == 0) {
socklen_t oldlen = sizeof(old);
- res = getsockopt(sd, IPPROTO_IP, IP_PORTRANGE, &old, &oldlen);
- if (res < 0)
- return(res);
- on = IP_PORTRANGE_LOW;
- res = setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, &on, sizeof(on));
- if (res < 0)
- return(res);
+ error = getsockopt(sd, proto, portrange, &old, &oldlen);
+ if (error < 0)
+ return (error);
+ error = setsockopt(sd, proto, portrange, &portlow,
+ sizeof(portlow));
+ if (error < 0)
+ return (error);
}
- res = bind(sd, (struct sockaddr *)(void *)sin, sinlen);
+ error = bind(sd, sa, salen);
- if (sin->sin_port == 0) {
+ if (*portp == 0) {
int saved_errno = errno;
- if (res < 0) {
- if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE,
- &old, sizeof(old)) < 0)
+ if (error < 0) {
+ if (setsockopt(sd, proto, portrange, &old,
+ sizeof(old)) < 0)
errno = saved_errno;
- return (res);
+ return (error);
}
- if (sin != &myaddr) { /* What did the kernel assign? */
- if (getsockname(sd, (struct sockaddr *)(void *)sin,
- &sinlen) < 0)
+ if (sa != (struct sockaddr *)&myaddr) {
+ /* What did the kernel assign? */
+ if (getsockname(sd, sa, &salen) < 0)
errno = saved_errno;
- return (res);
+ return (error);
}
}
- return (res);
+ return (error);
}
Home |
Main Index |
Thread Index |
Old Index