1d95e11bfSDag-Erling Smørgrav /* This file has be substantially modified from the original OpenBSD source */ 2d95e11bfSDag-Erling Smørgrav 3d95e11bfSDag-Erling Smørgrav /* $OpenBSD: bindresvport.c,v 1.15 2003/05/20 22:42:35 deraadt Exp $ */ 483d2307dSDag-Erling Smørgrav 583d2307dSDag-Erling Smørgrav /* 6d95e11bfSDag-Erling Smørgrav * Copyright 1996, Jason Downs. All rights reserved. 7d95e11bfSDag-Erling Smørgrav * Copyright 1998, Theo de Raadt. All rights reserved. 8d95e11bfSDag-Erling Smørgrav * Copyright 2000, Damien Miller. All rights reserved. 983d2307dSDag-Erling Smørgrav * 10d95e11bfSDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 11d95e11bfSDag-Erling Smørgrav * modification, are permitted provided that the following conditions 12d95e11bfSDag-Erling Smørgrav * are met: 13d95e11bfSDag-Erling Smørgrav * 1. Redistributions of source code must retain the above copyright 14d95e11bfSDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer. 15d95e11bfSDag-Erling Smørgrav * 2. Redistributions in binary form must reproduce the above copyright 16d95e11bfSDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer in the 17d95e11bfSDag-Erling Smørgrav * documentation and/or other materials provided with the distribution. 1883d2307dSDag-Erling Smørgrav * 19d95e11bfSDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20d95e11bfSDag-Erling Smørgrav * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21d95e11bfSDag-Erling Smørgrav * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22d95e11bfSDag-Erling Smørgrav * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23d95e11bfSDag-Erling Smørgrav * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24d95e11bfSDag-Erling Smørgrav * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25d95e11bfSDag-Erling Smørgrav * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26d95e11bfSDag-Erling Smørgrav * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27d95e11bfSDag-Erling Smørgrav * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28d95e11bfSDag-Erling Smørgrav * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2983d2307dSDag-Erling Smørgrav */ 3083d2307dSDag-Erling Smørgrav 314b17dab0SDag-Erling Smørgrav #include "includes.h" 3283d2307dSDag-Erling Smørgrav 3383d2307dSDag-Erling Smørgrav #ifndef HAVE_BINDRESVPORT_SA 3483d2307dSDag-Erling Smørgrav 3583d2307dSDag-Erling Smørgrav #include "includes.h" 3683d2307dSDag-Erling Smørgrav 3783d2307dSDag-Erling Smørgrav #define STARTPORT 600 3883d2307dSDag-Erling Smørgrav #define ENDPORT (IPPORT_RESERVED - 1) 3983d2307dSDag-Erling Smørgrav #define NPORTS (ENDPORT - STARTPORT + 1) 4083d2307dSDag-Erling Smørgrav 4183d2307dSDag-Erling Smørgrav /* 4283d2307dSDag-Erling Smørgrav * Bind a socket to a privileged IP port 4383d2307dSDag-Erling Smørgrav */ 4483d2307dSDag-Erling Smørgrav int 4583d2307dSDag-Erling Smørgrav bindresvport_sa(sd, sa) 4683d2307dSDag-Erling Smørgrav int sd; 4783d2307dSDag-Erling Smørgrav struct sockaddr *sa; 4883d2307dSDag-Erling Smørgrav { 4983d2307dSDag-Erling Smørgrav int error, af; 5083d2307dSDag-Erling Smørgrav struct sockaddr_storage myaddr; 5183d2307dSDag-Erling Smørgrav struct sockaddr_in *sin; 5283d2307dSDag-Erling Smørgrav struct sockaddr_in6 *sin6; 5383d2307dSDag-Erling Smørgrav u_int16_t *portp; 5483d2307dSDag-Erling Smørgrav u_int16_t port; 5583d2307dSDag-Erling Smørgrav socklen_t salen; 5683d2307dSDag-Erling Smørgrav int i; 5783d2307dSDag-Erling Smørgrav 5883d2307dSDag-Erling Smørgrav if (sa == NULL) { 5983d2307dSDag-Erling Smørgrav memset(&myaddr, 0, sizeof(myaddr)); 6083d2307dSDag-Erling Smørgrav sa = (struct sockaddr *)&myaddr; 6183d2307dSDag-Erling Smørgrav 6283d2307dSDag-Erling Smørgrav if (getsockname(sd, sa, &salen) == -1) 6383d2307dSDag-Erling Smørgrav return -1; /* errno is correctly set */ 6483d2307dSDag-Erling Smørgrav 6583d2307dSDag-Erling Smørgrav af = sa->sa_family; 6683d2307dSDag-Erling Smørgrav memset(&myaddr, 0, salen); 6783d2307dSDag-Erling Smørgrav } else 6883d2307dSDag-Erling Smørgrav af = sa->sa_family; 6983d2307dSDag-Erling Smørgrav 7083d2307dSDag-Erling Smørgrav if (af == AF_INET) { 7183d2307dSDag-Erling Smørgrav sin = (struct sockaddr_in *)sa; 7283d2307dSDag-Erling Smørgrav salen = sizeof(struct sockaddr_in); 7383d2307dSDag-Erling Smørgrav portp = &sin->sin_port; 7483d2307dSDag-Erling Smørgrav } else if (af == AF_INET6) { 7583d2307dSDag-Erling Smørgrav sin6 = (struct sockaddr_in6 *)sa; 7683d2307dSDag-Erling Smørgrav salen = sizeof(struct sockaddr_in6); 7783d2307dSDag-Erling Smørgrav portp = &sin6->sin6_port; 7883d2307dSDag-Erling Smørgrav } else { 7983d2307dSDag-Erling Smørgrav errno = EPFNOSUPPORT; 8083d2307dSDag-Erling Smørgrav return (-1); 8183d2307dSDag-Erling Smørgrav } 8283d2307dSDag-Erling Smørgrav sa->sa_family = af; 8383d2307dSDag-Erling Smørgrav 8483d2307dSDag-Erling Smørgrav port = ntohs(*portp); 8583d2307dSDag-Erling Smørgrav if (port == 0) 8683d2307dSDag-Erling Smørgrav port = (arc4random() % NPORTS) + STARTPORT; 8783d2307dSDag-Erling Smørgrav 8883d2307dSDag-Erling Smørgrav /* Avoid warning */ 8983d2307dSDag-Erling Smørgrav error = -1; 9083d2307dSDag-Erling Smørgrav 9183d2307dSDag-Erling Smørgrav for(i = 0; i < NPORTS; i++) { 9283d2307dSDag-Erling Smørgrav *portp = htons(port); 9383d2307dSDag-Erling Smørgrav 9483d2307dSDag-Erling Smørgrav error = bind(sd, sa, salen); 9583d2307dSDag-Erling Smørgrav 9683d2307dSDag-Erling Smørgrav /* Terminate on success */ 9783d2307dSDag-Erling Smørgrav if (error == 0) 9883d2307dSDag-Erling Smørgrav break; 9983d2307dSDag-Erling Smørgrav 10083d2307dSDag-Erling Smørgrav /* Terminate on errors, except "address already in use" */ 10183d2307dSDag-Erling Smørgrav if ((error < 0) && !((errno == EADDRINUSE) || (errno == EINVAL))) 10283d2307dSDag-Erling Smørgrav break; 10383d2307dSDag-Erling Smørgrav 10483d2307dSDag-Erling Smørgrav port++; 10583d2307dSDag-Erling Smørgrav if (port > ENDPORT) 10683d2307dSDag-Erling Smørgrav port = STARTPORT; 10783d2307dSDag-Erling Smørgrav } 10883d2307dSDag-Erling Smørgrav 10983d2307dSDag-Erling Smørgrav return (error); 11083d2307dSDag-Erling Smørgrav } 11183d2307dSDag-Erling Smørgrav 11283d2307dSDag-Erling Smørgrav #endif /* HAVE_BINDRESVPORT_SA */ 113