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