bindresvport.c revision 106121
138032Speter/* This file has be modified from the original OpenBSD source */ 2223067Sgshapiro 364565Sgshapiro/* 438032Speter * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 538032Speter * unrestricted use provided that this legend is included on all tape 638032Speter * media and as a part of the software program in whole or part. Users 738032Speter * may copy or modify Sun RPC without charge, but are not authorized 838032Speter * to license or distribute it to anyone else except as part of a product or 938032Speter * program developed by the user. 1038032Speter * 1138032Speter * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1238032Speter * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1338032Speter * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1490795Sgshapiro * 1538032Speter * Sun RPC is provided with no support and without any obligation on the 16223067Sgshapiro * part of Sun Microsystems, Inc. to assist in its use, correction, 1790795Sgshapiro * modification or enhancement. 1890795Sgshapiro * 1964565Sgshapiro * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 2064565Sgshapiro * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 2164565Sgshapiro * OR ANY PART THEREOF. 2264565Sgshapiro * 2364565Sgshapiro * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2464565Sgshapiro * or profits or other special, indirect and consequential damages, even if 2564565Sgshapiro * Sun has been advised of the possibility of such damages. 2664565Sgshapiro * 2764565Sgshapiro * Sun Microsystems, Inc. 2838032Speter * 2550 Garcia Avenue 2990795Sgshapiro * Mountain View, California 94043 3090795Sgshapiro */ 3190795Sgshapiro 3290795Sgshapiro#include "includes.h" 3390795Sgshapiro 3490795Sgshapiro#ifndef HAVE_BINDRESVPORT_SA 3590795Sgshapiro 3690795Sgshapiro#if defined(LIBC_SCCS) && !defined(lint) 3790795Sgshapirostatic char *rcsid = "$OpenBSD: bindresvport.c,v 1.13 2000/01/26 03:43:21 deraadt Exp $"; 3890795Sgshapiro#endif /* LIBC_SCCS and not lint */ 3990795Sgshapiro 4090795Sgshapiro/* 4190795Sgshapiro * Copyright (c) 1987 by Sun Microsystems, Inc. 4290795Sgshapiro * 4390795Sgshapiro * Portions Copyright(C) 1996, Jason Downs. All rights reserved. 4490795Sgshapiro */ 4590795Sgshapiro 4690795Sgshapiro#include "includes.h" 4790795Sgshapiro 4890795Sgshapiro#define STARTPORT 600 4990795Sgshapiro#define ENDPORT (IPPORT_RESERVED - 1) 5090795Sgshapiro#define NPORTS (ENDPORT - STARTPORT + 1) 5190795Sgshapiro 5290795Sgshapiro/* 5390795Sgshapiro * Bind a socket to a privileged IP port 5490795Sgshapiro */ 5590795Sgshapiroint 5690795Sgshapirobindresvport_sa(sd, sa) 5790795Sgshapiro int sd; 5890795Sgshapiro struct sockaddr *sa; 5990795Sgshapiro{ 6090795Sgshapiro int error, af; 6190795Sgshapiro struct sockaddr_storage myaddr; 6290795Sgshapiro struct sockaddr_in *sin; 6390795Sgshapiro struct sockaddr_in6 *sin6; 6490795Sgshapiro u_int16_t *portp; 6590795Sgshapiro u_int16_t port; 6690795Sgshapiro socklen_t salen; 6790795Sgshapiro int i; 6890795Sgshapiro 6990795Sgshapiro if (sa == NULL) { 7090795Sgshapiro memset(&myaddr, 0, sizeof(myaddr)); 7190795Sgshapiro sa = (struct sockaddr *)&myaddr; 7290795Sgshapiro 7390795Sgshapiro if (getsockname(sd, sa, &salen) == -1) 7490795Sgshapiro return -1; /* errno is correctly set */ 7590795Sgshapiro 7690795Sgshapiro af = sa->sa_family; 7790795Sgshapiro memset(&myaddr, 0, salen); 7890795Sgshapiro } else 7990795Sgshapiro af = sa->sa_family; 8090795Sgshapiro 8190795Sgshapiro if (af == AF_INET) { 8238032Speter sin = (struct sockaddr_in *)sa; 8338032Speter salen = sizeof(struct sockaddr_in); 8490795Sgshapiro portp = &sin->sin_port; 8538032Speter } else if (af == AF_INET6) { 8638032Speter sin6 = (struct sockaddr_in6 *)sa; 8738032Speter salen = sizeof(struct sockaddr_in6); 8838032Speter portp = &sin6->sin6_port; 8938032Speter } else { 9038032Speter errno = EPFNOSUPPORT; 9190795Sgshapiro return (-1); 9290795Sgshapiro } 9390795Sgshapiro sa->sa_family = af; 9490795Sgshapiro 9590795Sgshapiro port = ntohs(*portp); 9638032Speter if (port == 0) 9790795Sgshapiro port = (arc4random() % NPORTS) + STARTPORT; 9890795Sgshapiro 9990795Sgshapiro /* Avoid warning */ 10038032Speter error = -1; 10138032Speter 10238032Speter for(i = 0; i < NPORTS; i++) { 10338032Speter *portp = htons(port); 10490795Sgshapiro 10538032Speter error = bind(sd, sa, salen); 10638032Speter 10738032Speter /* Terminate on success */ 10838032Speter if (error == 0) 10938032Speter break; 11038032Speter 11164565Sgshapiro /* Terminate on errors, except "address already in use" */ 112168520Sgshapiro if ((error < 0) && !((errno == EADDRINUSE) || (errno == EINVAL))) 11338032Speter break; 11438032Speter 11538032Speter port++; 11664565Sgshapiro if (port > ENDPORT) 11738032Speter port = STARTPORT; 11838032Speter } 11938032Speter 12038032Speter return (error); 12138032Speter} 12264565Sgshapiro 12338032Speter#endif /* HAVE_BINDRESVPORT_SA */ 12438032Speter