Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 26 Jan 2000 13:20:38 +0900
From:      Yoshinobu Inoue <shin@nd.net.fujitsu.co.jp>
To:        cvs-committers@FreeBSD.org, cvs-all@FreeBSD.org
Subject:   Re: cvs commit: src/include unistd.h src/lib/libc/net Makefile.inc rcmd.3 rcmd.c src/lib/libutil realhostname_sa.3 Makefile libutil.h realhostname.3 realhostname.c src/libexec/telnetd Makefile         telnetd.8 telnetd.c src/libexec/rshd Makefile rshd.8 rshd.c ...
Message-ID:  <20000126132038W.shin@nd.net.fujitsu.co.jp>
In-Reply-To: <200001251452.GAA58052@freefall.freebsd.org>
References:  <200001251452.GAA58052@freefall.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
>   Added files:
>     lib/libutil          realhostname_sa.3 

I found that I should ask for repo copy first. Thanks for
repo-mysters repo removing realhostname2.3.


And now bindresvport() update is almost fixed between INRIA
and OpenBSD and I would like to commit the update.
But before doing man change, could repo-mysters please
repo-move bindresvport2.3 to bindresvport_sa.3?


I also attach the diff to bindresvport.c to this mail.  There
was much discussion and this should be better than previous
one. (Actually the code is also shared now)
If anyone have comments on this, please give me as soon as
possible.

Thanks,
Yoshinobu Inoue


Index: bindresvport.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/rpc/bindresvport.c,v
retrieving revision 1.11
diff -u -r1.11 bindresvport.c
--- bindresvport.c	2000/01/13 15:09:48	1.11
+++ bindresvport.c	2000/01/26 04:00:23
@@ -55,95 +55,89 @@
 	int sd;
 	struct sockaddr_in *sin;
 {
-	struct sockaddr_in myaddr;
-	int sinlen = sizeof(struct sockaddr_in);
-
-	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) {
-		errno = EPFNOSUPPORT;
-		return (-1);
-	}
-
-	return (bindresvport2(sd, sin, sinlen));
+	return bindresvport_sa(sd, (struct sockaddr *)sin);
 }
 
+/*
+ * Bind a socket to a privileged port for whatever protocol.
+ */
 int
-bindresvport2(sd, sa, addrlen)
+bindresvport_sa(sd, sa)
 	int sd;
 	struct sockaddr *sa;
-	socklen_t addrlen;
 {
-	int on, old, error, level, optname;
-	u_short port;
+	int old, error, af;
+	struct sockaddr_storage myaddr;
+	struct sockaddr_in *sin;
+	struct sockaddr_in6 *sin6;
+	int proto, portrange, portlow;
+	u_int16_t port;
+	int salen;
 
 	if (sa == NULL) {
-		errno = EINVAL;
-		return (-1);
-	}
-	switch (sa->sa_family) {
-	case AF_INET:
-		port = ntohs(((struct sockaddr_in *)sa)->sin_port);
-		level = IPPROTO_IP;
-		optname = IP_PORTRANGE;
-		on = IP_PORTRANGE_LOW;
-		break;
-#ifdef INET6
-	case AF_INET6:
-		port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
-		level = IPPROTO_IPV6;
-		optname = IPV6_PORTRANGE;
-		on = IPV6_PORTRANGE_LOW;
-		break;
-#endif
-	default:
-		errno = EAFNOSUPPORT;
+		salen = sizeof(myaddr);
+		sa = (struct sockaddr *)&myaddr;
+
+		if (getsockname(sd, sa, &salen) == -1)
+			return -1;	/* errno is correctly set */
+
+		af = sa->sa_family;
+		memset(&myaddr, 0, salen);
+	} else
+		af = sa->sa_family;
+
+	if (af == AF_INET) {
+		proto = IPPROTO_IP;
+		portrange = IP_PORTRANGE;
+		portlow = IP_PORTRANGE_LOW;
+		sin = (struct sockaddr_in *)sa;
+		salen = sizeof(struct sockaddr_in);
+		port = 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);
+		port = sin6->sin6_port;
+	} else {
+		errno = EPFNOSUPPORT;
 		return (-1);
 	}
+	sa->sa_family = af;
+	sa->sa_len = salen;
 
 	if (port == 0) {
 		int oldlen = sizeof(old);
-		error = getsockopt(sd, level, optname, &old, &oldlen);
+
+		error = getsockopt(sd, proto, portrange, &old, &oldlen);
 		if (error < 0)
-			return(error);
+			return (error);
 
-		error = setsockopt(sd, level, optname, &on, sizeof(on));
+		error = setsockopt(sd, proto, portrange, &portlow,
+		    sizeof(portlow));
 		if (error < 0)
-			return(error);
+			return (error);
 	}
 
-	error = bind(sd, sa, addrlen);
+	error = bind(sd, sa, salen);
 
-	switch (sa->sa_family) {
-	case AF_INET:
-		port = ntohs(((struct sockaddr_in *)sa)->sin_port);
-		break;
-#ifdef INET6
-	case AF_INET6:
-		port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
-		break;
-#endif
-	default: /* shoud not match here */
-		errno = EAFNOSUPPORT;
-		return (-1);
-	}
 	if (port == 0) {
 		int saved_errno = errno;
 
 		if (error) {
-			if (setsockopt(sd, level, optname,
-			    &old, sizeof(old)) < 0)
+			if (setsockopt(sd, proto, portrange, &old,
+			    sizeof(old)) < 0)
 				errno = saved_errno;
 			return (error);
 		}
 
-		/* Hmm, what did the kernel assign... */
-		if (getsockname(sd, (struct sockaddr *)sa, &addrlen) < 0)
-			errno = saved_errno;
-		return (error);
+		if (sa != (struct sockaddr *)&myaddr) {
+			/* Hmm, what did the kernel assign... */
+			if (getsockname(sd, sa, &salen) < 0)
+				errno = saved_errno;
+			return (error);
+		}
 	}
 	return (error);
 }


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000126132038W.shin>