1157016Sdes/* $OpenBSD: rresvport.c,v 1.9 2005/11/10 10:00:17 espie Exp $ */ 298937Sdes/* 398937Sdes * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved. 498937Sdes * Copyright (c) 1983, 1993, 1994 598937Sdes * The Regents of the University of California. All rights reserved. 698937Sdes * 798937Sdes * Redistribution and use in source and binary forms, with or without 898937Sdes * modification, are permitted provided that the following conditions 998937Sdes * are met: 1098937Sdes * 1. Redistributions of source code must retain the above copyright 1198937Sdes * notice, this list of conditions and the following disclaimer. 1298937Sdes * 2. Redistributions in binary form must reproduce the above copyright 1398937Sdes * notice, this list of conditions and the following disclaimer in the 1498937Sdes * documentation and/or other materials provided with the distribution. 15124208Sdes * 3. Neither the name of the University nor the names of its contributors 1698937Sdes * may be used to endorse or promote products derived from this software 1798937Sdes * without specific prior written permission. 1898937Sdes * 1998937Sdes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2098937Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2198937Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2298937Sdes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2398937Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2498937Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2598937Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2698937Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2798937Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2898937Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2998937Sdes * SUCH DAMAGE. 3098937Sdes */ 3198937Sdes 32157016Sdes/* OPENBSD ORIGINAL: lib/libc/net/rresvport.c */ 33157016Sdes 34106121Sdes#include "includes.h" 3598937Sdes 3698937Sdes#ifndef HAVE_RRESVPORT_AF 3798937Sdes 38162852Sdes#include <sys/types.h> 39162852Sdes#include <sys/socket.h> 40162852Sdes 41162852Sdes#include <netinet/in.h> 42162852Sdes#include <arpa/inet.h> 43162852Sdes 44162852Sdes#include <errno.h> 45162852Sdes#include <stdlib.h> 46162852Sdes#include <string.h> 47181111Sdes#include <unistd.h> 48162852Sdes 4998937Sdes#if 0 5098937Sdesint 51157016Sdesrresvport(int *alport) 5298937Sdes{ 5398937Sdes return rresvport_af(alport, AF_INET); 5498937Sdes} 5598937Sdes#endif 5698937Sdes 57157016Sdesint 5898937Sdesrresvport_af(int *alport, sa_family_t af) 5998937Sdes{ 6098937Sdes struct sockaddr_storage ss; 6198937Sdes struct sockaddr *sa; 6298937Sdes u_int16_t *portp; 6398937Sdes int s; 6498937Sdes socklen_t salen; 6598937Sdes 6698937Sdes memset(&ss, '\0', sizeof ss); 6798937Sdes sa = (struct sockaddr *)&ss; 6898937Sdes 6998937Sdes switch (af) { 7098937Sdes case AF_INET: 7198937Sdes salen = sizeof(struct sockaddr_in); 7298937Sdes portp = &((struct sockaddr_in *)sa)->sin_port; 7398937Sdes break; 7498937Sdes case AF_INET6: 7598937Sdes salen = sizeof(struct sockaddr_in6); 7698937Sdes portp = &((struct sockaddr_in6 *)sa)->sin6_port; 7798937Sdes break; 7898937Sdes default: 7998937Sdes errno = EPFNOSUPPORT; 8098937Sdes return (-1); 8198937Sdes } 8298937Sdes sa->sa_family = af; 8398937Sdes 8498937Sdes s = socket(af, SOCK_STREAM, 0); 8598937Sdes if (s < 0) 8698937Sdes return (-1); 8798937Sdes 8898937Sdes *portp = htons(*alport); 8998937Sdes if (*alport < IPPORT_RESERVED - 1) { 9098937Sdes if (bind(s, sa, salen) >= 0) 9198937Sdes return (s); 9298937Sdes if (errno != EADDRINUSE) { 9398937Sdes (void)close(s); 9498937Sdes return (-1); 9598937Sdes } 9698937Sdes } 9798937Sdes 9898937Sdes *portp = 0; 9998937Sdes sa->sa_family = af; 10098937Sdes if (bindresvport_sa(s, sa) == -1) { 10198937Sdes (void)close(s); 10298937Sdes return (-1); 10398937Sdes } 10498937Sdes *alport = ntohs(*portp); 10598937Sdes return (s); 10698937Sdes} 10798937Sdes 10898937Sdes#endif /* HAVE_RRESVPORT_AF */ 109