183d2307dSDag-Erling Smørgrav /* This file has be modified from the original OpenBSD source */ 283d2307dSDag-Erling Smørgrav 383d2307dSDag-Erling Smørgrav /* 483d2307dSDag-Erling Smørgrav * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 583d2307dSDag-Erling Smørgrav * unrestricted use provided that this legend is included on all tape 683d2307dSDag-Erling Smørgrav * media and as a part of the software program in whole or part. Users 783d2307dSDag-Erling Smørgrav * may copy or modify Sun RPC without charge, but are not authorized 883d2307dSDag-Erling Smørgrav * to license or distribute it to anyone else except as part of a product or 983d2307dSDag-Erling Smørgrav * program developed by the user. 1083d2307dSDag-Erling Smørgrav * 1183d2307dSDag-Erling Smørgrav * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1283d2307dSDag-Erling Smørgrav * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1383d2307dSDag-Erling Smørgrav * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1483d2307dSDag-Erling Smørgrav * 1583d2307dSDag-Erling Smørgrav * Sun RPC is provided with no support and without any obligation on the 1683d2307dSDag-Erling Smørgrav * part of Sun Microsystems, Inc. to assist in its use, correction, 1783d2307dSDag-Erling Smørgrav * modification or enhancement. 1883d2307dSDag-Erling Smørgrav * 1983d2307dSDag-Erling Smørgrav * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 2083d2307dSDag-Erling Smørgrav * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 2183d2307dSDag-Erling Smørgrav * OR ANY PART THEREOF. 2283d2307dSDag-Erling Smørgrav * 2383d2307dSDag-Erling Smørgrav * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2483d2307dSDag-Erling Smørgrav * or profits or other special, indirect and consequential damages, even if 2583d2307dSDag-Erling Smørgrav * Sun has been advised of the possibility of such damages. 2683d2307dSDag-Erling Smørgrav * 2783d2307dSDag-Erling Smørgrav * Sun Microsystems, Inc. 2883d2307dSDag-Erling Smørgrav * 2550 Garcia Avenue 2983d2307dSDag-Erling Smørgrav * Mountain View, California 94043 3083d2307dSDag-Erling Smørgrav */ 3183d2307dSDag-Erling Smørgrav 324b17dab0SDag-Erling Smørgrav #include "includes.h" 3383d2307dSDag-Erling Smørgrav 3483d2307dSDag-Erling Smørgrav #ifndef HAVE_BINDRESVPORT_SA 3583d2307dSDag-Erling Smørgrav 3683d2307dSDag-Erling Smørgrav #if defined(LIBC_SCCS) && !defined(lint) 3783d2307dSDag-Erling Smørgrav static char *rcsid = "$OpenBSD: bindresvport.c,v 1.13 2000/01/26 03:43:21 deraadt Exp $"; 3883d2307dSDag-Erling Smørgrav #endif /* LIBC_SCCS and not lint */ 3983d2307dSDag-Erling Smørgrav 4083d2307dSDag-Erling Smørgrav /* 4183d2307dSDag-Erling Smørgrav * Copyright (c) 1987 by Sun Microsystems, Inc. 4283d2307dSDag-Erling Smørgrav * 4383d2307dSDag-Erling Smørgrav * Portions Copyright(C) 1996, Jason Downs. All rights reserved. 4483d2307dSDag-Erling Smørgrav */ 4583d2307dSDag-Erling Smørgrav 4683d2307dSDag-Erling Smørgrav #include "includes.h" 4783d2307dSDag-Erling Smørgrav 4883d2307dSDag-Erling Smørgrav #define STARTPORT 600 4983d2307dSDag-Erling Smørgrav #define ENDPORT (IPPORT_RESERVED - 1) 5083d2307dSDag-Erling Smørgrav #define NPORTS (ENDPORT - STARTPORT + 1) 5183d2307dSDag-Erling Smørgrav 5283d2307dSDag-Erling Smørgrav /* 5383d2307dSDag-Erling Smørgrav * Bind a socket to a privileged IP port 5483d2307dSDag-Erling Smørgrav */ 5583d2307dSDag-Erling Smørgrav int 5683d2307dSDag-Erling Smørgrav bindresvport_sa(sd, sa) 5783d2307dSDag-Erling Smørgrav int sd; 5883d2307dSDag-Erling Smørgrav struct sockaddr *sa; 5983d2307dSDag-Erling Smørgrav { 6083d2307dSDag-Erling Smørgrav int error, af; 6183d2307dSDag-Erling Smørgrav struct sockaddr_storage myaddr; 6283d2307dSDag-Erling Smørgrav struct sockaddr_in *sin; 6383d2307dSDag-Erling Smørgrav struct sockaddr_in6 *sin6; 6483d2307dSDag-Erling Smørgrav u_int16_t *portp; 6583d2307dSDag-Erling Smørgrav u_int16_t port; 6683d2307dSDag-Erling Smørgrav socklen_t salen; 6783d2307dSDag-Erling Smørgrav int i; 6883d2307dSDag-Erling Smørgrav 6983d2307dSDag-Erling Smørgrav if (sa == NULL) { 7083d2307dSDag-Erling Smørgrav memset(&myaddr, 0, sizeof(myaddr)); 7183d2307dSDag-Erling Smørgrav sa = (struct sockaddr *)&myaddr; 7283d2307dSDag-Erling Smørgrav 7383d2307dSDag-Erling Smørgrav if (getsockname(sd, sa, &salen) == -1) 7483d2307dSDag-Erling Smørgrav return -1; /* errno is correctly set */ 7583d2307dSDag-Erling Smørgrav 7683d2307dSDag-Erling Smørgrav af = sa->sa_family; 7783d2307dSDag-Erling Smørgrav memset(&myaddr, 0, salen); 7883d2307dSDag-Erling Smørgrav } else 7983d2307dSDag-Erling Smørgrav af = sa->sa_family; 8083d2307dSDag-Erling Smørgrav 8183d2307dSDag-Erling Smørgrav if (af == AF_INET) { 8283d2307dSDag-Erling Smørgrav sin = (struct sockaddr_in *)sa; 8383d2307dSDag-Erling Smørgrav salen = sizeof(struct sockaddr_in); 8483d2307dSDag-Erling Smørgrav portp = &sin->sin_port; 8583d2307dSDag-Erling Smørgrav } else if (af == AF_INET6) { 8683d2307dSDag-Erling Smørgrav sin6 = (struct sockaddr_in6 *)sa; 8783d2307dSDag-Erling Smørgrav salen = sizeof(struct sockaddr_in6); 8883d2307dSDag-Erling Smørgrav portp = &sin6->sin6_port; 8983d2307dSDag-Erling Smørgrav } else { 9083d2307dSDag-Erling Smørgrav errno = EPFNOSUPPORT; 9183d2307dSDag-Erling Smørgrav return (-1); 9283d2307dSDag-Erling Smørgrav } 9383d2307dSDag-Erling Smørgrav sa->sa_family = af; 9483d2307dSDag-Erling Smørgrav 9583d2307dSDag-Erling Smørgrav port = ntohs(*portp); 9683d2307dSDag-Erling Smørgrav if (port == 0) 9783d2307dSDag-Erling Smørgrav port = (arc4random() % NPORTS) + STARTPORT; 9883d2307dSDag-Erling Smørgrav 9983d2307dSDag-Erling Smørgrav /* Avoid warning */ 10083d2307dSDag-Erling Smørgrav error = -1; 10183d2307dSDag-Erling Smørgrav 10283d2307dSDag-Erling Smørgrav for(i = 0; i < NPORTS; i++) { 10383d2307dSDag-Erling Smørgrav *portp = htons(port); 10483d2307dSDag-Erling Smørgrav 10583d2307dSDag-Erling Smørgrav error = bind(sd, sa, salen); 10683d2307dSDag-Erling Smørgrav 10783d2307dSDag-Erling Smørgrav /* Terminate on success */ 10883d2307dSDag-Erling Smørgrav if (error == 0) 10983d2307dSDag-Erling Smørgrav break; 11083d2307dSDag-Erling Smørgrav 11183d2307dSDag-Erling Smørgrav /* Terminate on errors, except "address already in use" */ 11283d2307dSDag-Erling Smørgrav if ((error < 0) && !((errno == EADDRINUSE) || (errno == EINVAL))) 11383d2307dSDag-Erling Smørgrav break; 11483d2307dSDag-Erling Smørgrav 11583d2307dSDag-Erling Smørgrav port++; 11683d2307dSDag-Erling Smørgrav if (port > ENDPORT) 11783d2307dSDag-Erling Smørgrav port = STARTPORT; 11883d2307dSDag-Erling Smørgrav } 11983d2307dSDag-Erling Smørgrav 12083d2307dSDag-Erling Smørgrav return (error); 12183d2307dSDag-Erling Smørgrav } 12283d2307dSDag-Erling Smørgrav 12383d2307dSDag-Erling Smørgrav #endif /* HAVE_BINDRESVPORT_SA */ 124