VM: simplify slab allocator
[minix.git] / lib / libc / rpc / bindresvport.c
blob1c8dc3eb47dc2c4dcdd2e7778c551fde0d3dbeb6
1 /* $NetBSD: bindresvport.c,v 1.21 2003/01/18 11:29:03 thorpej Exp $ */
3 /*
4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
5 * unrestricted use provided that this legend is included on all tape
6 * media and as a part of the software program in whole or part. Users
7 * may copy or modify Sun RPC without charge, but are not authorized
8 * to license or distribute it to anyone else except as part of a product or
9 * program developed by the user.
11 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
12 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
13 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
15 * Sun RPC is provided with no support and without any obligation on the
16 * part of Sun Microsystems, Inc. to assist in its use, correction,
17 * modification or enhancement.
19 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
21 * OR ANY PART THEREOF.
23 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24 * or profits or other special, indirect and consequential damages, even if
25 * Sun has been advised of the possibility of such damages.
27 * Sun Microsystems, Inc.
28 * 2550 Garcia Avenue
29 * Mountain View, California 94043
32 #include <sys/cdefs.h>
33 #if defined(LIBC_SCCS) && !defined(lint)
34 #if 0
35 static char *sccsid = "@(#)bindresvport.c 1.8 88/02/08 SMI";
36 static char *sccsid = "@(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC";
37 #else
38 __RCSID("$NetBSD: bindresvport.c,v 1.21 2003/01/18 11:29:03 thorpej Exp $");
39 #endif
40 #endif
43 * Copyright (c) 1987 by Sun Microsystems, Inc.
46 #include "namespace.h"
48 #include <sys/types.h>
49 #include <sys/socket.h>
51 #include <netinet/in.h>
53 #include <errno.h>
54 #include <string.h>
55 #include <unistd.h>
57 #include <rpc/rpc.h>
59 #ifdef __weak_alias
60 __weak_alias(bindresvport,_bindresvport)
61 __weak_alias(bindresvport_sa,_bindresvport_sa)
62 #endif
65 * Bind a socket to a privileged IP port
67 int
68 bindresvport(sd, brsin)
69 int sd;
70 struct sockaddr_in *brsin;
72 return bindresvport_sa(sd, (struct sockaddr *)(void *)brsin);
76 * Bind a socket to a privileged IP port
78 int
79 bindresvport_sa(sd, sa)
80 int sd;
81 struct sockaddr *sa;
83 int error, old;
84 struct sockaddr_storage myaddr;
85 struct sockaddr_in *brsin;
86 #ifdef INET6
87 struct sockaddr_in6 *brsin6;
88 #endif
89 int proto, portrange, portlow;
90 u_int16_t *portp;
91 socklen_t salen;
92 int af;
94 if (sa == NULL) {
95 salen = sizeof(myaddr);
96 sa = (struct sockaddr *)(void *)&myaddr;
98 if (getsockname(sd, sa, &salen) == -1)
99 return -1; /* errno is correctly set */
101 af = sa->sa_family;
102 memset(sa, 0, salen);
103 } else
104 af = sa->sa_family;
106 switch (af) {
107 case AF_INET:
108 proto = IPPROTO_IP;
109 portrange = IP_PORTRANGE;
110 portlow = IP_PORTRANGE_LOW;
111 brsin = (struct sockaddr_in *)(void *)sa;
112 salen = sizeof(struct sockaddr_in);
113 portp = &brsin->sin_port;
114 break;
115 #ifdef INET6
116 case AF_INET6:
117 proto = IPPROTO_IPV6;
118 portrange = IPV6_PORTRANGE;
119 portlow = IPV6_PORTRANGE_LOW;
120 brsin6 = (struct sockaddr_in6 *)(void *)sa;
121 salen = sizeof(struct sockaddr_in6);
122 portp = &brsin6->sin6_port;
123 break;
124 #endif
125 default:
126 errno = EPFNOSUPPORT;
127 return (-1);
129 sa->sa_family = af;
130 sa->sa_len = salen;
132 if (*portp == 0) {
133 socklen_t oldlen = sizeof(old);
135 error = getsockopt(sd, proto, portrange, &old, &oldlen);
136 if (error < 0)
137 return (error);
138 error = setsockopt(sd, proto, portrange, &portlow,
139 sizeof(portlow));
140 if (error < 0)
141 return (error);
144 error = bind(sd, sa, salen);
146 if (*portp == 0) {
147 int saved_errno = errno;
149 if (error < 0) {
150 if (setsockopt(sd, proto, portrange, &old,
151 sizeof(old)) < 0)
152 errno = saved_errno;
153 return (error);
156 if (sa != (struct sockaddr *)(void *)&myaddr) {
157 /* What did the kernel assign? */
158 if (getsockname(sd, sa, &salen) < 0)
159 errno = saved_errno;
160 return (error);
163 return (error);