]> andersk Git - openssh.git/blob - bsd-bindresvport.c
fb3f6f2b85767a7a61faa71c0c170dc1356ffe46
[openssh.git] / bsd-bindresvport.c
1 /*
2  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3  * unrestricted use provided that this legend is included on all tape
4  * media and as a part of the software program in whole or part.  Users
5  * may copy or modify Sun RPC without charge, but are not authorized
6  * to license or distribute it to anyone else except as part of a product or
7  * program developed by the user.
8  * 
9  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12  * 
13  * Sun RPC is provided with no support and without any obligation on the
14  * part of Sun Microsystems, Inc. to assist in its use, correction,
15  * modification or enhancement.
16  * 
17  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19  * OR ANY PART THEREOF.
20  * 
21  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22  * or profits or other special, indirect and consequential damages, even if
23  * Sun has been advised of the possibility of such damages.
24  * 
25  * Sun Microsystems, Inc.
26  * 2550 Garcia Avenue
27  * Mountain View, California  94043
28  */
29
30 #include "config.h"
31
32 #ifndef HAVE_BINDRESVPORT_AF
33
34 #if defined(LIBC_SCCS) && !defined(lint)
35 static char *rcsid = "$OpenBSD: bindresvport.c,v 1.11 1999/12/17 19:22:08 deraadt Exp $";
36 #endif /* LIBC_SCCS and not lint */
37
38 /*
39  * Copyright (c) 1987 by Sun Microsystems, Inc.
40  *
41  * Portions Copyright(C) 1996, Jason Downs.  All rights reserved.
42  */
43
44 #include "includes.h"
45
46 #define STARTPORT 600
47 #define ENDPORT (IPPORT_RESERVED - 1)
48 #define NPORTS  (ENDPORT - STARTPORT + 1)
49
50 /*
51  * Bind a socket to a privileged IP port
52  */
53 int
54 bindresvport_af(sd, sa, af)
55         int sd;
56         struct sockaddr *sa;
57         int af;
58 {
59         int error;
60         struct sockaddr_storage myaddr;
61         struct sockaddr_in *sin;
62         struct sockaddr_in6 *sin6;
63         u_int16_t *portp;
64         u_int16_t port;
65         int salen;
66         int i;
67
68         if (sa == NULL) {
69                 memset(&myaddr, 0, sizeof(myaddr));
70                 sa = (struct sockaddr *)&myaddr;
71         }
72
73         if (af == AF_INET) {
74                 sin = (struct sockaddr_in *)sa;
75                 salen = sizeof(struct sockaddr_in);
76                 portp = &sin->sin_port;
77         } else if (af == AF_INET6) {
78                 sin6 = (struct sockaddr_in6 *)sa;
79                 salen = sizeof(struct sockaddr_in6);
80                 portp = &sin6->sin6_port;
81         } else {
82                 errno = EPFNOSUPPORT;
83                 return (-1);
84         }
85         sa->sa_family = af;
86
87         port = ntohs(*portp);
88         if (port == 0)
89                 port = (arc4random() % NPORTS) + STARTPORT;
90
91         for(i = 0; i < NPORTS; i++) {
92                 *portp = htons(port);
93                 
94                 error = bind(sd, sa, salen);
95                 
96                 /* Terminate on success */
97                 if (error == 0)
98                         break;
99                         
100                 /* Terminate on errors, except "address already in use" */
101                 if ((error < 0) && !((errno == EADDRINUSE) || (errno == EINVAL)))
102                         break;
103                         
104                 port++;
105                 if (port > ENDPORT)
106                         port = STARTPORT;
107         }
108
109         return (error);
110 }
111
112 #endif /* HAVE_BINDRESVPORT_AF */
This page took 0.041772 seconds and 3 git commands to generate.