Line data Source code
1 : /*
2 : * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
3 : * (Royal Institute of Technology, Stockholm, Sweden).
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions
8 : * are met:
9 : *
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : *
13 : * 2. Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : *
17 : * 3. Neither the name of the Institute nor the names of its contributors
18 : * may be used to endorse or promote products derived from this software
19 : * without specific prior written permission.
20 : *
21 : * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 : * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 : * SUCH DAMAGE.
32 : */
33 :
34 : #include <config.h>
35 :
36 : #include "roken.h"
37 : #include <err.h>
38 :
39 : /*
40 : * Set `sa' to the unitialized address of address family `af'
41 : */
42 :
43 : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
44 0 : socket_set_any (struct sockaddr *sa, int af)
45 : {
46 0 : switch (af) {
47 0 : case AF_INET : {
48 0 : struct sockaddr_in *sin4 = (struct sockaddr_in *)sa;
49 :
50 0 : memset (sin4, 0, sizeof(*sin4));
51 0 : sin4->sin_family = AF_INET;
52 0 : sin4->sin_port = 0;
53 0 : sin4->sin_addr.s_addr = INADDR_ANY;
54 0 : break;
55 : }
56 : #ifdef HAVE_IPV6
57 0 : case AF_INET6 : {
58 0 : struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
59 :
60 0 : memset (sin6, 0, sizeof(*sin6));
61 0 : sin6->sin6_family = AF_INET6;
62 0 : sin6->sin6_port = 0;
63 0 : sin6->sin6_addr = in6addr_any;
64 0 : break;
65 : }
66 : #endif
67 0 : default :
68 0 : errx (1, "unknown address family %d", sa->sa_family);
69 0 : break;
70 : }
71 0 : }
72 :
73 : /*
74 : * set `sa' to (`ptr', `port')
75 : */
76 :
77 : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
78 0 : socket_set_address_and_port (struct sockaddr *sa, const void *ptr, int port)
79 : {
80 0 : switch (sa->sa_family) {
81 0 : case AF_INET : {
82 0 : struct sockaddr_in *sin4 = (struct sockaddr_in *)sa;
83 :
84 0 : memset (sin4, 0, sizeof(*sin4));
85 0 : sin4->sin_family = AF_INET;
86 0 : sin4->sin_port = port;
87 0 : memcpy (&sin4->sin_addr, ptr, sizeof(struct in_addr));
88 0 : break;
89 : }
90 : #ifdef HAVE_IPV6
91 0 : case AF_INET6 : {
92 0 : struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
93 :
94 0 : memset (sin6, 0, sizeof(*sin6));
95 0 : sin6->sin6_family = AF_INET6;
96 0 : sin6->sin6_port = port;
97 0 : memcpy (&sin6->sin6_addr, ptr, sizeof(struct in6_addr));
98 0 : break;
99 : }
100 : #endif
101 0 : default :
102 0 : errx (1, "unknown address family %d", sa->sa_family);
103 0 : break;
104 : }
105 0 : }
106 :
107 : /*
108 : * Return the size of an address of the type in `sa'
109 : */
110 :
111 : ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL
112 0 : socket_addr_size (const struct sockaddr *sa)
113 : {
114 0 : switch (sa->sa_family) {
115 0 : case AF_INET :
116 0 : return sizeof(struct in_addr);
117 : #ifdef HAVE_IPV6
118 0 : case AF_INET6 :
119 0 : return sizeof(struct in6_addr);
120 : #endif
121 0 : default :
122 0 : return 0;
123 : }
124 : }
125 :
126 : /*
127 : * Return the size of a `struct sockaddr' in `sa'.
128 : */
129 :
130 : ROKEN_LIB_FUNCTION size_t ROKEN_LIB_CALL
131 0 : socket_sockaddr_size (const struct sockaddr *sa)
132 : {
133 0 : switch (sa->sa_family) {
134 0 : case AF_INET :
135 0 : return sizeof(struct sockaddr_in);
136 : #ifdef HAVE_IPV6
137 0 : case AF_INET6 :
138 0 : return sizeof(struct sockaddr_in6);
139 : #endif
140 0 : default:
141 0 : return 0;
142 : }
143 : }
144 :
145 : /*
146 : * Return the binary address of `sa'.
147 : */
148 :
149 : ROKEN_LIB_FUNCTION void * ROKEN_LIB_CALL
150 0 : socket_get_address (const struct sockaddr *sa)
151 : {
152 0 : switch (sa->sa_family) {
153 0 : case AF_INET : {
154 0 : const struct sockaddr_in *sin4 = (const struct sockaddr_in *)sa;
155 0 : return rk_UNCONST(&sin4->sin_addr);
156 : }
157 : #ifdef HAVE_IPV6
158 0 : case AF_INET6 : {
159 0 : const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
160 0 : return rk_UNCONST(&sin6->sin6_addr);
161 : }
162 : #endif
163 0 : default:
164 0 : return NULL;
165 : }
166 : }
167 :
168 : /*
169 : * Return the port number from `sa'.
170 : */
171 :
172 : ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
173 0 : socket_get_port (const struct sockaddr *sa)
174 : {
175 0 : switch (sa->sa_family) {
176 0 : case AF_INET : {
177 0 : const struct sockaddr_in *sin4 = (const struct sockaddr_in *)sa;
178 0 : return sin4->sin_port;
179 : }
180 : #ifdef HAVE_IPV6
181 0 : case AF_INET6 : {
182 0 : const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
183 0 : return sin6->sin6_port;
184 : }
185 : #endif
186 0 : default :
187 0 : return 0;
188 : }
189 : }
190 :
191 : /*
192 : * Set the port in `sa' to `port'.
193 : */
194 :
195 : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
196 0 : socket_set_port (struct sockaddr *sa, int port)
197 : {
198 0 : switch (sa->sa_family) {
199 0 : case AF_INET : {
200 0 : struct sockaddr_in *sin4 = (struct sockaddr_in *)sa;
201 0 : sin4->sin_port = port;
202 0 : break;
203 : }
204 : #ifdef HAVE_IPV6
205 0 : case AF_INET6 : {
206 0 : struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
207 0 : sin6->sin6_port = port;
208 0 : break;
209 : }
210 : #endif
211 0 : default :
212 0 : errx (1, "unknown address family %d", sa->sa_family);
213 0 : break;
214 : }
215 0 : }
216 :
217 : /*
218 : * Set the range of ports to use when binding with port = 0.
219 : */
220 : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
221 0 : socket_set_portrange (rk_socket_t sock, int restr, int af)
222 : {
223 : #if defined(IP_PORTRANGE)
224 : if (af == AF_INET) {
225 : int on = restr ? IP_PORTRANGE_HIGH : IP_PORTRANGE_DEFAULT;
226 : (void) setsockopt(sock, IPPROTO_IP, IP_PORTRANGE, &on, sizeof(on));
227 : }
228 : #endif
229 : #if defined(IPV6_PORTRANGE)
230 : if (af == AF_INET6) {
231 : int on = restr ? IPV6_PORTRANGE_HIGH : IPV6_PORTRANGE_DEFAULT;
232 : (void) setsockopt(sock, IPPROTO_IPV6, IPV6_PORTRANGE, &on, sizeof(on));
233 : }
234 : #endif
235 0 : }
236 :
237 : /*
238 : * Enable debug on `sock'.
239 : */
240 :
241 : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
242 0 : socket_set_debug (rk_socket_t sock)
243 : {
244 : #if defined(SO_DEBUG) && defined(HAVE_SETSOCKOPT)
245 : int on = 1;
246 : (void) setsockopt(sock, SOL_SOCKET, SO_DEBUG, (void *) &on, sizeof (on));
247 : #endif
248 0 : }
249 :
250 : /*
251 : * Set the type-of-service of `sock' to `tos'.
252 : */
253 :
254 : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
255 0 : socket_set_tos (rk_socket_t sock, int tos)
256 : {
257 : #if defined(IP_TOS) && defined(HAVE_SETSOCKOPT)
258 : (void) setsockopt (sock, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(int));
259 : #endif
260 0 : }
261 :
262 : /*
263 : * Set the non-blocking-ness of the socket.
264 : */
265 :
266 : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
267 41795 : socket_set_nonblocking(rk_socket_t sock, int nonblock)
268 : {
269 : #if defined(O_NONBLOCK)
270 41795 : int flags = fcntl(sock, F_GETFL, 0);
271 41795 : if (flags == -1)
272 0 : return;
273 41795 : if (nonblock)
274 41795 : flags |= O_NONBLOCK;
275 : else
276 0 : flags &= ~O_NONBLOCK;
277 41795 : (void) fcntl(sock, F_SETFL, flags);
278 : #elif defined(FIOBIO)
279 : int flags = !!nonblock;
280 :
281 : (void) ioctl(sock, FIOBIO, &flags);
282 : #endif
283 : }
284 :
285 : /*
286 : * set the reuse of addresses on `sock' to `val'.
287 : */
288 :
289 : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
290 0 : socket_set_reuseaddr (rk_socket_t sock, int val)
291 : {
292 : #if defined(SO_REUSEADDR) && defined(HAVE_SETSOCKOPT)
293 : (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&val,
294 : sizeof(val));
295 : #endif
296 0 : }
297 :
298 : /*
299 : * Set the that the `sock' should bind to only IPv6 addresses.
300 : */
301 :
302 : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
303 0 : socket_set_ipv6only (rk_socket_t sock, int val)
304 : {
305 : #if defined(IPV6_V6ONLY) && defined(HAVE_SETSOCKOPT)
306 : (void) setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&val,
307 : sizeof(val));
308 : #endif
309 0 : }
310 :
311 : /*
312 : * Set the that the `sock' keepalive setting.
313 : */
314 :
315 : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
316 0 : socket_set_keepalive(rk_socket_t sock, int val)
317 : {
318 0 : (void) setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&val,
319 : sizeof(val));
320 0 : }
321 :
322 : /**
323 : * Create a file descriptor from a socket
324 : *
325 : * While the socket handle in \a sock can be used with WinSock
326 : * functions after calling socket_to_fd(), it should not be closed
327 : * with rk_closesocket(). The socket will be closed when the associated
328 : * file descriptor is closed.
329 : */
330 : ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
331 0 : socket_to_fd(rk_socket_t sock, int flags)
332 : {
333 : #ifndef _WIN32
334 0 : return sock;
335 : #else
336 : return _open_osfhandle((intptr_t) sock, flags);
337 : #endif
338 : }
339 :
340 : #ifdef HAVE_WINSOCK
341 : ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
342 : rk_SOCK_IOCTL(SOCKET s, long cmd, int * argp) {
343 : u_long ul = (argp)? *argp : 0;
344 : int rv;
345 :
346 : rv = ioctlsocket(s, cmd, &ul);
347 : if (argp)
348 : *argp = (int) ul;
349 : return rv;
350 : }
351 : #endif
352 :
353 : #ifndef HEIMDAL_SMALLER
354 : #undef socket
355 :
356 : int rk_socket(int, int, int);
357 :
358 : int
359 41824 : rk_socket(int domain, int type, int protocol)
360 : {
361 1658 : int s;
362 41824 : s = socket (domain, type, protocol);
363 : #ifdef SOCK_CLOEXEC
364 41824 : if ((SOCK_CLOEXEC & type) && s < 0 && errno == EINVAL) {
365 0 : type &= ~SOCK_CLOEXEC;
366 0 : s = socket (domain, type, protocol);
367 : }
368 : #endif
369 41824 : return s;
370 : }
371 :
372 : #endif /* HEIMDAL_SMALLER */
|