rresvport.c revision 124208
154359Sroberto/*
2182007Sroberto * Copyright (c) 1995, 1996, 1998 Theo de Raadt.  All rights reserved.
3285612Sdelphij * Copyright (c) 1983, 1993, 1994
4182007Sroberto *	The Regents of the University of California.  All rights reserved.
554359Sroberto *
654359Sroberto * Redistribution and use in source and binary forms, with or without
754359Sroberto * modification, are permitted provided that the following conditions
8285612Sdelphij * are met:
9285612Sdelphij * 1. Redistributions of source code must retain the above copyright
1054359Sroberto *    notice, this list of conditions and the following disclaimer.
11182007Sroberto * 2. Redistributions in binary form must reproduce the above copyright
12182007Sroberto *    notice, this list of conditions and the following disclaimer in the
13182007Sroberto *    documentation and/or other materials provided with the distribution.
14182007Sroberto * 3. Neither the name of the University nor the names of its contributors
15182007Sroberto *    may be used to endorse or promote products derived from this software
16182007Sroberto *    without specific prior written permission.
17182007Sroberto *
18182007Sroberto * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19182007Sroberto * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20182007Sroberto * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21182007Sroberto * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22182007Sroberto * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23182007Sroberto * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24182007Sroberto * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25182007Sroberto * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26182007Sroberto * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27182007Sroberto * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28182007Sroberto * SUCH DAMAGE.
29182007Sroberto */
30182007Sroberto
31182007Sroberto#include "includes.h"
32182007Sroberto
33182007Sroberto#ifndef HAVE_RRESVPORT_AF
34182007Sroberto
3554359Sroberto#if defined(LIBC_SCCS) && !defined(lint)
3654359Srobertostatic char *rcsid = "$OpenBSD: rresvport.c,v 1.6 2003/06/03 02:11:35 deraadt Exp $";
3754359Sroberto#endif /* LIBC_SCCS and not lint */
3854359Sroberto
3954359Sroberto#include "includes.h"
4054359Sroberto
4154359Sroberto#if 0
4254359Srobertoint
4354359Srobertorresvport(alport)
4454359Sroberto	int *alport;
4554359Sroberto{
4654359Sroberto	return rresvport_af(alport, AF_INET);
4754359Sroberto}
4854359Sroberto#endif
4954359Sroberto
5054359Srobertoint
5154359Srobertorresvport_af(int *alport, sa_family_t af)
5254359Sroberto{
5354359Sroberto	struct sockaddr_storage ss;
5454359Sroberto	struct sockaddr *sa;
5554359Sroberto	u_int16_t *portp;
5654359Sroberto	int s;
5754359Sroberto	socklen_t salen;
5854359Sroberto
5954359Sroberto	memset(&ss, '\0', sizeof ss);
6054359Sroberto	sa = (struct sockaddr *)&ss;
6154359Sroberto
6254359Sroberto	switch (af) {
6354359Sroberto	case AF_INET:
6454359Sroberto		salen = sizeof(struct sockaddr_in);
6554359Sroberto		portp = &((struct sockaddr_in *)sa)->sin_port;
6654359Sroberto		break;
6754359Sroberto	case AF_INET6:
68285612Sdelphij		salen = sizeof(struct sockaddr_in6);
6954359Sroberto		portp = &((struct sockaddr_in6 *)sa)->sin6_port;
7054359Sroberto		break;
7154359Sroberto	default:
7254359Sroberto		errno = EPFNOSUPPORT;
7354359Sroberto		return (-1);
7454359Sroberto	}
7554359Sroberto	sa->sa_family = af;
7654359Sroberto
7754359Sroberto	s = socket(af, SOCK_STREAM, 0);
7854359Sroberto	if (s < 0)
7954359Sroberto		return (-1);
8054359Sroberto
8154359Sroberto	*portp = htons(*alport);
8254359Sroberto	if (*alport < IPPORT_RESERVED - 1) {
8354359Sroberto		if (bind(s, sa, salen) >= 0)
8454359Sroberto			return (s);
8554359Sroberto		if (errno != EADDRINUSE) {
8654359Sroberto			(void)close(s);
8754359Sroberto			return (-1);
8854359Sroberto		}
8954359Sroberto	}
9054359Sroberto
9154359Sroberto	*portp = 0;
9254359Sroberto	sa->sa_family = af;
9354359Sroberto	if (bindresvport_sa(s, sa) == -1) {
9454359Sroberto		(void)close(s);
9554359Sroberto		return (-1);
9654359Sroberto	}
9754359Sroberto	*alport = ntohs(*portp);
9854359Sroberto	return (s);
9954359Sroberto}
10054359Sroberto
10154359Sroberto#endif /* HAVE_RRESVPORT_AF */
10254359Sroberto