]> andersk Git - openssh.git/blob - bsd-bindresvport.c
- Fix rresvport_af failure errors (logic error in bsd-bindresvport.c)
[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_BINRESVPORT_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         int salen;
65         int i;
66
67         if (sa == NULL) {
68                 memset(&myaddr, 0, sizeof(myaddr));
69                 sa = (struct sockaddr *)&myaddr;
70         }
71
72         if (af == AF_INET) {
73                 sin = (struct sockaddr_in *)sa;
74                 salen = sizeof(struct sockaddr_in);
75                 portp = &sin->sin_port;
76         } else if (af == AF_INET6) {
77                 sin6 = (struct sockaddr_in6 *)sa;
78                 salen = sizeof(struct sockaddr_in6);
79                 portp = &sin6->sin6_port;
80         } else {
81                 errno = EPFNOSUPPORT;
82                 return (-1);
83         }
84         sa->sa_family = af;
85
86         if (*portp == 0)
87                 *portp = (u_int16_t)(arc4random() % NPORTS) + STARTPORT;
88
89         for(i = 0; i < NPORTS; i++) {
90                 error = bind(sd, sa, salen);
91                 
92                 /* Terminate on success */
93                 if (error == 0)
94                         break;
95                         
96                 /* Terminate on errors, except "address already in use" */
97                 if ((error < 0) && !((errno == EADDRINUSE) || (errno == EINVAL)))
98                         break;
99                         
100                 *portp = (i % NPORTS) + STARTPORT;
101         }
102
103         return (error);
104 }
105
106 #endif /* HAVE_BINRESVPORT_AF */
This page took 0.0664400000000001 seconds and 5 git commands to generate.