11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* This file has be substantially modified from the original OpenBSD source */ 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: bindresvport.c,v 1.17 2005/12/21 01:40:22 millert Exp $ */ 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright 1996, Jason Downs. All rights reserved. 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright 1998, Theo de Raadt. All rights reserved. 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright 2000, Damien Miller. All rights reserved. 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met: 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer. 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer in the 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * documentation and/or other materials provided with the distribution. 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* OPENBSD ORIGINAL: lib/libc/rpc/bindresvport.c */ 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifndef HAVE_BINDRESVPORT_SA 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h> 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/socket.h> 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <netinet/in.h> 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <arpa/inet.h> 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <errno.h> 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define STARTPORT 600 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define ENDPORT (IPPORT_RESERVED - 1) 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define NPORTS (ENDPORT - STARTPORT + 1) 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Bind a socket to a privileged IP port 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodbindresvport_sa(int sd, struct sockaddr *sa) 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int error, af; 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct sockaddr_storage myaddr; 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct sockaddr_in *in; 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct sockaddr_in6 *in6; 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int16_t *portp; 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int16_t port; 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood socklen_t salen; 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i; 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sa == NULL) { 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(&myaddr, 0, sizeof(myaddr)); 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sa = (struct sockaddr *)&myaddr; 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (getsockname(sd, sa, &salen) == -1) 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; /* errno is correctly set */ 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood af = sa->sa_family; 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(&myaddr, 0, salen); 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood af = sa->sa_family; 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (af == AF_INET) { 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood in = (struct sockaddr_in *)sa; 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood salen = sizeof(struct sockaddr_in); 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood portp = &in->sin_port; 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (af == AF_INET6) { 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood in6 = (struct sockaddr_in6 *)sa; 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood salen = sizeof(struct sockaddr_in6); 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood portp = &in6->sin6_port; 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood errno = EPFNOSUPPORT; 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sa->sa_family = af; 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood port = ntohs(*portp); 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (port == 0) 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood port = arc4random_uniform(NPORTS) + STARTPORT; 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Avoid warning */ 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error = -1; 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for(i = 0; i < NPORTS; i++) { 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *portp = htons(port); 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error = bind(sd, sa, salen); 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Terminate on success */ 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (error == 0) 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Terminate on errors, except "address already in use" */ 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((error < 0) && !((errno == EADDRINUSE) || (errno == EINVAL))) 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood port++; 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (port > ENDPORT) 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood port = STARTPORT; 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (error); 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* HAVE_BINDRESVPORT_SA */ 119