lib/libc/rpc/bindresvport.c
int
bindresvport_sa(int sd, struct sockaddr *sa)
{
	int old, error, af;
	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;

	if (sa == NULL) {
		salen = sizeof(myaddr);
		sa = (struct sockaddr *)&myaddr;

		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 (*portp == 0) {
		socklen_t oldlen = sizeof(old);

		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);
	}

	error = _bind(sd, sa, salen);

	if (*portp == 0) {
		int saved_errno = errno;

		if (error < 0) {
			if (_setsockopt(sd, proto, portrange, &old,
			    sizeof(old)) < 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);
}
/*
 * Bind a socket to a privileged IP port
 */
Bind a socket to a privileged IP port
Bind a socket to a privileged IP port
int
bindresvport_sa(int sd, struct sockaddr *sa)
{
	int old, error, af;
	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;
	if (sa == NULL) {
		salen = sizeof(myaddr);
		sa = (struct sockaddr *)&myaddr;
		if (_getsockname(sd, sa, &salen) == -1)
			return -1;	
		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 (*portp == 0) {
		socklen_t oldlen = sizeof(old);
		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);
	}
	error = _bind(sd, sa, salen);
	if (*portp == 0) {
		int saved_errno = errno;
		if (error < 0) {
			if (_setsockopt(sd, proto, portrange, &old,
			    sizeof(old)) < 0)
				errno = saved_errno;
			return (error);
		}
		if (sa != (struct sockaddr *)&myaddr) {
			if (_getsockname(sd, sa, &salen) < 0)
				errno = saved_errno;
			return (error);
		}
	}
	return (error);
}
int bindresvport_sa ( int sd , struct sockaddr * sa ) { int old , error , af ; 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 ; if ( sa == NULL ) { salen = sizeof ( myaddr ) ; sa = ( struct sockaddr * ) & myaddr ; if ( _getsockname ( sd , sa , & salen ) == -1 ) return -1 ; 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 ( * portp == 0 ) { socklen_t oldlen = sizeof ( old ) ; 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 ) ; } error = _bind ( sd , sa , salen ) ; if ( * portp == 0 ) { int saved_errno = errno ; if ( error < 0 ) { if ( _setsockopt ( sd , proto , portrange , & old , sizeof ( old ) ) < 0 ) errno = saved_errno ; return ( error ) ; } if ( sa != ( struct sockaddr * ) & myaddr ) { if ( _getsockname ( sd , sa , & salen ) < 0 ) errno = saved_errno ; return ( error ) ; } } return ( error ) ; }
Bind a socket to a privileged IP port
Bind a socket to a privileged IP port
/* errno is correctly set */ /* Hmm, what did the kernel assign? */